@opengeni/react 1.0.1 → 2.3.0-canary.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 (174) hide show
  1. package/README.md +33 -10
  2. package/dist/artifacts-spreadsheet.js +1 -1
  3. package/dist/artifacts.js +1 -1
  4. package/dist/browser-viewer-GXUICIAG.js +14 -0
  5. package/dist/{chunk-R3AZOAB5.js → chunk-4MDLEHXL.js} +9 -115
  6. package/dist/chunk-4MDLEHXL.js.map +1 -0
  7. package/dist/chunk-5YK2ZDIG.js +116 -0
  8. package/dist/chunk-5YK2ZDIG.js.map +1 -0
  9. package/dist/chunk-H5YGYNXS.js +329 -0
  10. package/dist/chunk-H5YGYNXS.js.map +1 -0
  11. package/dist/{chunk-7WCLAEFV.js → chunk-ICA6R6TW.js} +2 -2
  12. package/dist/{chunk-7WCLAEFV.js.map → chunk-ICA6R6TW.js.map} +1 -1
  13. package/dist/{chunk-IGC6A2ZI.js → chunk-JOAVA2TW.js} +589 -217
  14. package/dist/chunk-JOAVA2TW.js.map +1 -0
  15. package/dist/{chunk-Y7OEDUJ5.js → chunk-LS4POUTY.js} +1057 -426
  16. package/dist/chunk-LS4POUTY.js.map +1 -0
  17. package/dist/{chunk-5UQPNLIO.js → chunk-LTCHJ4MS.js} +9 -9
  18. package/dist/chunk-LTCHJ4MS.js.map +1 -0
  19. package/dist/{chunk-C5ZPSSS5.js → chunk-NEXLLTP4.js} +2 -1
  20. package/dist/{chunk-C5ZPSSS5.js.map → chunk-NEXLLTP4.js.map} +1 -1
  21. package/dist/chunk-QGBJ6GHG.js +2300 -0
  22. package/dist/chunk-QGBJ6GHG.js.map +1 -0
  23. package/dist/{chunk-6KLX2RH5.js → chunk-RSXJN73N.js} +365 -21
  24. package/dist/chunk-RSXJN73N.js.map +1 -0
  25. package/dist/{chunk-B6WPZSTT.js → chunk-SE4W4WQ3.js} +78 -16
  26. package/dist/chunk-SE4W4WQ3.js.map +1 -0
  27. package/dist/{chunk-MKPIAGVL.js → chunk-W6NFJXSA.js} +8 -19
  28. package/dist/chunk-W6NFJXSA.js.map +1 -0
  29. package/dist/{chunk-XBZWOM2K.js → chunk-X4A66EWZ.js} +8 -3
  30. package/dist/chunk-X4A66EWZ.js.map +1 -0
  31. package/dist/chunk-X4JAFD5R.js +3907 -0
  32. package/dist/chunk-X4JAFD5R.js.map +1 -0
  33. package/dist/{chunk-HA46CYQK.js → chunk-XXWH2JLC.js} +792 -206
  34. package/dist/chunk-XXWH2JLC.js.map +1 -0
  35. package/dist/client.d.ts +2 -2
  36. package/dist/components/browser-viewer.d.ts +7 -1
  37. package/dist/components/computer-viewer.d.ts +4 -1
  38. package/dist/components/enrollment-consent.d.ts +6 -3
  39. package/dist/components/file-browser.d.ts +7 -1
  40. package/dist/components/human-input-form.d.ts +1 -1
  41. package/dist/components/human-input-surface.d.ts +1 -1
  42. package/dist/components/machine-card.d.ts +4 -1
  43. package/dist/components/machines/machine-detail.d.ts +4 -1
  44. package/dist/components/machines/machine-operation-policy.d.ts +11 -0
  45. package/dist/components/machines-dashboard.d.ts +3 -1
  46. package/dist/components/markdown.d.ts +20 -1
  47. package/dist/components/message-timeline.d.ts +1 -1
  48. package/dist/components/model-policy-picker.d.ts +2 -0
  49. package/dist/components/pierre-file.d.ts +1 -1
  50. package/dist/components/sandbox-files.d.ts +8 -2
  51. package/dist/components/sandbox-workspace.d.ts +33 -3
  52. package/dist/components/session-chrome.d.ts +15 -3
  53. package/dist/components/workspace-dock.d.ts +6 -2
  54. package/dist/composer.js +5 -5
  55. package/dist/computer-viewer-ZOP4Q7A7.js +16 -0
  56. package/dist/computer-viewer-ZOP4Q7A7.js.map +1 -0
  57. package/dist/hooks/channel-cache.d.ts +23 -0
  58. package/dist/hooks/shared-machines-list.d.ts +14 -0
  59. package/dist/hooks/use-attached-browsers.d.ts +2 -1
  60. package/dist/hooks/use-channels.d.ts +1 -0
  61. package/dist/hooks/use-composer.d.ts +37 -9
  62. package/dist/hooks/use-machine-chip.d.ts +3 -3
  63. package/dist/hooks/use-machines.d.ts +19 -1
  64. package/dist/hooks/use-sandbox-files.d.ts +1 -0
  65. package/dist/hooks/use-session-background-commands.d.ts +14 -0
  66. package/dist/hooks/use-turn-queue.d.ts +12 -0
  67. package/dist/hooks/use-workspace-sessions.d.ts +1 -0
  68. package/dist/index.d.ts +7 -5
  69. package/dist/index.js +1096 -623
  70. package/dist/index.js.map +1 -1
  71. package/dist/interaction.js +29 -181
  72. package/dist/interaction.js.map +1 -1
  73. package/dist/lib/interaction-errors.d.ts +3 -0
  74. package/dist/machines.d.ts +4 -2
  75. package/dist/machines.js +10 -2
  76. package/dist/model-policy.d.ts +1 -1
  77. package/dist/model-policy.js +1 -1
  78. package/dist/platform-activity-row-BJHUHXAT.js +169 -0
  79. package/dist/platform-activity-row-BJHUHXAT.js.map +1 -0
  80. package/dist/{queue-surface-implementation-2KVJTYXH.js → queue-surface-implementation-BSKUWHRI.js} +76 -16
  81. package/dist/queue-surface-implementation-BSKUWHRI.js.map +1 -0
  82. package/dist/realtime/realtime-control.d.ts +6 -3
  83. package/dist/realtime.js +36 -14
  84. package/dist/realtime.js.map +1 -1
  85. package/dist/session-ui.d.ts +1 -1
  86. package/dist/session-ui.js +6 -2
  87. package/dist/session.d.ts +2 -2
  88. package/dist/session.js +4 -4
  89. package/dist/timeline/index.d.ts +1 -1
  90. package/dist/timeline/platform-activity-row.d.ts +15 -0
  91. package/dist/timeline/screenshot-lightbox.d.ts +1 -1
  92. package/dist/timeline/shared.d.ts +4 -2
  93. package/dist/timeline/types.d.ts +50 -5
  94. package/dist/types/machines.d.ts +2 -2
  95. package/package.json +3 -3
  96. package/src/client.ts +12 -1
  97. package/src/components/artifacts/editable-spreadsheet.tsx +1 -1
  98. package/src/components/browser-viewer.tsx +361 -58
  99. package/src/components/chat-composer.tsx +1 -1
  100. package/src/components/composer.tsx +6 -6
  101. package/src/components/computer-viewer.tsx +368 -115
  102. package/src/components/enrollment-consent.tsx +64 -6
  103. package/src/components/file-browser.tsx +117 -2
  104. package/src/components/human-input-form.tsx +103 -59
  105. package/src/components/human-input-surface.tsx +1 -1
  106. package/src/components/machine-card.tsx +111 -0
  107. package/src/components/machine-input-display.ts +15 -0
  108. package/src/components/machines/machine-detail.tsx +47 -0
  109. package/src/components/machines/machine-operation-policy.tsx +179 -0
  110. package/src/components/machines-dashboard.tsx +6 -0
  111. package/src/components/markdown.tsx +174 -20
  112. package/src/components/message-timeline.tsx +215 -18
  113. package/src/components/model-policy-picker.tsx +9 -17
  114. package/src/components/pierre-file.tsx +1 -1
  115. package/src/components/queue-surface-implementation.tsx +82 -16
  116. package/src/components/sandbox-files.tsx +135 -19
  117. package/src/components/sandbox-workspace.tsx +204 -92
  118. package/src/components/session-chrome.tsx +415 -208
  119. package/src/components/session-status.tsx +1 -1
  120. package/src/components/user-message-body.tsx +168 -48
  121. package/src/components/workspace-dock.tsx +141 -175
  122. package/src/hooks/channel-cache.ts +104 -0
  123. package/src/hooks/shared-machines-list.ts +239 -0
  124. package/src/hooks/use-attached-browsers.ts +5 -1
  125. package/src/hooks/use-browser-frame-stream.ts +6 -1
  126. package/src/hooks/use-browser-session.ts +6 -4
  127. package/src/hooks/use-browser-sessions.ts +7 -1
  128. package/src/hooks/use-channels.ts +32 -10
  129. package/src/hooks/use-composer.ts +760 -291
  130. package/src/hooks/use-computer-frame-stream.ts +14 -9
  131. package/src/hooks/use-computer-session.ts +16 -14
  132. package/src/hooks/use-computer-sessions.ts +8 -1
  133. package/src/hooks/use-last-started-turn-policy.ts +1 -1
  134. package/src/hooks/use-machine-chip.ts +23 -6
  135. package/src/hooks/use-machines.ts +104 -6
  136. package/src/hooks/use-sandbox-files.ts +195 -140
  137. package/src/hooks/use-sandbox-git.ts +58 -29
  138. package/src/hooks/use-session-background-commands.ts +56 -0
  139. package/src/hooks/use-session-capabilities.ts +18 -0
  140. package/src/hooks/use-turn-queue.ts +111 -12
  141. package/src/hooks/use-workspace-sessions.ts +5 -1
  142. package/src/index.ts +26 -4
  143. package/src/lib/interaction-errors.ts +18 -0
  144. package/src/machines.ts +9 -1
  145. package/src/model-policy.ts +10 -2
  146. package/src/realtime/realtime-control.tsx +53 -17
  147. package/src/session-context.ts +1 -0
  148. package/src/session-ui.ts +6 -1
  149. package/src/session.ts +9 -1
  150. package/src/timeline/activity-rail.tsx +20 -75
  151. package/src/timeline/index.ts +4 -0
  152. package/src/timeline/platform-activity-row.tsx +201 -0
  153. package/src/timeline/projection.ts +529 -25
  154. package/src/timeline/screenshot-lightbox.tsx +48 -14
  155. package/src/timeline/shared.tsx +8 -2
  156. package/src/timeline/tool-renderers.tsx +104 -6
  157. package/src/timeline/turn-summary.tsx +6 -1
  158. package/src/timeline/types.ts +77 -2
  159. package/src/types/machines.ts +10 -0
  160. package/styles/compiled.css +115 -104
  161. package/dist/chunk-5UQPNLIO.js.map +0 -1
  162. package/dist/chunk-6KLX2RH5.js.map +0 -1
  163. package/dist/chunk-B6WPZSTT.js.map +0 -1
  164. package/dist/chunk-HA46CYQK.js.map +0 -1
  165. package/dist/chunk-IGC6A2ZI.js.map +0 -1
  166. package/dist/chunk-LLOLUHVG.js +0 -5937
  167. package/dist/chunk-LLOLUHVG.js.map +0 -1
  168. package/dist/chunk-MKPIAGVL.js.map +0 -1
  169. package/dist/chunk-R3AZOAB5.js.map +0 -1
  170. package/dist/chunk-XBZWOM2K.js.map +0 -1
  171. package/dist/chunk-Y7OEDUJ5.js.map +0 -1
  172. package/dist/interactive-workbench-viewers-TOHBXJEE.js +0 -15
  173. package/dist/queue-surface-implementation-2KVJTYXH.js.map +0 -1
  174. /package/dist/{interactive-workbench-viewers-TOHBXJEE.js.map → browser-viewer-GXUICIAG.js.map} +0 -0
@@ -310,6 +310,67 @@ function buildTimeline(events) {
310
310
  const items = [];
311
311
  const prescan = prescanTurnAnchors(events);
312
312
  const ordered = orderTimelineEvents(events, prescan);
313
+ const humanInputRequests = humanInputRequestsById(events);
314
+ const humanInputToolCallIds = new Set(
315
+ [...humanInputRequests.values()].map((request) => stringValue(request.toolCallId)).filter(Boolean)
316
+ );
317
+ const queuedAtByTurn = /* @__PURE__ */ new Map();
318
+ const startupRecoveryRevisionByTurn = /* @__PURE__ */ new Map();
319
+ const startupPhases = /* @__PURE__ */ new Map();
320
+ let startupEvent;
321
+ let startupTurnId = null;
322
+ let startupAttemptId = null;
323
+ let startupRecoveryRevision = 0;
324
+ const settleStartupPhase = (phase, status, duration, outcome, mode = 0, explicitStartedAt, explicitId) => {
325
+ const key = `${startupTurnId}:${phase}`;
326
+ const priorState = startupPhases.get(key);
327
+ const prior = priorState?.[0];
328
+ const comparedByAttempt = priorState?.[1] && startupAttemptId;
329
+ const sameAttempt = comparedByAttempt ? priorState[1] === startupAttemptId : (priorState?.[2] ?? 0) === startupRecoveryRevision;
330
+ const open = prior?.status === "running" && sameAttempt ? prior : void 0;
331
+ const replacesPriorAttempt = prior !== void 0 && (comparedByAttempt ? !sameAttempt : startupRecoveryRevision > (priorState?.[2] ?? 0));
332
+ if (replacesPriorAttempt && prior.status === "complete") return;
333
+ if (mode === 2 && prior && !replacesPriorAttempt) return;
334
+ if (mode === 1 && !open) return;
335
+ if (!replacesPriorAttempt && status !== "running" && open) {
336
+ open.status = status;
337
+ open.completedAt = startupEvent.occurredAt;
338
+ open.durationMs = duration === null ? elapsedDurationMs(open.startedAt, startupEvent.occurredAt) : Math.max(0, duration);
339
+ open.outcome = outcome ?? open.outcome;
340
+ return;
341
+ }
342
+ const running = status === "running";
343
+ const durationMs = running || duration === null ? null : Math.max(0, duration);
344
+ const completedEpoch = Date.parse(startupEvent.occurredAt);
345
+ const startedAt = explicitStartedAt ?? (!running && durationMs !== null && Number.isFinite(completedEpoch) ? new Date(completedEpoch - durationMs).toISOString() : startupEvent.occurredAt);
346
+ if (replacesPriorAttempt) {
347
+ Object.assign(prior, {
348
+ id: explicitId ?? startupEvent.id,
349
+ status,
350
+ startedAt,
351
+ completedAt: running ? null : startupEvent.occurredAt,
352
+ durationMs,
353
+ outcome,
354
+ occurredAt: startedAt
355
+ });
356
+ startupPhases.set(key, [prior, startupAttemptId, startupRecoveryRevision]);
357
+ return;
358
+ }
359
+ const item = {
360
+ kind: "startup-phase",
361
+ id: explicitId ?? startupEvent.id,
362
+ turnId: startupTurnId,
363
+ phase,
364
+ status,
365
+ startedAt,
366
+ completedAt: running ? null : startupEvent.occurredAt,
367
+ durationMs,
368
+ outcome,
369
+ occurredAt: startedAt
370
+ };
371
+ items.push(item);
372
+ startupPhases.set(key, [item, startupAttemptId, startupRecoveryRevision]);
373
+ };
313
374
  const last = () => items[items.length - 1];
314
375
  const closeStreamingTail = () => {
315
376
  const open = last();
@@ -317,7 +378,7 @@ function buildTimeline(events) {
317
378
  open.streaming = false;
318
379
  }
319
380
  };
320
- const finalizeOpen = (turnId, disposition = "complete") => {
381
+ const finalizeOpen = (turnId, disposition = "complete", completedAt) => {
321
382
  for (const item of items) {
322
383
  if (turnId !== void 0 && "turnId" in item && item.turnId && turnId && item.turnId !== turnId) {
323
384
  continue;
@@ -331,11 +392,34 @@ function buildTimeline(events) {
331
392
  if (item.kind === "sandbox" && item.status === "running") {
332
393
  item.status = disposition;
333
394
  }
395
+ if (item.kind === "startup-phase" && item.status === "running") {
396
+ item.status = disposition;
397
+ if (completedAt) {
398
+ item.completedAt = completedAt;
399
+ item.durationMs = elapsedDurationMs(item.startedAt, completedAt);
400
+ }
401
+ }
334
402
  }
335
403
  };
336
404
  for (const event of ordered) {
337
405
  const payload = asRecord2(event.payload);
338
406
  const turnId = event.turnId ?? null;
407
+ startupEvent = event;
408
+ startupTurnId = turnId;
409
+ startupAttemptId = (typeof event.turnAttemptId === "string" ? event.turnAttemptId : null) ?? stringValue(payload.attemptId);
410
+ startupRecoveryRevision = turnId ? startupRecoveryRevisionByTurn.get(turnId) ?? 0 : 0;
411
+ const setupPhase = event.type.startsWith("rig.setup.") ? "rig" : event.type.startsWith("turn.startup.phase.") ? startupPhaseFromPayload(payload.phase) : null;
412
+ const setupStatus = event.type.endsWith(".started") ? "running" : event.type.endsWith(".failed") ? "failed" : event.type.endsWith(".completed") || event.type === "rig.setup.skipped" ? "complete" : null;
413
+ if (setupPhase && setupStatus) {
414
+ closeStreamingTail();
415
+ settleStartupPhase(
416
+ setupPhase,
417
+ setupStatus,
418
+ numberOrNull(payload.durationMs),
419
+ event.type === "rig.setup.skipped" ? "skipped" : null
420
+ );
421
+ continue;
422
+ }
339
423
  switch (event.type) {
340
424
  case "user.message": {
341
425
  closeStreamingTail();
@@ -360,6 +444,7 @@ function buildTimeline(events) {
360
444
  items.push({
361
445
  kind: "user-message",
362
446
  id: event.id,
447
+ ...event.clientEventId ? { reconciliationKey: `user-message:${event.clientEventId}` } : {},
363
448
  text: voiceMessage?.text ?? stringValue(payload.text),
364
449
  annotations: timelineAnnotations(payload.annotations),
365
450
  annotationSource: {
@@ -377,6 +462,13 @@ function buildTimeline(events) {
377
462
  });
378
463
  break;
379
464
  }
465
+ case "user.humanInputResponse": {
466
+ const item = humanInputItemFromResponse(event, payload, humanInputRequests);
467
+ if (!item) break;
468
+ closeStreamingTail();
469
+ items.push(item);
470
+ break;
471
+ }
380
472
  case "system.update.delivered": {
381
473
  const inputs = machineInputMembers(payload.members);
382
474
  if (inputs.length === 0) break;
@@ -416,6 +508,7 @@ function buildTimeline(events) {
416
508
  }
417
509
  case "agent.message.completed": {
418
510
  const text = stringValue(payload.text);
511
+ const phase = assistantMessagePhase(payload.phase);
419
512
  let openIndex = -1;
420
513
  for (let index = items.length - 1; index >= 0; index -= 1) {
421
514
  const candidate2 = items[index];
@@ -431,6 +524,7 @@ function buildTimeline(events) {
431
524
  open.text = text || open.text;
432
525
  }
433
526
  open.streaming = false;
527
+ if (phase) open.phase = phase;
434
528
  open.occurredAt = event.occurredAt;
435
529
  open.annotationSource = text && open.text === text ? {
436
530
  kind: "assistant_message",
@@ -452,6 +546,7 @@ function buildTimeline(events) {
452
546
  id: event.id,
453
547
  turnId,
454
548
  text,
549
+ ...phase ? { phase } : {},
455
550
  streaming: false,
456
551
  occurredAt: event.occurredAt,
457
552
  annotationSource: {
@@ -492,6 +587,9 @@ function buildTimeline(events) {
492
587
  const callId = typeof payload.id === "string" ? payload.id : null;
493
588
  const args = payload.arguments ?? null;
494
589
  closeStreamingTail();
590
+ if (callId && humanInputToolCallIds.has(callId)) {
591
+ break;
592
+ }
495
593
  if (toolMatchesLeaf(name, WORKER_SPAWN_TOOL) || toolMatchesLeaf(name, WORKER_MESSAGE_TOOL)) {
496
594
  items.push({
497
595
  kind: "worker",
@@ -574,20 +672,49 @@ function buildTimeline(events) {
574
672
  }
575
673
  break;
576
674
  }
675
+ case "turn.queued": {
676
+ const queuedTurnId = turnId ?? (typeof payload.turnId === "string" ? payload.turnId : null);
677
+ if (queuedTurnId) {
678
+ queuedAtByTurn.set(queuedTurnId, event.occurredAt);
679
+ }
680
+ break;
681
+ }
682
+ case "turn.started": {
683
+ if (!turnId) break;
684
+ const queuedAt = queuedAtByTurn.get(turnId);
685
+ if (!queuedAt) break;
686
+ queuedAtByTurn.delete(turnId);
687
+ closeStreamingTail();
688
+ settleStartupPhase(
689
+ "queue",
690
+ "complete",
691
+ elapsedDurationMs(queuedAt, event.occurredAt),
692
+ null,
693
+ 0,
694
+ queuedAt,
695
+ `${event.id}-queue`
696
+ );
697
+ break;
698
+ }
577
699
  case "sandbox.operation.started":
578
700
  case "sandbox.operation.completed":
579
701
  case "sandbox.operation.failed": {
580
702
  const name = typeof payload.name === "string" ? payload.name : "sandbox";
581
- const status = event.type.endsWith(".failed") ? "failed" : event.type.endsWith(".completed") ? "complete" : "running";
703
+ const status = event.type.endsWith(".failed") ? payload.expectedTransition === true ? "cancelled" : "failed" : event.type.endsWith(".completed") ? "complete" : "running";
704
+ const origin = payload.origin === "created" || payload.origin === "restored" || payload.origin === "resumed" ? payload.origin : null;
705
+ const startupPhase = startupPhaseForSandboxOperation(name);
706
+ if (startupPhase) {
707
+ closeStreamingTail();
708
+ settleStartupPhase(startupPhase, status, numberOrNull(payload.durationMs), origin);
709
+ break;
710
+ }
582
711
  if ((name === "repository-clone" || name === "file-resource-download") && status !== "failed") {
583
712
  break;
584
713
  }
585
714
  const existing = findOpenSandbox(items, name);
586
715
  if (existing && status !== "running") {
587
716
  existing.status = status;
588
- if (payload.origin === "created" || payload.origin === "restored" || payload.origin === "resumed") {
589
- existing.origin = payload.origin;
590
- }
717
+ if (origin) existing.origin = origin;
591
718
  const message = failureMessage(payload);
592
719
  if (message) {
593
720
  existing.output = existing.output ? `${existing.output}
@@ -604,13 +731,28 @@ ${message}` : message;
604
731
  name,
605
732
  command: typeof payload.command === "string" ? payload.command : null,
606
733
  output: failureMessage(payload) ?? "",
607
- origin: payload.origin === "created" || payload.origin === "restored" || payload.origin === "resumed" ? payload.origin : null,
734
+ origin,
608
735
  status,
609
736
  occurredAt: event.occurredAt
610
737
  });
611
738
  }
612
739
  break;
613
740
  }
741
+ case "agent.model.request": {
742
+ const requestPhase = typeof payload.phase === "string" ? payload.phase : null;
743
+ const status = requestPhase === "started" ? "running" : requestPhase === "first_byte" || requestPhase === "first_event" ? "complete" : requestPhase === "failed" || requestPhase === "timed_out" ? "failed" : null;
744
+ if (status) {
745
+ if (status === "running") closeStreamingTail();
746
+ settleStartupPhase(
747
+ "provider_first_byte",
748
+ status,
749
+ status === "running" ? null : numberOrNull(payload.durationMs),
750
+ null,
751
+ status === "running" ? 2 : 1
752
+ );
753
+ }
754
+ break;
755
+ }
614
756
  case "sandbox.command.output.delta": {
615
757
  const text = typeof payload.chunk === "string" ? payload.chunk : typeof payload.text === "string" ? payload.text : typeof payload.output === "string" ? payload.output : "";
616
758
  if (!text) {
@@ -645,7 +787,7 @@ ${message}` : message;
645
787
  break;
646
788
  }
647
789
  case "session.requiresAction": {
648
- finalizeOpen(turnId);
790
+ finalizeOpen(turnId, "complete", event.occurredAt);
649
791
  items.push({
650
792
  kind: "notice",
651
793
  id: event.id,
@@ -702,6 +844,12 @@ ${message}` : message;
702
844
  break;
703
845
  }
704
846
  case "turn.recovery.requested": {
847
+ if (turnId) {
848
+ startupRecoveryRevisionByTurn.set(
849
+ turnId,
850
+ (startupRecoveryRevisionByTurn.get(turnId) ?? 0) + 1
851
+ );
852
+ }
705
853
  break;
706
854
  }
707
855
  case "turn.event.rejected_late": {
@@ -734,11 +882,11 @@ ${message}` : message;
734
882
  }
735
883
  case "turn.completed": {
736
884
  if (payload.maintenance === "context_compaction") {
737
- finalizeOpen(turnId);
885
+ finalizeOpen(turnId, "complete", event.occurredAt);
738
886
  break;
739
887
  }
740
888
  if (isCreditExhaustionPayload(payload)) {
741
- finalizeOpen(turnId);
889
+ finalizeOpen(turnId, "complete", event.occurredAt);
742
890
  items.push(turnEndItem(event, "failed", CREDIT_EXHAUSTION_MESSAGE));
743
891
  items.push({
744
892
  kind: "notice",
@@ -749,14 +897,14 @@ ${message}` : message;
749
897
  });
750
898
  break;
751
899
  }
752
- finalizeOpen(turnId);
900
+ finalizeOpen(turnId, "complete", event.occurredAt);
753
901
  items.push(turnEndItem(event, "complete", null));
754
902
  break;
755
903
  }
756
904
  case "turn.failed": {
757
905
  const hadActivity = hasTurnActivity(items, turnId);
758
906
  const failureText = isCreditExhaustionPayload(payload) ? CREDIT_EXHAUSTION_MESSAGE : failureMessage(payload);
759
- finalizeOpen(turnId, "cancelled");
907
+ finalizeOpen(turnId, "cancelled", event.occurredAt);
760
908
  items.push(turnEndItem(event, "failed", failureText));
761
909
  if (!hadActivity) {
762
910
  items.push({
@@ -774,7 +922,7 @@ ${message}` : message;
774
922
  break;
775
923
  }
776
924
  const hadActivity = hasTurnActivity(items, turnId);
777
- finalizeOpen(turnId, "cancelled");
925
+ finalizeOpen(turnId, "cancelled", event.occurredAt);
778
926
  items.push(turnEndItem(event, "cancelled", null));
779
927
  if (!hadActivity) {
780
928
  items.push({
@@ -810,6 +958,7 @@ ${message}` : message;
810
958
  case "goal.paused":
811
959
  case "goal.resumed":
812
960
  case "goal.cleared":
961
+ case "goal.held":
813
962
  case "goal.continuation": {
814
963
  if (shouldSuppressAgentGoalLandmark(event.type, payload)) {
815
964
  break;
@@ -818,7 +967,7 @@ ${message}` : message;
818
967
  kind: "goal",
819
968
  id: event.id,
820
969
  action: event.type.slice("goal.".length),
821
- text: goalText(payload),
970
+ text: event.type === "goal.held" && typeof payload.reason === "string" && payload.reason ? payload.reason : goalText(payload),
822
971
  occurredAt: event.occurredAt
823
972
  });
824
973
  break;
@@ -843,6 +992,93 @@ function realtimeVoiceMessage(payload) {
843
992
  }
844
993
  return null;
845
994
  }
995
+ function humanInputRequestsById(events) {
996
+ const requests = /* @__PURE__ */ new Map();
997
+ for (const event of events) {
998
+ if (event.type !== "session.humanInput.requested") continue;
999
+ const request = asRecord2(asRecord2(event.payload).request);
1000
+ const requestId = stringValue(request.id);
1001
+ if (requestId) requests.set(requestId, request);
1002
+ }
1003
+ return requests;
1004
+ }
1005
+ function humanInputItemFromResponse(event, payload, requests) {
1006
+ const response = asRecord2(payload.response);
1007
+ const outcome = response.outcome;
1008
+ if (outcome !== "answered" && outcome !== "skipped" && outcome !== "expired" && outcome !== "cancelled") {
1009
+ return null;
1010
+ }
1011
+ const requestId = stringValue(payload.requestId);
1012
+ const request = requests.get(requestId);
1013
+ const questions = humanInputQuestions(request?.questions);
1014
+ const normalizedResponse = outcome === "answered" ? {
1015
+ outcome,
1016
+ answers: Array.isArray(response.answers) ? response.answers.map(asRecord2).map(humanInputAnswer).filter((answer) => answer !== null) : []
1017
+ } : { outcome };
1018
+ const questionsById = new Map(questions.map((question) => [question.id, question]));
1019
+ const answers = normalizedResponse.outcome === "answered" ? normalizedResponse.answers.map(
1020
+ (answer) => humanInputAnswerSummary(answer, questionsById.get(answer.questionId))
1021
+ ) : [];
1022
+ return {
1023
+ kind: "human-input",
1024
+ id: event.id,
1025
+ turnId: event.turnId ?? null,
1026
+ requestId,
1027
+ questions,
1028
+ response: normalizedResponse,
1029
+ answers,
1030
+ occurredAt: event.occurredAt
1031
+ };
1032
+ }
1033
+ function humanInputQuestions(value) {
1034
+ if (!Array.isArray(value)) return [];
1035
+ return value.map(asRecord2).flatMap((question) => {
1036
+ const id = stringValue(question.id);
1037
+ const prompt = stringValue(question.prompt);
1038
+ const kind = question.kind;
1039
+ if (!id || !prompt || kind !== "text" && kind !== "single_select" && kind !== "multi_select") {
1040
+ return [];
1041
+ }
1042
+ const options = Array.isArray(question.options) ? question.options.map(asRecord2).flatMap((option) => {
1043
+ const optionId = stringValue(option.id);
1044
+ const label = stringValue(option.label);
1045
+ return optionId && label ? [{ id: optionId, label, description: stringValue(option.description) || null }] : [];
1046
+ }) : [];
1047
+ return [
1048
+ {
1049
+ id,
1050
+ kind,
1051
+ prompt,
1052
+ label: stringValue(question.label) || null,
1053
+ helpText: stringValue(question.helpText) || null,
1054
+ options,
1055
+ required: question.required === true,
1056
+ allowOther: question.allowOther === true
1057
+ }
1058
+ ];
1059
+ });
1060
+ }
1061
+ function humanInputAnswer(value) {
1062
+ const questionId = stringValue(value.questionId);
1063
+ if (!questionId) return null;
1064
+ return {
1065
+ questionId,
1066
+ values: Array.isArray(value.values) ? value.values.filter((answer) => typeof answer === "string") : [],
1067
+ ...typeof value.other === "string" && value.other ? { other: value.other } : {}
1068
+ };
1069
+ }
1070
+ function humanInputAnswerSummary(answer, question) {
1071
+ const optionLabels = new Map(question?.options.map((option) => [option.id, option.label]) ?? []);
1072
+ const values = answer.values.map((value) => optionLabels.get(value) || value);
1073
+ if (answer.other) values.push(answer.other);
1074
+ const fallbackLabel = answer.questionId.replace(/[_-]+/g, " ").replace(/\b\w/g, (character) => character.toUpperCase());
1075
+ return {
1076
+ questionId: answer.questionId,
1077
+ label: question?.label || question?.prompt || fallbackLabel,
1078
+ prompt: question?.prompt || fallbackLabel,
1079
+ values
1080
+ };
1081
+ }
846
1082
  function providerNativeToolStatus(rawValue) {
847
1083
  const raw = asRecord2(rawValue);
848
1084
  if (raw.type !== "hosted_tool_call") {
@@ -921,6 +1157,7 @@ function isActivityItem(item) {
921
1157
  case "tool-call":
922
1158
  case "worker":
923
1159
  case "sandbox":
1160
+ case "startup-phase":
924
1161
  case "memory":
925
1162
  case "fleet-decision":
926
1163
  return true;
@@ -958,16 +1195,48 @@ function prescanTurnAnchors(events) {
958
1195
  const queuedTurnByTrigger = /* @__PURE__ */ new Map();
959
1196
  const startSeqByTrigger = /* @__PURE__ */ new Map();
960
1197
  const cancelledTurnIds = /* @__PURE__ */ new Set();
1198
+ const withdrawnTurnIds = /* @__PURE__ */ new Set();
961
1199
  const fallbackSeqByTurn = /* @__PURE__ */ new Map();
1200
+ const directChatSequenceByTrigger = /* @__PURE__ */ new Map();
1201
+ const explicitQueuedTriggers = /* @__PURE__ */ new Set();
1202
+ const queueSteerSequenceByTurn = /* @__PURE__ */ new Map();
962
1203
  const startedTurnIds = /* @__PURE__ */ new Set();
1204
+ const userMessageSequenceById = /* @__PURE__ */ new Map();
963
1205
  for (const event of ordered) {
964
1206
  const payload = asRecord2(event.payload);
965
1207
  const turnId = event.turnId ?? null;
1208
+ if (event.type === "user.message") {
1209
+ userMessageSequenceById.set(event.id, event.sequence);
1210
+ if (payload.routing === "queued_for_execution") {
1211
+ explicitQueuedTriggers.add(event.id);
1212
+ } else if (payload.routing === "accepted_for_execution" || payload.routing === "accepted_for_steering") {
1213
+ directChatSequenceByTrigger.set(event.id, event.sequence);
1214
+ }
1215
+ }
1216
+ if (event.type === "user.message" && payload.delivery === "steer") {
1217
+ directChatSequenceByTrigger.set(event.id, event.sequence);
1218
+ }
1219
+ if (event.type === "session.control.steer_requested") {
1220
+ const targetTurnId = typeof payload.targetTurnId === "string" ? payload.targetTurnId : null;
1221
+ if (targetTurnId && !queueSteerSequenceByTurn.has(targetTurnId)) {
1222
+ queueSteerSequenceByTurn.set(targetTurnId, event.sequence);
1223
+ }
1224
+ }
1225
+ if (event.type === "session.queue.changed" && (payload.operation === "edit" || payload.operation === "delete")) {
1226
+ const withdrawnTurnId = typeof payload.turnId === "string" ? payload.turnId : turnId ?? null;
1227
+ if (withdrawnTurnId) withdrawnTurnIds.add(withdrawnTurnId);
1228
+ }
966
1229
  if (event.type === "turn.queued") {
967
1230
  const triggerEventId = typeof payload.triggerEventId === "string" ? payload.triggerEventId : null;
968
1231
  const queuedTurnId = typeof payload.turnId === "string" ? payload.turnId : turnId;
969
1232
  if (triggerEventId && queuedTurnId) {
970
1233
  queuedTurnByTrigger.set(triggerEventId, queuedTurnId);
1234
+ if ((payload.routing === "accepted_for_execution" || payload.routing === "accepted_for_steering") && !directChatSequenceByTrigger.has(triggerEventId)) {
1235
+ directChatSequenceByTrigger.set(
1236
+ triggerEventId,
1237
+ userMessageSequenceById.get(triggerEventId) ?? event.sequence
1238
+ );
1239
+ }
971
1240
  }
972
1241
  continue;
973
1242
  }
@@ -993,6 +1262,10 @@ function prescanTurnAnchors(events) {
993
1262
  }
994
1263
  }
995
1264
  for (const [triggerEventId, turnId] of queuedTurnByTrigger) {
1265
+ const queueSteerSequence = queueSteerSequenceByTurn.get(turnId);
1266
+ if (queueSteerSequence !== void 0) {
1267
+ directChatSequenceByTrigger.set(triggerEventId, queueSteerSequence);
1268
+ }
996
1269
  if (!startSeqByTrigger.has(triggerEventId)) {
997
1270
  const fallbackSeq = fallbackSeqByTurn.get(turnId);
998
1271
  if (fallbackSeq !== void 0) {
@@ -1002,7 +1275,7 @@ function prescanTurnAnchors(events) {
1002
1275
  }
1003
1276
  const cancelledBeforeStartTriggers = /* @__PURE__ */ new Set();
1004
1277
  for (const [triggerEventId, turnId] of queuedTurnByTrigger) {
1005
- if (cancelledTurnIds.has(turnId) && !startSeqByTrigger.has(triggerEventId) && !fallbackSeqByTurn.has(turnId)) {
1278
+ if ((cancelledTurnIds.has(turnId) || withdrawnTurnIds.has(turnId)) && !startSeqByTrigger.has(triggerEventId) && !fallbackSeqByTurn.has(turnId)) {
1006
1279
  cancelledBeforeStartTriggers.add(triggerEventId);
1007
1280
  }
1008
1281
  }
@@ -1010,6 +1283,8 @@ function prescanTurnAnchors(events) {
1010
1283
  queuedTurnByTrigger,
1011
1284
  startSeqByTrigger,
1012
1285
  cancelledBeforeStartTriggers,
1286
+ directChatSequenceByTrigger,
1287
+ explicitQueuedTriggers,
1013
1288
  startedTurnIds
1014
1289
  };
1015
1290
  }
@@ -1020,8 +1295,20 @@ function orderTimelineEvents(events, prescan) {
1020
1295
  if (event.type !== "user.message") {
1021
1296
  continue;
1022
1297
  }
1298
+ const directChatSequence = prescan.directChatSequenceByTrigger.get(event.id);
1299
+ if (directChatSequence !== void 0) {
1300
+ pushInsertion(insertions, directChatSequence, event);
1301
+ continue;
1302
+ }
1023
1303
  const queuedTurnId = prescan.queuedTurnByTrigger.get(event.id);
1024
1304
  if (!queuedTurnId) {
1305
+ if (prescan.explicitQueuedTriggers.has(event.id)) {
1306
+ const startSeq2 = prescan.startSeqByTrigger.get(event.id);
1307
+ if (startSeq2 !== void 0) {
1308
+ pushInsertion(insertions, startSeq2, event);
1309
+ }
1310
+ continue;
1311
+ }
1025
1312
  pushInsertion(insertions, event.sequence, event);
1026
1313
  continue;
1027
1314
  }
@@ -1058,7 +1345,7 @@ function isAgentActivityEvent(type) {
1058
1345
  return type.startsWith("agent.") || type.startsWith("sandbox.");
1059
1346
  }
1060
1347
  function isTurnExecutionEvidence(type) {
1061
- return isAgentActivityEvent(type) || type === "turn.completed" || type === "turn.failed" || type === "turn.recovery.requested" || type === "turn.capacity_waiting" || type === "session.requiresAction" || type === "tool.auth_needed" || type === "credential.auth_needed" || type.startsWith("rig.setup.") || type === "codex.capacity.waiting" || type === "codex.capacity.resumed" || type === "codex.fleet.decision";
1348
+ return isAgentActivityEvent(type) || type === "turn.completed" || type === "turn.failed" || type === "turn.recovery.requested" || type === "turn.capacity_waiting" || type === "session.requiresAction" || type === "tool.auth_needed" || type === "credential.auth_needed" || type.startsWith("turn.startup.phase.") || type.startsWith("rig.setup.") || type === "codex.capacity.waiting" || type === "codex.capacity.resumed" || type === "codex.fleet.decision";
1062
1349
  }
1063
1350
  function turnEndItem(event, outcome, failureText) {
1064
1351
  return {
@@ -1140,7 +1427,9 @@ function foldSettledTurn(groups, turnEnd) {
1140
1427
  return;
1141
1428
  }
1142
1429
  const finalMessage = extractFinalAgentMessage(collected, turnEnd);
1143
- const body = finalMessage ? collected.slice(0, -1) : collected;
1430
+ const fallbackMessage = finalMessage || hasOrdinaryFinalAgentMessage(collected, turnEnd) ? null : extractLatestCompletedCommentary(collected, turnEnd);
1431
+ const visibleMessage = finalMessage ?? fallbackMessage;
1432
+ const body = visibleMessage ? collected.filter((group) => group !== visibleMessage) : collected;
1144
1433
  if (body.length === 0) {
1145
1434
  return;
1146
1435
  }
@@ -1162,11 +1451,11 @@ function foldSettledTurn(groups, turnEnd) {
1162
1451
  groups.splice(
1163
1452
  startIndex,
1164
1453
  collected.length,
1165
- ...finalMessage ? [turnGroup, finalMessage] : [turnGroup]
1454
+ ...visibleMessage ? [turnGroup, visibleMessage] : [turnGroup]
1166
1455
  );
1167
1456
  }
1168
1457
  function isTurnBoundary(group) {
1169
- return group?.kind === "turn" || group?.kind === "item" && (group.item.kind === "user-message" || group.item.kind === "context-compaction" || group.item.kind === "machine-input-batch" && group.item.members.some((member) => member.kind === "media_generation_result") || group.item.kind === "notice" && group.item.tone === "input");
1458
+ return group?.kind === "turn" || group?.kind === "item" && (group.item.kind === "user-message" || group.item.kind === "human-input" || group.item.kind === "context-compaction" || group.item.kind === "machine-input-batch" && group.item.members.some((member) => member.kind === "media_generation_result") || group.item.kind === "notice" && group.item.tone === "input");
1170
1459
  }
1171
1460
  function belongsToDifferentTurn(group, turnId) {
1172
1461
  if (!group || !turnId) {
@@ -1190,6 +1479,27 @@ function extractFinalAgentMessage(groups, turnEnd) {
1190
1479
  }
1191
1480
  return tail;
1192
1481
  }
1482
+ function hasOrdinaryFinalAgentMessage(groups, turnEnd) {
1483
+ return groups.some((group) => {
1484
+ if (group.kind !== "item" || group.item.kind !== "agent-message") return false;
1485
+ const message = group.item;
1486
+ return !message.streaming && message.phase !== "commentary" && message.text.trim().length > 0 && belongsToTurn(message, turnEnd.turnId);
1487
+ });
1488
+ }
1489
+ function extractLatestCompletedCommentary(groups, turnEnd) {
1490
+ for (let index = groups.length - 1; index >= 0; index -= 1) {
1491
+ const group = groups[index];
1492
+ if (group?.kind !== "item" || group.item.kind !== "agent-message") continue;
1493
+ const message = group.item;
1494
+ if (!message.streaming && message.phase === "commentary" && message.text.trim().length > 0 && belongsToTurn(message, turnEnd.turnId)) {
1495
+ return group;
1496
+ }
1497
+ }
1498
+ return null;
1499
+ }
1500
+ function belongsToTurn(message, turnId) {
1501
+ return !message.turnId || !turnId || message.turnId === turnId;
1502
+ }
1193
1503
  function groupStartedAt(group) {
1194
1504
  if (!group) {
1195
1505
  return void 0;
@@ -1209,6 +1519,9 @@ function asRecord2(value) {
1209
1519
  function stringValue(value) {
1210
1520
  return typeof value === "string" ? value : "";
1211
1521
  }
1522
+ function assistantMessagePhase(value) {
1523
+ return value === "commentary" || value === "final_answer" ? value : void 0;
1524
+ }
1212
1525
  function numberOrNull(value) {
1213
1526
  return typeof value === "number" && Number.isFinite(value) ? value : null;
1214
1527
  }
@@ -1255,7 +1568,12 @@ function machineInputMembers(value) {
1255
1568
  "agent_message",
1256
1569
  "agent_steer_instruction",
1257
1570
  "child_terminal_result",
1258
- "media_generation_result"
1571
+ "media_generation_result",
1572
+ "child_requires_action",
1573
+ "child_requires_action_resolved",
1574
+ "child_paused",
1575
+ "child_waiting_capacity",
1576
+ "child_progress"
1259
1577
  ]);
1260
1578
  const classifications = /* @__PURE__ */ new Set([
1261
1579
  "success",
@@ -1391,6 +1709,32 @@ function findOpenSandbox(items, name) {
1391
1709
  (item) => item.kind === "sandbox" && item.name === name && item.status === "running"
1392
1710
  );
1393
1711
  }
1712
+ function startupPhaseForSandboxOperation(name) {
1713
+ return SANDBOX_STARTUP_PHASES[name] ?? null;
1714
+ }
1715
+ function startupPhaseFromPayload(value) {
1716
+ return typeof value === "string" && STARTUP_PHASES.has(value) ? value : null;
1717
+ }
1718
+ var SANDBOX_STARTUP_PHASES = {
1719
+ "sandbox.provision": "sandbox",
1720
+ "repository-clone": "repository",
1721
+ "file-resource-download": "files"
1722
+ };
1723
+ var STARTUP_PHASES = /* @__PURE__ */ new Set([
1724
+ "queue",
1725
+ "sandbox",
1726
+ "rig",
1727
+ "repository",
1728
+ "files",
1729
+ "tools",
1730
+ "model_preparation",
1731
+ "provider_first_byte"
1732
+ ]);
1733
+ function elapsedDurationMs(startedAt, completedAt) {
1734
+ const start = Date.parse(startedAt);
1735
+ const end = Date.parse(completedAt);
1736
+ return Number.isFinite(start) && Number.isFinite(end) ? Math.max(0, end - start) : null;
1737
+ }
1394
1738
  function failureMessage(payload) {
1395
1739
  for (const key of ["error", "message"]) {
1396
1740
  const value = payload[key];
@@ -1417,7 +1761,7 @@ function shouldSuppressAgentGoalLandmark(type, payload) {
1417
1761
  if (type === "goal.completed") {
1418
1762
  return true;
1419
1763
  }
1420
- if (type === "goal.set" || type === "goal.updated" || type === "goal.paused") {
1764
+ if (type === "goal.set" || type === "goal.updated" || type === "goal.paused" || type === "goal.held") {
1421
1765
  return payload.actor === "agent";
1422
1766
  }
1423
1767
  return false;
@@ -1604,4 +1948,4 @@ export {
1604
1948
  groupTimeline,
1605
1949
  extractSessionRef
1606
1950
  };
1607
- //# sourceMappingURL=chunk-6KLX2RH5.js.map
1951
+ //# sourceMappingURL=chunk-RSXJN73N.js.map