plugin-agent-orchestrator 1.0.17 → 1.0.19

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 (141) hide show
  1. package/dist/client/AIEmployeeSelect.d.ts +11 -0
  2. package/dist/client/AIEmployeesContext.d.ts +30 -0
  3. package/dist/client/AgentRunsTab.d.ts +2 -0
  4. package/dist/client/HarnessProfilesTab.d.ts +2 -0
  5. package/dist/client/OrchestratorSettings.d.ts +3 -0
  6. package/dist/client/RulesTab.d.ts +2 -0
  7. package/dist/client/TracingTab.d.ts +2 -0
  8. package/dist/client/index.d.ts +1 -0
  9. package/dist/client/index.js +1 -1
  10. package/dist/client/plugin.d.ts +6 -0
  11. package/dist/client/skill-hub/components/ExecutionHistory.d.ts +2 -0
  12. package/dist/client/skill-hub/components/ExecutionProgress.d.ts +20 -0
  13. package/dist/client/skill-hub/components/GitSkillImport.d.ts +7 -0
  14. package/dist/client/skill-hub/components/LoopSettings.d.ts +2 -0
  15. package/dist/client/skill-hub/components/SkillEditor.d.ts +7 -0
  16. package/dist/client/skill-hub/components/SkillManager.d.ts +2 -0
  17. package/dist/client/skill-hub/components/SkillMetrics.d.ts +2 -0
  18. package/dist/client/skill-hub/components/SkillTestPanel.d.ts +7 -0
  19. package/dist/client/skill-hub/index.d.ts +11 -0
  20. package/dist/client/skill-hub/locale.d.ts +3 -0
  21. package/dist/client/skill-hub/tools/InteractionSchemasProvider.d.ts +6 -0
  22. package/dist/client/skill-hub/tools/SkillHubCard.d.ts +3 -0
  23. package/dist/client/skill-hub/tools/loopTemplates.d.ts +22 -0
  24. package/dist/client/skill-hub/tools/registerSkillLoopCards.d.ts +1 -0
  25. package/dist/client/skill-hub/utils/jsonFields.d.ts +3 -0
  26. package/dist/client/tools/PlanApprovalCard.d.ts +3 -0
  27. package/dist/client/tools/registerOrchestratorCards.d.ts +1 -0
  28. package/dist/externalVersion.js +6 -6
  29. package/dist/index.d.ts +2 -0
  30. package/dist/server/collections/agent-execution-spans.d.ts +9 -0
  31. package/dist/server/collections/agent-harness-profiles.d.ts +2 -0
  32. package/dist/server/collections/agent-harness-profiles.js +89 -0
  33. package/dist/server/collections/agent-loop-events.d.ts +2 -0
  34. package/dist/server/collections/agent-loop-events.js +101 -0
  35. package/dist/server/collections/agent-loop-runs.d.ts +2 -0
  36. package/dist/server/collections/agent-loop-runs.js +188 -0
  37. package/dist/server/collections/agent-loop-steps.d.ts +2 -0
  38. package/dist/server/collections/agent-loop-steps.js +174 -0
  39. package/dist/server/collections/orchestrator-config.d.ts +2 -0
  40. package/dist/server/collections/orchestrator-config.js +7 -0
  41. package/dist/server/collections/orchestrator-logs.d.ts +8 -0
  42. package/dist/server/collections/skill-definitions.d.ts +3 -0
  43. package/dist/server/collections/skill-executions.d.ts +3 -0
  44. package/dist/server/collections/skill-executions.js +12 -0
  45. package/dist/server/collections/skill-loop-configs.d.ts +3 -0
  46. package/dist/server/collections/skill-loop-configs.js +94 -0
  47. package/dist/server/collections/skill-worker-configs.d.ts +3 -0
  48. package/dist/server/index.d.ts +1 -0
  49. package/dist/server/migrations/20260423000000-add-progress-fields.d.ts +4 -0
  50. package/dist/server/migrations/20260425000000-add-interaction-schema.d.ts +4 -0
  51. package/dist/server/migrations/20260427000000-add-tracing-detail-fields.d.ts +7 -0
  52. package/dist/server/migrations/20260427000000-change-packages-to-text.d.ts +4 -0
  53. package/dist/server/migrations/20260427000001-change-other-json-to-text.d.ts +4 -0
  54. package/dist/server/migrations/20260429000000-add-llm-fields.d.ts +7 -0
  55. package/dist/server/migrations/20260429000000-fix-inputargs-json-to-text.d.ts +16 -0
  56. package/dist/server/migrations/20260503000000-add-orchestrator-trace-fields.d.ts +7 -0
  57. package/dist/server/migrations/20260524000000-add-agent-loop-fields-to-skill-executions.d.ts +7 -0
  58. package/dist/server/migrations/20260524000000-add-agent-loop-fields-to-skill-executions.js +55 -0
  59. package/dist/server/migrations/20260524001000-add-plan-approval-and-harness-profiles.d.ts +12 -0
  60. package/dist/server/migrations/20260524001000-add-plan-approval-and-harness-profiles.js +162 -0
  61. package/dist/server/plugin.d.ts +16 -0
  62. package/dist/server/plugin.js +13 -0
  63. package/dist/server/resources/agent-loop.d.ts +3 -0
  64. package/dist/server/resources/agent-loop.js +205 -0
  65. package/dist/server/resources/tracing.d.ts +7 -0
  66. package/dist/server/services/AgentHarness.d.ts +42 -0
  67. package/dist/server/services/AgentHarness.js +565 -0
  68. package/dist/server/services/AgentLoopController.d.ts +205 -0
  69. package/dist/server/services/AgentLoopController.js +940 -0
  70. package/dist/server/services/AgentLoopRepository.d.ts +20 -0
  71. package/dist/server/services/AgentLoopRepository.js +210 -0
  72. package/dist/server/services/AgentLoopService.d.ts +149 -0
  73. package/dist/server/services/AgentLoopService.js +133 -0
  74. package/dist/server/services/AgentPlanValidator.d.ts +4 -0
  75. package/dist/server/services/AgentPlanValidator.js +99 -0
  76. package/dist/server/services/AgentPlannerService.d.ts +8 -0
  77. package/dist/server/services/AgentPlannerService.js +119 -0
  78. package/dist/server/services/AgentRegistryService.d.ts +13 -0
  79. package/dist/server/services/AgentRegistryService.js +178 -0
  80. package/dist/server/services/CodeValidator.d.ts +32 -0
  81. package/dist/server/services/ExecutionSpanService.d.ts +46 -0
  82. package/dist/server/services/FileManager.d.ts +28 -0
  83. package/dist/server/services/SandboxRunner.d.ts +41 -0
  84. package/dist/server/services/SkillManager.d.ts +6 -0
  85. package/dist/server/services/SkillRepositoryService.d.ts +22 -0
  86. package/dist/server/services/WorkerEnvManager.d.ts +26 -0
  87. package/dist/server/skill-hub/actions/git-import.d.ts +21 -0
  88. package/dist/server/skill-hub/mcp/McpController.d.ts +15 -0
  89. package/dist/server/skill-hub/plugin.d.ts +61 -0
  90. package/dist/server/skill-hub/plugin.js +152 -54
  91. package/dist/server/skill-hub/tasks/SkillExecutionTask.d.ts +16 -0
  92. package/dist/server/skill-hub/tasks/SkillExecutionTask.js +15 -0
  93. package/dist/server/skill-hub/utils/json-fields.d.ts +7 -0
  94. package/dist/server/tools/agent-loop.d.ts +235 -0
  95. package/dist/server/tools/agent-loop.js +406 -0
  96. package/dist/server/tools/delegate-task.d.ts +19 -0
  97. package/dist/server/tools/delegate-task.js +19 -368
  98. package/dist/server/tools/external-rag-search.d.ts +42 -0
  99. package/dist/server/tools/orchestrator-plan.d.ts +205 -0
  100. package/dist/server/tools/orchestrator-plan.js +291 -0
  101. package/dist/server/tools/skill-execute.d.ts +36 -0
  102. package/dist/server/tools/skill-execute.js +2 -0
  103. package/package.json +1 -1
  104. package/src/client/AgentRunsTab.tsx +764 -0
  105. package/src/client/HarnessProfilesTab.tsx +247 -0
  106. package/src/client/OrchestratorSettings.tsx +40 -2
  107. package/src/client/RulesTab.tsx +103 -6
  108. package/src/client/plugin.tsx +27 -54
  109. package/src/client/skill-hub/components/LoopSettings.tsx +331 -0
  110. package/src/client/skill-hub/index.tsx +51 -75
  111. package/src/client/skill-hub/tools/InteractionSchemasProvider.tsx +56 -16
  112. package/src/client/skill-hub/tools/SkillHubCard.tsx +35 -4
  113. package/src/client/skill-hub/tools/loopTemplates.ts +52 -0
  114. package/src/client/skill-hub/tools/registerSkillLoopCards.ts +58 -0
  115. package/src/client/tools/PlanApprovalCard.tsx +175 -0
  116. package/src/client/tools/registerOrchestratorCards.ts +7 -0
  117. package/src/server/collections/agent-harness-profiles.ts +59 -0
  118. package/src/server/collections/agent-loop-events.ts +71 -0
  119. package/src/server/collections/agent-loop-runs.ts +158 -0
  120. package/src/server/collections/agent-loop-steps.ts +144 -0
  121. package/src/server/collections/orchestrator-config.ts +7 -0
  122. package/src/server/collections/skill-executions.ts +63 -51
  123. package/src/server/collections/skill-loop-configs.ts +65 -0
  124. package/src/server/migrations/20260524000000-add-agent-loop-fields-to-skill-executions.ts +30 -0
  125. package/src/server/migrations/20260524001000-add-plan-approval-and-harness-profiles.ts +142 -0
  126. package/src/server/plugin.ts +15 -0
  127. package/src/server/resources/agent-loop.ts +183 -0
  128. package/src/server/services/AgentHarness.ts +663 -0
  129. package/src/server/services/AgentLoopController.ts +1128 -0
  130. package/src/server/services/AgentLoopRepository.ts +194 -0
  131. package/src/server/services/AgentLoopService.ts +161 -0
  132. package/src/server/services/AgentPlanValidator.ts +73 -0
  133. package/src/server/services/AgentPlannerService.ts +93 -0
  134. package/src/server/services/AgentRegistryService.ts +169 -0
  135. package/src/server/services/ExecutionSpanService.ts +2 -0
  136. package/src/server/skill-hub/plugin.ts +897 -771
  137. package/src/server/skill-hub/tasks/SkillExecutionTask.ts +15 -0
  138. package/src/server/tools/agent-loop.ts +399 -0
  139. package/src/server/tools/delegate-task.ts +23 -485
  140. package/src/server/tools/orchestrator-plan.ts +279 -0
  141. package/src/server/tools/skill-execute.ts +68 -64
@@ -53,6 +53,7 @@ var import_McpController = require("./mcp/McpController");
53
53
  var import_SkillRepositoryService = require("../services/SkillRepositoryService");
54
54
  var import_git_import = require("./actions/git-import");
55
55
  var import_json_fields = require("./utils/json-fields");
56
+ var import_ExecutionSpanService = require("../services/ExecutionSpanService");
56
57
  class RateLimiter {
57
58
  constructor(maxExecutions = 10, windowMs = 60 * 1e3) {
58
59
  this.maxExecutions = maxExecutions;
@@ -77,9 +78,7 @@ class RateLimiter {
77
78
  /** Get remaining executions for a user */
78
79
  remaining(userId) {
79
80
  const now = Date.now();
80
- const executions = (this.userExecutions.get(userId) || []).filter(
81
- (t) => now - t < this.windowMs
82
- );
81
+ const executions = (this.userExecutions.get(userId) || []).filter((t) => now - t < this.windowMs);
83
82
  return Math.max(0, this.maxExecutions - executions.length);
84
83
  }
85
84
  /** Periodically clean up expired entries (call from interval) */
@@ -152,7 +151,9 @@ class SkillHubSubFeature {
152
151
  require("fs").rmSync(dir, { recursive: true, force: true });
153
152
  }
154
153
  } catch (err) {
155
- this.app.logger.error(`[skill-hub] Failed to cleanup physical storage for execId ${execId}`, { error: err });
154
+ this.app.logger.error(`[skill-hub] Failed to cleanup physical storage for execId ${execId}`, {
155
+ error: err
156
+ });
156
157
  }
157
158
  });
158
159
  this.db.on("skillDefinitions.afterSave", async (model, options) => {
@@ -168,31 +169,56 @@ class SkillHubSubFeature {
168
169
  this.app.logger.warn("[skill-hub] plugin-file-manager not found, cannot extract skill package");
169
170
  return;
170
171
  }
172
+ const rawStorageId = attachment.get("storageId") || attachment.storageId;
173
+ if (rawStorageId) {
174
+ const strId = String(rawStorageId);
175
+ let matchedKey = null;
176
+ for (const key of fileManager.storagesCache.keys()) {
177
+ if (String(key) === strId) {
178
+ matchedKey = key;
179
+ break;
180
+ }
181
+ }
182
+ if (matchedKey !== null) {
183
+ attachment.set("storageId", matchedKey);
184
+ attachment.storageId = matchedKey;
185
+ }
186
+ }
171
187
  const streamData = await fileManager.getFileStream(attachment);
172
188
  if (!streamData || !streamData.stream) {
173
- this.app.logger.warn(`[skill-hub] Could not get file stream for attachment ${attachment.get("id")}`);
189
+ this.app.logger.warn(
190
+ `[skill-hub] Could not get file stream for attachment ${attachment.get("id")}`
191
+ );
174
192
  return;
175
193
  }
176
194
  const tempZipPath = (0, import_path.resolve)(os.tmpdir(), `skill_${Date.now()}_${model.get("id")}.zip`);
177
- await new Promise((resolvePipe, rejectPipe) => {
195
+ await new Promise((resolve2, reject) => {
178
196
  const writeStream = (0, import_fs.createWriteStream)(tempZipPath);
179
197
  streamData.stream.pipe(writeStream);
180
- writeStream.on("finish", resolvePipe);
181
- writeStream.on("error", rejectPipe);
182
- streamData.stream.on("error", rejectPipe);
198
+ writeStream.on("finish", resolve2);
199
+ writeStream.on("error", reject);
200
+ streamData.stream.on("error", reject);
183
201
  });
184
202
  if (require("fs").existsSync(tempZipPath)) {
185
203
  const skillName = model.get("name");
186
- const { metadata, instructions } = await this.skillRepoService.extractSkillPackage(skillName, tempZipPath);
204
+ const { metadata, instructions } = await this.skillRepoService.extractSkillPackage(
205
+ skillName,
206
+ tempZipPath
207
+ );
187
208
  const code = this.skillRepoService.getSkillCode(skillName);
188
- const updateValues = { storageType: attachment.get("storageId") ? `storage-${attachment.get("storageId")}` : "local" };
209
+ const updateValues = {
210
+ storageType: attachment.get("storageId") ? `storage-${attachment.get("storageId")}` : "local"
211
+ };
189
212
  if (code) updateValues.codeTemplate = code;
190
213
  if (metadata.description) updateValues.description = metadata.description;
191
214
  if (metadata.title) updateValues.title = metadata.title;
192
215
  if (metadata.language) updateValues.language = metadata.language;
193
- if (metadata.inputSchema) updateValues.inputSchema = (0, import_json_fields.stringifyJsonText)((0, import_json_fields.parseJsonLike)(metadata.inputSchema, null));
194
- if (metadata.interactionSchema) updateValues.interactionSchema = (0, import_json_fields.stringifyJsonText)((0, import_json_fields.parseJsonLike)(metadata.interactionSchema, null));
195
- if (metadata.packages) updateValues.packages = (0, import_json_fields.stringifyJsonText)((0, import_json_fields.parseJsonLike)(metadata.packages, []), []);
216
+ if (metadata.inputSchema)
217
+ updateValues.inputSchema = (0, import_json_fields.stringifyJsonText)((0, import_json_fields.parseJsonLike)(metadata.inputSchema, null));
218
+ if (metadata.interactionSchema)
219
+ updateValues.interactionSchema = (0, import_json_fields.stringifyJsonText)((0, import_json_fields.parseJsonLike)(metadata.interactionSchema, null));
220
+ if (metadata.packages)
221
+ updateValues.packages = (0, import_json_fields.stringifyJsonText)((0, import_json_fields.parseJsonLike)(metadata.packages, []), []);
196
222
  if (metadata.timeoutSeconds) updateValues.timeoutSeconds = metadata.timeoutSeconds;
197
223
  if (instructions) updateValues.instructions = instructions;
198
224
  await this.db.getRepository("skillDefinitions").update({
@@ -262,12 +288,19 @@ class SkillHubSubFeature {
262
288
  );
263
289
  }
264
290
  }
291
+ const traceContext = (0, import_ExecutionSpanService.getOrchestratorTraceContext)(ctx);
265
292
  const execution = await this.db.getRepository("skillExecutions").create({
266
293
  values: {
267
294
  skillId: skill.id,
268
295
  status: "pending",
269
296
  inputArgs: (0, import_json_fields.stringifyJsonText)(inputArgs, {}),
270
297
  sessionId: (_c = ctx == null ? void 0 : ctx.state) == null ? void 0 : _c.sessionId,
298
+ orchestratorRootRunId: traceContext == null ? void 0 : traceContext.rootRunId,
299
+ orchestratorSpanId: traceContext == null ? void 0 : traceContext.spanId,
300
+ orchestratorParentSpanId: traceContext == null ? void 0 : traceContext.parentSpanId,
301
+ orchestratorToolCallId: traceContext == null ? void 0 : traceContext.toolCallId,
302
+ agentLoopRunId: traceContext == null ? void 0 : traceContext.agentLoopRunId,
303
+ agentLoopStepId: traceContext == null ? void 0 : traceContext.agentLoopStepId,
271
304
  triggeredById: (_e = (_d = ctx == null ? void 0 : ctx.state) == null ? void 0 : _d.currentUser) == null ? void 0 : _e.id
272
305
  }
273
306
  });
@@ -340,7 +373,13 @@ class SkillHubSubFeature {
340
373
  downloadUrl: `/api/skillHub:download?execId=${execId}&f=${b64name}`
341
374
  };
342
375
  });
343
- return { ...result, files: filesWithUrls, execId };
376
+ return {
377
+ ...result,
378
+ files: filesWithUrls,
379
+ execId,
380
+ agentLoopRunId: traceContext == null ? void 0 : traceContext.agentLoopRunId,
381
+ agentLoopStepId: traceContext == null ? void 0 : traceContext.agentLoopStepId
382
+ };
344
383
  }
345
384
  async handleDownload(ctx, next) {
346
385
  var _a, _b;
@@ -455,6 +494,49 @@ class SkillHubSubFeature {
455
494
  await this.app.pubSubManager.subscribe("skill-hub.init-env.done", this.initEnvDoneCallback);
456
495
  await this.app.pubSubManager.subscribe("skill-hub.init-env.progress", this.initEnvProgressCallback);
457
496
  }
497
+ getSkillRecordId(skill) {
498
+ return String(skill.get ? skill.get("id") : skill.id);
499
+ }
500
+ resolveLoopInteractionSchema(loopConfig) {
501
+ if (!loopConfig) return null;
502
+ const schema = (0, import_json_fields.parseJsonText)(loopConfig.get ? loopConfig.get("schema") : loopConfig.schema, null);
503
+ const prompt = loopConfig.get ? loopConfig.get("prompt") : loopConfig.prompt;
504
+ if (schema && typeof schema === "object") {
505
+ return prompt && !schema.prompt ? { ...schema, prompt } : schema;
506
+ }
507
+ if (prompt) {
508
+ return {
509
+ type: "confirm",
510
+ prompt
511
+ };
512
+ }
513
+ return null;
514
+ }
515
+ async getLoopConfigsBySkillId(skillIds) {
516
+ const ids = Array.from(new Set(skillIds.map((id) => String(id)).filter(Boolean)));
517
+ const configsBySkillId = /* @__PURE__ */ new Map();
518
+ if (!ids.length) return configsBySkillId;
519
+ try {
520
+ const configs = await this.db.getRepository("skillLoopConfigs").find({
521
+ filter: {
522
+ enabled: true,
523
+ skillId: {
524
+ $in: ids
525
+ }
526
+ },
527
+ sort: ["-updatedAt"]
528
+ });
529
+ for (const config of configs || []) {
530
+ const skillId = String(config.get ? config.get("skillId") : config.skillId);
531
+ if (!configsBySkillId.has(skillId)) {
532
+ configsBySkillId.set(skillId, config);
533
+ }
534
+ }
535
+ } catch (err) {
536
+ this.app.logger.warn("[skill-hub] Failed to load loop configs", err);
537
+ }
538
+ return configsBySkillId;
539
+ }
458
540
  registerAITools() {
459
541
  var _a;
460
542
  try {
@@ -470,45 +552,56 @@ class SkillHubSubFeature {
470
552
  filter: { enabled: true }
471
553
  });
472
554
  if (!skills || skills.length === 0) return;
473
- const tools = await Promise.all(skills.map(async (skill) => {
474
- const sanitizedToolName = skill.get("name").toLowerCase().replace(/[^a-z0-9_]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
475
- const autoCall = !!skill.get("autoCall");
476
- const interactionSchema = (0, import_json_fields.parseJsonText)(skill.get("interactionSchema"), null);
477
- const fullDescription = await this.getSkillDescriptionForAI(skill);
478
- const baseDescription = `${fullDescription || skill.get("description")}
479
- Language: ${skill.get("language")}`;
480
- const description = !autoCall && interactionSchema ? `${baseDescription}
555
+ const loopConfigsBySkillId = await this.getLoopConfigsBySkillId(
556
+ skills.map((skill) => this.getSkillRecordId(skill))
557
+ );
558
+ const tools = await Promise.all(
559
+ skills.map(async (skill) => {
560
+ const sanitizedToolName = skill.get("name").toLowerCase().replace(/[^a-z0-9_]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
561
+ const autoCall = !!skill.get("autoCall");
562
+ const loopConfig = loopConfigsBySkillId.get(this.getSkillRecordId(skill));
563
+ const loopInteractionSchema = this.resolveLoopInteractionSchema(loopConfig);
564
+ const skillInteractionSchema = (0, import_json_fields.parseJsonText)(skill.get("interactionSchema"), null);
565
+ const interactionSchema = loopInteractionSchema || skillInteractionSchema;
566
+ const requiresHumanReview = !!interactionSchema;
567
+ const fullDescription = await this.getSkillDescriptionForAI(skill);
568
+ const baseDescription = `${fullDescription || skill.get("description")}
569
+ Language: ${skill.get(
570
+ "language"
571
+ )}`;
572
+ const description = requiresHumanReview ? `${baseDescription}
481
573
 
482
- IMPORTANT: This skill requires human confirmation. Pass best-effort args; the user will adjust them in UI before execution.` : baseDescription;
483
- return {
484
- scope: "CUSTOM",
485
- execution: "backend",
486
- defaultPermission: autoCall ? "ALLOW" : "ASK",
487
- introduction: {
488
- title: `Skill Hub: ${skill.get("title")}`,
489
- about: skill.get("description") || `Th\u1EF1c thi k\u1EF9 n\u0103ng ${skill.get("title")}`
490
- },
491
- definition: {
492
- name: `skill_hub_${sanitizedToolName}`,
493
- description,
494
- schema: (0, import_json_fields.parseJsonText)(skill.get("inputSchema"), { type: "object", properties: {} })
495
- },
496
- invoke: async (toolCtx, args) => {
497
- const latestSkill = await this.db.getRepository("skillDefinitions").findOne({
498
- filter: { id: skill.get("id"), enabled: true }
499
- });
500
- if (!latestSkill) {
501
- return { status: "error", content: `Skill "${skill.get("name")}" is no longer available` };
574
+ IMPORTANT: This skill is bound to a Skill Hub human-in-the-loop review template. Pass best-effort args; the user can approve, edit, or reject them before execution.` : baseDescription;
575
+ return {
576
+ scope: "CUSTOM",
577
+ execution: "backend",
578
+ defaultPermission: requiresHumanReview ? "ASK" : autoCall ? "ALLOW" : "ASK",
579
+ introduction: {
580
+ title: `Skill Hub: ${skill.get("title")}`,
581
+ about: skill.get("description") || `Th\u1EF1c thi k\u1EF9 n\u0103ng ${skill.get("title")}`
582
+ },
583
+ definition: {
584
+ name: `skill_hub_${sanitizedToolName}`,
585
+ description,
586
+ schema: (0, import_json_fields.parseJsonText)(skill.get("inputSchema"), { type: "object", properties: {} })
587
+ },
588
+ invoke: async (toolCtx, args) => {
589
+ const latestSkill = await this.db.getRepository("skillDefinitions").findOne({
590
+ filter: { id: skill.get("id"), enabled: true }
591
+ });
592
+ if (!latestSkill) {
593
+ return { status: "error", content: `Skill "${skill.get("name")}" is no longer available` };
594
+ }
595
+ const result = await this.executeSkill(latestSkill, args, toolCtx);
596
+ return {
597
+ status: result.status === "succeeded" ? "success" : "error",
598
+ result
599
+ // Attach raw result
600
+ };
502
601
  }
503
- const result = await this.executeSkill(latestSkill, args, toolCtx);
504
- return {
505
- status: result.status === "succeeded" ? "success" : "error",
506
- result
507
- // Attach raw result
508
- };
509
- }
510
- };
511
- }));
602
+ };
603
+ })
604
+ );
512
605
  register.registerTools(tools);
513
606
  } catch (err) {
514
607
  this.app.logger.warn("[skill-hub] Failed to provide dynamic tools", err);
@@ -616,7 +709,9 @@ IMPORTANT: This skill requires human confirmation. Pass best-effort args; the us
616
709
  */
617
710
  registerSkillTemplate(pluginName, skillDef) {
618
711
  this.skillTemplates.set(skillDef.name, this.hydrateSkillTemplate(pluginName, skillDef));
619
- this.app.logger.info(`[skill-hub] Registered skill template "${skillDef.name}" from plugin "${pluginName}"`);
712
+ this.app.logger.info(
713
+ `[skill-hub] Registered skill template "${skillDef.name}" from plugin "${pluginName}"`
714
+ );
620
715
  }
621
716
  resolveSkillTemplate(templateName) {
622
717
  if (!templateName) return null;
@@ -644,7 +739,10 @@ IMPORTANT: This skill requires human confirmation. Pass best-effort args; the us
644
739
  const description = skill.get ? skill.get("description") : skill.description;
645
740
  const instructions = await this.getSkillInstructions(skill);
646
741
  const maxInlineInstructionChars = 24e3;
647
- const inlineInstructions = instructions && instructions.length > maxInlineInstructionChars ? `${instructions.slice(0, maxInlineInstructionChars)}
742
+ const inlineInstructions = instructions && instructions.length > maxInlineInstructionChars ? `${instructions.slice(
743
+ 0,
744
+ maxInlineInstructionChars
745
+ )}
648
746
 
649
747
  [Instructions truncated in tool description. Call skill_hub_execute with action="describe" and this skillName to load the complete workflow.]` : instructions;
650
748
  return [description, inlineInstructions ? `Instructions:
@@ -0,0 +1,16 @@
1
+ import Application from '@nocobase/server';
2
+ import { SandboxRunner } from '../../services/SandboxRunner';
3
+ import { FileManager } from '../../services/FileManager';
4
+ import { SkillRepositoryService } from '../../services/SkillRepositoryService';
5
+ export declare class SkillExecutionTask {
6
+ private execution;
7
+ private sandboxRunner;
8
+ private fileManager;
9
+ private skillRepoService;
10
+ private app;
11
+ constructor(execution: any, sandboxRunner: SandboxRunner, fileManager: FileManager, skillRepoService: SkillRepositoryService, app: Application);
12
+ run(): Promise<void>;
13
+ private renderTemplate;
14
+ private installGeneratedSkillIfRequested;
15
+ private validateGeneratedSkillPackages;
16
+ }
@@ -163,6 +163,21 @@ class SkillExecutionTask {
163
163
  const fmPlugin = this.app.pm.get("@nocobase/plugin-file-manager");
164
164
  const attachment = await this.app.db.getRepository("attachments").findOne({ filter: { id: fileId } });
165
165
  if (fmPlugin && attachment) {
166
+ const rawStorageId = attachment.get("storageId") || attachment.storageId;
167
+ if (rawStorageId) {
168
+ const strId = String(rawStorageId);
169
+ let matchedKey = null;
170
+ for (const key of fmPlugin.storagesCache.keys()) {
171
+ if (String(key) === strId) {
172
+ matchedKey = key;
173
+ break;
174
+ }
175
+ }
176
+ if (matchedKey !== null) {
177
+ attachment.set("storageId", matchedKey);
178
+ attachment.storageId = matchedKey;
179
+ }
180
+ }
166
181
  try {
167
182
  const streamData = await fmPlugin.getFileStream(attachment);
168
183
  if (streamData == null ? void 0 : streamData.stream) {
@@ -0,0 +1,7 @@
1
+ export declare function parseJsonText<T = any>(value: any, fallback: T): T;
2
+ export declare function stringifyJsonText(value: any, fallback?: any): string;
3
+ export declare function parseJsonLike(value: any, fallback: any): any;
4
+ export declare function parseSkillMarkdown(markdown: string): {
5
+ metadata: Record<string, any>;
6
+ body: string;
7
+ };
@@ -0,0 +1,235 @@
1
+ import { z } from 'zod';
2
+ import { AgentLoopService } from '../services/AgentLoopService';
3
+ export declare function createAgentLoopTools(plugin: any, service: AgentLoopService): ({
4
+ scope: "CUSTOM";
5
+ execution: "backend";
6
+ defaultPermission: "ALLOW";
7
+ introduction: {
8
+ title: string;
9
+ about: string;
10
+ };
11
+ definition: {
12
+ name: string;
13
+ description: string;
14
+ schema: z.ZodObject<{
15
+ goal: z.ZodString;
16
+ leaderUsername: z.ZodOptional<z.ZodString>;
17
+ sessionId: z.ZodOptional<z.ZodString>;
18
+ messageId: z.ZodOptional<z.ZodString>;
19
+ policy: z.ZodOptional<z.ZodObject<{
20
+ maxIterations: z.ZodOptional<z.ZodNumber>;
21
+ maxStepAttempts: z.ZodOptional<z.ZodNumber>;
22
+ allowReplan: z.ZodOptional<z.ZodBoolean>;
23
+ requireVerification: z.ZodOptional<z.ZodBoolean>;
24
+ stopOnApprovalRequired: z.ZodOptional<z.ZodBoolean>;
25
+ }, "strip", z.ZodTypeAny, {
26
+ maxIterations?: number;
27
+ maxStepAttempts?: number;
28
+ allowReplan?: boolean;
29
+ requireVerification?: boolean;
30
+ stopOnApprovalRequired?: boolean;
31
+ }, {
32
+ maxIterations?: number;
33
+ maxStepAttempts?: number;
34
+ allowReplan?: boolean;
35
+ requireVerification?: boolean;
36
+ stopOnApprovalRequired?: boolean;
37
+ }>>;
38
+ metadata: z.ZodOptional<z.ZodAny>;
39
+ plan: z.ZodOptional<z.ZodArray<z.ZodObject<{
40
+ id: z.ZodOptional<z.ZodString>;
41
+ key: z.ZodOptional<z.ZodString>;
42
+ planKey: z.ZodOptional<z.ZodString>;
43
+ parentStepId: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
44
+ title: z.ZodOptional<z.ZodString>;
45
+ description: z.ZodOptional<z.ZodString>;
46
+ type: z.ZodOptional<z.ZodEnum<["reasoning", "skill", "tool", "sub_agent", "verification"]>>;
47
+ target: z.ZodOptional<z.ZodString>;
48
+ input: z.ZodOptional<z.ZodAny>;
49
+ dependsOn: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
50
+ maxAttempts: z.ZodOptional<z.ZodNumber>;
51
+ metadata: z.ZodOptional<z.ZodAny>;
52
+ }, "strip", z.ZodTypeAny, {
53
+ type?: "reasoning" | "skill" | "tool" | "sub_agent" | "verification";
54
+ key?: string;
55
+ title?: string;
56
+ description?: string;
57
+ metadata?: any;
58
+ input?: any;
59
+ planKey?: string;
60
+ target?: string;
61
+ dependsOn?: string[];
62
+ id?: string;
63
+ parentStepId?: string | number;
64
+ maxAttempts?: number;
65
+ }, {
66
+ type?: "reasoning" | "skill" | "tool" | "sub_agent" | "verification";
67
+ key?: string;
68
+ title?: string;
69
+ description?: string;
70
+ metadata?: any;
71
+ input?: any;
72
+ planKey?: string;
73
+ target?: string;
74
+ dependsOn?: string[];
75
+ id?: string;
76
+ parentStepId?: string | number;
77
+ maxAttempts?: number;
78
+ }>, "many">>;
79
+ }, "strip", z.ZodTypeAny, {
80
+ leaderUsername?: string;
81
+ metadata?: any;
82
+ sessionId?: string;
83
+ goal?: string;
84
+ messageId?: string;
85
+ policy?: {
86
+ maxIterations?: number;
87
+ maxStepAttempts?: number;
88
+ allowReplan?: boolean;
89
+ requireVerification?: boolean;
90
+ stopOnApprovalRequired?: boolean;
91
+ };
92
+ plan?: {
93
+ type?: "reasoning" | "skill" | "tool" | "sub_agent" | "verification";
94
+ key?: string;
95
+ title?: string;
96
+ description?: string;
97
+ metadata?: any;
98
+ input?: any;
99
+ planKey?: string;
100
+ target?: string;
101
+ dependsOn?: string[];
102
+ id?: string;
103
+ parentStepId?: string | number;
104
+ maxAttempts?: number;
105
+ }[];
106
+ }, {
107
+ leaderUsername?: string;
108
+ metadata?: any;
109
+ sessionId?: string;
110
+ goal?: string;
111
+ messageId?: string;
112
+ policy?: {
113
+ maxIterations?: number;
114
+ maxStepAttempts?: number;
115
+ allowReplan?: boolean;
116
+ requireVerification?: boolean;
117
+ stopOnApprovalRequired?: boolean;
118
+ };
119
+ plan?: {
120
+ type?: "reasoning" | "skill" | "tool" | "sub_agent" | "verification";
121
+ key?: string;
122
+ title?: string;
123
+ description?: string;
124
+ metadata?: any;
125
+ input?: any;
126
+ planKey?: string;
127
+ target?: string;
128
+ dependsOn?: string[];
129
+ id?: string;
130
+ parentStepId?: string | number;
131
+ maxAttempts?: number;
132
+ }[];
133
+ }>;
134
+ };
135
+ invoke: (ctx: any, args: any) => Promise<{
136
+ status: "success" | "error";
137
+ content: string;
138
+ }>;
139
+ } | {
140
+ scope: "CUSTOM";
141
+ execution: "backend";
142
+ defaultPermission: "ALLOW";
143
+ introduction: {
144
+ title: string;
145
+ about: string;
146
+ };
147
+ definition: {
148
+ name: string;
149
+ description: string;
150
+ schema: z.ZodObject<{
151
+ runId: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
152
+ }, "strip", z.ZodTypeAny, {
153
+ runId?: string | number;
154
+ }, {
155
+ runId?: string | number;
156
+ }>;
157
+ };
158
+ invoke: (ctx: any, args: any) => Promise<{
159
+ status: "success" | "error";
160
+ content: string;
161
+ }>;
162
+ } | {
163
+ scope: "CUSTOM";
164
+ execution: "backend";
165
+ defaultPermission: "ALLOW";
166
+ introduction: {
167
+ title: string;
168
+ about: string;
169
+ };
170
+ definition: {
171
+ name: string;
172
+ description: string;
173
+ schema: z.ZodObject<{
174
+ stepId: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
175
+ status: z.ZodEnum<["running", "succeeded", "failed", "skipped"]>;
176
+ output: z.ZodOptional<z.ZodAny>;
177
+ error: z.ZodOptional<z.ZodString>;
178
+ reason: z.ZodOptional<z.ZodString>;
179
+ skillExecutionId: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
180
+ agentExecutionSpanId: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
181
+ metadata: z.ZodOptional<z.ZodAny>;
182
+ }, "strip", z.ZodTypeAny, {
183
+ error?: string;
184
+ status?: "running" | "succeeded" | "failed" | "skipped";
185
+ metadata?: any;
186
+ output?: any;
187
+ skillExecutionId?: string | number;
188
+ reason?: string;
189
+ stepId?: string | number;
190
+ agentExecutionSpanId?: string | number;
191
+ }, {
192
+ error?: string;
193
+ status?: "running" | "succeeded" | "failed" | "skipped";
194
+ metadata?: any;
195
+ output?: any;
196
+ skillExecutionId?: string | number;
197
+ reason?: string;
198
+ stepId?: string | number;
199
+ agentExecutionSpanId?: string | number;
200
+ }>;
201
+ };
202
+ invoke: (ctx: any, args: any) => Promise<{
203
+ status: "success" | "error";
204
+ content: string;
205
+ }>;
206
+ } | {
207
+ scope: "CUSTOM";
208
+ execution: "backend";
209
+ defaultPermission: "ALLOW";
210
+ introduction: {
211
+ title: string;
212
+ about: string;
213
+ };
214
+ definition: {
215
+ name: string;
216
+ description: string;
217
+ schema: z.ZodObject<{
218
+ stepId: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
219
+ reason: z.ZodOptional<z.ZodString>;
220
+ approval: z.ZodOptional<z.ZodAny>;
221
+ }, "strip", z.ZodTypeAny, {
222
+ reason?: string;
223
+ stepId?: string | number;
224
+ approval?: any;
225
+ }, {
226
+ reason?: string;
227
+ stepId?: string | number;
228
+ approval?: any;
229
+ }>;
230
+ };
231
+ invoke: (ctx: any, args: any) => Promise<{
232
+ status: "success" | "error";
233
+ content: string;
234
+ }>;
235
+ })[];