@opengeni/react 0.48.0 → 0.52.1

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 (284) hide show
  1. package/README.md +90 -2
  2. package/dist/artifacts-document.d.ts +3 -0
  3. package/dist/artifacts-document.js +17 -0
  4. package/dist/artifacts-document.js.map +1 -0
  5. package/dist/artifacts-presentation.d.ts +3 -0
  6. package/dist/artifacts-presentation.js +17 -0
  7. package/dist/artifacts-presentation.js.map +1 -0
  8. package/dist/artifacts-spreadsheet.d.ts +3 -0
  9. package/dist/artifacts-spreadsheet.js +17 -0
  10. package/dist/artifacts-spreadsheet.js.map +1 -0
  11. package/dist/artifacts.d.ts +2 -0
  12. package/dist/artifacts.js +170 -0
  13. package/dist/artifacts.js.map +1 -0
  14. package/dist/chunk-6BBWWOOU.js +82 -0
  15. package/dist/chunk-6BBWWOOU.js.map +1 -0
  16. package/dist/{chunk-FWXGSNXT.js → chunk-724BW4TW.js} +585 -34
  17. package/dist/chunk-724BW4TW.js.map +1 -0
  18. package/dist/chunk-7I2KB3OK.js +3895 -0
  19. package/dist/chunk-7I2KB3OK.js.map +1 -0
  20. package/dist/chunk-7WCLAEFV.js +2828 -0
  21. package/dist/chunk-7WCLAEFV.js.map +1 -0
  22. package/dist/{chunk-I4MPFDRP.js → chunk-FWS3KC3Z.js} +3 -3
  23. package/dist/{chunk-EKZH6IDG.js → chunk-HDBG7XGO.js} +62 -1
  24. package/dist/chunk-HDBG7XGO.js.map +1 -0
  25. package/dist/chunk-HUIKIDM5.js +2148 -0
  26. package/dist/chunk-HUIKIDM5.js.map +1 -0
  27. package/dist/{chunk-XCNTXWBB.js → chunk-JAGDUCZQ.js} +854 -340
  28. package/dist/chunk-JAGDUCZQ.js.map +1 -0
  29. package/dist/{chunk-LHLYWG5R.js → chunk-JR3QFY6B.js} +413 -37
  30. package/dist/chunk-JR3QFY6B.js.map +1 -0
  31. package/dist/chunk-JVYQRRC4.js +53 -0
  32. package/dist/chunk-JVYQRRC4.js.map +1 -0
  33. package/dist/chunk-KCGXPP5V.js +157 -0
  34. package/dist/chunk-KCGXPP5V.js.map +1 -0
  35. package/dist/chunk-PEI6RANI.js +3234 -0
  36. package/dist/chunk-PEI6RANI.js.map +1 -0
  37. package/dist/{chunk-NJ7M2B6Z.js → chunk-ROIRTM37.js} +18 -10
  38. package/dist/{chunk-NJ7M2B6Z.js.map → chunk-ROIRTM37.js.map} +1 -1
  39. package/dist/{chunk-O4VXOBGF.js → chunk-WSK7G5LE.js} +70 -2
  40. package/dist/chunk-WSK7G5LE.js.map +1 -0
  41. package/dist/{chunk-OL6QVXGF.js → chunk-X4S56Y2H.js} +27 -7
  42. package/dist/{chunk-OL6QVXGF.js.map → chunk-X4S56Y2H.js.map} +1 -1
  43. package/dist/client.d.ts +7 -1
  44. package/dist/clipboard.d.ts +1 -0
  45. package/dist/clipboard.js +7 -0
  46. package/dist/clipboard.js.map +1 -0
  47. package/dist/commands/index.d.ts +3 -3
  48. package/dist/commands/registry.d.ts +1 -1
  49. package/dist/commands/types.d.ts +1 -1
  50. package/dist/components/approval-surface.d.ts +2 -2
  51. package/dist/components/artifacts/artifact-surface.d.ts +18 -0
  52. package/dist/components/artifacts/document-editor.d.ts +172 -0
  53. package/dist/components/artifacts/editable-artifact-ui.d.ts +13 -0
  54. package/dist/components/artifacts/editable-artifact-workbench.d.ts +49 -0
  55. package/dist/components/artifacts/editable-document.d.ts +24 -0
  56. package/dist/components/artifacts/editable-presentation.d.ts +24 -0
  57. package/dist/components/artifacts/editable-spreadsheet.d.ts +32 -0
  58. package/dist/components/artifacts/index.d.ts +8 -0
  59. package/dist/components/artifacts/presentation-editor.d.ts +297 -0
  60. package/dist/components/artifacts/spreadsheet-canvas.d.ts +120 -0
  61. package/dist/components/artifacts/spreadsheet-grid.d.ts +113 -0
  62. package/dist/components/browser-viewer.d.ts +29 -0
  63. package/dist/components/chat-composer.d.ts +8 -8
  64. package/dist/components/code-editor.d.ts +25 -3
  65. package/dist/components/command-palette.d.ts +2 -2
  66. package/dist/components/composer-transcription-control.d.ts +2 -2
  67. package/dist/components/composer.d.ts +17 -17
  68. package/dist/components/computer-viewer.d.ts +23 -0
  69. package/dist/components/copy-button.d.ts +2 -2
  70. package/dist/components/desktop-viewer.d.ts +25 -21
  71. package/dist/components/diff-view.d.ts +1 -1
  72. package/dist/components/enrollment-consent.d.ts +1 -1
  73. package/dist/components/enrollment-device-flow.d.ts +1 -1
  74. package/dist/components/file-browser.d.ts +2 -2
  75. package/dist/components/fleet-tile.d.ts +1 -1
  76. package/dist/components/generated-video-player.d.ts +10 -0
  77. package/dist/components/human-input-form.d.ts +1 -1
  78. package/dist/components/human-input-surface.d.ts +2 -2
  79. package/dist/components/interactive-workbench-viewers.d.ts +2 -0
  80. package/dist/components/machine-card.d.ts +2 -2
  81. package/dist/components/machine-dock-bar.d.ts +3 -3
  82. package/dist/components/machine-health-pill.d.ts +2 -2
  83. package/dist/components/machine-input-display.d.ts +1 -1
  84. package/dist/components/machine-metrics.d.ts +2 -2
  85. package/dist/components/machine-status-pill.d.ts +4 -4
  86. package/dist/components/machines/health.d.ts +1 -1
  87. package/dist/components/machines/machine-detail.d.ts +3 -3
  88. package/dist/components/machines/metric-history-chart.d.ts +1 -1
  89. package/dist/components/machines/metric-sparkline.d.ts +2 -2
  90. package/dist/components/machines/series.d.ts +2 -2
  91. package/dist/components/machines-dashboard.d.ts +2 -2
  92. package/dist/components/markdown.d.ts +1 -1
  93. package/dist/components/message-timeline.d.ts +12 -5
  94. package/dist/components/model-picker.d.ts +2 -2
  95. package/dist/components/model-policy-picker.d.ts +7 -7
  96. package/dist/components/pierre-diff.d.ts +1 -1
  97. package/dist/components/pierre-file.d.ts +1 -1
  98. package/dist/components/queue-draft-policy.d.ts +1 -1
  99. package/dist/components/queue-surface-implementation.d.ts +3 -3
  100. package/dist/components/queue-surface-state.d.ts +4 -4
  101. package/dist/components/queue-surface.d.ts +5 -5
  102. package/dist/components/sandbox-files.d.ts +3 -3
  103. package/dist/components/sandbox-terminal.d.ts +21 -4
  104. package/dist/components/sandbox-workspace.d.ts +25 -9
  105. package/dist/components/session-chrome.d.ts +4 -4
  106. package/dist/components/session-status.d.ts +2 -2
  107. package/dist/components/timeline-annotation-selection.d.ts +9 -0
  108. package/dist/components/timeline-annotations-dialog.d.ts +16 -0
  109. package/dist/components/timeline-annotations.d.ts +13 -0
  110. package/dist/components/tooltip.d.ts +4 -4
  111. package/dist/components/user-message-body.d.ts +2 -2
  112. package/dist/components/workbench-changes.d.ts +2 -2
  113. package/dist/components/workspace-dock.d.ts +1 -1
  114. package/dist/composer.d.ts +11 -11
  115. package/dist/composer.js +5 -5
  116. package/dist/hooks/internal.d.ts +1 -1
  117. package/dist/hooks/use-attached-browsers.d.ts +21 -0
  118. package/dist/hooks/use-available-models.d.ts +2 -2
  119. package/dist/hooks/use-billing-usage.d.ts +1 -1
  120. package/dist/hooks/use-browser-frame-stream.d.ts +28 -0
  121. package/dist/hooks/use-browser-identities.d.ts +26 -0
  122. package/dist/hooks/use-browser-session.d.ts +28 -0
  123. package/dist/hooks/use-browser-sessions.d.ts +32 -0
  124. package/dist/hooks/use-codex-accounts.d.ts +2 -2
  125. package/dist/hooks/use-composer.d.ts +36 -9
  126. package/dist/hooks/use-computer-frame-stream.d.ts +24 -0
  127. package/dist/hooks/use-computer-session.d.ts +28 -0
  128. package/dist/hooks/use-computer-sessions.d.ts +28 -0
  129. package/dist/hooks/use-desktop-stream.d.ts +1 -1
  130. package/dist/hooks/use-environments.d.ts +1 -1
  131. package/dist/hooks/use-file-attachments.d.ts +1 -1
  132. package/dist/hooks/use-goal.d.ts +2 -2
  133. package/dist/hooks/use-human-input.d.ts +2 -2
  134. package/dist/hooks/use-last-started-turn-policy.d.ts +2 -2
  135. package/dist/hooks/use-machine-chip.d.ts +2 -2
  136. package/dist/hooks/use-machines.d.ts +4 -4
  137. package/dist/hooks/use-packs.d.ts +7 -2
  138. package/dist/hooks/use-rigs.d.ts +1 -1
  139. package/dist/hooks/use-sandbox-files.d.ts +6 -4
  140. package/dist/hooks/use-sandbox-git.d.ts +6 -5
  141. package/dist/hooks/use-sandbox-terminal.d.ts +1 -1
  142. package/dist/hooks/use-scheduled-tasks.d.ts +1 -1
  143. package/dist/hooks/use-session-capabilities.d.ts +5 -4
  144. package/dist/hooks/use-session-control.d.ts +1 -1
  145. package/dist/hooks/use-session-events.d.ts +2 -2
  146. package/dist/hooks/use-session-lineage.d.ts +1 -1
  147. package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
  148. package/dist/hooks/use-session.d.ts +2 -2
  149. package/dist/hooks/use-slash-commands.d.ts +1 -1
  150. package/dist/hooks/use-terminal-stream.d.ts +8 -2
  151. package/dist/hooks/use-turn-queue.d.ts +2 -2
  152. package/dist/hooks/use-video-artifact-playback.d.ts +9 -0
  153. package/dist/hooks/use-voice-input.d.ts +1 -1
  154. package/dist/hooks/use-workspace-capture.d.ts +1 -1
  155. package/dist/hooks/use-workspace-edit.d.ts +1 -1
  156. package/dist/hooks/use-workspace-sessions.d.ts +1 -1
  157. package/dist/hooks/use-workspaces.d.ts +1 -1
  158. package/dist/index.d.ts +158 -155
  159. package/dist/index.js +906 -462
  160. package/dist/index.js.map +1 -1
  161. package/dist/interaction.d.ts +23 -0
  162. package/dist/interaction.js +36 -0
  163. package/dist/interaction.js.map +1 -0
  164. package/dist/interactive-workbench-viewers-KHNOHWQE.js +13 -0
  165. package/dist/interactive-workbench-viewers-KHNOHWQE.js.map +1 -0
  166. package/dist/lib/relay-wire.d.ts +4 -0
  167. package/dist/lib/sandbox-liveness.d.ts +9 -0
  168. package/dist/lib/terminal-capability.d.ts +5 -0
  169. package/dist/lib/xterm-theme.d.ts +1 -1
  170. package/dist/machines.d.ts +30 -30
  171. package/dist/machines.js +3 -3
  172. package/dist/provider.d.ts +4 -4
  173. package/dist/{queue-surface-implementation-U5JFG7HT.js → queue-surface-implementation-2KVJTYXH.js} +100 -48
  174. package/dist/queue-surface-implementation-2KVJTYXH.js.map +1 -0
  175. package/dist/realtime/dropdown-menu.d.ts +8 -8
  176. package/dist/realtime/realtime-control.d.ts +6 -6
  177. package/dist/realtime.d.ts +4 -4
  178. package/dist/realtime.js +3 -3
  179. package/dist/session-context.d.ts +19 -1
  180. package/dist/session-ui.d.ts +14 -14
  181. package/dist/session-ui.js +5 -4
  182. package/dist/session.d.ts +28 -28
  183. package/dist/session.js +5 -5
  184. package/dist/timeline/activity-rail.d.ts +5 -3
  185. package/dist/timeline/disclosure-context.d.ts +1 -1
  186. package/dist/timeline/fleet-decision-projection.d.ts +1 -1
  187. package/dist/timeline/fleet-decision-row.d.ts +3 -3
  188. package/dist/timeline/index.d.ts +19 -19
  189. package/dist/timeline/parsers.d.ts +4 -1
  190. package/dist/timeline/projection.d.ts +3 -3
  191. package/dist/timeline/registry.d.ts +8 -2
  192. package/dist/timeline/screenshot-lightbox.d.ts +2 -2
  193. package/dist/timeline/shared.d.ts +21 -10
  194. package/dist/timeline/tool-diff.d.ts +2 -2
  195. package/dist/timeline/tool-renderers.d.ts +1 -1
  196. package/dist/timeline/turn-summary.d.ts +3 -3
  197. package/dist/timeline/types.d.ts +39 -3
  198. package/dist/timeline-annotation-selection-3L7LHGG2.js +187 -0
  199. package/dist/timeline-annotation-selection-3L7LHGG2.js.map +1 -0
  200. package/dist/timeline-annotations-dialog-U7EVLR75.js +196 -0
  201. package/dist/timeline-annotations-dialog-U7EVLR75.js.map +1 -0
  202. package/package.json +36 -7
  203. package/src/artifacts-document.ts +31 -0
  204. package/src/artifacts-presentation.ts +36 -0
  205. package/src/artifacts-spreadsheet.ts +21 -0
  206. package/src/artifacts.ts +86 -0
  207. package/src/client.ts +87 -1
  208. package/src/clipboard.ts +2 -0
  209. package/src/components/artifacts/artifact-surface.tsx +93 -0
  210. package/src/components/artifacts/document-editor.tsx +2255 -0
  211. package/src/components/artifacts/editable-artifact-ui.tsx +89 -0
  212. package/src/components/artifacts/editable-artifact-workbench.tsx +203 -0
  213. package/src/components/artifacts/editable-document.tsx +657 -0
  214. package/src/components/artifacts/editable-presentation.tsx +1020 -0
  215. package/src/components/artifacts/editable-spreadsheet.tsx +733 -0
  216. package/src/components/artifacts/index.ts +99 -0
  217. package/src/components/artifacts/presentation-editor.tsx +3148 -0
  218. package/src/components/artifacts/spreadsheet-canvas.ts +799 -0
  219. package/src/components/artifacts/spreadsheet-grid.tsx +2129 -0
  220. package/src/components/browser-viewer.tsx +1592 -0
  221. package/src/components/chat-composer.tsx +13 -0
  222. package/src/components/code-editor.tsx +89 -30
  223. package/src/components/composer-transcription-control.tsx +10 -6
  224. package/src/components/computer-viewer.tsx +1139 -0
  225. package/src/components/desktop-viewer.tsx +101 -73
  226. package/src/components/generated-video-player.tsx +89 -0
  227. package/src/components/interactive-workbench-viewers.ts +2 -0
  228. package/src/components/machine-input-display.ts +3 -0
  229. package/src/components/message-timeline.tsx +289 -32
  230. package/src/components/queue-surface-implementation.tsx +116 -60
  231. package/src/components/sandbox-files.tsx +2 -2
  232. package/src/components/sandbox-terminal.tsx +106 -41
  233. package/src/components/sandbox-workspace.tsx +215 -87
  234. package/src/components/session-chrome.tsx +53 -13
  235. package/src/components/timeline-annotation-selection.tsx +221 -0
  236. package/src/components/timeline-annotations-dialog.tsx +213 -0
  237. package/src/components/timeline-annotations.tsx +84 -0
  238. package/src/components/workbench-changes.tsx +188 -31
  239. package/src/hooks/use-attached-browsers.ts +152 -0
  240. package/src/hooks/use-browser-frame-stream.ts +316 -0
  241. package/src/hooks/use-browser-identities.ts +225 -0
  242. package/src/hooks/use-browser-session.ts +476 -0
  243. package/src/hooks/use-browser-sessions.ts +281 -0
  244. package/src/hooks/use-composer.ts +769 -24
  245. package/src/hooks/use-computer-frame-stream.ts +311 -0
  246. package/src/hooks/use-computer-session.ts +442 -0
  247. package/src/hooks/use-computer-sessions.ts +245 -0
  248. package/src/hooks/use-machine-chip.ts +5 -3
  249. package/src/hooks/use-machines.ts +33 -3
  250. package/src/hooks/use-packs.ts +51 -0
  251. package/src/hooks/use-sandbox-files.ts +98 -55
  252. package/src/hooks/use-sandbox-git.ts +93 -38
  253. package/src/hooks/use-sandbox-terminal.ts +3 -2
  254. package/src/hooks/use-session-capabilities.ts +59 -46
  255. package/src/hooks/use-terminal-stream.ts +102 -23
  256. package/src/hooks/use-video-artifact-playback.ts +28 -0
  257. package/src/hooks/use-workspace-edit.ts +2 -1
  258. package/src/index.ts +10 -0
  259. package/src/interaction.ts +71 -0
  260. package/src/lib/relay-wire.ts +4 -0
  261. package/src/lib/sandbox-liveness.ts +11 -0
  262. package/src/lib/terminal-capability.ts +10 -0
  263. package/src/session-context.ts +90 -0
  264. package/src/timeline/activity-rail.tsx +19 -3
  265. package/src/timeline/index.ts +3 -0
  266. package/src/timeline/parsers.ts +14 -1
  267. package/src/timeline/projection.ts +211 -14
  268. package/src/timeline/registry.ts +13 -1
  269. package/src/timeline/screenshot-lightbox.tsx +19 -9
  270. package/src/timeline/shared.tsx +56 -8
  271. package/src/timeline/tool-renderers.tsx +303 -50
  272. package/src/timeline/types.ts +55 -3
  273. package/styles/compiled.css +248 -15
  274. package/styles/index.css +15 -0
  275. package/styles/responsive.css +13 -1
  276. package/dist/chunk-EKZH6IDG.js.map +0 -1
  277. package/dist/chunk-FWXGSNXT.js.map +0 -1
  278. package/dist/chunk-LHLYWG5R.js.map +0 -1
  279. package/dist/chunk-O4VXOBGF.js.map +0 -1
  280. package/dist/chunk-XCNTXWBB.js.map +0 -1
  281. package/dist/fleet-decision-projection-SLNZMS42.js +0 -241
  282. package/dist/fleet-decision-projection-SLNZMS42.js.map +0 -1
  283. package/dist/queue-surface-implementation-U5JFG7HT.js.map +0 -1
  284. /package/dist/{chunk-I4MPFDRP.js.map → chunk-FWS3KC3Z.js.map} +0 -0
@@ -1,8 +1,13 @@
1
- import type { ResourceRef, SessionStatus, ToolAuthNeededPayload, ToolRef } from "@opengeni/sdk";
1
+ import type { MediaGenerationResult, ResourceRef, SessionStatus, TimelineAnnotation, TimelineAnnotationSource, ToolAuthNeededPayload, ToolRef } from "@opengeni/sdk";
2
+ export type TimelineAnnotationSourceDescriptor = Omit<TimelineAnnotationSource, "startOffset" | "endOffset" | "contextBefore" | "contextAfter"> & {
3
+ text: string;
4
+ };
2
5
  export type UserMessageItem = {
3
6
  kind: "user-message";
4
7
  id: string;
5
8
  text: string;
9
+ annotations?: TimelineAnnotation[] | undefined;
10
+ annotationSource?: TimelineAnnotationSourceDescriptor | undefined;
6
11
  presentation?: {
7
12
  kind: "realtime_voice" | "realtime_voice_handoff";
8
13
  /** Full bounded execution context sent with this visible voice request. */
@@ -13,6 +18,13 @@ export type UserMessageItem = {
13
18
  /** Tools requested for the turn this message starts. */
14
19
  tools: ToolRef[];
15
20
  occurredAt: string;
21
+ /** Local-only delivery projection; absent for authoritative durable events. */
22
+ delivery?: {
23
+ state: "sending" | "queued" | "failed";
24
+ error?: string | undefined;
25
+ onRetry?: (() => void) | undefined;
26
+ onRemove?: (() => void) | undefined;
27
+ } | undefined;
16
28
  };
17
29
  export type AgentMessageItem = {
18
30
  kind: "agent-message";
@@ -22,6 +34,8 @@ export type AgentMessageItem = {
22
34
  /** Still receiving deltas (no completed/turn-end seen yet). */
23
35
  streaming: boolean;
24
36
  occurredAt: string;
37
+ /** Available only after the canonical completed event lands. */
38
+ annotationSource?: TimelineAnnotationSourceDescriptor | undefined;
25
39
  };
26
40
  export type ReasoningItem = {
27
41
  kind: "reasoning";
@@ -31,6 +45,22 @@ export type ReasoningItem = {
31
45
  streaming: boolean;
32
46
  occurredAt: string;
33
47
  };
48
+ /**
49
+ * Bounded delivery metadata carried by a projected tool-output event. The
50
+ * canonical event remains unchanged; this fact only explains what the current
51
+ * timeline surface could render and whether separately retained full evidence
52
+ * exists.
53
+ */
54
+ export type ToolCallTruncation = {
55
+ truncated: true;
56
+ surface: string;
57
+ reason: string;
58
+ omittedBytes: number | null;
59
+ fullEvidence: {
60
+ available: boolean;
61
+ reason: string | null;
62
+ };
63
+ };
34
64
  export type ToolCallItem = {
35
65
  kind: "tool-call";
36
66
  id: string;
@@ -39,6 +69,7 @@ export type ToolCallItem = {
39
69
  name: string;
40
70
  arguments: unknown;
41
71
  output: unknown;
72
+ truncation?: ToolCallTruncation | null;
42
73
  /**
43
74
  * The provider-native tool item (`agent.toolCall.created.payload.raw`). Carries
44
75
  * `type` (e.g. `apply_patch_call`, `computer_call`, `hosted_tool_call`) and the
@@ -49,6 +80,8 @@ export type ToolCallItem = {
49
80
  raw: unknown;
50
81
  status: "running" | "complete" | "failed" | "cancelled";
51
82
  occurredAt: string;
83
+ /** Canonical textual projection of the settled tool output. */
84
+ annotationSource?: TimelineAnnotationSourceDescriptor | undefined;
52
85
  };
53
86
  /**
54
87
  * An orchestration call against another session — the manager spawning or
@@ -210,10 +243,11 @@ export type ContextCompactionItem = {
210
243
  };
211
244
  export type MachineInputMember = {
212
245
  id: string;
213
- kind: "scheduled_occurrence" | "goal_continuation" | "agent_message" | "agent_steer_instruction" | "child_terminal_result";
246
+ kind: "scheduled_occurrence" | "goal_continuation" | "agent_message" | "agent_steer_instruction" | "child_terminal_result" | "media_generation_result";
214
247
  classification: "success" | "failure" | "action_required" | "info";
215
248
  sourceId: string;
216
249
  summary: string;
250
+ result?: MediaGenerationResult | undefined;
217
251
  };
218
252
  /**
219
253
  * One or more durable non-human inputs that joined the following agent turn.
@@ -243,7 +277,7 @@ export type AuthNeededItem = {
243
277
  /** The runtime surface that requested recovery, when the event is an MCP auth signal. */
244
278
  serverId: string | null;
245
279
  /** Durable event family that produced this notice. */
246
- source?: "tool" | "credential" | undefined;
280
+ source?: "tool" | "credential" | "capability" | undefined;
247
281
  /** The connection's registrable domain, e.g. "linear.app". */
248
282
  providerDomain: string;
249
283
  /** The lapsed connection to reconnect, when the row survived. */
@@ -257,6 +291,8 @@ export type AuthNeededItem = {
257
291
  toolName: string | null;
258
292
  /** A pre-minted authorization URL, when the broker already produced one. */
259
293
  authorizationUrl: string | null;
294
+ /** Agent-selected catalog recommendation. The host still owns authorization. */
295
+ capability?: NonNullable<ToolAuthNeededPayload["capability"]> | null | undefined;
260
296
  occurredAt: string;
261
297
  };
262
298
  export type TurnOutcome = "complete" | "failed" | "cancelled";
@@ -0,0 +1,187 @@
1
+ // src/components/timeline-annotation-selection.tsx
2
+ import { useEffect, useRef, useState } from "react";
3
+ import { createPortal } from "react-dom";
4
+ import { jsx } from "react/jsx-runtime";
5
+ var INTERACTIVE_SELECTOR = 'a,button,input,textarea,select,summary,[role="button"],[contenteditable="true"],[tabindex]:not([tabindex="-1"])';
6
+ var SOURCE_CONTEXT_BYTES = 160;
7
+ var MAX_QUOTE_BYTES = 16 * 1024;
8
+ function utf8Prefix(value, maxBytes) {
9
+ let output = "";
10
+ let bytes = 0;
11
+ for (const character of value) {
12
+ const next = new TextEncoder().encode(character).byteLength;
13
+ if (bytes + next > maxBytes) break;
14
+ output += character;
15
+ bytes += next;
16
+ }
17
+ return output;
18
+ }
19
+ function utf8Suffix(value, maxBytes) {
20
+ let output = "";
21
+ let bytes = 0;
22
+ for (const character of [...value].reverse()) {
23
+ const next = new TextEncoder().encode(character).byteLength;
24
+ if (bytes + next > maxBytes) break;
25
+ output = character + output;
26
+ bytes += next;
27
+ }
28
+ return output;
29
+ }
30
+ function selectionElement(node) {
31
+ return node instanceof Element ? node : node?.parentElement ?? null;
32
+ }
33
+ function containingSource(node) {
34
+ const element = selectionElement(node);
35
+ const source = element?.closest("[data-og-annotation-source-key]");
36
+ return source instanceof HTMLElement ? source : null;
37
+ }
38
+ function isInteractiveSelection(node, boundary) {
39
+ const element = selectionElement(node);
40
+ const interactive = element?.closest(INTERACTIVE_SELECTOR);
41
+ return interactive instanceof Element && boundary.contains(interactive);
42
+ }
43
+ function occurrenceOffsets(text, quote) {
44
+ const offsets = [];
45
+ let cursor = 0;
46
+ while (cursor <= text.length - quote.length) {
47
+ const offset = text.indexOf(quote, cursor);
48
+ if (offset < 0) break;
49
+ offsets.push(offset);
50
+ cursor = offset + 1;
51
+ }
52
+ return offsets;
53
+ }
54
+ function selectedOccurrence(boundary, range, quote) {
55
+ try {
56
+ const prefix = range.cloneRange();
57
+ prefix.selectNodeContents(boundary);
58
+ prefix.setEnd(range.startContainer, range.startOffset);
59
+ return occurrenceOffsets(prefix.toString(), quote).length;
60
+ } catch {
61
+ return 0;
62
+ }
63
+ }
64
+ function annotationId() {
65
+ if (typeof globalThis.crypto?.randomUUID === "function") {
66
+ return globalThis.crypto.randomUUID();
67
+ }
68
+ return `annotation-${Date.now()}-${Math.random().toString(16).slice(2)}`;
69
+ }
70
+ function buildCandidate(root, sources, keyboard) {
71
+ const selection = document.getSelection();
72
+ if (!selection || selection.rangeCount !== 1 || selection.isCollapsed) return null;
73
+ const range = selection.getRangeAt(0);
74
+ const startBoundary = containingSource(range.startContainer);
75
+ const endBoundary = containingSource(range.endContainer);
76
+ if (!startBoundary || startBoundary !== endBoundary || !root.contains(startBoundary)) return null;
77
+ if (isInteractiveSelection(range.startContainer, startBoundary) || isInteractiveSelection(range.endContainer, startBoundary)) {
78
+ return null;
79
+ }
80
+ const sourceKey = startBoundary.dataset.ogAnnotationSourceKey;
81
+ const source = sourceKey ? sources.get(sourceKey) : void 0;
82
+ const quote = selection.toString();
83
+ if (!source || quote.trim().length === 0 || new TextEncoder().encode(quote).byteLength > MAX_QUOTE_BYTES) {
84
+ return null;
85
+ }
86
+ const sourceOffsets = occurrenceOffsets(source.text, quote);
87
+ if (sourceOffsets.length === 0) return null;
88
+ const occurrence = selectedOccurrence(startBoundary, range, quote);
89
+ const startOffset = sourceOffsets[Math.min(occurrence, sourceOffsets.length - 1)];
90
+ const endOffset = startOffset + quote.length;
91
+ const rect = range.getBoundingClientRect();
92
+ if (rect.width === 0 && rect.height === 0) return null;
93
+ return {
94
+ annotation: {
95
+ id: annotationId(),
96
+ quote,
97
+ note: "",
98
+ source: {
99
+ kind: source.kind,
100
+ eventId: source.eventId,
101
+ eventType: source.eventType,
102
+ sequence: source.sequence,
103
+ turnId: source.turnId,
104
+ startOffset,
105
+ endOffset,
106
+ contextBefore: utf8Suffix(source.text.slice(0, startOffset), SOURCE_CONTEXT_BYTES),
107
+ contextAfter: utf8Prefix(source.text.slice(endOffset), SOURCE_CONTEXT_BYTES),
108
+ ...source.label ? { label: source.label } : {}
109
+ }
110
+ },
111
+ left: Math.min(Math.max(12, rect.left + rect.width / 2), window.innerWidth - 12),
112
+ top: rect.bottom + 48 <= window.innerHeight ? rect.bottom + 8 : Math.max(12, rect.top - 40),
113
+ keyboard
114
+ };
115
+ }
116
+ function TimelineAnnotationSelection({
117
+ rootRef,
118
+ sources,
119
+ onAnnotate
120
+ }) {
121
+ const [candidate, setCandidate] = useState(null);
122
+ const buttonRef = useRef(null);
123
+ useEffect(() => {
124
+ const root = rootRef.current;
125
+ if (!root || !onAnnotate) {
126
+ setCandidate(null);
127
+ return;
128
+ }
129
+ const update = (keyboard) => {
130
+ setCandidate(buildCandidate(root, sources, keyboard));
131
+ };
132
+ const onPointerUp = () => window.setTimeout(() => update(false), 0);
133
+ const onKeyUp = (event) => {
134
+ if (event.key === "Escape") {
135
+ setCandidate(null);
136
+ return;
137
+ }
138
+ window.setTimeout(() => update(true), 0);
139
+ };
140
+ const onPointerDown = (event) => {
141
+ if (candidate && !(event.target instanceof Node && buttonRef.current?.contains(event.target))) {
142
+ setCandidate(null);
143
+ }
144
+ };
145
+ const onDocumentKeyDown = (event) => {
146
+ if (event.key === "Escape") setCandidate(null);
147
+ };
148
+ root.addEventListener("pointerup", onPointerUp);
149
+ root.addEventListener("keyup", onKeyUp);
150
+ document.addEventListener("pointerdown", onPointerDown);
151
+ document.addEventListener("keydown", onDocumentKeyDown);
152
+ return () => {
153
+ root.removeEventListener("pointerup", onPointerUp);
154
+ root.removeEventListener("keyup", onKeyUp);
155
+ document.removeEventListener("pointerdown", onPointerDown);
156
+ document.removeEventListener("keydown", onDocumentKeyDown);
157
+ };
158
+ }, [candidate, onAnnotate, rootRef, sources]);
159
+ useEffect(() => {
160
+ if (candidate?.keyboard) buttonRef.current?.focus();
161
+ }, [candidate]);
162
+ if (!candidate || !onAnnotate || typeof document === "undefined") return null;
163
+ return createPortal(
164
+ /* @__PURE__ */ jsx(
165
+ "button",
166
+ {
167
+ ref: buttonRef,
168
+ type: "button",
169
+ style: { left: candidate.left, top: candidate.top },
170
+ className: "og-root fixed z-[80] -translate-x-1/2 rounded-full border border-og-border bg-og-surface-1 px-3 py-1.5 text-og-sm font-medium text-og-fg shadow-lg outline-hidden transition hover:bg-og-surface-2 focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:min-h-[44px]",
171
+ onClick: () => {
172
+ onAnnotate(candidate.annotation);
173
+ document.getSelection()?.removeAllRanges();
174
+ setCandidate(null);
175
+ },
176
+ children: "Annotate"
177
+ }
178
+ ),
179
+ document.body
180
+ );
181
+ }
182
+ var timeline_annotation_selection_default = TimelineAnnotationSelection;
183
+ export {
184
+ TimelineAnnotationSelection,
185
+ timeline_annotation_selection_default as default
186
+ };
187
+ //# sourceMappingURL=timeline-annotation-selection-3L7LHGG2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/timeline-annotation-selection.tsx"],"sourcesContent":["import type { DraftTimelineAnnotation } from \"@opengeni/sdk\";\nimport { useEffect, useRef, useState, type RefObject } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport type { TimelineAnnotationSourceDescriptor } from \"../timeline\";\n\ntype SelectionCandidate = {\n annotation: DraftTimelineAnnotation;\n left: number;\n top: number;\n keyboard: boolean;\n};\n\nconst INTERACTIVE_SELECTOR =\n 'a,button,input,textarea,select,summary,[role=\"button\"],[contenteditable=\"true\"],[tabindex]:not([tabindex=\"-1\"])';\nconst SOURCE_CONTEXT_BYTES = 160;\nconst MAX_QUOTE_BYTES = 16 * 1024;\n\nfunction utf8Prefix(value: string, maxBytes: number): string {\n let output = \"\";\n let bytes = 0;\n for (const character of value) {\n const next = new TextEncoder().encode(character).byteLength;\n if (bytes + next > maxBytes) break;\n output += character;\n bytes += next;\n }\n return output;\n}\n\nfunction utf8Suffix(value: string, maxBytes: number): string {\n let output = \"\";\n let bytes = 0;\n for (const character of [...value].reverse()) {\n const next = new TextEncoder().encode(character).byteLength;\n if (bytes + next > maxBytes) break;\n output = character + output;\n bytes += next;\n }\n return output;\n}\n\nfunction selectionElement(node: Node | null): Element | null {\n return node instanceof Element ? node : (node?.parentElement ?? null);\n}\n\nfunction containingSource(node: Node | null): HTMLElement | null {\n const element = selectionElement(node);\n const source = element?.closest(\"[data-og-annotation-source-key]\");\n return source instanceof HTMLElement ? source : null;\n}\n\nfunction isInteractiveSelection(node: Node | null, boundary: HTMLElement): boolean {\n const element = selectionElement(node);\n const interactive = element?.closest(INTERACTIVE_SELECTOR);\n return interactive instanceof Element && boundary.contains(interactive);\n}\n\nfunction occurrenceOffsets(text: string, quote: string): number[] {\n const offsets: number[] = [];\n let cursor = 0;\n while (cursor <= text.length - quote.length) {\n const offset = text.indexOf(quote, cursor);\n if (offset < 0) break;\n offsets.push(offset);\n cursor = offset + 1;\n }\n return offsets;\n}\n\nfunction selectedOccurrence(boundary: HTMLElement, range: Range, quote: string): number {\n try {\n const prefix = range.cloneRange();\n prefix.selectNodeContents(boundary);\n prefix.setEnd(range.startContainer, range.startOffset);\n return occurrenceOffsets(prefix.toString(), quote).length;\n } catch {\n return 0;\n }\n}\n\nfunction annotationId(): string {\n if (typeof globalThis.crypto?.randomUUID === \"function\") {\n return globalThis.crypto.randomUUID();\n }\n return `annotation-${Date.now()}-${Math.random().toString(16).slice(2)}`;\n}\n\nfunction buildCandidate(\n root: HTMLElement,\n sources: ReadonlyMap<string, TimelineAnnotationSourceDescriptor>,\n keyboard: boolean,\n): SelectionCandidate | null {\n const selection = document.getSelection();\n if (!selection || selection.rangeCount !== 1 || selection.isCollapsed) return null;\n const range = selection.getRangeAt(0);\n const startBoundary = containingSource(range.startContainer);\n const endBoundary = containingSource(range.endContainer);\n if (!startBoundary || startBoundary !== endBoundary || !root.contains(startBoundary)) return null;\n if (\n isInteractiveSelection(range.startContainer, startBoundary) ||\n isInteractiveSelection(range.endContainer, startBoundary)\n ) {\n return null;\n }\n const sourceKey = startBoundary.dataset.ogAnnotationSourceKey;\n const source = sourceKey ? sources.get(sourceKey) : undefined;\n const quote = selection.toString();\n if (\n !source ||\n quote.trim().length === 0 ||\n new TextEncoder().encode(quote).byteLength > MAX_QUOTE_BYTES\n ) {\n return null;\n }\n const sourceOffsets = occurrenceOffsets(source.text, quote);\n if (sourceOffsets.length === 0) return null;\n const occurrence = selectedOccurrence(startBoundary, range, quote);\n const startOffset = sourceOffsets[Math.min(occurrence, sourceOffsets.length - 1)]!;\n const endOffset = startOffset + quote.length;\n const rect = range.getBoundingClientRect();\n if (rect.width === 0 && rect.height === 0) return null;\n return {\n annotation: {\n id: annotationId(),\n quote,\n note: \"\",\n source: {\n kind: source.kind,\n eventId: source.eventId,\n eventType: source.eventType,\n sequence: source.sequence,\n turnId: source.turnId,\n startOffset,\n endOffset,\n contextBefore: utf8Suffix(source.text.slice(0, startOffset), SOURCE_CONTEXT_BYTES),\n contextAfter: utf8Prefix(source.text.slice(endOffset), SOURCE_CONTEXT_BYTES),\n ...(source.label ? { label: source.label } : {}),\n },\n },\n left: Math.min(Math.max(12, rect.left + rect.width / 2), window.innerWidth - 12),\n top: rect.bottom + 48 <= window.innerHeight ? rect.bottom + 8 : Math.max(12, rect.top - 40),\n keyboard,\n };\n}\n\nexport function TimelineAnnotationSelection({\n rootRef,\n sources,\n onAnnotate,\n}: {\n rootRef: RefObject<HTMLElement | null>;\n sources: ReadonlyMap<string, TimelineAnnotationSourceDescriptor>;\n onAnnotate?: ((annotation: DraftTimelineAnnotation) => void) | undefined;\n}) {\n const [candidate, setCandidate] = useState<SelectionCandidate | null>(null);\n const buttonRef = useRef<HTMLButtonElement | null>(null);\n\n useEffect(() => {\n const root = rootRef.current;\n if (!root || !onAnnotate) {\n setCandidate(null);\n return;\n }\n const update = (keyboard: boolean) => {\n setCandidate(buildCandidate(root, sources, keyboard));\n };\n const onPointerUp = () => window.setTimeout(() => update(false), 0);\n const onKeyUp = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n setCandidate(null);\n return;\n }\n window.setTimeout(() => update(true), 0);\n };\n const onPointerDown = (event: PointerEvent) => {\n if (\n candidate &&\n !(event.target instanceof Node && buttonRef.current?.contains(event.target))\n ) {\n setCandidate(null);\n }\n };\n const onDocumentKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") setCandidate(null);\n };\n root.addEventListener(\"pointerup\", onPointerUp);\n root.addEventListener(\"keyup\", onKeyUp);\n document.addEventListener(\"pointerdown\", onPointerDown);\n document.addEventListener(\"keydown\", onDocumentKeyDown);\n return () => {\n root.removeEventListener(\"pointerup\", onPointerUp);\n root.removeEventListener(\"keyup\", onKeyUp);\n document.removeEventListener(\"pointerdown\", onPointerDown);\n document.removeEventListener(\"keydown\", onDocumentKeyDown);\n };\n }, [candidate, onAnnotate, rootRef, sources]);\n\n useEffect(() => {\n if (candidate?.keyboard) buttonRef.current?.focus();\n }, [candidate]);\n\n if (!candidate || !onAnnotate || typeof document === \"undefined\") return null;\n return createPortal(\n <button\n ref={buttonRef}\n type=\"button\"\n style={{ left: candidate.left, top: candidate.top }}\n className=\"og-root fixed z-[80] -translate-x-1/2 rounded-full border border-og-border bg-og-surface-1 px-3 py-1.5 text-og-sm font-medium text-og-fg shadow-lg outline-hidden transition hover:bg-og-surface-2 focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:min-h-[44px]\"\n onClick={() => {\n onAnnotate(candidate.annotation);\n document.getSelection()?.removeAllRanges();\n setCandidate(null);\n }}\n >\n Annotate\n </button>,\n document.body,\n );\n}\n\nexport default TimelineAnnotationSelection;\n"],"mappings":"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","names":[]}
@@ -0,0 +1,196 @@
1
+ // src/components/timeline-annotations-dialog.tsx
2
+ import { useEffect, useLayoutEffect, useRef, useState } from "react";
3
+ import { createPortal } from "react-dom";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ function cssEscapeAttribute(value) {
6
+ if (typeof CSS !== "undefined" && typeof CSS.escape === "function") return CSS.escape(value);
7
+ return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
8
+ }
9
+ function revealLoadedSource(source) {
10
+ if (typeof document === "undefined") return false;
11
+ const element = document.querySelector(
12
+ `[data-og-annotation-source-key="${cssEscapeAttribute(source.eventId)}"]`
13
+ );
14
+ if (!(element instanceof HTMLElement)) return false;
15
+ element.scrollIntoView({ block: "center", behavior: "smooth" });
16
+ element.animate?.(
17
+ [
18
+ { outline: "2px solid color-mix(in srgb, currentColor 55%, transparent)" },
19
+ { outline: "2px solid transparent" }
20
+ ],
21
+ { duration: 1600, easing: "ease-out" }
22
+ );
23
+ return true;
24
+ }
25
+ function sourceLabel(annotation) {
26
+ if (annotation.source.label) return annotation.source.label;
27
+ switch (annotation.source.kind) {
28
+ case "user_message":
29
+ return "User message";
30
+ case "assistant_message":
31
+ return "Assistant message";
32
+ case "tool_output":
33
+ return "Tool output";
34
+ }
35
+ }
36
+ function TimelineAnnotationsDialog({
37
+ annotations,
38
+ editable,
39
+ focusAnnotationId,
40
+ onFocusConsumed,
41
+ onUpdate,
42
+ onRemove,
43
+ onRevealSource,
44
+ triggerRef,
45
+ countLabel,
46
+ onDismiss
47
+ }) {
48
+ const [unavailableId, setUnavailableId] = useState(null);
49
+ const [position, setPosition] = useState({ left: 12, top: 12, above: false });
50
+ const panelRef = useRef(null);
51
+ const noteRefs = useRef(/* @__PURE__ */ new Map());
52
+ useLayoutEffect(() => {
53
+ if (!focusAnnotationId) return;
54
+ const note = noteRefs.current.get(focusAnnotationId);
55
+ note?.focus();
56
+ if (note && document.activeElement === note) onFocusConsumed?.();
57
+ }, [focusAnnotationId, onFocusConsumed]);
58
+ useEffect(() => {
59
+ const updatePosition = () => {
60
+ const rect = triggerRef.current?.getBoundingClientRect();
61
+ if (!rect) return;
62
+ const panelWidth = Math.min(400, window.innerWidth - 24);
63
+ const left = Math.min(
64
+ Math.max(12, rect.left),
65
+ Math.max(12, window.innerWidth - panelWidth - 12)
66
+ );
67
+ const above = rect.top > Math.min(360, window.innerHeight * 0.55);
68
+ setPosition({ left, top: above ? rect.top - 8 : rect.bottom + 8, above });
69
+ };
70
+ const onKeyDown = (event) => {
71
+ if (event.key === "Escape") onDismiss(true);
72
+ };
73
+ const onPointerDown = (event) => {
74
+ if (!(event.target instanceof Node)) return;
75
+ if (panelRef.current?.contains(event.target) || triggerRef.current?.contains(event.target)) {
76
+ return;
77
+ }
78
+ onDismiss(false);
79
+ };
80
+ updatePosition();
81
+ window.addEventListener("resize", updatePosition);
82
+ window.addEventListener("scroll", updatePosition, true);
83
+ document.addEventListener("keydown", onKeyDown);
84
+ document.addEventListener("pointerdown", onPointerDown);
85
+ if (!focusAnnotationId) {
86
+ window.setTimeout(() => {
87
+ if (document.activeElement === triggerRef.current) panelRef.current?.focus();
88
+ }, 0);
89
+ }
90
+ return () => {
91
+ window.removeEventListener("resize", updatePosition);
92
+ window.removeEventListener("scroll", updatePosition, true);
93
+ document.removeEventListener("keydown", onKeyDown);
94
+ document.removeEventListener("pointerdown", onPointerDown);
95
+ };
96
+ }, [focusAnnotationId, onDismiss, triggerRef]);
97
+ if (typeof document === "undefined") return null;
98
+ return createPortal(
99
+ /* @__PURE__ */ jsxs(
100
+ "div",
101
+ {
102
+ ref: panelRef,
103
+ role: "dialog",
104
+ tabIndex: -1,
105
+ style: {
106
+ left: position.left,
107
+ top: position.top,
108
+ transform: position.above ? "translateY(-100%)" : void 0
109
+ },
110
+ className: "og-root fixed z-[75] box-border max-h-[min(32rem,70vh)] w-[min(25rem,calc(100vw-1.5rem))] overflow-y-auto rounded-og-lg border border-og-border bg-og-surface-1 p-3 text-og-fg shadow-xl outline-hidden",
111
+ "aria-label": editable ? "Review timeline annotations" : "Timeline annotations",
112
+ children: [
113
+ /* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center justify-between gap-3", children: [
114
+ /* @__PURE__ */ jsxs("div", { children: [
115
+ /* @__PURE__ */ jsx("p", { className: "text-og-sm font-semibold", children: countLabel }),
116
+ /* @__PURE__ */ jsx("p", { className: "text-og-xs text-og-fg-subtle", children: editable ? "Add a note for each quoted source." : "Sent with this message." })
117
+ ] }),
118
+ /* @__PURE__ */ jsx(
119
+ "button",
120
+ {
121
+ type: "button",
122
+ className: "rounded-md border-0 bg-transparent px-2 py-1 text-og-xs text-og-fg outline-hidden hover:bg-og-surface-2 focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:min-h-[44px]",
123
+ onClick: () => onDismiss(true),
124
+ children: "Close"
125
+ }
126
+ )
127
+ ] }),
128
+ /* @__PURE__ */ jsx("div", { className: "grid gap-2.5", children: annotations.map((annotation, index) => /* @__PURE__ */ jsxs(
129
+ "section",
130
+ {
131
+ className: "rounded-og-md border border-og-border bg-og-surface-2/60 p-2.5",
132
+ "aria-label": `Annotation ${index + 1}`,
133
+ children: [
134
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
135
+ /* @__PURE__ */ jsxs(
136
+ "button",
137
+ {
138
+ type: "button",
139
+ className: "truncate rounded border-0 bg-transparent text-left text-og-xs font-medium text-og-fg-muted underline-offset-2 outline-hidden hover:text-og-fg hover:underline focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:min-h-[44px]",
140
+ onClick: () => {
141
+ const revealed = onRevealSource?.(annotation.source) ?? revealLoadedSource(annotation.source);
142
+ setUnavailableId(revealed ? null : annotation.id);
143
+ },
144
+ children: [
145
+ sourceLabel(annotation),
146
+ " \xB7 view source"
147
+ ]
148
+ }
149
+ ),
150
+ editable && onRemove ? /* @__PURE__ */ jsx(
151
+ "button",
152
+ {
153
+ type: "button",
154
+ className: "shrink-0 rounded border-0 bg-transparent p-1 text-og-fg-subtle outline-hidden hover:bg-og-surface-1 hover:text-og-status-failed focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:size-[44px]",
155
+ "aria-label": `Remove annotation ${index + 1}`,
156
+ onClick: () => onRemove(annotation.id),
157
+ children: /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "text-og-md leading-none", children: "\xD7" })
158
+ }
159
+ ) : null
160
+ ] }),
161
+ unavailableId === annotation.id ? /* @__PURE__ */ jsx("p", { role: "status", className: "mt-1 text-og-xs text-og-status-waiting", children: "Source is outside the loaded timeline window." }) : null,
162
+ /* @__PURE__ */ jsx("blockquote", { className: "mt-2 max-h-28 overflow-auto whitespace-pre-wrap border-l-2 border-og-border pl-2 text-og-sm leading-5 text-og-fg-muted", children: annotation.quote }),
163
+ editable && onUpdate ? /* @__PURE__ */ jsxs("label", { className: "mt-2 block text-og-xs font-medium text-og-fg-muted", children: [
164
+ "Note",
165
+ /* @__PURE__ */ jsx(
166
+ "textarea",
167
+ {
168
+ ref: (node) => {
169
+ if (node) noteRefs.current.set(annotation.id, node);
170
+ else noteRefs.current.delete(annotation.id);
171
+ },
172
+ value: annotation.note,
173
+ rows: 2,
174
+ maxLength: 2048,
175
+ placeholder: "What should the agent do with this?",
176
+ className: "mt-1 w-full resize-y rounded-og-sm border border-og-border bg-og-surface-1 px-2.5 py-2 text-og-sm leading-5 text-og-fg outline-hidden placeholder:text-og-fg-subtle focus:border-og-accent focus:ring-1 focus:ring-og-accent",
177
+ onInput: (event) => onUpdate(annotation.id, event.currentTarget.value)
178
+ }
179
+ )
180
+ ] }) : annotation.note ? /* @__PURE__ */ jsx("p", { className: "mt-2 whitespace-pre-wrap text-og-sm leading-5 text-og-fg", children: annotation.note }) : null
181
+ ]
182
+ },
183
+ annotation.id
184
+ )) })
185
+ ]
186
+ }
187
+ ),
188
+ document.body
189
+ );
190
+ }
191
+ var timeline_annotations_dialog_default = TimelineAnnotationsDialog;
192
+ export {
193
+ TimelineAnnotationsDialog,
194
+ timeline_annotations_dialog_default as default
195
+ };
196
+ //# sourceMappingURL=timeline-annotations-dialog-U7EVLR75.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/timeline-annotations-dialog.tsx"],"sourcesContent":["import type { TimelineAnnotationSource } from \"@opengeni/sdk\";\nimport { useEffect, useLayoutEffect, useRef, useState, type RefObject } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport type { TimelineAnnotationLike } from \"./timeline-annotations\";\n\nfunction cssEscapeAttribute(value: string): string {\n if (typeof CSS !== \"undefined\" && typeof CSS.escape === \"function\") return CSS.escape(value);\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n}\n\nfunction revealLoadedSource(source: TimelineAnnotationSource): boolean {\n if (typeof document === \"undefined\") return false;\n const element = document.querySelector(\n `[data-og-annotation-source-key=\"${cssEscapeAttribute(source.eventId)}\"]`,\n );\n if (!(element instanceof HTMLElement)) return false;\n element.scrollIntoView({ block: \"center\", behavior: \"smooth\" });\n element.animate?.(\n [\n { outline: \"2px solid color-mix(in srgb, currentColor 55%, transparent)\" },\n { outline: \"2px solid transparent\" },\n ],\n { duration: 1600, easing: \"ease-out\" },\n );\n return true;\n}\n\nfunction sourceLabel(annotation: TimelineAnnotationLike): string {\n if (annotation.source.label) return annotation.source.label;\n switch (annotation.source.kind) {\n case \"user_message\":\n return \"User message\";\n case \"assistant_message\":\n return \"Assistant message\";\n case \"tool_output\":\n return \"Tool output\";\n }\n}\n\nexport function TimelineAnnotationsDialog({\n annotations,\n editable,\n focusAnnotationId,\n onFocusConsumed,\n onUpdate,\n onRemove,\n onRevealSource,\n triggerRef,\n countLabel,\n onDismiss,\n}: {\n annotations: readonly TimelineAnnotationLike[];\n editable: boolean;\n focusAnnotationId?: string | null | undefined;\n onFocusConsumed?: (() => void) | undefined;\n onUpdate?: ((id: string, note: string) => void) | undefined;\n onRemove?: ((id: string) => void) | undefined;\n onRevealSource?: ((source: TimelineAnnotationSource) => boolean) | undefined;\n triggerRef: RefObject<HTMLButtonElement | null>;\n countLabel: string;\n onDismiss: (restoreFocus: boolean) => void;\n}) {\n const [unavailableId, setUnavailableId] = useState<string | null>(null);\n const [position, setPosition] = useState({ left: 12, top: 12, above: false });\n const panelRef = useRef<HTMLDivElement | null>(null);\n const noteRefs = useRef(new Map<string, HTMLTextAreaElement>());\n\n useLayoutEffect(() => {\n if (!focusAnnotationId) return;\n const note = noteRefs.current.get(focusAnnotationId);\n note?.focus();\n if (note && document.activeElement === note) onFocusConsumed?.();\n }, [focusAnnotationId, onFocusConsumed]);\n\n useEffect(() => {\n const updatePosition = () => {\n const rect = triggerRef.current?.getBoundingClientRect();\n if (!rect) return;\n const panelWidth = Math.min(400, window.innerWidth - 24);\n const left = Math.min(\n Math.max(12, rect.left),\n Math.max(12, window.innerWidth - panelWidth - 12),\n );\n const above = rect.top > Math.min(360, window.innerHeight * 0.55);\n setPosition({ left, top: above ? rect.top - 8 : rect.bottom + 8, above });\n };\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") onDismiss(true);\n };\n const onPointerDown = (event: PointerEvent) => {\n if (!(event.target instanceof Node)) return;\n if (panelRef.current?.contains(event.target) || triggerRef.current?.contains(event.target)) {\n return;\n }\n onDismiss(false);\n };\n updatePosition();\n window.addEventListener(\"resize\", updatePosition);\n window.addEventListener(\"scroll\", updatePosition, true);\n document.addEventListener(\"keydown\", onKeyDown);\n document.addEventListener(\"pointerdown\", onPointerDown);\n if (!focusAnnotationId) {\n window.setTimeout(() => {\n if (document.activeElement === triggerRef.current) panelRef.current?.focus();\n }, 0);\n }\n return () => {\n window.removeEventListener(\"resize\", updatePosition);\n window.removeEventListener(\"scroll\", updatePosition, true);\n document.removeEventListener(\"keydown\", onKeyDown);\n document.removeEventListener(\"pointerdown\", onPointerDown);\n };\n }, [focusAnnotationId, onDismiss, triggerRef]);\n\n if (typeof document === \"undefined\") return null;\n return createPortal(\n <div\n ref={panelRef}\n role=\"dialog\"\n tabIndex={-1}\n style={{\n left: position.left,\n top: position.top,\n transform: position.above ? \"translateY(-100%)\" : undefined,\n }}\n className=\"og-root fixed z-[75] box-border max-h-[min(32rem,70vh)] w-[min(25rem,calc(100vw-1.5rem))] overflow-y-auto rounded-og-lg border border-og-border bg-og-surface-1 p-3 text-og-fg shadow-xl outline-hidden\"\n aria-label={editable ? \"Review timeline annotations\" : \"Timeline annotations\"}\n >\n <div className=\"mb-2 flex items-center justify-between gap-3\">\n <div>\n <p className=\"text-og-sm font-semibold\">{countLabel}</p>\n <p className=\"text-og-xs text-og-fg-subtle\">\n {editable ? \"Add a note for each quoted source.\" : \"Sent with this message.\"}\n </p>\n </div>\n <button\n type=\"button\"\n className=\"rounded-md border-0 bg-transparent px-2 py-1 text-og-xs text-og-fg outline-hidden hover:bg-og-surface-2 focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:min-h-[44px]\"\n onClick={() => onDismiss(true)}\n >\n Close\n </button>\n </div>\n <div className=\"grid gap-2.5\">\n {annotations.map((annotation, index) => (\n <section\n key={annotation.id}\n className=\"rounded-og-md border border-og-border bg-og-surface-2/60 p-2.5\"\n aria-label={`Annotation ${index + 1}`}\n >\n <div className=\"flex items-center justify-between gap-2\">\n <button\n type=\"button\"\n className=\"truncate rounded border-0 bg-transparent text-left text-og-xs font-medium text-og-fg-muted underline-offset-2 outline-hidden hover:text-og-fg hover:underline focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:min-h-[44px]\"\n onClick={() => {\n const revealed =\n onRevealSource?.(annotation.source) ?? revealLoadedSource(annotation.source);\n setUnavailableId(revealed ? null : annotation.id);\n }}\n >\n {sourceLabel(annotation)} · view source\n </button>\n {editable && onRemove ? (\n <button\n type=\"button\"\n className=\"shrink-0 rounded border-0 bg-transparent p-1 text-og-fg-subtle outline-hidden hover:bg-og-surface-1 hover:text-og-status-failed focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:size-[44px]\"\n aria-label={`Remove annotation ${index + 1}`}\n onClick={() => onRemove(annotation.id)}\n >\n <span aria-hidden=\"true\" className=\"text-og-md leading-none\">\n ×\n </span>\n </button>\n ) : null}\n </div>\n {unavailableId === annotation.id ? (\n <p role=\"status\" className=\"mt-1 text-og-xs text-og-status-waiting\">\n Source is outside the loaded timeline window.\n </p>\n ) : null}\n <blockquote className=\"mt-2 max-h-28 overflow-auto whitespace-pre-wrap border-l-2 border-og-border pl-2 text-og-sm leading-5 text-og-fg-muted\">\n {annotation.quote}\n </blockquote>\n {editable && onUpdate ? (\n <label className=\"mt-2 block text-og-xs font-medium text-og-fg-muted\">\n Note\n <textarea\n ref={(node) => {\n if (node) noteRefs.current.set(annotation.id, node);\n else noteRefs.current.delete(annotation.id);\n }}\n value={annotation.note}\n rows={2}\n maxLength={2048}\n placeholder=\"What should the agent do with this?\"\n className=\"mt-1 w-full resize-y rounded-og-sm border border-og-border bg-og-surface-1 px-2.5 py-2 text-og-sm leading-5 text-og-fg outline-hidden placeholder:text-og-fg-subtle focus:border-og-accent focus:ring-1 focus:ring-og-accent\"\n onInput={(event) => onUpdate(annotation.id, event.currentTarget.value)}\n />\n </label>\n ) : annotation.note ? (\n <p className=\"mt-2 whitespace-pre-wrap text-og-sm leading-5 text-og-fg\">\n {annotation.note}\n </p>\n ) : null}\n </section>\n ))}\n </div>\n </div>,\n document.body,\n );\n}\n\nexport default TimelineAnnotationsDialog;\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeni/react",
3
- "version": "0.48.0",
3
+ "version": "0.52.1",
4
4
  "description": "React hooks and styled components for OpenGeni: live session streaming, chat composer, message timeline, session status, and fleet views — token-themed (CSS variables), dark-first, built on Tailwind v4 + Radix + Motion.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -43,31 +43,56 @@
43
43
  },
44
44
  "./model-policy": {
45
45
  "types": "./dist/model-policy.d.ts",
46
- "import": "./dist/model-policy.js"
46
+ "import": "./dist/model-policy.js",
47
+ "default": "./dist/model-policy.js"
47
48
  },
48
49
  "./realtime": {
49
50
  "types": "./dist/realtime.d.ts",
50
51
  "import": "./dist/realtime.js"
51
52
  },
53
+ "./artifacts": {
54
+ "types": "./dist/artifacts.d.ts",
55
+ "import": "./dist/artifacts.js"
56
+ },
57
+ "./artifacts/spreadsheet": {
58
+ "types": "./dist/artifacts-spreadsheet.d.ts",
59
+ "import": "./dist/artifacts-spreadsheet.js"
60
+ },
61
+ "./artifacts/document": {
62
+ "types": "./dist/artifacts-document.d.ts",
63
+ "import": "./dist/artifacts-document.js"
64
+ },
65
+ "./artifacts/presentation": {
66
+ "types": "./dist/artifacts-presentation.d.ts",
67
+ "import": "./dist/artifacts-presentation.js"
68
+ },
69
+ "./interaction": {
70
+ "types": "./dist/interaction.d.ts",
71
+ "import": "./dist/interaction.js"
72
+ },
73
+ "./clipboard": {
74
+ "types": "./dist/clipboard.d.ts",
75
+ "import": "./dist/clipboard.js"
76
+ },
52
77
  "./styles.css": {
53
78
  "types": "./styles/index.d.ts",
54
79
  "style": "./styles/index.css",
55
- "import": "./styles/index.css"
80
+ "default": "./styles/index.css"
56
81
  },
57
82
  "./compiled.css": {
58
83
  "types": "./styles/compiled.d.ts",
59
84
  "style": "./styles/compiled.css",
60
- "import": "./styles/compiled.css"
85
+ "default": "./styles/compiled.css"
61
86
  },
62
87
  "./responsive.css": {
63
88
  "types": "./styles/responsive.d.ts",
64
89
  "style": "./styles/responsive.css",
65
- "import": "./styles/responsive.css"
90
+ "default": "./styles/responsive.css"
66
91
  },
67
92
  "./tokens.css": {
68
93
  "types": "./styles/tokens.d.ts",
69
94
  "style": "./styles/tokens.css",
70
- "import": "./styles/tokens.css"
95
+ "default": "./styles/tokens.css"
71
96
  }
72
97
  },
73
98
  "publishConfig": {
@@ -91,7 +116,7 @@
91
116
  "@dnd-kit/utilities": "3.2.2",
92
117
  "@fontsource-variable/noto-sans-arabic": "5.2.10",
93
118
  "@fontsource-variable/noto-sans-jp": "5.2.10",
94
- "@opengeni/sdk": "^0.48.0",
119
+ "@opengeni/sdk": "^0.52.1",
95
120
  "clsx": "^2.1.1",
96
121
  "lucide-react": "^1.8.0",
97
122
  "motion": "^12.0.0",
@@ -110,6 +135,7 @@
110
135
  "@codemirror/lang-markdown": "^6.0.0",
111
136
  "@codemirror/lang-python": "^6.0.0",
112
137
  "@novnc/novnc": "^1.7.0",
138
+ "@opengeni/artifact-tool": ">=0.1.0 <0.3.0",
113
139
  "@pierre/diffs": "^1.2.11",
114
140
  "@uiw/react-codemirror": "^4.23.0",
115
141
  "@xterm/addon-fit": "^0.11.0",
@@ -141,6 +167,9 @@
141
167
  "@novnc/novnc": {
142
168
  "optional": true
143
169
  },
170
+ "@opengeni/artifact-tool": {
171
+ "optional": true
172
+ },
144
173
  "@pierre/diffs": {
145
174
  "optional": true
146
175
  },