plugin-agent-orchestrator 1.0.13 → 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 (255) 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.d.ts +1 -1
  153. package/dist/server/collections/orchestrator-config.js +6 -0
  154. package/dist/server/collections/orchestrator-logs.d.ts +1 -1
  155. package/dist/server/collections/skill-definitions.d.ts +2 -0
  156. package/dist/server/collections/skill-definitions.js +158 -0
  157. package/dist/server/collections/skill-executions.d.ts +2 -0
  158. package/dist/server/collections/skill-executions.js +123 -0
  159. package/dist/server/collections/skill-worker-configs.d.ts +2 -0
  160. package/dist/server/collections/skill-worker-configs.js +115 -0
  161. package/dist/server/migrations/20260423000000-add-progress-fields.d.ts +4 -0
  162. package/dist/server/migrations/20260423000000-add-progress-fields.js +69 -0
  163. package/dist/server/migrations/20260425000000-add-interaction-schema.d.ts +4 -0
  164. package/dist/server/migrations/20260425000000-add-interaction-schema.js +61 -0
  165. package/dist/server/migrations/20260427000000-change-packages-to-text.d.ts +4 -0
  166. package/dist/server/migrations/20260427000000-change-packages-to-text.js +70 -0
  167. package/dist/server/migrations/20260427000001-change-other-json-to-text.d.ts +4 -0
  168. package/dist/server/migrations/20260427000001-change-other-json-to-text.js +80 -0
  169. package/dist/server/migrations/20260429000000-add-llm-fields.js +8 -0
  170. package/dist/server/migrations/20260429000000-fix-inputargs-json-to-text.d.ts +16 -0
  171. package/dist/server/migrations/20260429000000-fix-inputargs-json-to-text.js +51 -0
  172. package/dist/server/migrations/20260503000000-add-orchestrator-trace-fields.d.ts +7 -0
  173. package/dist/server/migrations/20260503000000-add-orchestrator-trace-fields.js +57 -0
  174. package/dist/server/plugin.d.ts +3 -0
  175. package/dist/server/plugin.js +37 -1
  176. package/dist/server/resources/tracing.js +154 -11
  177. package/dist/server/services/CodeValidator.d.ts +32 -0
  178. package/dist/server/services/CodeValidator.js +206 -0
  179. package/dist/server/services/ExecutionSpanService.d.ts +44 -0
  180. package/dist/server/services/ExecutionSpanService.js +104 -0
  181. package/dist/server/services/FileManager.d.ts +28 -0
  182. package/dist/server/services/FileManager.js +151 -0
  183. package/dist/server/services/SandboxRunner.d.ts +41 -0
  184. package/dist/server/services/SandboxRunner.js +167 -0
  185. package/dist/server/services/SkillManager.d.ts +6 -0
  186. package/dist/server/services/SkillManager.js +640 -0
  187. package/dist/server/services/SkillRepositoryService.d.ts +22 -0
  188. package/dist/server/services/SkillRepositoryService.js +157 -0
  189. package/dist/server/services/WorkerEnvManager.d.ts +26 -0
  190. package/dist/server/services/WorkerEnvManager.js +120 -0
  191. package/dist/server/skill-hub/actions/git-import.d.ts +21 -0
  192. package/dist/server/skill-hub/actions/git-import.js +413 -0
  193. package/dist/server/skill-hub/mcp/McpController.d.ts +15 -0
  194. package/dist/server/skill-hub/mcp/McpController.js +111 -0
  195. package/dist/server/skill-hub/plugin.d.ts +58 -0
  196. package/dist/server/skill-hub/plugin.js +694 -0
  197. package/dist/server/skill-hub/sandbox-config.json +6 -0
  198. package/dist/server/skill-hub/tasks/SkillExecutionTask.d.ts +16 -0
  199. package/dist/server/skill-hub/tasks/SkillExecutionTask.js +389 -0
  200. package/dist/server/skill-hub/utils/json-fields.d.ts +7 -0
  201. package/dist/server/skill-hub/utils/json-fields.js +88 -0
  202. package/dist/server/tools/delegate-task.d.ts +4 -0
  203. package/dist/server/tools/delegate-task.js +606 -104
  204. package/dist/server/tools/skill-execute.d.ts +36 -0
  205. package/dist/server/tools/skill-execute.js +167 -0
  206. package/package.json +3 -1
  207. package/src/client/AIEmployeeSelect.tsx +1 -3
  208. package/src/client/AIEmployeesContext.tsx +28 -13
  209. package/src/client/OrchestratorSettings.tsx +43 -5
  210. package/src/client/RulesTab.tsx +253 -32
  211. package/src/client/TracingTab.tsx +277 -213
  212. package/src/client/index.tsx +1 -1
  213. package/src/client/plugin.tsx +54 -15
  214. package/src/client/skill-hub/components/ExecutionHistory.tsx +201 -0
  215. package/src/client/skill-hub/components/ExecutionProgress.tsx +55 -0
  216. package/src/client/skill-hub/components/GitSkillImport.tsx +555 -0
  217. package/src/client/skill-hub/components/SkillEditor.tsx +456 -0
  218. package/src/client/skill-hub/components/SkillManager.tsx +181 -0
  219. package/src/client/skill-hub/components/SkillMetrics.tsx +124 -0
  220. package/src/client/skill-hub/components/SkillTestPanel.tsx +144 -0
  221. package/src/client/skill-hub/index.tsx +75 -0
  222. package/src/client/skill-hub/locale.ts +16 -0
  223. package/src/client/skill-hub/tools/InteractionSchemasProvider.tsx +59 -0
  224. package/src/client/skill-hub/tools/SkillHubCard.tsx +78 -0
  225. package/src/client/skill-hub/utils/jsonFields.ts +37 -0
  226. package/src/server/collections/agent-execution-spans.ts +129 -0
  227. package/src/server/collections/orchestrator-config.ts +7 -0
  228. package/src/server/collections/skill-definitions.ts +128 -0
  229. package/src/server/collections/skill-executions.ts +94 -0
  230. package/src/server/collections/skill-worker-configs.ts +86 -0
  231. package/src/server/migrations/20260423000000-add-progress-fields.ts +50 -0
  232. package/src/server/migrations/20260425000000-add-interaction-schema.ts +35 -0
  233. package/src/server/migrations/20260427000000-add-tracing-detail-fields.ts +5 -5
  234. package/src/server/migrations/20260427000000-change-packages-to-text.ts +47 -0
  235. package/src/server/migrations/20260427000001-change-other-json-to-text.ts +57 -0
  236. package/src/server/migrations/20260429000000-add-llm-fields.ts +11 -2
  237. package/src/server/migrations/20260429000000-fix-inputargs-json-to-text.ts +38 -0
  238. package/src/server/migrations/20260503000000-add-orchestrator-trace-fields.ts +32 -0
  239. package/src/server/plugin.ts +94 -46
  240. package/src/server/resources/tracing.ts +182 -15
  241. package/src/server/services/CodeValidator.ts +159 -0
  242. package/src/server/services/ExecutionSpanService.ts +106 -0
  243. package/src/server/services/FileManager.ts +144 -0
  244. package/src/server/services/SandboxRunner.ts +205 -0
  245. package/src/server/services/SkillManager.ts +623 -0
  246. package/src/server/services/SkillRepositoryService.ts +142 -0
  247. package/src/server/services/WorkerEnvManager.ts +113 -0
  248. package/src/server/skill-hub/actions/git-import.ts +486 -0
  249. package/src/server/skill-hub/mcp/McpController.ts +86 -0
  250. package/src/server/skill-hub/plugin.ts +771 -0
  251. package/src/server/skill-hub/sandbox-config.json +6 -0
  252. package/src/server/skill-hub/tasks/SkillExecutionTask.ts +443 -0
  253. package/src/server/skill-hub/utils/json-fields.ts +57 -0
  254. package/src/server/tools/delegate-task.ts +803 -127
  255. package/src/server/tools/skill-execute.ts +157 -0
@@ -26,30 +26,72 @@ var __copyProps = (to, from, except, desc) => {
26
26
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
27
  var delegate_task_exports = {};
28
28
  __export(delegate_task_exports, {
29
- createDelegateToolsProvider: () => createDelegateToolsProvider
29
+ createDelegateToolsProvider: () => createDelegateToolsProvider,
30
+ invalidateDelegateToolsCache: () => invalidateDelegateToolsCache
30
31
  });
31
32
  module.exports = __toCommonJS(delegate_task_exports);
32
33
  var import_zod = require("zod");
34
+ var import_crypto = require("crypto");
33
35
  var import_prebuilt = require("@langchain/langgraph/prebuilt");
34
36
  var import_tools = require("@langchain/core/tools");
35
37
  var import_messages = require("@langchain/core/messages");
38
+ var import_ExecutionSpanService = require("../services/ExecutionSpanService");
36
39
  const ORCHESTRATOR_DEPTH_KEY = "__orchestratorDepth";
40
+ const MAX_DISPATCH_CONCURRENCY = 5;
41
+ const MAX_DISPATCH_TASKS = 20;
42
+ const MAX_TOOL_NAME_LENGTH = 64;
37
43
  function sanitizeToolPart(value) {
38
44
  return (value || "").replace(/[^a-zA-Z0-9_-]/g, "_");
39
45
  }
40
46
  function buildDelegateToolName(leaderUsername, subAgentUsername) {
41
47
  return `delegate_${sanitizeToolPart(leaderUsername)}_to_${sanitizeToolPart(subAgentUsername)}`;
42
48
  }
43
- function isDelegateToolName(toolName) {
44
- return toolName.startsWith("delegate_to_") || toolName.startsWith("delegate_") && toolName.includes("_to_");
49
+ function buildDispatchToolName(leaderUsername) {
50
+ return `dispatch_subagents_${sanitizeToolPart(leaderUsername)}`;
51
+ }
52
+ function createRootRunId(seed = "") {
53
+ const hash = (0, import_crypto.createHash)("sha1").update(`${Date.now()}::${Math.random()}::${seed}`).digest("hex").slice(0, 10);
54
+ return `run_${Date.now()}_${hash}`;
55
+ }
56
+ let registeredDelegateNamesByPlugin = /* @__PURE__ */ new WeakMap();
57
+ function isDelegateToolName(plugin, toolName) {
58
+ var _a;
59
+ return ((_a = registeredDelegateNamesByPlugin.get(plugin)) == null ? void 0 : _a.has(toolName)) ?? false;
60
+ }
61
+ async function runWithConcurrency(items, limit, fn) {
62
+ const results = new Array(items.length);
63
+ let cursor = 0;
64
+ const workerCount = Math.max(1, Math.min(limit, items.length));
65
+ const workers = Array.from({ length: workerCount }, async () => {
66
+ while (cursor < items.length) {
67
+ const i = cursor;
68
+ cursor += 1;
69
+ results[i] = await fn(items[i], i);
70
+ }
71
+ });
72
+ await Promise.all(workers);
73
+ return results;
45
74
  }
46
75
  function createDelegateToolOptions(plugin, options) {
47
- const { leaderUsername, subAgentUsername, subAgentEmployee, maxDepth, timeout, toolName, legacyAlias, llmService, model } = options;
76
+ const {
77
+ leaderUsername,
78
+ subAgentUsername,
79
+ subAgentEmployee,
80
+ maxDepth,
81
+ timeout,
82
+ toolName,
83
+ legacyAlias,
84
+ llmService,
85
+ model,
86
+ recursionLimit
87
+ } = options;
88
+ const dispatchToolName = buildDispatchToolName(leaderUsername);
48
89
  const toolDescription = [
49
90
  `Delegate a task from "${leaderUsername}" to the AI Employee "${subAgentEmployee.nickname || subAgentUsername}".`,
50
91
  legacyAlias ? "This is a backward-compatible alias for existing skill assignments." : "",
51
92
  subAgentEmployee.about ? `Specialist profile: ${subAgentEmployee.about.substring(0, 200)}` : "",
52
- "The sub-agent will execute the task independently and return its final answer."
93
+ "The sub-agent will execute the task independently and return its final answer.",
94
+ `For multiple INDEPENDENT sub-tasks, prefer "${dispatchToolName}" to fan-out in one call (up to ${MAX_DISPATCH_CONCURRENCY} run in parallel), or emit several delegate_* calls in the SAME assistant turn so they run concurrently.`
53
95
  ].filter(Boolean).join(" ");
54
96
  return {
55
97
  scope: "CUSTOM",
@@ -69,7 +111,25 @@ function createDelegateToolOptions(plugin, options) {
69
111
  })
70
112
  },
71
113
  invoke: async (ctx, args, id) => {
72
- const callingEmployee = resolveCallingEmployee(ctx);
114
+ const callingEmployee = await resolveCallingEmployee(ctx, plugin);
115
+ if (!callingEmployee) {
116
+ await logDelegation(ctx, plugin, {
117
+ leaderUsername,
118
+ subAgentUsername,
119
+ toolName,
120
+ task: args.task,
121
+ context: args.context,
122
+ result: "",
123
+ status: "error",
124
+ depth: ctx[ORCHESTRATOR_DEPTH_KEY] ?? 0,
125
+ durationMs: 0,
126
+ error: `Cannot determine calling AI employee for delegation tool "${toolName}".`
127
+ });
128
+ return {
129
+ status: "error",
130
+ content: `Cannot determine calling AI employee for "${toolName}". Start the request from an AI Employee conversation so leader scoping can be enforced.`
131
+ };
132
+ }
73
133
  if (callingEmployee && callingEmployee !== leaderUsername) {
74
134
  await logDelegation(ctx, plugin, {
75
135
  leaderUsername,
@@ -99,16 +159,205 @@ function createDelegateToolOptions(plugin, options) {
99
159
  toolCallId: id,
100
160
  toolName,
101
161
  llmService,
102
- model
162
+ model,
163
+ recursionLimit
103
164
  });
104
165
  }
105
166
  };
106
167
  }
107
- function resolveCallingEmployee(ctx) {
108
- var _a, _b, _c;
109
- const raw = ctx._currentAIEmployee || ((_a = ctx.state) == null ? void 0 : _a.currentAIEmployee) || ((_c = (_b = ctx.runtime) == null ? void 0 : _b.context) == null ? void 0 : _c.currentAIEmployee);
168
+ function formatDispatchResults(results, rulesBySubAgent) {
169
+ var _a;
170
+ const total = results.length;
171
+ const ok = results.filter((r) => r.status === "success").length;
172
+ const lines = [
173
+ `Dispatched ${total} sub-task(s) \u2014 ${ok} succeeded, ${total - ok} failed (max ${MAX_DISPATCH_CONCURRENCY} ran in parallel).`,
174
+ ""
175
+ ];
176
+ for (const r of results) {
177
+ const employee = (_a = rulesBySubAgent.get(r.subAgent)) == null ? void 0 : _a.employee;
178
+ const displayName = (employee == null ? void 0 : employee.nickname) || r.subAgent;
179
+ const dur = `${(r.durationMs / 1e3).toFixed(1)}s`;
180
+ lines.push(`--- [${r.index + 1}] ${displayName} (${r.subAgent}) [${r.status}] (${dur}) ---`);
181
+ lines.push(r.content || "(empty)");
182
+ lines.push("");
183
+ }
184
+ return lines.join("\n").trimEnd();
185
+ }
186
+ function createDispatchToolOptions(plugin, options) {
187
+ const { leaderUsername, rulesBySubAgent } = options;
188
+ const toolName = buildDispatchToolName(leaderUsername);
189
+ const subAgentNames = Array.from(rulesBySubAgent.keys());
190
+ const subAgentList = subAgentNames.map((username) => {
191
+ var _a, _b;
192
+ const entry = rulesBySubAgent.get(username);
193
+ if (!entry) return `- ${username}`;
194
+ const profile = ((_a = entry.employee) == null ? void 0 : _a.about) ? ` \u2014 ${String(entry.employee.about).substring(0, 120)}` : "";
195
+ const display = ((_b = entry.employee) == null ? void 0 : _b.nickname) ? ` (${entry.employee.nickname})` : "";
196
+ return `- ${username}${display}${profile}`;
197
+ }).join("\n");
198
+ const description = [
199
+ `Dispatch multiple tasks from "${leaderUsername}" to its configured sub-agents in one call.`,
200
+ `At most ${MAX_DISPATCH_CONCURRENCY} sub-tasks run in parallel; up to ${MAX_DISPATCH_TASKS} tasks per call.`,
201
+ "Use this when you have already planned independent sub-tasks and want to fan-out, then aggregate the results.",
202
+ `Available sub-agents:
203
+ ${subAgentList}`
204
+ ].join(" ");
205
+ return {
206
+ scope: "CUSTOM",
207
+ execution: "backend",
208
+ defaultPermission: "ALLOW",
209
+ silence: false,
210
+ introduction: {
211
+ title: `[${leaderUsername}] Dispatch sub-agents`,
212
+ about: description
213
+ },
214
+ definition: {
215
+ name: toolName,
216
+ description,
217
+ schema: import_zod.z.object({
218
+ tasks: import_zod.z.array(
219
+ import_zod.z.object({
220
+ subAgent: import_zod.z.enum(subAgentNames).describe("Username of the sub-agent that should execute this task."),
221
+ task: import_zod.z.string().describe("Detailed task description for the sub-agent."),
222
+ context: import_zod.z.string().optional().describe("Optional additional context for the sub-agent.")
223
+ })
224
+ ).min(1).max(MAX_DISPATCH_TASKS).describe(`List of sub-tasks to dispatch concurrently. Up to ${MAX_DISPATCH_CONCURRENCY} run in parallel.`)
225
+ })
226
+ },
227
+ invoke: async (ctx, args, id) => {
228
+ var _a;
229
+ const callingEmployee = await resolveCallingEmployee(ctx, plugin);
230
+ if (!callingEmployee) {
231
+ const distinctSubs = Array.from(new Set((args.tasks ?? []).map((t) => t.subAgent).filter(Boolean)));
232
+ const reportedSub = distinctSubs.length === 1 ? distinctSubs[0] : "(multiple)";
233
+ await logDelegation(ctx, plugin, {
234
+ leaderUsername,
235
+ subAgentUsername: reportedSub,
236
+ toolName,
237
+ task: truncateText(args.tasks ?? [], 2e3),
238
+ result: "",
239
+ status: "error",
240
+ depth: ctx[ORCHESTRATOR_DEPTH_KEY] ?? 0,
241
+ durationMs: 0,
242
+ error: `Cannot determine calling AI employee for dispatch tool "${toolName}". Targets: ${distinctSubs.join(", ") || "(empty)"}.`
243
+ });
244
+ return {
245
+ status: "error",
246
+ content: `Cannot determine calling AI employee for "${toolName}". Start the request from an AI Employee conversation so leader scoping can be enforced.`
247
+ };
248
+ }
249
+ if (callingEmployee && callingEmployee !== leaderUsername) {
250
+ const distinctSubs = Array.from(new Set((args.tasks ?? []).map((t) => t.subAgent).filter(Boolean)));
251
+ const reportedSub = distinctSubs.length === 1 ? distinctSubs[0] : "(multiple)";
252
+ await logDelegation(ctx, plugin, {
253
+ leaderUsername,
254
+ subAgentUsername: reportedSub,
255
+ toolName,
256
+ task: truncateText(args.tasks ?? [], 2e3),
257
+ result: "",
258
+ status: "error",
259
+ depth: ctx[ORCHESTRATOR_DEPTH_KEY] ?? 0,
260
+ durationMs: 0,
261
+ error: `Employee "${callingEmployee}" is not authorized to dispatch sub-agents for leader "${leaderUsername}". Targets: ${distinctSubs.join(", ") || "(empty)"}.`
262
+ });
263
+ return {
264
+ status: "error",
265
+ content: `Employee "${callingEmployee}" is not authorized to dispatch sub-agents for leader "${leaderUsername}".`
266
+ };
267
+ }
268
+ const tasks = args.tasks ?? [];
269
+ if (!tasks.length) {
270
+ return {
271
+ status: "error",
272
+ content: "No tasks provided. Pass at least one item in `tasks`."
273
+ };
274
+ }
275
+ const dispatchRootRunId = ((_a = (0, import_ExecutionSpanService.getOrchestratorTraceContext)(ctx)) == null ? void 0 : _a.rootRunId) || createRootRunId(`${leaderUsername}:dispatch`);
276
+ const results = await runWithConcurrency(tasks, MAX_DISPATCH_CONCURRENCY, async (item, i) => {
277
+ const startedAt = Date.now();
278
+ const entry = rulesBySubAgent.get(item.subAgent);
279
+ if (!entry) {
280
+ return {
281
+ index: i,
282
+ subAgent: item.subAgent,
283
+ status: "error",
284
+ content: `Unknown sub-agent "${item.subAgent}". Allowed: ${subAgentNames.join(", ")}.`,
285
+ durationMs: 0
286
+ };
287
+ }
288
+ try {
289
+ const res = await invokeDelegateTask(ctx, plugin, {
290
+ leaderUsername,
291
+ subAgentUsername: item.subAgent,
292
+ subAgentEmployee: entry.employee,
293
+ task: item.task,
294
+ context: item.context,
295
+ maxDepth: entry.rule.maxDepth ?? 1,
296
+ timeout: entry.rule.timeout ?? 12e4,
297
+ toolCallId: `${id}-${i}`,
298
+ toolName,
299
+ llmService: entry.rule.llmService,
300
+ model: entry.rule.model,
301
+ recursionLimit: entry.rule.recursionLimit,
302
+ rootRunId: dispatchRootRunId
303
+ });
304
+ return {
305
+ index: i,
306
+ subAgent: item.subAgent,
307
+ status: res.status,
308
+ content: res.content,
309
+ durationMs: Date.now() - startedAt
310
+ };
311
+ } catch (e) {
312
+ return {
313
+ index: i,
314
+ subAgent: item.subAgent,
315
+ status: "error",
316
+ content: (e == null ? void 0 : e.message) || String(e),
317
+ durationMs: Date.now() - startedAt
318
+ };
319
+ }
320
+ });
321
+ const successCount = results.filter((r) => r.status === "success").length;
322
+ return {
323
+ status: successCount > 0 ? "success" : "error",
324
+ content: formatDispatchResults(results, rulesBySubAgent)
325
+ };
326
+ }
327
+ };
328
+ }
329
+ function captureCtxSnapshot(ctx) {
330
+ var _a, _b, _c, _d;
331
+ let userId;
332
+ try {
333
+ userId = ((_b = (_a = ctx.auth) == null ? void 0 : _a.user) == null ? void 0 : _b.id) || ((_d = (_c = ctx.state) == null ? void 0 : _c.currentUser) == null ? void 0 : _d.id);
334
+ } catch {
335
+ }
336
+ return { userId };
337
+ }
338
+ function normalizeEmployeeUsername(raw) {
110
339
  if (!raw) return null;
111
- return typeof raw === "string" ? raw : raw.username;
340
+ if (typeof raw === "string") return raw;
341
+ return raw.username || raw.aiEmployeeUsername || raw.name || null;
342
+ }
343
+ async function resolveCallingEmployee(ctx, plugin) {
344
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
345
+ const values = ((_b = (_a = ctx.action) == null ? void 0 : _a.params) == null ? void 0 : _b.values) || {};
346
+ const raw = ctx._currentAIEmployee || ((_c = ctx.state) == null ? void 0 : _c.currentAIEmployee) || ((_e = (_d = ctx.runtime) == null ? void 0 : _d.context) == null ? void 0 : _e.currentAIEmployee) || values.aiEmployee;
347
+ const direct = normalizeEmployeeUsername(raw);
348
+ if (direct) return direct;
349
+ const sessionId = values.sessionId || ((_g = (_f = ctx.action) == null ? void 0 : _f.params) == null ? void 0 : _g.sessionId);
350
+ if (!sessionId) return null;
351
+ try {
352
+ const repo = ((_i = (_h = ctx.db) == null ? void 0 : _h.getRepository) == null ? void 0 : _i.call(_h, "aiConversations")) || plugin.db.getRepository("aiConversations");
353
+ const conversation = await repo.findOne({
354
+ filter: { sessionId }
355
+ });
356
+ return normalizeEmployeeUsername((conversation == null ? void 0 : conversation.aiEmployeeUsername) || ((_j = conversation == null ? void 0 : conversation.get) == null ? void 0 : _j.call(conversation, "aiEmployeeUsername")));
357
+ } catch (e) {
358
+ plugin.app.log.warn(`[AgentOrchestrator] Failed to resolve AI employee for session "${sessionId}"`, e);
359
+ return null;
360
+ }
112
361
  }
113
362
  function truncateText(value, maxLen) {
114
363
  const text = typeof value === "string" ? value : value == null ? "" : JSON.stringify(value);
@@ -118,77 +367,211 @@ function truncateText(value, maxLen) {
118
367
  function nowIso() {
119
368
  return (/* @__PURE__ */ new Date()).toISOString();
120
369
  }
370
+ function hasModelSettings(value) {
371
+ return Boolean((value == null ? void 0 : value.llmService) && (value == null ? void 0 : value.model));
372
+ }
373
+ const TOOLS_CACHE_TTL_MS = 3e4;
374
+ let toolsCacheByPlugin = /* @__PURE__ */ new WeakMap();
375
+ let hooksAttached = null;
376
+ function attachInvalidationHooks(plugin) {
377
+ if (!hooksAttached) hooksAttached = /* @__PURE__ */ new WeakSet();
378
+ if (hooksAttached.has(plugin)) return;
379
+ hooksAttached.add(plugin);
380
+ const invalidate = () => {
381
+ toolsCacheByPlugin.delete(plugin);
382
+ registeredDelegateNamesByPlugin.delete(plugin);
383
+ };
384
+ plugin.db.on("orchestratorConfig.afterCreate", invalidate);
385
+ plugin.db.on("orchestratorConfig.afterUpdate", invalidate);
386
+ plugin.db.on("orchestratorConfig.afterDestroy", invalidate);
387
+ plugin.db.on("aiEmployees.afterCreate", invalidate);
388
+ plugin.db.on("aiEmployees.afterUpdate", invalidate);
389
+ plugin.db.on("aiEmployees.afterDestroy", invalidate);
390
+ }
391
+ async function buildDelegateTools(plugin) {
392
+ const configRepo = plugin.db.getRepository("orchestratorConfig");
393
+ if (!configRepo) {
394
+ registeredDelegateNamesByPlugin.set(plugin, /* @__PURE__ */ new Set());
395
+ return [];
396
+ }
397
+ const configs = await configRepo.find({
398
+ filter: { enabled: true }
399
+ });
400
+ if (!(configs == null ? void 0 : configs.length)) {
401
+ registeredDelegateNamesByPlugin.set(plugin, /* @__PURE__ */ new Set());
402
+ return [];
403
+ }
404
+ const employeeCache = /* @__PURE__ */ new Map();
405
+ const tools = [];
406
+ const generatedNames = /* @__PURE__ */ new Map();
407
+ const configsBySubAgent = /* @__PURE__ */ new Map();
408
+ for (const config of configs) {
409
+ const items = configsBySubAgent.get(config.subAgentUsername) || [];
410
+ items.push(config);
411
+ configsBySubAgent.set(config.subAgentUsername, items);
412
+ }
413
+ for (const config of configs) {
414
+ const { leaderUsername, subAgentUsername, maxDepth, timeout, recursionLimit } = config;
415
+ let subAgentEmployee = employeeCache.get(subAgentUsername);
416
+ if (!subAgentEmployee) {
417
+ subAgentEmployee = await plugin.db.getRepository("aiEmployees").findOne({
418
+ filter: { username: subAgentUsername }
419
+ });
420
+ if (subAgentEmployee) {
421
+ employeeCache.set(subAgentUsername, subAgentEmployee);
422
+ }
423
+ }
424
+ if (!subAgentEmployee) continue;
425
+ const toolName = buildDelegateToolName(leaderUsername, subAgentUsername);
426
+ if (toolName.length > MAX_TOOL_NAME_LENGTH) {
427
+ plugin.app.log.error(
428
+ `[AgentOrchestrator] Tool name "${toolName}" exceeds the ${MAX_TOOL_NAME_LENGTH}-char limit enforced by most LLM providers. Skipping rule (${leaderUsername} \u2192 ${subAgentUsername}). Shorten one of the usernames.`
429
+ );
430
+ continue;
431
+ }
432
+ const existing = generatedNames.get(toolName);
433
+ if (existing) {
434
+ const suffix = (0, import_crypto.createHash)("sha1").update(`${leaderUsername}::${subAgentUsername}`).digest("hex").slice(0, 6);
435
+ plugin.app.log.error(
436
+ `[AgentOrchestrator] Tool-name collision: rule (${leaderUsername} \u2192 ${subAgentUsername}) sanitizes to "${toolName}", same as (${existing.leader} \u2192 ${existing.sub}). Skipping duplicate registration. Rename one of the usernames or apply suffix "_${suffix}" manually.`
437
+ );
438
+ continue;
439
+ }
440
+ generatedNames.set(toolName, { leader: leaderUsername, sub: subAgentUsername });
441
+ tools.push(
442
+ createDelegateToolOptions(plugin, {
443
+ leaderUsername,
444
+ subAgentUsername,
445
+ subAgentEmployee,
446
+ maxDepth,
447
+ timeout,
448
+ toolName,
449
+ llmService: config.llmService,
450
+ model: config.model,
451
+ recursionLimit
452
+ })
453
+ );
454
+ }
455
+ for (const [subAgentUsername, items] of configsBySubAgent.entries()) {
456
+ if (items.length !== 1) {
457
+ const leaders = items.map((c) => c.leaderUsername).join(", ");
458
+ plugin.app.log.warn(
459
+ `[AgentOrchestrator] Legacy alias "delegate_to_${sanitizeToolPart(
460
+ subAgentUsername
461
+ )}" is NOT registered for sub-agent "${subAgentUsername}" because it has multiple leaders (${leaders}). Leaders must use the per-rule "delegate_<leader>_to_<sub>" tool name.`
462
+ );
463
+ continue;
464
+ }
465
+ const config = items[0];
466
+ const subAgentEmployee = employeeCache.get(subAgentUsername);
467
+ if (!subAgentEmployee) continue;
468
+ const legacyToolName = `delegate_to_${sanitizeToolPart(subAgentUsername)}`;
469
+ if (legacyToolName.length > MAX_TOOL_NAME_LENGTH) {
470
+ plugin.app.log.error(
471
+ `[AgentOrchestrator] Legacy alias "${legacyToolName}" exceeds the ${MAX_TOOL_NAME_LENGTH}-char limit. Skipping alias for sub-agent "${subAgentUsername}".`
472
+ );
473
+ continue;
474
+ }
475
+ const aliasExisting = generatedNames.get(legacyToolName);
476
+ if (aliasExisting) {
477
+ plugin.app.log.error(
478
+ `[AgentOrchestrator] Legacy alias "${legacyToolName}" collides with another rule (${aliasExisting.leader} \u2192 ${aliasExisting.sub}). Skipping alias registration.`
479
+ );
480
+ continue;
481
+ }
482
+ generatedNames.set(legacyToolName, {
483
+ leader: config.leaderUsername,
484
+ sub: subAgentUsername
485
+ });
486
+ tools.push(
487
+ createDelegateToolOptions(plugin, {
488
+ leaderUsername: config.leaderUsername,
489
+ subAgentUsername,
490
+ subAgentEmployee,
491
+ maxDepth: config.maxDepth,
492
+ timeout: config.timeout,
493
+ toolName: legacyToolName,
494
+ legacyAlias: true,
495
+ llmService: config.llmService,
496
+ model: config.model,
497
+ recursionLimit: config.recursionLimit
498
+ })
499
+ );
500
+ }
501
+ const rulesByLeader = /* @__PURE__ */ new Map();
502
+ for (const config of configs) {
503
+ const subAgentEmployee = employeeCache.get(config.subAgentUsername);
504
+ if (!subAgentEmployee) continue;
505
+ let bucket = rulesByLeader.get(config.leaderUsername);
506
+ if (!bucket) {
507
+ bucket = /* @__PURE__ */ new Map();
508
+ rulesByLeader.set(config.leaderUsername, bucket);
509
+ }
510
+ bucket.set(config.subAgentUsername, { rule: config, employee: subAgentEmployee });
511
+ }
512
+ for (const [leaderUsername, rulesBySubAgent] of rulesByLeader.entries()) {
513
+ if (!rulesBySubAgent.size) continue;
514
+ const dispatchToolName = buildDispatchToolName(leaderUsername);
515
+ if (dispatchToolName.length > MAX_TOOL_NAME_LENGTH) {
516
+ plugin.app.log.error(
517
+ `[AgentOrchestrator] Dispatch tool "${dispatchToolName}" exceeds the ${MAX_TOOL_NAME_LENGTH}-char limit. Skipping for leader "${leaderUsername}".`
518
+ );
519
+ continue;
520
+ }
521
+ const dispatchExisting = generatedNames.get(dispatchToolName);
522
+ if (dispatchExisting) {
523
+ plugin.app.log.error(
524
+ `[AgentOrchestrator] Dispatch tool "${dispatchToolName}" collides with another generated tool (${dispatchExisting.leader} \u2192 ${dispatchExisting.sub}). Skipping dispatch registration for leader "${leaderUsername}".`
525
+ );
526
+ continue;
527
+ }
528
+ generatedNames.set(dispatchToolName, { leader: leaderUsername, sub: "(dispatch)" });
529
+ tools.push(createDispatchToolOptions(plugin, { leaderUsername, rulesBySubAgent }));
530
+ }
531
+ registeredDelegateNamesByPlugin.set(plugin, new Set(generatedNames.keys()));
532
+ return tools;
533
+ }
121
534
  function createDelegateToolsProvider(plugin) {
535
+ attachInvalidationHooks(plugin);
122
536
  return async (register) => {
123
537
  try {
124
- const configRepo = plugin.db.getRepository("orchestratorConfig");
125
- if (!configRepo) return;
126
- const configs = await configRepo.find({
127
- filter: { enabled: true }
128
- });
129
- if (!(configs == null ? void 0 : configs.length)) return;
130
- const employeeCache = /* @__PURE__ */ new Map();
131
- const tools = [];
132
- const configsBySubAgent = /* @__PURE__ */ new Map();
133
- for (const config of configs) {
134
- const items = configsBySubAgent.get(config.subAgentUsername) || [];
135
- items.push(config);
136
- configsBySubAgent.set(config.subAgentUsername, items);
538
+ let toolsCache = toolsCacheByPlugin.get(plugin);
539
+ if (!toolsCache || toolsCache.expiresAt <= Date.now()) {
540
+ const tools = await buildDelegateTools(plugin);
541
+ toolsCache = { tools, expiresAt: Date.now() + TOOLS_CACHE_TTL_MS };
542
+ toolsCacheByPlugin.set(plugin, toolsCache);
137
543
  }
138
- for (const config of configs) {
139
- const { leaderUsername, subAgentUsername, maxDepth, timeout } = config;
140
- let subAgentEmployee = employeeCache.get(subAgentUsername);
141
- if (!subAgentEmployee) {
142
- subAgentEmployee = await plugin.db.getRepository("aiEmployees").findOne({
143
- filter: { username: subAgentUsername }
144
- });
145
- if (subAgentEmployee) {
146
- employeeCache.set(subAgentUsername, subAgentEmployee);
147
- }
148
- }
149
- if (!subAgentEmployee) continue;
150
- const toolName = buildDelegateToolName(leaderUsername, subAgentUsername);
151
- tools.push(createDelegateToolOptions(plugin, {
152
- leaderUsername,
153
- subAgentUsername,
154
- subAgentEmployee,
155
- maxDepth,
156
- timeout,
157
- toolName,
158
- llmService: config.llmService,
159
- model: config.model
160
- }));
161
- }
162
- for (const [subAgentUsername, items] of configsBySubAgent.entries()) {
163
- if (items.length !== 1) continue;
164
- const config = items[0];
165
- const subAgentEmployee = employeeCache.get(subAgentUsername);
166
- if (!subAgentEmployee) continue;
167
- const legacyToolName = `delegate_to_${sanitizeToolPart(subAgentUsername)}`;
168
- if (tools.some((tool) => tool.definition.name === legacyToolName)) continue;
169
- tools.push(createDelegateToolOptions(plugin, {
170
- leaderUsername: config.leaderUsername,
171
- subAgentUsername,
172
- subAgentEmployee,
173
- maxDepth: config.maxDepth,
174
- timeout: config.timeout,
175
- toolName: legacyToolName,
176
- legacyAlias: true,
177
- llmService: config.llmService,
178
- model: config.model
179
- }));
180
- }
181
- if (tools.length) {
182
- register.registerTools(tools);
544
+ if (toolsCache.tools.length) {
545
+ register.registerTools(toolsCache.tools);
183
546
  }
184
547
  } catch (e) {
185
548
  plugin.app.log.error("[AgentOrchestrator] Failed to register delegate tools", e);
186
549
  }
187
550
  };
188
551
  }
552
+ function invalidateDelegateToolsCache() {
553
+ toolsCacheByPlugin = /* @__PURE__ */ new WeakMap();
554
+ registeredDelegateNamesByPlugin = /* @__PURE__ */ new WeakMap();
555
+ }
189
556
  async function invokeDelegateTask(ctx, plugin, options) {
190
557
  var _a, _b, _c, _d, _e;
191
- const { leaderUsername, subAgentUsername, subAgentEmployee, task, context, maxDepth, timeout, toolCallId, toolName, llmService, model } = options;
558
+ const {
559
+ leaderUsername,
560
+ subAgentUsername,
561
+ subAgentEmployee,
562
+ task,
563
+ context,
564
+ maxDepth,
565
+ timeout,
566
+ toolCallId,
567
+ toolName,
568
+ llmService,
569
+ model,
570
+ recursionLimit,
571
+ rootRunId: providedRootRunId,
572
+ parentSpanId: providedParentSpanId
573
+ } = options;
574
+ const ctxSnapshot = captureCtxSnapshot(ctx);
192
575
  const currentDepth = ctx[ORCHESTRATOR_DEPTH_KEY] ?? 0;
193
576
  if (currentDepth >= maxDepth) {
194
577
  await logDelegation(ctx, plugin, {
@@ -201,13 +584,18 @@ async function invokeDelegateTask(ctx, plugin, options) {
201
584
  status: "error",
202
585
  depth: currentDepth,
203
586
  durationMs: 0,
204
- error: `Delegation depth limit reached (${currentDepth}/${maxDepth}).`
587
+ error: `Delegation depth limit reached (${currentDepth}/${maxDepth}).`,
588
+ snapshot: ctxSnapshot
205
589
  });
206
590
  return {
207
591
  status: "error",
208
592
  content: `Delegation depth limit reached (${currentDepth}/${maxDepth}). Sub-agent "${subAgentUsername}" cannot delegate further.`
209
593
  };
210
594
  }
595
+ const spanService = new import_ExecutionSpanService.ExecutionSpanService(plugin);
596
+ const upstreamTraceContext = (0, import_ExecutionSpanService.getOrchestratorTraceContext)(ctx);
597
+ const rootRunId = providedRootRunId || (upstreamTraceContext == null ? void 0 : upstreamTraceContext.rootRunId) || createRootRunId(`${leaderUsername}:${subAgentUsername}`);
598
+ const parentSpanId = providedParentSpanId || (upstreamTraceContext == null ? void 0 : upstreamTraceContext.spanId) || (upstreamTraceContext == null ? void 0 : upstreamTraceContext.parentSpanId);
211
599
  const startTime = Date.now();
212
600
  const trace = [
213
601
  {
@@ -217,6 +605,25 @@ async function invokeDelegateTask(ctx, plugin, options) {
217
605
  content: task
218
606
  }
219
607
  ];
608
+ const executionSpan = await spanService.create({
609
+ rootRunId,
610
+ parentSpanId,
611
+ type: "sub_agent",
612
+ status: "running",
613
+ leaderUsername,
614
+ employeeUsername: subAgentUsername,
615
+ title: `Delegation: ${leaderUsername} -> ${subAgentUsername}`,
616
+ input: { task, context },
617
+ metadata: {
618
+ depth: currentDepth,
619
+ maxDepth,
620
+ toolName,
621
+ recursionLimit,
622
+ llmOverride: llmService && model ? { llmService, model } : void 0
623
+ },
624
+ userId: ctxSnapshot.userId
625
+ });
626
+ const executionSpanId = (executionSpan == null ? void 0 : executionSpan.id) ? String(executionSpan.id) : void 0;
220
627
  const logRecord = await logDelegation(ctx, plugin, {
221
628
  leaderUsername,
222
629
  subAgentUsername,
@@ -227,25 +634,31 @@ async function invokeDelegateTask(ctx, plugin, options) {
227
634
  status: "running",
228
635
  depth: currentDepth,
229
636
  durationMs: 0,
230
- trace
637
+ trace,
638
+ snapshot: ctxSnapshot
231
639
  });
640
+ if (executionSpanId && (logRecord == null ? void 0 : logRecord.id)) {
641
+ await spanService.update(executionSpanId, { orchestratorLogId: logRecord.id });
642
+ }
232
643
  try {
233
644
  const aiPlugin = ctx.app.pm.get("ai");
234
645
  if (!aiPlugin) {
235
646
  throw new Error("Plugin AI is not installed or enabled");
236
647
  }
237
- let modelSettings = subAgentEmployee.modelSettings;
648
+ let modelSettings = hasModelSettings(subAgentEmployee.modelSettings) ? subAgentEmployee.modelSettings : void 0;
238
649
  if (llmService && model) {
239
650
  modelSettings = { llmService, model };
240
651
  }
241
- if (!(modelSettings == null ? void 0 : modelSettings.llmService) || !(modelSettings == null ? void 0 : modelSettings.model)) {
652
+ if (!hasModelSettings(modelSettings)) {
242
653
  const leaderEmployee = await plugin.db.getRepository("aiEmployees").findOne({
243
654
  filter: { username: leaderUsername }
244
655
  });
245
656
  const dynamicModel = (_c = (_b = (_a = ctx.action) == null ? void 0 : _a.params) == null ? void 0 : _b.values) == null ? void 0 : _c.model;
246
- modelSettings = (leaderEmployee == null ? void 0 : leaderEmployee.modelSettings) || dynamicModel;
247
- if (!(modelSettings == null ? void 0 : modelSettings.llmService) || !(modelSettings == null ? void 0 : modelSettings.model)) {
248
- throw new Error(`Sub-agent "${subAgentUsername}" has no LLM model configured (and leader fallback failed). Please configure a model in the Orchestrator Config or AI Employee settings.`);
657
+ modelSettings = hasModelSettings(leaderEmployee == null ? void 0 : leaderEmployee.modelSettings) ? leaderEmployee.modelSettings : hasModelSettings(dynamicModel) ? dynamicModel : void 0;
658
+ if (!hasModelSettings(modelSettings)) {
659
+ throw new Error(
660
+ `Sub-agent "${subAgentUsername}" has no LLM model configured (and leader fallback failed). Please configure a model in the Orchestrator Config or AI Employee settings.`
661
+ );
249
662
  }
250
663
  }
251
664
  const { provider } = await aiPlugin.aiManager.getLLMService({
@@ -255,22 +668,56 @@ async function invokeDelegateTask(ctx, plugin, options) {
255
668
  const chatModel = provider.createModel();
256
669
  const coreToolsManager = ctx.app.aiManager.toolsManager;
257
670
  const allTools = await coreToolsManager.listTools();
258
- const employeeSkills = (((_d = subAgentEmployee.skillSettings) == null ? void 0 : _d.skills) ?? []).map((s) => typeof s === "string" ? s : s.name).filter(Boolean);
671
+ const employeeSkills = (((_d = subAgentEmployee.skillSettings) == null ? void 0 : _d.skills) ?? []).map(
672
+ (s) => typeof s === "string" ? { name: s, autoCall: false } : { name: s == null ? void 0 : s.name, autoCall: (s == null ? void 0 : s.autoCall) === true }
673
+ ).filter((s) => Boolean(s.name));
674
+ const employeeSkillMap = new Map(employeeSkills.map((skill) => [skill.name, skill]));
259
675
  const langchainTools = [];
260
676
  for (const toolEntry of allTools) {
261
- const toolName2 = toolEntry.definition.name;
262
- if (!toolName2) continue;
263
- if (!employeeSkills.includes(toolName2) || isDelegateToolName(toolName2)) {
677
+ const entryName = toolEntry.definition.name;
678
+ if (!entryName) continue;
679
+ const employeeSkill = employeeSkillMap.get(entryName);
680
+ if (!employeeSkill || isDelegateToolName(plugin, entryName) || employeeSkill.autoCall !== true || toolEntry.defaultPermission !== "ALLOW") {
264
681
  continue;
265
682
  }
266
683
  langchainTools.push(
267
684
  new import_tools.DynamicStructuredTool({
268
- name: toolName2.replace(/[^a-zA-Z0-9_-]/g, "_"),
269
- description: toolEntry.definition.description || toolName2,
685
+ name: entryName.replace(/[^a-zA-Z0-9_-]/g, "_"),
686
+ description: toolEntry.definition.description || entryName,
270
687
  schema: toolEntry.definition.schema || import_zod.z.object({}),
271
688
  func: async (toolArgs) => {
689
+ var _a2;
272
690
  const invokeCtx = Object.create(ctx);
273
691
  invokeCtx[ORCHESTRATOR_DEPTH_KEY] = currentDepth + 1;
692
+ const toolStartedAt = Date.now();
693
+ const isSkillHubTool = entryName === "skill_hub_execute" || entryName.startsWith("skill_hub_");
694
+ const toolSpan = await spanService.create({
695
+ rootRunId,
696
+ parentSpanId: executionSpanId,
697
+ type: isSkillHubTool ? "skill" : "tool",
698
+ status: "running",
699
+ leaderUsername,
700
+ employeeUsername: subAgentUsername,
701
+ toolName: toolEntry.definition.name,
702
+ title: isSkillHubTool ? `Skill: ${toolEntry.definition.name}` : `Tool: ${toolEntry.definition.name}`,
703
+ input: toolArgs,
704
+ metadata: {
705
+ depth: currentDepth + 1,
706
+ toolCallId: `orch-${toolCallId}`,
707
+ defaultPermission: toolEntry.defaultPermission
708
+ },
709
+ userId: ctxSnapshot.userId
710
+ });
711
+ const toolSpanId = (toolSpan == null ? void 0 : toolSpan.id) ? String(toolSpan.id) : void 0;
712
+ (0, import_ExecutionSpanService.setOrchestratorTraceContext)(invokeCtx, {
713
+ rootRunId,
714
+ spanId: toolSpanId,
715
+ parentSpanId: executionSpanId,
716
+ toolCallId: `orch-${toolCallId}`,
717
+ leaderUsername,
718
+ employeeUsername: subAgentUsername,
719
+ toolName: toolEntry.definition.name
720
+ });
274
721
  trace.push({
275
722
  type: "tool_call",
276
723
  at: nowIso(),
@@ -280,17 +727,26 @@ async function invokeDelegateTask(ctx, plugin, options) {
280
727
  });
281
728
  try {
282
729
  const res = await toolEntry.invoke(invokeCtx, toolArgs, `orch-${toolCallId}`);
730
+ const output = truncateText((res == null ? void 0 : res.content) ?? (res == null ? void 0 : res.result) ?? res, 5e4);
283
731
  trace.push({
284
732
  type: "tool_result",
285
733
  at: nowIso(),
286
734
  title: `Tool finished: ${toolEntry.definition.name}`,
287
735
  toolName: toolEntry.definition.name,
288
736
  status: (res == null ? void 0 : res.status) || "success",
289
- content: truncateText((res == null ? void 0 : res.content) ?? res, 2e3)
737
+ content: truncateText(output, 2e3)
290
738
  });
291
739
  if ((res == null ? void 0 : res.status) === "error") {
740
+ await spanService.finish(toolSpanId, "error", toolStartedAt, {
741
+ output,
742
+ error: truncateText(res.content || output, 1e4)
743
+ });
292
744
  throw new Error(`Tool <${toolEntry.definition.name}> failed: ${res.content}`);
293
745
  }
746
+ await spanService.finish(toolSpanId, "success", toolStartedAt, {
747
+ output,
748
+ skillExecutionId: ((_a2 = res == null ? void 0 : res.result) == null ? void 0 : _a2.execId) || (res == null ? void 0 : res.execId)
749
+ });
294
750
  return typeof (res == null ? void 0 : res.content) === "string" ? res.content : JSON.stringify(res);
295
751
  } catch (e) {
296
752
  trace.push({
@@ -301,6 +757,9 @@ async function invokeDelegateTask(ctx, plugin, options) {
301
757
  status: "error",
302
758
  content: e.message
303
759
  });
760
+ await spanService.finish(toolSpanId, "error", toolStartedAt, {
761
+ error: truncateText(e.message, 1e4)
762
+ });
304
763
  throw e;
305
764
  }
306
765
  }
@@ -317,11 +776,21 @@ async function invokeDelegateTask(ctx, plugin, options) {
317
776
 
318
777
  Context Provided:
319
778
  ${context}` : `Task: ${task}`;
320
- const invokePromise = executeAgent(executor, systemPrompt, combinedTask, abortController.signal);
321
- const result = await Promise.race([
322
- invokePromise,
323
- createTimeout(timeout, subAgentUsername, abortController)
324
- ]);
779
+ const effectiveRecursionLimit = Number.isFinite(recursionLimit) && recursionLimit > 0 ? recursionLimit : 50;
780
+ const invokePromise = executeAgent(
781
+ executor,
782
+ systemPrompt,
783
+ combinedTask,
784
+ abortController.signal,
785
+ effectiveRecursionLimit
786
+ );
787
+ const timeoutHandle = createTimeout(timeout, subAgentUsername, abortController);
788
+ let result;
789
+ try {
790
+ result = await Promise.race([invokePromise, timeoutHandle.promise]);
791
+ } finally {
792
+ timeoutHandle.cancel();
793
+ }
325
794
  const content = result.content || "Sub-agent completed the task but produced no output.";
326
795
  trace.push({
327
796
  type: "finish",
@@ -342,7 +811,19 @@ ${context}` : `Task: ${task}`;
342
811
  depth: currentDepth,
343
812
  durationMs: Date.now() - startTime,
344
813
  trace,
345
- messages: result.messages
814
+ messages: result.messages,
815
+ snapshot: ctxSnapshot
816
+ });
817
+ await spanService.finish(executionSpanId, "success", startTime, {
818
+ output: content,
819
+ metadata: {
820
+ depth: currentDepth,
821
+ maxDepth,
822
+ toolName,
823
+ recursionLimit,
824
+ messages: result.messages,
825
+ traceCount: trace.length
826
+ }
346
827
  });
347
828
  return {
348
829
  status: "success",
@@ -371,10 +852,21 @@ ${context}` : `Task: ${task}`;
371
852
  status: "error",
372
853
  content: e.message
373
854
  }
374
- ]
855
+ ],
856
+ snapshot: ctxSnapshot
375
857
  }).catch((logErr) => {
376
858
  plugin.app.log.warn("[AgentOrchestrator] Failed to save error log for delegation", logErr);
377
859
  });
860
+ await spanService.finish(executionSpanId, "error", startTime, {
861
+ error: truncateText(e.message, 1e4),
862
+ metadata: {
863
+ depth: currentDepth,
864
+ maxDepth,
865
+ toolName,
866
+ recursionLimit,
867
+ traceCount: trace.length + 1
868
+ }
869
+ });
378
870
  return {
379
871
  status: "error",
380
872
  content: `Sub-agent "${subAgentUsername}" failed: ${e.message}`
@@ -382,17 +874,19 @@ ${context}` : `Task: ${task}`;
382
874
  }
383
875
  }
384
876
  async function logDelegation(ctx, plugin, data) {
385
- var _a, _b, _c, _d, _e;
877
+ var _a, _b, _c, _d, _e, _f;
386
878
  try {
387
879
  const logsRepo = plugin.db.getRepository("orchestratorLogs");
388
880
  if (!logsRepo) {
389
881
  plugin.app.log.warn("[AgentOrchestrator] orchestratorLogs repository not found \u2014 skipping log");
390
882
  return;
391
883
  }
392
- let userId;
393
- try {
394
- userId = ((_b = (_a = ctx.auth) == null ? void 0 : _a.user) == null ? void 0 : _b.id) || ((_d = (_c = ctx.state) == null ? void 0 : _c.currentUser) == null ? void 0 : _d.id);
395
- } catch {
884
+ let userId = (_a = data.snapshot) == null ? void 0 : _a.userId;
885
+ if (userId == null) {
886
+ try {
887
+ userId = ((_c = (_b = ctx.auth) == null ? void 0 : _b.user) == null ? void 0 : _c.id) || ((_e = (_d = ctx.state) == null ? void 0 : _d.currentUser) == null ? void 0 : _e.id);
888
+ } catch {
889
+ }
396
890
  }
397
891
  const values = {
398
892
  leaderUsername: data.leaderUsername,
@@ -423,13 +917,13 @@ async function logDelegation(ctx, plugin, data) {
423
917
  createdAt: /* @__PURE__ */ new Date()
424
918
  }
425
919
  });
426
- return ((_e = record == null ? void 0 : record.toJSON) == null ? void 0 : _e.call(record)) || record;
920
+ return ((_f = record == null ? void 0 : record.toJSON) == null ? void 0 : _f.call(record)) || record;
427
921
  } catch (e) {
428
922
  plugin.app.log.warn("[AgentOrchestrator] Failed to log delegation event", e);
429
923
  }
430
924
  }
431
- async function executeAgent(executor, systemPrompt, task, signal) {
432
- const config = { recursionLimit: 50 };
925
+ async function executeAgent(executor, systemPrompt, task, signal, recursionLimit = 50) {
926
+ const config = { recursionLimit };
433
927
  if (signal) {
434
928
  config.signal = signal;
435
929
  }
@@ -470,14 +964,22 @@ function serializeMessages(messages) {
470
964
  });
471
965
  }
472
966
  function createTimeout(ms, agentName, abortController) {
473
- return new Promise(
474
- (_, reject) => setTimeout(() => {
967
+ let timer;
968
+ const promise = new Promise((_resolve, reject) => {
969
+ timer = setTimeout(() => {
475
970
  abortController == null ? void 0 : abortController.abort();
476
971
  reject(new Error(`Sub-agent "${agentName}" timed out after ${ms / 1e3}s`));
477
- }, ms)
478
- );
972
+ }, ms);
973
+ });
974
+ return {
975
+ promise,
976
+ cancel: () => {
977
+ if (timer) clearTimeout(timer);
978
+ }
979
+ };
479
980
  }
480
981
  // Annotate the CommonJS export names for ESM import in node:
481
982
  0 && (module.exports = {
482
- createDelegateToolsProvider
983
+ createDelegateToolsProvider,
984
+ invalidateDelegateToolsCache
483
985
  });