kimaki 1.3.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (346) hide show
  1. package/assets/fonts/Geist-Bold.ttf +0 -0
  2. package/assets/fonts/Geist-Regular.ttf +0 -0
  3. package/assets/fonts/GeistMono-Regular.ttf +0 -0
  4. package/assets/fonts/OFL.txt +92 -0
  5. package/dist/agent-ui.e2e.test.js +27 -13
  6. package/dist/agent-ui.e2e.test.js.map +1 -1
  7. package/dist/agent-ui.js +2 -1
  8. package/dist/agent-ui.js.map +1 -1
  9. package/dist/analytics.e2e.test.js +1 -1
  10. package/dist/analytics.e2e.test.js.map +1 -1
  11. package/dist/autostart.d.ts +4 -0
  12. package/dist/autostart.js +55 -10
  13. package/dist/autostart.js.map +1 -1
  14. package/dist/bot.d.ts +13 -6
  15. package/dist/bot.js +17 -15
  16. package/dist/bot.js.map +1 -1
  17. package/dist/btw.e2e.test.js +3 -3
  18. package/dist/builtin-skills.d.ts +3 -0
  19. package/dist/builtin-skills.js +29 -0
  20. package/dist/builtin-skills.js.map +1 -1
  21. package/dist/builtin-skills.test.js +72 -1
  22. package/dist/builtin-skills.test.js.map +1 -1
  23. package/dist/catalog-refresh.e2e.test.js +2 -2
  24. package/dist/cli/bot.d.ts +1 -1
  25. package/dist/cli/bot.js +33 -18
  26. package/dist/cli/bot.js.map +1 -1
  27. package/dist/cli/discord.js +32 -6
  28. package/dist/cli/discord.js.map +1 -1
  29. package/dist/cli/schedule.js +23 -9
  30. package/dist/cli/schedule.js.map +1 -1
  31. package/dist/cli/session.js +37 -12
  32. package/dist/cli/session.js.map +1 -1
  33. package/dist/cli/shared.d.ts +5 -3
  34. package/dist/cli/shared.js +45 -10
  35. package/dist/cli/shared.js.map +1 -1
  36. package/dist/cli-discord.e2e.test.js +13 -8
  37. package/dist/cli-discord.e2e.test.js.map +1 -1
  38. package/dist/cli-lock.e2e.test.js +87 -20
  39. package/dist/cli-lock.e2e.test.js.map +1 -1
  40. package/dist/cli-read.e2e.test.js +18 -9
  41. package/dist/cli-read.e2e.test.js.map +1 -1
  42. package/dist/cli-sessions.e2e.test.js +4 -3
  43. package/dist/cli-sessions.e2e.test.js.map +1 -1
  44. package/dist/cli.js +2 -0
  45. package/dist/cli.js.map +1 -1
  46. package/dist/commands/preference-commands.d.ts +4 -0
  47. package/dist/commands/preference-commands.js +38 -4
  48. package/dist/commands/preference-commands.js.map +1 -1
  49. package/dist/commands/session-commands.js +11 -8
  50. package/dist/commands/session-commands.js.map +1 -1
  51. package/dist/commands/thread-commands.js +94 -24
  52. package/dist/commands/thread-commands.js.map +1 -1
  53. package/dist/commands/worktree-commands.d.ts +5 -6
  54. package/dist/commands/worktree-commands.js +8 -7
  55. package/dist/commands/worktree-commands.js.map +1 -1
  56. package/dist/commands.e2e.test.js +25 -21
  57. package/dist/commands.e2e.test.js.map +1 -1
  58. package/dist/coordinator-agents.e2e.test.d.ts +1 -0
  59. package/dist/coordinator-agents.e2e.test.js +113 -0
  60. package/dist/coordinator-agents.e2e.test.js.map +1 -0
  61. package/dist/coordinator-idle.e2e.test.d.ts +1 -0
  62. package/dist/coordinator-idle.e2e.test.js +100 -0
  63. package/dist/coordinator-idle.e2e.test.js.map +1 -0
  64. package/dist/coordinator-queue.e2e.test.d.ts +1 -0
  65. package/dist/coordinator-queue.e2e.test.js +244 -0
  66. package/dist/coordinator-queue.e2e.test.js.map +1 -0
  67. package/dist/coordinator-warmup.e2e.test.d.ts +1 -0
  68. package/dist/coordinator-warmup.e2e.test.js +131 -0
  69. package/dist/coordinator-warmup.e2e.test.js.map +1 -0
  70. package/dist/coordinator.d.ts +6 -0
  71. package/dist/coordinator.e2e.test.d.ts +1 -0
  72. package/dist/coordinator.e2e.test.js +505 -0
  73. package/dist/coordinator.e2e.test.js.map +1 -0
  74. package/dist/coordinator.js +164 -0
  75. package/dist/coordinator.js.map +1 -0
  76. package/dist/db.d.ts +78 -3
  77. package/dist/db.test.js +1 -0
  78. package/dist/db.test.js.map +1 -1
  79. package/dist/diagram.d.ts +11 -0
  80. package/dist/diagram.js +232 -0
  81. package/dist/diagram.js.map +1 -0
  82. package/dist/diagram.test.d.ts +1 -0
  83. package/dist/diagram.test.js +52 -0
  84. package/dist/diagram.test.js.map +1 -0
  85. package/dist/duration.js +13 -5
  86. package/dist/duration.js.map +1 -1
  87. package/dist/effects.d.ts +6 -1
  88. package/dist/effects.js +97 -26
  89. package/dist/effects.js.map +1 -1
  90. package/dist/event-loop.d.ts +2 -3
  91. package/dist/event-loop.js +74 -44
  92. package/dist/event-loop.js.map +1 -1
  93. package/dist/format-parts.d.ts +21 -4
  94. package/dist/format-parts.js +40 -23
  95. package/dist/format-parts.js.map +1 -1
  96. package/dist/gateway-replay.e2e.test.js +4 -4
  97. package/dist/harness.e2e.test.js +2 -2
  98. package/dist/harness.e2e.test.js.map +1 -1
  99. package/dist/hello-thread.e2e.test.js +56 -5
  100. package/dist/hello-thread.e2e.test.js.map +1 -1
  101. package/dist/ingress.js +47 -12
  102. package/dist/ingress.js.map +1 -1
  103. package/dist/interaction-context.d.ts +4 -4
  104. package/dist/interaction-context.js +9 -7
  105. package/dist/interaction-context.js.map +1 -1
  106. package/dist/interrupt.e2e.test.js +8 -5
  107. package/dist/interrupt.e2e.test.js.map +1 -1
  108. package/dist/legacy.e2e.test.js +1 -1
  109. package/dist/lock-routes.d.ts +83 -31
  110. package/dist/lock-routes.js +68 -8
  111. package/dist/lock-routes.js.map +1 -1
  112. package/dist/lock-server.d.ts +3 -2
  113. package/dist/lock-server.js +23 -7
  114. package/dist/lock-server.js.map +1 -1
  115. package/dist/main.d.ts +6 -3
  116. package/dist/main.js +14 -4
  117. package/dist/main.js.map +1 -1
  118. package/dist/mainmast-idle.e2e.test.d.ts +1 -0
  119. package/dist/mainmast-idle.e2e.test.js +99 -0
  120. package/dist/mainmast-idle.e2e.test.js.map +1 -0
  121. package/dist/mainmast-queue.e2e.test.d.ts +1 -0
  122. package/dist/mainmast-queue.e2e.test.js +244 -0
  123. package/dist/mainmast-queue.e2e.test.js.map +1 -0
  124. package/dist/mainmast-warmup.e2e.test.d.ts +1 -0
  125. package/dist/mainmast-warmup.e2e.test.js +130 -0
  126. package/dist/mainmast-warmup.e2e.test.js.map +1 -0
  127. package/dist/mainmast.d.ts +6 -0
  128. package/dist/mainmast.e2e.test.d.ts +1 -0
  129. package/dist/mainmast.e2e.test.js +428 -0
  130. package/dist/mainmast.e2e.test.js.map +1 -0
  131. package/dist/mainmast.js +156 -0
  132. package/dist/mainmast.js.map +1 -0
  133. package/dist/markdown/markdown.test.js +14 -4
  134. package/dist/markdown/markdown.test.js.map +1 -1
  135. package/dist/markdown/render-markdown.js +9 -6
  136. package/dist/markdown/render-markdown.js.map +1 -1
  137. package/dist/onboarding-cli.e2e.test.js +7 -6
  138. package/dist/onboarding-cli.e2e.test.js.map +1 -1
  139. package/dist/onboarding.d.ts +3 -10
  140. package/dist/onboarding.e2e.test.js +8 -10
  141. package/dist/onboarding.e2e.test.js.map +1 -1
  142. package/dist/onboarding.js +14 -24
  143. package/dist/onboarding.js.map +1 -1
  144. package/dist/permissions.e2e.test.js +3 -3
  145. package/dist/plugin/coordinator.d.ts +4 -0
  146. package/dist/plugin/coordinator.js +389 -0
  147. package/dist/plugin/coordinator.js.map +1 -0
  148. package/dist/plugin/index.js +93 -61
  149. package/dist/plugin/index.js.map +1 -1
  150. package/dist/plugin/mainmast.d.ts +4 -0
  151. package/dist/plugin/mainmast.js +379 -0
  152. package/dist/plugin/mainmast.js.map +1 -0
  153. package/dist/plugin.e2e.test.js +1 -1
  154. package/dist/preference-commands.e2e.test.js +103 -24
  155. package/dist/preference-commands.e2e.test.js.map +1 -1
  156. package/dist/project.d.ts +1 -1
  157. package/dist/prompt.d.ts +22 -9
  158. package/dist/prompt.js +64 -48
  159. package/dist/prompt.js.map +1 -1
  160. package/dist/questions.e2e.test.js +13 -13
  161. package/dist/queue-sources.e2e.test.d.ts +1 -0
  162. package/dist/queue-sources.e2e.test.js +168 -0
  163. package/dist/queue-sources.e2e.test.js.map +1 -0
  164. package/dist/queue.d.ts +9 -1
  165. package/dist/queue.e2e.test.js +48 -30
  166. package/dist/queue.e2e.test.js.map +1 -1
  167. package/dist/queue.js +97 -24
  168. package/dist/queue.js.map +1 -1
  169. package/dist/queue.test.d.ts +1 -0
  170. package/dist/queue.test.js +57 -0
  171. package/dist/queue.test.js.map +1 -0
  172. package/dist/remote-send.e2e.test.js +6 -6
  173. package/dist/remote-send.js +2 -1
  174. package/dist/remote-send.js.map +1 -1
  175. package/dist/renderer.e2e.test.js +7 -7
  176. package/dist/restart.e2e.test.js +2 -2
  177. package/dist/routines.e2e.test.js +2 -2
  178. package/dist/scheduler.d.ts +3 -3
  179. package/dist/scheduler.e2e.test.js +43 -20
  180. package/dist/scheduler.e2e.test.js.map +1 -1
  181. package/dist/scheduler.js +4 -2
  182. package/dist/scheduler.js.map +1 -1
  183. package/dist/schema-sql.d.ts +1 -1
  184. package/dist/schema-sql.js +1 -1
  185. package/dist/schema-sql.js.map +1 -1
  186. package/dist/schema.d.ts +152 -6
  187. package/dist/schema.js +12 -0
  188. package/dist/schema.js.map +1 -1
  189. package/dist/session-commands.e2e.test.js +36 -11
  190. package/dist/session-commands.e2e.test.js.map +1 -1
  191. package/dist/session-events.d.ts +18 -6
  192. package/dist/session-events.js +175 -27
  193. package/dist/session-events.js.map +1 -1
  194. package/dist/session-ops.e2e.test.js +63 -12
  195. package/dist/session-ops.e2e.test.js.map +1 -1
  196. package/dist/sessions.d.ts +44 -21
  197. package/dist/sessions.js +177 -65
  198. package/dist/sessions.js.map +1 -1
  199. package/dist/shell.e2e.test.js +4 -4
  200. package/dist/slash-commands.js +6 -4
  201. package/dist/slash-commands.js.map +1 -1
  202. package/dist/slash-commands.test.js +2 -0
  203. package/dist/slash-commands.test.js.map +1 -1
  204. package/dist/sleep.e2e.test.js +29 -14
  205. package/dist/sleep.e2e.test.js.map +1 -1
  206. package/dist/sleeps.d.ts +2 -1
  207. package/dist/sleeps.js +21 -3
  208. package/dist/sleeps.js.map +1 -1
  209. package/dist/store.d.ts +1 -0
  210. package/dist/store.js +3 -2
  211. package/dist/store.js.map +1 -1
  212. package/dist/system-prompt.d.ts +5 -15
  213. package/dist/system-prompt.js +180 -131
  214. package/dist/system-prompt.js.map +1 -1
  215. package/dist/test/generate-log-plugin/index.d.ts +3 -0
  216. package/dist/test/generate-log-plugin/index.js +15 -0
  217. package/dist/test/generate-log-plugin/index.js.map +1 -0
  218. package/dist/test/harness.d.ts +20 -2
  219. package/dist/test/harness.js +51 -11
  220. package/dist/test/harness.js.map +1 -1
  221. package/dist/test/replay.js +11 -8
  222. package/dist/test/replay.js.map +1 -1
  223. package/dist/thread-reducer.d.ts +29 -6
  224. package/dist/thread-reducer.fixtures.test.js +58 -51
  225. package/dist/thread-reducer.fixtures.test.js.map +1 -1
  226. package/dist/thread-reducer.js +109 -50
  227. package/dist/thread-reducer.js.map +1 -1
  228. package/dist/thread-reducer.test.js +190 -48
  229. package/dist/thread-reducer.test.js.map +1 -1
  230. package/dist/tunnel.d.ts +9 -0
  231. package/dist/tunnel.js +117 -28
  232. package/dist/tunnel.js.map +1 -1
  233. package/dist/tunnel.test.js +81 -5
  234. package/dist/tunnel.test.js.map +1 -1
  235. package/dist/voice-attachments.e2e.test.js +108 -18
  236. package/dist/voice-attachments.e2e.test.js.map +1 -1
  237. package/dist/voice-call.e2e.test.js +9 -9
  238. package/dist/voice-call.js +6 -6
  239. package/dist/voice-call.js.map +1 -1
  240. package/dist/voice-openai.e2e.test.js +59 -23
  241. package/dist/voice-openai.e2e.test.js.map +1 -1
  242. package/dist/voice.d.ts +1 -1
  243. package/dist/voice.js +72 -24
  244. package/dist/voice.js.map +1 -1
  245. package/dist/working-directory.e2e.test.js +11 -11
  246. package/dist/working-directory.e2e.test.js.map +1 -1
  247. package/package.json +11 -5
  248. package/skills/kimaki-tunnel/SKILL.md +3 -2
  249. package/src/agent-ui.e2e.test.ts +27 -13
  250. package/src/agent-ui.ts +2 -1
  251. package/src/analytics.e2e.test.ts +1 -1
  252. package/src/autostart.ts +55 -10
  253. package/src/bot.ts +36 -19
  254. package/src/btw.e2e.test.ts +3 -3
  255. package/src/builtin-skills.test.ts +73 -1
  256. package/src/builtin-skills.ts +33 -0
  257. package/src/catalog-refresh.e2e.test.ts +2 -2
  258. package/src/cli/bot.ts +30 -19
  259. package/src/cli/discord.ts +30 -6
  260. package/src/cli/schedule.ts +23 -9
  261. package/src/cli/session.ts +35 -12
  262. package/src/cli/shared.ts +43 -8
  263. package/src/cli-discord.e2e.test.ts +13 -8
  264. package/src/cli-lock.e2e.test.ts +88 -20
  265. package/src/cli-read.e2e.test.ts +17 -8
  266. package/src/cli-sessions.e2e.test.ts +4 -3
  267. package/src/cli.ts +2 -0
  268. package/src/commands/preference-commands.ts +38 -4
  269. package/src/commands/session-commands.ts +12 -7
  270. package/src/commands/thread-commands.ts +92 -24
  271. package/src/commands/worktree-commands.ts +10 -9
  272. package/src/commands.e2e.test.ts +25 -21
  273. package/src/coordinator-agents.e2e.test.ts +145 -0
  274. package/src/coordinator-idle.e2e.test.ts +122 -0
  275. package/src/coordinator-queue.e2e.test.ts +279 -0
  276. package/src/coordinator-warmup.e2e.test.ts +158 -0
  277. package/src/coordinator.e2e.test.ts +545 -0
  278. package/src/coordinator.ts +168 -0
  279. package/src/db.test.ts +1 -0
  280. package/src/diagram.test.ts +56 -0
  281. package/src/diagram.ts +243 -0
  282. package/src/duration.ts +13 -5
  283. package/src/effects.ts +99 -27
  284. package/src/event-loop.ts +71 -45
  285. package/src/format-parts.ts +53 -22
  286. package/src/gateway-replay.e2e.test.ts +4 -4
  287. package/src/harness.e2e.test.ts +2 -2
  288. package/src/hello-thread.e2e.test.ts +59 -5
  289. package/src/ingress.ts +44 -11
  290. package/src/interaction-context.ts +12 -11
  291. package/src/interrupt.e2e.test.ts +8 -5
  292. package/src/legacy.e2e.test.ts +1 -1
  293. package/src/lock-routes.ts +62 -8
  294. package/src/lock-server.ts +23 -7
  295. package/src/main.ts +26 -10
  296. package/src/markdown/markdown.test.ts +15 -4
  297. package/src/markdown/render-markdown.ts +9 -6
  298. package/src/onboarding-cli.e2e.test.ts +7 -6
  299. package/src/onboarding.e2e.test.ts +8 -10
  300. package/src/onboarding.ts +13 -29
  301. package/src/permissions.e2e.test.ts +3 -3
  302. package/src/plugin/coordinator.ts +401 -0
  303. package/src/plugin/index.ts +86 -59
  304. package/src/plugin.e2e.test.ts +1 -1
  305. package/src/preference-commands.e2e.test.ts +103 -23
  306. package/src/prompt.ts +87 -43
  307. package/src/questions.e2e.test.ts +13 -13
  308. package/src/queue-sources.e2e.test.ts +197 -0
  309. package/src/queue.e2e.test.ts +48 -30
  310. package/src/queue.test.ts +59 -0
  311. package/src/queue.ts +104 -24
  312. package/src/remote-send.e2e.test.ts +6 -6
  313. package/src/remote-send.ts +2 -1
  314. package/src/renderer.e2e.test.ts +7 -7
  315. package/src/restart.e2e.test.ts +2 -2
  316. package/src/routines.e2e.test.ts +2 -2
  317. package/src/scheduler.e2e.test.ts +45 -19
  318. package/src/scheduler.ts +4 -2
  319. package/src/schema-sql.ts +1 -1
  320. package/src/schema.ts +13 -0
  321. package/src/session-commands.e2e.test.ts +38 -11
  322. package/src/session-events.ts +168 -25
  323. package/src/session-ops.e2e.test.ts +64 -11
  324. package/src/sessions.ts +217 -67
  325. package/src/shell.e2e.test.ts +4 -4
  326. package/src/slash-commands.test.ts +2 -0
  327. package/src/slash-commands.ts +6 -4
  328. package/src/sleep.e2e.test.ts +30 -13
  329. package/src/sleeps.ts +20 -3
  330. package/src/store.ts +5 -2
  331. package/src/system-prompt.ts +190 -134
  332. package/src/test/generate-log-plugin/index.ts +16 -0
  333. package/src/test/harness.ts +77 -17
  334. package/src/test/replay.ts +12 -7
  335. package/src/thread-reducer.fixtures.test.ts +58 -51
  336. package/src/thread-reducer.test.ts +199 -49
  337. package/src/thread-reducer.ts +135 -66
  338. package/src/tunnel.test.ts +81 -5
  339. package/src/tunnel.ts +124 -25
  340. package/src/voice-attachments.e2e.test.ts +110 -18
  341. package/src/voice-call.e2e.test.ts +9 -9
  342. package/src/voice-call.ts +6 -6
  343. package/src/voice-openai.e2e.test.ts +64 -24
  344. package/src/voice.ts +93 -26
  345. package/src/working-directory.e2e.test.ts +11 -11
  346. package/src/message-tool.e2e.test.ts +0 -45
@@ -0,0 +1,244 @@
1
+ // The queue in a coordinator channel: the channel itself is the conversation, so
2
+ // acks and "Queued message sent" replies land in the channel. Every queued
3
+ // prompt that got an ack is marked when it starts, also when the coordinator
4
+ // answers IDLE; its answer is then not a second reply to the same message.
5
+ import { execFile } from 'node:child_process';
6
+ import fs from 'node:fs';
7
+ import path from 'node:path';
8
+ import { promisify } from 'node:util';
9
+ import { afterAll, beforeAll, expect, test } from 'vitest';
10
+ import { TEST_USER_ID, isFooter, seedProjectChannel, slowTextMatcher, startOpencodeTestServer, startTestBot, startTwin, tempDataDir, textParts, waitFor, waitForBotMessageContaining, waitForFooter, warmUp, } from "./test/harness.js";
11
+ const exec = promisify(execFile);
12
+ function reply(marker, text) {
13
+ return { id: marker, priority: 50, when: { latestUserTextIncludes: marker }, then: { parts: textParts(text) } };
14
+ }
15
+ const matchers = [
16
+ slowTextMatcher({ marker: 'slow-marker', text: 'slow-done', delayMs: 1_200 }),
17
+ reply('queued-idle', 'IDLE'),
18
+ reply('queued-one', 'queued one ok'),
19
+ reply('queued-two', 'queued two ok'),
20
+ reply('steer-marker', 'steer ok'),
21
+ reply('idle-marker', 'idle ok'),
22
+ reply('hello-marker', 'hello'),
23
+ ];
24
+ let server;
25
+ let twin;
26
+ let bot;
27
+ const dataDir = tempDataDir();
28
+ beforeAll(async () => {
29
+ ;
30
+ [server, twin] = await Promise.all([startOpencodeTestServer({ matchers }), startTwin()]);
31
+ await seedProjectChannel({ dataDir, channelId: twin.channelId, guildId: twin.discord.guildId, directory: server.projectDirectory });
32
+ await warmUp({ server });
33
+ bot = await startTestBot({ dataDir, twin, server, coordinator: true });
34
+ // The coordinator session exists before any test: its banner is not part of one test's snapshot.
35
+ await twin.discord.channel(twin.channelId).user(TEST_USER_ID).sendMessage({ content: 'Start hello-marker' });
36
+ await waitForFooter({ discord: twin.discord, threadId: twin.channelId });
37
+ }, 60_000);
38
+ afterAll(async () => {
39
+ await bot?.stop();
40
+ await twin?.stop();
41
+ await server?.stop();
42
+ fs.rmSync(dataDir, { recursive: true, force: true });
43
+ });
44
+ // The channel holds every test's turns: the text from the user message that starts with `content`.
45
+ async function channelTextFrom(content) {
46
+ const text = await twin.discord.channel(twin.channelId).text({ showReplies: true });
47
+ return text.slice(text.lastIndexOf('--- from:', text.lastIndexOf(`\n${content}`)));
48
+ }
49
+ function footers() {
50
+ return twin.discord.channel(twin.channelId).getMessages().then((messages) => messages.filter(isFooter).length);
51
+ }
52
+ // Sends a slow prompt and waits until the coordinator runs it.
53
+ async function startSlowTurn(content) {
54
+ const channel = twin.discord.channel(twin.channelId);
55
+ channel.clearTypingEvents();
56
+ await channel.user(TEST_USER_ID).sendMessage({ content: `${content} slow-marker` });
57
+ await channel.waitForTypingEvent();
58
+ }
59
+ async function waitForIdle() {
60
+ await waitFor({ label: 'coordinator idle', check: async () => !bot.store.getState().threads[twin.channelId]?.turn || null });
61
+ }
62
+ function rootSession() {
63
+ const sessionID = bot.store.getState().roots[twin.channelId];
64
+ if (!sessionID)
65
+ throw new Error('no coordinator session');
66
+ return sessionID;
67
+ }
68
+ test('. queue in a busy coordinator: each queued message gets a reply when it starts, also when it answers IDLE', async () => {
69
+ const before = await footers();
70
+ await startSlowTurn('First a long one');
71
+ const user = twin.discord.channel(twin.channelId).user(TEST_USER_ID);
72
+ const silent = await user.sendMessage({ content: 'Start a worker queued-idle. queue' });
73
+ await waitForBotMessageContaining({ discord: twin.discord, threadId: twin.channelId, text: 'position 1' });
74
+ const answered = await user.sendMessage({ content: 'Then answer queued-two. queue' });
75
+ await waitForBotMessageContaining({ discord: twin.discord, threadId: twin.channelId, text: 'queued two ok' });
76
+ // The IDLE turn posts no footer: slow-done and queued two get one each.
77
+ await waitForFooter({ discord: twin.discord, threadId: twin.channelId, count: before + 2 });
78
+ expect(await channelTextFrom('First a long one')).toMatchInlineSnapshot(`
79
+ "--- from: user (tommy)
80
+ First a long one slow-marker
81
+ Start a worker queued-idle. queue
82
+ --- from: assistant (TestBot)
83
+ [reply to tommy: Start a worker queued-idle. queue]
84
+ -# Queued
85
+ --- from: user (tommy)
86
+ Then answer queued-two. queue
87
+ --- from: assistant (TestBot)
88
+ [reply to tommy: Then answer queued-two. queue]
89
+ -# Queued
90
+ [reply to tommy: First a long one slow-marker]
91
+ slow-done
92
+ -# *main ⋅ Ns ⋅ N% ⋅ deterministic-v2*
93
+ [reply to tommy: Start a worker queued-idle. queue]
94
+ -# Queued message sent
95
+ [reply to tommy: Then answer queued-two. queue]
96
+ -# Queued message sent
97
+ queued two ok
98
+ -# *main ⋅ Ns ⋅ N% ⋅ deterministic-v2*"
99
+ `);
100
+ const messages = await twin.discord.channel(twin.channelId).getMessages();
101
+ const sent = messages.filter((message) => message.content === '-# Queued message sent');
102
+ expect(sent.map((message) => message.message_reference?.message_id)).toEqual([silent.id, answered.id]);
103
+ });
104
+ test('/queue and /clear-queue in a coordinator', async () => {
105
+ const before = await footers();
106
+ await startSlowTurn('Slash queue here');
107
+ const user = twin.discord.channel(twin.channelId).user(TEST_USER_ID);
108
+ await user.runSlashCommand({ name: 'queue', options: [{ name: 'message', type: 3, value: 'Slash queued-one' }] });
109
+ await waitForBotMessageContaining({ discord: twin.discord, threadId: twin.channelId, text: 'position 1' });
110
+ await user.runSlashCommand({ name: 'queue', options: [{ name: 'message', type: 3, value: 'Slash queued-two' }] });
111
+ await waitForBotMessageContaining({ discord: twin.discord, threadId: twin.channelId, text: 'position 2' });
112
+ await user.runSlashCommand({ name: 'clear-queue', options: [{ name: 'position', type: 4, value: 1 }] });
113
+ await waitForBotMessageContaining({ discord: twin.discord, threadId: twin.channelId, text: 'queued two ok' });
114
+ await waitForFooter({ discord: twin.discord, threadId: twin.channelId, count: before + 2 });
115
+ expect(await channelTextFrom('Slash queue here')).toMatchInlineSnapshot(`
116
+ "--- from: user (tommy)
117
+ Slash queue here slow-marker
118
+ --- from: assistant (TestBot)
119
+ -# » **tommy:** Slash queued-one
120
+ [reply to TestBot: -# » **tommy:** Slash queued-one]
121
+ -# Removed from queue
122
+ -# » **tommy:** Slash queued-two
123
+ [reply to TestBot: -# » **tommy:** Slash queued-two]
124
+ -# Queued
125
+ -# Cleared 1 queued message
126
+ [reply to tommy: Slash queue here slow-marker]
127
+ slow-done
128
+ -# *main ⋅ Ns ⋅ N% ⋅ deterministic-v2*
129
+ [reply to TestBot: -# » **tommy:** Slash queued-two]
130
+ -# Queued message sent
131
+ queued two ok
132
+ -# *main ⋅ Ns ⋅ N% ⋅ deterministic-v2*"
133
+ `);
134
+ });
135
+ test('deleting a queued coordinator message removes it from the queue', async () => {
136
+ const before = await footers();
137
+ await startSlowTurn('Delete in coordinator');
138
+ const user = twin.discord.channel(twin.channelId).user(TEST_USER_ID);
139
+ const queued = await user.sendMessage({ content: 'Never mind queued-one. queue' });
140
+ await waitForBotMessageContaining({ discord: twin.discord, threadId: twin.channelId, text: 'position 1' });
141
+ await user.deleteMessage({ messageId: queued.id });
142
+ await waitForBotMessageContaining({ discord: twin.discord, threadId: twin.channelId, text: 'Removed from queue' });
143
+ await waitForFooter({ discord: twin.discord, threadId: twin.channelId, count: before + 1 });
144
+ await waitForIdle();
145
+ expect(await channelTextFrom('Delete in coordinator')).toMatchInlineSnapshot(`
146
+ "--- from: user (tommy)
147
+ Delete in coordinator slow-marker
148
+ --- from: assistant (TestBot)
149
+ [reply to unknown message]
150
+ -# Removed from queue
151
+ [reply to tommy: Delete in coordinator slow-marker]
152
+ slow-done
153
+ -# *main ⋅ Ns ⋅ N% ⋅ deterministic-v2*"
154
+ `);
155
+ });
156
+ test('kimaki send . queue and a TUI prompt queued on the coordinator show their text, then a reply when they run', async () => {
157
+ const before = await footers();
158
+ await startSlowTurn('Other sources');
159
+ await exec(process.execPath, ['--import', 'tsx', path.resolve('src/cli.ts'), 'send', '--session', rootSession(), '--prompt', 'From the CLI queued-one. queue', '--data-dir', dataDir], {
160
+ env: { ...process.env, KIMAKI_LOCK_PORT: String(bot.lock.port) },
161
+ });
162
+ await waitForBotMessageContaining({ discord: twin.discord, threadId: twin.channelId, text: 'position 1' });
163
+ await (await server.client()).session.prompt({ sessionID: rootSession(), text: 'From the TUI queued-two', delivery: 'queue' });
164
+ await waitForBotMessageContaining({ discord: twin.discord, threadId: twin.channelId, text: 'queued two ok' });
165
+ await waitForFooter({ discord: twin.discord, threadId: twin.channelId, count: before + 3 });
166
+ expect(await channelTextFrom('Other sources')).toMatchInlineSnapshot(`
167
+ "--- from: user (tommy)
168
+ Other sources slow-marker
169
+ --- from: assistant (TestBot)
170
+ -# » **CLI:** From the CLI queued-one
171
+ -# » **user:** From the TUI queued-two
172
+ [reply to tommy: Other sources slow-marker]
173
+ slow-done
174
+ -# *main ⋅ Ns ⋅ N% ⋅ deterministic-v2*
175
+ [reply to TestBot: -# » **CLI:** From the CLI queued-one]
176
+ -# Queued message sent
177
+ queued one ok
178
+ -# *main ⋅ Ns ⋅ N% ⋅ deterministic-v2*
179
+ [reply to TestBot: -# » **user:** From the TUI queued-two]
180
+ -# Queued message sent
181
+ queued two ok
182
+ -# *main ⋅ Ns ⋅ N% ⋅ deterministic-v2*"
183
+ `);
184
+ });
185
+ test('a plain message in a busy coordinator runs first, then the queued one gets its reply', async () => {
186
+ const before = await footers();
187
+ await startSlowTurn('Steer the coordinator');
188
+ const user = twin.discord.channel(twin.channelId).user(TEST_USER_ID);
189
+ await user.sendMessage({ content: 'Afterwards queued-one. queue' });
190
+ await waitForBotMessageContaining({ discord: twin.discord, threadId: twin.channelId, text: 'position 1' });
191
+ await user.sendMessage({ content: 'Right now steer-marker' });
192
+ await waitForBotMessageContaining({ discord: twin.discord, threadId: twin.channelId, text: 'queued one ok' });
193
+ await waitForFooter({ discord: twin.discord, threadId: twin.channelId, count: before + 2 });
194
+ expect(await channelTextFrom('Steer the coordinator')).toMatchInlineSnapshot(`
195
+ "--- from: user (tommy)
196
+ Steer the coordinator slow-marker
197
+ Afterwards queued-one. queue
198
+ --- from: assistant (TestBot)
199
+ [reply to tommy: Afterwards queued-one. queue]
200
+ -# Queued
201
+ --- from: user (tommy)
202
+ Right now steer-marker
203
+ --- from: assistant (TestBot)
204
+ [reply to tommy: Right now steer-marker]
205
+ steer ok
206
+ -# *main ⋅ Ns ⋅ N% ⋅ deterministic-v2*
207
+ [reply to tommy: Afterwards queued-one. queue]
208
+ -# Queued message sent
209
+ queued one ok
210
+ -# *main ⋅ Ns ⋅ N% ⋅ deterministic-v2*"
211
+ `);
212
+ });
213
+ test('/abort in a coordinator stops the run and clears the queue', async () => {
214
+ await startSlowTurn('Abort the coordinator');
215
+ const user = twin.discord.channel(twin.channelId).user(TEST_USER_ID);
216
+ await user.sendMessage({ content: 'Never runs queued-one. queue' });
217
+ await waitForBotMessageContaining({ discord: twin.discord, threadId: twin.channelId, text: 'position 1' });
218
+ await user.runSlashCommand({ name: 'abort' });
219
+ await waitForBotMessageContaining({ discord: twin.discord, threadId: twin.channelId, text: 'Removed from queue' });
220
+ await waitForIdle();
221
+ expect(await channelTextFrom('Abort the coordinator')).toMatchInlineSnapshot(`
222
+ "--- from: user (tommy)
223
+ Abort the coordinator slow-marker
224
+ Never runs queued-one. queue
225
+ --- from: assistant (TestBot)
226
+ [reply to tommy: Never runs queued-one. queue]
227
+ -# Removed from queue
228
+ Request **aborted**, cleared 1 queued message"
229
+ `);
230
+ });
231
+ test('. queue on an idle coordinator runs at once: the answer replies to the message', async () => {
232
+ const before = await footers();
233
+ await twin.discord.channel(twin.channelId).user(TEST_USER_ID).sendMessage({ content: 'Nothing waits idle-marker. queue' });
234
+ await waitForFooter({ discord: twin.discord, threadId: twin.channelId, count: before + 1 });
235
+ expect(await channelTextFrom('Nothing waits idle-marker')).toMatchInlineSnapshot(`
236
+ "--- from: user (tommy)
237
+ Nothing waits idle-marker. queue
238
+ --- from: assistant (TestBot)
239
+ [reply to tommy: Nothing waits idle-marker. queue]
240
+ idle ok
241
+ -# *main ⋅ Ns ⋅ N% ⋅ deterministic-v2*"
242
+ `);
243
+ });
244
+ //# sourceMappingURL=coordinator-queue.e2e.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinator-queue.e2e.test.js","sourceRoot":"","sources":["../src/coordinator-queue.e2e.test.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,2EAA2E;AAC3E,6EAA6E;AAC7E,2EAA2E;AAE3E,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAErC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAG1D,OAAO,EACL,YAAY,EACZ,QAAQ,EACR,kBAAkB,EAClB,eAAe,EACf,uBAAuB,EACvB,YAAY,EACZ,SAAS,EACT,WAAW,EACX,SAAS,EACT,OAAO,EACP,2BAA2B,EAC3B,aAAa,EACb,MAAM,GAGP,MAAM,mBAAmB,CAAA;AAE1B,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;AAEhC,SAAS,KAAK,CAAC,MAAc,EAAE,IAAY;IACzC,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,sBAAsB,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,CAAA;AACjH,CAAC;AAED,MAAM,QAAQ,GAA2B;IACvC,eAAe,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC7E,KAAK,CAAC,aAAa,EAAE,MAAM,CAAC;IAC5B,KAAK,CAAC,YAAY,EAAE,eAAe,CAAC;IACpC,KAAK,CAAC,YAAY,EAAE,eAAe,CAAC;IACpC,KAAK,CAAC,cAAc,EAAE,UAAU,CAAC;IACjC,KAAK,CAAC,aAAa,EAAE,SAAS,CAAC;IAC/B,KAAK,CAAC,cAAc,EAAE,OAAO,CAAC;CAC/B,CAAA;AAED,IAAI,MAA0B,CAAA;AAC9B,IAAI,IAAc,CAAA;AAClB,IAAI,GAAc,CAAA;AAClB,MAAM,OAAO,GAAG,WAAW,EAAE,CAAA;AAE7B,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,CAAC;IAAA,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,uBAAuB,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAA;IACzF,MAAM,kBAAkB,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAA;IACnI,MAAM,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAA;IACxB,GAAG,GAAG,MAAM,YAAY,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;IACtE,iGAAiG;IACjG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC,CAAA;IAC5G,MAAM,aAAa,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAA;AAC1E,CAAC,EAAE,MAAM,CAAC,CAAA;AAEV,QAAQ,CAAC,KAAK,IAAI,EAAE;IAClB,MAAM,GAAG,EAAE,IAAI,EAAE,CAAA;IACjB,MAAM,IAAI,EAAE,IAAI,EAAE,CAAA;IAClB,MAAM,MAAM,EAAE,IAAI,EAAE,CAAA;IACpB,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;AACtD,CAAC,CAAC,CAAA;AAEF,mGAAmG;AACnG,KAAK,UAAU,eAAe,CAAC,OAAe;IAC5C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;IACnF,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,CAAA;AACpF,CAAC;AAED,SAAS,OAAO;IACd,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAA;AAChH,CAAC;AAED,+DAA+D;AAC/D,KAAK,UAAU,aAAa,CAAC,OAAe;IAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACpD,OAAO,CAAC,iBAAiB,EAAE,CAAA;IAC3B,MAAM,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,cAAc,EAAE,CAAC,CAAA;IACnF,MAAM,OAAO,CAAC,kBAAkB,EAAE,CAAA;AACpC,CAAC;AAED,KAAK,UAAU,WAAW;IACxB,MAAM,OAAO,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC,CAAA;AAC9H,CAAC;AAED,SAAS,WAAW;IAClB,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IAC5D,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAA;IACzD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,IAAI,CAAC,2GAA2G,EAAE,KAAK,IAAI,EAAE;IAC3H,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAA;IAC9B,MAAM,aAAa,CAAC,kBAAkB,CAAC,CAAA;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;IACpE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,mCAAmC,EAAE,CAAC,CAAA;IACvF,MAAM,2BAA2B,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAA;IAC1G,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAC,CAAA;IACrF,MAAM,2BAA2B,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,CAAA;IAC7G,wEAAwE;IACxE,MAAM,aAAa,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC,CAAA;IAC3F,MAAM,CAAC,MAAM,eAAe,CAAC,kBAAkB,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;GAqBvE,CAAC,CAAA;IACF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAA;IACzE,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,KAAK,wBAAwB,CAAC,CAAA;IACvF,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,iBAAiB,EAAE,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAA;AACxG,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;IAC1D,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAA;IAC9B,MAAM,aAAa,CAAC,kBAAkB,CAAC,CAAA;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;IACpE,MAAM,IAAI,CAAC,eAAe,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,EAAE,CAAC,CAAA;IACjH,MAAM,2BAA2B,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAA;IAC1G,MAAM,IAAI,CAAC,eAAe,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,EAAE,CAAC,CAAA;IACjH,MAAM,2BAA2B,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAA;IAC1G,MAAM,IAAI,CAAC,eAAe,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IACvG,MAAM,2BAA2B,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,CAAA;IAC7G,MAAM,aAAa,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC,CAAA;IAC3F,MAAM,CAAC,MAAM,eAAe,CAAC,kBAAkB,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;GAkBvE,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;IACjF,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAA;IAC9B,MAAM,aAAa,CAAC,uBAAuB,CAAC,CAAA;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;IACpE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC,CAAA;IAClF,MAAM,2BAA2B,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAA;IAC1G,MAAM,IAAI,CAAC,aAAa,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAA;IAClD,MAAM,2BAA2B,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,CAAA;IAClH,MAAM,aAAa,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC,CAAA;IAC3F,MAAM,WAAW,EAAE,CAAA;IACnB,MAAM,CAAC,MAAM,eAAe,CAAC,uBAAuB,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;GAS5E,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,4GAA4G,EAAE,KAAK,IAAI,EAAE;IAC5H,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAA;IAC9B,MAAM,aAAa,CAAC,eAAe,CAAC,CAAA;IACpC,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,UAAU,EAAE,gCAAgC,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE;QACrL,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,gBAAgB,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;KACjE,CAAC,CAAA;IACF,MAAM,2BAA2B,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAA;IAC1G,MAAM,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,yBAAyB,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAA;IAC9H,MAAM,2BAA2B,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,CAAA;IAC7G,MAAM,aAAa,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC,CAAA;IAC3F,MAAM,CAAC,MAAM,eAAe,CAAC,eAAe,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;GAiBpE,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,sFAAsF,EAAE,KAAK,IAAI,EAAE;IACtG,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAA;IAC9B,MAAM,aAAa,CAAC,uBAAuB,CAAC,CAAA;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;IACpE,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC,CAAA;IACnE,MAAM,2BAA2B,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAA;IAC1G,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,wBAAwB,EAAE,CAAC,CAAA;IAC7D,MAAM,2BAA2B,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,CAAA;IAC7G,MAAM,aAAa,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC,CAAA;IAC3F,MAAM,CAAC,MAAM,eAAe,CAAC,uBAAuB,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;GAiB5E,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;IAC5E,MAAM,aAAa,CAAC,uBAAuB,CAAC,CAAA;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;IACpE,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC,CAAA;IACnE,MAAM,2BAA2B,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAA;IAC1G,MAAM,IAAI,CAAC,eAAe,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAA;IAC7C,MAAM,2BAA2B,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,CAAA;IAClH,MAAM,WAAW,EAAE,CAAA;IACnB,MAAM,CAAC,MAAM,eAAe,CAAC,uBAAuB,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;GAQ5E,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;IAChG,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAA;IAC9B,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,kCAAkC,EAAE,CAAC,CAAA;IAC1H,MAAM,aAAa,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC,CAAA;IAC3F,MAAM,CAAC,MAAM,eAAe,CAAC,2BAA2B,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;GAOhF,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,131 @@
1
+ // The coordinator warmup (plugin/coordinator.ts) with short windows: keep-alives while
2
+ // a worker thread runs, compaction when the channel is idle again, and the cap
3
+ // that stops the warmup while a worker is stuck.
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ import { afterAll, beforeAll, expect, test } from 'vitest';
7
+ import { TEST_MODEL, TEST_USER_ID, seedProjectChannel, startOpencodeTestServer, startTestBot, startTwin, tempDataDir, textParts, toolParts, waitFor, waitForFooter, warmUp, } from "./test/harness.js";
8
+ let server;
9
+ let twin;
10
+ let bot;
11
+ const dataDir = tempDataDir();
12
+ // Big enough to be worth compacting (plugin/coordinator.ts MIN_COMPACT_TOKENS).
13
+ const bigUsage = { inputTokens: 120_000, outputTokens: 1, totalTokens: 120_001 };
14
+ const WARM_INTERVAL_MS = 400;
15
+ const WARM_MAX_MS = 1_500;
16
+ function bigText(text) {
17
+ return [
18
+ { type: 'text-start', id: 't' },
19
+ { type: 'text-delta', id: 't', delta: text },
20
+ { type: 'text-end', id: 't' },
21
+ { type: 'finish', finishReason: 'stop', usage: bigUsage },
22
+ ];
23
+ }
24
+ // The coordinator starts a worker thread, then answers IDLE.
25
+ function delegate({ marker, worker, channelId }) {
26
+ const command = `kimaki send --channel ${channelId} --name 'Worker ${worker}' --prompt '${worker} run' --parent-session "$OPENCODE_SESSION_ID"`;
27
+ return [
28
+ {
29
+ id: `${marker}-send`,
30
+ priority: 100,
31
+ when: { latestUserTextIncludes: marker },
32
+ then: { parts: toolParts({ toolCallId: `${marker}-call`, toolName: 'shell', input: { command, description: 'Start the worker', hasSideEffect: true } }) },
33
+ },
34
+ { id: `${marker}-idle`, priority: 101, when: { latestUserTextIncludes: marker, rawPromptIncludes: `${marker}-call` }, then: { parts: [...bigText('IDLE')] } },
35
+ ];
36
+ }
37
+ beforeAll(async () => {
38
+ twin = await startTwin();
39
+ server = await startOpencodeTestServer({
40
+ plugins: [path.resolve('src/test/generate-log-plugin')],
41
+ models: { [TEST_MODEL]: { name: TEST_MODEL, limit: { context: 1_000_000, output: 32_000 } } },
42
+ matchers: [
43
+ // OpenCode rejects a summary without the template headings.
44
+ { id: 'compaction-summary', priority: 900, when: { latestUserTextIncludes: 'You MUST use this format for your response' }, then: { parts: textParts('## Objective\n- Keep coordinating') } },
45
+ ...delegate({ marker: 'keepwarm-marker', worker: 'quickjob-marker', channelId: twin.channelId }),
46
+ ...delegate({ marker: 'capped-marker', worker: 'stuckjob-marker', channelId: twin.channelId }),
47
+ { id: 'quickjob', priority: 100, when: { latestUserTextIncludes: 'quickjob-marker' }, then: { parts: textParts('Quick job done.'), partDelaysMs: [0, 1_200, 0, 0] } },
48
+ { id: 'stuckjob', priority: 100, when: { latestUserTextIncludes: 'stuckjob-marker' }, then: { parts: textParts('Stuck job done.'), partDelaysMs: [0, 3_000, 0, 0] } },
49
+ { id: 'woken', priority: 300, when: { latestUserTextIncludes: '<session-finished' }, then: { parts: [...bigText('The worker finished.')] } },
50
+ ],
51
+ });
52
+ await seedProjectChannel({ dataDir, channelId: twin.channelId, guildId: twin.discord.guildId, directory: server.projectDirectory });
53
+ await warmUp({ server });
54
+ bot = await startTestBot({ dataDir, twin, server, coordinator: true, warmupTimers: { intervalMs: WARM_INTERVAL_MS, maxMs: WARM_MAX_MS } });
55
+ }, 60_000);
56
+ afterAll(async () => {
57
+ await bot?.stop();
58
+ await twin?.stop();
59
+ await server?.stop();
60
+ fs.rmSync(dataDir, { recursive: true, force: true });
61
+ });
62
+ // Keep-alive requests of a session, from the test plugin.
63
+ function keepAlives(sessionId) {
64
+ const file = path.join(server.root, 'generate.log');
65
+ if (!fs.existsSync(file))
66
+ return 0;
67
+ return fs.readFileSync(file, 'utf8').split('\n').filter((line) => line === sessionId).length;
68
+ }
69
+ async function compactions(sessionId) {
70
+ const client = await server.client();
71
+ const messages = await client.message.list({ sessionID: sessionId, order: 'desc', limit: 50 });
72
+ return messages.data.filter((message) => message.type === 'compaction').length;
73
+ }
74
+ test('the coordinator stays warm while its worker runs, then compacts', async () => {
75
+ const { discord, channelId } = twin;
76
+ await discord.channel(channelId).user(TEST_USER_ID).sendMessage({ content: 'Start keepwarm-marker' });
77
+ const root = await waitFor({ label: 'coordinator session', check: async () => bot.store.getState().roots[channelId] });
78
+ await waitForFooter({ discord, threadId: channelId });
79
+ await waitFor({ label: 'compaction after the wake', check: async () => (await compactions(root)) === 1 || null });
80
+ expect(await discord.channel(channelId).text()).toMatchInlineSnapshot(`
81
+ "--- from: user (tommy)
82
+ Start keepwarm-marker
83
+ --- from: assistant (TestBot)
84
+ -# *using deterministic-provider/deterministic-v2 ⋅ build*
85
+ -# Coordinator mode is on: this channel is one session that starts and manages project threads for you. Use /new-session for a thread without it. Turn it off with /toggle-coordinator or start kimaki with \`--coordinator false\`.
86
+ -# ┣ shell _Start the worker_
87
+ The worker finished.
88
+ -# *main ⋅ Ns ⋅ N% ⋅ deterministic-v2*"
89
+ `);
90
+ // The worker runs 1.2s, a keep-alive is due every 0.4s.
91
+ expect(keepAlives(root)).toBeGreaterThan(0);
92
+ const client = await server.client();
93
+ const messages = await client.message.list({ sessionID: root, order: 'asc', limit: 30 });
94
+ // No compaction before the wake: the channel was busy.
95
+ expect(messages.data.map((message) => message.type)).toMatchInlineSnapshot(`
96
+ [
97
+ "synthetic",
98
+ "synthetic",
99
+ "user",
100
+ "assistant",
101
+ "assistant",
102
+ "idle",
103
+ "synthetic",
104
+ "assistant",
105
+ "idle",
106
+ "compaction",
107
+ "idle",
108
+ ]
109
+ `);
110
+ });
111
+ test('a stuck worker stops the warmup at the cap', async () => {
112
+ const { discord, channelId } = twin;
113
+ const root = bot.store.getState().roots[channelId];
114
+ const before = keepAlives(root);
115
+ await discord.channel(channelId).user(TEST_USER_ID).sendMessage({ content: 'Start capped-marker' });
116
+ const worker = await waitFor({
117
+ label: 'stuck worker thread',
118
+ check: async () => (await discord.channel(channelId).getThreads()).find((thread) => thread.name?.includes('stuckjob')),
119
+ });
120
+ // The cap ends the warmup while the worker still runs: compaction, no footer in the worker yet.
121
+ await waitFor({ label: 'compaction at the cap', check: async () => (await compactions(root)) === 2 || null });
122
+ const workerText = await discord.thread(worker.id).text();
123
+ const atCap = keepAlives(root);
124
+ await waitForFooter({ discord, threadId: worker.id });
125
+ expect(workerText).not.toContain('-# *main');
126
+ // 1.5s cap, one keep-alive every 0.4s: at most 3, none after the cap.
127
+ expect(atCap - before).toBeGreaterThan(0);
128
+ expect(atCap - before).toBeLessThanOrEqual(3);
129
+ expect(keepAlives(root)).toBe(atCap);
130
+ });
131
+ //# sourceMappingURL=coordinator-warmup.e2e.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinator-warmup.e2e.test.js","sourceRoot":"","sources":["../src/coordinator-warmup.e2e.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { type Bot } from './bot.ts';
2
+ import type { RunEnded } from './event-loop.ts';
3
+ export declare function createCoordinatorNotes(): {
4
+ register(bot: Bot): void;
5
+ runEnded(run: RunEnded): void;
6
+ };
@@ -0,0 +1 @@
1
+ export {};