inspiration-agent 0.0.1
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 +368 -0
- package/dist/.env.example +53 -0
- package/dist/README.md +368 -0
- package/dist/agent/ai.agent.js +712 -0
- package/dist/channel/feishu-connection.js +238 -0
- package/dist/channel/feishu.service.js +222 -0
- package/dist/cli.js +659 -0
- package/dist/config/system.prompt.txt +312 -0
- package/dist/index.js +176 -0
- package/dist/model/base-llm.service.js +320 -0
- package/dist/model/deepseek.service.js +18 -0
- package/dist/model/kimi.service.js +19 -0
- package/dist/model/minimax.service.js +35 -0
- package/dist/model/zhipu.service.js +26 -0
- package/dist/services/database.service.js +697 -0
- package/dist/services/memory.manager.js +486 -0
- package/dist/services/message.queue.js +157 -0
- package/dist/tools/browser.tools.js +814 -0
- package/dist/tools/command.tools.js +361 -0
- package/dist/tools/file.tools.js +222 -0
- package/dist/tools/memory.tools.js +393 -0
- package/dist/tools/scheduler.tools.js +559 -0
- package/dist/tools/search.tools.js +208 -0
- package/dist/utils/logger.js +52 -0
- package/dist/utils/markdown-renderer.js +207 -0
- package/package.json +51 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
const axios = require("axios");
|
|
2
|
+
const logger = require("../utils/logger");
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 基础 LLM 服务类
|
|
6
|
+
* 提供通用的 LLM API 调用功能
|
|
7
|
+
*/
|
|
8
|
+
class BaseLLMService {
|
|
9
|
+
constructor(config) {
|
|
10
|
+
this.apiKey = config.apiKey;
|
|
11
|
+
this.apiUrl = config.apiUrl;
|
|
12
|
+
this.model = config.model;
|
|
13
|
+
this.providerName = config.providerName || "LLM";
|
|
14
|
+
this.onTokenUsage = null;
|
|
15
|
+
this.toolHandlers = {};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
setTokenUsageCallback(callback) {
|
|
19
|
+
this.onTokenUsage = callback;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
registerToolHandler(name, handler) {
|
|
23
|
+
this.toolHandlers[name] = handler;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
getHeaders() {
|
|
27
|
+
return {
|
|
28
|
+
"Content-Type": "application/json",
|
|
29
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
buildPayload(messages, tools = null, toolChoice = null, stream = false) {
|
|
34
|
+
const payload = {
|
|
35
|
+
model: this.model,
|
|
36
|
+
messages: messages,
|
|
37
|
+
temperature: 0.7,
|
|
38
|
+
stream: stream,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
if (tools) {
|
|
42
|
+
payload.tools = tools;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (toolChoice) {
|
|
46
|
+
payload.tool_choice = toolChoice;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return payload;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
logRequest(messages, tools, toolChoice) {
|
|
53
|
+
logger.debug(`\n========== ${this.providerName} API 请求 ==========`);
|
|
54
|
+
logger.debug(`URL: ${this.apiUrl}`);
|
|
55
|
+
logger.debug(`Model: ${this.model}`);
|
|
56
|
+
logger.debug(`Messages: ${JSON.stringify(messages, null, 2)}`);
|
|
57
|
+
logger.debug(`Tools: ${tools ? JSON.stringify(tools, null, 2) : "无"}`);
|
|
58
|
+
logger.debug(`Tool Choice: ${toolChoice || "无"}`);
|
|
59
|
+
logger.debug("====================================\n");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
logResponse(content, toolCalls, usage) {
|
|
63
|
+
logger.debug(`\n========== ${this.providerName} API 响应 ==========`);
|
|
64
|
+
logger.debug("Content Length:", content.length);
|
|
65
|
+
logger.debug(`Content: ${content}`);
|
|
66
|
+
logger.debug("Tool Calls:", toolCalls.length > 0 ? toolCalls : "无");
|
|
67
|
+
logger.debug("Usage:", usage ? usage : "无");
|
|
68
|
+
logger.debug("====================================\n");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
handleError(error) {
|
|
72
|
+
logger.error(`\n========== ${this.providerName} API 错误 ==========`);
|
|
73
|
+
logger.error(`Error: ${error.message}`);
|
|
74
|
+
if (error.response) {
|
|
75
|
+
logger.error(`Status: ${error.response.status}`);
|
|
76
|
+
logger.error(`Data: ${JSON.stringify(error.response.data, null, 2)}`);
|
|
77
|
+
}
|
|
78
|
+
logger.error("====================================\n");
|
|
79
|
+
|
|
80
|
+
if (error.response) {
|
|
81
|
+
throw new Error(
|
|
82
|
+
`${this.providerName} API Error: ${error.response.status} - ${JSON.stringify(error.response.data)}`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
throw new Error(`${this.providerName} API Error: ${error.message}`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async chat(messages, tools = null, toolChoice = null) {
|
|
89
|
+
try {
|
|
90
|
+
this.logRequest(messages, tools, toolChoice);
|
|
91
|
+
|
|
92
|
+
const payload = this.buildPayload(messages, tools, toolChoice, false);
|
|
93
|
+
|
|
94
|
+
const response = await axios.post(this.apiUrl, payload, {
|
|
95
|
+
headers: this.getHeaders(),
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const message = response.data.choices[0].message;
|
|
99
|
+
const usage = response.data.usage;
|
|
100
|
+
|
|
101
|
+
this.logResponse(message.content || "", message.tool_calls || [], usage);
|
|
102
|
+
|
|
103
|
+
if (usage && this.onTokenUsage) {
|
|
104
|
+
this.onTokenUsage(usage.prompt_tokens || 0, usage.completion_tokens || 0);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return response.data;
|
|
108
|
+
} catch (error) {
|
|
109
|
+
this.handleError(error);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async chatStream(messages, onChunk, tools = null, toolChoice = null) {
|
|
114
|
+
try {
|
|
115
|
+
this.logRequest(messages, tools, toolChoice);
|
|
116
|
+
|
|
117
|
+
const payload = this.buildPayload(messages, tools, toolChoice, true);
|
|
118
|
+
|
|
119
|
+
const response = await axios.post(this.apiUrl, payload, {
|
|
120
|
+
headers: this.getHeaders(),
|
|
121
|
+
responseType: "stream",
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
return new Promise((resolve, reject) => {
|
|
125
|
+
let fullContent = "";
|
|
126
|
+
let buffer = "";
|
|
127
|
+
let toolCalls = [];
|
|
128
|
+
let usage = null;
|
|
129
|
+
|
|
130
|
+
response.data.on("data", (chunk) => {
|
|
131
|
+
buffer += chunk.toString();
|
|
132
|
+
const lines = buffer.split("\n");
|
|
133
|
+
buffer = lines.pop() || "";
|
|
134
|
+
|
|
135
|
+
for (const line of lines) {
|
|
136
|
+
if (line.startsWith("data: ")) {
|
|
137
|
+
const data = line.slice(6);
|
|
138
|
+
if (data === "[DONE]") {
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
const parsed = JSON.parse(data);
|
|
143
|
+
const delta = parsed.choices[0]?.delta;
|
|
144
|
+
|
|
145
|
+
if (parsed.usage) {
|
|
146
|
+
usage = parsed.usage;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (delta?.content) {
|
|
150
|
+
fullContent += delta.content;
|
|
151
|
+
onChunk(delta.content);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (delta?.tool_calls) {
|
|
155
|
+
for (const toolCall of delta.tool_calls) {
|
|
156
|
+
if (toolCall.index !== undefined) {
|
|
157
|
+
if (!toolCalls[toolCall.index]) {
|
|
158
|
+
toolCalls[toolCall.index] = {
|
|
159
|
+
id: toolCall.id,
|
|
160
|
+
type: toolCall.type,
|
|
161
|
+
function: {
|
|
162
|
+
name: toolCall.function?.name || "",
|
|
163
|
+
arguments: "",
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
if (toolCall.function?.name) {
|
|
168
|
+
toolCalls[toolCall.index].function.name = toolCall.function.name;
|
|
169
|
+
}
|
|
170
|
+
if (toolCall.function?.arguments) {
|
|
171
|
+
toolCalls[toolCall.index].function.arguments += toolCall.function.arguments;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
} catch (e) {
|
|
177
|
+
// 忽略解析错误
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
response.data.on("end", () => {
|
|
184
|
+
const result = { content: fullContent };
|
|
185
|
+
if (toolCalls.length > 0) {
|
|
186
|
+
result.tool_calls = toolCalls;
|
|
187
|
+
}
|
|
188
|
+
if (usage) {
|
|
189
|
+
result.usage = usage;
|
|
190
|
+
if (this.onTokenUsage) {
|
|
191
|
+
this.onTokenUsage(usage.prompt_tokens || 0, usage.completion_tokens || 0);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
this.logResponse(fullContent, toolCalls, usage);
|
|
196
|
+
resolve(result);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
response.data.on("error", (error) => {
|
|
200
|
+
reject(error);
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
} catch (error) {
|
|
204
|
+
this.handleError(error);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
async executeToolCall(toolCall) {
|
|
209
|
+
const { name, arguments: args } = toolCall.function;
|
|
210
|
+
|
|
211
|
+
logger.debug(`\n========== executeToolCall ==========`);
|
|
212
|
+
logger.debug(`工具名称: ${name}`);
|
|
213
|
+
logger.debug(`工具参数: ${args}`);
|
|
214
|
+
logger.debug(`======================================\n`);
|
|
215
|
+
|
|
216
|
+
try {
|
|
217
|
+
const parsedArgs = JSON.parse(args);
|
|
218
|
+
logger.debug(`参数解析成功: ${JSON.stringify(parsedArgs, null, 2)}`);
|
|
219
|
+
|
|
220
|
+
if (this.toolHandlers[name]) {
|
|
221
|
+
logger.debug(`找到工具处理器,开始执行...`);
|
|
222
|
+
const result = await this.toolHandlers[name](parsedArgs);
|
|
223
|
+
logger.debug(`工具执行完成,结果: ${JSON.stringify(result, null, 2)}`);
|
|
224
|
+
return result;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
228
|
+
} catch (error) {
|
|
229
|
+
logger.error(`工具执行失败: ${error}`);
|
|
230
|
+
throw error;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async chatWithFunctionCalls(messages, tools, maxIterations = 100) {
|
|
235
|
+
let currentMessages = [...messages];
|
|
236
|
+
let iteration = 0;
|
|
237
|
+
|
|
238
|
+
while (iteration < maxIterations) {
|
|
239
|
+
iteration++;
|
|
240
|
+
|
|
241
|
+
const response = await this.chat(currentMessages, tools);
|
|
242
|
+
const message = response.choices[0].message;
|
|
243
|
+
|
|
244
|
+
if (!message.tool_calls) {
|
|
245
|
+
return message;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
currentMessages.push(message);
|
|
249
|
+
|
|
250
|
+
for (const toolCall of message.tool_calls) {
|
|
251
|
+
const result = await this.executeToolCall(toolCall);
|
|
252
|
+
currentMessages.push({
|
|
253
|
+
tool_call_id: toolCall.id,
|
|
254
|
+
role: "tool",
|
|
255
|
+
content: JSON.stringify(result),
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
throw new Error("Max iterations reached without final response");
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
async chatWithFunctionCallsStream(messages, onChunk, tools, maxIterations = 100) {
|
|
264
|
+
let currentMessages = [...messages];
|
|
265
|
+
let iteration = 0;
|
|
266
|
+
|
|
267
|
+
logger.debug(`\n========== chatWithFunctionCallsStream 开始 ==========`);
|
|
268
|
+
logger.debug(`工具数量: ${tools?.length || 0}`);
|
|
269
|
+
logger.debug(`消息数量: ${messages?.length || 0}`);
|
|
270
|
+
logger.debug("==============================================\n");
|
|
271
|
+
|
|
272
|
+
while (iteration < maxIterations) {
|
|
273
|
+
iteration++;
|
|
274
|
+
|
|
275
|
+
logger.debug(`\n--- 迭代 ${iteration} ---`);
|
|
276
|
+
|
|
277
|
+
const response = await this.chatStream(
|
|
278
|
+
currentMessages,
|
|
279
|
+
(chunk) => {
|
|
280
|
+
onChunk(chunk);
|
|
281
|
+
},
|
|
282
|
+
tools
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
if (!response.tool_calls) {
|
|
286
|
+
logger.debug("\n未检测到 tool_calls,返回最终响应");
|
|
287
|
+
logger.debug("==============================================\n");
|
|
288
|
+
return response;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
logger.debug(`\n检测到 tool_calls,数量: ${response.tool_calls.length}`);
|
|
292
|
+
currentMessages.push({
|
|
293
|
+
role: "assistant",
|
|
294
|
+
tool_calls: response.tool_calls,
|
|
295
|
+
content: response.content || "",
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
for (const toolCall of response.tool_calls) {
|
|
299
|
+
logger.debug(`\n========== 准备执行工具 ==========`);
|
|
300
|
+
logger.debug(`工具 ID: ${toolCall.id}`);
|
|
301
|
+
logger.debug(`工具类型: ${toolCall.type}`);
|
|
302
|
+
logger.debug(`工具名称: ${toolCall.function.name}`);
|
|
303
|
+
logger.debug(`工具参数: ${toolCall.function.arguments}`);
|
|
304
|
+
logger.debug(`======================================\n`);
|
|
305
|
+
|
|
306
|
+
const result = await this.executeToolCall(toolCall);
|
|
307
|
+
logger.debug(`\n工具 ${toolCall.function.name} 执行完成`);
|
|
308
|
+
currentMessages.push({
|
|
309
|
+
tool_call_id: toolCall.id,
|
|
310
|
+
role: "tool",
|
|
311
|
+
content: JSON.stringify(result),
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
throw new Error("Max iterations reached without final response");
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
module.exports = BaseLLMService;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const BaseLLMService = require("./base-llm.service");
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* DeepSeek API 服务类
|
|
5
|
+
* 继承基础 LLM 服务,提供 DeepSeek 特定配置
|
|
6
|
+
*/
|
|
7
|
+
class DeepSeekService extends BaseLLMService {
|
|
8
|
+
constructor() {
|
|
9
|
+
super({
|
|
10
|
+
apiKey: process.env.DEEPSEEK_API_KEY,
|
|
11
|
+
apiUrl: process.env.DEEPSEEK_API_URL,
|
|
12
|
+
model: process.env.DEEPSEEK_MODEL || "deepseek-chat",
|
|
13
|
+
providerName: "DeepSeek",
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = DeepSeekService;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const BaseLLMService = require("./base-llm.service");
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Kimi (月之暗面) API 服务类
|
|
5
|
+
* 继承基础 LLM 服务,提供 Kimi 特定配置
|
|
6
|
+
* API 文档: https://platform.moonshot.cn/docs
|
|
7
|
+
*/
|
|
8
|
+
class KimiService extends BaseLLMService {
|
|
9
|
+
constructor() {
|
|
10
|
+
super({
|
|
11
|
+
apiKey: process.env.KIMI_API_KEY,
|
|
12
|
+
apiUrl: process.env.KIMI_API_URL || "https://api.moonshot.cn/v1/chat/completions",
|
|
13
|
+
model: process.env.KIMI_MODEL || "moonshot-v1-8k",
|
|
14
|
+
providerName: "Kimi",
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = KimiService;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const BaseLLMService = require("./base-llm.service");
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MiniMax API 服务类
|
|
5
|
+
* 继承基础 LLM 服务,提供 MiniMax 特定配置
|
|
6
|
+
* API 文档: https://www.minimaxi.com/document/
|
|
7
|
+
*/
|
|
8
|
+
class MiniMaxService extends BaseLLMService {
|
|
9
|
+
constructor() {
|
|
10
|
+
super({
|
|
11
|
+
apiKey: process.env.MINIMAX_API_KEY,
|
|
12
|
+
apiUrl: process.env.MINIMAX_API_URL || "https://api.minimax.chat/v1/chat/completions",
|
|
13
|
+
model: process.env.MINIMAX_MODEL || "abab6.5s-chat",
|
|
14
|
+
providerName: "MiniMax",
|
|
15
|
+
});
|
|
16
|
+
this.groupId = process.env.MINIMAX_GROUP_ID;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
getHeaders() {
|
|
20
|
+
return {
|
|
21
|
+
"Content-Type": "application/json",
|
|
22
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
buildPayload(messages, tools = null, toolChoice = null, stream = false) {
|
|
27
|
+
const payload = super.buildPayload(messages, tools, toolChoice, stream);
|
|
28
|
+
if (this.groupId) {
|
|
29
|
+
payload.group_id = this.groupId;
|
|
30
|
+
}
|
|
31
|
+
return payload;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = MiniMaxService;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const BaseLLMService = require("./base-llm.service");
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 智谱 GLM (ZhipuAI) API 服务类
|
|
5
|
+
* 继承基础 LLM 服务,提供智谱 GLM 特定配置
|
|
6
|
+
* API 文档: https://open.bigmodel.cn/dev/api
|
|
7
|
+
*/
|
|
8
|
+
class ZhipuService extends BaseLLMService {
|
|
9
|
+
constructor() {
|
|
10
|
+
super({
|
|
11
|
+
apiKey: process.env.ZHIPU_API_KEY,
|
|
12
|
+
apiUrl: process.env.ZHIPU_API_URL || "https://open.bigmodel.cn/api/paas/v4/chat/completions",
|
|
13
|
+
model: process.env.ZHIPU_MODEL || "glm-4-flash",
|
|
14
|
+
providerName: "ZhipuGLM",
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
getHeaders() {
|
|
19
|
+
return {
|
|
20
|
+
"Content-Type": "application/json",
|
|
21
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = ZhipuService;
|