@nocobase/plugin-ai 2.1.0-alpha.13 → 2.1.0-alpha.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/dist/ai/ai-employees/atlas/index.d.ts +10 -0
- package/dist/ai/ai-employees/atlas/index.js +56 -0
- package/dist/ai/ai-employees/atlas/prompt.md +84 -0
- package/dist/ai/ai-employees/vera.js +1 -1
- package/dist/ai/skills/business-analysis-report/SKILLS.md +84 -0
- package/dist/ai/tools/businessReportGenerator.d.ts +10 -0
- package/dist/ai/tools/businessReportGenerator.js +83 -0
- package/dist/ai/tools/chartGenerator.js +1 -0
- package/dist/ai/tools/getSkill.js +1 -1
- package/dist/ai/tools/sub-agents/dispatch-sub-agent-task.d.ts +10 -0
- package/dist/ai/tools/sub-agents/dispatch-sub-agent-task.js +108 -0
- package/dist/ai/tools/sub-agents/get-ai-employee.d.ts +10 -0
- package/dist/ai/tools/sub-agents/get-ai-employee.js +67 -0
- package/dist/ai/tools/sub-agents/list-ai-employees.d.ts +10 -0
- package/dist/ai/tools/sub-agents/list-ai-employees.js +64 -0
- package/dist/ai/tools/sub-agents/shared.d.ts +33 -0
- package/dist/ai/tools/sub-agents/shared.js +169 -0
- package/dist/ai/tools/subAgentWebSearch.d.ts +10 -0
- package/dist/ai/tools/subAgentWebSearch.js +103 -0
- package/dist/ai/tools/suggestions.js +2 -2
- package/dist/client/0e94d90f0134df30.js +10 -0
- package/dist/client/{4f9117811ffc7ab3.js → 1c3ef55a6d63c9a3.js} +1 -1
- package/dist/client/55d67b74f02b8d74.js +10 -0
- package/dist/client/{6dc8c9b641452067.js → 5d5c118d11e91913.js} +1 -1
- package/dist/client/748fbb87c1013c6e.js +10 -0
- package/dist/client/8e82080c5e8ccfb7.js +10 -0
- package/dist/client/a8d6d81fb88f1a8e.js +10 -0
- package/dist/client/ai-employees/built-in/utils.d.ts +1 -0
- package/dist/client/ai-employees/business-report/tools/index.d.ts +10 -0
- package/dist/client/ai-employees/business-report/ui/BusinessReportCard.d.ts +12 -0
- package/dist/client/ai-employees/business-report/ui/BusinessReportModal.d.ts +17 -0
- package/dist/client/ai-employees/business-report/ui/report-utils.d.ts +36 -0
- package/dist/client/ai-employees/chatbox/AIEmployeeSwitch.d.ts +0 -1
- package/dist/client/ai-employees/chatbox/hooks/useChatBoxActions.d.ts +5 -3
- package/dist/client/ai-employees/chatbox/markdown/ECharts.d.ts +1 -2
- package/dist/client/ai-employees/chatbox/markdown/Markdown.d.ts +1 -1
- package/dist/client/ai-employees/chatbox/roles.d.ts +1 -0
- package/dist/client/ai-employees/chatbox/stores/chat-messages.d.ts +8 -0
- package/dist/client/ai-employees/chatbox/utils.d.ts +15 -1
- package/dist/client/ai-employees/sub-agents/tools/index.d.ts +10 -0
- package/dist/client/ai-employees/sub-agents/ui/SubAgentDispatchCard.d.ts +21 -0
- package/dist/client/ai-employees/types.d.ts +19 -0
- package/dist/client/c065565ccbb41f99.js +10 -0
- package/dist/client/d5e9663991c30eed.js +10 -0
- package/dist/client/f87cff5213f94856.js +10 -0
- package/dist/client/f8c075896e8b9c0b.js +10 -0
- package/dist/client/fd4e5dcaf24052c1.js +10 -0
- package/dist/client/index.js +7 -7
- package/dist/client/manager/ai-manager.d.ts +4 -23
- package/dist/externalVersion.js +17 -15
- package/dist/locale/en-US.json +30 -1
- package/dist/locale/zh-CN.json +30 -1
- package/dist/node_modules/fast-glob/package.json +1 -1
- package/dist/node_modules/flexsearch/package.json +1 -1
- package/dist/node_modules/fs-extra/package.json +1 -1
- package/dist/node_modules/nodejs-snowflake/package.json +1 -1
- package/dist/node_modules/openai/package.json +1 -1
- package/dist/node_modules/zod/package.json +1 -1
- package/dist/server/ai-employees/ai-conversations.d.ts +64 -0
- package/dist/server/ai-employees/ai-conversations.js +285 -0
- package/dist/server/ai-employees/ai-employee.d.ts +88 -14
- package/dist/server/ai-employees/ai-employee.js +335 -200
- package/dist/server/ai-employees/middleware/conversation.d.ts +2 -0
- package/dist/server/ai-employees/middleware/conversation.js +38 -5
- package/dist/server/ai-employees/middleware/tools.js +37 -10
- package/dist/server/ai-employees/prompts.d.ts +11 -1
- package/dist/server/ai-employees/prompts.js +29 -2
- package/dist/server/ai-employees/sub-agents/dispatcher.d.ts +36 -0
- package/dist/server/ai-employees/sub-agents/dispatcher.js +225 -0
- package/dist/server/ai-employees/sub-agents/index.d.ts +9 -0
- package/dist/server/ai-employees/sub-agents/index.js +36 -0
- package/dist/server/ai-employees/utils.js +1 -1
- package/dist/server/collections/ai-conversations.js +6 -0
- package/dist/server/llm-providers/anthropic.d.ts +1 -0
- package/dist/server/llm-providers/anthropic.js +2 -1
- package/dist/server/llm-providers/dashscope.d.ts +3 -0
- package/dist/server/llm-providers/dashscope.js +13 -1
- package/dist/server/llm-providers/deepseek.d.ts +1 -0
- package/dist/server/llm-providers/deepseek.js +5 -2
- package/dist/server/llm-providers/google-genai.d.ts +1 -0
- package/dist/server/llm-providers/google-genai.js +2 -1
- package/dist/server/llm-providers/kimi/provider.d.ts +1 -0
- package/dist/server/llm-providers/openai/responses.d.ts +1 -0
- package/dist/server/llm-providers/openai/responses.js +2 -1
- package/dist/server/llm-providers/provider.d.ts +1 -10
- package/dist/server/llm-providers/provider.js +3 -34
- package/dist/server/manager/ai-manager.d.ts +10 -0
- package/dist/server/manager/ai-manager.js +32 -0
- package/dist/server/migrations/20260319000000-add-ai-conversations-from.d.ts +14 -0
- package/dist/server/migrations/20260319000000-add-ai-conversations-from.js +63 -0
- package/dist/server/plugin.d.ts +4 -0
- package/dist/server/plugin.js +4 -0
- package/dist/server/resource/aiConversations.d.ts +3 -3
- package/dist/server/resource/aiConversations.js +125 -159
- package/dist/server/types/ai-chat-conversation.type.d.ts +8 -2
- package/dist/server/types/ai-message.type.d.ts +7 -0
- package/dist/server/utils.d.ts +3 -0
- package/dist/server/utils.js +28 -1
- package/package.json +4 -2
- package/dist/client/27539a4356faebb1.js +0 -10
- package/dist/client/39492c2121f4c722.js +0 -10
- package/dist/client/53190ab4290ef9d5.js +0 -10
- package/dist/client/9c00efb8eb0b4d69.js +0 -10
- package/dist/client/d4e2ed9fa44a82b2.js +0 -10
|
@@ -36,11 +36,11 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
36
36
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
37
|
var ai_employee_exports = {};
|
|
38
38
|
__export(ai_employee_exports, {
|
|
39
|
-
AIEmployee: () => AIEmployee
|
|
39
|
+
AIEmployee: () => AIEmployee,
|
|
40
|
+
ChatStreamProtocol: () => ChatStreamProtocol
|
|
40
41
|
});
|
|
41
42
|
module.exports = __toCommonJS(ai_employee_exports);
|
|
42
43
|
var import_database = require("@nocobase/database");
|
|
43
|
-
var import_provider = require("../llm-providers/provider");
|
|
44
44
|
var import_utils = require("../utils");
|
|
45
45
|
var import_prompts = require("./prompts");
|
|
46
46
|
var import_lodash = __toESM(require("lodash"));
|
|
@@ -54,20 +54,32 @@ var import_langgraph = require("@langchain/langgraph");
|
|
|
54
54
|
var import_stream = require("@langchain/core/utils/stream");
|
|
55
55
|
var import_utils2 = require("./utils");
|
|
56
56
|
var import_base = require("@langchain/core/callbacks/base");
|
|
57
|
+
var import_shared = require("../../ai/tools/sub-agents/shared");
|
|
57
58
|
class AIEmployee {
|
|
59
|
+
sessionId;
|
|
60
|
+
from = "main-agent";
|
|
58
61
|
employee;
|
|
59
62
|
aiChatConversation;
|
|
60
63
|
skillSettings;
|
|
61
64
|
plugin;
|
|
62
65
|
db;
|
|
63
|
-
sessionId;
|
|
64
66
|
ctx;
|
|
65
67
|
systemMessage;
|
|
68
|
+
protocol;
|
|
66
69
|
webSearch;
|
|
67
70
|
model;
|
|
68
71
|
legacy;
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
constructor({
|
|
73
|
+
ctx,
|
|
74
|
+
employee,
|
|
75
|
+
sessionId,
|
|
76
|
+
systemMessage,
|
|
77
|
+
skillSettings,
|
|
78
|
+
webSearch,
|
|
79
|
+
model,
|
|
80
|
+
legacy,
|
|
81
|
+
from = "main-agent"
|
|
82
|
+
}) {
|
|
71
83
|
this.employee = employee;
|
|
72
84
|
this.ctx = ctx;
|
|
73
85
|
this.plugin = ctx.app.pm.get("ai");
|
|
@@ -78,10 +90,21 @@ class AIEmployee {
|
|
|
78
90
|
this.skillSettings = skillSettings;
|
|
79
91
|
this.model = model;
|
|
80
92
|
this.legacy = legacy;
|
|
93
|
+
this.from = from;
|
|
81
94
|
const builtInManager = this.plugin.builtInManager;
|
|
82
95
|
builtInManager.setupBuiltInInfo(ctx, this.employee);
|
|
83
96
|
this.webSearch = webSearch;
|
|
84
|
-
this.protocol = ChatStreamProtocol.
|
|
97
|
+
this.protocol = ChatStreamProtocol.fromContext(ctx);
|
|
98
|
+
}
|
|
99
|
+
async getFormatMessages(userMessages) {
|
|
100
|
+
const { provider } = await this.plugin.aiManager.getLLMService({
|
|
101
|
+
...this.model
|
|
102
|
+
});
|
|
103
|
+
const { messages } = await this.aiChatConversation.getChatContext({
|
|
104
|
+
userMessages,
|
|
105
|
+
formatMessages: (messages2) => this.formatMessages({ messages: messages2, provider })
|
|
106
|
+
});
|
|
107
|
+
return messages;
|
|
85
108
|
}
|
|
86
109
|
// === Chat flow ===
|
|
87
110
|
buildState(messages) {
|
|
@@ -133,7 +156,9 @@ class AIEmployee {
|
|
|
133
156
|
userMessages,
|
|
134
157
|
userDecisions
|
|
135
158
|
}) {
|
|
136
|
-
const { provider, model, service } = await this.getLLMService(
|
|
159
|
+
const { provider, model, service } = await this.plugin.aiManager.getLLMService({
|
|
160
|
+
...this.model
|
|
161
|
+
});
|
|
137
162
|
const { historyMessages, tools, middleware, config, state } = await this.initSession({
|
|
138
163
|
messageId,
|
|
139
164
|
provider,
|
|
@@ -186,7 +211,9 @@ class AIEmployee {
|
|
|
186
211
|
async invoke({
|
|
187
212
|
messageId,
|
|
188
213
|
userMessages = [],
|
|
189
|
-
userDecisions
|
|
214
|
+
userDecisions,
|
|
215
|
+
writer,
|
|
216
|
+
context
|
|
190
217
|
}) {
|
|
191
218
|
try {
|
|
192
219
|
const { provider, chatContext, config, state } = await this.buildChatContext({
|
|
@@ -194,54 +221,25 @@ class AIEmployee {
|
|
|
194
221
|
userMessages,
|
|
195
222
|
userDecisions
|
|
196
223
|
});
|
|
197
|
-
const { threadId } = await this.getCurrentThread();
|
|
198
224
|
const invokeConfig = {
|
|
199
|
-
|
|
200
|
-
context: { ctx: this.ctx },
|
|
225
|
+
context: { ctx: this.ctx, decisions: chatContext.decisions, ...context },
|
|
201
226
|
recursionLimit: 100,
|
|
227
|
+
writer,
|
|
202
228
|
...config
|
|
203
229
|
};
|
|
230
|
+
if (this.from === "main-agent") {
|
|
231
|
+
const { threadId } = await this.getCurrentThread();
|
|
232
|
+
invokeConfig.configurable = { thread_id: threadId };
|
|
233
|
+
}
|
|
204
234
|
return await this.agentInvoke(provider, chatContext, invokeConfig, state);
|
|
205
235
|
} catch (err) {
|
|
236
|
+
if (err.name === "GraphInterrupt") {
|
|
237
|
+
throw err;
|
|
238
|
+
}
|
|
206
239
|
this.ctx.log.error(err);
|
|
207
240
|
throw err;
|
|
208
241
|
}
|
|
209
242
|
}
|
|
210
|
-
// === LLM/provider setup ===
|
|
211
|
-
async getLLMService() {
|
|
212
|
-
var _a, _b;
|
|
213
|
-
if (!((_a = this.model) == null ? void 0 : _a.llmService) || !((_b = this.model) == null ? void 0 : _b.model)) {
|
|
214
|
-
throw new Error("LLM service not configured");
|
|
215
|
-
}
|
|
216
|
-
const llmServiceName = this.model.llmService;
|
|
217
|
-
const model = this.model.model;
|
|
218
|
-
const modelOptions = {
|
|
219
|
-
llmService: llmServiceName,
|
|
220
|
-
model
|
|
221
|
-
};
|
|
222
|
-
if (this.webSearch === true) {
|
|
223
|
-
modelOptions.builtIn = { webSearch: true };
|
|
224
|
-
}
|
|
225
|
-
const service = await this.db.getRepository("llmServices").findOne({
|
|
226
|
-
filter: {
|
|
227
|
-
name: llmServiceName
|
|
228
|
-
}
|
|
229
|
-
});
|
|
230
|
-
if (!service) {
|
|
231
|
-
throw new Error("LLM service not found");
|
|
232
|
-
}
|
|
233
|
-
const providerOptions = this.plugin.aiManager.llmProviders.get(service.provider);
|
|
234
|
-
if (!providerOptions) {
|
|
235
|
-
throw new Error("LLM service provider not found");
|
|
236
|
-
}
|
|
237
|
-
const Provider = providerOptions.provider;
|
|
238
|
-
const provider = new Provider({
|
|
239
|
-
app: this.ctx.app,
|
|
240
|
-
serviceOptions: service.options,
|
|
241
|
-
modelOptions
|
|
242
|
-
});
|
|
243
|
-
return { provider, model, service };
|
|
244
|
-
}
|
|
245
243
|
// === Agent wiring & execution ===
|
|
246
244
|
async createAgent({
|
|
247
245
|
provider,
|
|
@@ -250,17 +248,24 @@ class AIEmployee {
|
|
|
250
248
|
middleware
|
|
251
249
|
}) {
|
|
252
250
|
const model = provider.createModel();
|
|
253
|
-
const
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
251
|
+
const allTools = provider.resolveTools((tools == null ? void 0 : tools.map(import_utils.buildTool)) ?? []);
|
|
252
|
+
if (this.from === "main-agent") {
|
|
253
|
+
const checkpointer = new import_checkpoints.SequelizeCollectionSaver(() => this.ctx.app.mainDataSource);
|
|
254
|
+
return (0, import_langchain.createAgent)({ model, tools: allTools, middleware, systemPrompt, checkpointer });
|
|
255
|
+
} else {
|
|
256
|
+
return (0, import_langchain.createAgent)({ model, tools: allTools, middleware, systemPrompt });
|
|
257
|
+
}
|
|
257
258
|
}
|
|
258
259
|
getAgentInput(context, state) {
|
|
259
|
-
var _a;
|
|
260
|
-
if ((_a = context.decisions) == null ? void 0 : _a.length) {
|
|
260
|
+
var _a, _b;
|
|
261
|
+
if ((_b = (_a = context.decisions) == null ? void 0 : _a.decisions) == null ? void 0 : _b.length) {
|
|
261
262
|
return new import_langgraph.Command({
|
|
262
|
-
resume: {
|
|
263
|
-
decisions:
|
|
263
|
+
resume: context.decisions.interruptId ? {
|
|
264
|
+
[context.decisions.interruptId]: {
|
|
265
|
+
decisions: context.decisions.decisions
|
|
266
|
+
}
|
|
267
|
+
} : {
|
|
268
|
+
decisions: context.decisions.decisions
|
|
264
269
|
}
|
|
265
270
|
});
|
|
266
271
|
}
|
|
@@ -273,13 +278,16 @@ class AIEmployee {
|
|
|
273
278
|
const { systemPrompt, tools, middleware } = context;
|
|
274
279
|
const agent = await this.createAgent({ provider, systemPrompt, tools, middleware });
|
|
275
280
|
const input = this.getAgentInput(context, state);
|
|
276
|
-
|
|
281
|
+
if (this.from === "sub-agent") {
|
|
282
|
+
delete config.configurable;
|
|
283
|
+
}
|
|
284
|
+
return agent.stream(input, this.withRunMetadata(config));
|
|
277
285
|
}
|
|
278
286
|
async agentInvoke(provider, context, config, state) {
|
|
279
287
|
const { systemPrompt, tools, middleware } = context;
|
|
280
288
|
const agent = await this.createAgent({ provider, systemPrompt, tools, middleware });
|
|
281
289
|
const input = this.getAgentInput(context, state);
|
|
282
|
-
return agent.invoke(input, config);
|
|
290
|
+
return agent.invoke(input, this.withRunMetadata(config));
|
|
283
291
|
}
|
|
284
292
|
async prepareChatStream({
|
|
285
293
|
chatContext,
|
|
@@ -297,8 +305,8 @@ class AIEmployee {
|
|
|
297
305
|
{
|
|
298
306
|
signal,
|
|
299
307
|
streamMode: ["updates", "messages", "custom"],
|
|
300
|
-
configurable: { thread_id: threadId },
|
|
301
|
-
context: { ctx: this.ctx },
|
|
308
|
+
configurable: this.from === "main-agent" ? { thread_id: threadId } : void 0,
|
|
309
|
+
context: { ctx: this.ctx, decisions: chatContext.decisions },
|
|
302
310
|
recursionLimit: 100,
|
|
303
311
|
...config
|
|
304
312
|
},
|
|
@@ -311,76 +319,91 @@ class AIEmployee {
|
|
|
311
319
|
}
|
|
312
320
|
}
|
|
313
321
|
async processChatStream(stream, options) {
|
|
314
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t;
|
|
315
|
-
|
|
322
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
|
|
323
|
+
const aiMessageIdMap = /* @__PURE__ */ new Map();
|
|
316
324
|
const { signal, providerName, model, provider, responseMetadata, allowEmpty = false } = options;
|
|
317
325
|
let isReasoning = false;
|
|
318
326
|
let gathered;
|
|
319
327
|
signal.addEventListener("abort", async () => {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
values
|
|
329
|
-
|
|
330
|
-
await this.aiChatConversation.withTransaction(async (conversation, transaction) => {
|
|
331
|
-
const result = await conversation.addMessages(values);
|
|
332
|
-
if (toolCalls == null ? void 0 : toolCalls.length) {
|
|
333
|
-
await this.initToolCall(transaction, result.messageId, toolCalls);
|
|
328
|
+
try {
|
|
329
|
+
if ((gathered == null ? void 0 : gathered.type) === "ai") {
|
|
330
|
+
const values = (0, import_utils2.convertAIMessage)({
|
|
331
|
+
aiEmployee: this,
|
|
332
|
+
providerName,
|
|
333
|
+
model,
|
|
334
|
+
aiMessage: gathered
|
|
335
|
+
});
|
|
336
|
+
if (values) {
|
|
337
|
+
values.metadata.interrupted = true;
|
|
334
338
|
}
|
|
335
|
-
|
|
339
|
+
await this.aiChatConversation.withTransaction(async (conversation, transaction) => {
|
|
340
|
+
const result = await conversation.addMessages(values);
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
} catch (e) {
|
|
344
|
+
this.logger.error("Fail to save message after conversation abort", gathered);
|
|
336
345
|
}
|
|
337
346
|
});
|
|
338
347
|
try {
|
|
339
|
-
|
|
348
|
+
const aiEmployeeConversation = {
|
|
349
|
+
sessionId: this.sessionId,
|
|
350
|
+
from: this.from,
|
|
351
|
+
username: this.employee.username
|
|
352
|
+
};
|
|
353
|
+
this.protocol.with(aiEmployeeConversation).startStream();
|
|
340
354
|
for await (const [mode, chunks] of stream) {
|
|
341
355
|
if (mode === "messages") {
|
|
342
|
-
const [chunk] = chunks;
|
|
356
|
+
const [chunk, metadata] = chunks;
|
|
357
|
+
const { currentConversation } = metadata;
|
|
343
358
|
if (chunk.type === "ai") {
|
|
344
359
|
gathered = gathered !== void 0 ? (0, import_stream.concat)(gathered, chunk) : chunk;
|
|
345
360
|
if (chunk.content) {
|
|
346
361
|
if (isReasoning) {
|
|
347
362
|
isReasoning = false;
|
|
348
|
-
this.protocol.stopReasoning();
|
|
363
|
+
this.protocol.with(currentConversation).stopReasoning();
|
|
349
364
|
}
|
|
350
365
|
const parsedContent = provider.parseResponseChunk(chunk.content);
|
|
351
366
|
if (parsedContent) {
|
|
352
|
-
this.protocol.content(parsedContent);
|
|
367
|
+
this.protocol.with(currentConversation).content(parsedContent);
|
|
353
368
|
}
|
|
354
369
|
}
|
|
355
370
|
if ((_a = chunk.tool_call_chunks) == null ? void 0 : _a.length) {
|
|
356
|
-
this.protocol.toolCallChunks(chunk.tool_call_chunks);
|
|
371
|
+
this.protocol.with(currentConversation).toolCallChunks(chunk.tool_call_chunks);
|
|
357
372
|
}
|
|
358
373
|
const webSearch = provider.parseWebSearchAction(chunk);
|
|
359
374
|
if (webSearch == null ? void 0 : webSearch.length) {
|
|
360
|
-
this.protocol.webSearch(webSearch);
|
|
375
|
+
this.protocol.with(currentConversation).webSearch(webSearch);
|
|
361
376
|
}
|
|
362
377
|
const reasoningContent = provider.parseReasoningContent(chunk);
|
|
363
378
|
if (reasoningContent) {
|
|
364
379
|
isReasoning = true;
|
|
365
|
-
this.protocol.reasoning(reasoningContent);
|
|
380
|
+
this.protocol.with(currentConversation).reasoning(reasoningContent);
|
|
366
381
|
}
|
|
367
382
|
}
|
|
368
383
|
} else if (mode === "updates") {
|
|
369
384
|
if ("__interrupt__" in chunks) {
|
|
385
|
+
const interruptId = chunks.__interrupt__[0].id;
|
|
370
386
|
const interruptActions = this.toInterruptActions(chunks.__interrupt__[0].value);
|
|
371
387
|
if (interruptActions.size) {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
if (!interruptAction) {
|
|
388
|
+
const toolsMap = await this.getToolsMap();
|
|
389
|
+
for (const interruptAction of interruptActions.values()) {
|
|
390
|
+
if (!interruptAction.currentConversation || !interruptAction.toolCall) {
|
|
391
|
+
this.logger.warn("currentConversation or toolCall not exist in __interrupt__", interruptAction);
|
|
375
392
|
continue;
|
|
376
393
|
}
|
|
377
|
-
|
|
378
|
-
|
|
394
|
+
const { sessionId, from, username } = interruptAction.currentConversation;
|
|
395
|
+
const { id: toolCallId, name: toolCallName } = interruptAction.toolCall;
|
|
396
|
+
const messageId = aiMessageIdMap.get(sessionId);
|
|
397
|
+
if (!messageId) {
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
await this.updateToolCallInterrupted(sessionId, messageId, toolCallId, interruptId, interruptAction);
|
|
401
|
+
this.protocol.with(interruptAction.currentConversation).toolCallStatus({
|
|
379
402
|
toolCall: {
|
|
380
|
-
messageId
|
|
381
|
-
id:
|
|
382
|
-
name:
|
|
383
|
-
willInterrupt:
|
|
403
|
+
messageId,
|
|
404
|
+
id: toolCallId,
|
|
405
|
+
name: toolCallName,
|
|
406
|
+
willInterrupt: this.shouldInterruptToolCall(toolsMap.get(toolCallName))
|
|
384
407
|
},
|
|
385
408
|
invokeStatus: "interrupted",
|
|
386
409
|
interruptAction
|
|
@@ -389,7 +412,9 @@ class AIEmployee {
|
|
|
389
412
|
}
|
|
390
413
|
}
|
|
391
414
|
} else if (mode === "custom") {
|
|
415
|
+
const { currentConversation } = chunks;
|
|
392
416
|
if (chunks.action === "AfterAIMessageSaved") {
|
|
417
|
+
aiMessageIdMap.set(currentConversation.sessionId, chunks.body.messageId);
|
|
393
418
|
const data = responseMetadata.get(chunks.body.id);
|
|
394
419
|
if (data) {
|
|
395
420
|
const savedMessage = await this.aiMessagesModel.findOne({
|
|
@@ -417,32 +442,34 @@ class AIEmployee {
|
|
|
417
442
|
}
|
|
418
443
|
}
|
|
419
444
|
} else if (chunks.action === "initToolCalls") {
|
|
420
|
-
toolCalls
|
|
421
|
-
this.protocol.toolCalls(chunks.body);
|
|
445
|
+
this.protocol.with(currentConversation).toolCalls(chunks.body);
|
|
422
446
|
} else if (chunks.action === "beforeToolCall") {
|
|
423
447
|
const toolsMap = await this.getToolsMap();
|
|
424
|
-
const willInterrupt = this.shouldInterruptToolCall(toolsMap.get((
|
|
425
|
-
this.protocol.toolCallStatus({
|
|
448
|
+
const willInterrupt = this.shouldInterruptToolCall(toolsMap.get((_c = (_b = chunks.body) == null ? void 0 : _b.toolCall) == null ? void 0 : _c.name));
|
|
449
|
+
this.protocol.with(currentConversation).toolCallStatus({
|
|
426
450
|
toolCall: {
|
|
427
|
-
messageId: (
|
|
428
|
-
id: (
|
|
429
|
-
name: (
|
|
451
|
+
messageId: (_e = (_d = chunks.body) == null ? void 0 : _d.toolCall) == null ? void 0 : _e.messageId,
|
|
452
|
+
id: (_g = (_f = chunks.body) == null ? void 0 : _f.toolCall) == null ? void 0 : _g.id,
|
|
453
|
+
name: (_i = (_h = chunks.body) == null ? void 0 : _h.toolCall) == null ? void 0 : _i.name,
|
|
430
454
|
willInterrupt
|
|
431
455
|
},
|
|
432
456
|
invokeStatus: "pending"
|
|
433
457
|
});
|
|
434
458
|
} else if (chunks.action === "afterToolCall") {
|
|
435
459
|
const toolsMap = await this.getToolsMap();
|
|
436
|
-
const willInterrupt = this.shouldInterruptToolCall(toolsMap.get((
|
|
437
|
-
this.protocol.toolCallStatus({
|
|
460
|
+
const willInterrupt = this.shouldInterruptToolCall(toolsMap.get((_k = (_j = chunks.body) == null ? void 0 : _j.toolCall) == null ? void 0 : _k.name));
|
|
461
|
+
this.protocol.with(currentConversation).toolCallStatus({
|
|
438
462
|
toolCall: {
|
|
439
|
-
messageId: (
|
|
440
|
-
id: (
|
|
441
|
-
name: (
|
|
463
|
+
messageId: (_m = (_l = chunks.body) == null ? void 0 : _l.toolCall) == null ? void 0 : _m.messageId,
|
|
464
|
+
id: (_o = (_n = chunks.body) == null ? void 0 : _n.toolCall) == null ? void 0 : _o.id,
|
|
465
|
+
name: (_q = (_p = chunks.body) == null ? void 0 : _p.toolCall) == null ? void 0 : _q.name,
|
|
442
466
|
willInterrupt
|
|
443
467
|
},
|
|
444
468
|
invokeStatus: "done",
|
|
445
|
-
status: (
|
|
469
|
+
status: (_s = (_r = chunks.body) == null ? void 0 : _r.toolCallResult) == null ? void 0 : _s.status,
|
|
470
|
+
invokeStartTime: (_u = (_t = chunks.body) == null ? void 0 : _t.toolCallResult) == null ? void 0 : _u.invokeStartTime,
|
|
471
|
+
invokeEndTime: (_w = (_v = chunks.body) == null ? void 0 : _v.toolCallResult) == null ? void 0 : _w.invokeEndTime,
|
|
472
|
+
content: (_y = (_x = chunks.body) == null ? void 0 : _x.toolCallResult) == null ? void 0 : _y.content
|
|
446
473
|
});
|
|
447
474
|
} else if (chunks.action === "beforeSendToolMessage") {
|
|
448
475
|
const { messageId, messages } = chunks.body ?? {};
|
|
@@ -455,7 +482,7 @@ class AIEmployee {
|
|
|
455
482
|
for (const { metadata } of messages) {
|
|
456
483
|
const tools = toolsMap.get(metadata.toolName);
|
|
457
484
|
const toolCallResult = toolCallResultMap.get(metadata.toolCallId);
|
|
458
|
-
this.protocol.toolCallStatus({
|
|
485
|
+
this.protocol.with(currentConversation).toolCallStatus({
|
|
459
486
|
toolCall: {
|
|
460
487
|
messageId,
|
|
461
488
|
id: metadata.toolCallId,
|
|
@@ -463,11 +490,16 @@ class AIEmployee {
|
|
|
463
490
|
willInterrupt: this.shouldInterruptToolCall(tools)
|
|
464
491
|
},
|
|
465
492
|
invokeStatus: "confirmed",
|
|
466
|
-
status: toolCallResult == null ? void 0 : toolCallResult.status
|
|
493
|
+
status: toolCallResult == null ? void 0 : toolCallResult.status,
|
|
494
|
+
invokeStartTime: toolCallResult == null ? void 0 : toolCallResult.invokeStartTime,
|
|
495
|
+
invokeEndTime: toolCallResult == null ? void 0 : toolCallResult.invokeEndTime,
|
|
496
|
+
content: toolCallResult == null ? void 0 : toolCallResult.content
|
|
467
497
|
});
|
|
468
498
|
}
|
|
469
499
|
}
|
|
470
|
-
this.protocol.newMessage();
|
|
500
|
+
this.protocol.with(currentConversation).newMessage();
|
|
501
|
+
} else if (chunks.action === "afterSubAgentInvoke") {
|
|
502
|
+
this.protocol.with(currentConversation).subAgentCompleted();
|
|
471
503
|
}
|
|
472
504
|
}
|
|
473
505
|
}
|
|
@@ -475,7 +507,7 @@ class AIEmployee {
|
|
|
475
507
|
this.sendErrorResponse("Empty message");
|
|
476
508
|
return;
|
|
477
509
|
}
|
|
478
|
-
this.protocol.endStream();
|
|
510
|
+
this.protocol.with(aiEmployeeConversation).endStream();
|
|
479
511
|
} catch (err) {
|
|
480
512
|
this.ctx.log.error(err);
|
|
481
513
|
if (err.name === "GraphRecursionError") {
|
|
@@ -484,7 +516,9 @@ class AIEmployee {
|
|
|
484
516
|
this.sendErrorResponse(provider.parseResponseError(err));
|
|
485
517
|
}
|
|
486
518
|
} finally {
|
|
487
|
-
this.
|
|
519
|
+
if (this.from === "main-agent") {
|
|
520
|
+
this.ctx.res.end();
|
|
521
|
+
}
|
|
488
522
|
}
|
|
489
523
|
}
|
|
490
524
|
// === Prompts & knowledge base ===
|
|
@@ -566,6 +600,7 @@ ${workContextBackground.join("\n")}`;
|
|
|
566
600
|
}
|
|
567
601
|
}
|
|
568
602
|
const availableSkills = await this.getAvailableSkills();
|
|
603
|
+
const availableAIEmployees = await this.getAvailableAIEmployees();
|
|
569
604
|
const systemPrompt = (0, import_prompts.getSystemPrompt)({
|
|
570
605
|
aiEmployee: {
|
|
571
606
|
nickname: this.employee.nickname,
|
|
@@ -578,10 +613,13 @@ ${workContextBackground.join("\n")}`;
|
|
|
578
613
|
dataSources: dataSourceMessage,
|
|
579
614
|
environment: {
|
|
580
615
|
database: this.db.sequelize.getDialect(),
|
|
581
|
-
locale: this.ctx.getCurrentLocale() || "en-US"
|
|
616
|
+
locale: this.ctx.getCurrentLocale() || "en-US",
|
|
617
|
+
currentDateTime: getCurrentDateTimeForPrompt(this.ctx.getCurrentLocale(), getCurrentTimezone(this.ctx)),
|
|
618
|
+
timezone: getCurrentTimezone(this.ctx)
|
|
582
619
|
},
|
|
583
620
|
knowledgeBase,
|
|
584
|
-
availableSkills
|
|
621
|
+
availableSkills,
|
|
622
|
+
availableAIEmployees
|
|
585
623
|
});
|
|
586
624
|
const { important } = this.ctx.action.params.values || {};
|
|
587
625
|
if (important === "GraphRecursionError") {
|
|
@@ -706,23 +744,54 @@ If information is missing, clearly state it in the summary.</Important>`;
|
|
|
706
744
|
transaction
|
|
707
745
|
});
|
|
708
746
|
}
|
|
709
|
-
async updateToolCallInterrupted(messageId, toolCallId, interruptAction) {
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
747
|
+
async updateToolCallInterrupted(sessionId, messageId, toolCallId, interruptId, interruptAction) {
|
|
748
|
+
return await this.db.sequelize.transaction(async (transaction) => {
|
|
749
|
+
const [updated] = await this.aiToolMessagesModel.update(
|
|
750
|
+
{
|
|
751
|
+
invokeStatus: "interrupted",
|
|
752
|
+
interruptActionOrder: interruptAction.order,
|
|
753
|
+
interruptAction
|
|
754
|
+
},
|
|
755
|
+
{
|
|
756
|
+
where: {
|
|
757
|
+
sessionId,
|
|
758
|
+
messageId,
|
|
759
|
+
toolCallId,
|
|
760
|
+
invokeStatus: "init"
|
|
761
|
+
},
|
|
762
|
+
transaction
|
|
763
|
+
}
|
|
764
|
+
);
|
|
765
|
+
if (!updated) {
|
|
766
|
+
return updated;
|
|
767
|
+
}
|
|
768
|
+
const message = await this.aiMessagesModel.findOne({
|
|
717
769
|
where: {
|
|
718
|
-
sessionId: this.sessionId,
|
|
719
770
|
messageId,
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
771
|
+
sessionId
|
|
772
|
+
},
|
|
773
|
+
transaction
|
|
774
|
+
});
|
|
775
|
+
if (!message) {
|
|
776
|
+
return updated;
|
|
723
777
|
}
|
|
724
|
-
|
|
725
|
-
|
|
778
|
+
await this.aiMessagesModel.update(
|
|
779
|
+
{
|
|
780
|
+
metadata: {
|
|
781
|
+
...message.get("metadata") ?? {},
|
|
782
|
+
interruptId
|
|
783
|
+
}
|
|
784
|
+
},
|
|
785
|
+
{
|
|
786
|
+
where: {
|
|
787
|
+
messageId,
|
|
788
|
+
sessionId
|
|
789
|
+
},
|
|
790
|
+
transaction
|
|
791
|
+
}
|
|
792
|
+
);
|
|
793
|
+
return updated;
|
|
794
|
+
});
|
|
726
795
|
}
|
|
727
796
|
async updateToolCallPending(messageId, toolCallId) {
|
|
728
797
|
const [updated] = await this.aiToolMessagesModel.update(
|
|
@@ -784,7 +853,6 @@ If information is missing, clearly state it in the summary.</Important>`;
|
|
|
784
853
|
var _a;
|
|
785
854
|
return (_a = await this.aiToolMessagesModel.findOne({
|
|
786
855
|
where: {
|
|
787
|
-
sessionId: this.sessionId,
|
|
788
856
|
messageId,
|
|
789
857
|
toolCallId
|
|
790
858
|
}
|
|
@@ -793,7 +861,6 @@ If information is missing, clearly state it in the summary.</Important>`;
|
|
|
793
861
|
async getToolCallResultMap(messageId, toolCallIds) {
|
|
794
862
|
const list = (await this.aiToolMessagesModel.findAll({
|
|
795
863
|
where: {
|
|
796
|
-
sessionId: this.sessionId,
|
|
797
864
|
messageId,
|
|
798
865
|
toolCallId: {
|
|
799
866
|
[import_database.Op.in]: toolCallIds
|
|
@@ -802,19 +869,6 @@ If information is missing, clearly state it in the summary.</Important>`;
|
|
|
802
869
|
})).map((it) => it.toJSON());
|
|
803
870
|
return new Map(list.map((it) => [it.toolCallId, it]));
|
|
804
871
|
}
|
|
805
|
-
async getUserDecisions(messageId) {
|
|
806
|
-
const allInterruptedToolCall = await this.aiToolMessagesModel.findAll({
|
|
807
|
-
where: {
|
|
808
|
-
messageId,
|
|
809
|
-
interruptActionOrder: { [import_database.Op.not]: null }
|
|
810
|
-
},
|
|
811
|
-
order: [["interruptActionOrder", "ASC"]]
|
|
812
|
-
});
|
|
813
|
-
if (!allInterruptedToolCall.every((t) => t.invokeStatus === "waiting")) {
|
|
814
|
-
return [];
|
|
815
|
-
}
|
|
816
|
-
return allInterruptedToolCall.map((item) => item.userDecision);
|
|
817
|
-
}
|
|
818
872
|
async cancelToolCall() {
|
|
819
873
|
var _a;
|
|
820
874
|
let messageId;
|
|
@@ -829,7 +883,6 @@ If information is missing, clearly state it in the summary.</Important>`;
|
|
|
829
883
|
}
|
|
830
884
|
const toolMessages = (await this.aiToolMessagesModel.findAll({
|
|
831
885
|
where: {
|
|
832
|
-
sessionId: this.sessionId,
|
|
833
886
|
messageId,
|
|
834
887
|
invokeStatus: {
|
|
835
888
|
[import_database.Op.ne]: "confirmed"
|
|
@@ -839,7 +892,9 @@ If information is missing, clearly state it in the summary.</Important>`;
|
|
|
839
892
|
if (!toolMessages || import_lodash.default.isEmpty(toolMessages)) {
|
|
840
893
|
return;
|
|
841
894
|
}
|
|
842
|
-
const { model, service } = await this.getLLMService(
|
|
895
|
+
const { model, service } = await this.plugin.aiManager.getLLMService({
|
|
896
|
+
...this.model
|
|
897
|
+
});
|
|
843
898
|
const toolCallMap = await this.getToolCallMap(messageId);
|
|
844
899
|
const now = /* @__PURE__ */ new Date();
|
|
845
900
|
const toolMessageContent = "The user ignored the application for tools usage and will continued to ask questions";
|
|
@@ -1068,10 +1123,20 @@ If information is missing, clearly state it in the summary.</Important>`;
|
|
|
1068
1123
|
const actionRequestsMap = new Map(actionRequests.map((x) => [x.name, x]));
|
|
1069
1124
|
const reviewConfigsMap = new Map(reviewConfigs.map((x) => [x.actionName, x]));
|
|
1070
1125
|
for (const [name, actionRequest] of actionRequestsMap.entries()) {
|
|
1126
|
+
const payload = actionRequest.description ? JSON.parse(actionRequest.description) : null;
|
|
1071
1127
|
result.set(name, {
|
|
1072
1128
|
order: order++,
|
|
1073
1129
|
description: actionRequest.description,
|
|
1074
|
-
allowedDecisions: (_a = reviewConfigsMap.get(name)) == null ? void 0 : _a.allowedDecisions
|
|
1130
|
+
allowedDecisions: (_a = reviewConfigsMap.get(name)) == null ? void 0 : _a.allowedDecisions,
|
|
1131
|
+
toolCall: {
|
|
1132
|
+
id: payload.toolCallId,
|
|
1133
|
+
name: payload.toolCallName
|
|
1134
|
+
},
|
|
1135
|
+
currentConversation: {
|
|
1136
|
+
sessionId: payload.sessionId,
|
|
1137
|
+
from: payload.from,
|
|
1138
|
+
username: payload.username
|
|
1139
|
+
}
|
|
1075
1140
|
});
|
|
1076
1141
|
}
|
|
1077
1142
|
return result;
|
|
@@ -1079,6 +1144,10 @@ If information is missing, clearly state it in the summary.</Important>`;
|
|
|
1079
1144
|
async getAIEmployeeTools() {
|
|
1080
1145
|
var _a, _b;
|
|
1081
1146
|
const tools = await this.listTools({ scope: "GENERAL" });
|
|
1147
|
+
if (this.webSearch === true) {
|
|
1148
|
+
const subAgentWebSearch = await this.toolsManager.getTools("subAgentWebSearch");
|
|
1149
|
+
tools.push(subAgentWebSearch);
|
|
1150
|
+
}
|
|
1082
1151
|
const generalToolsNameSet = new Set(tools.map((x) => x.definition.name));
|
|
1083
1152
|
const toolMap = await this.getToolsMap();
|
|
1084
1153
|
const employeeTools = ((_a = this.employee.skillSettings) == null ? void 0 : _a.tools) ?? [];
|
|
@@ -1098,11 +1167,16 @@ If information is missing, clearly state it in the summary.</Important>`;
|
|
|
1098
1167
|
async getAvailableSkills() {
|
|
1099
1168
|
var _a, _b;
|
|
1100
1169
|
const { skillsManager } = this.plugin.ai;
|
|
1170
|
+
const aIEmployeeTools = await this.getAIEmployeeTools();
|
|
1171
|
+
const getSkill = aIEmployeeTools.find((it) => it.definition.name === "getSkill");
|
|
1172
|
+
if (!getSkill) {
|
|
1173
|
+
return [];
|
|
1174
|
+
}
|
|
1101
1175
|
const generalSkills = await skillsManager.listSkills({ scope: "GENERAL" });
|
|
1102
1176
|
const specifiedSkillNames = ((_a = this.employee.skillSettings) == null ? void 0 : _a.skills) ?? [];
|
|
1103
1177
|
const specifiedSkills = specifiedSkillNames.length ? await skillsManager.getSkills(specifiedSkillNames) : [];
|
|
1104
1178
|
const skillFilter = ((_b = this.skillSettings) == null ? void 0 : _b.skills) ?? [];
|
|
1105
|
-
return import_lodash.default.uniqBy([...
|
|
1179
|
+
return import_lodash.default.uniqBy([...specifiedSkills || [], ...generalSkills || []], "name").filter(
|
|
1106
1180
|
(it) => skillFilter.length === 0 || skillFilter.includes(it.name)
|
|
1107
1181
|
);
|
|
1108
1182
|
}
|
|
@@ -1167,6 +1241,12 @@ If information is missing, clearly state it in the summary.</Important>`;
|
|
|
1167
1241
|
}
|
|
1168
1242
|
return result;
|
|
1169
1243
|
}
|
|
1244
|
+
async getAvailableAIEmployees() {
|
|
1245
|
+
const availableAIEmployees = (await (0, import_shared.listAccessibleAIEmployees)(this.ctx)).map(
|
|
1246
|
+
(employee) => (0, import_shared.serializeEmployeeSummary)(this.ctx, employee)
|
|
1247
|
+
);
|
|
1248
|
+
return availableAIEmployees;
|
|
1249
|
+
}
|
|
1170
1250
|
getMiddleware(options) {
|
|
1171
1251
|
const { providerName, model, tools, baseToolNames, messageId, agentThread } = options;
|
|
1172
1252
|
return [
|
|
@@ -1206,6 +1286,19 @@ If information is missing, clearly state it in the summary.</Important>`;
|
|
|
1206
1286
|
listTools(filter) {
|
|
1207
1287
|
return this.toolsManager.listTools(filter);
|
|
1208
1288
|
}
|
|
1289
|
+
withRunMetadata(config) {
|
|
1290
|
+
return {
|
|
1291
|
+
...config,
|
|
1292
|
+
metadata: {
|
|
1293
|
+
...(config == null ? void 0 : config.metadata) ?? {},
|
|
1294
|
+
currentConversation: {
|
|
1295
|
+
sessionId: this.sessionId,
|
|
1296
|
+
from: this.from,
|
|
1297
|
+
username: this.employee.get("username")
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
};
|
|
1301
|
+
}
|
|
1209
1302
|
get toolsManager() {
|
|
1210
1303
|
return this.ctx.app.aiManager.toolsManager;
|
|
1211
1304
|
}
|
|
@@ -1228,6 +1321,33 @@ If information is missing, clearly state it in the summary.</Important>`;
|
|
|
1228
1321
|
return this.ctx.db.getModel("aiFiles");
|
|
1229
1322
|
}
|
|
1230
1323
|
}
|
|
1324
|
+
function getCurrentTimezone(ctx) {
|
|
1325
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1326
|
+
const value = ((_a = ctx.get) == null ? void 0 : _a.call(ctx, "x-timezone")) || ((_c = (_b = ctx.request) == null ? void 0 : _b.get) == null ? void 0 : _c.call(_b, "x-timezone")) || ((_e = (_d = ctx.request) == null ? void 0 : _d.header) == null ? void 0 : _e["x-timezone"]) || ((_g = (_f = ctx.req) == null ? void 0 : _f.headers) == null ? void 0 : _g["x-timezone"]) || Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
1327
|
+
if (Array.isArray(value)) {
|
|
1328
|
+
return value[0];
|
|
1329
|
+
}
|
|
1330
|
+
return typeof value === "string" ? value : void 0;
|
|
1331
|
+
}
|
|
1332
|
+
function getCurrentDateTimeForPrompt(locale, timezone) {
|
|
1333
|
+
const now = /* @__PURE__ */ new Date();
|
|
1334
|
+
const normalizedLocale = locale || "en-US";
|
|
1335
|
+
try {
|
|
1336
|
+
const formatter = new Intl.DateTimeFormat(normalizedLocale, {
|
|
1337
|
+
timeZone: timezone,
|
|
1338
|
+
year: "numeric",
|
|
1339
|
+
month: "2-digit",
|
|
1340
|
+
day: "2-digit",
|
|
1341
|
+
hour: "2-digit",
|
|
1342
|
+
minute: "2-digit",
|
|
1343
|
+
second: "2-digit",
|
|
1344
|
+
hour12: false
|
|
1345
|
+
});
|
|
1346
|
+
return `${formatter.format(now)}${timezone ? ` (${timezone})` : ""}`;
|
|
1347
|
+
} catch (error) {
|
|
1348
|
+
return `${now.toISOString()}${timezone ? ` (${timezone})` : ""}`;
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1231
1351
|
class AgentThread {
|
|
1232
1352
|
constructor(_sessionId, _thread) {
|
|
1233
1353
|
this._sessionId = _sessionId;
|
|
@@ -1250,8 +1370,8 @@ class AgentThread {
|
|
|
1250
1370
|
}
|
|
1251
1371
|
}
|
|
1252
1372
|
class ChatStreamProtocol {
|
|
1253
|
-
constructor(
|
|
1254
|
-
this.
|
|
1373
|
+
constructor(streamConsumer) {
|
|
1374
|
+
this.streamConsumer = streamConsumer;
|
|
1255
1375
|
}
|
|
1256
1376
|
_statistics = {
|
|
1257
1377
|
sent: 0,
|
|
@@ -1262,71 +1382,85 @@ class ChatStreamProtocol {
|
|
|
1262
1382
|
this._statistics.sent = 0;
|
|
1263
1383
|
}
|
|
1264
1384
|
};
|
|
1265
|
-
static
|
|
1266
|
-
return new ChatStreamProtocol(ctx);
|
|
1385
|
+
static fromContext(ctx) {
|
|
1386
|
+
return new ChatStreamProtocol(ctx.res);
|
|
1267
1387
|
}
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
}
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1388
|
+
with(conversation) {
|
|
1389
|
+
const write = ({ type, body }) => {
|
|
1390
|
+
const { sessionId, from, username } = conversation;
|
|
1391
|
+
const data = `data: ${JSON.stringify({ sessionId, from, username, type, body })}
|
|
1392
|
+
|
|
1393
|
+
`;
|
|
1394
|
+
this.streamConsumer.write(data);
|
|
1395
|
+
this._statistics.addSent(data.length);
|
|
1396
|
+
};
|
|
1397
|
+
return {
|
|
1398
|
+
startStream: () => {
|
|
1399
|
+
this._statistics.reset();
|
|
1400
|
+
write({ type: "stream_start" });
|
|
1401
|
+
},
|
|
1402
|
+
endStream: () => {
|
|
1403
|
+
write({ type: "stream_end" });
|
|
1404
|
+
},
|
|
1405
|
+
subAgentCompleted: () => {
|
|
1406
|
+
write({ type: "sub_agent_completed" });
|
|
1407
|
+
},
|
|
1408
|
+
newMessage: (content) => {
|
|
1409
|
+
write({ type: "new_message", body: content });
|
|
1410
|
+
},
|
|
1411
|
+
content: (content) => {
|
|
1412
|
+
write({ type: "content", body: content });
|
|
1413
|
+
},
|
|
1414
|
+
webSearch: (content) => {
|
|
1415
|
+
write({ type: "web_search", body: content });
|
|
1416
|
+
},
|
|
1417
|
+
reasoning: (content) => {
|
|
1418
|
+
write({ type: "reasoning", body: content });
|
|
1419
|
+
},
|
|
1420
|
+
stopReasoning: () => {
|
|
1421
|
+
write({
|
|
1422
|
+
type: "reasoning",
|
|
1423
|
+
body: {
|
|
1424
|
+
status: "stop",
|
|
1425
|
+
content: ""
|
|
1426
|
+
}
|
|
1427
|
+
});
|
|
1428
|
+
},
|
|
1429
|
+
toolCallChunks: (content) => {
|
|
1430
|
+
write({ type: "tool_call_chunks", body: content });
|
|
1431
|
+
},
|
|
1432
|
+
toolCalls: (content) => {
|
|
1433
|
+
write({ type: "tool_calls", body: content });
|
|
1434
|
+
},
|
|
1435
|
+
toolCallStatus: ({
|
|
1311
1436
|
toolCall,
|
|
1312
1437
|
invokeStatus,
|
|
1313
1438
|
status,
|
|
1439
|
+
invokeStartTime,
|
|
1440
|
+
invokeEndTime,
|
|
1441
|
+
content,
|
|
1314
1442
|
interruptAction
|
|
1443
|
+
}) => {
|
|
1444
|
+
write({
|
|
1445
|
+
type: "tool_call_status",
|
|
1446
|
+
body: {
|
|
1447
|
+
toolCall,
|
|
1448
|
+
invokeStatus,
|
|
1449
|
+
status,
|
|
1450
|
+
invokeStartTime,
|
|
1451
|
+
invokeEndTime,
|
|
1452
|
+
content,
|
|
1453
|
+
interruptAction
|
|
1454
|
+
}
|
|
1455
|
+
});
|
|
1315
1456
|
}
|
|
1316
|
-
}
|
|
1457
|
+
};
|
|
1317
1458
|
}
|
|
1318
1459
|
get statistics() {
|
|
1319
1460
|
return {
|
|
1320
1461
|
sent: this._statistics.sent
|
|
1321
1462
|
};
|
|
1322
1463
|
}
|
|
1323
|
-
write({ type, body }) {
|
|
1324
|
-
const data = `data: ${JSON.stringify({ type, body })}
|
|
1325
|
-
|
|
1326
|
-
`;
|
|
1327
|
-
this.ctx.res.write(data);
|
|
1328
|
-
this._statistics.addSent(data.length);
|
|
1329
|
-
}
|
|
1330
1464
|
}
|
|
1331
1465
|
class ResponseMetadataCollector extends import_base.BaseCallbackHandler {
|
|
1332
1466
|
constructor(llmProvider, responseMetadata) {
|
|
@@ -1347,5 +1481,6 @@ class ResponseMetadataCollector extends import_base.BaseCallbackHandler {
|
|
|
1347
1481
|
}
|
|
1348
1482
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1349
1483
|
0 && (module.exports = {
|
|
1350
|
-
AIEmployee
|
|
1484
|
+
AIEmployee,
|
|
1485
|
+
ChatStreamProtocol
|
|
1351
1486
|
});
|