attocode 0.2.0 → 0.2.2

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 (179) hide show
  1. package/CHANGELOG.md +111 -1
  2. package/README.md +7 -0
  3. package/dist/src/adapters.d.ts +6 -1
  4. package/dist/src/adapters.d.ts.map +1 -1
  5. package/dist/src/adapters.js +14 -1
  6. package/dist/src/adapters.js.map +1 -1
  7. package/dist/src/agent.d.ts +50 -0
  8. package/dist/src/agent.d.ts.map +1 -1
  9. package/dist/src/agent.js +734 -316
  10. package/dist/src/agent.js.map +1 -1
  11. package/dist/src/defaults.d.ts +1 -1
  12. package/dist/src/defaults.d.ts.map +1 -1
  13. package/dist/src/defaults.js +2 -0
  14. package/dist/src/defaults.js.map +1 -1
  15. package/dist/src/integrations/agent-registry.d.ts +9 -2
  16. package/dist/src/integrations/agent-registry.d.ts.map +1 -1
  17. package/dist/src/integrations/agent-registry.js +30 -4
  18. package/dist/src/integrations/agent-registry.js.map +1 -1
  19. package/dist/src/integrations/async-subagent.d.ts +135 -0
  20. package/dist/src/integrations/async-subagent.d.ts.map +1 -0
  21. package/dist/src/integrations/async-subagent.js +213 -0
  22. package/dist/src/integrations/async-subagent.js.map +1 -0
  23. package/dist/src/integrations/auto-checkpoint.d.ts +98 -0
  24. package/dist/src/integrations/auto-checkpoint.d.ts.map +1 -0
  25. package/dist/src/integrations/auto-checkpoint.js +252 -0
  26. package/dist/src/integrations/auto-checkpoint.js.map +1 -0
  27. package/dist/src/integrations/budget-pool.d.ts +13 -1
  28. package/dist/src/integrations/budget-pool.d.ts.map +1 -1
  29. package/dist/src/integrations/budget-pool.js +17 -0
  30. package/dist/src/integrations/budget-pool.js.map +1 -1
  31. package/dist/src/integrations/complexity-classifier.d.ts +86 -0
  32. package/dist/src/integrations/complexity-classifier.d.ts.map +1 -0
  33. package/dist/src/integrations/complexity-classifier.js +233 -0
  34. package/dist/src/integrations/complexity-classifier.js.map +1 -0
  35. package/dist/src/integrations/delegation-protocol.d.ts +86 -0
  36. package/dist/src/integrations/delegation-protocol.d.ts.map +1 -0
  37. package/dist/src/integrations/delegation-protocol.js +127 -0
  38. package/dist/src/integrations/delegation-protocol.js.map +1 -0
  39. package/dist/src/integrations/dynamic-budget.d.ts +81 -0
  40. package/dist/src/integrations/dynamic-budget.d.ts.map +1 -0
  41. package/dist/src/integrations/dynamic-budget.js +151 -0
  42. package/dist/src/integrations/dynamic-budget.js.map +1 -0
  43. package/dist/src/integrations/economics.d.ts +44 -1
  44. package/dist/src/integrations/economics.d.ts.map +1 -1
  45. package/dist/src/integrations/economics.js +182 -3
  46. package/dist/src/integrations/economics.js.map +1 -1
  47. package/dist/src/integrations/environment-facts.d.ts +52 -0
  48. package/dist/src/integrations/environment-facts.d.ts.map +1 -0
  49. package/dist/src/integrations/environment-facts.js +84 -0
  50. package/dist/src/integrations/environment-facts.js.map +1 -0
  51. package/dist/src/integrations/index.d.ts +16 -1
  52. package/dist/src/integrations/index.d.ts.map +1 -1
  53. package/dist/src/integrations/index.js +31 -1
  54. package/dist/src/integrations/index.js.map +1 -1
  55. package/dist/src/integrations/injection-budget.d.ts +71 -0
  56. package/dist/src/integrations/injection-budget.d.ts.map +1 -0
  57. package/dist/src/integrations/injection-budget.js +136 -0
  58. package/dist/src/integrations/injection-budget.js.map +1 -0
  59. package/dist/src/integrations/mcp-client.d.ts.map +1 -1
  60. package/dist/src/integrations/mcp-client.js +14 -0
  61. package/dist/src/integrations/mcp-client.js.map +1 -1
  62. package/dist/src/integrations/mcp-custom-tools.d.ts +102 -0
  63. package/dist/src/integrations/mcp-custom-tools.d.ts.map +1 -0
  64. package/dist/src/integrations/mcp-custom-tools.js +232 -0
  65. package/dist/src/integrations/mcp-custom-tools.js.map +1 -0
  66. package/dist/src/integrations/mcp-tool-validator.d.ts +60 -0
  67. package/dist/src/integrations/mcp-tool-validator.d.ts.map +1 -0
  68. package/dist/src/integrations/mcp-tool-validator.js +141 -0
  69. package/dist/src/integrations/mcp-tool-validator.js.map +1 -0
  70. package/dist/src/integrations/routing.d.ts +2 -1
  71. package/dist/src/integrations/routing.d.ts.map +1 -1
  72. package/dist/src/integrations/routing.js.map +1 -1
  73. package/dist/src/integrations/self-improvement.d.ts +90 -0
  74. package/dist/src/integrations/self-improvement.d.ts.map +1 -0
  75. package/dist/src/integrations/self-improvement.js +217 -0
  76. package/dist/src/integrations/self-improvement.js.map +1 -0
  77. package/dist/src/integrations/smart-decomposer.d.ts +4 -0
  78. package/dist/src/integrations/smart-decomposer.d.ts.map +1 -1
  79. package/dist/src/integrations/smart-decomposer.js +55 -28
  80. package/dist/src/integrations/smart-decomposer.js.map +1 -1
  81. package/dist/src/integrations/subagent-output-store.d.ts +91 -0
  82. package/dist/src/integrations/subagent-output-store.d.ts.map +1 -0
  83. package/dist/src/integrations/subagent-output-store.js +257 -0
  84. package/dist/src/integrations/subagent-output-store.js.map +1 -0
  85. package/dist/src/integrations/swarm/index.d.ts +1 -1
  86. package/dist/src/integrations/swarm/index.d.ts.map +1 -1
  87. package/dist/src/integrations/swarm/index.js +1 -1
  88. package/dist/src/integrations/swarm/index.js.map +1 -1
  89. package/dist/src/integrations/swarm/model-selector.d.ts +1 -0
  90. package/dist/src/integrations/swarm/model-selector.d.ts.map +1 -1
  91. package/dist/src/integrations/swarm/model-selector.js +37 -3
  92. package/dist/src/integrations/swarm/model-selector.js.map +1 -1
  93. package/dist/src/integrations/swarm/swarm-config-loader.d.ts +10 -1
  94. package/dist/src/integrations/swarm/swarm-config-loader.d.ts.map +1 -1
  95. package/dist/src/integrations/swarm/swarm-config-loader.js +72 -6
  96. package/dist/src/integrations/swarm/swarm-config-loader.js.map +1 -1
  97. package/dist/src/integrations/swarm/swarm-event-bridge.d.ts.map +1 -1
  98. package/dist/src/integrations/swarm/swarm-event-bridge.js +26 -4
  99. package/dist/src/integrations/swarm/swarm-event-bridge.js.map +1 -1
  100. package/dist/src/integrations/swarm/swarm-events.d.ts +11 -0
  101. package/dist/src/integrations/swarm/swarm-events.d.ts.map +1 -1
  102. package/dist/src/integrations/swarm/swarm-events.js +4 -0
  103. package/dist/src/integrations/swarm/swarm-events.js.map +1 -1
  104. package/dist/src/integrations/swarm/swarm-orchestrator.d.ts +11 -0
  105. package/dist/src/integrations/swarm/swarm-orchestrator.d.ts.map +1 -1
  106. package/dist/src/integrations/swarm/swarm-orchestrator.js +233 -10
  107. package/dist/src/integrations/swarm/swarm-orchestrator.js.map +1 -1
  108. package/dist/src/integrations/swarm/swarm-quality-gate.d.ts +9 -2
  109. package/dist/src/integrations/swarm/swarm-quality-gate.d.ts.map +1 -1
  110. package/dist/src/integrations/swarm/swarm-quality-gate.js +128 -11
  111. package/dist/src/integrations/swarm/swarm-quality-gate.js.map +1 -1
  112. package/dist/src/integrations/swarm/task-queue.d.ts +11 -1
  113. package/dist/src/integrations/swarm/task-queue.d.ts.map +1 -1
  114. package/dist/src/integrations/swarm/task-queue.js +125 -15
  115. package/dist/src/integrations/swarm/task-queue.js.map +1 -1
  116. package/dist/src/integrations/swarm/types.d.ts +40 -1
  117. package/dist/src/integrations/swarm/types.d.ts.map +1 -1
  118. package/dist/src/integrations/swarm/types.js +6 -1
  119. package/dist/src/integrations/swarm/types.js.map +1 -1
  120. package/dist/src/integrations/swarm/worker-pool.d.ts +9 -3
  121. package/dist/src/integrations/swarm/worker-pool.d.ts.map +1 -1
  122. package/dist/src/integrations/swarm/worker-pool.js +89 -17
  123. package/dist/src/integrations/swarm/worker-pool.js.map +1 -1
  124. package/dist/src/integrations/thinking-strategy.d.ts +52 -0
  125. package/dist/src/integrations/thinking-strategy.d.ts.map +1 -0
  126. package/dist/src/integrations/thinking-strategy.js +129 -0
  127. package/dist/src/integrations/thinking-strategy.js.map +1 -0
  128. package/dist/src/integrations/tool-recommendation.d.ts +58 -0
  129. package/dist/src/integrations/tool-recommendation.d.ts.map +1 -0
  130. package/dist/src/integrations/tool-recommendation.js +215 -0
  131. package/dist/src/integrations/tool-recommendation.js.map +1 -0
  132. package/dist/src/integrations/verification-gate.d.ts +80 -0
  133. package/dist/src/integrations/verification-gate.d.ts.map +1 -0
  134. package/dist/src/integrations/verification-gate.js +146 -0
  135. package/dist/src/integrations/verification-gate.js.map +1 -0
  136. package/dist/src/integrations/work-log.d.ts +87 -0
  137. package/dist/src/integrations/work-log.d.ts.map +1 -0
  138. package/dist/src/integrations/work-log.js +275 -0
  139. package/dist/src/integrations/work-log.js.map +1 -0
  140. package/dist/src/main.js +5 -4
  141. package/dist/src/main.js.map +1 -1
  142. package/dist/src/modes.d.ts +6 -0
  143. package/dist/src/modes.d.ts.map +1 -1
  144. package/dist/src/modes.js +73 -2
  145. package/dist/src/modes.js.map +1 -1
  146. package/dist/src/providers/adapters/anthropic.d.ts.map +1 -1
  147. package/dist/src/providers/adapters/anthropic.js +20 -3
  148. package/dist/src/providers/adapters/anthropic.js.map +1 -1
  149. package/dist/src/providers/adapters/openrouter.d.ts.map +1 -1
  150. package/dist/src/providers/adapters/openrouter.js +3 -1
  151. package/dist/src/providers/adapters/openrouter.js.map +1 -1
  152. package/dist/src/providers/types.d.ts +4 -0
  153. package/dist/src/providers/types.d.ts.map +1 -1
  154. package/dist/src/providers/types.js.map +1 -1
  155. package/dist/src/tools/bash.d.ts +8 -2
  156. package/dist/src/tools/bash.d.ts.map +1 -1
  157. package/dist/src/tools/bash.js +14 -1
  158. package/dist/src/tools/bash.js.map +1 -1
  159. package/dist/src/tools/coercion.d.ts +14 -0
  160. package/dist/src/tools/coercion.d.ts.map +1 -0
  161. package/dist/src/tools/coercion.js +25 -0
  162. package/dist/src/tools/coercion.js.map +1 -0
  163. package/dist/src/tools/file.d.ts +2 -2
  164. package/dist/src/tools/file.d.ts.map +1 -1
  165. package/dist/src/tools/file.js +2 -1
  166. package/dist/src/tools/file.js.map +1 -1
  167. package/dist/src/tools/standard.d.ts +17 -1
  168. package/dist/src/tools/standard.d.ts.map +1 -1
  169. package/dist/src/tools/standard.js +64 -11
  170. package/dist/src/tools/standard.js.map +1 -1
  171. package/dist/src/tui/app.d.ts.map +1 -1
  172. package/dist/src/tui/app.js +8 -1
  173. package/dist/src/tui/app.js.map +1 -1
  174. package/dist/src/tui/event-display.d.ts.map +1 -1
  175. package/dist/src/tui/event-display.js +8 -1
  176. package/dist/src/tui/event-display.js.map +1 -1
  177. package/dist/src/types.d.ts +26 -0
  178. package/dist/src/types.d.ts.map +1 -1
  179. package/package.json +6 -2
@@ -76,6 +76,10 @@ export function formatSwarmEvent(event) {
76
76
  const roleLabel = event.role.charAt(0).toUpperCase() + event.role.slice(1);
77
77
  return `${roleLabel} ${event.action}: ${event.model.split('/').pop() ?? event.model}${event.taskId ? ` (task ${event.taskId})` : ''}`;
78
78
  }
79
+ case 'swarm.wave.allFailed':
80
+ return `Wave ${event.wave}: ALL tasks failed — attempting recovery`;
81
+ case 'swarm.phase.progress':
82
+ return `[${event.phase}] ${event.message}`;
79
83
  }
80
84
  }
81
85
  //# sourceMappingURL=swarm-events.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"swarm-events.js","sourceRoot":"","sources":["../../../../src/integrations/swarm/swarm-events.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"swarm-events.js","sourceRoot":"","sources":["../../../../src/integrations/swarm/swarm-events.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA2CH;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,KAAuB;IAClD,OAAO,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAiB;IAChD,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,aAAa;YAChB,OAAO,kBAAkB,KAAK,CAAC,SAAS,aAAa,KAAK,CAAC,SAAS,eAAe,KAAK,CAAC,MAAM,CAAC,cAAc,cAAc,CAAC;QAC/H,KAAK,oBAAoB;YACvB,OAAO,iBAAiB,KAAK,CAAC,KAAK,CAAC,MAAM,8BAA8B,CAAC;QAC3E,KAAK,kBAAkB;YACrB,OAAO,QAAQ,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,UAAU,iBAAiB,KAAK,CAAC,SAAS,QAAQ,CAAC;QACxF,KAAK,qBAAqB;YACxB,OAAO,QAAQ,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,UAAU,cAAc,KAAK,CAAC,SAAS,UAAU,KAAK,CAAC,MAAM,YAAY,KAAK,CAAC,OAAO,UAAU,CAAC;QACtI,KAAK,uBAAuB;YAC1B,OAAO,QAAQ,KAAK,CAAC,MAAM,MAAM,KAAK,CAAC,UAAU,KAAK,KAAK,CAAC,KAAK,MAAM,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QAC1G,KAAK,sBAAsB;YACzB,OAAO,QAAQ,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,KAAK,KAAK,CAAC,UAAU,aAAa,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;QAChL,KAAK,mBAAmB;YACtB,OAAO,QAAQ,KAAK,CAAC,MAAM,oBAAoB,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,WAAW,MAAM,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAChJ,KAAK,oBAAoB;YACvB,OAAO,QAAQ,KAAK,CAAC,MAAM,aAAa,KAAK,CAAC,MAAM,EAAE,CAAC;QACzD,KAAK,wBAAwB;YAC3B,OAAO,QAAQ,KAAK,CAAC,MAAM,oBAAoB,KAAK,CAAC,KAAK,QAAQ,KAAK,CAAC,QAAQ,EAAE,CAAC;QACrF,KAAK,qBAAqB;YACxB,OAAO,WAAW,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3K,KAAK,gBAAgB;YACnB,OAAO,mBAAmB,KAAK,CAAC,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,KAAK,CAAC,UAAU,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACvL,KAAK,cAAc;YACjB,OAAO,eAAe,KAAK,CAAC,MAAM,CAAC,WAAW,IAAI,KAAK,CAAC,MAAM,CAAC,UAAU,KAAK,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,iBAAiB,CAAC;QACnI,KAAK,aAAa;YAChB,OAAO,kBAAkB,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC;QACzD,YAAY;QACZ,KAAK,qBAAqB;YACxB,OAAO,iBAAiB,KAAK,CAAC,aAAa,uBAAuB,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACtI,KAAK,oBAAoB;YACvB,OAAO,kBAAkB,KAAK,CAAC,IAAI,aAAa,CAAC;QACnD,KAAK,uBAAuB;YAC1B,OAAO,QAAQ,KAAK,CAAC,IAAI,YAAY,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,UAAU,wBAAwB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACtI,KAAK,oBAAoB;YACvB,OAAO,WAAW,KAAK,CAAC,SAAS,wBAAwB,CAAC;QAC5D,KAAK,mBAAmB;YACtB,OAAO,eAAe,KAAK,CAAC,SAAS,GAAG,CAAC,KAAK,KAAK,CAAC,WAAW,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QACxG,KAAK,uBAAuB;YAC1B,OAAO,gBAAgB,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,KAAK,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAC9F,KAAK,oBAAoB;YACvB,OAAO,sBAAsB,KAAK,CAAC,MAAM,aAAa,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,KAAK,GAAG,CAAC;QAC7F,KAAK,sBAAsB;YACzB,OAAO,wBAAwB,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC;QACxG,KAAK,oBAAoB;YACvB,OAAO,iBAAiB,KAAK,CAAC,MAAM,CAAC,KAAK,MAAM,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,KAAK,KAAK,CAAC,MAAM,CAAC,SAAS,MAAM,KAAK,CAAC,MAAM,CAAC,QAAQ,QAAQ,KAAK,CAAC,MAAM,CAAC,UAAU,KAAK,CAAC;QAC3L,KAAK,wBAAwB;YAC3B,OAAO,6BAA6B,KAAK,CAAC,SAAS,UAAU,KAAK,CAAC,IAAI,EAAE,CAAC;QAC5E,KAAK,oBAAoB;YACvB,OAAO,oBAAoB,KAAK,CAAC,SAAS,cAAc,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC3E,KAAK,6BAA6B;YAChC,OAAO,aAAa,KAAK,CAAC,QAAQ,CAAC,KAAK,MAAM,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAC1E,KAAK,qBAAqB;YACxB,OAAO,eAAe,KAAK,CAAC,MAAM,YAAY,KAAK,CAAC,WAAW,KAAK,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QACvG,KAAK,oBAAoB;YACvB,OAAO,yBAAyB,KAAK,CAAC,WAAW,6CAA6C,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;QACrI,KAAK,sBAAsB;YACzB,OAAO,0CAA0C,CAAC;QACpD,KAAK,mBAAmB,CAAC,CAAC,CAAC;YACzB,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC3E,OAAO,GAAG,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACxI,CAAC;QACD,KAAK,sBAAsB;YACzB,OAAO,QAAQ,KAAK,CAAC,IAAI,0CAA0C,CAAC;QACtE,KAAK,sBAAsB;YACzB,OAAO,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;IAC/C,CAAC;AACH,CAAC"}
@@ -23,6 +23,13 @@ import type { SwarmConfig, SwarmExecutionResult, SwarmStatus } from './types.js'
23
23
  import { type SwarmBudgetPool } from './swarm-budget.js';
24
24
  import { type SpawnAgentFn } from './worker-pool.js';
25
25
  import type { SwarmEvent } from './swarm-events.js';
26
+ import type { SpawnResult } from '../agent-registry.js';
27
+ /**
28
+ * V10: Minimal hollow completion detection — let the quality gate judge everything else.
29
+ * Only catches truly empty completions: zero tool calls AND trivial output (<50 chars).
30
+ * No task-type lists, no closure report checks, no hardcoded thresholds beyond the bare minimum.
31
+ */
32
+ export declare function isHollowCompletion(spawnResult: SpawnResult): boolean;
26
33
  export type SwarmEventListener = (event: SwarmEvent) => void;
27
34
  export declare class SwarmOrchestrator {
28
35
  private config;
@@ -55,6 +62,9 @@ export declare class SwarmOrchestrator {
55
62
  private static readonly CIRCUIT_BREAKER_WINDOW_MS;
56
63
  private static readonly CIRCUIT_BREAKER_THRESHOLD;
57
64
  private static readonly CIRCUIT_BREAKER_PAUSE_MS;
65
+ private consecutiveQualityRejections;
66
+ private qualityGateDisabled;
67
+ private static readonly QUALITY_CIRCUIT_BREAKER_THRESHOLD;
58
68
  constructor(config: SwarmConfig, provider: LLMProvider, agentRegistry: AgentRegistry, spawnAgentFn: SpawnAgentFn, blackboard?: SharedBlackboard);
59
69
  /**
60
70
  * Get the swarm budget pool (used by parent agent to override its own pool).
@@ -119,6 +129,7 @@ export declare class SwarmOrchestrator {
119
129
  private executeWave;
120
130
  /**
121
131
  * Dispatch a single task to a worker.
132
+ * Selects the worker once and passes it through to avoid double-selection.
122
133
  */
123
134
  private dispatchTask;
124
135
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"swarm-orchestrator.d.ts","sourceRoot":"","sources":["../../../../src/integrations/swarm/swarm-orchestrator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"swarm-orchestrator.d.ts","sourceRoot":"","sources":["../../../../src/integrations/swarm/swarm-orchestrator.ts"],"names":[],"mappings":"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"}
@@ -25,6 +25,20 @@ import { createSwarmWorkerPool } from './worker-pool.js';
25
25
  import { evaluateWorkerOutput } from './swarm-quality-gate.js';
26
26
  import { ModelHealthTracker, selectAlternativeModel } from './model-selector.js';
27
27
  import { SwarmStateStore } from './swarm-state-store.js';
28
+ // ─── Hollow Completion Detection ──────────────────────────────────────────
29
+ /**
30
+ * V10: Minimal hollow completion detection — let the quality gate judge everything else.
31
+ * Only catches truly empty completions: zero tool calls AND trivial output (<50 chars).
32
+ * No task-type lists, no closure report checks, no hardcoded thresholds beyond the bare minimum.
33
+ */
34
+ export function isHollowCompletion(spawnResult) {
35
+ // Timeout uses toolCalls === -1, not hollow
36
+ if (spawnResult.metrics.toolCalls === -1)
37
+ return false;
38
+ // Only catch truly empty completions: zero tools AND trivial output
39
+ return spawnResult.metrics.toolCalls === 0
40
+ && (spawnResult.output?.trim().length ?? 0) < 50;
41
+ }
28
42
  // ─── Orchestrator ──────────────────────────────────────────────────────────
29
43
  export class SwarmOrchestrator {
30
44
  config;
@@ -61,6 +75,10 @@ export class SwarmOrchestrator {
61
75
  static CIRCUIT_BREAKER_WINDOW_MS = 30_000;
62
76
  static CIRCUIT_BREAKER_THRESHOLD = 3;
63
77
  static CIRCUIT_BREAKER_PAUSE_MS = 15_000;
78
+ // Quality gate circuit breaker: disable quality gates after too many consecutive rejections
79
+ consecutiveQualityRejections = 0;
80
+ qualityGateDisabled = false;
81
+ static QUALITY_CIRCUIT_BREAKER_THRESHOLD = 8;
64
82
  constructor(config, provider, agentRegistry, spawnAgentFn, blackboard) {
65
83
  this.config = { ...DEFAULT_SWARM_CONFIG, ...config };
66
84
  this.provider = provider;
@@ -78,6 +96,8 @@ export class SwarmOrchestrator {
78
96
  const llmDecompose = async (task, _context) => {
79
97
  const systemPrompt = `You are a task decomposition expert. Break down the given task into well-defined subtasks with clear dependencies.
80
98
 
99
+ CRITICAL: Dependencies MUST use zero-based integer indices referring to other subtasks in the array.
100
+
81
101
  Respond with valid JSON matching this exact schema:
82
102
  {
83
103
  "subtasks": [
@@ -85,7 +105,7 @@ Respond with valid JSON matching this exact schema:
85
105
  "description": "Clear description of what this subtask does",
86
106
  "type": "implement" | "research" | "analysis" | "design" | "test" | "refactor" | "review" | "document" | "integrate" | "deploy" | "merge",
87
107
  "complexity": 1-10,
88
- "dependencies": ["description of dependency task or index like '0'"],
108
+ "dependencies": [0, 1],
89
109
  "parallelizable": true | false,
90
110
  "relevantFiles": ["src/path/to/file.ts"]
91
111
  }
@@ -94,10 +114,34 @@ Respond with valid JSON matching this exact schema:
94
114
  "reasoning": "Brief explanation of why this decomposition was chosen"
95
115
  }
96
116
 
117
+ EXAMPLE 1 — Research task (3 parallel research + 1 merge):
118
+ {
119
+ "subtasks": [
120
+ { "description": "Research React state management", "type": "research", "complexity": 3, "dependencies": [], "parallelizable": true },
121
+ { "description": "Research routing options", "type": "research", "complexity": 3, "dependencies": [], "parallelizable": true },
122
+ { "description": "Research testing frameworks", "type": "research", "complexity": 2, "dependencies": [], "parallelizable": true },
123
+ { "description": "Synthesize findings into recommendation", "type": "merge", "complexity": 4, "dependencies": [0, 1, 2], "parallelizable": false }
124
+ ],
125
+ "strategy": "parallel",
126
+ "reasoning": "Independent research tasks feed into a single merge"
127
+ }
128
+
129
+ EXAMPLE 2 — Implementation task (sequential chain):
130
+ {
131
+ "subtasks": [
132
+ { "description": "Design API schema", "type": "design", "complexity": 4, "dependencies": [], "parallelizable": false },
133
+ { "description": "Implement API endpoints", "type": "implement", "complexity": 6, "dependencies": [0], "parallelizable": false },
134
+ { "description": "Write integration tests", "type": "test", "complexity": 3, "dependencies": [1], "parallelizable": false }
135
+ ],
136
+ "strategy": "sequential",
137
+ "reasoning": "Each step depends on the previous"
138
+ }
139
+
97
140
  Rules:
141
+ - Dependencies MUST be integer indices (e.g., [0, 1]), NOT descriptions or strings
98
142
  - Each subtask must have a clear, actionable description
99
- - Dependencies reference other subtask descriptions or zero-based indices
100
143
  - Mark subtasks as parallelizable: true if they don't depend on each other
144
+ - If there are multiple independent subtasks, ALWAYS create a final merge task that depends on ALL of them
101
145
  - Complexity 1-3: simple, 4-6: moderate, 7-10: complex
102
146
  - Return at least 2 subtasks for non-trivial tasks`;
103
147
  const response = await this.provider.chat([
@@ -174,6 +218,7 @@ Rules:
174
218
  }
175
219
  // Phase 1: Decompose
176
220
  this.currentPhase = 'decomposing';
221
+ this.emit({ type: 'swarm.phase.progress', phase: 'decomposing', message: 'Decomposing task into subtasks...' });
177
222
  const decomposition = await this.decompose(task);
178
223
  if (!decomposition) {
179
224
  this.currentPhase = 'failed';
@@ -181,12 +226,22 @@ Rules:
181
226
  }
182
227
  // Phase 2: Schedule into waves
183
228
  this.currentPhase = 'scheduling';
229
+ this.emit({ type: 'swarm.phase.progress', phase: 'scheduling', message: `Scheduling ${decomposition.subtasks.length} subtasks into waves...` });
184
230
  this.taskQueue.loadFromDecomposition(decomposition, this.config);
231
+ // Emit skip events when tasks are cascade-skipped due to dependency failures
232
+ this.taskQueue.setOnCascadeSkip((skippedTaskId, reason) => {
233
+ this.emit({ type: 'swarm.task.skipped', taskId: skippedTaskId, reason });
234
+ });
185
235
  const stats = this.taskQueue.getStats();
186
- // V2: Phase 2.5: Plan execution (acceptance criteria)
236
+ this.emit({ type: 'swarm.phase.progress', phase: 'scheduling', message: `Scheduled ${stats.total} tasks in ${this.taskQueue.getTotalWaves()} waves` });
237
+ // V2: Phase 2.5: Plan execution — fire in background, don't block waves
238
+ let planPromise;
187
239
  if (this.config.enablePlanning) {
188
240
  this.currentPhase = 'planning';
189
- await this.planExecution(task, decomposition);
241
+ this.emit({ type: 'swarm.phase.progress', phase: 'planning', message: 'Creating acceptance criteria...' });
242
+ planPromise = this.planExecution(task, decomposition).catch(err => {
243
+ this.logDecision('planning', 'Planning failed (non-fatal)', err.message);
244
+ });
190
245
  }
191
246
  this.emit({
192
247
  type: 'swarm.start',
@@ -204,9 +259,12 @@ Rules:
204
259
  type: 'swarm.tasks.loaded',
205
260
  tasks: this.taskQueue.getAllTasks(),
206
261
  });
207
- // Phase 3: Execute waves (V2: with review after each wave)
262
+ // Phase 3: Execute waves (planning runs concurrently)
208
263
  this.currentPhase = 'executing';
209
264
  await this.executeWaves();
265
+ // Ensure planning completed before verification/synthesis
266
+ if (planPromise)
267
+ await planPromise;
210
268
  // V2: Phase 3.5: Verify integration
211
269
  if (this.config.enableVerification && this.plan?.integrationTestPlan) {
212
270
  this.currentPhase = 'verifying';
@@ -257,6 +315,16 @@ Rules:
257
315
  // Too simple for swarm mode
258
316
  return null;
259
317
  }
318
+ // Reject heuristic fallback — the generic 3-task chain is worse than aborting
319
+ if (!result.metadata.llmAssisted) {
320
+ this.logDecision('decomposition', 'Rejected heuristic fallback DAG', 'LLM decomposition failed after retries. Heuristic DAG is not useful.');
321
+ return null;
322
+ }
323
+ // Flat-DAG detection: warn when all tasks land in wave 0 with no dependencies
324
+ const hasAnyDependency = result.subtasks.some(s => s.dependencies.length > 0);
325
+ if (!hasAnyDependency && result.subtasks.length >= 3) {
326
+ this.logDecision('decomposition', `Flat DAG: ${result.subtasks.length} tasks, zero dependencies`, 'All tasks will execute in wave 0 without ordering');
327
+ }
260
328
  return result;
261
329
  }
262
330
  catch (error) {
@@ -412,6 +480,11 @@ Respond with valid JSON:
412
480
  }
413
481
  if (fixupTasks.length > 0) {
414
482
  this.taskQueue.addFixupTasks(fixupTasks);
483
+ // V5: Re-emit full task list so dashboard picks up fixup tasks + edges
484
+ this.emit({
485
+ type: 'swarm.tasks.loaded',
486
+ tasks: this.taskQueue.getAllTasks(),
487
+ });
415
488
  }
416
489
  }
417
490
  const result = {
@@ -520,6 +593,11 @@ Respond with JSON: { "fixups": [{ "description": "what to fix", "type": "impleme
520
593
  fixInstructions: f.description,
521
594
  }));
522
595
  this.taskQueue.addFixupTasks(fixupTasks);
596
+ // V5: Re-emit full task list so dashboard picks up verification fixup tasks
597
+ this.emit({
598
+ type: 'swarm.tasks.loaded',
599
+ tasks: this.taskQueue.getAllTasks(),
600
+ });
523
601
  // Execute fix-up wave
524
602
  this.currentPhase = 'executing';
525
603
  await this.executeWave(fixupTasks);
@@ -566,6 +644,19 @@ Respond with JSON: { "fixups": [{ "description": "what to fix", "type": "impleme
566
644
  waves: checkpoint.waves,
567
645
  currentWave: checkpoint.currentWave,
568
646
  });
647
+ // Reset orphaned dispatched tasks — their workers died with the previous process
648
+ let resetCount = 0;
649
+ for (const task of this.taskQueue.getAllTasks()) {
650
+ if (task.status === 'dispatched') {
651
+ task.status = 'ready';
652
+ // Preserve at least 1 retry attempt
653
+ task.attempts = Math.min(task.attempts, Math.max(0, this.config.workerRetries - 1));
654
+ resetCount++;
655
+ }
656
+ }
657
+ if (resetCount > 0) {
658
+ this.logDecision('resume', `Reset ${resetCount} orphaned dispatched tasks to ready`, 'Workers died with previous process');
659
+ }
569
660
  // Continue from where we left off
570
661
  this.currentPhase = 'executing';
571
662
  await this.executeWaves();
@@ -623,12 +714,48 @@ Respond with JSON: { "fixups": [{ "description": "what to fix", "type": "impleme
623
714
  failed: waveFailed,
624
715
  skipped: waveSkipped,
625
716
  });
717
+ // Wave failure recovery: if ALL tasks in a wave failed, retry with adapted context
718
+ if (waveCompleted === 0 && waveFailed > 0 && readyTasks.length > 0) {
719
+ this.emit({ type: 'swarm.wave.allFailed', wave: waveIndex + 1 });
720
+ this.logDecision('wave-recovery', `Entire wave ${waveIndex + 1} failed (${waveFailed} tasks)`, 'Checking if budget allows retry with adapted strategy');
721
+ // Re-queue failed tasks with retry context if budget allows
722
+ const budgetRemaining = this.budgetPool.hasCapacity();
723
+ const failedWaveTasks = readyTasks.filter(t => {
724
+ const task = this.taskQueue.getTask(t.id);
725
+ return task && task.status === 'failed' && task.attempts < (this.config.workerRetries + 1);
726
+ });
727
+ if (budgetRemaining && failedWaveTasks.length > 0) {
728
+ for (const t of failedWaveTasks) {
729
+ const task = this.taskQueue.getTask(t.id);
730
+ if (!task)
731
+ continue;
732
+ task.status = 'ready';
733
+ task.retryContext = {
734
+ previousFeedback: 'All tasks in this batch failed. Try a fundamentally different approach — the previous strategy did not work.',
735
+ previousScore: 0,
736
+ attempt: task.attempts,
737
+ };
738
+ }
739
+ this.logDecision('wave-recovery', `Re-queued ${failedWaveTasks.length} tasks with adapted retry context`, 'Budget allows retry');
740
+ // Re-execute the wave with adapted tasks
741
+ await this.executeWave(failedWaveTasks.map(t => this.taskQueue.getTask(t.id)).filter(t => t.status === 'ready'));
742
+ }
743
+ }
626
744
  // V2: Review wave outputs
627
745
  const review = await this.reviewWave(waveIndex);
628
746
  if (review && review.fixupTasks.length > 0) {
629
747
  // Execute fix-up tasks immediately
630
748
  await this.executeWave(review.fixupTasks);
631
749
  }
750
+ // Reset quality circuit breaker at wave boundary — each wave gets a fresh chance.
751
+ // Within a wave, rejections accumulate properly so the breaker can trip.
752
+ // Between waves, we reset so each wave gets a fresh quality evaluation window.
753
+ // (The within-wave reset at quality-gate-passed is kept — that's correct.)
754
+ if (this.qualityGateDisabled) {
755
+ this.qualityGateDisabled = false;
756
+ this.consecutiveQualityRejections = 0;
757
+ this.logDecision('quality-circuit-breaker', `Re-enabled quality gates at wave ${waveIndex + 1} boundary`, 'Each wave gets a fresh quality evaluation window');
758
+ }
632
759
  // V2: Checkpoint after each wave
633
760
  this.checkpoint(`wave-${waveIndex}`);
634
761
  // Advance to next wave
@@ -700,6 +827,7 @@ Respond with JSON: { "fixups": [{ "description": "what to fix", "type": "impleme
700
827
  }
701
828
  /**
702
829
  * Dispatch a single task to a worker.
830
+ * Selects the worker once and passes it through to avoid double-selection.
703
831
  */
704
832
  async dispatchTask(task) {
705
833
  const worker = this.workerPool.selectWorker(task);
@@ -718,7 +846,8 @@ Respond with JSON: { "fixups": [{ "description": "what to fix", "type": "impleme
718
846
  }
719
847
  try {
720
848
  this.taskQueue.markDispatched(task.id, worker.model);
721
- await this.workerPool.dispatch(task);
849
+ // Pass the pre-selected worker to avoid double-selection in dispatch()
850
+ await this.workerPool.dispatch(task, worker);
722
851
  this.emit({
723
852
  type: 'swarm.task.dispatched',
724
853
  taskId: task.id,
@@ -752,6 +881,9 @@ Respond with JSON: { "fixups": [{ "description": "what to fix", "type": "impleme
752
881
  const task = this.taskQueue.getTask(taskId);
753
882
  if (!task)
754
883
  return;
884
+ // Guard: task was cascade-skipped while its worker was running — ignore the result
885
+ if (task.status === 'skipped' || task.status === 'failed')
886
+ return;
755
887
  const durationMs = Date.now() - startedAt;
756
888
  const taskResult = this.workerPool.toTaskResult(spawnResult, task, durationMs);
757
889
  // Track model usage
@@ -791,6 +923,19 @@ Respond with JSON: { "fixups": [{ "description": "what to fix", "type": "impleme
791
923
  this.logDecision('failover', `Switched ${taskId} from ${model} to ${alternative.model}`, `${errorType} error`);
792
924
  }
793
925
  }
926
+ // V5/V7: Store error context so retry gets different prompt
927
+ if (!(is429 || is402)) {
928
+ // V7: Timeout-specific feedback — the worker WAS working, just ran out of time
929
+ const isTimeout = spawnResult.metrics.toolCalls === -1;
930
+ const timeoutSeconds = isTimeout ? Math.round(durationMs / 1000) : 0;
931
+ task.retryContext = {
932
+ previousFeedback: isTimeout
933
+ ? `Previous attempt timed out after ${timeoutSeconds}s. You must complete this task more efficiently — work faster, use fewer tool calls, and produce your result sooner.`
934
+ : spawnResult.output.slice(0, 500),
935
+ previousScore: 0,
936
+ attempt: task.attempts,
937
+ };
938
+ }
794
939
  // Worker failed — use higher retry limit for rate limit errors
795
940
  const retryLimit = (is429 || is402)
796
941
  ? (this.config.rateLimitRetries ?? 3)
@@ -815,12 +960,56 @@ Respond with JSON: { "fixups": [{ "description": "what to fix", "type": "impleme
815
960
  });
816
961
  return;
817
962
  }
818
- // V2: Record model health on success
963
+ // V6: Hollow completion detection workers that "succeed" without doing any work
964
+ // Must check BEFORE recording success, otherwise hollow completions inflate health scores
965
+ if (isHollowCompletion(spawnResult)) {
966
+ // Record health failure so hollow-prone models accumulate failure records
967
+ // and eventually trigger failover via selectAlternativeModel
968
+ this.healthTracker.recordFailure(model, 'error');
969
+ task.retryContext = {
970
+ previousFeedback: 'Previous attempt produced no meaningful output. Try again with a concrete approach.',
971
+ previousScore: 1,
972
+ attempt: task.attempts,
973
+ };
974
+ // Model failover for hollow completions — same pattern as quality failover
975
+ if (this.config.enableModelFailover) {
976
+ const capability = SUBTASK_TO_CAPABILITY[task.type] ?? 'code';
977
+ const alternative = selectAlternativeModel(this.config.workers, model, capability, this.healthTracker);
978
+ if (alternative) {
979
+ this.emit({
980
+ type: 'swarm.model.failover',
981
+ taskId,
982
+ fromModel: model,
983
+ toModel: alternative.model,
984
+ reason: 'hollow-completion',
985
+ });
986
+ task.assignedModel = alternative.model;
987
+ this.logDecision('failover', `Hollow failover ${taskId}: ${model} → ${alternative.model}`, 'Model produced hollow completion');
988
+ }
989
+ }
990
+ const canRetry = this.taskQueue.markFailed(taskId, this.config.workerRetries);
991
+ if (canRetry)
992
+ this.retries++;
993
+ this.emit({
994
+ type: 'swarm.task.failed',
995
+ taskId,
996
+ error: 'Hollow completion: worker used no tools',
997
+ attempt: task.attempts,
998
+ maxAttempts: 1 + this.config.workerRetries,
999
+ willRetry: canRetry,
1000
+ });
1001
+ this.logDecision('hollow-completion', `${taskId}: worker completed with 0 tool calls`, 'Marking as failed for retry');
1002
+ return;
1003
+ }
1004
+ // Record model health on success (only for non-hollow completions)
819
1005
  this.healthTracker.recordSuccess(model, durationMs);
820
- // Run quality gate if enabled — skip under API pressure or on retried tasks
1006
+ // Run quality gate if enabled — skip under API pressure, skip if circuit breaker tripped,
1007
+ // and let the final attempt through without quality gate (so tasks produce *something*)
821
1008
  const recentRLCount = this.recentRateLimits.filter(t => t > Date.now() - 30_000).length;
1009
+ const isLastAttempt = task.attempts >= (this.config.workerRetries + 1);
822
1010
  const shouldRunQualityGate = this.config.qualityGates
823
- && task.attempts <= 1
1011
+ && !this.qualityGateDisabled
1012
+ && !isLastAttempt
824
1013
  && Date.now() >= this.circuitBreakerUntil
825
1014
  && recentRLCount < 2;
826
1015
  if (shouldRunQualityGate) {
@@ -832,11 +1021,39 @@ Respond with JSON: { "fixups": [{ "description": "what to fix", "type": "impleme
832
1021
  persona: this.config.hierarchy?.judge?.persona,
833
1022
  };
834
1023
  this.emit({ type: 'swarm.role.action', role: 'judge', action: 'quality-gate', model: judgeModel, taskId });
835
- const quality = await evaluateWorkerOutput(this.provider, judgeModel, task, taskResult, judgeConfig);
1024
+ const quality = await evaluateWorkerOutput(this.provider, judgeModel, task, taskResult, judgeConfig, this.config.qualityThreshold ?? 3);
836
1025
  taskResult.qualityScore = quality.score;
837
1026
  taskResult.qualityFeedback = quality.feedback;
838
1027
  if (!quality.passed) {
839
1028
  this.qualityRejections++;
1029
+ this.consecutiveQualityRejections++;
1030
+ // Quality circuit breaker: disable gates after too many consecutive rejections
1031
+ if (this.consecutiveQualityRejections >= SwarmOrchestrator.QUALITY_CIRCUIT_BREAKER_THRESHOLD) {
1032
+ this.qualityGateDisabled = true;
1033
+ this.logDecision('quality-circuit-breaker', `Disabled quality gates after ${this.consecutiveQualityRejections} consecutive rejections`, 'Workers cannot meet quality threshold — letting remaining tasks through');
1034
+ }
1035
+ // V5: Attach feedback so retry prompt includes it
1036
+ task.retryContext = {
1037
+ previousFeedback: quality.feedback,
1038
+ previousScore: quality.score,
1039
+ attempt: task.attempts,
1040
+ };
1041
+ // V5: Model failover on severe quality rejection — but NOT on artifact auto-fails
1042
+ if (quality.score <= 1 && this.config.enableModelFailover && !quality.artifactAutoFail) {
1043
+ const capability = SUBTASK_TO_CAPABILITY[task.type] ?? 'code';
1044
+ const alternative = selectAlternativeModel(this.config.workers, model, capability, this.healthTracker);
1045
+ if (alternative) {
1046
+ this.emit({
1047
+ type: 'swarm.model.failover',
1048
+ taskId,
1049
+ fromModel: model,
1050
+ toModel: alternative.model,
1051
+ reason: `quality-score-${quality.score}`,
1052
+ });
1053
+ task.assignedModel = alternative.model;
1054
+ this.logDecision('failover', `Quality failover ${taskId}: ${model} → ${alternative.model}`, `Score ${quality.score}/5`);
1055
+ }
1056
+ }
840
1057
  const canRetry = this.taskQueue.markFailed(taskId, this.config.workerRetries);
841
1058
  if (canRetry) {
842
1059
  this.retries++;
@@ -850,6 +1067,8 @@ Respond with JSON: { "fixups": [{ "description": "what to fix", "type": "impleme
850
1067
  });
851
1068
  return;
852
1069
  }
1070
+ // Quality passed — reset consecutive rejection counter
1071
+ this.consecutiveQualityRejections = 0;
853
1072
  }
854
1073
  // Task passed — mark completed
855
1074
  this.taskQueue.markCompleted(taskId, taskResult);
@@ -885,6 +1104,10 @@ Respond with JSON: { "fixups": [{ "description": "what to fix", "type": "impleme
885
1104
  costUsed: taskResult.costUsed,
886
1105
  durationMs: taskResult.durationMs,
887
1106
  qualityScore: taskResult.qualityScore,
1107
+ qualityFeedback: taskResult.qualityFeedback,
1108
+ output: taskResult.output,
1109
+ closureReport: taskResult.closureReport,
1110
+ toolCalls: spawnResult.metrics.toolCalls,
888
1111
  });
889
1112
  }
890
1113
  /**