@opengeni/react 0.28.2 → 0.32.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/approvals.d.ts +14 -0
- package/dist/{chunk-M7X4JZOD.js → chunk-4QOQ2DSR.js} +8 -1
- package/dist/chunk-4QOQ2DSR.js.map +1 -0
- package/dist/{chunk-HQFPO7VX.js → chunk-7CJOAW3V.js} +24 -3
- package/dist/{chunk-HQFPO7VX.js.map → chunk-7CJOAW3V.js.map} +1 -1
- package/dist/{chunk-PMSGE233.js → chunk-A2WITZTI.js} +377 -113
- package/dist/chunk-A2WITZTI.js.map +1 -0
- package/dist/{chunk-BC6RKIHS.js → chunk-GZ4KR67U.js} +11 -11
- package/dist/{chunk-4F2YLLHP.js → chunk-KZRUYCL4.js} +14 -17
- package/dist/chunk-KZRUYCL4.js.map +1 -0
- package/dist/{chunk-OCHBZ2X7.js → chunk-TCCE5ZU5.js} +192 -28
- package/dist/chunk-TCCE5ZU5.js.map +1 -0
- package/dist/chunk-U255M5EZ.js +178 -0
- package/dist/chunk-U255M5EZ.js.map +1 -0
- package/dist/{chunk-XVVQP7A4.js → chunk-WY2QN2CX.js} +2539 -2174
- package/dist/chunk-WY2QN2CX.js.map +1 -0
- package/dist/chunk-ZNNE2VES.js +6413 -0
- package/dist/chunk-ZNNE2VES.js.map +1 -0
- package/dist/client.d.ts +33 -0
- package/dist/commands/index.d.ts +3 -0
- package/dist/commands/registry.d.ts +41 -0
- package/dist/commands/types.d.ts +85 -0
- package/dist/components/approval-surface.d.ts +28 -0
- package/dist/components/chat-composer.d.ts +51 -0
- package/dist/components/code-editor.d.ts +43 -0
- package/dist/components/command-palette.d.ts +25 -0
- package/dist/components/composer-transcription-control.d.ts +36 -0
- package/dist/components/composer.d.ts +277 -0
- package/dist/components/copy-button.d.ts +26 -0
- package/dist/components/desktop-viewer.d.ts +85 -0
- package/dist/components/diff-view.d.ts +38 -0
- package/dist/components/enrollment-consent.d.ts +33 -0
- package/dist/components/enrollment-device-flow.d.ts +27 -0
- package/dist/components/file-browser.d.ts +47 -0
- package/dist/components/fleet-tile.d.ts +18 -0
- package/dist/components/human-input-form.d.ts +47 -0
- package/dist/components/machine-card.d.ts +21 -0
- package/dist/components/machine-dock-bar.d.ts +31 -0
- package/dist/components/machine-health-pill.d.ts +9 -0
- package/dist/components/machine-metrics.d.ts +15 -0
- package/dist/components/machine-status-pill.d.ts +54 -0
- package/dist/components/machines/health.d.ts +25 -0
- package/dist/components/machines/machine-detail.d.ts +14 -0
- package/dist/components/machines/metric-history-chart.d.ts +24 -0
- package/dist/components/machines/metric-sparkline.d.ts +9 -0
- package/dist/components/machines/series.d.ts +24 -0
- package/dist/components/machines-dashboard.d.ts +30 -0
- package/dist/components/markdown.d.ts +31 -0
- package/dist/components/message-timeline.d.ts +98 -0
- package/dist/components/model-picker.d.ts +19 -0
- package/dist/components/pierre-diff.d.ts +34 -0
- package/dist/components/pierre-file.d.ts +27 -0
- package/dist/components/queue-draft-policy.d.ts +7 -0
- package/dist/components/queue-surface-implementation.d.ts +20 -0
- package/dist/components/queue-surface-state.d.ts +12 -0
- package/dist/components/queue-surface.d.ts +12 -0
- package/dist/components/sandbox-files.d.ts +49 -0
- package/dist/components/sandbox-terminal.d.ts +123 -0
- package/dist/components/sandbox-workspace.d.ts +128 -0
- package/dist/components/session-chrome.d.ts +70 -0
- package/dist/components/session-status.d.ts +25 -0
- package/dist/components/soften-streaming-markdown.d.ts +13 -0
- package/dist/components/stream-reveal.d.ts +37 -0
- package/dist/components/tip-follow.d.ts +139 -0
- package/dist/components/tooltip.d.ts +16 -0
- package/dist/components/workbench-changes.d.ts +34 -0
- package/dist/components/workspace-dock.d.ts +35 -0
- package/dist/composer.d.ts +11 -7
- package/dist/composer.js +9 -6
- package/dist/hooks/internal.d.ts +46 -0
- package/dist/hooks/use-available-models.d.ts +37 -0
- package/dist/hooks/use-billing-usage.d.ts +26 -0
- package/dist/hooks/use-codex-accounts.d.ts +69 -0
- package/dist/{use-composer-ClHy1rkL.d.ts → hooks/use-composer.d.ts} +16 -24
- package/dist/hooks/use-desktop-stream.d.ts +43 -0
- package/dist/hooks/use-environments.d.ts +35 -0
- package/dist/{use-file-attachments-BmT8WtqO.d.ts → hooks/use-file-attachments.d.ts} +6 -9
- package/dist/hooks/use-goal.d.ts +46 -0
- package/dist/hooks/use-human-input.d.ts +26 -0
- package/dist/hooks/use-last-started-turn-policy.d.ts +27 -0
- package/dist/hooks/use-machine-chip.d.ts +54 -0
- package/dist/hooks/use-machines.d.ts +81 -0
- package/dist/hooks/use-packs.d.ts +27 -0
- package/dist/hooks/use-relay-frame-stream.d.ts +53 -0
- package/dist/hooks/use-rigs.d.ts +87 -0
- package/dist/hooks/use-sandbox-files.d.ts +108 -0
- package/dist/hooks/use-sandbox-git.d.ts +58 -0
- package/dist/hooks/use-sandbox-terminal.d.ts +62 -0
- package/dist/hooks/use-scheduled-tasks.d.ts +15 -0
- package/dist/hooks/use-session-capabilities.d.ts +83 -0
- package/dist/hooks/use-session-control.d.ts +22 -0
- package/dist/hooks/use-session-events.d.ts +92 -0
- package/dist/hooks/use-session-lineage.d.ts +17 -0
- package/dist/hooks/use-session-mcp-approval-policy.d.ts +23 -0
- package/dist/hooks/use-session.d.ts +23 -0
- package/dist/hooks/use-slash-commands.d.ts +66 -0
- package/dist/hooks/use-terminal-stream.d.ts +46 -0
- package/dist/hooks/use-transcription.d.ts +73 -0
- package/dist/hooks/use-turn-queue.d.ts +44 -0
- package/dist/hooks/use-voice-input.d.ts +25 -0
- package/dist/hooks/use-windowed-sections.d.ts +42 -0
- package/dist/hooks/use-workspace-capture.d.ts +49 -0
- package/dist/hooks/use-workspace-edit.d.ts +73 -0
- package/dist/hooks/use-workspace-sessions.d.ts +30 -0
- package/dist/hooks/use-workspaces.d.ts +22 -0
- package/dist/human-input.d.ts +18 -0
- package/dist/index.d.ts +144 -2119
- package/dist/index.js +421 -324
- package/dist/index.js.map +1 -1
- package/dist/lib/clipboard.d.ts +7 -0
- package/dist/lib/cn.d.ts +3 -0
- package/dist/lib/format.d.ts +48 -0
- package/dist/lib/git-patch.d.ts +8 -0
- package/dist/lib/motion-inspect.d.ts +5 -0
- package/dist/lib/motion.d.ts +14 -0
- package/dist/lib/noto-sans-arabic-loader.d.ts +1 -0
- package/dist/lib/noto-sans-jp-loader.generated.d.ts +1 -0
- package/dist/lib/relay-wire.d.ts +30 -0
- package/dist/lib/use-portal-token-style.d.ts +9 -0
- package/dist/lib/use-theme-type.d.ts +5 -0
- package/dist/lib/use-unicode-fonts.d.ts +12 -0
- package/dist/lib/xterm-renderer.d.ts +19 -0
- package/dist/lib/xterm-theme.d.ts +75 -0
- package/dist/machines.d.ts +30 -413
- package/dist/machines.js +3 -3
- package/dist/model-policy.d.ts +32 -0
- package/dist/model-policy.js +33 -0
- package/dist/model-policy.js.map +1 -0
- package/dist/provider.d.ts +16 -0
- package/dist/{queue-surface-implementation-UQ535OKQ.js → queue-surface-implementation-THPAKGMD.js} +2 -2
- package/dist/{queue-surface-implementation-UQ535OKQ.js.map → queue-surface-implementation-THPAKGMD.js.map} +1 -1
- package/dist/session-context.d.ts +82 -0
- package/dist/session-ui.d.ts +10 -7
- package/dist/session-ui.js +9 -5
- package/dist/session.d.ts +28 -6
- package/dist/session.js +11 -11
- package/dist/timeline/activity-rail.d.ts +19 -0
- package/dist/timeline/disclosure-context.d.ts +14 -0
- package/dist/timeline/entrance.d.ts +14 -0
- package/dist/timeline/fleet-decision-projection.d.ts +9 -0
- package/dist/timeline/fleet-decision-row.d.ts +11 -0
- package/dist/timeline/fold-memory.d.ts +15 -0
- package/dist/timeline/index.d.ts +18 -0
- package/dist/timeline/parsers.d.ts +96 -0
- package/dist/timeline/projection.d.ts +38 -0
- package/dist/timeline/registry.d.ts +40 -0
- package/dist/timeline/screenshot-lightbox.d.ts +26 -0
- package/dist/timeline/seen-activity-ids.d.ts +2 -0
- package/dist/timeline/shared.d.ts +125 -0
- package/dist/timeline/tool-diff.d.ts +8 -0
- package/dist/timeline/tool-display-name.d.ts +10 -0
- package/dist/timeline/tool-renderers.d.ts +5 -0
- package/dist/timeline/turn-summary.d.ts +116 -0
- package/dist/{use-turn-queue-Drm_ypue.d.ts → timeline/types.d.ts} +57 -67
- package/dist/types/machines.d.ts +11 -0
- package/package.json +8 -4
- package/src/client.ts +1 -0
- package/src/components/composer-transcription-control.tsx +278 -130
- package/src/components/composer.tsx +20 -15
- package/src/components/copy-button.tsx +127 -0
- package/src/components/markdown.tsx +231 -32
- package/src/components/message-timeline.tsx +1382 -378
- package/src/components/model-picker.tsx +83 -43
- package/src/components/queue-surface-implementation.tsx +1 -1
- package/src/components/session-chrome.tsx +942 -0
- package/src/components/soften-streaming-markdown.ts +205 -0
- package/src/components/stream-reveal.ts +195 -0
- package/src/components/tip-follow.ts +459 -0
- package/src/components/tooltip.tsx +103 -0
- package/src/composer.ts +6 -0
- package/src/hooks/internal.ts +30 -4
- package/src/hooks/use-available-models.ts +51 -4
- package/src/hooks/use-composer.ts +24 -18
- package/src/hooks/use-last-started-turn-policy.ts +95 -0
- package/src/hooks/use-session-events.ts +359 -5
- package/src/hooks/use-voice-input.ts +232 -0
- package/src/index.ts +49 -1
- package/src/lib/clipboard.ts +58 -0
- package/src/lib/format.ts +18 -0
- package/src/lib/motion-inspect.ts +5 -0
- package/src/lib/motion.ts +80 -0
- package/src/model-policy.ts +210 -0
- package/src/session-ui.ts +7 -0
- package/src/session.ts +2 -0
- package/src/timeline/activity-rail.tsx +46 -7
- package/src/timeline/entrance.tsx +10 -0
- package/src/timeline/fold-memory.ts +52 -0
- package/src/timeline/index.ts +11 -1
- package/src/timeline/projection.ts +252 -47
- package/src/timeline/seen-activity-ids.ts +19 -0
- package/src/timeline/shared.tsx +1 -1
- package/src/timeline/tool-renderers.tsx +75 -6
- package/src/timeline/turn-summary.tsx +387 -97
- package/src/timeline/types.ts +47 -0
- package/styles/index.css +99 -7
- package/styles/tokens.css +44 -3
- package/dist/chunk-4F2YLLHP.js.map +0 -1
- package/dist/chunk-M7X4JZOD.js.map +0 -1
- package/dist/chunk-OCHBZ2X7.js.map +0 -1
- package/dist/chunk-PMSGE233.js.map +0 -1
- package/dist/chunk-WAA247AB.js +0 -3858
- package/dist/chunk-WAA247AB.js.map +0 -1
- package/dist/chunk-XVVQP7A4.js.map +0 -1
- package/dist/composer-BMzimGTO.d.ts +0 -528
- package/dist/session-C3tIXLim.d.ts +0 -264
- package/dist/session-context-CAjlaeZb.d.ts +0 -84
- package/dist/session-ui-B_7cfN5u.d.ts +0 -259
- /package/dist/{chunk-BC6RKIHS.js.map → chunk-GZ4KR67U.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/use-composer.ts"],"sourcesContent":["import type {\n ComposerDraft,\n EffectiveControlResumeOption,\n EffectiveSessionControl,\n OpenGeniApiError,\n ResourceRef,\n SaveComposerDraftRequest,\n SendMessageInput,\n SessionEvent,\n} from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { useEmbeddedSession, type EmbeddedSessionClientOverride } from \"../session-context\";\nimport { useSessionEventTrigger, type SessionEventFeedOptions } from \"./internal\";\n\nexport type ComposerSendExtras = Omit<SendMessageInput, \"text\" | \"clientEventId\">;\n\nexport type UseComposerOptions = EmbeddedSessionClientOverride &\n SessionEventFeedOptions & {\n /** Called with the exact accepted wire input after a successful send. */\n onSent?: ((text: string, input: SendMessageInput) => void) | undefined;\n /**\n * Extra message fields (resources, tools, model, reasoningEffort, latencyMode) merged\n * into every send. A function is evaluated at send time so it can read the\n * surrounding UI state (attachment pickers, model selectors, ...).\n */\n sendExtras?: ComposerSendExtras | (() => ComposerSendExtras) | undefined;\n /**\n * Fail-closed delivery guard evaluated at send time. Attachment hosts use\n * this to preserve unresolved upload cards until the operator waits,\n * retries, or removes them; direct hook callers cannot bypass the UI gate.\n */\n sendBlocked?: (() => boolean) | undefined;\n /** Latest server-derived workstream control; bound into Send/Steer OCC. */\n effectiveControl?: EffectiveSessionControl | null | undefined;\n /** Apply durable model/tool/reasoning settings in the host's controlled UI. */\n onDraftApplied?: ((draft: ComposerDraft) => void) | undefined;\n /** Disable remote composer-draft reads and writes for embedded hosts. */\n draftPersistence?: \"durable\" | \"disabled\" | undefined;\n };\n\ntype ComposerDraftShadow = {\n text: string;\n resources: ResourceRef[];\n};\n\ntype PendingComposerOperation = {\n delivery: \"send\" | \"steer\";\n input: SendMessageInput;\n draftAtSend: string;\n resourcesAtSend: ResourceRef[];\n /** Latest local text/resources that must survive an uncertain delivery. */\n newerShadow: ComposerDraftShadow;\n clearDraftOnAccept: boolean;\n /** False after remount when the original input carried secret credentials. */\n canRetry: boolean;\n};\n\ntype StoredPendingComposerOperation = Omit<PendingComposerOperation, \"input\" | \"canRetry\"> & {\n input: Omit<SendMessageInput, \"mcpCredentialUpdates\">;\n hasMcpCredentialUpdates: boolean;\n};\n\nconst PENDING_COMPOSER_STORAGE_PREFIX = \"opengeni.pending-composer.v1:\";\n\n// A remount must not manufacture a new operation while the previous mutation\n// is still outcome-unknown. Keep only non-credential request fields here; the\n// mounted hook retains the exact input, including any credential updates. The\n// safe shadow is also session-scoped so a refresh cannot lose newer edits.\nconst pendingComposerOperations = new Map<string, StoredPendingComposerOperation>();\n\nfunction pendingComposerOperationKey(\n workspaceId: string,\n sessionId: string | null | undefined,\n): string | null {\n return sessionId ? `${workspaceId}\\u0000${sessionId}` : null;\n}\n\nfunction pendingComposerStorage(): Storage | null {\n try {\n return typeof window === \"undefined\" ? null : window.sessionStorage;\n } catch {\n return null;\n }\n}\n\nfunction pendingComposerStorageKey(key: string): string {\n return `${PENDING_COMPOSER_STORAGE_PREFIX}${encodeURIComponent(key)}`;\n}\n\nfunction resourceList(value: unknown): value is ResourceRef[] {\n return (\n Array.isArray(value) &&\n value.every((candidate) => {\n if (typeof candidate !== \"object\" || candidate === null) return false;\n const resource = candidate as Record<string, unknown>;\n return resource.kind === \"file\"\n ? typeof resource.fileId === \"string\"\n : resource.kind === \"repository\" &&\n typeof resource.uri === \"string\" &&\n typeof resource.ref === \"string\";\n })\n );\n}\n\nfunction readStoredPendingComposerOperation(\n key: string | null,\n): StoredPendingComposerOperation | null {\n const storage = key ? pendingComposerStorage() : null;\n if (!storage || !key) return null;\n try {\n const parsed: unknown = JSON.parse(storage.getItem(pendingComposerStorageKey(key)) ?? \"null\");\n if (typeof parsed !== \"object\" || parsed === null) return null;\n const record = parsed as Record<string, unknown>;\n const input = record.input;\n const shadow = record.newerShadow;\n if (\n typeof input !== \"object\" ||\n input === null ||\n typeof shadow !== \"object\" ||\n shadow === null\n ) {\n return null;\n }\n const inputRecord = input as Record<string, unknown>;\n const shadowRecord = shadow as Record<string, unknown>;\n if (\n (record.delivery !== \"send\" && record.delivery !== \"steer\") ||\n typeof record.draftAtSend !== \"string\" ||\n !resourceList(record.resourcesAtSend) ||\n typeof shadowRecord.text !== \"string\" ||\n !resourceList(shadowRecord.resources) ||\n typeof record.clearDraftOnAccept !== \"boolean\" ||\n typeof record.hasMcpCredentialUpdates !== \"boolean\" ||\n typeof inputRecord.text !== \"string\" ||\n typeof inputRecord.clientEventId !== \"string\" ||\n \"mcpCredentialUpdates\" in inputRecord ||\n (\"resources\" in inputRecord && !resourceList(inputRecord.resources))\n ) {\n return null;\n }\n return record as StoredPendingComposerOperation;\n } catch {\n return null;\n }\n}\n\nfunction writePendingComposerOperation(\n key: string,\n operation: StoredPendingComposerOperation,\n): void {\n const storage = pendingComposerStorage();\n if (!storage) return;\n try {\n storage.setItem(pendingComposerStorageKey(key), JSON.stringify(operation));\n } catch {\n // Storage is best effort; the in-memory record still protects remounts.\n }\n}\n\nfunction restorePendingComposerOperation(key: string | null): PendingComposerOperation | null {\n const stored =\n (key && pendingComposerOperations.get(key)) ?? readStoredPendingComposerOperation(key);\n if (!stored) return null;\n return {\n ...stored,\n input: stored.input,\n newerShadow: stored.newerShadow ?? {\n text: stored.draftAtSend,\n resources: stored.resourcesAtSend,\n },\n canRetry: !stored.hasMcpCredentialUpdates,\n };\n}\n\nfunction rememberPendingComposerOperation(\n key: string | null,\n operation: PendingComposerOperation,\n): void {\n if (!key) return;\n const { canRetry: _retry, ...safeOperation } = operation;\n const { input: originalInput, ...withoutInput } = safeOperation;\n const { mcpCredentialUpdates: _storedMcp, ...safeInput } = originalInput;\n const stored = {\n ...withoutInput,\n input: safeInput,\n hasMcpCredentialUpdates: operation.input.mcpCredentialUpdates !== undefined,\n newerShadow: {\n text: operation.newerShadow.text,\n resources: [...operation.newerShadow.resources],\n },\n } satisfies StoredPendingComposerOperation;\n pendingComposerOperations.set(key, stored);\n writePendingComposerOperation(key, stored);\n}\n\nfunction forgetPendingComposerOperation(key: string | null): void {\n if (!key) return;\n pendingComposerOperations.delete(key);\n const storage = pendingComposerStorage();\n if (!storage) return;\n try {\n storage.removeItem(pendingComposerStorageKey(key));\n } catch {\n // Ignore a blocked storage implementation; delivery has already settled.\n }\n}\n\nfunction updatePendingComposerShadow(\n key: string | null,\n operation: PendingComposerOperation | null,\n shadow: ComposerDraftShadow,\n): PendingComposerOperation | null {\n if (!key || !operation) return operation;\n const next = { ...operation, newerShadow: { ...shadow, resources: [...shadow.resources] } };\n rememberPendingComposerOperation(key, next);\n return next;\n}\n\nexport type ComposerState = {\n value: string;\n setValue: (value: string) => void;\n /** Read the current draft synchronously before a destructive replacement. */\n hasDraftContent: () => boolean;\n /** Append the draft behind prompts already visible in the queue. */\n send: (text?: string) => Promise<boolean>;\n /** Supersede current direction with the draft. */\n steer: (text?: string) => Promise<boolean>;\n sending: boolean;\n canSend: boolean;\n /** Pause the session without deleting its prompt queue. */\n pause: (reason?: string) => Promise<void>;\n pausing: boolean;\n resume: (reason?: string) => Promise<void>;\n resumeScope: (option: EffectiveControlResumeOption) => Promise<void>;\n resuming: boolean;\n draft: ComposerDraft | null;\n draftRevision: number;\n draftLoading: boolean;\n draftSaving: boolean;\n draftConflict: Error | null;\n /** Whether this controller owns a durable server-side draft. */\n draftPersistence?: \"durable\" | \"disabled\" | undefined;\n /** Apply an atomic queue Edit checkout without a second read. */\n applyDraft: (draft: ComposerDraft) => void;\n reloadDraft: () => Promise<void>;\n resolveDraftConflict: (choice: \"keep_mine\" | \"use_remote\") => Promise<void>;\n restoredResources: ResourceRef[];\n removeRestoredResource: (index: number) => void;\n error: Error | null;\n clearError: () => void;\n};\n\n/**\n * Draft + send + Pause/Resume state for the chat composer — the only\n * human-to-agent input surface. The draft survives a failed send (nothing is\n * more hostile than losing a typed message); each send carries a generated\n * `clientEventId` so retries stay idempotent server-side.\n */\nexport function useComposer(\n sessionId: string | null | undefined,\n options: UseComposerOptions = {},\n): ComposerState {\n const { client, workspaceId, registerSessionReconciler } = useEmbeddedSession(options);\n const durableDrafts = options.draftPersistence !== \"disabled\";\n const targetKey = `${workspaceId}\\u0000${sessionId ?? \"\"}\\u0000${durableDrafts ? \"durable\" : \"disabled\"}`;\n const pendingOperationKey = pendingComposerOperationKey(workspaceId, sessionId);\n const initialPendingOperation = restorePendingComposerOperation(pendingOperationKey);\n const initialShadow = initialPendingOperation?.newerShadow;\n const [value, setValue] = useState(() => initialShadow?.text ?? \"\");\n // Keep rendered state behind the committed target identity for one frame:\n // a parent may switch sessionId without remounting this public hook.\n const [stateTargetKey, setStateTargetKey] = useState(targetKey);\n const [sending, setSending] = useState(false);\n const [pausing, setPausing] = useState(false);\n const [resuming, setResuming] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [draft, setDraft] = useState<ComposerDraft | null>(null);\n const [draftLoading, setDraftLoading] = useState(Boolean(sessionId) && durableDrafts);\n const [draftSaving, setDraftSaving] = useState(false);\n const [draftConflict, setDraftConflict] = useState<Error | null>(null);\n const [restoredResources, setRestoredResources] = useState<ResourceRef[]>(\n () => initialShadow?.resources ?? [],\n );\n const pendingOperationRef = useRef<PendingComposerOperation | null>(initialPendingOperation);\n const pendingClientEventId = useRef<string | null>(\n initialPendingOperation?.input.clientEventId ?? null,\n );\n const valueRef = useRef(initialShadow?.text ?? \"\");\n const draftRef = useRef<ComposerDraft | null>(null);\n const restoredResourcesRef = useRef<ResourceRef[]>(initialShadow?.resources ?? []);\n const localEditRevision = useRef(initialShadow ? 1 : 0);\n const targetGeneration = useRef(0);\n const draftReadGeneration = useRef(0);\n const lastSavedSignature = useRef<string | null>(null);\n const saveChain = useRef<Promise<void>>(Promise.resolve());\n const onSent = options.onSent;\n const onDraftApplied = options.onDraftApplied;\n // Read through a ref so live session/policy projections can replace their\n // apply callback without invalidating the draft loader and re-running its\n // initial-load effect. Publish only committed callbacks: a suspended target\n // render must not retarget an in-flight read owned by the committed session.\n const onDraftAppliedRef = useRef(onDraftApplied);\n useLayoutEffect(() => {\n onDraftAppliedRef.current = onDraftApplied;\n }, [onDraftApplied]);\n // Read through a ref so a new extras closure (created every render by\n // callers passing inline functions) does not invalidate `send`.\n const sendExtrasRef = useRef(options.sendExtras);\n sendExtrasRef.current = options.sendExtras;\n const sendBlockedRef = useRef(options.sendBlocked);\n sendBlockedRef.current = options.sendBlocked;\n const liveExtrasVersion = JSON.stringify(resolveSendExtras(options.sendExtras));\n\n // A composer is bound to one session: switching targets must not leak the\n // previous session's draft, error, or retry idempotency key.\n const targetKeyRef = useRef(targetKey);\n useLayoutEffect(() => {\n if (targetKeyRef.current === targetKey) return;\n targetKeyRef.current = targetKey;\n targetGeneration.current += 1;\n draftReadGeneration.current += 1;\n pendingOperationRef.current = restorePendingComposerOperation(pendingOperationKey);\n pendingClientEventId.current = pendingOperationRef.current?.input.clientEventId ?? null;\n const shadow = pendingOperationRef.current?.newerShadow;\n localEditRevision.current = shadow ? 1 : 0;\n valueRef.current = shadow?.text ?? \"\";\n draftRef.current = null;\n restoredResourcesRef.current = shadow?.resources ?? [];\n lastSavedSignature.current = null;\n // Old saves may still be awaiting the network. Their generation fence\n // prevents settlement, and a fresh chain avoids blocking this target.\n saveChain.current = Promise.resolve();\n setStateTargetKey(targetKey);\n setValue(shadow?.text ?? \"\");\n setSending(false);\n setPausing(false);\n setResuming(false);\n setError(null);\n setDraft(null);\n setDraftLoading(Boolean(sessionId) && durableDrafts);\n setDraftSaving(false);\n setDraftConflict(null);\n setRestoredResources(shadow?.resources ?? []);\n }, [durableDrafts, pendingOperationKey, sessionId, targetKey]);\n\n const applyDraft = useCallback(\n (next: ComposerDraft): void => {\n if (targetKeyRef.current !== targetKey) return;\n if (!durableDrafts) {\n localEditRevision.current += 1;\n valueRef.current = next.text;\n restoredResourcesRef.current = next.resources;\n draftRef.current = null;\n lastSavedSignature.current = null;\n setDraft(null);\n setValue(next.text);\n setRestoredResources(next.resources);\n pendingOperationRef.current = updatePendingComposerShadow(\n pendingOperationKey,\n pendingOperationRef.current,\n {\n text: next.text,\n resources: mergeResources(\n next.resources,\n resolveSendExtras(sendExtrasRef.current).resources ?? [],\n ),\n },\n );\n setDraftConflict(null);\n return;\n }\n valueRef.current = next.text;\n draftRef.current = next;\n restoredResourcesRef.current = next.resources;\n lastSavedSignature.current = draftSignature(draftPayload(next));\n localEditRevision.current += 1;\n setDraft(next);\n setValue(next.text);\n setRestoredResources(next.resources);\n pendingOperationRef.current = updatePendingComposerShadow(\n pendingOperationKey,\n pendingOperationRef.current,\n {\n text: next.text,\n resources: mergeResources(\n next.resources,\n resolveSendExtras(sendExtrasRef.current).resources ?? [],\n ),\n },\n );\n setDraftConflict(null);\n onDraftAppliedRef.current?.(next);\n },\n [durableDrafts, pendingOperationKey, targetKey],\n );\n\n const loadDraft = useCallback(\n async (replaceLocal: boolean): Promise<void> => {\n if (targetKeyRef.current !== targetKey) return;\n if (!sessionId || !durableDrafts) {\n setDraftLoading(false);\n return;\n }\n const generation = targetGeneration.current;\n const readTicket = ++draftReadGeneration.current;\n const localAtStart = localEditRevision.current;\n const baseAtStart = draftRef.current;\n const extrasAtStart = resolveSendExtras(sendExtrasRef.current);\n const localSignatureAtStart = baseAtStart\n ? draftSignature(\n composerDraftPayload(\n baseAtStart,\n valueRef.current,\n restoredResourcesRef.current,\n extrasAtStart,\n ),\n )\n : null;\n const localWasDirtyAtStart =\n localSignatureAtStart === null\n ? localAtStart !== 0\n : localSignatureAtStart !== lastSavedSignature.current;\n setDraftLoading(true);\n try {\n const fetched = await client.getComposerDraft(workspaceId, sessionId);\n if (\n generation !== targetGeneration.current ||\n targetKeyRef.current !== targetKey ||\n readTicket !== draftReadGeneration.current\n ) {\n return;\n }\n const currentRevision = draftRef.current?.revision ?? -1;\n if (fetched.revision >= currentRevision) {\n draftRef.current = fetched;\n setDraft(fetched);\n setDraftConflict(null);\n const shadow = pendingOperationRef.current?.newerShadow;\n if (shadow) {\n // The server can only know the original operation. Never replace\n // newer local edits while that operation is still uncertain.\n valueRef.current = shadow.text;\n restoredResourcesRef.current = shadow.resources;\n localEditRevision.current ||= 1;\n setValue(shadow.text);\n setRestoredResources(shadow.resources);\n } else if (\n replaceLocal ||\n (!localWasDirtyAtStart && localAtStart === localEditRevision.current)\n ) {\n // Model/effort ride in sendExtras (outside localEditRevision). If\n // the picker changed during this fetch, skip onDraftApplied so a\n // stale server model/effort cannot undo the operator's pick.\n const extrasNow = resolveSendExtras(sendExtrasRef.current);\n const pickerChangedDuringFetch =\n extrasNow.model !== extrasAtStart.model ||\n extrasNow.reasoningEffort !== extrasAtStart.reasoningEffort;\n valueRef.current = fetched.text;\n restoredResourcesRef.current = fetched.resources;\n lastSavedSignature.current = draftSignature(draftPayload(fetched));\n setValue(fetched.text);\n setRestoredResources(fetched.resources);\n if (replaceLocal || !pickerChangedDuringFetch) {\n onDraftAppliedRef.current?.(fetched);\n }\n }\n }\n } catch (cause) {\n if (\n generation === targetGeneration.current &&\n targetKeyRef.current === targetKey &&\n readTicket === draftReadGeneration.current\n ) {\n setError(asError(cause));\n }\n } finally {\n if (\n generation === targetGeneration.current &&\n targetKeyRef.current === targetKey &&\n readTicket === draftReadGeneration.current\n ) {\n setDraftLoading(false);\n }\n }\n },\n [client, durableDrafts, sessionId, targetKey, workspaceId],\n );\n\n useEffect(() => {\n if (!sessionId || !durableDrafts) {\n setDraftLoading(false);\n return;\n }\n void loadDraft(false);\n }, [durableDrafts, loadDraft, sessionId]);\n useEffect(() => {\n if (!sessionId || !durableDrafts) return;\n return registerSessionReconciler(sessionId, \"composer\", async () => await loadDraft(false));\n }, [durableDrafts, loadDraft, registerSessionReconciler, sessionId]);\n useSessionEventTrigger(\n client,\n workspaceId,\n sessionId,\n isComposerDraftEvent,\n () => void loadDraft(false),\n {\n enabled: Boolean(sessionId) && durableDrafts,\n ...(options.events !== undefined ? { events: options.events } : {}),\n },\n );\n\n const currentDraftPayload = useCallback((): SaveComposerDraftRequest | null => {\n if (!durableDrafts || targetKeyRef.current !== targetKey) return null;\n const base = draftRef.current;\n if (!base) return null;\n const extras = resolveSendExtras(sendExtrasRef.current);\n return composerDraftPayload(base, value, restoredResources, extras);\n }, [durableDrafts, restoredResources, targetKey, value]);\n\n const persistPayload = useCallback(\n async (payload: SaveComposerDraftRequest): Promise<boolean> => {\n const ownedTargetKey = targetKey;\n const ownedGeneration = targetGeneration.current;\n if (!sessionId || !durableDrafts || targetKeyRef.current !== ownedTargetKey) {\n return false;\n }\n let success = false;\n const run = async () => {\n if (\n targetKeyRef.current !== ownedTargetKey ||\n targetGeneration.current !== ownedGeneration\n ) {\n return;\n }\n const current = draftRef.current;\n if (!current) return;\n const request = { ...payload, expectedRevision: current.revision };\n const signature = draftSignature(request);\n if (signature === lastSavedSignature.current) {\n success = true;\n return;\n }\n setDraftSaving(true);\n try {\n const saved = await client.saveComposerDraft(workspaceId, sessionId, request);\n if (\n targetKeyRef.current !== ownedTargetKey ||\n targetGeneration.current !== ownedGeneration\n ) {\n return;\n }\n draftRef.current = saved;\n setDraft(saved);\n lastSavedSignature.current = signature;\n setDraftConflict(null);\n success = true;\n } catch (cause) {\n if (\n targetKeyRef.current === ownedTargetKey &&\n targetGeneration.current === ownedGeneration\n ) {\n const problem = asError(cause);\n if (isDraftConflictError(problem)) setDraftConflict(problem);\n setError(problem);\n }\n } finally {\n if (\n targetKeyRef.current === ownedTargetKey &&\n targetGeneration.current === ownedGeneration\n ) {\n setDraftSaving(false);\n }\n }\n };\n saveChain.current = saveChain.current.then(run, run);\n await saveChain.current;\n return success;\n },\n [client, durableDrafts, sessionId, targetKey, workspaceId],\n );\n\n // Private durable autosave. A newer local edit is never replaced by an older\n // response; saves serialize and each reads the latest acknowledged revision.\n useEffect(() => {\n const pending = pendingOperationRef.current;\n if (pending) {\n const shadow = {\n text: valueRef.current,\n resources: mergeResources(\n restoredResourcesRef.current,\n resolveSendExtras(sendExtrasRef.current).resources ?? [],\n ),\n };\n if (\n pending.newerShadow.text !== shadow.text ||\n JSON.stringify(pending.newerShadow.resources) !== JSON.stringify(shadow.resources)\n ) {\n pendingOperationRef.current = updatePendingComposerShadow(\n pendingOperationKey,\n pending,\n shadow,\n );\n }\n return;\n }\n if (\n !durableDrafts ||\n !sessionId ||\n draftLoading ||\n sending ||\n !draftRef.current ||\n draftConflict\n )\n return;\n const payload = currentDraftPayload();\n if (!payload || draftSignature(payload) === lastSavedSignature.current) return;\n const timer = window.setTimeout(() => void persistPayload(payload), 500);\n return () => window.clearTimeout(timer);\n }, [\n currentDraftPayload,\n durableDrafts,\n draftConflict,\n draftLoading,\n liveExtrasVersion,\n pendingOperationKey,\n persistPayload,\n sending,\n sessionId,\n ]);\n\n const dispatch = useCallback(\n async (delivery: \"send\" | \"steer\", explicit?: string): Promise<boolean> => {\n const ownedTargetKey = targetKey;\n const ownedGeneration = targetGeneration.current;\n const operationKey = pendingComposerOperationKey(workspaceId, sessionId);\n const pending = pendingOperationRef.current ?? restorePendingComposerOperation(operationKey);\n if (pending && !pendingOperationRef.current) {\n pendingOperationRef.current = pending;\n pendingClientEventId.current = pending.input.clientEventId ?? null;\n }\n const draftAtSend = value;\n const rawText = explicit ?? draftAtSend;\n const hasText = rawText.trim().length > 0;\n // Resolve the extras once: a file-only message (empty text + ≥1 ready\n // resource) is legitimate, so we must not bail on empty text alone.\n const extras = pending ? {} : resolveSendExtras(sendExtrasRef.current);\n const hasResources = restoredResources.length > 0 || (extras.resources?.length ?? 0) > 0;\n if (\n (!pending && !hasText && !hasResources) ||\n !sessionId ||\n sending ||\n sendBlockedRef.current?.() === true ||\n targetKeyRef.current !== ownedTargetKey\n ) {\n return false;\n }\n\n const clearPending = (): void => {\n pendingOperationRef.current = null;\n pendingClientEventId.current = null;\n forgetPendingComposerOperation(operationKey);\n };\n\n const settleAccepted = (operation: PendingComposerOperation): void => {\n clearPending();\n const draftWasUnchanged = valueRef.current === operation.draftAtSend;\n const resourcesWereUnchanged =\n JSON.stringify(restoredResourcesRef.current) ===\n JSON.stringify(operation.resourcesAtSend);\n const previousDraft = draftRef.current;\n if (previousDraft) {\n const cleared = {\n ...previousDraft,\n revision: 0,\n text: \"\",\n resources: [],\n sourceTurnId: null,\n sourceTurnVersion: null,\n updatedAt: null,\n };\n draftRef.current = cleared;\n setDraft(cleared);\n lastSavedSignature.current = draftSignature(draftPayload(cleared));\n }\n if (resourcesWereUnchanged) {\n restoredResourcesRef.current = [];\n setRestoredResources([]);\n }\n if (operation.clearDraftOnAccept && draftWasUnchanged) {\n valueRef.current = \"\";\n setValue(\"\");\n }\n onSent?.(operation.input.text, operation.input);\n };\n\n const deliver = async (operation: PendingComposerOperation): Promise<void> => {\n if (operation.delivery === \"steer\") {\n await client.steerMessage(workspaceId, sessionId, operation.input);\n } else {\n await client.sendMessage(workspaceId, sessionId, operation.input);\n }\n };\n\n setSending(true);\n setError(null);\n try {\n if (pending) {\n let accepted = false;\n try {\n const events = await client.listEvents(workspaceId, sessionId, {\n includeTypes: [\"user.message\"],\n limit: 100,\n payloadMode: \"none\",\n });\n accepted = events.some(\n (event) =>\n event.type === \"user.message\" &&\n event.clientEventId === pending.input.clientEventId,\n );\n } catch (cause) {\n if (\n targetKeyRef.current === ownedTargetKey &&\n targetGeneration.current === ownedGeneration\n ) {\n setError(asError(cause));\n }\n return false;\n }\n if (\n targetKeyRef.current !== ownedTargetKey ||\n targetGeneration.current !== ownedGeneration\n ) {\n return false;\n }\n if (accepted) {\n settleAccepted(pending);\n return true;\n }\n if (!pending.canRetry) {\n setError(\n new Error(\n \"OpenGeni cannot safely retry this uncertain request after remount; reconcile the session before sending again.\",\n ),\n );\n return false;\n }\n try {\n await deliver(pending);\n } catch (cause) {\n if (\n targetKeyRef.current === ownedTargetKey &&\n targetGeneration.current === ownedGeneration\n ) {\n setError(asError(cause));\n }\n return false;\n }\n if (\n targetKeyRef.current !== ownedTargetKey ||\n targetGeneration.current !== ownedGeneration\n ) {\n return false;\n }\n settleAccepted(pending);\n return true;\n }\n\n // Trimming is only an emptiness check. A non-blank prompt is persisted\n // and submitted byte-for-byte, while file-only sends use the same\n // placeholder for both operations so the server content fence cannot\n // reject its own client.\n const sendText = hasText ? rawText : FILE_ONLY_MESSAGE_TEXT;\n const currentPayload = currentDraftPayload();\n const payload = currentPayload ? { ...currentPayload, text: sendText } : null;\n if (payload && !(await persistPayload(payload))) return false;\n if (\n targetKeyRef.current !== ownedTargetKey ||\n targetGeneration.current !== ownedGeneration\n ) {\n return false;\n }\n // The wire contract requires non-empty text (z.string().min(1)) and the\n // worker rejects whitespace-only text; a file-only message therefore\n // carries a minimal default so the attachments still get delivered.\n pendingClientEventId.current ??= generateClientEventId();\n const input = composeSendInput(sendText, pendingClientEventId.current, extras, {\n ...(options.effectiveControl?.controlEtag\n ? { controlEtag: options.effectiveControl.controlEtag }\n : {}),\n ...(durableDrafts && draftRef.current\n ? { expectedDraftRevision: draftRef.current.revision }\n : {}),\n resources: mergeResources(restoredResources, extras.resources ?? []),\n });\n const operation: PendingComposerOperation = {\n delivery,\n input,\n draftAtSend,\n resourcesAtSend: [...restoredResources],\n newerShadow: {\n text: draftAtSend,\n resources: mergeResources(restoredResources, extras.resources ?? []),\n },\n clearDraftOnAccept: explicit === undefined,\n canRetry: true,\n };\n pendingOperationRef.current = operation;\n rememberPendingComposerOperation(operationKey, operation);\n try {\n await deliver(operation);\n } catch (cause) {\n if (!isOutcomeUnknownError(cause)) {\n clearPending();\n }\n if (\n targetKeyRef.current === ownedTargetKey &&\n targetGeneration.current === ownedGeneration\n ) {\n setError(asError(cause));\n }\n return false;\n }\n if (\n targetKeyRef.current !== ownedTargetKey ||\n targetGeneration.current !== ownedGeneration\n ) {\n return false;\n }\n settleAccepted(operation);\n return true;\n } finally {\n if (\n targetKeyRef.current === ownedTargetKey &&\n targetGeneration.current === ownedGeneration\n ) {\n setSending(false);\n }\n }\n },\n [\n client,\n currentDraftPayload,\n durableDrafts,\n onSent,\n options.effectiveControl?.controlEtag,\n persistPayload,\n restoredResources,\n sending,\n sessionId,\n targetKey,\n value,\n workspaceId,\n ],\n );\n\n const send = useCallback(async (text?: string) => await dispatch(\"send\", text), [dispatch]);\n const steer = useCallback(async (text?: string) => await dispatch(\"steer\", text), [dispatch]);\n\n // A send is possible with non-empty text OR with ≥1 attached resource (a\n // file-only message). Resources ride in `sendExtras`, so we resolve them here\n // — keeping useComposer attachment-agnostic while still lighting up the send\n // affordance the moment a file is ready. Attachment hosts bind `sendBlocked`\n // to unresolved uploads so direct send()/steer() calls fail closed too.\n const hasReadyResources =\n restoredResources.length > 0 ||\n (resolveSendExtras(sendExtrasRef.current).resources?.length ?? 0) > 0;\n const hasPendingOperation = pendingOperationRef.current !== null;\n\n const pause = useCallback(\n async (reason?: string): Promise<void> => {\n const ownedTargetKey = targetKey;\n const ownedGeneration = targetGeneration.current;\n if (!sessionId || pausing || targetKeyRef.current !== ownedTargetKey) {\n return;\n }\n setPausing(true);\n setError(null);\n try {\n await client.pauseSession(workspaceId, sessionId, {\n ...(reason !== undefined ? { reason } : {}),\n ...(options.effectiveControl?.controlEtag\n ? { expectedControlEtag: options.effectiveControl.controlEtag }\n : {}),\n });\n } catch (cause) {\n if (\n targetKeyRef.current === ownedTargetKey &&\n targetGeneration.current === ownedGeneration\n ) {\n setError(cause instanceof Error ? cause : new Error(String(cause)));\n }\n } finally {\n if (\n targetKeyRef.current === ownedTargetKey &&\n targetGeneration.current === ownedGeneration\n ) {\n setPausing(false);\n }\n }\n },\n [client, workspaceId, sessionId, pausing, options.effectiveControl?.controlEtag, targetKey],\n );\n\n const resume = useCallback(\n async (reason?: string): Promise<void> => {\n const ownedTargetKey = targetKey;\n const ownedGeneration = targetGeneration.current;\n if (!sessionId || resuming || targetKeyRef.current !== ownedTargetKey) return;\n setResuming(true);\n setError(null);\n try {\n await client.resumeSession(workspaceId, sessionId, {\n ...(reason !== undefined ? { reason } : {}),\n ...(options.effectiveControl?.controlEtag\n ? { expectedControlEtag: options.effectiveControl.controlEtag }\n : {}),\n });\n } catch (cause) {\n if (\n targetKeyRef.current === ownedTargetKey &&\n targetGeneration.current === ownedGeneration\n ) {\n setError(cause instanceof Error ? cause : new Error(String(cause)));\n }\n } finally {\n if (\n targetKeyRef.current === ownedTargetKey &&\n targetGeneration.current === ownedGeneration\n ) {\n setResuming(false);\n }\n }\n },\n [client, workspaceId, sessionId, resuming, options.effectiveControl?.controlEtag, targetKey],\n );\n\n const resumeScope = useCallback(\n async (option: EffectiveControlResumeOption): Promise<void> => {\n const ownedTargetKey = targetKey;\n const ownedGeneration = targetGeneration.current;\n if (!sessionId || resuming || targetKeyRef.current !== ownedTargetKey) return;\n setResuming(true);\n setError(null);\n try {\n if (option.scope === \"workspace\") {\n const workspaceBlocker = options.effectiveControl?.blockers.find(\n (blocker) => blocker.kind === \"workspace\",\n );\n if (!client.setWorkspaceInferenceState) {\n throw new Error(\n \"@opengeni/react: workspace-scoped resume requires setWorkspaceInferenceState.\",\n );\n }\n await client.setWorkspaceInferenceState(workspaceId, {\n action: \"resume\",\n clientEventId: generateClientEventId(),\n ...(workspaceBlocker ? { expectedRevision: workspaceBlocker.revision } : {}),\n });\n } else if (option.scope === \"session\" && option.targetId) {\n const target = await client.getQueue(workspaceId, option.targetId);\n if (\n targetKeyRef.current !== ownedTargetKey ||\n targetGeneration.current !== ownedGeneration\n ) {\n return;\n }\n await client.resumeSession(workspaceId, option.targetId, {\n expectedControlEtag: target.effectiveControl.controlEtag,\n });\n } else {\n await client.resumeSession(workspaceId, sessionId, {\n ...(options.effectiveControl?.controlEtag\n ? { expectedControlEtag: options.effectiveControl.controlEtag }\n : {}),\n });\n }\n } catch (cause) {\n if (\n targetKeyRef.current === ownedTargetKey &&\n targetGeneration.current === ownedGeneration\n ) {\n setError(asError(cause));\n }\n } finally {\n if (\n targetKeyRef.current === ownedTargetKey &&\n targetGeneration.current === ownedGeneration\n ) {\n setResuming(false);\n }\n }\n },\n [client, options.effectiveControl, resuming, sessionId, targetKey, workspaceId],\n );\n\n const updateValue = useCallback(\n (next: string) => {\n if (targetKeyRef.current !== targetKey) return;\n localEditRevision.current += 1;\n valueRef.current = next;\n pendingOperationRef.current = updatePendingComposerShadow(\n pendingOperationKey,\n pendingOperationRef.current,\n {\n text: next,\n resources: mergeResources(\n restoredResourcesRef.current,\n resolveSendExtras(sendExtrasRef.current).resources ?? [],\n ),\n },\n );\n setValue(next);\n },\n [pendingOperationKey, targetKey],\n );\n\n const removeRestoredResource = useCallback(\n (index: number) => {\n if (targetKeyRef.current !== targetKey) return;\n localEditRevision.current += 1;\n const next = restoredResourcesRef.current.filter((_, candidate) => candidate !== index);\n restoredResourcesRef.current = next;\n pendingOperationRef.current = updatePendingComposerShadow(\n pendingOperationKey,\n pendingOperationRef.current,\n {\n text: valueRef.current,\n resources: mergeResources(next, resolveSendExtras(sendExtrasRef.current).resources ?? []),\n },\n );\n setRestoredResources(next);\n },\n [pendingOperationKey, targetKey],\n );\n\n const hasDraftContent = useCallback((): boolean => {\n const current = draftRef.current;\n const extras = resolveSendExtras(sendExtrasRef.current);\n return (\n valueRef.current.length > 0 ||\n restoredResourcesRef.current.length > 0 ||\n (extras.resources?.length ?? 0) > 0 ||\n (current?.sourceTurnId !== null && current?.sourceTurnId !== undefined)\n );\n }, []);\n\n const resolveDraftConflict = useCallback(\n async (choice: \"keep_mine\" | \"use_remote\"): Promise<void> => {\n const ownedTargetKey = targetKey;\n const ownedGeneration = targetGeneration.current;\n if (!sessionId || !durableDrafts || targetKeyRef.current !== ownedTargetKey) return;\n const remote = await client.getComposerDraft(workspaceId, sessionId);\n if (targetKeyRef.current !== ownedTargetKey || targetGeneration.current !== ownedGeneration) {\n return;\n }\n if (choice === \"use_remote\") {\n applyDraft(remote);\n return;\n }\n draftRef.current = remote;\n setDraft(remote);\n setDraftConflict(null);\n const payload = currentDraftPayload();\n if (payload) await persistPayload({ ...payload, expectedRevision: remote.revision });\n },\n [\n applyDraft,\n client,\n currentDraftPayload,\n durableDrafts,\n persistPayload,\n sessionId,\n targetKey,\n workspaceId,\n ],\n );\n\n const identityMatches = stateTargetKey === targetKey;\n const reloadDraft = useCallback(async () => await loadDraft(true), [loadDraft]);\n const clearError = useCallback(() => {\n if (targetKeyRef.current !== targetKey) return;\n setError(null);\n setDraftConflict(null);\n }, [targetKey]);\n\n return {\n value: identityMatches ? value : \"\",\n setValue: updateValue,\n hasDraftContent,\n send,\n steer,\n sending: identityMatches ? sending : false,\n canSend:\n identityMatches &&\n Boolean(sessionId) &&\n !sending &&\n sendBlockedRef.current?.() !== true &&\n (hasPendingOperation || value.trim().length > 0 || hasReadyResources),\n pause,\n pausing: identityMatches ? pausing : false,\n resume,\n resumeScope,\n resuming: identityMatches ? resuming : false,\n draft: identityMatches ? draft : null,\n draftRevision: identityMatches ? (draft?.revision ?? 0) : 0,\n draftLoading: identityMatches ? draftLoading : Boolean(sessionId) && durableDrafts,\n draftSaving: identityMatches ? draftSaving : false,\n draftConflict: identityMatches ? draftConflict : null,\n draftPersistence: durableDrafts ? \"durable\" : \"disabled\",\n applyDraft,\n reloadDraft,\n resolveDraftConflict,\n restoredResources: identityMatches ? restoredResources : [],\n removeRestoredResource,\n error: identityMatches ? error : null,\n clearError,\n };\n}\n\n/** Events that can atomically replace or clear this subject's durable draft. */\nexport function isComposerDraftEvent(event: Pick<SessionEvent, \"type\">): boolean {\n return event.type === \"user.message\" || event.type === \"session.queue.changed\";\n}\n\n/**\n * Default text for a file-only message (attachment(s) present, no typed draft).\n * Kept non-empty so the wire contract (`text: z.string().min(1)`) and the\n * worker's non-whitespace guard accept it; the attached files still ride in\n * `resources`. Exported for tests.\n */\nexport const FILE_ONLY_MESSAGE_TEXT = \"(see attached files)\";\n\n/** Resolve possibly-deferred extras to a concrete bag (function evaluated now). */\nexport function resolveSendExtras(\n extras: ComposerSendExtras | (() => ComposerSendExtras) | undefined,\n): ComposerSendExtras {\n return (typeof extras === \"function\" ? extras() : extras) ?? {};\n}\n\n/**\n * Merge the draft text + idempotency key with caller-provided extras. The\n * text and clientEventId always win over extras. Exported for tests.\n */\nexport function composeSendInput(\n text: string,\n clientEventId: string,\n extras: ComposerSendExtras | (() => ComposerSendExtras) | undefined,\n bound: Partial<SendMessageInput> = {},\n): SendMessageInput {\n return { ...resolveSendExtras(extras), ...bound, text, clientEventId };\n}\n\n/** Submit on plain Enter; Shift+Enter inserts a newline. Exported for tests. */\nexport function shouldSubmitOnKey(event: {\n key: string;\n shiftKey: boolean;\n metaKey?: boolean;\n ctrlKey?: boolean;\n nativeEvent?: { isComposing?: boolean };\n}): boolean {\n if (event.key !== \"Enter\" || event.shiftKey) {\n return false;\n }\n return event.nativeEvent?.isComposing !== true;\n}\n\n/** Cmd/Ctrl+Enter steers; ordinary Enter appends to the queue. */\nexport function shouldSteerOnKey(event: { metaKey?: boolean; ctrlKey?: boolean }): boolean {\n return event.metaKey === true || event.ctrlKey === true;\n}\n\nfunction generateClientEventId(): string {\n return globalThis.crypto.randomUUID();\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\nfunction asError(cause: unknown): Error {\n return cause instanceof Error ? cause : new Error(String(cause));\n}\n\nfunction isDraftConflictError(error: Error): boolean {\n const apiError = error as Partial<OpenGeniApiError>;\n return (\n apiError.status === 409 &&\n apiError.outcomeUnknown === false &&\n (apiError.code === undefined ||\n apiError.code === \"conflict\" ||\n apiError.code === \"idempotency_conflict\")\n );\n}\n\nfunction draftPayload(draft: ComposerDraft): SaveComposerDraftRequest {\n return {\n expectedRevision: draft.revision,\n text: draft.text,\n resources: draft.resources,\n model: draft.model,\n reasoningEffort: draft.reasoningEffort,\n latencyMode: draft.latencyMode ?? \"standard\",\n };\n}\n\nfunction composerDraftPayload(\n base: ComposerDraft,\n text: string,\n restoredResources: ResourceRef[],\n extras: ComposerSendExtras,\n): SaveComposerDraftRequest {\n return {\n expectedRevision: base.revision,\n text,\n resources: mergeResources(restoredResources, extras.resources ?? []),\n model: extras.model ?? base.model,\n reasoningEffort: extras.reasoningEffort ?? base.reasoningEffort,\n latencyMode: extras.latencyMode ?? base.latencyMode ?? \"standard\",\n };\n}\n\nfunction draftSignature(payload: SaveComposerDraftRequest): string {\n const { expectedRevision: _revision, ...content } = payload;\n return JSON.stringify(content);\n}\n\nfunction mergeResources(base: ResourceRef[], additions: ResourceRef[]): ResourceRef[] {\n const seen = new Set<string>();\n return [...base, ...additions].filter((resource) => {\n // Reconnect reconciliation can restore the canonical server form while\n // the still-mounted upload card supplies the same ready file without its\n // default mount. Treat those two wire shapes as one selected attachment;\n // preserving the first representation keeps custom mounts and ordering\n // intact while preventing the draft and command paths from seeing\n // different duplicate counts after server normalization.\n const key =\n resource.kind === \"file\"\n ? `file:${resource.fileId}\\u0000${resource.mountPath ?? `files/${resource.fileId}`}`\n : JSON.stringify(resource);\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
humanizeFailureReason,
|
|
4
4
|
isCreditExhaustion,
|
|
5
5
|
tryParseJson
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-4QOQ2DSR.js";
|
|
7
7
|
|
|
8
8
|
// src/timeline/projection.ts
|
|
9
9
|
var { default: fleetDecisionItem } = await import("./fleet-decision-projection-SLNZMS42.js");
|
|
@@ -79,11 +79,10 @@ function buildTimeline(events) {
|
|
|
79
79
|
if (inputs.length === 0) break;
|
|
80
80
|
closeStreamingTail();
|
|
81
81
|
items.push({
|
|
82
|
-
kind: "
|
|
82
|
+
kind: "machine-input-batch",
|
|
83
83
|
id: event.id,
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
details: { label: "Inputs", value: inputs },
|
|
84
|
+
turnId,
|
|
85
|
+
members: inputs,
|
|
87
86
|
occurredAt: event.occurredAt
|
|
88
87
|
});
|
|
89
88
|
break;
|
|
@@ -111,14 +110,25 @@ function buildTimeline(events) {
|
|
|
111
110
|
}
|
|
112
111
|
case "agent.message.completed": {
|
|
113
112
|
const text = stringValue(payload.text);
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
113
|
+
let openIndex = -1;
|
|
114
|
+
for (let index = items.length - 1; index >= 0; index -= 1) {
|
|
115
|
+
const candidate2 = items[index];
|
|
116
|
+
if (candidate2?.kind === "agent-message" && candidate2.turnId === turnId) {
|
|
117
|
+
openIndex = index;
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const candidate = openIndex >= 0 ? items[openIndex] : void 0;
|
|
122
|
+
const open = candidate?.kind === "agent-message" ? candidate : void 0;
|
|
117
123
|
if (open && (open.streaming || !open.text || text === open.text || text.startsWith(open.text))) {
|
|
118
124
|
if (!open.text || text && text.startsWith(open.text)) {
|
|
119
125
|
open.text = text || open.text;
|
|
120
126
|
}
|
|
121
127
|
open.streaming = false;
|
|
128
|
+
if (openIndex < items.length - 1) {
|
|
129
|
+
items.splice(openIndex, 1);
|
|
130
|
+
items.push(open);
|
|
131
|
+
}
|
|
122
132
|
break;
|
|
123
133
|
}
|
|
124
134
|
if (text) {
|
|
@@ -173,6 +183,21 @@ function buildTimeline(events) {
|
|
|
173
183
|
});
|
|
174
184
|
break;
|
|
175
185
|
}
|
|
186
|
+
if (callId) {
|
|
187
|
+
const existing = [...items].reverse().find(
|
|
188
|
+
(item) => item.kind === "tool-call" && item.callId === callId
|
|
189
|
+
);
|
|
190
|
+
if (existing) {
|
|
191
|
+
if (args != null) {
|
|
192
|
+
existing.arguments = args;
|
|
193
|
+
}
|
|
194
|
+
if (payload.raw !== void 0) {
|
|
195
|
+
existing.raw = mergeToolCallRaw(existing.raw, payload.raw);
|
|
196
|
+
}
|
|
197
|
+
existing.status = providerNativeToolStatus(existing.raw);
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
176
201
|
items.push({
|
|
177
202
|
kind: "tool-call",
|
|
178
203
|
id: event.id,
|
|
@@ -184,7 +209,7 @@ function buildTimeline(events) {
|
|
|
184
209
|
// The provider-native item drives the per-tool renderers (apply_patch
|
|
185
210
|
// operation, computer_call action, web_search providerData, …).
|
|
186
211
|
raw: payload.raw,
|
|
187
|
-
status:
|
|
212
|
+
status: providerNativeToolStatus(payload.raw),
|
|
188
213
|
occurredAt: event.occurredAt
|
|
189
214
|
});
|
|
190
215
|
break;
|
|
@@ -266,7 +291,12 @@ ${message}` : message;
|
|
|
266
291
|
if (previous?.status === status) {
|
|
267
292
|
break;
|
|
268
293
|
}
|
|
269
|
-
items.push({
|
|
294
|
+
items.push({
|
|
295
|
+
kind: "session-status",
|
|
296
|
+
id: event.id,
|
|
297
|
+
status,
|
|
298
|
+
occurredAt: event.occurredAt
|
|
299
|
+
});
|
|
270
300
|
break;
|
|
271
301
|
}
|
|
272
302
|
case "session.requiresAction": {
|
|
@@ -280,27 +310,48 @@ ${message}` : message;
|
|
|
280
310
|
});
|
|
281
311
|
break;
|
|
282
312
|
}
|
|
313
|
+
case "session.context.compaction.requested":
|
|
314
|
+
case "session.context.compaction.started": {
|
|
315
|
+
closeStreamingTail();
|
|
316
|
+
settleOrPushContextCompaction(items, {
|
|
317
|
+
id: event.id,
|
|
318
|
+
turnId,
|
|
319
|
+
phase: "started",
|
|
320
|
+
trigger: compactionTrigger(payload),
|
|
321
|
+
estimatedTokensBefore: numberOrNull(payload.estimatedTokensBefore),
|
|
322
|
+
estimatedTokensAfter: null,
|
|
323
|
+
skipReason: null,
|
|
324
|
+
implementation: typeof payload.implementation === "string" ? payload.implementation : null,
|
|
325
|
+
occurredAt: event.occurredAt
|
|
326
|
+
});
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
283
329
|
case "session.context.compacted": {
|
|
284
330
|
closeStreamingTail();
|
|
285
|
-
|
|
286
|
-
const after = typeof payload.estimatedTokensAfter === "number" ? Math.round(payload.estimatedTokensAfter).toLocaleString("en-US") : null;
|
|
287
|
-
items.push({
|
|
288
|
-
kind: "notice",
|
|
331
|
+
settleOrPushContextCompaction(items, {
|
|
289
332
|
id: event.id,
|
|
290
|
-
|
|
291
|
-
|
|
333
|
+
turnId,
|
|
334
|
+
phase: "compacted",
|
|
335
|
+
trigger: compactionTrigger(payload),
|
|
336
|
+
estimatedTokensBefore: numberOrNull(payload.estimatedTokensBefore),
|
|
337
|
+
estimatedTokensAfter: numberOrNull(payload.estimatedTokensAfter),
|
|
338
|
+
skipReason: null,
|
|
339
|
+
implementation: typeof payload.implementation === "string" ? payload.implementation : null,
|
|
292
340
|
occurredAt: event.occurredAt
|
|
293
341
|
});
|
|
294
342
|
break;
|
|
295
343
|
}
|
|
296
344
|
case "session.context.compaction.skipped": {
|
|
297
345
|
closeStreamingTail();
|
|
298
|
-
|
|
299
|
-
items.push({
|
|
300
|
-
kind: "notice",
|
|
346
|
+
settleOrPushContextCompaction(items, {
|
|
301
347
|
id: event.id,
|
|
302
|
-
|
|
303
|
-
|
|
348
|
+
turnId,
|
|
349
|
+
phase: "skipped",
|
|
350
|
+
trigger: compactionTrigger(payload),
|
|
351
|
+
estimatedTokensBefore: numberOrNull(payload.estimatedTokensBefore),
|
|
352
|
+
estimatedTokensAfter: null,
|
|
353
|
+
skipReason: typeof payload.reason === "string" ? payload.reason : null,
|
|
354
|
+
implementation: typeof payload.implementation === "string" ? payload.implementation : null,
|
|
304
355
|
occurredAt: event.occurredAt
|
|
305
356
|
});
|
|
306
357
|
break;
|
|
@@ -421,8 +472,54 @@ ${message}` : message;
|
|
|
421
472
|
break;
|
|
422
473
|
}
|
|
423
474
|
}
|
|
475
|
+
for (const item of items) {
|
|
476
|
+
if (item.kind === "agent-message") {
|
|
477
|
+
item.text = stripOpaqueCitationTokens(item.text);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
424
480
|
return items;
|
|
425
481
|
}
|
|
482
|
+
function providerNativeToolStatus(rawValue) {
|
|
483
|
+
const raw = asRecord(rawValue);
|
|
484
|
+
if (raw.type !== "hosted_tool_call") {
|
|
485
|
+
return "running";
|
|
486
|
+
}
|
|
487
|
+
switch (raw.status) {
|
|
488
|
+
case "completed":
|
|
489
|
+
return "complete";
|
|
490
|
+
case "failed":
|
|
491
|
+
case "incomplete":
|
|
492
|
+
return "failed";
|
|
493
|
+
case "cancelled":
|
|
494
|
+
return "cancelled";
|
|
495
|
+
default:
|
|
496
|
+
return "running";
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
function mergeToolCallRaw(existingValue, nextValue) {
|
|
500
|
+
const existing = asRecord(existingValue);
|
|
501
|
+
const next = asRecord(nextValue);
|
|
502
|
+
if (Object.keys(next).length === 0) {
|
|
503
|
+
return existingValue;
|
|
504
|
+
}
|
|
505
|
+
const existingProvider = asRecord(existing.providerData);
|
|
506
|
+
const nextProvider = asRecord(next.providerData);
|
|
507
|
+
const providerData = {
|
|
508
|
+
...existingProvider,
|
|
509
|
+
...nextProvider
|
|
510
|
+
};
|
|
511
|
+
if (existingProvider.action != null && (nextProvider.action == null || typeof nextProvider.action === "object" && nextProvider.action !== null && Object.keys(nextProvider.action).length === 0)) {
|
|
512
|
+
providerData.action = existingProvider.action;
|
|
513
|
+
}
|
|
514
|
+
return {
|
|
515
|
+
...existing,
|
|
516
|
+
...next,
|
|
517
|
+
...Object.keys(providerData).length > 0 ? { providerData } : {}
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
function stripOpaqueCitationTokens(text) {
|
|
521
|
+
return text.replace(/\s*cite(?:[^]+)+/gu, "");
|
|
522
|
+
}
|
|
426
523
|
function isCreditExhaustionPayload(payload) {
|
|
427
524
|
return isCreditExhaustion({
|
|
428
525
|
error: typeof payload.error === "string" ? payload.error : null,
|
|
@@ -475,7 +572,11 @@ function groupTimeline(items) {
|
|
|
475
572
|
if (open?.kind === "activity" && open.outcome === void 0) {
|
|
476
573
|
open.items.push(item);
|
|
477
574
|
} else {
|
|
478
|
-
groups.push({
|
|
575
|
+
groups.push({
|
|
576
|
+
kind: "activity",
|
|
577
|
+
id: `activity-${item.id}`,
|
|
578
|
+
items: [item]
|
|
579
|
+
});
|
|
479
580
|
}
|
|
480
581
|
continue;
|
|
481
582
|
}
|
|
@@ -541,7 +642,12 @@ function prescanTurnAnchors(events) {
|
|
|
541
642
|
cancelledBeforeStartTriggers.add(triggerEventId);
|
|
542
643
|
}
|
|
543
644
|
}
|
|
544
|
-
return {
|
|
645
|
+
return {
|
|
646
|
+
queuedTurnByTrigger,
|
|
647
|
+
startSeqByTrigger,
|
|
648
|
+
cancelledBeforeStartTriggers,
|
|
649
|
+
startedTurnIds
|
|
650
|
+
};
|
|
545
651
|
}
|
|
546
652
|
function orderTimelineEvents(events, prescan) {
|
|
547
653
|
const ordered = [...events].sort((a, b) => a.sequence - b.sequence);
|
|
@@ -675,13 +781,16 @@ function foldSettledTurn(groups, turnEnd) {
|
|
|
675
781
|
return;
|
|
676
782
|
}
|
|
677
783
|
const firstOccurredAt = groupStartedAt(body[0]) ?? turnEnd.occurredAt;
|
|
784
|
+
const prior = startIndex > 0 ? groups[startIndex - 1] : void 0;
|
|
785
|
+
const contextCompactionCount = prior?.kind === "item" && prior.item.kind === "context-compaction" && prior.item.phase === "compacted" ? 1 : 0;
|
|
678
786
|
const turnGroup = {
|
|
679
787
|
kind: "turn",
|
|
680
788
|
id: `turn-${turnEnd.turnId ?? turnEnd.id}`,
|
|
681
789
|
outcome: turnEnd.outcome,
|
|
682
790
|
startedAt: firstOccurredAt,
|
|
683
791
|
endedAt: turnEnd.occurredAt,
|
|
684
|
-
groups: body
|
|
792
|
+
groups: body,
|
|
793
|
+
...contextCompactionCount > 0 ? { contextCompactionCount } : {}
|
|
685
794
|
};
|
|
686
795
|
if (turnEnd.failureText) {
|
|
687
796
|
turnGroup.failureText = turnEnd.failureText;
|
|
@@ -693,7 +802,7 @@ function foldSettledTurn(groups, turnEnd) {
|
|
|
693
802
|
);
|
|
694
803
|
}
|
|
695
804
|
function isTurnBoundary(group) {
|
|
696
|
-
return group?.kind === "turn" || group?.kind === "item" && (group.item.kind === "user-message" || group.item.kind === "notice" && group.item.tone === "input");
|
|
805
|
+
return group?.kind === "turn" || group?.kind === "item" && (group.item.kind === "user-message" || group.item.kind === "context-compaction" || group.item.kind === "notice" && group.item.tone === "input");
|
|
697
806
|
}
|
|
698
807
|
function belongsToDifferentTurn(group, turnId) {
|
|
699
808
|
if (!group || !turnId) {
|
|
@@ -736,13 +845,68 @@ function asRecord(value) {
|
|
|
736
845
|
function stringValue(value) {
|
|
737
846
|
return typeof value === "string" ? value : "";
|
|
738
847
|
}
|
|
848
|
+
function numberOrNull(value) {
|
|
849
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
850
|
+
}
|
|
851
|
+
function compactionTrigger(payload) {
|
|
852
|
+
const trigger = payload.trigger;
|
|
853
|
+
return trigger === "auto" || trigger === "operator" || trigger === "proactive" || trigger === "overflow" ? trigger : null;
|
|
854
|
+
}
|
|
855
|
+
function settleOrPushContextCompaction(items, next) {
|
|
856
|
+
const openIndex = findOpenContextCompactionIndex(items, next.turnId);
|
|
857
|
+
if (openIndex >= 0) {
|
|
858
|
+
const open = items[openIndex];
|
|
859
|
+
if (open?.kind === "context-compaction") {
|
|
860
|
+
items[openIndex] = {
|
|
861
|
+
...open,
|
|
862
|
+
...next,
|
|
863
|
+
// Prefer the settled event id so keys stay stable with the finish row.
|
|
864
|
+
id: next.phase === "started" ? open.id : next.id,
|
|
865
|
+
trigger: next.trigger ?? open.trigger,
|
|
866
|
+
estimatedTokensBefore: next.estimatedTokensBefore ?? open.estimatedTokensBefore,
|
|
867
|
+
implementation: next.implementation ?? open.implementation
|
|
868
|
+
};
|
|
869
|
+
return;
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
items.push({ kind: "context-compaction", ...next });
|
|
873
|
+
}
|
|
874
|
+
function findOpenContextCompactionIndex(items, turnId) {
|
|
875
|
+
for (let index = items.length - 1; index >= 0; index -= 1) {
|
|
876
|
+
const item = items[index];
|
|
877
|
+
if (item?.kind !== "context-compaction" || item.phase !== "started") {
|
|
878
|
+
continue;
|
|
879
|
+
}
|
|
880
|
+
if (turnId && item.turnId && item.turnId !== turnId) {
|
|
881
|
+
continue;
|
|
882
|
+
}
|
|
883
|
+
return index;
|
|
884
|
+
}
|
|
885
|
+
return -1;
|
|
886
|
+
}
|
|
739
887
|
function machineInputMembers(value) {
|
|
888
|
+
const kinds = /* @__PURE__ */ new Set([
|
|
889
|
+
"scheduled_occurrence",
|
|
890
|
+
"goal_continuation",
|
|
891
|
+
"agent_message",
|
|
892
|
+
"agent_steer_instruction",
|
|
893
|
+
"child_terminal_result"
|
|
894
|
+
]);
|
|
895
|
+
const classifications = /* @__PURE__ */ new Set([
|
|
896
|
+
"success",
|
|
897
|
+
"failure",
|
|
898
|
+
"action_required",
|
|
899
|
+
"info"
|
|
900
|
+
]);
|
|
740
901
|
return Array.isArray(value) ? value.flatMap((candidate) => {
|
|
741
902
|
const member = asRecord(candidate);
|
|
742
|
-
return typeof member.id === "string" && typeof member.kind === "string" && typeof member.
|
|
903
|
+
return typeof member.id === "string" && typeof member.kind === "string" && kinds.has(member.kind) && typeof member.classification === "string" && classifications.has(
|
|
904
|
+
member.classification
|
|
905
|
+
) && typeof member.sourceId === "string" ? [
|
|
743
906
|
{
|
|
744
907
|
id: member.id,
|
|
745
|
-
kind: member.kind
|
|
908
|
+
kind: member.kind,
|
|
909
|
+
classification: member.classification,
|
|
746
910
|
sourceId: member.sourceId,
|
|
747
911
|
summary: stringValue(member.summary)
|
|
748
912
|
}
|
|
@@ -964,4 +1128,4 @@ export {
|
|
|
964
1128
|
groupTimeline,
|
|
965
1129
|
extractSessionRef
|
|
966
1130
|
};
|
|
967
|
-
//# sourceMappingURL=chunk-
|
|
1131
|
+
//# sourceMappingURL=chunk-TCCE5ZU5.js.map
|