@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.
- 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/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/suggestions.js +2 -2
- package/dist/client/7237366e104efa7a.js +10 -0
- package/dist/client/748fbb87c1013c6e.js +10 -0
- package/dist/client/ai-employees/built-in/utils.d.ts +1 -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/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/index.js +7 -7
- package/dist/externalVersion.js +16 -15
- package/dist/locale/en-US.json +10 -1
- package/dist/locale/zh-CN.json +10 -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 +85 -9
- package/dist/server/ai-employees/ai-employee.js +264 -149
- 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 +9 -1
- package/dist/server/ai-employees/prompts.js +24 -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/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 +16 -2
- 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/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 +25 -1
- package/package.json +4 -2
- package/dist/client/27539a4356faebb1.js +0 -10
|
@@ -75,55 +75,61 @@ var aiConversations_default = {
|
|
|
75
75
|
if (!userId) {
|
|
76
76
|
return ctx.throw(403);
|
|
77
77
|
}
|
|
78
|
+
const filter = ctx.action.params.filter || {};
|
|
78
79
|
ctx.action.mergeParams({
|
|
79
80
|
filter: {
|
|
80
|
-
|
|
81
|
+
...filter,
|
|
82
|
+
userId,
|
|
83
|
+
from: filter.from ?? "main-agent"
|
|
81
84
|
}
|
|
82
85
|
});
|
|
83
86
|
return import_actions.default.list(ctx, next);
|
|
84
87
|
},
|
|
85
88
|
async create(ctx, next) {
|
|
86
89
|
var _a;
|
|
90
|
+
const plugin = ctx.app.pm.get("ai");
|
|
87
91
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
92
|
+
if (!userId) {
|
|
93
|
+
return ctx.throw(403);
|
|
94
|
+
}
|
|
88
95
|
const { aiEmployee, systemMessage, skillSettings, conversationSettings } = ctx.action.params.values || {};
|
|
89
96
|
const employee = await getAIEmployee(ctx, aiEmployee.username);
|
|
90
97
|
if (!employee) {
|
|
91
98
|
ctx.throw(400, "AI employee not found");
|
|
92
99
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
values: {
|
|
100
|
+
try {
|
|
101
|
+
ctx.body = await plugin.aiConversationsManager.create({
|
|
96
102
|
userId,
|
|
97
103
|
aiEmployee,
|
|
98
104
|
options: {
|
|
99
105
|
systemMessage,
|
|
100
106
|
skillSettings,
|
|
101
107
|
conversationSettings
|
|
102
|
-
}
|
|
103
|
-
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
} catch (error) {
|
|
111
|
+
if (error.message === "AI employee not found") {
|
|
112
|
+
ctx.throw(400, error.message);
|
|
104
113
|
}
|
|
105
|
-
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
106
116
|
await next();
|
|
107
117
|
},
|
|
108
118
|
async update(ctx, next) {
|
|
109
119
|
var _a;
|
|
120
|
+
const plugin = ctx.app.pm.get("ai");
|
|
110
121
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
122
|
+
if (!userId) {
|
|
123
|
+
return ctx.throw(403);
|
|
124
|
+
}
|
|
111
125
|
const { filterByTk: sessionId } = ctx.action.params;
|
|
112
126
|
const { title } = ctx.action.params.values || {};
|
|
113
|
-
|
|
114
|
-
ctx.body = await repo.update({
|
|
115
|
-
filter: {
|
|
116
|
-
userId,
|
|
117
|
-
sessionId
|
|
118
|
-
},
|
|
119
|
-
values: {
|
|
120
|
-
title
|
|
121
|
-
}
|
|
122
|
-
});
|
|
127
|
+
ctx.body = await plugin.aiConversationsManager.update({ userId, sessionId, title });
|
|
123
128
|
await next();
|
|
124
129
|
},
|
|
125
130
|
async updateOptions(ctx, next) {
|
|
126
131
|
var _a;
|
|
132
|
+
const plugin = ctx.app.pm.get("ai");
|
|
127
133
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
128
134
|
if (!userId) {
|
|
129
135
|
return ctx.throw(403);
|
|
@@ -136,34 +142,18 @@ var aiConversations_default = {
|
|
|
136
142
|
if (!systemMessage && !skillSettings && !conversationSettings) {
|
|
137
143
|
return ctx.throw(400, "invalid options");
|
|
138
144
|
}
|
|
139
|
-
|
|
140
|
-
|
|
145
|
+
try {
|
|
146
|
+
ctx.body = await plugin.aiConversationsManager.update({
|
|
147
|
+
userId,
|
|
141
148
|
sessionId,
|
|
142
|
-
|
|
149
|
+
options: { systemMessage, skillSettings, conversationSettings }
|
|
150
|
+
});
|
|
151
|
+
} catch (error) {
|
|
152
|
+
if (error.message === "invalid sessionId") {
|
|
153
|
+
ctx.throw(400, error.message);
|
|
143
154
|
}
|
|
144
|
-
|
|
145
|
-
if (!conversation) {
|
|
146
|
-
ctx.throw(400, "invalid sessionId");
|
|
147
|
-
}
|
|
148
|
-
const options = conversation.options ?? {};
|
|
149
|
-
if (systemMessage) {
|
|
150
|
-
options["systemMessage"] = systemMessage;
|
|
151
|
-
}
|
|
152
|
-
if (skillSettings) {
|
|
153
|
-
options["skillSettings"] = skillSettings;
|
|
155
|
+
throw error;
|
|
154
156
|
}
|
|
155
|
-
if (conversationSettings) {
|
|
156
|
-
options["conversationSettings"] = conversationSettings;
|
|
157
|
-
}
|
|
158
|
-
ctx.body = await ctx.db.getRepository("aiConversations").update({
|
|
159
|
-
filter: {
|
|
160
|
-
userId,
|
|
161
|
-
sessionId
|
|
162
|
-
},
|
|
163
|
-
values: {
|
|
164
|
-
options
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
157
|
await next();
|
|
168
158
|
},
|
|
169
159
|
async destroy(ctx, next) {
|
|
@@ -191,88 +181,19 @@ var aiConversations_default = {
|
|
|
191
181
|
ctx.throw(400);
|
|
192
182
|
}
|
|
193
183
|
const paginate = ((_b = ctx.action.params) == null ? void 0 : _b.paginate) === "false" ? false : true;
|
|
194
|
-
|
|
195
|
-
|
|
184
|
+
try {
|
|
185
|
+
ctx.body = await plugin.aiConversationsManager.getMessages({
|
|
186
|
+
userId,
|
|
196
187
|
sessionId,
|
|
197
|
-
|
|
188
|
+
cursor,
|
|
189
|
+
paginate
|
|
190
|
+
});
|
|
191
|
+
} catch (error) {
|
|
192
|
+
if (error.message === "invalid sessionId") {
|
|
193
|
+
ctx.throw(400);
|
|
198
194
|
}
|
|
199
|
-
|
|
200
|
-
if (!conversation) {
|
|
201
|
-
ctx.throw(400);
|
|
195
|
+
throw error;
|
|
202
196
|
}
|
|
203
|
-
const pageSize = 10;
|
|
204
|
-
const maxLimit = 200;
|
|
205
|
-
const messageRepository = ctx.db.getRepository("aiConversations.messages", sessionId);
|
|
206
|
-
const filter = {
|
|
207
|
-
role: {
|
|
208
|
-
$notIn: ["tool"]
|
|
209
|
-
}
|
|
210
|
-
};
|
|
211
|
-
if (paginate && cursor) {
|
|
212
|
-
filter["messageId"] = {
|
|
213
|
-
$lt: cursor
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
const rows = await messageRepository.find({
|
|
217
|
-
sort: ["-messageId"],
|
|
218
|
-
limit: paginate ? pageSize + 1 : maxLimit,
|
|
219
|
-
filter
|
|
220
|
-
});
|
|
221
|
-
const hasMore = paginate && rows.length > pageSize;
|
|
222
|
-
const data = hasMore ? rows.slice(0, -1) : rows;
|
|
223
|
-
const newCursor = data.length ? data[data.length - 1].messageId : null;
|
|
224
|
-
const toolCallIds = data.filter((row) => {
|
|
225
|
-
var _a2;
|
|
226
|
-
return ((_a2 = row == null ? void 0 : row.toolCalls) == null ? void 0 : _a2.length) ?? 0 > 0;
|
|
227
|
-
}).flatMap((row) => row.toolCalls).map((toolCall) => toolCall.id);
|
|
228
|
-
const toolMessages = await ctx.db.getRepository("aiToolMessages").find({
|
|
229
|
-
filter: {
|
|
230
|
-
sessionId,
|
|
231
|
-
toolCallId: {
|
|
232
|
-
$in: toolCallIds
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
});
|
|
236
|
-
const toolMessageKey = (messageId, toolCallId) => `${messageId}:${toolCallId}`;
|
|
237
|
-
const toolMessageMap = new Map(
|
|
238
|
-
toolMessages.map((toolMessage) => [
|
|
239
|
-
toolMessageKey(toolMessage.messageId, toolMessage.toolCallId),
|
|
240
|
-
toolMessage
|
|
241
|
-
])
|
|
242
|
-
);
|
|
243
|
-
const toolsList = await plugin.ai.toolsManager.listTools();
|
|
244
|
-
const toolsMap = new Map(toolsList.map((t) => [t.definition.name, t]));
|
|
245
|
-
ctx.body = {
|
|
246
|
-
rows: data.map((row) => {
|
|
247
|
-
var _a2, _b2;
|
|
248
|
-
if (((_a2 = row == null ? void 0 : row.toolCalls) == null ? void 0 : _a2.length) ?? 0 > 0) {
|
|
249
|
-
for (const toolCall of row.toolCalls) {
|
|
250
|
-
const tools = toolsMap.get(toolCall.name);
|
|
251
|
-
const toolMessage = toolMessageMap.get(toolMessageKey(row.messageId, toolCall.id));
|
|
252
|
-
toolCall.invokeStatus = toolMessage == null ? void 0 : toolMessage.invokeStatus;
|
|
253
|
-
toolCall.auto = toolMessage == null ? void 0 : toolMessage.auto;
|
|
254
|
-
toolCall.status = toolMessage == null ? void 0 : toolMessage.status;
|
|
255
|
-
toolCall.content = toolMessage == null ? void 0 : toolMessage.content;
|
|
256
|
-
toolCall.execution = tools == null ? void 0 : tools.execution;
|
|
257
|
-
toolCall.willInterrupt = (tools == null ? void 0 : tools.execution) === "frontend" || (toolMessage == null ? void 0 : toolMessage.auto) === false;
|
|
258
|
-
toolCall.defaultPermission = tools == null ? void 0 : tools.defaultPermission;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
const providerOptions = plugin.aiManager.llmProviders.get((_b2 = row.metadata) == null ? void 0 : _b2.provider);
|
|
262
|
-
if (!providerOptions) {
|
|
263
|
-
return (0, import_utils.parseResponseMessage)(row);
|
|
264
|
-
}
|
|
265
|
-
const Provider = providerOptions.provider;
|
|
266
|
-
const provider = new Provider({
|
|
267
|
-
app: ctx.app
|
|
268
|
-
});
|
|
269
|
-
return provider.parseResponseMessage(row);
|
|
270
|
-
}),
|
|
271
|
-
...paginate && {
|
|
272
|
-
hasMore,
|
|
273
|
-
cursor: newCursor
|
|
274
|
-
}
|
|
275
|
-
};
|
|
276
197
|
await next();
|
|
277
198
|
},
|
|
278
199
|
async updateToolArgs(ctx, next) {
|
|
@@ -320,7 +241,12 @@ var aiConversations_default = {
|
|
|
320
241
|
await next();
|
|
321
242
|
},
|
|
322
243
|
async sendMessages(ctx, next) {
|
|
323
|
-
var _a, _b;
|
|
244
|
+
var _a, _b, _c;
|
|
245
|
+
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
246
|
+
if (!userId) {
|
|
247
|
+
return ctx.throw(403);
|
|
248
|
+
}
|
|
249
|
+
const plugin = ctx.app.pm.get("ai");
|
|
324
250
|
const {
|
|
325
251
|
sessionId,
|
|
326
252
|
aiEmployee: employeeName,
|
|
@@ -355,7 +281,10 @@ var aiConversations_default = {
|
|
|
355
281
|
}
|
|
356
282
|
try {
|
|
357
283
|
const conversation = await ctx.db.getRepository("aiConversations").findOne({
|
|
358
|
-
|
|
284
|
+
filter: {
|
|
285
|
+
sessionId,
|
|
286
|
+
userId
|
|
287
|
+
}
|
|
359
288
|
});
|
|
360
289
|
if (!conversation) {
|
|
361
290
|
if (shouldStream) {
|
|
@@ -390,29 +319,41 @@ var aiConversations_default = {
|
|
|
390
319
|
return next();
|
|
391
320
|
}
|
|
392
321
|
const legacy = conversation.thread === 0;
|
|
393
|
-
const aiEmployee = new import_ai_employee.AIEmployee(
|
|
322
|
+
const aiEmployee = new import_ai_employee.AIEmployee({
|
|
394
323
|
ctx,
|
|
395
324
|
employee,
|
|
396
325
|
sessionId,
|
|
397
|
-
(
|
|
398
|
-
(
|
|
326
|
+
systemMessage: (_b = conversation.options) == null ? void 0 : _b.systemMessage,
|
|
327
|
+
skillSettings: (_c = conversation.options) == null ? void 0 : _c.skillSettings,
|
|
399
328
|
webSearch,
|
|
400
329
|
model,
|
|
401
330
|
legacy
|
|
402
|
-
);
|
|
331
|
+
});
|
|
403
332
|
if (!editingMessageId) {
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
333
|
+
if (await plugin.subAgentsDispatcher.isInterrupted(ctx)) {
|
|
334
|
+
const userDecisions = await plugin.subAgentsDispatcher.reject(ctx);
|
|
335
|
+
if (userDecisions) {
|
|
336
|
+
if (shouldStream) {
|
|
337
|
+
await aiEmployee.stream({ userDecisions });
|
|
338
|
+
} else {
|
|
339
|
+
ctx.body = await aiEmployee.invoke({ userDecisions });
|
|
340
|
+
}
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
} else {
|
|
344
|
+
const toolMessages = await aiEmployee.cancelToolCall();
|
|
345
|
+
if (toolMessages == null ? void 0 : toolMessages.length) {
|
|
346
|
+
for (let i = toolMessages.length - 1; i >= 0; i--) {
|
|
347
|
+
const toolMessage = toolMessages[i];
|
|
348
|
+
messages.unshift({
|
|
349
|
+
role: toolMessage.role,
|
|
350
|
+
content: toolMessage.content,
|
|
351
|
+
toolCalls: toolMessage.toolCalls,
|
|
352
|
+
attachments: toolMessage.attachments,
|
|
353
|
+
workContext: toolMessage.workContext,
|
|
354
|
+
metadata: toolMessage.metadata
|
|
355
|
+
});
|
|
356
|
+
}
|
|
416
357
|
}
|
|
417
358
|
}
|
|
418
359
|
}
|
|
@@ -429,17 +370,36 @@ var aiConversations_default = {
|
|
|
429
370
|
ctx.status = 500;
|
|
430
371
|
ctx.body = { error: err.message || "Tool call error" };
|
|
431
372
|
}
|
|
373
|
+
} finally {
|
|
374
|
+
await next();
|
|
432
375
|
}
|
|
433
|
-
await next();
|
|
434
376
|
},
|
|
435
377
|
async abort(ctx, next) {
|
|
378
|
+
var _a;
|
|
379
|
+
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
380
|
+
if (!userId) {
|
|
381
|
+
return ctx.throw(403);
|
|
382
|
+
}
|
|
436
383
|
const { sessionId } = ctx.action.params.values || {};
|
|
437
384
|
const plugin = ctx.app.pm.get("ai");
|
|
385
|
+
const conversation = await ctx.db.getRepository("aiConversations").findOne({
|
|
386
|
+
filter: {
|
|
387
|
+
sessionId,
|
|
388
|
+
userId
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
if (!conversation) {
|
|
392
|
+
ctx.throw(404, "conversation not found");
|
|
393
|
+
}
|
|
438
394
|
plugin.aiEmployeesManager.abortConversation(sessionId);
|
|
439
395
|
await next();
|
|
440
396
|
},
|
|
441
397
|
async resendMessages(ctx, next) {
|
|
442
|
-
var _a, _b;
|
|
398
|
+
var _a, _b, _c;
|
|
399
|
+
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
400
|
+
if (!userId) {
|
|
401
|
+
return ctx.throw(403);
|
|
402
|
+
}
|
|
443
403
|
setupSSEHeaders(ctx);
|
|
444
404
|
const { sessionId, webSearch, model } = ctx.action.params.values || {};
|
|
445
405
|
let { messageId } = ctx.action.params.values || {};
|
|
@@ -450,7 +410,8 @@ var aiConversations_default = {
|
|
|
450
410
|
try {
|
|
451
411
|
const conversation = await ctx.db.getRepository("aiConversations").findOne({
|
|
452
412
|
filter: {
|
|
453
|
-
sessionId
|
|
413
|
+
sessionId,
|
|
414
|
+
userId
|
|
454
415
|
}
|
|
455
416
|
});
|
|
456
417
|
if (!conversation) {
|
|
@@ -496,15 +457,15 @@ var aiConversations_default = {
|
|
|
496
457
|
sendErrorResponse(ctx, "AI employee not found");
|
|
497
458
|
return next();
|
|
498
459
|
}
|
|
499
|
-
const aiEmployee = new import_ai_employee.AIEmployee(
|
|
460
|
+
const aiEmployee = new import_ai_employee.AIEmployee({
|
|
500
461
|
ctx,
|
|
501
462
|
employee,
|
|
502
463
|
sessionId,
|
|
503
|
-
(
|
|
504
|
-
(
|
|
464
|
+
systemMessage: (_b = conversation.options) == null ? void 0 : _b.systemMessage,
|
|
465
|
+
skillSettings: (_c = conversation.options) == null ? void 0 : _c.skillSettings,
|
|
505
466
|
webSearch,
|
|
506
467
|
model
|
|
507
|
-
);
|
|
468
|
+
});
|
|
508
469
|
await aiEmployee.stream({ messageId, userMessages: resendMessages.length ? resendMessages : void 0 });
|
|
509
470
|
} catch (err) {
|
|
510
471
|
ctx.log.error(err);
|
|
@@ -532,7 +493,7 @@ var aiConversations_default = {
|
|
|
532
493
|
if (!conversation) {
|
|
533
494
|
ctx.throw(400);
|
|
534
495
|
}
|
|
535
|
-
const message = await ctx.db.getRepository("
|
|
496
|
+
const message = await ctx.db.getRepository("aiMessages").findOne({
|
|
536
497
|
filter: {
|
|
537
498
|
messageId
|
|
538
499
|
}
|
|
@@ -546,7 +507,7 @@ var aiConversations_default = {
|
|
|
546
507
|
}
|
|
547
508
|
const aiToolMessagesModel = ctx.db.getModel("aiToolMessages");
|
|
548
509
|
const toolCall = await aiToolMessagesModel.findOne({
|
|
549
|
-
where: { sessionId, messageId, toolCallId }
|
|
510
|
+
where: { sessionId: message.sessionId, messageId: message.messageId, toolCallId }
|
|
550
511
|
});
|
|
551
512
|
if (!toolCall) {
|
|
552
513
|
ctx.throw(400);
|
|
@@ -558,8 +519,8 @@ var aiConversations_default = {
|
|
|
558
519
|
},
|
|
559
520
|
{
|
|
560
521
|
where: {
|
|
561
|
-
sessionId,
|
|
562
|
-
messageId,
|
|
522
|
+
sessionId: message.sessionId,
|
|
523
|
+
messageId: message.messageId,
|
|
563
524
|
toolCallId,
|
|
564
525
|
invokeStatus: "interrupted"
|
|
565
526
|
}
|
|
@@ -568,8 +529,8 @@ var aiConversations_default = {
|
|
|
568
529
|
const toolCallIds = toolCalls.map((x) => x.id);
|
|
569
530
|
const toolMessages = await ctx.db.getRepository("aiToolMessages").find({
|
|
570
531
|
filter: {
|
|
571
|
-
sessionId,
|
|
572
|
-
messageId,
|
|
532
|
+
sessionId: message.sessionId,
|
|
533
|
+
messageId: message.messageId,
|
|
573
534
|
toolCallId: {
|
|
574
535
|
$in: toolCallIds
|
|
575
536
|
}
|
|
@@ -599,7 +560,12 @@ var aiConversations_default = {
|
|
|
599
560
|
},
|
|
600
561
|
async resumeToolCall(ctx, next) {
|
|
601
562
|
var _a, _b, _c;
|
|
563
|
+
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
564
|
+
if (!userId) {
|
|
565
|
+
return ctx.throw(403);
|
|
566
|
+
}
|
|
602
567
|
setupSSEHeaders(ctx);
|
|
568
|
+
const plugin = ctx.app.pm.get("ai");
|
|
603
569
|
const { sessionId, messageId, model, webSearch } = ctx.action.params.values || {};
|
|
604
570
|
if (!sessionId) {
|
|
605
571
|
sendErrorResponse(ctx, "sessionId is required");
|
|
@@ -609,7 +575,7 @@ var aiConversations_default = {
|
|
|
609
575
|
const conversation = await ctx.db.getRepository("aiConversations").findOne({
|
|
610
576
|
filter: {
|
|
611
577
|
sessionId,
|
|
612
|
-
userId
|
|
578
|
+
userId
|
|
613
579
|
}
|
|
614
580
|
});
|
|
615
581
|
if (!conversation) {
|
|
@@ -623,7 +589,7 @@ var aiConversations_default = {
|
|
|
623
589
|
}
|
|
624
590
|
let message;
|
|
625
591
|
if (messageId) {
|
|
626
|
-
message = await ctx.db.getRepository("
|
|
592
|
+
message = await ctx.db.getRepository("aiMessages").findOne({
|
|
627
593
|
filter: {
|
|
628
594
|
messageId
|
|
629
595
|
}
|
|
@@ -642,16 +608,16 @@ var aiConversations_default = {
|
|
|
642
608
|
sendErrorResponse(ctx, "No tool calls found");
|
|
643
609
|
return next();
|
|
644
610
|
}
|
|
645
|
-
const aiEmployee = new import_ai_employee.AIEmployee(
|
|
611
|
+
const aiEmployee = new import_ai_employee.AIEmployee({
|
|
646
612
|
ctx,
|
|
647
613
|
employee,
|
|
648
614
|
sessionId,
|
|
649
|
-
(_b = conversation.options) == null ? void 0 : _b.systemMessage,
|
|
650
|
-
(_c = conversation.options) == null ? void 0 : _c.skillSettings,
|
|
615
|
+
systemMessage: (_b = conversation.options) == null ? void 0 : _b.systemMessage,
|
|
616
|
+
skillSettings: (_c = conversation.options) == null ? void 0 : _c.skillSettings,
|
|
651
617
|
webSearch,
|
|
652
618
|
model
|
|
653
|
-
);
|
|
654
|
-
const userDecisions = await
|
|
619
|
+
});
|
|
620
|
+
const userDecisions = await plugin.aiConversationsManager.getUserDecisions(messageId);
|
|
655
621
|
await aiEmployee.stream({
|
|
656
622
|
userDecisions
|
|
657
623
|
});
|
|
@@ -29,7 +29,10 @@ export type AIChatContext = {
|
|
|
29
29
|
tool_call_id?: string;
|
|
30
30
|
tool_calls?: AIToolCall[];
|
|
31
31
|
}[];
|
|
32
|
-
decisions?:
|
|
32
|
+
decisions?: {
|
|
33
|
+
interruptId?: string;
|
|
34
|
+
decisions: UserDecision[];
|
|
35
|
+
};
|
|
33
36
|
tools?: any[];
|
|
34
37
|
middleware?: any[];
|
|
35
38
|
structuredOutput?: {
|
|
@@ -48,7 +51,10 @@ export type AIMessageRemoveOptions = {
|
|
|
48
51
|
};
|
|
49
52
|
export type AIChatContextOptions = {
|
|
50
53
|
userMessages?: AIMessageInput[];
|
|
51
|
-
userDecisions?:
|
|
54
|
+
userDecisions?: {
|
|
55
|
+
interruptId?: string;
|
|
56
|
+
decisions: UserDecision[];
|
|
57
|
+
};
|
|
52
58
|
tools?: any[];
|
|
53
59
|
middleware?: any[];
|
|
54
60
|
getSystemPrompt?: (userMessages: AIMessageInput[]) => Promise<string>;
|
|
@@ -10,6 +10,7 @@ export type AIMessage = {
|
|
|
10
10
|
messageId: string;
|
|
11
11
|
sessionId: string;
|
|
12
12
|
role: string;
|
|
13
|
+
createdAt?: string | Date;
|
|
13
14
|
content: AIMessageContent;
|
|
14
15
|
toolCalls?: AIToolCall[];
|
|
15
16
|
attachments?: unknown[];
|
|
@@ -44,8 +45,14 @@ export type AIMessageMetadata = {
|
|
|
44
45
|
autoCallTools?: string[];
|
|
45
46
|
autoCall?: boolean;
|
|
46
47
|
interrupted?: boolean;
|
|
48
|
+
subAgentConversations?: SubAgentConversationMetadata[];
|
|
47
49
|
[key: string]: unknown;
|
|
48
50
|
};
|
|
51
|
+
export type SubAgentConversationMetadata = {
|
|
52
|
+
sessionId: string;
|
|
53
|
+
toolCallId: string;
|
|
54
|
+
status: 'pending' | 'completed';
|
|
55
|
+
};
|
|
49
56
|
export type AIToolMessage = {
|
|
50
57
|
id: string;
|
|
51
58
|
sessionId: string;
|
package/dist/server/utils.d.ts
CHANGED
|
@@ -8,13 +8,16 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { Model } from '@nocobase/database';
|
|
10
10
|
import { Context } from '@nocobase/actions';
|
|
11
|
+
import { ToolsEntry } from '@nocobase/ai';
|
|
11
12
|
export declare function sendSSEError(ctx: Context, error: Error | string, errorName?: string): void;
|
|
12
13
|
export declare function stripToolCallTags(content: string): string | null;
|
|
13
14
|
export declare function parseResponseMessage(row: Model): {
|
|
14
15
|
key: any;
|
|
16
|
+
createdAt: any;
|
|
15
17
|
content: any;
|
|
16
18
|
role: any;
|
|
17
19
|
};
|
|
18
20
|
export declare function encodeLocalFile(url: string): Promise<string>;
|
|
19
21
|
export declare function encodeFile(ctx: Context, url: string): Promise<string>;
|
|
20
22
|
export declare function parseVariables(ctx: Context, value: string): Promise<any>;
|
|
23
|
+
export declare const buildTool: (toolsEntry: ToolsEntry) => import("@langchain/core/dist/tools").DynamicTool<any>;
|
package/dist/server/utils.js
CHANGED
|
@@ -36,6 +36,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
36
36
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
37
|
var utils_exports = {};
|
|
38
38
|
__export(utils_exports, {
|
|
39
|
+
buildTool: () => buildTool,
|
|
39
40
|
encodeFile: () => encodeFile,
|
|
40
41
|
encodeLocalFile: () => encodeLocalFile,
|
|
41
42
|
parseResponseMessage: () => parseResponseMessage,
|
|
@@ -48,6 +49,7 @@ var import_path = __toESM(require("path"));
|
|
|
48
49
|
var import_fs = __toESM(require("fs"));
|
|
49
50
|
var import_axios = __toESM(require("axios"));
|
|
50
51
|
var import_utils = require("@nocobase/utils");
|
|
52
|
+
var import_langchain = require("langchain");
|
|
51
53
|
function sendSSEError(ctx, error, errorName) {
|
|
52
54
|
const body = typeof error === "string" ? error : error.message || "Unknown error";
|
|
53
55
|
if (!ctx.res.headersSent) {
|
|
@@ -70,7 +72,7 @@ function stripToolCallTags(content) {
|
|
|
70
72
|
return content.replace(/<[||]tool▁(?:calls▁begin|calls▁end|call▁begin|call▁end|sep)[||]>/g, "");
|
|
71
73
|
}
|
|
72
74
|
function parseResponseMessage(row) {
|
|
73
|
-
const { content: rawContent, messageId, metadata, role, toolCalls, attachments, workContext } = row;
|
|
75
|
+
const { content: rawContent, messageId, metadata, role, toolCalls, attachments, workContext, createdAt } = row;
|
|
74
76
|
const content = {
|
|
75
77
|
...rawContent ?? {},
|
|
76
78
|
content: stripToolCallTags(rawContent == null ? void 0 : rawContent.content),
|
|
@@ -84,6 +86,7 @@ function parseResponseMessage(row) {
|
|
|
84
86
|
}
|
|
85
87
|
return {
|
|
86
88
|
key: messageId,
|
|
89
|
+
createdAt,
|
|
87
90
|
content,
|
|
88
91
|
role
|
|
89
92
|
};
|
|
@@ -151,8 +154,29 @@ async function parseVariables(ctx, value) {
|
|
|
151
154
|
$nDate
|
|
152
155
|
});
|
|
153
156
|
}
|
|
157
|
+
const noWriter = (chunk) => console.warn(`No writer in tools runtime, chunk:[${chunk}]`);
|
|
158
|
+
const buildTool = (toolsEntry) => {
|
|
159
|
+
const {
|
|
160
|
+
invoke,
|
|
161
|
+
definition: { name, description, schema }
|
|
162
|
+
} = toolsEntry;
|
|
163
|
+
return (0, import_langchain.tool)(
|
|
164
|
+
(input, config) => {
|
|
165
|
+
const { context, toolCall } = config;
|
|
166
|
+
const writer = config["writer"] ?? noWriter;
|
|
167
|
+
return invoke(context.ctx, input, { toolCallId: toolCall.id, writer });
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
name,
|
|
171
|
+
description,
|
|
172
|
+
schema,
|
|
173
|
+
returnDirect: false
|
|
174
|
+
}
|
|
175
|
+
);
|
|
176
|
+
};
|
|
154
177
|
// Annotate the CommonJS export names for ESM import in node:
|
|
155
178
|
0 && (module.exports = {
|
|
179
|
+
buildTool,
|
|
156
180
|
encodeFile,
|
|
157
181
|
encodeLocalFile,
|
|
158
182
|
parseResponseMessage,
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"description": "Create AI employees with diverse skills to collaborate with humans, build systems, and handle business operations.",
|
|
7
7
|
"description.ru-RU": "Поддержка интеграции с AI-сервисами: предоставляются AI-узлы для рабочих процессов, расширяя возможности бизнес-обработки.",
|
|
8
8
|
"description.zh-CN": "创建各种技能的 AI 员工,与人类协同,搭建系统,处理业务。",
|
|
9
|
-
"version": "2.1.0-alpha.
|
|
9
|
+
"version": "2.1.0-alpha.14",
|
|
10
10
|
"main": "dist/server/index.js",
|
|
11
11
|
"homepage": "https://docs.nocobase.com/handbook/action-ai",
|
|
12
12
|
"homepage.ru-RU": "https://docs-ru.nocobase.com/handbook/action-ai",
|
|
@@ -22,7 +22,9 @@
|
|
|
22
22
|
"@nocobase/ai": "2.x",
|
|
23
23
|
"@nocobase/client": "2.x",
|
|
24
24
|
"@nocobase/flow-engine": "2.x",
|
|
25
|
+
"@nocobase/plugin-acl": "2.x",
|
|
25
26
|
"@nocobase/plugin-data-source-manager": "2.x",
|
|
27
|
+
"@nocobase/plugin-file-manager": "2.x",
|
|
26
28
|
"@nocobase/plugin-workflow": "2.x",
|
|
27
29
|
"@nocobase/server": "2.x",
|
|
28
30
|
"@nocobase/test": "2.x"
|
|
@@ -59,5 +61,5 @@
|
|
|
59
61
|
"keywords": [
|
|
60
62
|
"AI"
|
|
61
63
|
],
|
|
62
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "d8735b541de0ff9557bba704de49c799b4962672"
|
|
63
65
|
}
|