shutdown-while-running.ts 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import { runStreamCase, StreamEvent } from "../lib/stream-harness"
  2. const LONG_PROMPT =
  3. 'Run exactly this command and do not summarize until it finishes: sleep 20 && echo "done". After it finishes, reply with exactly "done".'
  4. async function main() {
  5. const startRequestId = `start-${Date.now()}`
  6. const shutdownRequestId = `shutdown-${Date.now()}`
  7. let initSeen = false
  8. let startAccepted = false
  9. let shutdownSent = false
  10. let shutdownAck = false
  11. let shutdownDone = false
  12. await runStreamCase({
  13. onEvent(event: StreamEvent, context) {
  14. if (event.type === "system" && event.subtype === "init" && !initSeen) {
  15. initSeen = true
  16. context.sendCommand({
  17. command: "start",
  18. requestId: startRequestId,
  19. prompt: LONG_PROMPT,
  20. })
  21. return
  22. }
  23. if (
  24. event.type === "control" &&
  25. event.subtype === "ack" &&
  26. event.command === "start" &&
  27. event.requestId === startRequestId &&
  28. !startAccepted
  29. ) {
  30. startAccepted = true
  31. context.sendCommand({
  32. command: "shutdown",
  33. requestId: shutdownRequestId,
  34. })
  35. shutdownSent = true
  36. return
  37. }
  38. if (
  39. event.type === "control" &&
  40. event.subtype === "ack" &&
  41. event.command === "shutdown" &&
  42. event.requestId === shutdownRequestId
  43. ) {
  44. shutdownAck = true
  45. return
  46. }
  47. if (
  48. event.type === "control" &&
  49. event.subtype === "done" &&
  50. event.command === "shutdown" &&
  51. event.requestId === shutdownRequestId
  52. ) {
  53. shutdownDone = true
  54. }
  55. },
  56. onTimeoutMessage() {
  57. return `timed out waiting for shutdown flow (initSeen=${initSeen}, startAccepted=${startAccepted}, shutdownSent=${shutdownSent}, shutdownAck=${shutdownAck}, shutdownDone=${shutdownDone})`
  58. },
  59. })
  60. if (!shutdownAck || !shutdownDone) {
  61. throw new Error("shutdown control events were not fully observed")
  62. }
  63. }
  64. main().catch((error) => {
  65. console.error(`[FAIL] ${error instanceof Error ? error.message : String(error)}`)
  66. process.exit(1)
  67. })