@nocobase/plugin-ai 2.1.0-alpha.13 → 2.1.0-alpha.14

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.
Files changed (75) hide show
  1. package/dist/ai/ai-employees/atlas/index.d.ts +10 -0
  2. package/dist/ai/ai-employees/atlas/index.js +56 -0
  3. package/dist/ai/ai-employees/atlas/prompt.md +84 -0
  4. package/dist/ai/ai-employees/vera.js +1 -1
  5. package/dist/ai/tools/chartGenerator.js +1 -0
  6. package/dist/ai/tools/getSkill.js +1 -1
  7. package/dist/ai/tools/sub-agents/dispatch-sub-agent-task.d.ts +10 -0
  8. package/dist/ai/tools/sub-agents/dispatch-sub-agent-task.js +108 -0
  9. package/dist/ai/tools/sub-agents/get-ai-employee.d.ts +10 -0
  10. package/dist/ai/tools/sub-agents/get-ai-employee.js +67 -0
  11. package/dist/ai/tools/sub-agents/list-ai-employees.d.ts +10 -0
  12. package/dist/ai/tools/sub-agents/list-ai-employees.js +64 -0
  13. package/dist/ai/tools/sub-agents/shared.d.ts +33 -0
  14. package/dist/ai/tools/sub-agents/shared.js +169 -0
  15. package/dist/ai/tools/suggestions.js +2 -2
  16. package/dist/client/7237366e104efa7a.js +10 -0
  17. package/dist/client/748fbb87c1013c6e.js +10 -0
  18. package/dist/client/ai-employees/built-in/utils.d.ts +1 -0
  19. package/dist/client/ai-employees/chatbox/AIEmployeeSwitch.d.ts +0 -1
  20. package/dist/client/ai-employees/chatbox/hooks/useChatBoxActions.d.ts +5 -3
  21. package/dist/client/ai-employees/chatbox/roles.d.ts +1 -0
  22. package/dist/client/ai-employees/chatbox/stores/chat-messages.d.ts +8 -0
  23. package/dist/client/ai-employees/chatbox/utils.d.ts +15 -1
  24. package/dist/client/ai-employees/sub-agents/tools/index.d.ts +10 -0
  25. package/dist/client/ai-employees/sub-agents/ui/SubAgentDispatchCard.d.ts +21 -0
  26. package/dist/client/ai-employees/types.d.ts +19 -0
  27. package/dist/client/index.js +7 -7
  28. package/dist/externalVersion.js +16 -15
  29. package/dist/locale/en-US.json +10 -1
  30. package/dist/locale/zh-CN.json +10 -1
  31. package/dist/node_modules/fast-glob/package.json +1 -1
  32. package/dist/node_modules/flexsearch/package.json +1 -1
  33. package/dist/node_modules/fs-extra/package.json +1 -1
  34. package/dist/node_modules/nodejs-snowflake/package.json +1 -1
  35. package/dist/node_modules/openai/package.json +1 -1
  36. package/dist/node_modules/zod/package.json +1 -1
  37. package/dist/server/ai-employees/ai-conversations.d.ts +64 -0
  38. package/dist/server/ai-employees/ai-conversations.js +285 -0
  39. package/dist/server/ai-employees/ai-employee.d.ts +85 -9
  40. package/dist/server/ai-employees/ai-employee.js +264 -149
  41. package/dist/server/ai-employees/middleware/conversation.d.ts +2 -0
  42. package/dist/server/ai-employees/middleware/conversation.js +38 -5
  43. package/dist/server/ai-employees/middleware/tools.js +37 -10
  44. package/dist/server/ai-employees/prompts.d.ts +9 -1
  45. package/dist/server/ai-employees/prompts.js +24 -2
  46. package/dist/server/ai-employees/sub-agents/dispatcher.d.ts +36 -0
  47. package/dist/server/ai-employees/sub-agents/dispatcher.js +225 -0
  48. package/dist/server/ai-employees/sub-agents/index.d.ts +9 -0
  49. package/dist/server/ai-employees/sub-agents/index.js +36 -0
  50. package/dist/server/collections/ai-conversations.js +6 -0
  51. package/dist/server/llm-providers/anthropic.d.ts +1 -0
  52. package/dist/server/llm-providers/anthropic.js +2 -1
  53. package/dist/server/llm-providers/dashscope.d.ts +3 -0
  54. package/dist/server/llm-providers/dashscope.js +16 -2
  55. package/dist/server/llm-providers/deepseek.d.ts +1 -0
  56. package/dist/server/llm-providers/deepseek.js +5 -2
  57. package/dist/server/llm-providers/google-genai.d.ts +1 -0
  58. package/dist/server/llm-providers/google-genai.js +2 -1
  59. package/dist/server/llm-providers/kimi/provider.d.ts +1 -0
  60. package/dist/server/llm-providers/openai/responses.d.ts +1 -0
  61. package/dist/server/llm-providers/openai/responses.js +2 -1
  62. package/dist/server/llm-providers/provider.d.ts +1 -10
  63. package/dist/server/llm-providers/provider.js +3 -34
  64. package/dist/server/migrations/20260319000000-add-ai-conversations-from.d.ts +14 -0
  65. package/dist/server/migrations/20260319000000-add-ai-conversations-from.js +63 -0
  66. package/dist/server/plugin.d.ts +4 -0
  67. package/dist/server/plugin.js +4 -0
  68. package/dist/server/resource/aiConversations.d.ts +3 -3
  69. package/dist/server/resource/aiConversations.js +125 -159
  70. package/dist/server/types/ai-chat-conversation.type.d.ts +8 -2
  71. package/dist/server/types/ai-message.type.d.ts +7 -0
  72. package/dist/server/utils.d.ts +3 -0
  73. package/dist/server/utils.js +25 -1
  74. package/package.json +4 -2
  75. package/dist/client/27539a4356faebb1.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
- protocol;
70
- constructor(ctx, employee, sessionId, systemMessage, skillSettings, webSearch, model, legacy) {
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,19 @@ 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.create(ctx);
97
+ this.protocol = ChatStreamProtocol.fromContext(ctx);
98
+ }
99
+ async getFormatMessages(userMessages) {
100
+ const { provider } = await this.getLLMService();
101
+ const { messages } = await this.aiChatConversation.getChatContext({
102
+ userMessages,
103
+ formatMessages: (messages2) => this.formatMessages({ messages: messages2, provider })
104
+ });
105
+ return messages;
85
106
  }
86
107
  // === Chat flow ===
87
108
  buildState(messages) {
@@ -186,7 +207,9 @@ class AIEmployee {
186
207
  async invoke({
187
208
  messageId,
188
209
  userMessages = [],
189
- userDecisions
210
+ userDecisions,
211
+ writer,
212
+ context
190
213
  }) {
191
214
  try {
192
215
  const { provider, chatContext, config, state } = await this.buildChatContext({
@@ -194,15 +217,21 @@ class AIEmployee {
194
217
  userMessages,
195
218
  userDecisions
196
219
  });
197
- const { threadId } = await this.getCurrentThread();
198
220
  const invokeConfig = {
199
- configurable: { thread_id: threadId },
200
- context: { ctx: this.ctx },
221
+ context: { ctx: this.ctx, decisions: chatContext.decisions, ...context },
201
222
  recursionLimit: 100,
223
+ writer,
202
224
  ...config
203
225
  };
226
+ if (this.from === "main-agent") {
227
+ const { threadId } = await this.getCurrentThread();
228
+ invokeConfig.configurable = { thread_id: threadId };
229
+ }
204
230
  return await this.agentInvoke(provider, chatContext, invokeConfig, state);
205
231
  } catch (err) {
232
+ if (err.name === "GraphInterrupt") {
233
+ throw err;
234
+ }
206
235
  this.ctx.log.error(err);
207
236
  throw err;
208
237
  }
@@ -250,17 +279,24 @@ class AIEmployee {
250
279
  middleware
251
280
  }) {
252
281
  const model = provider.createModel();
253
- const toolDefinitions = (tools == null ? void 0 : tools.map(import_provider.ToolDefinition.from("ToolsEntry"))) ?? [];
254
- const allTools = provider.resolveTools(toolDefinitions);
255
- const checkpointer = new import_checkpoints.SequelizeCollectionSaver(() => this.ctx.app.mainDataSource);
256
- return (0, import_langchain.createAgent)({ model, tools: allTools, middleware, systemPrompt, checkpointer });
282
+ const allTools = provider.resolveTools((tools == null ? void 0 : tools.map(import_utils.buildTool)) ?? []);
283
+ if (this.from === "main-agent") {
284
+ const checkpointer = new import_checkpoints.SequelizeCollectionSaver(() => this.ctx.app.mainDataSource);
285
+ return (0, import_langchain.createAgent)({ model, tools: allTools, middleware, systemPrompt, checkpointer });
286
+ } else {
287
+ return (0, import_langchain.createAgent)({ model, tools: allTools, middleware, systemPrompt });
288
+ }
257
289
  }
258
290
  getAgentInput(context, state) {
259
- var _a;
260
- if ((_a = context.decisions) == null ? void 0 : _a.length) {
291
+ var _a, _b;
292
+ if ((_b = (_a = context.decisions) == null ? void 0 : _a.decisions) == null ? void 0 : _b.length) {
261
293
  return new import_langgraph.Command({
262
- resume: {
263
- decisions: context.decisions
294
+ resume: context.decisions.interruptId ? {
295
+ [context.decisions.interruptId]: {
296
+ decisions: context.decisions.decisions
297
+ }
298
+ } : {
299
+ decisions: context.decisions.decisions
264
300
  }
265
301
  });
266
302
  }
@@ -273,13 +309,16 @@ class AIEmployee {
273
309
  const { systemPrompt, tools, middleware } = context;
274
310
  const agent = await this.createAgent({ provider, systemPrompt, tools, middleware });
275
311
  const input = this.getAgentInput(context, state);
276
- return agent.stream(input, config);
312
+ if (this.from === "sub-agent") {
313
+ delete config.configurable;
314
+ }
315
+ return agent.stream(input, this.withRunMetadata(config));
277
316
  }
278
317
  async agentInvoke(provider, context, config, state) {
279
318
  const { systemPrompt, tools, middleware } = context;
280
319
  const agent = await this.createAgent({ provider, systemPrompt, tools, middleware });
281
320
  const input = this.getAgentInput(context, state);
282
- return agent.invoke(input, config);
321
+ return agent.invoke(input, this.withRunMetadata(config));
283
322
  }
284
323
  async prepareChatStream({
285
324
  chatContext,
@@ -297,8 +336,8 @@ class AIEmployee {
297
336
  {
298
337
  signal,
299
338
  streamMode: ["updates", "messages", "custom"],
300
- configurable: { thread_id: threadId },
301
- context: { ctx: this.ctx },
339
+ configurable: this.from === "main-agent" ? { thread_id: threadId } : void 0,
340
+ context: { ctx: this.ctx, decisions: chatContext.decisions },
302
341
  recursionLimit: 100,
303
342
  ...config
304
343
  },
@@ -311,8 +350,8 @@ class AIEmployee {
311
350
  }
312
351
  }
313
352
  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
- let toolCalls;
353
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
354
+ const aiMessageIdMap = /* @__PURE__ */ new Map();
316
355
  const { signal, providerName, model, provider, responseMetadata, allowEmpty = false } = options;
317
356
  let isReasoning = false;
318
357
  let gathered;
@@ -329,58 +368,69 @@ class AIEmployee {
329
368
  }
330
369
  await this.aiChatConversation.withTransaction(async (conversation, transaction) => {
331
370
  const result = await conversation.addMessages(values);
332
- if (toolCalls == null ? void 0 : toolCalls.length) {
333
- await this.initToolCall(transaction, result.messageId, toolCalls);
334
- }
335
371
  });
336
372
  }
337
373
  });
338
374
  try {
339
- this.protocol.startStream();
375
+ const aiEmployeeConversation = {
376
+ sessionId: this.sessionId,
377
+ from: this.from,
378
+ username: this.employee.username
379
+ };
380
+ this.protocol.with(aiEmployeeConversation).startStream();
340
381
  for await (const [mode, chunks] of stream) {
341
382
  if (mode === "messages") {
342
- const [chunk] = chunks;
383
+ const [chunk, metadata] = chunks;
384
+ const { currentConversation } = metadata;
343
385
  if (chunk.type === "ai") {
344
386
  gathered = gathered !== void 0 ? (0, import_stream.concat)(gathered, chunk) : chunk;
345
387
  if (chunk.content) {
346
388
  if (isReasoning) {
347
389
  isReasoning = false;
348
- this.protocol.stopReasoning();
390
+ this.protocol.with(currentConversation).stopReasoning();
349
391
  }
350
392
  const parsedContent = provider.parseResponseChunk(chunk.content);
351
393
  if (parsedContent) {
352
- this.protocol.content(parsedContent);
394
+ this.protocol.with(currentConversation).content(parsedContent);
353
395
  }
354
396
  }
355
397
  if ((_a = chunk.tool_call_chunks) == null ? void 0 : _a.length) {
356
- this.protocol.toolCallChunks(chunk.tool_call_chunks);
398
+ this.protocol.with(currentConversation).toolCallChunks(chunk.tool_call_chunks);
357
399
  }
358
400
  const webSearch = provider.parseWebSearchAction(chunk);
359
401
  if (webSearch == null ? void 0 : webSearch.length) {
360
- this.protocol.webSearch(webSearch);
402
+ this.protocol.with(currentConversation).webSearch(webSearch);
361
403
  }
362
404
  const reasoningContent = provider.parseReasoningContent(chunk);
363
405
  if (reasoningContent) {
364
406
  isReasoning = true;
365
- this.protocol.reasoning(reasoningContent);
407
+ this.protocol.with(currentConversation).reasoning(reasoningContent);
366
408
  }
367
409
  }
368
410
  } else if (mode === "updates") {
369
411
  if ("__interrupt__" in chunks) {
412
+ const interruptId = chunks.__interrupt__[0].id;
370
413
  const interruptActions = this.toInterruptActions(chunks.__interrupt__[0].value);
371
414
  if (interruptActions.size) {
372
- for (const toolCall of toolCalls ?? []) {
373
- const interruptAction = interruptActions.get(toolCall.name);
374
- if (!interruptAction) {
415
+ const toolsMap = await this.getToolsMap();
416
+ for (const interruptAction of interruptActions.values()) {
417
+ if (!interruptAction.currentConversation || !interruptAction.toolCall) {
418
+ this.logger.warn("currentConversation or toolCall not exist in __interrupt__", interruptAction);
419
+ continue;
420
+ }
421
+ const { sessionId, from, username } = interruptAction.currentConversation;
422
+ const { id: toolCallId, name: toolCallName } = interruptAction.toolCall;
423
+ const messageId = aiMessageIdMap.get(sessionId);
424
+ if (!messageId) {
375
425
  continue;
376
426
  }
377
- await this.updateToolCallInterrupted(toolCall.messageId, toolCall.id, interruptAction);
378
- this.protocol.toolCallStatus({
427
+ await this.updateToolCallInterrupted(sessionId, messageId, toolCallId, interruptId, interruptAction);
428
+ this.protocol.with(interruptAction.currentConversation).toolCallStatus({
379
429
  toolCall: {
380
- messageId: toolCall.messageId,
381
- id: toolCall.id,
382
- name: toolCall.name,
383
- willInterrupt: toolCall.willInterrupt
430
+ messageId,
431
+ id: toolCallId,
432
+ name: toolCallName,
433
+ willInterrupt: this.shouldInterruptToolCall(toolsMap.get(toolCallName))
384
434
  },
385
435
  invokeStatus: "interrupted",
386
436
  interruptAction
@@ -389,7 +439,9 @@ class AIEmployee {
389
439
  }
390
440
  }
391
441
  } else if (mode === "custom") {
442
+ const { currentConversation } = chunks;
392
443
  if (chunks.action === "AfterAIMessageSaved") {
444
+ aiMessageIdMap.set(currentConversation.sessionId, chunks.body.messageId);
393
445
  const data = responseMetadata.get(chunks.body.id);
394
446
  if (data) {
395
447
  const savedMessage = await this.aiMessagesModel.findOne({
@@ -417,32 +469,31 @@ class AIEmployee {
417
469
  }
418
470
  }
419
471
  } else if (chunks.action === "initToolCalls") {
420
- toolCalls = ((_b = chunks.body) == null ? void 0 : _b.toolCalls) ?? [];
421
- this.protocol.toolCalls(chunks.body);
472
+ this.protocol.with(currentConversation).toolCalls(chunks.body);
422
473
  } else if (chunks.action === "beforeToolCall") {
423
474
  const toolsMap = await this.getToolsMap();
424
- const willInterrupt = this.shouldInterruptToolCall(toolsMap.get((_d = (_c = chunks.body) == null ? void 0 : _c.toolCall) == null ? void 0 : _d.name));
425
- this.protocol.toolCallStatus({
475
+ const willInterrupt = this.shouldInterruptToolCall(toolsMap.get((_c = (_b = chunks.body) == null ? void 0 : _b.toolCall) == null ? void 0 : _c.name));
476
+ this.protocol.with(currentConversation).toolCallStatus({
426
477
  toolCall: {
427
- messageId: (_f = (_e = chunks.body) == null ? void 0 : _e.toolCall) == null ? void 0 : _f.messageId,
428
- id: (_h = (_g = chunks.body) == null ? void 0 : _g.toolCall) == null ? void 0 : _h.id,
429
- name: (_j = (_i = chunks.body) == null ? void 0 : _i.toolCall) == null ? void 0 : _j.name,
478
+ messageId: (_e = (_d = chunks.body) == null ? void 0 : _d.toolCall) == null ? void 0 : _e.messageId,
479
+ id: (_g = (_f = chunks.body) == null ? void 0 : _f.toolCall) == null ? void 0 : _g.id,
480
+ name: (_i = (_h = chunks.body) == null ? void 0 : _h.toolCall) == null ? void 0 : _i.name,
430
481
  willInterrupt
431
482
  },
432
483
  invokeStatus: "pending"
433
484
  });
434
485
  } else if (chunks.action === "afterToolCall") {
435
486
  const toolsMap = await this.getToolsMap();
436
- const willInterrupt = this.shouldInterruptToolCall(toolsMap.get((_l = (_k = chunks.body) == null ? void 0 : _k.toolCall) == null ? void 0 : _l.name));
437
- this.protocol.toolCallStatus({
487
+ const willInterrupt = this.shouldInterruptToolCall(toolsMap.get((_k = (_j = chunks.body) == null ? void 0 : _j.toolCall) == null ? void 0 : _k.name));
488
+ this.protocol.with(currentConversation).toolCallStatus({
438
489
  toolCall: {
439
- messageId: (_n = (_m = chunks.body) == null ? void 0 : _m.toolCall) == null ? void 0 : _n.messageId,
440
- id: (_p = (_o = chunks.body) == null ? void 0 : _o.toolCall) == null ? void 0 : _p.id,
441
- name: (_r = (_q = chunks.body) == null ? void 0 : _q.toolCall) == null ? void 0 : _r.name,
490
+ messageId: (_m = (_l = chunks.body) == null ? void 0 : _l.toolCall) == null ? void 0 : _m.messageId,
491
+ id: (_o = (_n = chunks.body) == null ? void 0 : _n.toolCall) == null ? void 0 : _o.id,
492
+ name: (_q = (_p = chunks.body) == null ? void 0 : _p.toolCall) == null ? void 0 : _q.name,
442
493
  willInterrupt
443
494
  },
444
495
  invokeStatus: "done",
445
- status: (_t = (_s = chunks.body) == null ? void 0 : _s.toolCallResult) == null ? void 0 : _t.status
496
+ status: (_s = (_r = chunks.body) == null ? void 0 : _r.toolCallResult) == null ? void 0 : _s.status
446
497
  });
447
498
  } else if (chunks.action === "beforeSendToolMessage") {
448
499
  const { messageId, messages } = chunks.body ?? {};
@@ -455,7 +506,7 @@ class AIEmployee {
455
506
  for (const { metadata } of messages) {
456
507
  const tools = toolsMap.get(metadata.toolName);
457
508
  const toolCallResult = toolCallResultMap.get(metadata.toolCallId);
458
- this.protocol.toolCallStatus({
509
+ this.protocol.with(currentConversation).toolCallStatus({
459
510
  toolCall: {
460
511
  messageId,
461
512
  id: metadata.toolCallId,
@@ -467,7 +518,9 @@ class AIEmployee {
467
518
  });
468
519
  }
469
520
  }
470
- this.protocol.newMessage();
521
+ this.protocol.with(currentConversation).newMessage();
522
+ } else if (chunks.action === "afterSubAgentInvoke") {
523
+ this.protocol.with(currentConversation).subAgentCompleted();
471
524
  }
472
525
  }
473
526
  }
@@ -475,7 +528,7 @@ class AIEmployee {
475
528
  this.sendErrorResponse("Empty message");
476
529
  return;
477
530
  }
478
- this.protocol.endStream();
531
+ this.protocol.with(aiEmployeeConversation).endStream();
479
532
  } catch (err) {
480
533
  this.ctx.log.error(err);
481
534
  if (err.name === "GraphRecursionError") {
@@ -484,7 +537,9 @@ class AIEmployee {
484
537
  this.sendErrorResponse(provider.parseResponseError(err));
485
538
  }
486
539
  } finally {
487
- this.ctx.res.end();
540
+ if (this.from === "main-agent") {
541
+ this.ctx.res.end();
542
+ }
488
543
  }
489
544
  }
490
545
  // === Prompts & knowledge base ===
@@ -566,6 +621,7 @@ ${workContextBackground.join("\n")}`;
566
621
  }
567
622
  }
568
623
  const availableSkills = await this.getAvailableSkills();
624
+ const availableAIEmployees = await this.getAvailableAIEmployees();
569
625
  const systemPrompt = (0, import_prompts.getSystemPrompt)({
570
626
  aiEmployee: {
571
627
  nickname: this.employee.nickname,
@@ -581,7 +637,8 @@ ${workContextBackground.join("\n")}`;
581
637
  locale: this.ctx.getCurrentLocale() || "en-US"
582
638
  },
583
639
  knowledgeBase,
584
- availableSkills
640
+ availableSkills,
641
+ availableAIEmployees
585
642
  });
586
643
  const { important } = this.ctx.action.params.values || {};
587
644
  if (important === "GraphRecursionError") {
@@ -706,23 +763,54 @@ If information is missing, clearly state it in the summary.</Important>`;
706
763
  transaction
707
764
  });
708
765
  }
709
- async updateToolCallInterrupted(messageId, toolCallId, interruptAction) {
710
- const [updated] = await this.aiToolMessagesModel.update(
711
- {
712
- invokeStatus: "interrupted",
713
- interruptActionOrder: interruptAction.order,
714
- interruptAction
715
- },
716
- {
766
+ async updateToolCallInterrupted(sessionId, messageId, toolCallId, interruptId, interruptAction) {
767
+ return await this.db.sequelize.transaction(async (transaction) => {
768
+ const [updated] = await this.aiToolMessagesModel.update(
769
+ {
770
+ invokeStatus: "interrupted",
771
+ interruptActionOrder: interruptAction.order,
772
+ interruptAction
773
+ },
774
+ {
775
+ where: {
776
+ sessionId,
777
+ messageId,
778
+ toolCallId,
779
+ invokeStatus: "init"
780
+ },
781
+ transaction
782
+ }
783
+ );
784
+ if (!updated) {
785
+ return updated;
786
+ }
787
+ const message = await this.aiMessagesModel.findOne({
717
788
  where: {
718
- sessionId: this.sessionId,
719
789
  messageId,
720
- toolCallId,
721
- invokeStatus: "init"
722
- }
790
+ sessionId
791
+ },
792
+ transaction
793
+ });
794
+ if (!message) {
795
+ return updated;
723
796
  }
724
- );
725
- return updated;
797
+ await this.aiMessagesModel.update(
798
+ {
799
+ metadata: {
800
+ ...message.get("metadata") ?? {},
801
+ interruptId
802
+ }
803
+ },
804
+ {
805
+ where: {
806
+ messageId,
807
+ sessionId
808
+ },
809
+ transaction
810
+ }
811
+ );
812
+ return updated;
813
+ });
726
814
  }
727
815
  async updateToolCallPending(messageId, toolCallId) {
728
816
  const [updated] = await this.aiToolMessagesModel.update(
@@ -784,7 +872,6 @@ If information is missing, clearly state it in the summary.</Important>`;
784
872
  var _a;
785
873
  return (_a = await this.aiToolMessagesModel.findOne({
786
874
  where: {
787
- sessionId: this.sessionId,
788
875
  messageId,
789
876
  toolCallId
790
877
  }
@@ -793,7 +880,6 @@ If information is missing, clearly state it in the summary.</Important>`;
793
880
  async getToolCallResultMap(messageId, toolCallIds) {
794
881
  const list = (await this.aiToolMessagesModel.findAll({
795
882
  where: {
796
- sessionId: this.sessionId,
797
883
  messageId,
798
884
  toolCallId: {
799
885
  [import_database.Op.in]: toolCallIds
@@ -802,19 +888,6 @@ If information is missing, clearly state it in the summary.</Important>`;
802
888
  })).map((it) => it.toJSON());
803
889
  return new Map(list.map((it) => [it.toolCallId, it]));
804
890
  }
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
891
  async cancelToolCall() {
819
892
  var _a;
820
893
  let messageId;
@@ -829,7 +902,6 @@ If information is missing, clearly state it in the summary.</Important>`;
829
902
  }
830
903
  const toolMessages = (await this.aiToolMessagesModel.findAll({
831
904
  where: {
832
- sessionId: this.sessionId,
833
905
  messageId,
834
906
  invokeStatus: {
835
907
  [import_database.Op.ne]: "confirmed"
@@ -1068,10 +1140,20 @@ If information is missing, clearly state it in the summary.</Important>`;
1068
1140
  const actionRequestsMap = new Map(actionRequests.map((x) => [x.name, x]));
1069
1141
  const reviewConfigsMap = new Map(reviewConfigs.map((x) => [x.actionName, x]));
1070
1142
  for (const [name, actionRequest] of actionRequestsMap.entries()) {
1143
+ const payload = actionRequest.description ? JSON.parse(actionRequest.description) : null;
1071
1144
  result.set(name, {
1072
1145
  order: order++,
1073
1146
  description: actionRequest.description,
1074
- allowedDecisions: (_a = reviewConfigsMap.get(name)) == null ? void 0 : _a.allowedDecisions
1147
+ allowedDecisions: (_a = reviewConfigsMap.get(name)) == null ? void 0 : _a.allowedDecisions,
1148
+ toolCall: {
1149
+ id: payload.toolCallId,
1150
+ name: payload.toolCallName
1151
+ },
1152
+ currentConversation: {
1153
+ sessionId: payload.sessionId,
1154
+ from: payload.from,
1155
+ username: payload.username
1156
+ }
1075
1157
  });
1076
1158
  }
1077
1159
  return result;
@@ -1098,11 +1180,16 @@ If information is missing, clearly state it in the summary.</Important>`;
1098
1180
  async getAvailableSkills() {
1099
1181
  var _a, _b;
1100
1182
  const { skillsManager } = this.plugin.ai;
1183
+ const aIEmployeeTools = await this.getAIEmployeeTools();
1184
+ const getSkill = aIEmployeeTools.find((it) => it.definition.name === "getSkill");
1185
+ if (!getSkill) {
1186
+ return [];
1187
+ }
1101
1188
  const generalSkills = await skillsManager.listSkills({ scope: "GENERAL" });
1102
1189
  const specifiedSkillNames = ((_a = this.employee.skillSettings) == null ? void 0 : _a.skills) ?? [];
1103
1190
  const specifiedSkills = specifiedSkillNames.length ? await skillsManager.getSkills(specifiedSkillNames) : [];
1104
1191
  const skillFilter = ((_b = this.skillSettings) == null ? void 0 : _b.skills) ?? [];
1105
- return import_lodash.default.uniqBy([...generalSkills || [], ...specifiedSkills || []], "name").filter(
1192
+ return import_lodash.default.uniqBy([...specifiedSkills || [], ...generalSkills || []], "name").filter(
1106
1193
  (it) => skillFilter.length === 0 || skillFilter.includes(it.name)
1107
1194
  );
1108
1195
  }
@@ -1167,6 +1254,12 @@ If information is missing, clearly state it in the summary.</Important>`;
1167
1254
  }
1168
1255
  return result;
1169
1256
  }
1257
+ async getAvailableAIEmployees() {
1258
+ const availableAIEmployees = (await (0, import_shared.listAccessibleAIEmployees)(this.ctx)).map(
1259
+ (employee) => (0, import_shared.serializeEmployeeSummary)(this.ctx, employee)
1260
+ );
1261
+ return availableAIEmployees;
1262
+ }
1170
1263
  getMiddleware(options) {
1171
1264
  const { providerName, model, tools, baseToolNames, messageId, agentThread } = options;
1172
1265
  return [
@@ -1206,6 +1299,19 @@ If information is missing, clearly state it in the summary.</Important>`;
1206
1299
  listTools(filter) {
1207
1300
  return this.toolsManager.listTools(filter);
1208
1301
  }
1302
+ withRunMetadata(config) {
1303
+ return {
1304
+ ...config,
1305
+ metadata: {
1306
+ ...(config == null ? void 0 : config.metadata) ?? {},
1307
+ currentConversation: {
1308
+ sessionId: this.sessionId,
1309
+ from: this.from,
1310
+ username: this.employee.get("username")
1311
+ }
1312
+ }
1313
+ };
1314
+ }
1209
1315
  get toolsManager() {
1210
1316
  return this.ctx.app.aiManager.toolsManager;
1211
1317
  }
@@ -1250,8 +1356,8 @@ class AgentThread {
1250
1356
  }
1251
1357
  }
1252
1358
  class ChatStreamProtocol {
1253
- constructor(ctx) {
1254
- this.ctx = ctx;
1359
+ constructor(streamConsumer) {
1360
+ this.streamConsumer = streamConsumer;
1255
1361
  }
1256
1362
  _statistics = {
1257
1363
  sent: 0,
@@ -1262,71 +1368,79 @@ class ChatStreamProtocol {
1262
1368
  this._statistics.sent = 0;
1263
1369
  }
1264
1370
  };
1265
- static create(ctx) {
1266
- return new ChatStreamProtocol(ctx);
1371
+ static fromContext(ctx) {
1372
+ return new ChatStreamProtocol(ctx.res);
1267
1373
  }
1268
- startStream() {
1269
- this._statistics.reset();
1270
- this.write({ type: "stream_start" });
1271
- }
1272
- endStream() {
1273
- this.write({ type: "stream_end" });
1274
- }
1275
- newMessage(content) {
1276
- this.write({ type: "new_message", body: content });
1277
- }
1278
- content(content) {
1279
- this.write({ type: "content", body: content });
1280
- }
1281
- webSearch(content) {
1282
- this.write({ type: "web_search", body: content });
1283
- }
1284
- reasoning(content) {
1285
- this.write({ type: "reasoning", body: content });
1286
- }
1287
- stopReasoning() {
1288
- this.write({
1289
- type: "reasoning",
1290
- body: {
1291
- status: "stop",
1292
- content: ""
1293
- }
1294
- });
1295
- }
1296
- toolCallChunks(content) {
1297
- this.write({ type: "tool_call_chunks", body: content });
1298
- }
1299
- toolCalls(content) {
1300
- this.write({ type: "tool_calls", body: content });
1301
- }
1302
- toolCallStatus({
1303
- toolCall,
1304
- invokeStatus,
1305
- status,
1306
- interruptAction
1307
- }) {
1308
- this.write({
1309
- type: "tool_call_status",
1310
- body: {
1374
+ with(conversation) {
1375
+ const write = ({ type, body }) => {
1376
+ const { sessionId, from, username } = conversation;
1377
+ const data = `data: ${JSON.stringify({ sessionId, from, username, type, body })}
1378
+
1379
+ `;
1380
+ this.streamConsumer.write(data);
1381
+ this._statistics.addSent(data.length);
1382
+ };
1383
+ return {
1384
+ startStream: () => {
1385
+ this._statistics.reset();
1386
+ write({ type: "stream_start" });
1387
+ },
1388
+ endStream: () => {
1389
+ write({ type: "stream_end" });
1390
+ },
1391
+ subAgentCompleted: () => {
1392
+ write({ type: "sub_agent_completed" });
1393
+ },
1394
+ newMessage: (content) => {
1395
+ write({ type: "new_message", body: content });
1396
+ },
1397
+ content: (content) => {
1398
+ write({ type: "content", body: content });
1399
+ },
1400
+ webSearch: (content) => {
1401
+ write({ type: "web_search", body: content });
1402
+ },
1403
+ reasoning: (content) => {
1404
+ write({ type: "reasoning", body: content });
1405
+ },
1406
+ stopReasoning: () => {
1407
+ write({
1408
+ type: "reasoning",
1409
+ body: {
1410
+ status: "stop",
1411
+ content: ""
1412
+ }
1413
+ });
1414
+ },
1415
+ toolCallChunks: (content) => {
1416
+ write({ type: "tool_call_chunks", body: content });
1417
+ },
1418
+ toolCalls: (content) => {
1419
+ write({ type: "tool_calls", body: content });
1420
+ },
1421
+ toolCallStatus: ({
1311
1422
  toolCall,
1312
1423
  invokeStatus,
1313
1424
  status,
1314
1425
  interruptAction
1426
+ }) => {
1427
+ write({
1428
+ type: "tool_call_status",
1429
+ body: {
1430
+ toolCall,
1431
+ invokeStatus,
1432
+ status,
1433
+ interruptAction
1434
+ }
1435
+ });
1315
1436
  }
1316
- });
1437
+ };
1317
1438
  }
1318
1439
  get statistics() {
1319
1440
  return {
1320
1441
  sent: this._statistics.sent
1321
1442
  };
1322
1443
  }
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
1444
  }
1331
1445
  class ResponseMetadataCollector extends import_base.BaseCallbackHandler {
1332
1446
  constructor(llmProvider, responseMetadata) {
@@ -1347,5 +1461,6 @@ class ResponseMetadataCollector extends import_base.BaseCallbackHandler {
1347
1461
  }
1348
1462
  // Annotate the CommonJS export names for ESM import in node:
1349
1463
  0 && (module.exports = {
1350
- AIEmployee
1464
+ AIEmployee,
1465
+ ChatStreamProtocol
1351
1466
  });