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.
Files changed (114) hide show
  1. package/bin/cli.js +6 -5
  2. package/dashboard/dist/assets/index-BTAsOZv2.js +128 -0
  3. package/dashboard/dist/assets/index-C_72Ct98.css +1 -0
  4. package/dashboard/dist/index.html +2 -2
  5. package/lib/cli/AiScanService.js +23 -26
  6. package/lib/cli/SetupService.js +1 -1
  7. package/lib/cli/deploy/FileManifest.js +1 -1
  8. package/lib/core/AstAnalyzer.js +1 -1
  9. package/lib/core/discovery/index.js +2 -2
  10. package/lib/external/ai/AiProvider.js +66 -172
  11. package/lib/external/ai/providers/GoogleGeminiProvider.js +29 -5
  12. package/lib/external/mcp/handlers/bootstrap/BootstrapSession.js +1 -1
  13. package/lib/external/mcp/handlers/bootstrap/ExternalSubmissionTracker.js +3 -3
  14. package/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.js +1 -1
  15. package/lib/external/mcp/handlers/bootstrap/pipeline/IncrementalBootstrap.js +1 -1
  16. package/lib/external/mcp/handlers/bootstrap/pipeline/dimension-context.js +8 -8
  17. package/lib/external/mcp/handlers/bootstrap/pipeline/noAiFallback.js +1 -1
  18. package/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +291 -204
  19. package/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +7 -6
  20. package/lib/external/mcp/handlers/bootstrap/shared/dimension-sop.js +1 -1
  21. package/lib/external/mcp/handlers/bootstrap-internal.js +2 -2
  22. package/lib/external/mcp/handlers/dimension-complete-external.js +6 -6
  23. package/lib/http/HttpServer.js +1 -1
  24. package/lib/http/middleware/requestLogger.js +1 -0
  25. package/lib/http/routes/ai.js +240 -35
  26. package/lib/http/routes/candidates.js +2 -3
  27. package/lib/http/routes/extract.js +13 -11
  28. package/lib/http/routes/modules.js +2 -2
  29. package/lib/http/routes/recipes.js +5 -5
  30. package/lib/http/routes/remote.js +134 -255
  31. package/lib/http/routes/violations.js +0 -54
  32. package/lib/http/utils/sse-sessions.js +1 -1
  33. package/lib/infrastructure/logging/Logger.js +5 -4
  34. package/lib/infrastructure/monitoring/PerformanceMonitor.js +3 -2
  35. package/lib/injection/ServiceContainer.js +64 -17
  36. package/lib/platform/ScreenCaptureService.js +177 -0
  37. package/lib/platform/ios/routes/spm.js +2 -2
  38. package/lib/service/agent/AgentEventBus.js +207 -0
  39. package/lib/service/agent/AgentFactory.js +535 -0
  40. package/lib/service/agent/AgentMessage.js +240 -0
  41. package/lib/service/agent/AgentRouter.js +228 -0
  42. package/lib/service/agent/AgentRuntime.js +1056 -0
  43. package/lib/service/agent/AgentState.js +217 -0
  44. package/lib/service/agent/IntentClassifier.js +331 -0
  45. package/lib/service/agent/LarkTransport.js +389 -0
  46. package/lib/service/agent/capabilities.js +409 -0
  47. package/lib/service/{chat → agent/context}/ContextWindow.js +37 -12
  48. package/lib/service/{chat → agent/context}/ExplorationTracker.js +112 -33
  49. package/lib/service/{chat → agent/core}/ChatAgentPrompts.js +5 -3
  50. package/lib/service/agent/core/LoopContext.js +170 -0
  51. package/lib/service/agent/core/MessageAdapter.js +223 -0
  52. package/lib/service/agent/core/ToolExecutionPipeline.js +376 -0
  53. package/lib/service/{chat → agent/domain}/ChatAgentTasks.js +15 -98
  54. package/lib/service/{chat → agent/domain}/EpisodicConsolidator.js +7 -7
  55. package/lib/service/{chat → agent/domain}/EvidenceCollector.js +4 -2
  56. package/lib/service/{chat/AnalystAgent.js → agent/domain/insight-analyst.js} +37 -172
  57. package/lib/service/{chat/HandoffProtocol.js → agent/domain/insight-gate.js} +85 -135
  58. package/lib/service/agent/domain/insight-producer.js +270 -0
  59. package/lib/service/agent/domain/scan-prompts.js +444 -0
  60. package/lib/service/agent/forced-summary.js +266 -0
  61. package/lib/service/agent/index.js +91 -0
  62. package/lib/service/{chat → agent}/memory/ActiveContext.js +29 -1
  63. package/lib/service/{chat → agent}/memory/MemoryCoordinator.js +7 -7
  64. package/lib/service/{chat/ProjectSemanticMemory.js → agent/memory/PersistentMemory.js} +359 -89
  65. package/lib/service/{chat → agent}/memory/SessionStore.js +1 -1
  66. package/lib/service/{chat → agent}/memory/index.js +1 -1
  67. package/lib/service/agent/policies.js +442 -0
  68. package/lib/service/agent/presets.js +305 -0
  69. package/lib/service/agent/strategies.js +756 -0
  70. package/lib/service/{chat → agent/tools}/ToolRegistry.js +3 -3
  71. package/lib/service/agent/tools/ai-analysis.js +75 -0
  72. package/lib/service/{chat → agent}/tools/composite.js +2 -1
  73. package/lib/service/{chat → agent}/tools/guard.js +1 -121
  74. package/lib/service/{chat → agent}/tools/index.js +27 -21
  75. package/lib/service/{chat → agent}/tools/infrastructure.js +1 -1
  76. package/lib/service/agent/tools/knowledge-graph.js +112 -0
  77. package/lib/service/agent/tools/scan-recipe.js +189 -0
  78. package/lib/service/agent/tools/system-interaction.js +476 -0
  79. package/lib/service/automation/DirectiveDetector.js +0 -1
  80. package/lib/service/automation/FileWatcher.js +0 -8
  81. package/lib/service/automation/handlers/CreateHandler.js +7 -3
  82. package/lib/service/automation/handlers/DraftHandler.js +7 -6
  83. package/lib/service/module/ModuleService.js +40 -73
  84. package/lib/service/skills/SignalCollector.js +26 -19
  85. package/lib/service/snippet/codecs/VSCodeCodec.js +1 -1
  86. package/lib/shared/FieldSpec.js +1 -1
  87. package/lib/shared/StyleGuide.js +1 -1
  88. package/package.json +4 -1
  89. package/resources/native-ui/screenshot.swift +228 -0
  90. package/dashboard/dist/assets/index-D5jiDBQG.css +0 -1
  91. package/dashboard/dist/assets/index-e5OKj-Ni.js +0 -128
  92. package/lib/core/discovery/SpmDiscoverer.js +0 -5
  93. package/lib/external/mcp/handlers/bootstrap/pipeline/EpisodicMemory.js +0 -750
  94. package/lib/external/mcp/handlers/bootstrap/pipeline/ToolResultCache.js +0 -277
  95. package/lib/http/routes/spm.js +0 -5
  96. package/lib/infrastructure/external/XcodeAutomation.js +0 -15
  97. package/lib/service/chat/ChatAgent.js +0 -1602
  98. package/lib/service/chat/Memory.js +0 -161
  99. package/lib/service/chat/ProducerAgent.js +0 -431
  100. package/lib/service/chat/ReasoningTrace.js +0 -523
  101. package/lib/service/chat/TaskPipeline.js +0 -357
  102. package/lib/service/chat/WorkingMemory.js +0 -359
  103. package/lib/service/chat/memory/PersistentMemory.js +0 -450
  104. package/lib/service/chat/tools/ai-analysis.js +0 -267
  105. package/lib/service/chat/tools/knowledge-graph.js +0 -234
  106. package/lib/service/chat/tools.js +0 -18
  107. package/lib/service/snippet/PlaceholderConverter.js +0 -5
  108. package/lib/service/snippet/codecs/XcodeCodec.js +0 -5
  109. /package/lib/service/{chat → agent}/ConversationStore.js +0 -0
  110. /package/lib/service/{chat → agent}/tools/_shared.js +0 -0
  111. /package/lib/service/{chat → agent}/tools/ast-graph.js +0 -0
  112. /package/lib/service/{chat → agent}/tools/lifecycle.js +0 -0
  113. /package/lib/service/{chat → agent}/tools/project-access.js +0 -0
  114. /package/lib/service/{chat → agent}/tools/query.js +0 -0
@@ -0,0 +1,305 @@
1
+ /**
2
+ * Presets — 命名的 Agent 配置组合
3
+ *
4
+ * 核心思想: Agent 不分"类型",只有"配置"。
5
+ * Preset 是 Capability + Strategy + Policy 的命名组合。
6
+ *
7
+ * 这是统一架构的最终体现:
8
+ *
9
+ * | 使用场景 | Capabilities | Strategy | Policies |
10
+ * |------------------|--------------------------|--------------|---------------------|
11
+ * | chat | Conv + Analysis | Single | StandardBudget |
12
+ * | insight | Analysis + Production | FanOut+Pipe | DeepBudget+Quality |
13
+ * | remote-exec | Conv + Analysis + System | Single | ShortBudget+Safety |
14
+ *
15
+ * 注意:
16
+ * - "飞书聊天" 用 chat preset,不需要单独的 Agent
17
+ * - "飞书远程执行" 用 remote-exec preset,Safety 由 Policy 提供
18
+ * - "冷启动" 和 "扫描" 统一使用 insight preset,仅编排层不同
19
+ *
20
+ * @module presets
21
+ */
22
+
23
+ import { BudgetPolicy, SafetyPolicy, QualityGatePolicy } from './policies.js';
24
+ import { SingleStrategy, PipelineStrategy, FanOutStrategy, AdaptiveStrategy } from './strategies.js';
25
+
26
+ // v3.0: 导入 Insight 领域函数 (domain/ 模块)
27
+ import {
28
+ buildAnalystPrompt, ANALYST_SYSTEM_PROMPT, ANALYST_BUDGET,
29
+ } from './domain/insight-analyst.js';
30
+ import {
31
+ insightGateEvaluator, buildRetryPrompt,
32
+ } from './domain/insight-gate.js';
33
+ import {
34
+ buildProducerPromptV2, PRODUCER_SYSTEM_PROMPT, PRODUCER_BUDGET,
35
+ producerRejectionGateEvaluator,
36
+ } from './domain/insight-producer.js';
37
+
38
+ // ─── Preset 定义 ──────────────────────────────
39
+
40
+ /**
41
+ * @typedef {Object} PresetConfig
42
+ * @property {string} name — 人类可读名称
43
+ * @property {string} description — 描述
44
+ * @property {string[]} capabilities — Capability 名称列表
45
+ * @property {Object} strategy — Strategy 配置 { type, ...opts }
46
+ * @property {Array<Object>} policies — Policy 实例或配置
47
+ * @property {Object} [persona] — 人格/角色配置
48
+ * @property {Object} [memory] — 记忆配置
49
+ */
50
+
51
+ /**
52
+ * 所有内置 Preset
53
+ */
54
+ export const PRESETS = Object.freeze({
55
+
56
+ // ─── chat: 通用对话 ──────────────────────
57
+
58
+ chat: {
59
+ name: '对话',
60
+ description: '多轮对话、知识检索、代码问答。适用于 Dashboard 和飞书的常规对话。',
61
+ capabilities: ['conversation', 'code_analysis'],
62
+ strategy: { type: 'single' },
63
+ policies: [
64
+ new BudgetPolicy({ maxIterations: 8, maxTokens: 4096, temperature: 0.7, timeoutMs: 120_000 }),
65
+ ],
66
+ persona: {
67
+ role: 'assistant',
68
+ description: 'AutoSnippet 知识管理助手',
69
+ },
70
+ memory: {
71
+ enabled: true,
72
+ mode: 'user',
73
+ tiers: ['working', 'episodic', 'semantic'],
74
+ },
75
+ },
76
+
77
+ // ─── insight: 深度代码分析 + 知识产出 ────────
78
+ //
79
+ // v3.0 重设计: PipelineStrategy 增强版
80
+ // - 每个 stage 有 systemPrompt + promptBuilder (替代通用 Capability prompt)
81
+ // - Quality Gate 使用自定义 evaluator (三态: pass/retry/degrade)
82
+ // - Rejection Gate 监控 Producer 拒绝率
83
+ // - promptBuilder 通过 strategyContext 获取运行时数据 (dimConfig/sessionStore/...)
84
+ //
85
+ // orchestrator 通过 createRuntime('insight', { strategy: {...} }) 按需覆盖
86
+ // onToolCall 由 orchestrator 按维度注入 (闭包引用 ActiveContext)
87
+
88
+ insight: {
89
+ name: '洞察',
90
+ description: '深度代码分析 + 知识提取。增强 PipelineStrategy: Analyze→QualityGate→Produce→RejectionGate。',
91
+ capabilities: ['code_analysis', 'knowledge_production'],
92
+ strategy: {
93
+ type: 'pipeline',
94
+ maxRetries: 1,
95
+ stages: [
96
+ // ── Phase 1: Analyst ──
97
+ {
98
+ name: 'analyze',
99
+ capabilities: ['code_analysis'],
100
+ budget: { maxIterations: ANALYST_BUDGET.maxIterations, temperature: 0.4, timeoutMs: 300_000 },
101
+ systemPrompt: ANALYST_SYSTEM_PROMPT,
102
+ promptBuilder: (ctx) => buildAnalystPrompt(
103
+ ctx.dimConfig, ctx.projectInfo,
104
+ ctx.dimContext, ctx.sessionStore, ctx.semanticMemory, ctx.codeEntityGraph,
105
+ ),
106
+ retryPromptBuilder: (retryCtx, _origPrompt, prev) => {
107
+ const prevAnalysis = prev.analyze?.reply || '';
108
+ const retryHint = buildRetryPrompt(retryCtx.reason);
109
+ return `${prevAnalysis}\n\n⚠️ 上述分析未通过质量检查: ${retryCtx.reason}\n\n${retryHint}`;
110
+ },
111
+ // onToolCall: 由 orchestrator 按维度注入
112
+ },
113
+
114
+ // ── Phase 2: Quality Gate ──
115
+ {
116
+ name: 'quality_gate',
117
+ gate: {
118
+ evaluator: insightGateEvaluator,
119
+ maxRetries: 1,
120
+ },
121
+ },
122
+
123
+ // ── Phase 3: Producer ──
124
+ {
125
+ name: 'produce',
126
+ capabilities: ['knowledge_production'],
127
+ // 透传完整 PRODUCER_BUDGET (searchBudget/maxSubmits/softSubmitLimit/idleRoundsToExit)
128
+ // 供 ExplorationTracker 精确控制 PRODUCE→SUMMARIZE 转换时机
129
+ budget: { ...PRODUCER_BUDGET, temperature: 0.3, timeoutMs: 180_000 },
130
+ systemPrompt: PRODUCER_SYSTEM_PROMPT,
131
+ promptBuilder: (ctx) => buildProducerPromptV2(
132
+ ctx.gateArtifact, // 来自 quality_gate 的 AnalysisArtifact
133
+ ctx.dimConfig, ctx.projectInfo,
134
+ ),
135
+ // 拒绝率过高时: 缩减预算 + 特定修复 prompt (对齐旧 ProducerAgent 的 rejection retry)
136
+ retryBudget: { maxIterations: 5, temperature: 0.3, timeoutMs: 120_000 },
137
+ retryPromptBuilder: (retryCtx, _origPrompt, prev) => {
138
+ const prevProduce = prev.produce;
139
+ const submitCalls = (prevProduce?.toolCalls || []).filter(tc =>
140
+ ['submit_knowledge', 'submit_with_check'].includes(tc.tool || tc.name));
141
+ const rejected = submitCalls.filter(tc => {
142
+ const res = tc.result;
143
+ if (!res) return false;
144
+ if (typeof res === 'string') return res.includes('rejected') || res.includes('error');
145
+ return res.status === 'rejected' || res.status === 'error' || res.reason === 'validation_failed';
146
+ }).length;
147
+ return `你的 ${rejected} 个提交被拒绝了。请根据拒绝原因改进后重新提交,确保:
148
+ 1. content 必须是对象: { markdown: "...", rationale: "...", pattern: "..." }
149
+ 2. content.markdown 字段 ≥ 200 字符,含代码块 (\`\`\`)
150
+ 3. content.rationale 必填 — 设计原理说明(为什么这样设计)
151
+ 4. 包含来源标注 (来源: FileName.m:行号)
152
+ 5. 标题使用项目真实类名
153
+ 6. 必填: trigger (@kebab-case)、kind (rule/pattern/fact)、doClause (英文祈使句)`;
154
+ },
155
+ skipOnDegrade: true,
156
+ },
157
+
158
+ // ── Phase 4: Rejection Gate ──
159
+ {
160
+ name: 'rejection_gate',
161
+ gate: {
162
+ evaluator: producerRejectionGateEvaluator,
163
+ maxRetries: 1,
164
+ },
165
+ skipOnDegrade: true,
166
+ },
167
+ ],
168
+ },
169
+ policies: [
170
+ new BudgetPolicy({ maxIterations: 24, maxTokens: 4096, temperature: 0.3, timeoutMs: 600_000 }),
171
+ new QualityGatePolicy({ minEvidenceLength: 500, minFileRefs: 3, minToolCalls: 3 }),
172
+ ],
173
+ persona: {
174
+ role: 'analyst',
175
+ description: '高级软件架构师 + 知识管理专家',
176
+ },
177
+ memory: {
178
+ enabled: false, // 无状态 worker
179
+ },
180
+ },
181
+
182
+ // ─── lark: 飞书知识管理对话 ─────────────
183
+
184
+ lark: {
185
+ name: '飞书对话',
186
+ description: '通过飞书自然语言进行知识管理、代码分析、项目理解。服务端直接处理,不转发 IDE。',
187
+ capabilities: ['conversation', 'code_analysis'],
188
+ strategy: { type: 'single' },
189
+ policies: [
190
+ new BudgetPolicy({ maxIterations: 12, maxTokens: 4096, temperature: 0.7, timeoutMs: 180_000 }),
191
+ new SafetyPolicy({
192
+ allowedSenders: process.env.ASD_LARK_ALLOWED_USERS?.split(',').filter(Boolean) || [],
193
+ }),
194
+ ],
195
+ persona: {
196
+ role: 'assistant',
197
+ description: 'AutoSnippet 知识管理助手 (飞书)。用中文回复,简洁专业。',
198
+ },
199
+ memory: {
200
+ enabled: true,
201
+ mode: 'user',
202
+ tiers: ['working', 'episodic', 'semantic'],
203
+ },
204
+ },
205
+
206
+ // ─── remote-exec: 远程执行 ──────────────
207
+
208
+ 'remote-exec': {
209
+ name: '远程执行',
210
+ description: '通过飞书/远程终端执行本地操作。搭配 SafetyPolicy 保障安全。',
211
+ capabilities: ['conversation', 'code_analysis', 'system_interaction'],
212
+ strategy: { type: 'single' },
213
+ policies: [
214
+ new BudgetPolicy({ maxIterations: 6, maxTokens: 2048, temperature: 0.5, timeoutMs: 60_000 }),
215
+ new SafetyPolicy({
216
+ // 实际部署时从环境变量读取 allowedSenders
217
+ allowedSenders: process.env.ASD_LARK_ALLOWED_USERS?.split(',').filter(Boolean) || [],
218
+ fileScope: process.env.ASD_PROJECT_ROOT || null,
219
+ }),
220
+ ],
221
+ persona: {
222
+ role: 'assistant',
223
+ description: 'AutoSnippet 远程编程助手',
224
+ },
225
+ memory: {
226
+ enabled: true,
227
+ mode: 'user',
228
+ tiers: ['working', 'episodic'],
229
+ },
230
+ },
231
+
232
+ });
233
+
234
+ // ─── Preset 解析器 ────────────────────────────
235
+
236
+ /**
237
+ * 将 Preset 配置中的 strategy 声明式配置转换为实际 Strategy 实例
238
+ *
239
+ * @param {Object} strategyConfig — { type: 'single'|'pipeline'|'fan_out'|'adaptive', ...opts }
240
+ * @returns {import('./strategies.js').Strategy}
241
+ */
242
+ export function resolveStrategy(strategyConfig) {
243
+ if (!strategyConfig) return new SingleStrategy();
244
+
245
+ switch (strategyConfig.type) {
246
+ case 'single':
247
+ return new SingleStrategy();
248
+
249
+ case 'pipeline':
250
+ return new PipelineStrategy({
251
+ stages: strategyConfig.stages || [],
252
+ maxRetries: strategyConfig.maxRetries,
253
+ });
254
+
255
+ case 'fan_out': {
256
+ const itemStrategy = strategyConfig.itemStrategy
257
+ ? resolveStrategy(strategyConfig.itemStrategy)
258
+ : new SingleStrategy();
259
+ return new FanOutStrategy({
260
+ itemStrategy,
261
+ tiers: strategyConfig.tiers,
262
+ merge: strategyConfig.merge,
263
+ });
264
+ }
265
+
266
+ case 'adaptive':
267
+ return new AdaptiveStrategy({
268
+ single: strategyConfig.single ? resolveStrategy(strategyConfig.single) : undefined,
269
+ pipeline: strategyConfig.pipeline ? resolveStrategy(strategyConfig.pipeline) : undefined,
270
+ fanOut: strategyConfig.fanOut ? resolveStrategy(strategyConfig.fanOut) : undefined,
271
+ });
272
+
273
+ default:
274
+ throw new Error(`Unknown strategy type: ${strategyConfig.type}`);
275
+ }
276
+ }
277
+
278
+ /**
279
+ * 获取 Preset 并展开为可用配置
280
+ *
281
+ * @param {string} presetName
282
+ * @param {Object} [overrides] — 覆盖 preset 中的特定字段
283
+ * @returns {PresetConfig & { strategyInstance: Strategy }}
284
+ */
285
+ export function getPreset(presetName, overrides = {}) {
286
+ const preset = PRESETS[presetName];
287
+ if (!preset) throw new Error(`Unknown preset: "${presetName}". Available: ${Object.keys(PRESETS).join(', ')}`);
288
+
289
+ const merged = {
290
+ ...preset,
291
+ ...overrides,
292
+ capabilities: overrides.capabilities || preset.capabilities,
293
+ policies: overrides.policies || preset.policies,
294
+ persona: { ...preset.persona, ...overrides.persona },
295
+ memory: { ...preset.memory, ...overrides.memory },
296
+ };
297
+
298
+ // 解析 strategy
299
+ const strategyConfig = overrides.strategy || preset.strategy;
300
+ merged.strategyInstance = resolveStrategy(strategyConfig);
301
+
302
+ return merged;
303
+ }
304
+
305
+ export default { PRESETS, resolveStrategy, getPreset };