@nocobase/plugin-ai 2.2.0-beta.16 → 2.2.0-beta.18
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/ai-dev/watermark-plugin.md +2 -0
- package/dist/ai/docs/nocobase/api/cli/api/resource/create.md +4 -3
- package/dist/ai/docs/nocobase/file-manager/file-preview/index.md +44 -3
- package/dist/ai/docs/nocobase/file-manager/storage/aliyun-oss.md +100 -3
- package/dist/ai/docs/nocobase/plugin-development/build.md +10 -4
- package/dist/ai/docs/nocobase/plugin-development/client/appendix/faq.md +1 -1
- package/dist/ai/docs/nocobase/plugin-development/client/examples/custom-action.md +2 -0
- package/dist/ai/docs/nocobase/plugin-development/client/examples/custom-block.md +2 -0
- package/dist/ai/docs/nocobase/plugin-development/client/examples/custom-field.md +2 -0
- package/dist/ai/docs/nocobase/plugin-development/client/examples/fullstack-plugin.md +2 -0
- package/dist/ai/docs/nocobase/plugin-development/client/examples/settings-page.md +2 -0
- package/dist/ai/docs/nocobase/plugin-development/common/i18n.md +3 -3
- package/dist/ai/docs/nocobase/plugin-development/server/cache.md +1 -1
- package/dist/ai/docs/nocobase/plugin-development/server/collections.md +0 -6
- package/dist/ai/docs/nocobase/plugin-development/server/command.md +2 -2
- package/dist/ai/docs/nocobase/plugin-development/server/context.md +2 -2
- package/dist/ai/docs/nocobase/plugin-development/server/i18n.md +4 -4
- package/dist/ai/docs/nocobase/plugin-development/write-your-first-plugin.md +91 -43
- package/dist/ai/docs/nocobase/users-permissions/sync/index.md +8 -1
- package/dist/ai/docs/nocobase/users-permissions/sync/sources/dingtalk.md +138 -0
- package/dist/ai/docs/nocobase/users-permissions/sync/sources/ldap.md +87 -0
- package/dist/ai/docs/nocobase/workflow/nodes/javascript.md +21 -1
- package/dist/client/244.1086967ad8fdedf4.js +10 -0
- package/dist/client/{705.19b642db34de438a.js → 705.a4fe26945d175e8a.js} +1 -1
- package/dist/client/index.js +3 -3
- package/dist/client-v2/244.678c34d698985c60.js +10 -0
- package/dist/client-v2/420.a5b929a5e7f330be.js +10 -0
- package/dist/client-v2/{705.8dc34d43f02f322c.js → 705.f2e1b26a3f000075.js} +1 -1
- package/dist/client-v2/ai-employees/chatbox/hooks/reasoning-stream.d.ts +10 -0
- package/dist/client-v2/ai-employees/chatbox/stores/chat-box.d.ts +0 -2
- package/dist/client-v2/index.js +3 -3
- package/dist/client-v2/llm-providers/forms.d.ts +2 -0
- package/dist/client-v2/llm-providers/index.d.ts +1 -0
- package/dist/client-v2/models/ai-employees/AIEmployeeShortcutModel.d.ts +3 -0
- package/dist/client-v2/pages/EmployeesPage.d.ts +3 -0
- package/dist/client-v2/pages/LLMServicesPage.d.ts +9 -4
- package/dist/client-v2/repositories/AIConfigRepository.d.ts +2 -0
- package/dist/externalVersion.js +18 -16
- package/dist/locale/de-DE.json +2 -1
- package/dist/locale/en-US.json +9 -5
- package/dist/locale/es-ES.json +2 -1
- package/dist/locale/fr-FR.json +2 -1
- package/dist/locale/hu-HU.json +2 -1
- package/dist/locale/id-ID.json +2 -1
- package/dist/locale/it-IT.json +2 -1
- package/dist/locale/ja-JP.json +2 -1
- package/dist/locale/ko-KR.json +2 -1
- package/dist/locale/nl-NL.json +2 -1
- package/dist/locale/pt-BR.json +2 -1
- package/dist/locale/ru-RU.json +2 -1
- package/dist/locale/tr-TR.json +2 -1
- package/dist/locale/uk-UA.json +2 -1
- package/dist/locale/vi-VN.json +2 -1
- package/dist/locale/zh-CN.json +9 -5
- package/dist/locale/zh-TW.json +2 -1
- package/dist/node_modules/@langchain/mistralai/package.json +1 -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-employee.js +40 -24
- package/dist/server/ai-employees/reasoning-stream-state.d.ts +23 -0
- package/dist/server/ai-employees/reasoning-stream-state.js +63 -0
- package/dist/server/llm-providers/common/reasoning.js +18 -10
- package/dist/{client-v2/ai-employees/chatbox/components/DebugPanel.d.ts → server/llm-providers/deepseek/index.d.ts} +2 -2
- package/dist/server/llm-providers/deepseek/index.js +32 -0
- package/dist/server/llm-providers/deepseek/provider.d.ts +57 -0
- package/dist/server/llm-providers/deepseek/provider.js +320 -0
- package/dist/server/llm-providers/deepseek/reasoning.d.ts +83 -0
- package/dist/server/llm-providers/deepseek/reasoning.js +285 -0
- package/dist/server/llm-providers/mistral.d.ts +1 -1
- package/dist/server/llm-providers/provider.d.ts +1 -0
- package/dist/server/llm-providers/provider.js +3 -0
- package/dist/server/llm-providers/shengsuanyun.d.ts +29 -0
- package/dist/server/llm-providers/shengsuanyun.js +114 -0
- package/dist/server/manager/ai-manager.d.ts +3 -0
- package/dist/server/manager/ai-manager.js +7 -2
- package/dist/server/plugin.js +2 -0
- package/dist/server/types/ai-message.type.d.ts +4 -0
- package/dist/swagger/index.d.ts +14 -0
- package/dist/swagger/llm.d.ts +8 -0
- package/dist/swagger/llm.js +8 -0
- package/dist/swagger/schemas.d.ts +6 -0
- package/dist/swagger/schemas.js +6 -0
- package/package.json +2 -2
- package/dist/client/244.8631eb5cf3f05e21.js +0 -10
- package/dist/client-v2/244.c428e645ecb94414.js +0 -10
- package/dist/client-v2/420.b2aedb1ff71fca0e.js +0 -10
- package/dist/client-v2/debug-logger.d.ts +0 -52
- package/dist/server/llm-providers/deepseek.d.ts +0 -40
- package/dist/server/llm-providers/deepseek.js +0 -174
|
@@ -0,0 +1,83 @@
|
|
|
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 type OpenAI from 'openai';
|
|
10
|
+
import type { ReasoningOptions } from '../provider';
|
|
11
|
+
export type DeepSeekApiProtocol = 'chat-completions' | 'responses';
|
|
12
|
+
export type DeepSeekThinkingMode = 'enabled' | 'disabled';
|
|
13
|
+
export type DeepSeekReasoningEffort = 'low' | 'high' | 'max';
|
|
14
|
+
type DeepSeekReasoningBehavior = 'switchable' | 'always-on' | 'always-off';
|
|
15
|
+
type DeepSeekModelCapabilities = {
|
|
16
|
+
protocol: DeepSeekApiProtocol;
|
|
17
|
+
reasoning: DeepSeekReasoningBehavior;
|
|
18
|
+
defaultThinking: DeepSeekThinkingMode;
|
|
19
|
+
efforts: ReadonlySet<DeepSeekReasoningEffort>;
|
|
20
|
+
supportsFunctionTools: boolean;
|
|
21
|
+
supportsStructuredOutput: boolean;
|
|
22
|
+
supportsWebSearch: boolean;
|
|
23
|
+
};
|
|
24
|
+
export type DeepSeekReasoningConfig = {
|
|
25
|
+
protocol: DeepSeekApiProtocol;
|
|
26
|
+
recognizedModel: boolean;
|
|
27
|
+
thinking?: DeepSeekThinkingMode;
|
|
28
|
+
effort?: DeepSeekReasoningEffort;
|
|
29
|
+
unsupportedRequestFields: ReadonlySet<string>;
|
|
30
|
+
};
|
|
31
|
+
type ReasoningSource = {
|
|
32
|
+
content?: unknown;
|
|
33
|
+
additional_kwargs?: Record<string, unknown>;
|
|
34
|
+
response_metadata?: Record<string, unknown>;
|
|
35
|
+
};
|
|
36
|
+
export declare const DEEPSEEK_MODEL_CAPABILITIES: {
|
|
37
|
+
readonly 'deepseek-v4-flash': {
|
|
38
|
+
readonly protocol: "responses";
|
|
39
|
+
readonly reasoning: "switchable";
|
|
40
|
+
readonly defaultThinking: "enabled";
|
|
41
|
+
readonly efforts: Set<DeepSeekReasoningEffort>;
|
|
42
|
+
readonly supportsFunctionTools: true;
|
|
43
|
+
readonly supportsStructuredOutput: true;
|
|
44
|
+
readonly supportsWebSearch: true;
|
|
45
|
+
};
|
|
46
|
+
readonly 'deepseek-v4-pro': {
|
|
47
|
+
readonly protocol: "responses";
|
|
48
|
+
readonly reasoning: "switchable";
|
|
49
|
+
readonly defaultThinking: "enabled";
|
|
50
|
+
readonly efforts: Set<DeepSeekReasoningEffort>;
|
|
51
|
+
readonly supportsFunctionTools: true;
|
|
52
|
+
readonly supportsStructuredOutput: true;
|
|
53
|
+
readonly supportsWebSearch: true;
|
|
54
|
+
};
|
|
55
|
+
readonly 'deepseek-chat': {
|
|
56
|
+
readonly protocol: "chat-completions";
|
|
57
|
+
readonly reasoning: "always-off";
|
|
58
|
+
readonly defaultThinking: "disabled";
|
|
59
|
+
readonly efforts: Set<DeepSeekReasoningEffort>;
|
|
60
|
+
readonly supportsFunctionTools: true;
|
|
61
|
+
readonly supportsStructuredOutput: true;
|
|
62
|
+
readonly supportsWebSearch: false;
|
|
63
|
+
};
|
|
64
|
+
readonly 'deepseek-reasoner': {
|
|
65
|
+
readonly protocol: "chat-completions";
|
|
66
|
+
readonly reasoning: "always-on";
|
|
67
|
+
readonly defaultThinking: "enabled";
|
|
68
|
+
readonly efforts: Set<DeepSeekReasoningEffort>;
|
|
69
|
+
readonly supportsFunctionTools: true;
|
|
70
|
+
readonly supportsStructuredOutput: true;
|
|
71
|
+
readonly supportsWebSearch: false;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
export type OfficialDeepSeekModel = keyof typeof DEEPSEEK_MODEL_CAPABILITIES;
|
|
75
|
+
export declare const getDeepSeekModelCapabilities: (model: string) => DeepSeekModelCapabilities | null;
|
|
76
|
+
export declare const resolveDeepSeekReasoningConfig: (model: string, reasoning?: ReasoningOptions) => DeepSeekReasoningConfig;
|
|
77
|
+
export declare const getDeepSeekReasoningRequestParams: (config: DeepSeekReasoningConfig) => Record<string, unknown>;
|
|
78
|
+
export declare const normalizeDeepSeekChatRequest: <Request_1 extends OpenAI.Chat.Completions.ChatCompletionCreateParams>(request: Request_1, config: DeepSeekReasoningConfig) => Request_1;
|
|
79
|
+
export declare const normalizeDeepSeekResponsesRequest: <Request_1 extends OpenAI.Responses.ResponseCreateParams>(request: Request_1, config: DeepSeekReasoningConfig) => Request_1;
|
|
80
|
+
export declare const extractDeepSeekReasoningText: (source: Partial<ReasoningSource>) => string;
|
|
81
|
+
export declare const getDeepSeekResponsesReasoningItem: (source: Partial<ReasoningSource>) => Record<string, unknown> | null;
|
|
82
|
+
export declare function adaptDeepSeekResponsesStream(stream: AsyncIterable<OpenAI.Responses.ResponseStreamEvent>): AsyncGenerator<OpenAI.Responses.ResponseStreamEvent>;
|
|
83
|
+
export {};
|
|
@@ -0,0 +1,285 @@
|
|
|
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 reasoning_exports = {};
|
|
28
|
+
__export(reasoning_exports, {
|
|
29
|
+
DEEPSEEK_MODEL_CAPABILITIES: () => DEEPSEEK_MODEL_CAPABILITIES,
|
|
30
|
+
adaptDeepSeekResponsesStream: () => adaptDeepSeekResponsesStream,
|
|
31
|
+
extractDeepSeekReasoningText: () => extractDeepSeekReasoningText,
|
|
32
|
+
getDeepSeekModelCapabilities: () => getDeepSeekModelCapabilities,
|
|
33
|
+
getDeepSeekReasoningRequestParams: () => getDeepSeekReasoningRequestParams,
|
|
34
|
+
getDeepSeekResponsesReasoningItem: () => getDeepSeekResponsesReasoningItem,
|
|
35
|
+
normalizeDeepSeekChatRequest: () => normalizeDeepSeekChatRequest,
|
|
36
|
+
normalizeDeepSeekResponsesRequest: () => normalizeDeepSeekResponsesRequest,
|
|
37
|
+
resolveDeepSeekReasoningConfig: () => resolveDeepSeekReasoningConfig
|
|
38
|
+
});
|
|
39
|
+
module.exports = __toCommonJS(reasoning_exports);
|
|
40
|
+
const NO_EFFORTS = /* @__PURE__ */ new Set();
|
|
41
|
+
const V4_EFFORTS = /* @__PURE__ */ new Set(["low", "high", "max"]);
|
|
42
|
+
const THINKING_UNSUPPORTED_FIELDS = /* @__PURE__ */ new Set(["temperature", "top_p", "presence_penalty", "frequency_penalty"]);
|
|
43
|
+
const NO_UNSUPPORTED_FIELDS = /* @__PURE__ */ new Set();
|
|
44
|
+
const DEEPSEEK_MODEL_CAPABILITIES = {
|
|
45
|
+
"deepseek-v4-flash": {
|
|
46
|
+
protocol: "responses",
|
|
47
|
+
reasoning: "switchable",
|
|
48
|
+
defaultThinking: "enabled",
|
|
49
|
+
efforts: V4_EFFORTS,
|
|
50
|
+
supportsFunctionTools: true,
|
|
51
|
+
supportsStructuredOutput: true,
|
|
52
|
+
supportsWebSearch: true
|
|
53
|
+
},
|
|
54
|
+
"deepseek-v4-pro": {
|
|
55
|
+
protocol: "responses",
|
|
56
|
+
reasoning: "switchable",
|
|
57
|
+
defaultThinking: "enabled",
|
|
58
|
+
efforts: V4_EFFORTS,
|
|
59
|
+
supportsFunctionTools: true,
|
|
60
|
+
supportsStructuredOutput: true,
|
|
61
|
+
supportsWebSearch: true
|
|
62
|
+
},
|
|
63
|
+
"deepseek-chat": {
|
|
64
|
+
protocol: "chat-completions",
|
|
65
|
+
reasoning: "always-off",
|
|
66
|
+
defaultThinking: "disabled",
|
|
67
|
+
efforts: NO_EFFORTS,
|
|
68
|
+
supportsFunctionTools: true,
|
|
69
|
+
supportsStructuredOutput: true,
|
|
70
|
+
supportsWebSearch: false
|
|
71
|
+
},
|
|
72
|
+
"deepseek-reasoner": {
|
|
73
|
+
protocol: "chat-completions",
|
|
74
|
+
reasoning: "always-on",
|
|
75
|
+
defaultThinking: "enabled",
|
|
76
|
+
efforts: NO_EFFORTS,
|
|
77
|
+
supportsFunctionTools: true,
|
|
78
|
+
supportsStructuredOutput: true,
|
|
79
|
+
supportsWebSearch: false
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
83
|
+
const isOfficialDeepSeekModel = (model) => model in DEEPSEEK_MODEL_CAPABILITIES;
|
|
84
|
+
const getDeepSeekModelCapabilities = (model) => isOfficialDeepSeekModel(model) ? DEEPSEEK_MODEL_CAPABILITIES[model] : null;
|
|
85
|
+
const normalizeReasoningEffort = (mode) => {
|
|
86
|
+
if (mode === "minimal" || mode === "low") {
|
|
87
|
+
return "low";
|
|
88
|
+
}
|
|
89
|
+
if (mode === "xhigh") {
|
|
90
|
+
return "high";
|
|
91
|
+
}
|
|
92
|
+
return "high";
|
|
93
|
+
};
|
|
94
|
+
const resolveDeepSeekReasoningConfig = (model, reasoning) => {
|
|
95
|
+
const capabilities = getDeepSeekModelCapabilities(model);
|
|
96
|
+
if (!capabilities) {
|
|
97
|
+
return {
|
|
98
|
+
protocol: "chat-completions",
|
|
99
|
+
recognizedModel: false,
|
|
100
|
+
unsupportedRequestFields: NO_UNSUPPORTED_FIELDS
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
const mode = (reasoning == null ? void 0 : reasoning.mode) ?? "default";
|
|
104
|
+
if (mode === "default") {
|
|
105
|
+
return {
|
|
106
|
+
protocol: capabilities.protocol,
|
|
107
|
+
recognizedModel: true,
|
|
108
|
+
unsupportedRequestFields: capabilities.defaultThinking === "enabled" ? THINKING_UNSUPPORTED_FIELDS : NO_UNSUPPORTED_FIELDS
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
if (mode === "off") {
|
|
112
|
+
if (capabilities.reasoning === "always-on") {
|
|
113
|
+
throw new Error(`DeepSeek model "${model}" does not support disabling reasoning`);
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
protocol: capabilities.protocol,
|
|
117
|
+
recognizedModel: true,
|
|
118
|
+
...capabilities.reasoning === "switchable" ? { thinking: "disabled" } : {},
|
|
119
|
+
unsupportedRequestFields: NO_UNSUPPORTED_FIELDS
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
if (capabilities.reasoning === "always-off") {
|
|
123
|
+
throw new Error(`DeepSeek model "${model}" does not support reasoning`);
|
|
124
|
+
}
|
|
125
|
+
const effort = normalizeReasoningEffort(mode);
|
|
126
|
+
return {
|
|
127
|
+
protocol: capabilities.protocol,
|
|
128
|
+
recognizedModel: true,
|
|
129
|
+
...capabilities.reasoning === "switchable" ? { thinking: "enabled" } : {},
|
|
130
|
+
...capabilities.efforts.has(effort) ? { effort } : {},
|
|
131
|
+
unsupportedRequestFields: THINKING_UNSUPPORTED_FIELDS
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
const getDeepSeekReasoningRequestParams = (config) => {
|
|
135
|
+
if (!config.recognizedModel) {
|
|
136
|
+
return {};
|
|
137
|
+
}
|
|
138
|
+
if (config.protocol === "responses") {
|
|
139
|
+
if (config.thinking === "disabled") {
|
|
140
|
+
return { reasoning: { effort: "none" } };
|
|
141
|
+
}
|
|
142
|
+
return config.effort ? { reasoning: { effort: config.effort } } : {};
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
...config.thinking ? { thinking: { type: config.thinking } } : {},
|
|
146
|
+
...config.effort ? { reasoning_effort: config.effort } : {}
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
const removeUnsupportedRequestFields = (request, fields) => {
|
|
150
|
+
for (const field of fields) {
|
|
151
|
+
delete request[field];
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
const normalizeDeepSeekChatRequest = (request, config) => {
|
|
155
|
+
if (!config.recognizedModel) {
|
|
156
|
+
return request;
|
|
157
|
+
}
|
|
158
|
+
const mutableRequest = request;
|
|
159
|
+
delete mutableRequest.thinking;
|
|
160
|
+
delete mutableRequest.reasoning_effort;
|
|
161
|
+
Object.assign(mutableRequest, getDeepSeekReasoningRequestParams(config));
|
|
162
|
+
removeUnsupportedRequestFields(mutableRequest, config.unsupportedRequestFields);
|
|
163
|
+
return request;
|
|
164
|
+
};
|
|
165
|
+
const normalizeResponsesReasoningItems = (input) => {
|
|
166
|
+
if (!Array.isArray(input)) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
for (const item of input) {
|
|
170
|
+
if (!isRecord(item) || item.type !== "reasoning") {
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
const hasReasoningContent = Array.isArray(item.content) && item.content.some((part) => isRecord(part) && part.type === "reasoning_text" && typeof part.text === "string");
|
|
174
|
+
if (hasReasoningContent || !Array.isArray(item.summary)) {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
const text = item.summary.filter(isRecord).map((part) => part.text).filter((part) => typeof part === "string" && part.length > 0).join("");
|
|
178
|
+
if (text) {
|
|
179
|
+
item.content = [{ type: "reasoning_text", text }];
|
|
180
|
+
item.summary = [];
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
const normalizeDeepSeekResponsesRequest = (request, config) => {
|
|
185
|
+
if (!config.recognizedModel) {
|
|
186
|
+
return request;
|
|
187
|
+
}
|
|
188
|
+
const mutableRequest = request;
|
|
189
|
+
delete mutableRequest.reasoning;
|
|
190
|
+
Object.assign(mutableRequest, getDeepSeekReasoningRequestParams(config));
|
|
191
|
+
removeUnsupportedRequestFields(mutableRequest, config.unsupportedRequestFields);
|
|
192
|
+
normalizeResponsesReasoningItems(request.input);
|
|
193
|
+
return request;
|
|
194
|
+
};
|
|
195
|
+
const getReasoningItemText = (value) => {
|
|
196
|
+
if (!isRecord(value)) {
|
|
197
|
+
return "";
|
|
198
|
+
}
|
|
199
|
+
if (Array.isArray(value.content)) {
|
|
200
|
+
const content = value.content.filter(isRecord).filter((part) => part.type === "reasoning_text").map((part) => part.text).filter((text) => typeof text === "string" && text.length > 0).join("");
|
|
201
|
+
if (content) {
|
|
202
|
+
return content;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (Array.isArray(value.summary)) {
|
|
206
|
+
return value.summary.filter(isRecord).map((part) => part.text).filter((text) => typeof text === "string" && text.length > 0).join("");
|
|
207
|
+
}
|
|
208
|
+
return "";
|
|
209
|
+
};
|
|
210
|
+
const extractDeepSeekReasoningText = (source) => {
|
|
211
|
+
var _a, _b, _c;
|
|
212
|
+
const reasoningContent = (_a = source.additional_kwargs) == null ? void 0 : _a.reasoning_content;
|
|
213
|
+
if (typeof reasoningContent === "string" && reasoningContent.length > 0) {
|
|
214
|
+
return reasoningContent;
|
|
215
|
+
}
|
|
216
|
+
if (Array.isArray(source.content)) {
|
|
217
|
+
const contentBlockText = source.content.filter(isRecord).filter((block) => block.type === "reasoning").map((block) => typeof block.reasoning === "string" ? block.reasoning : "").filter(Boolean).join("");
|
|
218
|
+
if (contentBlockText) {
|
|
219
|
+
return contentBlockText;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const additionalReasoningText = getReasoningItemText((_b = source.additional_kwargs) == null ? void 0 : _b.reasoning);
|
|
223
|
+
if (additionalReasoningText) {
|
|
224
|
+
return additionalReasoningText;
|
|
225
|
+
}
|
|
226
|
+
const output = (_c = source.response_metadata) == null ? void 0 : _c.output;
|
|
227
|
+
if (Array.isArray(output)) {
|
|
228
|
+
const reasoningItem = output.find((item) => isRecord(item) && item.type === "reasoning");
|
|
229
|
+
return getReasoningItemText(reasoningItem);
|
|
230
|
+
}
|
|
231
|
+
return "";
|
|
232
|
+
};
|
|
233
|
+
const getDeepSeekResponsesReasoningItem = (source) => {
|
|
234
|
+
var _a, _b;
|
|
235
|
+
const output = (_a = source.response_metadata) == null ? void 0 : _a.output;
|
|
236
|
+
if (Array.isArray(output)) {
|
|
237
|
+
const reasoningItem = output.find((item) => isRecord(item) && item.type === "reasoning");
|
|
238
|
+
if (isRecord(reasoningItem)) {
|
|
239
|
+
return reasoningItem;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return isRecord((_b = source.additional_kwargs) == null ? void 0 : _b.reasoning) ? source.additional_kwargs.reasoning : null;
|
|
243
|
+
};
|
|
244
|
+
async function* adaptDeepSeekResponsesStream(stream) {
|
|
245
|
+
const emittedWebSearchItems = /* @__PURE__ */ new Set();
|
|
246
|
+
for await (const event of stream) {
|
|
247
|
+
if (event.type === "response.reasoning_text.delta") {
|
|
248
|
+
yield {
|
|
249
|
+
type: "response.reasoning_summary_text.delta",
|
|
250
|
+
delta: event.delta,
|
|
251
|
+
item_id: event.item_id,
|
|
252
|
+
output_index: event.output_index,
|
|
253
|
+
sequence_number: event.sequence_number,
|
|
254
|
+
summary_index: event.content_index
|
|
255
|
+
};
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
if (event.type === "response.output_item.added" && event.item.type === "web_search_call" && isRecord(event.item.action) && typeof event.item.action.query === "string") {
|
|
259
|
+
emittedWebSearchItems.add(event.item.id);
|
|
260
|
+
yield {
|
|
261
|
+
type: "response.output_item.done",
|
|
262
|
+
item: event.item,
|
|
263
|
+
output_index: event.output_index,
|
|
264
|
+
sequence_number: event.sequence_number
|
|
265
|
+
};
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
if (event.type === "response.output_item.done" && event.item.type === "web_search_call" && emittedWebSearchItems.has(event.item.id)) {
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
yield event;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
275
|
+
0 && (module.exports = {
|
|
276
|
+
DEEPSEEK_MODEL_CAPABILITIES,
|
|
277
|
+
adaptDeepSeekResponsesStream,
|
|
278
|
+
extractDeepSeekReasoningText,
|
|
279
|
+
getDeepSeekModelCapabilities,
|
|
280
|
+
getDeepSeekReasoningRequestParams,
|
|
281
|
+
getDeepSeekResponsesReasoningItem,
|
|
282
|
+
normalizeDeepSeekChatRequest,
|
|
283
|
+
normalizeDeepSeekResponsesRequest,
|
|
284
|
+
resolveDeepSeekReasoningConfig
|
|
285
|
+
});
|
|
@@ -46,9 +46,9 @@ declare class ReasoningChatMistralAI extends ChatMistralAI {
|
|
|
46
46
|
presencePenalty?: number;
|
|
47
47
|
n?: number;
|
|
48
48
|
stop?: string | string[];
|
|
49
|
+
prediction?: import("@mistralai/mistralai/models/components/prediction").Prediction;
|
|
49
50
|
toolChoice?: import("@mistralai/mistralai/models/components/toolchoice").ToolChoice | import("@mistralai/mistralai/models/components/toolchoiceenum").ToolChoiceEnum;
|
|
50
51
|
randomSeed?: number;
|
|
51
|
-
prediction?: import("@mistralai/mistralai/models/components/prediction").Prediction;
|
|
52
52
|
parallelToolCalls?: boolean;
|
|
53
53
|
promptMode?: import("@mistralai/mistralai/models/components/mistralpromptmode").MistralPromptMode;
|
|
54
54
|
safePrompt?: boolean;
|
|
@@ -98,6 +98,7 @@ export declare abstract class LLMProvider {
|
|
|
98
98
|
} | null;
|
|
99
99
|
parseResponseMetadata(output: LLMResult): any;
|
|
100
100
|
parseResponseError(err: any): any;
|
|
101
|
+
prepareStoredAssistantAdditionalKwargs(additionalKwargs?: Record<string, unknown>): Record<string, unknown> | undefined;
|
|
101
102
|
reshapeAIMessage(_options: {
|
|
102
103
|
aiMessage: AIMessage;
|
|
103
104
|
values: AIMessageInput;
|
|
@@ -367,6 +367,9 @@ ${parsed.text}
|
|
|
367
367
|
parseResponseError(err) {
|
|
368
368
|
return (err == null ? void 0 : err.message) ?? "Unexpected LLM service error";
|
|
369
369
|
}
|
|
370
|
+
prepareStoredAssistantAdditionalKwargs(additionalKwargs) {
|
|
371
|
+
return additionalKwargs;
|
|
372
|
+
}
|
|
370
373
|
reshapeAIMessage(_options) {
|
|
371
374
|
}
|
|
372
375
|
get documentLoader() {
|
|
@@ -0,0 +1,29 @@
|
|
|
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 { ChatOpenAI } from '@langchain/openai';
|
|
10
|
+
import { LLMProviderMeta } from '../manager/ai-manager';
|
|
11
|
+
import { LLMProvider } from './provider';
|
|
12
|
+
export type ShengSuanYunModel = {
|
|
13
|
+
id: string;
|
|
14
|
+
support_apis?: string[];
|
|
15
|
+
};
|
|
16
|
+
export declare function supportsChatCompletions(model: ShengSuanYunModel): boolean;
|
|
17
|
+
export declare class ShengSuanYunProvider extends LLMProvider {
|
|
18
|
+
chatModel: ChatOpenAI;
|
|
19
|
+
get baseURL(): string;
|
|
20
|
+
createModel(): ChatOpenAI<import("@langchain/openai/dist/chat_models/index.cjs").ChatOpenAICallOptions>;
|
|
21
|
+
listModels(): Promise<{
|
|
22
|
+
models?: {
|
|
23
|
+
id: string;
|
|
24
|
+
}[];
|
|
25
|
+
code?: number;
|
|
26
|
+
errMsg?: string;
|
|
27
|
+
}>;
|
|
28
|
+
}
|
|
29
|
+
export declare const shengsuanyunProviderOptions: LLMProviderMeta;
|
|
@@ -0,0 +1,114 @@
|
|
|
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 shengsuanyun_exports = {};
|
|
28
|
+
__export(shengsuanyun_exports, {
|
|
29
|
+
ShengSuanYunProvider: () => ShengSuanYunProvider,
|
|
30
|
+
shengsuanyunProviderOptions: () => shengsuanyunProviderOptions,
|
|
31
|
+
supportsChatCompletions: () => supportsChatCompletions
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(shengsuanyun_exports);
|
|
34
|
+
var import_openai = require("@langchain/openai");
|
|
35
|
+
var import_utils = require("@nocobase/utils");
|
|
36
|
+
var import_ai_manager = require("../manager/ai-manager");
|
|
37
|
+
var import_provider = require("./provider");
|
|
38
|
+
const CHAT_COMPLETIONS_API = "/v1/chat/completions";
|
|
39
|
+
function supportsChatCompletions(model) {
|
|
40
|
+
return !Array.isArray(model.support_apis) || model.support_apis.includes(CHAT_COMPLETIONS_API);
|
|
41
|
+
}
|
|
42
|
+
class ShengSuanYunProvider extends import_provider.LLMProvider {
|
|
43
|
+
get baseURL() {
|
|
44
|
+
return "https://router.shengsuanyun.com/api/v1";
|
|
45
|
+
}
|
|
46
|
+
createModel() {
|
|
47
|
+
const { apiKey, xTitle } = this.serviceOptions || {};
|
|
48
|
+
const { responseFormat, structuredOutput } = this.modelOptions || {};
|
|
49
|
+
const { name, schema } = structuredOutput || {};
|
|
50
|
+
const responseFormatOptions = {
|
|
51
|
+
type: responseFormat ?? "text"
|
|
52
|
+
};
|
|
53
|
+
if (responseFormat === "json_schema" && schema) {
|
|
54
|
+
responseFormatOptions.json_schema = {
|
|
55
|
+
schema,
|
|
56
|
+
name: name ?? "schema"
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return new import_openai.ChatOpenAI({
|
|
60
|
+
apiKey,
|
|
61
|
+
...this.modelOptions,
|
|
62
|
+
modelKwargs: {
|
|
63
|
+
response_format: responseFormatOptions
|
|
64
|
+
},
|
|
65
|
+
configuration: {
|
|
66
|
+
baseURL: this.getResolvedBaseURL(),
|
|
67
|
+
...xTitle ? { defaultHeaders: { "X-Title": xTitle } } : {}
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
async listModels() {
|
|
72
|
+
var _a;
|
|
73
|
+
const { apiKey, xTitle } = this.serviceOptions || {};
|
|
74
|
+
let url;
|
|
75
|
+
try {
|
|
76
|
+
url = this.buildRequestURL("models");
|
|
77
|
+
} catch (error) {
|
|
78
|
+
return { code: 400, errMsg: error instanceof Error ? error.message : String(error) };
|
|
79
|
+
}
|
|
80
|
+
if (!apiKey) {
|
|
81
|
+
return { code: 400, errMsg: "API Key required" };
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
const response = await (0, import_utils.serverRequest)({
|
|
85
|
+
method: "GET",
|
|
86
|
+
url,
|
|
87
|
+
headers: {
|
|
88
|
+
Authorization: `Bearer ${apiKey}`,
|
|
89
|
+
...xTitle ? { "X-Title": xTitle } : {}
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
const models = Array.isArray((_a = response == null ? void 0 : response.data) == null ? void 0 : _a.data) ? response.data.data : [];
|
|
93
|
+
return {
|
|
94
|
+
models: models.filter(supportsChatCompletions).map(({ id }) => ({ id }))
|
|
95
|
+
};
|
|
96
|
+
} catch (error) {
|
|
97
|
+
return {
|
|
98
|
+
code: 500,
|
|
99
|
+
errMsg: error instanceof Error ? error.message : String(error)
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const shengsuanyunProviderOptions = {
|
|
105
|
+
title: "SSYCloud",
|
|
106
|
+
supportedModel: [import_ai_manager.SupportedModel.LLM],
|
|
107
|
+
provider: ShengSuanYunProvider
|
|
108
|
+
};
|
|
109
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
110
|
+
0 && (module.exports = {
|
|
111
|
+
ShengSuanYunProvider,
|
|
112
|
+
shengsuanyunProviderOptions,
|
|
113
|
+
supportsChatCompletions
|
|
114
|
+
});
|
|
@@ -16,6 +16,7 @@ export type LLMProviderMeta = {
|
|
|
16
16
|
provider: new (opts: LLMProviderOptions) => LLMProvider;
|
|
17
17
|
embedding?: new (opts: EmbeddingProviderOptions) => EmbeddingProvider;
|
|
18
18
|
supportWebSearch?: boolean;
|
|
19
|
+
webSearchModels?: string[];
|
|
19
20
|
};
|
|
20
21
|
export declare enum SupportedModel {
|
|
21
22
|
LLM = "LLM",
|
|
@@ -38,6 +39,7 @@ export type EnabledLLMService = {
|
|
|
38
39
|
providerTitle?: string;
|
|
39
40
|
enabledModels: EnabledLLMModel[];
|
|
40
41
|
supportWebSearch: boolean;
|
|
42
|
+
webSearchModels?: string[];
|
|
41
43
|
isToolConflict: boolean;
|
|
42
44
|
};
|
|
43
45
|
export declare class AIManager {
|
|
@@ -51,6 +53,7 @@ export declare class AIManager {
|
|
|
51
53
|
title: string;
|
|
52
54
|
supportedModel: SupportedModel[];
|
|
53
55
|
supportWebSearch: boolean;
|
|
56
|
+
webSearchModels: string[];
|
|
54
57
|
}[];
|
|
55
58
|
getSupportedProvider(model: SupportedModel): string[];
|
|
56
59
|
listAllEnabledModels(): Promise<EnabledLLMService[]>;
|
|
@@ -48,11 +48,12 @@ class AIManager {
|
|
|
48
48
|
}
|
|
49
49
|
listLLMProviders() {
|
|
50
50
|
const providers = this.llmProviders.entries();
|
|
51
|
-
return Array.from(providers).map(([name, { title, supportedModel, supportWebSearch }]) => ({
|
|
51
|
+
return Array.from(providers).map(([name, { title, supportedModel, supportWebSearch, webSearchModels }]) => ({
|
|
52
52
|
name,
|
|
53
53
|
title,
|
|
54
54
|
supportedModel: supportedModel ?? ["LLM" /* LLM */],
|
|
55
|
-
supportWebSearch: supportWebSearch ?? false
|
|
55
|
+
supportWebSearch: supportWebSearch ?? false,
|
|
56
|
+
webSearchModels
|
|
56
57
|
}));
|
|
57
58
|
}
|
|
58
59
|
getSupportedProvider(model) {
|
|
@@ -98,6 +99,7 @@ class AIManager {
|
|
|
98
99
|
providerTitle: providerMeta.title,
|
|
99
100
|
enabledModels,
|
|
100
101
|
supportWebSearch: providerMeta.supportWebSearch ?? false,
|
|
102
|
+
webSearchModels: providerMeta.webSearchModels,
|
|
101
103
|
isToolConflict: providerClient.isToolConflict()
|
|
102
104
|
};
|
|
103
105
|
}
|
|
@@ -149,6 +151,9 @@ class AIManager {
|
|
|
149
151
|
if (!providerOptions) {
|
|
150
152
|
throw new Error("LLM service provider not found");
|
|
151
153
|
}
|
|
154
|
+
if (webSearch === true && providerOptions.webSearchModels && !providerOptions.webSearchModels.includes(model)) {
|
|
155
|
+
throw new Error(`Web search is not supported by model "${model}"`);
|
|
156
|
+
}
|
|
152
157
|
const Provider = providerOptions.provider;
|
|
153
158
|
const provider = new Provider({
|
|
154
159
|
app: this.plugin.app,
|
package/dist/server/plugin.js
CHANGED
|
@@ -77,6 +77,7 @@ var import_checkpoints = require("./ai-employees/checkpoints");
|
|
|
77
77
|
var import_mimo = require("./llm-providers/mimo");
|
|
78
78
|
var import_mistral = require("./llm-providers/mistral");
|
|
79
79
|
var import_orcarouter = require("./llm-providers/orcarouter");
|
|
80
|
+
var import_shengsuanyun = require("./llm-providers/shengsuanyun");
|
|
80
81
|
var import_sub_agents = require("./ai-employees/sub-agents");
|
|
81
82
|
var import_employee = require("./workflow/nodes/employee");
|
|
82
83
|
var import_ai_knowledge_base = require("./ai-employees/ai-knowledge-base");
|
|
@@ -191,6 +192,7 @@ class PluginAIServer extends import_server.Plugin {
|
|
|
191
192
|
this.aiManager.registerLLMProvider("kimi", import_kimi.kimiProviderOptions);
|
|
192
193
|
this.aiManager.registerLLMProvider("xai", import_xai.xaiProviderOptions);
|
|
193
194
|
this.aiManager.registerLLMProvider("orcarouter", import_orcarouter.orcarouterProviderOptions);
|
|
195
|
+
this.aiManager.registerLLMProvider("shengsuanyun", import_shengsuanyun.shengsuanyunProviderOptions);
|
|
194
196
|
}
|
|
195
197
|
registerTools() {
|
|
196
198
|
const toolsManager = this.ai.toolsManager;
|
package/dist/swagger/index.d.ts
CHANGED
|
@@ -699,6 +699,10 @@ declare const _default: {
|
|
|
699
699
|
'/llmServices:create': {
|
|
700
700
|
post: {
|
|
701
701
|
operationId: string;
|
|
702
|
+
'x-nocobase-cli-ui': {
|
|
703
|
+
path: string;
|
|
704
|
+
parameters: string[];
|
|
705
|
+
};
|
|
702
706
|
tags: string[];
|
|
703
707
|
summary: string;
|
|
704
708
|
requestBody: {
|
|
@@ -748,6 +752,10 @@ declare const _default: {
|
|
|
748
752
|
'/llmServices:update': {
|
|
749
753
|
post: {
|
|
750
754
|
operationId: string;
|
|
755
|
+
'x-nocobase-cli-ui': {
|
|
756
|
+
path: string;
|
|
757
|
+
parameters: string[];
|
|
758
|
+
};
|
|
751
759
|
tags: string[];
|
|
752
760
|
summary: string;
|
|
753
761
|
parameters: {
|
|
@@ -897,6 +905,12 @@ declare const _default: {
|
|
|
897
905
|
supportWebSearch: {
|
|
898
906
|
type: string;
|
|
899
907
|
};
|
|
908
|
+
webSearchModels: {
|
|
909
|
+
type: string;
|
|
910
|
+
items: {
|
|
911
|
+
type: string;
|
|
912
|
+
};
|
|
913
|
+
};
|
|
900
914
|
};
|
|
901
915
|
additionalProperties: boolean;
|
|
902
916
|
};
|