autosnippet 3.2.8 → 3.2.10
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 +6 -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 +23 -26
- package/lib/cli/SetupService.js +1 -1
- package/lib/cli/deploy/FileManifest.js +1 -1
- package/lib/core/AstAnalyzer.js +1 -1
- package/lib/core/discovery/index.js +2 -2
- package/lib/external/ai/AiProvider.js +66 -172
- package/lib/external/ai/providers/GoogleGeminiProvider.js +29 -5
- 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 +1 -1
- package/lib/external/mcp/handlers/bootstrap/pipeline/IncrementalBootstrap.js +1 -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 +291 -204
- package/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +7 -6
- package/lib/external/mcp/handlers/bootstrap/shared/dimension-sop.js +1 -1
- package/lib/external/mcp/handlers/bootstrap-internal.js +2 -2
- package/lib/external/mcp/handlers/dimension-complete-external.js +6 -6
- 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 +5 -5
- package/lib/http/routes/remote.js +134 -255
- 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 +64 -17
- package/lib/platform/ScreenCaptureService.js +177 -0
- package/lib/platform/ios/routes/spm.js +2 -2
- package/lib/service/agent/AgentEventBus.js +207 -0
- package/lib/service/agent/AgentFactory.js +535 -0
- package/lib/service/agent/AgentMessage.js +240 -0
- package/lib/service/agent/AgentRouter.js +228 -0
- package/lib/service/agent/AgentRuntime.js +1056 -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 +409 -0
- package/lib/service/{chat → agent/context}/ContextWindow.js +37 -12
- package/lib/service/{chat → agent/context}/ExplorationTracker.js +112 -33
- package/lib/service/{chat → agent/core}/ChatAgentPrompts.js +5 -3
- 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 +15 -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} +85 -135
- package/lib/service/agent/domain/insight-producer.js +270 -0
- package/lib/service/agent/domain/scan-prompts.js +444 -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 +29 -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 +1 -1
- package/lib/service/{chat → agent}/memory/index.js +1 -1
- package/lib/service/agent/policies.js +442 -0
- package/lib/service/agent/presets.js +305 -0
- package/lib/service/agent/strategies.js +756 -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/composite.js +2 -1
- package/lib/service/{chat → agent}/tools/guard.js +1 -121
- package/lib/service/{chat → agent}/tools/index.js +27 -21
- package/lib/service/{chat → agent}/tools/infrastructure.js +1 -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/module/ModuleService.js +40 -73
- package/lib/service/skills/SignalCollector.js +26 -19
- package/lib/service/snippet/codecs/VSCodeCodec.js +1 -1
- package/lib/shared/FieldSpec.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-D5jiDBQG.css +0 -1
- package/dashboard/dist/assets/index-e5OKj-Ni.js +0 -128
- package/lib/core/discovery/SpmDiscoverer.js +0 -5
- package/lib/external/mcp/handlers/bootstrap/pipeline/EpisodicMemory.js +0 -750
- 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 -359
- 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/ast-graph.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
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capabilities — 可组合的 Agent 技能模块
|
|
3
|
+
*
|
|
4
|
+
* 核心思想: Agent 的能力不由"类型"决定,而由加载了哪些 Capability 模块决定。
|
|
5
|
+
*
|
|
6
|
+
* 每个 Capability 提供:
|
|
7
|
+
* 1. promptFragment — 系统提示词片段 (告诉 LLM 它能做什么)
|
|
8
|
+
* 2. tools — 工具白名单 (该能力需要哪些工具)
|
|
9
|
+
* 3. hooks — 生命周期钩子 (可选的前/后处理)
|
|
10
|
+
*
|
|
11
|
+
* 组合示例:
|
|
12
|
+
* - 用户聊天 = Conversation + CodeAnalysis
|
|
13
|
+
* - 冷启动分析 = CodeAnalysis + KnowledgeProduction
|
|
14
|
+
* - 飞书远程执行 = Conversation + SystemInteraction
|
|
15
|
+
* - 智能全能 = Conversation + CodeAnalysis + KnowledgeProduction + SystemInteraction
|
|
16
|
+
*
|
|
17
|
+
* 这就是为什么"飞书聊天"和"前端聊天"是同一个概念:
|
|
18
|
+
* 它们加载相同的 Capability,只是到达方式 (Transport) 不同。
|
|
19
|
+
*
|
|
20
|
+
* @module capabilities
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import fs from 'node:fs';
|
|
24
|
+
import path from 'node:path';
|
|
25
|
+
import { fileURLToPath } from 'node:url';
|
|
26
|
+
|
|
27
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
28
|
+
|
|
29
|
+
// ─── Base Capability ─────────────────────────────────────
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Capability 基类 — 所有技能模块的抽象接口
|
|
33
|
+
*/
|
|
34
|
+
export class Capability {
|
|
35
|
+
/** @type {string} 能力名称 */
|
|
36
|
+
get name() { throw new Error('Subclass must implement name'); }
|
|
37
|
+
|
|
38
|
+
/** @type {string} 系统提示词片段 */
|
|
39
|
+
get promptFragment() { throw new Error('Subclass must implement promptFragment'); }
|
|
40
|
+
|
|
41
|
+
/** @type {string[]} 工具白名单 */
|
|
42
|
+
get tools() { return []; }
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 构建 prompt 时调用,可注入动态上下文
|
|
46
|
+
* @param {Object} context — { message, memory, projectBriefing, lang, ... }
|
|
47
|
+
* @returns {string|null} 额外的 prompt 片段
|
|
48
|
+
*/
|
|
49
|
+
buildContext(_context) { return null; }
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 每轮 ReAct 步骤前的钩子
|
|
53
|
+
* @param {Object} stepState — 当前步骤状态
|
|
54
|
+
*/
|
|
55
|
+
onBeforeStep(_stepState) {}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* 每轮 ReAct 步骤后的钩子
|
|
59
|
+
* @param {Object} stepResult — 步骤结果
|
|
60
|
+
*/
|
|
61
|
+
onAfterStep(_stepResult) {}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ─── Conversation — 对话能力 ─────────────────────
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* 对话能力: 多轮问答、知识检索、记忆管理
|
|
68
|
+
*
|
|
69
|
+
* 核心工具: 知识库搜索、语义搜索
|
|
70
|
+
* 用于: 用户聊天、飞书聊天、任何需要对话的场景
|
|
71
|
+
*/
|
|
72
|
+
export class Conversation extends Capability {
|
|
73
|
+
#memoryCoordinator;
|
|
74
|
+
#soulContent;
|
|
75
|
+
#projectBriefing;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @param {Object} [opts]
|
|
79
|
+
* @param {Object} [opts.memoryCoordinator] — MemoryCoordinator 实例
|
|
80
|
+
* @param {string} [opts.soulPath] — SOUL.md 路径
|
|
81
|
+
* @param {string} [opts.projectBriefing] — 项目概况文本
|
|
82
|
+
*/
|
|
83
|
+
constructor(opts = {}) {
|
|
84
|
+
super();
|
|
85
|
+
this.#memoryCoordinator = opts.memoryCoordinator || null;
|
|
86
|
+
this.#projectBriefing = opts.projectBriefing || null;
|
|
87
|
+
|
|
88
|
+
// 加载 SOUL.md (人格定义)
|
|
89
|
+
const soulPath = opts.soulPath || path.resolve(__dirname, '../../..', 'SOUL.md');
|
|
90
|
+
try {
|
|
91
|
+
this.#soulContent = fs.existsSync(soulPath) ? fs.readFileSync(soulPath, 'utf-8').trim() : null;
|
|
92
|
+
} catch { this.#soulContent = null; }
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
get name() { return 'conversation'; }
|
|
96
|
+
|
|
97
|
+
get promptFragment() {
|
|
98
|
+
return `## 对话能力
|
|
99
|
+
你是 AutoSnippet 知识管理助手。
|
|
100
|
+
|
|
101
|
+
行为规则:
|
|
102
|
+
1. 回答问题时优先从知识库搜索相关知识
|
|
103
|
+
2. 用户要求编辑/创建知识时,通过工具完成
|
|
104
|
+
3. 每轮至少调用一个工具获取信息(除非纯闲聊)
|
|
105
|
+
4. 保持对话连贯性,引用之前的上下文`;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
get tools() {
|
|
109
|
+
return [
|
|
110
|
+
// 知识检索 (内部 ToolRegistry 名称)
|
|
111
|
+
'search_knowledge',
|
|
112
|
+
'search_recipes',
|
|
113
|
+
'get_recipe_detail',
|
|
114
|
+
'get_related_recipes',
|
|
115
|
+
// 语义搜索
|
|
116
|
+
'semantic_search_code',
|
|
117
|
+
// 知识管理
|
|
118
|
+
'submit_knowledge',
|
|
119
|
+
'knowledge_overview',
|
|
120
|
+
// 项目统计
|
|
121
|
+
'get_project_stats',
|
|
122
|
+
];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
buildContext(context) {
|
|
126
|
+
const parts = [];
|
|
127
|
+
|
|
128
|
+
// SOUL.md 人格注入
|
|
129
|
+
if (this.#soulContent) {
|
|
130
|
+
parts.push(this.#soulContent);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// 项目概况 (优先用 context 传入的, 回退到构造器注入的)
|
|
134
|
+
const briefing = context.projectBriefing || this.#projectBriefing;
|
|
135
|
+
if (briefing) {
|
|
136
|
+
parts.push(`## 项目概况\n${briefing}`);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// 记忆注入
|
|
140
|
+
if (this.#memoryCoordinator) {
|
|
141
|
+
try {
|
|
142
|
+
const memoryContext = this.#memoryCoordinator.buildPromptInjection(
|
|
143
|
+
context.memoryMode || 'user'
|
|
144
|
+
);
|
|
145
|
+
if (memoryContext) parts.push(`## 记忆上下文\n${memoryContext}`);
|
|
146
|
+
} catch { /* non-critical */ }
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return parts.length > 0 ? parts.join('\n\n') : null;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
onAfterStep(stepResult) {
|
|
153
|
+
// 缓存工具结果到记忆
|
|
154
|
+
if (this.#memoryCoordinator && stepResult.toolCalls?.length > 0) {
|
|
155
|
+
try {
|
|
156
|
+
for (const tc of stepResult.toolCalls) {
|
|
157
|
+
this.#memoryCoordinator.cacheToolResult?.(tc.tool, tc.args, tc.result);
|
|
158
|
+
}
|
|
159
|
+
} catch { /* non-critical */ }
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// ─── CodeAnalysis — 代码分析能力 ─────────────────
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* 代码分析能力: AST 解析、代码搜索、结构理解
|
|
168
|
+
*
|
|
169
|
+
* 核心工具: AST 工具集 + 文件读取 + 代码搜索
|
|
170
|
+
* 用于: 用户聊天中的代码问题、冷启动分析、目标扫描
|
|
171
|
+
*/
|
|
172
|
+
export class CodeAnalysis extends Capability {
|
|
173
|
+
|
|
174
|
+
get name() { return 'code_analysis'; }
|
|
175
|
+
|
|
176
|
+
get promptFragment() {
|
|
177
|
+
return `## 代码分析能力
|
|
178
|
+
你是高级软件架构师,可以深度分析代码结构。
|
|
179
|
+
|
|
180
|
+
分析策略:
|
|
181
|
+
| 阶段 | 目标 |
|
|
182
|
+
|------|------|
|
|
183
|
+
| 全局扫描 | get_project_overview + list_project_structure |
|
|
184
|
+
| 结构化探索 | get_class_hierarchy / search_project_code 批量搜索 |
|
|
185
|
+
| 深度验证 | read_project_file 阅读关键实现 |
|
|
186
|
+
| 输出总结 | 停止工具调用,输出分析 |
|
|
187
|
+
|
|
188
|
+
关键规则:
|
|
189
|
+
- 批量搜索: search_project_code({ patterns: [...] })
|
|
190
|
+
- 批量读文件: read_project_file({ filePaths: [...] })
|
|
191
|
+
- 不要重复搜索相同关键词
|
|
192
|
+
- 输出时包含具体文件路径和代码位置`;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
get tools() {
|
|
196
|
+
return [
|
|
197
|
+
// AST 结构
|
|
198
|
+
'get_project_overview', 'get_class_hierarchy', 'get_class_info',
|
|
199
|
+
'get_protocol_info', 'get_method_overrides', 'get_category_map',
|
|
200
|
+
// 搜索与读取
|
|
201
|
+
'search_project_code', 'read_project_file', 'list_project_structure',
|
|
202
|
+
'get_file_summary', 'semantic_search_code',
|
|
203
|
+
// 图谱
|
|
204
|
+
'query_code_graph',
|
|
205
|
+
// 探索追踪
|
|
206
|
+
'get_previous_analysis', 'note_finding', 'get_previous_evidence',
|
|
207
|
+
];
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// ─── KnowledgeProduction — 知识生产能力 ─────────
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* 知识生产能力: 将分析结果转化为结构化知识候选
|
|
215
|
+
*
|
|
216
|
+
* 核心工具: 知识提交 + Guard 检查
|
|
217
|
+
* 用于: 冷启动提交、扫描后提交、用户主动创建知识
|
|
218
|
+
*/
|
|
219
|
+
export class KnowledgeProduction extends Capability {
|
|
220
|
+
|
|
221
|
+
get name() { return 'knowledge_production'; }
|
|
222
|
+
|
|
223
|
+
get promptFragment() {
|
|
224
|
+
return `## 知识生产能力
|
|
225
|
+
你是知识管理专家,将代码分析转化为结构化知识候选。
|
|
226
|
+
|
|
227
|
+
每个候选必须有:
|
|
228
|
+
1. 清晰的标题 (使用项目真实类名/模块名)
|
|
229
|
+
2. 项目特写风格的正文 (content.markdown)
|
|
230
|
+
3. 相关文件路径
|
|
231
|
+
4. 正确的 kind (rule / pattern / fact)
|
|
232
|
+
5. 完整的 Cursor 交付字段
|
|
233
|
+
|
|
234
|
+
工作流:
|
|
235
|
+
1. 识别分析中的知识点
|
|
236
|
+
2. read_project_file 获取代码片段 (如需)
|
|
237
|
+
3. submit_knowledge 或 submit_with_check 提交
|
|
238
|
+
4. 提交优先于完美 — 文件读取失败时用已有信息直接提交`;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
get tools() {
|
|
242
|
+
// 与旧版 PRODUCER_TOOLS 保持一致: 仅 3 个核心工具
|
|
243
|
+
// guard_check_code / validate_candidate 不需要:提交时 UnifiedValidator 已自动校验
|
|
244
|
+
// 额外工具会分散 LLM 注意力,浪费 produce 轮次在验证而非提交上
|
|
245
|
+
return [
|
|
246
|
+
'submit_knowledge', 'submit_with_check',
|
|
247
|
+
'read_project_file', // 获取代码片段用于知识正文
|
|
248
|
+
];
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// ─── SystemInteraction — 系统交互能力 ────────────
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* 系统交互能力: 终端命令执行、文件写入、环境探测、项目探索
|
|
256
|
+
*
|
|
257
|
+
* 核心工具: 终端执行 + 文件写入 + 环境信息 + 项目读取
|
|
258
|
+
* 用于: 飞书远程执行、自动化脚本、任何需要操作本地系统的场景
|
|
259
|
+
*
|
|
260
|
+
* ⚙️ 安全设计 (3 层防护):
|
|
261
|
+
* 1. 工具层: run_safe_command / write_project_file 内置硬编码黑名单
|
|
262
|
+
* 2. Policy 层: SafetyPolicy.checkCommand() / checkFilePath() 动态拦截
|
|
263
|
+
* 3. Runtime 层: reactLoop 工具执行前自动调用 PolicyEngine.validateToolCall()
|
|
264
|
+
*
|
|
265
|
+
* ⚠️ 该能力通常搭配 SafetyPolicy 使用
|
|
266
|
+
*/
|
|
267
|
+
export class SystemInteraction extends Capability {
|
|
268
|
+
#projectRoot;
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* @param {Object} [opts]
|
|
272
|
+
* @param {string} [opts.projectRoot] — 项目根目录 (限制操作范围)
|
|
273
|
+
*/
|
|
274
|
+
constructor(opts = {}) {
|
|
275
|
+
super();
|
|
276
|
+
this.#projectRoot = opts.projectRoot || process.cwd();
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
get name() { return 'system_interaction'; }
|
|
280
|
+
|
|
281
|
+
get promptFragment() {
|
|
282
|
+
return `## 系统交互能力
|
|
283
|
+
你可以在本地环境中执行终端命令、写入文件、探索项目。
|
|
284
|
+
|
|
285
|
+
能力:
|
|
286
|
+
1. **终端命令**: run_safe_command 执行 shell 命令 (git, npm, ls, grep 等)
|
|
287
|
+
2. **文件写入**: write_project_file 创建/覆盖项目内文件
|
|
288
|
+
3. **环境探测**: get_environment_info 获取 OS/Node/Git/项目信息
|
|
289
|
+
4. **项目探索**: 搜索代码、读取文件、列出目录结构
|
|
290
|
+
|
|
291
|
+
安全规则:
|
|
292
|
+
- 所有操作限制在项目目录 (${this.#projectRoot}) 内
|
|
293
|
+
- 危险命令 (sudo, rm -rf /, shutdown 等) 被自动拦截
|
|
294
|
+
- 受保护文件 (.git/, node_modules/, .env) 不可写入
|
|
295
|
+
- SafetyPolicy 可进一步约束可执行命令和可访问路径
|
|
296
|
+
|
|
297
|
+
最佳实践:
|
|
298
|
+
- 执行命令前先 get_environment_info 了解环境
|
|
299
|
+
- git 命令用于查看状态、diff、log,不建议执行 push/commit
|
|
300
|
+
- 需要管道/重定向时用 sh -c "命令" 包装
|
|
301
|
+
|
|
302
|
+
项目路径: ${this.#projectRoot}`;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
get tools() {
|
|
306
|
+
return [
|
|
307
|
+
// 终端执行
|
|
308
|
+
'run_safe_command',
|
|
309
|
+
// 文件写入
|
|
310
|
+
'write_project_file',
|
|
311
|
+
// 环境探测
|
|
312
|
+
'get_environment_info',
|
|
313
|
+
// 项目探索 (只读)
|
|
314
|
+
'search_project_code',
|
|
315
|
+
'read_project_file',
|
|
316
|
+
'list_project_structure',
|
|
317
|
+
'get_project_overview',
|
|
318
|
+
'get_file_summary',
|
|
319
|
+
];
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// ─── ScanProduction — 扫描知识生产能力 ─────────
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* 扫描知识生产能力: 将分析结果转化为标准 Recipe
|
|
327
|
+
*
|
|
328
|
+
* 与冷启动 KnowledgeProduction 的区别:
|
|
329
|
+
* - 使用 collect_scan_recipe 工具(内存收集,不入库)
|
|
330
|
+
* - 冷启动用 submit_knowledge(直接入库)
|
|
331
|
+
* - 字段 schema 完全一致 — 产出质量相同
|
|
332
|
+
*
|
|
333
|
+
* 用于: scanKnowledge produce 阶段
|
|
334
|
+
*/
|
|
335
|
+
export class ScanProduction extends Capability {
|
|
336
|
+
|
|
337
|
+
get name() { return 'scan_production'; }
|
|
338
|
+
|
|
339
|
+
get promptFragment() {
|
|
340
|
+
return `## 知识生产能力
|
|
341
|
+
你是知识管理专家,将代码分析转化为结构化知识候选。
|
|
342
|
+
|
|
343
|
+
每个候选必须有:
|
|
344
|
+
1. 清晰的标题 (使用项目真实类名/模块名)
|
|
345
|
+
2. 项目特写风格的正文 (content.markdown ≥200字)
|
|
346
|
+
3. 设计原理说明 (content.rationale)
|
|
347
|
+
4. 相关文件路径 (reasoning.sources)
|
|
348
|
+
5. 正确的 kind (rule / pattern / fact)
|
|
349
|
+
6. 完整的 Cursor 交付字段 (trigger, doClause, whenClause 等)
|
|
350
|
+
|
|
351
|
+
工作流:
|
|
352
|
+
1. 识别分析中的知识点
|
|
353
|
+
2. read_project_file 获取代码片段 (如需)
|
|
354
|
+
3. collect_scan_recipe 逐个提交每个知识点
|
|
355
|
+
4. 每个独立模式/发现单独提交 — 不要合并`;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
get tools() {
|
|
359
|
+
return [
|
|
360
|
+
'collect_scan_recipe', // 扫描专用 Recipe 收集
|
|
361
|
+
'read_project_file', // 获取代码片段
|
|
362
|
+
];
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// ─── Capability 注册表 ─────────────────────────
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* 所有内置 Capability 的注册表
|
|
370
|
+
*
|
|
371
|
+
* 用于按名称查找和实例化:
|
|
372
|
+
* const cap = CapabilityRegistry.create('conversation', { memoryCoordinator });
|
|
373
|
+
*/
|
|
374
|
+
export const CapabilityRegistry = {
|
|
375
|
+
/** @type {Map<string, typeof Capability>} */
|
|
376
|
+
_registry: new Map([
|
|
377
|
+
['conversation', Conversation],
|
|
378
|
+
['code_analysis', CodeAnalysis],
|
|
379
|
+
['knowledge_production', KnowledgeProduction],
|
|
380
|
+
['scan_production', ScanProduction],
|
|
381
|
+
['system_interaction', SystemInteraction],
|
|
382
|
+
]),
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* 按名称创建 Capability 实例
|
|
386
|
+
* @param {string} name
|
|
387
|
+
* @param {Object} [opts]
|
|
388
|
+
* @returns {Capability}
|
|
389
|
+
*/
|
|
390
|
+
create(name, opts = {}) {
|
|
391
|
+
const Cls = this._registry.get(name);
|
|
392
|
+
if (!Cls) throw new Error(`Unknown capability: ${name}`);
|
|
393
|
+
return new Cls(opts);
|
|
394
|
+
},
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* 注册自定义 Capability
|
|
398
|
+
* @param {string} name
|
|
399
|
+
* @param {typeof Capability} cls
|
|
400
|
+
*/
|
|
401
|
+
register(name, cls) {
|
|
402
|
+
this._registry.set(name, cls);
|
|
403
|
+
},
|
|
404
|
+
|
|
405
|
+
/** 所有注册名 */
|
|
406
|
+
get names() { return [...this._registry.keys()]; },
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
export default { Capability, Conversation, CodeAnalysis, KnowledgeProduction, SystemInteraction, CapabilityRegistry };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ContextWindow —
|
|
2
|
+
* ContextWindow — Agent 的上下文窗口管理器
|
|
3
3
|
*
|
|
4
4
|
* 业界最佳实践:
|
|
5
5
|
* - OpenAI Compaction: 阈值触发自动压缩,保留关键上下文
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
* @module ContextWindow
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
-
import Logger from '
|
|
25
|
-
import { estimateTokensFast } from '
|
|
24
|
+
import Logger from '../../../infrastructure/logging/Logger.js';
|
|
25
|
+
import { estimateTokensFast } from '../../../shared/token-utils.js';
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* 一组相关消息的原子单元:
|
|
@@ -439,18 +439,43 @@ export class ContextWindow {
|
|
|
439
439
|
resetToPromptOnly() {
|
|
440
440
|
if (this.#messages.length > 1) {
|
|
441
441
|
// 提取所有已提交候选
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
442
|
+
this.#extractCompactedSubmits(1);
|
|
443
|
+
this.#messages.length = 1;
|
|
444
|
+
this.#compactionLog.push(`RESET: cleared all messages except prompt`);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Pipeline 阶段隔离 — 清空全部消息。
|
|
450
|
+
*
|
|
451
|
+
* 用于 PipelineStrategy 在阶段间重置 ContextWindow:
|
|
452
|
+
* analyze → (reset) → produce
|
|
453
|
+
*
|
|
454
|
+
* reactLoop 会将新阶段的 prompt 追加为 messages[0],
|
|
455
|
+
* systemPrompt 通过 chatWithTools 参数独立传递,不受影响。
|
|
456
|
+
*
|
|
457
|
+
* 保留 compactedSubmits 以支持跨阶段提交去重。
|
|
458
|
+
*/
|
|
459
|
+
resetForNewStage() {
|
|
460
|
+
this.#extractCompactedSubmits(0);
|
|
461
|
+
this.#messages = [];
|
|
462
|
+
this.#compactionLog.push('RESET_STAGE: cleared all messages for new pipeline stage');
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* 从消息中提取已提交候选到 compactedSubmits
|
|
467
|
+
* @param {number} fromIdx — 从哪个索引开始扫描
|
|
468
|
+
*/
|
|
469
|
+
#extractCompactedSubmits(fromIdx) {
|
|
470
|
+
for (let i = fromIdx; i < this.#messages.length; i++) {
|
|
471
|
+
const m = this.#messages[i];
|
|
472
|
+
if (m.role === 'assistant' && m.toolCalls) {
|
|
473
|
+
for (const tc of m.toolCalls) {
|
|
474
|
+
if (tc.name === 'submit_knowledge' || tc.name === 'submit_with_check') {
|
|
475
|
+
this.#compactedSubmits.add(tc.args?.title || tc.args?.category || 'untitled');
|
|
449
476
|
}
|
|
450
477
|
}
|
|
451
478
|
}
|
|
452
|
-
this.#messages.length = 1;
|
|
453
|
-
this.#compactionLog.push(`RESET: cleared all messages except prompt`);
|
|
454
479
|
}
|
|
455
480
|
}
|
|
456
481
|
|