message-images-queue-metadata.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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 messageRequestId = `message-${Date.now()}`
  7. const shutdownRequestId = `shutdown-${Date.now()}`
  8. const testImage = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB"
  9. let initSeen = false
  10. let startAccepted = false
  11. let messageAccepted = false
  12. let messageQueued = false
  13. let queueImageCountObserved = false
  14. let shutdownSent = false
  15. let shutdownAck = false
  16. let shutdownDone = false
  17. await runStreamCase({
  18. timeoutMs: 180_000,
  19. onEvent(event: StreamEvent, context) {
  20. if (event.type === "system" && event.subtype === "init" && !initSeen) {
  21. initSeen = true
  22. context.sendCommand({ command: "start", requestId: startRequestId, prompt: LONG_PROMPT })
  23. return
  24. }
  25. if (
  26. event.type === "control" &&
  27. event.subtype === "ack" &&
  28. event.command === "start" &&
  29. event.requestId === startRequestId &&
  30. !startAccepted
  31. ) {
  32. startAccepted = true
  33. context.sendCommand({
  34. command: "message",
  35. requestId: messageRequestId,
  36. prompt: "Respond with exactly IMAGE-QUEUED when this message is processed.",
  37. images: [testImage],
  38. })
  39. return
  40. }
  41. if (
  42. event.type === "control" &&
  43. event.subtype === "ack" &&
  44. event.command === "message" &&
  45. event.requestId === messageRequestId
  46. ) {
  47. messageAccepted = true
  48. return
  49. }
  50. if (
  51. event.type === "control" &&
  52. event.subtype === "done" &&
  53. event.command === "message" &&
  54. event.requestId === messageRequestId &&
  55. event.code === "queued"
  56. ) {
  57. messageQueued = true
  58. return
  59. }
  60. if (
  61. event.type === "queue" &&
  62. (event.subtype === "snapshot" || event.subtype === "enqueued" || event.subtype === "updated") &&
  63. Array.isArray(event.queue) &&
  64. event.queue.some((item) => item?.imageCount === 1)
  65. ) {
  66. queueImageCountObserved = true
  67. if (!shutdownSent) {
  68. context.sendCommand({ command: "shutdown", requestId: shutdownRequestId })
  69. shutdownSent = true
  70. }
  71. return
  72. }
  73. if (
  74. event.type === "control" &&
  75. event.subtype === "ack" &&
  76. event.command === "shutdown" &&
  77. event.requestId === shutdownRequestId
  78. ) {
  79. shutdownAck = true
  80. return
  81. }
  82. if (
  83. event.type === "control" &&
  84. event.subtype === "done" &&
  85. event.command === "shutdown" &&
  86. event.requestId === shutdownRequestId
  87. ) {
  88. shutdownDone = true
  89. }
  90. },
  91. onTimeoutMessage() {
  92. return `timed out waiting for queue image metadata (initSeen=${initSeen}, startAccepted=${startAccepted}, messageAccepted=${messageAccepted}, messageQueued=${messageQueued}, queueImageCountObserved=${queueImageCountObserved}, shutdownSent=${shutdownSent}, shutdownAck=${shutdownAck}, shutdownDone=${shutdownDone})`
  93. },
  94. })
  95. if (!messageAccepted || !messageQueued || !queueImageCountObserved) {
  96. throw new Error(
  97. `expected queued message with image metadata (messageAccepted=${messageAccepted}, messageQueued=${messageQueued}, queueImageCountObserved=${queueImageCountObserved})`,
  98. )
  99. }
  100. if (!shutdownAck || !shutdownDone) {
  101. throw new Error("shutdown control events were not fully observed")
  102. }
  103. }
  104. main().catch((error) => {
  105. console.error(`[FAIL] ${error instanceof Error ? error.message : String(error)}`)
  106. process.exit(1)
  107. })