/** * CLI Agent 基类:封装"起子进程、传 prompt、解析输出"的通用逻辑。 * 新增 CLI agent 只需继承并实现抽象方法。 */ import { type AgentBackend, type AgentSession, type AgentResponse, type SessionConfig, type AgentSessionActivity, type ExecHooks, type SessionTranscript } from "./types.js"; /** 子类 session 的基础字段 */ export interface BaseCliSession { workingDirectory: string; model?: string; /** 推理强度(low/medium/high/xhigh/max),backend 支持时透传给 CLI */ reasoningEffort?: string; importantContext?: string; /** NativeSessionId:backend 原生 id,用于 --resume。禁止放 EngineHandle。 */ agentSessionId?: string; extraEnv: Record; cumulativeBytes: number; /** 累计 compact 次数 */ compactCount: number; /** JSONL 文件上次扫描的字节偏移(用于增量扫描) */ jsonlOffset: number; } /** 子类解析输出后返回的结构 */ export interface ParsedOutput { text: string; /** 是否收到 backend 原生的正式终态事件;进程退出不等于回合完成。 */ turnCompleted: boolean; /** 回合异常结束时用于诊断的最后一段 assistant 文本。 */ lastMessage?: string; /** backend 给出的未完成原因,如缺少 agent_end / turn.completed。 */ incompleteReason?: string; /** NativeSessionId:backend 真正开场后的 id */ agentSessionId?: string; /** 本次调用的上下文 token 总数 */ contextTokens?: number; /** 模型上下文窗口大小 */ contextWindow?: number; /** 本次调用使用的模型 */ model?: string; /** 累计 compact 次数 */ compactCount?: number; /** 后端提取到的原始错误信息 */ error?: string; /** 后端明确表示本轮失败,但没有可用错误信息时由基类生成兜底文案 */ failed?: boolean; } export declare abstract class CliAgentBackend implements AgentBackend { protected name: string; protected sessions: Map; private activeProcesses; private cancelledSessions; /** 每个 session 的活动状态(watchdog 用) */ private activityMap; protected log: { debug: (msg: string, data?: Record) => void; info: (msg: string, data?: Record) => void; warn: (msg: string, data?: Record) => void; error: (msg: string, data?: Record) => void; }; constructor(name: string); /** CLI 无持久 system 能力时,由 pipeline 把 stable 前缀进首条 user */ needsStableUserPrefix(): boolean; /** compact 后是否注入恢复提醒;Cursor 由 workspace rules 承载 */ needsCompactRecoveryReminder(): boolean; /** 获取指定 session 的活动状态(供 watchdog / /list 读取) */ getActivity(sessionId: string): AgentSessionActivity | undefined; /** 子类可 override,在 getActivity 返回前刷新 recentLines 等字段 */ protected refreshActivity(_sessionId: string, _activity: AgentSessionActivity): void; /** 子类可 override,隐藏命令参数中的消息、系统提示词等敏感内容。 */ protected argsForLog(args: string[]): string[]; /** 获取所有活动状态(供 watchdog 遍历) */ getAllActivities(): ReadonlyMap; /** CLI 命令名(如 "claude"、"codex") */ abstract command(): string; /** 首次创建 session 时,构造 agent 特有的 session 字段 */ abstract buildSession(config: SessionConfig): S; /** * 构造 CLI 调用:参数 + stdin 内容。 * - 返回 stdin: 将其写入子进程 stdin * - 不返回 stdin: 不写 stdin(子进程 stdin 直接关闭) */ abstract buildInput(session: S, message: string): { args: string[]; stdin?: string; }; /** 解析 CLI 输出 → 结构化结果(可访问 session 获取额外信息) */ abstract parseOutput(stdout: string, session: S): ParsedOutput; /** 读取 backend 原生 session 记录。子类必须在接入归档前实现。 */ protected loadSessionTranscript(_session: S): Promise; /** 探测模型名是否可用:用 CLI 发送最小请求,检查 parseOutput 是否报错 */ validateModel(modelName: string): Promise<{ valid: boolean; error?: string; }>; /** 构造 probe 用的最小 session(不注册到 sessions Map,不走 activity) */ protected buildProbeSession(modelName: string): S; /** 判断 exec 抛出的错误是否表示模型不存在(默认否,子类可 override) */ protected isProbeError(_err: any): boolean; /** CLI 瞬时失败时额外重试次数;默认不重试。 */ protected transientRetryLimit(): number; /** 是否为可自动 resume 再试的瞬时 CLI 错误(网络断流等)。 */ protected isTransientCliError(_err: unknown): boolean; /** 子进程非零退出时,尽量把 stdout 里的 backend 错误提成用户可见原因。 */ private promoteExecError; /** 检查 CLI 工具是否可用(start 时调用)。默认执行 command() --version */ checkAvailable(): Promise; /** 每次执行子进程时需要额外设置的环境变量 */ protected agentEnv(): Record; /** watchdog 调用:返回 session 文件的最新 mtime(毫秒时间戳),null 表示不支持或文件不存在 */ protected probeSessionFileMtime?(_session: S): number | null; /** watchdog 调用:从 session 文件尾部读取最后一行(用于无 stdout 流的 backend) */ protected probeSessionLastLine?(_session: S): string | null; /** 子类提供 exec hooks(onLine / isComplete / onStatus) */ protected getExecHooks?(_session: S): ExecHooks; start(): Promise; stop(): Promise; createSession(config: SessionConfig): Promise; /** CLI session 可通过 nbt collab turn 提交结构化协作动作。 */ supportsCollabTurns(): boolean; refreshSessionEnv(session: AgentSession, env: { threadId?: string; replyToMsgId?: string; collabTurnToken?: string; }): void; sendMessage(agentSession: AgentSession, message: string): Promise; private sendMessageAttempt; cancelSession(session: AgentSession): Promise; private getParsedError; private buildIncompleteTurnError; closeSession(session: AgentSession): Promise; exportSessionTranscript(session: AgentSession): Promise; inspectSessionTranscript(session: AgentSession): Promise; private reapLeftoverProcess; private waitForSessionProcessExit; updateSessionModels(sessionId: string, models: { model?: string; effort?: string; }): void; getAgentSessionId(sessionId: string): string | undefined; getCumulativeBytes(sessionId: string): number; private maybeDumpAgentStdout; protected exec(cmd: string, args: string[], opts?: { cwd?: string; env?: Record; stdin?: string; }, sessionId?: string, hooks?: ExecHooks): Promise; } /** 从 SessionConfig 构造 NiuBot CLI 工具需要的环境变量 */ export declare function buildNiubotEnv(config: SessionConfig): Record;