@saber2pr/ai-agent 0.0.14 → 0.0.15
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-chain.d.ts +3 -9
- package/lib/core/agent-chain.js +73 -159
- package/lib/core/agent.js +14 -17
- package/package.json +6 -6
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { AgentOptions } from '../types/type';
|
|
2
2
|
export default class McpChainAgent {
|
|
3
3
|
private allTools;
|
|
4
|
-
private messages;
|
|
5
4
|
private encoder;
|
|
6
5
|
private extraTools;
|
|
7
6
|
private maxTokens;
|
|
@@ -9,17 +8,12 @@ export default class McpChainAgent {
|
|
|
9
8
|
private apiConfig;
|
|
10
9
|
private maxIterations;
|
|
11
10
|
private apiModel?;
|
|
12
|
-
private
|
|
13
|
-
private
|
|
11
|
+
private memory?;
|
|
12
|
+
private systemPrompt;
|
|
14
13
|
private runningTokenCounter;
|
|
15
14
|
constructor(options?: AgentOptions);
|
|
16
|
-
/**
|
|
17
|
-
* 工具处理器包装逻辑:增加日志打印和 Token 监控
|
|
18
|
-
*/
|
|
19
|
-
private wrapHandler;
|
|
20
15
|
private initTools;
|
|
21
|
-
private
|
|
22
|
-
private pruneMessages;
|
|
16
|
+
private wrapHandler;
|
|
23
17
|
init(): Promise<void>;
|
|
24
18
|
chat(input: string): Promise<string>;
|
|
25
19
|
private showLoading;
|
package/lib/core/agent-chain.js
CHANGED
|
@@ -39,149 +39,106 @@ 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 readline = __importStar(require("readline"));
|
|
43
42
|
const prompts_1 = require("@langchain/core/prompts");
|
|
44
43
|
const tools_1 = require("@langchain/core/tools");
|
|
45
44
|
const openai_1 = require("@langchain/openai");
|
|
45
|
+
const memory_1 = require("langchain/memory");
|
|
46
|
+
const readline = __importStar(require("readline"));
|
|
46
47
|
const config_1 = require("../config/config");
|
|
47
48
|
const jsonSchemaToZod_1 = require("../utils/jsonSchemaToZod");
|
|
48
49
|
const builtin_1 = require("../tools/builtin");
|
|
49
50
|
class McpChainAgent {
|
|
50
51
|
constructor(options) {
|
|
51
52
|
this.allTools = [];
|
|
52
|
-
this.messages = [];
|
|
53
53
|
this.encoder = (0, js_tiktoken_1.getEncoding)("cl100k_base");
|
|
54
54
|
this.extraTools = [];
|
|
55
|
-
this.runningTokenCounter = 0;
|
|
55
|
+
this.runningTokenCounter = 0;
|
|
56
56
|
this.extraTools = (options === null || options === void 0 ? void 0 : options.tools) || [];
|
|
57
57
|
this.maxTokens = (options === null || options === void 0 ? void 0 : options.maxTokens) || 100000;
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
61
|
+
const baseSystemPrompt = `你是一个专业的代码架构师。
|
|
62
|
+
你的目标是理解并分析用户项目,请务必遵循以下工作流:
|
|
63
|
+
|
|
64
|
+
### 第一阶段:全景感知 (The "Where" Phase)
|
|
65
|
+
1. **必须首先调用 'get_directory_tree'**:获取项目完整文件列表,包括样式文件 (.less, .css) 和资源文件。
|
|
66
|
+
2. 结合目录结构,观察项目架构(如 Monorepo 结构或 src 布局)。
|
|
67
|
+
|
|
68
|
+
### 第二阶段:逻辑映射 (The "What" Phase)
|
|
69
|
+
1. **调用 'get_repo_map'**:针对代码文件提取导出定义,理解模块间的调用关系。
|
|
70
|
+
2. 如果需要查看具体的样式定义,直接使用 'read_text_file' 读取 .less 或 .css 文件。
|
|
71
|
+
|
|
72
|
+
### 核心原则:
|
|
73
|
+
- 不要猜测文件是否存在,先看目录树。
|
|
74
|
+
- 优先查看 Skeleton(骨架),只有需要修复逻辑时才读取完整 Text(全文)。
|
|
75
|
+
- 始终以中文回答思考过程。`;
|
|
76
|
+
this.systemPrompt = (options === null || options === void 0 ? void 0 : options.extraSystemPrompt)
|
|
77
|
+
? `${baseSystemPrompt}\n\n[额外指令]:\n${JSON.stringify(options.extraSystemPrompt)}`
|
|
78
|
+
: baseSystemPrompt;
|
|
77
79
|
this.initTools(options);
|
|
78
80
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
initTools(options) {
|
|
82
|
+
const allTools = [...(0, builtin_1.createDefaultBuiltinTools)({ options: { ...options, ...this } }), ...this.extraTools];
|
|
83
|
+
this.allTools = allTools.map((t) => ({
|
|
84
|
+
...t,
|
|
85
|
+
_handler: this.wrapHandler(t.function.name, t._handler),
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
82
88
|
wrapHandler(name, handler) {
|
|
83
89
|
return async (args) => {
|
|
84
|
-
// 1. 打印工具执行日志
|
|
85
90
|
console.log(`\n [工具调用]: ${name}`);
|
|
86
|
-
if (args === null || args === void 0 ? void 0 : args.filePath) {
|
|
87
|
-
console.log(` [目标文件]: ${args.filePath}`);
|
|
88
|
-
}
|
|
89
|
-
// 2. 执行逻辑
|
|
90
91
|
const result = await handler(args);
|
|
91
92
|
const content = typeof result === "string" ? result : JSON.stringify(result);
|
|
92
|
-
|
|
93
|
-
const outputTokens = this.encoder.encode(content).length;
|
|
94
|
-
console.log(` [输出长度]: ${outputTokens} tokens`);
|
|
95
|
-
// 2. 更新动态计数器:
|
|
96
|
-
// 这里的逻辑是:当前基础 Context + 本次工具调用的输出
|
|
97
|
-
// 随着迭代增加,这个值会一直累加,直到任务结束存入 messages
|
|
98
|
-
const baseTokens = this.calculateTokens();
|
|
99
|
-
this.runningTokenCounter = baseTokens + outputTokens;
|
|
100
|
-
// 3. 打印正确且递增的状态
|
|
101
|
-
console.log(` 📊 状态: Context ${this.runningTokenCounter} / Limit ${this.maxTokens} tokens`);
|
|
93
|
+
this.runningTokenCounter += this.encoder.encode(content).length;
|
|
102
94
|
return content;
|
|
103
95
|
};
|
|
104
96
|
}
|
|
105
|
-
initTools(options) {
|
|
106
|
-
const allTools = [
|
|
107
|
-
// 注册内置工具
|
|
108
|
-
...(0, builtin_1.createDefaultBuiltinTools)({
|
|
109
|
-
options: {
|
|
110
|
-
...options,
|
|
111
|
-
...this
|
|
112
|
-
}
|
|
113
|
-
}),
|
|
114
|
-
...this.extraTools
|
|
115
|
-
];
|
|
116
|
-
if (allTools === null || allTools === void 0 ? void 0 : allTools.length) {
|
|
117
|
-
this.allTools.push(...allTools.map((t) => ({
|
|
118
|
-
type: t.type,
|
|
119
|
-
function: t.function,
|
|
120
|
-
_handler: this.wrapHandler(t.function.name, t._handler),
|
|
121
|
-
})));
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
calculateTokens() {
|
|
125
|
-
return this.messages.reduce((acc, msg) => acc + this.encoder.encode(String(msg.content || "")).length, 0);
|
|
126
|
-
}
|
|
127
|
-
pruneMessages() {
|
|
128
|
-
const current = this.calculateTokens();
|
|
129
|
-
if (current > this.maxTokens) {
|
|
130
|
-
console.log(`\n⚠️ 上下文达到限制 (${current} tokens),正在裁剪旧消息...`);
|
|
131
|
-
// 保留 system prompt (index 0),移除后续消息
|
|
132
|
-
while (this.calculateTokens() > this.maxTokens * 0.8 && this.messages.length > 2) {
|
|
133
|
-
this.messages.splice(1, 1);
|
|
134
|
-
}
|
|
135
|
-
console.log(`✅ 裁剪完成,当前: ${this.calculateTokens()} tokens`);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
97
|
async init() {
|
|
139
98
|
if (this.executor)
|
|
140
99
|
return;
|
|
141
100
|
let model;
|
|
142
101
|
if (this.apiModel) {
|
|
143
|
-
console.log("ℹ️ 使用自定义 API Model 实例");
|
|
144
102
|
model = this.apiModel;
|
|
145
103
|
}
|
|
146
104
|
else {
|
|
147
|
-
// 降级方案:使用配置创建默认的 ChatOpenAI
|
|
148
105
|
const apiConfig = await this.ensureApiConfig();
|
|
149
|
-
console.log(`ℹ️ 使用默认 ChatOpenAI (${apiConfig.model})`);
|
|
150
106
|
model = new openai_1.ChatOpenAI({
|
|
151
107
|
configuration: { baseURL: apiConfig.baseURL, apiKey: apiConfig.apiKey },
|
|
152
108
|
modelName: apiConfig.model,
|
|
153
109
|
temperature: 0,
|
|
154
|
-
streaming: false
|
|
155
110
|
});
|
|
156
111
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
},
|
|
168
|
-
});
|
|
112
|
+
// 1. 初始化 SummaryBufferMemory
|
|
113
|
+
// maxTokenLimit 决定了当对话历史超过多少 Token 时触发“自动总结”
|
|
114
|
+
this.memory = new memory_1.ConversationSummaryBufferMemory({
|
|
115
|
+
llm: model,
|
|
116
|
+
maxTokenLimit: 2000,
|
|
117
|
+
memoryKey: "chat_history",
|
|
118
|
+
returnMessages: true,
|
|
119
|
+
// 必须添加下面这两行显式声明:
|
|
120
|
+
inputKey: "input", // 对应 invoke 里的 input 字段
|
|
121
|
+
outputKey: "output", // 对应 Agent 输出的字段
|
|
169
122
|
});
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
123
|
+
const langchainTools = this.allTools.map(t => new tools_1.DynamicStructuredTool({
|
|
124
|
+
name: t.function.name,
|
|
125
|
+
description: t.function.description || "",
|
|
126
|
+
schema: (0, jsonSchemaToZod_1.jsonSchemaToZod)(t.function.parameters),
|
|
127
|
+
func: async (args) => await t._handler(args),
|
|
128
|
+
}));
|
|
129
|
+
// 2. 构造支持 Memory 的 Prompt
|
|
130
|
+
const prompt = prompts_1.PromptTemplate.fromTemplate(`{system_prompt}
|
|
131
|
+
|
|
132
|
+
### 历史记录摘要及近期对话:
|
|
133
|
+
{chat_history}
|
|
173
134
|
|
|
174
|
-
###
|
|
175
|
-
--------------------
|
|
135
|
+
### 可用工具:
|
|
176
136
|
{tools}
|
|
177
137
|
|
|
178
138
|
工具名称列表: [{tool_names}]
|
|
179
139
|
|
|
180
|
-
###
|
|
181
|
-
|
|
182
|
-
你必须严格遵守以下回复格式:
|
|
183
|
-
|
|
184
|
-
Thought: 首先,我会[此处用中文简述你的分析思路和下一步目标]。
|
|
140
|
+
### 交互协议:
|
|
141
|
+
Thought: [你的中文分析思路]
|
|
185
142
|
\`\`\`json
|
|
186
143
|
{{
|
|
187
144
|
"action": "工具名称",
|
|
@@ -189,10 +146,6 @@ Thought: 首先,我会[此处用中文简述你的分析思路和下一步目
|
|
|
189
146
|
}}
|
|
190
147
|
\`\`\`
|
|
191
148
|
|
|
192
|
-
注意:
|
|
193
|
-
- 严禁直接输出 JSON,必须先写 Thought。
|
|
194
|
-
- Thought 必须包含具体的分析意图,不少于 10 个字。
|
|
195
|
-
|
|
196
149
|
Begin!
|
|
197
150
|
Question: {input}
|
|
198
151
|
Thought: {agent_scratchpad}`);
|
|
@@ -200,61 +153,35 @@ Thought: {agent_scratchpad}`);
|
|
|
200
153
|
this.executor = new agents_1.AgentExecutor({
|
|
201
154
|
agent,
|
|
202
155
|
tools: langchainTools,
|
|
203
|
-
|
|
156
|
+
memory: this.memory, // 挂载内存模块
|
|
157
|
+
verbose: false,
|
|
204
158
|
handleParsingErrors: true,
|
|
205
159
|
maxIterations: this.maxIterations
|
|
206
160
|
});
|
|
207
161
|
}
|
|
208
162
|
async chat(input) {
|
|
209
|
-
var _a;
|
|
210
163
|
if (!this.executor)
|
|
211
164
|
await this.init();
|
|
212
|
-
this.
|
|
213
|
-
this.
|
|
214
|
-
console.log(`\n📊 状态: Context ${this.calculateTokens()} / Limit ${this.maxTokens} tokens`);
|
|
215
|
-
const stopLoading = this.showLoading("🤖 Agent 正在思考并执行工具...");
|
|
165
|
+
this.runningTokenCounter = this.encoder.encode(input).length;
|
|
166
|
+
const stopLoading = this.showLoading("🤖 Agent 正在思考并管理上下文...");
|
|
216
167
|
try {
|
|
168
|
+
// 执行请求,AgentExecutor 会自动:
|
|
169
|
+
// 1. 从 memory 加载历史 (chat_history)
|
|
170
|
+
// 2. 将这次对话的结果 saveContext 到 memory
|
|
217
171
|
const response = await this.executor.invoke({
|
|
218
172
|
input: input,
|
|
219
|
-
system_prompt: this.
|
|
173
|
+
system_prompt: this.systemPrompt,
|
|
220
174
|
}, {
|
|
221
|
-
// --- 新增:使用回调函数捕获 Thought ---
|
|
222
175
|
callbacks: [{
|
|
223
|
-
handleAgentAction: (action
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
const thoughtMatch = log.match(/Thought:\s*([\s\S]*?)(?=(?:```json|\{|Action:|$))/i);
|
|
228
|
-
let thought = "";
|
|
229
|
-
if (thoughtMatch && thoughtMatch[1]) {
|
|
230
|
-
thought = thoughtMatch[1].trim();
|
|
231
|
-
}
|
|
232
|
-
else {
|
|
233
|
-
// 备选方案:如果没有 Thought 标签,直接截取 JSON 之前的文本
|
|
234
|
-
thought = log.split(/```json|\{/)[0].replace(/Thought:/i, "").trim();
|
|
235
|
-
}
|
|
236
|
-
// 2. 只有当 thought 真的有文字内容(且不是 JSON)时才打印
|
|
237
|
-
if (thought && thought.length > 0 && !thought.startsWith('{')) {
|
|
238
|
-
// 进一步清洗:如果 thought 包含多行,只取非空的第一行,避免打印太长
|
|
239
|
-
const displayThought = thought.split('\n').find(line => line.trim().length > 0);
|
|
240
|
-
if (displayThought) {
|
|
241
|
-
console.log(`\n💭 [思考]: ${displayThought}`);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
176
|
+
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]}`);
|
|
244
180
|
}
|
|
245
181
|
}
|
|
246
182
|
}]
|
|
247
183
|
});
|
|
248
|
-
|
|
249
|
-
let output = typeof response.output === 'string'
|
|
250
|
-
? response.output
|
|
251
|
-
: JSON.stringify(response.output);
|
|
252
|
-
// 清洗 ReAct 冗余标签
|
|
253
|
-
if (output.includes("Final Answer:")) {
|
|
254
|
-
output = ((_a = output.split("Final Answer:").pop()) === null || _a === void 0 ? void 0 : _a.trim()) || output;
|
|
255
|
-
}
|
|
256
|
-
this.messages.push({ role: "assistant", content: output });
|
|
257
|
-
return output;
|
|
184
|
+
return typeof response.output === 'string' ? response.output : JSON.stringify(response.output);
|
|
258
185
|
}
|
|
259
186
|
finally {
|
|
260
187
|
stopLoading();
|
|
@@ -267,16 +194,12 @@ Thought: {agent_scratchpad}`);
|
|
|
267
194
|
process.stdout.write(`\r${chars[i]} ${text}`);
|
|
268
195
|
i = (i + 1) % chars.length;
|
|
269
196
|
}, 80);
|
|
270
|
-
return () => {
|
|
271
|
-
clearInterval(timer);
|
|
272
|
-
process.stdout.write('\r\x1b[K');
|
|
273
|
-
};
|
|
197
|
+
return () => { clearInterval(timer); process.stdout.write('\r\x1b[K'); };
|
|
274
198
|
}
|
|
275
199
|
async start() {
|
|
276
200
|
await this.init();
|
|
277
201
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
278
|
-
console.log(`\n🚀 AI
|
|
279
|
-
console.log(`📂 目标目录: ${this.targetDir}`);
|
|
202
|
+
console.log(`\n🚀 AI 助手 (Summary+Window 模式) 已启动`);
|
|
280
203
|
const chatLoop = () => {
|
|
281
204
|
rl.question("\n👤 你: ", async (input) => {
|
|
282
205
|
if (!input.trim())
|
|
@@ -284,8 +207,8 @@ Thought: {agent_scratchpad}`);
|
|
|
284
207
|
if (input.toLowerCase() === "exit")
|
|
285
208
|
process.exit(0);
|
|
286
209
|
try {
|
|
287
|
-
const
|
|
288
|
-
console.log(`\n🤖 Agent: ${
|
|
210
|
+
const res = await this.chat(input);
|
|
211
|
+
console.log(`\n🤖 Agent: ${res}`);
|
|
289
212
|
}
|
|
290
213
|
catch (err) {
|
|
291
214
|
console.error("\n❌ 系统错误:", err.message);
|
|
@@ -298,20 +221,11 @@ Thought: {agent_scratchpad}`);
|
|
|
298
221
|
async ensureApiConfig() {
|
|
299
222
|
if (this.apiConfig)
|
|
300
223
|
return this.apiConfig;
|
|
301
|
-
if (fs_1.default.existsSync(config_1.CONFIG_FILE))
|
|
224
|
+
if (fs_1.default.existsSync(config_1.CONFIG_FILE))
|
|
302
225
|
return JSON.parse(fs_1.default.readFileSync(config_1.CONFIG_FILE, "utf-8"));
|
|
303
|
-
}
|
|
304
|
-
const rl = readline.createInterface({
|
|
305
|
-
input: process.stdin,
|
|
306
|
-
output: process.stdout,
|
|
307
|
-
});
|
|
226
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
308
227
|
const question = (q) => new Promise((res) => rl.question(q, res));
|
|
309
|
-
|
|
310
|
-
const config = {
|
|
311
|
-
baseURL: await question("? API Base URL (如 https://api.openai.com/v1): "),
|
|
312
|
-
apiKey: await question("? API Key: "),
|
|
313
|
-
model: await question("? Model Name (如 gpt-4o): "),
|
|
314
|
-
};
|
|
228
|
+
const config = { baseURL: await question("? API Base URL: "), apiKey: await question("? API Key: "), model: await question("? Model Name: ") };
|
|
315
229
|
fs_1.default.writeFileSync(config_1.CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
316
230
|
rl.close();
|
|
317
231
|
return config;
|
package/lib/core/agent.js
CHANGED
|
@@ -57,24 +57,21 @@ class McpAgent {
|
|
|
57
57
|
this.extraTools = (options === null || options === void 0 ? void 0 : options.tools) || []; // 接收外部传入的工具
|
|
58
58
|
this.maxTokens = (options === null || options === void 0 ? void 0 : options.maxTokens) || 100000; // 默认 100k
|
|
59
59
|
this.apiConfig = options === null || options === void 0 ? void 0 : options.apiConfig;
|
|
60
|
-
let baseSystemPrompt =
|
|
60
|
+
let baseSystemPrompt = `你是一个专业的代码架构师。
|
|
61
|
+
你的目标是理解并分析用户项目,请务必遵循以下工作流:
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
### 执行准则:
|
|
76
|
-
- **任务导向**:直接通过工具链解决问题,减少不必要的中间对话。
|
|
77
|
-
- **自主决策**:根据任务需求自主选择最合适的工具组合,无需每一步都向用户请示。`;
|
|
63
|
+
### 第一阶段:全景感知 (The "Where" Phase)
|
|
64
|
+
1. **必须首先调用 'get_directory_tree'**:获取项目完整文件列表,包括样式文件 (.less, .css) 和资源文件。
|
|
65
|
+
2. 结合目录结构,观察项目架构(如 Monorepo 结构或 src 布局)。
|
|
66
|
+
|
|
67
|
+
### 第二阶段:逻辑映射 (The "What" Phase)
|
|
68
|
+
1. **调用 'get_repo_map'**:针对代码文件提取导出定义,理解模块间的调用关系。
|
|
69
|
+
2. 如果需要查看具体的样式定义,直接使用 'read_text_file' 读取 .less 或 .css 文件。
|
|
70
|
+
|
|
71
|
+
### 核心原则:
|
|
72
|
+
- 不要猜测文件是否存在,先看目录树。
|
|
73
|
+
- 优先查看 Skeleton(骨架),只有需要修复逻辑时才读取完整 Text(全文)。
|
|
74
|
+
- 始终以中文回答思考过程。`;
|
|
78
75
|
// 2. 拼接额外指令
|
|
79
76
|
if (options === null || options === void 0 ? void 0 : options.extraSystemPrompt) {
|
|
80
77
|
const extra = typeof options.extraSystemPrompt === 'string'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saber2pr/ai-agent",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.15",
|
|
4
4
|
"description": "AI Assistant CLI.",
|
|
5
5
|
"author": "saber2pr",
|
|
6
6
|
"license": "ISC",
|
|
@@ -25,13 +25,13 @@
|
|
|
25
25
|
"@langchain/core": "^1.1.18",
|
|
26
26
|
"@langchain/openai": "^1.2.4",
|
|
27
27
|
"@modelcontextprotocol/sdk": "^1.25.3",
|
|
28
|
-
"@saber2pr/ts-context-mcp": "^0.0.
|
|
29
|
-
"js-tiktoken": "^1.0.21",
|
|
30
|
-
"langchain": "~0.3",
|
|
31
|
-
"openai": "^6.16.0",
|
|
28
|
+
"@saber2pr/ts-context-mcp": "^0.0.8",
|
|
32
29
|
"diff": "^8.0.3",
|
|
33
30
|
"glob": "^10.5.0",
|
|
34
|
-
"
|
|
31
|
+
"js-tiktoken": "^1.0.21",
|
|
32
|
+
"langchain": "~0.3",
|
|
33
|
+
"minimatch": "^10.0.1",
|
|
34
|
+
"openai": "^6.16.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@types/node": "^16.3.3",
|