@nocobase/plugin-ai 2.1.0-alpha.34 → 2.1.0-alpha.35
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/client-v2.d.ts +1 -0
- package/client-v2.js +1 -0
- package/dist/ai/docs/nocobase/ai/index.md +1 -1
- package/dist/ai/docs/nocobase/ai-employees/built-in/atlas.md +24 -0
- package/dist/ai/docs/nocobase/ai-employees/built-in/dara.md +22 -0
- package/dist/ai/docs/nocobase/ai-employees/built-in/dex.md +32 -0
- package/dist/ai/docs/nocobase/ai-employees/built-in/ellis.md +22 -0
- package/dist/ai/docs/nocobase/ai-employees/built-in/index.md +25 -0
- package/dist/ai/docs/nocobase/ai-employees/built-in/lexi.md +26 -0
- package/dist/ai/docs/nocobase/ai-employees/built-in/lina.md +142 -0
- package/dist/ai/docs/nocobase/ai-employees/built-in/nathan.md +36 -0
- package/dist/ai/docs/nocobase/ai-employees/built-in/vera.md +22 -0
- package/dist/ai/docs/nocobase/ai-employees/built-in/viz.md +25 -0
- package/dist/ai/docs/nocobase/ai-employees/features/built-in-employee.md +1 -29
- package/dist/ai/docs/nocobase/ai-employees/features/collaborate.md +17 -7
- package/dist/ai/docs/nocobase/ai-employees/features/enable-ai-employee.md +4 -4
- package/dist/ai/docs/nocobase/ai-employees/features/model-settings.md +87 -0
- package/dist/ai/docs/nocobase/ai-employees/index.md +1 -1
- package/dist/ai/docs/nocobase/ai-employees/scenarios/localization-hy-mt.md +241 -0
- package/dist/ai/docs/nocobase/ai-employees/workflow/nodes/employee/configuration.md +1 -1
- package/dist/ai/docs/nocobase/cluster-mode/index.md +5 -1
- package/dist/ai/docs/nocobase/cluster-mode/preparations.md +58 -3
- package/dist/ai/docs/nocobase/get-started/deployment/how-to-deploy-nocobase-faster.mdx +384 -0
- package/dist/ai/docs/nocobase/get-started/upgrading/docker.md +1 -1
- package/dist/ai/docs/nocobase/interface-builder/actions/types/js-action.md +1 -1
- package/dist/ai/docs/nocobase/interface-builder/actions/types/js-item.md +1 -1
- package/dist/ai/docs/nocobase/interface-builder/blocks/other-blocks/js-block.md +1 -1
- package/dist/ai/docs/nocobase/interface-builder/fields/specific/js-column.md +1 -1
- package/dist/ai/docs/nocobase/interface-builder/fields/specific/js-field.md +1 -1
- package/dist/ai/docs/nocobase/interface-builder/fields/specific/js-item.md +1 -1
- package/dist/ai/docs/nocobase/security/guide.md +13 -1
- package/dist/ai/docs/nocobase/system-management/localization/index.md +25 -1
- package/dist/client/462.1708385b148779cd.js +10 -0
- package/dist/client/{559.39872901b9053629.js → 559.585f80c3bcea0bed.js} +1 -1
- package/dist/client/646.b0ed728921b007d4.js +10 -0
- package/dist/client/{927.ac9ee9a8c1cb4f1d.js → 927.d95c74ebb8fd51c9.js} +1 -1
- package/dist/client/ai-employees/admin/ModelSettings.d.ts +10 -0
- package/dist/client/ai-employees/admin/hooks.d.ts +1 -1
- package/dist/client/ai-employees/avatars.d.ts +9 -783
- package/dist/client/ai-employees/chatbox/model.d.ts +6 -3
- package/dist/client/ai-employees/types.d.ts +23 -0
- package/dist/client/features/vector-database-provider.d.ts +1 -1
- package/dist/client/index.js +4 -4
- package/dist/client/llm-services/component/EnabledModelsSelect.d.ts +1 -14
- package/dist/client-v2/ai-employees/AIEmployeeShortcut.d.ts +21 -0
- package/dist/client-v2/ai-employees/ProfileCard.d.ts +17 -0
- package/dist/client-v2/ai-employees/avatars.d.ts +783 -0
- package/dist/client-v2/ai-employees/types.d.ts +20 -0
- package/dist/client-v2/index.d.ts +17 -0
- package/dist/client-v2/index.js +10 -0
- package/dist/client-v2/llm-services/model-label.d.ts +22 -0
- package/dist/collections/ai-employees.d.ts +2 -1
- package/dist/collections/ai-employees.js +1 -1
- package/dist/externalVersion.js +17 -17
- package/dist/locale/en-US.json +15 -1
- package/dist/locale/zh-CN.json +15 -1
- 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-conversations.d.ts +1 -0
- package/dist/server/ai-employees/ai-conversations.js +4 -1
- package/dist/server/ai-employees/ai-employee.d.ts +15 -1
- package/dist/server/ai-employees/ai-employee.js +140 -9
- package/dist/server/ai-employees/ai-employees-manager.d.ts +4 -0
- package/dist/server/ai-employees/ai-employees-manager.js +41 -0
- package/dist/server/ai-employees/ai-knowledge-base.js +7 -7
- package/dist/server/ai-employees/middleware/conversation.d.ts +1 -0
- package/dist/server/ai-employees/middleware/conversation.js +4 -2
- package/dist/server/ai-employees/sub-agents/dispatcher.js +2 -4
- package/dist/server/ai-employees/utils.d.ts +6 -3
- package/dist/server/ai-employees/utils.js +7 -1
- package/dist/server/features/knowledge-base.d.ts +3 -2
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.js +3 -0
- package/dist/server/llm-providers/common/reasoning.d.ts +2 -0
- package/dist/server/llm-providers/common/reasoning.js +15 -2
- package/dist/server/llm-providers/dashscope.d.ts +2 -1
- package/dist/server/llm-providers/dashscope.js +39 -0
- package/dist/server/llm-providers/deepseek.js +2 -0
- package/dist/server/llm-providers/provider.d.ts +15 -1
- package/dist/server/llm-providers/provider.js +21 -2
- package/dist/server/manager/ai-chat-conversation.js +3 -4
- package/dist/server/manager/ai-manager.d.ts +17 -0
- package/dist/server/manager/ai-manager.js +65 -0
- 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.d.ts +14 -0
- package/dist/server/migrations/20260407170416-ai-employee-knowledge-base-add-key.js +61 -0
- package/dist/server/resource/ai.js +1 -41
- package/dist/server/resource/aiConversations.d.ts +12 -13
- package/dist/server/resource/aiConversations.js +129 -121
- package/dist/server/resource/aiEmployees.js +32 -1
- package/dist/server/types/knowledge-base.type.d.ts +3 -2
- package/dist/server/utils.d.ts +4 -0
- package/dist/server/utils.js +9 -0
- package/dist/server/workflow/nodes/employee/index.js +4 -2
- package/package.json +2 -2
- package/dist/client/343.6f36d97dd122c5b6.js +0 -10
- package/dist/client/646.5860101cb28c8272.js +0 -10
|
@@ -0,0 +1,61 @@
|
|
|
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 ai_employee_knowledge_base_add_key_exports = {};
|
|
28
|
+
__export(ai_employee_knowledge_base_add_key_exports, {
|
|
29
|
+
default: () => ai_employee_knowledge_base_add_key_default
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(ai_employee_knowledge_base_add_key_exports);
|
|
32
|
+
var import_server = require("@nocobase/server");
|
|
33
|
+
class ai_employee_knowledge_base_add_key_default extends import_server.Migration {
|
|
34
|
+
on = "afterSync";
|
|
35
|
+
// 'beforeLoad' or 'afterLoad'
|
|
36
|
+
appVersion = "<2.1.0";
|
|
37
|
+
async up() {
|
|
38
|
+
var _a, _b, _c, _d;
|
|
39
|
+
const aiEmployeesRepo = this.app.db.getRepository("aiEmployees");
|
|
40
|
+
const aiEmployeeList = await aiEmployeesRepo.find();
|
|
41
|
+
for (const item of aiEmployeeList) {
|
|
42
|
+
if (!((_b = (_a = item.knowledgeBase) == null ? void 0 : _a.knowledgeBaseIds) == null ? void 0 : _b.length)) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if ((_d = (_c = item.knowledgeBase) == null ? void 0 : _c.knowledgeBaseKeys) == null ? void 0 : _d.length) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
await aiEmployeesRepo.update({
|
|
49
|
+
values: {
|
|
50
|
+
knowledgeBase: {
|
|
51
|
+
...item.knowledgeBase,
|
|
52
|
+
knowledgeBaseKeys: item.knowledgeBase.knowledgeBaseIds.map((it) => String(it))
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
filter: {
|
|
56
|
+
username: item.username
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -40,7 +40,6 @@ __export(ai_exports, {
|
|
|
40
40
|
});
|
|
41
41
|
module.exports = __toCommonJS(ai_exports);
|
|
42
42
|
var import_lodash = __toESM(require("lodash"));
|
|
43
|
-
var import_recommended_models = require("../../common/recommended-models");
|
|
44
43
|
const aiResource = {
|
|
45
44
|
name: "ai",
|
|
46
45
|
actions: {
|
|
@@ -157,46 +156,7 @@ const aiResource = {
|
|
|
157
156
|
},
|
|
158
157
|
listAllEnabledModels: async (ctx, next) => {
|
|
159
158
|
const plugin = ctx.app.pm.get("ai");
|
|
160
|
-
|
|
161
|
-
const llmServices = services.filter((service) => service.enabled !== false).map((service) => {
|
|
162
|
-
const raw = service.enabledModels;
|
|
163
|
-
let enabledModels;
|
|
164
|
-
if (raw && typeof raw === "object" && !Array.isArray(raw) && raw.mode) {
|
|
165
|
-
if (raw.mode === "recommended") {
|
|
166
|
-
enabledModels = (0, import_recommended_models.getRecommendedModels)(service.provider);
|
|
167
|
-
} else {
|
|
168
|
-
enabledModels = (raw.models || []).filter((m) => m.value).map((m) => ({
|
|
169
|
-
label: m.label || m.value,
|
|
170
|
-
value: m.value
|
|
171
|
-
}));
|
|
172
|
-
}
|
|
173
|
-
} else if (Array.isArray(raw)) {
|
|
174
|
-
if (raw.length === 0) {
|
|
175
|
-
enabledModels = (0, import_recommended_models.getRecommendedModels)(service.provider);
|
|
176
|
-
} else {
|
|
177
|
-
enabledModels = raw.map((id) => ({ label: id, value: id }));
|
|
178
|
-
}
|
|
179
|
-
} else {
|
|
180
|
-
enabledModels = (0, import_recommended_models.getRecommendedModels)(service.provider);
|
|
181
|
-
}
|
|
182
|
-
if (enabledModels.length === 0) {
|
|
183
|
-
return null;
|
|
184
|
-
}
|
|
185
|
-
const providerMeta = plugin.aiManager.llmProviders.get(service.provider);
|
|
186
|
-
const P = providerMeta.provider;
|
|
187
|
-
const p = new P({ app: ctx.app });
|
|
188
|
-
const isToolConflict = p.isToolConflict();
|
|
189
|
-
return {
|
|
190
|
-
llmService: service.name,
|
|
191
|
-
llmServiceTitle: service.title,
|
|
192
|
-
provider: service.provider,
|
|
193
|
-
providerTitle: providerMeta == null ? void 0 : providerMeta.title,
|
|
194
|
-
enabledModels,
|
|
195
|
-
supportWebSearch: (providerMeta == null ? void 0 : providerMeta.supportWebSearch) ?? false,
|
|
196
|
-
isToolConflict
|
|
197
|
-
};
|
|
198
|
-
}).filter(Boolean);
|
|
199
|
-
ctx.body = llmServices;
|
|
159
|
+
ctx.body = await plugin.aiManager.listAllEnabledModels();
|
|
200
160
|
await next();
|
|
201
161
|
}
|
|
202
162
|
}
|
|
@@ -7,28 +7,27 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
import { Context, Next } from '@nocobase/actions';
|
|
10
|
-
declare function
|
|
10
|
+
declare function loginInCheck(ctx: Context, next: Next): Promise<never>;
|
|
11
11
|
declare const _default: {
|
|
12
12
|
name: string;
|
|
13
13
|
middlewares: {
|
|
14
|
-
|
|
15
|
-
handler: typeof parallelConversationsLimit;
|
|
14
|
+
handler: typeof loginInCheck;
|
|
16
15
|
}[];
|
|
17
16
|
actions: {
|
|
18
17
|
list(ctx: Context, next: Next): Promise<void>;
|
|
19
|
-
unreadCount(ctx: Context, next: Next): Promise<
|
|
20
|
-
unreadCounts(ctx: Context, next: Next): Promise<
|
|
21
|
-
create(ctx: Context, next: Next): Promise<
|
|
22
|
-
update(ctx: Context, next: Next): Promise<
|
|
18
|
+
unreadCount(ctx: Context, next: Next): Promise<void>;
|
|
19
|
+
unreadCounts(ctx: Context, next: Next): Promise<void>;
|
|
20
|
+
create(ctx: Context, next: Next): Promise<void>;
|
|
21
|
+
update(ctx: Context, next: Next): Promise<void>;
|
|
23
22
|
updateOptions(ctx: Context, next: Next): Promise<never>;
|
|
24
23
|
destroy(ctx: Context, next: Next): Promise<void>;
|
|
25
|
-
getMessages(ctx: Context, next: Next): Promise<
|
|
24
|
+
getMessages(ctx: Context, next: Next): Promise<void>;
|
|
26
25
|
updateToolArgs(ctx: Context, next: Next): Promise<any>;
|
|
27
|
-
sendMessages(ctx: Context, next: Next): Promise<
|
|
28
|
-
abort(ctx: Context, next: Next): Promise<
|
|
29
|
-
resumeStream(ctx: Context, next: Next): Promise<
|
|
30
|
-
resendMessages(ctx: Context, next: Next): Promise<
|
|
31
|
-
updateUserDecision(ctx: Context, next: Next): Promise<
|
|
26
|
+
sendMessages(ctx: Context, next: Next): Promise<void>;
|
|
27
|
+
abort(ctx: Context, next: Next): Promise<void>;
|
|
28
|
+
resumeStream(ctx: Context, next: Next): Promise<void>;
|
|
29
|
+
resendMessages(ctx: Context, next: Next): Promise<void>;
|
|
30
|
+
updateUserDecision(ctx: Context, next: Next): Promise<void>;
|
|
32
31
|
resumeToolCall(ctx: Context, next: Next): Promise<any>;
|
|
33
32
|
};
|
|
34
33
|
};
|
|
@@ -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,10 +170,7 @@ 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
|
-
|
|
169
|
-
return ctx.throw(403);
|
|
170
|
-
}
|
|
171
|
-
const { aiEmployee, systemMessage, skillSettings, conversationSettings } = ctx.action.params.values || {};
|
|
173
|
+
const { aiEmployee, systemMessage, skillSettings, conversationSettings, modelSettings } = ctx.action.params.values || {};
|
|
172
174
|
const employee = await getAIEmployee(ctx, aiEmployee.username);
|
|
173
175
|
if (!employee) {
|
|
174
176
|
ctx.throw(400, "AI employee not found");
|
|
@@ -180,7 +182,8 @@ var aiConversations_default = {
|
|
|
180
182
|
options: {
|
|
181
183
|
systemMessage,
|
|
182
184
|
skillSettings,
|
|
183
|
-
conversationSettings
|
|
185
|
+
conversationSettings,
|
|
186
|
+
modelSettings
|
|
184
187
|
}
|
|
185
188
|
});
|
|
186
189
|
} catch (error) {
|
|
@@ -195,9 +198,6 @@ var aiConversations_default = {
|
|
|
195
198
|
var _a;
|
|
196
199
|
const plugin = ctx.app.pm.get("ai");
|
|
197
200
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
198
|
-
if (!userId) {
|
|
199
|
-
return ctx.throw(403);
|
|
200
|
-
}
|
|
201
201
|
const { filterByTk: sessionId } = ctx.action.params;
|
|
202
202
|
const { title } = ctx.action.params.values || {};
|
|
203
203
|
ctx.body = await plugin.aiConversationsManager.update({ userId, sessionId, title });
|
|
@@ -207,22 +207,19 @@ var aiConversations_default = {
|
|
|
207
207
|
var _a;
|
|
208
208
|
const plugin = ctx.app.pm.get("ai");
|
|
209
209
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
210
|
-
if (!userId) {
|
|
211
|
-
return ctx.throw(403);
|
|
212
|
-
}
|
|
213
210
|
const { filterByTk: sessionId } = ctx.action.params;
|
|
214
211
|
if (!sessionId) {
|
|
215
212
|
return ctx.throw(400, "invalid sessionId");
|
|
216
213
|
}
|
|
217
|
-
const { systemMessage, skillSettings, conversationSettings } = ctx.action.params.values || {};
|
|
218
|
-
if (!systemMessage && !skillSettings && !conversationSettings) {
|
|
214
|
+
const { systemMessage, skillSettings, conversationSettings, modelSettings } = ctx.action.params.values || {};
|
|
215
|
+
if (!systemMessage && !skillSettings && !conversationSettings && !modelSettings) {
|
|
219
216
|
return ctx.throw(400, "invalid options");
|
|
220
217
|
}
|
|
221
218
|
try {
|
|
222
219
|
ctx.body = await plugin.aiConversationsManager.update({
|
|
223
220
|
userId,
|
|
224
221
|
sessionId,
|
|
225
|
-
options: { systemMessage, skillSettings, conversationSettings }
|
|
222
|
+
options: { systemMessage, skillSettings, conversationSettings, modelSettings }
|
|
226
223
|
});
|
|
227
224
|
} catch (error) {
|
|
228
225
|
if (error.message === "invalid sessionId") {
|
|
@@ -235,9 +232,6 @@ var aiConversations_default = {
|
|
|
235
232
|
async destroy(ctx, next) {
|
|
236
233
|
var _a;
|
|
237
234
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
238
|
-
if (!userId) {
|
|
239
|
-
return ctx.throw(403);
|
|
240
|
-
}
|
|
241
235
|
ctx.action.mergeParams({
|
|
242
236
|
filter: {
|
|
243
237
|
userId
|
|
@@ -249,9 +243,6 @@ var aiConversations_default = {
|
|
|
249
243
|
var _a, _b;
|
|
250
244
|
const plugin = ctx.app.pm.get("ai");
|
|
251
245
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
252
|
-
if (!userId) {
|
|
253
|
-
return ctx.throw(403);
|
|
254
|
-
}
|
|
255
246
|
const { sessionId, cursor, updateRead: originalUpdateRead } = ctx.action.params || {};
|
|
256
247
|
if (!sessionId) {
|
|
257
248
|
ctx.throw(400);
|
|
@@ -278,9 +269,6 @@ var aiConversations_default = {
|
|
|
278
269
|
var _a;
|
|
279
270
|
const plugin = ctx.app.pm.get("ai");
|
|
280
271
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
281
|
-
if (!userId) {
|
|
282
|
-
return ctx.throw(403);
|
|
283
|
-
}
|
|
284
272
|
const {
|
|
285
273
|
sessionId,
|
|
286
274
|
messageId,
|
|
@@ -319,11 +307,8 @@ var aiConversations_default = {
|
|
|
319
307
|
},
|
|
320
308
|
async sendMessages(ctx, next) {
|
|
321
309
|
var _a, _b, _c, _d;
|
|
322
|
-
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
323
|
-
if (!userId) {
|
|
324
|
-
return ctx.throw(403);
|
|
325
|
-
}
|
|
326
310
|
const plugin = ctx.app.pm.get("ai");
|
|
311
|
+
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
327
312
|
const {
|
|
328
313
|
sessionId,
|
|
329
314
|
aiEmployee: employeeName,
|
|
@@ -337,38 +322,27 @@ var aiConversations_default = {
|
|
|
337
322
|
if (shouldStream) {
|
|
338
323
|
setupSSEHeaders(ctx);
|
|
339
324
|
}
|
|
340
|
-
|
|
341
|
-
if (
|
|
342
|
-
|
|
343
|
-
} else {
|
|
344
|
-
ctx.status = 400;
|
|
345
|
-
ctx.body = { error: "sessionId is required" };
|
|
325
|
+
try {
|
|
326
|
+
if (!sessionId) {
|
|
327
|
+
throw new import_utils.ResourceActionError(400, ctx.t("sessionId is required"));
|
|
346
328
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
if (
|
|
352
|
-
|
|
353
|
-
} else {
|
|
354
|
-
ctx.status = 400;
|
|
355
|
-
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"));
|
|
356
335
|
}
|
|
357
|
-
return next();
|
|
358
|
-
}
|
|
359
|
-
try {
|
|
360
336
|
const conversation = await plugin.aiConversationsManager.getConversation({
|
|
361
337
|
sessionId,
|
|
362
338
|
userId
|
|
363
339
|
});
|
|
364
340
|
if (!conversation) {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
}
|
|
371
|
-
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"));
|
|
372
346
|
}
|
|
373
347
|
if (!conversation.title) {
|
|
374
348
|
const textUserMessage = messages.find(
|
|
@@ -383,17 +357,12 @@ var aiConversations_default = {
|
|
|
383
357
|
await conversation.save();
|
|
384
358
|
}
|
|
385
359
|
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
sendErrorResponse(ctx, "AI employee not found");
|
|
390
|
-
} else {
|
|
391
|
-
ctx.status = 404;
|
|
392
|
-
ctx.body = { error: "AI employee not found" };
|
|
393
|
-
}
|
|
394
|
-
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."));
|
|
395
363
|
}
|
|
396
364
|
const legacy = conversation.thread === 0;
|
|
365
|
+
const resolvedModel = await plugin.aiEmployeesManager.resolveModel(employee, model);
|
|
397
366
|
const aiEmployee = new import_ai_employee.AIEmployee({
|
|
398
367
|
ctx,
|
|
399
368
|
employee,
|
|
@@ -402,7 +371,7 @@ var aiConversations_default = {
|
|
|
402
371
|
skillSettings: (_c = conversation.options) == null ? void 0 : _c.skillSettings,
|
|
403
372
|
tools: (_d = conversation.options) == null ? void 0 : _d.tools,
|
|
404
373
|
webSearch,
|
|
405
|
-
model,
|
|
374
|
+
model: resolvedModel,
|
|
406
375
|
legacy
|
|
407
376
|
});
|
|
408
377
|
if (!editingMessageId) {
|
|
@@ -440,11 +409,19 @@ var aiConversations_default = {
|
|
|
440
409
|
}
|
|
441
410
|
} catch (err) {
|
|
442
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
|
+
}
|
|
443
421
|
if (shouldStream) {
|
|
444
|
-
sendErrorResponse(ctx,
|
|
422
|
+
sendErrorResponse(ctx, message);
|
|
445
423
|
} else {
|
|
446
|
-
ctx.status
|
|
447
|
-
ctx.body = { error: err.message || "Tool call error" };
|
|
424
|
+
ctx.throw(status, message);
|
|
448
425
|
}
|
|
449
426
|
} finally {
|
|
450
427
|
await next();
|
|
@@ -453,9 +430,6 @@ var aiConversations_default = {
|
|
|
453
430
|
async abort(ctx, next) {
|
|
454
431
|
var _a;
|
|
455
432
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
456
|
-
if (!userId) {
|
|
457
|
-
return ctx.throw(403);
|
|
458
|
-
}
|
|
459
433
|
const { sessionId } = ctx.action.params.values || {};
|
|
460
434
|
const plugin = ctx.app.pm.get("ai");
|
|
461
435
|
const conversation = await plugin.aiConversationsManager.getConversation({
|
|
@@ -472,30 +446,44 @@ var aiConversations_default = {
|
|
|
472
446
|
var _a, _b, _c, _d, _e;
|
|
473
447
|
const plugin = ctx.app.pm.get("ai");
|
|
474
448
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
449
|
+
const abortController = new AbortController();
|
|
450
|
+
const abortStream = () => abortController.abort();
|
|
451
|
+
const shouldStopStream = () => abortController.signal.aborted || ctx.res.destroyed || ctx.res.writableEnded;
|
|
478
452
|
setupSSEHeaders(ctx);
|
|
479
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);
|
|
480
454
|
if (!sessionId) {
|
|
481
455
|
sendErrorResponse(ctx, "sessionId is required");
|
|
482
456
|
return;
|
|
483
457
|
}
|
|
458
|
+
ctx.req.once("aborted", abortStream);
|
|
459
|
+
ctx.res.once("close", abortStream);
|
|
484
460
|
try {
|
|
485
461
|
const conversation = await plugin.aiConversationsManager.getConversation({
|
|
486
462
|
sessionId,
|
|
487
463
|
userId
|
|
488
464
|
});
|
|
465
|
+
if (shouldStopStream()) {
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
489
468
|
if (!conversation) {
|
|
490
469
|
sendErrorResponse(ctx, "conversation not found");
|
|
491
470
|
return;
|
|
492
471
|
}
|
|
472
|
+
const reachLimit = await isReachParallelLimit(ctx);
|
|
473
|
+
if (shouldStopStream()) {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
493
476
|
let hasChunks = false;
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
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
|
+
}
|
|
497
485
|
}
|
|
498
|
-
if (!hasChunks) {
|
|
486
|
+
if (!hasChunks && !shouldStopStream()) {
|
|
499
487
|
const currentConversation = await plugin.aiConversationsManager.getConversation({
|
|
500
488
|
sessionId,
|
|
501
489
|
userId
|
|
@@ -508,11 +496,16 @@ var aiConversations_default = {
|
|
|
508
496
|
}
|
|
509
497
|
}
|
|
510
498
|
} catch (err) {
|
|
499
|
+
if (shouldStopStream()) {
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
511
502
|
ctx.log.error(err);
|
|
512
503
|
sendErrorResponse(ctx, err.message || "Resume stream error");
|
|
513
504
|
return;
|
|
514
505
|
} finally {
|
|
515
|
-
|
|
506
|
+
ctx.req.off("aborted", abortStream);
|
|
507
|
+
ctx.res.off("close", abortStream);
|
|
508
|
+
if (!shouldStopStream()) {
|
|
516
509
|
ctx.res.end();
|
|
517
510
|
}
|
|
518
511
|
await next();
|
|
@@ -522,24 +515,26 @@ var aiConversations_default = {
|
|
|
522
515
|
var _a, _b, _c, _d;
|
|
523
516
|
const plugin = ctx.app.pm.get("ai");
|
|
524
517
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
525
|
-
|
|
526
|
-
return ctx.throw(403);
|
|
527
|
-
}
|
|
528
|
-
setupSSEHeaders(ctx);
|
|
529
|
-
const { sessionId, webSearch, model } = ctx.action.params.values || {};
|
|
518
|
+
const { sessionId, webSearch, model, stream = true } = ctx.action.params.values || {};
|
|
530
519
|
let { messageId } = ctx.action.params.values || {};
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
520
|
+
const shouldStream = stream !== false;
|
|
521
|
+
if (shouldStream) {
|
|
522
|
+
setupSSEHeaders(ctx);
|
|
534
523
|
}
|
|
535
524
|
try {
|
|
525
|
+
if (!sessionId) {
|
|
526
|
+
throw new import_utils.ResourceActionError(400, ctx.t("sessionId is required"));
|
|
527
|
+
}
|
|
536
528
|
const conversation = await plugin.aiConversationsManager.getConversation({
|
|
537
529
|
sessionId,
|
|
538
530
|
userId
|
|
539
531
|
});
|
|
540
532
|
if (!conversation) {
|
|
541
|
-
|
|
542
|
-
|
|
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"));
|
|
543
538
|
}
|
|
544
539
|
const resendMessages = [];
|
|
545
540
|
if (messageId) {
|
|
@@ -549,8 +544,7 @@ var aiConversations_default = {
|
|
|
549
544
|
}
|
|
550
545
|
});
|
|
551
546
|
if (!message) {
|
|
552
|
-
|
|
553
|
-
return next();
|
|
547
|
+
throw new import_utils.ResourceActionError(400, ctx.t("message not found"));
|
|
554
548
|
}
|
|
555
549
|
} else {
|
|
556
550
|
const message = await ctx.db.getRepository("aiConversations.messages", sessionId).findOne({
|
|
@@ -560,8 +554,7 @@ var aiConversations_default = {
|
|
|
560
554
|
sort: ["-messageId"]
|
|
561
555
|
});
|
|
562
556
|
if (!message) {
|
|
563
|
-
|
|
564
|
-
return next();
|
|
557
|
+
throw new import_utils.ResourceActionError(400, ctx.t("message not found"));
|
|
565
558
|
}
|
|
566
559
|
messageId = message.messageId;
|
|
567
560
|
if (["user", "tool"].includes(message.role)) {
|
|
@@ -575,11 +568,10 @@ var aiConversations_default = {
|
|
|
575
568
|
});
|
|
576
569
|
}
|
|
577
570
|
}
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
sendErrorResponse(ctx, "AI employee not found");
|
|
581
|
-
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."));
|
|
582
573
|
}
|
|
574
|
+
const resolvedModel = await plugin.aiEmployeesManager.resolveModel(employee, model);
|
|
583
575
|
const aiEmployee = new import_ai_employee.AIEmployee({
|
|
584
576
|
ctx,
|
|
585
577
|
employee,
|
|
@@ -588,22 +580,40 @@ var aiConversations_default = {
|
|
|
588
580
|
skillSettings: (_c = conversation.options) == null ? void 0 : _c.skillSettings,
|
|
589
581
|
tools: (_d = conversation.options) == null ? void 0 : _d.tools,
|
|
590
582
|
webSearch,
|
|
591
|
-
model
|
|
583
|
+
model: resolvedModel
|
|
592
584
|
});
|
|
593
|
-
|
|
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
|
+
}
|
|
594
593
|
} catch (err) {
|
|
595
594
|
ctx.log.error(err);
|
|
596
|
-
|
|
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();
|
|
597
611
|
}
|
|
598
|
-
await next();
|
|
599
612
|
},
|
|
600
613
|
async updateUserDecision(ctx, next) {
|
|
601
614
|
var _a;
|
|
602
615
|
const plugin = ctx.app.pm.get("ai");
|
|
603
616
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
604
|
-
if (!userId) {
|
|
605
|
-
return ctx.throw(403);
|
|
606
|
-
}
|
|
607
617
|
const { sessionId, messageId, toolCallId, userDecision } = ctx.action.params.values || {};
|
|
608
618
|
if (!sessionId) {
|
|
609
619
|
ctx.throw(400);
|
|
@@ -683,9 +693,6 @@ var aiConversations_default = {
|
|
|
683
693
|
async resumeToolCall(ctx, next) {
|
|
684
694
|
var _a, _b, _c, _d;
|
|
685
695
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
686
|
-
if (!userId) {
|
|
687
|
-
return ctx.throw(403);
|
|
688
|
-
}
|
|
689
696
|
setupSSEHeaders(ctx);
|
|
690
697
|
const plugin = ctx.app.pm.get("ai");
|
|
691
698
|
const { sessionId, messageId, model, webSearch } = ctx.action.params.values || {};
|
|
@@ -728,6 +735,7 @@ var aiConversations_default = {
|
|
|
728
735
|
sendErrorResponse(ctx, "No tool calls found");
|
|
729
736
|
return next();
|
|
730
737
|
}
|
|
738
|
+
const resolvedModel = await plugin.aiEmployeesManager.resolveModel(employee, model);
|
|
731
739
|
const aiEmployee = new import_ai_employee.AIEmployee({
|
|
732
740
|
ctx,
|
|
733
741
|
employee,
|
|
@@ -736,7 +744,7 @@ var aiConversations_default = {
|
|
|
736
744
|
skillSettings: (_c = conversation.options) == null ? void 0 : _c.skillSettings,
|
|
737
745
|
tools: (_d = conversation.options) == null ? void 0 : _d.tools,
|
|
738
746
|
webSearch,
|
|
739
|
-
model
|
|
747
|
+
model: resolvedModel
|
|
740
748
|
});
|
|
741
749
|
const userDecisions = await plugin.aiConversationsManager.getUserDecisions(messageId);
|
|
742
750
|
await aiEmployee.stream({
|