@opengeni/react 1.0.1 → 2.2.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-Y7OEDUJ5.js → chunk-5RZN3DD5.js} +1014 -420
  8. package/dist/chunk-5RZN3DD5.js.map +1 -0
  9. package/dist/chunk-5YK2ZDIG.js +116 -0
  10. package/dist/chunk-5YK2ZDIG.js.map +1 -0
  11. package/dist/chunk-H5YGYNXS.js +329 -0
  12. package/dist/chunk-H5YGYNXS.js.map +1 -0
  13. package/dist/{chunk-7WCLAEFV.js → chunk-ICA6R6TW.js} +2 -2
  14. package/dist/{chunk-7WCLAEFV.js.map → chunk-ICA6R6TW.js.map} +1 -1
  15. package/dist/{chunk-IGC6A2ZI.js → chunk-JOAVA2TW.js} +589 -217
  16. package/dist/chunk-JOAVA2TW.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-B6WPZSTT.js → chunk-UOLJWT5Y.js} +78 -16
  24. package/dist/chunk-UOLJWT5Y.js.map +1 -0
  25. package/dist/{chunk-MKPIAGVL.js → chunk-W6NFJXSA.js} +8 -19
  26. package/dist/chunk-W6NFJXSA.js.map +1 -0
  27. package/dist/{chunk-XBZWOM2K.js → chunk-X4A66EWZ.js} +8 -3
  28. package/dist/chunk-X4A66EWZ.js.map +1 -0
  29. package/dist/chunk-X4JAFD5R.js +3907 -0
  30. package/dist/chunk-X4JAFD5R.js.map +1 -0
  31. package/dist/{chunk-6KLX2RH5.js → chunk-XSA2QAKP.js} +334 -19
  32. package/dist/chunk-XSA2QAKP.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 +48 -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 +91 -55
  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 +162 -17
  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 +476 -23
  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 +75 -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;
@@ -492,6 +584,9 @@ function buildTimeline(events) {
492
584
  const callId = typeof payload.id === "string" ? payload.id : null;
493
585
  const args = payload.arguments ?? null;
494
586
  closeStreamingTail();
587
+ if (callId && humanInputToolCallIds.has(callId)) {
588
+ break;
589
+ }
495
590
  if (toolMatchesLeaf(name, WORKER_SPAWN_TOOL) || toolMatchesLeaf(name, WORKER_MESSAGE_TOOL)) {
496
591
  items.push({
497
592
  kind: "worker",
@@ -574,20 +669,49 @@ function buildTimeline(events) {
574
669
  }
575
670
  break;
576
671
  }
672
+ case "turn.queued": {
673
+ const queuedTurnId = turnId ?? (typeof payload.turnId === "string" ? payload.turnId : null);
674
+ if (queuedTurnId) {
675
+ queuedAtByTurn.set(queuedTurnId, event.occurredAt);
676
+ }
677
+ break;
678
+ }
679
+ case "turn.started": {
680
+ if (!turnId) break;
681
+ const queuedAt = queuedAtByTurn.get(turnId);
682
+ if (!queuedAt) break;
683
+ queuedAtByTurn.delete(turnId);
684
+ closeStreamingTail();
685
+ settleStartupPhase(
686
+ "queue",
687
+ "complete",
688
+ elapsedDurationMs(queuedAt, event.occurredAt),
689
+ null,
690
+ 0,
691
+ queuedAt,
692
+ `${event.id}-queue`
693
+ );
694
+ break;
695
+ }
577
696
  case "sandbox.operation.started":
578
697
  case "sandbox.operation.completed":
579
698
  case "sandbox.operation.failed": {
580
699
  const name = typeof payload.name === "string" ? payload.name : "sandbox";
581
- const status = event.type.endsWith(".failed") ? "failed" : event.type.endsWith(".completed") ? "complete" : "running";
700
+ const status = event.type.endsWith(".failed") ? payload.expectedTransition === true ? "cancelled" : "failed" : event.type.endsWith(".completed") ? "complete" : "running";
701
+ const origin = payload.origin === "created" || payload.origin === "restored" || payload.origin === "resumed" ? payload.origin : null;
702
+ const startupPhase = startupPhaseForSandboxOperation(name);
703
+ if (startupPhase) {
704
+ closeStreamingTail();
705
+ settleStartupPhase(startupPhase, status, numberOrNull(payload.durationMs), origin);
706
+ break;
707
+ }
582
708
  if ((name === "repository-clone" || name === "file-resource-download") && status !== "failed") {
583
709
  break;
584
710
  }
585
711
  const existing = findOpenSandbox(items, name);
586
712
  if (existing && status !== "running") {
587
713
  existing.status = status;
588
- if (payload.origin === "created" || payload.origin === "restored" || payload.origin === "resumed") {
589
- existing.origin = payload.origin;
590
- }
714
+ if (origin) existing.origin = origin;
591
715
  const message = failureMessage(payload);
592
716
  if (message) {
593
717
  existing.output = existing.output ? `${existing.output}
@@ -604,13 +728,28 @@ ${message}` : message;
604
728
  name,
605
729
  command: typeof payload.command === "string" ? payload.command : null,
606
730
  output: failureMessage(payload) ?? "",
607
- origin: payload.origin === "created" || payload.origin === "restored" || payload.origin === "resumed" ? payload.origin : null,
731
+ origin,
608
732
  status,
609
733
  occurredAt: event.occurredAt
610
734
  });
611
735
  }
612
736
  break;
613
737
  }
738
+ case "agent.model.request": {
739
+ const requestPhase = typeof payload.phase === "string" ? payload.phase : null;
740
+ const status = requestPhase === "started" ? "running" : requestPhase === "first_byte" || requestPhase === "first_event" ? "complete" : requestPhase === "failed" || requestPhase === "timed_out" ? "failed" : null;
741
+ if (status) {
742
+ if (status === "running") closeStreamingTail();
743
+ settleStartupPhase(
744
+ "provider_first_byte",
745
+ status,
746
+ status === "running" ? null : numberOrNull(payload.durationMs),
747
+ null,
748
+ status === "running" ? 2 : 1
749
+ );
750
+ }
751
+ break;
752
+ }
614
753
  case "sandbox.command.output.delta": {
615
754
  const text = typeof payload.chunk === "string" ? payload.chunk : typeof payload.text === "string" ? payload.text : typeof payload.output === "string" ? payload.output : "";
616
755
  if (!text) {
@@ -645,7 +784,7 @@ ${message}` : message;
645
784
  break;
646
785
  }
647
786
  case "session.requiresAction": {
648
- finalizeOpen(turnId);
787
+ finalizeOpen(turnId, "complete", event.occurredAt);
649
788
  items.push({
650
789
  kind: "notice",
651
790
  id: event.id,
@@ -702,6 +841,12 @@ ${message}` : message;
702
841
  break;
703
842
  }
704
843
  case "turn.recovery.requested": {
844
+ if (turnId) {
845
+ startupRecoveryRevisionByTurn.set(
846
+ turnId,
847
+ (startupRecoveryRevisionByTurn.get(turnId) ?? 0) + 1
848
+ );
849
+ }
705
850
  break;
706
851
  }
707
852
  case "turn.event.rejected_late": {
@@ -734,11 +879,11 @@ ${message}` : message;
734
879
  }
735
880
  case "turn.completed": {
736
881
  if (payload.maintenance === "context_compaction") {
737
- finalizeOpen(turnId);
882
+ finalizeOpen(turnId, "complete", event.occurredAt);
738
883
  break;
739
884
  }
740
885
  if (isCreditExhaustionPayload(payload)) {
741
- finalizeOpen(turnId);
886
+ finalizeOpen(turnId, "complete", event.occurredAt);
742
887
  items.push(turnEndItem(event, "failed", CREDIT_EXHAUSTION_MESSAGE));
743
888
  items.push({
744
889
  kind: "notice",
@@ -749,14 +894,14 @@ ${message}` : message;
749
894
  });
750
895
  break;
751
896
  }
752
- finalizeOpen(turnId);
897
+ finalizeOpen(turnId, "complete", event.occurredAt);
753
898
  items.push(turnEndItem(event, "complete", null));
754
899
  break;
755
900
  }
756
901
  case "turn.failed": {
757
902
  const hadActivity = hasTurnActivity(items, turnId);
758
903
  const failureText = isCreditExhaustionPayload(payload) ? CREDIT_EXHAUSTION_MESSAGE : failureMessage(payload);
759
- finalizeOpen(turnId, "cancelled");
904
+ finalizeOpen(turnId, "cancelled", event.occurredAt);
760
905
  items.push(turnEndItem(event, "failed", failureText));
761
906
  if (!hadActivity) {
762
907
  items.push({
@@ -774,7 +919,7 @@ ${message}` : message;
774
919
  break;
775
920
  }
776
921
  const hadActivity = hasTurnActivity(items, turnId);
777
- finalizeOpen(turnId, "cancelled");
922
+ finalizeOpen(turnId, "cancelled", event.occurredAt);
778
923
  items.push(turnEndItem(event, "cancelled", null));
779
924
  if (!hadActivity) {
780
925
  items.push({
@@ -810,6 +955,7 @@ ${message}` : message;
810
955
  case "goal.paused":
811
956
  case "goal.resumed":
812
957
  case "goal.cleared":
958
+ case "goal.held":
813
959
  case "goal.continuation": {
814
960
  if (shouldSuppressAgentGoalLandmark(event.type, payload)) {
815
961
  break;
@@ -818,7 +964,7 @@ ${message}` : message;
818
964
  kind: "goal",
819
965
  id: event.id,
820
966
  action: event.type.slice("goal.".length),
821
- text: goalText(payload),
967
+ text: event.type === "goal.held" && typeof payload.reason === "string" && payload.reason ? payload.reason : goalText(payload),
822
968
  occurredAt: event.occurredAt
823
969
  });
824
970
  break;
@@ -843,6 +989,93 @@ function realtimeVoiceMessage(payload) {
843
989
  }
844
990
  return null;
845
991
  }
992
+ function humanInputRequestsById(events) {
993
+ const requests = /* @__PURE__ */ new Map();
994
+ for (const event of events) {
995
+ if (event.type !== "session.humanInput.requested") continue;
996
+ const request = asRecord2(asRecord2(event.payload).request);
997
+ const requestId = stringValue(request.id);
998
+ if (requestId) requests.set(requestId, request);
999
+ }
1000
+ return requests;
1001
+ }
1002
+ function humanInputItemFromResponse(event, payload, requests) {
1003
+ const response = asRecord2(payload.response);
1004
+ const outcome = response.outcome;
1005
+ if (outcome !== "answered" && outcome !== "skipped" && outcome !== "expired" && outcome !== "cancelled") {
1006
+ return null;
1007
+ }
1008
+ const requestId = stringValue(payload.requestId);
1009
+ const request = requests.get(requestId);
1010
+ const questions = humanInputQuestions(request?.questions);
1011
+ const normalizedResponse = outcome === "answered" ? {
1012
+ outcome,
1013
+ answers: Array.isArray(response.answers) ? response.answers.map(asRecord2).map(humanInputAnswer).filter((answer) => answer !== null) : []
1014
+ } : { outcome };
1015
+ const questionsById = new Map(questions.map((question) => [question.id, question]));
1016
+ const answers = normalizedResponse.outcome === "answered" ? normalizedResponse.answers.map(
1017
+ (answer) => humanInputAnswerSummary(answer, questionsById.get(answer.questionId))
1018
+ ) : [];
1019
+ return {
1020
+ kind: "human-input",
1021
+ id: event.id,
1022
+ turnId: event.turnId ?? null,
1023
+ requestId,
1024
+ questions,
1025
+ response: normalizedResponse,
1026
+ answers,
1027
+ occurredAt: event.occurredAt
1028
+ };
1029
+ }
1030
+ function humanInputQuestions(value) {
1031
+ if (!Array.isArray(value)) return [];
1032
+ return value.map(asRecord2).flatMap((question) => {
1033
+ const id = stringValue(question.id);
1034
+ const prompt = stringValue(question.prompt);
1035
+ const kind = question.kind;
1036
+ if (!id || !prompt || kind !== "text" && kind !== "single_select" && kind !== "multi_select") {
1037
+ return [];
1038
+ }
1039
+ const options = Array.isArray(question.options) ? question.options.map(asRecord2).flatMap((option) => {
1040
+ const optionId = stringValue(option.id);
1041
+ const label = stringValue(option.label);
1042
+ return optionId && label ? [{ id: optionId, label, description: stringValue(option.description) || null }] : [];
1043
+ }) : [];
1044
+ return [
1045
+ {
1046
+ id,
1047
+ kind,
1048
+ prompt,
1049
+ label: stringValue(question.label) || null,
1050
+ helpText: stringValue(question.helpText) || null,
1051
+ options,
1052
+ required: question.required === true,
1053
+ allowOther: question.allowOther === true
1054
+ }
1055
+ ];
1056
+ });
1057
+ }
1058
+ function humanInputAnswer(value) {
1059
+ const questionId = stringValue(value.questionId);
1060
+ if (!questionId) return null;
1061
+ return {
1062
+ questionId,
1063
+ values: Array.isArray(value.values) ? value.values.filter((answer) => typeof answer === "string") : [],
1064
+ ...typeof value.other === "string" && value.other ? { other: value.other } : {}
1065
+ };
1066
+ }
1067
+ function humanInputAnswerSummary(answer, question) {
1068
+ const optionLabels = new Map(question?.options.map((option) => [option.id, option.label]) ?? []);
1069
+ const values = answer.values.map((value) => optionLabels.get(value) || value);
1070
+ if (answer.other) values.push(answer.other);
1071
+ const fallbackLabel = answer.questionId.replace(/[_-]+/g, " ").replace(/\b\w/g, (character) => character.toUpperCase());
1072
+ return {
1073
+ questionId: answer.questionId,
1074
+ label: question?.label || question?.prompt || fallbackLabel,
1075
+ prompt: question?.prompt || fallbackLabel,
1076
+ values
1077
+ };
1078
+ }
846
1079
  function providerNativeToolStatus(rawValue) {
847
1080
  const raw = asRecord2(rawValue);
848
1081
  if (raw.type !== "hosted_tool_call") {
@@ -921,6 +1154,7 @@ function isActivityItem(item) {
921
1154
  case "tool-call":
922
1155
  case "worker":
923
1156
  case "sandbox":
1157
+ case "startup-phase":
924
1158
  case "memory":
925
1159
  case "fleet-decision":
926
1160
  return true;
@@ -958,16 +1192,48 @@ function prescanTurnAnchors(events) {
958
1192
  const queuedTurnByTrigger = /* @__PURE__ */ new Map();
959
1193
  const startSeqByTrigger = /* @__PURE__ */ new Map();
960
1194
  const cancelledTurnIds = /* @__PURE__ */ new Set();
1195
+ const withdrawnTurnIds = /* @__PURE__ */ new Set();
961
1196
  const fallbackSeqByTurn = /* @__PURE__ */ new Map();
1197
+ const directChatSequenceByTrigger = /* @__PURE__ */ new Map();
1198
+ const explicitQueuedTriggers = /* @__PURE__ */ new Set();
1199
+ const queueSteerSequenceByTurn = /* @__PURE__ */ new Map();
962
1200
  const startedTurnIds = /* @__PURE__ */ new Set();
1201
+ const userMessageSequenceById = /* @__PURE__ */ new Map();
963
1202
  for (const event of ordered) {
964
1203
  const payload = asRecord2(event.payload);
965
1204
  const turnId = event.turnId ?? null;
1205
+ if (event.type === "user.message") {
1206
+ userMessageSequenceById.set(event.id, event.sequence);
1207
+ if (payload.routing === "queued_for_execution") {
1208
+ explicitQueuedTriggers.add(event.id);
1209
+ } else if (payload.routing === "accepted_for_execution" || payload.routing === "accepted_for_steering") {
1210
+ directChatSequenceByTrigger.set(event.id, event.sequence);
1211
+ }
1212
+ }
1213
+ if (event.type === "user.message" && payload.delivery === "steer") {
1214
+ directChatSequenceByTrigger.set(event.id, event.sequence);
1215
+ }
1216
+ if (event.type === "session.control.steer_requested") {
1217
+ const targetTurnId = typeof payload.targetTurnId === "string" ? payload.targetTurnId : null;
1218
+ if (targetTurnId && !queueSteerSequenceByTurn.has(targetTurnId)) {
1219
+ queueSteerSequenceByTurn.set(targetTurnId, event.sequence);
1220
+ }
1221
+ }
1222
+ if (event.type === "session.queue.changed" && (payload.operation === "edit" || payload.operation === "delete")) {
1223
+ const withdrawnTurnId = typeof payload.turnId === "string" ? payload.turnId : turnId ?? null;
1224
+ if (withdrawnTurnId) withdrawnTurnIds.add(withdrawnTurnId);
1225
+ }
966
1226
  if (event.type === "turn.queued") {
967
1227
  const triggerEventId = typeof payload.triggerEventId === "string" ? payload.triggerEventId : null;
968
1228
  const queuedTurnId = typeof payload.turnId === "string" ? payload.turnId : turnId;
969
1229
  if (triggerEventId && queuedTurnId) {
970
1230
  queuedTurnByTrigger.set(triggerEventId, queuedTurnId);
1231
+ if ((payload.routing === "accepted_for_execution" || payload.routing === "accepted_for_steering") && !directChatSequenceByTrigger.has(triggerEventId)) {
1232
+ directChatSequenceByTrigger.set(
1233
+ triggerEventId,
1234
+ userMessageSequenceById.get(triggerEventId) ?? event.sequence
1235
+ );
1236
+ }
971
1237
  }
972
1238
  continue;
973
1239
  }
@@ -993,6 +1259,10 @@ function prescanTurnAnchors(events) {
993
1259
  }
994
1260
  }
995
1261
  for (const [triggerEventId, turnId] of queuedTurnByTrigger) {
1262
+ const queueSteerSequence = queueSteerSequenceByTurn.get(turnId);
1263
+ if (queueSteerSequence !== void 0) {
1264
+ directChatSequenceByTrigger.set(triggerEventId, queueSteerSequence);
1265
+ }
996
1266
  if (!startSeqByTrigger.has(triggerEventId)) {
997
1267
  const fallbackSeq = fallbackSeqByTurn.get(turnId);
998
1268
  if (fallbackSeq !== void 0) {
@@ -1002,7 +1272,7 @@ function prescanTurnAnchors(events) {
1002
1272
  }
1003
1273
  const cancelledBeforeStartTriggers = /* @__PURE__ */ new Set();
1004
1274
  for (const [triggerEventId, turnId] of queuedTurnByTrigger) {
1005
- if (cancelledTurnIds.has(turnId) && !startSeqByTrigger.has(triggerEventId) && !fallbackSeqByTurn.has(turnId)) {
1275
+ if ((cancelledTurnIds.has(turnId) || withdrawnTurnIds.has(turnId)) && !startSeqByTrigger.has(triggerEventId) && !fallbackSeqByTurn.has(turnId)) {
1006
1276
  cancelledBeforeStartTriggers.add(triggerEventId);
1007
1277
  }
1008
1278
  }
@@ -1010,6 +1280,8 @@ function prescanTurnAnchors(events) {
1010
1280
  queuedTurnByTrigger,
1011
1281
  startSeqByTrigger,
1012
1282
  cancelledBeforeStartTriggers,
1283
+ directChatSequenceByTrigger,
1284
+ explicitQueuedTriggers,
1013
1285
  startedTurnIds
1014
1286
  };
1015
1287
  }
@@ -1020,8 +1292,20 @@ function orderTimelineEvents(events, prescan) {
1020
1292
  if (event.type !== "user.message") {
1021
1293
  continue;
1022
1294
  }
1295
+ const directChatSequence = prescan.directChatSequenceByTrigger.get(event.id);
1296
+ if (directChatSequence !== void 0) {
1297
+ pushInsertion(insertions, directChatSequence, event);
1298
+ continue;
1299
+ }
1023
1300
  const queuedTurnId = prescan.queuedTurnByTrigger.get(event.id);
1024
1301
  if (!queuedTurnId) {
1302
+ if (prescan.explicitQueuedTriggers.has(event.id)) {
1303
+ const startSeq2 = prescan.startSeqByTrigger.get(event.id);
1304
+ if (startSeq2 !== void 0) {
1305
+ pushInsertion(insertions, startSeq2, event);
1306
+ }
1307
+ continue;
1308
+ }
1025
1309
  pushInsertion(insertions, event.sequence, event);
1026
1310
  continue;
1027
1311
  }
@@ -1058,7 +1342,7 @@ function isAgentActivityEvent(type) {
1058
1342
  return type.startsWith("agent.") || type.startsWith("sandbox.");
1059
1343
  }
1060
1344
  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";
1345
+ 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
1346
  }
1063
1347
  function turnEndItem(event, outcome, failureText) {
1064
1348
  return {
@@ -1166,7 +1450,7 @@ function foldSettledTurn(groups, turnEnd) {
1166
1450
  );
1167
1451
  }
1168
1452
  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");
1453
+ 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
1454
  }
1171
1455
  function belongsToDifferentTurn(group, turnId) {
1172
1456
  if (!group || !turnId) {
@@ -1255,7 +1539,12 @@ function machineInputMembers(value) {
1255
1539
  "agent_message",
1256
1540
  "agent_steer_instruction",
1257
1541
  "child_terminal_result",
1258
- "media_generation_result"
1542
+ "media_generation_result",
1543
+ "child_requires_action",
1544
+ "child_requires_action_resolved",
1545
+ "child_paused",
1546
+ "child_waiting_capacity",
1547
+ "child_progress"
1259
1548
  ]);
1260
1549
  const classifications = /* @__PURE__ */ new Set([
1261
1550
  "success",
@@ -1391,6 +1680,32 @@ function findOpenSandbox(items, name) {
1391
1680
  (item) => item.kind === "sandbox" && item.name === name && item.status === "running"
1392
1681
  );
1393
1682
  }
1683
+ function startupPhaseForSandboxOperation(name) {
1684
+ return SANDBOX_STARTUP_PHASES[name] ?? null;
1685
+ }
1686
+ function startupPhaseFromPayload(value) {
1687
+ return typeof value === "string" && STARTUP_PHASES.has(value) ? value : null;
1688
+ }
1689
+ var SANDBOX_STARTUP_PHASES = {
1690
+ "sandbox.provision": "sandbox",
1691
+ "repository-clone": "repository",
1692
+ "file-resource-download": "files"
1693
+ };
1694
+ var STARTUP_PHASES = /* @__PURE__ */ new Set([
1695
+ "queue",
1696
+ "sandbox",
1697
+ "rig",
1698
+ "repository",
1699
+ "files",
1700
+ "tools",
1701
+ "model_preparation",
1702
+ "provider_first_byte"
1703
+ ]);
1704
+ function elapsedDurationMs(startedAt, completedAt) {
1705
+ const start = Date.parse(startedAt);
1706
+ const end = Date.parse(completedAt);
1707
+ return Number.isFinite(start) && Number.isFinite(end) ? Math.max(0, end - start) : null;
1708
+ }
1394
1709
  function failureMessage(payload) {
1395
1710
  for (const key of ["error", "message"]) {
1396
1711
  const value = payload[key];
@@ -1417,7 +1732,7 @@ function shouldSuppressAgentGoalLandmark(type, payload) {
1417
1732
  if (type === "goal.completed") {
1418
1733
  return true;
1419
1734
  }
1420
- if (type === "goal.set" || type === "goal.updated" || type === "goal.paused") {
1735
+ if (type === "goal.set" || type === "goal.updated" || type === "goal.paused" || type === "goal.held") {
1421
1736
  return payload.actor === "agent";
1422
1737
  }
1423
1738
  return false;
@@ -1604,4 +1919,4 @@ export {
1604
1919
  groupTimeline,
1605
1920
  extractSessionRef
1606
1921
  };
1607
- //# sourceMappingURL=chunk-6KLX2RH5.js.map
1922
+ //# sourceMappingURL=chunk-XSA2QAKP.js.map