@saber2pr/ai-agent 0.0.50 → 0.0.52
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.d.ts +1 -20
- package/lib/core/agent-graph.js +25 -55
- package/lib/types/type.d.ts +1 -2
- package/package.json +1 -1
|
@@ -6,9 +6,6 @@ interface TokenUsage {
|
|
|
6
6
|
}
|
|
7
7
|
declare const AgentState: import("@langchain/langgraph").AnnotationRoot<{
|
|
8
8
|
messages: import("@langchain/langgraph").BinaryOperatorAggregate<BaseMessage[], BaseMessage[]>;
|
|
9
|
-
auditedFiles: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
10
|
-
targetCount: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
11
|
-
mode: import("@langchain/langgraph").BinaryOperatorAggregate<"chat" | "auto", "chat" | "auto">;
|
|
12
9
|
tokenUsage: import("@langchain/langgraph").BinaryOperatorAggregate<TokenUsage, TokenUsage>;
|
|
13
10
|
totalDuration: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
14
11
|
}>;
|
|
@@ -24,7 +21,6 @@ export default class McpGraphAgent<T extends AgentGraphModel = any> {
|
|
|
24
21
|
private alwaysSystem;
|
|
25
22
|
private recursionLimit;
|
|
26
23
|
private apiConfig;
|
|
27
|
-
private maxTargetCount;
|
|
28
24
|
private maxTokens;
|
|
29
25
|
private mcpClients;
|
|
30
26
|
private streamEnabled;
|
|
@@ -66,36 +62,21 @@ export default class McpGraphAgent<T extends AgentGraphModel = any> {
|
|
|
66
62
|
totalDuration: number;
|
|
67
63
|
}>;
|
|
68
64
|
private getRecentToolCalls;
|
|
69
|
-
trackProgress(state: typeof AgentState.State): Promise<{
|
|
70
|
-
auditedFiles: string[];
|
|
71
|
-
}>;
|
|
72
65
|
private printFinalSummary;
|
|
73
66
|
createGraph(): Promise<import("@langchain/langgraph").CompiledStateGraph<import("@langchain/langgraph").StateType<{
|
|
74
67
|
messages: import("@langchain/langgraph").BinaryOperatorAggregate<BaseMessage[], BaseMessage[]>;
|
|
75
|
-
auditedFiles: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
76
|
-
targetCount: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
77
|
-
mode: import("@langchain/langgraph").BinaryOperatorAggregate<"chat" | "auto", "chat" | "auto">;
|
|
78
68
|
tokenUsage: import("@langchain/langgraph").BinaryOperatorAggregate<TokenUsage, TokenUsage>;
|
|
79
69
|
totalDuration: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
80
70
|
}>, import("@langchain/langgraph").UpdateType<{
|
|
81
71
|
messages: import("@langchain/langgraph").BinaryOperatorAggregate<BaseMessage[], BaseMessage[]>;
|
|
82
|
-
auditedFiles: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
83
|
-
targetCount: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
84
|
-
mode: import("@langchain/langgraph").BinaryOperatorAggregate<"chat" | "auto", "chat" | "auto">;
|
|
85
72
|
tokenUsage: import("@langchain/langgraph").BinaryOperatorAggregate<TokenUsage, TokenUsage>;
|
|
86
73
|
totalDuration: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
87
|
-
}>, "tools" | "__start__" | "agent"
|
|
74
|
+
}>, "tools" | "__start__" | "agent", {
|
|
88
75
|
messages: import("@langchain/langgraph").BinaryOperatorAggregate<BaseMessage[], BaseMessage[]>;
|
|
89
|
-
auditedFiles: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
90
|
-
targetCount: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
91
|
-
mode: import("@langchain/langgraph").BinaryOperatorAggregate<"chat" | "auto", "chat" | "auto">;
|
|
92
76
|
tokenUsage: import("@langchain/langgraph").BinaryOperatorAggregate<TokenUsage, TokenUsage>;
|
|
93
77
|
totalDuration: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
94
78
|
}, {
|
|
95
79
|
messages: import("@langchain/langgraph").BinaryOperatorAggregate<BaseMessage[], BaseMessage[]>;
|
|
96
|
-
auditedFiles: import("@langchain/langgraph").BinaryOperatorAggregate<string[], string[]>;
|
|
97
|
-
targetCount: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
98
|
-
mode: import("@langchain/langgraph").BinaryOperatorAggregate<"chat" | "auto", "chat" | "auto">;
|
|
99
80
|
tokenUsage: import("@langchain/langgraph").BinaryOperatorAggregate<TokenUsage, TokenUsage>;
|
|
100
81
|
totalDuration: import("@langchain/langgraph").BinaryOperatorAggregate<number, number>;
|
|
101
82
|
}, import("@langchain/langgraph").StateDefinition>>;
|
package/lib/core/agent-graph.js
CHANGED
|
@@ -29,18 +29,6 @@ const AgentState = langgraph_1.Annotation.Root({
|
|
|
29
29
|
reducer: (x, y) => x.concat(y),
|
|
30
30
|
default: () => [],
|
|
31
31
|
}),
|
|
32
|
-
auditedFiles: (0, langgraph_1.Annotation)({
|
|
33
|
-
reducer: (x, y) => Array.from(new Set([...x, ...y])),
|
|
34
|
-
default: () => [],
|
|
35
|
-
}),
|
|
36
|
-
targetCount: (0, langgraph_1.Annotation)({
|
|
37
|
-
reducer: (x, y) => y !== null && y !== void 0 ? y : x,
|
|
38
|
-
default: () => 4,
|
|
39
|
-
}),
|
|
40
|
-
mode: (0, langgraph_1.Annotation)({
|
|
41
|
-
reducer: (x, y) => y !== null && y !== void 0 ? y : x,
|
|
42
|
-
default: () => 'chat',
|
|
43
|
-
}),
|
|
44
32
|
// ✅ Token 累加器
|
|
45
33
|
tokenUsage: (0, langgraph_1.Annotation)({
|
|
46
34
|
reducer: (x, y) => ({
|
|
@@ -67,8 +55,7 @@ class McpGraphAgent {
|
|
|
67
55
|
this.targetDir = options.targetDir || process.cwd();
|
|
68
56
|
this.recursionLimit = options.recursionLimit || 80;
|
|
69
57
|
this.apiConfig = options.apiConfig;
|
|
70
|
-
this.
|
|
71
|
-
this.maxTokens = options.maxTokens || 8000;
|
|
58
|
+
this.maxTokens = options.maxTokens || 100000;
|
|
72
59
|
this.streamEnabled = options.stream || false;
|
|
73
60
|
process.setMaxListeners(100);
|
|
74
61
|
// ✅ 修复 AbortSignal 监听器数量警告
|
|
@@ -283,8 +270,6 @@ class McpGraphAgent {
|
|
|
283
270
|
const app = await this.createGraph();
|
|
284
271
|
const graphStream = await app.stream({
|
|
285
272
|
messages: [new messages_1.HumanMessage(query)],
|
|
286
|
-
mode: 'auto',
|
|
287
|
-
targetCount: this.maxTargetCount,
|
|
288
273
|
}, {
|
|
289
274
|
configurable: { thread_id: 'auto_worker' },
|
|
290
275
|
recursionLimit: this.recursionLimit,
|
|
@@ -312,8 +297,6 @@ class McpGraphAgent {
|
|
|
312
297
|
const app = await this.createGraph();
|
|
313
298
|
const graphStream = await app.stream({
|
|
314
299
|
messages: [new messages_1.HumanMessage(query)],
|
|
315
|
-
mode: 'auto',
|
|
316
|
-
targetCount: this.maxTargetCount,
|
|
317
300
|
}, {
|
|
318
301
|
configurable: { thread_id: 'stream_worker' },
|
|
319
302
|
recursionLimit: this.recursionLimit,
|
|
@@ -346,7 +329,7 @@ class McpGraphAgent {
|
|
|
346
329
|
rl.close();
|
|
347
330
|
return;
|
|
348
331
|
}
|
|
349
|
-
const graphStream = await app.stream({ messages: [new messages_1.HumanMessage(input)]
|
|
332
|
+
const graphStream = await app.stream({ messages: [new messages_1.HumanMessage(input)] }, {
|
|
350
333
|
configurable: { thread_id: 'session' },
|
|
351
334
|
recursionLimit: this.recursionLimit,
|
|
352
335
|
debug: this.verbose,
|
|
@@ -416,7 +399,6 @@ class McpGraphAgent {
|
|
|
416
399
|
}
|
|
417
400
|
}
|
|
418
401
|
async callModel(state) {
|
|
419
|
-
const auditedListStr = state.auditedFiles.length > 0 ? state.auditedFiles.map(f => `\n - ${f}`).join('') : '暂无';
|
|
420
402
|
const recentToolCalls = this.getRecentToolCalls(state.messages);
|
|
421
403
|
const recentToolCallsStr = recentToolCalls.length > 0
|
|
422
404
|
? `\n\n⚠️ 最近调用的工具(避免重复调用相同工具和参数):\n${recentToolCalls
|
|
@@ -425,9 +407,14 @@ class McpGraphAgent {
|
|
|
425
407
|
: '';
|
|
426
408
|
// 1. 构建当前的系统提示词模板
|
|
427
409
|
const systemPromptTemplate = `你是一个代码专家。工作目录:${this.targetDir}。
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
410
|
+
|
|
411
|
+
# 🧠 思考要求 (Mandatory Thinking Process)
|
|
412
|
+
在进行任何输出或调用工具之前,你**必须**先进行深度的逻辑思考。请将你的思考过程包裹在 <think> 标签内。
|
|
413
|
+
你的思考应包含:
|
|
414
|
+
1. **当前状态分析**:目前任务进展到哪一步了?
|
|
415
|
+
2. **逻辑推导**:基于已知信息,下一步应该做什么?为什么?
|
|
416
|
+
3. **工具选择建议**:如果需要调用工具,预期通过该工具获得什么结果?
|
|
417
|
+
4. **风险/边界评估**:有哪些潜在的代码缺陷或执行风险需要注意?
|
|
431
418
|
|
|
432
419
|
# 🛠️ 工具调用规范
|
|
433
420
|
1. Arguments 必须是纯粹的 JSON 对象,严禁将其作为字符串放入引号中。
|
|
@@ -458,10 +445,6 @@ class McpGraphAgent {
|
|
|
458
445
|
try {
|
|
459
446
|
const promptParams = {
|
|
460
447
|
messages: inputMessages,
|
|
461
|
-
mode: state.mode,
|
|
462
|
-
targetCount: state.targetCount,
|
|
463
|
-
doneCount: state.auditedFiles.length,
|
|
464
|
-
auditedList: auditedListStr,
|
|
465
448
|
recentToolCalls: recentToolCallsStr,
|
|
466
449
|
extraPrompt: this.options.extraSystemPrompt || '',
|
|
467
450
|
};
|
|
@@ -611,21 +594,6 @@ class McpGraphAgent {
|
|
|
611
594
|
}
|
|
612
595
|
return toolCalls;
|
|
613
596
|
}
|
|
614
|
-
async trackProgress(state) {
|
|
615
|
-
var _a;
|
|
616
|
-
const lastAiMsg = state.messages[state.messages.length - 1];
|
|
617
|
-
const currentAudited = new Set(state.auditedFiles);
|
|
618
|
-
if ((_a = lastAiMsg === null || lastAiMsg === void 0 ? void 0 : lastAiMsg.tool_calls) === null || _a === void 0 ? void 0 : _a.length) {
|
|
619
|
-
for (const tc of lastAiMsg.tool_calls) {
|
|
620
|
-
// 兼容所有可能的路径参数字段
|
|
621
|
-
const file = tc.args.path || tc.args.filePath || tc.args.file || tc.args.file_path;
|
|
622
|
-
if (file && typeof file === 'string') {
|
|
623
|
-
currentAudited.add(file);
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
return { auditedFiles: Array.from(currentAudited) };
|
|
628
|
-
}
|
|
629
597
|
printFinalSummary(state) {
|
|
630
598
|
var _a;
|
|
631
599
|
const totalTokens = ((_a = state.tokenUsage) === null || _a === void 0 ? void 0 : _a.total) || 0;
|
|
@@ -635,7 +603,6 @@ class McpGraphAgent {
|
|
|
635
603
|
console.log(`🏁 \x1b[32;1m[审计任务全量结算]\x1b[0m`);
|
|
636
604
|
console.log(` - 累计消耗总额: \x1b[33m${totalTokens}\x1b[0m Tokens`);
|
|
637
605
|
console.log(` - 累计执行耗时: \x1b[36m${(totalMs / 1000).toFixed(2)}\x1b[0m s`);
|
|
638
|
-
console.log(` - 审计文件总数: ${state.auditedFiles.length} 个`);
|
|
639
606
|
console.log('═'.repeat(50) + '\n');
|
|
640
607
|
}
|
|
641
608
|
}
|
|
@@ -643,7 +610,6 @@ class McpGraphAgent {
|
|
|
643
610
|
const workflow = new langgraph_1.StateGraph(AgentState)
|
|
644
611
|
.addNode('agent', state => this.callModel(state))
|
|
645
612
|
.addNode('tools', this.toolNode)
|
|
646
|
-
.addNode('progress', state => this.trackProgress(state))
|
|
647
613
|
.addEdge(langgraph_1.START, 'agent')
|
|
648
614
|
.addConditionalEdges('agent', state => {
|
|
649
615
|
const { messages } = state;
|
|
@@ -653,6 +619,9 @@ class McpGraphAgent {
|
|
|
653
619
|
// 如果已消耗 Token 超过了 options 中设置的 maxTokens (假设是总限额)
|
|
654
620
|
if (this.options.maxTokens && state.tokenUsage.total >= this.options.maxTokens) {
|
|
655
621
|
console.warn('⚠️ [警告] 已达到最大 Token 限制,强制结束任务。');
|
|
622
|
+
state.messages.push(new messages_1.AIMessage({
|
|
623
|
+
content: `⚠️ 抱歉,当前任务消耗的 Token 已达上限 ${this.options.maxTokens}。为了防止无限循环,我已停止执行。你可以尝试分步骤指令,继续发送指令,直到任务完成。`
|
|
624
|
+
}));
|
|
656
625
|
this.printFinalSummary(state);
|
|
657
626
|
return langgraph_1.END;
|
|
658
627
|
}
|
|
@@ -660,22 +629,23 @@ class McpGraphAgent {
|
|
|
660
629
|
if (lastMsg.tool_calls && lastMsg.tool_calls.length > 0) {
|
|
661
630
|
return 'tools';
|
|
662
631
|
}
|
|
663
|
-
// 2. 判定结束的条件:
|
|
664
|
-
// - 模式是 auto 且审计完成
|
|
665
|
-
// - 或者 AI 明确输出了结束语
|
|
666
|
-
// - 或者 AI 输出了普通内容且没有工具调用(针对问答模式)
|
|
667
|
-
const isAutoFinished = state.mode === 'auto' && state.auditedFiles.length > state.targetCount;
|
|
668
632
|
const isFinalAnswer = content.includes('Final Answer');
|
|
669
|
-
|
|
670
|
-
if (isAutoFinished || isFinalAnswer || state.mode === 'chat') {
|
|
633
|
+
if (isFinalAnswer) {
|
|
671
634
|
this.printFinalSummary(state);
|
|
672
635
|
return langgraph_1.END;
|
|
673
636
|
}
|
|
674
|
-
|
|
637
|
+
if (messages.length > 50) {
|
|
638
|
+
state.messages.push(new messages_1.AIMessage({
|
|
639
|
+
content: `💡 **嘿,我们已经聊了很多了!**
|
|
640
|
+
|
|
641
|
+
为了保证服务质量,我通常会在 50 步操作后停下来和您确认一下。这样可以避免我产生“幻觉”或者做一些无用功。
|
|
642
|
+
|
|
643
|
+
**任务还没完成吗?** 没关系,只要您回复“继续”,我马上就回来接着干!或者您有什么新的想法要告诉我?`
|
|
644
|
+
}));
|
|
645
|
+
return langgraph_1.END;
|
|
646
|
+
}
|
|
675
647
|
return langgraph_1.END;
|
|
676
|
-
})
|
|
677
|
-
.addEdge('tools', 'progress')
|
|
678
|
-
.addEdge('progress', 'agent');
|
|
648
|
+
}).addEdge('tools', 'agent');
|
|
679
649
|
return workflow.compile({ checkpointer: this.checkpointer });
|
|
680
650
|
}
|
|
681
651
|
}
|
package/lib/types/type.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export interface ApiConfig {
|
|
|
7
7
|
model: string;
|
|
8
8
|
}
|
|
9
9
|
export interface ToolInfo {
|
|
10
|
-
type:
|
|
10
|
+
type: 'function';
|
|
11
11
|
function: {
|
|
12
12
|
name: string;
|
|
13
13
|
description?: string;
|
|
@@ -38,7 +38,6 @@ export interface GraphAgentOptions<T extends AgentGraphModel = any> extends Agen
|
|
|
38
38
|
apiModel?: T;
|
|
39
39
|
alwaysSystem?: boolean;
|
|
40
40
|
recursionLimit?: number;
|
|
41
|
-
maxTargetCount?: number;
|
|
42
41
|
/** 是否启用流式输出,默认 false */
|
|
43
42
|
stream?: boolean;
|
|
44
43
|
}
|