@saber2pr/ai-agent 0.0.32 → 0.0.34
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/lib/core/agent-graph.js +18 -11
- package/lib/core/agent.d.ts +2 -0
- package/lib/core/agent.js +31 -11
- package/package.json +5 -6
package/lib/core/agent-graph.js
CHANGED
|
@@ -255,16 +255,24 @@ class McpGraphAgent {
|
|
|
255
255
|
return config;
|
|
256
256
|
}
|
|
257
257
|
async chat(query = "开始代码审计") {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
258
|
+
try {
|
|
259
|
+
await this.ensureInitialized();
|
|
260
|
+
await this.getModel();
|
|
261
|
+
const app = await this.createGraph();
|
|
262
|
+
const stream = await app.stream({
|
|
263
|
+
messages: [new messages_1.HumanMessage(query)],
|
|
264
|
+
mode: "auto",
|
|
265
|
+
targetCount: this.maxTargetCount,
|
|
266
|
+
}, { configurable: { thread_id: "auto_worker" }, recursionLimit: this.recursionLimit, debug: this.verbose, });
|
|
267
|
+
for await (const output of stream)
|
|
268
|
+
this.renderOutput(output);
|
|
269
|
+
}
|
|
270
|
+
catch (error) {
|
|
271
|
+
console.error("\n❌ Chat 过程中发生错误:", error);
|
|
272
|
+
}
|
|
273
|
+
finally {
|
|
274
|
+
await this.closeMcpClients();
|
|
275
|
+
}
|
|
268
276
|
}
|
|
269
277
|
async start() {
|
|
270
278
|
await this.ensureInitialized();
|
|
@@ -373,7 +381,6 @@ class McpGraphAgent {
|
|
|
373
381
|
# 🎯 核心指令
|
|
374
382
|
1. **任务终结判定**:当你已经读取了用户要求的文件、回答了问题或完成了审计目标时,必须立即提供最终回复。
|
|
375
383
|
2. **回复格式**:任务完成时,请以 "Final Answer:" 开头进行总结,此时不再调用任何工具。
|
|
376
|
-
3. **避免重复**:不要重复调用相同的工具和参数。如果工具返回错误,请分析原因(如参数 Schema 错误)而不是盲目重试。{recentToolCalls}
|
|
377
384
|
|
|
378
385
|
# 📝 审计任务专项
|
|
379
386
|
1. 避免在同一个文件上陷入无限循环尝试。
|
package/lib/core/agent.d.ts
CHANGED
|
@@ -9,7 +9,9 @@ export default class McpAgent {
|
|
|
9
9
|
private maxTokens;
|
|
10
10
|
private apiConfig;
|
|
11
11
|
private targetDir;
|
|
12
|
+
private mcpClients;
|
|
12
13
|
constructor(options?: AgentOptions);
|
|
14
|
+
private closeMcpClients;
|
|
13
15
|
/**
|
|
14
16
|
* 计算当前消息列表的总 Token 消耗
|
|
15
17
|
* 兼容多模态内容 (Content Parts) 和 工具调用 (Tool Calls)
|
package/lib/core/agent.js
CHANGED
|
@@ -55,6 +55,7 @@ class McpAgent {
|
|
|
55
55
|
this.messages = [];
|
|
56
56
|
this.encoder = (0, js_tiktoken_1.getEncoding)("cl100k_base");
|
|
57
57
|
this.extraTools = [];
|
|
58
|
+
this.mcpClients = [];
|
|
58
59
|
this.targetDir = (options === null || options === void 0 ? void 0 : options.targetDir) || process.cwd();
|
|
59
60
|
this.extraTools = (options === null || options === void 0 ? void 0 : options.tools) || []; // 接收外部传入的工具
|
|
60
61
|
this.maxTokens = (options === null || options === void 0 ? void 0 : options.maxTokens) || 100000; // 默认 100k
|
|
@@ -63,12 +64,11 @@ class McpAgent {
|
|
|
63
64
|
你的目标是理解并分析用户项目,请务必遵循以下工作流:
|
|
64
65
|
|
|
65
66
|
### 第一阶段:全景感知 (The "Where" Phase)
|
|
66
|
-
1. **必须首先调用 '
|
|
67
|
-
2. 结合目录结构,观察项目架构(如 Monorepo 结构或 src 布局)。
|
|
67
|
+
1. **必须首先调用 'list_directory'** 了解全局,再深入具体文件。
|
|
68
68
|
|
|
69
69
|
### 第二阶段:逻辑映射 (The "What" Phase)
|
|
70
70
|
1. **调用 'get_repo_map'**:针对代码文件提取导出定义,理解模块间的调用关系。
|
|
71
|
-
2. 如果需要查看具体的样式定义,直接使用 'read_text_file'
|
|
71
|
+
2. 如果需要查看具体的样式定义,直接使用 'read_text_file' 读取文件内容。
|
|
72
72
|
|
|
73
73
|
### 核心原则:
|
|
74
74
|
- 不要猜测文件是否存在,先看目录树。
|
|
@@ -87,6 +87,16 @@ class McpAgent {
|
|
|
87
87
|
});
|
|
88
88
|
this.initTools(options); // 注入外部工具
|
|
89
89
|
}
|
|
90
|
+
// ✅ 新增:关闭连接
|
|
91
|
+
async closeMcpClients() {
|
|
92
|
+
for (const client of this.mcpClients) {
|
|
93
|
+
try {
|
|
94
|
+
await client.close();
|
|
95
|
+
}
|
|
96
|
+
catch (e) { }
|
|
97
|
+
}
|
|
98
|
+
this.mcpClients = [];
|
|
99
|
+
}
|
|
90
100
|
/**
|
|
91
101
|
* 计算当前消息列表的总 Token 消耗
|
|
92
102
|
* 兼容多模态内容 (Content Parts) 和 工具调用 (Tool Calls)
|
|
@@ -198,6 +208,7 @@ class McpAgent {
|
|
|
198
208
|
});
|
|
199
209
|
const client = new index_js_1.Client({ name, version: "1.0.0" }, { capabilities: {} });
|
|
200
210
|
await client.connect(transport);
|
|
211
|
+
this.mcpClients.push(client);
|
|
201
212
|
const { tools } = await client.listTools();
|
|
202
213
|
this.allTools.push(...tools.map((t) => ({
|
|
203
214
|
type: "function",
|
|
@@ -348,15 +359,24 @@ class McpAgent {
|
|
|
348
359
|
* @returns AI 的最终答复内容
|
|
349
360
|
*/
|
|
350
361
|
async chat(input) {
|
|
351
|
-
|
|
352
|
-
|
|
362
|
+
try {
|
|
363
|
+
if (!this.openai) {
|
|
364
|
+
await this.init();
|
|
365
|
+
}
|
|
366
|
+
// 调用现有的处理逻辑
|
|
367
|
+
// 假设你的 processChat 已经处理了所有的 tool_calls 循环
|
|
368
|
+
await this.processChat(input);
|
|
369
|
+
// 返回消息列表中的最后一条 AI 回复
|
|
370
|
+
const lastMsg = this.messages[this.messages.length - 1];
|
|
371
|
+
return lastMsg.role === 'assistant' ? lastMsg.content : '';
|
|
372
|
+
}
|
|
373
|
+
catch (error) {
|
|
374
|
+
console.error("\n❌ 系统错误:", error.message);
|
|
375
|
+
return '';
|
|
376
|
+
}
|
|
377
|
+
finally {
|
|
378
|
+
await this.closeMcpClients();
|
|
353
379
|
}
|
|
354
|
-
// 调用现有的处理逻辑
|
|
355
|
-
// 假设你的 processChat 已经处理了所有的 tool_calls 循环
|
|
356
|
-
await this.processChat(input);
|
|
357
|
-
// 返回消息列表中的最后一条 AI 回复
|
|
358
|
-
const lastMsg = this.messages[this.messages.length - 1];
|
|
359
|
-
return lastMsg.role === 'assistant' ? lastMsg.content : '';
|
|
360
380
|
}
|
|
361
381
|
// 修改原来的 start 方法,使其内部也调用 chat
|
|
362
382
|
async start() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saber2pr/ai-agent",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.34",
|
|
4
4
|
"description": "AI Assistant CLI.",
|
|
5
5
|
"author": "saber2pr",
|
|
6
6
|
"license": "ISC",
|
|
@@ -23,15 +23,14 @@
|
|
|
23
23
|
"prepublishOnly": "tsc"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@langchain/core": "0.3.
|
|
27
|
-
"@langchain/langgraph": "^0.2.
|
|
28
|
-
"@langchain/openai": "0.4.
|
|
26
|
+
"@langchain/core": "0.3.40",
|
|
27
|
+
"@langchain/langgraph": "^0.2.74",
|
|
28
|
+
"@langchain/openai": "0.4.9",
|
|
29
29
|
"@modelcontextprotocol/sdk": "^1.25.3",
|
|
30
30
|
"@saber2pr/ts-context-mcp": "^0.0.8",
|
|
31
31
|
"diff": "^8.0.3",
|
|
32
32
|
"glob": "^10.5.0",
|
|
33
33
|
"js-tiktoken": "^1.0.21",
|
|
34
|
-
"langchain": "0.3.15",
|
|
35
34
|
"minimatch": "^10.0.1",
|
|
36
35
|
"openai": "^6.16.0",
|
|
37
36
|
"zod": "3.25",
|
|
@@ -40,7 +39,7 @@
|
|
|
40
39
|
},
|
|
41
40
|
"resolutions": {
|
|
42
41
|
"zod": "3.25",
|
|
43
|
-
"@langchain/core": "0.3.
|
|
42
|
+
"@langchain/core": "0.3.40"
|
|
44
43
|
},
|
|
45
44
|
"devDependencies": {
|
|
46
45
|
"@types/node": "^16.3.3",
|