@hailer/mcp 1.1.14 → 1.1.16

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 (713) hide show
  1. package/.claude/CLAUDE.md +370 -0
  2. package/.claude/agents/agent-ada-skill-builder.md +94 -0
  3. package/.claude/agents/agent-alejandro-function-fields.md +342 -0
  4. package/.claude/agents/agent-bjorn-config-audit.md +103 -0
  5. package/.claude/agents/agent-builder-agent-creator.md +130 -0
  6. package/.claude/agents/agent-code-simplifier.md +53 -0
  7. package/.claude/agents/agent-dmitri-activity-crud.md +159 -0
  8. package/.claude/agents/agent-giuseppe-app-builder.md +208 -0
  9. package/.claude/agents/agent-gunther-mcp-tools.md +39 -0
  10. package/.claude/agents/agent-helga-workflow-config.md +204 -0
  11. package/.claude/agents/agent-igor-activity-mover-automation.md +125 -0
  12. package/.claude/agents/agent-ingrid-doc-templates.md +261 -0
  13. package/.claude/agents/agent-ivan-monolith.md +154 -0
  14. package/.claude/agents/agent-kenji-data-reader.md +86 -0
  15. package/.claude/agents/agent-lars-code-inspector.md +102 -0
  16. package/.claude/agents/agent-marco-mockup-builder.md +110 -0
  17. package/.claude/agents/agent-marcus-api-documenter.md +323 -0
  18. package/.claude/agents/agent-marketplace-publisher.md +280 -0
  19. package/.claude/agents/agent-marketplace-reviewer.md +309 -0
  20. package/.claude/agents/agent-permissions-handler.md +208 -0
  21. package/.claude/agents/agent-simple-writer.md +48 -0
  22. package/.claude/agents/agent-svetlana-code-review.md +171 -0
  23. package/.claude/agents/agent-tanya-test-runner.md +333 -0
  24. package/.claude/agents/agent-ui-designer.md +100 -0
  25. package/.claude/agents/agent-viktor-sql-insights.md +212 -0
  26. package/.claude/agents/agent-web-search.md +55 -0
  27. package/.claude/agents/agent-yevgeni-discussions.md +45 -0
  28. package/.claude/agents/agent-zara-zapier.md +159 -0
  29. package/.claude/agents/ragnar.md +68 -0
  30. package/.claude/commands/app-squad.md +135 -0
  31. package/.claude/commands/audit-squad.md +158 -0
  32. package/.claude/commands/autoplan.md +563 -0
  33. package/.claude/commands/cleanup-squad.md +98 -0
  34. package/.claude/commands/config-squad.md +106 -0
  35. package/.claude/commands/crud-squad.md +87 -0
  36. package/.claude/commands/data-squad.md +97 -0
  37. package/.claude/commands/debug-squad.md +303 -0
  38. package/.claude/commands/doc-squad.md +65 -0
  39. package/.claude/commands/handoff.md +137 -0
  40. package/.claude/commands/health.md +49 -0
  41. package/.claude/commands/help.md +29 -0
  42. package/.claude/commands/help:agents.md +151 -0
  43. package/.claude/commands/help:commands.md +78 -0
  44. package/.claude/commands/help:faq.md +79 -0
  45. package/.claude/commands/help:plugins.md +50 -0
  46. package/.claude/commands/help:skills.md +93 -0
  47. package/.claude/commands/help:tools.md +75 -0
  48. package/.claude/commands/hotfix-squad.md +112 -0
  49. package/.claude/commands/integration-squad.md +82 -0
  50. package/.claude/commands/janitor-squad.md +167 -0
  51. package/.claude/commands/learn-auto.md +120 -0
  52. package/.claude/commands/learn.md +120 -0
  53. package/.claude/commands/mcp-list.md +27 -0
  54. package/.claude/commands/onboard-squad.md +140 -0
  55. package/.claude/commands/plan-workspace.md +732 -0
  56. package/.claude/commands/prd.md +130 -0
  57. package/.claude/commands/project-status.md +82 -0
  58. package/.claude/commands/publish.md +138 -0
  59. package/.claude/commands/recap.md +69 -0
  60. package/.claude/commands/restore.md +64 -0
  61. package/.claude/commands/review-squad.md +152 -0
  62. package/.claude/commands/save.md +24 -0
  63. package/.claude/commands/stats.md +19 -0
  64. package/.claude/commands/swarm.md +210 -0
  65. package/.claude/commands/tool-builder.md +39 -0
  66. package/.claude/commands/ws-pull.md +44 -0
  67. package/.claude/skills/SDK-activity-patterns/SKILL.md +428 -0
  68. package/.claude/skills/SDK-document-templates/SKILL.md +1033 -0
  69. package/.claude/skills/SDK-function-fields/SKILL.md +542 -0
  70. package/.claude/skills/SDK-generate-skill/SKILL.md +92 -0
  71. package/.claude/skills/SDK-init-skill/SKILL.md +127 -0
  72. package/.claude/skills/SDK-insight-queries/SKILL.md +787 -0
  73. package/.claude/skills/SDK-ws-config-skill/SKILL.md +1139 -0
  74. package/.claude/skills/agent-structure/SKILL.md +98 -0
  75. package/.claude/skills/api-documentation-patterns/SKILL.md +474 -0
  76. package/.claude/skills/chrome-mcp-reference/SKILL.md +370 -0
  77. package/.claude/skills/delegation-routing/SKILL.md +202 -0
  78. package/.claude/skills/frontend-design/SKILL.md +254 -0
  79. package/.claude/skills/hailer-activity-mover/SKILL.md +213 -0
  80. package/.claude/skills/hailer-api-client/SKILL.md +518 -0
  81. package/.claude/skills/hailer-app-builder/SKILL.md +1440 -0
  82. package/.claude/skills/hailer-apps-pictures/SKILL.md +269 -0
  83. package/.claude/skills/hailer-design-system/SKILL.md +231 -0
  84. package/.claude/skills/hailer-monolith-automations/SKILL.md +686 -0
  85. package/.claude/skills/hailer-permissions-system/SKILL.md +121 -0
  86. package/.claude/skills/hailer-project-protocol/SKILL.md +488 -0
  87. package/.claude/skills/hailer-rest-api/SKILL.md +61 -0
  88. package/.claude/skills/hailer-rest-api/hailer-activities.md +184 -0
  89. package/.claude/skills/hailer-rest-api/hailer-admin.md +473 -0
  90. package/.claude/skills/hailer-rest-api/hailer-calendar.md +256 -0
  91. package/.claude/skills/hailer-rest-api/hailer-feed.md +249 -0
  92. package/.claude/skills/hailer-rest-api/hailer-insights.md +195 -0
  93. package/.claude/skills/hailer-rest-api/hailer-messaging.md +276 -0
  94. package/.claude/skills/hailer-rest-api/hailer-workflows.md +283 -0
  95. package/.claude/skills/insight-join-patterns/SKILL.md +174 -0
  96. package/.claude/skills/integration-patterns/SKILL.md +421 -0
  97. package/.claude/skills/json-only-output/SKILL.md +72 -0
  98. package/.claude/skills/lsp-setup/SKILL.md +160 -0
  99. package/.claude/skills/mcp-direct-tools/SKILL.md +153 -0
  100. package/.claude/skills/optional-parameters/SKILL.md +72 -0
  101. package/.claude/skills/publish-hailer-app/SKILL.md +221 -0
  102. package/.claude/skills/testing-patterns/SKILL.md +630 -0
  103. package/.claude/skills/tool-builder/SKILL.md +250 -0
  104. package/.claude/skills/tool-parameter-usage/SKILL.md +126 -0
  105. package/.claude/skills/tool-response-verification/SKILL.md +92 -0
  106. package/.claude/skills/zapier-hailer-patterns/SKILL.md +581 -0
  107. package/.opencode/agent/agent-ada-skill-builder.md +35 -0
  108. package/.opencode/agent/agent-alejandro-function-fields.md +39 -0
  109. package/.opencode/agent/agent-bjorn-config-audit.md +36 -0
  110. package/.opencode/agent/agent-builder-agent-creator.md +39 -0
  111. package/.opencode/agent/agent-code-simplifier.md +31 -0
  112. package/.opencode/agent/agent-dmitri-activity-crud.md +40 -0
  113. package/.opencode/agent/agent-giuseppe-app-builder.md +37 -0
  114. package/.opencode/agent/agent-gunther-mcp-tools.md +39 -0
  115. package/.opencode/agent/agent-helga-workflow-config.md +204 -0
  116. package/.opencode/agent/agent-igor-activity-mover-automation.md +46 -0
  117. package/.opencode/agent/agent-ingrid-doc-templates.md +39 -0
  118. package/.opencode/agent/agent-ivan-monolith.md +46 -0
  119. package/.opencode/agent/agent-kenji-data-reader.md +53 -0
  120. package/.opencode/agent/agent-lars-code-inspector.md +28 -0
  121. package/.opencode/agent/agent-marco-mockup-builder.md +42 -0
  122. package/.opencode/agent/agent-marcus-api-documenter.md +53 -0
  123. package/.opencode/agent/agent-marketplace-publisher.md +44 -0
  124. package/.opencode/agent/agent-marketplace-reviewer.md +42 -0
  125. package/.opencode/agent/agent-permissions-handler.md +50 -0
  126. package/.opencode/agent/agent-simple-writer.md +45 -0
  127. package/.opencode/agent/agent-svetlana-code-review.md +39 -0
  128. package/.opencode/agent/agent-tanya-test-runner.md +57 -0
  129. package/.opencode/agent/agent-ui-designer.md +56 -0
  130. package/.opencode/agent/agent-viktor-sql-insights.md +34 -0
  131. package/.opencode/agent/agent-web-search.md +42 -0
  132. package/.opencode/agent/agent-yevgeni-discussions.md +37 -0
  133. package/.opencode/agent/agent-zara-zapier.md +53 -0
  134. package/.opencode/commands/app-squad.md +135 -0
  135. package/.opencode/commands/audit-squad.md +158 -0
  136. package/.opencode/commands/autoplan.md +563 -0
  137. package/.opencode/commands/cleanup-squad.md +98 -0
  138. package/.opencode/commands/config-squad.md +106 -0
  139. package/.opencode/commands/crud-squad.md +87 -0
  140. package/.opencode/commands/data-squad.md +97 -0
  141. package/.opencode/commands/debug-squad.md +303 -0
  142. package/.opencode/commands/doc-squad.md +65 -0
  143. package/.opencode/commands/handoff.md +137 -0
  144. package/.opencode/commands/health.md +49 -0
  145. package/.opencode/commands/help-agents.md +151 -0
  146. package/.opencode/commands/help-commands.md +32 -0
  147. package/.opencode/commands/help-faq.md +29 -0
  148. package/.opencode/commands/help-plugins.md +28 -0
  149. package/.opencode/commands/help-skills.md +7 -0
  150. package/.opencode/commands/help-tools.md +40 -0
  151. package/.opencode/commands/help.md +28 -0
  152. package/.opencode/commands/hotfix-squad.md +112 -0
  153. package/.opencode/commands/integration-squad.md +82 -0
  154. package/.opencode/commands/janitor-squad.md +167 -0
  155. package/.opencode/commands/learn-auto.md +120 -0
  156. package/.opencode/commands/learn.md +120 -0
  157. package/.opencode/commands/mcp-list.md +27 -0
  158. package/.opencode/commands/onboard-squad.md +140 -0
  159. package/.opencode/commands/plan-workspace.md +732 -0
  160. package/.opencode/commands/prd.md +131 -0
  161. package/.opencode/commands/project-status.md +82 -0
  162. package/.opencode/commands/publish.md +138 -0
  163. package/.opencode/commands/recap.md +69 -0
  164. package/.opencode/commands/restore.md +64 -0
  165. package/.opencode/commands/review-squad.md +152 -0
  166. package/.opencode/commands/save.md +24 -0
  167. package/.opencode/commands/stats.md +19 -0
  168. package/.opencode/commands/swarm.md +210 -0
  169. package/.opencode/commands/tool-builder.md +39 -0
  170. package/.opencode/commands/ws-pull.md +44 -0
  171. package/.opencode/opencode.json +21 -0
  172. package/dist/agents/bot-manager.d.ts +48 -0
  173. package/dist/agents/bot-manager.d.ts.map +1 -0
  174. package/dist/agents/bot-manager.js +254 -0
  175. package/dist/agents/bot-manager.js.map +1 -0
  176. package/dist/agents/bug-fixer/ai.d.ts +80 -0
  177. package/dist/agents/bug-fixer/ai.d.ts.map +1 -0
  178. package/dist/agents/bug-fixer/ai.js +466 -0
  179. package/dist/agents/bug-fixer/ai.js.map +1 -0
  180. package/dist/agents/bug-fixer/bot.d.ts +92 -0
  181. package/dist/agents/bug-fixer/bot.d.ts.map +1 -0
  182. package/dist/agents/bug-fixer/bot.js +687 -0
  183. package/dist/agents/bug-fixer/bot.js.map +1 -0
  184. package/dist/agents/bug-fixer/config.d.ts +21 -0
  185. package/dist/agents/bug-fixer/config.d.ts.map +1 -0
  186. package/dist/agents/bug-fixer/config.js +218 -0
  187. package/dist/agents/bug-fixer/config.js.map +1 -0
  188. package/dist/agents/bug-fixer/files.d.ts +67 -0
  189. package/dist/agents/bug-fixer/files.d.ts.map +1 -0
  190. package/dist/agents/bug-fixer/files.js +386 -0
  191. package/dist/agents/bug-fixer/files.js.map +1 -0
  192. package/dist/agents/bug-fixer/git.d.ts +48 -0
  193. package/dist/agents/bug-fixer/git.d.ts.map +1 -0
  194. package/dist/agents/bug-fixer/git.js +298 -0
  195. package/dist/agents/bug-fixer/git.js.map +1 -0
  196. package/dist/agents/bug-fixer/index.d.ts +103 -0
  197. package/dist/agents/bug-fixer/index.d.ts.map +1 -0
  198. package/dist/agents/bug-fixer/index.js +262 -0
  199. package/dist/agents/bug-fixer/index.js.map +1 -0
  200. package/dist/agents/bug-fixer/lsp.d.ts +113 -0
  201. package/dist/agents/bug-fixer/lsp.d.ts.map +1 -0
  202. package/dist/agents/bug-fixer/lsp.js +485 -0
  203. package/dist/agents/bug-fixer/lsp.js.map +1 -0
  204. package/dist/agents/bug-fixer/monitor.d.ts +123 -0
  205. package/dist/agents/bug-fixer/monitor.d.ts.map +1 -0
  206. package/dist/agents/bug-fixer/monitor.js +629 -0
  207. package/dist/agents/bug-fixer/monitor.js.map +1 -0
  208. package/dist/agents/bug-fixer/prompt.d.ts +5 -0
  209. package/dist/agents/bug-fixer/prompt.d.ts.map +1 -0
  210. package/dist/agents/bug-fixer/prompt.js +94 -0
  211. package/dist/agents/bug-fixer/prompt.js.map +1 -0
  212. package/dist/agents/bug-fixer/registries/pending-classification.d.ts +28 -0
  213. package/dist/agents/bug-fixer/registries/pending-classification.d.ts.map +1 -0
  214. package/dist/agents/bug-fixer/registries/pending-classification.js +50 -0
  215. package/dist/agents/bug-fixer/registries/pending-classification.js.map +1 -0
  216. package/dist/agents/bug-fixer/registries/pending-fix.d.ts +33 -0
  217. package/dist/agents/bug-fixer/registries/pending-fix.d.ts.map +1 -0
  218. package/dist/agents/bug-fixer/registries/pending-fix.js +64 -0
  219. package/dist/agents/bug-fixer/registries/pending-fix.js.map +1 -0
  220. package/dist/agents/bug-fixer/registries/pending.d.ts +27 -0
  221. package/dist/agents/bug-fixer/registries/pending.d.ts.map +1 -0
  222. package/dist/agents/bug-fixer/registries/pending.js +49 -0
  223. package/dist/agents/bug-fixer/registries/pending.js.map +1 -0
  224. package/dist/agents/bug-fixer/specialist-daemon.d.ts +88 -0
  225. package/dist/agents/bug-fixer/specialist-daemon.d.ts.map +1 -0
  226. package/dist/agents/bug-fixer/specialist-daemon.js +431 -0
  227. package/dist/agents/bug-fixer/specialist-daemon.js.map +1 -0
  228. package/dist/agents/bug-fixer/specialist.d.ts +47 -0
  229. package/dist/agents/bug-fixer/specialist.d.ts.map +1 -0
  230. package/dist/agents/bug-fixer/specialist.js +327 -0
  231. package/dist/agents/bug-fixer/specialist.js.map +1 -0
  232. package/dist/agents/bug-fixer/types.d.ts +123 -0
  233. package/dist/agents/bug-fixer/types.d.ts.map +1 -0
  234. package/dist/agents/bug-fixer/types.js +9 -0
  235. package/dist/agents/bug-fixer/types.js.map +1 -0
  236. package/dist/agents/factory.d.ts +172 -0
  237. package/dist/agents/factory.d.ts.map +1 -0
  238. package/dist/agents/factory.js +706 -0
  239. package/dist/agents/factory.js.map +1 -0
  240. package/dist/agents/hailer-expert/index.d.ts +8 -0
  241. package/dist/agents/hailer-expert/index.d.ts.map +1 -0
  242. package/dist/agents/hailer-expert/index.js +14 -0
  243. package/dist/agents/hailer-expert/index.js.map +1 -0
  244. package/dist/agents/hal/daemon.d.ts +174 -0
  245. package/dist/agents/hal/daemon.d.ts.map +1 -0
  246. package/dist/agents/hal/daemon.js +1385 -0
  247. package/dist/agents/hal/daemon.js.map +1 -0
  248. package/dist/agents/hal/definitions.d.ts +42 -0
  249. package/dist/agents/hal/definitions.d.ts.map +1 -0
  250. package/dist/agents/hal/definitions.js +300 -0
  251. package/dist/agents/hal/definitions.js.map +1 -0
  252. package/dist/agents/hal/index.d.ts +3 -0
  253. package/dist/agents/hal/index.d.ts.map +1 -0
  254. package/dist/agents/hal/index.js +8 -0
  255. package/dist/agents/hal/index.js.map +1 -0
  256. package/dist/agents/index.d.ts +18 -0
  257. package/dist/agents/index.d.ts.map +1 -0
  258. package/dist/agents/index.js +48 -0
  259. package/dist/agents/index.js.map +1 -0
  260. package/dist/agents/shared/base.d.ts +253 -0
  261. package/dist/agents/shared/base.d.ts.map +1 -0
  262. package/dist/agents/shared/base.js +1122 -0
  263. package/dist/agents/shared/base.js.map +1 -0
  264. package/dist/agents/shared/schemas/action-schema.d.ts +62 -0
  265. package/dist/agents/shared/schemas/action-schema.d.ts.map +1 -0
  266. package/dist/agents/shared/schemas/action-schema.js +483 -0
  267. package/dist/agents/shared/schemas/action-schema.js.map +1 -0
  268. package/dist/agents/shared/services/agent-registry.d.ts +108 -0
  269. package/dist/agents/shared/services/agent-registry.d.ts.map +1 -0
  270. package/dist/agents/shared/services/agent-registry.js +469 -0
  271. package/dist/agents/shared/services/agent-registry.js.map +1 -0
  272. package/dist/agents/shared/services/conversation-manager.d.ts +57 -0
  273. package/dist/agents/shared/services/conversation-manager.d.ts.map +1 -0
  274. package/dist/agents/shared/services/conversation-manager.js +168 -0
  275. package/dist/agents/shared/services/conversation-manager.js.map +1 -0
  276. package/dist/agents/shared/services/mcp-client.d.ts +56 -0
  277. package/dist/agents/shared/services/mcp-client.d.ts.map +1 -0
  278. package/dist/agents/shared/services/mcp-client.js +124 -0
  279. package/dist/agents/shared/services/mcp-client.js.map +1 -0
  280. package/dist/agents/shared/services/message-classifier.d.ts +37 -0
  281. package/dist/agents/shared/services/message-classifier.d.ts.map +1 -0
  282. package/dist/agents/shared/services/message-classifier.js +203 -0
  283. package/dist/agents/shared/services/message-classifier.js.map +1 -0
  284. package/dist/agents/shared/services/message-formatter.d.ts +89 -0
  285. package/dist/agents/shared/services/message-formatter.d.ts.map +1 -0
  286. package/dist/agents/shared/services/message-formatter.js +390 -0
  287. package/dist/agents/shared/services/message-formatter.js.map +1 -0
  288. package/dist/agents/shared/services/session-logger.d.ts +162 -0
  289. package/dist/agents/shared/services/session-logger.d.ts.map +1 -0
  290. package/dist/agents/shared/services/session-logger.js +724 -0
  291. package/dist/agents/shared/services/session-logger.js.map +1 -0
  292. package/dist/agents/shared/services/structured-output-executor.d.ts +88 -0
  293. package/dist/agents/shared/services/structured-output-executor.d.ts.map +1 -0
  294. package/dist/agents/shared/services/structured-output-executor.js +296 -0
  295. package/dist/agents/shared/services/structured-output-executor.js.map +1 -0
  296. package/dist/agents/shared/services/token-billing.d.ts +72 -0
  297. package/dist/agents/shared/services/token-billing.d.ts.map +1 -0
  298. package/dist/agents/shared/services/token-billing.js +198 -0
  299. package/dist/agents/shared/services/token-billing.js.map +1 -0
  300. package/dist/agents/shared/services/tool-executor.d.ts +43 -0
  301. package/dist/agents/shared/services/tool-executor.d.ts.map +1 -0
  302. package/dist/agents/shared/services/tool-executor.js +175 -0
  303. package/dist/agents/shared/services/tool-executor.js.map +1 -0
  304. package/dist/agents/shared/services/typing-indicator.d.ts +24 -0
  305. package/dist/agents/shared/services/typing-indicator.d.ts.map +1 -0
  306. package/dist/agents/shared/services/typing-indicator.js +54 -0
  307. package/dist/agents/shared/services/typing-indicator.js.map +1 -0
  308. package/dist/agents/shared/services/workspace-schema-cache.d.ts +122 -0
  309. package/dist/agents/shared/services/workspace-schema-cache.d.ts.map +1 -0
  310. package/dist/agents/shared/services/workspace-schema-cache.js +507 -0
  311. package/dist/agents/shared/services/workspace-schema-cache.js.map +1 -0
  312. package/dist/agents/shared/specialist.d.ts +91 -0
  313. package/dist/agents/shared/specialist.d.ts.map +1 -0
  314. package/dist/agents/shared/specialist.js +399 -0
  315. package/dist/agents/shared/specialist.js.map +1 -0
  316. package/dist/agents/shared/tool-schema-loader.d.ts +65 -0
  317. package/dist/agents/shared/tool-schema-loader.d.ts.map +1 -0
  318. package/dist/agents/shared/tool-schema-loader.js +238 -0
  319. package/dist/agents/shared/tool-schema-loader.js.map +1 -0
  320. package/dist/agents/shared/types.d.ts +190 -0
  321. package/dist/agents/shared/types.d.ts.map +1 -0
  322. package/dist/agents/shared/types.js +13 -0
  323. package/dist/agents/shared/types.js.map +1 -0
  324. package/dist/app.d.ts.map +1 -0
  325. package/dist/app.js.map +1 -0
  326. package/dist/bot/bot-config.d.ts.map +1 -0
  327. package/dist/bot/bot-config.js.map +1 -0
  328. package/dist/bot/bot-manager.d.ts.map +1 -0
  329. package/dist/bot/bot-manager.js.map +1 -0
  330. package/dist/bot/bot.d.ts.map +1 -0
  331. package/dist/bot/bot.js.map +1 -0
  332. package/dist/bot/operation-logger.d.ts.map +1 -0
  333. package/dist/bot/operation-logger.js.map +1 -0
  334. package/dist/bot/services/__tests__/permission-guard.test.d.ts +2 -0
  335. package/dist/bot/services/__tests__/permission-guard.test.d.ts.map +1 -0
  336. package/dist/bot/services/__tests__/permission-guard.test.js +357 -0
  337. package/dist/bot/services/__tests__/permission-guard.test.js.map +1 -0
  338. package/dist/bot/services/conversation-manager.d.ts.map +1 -0
  339. package/dist/bot/services/conversation-manager.js.map +1 -0
  340. package/dist/bot/services/index.d.ts.map +1 -0
  341. package/dist/bot/services/index.js.map +1 -0
  342. package/dist/bot/services/message-classifier.d.ts.map +1 -0
  343. package/dist/bot/services/message-classifier.js.map +1 -0
  344. package/dist/bot/services/message-formatter.d.ts.map +1 -0
  345. package/dist/bot/services/message-formatter.js.map +1 -0
  346. package/dist/bot/services/permission-guard.d.ts.map +1 -0
  347. package/dist/bot/services/permission-guard.js.map +1 -0
  348. package/dist/bot/services/session-logger.d.ts.map +1 -0
  349. package/dist/bot/services/session-logger.js.map +1 -0
  350. package/dist/bot/services/token-billing.d.ts.map +1 -0
  351. package/dist/bot/services/token-billing.js.map +1 -0
  352. package/dist/bot/services/types.d.ts.map +1 -0
  353. package/dist/bot/services/types.js.map +1 -0
  354. package/dist/bot/services/typing-indicator.d.ts.map +1 -0
  355. package/dist/bot/services/typing-indicator.js.map +1 -0
  356. package/dist/bot/services/workspace-schema-cache.d.ts.map +1 -0
  357. package/dist/bot/services/workspace-schema-cache.js.map +1 -0
  358. package/dist/bot/tool-executor.d.ts.map +1 -0
  359. package/dist/bot/tool-executor.js.map +1 -0
  360. package/dist/bot/workspace-overview.d.ts.map +1 -0
  361. package/dist/bot/workspace-overview.js.map +1 -0
  362. package/dist/bot-config/constants.d.ts +42 -0
  363. package/dist/bot-config/constants.d.ts.map +1 -0
  364. package/dist/bot-config/constants.js +118 -0
  365. package/dist/bot-config/constants.js.map +1 -0
  366. package/dist/bot-config/context.d.ts +157 -0
  367. package/dist/bot-config/context.d.ts.map +1 -0
  368. package/dist/bot-config/context.js +475 -0
  369. package/dist/bot-config/context.js.map +1 -0
  370. package/dist/bot-config/index.d.ts +21 -0
  371. package/dist/bot-config/index.d.ts.map +1 -0
  372. package/dist/bot-config/index.js +104 -0
  373. package/dist/bot-config/index.js.map +1 -0
  374. package/dist/bot-config/loader.d.ts +28 -0
  375. package/dist/bot-config/loader.d.ts.map +1 -0
  376. package/dist/bot-config/loader.js +194 -0
  377. package/dist/bot-config/loader.js.map +1 -0
  378. package/dist/bot-config/persistence.d.ts +68 -0
  379. package/dist/bot-config/persistence.d.ts.map +1 -0
  380. package/dist/bot-config/persistence.js +261 -0
  381. package/dist/bot-config/persistence.js.map +1 -0
  382. package/dist/bot-config/state.d.ts +56 -0
  383. package/dist/bot-config/state.d.ts.map +1 -0
  384. package/dist/bot-config/state.js +197 -0
  385. package/dist/bot-config/state.js.map +1 -0
  386. package/dist/bot-config/tools.d.ts +28 -0
  387. package/dist/bot-config/tools.d.ts.map +1 -0
  388. package/dist/bot-config/tools.js +279 -0
  389. package/dist/bot-config/tools.js.map +1 -0
  390. package/dist/bot-config/types.d.ts +45 -0
  391. package/dist/bot-config/types.d.ts.map +1 -0
  392. package/dist/bot-config/types.js +9 -0
  393. package/dist/bot-config/types.js.map +1 -0
  394. package/dist/bot-config/webhooks.d.ts +27 -0
  395. package/dist/bot-config/webhooks.d.ts.map +1 -0
  396. package/dist/bot-config/webhooks.js +212 -0
  397. package/dist/bot-config/webhooks.js.map +1 -0
  398. package/dist/cli.d.ts.map +1 -0
  399. package/dist/cli.js.map +1 -0
  400. package/dist/client/agents/base.d.ts +207 -0
  401. package/dist/client/agents/base.d.ts.map +1 -0
  402. package/dist/client/agents/base.js +744 -0
  403. package/dist/client/agents/base.js.map +1 -0
  404. package/dist/client/agents/definitions.d.ts +53 -0
  405. package/dist/client/agents/definitions.d.ts.map +1 -0
  406. package/dist/client/agents/definitions.js +263 -0
  407. package/dist/client/agents/definitions.js.map +1 -0
  408. package/dist/client/agents/orchestrator.d.ts +141 -0
  409. package/dist/client/agents/orchestrator.d.ts.map +1 -0
  410. package/dist/client/agents/orchestrator.js +1062 -0
  411. package/dist/client/agents/orchestrator.js.map +1 -0
  412. package/dist/client/agents/specialist.d.ts +86 -0
  413. package/dist/client/agents/specialist.d.ts.map +1 -0
  414. package/dist/client/agents/specialist.js +340 -0
  415. package/dist/client/agents/specialist.js.map +1 -0
  416. package/dist/client/bot-entrypoint.d.ts +7 -0
  417. package/dist/client/bot-entrypoint.d.ts.map +1 -0
  418. package/dist/client/bot-entrypoint.js +103 -0
  419. package/dist/client/bot-entrypoint.js.map +1 -0
  420. package/dist/client/bot-manager.d.ts +44 -0
  421. package/dist/client/bot-manager.d.ts.map +1 -0
  422. package/dist/client/bot-manager.js +173 -0
  423. package/dist/client/bot-manager.js.map +1 -0
  424. package/dist/client/bot-runner.d.ts +35 -0
  425. package/dist/client/bot-runner.d.ts.map +1 -0
  426. package/dist/client/bot-runner.js +188 -0
  427. package/dist/client/bot-runner.js.map +1 -0
  428. package/dist/client/chat-agent-daemon.d.ts +464 -0
  429. package/dist/client/chat-agent-daemon.d.ts.map +1 -0
  430. package/dist/client/chat-agent-daemon.js +1774 -0
  431. package/dist/client/chat-agent-daemon.js.map +1 -0
  432. package/dist/client/daemon-factory.d.ts +106 -0
  433. package/dist/client/daemon-factory.d.ts.map +1 -0
  434. package/dist/client/daemon-factory.js +301 -0
  435. package/dist/client/daemon-factory.js.map +1 -0
  436. package/dist/client/factory.d.ts +111 -0
  437. package/dist/client/factory.d.ts.map +1 -0
  438. package/dist/client/factory.js +314 -0
  439. package/dist/client/factory.js.map +1 -0
  440. package/dist/client/index.d.ts +17 -0
  441. package/dist/client/index.d.ts.map +1 -0
  442. package/dist/client/index.js +38 -0
  443. package/dist/client/index.js.map +1 -0
  444. package/dist/client/multi-bot-manager.d.ts +42 -0
  445. package/dist/client/multi-bot-manager.d.ts.map +1 -0
  446. package/dist/client/multi-bot-manager.js +161 -0
  447. package/dist/client/multi-bot-manager.js.map +1 -0
  448. package/dist/client/orchestrator-daemon.d.ts +87 -0
  449. package/dist/client/orchestrator-daemon.d.ts.map +1 -0
  450. package/dist/client/orchestrator-daemon.js +444 -0
  451. package/dist/client/orchestrator-daemon.js.map +1 -0
  452. package/dist/client/server.d.ts +8 -0
  453. package/dist/client/server.d.ts.map +1 -0
  454. package/dist/client/server.js +251 -0
  455. package/dist/client/server.js.map +1 -0
  456. package/dist/client/services/agent-registry.d.ts +108 -0
  457. package/dist/client/services/agent-registry.d.ts.map +1 -0
  458. package/dist/client/services/agent-registry.js +630 -0
  459. package/dist/client/services/agent-registry.js.map +1 -0
  460. package/dist/client/services/conversation-manager.d.ts +50 -0
  461. package/dist/client/services/conversation-manager.d.ts.map +1 -0
  462. package/dist/client/services/conversation-manager.js +136 -0
  463. package/dist/client/services/conversation-manager.js.map +1 -0
  464. package/dist/client/services/mcp-client.d.ts +48 -0
  465. package/dist/client/services/mcp-client.d.ts.map +1 -0
  466. package/dist/client/services/mcp-client.js +105 -0
  467. package/dist/client/services/mcp-client.js.map +1 -0
  468. package/dist/client/services/message-classifier.d.ts +37 -0
  469. package/dist/client/services/message-classifier.d.ts.map +1 -0
  470. package/dist/client/services/message-classifier.js +187 -0
  471. package/dist/client/services/message-classifier.js.map +1 -0
  472. package/dist/client/services/message-formatter.d.ts +84 -0
  473. package/dist/client/services/message-formatter.d.ts.map +1 -0
  474. package/dist/client/services/message-formatter.js +353 -0
  475. package/dist/client/services/message-formatter.js.map +1 -0
  476. package/dist/client/services/session-logger.d.ts +106 -0
  477. package/dist/client/services/session-logger.d.ts.map +1 -0
  478. package/dist/client/services/session-logger.js +446 -0
  479. package/dist/client/services/session-logger.js.map +1 -0
  480. package/dist/client/services/tool-executor.d.ts +41 -0
  481. package/dist/client/services/tool-executor.d.ts.map +1 -0
  482. package/dist/client/services/tool-executor.js +169 -0
  483. package/dist/client/services/tool-executor.js.map +1 -0
  484. package/dist/client/services/workspace-schema-cache.d.ts +149 -0
  485. package/dist/client/services/workspace-schema-cache.d.ts.map +1 -0
  486. package/dist/client/services/workspace-schema-cache.js +732 -0
  487. package/dist/client/services/workspace-schema-cache.js.map +1 -0
  488. package/dist/client/specialist-daemon.d.ts +77 -0
  489. package/dist/client/specialist-daemon.d.ts.map +1 -0
  490. package/dist/client/specialist-daemon.js +197 -0
  491. package/dist/client/specialist-daemon.js.map +1 -0
  492. package/dist/client/specialists.d.ts +53 -0
  493. package/dist/client/specialists.d.ts.map +1 -0
  494. package/dist/client/specialists.js +178 -0
  495. package/dist/client/specialists.js.map +1 -0
  496. package/dist/client/tool-schema-loader.d.ts +62 -0
  497. package/dist/client/tool-schema-loader.d.ts.map +1 -0
  498. package/dist/client/tool-schema-loader.js +232 -0
  499. package/dist/client/tool-schema-loader.js.map +1 -0
  500. package/dist/client/types.d.ts +327 -0
  501. package/dist/client/types.d.ts.map +1 -0
  502. package/dist/client/types.js +121 -0
  503. package/dist/client/types.js.map +1 -0
  504. package/dist/commands/seed-config.d.ts +9 -0
  505. package/dist/commands/seed-config.d.ts.map +1 -0
  506. package/dist/commands/seed-config.js +392 -0
  507. package/dist/commands/seed-config.js.map +1 -0
  508. package/dist/commands/setup.d.ts +11 -0
  509. package/dist/commands/setup.d.ts.map +1 -0
  510. package/dist/commands/setup.js +320 -0
  511. package/dist/commands/setup.js.map +1 -0
  512. package/dist/config.d.ts.map +1 -0
  513. package/dist/config.js.map +1 -0
  514. package/dist/core.d.ts.map +1 -0
  515. package/dist/core.js.map +1 -0
  516. package/dist/lib/discussion-lock.d.ts.map +1 -0
  517. package/dist/lib/discussion-lock.js.map +1 -0
  518. package/dist/lib/logger.d.ts.map +1 -0
  519. package/dist/lib/logger.js.map +1 -0
  520. package/dist/lib/request-logger.d.ts.map +1 -0
  521. package/dist/lib/request-logger.js.map +1 -0
  522. package/dist/mcp/UserContextCache.d.ts.map +1 -0
  523. package/dist/mcp/UserContextCache.js.map +1 -0
  524. package/dist/mcp/auth.d.ts.map +1 -0
  525. package/dist/mcp/auth.js.map +1 -0
  526. package/dist/mcp/hailer-clients.d.ts.map +1 -0
  527. package/dist/mcp/hailer-clients.js.map +1 -0
  528. package/dist/mcp/session-store.d.ts.map +1 -0
  529. package/dist/mcp/session-store.js.map +1 -0
  530. package/dist/mcp/signal-handler.d.ts.map +1 -0
  531. package/dist/mcp/signal-handler.js.map +1 -0
  532. package/dist/mcp/tool-registry.d.ts.map +1 -0
  533. package/dist/mcp/tool-registry.js.map +1 -0
  534. package/dist/mcp/tools/__tests__/discussion-forward.test.d.ts +2 -0
  535. package/dist/mcp/tools/__tests__/discussion-forward.test.d.ts.map +1 -0
  536. package/dist/mcp/tools/__tests__/discussion-forward.test.js +218 -0
  537. package/dist/mcp/tools/__tests__/discussion-forward.test.js.map +1 -0
  538. package/dist/mcp/tools/activity.d.ts.map +1 -0
  539. package/dist/mcp/tools/activity.js.map +1 -0
  540. package/dist/mcp/tools/app-core.d.ts.map +1 -0
  541. package/dist/mcp/tools/app-core.js.map +1 -0
  542. package/dist/mcp/tools/app-marketplace.d.ts.map +1 -0
  543. package/dist/mcp/tools/app-marketplace.js.map +1 -0
  544. package/dist/mcp/tools/app-member.d.ts.map +1 -0
  545. package/dist/mcp/tools/app-member.js.map +1 -0
  546. package/dist/mcp/tools/app-scaffold.d.ts.map +1 -0
  547. package/dist/mcp/tools/app-scaffold.js.map +1 -0
  548. package/dist/mcp/tools/app.d.ts.map +1 -0
  549. package/dist/mcp/tools/app.js.map +1 -0
  550. package/dist/mcp/tools/bot-config/constants.d.ts.map +1 -0
  551. package/dist/mcp/tools/bot-config/constants.js.map +1 -0
  552. package/dist/mcp/tools/bot-config/core.d.ts.map +1 -0
  553. package/dist/mcp/tools/bot-config/core.js.map +1 -0
  554. package/dist/mcp/tools/bot-config/index.d.ts.map +1 -0
  555. package/dist/mcp/tools/bot-config/index.js.map +1 -0
  556. package/dist/mcp/tools/bot-config/tools.d.ts.map +1 -0
  557. package/dist/mcp/tools/bot-config/tools.js.map +1 -0
  558. package/dist/mcp/tools/bot-config/types.d.ts.map +1 -0
  559. package/dist/mcp/tools/bot-config/types.js.map +1 -0
  560. package/dist/mcp/tools/bug-fixer-tools.d.ts.map +1 -0
  561. package/dist/mcp/tools/bug-fixer-tools.js.map +1 -0
  562. package/dist/mcp/tools/company.d.ts.map +1 -0
  563. package/dist/mcp/tools/company.js.map +1 -0
  564. package/dist/mcp/tools/discussion.d.ts.map +1 -0
  565. package/dist/mcp/tools/discussion.js.map +1 -0
  566. package/dist/mcp/tools/document.d.ts.map +1 -0
  567. package/dist/mcp/tools/document.js.map +1 -0
  568. package/dist/mcp/tools/file.d.ts.map +1 -0
  569. package/dist/mcp/tools/file.js.map +1 -0
  570. package/dist/mcp/tools/insight.d.ts.map +1 -0
  571. package/dist/mcp/tools/insight.js.map +1 -0
  572. package/dist/mcp/tools/investigate.d.ts.map +1 -0
  573. package/dist/mcp/tools/investigate.js.map +1 -0
  574. package/dist/mcp/tools/user.d.ts.map +1 -0
  575. package/dist/mcp/tools/user.js.map +1 -0
  576. package/dist/mcp/tools/workflow-permissions.d.ts.map +1 -0
  577. package/dist/mcp/tools/workflow-permissions.js.map +1 -0
  578. package/dist/mcp/tools/workflow.d.ts.map +1 -0
  579. package/dist/mcp/tools/workflow.js.map +1 -0
  580. package/dist/mcp/utils/api-errors.d.ts.map +1 -0
  581. package/dist/mcp/utils/api-errors.js.map +1 -0
  582. package/dist/mcp/utils/data-transformers.d.ts.map +1 -0
  583. package/dist/mcp/utils/data-transformers.js.map +1 -0
  584. package/dist/mcp/utils/file-upload.d.ts.map +1 -0
  585. package/dist/mcp/utils/file-upload.js.map +1 -0
  586. package/dist/mcp/utils/hailer-api-client.d.ts.map +1 -0
  587. package/dist/mcp/utils/hailer-api-client.js.map +1 -0
  588. package/dist/mcp/utils/index.d.ts.map +1 -0
  589. package/dist/mcp/utils/index.js.map +1 -0
  590. package/dist/mcp/utils/logger.d.ts.map +1 -0
  591. package/dist/mcp/utils/logger.js.map +1 -0
  592. package/dist/mcp/utils/pagination.d.ts.map +1 -0
  593. package/dist/mcp/utils/pagination.js.map +1 -0
  594. package/dist/mcp/utils/response-builder.d.ts.map +1 -0
  595. package/dist/mcp/utils/response-builder.js.map +1 -0
  596. package/dist/mcp/utils/role-utils.d.ts.map +1 -0
  597. package/dist/mcp/utils/role-utils.js.map +1 -0
  598. package/dist/mcp/utils/tool-helpers.d.ts.map +1 -0
  599. package/dist/mcp/utils/tool-helpers.js.map +1 -0
  600. package/dist/mcp/utils/types.d.ts.map +1 -0
  601. package/dist/mcp/utils/types.js.map +1 -0
  602. package/dist/mcp/webhook-handler.d.ts.map +1 -0
  603. package/dist/mcp/webhook-handler.js.map +1 -0
  604. package/dist/mcp/workspace-cache.d.ts.map +1 -0
  605. package/dist/mcp/workspace-cache.js.map +1 -0
  606. package/dist/mcp-server.d.ts.map +1 -0
  607. package/dist/mcp-server.js.map +1 -0
  608. package/dist/modules/bug-reports/bug-config.d.ts +25 -0
  609. package/dist/modules/bug-reports/bug-config.d.ts.map +1 -0
  610. package/dist/modules/bug-reports/bug-config.js +187 -0
  611. package/dist/modules/bug-reports/bug-config.js.map +1 -0
  612. package/dist/modules/bug-reports/bug-monitor.d.ts +108 -0
  613. package/dist/modules/bug-reports/bug-monitor.d.ts.map +1 -0
  614. package/dist/modules/bug-reports/bug-monitor.js +510 -0
  615. package/dist/modules/bug-reports/bug-monitor.js.map +1 -0
  616. package/dist/modules/bug-reports/giuseppe-agent.d.ts +58 -0
  617. package/dist/modules/bug-reports/giuseppe-agent.d.ts.map +1 -0
  618. package/dist/modules/bug-reports/giuseppe-agent.js +467 -0
  619. package/dist/modules/bug-reports/giuseppe-agent.js.map +1 -0
  620. package/dist/modules/bug-reports/giuseppe-ai.d.ts +83 -0
  621. package/dist/modules/bug-reports/giuseppe-ai.d.ts.map +1 -0
  622. package/dist/modules/bug-reports/giuseppe-ai.js +466 -0
  623. package/dist/modules/bug-reports/giuseppe-ai.js.map +1 -0
  624. package/dist/modules/bug-reports/giuseppe-bot.d.ts +110 -0
  625. package/dist/modules/bug-reports/giuseppe-bot.d.ts.map +1 -0
  626. package/dist/modules/bug-reports/giuseppe-bot.js +804 -0
  627. package/dist/modules/bug-reports/giuseppe-bot.js.map +1 -0
  628. package/dist/modules/bug-reports/giuseppe-daemon.d.ts +80 -0
  629. package/dist/modules/bug-reports/giuseppe-daemon.d.ts.map +1 -0
  630. package/dist/modules/bug-reports/giuseppe-daemon.js +617 -0
  631. package/dist/modules/bug-reports/giuseppe-daemon.js.map +1 -0
  632. package/dist/modules/bug-reports/giuseppe-files.d.ts +64 -0
  633. package/dist/modules/bug-reports/giuseppe-files.d.ts.map +1 -0
  634. package/dist/modules/bug-reports/giuseppe-files.js +375 -0
  635. package/dist/modules/bug-reports/giuseppe-files.js.map +1 -0
  636. package/dist/modules/bug-reports/giuseppe-git.d.ts +48 -0
  637. package/dist/modules/bug-reports/giuseppe-git.d.ts.map +1 -0
  638. package/dist/modules/bug-reports/giuseppe-git.js +298 -0
  639. package/dist/modules/bug-reports/giuseppe-git.js.map +1 -0
  640. package/dist/modules/bug-reports/giuseppe-lsp.d.ts +113 -0
  641. package/dist/modules/bug-reports/giuseppe-lsp.d.ts.map +1 -0
  642. package/dist/modules/bug-reports/giuseppe-lsp.js +485 -0
  643. package/dist/modules/bug-reports/giuseppe-lsp.js.map +1 -0
  644. package/dist/modules/bug-reports/giuseppe-prompt.d.ts +5 -0
  645. package/dist/modules/bug-reports/giuseppe-prompt.d.ts.map +1 -0
  646. package/dist/modules/bug-reports/giuseppe-prompt.js +94 -0
  647. package/dist/modules/bug-reports/giuseppe-prompt.js.map +1 -0
  648. package/dist/modules/bug-reports/index.d.ts +77 -0
  649. package/dist/modules/bug-reports/index.d.ts.map +1 -0
  650. package/dist/modules/bug-reports/index.js +215 -0
  651. package/dist/modules/bug-reports/index.js.map +1 -0
  652. package/dist/modules/bug-reports/pending-classification-registry.d.ts +28 -0
  653. package/dist/modules/bug-reports/pending-classification-registry.d.ts.map +1 -0
  654. package/dist/modules/bug-reports/pending-classification-registry.js +50 -0
  655. package/dist/modules/bug-reports/pending-classification-registry.js.map +1 -0
  656. package/dist/modules/bug-reports/pending-fix-registry.d.ts +30 -0
  657. package/dist/modules/bug-reports/pending-fix-registry.d.ts.map +1 -0
  658. package/dist/modules/bug-reports/pending-fix-registry.js +42 -0
  659. package/dist/modules/bug-reports/pending-fix-registry.js.map +1 -0
  660. package/dist/modules/bug-reports/pending-registry.d.ts +27 -0
  661. package/dist/modules/bug-reports/pending-registry.d.ts.map +1 -0
  662. package/dist/modules/bug-reports/pending-registry.js +49 -0
  663. package/dist/modules/bug-reports/pending-registry.js.map +1 -0
  664. package/dist/modules/bug-reports/types.d.ts +123 -0
  665. package/dist/modules/bug-reports/types.d.ts.map +1 -0
  666. package/dist/modules/bug-reports/types.js +9 -0
  667. package/dist/modules/bug-reports/types.js.map +1 -0
  668. package/dist/plugins/bug-fixer/index.d.ts.map +1 -0
  669. package/dist/plugins/bug-fixer/index.js.map +1 -0
  670. package/dist/plugins/bug-fixer/tools.d.ts.map +1 -0
  671. package/dist/plugins/bug-fixer/tools.js.map +1 -0
  672. package/dist/plugins/vipunen/__tests__/tools.test.d.ts +10 -0
  673. package/dist/plugins/vipunen/__tests__/tools.test.d.ts.map +1 -0
  674. package/dist/plugins/vipunen/__tests__/tools.test.js +646 -0
  675. package/dist/plugins/vipunen/__tests__/tools.test.js.map +1 -0
  676. package/dist/plugins/vipunen/client.d.ts.map +1 -0
  677. package/dist/plugins/vipunen/client.js.map +1 -0
  678. package/dist/plugins/vipunen/index.d.ts.map +1 -0
  679. package/dist/plugins/vipunen/index.js.map +1 -0
  680. package/dist/plugins/vipunen/tools.d.ts.map +1 -0
  681. package/dist/plugins/vipunen/tools.js.map +1 -0
  682. package/dist/routes/agents.d.ts +44 -0
  683. package/dist/routes/agents.d.ts.map +1 -0
  684. package/dist/routes/agents.js +311 -0
  685. package/dist/routes/agents.js.map +1 -0
  686. package/dist/services/agent-credential-store.d.ts +73 -0
  687. package/dist/services/agent-credential-store.d.ts.map +1 -0
  688. package/dist/services/agent-credential-store.js +212 -0
  689. package/dist/services/agent-credential-store.js.map +1 -0
  690. package/dist/stdio-server.d.ts.map +1 -0
  691. package/dist/stdio-server.js.map +1 -0
  692. package/dist/workspace/context.d.ts +148 -0
  693. package/dist/workspace/context.d.ts.map +1 -0
  694. package/dist/workspace/context.js +339 -0
  695. package/dist/workspace/context.js.map +1 -0
  696. package/dist/workspace/credentials.d.ts +55 -0
  697. package/dist/workspace/credentials.d.ts.map +1 -0
  698. package/dist/workspace/credentials.js +239 -0
  699. package/dist/workspace/credentials.js.map +1 -0
  700. package/dist/workspace/index.d.ts +21 -0
  701. package/dist/workspace/index.d.ts.map +1 -0
  702. package/dist/workspace/index.js +45 -0
  703. package/dist/workspace/index.js.map +1 -0
  704. package/dist/workspace/loader.d.ts +27 -0
  705. package/dist/workspace/loader.d.ts.map +1 -0
  706. package/dist/workspace/loader.js +222 -0
  707. package/dist/workspace/loader.js.map +1 -0
  708. package/dist/workspace/schema.d.ts +37 -0
  709. package/dist/workspace/schema.d.ts.map +1 -0
  710. package/dist/workspace/schema.js +192 -0
  711. package/dist/workspace/schema.js.map +1 -0
  712. package/package.json +13 -1
  713. package/test-billing-server.js +0 -136
@@ -0,0 +1,1385 @@
1
+ "use strict";
2
+ /**
3
+ * Orchestrator Daemon (HAL) - OMNIPOTENT HAILER ASSISTANT
4
+ *
5
+ * The definitive Hailer expert with FULL ACCESS to all 39+ MCP tools.
6
+ * HAL handles EVERYTHING - from simple queries to complex multi-step operations.
7
+ *
8
+ * HAL can:
9
+ * - Full workflow management (create, configure, update fields/phases)
10
+ * - Complete activity operations (CRUD, single and bulk)
11
+ * - SQL insight creation, previewing, and analytics
12
+ * - App management, scaffolding, and deployment
13
+ * - Template and marketplace operations
14
+ * - Discussion management, file handling, user searches
15
+ * - Billing and workspace balance checks
16
+ * - Coordinate specialists for collaborative tasks (rare)
17
+ *
18
+ * Specialists exist but are RARELY needed - HAL handles everything himself first.
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.OrchestratorDaemon = void 0;
22
+ const base_1 = require("../shared/base");
23
+ const definitions_1 = require("./definitions");
24
+ const logger_1 = require("../../lib/logger");
25
+ const pending_fix_1 = require("../bug-fixer/registries/pending-fix");
26
+ const pending_classification_1 = require("../bug-fixer/registries/pending-classification");
27
+ class OrchestratorDaemon extends base_1.ChatAgentDaemon {
28
+ orchestratorLogger;
29
+ specialists = new Map();
30
+ activeSpecialistsInDiscussion = new Map(); // discussionId -> Set<specialistUserId>
31
+ specialistUserIds = new Map(); // specialistKey -> userId
32
+ toolsUsedInCurrentMessage = false; // Track if tools were used in current message processing
33
+ lastToolsUsed = []; // Track which tools were used (for silent success detection)
34
+ lastToolsFailed = false; // Track if any tool failed (to allow error reporting)
35
+ // Tools that should NOT trigger confirmation messages back to source chat (on SUCCESS only)
36
+ static SILENT_SUCCESS_TOOLS = new Set(['join_discussion']);
37
+ // Cross-discussion memory - remembers recent activity context
38
+ lastKnownActivityId = null;
39
+ lastKnownActivityName = null;
40
+ lastKnownActivityTime = 0;
41
+ static CONTEXT_MEMORY_TIMEOUT = 5 * 60 * 1000; // 5 minutes
42
+ constructor(config) {
43
+ super(config);
44
+ this.orchestratorLogger = (0, logger_1.createLogger)({
45
+ component: "OrchestratorDaemon",
46
+ botId: config.botClient.userId,
47
+ });
48
+ // Register specialists from config (make copies to avoid cross-workspace contamination)
49
+ for (const [key, specialist] of Object.entries(definitions_1.SPECIALISTS)) {
50
+ // Clone the specialist so each orchestrator has its own instance
51
+ this.specialists.set(key, { ...specialist });
52
+ }
53
+ // Set specialist user IDs if provided
54
+ if (config.specialistUserIds) {
55
+ this.specialistUserIds = config.specialistUserIds;
56
+ }
57
+ }
58
+ /**
59
+ * Trigger HAL to respond in a discussion with specific context
60
+ * Used when bug monitor needs HAL to naturally inform users about Bug Fixer being disabled
61
+ */
62
+ async respondWithContext(discussionId, activityId, contextMessage) {
63
+ this.orchestratorLogger.info('Triggering contextual response', { discussionId, activityId });
64
+ try {
65
+ // Join the discussion first using MCP tool
66
+ await this.callMcpTool("join_discussion", { activityId });
67
+ // Get workspace ID from bot client cache
68
+ const workspaceId = this.config.botClient.workspaceCache?.currentWorkspace?._id || '';
69
+ // Create a synthetic incoming message with the context
70
+ const syntheticMessage = {
71
+ id: `synthetic-${Date.now()}`,
72
+ discussionId,
73
+ linkedActivityId: activityId,
74
+ workspaceId,
75
+ content: contextMessage,
76
+ senderName: 'System',
77
+ senderId: 'system',
78
+ timestamp: Date.now(),
79
+ priority: 'high',
80
+ priorityReason: 'system_notification',
81
+ isReplyToBot: false,
82
+ isMention: false,
83
+ isDirectMessage: false,
84
+ };
85
+ // Process through normal LLM pipeline
86
+ // This will make HAL respond naturally with the context
87
+ await this['processMessage'](syntheticMessage);
88
+ }
89
+ catch (error) {
90
+ this.orchestratorLogger.error('Failed to respond with context', { error });
91
+ }
92
+ }
93
+ // ===== AGENT DIRECTORY OVERRIDES =====
94
+ /**
95
+ * Override agent name for Agent Directory
96
+ * Uses the actual Hailer user name from BotClient (set in workspace)
97
+ */
98
+ getAgentName() {
99
+ // Use parent implementation which gets name from BotClient
100
+ return super.getAgentName();
101
+ }
102
+ /**
103
+ * Override agent description for Agent Directory
104
+ */
105
+ getAgentDescription() {
106
+ return "HAL - the omnipotent Hailer Assistant. Full access to 39+ MCP tools. Handles everything from simple queries to complex workflows, insights, and bulk operations. Can view apps but cannot create or manage them.";
107
+ }
108
+ /**
109
+ * Override Position details for Orchestrator
110
+ */
111
+ getPositionDetails() {
112
+ return {
113
+ name: "HAL - Omnipotent Hailer Assistant",
114
+ purpose: "THE definitive Hailer expert. Full access to 39+ MCP tools. Handles everything from simple queries to complex workflows, insights, bulk operations, and marketplace operations. Can view apps but cannot create or manage them.",
115
+ personaTone: "Sharp, efficient, and confident. Professional but approachable. Knows the platform inside and out.",
116
+ coreCapabilities: "- Full workflow management (create, configure, update fields/phases)\n- Complete activity operations (CRUD, bulk updates)\n- SQL insight creation and analytics\n- View apps (no creation or management)\n- Template and marketplace operations\n- Discussion management and file handling\n- User management and billing\n- Monitor all workspace discussions\n- Coordinate specialists for collaborative tasks (rare)",
117
+ boundaries: "- Never fabricate data - always use tools\n- Don't share credentials or sensitive config\n- Specialists available but rarely needed",
118
+ };
119
+ }
120
+ /**
121
+ * Full Hailer Expert - HAL can do everything a Hailer power user can do
122
+ */
123
+ getToolWhitelist() {
124
+ return [
125
+ // === WORKFLOW MANAGEMENT ===
126
+ "list_workflows",
127
+ "list_workflow_phases",
128
+ "get_workflow_schema",
129
+ "list_workflows_minimal",
130
+ "install_workflow",
131
+ "update_workflow_field",
132
+ "update_workflow_phase",
133
+ // === ACTIVITY OPERATIONS ===
134
+ "list_activities",
135
+ "show_activity_by_id",
136
+ "count_activities",
137
+ "create_activity",
138
+ "update_activity",
139
+ // === INSIGHT MANAGEMENT ===
140
+ "list_insights",
141
+ "create_insight",
142
+ "preview_insight",
143
+ "get_insight_data",
144
+ "update_insight",
145
+ // === APP MANAGEMENT ===
146
+ "list_apps", // View only
147
+ // === TEMPLATE & MARKETPLACE ===
148
+ "list_templates",
149
+ "get_template",
150
+ "create_template",
151
+ "install_template",
152
+ "publish_template",
153
+ "get_product",
154
+ "get_product_manifest",
155
+ "install_marketplace_app",
156
+ // === DISCUSSION TOOLS ===
157
+ "join_discussion",
158
+ "leave_discussion",
159
+ "add_discussion_message",
160
+ "invite_discussion_members",
161
+ "fetch_discussion_messages",
162
+ "fetch_previous_discussion_messages",
163
+ "get_activity_from_discussion",
164
+ "list_my_discussions",
165
+ // === USER & FILES ===
166
+ "search_workspace_users",
167
+ "download_file",
168
+ "upload_files",
169
+ // === BILLING ===
170
+ "get_workspace_balance",
171
+ // === ADVANCED ===
172
+ "test_function_field",
173
+ ];
174
+ }
175
+ /**
176
+ * Get allowed actions for structured outputs mode
177
+ * Maps to the tool whitelist but includes meta actions
178
+ */
179
+ getAllowedActions() {
180
+ return [
181
+ // Meta actions
182
+ "respond",
183
+ "ignore",
184
+ "invite_specialist",
185
+ // Same as tool whitelist
186
+ ...this.getToolWhitelist(),
187
+ ];
188
+ }
189
+ /**
190
+ * Handle specialist invitation from structured outputs
191
+ * Translates action to existing specialist coordination logic
192
+ */
193
+ async handleSpecialistInvite(specialistKey, context, originalMessage) {
194
+ const specialist = this.specialists.get(specialistKey);
195
+ if (!specialist) {
196
+ this.orchestratorLogger.warn("Unknown specialist requested", { specialistKey });
197
+ // Respond with error
198
+ await this.postResponse(originalMessage.discussionId, `I don't have a specialist available for "${specialistKey}". Available specialists: ${Array.from(this.specialists.keys()).join(", ")}`);
199
+ return;
200
+ }
201
+ // Use existing specialist invitation logic
202
+ await this.inviteSpecialist(specialist, originalMessage.discussionId, context || "");
203
+ }
204
+ /**
205
+ * Preprocess tool input - inject context for certain tools
206
+ * Uses cross-discussion memory to maintain context awareness
207
+ */
208
+ preprocessToolInput(toolName, input) {
209
+ // Force compact output for schema tools (avoid verbose field dumps in discussions)
210
+ if (toolName === "get_workflow_schema") {
211
+ return { ...input, compact: true };
212
+ }
213
+ // Auto-inject sourceActivityId for join_discussion
214
+ if (toolName === "join_discussion") {
215
+ // Debug: Log current context state
216
+ this.orchestratorLogger.debug("join_discussion context check", {
217
+ currentLinkedActivityId: this.currentLinkedActivityId || "none",
218
+ lastKnownActivityId: this.lastKnownActivityId || "none",
219
+ inputSourceActivityId: input.sourceActivityId || "none",
220
+ currentDiscussionId: this.currentDiscussionId || "none",
221
+ });
222
+ if (!input.sourceActivityId) {
223
+ // First try current message's linked activity
224
+ const currentActivityId = this.currentLinkedActivityId;
225
+ // Fall back to recent memory if within timeout
226
+ const memoryStillValid = Date.now() - this.lastKnownActivityTime < OrchestratorDaemon.CONTEXT_MEMORY_TIMEOUT;
227
+ const sourceActivityId = currentActivityId || (memoryStillValid ? this.lastKnownActivityId : null);
228
+ if (sourceActivityId) {
229
+ this.orchestratorLogger.info("Auto-injected sourceActivityId", {
230
+ sourceActivityId,
231
+ fromCurrentMessage: !!currentActivityId,
232
+ fromMemory: !currentActivityId && !!sourceActivityId,
233
+ });
234
+ input = { ...input, sourceActivityId };
235
+ }
236
+ else {
237
+ this.orchestratorLogger.debug("No sourceActivityId available to inject", {
238
+ currentLinkedActivityId: this.currentLinkedActivityId,
239
+ lastKnownActivityId: this.lastKnownActivityId,
240
+ memoryStillValid,
241
+ });
242
+ }
243
+ }
244
+ // Always inject a default welcomeReason if user is being invited
245
+ // This ensures welcome messages are always posted
246
+ if (input.inviteUserId && !input.welcomeReason) {
247
+ const reason = this.lastKnownActivityName
248
+ ? `Added from ${this.lastKnownActivityName} discussion`
249
+ : "Added to this discussion";
250
+ this.orchestratorLogger.debug("Auto-injected welcomeReason", { reason });
251
+ input = { ...input, welcomeReason: reason };
252
+ }
253
+ }
254
+ return input;
255
+ }
256
+ /**
257
+ * Override to detect tool failures for silent success feature
258
+ */
259
+ async executeToolsAndContinue(toolUseBlocks, originalMessage) {
260
+ // Reset failure flag before executing tools
261
+ this.lastToolsFailed = false;
262
+ // Handle local tools (not sent to MCP)
263
+ const localToolResults = [];
264
+ const mcpToolBlocks = [];
265
+ for (const toolBlock of toolUseBlocks) {
266
+ if (toolBlock.name === 'trigger_bug_fixer_retry') {
267
+ // Handle locally - trigger Bug Fixer retry
268
+ const input = toolBlock.input;
269
+ const explanation = input.explanation || '';
270
+ const discussionId = originalMessage.discussionId;
271
+ const pendingFix = pending_fix_1.pendingFixRegistry.getPendingFix(discussionId);
272
+ if (!pendingFix) {
273
+ localToolResults.push({
274
+ type: 'tool_result',
275
+ tool_use_id: toolBlock.id,
276
+ content: 'No pending fix found for this discussion. The fix may have already been approved or cancelled.',
277
+ is_error: true,
278
+ });
279
+ }
280
+ else {
281
+ // Trigger the retry
282
+ const success = await pending_fix_1.pendingFixRegistry.triggerRetry(discussionId, explanation);
283
+ localToolResults.push({
284
+ type: 'tool_result',
285
+ tool_use_id: toolBlock.id,
286
+ content: success
287
+ ? `✅ Triggered Bug Fixer retry with explanation: "${explanation.substring(0, 100)}...". Bug Fixer will analyze and apply a new fix.`
288
+ : '❌ Failed to trigger retry. Bug Fixer may not be available.',
289
+ is_error: !success,
290
+ });
291
+ }
292
+ }
293
+ else if (toolBlock.name === 'confirm_bug_fix') {
294
+ // Handle locally - trigger Bug Fixer fix confirmation
295
+ const discussionId = originalMessage.discussionId;
296
+ const hasPending = pending_classification_1.pendingClassificationRegistry.has(discussionId);
297
+ if (!hasPending) {
298
+ localToolResults.push({
299
+ type: 'tool_result',
300
+ tool_use_id: toolBlock.id,
301
+ content: 'No pending classification found for this discussion. Bug Fixer may have already processed it.',
302
+ is_error: true,
303
+ });
304
+ }
305
+ else {
306
+ const success = await pending_classification_1.pendingClassificationRegistry.triggerFixIt(discussionId);
307
+ localToolResults.push({
308
+ type: 'tool_result',
309
+ tool_use_id: toolBlock.id,
310
+ content: success
311
+ ? '✅ Triggered Bug Fixer to proceed with bug fix.'
312
+ : '❌ Failed to trigger fix. Bug Fixer may not be available.',
313
+ is_error: !success,
314
+ });
315
+ }
316
+ }
317
+ else if (toolBlock.name === 'decline_bug_report') {
318
+ // Handle locally - trigger Bug Fixer decline
319
+ const discussionId = originalMessage.discussionId;
320
+ const hasPending = pending_classification_1.pendingClassificationRegistry.has(discussionId);
321
+ if (!hasPending) {
322
+ localToolResults.push({
323
+ type: 'tool_result',
324
+ tool_use_id: toolBlock.id,
325
+ content: 'No pending classification found for this discussion. Bug Fixer may have already processed it.',
326
+ is_error: true,
327
+ });
328
+ }
329
+ else {
330
+ const success = await pending_classification_1.pendingClassificationRegistry.triggerNotABug(discussionId);
331
+ localToolResults.push({
332
+ type: 'tool_result',
333
+ tool_use_id: toolBlock.id,
334
+ content: success
335
+ ? '✅ Marked as not a bug. Report moved to Declined.'
336
+ : '❌ Failed to decline. Bug Fixer may not be available.',
337
+ is_error: !success,
338
+ });
339
+ }
340
+ }
341
+ else {
342
+ // Send to MCP
343
+ mcpToolBlocks.push(toolBlock);
344
+ }
345
+ }
346
+ // If we handled all tools locally, skip MCP execution
347
+ if (mcpToolBlocks.length === 0 && localToolResults.length > 0) {
348
+ const conversation = this.conversationManager.getConversation(originalMessage.discussionId);
349
+ conversation.push({
350
+ role: 'user',
351
+ content: localToolResults,
352
+ });
353
+ // Continue with LLM (with caching enabled)
354
+ const cachedConversation = this.conversationManager.prepareForCaching(conversation);
355
+ const response = await this.client.messages.create({
356
+ model: this.config.model || 'claude-haiku-4-5-20251001',
357
+ max_tokens: 2000,
358
+ system: this.getCachedSystemPrompt(),
359
+ messages: cachedConversation,
360
+ tools: this.getToolsWithBugFixerRetry(),
361
+ });
362
+ // Track and burn tokens for local tool handling
363
+ const sessionKey = this.currentLinkedActivityId || this.currentDiscussionId || "default";
364
+ const localSession = this.sessionLogger.getSession(sessionKey);
365
+ if (localSession && response.usage) {
366
+ const inputTokens = response.usage.input_tokens;
367
+ const outputTokens = response.usage.output_tokens;
368
+ const cacheCreationTokens = response.usage.cache_creation_input_tokens || 0;
369
+ const cacheReadTokens = response.usage.cache_read_input_tokens || 0;
370
+ localSession.metrics.inputTokens += inputTokens;
371
+ localSession.metrics.outputTokens += outputTokens;
372
+ localSession.metrics.cacheCreationTokens += cacheCreationTokens;
373
+ localSession.metrics.cacheReadTokens += cacheReadTokens;
374
+ localSession.metrics.apiCalls += 1;
375
+ localSession.lastActivityTime = Date.now();
376
+ // Burn tokens real-time (fire-and-forget)
377
+ if (this.tokenBilling && localSession.workspaceId) {
378
+ const cost = this.tokenBilling.calculateCost(inputTokens, outputTokens, cacheCreationTokens, cacheReadTokens);
379
+ this.tokenBilling.burnTokens({
380
+ workspaceId: localSession.workspaceId,
381
+ inputTokens,
382
+ outputTokens,
383
+ cacheCreationTokens,
384
+ cacheReadTokens,
385
+ costUsd: cost,
386
+ sessionId: localSession.discussionId,
387
+ activityId: localSession.activityId,
388
+ });
389
+ }
390
+ }
391
+ await this.handleLlmResponse(response, originalMessage);
392
+ return;
393
+ }
394
+ // If we have local results, add them to be processed together with MCP results
395
+ // (for now, just continue with original flow for MCP tools)
396
+ // Get current activity session
397
+ const sessionKey = this.currentLinkedActivityId || this.currentDiscussionId || "default";
398
+ const session = this.sessionLogger.getSession(sessionKey);
399
+ // Store the user's request that triggered these tool calls (for context)
400
+ if (session && !session.triggerRequest) {
401
+ session.triggerRequest = originalMessage.content.substring(0, 500);
402
+ session.requestedBy = originalMessage.senderName;
403
+ session.requestedById = originalMessage.senderId;
404
+ }
405
+ // Execute tools using the tool executor service
406
+ const toolResults = await this.toolExecutor.executeTools(toolUseBlocks, {
407
+ session,
408
+ preprocessToolInput: this.preprocessToolInput.bind(this),
409
+ });
410
+ // Check if any tool failed (detect various error patterns)
411
+ const anyToolFailed = toolResults.some(r => {
412
+ if (r.is_error)
413
+ return true;
414
+ // Check for error patterns in content (MCP tools return error text)
415
+ const content = r.content.toLowerCase();
416
+ return content.includes('error') || content.includes('failed') || content.includes('❌');
417
+ });
418
+ if (anyToolFailed) {
419
+ this.lastToolsFailed = true;
420
+ this.orchestratorLogger.debug("Tool failure detected", {
421
+ tools: this.lastToolsUsed,
422
+ failedCount: toolResults.filter(r => r.is_error).length,
423
+ });
424
+ }
425
+ // Get conversation for this discussion
426
+ const conversation = this.conversationManager.getConversation(originalMessage.discussionId);
427
+ // Add tool results to conversation
428
+ conversation.push({
429
+ role: "user",
430
+ content: toolResults,
431
+ });
432
+ // Continue with LLM (with caching enabled)
433
+ const cachedConversation = this.conversationManager.prepareForCaching(conversation);
434
+ const response = await this.client.messages.create({
435
+ model: this.config.model || "claude-haiku-4-5-20251001",
436
+ max_tokens: 2000,
437
+ system: this.getCachedSystemPrompt(),
438
+ messages: cachedConversation,
439
+ tools: this.minimalTools,
440
+ });
441
+ // Track token usage in session (including cache stats for billing)
442
+ if (session && response.usage) {
443
+ const inputTokens = response.usage.input_tokens;
444
+ const outputTokens = response.usage.output_tokens;
445
+ const cacheCreationTokens = response.usage.cache_creation_input_tokens || 0;
446
+ const cacheReadTokens = response.usage.cache_read_input_tokens || 0;
447
+ session.metrics.inputTokens += inputTokens;
448
+ session.metrics.outputTokens += outputTokens;
449
+ session.metrics.cacheCreationTokens += cacheCreationTokens;
450
+ session.metrics.cacheReadTokens += cacheReadTokens;
451
+ session.metrics.apiCalls += 1;
452
+ session.lastActivityTime = Date.now();
453
+ // Burn tokens real-time (fire-and-forget) - inherited from base
454
+ if (this.tokenBilling && session.workspaceId) {
455
+ const cost = this.tokenBilling.calculateCost(inputTokens, outputTokens, cacheCreationTokens, cacheReadTokens);
456
+ this.tokenBilling.burnTokens({
457
+ workspaceId: session.workspaceId,
458
+ inputTokens,
459
+ outputTokens,
460
+ cacheCreationTokens,
461
+ cacheReadTokens,
462
+ costUsd: cost,
463
+ sessionId: session.discussionId,
464
+ activityId: session.activityId,
465
+ });
466
+ }
467
+ }
468
+ // Recursively handle (might need more tools or finally respond)
469
+ await this.handleLlmResponse(response, originalMessage);
470
+ }
471
+ /**
472
+ * Update cross-discussion memory when processing messages
473
+ * Call this when entering an activity discussion to remember context
474
+ */
475
+ updateContextMemory(activityId, activityName) {
476
+ if (activityId) {
477
+ this.lastKnownActivityId = activityId;
478
+ this.lastKnownActivityName = activityName;
479
+ this.lastKnownActivityTime = Date.now();
480
+ this.orchestratorLogger.debug("Updated context memory", { activityId, activityName });
481
+ }
482
+ }
483
+ /**
484
+ * Override to update cross-discussion memory when entering activity discussions
485
+ */
486
+ async extractIncomingMessage(signal) {
487
+ const message = await super.extractIncomingMessage(signal);
488
+ // Update context memory if this message is from an activity discussion
489
+ if (message?.linkedActivityId) {
490
+ this.updateContextMemory(message.linkedActivityId, message.linkedActivityName || null);
491
+ }
492
+ return message;
493
+ }
494
+ /**
495
+ * Register a specialist's Hailer user ID
496
+ * Called during initialization when we know the specialist bot's user ID
497
+ */
498
+ registerSpecialistUserId(specialistKey, userId, displayName) {
499
+ this.specialistUserIds.set(specialistKey, userId);
500
+ const specialist = this.specialists.get(specialistKey);
501
+ if (specialist) {
502
+ specialist.botUserId = userId;
503
+ if (displayName) {
504
+ specialist.displayName = displayName;
505
+ }
506
+ this.orchestratorLogger.info("Specialist registered", {
507
+ key: specialistKey,
508
+ name: specialist.name,
509
+ displayName: specialist.displayName || specialist.name,
510
+ userId,
511
+ });
512
+ }
513
+ }
514
+ /**
515
+ * Unregister a specialist (called when specialist is disabled/stopped)
516
+ * This prevents HAL from trying to invite a disabled specialist
517
+ */
518
+ unregisterSpecialist(specialistKey) {
519
+ const specialist = this.specialists.get(specialistKey);
520
+ if (specialist) {
521
+ specialist.botUserId = undefined; // Mark as unavailable
522
+ this.orchestratorLogger.info("Specialist unregistered", {
523
+ key: specialistKey,
524
+ name: specialist.name,
525
+ });
526
+ }
527
+ this.specialistUserIds.delete(specialistKey);
528
+ }
529
+ /**
530
+ * Mark a specialist as active in a discussion
531
+ */
532
+ markSpecialistActive(discussionId, specialistUserId) {
533
+ if (!this.activeSpecialistsInDiscussion.has(discussionId)) {
534
+ this.activeSpecialistsInDiscussion.set(discussionId, new Set());
535
+ }
536
+ this.activeSpecialistsInDiscussion.get(discussionId).add(specialistUserId);
537
+ }
538
+ /**
539
+ * Invite a specialist to a discussion
540
+ * Always invites first (tool handles membership check), then tags
541
+ */
542
+ async inviteSpecialist(specialist, discussionId, handoffContext) {
543
+ const specialistUserId = specialist.botUserId;
544
+ const displayName = specialist.displayName || specialist.name;
545
+ if (!specialistUserId) {
546
+ this.orchestratorLogger.warn("Specialist has no user ID", {
547
+ name: specialist.name,
548
+ });
549
+ return false;
550
+ }
551
+ try {
552
+ this.orchestratorLogger.info("Inviting specialist to discussion", {
553
+ name: specialist.name,
554
+ displayName,
555
+ userId: specialistUserId,
556
+ discussionId,
557
+ });
558
+ // Always call invite - the tool checks if already a member and handles gracefully
559
+ await this.callMcpTool("invite_discussion_members", {
560
+ discussionId,
561
+ userIds: [specialistUserId],
562
+ });
563
+ this.markSpecialistActive(discussionId, specialistUserId);
564
+ // Post handoff message with Hailer tag format using actual display name
565
+ await this.postResponse(discussionId, `[hailerTag|${displayName}](${specialistUserId}) - ${handoffContext}`);
566
+ this.orchestratorLogger.info("Specialist invited successfully", {
567
+ name: specialist.name,
568
+ displayName,
569
+ discussionId,
570
+ });
571
+ return true;
572
+ }
573
+ catch (error) {
574
+ this.orchestratorLogger.error("Failed to invite specialist", {
575
+ name: specialist.name,
576
+ displayName,
577
+ discussionId,
578
+ error: error instanceof Error ? error.message : String(error),
579
+ });
580
+ return false;
581
+ }
582
+ }
583
+ /**
584
+ * Override getTools to include Bug Fixer retry tool when there's a pending fix
585
+ */
586
+ getTools() {
587
+ // Always include the Bug Fixer retry tool so LLM knows about it
588
+ return this.getToolsWithBugFixerRetry();
589
+ }
590
+ /**
591
+ * Get tools list with Bug Fixer retry tool added
592
+ */
593
+ getToolsWithBugFixerRetry() {
594
+ const bugFixerRetryTool = {
595
+ name: 'trigger_bug_fixer_retry',
596
+ description: 'Trigger Bug Fixer to retry fixing a bug with new explanation. Use this after gathering enough info about what went wrong with the previous fix. Only works in discussions with a pending bug fix.',
597
+ input_schema: {
598
+ type: 'object',
599
+ properties: {
600
+ explanation: {
601
+ type: 'string',
602
+ description: 'Clear explanation of what is wrong with the current fix and what the expected behavior should be. Include: (1) what is broken, (2) expected vs actual behavior, (3) any specific details the user mentioned.',
603
+ },
604
+ },
605
+ required: ['explanation'],
606
+ },
607
+ };
608
+ const confirmBugFixTool = {
609
+ name: 'confirm_bug_fix',
610
+ description: 'Confirm that a bug report should be fixed. Use when user indicates they want the bug fixed (variations of "fix it", "yes fix", "please fix", etc.). Only works in discussions with a pending classification.',
611
+ input_schema: {
612
+ type: 'object',
613
+ properties: {},
614
+ required: [],
615
+ },
616
+ };
617
+ const declineBugReportTool = {
618
+ name: 'decline_bug_report',
619
+ description: 'Decline a bug report as not actually a bug. Use when user indicates it\'s not a bug (variations of "not a bug", "feature request", "not actually broken", etc.). Only works in discussions with a pending classification.',
620
+ input_schema: {
621
+ type: 'object',
622
+ properties: {},
623
+ required: [],
624
+ },
625
+ };
626
+ return [...this.minimalTools, bugFixerRetryTool, confirmBugFixTool, declineBugReportTool];
627
+ }
628
+ /**
629
+ * Get pending fix context for a discussion (if any)
630
+ */
631
+ getPendingFixContext(discussionId) {
632
+ const pendingFix = pending_fix_1.pendingFixRegistry.getPendingFix(discussionId);
633
+ if (!pendingFix) {
634
+ return '';
635
+ }
636
+ return `
637
+ <pending_bug_fix>
638
+ **IMPORTANT: This discussion has a pending bug fix from Bug Fixer!**
639
+
640
+ - Bug ID: ${pendingFix.bugId}
641
+ - State: ${pendingFix.state}
642
+ - Fix Summary: ${pendingFix.fixSummary}
643
+
644
+ **Your role:**
645
+ - If user says "approved" → Bug Fixer handles it automatically (you do nothing)
646
+ - If user expresses ANY dissatisfaction (denied, not working, still broken, etc.):
647
+ 1. Ask what's wrong (if not clear)
648
+ 2. Gather: what's broken + expected behavior
649
+ 3. Use trigger_bug_fixer_retry tool with the explanation
650
+
651
+ **Remember:** You're gathering info for Bug Fixer. Be concise, ask ONE question at a time.
652
+ </pending_bug_fix>
653
+ `;
654
+ }
655
+ /**
656
+ * Get pending classification context for a discussion (if any)
657
+ */
658
+ getPendingClassificationContext(discussionId) {
659
+ const pending = pending_classification_1.pendingClassificationRegistry.getPendingClassification(discussionId);
660
+ if (!pending) {
661
+ return '';
662
+ }
663
+ const classificationLabel = pending.classification === 'bug' ? 'Bug' :
664
+ pending.classification === 'feature_request' ? 'Feature Request' : 'Unclear';
665
+ return `
666
+ <pending_classification>
667
+ **IMPORTANT: Bug Fixer just classified this report and is waiting for user decision!**
668
+
669
+ - Bug: ${pending.bugName}
670
+ - App: ${pending.appName || pending.appId || 'Unknown'}
671
+ - Classification: ${classificationLabel}
672
+ - Reason: ${pending.reason}
673
+
674
+ **User options:**
675
+ - "fix it" → Bug Fixer will proceed to fix the bug
676
+ - "not a bug" → Report will be moved to Declined
677
+
678
+ **Your role - Use tools for user intent:**
679
+ - User wants to fix the bug → Call confirm_bug_fix tool
680
+ - User says it's not a bug / feature request → Call decline_bug_report tool
681
+ - User has questions → Help explain the classification
682
+
683
+ **Detecting intent (use tools, don't wait for exact words):**
684
+ - "fix it", "yes fix", "go ahead", "please fix", "fix this" → confirm_bug_fix
685
+ - "not a bug", "feature request", "not broken", "close it", "decline" → decline_bug_report
686
+
687
+ **Remember:** Use the tools to trigger actions. Don't tell user to type magic words.
688
+ </pending_classification>
689
+ `;
690
+ }
691
+ /**
692
+ * Get the STATIC portion of the system prompt (cacheable)
693
+ * This contains all content that doesn't change between calls for this bot instance
694
+ */
695
+ getStaticSystemPrompt() {
696
+ const { firstName, lastName } = this.getAgentName();
697
+ const fullName = `${firstName} ${lastName}`.trim();
698
+ return `<identity>
699
+ You are ${fullName} - the OMNIPOTENT Hailer Assistant. The full Hailer expert.
700
+ Bot ID: ${this.botClient.userId}
701
+
702
+ You are THE definitive Hailer power user. You have FULL ACCESS to ALL Hailer capabilities:
703
+ workflows, activities, insights, apps, templates, marketplace, discussions, files, and more.
704
+ You handle EVERYTHING yourself - from simple queries to complex multi-step operations.
705
+
706
+ Specialists exist but are RARELY needed. You should ALWAYS try to solve tasks yourself first.
707
+ Only consider specialists for truly collaborative multi-person tasks that benefit from
708
+ parallel work or when you explicitly want to demonstrate specialist capabilities.
709
+ </identity>
710
+
711
+ <personality>
712
+ **BUSINESS MODE** (default):
713
+ - Professional, direct, competent
714
+ - Get things done efficiently
715
+ - Provide accurate information
716
+ - Confident in your full capabilities
717
+
718
+ **SARCASM MODE** (for ridiculous requests):
719
+ - Dry wit, not mean-spirited
720
+ - Still help after the gentle mockery
721
+ </personality>
722
+
723
+ <memory_awareness>
724
+ **When users ask about your memory or what you remember:**
725
+
726
+ You have access to the current discussion's message history. On each conversation:
727
+ - You load the last 15 messages from this discussion
728
+ - You remember everything said in THIS discussion thread
729
+ - Cross-session memory (what happened in OTHER discussions) is not available
730
+
731
+ **How to respond to "what do you remember?":**
732
+ - Keep it brief and positive
733
+ - Focus on what you CAN see (this discussion)
734
+ - Don't over-explain limitations
735
+ - If they want to reference past work, ask them to remind you of the context
736
+
737
+ **Good response:** "I can see our conversation in this thread. What specifically would you like me to recall or work on?"
738
+
739
+ **Bad response:** "That's a great question. Honestly, I don't have access to your previous conversation history with me..." (too verbose, focuses on limitations)
740
+ </memory_awareness>
741
+
742
+ <decision_framework>
743
+ For each message, decide:
744
+
745
+ 1. **HIGH PRIORITY** (priority="high") - ALWAYS RESPOND:
746
+ - Direct messages (1:1) -> respond helpfully
747
+ - @mentions -> respond (even if just a greeting - acknowledge and ask how you can help)
748
+ - Replies to your messages -> respond
749
+ - **NEVER use <ignore/> for HIGH priority. Always acknowledge the user.**
750
+
751
+ 2. **NORMAL PRIORITY** (general chat) - STRICT FILTERING:
752
+
753
+ **RESPOND ONLY IF the message:**
754
+ - Explicitly asks about Hailer (workflows, activities, insights, apps, discussions)
755
+ - Requests to find/list/create/update workspace data
756
+ - Discusses a specific activity, customer, project, or workflow by name
757
+ - You can genuinely help with workspace-related context
758
+ - Is a complex task needing specialist help
759
+
760
+ **IGNORE (output <ignore/>) for NORMAL priority if:**
761
+ - Random characters, gibberish, keyboard mashing (no real words, repeated patterns)
762
+ - General chit-chat unrelated to workspace ("how are you", jokes)
763
+ - Conversations between other users that don't need you
764
+ - Bare greetings without a question ("hi", "hey") - but NOT if HIGH priority!
765
+ - Off-topic discussions (sports, weather, personal chat)
766
+ - Anything you're uncertain about
767
+
768
+ **CRITICAL:** For NORMAL priority only - if no clear workspace-related question/task, output <ignore/>.
769
+ When in doubt about NORMAL priority, IGNORE. Your DEFAULT for normal priority is <ignore/>.
770
+
771
+ 3. **RESPOND FORMAT** (only when you have something helpful):
772
+ <respond discussion="DISCUSSION_ID">
773
+ Your response
774
+ </respond>
775
+
776
+ 4. **IGNORE FORMAT** (use liberally - this is your DEFAULT):
777
+ <ignore/>
778
+ </decision_framework>
779
+
780
+ <specialist_guidelines>
781
+ **YOU ARE THE EXPERT - Handle everything yourself first!**
782
+
783
+ You have FULL ACCESS to all 39+ MCP tools. You can do EVERYTHING:
784
+ - Create workflows, configure fields and phases
785
+ - Build insights with SQL queries
786
+ - Perform bulk operations on activities
787
+ - Generate reports and dashboards
788
+ - Manage apps and marketplace items
789
+ - Handle complex multi-step workflows
790
+
791
+ **When to HANDLE YOURSELF (almost always):**
792
+ - ALL workflow operations (create, configure, update)
793
+ - ALL insight creation (SQL queries, dashboards, reports)
794
+ - ALL bulk operations (even 100+ items)
795
+ - Complex multi-step data tasks
796
+ - Activity CRUD (single or bulk)
797
+ - File handling and attachments
798
+ - User searches and invitations
799
+ - Template and marketplace operations
800
+ - App management
801
+
802
+ **When specialists MIGHT help (rare):**
803
+ - User explicitly requests collaborative work with multiple bots
804
+ - Demonstrating specialist capabilities to users
805
+ - Long-running parallel tasks where multiple agents working simultaneously adds value
806
+
807
+ **DEFAULT BEHAVIOR:** Do it yourself. You're the Hailer expert.
808
+
809
+ <invite_syntax>
810
+ <invite specialist="specialistKey">
811
+ Clear description of what you need done.
812
+ Include relevant context from the conversation.
813
+ </invite>
814
+ </invite_syntax>
815
+
816
+ <invite_rules>
817
+ **CRITICAL: NEVER use tools to invite or tag specialists directly!**
818
+ - DO NOT use invite_discussion_members for specialists
819
+ - DO NOT use add_discussion_message with [hailerTag|...] for specialists
820
+ - ALWAYS use the <invite specialist="key">...</invite> XML pattern
821
+
822
+ The system will handle inviting the specialist to the discussion and tagging them.
823
+ If you try to invite/tag specialists directly via tools, they may not receive the message.
824
+ </invite_rules>
825
+
826
+ <handoff_rules>
827
+ If you DO invite a specialist (rare), include all gathered IDs:
828
+
829
+ <bad_handoff>
830
+ "Create an insight for the Injuries workflow showing player data"
831
+ </bad_handoff>
832
+
833
+ <good_handoff>
834
+ "Create insight for Injuries workflow:
835
+ - workflowId: 691ffdf84217e9e8434e56ad
836
+ - Fields: { name: 'playerName', fieldId: '691ffdf84217e9e8434e56b1' }, { name: 'injuryType', fieldId: '691ffdf84217e9e8434e56b2' }
837
+ - Query: SELECT name as \\"Activity\\", playerName, injuryType FROM injuries ORDER BY name"
838
+ </good_handoff>
839
+
840
+ <insight_field_format>
841
+ Always format fields as: { name: 'Column Name', fieldId: 'FIELD_ID' }
842
+ Use 'fieldId' not 'id' for the field identifier.
843
+ </insight_field_format>
844
+ </handoff_rules>
845
+
846
+ <after_invite>
847
+ 1. I invite them to the discussion
848
+ 2. I post your handoff message mentioning them
849
+ 3. They see it and take action
850
+ </after_invite>
851
+ </specialist_guidelines>
852
+
853
+ <tagging_syntax>
854
+ To @mention someone in Hailer, use this format:
855
+ [hailerTag|Display Name](userId)
856
+
857
+ Example: [hailerTag|User Name](userId)
858
+
859
+ For specialists, use their display name and userId from the specialists list.
860
+ Do NOT use plain @mentions like "@hailerExpert" - they won't work.
861
+ </tagging_syntax>
862
+
863
+ <bug_fixer_autonomous>
864
+ **Bug Fixer - Autonomous Bug Fixer**
865
+
866
+ Bug Fixer is SPECIAL - he works AUTONOMOUSLY, not through invites!
867
+
868
+ **How Bug Fixer works:**
869
+ 1. Users create a bug report in the "Bug Reports" workflow
870
+ 2. Bug Fixer automatically detects new bugs and starts fixing them
871
+ 3. He analyzes the code, generates a fix, tests it
872
+ 4. He asks the user to verify with "approved" or "denied"
873
+ 5. On "approved" → Bug Fixer publishes to production automatically
874
+ 6. On "denied" or complaint → YOU (HAL) gather info, then trigger Bug Fixer retry
875
+
876
+ **YOUR ROLE IN BUG FIX DENIALS:**
877
+ When a discussion has a pending bug fix and the user expresses dissatisfaction:
878
+ 1. YOU handle the conversation - ask what's wrong, what behavior they expected
879
+ 2. Gather enough context: what's broken, expected vs actual behavior
880
+ 3. Once you have clear info, use trigger_bug_fixer_retry tool to pass the explanation
881
+ 4. Bug Fixer will receive your gathered info and retry the fix
882
+
883
+ **Detecting denial signals:**
884
+ - "denied", "not working", "still broken", "wrong", "doesn't work"
885
+ - Any complaint about the fix behavior
886
+ - User describing unexpected behavior
887
+
888
+ **Gathering info (ask ONE question at a time):**
889
+ - "What behavior are you seeing?"
890
+ - "What did you expect to happen instead?"
891
+ - "Is the issue consistent or intermittent?"
892
+
893
+ **When to trigger retry:**
894
+ Once you have: (1) what's wrong, (2) expected behavior → trigger the retry
895
+
896
+ **When someone mentions bugs (NEW bugs):**
897
+ - Tell them to create a bug report in "Bug Reports" workflow
898
+ - Explain Bug Fixer will pick it up automatically
899
+ - Offer to help create the bug report for them
900
+ </bug_fixer_autonomous>
901
+
902
+ <your_tools>
903
+ **YOU HAVE FULL ACCESS TO ALL 39+ HAILER MCP TOOLS:**
904
+
905
+ **WORKFLOW MANAGEMENT:**
906
+ - list_workflows, list_workflows_minimal - Browse all workflows
907
+ - list_workflow_phases - Get phases for a workflow
908
+ - get_workflow_schema - Get field definitions (use compact: true)
909
+ - install_workflow - Create new workflows from templates
910
+ - update_workflow_field - Modify field properties
911
+ - update_workflow_phase - Modify phase properties
912
+
913
+ **ACTIVITY OPERATIONS:**
914
+ - list_activities - Query activities with filters
915
+ - show_activity_by_id - Get full activity details
916
+ - count_activities - Get activity counts
917
+ - create_activity - Create single or BULK activities
918
+ - update_activity - Update single or BULK activities
919
+
920
+ **INSIGHT MANAGEMENT (SQL Analytics):**
921
+ - list_insights - Browse existing insights
922
+ - preview_insight - Test SQL queries before saving
923
+ - create_insight - Save new SQL insights
924
+ - get_insight_data - Execute and get results
925
+ - update_insight - Modify existing insights
926
+
927
+ **APP MANAGEMENT:**
928
+ - list_apps (view only)
929
+
930
+ **TEMPLATE & MARKETPLACE:**
931
+ - list_templates, get_template, create_template, install_template
932
+ - publish_template - Publish workspace as template
933
+ - get_product, get_product_manifest
934
+ - install_marketplace_app, publish_app
935
+
936
+ **DISCUSSION TOOLS:**
937
+ - join_discussion, leave_discussion
938
+ - add_discussion_message - Post messages
939
+ - invite_discussion_members - Add users to chats
940
+ - fetch_discussion_messages, fetch_previous_discussion_messages
941
+ - get_activity_from_discussion, list_my_discussions
942
+
943
+ **USER & FILES:**
944
+ - search_workspace_users - Find users by name
945
+ - upload_files, download_file - Handle file attachments
946
+
947
+ **BILLING:**
948
+ - get_workspace_balance - Check token balance
949
+
950
+ **ADVANCED:**
951
+ - test_function_field - Test computed field functions
952
+
953
+ **You are the FULL Hailer expert. Use these tools directly - no need to delegate!**
954
+
955
+ **CRITICAL for join_discussion when inviting users:**
956
+ ALWAYS pass these parameters from the incoming message:
957
+ - inviteUserId = user_id attribute
958
+ - sourceActivityId = activity_id attribute (creates "came from" link!)
959
+ - welcomeReason = why they're being invited
960
+
961
+ **join_discussion ID types:**
962
+ - HailerTags like [hailerTag|Name](ID) usually contain ACTIVITY IDs, not discussion IDs
963
+ - When user references an activity/player/customer by tag, use: activityId parameter
964
+ - Only use discussionId for direct discussion links (rare)
965
+ - The tool auto-detects: if discussionId fails, it tries as activityId
966
+
967
+ **SILENT SUCCESS for join_discussion:**
968
+ After successfully joining a discussion, do NOT post a confirmation message back to the source chat.
969
+ The action is self-evident (bot appears in target discussion). Only report ERRORS back to source chat.
970
+
971
+ **CRITICAL - Extract IDs from context:**
972
+ The <incoming> tag contains IDs. ALWAYS use them:
973
+ - activityId attribute → pass to show_activity_by_id, update_activity
974
+ - discussionId attribute → pass to get_activity_from_discussion, add_discussion_message
975
+
976
+ **NEVER call tools with empty parameters {}** - always extract from context first.
977
+
978
+ **update_activity formats:**
979
+ - Single mode: use \`activityId\` parameter
980
+ - Bulk mode (activities array): use \`_id\` inside each object, NOT \`activityId\`
981
+
982
+ **Field values must be plain:**
983
+ - numericunit: just the number → \`78\` (NOT \`{"type":"numericunit","value":78}\`)
984
+ - text: just the string → \`"hello"\`
985
+ - activitylink: just the ID → \`"abc123..."\`
986
+ </your_tools>
987
+
988
+ <file_handling>
989
+ **When users drop files in chat:**
990
+
991
+ The incoming message will contain file attachment info like:
992
+ \`[File attached: 1 file(s) - IDs: abc123...]\`
993
+
994
+ **To read a file:** Use \`download_file\` with the fileId to read its contents.
995
+
996
+ **To attach a file to an EXISTING activity:**
997
+ The Hailer API doesn't support adding files via update_activity. Instead:
998
+ 1. Get the activity's discussion ID using \`show_activity_by_id\`
999
+ 2. Join the discussion using \`join_discussion(activityId: "...")\`
1000
+ 3. Post the file using \`add_discussion_message\` with the fileId:
1001
+ \`add_discussion_message(discussionId: "...", content: "Attaching file", fileIds: ["abc123"])\`
1002
+
1003
+ The file will appear in the activity's discussion thread.
1004
+
1005
+ **To attach a file to a NEW activity:**
1006
+ Use \`create_activity\` with the \`fileIds\` parameter - this works directly.
1007
+
1008
+ **Key point:** When a user drops a file, it's already uploaded to Hailer. Use the fileId directly - no need to re-upload.
1009
+ </file_handling>
1010
+
1011
+ <tagging>
1012
+ **Activity Tags:** #ACTIVITY_ID (24-char hex)
1013
+ - Correct: "Check out #691ffe874217e9e8434e57fc"
1014
+ - Wrong: "Check out #691ffe874217e9e8434e57fc (Name)" - name auto-displays
1015
+
1016
+ **User Mentions:** @"Full Name" or @userId
1017
+ </tagging>
1018
+
1019
+ <agentic_loop>
1020
+ **CRITICAL: The 'respond' action ENDS YOUR TURN!**
1021
+
1022
+ When you output {"action": "respond", ...}, your turn ENDS IMMEDIATELY.
1023
+ You CANNOT call any more tools after responding. There is NO "next turn".
1024
+
1025
+ **THIS WILL FAIL (you lose your turn before doing work):**
1026
+ {"action": "respond", "response_text": "Let me check that for you..."}
1027
+ → Message posted, turn ends, NO tools called!
1028
+
1029
+ **THIS IS CORRECT (gather data FIRST, then respond):**
1030
+ 1. {"action": "list_workflow_phases", "params": {...}} → get phases
1031
+ 2. {"action": "get_workflow_schema", "params": {...}} → get fields
1032
+ 3. {"action": "list_activities", "params": {...}} → get data
1033
+ 4. {"action": "respond", "response_text": "Here are the 3 injured players: ..."} → FINAL answer
1034
+
1035
+ **FORBIDDEN response_text patterns:**
1036
+ - "Let me check..." / "I'll look into..." / "One moment..."
1037
+ - "Working on it..." / "I'm going to..."
1038
+ - ANY promise of future work
1039
+
1040
+ **ONLY respond when you have the ACTUAL ANSWER.**
1041
+ </agentic_loop>
1042
+
1043
+ <rules>
1044
+ - Be concise - snappy responses, not essays
1045
+ - Use your memory - reference past conversations
1046
+ - For HIGH priority: respond immediately with work, not promises
1047
+ - For NORMAL priority: your DEFAULT is "ignore" action. Only respond if clear workspace question.
1048
+ - **Gibberish test:** No recognizable words = "ignore" action
1049
+ - **Relevance test:** Is this about workflows/activities/insights? If not = "ignore" action
1050
+ - When inviting specialists, explain what's happening
1051
+ - **NEVER use "respond" until you have gathered ALL needed data via tool actions**
1052
+ </rules>`;
1053
+ }
1054
+ /**
1055
+ * Get the DYNAMIC portion of the system prompt (not cacheable)
1056
+ * This contains time-sensitive and per-call context
1057
+ */
1058
+ getDynamicContext() {
1059
+ // Round time to 5-minute intervals to allow cache reuse
1060
+ // Without this, every request has a different timestamp, killing the cache
1061
+ const now = new Date();
1062
+ const fiveMinutes = 5 * 60 * 1000;
1063
+ const roundedTime = new Date(Math.floor(now.getTime() / fiveMinutes) * fiveMinutes);
1064
+ // Build specialist info for prompt - ONLY show available specialists
1065
+ const availableSpecialists = Array.from(this.specialists.entries())
1066
+ .filter(([_, spec]) => !!spec.botUserId);
1067
+ const specialistInfo = availableSpecialists.length > 0
1068
+ ? availableSpecialists
1069
+ .map(([key, spec]) => {
1070
+ const mentionName = spec.displayName || spec.name;
1071
+ return `- **${spec.name}** (available)
1072
+ Tag with: [hailerTag|${mentionName}](${spec.botUserId})
1073
+ Key for invite tag: ${key}
1074
+ Expertise: ${spec.expertise.join(", ")}
1075
+ Triggers: ${spec.triggerKeywords.slice(0, 5).join(", ")}`;
1076
+ })
1077
+ .join("\n\n")
1078
+ : `**NO SPECIALISTS ARE CURRENTLY ENABLED.**
1079
+ DO NOT invent, fabricate, or mention any specialist names.
1080
+ DO NOT use <invite> tags. DO NOT claim to "hand off" to anyone.
1081
+ Handle all requests yourself or tell the user: "No specialists are enabled. You can enable them in AI Hub."`;
1082
+ return `<current_time>${roundedTime.toISOString()}</current_time>
1083
+
1084
+ <specialists>
1085
+ ${specialistInfo}
1086
+ </specialists>
1087
+
1088
+ ${this.currentDiscussionId ? this.getPendingFixContext(this.currentDiscussionId) : ''}
1089
+ ${this.currentDiscussionId ? this.getPendingClassificationContext(this.currentDiscussionId) : ''}`;
1090
+ }
1091
+ /**
1092
+ * Override system prompt to combine static and dynamic parts
1093
+ * Used for backwards compatibility
1094
+ */
1095
+ getSystemPrompt() {
1096
+ return this.getStaticSystemPrompt() + "\n\n" + this.getDynamicContext();
1097
+ }
1098
+ /**
1099
+ * Override to return cached system prompt with proper structure
1100
+ * Static content is cached (50% cost reduction), dynamic content appended fresh
1101
+ */
1102
+ getCachedSystemPrompt() {
1103
+ return [
1104
+ {
1105
+ type: "text",
1106
+ text: this.getStaticSystemPrompt(),
1107
+ cache_control: { type: "ephemeral" },
1108
+ },
1109
+ {
1110
+ type: "text",
1111
+ text: this.getDynamicContext(),
1112
+ },
1113
+ ];
1114
+ }
1115
+ /**
1116
+ * Override response handling to detect specialist invitations
1117
+ */
1118
+ async handleLlmResponse(response, originalMessage) {
1119
+ // Get conversation for this discussion
1120
+ const conversation = this.conversationManager.getConversation(originalMessage.discussionId);
1121
+ // Add assistant response to conversation
1122
+ // Cast response content to MessageParam content type (ContentBlock[] → ContentBlockParam[])
1123
+ conversation.push({
1124
+ role: "assistant",
1125
+ content: response.content,
1126
+ });
1127
+ // Check for specialist invitation in text content
1128
+ const textBlocks = response.content.filter((block) => block.type === "text");
1129
+ const textContent = textBlocks.map((b) => b.text).join("\n");
1130
+ // Look for <invite specialist="...">...</invite> pattern
1131
+ const inviteMatch = textContent.match(/<invite specialist="(\w+)">([\s\S]*?)<\/invite>/);
1132
+ if (inviteMatch) {
1133
+ const [_fullMatch, specialistKey, handoffContext] = inviteMatch;
1134
+ const specialist = this.specialists.get(specialistKey);
1135
+ if (specialist && specialist.botUserId) {
1136
+ this.orchestratorLogger.info("LLM requested specialist invitation", {
1137
+ specialist: specialistKey,
1138
+ discussionId: originalMessage.discussionId,
1139
+ });
1140
+ // Extract any text before the invite tag to post as acknowledgment
1141
+ const preInviteText = textContent
1142
+ .substring(0, textContent.indexOf("<invite"))
1143
+ .trim();
1144
+ // Check for respond wrapper
1145
+ const respondMatch = preInviteText.match(/<respond discussion="([^"]+)">([\s\S]*)/);
1146
+ if (respondMatch) {
1147
+ const [, discussionId, content] = respondMatch;
1148
+ const cleanContent = content.replace(/<\/respond>.*$/s, "").trim();
1149
+ if (cleanContent) {
1150
+ await this.postResponse(discussionId, cleanContent);
1151
+ }
1152
+ }
1153
+ else if (preInviteText) {
1154
+ // No respond wrapper, but there's text - might be for high priority
1155
+ if (originalMessage.priority === "high") {
1156
+ await this.postResponse(originalMessage.discussionId, preInviteText);
1157
+ }
1158
+ }
1159
+ // Invite the specialist
1160
+ const invited = await this.inviteSpecialist(specialist, originalMessage.discussionId, handoffContext.trim());
1161
+ if (!invited) {
1162
+ // Failed to invite - let user know
1163
+ await this.postResponse(originalMessage.discussionId, `I tried to bring in ${specialist.name} but couldn't reach them. Let me try handling this myself...`);
1164
+ // Continue with normal handling
1165
+ }
1166
+ return; // Don't continue with normal response handling
1167
+ }
1168
+ else {
1169
+ // Specialist is disabled - feed back to LLM for natural response
1170
+ this.orchestratorLogger.info("Specialist disabled, asking LLM to respond naturally", {
1171
+ key: specialistKey,
1172
+ name: specialist?.name || specialistKey,
1173
+ });
1174
+ // Add system feedback to conversation so LLM knows the specialist is unavailable
1175
+ const conversation = this.conversationManager.getConversation(originalMessage.discussionId);
1176
+ conversation.push({
1177
+ role: 'user',
1178
+ content: `[SYSTEM: The specialist "${specialist?.name || specialistKey}" you tried to invite is currently disabled. Please inform the user naturally that this specialist is not available and they can enable it in the AI Hub settings if needed. Do NOT use XML tags in your response.]`,
1179
+ });
1180
+ // Get LLM to respond naturally about the unavailability (with caching enabled)
1181
+ const cachedConversation = this.conversationManager.prepareForCaching(conversation);
1182
+ const retryResponse = await this.client.messages.create({
1183
+ model: this.config.model || 'claude-haiku-4-5-20251001',
1184
+ max_tokens: 1000,
1185
+ system: this.getCachedSystemPrompt(),
1186
+ messages: cachedConversation,
1187
+ tools: this.getTools(),
1188
+ });
1189
+ // Track and burn tokens for specialist unavailable retry
1190
+ const sessionKey = this.currentLinkedActivityId || this.currentDiscussionId || "default";
1191
+ const retrySession = this.sessionLogger.getSession(sessionKey);
1192
+ if (retrySession && retryResponse.usage) {
1193
+ const inputTokens = retryResponse.usage.input_tokens;
1194
+ const outputTokens = retryResponse.usage.output_tokens;
1195
+ const cacheCreationTokens = retryResponse.usage.cache_creation_input_tokens || 0;
1196
+ const cacheReadTokens = retryResponse.usage.cache_read_input_tokens || 0;
1197
+ retrySession.metrics.inputTokens += inputTokens;
1198
+ retrySession.metrics.outputTokens += outputTokens;
1199
+ retrySession.metrics.cacheCreationTokens += cacheCreationTokens;
1200
+ retrySession.metrics.cacheReadTokens += cacheReadTokens;
1201
+ retrySession.metrics.apiCalls += 1;
1202
+ retrySession.lastActivityTime = Date.now();
1203
+ // Burn tokens real-time (fire-and-forget)
1204
+ if (this.tokenBilling && retrySession.workspaceId) {
1205
+ const cost = this.tokenBilling.calculateCost(inputTokens, outputTokens, cacheCreationTokens, cacheReadTokens);
1206
+ this.tokenBilling.burnTokens({
1207
+ workspaceId: retrySession.workspaceId,
1208
+ inputTokens,
1209
+ outputTokens,
1210
+ cacheCreationTokens,
1211
+ cacheReadTokens,
1212
+ costUsd: cost,
1213
+ sessionId: retrySession.discussionId,
1214
+ activityId: retrySession.activityId,
1215
+ });
1216
+ }
1217
+ }
1218
+ // Process the retry response (should be a simple text response)
1219
+ await this.handleLlmResponse(retryResponse, originalMessage);
1220
+ return;
1221
+ }
1222
+ }
1223
+ // Check for tool calls
1224
+ const toolUseBlocks = response.content.filter((block) => block.type === "tool_use");
1225
+ if (toolUseBlocks.length > 0) {
1226
+ // Mark that tools were used - subsequent responses should be posted
1227
+ this.toolsUsedInCurrentMessage = true;
1228
+ // Track which tools were used (for silent success detection)
1229
+ this.lastToolsUsed = toolUseBlocks.map(b => b.name);
1230
+ // Execute tools and continue conversation
1231
+ await this.executeToolsAndContinue(toolUseBlocks, originalMessage);
1232
+ return;
1233
+ }
1234
+ // Check for regular response (no invite, no tools)
1235
+ if (textBlocks.length > 0) {
1236
+ const responseText = textContent.trim();
1237
+ this.orchestratorLogger.info("LLM raw response", {
1238
+ discussion: originalMessage.discussionId,
1239
+ priority: originalMessage.priority,
1240
+ responseLength: responseText.length,
1241
+ fullResponse: responseText.substring(0, 500),
1242
+ hasIgnoreTag: responseText.includes("<ignore"),
1243
+ hasRespondTag: responseText.includes("<respond"),
1244
+ });
1245
+ // Check for IGNORE decision - remove from context to keep it clean
1246
+ if (responseText.includes("<decision>IGNORE</decision>") ||
1247
+ responseText.includes("<ignore")) {
1248
+ this.orchestratorLogger.debug("LLM decided to ignore - removing from context", {
1249
+ discussion: originalMessage.discussionId,
1250
+ });
1251
+ // Stop typing indicator
1252
+ this.typingIndicator?.stop();
1253
+ // Remove both the assistant's response AND the incoming message from context
1254
+ conversation.pop(); // Remove assistant response we just added
1255
+ conversation.pop(); // Remove the incoming message
1256
+ this.toolsUsedInCurrentMessage = false; // Reset for next message
1257
+ return;
1258
+ }
1259
+ // Check for explicit response directive
1260
+ const responseMatch = responseText.match(/<respond discussion="([^"]+)">([\s\S]*?)<\/respond>/);
1261
+ if (responseMatch) {
1262
+ const targetDiscussion = responseMatch[1];
1263
+ const content = responseMatch[2].trim();
1264
+ // SILENT SUCCESS: Skip confirmation if we just ran a silent tool successfully (not on error)
1265
+ const usedSilentTool = this.lastToolsUsed.some(t => OrchestratorDaemon.SILENT_SUCCESS_TOOLS.has(t));
1266
+ if (usedSilentTool && !this.lastToolsFailed) {
1267
+ this.orchestratorLogger.debug("Suppressing confirmation for silent success tool", {
1268
+ discussion: originalMessage.discussionId,
1269
+ tools: this.lastToolsUsed,
1270
+ });
1271
+ // Stop typing indicator
1272
+ this.typingIndicator?.stop();
1273
+ // NOTE: Don't pop from context - keep conversation valid for future messages
1274
+ this.toolsUsedInCurrentMessage = false;
1275
+ this.lastToolsUsed = [];
1276
+ this.lastToolsFailed = false;
1277
+ return;
1278
+ }
1279
+ await this.postResponse(targetDiscussion, content);
1280
+ this.toolsUsedInCurrentMessage = false; // Reset for next message
1281
+ this.lastToolsUsed = [];
1282
+ this.lastToolsFailed = false;
1283
+ return;
1284
+ }
1285
+ // For high priority messages, always send substantive responses
1286
+ // (unless we just ran a silent success tool)
1287
+ if (originalMessage.priority === "high" &&
1288
+ responseText &&
1289
+ !responseText.includes("<thinking>") &&
1290
+ !responseText.startsWith("I'll") &&
1291
+ responseText.length > 10) {
1292
+ // SILENT SUCCESS: Skip confirmation if we just ran a silent tool successfully (not on error)
1293
+ const usedSilentTool = this.lastToolsUsed.some(t => OrchestratorDaemon.SILENT_SUCCESS_TOOLS.has(t));
1294
+ if (usedSilentTool && !this.lastToolsFailed) {
1295
+ this.orchestratorLogger.debug("Suppressing high-priority confirmation for silent success tool", {
1296
+ discussion: originalMessage.discussionId,
1297
+ tools: this.lastToolsUsed,
1298
+ });
1299
+ // Stop typing indicator
1300
+ this.typingIndicator?.stop();
1301
+ // NOTE: Don't pop from context - keep conversation valid for future messages
1302
+ this.toolsUsedInCurrentMessage = false;
1303
+ this.lastToolsUsed = [];
1304
+ this.lastToolsFailed = false;
1305
+ return;
1306
+ }
1307
+ await this.postResponse(originalMessage.discussionId, responseText);
1308
+ this.toolsUsedInCurrentMessage = false; // Reset for next message
1309
+ this.lastToolsUsed = [];
1310
+ this.lastToolsFailed = false;
1311
+ return;
1312
+ }
1313
+ // For normal priority:
1314
+ // - If tools were used, post substantive responses (LLM was doing real work)
1315
+ // - Otherwise, require explicit <respond> tag
1316
+ if (originalMessage.priority === "normal") {
1317
+ // SILENT SUCCESS: Skip confirmation if we just ran a silent tool successfully (not on error)
1318
+ const usedSilentTool = this.lastToolsUsed.some(t => OrchestratorDaemon.SILENT_SUCCESS_TOOLS.has(t));
1319
+ const shouldSuppressSilent = usedSilentTool && !this.lastToolsFailed;
1320
+ if (this.toolsUsedInCurrentMessage && responseText.length > 50 && !responseText.includes("<ignore") && !shouldSuppressSilent) {
1321
+ // Tools were used and we have a substantive response - post it
1322
+ this.orchestratorLogger.info("Posting tool-assisted response", {
1323
+ discussion: originalMessage.discussionId,
1324
+ responseLength: responseText.length,
1325
+ });
1326
+ await this.postResponse(originalMessage.discussionId, responseText);
1327
+ this.toolsUsedInCurrentMessage = false; // Reset for next message
1328
+ this.lastToolsUsed = [];
1329
+ this.lastToolsFailed = false;
1330
+ return;
1331
+ }
1332
+ if (shouldSuppressSilent) {
1333
+ this.orchestratorLogger.debug("Suppressing normal-priority confirmation for silent success tool", {
1334
+ discussion: originalMessage.discussionId,
1335
+ tools: this.lastToolsUsed,
1336
+ });
1337
+ // Stop typing indicator
1338
+ this.typingIndicator?.stop();
1339
+ // NOTE: Don't pop from context when tools were used - keep conversation valid
1340
+ this.toolsUsedInCurrentMessage = false;
1341
+ this.lastToolsUsed = [];
1342
+ this.lastToolsFailed = false;
1343
+ return;
1344
+ }
1345
+ this.orchestratorLogger.debug("Normal priority without <respond> tag - removing from context", {
1346
+ discussion: originalMessage.discussionId,
1347
+ responsePreview: responseText.substring(0, 100),
1348
+ toolsUsed: this.toolsUsedInCurrentMessage,
1349
+ });
1350
+ // Stop typing indicator
1351
+ this.typingIndicator?.stop();
1352
+ // Remove from context - we didn't respond (only safe when no tools were used)
1353
+ if (!this.toolsUsedInCurrentMessage) {
1354
+ conversation.pop(); // Remove assistant response
1355
+ conversation.pop(); // Remove incoming message
1356
+ }
1357
+ this.toolsUsedInCurrentMessage = false; // Reset for next message
1358
+ this.lastToolsUsed = [];
1359
+ this.lastToolsFailed = false;
1360
+ }
1361
+ }
1362
+ }
1363
+ /**
1364
+ * Get orchestrator status including specialist info
1365
+ */
1366
+ getOrchestratorStatus() {
1367
+ const specialists = Array.from(this.specialists.entries()).map(([key, spec]) => ({
1368
+ key,
1369
+ name: spec.name,
1370
+ available: !!spec.botUserId,
1371
+ userId: spec.botUserId,
1372
+ }));
1373
+ const activeInDiscussions = {};
1374
+ for (const [discussionId, userIds] of this.activeSpecialistsInDiscussion) {
1375
+ activeInDiscussions[discussionId] = Array.from(userIds);
1376
+ }
1377
+ return {
1378
+ conversationState: this.getConversationState(),
1379
+ specialists,
1380
+ activeInDiscussions,
1381
+ };
1382
+ }
1383
+ }
1384
+ exports.OrchestratorDaemon = OrchestratorDaemon;
1385
+ //# sourceMappingURL=daemon.js.map