chaite
Version:
core for chatgpt-plugin and karin-plugin-chatgpt
1,715 lines (1,714 loc) • 91.6 kB
TypeScript
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 {