@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 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
- To use your own API protocol, extend the `BaseChatModel` from `@langchain/core`:
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 { BaseChatModel } = require("@langchain/core/language_models/chat_models");
88
+ const { AgentChainModel } = require("@saber2pr/ai-agent");
89
+
90
+ class MyPrivateLLM extends AgentChainModel {
91
+ constructor(fields) {
92
+ super(fields || {});
93
+ }
87
94
 
88
- class MyPrivateLLM extends BaseChatModel {
89
- async _generate(messages) {
95
+ async generateAgentChainResponse(messages) {
90
96
  const lastMessage = messages[messages.length - 1];
91
- const response = await fetch("https://your-api.com/v1/chat", {
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: lastMessage.content }),
94
- headers: { 'Authorization': `Bearer ${token}` }
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
- return {
98
- generations: [{ text: data.text, message: { content: data.text, role: "assistant" } }]
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
- | Tool | Description |
111
- | ----------------- | ------------------------------------------------------------------------ |
112
- | `generate_review` | Finalizes the process by submitting a structured violation report. |
113
- | `get_repo_map` | Generates a high-level map of the project files and exports. |
114
- | `read_text_file` | Reads file content with line numbers for precise auditing. |
115
- | `read_skeleton` | Extracts class/function signatures without full logic (Token efficient). |
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
 
@@ -11,6 +11,7 @@ export default class McpChainAgent {
11
11
  private memory?;
12
12
  private systemPrompt;
13
13
  private runningTokenCounter;
14
+ private verbose;
14
15
  constructor(options?: AgentOptions);
15
16
  private initTools;
16
17
  private wrapHandler;
@@ -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
- 工具名称列表: [{tool_names}]
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
- Thought: {agent_scratchpad}`);
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: false,
158
- handleParsingErrors: true,
159
- maxIterations: this.maxIterations
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 thought = action.log.split(/```json|\{/)[0].replace(/Thought:/i, "").trim();
178
- if (thought && !thought.startsWith('{')) {
179
- console.log(`\n💭 [思考]: ${thought.split('\n')[0]}`);
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
@@ -2,3 +2,4 @@ export * from './core/agent';
2
2
  export { default as McpChainAgent } from './core/agent-chain';
3
3
  export { default } from './core/agent';
4
4
  export { createTool } from './utils/createTool';
5
+ export { AgentChainModel } from './model/AgentChainModel';
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: ReadTextFileArgsSchema.toJSONSchema(),
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: ReadMultipleFilesArgsSchema.toJSONSchema(),
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: WriteFileArgsSchema.toJSONSchema(),
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: EditFileArgsSchema.toJSONSchema(),
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: CreateDirectoryArgsSchema.toJSONSchema(),
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: ListDirectoryArgsSchema.toJSONSchema(),
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: ListDirectoryWithSizesArgsSchema.toJSONSchema(),
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: DirectoryTreeArgsSchema.toJSONSchema(),
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: MoveFileArgsSchema.toJSONSchema(),
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: SearchFilesArgsSchema.toJSONSchema(),
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: GetFileInfoArgsSchema.toJSONSchema(),
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);
@@ -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
- apiModel?: BaseChatModel;
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.15",
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",