UNPKG

autosnippet

Version:

Extract code patterns into a knowledge base for AI coding assistants

136 lines (135 loc) 8.49 kB
/** * insight-producer.js — Insight Producer 领域函数 * * 从旧 ProducerAgent.js 提取的纯领域逻辑: * - Producer System Prompt * - 工具白名单 * - 预算常量 * - Prompt 构建器 (v1 + v2) * - 代码上下文注入 (evidenceMap → prompt section) * - 拒绝率门控 (producerRejectionGateEvaluator) * * 被 PipelineStrategy 的 bootstrap preset 直接引用。 * 不再包含任何 Agent 类 — Agent 由 AgentRuntime + PipelineStrategy 驱动。 * * @module insight-producer */ import type { EvidenceEntry } from './EvidenceCollector.js'; /** AnalysisReport 最小接口 (v1) */ interface AnalysisReportLike { analysisText: string; referencedFiles: string[]; } /** AnalysisArtifact 最小接口 (v2) */ interface AnalysisArtifactLike extends AnalysisReportLike { findings: Array<{ finding: string; evidence?: string; importance: number; }>; evidenceMap?: Map<string, EvidenceEntry>; negativeSignals: Array<{ searchPattern: string; implication: string; }>; } /** 维度配置 */ interface DimConfig { id: string; label: string; allowedKnowledgeTypes?: string[]; outputType?: string; } /** 项目基本信息 */ interface ProjectInfo { name: string; } /** reactLoop 返回值 (门控评估用) */ interface ReactLoopResult { toolCalls?: ToolCallRecord[]; } /** 工具调用记录 */ interface ToolCallRecord { tool?: string; name?: string; result?: string | { status?: string; reason?: string; }; } /** 门控策略上下文 */ interface GateStrategyContext { submitToolNames?: string[]; [key: string]: unknown; } export declare const PRODUCER_SYSTEM_PROMPT = "\u4F60\u662F\u77E5\u8BC6\u7BA1\u7406\u4E13\u5BB6\u3002\u4F60\u4F1A\u6536\u5230\u4E00\u6BB5\u4EE3\u7801\u5206\u6790\u6587\u672C\uFF0C\u9700\u8981\u5C06\u5176\u4E2D\u7684\u77E5\u8BC6\u70B9\u8F6C\u5316\u4E3A\u7ED3\u6784\u5316\u7684\u77E5\u8BC6\u5019\u9009\u3002\n\n\u6838\u5FC3\u539F\u5219: \u5206\u6790\u6587\u672C\u5DF2\u7ECF\u5305\u542B\u4E86\u6240\u6709\u53D1\u73B0\uFF0C\u4F60\u7684\u552F\u4E00\u5DE5\u4F5C\u662F\u5C06\u5B83\u4EEC\u683C\u5F0F\u5316\u4E3A submit_knowledge \u8C03\u7528\u3002\n\n\u6BCF\u4E2A\u5019\u9009\u5FC5\u987B:\n1. \u6709\u6E05\u6670\u7684\u6807\u9898 (\u63CF\u8FF0\u77E5\u8BC6\u70B9\u7684\u6838\u5FC3\uFF0C\u4F7F\u7528\u9879\u76EE\u771F\u5B9E\u7C7B\u540D\uFF0C\u4E0D\u4EE5\u9879\u76EE\u540D\u5F00\u5934)\n2. \u6709\u9879\u76EE\u7279\u5199\u98CE\u683C\u7684\u6B63\u6587 (content.markdown \u5B57\u6BB5\uFF0C\u7ED3\u5408\u4EE3\u7801\u5C55\u793A)\n3. \u6807\u6CE8\u76F8\u5173\u6587\u4EF6\u7684\u5B8C\u6574\u76F8\u5BF9\u8DEF\u5F84 + \u884C\u53F7\uFF08\u4ECE\u9879\u76EE\u6839\u76EE\u5F55\u5F00\u59CB\uFF0C\u5982 Packages/AOXNetworkKit/Sources/.../NetworkClient.swift:42\uFF09\n4. \u9009\u62E9\u6B63\u786E\u7684 kind (rule/pattern/fact)\n5. \u63D0\u4F9B\u5B8C\u6574\u7684 Cursor \u4EA4\u4ED8\u5B57\u6BB5 (trigger, doClause, whenClause \u7B49)\n6. \u6807\u6CE8\u6240\u5C5E\u6A21\u5757/\u5305\u540D\uFF08\u5982\u300C\u6240\u5C5E\u6A21\u5757: AOXNetworkKit\u300D\uFF09\uFF0C\u7279\u522B\u662F\u6765\u81EA\u672C\u5730\u5B50\u5305\u7684\u77E5\u8BC6\n\n\u5DE5\u4F5C\u6D41\u7A0B:\n1. \u9605\u8BFB\u5206\u6790\u6587\u672C\uFF0C\u8BC6\u522B\u6BCF\u4E2A\u72EC\u7ACB\u7684\u77E5\u8BC6\u70B9/\u53D1\u73B0\n2. \u7528 read_project_file \u6279\u91CF\u83B7\u53D6\u5173\u952E\u4EE3\u7801\u7247\u6BB5:\n read_project_file({ filePaths: [\"Full/Path/To/FileA.swift\", \"Full/Path/To/FileB.swift\"], maxLines: 80 })\n3. \u7ACB\u523B\u8C03\u7528 submit_knowledge \u63D0\u4EA4\n4. \u91CD\u590D\u76F4\u5230\u5206\u6790\u4E2D\u7684\u6240\u6709\u77E5\u8BC6\u70B9\u90FD\u5DF2\u63D0\u4EA4\n\n\u5173\u952E\u89C4\u5219:\n- \u5206\u6790\u4E2D\u7684\u6BCF\u4E2A\u8981\u70B9/\u6BB5\u843D\u90FD\u5E94\u8F6C\u5316\u4E3A\u81F3\u5C11\u4E00\u4E2A\u5019\u9009\n- read_project_file \u652F\u6301 filePaths \u6570\u7EC4\u6279\u91CF\u8BFB\u53D6\u591A\u4E2A\u6587\u4EF6\uFF0C\u4E00\u6B21\u8C03\u7528\u5B8C\u6210\n- read_project_file \u65F6\u8BFB\u53D6\u8DB3\u591F\u591A\u7684\u884C\u6570\uFF08startLine + maxLines \u81F3\u5C11 30 \u884C\uFF09\n- reasoning.sources \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4\uFF0C\u586B\u5199\u6587\u4EF6\u7684\u5B8C\u6574\u76F8\u5BF9\u8DEF\u5F84\u5982 [\"Packages/AOXNetworkKit/Sources/AOXNetworkKit/Client/NetworkClient.swift\"]\uFF08\u7981\u6B62\u53EA\u5199\u6587\u4EF6\u540D\uFF09\n- content.markdown \u4E2D\u7684\u6765\u6E90\u6807\u6CE8\u5FC5\u987B\u4F7F\u7528\u5B8C\u6574\u76F8\u5BF9\u8DEF\u5F84+\u884C\u53F7: (\u6765\u6E90: Full/Path/FileName.ext:\u884C\u53F7)\n- \u5982\u679C\u5206\u6790\u63D0\u5230\u4E86 3 \u4E2A\u6A21\u5F0F\uFF0C\u5C31\u5E94\u8BE5\u63D0\u4EA4 3 \u4E2A\u5019\u9009\uFF0C\u4E0D\u8981\u5408\u5E76\n- \u7981\u6B62: \u4E0D\u8981\u641C\u7D22\u65B0\u6587\u4EF6\u3001\u4E0D\u8981\u505A\u989D\u5916\u5206\u6790\uFF0C\u4E13\u6CE8\u4E8E\u683C\u5F0F\u5316\u548C\u63D0\u4EA4\n- \u3010\u8DE8\u7EF4\u5EA6\u53BB\u91CD\u3011\u6BCF\u6761\u5019\u9009\u5FC5\u987B\u805A\u7126\u5F53\u524D\u7EF4\u5EA6\u72EC\u6709\u7684\u89C6\u89D2\uFF0C\u4E0D\u5F97\u5C06\u540C\u4E00\u77E5\u8BC6\u70B9\u6362\u4E2A\u8BF4\u6CD5\u91CD\u590D\u63D0\u4EA4\u3002\u76F8\u540C\u7684\u7C7B/\u6A21\u5F0F\u53EA\u5728\u6700\u76F8\u5173\u7684\u7EF4\u5EA6\u51FA\u73B0\u4E00\u6B21\uFF0C\u5B81\u53EF\u5C11\u63D0\u4EA4\u4E5F\u4E0D\u8981\u5145\u6570\n\n\u5BB9\u9519\u89C4\u5219:\n- \u5982\u679C read_project_file \u8FD4\u56DE\"\u6587\u4EF6\u4E0D\u5B58\u5728\"\u6216\u9519\u8BEF\uFF0C\u4E0D\u8981\u91CD\u8BD5\u540C\u4E00\u6587\u4EF6\u7684\u5176\u4ED6\u8DEF\u5F84\u53D8\u4F53\n- \u6587\u4EF6\u8BFB\u53D6\u5931\u8D25\u65F6\uFF0C\u76F4\u63A5\u4F7F\u7528\u5206\u6790\u6587\u672C\u4E2D\u5DF2\u6709\u7684\u4EE3\u7801\u548C\u63CF\u8FF0\u6765\u63D0\u4EA4\u5019\u9009\n- \u6C38\u8FDC\u4E0D\u8981\u56E0\u4E3A\u6587\u4EF6\u8BFB\u53D6\u5931\u8D25\u800C\u8DF3\u8FC7\u77E5\u8BC6\u70B9 \u2014 \u5206\u6790\u6587\u672C\u5DF2\u7ECF\u5305\u542B\u8DB3\u591F\u4FE1\u606F\n- \u5148\u63D0\u4EA4\u5019\u9009\uFF0C\u518D\u8003\u8651\u662F\u5426\u9700\u8981\u8BFB\u53D6\u66F4\u591A\u4EE3\u7801\uFF08\u63D0\u4EA4\u4F18\u5148\u4E8E\u9A8C\u8BC1\uFF09"; export declare const PRODUCER_TOOLS: string[]; export declare const PRODUCER_BUDGET: { maxIterations: number; searchBudget: number; searchBudgetGrace: number; maxSubmits: number; softSubmitLimit: number; idleRoundsToExit: number; }; /** * 构建 Producer Prompt (v1 — 用于 AnalysisReport) * * @param dimConfig { id, label, allowedKnowledgeTypes, outputType } * @param projectInfo { name } */ export declare function buildProducerPrompt(analysisReport: AnalysisReportLike, dimConfig: DimConfig, projectInfo: ProjectInfo): string; /** Panorama context for Producer */ interface ProducerPanoramaContext { moduleRole: string | null; moduleLayer: number | null; knownGaps: string[]; layerContext: string | null; } /** Rescan context for Producer — gap info + existing recipe titles */ interface ProducerRescanContext { existingRecipes: Array<{ title: string; trigger: string; }>; decayingRecipes?: Array<{ id?: string; title: string; trigger: string; decayReason?: string; }>; occupiedTriggers: string[]; gap: number; existing: number; } /** * 构建 Producer Prompt v2 — 用于 AnalysisArtifact * * 相比 v1 增加: * - §3 结构化发现 (findings) * - §4 代码证据 (evidenceMap → code context) * - §5 负空间信号 * - §9 (可选) Rescan 模式约束 * - §M1 (可选) 全景上下文 */ export declare function buildProducerPromptV2(artifact: AnalysisArtifactLike, dimConfig: DimConfig, projectInfo: ProjectInfo, rescanContext?: ProducerRescanContext | null, panorama?: ProducerPanoramaContext | null): string; /** * 从 evidenceMap 构建代码上下文段 * * 策略: 按代码片段数量排序 * 预算: ≤ 4000 chars (~1000 tokens) */ export declare function buildCodeContextSection(evidenceMap: Map<string, EvidenceEntry> | null | undefined): string | null; /** * Producer 拒绝率门控 — 面向 PipelineStrategy gate.evaluator * * 当 produce 阶段的提交拒绝率过高时触发 retry。 * * @param source produce 阶段的 reactLoop 返回值 * @returns } */ export declare function producerRejectionGateEvaluator(source: ReactLoopResult | null | undefined, _phaseResults: unknown, _strategyContext?: GateStrategyContext): { action: string; reason: string; }; export {};