@nocobase/plugin-ai 2.1.0-alpha.12 → 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
@@ -26,6 +26,8 @@ export declare const conversationMiddleware: (aiEmployee: AIEmployee, options: {
26
26
  }, z.core.$strip>>;
27
27
  }, z.core.$strip>, z.ZodObject<{
28
28
  ctx: z.ZodAny;
29
+ appendMessage: z.ZodAny;
29
30
  }, z.core.$strip>, {
30
31
  ctx: any;
32
+ appendMessage: any;
31
33
  }, readonly (import("@langchain/core/dist/tools").ClientTool | import("@langchain/core/dist/tools").ServerTool)[]>;
@@ -77,7 +77,8 @@ const conversationMiddleware = (aiEmployee, options) => {
77
77
  return (0, import_langchain.createMiddleware)({
78
78
  name: "ConversationMiddleware",
79
79
  contextSchema: import_zod.default.object({
80
- ctx: import_zod.default.any()
80
+ ctx: import_zod.default.any(),
81
+ appendMessage: import_zod.default.any()
81
82
  }),
82
83
  stateSchema: import_zod.default.object({
83
84
  messageId: import_zod.default.coerce.string().optional(),
@@ -125,13 +126,28 @@ const conversationMiddleware = (aiEmployee, options) => {
125
126
  toolMessages.map((x) => x.metadata.toolCallId)
126
127
  );
127
128
  });
128
- (_a = runtime.writer) == null ? void 0 : _a.call(runtime, { action: "beforeSendToolMessage", body: { messageId: messageId2, messages: toolMessages } });
129
+ const currentConversation = {
130
+ sessionId: aiEmployee.sessionId,
131
+ username: aiEmployee.employee.username,
132
+ from: aiEmployee.from
133
+ };
134
+ (_a = runtime.writer) == null ? void 0 : _a.call(runtime, {
135
+ action: "beforeSendToolMessage",
136
+ body: { messageId: messageId2, messages: toolMessages },
137
+ currentConversation
138
+ });
129
139
  }
130
140
  },
131
141
  afterModel: async (state, runtime) => {
132
142
  var _a, _b, _c, _d, _e, _f;
133
143
  try {
144
+ const currentConversation = {
145
+ sessionId: aiEmployee.sessionId,
146
+ username: aiEmployee.employee.username,
147
+ from: aiEmployee.from
148
+ };
134
149
  const newState = {
150
+ messageId: state.messageId,
135
151
  lastMessageIndex: {
136
152
  lastHumanMessageIndex: state.messages.filter((x) => x.type === "human").length,
137
153
  lastAIMessageIndex: state.messages.filter((x) => x.type === "ai").length,
@@ -153,7 +169,7 @@ const conversationMiddleware = (aiEmployee, options) => {
153
169
  if (values) {
154
170
  await aiEmployee.aiChatConversation.withTransaction(async (conversation, transaction) => {
155
171
  const result = await conversation.addMessages(values);
156
- state.messageId = result.messageId;
172
+ newState.messageId = result.messageId;
157
173
  if (toolCalls == null ? void 0 : toolCalls.length) {
158
174
  const toolsMap = await aiEmployee.getToolsMap();
159
175
  const initializedToolCalls = await aiEmployee.initToolCall(
@@ -166,19 +182,36 @@ const conversationMiddleware = (aiEmployee, options) => {
166
182
  });
167
183
  (_b = runtime.writer) == null ? void 0 : _b.call(runtime, {
168
184
  action: "AfterAIMessageSaved",
169
- body: { id: aiMessage.id, messageId: state.messageId }
185
+ body: { id: aiMessage.id, messageId: newState.messageId },
186
+ currentConversation
170
187
  });
171
188
  }
172
189
  if (toolCalls == null ? void 0 : toolCalls.length) {
173
190
  (_c = runtime.writer) == null ? void 0 : _c.call(runtime, {
174
191
  action: "initToolCalls",
175
- body: { toolCalls }
192
+ body: { toolCalls },
193
+ currentConversation
176
194
  });
177
195
  }
178
196
  return newState;
179
197
  } catch (e) {
180
198
  (_f = (_e = (_d = runtime.context) == null ? void 0 : _d.ctx) == null ? void 0 : _e.logger) == null ? void 0 : _f.error(e);
181
199
  }
200
+ },
201
+ wrapModelCall: async (request, handler) => {
202
+ const runtimeContext = request.runtime.context;
203
+ const appendMessage = runtimeContext == null ? void 0 : runtimeContext.appendMessage;
204
+ if (Array.isArray(appendMessage) && appendMessage.length) {
205
+ await aiEmployee.aiChatConversation.withTransaction(async (conversation) => {
206
+ await conversation.addMessages(convertToolMessage(request.messages.at(-1)));
207
+ await conversation.addMessages(appendMessage.map((x) => x).map(convertHumanMessage));
208
+ });
209
+ request.messages.push(...appendMessage);
210
+ if (runtimeContext) {
211
+ delete runtimeContext.appendMessage;
212
+ }
213
+ }
214
+ return handler(request);
182
215
  }
183
216
  });
184
217
  };
@@ -46,7 +46,16 @@ var import_lodash = __toESM(require("lodash"));
46
46
  const toolInteractionMiddleware = (aiEmployee, tools) => {
47
47
  const interruptOn = {};
48
48
  for (const tool of tools) {
49
- interruptOn[tool.definition.name] = aiEmployee.shouldInterruptToolCall(tool);
49
+ interruptOn[tool.definition.name] = aiEmployee.shouldInterruptToolCall(tool) ? {
50
+ allowedDecisions: ["approve", "reject", "edit"],
51
+ description: (toolCall) => JSON.stringify({
52
+ sessionId: aiEmployee.sessionId,
53
+ from: aiEmployee.from,
54
+ username: aiEmployee.employee.username,
55
+ toolCallId: toolCall.id,
56
+ toolCallName: toolCall.name
57
+ })
58
+ } : false;
50
59
  }
51
60
  return (0, import_langchain.humanInTheLoopMiddleware)({
52
61
  interruptOn
@@ -60,13 +69,23 @@ const toolCallStatusMiddleware = (aiEmployee) => {
60
69
  }),
61
70
  wrapToolCall: async (request, handler) => {
62
71
  var _a, _b, _c, _d;
72
+ let interrupted = false;
63
73
  const { runtime, toolCall } = request;
64
74
  const { messageId } = request.state;
75
+ const currentConversation = {
76
+ sessionId: aiEmployee.sessionId,
77
+ username: aiEmployee.employee.username,
78
+ from: aiEmployee.from
79
+ };
65
80
  const tm = await aiEmployee.getToolCallResult(messageId, request.toolCall.id);
81
+ if (!tm) {
82
+ throw new Error(`Tool call result not found for messageId=${messageId}, toolCallId=${request.toolCall.id}`);
83
+ }
66
84
  if (tm.status === "error") {
67
85
  (_a = runtime.writer) == null ? void 0 : _a.call(runtime, {
68
86
  action: "afterToolCall",
69
- body: { toolCall, toolCallResult: tm }
87
+ body: { toolCall, toolCallResult: tm },
88
+ currentConversation
70
89
  });
71
90
  return new import_langchain.ToolMessage({
72
91
  tool_call_id: request.toolCall.id,
@@ -78,7 +97,7 @@ const toolCallStatusMiddleware = (aiEmployee) => {
78
97
  });
79
98
  }
80
99
  await aiEmployee.updateToolCallPending(messageId, request.toolCall.id);
81
- (_b = runtime.writer) == null ? void 0 : _b.call(runtime, { action: "beforeToolCall", body: { toolCall } });
100
+ (_b = runtime.writer) == null ? void 0 : _b.call(runtime, { action: "beforeToolCall", body: { toolCall }, currentConversation });
82
101
  let result;
83
102
  try {
84
103
  const toolMessage = await handler(request);
@@ -100,11 +119,16 @@ const toolCallStatusMiddleware = (aiEmployee) => {
100
119
  }
101
120
  return toolMessage;
102
121
  } catch (e) {
122
+ if (e.name === "GraphInterrupt") {
123
+ interrupted = true;
124
+ throw e;
125
+ }
103
126
  aiEmployee.logger.error(e);
104
127
  result = { status: "error", content: e.message };
105
128
  (_c = runtime.writer) == null ? void 0 : _c.call(runtime, {
106
129
  action: "afterToolCallError",
107
- body: { toolCall, error: e }
130
+ body: { toolCall, error: e },
131
+ currentConversation
108
132
  });
109
133
  return new import_langchain.ToolMessage({
110
134
  tool_call_id: request.toolCall.id,
@@ -115,12 +139,15 @@ const toolCallStatusMiddleware = (aiEmployee) => {
115
139
  }
116
140
  });
117
141
  } finally {
118
- await aiEmployee.updateToolCallDone(messageId, request.toolCall.id, result);
119
- const toolCallResult = await aiEmployee.getToolCallResult(messageId, request.toolCall.id);
120
- (_d = runtime.writer) == null ? void 0 : _d.call(runtime, {
121
- action: "afterToolCall",
122
- body: { toolCall, toolCallResult }
123
- });
142
+ if (!interrupted) {
143
+ await aiEmployee.updateToolCallDone(messageId, request.toolCall.id, result);
144
+ const toolCallResult = await aiEmployee.getToolCallResult(messageId, request.toolCall.id);
145
+ (_d = runtime.writer) == null ? void 0 : _d.call(runtime, {
146
+ action: "afterToolCall",
147
+ body: { toolCall, toolCallResult },
148
+ currentConversation
149
+ });
150
+ }
124
151
  }
125
152
  }
126
153
  });
@@ -6,7 +6,7 @@
6
6
  * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
- export declare function getSystemPrompt({ aiEmployee, personal, task, environment, dataSources, knowledgeBase, availableSkills, }: {
9
+ export declare function getSystemPrompt({ aiEmployee, personal, task, environment, dataSources, knowledgeBase, availableSkills, availableAIEmployees, }: {
10
10
  aiEmployee: {
11
11
  nickname: string;
12
12
  about: string;
@@ -27,4 +27,12 @@ export declare function getSystemPrompt({ aiEmployee, personal, task, environmen
27
27
  description: string;
28
28
  content?: string;
29
29
  }[];
30
+ availableAIEmployees?: {
31
+ username: string;
32
+ nickname: string;
33
+ position: string;
34
+ bio: string;
35
+ greeting: string;
36
+ skillSettings: any;
37
+ }[];
30
38
  }): string;
@@ -36,7 +36,8 @@ function getSystemPrompt({
36
36
  environment,
37
37
  dataSources,
38
38
  knowledgeBase,
39
- availableSkills
39
+ availableSkills,
40
+ availableAIEmployees
40
41
  }) {
41
42
  const getDatabaseQuotingRules = () => {
42
43
  const quotingMap = {
@@ -138,12 +139,33 @@ ${task.context}
138
139
  </environment>
139
140
 
140
141
  ${(availableSkills == null ? void 0 : availableSkills.length) ? `<skills>
141
- You have access to the following skills (tools groups). When a user's request matches a skill's description, use the getSkill tool to load that skill's detailed content and available tools:
142
+ You have access to the following skills (tools groups). When a user's request matches a skill's description, use the **getSkill** tool to load that skill's detailed content and available tools
142
143
 
143
144
  ${availableSkills.map((skill) => `- **${skill.name}**: ${skill.description || "No description"}`).join("\n")}
144
145
  </skills>
145
146
  ` : ""}
146
147
 
148
+ ${(availableAIEmployees == null ? void 0 : availableAIEmployees.length) ? `<sub_agents>
149
+ The following ${availableAIEmployees.length} AI employees are currently available as sub agents.
150
+ Treat this list as the authoritative routing roster for this conversation.
151
+ Do not call discovery tools just to confirm the same list again.
152
+ Only use discovery when this section is missing, clearly insufficient for the routing decision, contradictory to the current conversation, or you have strong evidence the roster has changed.
153
+ If one listed employee is already an obvious fit, dispatch directly.
154
+ Use profile lookup only when you need deeper instructions before dispatching.
155
+
156
+ ${availableAIEmployees.map(
157
+ (it) => {
158
+ var _a, _b, _c, _d, _e, _f;
159
+ return `- ${it.nickname}
160
+ - username: ${it.username}
161
+ - description: ${it.bio}
162
+ - position: ${it.position}
163
+ ${((_b = (_a = it.skillSettings) == null ? void 0 : _a.skills) == null ? void 0 : _b.length) ? "- skills:" + ((_c = it.skillSettings) == null ? void 0 : _c.skills.join(",")) : ""}
164
+ ${((_e = (_d = it.skillSettings) == null ? void 0 : _d.tools) == null ? void 0 : _e.length) ? "- tools:" + ((_f = it.skillSettings) == null ? void 0 : _f.tools.map((t) => t.name).join(",")) : ""}`;
165
+ }
166
+ )}
167
+ </sub_agents>` : ""}
168
+
147
169
  ${knowledgeBase ? `<knowledgeBase>${knowledgeBase}</knowledgeBase>` : ""}
148
170
  `;
149
171
  }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+ import { Context } from '@nocobase/actions';
10
+ import { Model } from '@nocobase/database';
11
+ import { ModelRef } from '../ai-employee';
12
+ import type PluginAIServer from '../../plugin';
13
+ import type { UserDecision } from '../../types';
14
+ export type SubAgentTask = {
15
+ ctx: Context;
16
+ sessionId: string;
17
+ employee: Model;
18
+ model: ModelRef;
19
+ question: string;
20
+ skillSettings?: Record<string, any>;
21
+ writer?: (chunk: any) => void;
22
+ };
23
+ export declare class SubAgentsDispatcher {
24
+ protected plugin: PluginAIServer;
25
+ constructor(plugin: PluginAIServer);
26
+ private extractTextContent;
27
+ private extractLastMessageText;
28
+ private resolveSubAgentSessionId;
29
+ private resolveLastMessage;
30
+ run(task: SubAgentTask): Promise<string>;
31
+ isInterrupted(ctx: Context): Promise<boolean>;
32
+ reject(ctx: Context): Promise<{
33
+ interruptId?: string;
34
+ decisions: UserDecision[];
35
+ }>;
36
+ }
@@ -0,0 +1,225 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var dispatcher_exports = {};
28
+ __export(dispatcher_exports, {
29
+ SubAgentsDispatcher: () => SubAgentsDispatcher
30
+ });
31
+ module.exports = __toCommonJS(dispatcher_exports);
32
+ var import_ai_employee = require("../ai-employee");
33
+ class SubAgentsDispatcher {
34
+ constructor(plugin) {
35
+ this.plugin = plugin;
36
+ }
37
+ extractTextContent(content) {
38
+ if (typeof content === "string") {
39
+ return content;
40
+ }
41
+ if (Array.isArray(content)) {
42
+ return content.map((block) => {
43
+ if (typeof block === "string") {
44
+ return block;
45
+ }
46
+ if (block && typeof block === "object" && "type" in block && block.type === "text") {
47
+ return typeof block.text === "string" ? block.text : "";
48
+ }
49
+ return "";
50
+ }).join("");
51
+ }
52
+ if (content && typeof content === "object" && "content" in content) {
53
+ return this.extractTextContent(content.content);
54
+ }
55
+ return "";
56
+ }
57
+ extractLastMessageText(result) {
58
+ var _a;
59
+ const messages = result == null ? void 0 : result.messages;
60
+ if (!Array.isArray(messages) || messages.length === 0) {
61
+ return "";
62
+ }
63
+ return this.extractTextContent((_a = messages.at(-1)) == null ? void 0 : _a.content);
64
+ }
65
+ async resolveSubAgentSessionId(ctx) {
66
+ var _a, _b, _c, _d, _e;
67
+ const sessionId = (_c = (_b = (_a = ctx.action) == null ? void 0 : _a.params) == null ? void 0 : _b.values) == null ? void 0 : _c.sessionId;
68
+ if (!sessionId) {
69
+ return null;
70
+ }
71
+ const aiToolMessage = await ctx.db.getRepository("aiToolMessages").findOne({
72
+ filter: {
73
+ sessionId,
74
+ toolName: "dispatch-sub-agent-task",
75
+ invokeStatus: {
76
+ $ne: "confirmed"
77
+ }
78
+ },
79
+ sort: ["-id"]
80
+ });
81
+ if (!(aiToolMessage == null ? void 0 : aiToolMessage.messageId)) {
82
+ return null;
83
+ }
84
+ const aiMessage = await ctx.db.getRepository("aiMessages").findOne({
85
+ filter: {
86
+ sessionId,
87
+ messageId: aiToolMessage.messageId
88
+ }
89
+ });
90
+ const subAgentConversations = (_d = aiMessage == null ? void 0 : aiMessage.metadata) == null ? void 0 : _d.subAgentConversations;
91
+ if (!Array.isArray(subAgentConversations) || !subAgentConversations.length) {
92
+ return null;
93
+ }
94
+ return ((_e = subAgentConversations.at(-1)) == null ? void 0 : _e.sessionId) ?? null;
95
+ }
96
+ async resolveLastMessage(ctx) {
97
+ const subSessionId = await this.resolveSubAgentSessionId(ctx);
98
+ if (!subSessionId) {
99
+ return null;
100
+ }
101
+ return ctx.db.getRepository("aiMessages").findOne({
102
+ filter: {
103
+ sessionId: subSessionId
104
+ },
105
+ sort: ["-messageId"]
106
+ });
107
+ }
108
+ async run(task) {
109
+ var _a, _b, _c, _d, _e, _f, _g;
110
+ const { ctx, sessionId, employee, model, question, skillSettings, writer } = task;
111
+ const { webSearch } = ((_b = (_a = ctx.action) == null ? void 0 : _a.params) == null ? void 0 : _b.values) ?? {};
112
+ const plugin = ctx.app.pm.get("ai");
113
+ const userId = (_d = (_c = ctx.auth) == null ? void 0 : _c.user) == null ? void 0 : _d.id;
114
+ if (!userId) {
115
+ throw new Error("User not authenticated");
116
+ }
117
+ if (!(model == null ? void 0 : model.llmService) || !(model == null ? void 0 : model.model)) {
118
+ throw new Error("LLM service not configured");
119
+ }
120
+ const aiEmployee = new import_ai_employee.AIEmployee({
121
+ ctx,
122
+ employee,
123
+ sessionId,
124
+ skillSettings,
125
+ webSearch,
126
+ model,
127
+ from: "sub-agent"
128
+ });
129
+ const lastMessage = await ctx.db.getRepository("aiMessages").findOne({
130
+ filter: {
131
+ sessionId
132
+ },
133
+ sort: ["-messageId"]
134
+ });
135
+ const decisions = lastMessage ? await plugin.aiConversationsManager.getUserDecisions(lastMessage.messageId) : null;
136
+ let context;
137
+ const { messages } = ((_f = (_e = ctx.action) == null ? void 0 : _e.params) == null ? void 0 : _f.values) ?? {};
138
+ if (messages && ((_g = decisions == null ? void 0 : decisions.decisions) == null ? void 0 : _g.some((it) => it.type === "reject"))) {
139
+ context = {
140
+ appendMessage: await aiEmployee.getFormatMessages(messages)
141
+ };
142
+ }
143
+ const result = await aiEmployee.invoke({
144
+ userDecisions: decisions,
145
+ userMessages: decisions ? void 0 : [
146
+ {
147
+ role: "user",
148
+ content: {
149
+ type: "text",
150
+ content: question
151
+ }
152
+ }
153
+ ],
154
+ writer,
155
+ context
156
+ });
157
+ writer == null ? void 0 : writer({
158
+ action: "afterSubAgentInvoke",
159
+ body: {},
160
+ currentConversation: {
161
+ sessionId,
162
+ username: employee.username,
163
+ from: "sub-agent"
164
+ }
165
+ });
166
+ return this.extractLastMessageText(result);
167
+ }
168
+ async isInterrupted(ctx) {
169
+ var _a, _b, _c;
170
+ const sessionId = (_c = (_b = (_a = ctx.action) == null ? void 0 : _a.params) == null ? void 0 : _b.values) == null ? void 0 : _c.sessionId;
171
+ if (!sessionId) {
172
+ return false;
173
+ }
174
+ const aiToolMessage = await ctx.db.getRepository("aiToolMessages").findOne({
175
+ filter: {
176
+ sessionId,
177
+ toolName: "dispatch-sub-agent-task",
178
+ invokeStatus: "pending"
179
+ },
180
+ sort: ["-id"]
181
+ });
182
+ return aiToolMessage ? true : false;
183
+ }
184
+ async reject(ctx) {
185
+ var _a, _b, _c;
186
+ const plugin = ctx.app.pm.get("ai");
187
+ const { sessionId } = ((_b = (_a = ctx.action) == null ? void 0 : _a.params) == null ? void 0 : _b.values) ?? {};
188
+ const conversation = await ctx.db.getRepository("aiConversations").findOne({
189
+ filter: {
190
+ sessionId,
191
+ userId: (_c = ctx.auth) == null ? void 0 : _c.user.id
192
+ }
193
+ });
194
+ if (!conversation) {
195
+ return;
196
+ }
197
+ const lastMessage = await this.resolveLastMessage(ctx);
198
+ if (!sessionId || !lastMessage) {
199
+ return;
200
+ }
201
+ const userDecision = {
202
+ type: "reject",
203
+ message: `The user ignored the tools usage and send new messages`
204
+ };
205
+ const [updated] = await ctx.db.getRepository("aiToolMessages").model.update(
206
+ { userDecision, invokeStatus: "waiting" },
207
+ {
208
+ where: {
209
+ sessionId: lastMessage.get("sessionId"),
210
+ messageId: lastMessage.get("messageId"),
211
+ invokeStatus: "interrupted"
212
+ }
213
+ }
214
+ );
215
+ if (updated > 0) {
216
+ return await plugin.aiConversationsManager.getUserDecisions(lastMessage.get("messageId"));
217
+ } else {
218
+ return null;
219
+ }
220
+ }
221
+ }
222
+ // Annotate the CommonJS export names for ESM import in node:
223
+ 0 && (module.exports = {
224
+ SubAgentsDispatcher
225
+ });
@@ -0,0 +1,9 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+ export { SubAgentsDispatcher } from './dispatcher';
@@ -0,0 +1,36 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var sub_agents_exports = {};
28
+ __export(sub_agents_exports, {
29
+ SubAgentsDispatcher: () => import_dispatcher.SubAgentsDispatcher
30
+ });
31
+ module.exports = __toCommonJS(sub_agents_exports);
32
+ var import_dispatcher = require("./dispatcher");
33
+ // Annotate the CommonJS export names for ESM import in node:
34
+ 0 && (module.exports = {
35
+ SubAgentsDispatcher
36
+ });
@@ -50,6 +50,12 @@ var ai_conversations_default = (0, import_database.defineCollection)({
50
50
  name: "topicId",
51
51
  type: "string"
52
52
  },
53
+ {
54
+ name: "from",
55
+ type: "string",
56
+ defaultValue: "main-agent",
57
+ allowNull: false
58
+ },
53
59
  {
54
60
  name: "user",
55
61
  type: "belongsTo",
@@ -25,6 +25,7 @@ export declare class AnthropicProvider extends LLMProvider {
25
25
  }>;
26
26
  parseResponseMessage(message: Model): {
27
27
  key: any;
28
+ createdAt: any;
28
29
  content: any;
29
30
  role: any;
30
31
  };
@@ -116,7 +116,7 @@ class AnthropicProvider extends import_provider.LLMProvider {
116
116
  }
117
117
  }
118
118
  parseResponseMessage(message) {
119
- const { content: rawContent, messageId, metadata, role, toolCalls, attachments, workContext } = message;
119
+ const { content: rawContent, messageId, metadata, role, toolCalls, attachments, workContext, createdAt } = message;
120
120
  const content = {
121
121
  ...rawContent,
122
122
  messageId,
@@ -149,6 +149,7 @@ class AnthropicProvider extends import_provider.LLMProvider {
149
149
  }
150
150
  return {
151
151
  key: messageId,
152
+ createdAt,
152
153
  content,
153
154
  role
154
155
  };
@@ -17,8 +17,11 @@ export declare class DashscopeProvider extends LLMProvider {
17
17
  chatModel: ReasoningChatOpenAI;
18
18
  get baseURL(): string;
19
19
  createModel(): ReasoningChatOpenAI;
20
+ isToolConflict(): boolean;
21
+ resolveTools(toolDefinitions: any[]): any[];
20
22
  parseResponseMessage(message: Model): {
21
23
  key: any;
24
+ createdAt: any;
22
25
  content: any;
23
26
  role: any;
24
27
  };
@@ -57,7 +57,9 @@ class DashscopeProvider extends import_provider.LLMProvider {
57
57
  const { baseURL, apiKey } = this.serviceOptions || {};
58
58
  const { responseFormat, structuredOutput } = this.modelOptions || {};
59
59
  const { schema } = structuredOutput || {};
60
- const modelKwargs = {};
60
+ const modelKwargs = {
61
+ thinking_budget: 4e4
62
+ };
61
63
  if (responseFormat) {
62
64
  const responseFormatOptions = {
63
65
  type: responseFormat
@@ -71,10 +73,11 @@ class DashscopeProvider extends import_provider.LLMProvider {
71
73
  }
72
74
  if (((_b = (_a = this.modelOptions) == null ? void 0 : _a.builtIn) == null ? void 0 : _b.webSearch) === true) {
73
75
  modelKwargs["enable_search"] = true;
74
- modelKwargs["search_options"] = { forced_search: true };
75
76
  }
76
77
  return new import_reasoning.ReasoningChatOpenAI({
77
78
  apiKey,
79
+ topP: 0.8,
80
+ temperature: 0.7,
78
81
  ...this.modelOptions,
79
82
  modelKwargs,
80
83
  configuration: {
@@ -83,6 +86,17 @@ class DashscopeProvider extends import_provider.LLMProvider {
83
86
  verbose: false
84
87
  });
85
88
  }
89
+ isToolConflict() {
90
+ return true;
91
+ }
92
+ resolveTools(toolDefinitions) {
93
+ var _a, _b;
94
+ if (this.isToolConflict() && ((_b = (_a = this.modelOptions) == null ? void 0 : _a.builtIn) == null ? void 0 : _b.webSearch) === true) {
95
+ return [];
96
+ } else {
97
+ return toolDefinitions;
98
+ }
99
+ }
86
100
  parseResponseMessage(message) {
87
101
  var _a;
88
102
  const result = super.parseResponseMessage(message);
@@ -25,6 +25,7 @@ export declare class DeepSeekProvider extends LLMProvider {
25
25
  createModel(): ReasoningDeepSeek;
26
26
  parseResponseMessage(message: Model): {
27
27
  key: any;
28
+ createdAt: any;
28
29
  content: any;
29
30
  role: any;
30
31
  };