plugin-agent-orchestrator 1.0.6 → 1.0.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 (257) hide show
  1. package/README.md +16 -291
  2. package/dist/client/AIEmployeesContext.d.ts +7 -0
  3. package/dist/client/OrchestratorSettings.d.ts +2 -1
  4. package/dist/client/index.js +1 -1
  5. package/dist/client/plugin.d.ts +1 -0
  6. package/dist/client/skill-hub/components/ExecutionHistory.d.ts +2 -0
  7. package/dist/client/skill-hub/components/ExecutionProgress.d.ts +20 -0
  8. package/dist/client/skill-hub/components/GitSkillImport.d.ts +7 -0
  9. package/dist/client/skill-hub/components/SkillEditor.d.ts +7 -0
  10. package/dist/client/skill-hub/components/SkillManager.d.ts +2 -0
  11. package/dist/client/skill-hub/components/SkillMetrics.d.ts +2 -0
  12. package/dist/client/skill-hub/components/SkillTestPanel.d.ts +7 -0
  13. package/dist/client/skill-hub/index.d.ts +10 -0
  14. package/dist/client/skill-hub/locale.d.ts +3 -0
  15. package/dist/client/skill-hub/tools/InteractionSchemasProvider.d.ts +19 -0
  16. package/dist/client/skill-hub/tools/SkillHubCard.d.ts +3 -0
  17. package/dist/client/skill-hub/utils/jsonFields.d.ts +3 -0
  18. package/dist/externalVersion.js +6 -6
  19. package/dist/node_modules/adm-zip/LICENSE +21 -0
  20. package/dist/node_modules/adm-zip/adm-zip.js +1 -0
  21. package/dist/node_modules/adm-zip/headers/entryHeader.js +377 -0
  22. package/dist/node_modules/adm-zip/headers/index.js +2 -0
  23. package/dist/node_modules/adm-zip/headers/mainHeader.js +130 -0
  24. package/dist/node_modules/adm-zip/methods/deflater.js +33 -0
  25. package/dist/node_modules/adm-zip/methods/index.js +3 -0
  26. package/dist/node_modules/adm-zip/methods/inflater.js +34 -0
  27. package/dist/node_modules/adm-zip/methods/zipcrypto.js +175 -0
  28. package/dist/node_modules/adm-zip/package.json +1 -0
  29. package/dist/node_modules/adm-zip/util/constants.js +142 -0
  30. package/dist/node_modules/adm-zip/util/decoder.js +5 -0
  31. package/dist/node_modules/adm-zip/util/errors.js +63 -0
  32. package/dist/node_modules/adm-zip/util/fattr.js +76 -0
  33. package/dist/node_modules/adm-zip/util/index.js +5 -0
  34. package/dist/node_modules/adm-zip/util/utils.js +339 -0
  35. package/dist/node_modules/adm-zip/zipEntry.js +405 -0
  36. package/dist/node_modules/adm-zip/zipFile.js +446 -0
  37. package/dist/node_modules/simple-git/dist/cjs/index.js +7399 -0
  38. package/dist/node_modules/simple-git/dist/esm/index.js +4745 -0
  39. package/dist/node_modules/simple-git/dist/esm/package.json +3 -0
  40. package/dist/node_modules/simple-git/dist/src/lib/api.d.ts +13 -0
  41. package/dist/node_modules/simple-git/dist/src/lib/args/log-format.d.ts +9 -0
  42. package/dist/node_modules/simple-git/dist/src/lib/errors/git-construct-error.d.ts +15 -0
  43. package/dist/node_modules/simple-git/dist/src/lib/errors/git-error.d.ts +30 -0
  44. package/dist/node_modules/simple-git/dist/src/lib/errors/git-plugin-error.d.ts +7 -0
  45. package/dist/node_modules/simple-git/dist/src/lib/errors/git-response-error.d.ts +32 -0
  46. package/dist/node_modules/simple-git/dist/src/lib/errors/task-configuration-error.d.ts +12 -0
  47. package/dist/node_modules/simple-git/dist/src/lib/git-factory.d.ts +15 -0
  48. package/dist/node_modules/simple-git/dist/src/lib/git-logger.d.ts +21 -0
  49. package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-branch-delete.d.ts +5 -0
  50. package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-branch.d.ts +2 -0
  51. package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-commit.d.ts +2 -0
  52. package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-diff-summary.d.ts +3 -0
  53. package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-fetch.d.ts +2 -0
  54. package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-list-log-summary.d.ts +6 -0
  55. package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-merge.d.ts +11 -0
  56. package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-move.d.ts +2 -0
  57. package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-pull.d.ts +6 -0
  58. package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-push.d.ts +4 -0
  59. package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-remote-messages.d.ts +5 -0
  60. package/dist/node_modules/simple-git/dist/src/lib/parsers/parse-remote-objects.d.ts +3 -0
  61. package/dist/node_modules/simple-git/dist/src/lib/plugins/abort-plugin.d.ts +3 -0
  62. package/dist/node_modules/simple-git/dist/src/lib/plugins/block-unsafe-operations-plugin.d.ts +3 -0
  63. package/dist/node_modules/simple-git/dist/src/lib/plugins/command-config-prefixing-plugin.d.ts +2 -0
  64. package/dist/node_modules/simple-git/dist/src/lib/plugins/completion-detection.plugin.d.ts +3 -0
  65. package/dist/node_modules/simple-git/dist/src/lib/plugins/custom-binary.plugin.d.ts +3 -0
  66. package/dist/node_modules/simple-git/dist/src/lib/plugins/error-detection.plugin.d.ts +7 -0
  67. package/dist/node_modules/simple-git/dist/src/lib/plugins/index.d.ts +11 -0
  68. package/dist/node_modules/simple-git/dist/src/lib/plugins/plugin-store.d.ts +11 -0
  69. package/dist/node_modules/simple-git/dist/src/lib/plugins/progress-monitor-plugin.d.ts +3 -0
  70. package/dist/node_modules/simple-git/dist/src/lib/plugins/simple-git-plugin.d.ts +48 -0
  71. package/dist/node_modules/simple-git/dist/src/lib/plugins/spawn-options-plugin.d.ts +3 -0
  72. package/dist/node_modules/simple-git/dist/src/lib/plugins/suffix-paths.plugin.d.ts +2 -0
  73. package/dist/node_modules/simple-git/dist/src/lib/plugins/timout-plugin.d.ts +3 -0
  74. package/dist/node_modules/simple-git/dist/src/lib/responses/BranchDeleteSummary.d.ts +12 -0
  75. package/dist/node_modules/simple-git/dist/src/lib/responses/BranchSummary.d.ts +14 -0
  76. package/dist/node_modules/simple-git/dist/src/lib/responses/CheckIgnore.d.ts +4 -0
  77. package/dist/node_modules/simple-git/dist/src/lib/responses/CleanSummary.d.ts +9 -0
  78. package/dist/node_modules/simple-git/dist/src/lib/responses/ConfigList.d.ts +13 -0
  79. package/dist/node_modules/simple-git/dist/src/lib/responses/DiffSummary.d.ts +10 -0
  80. package/dist/node_modules/simple-git/dist/src/lib/responses/FileStatusSummary.d.ts +9 -0
  81. package/dist/node_modules/simple-git/dist/src/lib/responses/GetRemoteSummary.d.ts +11 -0
  82. package/dist/node_modules/simple-git/dist/src/lib/responses/InitSummary.d.ts +9 -0
  83. package/dist/node_modules/simple-git/dist/src/lib/responses/MergeSummary.d.ts +16 -0
  84. package/dist/node_modules/simple-git/dist/src/lib/responses/PullSummary.d.ts +25 -0
  85. package/dist/node_modules/simple-git/dist/src/lib/responses/StatusSummary.d.ts +19 -0
  86. package/dist/node_modules/simple-git/dist/src/lib/responses/TagList.d.ts +7 -0
  87. package/dist/node_modules/simple-git/dist/src/lib/runners/git-executor-chain.d.ts +25 -0
  88. package/dist/node_modules/simple-git/dist/src/lib/runners/git-executor.d.ts +14 -0
  89. package/dist/node_modules/simple-git/dist/src/lib/runners/promise-wrapped.d.ts +2 -0
  90. package/dist/node_modules/simple-git/dist/src/lib/runners/scheduler.d.ts +11 -0
  91. package/dist/node_modules/simple-git/dist/src/lib/runners/tasks-pending-queue.d.ts +23 -0
  92. package/dist/node_modules/simple-git/dist/src/lib/simple-git-api.d.ts +20 -0
  93. package/dist/node_modules/simple-git/dist/src/lib/task-callback.d.ts +2 -0
  94. package/dist/node_modules/simple-git/dist/src/lib/tasks/apply-patch.d.ts +3 -0
  95. package/dist/node_modules/simple-git/dist/src/lib/tasks/branch.d.ts +7 -0
  96. package/dist/node_modules/simple-git/dist/src/lib/tasks/change-working-directory.d.ts +2 -0
  97. package/dist/node_modules/simple-git/dist/src/lib/tasks/check-ignore.d.ts +2 -0
  98. package/dist/node_modules/simple-git/dist/src/lib/tasks/check-is-repo.d.ts +9 -0
  99. package/dist/node_modules/simple-git/dist/src/lib/tasks/checkout.d.ts +2 -0
  100. package/dist/node_modules/simple-git/dist/src/lib/tasks/clean.d.ts +25 -0
  101. package/dist/node_modules/simple-git/dist/src/lib/tasks/clone.d.ts +9 -0
  102. package/dist/node_modules/simple-git/dist/src/lib/tasks/commit.d.ts +4 -0
  103. package/dist/node_modules/simple-git/dist/src/lib/tasks/config.d.ts +8 -0
  104. package/dist/node_modules/simple-git/dist/src/lib/tasks/count-objects.d.ts +12 -0
  105. package/dist/node_modules/simple-git/dist/src/lib/tasks/diff-name-status.d.ts +12 -0
  106. package/dist/node_modules/simple-git/dist/src/lib/tasks/diff.d.ts +5 -0
  107. package/dist/node_modules/simple-git/dist/src/lib/tasks/fetch.d.ts +4 -0
  108. package/dist/node_modules/simple-git/dist/src/lib/tasks/first-commit.d.ts +2 -0
  109. package/dist/node_modules/simple-git/dist/src/lib/tasks/grep.d.ts +12 -0
  110. package/dist/node_modules/simple-git/dist/src/lib/tasks/hash-object.d.ts +5 -0
  111. package/dist/node_modules/simple-git/dist/src/lib/tasks/init.d.ts +3 -0
  112. package/dist/node_modules/simple-git/dist/src/lib/tasks/log.d.ts +32 -0
  113. package/dist/node_modules/simple-git/dist/src/lib/tasks/merge.d.ts +4 -0
  114. package/dist/node_modules/simple-git/dist/src/lib/tasks/move.d.ts +3 -0
  115. package/dist/node_modules/simple-git/dist/src/lib/tasks/pull.d.ts +3 -0
  116. package/dist/node_modules/simple-git/dist/src/lib/tasks/push.d.ts +9 -0
  117. package/dist/node_modules/simple-git/dist/src/lib/tasks/remote.d.ts +8 -0
  118. package/dist/node_modules/simple-git/dist/src/lib/tasks/reset.d.ts +11 -0
  119. package/dist/node_modules/simple-git/dist/src/lib/tasks/show.d.ts +2 -0
  120. package/dist/node_modules/simple-git/dist/src/lib/tasks/stash-list.d.ts +4 -0
  121. package/dist/node_modules/simple-git/dist/src/lib/tasks/status.d.ts +3 -0
  122. package/dist/node_modules/simple-git/dist/src/lib/tasks/sub-module.d.ts +5 -0
  123. package/dist/node_modules/simple-git/dist/src/lib/tasks/tag.d.ts +18 -0
  124. package/dist/node_modules/simple-git/dist/src/lib/tasks/task.d.ts +14 -0
  125. package/dist/node_modules/simple-git/dist/src/lib/tasks/version.d.ts +9 -0
  126. package/dist/node_modules/simple-git/dist/src/lib/types/handlers.d.ts +21 -0
  127. package/dist/node_modules/simple-git/dist/src/lib/types/index.d.ts +136 -0
  128. package/dist/node_modules/simple-git/dist/src/lib/types/tasks.d.ts +19 -0
  129. package/dist/node_modules/simple-git/dist/src/lib/utils/argument-filters.d.ts +14 -0
  130. package/dist/node_modules/simple-git/dist/src/lib/utils/exit-codes.d.ts +10 -0
  131. package/dist/node_modules/simple-git/dist/src/lib/utils/git-output-streams.d.ts +7 -0
  132. package/dist/node_modules/simple-git/dist/src/lib/utils/index.d.ts +8 -0
  133. package/dist/node_modules/simple-git/dist/src/lib/utils/line-parser.d.ts +15 -0
  134. package/dist/node_modules/simple-git/dist/src/lib/utils/simple-git-options.d.ts +2 -0
  135. package/dist/node_modules/simple-git/dist/src/lib/utils/task-options.d.ts +13 -0
  136. package/dist/node_modules/simple-git/dist/src/lib/utils/task-parser.d.ts +5 -0
  137. package/dist/node_modules/simple-git/dist/src/lib/utils/util.d.ts +47 -0
  138. package/dist/node_modules/simple-git/dist/typings/errors.d.ts +5 -0
  139. package/dist/node_modules/simple-git/dist/typings/index.d.ts +14 -0
  140. package/dist/node_modules/simple-git/dist/typings/response.d.ts +556 -0
  141. package/dist/node_modules/simple-git/dist/typings/simple-git.d.ts +1033 -0
  142. package/dist/node_modules/simple-git/dist/typings/types.d.ts +22 -0
  143. package/dist/node_modules/simple-git/node_modules/debug/package.json +64 -0
  144. package/dist/node_modules/simple-git/node_modules/debug/src/browser.js +272 -0
  145. package/dist/node_modules/simple-git/node_modules/debug/src/common.js +292 -0
  146. package/dist/node_modules/simple-git/node_modules/debug/src/index.js +10 -0
  147. package/dist/node_modules/simple-git/node_modules/debug/src/node.js +263 -0
  148. package/dist/node_modules/simple-git/package.json +1 -0
  149. package/dist/node_modules/simple-git/promise.js +17 -0
  150. package/dist/server/collections/agent-execution-spans.d.ts +9 -0
  151. package/dist/server/collections/agent-execution-spans.js +152 -0
  152. package/dist/server/collections/orchestrator-config.js +16 -0
  153. package/dist/server/collections/orchestrator-logs.js +19 -2
  154. package/dist/server/collections/skill-definitions.d.ts +3 -0
  155. package/dist/server/collections/skill-definitions.js +158 -0
  156. package/dist/server/collections/skill-executions.d.ts +3 -0
  157. package/dist/server/collections/skill-executions.js +123 -0
  158. package/dist/server/collections/skill-worker-configs.d.ts +3 -0
  159. package/dist/server/collections/skill-worker-configs.js +115 -0
  160. package/dist/server/migrations/20260423000000-add-progress-fields.d.ts +4 -0
  161. package/dist/server/migrations/20260423000000-add-progress-fields.js +69 -0
  162. package/dist/server/migrations/20260425000000-add-interaction-schema.d.ts +4 -0
  163. package/dist/server/migrations/20260425000000-add-interaction-schema.js +61 -0
  164. package/dist/server/migrations/20260427000000-add-tracing-detail-fields.d.ts +7 -0
  165. package/dist/server/migrations/20260427000000-add-tracing-detail-fields.js +62 -0
  166. package/dist/server/migrations/20260427000000-change-packages-to-text.d.ts +4 -0
  167. package/dist/server/migrations/20260427000000-change-packages-to-text.js +70 -0
  168. package/dist/server/migrations/20260427000001-change-other-json-to-text.d.ts +4 -0
  169. package/dist/server/migrations/20260427000001-change-other-json-to-text.js +80 -0
  170. package/dist/server/migrations/20260429000000-add-llm-fields.d.ts +7 -0
  171. package/dist/server/migrations/20260429000000-add-llm-fields.js +68 -0
  172. package/dist/server/migrations/20260429000000-fix-inputargs-json-to-text.d.ts +16 -0
  173. package/dist/server/migrations/20260429000000-fix-inputargs-json-to-text.js +51 -0
  174. package/dist/server/migrations/20260503000000-add-orchestrator-trace-fields.d.ts +7 -0
  175. package/dist/server/migrations/20260503000000-add-orchestrator-trace-fields.js +57 -0
  176. package/dist/server/plugin.d.ts +3 -0
  177. package/dist/server/plugin.js +37 -1
  178. package/dist/server/resources/tracing.js +160 -12
  179. package/dist/server/services/CodeValidator.d.ts +32 -0
  180. package/dist/server/services/CodeValidator.js +205 -0
  181. package/dist/server/services/ExecutionSpanService.d.ts +44 -0
  182. package/dist/server/services/ExecutionSpanService.js +104 -0
  183. package/dist/server/services/FileManager.d.ts +28 -0
  184. package/dist/server/services/FileManager.js +151 -0
  185. package/dist/server/services/SandboxRunner.d.ts +41 -0
  186. package/dist/server/services/SandboxRunner.js +167 -0
  187. package/dist/server/services/SkillManager.d.ts +6 -0
  188. package/dist/server/services/SkillManager.js +640 -0
  189. package/dist/server/services/SkillRepositoryService.d.ts +22 -0
  190. package/dist/server/services/SkillRepositoryService.js +157 -0
  191. package/dist/server/services/WorkerEnvManager.d.ts +26 -0
  192. package/dist/server/services/WorkerEnvManager.js +120 -0
  193. package/dist/server/skill-hub/actions/git-import.d.ts +21 -0
  194. package/dist/server/skill-hub/actions/git-import.js +413 -0
  195. package/dist/server/skill-hub/mcp/McpController.d.ts +15 -0
  196. package/dist/server/skill-hub/mcp/McpController.js +111 -0
  197. package/dist/server/skill-hub/plugin.d.ts +58 -0
  198. package/dist/server/skill-hub/plugin.js +694 -0
  199. package/dist/server/skill-hub/sandbox-config.json +6 -0
  200. package/dist/server/skill-hub/tasks/SkillExecutionTask.d.ts +14 -0
  201. package/dist/server/skill-hub/tasks/SkillExecutionTask.js +267 -0
  202. package/dist/server/skill-hub/utils/json-fields.d.ts +7 -0
  203. package/dist/server/skill-hub/utils/json-fields.js +88 -0
  204. package/dist/server/tools/delegate-task.d.ts +4 -0
  205. package/dist/server/tools/delegate-task.js +832 -119
  206. package/dist/server/tools/skill-execute.d.ts +36 -0
  207. package/dist/server/tools/skill-execute.js +167 -0
  208. package/package.json +3 -1
  209. package/src/client/AIEmployeeSelect.tsx +1 -3
  210. package/src/client/AIEmployeesContext.tsx +28 -13
  211. package/src/client/OrchestratorSettings.tsx +43 -5
  212. package/src/client/RulesTab.tsx +368 -21
  213. package/src/client/TracingTab.tsx +316 -102
  214. package/src/client/plugin.tsx +39 -0
  215. package/src/client/skill-hub/components/ExecutionHistory.tsx +201 -0
  216. package/src/client/skill-hub/components/ExecutionProgress.tsx +55 -0
  217. package/src/client/skill-hub/components/GitSkillImport.tsx +555 -0
  218. package/src/client/skill-hub/components/SkillEditor.tsx +456 -0
  219. package/src/client/skill-hub/components/SkillManager.tsx +181 -0
  220. package/src/client/skill-hub/components/SkillMetrics.tsx +124 -0
  221. package/src/client/skill-hub/components/SkillTestPanel.tsx +144 -0
  222. package/src/client/skill-hub/index.tsx +75 -0
  223. package/src/client/skill-hub/locale.ts +16 -0
  224. package/src/client/skill-hub/tools/InteractionSchemasProvider.tsx +59 -0
  225. package/src/client/skill-hub/tools/SkillHubCard.tsx +78 -0
  226. package/src/client/skill-hub/utils/jsonFields.ts +37 -0
  227. package/src/server/collections/agent-execution-spans.ts +129 -0
  228. package/src/server/collections/orchestrator-config.ts +17 -0
  229. package/src/server/collections/orchestrator-logs.ts +19 -2
  230. package/src/server/collections/skill-definitions.ts +128 -0
  231. package/src/server/collections/skill-executions.ts +94 -0
  232. package/src/server/collections/skill-worker-configs.ts +86 -0
  233. package/src/server/migrations/20260423000000-add-progress-fields.ts +50 -0
  234. package/src/server/migrations/20260425000000-add-interaction-schema.ts +35 -0
  235. package/src/server/migrations/20260427000000-add-tracing-detail-fields.ts +41 -0
  236. package/src/server/migrations/20260427000000-change-packages-to-text.ts +47 -0
  237. package/src/server/migrations/20260427000001-change-other-json-to-text.ts +57 -0
  238. package/src/server/migrations/20260429000000-add-llm-fields.ts +46 -0
  239. package/src/server/migrations/20260429000000-fix-inputargs-json-to-text.ts +38 -0
  240. package/src/server/migrations/20260503000000-add-orchestrator-trace-fields.ts +32 -0
  241. package/src/server/plugin.ts +51 -3
  242. package/src/server/resources/tracing.ts +187 -16
  243. package/src/server/services/CodeValidator.ts +159 -0
  244. package/src/server/services/ExecutionSpanService.ts +106 -0
  245. package/src/server/services/FileManager.ts +144 -0
  246. package/src/server/services/SandboxRunner.ts +205 -0
  247. package/src/server/services/SkillManager.ts +623 -0
  248. package/src/server/services/SkillRepositoryService.ts +142 -0
  249. package/src/server/services/WorkerEnvManager.ts +113 -0
  250. package/src/server/skill-hub/actions/git-import.ts +486 -0
  251. package/src/server/skill-hub/mcp/McpController.ts +86 -0
  252. package/src/server/skill-hub/plugin.ts +771 -0
  253. package/src/server/skill-hub/sandbox-config.json +6 -0
  254. package/src/server/skill-hub/tasks/SkillExecutionTask.ts +297 -0
  255. package/src/server/skill-hub/utils/json-fields.ts +57 -0
  256. package/src/server/tools/delegate-task.ts +1085 -147
  257. package/src/server/tools/skill-execute.ts +157 -0
@@ -0,0 +1,6 @@
1
+ {
2
+ "verifyPackages": [
3
+ "xlsx",
4
+ "dayjs"
5
+ ]
6
+ }
@@ -0,0 +1,297 @@
1
+ import Application from '@nocobase/server';
2
+ import { resolve } from 'path';
3
+ import { SandboxRunner } from '../../services/SandboxRunner';
4
+ import { FileManager } from '../../services/FileManager';
5
+ import { SkillRepositoryService } from '../../services/SkillRepositoryService';
6
+ import { parseJsonText, stringifyJsonText } from '../utils/json-fields';
7
+
8
+ /**
9
+ * Lightweight abort controller compatible with the SandboxRunner signal interface.
10
+ * Worker-side: subscribes to PubSub abort channel and triggers signal.
11
+ */
12
+ class TaskAbortController {
13
+ private listeners: Array<() => void> = [];
14
+ private _aborted = false;
15
+
16
+ get aborted() {
17
+ return this._aborted;
18
+ }
19
+
20
+ get signal() {
21
+ return {
22
+ addEventListener: (_event: string, listener: () => void) => {
23
+ if (this._aborted) {
24
+ listener();
25
+ } else {
26
+ this.listeners.push(listener);
27
+ }
28
+ },
29
+ };
30
+ }
31
+
32
+ abort() {
33
+ if (this._aborted) return;
34
+ this._aborted = true;
35
+ for (const listener of this.listeners) {
36
+ try {
37
+ listener();
38
+ } catch {
39
+ // ignore
40
+ }
41
+ }
42
+ this.listeners = [];
43
+ }
44
+ }
45
+
46
+ export class SkillExecutionTask {
47
+ constructor(
48
+ private execution: any,
49
+ private sandboxRunner: SandboxRunner,
50
+ private fileManager: FileManager,
51
+ private skillRepoService: SkillRepositoryService,
52
+ private app: Application,
53
+ ) {}
54
+
55
+ async run() {
56
+ const skill = this.execution.get('skill') || this.execution.skill;
57
+ const execId = String(this.execution.get('id'));
58
+
59
+ await this.execution.update({ status: 'running' });
60
+
61
+ // Set up abort controller — listens for cancel from main server via PubSub
62
+ const abortController = new TaskAbortController();
63
+ const abortChannel = `skill-hub.abort.${execId}`;
64
+ const abortCallback = async () => {
65
+ this.app.logger.info(`[skill-hub] Task ${execId}: received abort signal`);
66
+ abortController.abort();
67
+ };
68
+
69
+ try {
70
+ // Subscribe to abort channel before starting execution
71
+ await this.app.pubSubManager.subscribe(abortChannel, abortCallback);
72
+
73
+ // Render code template with input args
74
+ const inputArgs = parseJsonText(this.execution.get('inputArgs'), {});
75
+ const storageType = skill.get ? skill.get('storageType') : skill.storageType;
76
+
77
+ let rawCodeTemplate = skill.get ? skill.get('codeTemplate') : skill.codeTemplate;
78
+ let language = skill.get ? skill.get('language') : skill.language;
79
+ let timeoutSeconds = skill.get ? skill.get('timeoutSeconds') : skill.timeoutSeconds;
80
+ let maxOutputSizeMb = skill.get ? skill.get('maxOutputSizeMb') : skill.maxOutputSizeMb;
81
+ const skillName = skill.get ? skill.get('name') : skill.name;
82
+ const workDir = this.fileManager.createExecDir(execId);
83
+ let skillDir: string | undefined;
84
+
85
+ if (storageType === 'plugin') {
86
+ const pluginSkillName = (skill.get ? skill.get('pluginSource') : skill.pluginSource) || skillName;
87
+ const orchestratorPlugin = this.app.pm.get('plugin-agent-orchestrator') as any;
88
+ const skillHub = orchestratorPlugin?.skillHub;
89
+ let pluginTemplate = typeof skillHub?.resolveSkillTemplate === 'function'
90
+ ? skillHub.resolveSkillTemplate(pluginSkillName)
91
+ : skillHub?.skillTemplates?.get(pluginSkillName);
92
+
93
+ // Fallback: discover dynamically if not cached (e.g. executed in worker before UI was loaded)
94
+ if (!pluginTemplate && skillHub) {
95
+ const allPlugins = this.app.pm.getPlugins();
96
+ for (const [, pInstance] of allPlugins) {
97
+ if (typeof (pInstance as any).getSkillTemplates === 'function') {
98
+ const pluginSkills = (pInstance as any).getSkillTemplates();
99
+ if (Array.isArray(pluginSkills)) {
100
+ for (const s of pluginSkills) {
101
+ if (s.name === pluginSkillName) {
102
+ pluginTemplate = typeof skillHub?.hydrateSkillTemplate === 'function'
103
+ ? skillHub.hydrateSkillTemplate(pInstance.name, s)
104
+ : { ...s, pluginSource: s.name, pluginName: pInstance.name };
105
+ skillHub.skillTemplates.set(s.name, pluginTemplate);
106
+ break;
107
+ }
108
+ }
109
+ }
110
+ }
111
+ if (pluginTemplate) break;
112
+ }
113
+ }
114
+
115
+ if (pluginTemplate) {
116
+ rawCodeTemplate = pluginTemplate.codeTemplate;
117
+ language = pluginTemplate.language;
118
+ if (pluginTemplate.timeoutSeconds) timeoutSeconds = pluginTemplate.timeoutSeconds;
119
+ if (pluginTemplate.maxOutputSizeMb) maxOutputSizeMb = pluginTemplate.maxOutputSizeMb;
120
+ const packageRoot = pluginTemplate.skillPackage?.rootDir;
121
+ if (packageRoot) {
122
+ const mountMode = pluginTemplate.skillPackage?.mountMode || 'reference';
123
+ if (mountMode === 'copy') {
124
+ skillDir = resolve(workDir, 'skill');
125
+ this.skillRepoService.copyDirectoryTo(packageRoot, skillDir);
126
+ } else {
127
+ skillDir = packageRoot;
128
+ }
129
+ }
130
+ } else {
131
+ throw new Error(`Plugin skill "${pluginSkillName}" not found. Is the parent plugin enabled?`);
132
+ }
133
+ }
134
+
135
+ if (!rawCodeTemplate) {
136
+ throw new Error(
137
+ `Skill "${skillName}" has no codeTemplate. Add a code file, inline codeTemplate, or bind it to an installed plugin skill.`,
138
+ );
139
+ }
140
+
141
+ if (storageType !== 'plugin') {
142
+ skillDir = workDir;
143
+ }
144
+
145
+ const code = this.renderTemplate(rawCodeTemplate, inputArgs, execId, skillDir);
146
+ await this.execution.update({ executedCode: code });
147
+
148
+ // Load package whitelist for import validation
149
+ let packageWhitelist: string[] = [];
150
+ try {
151
+ const workerConfig = await this.app.db.getRepository('skillWorkerConfigs').findOne();
152
+ if (workerConfig) {
153
+ const wl = parseJsonText(
154
+ workerConfig.get ? workerConfig.get('packageWhitelist') : workerConfig.packageWhitelist,
155
+ { python: [], node: [], apt: [] },
156
+ );
157
+ if (wl) {
158
+ packageWhitelist = (language === 'node' ? wl.node : wl.python) || [];
159
+ }
160
+ }
161
+ } catch {
162
+ // Skip whitelist validation if config not available
163
+ }
164
+
165
+ // Pre-hydrate execution workspace with package contents (multi-file support)
166
+ const fileId = skill.get ? skill.get('fileId') : skill.fileId;
167
+
168
+ // In multi-node setups, local cache might be missing on this specific worker node. Re-download from S3 if needed.
169
+ if (!require('fs').existsSync(this.skillRepoService.getSkillPath(skillName)) && fileId) {
170
+ const fmPlugin = this.app.pm.get('@nocobase/plugin-file-manager') as any;
171
+ const attachment = await this.app.db.getRepository('attachments').findOne({ filter: { id: fileId } });
172
+ if (fmPlugin && attachment) {
173
+ try {
174
+ const streamData = await fmPlugin.getFileStream(attachment);
175
+ if (streamData?.stream) {
176
+ const tempZipPath = require('path').resolve(require('os').tmpdir(), `skill_${Date.now()}_exec.zip`);
177
+ await new Promise((resolve, reject) => {
178
+ const writeStream = require('fs').createWriteStream(tempZipPath);
179
+ streamData.stream.pipe(writeStream);
180
+ writeStream.on('finish', resolve);
181
+ writeStream.on('error', reject);
182
+ streamData.stream.on('error', reject);
183
+ });
184
+ await this.skillRepoService.extractSkillPackage(skillName, tempZipPath);
185
+ require('fs').unlinkSync(tempZipPath);
186
+ this.app.logger.info(
187
+ `[skill-hub] Task ${execId}: Auto-restored skill package ${skillName} from S3/Storage`,
188
+ );
189
+ }
190
+ } catch (fetchErr) {
191
+ this.app.logger.warn(
192
+ `[skill-hub] Task ${execId}: Failed to fetch skill package ${skillName} from storage`,
193
+ { error: fetchErr },
194
+ );
195
+ }
196
+ }
197
+ }
198
+
199
+ if (storageType !== 'plugin') {
200
+ this.skillRepoService.copySkillPackageTo(skillName, workDir);
201
+ skillDir = workDir;
202
+ }
203
+
204
+ const result = await this.sandboxRunner.execute({
205
+ language,
206
+ code,
207
+ execId,
208
+ timeoutSeconds: timeoutSeconds || 60,
209
+ maxOutputSizeMb: maxOutputSizeMb || 50,
210
+ skillDir,
211
+ signal: abortController.signal,
212
+ packageWhitelist,
213
+ onProgress: (progress) => {
214
+ // Worker → PubSub → Main Server → runtime.writer → SSE → Client
215
+ this.app.pubSubManager.publish(`skill-hub.progress.${execId}`, progress);
216
+ },
217
+ });
218
+
219
+ // Determine final status
220
+ let status: string;
221
+ if (result.canceled) {
222
+ status = 'canceled';
223
+ } else if (result.timedOut) {
224
+ status = 'timeout';
225
+ } else {
226
+ status = result.success ? 'succeeded' : 'failed';
227
+ }
228
+
229
+ await this.execution.update({
230
+ status,
231
+ stdout: result.stdout,
232
+ stderr: result.stderr,
233
+ outputFiles: stringifyJsonText(result.files, []),
234
+ durationMs: result.durationMs,
235
+ });
236
+
237
+ // Notify main server: task completed
238
+ await this.app.pubSubManager.publish(`skill-hub.done.${execId}`, {
239
+ status,
240
+ stdout: result.stdout?.slice(0, 3000),
241
+ stderr: result.stderr?.slice(0, 1000),
242
+ files: result.files,
243
+ durationMs: result.durationMs,
244
+ });
245
+
246
+ // Log execution metrics
247
+ this.app.logger.info(
248
+ `[skill-hub] Execution ${execId} ${status}: ` +
249
+ `skill=${skill.get ? skill.get('name') : skill.name}, ` +
250
+ `language=${language}, ` +
251
+ `duration=${result.durationMs}ms, ` +
252
+ `files=${result.files.length}, ` +
253
+ `outputSize=${this.fileManager.getTotalOutputSize(execId)}bytes`,
254
+ );
255
+ } catch (error) {
256
+ const errorMessage = error instanceof Error ? error.message : String(error);
257
+
258
+ await this.execution.update({
259
+ status: 'failed',
260
+ stderr: errorMessage,
261
+ });
262
+
263
+ await this.app.pubSubManager.publish(`skill-hub.done.${execId}`, {
264
+ status: 'failed',
265
+ stderr: errorMessage,
266
+ files: [],
267
+ durationMs: 0,
268
+ });
269
+
270
+ this.app.logger.error(`[skill-hub] Execution ${execId} error: ${errorMessage}`);
271
+ } finally {
272
+ // Always cleanup abort subscription
273
+ try {
274
+ await this.app.pubSubManager.unsubscribe(abortChannel, abortCallback);
275
+ } catch {
276
+ // ignore cleanup errors
277
+ }
278
+ }
279
+ }
280
+
281
+ private renderTemplate(template: string, args: Record<string, any>, execId: string, skillDir?: string): string {
282
+ let code = template;
283
+ for (const [key, value] of Object.entries(args)) {
284
+ const serialized = typeof value === 'string' ? value : JSON.stringify(value);
285
+ // Raw injection — use for simple scalar values (canvas_format, transition, etc.)
286
+ code = code.replaceAll(`{{${key}}}`, serialized);
287
+ // Safe base64 injection — use for fields that may contain quotes/newlines (slides_svg, title, etc.)
288
+ // Template placeholder: {{key_b64}}
289
+ const b64 = Buffer.from(serialized, 'utf-8').toString('base64');
290
+ code = code.replaceAll(`{{${key}_b64}}`, b64);
291
+ }
292
+ // Inject outputDir so code templates can use {{outputDir}}
293
+ code = code.replaceAll('{{outputDir}}', this.fileManager.getOutputDir(execId).replace(/\\/g, '/'));
294
+ code = code.replaceAll('{{skillDir}}', (skillDir || '').replace(/\\/g, '/'));
295
+ return code;
296
+ }
297
+ }
@@ -0,0 +1,57 @@
1
+ export function parseJsonText<T = any>(value: any, fallback: T): T {
2
+ if (value === undefined || value === null || value === '') return fallback;
3
+ if (typeof value !== 'string') return value;
4
+
5
+ const trimmed = value.trim();
6
+ const fenced = trimmed.match(/^```(?:json)?\s*([\s\S]*?)\s*```$/i);
7
+ const json = fenced ? fenced[1].trim() : trimmed;
8
+
9
+ try {
10
+ return JSON.parse(json);
11
+ } catch {
12
+ return fallback;
13
+ }
14
+ }
15
+
16
+ export function stringifyJsonText(value: any, fallback: any = null): string {
17
+ const normalized = value === undefined || value === null || value === '' ? fallback : value;
18
+ if (typeof normalized === 'string') {
19
+ const parsed = parseJsonText(normalized, undefined);
20
+ if (parsed === undefined) return normalized;
21
+ return `\`\`\`json\n${JSON.stringify(parsed, null, 2)}\n\`\`\``;
22
+ }
23
+ return `\`\`\`json\n${JSON.stringify(normalized, null, 2)}\n\`\`\``;
24
+ }
25
+
26
+ export function parseJsonLike(value: any, fallback: any) {
27
+ if (value === undefined || value === null || value === '') return fallback;
28
+ if (typeof value !== 'string') return value;
29
+
30
+ const parsed = parseJsonText(value, undefined);
31
+ if (parsed !== undefined) return parsed;
32
+
33
+ return value.includes(',')
34
+ ? value
35
+ .split(',')
36
+ .map((item) => item.trim())
37
+ .filter(Boolean)
38
+ : fallback;
39
+ }
40
+
41
+ export function parseSkillMarkdown(markdown: string) {
42
+ const match = markdown.match(/^---\r?\n([\s\S]*?)\r?\n---/);
43
+ if (!match) return { metadata: {}, body: markdown.trim() };
44
+
45
+ const result: Record<string, any> = {};
46
+ match[1].split(/\r?\n/).forEach((line) => {
47
+ const idx = line.indexOf(':');
48
+ if (idx > 0) {
49
+ const key = line.substring(0, idx).trim();
50
+ const value = line.substring(idx + 1).trim();
51
+ if (key) result[key] = value;
52
+ }
53
+ });
54
+
55
+ const body = markdown.substring(match[0].length).trim();
56
+ return { metadata: result, body };
57
+ }