qlogicagent 0.2.1 → 0.3.0

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 (229) hide show
  1. package/dist/agent.js +1 -0
  2. package/dist/cli.js +9 -0
  3. package/dist/contracts.js +1 -0
  4. package/dist/index.js +5 -15
  5. package/dist/orchestration.js +118 -0
  6. package/package.json +56 -42
  7. package/dist/agent/agent.js +0 -113
  8. package/dist/agent/tool-loop.js +0 -575
  9. package/dist/agent/types.js +0 -14
  10. package/dist/cli/main.js +0 -23
  11. package/dist/cli/stdio-server.js +0 -463
  12. package/dist/config/config.js +0 -21
  13. package/dist/contracts/hooks.js +0 -7
  14. package/dist/contracts/index.js +0 -10
  15. package/dist/contracts/planner.js +0 -2
  16. package/dist/contracts/skill-candidate.js +0 -195
  17. package/dist/contracts/todo.js +0 -9
  18. package/dist/llm/builtin-providers.js +0 -531
  19. package/dist/llm/index.js +0 -14
  20. package/dist/llm/llm-client.js +0 -67
  21. package/dist/llm/model-catalog.js +0 -191
  22. package/dist/llm/provider-def.js +0 -12
  23. package/dist/llm/provider-registry.js +0 -147
  24. package/dist/llm/transport.js +0 -27
  25. package/dist/llm/transports/anthropic-messages.js +0 -293
  26. package/dist/llm/transports/openai-chat.js +0 -165
  27. package/dist/orchestration/agent-registry.js +0 -116
  28. package/dist/orchestration/approval-aware-tool-plan.js +0 -87
  29. package/dist/orchestration/context-compression.js +0 -583
  30. package/dist/orchestration/conversation-repair.js +0 -429
  31. package/dist/orchestration/curator-scheduler.js +0 -135
  32. package/dist/orchestration/embedded-failover-policy.js +0 -168
  33. package/dist/orchestration/error-classification.js +0 -77
  34. package/dist/orchestration/failover-classification.js +0 -381
  35. package/dist/orchestration/failover-error.js +0 -198
  36. package/dist/orchestration/fork-subagent.js +0 -98
  37. package/dist/orchestration/index.js +0 -267
  38. package/dist/orchestration/memory-flush-policy.js +0 -85
  39. package/dist/orchestration/memory-provider.js +0 -2
  40. package/dist/orchestration/parallel-tool-calls.js +0 -59
  41. package/dist/orchestration/prompt-cache-strategy.js +0 -228
  42. package/dist/orchestration/reactive-compact.js +0 -78
  43. package/dist/orchestration/retry-loop.js +0 -24
  44. package/dist/orchestration/skill-candidate.js +0 -141
  45. package/dist/orchestration/skill-consolidation.js +0 -220
  46. package/dist/orchestration/skill-improvement.js +0 -66
  47. package/dist/orchestration/skill-similarity.js +0 -131
  48. package/dist/orchestration/streaming-tool-executor.js +0 -96
  49. package/dist/orchestration/team-orchestration.js +0 -369
  50. package/dist/orchestration/team-tool-loop-wiring.js +0 -147
  51. package/dist/orchestration/tool-choice-policy.js +0 -164
  52. package/dist/orchestration/tool-loop-state.js +0 -133
  53. package/dist/orchestration/tool-schema.js +0 -297
  54. package/dist/orchestration/transcript-repair.js +0 -426
  55. package/dist/orchestration/turn-loop-guard.js +0 -92
  56. package/dist/orchestration/web-browser-policy.js +0 -39
  57. package/dist/runtime/context-compression.js +0 -274
  58. package/dist/runtime/hook-registry.js +0 -53
  59. package/dist/runtime/memory-hooks.js +0 -65
  60. package/dist/runtime/tool-eligibility.js +0 -111
  61. package/dist/skills/index.js +0 -82
  62. package/dist/skills/memory-extractor.js +0 -173
  63. package/dist/skills/memory-query-tool.js +0 -127
  64. package/dist/skills/memory-store.js +0 -228
  65. package/dist/skills/memory-tool.js +0 -192
  66. package/dist/skills/portable-tool.js +0 -14
  67. package/dist/skills/qmemory-adapter.js +0 -165
  68. package/dist/skills/skill-frontmatter.js +0 -344
  69. package/dist/skills/skill-guard.js +0 -229
  70. package/dist/skills/skill-loader.js +0 -303
  71. package/dist/skills/skill-source.js +0 -126
  72. package/dist/skills/skill-types.js +0 -6
  73. package/dist/skills/think-tool.js +0 -59
  74. package/dist/skills/todo-tool.js +0 -114
  75. package/dist/skills/tools/agent-tool.js +0 -142
  76. package/dist/skills/tools/apply-patch-tool.js +0 -184
  77. package/dist/skills/tools/ask-user-tool.js +0 -121
  78. package/dist/skills/tools/brief-tool.js +0 -95
  79. package/dist/skills/tools/browser-tool.js +0 -155
  80. package/dist/skills/tools/checkpoint-tool.js +0 -102
  81. package/dist/skills/tools/config-tool.js +0 -143
  82. package/dist/skills/tools/cron-tool.js +0 -175
  83. package/dist/skills/tools/edit-tool.js +0 -70
  84. package/dist/skills/tools/exec-tool.js +0 -133
  85. package/dist/skills/tools/image-generate-tool.js +0 -67
  86. package/dist/skills/tools/instructions-tool.js +0 -187
  87. package/dist/skills/tools/lsp-tool.js +0 -227
  88. package/dist/skills/tools/mcp-client-types.js +0 -53
  89. package/dist/skills/tools/mcp-tool.js +0 -503
  90. package/dist/skills/tools/memory-tool.js +0 -88
  91. package/dist/skills/tools/monitor-tool.js +0 -131
  92. package/dist/skills/tools/music-generate-tool.js +0 -62
  93. package/dist/skills/tools/notify-tool.js +0 -62
  94. package/dist/skills/tools/patch-tool.js +0 -505
  95. package/dist/skills/tools/pdf-tool.js +0 -88
  96. package/dist/skills/tools/plan-mode-tool.js +0 -122
  97. package/dist/skills/tools/read-tool.js +0 -84
  98. package/dist/skills/tools/repl-tool.js +0 -69
  99. package/dist/skills/tools/search-tool.js +0 -225
  100. package/dist/skills/tools/send-message-tool.js +0 -76
  101. package/dist/skills/tools/skill-list-tool.js +0 -54
  102. package/dist/skills/tools/skill-manage-tool.js +0 -153
  103. package/dist/skills/tools/skill-view-tool.js +0 -72
  104. package/dist/skills/tools/sleep-tool.js +0 -81
  105. package/dist/skills/tools/structured-output-tool.js +0 -176
  106. package/dist/skills/tools/task-tool.js +0 -161
  107. package/dist/skills/tools/team-tool.js +0 -105
  108. package/dist/skills/tools/tool-search-tool.js +0 -110
  109. package/dist/skills/tools/tts-tool.js +0 -45
  110. package/dist/skills/tools/video-edit-tool.js +0 -74
  111. package/dist/skills/tools/video-generate-tool.js +0 -66
  112. package/dist/skills/tools/video-merge-tool.js +0 -92
  113. package/dist/skills/tools/video-upscale-tool.js +0 -52
  114. package/dist/skills/tools/web-fetch-tool.js +0 -92
  115. package/dist/skills/tools/web-search-tool.js +0 -86
  116. package/dist/skills/tools/worktree-tool.js +0 -147
  117. package/dist/skills/tools/write-tool.js +0 -81
  118. /package/dist/{agent → types/agent}/agent.d.ts +0 -0
  119. /package/dist/{agent → types/agent}/tool-loop.d.ts +0 -0
  120. /package/dist/{agent → types/agent}/types.d.ts +0 -0
  121. /package/dist/{cli → types/cli}/main.d.ts +0 -0
  122. /package/dist/{cli → types/cli}/stdio-server.d.ts +0 -0
  123. /package/dist/{config → types/config}/config.d.ts +0 -0
  124. /package/dist/{contracts → types/contracts}/hooks.d.ts +0 -0
  125. /package/dist/{contracts → types/contracts}/index.d.ts +0 -0
  126. /package/dist/{contracts → types/contracts}/planner.d.ts +0 -0
  127. /package/dist/{contracts → types/contracts}/skill-candidate.d.ts +0 -0
  128. /package/dist/{contracts → types/contracts}/todo.d.ts +0 -0
  129. /package/dist/{index.d.ts → types/index.d.ts} +0 -0
  130. /package/dist/{llm → types/llm}/builtin-providers.d.ts +0 -0
  131. /package/dist/{llm → types/llm}/index.d.ts +0 -0
  132. /package/dist/{llm → types/llm}/llm-client.d.ts +0 -0
  133. /package/dist/{llm → types/llm}/model-catalog.d.ts +0 -0
  134. /package/dist/{llm → types/llm}/provider-def.d.ts +0 -0
  135. /package/dist/{llm → types/llm}/provider-registry.d.ts +0 -0
  136. /package/dist/{llm → types/llm}/transport.d.ts +0 -0
  137. /package/dist/{llm → types/llm}/transports/anthropic-messages.d.ts +0 -0
  138. /package/dist/{llm → types/llm}/transports/openai-chat.d.ts +0 -0
  139. /package/dist/{orchestration → types/orchestration}/agent-registry.d.ts +0 -0
  140. /package/dist/{orchestration → types/orchestration}/approval-aware-tool-plan.d.ts +0 -0
  141. /package/dist/{orchestration → types/orchestration}/context-compression.d.ts +0 -0
  142. /package/dist/{orchestration → types/orchestration}/conversation-repair.d.ts +0 -0
  143. /package/dist/{orchestration → types/orchestration}/curator-scheduler.d.ts +0 -0
  144. /package/dist/{orchestration → types/orchestration}/embedded-failover-policy.d.ts +0 -0
  145. /package/dist/{orchestration → types/orchestration}/error-classification.d.ts +0 -0
  146. /package/dist/{orchestration → types/orchestration}/failover-classification.d.ts +0 -0
  147. /package/dist/{orchestration → types/orchestration}/failover-error.d.ts +0 -0
  148. /package/dist/{orchestration → types/orchestration}/fork-subagent.d.ts +0 -0
  149. /package/dist/{orchestration → types/orchestration}/index.d.ts +0 -0
  150. /package/dist/{orchestration → types/orchestration}/memory-flush-policy.d.ts +0 -0
  151. /package/dist/{orchestration → types/orchestration}/memory-provider.d.ts +0 -0
  152. /package/dist/{orchestration → types/orchestration}/parallel-tool-calls.d.ts +0 -0
  153. /package/dist/{orchestration → types/orchestration}/prompt-cache-strategy.d.ts +0 -0
  154. /package/dist/{orchestration → types/orchestration}/reactive-compact.d.ts +0 -0
  155. /package/dist/{orchestration → types/orchestration}/retry-loop.d.ts +0 -0
  156. /package/dist/{orchestration → types/orchestration}/skill-candidate.d.ts +0 -0
  157. /package/dist/{orchestration → types/orchestration}/skill-consolidation.d.ts +0 -0
  158. /package/dist/{orchestration → types/orchestration}/skill-improvement.d.ts +0 -0
  159. /package/dist/{orchestration → types/orchestration}/skill-similarity.d.ts +0 -0
  160. /package/dist/{orchestration → types/orchestration}/streaming-tool-executor.d.ts +0 -0
  161. /package/dist/{orchestration → types/orchestration}/team-orchestration.d.ts +0 -0
  162. /package/dist/{orchestration → types/orchestration}/team-tool-loop-wiring.d.ts +0 -0
  163. /package/dist/{orchestration → types/orchestration}/tool-choice-policy.d.ts +0 -0
  164. /package/dist/{orchestration → types/orchestration}/tool-loop-state.d.ts +0 -0
  165. /package/dist/{orchestration → types/orchestration}/tool-schema.d.ts +0 -0
  166. /package/dist/{orchestration → types/orchestration}/transcript-repair.d.ts +0 -0
  167. /package/dist/{orchestration → types/orchestration}/turn-loop-guard.d.ts +0 -0
  168. /package/dist/{orchestration → types/orchestration}/web-browser-policy.d.ts +0 -0
  169. /package/dist/{runtime → types/runtime}/context-compression.d.ts +0 -0
  170. /package/dist/{runtime → types/runtime}/hook-registry.d.ts +0 -0
  171. /package/dist/{runtime → types/runtime}/memory-hooks.d.ts +0 -0
  172. /package/dist/{runtime → types/runtime}/tool-eligibility.d.ts +0 -0
  173. /package/dist/{skills → types/skills}/index.d.ts +0 -0
  174. /package/dist/{skills → types/skills}/memory-extractor.d.ts +0 -0
  175. /package/dist/{skills → types/skills}/memory-query-tool.d.ts +0 -0
  176. /package/dist/{skills → types/skills}/memory-store.d.ts +0 -0
  177. /package/dist/{skills → types/skills}/memory-tool.d.ts +0 -0
  178. /package/dist/{skills → types/skills}/portable-tool.d.ts +0 -0
  179. /package/dist/{skills → types/skills}/qmemory-adapter.d.ts +0 -0
  180. /package/dist/{skills → types/skills}/skill-frontmatter.d.ts +0 -0
  181. /package/dist/{skills → types/skills}/skill-guard.d.ts +0 -0
  182. /package/dist/{skills → types/skills}/skill-loader.d.ts +0 -0
  183. /package/dist/{skills → types/skills}/skill-source.d.ts +0 -0
  184. /package/dist/{skills → types/skills}/skill-types.d.ts +0 -0
  185. /package/dist/{skills → types/skills}/think-tool.d.ts +0 -0
  186. /package/dist/{skills → types/skills}/todo-tool.d.ts +0 -0
  187. /package/dist/{skills → types/skills}/tools/agent-tool.d.ts +0 -0
  188. /package/dist/{skills → types/skills}/tools/apply-patch-tool.d.ts +0 -0
  189. /package/dist/{skills → types/skills}/tools/ask-user-tool.d.ts +0 -0
  190. /package/dist/{skills → types/skills}/tools/brief-tool.d.ts +0 -0
  191. /package/dist/{skills → types/skills}/tools/browser-tool.d.ts +0 -0
  192. /package/dist/{skills → types/skills}/tools/checkpoint-tool.d.ts +0 -0
  193. /package/dist/{skills → types/skills}/tools/config-tool.d.ts +0 -0
  194. /package/dist/{skills → types/skills}/tools/cron-tool.d.ts +0 -0
  195. /package/dist/{skills → types/skills}/tools/edit-tool.d.ts +0 -0
  196. /package/dist/{skills → types/skills}/tools/exec-tool.d.ts +0 -0
  197. /package/dist/{skills → types/skills}/tools/image-generate-tool.d.ts +0 -0
  198. /package/dist/{skills → types/skills}/tools/instructions-tool.d.ts +0 -0
  199. /package/dist/{skills → types/skills}/tools/lsp-tool.d.ts +0 -0
  200. /package/dist/{skills → types/skills}/tools/mcp-client-types.d.ts +0 -0
  201. /package/dist/{skills → types/skills}/tools/mcp-tool.d.ts +0 -0
  202. /package/dist/{skills → types/skills}/tools/memory-tool.d.ts +0 -0
  203. /package/dist/{skills → types/skills}/tools/monitor-tool.d.ts +0 -0
  204. /package/dist/{skills → types/skills}/tools/music-generate-tool.d.ts +0 -0
  205. /package/dist/{skills → types/skills}/tools/notify-tool.d.ts +0 -0
  206. /package/dist/{skills → types/skills}/tools/patch-tool.d.ts +0 -0
  207. /package/dist/{skills → types/skills}/tools/pdf-tool.d.ts +0 -0
  208. /package/dist/{skills → types/skills}/tools/plan-mode-tool.d.ts +0 -0
  209. /package/dist/{skills → types/skills}/tools/read-tool.d.ts +0 -0
  210. /package/dist/{skills → types/skills}/tools/repl-tool.d.ts +0 -0
  211. /package/dist/{skills → types/skills}/tools/search-tool.d.ts +0 -0
  212. /package/dist/{skills → types/skills}/tools/send-message-tool.d.ts +0 -0
  213. /package/dist/{skills → types/skills}/tools/skill-list-tool.d.ts +0 -0
  214. /package/dist/{skills → types/skills}/tools/skill-manage-tool.d.ts +0 -0
  215. /package/dist/{skills → types/skills}/tools/skill-view-tool.d.ts +0 -0
  216. /package/dist/{skills → types/skills}/tools/sleep-tool.d.ts +0 -0
  217. /package/dist/{skills → types/skills}/tools/structured-output-tool.d.ts +0 -0
  218. /package/dist/{skills → types/skills}/tools/task-tool.d.ts +0 -0
  219. /package/dist/{skills → types/skills}/tools/team-tool.d.ts +0 -0
  220. /package/dist/{skills → types/skills}/tools/tool-search-tool.d.ts +0 -0
  221. /package/dist/{skills → types/skills}/tools/tts-tool.d.ts +0 -0
  222. /package/dist/{skills → types/skills}/tools/video-edit-tool.d.ts +0 -0
  223. /package/dist/{skills → types/skills}/tools/video-generate-tool.d.ts +0 -0
  224. /package/dist/{skills → types/skills}/tools/video-merge-tool.d.ts +0 -0
  225. /package/dist/{skills → types/skills}/tools/video-upscale-tool.d.ts +0 -0
  226. /package/dist/{skills → types/skills}/tools/web-fetch-tool.d.ts +0 -0
  227. /package/dist/{skills → types/skills}/tools/web-search-tool.d.ts +0 -0
  228. /package/dist/{skills → types/skills}/tools/worktree-tool.d.ts +0 -0
  229. /package/dist/{skills → types/skills}/tools/write-tool.d.ts +0 -0
@@ -1,369 +0,0 @@
1
- /**
2
- * Team Orchestration Strategy — multi-agent coordination layer.
3
- *
4
- * Extends the existing sidechain foundation with team/swarm semantics:
5
- * - Parallel agent spawning (multiple sidechains at once)
6
- * - Role-based agent assignment (planner / executor / reviewer)
7
- * - Shared knowledge pool via merge policies
8
- * - Budget-aware concurrency limits
9
- * - Lifecycle state machine for team coordination
10
- *
11
- * Architecture:
12
- * Gateway ─── Hub ─── orchestration (this module, pure strategy)
13
- * │
14
- * ┌───────────┼───────────┐
15
- * │ TeamCoordinator │ ← Hub runtime (multi-sidechain-coordinator.ts)
16
- * │ │ │
17
- * │ ├── Agent #1 (planner)
18
- * │ ├── Agent #2 (executor)
19
- * │ └── Agent #3 (reviewer)
20
- * └───────────────────────┘
21
- *
22
- * This module provides:
23
- * 1. Type definitions (TeamPlan, AgentRole, TeamLifecycle)
24
- * 2. Pure strategy functions (plan resolution, role assignment, budget allocation)
25
- * 3. Merge/aggregation policies (how agent results combine)
26
- *
27
- * Hub consumes these types and strategy functions in its coordinator runtime.
28
- * Gateway consumes TeamPlan to spawn/manage multiple sidechain executions.
29
- */
30
- // ---------------------------------------------------------------------------
31
- // Strategy Functions — Pure, no I/O
32
- // ---------------------------------------------------------------------------
33
- /** Budget allocation weights per role (relative). */
34
- const ROLE_BUDGET_WEIGHTS = {
35
- planner: 3,
36
- executor: 4,
37
- reviewer: 2,
38
- researcher: 3,
39
- custom: 2,
40
- };
41
- /** Default concurrency limits by execution mode. */
42
- const MODE_CONCURRENCY_DEFAULTS = {
43
- parallel: 4,
44
- sequential: 1,
45
- pipeline: 1,
46
- adaptive: 3,
47
- };
48
- /** Maximum agents allowed in a team (safety bound). */
49
- export const TEAM_MAX_AGENTS = 8;
50
- /** Maximum recursion depth (teams spawning teams). */
51
- export const TEAM_MAX_DEPTH = 2;
52
- /**
53
- * Resolve a team plan from a high-level task decomposition.
54
- *
55
- * This is the main entry point: given a set of subtasks and constraints,
56
- * produce a concrete TeamPlan that the coordinator can execute.
57
- */
58
- export function resolveTeamPlan(params) {
59
- const agents = params.subtasks.slice(0, TEAM_MAX_AGENTS).map((sub) => {
60
- const budgetTier = resolveAgentBudgetTier(sub.role);
61
- return {
62
- agentId: sub.id,
63
- role: sub.role,
64
- label: sub.label,
65
- sidechainType: mapRoleToSidechainType(sub.role),
66
- taskDescription: sub.task,
67
- toolAccessMode: resolveAgentToolAccess(sub.role),
68
- budgetTier,
69
- dependsOn: sub.dependsOn ?? [],
70
- maxTokenBudget: 0, // Will be allocated below
71
- maxToolCalls: resolveMaxToolCalls(sub.role),
72
- timeoutMs: 0,
73
- };
74
- });
75
- const mode = params.mode ?? inferExecutionMode(agents);
76
- const totalBudget = params.totalTokenBudget ?? 100_000;
77
- const allocatedAgents = allocateTokenBudgets(agents, totalBudget);
78
- return {
79
- teamId: params.teamId,
80
- mode,
81
- aggregationPolicy: params.aggregationPolicy ?? inferAggregationPolicy(mode, agents),
82
- agents: allocatedAgents,
83
- maxConcurrency: MODE_CONCURRENCY_DEFAULTS[mode],
84
- timeoutMs: params.timeoutMs ?? 300_000, // 5 min default
85
- totalTokenBudget: totalBudget,
86
- failFast: params.failFast ?? (mode === "pipeline"),
87
- sharedContext: params.sharedContext ?? "",
88
- mergePolicy: params.mergePolicy ?? "summary-only",
89
- };
90
- }
91
- /**
92
- * Map agent role to sidechain type for existing Hub plumbing compatibility.
93
- */
94
- export function mapRoleToSidechainType(role) {
95
- switch (role) {
96
- case "planner": return "planner";
97
- case "executor": return "code-repair";
98
- case "reviewer": return "research";
99
- case "researcher": return "research";
100
- case "custom": return "research";
101
- }
102
- }
103
- /**
104
- * Resolve tool access mode for a given role.
105
- */
106
- export function resolveAgentToolAccess(role) {
107
- switch (role) {
108
- case "planner": return "none"; // Planner thinks, doesn't act
109
- case "executor": return "full"; // Executor needs full tool access
110
- case "reviewer": return "read-only"; // Reviewer inspects, doesn't modify
111
- case "researcher": return "read-only";
112
- case "custom": return "read-only";
113
- }
114
- }
115
- /**
116
- * Resolve maximum tool calls for a given role.
117
- */
118
- function resolveMaxToolCalls(role) {
119
- switch (role) {
120
- case "planner": return 0;
121
- case "executor": return 30;
122
- case "reviewer": return 10;
123
- case "researcher": return 15;
124
- case "custom": return 10;
125
- }
126
- }
127
- /**
128
- * Resolve budget tier for a given role.
129
- */
130
- function resolveAgentBudgetTier(role) {
131
- switch (role) {
132
- case "planner": return "high";
133
- case "executor": return "high";
134
- case "reviewer": return "medium";
135
- case "researcher": return "medium";
136
- case "custom": return "low";
137
- }
138
- }
139
- /**
140
- * Allocate token budgets proportionally by role weight.
141
- */
142
- export function allocateTokenBudgets(agents, totalBudget) {
143
- const totalWeight = agents.reduce((sum, a) => sum + ROLE_BUDGET_WEIGHTS[a.role], 0);
144
- if (totalWeight === 0)
145
- return agents;
146
- return agents.map((agent) => ({
147
- ...agent,
148
- maxTokenBudget: Math.floor((ROLE_BUDGET_WEIGHTS[agent.role] / totalWeight) * totalBudget),
149
- }));
150
- }
151
- /**
152
- * Infer execution mode from agent dependency graph.
153
- */
154
- export function inferExecutionMode(agents) {
155
- const hasDeps = agents.some((a) => a.dependsOn.length > 0);
156
- if (!hasDeps)
157
- return "parallel";
158
- // If every agent depends on the previous → pipeline
159
- const isLinearChain = agents.every((a, i) => i === 0 ? a.dependsOn.length === 0 : a.dependsOn.includes(agents[i - 1].agentId));
160
- if (isLinearChain)
161
- return "pipeline";
162
- return "sequential";
163
- }
164
- /**
165
- * Infer aggregation policy from mode and agent composition.
166
- */
167
- export function inferAggregationPolicy(mode, agents) {
168
- const hasReviewer = agents.some((a) => a.role === "reviewer");
169
- const hasPlanner = agents.some((a) => a.role === "planner");
170
- if (hasReviewer)
171
- return "reviewer-gate";
172
- if (hasPlanner && mode === "adaptive")
173
- return "planner-sync";
174
- if (mode === "parallel" && agents.length >= 3)
175
- return "majority-vote";
176
- return "merge-all";
177
- }
178
- /**
179
- * Determine the execution order for agents given their dependency graph.
180
- * Returns groups of agent IDs that can execute concurrently.
181
- *
182
- * Example: [[planner], [executor-a, executor-b], [reviewer]]
183
- */
184
- export function resolveExecutionOrder(agents) {
185
- const idSet = new Set(agents.map((a) => a.agentId));
186
- const depMap = new Map(agents.map((a) => [a.agentId, a.dependsOn.filter((d) => idSet.has(d))]));
187
- const completed = new Set();
188
- const groups = [];
189
- let remaining = new Set(idSet);
190
- let iterations = 0;
191
- const maxIterations = agents.length + 1;
192
- while (remaining.size > 0 && iterations < maxIterations) {
193
- const ready = [];
194
- for (const id of remaining) {
195
- const deps = depMap.get(id) ?? [];
196
- if (deps.every((d) => completed.has(d))) {
197
- ready.push(id);
198
- }
199
- }
200
- if (ready.length === 0) {
201
- // Circular dependency — break by picking first remaining
202
- const first = remaining.values().next().value;
203
- if (first)
204
- ready.push(first);
205
- }
206
- for (const id of ready) {
207
- remaining.delete(id);
208
- completed.add(id);
209
- }
210
- groups.push(ready);
211
- iterations++;
212
- }
213
- return groups;
214
- }
215
- /**
216
- * Aggregate team results into a single output string.
217
- */
218
- export function aggregateTeamResults(results, policy) {
219
- const completed = results.filter((r) => r.status === "completed");
220
- switch (policy) {
221
- case "first-success":
222
- return completed[0]?.output ?? "[No successful agent output]";
223
- case "majority-vote":
224
- // Simple: return the most common non-empty output
225
- if (completed.length === 0)
226
- return "[No successful agent output]";
227
- const counts = new Map();
228
- for (const r of completed) {
229
- const key = r.output.trim();
230
- counts.set(key, (counts.get(key) ?? 0) + 1);
231
- }
232
- let best = "";
233
- let bestCount = 0;
234
- for (const [output, count] of counts) {
235
- if (count > bestCount) {
236
- best = output;
237
- bestCount = count;
238
- }
239
- }
240
- return best || completed[0].output;
241
- case "merge-all":
242
- return completed
243
- .map((r) => `[${r.role}:${r.agentId}]\n${r.output}`)
244
- .join("\n\n---\n\n");
245
- case "reviewer-gate": {
246
- const reviewer = completed.find((r) => r.role === "reviewer");
247
- const executors = completed.filter((r) => r.role !== "reviewer");
248
- if (reviewer) {
249
- return `[Review]\n${reviewer.output}\n\n[Execution]\n${executors.map((e) => e.output).join("\n")}`;
250
- }
251
- return executors.map((e) => e.output).join("\n\n");
252
- }
253
- case "planner-sync": {
254
- const planner = completed.find((r) => r.role === "planner");
255
- const others = completed.filter((r) => r.role !== "planner");
256
- if (planner) {
257
- return `[Plan]\n${planner.output}\n\n[Results]\n${others.map((o) => `- ${o.agentId}: ${o.output.slice(0, 500)}`).join("\n")}`;
258
- }
259
- return others.map((o) => o.output).join("\n\n");
260
- }
261
- }
262
- }
263
- /**
264
- * Validate a team plan before execution.
265
- * Returns a list of issues (empty = valid).
266
- */
267
- export function validateTeamPlan(plan) {
268
- const issues = [];
269
- if (plan.agents.length === 0) {
270
- issues.push("Team plan has no agents");
271
- }
272
- if (plan.agents.length > TEAM_MAX_AGENTS) {
273
- issues.push(`Too many agents: ${plan.agents.length} > ${TEAM_MAX_AGENTS}`);
274
- }
275
- if (plan.totalTokenBudget <= 0) {
276
- issues.push("Total token budget must be positive");
277
- }
278
- // Check for duplicate IDs
279
- const ids = plan.agents.map((a) => a.agentId);
280
- const uniqueIds = new Set(ids);
281
- if (uniqueIds.size !== ids.length) {
282
- issues.push("Duplicate agent IDs in team plan");
283
- }
284
- // Check dependency references
285
- for (const agent of plan.agents) {
286
- for (const dep of agent.dependsOn) {
287
- if (!uniqueIds.has(dep)) {
288
- issues.push(`Agent "${agent.agentId}" depends on non-existent agent "${dep}"`);
289
- }
290
- if (dep === agent.agentId) {
291
- issues.push(`Agent "${agent.agentId}" depends on itself`);
292
- }
293
- }
294
- }
295
- // Pipeline mode must have linear dependencies
296
- if (plan.mode === "pipeline") {
297
- for (let i = 1; i < plan.agents.length; i++) {
298
- if (!plan.agents[i].dependsOn.includes(plan.agents[i - 1].agentId)) {
299
- issues.push(`Pipeline mode requires linear dependencies; agent "${plan.agents[i].agentId}" doesn't depend on previous`);
300
- }
301
- }
302
- }
303
- return issues;
304
- }
305
- /**
306
- * Determine if a team execution should be cancelled early based on current state.
307
- */
308
- export function shouldCancelTeam(params) {
309
- const { plan, results, elapsedMs } = params;
310
- // Timeout check
311
- if (plan.timeoutMs > 0 && elapsedMs > plan.timeoutMs) {
312
- return { cancel: true, reason: "team_timeout" };
313
- }
314
- // Fail-fast: any failure causes cancel
315
- if (plan.failFast && results.some((r) => r.status === "failed")) {
316
- return { cancel: true, reason: "fail_fast" };
317
- }
318
- // All agents completed or failed — no need to cancel, just aggregate
319
- if (results.length >= plan.agents.length) {
320
- return { cancel: false, reason: "" };
321
- }
322
- // Budget exhaustion
323
- const usedTokens = results.reduce((sum, r) => sum + r.tokenUsage.prompt + r.tokenUsage.completion, 0);
324
- if (usedTokens >= plan.totalTokenBudget * 0.95) {
325
- return { cancel: true, reason: "budget_exhausted" };
326
- }
327
- return { cancel: false, reason: "" };
328
- }
329
- /**
330
- * Build the task prompt for a specific agent, incorporating shared context
331
- * and outputs from dependency agents.
332
- */
333
- export function buildAgentTaskPrompt(params) {
334
- const { agent, plan, dependencyResults } = params;
335
- const parts = [];
336
- // Shared context
337
- if (plan.sharedContext) {
338
- parts.push(`[Shared Context]\n${plan.sharedContext}`);
339
- }
340
- // Dependency outputs
341
- if (dependencyResults.length > 0) {
342
- const depSection = dependencyResults
343
- .filter((r) => r.status === "completed")
344
- .map((r) => `[From ${r.agentId} (${r.role})]\n${r.output}`)
345
- .join("\n\n");
346
- if (depSection) {
347
- parts.push(`[Prior Results]\n${depSection}`);
348
- }
349
- }
350
- // Agent-specific task
351
- parts.push(`[Your Task]\n${agent.taskDescription}`);
352
- // Role-specific guidance
353
- parts.push(`[Your Role: ${agent.role}]\n${getRoleGuidance(agent.role)}`);
354
- return parts.join("\n\n---\n\n");
355
- }
356
- function getRoleGuidance(role) {
357
- switch (role) {
358
- case "planner":
359
- return "You are the planner. Break down the task, identify dependencies, and create a clear execution plan. Do NOT execute actions yourself.";
360
- case "executor":
361
- return "You are the executor. Follow the plan and use tools to accomplish the task. Report what you did and any issues encountered.";
362
- case "reviewer":
363
- return "You are the reviewer. Examine the execution results for correctness, completeness, and quality. Point out any issues or improvements needed.";
364
- case "researcher":
365
- return "You are the researcher. Gather information, search for relevant context, and provide evidence-based findings. Do NOT modify any files.";
366
- case "custom":
367
- return "Complete the assigned task to the best of your ability.";
368
- }
369
- }
@@ -1,147 +0,0 @@
1
- /**
2
- * Team Tool Loop Wiring — Connects team orchestration to the tool loop.
3
- *
4
- * When the LLM invokes `team_create`, this module:
5
- * 1. Validates the team plan
6
- * 2. Maps team agents to fork contexts
7
- * 3. Coordinates execution according to the team execution mode
8
- * 4. Aggregates results according to the aggregation policy
9
- * 5. Returns the aggregated result as a tool_result
10
- *
11
- * This bridges the gap between the pure strategy layer (team-orchestration.ts)
12
- * and the Hub's tool loop.
13
- */
14
- /**
15
- * Resolve the execution plan for a team request.
16
- * Validates the request, resolves dependencies into ordered batches,
17
- * and determines the execution topology.
18
- */
19
- export function resolveTeamExecutionPlan(request) {
20
- const agents = request.agents;
21
- if (agents.length === 0) {
22
- return { batches: [], totalBudget: 0, state: "planning" };
23
- }
24
- if (agents.length > 8) {
25
- throw new Error(`Team cannot have more than 8 agents (got ${agents.length})`);
26
- }
27
- // For "parallel" mode — single batch with all agents
28
- if (request.mode === "parallel") {
29
- return {
30
- batches: [{ agents, mode: "parallel" }],
31
- totalBudget: agents.length * 50000,
32
- state: "spawning",
33
- };
34
- }
35
- // For "sequential" or "pipeline" — one agent per batch
36
- if (request.mode === "sequential" || request.mode === "pipeline") {
37
- return {
38
- batches: agents.map((a) => ({ agents: [a], mode: "serial" })),
39
- totalBudget: agents.length * 50000,
40
- state: "spawning",
41
- };
42
- }
43
- // "adaptive" — planner first, then remaining in parallel
44
- const planners = agents.filter((a) => a.role === "planner");
45
- const rest = agents.filter((a) => a.role !== "planner");
46
- const batches = [];
47
- if (planners.length > 0) {
48
- batches.push({ agents: planners, mode: "serial" });
49
- }
50
- if (rest.length > 0) {
51
- batches.push({ agents: rest, mode: "parallel" });
52
- }
53
- return {
54
- batches,
55
- totalBudget: agents.length * 50000,
56
- state: "spawning",
57
- };
58
- }
59
- /**
60
- * Aggregate results from team agents according to the aggregation policy.
61
- */
62
- export function aggregateTeamToolResults(results, policy) {
63
- const totalTokens = results.reduce((sum, r) => sum + r.result.tokensUsed, 0);
64
- const allOk = results.every((r) => r.result.ok);
65
- const anyOk = results.some((r) => r.result.ok);
66
- switch (policy) {
67
- case "first-success": {
68
- const first = results.find((r) => r.result.ok);
69
- return {
70
- ok: !!first,
71
- output: first?.result.output || "(No agent succeeded)",
72
- agentResults: results,
73
- totalTokensUsed: totalTokens,
74
- finalState: first ? "completed" : "failed",
75
- };
76
- }
77
- case "merge-all": {
78
- const outputs = results.map((r) => `### ${r.role} (${r.agentId})\n${r.result.output || "(no output)"}`);
79
- return {
80
- ok: anyOk,
81
- output: outputs.join("\n\n---\n\n"),
82
- agentResults: results,
83
- totalTokensUsed: totalTokens,
84
- finalState: anyOk ? "completed" : "failed",
85
- };
86
- }
87
- case "reviewer-gate": {
88
- const reviewer = results.find((r) => r.role === "reviewer");
89
- const executors = results.filter((r) => r.role !== "reviewer");
90
- const executorOutput = executors.map((r) => r.result.output).filter(Boolean).join("\n\n");
91
- if (reviewer && reviewer.result.ok) {
92
- return {
93
- ok: true,
94
- output: `## Reviewed Output\n${executorOutput}\n\n## Review\n${reviewer.result.output}`,
95
- agentResults: results,
96
- totalTokensUsed: totalTokens,
97
- finalState: "completed",
98
- };
99
- }
100
- return {
101
- ok: false,
102
- output: `Review failed: ${reviewer?.result.output || "no reviewer result"}`,
103
- agentResults: results,
104
- totalTokensUsed: totalTokens,
105
- finalState: "failed",
106
- };
107
- }
108
- case "planner-sync": {
109
- // Planner agent's output is the consolidated result
110
- const planner = results.find((r) => r.role === "planner");
111
- if (planner) {
112
- return {
113
- ok: planner.result.ok,
114
- output: planner.result.output,
115
- agentResults: results,
116
- totalTokensUsed: totalTokens,
117
- finalState: planner.result.ok ? "completed" : "failed",
118
- };
119
- }
120
- // Fallback to merge-all
121
- return aggregateTeamToolResults(results, "merge-all");
122
- }
123
- case "majority-vote":
124
- default: {
125
- // Simple: all outputs merged
126
- return aggregateTeamToolResults(results, "merge-all");
127
- }
128
- }
129
- }
130
- /**
131
- * Map a team tool_call into the format needed for the tool loop to dispatch.
132
- * Returns the list of fork configs the tool loop should execute.
133
- */
134
- export function mapTeamRequestToForkConfigs(request, agentRegistry) {
135
- return request.agents.map((agent) => {
136
- const def = agentRegistry(agent.agentType);
137
- if (!def) {
138
- throw new Error(`Unknown agent type "${agent.agentType}" in team request`);
139
- }
140
- return {
141
- agentDef: def,
142
- prompt: agent.prompt,
143
- maxTurns: agent.maxTurns,
144
- role: agent.role,
145
- };
146
- });
147
- }
@@ -1,164 +0,0 @@
1
- function resolveToolName(tool) {
2
- if (tool.function && typeof tool.function === "object" && typeof tool.function.name === "string") {
3
- return tool.function.name.trim();
4
- }
5
- if (typeof tool.name === "string") {
6
- return tool.name.trim();
7
- }
8
- return "";
9
- }
10
- function isEligibleStatus(status) {
11
- return status === "enabled-eligible" || status === "installed-awaiting-approval";
12
- }
13
- function buildEligibilityMap(eligibility) {
14
- return new Map((eligibility ?? []).map((entry) => [entry.toolName, entry]));
15
- }
16
- export function filterEligibleTools(params) {
17
- if (!params.eligibility?.length) {
18
- return [...params.tools];
19
- }
20
- const eligibilityMap = buildEligibilityMap(params.eligibility);
21
- return params.tools.filter((tool) => {
22
- const name = resolveToolName(tool);
23
- if (!name) {
24
- return false;
25
- }
26
- const eligibility = eligibilityMap.get(name);
27
- return !eligibility || isEligibleStatus(eligibility.status);
28
- });
29
- }
30
- export function normalizeAnthropicFunctionToolDefinition(tool) {
31
- if (!tool || typeof tool !== "object" || Array.isArray(tool)) {
32
- return undefined;
33
- }
34
- const toolRecord = tool;
35
- if (toolRecord.function && typeof toolRecord.function === "object") {
36
- return toolRecord;
37
- }
38
- const name = typeof toolRecord.name === "string" ? toolRecord.name.trim() : "";
39
- if (!name) {
40
- return toolRecord;
41
- }
42
- const functionSpec = {
43
- name,
44
- parameters: toolRecord.input_schema && typeof toolRecord.input_schema === "object"
45
- ? toolRecord.input_schema
46
- : toolRecord.parameters && typeof toolRecord.parameters === "object"
47
- ? toolRecord.parameters
48
- : { type: "object", properties: {} },
49
- };
50
- if (typeof toolRecord.description === "string" && toolRecord.description.trim()) {
51
- functionSpec.description = toolRecord.description;
52
- }
53
- if (typeof toolRecord.strict === "boolean") {
54
- functionSpec.strict = toolRecord.strict;
55
- }
56
- return {
57
- type: "function",
58
- function: functionSpec,
59
- };
60
- }
61
- export function normalizeAnthropicToolChoice(toolChoice) {
62
- if (!toolChoice || typeof toolChoice !== "object" || Array.isArray(toolChoice)) {
63
- return toolChoice;
64
- }
65
- const choice = toolChoice;
66
- if (choice.type === "auto") {
67
- return "auto";
68
- }
69
- if (choice.type === "none") {
70
- return "none";
71
- }
72
- if (choice.type === "required" || choice.type === "any") {
73
- return "required";
74
- }
75
- if (choice.type === "tool" && typeof choice.name === "string" && choice.name.trim()) {
76
- return {
77
- type: "function",
78
- function: { name: choice.name.trim() },
79
- };
80
- }
81
- return toolChoice;
82
- }
83
- export function applyToolChoiceCompatibility(params) {
84
- const warnings = [];
85
- const compatibility = params.compatibility ?? {};
86
- let normalizedToolChoice = params.toolChoice;
87
- if (params.thinkingEnabled && compatibility.requireAutoWhenThinking) {
88
- const type = typeof normalizedToolChoice === "object" && normalizedToolChoice && !Array.isArray(normalizedToolChoice)
89
- ? String(normalizedToolChoice.type ?? "")
90
- : normalizedToolChoice;
91
- if (type && type !== "auto" && type !== "none") {
92
- warnings.push("tool_choice downgraded to auto because thinking mode requires auto/none compatibility.");
93
- normalizedToolChoice = "auto";
94
- }
95
- }
96
- if (normalizedToolChoice === "required" && compatibility.allowRequiredToolChoice === false) {
97
- const fallback = compatibility.requiredFallback ?? "auto";
98
- warnings.push(`tool_choice=required is not supported by this provider; downgraded to ${fallback}.`);
99
- normalizedToolChoice = fallback;
100
- }
101
- if (normalizedToolChoice
102
- && typeof normalizedToolChoice === "object"
103
- && !Array.isArray(normalizedToolChoice)
104
- && normalizedToolChoice.type === "function"
105
- && compatibility.allowNamedToolChoice === false) {
106
- const fallback = compatibility.namedFallback ?? "required";
107
- warnings.push(`named tool_choice is not supported by this provider; downgraded to ${fallback}.`);
108
- normalizedToolChoice = fallback;
109
- }
110
- return { normalizedToolChoice, warnings };
111
- }
112
- export function applyToolChoicePolicy(params) {
113
- const compatibilityResult = applyToolChoiceCompatibility({
114
- toolChoice: params.toolChoice,
115
- thinkingEnabled: params.thinkingEnabled,
116
- compatibility: params.compatibility,
117
- });
118
- const toolChoice = compatibilityResult.normalizedToolChoice;
119
- const warnings = [...compatibilityResult.warnings];
120
- const tools = filterEligibleTools({
121
- tools: params.tools,
122
- eligibility: params.eligibility,
123
- });
124
- if (!toolChoice || toolChoice === "auto") {
125
- return { tools, normalizedToolChoice: toolChoice, warnings };
126
- }
127
- if (toolChoice === "none") {
128
- return { tools: [], normalizedToolChoice: "none", warnings };
129
- }
130
- if (toolChoice === "required") {
131
- if (tools.length === 0) {
132
- throw new Error("tool_choice=required but no tools were provided");
133
- }
134
- return {
135
- tools,
136
- normalizedToolChoice: "required",
137
- extraSystemPrompt: "You must call one of the available tools before responding.",
138
- warnings,
139
- };
140
- }
141
- if (typeof toolChoice === "object" && !Array.isArray(toolChoice) && toolChoice.type === "function") {
142
- const functionChoice = (toolChoice.function ?? undefined);
143
- const targetName = typeof functionChoice?.name === "string"
144
- ? functionChoice.name.trim()
145
- : "";
146
- if (!targetName) {
147
- throw new Error("tool_choice.function.name is required");
148
- }
149
- const matchedTools = tools.filter((tool) => resolveToolName(tool) === targetName);
150
- if (matchedTools.length === 0) {
151
- throw new Error(`tool_choice requested unknown tool: ${targetName}`);
152
- }
153
- return {
154
- tools: matchedTools,
155
- normalizedToolChoice: {
156
- type: "function",
157
- function: { name: targetName },
158
- },
159
- extraSystemPrompt: `You must call the ${targetName} tool before responding.`,
160
- warnings,
161
- };
162
- }
163
- return { tools, normalizedToolChoice: toolChoice, warnings };
164
- }