heyio 1.13.0 → 3.0.1

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 (380) hide show
  1. package/README.md +162 -278
  2. package/dist/api/middleware/auth.d.ts +14 -0
  3. package/dist/api/middleware/auth.d.ts.map +1 -0
  4. package/dist/api/middleware/auth.js +66 -0
  5. package/dist/api/middleware/auth.js.map +1 -0
  6. package/dist/api/notifications.d.ts +14 -0
  7. package/dist/api/notifications.d.ts.map +1 -0
  8. package/dist/api/notifications.js +112 -0
  9. package/dist/api/notifications.js.map +1 -0
  10. package/dist/api/routes/activity.d.ts +3 -0
  11. package/dist/api/routes/activity.d.ts.map +1 -0
  12. package/dist/api/routes/activity.js +28 -0
  13. package/dist/api/routes/activity.js.map +1 -0
  14. package/dist/api/routes/attachments.d.ts +3 -0
  15. package/dist/api/routes/attachments.d.ts.map +1 -0
  16. package/dist/api/routes/attachments.js +83 -0
  17. package/dist/api/routes/attachments.js.map +1 -0
  18. package/dist/api/routes/config.d.ts +3 -0
  19. package/dist/api/routes/config.d.ts.map +1 -0
  20. package/dist/api/routes/config.js +106 -0
  21. package/dist/api/routes/config.js.map +1 -0
  22. package/dist/api/routes/conversations.d.ts +3 -0
  23. package/dist/api/routes/conversations.d.ts.map +1 -0
  24. package/dist/api/routes/conversations.js +69 -0
  25. package/dist/api/routes/conversations.js.map +1 -0
  26. package/dist/api/routes/health.d.ts +3 -0
  27. package/dist/api/routes/health.d.ts.map +1 -0
  28. package/dist/api/routes/health.js +16 -0
  29. package/dist/api/routes/health.js.map +1 -0
  30. package/dist/api/routes/inbox.d.ts +3 -0
  31. package/dist/api/routes/inbox.d.ts.map +1 -0
  32. package/dist/api/routes/inbox.js +88 -0
  33. package/dist/api/routes/inbox.js.map +1 -0
  34. package/dist/api/routes/schedules.d.ts +3 -0
  35. package/dist/api/routes/schedules.d.ts.map +1 -0
  36. package/dist/api/routes/schedules.js +96 -0
  37. package/dist/api/routes/schedules.js.map +1 -0
  38. package/dist/api/routes/skills.d.ts +2 -0
  39. package/dist/api/routes/skills.d.ts.map +1 -0
  40. package/dist/api/routes/skills.js +85 -0
  41. package/dist/api/routes/skills.js.map +1 -0
  42. package/dist/api/routes/squads.d.ts +3 -0
  43. package/dist/api/routes/squads.d.ts.map +1 -0
  44. package/dist/api/routes/squads.js +129 -0
  45. package/dist/api/routes/squads.js.map +1 -0
  46. package/dist/api/routes/usage.d.ts +3 -0
  47. package/dist/api/routes/usage.d.ts.map +1 -0
  48. package/dist/api/routes/usage.js +55 -0
  49. package/dist/api/routes/usage.js.map +1 -0
  50. package/dist/api/routes/wiki.d.ts +2 -0
  51. package/dist/api/routes/wiki.d.ts.map +1 -0
  52. package/dist/api/routes/wiki.js +43 -0
  53. package/dist/api/routes/wiki.js.map +1 -0
  54. package/dist/api/server.d.ts +7 -0
  55. package/dist/api/server.d.ts.map +1 -0
  56. package/dist/api/server.js +136 -634
  57. package/dist/api/server.js.map +1 -0
  58. package/dist/config.d.ts +3 -0
  59. package/dist/config.d.ts.map +1 -0
  60. package/dist/config.js +2 -91
  61. package/dist/config.js.map +1 -0
  62. package/dist/copilot/client.d.ts +5 -0
  63. package/dist/copilot/client.d.ts.map +1 -0
  64. package/dist/copilot/client.js +19 -11
  65. package/dist/copilot/client.js.map +1 -0
  66. package/dist/copilot/health-monitor.d.ts +14 -0
  67. package/dist/copilot/health-monitor.d.ts.map +1 -0
  68. package/dist/copilot/health-monitor.js +70 -0
  69. package/dist/copilot/health-monitor.js.map +1 -0
  70. package/dist/copilot/orchestrator.d.ts +5 -0
  71. package/dist/copilot/orchestrator.d.ts.map +1 -0
  72. package/dist/copilot/orchestrator.js +127 -123
  73. package/dist/copilot/orchestrator.js.map +1 -0
  74. package/dist/copilot/tools.d.ts +49 -0
  75. package/dist/copilot/tools.d.ts.map +1 -0
  76. package/dist/copilot/tools.js +545 -321
  77. package/dist/copilot/tools.js.map +1 -0
  78. package/dist/index.d.ts +3 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +82 -26
  81. package/dist/index.js.map +1 -0
  82. package/dist/logging/logger.d.ts +6 -0
  83. package/dist/logging/logger.d.ts.map +1 -0
  84. package/dist/logging/logger.js +21 -0
  85. package/dist/logging/logger.js.map +1 -0
  86. package/dist/models/index.d.ts +6 -0
  87. package/dist/models/index.d.ts.map +1 -0
  88. package/dist/models/index.js +4 -0
  89. package/dist/models/index.js.map +1 -0
  90. package/dist/models/pricing.d.ts +25 -0
  91. package/dist/models/pricing.d.ts.map +1 -0
  92. package/dist/models/pricing.js +96 -0
  93. package/dist/models/pricing.js.map +1 -0
  94. package/dist/models/registry.d.ts +34 -0
  95. package/dist/models/registry.d.ts.map +1 -0
  96. package/dist/models/registry.js +109 -0
  97. package/dist/models/registry.js.map +1 -0
  98. package/dist/models/token-tracker.d.ts +40 -0
  99. package/dist/models/token-tracker.d.ts.map +1 -0
  100. package/dist/models/token-tracker.js +102 -0
  101. package/dist/models/token-tracker.js.map +1 -0
  102. package/dist/scheduler/engine.d.ts +9 -0
  103. package/dist/scheduler/engine.d.ts.map +1 -0
  104. package/dist/scheduler/engine.js +127 -0
  105. package/dist/scheduler/engine.js.map +1 -0
  106. package/dist/skills/index.d.ts +3 -0
  107. package/dist/skills/index.d.ts.map +1 -0
  108. package/dist/skills/index.js +2 -0
  109. package/dist/skills/index.js.map +1 -0
  110. package/dist/skills/store.d.ts +52 -0
  111. package/dist/skills/store.d.ts.map +1 -0
  112. package/dist/skills/store.js +148 -0
  113. package/dist/skills/store.js.map +1 -0
  114. package/dist/squad/agent.d.ts +46 -0
  115. package/dist/squad/agent.d.ts.map +1 -0
  116. package/dist/squad/agent.js +261 -0
  117. package/dist/squad/agent.js.map +1 -0
  118. package/dist/squad/autonomy.d.ts +16 -0
  119. package/dist/squad/autonomy.d.ts.map +1 -0
  120. package/dist/squad/autonomy.js +63 -0
  121. package/dist/squad/autonomy.js.map +1 -0
  122. package/dist/squad/event-bus.d.ts +22 -0
  123. package/dist/squad/event-bus.d.ts.map +1 -0
  124. package/dist/squad/event-bus.js +56 -0
  125. package/dist/squad/event-bus.js.map +1 -0
  126. package/dist/squad/execution/index.d.ts +12 -0
  127. package/dist/squad/execution/index.d.ts.map +1 -0
  128. package/dist/squad/execution/index.js +7 -0
  129. package/dist/squad/execution/index.js.map +1 -0
  130. package/dist/squad/execution/instance.d.ts +40 -0
  131. package/dist/squad/execution/instance.d.ts.map +1 -0
  132. package/dist/squad/execution/instance.js +138 -0
  133. package/dist/squad/execution/instance.js.map +1 -0
  134. package/dist/squad/execution/meeting.d.ts +25 -0
  135. package/dist/squad/execution/meeting.d.ts.map +1 -0
  136. package/dist/squad/execution/meeting.js +140 -0
  137. package/dist/squad/execution/meeting.js.map +1 -0
  138. package/dist/squad/execution/pr.d.ts +15 -0
  139. package/dist/squad/execution/pr.d.ts.map +1 -0
  140. package/dist/squad/execution/pr.js +93 -0
  141. package/dist/squad/execution/pr.js.map +1 -0
  142. package/dist/squad/execution/runner.d.ts +22 -0
  143. package/dist/squad/execution/runner.d.ts.map +1 -0
  144. package/dist/squad/execution/runner.js +68 -0
  145. package/dist/squad/execution/runner.js.map +1 -0
  146. package/dist/squad/execution/tasks.d.ts +11 -0
  147. package/dist/squad/execution/tasks.d.ts.map +1 -0
  148. package/dist/squad/execution/tasks.js +85 -0
  149. package/dist/squad/execution/tasks.js.map +1 -0
  150. package/dist/squad/execution/worktree.d.ts +26 -0
  151. package/dist/squad/execution/worktree.d.ts.map +1 -0
  152. package/dist/squad/execution/worktree.js +111 -0
  153. package/dist/squad/execution/worktree.js.map +1 -0
  154. package/dist/squad/hiring.d.ts +32 -0
  155. package/dist/squad/hiring.d.ts.map +1 -0
  156. package/dist/squad/hiring.js +200 -0
  157. package/dist/squad/hiring.js.map +1 -0
  158. package/dist/squad/index.d.ts +8 -0
  159. package/dist/squad/index.d.ts.map +1 -0
  160. package/dist/squad/index.js +6 -0
  161. package/dist/squad/index.js.map +1 -0
  162. package/dist/squad/manager.d.ts +48 -0
  163. package/dist/squad/manager.d.ts.map +1 -0
  164. package/dist/squad/manager.js +274 -0
  165. package/dist/squad/manager.js.map +1 -0
  166. package/dist/squad/name-generator.d.ts +16 -0
  167. package/dist/squad/name-generator.d.ts.map +1 -0
  168. package/dist/squad/name-generator.js +113 -0
  169. package/dist/squad/name-generator.js.map +1 -0
  170. package/dist/squad/roles/templates.d.ts +5 -0
  171. package/dist/squad/roles/templates.d.ts.map +1 -0
  172. package/dist/squad/roles/templates.js +102 -0
  173. package/dist/squad/roles/templates.js.map +1 -0
  174. package/dist/squad/skill-parser.d.ts +36 -0
  175. package/dist/squad/skill-parser.d.ts.map +1 -0
  176. package/dist/squad/skill-parser.js +83 -0
  177. package/dist/squad/skill-parser.js.map +1 -0
  178. package/dist/squad/source-resolver.d.ts +20 -0
  179. package/dist/squad/source-resolver.d.ts.map +1 -0
  180. package/dist/squad/source-resolver.js +52 -0
  181. package/dist/squad/source-resolver.js.map +1 -0
  182. package/dist/store/activity.d.ts +43 -0
  183. package/dist/store/activity.d.ts.map +1 -0
  184. package/dist/store/activity.js +131 -0
  185. package/dist/store/activity.js.map +1 -0
  186. package/dist/store/db.d.ts +5 -0
  187. package/dist/store/db.d.ts.map +1 -0
  188. package/dist/store/db.js +209 -248
  189. package/dist/store/db.js.map +1 -0
  190. package/dist/store/inbox.d.ts +53 -0
  191. package/dist/store/inbox.d.ts.map +1 -0
  192. package/dist/store/inbox.js +151 -0
  193. package/dist/store/inbox.js.map +1 -0
  194. package/dist/store/schedules.d.ts +53 -0
  195. package/dist/store/schedules.d.ts.map +1 -0
  196. package/dist/store/schedules.js +149 -54
  197. package/dist/store/schedules.js.map +1 -0
  198. package/dist/wiki/index.d.ts +3 -0
  199. package/dist/wiki/index.d.ts.map +1 -0
  200. package/dist/wiki/index.js +2 -0
  201. package/dist/wiki/index.js.map +1 -0
  202. package/dist/wiki/store.d.ts +49 -0
  203. package/dist/wiki/store.d.ts.map +1 -0
  204. package/dist/wiki/store.js +115 -0
  205. package/dist/wiki/store.js.map +1 -0
  206. package/node_modules/@io/shared/dist/config.d.ts +25 -0
  207. package/node_modules/@io/shared/dist/config.d.ts.map +1 -0
  208. package/node_modules/@io/shared/dist/config.js +47 -0
  209. package/node_modules/@io/shared/dist/config.js.map +1 -0
  210. package/node_modules/@io/shared/dist/constants.d.ts +13 -0
  211. package/node_modules/@io/shared/dist/constants.d.ts.map +1 -0
  212. package/node_modules/@io/shared/dist/constants.js +34 -0
  213. package/node_modules/@io/shared/dist/constants.js.map +1 -0
  214. package/node_modules/@io/shared/dist/index.d.ts +11 -0
  215. package/node_modules/@io/shared/dist/index.d.ts.map +1 -0
  216. package/node_modules/@io/shared/dist/index.js +3 -0
  217. package/node_modules/@io/shared/dist/index.js.map +1 -0
  218. package/node_modules/@io/shared/dist/types/agents.d.ts +3 -0
  219. package/node_modules/@io/shared/dist/types/agents.d.ts.map +1 -0
  220. package/node_modules/@io/shared/dist/types/agents.js +2 -0
  221. package/node_modules/@io/shared/dist/types/agents.js.map +1 -0
  222. package/node_modules/@io/shared/dist/types/api.d.ts +33 -0
  223. package/node_modules/@io/shared/dist/types/api.d.ts.map +1 -0
  224. package/node_modules/@io/shared/dist/types/api.js +2 -0
  225. package/node_modules/@io/shared/dist/types/api.js.map +1 -0
  226. package/node_modules/@io/shared/dist/types/attachments.d.ts +10 -0
  227. package/node_modules/@io/shared/dist/types/attachments.d.ts.map +1 -0
  228. package/node_modules/@io/shared/dist/types/attachments.js +2 -0
  229. package/node_modules/@io/shared/dist/types/attachments.js.map +1 -0
  230. package/node_modules/@io/shared/dist/types/events.d.ts +44 -0
  231. package/node_modules/@io/shared/dist/types/events.d.ts.map +1 -0
  232. package/node_modules/@io/shared/dist/types/events.js +2 -0
  233. package/node_modules/@io/shared/dist/types/events.js.map +1 -0
  234. package/node_modules/@io/shared/dist/types/messages.d.ts +15 -0
  235. package/node_modules/@io/shared/dist/types/messages.d.ts.map +1 -0
  236. package/node_modules/@io/shared/dist/types/messages.js +2 -0
  237. package/node_modules/@io/shared/dist/types/messages.js.map +1 -0
  238. package/node_modules/@io/shared/dist/types/squads.d.ts +43 -0
  239. package/node_modules/@io/shared/dist/types/squads.d.ts.map +1 -0
  240. package/node_modules/@io/shared/dist/types/squads.js +2 -0
  241. package/node_modules/@io/shared/dist/types/squads.js.map +1 -0
  242. package/node_modules/@io/shared/dist/types/tokens.d.ts +19 -0
  243. package/node_modules/@io/shared/dist/types/tokens.d.ts.map +1 -0
  244. package/node_modules/@io/shared/dist/types/tokens.js +2 -0
  245. package/node_modules/@io/shared/dist/types/tokens.js.map +1 -0
  246. package/node_modules/@io/shared/package.json +18 -0
  247. package/node_modules/@io/shared/src/config.ts +74 -0
  248. package/node_modules/@io/shared/src/constants.ts +36 -0
  249. package/node_modules/@io/shared/src/index.ts +37 -0
  250. package/node_modules/@io/shared/src/types/agents.ts +3 -0
  251. package/node_modules/@io/shared/src/types/api.ts +35 -0
  252. package/node_modules/@io/shared/src/types/attachments.ts +9 -0
  253. package/node_modules/@io/shared/src/types/events.ts +81 -0
  254. package/node_modules/@io/shared/src/types/messages.ts +15 -0
  255. package/node_modules/@io/shared/src/types/squads.ts +53 -0
  256. package/node_modules/@io/shared/src/types/tokens.ts +19 -0
  257. package/node_modules/@io/shared/tsconfig.json +9 -0
  258. package/node_modules/@io/shared/tsconfig.tsbuildinfo +1 -0
  259. package/package.json +56 -59
  260. package/src/api/middleware/auth.ts +76 -0
  261. package/src/api/notifications.ts +122 -0
  262. package/src/api/routes/activity.ts +29 -0
  263. package/src/api/routes/attachments.ts +93 -0
  264. package/src/api/routes/config.ts +115 -0
  265. package/src/api/routes/conversations.ts +87 -0
  266. package/src/api/routes/health.ts +18 -0
  267. package/src/api/routes/inbox.ts +98 -0
  268. package/src/api/routes/schedules.ts +121 -0
  269. package/src/api/routes/skills.ts +105 -0
  270. package/src/api/routes/squads.ts +145 -0
  271. package/src/api/routes/usage.ts +57 -0
  272. package/src/api/routes/wiki.ts +49 -0
  273. package/src/api/server.ts +186 -0
  274. package/src/config.ts +3 -0
  275. package/src/copilot/client.ts +42 -0
  276. package/src/copilot/health-monitor.ts +85 -0
  277. package/src/copilot/orchestrator.ts +222 -0
  278. package/src/copilot/tools.ts +707 -0
  279. package/src/index.ts +112 -0
  280. package/src/logging/logger.ts +26 -0
  281. package/src/models/index.ts +11 -0
  282. package/src/models/pricing.ts +121 -0
  283. package/src/models/registry.ts +131 -0
  284. package/src/models/token-tracker.ts +151 -0
  285. package/src/scheduler/engine.ts +146 -0
  286. package/src/skills/index.ts +13 -0
  287. package/src/skills/store.ts +188 -0
  288. package/src/squad/agent.ts +326 -0
  289. package/src/squad/autonomy.ts +78 -0
  290. package/src/squad/event-bus.ts +71 -0
  291. package/src/squad/execution/index.ts +17 -0
  292. package/src/squad/execution/instance.ts +186 -0
  293. package/src/squad/execution/meeting.ts +191 -0
  294. package/src/squad/execution/pr.ts +127 -0
  295. package/src/squad/execution/runner.ts +97 -0
  296. package/src/squad/execution/tasks.ts +111 -0
  297. package/src/squad/execution/worktree.ts +138 -0
  298. package/src/squad/hiring.ts +222 -0
  299. package/src/squad/index.ts +17 -0
  300. package/src/squad/manager.ts +337 -0
  301. package/src/squad/name-generator.ts +135 -0
  302. package/src/squad/roles/templates.ts +104 -0
  303. package/src/squad/skill-parser.ts +120 -0
  304. package/src/squad/source-resolver.ts +57 -0
  305. package/src/store/activity.ts +176 -0
  306. package/src/store/db.ts +237 -0
  307. package/src/store/inbox.ts +199 -0
  308. package/src/store/schedules.ts +199 -0
  309. package/src/wiki/index.ts +12 -0
  310. package/src/wiki/store.ts +139 -0
  311. package/tsconfig.json +9 -0
  312. package/LICENSE +0 -21
  313. package/dist/api/auth.js +0 -46
  314. package/dist/chat/attachments.js +0 -112
  315. package/dist/copilot/agents.js +0 -309
  316. package/dist/copilot/ceremonies.js +0 -174
  317. package/dist/copilot/gh-token.js +0 -64
  318. package/dist/copilot/io-scheduler.js +0 -79
  319. package/dist/copilot/model-router.js +0 -114
  320. package/dist/copilot/scheduler.js +0 -88
  321. package/dist/copilot/skills.js +0 -252
  322. package/dist/copilot/specialist-runner.js +0 -191
  323. package/dist/copilot/squad-tools.js +0 -258
  324. package/dist/copilot/system-message.js +0 -86
  325. package/dist/copilot/token-tracker.js +0 -98
  326. package/dist/copilot/trigger-schedule.js +0 -33
  327. package/dist/daemon.js +0 -67
  328. package/dist/logging.js +0 -27
  329. package/dist/mcp/config.js +0 -29
  330. package/dist/mcp/index.js +0 -3
  331. package/dist/mcp/registry.js +0 -42
  332. package/dist/notify.js +0 -25
  333. package/dist/paths.js +0 -17
  334. package/dist/setup.js +0 -35
  335. package/dist/store/agent-events.js +0 -19
  336. package/dist/store/audit-log.js +0 -71
  337. package/dist/store/conversations.js +0 -164
  338. package/dist/store/feed.js +0 -44
  339. package/dist/store/instances.js +0 -75
  340. package/dist/store/squad-colors.js +0 -23
  341. package/dist/store/squads.js +0 -60
  342. package/dist/store/tasks.js +0 -78
  343. package/dist/store/token-usage.js +0 -94
  344. package/dist/telegram/bot.js +0 -41
  345. package/dist/telegram/handlers.js +0 -42
  346. package/dist/watchdog.js +0 -37
  347. package/dist/wiki/backlinks.js +0 -51
  348. package/dist/wiki/fs.js +0 -108
  349. package/dist/wiki/search.js +0 -47
  350. package/web-dist/assets/AuditLogView-BzfjNXBT.js +0 -6
  351. package/web-dist/assets/ChatView-BdMukPKG.js +0 -1
  352. package/web-dist/assets/FeedView-BfPIabGr.js +0 -6
  353. package/web-dist/assets/HistoryView-BmEEk3Rs.js +0 -1
  354. package/web-dist/assets/LoginView-D7LrkeX7.js +0 -1
  355. package/web-dist/assets/McpView-BAP_ah3T.js +0 -1
  356. package/web-dist/assets/SchedulesView-CAtsUPCZ.js +0 -6
  357. package/web-dist/assets/SettingsView-BovjWZDa.js +0 -1
  358. package/web-dist/assets/SkillsView-DQSMM5LN.js +0 -16
  359. package/web-dist/assets/SquadDetailView-DBscu0m2.js +0 -26
  360. package/web-dist/assets/SquadHealthView-D686BuQo.js +0 -11
  361. package/web-dist/assets/SquadsView-AzMht2NJ.js +0 -6
  362. package/web-dist/assets/ToggleSwitch.vue_vue_type_script_setup_true_lang-DtShZAjW.js +0 -1
  363. package/web-dist/assets/UsageView-DiVn97aI.js +0 -16
  364. package/web-dist/assets/WikiView-Cn7KipkZ.js +0 -26
  365. package/web-dist/assets/api-D4mHJ3u0.js +0 -1
  366. package/web-dist/assets/arrow-left-D_qUNUWW.js +0 -6
  367. package/web-dist/assets/git-branch-DOM-orcl.js +0 -6
  368. package/web-dist/assets/index-Bo83B1LR.css +0 -1
  369. package/web-dist/assets/index-ELvnkQjd.js +0 -273
  370. package/web-dist/assets/pencil-CFsi7ufI.js +0 -6
  371. package/web-dist/assets/plus-BAzlGFd_.js +0 -6
  372. package/web-dist/assets/save-BmgCYJ1g.js +0 -6
  373. package/web-dist/assets/search-CS9zSIeW.js +0 -6
  374. package/web-dist/assets/squad-colors-B8B_Y-lz.js +0 -1
  375. package/web-dist/assets/trash-2-DLveUEsd.js +0 -6
  376. package/web-dist/assets/triangle-alert-lj4I30rL.js +0 -6
  377. package/web-dist/assets/x-CjXR97Fa.js +0 -6
  378. package/web-dist/favicon.svg +0 -10
  379. package/web-dist/index.html +0 -14
  380. package/web-dist/logo.svg +0 -10
@@ -1,114 +0,0 @@
1
- import { loadConfig } from "../config.js";
2
- import { getClient } from "./client.js";
3
- import { logWarn } from "../logging.js";
4
- // Cache discovered models so we don't call listModels() on every task
5
- let discoveredModels;
6
- /**
7
- * Built-in model capability hints. Used as fallback when billing info
8
- * isn't available from the SDK. Higher = more capable.
9
- */
10
- const MODEL_CAPABILITY_HINTS = {
11
- "claude-opus-4.7": 90,
12
- "claude-opus-4.6": 88,
13
- "claude-opus-4.5": 85,
14
- "gpt-5.5": 87,
15
- "gpt-5.4": 84,
16
- "gpt-5.3-codex": 83,
17
- "gpt-5.2-codex": 82,
18
- "gpt-5.2": 80,
19
- "claude-sonnet-4.6": 70,
20
- "claude-sonnet-4.5": 68,
21
- "gpt-4.1": 65,
22
- "claude-haiku-4.5": 40,
23
- "gpt-5.4-mini": 42,
24
- "gpt-5-mini": 38,
25
- };
26
- /**
27
- * Discover available models from the Copilot SDK and score them.
28
- * Uses billing multiplier as primary capability signal, falls back to
29
- * built-in hints for unknown models.
30
- */
31
- export async function discoverModels() {
32
- if (discoveredModels)
33
- return discoveredModels;
34
- try {
35
- const client = await getClient();
36
- const models = await client.listModels();
37
- discoveredModels = models
38
- .filter((m) => !m.policy || m.policy.state === "enabled")
39
- .map((m) => ({
40
- id: m.id,
41
- // Use billing multiplier as capability proxy (higher cost = more capable)
42
- // Fall back to built-in hints, then default of 50
43
- score: m.billing
44
- ? Math.min(m.billing.multiplier * 10, 100)
45
- : (MODEL_CAPABILITY_HINTS[m.id] ?? 50),
46
- }))
47
- .sort((a, b) => b.score - a.score);
48
- }
49
- catch (err) {
50
- logWarn("Failed to discover models from SDK, falling back to configured default model", {}, err);
51
- // SDK discovery failed — fall back to defaultModel only
52
- const config = loadConfig();
53
- discoveredModels = [{ id: config.defaultModel, score: 65 }];
54
- }
55
- return discoveredModels;
56
- }
57
- /** Reset cached models (e.g. after client reconnect) */
58
- export function resetModelCache() {
59
- discoveredModels = undefined;
60
- }
61
- /**
62
- * Select the best available model for a given task complexity.
63
- * Discovers models from the Copilot SDK and picks based on capability —
64
- * zero configuration required.
65
- */
66
- export async function selectModel(complexity) {
67
- const config = loadConfig();
68
- const scored = await discoverModels();
69
- if (scored.length === 0)
70
- return config.defaultModel;
71
- if (complexity === "high") {
72
- // Most capable model
73
- return scored[0].id;
74
- }
75
- if (complexity === "low") {
76
- // Cheapest model
77
- return scored[scored.length - 1].id;
78
- }
79
- // Medium — pick a model around the middle of the ranked list
80
- const midIdx = Math.floor(scored.length / 2);
81
- return scored[midIdx].id;
82
- }
83
- export function classifyComplexity(task) {
84
- const lower = task.toLowerCase();
85
- const highPatterns = [
86
- "architect",
87
- "design system",
88
- "refactor",
89
- "security audit",
90
- "performance optimization",
91
- "migration",
92
- "complex",
93
- "deep analysis",
94
- "debug",
95
- "race condition",
96
- ];
97
- if (highPatterns.some((p) => lower.includes(p)))
98
- return "high";
99
- const lowPatterns = [
100
- "format",
101
- "rename",
102
- "typo",
103
- "simple",
104
- "lookup",
105
- "list",
106
- "read",
107
- "status",
108
- "check",
109
- ];
110
- if (lowPatterns.some((p) => lower.includes(p)))
111
- return "low";
112
- return "medium";
113
- }
114
- //# sourceMappingURL=model-router.js.map
@@ -1,88 +0,0 @@
1
- import { listSchedules, updateScheduleLastRun } from "../store/schedules.js";
2
- import { delegateTask } from "./agents.js";
3
- import { addAuditEntry } from "../store/audit-log.js";
4
- let schedulerInterval;
5
- export function startSquadScheduler() {
6
- // Check every minute for due schedules
7
- schedulerInterval = setInterval(() => {
8
- checkSquadSchedules();
9
- }, 60_000);
10
- schedulerInterval.unref();
11
- }
12
- function checkSquadSchedules() {
13
- const schedules = listSchedules("squad");
14
- const now = new Date();
15
- for (const schedule of schedules) {
16
- if (!schedule.enabled)
17
- continue;
18
- if (!isDue(schedule.cron, schedule.last_run, now))
19
- continue;
20
- if (!schedule.squad_id) {
21
- console.warn(`[scheduler] Schedule ${schedule.id} skipped: missing squad_id.`);
22
- continue;
23
- }
24
- const squadId = schedule.squad_id;
25
- updateScheduleLastRun(schedule.id);
26
- const task = schedule.prompt || `Run "triage" stand-up. Agenda: triage`;
27
- addAuditEntry("schedule_triggered", `Schedule triggered for squad ${squadId}: ${task.slice(0, 200)}`, { squad_id: squadId, schedule_id: schedule.id, task: task.slice(0, 1000) }, { squad_id: squadId });
28
- // Delegate directly to the squad lead — bypasses orchestrator rephrasing
29
- delegateTask(squadId, task).catch((err) => {
30
- const errMsg = err instanceof Error ? err.message : "Unknown error";
31
- console.error(`[scheduler] Delegation failed for squad ${squadId}: ${errMsg}`);
32
- addAuditEntry("schedule_error", `Scheduled delegation failed: ${errMsg}`, { squad_id: squadId, error: errMsg }, { squad_id: squadId });
33
- });
34
- console.log(`[scheduler] Task delegated to squad ${squadId}`);
35
- }
36
- }
37
- function isDue(cron, lastRun, now) {
38
- // Simple cron matching: parse "minute hour day month weekday"
39
- const parts = cron.split(" ");
40
- if (parts.length !== 5)
41
- return false;
42
- const [minSpec, hourSpec, daySpec, monthSpec, weekdaySpec] = parts;
43
- if (!matchesCronField(minSpec, now.getMinutes()))
44
- return false;
45
- if (!matchesCronField(hourSpec, now.getHours()))
46
- return false;
47
- if (!matchesCronField(daySpec, now.getDate()))
48
- return false;
49
- if (!matchesCronField(monthSpec, now.getMonth() + 1))
50
- return false;
51
- if (!matchesCronField(weekdaySpec, now.getDay()))
52
- return false;
53
- // Prevent running more than once per matching minute
54
- if (lastRun) {
55
- const lastDate = new Date(lastRun);
56
- const diffMs = now.getTime() - lastDate.getTime();
57
- if (diffMs < 60_000)
58
- return false;
59
- }
60
- return true;
61
- }
62
- function matchesCronField(spec, value) {
63
- if (spec === "*")
64
- return true;
65
- // Handle ranges (e.g., "1-5")
66
- if (spec.includes("-")) {
67
- const [start, end] = spec.split("-").map(Number);
68
- return value >= start && value <= end;
69
- }
70
- // Handle lists (e.g., "1,3,5")
71
- if (spec.includes(",")) {
72
- return spec.split(",").map(Number).includes(value);
73
- }
74
- // Handle step values (e.g., "*/5")
75
- if (spec.startsWith("*/")) {
76
- const step = parseInt(spec.slice(2), 10);
77
- return value % step === 0;
78
- }
79
- // Exact match
80
- return parseInt(spec, 10) === value;
81
- }
82
- export function stopSquadScheduler() {
83
- if (schedulerInterval) {
84
- clearInterval(schedulerInterval);
85
- schedulerInterval = undefined;
86
- }
87
- }
88
- //# sourceMappingURL=scheduler.js.map
@@ -1,252 +0,0 @@
1
- import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
2
- import { join, basename, resolve, sep } from "node:path";
3
- import { execFile } from "node:child_process";
4
- import { promisify } from "node:util";
5
- import { PATHS } from "../paths.js";
6
- const execFileAsync = promisify(execFile);
7
- export async function listSkills() {
8
- if (!existsSync(PATHS.skills))
9
- return [];
10
- const entries = readdirSync(PATHS.skills, { withFileTypes: true });
11
- const skills = [];
12
- for (const entry of entries) {
13
- if (!entry.isDirectory())
14
- continue;
15
- const skillMd = join(PATHS.skills, entry.name, "SKILL.md");
16
- if (!existsSync(skillMd))
17
- continue;
18
- const content = readFileSync(skillMd, "utf-8");
19
- const firstLine = content.split("\n").find((l) => l.startsWith("# "));
20
- const name = firstLine?.replace(/^#\s+/, "") ?? entry.name;
21
- const descLine = content
22
- .split("\n")
23
- .find((l) => l.trim() && !l.startsWith("#"));
24
- const description = descLine?.trim() ?? "";
25
- skills.push({
26
- name,
27
- slug: entry.name,
28
- description,
29
- path: join(PATHS.skills, entry.name),
30
- });
31
- }
32
- return skills;
33
- }
34
- export async function addSkill(url) {
35
- const slug = basename(url, ".git").replace(/[^a-z0-9-]/gi, "-").toLowerCase();
36
- const dest = join(PATHS.skills, slug);
37
- if (existsSync(dest)) {
38
- throw new Error(`Skill "${slug}" is already installed.`);
39
- }
40
- await execFileAsync("git", ["clone", "--depth", "1", "--", url, dest]);
41
- // Verify SKILL.md exists
42
- if (!existsSync(join(dest, "SKILL.md"))) {
43
- rmSync(dest, { recursive: true, force: true });
44
- throw new Error("Repository does not contain a SKILL.md file.");
45
- }
46
- }
47
- export async function removeSkill(slug) {
48
- const dest = join(PATHS.skills, slug);
49
- if (!existsSync(dest)) {
50
- throw new Error(`Skill "${slug}" not found.`);
51
- }
52
- rmSync(dest, { recursive: true, force: true });
53
- }
54
- export async function getSkillContent(slug) {
55
- const skillMd = join(PATHS.skills, slug, "SKILL.md");
56
- if (!existsSync(skillMd)) {
57
- throw new Error(`Skill "${slug}" not found.`);
58
- }
59
- return readFileSync(skillMd, "utf-8");
60
- }
61
- export async function updateSkillContent(slug, content) {
62
- const skillMd = join(PATHS.skills, slug, "SKILL.md");
63
- if (!existsSync(join(PATHS.skills, slug))) {
64
- throw new Error(`Skill "${slug}" not found.`);
65
- }
66
- writeFileSync(skillMd, content);
67
- }
68
- export async function createSkill(slug, content) {
69
- const cleanSlug = slug
70
- .trim()
71
- .replace(/[^a-z0-9-]/gi, "-")
72
- .toLowerCase()
73
- .replace(/-+/g, "-")
74
- .replace(/^-|-$/g, "");
75
- if (!cleanSlug) {
76
- throw new Error("Skill title must contain at least one alphanumeric character.");
77
- }
78
- // Guard against path traversal: the resolved destination must be a direct
79
- // child of the skills directory (not above or beside it).
80
- const skillsRoot = resolve(PATHS.skills);
81
- const dest = resolve(skillsRoot, cleanSlug);
82
- if (!dest.startsWith(skillsRoot + sep)) {
83
- throw new Error("Invalid skill slug.");
84
- }
85
- if (existsSync(dest)) {
86
- throw new Error(`Skill "${cleanSlug}" already exists.`);
87
- }
88
- mkdirSync(dest, { recursive: true });
89
- writeFileSync(join(dest, "SKILL.md"), content);
90
- }
91
- export async function loadSkillDirectories() {
92
- if (!existsSync(PATHS.skills))
93
- return [];
94
- const entries = readdirSync(PATHS.skills, { withFileTypes: true });
95
- return entries
96
- .filter((e) => e.isDirectory() && existsSync(join(PATHS.skills, e.name, "SKILL.md")))
97
- .map((e) => join(PATHS.skills, e.name));
98
- }
99
- export const GITHUB_REPO_PATH = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
100
- export function isGitHubRepoPath(value) {
101
- return GITHUB_REPO_PATH.test(value.trim());
102
- }
103
- const DISCOVERY_CACHE = new Map();
104
- const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
105
- /** Validate and return a safe slug, throwing if it contains unsafe characters. */
106
- function validateSlug(slug) {
107
- if (!slug || !/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/i.test(slug)) {
108
- throw new Error("Invalid skill slug: must contain only letters, digits, and hyphens.");
109
- }
110
- return slug;
111
- }
112
- function parseAwesomeCopilotTable(markdown) {
113
- const skills = [];
114
- for (const line of markdown.split("\n")) {
115
- if (!line.startsWith("|"))
116
- continue;
117
- const cells = line
118
- .split("|")
119
- .map((c) => c.trim())
120
- .filter(Boolean);
121
- if (cells.length < 2)
122
- continue;
123
- // First cell contains [slug](../skills/slug/SKILL.md)
124
- const slugMatch = cells[0].match(/^\[([^\]]+)\]/);
125
- if (!slugMatch)
126
- continue;
127
- const slug = slugMatch[1];
128
- if (slug === "Name")
129
- continue; // header row
130
- // Second cell is the description (may contain <br /> markup)
131
- const description = cells[1]
132
- .replace(/<br\s*\/?>/gi, " ")
133
- .replace(/\*\*([^*]+)\*\*/g, "$1")
134
- .trim();
135
- if (!description || description === "Description")
136
- continue;
137
- skills.push({ slug, name: slug, description, source: "awesome-copilot" });
138
- }
139
- return skills;
140
- }
141
- async function fetchAwesomeCopilotSkills() {
142
- const url = "https://raw.githubusercontent.com/github/awesome-copilot/main/docs/README.skills.md";
143
- const res = await fetch(url, { signal: AbortSignal.timeout(15_000) });
144
- if (!res.ok)
145
- throw new Error(`Failed to fetch awesome-copilot skills list: HTTP ${res.status}`);
146
- const text = await res.text();
147
- return parseAwesomeCopilotTable(text);
148
- }
149
- async function fetchSkillsShSkills(query) {
150
- try {
151
- const searchQuery = query?.trim() || "";
152
- const url = `https://skills.sh/api/search?q=${encodeURIComponent(searchQuery)}`;
153
- const res = await fetch(url, {
154
- headers: { Accept: "application/json" },
155
- signal: AbortSignal.timeout(10_000),
156
- });
157
- if (!res.ok)
158
- return [];
159
- const data = (await res.json());
160
- return data.skills
161
- .map((item) => ({
162
- slug: item.skillId || item.name || "",
163
- name: item.name || item.skillId || "",
164
- description: "",
165
- source: "skillssh",
166
- sourceRepo: item.source,
167
- installs: item.installs,
168
- }))
169
- .filter((item) => item.sourceRepo ? isGitHubRepoPath(item.sourceRepo) : false);
170
- }
171
- catch {
172
- return [];
173
- }
174
- }
175
- export async function discoverSkills(source, query) {
176
- // For skills.sh, use the search API directly with the query
177
- if (source === "skillssh") {
178
- return fetchSkillsShSkills(query);
179
- }
180
- // For awesome-copilot, use caching and client-side filtering
181
- const cached = DISCOVERY_CACHE.get(source);
182
- let skills;
183
- if (cached && Date.now() - cached.fetchedAt < CACHE_TTL_MS) {
184
- skills = cached.skills;
185
- }
186
- else {
187
- skills = await fetchAwesomeCopilotSkills();
188
- DISCOVERY_CACHE.set(source, { skills, fetchedAt: Date.now() });
189
- }
190
- if (query) {
191
- const q = query.toLowerCase();
192
- skills = skills.filter((s) => s.slug.toLowerCase().includes(q) || s.description.toLowerCase().includes(q));
193
- }
194
- return skills;
195
- }
196
- /**
197
- * Find the path to SKILL.md in a GitHub repo by searching the repo tree.
198
- * Returns the full path (e.g., "skills/features/clerk-testing/SKILL.md").
199
- */
200
- async function findSkillPathInRepo(repoPath, skillId) {
201
- const treeUrl = `https://api.github.com/repos/${repoPath}/git/trees/main?recursive=1`;
202
- const res = await fetch(treeUrl, { signal: AbortSignal.timeout(10_000) });
203
- if (!res.ok) {
204
- throw new Error(`Failed to fetch repo tree for "${repoPath}": HTTP ${res.status}`);
205
- }
206
- const data = (await res.json());
207
- // Look for a SKILL.md file in a folder named after the skillId
208
- const targetSuffix = `${skillId}/SKILL.md`;
209
- const match = data.tree.find((item) => item.type === "blob" && item.path.endsWith(targetSuffix));
210
- if (!match) {
211
- throw new Error(`Could not find SKILL.md for "${skillId}" in repo "${repoPath}"`);
212
- }
213
- return match.path;
214
- }
215
- function remoteSkillMdUrl(source, safeSlug) {
216
- const encodedSlug = encodeURIComponent(safeSlug);
217
- if (source === "awesome-copilot") {
218
- return `https://raw.githubusercontent.com/github/awesome-copilot/main/skills/${encodedSlug}/SKILL.md`;
219
- }
220
- // Legacy fallback for skillssh without sourceRepo (shouldn't be used anymore)
221
- return `https://skills.sh/skills/${encodedSlug}/SKILL.md`;
222
- }
223
- export async function fetchRemoteSkillPreview(source, slug, sourceRepo) {
224
- const safeSlug = validateSlug(slug);
225
- // For skillssh with a sourceRepo, use GitHub directly
226
- if (source === "skillssh" && sourceRepo) {
227
- const skillPath = await findSkillPathInRepo(sourceRepo, safeSlug);
228
- const rawUrl = `https://raw.githubusercontent.com/${sourceRepo}/main/${skillPath}`;
229
- const res = await fetch(rawUrl, { signal: AbortSignal.timeout(10_000) });
230
- if (!res.ok) {
231
- throw new Error(`Failed to fetch preview for "${safeSlug}": HTTP ${res.status}`);
232
- }
233
- return res.text();
234
- }
235
- // Fallback to legacy URL approach
236
- const url = remoteSkillMdUrl(source, safeSlug);
237
- const res = await fetch(url, { signal: AbortSignal.timeout(10_000) });
238
- if (!res.ok)
239
- throw new Error(`Failed to fetch preview for "${safeSlug}": HTTP ${res.status}`);
240
- return res.text();
241
- }
242
- export async function installFromSource(source, slug, sourceRepo) {
243
- const safeSlug = validateSlug(slug);
244
- const dest = join(PATHS.skills, safeSlug);
245
- if (existsSync(dest)) {
246
- throw new Error(`Skill "${safeSlug}" is already installed.`);
247
- }
248
- const content = await fetchRemoteSkillPreview(source, safeSlug, sourceRepo);
249
- mkdirSync(dest, { recursive: true });
250
- writeFileSync(join(dest, "SKILL.md"), content);
251
- }
252
- //# sourceMappingURL=skills.js.map
@@ -1,191 +0,0 @@
1
- import { approveAll } from "@github/copilot-sdk";
2
- import { getClient } from "./client.js";
3
- import { selectModel, classifyComplexity } from "./model-router.js";
4
- import { attachTokenTracker } from "./token-tracker.js";
5
- import { createSquadTools } from "./squad-tools.js";
6
- import { loadSkillDirectories } from "./skills.js";
7
- import { getMcpServersForSession } from "../mcp/registry.js";
8
- import { addAgentEvent } from "../store/agent-events.js";
9
- import { addAuditEntry } from "../store/audit-log.js";
10
- import { updateAgentStatus } from "../store/squads.js";
11
- import { touchInstanceActivity } from "../store/instances.js";
12
- /**
13
- * Build the system message for a specialist agent session.
14
- * Wiki knowledge is placed at the END for maximum LLM attention (recency bias).
15
- */
16
- function buildSpecialistSystemMessage(agent, squad, wikiKnowledge, roster) {
17
- return `# Squad Specialist: ${agent.character_name}
18
-
19
- ## 🚨 CRITICAL SECURITY RULE — ABSOLUTE, NON-NEGOTIABLE 🚨
20
-
21
- You must NEVER expose secrets, credentials, or sensitive values in ANY publicly visible location. This includes:
22
- - GitHub issues, pull requests, PR descriptions, comments, or commit messages
23
- - Log output, error messages, or stack traces shared externally
24
- - Wiki pages, feed items, or any content viewable by others
25
-
26
- What counts as a secret: API keys, access tokens, passwords, connection strings, environment variable values, private config file contents, SSH keys, certificates, webhook URLs with tokens.
27
-
28
- If you need to reference that a secret exists, use \`<REDACTED>\` or \`***\` as a placeholder. NEVER include the actual value.
29
-
30
- Violation of this rule is a HARD FAILURE — no exceptions, no workarounds, no "just this once."
31
-
32
- ## Identity & Role
33
-
34
- You are **${agent.character_name}**, a **${agent.role_title}** on the ${squad.name} squad.
35
- You are an independent specialist — you execute implementation work within your domain of expertise.
36
-
37
- ## Your Responsibilities:
38
- 1. Execute the assigned sub-task fully and correctly
39
- 2. Write clean, tested, production-quality code
40
- 3. Follow project conventions and existing patterns
41
- 4. Commit work to the appropriate branch
42
- 5. Report completion or blockers clearly
43
-
44
- ## Squad Wiki = Your Source of Truth
45
- Your squad wiki contains workflow rules set by the project owner. Read it (use \`wiki_read\`) and follow those rules exactly — branching, PR process, review format, merge criteria. If your task involves reviewing a PR, follow the wiki's review process precisely.
46
-
47
- ## Your Team (for context):
48
- ${roster}
49
-
50
- ## Workflow Rules:
51
- - Always use the gh CLI for GitHub interactions
52
- - Use \`--comment\` with "LGTM" for approvals (not \`--approve\`)
53
- - When your work is complete, provide a clear summary of what was done
54
- - Consult the squad wiki (wiki_read) for additional context when needed
55
- - Follow all squad rules from the wiki — they are non-negotiable
56
- ${wikiKnowledge}
57
- ${agent.persona ? `## Personality:\n${agent.persona}` : ""}
58
- `;
59
- }
60
- /**
61
- * Run a specialist agent session independently.
62
- * Creates a full Copilot SDK session with tools, executes the task, returns the result.
63
- */
64
- export async function runSpecialistSession(request) {
65
- const { agent, squad, squadSlug, squadId, task, wikiKnowledge, workDir, instanceId, parentTaskId } = request;
66
- // Select model based on task complexity
67
- const tier = classifyComplexity(task);
68
- const model = await selectModel(tier);
69
- // Build roster for context
70
- const { getAgentsForSquad } = await import("../store/squads.js");
71
- const agents = getAgentsForSquad(squadId);
72
- const roster = agents
73
- .map((a) => `- ${a.character_name} (${a.role_title})${a.is_lead ? " [LEAD]" : ""}${a.is_qa ? " [QA]" : ""}${a.is_test ? " [TEST]" : ""}`)
74
- .join("\n");
75
- const systemMessage = buildSpecialistSystemMessage(agent, squad, wikiKnowledge, roster);
76
- // Update agent status
77
- updateAgentStatus(agent.id, "working");
78
- // Touch instance activity
79
- if (instanceId) {
80
- touchInstanceActivity(instanceId);
81
- }
82
- // Audit: specialist task started
83
- addAuditEntry("specialist_task_started", `Specialist task delegated to ${agent.character_name} (${agent.role_title})`, { task: task.slice(0, 500), model, parentTaskId }, { squad_id: squadId, agent_id: agent.id });
84
- addAgentEvent(parentTaskId, "status", `Sub-task delegated to specialist ${agent.character_name} (${agent.role_title})`, {
85
- agent: agent.character_name,
86
- role: agent.role_title,
87
- task: task.slice(0, 300),
88
- });
89
- const client = await getClient();
90
- try {
91
- // Load squad-scoped tools, skills, and MCP servers
92
- const squadTools = createSquadTools(squadSlug, squadId, squad.repo_url);
93
- const skillDirs = await loadSkillDirectories();
94
- const mcpServers = getMcpServersForSession();
95
- const session = await client.createSession({
96
- model,
97
- streaming: true,
98
- workingDirectory: workDir,
99
- systemMessage: { content: systemMessage },
100
- tools: squadTools,
101
- skillDirectories: skillDirs,
102
- mcpServers,
103
- onPermissionRequest: approveAll,
104
- infiniteSessions: {
105
- enabled: true,
106
- backgroundCompactionThreshold: 0.8,
107
- bufferExhaustionThreshold: 0.95,
108
- },
109
- });
110
- const flushTokens = attachTokenTracker(session, {
111
- squadId,
112
- agentId: agent.id,
113
- taskId: parentTaskId,
114
- });
115
- // Stream deltas and broadcast via SSE
116
- let accumulatedMessage = "";
117
- const { broadcast } = await import("../api/server.js");
118
- const unsubscribeDelta = session.on("assistant.message_delta", (event) => {
119
- const delta = event.data?.deltaContent ?? "";
120
- if (delta) {
121
- accumulatedMessage += delta;
122
- broadcast("agent_event", {
123
- taskId: parentTaskId,
124
- agentName: agent.character_name,
125
- type: "specialist_delta",
126
- summary: accumulatedMessage,
127
- payload: { delta, accumulated: accumulatedMessage },
128
- });
129
- }
130
- });
131
- let result;
132
- try {
133
- const response = await session.sendAndWait({ prompt: `You have been assigned the following sub-task by your team lead:\n\n${task}\n\nExecute this task fully. When done, provide a clear summary of what was accomplished.` }, 7_200_000 // 2 hours — watchdog handles stale detection
134
- );
135
- result = response?.data?.content ?? "Task completed (no response content).";
136
- }
137
- finally {
138
- unsubscribeDelta();
139
- flushTokens();
140
- await session.disconnect();
141
- }
142
- // Record completion
143
- addAgentEvent(parentTaskId, "status", `Specialist ${agent.character_name} completed sub-task`, {
144
- agent: agent.character_name,
145
- role: agent.role_title,
146
- result: result.slice(0, 500),
147
- });
148
- addAuditEntry("specialist_task_completed", `Specialist ${agent.character_name} completed task`, { result: result.slice(0, 500) }, { squad_id: squadId, agent_id: agent.id });
149
- updateAgentStatus(agent.id, "idle");
150
- return {
151
- agentName: agent.character_name,
152
- role: agent.role_title,
153
- success: true,
154
- result,
155
- };
156
- }
157
- catch (err) {
158
- const errMsg = err instanceof Error ? err.message : "Unknown error";
159
- addAgentEvent(parentTaskId, "status", `Specialist ${agent.character_name} failed: ${errMsg}`, {
160
- agent: agent.character_name,
161
- error: errMsg,
162
- });
163
- addAuditEntry("specialist_task_failed", `Specialist ${agent.character_name} failed: ${errMsg.slice(0, 200)}`, { error: errMsg }, { squad_id: squadId, agent_id: agent.id });
164
- updateAgentStatus(agent.id, "idle");
165
- return {
166
- agentName: agent.character_name,
167
- role: agent.role_title,
168
- success: false,
169
- result: `Error: ${errMsg}`,
170
- };
171
- }
172
- }
173
- /**
174
- * Run multiple specialist sessions in parallel.
175
- * Returns results in the same order as the input requests.
176
- */
177
- export async function runSpecialistsParallel(requests) {
178
- const results = await Promise.allSettled(requests.map(runSpecialistSession));
179
- return results.map((r, i) => {
180
- if (r.status === "fulfilled") {
181
- return r.value;
182
- }
183
- return {
184
- agentName: requests[i].agent.character_name,
185
- role: requests[i].agent.role_title,
186
- success: false,
187
- result: `Session error: ${r.reason instanceof Error ? r.reason.message : "Unknown error"}`,
188
- };
189
- });
190
- }
191
- //# sourceMappingURL=specialist-runner.js.map