@nocobase/plugin-ai 2.1.0-beta.32 → 2.1.0-beta.34
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/docs/nocobase/api/cli/env/remove.md +5 -3
- package/dist/ai/docs/nocobase/cluster-mode/index.md +5 -1
- package/dist/ai/docs/nocobase/cluster-mode/preparations.md +58 -3
- package/dist/externalVersion.js +16 -16
- package/dist/node_modules/@langchain/xai/package.json +1 -1
- package/dist/node_modules/fs-extra/package.json +1 -1
- package/dist/node_modules/jsonrepair/package.json +1 -1
- package/dist/node_modules/just-bash/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-employee.d.ts +0 -1
- package/dist/server/ai-employees/ai-employee.js +0 -41
- package/dist/server/document-loader/cached.d.ts +5 -7
- package/dist/server/document-loader/cached.js +49 -120
- package/dist/server/document-loader/loader.d.ts +1 -1
- package/dist/server/document-loader/loader.js +2 -2
- package/dist/server/document-loader/types.d.ts +1 -6
- package/dist/server/features/vector-database-provider.d.ts +8 -0
- package/dist/server/llm-providers/kimi/document-loader.d.ts +1 -1
- package/dist/server/llm-providers/kimi/document-loader.js +4 -4
- package/dist/server/llm-providers/provider.d.ts +1 -1
- package/dist/server/llm-providers/provider.js +11 -2
- package/dist/server/manager/llm-stream-manager.d.ts +16 -10
- package/dist/server/manager/llm-stream-manager.js +121 -27
- package/dist/server/migrations/20260407170416-ai-employee-knowledge-base-add-key.js +1 -1
- package/dist/server/resource/aiConversations.d.ts +12 -13
- package/dist/server/resource/aiConversations.js +117 -113
- package/dist/server/utils.d.ts +4 -0
- package/dist/server/utils.js +9 -0
- package/dist/server/workflow/nodes/employee/index.js +3 -4
- package/package.json +2 -2
|
@@ -43,6 +43,7 @@ var import_actions = __toESM(require("@nocobase/actions"));
|
|
|
43
43
|
var import_database = require("@nocobase/database");
|
|
44
44
|
var import_utils = require("../utils");
|
|
45
45
|
var import_ai_employee = require("../ai-employees/ai-employee");
|
|
46
|
+
var import_ai_chat_conversation = require("../manager/ai-chat-conversation");
|
|
46
47
|
async function getAIEmployee(ctx, username) {
|
|
47
48
|
var _a;
|
|
48
49
|
const filter = {
|
|
@@ -67,12 +68,17 @@ function setupSSEHeaders(ctx) {
|
|
|
67
68
|
function sendErrorResponse(ctx, errorMessage) {
|
|
68
69
|
(0, import_utils.sendSSEError)(ctx, errorMessage);
|
|
69
70
|
}
|
|
70
|
-
async function
|
|
71
|
+
async function loginInCheck(ctx, next) {
|
|
71
72
|
var _a;
|
|
72
73
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
73
74
|
if (!userId) {
|
|
74
75
|
return ctx.throw(403);
|
|
75
76
|
}
|
|
77
|
+
await next();
|
|
78
|
+
}
|
|
79
|
+
const isReachParallelLimit = async (ctx) => {
|
|
80
|
+
var _a;
|
|
81
|
+
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
76
82
|
const activeStreamCount = await ctx.db.getModel("aiConversations").count({
|
|
77
83
|
where: {
|
|
78
84
|
userId,
|
|
@@ -82,27 +88,32 @@ async function parallelConversationsLimit(ctx, next) {
|
|
|
82
88
|
}
|
|
83
89
|
}
|
|
84
90
|
});
|
|
85
|
-
|
|
86
|
-
|
|
91
|
+
return activeStreamCount > 2;
|
|
92
|
+
};
|
|
93
|
+
const saveUserMessages = async (ctx, sessionId, messages, messageId) => {
|
|
94
|
+
const userMessages = messages.filter((message) => message.role === "user");
|
|
95
|
+
if (!userMessages.length) {
|
|
87
96
|
return;
|
|
88
97
|
}
|
|
89
|
-
|
|
90
|
-
|
|
98
|
+
const aiChatConversation = (0, import_ai_chat_conversation.createAIChatConversation)(ctx, sessionId);
|
|
99
|
+
await aiChatConversation.withTransaction(async (conversation) => {
|
|
100
|
+
if (messageId && await conversation.getMessage(messageId)) {
|
|
101
|
+
await conversation.removeMessages({ messageId });
|
|
102
|
+
}
|
|
103
|
+
await conversation.addMessages(userMessages);
|
|
104
|
+
});
|
|
105
|
+
};
|
|
91
106
|
var aiConversations_default = {
|
|
92
107
|
name: "aiConversations",
|
|
93
108
|
middlewares: [
|
|
94
109
|
{
|
|
95
|
-
|
|
96
|
-
handler: parallelConversationsLimit
|
|
110
|
+
handler: loginInCheck
|
|
97
111
|
}
|
|
98
112
|
],
|
|
99
113
|
actions: {
|
|
100
114
|
async list(ctx, next) {
|
|
101
115
|
var _a;
|
|
102
116
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
103
|
-
if (!userId) {
|
|
104
|
-
return ctx.throw(403);
|
|
105
|
-
}
|
|
106
117
|
const filter = ctx.action.params.filter || {};
|
|
107
118
|
ctx.action.mergeParams({
|
|
108
119
|
filter: {
|
|
@@ -117,9 +128,6 @@ var aiConversations_default = {
|
|
|
117
128
|
async unreadCount(ctx, next) {
|
|
118
129
|
var _a;
|
|
119
130
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
120
|
-
if (!userId) {
|
|
121
|
-
return ctx.throw(403);
|
|
122
|
-
}
|
|
123
131
|
const count = await ctx.db.getModel("aiConversations").count({
|
|
124
132
|
where: {
|
|
125
133
|
userId,
|
|
@@ -136,9 +144,6 @@ var aiConversations_default = {
|
|
|
136
144
|
async unreadCounts(ctx, next) {
|
|
137
145
|
var _a;
|
|
138
146
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
139
|
-
if (!userId) {
|
|
140
|
-
return ctx.throw(403);
|
|
141
|
-
}
|
|
142
147
|
const [conversationUnreadCount, workflowTaskUnreadCount] = await Promise.all([
|
|
143
148
|
ctx.db.getModel("aiConversations").count({
|
|
144
149
|
where: {
|
|
@@ -165,9 +170,6 @@ var aiConversations_default = {
|
|
|
165
170
|
var _a;
|
|
166
171
|
const plugin = ctx.app.pm.get("ai");
|
|
167
172
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
168
|
-
if (!userId) {
|
|
169
|
-
return ctx.throw(403);
|
|
170
|
-
}
|
|
171
173
|
const { aiEmployee, systemMessage, skillSettings, conversationSettings, modelSettings } = ctx.action.params.values || {};
|
|
172
174
|
const employee = await getAIEmployee(ctx, aiEmployee.username);
|
|
173
175
|
if (!employee) {
|
|
@@ -196,9 +198,6 @@ var aiConversations_default = {
|
|
|
196
198
|
var _a;
|
|
197
199
|
const plugin = ctx.app.pm.get("ai");
|
|
198
200
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
199
|
-
if (!userId) {
|
|
200
|
-
return ctx.throw(403);
|
|
201
|
-
}
|
|
202
201
|
const { filterByTk: sessionId } = ctx.action.params;
|
|
203
202
|
const { title } = ctx.action.params.values || {};
|
|
204
203
|
ctx.body = await plugin.aiConversationsManager.update({ userId, sessionId, title });
|
|
@@ -208,9 +207,6 @@ var aiConversations_default = {
|
|
|
208
207
|
var _a;
|
|
209
208
|
const plugin = ctx.app.pm.get("ai");
|
|
210
209
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
211
|
-
if (!userId) {
|
|
212
|
-
return ctx.throw(403);
|
|
213
|
-
}
|
|
214
210
|
const { filterByTk: sessionId } = ctx.action.params;
|
|
215
211
|
if (!sessionId) {
|
|
216
212
|
return ctx.throw(400, "invalid sessionId");
|
|
@@ -236,9 +232,6 @@ var aiConversations_default = {
|
|
|
236
232
|
async destroy(ctx, next) {
|
|
237
233
|
var _a;
|
|
238
234
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
239
|
-
if (!userId) {
|
|
240
|
-
return ctx.throw(403);
|
|
241
|
-
}
|
|
242
235
|
ctx.action.mergeParams({
|
|
243
236
|
filter: {
|
|
244
237
|
userId
|
|
@@ -250,9 +243,6 @@ var aiConversations_default = {
|
|
|
250
243
|
var _a, _b;
|
|
251
244
|
const plugin = ctx.app.pm.get("ai");
|
|
252
245
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
253
|
-
if (!userId) {
|
|
254
|
-
return ctx.throw(403);
|
|
255
|
-
}
|
|
256
246
|
const { sessionId, cursor, updateRead: originalUpdateRead } = ctx.action.params || {};
|
|
257
247
|
if (!sessionId) {
|
|
258
248
|
ctx.throw(400);
|
|
@@ -279,9 +269,6 @@ var aiConversations_default = {
|
|
|
279
269
|
var _a;
|
|
280
270
|
const plugin = ctx.app.pm.get("ai");
|
|
281
271
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
282
|
-
if (!userId) {
|
|
283
|
-
return ctx.throw(403);
|
|
284
|
-
}
|
|
285
272
|
const {
|
|
286
273
|
sessionId,
|
|
287
274
|
messageId,
|
|
@@ -320,11 +307,8 @@ var aiConversations_default = {
|
|
|
320
307
|
},
|
|
321
308
|
async sendMessages(ctx, next) {
|
|
322
309
|
var _a, _b, _c, _d;
|
|
323
|
-
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
324
|
-
if (!userId) {
|
|
325
|
-
return ctx.throw(403);
|
|
326
|
-
}
|
|
327
310
|
const plugin = ctx.app.pm.get("ai");
|
|
311
|
+
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
328
312
|
const {
|
|
329
313
|
sessionId,
|
|
330
314
|
aiEmployee: employeeName,
|
|
@@ -338,38 +322,27 @@ var aiConversations_default = {
|
|
|
338
322
|
if (shouldStream) {
|
|
339
323
|
setupSSEHeaders(ctx);
|
|
340
324
|
}
|
|
341
|
-
|
|
342
|
-
if (
|
|
343
|
-
|
|
344
|
-
} else {
|
|
345
|
-
ctx.status = 400;
|
|
346
|
-
ctx.body = { error: "sessionId is required" };
|
|
325
|
+
try {
|
|
326
|
+
if (!sessionId) {
|
|
327
|
+
throw new import_utils.ResourceActionError(400, ctx.t("sessionId is required"));
|
|
347
328
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
if (
|
|
353
|
-
|
|
354
|
-
} else {
|
|
355
|
-
ctx.status = 400;
|
|
356
|
-
ctx.body = { error: "user message is required" };
|
|
329
|
+
if (!Array.isArray(messages)) {
|
|
330
|
+
throw new import_utils.ResourceActionError(400, ctx.t("messages must be an array"));
|
|
331
|
+
}
|
|
332
|
+
const userMessage = messages.find((message) => message.role === "user");
|
|
333
|
+
if (!userMessage) {
|
|
334
|
+
throw new import_utils.ResourceActionError(400, ctx.t("user message is required"));
|
|
357
335
|
}
|
|
358
|
-
return next();
|
|
359
|
-
}
|
|
360
|
-
try {
|
|
361
336
|
const conversation = await plugin.aiConversationsManager.getConversation({
|
|
362
337
|
sessionId,
|
|
363
338
|
userId
|
|
364
339
|
});
|
|
365
340
|
if (!conversation) {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
}
|
|
372
|
-
return next();
|
|
341
|
+
throw new import_utils.ResourceActionError(400, ctx.t("conversation not found"));
|
|
342
|
+
}
|
|
343
|
+
const employee = await getAIEmployee(ctx, employeeName);
|
|
344
|
+
if (!employee) {
|
|
345
|
+
throw new import_utils.ResourceActionError(400, ctx.t("AI employee not found"));
|
|
373
346
|
}
|
|
374
347
|
if (!conversation.title) {
|
|
375
348
|
const textUserMessage = messages.find(
|
|
@@ -384,15 +357,9 @@ var aiConversations_default = {
|
|
|
384
357
|
await conversation.save();
|
|
385
358
|
}
|
|
386
359
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
sendErrorResponse(ctx, "AI employee not found");
|
|
391
|
-
} else {
|
|
392
|
-
ctx.status = 404;
|
|
393
|
-
ctx.body = { error: "AI employee not found" };
|
|
394
|
-
}
|
|
395
|
-
return next();
|
|
360
|
+
if (await isReachParallelLimit(ctx)) {
|
|
361
|
+
await saveUserMessages(ctx, sessionId, messages, editingMessageId);
|
|
362
|
+
throw new import_utils.ResourceActionError(400, ctx.t("There are conversations in progress. Please try again later."));
|
|
396
363
|
}
|
|
397
364
|
const legacy = conversation.thread === 0;
|
|
398
365
|
const resolvedModel = await plugin.aiEmployeesManager.resolveModel(employee, model);
|
|
@@ -442,11 +409,19 @@ var aiConversations_default = {
|
|
|
442
409
|
}
|
|
443
410
|
} catch (err) {
|
|
444
411
|
ctx.log.error(err);
|
|
412
|
+
let status = 500;
|
|
413
|
+
let message = ctx.t("Server unexpected error occur");
|
|
414
|
+
if (err instanceof import_utils.ResourceActionError) {
|
|
415
|
+
status = err.status;
|
|
416
|
+
message = err.message;
|
|
417
|
+
} else if (err instanceof Error) {
|
|
418
|
+
status = 500;
|
|
419
|
+
message = err.message;
|
|
420
|
+
}
|
|
445
421
|
if (shouldStream) {
|
|
446
|
-
sendErrorResponse(ctx,
|
|
422
|
+
sendErrorResponse(ctx, message);
|
|
447
423
|
} else {
|
|
448
|
-
ctx.status
|
|
449
|
-
ctx.body = { error: err.message || "Tool call error" };
|
|
424
|
+
ctx.throw(status, message);
|
|
450
425
|
}
|
|
451
426
|
} finally {
|
|
452
427
|
await next();
|
|
@@ -455,9 +430,6 @@ var aiConversations_default = {
|
|
|
455
430
|
async abort(ctx, next) {
|
|
456
431
|
var _a;
|
|
457
432
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
458
|
-
if (!userId) {
|
|
459
|
-
return ctx.throw(403);
|
|
460
|
-
}
|
|
461
433
|
const { sessionId } = ctx.action.params.values || {};
|
|
462
434
|
const plugin = ctx.app.pm.get("ai");
|
|
463
435
|
const conversation = await plugin.aiConversationsManager.getConversation({
|
|
@@ -474,30 +446,44 @@ var aiConversations_default = {
|
|
|
474
446
|
var _a, _b, _c, _d, _e;
|
|
475
447
|
const plugin = ctx.app.pm.get("ai");
|
|
476
448
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
449
|
+
const abortController = new AbortController();
|
|
450
|
+
const abortStream = () => abortController.abort();
|
|
451
|
+
const shouldStopStream = () => abortController.signal.aborted || ctx.res.destroyed || ctx.res.writableEnded;
|
|
480
452
|
setupSSEHeaders(ctx);
|
|
481
453
|
const sessionId = ((_b = ctx.action.params) == null ? void 0 : _b.sessionId) || ((_d = (_c = ctx.action.params) == null ? void 0 : _c.values) == null ? void 0 : _d.sessionId) || ((_e = ctx.action.params) == null ? void 0 : _e.filterByTk);
|
|
482
454
|
if (!sessionId) {
|
|
483
455
|
sendErrorResponse(ctx, "sessionId is required");
|
|
484
456
|
return;
|
|
485
457
|
}
|
|
458
|
+
ctx.req.once("aborted", abortStream);
|
|
459
|
+
ctx.res.once("close", abortStream);
|
|
486
460
|
try {
|
|
487
461
|
const conversation = await plugin.aiConversationsManager.getConversation({
|
|
488
462
|
sessionId,
|
|
489
463
|
userId
|
|
490
464
|
});
|
|
465
|
+
if (shouldStopStream()) {
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
491
468
|
if (!conversation) {
|
|
492
469
|
sendErrorResponse(ctx, "conversation not found");
|
|
493
470
|
return;
|
|
494
471
|
}
|
|
472
|
+
const reachLimit = await isReachParallelLimit(ctx);
|
|
473
|
+
if (shouldStopStream()) {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
495
476
|
let hasChunks = false;
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
477
|
+
if (!reachLimit) {
|
|
478
|
+
for await (const chunk of plugin.llmStreamCachedManager.getCached(sessionId).stream({ signal: abortController.signal })) {
|
|
479
|
+
if (shouldStopStream()) {
|
|
480
|
+
break;
|
|
481
|
+
}
|
|
482
|
+
hasChunks = true;
|
|
483
|
+
ctx.res.write(chunk);
|
|
484
|
+
}
|
|
499
485
|
}
|
|
500
|
-
if (!hasChunks) {
|
|
486
|
+
if (!hasChunks && !shouldStopStream()) {
|
|
501
487
|
const currentConversation = await plugin.aiConversationsManager.getConversation({
|
|
502
488
|
sessionId,
|
|
503
489
|
userId
|
|
@@ -510,11 +496,16 @@ var aiConversations_default = {
|
|
|
510
496
|
}
|
|
511
497
|
}
|
|
512
498
|
} catch (err) {
|
|
499
|
+
if (shouldStopStream()) {
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
513
502
|
ctx.log.error(err);
|
|
514
503
|
sendErrorResponse(ctx, err.message || "Resume stream error");
|
|
515
504
|
return;
|
|
516
505
|
} finally {
|
|
517
|
-
|
|
506
|
+
ctx.req.off("aborted", abortStream);
|
|
507
|
+
ctx.res.off("close", abortStream);
|
|
508
|
+
if (!shouldStopStream()) {
|
|
518
509
|
ctx.res.end();
|
|
519
510
|
}
|
|
520
511
|
await next();
|
|
@@ -524,24 +515,26 @@ var aiConversations_default = {
|
|
|
524
515
|
var _a, _b, _c, _d;
|
|
525
516
|
const plugin = ctx.app.pm.get("ai");
|
|
526
517
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
527
|
-
|
|
528
|
-
return ctx.throw(403);
|
|
529
|
-
}
|
|
530
|
-
setupSSEHeaders(ctx);
|
|
531
|
-
const { sessionId, webSearch, model } = ctx.action.params.values || {};
|
|
518
|
+
const { sessionId, webSearch, model, stream = true } = ctx.action.params.values || {};
|
|
532
519
|
let { messageId } = ctx.action.params.values || {};
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
520
|
+
const shouldStream = stream !== false;
|
|
521
|
+
if (shouldStream) {
|
|
522
|
+
setupSSEHeaders(ctx);
|
|
536
523
|
}
|
|
537
524
|
try {
|
|
525
|
+
if (!sessionId) {
|
|
526
|
+
throw new import_utils.ResourceActionError(400, ctx.t("sessionId is required"));
|
|
527
|
+
}
|
|
538
528
|
const conversation = await plugin.aiConversationsManager.getConversation({
|
|
539
529
|
sessionId,
|
|
540
530
|
userId
|
|
541
531
|
});
|
|
542
532
|
if (!conversation) {
|
|
543
|
-
|
|
544
|
-
|
|
533
|
+
throw new import_utils.ResourceActionError(400, ctx.t("conversation not found"));
|
|
534
|
+
}
|
|
535
|
+
const employee = await getAIEmployee(ctx, conversation.aiEmployeeUsername);
|
|
536
|
+
if (!employee) {
|
|
537
|
+
throw new import_utils.ResourceActionError(400, ctx.t("AI employee not found"));
|
|
545
538
|
}
|
|
546
539
|
const resendMessages = [];
|
|
547
540
|
if (messageId) {
|
|
@@ -551,8 +544,7 @@ var aiConversations_default = {
|
|
|
551
544
|
}
|
|
552
545
|
});
|
|
553
546
|
if (!message) {
|
|
554
|
-
|
|
555
|
-
return next();
|
|
547
|
+
throw new import_utils.ResourceActionError(400, ctx.t("message not found"));
|
|
556
548
|
}
|
|
557
549
|
} else {
|
|
558
550
|
const message = await ctx.db.getRepository("aiConversations.messages", sessionId).findOne({
|
|
@@ -562,8 +554,7 @@ var aiConversations_default = {
|
|
|
562
554
|
sort: ["-messageId"]
|
|
563
555
|
});
|
|
564
556
|
if (!message) {
|
|
565
|
-
|
|
566
|
-
return next();
|
|
557
|
+
throw new import_utils.ResourceActionError(400, ctx.t("message not found"));
|
|
567
558
|
}
|
|
568
559
|
messageId = message.messageId;
|
|
569
560
|
if (["user", "tool"].includes(message.role)) {
|
|
@@ -577,10 +568,8 @@ var aiConversations_default = {
|
|
|
577
568
|
});
|
|
578
569
|
}
|
|
579
570
|
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
sendErrorResponse(ctx, "AI employee not found");
|
|
583
|
-
return next();
|
|
571
|
+
if (await isReachParallelLimit(ctx)) {
|
|
572
|
+
throw new import_utils.ResourceActionError(400, ctx.t("There are conversations in progress. Please try again later."));
|
|
584
573
|
}
|
|
585
574
|
const resolvedModel = await plugin.aiEmployeesManager.resolveModel(employee, model);
|
|
586
575
|
const aiEmployee = new import_ai_employee.AIEmployee({
|
|
@@ -593,20 +582,38 @@ var aiConversations_default = {
|
|
|
593
582
|
webSearch,
|
|
594
583
|
model: resolvedModel
|
|
595
584
|
});
|
|
596
|
-
|
|
585
|
+
if (shouldStream) {
|
|
586
|
+
await aiEmployee.stream({ messageId, userMessages: resendMessages.length ? resendMessages : void 0 });
|
|
587
|
+
} else {
|
|
588
|
+
ctx.body = await aiEmployee.invoke({
|
|
589
|
+
messageId,
|
|
590
|
+
userMessages: resendMessages.length ? resendMessages : void 0
|
|
591
|
+
});
|
|
592
|
+
}
|
|
597
593
|
} catch (err) {
|
|
598
594
|
ctx.log.error(err);
|
|
599
|
-
|
|
595
|
+
let status = 500;
|
|
596
|
+
let message = ctx.t("Server unexpected error occur");
|
|
597
|
+
if (err instanceof import_utils.ResourceActionError) {
|
|
598
|
+
status = err.status;
|
|
599
|
+
message = err.message;
|
|
600
|
+
} else if (err instanceof Error) {
|
|
601
|
+
status = 500;
|
|
602
|
+
message = err.message;
|
|
603
|
+
}
|
|
604
|
+
if (shouldStream) {
|
|
605
|
+
sendErrorResponse(ctx, message);
|
|
606
|
+
} else {
|
|
607
|
+
ctx.throw(status, message);
|
|
608
|
+
}
|
|
609
|
+
} finally {
|
|
610
|
+
await next();
|
|
600
611
|
}
|
|
601
|
-
await next();
|
|
602
612
|
},
|
|
603
613
|
async updateUserDecision(ctx, next) {
|
|
604
614
|
var _a;
|
|
605
615
|
const plugin = ctx.app.pm.get("ai");
|
|
606
616
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
607
|
-
if (!userId) {
|
|
608
|
-
return ctx.throw(403);
|
|
609
|
-
}
|
|
610
617
|
const { sessionId, messageId, toolCallId, userDecision } = ctx.action.params.values || {};
|
|
611
618
|
if (!sessionId) {
|
|
612
619
|
ctx.throw(400);
|
|
@@ -686,9 +693,6 @@ var aiConversations_default = {
|
|
|
686
693
|
async resumeToolCall(ctx, next) {
|
|
687
694
|
var _a, _b, _c, _d;
|
|
688
695
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
689
|
-
if (!userId) {
|
|
690
|
-
return ctx.throw(403);
|
|
691
|
-
}
|
|
692
696
|
setupSSEHeaders(ctx);
|
|
693
697
|
const plugin = ctx.app.pm.get("ai");
|
|
694
698
|
const { sessionId, messageId, model, webSearch } = ctx.action.params.values || {};
|
package/dist/server/utils.d.ts
CHANGED
|
@@ -21,3 +21,7 @@ export declare function encodeLocalFile(url: string): Promise<string>;
|
|
|
21
21
|
export declare function encodeFile(ctx: Context, url: string): Promise<string>;
|
|
22
22
|
export declare function parseVariables(ctx: Context, value: string): Promise<any>;
|
|
23
23
|
export declare const buildTool: (toolsEntry: ToolsEntry) => import("@langchain/core/dist/tools").DynamicTool<any>;
|
|
24
|
+
export declare class ResourceActionError extends Error {
|
|
25
|
+
readonly status: number;
|
|
26
|
+
constructor(status: number, message: string, options?: ErrorOptions);
|
|
27
|
+
}
|
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
|
+
ResourceActionError: () => ResourceActionError,
|
|
39
40
|
buildTool: () => buildTool,
|
|
40
41
|
encodeFile: () => encodeFile,
|
|
41
42
|
encodeLocalFile: () => encodeLocalFile,
|
|
@@ -179,8 +180,16 @@ const buildTool = (toolsEntry) => {
|
|
|
179
180
|
}
|
|
180
181
|
);
|
|
181
182
|
};
|
|
183
|
+
class ResourceActionError extends Error {
|
|
184
|
+
constructor(status, message, options) {
|
|
185
|
+
super(message, options);
|
|
186
|
+
this.status = status;
|
|
187
|
+
this.name = "ResourceActionError";
|
|
188
|
+
}
|
|
189
|
+
}
|
|
182
190
|
// Annotate the CommonJS export names for ESM import in node:
|
|
183
191
|
0 && (module.exports = {
|
|
192
|
+
ResourceActionError,
|
|
184
193
|
buildTool,
|
|
185
194
|
encodeFile,
|
|
186
195
|
encodeLocalFile,
|
|
@@ -103,13 +103,12 @@ ${typeof message.system === "object" ? JSON.stringify(message.system) : message.
|
|
|
103
103
|
});
|
|
104
104
|
let currentRoles = (_a = input == null ? void 0 : input.result) == null ? void 0 : _a.roleName;
|
|
105
105
|
if (!currentRoles) {
|
|
106
|
-
const
|
|
106
|
+
const roles = await this.workflow.db.getRepository("rolesUsers").find({
|
|
107
107
|
filter: {
|
|
108
|
-
userId: ((_c = (_b = input == null ? void 0 : input.result) == null ? void 0 : _b.user) == null ? void 0 : _c.id) ?? userId
|
|
109
|
-
default: true
|
|
108
|
+
userId: ((_c = (_b = input == null ? void 0 : input.result) == null ? void 0 : _b.user) == null ? void 0 : _c.id) ?? userId
|
|
110
109
|
}
|
|
111
110
|
});
|
|
112
|
-
currentRoles =
|
|
111
|
+
currentRoles = roles.map((x) => x.roleName);
|
|
113
112
|
}
|
|
114
113
|
const employee = await this.workflow.db.getRepository("aiEmployees").findOne({
|
|
115
114
|
filter: {
|
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-beta.
|
|
9
|
+
"version": "2.1.0-beta.34",
|
|
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",
|
|
@@ -64,5 +64,5 @@
|
|
|
64
64
|
"keywords": [
|
|
65
65
|
"AI"
|
|
66
66
|
],
|
|
67
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "ca804833299c547f8d49f8d58f73273a4bfcd03c"
|
|
68
68
|
}
|