plugin-agent-orchestrator 1.0.27 → 1.0.32

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 (110) hide show
  1. package/README.md +9 -7
  2. package/dist/client/index.js +1 -1
  3. package/dist/client-v2/{214.723affb37c13bf7a.js → 214.79650a549273f163.js} +1 -1
  4. package/dist/client-v2/264.718a107e43fc163c.js +10 -0
  5. package/dist/client-v2/373.f5d5292e53c4e832.js +10 -0
  6. package/dist/client-v2/{41.1805b2edfaa4afe2.js → 41.ba6e080cc0488143.js} +1 -1
  7. package/dist/client-v2/418.29e713f79131eece.js +10 -0
  8. package/dist/client-v2/619.bd3c5698b40705c3.js +10 -0
  9. package/dist/client-v2/677.a991ce0250ff5c77.js +10 -0
  10. package/dist/client-v2/{70.a15d7fcec7c41768.js → 70.bda9518881c05360.js} +1 -1
  11. package/dist/client-v2/925.f5370de8f6632d65.js +10 -0
  12. package/dist/client-v2/index.js +1 -1
  13. package/dist/externalVersion.js +7 -10
  14. package/dist/locale/en-US.json +94 -25
  15. package/dist/locale/vi-VN.json +94 -25
  16. package/dist/locale/zh-CN.json +94 -25
  17. package/dist/server/collections/agent-execution-spans.js +37 -0
  18. package/dist/server/collections/agent-harness-profiles.js +2 -2
  19. package/dist/server/collections/agent-memory-contexts.js +125 -0
  20. package/dist/server/collections/orchestrator-logs.js +2 -2
  21. package/dist/server/migrations/20260425000000-add-interaction-schema.js +3 -1
  22. package/dist/server/migrations/20260427000000-change-packages-to-text.js +3 -1
  23. package/dist/server/migrations/20260427000001-change-other-json-to-text.js +6 -2
  24. package/dist/server/migrations/20260524001000-add-plan-approval-and-harness-profiles.js +21 -19
  25. package/dist/server/migrations/20260621000000-native-policy-profile-defaults.js +193 -0
  26. package/dist/server/plugin.js +128 -74
  27. package/dist/server/resources/agent-monitor.js +454 -0
  28. package/dist/server/services/AgentHarness.js +24 -499
  29. package/dist/server/services/AgentMemoryContextService.js +216 -0
  30. package/dist/server/services/ExecutionSpanService.js +2 -2
  31. package/dist/server/services/NativeSubAgentObserver.js +413 -0
  32. package/dist/server/skill-hub/mcp/McpController.js +16 -5
  33. package/dist/server/skill-hub/plugin.js +81 -5
  34. package/dist/server/skill-hub/tasks/SkillExecutionTask.js +9 -3
  35. package/dist/server/tools/delegate-task.js +11 -589
  36. package/dist/server/utils/skill-settings.js +18 -1
  37. package/package.json +47 -49
  38. package/src/client/AIEmployeesContext.tsx +5 -18
  39. package/src/client/AgentRunsTab.tsx +2 -771
  40. package/src/client/HarnessProfilesTab.tsx +2 -257
  41. package/src/client/OrchestratorSettings.tsx +97 -106
  42. package/src/client/RulesTab.tsx +2 -788
  43. package/src/client/plugin.tsx +0 -2
  44. package/src/client/skill-hub/components/ExecutionHistory.tsx +200 -202
  45. package/src/client/skill-hub/components/ExecutionProgress.tsx +51 -55
  46. package/src/client/skill-hub/components/LoopSettings.tsx +331 -331
  47. package/src/client/skill-hub/components/SkillEditor.tsx +43 -39
  48. package/src/client/skill-hub/components/SkillManager.tsx +194 -181
  49. package/src/client/skill-hub/components/SkillTestPanel.tsx +141 -145
  50. package/src/client/skill-hub/locale.ts +16 -16
  51. package/src/client/skill-hub/tools/SkillHubCard.tsx +104 -109
  52. package/src/client/skill-hub/tools/loopTemplates.ts +52 -52
  53. package/src/client/skill-hub/utils/jsonFields.ts +7 -3
  54. package/src/client-v2/components/AIEmployeesContext.tsx +3 -16
  55. package/src/client-v2/components/AgentRunsTab.tsx +182 -455
  56. package/src/client-v2/components/HarnessProfilesTab.tsx +34 -31
  57. package/src/client-v2/components/RulesTab.tsx +2 -782
  58. package/src/client-v2/components/TracingTab.tsx +1 -1
  59. package/src/client-v2/hooks/useApiRequest.ts +8 -1
  60. package/src/client-v2/pages/RulesPage.tsx +2 -2
  61. package/src/client-v2/plugin.tsx +3 -3
  62. package/src/locale/en-US.json +94 -25
  63. package/src/locale/vi-VN.json +94 -25
  64. package/src/locale/zh-CN.json +94 -25
  65. package/src/server/__tests__/native-sub-agent-observer.test.ts +246 -0
  66. package/src/server/__tests__/skill-settings.test.ts +6 -6
  67. package/src/server/__tests__/smoke.test.ts +1 -0
  68. package/src/server/collections/agent-execution-spans.ts +37 -0
  69. package/src/server/collections/agent-harness-profiles.ts +59 -59
  70. package/src/server/collections/agent-loop-events.ts +71 -71
  71. package/src/server/collections/agent-loop-steps.ts +144 -144
  72. package/src/server/collections/agent-memory-contexts.ts +95 -0
  73. package/src/server/collections/orchestrator-logs.ts +4 -4
  74. package/src/server/collections/skill-definitions.ts +111 -111
  75. package/src/server/collections/skill-executions.ts +106 -106
  76. package/src/server/collections/skill-loop-configs.ts +65 -65
  77. package/src/server/migrations/20260423000000-add-progress-fields.ts +14 -14
  78. package/src/server/migrations/20260425000000-add-interaction-schema.ts +3 -1
  79. package/src/server/migrations/20260427000000-change-packages-to-text.ts +4 -2
  80. package/src/server/migrations/20260427000001-change-other-json-to-text.ts +9 -5
  81. package/src/server/migrations/20260524000000-add-agent-loop-fields-to-skill-executions.ts +30 -30
  82. package/src/server/migrations/20260524001000-add-plan-approval-and-harness-profiles.ts +145 -142
  83. package/src/server/migrations/20260615000000-normalize-ai-employee-tool-bindings.ts +2 -2
  84. package/src/server/migrations/20260621000000-native-policy-profile-defaults.ts +193 -0
  85. package/src/server/plugin.ts +151 -94
  86. package/src/server/resources/agent-monitor.ts +482 -0
  87. package/src/server/services/AgentHarness.ts +38 -623
  88. package/src/server/services/AgentMemoryContextService.ts +256 -0
  89. package/src/server/services/AgentPlanValidator.ts +73 -73
  90. package/src/server/services/ExecutionSpanService.ts +6 -2
  91. package/src/server/services/FileManager.ts +144 -144
  92. package/src/server/services/NativeSubAgentObserver.ts +507 -0
  93. package/src/server/services/SkillManager.ts +583 -583
  94. package/src/server/services/SkillRepositoryService.ts +5 -7
  95. package/src/server/services/TokenTracker.ts +3 -3
  96. package/src/server/services/WorkerEnvManager.ts +1 -2
  97. package/src/server/skill-hub/actions/git-import.ts +5 -7
  98. package/src/server/skill-hub/mcp/McpController.ts +41 -14
  99. package/src/server/skill-hub/plugin.ts +89 -6
  100. package/src/server/skill-hub/tasks/SkillExecutionTask.ts +470 -460
  101. package/src/server/skill-hub/utils/json-fields.ts +1 -1
  102. package/src/server/tools/delegate-task.ts +13 -847
  103. package/src/server/utils/skill-settings.ts +24 -6
  104. package/dist/client-v2/264.0533912e6c5ea2d7.js +0 -10
  105. package/dist/client-v2/418.5ae055abf141820e.js +0 -10
  106. package/dist/client-v2/619.d99d3c9e61c99064.js +0 -10
  107. package/dist/client-v2/892.72db4161511c8a16.js +0 -10
  108. package/dist/client-v2/926.87f660b670d85bcc.js +0 -10
  109. package/src/client/tools/PlanApprovalCard.tsx +0 -176
  110. package/src/client/tools/registerOrchestratorCards.ts +0 -17
@@ -26,23 +26,12 @@ 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
+ buildDelegateToolName: () => buildDelegateToolName,
30
+ buildDispatchToolName: () => buildDispatchToolName,
29
31
  createDelegateToolsProvider: () => createDelegateToolsProvider,
30
32
  invalidateDelegateToolsCache: () => invalidateDelegateToolsCache
31
33
  });
32
34
  module.exports = __toCommonJS(delegate_task_exports);
33
- var import_zod = require("zod");
34
- var import_crypto = require("crypto");
35
- var import_ExecutionSpanService = require("../services/ExecutionSpanService");
36
- var import_ctx_utils = require("../utils/ctx-utils");
37
- var import_logging = require("../utils/logging");
38
- const ORCHESTRATOR_DEPTH_KEY = "__orchestratorDepth";
39
- const ORCHESTRATOR_PATH_KEY = "__orchestratorPath";
40
- const MAX_DISPATCH_CONCURRENCY = 5;
41
- const MAX_DISPATCH_TASKS = 20;
42
- const MAX_TOOL_NAME_LENGTH = 64;
43
- function getToolCallId(runtime) {
44
- return typeof runtime === "string" ? runtime : runtime == null ? void 0 : runtime.toolCallId;
45
- }
46
35
  function sanitizeToolPart(value) {
47
36
  return (value || "").replace(/[^a-zA-Z0-9_-]/g, "_");
48
37
  }
@@ -52,588 +41,21 @@ function buildDelegateToolName(leaderUsername, subAgentUsername) {
52
41
  function buildDispatchToolName(leaderUsername) {
53
42
  return `dispatch_subagents_${sanitizeToolPart(leaderUsername)}`;
54
43
  }
55
- function createRootRunId(seed = "") {
56
- const hash = (0, import_crypto.createHash)("sha1").update(`${Date.now()}::${Math.random()}::${seed}`).digest("hex").slice(0, 10);
57
- return `run_${Date.now()}_${hash}`;
58
- }
59
- let registeredDelegateNamesByPlugin = /* @__PURE__ */ new WeakMap();
60
- function isDelegateToolName(plugin, toolName) {
61
- var _a;
62
- return ((_a = registeredDelegateNamesByPlugin.get(plugin)) == null ? void 0 : _a.has(toolName)) ?? false;
63
- }
64
- async function runWithConcurrency(items, limit, fn) {
65
- const results = new Array(items.length);
66
- let cursor = 0;
67
- const workerCount = Math.max(1, Math.min(limit, items.length));
68
- const workers = Array.from({ length: workerCount }, async () => {
69
- while (cursor < items.length) {
70
- const i = cursor;
71
- cursor += 1;
72
- results[i] = await fn(items[i], i);
73
- }
74
- });
75
- await Promise.all(workers);
76
- return results;
77
- }
78
- function createDelegateToolOptions(plugin, options) {
79
- const {
80
- leaderUsername,
81
- subAgentUsername,
82
- subAgentEmployee,
83
- maxDepth,
84
- timeout,
85
- toolName,
86
- legacyAlias,
87
- llmService,
88
- model,
89
- recursionLimit
90
- } = options;
91
- const dispatchToolName = buildDispatchToolName(leaderUsername);
92
- const toolDescription = [
93
- `Delegate a task from "${leaderUsername}" to the AI Employee "${subAgentEmployee.nickname || subAgentUsername}".`,
94
- legacyAlias ? "This is a backward-compatible alias for existing skill assignments." : "",
95
- subAgentEmployee.about ? `Specialist profile: ${subAgentEmployee.about.substring(0, 200)}` : "",
96
- "The sub-agent will execute the task independently and return its final answer.",
97
- `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.`
98
- ].filter(Boolean).join(" ");
99
- return {
100
- scope: "CUSTOM",
101
- execution: "backend",
102
- defaultPermission: "ASK",
103
- silence: false,
104
- introduction: {
105
- title: `[${leaderUsername}] ${subAgentEmployee.nickname || subAgentUsername}${legacyAlias ? " (legacy)" : ""}`,
106
- about: toolDescription
107
- },
108
- definition: {
109
- name: toolName,
110
- description: toolDescription,
111
- schema: import_zod.z.object({
112
- task: import_zod.z.string().describe("The detailed task description for the sub-agent to execute."),
113
- context: import_zod.z.string().optional().describe("Optional additional context to help the sub-agent understand the task better.")
114
- })
115
- },
116
- invoke: async (ctx, args, runtime) => {
117
- const id = getToolCallId(runtime) || `delegate-${Date.now()}`;
118
- const callingEmployee = await resolveCallingEmployee(ctx, plugin);
119
- if (!callingEmployee) {
120
- await logDelegation(ctx, plugin, {
121
- leaderUsername,
122
- subAgentUsername,
123
- toolName,
124
- task: args.task,
125
- context: args.context,
126
- result: "",
127
- status: "error",
128
- depth: ctx[ORCHESTRATOR_DEPTH_KEY] ?? 0,
129
- durationMs: 0,
130
- error: `Cannot determine calling AI employee for delegation tool "${toolName}".`
131
- });
132
- return {
133
- status: "error",
134
- content: `Cannot determine calling AI employee for "${toolName}". Start the request from an AI Employee conversation so leader scoping can be enforced.`
135
- };
136
- }
137
- if (callingEmployee && callingEmployee !== leaderUsername) {
138
- await logDelegation(ctx, plugin, {
139
- leaderUsername,
140
- subAgentUsername,
141
- toolName,
142
- task: args.task,
143
- context: args.context,
144
- result: "",
145
- status: "error",
146
- depth: ctx[ORCHESTRATOR_DEPTH_KEY] ?? 0,
147
- durationMs: 0,
148
- error: `Employee "${callingEmployee}" is not authorized to use this delegation rule.`
149
- });
150
- return {
151
- status: "error",
152
- content: `Employee "${callingEmployee}" is not authorized to delegate to "${subAgentUsername}". Configure an orchestration rule first.`
153
- };
154
- }
155
- return invokeDelegateTask(ctx, plugin, {
156
- leaderUsername,
157
- subAgentUsername,
158
- subAgentEmployee,
159
- task: args.task,
160
- context: args.context,
161
- maxDepth: maxDepth ?? 1,
162
- timeout: timeout ?? 12e4,
163
- toolCallId: id,
164
- toolName,
165
- llmService,
166
- model,
167
- recursionLimit
168
- });
169
- }
170
- };
171
- }
172
- function formatDispatchResults(results, rulesBySubAgent) {
173
- var _a;
174
- const total = results.length;
175
- const ok = results.filter((r) => r.status === "success").length;
176
- const lines = [
177
- `Dispatched ${total} sub-task(s) \u2014 ${ok} succeeded, ${total - ok} failed (max ${MAX_DISPATCH_CONCURRENCY} ran in parallel).`,
178
- ""
179
- ];
180
- for (const r of results) {
181
- const employee = (_a = rulesBySubAgent.get(r.subAgent)) == null ? void 0 : _a.employee;
182
- const displayName = (employee == null ? void 0 : employee.nickname) || r.subAgent;
183
- const dur = `${(r.durationMs / 1e3).toFixed(1)}s`;
184
- lines.push(`--- [${r.index + 1}] ${displayName} (${r.subAgent}) [${r.status}] (${dur}) ---`);
185
- lines.push(r.content || "(empty)");
186
- lines.push("");
187
- }
188
- return lines.join("\n").trimEnd();
189
- }
190
- function createDispatchToolOptions(plugin, options) {
191
- const { leaderUsername, rulesBySubAgent } = options;
192
- const toolName = buildDispatchToolName(leaderUsername);
193
- const subAgentNames = Array.from(rulesBySubAgent.keys());
194
- const subAgentList = subAgentNames.map((username) => {
195
- var _a, _b;
196
- const entry = rulesBySubAgent.get(username);
197
- if (!entry) return `- ${username}`;
198
- const profile = ((_a = entry.employee) == null ? void 0 : _a.about) ? ` \u2014 ${String(entry.employee.about).substring(0, 120)}` : "";
199
- const display = ((_b = entry.employee) == null ? void 0 : _b.nickname) ? ` (${entry.employee.nickname})` : "";
200
- return `- ${username}${display}${profile}`;
201
- }).join("\n");
202
- const description = [
203
- `Dispatch multiple tasks from "${leaderUsername}" to its configured sub-agents in one call.`,
204
- `At most ${MAX_DISPATCH_CONCURRENCY} sub-tasks run in parallel; up to ${MAX_DISPATCH_TASKS} tasks per call.`,
205
- "Use this when you have already planned independent sub-tasks and want to fan-out, then aggregate the results.",
206
- `Available sub-agents:
207
- ${subAgentList}`
208
- ].join(" ");
209
- return {
210
- scope: "CUSTOM",
211
- execution: "backend",
212
- defaultPermission: "ASK",
213
- silence: false,
214
- introduction: {
215
- title: `[${leaderUsername}] Dispatch sub-agents`,
216
- about: description
217
- },
218
- definition: {
219
- name: toolName,
220
- description,
221
- schema: import_zod.z.object({
222
- tasks: import_zod.z.array(
223
- import_zod.z.object({
224
- subAgent: import_zod.z.enum(subAgentNames).describe("Username of the sub-agent that should execute this task."),
225
- task: import_zod.z.string().describe("Detailed task description for the sub-agent."),
226
- context: import_zod.z.string().optional().describe("Optional additional context for the sub-agent.")
227
- })
228
- ).min(1).max(MAX_DISPATCH_TASKS).describe(`List of sub-tasks to dispatch concurrently. Up to ${MAX_DISPATCH_CONCURRENCY} run in parallel.`)
229
- })
230
- },
231
- invoke: async (ctx, args, runtime) => {
232
- var _a;
233
- const id = getToolCallId(runtime) || `dispatch-${Date.now()}`;
234
- const callingEmployee = await resolveCallingEmployee(ctx, plugin);
235
- if (!callingEmployee) {
236
- const distinctSubs = Array.from(new Set((args.tasks ?? []).map((t) => t.subAgent).filter(Boolean)));
237
- const reportedSub = distinctSubs.length === 1 ? distinctSubs[0] : "(multiple)";
238
- await logDelegation(ctx, plugin, {
239
- leaderUsername,
240
- subAgentUsername: reportedSub,
241
- toolName,
242
- task: (0, import_ctx_utils.trimText)(args.tasks ?? [], 2e3),
243
- result: "",
244
- status: "error",
245
- depth: ctx[ORCHESTRATOR_DEPTH_KEY] ?? 0,
246
- durationMs: 0,
247
- error: `Cannot determine calling AI employee for dispatch tool "${toolName}". Targets: ${distinctSubs.join(", ") || "(empty)"}.`
248
- });
249
- return {
250
- status: "error",
251
- content: `Cannot determine calling AI employee for "${toolName}". Start the request from an AI Employee conversation so leader scoping can be enforced.`
252
- };
253
- }
254
- if (callingEmployee && callingEmployee !== leaderUsername) {
255
- const distinctSubs = Array.from(new Set((args.tasks ?? []).map((t) => t.subAgent).filter(Boolean)));
256
- const reportedSub = distinctSubs.length === 1 ? distinctSubs[0] : "(multiple)";
257
- await logDelegation(ctx, plugin, {
258
- leaderUsername,
259
- subAgentUsername: reportedSub,
260
- toolName,
261
- task: (0, import_ctx_utils.trimText)(args.tasks ?? [], 2e3),
262
- result: "",
263
- status: "error",
264
- depth: ctx[ORCHESTRATOR_DEPTH_KEY] ?? 0,
265
- durationMs: 0,
266
- error: `Employee "${callingEmployee}" is not authorized to dispatch sub-agents for leader "${leaderUsername}". Targets: ${distinctSubs.join(", ") || "(empty)"}.`
267
- });
268
- return {
269
- status: "error",
270
- content: `Employee "${callingEmployee}" is not authorized to dispatch sub-agents for leader "${leaderUsername}".`
271
- };
272
- }
273
- const tasks = args.tasks ?? [];
274
- if (!tasks.length) {
275
- return {
276
- status: "error",
277
- content: "No tasks provided. Pass at least one item in `tasks`."
278
- };
279
- }
280
- const dispatchRootRunId = ((_a = (0, import_ExecutionSpanService.getOrchestratorTraceContext)(ctx)) == null ? void 0 : _a.rootRunId) || createRootRunId(`${leaderUsername}:dispatch`);
281
- const results = await runWithConcurrency(tasks, MAX_DISPATCH_CONCURRENCY, async (item, i) => {
282
- const startedAt = Date.now();
283
- const entry = rulesBySubAgent.get(item.subAgent);
284
- if (!entry) {
285
- return {
286
- index: i,
287
- subAgent: item.subAgent,
288
- status: "error",
289
- content: `Unknown sub-agent "${item.subAgent}". Allowed: ${subAgentNames.join(", ")}.`,
290
- durationMs: 0
291
- };
292
- }
293
- try {
294
- const res = await invokeDelegateTask(ctx, plugin, {
295
- leaderUsername,
296
- subAgentUsername: item.subAgent,
297
- subAgentEmployee: entry.employee,
298
- task: item.task,
299
- context: item.context,
300
- maxDepth: entry.rule.maxDepth ?? 1,
301
- timeout: entry.rule.timeout ?? 12e4,
302
- toolCallId: `${id}-${i}`,
303
- toolName,
304
- llmService: entry.rule.llmService,
305
- model: entry.rule.model,
306
- recursionLimit: entry.rule.recursionLimit,
307
- rootRunId: dispatchRootRunId
308
- });
309
- return {
310
- index: i,
311
- subAgent: item.subAgent,
312
- status: res.status,
313
- content: res.content,
314
- durationMs: Date.now() - startedAt
315
- };
316
- } catch (e) {
317
- return {
318
- index: i,
319
- subAgent: item.subAgent,
320
- status: "error",
321
- content: (e == null ? void 0 : e.message) || String(e),
322
- durationMs: Date.now() - startedAt
323
- };
324
- }
325
- });
326
- const successCount = results.filter((r) => r.status === "success").length;
327
- return {
328
- status: successCount > 0 ? "success" : "error",
329
- content: formatDispatchResults(results, rulesBySubAgent)
330
- };
331
- }
332
- };
333
- }
334
- async function resolveCallingEmployee(ctx, plugin) {
335
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
336
- const values = ((_b = (_a = ctx.action) == null ? void 0 : _a.params) == null ? void 0 : _b.values) || {};
337
- 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;
338
- const direct = (0, import_ctx_utils.normalizeEmployeeUsername)(raw);
339
- if (direct) return direct;
340
- const sessionId = values.sessionId || ((_g = (_f = ctx.action) == null ? void 0 : _f.params) == null ? void 0 : _g.sessionId);
341
- if (!sessionId) return null;
342
- try {
343
- const repo = ((_i = (_h = ctx.db) == null ? void 0 : _h.getRepository) == null ? void 0 : _i.call(_h, "aiConversations")) || plugin.db.getRepository("aiConversations");
344
- const conversation = await repo.findOne({
345
- filter: { sessionId }
346
- });
347
- return (0, import_ctx_utils.normalizeEmployeeUsername)((conversation == null ? void 0 : conversation.aiEmployeeUsername) || ((_j = conversation == null ? void 0 : conversation.get) == null ? void 0 : _j.call(conversation, "aiEmployeeUsername")));
348
- } catch (e) {
349
- plugin.app.log.warn(`[AgentOrchestrator] Failed to resolve AI employee for session "${sessionId}"`, e);
350
- return null;
351
- }
352
- }
353
- function hasModelSettings(value) {
354
- return Boolean((value == null ? void 0 : value.llmService) && (value == null ? void 0 : value.model));
355
- }
356
- const TOOLS_CACHE_TTL_MS = 3e4;
357
- let toolsCacheByPlugin = /* @__PURE__ */ new WeakMap();
358
- let hooksAttached = null;
359
- function attachInvalidationHooks(plugin) {
360
- if (!hooksAttached) hooksAttached = /* @__PURE__ */ new WeakSet();
361
- if (hooksAttached.has(plugin)) return;
362
- hooksAttached.add(plugin);
363
- const invalidate = () => {
364
- toolsCacheByPlugin.delete(plugin);
365
- registeredDelegateNamesByPlugin.delete(plugin);
366
- };
367
- plugin.db.on("orchestratorConfig.afterCreate", invalidate);
368
- plugin.db.on("orchestratorConfig.afterUpdate", invalidate);
369
- plugin.db.on("orchestratorConfig.afterDestroy", invalidate);
370
- plugin.db.on("aiEmployees.afterCreate", invalidate);
371
- plugin.db.on("aiEmployees.afterUpdate", invalidate);
372
- plugin.db.on("aiEmployees.afterDestroy", invalidate);
373
- }
374
- async function buildDelegateTools(plugin) {
375
- const configRepo = plugin.db.getRepository("orchestratorConfig");
376
- if (!configRepo) {
377
- registeredDelegateNamesByPlugin.set(plugin, /* @__PURE__ */ new Set());
378
- return [];
379
- }
380
- const configs = await configRepo.find({
381
- filter: { enabled: true }
382
- });
383
- if (!(configs == null ? void 0 : configs.length)) {
384
- registeredDelegateNamesByPlugin.set(plugin, /* @__PURE__ */ new Set());
385
- return [];
386
- }
387
- const employeeCache = /* @__PURE__ */ new Map();
388
- const tools = [];
389
- const generatedNames = /* @__PURE__ */ new Map();
390
- const configsBySubAgent = /* @__PURE__ */ new Map();
391
- for (const config of configs) {
392
- const items = configsBySubAgent.get(config.subAgentUsername) || [];
393
- items.push(config);
394
- configsBySubAgent.set(config.subAgentUsername, items);
395
- }
396
- for (const config of configs) {
397
- const { leaderUsername, subAgentUsername, maxDepth, timeout, recursionLimit } = config;
398
- let subAgentEmployee = employeeCache.get(subAgentUsername);
399
- if (!subAgentEmployee) {
400
- subAgentEmployee = await plugin.db.getRepository("aiEmployees").findOne({
401
- filter: { username: subAgentUsername }
402
- });
403
- if (subAgentEmployee) {
404
- employeeCache.set(subAgentUsername, subAgentEmployee);
405
- }
406
- }
407
- if (!subAgentEmployee) continue;
408
- const toolName = buildDelegateToolName(leaderUsername, subAgentUsername);
409
- if (toolName.length > MAX_TOOL_NAME_LENGTH) {
410
- plugin.app.log.error(
411
- `[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.`
412
- );
413
- continue;
414
- }
415
- const existing = generatedNames.get(toolName);
416
- if (existing) {
417
- const suffix = (0, import_crypto.createHash)("sha1").update(`${leaderUsername}::${subAgentUsername}`).digest("hex").slice(0, 6);
418
- plugin.app.log.error(
419
- `[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.`
420
- );
421
- continue;
422
- }
423
- generatedNames.set(toolName, { leader: leaderUsername, sub: subAgentUsername });
424
- tools.push(
425
- createDelegateToolOptions(plugin, {
426
- leaderUsername,
427
- subAgentUsername,
428
- subAgentEmployee,
429
- maxDepth,
430
- timeout,
431
- toolName,
432
- llmService: config.llmService,
433
- model: config.model,
434
- recursionLimit
435
- })
436
- );
437
- }
438
- for (const [subAgentUsername, items] of configsBySubAgent.entries()) {
439
- if (items.length !== 1) {
440
- const leaders = items.map((c) => c.leaderUsername).join(", ");
441
- plugin.app.log.warn(
442
- `[AgentOrchestrator] Legacy alias "delegate_to_${sanitizeToolPart(
443
- subAgentUsername
444
- )}" 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.`
445
- );
446
- continue;
447
- }
448
- const config = items[0];
449
- const subAgentEmployee = employeeCache.get(subAgentUsername);
450
- if (!subAgentEmployee) continue;
451
- const legacyToolName = `delegate_to_${sanitizeToolPart(subAgentUsername)}`;
452
- if (legacyToolName.length > MAX_TOOL_NAME_LENGTH) {
453
- plugin.app.log.error(
454
- `[AgentOrchestrator] Legacy alias "${legacyToolName}" exceeds the ${MAX_TOOL_NAME_LENGTH}-char limit. Skipping alias for sub-agent "${subAgentUsername}".`
455
- );
456
- continue;
457
- }
458
- const aliasExisting = generatedNames.get(legacyToolName);
459
- if (aliasExisting) {
460
- plugin.app.log.error(
461
- `[AgentOrchestrator] Legacy alias "${legacyToolName}" collides with another rule (${aliasExisting.leader} \u2192 ${aliasExisting.sub}). Skipping alias registration.`
462
- );
463
- continue;
464
- }
465
- generatedNames.set(legacyToolName, {
466
- leader: config.leaderUsername,
467
- sub: subAgentUsername
468
- });
469
- tools.push(
470
- createDelegateToolOptions(plugin, {
471
- leaderUsername: config.leaderUsername,
472
- subAgentUsername,
473
- subAgentEmployee,
474
- maxDepth: config.maxDepth,
475
- timeout: config.timeout,
476
- toolName: legacyToolName,
477
- legacyAlias: true,
478
- llmService: config.llmService,
479
- model: config.model,
480
- recursionLimit: config.recursionLimit
481
- })
482
- );
483
- }
484
- const rulesByLeader = /* @__PURE__ */ new Map();
485
- for (const config of configs) {
486
- const subAgentEmployee = employeeCache.get(config.subAgentUsername);
487
- if (!subAgentEmployee) continue;
488
- let bucket = rulesByLeader.get(config.leaderUsername);
489
- if (!bucket) {
490
- bucket = /* @__PURE__ */ new Map();
491
- rulesByLeader.set(config.leaderUsername, bucket);
492
- }
493
- bucket.set(config.subAgentUsername, { rule: config, employee: subAgentEmployee });
494
- }
495
- for (const [leaderUsername, rulesBySubAgent] of rulesByLeader.entries()) {
496
- if (!rulesBySubAgent.size) continue;
497
- const dispatchToolName = buildDispatchToolName(leaderUsername);
498
- if (dispatchToolName.length > MAX_TOOL_NAME_LENGTH) {
499
- plugin.app.log.error(
500
- `[AgentOrchestrator] Dispatch tool "${dispatchToolName}" exceeds the ${MAX_TOOL_NAME_LENGTH}-char limit. Skipping for leader "${leaderUsername}".`
501
- );
502
- continue;
503
- }
504
- const dispatchExisting = generatedNames.get(dispatchToolName);
505
- if (dispatchExisting) {
506
- plugin.app.log.error(
507
- `[AgentOrchestrator] Dispatch tool "${dispatchToolName}" collides with another generated tool (${dispatchExisting.leader} \u2192 ${dispatchExisting.sub}). Skipping dispatch registration for leader "${leaderUsername}".`
508
- );
509
- continue;
510
- }
511
- generatedNames.set(dispatchToolName, { leader: leaderUsername, sub: "(dispatch)" });
512
- tools.push(createDispatchToolOptions(plugin, { leaderUsername, rulesBySubAgent }));
513
- }
514
- registeredDelegateNamesByPlugin.set(plugin, new Set(generatedNames.keys()));
515
- return tools;
44
+ function invalidateDelegateToolsCache() {
516
45
  }
517
46
  function createDelegateToolsProvider(plugin) {
518
- attachInvalidationHooks(plugin);
519
- return async (register) => {
520
- try {
521
- let toolsCache = toolsCacheByPlugin.get(plugin);
522
- if (!toolsCache || toolsCache.expiresAt <= Date.now()) {
523
- const tools = await buildDelegateTools(plugin);
524
- toolsCache = { tools, expiresAt: Date.now() + TOOLS_CACHE_TTL_MS };
525
- toolsCacheByPlugin.set(plugin, toolsCache);
526
- }
527
- if (toolsCache.tools.length) {
528
- register.registerTools(toolsCache.tools);
529
- }
530
- } catch (e) {
531
- plugin.app.log.error("[AgentOrchestrator] Failed to register delegate tools", e);
532
- }
47
+ return async () => {
48
+ var _a, _b, _c;
49
+ (_c = (_b = (_a = plugin.app) == null ? void 0 : _a.logger) == null ? void 0 : _b.info) == null ? void 0 : _c.call(
50
+ _b,
51
+ "[AgentOrchestrator] Legacy delegate_* tools are retired; native dispatch-sub-agent-task is used instead."
52
+ );
533
53
  };
534
54
  }
535
- function invalidateDelegateToolsCache() {
536
- toolsCacheByPlugin = /* @__PURE__ */ new WeakMap();
537
- registeredDelegateNamesByPlugin = /* @__PURE__ */ new WeakMap();
538
- }
539
- async function invokeDelegateTask(ctx, plugin, options) {
540
- const {
541
- leaderUsername,
542
- subAgentUsername,
543
- subAgentEmployee,
544
- task,
545
- context,
546
- maxDepth,
547
- timeout,
548
- toolCallId,
549
- toolName,
550
- llmService,
551
- model,
552
- recursionLimit,
553
- rootRunId: providedRootRunId,
554
- parentSpanId: providedParentSpanId
555
- } = options;
556
- const ctxSnapshot = (0, import_ctx_utils.captureCtxSnapshot)(ctx);
557
- const currentDepth = ctx[ORCHESTRATOR_DEPTH_KEY] ?? 0;
558
- const currentPath = ctx[ORCHESTRATOR_PATH_KEY] ?? [leaderUsername];
559
- if (currentPath.includes(subAgentUsername)) {
560
- const loopChain = [...currentPath, subAgentUsername].join(" -> ");
561
- await logDelegation(ctx, plugin, {
562
- leaderUsername,
563
- subAgentUsername,
564
- toolName,
565
- task,
566
- context,
567
- result: "",
568
- status: "error",
569
- depth: currentDepth,
570
- durationMs: 0,
571
- error: `Circular delegation detected: ${loopChain}.`,
572
- snapshot: ctxSnapshot
573
- });
574
- return {
575
- status: "error",
576
- content: `Circular delegation detected: ${loopChain}. Execution aborted to prevent infinite reasoning loops.`
577
- };
578
- }
579
- if (currentDepth >= maxDepth) {
580
- await logDelegation(ctx, plugin, {
581
- leaderUsername,
582
- subAgentUsername,
583
- toolName,
584
- task,
585
- context,
586
- result: "",
587
- status: "error",
588
- depth: currentDepth,
589
- durationMs: 0,
590
- error: `Delegation depth limit reached (${currentDepth}/${maxDepth}).`,
591
- snapshot: ctxSnapshot
592
- });
593
- return {
594
- status: "error",
595
- content: `Delegation depth limit reached (${currentDepth}/${maxDepth}). Sub-agent "${subAgentUsername}" cannot delegate further.`
596
- };
597
- }
598
- const upstreamTraceContext = (0, import_ExecutionSpanService.getOrchestratorTraceContext)(ctx);
599
- const rootRunId = providedRootRunId || (upstreamTraceContext == null ? void 0 : upstreamTraceContext.rootRunId) || createRootRunId(`${leaderUsername}:${subAgentUsername}`);
600
- const parentSpanId = providedParentSpanId || (upstreamTraceContext == null ? void 0 : upstreamTraceContext.spanId) || (upstreamTraceContext == null ? void 0 : upstreamTraceContext.parentSpanId);
601
- const agentLoopRunId = upstreamTraceContext == null ? void 0 : upstreamTraceContext.agentLoopRunId;
602
- const agentLoopStepId = upstreamTraceContext == null ? void 0 : upstreamTraceContext.agentLoopStepId;
603
- return plugin.agentLoopService.harness.runSubAgent(ctx, {
604
- leaderUsername,
605
- subAgentUsername,
606
- subAgentEmployee,
607
- task,
608
- context,
609
- currentDepth,
610
- currentPath,
611
- maxDepth,
612
- timeout,
613
- toolCallId,
614
- toolName,
615
- llmService,
616
- model,
617
- recursionLimit,
618
- rootRunId,
619
- parentSpanId,
620
- agentLoopRunId,
621
- agentLoopStepId
622
- });
623
- }
624
- async function logDelegation(ctx, plugin, data) {
625
- var _a, _b, _c, _d, _e;
626
- let userId = (_a = data.snapshot) == null ? void 0 : _a.userId;
627
- if (userId == null) {
628
- try {
629
- 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);
630
- } catch {
631
- }
632
- }
633
- return (0, import_logging.logDelegation)(ctx, plugin, { ...data, userId });
634
- }
635
55
  // Annotate the CommonJS export names for ESM import in node:
636
56
  0 && (module.exports = {
57
+ buildDelegateToolName,
58
+ buildDispatchToolName,
637
59
  createDelegateToolsProvider,
638
60
  invalidateDelegateToolsCache
639
61
  });
@@ -27,6 +27,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
27
27
  var skill_settings_exports = {};
28
28
  __export(skill_settings_exports, {
29
29
  isOrchestratorToolName: () => isOrchestratorToolName,
30
+ isRetiredOrchestratorToolName: () => isRetiredOrchestratorToolName,
30
31
  normalizeAIEmployeeSkillSettings: () => normalizeAIEmployeeSkillSettings
31
32
  });
32
33
  module.exports = __toCommonJS(skill_settings_exports);
@@ -34,7 +35,10 @@ function isRecord(value) {
34
35
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
35
36
  }
36
37
  function isOrchestratorToolName(name) {
37
- return name === "orchestrator_plan_goal" || name === "orchestrator_execute_plan" || name === "orchestrator_status" || name === "orchestrator_cancel" || name === "external_rag_search" || name === "skill_hub_execute" || name.startsWith("delegate_") || name.startsWith("dispatch_subagents_") || name.startsWith("skill_hub_") || name.startsWith("browser_") || name.startsWith("drawio-");
38
+ return name === "dispatch-sub-agent-task" || name === "external_rag_search" || name === "skill_hub_execute" || name.startsWith("skill_hub_") || name.startsWith("browser_") || name.startsWith("drawio-");
39
+ }
40
+ function isRetiredOrchestratorToolName(name) {
41
+ return name === "orchestrator_plan_goal" || name === "orchestrator_execute_plan" || name === "orchestrator_status" || name === "orchestrator_cancel" || name.startsWith("delegate_") || name.startsWith("dispatch_subagents_");
38
42
  }
39
43
  function toToolBinding(value) {
40
44
  if (typeof value === "string") {
@@ -69,6 +73,10 @@ function normalizeAIEmployeeSkillSettings(value) {
69
73
  for (const item of sourceTools) {
70
74
  const binding = toToolBinding(item);
71
75
  if (binding) {
76
+ if (isRetiredOrchestratorToolName(binding.name)) {
77
+ changed = true;
78
+ continue;
79
+ }
72
80
  addToolBinding(toolsByName, binding);
73
81
  if (typeof item === "string") {
74
82
  changed = true;
@@ -87,6 +95,10 @@ function normalizeAIEmployeeSkillSettings(value) {
87
95
  changed = true;
88
96
  continue;
89
97
  }
98
+ if (isRetiredOrchestratorToolName(name)) {
99
+ changed = true;
100
+ continue;
101
+ }
90
102
  if (isOrchestratorToolName(name)) {
91
103
  addToolBinding(toolsByName, { name, autoCall: false });
92
104
  changed = true;
@@ -100,6 +112,10 @@ function normalizeAIEmployeeSkillSettings(value) {
100
112
  }
101
113
  const legacyToolBinding = toToolBinding(item);
102
114
  if (legacyToolBinding) {
115
+ if (isRetiredOrchestratorToolName(legacyToolBinding.name)) {
116
+ changed = true;
117
+ continue;
118
+ }
103
119
  addToolBinding(toolsByName, legacyToolBinding);
104
120
  }
105
121
  changed = true;
@@ -118,5 +134,6 @@ function normalizeAIEmployeeSkillSettings(value) {
118
134
  // Annotate the CommonJS export names for ESM import in node:
119
135
  0 && (module.exports = {
120
136
  isOrchestratorToolName,
137
+ isRetiredOrchestratorToolName,
121
138
  normalizeAIEmployeeSkillSettings
122
139
  });