@nocobase/plugin-ai 2.1.11 → 2.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/ai/docs/nocobase/api/cli/config/delete.md +1 -0
  2. package/dist/ai/docs/nocobase/api/cli/config/index.md +4 -1
  3. package/dist/ai/docs/nocobase/api/cli/config/set.md +1 -0
  4. package/dist/ai/docs/nocobase/api/cli/env/auth.md +53 -5
  5. package/dist/ai/docs/nocobase/api/cli/self/check.md +19 -2
  6. package/dist/ai/docs/nocobase/api/cli/self/index.md +1 -1
  7. package/dist/ai/docs/nocobase/api/cli/self/update.md +17 -3
  8. package/dist/ai/docs/nocobase/nocobase-cli/installation/cli.md +2 -0
  9. package/dist/client/{559.a0f2f1cc2be3c039.js → 559.9061f1f36be7b76c.js} +1 -1
  10. package/dist/client/{604.de96f3ec4d471afd.js → 604.89c674f35b52b4ef.js} +1 -1
  11. package/dist/client/index.js +3 -3
  12. package/dist/client/llm-providers/mistral/ModelSettings.d.ts +10 -0
  13. package/dist/client/llm-providers/mistral/index.d.ts +10 -0
  14. package/dist/externalVersion.js +16 -16
  15. package/dist/locale/en-US.json +1 -0
  16. package/dist/locale/zh-CN.json +1 -0
  17. package/dist/node_modules/@langchain/mistralai/LICENSE +21 -0
  18. package/dist/node_modules/@langchain/mistralai/dist/_virtual/rolldown_runtime.cjs +25 -0
  19. package/dist/node_modules/@langchain/mistralai/dist/chat_models.cjs +859 -0
  20. package/dist/node_modules/@langchain/mistralai/dist/chat_models.d.cts +541 -0
  21. package/dist/node_modules/@langchain/mistralai/dist/chat_models.d.ts +541 -0
  22. package/dist/node_modules/@langchain/mistralai/dist/chat_models.js +857 -0
  23. package/dist/node_modules/@langchain/mistralai/dist/embeddings.cjs +140 -0
  24. package/dist/node_modules/@langchain/mistralai/dist/embeddings.d.cts +116 -0
  25. package/dist/node_modules/@langchain/mistralai/dist/embeddings.d.ts +116 -0
  26. package/dist/node_modules/@langchain/mistralai/dist/embeddings.js +139 -0
  27. package/dist/node_modules/@langchain/mistralai/dist/index.cjs +21 -0
  28. package/dist/node_modules/@langchain/mistralai/dist/index.d.cts +4 -0
  29. package/dist/node_modules/@langchain/mistralai/dist/index.d.ts +4 -0
  30. package/dist/node_modules/@langchain/mistralai/dist/index.js +5 -0
  31. package/dist/node_modules/@langchain/mistralai/dist/llms.cjs +275 -0
  32. package/dist/node_modules/@langchain/mistralai/dist/llms.d.cts +147 -0
  33. package/dist/node_modules/@langchain/mistralai/dist/llms.d.ts +147 -0
  34. package/dist/node_modules/@langchain/mistralai/dist/llms.js +274 -0
  35. package/dist/node_modules/@langchain/mistralai/dist/utils.cjs +61 -0
  36. package/dist/node_modules/@langchain/mistralai/dist/utils.js +59 -0
  37. package/dist/node_modules/@langchain/mistralai/package.json +1 -0
  38. package/dist/node_modules/@langchain/xai/dist/index.cjs +2 -2
  39. package/dist/node_modules/@langchain/xai/package.json +1 -1
  40. package/dist/node_modules/fs-extra/package.json +1 -1
  41. package/dist/node_modules/jsonrepair/package.json +1 -1
  42. package/dist/node_modules/just-bash/package.json +1 -1
  43. package/dist/node_modules/nodejs-snowflake/package.json +1 -1
  44. package/dist/node_modules/openai/package.json +1 -1
  45. package/dist/node_modules/zod/package.json +1 -1
  46. package/dist/server/ai-employees/ai-employee.js +17 -4
  47. package/dist/server/ai-employees/middleware/conversation.d.ts +2 -0
  48. package/dist/server/ai-employees/middleware/conversation.js +2 -1
  49. package/dist/server/ai-employees/middleware/index.d.ts +1 -0
  50. package/dist/server/ai-employees/middleware/index.js +2 -0
  51. package/dist/server/ai-employees/middleware/tool-call-sanitizer.d.ts +16 -0
  52. package/dist/server/ai-employees/middleware/tool-call-sanitizer.js +90 -0
  53. package/dist/server/ai-employees/tool-call-sanitizer.d.ts +26 -0
  54. package/dist/server/ai-employees/tool-call-sanitizer.js +84 -0
  55. package/dist/server/ai-employees/utils.d.ts +3 -1
  56. package/dist/server/ai-employees/utils.js +16 -2
  57. package/dist/server/llm-providers/mistral.d.ts +62 -0
  58. package/dist/server/llm-providers/mistral.js +265 -0
  59. package/dist/server/llm-providers/provider.d.ts +6 -2
  60. package/dist/server/llm-providers/provider.js +2 -0
  61. package/dist/server/plugin.js +2 -0
  62. package/package.json +3 -2
@@ -0,0 +1,265 @@
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 mistral_exports = {};
28
+ __export(mistral_exports, {
29
+ MistralEmbeddingProvider: () => MistralEmbeddingProvider,
30
+ MistralProvider: () => MistralProvider,
31
+ injectMistralReasoningEffort: () => injectMistralReasoningEffort,
32
+ mistralProviderOptions: () => mistralProviderOptions
33
+ });
34
+ module.exports = __toCommonJS(mistral_exports);
35
+ var import_mistralai = require("@langchain/mistralai");
36
+ var import_utils = require("@nocobase/utils");
37
+ var import_provider = require("./provider");
38
+ var import_ai_manager = require("../manager/ai-manager");
39
+ const MISTRAL_URL = "https://api.mistral.ai";
40
+ const MISTRAL_REASONING_EFFORT = "high";
41
+ const MISTRAL_REASONING_MODELS = /* @__PURE__ */ new Set(["mistral-small-latest", "mistral-medium-3-5"]);
42
+ function omitDisabledNumberOptions(options) {
43
+ for (const key of ["maxTokens", "maxRetries"]) {
44
+ if (options[key] === -1) {
45
+ delete options[key];
46
+ }
47
+ }
48
+ }
49
+ function extractTextChunks(content) {
50
+ if (typeof content === "string") {
51
+ return content;
52
+ }
53
+ if (!Array.isArray(content)) {
54
+ return "";
55
+ }
56
+ return content.filter((chunk) => chunk && typeof chunk === "object").filter((chunk) => chunk.type === "text" && typeof chunk.text === "string").map((chunk) => chunk.text).join("");
57
+ }
58
+ function extractThinkingChunks(content) {
59
+ if (!Array.isArray(content)) {
60
+ return "";
61
+ }
62
+ return content.filter((chunk) => chunk && typeof chunk === "object").filter((chunk) => chunk.type === "thinking" && Array.isArray(chunk.thinking)).map((chunk) => extractTextChunks(chunk.thinking)).join("");
63
+ }
64
+ const injectMistralReasoningEffort = async (request) => {
65
+ if (request.method !== "POST") {
66
+ return;
67
+ }
68
+ const contentType = request.headers.get("content-type") || "";
69
+ if (!contentType.toLowerCase().includes("application/json")) {
70
+ return;
71
+ }
72
+ const body = await request.clone().json().catch(() => null);
73
+ if (!body || typeof body !== "object") {
74
+ return;
75
+ }
76
+ if (typeof body.model !== "string" || !MISTRAL_REASONING_MODELS.has(body.model)) {
77
+ return;
78
+ }
79
+ const headers = new Headers(request.headers);
80
+ headers.delete("content-length");
81
+ return new Request(request, {
82
+ headers,
83
+ body: JSON.stringify({
84
+ ...body,
85
+ reasoning_effort: MISTRAL_REASONING_EFFORT
86
+ })
87
+ });
88
+ };
89
+ class MistralProvider extends import_provider.LLMProvider {
90
+ get baseURL() {
91
+ return MISTRAL_URL;
92
+ }
93
+ createModel() {
94
+ const { apiKey } = this.serviceOptions || {};
95
+ const { responseFormat, structuredOutput, ...modelOptions } = this.modelOptions || {};
96
+ omitDisabledNumberOptions(modelOptions);
97
+ const beforeRequestHooks = Array.isArray(modelOptions.beforeRequestHooks) ? [injectMistralReasoningEffort, ...modelOptions.beforeRequestHooks] : [injectMistralReasoningEffort];
98
+ return new import_mistralai.ChatMistralAI({
99
+ apiKey,
100
+ ...modelOptions,
101
+ beforeRequestHooks,
102
+ serverURL: this.getResolvedServerURL(),
103
+ verbose: false
104
+ });
105
+ }
106
+ async stream(context, options) {
107
+ return super.stream(context, this.withResponseFormat(options));
108
+ }
109
+ async invoke(context, options) {
110
+ return super.invoke(context, this.withResponseFormat(options));
111
+ }
112
+ async listModels() {
113
+ var _a, _b, _c, _d;
114
+ const options = this.serviceOptions || {};
115
+ const apiKey = options.apiKey;
116
+ let url;
117
+ try {
118
+ url = this.buildMistralRequestURL("v1/models");
119
+ } catch (e) {
120
+ return { code: 400, errMsg: e instanceof Error ? e.message : String(e) };
121
+ }
122
+ if (!apiKey) {
123
+ return { code: 400, errMsg: "API Key required" };
124
+ }
125
+ try {
126
+ const res = await (0, import_utils.serverRequest)({
127
+ method: "GET",
128
+ url,
129
+ headers: {
130
+ Authorization: `Bearer ${apiKey}`
131
+ }
132
+ });
133
+ return { models: (_a = res == null ? void 0 : res.data) == null ? void 0 : _a.data };
134
+ } catch (e) {
135
+ const error = e;
136
+ const status = ((_b = error.response) == null ? void 0 : _b.status) || 500;
137
+ const data = (_c = error.response) == null ? void 0 : _c.data;
138
+ const errorMsg = (typeof data === "object" ? data.message : void 0) || (typeof data === "object" && typeof data.detail === "object" ? data.detail.message : void 0) || (typeof data === "object" && typeof data.detail === "string" ? data.detail : void 0) || (typeof data === "string" ? data : void 0) || ((_d = error.response) == null ? void 0 : _d.statusText) || error.message;
139
+ return { code: status, errMsg: errorMsg };
140
+ }
141
+ }
142
+ isApiSupportedAttachment(attachment) {
143
+ var _a;
144
+ return ((_a = attachment.mimetype) == null ? void 0 : _a.startsWith("image/")) ?? false;
145
+ }
146
+ reshapeAIMessage({ aiMessage, values }) {
147
+ const reasoning = extractThinkingChunks(aiMessage.content);
148
+ if (Array.isArray(aiMessage.content)) {
149
+ aiMessage.content = extractTextChunks(aiMessage.content);
150
+ }
151
+ if (!reasoning) {
152
+ return;
153
+ }
154
+ values.metadata.additional_kwargs = {
155
+ ...values.metadata.additional_kwargs ?? {},
156
+ reasoning_content: reasoning
157
+ };
158
+ }
159
+ parseResponseMessage(message) {
160
+ var _a, _b, _c, _d;
161
+ const result = super.parseResponseMessage(message);
162
+ if (["user", "tool"].includes(result == null ? void 0 : result.role)) {
163
+ return result;
164
+ }
165
+ const metadataReasoning = (_c = (_b = (_a = result == null ? void 0 : result.content) == null ? void 0 : _a.metadata) == null ? void 0 : _b.additional_kwargs) == null ? void 0 : _c.reasoning_content;
166
+ if (typeof metadataReasoning === "string" && metadataReasoning) {
167
+ result.content = {
168
+ ...result.content ?? {},
169
+ reasoning: {
170
+ status: "stop",
171
+ content: metadataReasoning
172
+ }
173
+ };
174
+ return result;
175
+ }
176
+ const rawContent = (_d = result == null ? void 0 : result.content) == null ? void 0 : _d.content;
177
+ const reasoning = extractThinkingChunks(rawContent);
178
+ if (reasoning) {
179
+ result.content = {
180
+ ...result.content ?? {},
181
+ content: extractTextChunks(rawContent),
182
+ reasoning: {
183
+ status: "stop",
184
+ content: reasoning
185
+ }
186
+ };
187
+ }
188
+ return result;
189
+ }
190
+ parseResponseChunk(chunk) {
191
+ if (Array.isArray(chunk)) {
192
+ return extractTextChunks(chunk);
193
+ }
194
+ return super.parseResponseChunk(chunk);
195
+ }
196
+ parseReasoningContent(chunk) {
197
+ const content = extractThinkingChunks(chunk == null ? void 0 : chunk.content);
198
+ if (!content) {
199
+ return null;
200
+ }
201
+ return {
202
+ status: "streaming",
203
+ content
204
+ };
205
+ }
206
+ withResponseFormat(options) {
207
+ var _a;
208
+ const responseFormat = (_a = this.modelOptions) == null ? void 0 : _a.responseFormat;
209
+ if (responseFormat !== "json_object") {
210
+ return options;
211
+ }
212
+ return {
213
+ ...options || {},
214
+ response_format: {
215
+ type: responseFormat
216
+ }
217
+ };
218
+ }
219
+ getResolvedServerURL() {
220
+ return this.getResolvedBaseURL().replace(/\/v1$/, "");
221
+ }
222
+ buildMistralRequestURL(pathname) {
223
+ const url = new URL(pathname.replace(/^\/+/, ""), `${this.getResolvedServerURL()}/`).toString();
224
+ (0, import_utils.checkUrlAgainstWhitelist)(url);
225
+ return url;
226
+ }
227
+ }
228
+ class MistralEmbeddingProvider extends import_provider.EmbeddingProvider {
229
+ getDefaultUrl() {
230
+ return MISTRAL_URL;
231
+ }
232
+ createEmbedding() {
233
+ return new import_mistralai.MistralAIEmbeddings({
234
+ apiKey: this.apiKey,
235
+ serverURL: this.baseURL.replace(/\/v1$/, ""),
236
+ model: this.model
237
+ });
238
+ }
239
+ }
240
+ const mistralProviderOptions = {
241
+ title: "Mistral AI",
242
+ supportedModel: [import_ai_manager.SupportedModel.LLM, import_ai_manager.SupportedModel.EMBEDDING],
243
+ models: {
244
+ [import_ai_manager.SupportedModel.LLM]: [
245
+ "mistral-large-latest",
246
+ "mistral-medium-latest",
247
+ "mistral-medium-3-5",
248
+ "mistral-small-latest",
249
+ "ministral-8b-latest",
250
+ "ministral-3b-latest",
251
+ "codestral-latest",
252
+ "pixtral-large-latest"
253
+ ],
254
+ [import_ai_manager.SupportedModel.EMBEDDING]: ["mistral-embed"]
255
+ },
256
+ provider: MistralProvider,
257
+ embedding: MistralEmbeddingProvider
258
+ };
259
+ // Annotate the CommonJS export names for ESM import in node:
260
+ 0 && (module.exports = {
261
+ MistralEmbeddingProvider,
262
+ MistralProvider,
263
+ injectMistralReasoningEffort,
264
+ mistralProviderOptions
265
+ });
@@ -10,9 +10,9 @@ import { BaseChatModel } from '@langchain/core/language_models/chat_models';
10
10
  import { Model } from '@nocobase/database';
11
11
  import { AttachmentModel } from '@nocobase/plugin-file-manager';
12
12
  import { Application } from '@nocobase/server';
13
- import { AIChatContext } from '../types/ai-chat-conversation.type';
13
+ import { AIChatContext, AIMessageInput } from '../types/ai-chat-conversation.type';
14
14
  import { EmbeddingsInterface } from '@langchain/core/embeddings';
15
- import { AIMessageChunk } from '@langchain/core/messages';
15
+ import { AIMessage, AIMessageChunk } from '@langchain/core/messages';
16
16
  import { Context } from '@nocobase/actions';
17
17
  import '@langchain/core/utils/stream';
18
18
  import { LLMResult } from '@langchain/core/outputs';
@@ -90,6 +90,10 @@ export declare abstract class LLMProvider {
90
90
  } | null;
91
91
  parseResponseMetadata(output: LLMResult): any;
92
92
  parseResponseError(err: any): any;
93
+ reshapeAIMessage(_options: {
94
+ aiMessage: AIMessage;
95
+ values: AIMessageInput;
96
+ }): void;
93
97
  protected get documentLoader(): CachedDocumentLoader;
94
98
  protected getResolvedBaseURL(): string;
95
99
  protected buildRequestURL(pathname: string): string;
@@ -319,6 +319,8 @@ ${parsed.text}
319
319
  parseResponseError(err) {
320
320
  return (err == null ? void 0 : err.message) ?? "Unexpected LLM service error";
321
321
  }
322
+ reshapeAIMessage(_options) {
323
+ }
322
324
  get documentLoader() {
323
325
  return this.aiPlugin.documentLoaders.cached;
324
326
  }
@@ -74,6 +74,7 @@ var import_xai = require("./llm-providers/xai");
74
74
  var import_document_loader = require("./document-loader");
75
75
  var import_checkpoints = require("./ai-employees/checkpoints");
76
76
  var import_mimo = require("./llm-providers/mimo");
77
+ var import_mistral = require("./llm-providers/mistral");
77
78
  var import_sub_agents = require("./ai-employees/sub-agents");
78
79
  var import_employee = require("./workflow/nodes/employee");
79
80
  var import_ai_knowledge_base = require("./ai-employees/ai-knowledge-base");
@@ -180,6 +181,7 @@ class PluginAIServer extends import_server.Plugin {
180
181
  this.aiManager.registerLLMProvider("dashscope", import_dashscope.dashscopeProviderOptions);
181
182
  this.aiManager.registerLLMProvider("kimi", import_kimi.kimiProviderOptions);
182
183
  this.aiManager.registerLLMProvider("mimo", import_mimo.mimoProviderOptions);
184
+ this.aiManager.registerLLMProvider("mistral", import_mistral.mistralProviderOptions);
183
185
  this.aiManager.registerLLMProvider("ollama", import_ollama.ollamaProviderOptions);
184
186
  this.aiManager.registerLLMProvider("openai-completions", import_openai2.openaiCompletionsProviderOptions);
185
187
  this.aiManager.registerLLMProvider("kimi", import_kimi.kimiProviderOptions);
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "description": "Create AI employees with diverse skills to collaborate with humans, build systems, and handle business operations.",
7
7
  "description.ru-RU": "Поддержка интеграции с AI-сервисами: предоставляются AI-узлы для рабочих процессов, расширяя возможности бизнес-обработки.",
8
8
  "description.zh-CN": "创建各种技能的 AI 员工,与人类协同,搭建系统,处理业务。",
9
- "version": "2.1.11",
9
+ "version": "2.1.14",
10
10
  "main": "dist/server/index.js",
11
11
  "homepage": "https://docs.nocobase.com/handbook/action-ai",
12
12
  "homepage.ru-RU": "https://docs-ru.nocobase.com/handbook/action-ai",
@@ -41,6 +41,7 @@
41
41
  "@langchain/google-genai": "2.1.18",
42
42
  "@langchain/langgraph": "1.4.4",
43
43
  "@langchain/langgraph-checkpoint": "1.1.2",
44
+ "@langchain/mistralai": "1.0.0",
44
45
  "@langchain/ollama": "1.2.7",
45
46
  "@langchain/openai": "1.4.7",
46
47
  "@langchain/xai": "1.3.19",
@@ -65,5 +66,5 @@
65
66
  "keywords": [
66
67
  "AI"
67
68
  ],
68
- "gitHead": "1ccf891d837e21089f65f84b892407b34a0a0cb9"
69
+ "gitHead": "2a8c3e0e9362aeb49b39c1d02358639b29769f32"
69
70
  }