autosnippet 3.2.7 → 3.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +13 -5
- package/dashboard/dist/assets/index-BTAsOZv2.js +128 -0
- package/dashboard/dist/assets/index-C_72Ct98.css +1 -0
- package/dashboard/dist/index.html +2 -2
- package/lib/cli/AiScanService.js +26 -29
- package/lib/cli/SetupService.js +1 -1
- package/lib/core/AstAnalyzer.js +27 -5
- package/lib/core/analysis/CallEdgeResolver.js +402 -0
- package/lib/core/analysis/CallGraphAnalyzer.js +367 -0
- package/lib/core/analysis/CallSiteExtractor.js +629 -0
- package/lib/core/analysis/DataFlowInferrer.js +57 -0
- package/lib/core/analysis/ImportPathResolver.js +189 -0
- package/lib/core/analysis/ImportRecord.js +105 -0
- package/lib/core/analysis/SymbolTableBuilder.js +211 -0
- package/lib/core/ast/ProjectGraph.js +8 -0
- package/lib/core/ast/lang-dart.js +352 -5
- package/lib/core/ast/lang-go.js +212 -10
- package/lib/core/ast/lang-java.js +205 -1
- package/lib/core/ast/lang-kotlin.js +330 -1
- package/lib/core/ast/lang-python.js +31 -2
- package/lib/core/ast/lang-rust.js +284 -3
- package/lib/core/ast/lang-swift.js +180 -1
- package/lib/core/ast/lang-typescript.js +290 -1
- package/lib/core/discovery/index.js +2 -2
- package/lib/external/ai/AiProvider.js +66 -172
- package/lib/external/ai/providers/GoogleGeminiProvider.js +23 -1
- package/lib/external/mcp/McpServer.js +1 -0
- package/lib/external/mcp/handlers/bootstrap/BootstrapSession.js +1 -1
- package/lib/external/mcp/handlers/bootstrap/ExternalSubmissionTracker.js +3 -3
- package/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.js +22 -1
- package/lib/external/mcp/handlers/bootstrap/pipeline/IncrementalBootstrap.js +1 -1
- package/lib/external/mcp/handlers/bootstrap/pipeline/dimension-configs.js +2 -1
- package/lib/external/mcp/handlers/bootstrap/pipeline/dimension-context.js +8 -8
- package/lib/external/mcp/handlers/bootstrap/pipeline/noAiFallback.js +1 -1
- package/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +311 -162
- package/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +102 -7
- package/lib/external/mcp/handlers/bootstrap/shared/dimension-sop.js +1 -1
- package/lib/external/mcp/handlers/bootstrap-external.js +9 -2
- package/lib/external/mcp/handlers/bootstrap-internal.js +19 -8
- package/lib/external/mcp/handlers/consolidated.js +9 -0
- package/lib/external/mcp/handlers/dimension-complete-external.js +6 -6
- package/lib/external/mcp/handlers/guard.js +3 -3
- package/lib/external/mcp/handlers/structure.js +62 -0
- package/lib/external/mcp/handlers/wiki-external.js +66 -3
- package/lib/external/mcp/tools.js +36 -1
- package/lib/http/HttpServer.js +1 -1
- package/lib/http/middleware/requestLogger.js +1 -0
- package/lib/http/routes/ai.js +240 -35
- package/lib/http/routes/candidates.js +2 -3
- package/lib/http/routes/extract.js +13 -11
- package/lib/http/routes/modules.js +2 -2
- package/lib/http/routes/recipes.js +9 -5
- package/lib/http/routes/remote.js +149 -270
- package/lib/http/routes/violations.js +0 -54
- package/lib/http/utils/sse-sessions.js +1 -1
- package/lib/infrastructure/logging/Logger.js +5 -4
- package/lib/infrastructure/monitoring/PerformanceMonitor.js +3 -2
- package/lib/injection/ServiceContainer.js +70 -28
- package/lib/platform/ScreenCaptureService.js +177 -0
- package/lib/platform/ios/index.js +2 -2
- package/lib/platform/ios/routes/spm.js +2 -2
- package/lib/platform/ios/spm/PackageSwiftParser.js +14 -3
- package/lib/platform/ios/spm/SpmDiscoverer.js +123 -17
- package/lib/platform/ios/spm/{SpmService.js → SpmHelper.js} +43 -675
- package/lib/platform/ios/xcode/XcodeWriteUtils.js +1 -1
- package/lib/service/agent/AgentEventBus.js +207 -0
- package/lib/service/agent/AgentFactory.js +490 -0
- package/lib/service/agent/AgentMessage.js +240 -0
- package/lib/service/agent/AgentRouter.js +228 -0
- package/lib/service/agent/AgentRuntime.js +1016 -0
- package/lib/service/agent/AgentState.js +217 -0
- package/lib/service/agent/IntentClassifier.js +331 -0
- package/lib/service/agent/LarkTransport.js +389 -0
- package/lib/service/agent/capabilities.js +408 -0
- package/lib/service/{chat → agent/context}/ContextWindow.js +37 -12
- package/lib/service/{chat → agent/context}/ExplorationTracker.js +77 -22
- package/lib/service/{chat → agent/core}/ChatAgentPrompts.js +14 -2
- package/lib/service/agent/core/LoopContext.js +170 -0
- package/lib/service/agent/core/MessageAdapter.js +223 -0
- package/lib/service/agent/core/ToolExecutionPipeline.js +376 -0
- package/lib/service/{chat → agent/domain}/ChatAgentTasks.js +19 -98
- package/lib/service/{chat → agent/domain}/EpisodicConsolidator.js +7 -7
- package/lib/service/{chat → agent/domain}/EvidenceCollector.js +4 -2
- package/lib/service/{chat/AnalystAgent.js → agent/domain/insight-analyst.js} +37 -172
- package/lib/service/{chat/HandoffProtocol.js → agent/domain/insight-gate.js} +91 -123
- package/lib/service/agent/domain/insight-producer.js +267 -0
- package/lib/service/agent/domain/scan-prompts.js +105 -0
- package/lib/service/agent/forced-summary.js +266 -0
- package/lib/service/agent/index.js +91 -0
- package/lib/service/{chat → agent}/memory/ActiveContext.js +3 -1
- package/lib/service/{chat → agent}/memory/MemoryCoordinator.js +7 -7
- package/lib/service/{chat/ProjectSemanticMemory.js → agent/memory/PersistentMemory.js} +359 -89
- package/lib/service/{chat → agent}/memory/SessionStore.js +5 -4
- package/lib/service/{chat → agent}/memory/index.js +1 -1
- package/lib/service/agent/policies.js +442 -0
- package/lib/service/agent/presets.js +303 -0
- package/lib/service/agent/strategies.js +717 -0
- package/lib/service/{chat → agent/tools}/ToolRegistry.js +3 -3
- package/lib/service/agent/tools/ai-analysis.js +75 -0
- package/lib/service/{chat → agent}/tools/ast-graph.js +229 -32
- package/lib/service/{chat → agent}/tools/composite.js +2 -1
- package/lib/service/{chat → agent}/tools/guard.js +1 -121
- package/lib/service/{chat → agent}/tools/index.js +33 -22
- package/lib/service/{chat → agent}/tools/infrastructure.js +6 -1
- package/lib/service/agent/tools/knowledge-graph.js +112 -0
- package/lib/service/agent/tools/scan-recipe.js +189 -0
- package/lib/service/agent/tools/system-interaction.js +476 -0
- package/lib/service/automation/DirectiveDetector.js +0 -1
- package/lib/service/automation/FileWatcher.js +0 -8
- package/lib/service/automation/handlers/CreateHandler.js +7 -3
- package/lib/service/automation/handlers/DraftHandler.js +7 -6
- package/lib/service/cursor/CursorDeliveryPipeline.js +167 -1
- package/lib/service/knowledge/CodeEntityGraph.js +327 -2
- package/lib/service/knowledge/KnowledgeService.js +5 -1
- package/lib/service/module/ModuleService.js +49 -73
- package/lib/service/skills/SignalCollector.js +26 -19
- package/lib/service/snippet/codecs/VSCodeCodec.js +1 -1
- package/lib/service/wiki/WikiGenerator.js +1 -1
- package/lib/shared/FieldSpec.js +1 -1
- package/lib/shared/PathGuard.js +1 -1
- package/lib/shared/StyleGuide.js +1 -1
- package/package.json +4 -1
- package/resources/native-ui/screenshot.swift +228 -0
- package/dashboard/dist/assets/index-BaGY7kJI.css +0 -1
- package/dashboard/dist/assets/index-DfHY_3ln.js +0 -128
- package/lib/core/discovery/SpmDiscoverer.js +0 -5
- package/lib/external/mcp/handlers/bootstrap/pipeline/EpisodicMemory.js +0 -749
- package/lib/external/mcp/handlers/bootstrap/pipeline/ToolResultCache.js +0 -277
- package/lib/http/routes/spm.js +0 -5
- package/lib/infrastructure/external/XcodeAutomation.js +0 -15
- package/lib/service/chat/ChatAgent.js +0 -1602
- package/lib/service/chat/Memory.js +0 -161
- package/lib/service/chat/ProducerAgent.js +0 -431
- package/lib/service/chat/ReasoningTrace.js +0 -523
- package/lib/service/chat/TaskPipeline.js +0 -357
- package/lib/service/chat/WorkingMemory.js +0 -357
- package/lib/service/chat/memory/PersistentMemory.js +0 -450
- package/lib/service/chat/tools/ai-analysis.js +0 -267
- package/lib/service/chat/tools/knowledge-graph.js +0 -234
- package/lib/service/chat/tools.js +0 -18
- package/lib/service/snippet/PlaceholderConverter.js +0 -5
- package/lib/service/snippet/codecs/XcodeCodec.js +0 -5
- /package/lib/service/{chat → agent}/ConversationStore.js +0 -0
- /package/lib/service/{chat → agent}/tools/_shared.js +0 -0
- /package/lib/service/{chat → agent}/tools/lifecycle.js +0 -0
- /package/lib/service/{chat → agent}/tools/project-access.js +0 -0
- /package/lib/service/{chat → agent}/tools/query.js +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 合并了三个原本各自为政的系统:
|
|
5
5
|
* 1. PhaseRouter (ContextWindow.js) — 阶段状态机
|
|
6
|
-
* 2. 探索进度追踪 (
|
|
6
|
+
* 2. 探索进度追踪 (原内联逻辑) — 信息增量检测
|
|
7
7
|
* 3. ReasoningLayer 行为控制部分 — 反思/规划/停滞 nudge
|
|
8
8
|
*
|
|
9
9
|
* 职责:
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* @module ExplorationTracker
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
-
import Logger from '
|
|
24
|
+
import Logger from '../../../infrastructure/logging/Logger.js';
|
|
25
25
|
|
|
26
26
|
// ─── 常量 ──────────────────────────────────────────────
|
|
27
27
|
|
|
@@ -36,14 +36,14 @@ const DEFAULT_REPLAN_INTERVAL = 8;
|
|
|
36
36
|
/** 默认偏差阈值 */
|
|
37
37
|
const DEFAULT_DEVIATION_THRESHOLD = 0.6;
|
|
38
38
|
/** 默认最少探索轮次(冷启动质量保障) */
|
|
39
|
-
const DEFAULT_MIN_EXPLORE_ITERS =
|
|
39
|
+
const DEFAULT_MIN_EXPLORE_ITERS = 10;
|
|
40
40
|
/** 默认停滞收敛阈值 */
|
|
41
41
|
const DEFAULT_CONVERGENCE_STALE_THRESHOLD = 3;
|
|
42
42
|
|
|
43
43
|
// ─── 内置策略 ────────────────────────────────────────────
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
* Bootstrap
|
|
46
|
+
* Bootstrap 策略(有 submit 阶段)
|
|
47
47
|
* @param {boolean} isSkillOnly — skill-only 维度跳过 PRODUCE 阶段
|
|
48
48
|
* @returns {object} 策略配置
|
|
49
49
|
*/
|
|
@@ -168,6 +168,8 @@ const SEARCH_TOOLS = new Set([
|
|
|
168
168
|
'list_project_structure',
|
|
169
169
|
'get_project_overview',
|
|
170
170
|
'get_file_summary',
|
|
171
|
+
'query_code_graph',
|
|
172
|
+
'query_call_graph',
|
|
171
173
|
]);
|
|
172
174
|
|
|
173
175
|
// ─── ExplorationTracker 主类 ─────────────────────────────
|
|
@@ -232,7 +234,18 @@ export class ExplorationTracker {
|
|
|
232
234
|
*/
|
|
233
235
|
constructor(strategy, budget) {
|
|
234
236
|
this.#strategy = strategy;
|
|
235
|
-
|
|
237
|
+
// 合并默认值: PipelineStrategy 创建 per-stage tracker 时,
|
|
238
|
+
// budget 可能仅含 maxIterations/temperature (来自 stage.budget),
|
|
239
|
+
// 需要补全 tracker 所需的 searchBudget、maxSubmits 等字段。
|
|
240
|
+
this.#budget = {
|
|
241
|
+
maxIterations: 24,
|
|
242
|
+
searchBudget: 18,
|
|
243
|
+
searchBudgetGrace: 10,
|
|
244
|
+
maxSubmits: 10,
|
|
245
|
+
softSubmitLimit: 8,
|
|
246
|
+
idleRoundsToExit: 3,
|
|
247
|
+
...budget,
|
|
248
|
+
};
|
|
236
249
|
this.#phase = strategy.phases[0];
|
|
237
250
|
this.#logger = Logger.getInstance();
|
|
238
251
|
}
|
|
@@ -241,7 +254,7 @@ export class ExplorationTracker {
|
|
|
241
254
|
|
|
242
255
|
/**
|
|
243
256
|
* 根据调用参数解析应使用的策略
|
|
244
|
-
* @param {object} opts —
|
|
257
|
+
* @param {object} opts — AgentRuntime execute 的选项
|
|
245
258
|
* @param {object} budget — 预算配置
|
|
246
259
|
* @returns {ExplorationTracker|null} — User 模式返回 null
|
|
247
260
|
*/
|
|
@@ -334,7 +347,7 @@ export class ExplorationTracker {
|
|
|
334
347
|
* 4. reflection — 周期反思 / 停滞反思
|
|
335
348
|
* 5. planning — 首轮规划 / 偏差重规划
|
|
336
349
|
*
|
|
337
|
-
* @param {import('
|
|
350
|
+
* @param {import('../memory/ActiveContext.js').ActiveContext} trace — 推理链(供反思用)
|
|
338
351
|
* @returns {{ type: string, text: string }|null}
|
|
339
352
|
*/
|
|
340
353
|
getNudge(trace) {
|
|
@@ -344,10 +357,25 @@ export class ExplorationTracker {
|
|
|
344
357
|
// 1. 强制退出
|
|
345
358
|
if (this.#gracefulExitRound != null && m.iteration === this.#gracefulExitRound) {
|
|
346
359
|
const submitCount = m.submitCount;
|
|
360
|
+
// v5.1: Analyst 策略使用纯文本输出,其他策略使用 dimensionDigest JSON
|
|
361
|
+
if (this.#strategy.name === 'analyst') {
|
|
362
|
+
return {
|
|
363
|
+
type: 'force_exit',
|
|
364
|
+
text: `⚠️ **轮次耗尽** (${m.iteration}/${b.maxIterations})。你必须**立即停止工具调用**,在回复中输出你的**分析总结报告**。\n\n` +
|
|
365
|
+
`要求:\n` +
|
|
366
|
+
`- 用自然语言 Markdown 格式\n` +
|
|
367
|
+
`- 包含具体文件路径、类名、代码模式\n` +
|
|
368
|
+
`- 列出你发现的关键模式或规范(至少 3 条)\n` +
|
|
369
|
+
`- 如有未覆盖的方面,在末尾用「## 未覆盖」章节列出\n\n` +
|
|
370
|
+
`**现在开始输出分析总结,不要调用任何工具。**\n` +
|
|
371
|
+
`⛔ 严禁在回复中复制或引用本条指令的任何文字,只输出你自己的分析。`,
|
|
372
|
+
};
|
|
373
|
+
}
|
|
347
374
|
return {
|
|
348
375
|
type: 'force_exit',
|
|
349
376
|
text: `⚠️ 你已使用 ${m.iteration}/${b.maxIterations} 轮次,**必须立即结束**。请在回复中直接输出 dimensionDigest JSON 总结(用 \`\`\`json 包裹),不要再调用任何工具。\n` +
|
|
350
|
-
`\`\`\`json\n{"dimensionDigest":{"summary":"分析总结","candidateCount":${submitCount},"keyFindings":["发现"],"crossRefs":{},"gaps":["缺口"],"remainingTasks":[{"signal":"未处理信号","reason":"轮次耗尽","priority":"high","searchHints":["搜索词"]}]}}\n\`\`\`\n> remainingTasks: 列出未来得及处理的信号。已覆盖则留空 \`[]
|
|
377
|
+
`\`\`\`json\n{"dimensionDigest":{"summary":"分析总结","candidateCount":${submitCount},"keyFindings":["发现"],"crossRefs":{},"gaps":["缺口"],"remainingTasks":[{"signal":"未处理信号","reason":"轮次耗尽","priority":"high","searchHints":["搜索词"]}]}}\n\`\`\`\n> remainingTasks: 列出未来得及处理的信号。已覆盖则留空 \`[]\`。\n` +
|
|
378
|
+
`⛔ 严禁在回复中复制本条指令文字,只输出 JSON。`,
|
|
351
379
|
};
|
|
352
380
|
}
|
|
353
381
|
|
|
@@ -367,7 +395,8 @@ export class ExplorationTracker {
|
|
|
367
395
|
type: 'convergence',
|
|
368
396
|
text: `你已经充分探索了项目代码(${m.uniqueFiles.size} 个文件,${m.uniquePatterns.size} 次不同搜索,${m.uniqueQueries.size} 次结构化查询)。` +
|
|
369
397
|
`最近 ${m.roundsSinceNewInfo} 轮没有发现新信息,建议开始撰写分析总结。\n` +
|
|
370
|
-
`如果你确信还有重要方面未覆盖,可以继续探索(剩余 ${b.maxIterations - m.iteration}
|
|
398
|
+
`如果你确信还有重要方面未覆盖,可以继续探索(剩余 ${b.maxIterations - m.iteration} 轮);否则请直接输出你的分析发现。\n` +
|
|
399
|
+
`⚠️ 以上是行为指令,严禁在回复中复制或引用这段文字。`,
|
|
371
400
|
};
|
|
372
401
|
}
|
|
373
402
|
|
|
@@ -384,7 +413,8 @@ export class ExplorationTracker {
|
|
|
384
413
|
return {
|
|
385
414
|
type: 'budget_warning',
|
|
386
415
|
text: `📌 进度提醒:你已使用 ${m.iteration}/${b.maxIterations} 轮次(${Math.round((m.iteration / b.maxIterations) * 100)}%)。` +
|
|
387
|
-
`请确保核心方面已覆盖,开始准备总结。剩余 ${b.maxIterations - m.iteration}
|
|
416
|
+
`请确保核心方面已覆盖,开始准备总结。剩余 ${b.maxIterations - m.iteration} 轮,优先填补最重要的分析空白。\n` +
|
|
417
|
+
`⚠️ 以上是行为指令,严禁在回复中复制或引用这段文字。`,
|
|
388
418
|
};
|
|
389
419
|
}
|
|
390
420
|
|
|
@@ -440,7 +470,7 @@ export class ExplorationTracker {
|
|
|
440
470
|
|
|
441
471
|
/**
|
|
442
472
|
* 记录一次工具调用结果,更新内部指标
|
|
443
|
-
*
|
|
473
|
+
* 替代原内联的 ~120 行 if-else 逻辑
|
|
444
474
|
*
|
|
445
475
|
* @param {string} toolName
|
|
446
476
|
* @param {object} args
|
|
@@ -451,8 +481,8 @@ export class ExplorationTracker {
|
|
|
451
481
|
this.#metrics.totalToolCalls++;
|
|
452
482
|
const isNew = this.#detectNewInfo(toolName, args, result);
|
|
453
483
|
|
|
454
|
-
// Submit
|
|
455
|
-
if (toolName === 'submit_knowledge' || toolName === 'submit_with_check') {
|
|
484
|
+
// Submit 追踪(只记成功提交)— 含 scan 阶段的 collect_scan_recipe
|
|
485
|
+
if (toolName === 'submit_knowledge' || toolName === 'submit_with_check' || toolName === 'collect_scan_recipe') {
|
|
456
486
|
const status = typeof result === 'object' ? result?.status : 'ok';
|
|
457
487
|
const isRejected = status === 'rejected';
|
|
458
488
|
const isError = status === 'error';
|
|
@@ -540,12 +570,17 @@ export class ExplorationTracker {
|
|
|
540
570
|
if (isTerminal && transitioned) {
|
|
541
571
|
// 刚转入终结阶段 → 需要 digest nudge,不是最终回答
|
|
542
572
|
const submitCount = m.submitCount;
|
|
573
|
+
// v5.1: Analyst 策略要求自然语言输出
|
|
574
|
+
const nudge = this.#strategy.name === 'analyst'
|
|
575
|
+
? `请**停止调用工具**,直接输出你的完整分析报告。用 Markdown 格式,包含具体文件路径、类名和代码模式。至少涵盖 3 个核心发现。\n\n**现在开始输出你的分析报告。**\n⚠️ 严禁在回复中复制本条指令文字,只输出你自己的分析。`
|
|
576
|
+
: `请在回复中直接输出 dimensionDigest JSON 总结(用 \`\`\`json 包裹):\n` +
|
|
577
|
+
`\`\`\`json\n{"dimensionDigest":{"summary":"分析总结(100-200字)","candidateCount":${submitCount},"keyFindings":["关键发现"],"crossRefs":{},"gaps":["未覆盖方面"],"remainingTasks":[{"signal":"未处理的信号/主题","reason":"未完成原因","priority":"high|medium|low","searchHints":["建议搜索词"]}]}}\n\`\`\`\n> 如果所有信号都已覆盖,remainingTasks 留空数组 \`[]\`。\n` +
|
|
578
|
+
`⚠️ 严禁在回复中复制本条指令文字,只输出 JSON。`;
|
|
543
579
|
return {
|
|
544
580
|
isFinalAnswer: false,
|
|
545
581
|
needsDigestNudge: true,
|
|
546
582
|
shouldContinue: true,
|
|
547
|
-
nudge
|
|
548
|
-
`\`\`\`json\n{"dimensionDigest":{"summary":"分析总结(100-200字)","candidateCount":${submitCount},"keyFindings":["关键发现"],"crossRefs":{},"gaps":["未覆盖方面"],"remainingTasks":[{"signal":"未处理的信号/主题","reason":"未完成原因","priority":"high|medium|low","searchHints":["建议搜索词"]}]}}\n\`\`\`\n> 如果所有信号都已覆盖,remainingTasks 留空数组 \`[]\`。`,
|
|
583
|
+
nudge,
|
|
549
584
|
};
|
|
550
585
|
}
|
|
551
586
|
|
|
@@ -638,7 +673,7 @@ export class ExplorationTracker {
|
|
|
638
673
|
|
|
639
674
|
/**
|
|
640
675
|
* 检测工具调用是否产生了新信息
|
|
641
|
-
*
|
|
676
|
+
* 合并了原内联的探索追踪 + ReasoningLayer.buildObservationMeta 的逻辑
|
|
642
677
|
*
|
|
643
678
|
* @param {string} toolName
|
|
644
679
|
* @param {object} args
|
|
@@ -717,7 +752,9 @@ export class ExplorationTracker {
|
|
|
717
752
|
case 'get_class_hierarchy':
|
|
718
753
|
case 'get_protocol_info':
|
|
719
754
|
case 'get_method_overrides':
|
|
720
|
-
case 'get_category_map':
|
|
755
|
+
case 'get_category_map':
|
|
756
|
+
case 'query_code_graph':
|
|
757
|
+
case 'query_call_graph': {
|
|
721
758
|
const queryTarget =
|
|
722
759
|
args?.className || args?.protocolName || args?.name || '';
|
|
723
760
|
const qKey = `${toolName}:${queryTarget}`;
|
|
@@ -840,8 +877,21 @@ export class ExplorationTracker {
|
|
|
840
877
|
|
|
841
878
|
if (toPhase === 'SUMMARIZE') {
|
|
842
879
|
const submitCount = m.submitCount;
|
|
880
|
+
// v5.1: Analyst 策略使用纯文本输出
|
|
881
|
+
if (this.#strategy.name === 'analyst') {
|
|
882
|
+
return `你已完成分析探索。请**停止调用工具**,直接输出你的**完整分析报告**。\n\n` +
|
|
883
|
+
`要求:\n` +
|
|
884
|
+
`- 用 Markdown 格式组织内容(二级/三级标题)\n` +
|
|
885
|
+
`- 包含具体的文件路径、类名、方法名、代码模式\n` +
|
|
886
|
+
`- 每个关键发现都要给出证据(文件路径 + 代码片段或行为描述)\n` +
|
|
887
|
+
`- 至少涵盖 3 个核心发现\n` +
|
|
888
|
+
`- 如有未覆盖的方面,在末尾用 「## 待探索」 章节列出\n\n` +
|
|
889
|
+
`**现在开始输出你的分析报告。不要再调用任何工具。**\n` +
|
|
890
|
+
`⚠️ 以上是行为指令,严禁在回复中复制或引用这段文字,只输出你自己的分析内容。`;
|
|
891
|
+
}
|
|
843
892
|
return `你已完成分析探索。请在回复中直接输出 dimensionDigest JSON(用 \`\`\`json 包裹),包含以下字段:\n` +
|
|
844
|
-
`\`\`\`json\n{"dimensionDigest":{"summary":"分析总结(100-200字)","candidateCount":${submitCount},"keyFindings":["关键发现"],"crossRefs":{},"gaps":["未覆盖方面"],"remainingTasks":[{"signal":"未处理的信号/主题","reason":"未完成原因(如:提交上限已达)","priority":"high|medium|low","searchHints":["建议搜索词"]}]}}\n\`\`\`\n> 如果所有信号都已覆盖,remainingTasks 留空数组 \`[]
|
|
893
|
+
`\`\`\`json\n{"dimensionDigest":{"summary":"分析总结(100-200字)","candidateCount":${submitCount},"keyFindings":["关键发现"],"crossRefs":{},"gaps":["未覆盖方面"],"remainingTasks":[{"signal":"未处理的信号/主题","reason":"未完成原因(如:提交上限已达)","priority":"high|medium|low","searchHints":["建议搜索词"]}]}}\n\`\`\`\n> 如果所有信号都已覆盖,remainingTasks 留空数组 \`[]\`。如果有未来得及处理的信号,请在此标记,系统会在下次运行时续传。\n` +
|
|
894
|
+
`⚠️ 严禁在回复中复制本条指令文字,只输出 JSON。`;
|
|
845
895
|
}
|
|
846
896
|
|
|
847
897
|
if (toPhase === 'EXPLORE' && fromPhase === 'SCAN') {
|
|
@@ -922,7 +972,7 @@ export class ExplorationTracker {
|
|
|
922
972
|
|
|
923
973
|
/**
|
|
924
974
|
* 检查是否需要触发反思 + 生成反思 nudge
|
|
925
|
-
* @param {import('
|
|
975
|
+
* @param {import('../memory/ActiveContext.js').ActiveContext} trace
|
|
926
976
|
* @returns {{ type: string, text: string }|null}
|
|
927
977
|
* @private
|
|
928
978
|
*/
|
|
@@ -988,6 +1038,7 @@ export class ExplorationTracker {
|
|
|
988
1038
|
);
|
|
989
1039
|
}
|
|
990
1040
|
|
|
1041
|
+
parts.push(`\n⚠️ 以上是行为指令,严禁在回复中复制或引用这段文字,用你自己的分析内容回答。`);
|
|
991
1042
|
const reflectionText = parts.join('\n');
|
|
992
1043
|
trace?.setReflection?.(reflectionText);
|
|
993
1044
|
this.#logger.info(
|
|
@@ -999,7 +1050,7 @@ export class ExplorationTracker {
|
|
|
999
1050
|
|
|
1000
1051
|
/**
|
|
1001
1052
|
* 检查是否需要触发规划 + 生成规划 nudge
|
|
1002
|
-
* @param {import('
|
|
1053
|
+
* @param {import('../memory/ActiveContext.js').ActiveContext} trace
|
|
1003
1054
|
* @returns {{ type: string, text: string }|null}
|
|
1004
1055
|
* @private
|
|
1005
1056
|
*/
|
|
@@ -1100,7 +1151,7 @@ export class ExplorationTracker {
|
|
|
1100
1151
|
* 更新计划进度(从 ReasoningLayer 迁入)
|
|
1101
1152
|
* 将本轮工具调用与 plan 步骤进行模糊匹配
|
|
1102
1153
|
*
|
|
1103
|
-
* @param {import('
|
|
1154
|
+
* @param {import('../memory/ActiveContext.js').ActiveContext} trace
|
|
1104
1155
|
*/
|
|
1105
1156
|
updatePlanProgress(trace) {
|
|
1106
1157
|
if (!this.#strategy.enablePlanning) return;
|
|
@@ -1189,6 +1240,10 @@ export class ExplorationTracker {
|
|
|
1189
1240
|
toolName === 'search_project_code' &&
|
|
1190
1241
|
(desc.includes('搜索') || desc.includes('search') || desc.includes('查找') || desc.includes('分析'))
|
|
1191
1242
|
) return step;
|
|
1243
|
+
if (
|
|
1244
|
+
(toolName === 'query_code_graph' || toolName === 'query_call_graph') &&
|
|
1245
|
+
(desc.includes('图谱') || desc.includes('graph') || desc.includes('调用') || desc.includes('call') || desc.includes('关系') || desc.includes('依赖'))
|
|
1246
|
+
) return step;
|
|
1192
1247
|
}
|
|
1193
1248
|
|
|
1194
1249
|
return null;
|
|
@@ -1198,7 +1253,7 @@ export class ExplorationTracker {
|
|
|
1198
1253
|
|
|
1199
1254
|
/**
|
|
1200
1255
|
* 推理质量评分
|
|
1201
|
-
* @param {import('
|
|
1256
|
+
* @param {import('../memory/ActiveContext.js').ActiveContext} trace
|
|
1202
1257
|
* @returns {{ score: number, breakdown: object }}
|
|
1203
1258
|
*/
|
|
1204
1259
|
getQualityMetrics(trace) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ChatAgentPrompts —
|
|
2
|
+
* ChatAgentPrompts — Agent 提示词构建和文本处理方法
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import fs from 'node:fs';
|
|
@@ -83,7 +83,12 @@ submit_knowledge 的 code 字段必须是「项目特写」— 将技术的基
|
|
|
83
83
|
- 代码必须真实,来自工具返回,不可编造
|
|
84
84
|
- 引用具体类名、方法名、数字,禁止「本模块」「该文件」等泛化描述
|
|
85
85
|
- 质量优先于数量,证据不足宁可不提交
|
|
86
|
-
- 高效利用步数 (≤${budget.maxIterations} 轮)
|
|
86
|
+
- 高效利用步数 (≤${budget.maxIterations} 轮)
|
|
87
|
+
|
|
88
|
+
## 严禁透传指令
|
|
89
|
+
你会收到系统发来的进度提醒和阶段引导,这些是行为指令,不是问题。
|
|
90
|
+
**绝对禁止**在回复中复制、改写或引用这些系统指令的任何文字。
|
|
91
|
+
你的回复必须只包含你自己的分析内容或工具调用。`;
|
|
87
92
|
}
|
|
88
93
|
|
|
89
94
|
/**
|
|
@@ -142,6 +147,13 @@ export function cleanFinalAnswer(response) {
|
|
|
142
147
|
return response
|
|
143
148
|
.replace(/^(Final Answer|最终回答|Answer)\s*[::]\s*/i, '')
|
|
144
149
|
.replace(/\[MEMORY:\w+\]\s*[\s\S]*?\s*\[\/MEMORY\]/g, '')
|
|
150
|
+
// v5.1: 清理 AI 回显的 nudge 指令(常见于 force-exit 场景)
|
|
151
|
+
.replace(/^>\s*(?:searchHints|remainingTasks|candidateCount|crossRefs|keyFindings|gaps)\s*[::][^\n]*\n?/gm, '')
|
|
152
|
+
.replace(/^\*{0,2}(?:请在|请直接|请确保|请务必|现在开始|输出你的|不要输出|不要再|不要包含|重要\s*[::]).*(?:分析文本|分析总结|JSON|工具|输出|文本|报告)\*{0,2}[。.]?\s*$/gm, '')
|
|
153
|
+
.replace(/^注意[::]\s*到达第\s*\d+\s*轮时.*$/gm, '')
|
|
154
|
+
.replace(/^第\s*\d+\/\d+\s*轮\s*\|[^\n]*$/gm, '')
|
|
155
|
+
// 清理 dimensionDigest JSON 块(Analyst 回显)
|
|
156
|
+
.replace(/```json\s*\n\s*\{\s*"dimensionDigest"\s*:[\s\S]*?\n```/g, '')
|
|
145
157
|
.replace(/\n{3,}/g, '\n\n')
|
|
146
158
|
.trim();
|
|
147
159
|
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LoopContext — reactLoop 单次执行的完整状态
|
|
3
|
+
*
|
|
4
|
+
* 封装原 reactLoop 内散落的 10+ 局部变量:
|
|
5
|
+
* - 注入依赖 (messages, tracker, trace, memoryCoordinator, sharedState)
|
|
6
|
+
* - 循环状态 (iteration, lastReply, toolCalls, tokenUsage)
|
|
7
|
+
* - 错误恢复 (consecutiveAiErrors, consecutiveEmptyResponses)
|
|
8
|
+
* - 配置 (source, budget, capabilities, baseSystemPrompt, toolSchemas, prompt)
|
|
9
|
+
*
|
|
10
|
+
* 使 reactLoop 的提取方法只需接收一个 ctx 参数。
|
|
11
|
+
*
|
|
12
|
+
* @module core/LoopContext
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {Object} LoopContextConfig
|
|
17
|
+
* @property {import('./MessageAdapter.js').MessageAdapter} messages — 统一消息适配器
|
|
18
|
+
* @property {Object|null} [tracker] — ExplorationTracker 实例
|
|
19
|
+
* @property {Object|null} [trace] — ActiveContext 实例
|
|
20
|
+
* @property {Object|null} [memoryCoordinator] — MemoryCoordinator 实例
|
|
21
|
+
* @property {Object|null} [sharedState] — 共享状态 { submittedTitles, submittedPatterns }
|
|
22
|
+
* @property {string} [source] — 'user' | 'system'
|
|
23
|
+
* @property {Object} budget — 预算配置
|
|
24
|
+
* @property {import('../capabilities.js').Capability[]} capabilities — 本轮使用的 capabilities
|
|
25
|
+
* @property {string} baseSystemPrompt — 基础系统提示词
|
|
26
|
+
* @property {Array} toolSchemas — 工具 schema 列表
|
|
27
|
+
* @property {string} prompt — 原始用户提示
|
|
28
|
+
* @property {Function|null} [onToolCall] — 本轮工具调用钩子
|
|
29
|
+
* @property {Object} [context] — 额外上下文
|
|
30
|
+
* @property {import('../context/ContextWindow.js').ContextWindow|null} [contextWindow] — 原始 ContextWindow (供 forced-summary 等外部逻辑)
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
export class LoopContext {
|
|
34
|
+
// ─── 注入依赖 ───
|
|
35
|
+
|
|
36
|
+
/** @type {import('./MessageAdapter.js').MessageAdapter} 统一消息适配器 */
|
|
37
|
+
messages;
|
|
38
|
+
|
|
39
|
+
/** @type {Object|null} ExplorationTracker 实例 */
|
|
40
|
+
tracker;
|
|
41
|
+
|
|
42
|
+
/** @type {Object|null} ActiveContext 实例 */
|
|
43
|
+
trace;
|
|
44
|
+
|
|
45
|
+
/** @type {Object|null} MemoryCoordinator 实例 */
|
|
46
|
+
memoryCoordinator;
|
|
47
|
+
|
|
48
|
+
/** @type {Object|null} 共享状态 */
|
|
49
|
+
sharedState;
|
|
50
|
+
|
|
51
|
+
// ─── 循环状态 ───
|
|
52
|
+
|
|
53
|
+
/** @type {number} 当前迭代次数 */
|
|
54
|
+
iteration = 0;
|
|
55
|
+
|
|
56
|
+
/** @type {string} 最终回复文本 */
|
|
57
|
+
lastReply = '';
|
|
58
|
+
|
|
59
|
+
/** @type {Array} 本轮工具调用记录 */
|
|
60
|
+
toolCalls = [];
|
|
61
|
+
|
|
62
|
+
/** @type {{input: number, output: number}} 本轮 token 用量 */
|
|
63
|
+
tokenUsage = { input: 0, output: 0 };
|
|
64
|
+
|
|
65
|
+
/** @type {number} 循环开始时间戳 */
|
|
66
|
+
loopStartTime = 0;
|
|
67
|
+
|
|
68
|
+
// ─── 错误恢复 ───
|
|
69
|
+
|
|
70
|
+
/** @type {number} 连续 AI 错误计数 (2-strike 策略) */
|
|
71
|
+
consecutiveAiErrors = 0;
|
|
72
|
+
|
|
73
|
+
/** @type {number} 连续空响应计数 */
|
|
74
|
+
consecutiveEmptyResponses = 0;
|
|
75
|
+
|
|
76
|
+
// ─── 配置 (只读) ───
|
|
77
|
+
|
|
78
|
+
/** @type {string} 来源 'user' | 'system' */
|
|
79
|
+
source;
|
|
80
|
+
|
|
81
|
+
/** @type {Object} 预算配置 */
|
|
82
|
+
budget;
|
|
83
|
+
|
|
84
|
+
/** @type {import('../capabilities.js').Capability[]} */
|
|
85
|
+
capabilities;
|
|
86
|
+
|
|
87
|
+
/** @type {string} 基础系统提示词 */
|
|
88
|
+
baseSystemPrompt;
|
|
89
|
+
|
|
90
|
+
/** @type {Array} 工具 schemas */
|
|
91
|
+
toolSchemas;
|
|
92
|
+
|
|
93
|
+
/** @type {string} 原始用户提示 */
|
|
94
|
+
prompt;
|
|
95
|
+
|
|
96
|
+
/** @type {Function|null} 工具调用钩子 */
|
|
97
|
+
onToolCall;
|
|
98
|
+
|
|
99
|
+
/** @type {Object} 额外上下文 */
|
|
100
|
+
context;
|
|
101
|
+
|
|
102
|
+
/** @type {import('../../chat/ContextWindow.js').ContextWindow|null} 原始 ContextWindow 引用 */
|
|
103
|
+
contextWindow;
|
|
104
|
+
|
|
105
|
+
/** @type {string|null} 首轮 toolChoice 覆盖 ('required'/'auto'/'none') */
|
|
106
|
+
toolChoiceOverride;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @param {LoopContextConfig} config
|
|
110
|
+
*/
|
|
111
|
+
constructor(config) {
|
|
112
|
+
this.messages = config.messages;
|
|
113
|
+
this.tracker = config.tracker || null;
|
|
114
|
+
this.trace = config.trace || null;
|
|
115
|
+
this.memoryCoordinator = config.memoryCoordinator || null;
|
|
116
|
+
this.sharedState = config.sharedState || null;
|
|
117
|
+
this.source = config.source || 'user';
|
|
118
|
+
this.budget = config.budget;
|
|
119
|
+
this.capabilities = config.capabilities;
|
|
120
|
+
this.baseSystemPrompt = config.baseSystemPrompt;
|
|
121
|
+
this.toolSchemas = config.toolSchemas;
|
|
122
|
+
this.prompt = config.prompt;
|
|
123
|
+
this.onToolCall = config.onToolCall || null;
|
|
124
|
+
this.context = config.context || {};
|
|
125
|
+
this.contextWindow = config.contextWindow || null;
|
|
126
|
+
this.toolChoiceOverride = config.toolChoiceOverride || null;
|
|
127
|
+
this.loopStartTime = Date.now();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// ─── 计算属性 ───
|
|
131
|
+
|
|
132
|
+
/** 是否为 system 场景 */
|
|
133
|
+
get isSystem() {
|
|
134
|
+
return this.source === 'system';
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** 最大迭代数 */
|
|
138
|
+
get maxIterations() {
|
|
139
|
+
return this.budget.maxIterations || 20;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ─── Token 累计辅助 ───
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* 累加 token 用量到循环级统计
|
|
146
|
+
* @param {Object} usage — { inputTokens, outputTokens }
|
|
147
|
+
*/
|
|
148
|
+
addTokenUsage(usage) {
|
|
149
|
+
if (!usage) return;
|
|
150
|
+
const inTok = usage.inputTokens || 0;
|
|
151
|
+
const outTok = usage.outputTokens || 0;
|
|
152
|
+
this.tokenUsage.input += inTok;
|
|
153
|
+
this.tokenUsage.output += outTok;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ─── 结果构建 ───
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* 构建循环返回值
|
|
160
|
+
* @returns {{ reply: string, toolCalls: Array, tokenUsage: Object, iterations: number }}
|
|
161
|
+
*/
|
|
162
|
+
buildResult() {
|
|
163
|
+
return {
|
|
164
|
+
reply: this.lastReply,
|
|
165
|
+
toolCalls: [...this.toolCalls],
|
|
166
|
+
tokenUsage: { ...this.tokenUsage },
|
|
167
|
+
iterations: this.iteration,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
}
|