koishi-plugin-teach
Version:
Teach plugin for Koishi
358 lines (357 loc) • 11.5 kB
TypeScript
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;