@nocobase/plugin-ai 2.1.0-alpha.20 → 2.1.0-alpha.21

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 (96) hide show
  1. package/dist/ai/tools/knowledge-base-retrieve.d.ts +10 -0
  2. package/dist/ai/tools/knowledge-base-retrieve.js +94 -0
  3. package/dist/client/486.77c26e2e7f8daf28.js +10 -0
  4. package/dist/client/646.ef9d7c2ea8641044.js +10 -0
  5. package/dist/client/ai-employees/chatbox/AIEmployeeSwitch.d.ts +3 -1
  6. package/dist/client/ai-employees/chatbox/HintMessageHeader.d.ts +10 -0
  7. package/dist/client/ai-employees/chatbox/ModelSwitcher.d.ts +3 -1
  8. package/dist/client/ai-employees/chatbox/SearchSwitch.d.ts +3 -1
  9. package/dist/client/ai-employees/chatbox/Upload.d.ts +3 -1
  10. package/dist/client/ai-employees/chatbox/conversations/ConversationsList.d.ts +27 -0
  11. package/dist/client/ai-employees/chatbox/conversations/WorkflowTasksList.d.ts +31 -0
  12. package/dist/client/ai-employees/chatbox/conversations/common.d.ts +43 -0
  13. package/dist/{server/document-loader/loader.worker.d.ts → client/ai-employees/chatbox/conversations/index.d.ts} +1 -1
  14. package/dist/client/ai-employees/chatbox/hooks/useWorkflowTasks.d.ts +24 -0
  15. package/dist/client/ai-employees/chatbox/stores/chat-box.d.ts +8 -0
  16. package/dist/client/ai-employees/chatbox/stores/chat-conversations.d.ts +4 -0
  17. package/dist/client/ai-employees/chatbox/stores/workflow-tasks.d.ts +41 -0
  18. package/dist/client/ai-employees/workflow-tasks/tools/index.d.ts +10 -0
  19. package/dist/client/ai-employees/workflow-tasks/ui/WorkflowTaskOutputCard.d.ts +11 -0
  20. package/dist/client/components/ListCollapse.d.ts +28 -0
  21. package/dist/client/index.js +7 -7
  22. package/dist/client/repositories/AIConfigRepository.d.ts +3 -2
  23. package/dist/client/workflow/nodes/employee/components/AIEmployeeSelect.d.ts +10 -0
  24. package/dist/client/workflow/nodes/employee/components/assigness.d.ts +11 -0
  25. package/dist/client/workflow/nodes/employee/components/file-inputs.d.ts +10 -0
  26. package/dist/client/workflow/nodes/employee/components/message-inputs.d.ts +12 -0
  27. package/dist/client/workflow/nodes/employee/components/model-options.d.ts +10 -0
  28. package/dist/client/workflow/nodes/employee/components/skill-settings.d.ts +10 -0
  29. package/dist/client/workflow/nodes/employee/components/structured-output.d.ts +10 -0
  30. package/dist/client/workflow/nodes/employee/components/users-select.d.ts +15 -0
  31. package/dist/client/workflow/nodes/employee/components/web-search-options.d.ts +10 -0
  32. package/dist/client/workflow/nodes/employee/configuration.d.ts +12 -0
  33. package/dist/client/workflow/nodes/employee/flow-models/feedback.d.ts +13 -0
  34. package/dist/client/workflow/nodes/employee/flow-models/task.d.ts +13 -0
  35. package/dist/client/workflow/nodes/employee/index.d.ts +7 -31
  36. package/dist/externalVersion.js +14 -15
  37. package/dist/locale/en-US.json +44 -1
  38. package/dist/locale/zh-CN.json +45 -1
  39. package/dist/node_modules/fast-glob/out/index.js +8 -8
  40. package/dist/node_modules/fast-glob/package.json +1 -1
  41. package/dist/node_modules/flexsearch/dist/flexsearch.bundle.min.js +2 -2
  42. package/dist/node_modules/flexsearch/package.json +1 -1
  43. package/dist/node_modules/fs-extra/lib/index.js +1 -1
  44. package/dist/node_modules/fs-extra/package.json +1 -1
  45. package/dist/node_modules/nodejs-snowflake/nodejs_snowflake.js +1 -1
  46. package/dist/node_modules/nodejs-snowflake/package.json +1 -1
  47. package/dist/node_modules/openai/index.js +1 -1
  48. package/dist/node_modules/openai/package.json +1 -1
  49. package/dist/node_modules/zod/index.cjs +1 -1
  50. package/dist/node_modules/zod/package.json +1 -1
  51. package/dist/server/ai-employees/ai-conversations.d.ts +10 -4
  52. package/dist/server/ai-employees/ai-conversations.js +52 -14
  53. package/dist/server/ai-employees/ai-employee.d.ts +8 -10
  54. package/dist/server/ai-employees/ai-employee.js +130 -145
  55. package/dist/server/ai-employees/ai-knowledge-base.d.ts +28 -0
  56. package/dist/server/ai-employees/ai-knowledge-base.js +167 -0
  57. package/dist/server/ai-employees/middleware/index.d.ts +1 -0
  58. package/dist/server/ai-employees/middleware/index.js +3 -1
  59. package/dist/server/ai-employees/middleware/workflow-history.d.ts +22 -0
  60. package/dist/server/ai-employees/middleware/workflow-history.js +173 -0
  61. package/dist/server/collections/ai-conversations.js +12 -0
  62. package/dist/server/collections/ai-workflow-tasks.d.ts +10 -0
  63. package/dist/server/collections/ai-workflow-tasks.js +112 -0
  64. package/dist/server/collections/users-ai-workflow-tasks.d.ts +10 -0
  65. package/dist/server/collections/users-ai-workflow-tasks.js +44 -0
  66. package/dist/server/document-loader/constants.d.ts +1 -2
  67. package/dist/server/document-loader/constants.js +6 -1
  68. package/dist/server/document-loader/loader.d.ts +0 -1
  69. package/dist/server/document-loader/loader.js +2 -55
  70. package/dist/server/document-loader/types.d.ts +0 -1
  71. package/dist/server/llm-providers/provider.js +1 -1
  72. package/dist/server/manager/built-in-manager.js +5 -4
  73. package/dist/server/plugin.d.ts +2 -0
  74. package/dist/server/plugin.js +10 -0
  75. package/dist/server/resource/aiConversations.js +29 -35
  76. package/dist/server/resource/aiWorkflowTasks.d.ts +12 -0
  77. package/dist/server/resource/aiWorkflowTasks.js +290 -0
  78. package/dist/server/utils.js +3 -2
  79. package/dist/server/workflow/nodes/employee/files.d.ts +16 -0
  80. package/dist/server/workflow/nodes/employee/files.js +125 -0
  81. package/dist/server/workflow/nodes/employee/handler.d.ts +11 -0
  82. package/dist/server/workflow/nodes/employee/handler.js +107 -0
  83. package/dist/server/workflow/nodes/employee/index.d.ts +17 -0
  84. package/dist/server/workflow/nodes/employee/index.js +391 -0
  85. package/dist/server/workflow/nodes/employee/tools.d.ts +12 -0
  86. package/dist/server/workflow/nodes/employee/tools.js +133 -0
  87. package/dist/server/workflow/nodes/employee/types.d.ts +35 -0
  88. package/dist/server/workflow/nodes/employee/types.js +24 -0
  89. package/dist/server/workflow/utils.d.ts +14 -0
  90. package/dist/server/workflow/utils.js +111 -0
  91. package/package.json +2 -2
  92. package/dist/client/30.4f30511a3059c422.js +0 -10
  93. package/dist/server/document-loader/loader.worker.js +0 -68
  94. package/dist/server/document-loader/vendor/langchain/document_loaders/fs/text.d.ts +0 -20
  95. package/dist/server/document-loader/vendor/langchain/document_loaders/fs/text.js +0 -96
  96. /package/dist/client/ai-employees/chatbox/{Conversations.d.ts → conversations/Conversations.d.ts} +0 -0
@@ -80,7 +80,8 @@ var aiConversations_default = {
80
80
  filter: {
81
81
  ...filter,
82
82
  userId,
83
- from: filter.from ?? "main-agent"
83
+ from: filter.from ?? "main-agent",
84
+ category: "chat"
84
85
  }
85
86
  });
86
87
  return import_actions.default.list(ctx, next);
@@ -198,6 +199,7 @@ var aiConversations_default = {
198
199
  },
199
200
  async updateToolArgs(ctx, next) {
200
201
  var _a;
202
+ const plugin = ctx.app.pm.get("ai");
201
203
  const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
202
204
  if (!userId) {
203
205
  return ctx.throw(403);
@@ -210,11 +212,9 @@ var aiConversations_default = {
210
212
  if (!sessionId) {
211
213
  ctx.throw(400);
212
214
  }
213
- const conversation = await ctx.db.getRepository("aiConversations").findOne({
214
- filter: {
215
- sessionId,
216
- userId
217
- }
215
+ const conversation = await plugin.aiConversationsManager.getConversation({
216
+ sessionId,
217
+ userId
218
218
  });
219
219
  if (!conversation) {
220
220
  ctx.throw(400);
@@ -241,7 +241,7 @@ var aiConversations_default = {
241
241
  await next();
242
242
  },
243
243
  async sendMessages(ctx, next) {
244
- var _a, _b, _c;
244
+ var _a, _b, _c, _d;
245
245
  const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
246
246
  if (!userId) {
247
247
  return ctx.throw(403);
@@ -280,11 +280,9 @@ var aiConversations_default = {
280
280
  return next();
281
281
  }
282
282
  try {
283
- const conversation = await ctx.db.getRepository("aiConversations").findOne({
284
- filter: {
285
- sessionId,
286
- userId
287
- }
283
+ const conversation = await plugin.aiConversationsManager.getConversation({
284
+ sessionId,
285
+ userId
288
286
  });
289
287
  if (!conversation) {
290
288
  if (shouldStream) {
@@ -325,6 +323,7 @@ var aiConversations_default = {
325
323
  sessionId,
326
324
  systemMessage: (_b = conversation.options) == null ? void 0 : _b.systemMessage,
327
325
  skillSettings: (_c = conversation.options) == null ? void 0 : _c.skillSettings,
326
+ tools: (_d = conversation.options) == null ? void 0 : _d.tools,
328
327
  webSearch,
329
328
  model,
330
329
  legacy
@@ -382,11 +381,9 @@ var aiConversations_default = {
382
381
  }
383
382
  const { sessionId } = ctx.action.params.values || {};
384
383
  const plugin = ctx.app.pm.get("ai");
385
- const conversation = await ctx.db.getRepository("aiConversations").findOne({
386
- filter: {
387
- sessionId,
388
- userId
389
- }
384
+ const conversation = await plugin.aiConversationsManager.getConversation({
385
+ sessionId,
386
+ userId
390
387
  });
391
388
  if (!conversation) {
392
389
  ctx.throw(404, "conversation not found");
@@ -395,7 +392,8 @@ var aiConversations_default = {
395
392
  await next();
396
393
  },
397
394
  async resendMessages(ctx, next) {
398
- var _a, _b, _c;
395
+ var _a, _b, _c, _d;
396
+ const plugin = ctx.app.pm.get("ai");
399
397
  const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
400
398
  if (!userId) {
401
399
  return ctx.throw(403);
@@ -408,11 +406,9 @@ var aiConversations_default = {
408
406
  return next();
409
407
  }
410
408
  try {
411
- const conversation = await ctx.db.getRepository("aiConversations").findOne({
412
- filter: {
413
- sessionId,
414
- userId
415
- }
409
+ const conversation = await plugin.aiConversationsManager.getConversation({
410
+ sessionId,
411
+ userId
416
412
  });
417
413
  if (!conversation) {
418
414
  sendErrorResponse(ctx, "conversation not found");
@@ -463,6 +459,7 @@ var aiConversations_default = {
463
459
  sessionId,
464
460
  systemMessage: (_b = conversation.options) == null ? void 0 : _b.systemMessage,
465
461
  skillSettings: (_c = conversation.options) == null ? void 0 : _c.skillSettings,
462
+ tools: (_d = conversation.options) == null ? void 0 : _d.tools,
466
463
  webSearch,
467
464
  model
468
465
  });
@@ -484,11 +481,9 @@ var aiConversations_default = {
484
481
  if (!sessionId) {
485
482
  ctx.throw(400);
486
483
  }
487
- const conversation = await ctx.db.getRepository("aiConversations").findOne({
488
- filter: {
489
- sessionId,
490
- userId
491
- }
484
+ const conversation = await plugin.aiConversationsManager.getConversation({
485
+ sessionId,
486
+ userId
492
487
  });
493
488
  if (!conversation) {
494
489
  ctx.throw(400);
@@ -539,7 +534,7 @@ var aiConversations_default = {
539
534
  const toolMessageMap = new Map(
540
535
  toolMessages.map((toolMessage) => [toolMessage.toolCallId, toolMessage])
541
536
  );
542
- const toolsList = await plugin.ai.toolsManager.listTools();
537
+ const toolsList = await plugin.ai.toolsManager.listTools({ sessionId: message.sessionId });
543
538
  const toolsMap = new Map(toolsList.map((t) => [t.definition.name, t]));
544
539
  for (const toolCall2 of toolCalls) {
545
540
  const tools = toolsMap.get(toolCall2.name);
@@ -559,7 +554,7 @@ var aiConversations_default = {
559
554
  await next();
560
555
  },
561
556
  async resumeToolCall(ctx, next) {
562
- var _a, _b, _c;
557
+ var _a, _b, _c, _d;
563
558
  const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
564
559
  if (!userId) {
565
560
  return ctx.throw(403);
@@ -572,11 +567,9 @@ var aiConversations_default = {
572
567
  return next();
573
568
  }
574
569
  try {
575
- const conversation = await ctx.db.getRepository("aiConversations").findOne({
576
- filter: {
577
- sessionId,
578
- userId
579
- }
570
+ const conversation = await plugin.aiConversationsManager.getConversation({
571
+ sessionId,
572
+ userId
580
573
  });
581
574
  if (!conversation) {
582
575
  sendErrorResponse(ctx, "conversation not found");
@@ -614,6 +607,7 @@ var aiConversations_default = {
614
607
  sessionId,
615
608
  systemMessage: (_b = conversation.options) == null ? void 0 : _b.systemMessage,
616
609
  skillSettings: (_c = conversation.options) == null ? void 0 : _c.skillSettings,
610
+ tools: (_d = conversation.options) == null ? void 0 : _d.tools,
617
611
  webSearch,
618
612
  model
619
613
  });
@@ -0,0 +1,12 @@
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 { ResourceOptions } from '@nocobase/resourcer';
10
+ export declare const parseAiWorkflowTaskListRecord: (record: any, userId: string | number, jobStatusMap: Map<string, number>) => any;
11
+ export declare const aiWorkflowTasks: ResourceOptions;
12
+ export default aiWorkflowTasks;
@@ -0,0 +1,290 @@
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 __create = Object.create;
11
+ var __defProp = Object.defineProperty;
12
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
13
+ var __getOwnPropNames = Object.getOwnPropertyNames;
14
+ var __getProtoOf = Object.getPrototypeOf;
15
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
16
+ var __export = (target, all) => {
17
+ for (var name in all)
18
+ __defProp(target, name, { get: all[name], enumerable: true });
19
+ };
20
+ var __copyProps = (to, from, except, desc) => {
21
+ if (from && typeof from === "object" || typeof from === "function") {
22
+ for (let key of __getOwnPropNames(from))
23
+ if (!__hasOwnProp.call(to, key) && key !== except)
24
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
25
+ }
26
+ return to;
27
+ };
28
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
29
+ // If the importer is in node compatibility mode or this is not an ESM
30
+ // file that has been converted to a CommonJS file using a Babel-
31
+ // compatible transform (i.e. "__esModule" has not been set), then set
32
+ // "default" to the CommonJS "module.exports" for node compatibility.
33
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
34
+ mod
35
+ ));
36
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
+ var aiWorkflowTasks_exports = {};
38
+ __export(aiWorkflowTasks_exports, {
39
+ aiWorkflowTasks: () => aiWorkflowTasks,
40
+ default: () => aiWorkflowTasks_default,
41
+ parseAiWorkflowTaskListRecord: () => parseAiWorkflowTaskListRecord
42
+ });
43
+ module.exports = __toCommonJS(aiWorkflowTasks_exports);
44
+ var import_actions = __toESM(require("@nocobase/actions"));
45
+ var import_plugin_workflow = require("@nocobase/plugin-workflow");
46
+ const parseAiWorkflowTaskListRecord = (record, userId, jobStatusMap) => {
47
+ var _a, _b;
48
+ const users = (record == null ? void 0 : record.users) || [];
49
+ const currentUser = users.find(
50
+ (user) => String(user == null ? void 0 : user.id) === String(userId)
51
+ );
52
+ return {
53
+ ...(record == null ? void 0 : record.toJSON()) ?? {},
54
+ read: ((_a = currentUser == null ? void 0 : currentUser.usersAiWorkflowTasks) == null ? void 0 : _a.read) ?? false,
55
+ jobStatus: jobStatusMap.get(String((record == null ? void 0 : record.jobId) ?? ((_b = record == null ? void 0 : record.get) == null ? void 0 : _b.call(record, "jobId")))) ?? import_plugin_workflow.JOB_STATUS.PENDING
56
+ };
57
+ };
58
+ const aiWorkflowTasks = {
59
+ name: "aiWorkflowTasks",
60
+ actions: {
61
+ list: async (ctx, next) => {
62
+ var _a;
63
+ const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
64
+ if (!userId) {
65
+ return ctx.throw(403);
66
+ }
67
+ const filter = ctx.action.params.filter || {};
68
+ const appends = Array.isArray(ctx.action.params.appends) ? ctx.action.params.appends : ctx.action.params.appends ? [ctx.action.params.appends] : [];
69
+ if (!appends.includes("users")) {
70
+ appends.push("users");
71
+ }
72
+ ctx.action.mergeParams({
73
+ filter: {
74
+ $and: [
75
+ filter,
76
+ {
77
+ "users.id": userId
78
+ }
79
+ ]
80
+ },
81
+ appends
82
+ });
83
+ await import_actions.default.list(ctx, async () => {
84
+ });
85
+ const jobIds = Array.from(
86
+ new Set(
87
+ (ctx.body.rows || []).map((record) => {
88
+ var _a2;
89
+ return (record == null ? void 0 : record.jobId) ?? ((_a2 = record == null ? void 0 : record.get) == null ? void 0 : _a2.call(record, "jobId"));
90
+ }).filter((jobId) => jobId != null)
91
+ )
92
+ );
93
+ const jobs = jobIds.length ? await ctx.db.getRepository("jobs").find({
94
+ filter: {
95
+ id: {
96
+ $in: jobIds
97
+ }
98
+ },
99
+ fields: ["id", "status"]
100
+ }) : [];
101
+ const jobStatusMap = new Map(
102
+ jobs.map((job) => {
103
+ var _a2, _b;
104
+ return [
105
+ String((job == null ? void 0 : job.id) ?? ((_a2 = job == null ? void 0 : job.get) == null ? void 0 : _a2.call(job, "id"))),
106
+ (job == null ? void 0 : job.status) ?? ((_b = job == null ? void 0 : job.get) == null ? void 0 : _b.call(job, "status")) ?? import_plugin_workflow.JOB_STATUS.PENDING
107
+ ];
108
+ })
109
+ );
110
+ ctx.body.rows = ctx.body.rows.map((record) => parseAiWorkflowTaskListRecord(record, userId, jobStatusMap));
111
+ await next();
112
+ },
113
+ unreadCount: async (ctx, next) => {
114
+ var _a;
115
+ const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
116
+ if (!userId) {
117
+ return ctx.throw(403);
118
+ }
119
+ const usersAiWorkflowTasksModel = ctx.db.getModel("usersAiWorkflowTasks");
120
+ const count = await usersAiWorkflowTasksModel.count({
121
+ where: {
122
+ userId,
123
+ read: false
124
+ }
125
+ });
126
+ ctx.body = {
127
+ count
128
+ };
129
+ await next();
130
+ },
131
+ getBySession: async (ctx, next) => {
132
+ var _a, _b, _c, _d, _e;
133
+ const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
134
+ if (!userId) {
135
+ return ctx.throw(403);
136
+ }
137
+ const sessionId = (_b = ctx.action.params.values) == null ? void 0 : _b.sessionId;
138
+ if (!sessionId) {
139
+ return ctx.throw(400, "sessionId is required");
140
+ }
141
+ const task = await ctx.db.getRepository("aiWorkflowTasks").findOne({
142
+ filter: {
143
+ sessionId,
144
+ "users.id": userId
145
+ }
146
+ });
147
+ if (!task) {
148
+ return ctx.throw(404, "workflow task not found");
149
+ }
150
+ const usersAiWorkflowTasks = await ctx.db.getModel("usersAiWorkflowTasks").findOne({
151
+ where: {
152
+ aiWorkflowTaskId: task.id,
153
+ userId
154
+ }
155
+ });
156
+ const node = await ctx.db.getRepository("flow_nodes").findOne({
157
+ filter: {
158
+ id: task.nodeId
159
+ }
160
+ });
161
+ const readonly = task.status !== "pending_approval" || task.acceptedUserId !== userId;
162
+ ctx.body = {
163
+ ...((_c = task == null ? void 0 : task.toJSON) == null ? void 0 : _c.call(task)) ?? task,
164
+ read: (usersAiWorkflowTasks == null ? void 0 : usersAiWorkflowTasks.read) ?? true,
165
+ config: (node == null ? void 0 : node.config) ?? null,
166
+ structuredOutputSchema: ((_e = (_d = node == null ? void 0 : node.config) == null ? void 0 : _d.structuredOutput) == null ? void 0 : _e.schema) ?? null,
167
+ readonly
168
+ };
169
+ await next();
170
+ },
171
+ accept: async (ctx, next) => {
172
+ var _a, _b;
173
+ const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
174
+ if (!userId) {
175
+ return ctx.throw(403);
176
+ }
177
+ const sessionId = (_b = ctx.action.params.values) == null ? void 0 : _b.sessionId;
178
+ if (!sessionId) {
179
+ return ctx.throw(400, "sessionId is required");
180
+ }
181
+ const task = await ctx.db.getRepository("aiWorkflowTasks").findOne({
182
+ filter: {
183
+ sessionId,
184
+ "users.id": userId
185
+ }
186
+ });
187
+ if (!task) {
188
+ return ctx.throw(404, "workflow task not found");
189
+ }
190
+ const aiWorkflowTasksModel = ctx.db.getModel("aiWorkflowTasks");
191
+ const [acceptedCount] = await aiWorkflowTasksModel.update(
192
+ {
193
+ acceptedUserId: userId,
194
+ status: "pending_approval"
195
+ },
196
+ {
197
+ where: {
198
+ id: task.id,
199
+ acceptedUserId: null,
200
+ status: "pending_acceptance"
201
+ }
202
+ }
203
+ );
204
+ const usersAiWorkflowTasksModel = ctx.db.getModel("usersAiWorkflowTasks");
205
+ const [readCount] = await usersAiWorkflowTasksModel.update(
206
+ {
207
+ read: true
208
+ },
209
+ {
210
+ where: {
211
+ aiWorkflowTaskId: task.id,
212
+ userId
213
+ }
214
+ }
215
+ );
216
+ const latestTask = await ctx.db.getRepository("aiWorkflowTasks").findOne({
217
+ filter: {
218
+ id: task.id
219
+ }
220
+ });
221
+ ctx.body = {
222
+ accepted: acceptedCount > 0,
223
+ readUpdated: readCount > 0,
224
+ acceptedUserId: (latestTask == null ? void 0 : latestTask.acceptedUserId) ?? null
225
+ };
226
+ await next();
227
+ },
228
+ reject: async (ctx, next) => {
229
+ var _a, _b, _c;
230
+ const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
231
+ if (!userId) {
232
+ return ctx.throw(403);
233
+ }
234
+ const id = (_b = ctx.action.params.values) == null ? void 0 : _b.id;
235
+ const result = (_c = ctx.action.params.values) == null ? void 0 : _c.result;
236
+ if (!id) {
237
+ return ctx.throw(400, "id is required");
238
+ }
239
+ if (!result) {
240
+ return ctx.throw(400, "result is required");
241
+ }
242
+ const task = await ctx.db.getRepository("aiWorkflowTasks").findOne({
243
+ filter: {
244
+ id,
245
+ "users.id": userId
246
+ }
247
+ });
248
+ if (!task) {
249
+ return ctx.throw(404, "workflow task not found");
250
+ }
251
+ if (task.status !== "pending_approval" || String(task.acceptedUserId) !== String(userId)) {
252
+ return ctx.throw(403);
253
+ }
254
+ const job = await ctx.db.getRepository("jobs").findOne({
255
+ filter: {
256
+ id: task.jobId
257
+ }
258
+ });
259
+ if (!job) {
260
+ return ctx.throw(404, "job not found");
261
+ }
262
+ await ctx.db.getRepository("aiWorkflowTasks").update({
263
+ values: {
264
+ status: "rejected"
265
+ },
266
+ filter: {
267
+ id: task.id,
268
+ acceptedUserId: userId,
269
+ status: "pending_approval"
270
+ }
271
+ });
272
+ await job.update({
273
+ status: import_plugin_workflow.JOB_STATUS.REJECTED,
274
+ result
275
+ });
276
+ const workflowPlugin = ctx.app.pm.get("workflow");
277
+ await workflowPlugin.resume(job);
278
+ ctx.body = {
279
+ status: "success"
280
+ };
281
+ await next();
282
+ }
283
+ }
284
+ };
285
+ var aiWorkflowTasks_default = aiWorkflowTasks;
286
+ // Annotate the CommonJS export names for ESM import in node:
287
+ 0 && (module.exports = {
288
+ aiWorkflowTasks,
289
+ parseAiWorkflowTaskListRecord
290
+ });
@@ -131,6 +131,7 @@ async function getUser(ctx, fields) {
131
131
  return user;
132
132
  }
133
133
  async function parseVariables(ctx, value) {
134
+ var _a, _b;
134
135
  const re = /\{\{\$user\.([^}]+)\}\}/g;
135
136
  const userFieldsSet = /* @__PURE__ */ new Set();
136
137
  const matches = value.matchAll(re);
@@ -144,7 +145,7 @@ async function parseVariables(ctx, value) {
144
145
  for (const [key, value2] of Object.entries(dateVariables)) {
145
146
  if (typeof value2 === "function") {
146
147
  $nDate[key] = value2({
147
- timezone: ctx.get("x-timezone"),
148
+ timezone: (_a = ctx.get) == null ? void 0 : _a.call(ctx, "x-timezone"),
148
149
  now: (/* @__PURE__ */ new Date()).toISOString()
149
150
  });
150
151
  } else {
@@ -154,7 +155,7 @@ async function parseVariables(ctx, value) {
154
155
  return (0, import_utils.parse)(value)({
155
156
  $user,
156
157
  $nRole: ctx.state.currentRole === "__union__" ? ctx.state.currentRoles : ctx.state.currentRole,
157
- $nLang: ctx.getCurrentLocale(),
158
+ $nLang: (_b = ctx.getCurrentLocale) == null ? void 0 : _b.call(ctx),
158
159
  $nDate
159
160
  });
160
161
  }
@@ -0,0 +1,16 @@
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 { AIEmployeeInstructionFiles } from './types';
10
+ import { Plugin } from '@nocobase/server';
11
+ export declare abstract class Files {
12
+ static resolvers(plugin: Plugin, attachmentPart: Record<string, any>): {
13
+ resolveAttachments: (files: AIEmployeeInstructionFiles[]) => Promise<void>;
14
+ resolveUrls: (files: AIEmployeeInstructionFiles[]) => Promise<void>;
15
+ };
16
+ }
@@ -0,0 +1,125 @@
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 __create = Object.create;
11
+ var __defProp = Object.defineProperty;
12
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
13
+ var __getOwnPropNames = Object.getOwnPropertyNames;
14
+ var __getProtoOf = Object.getPrototypeOf;
15
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
16
+ var __export = (target, all) => {
17
+ for (var name in all)
18
+ __defProp(target, name, { get: all[name], enumerable: true });
19
+ };
20
+ var __copyProps = (to, from, except, desc) => {
21
+ if (from && typeof from === "object" || typeof from === "function") {
22
+ for (let key of __getOwnPropNames(from))
23
+ if (!__hasOwnProp.call(to, key) && key !== except)
24
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
25
+ }
26
+ return to;
27
+ };
28
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
29
+ // If the importer is in node compatibility mode or this is not an ESM
30
+ // file that has been converted to a CommonJS file using a Babel-
31
+ // compatible transform (i.e. "__esModule" has not been set), then set
32
+ // "default" to the CommonJS "module.exports" for node compatibility.
33
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
34
+ mod
35
+ ));
36
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
+ var files_exports = {};
38
+ __export(files_exports, {
39
+ Files: () => Files
40
+ });
41
+ module.exports = __toCommonJS(files_exports);
42
+ var import_promises = __toESM(require("node:fs/promises"));
43
+ var import_node_os = __toESM(require("node:os"));
44
+ var import_node_path = __toESM(require("node:path"));
45
+ var import_lodash = __toESM(require("lodash"));
46
+ var import_axios = __toESM(require("axios"));
47
+ var import_utils = require("../../utils");
48
+ class Files {
49
+ static resolvers(plugin, attachmentPart) {
50
+ const resolveAttachments = async (files) => {
51
+ var _a;
52
+ const attachments = files.filter((it) => it.type === "file_id");
53
+ if (attachments.length) {
54
+ const attachmentGroup = import_lodash.default.groupBy(attachments, (it) => it.collection);
55
+ for (const collection of import_lodash.default.uniq(attachments.map((it) => it.collection))) {
56
+ const repository = plugin.db.getRepository(collection);
57
+ if (!repository) {
58
+ throw new Error(`Attachment collection [${collection}] not existed`);
59
+ }
60
+ const attachmentKeys = (_a = attachmentGroup[collection]) == null ? void 0 : _a.map((it) => it.value);
61
+ const attachmentModels = await repository.find({
62
+ filter: {
63
+ id: {
64
+ $in: attachmentKeys
65
+ }
66
+ }
67
+ });
68
+ if (!attachmentModels.length) {
69
+ throw new Error(`Attachment [${collection}] record not existed. Keys: [${attachmentKeys.join(",")}]`);
70
+ }
71
+ attachmentPart.attachments = [
72
+ ...attachmentPart.attachments ?? [],
73
+ ...attachmentModels.map((it) => it.toJSON())
74
+ ];
75
+ }
76
+ }
77
+ };
78
+ const resolveUrls = async (files) => {
79
+ var _a;
80
+ const urls = files.filter((it) => it.type === "file_url");
81
+ if (urls.length) {
82
+ const fileManager = plugin.pm.get("file-manager");
83
+ const settings = await plugin.db.getRepository("aiSettings").findOne();
84
+ const storageName = (_a = settings == null ? void 0 : settings.options) == null ? void 0 : _a.storage;
85
+ const attachments = await Promise.all(
86
+ urls.map(async ({ value: url }) => {
87
+ const response = await import_axios.default.get(url, {
88
+ responseType: "arraybuffer"
89
+ });
90
+ const contentType = (0, import_utils.resolveContentType)(response.headers);
91
+ const fileIdentity = (0, import_utils.resolveFileIdentity)(url, response.headers);
92
+ const tempFilePath = import_node_path.default.join(import_node_os.default.tmpdir(), `${Date.now()}-${import_lodash.default.random(1e9)}`);
93
+ await import_promises.default.writeFile(tempFilePath, response.data);
94
+ try {
95
+ const created = await fileManager.createFileRecord({
96
+ collectionName: "aiFiles",
97
+ filePath: tempFilePath,
98
+ storageName,
99
+ values: {
100
+ ...fileIdentity,
101
+ mimetype: contentType,
102
+ meta: {
103
+ sourceUrl: url
104
+ }
105
+ }
106
+ });
107
+ return created.toJSON();
108
+ } finally {
109
+ await import_promises.default.rm(tempFilePath, { force: true });
110
+ }
111
+ })
112
+ );
113
+ attachmentPart.attachments = [...attachmentPart.attachments ?? [], ...attachments];
114
+ }
115
+ };
116
+ return {
117
+ resolveAttachments,
118
+ resolveUrls
119
+ };
120
+ }
121
+ }
122
+ // Annotate the CommonJS export names for ESM import in node:
123
+ 0 && (module.exports = {
124
+ Files
125
+ });
@@ -0,0 +1,11 @@
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 PluginAIServer from '../../../plugin';
10
+ export declare const registerOnJobAbortedHandler: (plugin: PluginAIServer) => void;
11
+ export declare const registerAIEmployeeTaskNotification: (plugin: PluginAIServer) => void;