@saber2pr/ai-agent 0.0.15 → 0.0.16
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/README.md +72 -18
- package/lib/core/agent-chain.d.ts +1 -0
- package/lib/core/agent-chain.js +33 -20
- package/lib/index.d.ts +1 -0
- package/lib/index.js +3 -1
- package/lib/model/AgentChainModel.d.ts +18 -0
- package/lib/model/AgentChainModel.js +23 -0
- package/lib/tools/filesystem/index.js +12 -11
- package/lib/types/type.d.ts +14 -3
- package/package.json +10 -5
package/README.md
CHANGED
|
@@ -80,39 +80,93 @@ await agent.chat("Scan for hardcoded colors and submit a review report.");
|
|
|
80
80
|
|
|
81
81
|
## 🔧 Extending with Private LLMs
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
### Using AgentChainModel (Recommended)
|
|
84
|
+
|
|
85
|
+
For LangChain mode, extend `AgentChainModel` which provides a simplified interface for integrating custom LLMs:
|
|
84
86
|
|
|
85
87
|
```javascript
|
|
86
|
-
const {
|
|
88
|
+
const { AgentChainModel } = require("@saber2pr/ai-agent");
|
|
89
|
+
|
|
90
|
+
class MyPrivateLLM extends AgentChainModel {
|
|
91
|
+
constructor(fields) {
|
|
92
|
+
super(fields || {});
|
|
93
|
+
}
|
|
87
94
|
|
|
88
|
-
|
|
89
|
-
async _generate(messages) {
|
|
95
|
+
async generateAgentChainResponse(messages) {
|
|
90
96
|
const lastMessage = messages[messages.length - 1];
|
|
91
|
-
const
|
|
97
|
+
const queryText = lastMessage.content;
|
|
98
|
+
|
|
99
|
+
const response = await fetch("https://your-api-gateway.com/api/completions", {
|
|
92
100
|
method: 'POST',
|
|
93
|
-
body: JSON.stringify({ query:
|
|
94
|
-
headers: {
|
|
101
|
+
body: JSON.stringify({ query: queryText, stream: false }),
|
|
102
|
+
headers: {
|
|
103
|
+
'Content-Type': 'application/json',
|
|
104
|
+
Authorization: `Bearer YOUR_API_KEY`,
|
|
105
|
+
}
|
|
95
106
|
});
|
|
107
|
+
|
|
108
|
+
if (!response.ok) {
|
|
109
|
+
const errorText = await response.text();
|
|
110
|
+
throw new Error(`HTTP Error: ${response.status}, ${errorText}`);
|
|
111
|
+
}
|
|
112
|
+
|
|
96
113
|
const data = await response.json();
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
114
|
+
let text = data.text || "";
|
|
115
|
+
|
|
116
|
+
// Handle special response formats if needed
|
|
117
|
+
if (text.includes("Action:") && text.includes("Final Answer:")) {
|
|
118
|
+
text = text.split("Final Answer:")[0].trim();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return text;
|
|
100
122
|
}
|
|
101
|
-
_llmType() { return "private_llm"; }
|
|
102
123
|
}
|
|
103
|
-
|
|
104
124
|
```
|
|
105
125
|
|
|
126
|
+
**Key Points:**
|
|
127
|
+
- `AgentChainModel` abstracts away LangChain's internal message handling
|
|
128
|
+
- You only need to implement `generateAgentChainResponse(messages)` which receives an array of messages
|
|
129
|
+
- The method should return a plain string response
|
|
130
|
+
- The base class handles conversion to LangChain's expected format
|
|
131
|
+
|
|
106
132
|
---
|
|
107
133
|
|
|
108
134
|
## 📦 Built-in Toolset
|
|
109
135
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
|
115
|
-
|
|
136
|
+
The toolkit provides a comprehensive set of built-in tools organized into two categories: **Filesystem Tools** and **Code Analysis Tools**. All tools operate within the `targetDir` scope for security.
|
|
137
|
+
|
|
138
|
+
### Filesystem Tools
|
|
139
|
+
|
|
140
|
+
| Tool | Description | Parameters |
|
|
141
|
+
|------|-------------|------------|
|
|
142
|
+
| `read_text_file` | Read complete file contents as text. Supports `head` and `tail` parameters for partial reading. Handles various text encodings. | `path` (required), `head?`, `tail?` |
|
|
143
|
+
| `read_multiple_files` | Read multiple files simultaneously for efficient batch analysis. Individual failures won't stop the operation. | `paths` (array, required) |
|
|
144
|
+
| `write_file` | Create a new file or completely overwrite an existing file. Use with caution as it overwrites without warning. | `path` (required), `content` (required) |
|
|
145
|
+
| `edit_file` | Make line-based edits to a text file. Replaces exact line sequences with new content. Returns git-style diff. Supports `dryRun` mode for preview. | `path` (required), `edits` (array, required), `dryRun?` |
|
|
146
|
+
| `get_directory_tree` | Get a recursive tree view of files and directories as JSON. Supports `excludePatterns` for filtering (minimatch patterns). Essential for understanding project structure. | `path` (required), `excludePatterns?` (array) |
|
|
147
|
+
| `list_directory` | List all files and directories in a specified path. Results distinguish files and directories with `[FILE]` and `[DIR]` prefixes. | `path` (required) |
|
|
148
|
+
| `list_directory_with_sizes` | List directory contents with file sizes. Supports sorting by name or size. Includes summary statistics. | `path` (required), `sortBy?` ("name" \| "size") |
|
|
149
|
+
| `search_files` | Search for files matching a glob pattern. Supports exclude patterns for filtering. | `path` (required), `pattern` (required), `excludePatterns?` (array) |
|
|
150
|
+
| `move_file` | Move or rename files and directories. Can move between directories and rename in a single operation. | `source` (required), `destination` (required) |
|
|
151
|
+
| `create_directory` | Create a new directory or ensure it exists. Can create multiple nested directories recursively. | `path` (required) |
|
|
152
|
+
| `get_file_info` | Get detailed metadata about a file: size, last modified time, type, etc. | `path` (required) |
|
|
153
|
+
|
|
154
|
+
### Code Analysis Tools
|
|
155
|
+
|
|
156
|
+
| Tool | Description | Parameters |
|
|
157
|
+
|------|-------------|------------|
|
|
158
|
+
| `get_repo_map` | Generate a high-level map of project files and exports. Extracts export definitions to understand module relationships. Use this first to understand project structure. | None |
|
|
159
|
+
| `read_skeleton` | Extract structural definitions (interfaces, classes, method signatures) without implementation details. Token-efficient for code analysis. | `filePath` (required) |
|
|
160
|
+
| `analyze_deps` | Analyze dependency relationships for a specific file. Supports TypeScript path alias resolution via tsconfig. | `filePath` (required) |
|
|
161
|
+
| `get_method_body` | Get the complete implementation code for a specific method or function within a file. | `filePath` (required), `methodName` (required) |
|
|
162
|
+
|
|
163
|
+
### Tool Usage Tips
|
|
164
|
+
|
|
165
|
+
1. **Start with `get_directory_tree`**: Always begin by understanding the project structure before reading files.
|
|
166
|
+
2. **Use `read_skeleton` before `read_text_file`**: Extract signatures first to save tokens, then read full content only when needed.
|
|
167
|
+
3. **Leverage `excludePatterns`**: Use minimatch patterns to exclude `node_modules`, `.git`, build artifacts, etc.
|
|
168
|
+
4. **Batch operations**: Use `read_multiple_files` when analyzing multiple files to improve efficiency.
|
|
169
|
+
5. **Preview changes**: Use `edit_file` with `dryRun: true` to preview changes before applying them.
|
|
116
170
|
|
|
117
171
|
---
|
|
118
172
|
|
package/lib/core/agent-chain.js
CHANGED
|
@@ -39,14 +39,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
39
39
|
const fs_1 = __importDefault(require("fs"));
|
|
40
40
|
const js_tiktoken_1 = require("js-tiktoken");
|
|
41
41
|
const agents_1 = require("langchain/agents");
|
|
42
|
+
const memory_1 = require("langchain/memory");
|
|
43
|
+
const readline = __importStar(require("readline"));
|
|
42
44
|
const prompts_1 = require("@langchain/core/prompts");
|
|
43
45
|
const tools_1 = require("@langchain/core/tools");
|
|
44
46
|
const openai_1 = require("@langchain/openai");
|
|
45
|
-
const memory_1 = require("langchain/memory");
|
|
46
|
-
const readline = __importStar(require("readline"));
|
|
47
47
|
const config_1 = require("../config/config");
|
|
48
|
-
const jsonSchemaToZod_1 = require("../utils/jsonSchemaToZod");
|
|
49
48
|
const builtin_1 = require("../tools/builtin");
|
|
49
|
+
const jsonSchemaToZod_1 = require("../utils/jsonSchemaToZod");
|
|
50
50
|
class McpChainAgent {
|
|
51
51
|
constructor(options) {
|
|
52
52
|
this.allTools = [];
|
|
@@ -58,6 +58,7 @@ class McpChainAgent {
|
|
|
58
58
|
this.apiConfig = options === null || options === void 0 ? void 0 : options.apiConfig;
|
|
59
59
|
this.maxIterations = (options === null || options === void 0 ? void 0 : options.maxIterations) || 20;
|
|
60
60
|
this.apiModel = options === null || options === void 0 ? void 0 : options.apiModel;
|
|
61
|
+
this.verbose = (options === null || options === void 0 ? void 0 : options.verbose) || false;
|
|
61
62
|
const baseSystemPrompt = `你是一个专业的代码架构师。
|
|
62
63
|
你的目标是理解并分析用户项目,请务必遵循以下工作流:
|
|
63
64
|
|
|
@@ -119,6 +120,7 @@ class McpChainAgent {
|
|
|
119
120
|
// 必须添加下面这两行显式声明:
|
|
120
121
|
inputKey: "input", // 对应 invoke 里的 input 字段
|
|
121
122
|
outputKey: "output", // 对应 Agent 输出的字段
|
|
123
|
+
chatHistory: new memory_1.ChatMessageHistory(), // 👈 显式指定 history 实例
|
|
122
124
|
});
|
|
123
125
|
const langchainTools = this.allTools.map(t => new tools_1.DynamicStructuredTool({
|
|
124
126
|
name: t.function.name,
|
|
@@ -126,37 +128,44 @@ class McpChainAgent {
|
|
|
126
128
|
schema: (0, jsonSchemaToZod_1.jsonSchemaToZod)(t.function.parameters),
|
|
127
129
|
func: async (args) => await t._handler(args),
|
|
128
130
|
}));
|
|
129
|
-
// 2. 构造支持 Memory 的 Prompt
|
|
130
131
|
const prompt = prompts_1.PromptTemplate.fromTemplate(`{system_prompt}
|
|
131
132
|
|
|
132
|
-
###
|
|
133
|
-
{chat_history}
|
|
134
|
-
|
|
135
|
-
### 可用工具:
|
|
133
|
+
### 🛠 可用工具:
|
|
136
134
|
{tools}
|
|
137
135
|
|
|
138
|
-
|
|
136
|
+
### 🛠 工具名称:
|
|
137
|
+
[{tool_names}]
|
|
138
|
+
|
|
139
|
+
### 📝 历史记录:
|
|
140
|
+
{chat_history}
|
|
141
|
+
|
|
142
|
+
### ⚠️ 回复规范(严格遵守):
|
|
143
|
+
1. 首先输出 **Thought:**,用中文详细说明你的分析思路。
|
|
144
|
+
2. 接着输出一个 **JSON Action 代码块**。
|
|
139
145
|
|
|
140
|
-
|
|
141
|
-
Thought:
|
|
146
|
+
示例格式:
|
|
147
|
+
Thought: 正在查看目录。
|
|
142
148
|
\`\`\`json
|
|
143
149
|
{{
|
|
144
|
-
"action": "
|
|
145
|
-
"action_input": {{
|
|
150
|
+
"action": "directory_tree",
|
|
151
|
+
"action_input": {{}}
|
|
146
152
|
}}
|
|
147
153
|
\`\`\`
|
|
148
154
|
|
|
149
155
|
Begin!
|
|
150
156
|
Question: {input}
|
|
151
|
-
|
|
157
|
+
{agent_scratchpad}`); // 👈 强制以 Thought: 开头,解决断更问题
|
|
152
158
|
const agent = await (0, agents_1.createStructuredChatAgent)({ llm: model, tools: langchainTools, prompt });
|
|
153
159
|
this.executor = new agents_1.AgentExecutor({
|
|
154
160
|
agent,
|
|
155
161
|
tools: langchainTools,
|
|
156
162
|
memory: this.memory, // 挂载内存模块
|
|
157
|
-
verbose:
|
|
158
|
-
|
|
159
|
-
|
|
163
|
+
verbose: this.verbose,
|
|
164
|
+
maxIterations: this.maxIterations,
|
|
165
|
+
handleParsingErrors: (e) => {
|
|
166
|
+
// 简化报错,不要再给 AI 错误的 JSON 示例
|
|
167
|
+
return `格式不正确。请确保你输出了一个正确的 Markdown JSON 代码块,例如:\n\`\`\`json\n{ "action": "...", "action_input": { ... } }\n\`\`\``;
|
|
168
|
+
},
|
|
160
169
|
});
|
|
161
170
|
}
|
|
162
171
|
async chat(input) {
|
|
@@ -174,9 +183,13 @@ Thought: {agent_scratchpad}`);
|
|
|
174
183
|
}, {
|
|
175
184
|
callbacks: [{
|
|
176
185
|
handleAgentAction: (action) => {
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
186
|
+
const rawLog = action.log || "";
|
|
187
|
+
// 兼容 Thought: Thought: [内容]
|
|
188
|
+
let thought = rawLog.split(/```json|\{/)[0]
|
|
189
|
+
.replace(/Thought:/gi, "") // 全局替换掉所有 Thought: 标签
|
|
190
|
+
.trim();
|
|
191
|
+
if (thought) {
|
|
192
|
+
console.log(`\n💭 [思考]: ${thought}`);
|
|
180
193
|
}
|
|
181
194
|
}
|
|
182
195
|
}]
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -17,7 +17,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
17
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
18
|
};
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.createTool = exports.default = exports.McpChainAgent = void 0;
|
|
20
|
+
exports.AgentChainModel = exports.createTool = exports.default = exports.McpChainAgent = void 0;
|
|
21
21
|
__exportStar(require("./core/agent"), exports);
|
|
22
22
|
var agent_chain_1 = require("./core/agent-chain");
|
|
23
23
|
Object.defineProperty(exports, "McpChainAgent", { enumerable: true, get: function () { return __importDefault(agent_chain_1).default; } });
|
|
@@ -25,3 +25,5 @@ var agent_1 = require("./core/agent");
|
|
|
25
25
|
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(agent_1).default; } });
|
|
26
26
|
var createTool_1 = require("./utils/createTool");
|
|
27
27
|
Object.defineProperty(exports, "createTool", { enumerable: true, get: function () { return createTool_1.createTool; } });
|
|
28
|
+
var AgentChainModel_1 = require("./model/AgentChainModel");
|
|
29
|
+
Object.defineProperty(exports, "AgentChainModel", { enumerable: true, get: function () { return AgentChainModel_1.AgentChainModel; } });
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { BaseChatModel } from "@langchain/core/language_models/chat_models";
|
|
2
|
+
import { AIMessage, MessageFieldWithRole } from "@langchain/core/messages";
|
|
3
|
+
interface AgentChainModelImpl {
|
|
4
|
+
generateAgentChainResponse: (messages: MessageFieldWithRole[]) => Promise<string>;
|
|
5
|
+
}
|
|
6
|
+
export declare abstract class AgentChainModel extends BaseChatModel implements AgentChainModelImpl {
|
|
7
|
+
bind(args: any): any;
|
|
8
|
+
constructor(fields?: any);
|
|
9
|
+
generateAgentChainResponse(messages: MessageFieldWithRole[]): Promise<string>;
|
|
10
|
+
_generate(messages: any): Promise<{
|
|
11
|
+
generations: {
|
|
12
|
+
text: string;
|
|
13
|
+
message: AIMessage;
|
|
14
|
+
}[];
|
|
15
|
+
}>;
|
|
16
|
+
_llmType(): string;
|
|
17
|
+
}
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AgentChainModel = void 0;
|
|
4
|
+
const chat_models_1 = require("@langchain/core/language_models/chat_models");
|
|
5
|
+
const messages_1 = require("@langchain/core/messages");
|
|
6
|
+
class AgentChainModel extends chat_models_1.BaseChatModel {
|
|
7
|
+
bind(args) {
|
|
8
|
+
// 逻辑上调用基类(即使基类在类型上说没有,运行时通常是有的)
|
|
9
|
+
// 如果运行时也没有,这里就返回 this 本身
|
|
10
|
+
// @ts-ignore
|
|
11
|
+
return (super.bind ? super.bind(args) : this);
|
|
12
|
+
}
|
|
13
|
+
constructor(fields) { super(fields || {}); }
|
|
14
|
+
async generateAgentChainResponse(messages) {
|
|
15
|
+
return '';
|
|
16
|
+
}
|
|
17
|
+
async _generate(messages) {
|
|
18
|
+
let text = await this.generateAgentChainResponse(messages);
|
|
19
|
+
return { generations: [{ text, message: new messages_1.AIMessage(text) }] };
|
|
20
|
+
}
|
|
21
|
+
_llmType() { return "my_private_llm"; }
|
|
22
|
+
}
|
|
23
|
+
exports.AgentChainModel = AgentChainModel;
|
|
@@ -7,6 +7,7 @@ exports.getFilesystemTools = void 0;
|
|
|
7
7
|
const zod_1 = require("zod");
|
|
8
8
|
const promises_1 = __importDefault(require("fs/promises"));
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const zod_to_json_schema_1 = require("zod-to-json-schema");
|
|
10
11
|
const createTool_1 = require("../../utils/createTool");
|
|
11
12
|
const minimatch_1 = require("minimatch");
|
|
12
13
|
const lib_1 = require("./lib");
|
|
@@ -89,7 +90,7 @@ const getFilesystemTools = (targetDir) => {
|
|
|
89
90
|
"the contents of a single file. Use the 'head' parameter to read only " +
|
|
90
91
|
"the first N lines of a file, or the 'tail' parameter to read only " +
|
|
91
92
|
"the last N lines of a file. Operates on the file as text regardless of extension.",
|
|
92
|
-
parameters:
|
|
93
|
+
parameters: (0, zod_to_json_schema_1.zodToJsonSchema)(ReadTextFileArgsSchema, 'ReadTextFileArgsSchema'),
|
|
93
94
|
validateParams: ["path"],
|
|
94
95
|
handler: readTextFileHandler
|
|
95
96
|
});
|
|
@@ -100,7 +101,7 @@ const getFilesystemTools = (targetDir) => {
|
|
|
100
101
|
"or compare multiple files. Each file's content is returned with its " +
|
|
101
102
|
"path as a reference. Failed reads for individual files won't stop " +
|
|
102
103
|
"the entire operation. Only works within allowed directories.",
|
|
103
|
-
parameters:
|
|
104
|
+
parameters: (0, zod_to_json_schema_1.zodToJsonSchema)(ReadMultipleFilesArgsSchema, 'ReadMultipleFilesArgsSchema'),
|
|
104
105
|
validateParams: ["paths"],
|
|
105
106
|
handler: async (args) => {
|
|
106
107
|
const results = await Promise.all(args.paths.map(async (filePath) => {
|
|
@@ -123,7 +124,7 @@ const getFilesystemTools = (targetDir) => {
|
|
|
123
124
|
description: "Create a new file or completely overwrite an existing file with new content. " +
|
|
124
125
|
"Use with caution as it will overwrite existing files without warning. " +
|
|
125
126
|
"Handles text content with proper encoding. Only works within allowed directories.",
|
|
126
|
-
parameters:
|
|
127
|
+
parameters: (0, zod_to_json_schema_1.zodToJsonSchema)(WriteFileArgsSchema, 'WriteFileArgsSchema'),
|
|
127
128
|
validateParams: ["path", "content"],
|
|
128
129
|
handler: async (args) => {
|
|
129
130
|
const validPath = await (0, lib_1.validatePath)(targetDir, args.path);
|
|
@@ -137,7 +138,7 @@ const getFilesystemTools = (targetDir) => {
|
|
|
137
138
|
description: "Make line-based edits to a text file. Each edit replaces exact line sequences " +
|
|
138
139
|
"with new content. Returns a git-style diff showing the changes made. " +
|
|
139
140
|
"Only works within allowed directories.",
|
|
140
|
-
parameters:
|
|
141
|
+
parameters: (0, zod_to_json_schema_1.zodToJsonSchema)(EditFileArgsSchema, 'EditFileArgsSchema'),
|
|
141
142
|
validateParams: ["path", "edits"],
|
|
142
143
|
handler: async (args) => {
|
|
143
144
|
const validPath = await (0, lib_1.validatePath)(targetDir, args.path);
|
|
@@ -151,7 +152,7 @@ const getFilesystemTools = (targetDir) => {
|
|
|
151
152
|
"nested directories in one operation. If the directory already exists, " +
|
|
152
153
|
"this operation will succeed silently. Perfect for setting up directory " +
|
|
153
154
|
"structures for projects or ensuring required paths exist. Only works within allowed directories.",
|
|
154
|
-
parameters:
|
|
155
|
+
parameters: (0, zod_to_json_schema_1.zodToJsonSchema)(CreateDirectoryArgsSchema, 'CreateDirectoryArgsSchema'),
|
|
155
156
|
validateParams: ["path"],
|
|
156
157
|
handler: async (args) => {
|
|
157
158
|
const validPath = await (0, lib_1.validatePath)(targetDir, args.path);
|
|
@@ -166,7 +167,7 @@ const getFilesystemTools = (targetDir) => {
|
|
|
166
167
|
"Results clearly distinguish between files and directories with [FILE] and [DIR] " +
|
|
167
168
|
"prefixes. This tool is essential for understanding directory structure and " +
|
|
168
169
|
"finding specific files within a directory. Only works within allowed directories.",
|
|
169
|
-
parameters:
|
|
170
|
+
parameters: (0, zod_to_json_schema_1.zodToJsonSchema)(ListDirectoryArgsSchema, 'ListDirectoryArgsSchema'),
|
|
170
171
|
validateParams: ["path"],
|
|
171
172
|
handler: async (args) => {
|
|
172
173
|
const validPath = await (0, lib_1.validatePath)(targetDir, args.path);
|
|
@@ -183,7 +184,7 @@ const getFilesystemTools = (targetDir) => {
|
|
|
183
184
|
"Results clearly distinguish between files and directories with [FILE] and [DIR] " +
|
|
184
185
|
"prefixes. This tool is useful for understanding directory structure and " +
|
|
185
186
|
"finding specific files within a directory. Only works within allowed directories.",
|
|
186
|
-
parameters:
|
|
187
|
+
parameters: (0, zod_to_json_schema_1.zodToJsonSchema)(ListDirectoryWithSizesArgsSchema, 'ListDirectoryWithSizesArgsSchema'),
|
|
187
188
|
validateParams: ["path"],
|
|
188
189
|
handler: async (args) => {
|
|
189
190
|
const validPath = await (0, lib_1.validatePath)(targetDir, args.path);
|
|
@@ -238,7 +239,7 @@ const getFilesystemTools = (targetDir) => {
|
|
|
238
239
|
"Each entry includes 'name', 'type' (file/directory), and 'children' for directories. " +
|
|
239
240
|
"Files have no children array, while directories always have a children array (which may be empty). " +
|
|
240
241
|
"The output is formatted with 2-space indentation for readability. Only works within allowed directories.",
|
|
241
|
-
parameters:
|
|
242
|
+
parameters: (0, zod_to_json_schema_1.zodToJsonSchema)(DirectoryTreeArgsSchema, 'DirectoryTreeArgsSchema'),
|
|
242
243
|
validateParams: ["path"],
|
|
243
244
|
handler: async (args) => {
|
|
244
245
|
const rootPath = args.path;
|
|
@@ -283,7 +284,7 @@ const getFilesystemTools = (targetDir) => {
|
|
|
283
284
|
"and rename them in a single operation. If the destination exists, the " +
|
|
284
285
|
"operation will fail. Works across different directories and can be used " +
|
|
285
286
|
"for simple renaming within the same directory. Both source and destination must be within allowed directories.",
|
|
286
|
-
parameters:
|
|
287
|
+
parameters: (0, zod_to_json_schema_1.zodToJsonSchema)(MoveFileArgsSchema, 'MoveFileArgsSchema'),
|
|
287
288
|
validateParams: ["source", "destination"],
|
|
288
289
|
handler: async (args) => {
|
|
289
290
|
const validSourcePath = await (0, lib_1.validatePath)(targetDir, args.source);
|
|
@@ -297,7 +298,7 @@ const getFilesystemTools = (targetDir) => {
|
|
|
297
298
|
name: "search_files",
|
|
298
299
|
description: "Search for files matching a specific pattern in a specified path. " +
|
|
299
300
|
"Returns a list of files that match the pattern. Only works within allowed directories.",
|
|
300
|
-
parameters:
|
|
301
|
+
parameters: (0, zod_to_json_schema_1.zodToJsonSchema)(SearchFilesArgsSchema, 'SearchFilesArgsSchema'),
|
|
301
302
|
validateParams: ["path", "pattern"],
|
|
302
303
|
handler: async (args) => {
|
|
303
304
|
const validPath = await (0, lib_1.validatePath)(targetDir, args.path);
|
|
@@ -310,7 +311,7 @@ const getFilesystemTools = (targetDir) => {
|
|
|
310
311
|
name: "get_file_info",
|
|
311
312
|
description: "Get detailed information about a file, including its size, last modified time, and type. " +
|
|
312
313
|
"Only works within allowed directories.",
|
|
313
|
-
parameters:
|
|
314
|
+
parameters: (0, zod_to_json_schema_1.zodToJsonSchema)(GetFileInfoArgsSchema, 'GetFileInfoArgsSchema'),
|
|
314
315
|
validateParams: ["path"],
|
|
315
316
|
handler: async (args) => {
|
|
316
317
|
const validPath = await (0, lib_1.validatePath)(targetDir, args.path);
|
package/lib/types/type.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { BaseChatModel } from "@langchain/core/language_models/chat_models";
|
|
2
1
|
import { Client } from "@modelcontextprotocol/sdk/client/index";
|
|
3
2
|
export interface ApiConfig {
|
|
4
3
|
baseURL: string;
|
|
@@ -27,12 +26,24 @@ export interface McpConfig {
|
|
|
27
26
|
}
|
|
28
27
|
export interface AgentOptions {
|
|
29
28
|
targetDir?: string;
|
|
30
|
-
/** 外部传入的内置工具列表,不传则使用默认的 registerBuiltinTools */
|
|
31
29
|
tools?: ToolInfo[];
|
|
32
30
|
extraSystemPrompt?: any;
|
|
33
31
|
maxTokens?: number;
|
|
32
|
+
/**
|
|
33
|
+
* only for chain agent
|
|
34
|
+
*/
|
|
34
35
|
apiConfig?: ApiConfig;
|
|
35
|
-
|
|
36
|
+
/**
|
|
37
|
+
* only for chain agent
|
|
38
|
+
* extends BaseChatModel
|
|
39
|
+
*/
|
|
40
|
+
apiModel?: any;
|
|
41
|
+
/**
|
|
42
|
+
* only for chain agent
|
|
43
|
+
*/
|
|
36
44
|
maxIterations?: number;
|
|
45
|
+
/**
|
|
46
|
+
* only for chain agent
|
|
47
|
+
*/
|
|
37
48
|
verbose?: boolean;
|
|
38
49
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saber2pr/ai-agent",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.16",
|
|
4
4
|
"description": "AI Assistant CLI.",
|
|
5
5
|
"author": "saber2pr",
|
|
6
6
|
"license": "ISC",
|
|
@@ -22,16 +22,21 @@
|
|
|
22
22
|
"prepublishOnly": "tsc"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@langchain/core": "^1.1.18",
|
|
26
|
-
"@langchain/openai": "^1.2.4",
|
|
27
25
|
"@modelcontextprotocol/sdk": "^1.25.3",
|
|
28
26
|
"@saber2pr/ts-context-mcp": "^0.0.8",
|
|
29
27
|
"diff": "^8.0.3",
|
|
30
28
|
"glob": "^10.5.0",
|
|
31
29
|
"js-tiktoken": "^1.0.21",
|
|
32
|
-
"langchain": "~0.3",
|
|
33
30
|
"minimatch": "^10.0.1",
|
|
34
|
-
"openai": "^6.16.0"
|
|
31
|
+
"openai": "^6.16.0",
|
|
32
|
+
"zod-to-json-schema": "3.23.2",
|
|
33
|
+
"langchain": "0.3.15",
|
|
34
|
+
"@langchain/core": "0.3.39",
|
|
35
|
+
"@langchain/openai": "0.4.0",
|
|
36
|
+
"zod": "3.23.8"
|
|
37
|
+
},
|
|
38
|
+
"resolutions": {
|
|
39
|
+
"@langchain/core": "0.3.39"
|
|
35
40
|
},
|
|
36
41
|
"devDependencies": {
|
|
37
42
|
"@types/node": "^16.3.3",
|