UNPKG

koishi-plugin-teach

Version:
358 lines (357 loc) 11.5 kB
import { Session, App, Context, User, NextFunction, Argv } from 'koishi-core'; import { Observed, Awaitable } from 'koishi-utils'; declare module 'koishi-core' { interface App { teachHistory: Record<number, Dialogue>; } interface EventMap { 'dialogue/permit'(argv: Dialogue.Argv, dialogue: Dialogue): boolean; 'dialogue/flag'(flag: keyof typeof Dialogue.Flag): void; 'dialogue/test'(test: DialogueTest, query: Query.Expr<Dialogue>): void; } interface Tables { dialogue: Dialogue; } } export interface Dialogue { id?: number; question: string; answer: string; original: string; flag: number; _weight?: number; _capture?: RegExpExecArray; _type?: Dialogue.ModifyType; _operator?: string; _timestamp?: number; _backup?: Readonly<Dialogue>; } export interface DialogueTest { original?: string; question?: string; answer?: string; regexp?: boolean; activated?: boolean; appellative?: boolean; noRecursive?: boolean; } export namespace Dialogue { type ModifyType = '添加' | '修改' | '删除'; type Field = keyof Dialogue; interface AuthorityConfig { /** 可访问教学系统,默认值为 2 */ base?: number; /** 可修改非自己创建的问答,默认值为 3 */ admin?: number; /** 可修改上下文设置,默认值为 3 */ context?: number; /** 可修改锁定的问答,默认值为 4 */ frozen?: number; /** 可使用正则表达式,默认值为 3 */ regExp?: number; /** 可设置作者或匿名,默认值为 2 */ writer?: number; /** 可触发教学问答,默认值为 1 */ receive?: number; } interface Config { prefix?: string; authority?: AuthorityConfig; historyAge?: number; } interface Stats { questions: number; dialogues: number; } enum Flag { /** 冻结:只有 4 级以上权限者可修改 */ frozen = 1, /** 正则:使用正则表达式进行匹配 */ regexp = 2, /** 上下文:后继问答可以被上下文内任何人触发 */ context = 4, /** 代行者:由教学者完成回答的执行 */ substitute = 8, /** 补集:上下文匹配时取补集 */ complement = 16 } function get(ctx: Context, test: DialogueTest): Promise<Dialogue[]>; function get<K extends Field>(ctx: Context, ids: number[], fields?: K[]): Promise<Pick<Dialogue, K>[]>; function update(dialogues: Observed<Dialogue>[], argv: Argv): Promise<void>; function stats(ctx: Context): Promise<Stats>; function remove(dialogues: Dialogue[], argv: Argv, revert?: boolean): Promise<number[]>; function revert(dialogues: Dialogue[], argv: Argv): Promise<string>; function recover(dialogues: Dialogue[], argv: Argv): Promise<void>; function addHistory(dialogue: Dialogue, type: ModifyType, argv: Argv, revert: boolean): boolean; interface Argv { app: App; session: Session<'authority' | 'id'>; args: string[]; config: Config; target?: number[]; options: Record<string, any>; dialogues?: Dialogue[]; dialogueMap?: Record<number, Dialogue>; skipped?: number[]; updated?: number[]; unknown?: number[]; uneditable?: number[]; } } export function sendResult(argv: Dialogue.Argv, prefix?: string, suffix?: string): Promise<void>; export function split(source: string): number[]; export function equal(array1: (string | number)[], array2: (string | number)[]): boolean; export function prepareTargets(argv: Dialogue.Argv, dialogues?: Dialogue[]): Observed<Dialogue, void>[]; export function isPositiveInteger(source: string): number; export function isZeroToOne(source: string): number; export const RE_DIALOGUES: RegExp; declare module 'koishi-core' { interface App { _dialogueStates: Record<number, SessionState>; } interface EventMap { 'dialogue/state'(state: SessionState): void; 'dialogue/receive'(state: SessionState): void | boolean; 'dialogue/prepare'(state: SessionState): void; 'dialogue/before-attach-user'(state: SessionState, userFields: Set<User.Field>): void; 'dialogue/attach-user'(state: SessionState): void | boolean; 'dialogue/before-send'(state: SessionState): Awaitable<void | boolean>; 'dialogue/send'(state: SessionState): void; } interface Context { getSessionState(this: Context, session: Session): SessionState; } interface Session { _redirected?: number; } } interface Question { /** 被 unescape 处理后原本的句子 */ original: string; /** 去除句首句尾标点符号,句中空格和句首称呼的句子 */ parsed: string; /** 是否含有称呼 */ appellative: boolean; /** 是否仅含有称呼 */ activated: boolean; } export namespace Dialogue { interface Config { nickname?: string | string[]; appellationTimeout?: number; maxRedirections?: number; _stripQuestion?(source: string): Question; } } export interface SessionState { userId?: string; channelId?: string; answer?: string; session?: Session<User.Field>; test?: DialogueTest; dialogue?: Dialogue; dialogues?: Dialogue[]; next?: NextFunction; isSearch?: boolean; } export function escapeAnswer(message: string): string; export function unescapeAnswer(message: string): string; export function getTotalWeight(ctx: Context, state: SessionState): Promise<number>; export class MessageBuffer { private session; private buffer; private original; hasData: boolean; send: Session['send']; sendQueued: Session['sendQueued']; constructor(session: Session); write(message: string): void; private _flush; flush(): Promise<void>; execute(argv: Argv): Promise<void>; end(message?: string): Promise<void>; } export function triggerDialogue(ctx: Context, session: Session, next?: NextFunction): Promise<void>; export interface SearchDetails extends Array<string> { questionType?: string; answerType?: string; } declare module 'koishi-core' { interface EventMap { 'dialogue/list'(dialogue: Dialogue, output: string[], prefix: string, argv: Dialogue.Argv): void; 'dialogue/detail-short'(dialogue: Dialogue, output: SearchDetails, argv: Dialogue.Argv): void; 'dialogue/before-search'(argv: Dialogue.Argv, test: DialogueTest): void | boolean; 'dialogue/search'(argv: Dialogue.Argv, test: DialogueTest, dialogue: Dialogue[]): Promise<void>; } } interface Dialogue { _redirections: Dialogue[]; } export namespace Dialogue { interface Config { itemsPerPage?: number; mergeThreshold?: number; maxAnswerLength?: number; } interface Argv { questionMap?: Record<string, Dialogue[]>; } } export function formatAnswer(source: string, { maxAnswerLength }: Dialogue.Config): string; export function getDetails(argv: Dialogue.Argv, dialogue: Dialogue): SearchDetails; export function formatDetails(dialogue: Dialogue, details: SearchDetails): string; export function formatAnswers(argv: Dialogue.Argv, dialogues: Dialogue[], prefix?: string): string[]; export function formatQuestionAnswers(argv: Dialogue.Argv, dialogues: Dialogue[], prefix?: string): string[]; declare module 'koishi-core' { interface EventMap { 'dialogue/before-modify'(argv: Dialogue.Argv): Awaitable<void | string>; 'dialogue/modify'(argv: Dialogue.Argv, dialogue: Dialogue): void; 'dialogue/after-modify'(argv: Dialogue.Argv): Awaitable<void>; 'dialogue/before-detail'(argv: Dialogue.Argv): Awaitable<void>; 'dialogue/detail'(dialogue: Dialogue, output: string[], argv: Dialogue.Argv): Awaitable<void>; } } export namespace Dialogue { interface Config { previewDelay?: number; maxPreviews?: number; } } export function update(argv: Dialogue.Argv): Promise<string | void>; export function create(argv: Dialogue.Argv): Promise<string | void>; declare module 'koishi-core' { namespace Command { interface Config { noInterp?: boolean; } } } interface DialogueTest { groups?: string[]; reversed?: boolean; partial?: boolean; } interface Dialogue { groups: string[]; } export namespace Dialogue { interface Config { useContext?: boolean; } } export const RE_GROUPS: RegExp; export interface ThrottleConfig { interval: number; responses: number; } export interface LoopConfig { participants: number; length: number; debounce?: number; } export namespace Dialogue { interface Config { throttle?: ThrottleConfig | ThrottleConfig[]; preventLoop?: number | LoopConfig | LoopConfig[]; } } interface SessionState { counters?: Record<number, number>; initiators?: string[]; loopTimestamp?: number; } interface Dialogue { probS: number; probA: number; } interface SessionState { activated?: Record<number, number>; } interface SessionState { predecessors?: Record<number, Record<number, number>>; } interface DialogueTest { stateful?: boolean; context?: boolean; predecessors?: (string | number)[]; } interface Dialogue { predecessors: string[]; successorTimeout: number; _predecessors: Dialogue[]; _successors: Dialogue[]; } export namespace Dialogue { interface Config { successorTimeout?: number; } interface Argv { predecessors?: number[]; successors?: number[]; predOverwrite?: boolean; succOverwrite?: boolean; } } interface DialogueTest { matchTime?: number; mismatchTime?: number; } interface Dialogue { startTime: number; endTime: number; } export namespace Dialogue { interface Config { useTime?: boolean; } } export function isHours(value: string): string; interface DialogueTest { writer?: string; frozen?: boolean; substitute?: boolean; } interface Dialogue { writer: string; } export namespace Dialogue { interface Argv { writer?: string; nameMap?: Record<string, string>; /** 用于保存用户权限的键值对,键的范围包括目标问答列表的全体作者以及 -w 参数 */ authMap?: Record<string, number>; } interface Config { useWriter?: boolean; } } export type Config = Dialogue.Config; declare module 'koishi-core' { interface EventMap { 'dialogue/validate'(argv: Dialogue.Argv): void | string; 'dialogue/execute'(argv: Dialogue.Argv): void | Promise<void | string>; } namespace Plugin { interface Packages { 'koishi-plugin-teach': typeof import("."); } } } declare module 'koishi-plugin-webui' { namespace Meta { interface Payload extends Dialogue.Stats { } } namespace Statistics { interface Payload { questions: QuestionData[]; } } } interface QuestionData { name: string; value: number; } export const name = "teach"; export const disposable = true; export function apply(ctx: Context, config?: Config): void;export default function apply(ctx: Context, config: Dialogue.Config): void;