@opengeni/react 6.1.0 → 7.0.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 (206) hide show
  1. package/README.md +83 -2
  2. package/dist/artifacts-document.js +1 -1
  3. package/dist/artifacts-presentation.js +1 -1
  4. package/dist/artifacts-spreadsheet.js +1 -1
  5. package/dist/artifacts.js +3 -3
  6. package/dist/{browser-viewer-NTD6UIPR.js → browser-viewer-LGH4IP47.js} +3 -3
  7. package/dist/capability-catalog-row.d.ts +20 -0
  8. package/dist/capability-logo-fallback.d.ts +3 -0
  9. package/dist/{chunk-NOSYBS2D.js → chunk-2VHARTBL.js} +2 -1
  10. package/dist/{chunk-VRBL3F5E.js → chunk-5GAL23FF.js} +10 -2
  11. package/dist/{chunk-VRBL3F5E.js.map → chunk-5GAL23FF.js.map} +1 -1
  12. package/dist/chunk-5UONOQ3Y.js +635 -0
  13. package/dist/chunk-5UONOQ3Y.js.map +1 -0
  14. package/dist/{chunk-NYESIADM.js → chunk-AKOMC3VO.js} +3 -3
  15. package/dist/chunk-AKOMC3VO.js.map +1 -0
  16. package/dist/chunk-BRM6FVZA.js +302 -0
  17. package/dist/chunk-BRM6FVZA.js.map +1 -0
  18. package/dist/{chunk-TDSEILUH.js → chunk-D5NOQPLR.js} +1289 -1530
  19. package/dist/chunk-D5NOQPLR.js.map +1 -0
  20. package/dist/chunk-D7GAPJ3V.js +1558 -0
  21. package/dist/chunk-D7GAPJ3V.js.map +1 -0
  22. package/dist/{chunk-5M6VTFJ5.js → chunk-GBPCZH3Y.js} +2 -2
  23. package/dist/{chunk-YBM6CQRU.js → chunk-GEN54DU5.js} +4 -4
  24. package/dist/{chunk-UMECRJRV.js → chunk-HJ5VJ4JB.js} +21 -12
  25. package/dist/chunk-HJ5VJ4JB.js.map +1 -0
  26. package/dist/{chunk-R4KRSFGA.js → chunk-IP4BUBKH.js} +3 -3
  27. package/dist/{chunk-KANFU34B.js → chunk-IYUPN32E.js} +6 -2
  28. package/dist/chunk-IYUPN32E.js.map +1 -0
  29. package/dist/{chunk-L2NBTKRX.js → chunk-JKLGJQO5.js} +193 -12
  30. package/dist/chunk-JKLGJQO5.js.map +1 -0
  31. package/dist/{chunk-NLTS7JHI.js → chunk-JPHDWKZE.js} +5 -5
  32. package/dist/{chunk-ICA6R6TW.js → chunk-OWHPKAOV.js} +28 -20
  33. package/dist/chunk-OWHPKAOV.js.map +1 -0
  34. package/dist/{chunk-24M4YBCL.js → chunk-PNAVEK2U.js} +4 -4
  35. package/dist/{chunk-45XEUVTK.js → chunk-UXE5SSNN.js} +293 -463
  36. package/dist/chunk-UXE5SSNN.js.map +1 -0
  37. package/dist/{chunk-PEI6RANI.js → chunk-VR4Z73EU.js} +203 -9
  38. package/dist/chunk-VR4Z73EU.js.map +1 -0
  39. package/dist/{chunk-HUIKIDM5.js → chunk-XMXRI5JK.js} +65 -18
  40. package/dist/chunk-XMXRI5JK.js.map +1 -0
  41. package/dist/client.d.ts +1 -1
  42. package/dist/components/artifacts/spreadsheet-general-display.d.ts +24 -0
  43. package/dist/components/chat-composer.d.ts +13 -3
  44. package/dist/components/markdown.d.ts +4 -3
  45. package/dist/components/message-timeline.d.ts +7 -2
  46. package/dist/components/preview-loading.d.ts +2 -0
  47. package/dist/components/session-capability-frame.d.ts +24 -0
  48. package/dist/components/session-chrome.d.ts +1 -2
  49. package/dist/components/session-commands.d.ts +6 -0
  50. package/dist/components/session-connection-request.d.ts +8 -0
  51. package/dist/components/session-mcp-capability-card.d.ts +22 -0
  52. package/dist/components/timeline-search.d.ts +34 -0
  53. package/dist/composer.js +7 -7
  54. package/dist/connect-account-identity.d.ts +8 -0
  55. package/dist/connect-accounts.d.ts +5 -0
  56. package/dist/connect-chooser.d.ts +6 -0
  57. package/dist/connect-panel.d.ts +9 -2
  58. package/dist/connect-setup.d.ts +5 -1
  59. package/dist/connect.d.ts +5 -21
  60. package/dist/connect.js +1268 -584
  61. package/dist/connect.js.map +1 -1
  62. package/dist/connection-catalog.d.ts +6 -1
  63. package/dist/connection-discovery.d.ts +12 -0
  64. package/dist/connection-installed.d.ts +1 -0
  65. package/dist/connection-logo.d.ts +5 -2
  66. package/dist/connection-service-logo.d.ts +8 -0
  67. package/dist/connection-service-presentation.d.ts +13 -0
  68. package/dist/connection-skeleton.d.ts +5 -0
  69. package/dist/discovery-cache.d.ts +5 -0
  70. package/dist/hooks/use-codex-accounts.d.ts +11 -5
  71. package/dist/hooks/use-connect.d.ts +22 -0
  72. package/dist/hooks/use-session-events.d.ts +5 -0
  73. package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
  74. package/dist/hooks/use-workspace-sessions.d.ts +2 -0
  75. package/dist/index.d.ts +8 -2
  76. package/dist/index.js +771 -793
  77. package/dist/index.js.map +1 -1
  78. package/dist/interaction.js +2 -2
  79. package/dist/machines.js +2 -2
  80. package/dist/mcp-connection-status.d.ts +14 -0
  81. package/dist/{model-policy-picker-menu-3R336DP2.js → model-policy-picker-menu-RVOQ4ZZG.js} +4 -4
  82. package/dist/model-policy.d.ts +6 -2
  83. package/dist/model-policy.js +1 -1
  84. package/dist/{platform-activity-row-DUE2W74J.js → platform-activity-row-HLOH7FW4.js} +9 -4
  85. package/dist/platform-activity-row-HLOH7FW4.js.map +1 -0
  86. package/dist/plugin-discovery.d.ts +6 -0
  87. package/dist/{queue-surface-implementation-LK3S4BIW.js → queue-surface-implementation-3RIFK2BS.js} +4 -4
  88. package/dist/realtime.js +22 -22
  89. package/dist/realtime.js.map +1 -1
  90. package/dist/session-auth-recommendation.d.ts +5 -0
  91. package/dist/session-capability-policy.d.ts +12 -0
  92. package/dist/session-ui.d.ts +2 -0
  93. package/dist/session-ui.js +14 -12
  94. package/dist/session.d.ts +1 -0
  95. package/dist/session.js +6 -4
  96. package/dist/skill-discovery.d.ts +11 -0
  97. package/dist/timeline/compaction-copy.d.ts +10 -0
  98. package/dist/timeline/projection.d.ts +3 -1
  99. package/dist/timeline/turn-summary.d.ts +2 -2
  100. package/dist/timeline/types.d.ts +22 -1
  101. package/dist/{timeline-annotation-markers-DRSTLEM6.js → timeline-annotation-markers-OY6OWR3V.js} +2 -2
  102. package/dist/{timeline-annotation-selection-IHLUGVND.js → timeline-annotation-selection-BOXA2TIN.js} +2 -2
  103. package/dist/{timeline-annotations-dialog-6Q53N5FG.js → timeline-annotations-dialog-RGY3MHL3.js} +3 -3
  104. package/package.json +3 -3
  105. package/src/assets/README.md +8 -0
  106. package/src/assets/gmail.ico +0 -0
  107. package/src/assets/outlook.ico +0 -0
  108. package/src/capability-catalog-row.tsx +94 -0
  109. package/src/capability-logo-fallback.ts +22 -0
  110. package/src/client.ts +0 -9
  111. package/src/components/artifacts/document-editor.tsx +63 -6
  112. package/src/components/artifacts/presentation-editor.tsx +214 -9
  113. package/src/components/artifacts/spreadsheet-canvas.ts +3 -8
  114. package/src/components/artifacts/spreadsheet-general-display.ts +43 -0
  115. package/src/components/artifacts/spreadsheet-grid.tsx +10 -11
  116. package/src/components/chat-composer.tsx +26 -3
  117. package/src/components/composer.tsx +10 -4
  118. package/src/components/human-input-form.tsx +12 -2
  119. package/src/components/markdown.tsx +86 -4
  120. package/src/components/message-timeline.tsx +104 -36
  121. package/src/components/model-picker.tsx +11 -3
  122. package/src/components/model-policy-picker-menu.tsx +10 -3
  123. package/src/components/preview-loading.tsx +154 -0
  124. package/src/components/sandbox-workspace.tsx +20 -36
  125. package/src/components/session-capability-frame.tsx +163 -0
  126. package/src/components/session-chrome.tsx +46 -77
  127. package/src/components/session-commands.tsx +18 -0
  128. package/src/components/session-connection-request.tsx +97 -0
  129. package/src/components/session-conversation.tsx +5 -4
  130. package/src/components/session-mcp-capability-card.tsx +532 -0
  131. package/src/components/session-status.tsx +2 -2
  132. package/src/components/timeline-anchor.tsx +9 -8
  133. package/src/components/timeline-search.tsx +168 -0
  134. package/src/components/user-message-body.tsx +7 -0
  135. package/src/connect-account-identity.tsx +34 -0
  136. package/src/connect-accounts.tsx +114 -52
  137. package/src/connect-chooser.tsx +171 -39
  138. package/src/connect-panel.tsx +73 -9
  139. package/src/connect-setup.tsx +72 -25
  140. package/src/connect.ts +13 -22
  141. package/src/connection-assets.d.ts +4 -0
  142. package/src/connection-catalog.tsx +61 -39
  143. package/src/connection-discovery.tsx +235 -0
  144. package/src/connection-installed.tsx +2 -0
  145. package/src/connection-logo.tsx +18 -10
  146. package/src/connection-service-logo.tsx +55 -0
  147. package/src/connection-service-presentation.ts +46 -0
  148. package/src/connection-skeleton.tsx +16 -0
  149. package/src/conversation-timeline.ts +1 -0
  150. package/src/discovery-cache.ts +42 -0
  151. package/src/hooks/use-codex-accounts.ts +33 -14
  152. package/src/hooks/use-composer.ts +4 -5
  153. package/src/hooks/use-connect.ts +23 -0
  154. package/src/hooks/use-session-events.ts +114 -1
  155. package/src/hooks/use-session-mcp-approval-policy.ts +13 -5
  156. package/src/hooks/use-workspace-sessions.ts +10 -0
  157. package/src/index.ts +22 -2
  158. package/src/mcp-connection-status.ts +35 -0
  159. package/src/model-policy.ts +21 -0
  160. package/src/plugin-details.tsx +8 -5
  161. package/src/plugin-discovery.tsx +92 -72
  162. package/src/realtime/realtime-control.tsx +6 -8
  163. package/src/session-auth-recommendation.ts +48 -0
  164. package/src/session-capability-policy.ts +83 -0
  165. package/src/session-ui.ts +2 -0
  166. package/src/session.ts +1 -0
  167. package/src/skill-discovery.tsx +101 -56
  168. package/src/timeline/compaction-copy.ts +40 -0
  169. package/src/timeline/platform-activity-row.tsx +8 -3
  170. package/src/timeline/projection.ts +74 -2
  171. package/src/timeline/shared.tsx +6 -1
  172. package/src/timeline/startup-timings.tsx +1 -1
  173. package/src/timeline/turn-summary.tsx +17 -3
  174. package/src/timeline/types.ts +22 -2
  175. package/styles/compiled.css +325 -27
  176. package/styles/connect.css +90 -15
  177. package/styles/index.css +46 -0
  178. package/styles/session-capability.css +42 -0
  179. package/dist/chunk-45XEUVTK.js.map +0 -1
  180. package/dist/chunk-HQV2I5HV.js +0 -124
  181. package/dist/chunk-HQV2I5HV.js.map +0 -1
  182. package/dist/chunk-HUIKIDM5.js.map +0 -1
  183. package/dist/chunk-ICA6R6TW.js.map +0 -1
  184. package/dist/chunk-IHQII5WO.js +0 -886
  185. package/dist/chunk-IHQII5WO.js.map +0 -1
  186. package/dist/chunk-KANFU34B.js.map +0 -1
  187. package/dist/chunk-L2NBTKRX.js.map +0 -1
  188. package/dist/chunk-NYESIADM.js.map +0 -1
  189. package/dist/chunk-PEI6RANI.js.map +0 -1
  190. package/dist/chunk-TDSEILUH.js.map +0 -1
  191. package/dist/chunk-UMECRJRV.js.map +0 -1
  192. package/dist/hooks/use-packs.d.ts +0 -32
  193. package/dist/platform-activity-row-DUE2W74J.js.map +0 -1
  194. package/src/hooks/use-packs.ts +0 -157
  195. /package/dist/{browser-viewer-NTD6UIPR.js.map → browser-viewer-LGH4IP47.js.map} +0 -0
  196. /package/dist/{chunk-NOSYBS2D.js.map → chunk-2VHARTBL.js.map} +0 -0
  197. /package/dist/{chunk-5M6VTFJ5.js.map → chunk-GBPCZH3Y.js.map} +0 -0
  198. /package/dist/{chunk-YBM6CQRU.js.map → chunk-GEN54DU5.js.map} +0 -0
  199. /package/dist/{chunk-R4KRSFGA.js.map → chunk-IP4BUBKH.js.map} +0 -0
  200. /package/dist/{chunk-NLTS7JHI.js.map → chunk-JPHDWKZE.js.map} +0 -0
  201. /package/dist/{chunk-24M4YBCL.js.map → chunk-PNAVEK2U.js.map} +0 -0
  202. /package/dist/{model-policy-picker-menu-3R336DP2.js.map → model-policy-picker-menu-RVOQ4ZZG.js.map} +0 -0
  203. /package/dist/{queue-surface-implementation-LK3S4BIW.js.map → queue-surface-implementation-3RIFK2BS.js.map} +0 -0
  204. /package/dist/{timeline-annotation-markers-DRSTLEM6.js.map → timeline-annotation-markers-OY6OWR3V.js.map} +0 -0
  205. /package/dist/{timeline-annotation-selection-IHLUGVND.js.map → timeline-annotation-selection-BOXA2TIN.js.map} +0 -0
  206. /package/dist/{timeline-annotations-dialog-6Q53N5FG.js.map → timeline-annotations-dialog-RGY3MHL3.js.map} +0 -0
@@ -0,0 +1,40 @@
1
+ import type { ContextCompactionItem } from "./types";
2
+
3
+ /**
4
+ * Subtitle for a settled compaction landmark. A definitive provider rejection
5
+ * repeats deterministically for the same conversation, so it names the
6
+ * rejected field and withholds the generic retry promise; every other skip
7
+ * keeps its existing copy.
8
+ */
9
+ export function compactionSkipSubtitle(
10
+ reason: string | null,
11
+ providerRejection: ContextCompactionItem["providerRejection"] = null,
12
+ ): string {
13
+ switch (reason) {
14
+ case "no_history":
15
+ return "No active history to compact";
16
+ case "replacement_not_smaller":
17
+ return "Checkpoint would not reduce memory size";
18
+ case "replacement_unchanged":
19
+ return "Checkpoint made no progress";
20
+ case "summarization_failed":
21
+ return providerRejection
22
+ ? `The model provider rejected the compaction request (${describeCompactionProviderRejection(providerRejection)}). Chat history is unchanged. Repeating it fails the same way until the conversation changes; if a new message fails again, start a new session.`
23
+ : "Request it again to retry. Chat history is unchanged.";
24
+ default:
25
+ return "Compaction was not needed. Chat history is unchanged.";
26
+ }
27
+ }
28
+
29
+ /** `HTTP 400 invalid_request_error, param input[3].encrypted_content`; identifiers only. */
30
+ export function describeCompactionProviderRejection(
31
+ rejection: NonNullable<ContextCompactionItem["providerRejection"]>,
32
+ ): string {
33
+ const parts = [
34
+ `HTTP ${rejection.httpStatus}${rejection.type ? ` ${rejection.type}` : ""}${
35
+ rejection.code ? ` ${rejection.code}` : ""
36
+ }`,
37
+ ];
38
+ if (rejection.param) parts.push(`param ${rejection.param}`);
39
+ return parts.join(", ");
40
+ }
@@ -73,7 +73,7 @@ export default function PlatformActivityRow({
73
73
  : startupPhaseTitle(item.phase, item.status, item.outcome),
74
74
  preview:
75
75
  item.phase === "model_preparation"
76
- ? "Includes overlapping sandbox, rig, repository, and runtime setup shown below."
76
+ ? "Includes overlapping sandbox startup, custom environment setup, repository preparation, and runtime setup shown below."
77
77
  : undefined,
78
78
  running,
79
79
  failed,
@@ -140,7 +140,7 @@ function startupPhaseTitle(
140
140
  return `Sandbox ${outcome === "resumed" ? "reattached" : outcome}`;
141
141
  }
142
142
  if (status === "complete" && phase === "rig" && outcome === "skipped") {
143
- return "Rig already ready";
143
+ return "Sandbox Environment already ready";
144
144
  }
145
145
  const statusIndex =
146
146
  status === "running" ? 0 : status === "failed" ? 1 : status === "cancelled" ? 2 : 3;
@@ -163,7 +163,12 @@ const STARTUP_PHASE_TITLES: Record<
163
163
  "Sandbox startup interrupted",
164
164
  "Sandbox ready",
165
165
  ],
166
- rig: ["Setting up rig", "Rig setup failed", "Rig setup interrupted", "Rig ready"],
166
+ rig: [
167
+ "Setting up sandbox environment",
168
+ "Sandbox Environment setup failed",
169
+ "Sandbox Environment setup interrupted",
170
+ "Sandbox Environment ready",
171
+ ],
167
172
  repository: [
168
173
  "Preparing repository",
169
174
  "Repository preparation failed",
@@ -129,10 +129,20 @@ function timelineAnnotationToolOutputText(output: unknown): string | null {
129
129
  return text.length > 0 ? text : null;
130
130
  }
131
131
 
132
- export function buildTimeline(events: SessionEvent[]): TimelineItem[] {
132
+ export function buildTimeline(
133
+ events: SessionEvent[],
134
+ options: { partialStart?: boolean } = {},
135
+ ): TimelineItem[] {
133
136
  const items: TimelineItem[] = [];
134
137
  const prescan = prescanTurnAnchors(events);
135
138
  const ordered = orderTimelineEvents(events, prescan);
139
+ // A bounded replay can begin halfway through a message (including inside an
140
+ // interactive fence). Never parse that suffix as a complete Markdown source.
141
+ // Keep the raw events available for pagination; a completed receipt restores
142
+ // the authoritative message without requiring an unbounded history fetch.
143
+ let completeHistoryPrefix = options.partialStart !== true;
144
+ const knownMessagePrefixTurns = new Set<string | null>();
145
+ const incompleteMessageKeys = new Set<string>();
136
146
  const pendingWaitOutcomeByTurn = new Map<string | null, PendingWaitOutcome>();
137
147
  const latestAgentResponseByTurn = new Map<string | null, TrackedAgentResponse>();
138
148
  const identifiedMessages = new Map<string, AgentMessageItem>();
@@ -299,6 +309,18 @@ export function buildTimeline(events: SessionEvent[]): TimelineItem[] {
299
309
  for (const event of ordered) {
300
310
  const payload = asRecord(event.payload);
301
311
  const turnId = event.turnId ?? null;
312
+ if (event.type === "session.created") {
313
+ completeHistoryPrefix = true;
314
+ } else if (
315
+ event.type === "turn.started" ||
316
+ (event.type === "user.message" &&
317
+ payload.delivery !== "steer" &&
318
+ payload.routing !== "accepted_for_steering")
319
+ ) {
320
+ // Accepted Steer is visible before its replacement turn starts. It says
321
+ // nothing about the prefix of a still-streaming message from the old turn.
322
+ knownMessagePrefixTurns.add(turnId);
323
+ }
302
324
  startupEvent = event;
303
325
  startupTurnId = turnId;
304
326
  startupAttemptId =
@@ -415,6 +437,13 @@ export function buildTimeline(events: SessionEvent[]): TimelineItem[] {
415
437
  }
416
438
  const messageId = stringValue(payload.messageId);
417
439
  const messageKey = messageId ? JSON.stringify([turnId, messageId]) : null;
440
+ if (
441
+ (!completeHistoryPrefix && !knownMessagePrefixTurns.has(turnId)) ||
442
+ (messageKey && incompleteMessageKeys.has(messageKey))
443
+ ) {
444
+ if (messageKey) incompleteMessageKeys.add(messageKey);
445
+ break;
446
+ }
418
447
  const identified = messageKey ? identifiedMessages.get(messageKey) : undefined;
419
448
  if (identified) {
420
449
  if (identified.annotationSource?.eventType !== "agent.message.completed") {
@@ -470,6 +499,7 @@ export function buildTimeline(events: SessionEvent[]): TimelineItem[] {
470
499
  }
471
500
 
472
501
  case "agent.message.completed": {
502
+ knownMessagePrefixTurns.add(turnId);
473
503
  const text = stringValue(payload.text);
474
504
  const messageId = stringValue(payload.messageId);
475
505
  const messageKey = messageId ? JSON.stringify([turnId, messageId]) : null;
@@ -915,6 +945,7 @@ export function buildTimeline(events: SessionEvent[]): TimelineItem[] {
915
945
  estimatedTokensBefore: numberOrNull(payload.estimatedTokensBefore),
916
946
  estimatedTokensAfter: null,
917
947
  skipReason: null,
948
+ providerRejection: null,
918
949
  implementation:
919
950
  typeof payload.implementation === "string" ? payload.implementation : null,
920
951
  occurredAt: event.occurredAt,
@@ -932,6 +963,7 @@ export function buildTimeline(events: SessionEvent[]): TimelineItem[] {
932
963
  estimatedTokensBefore: numberOrNull(payload.estimatedTokensBefore),
933
964
  estimatedTokensAfter: numberOrNull(payload.estimatedTokensAfter),
934
965
  skipReason: null,
966
+ providerRejection: null,
935
967
  implementation:
936
968
  typeof payload.implementation === "string" ? payload.implementation : null,
937
969
  occurredAt: event.occurredAt,
@@ -949,6 +981,7 @@ export function buildTimeline(events: SessionEvent[]): TimelineItem[] {
949
981
  estimatedTokensBefore: numberOrNull(payload.estimatedTokensBefore),
950
982
  estimatedTokensAfter: null,
951
983
  skipReason: typeof payload.reason === "string" ? payload.reason : null,
984
+ providerRejection: compactionProviderRejection(payload),
952
985
  implementation:
953
986
  typeof payload.implementation === "string" ? payload.implementation : null,
954
987
  occurredAt: event.occurredAt,
@@ -1001,6 +1034,13 @@ export function buildTimeline(events: SessionEvent[]): TimelineItem[] {
1001
1034
  id: event.id,
1002
1035
  turnId,
1003
1036
  serverId: typeof payload.serverId === "string" ? payload.serverId : null,
1037
+ canonicalServerId:
1038
+ typeof payload.canonicalServerId === "string" ? payload.canonicalServerId : null,
1039
+ connectionSubjectScope:
1040
+ payload.connectionSubjectScope === "subject" ||
1041
+ payload.connectionSubjectScope === "workspace"
1042
+ ? payload.connectionSubjectScope
1043
+ : null,
1004
1044
  source: capability
1005
1045
  ? "capability"
1006
1046
  : event.type === "tool.auth_needed"
@@ -1277,7 +1317,16 @@ export function buildTimeline(events: SessionEvent[]): TimelineItem[] {
1277
1317
  }
1278
1318
  }
1279
1319
 
1320
+ const sourceEventsById = new Map(events.map((event) => [event.id, event]));
1280
1321
  for (const item of items) {
1322
+ const source = sourceEventsById.get(item.id);
1323
+ const canonical = "annotationSource" in item ? item.annotationSource : undefined;
1324
+ item.sourceEvents = [
1325
+ ...(source ? [{ eventId: source.id, sequence: source.sequence }] : []),
1326
+ ...(canonical && canonical.eventId !== source?.id
1327
+ ? [{ eventId: canonical.eventId, sequence: canonical.sequence }]
1328
+ : []),
1329
+ ];
1281
1330
  if (item.kind === "agent-message") {
1282
1331
  item.text = stripOpaqueCitationTokens(item.text);
1283
1332
  }
@@ -2096,6 +2145,29 @@ function numberOrNull(value: unknown): number | null {
2096
2145
  return typeof value === "number" && Number.isFinite(value) ? value : null;
2097
2146
  }
2098
2147
 
2148
+ /**
2149
+ * Read the closed provider-rejection record a `summarization_failed` skip
2150
+ * carries. Only bounded identifiers are accepted; a provider message is never
2151
+ * part of the payload and would be ignored here anyway.
2152
+ */
2153
+ function compactionProviderRejection(
2154
+ payload: Record<string, unknown>,
2155
+ ): ContextCompactionItem["providerRejection"] {
2156
+ const record = asRecord(payload.providerRejection);
2157
+ if (typeof record.httpStatus !== "number" || !Number.isFinite(record.httpStatus)) {
2158
+ return null;
2159
+ }
2160
+ const text = (value: unknown): string | null =>
2161
+ typeof value === "string" && value.trim() ? value : null;
2162
+ return {
2163
+ httpStatus: record.httpStatus,
2164
+ type: text(record.type),
2165
+ code: text(record.code),
2166
+ param: text(record.param),
2167
+ requestId: text(record.requestId),
2168
+ };
2169
+ }
2170
+
2099
2171
  function compactionTrigger(payload: Record<string, unknown>): ContextCompactionItem["trigger"] {
2100
2172
  const trigger = payload.trigger;
2101
2173
  return trigger === "auto" ||
@@ -2527,7 +2599,7 @@ function capabilityAuthorizationRequest(
2527
2599
  if (
2528
2600
  typeof record.id !== "string" ||
2529
2601
  typeof record.name !== "string" ||
2530
- !["pack", "mcp", "api", "skill", "plugin"].includes(String(kind)) ||
2602
+ !["mcp", "api", "skill", "plugin"].includes(String(kind)) ||
2531
2603
  !["built_in", "library", "configured", "public_registry", "registry", "manual"].includes(
2532
2604
  String(source),
2533
2605
  ) ||
@@ -1,5 +1,6 @@
1
1
  import { CameraIcon, CameraOffIcon, ChevronRightIcon } from "lucide-react";
2
- import { createContext, useContext, useState, type ReactNode } from "react";
2
+ import { createContext, useContext, useEffect, useState, type ReactNode } from "react";
3
+ import { useTimelineSearchReveal } from "../components/timeline-search";
3
4
  import { cn } from "../lib/cn";
4
5
  import { stringifyPayload } from "../lib/format";
5
6
  import { useForcedDefaultOpen } from "./disclosure-context";
@@ -154,6 +155,10 @@ export function ActivityDisclosure({
154
155
  // absent in normal app usage, where the row starts collapsed.
155
156
  const forcedDefaultOpen = useForcedDefaultOpen();
156
157
  const [open, setOpen] = useState(defaultOpen ?? forcedDefaultOpen ?? false);
158
+ const searchReveal = useTimelineSearchReveal();
159
+ useEffect(() => {
160
+ if (searchReveal) setOpen(true);
161
+ }, [searchReveal]);
157
162
  const truncation = useContext(ToolCallTruncationContext);
158
163
  const compact = useContext(CompactActivityContext);
159
164
  if (compact)
@@ -3,7 +3,7 @@ import type { StartupPhaseItem } from "./types";
3
3
  const LABELS: Record<StartupPhaseItem["phase"], string> = {
4
4
  queue: "Worker queue",
5
5
  sandbox: "Sandbox",
6
- rig: "Rig",
6
+ rig: "Sandbox Environment",
7
7
  repository: "Repository",
8
8
  files: "Files",
9
9
  tools: "Tools",
@@ -14,6 +14,7 @@ import { CopyButton } from "../components/copy-button";
14
14
  import { cn } from "../lib/cn";
15
15
  import { MOTION_INSPECT_SCALE } from "../lib/motion-inspect";
16
16
  import { useForcedDefaultOpen } from "./disclosure-context";
17
+ import { useTimelineSearchReveal } from "../components/timeline-search";
17
18
  import { useEntranceAnimation } from "./entrance";
18
19
  import { useFoldMemory, type FoldRestingState } from "./fold-memory";
19
20
  import {
@@ -125,8 +126,8 @@ export type TurnSummaryProps = {
125
126
  items: ActivityItem[];
126
127
  /**
127
128
  * The settled verdict — or absent for a completed CLUSTER of a still-running
128
- * turn, which folds neutrally: no verdict glyph (the turn has none yet), a
129
- * quiet pulse dot in its place so alignment and the running feel both hold.
129
+ * turn, which folds neutrally. Only unfinished activity inside this summary
130
+ * animates; the parent turn may still be composing a response elsewhere.
130
131
  */
131
132
  outcome?: TurnOutcome | undefined;
132
133
  /** A short failure reason shown inline on a failed chip (never hidden). */
@@ -202,6 +203,7 @@ export function TurnSummary({
202
203
  // An explicit `defaultOpen` always wins; otherwise an ancestor may seed it
203
204
  // (screenshot instrumentation); otherwise the turn starts folded.
204
205
  const forcedDefaultOpen = useForcedDefaultOpen();
206
+ const searchReveal = useTimelineSearchReveal();
205
207
  const foldMemory = useFoldMemory();
206
208
  // A remembered resting state outranks author defaults: a fold that already
207
209
  // finished its settle collapse (or that the reader closed) mounts closed
@@ -315,6 +317,18 @@ export function TurnSummary({
315
317
  }
316
318
  // oxlint-disable-next-line react-hooks/exhaustive-deps
317
319
  }, [settleFold]);
320
+ useEffect(() => {
321
+ if (!searchReveal) return;
322
+ clearSettleTimers();
323
+ settleArmedRef.current = false;
324
+ setSettling(false);
325
+ setSettlePhase(false);
326
+ setNestSuppressLatch(false);
327
+ setOpen(true);
328
+ rememberResting("open");
329
+ // Search is an explicit, persistent reader action, not a new fold default.
330
+ // oxlint-disable-next-line react-hooks/exhaustive-deps
331
+ }, [searchReveal]);
318
332
  const onOpenChange = (next: boolean) => {
319
333
  // The reader took over — cancel the pending auto-collapse for good.
320
334
  // Clear settle CSS phase immediately (fast collapse) but keep nest latch
@@ -447,7 +461,7 @@ export function TurnSummary({
447
461
  />
448
462
  {/* Completion is the quiet default and needs no repeated glyph. Failed,
449
463
  cancelled, and still-running folds retain a visible state marker. */}
450
- {outcome === "complete" || (liveHeader && !outcome) ? null : (
464
+ {outcome === "complete" || (!outcome && (liveHeader || context.settled)) ? null : (
451
465
  <span
452
466
  className={cn(
453
467
  "inline-flex shrink-0 items-center justify-center",
@@ -383,11 +383,24 @@ export type ContextCompactionItem = {
383
383
  estimatedTokensBefore: number | null;
384
384
  estimatedTokensAfter: number | null;
385
385
  skipReason: string | null;
386
+ /**
387
+ * Present only for a `summarization_failed` skip where the provider
388
+ * definitively rejected the compaction request. Content-free identifiers.
389
+ */
390
+ providerRejection: ContextCompactionProviderRejection | null;
386
391
  /** Provider implementation id for debug disclosure only. */
387
392
  implementation: string | null;
388
393
  occurredAt: string;
389
394
  };
390
395
 
396
+ export type ContextCompactionProviderRejection = {
397
+ httpStatus: number;
398
+ type: string | null;
399
+ code: string | null;
400
+ param: string | null;
401
+ requestId: string | null;
402
+ };
403
+
391
404
  export type MachineInputMember = {
392
405
  id: string;
393
406
  kind:
@@ -438,6 +451,9 @@ export type AuthNeededItem = {
438
451
  turnId: string | null;
439
452
  /** The runtime surface that requested recovery, when the event is an MCP auth signal. */
440
453
  serverId: string | null;
454
+ /** Explicit recovery identity; never inferred from an opaque execution alias. */
455
+ canonicalServerId?: string | null;
456
+ connectionSubjectScope?: "workspace" | "subject" | null;
441
457
  /** Durable event family that produced this notice. */
442
458
  source?: "tool" | "credential" | "capability" | undefined;
443
459
  /** The connection's registrable domain, e.g. "linear.app". */
@@ -473,7 +489,7 @@ export type TurnEndItem = {
473
489
  occurredAt: string;
474
490
  };
475
491
 
476
- export type TimelineItem =
492
+ export type TimelineItem = (
477
493
  | UserMessageItem
478
494
  | HumanInputItem
479
495
  | AgentMessageItem
@@ -492,7 +508,11 @@ export type TimelineItem =
492
508
  | MemoryItem
493
509
  | KnowledgeItem
494
510
  | FleetDecisionItem
495
- | TurnEndItem;
511
+ | TurnEndItem
512
+ ) & {
513
+ /** Durable identities, independent of renderer/reconciliation keys. */
514
+ sourceEvents?: readonly { eventId: string; sequence: number }[] | undefined;
515
+ };
496
516
 
497
517
  /** Activity items cluster between chat messages (reasoning, tools, workers, sandbox, memory). */
498
518
  export type ActivityItem =