autosnippet 3.2.8 → 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 +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/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 +23 -1
- 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 +287 -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 +9 -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 +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 +25 -14
- package/lib/service/{chat → agent/core}/ChatAgentPrompts.js +1 -1
- 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} +85 -135
- 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/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 +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/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}/memory/ActiveContext.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
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ToolRegistry — 统一工具注册表
|
|
3
3
|
*
|
|
4
|
-
* 管理
|
|
4
|
+
* 管理 Agent 可调用的所有工具定义。
|
|
5
5
|
* 每个工具包含: name, description, parameters(JSON Schema), handler
|
|
6
6
|
*
|
|
7
7
|
* 设计原则:
|
|
8
8
|
* - 所有 AI 能力均封装为 Tool,不再散落在各处
|
|
9
9
|
* - Tool handler 仅做参数整理 + 调用已有 Service,不含业务逻辑
|
|
10
|
-
* - 支持
|
|
10
|
+
* - 支持 Agent ReAct 循环调用(通过 LLM 推理决定工具调用)
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import Logger from '
|
|
13
|
+
import Logger from '../../../infrastructure/logging/Logger.js';
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* AI 模型常见的参数命名变体 → schema 标准名映射
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ai-analysis.js — AI 分析类工具 (2)
|
|
3
|
+
*
|
|
4
|
+
* 9. enrich_candidate 结构补齐
|
|
5
|
+
* 9b. refine_bootstrap_candidates 内容润色
|
|
6
|
+
*
|
|
7
|
+
* 注意: summarize_code / extract_recipes 已删除。
|
|
8
|
+
* 代码摘要和 Recipe 提取由 Agent LLM 直接推理完成,不再需要专用工具。
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// ────────────────────────────────────────────────────────────
|
|
12
|
+
// 9. enrich_candidate
|
|
13
|
+
// ────────────────────────────────────────────────────────────
|
|
14
|
+
export const enrichCandidate = {
|
|
15
|
+
name: 'enrich_candidate',
|
|
16
|
+
description:
|
|
17
|
+
'① 结构补齐 — 自动填充缺失的结构性语义字段(rationale/knowledgeType/complexity/scope/steps/constraints)。批量处理,只填空不覆盖。建议在 refine_bootstrap_candidates 之前执行。',
|
|
18
|
+
parameters: {
|
|
19
|
+
type: 'object',
|
|
20
|
+
properties: {
|
|
21
|
+
candidateIds: {
|
|
22
|
+
type: 'array',
|
|
23
|
+
items: { type: 'string' },
|
|
24
|
+
description: '候选 ID 列表 (最多 20 个)',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
required: ['candidateIds'],
|
|
28
|
+
},
|
|
29
|
+
handler: async (params, ctx) => {
|
|
30
|
+
if (!ctx.aiProvider) {
|
|
31
|
+
return { error: 'AI provider not available' };
|
|
32
|
+
}
|
|
33
|
+
// V3: 使用 MCP handler enrichCandidates 的逻辑
|
|
34
|
+
const { enrichCandidates: enrichFn } = await import('../../../external/mcp/handlers/candidate.js');
|
|
35
|
+
const result = await enrichFn(ctx, { candidateIds: params.candidateIds });
|
|
36
|
+
return result?.data || result;
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// ────────────────────────────────────────────────────────────
|
|
41
|
+
// 9b. refine_bootstrap_candidates (Phase 6)
|
|
42
|
+
// ────────────────────────────────────────────────────────────
|
|
43
|
+
export const refineBootstrapCandidates = {
|
|
44
|
+
name: 'refine_bootstrap_candidates',
|
|
45
|
+
description:
|
|
46
|
+
'② 内容润色 — 逐条精炼 Bootstrap 候选的内容质量:改善 summary、补充架构 insight、推断 relations 关联、调整 confidence、丰富 tags。建议在 enrich_candidate 之后执行。',
|
|
47
|
+
parameters: {
|
|
48
|
+
type: 'object',
|
|
49
|
+
properties: {
|
|
50
|
+
candidateIds: {
|
|
51
|
+
type: 'array',
|
|
52
|
+
items: { type: 'string' },
|
|
53
|
+
description: '指定候选 ID 列表(可选,默认全部 bootstrap 候选)',
|
|
54
|
+
},
|
|
55
|
+
userPrompt: {
|
|
56
|
+
type: 'string',
|
|
57
|
+
description: '用户自定义润色提示词,指导 AI 润色方向(如"侧重描述线程安全注意事项")',
|
|
58
|
+
},
|
|
59
|
+
dryRun: { type: 'boolean', description: '仅预览 AI 润色结果,不写入数据库' },
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
handler: async (params, ctx) => {
|
|
63
|
+
if (!ctx.aiProvider) {
|
|
64
|
+
return { error: 'AI provider not available' };
|
|
65
|
+
}
|
|
66
|
+
// V3: 委托给 bootstrap handler 的 refine 逻辑
|
|
67
|
+
const { bootstrapRefine } = await import('../../../external/mcp/handlers/bootstrap-internal.js');
|
|
68
|
+
const result = await bootstrapRefine(ctx, {
|
|
69
|
+
candidateIds: params.candidateIds,
|
|
70
|
+
userPrompt: params.userPrompt,
|
|
71
|
+
dryRun: params.dryRun,
|
|
72
|
+
});
|
|
73
|
+
return result?.data || result;
|
|
74
|
+
},
|
|
75
|
+
};
|
|
@@ -160,7 +160,7 @@ export const submitWithCheck = {
|
|
|
160
160
|
content: {
|
|
161
161
|
type: 'object',
|
|
162
162
|
description:
|
|
163
|
-
'{ markdown: "项目特写 Markdown", pattern: "核心代码 3-8
|
|
163
|
+
'{ markdown: "项目特写 Markdown (≥200字符,含代码块)", rationale: "设计原理说明 (必填)", pattern: "核心代码 3-8 行,语法完整" }',
|
|
164
164
|
},
|
|
165
165
|
title: { type: 'string', description: '候选标题' },
|
|
166
166
|
description: { type: 'string', description: '中文简述 ≤80 字' },
|
|
@@ -234,6 +234,7 @@ export const submitWithCheck = {
|
|
|
234
234
|
ctx.logger?.info(`[submit_with_check] ✗ validator rejected: ${validResult.errors.join('; ')}`);
|
|
235
235
|
return {
|
|
236
236
|
submitted: false,
|
|
237
|
+
status: 'rejected',
|
|
237
238
|
reason: 'validation_failed',
|
|
238
239
|
errors: validResult.errors,
|
|
239
240
|
warnings: validResult.warnings,
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* guard.js — Guard 安全类工具 (
|
|
2
|
+
* guard.js — Guard 安全类工具 (4)
|
|
3
3
|
*
|
|
4
4
|
* 7b. list_guard_rules 列出 Guard 规则
|
|
5
5
|
* 8b. get_recommendations 获取推荐 Recipe
|
|
6
|
-
* 12. ai_translate AI 翻译
|
|
7
6
|
* 13. guard_check_code Guard 检查代码
|
|
8
7
|
* 14. query_violations 查询违规历史
|
|
9
|
-
* 15. generate_guard_rule AI 生成 Guard 规则
|
|
10
8
|
*/
|
|
11
9
|
|
|
12
10
|
// ────────────────────────────────────────────────────────────
|
|
@@ -75,46 +73,6 @@ export const getRecommendations = {
|
|
|
75
73
|
},
|
|
76
74
|
};
|
|
77
75
|
|
|
78
|
-
// ────────────────────────────────────────────────────────────
|
|
79
|
-
// 12. ai_translate
|
|
80
|
-
// ────────────────────────────────────────────────────────────
|
|
81
|
-
export const aiTranslate = {
|
|
82
|
-
name: 'ai_translate',
|
|
83
|
-
description: 'AI 翻译 — 将中文 summary/usageGuide 翻译为英文。',
|
|
84
|
-
parameters: {
|
|
85
|
-
type: 'object',
|
|
86
|
-
properties: {
|
|
87
|
-
summary: { type: 'string', description: '中文摘要' },
|
|
88
|
-
usageGuide: { type: 'string', description: '中文使用指南' },
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
handler: async (params, ctx) => {
|
|
92
|
-
if (!ctx.aiProvider) {
|
|
93
|
-
return { error: 'AI provider not available' };
|
|
94
|
-
}
|
|
95
|
-
const { summary, usageGuide } = params;
|
|
96
|
-
if (!summary && !usageGuide) {
|
|
97
|
-
return { summaryEn: '', usageGuideEn: '' };
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const systemPrompt =
|
|
101
|
-
'You are a technical translator. Translate from Chinese to English. Keep technical terms unchanged. Return ONLY valid JSON: { "summaryEn": "...", "usageGuideEn": "..." }.';
|
|
102
|
-
const parts = [];
|
|
103
|
-
if (summary) {
|
|
104
|
-
parts.push(`summary: ${summary}`);
|
|
105
|
-
}
|
|
106
|
-
if (usageGuide) {
|
|
107
|
-
parts.push(`usageGuide: ${usageGuide}`);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const parsed = await ctx.aiProvider.chatWithStructuredOutput(parts.join('\n'), {
|
|
111
|
-
systemPrompt,
|
|
112
|
-
temperature: 0.2,
|
|
113
|
-
});
|
|
114
|
-
return parsed || { summaryEn: summary || '', usageGuideEn: usageGuide || '' };
|
|
115
|
-
},
|
|
116
|
-
};
|
|
117
|
-
|
|
118
76
|
// ────────────────────────────────────────────────────────────
|
|
119
77
|
// 13. guard_check_code
|
|
120
78
|
// ────────────────────────────────────────────────────────────
|
|
@@ -184,82 +142,4 @@ export const queryViolations = {
|
|
|
184
142
|
},
|
|
185
143
|
};
|
|
186
144
|
|
|
187
|
-
// ────────────────────────────────────────────────────────────
|
|
188
|
-
// 15. generate_guard_rule
|
|
189
|
-
// ────────────────────────────────────────────────────────────
|
|
190
|
-
export const generateGuardRule = {
|
|
191
|
-
name: 'generate_guard_rule',
|
|
192
|
-
description: 'AI 生成 Guard 规则 — 描述你想阻止的代码模式,AI 自动生成正则表达式和规则定义。',
|
|
193
|
-
parameters: {
|
|
194
|
-
type: 'object',
|
|
195
|
-
properties: {
|
|
196
|
-
description: {
|
|
197
|
-
type: 'string',
|
|
198
|
-
description: '规则描述(例如 "禁止在主线程使用同步网络请求")',
|
|
199
|
-
},
|
|
200
|
-
language: { type: 'string', description: '目标语言 (swift/objc 等)' },
|
|
201
|
-
severity: { type: 'string', description: '严重程度 (error/warning/info),默认 warning' },
|
|
202
|
-
autoCreate: { type: 'boolean', description: '是否自动创建到数据库,默认 false' },
|
|
203
|
-
},
|
|
204
|
-
required: ['description'],
|
|
205
|
-
},
|
|
206
|
-
handler: async (params, ctx) => {
|
|
207
|
-
if (!ctx.aiProvider) {
|
|
208
|
-
return { error: 'AI provider not available' };
|
|
209
|
-
}
|
|
210
|
-
const { description, language = 'swift', severity = 'warning', autoCreate = false } = params;
|
|
211
|
-
|
|
212
|
-
const prompt = `Generate a Guard rule for this requirement:
|
|
213
|
-
Description: ${description}
|
|
214
|
-
Language: ${language}
|
|
215
|
-
Severity: ${severity}
|
|
216
|
-
|
|
217
|
-
Return ONLY valid JSON:
|
|
218
|
-
{
|
|
219
|
-
"name": "rule-name-kebab-case",
|
|
220
|
-
"description": "One-line description in English",
|
|
221
|
-
"description_cn": "一行中文描述",
|
|
222
|
-
"pattern": "regex pattern for matching the problematic code",
|
|
223
|
-
"languages": ["${language}"],
|
|
224
|
-
"severity": "${severity}",
|
|
225
|
-
"testCases": {
|
|
226
|
-
"shouldMatch": ["code example that should trigger"],
|
|
227
|
-
"shouldNotMatch": ["code example that should NOT trigger"]
|
|
228
|
-
}
|
|
229
|
-
}`;
|
|
230
|
-
|
|
231
|
-
const rule = await ctx.aiProvider.chatWithStructuredOutput(prompt, { temperature: 0.2 });
|
|
232
|
-
if (!rule) {
|
|
233
|
-
return { error: 'Failed to parse AI response' };
|
|
234
|
-
}
|
|
235
145
|
|
|
236
|
-
// 验证正则表达式
|
|
237
|
-
try {
|
|
238
|
-
new RegExp(rule.pattern);
|
|
239
|
-
} catch (e) {
|
|
240
|
-
return { error: `Invalid regex pattern: ${e.message}`, rule };
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// 自动创建
|
|
244
|
-
if (autoCreate && rule.name && rule.pattern) {
|
|
245
|
-
try {
|
|
246
|
-
const guardService = ctx.container.get('guardService');
|
|
247
|
-
const created = await guardService.createRule(
|
|
248
|
-
{
|
|
249
|
-
name: rule.name,
|
|
250
|
-
description: rule.description || description,
|
|
251
|
-
pattern: rule.pattern,
|
|
252
|
-
languages: rule.languages || [language],
|
|
253
|
-
severity: rule.severity || severity,
|
|
254
|
-
},
|
|
255
|
-
{ userId: 'agent' }
|
|
256
|
-
);
|
|
257
|
-
return { rule, created: true, recipeId: created.id };
|
|
258
|
-
} catch (err) {
|
|
259
|
-
return { rule, created: false, error: err.message };
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
return { rule, created: false };
|
|
264
|
-
},
|
|
265
|
-
};
|
|
@@ -4,12 +4,10 @@
|
|
|
4
4
|
* 从各子模块导入所有工具,按原始顺序组装 ALL_TOOLS 数组并导出。
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
// ── AI 分析类 (
|
|
7
|
+
// ── AI 分析类 (2) ──
|
|
8
8
|
import {
|
|
9
9
|
enrichCandidate,
|
|
10
|
-
extractRecipes,
|
|
11
10
|
refineBootstrapCandidates,
|
|
12
|
-
summarizeCode,
|
|
13
11
|
} from './ai-analysis.js';
|
|
14
12
|
// ── AST 结构化分析 + Agent Memory (11) ──
|
|
15
13
|
import {
|
|
@@ -35,10 +33,8 @@ import {
|
|
|
35
33
|
submitWithCheck,
|
|
36
34
|
} from './composite.js';
|
|
37
35
|
|
|
38
|
-
// ── Guard 安全类 (
|
|
36
|
+
// ── Guard 安全类 (4) ──
|
|
39
37
|
import {
|
|
40
|
-
aiTranslate,
|
|
41
|
-
generateGuardRule,
|
|
42
38
|
getRecommendations,
|
|
43
39
|
guardCheckCode,
|
|
44
40
|
listGuardRules,
|
|
@@ -54,8 +50,16 @@ import {
|
|
|
54
50
|
rebuildIndex,
|
|
55
51
|
suggestSkills,
|
|
56
52
|
} from './infrastructure.js';
|
|
57
|
-
// ── 知识图谱类 (
|
|
58
|
-
import { addGraphEdge, checkDuplicate
|
|
53
|
+
// ── 知识图谱类 (2) ──
|
|
54
|
+
import { addGraphEdge, checkDuplicate } from './knowledge-graph.js';
|
|
55
|
+
// ── 扫描 Recipe 收集 (1) ──
|
|
56
|
+
import { collectScanRecipe } from './scan-recipe.js';
|
|
57
|
+
// ── 系统交互类 (3) ──
|
|
58
|
+
import {
|
|
59
|
+
getEnvironmentInfo,
|
|
60
|
+
runSafeCommand,
|
|
61
|
+
writeProjectFile,
|
|
62
|
+
} from './system-interaction.js';
|
|
59
63
|
// ── 生命周期操作类 (11) ──
|
|
60
64
|
import {
|
|
61
65
|
approveCandidate,
|
|
@@ -104,20 +108,15 @@ export {
|
|
|
104
108
|
searchKnowledge,
|
|
105
109
|
getRelatedRecipes,
|
|
106
110
|
// AI 分析类
|
|
107
|
-
summarizeCode,
|
|
108
|
-
extractRecipes,
|
|
109
111
|
enrichCandidate,
|
|
110
112
|
refineBootstrapCandidates,
|
|
111
113
|
// Guard 安全类
|
|
112
114
|
listGuardRules,
|
|
113
115
|
getRecommendations,
|
|
114
|
-
aiTranslate,
|
|
115
116
|
guardCheckCode,
|
|
116
117
|
queryViolations,
|
|
117
|
-
generateGuardRule,
|
|
118
118
|
// 知识图谱类
|
|
119
119
|
checkDuplicate,
|
|
120
|
-
discoverRelations,
|
|
121
120
|
addGraphEdge,
|
|
122
121
|
// 生命周期操作类
|
|
123
122
|
submitCandidate,
|
|
@@ -161,6 +160,12 @@ export {
|
|
|
161
160
|
queryCodeGraph,
|
|
162
161
|
// 调用图查询 (Phase 5)
|
|
163
162
|
queryCallGraph,
|
|
163
|
+
// 扫描 Recipe 收集
|
|
164
|
+
collectScanRecipe,
|
|
165
|
+
// 系统交互类
|
|
166
|
+
runSafeCommand,
|
|
167
|
+
writeProjectFile,
|
|
168
|
+
getEnvironmentInfo,
|
|
164
169
|
};
|
|
165
170
|
|
|
166
171
|
// ── ALL_TOOLS 数组(与原始 tools.js 顺序一致)──
|
|
@@ -180,16 +185,12 @@ export const ALL_TOOLS = [
|
|
|
180
185
|
getRelatedRecipes,
|
|
181
186
|
listGuardRules,
|
|
182
187
|
getRecommendations,
|
|
183
|
-
// AI 分析类 (
|
|
184
|
-
summarizeCode,
|
|
185
|
-
extractRecipes,
|
|
188
|
+
// AI 分析类 (2)
|
|
186
189
|
enrichCandidate,
|
|
187
190
|
refineBootstrapCandidates,
|
|
188
|
-
|
|
189
|
-
// Guard 安全类 (3)
|
|
191
|
+
// Guard 安全类 (2)
|
|
190
192
|
guardCheckCode,
|
|
191
193
|
queryViolations,
|
|
192
|
-
generateGuardRule,
|
|
193
194
|
// 生命周期操作类 (7)
|
|
194
195
|
submitCandidate,
|
|
195
196
|
saveDocument,
|
|
@@ -203,9 +204,8 @@ export const ALL_TOOLS = [
|
|
|
203
204
|
qualityScore,
|
|
204
205
|
validateCandidate,
|
|
205
206
|
getFeedbackStats,
|
|
206
|
-
// 知识图谱类 (
|
|
207
|
+
// 知识图谱类 (2)
|
|
207
208
|
checkDuplicate,
|
|
208
|
-
discoverRelations,
|
|
209
209
|
addGraphEdge,
|
|
210
210
|
// 基础设施类 (3)
|
|
211
211
|
graphImpactAnalysis,
|
|
@@ -239,6 +239,12 @@ export const ALL_TOOLS = [
|
|
|
239
239
|
queryCodeGraph,
|
|
240
240
|
// 调用图查询 (1) — Phase 5
|
|
241
241
|
queryCallGraph,
|
|
242
|
+
// 系统交互 (3) — Agent 终端/文件写入/环境探测
|
|
243
|
+
runSafeCommand,
|
|
244
|
+
writeProjectFile,
|
|
245
|
+
getEnvironmentInfo,
|
|
246
|
+
// 扫描 Recipe 收集 (1) — scanKnowledge produce 阶段专用
|
|
247
|
+
collectScanRecipe,
|
|
242
248
|
];
|
|
243
249
|
|
|
244
250
|
export default ALL_TOOLS;
|
|
@@ -157,7 +157,7 @@ export const createSkillTool = {
|
|
|
157
157
|
},
|
|
158
158
|
handler: async (params, ctx) => {
|
|
159
159
|
const { createSkill } = await import('../../../external/mcp/handlers/skill.js');
|
|
160
|
-
// 根据
|
|
160
|
+
// 根据 Agent 的 source 推断 createdBy
|
|
161
161
|
const createdBy = ctx?.source === 'system' ? 'system-ai' : 'user-ai';
|
|
162
162
|
const raw = createSkill(null, { ...params, createdBy });
|
|
163
163
|
try {
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* knowledge-graph.js — 知识图谱类工具 (2)
|
|
3
|
+
*
|
|
4
|
+
* 10. check_duplicate 候选查重
|
|
5
|
+
* 12. add_graph_edge 手动添加图谱边
|
|
6
|
+
*
|
|
7
|
+
* 注意: discover_relations 已删除。
|
|
8
|
+
* 关系发现由 Agent LLM 直接推理完成,利用通用工具(search_knowledge, query_code_graph 等)。
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { findSimilarRecipes } from '../../candidate/SimilarityService.js';
|
|
12
|
+
|
|
13
|
+
// ────────────────────────────────────────────────────────────
|
|
14
|
+
// 10. check_duplicate
|
|
15
|
+
// ────────────────────────────────────────────────────────────
|
|
16
|
+
export const checkDuplicate = {
|
|
17
|
+
name: 'check_duplicate',
|
|
18
|
+
description:
|
|
19
|
+
'候选查重 — 检测候选代码是否与已有 Recipe 重复(基于标题/摘要/代码的 Jaccard 相似度)。',
|
|
20
|
+
parameters: {
|
|
21
|
+
type: 'object',
|
|
22
|
+
properties: {
|
|
23
|
+
candidate: { type: 'object', description: '候选对象 { title, summary, code, usageGuide }' },
|
|
24
|
+
candidateId: { type: 'string', description: '或提供候选 ID,从数据库读取' },
|
|
25
|
+
projectRoot: { type: 'string', description: '项目根目录(可选,默认当前项目)' },
|
|
26
|
+
threshold: { type: 'number', description: '相似度阈值,默认 0.5' },
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
handler: async (params, ctx) => {
|
|
30
|
+
let cand = params.candidate;
|
|
31
|
+
const projectRoot = params.projectRoot || ctx.projectRoot;
|
|
32
|
+
const threshold = params.threshold ?? 0.5;
|
|
33
|
+
|
|
34
|
+
// 如果提供 candidateId,从数据库读取条目信息
|
|
35
|
+
if (!cand && params.candidateId) {
|
|
36
|
+
try {
|
|
37
|
+
const knowledgeService = ctx.container.get('knowledgeService');
|
|
38
|
+
const found = await knowledgeService.get(params.candidateId);
|
|
39
|
+
if (found) {
|
|
40
|
+
const json = typeof found.toJSON === 'function' ? found.toJSON() : found;
|
|
41
|
+
cand = {
|
|
42
|
+
title: json.title || '',
|
|
43
|
+
summary: json.description || '',
|
|
44
|
+
code: json.content?.pattern || '',
|
|
45
|
+
usageGuide: '',
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
} catch {
|
|
49
|
+
/* ignore */
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!cand) {
|
|
54
|
+
return { similar: [], message: 'No candidate provided' };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const similar = findSimilarRecipes(projectRoot, cand, {
|
|
58
|
+
threshold,
|
|
59
|
+
topK: 10,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
similar,
|
|
64
|
+
hasDuplicate: similar.some((s) => s.similarity >= 0.7),
|
|
65
|
+
highestSimilarity: similar.length > 0 ? similar[0].similarity : 0,
|
|
66
|
+
_meta: {
|
|
67
|
+
confidence: similar.length === 0 ? 'none' : similar[0].similarity >= 0.7 ? 'high' : 'low',
|
|
68
|
+
hint:
|
|
69
|
+
similar.length === 0
|
|
70
|
+
? '未发现相似 Recipe,可放心提交。'
|
|
71
|
+
: similar[0].similarity >= 0.7
|
|
72
|
+
? '发现高度相似 Recipe,建议人工审核是否重复。'
|
|
73
|
+
: '有低相似度匹配,大概率不是重复。',
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// ────────────────────────────────────────────────────────────
|
|
80
|
+
// 12. add_graph_edge
|
|
81
|
+
// ────────────────────────────────────────────────────────────
|
|
82
|
+
export const addGraphEdge = {
|
|
83
|
+
name: 'add_graph_edge',
|
|
84
|
+
description: '手动添加知识图谱关系边(从 A 到 B 的关系)。',
|
|
85
|
+
parameters: {
|
|
86
|
+
type: 'object',
|
|
87
|
+
properties: {
|
|
88
|
+
fromId: { type: 'string', description: '源节点 ID' },
|
|
89
|
+
fromType: { type: 'string', description: '源节点类型 (recipe/candidate)' },
|
|
90
|
+
toId: { type: 'string', description: '目标节点 ID' },
|
|
91
|
+
toType: { type: 'string', description: '目标节点类型 (recipe/candidate)' },
|
|
92
|
+
relation: {
|
|
93
|
+
type: 'string',
|
|
94
|
+
description:
|
|
95
|
+
'关系类型 (requires/extends/enforces/depends_on/inherits/implements/calls/prerequisite)',
|
|
96
|
+
},
|
|
97
|
+
weight: { type: 'number', description: '权重 0-1,默认 1.0' },
|
|
98
|
+
},
|
|
99
|
+
required: ['fromId', 'fromType', 'toId', 'toType', 'relation'],
|
|
100
|
+
},
|
|
101
|
+
handler: async (params, ctx) => {
|
|
102
|
+
const kgService = ctx.container.get('knowledgeGraphService');
|
|
103
|
+
return kgService.addEdge(
|
|
104
|
+
params.fromId,
|
|
105
|
+
params.fromType,
|
|
106
|
+
params.toId,
|
|
107
|
+
params.toType,
|
|
108
|
+
params.relation,
|
|
109
|
+
{ weight: params.weight || 1.0, source: 'manual' }
|
|
110
|
+
);
|
|
111
|
+
},
|
|
112
|
+
};
|