plugin-agent-orchestrator 1.0.14 → 1.0.15

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 (28) hide show
  1. package/dist/externalVersion.js +6 -6
  2. package/dist/server/collections/agent-execution-spans.d.ts +1 -1
  3. package/dist/server/collections/orchestrator-config.d.ts +1 -1
  4. package/dist/server/collections/orchestrator-logs.d.ts +1 -1
  5. package/dist/server/collections/skill-definitions.d.ts +0 -1
  6. package/dist/server/collections/skill-executions.d.ts +0 -1
  7. package/dist/server/collections/skill-worker-configs.d.ts +0 -1
  8. package/dist/server/services/CodeValidator.js +1 -0
  9. package/dist/server/skill-hub/tasks/SkillExecutionTask.d.ts +2 -0
  10. package/dist/server/skill-hub/tasks/SkillExecutionTask.js +122 -0
  11. package/package.json +1 -1
  12. package/src/client/index.tsx +1 -1
  13. package/src/client/plugin.tsx +54 -54
  14. package/src/client/skill-hub/index.tsx +75 -75
  15. package/src/server/migrations/20260423000000-add-progress-fields.ts +5 -5
  16. package/src/server/migrations/20260425000000-add-interaction-schema.ts +5 -5
  17. package/src/server/migrations/20260427000000-add-tracing-detail-fields.ts +5 -5
  18. package/src/server/migrations/20260427000000-change-packages-to-text.ts +7 -7
  19. package/src/server/migrations/20260427000001-change-other-json-to-text.ts +10 -10
  20. package/src/server/migrations/20260429000000-add-llm-fields.ts +2 -2
  21. package/src/server/migrations/20260429000000-fix-inputargs-json-to-text.ts +2 -2
  22. package/src/server/migrations/20260503000000-add-orchestrator-trace-fields.ts +2 -2
  23. package/src/server/plugin.ts +94 -94
  24. package/src/server/services/CodeValidator.ts +5 -5
  25. package/src/server/services/SkillManager.ts +1 -1
  26. package/src/server/services/WorkerEnvManager.ts +5 -5
  27. package/src/server/skill-hub/plugin.ts +58 -58
  28. package/src/server/skill-hub/tasks/SkillExecutionTask.ts +162 -16
@@ -9,14 +9,14 @@
9
9
 
10
10
  module.exports = {
11
11
  "react": "18.2.0",
12
- "@nocobase/client": "2.0.46",
12
+ "@nocobase/client": "2.0.49",
13
13
  "antd": "5.24.2",
14
14
  "@ant-design/icons": "5.6.1",
15
- "@nocobase/server": "2.0.46",
16
- "@nocobase/database": "2.0.46",
17
- "@nocobase/actions": "2.0.46",
15
+ "@nocobase/server": "2.0.49",
16
+ "@nocobase/database": "2.0.49",
17
+ "@nocobase/actions": "2.0.49",
18
18
  "@langchain/langgraph": "0.2.74",
19
19
  "@langchain/core": "0.3.80",
20
- "@nocobase/plugin-ai": "2.0.46",
21
- "@nocobase/ai": "2.0.46"
20
+ "@nocobase/plugin-ai": "2.0.49",
21
+ "@nocobase/ai": "2.0.49"
22
22
  };
@@ -5,5 +5,5 @@
5
5
  * keeps its own sandbox execution records; this collection stores the flow
6
6
  * relationship and links to those records when applicable.
7
7
  */
8
- declare const _default: import("@nocobase/database").CollectionOptions;
8
+ declare const _default: any;
9
9
  export default _default;
@@ -1,2 +1,2 @@
1
- declare const _default: import("@nocobase/database").CollectionOptions;
1
+ declare const _default: any;
2
2
  export default _default;
@@ -4,5 +4,5 @@
4
4
  * Since createReactAgent doesn't create aiConversation records,
5
5
  * we log delegation events to a dedicated table for observability.
6
6
  */
7
- declare const _default: import("@nocobase/database").CollectionOptions;
7
+ declare const _default: any;
8
8
  export default _default;
@@ -1,3 +1,2 @@
1
- import { CollectionOptions } from '@nocobase/database';
2
1
  declare const _default: CollectionOptions;
3
2
  export default _default;
@@ -1,3 +1,2 @@
1
- import { CollectionOptions } from '@nocobase/database';
2
1
  declare const _default: CollectionOptions;
3
2
  export default _default;
@@ -1,3 +1,2 @@
1
- import { CollectionOptions } from '@nocobase/database';
2
1
  declare const _default: CollectionOptions;
3
2
  export default _default;
@@ -111,6 +111,7 @@ const PYTHON_BUILTINS = [
111
111
  "logging",
112
112
  "unittest",
113
113
  "argparse",
114
+ "ast",
114
115
  "tempfile",
115
116
  "xml",
116
117
  "zipfile",
@@ -11,4 +11,6 @@ export declare class SkillExecutionTask {
11
11
  constructor(execution: any, sandboxRunner: SandboxRunner, fileManager: FileManager, skillRepoService: SkillRepositoryService, app: Application);
12
12
  run(): Promise<void>;
13
13
  private renderTemplate;
14
+ private installGeneratedSkillIfRequested;
15
+ private validateGeneratedSkillPackages;
14
16
  }
@@ -29,7 +29,9 @@ __export(SkillExecutionTask_exports, {
29
29
  SkillExecutionTask: () => SkillExecutionTask
30
30
  });
31
31
  module.exports = __toCommonJS(SkillExecutionTask_exports);
32
+ var import_fs = require("fs");
32
33
  var import_path = require("path");
34
+ var import_CodeValidator = require("../../services/CodeValidator");
33
35
  var import_json_fields = require("../utils/json-fields");
34
36
  class TaskAbortController {
35
37
  listeners = [];
@@ -203,6 +205,12 @@ class SkillExecutionTask {
203
205
  this.app.pubSubManager.publish(`skill-hub.progress.${execId}`, progress);
204
206
  }
205
207
  });
208
+ if (result.success) {
209
+ const installMessage = await this.installGeneratedSkillIfRequested(execId);
210
+ if (installMessage) {
211
+ result.stdout = [result.stdout, installMessage].filter(Boolean).join("\n");
212
+ }
213
+ }
206
214
  let status;
207
215
  if (result.canceled) {
208
216
  status = "canceled";
@@ -260,6 +268,120 @@ class SkillExecutionTask {
260
268
  code = code.replaceAll("{{skillDir}}", (skillDir || "").replace(/\\/g, "/"));
261
269
  return code;
262
270
  }
271
+ async installGeneratedSkillIfRequested(execId) {
272
+ const manifestPath = this.fileManager.getOutputFilePath(execId, "skill-hub-install.json");
273
+ if (!manifestPath) return null;
274
+ let manifest;
275
+ try {
276
+ manifest = JSON.parse((0, import_fs.readFileSync)(manifestPath, "utf8"));
277
+ } catch (error) {
278
+ throw new Error(`Generated skill install manifest is invalid JSON: ${error instanceof Error ? error.message : String(error)}`);
279
+ }
280
+ if (!(manifest == null ? void 0 : manifest.autoInstall)) return null;
281
+ const skill = manifest.skill || {};
282
+ const name = String(skill.name || "").trim();
283
+ if (!/^[a-z0-9][a-z0-9-]{0,63}$/.test(name)) {
284
+ throw new Error(`Generated skill name "${name}" is invalid. Use lowercase letters, numbers, and hyphens.`);
285
+ }
286
+ const language = skill.language;
287
+ if (language !== "python" && language !== "node") {
288
+ throw new Error(`Generated skill "${name}" has unsupported language "${language}".`);
289
+ }
290
+ if (!skill.codeTemplate) {
291
+ throw new Error(`Generated skill "${name}" is missing codeTemplate.`);
292
+ }
293
+ const validator = new import_CodeValidator.CodeValidator();
294
+ validator.validate(skill.codeTemplate, language);
295
+ await this.validateGeneratedSkillPackages(name, language, skill.packages);
296
+ const outputDir = this.fileManager.getOutputDir(execId);
297
+ const outputRoot = (0, import_path.resolve)(outputDir);
298
+ const packageDirName = String(manifest.packageDir || name);
299
+ const packageDir = (0, import_path.resolve)(outputRoot, packageDirName);
300
+ if (packageDir !== outputRoot && !packageDir.startsWith(outputRoot + import_path.sep) || !(0, import_fs.existsSync)(packageDir)) {
301
+ throw new Error(`Generated skill package directory "${packageDirName}" was not found in output.`);
302
+ }
303
+ if (manifest.testInput && Object.keys(manifest.testInput).length > 0) {
304
+ const verifyExecId = `${execId}-verify-${name}`;
305
+ const verifyCode = this.renderTemplate(skill.codeTemplate, manifest.testInput, verifyExecId, packageDir);
306
+ const verifyResult = await this.sandboxRunner.execute({
307
+ language,
308
+ code: verifyCode,
309
+ execId: verifyExecId,
310
+ timeoutSeconds: Math.min(Number(skill.timeoutSeconds || 60), 30),
311
+ maxOutputSizeMb: Math.min(Number(skill.maxOutputSizeMb || 50), 10),
312
+ skillDir: packageDir
313
+ });
314
+ if (!verifyResult.success) {
315
+ throw new Error(
316
+ `Generated skill "${name}" failed smoke verification: ${verifyResult.stderr || verifyResult.stdout || "unknown error"}`
317
+ );
318
+ }
319
+ }
320
+ const skillRepoDir = this.skillRepoService.getSkillPath(name);
321
+ if ((0, import_fs.existsSync)(skillRepoDir)) {
322
+ (0, import_fs.rmSync)(skillRepoDir, { recursive: true, force: true });
323
+ }
324
+ (0, import_fs.cpSync)(packageDir, skillRepoDir, {
325
+ recursive: true,
326
+ force: true,
327
+ filter: (src) => {
328
+ const leaf = src.split(/[\\/]/).pop();
329
+ return !["node_modules", ".git", "__pycache__"].includes(leaf || "") && !src.endsWith(".pyc");
330
+ }
331
+ });
332
+ const values = {
333
+ name,
334
+ title: skill.title || name,
335
+ description: skill.description || "",
336
+ instructions: skill.instructions || "",
337
+ language,
338
+ codeTemplate: skill.codeTemplate,
339
+ inputSchema: (0, import_json_fields.stringifyJsonText)(skill.inputSchema || { type: "object", properties: {} }),
340
+ packages: (0, import_json_fields.stringifyJsonText)(skill.packages || [], []),
341
+ timeoutSeconds: skill.timeoutSeconds || 60,
342
+ maxOutputSizeMb: skill.maxOutputSizeMb || 50,
343
+ enabled: skill.enabled !== false,
344
+ toolScope: skill.toolScope || "CUSTOM",
345
+ autoCall: !!skill.autoCall,
346
+ storageType: "local",
347
+ storageUrl: `local://generated/${name}`
348
+ };
349
+ if (skill.interactionSchema) {
350
+ values.interactionSchema = (0, import_json_fields.stringifyJsonText)(skill.interactionSchema);
351
+ }
352
+ const repo = this.app.db.getRepository("skillDefinitions");
353
+ const existing = await repo.findOne({ filter: { name } });
354
+ if (existing) {
355
+ if (manifest.overwrite === false) {
356
+ throw new Error(`Skill "${name}" already exists and overwrite=false.`);
357
+ }
358
+ await repo.update({ filter: { name }, values });
359
+ return `[skill-hub] Updated generated skill "${name}" in Skill Hub.`;
360
+ }
361
+ await repo.create({ values });
362
+ return `[skill-hub] Installed generated skill "${name}" in Skill Hub.`;
363
+ }
364
+ async validateGeneratedSkillPackages(name, language, packages) {
365
+ if (!Array.isArray(packages) || packages.length === 0) return;
366
+ if (!packages.every((pkg) => typeof pkg === "string" && pkg.trim())) {
367
+ throw new Error(`Generated skill "${name}" has invalid packages. Use an array of package names.`);
368
+ }
369
+ const workerConfig = await this.app.db.getRepository("skillWorkerConfigs").findOne();
370
+ if (!workerConfig) return;
371
+ const whitelist = (0, import_json_fields.parseJsonText)(
372
+ workerConfig.get ? workerConfig.get("packageWhitelist") : workerConfig.packageWhitelist,
373
+ null
374
+ );
375
+ const allowed = whitelist == null ? void 0 : whitelist[language];
376
+ if (!Array.isArray(allowed) || allowed.length === 0) return;
377
+ const allowedSet = new Set(allowed.map((pkg) => pkg.toLowerCase()));
378
+ const missing = packages.map((pkg) => pkg.trim()).filter((pkg) => !allowedSet.has(pkg.toLowerCase()));
379
+ if (missing.length > 0) {
380
+ throw new Error(
381
+ `Generated skill "${name}" requires ${language} package(s) not available in the Skill Hub worker environment: ${missing.join(", ")}. Add them to the worker environment and refresh/init Skill Hub before installing this skill.`
382
+ );
383
+ }
384
+ }
263
385
  }
264
386
  // Annotate the CommonJS export names for ESM import in node:
265
387
  0 && (module.exports = {
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "displayName.zh-CN": "代理协调器",
5
5
  "displayName.vi-VN": "Điều phối Agent",
6
6
  "description": "Hierarchical Multi-Agent orchestration for NocoBase AI Employees. Enables Leader agents to delegate tasks to Sub-Agent employees without modifying core plugin-ai.",
7
- "version": "1.0.14",
7
+ "version": "1.0.15",
8
8
  "license": "Apache-2.0",
9
9
  "main": "dist/server/index.js",
10
10
  "keywords": [
@@ -1 +1 @@
1
- export { default } from './plugin';
1
+ export { default } from './plugin';
@@ -1,54 +1,54 @@
1
- import { Plugin } from '@nocobase/client';
2
- import { OrchestratorSettings } from './OrchestratorSettings';
3
-
4
- import { InteractionSchemasProvider } from './skill-hub/tools/InteractionSchemasProvider';
5
- import { SkillHubCard } from './skill-hub/tools/SkillHubCard';
6
- import { parseJsonText } from './skill-hub/utils/jsonFields';
7
-
8
- const sanitize = (name: string) =>
9
- name
10
- .toLowerCase()
11
- .replace(/[^a-z0-9_]/g, '_')
12
- .replace(/_+/g, '_')
13
- .replace(/^_|_$/g, '');
14
-
15
- export class PluginAgentOrchestratorClient extends Plugin {
16
- async load() {
17
- this.app.use(InteractionSchemasProvider);
18
-
19
- // Register under the "AI" settings group for consistency with other AI plugins
20
- this.app.pluginSettingsManager.add('ai.orchestrator', {
21
- title: 'Agent Orchestrator',
22
- icon: 'ApartmentOutlined',
23
- Component: OrchestratorSettings,
24
- });
25
-
26
- await this.registerSkillUiCards();
27
- }
28
-
29
- private async registerSkillUiCards() {
30
- const toolsManager = this.app.aiManager?.toolsManager;
31
- if (!toolsManager) return;
32
-
33
- try {
34
- const { data } = await this.app.apiClient.request({
35
- url: 'skillDefinitions:list',
36
- params: {
37
- filter: { enabled: true },
38
- fields: ['name', 'autoCall', 'interactionSchema'],
39
- pageSize: 200,
40
- },
41
- });
42
- const list = (data as any)?.data ?? [];
43
- for (const s of list) {
44
- if (s.autoCall) continue;
45
- if (!parseJsonText(s.interactionSchema, null)) continue;
46
- toolsManager.registerTools(`skill_hub_${sanitize(s.name)}`, { ui: { card: SkillHubCard } });
47
- }
48
- } catch {
49
- // user without ACL or backend unavailable — skip silently
50
- }
51
- }
52
- }
53
-
54
- export default PluginAgentOrchestratorClient;
1
+ import { Plugin } from '@nocobase/client';
2
+ import { OrchestratorSettings } from './OrchestratorSettings';
3
+
4
+ import { InteractionSchemasProvider } from './skill-hub/tools/InteractionSchemasProvider';
5
+ import { SkillHubCard } from './skill-hub/tools/SkillHubCard';
6
+ import { parseJsonText } from './skill-hub/utils/jsonFields';
7
+
8
+ const sanitize = (name: string) =>
9
+ name
10
+ .toLowerCase()
11
+ .replace(/[^a-z0-9_]/g, '_')
12
+ .replace(/_+/g, '_')
13
+ .replace(/^_|_$/g, '');
14
+
15
+ export class PluginAgentOrchestratorClient extends Plugin {
16
+ async load() {
17
+ (this as any).app.use(InteractionSchemasProvider);
18
+
19
+ // Register under the "AI" settings group for consistency with other AI plugins
20
+ (this as any).app.pluginSettingsManager.add('ai.orchestrator', {
21
+ title: 'Agent Orchestrator',
22
+ icon: 'ApartmentOutlined',
23
+ Component: OrchestratorSettings,
24
+ });
25
+
26
+ await this.registerSkillUiCards();
27
+ }
28
+
29
+ private async registerSkillUiCards() {
30
+ const toolsManager = (this as any).app.aiManager?.toolsManager;
31
+ if (!toolsManager) return;
32
+
33
+ try {
34
+ const { data } = await (this as any).app.apiClient.request({
35
+ url: 'skillDefinitions:list',
36
+ params: {
37
+ filter: { enabled: true },
38
+ fields: ['name', 'autoCall', 'interactionSchema'],
39
+ pageSize: 200,
40
+ },
41
+ });
42
+ const list = (data as any)?.data ?? [];
43
+ for (const s of list) {
44
+ if (s.autoCall) continue;
45
+ if (!parseJsonText(s.interactionSchema, null)) continue;
46
+ toolsManager.registerTools(`skill_hub_${sanitize(s.name)}`, { ui: { card: SkillHubCard } });
47
+ }
48
+ } catch {
49
+ // user without ACL or backend unavailable — skip silently
50
+ }
51
+ }
52
+ }
53
+
54
+ export default PluginAgentOrchestratorClient;
@@ -1,75 +1,75 @@
1
- import { Plugin } from '@nocobase/client';
2
- import { SkillManager } from './components/SkillManager';
3
- import { ExecutionHistory } from './components/ExecutionHistory';
4
-
5
- import { SkillMetrics } from './components/SkillMetrics';
6
- import { InteractionSchemasProvider } from './tools/InteractionSchemasProvider';
7
- import { SkillHubCard } from './tools/SkillHubCard';
8
- import { parseJsonText } from './utils/jsonFields';
9
-
10
- const sanitize = (name: string) =>
11
- name
12
- .toLowerCase()
13
- .replace(/[^a-z0-9_]/g, '_')
14
- .replace(/_+/g, '_')
15
- .replace(/^_|_$/g, '');
16
-
17
- export class PluginSkillHubClient extends Plugin {
18
- async load() {
19
- this.app.use(InteractionSchemasProvider);
20
-
21
- this.app.pluginSettingsManager.add('skill-hub', {
22
- title: this.t('Skill Hub'),
23
- icon: 'CodeOutlined',
24
- });
25
-
26
- this.app.pluginSettingsManager.add('skill-hub.definitions', {
27
- title: this.t('Skill Definitions'),
28
- Component: SkillManager,
29
- aclSnippet: 'pm.skill-hub',
30
- });
31
-
32
- this.app.pluginSettingsManager.add('skill-hub.executions', {
33
- title: this.t('Execution History'),
34
- Component: ExecutionHistory,
35
- aclSnippet: 'pm.skill-hub',
36
- });
37
-
38
- this.app.pluginSettingsManager.add('skill-hub.metrics', {
39
- title: this.t('Dashboard Metrics'),
40
- Component: SkillMetrics,
41
- aclSnippet: 'pm.skill-hub',
42
- });
43
-
44
-
45
-
46
- await this.registerSkillUiCards();
47
- }
48
-
49
- private async registerSkillUiCards() {
50
- const toolsManager = this.app.aiManager?.toolsManager;
51
- if (!toolsManager) return;
52
-
53
- try {
54
- const { data } = await this.app.apiClient.request({
55
- url: 'skillDefinitions:list',
56
- params: {
57
- filter: { enabled: true },
58
- fields: ['name', 'autoCall', 'interactionSchema'],
59
- pageSize: 200,
60
- },
61
- });
62
- const list = (data as any)?.data ?? [];
63
- for (const s of list) {
64
- if (s.autoCall) continue;
65
- if (!parseJsonText(s.interactionSchema, null)) continue;
66
- toolsManager.registerTools(`skill_hub_${sanitize(s.name)}`, { ui: { card: SkillHubCard } });
67
- }
68
- } catch {
69
- // user without ACL or backend unavailable — skip silently
70
- }
71
- }
72
- }
73
-
74
- export { SkillManager, ExecutionHistory, SkillMetrics };
75
- export default PluginSkillHubClient;
1
+ import { Plugin } from '@nocobase/client';
2
+ import { SkillManager } from './components/SkillManager';
3
+ import { ExecutionHistory } from './components/ExecutionHistory';
4
+
5
+ import { SkillMetrics } from './components/SkillMetrics';
6
+ import { InteractionSchemasProvider } from './tools/InteractionSchemasProvider';
7
+ import { SkillHubCard } from './tools/SkillHubCard';
8
+ import { parseJsonText } from './utils/jsonFields';
9
+
10
+ const sanitize = (name: string) =>
11
+ name
12
+ .toLowerCase()
13
+ .replace(/[^a-z0-9_]/g, '_')
14
+ .replace(/_+/g, '_')
15
+ .replace(/^_|_$/g, '');
16
+
17
+ export class PluginSkillHubClient extends Plugin {
18
+ async load() {
19
+ (this as any).app.use(InteractionSchemasProvider);
20
+
21
+ (this as any).app.pluginSettingsManager.add('skill-hub', {
22
+ title: (this as any).t('Skill Hub'),
23
+ icon: 'CodeOutlined',
24
+ });
25
+
26
+ (this as any).app.pluginSettingsManager.add('skill-hub.definitions', {
27
+ title: (this as any).t('Skill Definitions'),
28
+ Component: SkillManager,
29
+ aclSnippet: 'pm.skill-hub',
30
+ });
31
+
32
+ (this as any).app.pluginSettingsManager.add('skill-hub.executions', {
33
+ title: (this as any).t('Execution History'),
34
+ Component: ExecutionHistory,
35
+ aclSnippet: 'pm.skill-hub',
36
+ });
37
+
38
+ (this as any).app.pluginSettingsManager.add('skill-hub.metrics', {
39
+ title: (this as any).t('Dashboard Metrics'),
40
+ Component: SkillMetrics,
41
+ aclSnippet: 'pm.skill-hub',
42
+ });
43
+
44
+
45
+
46
+ await this.registerSkillUiCards();
47
+ }
48
+
49
+ private async registerSkillUiCards() {
50
+ const toolsManager = (this as any).app.aiManager?.toolsManager;
51
+ if (!toolsManager) return;
52
+
53
+ try {
54
+ const { data } = await (this as any).app.apiClient.request({
55
+ url: 'skillDefinitions:list',
56
+ params: {
57
+ filter: { enabled: true },
58
+ fields: ['name', 'autoCall', 'interactionSchema'],
59
+ pageSize: 200,
60
+ },
61
+ });
62
+ const list = (data as any)?.data ?? [];
63
+ for (const s of list) {
64
+ if (s.autoCall) continue;
65
+ if (!parseJsonText(s.interactionSchema, null)) continue;
66
+ toolsManager.registerTools(`skill_hub_${sanitize(s.name)}`, { ui: { card: SkillHubCard } });
67
+ }
68
+ } catch {
69
+ // user without ACL or backend unavailable — skip silently
70
+ }
71
+ }
72
+ }
73
+
74
+ export { SkillManager, ExecutionHistory, SkillMetrics };
75
+ export default PluginSkillHubClient;
@@ -2,8 +2,8 @@ import { Migration } from '@nocobase/server';
2
2
 
3
3
  export default class AddProgressFieldsMigration extends Migration {
4
4
  async up() {
5
- const queryInterface = this.db.sequelize.getQueryInterface();
6
- const tablePrefix = this.db.options.tablePrefix || '';
5
+ const queryInterface = (this as any).db.sequelize.getQueryInterface();
6
+ const tablePrefix = (this as any).db.options.tablePrefix || '';
7
7
  const tableName = `${tablePrefix}skillWorkerConfigs`;
8
8
 
9
9
  try {
@@ -14,7 +14,7 @@ export default class AddProgressFieldsMigration extends Migration {
14
14
 
15
15
  // Force NocoBase fields metadata to recognize the physical columns exists
16
16
  // so it won't crash trying to ADD COLUMN during db.sync()
17
- const fieldRepo = this.db.getRepository('fields');
17
+ const fieldRepo = (this as any).db.getRepository('fields');
18
18
  const collectionName = 'skillWorkerConfigs';
19
19
 
20
20
  const fieldsToSync = [
@@ -40,11 +40,11 @@ export default class AddProgressFieldsMigration extends Migration {
40
40
  interface: f.type,
41
41
  }
42
42
  });
43
- this.app.logger.info(`[skill-hub] Restored NocoBase metadata for preexisting column ${f.name}`);
43
+ (this as any).app.logger.info(`[skill-hub] Restored NocoBase metadata for preexisting column ${f.name}`);
44
44
  }
45
45
  }
46
46
  } catch (error) {
47
- this.app.logger.error(`[skill-hub] Failed to check progress fields: ${error.message}`);
47
+ (this as any).app.logger.error(`[skill-hub] Failed to check progress fields: ${error.message}`);
48
48
  }
49
49
  }
50
50
  }
@@ -2,15 +2,15 @@ import { Migration } from '@nocobase/server';
2
2
 
3
3
  export default class AddInteractionSchemaMigration extends Migration {
4
4
  async up() {
5
- const queryInterface = this.db.sequelize.getQueryInterface();
6
- const tableName = `${this.db.options.tablePrefix || ''}skillDefinitions`;
5
+ const queryInterface = (this as any).db.sequelize.getQueryInterface();
6
+ const tableName = `${(this as any).db.options.tablePrefix || ''}skillDefinitions`;
7
7
 
8
8
  try {
9
9
  const tableExists = await queryInterface.tableExists(tableName);
10
10
  if (!tableExists) return;
11
11
 
12
12
  const tableDesc = await queryInterface.describeTable(tableName);
13
- const fieldRepo = this.db.getRepository('fields');
13
+ const fieldRepo = (this as any).db.getRepository('fields');
14
14
  const collectionName = 'skillDefinitions';
15
15
 
16
16
  const fieldMeta = await fieldRepo.findOne({
@@ -26,10 +26,10 @@ export default class AddInteractionSchemaMigration extends Migration {
26
26
  interface: 'textarea',
27
27
  },
28
28
  });
29
- this.app.logger.info('[skill-hub] Restored NocoBase metadata for preexisting column interactionSchema');
29
+ (this as any).app.logger.info('[skill-hub] Restored NocoBase metadata for preexisting column interactionSchema');
30
30
  }
31
31
  } catch (error) {
32
- this.app.logger.error(`[skill-hub] Failed to check interactionSchema field: ${error.message}`);
32
+ (this as any).app.logger.error(`[skill-hub] Failed to check interactionSchema field: ${error.message}`);
33
33
  }
34
34
  }
35
35
  }
@@ -5,9 +5,9 @@ export default class AddTracingDetailFieldsMigration extends Migration {
5
5
  appVersion = '<=2.x';
6
6
 
7
7
  async up() {
8
- const queryInterface = this.db.sequelize.getQueryInterface();
9
- const DataTypes = this.db.sequelize.constructor['DataTypes'];
10
- const tableName = `${this.db.options.tablePrefix || ''}orchestratorLogs`;
8
+ const queryInterface = (this as any).db.sequelize.getQueryInterface();
9
+ const DataTypes = (this as any).db.sequelize.constructor['DataTypes'];
10
+ const tableName = `${(this as any).db.options.tablePrefix || ''}orchestratorLogs`;
11
11
 
12
12
  const tableExists = await queryInterface
13
13
  .describeTable(tableName)
@@ -31,8 +31,8 @@ export default class AddTracingDetailFieldsMigration extends Migration {
31
31
  }
32
32
 
33
33
  async down() {
34
- const queryInterface = this.db.sequelize.getQueryInterface();
35
- const tableName = `${this.db.options.tablePrefix || ''}orchestratorLogs`;
34
+ const queryInterface = (this as any).db.sequelize.getQueryInterface();
35
+ const tableName = `${(this as any).db.options.tablePrefix || ''}orchestratorLogs`;
36
36
 
37
37
  for (const column of ['context', 'trace', 'messages']) {
38
38
  await queryInterface.removeColumn(tableName, column).catch(() => {});
@@ -2,8 +2,8 @@ import { Migration } from '@nocobase/server';
2
2
 
3
3
  export default class ChangePackagesToTextMigration extends Migration {
4
4
  async up() {
5
- const queryInterface = this.db.sequelize.getQueryInterface();
6
- const tableName = `${this.db.options.tablePrefix || ''}skillDefinitions`;
5
+ const queryInterface = (this as any).db.sequelize.getQueryInterface();
6
+ const tableName = `${(this as any).db.options.tablePrefix || ''}skillDefinitions`;
7
7
 
8
8
  try {
9
9
  const tableExists = await queryInterface.tableExists(tableName);
@@ -11,15 +11,15 @@ export default class ChangePackagesToTextMigration extends Migration {
11
11
 
12
12
  const tableDesc = await queryInterface.describeTable(tableName);
13
13
  const columnsToChange = ['packages', 'inputSchema', 'interactionSchema'];
14
- const fieldRepo = this.db.getRepository('fields');
14
+ const fieldRepo = (this as any).db.getRepository('fields');
15
15
  const collectionName = 'skillDefinitions';
16
16
 
17
17
  for (const col of columnsToChange) {
18
18
  if (tableDesc[col]) {
19
19
  // Change physical column type in Postgres if needed
20
- const dialect = this.db.sequelize.getDialect();
20
+ const dialect = (this as any).db.sequelize.getDialect();
21
21
  if (dialect === 'postgres') {
22
- await this.db.sequelize.query(`ALTER TABLE "${tableName}" ALTER COLUMN "${col}" TYPE text USING "${col}"::text;`);
22
+ await (this as any).db.sequelize.query(`ALTER TABLE "${tableName}" ALTER COLUMN "${col}" TYPE text USING "${col}"::text;`);
23
23
  } else {
24
24
  await queryInterface.changeColumn(tableName, col, {
25
25
  type: 'TEXT',
@@ -37,11 +37,11 @@ export default class ChangePackagesToTextMigration extends Migration {
37
37
  values: { type: 'text' },
38
38
  });
39
39
  }
40
- this.app.logger.info(`[skill-hub] Changed ${col} column type to text to support markdown`);
40
+ (this as any).app.logger.info(`[skill-hub] Changed ${col} column type to text to support markdown`);
41
41
  }
42
42
  }
43
43
  } catch (error) {
44
- this.app.logger.error(`[skill-hub] Failed to change packages field type: ${error.message}`);
44
+ (this as any).app.logger.error(`[skill-hub] Failed to change packages field type: ${error.message}`);
45
45
  }
46
46
  }
47
47
  }