@saber2pr/ai-agent 0.0.58 → 0.0.59
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/adapters/llm.js +3 -1
- package/lib/core/agent-graph.js +1 -1
- package/lib/core/agent.js +1 -1
- package/lib/model/AgentGraphModel.d.ts +4 -1
- package/lib/model/AgentGraphModel.js +13 -1
- package/lib/tools/builtin.js +2 -0
- package/lib/tools/loader/get_all_tools_schema.d.ts +1 -0
- package/lib/tools/loader/get_all_tools_schema.js +33 -0
- package/lib/types/type.d.ts +3 -1
- package/lib/utils/convertToLangChainTool.d.ts +3 -1
- package/lib/utils/convertToLangChainTool.js +2 -2
- package/lib/utils/createTool.d.ts +3 -1
- package/lib/utils/createTool.js +2 -2
- package/lib/utils/getRepoMapPrompt.d.ts +1 -0
- package/lib/utils/getRepoMapPrompt.js +40 -0
- package/package.json +1 -1
package/lib/adapters/llm.js
CHANGED
|
@@ -5,7 +5,9 @@ const AgentGraphModel_1 = require("../model/AgentGraphModel");
|
|
|
5
5
|
class LLMModel extends AgentGraphModel_1.AgentGraphModel {
|
|
6
6
|
options;
|
|
7
7
|
constructor(options) {
|
|
8
|
-
super(
|
|
8
|
+
super({
|
|
9
|
+
targetDir: options.targetDir,
|
|
10
|
+
});
|
|
9
11
|
this.options = options;
|
|
10
12
|
}
|
|
11
13
|
async callApi(prompt) {
|
package/lib/core/agent-graph.js
CHANGED
|
@@ -175,7 +175,7 @@ class McpGraphAgent {
|
|
|
175
175
|
const mcpToolInfos = await this.initMcpTools();
|
|
176
176
|
// 合并内置、手动传入和 MCP 工具
|
|
177
177
|
const allToolInfos = [...builtinToolInfos, ...(this.options.tools || []), ...mcpToolInfos];
|
|
178
|
-
this.langchainTools = allToolInfos.map(t => (0, convertToLangChainTool_1.convertToLangChainTool)(t));
|
|
178
|
+
this.langchainTools = allToolInfos.map(t => (0, convertToLangChainTool_1.convertToLangChainTool)(t, { allTools: allToolInfos }));
|
|
179
179
|
this.toolNode = new prebuilt_1.ToolNode(this.langchainTools);
|
|
180
180
|
return {
|
|
181
181
|
builtinToolInfos,
|
package/lib/core/agent.js
CHANGED
|
@@ -306,7 +306,7 @@ class McpAgent {
|
|
|
306
306
|
console.log(` 📦 传入参数: \x1b[2m${JSON.stringify(args)}\x1b[0m`);
|
|
307
307
|
let result;
|
|
308
308
|
if (tool?._handler) {
|
|
309
|
-
result = await tool._handler(args);
|
|
309
|
+
result = await tool._handler(args, { allTools: this.allTools });
|
|
310
310
|
}
|
|
311
311
|
else if (tool?._client && tool._originalName) {
|
|
312
312
|
const mcpRes = await tool._client.callTool({
|
|
@@ -14,13 +14,16 @@ export declare abstract class AgentGraphModel extends BaseChatModel {
|
|
|
14
14
|
private mcpEnabled?;
|
|
15
15
|
private mcpTools?;
|
|
16
16
|
protected chatId: string;
|
|
17
|
+
protected targetDir?: string;
|
|
17
18
|
resetChat(): void;
|
|
18
19
|
setMcpTools(tools: any[]): void;
|
|
19
20
|
setMcpEnabled(enabled?: boolean): void;
|
|
20
21
|
getMcpEnabled(): boolean;
|
|
21
22
|
getMcpTools(): any[];
|
|
22
23
|
private isMcpTool;
|
|
23
|
-
constructor(fields?: BaseChatModelParams
|
|
24
|
+
constructor(fields?: BaseChatModelParams & {
|
|
25
|
+
targetDir?: string;
|
|
26
|
+
});
|
|
24
27
|
bindTools(tools: any[]): any;
|
|
25
28
|
abstract callApi(prompt: string, lastMsg: BaseMessage): Promise<AgentGraphLLMResponse>;
|
|
26
29
|
/**
|
|
@@ -6,11 +6,13 @@ const messages_1 = require("@langchain/core/messages");
|
|
|
6
6
|
const function_calling_1 = require("@langchain/core/utils/function_calling");
|
|
7
7
|
const generateToolMarkdown_1 = require("../utils/generateToolMarkdown");
|
|
8
8
|
const kit_1 = require("../utils/kit");
|
|
9
|
+
const getRepoMapPrompt_1 = require("../utils/getRepoMapPrompt");
|
|
9
10
|
class AgentGraphModel extends chat_models_1.BaseChatModel {
|
|
10
11
|
boundTools;
|
|
11
12
|
mcpEnabled = true;
|
|
12
13
|
mcpTools = [];
|
|
13
14
|
chatId = '';
|
|
15
|
+
targetDir;
|
|
14
16
|
resetChat() {
|
|
15
17
|
this.chatId = '';
|
|
16
18
|
}
|
|
@@ -35,6 +37,7 @@ class AgentGraphModel extends chat_models_1.BaseChatModel {
|
|
|
35
37
|
this.chatId = '';
|
|
36
38
|
this.mcpTools = [];
|
|
37
39
|
this.mcpEnabled = true;
|
|
40
|
+
this.targetDir = fields?.targetDir;
|
|
38
41
|
}
|
|
39
42
|
bindTools(tools) {
|
|
40
43
|
this.boundTools = tools.map(t => (0, function_calling_1.convertToOpenAITool)(t));
|
|
@@ -189,7 +192,16 @@ class AgentGraphModel extends chat_models_1.BaseChatModel {
|
|
|
189
192
|
const systemContext = isFirstMessage ? `
|
|
190
193
|
${isFirstMessage ? format(systemMsg) : ''}
|
|
191
194
|
${toolsContext}
|
|
192
|
-
|
|
195
|
+
${(0, getRepoMapPrompt_1.getIncrementalRepoMapPrompt)(this.targetDir, isFirstMessage)}
|
|
196
|
+
`.trim() : `
|
|
197
|
+
## Active Tools (Summary)
|
|
198
|
+
Available: ${(0, kit_1.getArray)(tools).map(t => t.function.name).join(', ')}
|
|
199
|
+
|
|
200
|
+
**Self-Correction**: If you encounter "tool not found" or need parameter details, you MUST call:
|
|
201
|
+
- \`get_all_tools_schema\`: Retrieve full tool definitions and schemas.
|
|
202
|
+
|
|
203
|
+
${(0, getRepoMapPrompt_1.getIncrementalRepoMapPrompt)(this.targetDir, isFirstMessage)}
|
|
204
|
+
`.trim();
|
|
193
205
|
return `
|
|
194
206
|
${systemContext}
|
|
195
207
|
# Current Progress
|
package/lib/tools/builtin.js
CHANGED
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createDefaultBuiltinTools = createDefaultBuiltinTools;
|
|
4
4
|
const filesystem_1 = require("./filesystem");
|
|
5
|
+
const get_all_tools_schema_1 = require("./loader/get_all_tools_schema");
|
|
5
6
|
const ts_lsp_1 = require("./ts-lsp");
|
|
6
7
|
function createDefaultBuiltinTools(context) {
|
|
7
8
|
const { options } = context;
|
|
8
9
|
return [
|
|
9
10
|
...(0, ts_lsp_1.getTsLspTools)(options?.targetDir || process.cwd()),
|
|
10
11
|
...(0, filesystem_1.getFilesystemTools)(options?.targetDir || process.cwd()),
|
|
12
|
+
get_all_tools_schema_1.getAllToolsSchema,
|
|
11
13
|
];
|
|
12
14
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const getAllToolsSchema: import("../..").ToolInfo;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getAllToolsSchema = void 0;
|
|
7
|
+
const zod_1 = require("zod");
|
|
8
|
+
const zod_to_json_schema_1 = __importDefault(require("zod-to-json-schema"));
|
|
9
|
+
const createTool_1 = require("../../utils/createTool");
|
|
10
|
+
const generateToolMarkdown_1 = require("../../utils/generateToolMarkdown");
|
|
11
|
+
const kit_1 = require("../../utils/kit");
|
|
12
|
+
exports.getAllToolsSchema = (0, createTool_1.createTool)({
|
|
13
|
+
name: 'get_all_tools_schema',
|
|
14
|
+
description: 'Use this tool when you encounter a "tool not found" error or are unsure about the parameter schema. It retrieves the full definitions and JSON schemas for all available tools in the current environment.',
|
|
15
|
+
parameters: zod_1.z.object({
|
|
16
|
+
toolName: zod_1.z.string().optional().describe('Optional: Specify a tool name to get its detailed schema. If omitted, returns all available tools.')
|
|
17
|
+
}),
|
|
18
|
+
// 增加第二个参数 context
|
|
19
|
+
handler: async ({ toolName }, context) => {
|
|
20
|
+
// 这里的 context.allTools 是在运行时从 Agent 实例传入的
|
|
21
|
+
const availableTools = (0, kit_1.getArray)(context?.allTools);
|
|
22
|
+
const targetTools = toolName
|
|
23
|
+
? availableTools.filter(t => t.function.name === toolName)
|
|
24
|
+
: availableTools;
|
|
25
|
+
return (0, generateToolMarkdown_1.generateToolMarkdown)(targetTools.map(item => ({
|
|
26
|
+
...item,
|
|
27
|
+
function: {
|
|
28
|
+
...item.function,
|
|
29
|
+
parameters: (0, zod_to_json_schema_1.default)(item.function.parameters)
|
|
30
|
+
}
|
|
31
|
+
})));
|
|
32
|
+
}
|
|
33
|
+
});
|
package/lib/types/type.d.ts
CHANGED
|
@@ -13,7 +13,9 @@ export interface ToolInfo {
|
|
|
13
13
|
description?: string;
|
|
14
14
|
parameters: z.ZodObject<any>;
|
|
15
15
|
};
|
|
16
|
-
_handler?: (args: any
|
|
16
|
+
_handler?: (args: any, context: {
|
|
17
|
+
allTools: ToolInfo[];
|
|
18
|
+
}) => Promise<any>;
|
|
17
19
|
_client?: Client;
|
|
18
20
|
_originalName?: string;
|
|
19
21
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { DynamicStructuredTool } from '@langchain/core/tools';
|
|
2
2
|
import { ToolInfo } from '../types/type';
|
|
3
|
-
export declare function convertToLangChainTool(info: ToolInfo
|
|
3
|
+
export declare function convertToLangChainTool(info: ToolInfo, context: {
|
|
4
|
+
allTools: ToolInfo[];
|
|
5
|
+
}): DynamicStructuredTool<import("zod").ZodObject<any, import("zod").UnknownKeysParam, import("zod").ZodTypeAny, {
|
|
4
6
|
[x: string]: any;
|
|
5
7
|
}, {
|
|
6
8
|
[x: string]: any;
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.convertToLangChainTool = convertToLangChainTool;
|
|
4
4
|
const tools_1 = require("@langchain/core/tools");
|
|
5
|
-
function convertToLangChainTool(info) {
|
|
5
|
+
function convertToLangChainTool(info, context) {
|
|
6
6
|
return new tools_1.DynamicStructuredTool({
|
|
7
7
|
name: info.function.name,
|
|
8
8
|
description: info.function.description || '',
|
|
9
9
|
schema: info.function.parameters,
|
|
10
10
|
func: async (args) => {
|
|
11
11
|
if (info._handler)
|
|
12
|
-
return await info._handler(args);
|
|
12
|
+
return await info._handler(args, context);
|
|
13
13
|
if (info._client && info._originalName) {
|
|
14
14
|
const result = await info._client.callTool({
|
|
15
15
|
name: info._originalName,
|
|
@@ -7,6 +7,8 @@ export interface CreateToolOptions {
|
|
|
7
7
|
* zod@3.25
|
|
8
8
|
*/
|
|
9
9
|
parameters: z.ZodObject<any>;
|
|
10
|
-
handler: (args: any
|
|
10
|
+
handler: (args: any, context: {
|
|
11
|
+
allTools: ToolInfo[];
|
|
12
|
+
}) => Promise<string>;
|
|
11
13
|
}
|
|
12
14
|
export declare function createTool(options: CreateToolOptions): ToolInfo;
|
package/lib/utils/createTool.js
CHANGED
|
@@ -9,7 +9,7 @@ function createTool(options) {
|
|
|
9
9
|
description: options.description,
|
|
10
10
|
parameters: options.parameters,
|
|
11
11
|
},
|
|
12
|
-
_handler: async (input) => {
|
|
12
|
+
_handler: async (input, context) => {
|
|
13
13
|
// 兼容处理:如果 input 是字符串,尝试解析为 JSON 对象
|
|
14
14
|
let args = input;
|
|
15
15
|
if (typeof input === 'string') {
|
|
@@ -20,7 +20,7 @@ function createTool(options) {
|
|
|
20
20
|
args = input;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
-
return options.handler(args);
|
|
23
|
+
return options.handler(args, context);
|
|
24
24
|
},
|
|
25
25
|
};
|
|
26
26
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const getIncrementalRepoMapPrompt: (targetDir: string, isFirstTurn: boolean) => string;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getIncrementalRepoMapPrompt = void 0;
|
|
4
|
+
const ts_context_mcp_1 = require("@saber2pr/ts-context-mcp");
|
|
5
|
+
let lastRepoMapContent = '';
|
|
6
|
+
const getIncrementalRepoMapPrompt = (targetDir, isFirstTurn) => {
|
|
7
|
+
try {
|
|
8
|
+
const engine = new ts_context_mcp_1.PromptEngine(targetDir);
|
|
9
|
+
const currentContent = engine.getRepoMap();
|
|
10
|
+
// 1. 第一轮对话:必须全量发送
|
|
11
|
+
if (isFirstTurn || !lastRepoMapContent) {
|
|
12
|
+
lastRepoMapContent = currentContent;
|
|
13
|
+
return `\n# Initial Project Repository Map\n\`\`\`text\n${currentContent}\n\`\`\``;
|
|
14
|
+
}
|
|
15
|
+
// 2. 如果完全没变:发送静默占位符
|
|
16
|
+
if (currentContent === lastRepoMapContent) {
|
|
17
|
+
return "\n\n(Note: Project structure remains unchanged.)";
|
|
18
|
+
}
|
|
19
|
+
// 3. 如果变了:计算增量 (Incremental Diff)
|
|
20
|
+
const lastLines = lastRepoMapContent.split('\n');
|
|
21
|
+
const currentLines = currentContent.split('\n');
|
|
22
|
+
// 找出发生变化的行 (简单示例:找出在 current 中但不在 last 中的行)
|
|
23
|
+
const changes = currentLines.filter(line => !lastLines.includes(line));
|
|
24
|
+
lastRepoMapContent = currentContent;
|
|
25
|
+
if (changes.length > 0) {
|
|
26
|
+
return `
|
|
27
|
+
# 🆕 Project Map Updates (Incremental)
|
|
28
|
+
The project structure has changed. Key updates:
|
|
29
|
+
\`\`\`text
|
|
30
|
+
${changes.join('\n')}
|
|
31
|
+
\`\`\`
|
|
32
|
+
*(Refer to previous messages for the rest of the map)*`;
|
|
33
|
+
}
|
|
34
|
+
return "\n\n(Note: Minor internal structure changes detected.)";
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
return '';
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
exports.getIncrementalRepoMapPrompt = getIncrementalRepoMapPrompt;
|