UNPKG

autosnippet

Version:

Extract code patterns into a knowledge base for AI coding assistants

156 lines (155 loc) 5.63 kB
/** * ContextWindow — Agent 的上下文窗口管理器 * * 业界最佳实践: * - OpenAI Compaction: 阈值触发自动压缩,保留关键上下文 * - LangChain trim_messages: 按 token 裁剪,保证消息合法性 * - Anthropic 长上下文: 长文档前置,查询后置 * - Gemini API: functionResponse 必须紧跟 functionCall * * 设计不变量: * 1. messages[0] 始终是原始 user prompt(不可删除) * 2. assistant(toolCalls) 与其 tool results 是原子单元(不可拆分) * 3. 每次 AI 调用前自动压缩到 TOKEN_BUDGET 以内 * 4. 不通过追加 user 消息来控制 AI 行为(由 ExplorationTracker 管理) * * 三级递进压缩: * L1 (60-80%): 截断旧的 tool results 内容 * L2 (80-95%): 摘要历史轮次,保留最后 2 轮完整链 * L3 (>95%): 仅保留 prompt + 最后 1 轮 + 已提交列表 * * @module ContextWindow */ /** 工具调用信息 */ interface ToolCallInfo { id: string; name: string; args?: Record<string, unknown>; } /** 上下文窗口中的消息 */ export interface ContextMessage { role: 'user' | 'assistant' | 'tool'; content?: string | null; toolCalls?: ToolCallInfo[]; toolCallId?: string; name?: string; } /** 工具结果配额 */ interface ToolResultQuota { maxChars?: number; maxMatches?: number; } /** * 一组相关消息的原子单元: * - assistant(toolCalls) + 所有后续 tool results * - 或单独的 user/assistant 文本消息 */ export declare class ContextWindow { #private; /** * 模型名 → 上下文窗口大小映射(token 数)。 * 键为正则模式,按优先级从上到下匹配。 * 值为模型的原始上下文窗口上限。 */ static MODEL_CONTEXT_WINDOWS: (number | RegExp)[][]; /** * 根据模型名称解析合适的 ContextWindow token 预算。 * * 策略: 取模型最大上下文窗口的一个安全分片, * - 超大窗口 (≥400k): 预算 48000(1M 级模型可容纳更多上下文) * - 大窗口 (≥200k): 预算 32000(tool schemas + system prompt 占显著空间) * - 中窗口 (≥64k): 预算 24000 * - 小窗口 (≥16k): 预算 12000 * - 微窗口 (<16k): 预算 = 窗口 × 0.7(留 30% 给 prompt/tool schema) * * @param modelName 模型名称,如 'gemini-3-flash-preview', 'gpt-5.4-mini' * @param [opts] - isSystem 为 true 时给予更高预算 * @returns 建议的 token 预算 */ static resolveTokenBudget(modelName: string, opts?: { isSystem?: boolean; }): number; /** @param [tokenBudget=24000] token 预算上限 */ constructor(tokenBudget?: number); /** 追加用户消息 */ appendUserMessage(content: string): void; /** * 追加阶段过渡引导消息 — 轻量级 user 消息,用于在 ExplorationTracker 阶段转换时 * 向 AI 明确传达新阶段的行为期望。与 appendUserMessage 功能相同, * 独立命名以便审计和搜索。 */ appendUserNudge(content: string): void; /** * 追加 assistant 消息(含工具调用) * @param text assistant 文本 * @param toolCalls [{id, name, args}] */ appendAssistantWithToolCalls(text: string | null, toolCalls: ToolCallInfo[]): void; /** * 追加工具结果(必须紧跟 assistant toolCalls 后) * @param name 工具名 * @param content 工具返回内容(已经过 ToolResultLimiter 截断) */ appendToolResult(toolCallId: string, name: string, content: string): void; /** 追加 assistant 纯文本消息(无工具调用) */ appendAssistantText(text: string): void; /** * 在每次 AI 调用前调用 — 根据 token 使用率执行分级压缩 * * @returns } 压缩结果 */ compactIfNeeded(): { level: number; removed: number; }; /** 导出消息(供 AI Provider 使用) */ toMessages(): ContextMessage[]; /** 获取消息数量 */ get length(): number; /** 获取 token 预算 */ get tokenBudget(): number; /** 估算当前 token 使用量 */ estimateTokens(): number; /** 获取 token 使用率 (0-1) */ getTokenUsageRatio(): number; /** * 获取动态工具结果配额 * 根据当前 token 使用率返回工具结果的大小限制 * @returns } */ getToolResultQuota(): { maxChars: number; maxMatches: number; }; /** 获取压缩日志(用于调试) */ getCompactionLog(): string[]; /** 获取被压缩掉的已提交候选标题 */ getCompactedSubmits(): Set<unknown>; /** * 清空消息 — 仅保留首条 prompt * 用于致命错误后的恢复 */ resetToPromptOnly(): void; /** * Pipeline 阶段隔离 — 清空全部消息。 * * 用于 PipelineStrategy 在阶段间重置 ContextWindow: * analyze → (reset) → produce * * reactLoop 会将新阶段的 prompt 追加为 messages[0], * systemPrompt 通过 chatWithTools 参数独立传递,不受影响。 * * 保留 compactedSubmits 以支持跨阶段提交去重。 */ resetForNewStage(): void; } /** * 工具结果入口限制器 — 在工具结果进入 ContextWindow 前压缩 * * @param toolName 工具名 * @param result 工具原始返回 * @param quota 动态配额 * @returns 压缩后的结果字符串 */ export declare function limitToolResult(toolName: string, result: unknown, quota: ToolResultQuota): string; export {};