@nocobase/plugin-ai 2.1.0-beta.43 → 2.1.0-beta.45

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 (117) hide show
  1. package/dist/ai/docs/nocobase/ai/install-upgrade-migration.mdx +127 -132
  2. package/dist/ai/docs/nocobase/ai-dev/capabilities.md +1 -1
  3. package/dist/ai/docs/nocobase/ai-dev/index.md +1 -1
  4. package/dist/ai/docs/nocobase/ai-dev/watermark-plugin.md +1 -1
  5. package/dist/ai/docs/nocobase/api/cli/app/autostart/disable.md +44 -0
  6. package/dist/ai/docs/nocobase/api/cli/app/autostart/enable.md +44 -0
  7. package/dist/ai/docs/nocobase/api/cli/app/autostart/index.md +63 -0
  8. package/dist/ai/docs/nocobase/api/cli/app/autostart/list.md +41 -0
  9. package/dist/ai/docs/nocobase/api/cli/app/autostart/run.md +50 -0
  10. package/dist/ai/docs/nocobase/api/cli/app/index.md +18 -15
  11. package/dist/ai/docs/nocobase/api/cli/app/restart.md +3 -11
  12. package/dist/ai/docs/nocobase/api/cli/app/start.md +3 -11
  13. package/dist/ai/docs/nocobase/api/cli/app/stop.md +22 -12
  14. package/dist/ai/docs/nocobase/api/cli/app/upgrade.md +6 -6
  15. package/dist/ai/docs/nocobase/api/cli/backup/create.md +49 -0
  16. package/dist/ai/docs/nocobase/api/cli/backup/index.md +46 -0
  17. package/dist/ai/docs/nocobase/api/cli/backup/restore.md +46 -0
  18. package/dist/ai/docs/nocobase/api/cli/config/delete.md +11 -9
  19. package/dist/ai/docs/nocobase/api/cli/config/get.md +11 -8
  20. package/dist/ai/docs/nocobase/api/cli/config/index.md +28 -24
  21. package/dist/ai/docs/nocobase/api/cli/config/set.md +14 -12
  22. package/dist/ai/docs/nocobase/api/cli/db/stop.md +10 -11
  23. package/dist/ai/docs/nocobase/api/cli/env/index.md +25 -23
  24. package/dist/ai/docs/nocobase/api/cli/env/info.md +12 -10
  25. package/dist/ai/docs/nocobase/api/cli/env/proxy/caddy.md +108 -0
  26. package/dist/ai/docs/nocobase/api/cli/env/proxy/index.md +54 -0
  27. package/dist/ai/docs/nocobase/api/cli/env/proxy/nginx.md +104 -0
  28. package/dist/ai/docs/nocobase/api/cli/env/remove.md +18 -14
  29. package/dist/ai/docs/nocobase/api/cli/env/update.md +115 -14
  30. package/dist/ai/docs/nocobase/api/cli/index.md +66 -52
  31. package/dist/ai/docs/nocobase/api/cli/init.md +244 -62
  32. package/dist/ai/docs/nocobase/api/cli/license/activate.md +13 -12
  33. package/dist/ai/docs/nocobase/api/cli/license/index.md +2 -2
  34. package/dist/ai/docs/nocobase/api/cli/plugin/import.md +74 -0
  35. package/dist/ai/docs/nocobase/api/cli/plugin/index.md +4 -2
  36. package/dist/ai/docs/nocobase/get-started/deployment/how-to-deploy-nocobase-faster.mdx +384 -0
  37. package/dist/ai/docs/nocobase/get-started/install-upgrade-plugins.mdx +16 -10
  38. package/dist/ai/docs/nocobase/get-started/upgrading/docker.md +1 -1
  39. package/dist/ai/docs/nocobase/index.md +3 -3
  40. package/dist/ai/docs/nocobase/multi-app/multi-app/app-block-and-switcher.md +68 -0
  41. package/dist/ai/docs/nocobase/multi-app/multi-app/app-sso.md +71 -0
  42. package/dist/ai/docs/nocobase/multi-app/multi-app/index.md +9 -1
  43. package/dist/ai/docs/nocobase/multi-app/multi-app/sub-app-api.md +112 -0
  44. package/dist/ai/docs/nocobase/plugin-development/client/appendix/faq.md +3 -3
  45. package/dist/ai/docs/nocobase/plugin-development/client/component/index.md +1 -1
  46. package/dist/ai/docs/nocobase/plugin-development/client/ctx/common-capabilities.md +2 -2
  47. package/dist/ai/docs/nocobase/plugin-development/client/ctx/index.md +1 -1
  48. package/dist/ai/docs/nocobase/plugin-development/client/router.md +11 -11
  49. package/dist/ai/docs/nocobase/quickstart/index.md +27 -0
  50. package/dist/ai/docs/nocobase/quickstart/installation/airgap.md +67 -0
  51. package/dist/ai/docs/nocobase/quickstart/installation/cli.md +205 -0
  52. package/dist/ai/docs/nocobase/quickstart/installation/docker-compose.md +123 -0
  53. package/dist/ai/docs/nocobase/quickstart/installation/env.md +101 -0
  54. package/dist/ai/docs/nocobase/quickstart/installation/migration.md +50 -0
  55. package/dist/ai/docs/nocobase/quickstart/operations/backup-restore.md +94 -0
  56. package/dist/ai/docs/nocobase/quickstart/operations/manage-app.md +166 -0
  57. package/dist/ai/docs/nocobase/quickstart/operations/multi-environment.md +171 -0
  58. package/dist/ai/docs/nocobase/quickstart/plugins/third-party.md +86 -0
  59. package/dist/ai/docs/nocobase/quickstart/production/index.md +163 -0
  60. package/dist/ai/docs/nocobase/quickstart/production/reverse-proxy/caddy.md +158 -0
  61. package/dist/ai/docs/nocobase/quickstart/production/reverse-proxy/index.md +100 -0
  62. package/dist/ai/docs/nocobase/quickstart/production/reverse-proxy/nginx.md +166 -0
  63. package/dist/ai/docs/nocobase/quickstart/release-management.md +1 -0
  64. package/dist/ai/docs/nocobase/solution/all-in-one/installation.md +181 -0
  65. package/dist/ai/docs/nocobase/solution/crm/changelog.md +0 -3
  66. package/dist/ai/docs/nocobase/solution/crm/installation.md +6 -76
  67. package/dist/ai/docs/nocobase/solution/crm/v1.md +6 -35
  68. package/dist/ai/docs/nocobase/solution/ticket-system/changelog.md +0 -2
  69. package/dist/ai/docs/nocobase/solution/ticket-system/installation.md +6 -69
  70. package/dist/ai/docs/nocobase/workflow/advanced/options.md +45 -1
  71. package/dist/client/{406.15c09d98faa2ccf1.js → 406.9a530334eae8cede.js} +1 -1
  72. package/dist/client/{428.e9f38da3b0d8b498.js → 428.431a00d29107058e.js} +1 -1
  73. package/dist/client/index.js +2 -2
  74. package/dist/client-v2/index.js +1 -1
  75. package/dist/externalVersion.js +18 -18
  76. package/dist/locale/de-DE.json +1 -0
  77. package/dist/locale/en-US.json +2 -1
  78. package/dist/locale/es-ES.json +1 -0
  79. package/dist/locale/fr-FR.json +1 -0
  80. package/dist/locale/hu-HU.json +1 -0
  81. package/dist/locale/id-ID.json +1 -0
  82. package/dist/locale/it-IT.json +1 -0
  83. package/dist/locale/ja-JP.json +1 -0
  84. package/dist/locale/ko-KR.json +1 -0
  85. package/dist/locale/nl-NL.json +1 -0
  86. package/dist/locale/pt-BR.json +1 -0
  87. package/dist/locale/ru-RU.json +1 -0
  88. package/dist/locale/tr-TR.json +1 -0
  89. package/dist/locale/uk-UA.json +1 -0
  90. package/dist/locale/vi-VN.json +1 -0
  91. package/dist/locale/zh-CN.json +2 -1
  92. package/dist/locale/zh-TW.json +1 -0
  93. package/dist/node_modules/@langchain/xai/package.json +1 -1
  94. package/dist/node_modules/fs-extra/package.json +1 -1
  95. package/dist/node_modules/jsonrepair/package.json +1 -1
  96. package/dist/node_modules/just-bash/package.json +1 -1
  97. package/dist/node_modules/nodejs-snowflake/package.json +1 -1
  98. package/dist/node_modules/openai/package.json +1 -1
  99. package/dist/node_modules/zod/package.json +1 -1
  100. package/dist/server/llm-providers/anthropic.js +17 -23
  101. package/dist/server/llm-providers/dashscope.js +3 -3
  102. package/dist/server/llm-providers/deepseek.js +2 -2
  103. package/dist/server/llm-providers/google-genai.js +17 -22
  104. package/dist/server/llm-providers/kimi/provider.js +4 -4
  105. package/dist/server/llm-providers/mimo.js +2 -2
  106. package/dist/server/llm-providers/ollama.js +14 -21
  107. package/dist/server/llm-providers/openai/completions.js +2 -2
  108. package/dist/server/llm-providers/openai/embedding.js +1 -1
  109. package/dist/server/llm-providers/openai/responses.js +2 -2
  110. package/dist/server/llm-providers/provider.d.ts +3 -1
  111. package/dist/server/llm-providers/provider.js +55 -22
  112. package/dist/server/llm-providers/xai.js +2 -2
  113. package/dist/server/resource/ai.js +11 -9
  114. package/dist/server/workflow/nodes/employee/index.js +2 -4
  115. package/dist/server/workflow/nodes/employee/types.d.ts +2 -2
  116. package/package.json +2 -2
  117. package/dist/ai/docs/nocobase/api/cli/app/down.md +0 -41
@@ -7,11 +7,9 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
 
10
- var __create = Object.create;
11
10
  var __defProp = Object.defineProperty;
12
11
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
13
12
  var __getOwnPropNames = Object.getOwnPropertyNames;
14
- var __getProtoOf = Object.getPrototypeOf;
15
13
  var __hasOwnProp = Object.prototype.hasOwnProperty;
16
14
  var __export = (target, all) => {
17
15
  for (var name in all)
@@ -25,14 +23,6 @@ var __copyProps = (to, from, except, desc) => {
25
23
  }
26
24
  return to;
27
25
  };
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
26
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
27
  var ollama_exports = {};
38
28
  __export(ollama_exports, {
@@ -44,17 +34,16 @@ module.exports = __toCommonJS(ollama_exports);
44
34
  var import_ollama = require("@langchain/ollama");
45
35
  var import_provider = require("./provider");
46
36
  var import_ai_manager = require("../manager/ai-manager");
47
- var import_axios = __toESM(require("axios"));
37
+ var import_utils = require("@nocobase/utils");
48
38
  const OLLAMA_DEFAULT_URL = "http://localhost:11434";
49
39
  class OllamaProvider extends import_provider.LLMProvider {
50
40
  get baseURL() {
51
41
  return OLLAMA_DEFAULT_URL;
52
42
  }
53
43
  createModel() {
54
- const { baseURL } = this.serviceOptions || {};
55
44
  const { model, temperature, topP, topK, numPredict, ...rest } = this.modelOptions || {};
56
45
  return new import_ollama.ChatOllama({
57
- baseUrl: baseURL || this.baseURL,
46
+ baseUrl: this.getResolvedBaseURL(),
58
47
  model: model || "mistral-nemo:12b",
59
48
  temperature,
60
49
  topP,
@@ -68,16 +57,20 @@ class OllamaProvider extends import_provider.LLMProvider {
68
57
  }
69
58
  async listModels() {
70
59
  var _a;
71
- const options = this.serviceOptions || {};
72
- let baseURL = options.baseURL || this.baseURL;
73
- if (!baseURL) {
74
- return { code: 400, errMsg: "baseURL is required" };
60
+ let url;
61
+ try {
62
+ url = this.buildRequestURL("api/tags");
63
+ } catch (e) {
64
+ return { code: 400, errMsg: e instanceof Error ? e.message : String(e) };
75
65
  }
76
- if (baseURL && baseURL.endsWith("/")) {
77
- baseURL = baseURL.slice(0, -1);
66
+ if (!url) {
67
+ return { code: 400, errMsg: "baseURL is required" };
78
68
  }
79
69
  try {
80
- const res = await import_axios.default.get(`${baseURL}/api/tags`);
70
+ const res = await (0, import_utils.serverRequest)({
71
+ method: "GET",
72
+ url
73
+ });
81
74
  const models = ((_a = res == null ? void 0 : res.data) == null ? void 0 : _a.models) || [];
82
75
  return {
83
76
  models: models.map((model) => ({
@@ -87,7 +80,7 @@ class OllamaProvider extends import_provider.LLMProvider {
87
80
  } catch (e) {
88
81
  return {
89
82
  code: 500,
90
- errMsg: `Failed to fetch Ollama models: ${e.message}. Make sure Ollama is running at ${baseURL}`
83
+ errMsg: `Failed to fetch Ollama models: ${e.message}. Make sure Ollama is running at ${this.getResolvedBaseURL()}`
91
84
  };
92
85
  }
93
86
  }
@@ -36,7 +36,7 @@ class OpenAICompletionsProvider extends import_provider.LLMProvider {
36
36
  return "https://api.openai.com/v1";
37
37
  }
38
38
  createModel() {
39
- const { baseURL, apiKey } = this.serviceOptions || {};
39
+ const { apiKey } = this.serviceOptions || {};
40
40
  const { responseFormat, structuredOutput } = this.modelOptions || {};
41
41
  const { schema } = structuredOutput || {};
42
42
  const responseFormatOptions = {
@@ -52,7 +52,7 @@ class OpenAICompletionsProvider extends import_provider.LLMProvider {
52
52
  response_format: responseFormatOptions
53
53
  },
54
54
  configuration: {
55
- baseURL: baseURL || this.baseURL
55
+ baseURL: this.getResolvedBaseURL()
56
56
  }
57
57
  });
58
58
  }
@@ -38,7 +38,7 @@ class OpenAiEmbeddingProvider extends import_provider.EmbeddingProvider {
38
38
  createEmbedding() {
39
39
  return new import_openai.OpenAIEmbeddings({
40
40
  configuration: {
41
- baseURL: this.baseURL ?? "",
41
+ baseURL: this.baseURL,
42
42
  apiKey: this.apiKey
43
43
  },
44
44
  model: this.model
@@ -37,7 +37,7 @@ class OpenAIResponsesProvider extends import_provider.LLMProvider {
37
37
  return "https://api.openai.com/v1";
38
38
  }
39
39
  createModel() {
40
- const { baseURL, apiKey } = this.serviceOptions || {};
40
+ const { apiKey } = this.serviceOptions || {};
41
41
  const { responseFormat, structuredOutput } = this.modelOptions || {};
42
42
  const { schema } = structuredOutput || {};
43
43
  const responseFormatOptions = {
@@ -56,7 +56,7 @@ class OpenAIResponsesProvider extends import_provider.LLMProvider {
56
56
  }
57
57
  },
58
58
  configuration: {
59
- baseURL: baseURL || this.baseURL
59
+ baseURL: this.getResolvedBaseURL()
60
60
  },
61
61
  verbose: false,
62
62
  useResponsesApi: true
@@ -91,6 +91,8 @@ export declare abstract class LLMProvider {
91
91
  parseResponseMetadata(output: LLMResult): any;
92
92
  parseResponseError(err: any): any;
93
93
  protected get documentLoader(): CachedDocumentLoader;
94
+ protected getResolvedBaseURL(): string;
95
+ protected buildRequestURL(pathname: string): string;
94
96
  protected get aiPlugin(): PluginAIServer;
95
97
  }
96
98
  export interface EmbeddingProviderOptions {
@@ -107,6 +109,6 @@ export declare abstract class EmbeddingProvider {
107
109
  abstract createEmbedding(): EmbeddingsInterface;
108
110
  protected abstract getDefaultUrl(): string;
109
111
  protected get apiKey(): any;
110
- protected get baseURL(): any;
112
+ protected get baseURL(): string;
111
113
  protected get model(): any;
112
114
  }
@@ -40,12 +40,26 @@ __export(provider_exports, {
40
40
  LLMProvider: () => LLMProvider
41
41
  });
42
42
  module.exports = __toCommonJS(provider_exports);
43
- var import_axios = __toESM(require("axios"));
44
- var import_utils = require("../utils");
43
+ var import_utils = require("@nocobase/utils");
44
+ var import_utils2 = require("../utils");
45
45
  var import_stream = require("@langchain/core/utils/stream");
46
46
  var import_document_loader = require("../document-loader");
47
47
  var import_node_path = __toESM(require("node:path"));
48
48
  var import_reasoning = require("./common/reasoning");
49
+ function normalizeBaseURL(baseURL) {
50
+ (0, import_utils.checkUrlAgainstWhitelist)(baseURL);
51
+ return new URL(baseURL).toString().replace(/\/$/, "");
52
+ }
53
+ function resolveServiceOptions(serviceOptions, app) {
54
+ const rendered = app.environment.renderJsonTemplate(serviceOptions ?? {});
55
+ if ((rendered == null ? void 0 : rendered.baseURL) != null) {
56
+ if (typeof rendered.baseURL !== "string") {
57
+ throw new Error("baseURL must be a string");
58
+ }
59
+ rendered.baseURL = normalizeBaseURL(rendered.baseURL);
60
+ }
61
+ return rendered;
62
+ }
49
63
  class LLMProvider {
50
64
  app;
51
65
  serviceOptions;
@@ -57,7 +71,7 @@ class LLMProvider {
57
71
  constructor(opts) {
58
72
  const { app, serviceOptions, modelOptions } = opts;
59
73
  this.app = app;
60
- this.serviceOptions = app.environment.renderJsonTemplate(serviceOptions);
74
+ this.serviceOptions = resolveServiceOptions(serviceOptions, app);
61
75
  if (modelOptions) {
62
76
  this.modelOptions = modelOptions;
63
77
  this.chatModel = this.createModel();
@@ -69,7 +83,7 @@ class LLMProvider {
69
83
  prepareChain(context) {
70
84
  var _a, _b, _c, _d;
71
85
  let chain = this.chatModel;
72
- const toolDefinitions = (_a = context.tools) == null ? void 0 : _a.map(import_utils.buildTool);
86
+ const toolDefinitions = (_a = context.tools) == null ? void 0 : _a.map(import_utils2.buildTool);
73
87
  if ((_b = this.builtInTools()) == null ? void 0 : _b.length) {
74
88
  const tools = [...this.builtInTools()];
75
89
  if (!this.isToolConflict() && (toolDefinitions == null ? void 0 : toolDefinitions.length)) {
@@ -118,18 +132,19 @@ class LLMProvider {
118
132
  var _a, _b, _c, _d;
119
133
  const options = this.serviceOptions || {};
120
134
  const apiKey = options.apiKey;
121
- let baseURL = options.baseURL || this.baseURL;
122
- if (!baseURL) {
123
- return { code: 400, errMsg: "baseURL is required" };
135
+ let url;
136
+ try {
137
+ url = this.buildRequestURL("models");
138
+ } catch (e) {
139
+ return { code: 400, errMsg: e instanceof Error ? e.message : String(e) };
124
140
  }
125
141
  if (!apiKey) {
126
142
  return { code: 400, errMsg: "API Key required" };
127
143
  }
128
- if (baseURL && baseURL.endsWith("/")) {
129
- baseURL = baseURL.slice(0, -1);
130
- }
131
144
  try {
132
- const res = await import_axios.default.get(`${baseURL}/models`, {
145
+ const res = await (0, import_utils.serverRequest)({
146
+ method: "GET",
147
+ url,
133
148
  headers: {
134
149
  Authorization: `Bearer ${apiKey}`
135
150
  }
@@ -143,10 +158,10 @@ class LLMProvider {
143
158
  }
144
159
  }
145
160
  parseResponseMessage(message) {
146
- return (0, import_utils.parseResponseMessage)(message);
161
+ return (0, import_utils2.parseResponseMessage)(message);
147
162
  }
148
163
  parseResponseChunk(chunk) {
149
- return (0, import_utils.stripToolCallTags)(chunk);
164
+ return (0, import_utils2.stripToolCallTags)(chunk);
150
165
  }
151
166
  async parseAttachment(ctx, attachment) {
152
167
  if (this.isApiSupportedAttachment(attachment)) {
@@ -181,7 +196,7 @@ class LLMProvider {
181
196
  async convertToContent(ctx, attachment) {
182
197
  const fileManager = this.app.pm.get("file-manager");
183
198
  const url = await fileManager.getFileURL(attachment);
184
- const data = await (0, import_utils.encodeFile)(ctx, decodeURIComponent(url));
199
+ const data = await (0, import_utils2.encodeFile)(ctx, decodeURIComponent(url));
185
200
  if (attachment.mimetype.startsWith("image/")) {
186
201
  return {
187
202
  placement: "contentBlocks",
@@ -207,17 +222,16 @@ class LLMProvider {
207
222
  }
208
223
  }
209
224
  async loadDocument(ctx, attachment) {
210
- const referer = ctx.get("referer") || "";
211
- const ua = ctx.get("user-agent") || "";
212
225
  const safeFilename = attachment.filename ? import_node_path.default.basename(attachment.filename) : "document";
213
- const parsed = await this.documentLoader.load(attachment, {
226
+ const loaderOptions = typeof ctx.get === "function" ? {
214
227
  requestOptions: {
215
228
  headers: {
216
- Referer: referer,
217
- "User-Agent": ua
229
+ Referer: ctx.get("referer") || "",
230
+ "User-Agent": ctx.get("user-agent") || ""
218
231
  }
219
232
  }
220
- });
233
+ } : void 0;
234
+ const parsed = await this.documentLoader.load(attachment, loaderOptions);
221
235
  if (!parsed.supported) {
222
236
  return {
223
237
  placement: "system",
@@ -307,6 +321,22 @@ ${parsed.text}
307
321
  get documentLoader() {
308
322
  return this.aiPlugin.documentLoaders.cached;
309
323
  }
324
+ getResolvedBaseURL() {
325
+ var _a;
326
+ const baseURL = ((_a = this.serviceOptions) == null ? void 0 : _a.baseURL) ?? this.baseURL;
327
+ if (!baseURL) {
328
+ throw new Error("baseURL is required");
329
+ }
330
+ if (typeof baseURL !== "string") {
331
+ throw new Error("baseURL must be a string");
332
+ }
333
+ return normalizeBaseURL(baseURL);
334
+ }
335
+ buildRequestURL(pathname) {
336
+ const url = new URL(pathname.replace(/^\/+/, ""), `${this.getResolvedBaseURL()}/`).toString();
337
+ (0, import_utils.checkUrlAgainstWhitelist)(url);
338
+ return url;
339
+ }
310
340
  get aiPlugin() {
311
341
  return this.app.pm.get("ai");
312
342
  }
@@ -316,7 +346,7 @@ class EmbeddingProvider {
316
346
  this.opts = opts;
317
347
  const { app, serviceOptions, modelOptions } = this.opts;
318
348
  this.app = app;
319
- this.serviceOptions = app.environment.renderJsonTemplate(serviceOptions ?? {});
349
+ this.serviceOptions = resolveServiceOptions(serviceOptions, app);
320
350
  this.modelOptions = modelOptions;
321
351
  }
322
352
  app;
@@ -335,7 +365,10 @@ class EmbeddingProvider {
335
365
  if (!baseURL) {
336
366
  throw new Error("baseURL is required");
337
367
  }
338
- return baseURL;
368
+ if (typeof baseURL !== "string") {
369
+ throw new Error("baseURL must be a string");
370
+ }
371
+ return normalizeBaseURL(baseURL);
339
372
  }
340
373
  get model() {
341
374
  const { model } = this.modelOptions ?? {};
@@ -38,7 +38,7 @@ class XAIProvider extends import_provider.LLMProvider {
38
38
  return "https://api.x.ai/v1";
39
39
  }
40
40
  createModel() {
41
- const { baseURL, apiKey } = this.serviceOptions || {};
41
+ const { apiKey } = this.serviceOptions || {};
42
42
  const { responseFormat, structuredOutput, ...restModelOptions } = this.modelOptions || {};
43
43
  const { schema } = structuredOutput || {};
44
44
  const responseFormatOptions = {
@@ -50,7 +50,7 @@ class XAIProvider extends import_provider.LLMProvider {
50
50
  return new import_xai.ChatXAI({
51
51
  apiKey,
52
52
  ...restModelOptions,
53
- baseURL: baseURL || this.baseURL,
53
+ baseURL: this.getResolvedBaseURL(),
54
54
  modelKwargs: {
55
55
  response_format: responseFormatOptions
56
56
  }
@@ -39,7 +39,10 @@ __export(ai_exports, {
39
39
  default: () => ai_default
40
40
  });
41
41
  module.exports = __toCommonJS(ai_exports);
42
+ var import_package = require("../../../package.json");
42
43
  var import_lodash = __toESM(require("lodash"));
44
+ const getModelsListFailedMessage = "Get models list failed, you can enter a model name manually.";
45
+ const testFlightFailedMessage = "LLM service test failed. Please check the service configuration.";
43
46
  const aiResource = {
44
47
  name: "ai",
45
48
  actions: {
@@ -98,10 +101,7 @@ const aiResource = {
98
101
  const res = await provider.listModels();
99
102
  if (res.errMsg) {
100
103
  ctx.log.error(res.errMsg);
101
- ctx.throw(
102
- res.code || 500,
103
- `${ctx.t("Get models list failed, you can enter a model name manually.")} ${res.errMsg}`
104
- );
104
+ ctx.throw(res.code || 500, ctx.t(getModelsListFailedMessage, { ns: import_package.name }));
105
105
  }
106
106
  ctx.body = res.models || [];
107
107
  }
@@ -122,10 +122,7 @@ const aiResource = {
122
122
  const res = await providerClient.listModels();
123
123
  if (res.errMsg) {
124
124
  ctx.log.error(res.errMsg);
125
- ctx.throw(
126
- res.code || 500,
127
- `${ctx.t("Get models list failed, you can enter a model name manually.")} ${res.errMsg}`
128
- );
125
+ ctx.throw(res.code || 500, ctx.t(getModelsListFailedMessage, { ns: import_package.name }));
129
126
  }
130
127
  const models = res.models || [];
131
128
  if (model) {
@@ -151,7 +148,12 @@ const aiResource = {
151
148
  responseFormat: "text"
152
149
  }
153
150
  });
154
- ctx.body = await providerClient.testFlight();
151
+ const result = await providerClient.testFlight();
152
+ if (result.status === "error") {
153
+ ctx.log.error(result.message);
154
+ result.message = ctx.t(testFlightFailedMessage, { ns: import_package.name });
155
+ }
156
+ ctx.body = result;
155
157
  return next();
156
158
  },
157
159
  listAllEnabledModels: async (ctx, next) => {
@@ -436,8 +436,7 @@ async function parseAssignees(node, processor) {
436
436
  if (plainIds.length) {
437
437
  const users = await UserRepo.find({
438
438
  filter: { id: { $in: plainIds } },
439
- fields: ["id"],
440
- transaction: processor.mainTransaction
439
+ fields: ["id"]
441
440
  });
442
441
  users.forEach((u) => validIdSet.add(u.id));
443
442
  }
@@ -454,8 +453,7 @@ async function parseAssignees(node, processor) {
454
453
  }
455
454
  const result = await UserRepo.find({
456
455
  ...item,
457
- fields: ["id"],
458
- transaction: processor.mainTransaction
456
+ fields: ["id"]
459
457
  });
460
458
  result.forEach((user) => addAssignee(user.id));
461
459
  } else {
@@ -21,10 +21,10 @@ export type AIEmployeeInstructionConfig = {
21
21
  [key: string]: any;
22
22
  };
23
23
  webSearch?: boolean;
24
- model: {
24
+ model?: {
25
25
  llmService: string;
26
26
  model: string;
27
- };
27
+ } | null;
28
28
  requiresApproval?: RequiresApproval;
29
29
  assignees?: string[];
30
30
  userId: string;
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "description": "Create AI employees with diverse skills to collaborate with humans, build systems, and handle business operations.",
7
7
  "description.ru-RU": "Поддержка интеграции с AI-сервисами: предоставляются AI-узлы для рабочих процессов, расширяя возможности бизнес-обработки.",
8
8
  "description.zh-CN": "创建各种技能的 AI 员工,与人类协同,搭建系统,处理业务。",
9
- "version": "2.1.0-beta.43",
9
+ "version": "2.1.0-beta.45",
10
10
  "main": "dist/server/index.js",
11
11
  "homepage": "https://docs.nocobase.com/handbook/action-ai",
12
12
  "homepage.ru-RU": "https://docs-ru.nocobase.com/handbook/action-ai",
@@ -64,5 +64,5 @@
64
64
  "keywords": [
65
65
  "AI"
66
66
  ],
67
- "gitHead": "6d7750e2373bf2451d246de88cc1f62491685e18"
67
+ "gitHead": "42587115fc34c3eb01ef2b2549f1c998e5708318"
68
68
  }
@@ -1,41 +0,0 @@
1
- ---
2
- title: "nb app down"
3
- description: "nb app down command reference: stop and clean up local runtime resources for a selected env."
4
- keywords: "nb app down,NocoBase CLI,cleanup,remove containers,storage"
5
- ---
6
-
7
- # nb app down
8
-
9
- Stop and clean up local runtime resources for a selected env. Storage data and env configuration are kept by default; pass `--all --force` explicitly to delete everything.
10
-
11
- ## Usage
12
-
13
- ```bash
14
- nb app down [flags]
15
- ```
16
-
17
- ## Parameters
18
-
19
- | Parameter | Type | Description |
20
- | --- | --- | --- |
21
- | `--env`, `-e` | string | CLI env name to clean up; uses the current env if omitted |
22
- | `--all` | boolean | Delete all content for the env, including storage data and saved env configuration |
23
- | `--yes`, `-y` | boolean | When an explicitly passed `--env` targets a different env than the current env, skip the interactive confirmation prompt |
24
- | `--force`, `-f` | boolean | Force destructive cleanup, such as `--all` or other high-risk cleanup in non-interactive mode |
25
- | `--verbose` | boolean | Show underlying stop and cleanup command output |
26
-
27
- ## Examples
28
-
29
- ```bash
30
- nb app down --env app1
31
- nb app down --env app1 --all --force
32
- nb app down --env app1 --force
33
- ```
34
-
35
- `--yes` only skips the interactive confirmation when an explicitly passed `--env` targets a different env than the current env. `--force` is for actually forcing destructive cleanup, such as `--all` or other high-risk cleanup in non-interactive mode.
36
-
37
- ## Related Commands
38
-
39
- - [`nb app stop`](./stop.md)
40
- - [`nb env remove`](../env/remove.md)
41
- - [`nb db stop`](../db/stop.md)