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
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentEventBus — Agent 间事件通信总线
|
|
3
|
+
*
|
|
4
|
+
* 借鉴 AutoGen Core Event-Driven 架构 + RxJS Observable 模式:
|
|
5
|
+
* - Agent 间松耦合通信(publish/subscribe)
|
|
6
|
+
* - 支持同步和异步事件处理
|
|
7
|
+
* - 内置事件过滤、优先级、TTL
|
|
8
|
+
* - 支持 request/reply 模式(Agent 间 RPC)
|
|
9
|
+
*
|
|
10
|
+
* @module AgentEventBus
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { EventEmitter } from 'node:events';
|
|
14
|
+
import Logger from '../../infrastructure/logging/Logger.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 标准事件类型
|
|
18
|
+
*/
|
|
19
|
+
export const AgentEvents = Object.freeze({
|
|
20
|
+
// ── 生命周期 ──
|
|
21
|
+
AGENT_CREATED: 'agent:created',
|
|
22
|
+
AGENT_STARTED: 'agent:started',
|
|
23
|
+
AGENT_COMPLETED: 'agent:completed',
|
|
24
|
+
AGENT_FAILED: 'agent:failed',
|
|
25
|
+
AGENT_ABORTED: 'agent:aborted',
|
|
26
|
+
|
|
27
|
+
// ── 执行 ──
|
|
28
|
+
TOOL_CALL_START: 'tool:call:start',
|
|
29
|
+
TOOL_CALL_END: 'tool:call:end',
|
|
30
|
+
LLM_CALL_START: 'llm:call:start',
|
|
31
|
+
LLM_CALL_END: 'llm:call:end',
|
|
32
|
+
STEP_COMPLETED: 'step:completed',
|
|
33
|
+
|
|
34
|
+
// ── Agent 间交互 ──
|
|
35
|
+
HANDOFF_REQUEST: 'handoff:request',
|
|
36
|
+
HANDOFF_ACCEPT: 'handoff:accept',
|
|
37
|
+
HANDOFF_RESULT: 'handoff:result',
|
|
38
|
+
|
|
39
|
+
// ── 进度 ──
|
|
40
|
+
PROGRESS: 'progress',
|
|
41
|
+
THINKING: 'thinking',
|
|
42
|
+
STREAM_DELTA: 'stream:delta',
|
|
43
|
+
|
|
44
|
+
// ── 外部触发 ──
|
|
45
|
+
USER_INPUT: 'user:input',
|
|
46
|
+
LARK_MESSAGE: 'lark:message',
|
|
47
|
+
SCAN_REQUEST: 'scan:request',
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @typedef {Object} AgentEvent
|
|
52
|
+
* @property {string} type — 事件类型
|
|
53
|
+
* @property {string} source — 发送者 agentId
|
|
54
|
+
* @property {string} [target] — 目标 agentId(广播时为 null)
|
|
55
|
+
* @property {Object} payload — 事件数据
|
|
56
|
+
* @property {number} timestamp — 事件时间戳
|
|
57
|
+
* @property {string} [correlationId] — 关联 ID(用于 request/reply)
|
|
58
|
+
*/
|
|
59
|
+
|
|
60
|
+
export class AgentEventBus extends EventEmitter {
|
|
61
|
+
/** @type {AgentEventBus|null} */
|
|
62
|
+
static #instance = null;
|
|
63
|
+
#logger;
|
|
64
|
+
/** @type {Map<string, Function[]>} topic → handlers */
|
|
65
|
+
#subscriptions = new Map();
|
|
66
|
+
/** @type {Map<string, {resolve: Function, reject: Function, timer: NodeJS.Timeout}>} */
|
|
67
|
+
#pendingReplies = new Map();
|
|
68
|
+
/** @type {number} 事件计数 */
|
|
69
|
+
#eventCount = 0;
|
|
70
|
+
|
|
71
|
+
constructor() {
|
|
72
|
+
super();
|
|
73
|
+
this.setMaxListeners(100);
|
|
74
|
+
this.#logger = Logger.getInstance();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* 获取全局单例
|
|
79
|
+
* @returns {AgentEventBus}
|
|
80
|
+
*/
|
|
81
|
+
static getInstance() {
|
|
82
|
+
if (!AgentEventBus.#instance) {
|
|
83
|
+
AgentEventBus.#instance = new AgentEventBus();
|
|
84
|
+
}
|
|
85
|
+
return AgentEventBus.#instance;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* 重置单例(测试用)
|
|
90
|
+
*/
|
|
91
|
+
static resetInstance() {
|
|
92
|
+
if (AgentEventBus.#instance) {
|
|
93
|
+
AgentEventBus.#instance.removeAllListeners();
|
|
94
|
+
AgentEventBus.#instance.#subscriptions.clear();
|
|
95
|
+
AgentEventBus.#instance.#pendingReplies.clear();
|
|
96
|
+
}
|
|
97
|
+
AgentEventBus.#instance = null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ─── 发布 ────────────────────────────────
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* 发布事件(广播)
|
|
104
|
+
* @param {string} type — 事件类型
|
|
105
|
+
* @param {Object} payload — 事件数据
|
|
106
|
+
* @param {Object} [opts]
|
|
107
|
+
* @param {string} [opts.source] — 发送者 agentId
|
|
108
|
+
* @param {string} [opts.target] — 目标 agentId
|
|
109
|
+
* @param {string} [opts.correlationId] — 关联 ID
|
|
110
|
+
*/
|
|
111
|
+
publish(type, payload = {}, opts = {}) {
|
|
112
|
+
this.#eventCount++;
|
|
113
|
+
const event = {
|
|
114
|
+
type,
|
|
115
|
+
source: opts.source || 'system',
|
|
116
|
+
target: opts.target || null,
|
|
117
|
+
payload,
|
|
118
|
+
timestamp: Date.now(),
|
|
119
|
+
correlationId: opts.correlationId || null,
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
// 发射到 EventEmitter(通用监听)
|
|
123
|
+
this.emit(type, event);
|
|
124
|
+
this.emit('*', event); // 全局监听
|
|
125
|
+
|
|
126
|
+
// 发射到 topic 订阅者
|
|
127
|
+
const handlers = this.#subscriptions.get(type) || [];
|
|
128
|
+
for (const handler of handlers) {
|
|
129
|
+
try {
|
|
130
|
+
handler(event);
|
|
131
|
+
} catch (err) {
|
|
132
|
+
this.#logger.warn(`[AgentEventBus] Handler error on ${type}: ${err.message}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// 检查是否有 pending reply
|
|
137
|
+
if (opts.correlationId && this.#pendingReplies.has(opts.correlationId)) {
|
|
138
|
+
const pending = this.#pendingReplies.get(opts.correlationId);
|
|
139
|
+
clearTimeout(pending.timer);
|
|
140
|
+
this.#pendingReplies.delete(opts.correlationId);
|
|
141
|
+
pending.resolve(event);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* 订阅事件
|
|
147
|
+
* @param {string} type — 事件类型
|
|
148
|
+
* @param {Function} handler — 处理函数 (event) => void
|
|
149
|
+
* @returns {Function} 取消订阅函数
|
|
150
|
+
*/
|
|
151
|
+
subscribe(type, handler) {
|
|
152
|
+
if (!this.#subscriptions.has(type)) {
|
|
153
|
+
this.#subscriptions.set(type, []);
|
|
154
|
+
}
|
|
155
|
+
this.#subscriptions.get(type).push(handler);
|
|
156
|
+
|
|
157
|
+
return () => {
|
|
158
|
+
const handlers = this.#subscriptions.get(type);
|
|
159
|
+
if (handlers) {
|
|
160
|
+
const idx = handlers.indexOf(handler);
|
|
161
|
+
if (idx >= 0) handlers.splice(idx, 1);
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Request/Reply 模式 — 发送请求并等待响应
|
|
168
|
+
* @param {string} requestType — 请求事件类型
|
|
169
|
+
* @param {Object} payload — 请求数据
|
|
170
|
+
* @param {Object} [opts]
|
|
171
|
+
* @param {number} [opts.timeout=30000] — 超时毫秒
|
|
172
|
+
* @param {string} [opts.source] — 发送者
|
|
173
|
+
* @returns {Promise<AgentEvent>} 响应事件
|
|
174
|
+
*/
|
|
175
|
+
async request(requestType, payload = {}, opts = {}) {
|
|
176
|
+
const correlationId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
177
|
+
const timeout = opts.timeout || 30_000;
|
|
178
|
+
|
|
179
|
+
return new Promise((resolve, reject) => {
|
|
180
|
+
const timer = setTimeout(() => {
|
|
181
|
+
this.#pendingReplies.delete(correlationId);
|
|
182
|
+
reject(new Error(`AgentEventBus request timeout: ${requestType} (${timeout}ms)`));
|
|
183
|
+
}, timeout);
|
|
184
|
+
|
|
185
|
+
this.#pendingReplies.set(correlationId, { resolve, reject, timer });
|
|
186
|
+
|
|
187
|
+
this.publish(requestType, payload, {
|
|
188
|
+
source: opts.source,
|
|
189
|
+
correlationId,
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* 获取事件统计
|
|
196
|
+
* @returns {Object}
|
|
197
|
+
*/
|
|
198
|
+
getStats() {
|
|
199
|
+
return {
|
|
200
|
+
totalEvents: this.#eventCount,
|
|
201
|
+
subscriptionTopics: this.#subscriptions.size,
|
|
202
|
+
pendingReplies: this.#pendingReplies.size,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export default AgentEventBus;
|
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentFactory — 统一 Agent 创建工厂
|
|
3
|
+
*
|
|
4
|
+
* 在新架构中,Factory 的职责是:
|
|
5
|
+
* - 将 Preset 配置 + DI 依赖 → AgentRuntime 实例
|
|
6
|
+
* - 提供 Router (intent → preset → runtime)
|
|
7
|
+
* - 提供快捷方法 (createChat, createInsight, ...)
|
|
8
|
+
*
|
|
9
|
+
* 关键变化 (vs 旧 AgentFactory):
|
|
10
|
+
* - 不再创建独立 Agent 子类
|
|
11
|
+
* - 只创建 AgentRuntime,通过 Preset 配置差异化行为
|
|
12
|
+
* - 同一个工厂,同一种 Runtime,不同的配置
|
|
13
|
+
*
|
|
14
|
+
* @module AgentFactory
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import Logger from '../../infrastructure/logging/Logger.js';
|
|
18
|
+
import { AgentMessage } from './AgentMessage.js';
|
|
19
|
+
import { AgentRouter, PresetName } from './AgentRouter.js';
|
|
20
|
+
import { AgentRuntime } from './AgentRuntime.js';
|
|
21
|
+
import { CapabilityRegistry } from './capabilities.js';
|
|
22
|
+
import { BudgetPolicy, PolicyEngine } from './policies.js';
|
|
23
|
+
import { getPreset, resolveStrategy } from './presets.js';
|
|
24
|
+
import { ContextWindow } from './context/ContextWindow.js';
|
|
25
|
+
import { ExplorationTracker } from './context/ExplorationTracker.js';
|
|
26
|
+
import { ANALYST_SYSTEM_PROMPT } from './domain/insight-analyst.js';
|
|
27
|
+
import { SCAN_TASK_CONFIGS } from './domain/scan-prompts.js';
|
|
28
|
+
|
|
29
|
+
export class AgentFactory {
|
|
30
|
+
#container;
|
|
31
|
+
#toolRegistry;
|
|
32
|
+
#aiProvider;
|
|
33
|
+
#logger;
|
|
34
|
+
/** @type {AgentRouter|null} */
|
|
35
|
+
#router = null;
|
|
36
|
+
/** @type {Object} 共享的 Capability 实例缓存 (如 MemoryCoordinator) */
|
|
37
|
+
#sharedOpts;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {Object} opts
|
|
41
|
+
* @param {Object} opts.container — ServiceContainer 实例
|
|
42
|
+
* @param {import('./tools/ToolRegistry.js').ToolRegistry} opts.toolRegistry
|
|
43
|
+
* @param {import('../../external/ai/AiProvider.js').AiProvider} opts.aiProvider
|
|
44
|
+
* @param {Object} [opts.memoryCoordinator] — MemoryCoordinator 实例 (注入 Conversation)
|
|
45
|
+
* @param {string} [opts.projectBriefing] — 项目概况文本
|
|
46
|
+
* @param {string} [opts.projectRoot] — 项目根目录
|
|
47
|
+
*/
|
|
48
|
+
constructor({ container, toolRegistry, aiProvider, memoryCoordinator, projectBriefing, projectRoot }) {
|
|
49
|
+
this.#container = container;
|
|
50
|
+
this.#toolRegistry = toolRegistry;
|
|
51
|
+
this.#aiProvider = aiProvider;
|
|
52
|
+
this.#logger = Logger.getInstance();
|
|
53
|
+
this.#sharedOpts = {
|
|
54
|
+
memoryCoordinator: memoryCoordinator || null,
|
|
55
|
+
projectBriefing: projectBriefing || null,
|
|
56
|
+
projectRoot: projectRoot || process.cwd(),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ─── Router ──────────────────────────────────
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* 创建带路由器的自动调度系统
|
|
64
|
+
* @returns {AgentRouter}
|
|
65
|
+
*/
|
|
66
|
+
createRouter() {
|
|
67
|
+
if (this.#router) return this.#router;
|
|
68
|
+
|
|
69
|
+
const router = new AgentRouter();
|
|
70
|
+
router.setAiProvider(this.#aiProvider);
|
|
71
|
+
router.setExecutor((presetName, message, opts) => {
|
|
72
|
+
const runtime = this.createRuntime(presetName, opts);
|
|
73
|
+
return runtime.execute(message, opts.strategyOpts || opts);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
this.#router = router;
|
|
77
|
+
this.#logger.info('[AgentFactory] Router created');
|
|
78
|
+
return router;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// ─── 核心创建方法 ─────────────────────────────
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* 根据 Preset 名称创建 AgentRuntime
|
|
85
|
+
*
|
|
86
|
+
* 这是一切的根基 — 任何 "Agent 类型" 都通过这个方法创建。
|
|
87
|
+
*
|
|
88
|
+
* @param {string} presetName — Preset 名称 (chat/insight/remote-exec)
|
|
89
|
+
* @param {Object} [overrides] — 覆盖 preset 配置
|
|
90
|
+
* @returns {AgentRuntime}
|
|
91
|
+
*/
|
|
92
|
+
createRuntime(presetName, overrides = {}) {
|
|
93
|
+
const preset = getPreset(presetName, overrides);
|
|
94
|
+
|
|
95
|
+
// 实例化 Capabilities
|
|
96
|
+
const capabilities = preset.capabilities.map(name => {
|
|
97
|
+
const opts = this.#getCapabilityOpts(name);
|
|
98
|
+
return CapabilityRegistry.create(name, opts);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// 实例化 Policies
|
|
102
|
+
const policyEngine = new PolicyEngine(preset.policies || []);
|
|
103
|
+
|
|
104
|
+
return new AgentRuntime({
|
|
105
|
+
presetName,
|
|
106
|
+
aiProvider: this.#aiProvider,
|
|
107
|
+
toolRegistry: this.#toolRegistry,
|
|
108
|
+
container: this.#container,
|
|
109
|
+
capabilities,
|
|
110
|
+
strategy: preset.strategyInstance,
|
|
111
|
+
policies: policyEngine,
|
|
112
|
+
persona: preset.persona,
|
|
113
|
+
memory: preset.memory,
|
|
114
|
+
onProgress: overrides.onProgress || null,
|
|
115
|
+
onToolCall: overrides.onToolCall || null,
|
|
116
|
+
lang: overrides.lang || null,
|
|
117
|
+
additionalTools: overrides.additionalTools || [],
|
|
118
|
+
projectRoot: this.#sharedOpts.projectRoot,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// ─── 快捷方法 (语义化) ─────────────────────
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* 创建 ContextWindow (根据当前 AI Provider 自动解析 token 预算)
|
|
126
|
+
* @param {{ isSystem?: boolean }} [opts]
|
|
127
|
+
* @returns {ContextWindow}
|
|
128
|
+
*/
|
|
129
|
+
createContextWindow(opts = {}) {
|
|
130
|
+
const modelName = this.#aiProvider?.model || '';
|
|
131
|
+
const tokenBudget = ContextWindow.resolveTokenBudget(modelName, opts);
|
|
132
|
+
return new ContextWindow(tokenBudget);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* 构建系统级多轮执行上下文 — 统一基础设施
|
|
137
|
+
*
|
|
138
|
+
* 抽取 bootstrap orchestrator 中创建 ExplorationTracker / ContextWindow / source 的
|
|
139
|
+
* 通用逻辑,供 scanKnowledge 等系统场景共用完整的多轮 Agent 框架。
|
|
140
|
+
*
|
|
141
|
+
* bootstrap orchestrator 不使用此方法(它还需要领域特定的 MemoryCoordinator / dimContext 等),
|
|
142
|
+
* 但引擎层基础设施是一致的。
|
|
143
|
+
*
|
|
144
|
+
* @param {Object} [opts]
|
|
145
|
+
* @param {Object} [opts.budget] — 预算覆盖 (透传给 ExplorationTracker)
|
|
146
|
+
* @param {string} [opts.trackerStrategy='analyst'] — tracker 策略名: 'analyst' | 'producer' | 'bootstrap'
|
|
147
|
+
* @returns {{ contextWindow: ContextWindow, tracker: ExplorationTracker, sharedState: Object, source: string }}
|
|
148
|
+
*/
|
|
149
|
+
buildSystemContext({ budget, trackerStrategy = 'analyst' } = {}) {
|
|
150
|
+
return {
|
|
151
|
+
contextWindow: this.createContextWindow({ isSystem: true }),
|
|
152
|
+
tracker: ExplorationTracker.resolve(
|
|
153
|
+
{ source: 'system', strategy: trackerStrategy },
|
|
154
|
+
budget || {},
|
|
155
|
+
),
|
|
156
|
+
sharedState: {
|
|
157
|
+
submittedTitles: new Set(),
|
|
158
|
+
submittedPatterns: new Set(),
|
|
159
|
+
},
|
|
160
|
+
source: 'system',
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* 获取 AI Provider 信息 (供 orchestrator 等外部使用)
|
|
166
|
+
* @returns {{ model: string, name: string }}
|
|
167
|
+
*/
|
|
168
|
+
getAiProviderInfo() {
|
|
169
|
+
return {
|
|
170
|
+
model: this.#aiProvider?.model || 'unknown',
|
|
171
|
+
name: this.#aiProvider?.name || 'unknown',
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* 创建对话 Runtime (Dashboard / 飞书聊天)
|
|
177
|
+
* @param {Object} [opts]
|
|
178
|
+
*/
|
|
179
|
+
createChat(opts = {}) {
|
|
180
|
+
return this.createRuntime(PresetName.CHAT, opts);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* 创建洞察 Runtime (深度代码分析 + 知识提取)
|
|
185
|
+
* @param {Object} [opts]
|
|
186
|
+
* @param {Array} [opts.dimensions] — 维度列表 (传给 FanOutStrategy 的 items)
|
|
187
|
+
* @param {Object} [opts.projectInfo] — 项目信息
|
|
188
|
+
*/
|
|
189
|
+
createInsight(opts = {}) {
|
|
190
|
+
return this.createRuntime(PresetName.INSIGHT, opts);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* 创建飞书对话 Runtime (知识管理,服务端处理)
|
|
195
|
+
* @param {Object} [opts]
|
|
196
|
+
*/
|
|
197
|
+
createLark(opts = {}) {
|
|
198
|
+
return this.createRuntime(PresetName.LARK, opts);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* 创建远程执行 Runtime (飞书终端 / 远程操作)
|
|
203
|
+
* @param {Object} [opts]
|
|
204
|
+
*/
|
|
205
|
+
createRemoteExec(opts = {}) {
|
|
206
|
+
return this.createRuntime(PresetName.REMOTE_EXEC, opts);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// ─── 领域语义方法 (意图驱动, Agent 直接完成 AI 推理) ─────
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* 统一知识扫描 — 走 insight 管线 (Analyze → QualityGate → Produce)
|
|
213
|
+
*
|
|
214
|
+
* 三种任务模式共享同一管线,仅 Produce 阶段的 systemPrompt 不同。
|
|
215
|
+
* 替代: extractRecipes + summarizeCode + discoverRelations
|
|
216
|
+
*
|
|
217
|
+
* @param {Object} opts
|
|
218
|
+
* @param {string} opts.label — 上下文标签(target 名 / 文件名)
|
|
219
|
+
* @param {Array<{name, content, language?}>} opts.files — 源文件
|
|
220
|
+
* @param {'extract'|'summarize'|'relations'} [opts.task='extract'] — 任务类型
|
|
221
|
+
* @param {string} [opts.lang] — 语言提示
|
|
222
|
+
* @param {boolean} [opts.comprehensive] — 深度扫描标志
|
|
223
|
+
* @returns {Promise<Object>} — task-specific JSON
|
|
224
|
+
*/
|
|
225
|
+
async scanKnowledge({ label, files, task = 'extract', lang, comprehensive } = {}) {
|
|
226
|
+
const taskConfig = SCAN_TASK_CONFIGS[task];
|
|
227
|
+
if (!taskConfig) {
|
|
228
|
+
throw new Error(`Unknown scanKnowledge task: "${task}". Available: ${Object.keys(SCAN_TASK_CONFIGS).join(', ')}`);
|
|
229
|
+
}
|
|
230
|
+
const { producePrompt, fallback } = taskConfig;
|
|
231
|
+
|
|
232
|
+
// relations task 需要知识查询工具
|
|
233
|
+
const caps = task === 'relations'
|
|
234
|
+
? ['code_analysis', 'knowledge_production']
|
|
235
|
+
: ['code_analysis'];
|
|
236
|
+
|
|
237
|
+
// produce 阶段: extract 使用 scan_production(工具驱动,与冷启动一致),
|
|
238
|
+
// summarize/relations 保持纯文本输出
|
|
239
|
+
const produceCaps = task === 'extract'
|
|
240
|
+
? ['scan_production']
|
|
241
|
+
: [];
|
|
242
|
+
|
|
243
|
+
// ── Pipeline 配置 (与冷启动对齐: 24 轮标准) ──
|
|
244
|
+
const analyzeMaxIter = 24;
|
|
245
|
+
const stages = [
|
|
246
|
+
{
|
|
247
|
+
name: 'analyze',
|
|
248
|
+
capabilities: caps,
|
|
249
|
+
budget: { maxIterations: analyzeMaxIter, maxTokens: 8192, temperature: 0.3 },
|
|
250
|
+
systemPrompt: ANALYST_SYSTEM_PROMPT,
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
name: 'produce',
|
|
254
|
+
capabilities: produceCaps,
|
|
255
|
+
budget: { maxIterations: 24, temperature: 0.2 },
|
|
256
|
+
systemPrompt: producePrompt,
|
|
257
|
+
promptTransform: (_input, prev) => {
|
|
258
|
+
const analysis = prev.analyze?.reply || '';
|
|
259
|
+
if (analysis.length >= 200) {
|
|
260
|
+
return `将以下代码分析转化为结构化输出。\n\n## 代码分析\n${analysis}`;
|
|
261
|
+
}
|
|
262
|
+
// Fallback: analyze reply 不足时直接提供源代码
|
|
263
|
+
const fileCtx = (files || []).slice(0, 15).map(f => {
|
|
264
|
+
const body = f.content.length > 1200
|
|
265
|
+
? f.content.slice(0, 1200) + '\n// ... (truncated)'
|
|
266
|
+
: f.content;
|
|
267
|
+
return `### ${f.relativePath}\n\`\`\`\n${body}\n\`\`\``;
|
|
268
|
+
}).join('\n\n');
|
|
269
|
+
const preamble = analysis
|
|
270
|
+
? `## 部分分析\n${analysis}\n\n`
|
|
271
|
+
: '';
|
|
272
|
+
return `${preamble}分析以下 ${files?.length || 0} 个源文件,提取知识 Recipe。\n\n${fileCtx}`;
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
];
|
|
276
|
+
|
|
277
|
+
// ── 创建 Runtime — 使用 insight preset + 对齐 policies ──
|
|
278
|
+
// policies override: 让 Runtime 级 BudgetPolicy 与 stage budget 对齐
|
|
279
|
+
// (避免 insight preset 的 maxIterations:24 与 stage 的 10 冲突)
|
|
280
|
+
const runtime = this.createRuntime(PresetName.INSIGHT, {
|
|
281
|
+
strategy: { type: 'pipeline', stages },
|
|
282
|
+
capabilities: caps,
|
|
283
|
+
policies: [
|
|
284
|
+
new BudgetPolicy({
|
|
285
|
+
maxIterations: 30, // 24 stage budget + 6 tracker grace (SUMMARIZE 2轮 + 硬上限 buffer)
|
|
286
|
+
maxTokens: 8192,
|
|
287
|
+
temperature: 0.3,
|
|
288
|
+
timeoutMs: 600_000,
|
|
289
|
+
}),
|
|
290
|
+
],
|
|
291
|
+
memory: { enabled: false },
|
|
292
|
+
lang,
|
|
293
|
+
});
|
|
294
|
+
if (files?.length) {
|
|
295
|
+
runtime.setFileCache(files);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// ── 完整的系统级多轮基础设施 ──
|
|
299
|
+
// ExplorationTracker (analyst 策略) 提供:
|
|
300
|
+
// - 四阶段管理: SCAN → EXPLORE → VERIFY → SUMMARIZE
|
|
301
|
+
// - Nudge: budget_warning / convergence / reflection / force_exit
|
|
302
|
+
// - 阶段 toolChoice: SUMMARIZE='none' 强制 LLM 输出文本
|
|
303
|
+
// - Graceful exit: 终结阶段 2 轮 grace + 硬上限兜底
|
|
304
|
+
// ContextWindow 提供:
|
|
305
|
+
// - 自动三级递进上下文压缩
|
|
306
|
+
// source:'system' 提供:
|
|
307
|
+
// - 空响应自动重试 (2 次)
|
|
308
|
+
// - finalize 强制摘要兜底
|
|
309
|
+
const systemCtx = this.buildSystemContext({
|
|
310
|
+
budget: { maxIterations: analyzeMaxIter },
|
|
311
|
+
trackerStrategy: 'analyst',
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
// ── 执行 ──
|
|
315
|
+
const message = AgentMessage.internal(
|
|
316
|
+
`分析 "${label}" 的 ${files?.length || 0} 个源文件。${comprehensive ? '请进行深度分析。' : ''}`,
|
|
317
|
+
);
|
|
318
|
+
const result = await runtime.execute(message, { strategyContext: systemCtx });
|
|
319
|
+
|
|
320
|
+
// ── 提取结果 ──
|
|
321
|
+
if (task === 'extract') {
|
|
322
|
+
// 工具驱动模式: 从 tool calls 中提取 collected recipes (与冷启动相同的提取方式)
|
|
323
|
+
const allToolCalls = result.toolCalls || [];
|
|
324
|
+
const recipes = allToolCalls
|
|
325
|
+
.filter(tc => (tc.tool || tc.name) === 'collect_scan_recipe')
|
|
326
|
+
.map(tc => {
|
|
327
|
+
// 优先从 handler 返回的 recipe 对象取,回退到参数
|
|
328
|
+
const res = tc.result;
|
|
329
|
+
if (res && typeof res === 'object' && res.status === 'collected' && res.recipe) {
|
|
330
|
+
return res.recipe;
|
|
331
|
+
}
|
|
332
|
+
return null;
|
|
333
|
+
})
|
|
334
|
+
.filter(Boolean);
|
|
335
|
+
|
|
336
|
+
if (recipes.length > 0) {
|
|
337
|
+
return { targetName: label, extracted: recipes.length, recipes };
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Fallback: 工具未被调用时,尝试从文本解析
|
|
341
|
+
const produceReply = result.phases?.produce?.reply || result.reply;
|
|
342
|
+
return this.#parseJsonResponse(produceReply, fallback(label));
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// summarize / relations: 纯文本 JSON 输出
|
|
346
|
+
const produceReply = result.phases?.produce?.reply || result.reply;
|
|
347
|
+
return this.#parseJsonResponse(produceReply, fallback(label));
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* AI 翻译 — chat 模式,单轮生成
|
|
352
|
+
*
|
|
353
|
+
* Agent(LLM) 直接翻译文本,无需工具。
|
|
354
|
+
*
|
|
355
|
+
* @param {string} summary — 中文摘要
|
|
356
|
+
* @param {string} [usageGuide] — 中文使用指南
|
|
357
|
+
* @returns {Promise<{ summaryEn?: string, usageGuideEn?: string, error?: string }>}
|
|
358
|
+
*/
|
|
359
|
+
async translateToEnglish(summary, usageGuide) {
|
|
360
|
+
if (!summary && !usageGuide) {
|
|
361
|
+
return { summaryEn: '', usageGuideEn: '' };
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const runtime = this.createChat({
|
|
365
|
+
policies: [
|
|
366
|
+
new BudgetPolicy({ maxIterations: 1, maxTokens: 4096, temperature: 0.2, timeoutMs: 60_000 }),
|
|
367
|
+
],
|
|
368
|
+
persona: {
|
|
369
|
+
description: [
|
|
370
|
+
'你是技术文档翻译专家。将中文技术内容翻译为地道的英文。保持技术术语不变。',
|
|
371
|
+
'',
|
|
372
|
+
'## 输出格式(必须是纯 JSON,不包含任何其他文字)',
|
|
373
|
+
'{ "summaryEn": "...", "usageGuideEn": "..." }',
|
|
374
|
+
].join('\n'),
|
|
375
|
+
},
|
|
376
|
+
memory: { enabled: false },
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
const message = AgentMessage.internal(
|
|
380
|
+
`翻译以下内容为英文,输出纯 JSON:\nsummary: ${summary || '(空)'}\nusageGuide: ${usageGuide || '(空)'}`,
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
const result = await runtime.execute(message);
|
|
384
|
+
return this.#parseJsonResponse(result.reply, {
|
|
385
|
+
summaryEn: summary || '',
|
|
386
|
+
usageGuideEn: usageGuide || '',
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* 冷启动知识库 — 直接调用 handler(纯启发式,不需要 LLM)
|
|
392
|
+
*
|
|
393
|
+
* bootstrap_knowledge 是纯启发式工具:SPM Target 扫描 → 依赖图谱 → Guard 审计 →
|
|
394
|
+
* Candidate 创建,全程无 AI 推理。直接调用 handler 即可,无需创建 Agent。
|
|
395
|
+
*
|
|
396
|
+
* @param {{ maxFiles?: number, skipGuard?: boolean, contentMaxLines?: number, loadSkills?: boolean, skipAsyncFill?: boolean }} [opts]
|
|
397
|
+
* @returns {Promise<Object>}
|
|
398
|
+
*/
|
|
399
|
+
async bootstrapKnowledge(opts = {}) {
|
|
400
|
+
const { bootstrapKnowledge } = await import('../../external/mcp/handlers/bootstrap-internal.js');
|
|
401
|
+
const result = await bootstrapKnowledge(
|
|
402
|
+
{ container: this.#container, logger: this.#logger },
|
|
403
|
+
{
|
|
404
|
+
maxFiles: opts.maxFiles || 500,
|
|
405
|
+
skipGuard: opts.skipGuard || false,
|
|
406
|
+
contentMaxLines: opts.contentMaxLines || 120,
|
|
407
|
+
loadSkills: opts.loadSkills ?? true,
|
|
408
|
+
skipAsyncFill: opts.skipAsyncFill || false,
|
|
409
|
+
},
|
|
410
|
+
);
|
|
411
|
+
const parsed = typeof result === 'string' ? JSON.parse(result) : result;
|
|
412
|
+
return parsed?.data || parsed;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* 通用工具执行 — 直接调用工具 handler
|
|
417
|
+
*
|
|
418
|
+
* 纯数据工具直接执行,无需创建 Agent。
|
|
419
|
+
* AI 推理由各语义方法的 Agent 自主完成,此方法仅用于纯数据工具。
|
|
420
|
+
*
|
|
421
|
+
* @param {string} toolName — 工具名称
|
|
422
|
+
* @param {Object} params — 工具参数
|
|
423
|
+
* @returns {Promise<*>} 工具原始返回值
|
|
424
|
+
*/
|
|
425
|
+
async invokeAgent(toolName, params) {
|
|
426
|
+
return this.#toolRegistry.execute(toolName, params, this.#makeToolContext());
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// ─── 私有方法 ────────────────────────────────
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* 解析 Agent 响应中的 JSON(支持 markdown 代码块包装)
|
|
433
|
+
* @param {string} text — Agent 响应文本
|
|
434
|
+
* @param {Object} fallback — 解析失败时的默认值
|
|
435
|
+
* @returns {Object}
|
|
436
|
+
*/
|
|
437
|
+
#parseJsonResponse(text, fallback) {
|
|
438
|
+
if (!text) return fallback;
|
|
439
|
+
try {
|
|
440
|
+
// 尝试从 markdown 代码块中提取 JSON
|
|
441
|
+
const codeBlockMatch = text.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
442
|
+
if (codeBlockMatch) {
|
|
443
|
+
return JSON.parse(codeBlockMatch[1].trim());
|
|
444
|
+
}
|
|
445
|
+
// 尝试直接提取 JSON 对象
|
|
446
|
+
const objMatch = text.match(/(\{[\s\S]*\})/);
|
|
447
|
+
if (objMatch) {
|
|
448
|
+
return JSON.parse(objMatch[1].trim());
|
|
449
|
+
}
|
|
450
|
+
return JSON.parse(text.trim());
|
|
451
|
+
} catch {
|
|
452
|
+
this.#logger.warn('[AgentFactory] Failed to parse JSON from Agent response');
|
|
453
|
+
return fallback;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* 构建工具 handler 执行所需的上下文对象
|
|
459
|
+
* @returns {Object}
|
|
460
|
+
*/
|
|
461
|
+
#makeToolContext() {
|
|
462
|
+
return {
|
|
463
|
+
aiProvider: this.#aiProvider,
|
|
464
|
+
container: this.#container,
|
|
465
|
+
logger: this.#logger,
|
|
466
|
+
projectRoot: this.#sharedOpts.projectRoot,
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* 获取 Capability 实例化时需要的依赖注入参数
|
|
472
|
+
*/
|
|
473
|
+
#getCapabilityOpts(capabilityName) {
|
|
474
|
+
switch (capabilityName) {
|
|
475
|
+
case 'conversation':
|
|
476
|
+
return {
|
|
477
|
+
memoryCoordinator: this.#sharedOpts.memoryCoordinator,
|
|
478
|
+
projectBriefing: this.#sharedOpts.projectBriefing,
|
|
479
|
+
};
|
|
480
|
+
case 'system_interaction':
|
|
481
|
+
return {
|
|
482
|
+
projectRoot: this.#sharedOpts.projectRoot,
|
|
483
|
+
};
|
|
484
|
+
default:
|
|
485
|
+
return {};
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
export default AgentFactory;
|