@opengeni/react 2.5.0-canary.1 → 3.0.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 (70) hide show
  1. package/README.md +15 -0
  2. package/dist/accounts.d.ts +64 -0
  3. package/dist/accounts.js +746 -0
  4. package/dist/accounts.js.map +1 -0
  5. package/dist/{browser-viewer-GXUICIAG.js → browser-viewer-AEFHUYZK.js} +3 -3
  6. package/dist/{chunk-MXJGO7LE.js → chunk-D3UIAJKY.js} +52 -2
  7. package/dist/chunk-D3UIAJKY.js.map +1 -0
  8. package/dist/{chunk-QGBJ6GHG.js → chunk-ELIYWBZR.js} +4 -4
  9. package/dist/{chunk-6H6S5V4Z.js → chunk-HQVCKCLG.js} +758 -871
  10. package/dist/chunk-HQVCKCLG.js.map +1 -0
  11. package/dist/{chunk-T7VAYG2I.js → chunk-MZ2G2XBA.js} +54 -2
  12. package/dist/chunk-MZ2G2XBA.js.map +1 -0
  13. package/dist/{chunk-X4JAFD5R.js → chunk-OAM4WAAM.js} +4 -4
  14. package/dist/{chunk-KSDXER4X.js → chunk-RGALCTWO.js} +64 -15
  15. package/dist/chunk-RGALCTWO.js.map +1 -0
  16. package/dist/chunk-YFKJ7VZH.js +268 -0
  17. package/dist/chunk-YFKJ7VZH.js.map +1 -0
  18. package/dist/{chunk-ATQJEWCA.js → chunk-YJFGAFBD.js} +124 -50
  19. package/dist/chunk-YJFGAFBD.js.map +1 -0
  20. package/dist/components/composer.d.ts +8 -0
  21. package/dist/components/file-browser.d.ts +4 -1
  22. package/dist/components/sandbox-files.d.ts +4 -1
  23. package/dist/components/sandbox-workspace.d.ts +5 -0
  24. package/dist/composer.js +3 -3
  25. package/dist/{computer-viewer-ZOP4Q7A7.js → computer-viewer-FWEZISW4.js} +3 -3
  26. package/dist/embedded-session-client.d.ts +23 -0
  27. package/dist/file-node-visibility.d.ts +15 -0
  28. package/dist/hooks/use-file-attachments.d.ts +9 -2
  29. package/dist/human-input.d.ts +3 -1
  30. package/dist/index.d.ts +5 -1
  31. package/dist/index.js +139 -53
  32. package/dist/index.js.map +1 -1
  33. package/dist/interaction.js +3 -3
  34. package/dist/session-ui.js +4 -4
  35. package/dist/session.d.ts +2 -0
  36. package/dist/session.js +7 -5
  37. package/dist/timeline/index.d.ts +1 -0
  38. package/dist/timeline/screenshot-lightbox.d.ts +16 -1
  39. package/package.json +6 -2
  40. package/src/accounts.tsx +970 -0
  41. package/src/components/chat-composer.tsx +88 -84
  42. package/src/components/composer.tsx +61 -9
  43. package/src/components/file-browser.tsx +33 -20
  44. package/src/components/human-input-surface.tsx +10 -6
  45. package/src/components/message-timeline.tsx +37 -9
  46. package/src/components/sandbox-files.tsx +42 -2
  47. package/src/components/sandbox-workspace.tsx +10 -0
  48. package/src/embedded-session-client.ts +104 -0
  49. package/src/file-node-visibility.ts +66 -0
  50. package/src/hooks/use-composer.ts +64 -2
  51. package/src/hooks/use-file-attachments.ts +38 -6
  52. package/src/hooks/use-human-input.ts +31 -4
  53. package/src/human-input.ts +12 -1
  54. package/src/index.ts +12 -0
  55. package/src/session.ts +5 -0
  56. package/src/timeline/index.ts +1 -0
  57. package/src/timeline/screenshot-lightbox.tsx +93 -29
  58. package/styles/compiled.css +11 -1
  59. package/styles/tokens.css +3 -1
  60. package/dist/chunk-6H6S5V4Z.js.map +0 -1
  61. package/dist/chunk-ATQJEWCA.js.map +0 -1
  62. package/dist/chunk-FK6VG4LL.js +0 -90
  63. package/dist/chunk-FK6VG4LL.js.map +0 -1
  64. package/dist/chunk-KSDXER4X.js.map +0 -1
  65. package/dist/chunk-MXJGO7LE.js.map +0 -1
  66. package/dist/chunk-T7VAYG2I.js.map +0 -1
  67. /package/dist/{browser-viewer-GXUICIAG.js.map → browser-viewer-AEFHUYZK.js.map} +0 -0
  68. /package/dist/{chunk-QGBJ6GHG.js.map → chunk-ELIYWBZR.js.map} +0 -0
  69. /package/dist/{chunk-X4JAFD5R.js.map → chunk-OAM4WAAM.js.map} +0 -0
  70. /package/dist/{computer-viewer-ZOP4Q7A7.js.map → computer-viewer-FWEZISW4.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/hooks/use-session.ts","../src/hooks/use-session-events.ts","../src/hooks/use-file-attachments.ts","../src/hooks/use-turn-queue.ts","../src/hooks/use-goal.ts","../src/hooks/use-session-control.ts","../src/hooks/use-session-mcp-approval-policy.ts","../src/hooks/use-session-lineage.ts","../src/approvals.ts","../src/human-input.ts","../src/hooks/use-human-input.ts"],"sourcesContent":["import type { Session, SessionEvent } from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useEmbeddedSessionRead, type EmbeddedSessionReadClientOverride } from \"../session-context\";\nimport {\n useMutationRunner,\n usePolledValue,\n useSessionEventTrigger,\n type SessionEventFeedOptions,\n} from \"./internal\";\n\nexport type UseSessionOptions = EmbeddedSessionReadClientOverride &\n SessionEventFeedOptions & {\n /** Re-fetch on an interval (ms). Off by default — pair with `useSessionEvents` for live status. */\n pollIntervalMs?: number | undefined;\n /** Optional shared causal clock invoked when each network read starts. */\n beginRead?: (() => number) | undefined;\n };\n\nexport type UseSessionResult = {\n session: Session | null;\n loading: boolean;\n error: Error | null;\n /** Monotonic revision of accepted authoritative detail reads. */\n readRevision: number;\n /** Causal generation captured when the accepted network read started. */\n readGeneration: number;\n refresh: () => Promise<void>;\n /** Manually rename the session (PATCH, source='user'). Returns the updated session, or null on failure. */\n updateTitle: (title: string) => Promise<Session | null>;\n /** True while a rename is in flight. */\n updating: boolean;\n mutationError: Error | null;\n clearMutationError: () => void;\n};\n\n/** Event types that change the session title (auto + cross-client renames). */\nexport function isTitleEvent(event: Pick<SessionEvent, \"type\">): boolean {\n return event.type === \"session.title_set\";\n}\n\n/** Fetch one session (with optional polling), live-patching its title on `session.title_set`. */\nexport function useSession(\n sessionId: string | null | undefined,\n options: UseSessionOptions = {},\n): UseSessionResult {\n const { client, workspaceId, workspaceControlEvent, registerSessionReconciler } =\n useEmbeddedSessionRead(options);\n const enabled = (options.enabled ?? true) && Boolean(sessionId);\n const [override, setOverride] = useState<Session | null>(null);\n const nextReadRevision = useRef(0);\n const nextReadGeneration = useRef(0);\n const beginRead = options.beginRead;\n const { run, mutating, mutationError, clearMutationError } = useMutationRunner();\n const load = useCallback(async () => {\n if (!sessionId) {\n return null;\n }\n let readGeneration = 0;\n const fetched = await client.getSession(workspaceId, sessionId, {\n fresh: true,\n onRequestStart: () => {\n readGeneration = beginRead?.() ?? ++nextReadGeneration.current;\n },\n });\n // A fresh server read supersedes any optimistic/event-driven override.\n setOverride(null);\n return {\n session: fetched,\n revision: ++nextReadRevision.current,\n readGeneration,\n };\n }, [beginRead, client, workspaceId, sessionId]);\n const { data, loading, error, refresh } = usePolledValue(load, {\n pollIntervalMs: options.pollIntervalMs,\n enabled,\n });\n useEffect(() => {\n if (enabled && workspaceControlEvent) void refresh();\n }, [enabled, refresh, workspaceControlEvent]);\n useEffect(() => {\n if (!sessionId || !enabled) return;\n return registerSessionReconciler(sessionId, \"session\", refresh);\n }, [enabled, refresh, registerSessionReconciler, sessionId]);\n\n const base = data?.session ?? null;\n const readRevision = data?.revision ?? 0;\n const readGeneration = data?.readGeneration ?? 0;\n // The override only ever carries title/titleSource patches; it is reset on\n // every fresh load so it can never go stale against the server snapshot.\n const session = useMemo(\n () =>\n base && override && override.id === base.id\n ? { ...base, title: override.title, titleSource: override.titleSource }\n : base,\n [base, override],\n );\n\n // Live-patch the title on auto (agent) + cross-client (user/agent) renames so\n // the UI reflects the new title without polling or a full re-fetch.\n const onTitleEvent = useCallback(\n (event: SessionEvent) => {\n // The fetched session row is the authoritative title projection through\n // lastSequence. Shared feeds may replay that historical tail after the\n // fetch; applying it would undo a row-only migration quarantine. Only an\n // event committed after this snapshot may live-patch the title.\n if (!base || event.sequence <= base.lastSequence) {\n return;\n }\n const payload = (event.payload ?? {}) as { title?: unknown; source?: unknown };\n const title = payload.title;\n if (typeof title !== \"string\") {\n return;\n }\n const source: \"user\" | \"agent\" | null =\n payload.source === \"user\" || payload.source === \"agent\" ? payload.source : null;\n setOverride((current): Session | null => {\n const next = current ?? base;\n return { ...next, title, titleSource: source };\n });\n },\n [base],\n );\n useSessionEventTrigger(client, workspaceId, sessionId, isTitleEvent, onTitleEvent, {\n enabled,\n ...(options.events !== undefined ? { events: options.events } : {}),\n });\n\n const updateTitle = useCallback(\n async (title: string): Promise<Session | null> => {\n if (!sessionId) {\n return null;\n }\n const result = await run(() => client.updateSession(workspaceId, sessionId, { title }));\n if (result) {\n setOverride(result);\n }\n return result;\n },\n [client, workspaceId, sessionId, run],\n );\n\n return {\n session,\n loading,\n error,\n readRevision,\n readGeneration,\n refresh,\n updateTitle,\n updating: mutating,\n mutationError,\n clearMutationError,\n };\n}\n","import type { SessionEvent, SessionStatus, StreamConnectionState } from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useEmbeddedSession, type EmbeddedSessionClientOverride } from \"../session-context\";\nimport { createOlderHistoryLoadReceipt, type OlderHistoryLoadReceipt } from \"../older-history\";\nimport { buildTimeline, groupTimeline, sessionStatusFromEvents } from \"../timeline/projection\";\nimport type { TimelineItem } from \"../timeline/types\";\nimport type { EmbeddedSessionClientLike } from \"../client\";\nimport { usePageLiveActivity } from \"./internal\";\n\nexport type SessionEventsConnectionState = StreamConnectionState | \"idle\" | \"ended\" | \"error\";\n\nexport type UseSessionEventsOptions = EmbeddedSessionClientOverride & {\n /** Resume after this sequence (exclusive). Nonzero keeps full replay/resume semantics. */\n after?: number | undefined;\n /** Load a bounded tail by default, or opt back into full replay from `after`. */\n replay?: \"windowed\" | \"full\" | undefined;\n /** Pause the stream without unmounting (e.g. hidden tab). Defaults to true. */\n enabled?: boolean | undefined;\n};\n\nexport type UseSessionEventsResult = {\n /** Replayed + live events, ordered by sequence, no gaps, no duplicates. */\n events: SessionEvent[];\n /** Projected, renderable timeline (memoized over `events`). */\n timeline: TimelineItem[];\n /** Latest session status observed in the event log, if any. */\n sessionStatus: SessionStatus | null;\n connectionState: SessionEventsConnectionState;\n /** Highest sequence seen so far (0 before the first event). */\n lastSequence: number;\n /** Exact serialized bytes retained in the current browser event window. */\n windowBytes: number;\n /** Whether older delivered events were evicted from the browser window. */\n windowTruncated: boolean;\n /** True until the initial tail window has been applied (windowed mode). */\n initialLoading: boolean;\n /** Whether older durable events are available before the current window. */\n hasOlder: boolean;\n /** True while an older window is being fetched. */\n loadingOlder: boolean;\n /** Prepend an older density-bounded window; resolves true when more remain. */\n loadOlder: () => OlderHistoryLoadReceipt;\n /**\n * Durable events exist after the current window (history view jumped away\n * from the live tip, or a forward page is incomplete).\n */\n hasNewer: boolean;\n /** True while a newer history page is being fetched. */\n loadingNewer: boolean;\n /**\n * Append one density-bounded newer page without pulling the whole gap.\n * Resolves true when more newer history remains.\n */\n loadNewer: () => Promise<boolean>;\n /** True while replacing the window with the session start. */\n loadingOldest: boolean;\n /**\n * Jump to the durable session start: one bounded oldest window, no middle.\n * Leaves live streaming until {@link jumpToLatest} (or loadNewer catches up).\n */\n loadOldest: () => Promise<boolean>;\n /** True while reloading the live tip window. */\n loadingLatest: boolean;\n /**\n * Reload the newest bounded tip and resume live streaming. Use for\n * \"Jump to latest\" when the tip is not in memory (history view).\n */\n jumpToLatest: () => Promise<void>;\n error: Error | null;\n};\n\nconst INITIAL_TAIL_PAGE_SIZE = 1000;\nconst OLDER_PAGE_SIZE = 5000;\nconst NEWER_PAGE_SIZE = 5000;\nconst OLDEST_PAGE_SIZE = 1000;\nconst INITIAL_FETCH_CAP = 1;\nconst OLDER_GROUP_TARGET = 32;\nconst OLDER_FETCH_CAP = 2;\nconst NEWER_GROUP_TARGET = 32;\nconst NEWER_FETCH_CAP = 2;\nconst OLDEST_GROUP_TARGET = 32;\nconst OLDEST_FETCH_CAP = 2;\nconst BOUNDARY_PAGE_CAP = 4;\nconst EMPTY_EVENTS: SessionEvent[] = [];\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\nconst BROWSER_EVENT_TYPE_MAX_BYTES = 256;\nconst BROWSER_EVENT_ID_MAX_BYTES = 256;\nconst BROWSER_EVENT_CLIENT_ID_MAX_BYTES = 4 * 1024;\nconst BROWSER_EVENT_DUPLICATE_REASON_MAX_BYTES = 4 * 1024;\nconst BROWSER_EVENT_PAYLOAD_PREVIEW_MAX_BYTES = 48 * 1024;\nconst BROWSER_EVENT_PAYLOAD_IDENTITY_FIELDS = [\n \"id\",\n \"callId\",\n \"call_id\",\n \"name\",\n \"toolName\",\n \"status\",\n \"code\",\n \"isError\",\n \"stream\",\n \"commandId\",\n \"sequence\",\n \"coalescedUntil\",\n \"coalescedCount\",\n \"firstSequence\",\n \"lastSequence\",\n] as const;\n\nexport const SESSION_EVENT_BROWSER_MAX_BYTES = 8 * 1024 * 1024;\nexport const SESSION_EVENT_BROWSER_MAX_COUNT = 10_000;\nexport const SESSION_EVENT_BROWSER_SINGLE_EVENT_MAX_BYTES = 96 * 1024;\nexport const SESSION_EVENT_BROWSER_PENDING_MAX_BYTES = 1024 * 1024;\nexport const SESSION_EVENT_BROWSER_PENDING_MAX_COUNT = 256;\n\nexport type BrowserSessionEventWindow = {\n events: SessionEvent[];\n bytes: number;\n truncated: boolean;\n};\n\nconst EMPTY_EVENT_WINDOW: BrowserSessionEventWindow = {\n events: EMPTY_EVENTS,\n bytes: 2,\n truncated: false,\n};\n\n/**\n * Live-stream a session's event log with replay-by-sequence, reconnect, and\n * batched React updates. Fresh loads default to a bounded tail window; pass\n * `replay: \"full\"` or a nonzero `after` for the previous full replay path.\n */\nexport function useSessionEvents(\n sessionId: string | null | undefined,\n options: UseSessionEventsOptions = {},\n): UseSessionEventsResult {\n const { client, workspaceId, reconcileSession } = useEmbeddedSession(options);\n const enabled = options.enabled ?? true;\n const pageLive = usePageLiveActivity();\n const streamEnabled = enabled && pageLive;\n const after = options.after ?? 0;\n const replay = options.replay ?? \"windowed\";\n const fullReplay = replay === \"full\" || after !== 0;\n const streamKey = `${workspaceId}\\u0000${sessionId ?? \"\"}\\u0000${after}\\u0000${fullReplay ? \"full\" : \"windowed\"}`;\n\n const [eventWindow, setEventWindow] = useState<BrowserSessionEventWindow>(EMPTY_EVENT_WINDOW);\n const [connectionState, setConnectionState] = useState<SessionEventsConnectionState>(\"idle\");\n const [error, setError] = useState<Error | null>(null);\n const [hasOlder, setHasOlder] = useState(false);\n const [hasNewer, setHasNewer] = useState(false);\n const [sessionStatusProjection, setSessionStatusProjection] = useState<SessionStatus | null>(\n null,\n );\n const [initialLoading, setInitialLoading] = useState(true);\n const [loadingOlder, setLoadingOlder] = useState(false);\n const [loadingNewer, setLoadingNewer] = useState(false);\n const [loadingOldest, setLoadingOldest] = useState(false);\n const [loadingLatest, setLoadingLatest] = useState(false);\n const [streamEpoch, setStreamEpoch] = useState(0);\n // \"history\" = reading a non-tip window; live SSE must not fill the gap.\n const [viewMode, setViewMode] = useState<\"live\" | \"history\">(\"live\");\n const lastSequenceRef = useRef(after);\n const streamResumeSequenceRef = useRef(after);\n const oldestSequenceRef = useRef<number | null>(null);\n const newestSequenceRef = useRef<number | null>(null);\n const hasOlderRef = useRef(false);\n const hasNewerRef = useRef(false);\n const loadingOlderRef = useRef(false);\n const loadingNewerRef = useRef(false);\n const loadingOldestRef = useRef(false);\n const loadingLatestRef = useRef(false);\n const viewModeRef = useRef<\"live\" | \"history\">(\"live\");\n const initialWindowLoadedRef = useRef(false);\n const streamAbortRef = useRef<AbortController | null>(null);\n const streamKeyRef = useRef<string | null>(null);\n const generationRef = useRef(0);\n const eventWindowRef = useRef<BrowserSessionEventWindow>(EMPTY_EVENT_WINDOW);\n const sessionStatusRef = useRef<{\n sequence: number;\n status: SessionStatus | null;\n }>({\n sequence: after,\n status: null,\n });\n // Effects reset state after commit. Tag the state so the first render for a\n // new stream identity cannot expose the previous session's event log.\n const [stateStreamKey, setStateStreamKey] = useState(streamKey);\n\n useEffect(() => {\n // Reset the accumulated log only when the stream identity changes —\n // pausing via `enabled: false` keeps the timeline visible.\n if (streamKeyRef.current !== streamKey) {\n streamKeyRef.current = streamKey;\n setStateStreamKey(streamKey);\n eventWindowRef.current = EMPTY_EVENT_WINDOW;\n setEventWindow(EMPTY_EVENT_WINDOW);\n setError(null);\n setHasOlder(false);\n setHasNewer(false);\n sessionStatusRef.current = { sequence: after, status: null };\n setSessionStatusProjection(null);\n setLoadingOlder(false);\n setLoadingNewer(false);\n setLoadingOldest(false);\n setLoadingLatest(false);\n setInitialLoading(true);\n lastSequenceRef.current = after;\n streamResumeSequenceRef.current = after;\n oldestSequenceRef.current = null;\n newestSequenceRef.current = null;\n hasOlderRef.current = false;\n hasNewerRef.current = false;\n loadingOlderRef.current = false;\n loadingNewerRef.current = false;\n loadingOldestRef.current = false;\n loadingLatestRef.current = false;\n viewModeRef.current = \"live\";\n setViewMode(\"live\");\n initialWindowLoadedRef.current = false;\n }\n // AbortController is advisory: custom SDK clients and async iterators may\n // ignore it and resolve/yield after cleanup. Fence every effect instance so\n // only the newest dependency generation can mutate refs or React state.\n const generation = generationRef.current + 1;\n generationRef.current = generation;\n if (loadingOlderRef.current) {\n loadingOlderRef.current = false;\n setLoadingOlder(false);\n }\n if (!sessionId || !streamEnabled) {\n setConnectionState(\"idle\");\n return;\n }\n // History view owns a non-tip window; do not open SSE (it would replay the\n // entire gap into the browser). jumpToLatest / catching loadNewer resume live.\n if (viewMode === \"history\") {\n setConnectionState(\"idle\");\n setInitialLoading(false);\n return;\n }\n const controller = new AbortController();\n const isCurrent = () => generationRef.current === generation && !controller.signal.aborted;\n streamAbortRef.current = controller;\n // Batch yielded events into one React update per flush window so a long\n // replay (thousands of events) does not render per event. Project every\n // event before retaining it here and synchronously flush at independent\n // count+byte high-water marks: a synchronously yielding async iterator can\n // otherwise starve the 16 ms timer and grow this pre-React buffer without\n // bound even though the final browser window is bounded.\n let pending: SessionEvent[] = [];\n let pendingBytes = 2; // []\n let flushTimer: ReturnType<typeof setTimeout> | null = null;\n const flush = () => {\n // A synchronous count/byte high-water flush can run before the scheduled\n // callback gets a macrotask. Cancel that callback before clearing its\n // handle so a long synchronously yielding replay retains at most one\n // timer rather than one stale callback per flushed batch.\n if (flushTimer !== null) {\n clearTimeout(flushTimer);\n flushTimer = null;\n }\n if (!isCurrent()) {\n pending = [];\n pendingBytes = 2;\n return;\n }\n if (pending.length === 0) {\n return;\n }\n const batch = pending;\n pending = [];\n pendingBytes = 2;\n // The resume cursor only advances with delivered batches: events still\n // sitting in `pending` when the stream is torn down are re-fetched on\n // the next connect instead of being skipped.\n const lastInBatch = batch[batch.length - 1];\n if (lastInBatch) {\n const batchResumeSequence = Math.max(...batch.map(eventResumeSequence));\n lastSequenceRef.current = Math.max(lastSequenceRef.current, batchResumeSequence);\n streamResumeSequenceRef.current = Math.max(\n streamResumeSequenceRef.current,\n batchResumeSequence,\n );\n }\n observeSessionStatus(batch, sessionStatusRef, setSessionStatusProjection);\n const current = eventWindowRef.current;\n const next = boundBrowserSessionEventWindow([...current.events, ...batch]);\n const retained = {\n ...next,\n truncated: current.truncated || next.truncated,\n };\n eventWindowRef.current = retained;\n setEventWindow(retained);\n oldestSequenceRef.current = retained.events[0]?.sequence ?? null;\n newestSequenceRef.current = retained.events.at(-1)?.sequence ?? null;\n if (retained.truncated) {\n hasOlderRef.current = true;\n setHasOlder(true);\n }\n };\n const scheduleFlush = () => {\n if (!isCurrent()) return;\n flushTimer ??= setTimeout(flush, 16);\n };\n\n void (async () => {\n try {\n if (!fullReplay && !initialWindowLoadedRef.current) {\n setConnectionState(\"connecting\");\n // First paint is ONE compact fetch — the newest window, revealed at\n // the bottom in a few hundred ms. Deeper history loads only when the\n // reader actually scrolls up (the sentinel drives loadOlder).\n const window = await loadEventWindow(client, workspaceId, sessionId, {\n before: Number.MAX_SAFE_INTEGER,\n pageSize: INITIAL_TAIL_PAGE_SIZE,\n targetGroups: Number.POSITIVE_INFINITY,\n maxFetches: INITIAL_FETCH_CAP,\n signal: controller.signal,\n });\n if (!isCurrent()) {\n return;\n }\n observeSessionStatus(window.events, sessionStatusRef, setSessionStatusProjection);\n const retained = boundBrowserSessionEventWindow(window.events);\n eventWindowRef.current = retained;\n setEventWindow(retained);\n oldestSequenceRef.current = retained.events[0]?.sequence ?? window.oldestSequence;\n newestSequenceRef.current = retained.events.at(-1)?.sequence ?? window.newestSequence;\n hasOlderRef.current = window.hasOlder || retained.truncated;\n hasNewerRef.current = false;\n lastSequenceRef.current = window.newestSequence;\n streamResumeSequenceRef.current = window.newestSequence;\n initialWindowLoadedRef.current = true;\n setHasOlder(window.hasOlder || retained.truncated);\n setHasNewer(false);\n setInitialLoading(false);\n }\n if (fullReplay) {\n setInitialLoading(false);\n }\n const stream = client.streamEvents(workspaceId, sessionId, {\n after: streamResumeSequenceRef.current,\n signal: controller.signal,\n onOpen: () => {\n // Reconciliation repairs projections, but it must not block reading\n // the already-open SSE body. Otherwise live events accumulate in the\n // browser and appear as one delayed burst after every reconciler ends.\n void Promise.resolve()\n .then(() => reconcileSession(sessionId))\n .catch((cause) => {\n if (isCurrent()) {\n setError(cause instanceof Error ? cause : new Error(String(cause)));\n }\n });\n },\n onStateChange: (state) => {\n if (isCurrent()) {\n setConnectionState(state);\n }\n },\n });\n for await (const event of stream) {\n if (!isCurrent()) break;\n const boundedEvent = boundBrowserLegacyEvent(event);\n const boundedEventBytes = browserJsonBytes(boundedEvent);\n const separatorBytes = pending.length === 0 ? 0 : 1;\n if (\n pending.length > 0 &&\n (pending.length >= SESSION_EVENT_BROWSER_PENDING_MAX_COUNT ||\n pendingBytes + separatorBytes + boundedEventBytes >\n SESSION_EVENT_BROWSER_PENDING_MAX_BYTES)\n ) {\n flush();\n }\n pending.push(boundedEvent);\n pendingBytes += (pending.length === 1 ? 0 : 1) + boundedEventBytes;\n if (\n pending.length >= SESSION_EVENT_BROWSER_PENDING_MAX_COUNT ||\n pendingBytes >= SESSION_EVENT_BROWSER_PENDING_MAX_BYTES\n ) {\n flush();\n } else {\n scheduleFlush();\n }\n }\n if (isCurrent()) {\n flush();\n setConnectionState(\"ended\");\n }\n } catch (cause) {\n if (isCurrent()) {\n flush();\n setError(cause instanceof Error ? cause : new Error(String(cause)));\n setConnectionState(\"error\");\n }\n }\n })();\n\n return () => {\n controller.abort();\n if (generationRef.current === generation) {\n generationRef.current = generation + 1;\n }\n if (streamAbortRef.current === controller) {\n streamAbortRef.current = null;\n }\n if (flushTimer !== null) {\n clearTimeout(flushTimer);\n }\n };\n }, [\n client,\n workspaceId,\n sessionId,\n after,\n streamEnabled,\n fullReplay,\n streamKey,\n streamEpoch,\n viewMode,\n reconcileSession,\n ]);\n\n const navigationBusy = (): boolean =>\n loadingOlderRef.current ||\n loadingNewerRef.current ||\n loadingOldestRef.current ||\n loadingLatestRef.current;\n\n const loadOlder = useCallback(\n (): OlderHistoryLoadReceipt =>\n createOlderHistoryLoadReceipt(async (markCommitted) => {\n if (!sessionId || navigationBusy() || !hasOlderRef.current) {\n return false;\n }\n const before = oldestSequenceRef.current;\n if (before === null) {\n oldestSequenceRef.current = null;\n hasOlderRef.current = false;\n setHasOlder(false);\n return false;\n }\n const generation = generationRef.current;\n loadingOlderRef.current = true;\n setLoadingOlder(true);\n try {\n const window = await loadEventWindow(client, workspaceId, sessionId, {\n before,\n pageSize: OLDER_PAGE_SIZE,\n targetGroups: OLDER_GROUP_TARGET,\n maxFetches: OLDER_FETCH_CAP,\n });\n if (generationRef.current !== generation) {\n return false;\n }\n if (window.events.length === 0) {\n oldestSequenceRef.current = null;\n hasOlderRef.current = false;\n setHasOlder(false);\n return false;\n }\n const current = eventWindowRef.current;\n assertPrependOrder(current.events, window.events);\n // Freeze the live iterator before replacing its in-memory window. Rows\n // pending in the aborted iterator were never cursor-committed and will\n // be replayed from the retained high-water mark below.\n streamAbortRef.current?.abort();\n observeSessionStatus(window.events, sessionStatusRef, setSessionStatusProjection);\n const next = boundBrowserSessionEventWindow([...window.events, ...current.events], {\n direction: \"oldest\",\n });\n const retained = {\n ...next,\n truncated: current.truncated || next.truncated,\n };\n const retainedOldest = retained.events[0]?.sequence ?? null;\n if (retainedOldest === null || retainedOldest >= before) {\n throw new Error(\"@opengeni/react: loadOlder made no durable sequence progress\");\n }\n const retainedNewest = retained.events.at(-1)?.sequence ?? null;\n eventWindowRef.current = retained;\n markCommitted();\n setEventWindow(retained);\n oldestSequenceRef.current = retainedOldest;\n newestSequenceRef.current = retainedNewest;\n streamResumeSequenceRef.current = maxResumeSequence(retained.events);\n // Oldest-directed eviction can discard newer in-memory rows. That fact\n // keeps windowTruncated true, but it does not imply older durable rows\n // exist; only the backward DB page can answer hasOlder truthfully.\n const olderStillAvailable = window.hasOlder;\n hasOlderRef.current = olderStillAvailable;\n setHasOlder(olderStillAvailable);\n if (viewModeRef.current === \"history\") {\n const highWater = lastSequenceRef.current;\n const newer =\n retainedNewest !== null && (retainedNewest < highWater || retained.truncated);\n hasNewerRef.current = newer;\n setHasNewer(newer);\n } else {\n // Live mode keeps the historical contract: reconnect and replay the\n // evicted tip through SSE so the window stays one contiguous suffix.\n setStreamEpoch((epoch) => epoch + 1);\n }\n return olderStillAvailable;\n } finally {\n loadingOlderRef.current = false;\n setLoadingOlder(false);\n }\n }),\n [client, workspaceId, sessionId],\n );\n\n const loadOldest = useCallback(async (): Promise<boolean> => {\n if (!sessionId || navigationBusy() || !hasOlderRef.current) {\n return false;\n }\n const generation = generationRef.current;\n loadingOldestRef.current = true;\n setLoadingOldest(true);\n try {\n const window = await loadForwardEventWindow(client, workspaceId, sessionId, {\n after: 0,\n pageSize: OLDEST_PAGE_SIZE,\n targetGroups: OLDEST_GROUP_TARGET,\n maxFetches: OLDEST_FETCH_CAP,\n });\n if (generationRef.current !== generation) {\n return false;\n }\n if (window.events.length === 0) {\n hasOlderRef.current = false;\n setHasOlder(false);\n return false;\n }\n streamAbortRef.current?.abort();\n observeSessionStatus(window.events, sessionStatusRef, setSessionStatusProjection);\n // Keep the oldest prefix — never the middle or tip.\n const retained = boundBrowserSessionEventWindow(window.events, { direction: \"oldest\" });\n const retainedOldest = retained.events[0]?.sequence ?? null;\n const retainedNewest = retained.events.at(-1)?.sequence ?? null;\n eventWindowRef.current = retained;\n setEventWindow(retained);\n oldestSequenceRef.current = retainedOldest;\n newestSequenceRef.current = retainedNewest;\n hasOlderRef.current = false;\n setHasOlder(false);\n const highWater = Math.max(lastSequenceRef.current, retainedNewest ?? 0);\n lastSequenceRef.current = highWater;\n const newer =\n window.hasNewer ||\n retained.truncated ||\n (retainedNewest !== null && retainedNewest < highWater);\n hasNewerRef.current = newer;\n setHasNewer(newer);\n initialWindowLoadedRef.current = true;\n viewModeRef.current = \"history\";\n setViewMode(\"history\");\n return newer;\n } finally {\n loadingOldestRef.current = false;\n setLoadingOldest(false);\n }\n }, [client, workspaceId, sessionId]);\n\n const loadNewer = useCallback(async (): Promise<boolean> => {\n if (!sessionId || navigationBusy() || !hasNewerRef.current) {\n return false;\n }\n const afterSequence = newestSequenceRef.current;\n if (afterSequence === null) {\n hasNewerRef.current = false;\n setHasNewer(false);\n return false;\n }\n const generation = generationRef.current;\n loadingNewerRef.current = true;\n setLoadingNewer(true);\n try {\n const window = await loadForwardEventWindow(client, workspaceId, sessionId, {\n after: afterSequence,\n pageSize: NEWER_PAGE_SIZE,\n targetGroups: NEWER_GROUP_TARGET,\n maxFetches: NEWER_FETCH_CAP,\n });\n if (generationRef.current !== generation) {\n return false;\n }\n if (window.events.length === 0) {\n hasNewerRef.current = false;\n setHasNewer(false);\n // Caught up with durable history — resume the live tip stream.\n streamResumeSequenceRef.current = afterSequence;\n viewModeRef.current = \"live\";\n setViewMode(\"live\");\n setStreamEpoch((epoch) => epoch + 1);\n return false;\n }\n const current = eventWindowRef.current;\n assertAppendOrder(current.events, window.events);\n observeSessionStatus(window.events, sessionStatusRef, setSessionStatusProjection);\n const previousOldest = current.events[0]?.sequence ?? null;\n // Moving forward through history: keep the newest suffix of the merge.\n const next = boundBrowserSessionEventWindow([...current.events, ...window.events], {\n direction: \"newest\",\n });\n const retained = {\n ...next,\n truncated: current.truncated || next.truncated || window.hasNewer,\n };\n const retainedOldest = retained.events[0]?.sequence ?? null;\n const retainedNewest = retained.events.at(-1)?.sequence ?? null;\n if (retainedNewest === null || retainedNewest <= afterSequence) {\n throw new Error(\"@opengeni/react: loadNewer made no durable sequence progress\");\n }\n eventWindowRef.current = retained;\n setEventWindow(retained);\n oldestSequenceRef.current = retainedOldest;\n newestSequenceRef.current = retainedNewest;\n // Evicting the start while paging forward re-arms hasOlder.\n if (\n retainedOldest !== null &&\n (previousOldest === null ||\n retainedOldest > previousOldest ||\n (retained.truncated &&\n retained.events[0]?.type !== \"session.created\" &&\n retainedOldest > 1))\n ) {\n hasOlderRef.current = true;\n setHasOlder(true);\n }\n const highWater = Math.max(lastSequenceRef.current, retainedNewest);\n lastSequenceRef.current = highWater;\n const newer = window.hasNewer || retainedNewest < highWater;\n hasNewerRef.current = newer;\n setHasNewer(newer);\n if (!newer) {\n streamResumeSequenceRef.current = retainedNewest;\n viewModeRef.current = \"live\";\n setViewMode(\"live\");\n setStreamEpoch((epoch) => epoch + 1);\n }\n return newer;\n } finally {\n loadingNewerRef.current = false;\n setLoadingNewer(false);\n }\n }, [client, workspaceId, sessionId]);\n\n const jumpToLatest = useCallback(async (): Promise<void> => {\n if (!sessionId || navigationBusy()) {\n return;\n }\n loadingLatestRef.current = true;\n setLoadingLatest(true);\n try {\n streamAbortRef.current?.abort();\n hasNewerRef.current = false;\n setHasNewer(false);\n hasOlderRef.current = false;\n setHasOlder(false);\n newestSequenceRef.current = null;\n oldestSequenceRef.current = null;\n eventWindowRef.current = EMPTY_EVENT_WINDOW;\n setEventWindow(EMPTY_EVENT_WINDOW);\n initialWindowLoadedRef.current = false;\n streamResumeSequenceRef.current = after;\n setInitialLoading(true);\n viewModeRef.current = \"live\";\n setViewMode(\"live\");\n setStreamEpoch((epoch) => epoch + 1);\n // Effect reloads the tip. The tip fetch itself is owned by the effect.\n await Promise.resolve();\n } finally {\n loadingLatestRef.current = false;\n setLoadingLatest(false);\n }\n }, [after, sessionId]);\n\n const identityMatches = stateStreamKey === streamKey;\n const visibleEvents = identityMatches ? eventWindow.events : EMPTY_EVENTS;\n const timeline = useMemo(() => buildTimeline(visibleEvents), [visibleEvents]);\n\n return {\n events: visibleEvents,\n timeline,\n sessionStatus: identityMatches ? sessionStatusProjection : null,\n connectionState: identityMatches ? connectionState : \"idle\",\n lastSequence: identityMatches ? lastSequenceRef.current : after,\n windowBytes: identityMatches ? eventWindow.bytes : 2,\n windowTruncated: identityMatches ? eventWindow.truncated : false,\n initialLoading: fullReplay ? false : identityMatches ? initialLoading : true,\n hasOlder: !identityMatches ? false : hasOlder,\n loadingOlder: !identityMatches ? false : loadingOlder,\n loadOlder,\n hasNewer: !identityMatches ? false : hasNewer,\n loadingNewer: !identityMatches ? false : loadingNewer,\n loadNewer,\n loadingOldest: !identityMatches ? false : loadingOldest,\n loadOldest,\n loadingLatest: !identityMatches ? false : loadingLatest,\n jumpToLatest,\n error: identityMatches ? error : null,\n };\n}\n\n/**\n * Keep one direction-aware count+byte-bounded browser window. Live/default\n * accumulation retains the newest suffix; backward paging retains the oldest\n * prefix so newly fetched history cannot be immediately evicted. This is\n * deliberately separate from durable history and transport paging: when a\n * backward page evicts the live tail, the hook reconnects from the retained\n * high-water mark while preserving the highest-ever-observed sequence\n * separately. The source event remains durable in PostgreSQL throughout.\n */\nexport function boundBrowserSessionEventWindow(\n events: readonly SessionEvent[],\n options: {\n maxBytes?: number;\n maxCount?: number;\n direction?: \"newest\" | \"oldest\";\n } = {},\n): BrowserSessionEventWindow {\n const maxBytes = Math.max(1024, options.maxBytes ?? SESSION_EVENT_BROWSER_MAX_BYTES);\n const maxCount = Math.max(1, Math.floor(options.maxCount ?? SESSION_EVENT_BROWSER_MAX_COUNT));\n const safe = events.map(boundBrowserLegacyEvent);\n const selected: SessionEvent[] = [];\n let bytes = 2; // []\n const direction = options.direction ?? \"newest\";\n const start = direction === \"newest\" ? safe.length - 1 : 0;\n const end = direction === \"newest\" ? Math.max(-1, safe.length - maxCount - 1) : safe.length;\n const step = direction === \"newest\" ? -1 : 1;\n for (let index = start; index !== end && selected.length < maxCount; index += step) {\n const event = safe[index]!;\n const eventBytes = browserJsonBytes(event);\n const separator = selected.length === 0 ? 0 : 1;\n if (bytes + separator + eventBytes > maxBytes) break;\n selected.push(event);\n bytes += separator + eventBytes;\n }\n if (direction === \"newest\") selected.reverse();\n return {\n events: selected,\n bytes,\n truncated: selected.length < safe.length,\n };\n}\n\nfunction boundBrowserLegacyEvent(event: SessionEvent): SessionEvent {\n // The server-side canonical projection lives in @opengeni/contracts. The\n // publishable React package may depend only on the zero-runtime-dependency\n // SDK, so this is intentionally a last-resort client guard rather than a\n // second durable representation. Reconstructing the SDK wire shape prevents\n // legacy/malformed extra properties from bypassing the browser byte cap.\n const serialized = browserSerialize(event);\n const originalBytes = serialized.serializable\n ? encoder.encode(serialized.value).byteLength\n : null;\n const typeIsSafe =\n browserUtf8Bytes(event.type) <= BROWSER_EVENT_TYPE_MAX_BYTES &&\n !event.type.includes(\"\\n\") &&\n !event.type.includes(\"\\r\");\n const clientEventId = boundBrowserOptionalText(\n event.clientEventId,\n BROWSER_EVENT_CLIENT_ID_MAX_BYTES,\n );\n const duplicateReason = boundBrowserOptionalText(\n event.duplicateReason,\n BROWSER_EVENT_DUPLICATE_REASON_MAX_BYTES,\n );\n\n if (\n serialized.serializable &&\n originalBytes !== null &&\n originalBytes <= SESSION_EVENT_BROWSER_SINGLE_EVENT_MAX_BYTES &&\n typeIsSafe &&\n clientEventId === event.clientEventId &&\n duplicateReason === event.duplicateReason\n ) {\n return event;\n }\n\n const envelopeProjection = [\n !typeIsSafe\n ? browserEnvelopeFieldProjection(\"type\", event.type, \"session.event.envelope_omitted\")\n : null,\n clientEventId !== event.clientEventId\n ? browserEnvelopeFieldProjection(\"clientEventId\", event.clientEventId, clientEventId)\n : null,\n duplicateReason !== event.duplicateReason\n ? browserEnvelopeFieldProjection(\"duplicateReason\", event.duplicateReason, duplicateReason)\n : null,\n ].filter((field) => field !== null);\n const payloadSerialization = browserSerialize(event.payload);\n const payloadBytes = payloadSerialization.serializable\n ? encoder.encode(payloadSerialization.value).byteLength\n : null;\n const preview = truncateBrowserUtf8Middle(\n payloadSerialization.value,\n BROWSER_EVENT_PAYLOAD_PREVIEW_MAX_BYTES,\n );\n const truncation = {\n truncated: true as const,\n surface: \"browser_legacy_guard\" as const,\n reason: serialized.serializable ? \"event_envelope_bytes_exceeded\" : \"event_not_serializable\",\n originalBytes,\n deliveredBytes: 0,\n omittedBytes: originalBytes,\n estimatedOriginalTokens: originalBytes === null ? null : Math.ceil(originalBytes / 4),\n estimatedDeliveredTokens: 0,\n fullEvidence: { available: false as const, reason: \"not_retained\" as const },\n details: [\n {\n path: \"$.payload\",\n kind: \"payload_preview\",\n originalBytes: payloadBytes,\n deliveredBytes: browserUtf8Bytes(preview),\n },\n ],\n };\n const payload: Record<string, unknown> = {\n ...browserPayloadIdentity(event.payload),\n preview,\n ...(envelopeProjection.length > 0\n ? {\n originalType: boundBrowserText(event.type, BROWSER_EVENT_TYPE_MAX_BYTES),\n envelopeProjection: {\n truncated: true,\n surface: \"browser_legacy_guard\",\n fields: envelopeProjection,\n },\n }\n : {}),\n truncation,\n };\n const bounded: SessionEvent = {\n id: boundBrowserText(event.id, BROWSER_EVENT_ID_MAX_BYTES),\n workspaceId: boundBrowserText(event.workspaceId, BROWSER_EVENT_ID_MAX_BYTES),\n sessionId: boundBrowserText(event.sessionId, BROWSER_EVENT_ID_MAX_BYTES),\n sequence: event.sequence,\n type: typeIsSafe ? event.type : \"session.event.envelope_omitted\",\n payload,\n occurredAt: boundBrowserText(event.occurredAt, BROWSER_EVENT_ID_MAX_BYTES),\n clientEventId,\n turnId: boundBrowserOptionalText(event.turnId, BROWSER_EVENT_ID_MAX_BYTES),\n turnGeneration: event.turnGeneration,\n turnAttemptId: boundBrowserOptionalText(event.turnAttemptId, BROWSER_EVENT_ID_MAX_BYTES),\n turnAssociation: event.turnAssociation,\n duplicateOfEventId: boundBrowserOptionalText(\n event.duplicateOfEventId,\n BROWSER_EVENT_ID_MAX_BYTES,\n ),\n duplicateReason,\n };\n\n settleBrowserEventTruncation(bounded, truncation);\n if (browserJsonBytes(bounded) > SESSION_EVENT_BROWSER_SINGLE_EVENT_MAX_BYTES) {\n payload.preview = truncateBrowserUtf8Middle(String(payload.preview), 4 * 1024);\n truncation.details = truncation.details.slice(0, 1);\n settleBrowserEventTruncation(bounded, truncation);\n }\n if (browserJsonBytes(bounded) > SESSION_EVENT_BROWSER_SINGLE_EVENT_MAX_BYTES) {\n bounded.clientEventId = null;\n bounded.duplicateReason = null;\n payload.preview = \"[legacy event omitted at the browser byte boundary]\";\n settleBrowserEventTruncation(bounded, truncation);\n }\n return bounded;\n}\n\nfunction browserJsonBytes(value: unknown): number {\n return encoder.encode(browserSerialize(value).value).byteLength;\n}\n\nfunction browserSerialize(value: unknown): { value: string; serializable: boolean } {\n try {\n const serialized = JSON.stringify(value);\n return { value: serialized === undefined ? \"null\" : serialized, serializable: true };\n } catch {\n return {\n value: '\"[unserializable event payload omitted at browser boundary]\"',\n serializable: false,\n };\n }\n}\n\nfunction browserPayloadIdentity(payload: unknown): Record<string, unknown> {\n if (!payload || typeof payload !== \"object\" || Array.isArray(payload)) return {};\n const record = payload as Record<string, unknown>;\n const identity: Record<string, unknown> = {};\n for (const field of BROWSER_EVENT_PAYLOAD_IDENTITY_FIELDS) {\n const value = record[field];\n if (typeof value === \"string\") {\n identity[field] = boundBrowserText(value, BROWSER_EVENT_ID_MAX_BYTES);\n } else if (typeof value === \"number\" || typeof value === \"boolean\" || value === null) {\n identity[field] = value;\n }\n }\n return identity;\n}\n\nfunction browserEnvelopeFieldProjection(\n field: string,\n original: string | null | undefined,\n delivered: string | null | undefined,\n): { field: string; originalBytes: number; deliveredBytes: number } {\n return {\n field,\n originalBytes: typeof original === \"string\" ? browserUtf8Bytes(original) : 0,\n deliveredBytes: typeof delivered === \"string\" ? browserUtf8Bytes(delivered) : 0,\n };\n}\n\nfunction boundBrowserOptionalText<T extends string | null | undefined>(\n value: T,\n maxBytes: number,\n): T {\n return (typeof value === \"string\" ? boundBrowserText(value, maxBytes) : value) as T;\n}\n\nfunction boundBrowserText(value: string, maxBytes: number): string {\n const bytes = encoder.encode(value);\n if (bytes.byteLength <= maxBytes) return value;\n const marker = \"…[truncated]\";\n const prefixBudget = Math.max(0, maxBytes - browserUtf8Bytes(marker));\n let prefixEnd = Math.min(prefixBudget, bytes.byteLength);\n while (\n prefixEnd > 0 &&\n prefixEnd < bytes.byteLength &&\n isBrowserUtf8Continuation(bytes[prefixEnd]!)\n ) {\n prefixEnd -= 1;\n }\n return `${decoder.decode(bytes.subarray(0, prefixEnd))}${marker}`;\n}\n\nfunction truncateBrowserUtf8Middle(value: string, maxBytes: number): string {\n const bytes = encoder.encode(value);\n if (bytes.byteLength <= maxBytes) return value;\n const marker = `…[${bytes.byteLength - maxBytes} bytes omitted]…`;\n const contentBudget = Math.max(0, maxBytes - browserUtf8Bytes(marker));\n const leftBudget = Math.floor(contentBudget / 2);\n const rightBudget = contentBudget - leftBudget;\n let leftEnd = Math.min(leftBudget, bytes.byteLength);\n while (leftEnd > 0 && leftEnd < bytes.byteLength && isBrowserUtf8Continuation(bytes[leftEnd]!)) {\n leftEnd -= 1;\n }\n let rightStart = Math.max(0, bytes.byteLength - rightBudget);\n while (rightStart < bytes.byteLength && isBrowserUtf8Continuation(bytes[rightStart]!)) {\n rightStart += 1;\n }\n return `${decoder.decode(bytes.subarray(0, leftEnd))}${marker}${decoder.decode(bytes.subarray(rightStart))}`;\n}\n\nfunction settleBrowserEventTruncation(\n event: SessionEvent,\n truncation: {\n originalBytes: number | null;\n deliveredBytes: number;\n omittedBytes: number | null;\n estimatedDeliveredTokens: number;\n },\n): void {\n for (let attempt = 0; attempt < 16; attempt += 1) {\n const deliveredBytes = browserJsonBytes(event);\n const omittedBytes =\n truncation.originalBytes === null\n ? null\n : Math.max(0, truncation.originalBytes - deliveredBytes);\n const estimatedDeliveredTokens = Math.ceil(deliveredBytes / 4);\n if (\n truncation.deliveredBytes === deliveredBytes &&\n truncation.omittedBytes === omittedBytes &&\n truncation.estimatedDeliveredTokens === estimatedDeliveredTokens\n ) {\n return;\n }\n truncation.deliveredBytes = deliveredBytes;\n truncation.omittedBytes = omittedBytes;\n truncation.estimatedDeliveredTokens = estimatedDeliveredTokens;\n }\n throw new RangeError(\"Browser event byte accounting did not converge\");\n}\n\nfunction browserUtf8Bytes(value: string): number {\n return encoder.encode(value).byteLength;\n}\n\nfunction isBrowserUtf8Continuation(value: number): boolean {\n return (value & 0xc0) === 0x80;\n}\n\nfunction observeSessionStatus(\n events: readonly SessionEvent[],\n ref: { current: { sequence: number; status: SessionStatus | null } },\n setStatus: (status: SessionStatus | null) => void,\n): void {\n let latest: { sequence: number; status: SessionStatus } | null = null;\n for (const event of events) {\n const status = sessionStatusFromEvents([event]);\n if (status && (!latest || event.sequence >= latest.sequence)) {\n latest = { sequence: event.sequence, status };\n }\n }\n if (!latest || latest.sequence < ref.current.sequence) return;\n ref.current = latest;\n setStatus(latest.status);\n}\n\ntype LoadedEventWindow = {\n events: SessionEvent[];\n oldestSequence: number | null;\n newestSequence: number;\n hasOlder: boolean;\n};\n\ntype LoadedForwardEventWindow = {\n events: SessionEvent[];\n oldestSequence: number | null;\n newestSequence: number;\n hasNewer: boolean;\n};\n\nasync function loadEventWindow(\n client: EmbeddedSessionClientLike,\n workspaceId: string,\n sessionId: string,\n options: {\n before: number;\n pageSize: number;\n targetGroups: number;\n maxFetches: number;\n signal?: AbortSignal;\n },\n): Promise<LoadedEventWindow> {\n let cursor = options.before;\n let buffer: SessionEvent[] = [];\n let reachedStart = false;\n let fetches = 0;\n\n while (fetches < options.maxFetches) {\n if (buffer.length > 0 && groupCount(buffer) >= options.targetGroups) {\n break;\n }\n const page = await loadPreviousPage(client, workspaceId, sessionId, cursor, {\n pageSize: options.pageSize,\n ...(options.signal ? { signal: options.signal } : {}),\n });\n fetches += 1;\n if (page.length === 0) {\n reachedStart = true;\n break;\n }\n assertAscending(page);\n buffer = [...page, ...buffer];\n cursor = page[0]!.sequence;\n if (isLogStart(page[0]!)) {\n reachedStart = true;\n break;\n }\n }\n\n // Boundary snap: a window that starts mid-turn TRIMS its head to the oldest\n // turn boundary already in the buffer — the dropped fragment is refetched by\n // the next loadOlder (everything below the new oldest sequence), whose own\n // window snaps the same way, so every seam lands on a turn start. Extra\n // pages are fetched only when the buffer holds no boundary at all (one\n // monster turn); past the cap a mid-turn top is accepted.\n let snapPages = 0;\n while (\n !reachedStart &&\n findBoundaryIndex(buffer) === -1 &&\n snapPages < BOUNDARY_PAGE_CAP &&\n fetches < options.maxFetches\n ) {\n const page = await loadPreviousPage(client, workspaceId, sessionId, cursor, {\n pageSize: options.pageSize,\n ...(options.signal ? { signal: options.signal } : {}),\n });\n fetches += 1;\n snapPages += 1;\n if (page.length === 0) {\n reachedStart = true;\n break;\n }\n assertAscending(page);\n buffer = [...page, ...buffer];\n cursor = page[0]!.sequence;\n if (isLogStart(page[0]!)) {\n reachedStart = true;\n break;\n }\n }\n if (!reachedStart) {\n const boundary = findBoundaryIndex(buffer);\n if (boundary > 0) {\n buffer = buffer.slice(boundary);\n }\n }\n\n const oldest = buffer[0] ?? null;\n const newest = buffer[buffer.length - 1] ?? null;\n return {\n events: buffer,\n oldestSequence: oldest?.sequence ?? null,\n newestSequence: newest ? maxResumeSequence(buffer) : 0,\n hasOlder: buffer.length > 0 && !reachedStart && oldest?.type !== \"session.created\",\n };\n}\n\n/** Index of the oldest clean turn start in the buffer, or -1. */\nfunction findBoundaryIndex(events: SessionEvent[]): number {\n for (let index = 0; index < events.length; index += 1) {\n const type = events[index]!.type;\n if (type === \"session.created\" || type === \"user.message\") {\n return index;\n }\n }\n return -1;\n}\n\n/**\n * Forward (oldest→newer) density-bounded window. Used for jump-to-start and\n * loadNewer so the browser never walks the whole middle gap.\n */\nasync function loadForwardEventWindow(\n client: EmbeddedSessionClientLike,\n workspaceId: string,\n sessionId: string,\n options: {\n after: number;\n pageSize: number;\n targetGroups: number;\n maxFetches: number;\n signal?: AbortSignal;\n },\n): Promise<LoadedForwardEventWindow> {\n let cursor = options.after;\n let buffer: SessionEvent[] = [];\n let fetches = 0;\n let reachedEnd = false;\n\n while (fetches < options.maxFetches) {\n if (buffer.length > 0 && groupCount(buffer) >= options.targetGroups) {\n break;\n }\n const page = await loadNextPage(client, workspaceId, sessionId, cursor, {\n pageSize: options.pageSize,\n ...(options.signal ? { signal: options.signal } : {}),\n });\n fetches += 1;\n if (page.length === 0) {\n reachedEnd = true;\n break;\n }\n assertAscending(page);\n buffer = [...buffer, ...page];\n cursor = page[page.length - 1]!.sequence;\n if (page.length < options.pageSize) {\n reachedEnd = true;\n break;\n }\n }\n\n const oldest = buffer[0] ?? null;\n const newest = buffer[buffer.length - 1] ?? null;\n return {\n events: buffer,\n oldestSequence: oldest?.sequence ?? null,\n newestSequence: newest ? maxResumeSequence(buffer) : 0,\n hasNewer: buffer.length > 0 && !reachedEnd,\n };\n}\n\ntype PreviousPage = SessionEvent[] & { requested: number };\n\nasync function loadPreviousPage(\n client: EmbeddedSessionClientLike,\n workspaceId: string,\n sessionId: string,\n before: number,\n options: {\n pageSize: number;\n signal?: AbortSignal;\n },\n): Promise<PreviousPage> {\n if (options.signal?.aborted) {\n throw abortError();\n }\n const requested = options.pageSize;\n if (requested === 0) {\n return Object.assign([], { requested });\n }\n const page = await client.listEvents(workspaceId, sessionId, {\n before,\n limit: requested,\n compact: true,\n // Monitoring summaries omit correlation fields once a bounded durable\n // payload exceeds their preview threshold. The browser timeline needs the\n // exact stored payload so persisted tool outputs still match their\n // calls and expose truthful truncation telemetry after a reload.\n payloadMode: \"full\",\n });\n if (options.signal?.aborted) {\n throw abortError();\n }\n return Object.assign(page, { requested });\n}\n\nasync function loadNextPage(\n client: EmbeddedSessionClientLike,\n workspaceId: string,\n sessionId: string,\n after: number,\n options: {\n pageSize: number;\n signal?: AbortSignal;\n },\n): Promise<PreviousPage> {\n if (options.signal?.aborted) {\n throw abortError();\n }\n const requested = options.pageSize;\n if (requested === 0) {\n return Object.assign([], { requested });\n }\n const page = await client.listEvents(workspaceId, sessionId, {\n after,\n limit: requested,\n compact: true,\n direction: \"after\",\n payloadMode: \"full\",\n });\n if (options.signal?.aborted) {\n throw abortError();\n }\n return Object.assign(page, { requested });\n}\n\nfunction groupCount(events: SessionEvent[]): number {\n if (events.length === 0) {\n return 0;\n }\n return groupTimeline(buildTimeline(events)).length;\n}\n\nfunction isLogStart(event: SessionEvent): boolean {\n return event.type === \"session.created\" || event.sequence <= 1;\n}\n\nfunction maxResumeSequence(events: SessionEvent[]): number {\n return events.reduce((max, event) => Math.max(max, eventResumeSequence(event)), 0);\n}\n\nfunction eventResumeSequence(event: SessionEvent): number {\n const payload = asRecord(event.payload);\n const coalescedUntil = Number(payload.coalescedUntil);\n return Math.max(event.sequence, Number.isFinite(coalescedUntil) ? Math.floor(coalescedUntil) : 0);\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> {\n return value && typeof value === \"object\" ? (value as Record<string, unknown>) : {};\n}\n\nfunction assertAscending(events: SessionEvent[]): void {\n for (let index = 1; index < events.length; index += 1) {\n if (events[index - 1]!.sequence >= events[index]!.sequence) {\n throw new Error(\"@opengeni/react: session events must be ordered by ascending sequence\");\n }\n }\n}\n\nfunction assertPrependOrder(existing: SessionEvent[], older: SessionEvent[]): void {\n if (!shouldAssertDevelopment() || existing.length === 0 || older.length === 0) {\n return;\n }\n if (older[older.length - 1]!.sequence >= existing[0]!.sequence) {\n throw new Error(\"@opengeni/react: loadOlder returned overlapping session events\");\n }\n}\n\nfunction assertAppendOrder(existing: SessionEvent[], newer: SessionEvent[]): void {\n if (!shouldAssertDevelopment() || existing.length === 0 || newer.length === 0) {\n return;\n }\n if (newer[0]!.sequence <= existing[existing.length - 1]!.sequence) {\n throw new Error(\"@opengeni/react: loadNewer returned overlapping session events\");\n }\n}\n\nfunction shouldAssertDevelopment(): boolean {\n const processEnv = (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process?.env;\n return processEnv !== undefined && processEnv.NODE_ENV !== \"production\";\n}\n\nfunction abortError(): Error {\n const error = new Error(\"The operation was aborted.\");\n error.name = \"AbortError\";\n return error;\n}\n","import type { FileAsset, FileResourceRef } from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n useEmbeddedFileAttachments,\n type EmbeddedFileAttachmentClientOverride,\n} from \"../session-context\";\n\nexport type UseFileAttachmentsOptions = EmbeddedFileAttachmentClientOverride & {\n /**\n * Only files matching this predicate are accepted by {@link\n * UseFileAttachmentsResult.addFromPaste} (the clipboard path). Defaults to\n * `image/*` — the console's historical paste filter. {@link\n * UseFileAttachmentsResult.addFiles} (the explicit picker / drop path)\n * bypasses it.\n */\n pasteFilter?: ((file: File) => boolean) | undefined;\n};\n\nexport type FileAttachment = {\n id: string;\n name: string;\n contentType: string;\n sizeBytes: number;\n status: \"uploading\" | \"ready\" | \"failed\";\n /** The SDK `FileAsset` once the upload finishes. */\n file?: FileAsset | undefined;\n /** Object-URL for an inline preview; minted for `image/*` files only. */\n previewUrl?: string | undefined;\n error?: string | undefined;\n};\n\nexport type UseFileAttachmentsResult = {\n attachments: FileAttachment[];\n /**\n * `FileResourceRef[]` for every attachment that finished uploading — feed\n * straight into `useComposer`'s `sendExtras.resources`.\n */\n readyResources: FileResourceRef[];\n /** True while any attachment is still uploading (drives progress UI). */\n uploading: boolean;\n /**\n * True while any attachment still needs an explicit outcome: wait for an\n * upload, retry a failure, or remove it. This is the loss-prevention send\n * gate; failed cards must never be silently omitted from a message.\n */\n hasUnresolved: boolean;\n /** Explicit picker / drop path — uploads every file, no filter. */\n addFiles: (files: Iterable<File>) => void;\n /** Clipboard path — applies `pasteFilter` (default `image/*`) then uploads. */\n addFromPaste: (event: { clipboardData: DataTransfer | null }) => void;\n /** Restore already-ready server assets without recreating browser-local bytes. */\n restoreReadyFiles: (files: Iterable<FileAsset>) => void;\n /**\n * Re-run the upload for a `failed` attachment, in place (same id, same\n * source file). No-op for an id that isn't a known failed upload.\n */\n retry: (id: string) => void;\n /** Remove one attachment; revokes its object-URL. */\n remove: (id: string) => void;\n /**\n * Remove only finalized files whose durable ids were accepted by a send.\n * Attachments added while that request was in flight remain queued for the\n * next message.\n */\n removeReadyFiles: (fileIds: Iterable<string>) => void;\n /** Remove all attachments and revoke every object-URL. */\n clear: () => void;\n};\n\nconst isImage = (file: File): boolean => file.type.startsWith(\"image/\");\n\n/**\n * Upload-and-track state for files attached to the next message. Owns the\n * full client-side upload layer: a per-file `uploading | ready | failed`\n * status machine driven by the SDK's `client.uploadFile`, object-URL image\n * previews with create/revoke lifecycle, the `image/*` clipboard paste filter,\n * and a `FileResourceRef[]` projection that drops straight into a message's\n * `resources`. Workspace-scoped, so it resolves both client and workspace from\n * the {@link OpenGeniProvider} (or a per-call `{ client, workspaceId }`).\n */\nexport function useFileAttachments(\n options: UseFileAttachmentsOptions = {},\n): UseFileAttachmentsResult {\n const { client, workspaceId } = useEmbeddedFileAttachments(options);\n const pasteFilter = options.pasteFilter ?? isImage;\n const [attachments, setAttachments] = useState<FileAttachment[]>([]);\n // Keep the source File per attachment id so a failed upload can be retried\n // in place. Cleared on remove/clear so it never outlives its attachment.\n const sources = useRef<Map<string, File>>(new Map());\n // Object URLs must be owned synchronously: React may discard an attachment\n // state update when its component unmounts in the same batch that minted the\n // preview. The registry remains available to cleanup even before a render.\n const previewUrls = useRef<Map<string, string>>(new Map());\n const revokePreview = useCallback((id: string) => {\n const previewUrl = previewUrls.current.get(id);\n if (!previewUrl) return;\n previewUrls.current.delete(id);\n URL.revokeObjectURL(previewUrl);\n }, []);\n const revokeAllPreviews = useCallback(() => {\n const urls = [...previewUrls.current.values()];\n previewUrls.current.clear();\n for (const previewUrl of urls) URL.revokeObjectURL(previewUrl);\n }, []);\n // Ready-file reconciliation uses functional state updaters, which React may\n // evaluate during a concurrent render that later suspends or is abandoned.\n // Diff only committed attachment sets here so URL revocation cannot run from\n // render-phase code while the previously committed DOM still uses a preview.\n const committedAttachmentIds = useRef<Set<string>>(new Set());\n useEffect(() => {\n const currentIds = new Set(attachments.map((attachment) => attachment.id));\n for (const id of committedAttachmentIds.current) {\n if (!currentIds.has(id)) revokePreview(id);\n }\n committedAttachmentIds.current = currentIds;\n }, [attachments, revokePreview]);\n // Upload promises are not cancellable at this layer. Fence their settlements\n // when the hook changes client/workspace or unmounts so an old tenant/session\n // cannot mutate the next attachment queue (or an already-unmounted component).\n const scopeGeneration = useRef(0);\n const previousScope = useRef({ client, workspaceId });\n\n useEffect(() => {\n const previous = previousScope.current;\n if (previous.client === client && previous.workspaceId === workspaceId) return;\n previousScope.current = { client, workspaceId };\n scopeGeneration.current += 1;\n sources.current.clear();\n revokeAllPreviews();\n setAttachments([]);\n }, [client, revokeAllPreviews, workspaceId]);\n\n useEffect(\n () => () => {\n scopeGeneration.current += 1;\n sources.current.clear();\n revokeAllPreviews();\n },\n [revokeAllPreviews],\n );\n\n // Run (or re-run) the upload for one already-tracked attachment id. Sets it\n // back to `uploading`, then resolves to `ready` (with the asset) or `failed`\n // (with the error message).\n const startUpload = useCallback(\n (id: string, file: File) => {\n const generation = scopeGeneration.current;\n void client\n .uploadFile(workspaceId, {\n filename: file.name || \"file\",\n contentType: file.type || \"application/octet-stream\",\n data: file,\n })\n .then((asset) => {\n if (scopeGeneration.current !== generation) return;\n // Retry bytes are useful only until durable finalization succeeds.\n // Drop the source File immediately; restored/ready attachments must\n // never retain browser-local byte authority.\n sources.current.delete(id);\n setAttachments((current) =>\n current.map((attachment) =>\n attachment.id === id\n ? {\n ...attachment,\n status: \"ready\",\n file: asset,\n name: asset.filename,\n contentType: asset.contentType,\n sizeBytes: asset.sizeBytes,\n error: undefined,\n }\n : attachment,\n ),\n );\n })\n .catch((error: unknown) => {\n if (scopeGeneration.current !== generation) return;\n setAttachments((current) =>\n current.map((attachment) =>\n attachment.id === id\n ? {\n ...attachment,\n status: \"failed\",\n error: error instanceof Error ? error.message : String(error),\n }\n : attachment,\n ),\n );\n });\n },\n [client, workspaceId],\n );\n\n const addFiles = useCallback(\n (files: Iterable<File>) => {\n for (const file of files) {\n const id = crypto.randomUUID();\n sources.current.set(id, file);\n const previewUrl = isImage(file) ? URL.createObjectURL(file) : undefined;\n if (previewUrl) previewUrls.current.set(id, previewUrl);\n setAttachments((current) => [\n ...current,\n {\n id,\n name: file.name || \"image\",\n contentType: file.type || \"application/octet-stream\",\n sizeBytes: file.size,\n status: \"uploading\",\n ...(previewUrl ? { previewUrl } : {}),\n },\n ]);\n startUpload(id, file);\n }\n },\n [startUpload],\n );\n\n const retry = useCallback(\n (id: string) => {\n const file = sources.current.get(id);\n if (!file) {\n return;\n }\n setAttachments((current) =>\n current.map((attachment) =>\n attachment.id === id\n ? { ...attachment, status: \"uploading\", error: undefined }\n : attachment,\n ),\n );\n startUpload(id, file);\n },\n [startUpload],\n );\n\n const addFromPaste = useCallback(\n (event: { clipboardData: DataTransfer | null }) => {\n const clipboardFiles = event.clipboardData?.files;\n if (!clipboardFiles) {\n return;\n }\n const files = [...clipboardFiles].filter(pasteFilter);\n if (files.length > 0) {\n addFiles(files);\n }\n },\n [addFiles, pasteFilter],\n );\n\n const restoreReadyFiles = useCallback(\n (files: Iterable<FileAsset>) => {\n const incoming = new Map<string, FileAsset>();\n for (const file of files) {\n if (file.status === \"ready\" && file.workspaceId === workspaceId) {\n incoming.set(file.id, file);\n }\n }\n setAttachments((current) => {\n const unresolved = current.filter((attachment) => attachment.status !== \"ready\");\n const existingReady = new Map(\n current.flatMap((attachment) =>\n attachment.status === \"ready\" && attachment.file\n ? ([[attachment.file.id, attachment]] as const)\n : [],\n ),\n );\n const restored = [...incoming.values()].map((file): FileAttachment => {\n const existing = existingReady.get(file.id);\n return existing\n ? {\n ...existing,\n name: file.filename,\n contentType: file.contentType,\n sizeBytes: file.sizeBytes,\n status: \"ready\",\n file,\n error: undefined,\n }\n : {\n id: `restored:${file.id}`,\n name: file.filename,\n contentType: file.contentType,\n sizeBytes: file.sizeBytes,\n status: \"ready\",\n file,\n // No source File and no object URL: server metadata is the\n // only authority restored across page/device boundaries.\n };\n });\n // A server restoration is authoritative for finalized assets, but an\n // upload that has not finalized still belongs to the local actor. Keep\n // those unresolved entries while replacing the ready set exactly.\n return [...unresolved, ...restored];\n });\n },\n [workspaceId],\n );\n\n const remove = useCallback(\n (id: string) => {\n sources.current.delete(id);\n revokePreview(id);\n setAttachments((current) => current.filter((attachment) => attachment.id !== id));\n },\n [revokePreview],\n );\n\n const removeReadyFiles = useCallback((fileIds: Iterable<string>) => {\n const accepted = new Set(fileIds);\n if (accepted.size === 0) return;\n setAttachments((current) =>\n current.filter((attachment) => {\n return !(\n attachment.status === \"ready\" &&\n attachment.file !== undefined &&\n accepted.has(attachment.file.id)\n );\n }),\n );\n }, []);\n\n const clear = useCallback(() => {\n sources.current.clear();\n revokeAllPreviews();\n setAttachments([]);\n }, [revokeAllPreviews]);\n\n return {\n attachments,\n readyResources: attachments.flatMap((attachment): FileResourceRef[] =>\n attachment.status === \"ready\" && attachment.file\n ? [{ kind: \"file\", fileId: attachment.file.id }]\n : [],\n ),\n uploading: attachments.some((attachment) => attachment.status === \"uploading\"),\n hasUnresolved: attachments.some((attachment) => attachment.status !== \"ready\"),\n addFiles,\n addFromPaste,\n restoreReadyFiles,\n retry,\n remove,\n removeReadyFiles,\n clear,\n };\n}\n","import type {\n ComposerDraft,\n EffectiveSessionControl,\n McpPersonalConnectionSummary,\n SessionEvent,\n SessionQueueMutationResponse,\n SessionQueueSnapshot,\n SessionPendingInputPreview,\n SessionTurn,\n} from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { useEmbeddedSession, type EmbeddedSessionClientOverride } from \"../session-context\";\nimport {\n useDebouncedCallback,\n usePageLiveActivity,\n useSessionEventTrigger,\n type SessionEventFeedOptions,\n} from \"./internal\";\n\n/** Events that can change the authoritative prompt queue or effective control. */\nexport function isTurnQueueEvent(event: Pick<SessionEvent, \"type\">): boolean {\n return (\n event.type.startsWith(\"turn.\") ||\n event.type.startsWith(\"session.queue.\") ||\n event.type.startsWith(\"session.control.\") ||\n event.type.startsWith(\"system.update.\") ||\n event.type.startsWith(\"workspace.inference.\")\n );\n}\n\nfunction queueSnapshotCovers(\n candidate: SessionQueueSnapshot | null,\n observed: SessionQueueSnapshot,\n): boolean {\n return Boolean(\n candidate &&\n candidate.version >= observed.version &&\n candidate.effectiveControl.controlVersion >= observed.effectiveControl.controlVersion,\n );\n}\n\nexport type QueueMutationKind = \"move\" | \"edit\" | \"steer\" | \"delete\";\nconst EMPTY_PENDING_BY_TURN: Readonly<Record<string, QueueMutationKind>> = {};\n\nexport type AcceptedQueueSteer = {\n turnId: string;\n triggerEventId: string;\n text: string;\n annotations: SessionTurn[\"annotations\"];\n resources: SessionTurn[\"resources\"];\n tools: SessionTurn[\"tools\"];\n occurredAt: string;\n state: \"sending\" | \"queued\";\n};\n\nexport type UseTurnQueueOptions = EmbeddedSessionClientOverride &\n SessionEventFeedOptions & {\n pollIntervalMs?: number | undefined;\n };\n\nexport type UseTurnQueueResult = {\n snapshot: SessionQueueSnapshot | null;\n /** Human/API prompts exactly in server execution order. Never client-sorted. */\n queue: SessionTurn[];\n /** Canonical pending machine inputs. Events only trigger an authoritative refresh. */\n pendingInputs: SessionPendingInputPreview[];\n /** Exact pending members projected to join an already-waiting prompt. */\n pendingInputAttachment: SessionQueueSnapshot[\"pendingInputAttachment\"];\n /** Secret-safe personal MCP summaries frozen on the exact active turn. */\n activePersonalConnections: McpPersonalConnectionSummary[];\n effectiveControl: EffectiveSessionControl | null;\n /** The latest interrupted attempt has not yet durably proved physical quiescence. */\n stoppingPreviousAttempt: boolean;\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n moveTurn: (turnId: string, beforeTurnId: string | null) => Promise<boolean>;\n /** Atomically withdraw a waiting prompt into the private durable composer draft. */\n editTurn: (\n turnId: string,\n options: { expectedDraftRevision: number; replaceDraft: boolean },\n ) => Promise<ComposerDraft | null>;\n /** Advance the same durable waiting prompt; no duplicate prompt is created. */\n steerTurn: (turnId: string) => Promise<boolean>;\n removeTurn: (turnId: string) => Promise<boolean>;\n pendingByTurn: Readonly<Record<string, QueueMutationKind>>;\n mutationFor: (turnId: string) => QueueMutationKind | null;\n mutating: boolean;\n mutationError: Error | null;\n clearMutationError: () => void;\n /** Immediate chat bridge while the durable Steer event catches up over SSE. */\n acceptedSteers?: AcceptedQueueSteer[] | undefined;\n};\n\n/**\n * The one authoritative human prompt queue. Every mutation carries the exact\n * server versions the operator saw and accepts only monotonic snapshots. A\n * conflict immediately reloads server truth; the client never invents order.\n */\nexport function useTurnQueue(\n sessionId: string | null | undefined,\n options: UseTurnQueueOptions = {},\n): UseTurnQueueResult {\n const { client, workspaceId, workspaceControlEvent, registerSessionReconciler } =\n useEmbeddedSession(options);\n const enabled = (options.enabled ?? true) && Boolean(sessionId);\n const targetKey = `${workspaceId}\\u0000${sessionId ?? \"\"}`;\n const pageLive = usePageLiveActivity();\n const [snapshot, setSnapshot] = useState<SessionQueueSnapshot | null>(null);\n const [stateTargetKey, setStateTargetKey] = useState(targetKey);\n const [loading, setLoading] = useState(enabled);\n const [error, setError] = useState<Error | null>(null);\n const [mutationError, setMutationError] = useState<Error | null>(null);\n const [pendingByTurn, setPendingByTurn] = useState<Record<string, QueueMutationKind>>({});\n const [acceptedSteers, setAcceptedSteers] = useState<AcceptedQueueSteer[]>([]);\n const pendingRef = useRef<Record<string, QueueMutationKind>>({});\n const readGeneration = useRef(0);\n const targetKeyRef = useRef(targetKey);\n const snapshotRef = useRef<SessionQueueSnapshot | null>(null);\n\n // Revoke the old target only when the new one commits. A concurrent render\n // may suspend while the previous target remains visible and interactive.\n useLayoutEffect(() => {\n if (targetKeyRef.current === targetKey) return;\n targetKeyRef.current = targetKey;\n readGeneration.current += 1;\n snapshotRef.current = null;\n pendingRef.current = {};\n setStateTargetKey(targetKey);\n setSnapshot(null);\n setLoading(enabled);\n setError(null);\n setMutationError(null);\n setPendingByTurn({});\n setAcceptedSteers([]);\n }, [enabled, targetKey]);\n\n useEffect(() => {\n if (acceptedSteers.length === 0 || options.events === undefined) return;\n const durablyStartedTurnIds = new Set(\n options.events.flatMap((event) =>\n event.type === \"turn.started\" && event.turnId ? [event.turnId] : [],\n ),\n );\n if (durablyStartedTurnIds.size === 0) return;\n // steer_requested can reach the browser before the timeline projection\n // that moves the queued user.message into chat. Keep this bridge through\n // physical cancellation; turn.started is the first boundary at which the\n // replacement timeline must already be visible.\n setAcceptedSteers((current) =>\n current.filter((steer) => !durablyStartedTurnIds.has(steer.turnId)),\n );\n }, [acceptedSteers.length, options.events]);\n\n const acceptSnapshot = useCallback(\n (ownedTargetKey: string, next: SessionQueueSnapshot | null): boolean => {\n if (targetKeyRef.current !== ownedTargetKey) return false;\n const current = snapshotRef.current;\n if (\n next &&\n current &&\n (next.version < current.version ||\n next.effectiveControl.controlVersion < current.effectiveControl.controlVersion)\n ) {\n return false;\n }\n snapshotRef.current = next;\n setStateTargetKey(ownedTargetKey);\n setSnapshot(next);\n return true;\n },\n [],\n );\n\n const load = useCallback(\n async (rejectOnFailure = false): Promise<void> => {\n if (!sessionId) return;\n const ownedTargetKey = `${workspaceId}\\u0000${sessionId}`;\n const ticket = ++readGeneration.current;\n try {\n const fetched = await client.getQueue(workspaceId, sessionId);\n if (targetKeyRef.current !== ownedTargetKey) return;\n const ownsLatestRead = ticket === readGeneration.current;\n if (rejectOnFailure) {\n const committed = acceptSnapshot(ownedTargetKey, fetched);\n if (!committed && !queueSnapshotCovers(snapshotRef.current, fetched)) {\n throw new TypeError(\"Queue reconciliation did not commit authoritative state\");\n }\n setError(null);\n if (ownsLatestRead) setLoading(false);\n } else if (ownsLatestRead) {\n acceptSnapshot(ownedTargetKey, fetched);\n setError(null);\n setLoading(false);\n }\n } catch (cause) {\n if (\n targetKeyRef.current === ownedTargetKey &&\n (ticket === readGeneration.current || rejectOnFailure)\n ) {\n setError(asError(cause));\n if (ticket === readGeneration.current) setLoading(false);\n }\n if (rejectOnFailure) throw cause;\n }\n },\n [client, workspaceId, sessionId, acceptSnapshot],\n );\n\n useEffect(() => {\n if (!enabled || !pageLive) {\n setLoading(false);\n return;\n }\n setLoading(true);\n const pollIntervalMs = options.pollIntervalMs;\n if (pollIntervalMs === undefined || pollIntervalMs <= 0) {\n void load();\n return () => {\n readGeneration.current += 1;\n };\n }\n let cancelled = false;\n let timer: ReturnType<typeof setTimeout> | null = null;\n const schedule = () => {\n if (cancelled) return;\n timer = setTimeout(() => {\n timer = null;\n void load().finally(schedule);\n }, pollIntervalMs);\n };\n void load().finally(schedule);\n return () => {\n cancelled = true;\n if (timer !== null) clearTimeout(timer);\n readGeneration.current += 1;\n };\n }, [load, enabled, pageLive, options.pollIntervalMs]);\n\n useEffect(() => {\n if (enabled && workspaceControlEvent) void load();\n }, [enabled, load, workspaceControlEvent]);\n useEffect(() => {\n if (!sessionId || !enabled) return;\n return registerSessionReconciler(sessionId, \"queue\", load);\n }, [enabled, load, registerSessionReconciler, sessionId]);\n\n const scheduleRefresh = useDebouncedCallback(() => void load());\n useSessionEventTrigger(\n client,\n workspaceId,\n sessionId,\n isTurnQueueEvent,\n scheduleRefresh,\n {\n enabled,\n ...(options.events !== undefined ? { events: options.events } : {}),\n },\n async () => await load(true),\n );\n\n const mutate = useCallback(\n async (\n turnId: string,\n kind: QueueMutationKind,\n command: (\n current: SessionQueueSnapshot,\n turn: SessionTurn,\n clientEventId: string,\n ) => Promise<SessionQueueMutationResponse>,\n ): Promise<SessionQueueMutationResponse | null> => {\n const ownedTargetKey = targetKey;\n if (!sessionId || targetKeyRef.current !== ownedTargetKey || pendingRef.current[turnId]) {\n return null;\n }\n const current = snapshotRef.current;\n const turn = current?.items.find((candidate) => candidate.id === turnId);\n if (!current || !turn) return null;\n pendingRef.current = { ...pendingRef.current, [turnId]: kind };\n setStateTargetKey(ownedTargetKey);\n setPendingByTurn(pendingRef.current);\n setMutationError(null);\n const clientEventId = operationKey();\n try {\n let result: SessionQueueMutationResponse;\n try {\n result = await command(current, turn, clientEventId);\n } catch (cause) {\n if (!isOutcomeUnknownError(cause)) throw cause;\n // Same-key replay is a fact check against the durable receipt. It\n // cannot duplicate the command even if the first response was lost.\n result = await command(current, turn, clientEventId);\n }\n if (targetKeyRef.current !== ownedTargetKey) return null;\n acceptSnapshot(ownedTargetKey, result.snapshot);\n return result;\n } catch (cause) {\n if (targetKeyRef.current === ownedTargetKey) {\n setMutationError(asError(cause));\n await load();\n }\n return null;\n } finally {\n if (targetKeyRef.current === ownedTargetKey && turnId in pendingRef.current) {\n const next = { ...pendingRef.current };\n delete next[turnId];\n pendingRef.current = next;\n setPendingByTurn(next);\n }\n }\n },\n [acceptSnapshot, load, sessionId, targetKey],\n );\n\n const moveTurn = useCallback(\n async (turnId: string, beforeTurnId: string | null): Promise<boolean> => {\n const result = await mutate(turnId, \"move\", (current, _turn, clientEventId) =>\n client.moveQueueItem(workspaceId, sessionId!, turnId, {\n clientEventId,\n expectedQueueVersion: current.version,\n beforeTurnId,\n }),\n );\n return result !== null;\n },\n [client, mutate, sessionId, workspaceId],\n );\n\n const editTurn = useCallback(\n async (\n turnId: string,\n edit: { expectedDraftRevision: number; replaceDraft: boolean },\n ): Promise<ComposerDraft | null> => {\n const result = await mutate(turnId, \"edit\", (_current, turn, clientEventId) =>\n client.editQueueItem(workspaceId, sessionId!, turnId, {\n clientEventId,\n expectedTurnVersion: turn.version,\n expectedDraftRevision: edit.expectedDraftRevision,\n replaceDraft: edit.replaceDraft,\n }),\n );\n return result?.draft ?? null;\n },\n [client, mutate, sessionId, workspaceId],\n );\n\n const steerTurn = useCallback(\n async (turnId: string): Promise<boolean> => {\n const ownedTargetKey = targetKey;\n const turn = snapshotRef.current?.items.find((candidate) => candidate.id === turnId);\n if (targetKeyRef.current !== ownedTargetKey) return false;\n if (!turn) {\n setMutationError(new Error(\"That queued prompt changed before Steer could be sent.\"));\n await load();\n return false;\n }\n const optimistic: AcceptedQueueSteer = {\n turnId: turn.id,\n triggerEventId: turn.triggerEventId,\n text: turn.prompt,\n annotations: turn.annotations ?? [],\n resources: turn.resources,\n tools: turn.tools,\n occurredAt: new Date().toISOString(),\n state: \"sending\",\n };\n setAcceptedSteers((current) => [\n ...current.filter((steer) => steer.turnId !== turnId),\n optimistic,\n ]);\n const result = await mutate(turnId, \"steer\", (current, queuedTurn, clientEventId) =>\n client.steerQueueItem(workspaceId, sessionId!, turnId, {\n clientEventId,\n expectedTurnVersion: queuedTurn.version,\n controlEtag: current.effectiveControl.controlEtag,\n }),\n );\n if (targetKeyRef.current !== ownedTargetKey) return false;\n // The active turn can finish while the operator clicks Steer. In that\n // race the queued prompt is atomically claimed before the steer command,\n // so the command conflicts but the user's prompt already advanced into\n // chat. Reconciled absence is success, not a scary unknown-outcome lie.\n const advancedWithoutSteer =\n result === null &&\n snapshotRef.current !== null &&\n !snapshotRef.current.items.some((candidate) => candidate.id === turnId);\n if (advancedWithoutSteer) {\n setMutationError(null);\n setAcceptedSteers((current) => current.filter((steer) => steer.turnId !== turnId));\n return true;\n }\n const accepted =\n result !== null ||\n snapshotRef.current?.items.some(\n (candidate) => candidate.id === turnId && candidate.metadata.delivery === \"steer\",\n ) === true;\n setAcceptedSteers((current) =>\n accepted\n ? current.map((steer) =>\n steer.turnId === turnId ? { ...steer, state: \"queued\" as const } : steer,\n )\n : current.filter((steer) => steer.turnId !== turnId),\n );\n return accepted;\n },\n [client, load, mutate, sessionId, targetKey, workspaceId],\n );\n\n const removeTurn = useCallback(\n async (turnId: string): Promise<boolean> => {\n const result = await mutate(turnId, \"delete\", (_current, turn, clientEventId) =>\n client.deleteQueueItem(workspaceId, sessionId!, turnId, {\n clientEventId,\n expectedTurnVersion: turn.version,\n reason: \"Deleted from the prompt queue\",\n }),\n );\n return result !== null;\n },\n [client, mutate, sessionId, workspaceId],\n );\n\n const identityMatches = stateTargetKey === targetKey;\n const visibleSnapshot = identityMatches ? snapshot : null;\n const visiblePendingByTurn = identityMatches ? pendingByTurn : EMPTY_PENDING_BY_TURN;\n const mutating = useMemo(\n () => Object.keys(visiblePendingByTurn).length > 0,\n [visiblePendingByTurn],\n );\n const mutationFor = useCallback(\n (turnId: string): QueueMutationKind | null => visiblePendingByTurn[turnId] ?? null,\n [visiblePendingByTurn],\n );\n\n return {\n snapshot: visibleSnapshot,\n queue: visibleSnapshot?.items ?? [],\n pendingInputs: visibleSnapshot?.pendingInputs ?? [],\n pendingInputAttachment: visibleSnapshot?.pendingInputAttachment ?? null,\n activePersonalConnections: visibleSnapshot?.activePersonalConnections ?? [],\n effectiveControl: visibleSnapshot?.effectiveControl ?? null,\n stoppingPreviousAttempt: visibleSnapshot?.stoppingPreviousAttempt ?? false,\n loading: identityMatches ? loading : enabled,\n error: identityMatches ? error : null,\n refresh: load,\n moveTurn,\n editTurn,\n steerTurn,\n removeTurn,\n pendingByTurn: visiblePendingByTurn,\n mutationFor,\n mutating,\n mutationError: identityMatches ? mutationError : null,\n clearMutationError: useCallback(() => {\n if (targetKeyRef.current === targetKey) setMutationError(null);\n }, [targetKey]),\n acceptedSteers: identityMatches ? acceptedSteers : [],\n };\n}\n\nfunction operationKey(): string {\n return globalThis.crypto.randomUUID();\n}\n\nfunction asError(cause: unknown): Error {\n return cause instanceof Error ? cause : new Error(String(cause));\n}\n\nfunction isOutcomeUnknownError(cause: unknown): boolean {\n return (\n typeof cause === \"object\" &&\n cause !== null &&\n (cause as { outcomeUnknown?: unknown }).outcomeUnknown === true\n );\n}\n","import { OpenGeniApiError, type SessionEvent, type SessionGoal } from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useEmbeddedGoal, type EmbeddedGoalClientOverride } from \"../session-context\";\nimport {\n useDebouncedCallback,\n useMutationRunner,\n usePageLiveActivity,\n useSessionEventTrigger,\n type SessionEventFeedOptions,\n} from \"./internal\";\n\n/** Event types that change the session goal (set/updated/completed/paused/...). */\nexport function isGoalEvent(event: Pick<SessionEvent, \"type\">): boolean {\n return event.type.startsWith(\"goal.\");\n}\n\n/**\n * Events that can change the server-authoritative continuation projection.\n * The projection is derived from durable turn, session, control, and system\n * update state, so those events refresh the goal without model polling.\n */\nexport function isGoalRefreshEvent(event: Pick<SessionEvent, \"type\">): boolean {\n const type = event.type;\n return (\n isGoalEvent(event) ||\n type.startsWith(\"turn.\") ||\n type.startsWith(\"session.\") ||\n type.startsWith(\"system.update.\") ||\n type.startsWith(\"workspace.inference.\") ||\n type.startsWith(\"user.\")\n );\n}\n\nexport type UseGoalOptions = EmbeddedGoalClientOverride &\n SessionEventFeedOptions & {\n /** Optional safety-net polling (ms). Off by default — event refreshes drive updates. */\n pollIntervalMs?: number | undefined;\n };\n\nexport type UseGoalResult = {\n /** The session goal, or null when the session has none. */\n goal: SessionGoal | null;\n /** Convenience flags over `goal.status`. */\n isActive: boolean;\n isPaused: boolean;\n isCompleted: boolean;\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n /** Pause the goal loop (PATCH status=paused). */\n pause: (rationale?: string) => Promise<SessionGoal | null>;\n /** Resume a paused goal: resets counters and re-arms continuations. */\n resume: () => Promise<SessionGoal | null>;\n /** Clear the session goal; goal-less sessions remain a successful no-op. */\n clearGoal: () => Promise<void>;\n /** Alias for `clearGoal`. */\n deleteGoal: () => Promise<void>;\n /** True while a pause/resume/clear is in flight. */\n updating: boolean;\n mutationError: Error | null;\n clearMutationError: () => void;\n};\n\n/**\n * The session's goal: state, the autonomy counters (`autoContinuations`,\n * `noProgressStreak`), and pause/resume control. A goal-less session yields\n * `goal: null` (the 404 is absorbed). Live-updates on goal, turn, session,\n * control, and system-update events — pass `options.events` from\n * `useSessionEvents` to reuse its stream.\n */\nexport function useGoal(\n sessionId: string | null | undefined,\n options: UseGoalOptions = {},\n): UseGoalResult {\n const { client, workspaceId } = useEmbeddedGoal(options);\n const enabled = (options.enabled ?? true) && Boolean(sessionId);\n const sharedEvents = options.events;\n const sharedFeed = sharedEvents !== undefined;\n const pageLive = usePageLiveActivity();\n const [goal, setGoal] = useState<SessionGoal | null>(null);\n const [loading, setLoading] = useState(enabled);\n const [error, setError] = useState<Error | null>(null);\n const { run, mutating, mutationError, clearMutationError } = useMutationRunner();\n const generation = useRef(0);\n const targetKeyRef = useRef<string | null>(null);\n\n const load = useCallback(async (): Promise<void> => {\n if (!sessionId) {\n return;\n }\n const ticket = ++generation.current;\n try {\n const fetched = await client.getGoal(workspaceId, sessionId);\n if (ticket === generation.current) {\n setGoal(fetched);\n setError(null);\n setLoading(false);\n }\n } catch (cause) {\n if (ticket !== generation.current) {\n return;\n }\n if (cause instanceof OpenGeniApiError && cause.status === 404) {\n // No goal is a normal state, not an error.\n setGoal(null);\n setError(null);\n } else {\n setError(cause instanceof Error ? cause : new Error(String(cause)));\n }\n setLoading(false);\n }\n }, [client, workspaceId, sessionId]);\n\n useEffect(() => {\n const targetKey = `${workspaceId} ${sessionId ?? \"\"}`;\n if (targetKeyRef.current !== targetKey) {\n targetKeyRef.current = targetKey;\n setGoal(null);\n setError(null);\n }\n if (!enabled || !pageLive) {\n setLoading(false);\n return;\n }\n if (sharedFeed) {\n setLoading(false);\n return () => {\n generation.current += 1;\n };\n }\n setLoading(true);\n const pollIntervalMs = options.pollIntervalMs;\n if (pollIntervalMs === undefined || pollIntervalMs <= 0) {\n void load();\n return () => {\n generation.current += 1;\n };\n }\n let cancelled = false;\n let timer: ReturnType<typeof setTimeout> | null = null;\n const schedule = () => {\n if (cancelled) return;\n timer = setTimeout(() => {\n timer = null;\n void load().finally(schedule);\n }, pollIntervalMs);\n };\n void load().finally(schedule);\n return () => {\n cancelled = true;\n if (timer !== null) clearTimeout(timer);\n generation.current += 1;\n };\n }, [load, enabled, pageLive, workspaceId, sessionId, options.pollIntervalMs, sharedFeed]);\n\n const scheduleRefresh = useDebouncedCallback(() => void load());\n useSessionEventTrigger(client, workspaceId, sessionId, isGoalRefreshEvent, scheduleRefresh, {\n enabled,\n ...(sharedEvents !== undefined ? { events: sharedEvents } : {}),\n });\n\n const pause = useCallback(\n async (rationale?: string): Promise<SessionGoal | null> => {\n if (!sessionId) {\n return null;\n }\n const result = await run(() =>\n client.updateGoal(workspaceId, sessionId, {\n status: \"paused\",\n ...(rationale !== undefined ? { rationale } : {}),\n }),\n );\n if (result) {\n setGoal(result);\n }\n return result;\n },\n [client, workspaceId, sessionId, run],\n );\n\n const resume = useCallback(async (): Promise<SessionGoal | null> => {\n if (!sessionId) {\n return null;\n }\n const result = await run(() => client.updateGoal(workspaceId, sessionId, { status: \"active\" }));\n if (result) {\n setGoal(result);\n }\n return result;\n }, [client, workspaceId, sessionId, run]);\n\n const clearGoal = useCallback(async (): Promise<void> => {\n if (!sessionId) {\n return;\n }\n // deleteGoal resolves void, so distinguish success (a truthy sentinel) from\n // mutation.run's null-on-failure. Only a SUCCESSFUL delete hides the goal:\n // a failed one leaves the pill up so its mutationError renders. And invalidate\n // any in-flight load first so a slower getGoal started before the delete can't\n // commit and repopulate the just-cleared goal.\n const ok = await run(async () => {\n await client.deleteGoal(workspaceId, sessionId);\n return true as const;\n });\n if (ok) {\n generation.current += 1;\n setGoal(null);\n setError(null);\n }\n }, [client, workspaceId, sessionId, run]);\n\n return {\n goal,\n isActive: goal?.status === \"active\",\n isPaused: goal?.status === \"paused\",\n isCompleted: goal?.status === \"completed\",\n loading,\n error,\n refresh: load,\n pause,\n resume,\n clearGoal,\n deleteGoal: clearGoal,\n updating: mutating,\n mutationError,\n clearMutationError,\n };\n}\n","import type { SessionControlResponse, SessionEvent } from \"@opengeni/sdk\";\nimport { useCallback, useLayoutEffect, useRef } from \"react\";\nimport { useEmbeddedSession, type EmbeddedSessionClientOverride } from \"../session-context\";\nimport { useMutationRunner } from \"./internal\";\n\nexport type UseSessionControlOptions = EmbeddedSessionClientOverride;\n\nexport type UseSessionControlResult = {\n pause: (reason?: string) => Promise<SessionControlResponse | null>;\n resume: (reason?: string) => Promise<SessionControlResponse | null>;\n controlling: boolean;\n /** Approve a pending `requires_action` approval. */\n approve: (approvalId: string, message?: string) => Promise<SessionEvent | null>;\n /** Reject a pending `requires_action` approval. */\n reject: (approvalId: string, message?: string) => Promise<SessionEvent | null>;\n /** True while an approval decision is in flight. */\n responding: boolean;\n error: Error | null;\n clearError: () => void;\n};\n\n/**\n * Session pause/resume and approval decisions. Pair with\n * `useSessionEvents` (for `session.requiresAction` payloads carrying the\n * `approvalId`) to render an approval bar.\n */\nexport function useSessionControl(\n sessionId: string | null | undefined,\n options: UseSessionControlOptions = {},\n): UseSessionControlResult {\n const { client, workspaceId } = useEmbeddedSession(options);\n const approvalTargetKey = `${workspaceId}\\u0000${sessionId ?? \"\"}`;\n const pendingApproval = useRef<{\n targetKey: string;\n decisionKey: string;\n clientEventId: string;\n } | null>(null);\n useLayoutEffect(() => {\n if (pendingApproval.current?.targetKey !== approvalTargetKey) {\n pendingApproval.current = null;\n }\n }, [approvalTargetKey]);\n const {\n run: runControl,\n mutating: controlling,\n mutationError: controlError,\n clearMutationError: clearControlError,\n } = useMutationRunner(approvalTargetKey);\n const {\n run: runApproval,\n mutating: responding,\n mutationError: approvalError,\n clearMutationError: clearApprovalError,\n } = useMutationRunner(approvalTargetKey);\n\n const pause = useCallback(\n async (reason?: string): Promise<SessionControlResponse | null> => {\n if (!sessionId) {\n return null;\n }\n return await runControl(() =>\n client.pauseSession(workspaceId, sessionId, reason !== undefined ? { reason } : {}),\n );\n },\n [client, workspaceId, sessionId, runControl],\n );\n\n const resume = useCallback(\n async (reason?: string): Promise<SessionControlResponse | null> => {\n if (!sessionId) return null;\n return await runControl(() =>\n client.resumeSession(workspaceId, sessionId, reason !== undefined ? { reason } : {}),\n );\n },\n [client, workspaceId, sessionId, runControl],\n );\n\n const decide = useCallback(\n async (\n approvalId: string,\n decision: \"approve\" | \"reject\",\n message?: string,\n ): Promise<SessionEvent | null> => {\n if (!sessionId) {\n return null;\n }\n const decisionKey = JSON.stringify([approvalId, decision, message ?? null]);\n if (pendingApproval.current?.decisionKey !== decisionKey) {\n pendingApproval.current = {\n targetKey: approvalTargetKey,\n decisionKey,\n clientEventId: crypto.randomUUID(),\n };\n }\n const clientEventId = pendingApproval.current.clientEventId;\n const accepted = await runApproval(() =>\n client.sendApprovalDecision(workspaceId, sessionId, {\n approvalId,\n decision,\n ...(message !== undefined ? { message } : {}),\n clientEventId,\n }),\n );\n if (\n accepted !== null &&\n pendingApproval.current?.targetKey === approvalTargetKey &&\n pendingApproval.current.clientEventId === clientEventId\n ) {\n pendingApproval.current = null;\n }\n return accepted;\n },\n [approvalTargetKey, client, workspaceId, sessionId, runApproval],\n );\n\n const approve = useCallback(\n async (approvalId: string, message?: string) => await decide(approvalId, \"approve\", message),\n [decide],\n );\n const reject = useCallback(\n async (approvalId: string, message?: string) => await decide(approvalId, \"reject\", message),\n [decide],\n );\n\n const error = approvalError ?? controlError;\n const clearError = useCallback(() => {\n clearControlError();\n clearApprovalError();\n }, [clearControlError, clearApprovalError]);\n\n return {\n pause,\n resume,\n controlling,\n approve,\n reject,\n responding,\n error,\n clearError,\n };\n}\n","import type {\n SessionEvent,\n SessionMcpApprovalPolicy,\n SessionMcpServerMetadata,\n UpdateSessionMcpApprovalPolicyResponse,\n} from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport {\n useEmbeddedSessionMcpApprovalPolicy,\n type EmbeddedSessionMcpApprovalPolicyClientOverride,\n} from \"../session-context\";\nimport {\n useDebouncedCallback,\n useMutationRunner,\n usePolledValue,\n useSessionEventTrigger,\n type SessionEventFeedOptions,\n} from \"./internal\";\n\nexport function isSessionMcpApprovalPolicyEvent(\n event: Pick<SessionEvent, \"type\" | \"payload\">,\n serverId?: string,\n): boolean {\n if (event.type !== \"session.mcp.approval_policy.updated\") {\n return false;\n }\n if (serverId === undefined) {\n return true;\n }\n const payload = event.payload as { serverId?: unknown } | null;\n return payload?.serverId === serverId;\n}\n\nexport type UseSessionMcpApprovalPolicyOptions = EmbeddedSessionMcpApprovalPolicyClientOverride &\n SessionEventFeedOptions & {\n /** Optional safety-net polling (ms). Off by default; policy events drive refreshes. */\n pollIntervalMs?: number | undefined;\n };\n\nexport type UseSessionMcpApprovalPolicyResult = {\n server: SessionMcpServerMetadata | null;\n policy: SessionMcpApprovalPolicy | null;\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n update: (\n policy: SessionMcpApprovalPolicy,\n ) => Promise<UpdateSessionMcpApprovalPolicyResponse | null>;\n updating: boolean;\n clearError: () => void;\n};\n\n/**\n * Read and update one existing session MCP server's approval policy. Updates\n * become effective for the next claimed attempt; current work is unchanged.\n */\nexport function useSessionMcpApprovalPolicy(\n sessionId: string | null | undefined,\n serverId: string | null | undefined,\n options: UseSessionMcpApprovalPolicyOptions = {},\n): UseSessionMcpApprovalPolicyResult {\n const { client, workspaceId } = useEmbeddedSessionMcpApprovalPolicy(options);\n const enabled = (options.enabled ?? true) && Boolean(sessionId && serverId);\n const [override, setOverride] = useState<SessionMcpServerMetadata | null>(null);\n const targetKey = `${workspaceId}\\u0000${sessionId ?? \"\"}\\u0000${serverId ?? \"\"}`;\n const authoritativeGeneration = useRef(0);\n const mutationIdentity = useMemo(() => ({ client, targetKey }), [client, targetKey]);\n const { run, mutating, mutationError, clearMutationError } = useMutationRunner(mutationIdentity);\n\n useLayoutEffect(() => {\n authoritativeGeneration.current += 1;\n setOverride(null);\n }, [client, targetKey]);\n\n type PolicyRead = {\n targetKey: string;\n generation: number;\n server: SessionMcpServerMetadata | null;\n };\n const load = useCallback(async (): Promise<PolicyRead> => {\n const generation = authoritativeGeneration.current;\n if (!sessionId || !serverId) {\n return { targetKey, generation, server: null };\n }\n const session = await client.getSession(workspaceId, sessionId);\n return {\n targetKey,\n generation,\n server: session.mcpServers.find((server) => server.id === serverId) ?? null,\n };\n }, [client, serverId, sessionId, targetKey, workspaceId]);\n const {\n data,\n loading,\n error: loadError,\n refresh,\n } = usePolledValue(load, {\n enabled,\n pollIntervalMs: options.pollIntervalMs,\n });\n useEffect(() => {\n if (data?.targetKey === targetKey && data.generation === authoritativeGeneration.current) {\n setOverride(null);\n }\n }, [data, targetKey]);\n\n const scheduleRefresh = useDebouncedCallback(() => void refresh());\n const matchesPolicyEvent = useCallback(\n (event: Pick<SessionEvent, \"type\" | \"payload\">) =>\n isSessionMcpApprovalPolicyEvent(event, serverId ?? undefined),\n [serverId],\n );\n useSessionEventTrigger(\n client,\n workspaceId,\n sessionId,\n matchesPolicyEvent,\n scheduleRefresh,\n {\n enabled,\n ...(options.events !== undefined ? { events: options.events } : {}),\n },\n async () => await refresh(),\n );\n\n const update = useCallback(\n async (\n policy: SessionMcpApprovalPolicy,\n ): Promise<UpdateSessionMcpApprovalPolicyResponse | null> => {\n if (!sessionId || !serverId) {\n return null;\n }\n const response = await run(() =>\n client.updateSessionMcpApprovalPolicy(workspaceId, sessionId, serverId, {\n requireApproval: policy,\n }),\n );\n if (response) {\n authoritativeGeneration.current += 1;\n setOverride(response.server);\n void refresh();\n }\n return response;\n },\n [client, refresh, run, serverId, sessionId, workspaceId],\n );\n\n const server = override ?? data?.server ?? null;\n return {\n server,\n policy: server?.requireApproval ?? null,\n loading,\n error: mutationError ?? loadError,\n refresh: async () => {\n await refresh();\n },\n update,\n updating: mutating,\n clearError: clearMutationError,\n };\n}\n","import type { SessionEvent, SessionLineageResponse } from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useRef } from \"react\";\nimport {\n useEmbeddedSessionLineage,\n type EmbeddedSessionLineageClientOverride,\n} from \"../session-context\";\nimport { useDebouncedCallback, usePolledValue, useSessionEventTrigger } from \"./internal\";\n\nexport type UseSessionLineageOptions = EmbeddedSessionLineageClientOverride & {\n events?: SessionEvent[] | undefined;\n /** Refresh interval (ms). Off by default. */\n pollIntervalMs?: number | undefined;\n enabled?: boolean | undefined;\n /** Optional shared causal clock invoked when each network read starts. */\n beginRead?: (() => number) | undefined;\n};\n\nexport type UseSessionLineageResult = {\n lineage: SessionLineageResponse | null;\n loading: boolean;\n error: Error | null;\n /** Causal generation captured when the accepted lineage read started. */\n readGeneration: number;\n refresh: () => Promise<void>;\n};\n\nexport function isLineageRefreshEvent(event: SessionEvent): boolean {\n if (event.type === \"session.status.changed\" || event.type === \"session.created\") {\n return true;\n }\n // A child's creation never appears on the PARENT's stream as session.created —\n // the parent sees its own spawn as an agent.toolCall.* for session_create.\n // Created events are handled separately so they can refresh immediately and\n // once after the child row has had time to commit.\n if (event.type === \"agent.toolCall.output\") {\n const payload = event.payload as { name?: unknown; toolName?: unknown } | null | undefined;\n const name =\n typeof payload?.name === \"string\"\n ? payload.name\n : typeof payload?.toolName === \"string\"\n ? payload.toolName\n : \"\";\n return name === \"session_create\" || name.endsWith(\"__session_create\");\n }\n return false;\n}\n\nfunction isSessionCreateToolCallCreated(event: SessionEvent): boolean {\n if (event.type !== \"agent.toolCall.created\") {\n return false;\n }\n const payload = event.payload as { name?: unknown; toolName?: unknown } | null | undefined;\n const name =\n typeof payload?.name === \"string\"\n ? payload.name\n : typeof payload?.toolName === \"string\"\n ? payload.toolName\n : \"\";\n return name === \"session_create\" || name.endsWith(\"__session_create\");\n}\n\n/** Read the ancestors + descendant tree for one session. Data-only; no UI state. */\nexport function useSessionLineage(\n sessionId: string | null | undefined,\n options: UseSessionLineageOptions = {},\n): UseSessionLineageResult {\n const { client, workspaceId, workspaceControlEvent, registerSessionReconciler } =\n useEmbeddedSessionLineage(options);\n const enabled = (options.enabled ?? true) && Boolean(sessionId);\n const nextReadGeneration = useRef(0);\n const beginRead = options.beginRead;\n const load = useCallback(async () => {\n if (!sessionId) {\n return {\n lineage: { ancestors: [], children: [], truncated: false },\n readGeneration: 0,\n };\n }\n let readGeneration = 0;\n const lineage = await client.getSessionLineage(workspaceId, sessionId, {\n onRequestStart: (sharedReadGeneration) => {\n readGeneration = sharedReadGeneration ?? beginRead?.() ?? ++nextReadGeneration.current;\n },\n });\n return {\n lineage,\n readGeneration,\n };\n }, [beginRead, client, workspaceId, sessionId]);\n const state = usePolledValue(load, { pollIntervalMs: options.pollIntervalMs, enabled });\n const refresh = state.refresh;\n useEffect(() => {\n if (enabled && workspaceControlEvent) void refresh();\n }, [enabled, refresh, workspaceControlEvent]);\n useEffect(() => {\n if (!sessionId || !enabled) return;\n return registerSessionReconciler(sessionId, \"lineage\", refresh);\n }, [enabled, refresh, registerSessionReconciler, sessionId]);\n const refreshSoon = useDebouncedCallback(() => void refresh(), 150);\n const delayedChildRefreshRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n // Clear a pending delayed refresh on session/workspace SWITCH (not just\n // unmount): otherwise a timer scheduled for the previous session can fire\n // ~2.5s later and commit that session's lineage onto the new one.\n useEffect(() => {\n return () => {\n if (delayedChildRefreshRef.current !== null) {\n clearTimeout(delayedChildRefreshRef.current);\n delayedChildRefreshRef.current = null;\n }\n };\n }, [sessionId, workspaceId]);\n const refreshAfterChildCreate = useCallback(() => {\n void refresh();\n if (delayedChildRefreshRef.current !== null) {\n clearTimeout(delayedChildRefreshRef.current);\n }\n delayedChildRefreshRef.current = setTimeout(() => {\n delayedChildRefreshRef.current = null;\n void refresh();\n }, 2500);\n }, [refresh]);\n useSessionEventTrigger(\n client,\n workspaceId,\n sessionId,\n isLineageRefreshEvent,\n refreshSoon,\n // SHARED-FEED ONLY: without a caller-provided events log the trigger would\n // open its OWN streamEvents tail — a second live SSE connection next to the\n // session route's useSessionEvents. A caller with no feed opts into polling\n // (pollIntervalMs), never a duplicate stream.\n { events: options.events, enabled: enabled && options.events !== undefined },\n );\n useSessionEventTrigger(\n client,\n workspaceId,\n sessionId,\n isSessionCreateToolCallCreated,\n refreshAfterChildCreate,\n { events: options.events, enabled: enabled && options.events !== undefined },\n );\n return {\n lineage: state.data?.lineage ?? null,\n loading: state.loading,\n error: state.error,\n readGeneration: state.data?.readGeneration ?? 0,\n refresh,\n };\n}\n","import type { SessionEvent } from \"@opengeni/sdk\";\n\n/* ----------------------------------------------------------------------------\n Pending-approvals projection\n\n `session.requiresAction` events live forever in the durable log, so a\n console that replays the log from sequence 0 must not render every\n historical approval as actionable. `projectPendingApprovals` folds the\n ordered event log into the approvals that are still undecided *now*:\n\n - `session.requiresAction` replaces the pending set with the payload's\n approvals (the producer always emits the full currently-pending set, so\n re-emission after a worker re-dispatch cannot duplicate cards);\n - `user.approvalDecision` subtracts the decided approval;\n - the owning turn finishing (`turn.completed`/`turn.failed`/\n `turn.cancelled`) clears the set — whatever was pending died with the\n turn. A `turn.cancelled` for a *different* turn (deleting a queued turn\n while the session waits on an approval) leaves the set alone.\n\n Pure function — same events in, same approvals out — so approve-then-reload\n projects to an empty set instead of a zombie Approve button.\n -------------------------------------------------------------------------- */\n\nexport type PendingApproval = {\n /** The id to send back via `user.approvalDecision` (`approvalId`). */\n id: string;\n /** Tool/function name awaiting the decision. */\n name: string;\n arguments?: unknown;\n /** The raw approval entry from the `session.requiresAction` payload. */\n raw?: unknown;\n};\n\n/** The approvals carried by one `session.requiresAction` payload. */\nexport function approvalsFromRequiresAction(payload: unknown): PendingApproval[] {\n const approvals =\n payload && typeof payload === \"object\"\n ? (payload as { approvals?: unknown }).approvals\n : undefined;\n if (!Array.isArray(approvals)) {\n return [];\n }\n return approvals.map((approval, index) => {\n const raw = (approval && typeof approval === \"object\" ? approval : {}) as Record<\n string,\n unknown\n >;\n const rawItem =\n raw.rawItem && typeof raw.rawItem === \"object\"\n ? (raw.rawItem as Record<string, unknown>)\n : {};\n return {\n // Mirror the runtime's canonical interruption identity before retaining\n // the legacy top-level callId fallback for already-normalized payloads.\n id: String(rawItem.callId ?? rawItem.id ?? raw.id ?? raw.callId ?? raw.name ?? index),\n name: String(raw.name ?? raw.toolName ?? rawItem.name ?? \"approval\"),\n arguments: raw.arguments ?? rawItem.arguments,\n raw: approval,\n };\n });\n}\n\n/** The approvals still awaiting a decision after replaying `events` in order. */\nexport function projectPendingApprovals(events: SessionEvent[]): PendingApproval[] {\n let pending: PendingApproval[] = [];\n let owningTurnId: string | null = null;\n for (const event of events) {\n switch (event.type) {\n case \"session.requiresAction\": {\n pending = approvalsFromRequiresAction(event.payload);\n owningTurnId = event.turnId ?? null;\n break;\n }\n case \"user.approvalDecision\": {\n const payload =\n event.payload && typeof event.payload === \"object\"\n ? (event.payload as { approvalId?: unknown })\n : {};\n if (typeof payload.approvalId === \"string\") {\n pending = pending.filter((approval) => approval.id !== payload.approvalId);\n }\n break;\n }\n case \"turn.completed\":\n case \"turn.failed\":\n case \"turn.cancelled\": {\n // Scope clearing to the turn that raised the approvals when both\n // sides carry a turn id; clear conservatively when either is unknown.\n if (owningTurnId === null || event.turnId == null || event.turnId === owningTurnId) {\n pending = [];\n owningTurnId = null;\n }\n break;\n }\n default:\n break;\n }\n }\n return pending;\n}\n","import type { HumanInputQuestion, SessionEvent } from \"@opengeni/sdk\";\n\n/** Minimal actionable request shape available from the durable event log. */\nexport type PendingHumanInputRequest = {\n id: string;\n turnId: string | null;\n questions: HumanInputQuestion[];\n allowSkip: boolean;\n expiresAt: string | null;\n};\n\n/** Parse one generic `session.humanInput.requested` event defensively. */\nexport function humanInputRequestFromEvent(\n event: Pick<SessionEvent, \"type\" | \"payload\" | \"turnId\">,\n): PendingHumanInputRequest | null {\n if (event.type !== \"session.humanInput.requested\" || !isRecord(event.payload)) return null;\n const request = event.payload.request;\n if (!isRecord(request) || typeof request.id !== \"string\" || !Array.isArray(request.questions)) {\n return null;\n }\n return {\n id: request.id,\n turnId: event.turnId ?? null,\n questions: request.questions as HumanInputQuestion[],\n allowSkip: request.allowSkip === true,\n expiresAt: typeof request.expiresAt === \"string\" ? request.expiresAt : null,\n };\n}\n\n/**\n * Fold a durable event log into the structured requests that are actionable\n * now. Responses remove one request; a terminal owning turn clears any\n * unresolved requests that died with it. Replaying history cannot resurrect a\n * previously answered card.\n */\nexport function projectPendingHumanInputRequests(\n events: SessionEvent[],\n): PendingHumanInputRequest[] {\n const pending = new Map<string, PendingHumanInputRequest>();\n for (const event of events) {\n const requested = humanInputRequestFromEvent(event);\n if (requested) {\n pending.set(requested.id, requested);\n continue;\n }\n if (event.type === \"user.humanInputResponse\" && isRecord(event.payload)) {\n if (typeof event.payload.requestId === \"string\") pending.delete(event.payload.requestId);\n continue;\n }\n if (\n event.type === \"turn.completed\" ||\n event.type === \"turn.failed\" ||\n event.type === \"turn.cancelled\"\n ) {\n for (const [id, request] of pending) {\n if (\n request.turnId === null ||\n event.turnId === null ||\n event.turnId === undefined ||\n request.turnId === event.turnId\n ) {\n pending.delete(id);\n }\n }\n }\n }\n return [...pending.values()];\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n","import type {\n SessionEvent,\n SessionHumanInputRequest,\n SubmitHumanInputResponseRequest,\n} from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n useEmbeddedHumanInputSession,\n type EmbeddedHumanInputClientOverride,\n} from \"../session-context\";\nimport {\n useDebouncedCallback,\n useMutationRunner,\n usePolledValue,\n useSessionEventTrigger,\n type SessionEventFeedOptions,\n} from \"./internal\";\n\n/** Events that can create, settle, or invalidate an actionable request. */\nexport function isHumanInputEvent(event: Pick<SessionEvent, \"type\">): boolean {\n return (\n event.type === \"session.humanInput.requested\" ||\n event.type === \"user.humanInputResponse\" ||\n event.type === \"turn.completed\" ||\n event.type === \"turn.failed\" ||\n event.type === \"turn.cancelled\"\n );\n}\n\nexport type UseHumanInputRequestsOptions = EmbeddedHumanInputClientOverride &\n SessionEventFeedOptions & {\n /** Optional safety-net polling. Durable events drive refresh by default. */\n pollIntervalMs?: number | undefined;\n };\n\nexport type UseHumanInputRequestsResult = {\n requests: SessionHumanInputRequest[];\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n respond: (\n requestId: string,\n response: SubmitHumanInputResponseRequest,\n ) => Promise<SessionEvent | null>;\n respondingRequestId: string | null;\n mutationError: Error | null;\n clearMutationError: () => void;\n};\n\n/**\n * Authoritative structured-human-input hook. The server's pending-request\n * table is the read model; events only trigger reconciliation. This lets an\n * embedded host use the same primitive with a shared event feed or its own SDK\n * proxy without rebuilding request lifecycle logic.\n */\nexport function useHumanInputRequests(\n sessionId: string | null | undefined,\n options: UseHumanInputRequestsOptions = {},\n): UseHumanInputRequestsResult {\n const { client, workspaceId, registerSessionReconciler } = useEmbeddedHumanInputSession(options);\n const enabled = (options.enabled ?? true) && Boolean(sessionId);\n const load = useCallback(\n async (): Promise<SessionHumanInputRequest[]> =>\n sessionId\n ? await client.listHumanInputRequests(workspaceId, sessionId, { status: \"pending\" })\n : [],\n [client, sessionId, workspaceId],\n );\n const state = usePolledValue(load, {\n enabled,\n pollIntervalMs: options.pollIntervalMs,\n });\n const mutation = useMutationRunner(`${workspaceId}\\u0000${sessionId ?? \"\"}`);\n const [respondingRequestId, setRespondingRequestId] = useState<string | null>(null);\n const respondingRequestRef = useRef<string | null>(null);\n\n useEffect(() => {\n respondingRequestRef.current = null;\n setRespondingRequestId(null);\n }, [sessionId, workspaceId]);\n useEffect(() => {\n if (!sessionId || !enabled) return;\n return registerSessionReconciler(sessionId, \"human-input\", state.refresh);\n }, [enabled, registerSessionReconciler, sessionId, state.refresh]);\n\n const scheduleRefresh = useDebouncedCallback(() => void state.refresh());\n useSessionEventTrigger(client, workspaceId, sessionId, isHumanInputEvent, scheduleRefresh, {\n enabled,\n ...(options.events !== undefined ? { events: options.events } : {}),\n });\n\n const respond = useCallback(\n async (\n requestId: string,\n response: SubmitHumanInputResponseRequest,\n ): Promise<SessionEvent | null> => {\n if (!sessionId || respondingRequestRef.current !== null) return null;\n respondingRequestRef.current = requestId;\n setRespondingRequestId(requestId);\n try {\n const event = await mutation.run(() =>\n client.submitHumanInputResponse(workspaceId, sessionId, requestId, response, {\n clientEventId: globalThis.crypto.randomUUID(),\n }),\n );\n if (event) await state.refresh();\n return event;\n } finally {\n if (respondingRequestRef.current === requestId) {\n respondingRequestRef.current = null;\n setRespondingRequestId(null);\n }\n }\n },\n [client, mutation, sessionId, state, workspaceId],\n );\n\n return {\n requests: [...(state.data ?? [])].sort(\n (left, right) =>\n left.createdAt.localeCompare(right.createdAt) || left.id.localeCompare(right.id),\n ),\n loading: state.loading,\n error: state.error,\n refresh: state.refresh,\n respond,\n respondingRequestId,\n mutationError: mutation.mutationError,\n clearMutationError: mutation.clearMutationError,\n };\n}\n"],"mappings":"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","names":["readGeneration","useCallback","useEffect","useMemo","useRef","useState","useState","useRef","useEffect","useCallback","useMemo","useCallback","useEffect","useRef","useState","useState","useRef","useCallback","useEffect","useCallback","useEffect","useMemo","useRef","useState","useState","useRef","useEffect","useCallback","useMemo","useCallback","useEffect","useRef","useState","useState","useRef","useCallback","useEffect","useCallback","useLayoutEffect","useRef","useRef","useLayoutEffect","useCallback","useCallback","useEffect","useLayoutEffect","useMemo","useRef","useState","useState","useRef","useMemo","useLayoutEffect","useCallback","server","useEffect","useCallback","useEffect","useRef","useRef","useCallback","useEffect","useCallback","useEffect","useRef","useState","useCallback","useState","useRef","useEffect"]}
@@ -1,90 +0,0 @@
1
- import {
2
- usePortalTokenSource,
3
- usePortalTokenStyle
4
- } from "./chunk-VZTQ73XT.js";
5
- import {
6
- cn
7
- } from "./chunk-22KP6LR5.js";
8
-
9
- // src/components/tooltip.tsx
10
- import { Tooltip as TooltipPrimitive } from "radix-ui";
11
- import { createContext, useContext } from "react";
12
- import { jsx, jsxs } from "react/jsx-runtime";
13
- var TooltipSourceContext = createContext(null);
14
- function TooltipProvider({
15
- delayDuration = 300,
16
- ...props
17
- }) {
18
- return /* @__PURE__ */ jsx(TooltipPrimitive.Provider, { delayDuration, ...props });
19
- }
20
- function Tooltip({ children, ...props }) {
21
- const source = usePortalTokenSource();
22
- return /* @__PURE__ */ jsx(TooltipSourceContext.Provider, { value: source, children: /* @__PURE__ */ jsx(TooltipPrimitive.Root, { "data-slot": "tooltip", ...props, children }) });
23
- }
24
- function TooltipTrigger({
25
- asChild = true,
26
- ...props
27
- }) {
28
- const sourceRef = useContext(TooltipSourceContext);
29
- return /* @__PURE__ */ jsx(
30
- TooltipPrimitive.Trigger,
31
- {
32
- "data-slot": "tooltip-trigger",
33
- asChild,
34
- ref: (node) => {
35
- sourceRef?.ref(node);
36
- },
37
- ...props
38
- }
39
- );
40
- }
41
- var tooltipSurfaceStyle = {
42
- backgroundColor: "var(--og-color-fg)",
43
- color: "var(--og-color-bg)"
44
- };
45
- function TooltipContent({
46
- className,
47
- sideOffset = 6,
48
- children,
49
- style,
50
- ...props
51
- }) {
52
- const source = useContext(TooltipSourceContext);
53
- const portalStyle = usePortalTokenStyle(source?.source ?? null);
54
- return /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
55
- TooltipPrimitive.Content,
56
- {
57
- "data-slot": "tooltip-content",
58
- sideOffset,
59
- className: cn(
60
- "og-root z-50 w-fit max-w-xs origin-[var(--radix-tooltip-content-transform-origin)]",
61
- "rounded-og-md px-2.5 py-1.5 text-og-xs leading-4 text-balance shadow-og-md",
62
- "animate-og-enter data-[state=closed]:opacity-0 data-[state=closed]:transition-opacity",
63
- className
64
- ),
65
- style: { ...portalStyle, ...tooltipSurfaceStyle, ...style },
66
- ...props,
67
- children: [
68
- children,
69
- /* @__PURE__ */ jsx(
70
- TooltipPrimitive.Arrow,
71
- {
72
- className: "z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]",
73
- style: {
74
- backgroundColor: "var(--og-color-fg)",
75
- fill: "var(--og-color-fg)"
76
- }
77
- }
78
- )
79
- ]
80
- }
81
- ) });
82
- }
83
-
84
- export {
85
- TooltipProvider,
86
- Tooltip,
87
- TooltipTrigger,
88
- TooltipContent
89
- };
90
- //# sourceMappingURL=chunk-FK6VG4LL.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/tooltip.tsx"],"sourcesContent":["/**\n * Token-styled Radix tooltip — SDK counterpart to apps/web `components/ui/tooltip`.\n * Portals copy `--og-*` tokens so embeds keep the host theme outside `.og-root`.\n *\n * Background/foreground are applied as inline styles (not only Tailwind\n * utilities): `.og-root` sets `color: var(--og-color-fg)` after utilities in the\n * consumer CSS cascade, which would otherwise paint light-on-light inverted\n * tips and look like a blank white bubble.\n */\nimport { Tooltip as TooltipPrimitive } from \"radix-ui\";\nimport { createContext, useContext, type ComponentProps, type CSSProperties } from \"react\";\n\nimport { cn } from \"../lib/cn\";\nimport { usePortalTokenSource, usePortalTokenStyle } from \"../lib/use-portal-token-style\";\n\ntype TooltipSourceContextValue = {\n source: HTMLElement | null;\n ref: (node: HTMLElement | null) => void;\n};\n\nconst TooltipSourceContext = createContext<TooltipSourceContextValue | null>(null);\n\nfunction TooltipProvider({\n delayDuration = 300,\n ...props\n}: ComponentProps<typeof TooltipPrimitive.Provider>) {\n return <TooltipPrimitive.Provider delayDuration={delayDuration} {...props} />;\n}\n\nfunction Tooltip({ children, ...props }: ComponentProps<typeof TooltipPrimitive.Root>) {\n const source = usePortalTokenSource<HTMLElement>();\n return (\n <TooltipSourceContext.Provider value={source}>\n <TooltipPrimitive.Root data-slot=\"tooltip\" {...props}>\n {children}\n </TooltipPrimitive.Root>\n </TooltipSourceContext.Provider>\n );\n}\n\nfunction TooltipTrigger({\n asChild = true,\n ...props\n}: ComponentProps<typeof TooltipPrimitive.Trigger>) {\n const sourceRef = useContext(TooltipSourceContext);\n return (\n <TooltipPrimitive.Trigger\n data-slot=\"tooltip-trigger\"\n asChild={asChild}\n ref={(node) => {\n sourceRef?.ref(node);\n }}\n {...props}\n />\n );\n}\n\nconst tooltipSurfaceStyle: CSSProperties = {\n backgroundColor: \"var(--og-color-fg)\",\n color: \"var(--og-color-bg)\",\n};\n\nfunction TooltipContent({\n className,\n sideOffset = 6,\n children,\n style,\n ...props\n}: ComponentProps<typeof TooltipPrimitive.Content>) {\n const source = useContext(TooltipSourceContext);\n const portalStyle = usePortalTokenStyle(source?.source ?? null);\n\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n \"og-root z-50 w-fit max-w-xs origin-[var(--radix-tooltip-content-transform-origin)]\",\n \"rounded-og-md px-2.5 py-1.5 text-og-xs leading-4 text-balance shadow-og-md\",\n \"animate-og-enter data-[state=closed]:opacity-0 data-[state=closed]:transition-opacity\",\n className,\n )}\n style={{ ...portalStyle, ...tooltipSurfaceStyle, ...style }}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow\n className=\"z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]\"\n style={{\n backgroundColor: \"var(--og-color-fg)\",\n fill: \"var(--og-color-fg)\",\n }}\n />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n}\n\nexport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };\n"],"mappings":";;;;;;;;;AASA,SAAS,WAAW,wBAAwB;AAC5C,SAAS,eAAe,kBAA2D;AAgB1E,cAgDH,YAhDG;AANT,IAAM,uBAAuB,cAAgD,IAAI;AAEjF,SAAS,gBAAgB;AAAA,EACvB,gBAAgB;AAAA,EAChB,GAAG;AACL,GAAqD;AACnD,SAAO,oBAAC,iBAAiB,UAAjB,EAA0B,eAA+B,GAAG,OAAO;AAC7E;AAEA,SAAS,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAiD;AACrF,QAAM,SAAS,qBAAkC;AACjD,SACE,oBAAC,qBAAqB,UAArB,EAA8B,OAAO,QACpC,8BAAC,iBAAiB,MAAjB,EAAsB,aAAU,WAAW,GAAG,OAC5C,UACH,GACF;AAEJ;AAEA,SAAS,eAAe;AAAA,EACtB,UAAU;AAAA,EACV,GAAG;AACL,GAAoD;AAClD,QAAM,YAAY,WAAW,oBAAoB;AACjD,SACE;AAAA,IAAC,iBAAiB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MACA,KAAK,CAAC,SAAS;AACb,mBAAW,IAAI,IAAI;AAAA,MACrB;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,IAAM,sBAAqC;AAAA,EACzC,iBAAiB;AAAA,EACjB,OAAO;AACT;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAoD;AAClD,QAAM,SAAS,WAAW,oBAAoB;AAC9C,QAAM,cAAc,oBAAoB,QAAQ,UAAU,IAAI;AAE9D,SACE,oBAAC,iBAAiB,QAAjB,EACC;AAAA,IAAC,iBAAiB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,OAAO,EAAE,GAAG,aAAa,GAAG,qBAAqB,GAAG,MAAM;AAAA,MACzD,GAAG;AAAA,MAEH;AAAA;AAAA,QACD;AAAA,UAAC,iBAAiB;AAAA,UAAjB;AAAA,YACC,WAAU;AAAA,YACV,OAAO;AAAA,cACL,iBAAiB;AAAA,cACjB,MAAM;AAAA,YACR;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF,GACF;AAEJ;","names":[]}