UNPKG

chaite

Version:

core for chatgpt-plugin and karin-plugin-chatgpt

1,715 lines (1,714 loc) 91.6 kB
import { AsyncLocalStorage } from "async_hooks"; import EventEmitter from "node:events"; import { Server } from "node:http"; import { SafetySetting } from "@google/genai"; import { AxiosError, AxiosInstance, AxiosRequestConfig, InternalAxiosRequestConfig } from "axios"; import { Application } from "express"; import { Job } from "@karinjs/node-schedule"; //#region src/types/models.d.ts type Feature = 'chat' | 'visual' | 'tool' | 'embedding'; /** 模型配置:名称 + 功能特性 */ interface ModelConfig { name: string; features: Feature[]; } /** * other roles like developer or function should be handled by different implementations */ type Role = 'system' | 'user' | 'assistant' | 'tool' | 'developer'; interface MessageContent { type: 'text' | 'image' | 'audio' | 'video' | 'tool' | 'reasoning'; thoughtSignature?: string; } interface TextContent extends MessageContent { type: 'text'; /** * Content of text */ text: string; } interface ReasoningContent extends MessageContent { type: 'reasoning'; /** * thinking text */ text: string; } interface ImageContent extends MessageContent { type: 'image'; /** * Either a URL of the image or the base64 encoded image data */ image: string; mimeType?: string; } interface AudioContent extends MessageContent { type: 'audio'; /** * Base64 encoded audio data */ data: string; format: 'mp3' | 'wav'; } type History = { id: string; parentId: string | null; }; interface IMessage { role: Role; content: MessageContent[]; toolCalls?: ToolCall[]; } /** * 模型返回的工具调用,role是assistant */ interface ToolCall { id: string; type: 'function'; function: FunctionCall; thoughtSignature?: string; } type ArgumentValue = string | number | boolean | ArgumentValue[]; type FunctionCall = { name: string; /** * raw可能是JSON字符串,需要反序列化一次 */ arguments: Record<string, ArgumentValue | Record<string, ArgumentValue>>; }; /** * 用户发送的消息,可能有文本和多模态消息 */ interface UserMessage extends IMessage { role: 'user'; content: Array<TextContent | ImageContent | AudioContent>; } interface SystemMessage extends IMessage { role: 'system'; content: TextContent[]; } interface DeveloperMessage extends IMessage { role: 'developer'; content: TextContent[]; } /** * 模型返回的消息,包括文本以及可能的工具调用 */ interface AssistantMessage extends IMessage { role: 'assistant'; content: Array<MessageContent>; toolCalls?: ToolCall[]; } interface ReasoningPart { reasoning_content?: string; reasoning?: string; thinking_content?: string; thinking?: string; think?: string; } /** * 客户端执行工具调用的函数结果 */ interface ToolCallResultMessage extends IMessage { role: 'tool'; content: ToolCallResult[]; } interface ToolCallResult extends MessageContent { type: 'tool'; tool_call_id?: string; content: string; name?: string; } type HistoryMessage = History & IMessage; interface ModelResponse { id?: string; model?: string; contents: MessageContent[]; usage?: ModelUsage; } interface ModelUsage { promptTokens?: number; completionTokens?: number; totalTokens?: number; cachedTokens?: number; reasoningTokens?: number; } interface ModelResponseChunk { id?: string; model?: string; delta: MessageContent[]; toolCall?: ToolCall[]; } interface EmbeddingResult { embeddings: Array<number>[]; } //#endregion //#region src/types/cloud.d.ts interface CloudAPIResponse<T> { code: number; data: T; msg: string; } interface PaginationResult<T> { items: T[]; pagination: { currentPage: number; pageSize: number; totalItems: number; totalPages: number; hasNextPage: boolean; hasPreviousPage: boolean; }; type: string; } interface CloudSharingService<T extends AbstractShareable<unknown>> { setUser(user: User): void; getUser(): User | null; authenticate(apiKey: string): Promise<User | null>; upload(model: Serializable): Promise<T | null>; download(shareId: string): Promise<T | null>; initializeTransfer(model: Serializable): Promise<string | null>; list(filter: Filter, query: string, searchOption: SearchOption): Promise<PaginationResult<T>>; delete(shareId: string): Promise<boolean>; } type FilterValue = string | number | boolean | FilterValue[]; type Filter = Record<string, FilterValue | Record<string, FilterValue>>; interface SearchOption { searchFields?: string[]; page?: number; pageSize?: number; } interface User { username: string; user_id: string | number; api_key?: string; github?: string; email?: string; google?: string; linux_do?: string; apple?: string; microsoft?: string; } interface Serializable { toString(): string; } interface DeSerializable<T> { fromString(str: string): T; } interface CloudModel { modelType: 'settings' | 'executable'; code?: string; name: string; id: string; cloudId?: string; embedded: boolean; description: string; uploader: User; updatedAt: string; createdAt: string; md5: string; toFormatedString(verbose?: boolean): string; } type Shareable<T> = Serializable & DeSerializable<T> & CloudModel; declare abstract class AbstractShareable<T> implements Shareable<T> { constructor(params?: Partial<AbstractShareable<T>>); modelType: 'settings' | 'executable'; code?: string; createdAt: string; description: string; embedded: boolean; id: string; cloudId?: string; name: string; uploader: User; updatedAt: string; fromString(str: string): T; toString(): string; toFormatedString(verbose?: boolean): string; md5: string; } interface Wait { ready(): Promise<void>; } //#endregion //#region src/types/processors.d.ts declare class ProcessorDTO extends AbstractShareable<ProcessorDTO> { constructor(params: Partial<ProcessorDTO>); type: 'pre' | 'post'; fromString(str: string): ProcessorDTO; toFormatedString(_verbose?: boolean): string; } interface Processor { type: 'pre' | 'post'; name: string; } /** * 继承这个来实现一个前处理器 */ declare abstract class PreProcessor implements Processor { type: 'pre'; abstract process(message: UserMessage): Promise<UserMessage>; name: string; id: string; } /** * 继承这个来实现一个后处理器 */ declare abstract class PostProcessor implements Processor { type: 'post'; abstract process(message: AssistantMessage): Promise<AssistantMessage>; name: string; id: string; } //#endregion //#region src/types/adapter.d.ts interface ToolCallLimitConfig { maxConsecutiveCalls?: number; maxConsecutiveIdenticalCalls?: number; } declare class SendMessageOption implements Serializable, DeSerializable<SendMessageOption> { constructor(option: Partial<SendMessageOption>); static create(options?: SendMessageOption | Partial<SendMessageOption>): SendMessageOption; model?: string; temperature?: number; maxToken?: number; /** * 将系统提示词覆盖 */ systemOverride?: string; /** * 本轮对话禁用历史 */ disableHistoryRead?: boolean; /** * 禁用本轮对话存储到历史 */ disableHistorySave?: boolean; /** * 对话ID。如果不传则默认为第一次对话 */ conversationId?: string; /** * 上一条消息的ID,如果不传则默认为第一次对话 */ parentMessageId?: string; /** * 流模式 */ stream?: boolean; /** * 是否是思考模型 */ isThinkingModel?: boolean; enableReasoning?: boolean; reasoningEffort?: 'high' | 'medium' | 'low' | 'minimal'; reasoningBudgetTokens?: number; toolChoice?: ToolChoice; postProcessorIds?: string[]; preProcessorIds?: string[]; toolGroupId?: string[]; responseModalities?: string[]; safetySettings?: SafetySetting[]; toolCallLimit?: ToolCallLimitConfig; _consecutiveToolCallCount?: number; _consecutiveIdenticalToolCallCount?: number; _lastToolCallSignature?: string; /** * Per-tool call timeout in ms. Overrides channel-level toolTimeoutMs. */ toolTimeoutMs?: number; /** * Agent context fields propagated through the call chain. * Set automatically by Chaite when running under a background job or plan. */ jobId?: string; planId?: string; skillName?: string; /** * 流模式的回调 * @param chunk */ onChunk?(chunk: ModelResponseChunk): Promise<void>; /** * 工具调用轮次,如果有其他非tool_call类消息会被丢弃最后不会返回,但是可以通过onMessageWithToolCall来处理 * @param message */ onMessageWithToolCall?(message: MessageContent): Promise<void>; fromString(str: string): SendMessageOption; toString(): string; } interface ToolChoice { type: 'none' | 'any' | 'auto' | 'specified'; tools?: string[]; } interface EmbeddingOption { model: string; dimensions?: number; } type ClientType = 'openai' | 'gemini' | 'claude'; interface IClient { name: ClientType; features: Feature[]; tools: Tool[]; baseUrl: string; apiKey: string | string[]; multipleKeyStrategy: MultipleKeyStrategy; historyManager: HistoryManager; postProcessors?: PostProcessor[]; preProcessors?: PreProcessor[]; sendMessage(message: UserMessage | undefined, options?: SendMessageOption | Partial<SendMessageOption>): Promise<ModelResponse>; sendMessageWithHistory(history: IMessage[], options?: SendMessageOption | Partial<SendMessageOption>): Promise<IMessage & { usage: ModelUsage; }>; getEmbedding(text: string | string[], options: EmbeddingOption): Promise<EmbeddingResult>; logger: ILogger; } interface HistoryManager { name: string; saveHistory(message: HistoryMessage, conversationId: string): Promise<void>; getHistory(messageId?: string, conversationId?: string): Promise<HistoryMessage[]>; deleteConversation(conversationId: string): Promise<void>; getOneHistory(messageId: string, conversationId: string): Promise<HistoryMessage | undefined>; } declare abstract class AbstractHistoryManager implements HistoryManager { name: string; abstract saveHistory(message: HistoryMessage, conversationId: string): Promise<void>; abstract getHistory(messageId?: string, conversationId?: string): Promise<HistoryMessage[]>; abstract deleteConversation(conversationId: string): Promise<void>; abstract getOneHistory(messageId: string, conversationId: string): Promise<HistoryMessage | undefined>; } //#endregion //#region src/channels/channels.d.ts declare class DefaultChannelLoadBalancer implements ChannelsLoadBalancer { constructor(); getChannel(name: string, channels: Channel[]): Promise<Channel>; private groupByPriority; private selectByWeight; /** * 获取渠道列表及其分配的数量 * generated by qwen-2.5-max * * @param modelName 模型名称 * @param channels 渠道列表 * @param totalQuantity 总数量 * @returns 返回一个包含渠道及其分配数量的数组 */ getChannels(modelName: string, channels: Channel[], totalQuantity: number): Promise<{ channel: Channel; quantity: number; }[]>; } /** * 渠道 * 每个渠道对应一个adapter,并记录客户端的options */ declare class Channel extends AbstractShareable<Channel> implements Wait { constructor(params: Partial<Channel>); init(): Promise<void>; ready(): Promise<void>; getOptionsForModel(modelName: string): BaseClientOptions; adapterType: ClientType; options: BaseClientOptions; models: ModelConfig[]; type: ClientType; weight: number; priority: number; status: 'enabled' | 'disabled'; disabledReason?: string; statistics: ChannelStatistics; fromString(str: string): Channel; toString(): string; toFormatedString(verbose?: boolean): string; } //#endregion //#region src/channels/preset.d.ts /** * 对话模式预设,最终使用的 */ declare class ChatPreset extends AbstractShareable<ChatPreset> { constructor(params?: Partial<ChatPreset>); prefix: string; local: boolean; namespace?: string; sendMessageOption: SendMessageOption; /** * 携带群聊上下文 */ groupContext?: 'disable' | 'enabled' | 'use_system'; /** * 禁止系统prompt */ disableSystemInstructions?: boolean; toString(): string; fromString(str: string): ChatPreset; toFormatedString(verbose?: boolean): string; } //#endregion //#region src/types/external.d.ts interface EventMessage { sender: { user_id: string | number; nickname?: string; card?: string; }; group?: { group_id: number | string; }; } interface UserModeSelector { getChatPreset(e: EventMessage): Promise<ChatPreset>; } declare abstract class AbstractUserModeSelector implements UserModeSelector { abstract getChatPreset(e: EventMessage): Promise<ChatPreset>; } //#endregion //#region src/adapters/clients.d.ts declare class AbstractClient implements IClient { options: BaseClientOptions; constructor(options: BaseClientOptions | Partial<BaseClientOptions>, context?: ChaiteContext); fullfillProcessors(preIds?: string[], postIds?: string[]): Promise<{ pre: PreProcessor[]; post: PostProcessor[]; }>; fullfillTools(toolGroupIds?: string[]): Promise<Tool[]>; sendMessage(message: UserMessage | undefined, options: SendMessageOption | Partial<SendMessageOption>): Promise<ModelResponse>; protected shouldPersistHistory(message?: HistoryMessage): boolean; private getUsageLogContext; protected isEffectivelyEmptyMessage(message?: IMessage): boolean; private hasMeaningfulContent; private isMessagePartMeaningful; protected setToolCallLimitConfig(config?: ToolCallLimitConfig): void; private getEffectiveToolCallLimit; private updateToolCallTracking; private resetToolCallTracking; private buildToolCallSignature; _sendMessage(_histories: IMessage[], _apiKey: string, _options: SendMessageOption): Promise<HistoryMessage & { usage: ModelUsage; }>; sendMessageWithHistory(history: IMessage[], options?: SendMessageOption | Partial<SendMessageOption>): Promise<IMessage & { usage: ModelUsage; }>; apiKey: string | string[]; baseUrl: string; features: Feature[]; multipleKeyStrategy: MultipleKeyStrategy; name: ClientType; tools: Tool[]; logger: ILogger; historyManager: HistoryManager; context: ChaiteContext; postProcessors?: PostProcessor[]; preProcessors?: PreProcessor[]; protected toolCallLimitConfig?: ToolCallLimitConfig; getEmbedding(_text: string | string[], _options: EmbeddingOption): Promise<EmbeddingResult>; } //#endregion //#region src/adapters/create.d.ts declare function createClient(name: ClientType, options: BaseClientOptions | Partial<BaseClientOptions>, context?: ChaiteContext): IClient; //#endregion //#region src/adapters/impl/openai/OpenAIClient.d.ts type OpenAIClientOptions = BaseClientOptions; declare class OpenAIClient extends AbstractClient { constructor(options: OpenAIClientOptions | Partial<OpenAIClientOptions>, context?: ChaiteContext); _sendMessage(histories: IMessage[], apiKey: string, options: SendMessageOption): Promise<HistoryMessage & { usage: ModelUsage; }>; getEmbedding(text: string | string[], options: EmbeddingOption): Promise<EmbeddingResult>; } declare module 'openai' { interface ChatCompletionCreateParamsBase { thinking_budget_tokens?: number | null; } } //#endregion //#region src/adapters/impl/gemini/GeminiClient.d.ts type GeminiClientOptions = BaseClientOptions & { toolCallLimit?: ToolCallLimitConfig; }; declare class GeminiClient extends AbstractClient { constructor(options: GeminiClientOptions | Partial<GeminiClientOptions>, context?: ChaiteContext); _sendMessage(histories: IMessage[], apiKey: string, options: SendMessageOption): Promise<HistoryMessage & { usage: ModelUsage; }>; getEmbedding(text: string | string[], options: EmbeddingOption): Promise<EmbeddingResult>; } //#endregion //#region src/adapters/impl/claude/ClaudeClient.d.ts declare class ClaudeClient extends AbstractClient { constructor(options: GeminiClientOptions | Partial<GeminiClientOptions>, context?: ChaiteContext); _sendMessage(histories: IMessage[], apiKey: string, options: SendMessageOption): Promise<HistoryMessage & { usage: ModelUsage; }>; } //#endregion //#region src/share/shareable.d.ts type ExecutableSShareableType = 'tool' | 'processor'; /** * T是DTO * C是T对应的可执行的实例类型 * @interface ExecutableShareableManager */ declare abstract class ExecutableShareableManager<T extends Shareable<T>, C> { private type; private storage; private watcher; /** * 存储示例名称和文件名的映射 * @private */ protected instanceMap: Map<string, string>; /** * codeDirectory是存放实际代码的目录 * @private */ protected codeDirectory: string; cloudService?: CloudSharingService<T>; protected constructor(type: ExecutableSShareableType, codeDirectory: string, storage: BasicStorage<T>); setCloudService(cloudService: CloudSharingService<T>): void; /** * 只有可执行类型的实例才需要,如工具、处理器等。设置类不需要 * @private */ initialize(): Promise<void>; private setupFileWatcher; private scanInstances; /** * 返回实例名字们 * @returns 实例名字列表 */ listInstanceNames(): Promise<string[]>; listInstances(): Promise<T[]>; getInstanceT(id: string): Promise<T | null>; /** * 获取实例对象而非Shareable DTO * @param name */ getInstance(name: string): Promise<C | undefined>; /** * Plugins historically used both `export default new Tool()` and * `export class MyProcessor ...`. Resolve both shapes from the same loader. */ private resolveModuleInstance; /** * 新增或更新 * 有id就是更新,靠storage实现去控制,这里不管 * @param instance * @return id */ addInstance(instance: T): Promise<string>; addInstanceCode(name: string, code: string): Promise<void>; upsertInstanceT(t: T): Promise<string>; getInstanceTByCloudId(cloudId: string): Promise<T[]>; renameFile(id: string, oldName: string, newName: string): Promise<void>; deleteInstance(id: string): Promise<void>; /** * 序列化实例,返回DTO * @param name */ abstract serializeInstance(name: string): Promise<T | null>; private checkCloudService; shareToCloud(id: string): Promise<string | undefined>; listFromCloud(filter: Filter, query: string, searchOption: SearchOption): Promise<PaginationResult<T & { downloaded: string; }>>; getFromCloud(shareId: string): Promise<T | null>; shareP2P(name: string): Promise<string | null>; dispose(): Promise<void>; } type NonExecutableSShareableType = 'chat-preset' | 'tool-settings' | 'channel' | 'tools-group'; declare abstract class NonExecutableShareableManager<T extends Shareable<T>> { protected type: NonExecutableSShareableType; protected storage: BasicStorage<T>; cloudService?: CloudSharingService<T>; protected constructor(type: NonExecutableSShareableType, storage: BasicStorage<T>); setCloudService(cloudService: CloudSharingService<T>): void; addInstance(instance: T): Promise<string>; deleteInstance(key: string): Promise<void>; listInstances(): Promise<T[]>; getInstance(key: string): Promise<T | null>; upsertInstance(t: T): Promise<string>; getInstanceByCloudId(cloudId: string): Promise<T[]>; private checkCloudService; shareToCloud(key: string): Promise<string | undefined>; shareP2P(key: string): Promise<string | null>; getFromCloud(shareId: string): Promise<T | null>; listFromCloud(filter: Filter, query: string, searchOption: SearchOption): Promise<PaginationResult<T & { id: string; }>>; deleteFromCloud(key: string): Promise<void>; } //#endregion //#region src/share/tool.d.ts declare class ToolManager extends ExecutableShareableManager<ToolDTO, Tool> { private static instance; private constructor(); setCloudService(cloudService: CloudSharingService<ToolDTO>): void; static init(toolsDirectory: string, storage: BasicStorage<ToolDTO>): Promise<ToolManager>; static getInstance(): Promise<ToolManager | null>; serializeInstance(name: string): Promise<ToolDTO | null>; } //#endregion //#region src/utils/helpers.d.ts declare function getKey(apiKeys: string[] | string, strategy: MultipleKeyStrategy): Promise<string>; declare const asyncLocalStorage: AsyncLocalStorage<ChaiteContext>; declare function useEvent(): Promise<EventMessage | undefined>; /** * 表示构造函数的类型 */ type AbstractConstructor<T> = abstract new (...args: unknown[]) => T; /** * 将JS代码保存到指定目录并导入其默认导出 * * @param {string} jsContent - JS代码内容 * @param {string} modulesDir - 保存模块的目录 * @param {string} fileName - 文件名(不含路径) * @param {Function} AbstractClass - 抽象类,用于检查实例是否继承自它 * @returns {Promise<T | null>} 如果默认导出继承自AbstractClass则返回该实例,否则返回null */ declare function saveAndLoadModule<T>(jsContent: string, modulesDir: string, fileName: string, AbstractClass: AbstractConstructor<T>): Promise<T | null>; /** * 解析 JavaScript 代码中的 class 变量 name 的值 * @param {string} code - 输入的 JavaScript 代码 * @returns {string|null} - 解析出的 class 的 name 值,或者 null 如果没有找到 */ declare function extractClassName(code: string): string | null; //#endregion //#region src/utils/kv_history.d.ts interface KVStore { get(key: string): Promise<string>; set(key: string, value: string): Promise<void>; delete(key: string): Promise<void>; } declare class KVHistoryManager implements HistoryManager { private kvStore; name: string; constructor(kvStore: KVStore, name: string); private getConversationKey; private getMessageKey; saveHistory(message: HistoryMessage, conversationId: string): Promise<void>; getHistory(messageId?: string, conversationId?: string): Promise<HistoryMessage[]>; deleteConversation(conversationId: string): Promise<void>; getOneHistory(messageId: string, conversationId: string): Promise<HistoryMessage | undefined>; } //#endregion //#region src/utils/history.d.ts type HistoryCache = Map<string, Map<string, HistoryMessage>>; declare class InMemoryHistoryManager extends AbstractHistoryManager { cache: HistoryCache; constructor(); saveHistory(message: HistoryMessage, conversationId: string): Promise<void>; getHistory(messageId?: string, conversationId?: string): Promise<HistoryMessage[]>; deleteConversation(conversationId: string): Promise<void>; getOneHistory(messageId: string, conversationId: string): Promise<HistoryMessage | undefined>; name: string; } //#endregion //#region src/utils/axios.d.ts interface ApiError { status?: number; data?: unknown; message: string; request?: unknown; originalError?: Error | AxiosError; } interface HttpClientOptions { baseURL?: string; timeout?: number; headers?: Record<string, string>; authorizationPrefix?: string; getToken?: () => string | Promise<string> | null | undefined; onRequest?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig; onResponse?: <T>(response: T) => T; onError?: (error: ApiError) => ApiError; } /** * 创建HTTP客户端 */ declare class HttpClient { private instance; private options; /** * 构造HTTP客户端 * @param options 配置选项 */ constructor(options?: HttpClientOptions); /** * 创建Axios实例 */ private createAxiosInstance; /** * 设置拦截器 */ private setupInterceptors; /** * 标准化错误对象 */ private normalizeError; /** * 更新配置 * @param options 新配置 */ updateOptions(options: Partial<HttpClientOptions>): void; /** * 获取底层 Axios 实例 */ getAxiosInstance(): AxiosInstance; /** * HTTP GET 请求 */ get<T>(url: string, config?: AxiosRequestConfig): Promise<T>; /** * HTTP POST 请求 */ post<T, D = unknown>(url: string, data?: D, config?: AxiosRequestConfig): Promise<T>; /** * HTTP PUT 请求 */ put<T, D = unknown>(url: string, data?: D, config?: AxiosRequestConfig): Promise<T>; /** * HTTP DELETE 请求 */ delete<T>(url: string, config?: AxiosRequestConfig): Promise<T>; /** * HTTP PATCH 请求 */ patch<T, D = unknown>(url: string, data?: D, config?: AxiosRequestConfig): Promise<T>; } /** * 创建默认的HTTP客户端 */ declare const createHttpClient: (options?: HttpClientOptions) => HttpClient; //#endregion //#region src/utils/config.d.ts declare const DEFAULT_HOST = "127.0.0.1"; declare const DEFAULT_PORT = 48370; declare class GlobalConfig extends EventEmitter { /** * jwt密钥 */ private authKey; /** * 监听地址 */ private host; /** * 监听端口 */ private port; /** * 是否开启调试模式 */ private debug; /** * 登录有效期,单位秒 */ private loginValidTime; setAuthKey(key: string): void; setHost(host: string): void; setPort(port: number): void; setDebug(debug: boolean): void; setLoginValidTime(time: number): void; getAuthKey(): string; getHost(): string; getPort(): number; getDebug(): boolean; getLoginValidTime(): number; } //#endregion //#region src/utils/auth.d.ts declare class FrontEndAuthHandler { private token; constructor(); generateToken(timeout?: number, onetime?: boolean): string; validateToken(token: string): boolean; static generateJWT(key: string): string; static validateJWT(key: string, token: string): boolean; } //#endregion //#region src/utils/logger.d.ts declare function getLogger(): ILogger; //#endregion //#region src/share/cloud.d.ts declare class DefaultCloudService<T extends AbstractShareable<T>> implements CloudSharingService<T> { private cloudApiBaseUrl; client: HttpClient; type: CloudAPIType; user: User; identifier: string; apiKey: string; constructor(cloudApiBaseUrl: string, type: CloudAPIType); setUser(user: User): void; authenticate(apiKey: string): Promise<User | null>; list(filter: Filter, query: string, searchOption: SearchOption): Promise<PaginationResult<T>>; private createEmptyInstance; private getClassForType; upload(model: T): Promise<T | null>; download(shareId: string): Promise<T | null>; initializeTransfer(model: T): Promise<string | null>; delete(shareId: string): Promise<boolean>; getUser(): User | null; } //#endregion //#region src/share/channels.d.ts declare class ChannelsManager extends NonExecutableShareableManager<Channel> { protected storage: BasicStorage<Channel>; private loadBalancer; private static instance; private constructor(); static init(storage: BasicStorage<Channel>, loadBalancer: ChannelsLoadBalancer): Promise<ChannelsManager>; static getInstance(): Promise<ChannelsManager | null>; getAllChannels(name?: string): Promise<Channel[]>; getChannelByType(type: Channel['type']): Promise<Channel[]>; getChannelByStatus(status: 'enabled' | 'disabled'): Promise<Channel[]>; getChannelByModel(model: string): Promise<Channel[]>; getChannelsByModel(model: string, totalQuantity: number): Promise<{ channel: Channel; quantity: number; }[]>; } //#endregion //#region src/share/processors.d.ts declare class ProcessorsManager extends ExecutableShareableManager<ProcessorDTO, Processor> { private static instance; private constructor(); setCloudService(cloudService: CloudSharingService<ProcessorDTO>): void; static init(processorsDirectory: string, storage: BasicStorage<ProcessorDTO>): Promise<ProcessorsManager>; static getInstance(): Promise<ProcessorsManager | null>; serializeInstance(name: string): Promise<ProcessorDTO | null>; } //#endregion //#region src/share/preset.d.ts declare class ChatPresetManager extends NonExecutableShareableManager<ChatPreset> { protected storage: BasicStorage<ChatPreset>; private static instance; private constructor(); static init(storage: BasicStorage<ChatPreset>): Promise<ChatPresetManager>; static getInstance(): Promise<ChatPresetManager | null>; getAllPresets(options?: { includeLocal?: boolean; namespace?: string; }): Promise<ChatPreset[]>; getPresetByPrefix(prefix: string): Promise<ChatPreset | null>; } //#endregion //#region src/share/tools_group.d.ts declare class ToolsGroupManager extends NonExecutableShareableManager<ToolsGroupDTO> { private static instance; private constructor(); static init(storage: BasicStorage<ToolsGroupDTO>): Promise<ToolsGroupManager>; static getInstance(): Promise<ToolsGroupManager | null>; } //#endregion //#region src/share/trigger.d.ts /** * 专门用于管理触发器的管理器 * 由于触发器需要注册并保持状态运行,因此管理方式不同于普通的可执行代码 */ declare class TriggerManager<T extends TriggerDTO> { private storage; /** * 存储触发器名称到 DTO ID 的映射 * 这样通过实例的 name 就可以找到对应的 DTO id */ protected nameToIdMap: Map<string, string>; private watcher; /** * 存储示例名称和文件名的映射 */ protected instanceMap: Map<string, string>; /** * 已注册的触发器实例 */ protected activeInstances: Map<string, Trigger>; /** * 全局上下文,用于传递给触发器 */ protected context: ChaiteContext; /** * codeDirectory是存放实际代码的目录 */ protected codeDirectory: string; cloudService?: CloudSharingService<T>; constructor(codeDirectory: string, storage: BasicStorage<T>); setCloudService(cloudService: CloudSharingService<T>): void; /** * 初始化管理器,加载所有触发器并注册 */ initialize(): Promise<void>; /** * 设置文件监听器,监控触发器文件的变化 */ private setupFileWatcher; /** * 扫描触发器实例 */ private scanInstances; /** * 注册所有启用状态的触发器 */ private registerAllEnabledTriggers; /** * 注册单个触发器 */ registerTrigger(dtoName: string): Promise<void>; /** * 通过触发器实例的 name 删除触发器 * 注意:这里的 name 是触发器实例的 name,而不是 DTO 中的 name */ deleteInstanceByName(triggerName: string): Promise<void>; /** * 取消注册触发器 */ unregisterTrigger(name: string): Promise<void>; /** * 返回实例名字们 */ listInstanceNames(): Promise<string[]>; /** * 获取所有触发器DTO */ listInstances(): Promise<T[]>; /** * 获取触发器DTO */ getInstanceT(id: string): Promise<T | null>; /** * 通过名称获取触发器DTO */ getInstanceTByName(name: string): Promise<T | null>; /** * 获取触发器实例对象 */ getInstance(name: string): Promise<Trigger | undefined>; /** * 新增或更新触发器 */ addInstance(instance: T): Promise<string>; /** * 添加触发器代码 */ addInstanceCode(name: string, code: string): Promise<void>; /** * 更新或新增触发器 */ upsertInstanceT(t: T): Promise<string>; /** * 通过云ID获取触发器 */ getInstanceTByCloudId(cloudId: string): Promise<T[]>; /** * 重命名触发器文件 */ renameFile(id: string, oldName: string, newName: string): Promise<void>; /** * 删除触发器 */ deleteInstance(id: string): Promise<void>; /** * 更新上下文 */ updateContext(context: ChaiteContext): void; /** * 序列化触发器,返回DTO */ serializeInstance(name: string): Promise<T | null>; private checkCloudService; shareToCloud(id: string): Promise<string | undefined>; listFromCloud(filter: Filter, query: string, searchOption: SearchOption): Promise<PaginationResult<T & { downloaded: string; }>>; getFromCloud(shareId: string): Promise<T | null>; shareP2P(name: string): Promise<string | null>; /** * 清理资源,关闭文件监听器 */ dispose(): Promise<void>; /** * 启用触发器 */ enableTrigger(id: string): Promise<void>; /** * 禁用触发器 */ disableTrigger(id: string): Promise<void>; /** * 检查触发器是否正在运行 */ isRunning(name: string): boolean; /** * 获取当前运行中的所有触发器 */ getRunningTriggers(): string[]; } //#endregion //#region src/types/operation-log.d.ts /** * Operation log types for tracking all AI system activities. */ /** Fine-grained categories of AI system operations */ type OperationLogType = 'llm.call' | 'processor.call' | 'processor.error' | 'trigger.call' | 'trigger.error' | 'tool.call' | 'tool.error' | 'job.queued' | 'job.start' | 'job.complete' | 'job.failed' | 'job.progress' | 'task.fire' | 'task.complete' | 'task.failed' | 'plan.start' | 'plan.step.start' | 'plan.step.end' | 'plan.complete' | 'plan.failed'; type OperationLogLevel = 'info' | 'warn' | 'error'; interface OperationLog { id: string; timestamp: number; type: OperationLogType; level: OperationLogLevel; /** Short human-readable summary */ summary: string; /** Extended detail, error message or result snippet */ detail?: string; userId?: string; /** QQ group id; omitted for private conversations and system tasks */ groupId?: string; conversationId?: string; channelId?: string; channelName?: string; /** Model name for LLM calls */ model?: string; presetId?: string; presetName?: string; /** Tool name for tool.call / tool.error */ toolName?: string; processorName?: string; triggerName?: string; skillName?: string; jobId?: string; planId?: string; stepId?: string; /** Elapsed time in milliseconds */ durationMs?: number; /** Input tokens consumed (LLM calls) */ inputTokens?: number; /** Output tokens produced (LLM calls) */ outputTokens?: number; totalTokens?: number; cachedTokens?: number; reasoningTokens?: number; /** Arbitrary extra metadata */ metadata?: Record<string, unknown>; } interface ListLogsFilter { type?: OperationLogType; level?: OperationLogLevel; userId?: string; groupId?: string; channelId?: string; model?: string; presetId?: string; toolName?: string; processorName?: string; triggerName?: string; /** Unix ms — only logs at or after this time */ from?: number; /** Unix ms — only logs at or before this time */ to?: number; /** Keyword search in summary / detail */ keyword?: string; page?: number; pageSize?: number; } interface LogsPage { items: OperationLog[]; total: number; page: number; pageSize: number; } interface LogsStats { total: number; byType: Partial<Record<OperationLogType, number>>; byLevel: Record<OperationLogLevel, number>; /** Count of logs in last 24 h */ last24h: number; /** Avg LLM call duration ms */ avgLlmDurationMs: number; /** Total tokens (input + output) */ totalTokens: number; inputTokens: number; outputTokens: number; cachedTokens: number; reasoningTokens: number; errorRate: number; byChannel: Record<string, number>; byModel: Record<string, number>; byPreset: Record<string, number>; } //#endregion //#region src/types/storage.d.ts /** * 基本存储接口 */ interface BasicStorage<T> { getName(): string; getItem(key: string): Promise<T | null>; setItem(key: string, value: T): Promise<string>; removeItem(key: string): Promise<void>; listItems(): Promise<T[]>; listItemsByEqFilter(filter: Record<string, unknown>): Promise<T[]>; listItemsByInQuery(query: Array<{ field: string; values: unknown[]; }>): Promise<T[]>; clear(): Promise<void>; } declare abstract class ChaiteStorage<T> implements BasicStorage<T> { abstract getItem(key: string): Promise<T | null>; abstract setItem(key: string, value: T): Promise<string>; abstract removeItem(key: string): Promise<void>; abstract listItems(): Promise<T[]>; abstract listItemsByEqFilter(filter: Record<string, unknown>): Promise<T[]>; abstract listItemsByInQuery(query: Array<{ field: string; values: unknown[]; }>): Promise<T[]>; abstract clear(): Promise<void>; getName(): string; } interface UserState { userId: number | string; nickname?: string; card?: string; conversations: Conversation[]; settings: UserSettings; current: { conversationId?: string; messageId?: string; }; } interface Conversation { id: string; name: string; lastMessageId: string; } interface UserSettings { preset: string; model: string; temperature: number; maxToken: number; systemOverride: string; enableReasoning: boolean; reasoningEffort: 'high' | 'medium' | 'low'; reasoningBudgetTokens: number; toolChoice: ToolChoice; } //#endregion //#region src/share/operation-log.d.ts /** * Manages operation logs for the AI system. * * By default stores up to `maxInMemory` recent entries in a ring buffer. * Optionally accepts a `BasicStorage<OperationLog>` for durable persistence — * when provided, all writes go to storage and reads query from there. * * Attach to Chaite via `chaite.setOperationLogManager(mgr)` to activate * event-based logging of jobs, plans, and tool calls. */ declare class OperationLogManager { private readonly storage?; private readonly memBuf; private readonly maxInMemory; constructor(storage?: BasicStorage<OperationLog> | undefined, maxInMemory?: number); add(entry: Omit<OperationLog, 'id' | 'timestamp'> & Partial<Pick<OperationLog, 'id' | 'timestamp'>>): Promise<OperationLog>; /** Convenience: add a log entry synchronously (fire-and-forget, swallows errors) */ addSync(entry: Omit<OperationLog, 'id' | 'timestamp'> & Partial<Pick<OperationLog, 'id' | 'timestamp'>>): void; list(filter?: ListLogsFilter): Promise<LogsPage>; getStats(): Promise<LogsStats>; clear(filter?: Pick<ListLogsFilter, 'type' | 'level' | 'userId' | 'from' | 'to'>): Promise<number>; private pushMemory; private matchesFilter; } //#endregion //#region src/rag/vector.d.ts /** * generated by claude-3-5-sonnet */ interface VectorDatabase { /** * 添加单个向量到数据库 * @param vector - 要添加的向量,表示为数字数组 * @param text - 与向量关联的文本 * @returns 返回添加的向量的唯一标识符 */ addVector(vector: number[], text: string): Promise<string>; /** * 批量添加多个向量到数据库 * @param vectors - 要添加的向量数组,每个向量表示为数字数组 * @param texts - 与向量关联的文本数组,顺序应与向量数组对应 * @returns 返回添加的向量的唯一标识符数组 */ addVectors(vectors: number[][], texts: string[]): Promise<string[]>; /** * 搜索与给定查询向量最相似的向量 * @param queryVector - 查询向量,表示为数字数组 * @param k - 要返回的最相似向量的数量 * @returns 返回最相似向量的数组,每个元素包含id、相似度分数和关联文本 */ search(queryVector: number[], k: number): Promise<Array<{ id: string; score: number; text: string; }>>; /** * 根据ID获取特定的向量 * @param id - 向量的唯一标识符 * @returns 返回包含向量和关联文本的对象,如果未找到则返回null */ getVector(id: string): Promise<{ vector: number[]; text: string; } | null>; /** * 从数据库中删除指定ID的向量 * @param id - 要删除的向量的唯一标识符 * @returns 返回一个布尔值,表示删除操作是否成功 */ deleteVector(id: string): Promise<boolean>; /** * 更新数据库中指定ID的向量 * @param id - 要更新的向量的唯一标识符 * @param newVector - 新的向量,表示为数字数组 * @param newText - 新的关联文本 * @returns 返回一个布尔值,表示更新操作是否成功 */ updateVector(id: string, newVector: number[], newText: string): Promise<boolean>; /** * 获取数据库中向量的总数 * @returns 返回数据库中存储的向量总数 */ count(): Promise<number>; /** * 清空数据库中的所有向量 * @returns 无返回值 */ clear(): Promise<void>; } declare abstract class AbstractVectorDatabase implements VectorDatabase { abstract addVector(vector: number[], text: string): Promise<string>; abstract addVectors(vectors: number[][], texts: string[]): Promise<string[]>; abstract search(queryVector: number[], k: number): Promise<Array<{ id: string; score: number; text: string; }>>; abstract getVector(id: string): Promise<{ vector: number[]; text: string; } | null>; abstract deleteVector(id: string): Promise<boolean>; abstract clear(): Promise<void>; abstract count(): Promise<number>; abstract updateVector(id: string, newVector: number[], newText: string): Promise<boolean>; } //#endregion //#region src/rag/manager.d.ts declare class RAGManager { private vectorDb; private vectorizer; constructor(vectorDb: VectorDatabase, vectorizer: Vectorizer); /** * 添加文档到 RAG 系统 * @param document 文档文本 * @param maxNum 最大分割数 */ addDocument(document: string, maxNum?: number): Promise<void>; /** * 执行 RAG 查询 * @param query 查询文本 * @param k 返回结果数量 * @returns 查询结果 */ query(query: string, k: number): Promise<RAGResult[]>; /** * 聚合检索出来的结果 * @param results 文本形式 * @param filterScore 过滤的最低分数 */ getAggregatedResults(results: RAGResult[], filterScore?: number): string; } //#endregion //#region src/rag/impl/VectorizerImpl.d.ts declare class VectorizerImpl implements Vectorizer { private client; private model; private dimensions; constructor(client: IClient, model: string, dimensions: number); textToVector(text: string): Promise<number[]>; batchTextToVector(texts: string[]): Promise<number[][]>; } //#endregion //#region src/types/document.d.ts type ParserType = 'docx' | 'xlsx' | 'pptx' | 'pdf' | 'txt' | 'other'; type TypePredicate<T> = (value: unknown) => value is T; interface Parser<T> { type: ParserType; supportedExtensions: ValidExtension[]; isCompatibleType: TypePredicate<T>; parse(document: T): Promise<string>; } type ValidExtension = `.${string}` | string; type FilePath = `${string}${ValidExtension}`; declare class DocumentPathParser implements Parser<FilePath> { isCompatibleType(value: unknown): value is string; supportedExtensions: ValidExtension[]; type: ParserType; parse(document: FilePath): Promise<string>; } declare class DocumentFileParser implements Parser<Buffer> { isCompatibleType(value: unknown): value is Buffer; supportedExtensions: ValidExtension[]; type: ParserType; parse(document: Buffer): Promise<string>; } //#endregion //#region src/rag/impl/PdfParser.d.ts declare class PdfFileParser extends DocumentPathParser { constructor(); private initPromise; valid: boolean; type: ParserType; supportedExtensions: string[]; private initializePdfParse; ready(): Promise<void>; parse(documentPath: string): Promise<string>; } declare class PdfBufferParser extends DocumentFileParser { constructor(); private initPromise; private initializePdfParse; valid: boolean; type: ParserType; supportedExtensions: string[]; ready(): Promise<void>; parse(buffer: Buffer): Promise<string>; } //#endregion //#region src/rag/impl/DocxParser.d.ts declare class DocxFileParser extends DocumentPathParser { constructor(); type: ParserType; supportedExtensions: string[]; parse(documentPath: string): Promise<string>; } declare class DocxBufferParser extends DocumentFileParser { constructor(); type: ParserType; supportedExtensions: string[]; parse(buffer: Buffer): Promise<string>; } //#endregion //#region src/rag/impl/PureTextParser.d.ts declare class PureTextFileParser extends DocumentPathParser { constructor(); type: ParserType; supportedExtensions: string[]; parse(documentPath: string): Promise<string>; } declare class PureTextBufferParser extends DocumentFileParser { constructor(); type: ParserType; supportedExtensions: string[]; parse(buffer: Buffer): Promise<string>; } //#endregion //#region src/rag/text.d.ts declare class TextProcessor { private static readonly punctuationRegex; private static readonly stopWords; /** * 将文本分割成小段落 * @param text 输入的长文本 * @param maxLength 每个段落的最大长度 * @returns 分割后的段落数组 */ static splitIntoChunks(text: string, maxLength: number): string[]; /** * 清理和标准化文本 * @param text 输入文本 * @returns 清理后的文本 */ static cleanText(text: string): string; /** * 简单的分词(按空格分割英文,按字符分割中文) * @param text 输入文本 * @returns 分词后的数组 */ static tokenize(text: string): string[]; /** * 从文本中移除停用词 * @param text 输入文本 * @returns 移除停用词后的文本 */ static removeStopWords(text: string): string; /** * 提取文本中的关键词(基于简单频率) * @param text 输入文本 * @param topN 返回的关键词数量 * @returns 关键词数组 */ static extractKeywords(text: string, topN?: number): string[]; /** * 计算两个文本之间的简单相似度 * @param text1 第一个文本 * @param text2 第二个文本 * @returns 相似度分数(0-1之间) */ static simpleSimilarity(text1: string, text2: string): number; } //#endregion //#region src/agent/skills/skill.types.d.ts type ExecutionMode = 'plan' | 'workflow' | 'direct'; interface SkillFrontmatter { /** Unique skill name, a-z0-9- recommended */ name: string; description: string; version?: string; license?: string; compatibility?: string; /** Tool names this skill is allowed to invoke */ allowedTools?: string[]; executionMode?: ExecutionMode; /** Model used for the planning step when executionMode=plan */ planningModel?: string; /** Path to workflow definition file when executionMode=workflow */ workflowRef?: string; /** ChatPreset name to activate */ preset?: string; /** Processor ids */ processors?: string[]; /** Trigger ids */ triggers?: string[]; /** * When true, this skill is protected from modification or deletion by the LLM's * self-management tools (update_skill / delete_skill / create_skill overwrite). * Set this in SKILL.md for developer-configured skills you don't want the LLM to touch. * Only a human with filesystem access can modify readonly skills. */ readonly?: boolean; metadata?: Record<string, unknown>; } interface Skill { id: string; rootDir: string; frontmatter: SkillFrontmatter; /** * Progressive disclosure: load full instruction body on demand. * Tries system-prompt.md first, falls back to SKILL.md body. */ loadInstructions(): Promise<string>; /** Read a file relative to the skill root directory */ readFile(relPath: string): Promise<Buffer>; } type SkillMeta = Pick<Skill, 'id' | 'rootDir' | 'frontmatter'>; //#endregion //#region src/agent/skills/SkillRegistry.d.ts declare class SkillRegistry { private skills; private readonly skillsDir; constructor(skillsDir: string); load(): Promise<void>; listSkillMetas(): SkillMeta[]; getSkillByName(name: string): Skill | null; getAllSkills(): Skill[]; getSkillsDir(): string; /** * Simple rule-based skill matcher. * Searches skill descriptions and names for keyword overlap with the user message. * Returns the best match, or null if no good match found. */ matchSkill(userMessage: string): Skill | null; } //#endregion //#region src/agent/background/job.types.d.ts type JobStatus = 'queued' | 'running' | 'done' | 'failed'; interface BackgroundJob { id: string; description: string; userId: string; groupId?: string; skillName?: string; conversationId?: string; /** Associated plan id if the job runs a Plan */ planId?: string; status: JobStatus; /** Final output text, available when status=done */ result?: string; error?: string; createdAt: number; updatedAt: number; } /** Payload returned by job:complete / job:failed events */ interface JobCompletePayload { jobId: string; userId: string; groupId?: string; status: 'done' | 'failed'; result?: string; error?: string; planId?: string; } /** Payload returned by job:progress events (per plan step) */ interface JobProgressPayload { jobId: string; userId: string; groupId?: string; planId?: string; stepIndex?: number; stepTotal?: number; stepTitle?: string; } //#endregion //#region src/agent/contracts.d.ts interface AgentToolCall { id: string; name: string; arguments: Record<string, unknown>; } interface ToolResult { id: string; name: string; ok: boolean; outputText: string; error?: { kind: 'RETRYABLE' | 'POLICY_DENIED' | 'FATAL'; message: string; cause?: unknown; }; meta?: Record<string, unknown>; } interface ToolSchema { name: string; description?: string; schema?: unknown; } interface ExecutionContext { runId: string; userId: string; groupId?: string; conversationId?: string; skillName?: string; jobId?: string; planId?: string; timeoutMs?: number; tags?: Record<string, string>; } interface ToolExecutor { execute(call: AgentToolCall, ctx: ExecutionContext): Promise<ToolResult>; listAvailableTools?(ctx: ExecutionContext): Promise<ToolSchema[]>; } interface SandboxOptions { timeoutMs?: number; /** Allowed env vars; empty = no env passed */ env?: Record<string, string>; maxOutputBytes?: number; } interface SandboxResult { output: string; exitCode: number; timedOut: boolean; } /** * Abstract sandbox execution contract. * Local impl: child_process with restricted env + timeout. * Remote impl: POST to a REST sandbox API. */ interface SandboxExecutor { run(entry: string, argsJson: string, opts?: SandboxOptions): Promise<SandboxResult>; } /** Minimal interface used by workflow/plan steps to avoid circular dep */ interface IBackgroundJobManager { createAndRun(spec: BackgroundJobSpec): Promise<string>; getJob(jobId: string): Promise<BackgroundJob | null>; } interface BackgroundJobSpec { description: string; userId: string; groupId?: string; skillName?: string; conversationId?: string; /** Arbitrary data for the executor to consume */ payload?: Record<string, unknown>; } /** * Runtime context passed to workflow runners and plan executors. * Injected by Chaite at execution time — avoids constructor-level circular deps. */ interface AgentRunContext { /** Send a message through the main LLM pipeline */ sendMessage(goal: string, options?: Record<string, unknown>): Promise<ModelResponse>; toolExecutor?: ToolExecutor; storage: BasicStorage<unknown>; logger: ILogger; jobManager?: IBackgroundJobManager; /** Emit a structured audit/progress event */ emitAudit?(event: AuditEvent): void; } type AuditEventType = 'tool:start' | 'tool:end' | 'tool:error' | 'job:queued' | 'job:start' | 'job:complete' | 'job:failed' | 'job:progress' | 'plan:start' | 'plan:step:start' | 'plan:step:end' | 'plan:step:revised' | 'plan:complete' | 'plan:failed'; interface AuditEvent { type: AuditEventType; timestamp: number; runId?: string; jobId?: string; planId?: string; stepId?: string; userId?: string; groupId?: string; data?: Record<string, unknown>; } interface AuditEmitter { emit(event: AuditEvent): void; } //#endregion //#region src/agent/planning/plan.types.d.ts type PlanStepStatus = 'pending' | 'running' | 'done' | 'failed' | 'skipped' | 'revised'; type PlanStatus = 'planning' | 'executing' | 'reviewing' | 'done' | 'failed'; interface PlanStep { id: string; /** 1-based display index */ index: number; /** Short title shown in progress notifications */ title: string; description: string; /** Hint about which tool to use; LLM may suggest this */ toolHint?: string; /** Step ids this step depends on */ dependsOn?: string[]; status: PlanStepStatus; /** Step output after execution */ result?: string; startedAt?: number; completedAt?: number; retryCount: number; } interface Plan { id: string; /** Associated background job id, if running asynchronously */ jobId?: string; goal: string; steps: PlanStep[]; status: PlanStatus; /** How many times the plan has been revised during execution */ revision: number; createdAt: number; updatedAt: number; } /** Compact progress snapshot for QQ push notifications */ interface PlanProgress { planId: string; goal: string; status: PlanStatus; totalSteps: number; doneSteps: number; currentStep?: { index: number; title: string; status: PlanStepStatus; }; revision: number; } declare function getPlanProgress(plan: Plan): PlanProgress; //#endregion //#region src/agent/planning/Planner.d.ts /** * Abstract Planner interface. * Takes a goal and returns a structured Plan (not yet executed). */ interface Planner {