@athenaintel/react 0.26.6 → 0.28.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 (75) hide show
  1. package/README.md +32 -1
  2. package/dist/chat/StatewireApprovalCard.cjs +19 -0
  3. package/dist/chat/StatewireApprovalCard.cjs.map +1 -1
  4. package/dist/chat/StatewireApprovalCard.js +19 -0
  5. package/dist/chat/StatewireApprovalCard.js.map +1 -1
  6. package/dist/chat/message-time.cjs.map +1 -1
  7. package/dist/chat/message-time.d.ts +4 -3
  8. package/dist/chat/message-time.js.map +1 -1
  9. package/dist/composer/QuoteContext.cjs +13 -1
  10. package/dist/composer/QuoteContext.cjs.map +1 -1
  11. package/dist/composer/QuoteContext.d.ts +11 -1
  12. package/dist/composer/QuoteContext.js +13 -1
  13. package/dist/composer/QuoteContext.js.map +1 -1
  14. package/dist/diagnostics/athena-diagnostics.cjs.map +1 -1
  15. package/dist/diagnostics/athena-diagnostics.d.ts +1 -1
  16. package/dist/diagnostics/athena-diagnostics.js.map +1 -1
  17. package/dist/diagnostics/errors.cjs +11 -2
  18. package/dist/diagnostics/errors.cjs.map +1 -1
  19. package/dist/diagnostics/errors.d.ts +11 -2
  20. package/dist/diagnostics/errors.js +11 -2
  21. package/dist/diagnostics/errors.js.map +1 -1
  22. package/dist/lib/athena-urls.cjs +1 -1
  23. package/dist/lib/athena-urls.cjs.map +1 -1
  24. package/dist/lib/athena-urls.js +1 -1
  25. package/dist/lib/athena-urls.js.map +1 -1
  26. package/dist/lib/posthog/mask-sensitive-input.cjs +34 -0
  27. package/dist/lib/posthog/mask-sensitive-input.cjs.map +1 -0
  28. package/dist/lib/posthog/mask-sensitive-input.d.ts +9 -0
  29. package/dist/lib/posthog/mask-sensitive-input.js +34 -0
  30. package/dist/lib/posthog/mask-sensitive-input.js.map +1 -0
  31. package/dist/packages/agent-runtime/src/conversation-index.cjs +2 -1
  32. package/dist/packages/agent-runtime/src/conversation-index.cjs.map +1 -1
  33. package/dist/packages/agent-runtime/src/conversation-index.js +2 -1
  34. package/dist/packages/agent-runtime/src/conversation-index.js.map +1 -1
  35. package/dist/packages/agent-runtime/src/generated/runconfig-contract.cjs +2 -0
  36. package/dist/packages/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
  37. package/dist/packages/agent-runtime/src/generated/runconfig-contract.js +2 -0
  38. package/dist/packages/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
  39. package/dist/packages/agent-runtime/src/interrupts.cjs +26 -8
  40. package/dist/packages/agent-runtime/src/interrupts.cjs.map +1 -1
  41. package/dist/packages/agent-runtime/src/interrupts.js +26 -8
  42. package/dist/packages/agent-runtime/src/interrupts.js.map +1 -1
  43. package/dist/packages/agent-runtime/src/messages.cjs +70 -14
  44. package/dist/packages/agent-runtime/src/messages.cjs.map +1 -1
  45. package/dist/packages/agent-runtime/src/messages.js +71 -15
  46. package/dist/packages/agent-runtime/src/messages.js.map +1 -1
  47. package/dist/packages/agent-runtime/src/tool-metadata.cjs +75 -0
  48. package/dist/packages/agent-runtime/src/tool-metadata.cjs.map +1 -1
  49. package/dist/packages/agent-runtime/src/tool-metadata.js +75 -0
  50. package/dist/packages/agent-runtime/src/tool-metadata.js.map +1 -1
  51. package/dist/packages/agent-runtime/src/tool-result.cjs +19 -4
  52. package/dist/packages/agent-runtime/src/tool-result.cjs.map +1 -1
  53. package/dist/packages/agent-runtime/src/tool-result.js +19 -4
  54. package/dist/packages/agent-runtime/src/tool-result.js.map +1 -1
  55. package/dist/packages/agent-runtime/src/use-deep-agent-thread.cjs +23 -4
  56. package/dist/packages/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
  57. package/dist/packages/agent-runtime/src/use-deep-agent-thread.js +24 -5
  58. package/dist/packages/agent-runtime/src/use-deep-agent-thread.js.map +1 -1
  59. package/dist/packages/react/package.json.cjs +1 -1
  60. package/dist/packages/react/package.json.js +1 -1
  61. package/dist/provider/AthenaProvider.cjs +3 -0
  62. package/dist/provider/AthenaProvider.cjs.map +1 -1
  63. package/dist/provider/AthenaProvider.js +3 -0
  64. package/dist/provider/AthenaProvider.js.map +1 -1
  65. package/dist/provider/PostHogProvider.cjs +3 -1
  66. package/dist/provider/PostHogProvider.cjs.map +1 -1
  67. package/dist/provider/PostHogProvider.js +3 -1
  68. package/dist/provider/PostHogProvider.js.map +1 -1
  69. package/dist/runtime/auth.cjs +307 -108
  70. package/dist/runtime/auth.cjs.map +1 -1
  71. package/dist/runtime/auth.d.ts +151 -10
  72. package/dist/runtime/auth.js +307 -108
  73. package/dist/runtime/auth.js.map +1 -1
  74. package/dist/styles.css +1 -1
  75. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"use-deep-agent-thread.js","sources":["../../../../../agent-runtime/src/use-deep-agent-thread.ts"],"sourcesContent":["import type { LangChainMessage } from '@assistant-ui/react-langgraph';\nimport { StatewireThread } from '@assistant-ui/react-statewire';\nimport { withKey } from '@assistant-ui/tap';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n type AuthDenialTrackerState,\n initialAuthDenialTrackerState,\n observeAuthDenial,\n} from './auth-denial';\nimport {\n createDeepAgentAttachTransport,\n type DeepAgentHeadersResolver,\n} from './deep-agent-transport-recipe';\nimport { projectDeepAgentConnection } from './errors';\nimport { type DeepAgentMessageAuthor, isSameMessageAuthor } from './message-author';\nimport { DEEP_AGENT_INTEREST_PROTOCOL } from './generated/runconfig-contract';\nimport {\n type DeepAgentMessageWindowDeclaration,\n headInterestRequest,\n readDeepAgentMessageWindow,\n} from './message-window';\nimport { convertDeepAgentState, createDeepAgentMaterialize } from './messages';\nimport { type DeepAgentProtocolStatus, projectDeepAgentProtocol } from './protocol';\nimport type { DeepAgentAttachTimingEvent } from './statewire-attach-observer';\nimport type { StatewireDiagnosticsRecorder } from './statewire-diagnostics';\nimport { isDeepAgentStateHydrated, readDeepAgentStreamValues } from './statewire-state';\nimport { StatewireSuspended } from './statewire-suspended';\nimport {\n DEEP_AGENT_STATEWIRE_PROTOCOL,\n type StatewireTransportOptions,\n} from './statewire-transport';\nimport type { DeepAgentThreadPrewarmPool } from './thread-prewarm';\nimport { type DeepAgentThreadSnapshotCache, toThreadSnapshotSeed } from './thread-snapshot-cache';\nimport type { DeepAgentToolOutputStore } from './tool-outputs';\nimport type { DeepAgentWithdrawnTurns } from './withdrawn-turns';\nimport type {\n DeepAgentConnectionState,\n DeepAgentLaneProjection,\n DeepAgentStreamValues,\n} from './types';\n\ntype ThreadOptions = StatewireThread.Options<DeepAgentStreamValues>;\n\nexport type { DeepAgentHeadersResolver } from './deep-agent-transport-recipe';\n\n/**\n * How an attach's FIRST frame is sourced, decided once per attach at mount: the\n * hello a pooled pre-dialed attach already replicated (`prewarm`), a remembered\n * snapshot seed (`snapshot`), or nothing (`none` — the thread loads until its\n * hello).\n */\nexport type DeepAgentAttachSource = 'prewarm' | 'snapshot' | 'none';\n\nexport interface UseDeepAgentThreadOptions {\n threadId: string;\n /** Base URL of the deep-agent statewire host (the `…/v2/threads` mount). */\n baseUrl: string;\n /** Transport selection: SSE when true, WebSocket otherwise. */\n sse?: boolean;\n /**\n * Auth headers for the transport. Statewire passes `{ staleAuth: true }`\n * when the previous credential was refused, so resolvers that can\n * force-renew should honor it.\n */\n headers: DeepAgentHeadersResolver;\n /**\n * Statewire session store for reconnect command-session recovery (e.g. the\n * mobile AsyncStorage-backed store). Host-resolved; omitted, sessions are\n * process-local.\n */\n sessionStore?: StatewireTransportOptions['sessionStore'];\n /**\n * Mounted storage seams for the thread: `session` holds the lane identity and\n * the commands still awaiting a durable verdict, so a reload resumes the lane\n * instead of minting a new client (browser hosts pass `LocalStorageSession`\n * from `@assistant-ui/react-statewire/local-storage`); `composer` persists the\n * draft. Mutually exclusive with `sessionStore` — statewire refuses a session\n * mounted twice.\n */\n storage?: ThreadOptions['storage'];\n /** True only for a never-started local chat; existing empty threads still load until their snapshot. */\n isNewChat?: boolean;\n /**\n * Extra transport-key discriminator for the SAME thread. The session is keyed\n * by `threadId` alone by default; hosts that must re-read the server snapshot\n * without a thread switch (a run dispatched outside this client, e.g. a\n * backgrounded AOP run writing the thread's first messages) bump this to\n * remount the session against the same URL.\n */\n attachKey?: string | number;\n /**\n * Host gate: park the transport instead of attaching — no socket, no retry\n * loop. The thread element stays mounted so assistant-ui consumers keep\n * rendering. Pass it when the host already knows every attach would be denied (e.g.\n * the signed-in user has no workspace yet), so a locked-out tab does not\n * hammer the attach endpoint on every backoff interval.\n */\n suspended?: { reason: string } | false;\n /**\n * Adapter capabilities the host UI exposes. Defaults preserve each client's\n * pre-extraction surface — pass what the product mounts.\n */\n capabilities?: {\n edit?: boolean;\n continue?: boolean;\n reload?: boolean;\n unstable_switchBranch?: boolean;\n };\n /** Which run lanes project into the message tail; see {@link DeepAgentLaneProjection}. */\n laneProjection?: DeepAgentLaneProjection;\n /**\n * The viewer, as the backend would stamp them (`metadata.custom.author`).\n * Stamped onto this client's own optimistic bubbles — a send still in flight\n * has no host `meta` yet — so a just-sent turn is attributed, and the\n * multi-author avatar gate flips for a second poster, without waiting for\n * the acknowledgment. Replicated entries carry the host's own stamp instead.\n * Compared field-wise, so callers need not memoize the object.\n */\n selfAuthor?: DeepAgentMessageAuthor | null;\n /**\n * Snapshot host context when each user message is submitted, before it is\n * journaled. Includes programmatic appends, keyboard sends, queued messages,\n * steering, and edits. The async getter starts immediately at submission;\n * sends retain their order while it resolves. Retries, queue text edits,\n * lane moves, reload, and continue preserve the original association.\n * Return JSON-serializable metadata; optional capture failures can\n * return an explicit null field rather than blocking the message.\n *\n * Declared structurally rather than as `ThreadOptions['getMessageMetadata']`:\n * the option is what the monorepo patches into\n * `@assistant-ui/react-statewire@0.29.1`, and the published sources must also\n * compile against the unpatched upstream typings, where the library does not\n * know the option and ignores it.\n */\n getMessageMetadata?:\n | (() => Record<string, unknown> | undefined | Promise<Record<string, unknown> | undefined>)\n | undefined;\n /** Host-owned adapters: attachments (upload/mention choreography), speech, feedback. */\n adapters?: ThreadOptions['adapters'];\n /**\n * Transport lifecycle recorder (attach latency, reconnect loops, command\n * settle fates, stale-auth renewals) fed from the hook's own seams. Pass one\n * only when the host's diagnostics channel is enabled — the recorder is\n * observed on hot paths, and an absent recorder costs a single optional call.\n */\n diagnostics?: StatewireDiagnosticsRecorder;\n /**\n * Per-tab LRU of the last wire state seen per thread. When set, every\n * hydrated state the transport publishes is remembered, and a mount of a\n * remembered thread seeds `initialState` from the cache (through\n * {@link toThreadSnapshotSeed}) — the thread renders its last-known\n * messages on the first frame instead of holding a loading treatment for\n * the attach round-trip, and projects \"running\" when the run was live at\n * capture (else \"ready\"). The attach snapshot then\n * REPLACES the seeded state (statewire's `initialState` contract), so a\n * thread that advanced elsewhere reconciles in one round-trip. New chats\n * keep their preload and never read the cache.\n */\n snapshotCache?: DeepAgentThreadSnapshotCache;\n /**\n * The head window this surface wants: declared on every attach\n * (`x-athena-deep-agent-window`, part of the transport recipe) so the hello\n * of a client the host does not remember carries the newest `size`\n * messages, and stated as `athena/interest` after the hello only when the\n * hello's head is narrower — never to shrink it (the host holds what a\n * viewer has loaded for the life of its connection). The resolved chain is\n * joined with the mounted message documents into the converted transcript\n * (see `message-window.ts`); older pages load through\n * `useDeepAgentWindowSync`. Read once per attach.\n */\n messageWindow?: DeepAgentMessageWindowDeclaration;\n /**\n * Full tool outputs fetched back for the wire's cut tool messages\n * (`history/tool_output`); the thread re-converts when one lands.\n */\n toolOutputs?: DeepAgentToolOutputStore;\n /**\n * User turns this client took back ahead of the wire (a user stop before\n * any assistant output); the thread re-converts when one opens or closes.\n */\n withdrawnTurns?: DeepAgentWithdrawnTurns;\n /**\n * Pre-dialed attaches (see `thread-prewarm.ts`). When the pool holds a root\n * for this thread at mount, the thread takes the hello it replicated as its\n * seed — the transcript is the first frame — and dials its own attach\n * against the instance the pool warmed; the pooled root is disposed in the\n * same step, so one socket is live per thread after mount. Never seeded for\n * a preloaded new chat or a suspended attach; such a root is discarded.\n */\n prewarmPool?: DeepAgentThreadPrewarmPool<DeepAgentStreamValues>;\n /**\n * Attach-path timing: socket open, hello size + handler cost, server retry\n * hints — attributed to the attach's own thread, since a late event from the\n * thread being left can land after the host has moved on.\n */\n onAttachTiming?: (info: { threadId: string; event: DeepAgentAttachTimingEvent }) => void;\n /** Where this attach's first frame comes from; once per attach, at mount. */\n onAttachSource?: (info: { threadId: string; source: DeepAgentAttachSource }) => void;\n /** Full transport error policy (paywall, toast, telemetry) — client-owned. */\n onError?: ThreadOptions['onError'];\n /**\n * Raw statewire state observer (first-attach latches, telemetry). The state\n * argument is never `undefined`/`null`: passes where the wire has no\n * snapshot yet (pre-attach, replay boundaries) deliver the typed\n * `DEEP_AGENT_PRE_STREAM_STATE` default — `isDeepAgentStateHydrated`\n * distinguishes them from a real (possibly empty) snapshot.\n */\n onStateChange?: ThreadOptions['onStateChange'];\n /** Raw command-lifecycle observer (send-failure salvage, telemetry). */\n onCommandChange?: ThreadOptions['onCommandChange'];\n /** Raw connection observer (reconnect handles, telemetry). */\n onRawConnectionChange?: ThreadOptions['onConnectionChange'];\n /**\n * Projected connection status changes, deduped per thread, with `null` on\n * unmount so an indicator never shows a stale status.\n */\n onConnectionChange?: (connection: DeepAgentConnectionState | null) => void;\n /** Notified when a run starts/stops so the page can reflect the running thread. */\n onRunningChange?: (isRunning: boolean) => void;\n /**\n * Notified once per thread with the `runConfig` carried by the statewire\n * snapshot (the backend's persisted panel config, seeded in `_load_history`),\n * so the host can hydrate its config store from the thread. Notified with\n * `null` (at most once per attach) when a server snapshot arrives WITHOUT a\n * persisted config, so a host waiting on hydration can stop waiting; a\n * config appearing on a later snapshot of the same attach (mirrored at run\n * start) still delivers the config notification.\n */\n onServerRunConfig?: (config: Record<string, unknown> | null) => void;\n /**\n * Notified when the snapshot's `outOfBandRunActive` flag changes: the host set\n * it while a run executing OUTSIDE this surface (an AOP / HTTP-route run)\n * is actively writing the thread's bare-namespace history, which the host\n * live-refreshes onto the wire. Lets the page show run-in-progress\n * treatment instead of an empty conversation, and stand down its own\n * re-attach polling. Change-notified per attach (an initial `false` before\n * the snapshot stays silent), mirroring `onRunningChange`.\n */\n onOutOfBandRunActive?: (outOfBandRunActive: boolean) => void;\n /**\n * Notified with the state's session-asset lifecycle flag\n * ({@link readSessionPersisted}) PAIRED with the thread it describes: `false`\n * while the thread's `session` asset provably does not exist yet (a\n * never-started chat's preload, a first run before the mint), `true` once\n * minted, `null` when the state carries no flag (a host that predates it).\n *\n * Fired from the converter pass, so the pair is read from the state of the\n * thread this attach was mounted for. A component reading the flag off the\n * client store instead lags the mounted thread id by one render on a switch\n * and can pair the new id with the previous thread's flag — releasing a\n * session-scoped read for a row the backend has not minted. Change-notified\n * per attach; the first pass of every attach notifies, so a host holding a\n * read back until it hears from the mounted thread always does.\n */\n onSessionPersistedChange?: (event: {\n threadId: string;\n sessionPersisted: boolean | null;\n }) => void;\n /**\n * Notified with the wire-contract status once the attach snapshot\n * advertises the `protocol` lane, and again whenever it changes (a\n * re-attach after a server roll can advertise a new `version`). Telemetry\n * and per-version behaviour only: the host has no minimum client version,\n * so nothing about the status gates a send. Never called for\n * pre-declaration servers (their snapshots carry no lane) — absence of a\n * call means \"no advertisement\", not \"compatible\".\n */\n onProtocolChange?: (status: DeepAgentProtocolStatus) => void;\n}\n\n/** One thread's replicated running state, keyed so a switch between two\n * threads with the same status still re-notifies (the host page clears its\n * per-thread state on selection, mirroring the connection dedupe below). */\nexport interface RunningSnapshot {\n threadId: string;\n isRunning: boolean;\n}\n\n/** Whether the thread's `session` asset exists, read off a statewire state, or\n * `null` when the state does not carry the flag.\n *\n * Absence is not absence of the asset: a snapshot from a host that predates\n * the flag has no such key, and reading that as \"the asset does not exist\"\n * would gate a read the client is entitled to make, with nothing left to\n * un-gate it. A new thread's preload seeds `false` (see `initialState`), so\n * the pre-attach pass of a chat that cannot have an asset yet still gates.\n *\n * Hosts pass this to `useStatewireState` so the flag and the thread it belongs\n * to are read in one component — a thread switch then cannot pair one thread's\n * id with the other's flag. */\nexport function readSessionPersisted(state: unknown): boolean | null {\n const flag = (state as { sessionPersisted?: unknown } | null)?.sessionPersisted;\n return typeof flag === 'boolean' ? flag : null;\n}\n\n/** Whether a converter pass must notify `onRunningChange`.\n *\n * The mount's very first status notifies only when it is `true` (a snapshot\n * carrying a live run) — an initial `false` before the snapshot must stay\n * silent so it cannot clear a still-valid indicator. After that, every\n * transition notifies, and so does the first status after a thread switch\n * (the host page clears its per-thread state on selection, so a switch\n * between two threads with the same status must still re-notify). */\nexport function shouldNotifyRunningChange(\n previous: RunningSnapshot | null,\n next: RunningSnapshot\n): boolean {\n if (previous === null) return next.isRunning;\n return previous.threadId !== next.threadId || previous.isRunning !== next.isRunning;\n}\n\n/**\n * The shared deep-agent Statewire thread.\n *\n * `StatewireThread` (from `@assistant-ui/react-statewire`) attaches to the\n * agora-hosted thread at `${baseUrl}/${threadId}` (WebSocket by default,\n * with SSE retained only as a host-selected compatibility switch): the backend\n * hosts the thread state and this client\n * replicates it live, so the server snapshot is the single source of history\n * (no local import, no `/status` resume probing) and run scheduling — queueing,\n * steering, stop, edit rewinds — rides the built-in `run/*` commands.\n *\n * The thread element is keyed by `threadId`, so a thread switch remounts the\n * session against the new URL instead of importing history in place.\n *\n * Returns the thread element for the host's own `useAui({ thread })` — web\n * hosts take `useAui` from `@assistant-ui/react`, React Native hosts from\n * `@assistant-ui/react-native`; this package imports neither.\n */\nexport function useDeepAgentThread({\n threadId,\n baseUrl,\n sse = false,\n headers,\n sessionStore,\n storage,\n isNewChat = false,\n attachKey,\n suspended = false,\n capabilities,\n laneProjection = 'both',\n selfAuthor = null,\n getMessageMetadata,\n adapters,\n diagnostics,\n snapshotCache,\n messageWindow,\n toolOutputs,\n withdrawnTurns,\n prewarmPool,\n onAttachTiming,\n onAttachSource,\n onError,\n onStateChange,\n onCommandChange,\n onRawConnectionChange,\n onConnectionChange,\n onRunningChange,\n onServerRunConfig,\n onOutOfBandRunActive,\n onSessionPersistedChange,\n onProtocolChange,\n}: UseDeepAgentThreadOptions) {\n const onRunningChangeRef = useRef(onRunningChange);\n onRunningChangeRef.current = onRunningChange;\n const onSessionPersistedChangeRef = useRef(onSessionPersistedChange);\n onSessionPersistedChangeRef.current = onSessionPersistedChange;\n const onConnectionChangeRef = useRef(onConnectionChange);\n onConnectionChangeRef.current = onConnectionChange;\n const onServerRunConfigRef = useRef(onServerRunConfig);\n onServerRunConfigRef.current = onServerRunConfig;\n const onOutOfBandRunActiveRef = useRef(onOutOfBandRunActive);\n onOutOfBandRunActiveRef.current = onOutOfBandRunActive;\n const onProtocolChangeRef = useRef(onProtocolChange);\n onProtocolChangeRef.current = onProtocolChange;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const onStateChangeRef = useRef(onStateChange);\n onStateChangeRef.current = onStateChange;\n const onCommandChangeRef = useRef(onCommandChange);\n onCommandChangeRef.current = onCommandChange;\n const onRawConnectionChangeRef = useRef(onRawConnectionChange);\n onRawConnectionChangeRef.current = onRawConnectionChange;\n const headersRef = useRef(headers);\n headersRef.current = headers;\n const messageWindowRef = useRef(messageWindow);\n messageWindowRef.current = messageWindow;\n // The head interest is checked once per connected session, after the hello\n // negotiated the lane (a statement before that would be minted durable):\n // the hello carries the host's head — the attach header's size, or what\n // this client id held — and a set goes out only to widen it.\n const interestRef = useRef({ attachId: '', stated: false });\n // The last joined transcript, held across the gap between a hello and its\n // interest answer (and across a reconnect) so the thread never blanks.\n const lastMessagesRef = useRef<{ attachId: string; messages: LangChainMessage[] } | null>(null);\n // A fetched tool output must re-run the converter (the store is read inside\n // it); the version is the memo's signal that the store's contents moved.\n const [toolOutputsVersion, setToolOutputsVersion] = useState(0);\n useEffect(() => {\n if (!toolOutputs) return undefined;\n return toolOutputs.subscribe(() => setToolOutputsVersion((version) => version + 1));\n }, [toolOutputs]);\n const [withdrawnTurnsVersion, setWithdrawnTurnsVersion] = useState(0);\n useEffect(() => {\n if (!withdrawnTurns) return undefined;\n return withdrawnTurns.subscribe(() => setWithdrawnTurnsVersion((version) => version + 1));\n }, [withdrawnTurns]);\n const diagnosticsRef = useRef(diagnostics);\n diagnosticsRef.current = diagnostics;\n const onAttachTimingRef = useRef(onAttachTiming);\n onAttachTimingRef.current = onAttachTiming;\n const onAttachSourceRef = useRef(onAttachSource);\n onAttachSourceRef.current = onAttachSource;\n\n const lastRunningRef = useRef<RunningSnapshot | null>(null);\n // Out-of-band run activity (`outOfBandRunActive`), change-notified with the\n // same semantics as the running flag above.\n const lastOutOfBandRunActiveRef = useRef<RunningSnapshot | null>(null);\n // The session-asset lifecycle flag last notified, keyed by attach so every\n // attach's first pass notifies (a host holding a read back until it hears\n // from the mounted thread must always hear from it).\n const lastSessionPersistedRef = useRef<{\n attachId: string;\n threadId: string;\n sessionPersisted: boolean | null;\n } | null>(null);\n // The last wire-contract status notified, keyed by attach so a re-attach\n // re-notifies (the new snapshot may advertise a different version).\n // `status: null` = nothing advertised yet on this attach.\n const lastProtocolRef = useRef<{\n attachId: string;\n status: DeepAgentProtocolStatus | null;\n } | null>(null);\n // The thread whose statewire-carried runConfig has been surfaced to the host\n // (once per thread; later snapshots must not clobber edits).\n const appliedStateRunConfigThreadRef = useRef<string | null>(null);\n // The attach that already notified `onServerRunConfig(null)` (snapshot\n // arrived carrying no persisted config) — at most once per attach.\n const absentStateRunConfigAttachRef = useRef<string | null>(null);\n // Live thread id for the callbacks: they are created per render but may\n // settle after a switch, so they compare against the current id.\n const threadIdRef = useRef(threadId);\n threadIdRef.current = threadId;\n // Identity of the current attach. Every per-thread latch keys off this, so a\n // re-attach of the same thread (a bumped `attachKey`) re-notifies the host\n // exactly like a switch would — the host clears its per-thread state on\n // re-attach, so a snapshot that repeats the previous status must not dedupe.\n const attachId: string = attachKey === undefined ? threadId : `${threadId}:${attachKey}`;\n const attachIdRef = useRef(attachId);\n attachIdRef.current = attachId;\n\n // Auth-denial park: the server fins every denied attach `unauthorized` and\n // the reconnect loop would otherwise retry it every 30s forever (prod tabs\n // looped for hours against revoked/workspace-less credentials). After a\n // streak of denials the live transport is swapped for a parked one; a new\n // attach (thread switch, bumped attachKey) or the parked connection's\n // `reconnect()` re-arms it.\n const [authParked, setAuthParked] = useState<{\n attachId: string;\n message: string | undefined;\n } | null>(null);\n const authDenialRef = useRef<{ attachId: string; state: AuthDenialTrackerState }>({\n attachId,\n state: initialAuthDenialTrackerState(),\n });\n useEffect(() => {\n setAuthParked((prev) => (prev !== null && prev.attachId !== attachId ? null : prev));\n }, [attachId]);\n\n // Field-wise stable identity for the viewer stamp, so a host that rebuilds\n // the author object per render does not rebuild the converter (and with it\n // every message) per render. Adjusting state during render is React's\n // sanctioned derived-state pattern: it re-renders once with the new value.\n const [stableSelfAuthor, setStableSelfAuthor] = useState(selfAuthor);\n if (!isSameMessageAuthor(stableSelfAuthor, selfAuthor)) setStableSelfAuthor(selfAuthor);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: toolOutputsVersion / withdrawnTurnsVersion are the stores' change signals — the converter reads the stores' contents, not the counters.\n const converter = useMemo(\n () => (state: unknown, isRunning: boolean) => {\n // Statewire snapshots carry the thread's persisted panel config (the\n // backend seeds `runConfig` in `_load_history` and mirrors it on run\n // start). Surface it once per thread so the host can hydrate its config\n // store.\n const stateRunConfig = (state as { runConfig?: unknown } | null)?.runConfig;\n if (\n stateRunConfig &&\n typeof stateRunConfig === 'object' &&\n !Array.isArray(stateRunConfig) &&\n appliedStateRunConfigThreadRef.current !== attachIdRef.current\n ) {\n appliedStateRunConfigThreadRef.current = attachIdRef.current;\n const notifyRunConfig = onServerRunConfigRef.current;\n if (notifyRunConfig) {\n queueMicrotask(() => notifyRunConfig(stateRunConfig as Record<string, unknown>));\n }\n } else if (\n !stateRunConfig &&\n appliedStateRunConfigThreadRef.current !== attachIdRef.current &&\n absentStateRunConfigAttachRef.current !== attachIdRef.current &&\n projectDeepAgentProtocol(state) !== null\n ) {\n // No persisted config on a SERVER state: the protocol lane rides every\n // attach snapshot, so its presence distinguishes \"the server answered\n // without a config\" from the pre-attach `initialState` (which must not\n // end the host's hydration wait).\n absentStateRunConfigAttachRef.current = attachIdRef.current;\n const notifyRunConfig = onServerRunConfigRef.current;\n if (notifyRunConfig) {\n queueMicrotask(() => notifyRunConfig(null));\n }\n }\n // Out-of-band run activity: the host live-refreshes a bare-namespace\n // (AOP / HTTP-route) thread's transcript while its run is active and\n // flags the wire state so the page can reflect it.\n const stateOutOfBandRunActive =\n (state as { outOfBandRunActive?: unknown } | null)?.outOfBandRunActive === true;\n const outOfBandRunActiveSnapshot = {\n threadId: attachIdRef.current,\n isRunning: stateOutOfBandRunActive,\n };\n if (shouldNotifyRunningChange(lastOutOfBandRunActiveRef.current, outOfBandRunActiveSnapshot)) {\n lastOutOfBandRunActiveRef.current = outOfBandRunActiveSnapshot;\n const observedAttachId = attachIdRef.current;\n queueMicrotask(() => {\n // A re-attach or newer snapshot between the converter pass and this\n // microtask owns the channel now — a stale flag must not leak into\n // the new attach's per-thread state.\n if (\n attachIdRef.current !== observedAttachId ||\n lastOutOfBandRunActiveRef.current !== outOfBandRunActiveSnapshot\n ) {\n return;\n }\n onOutOfBandRunActiveRef.current?.(stateOutOfBandRunActive);\n });\n }\n // Wire-contract advertisement: the host publishes the `protocol` lane in\n // every attach snapshot. Notify on first advertisement and on change\n // (dedupe by value, re-keyed per attach), with the same stale-guard\n // microtask as the other observers.\n const protocolStatus = projectDeepAgentProtocol(state);\n if (protocolStatus !== null) {\n const previous =\n lastProtocolRef.current?.attachId === attachIdRef.current\n ? lastProtocolRef.current.status\n : null;\n if (previous === null || previous.protocolVersion !== protocolStatus.protocolVersion) {\n const update = { attachId: attachIdRef.current, status: protocolStatus };\n lastProtocolRef.current = update;\n queueMicrotask(() => {\n if (lastProtocolRef.current !== update || attachIdRef.current !== update.attachId) {\n return;\n }\n onProtocolChangeRef.current?.(protocolStatus);\n });\n }\n }\n const runningSnapshot = { threadId: attachIdRef.current, isRunning };\n if (shouldNotifyRunningChange(lastRunningRef.current, runningSnapshot)) {\n lastRunningRef.current = runningSnapshot;\n const notify = onRunningChangeRef.current;\n if (notify) queueMicrotask(() => notify(isRunning));\n }\n return {\n ...convertDeepAgentState(state, {\n laneProjection,\n selfAuthor: stableSelfAuthor,\n toolOutputs,\n withdrawnTurns,\n }),\n state: state as StatewireThread.State['state'],\n };\n },\n [\n laneProjection,\n stableSelfAuthor,\n toolOutputs,\n toolOutputsVersion,\n withdrawnTurns,\n withdrawnTurnsVersion,\n ]\n );\n const materialize = useMemo(\n () => createDeepAgentMaterialize({ selfAuthor: stableSelfAuthor }),\n [stableSelfAuthor]\n );\n\n // Surface the statewire connection status through `onConnectionChange` (the\n // converter re-runs on connection changes), and clear it when the runtime\n // unmounts so an indicator never shows a stale status. Dedup is keyed by\n // thread: the runtime stays mounted across idle thread switches, so the new\n // thread's first status must notify even when it equals the previous\n // thread's last one.\n const lastConnectionRef = useRef<{\n threadId: string;\n connection: DeepAgentConnectionState;\n } | null>(null);\n useEffect(\n () => () => {\n lastConnectionRef.current = null;\n onConnectionChangeRef.current?.(null);\n },\n []\n );\n\n // The preload decision pins at thread entry: `isNewChat` flips once the\n // thread persists, but the mount that began as a new thread stays preloaded.\n const preloadRef = useRef({ threadId, preload: isNewChat });\n if (preloadRef.current.threadId !== threadId)\n preloadRef.current = { threadId, preload: isNewChat };\n\n const snapshotCacheRef = useRef(snapshotCache);\n snapshotCacheRef.current = snapshotCache;\n // The snapshot seed pins at attach identity, like the preload decision: the\n // cache is read once per mount, so a mid-session cache write (this thread's\n // own states being remembered) never changes what `initialState` was.\n //\n // A suspended attach never seeds: the suspended transport never dials, so a\n // seed would be served indefinitely — under a view-as lens that would paint\n // thread content the parked transport exists to withhold (the lens must\n // show what the LENSED identity is authorized to see, and only the server\n // can decide that).\n //\n // The pooled hello is taken the same way: exactly once, at the attach's\n // first render (the pool disposes its root in that step).\n const snapshotSeedRef = useRef<{\n attachId: string;\n seed: DeepAgentStreamValues | undefined;\n } | null>(null);\n if (snapshotSeedRef.current === null || snapshotSeedRef.current.attachId !== attachId) {\n const preload = preloadRef.current.preload;\n let pooledState: DeepAgentStreamValues | undefined;\n if (prewarmPool?.has(threadId)) {\n if (preload || suspended) {\n // This mount attaches on its own terms (or not at all): the pooled\n // dial must not linger as a second socket to the same session.\n prewarmPool.discard(threadId);\n } else {\n pooledState = prewarmPool.take(threadId)?.state;\n }\n }\n // The pooled hello outranks a remembered snapshot (it is newer by\n // construction); a pooled dial that had not landed seeds like a plain\n // attach and reconciles when this attach's own hello lands.\n const remembered =\n preload || suspended ? undefined : (pooledState ?? snapshotCache?.take(threadId));\n const seed = remembered ? toThreadSnapshotSeed(remembered) : undefined;\n snapshotSeedRef.current = { attachId, seed };\n const source: DeepAgentAttachSource =\n pooledState !== undefined ? 'prewarm' : seed ? 'snapshot' : 'none';\n const notifySource = onAttachSourceRef.current;\n if (notifySource) queueMicrotask(() => notifySource({ threadId, source }));\n }\n\n // react-statewire memoizes the converted thread on this function's\n // identity, so an inline closure would re-run `convertDeepAgentState` over\n // the whole transcript on every host render. Keyed on the attach identity (a\n // re-attach re-keys its per-thread latches); everything else the body needs\n // is read through the per-render refs above.\n const threadConverter = useCallback<ThreadOptions['converter']>(\n (wireState, meta) => {\n // The wire main document carries no messages: join the interest window\n // off the mounted documents, fold the dispatch record onto it, and hand\n // the composite on as the thread state every reader sees.\n const values = readDeepAgentStreamValues(wireState);\n const window = readDeepAgentMessageWindow(meta.mounted);\n const held =\n lastMessagesRef.current?.attachId === attachId ? lastMessagesRef.current.messages : null;\n const messages = window?.messages ?? values.messages ?? held ?? [];\n if (window !== null || messages.length > 0) lastMessagesRef.current = { attachId, messages };\n const state: DeepAgentStreamValues = { ...values, messages: [...messages] };\n materialize(state);\n if (window !== null && isDeepAgentStateHydrated(values)) {\n snapshotCacheRef.current?.remember(threadId, state);\n }\n if (interestRef.current.attachId !== attachId) {\n interestRef.current = { attachId, stated: false };\n }\n if (meta.connection.status !== 'connected') {\n interestRef.current.stated = false;\n } else if (!interestRef.current.stated) {\n interestRef.current.stated = true;\n const wanted = headInterestRequest(messageWindowRef.current?.size);\n const head = window?.requests[0];\n // The hello's head is kept whenever it is at least what this surface\n // wants (a remembered client's wider view, the declared header):\n // stating a narrower head would shrink what the viewer holds. A\n // narrower head — or none, a host without the lane — is widened, the\n // hello's pages kept alongside.\n const preloaded = head !== undefined && head.at === undefined && head.before >= wanted.before;\n if (!preloaded) {\n const requests = [\n wanted,\n ...(window?.requests.filter((request) => request.at !== undefined) ?? []),\n ];\n queueMicrotask(() => {\n if (attachIdRef.current !== attachId) return;\n meta\n .invoke(DEEP_AGENT_INTEREST_PROTOCOL, 'set', [requests])\n .catch((error: unknown) => {\n onErrorRef.current?.(error instanceof Error ? error : new Error(String(error)));\n });\n });\n }\n }\n // Projected once per pass through the single seam; every fold below\n // consumes the projection (the recorder projects the raw connection\n // itself, so any host observer can feed it).\n const connection = projectDeepAgentConnection(meta.connection);\n // Transition-deduped inside the recorder, so this per-pass observation\n // is free while the connection is unchanged.\n diagnosticsRef.current?.observeConnection(meta.connection);\n // Fold this pass's connection into the denial streak (the converter\n // re-runs on every reconnect-attempt bump). Parking is deferred to a\n // microtask like every other notification here.\n if (authDenialRef.current.attachId !== attachIdRef.current) {\n authDenialRef.current = {\n attachId: attachIdRef.current,\n state: initialAuthDenialTrackerState(),\n };\n }\n const denial = observeAuthDenial(authDenialRef.current.state, connection);\n authDenialRef.current.state = denial.state;\n if (denial.park) {\n const parkAttachId = attachIdRef.current;\n const parkMessage = denial.state.message;\n // The server refused authorization for this thread: any remembered\n // snapshot must not warm-paint it on a later mount (permissions may\n // have been revoked since the state was captured).\n snapshotCacheRef.current?.forget(threadId);\n queueMicrotask(() => {\n if (attachIdRef.current !== parkAttachId) return;\n setAuthParked((prev) =>\n prev?.attachId === parkAttachId\n ? prev\n : { attachId: parkAttachId, message: parkMessage }\n );\n });\n }\n const previous = lastConnectionRef.current;\n if (\n previous?.threadId !== attachId ||\n !Object.keys({ ...previous.connection, ...connection }).every(\n (key) => Reflect.get(previous.connection, key) === Reflect.get(connection, key)\n )\n ) {\n const update = { threadId: attachId, connection };\n lastConnectionRef.current = update;\n queueMicrotask(() => {\n // A newer projection, a thread switch, or the unmount cleanup owns\n // the channel now.\n if (lastConnectionRef.current !== update || attachIdRef.current !== attachId) return;\n onConnectionChangeRef.current?.(connection);\n });\n }\n // Session-asset lifecycle, paired with THIS attach's thread by closure:\n // the state converted here is the state of the thread the element was\n // built for, so the pair can never straddle a switch (a client-store\n // read would). Deduped by value per attach. A pass from an attach the\n // host has already replaced never touches the latch — it could otherwise\n // cancel the current attach's still-queued verdict — and the microtask\n // guard drops a pass whose attach is replaced before it settles.\n if (attachIdRef.current === attachId) {\n const sessionPersisted = readSessionPersisted(state);\n const lastSession = lastSessionPersistedRef.current;\n if (\n lastSession?.attachId !== attachId ||\n lastSession.sessionPersisted !== sessionPersisted\n ) {\n const sessionUpdate = { attachId, threadId, sessionPersisted };\n lastSessionPersistedRef.current = sessionUpdate;\n queueMicrotask(() => {\n if (\n lastSessionPersistedRef.current !== sessionUpdate ||\n attachIdRef.current !== attachId\n ) {\n return;\n }\n onSessionPersistedChangeRef.current?.({ threadId, sessionPersisted });\n });\n }\n }\n // The replicated run status IS the running signal: the lib's run-dialect\n // fold flips it to \"running\" on the send, before the app converter runs,\n // so the optimistic window needs no hand-tracked flag.\n return converter(state, state.runs?.[0]?.status === 'running');\n },\n [attachId, converter, materialize, threadId]\n );\n\n return StatewireThread<DeepAgentStreamValues>({\n // The transport stamps this protocol on every command; the thread client\n // must declare it too or the core skips the optimistic folds and a send\n // stays invisible until the server frame lands.\n protocol: DEEP_AGENT_STATEWIRE_PROTOCOL,\n // New threads preload an empty runs mount and report `deferred` — the\n // composer is interactive before the stream attaches and pre-attach sends\n // render through the optimistic folds. Existing threads omit the runs\n // mount and project \"loading\" until the attach snapshot: the server seeds\n // messages/todos/runConfig in `_load_history`.\n //\n // The preload also seeds `sessionPersisted: false`: a never-started chat\n // provably has no `session` asset until its first run mints one, so the\n // wire carries that from the first render and a host reading the flag off\n // the state needs no separate \"is this a new chat\" knowledge. An existing\n // thread leaves it absent (unknown) so its asset read is never gated.\n initialState:\n snapshotSeedRef.current.seed ??\n ({\n messages: [],\n todos: [],\n ...(preloadRef.current.preload && { runs: [], sessionPersisted: false }),\n } satisfies DeepAgentStreamValues),\n // Keyed by thread: a switch unmounts the previous thread's session and\n // remounts against the new URL, so the converter never sees the previous\n // thread's snapshot (a new thread serves its preload again, an existing\n // one loads until its snapshot). A host-suspended or auth-parked attach\n // swaps in the never-dialing transport instead.\n transport: withKey(\n attachId,\n (() => {\n if (suspended) return StatewireSuspended({ message: suspended.reason });\n if (authParked !== null && authParked.attachId === attachId) {\n return StatewireSuspended({\n message: authParked.message ?? 'Session authorization was refused.',\n onReconnectRequested: () => {\n authDenialRef.current = {\n attachId: attachIdRef.current,\n state: initialAuthDenialTrackerState(),\n };\n setAuthParked(null);\n },\n });\n }\n // The shared recipe (URL, auth + wire-contract headers, session lane,\n // attach instrumentation, retry-hint floor) — the same one the prewarm\n // pool dials with, so the instance a pooled attach warmed is the one\n // this dial reaches. A never-started chat dials nothing until its\n // first send.\n return createDeepAgentAttachTransport<DeepAgentStreamValues>({\n baseUrl,\n threadId,\n sse,\n isNew: preloadRef.current.preload,\n headers: (ctx) => headersRef.current(ctx),\n messageWindow: messageWindowRef.current,\n sessionStore,\n onAuthResolve: (ctx) => diagnosticsRef.current?.observeAuthResolve(ctx),\n onAttachTiming: (event) => onAttachTimingRef.current?.({ threadId, event }),\n });\n })()\n ),\n // Survives the transport remounts above: a bumped attachKey re-attaches the\n // same lane, and a persistent session storage carries it across reloads.\n ...(storage && { storage }),\n // The run subsystem (status, lanes, input requests, runId) is mounted on\n // the state root and always replicated by react-statewire >= 0.14 (the\n // former `runs: true` opt-in is gone) — the converter only maps app-owned\n // keys, including the `run/stop` runId stamp the lib projects itself.\n converter: threadConverter,\n // Native message editing: an edited turn is resubmitted as a `run/edit`\n // command, and the deep-agent backend rewinds the checkpointed thread to\n // the edited message's parent before appending (route `plan_rewind`).\n capabilities: capabilities ?? { edit: true },\n ...(getMessageMetadata && { getMessageMetadata }),\n ...(adapters && { adapters }),\n contextSync: 'command-send',\n // The Stop control is the only `cancelRun()` caller — teardown paths\n // unmount the keyed transport instead — so every `run/stop` is a\n // deliberate user stop.\n stopPayload: () => ({ reason: 'user_stop' }),\n onError: (error) => {\n diagnosticsRef.current?.observeError(error);\n onErrorRef.current?.(error);\n },\n ...(onStateChange && {\n // The lib types the observed state `NonNullable`, but the runtime\n // delivers `undefined` where the wire has no snapshot (pre-attach and\n // replay boundaries republish it) — normalize so the type is true and\n // host observers never crash on a field read.\n onStateChange: ((state, ctx) => {\n onStateChangeRef.current?.(readDeepAgentStreamValues(state), ctx);\n }) satisfies ThreadOptions['onStateChange'],\n }),\n ...((onCommandChange || diagnostics) && {\n onCommandChange: ((update, ctx) => {\n diagnosticsRef.current?.observeCommand(update);\n onCommandChangeRef.current?.(update, ctx);\n }) satisfies ThreadOptions['onCommandChange'],\n }),\n ...(onRawConnectionChange && {\n onConnectionChange: ((connection) =>\n onRawConnectionChangeRef.current?.(\n connection\n )) satisfies ThreadOptions['onConnectionChange'],\n }),\n });\n}\n"],"names":["_a"],"mappings":"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"}
1
+ {"version":3,"file":"use-deep-agent-thread.js","sources":["../../../../../agent-runtime/src/use-deep-agent-thread.ts"],"sourcesContent":["import type { LangChainMessage } from '@assistant-ui/react-langgraph';\nimport { StatewireThread } from '@assistant-ui/react-statewire';\nimport { withKey } from '@assistant-ui/tap';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n type AuthDenialTrackerState,\n initialAuthDenialTrackerState,\n observeAuthDenial,\n} from './auth-denial';\nimport {\n createDeepAgentAttachTransport,\n type DeepAgentHeadersResolver,\n} from './deep-agent-transport-recipe';\nimport { projectDeepAgentConnection } from './errors';\nimport { type DeepAgentMessageAuthor, isSameMessageAuthor } from './message-author';\nimport { DEEP_AGENT_INTEREST_PROTOCOL } from './generated/runconfig-contract';\nimport {\n type DeepAgentMessageWindowDeclaration,\n headInterestRequest,\n readDeepAgentMessageWindow,\n} from './message-window';\nimport {\n convertDeepAgentState,\n createDeepAgentMaterialize,\n createDeepAgentMessageConversionCache,\n type DeepAgentMessageConversionCache,\n} from './messages';\nimport { type DeepAgentProtocolStatus, projectDeepAgentProtocol } from './protocol';\nimport type { DeepAgentAttachTimingEvent } from './statewire-attach-observer';\nimport type { StatewireDiagnosticsRecorder } from './statewire-diagnostics';\nimport { isDeepAgentStateHydrated, readDeepAgentStreamValues } from './statewire-state';\nimport { StatewireSuspended } from './statewire-suspended';\nimport {\n DEEP_AGENT_STATEWIRE_PROTOCOL,\n type StatewireTransportOptions,\n} from './statewire-transport';\nimport type { DeepAgentThreadPrewarmPool } from './thread-prewarm';\nimport { type DeepAgentThreadSnapshotCache, toThreadSnapshotSeed } from './thread-snapshot-cache';\nimport type { DeepAgentToolOutputStore } from './tool-outputs';\nimport type { DeepAgentWithdrawnTurns } from './withdrawn-turns';\nimport type {\n DeepAgentConnectionState,\n DeepAgentLaneProjection,\n DeepAgentStreamValues,\n} from './types';\n\ntype ThreadOptions = StatewireThread.Options<DeepAgentStreamValues>;\n\nexport type { DeepAgentHeadersResolver } from './deep-agent-transport-recipe';\n\n/**\n * How an attach's FIRST frame is sourced, decided once per attach at mount: the\n * hello a pooled pre-dialed attach already replicated (`prewarm`), a remembered\n * snapshot seed (`snapshot`), or nothing (`none` — the thread loads until its\n * hello).\n */\nexport type DeepAgentAttachSource = 'prewarm' | 'snapshot' | 'none';\n\nexport interface UseDeepAgentThreadOptions {\n threadId: string;\n /** Base URL of the deep-agent statewire host (the `…/v2/threads` mount). */\n baseUrl: string;\n /** Transport selection: SSE when true, WebSocket otherwise. */\n sse?: boolean;\n /**\n * Auth headers for the transport. Statewire passes `{ staleAuth: true }`\n * when the previous credential was refused, so resolvers that can\n * force-renew should honor it.\n */\n headers: DeepAgentHeadersResolver;\n /**\n * Statewire session store for reconnect command-session recovery (e.g. the\n * mobile AsyncStorage-backed store). Host-resolved; omitted, sessions are\n * process-local.\n */\n sessionStore?: StatewireTransportOptions['sessionStore'];\n /**\n * Mounted storage seams for the thread: `session` holds the lane identity and\n * the commands still awaiting a durable verdict, so a reload resumes the lane\n * instead of minting a new client (browser hosts pass `LocalStorageSession`\n * from `@assistant-ui/react-statewire/local-storage`); `composer` persists the\n * draft. Mutually exclusive with `sessionStore` — statewire refuses a session\n * mounted twice.\n */\n storage?: ThreadOptions['storage'];\n /** True only for a never-started local chat; existing empty threads still load until their snapshot. */\n isNewChat?: boolean;\n /**\n * Extra transport-key discriminator for the SAME thread. The session is keyed\n * by `threadId` alone by default; hosts that must re-read the server snapshot\n * without a thread switch (a run dispatched outside this client, e.g. a\n * backgrounded AOP run writing the thread's first messages) bump this to\n * remount the session against the same URL.\n */\n attachKey?: string | number;\n /**\n * Host gate: park the transport instead of attaching — no socket, no retry\n * loop. The thread element stays mounted so assistant-ui consumers keep\n * rendering. Pass it when the host already knows every attach would be denied (e.g.\n * the signed-in user has no workspace yet), so a locked-out tab does not\n * hammer the attach endpoint on every backoff interval.\n */\n suspended?: { reason: string } | false;\n /**\n * Adapter capabilities the host UI exposes. Defaults preserve each client's\n * pre-extraction surface — pass what the product mounts.\n */\n capabilities?: {\n edit?: boolean;\n continue?: boolean;\n reload?: boolean;\n unstable_switchBranch?: boolean;\n };\n /** Which run lanes project into the message tail; see {@link DeepAgentLaneProjection}. */\n laneProjection?: DeepAgentLaneProjection;\n /**\n * The viewer, as the backend would stamp them (`metadata.custom.author`).\n * Stamped onto this client's own optimistic bubbles — a send still in flight\n * has no host `meta` yet — so a just-sent turn is attributed, and the\n * multi-author avatar gate flips for a second poster, without waiting for\n * the acknowledgment. Replicated entries carry the host's own stamp instead.\n * Compared field-wise, so callers need not memoize the object.\n */\n selfAuthor?: DeepAgentMessageAuthor | null;\n /**\n * Snapshot host context when each user message is submitted, before it is\n * journaled. Includes programmatic appends, keyboard sends, queued messages,\n * steering, and edits. The async getter starts immediately at submission;\n * sends retain their order while it resolves. Retries, queue text edits,\n * lane moves, reload, and continue preserve the original association.\n * Return JSON-serializable metadata; optional capture failures can\n * return an explicit null field rather than blocking the message.\n *\n * Declared structurally rather than as `ThreadOptions['getMessageMetadata']`:\n * the option is what the monorepo patches into\n * `@assistant-ui/react-statewire@0.29.1`, and the published sources must also\n * compile against the unpatched upstream typings, where the library does not\n * know the option and ignores it.\n */\n getMessageMetadata?:\n | (() => Record<string, unknown> | undefined | Promise<Record<string, unknown> | undefined>)\n | undefined;\n /** Host-owned adapters: attachments (upload/mention choreography), speech, feedback. */\n adapters?: ThreadOptions['adapters'];\n /**\n * Transport lifecycle recorder (attach latency, reconnect loops, command\n * settle fates, stale-auth renewals) fed from the hook's own seams. Pass one\n * only when the host's diagnostics channel is enabled — the recorder is\n * observed on hot paths, and an absent recorder costs a single optional call.\n */\n diagnostics?: StatewireDiagnosticsRecorder;\n /**\n * Per-tab LRU of the last wire state seen per thread. When set, every\n * hydrated state the transport publishes is remembered, and a mount of a\n * remembered thread seeds `initialState` from the cache (through\n * {@link toThreadSnapshotSeed}) — the thread renders its last-known\n * messages on the first frame instead of holding a loading treatment for\n * the attach round-trip, and projects \"running\" when the run was live at\n * capture (else \"ready\"). The attach snapshot then\n * REPLACES the seeded state (statewire's `initialState` contract), so a\n * thread that advanced elsewhere reconciles in one round-trip. New chats\n * keep their preload and never read the cache.\n */\n snapshotCache?: DeepAgentThreadSnapshotCache;\n /**\n * The head window this surface wants: declared on every attach\n * (`x-athena-deep-agent-window`, part of the transport recipe) so the hello\n * of a client the host does not remember carries the newest `size`\n * messages, and stated as `athena/interest` after the hello only when the\n * hello's head is narrower — never to shrink it (the host holds what a\n * viewer has loaded for the life of its connection). The resolved chain is\n * joined with the mounted message documents into the converted transcript\n * (see `message-window.ts`); older pages load through\n * `useDeepAgentWindowSync`. Read once per attach.\n */\n messageWindow?: DeepAgentMessageWindowDeclaration;\n /**\n * Full tool outputs fetched back for the wire's cut tool messages\n * (`history/tool_output`); the thread re-converts when one lands.\n */\n toolOutputs?: DeepAgentToolOutputStore;\n /**\n * User turns this client took back ahead of the wire (a user stop before\n * any assistant output); the thread re-converts when one opens or closes.\n */\n withdrawnTurns?: DeepAgentWithdrawnTurns;\n /**\n * Pre-dialed attaches (see `thread-prewarm.ts`). When the pool holds a root\n * for this thread at mount, the thread takes the hello it replicated as its\n * seed — the transcript is the first frame — and dials its own attach\n * against the instance the pool warmed; the pooled root is disposed in the\n * same step, so one socket is live per thread after mount. Never seeded for\n * a preloaded new chat or a suspended attach; such a root is discarded.\n */\n prewarmPool?: DeepAgentThreadPrewarmPool<DeepAgentStreamValues>;\n /**\n * Attach-path timing: socket open, hello size + handler cost, server retry\n * hints — attributed to the attach's own thread, since a late event from the\n * thread being left can land after the host has moved on.\n */\n onAttachTiming?: (info: { threadId: string; event: DeepAgentAttachTimingEvent }) => void;\n /** Where this attach's first frame comes from; once per attach, at mount. */\n onAttachSource?: (info: { threadId: string; source: DeepAgentAttachSource }) => void;\n /** Full transport error policy (paywall, toast, telemetry) — client-owned. */\n onError?: ThreadOptions['onError'];\n /**\n * Raw statewire state observer (first-attach latches, telemetry). The state\n * argument is never `undefined`/`null`: passes where the wire has no\n * snapshot yet (pre-attach, replay boundaries) deliver the typed\n * `DEEP_AGENT_PRE_STREAM_STATE` default — `isDeepAgentStateHydrated`\n * distinguishes them from a real (possibly empty) snapshot.\n */\n onStateChange?: ThreadOptions['onStateChange'];\n /** Raw command-lifecycle observer (send-failure salvage, telemetry). */\n onCommandChange?: ThreadOptions['onCommandChange'];\n /** Raw connection observer (reconnect handles, telemetry). */\n onRawConnectionChange?: ThreadOptions['onConnectionChange'];\n /**\n * Projected connection status changes, deduped per thread, with `null` on\n * unmount so an indicator never shows a stale status.\n */\n onConnectionChange?: (connection: DeepAgentConnectionState | null) => void;\n /** Notified when a run starts/stops so the page can reflect the running thread. */\n onRunningChange?: (isRunning: boolean) => void;\n /**\n * Notified once per thread with the `runConfig` carried by the statewire\n * snapshot (the backend's persisted panel config, seeded in `_load_history`),\n * so the host can hydrate its config store from the thread. Notified with\n * `null` (at most once per attach) when a server snapshot arrives WITHOUT a\n * persisted config, so a host waiting on hydration can stop waiting; a\n * config appearing on a later snapshot of the same attach (mirrored at run\n * start) still delivers the config notification.\n */\n onServerRunConfig?: (config: Record<string, unknown> | null) => void;\n /**\n * Notified when the snapshot's `outOfBandRunActive` flag changes: the host set\n * it while a run executing OUTSIDE this surface (an AOP / HTTP-route run)\n * is actively writing the thread's bare-namespace history, which the host\n * live-refreshes onto the wire. Lets the page show run-in-progress\n * treatment instead of an empty conversation, and stand down its own\n * re-attach polling. Change-notified per attach (an initial `false` before\n * the snapshot stays silent), mirroring `onRunningChange`.\n */\n onOutOfBandRunActive?: (outOfBandRunActive: boolean) => void;\n /**\n * Notified with the state's session-asset lifecycle flag\n * ({@link readSessionPersisted}) PAIRED with the thread it describes: `false`\n * while the thread's `session` asset provably does not exist yet (a\n * never-started chat's preload, a first run before the mint), `true` once\n * minted, `null` when the state carries no flag (a host that predates it).\n *\n * Fired from the converter pass, so the pair is read from the state of the\n * thread this attach was mounted for. A component reading the flag off the\n * client store instead lags the mounted thread id by one render on a switch\n * and can pair the new id with the previous thread's flag — releasing a\n * session-scoped read for a row the backend has not minted. Change-notified\n * per attach; the first pass of every attach notifies, so a host holding a\n * read back until it hears from the mounted thread always does.\n */\n onSessionPersistedChange?: (event: {\n threadId: string;\n sessionPersisted: boolean | null;\n }) => void;\n /**\n * Notified with the wire-contract status once the attach snapshot\n * advertises the `protocol` lane, and again whenever it changes (a\n * re-attach after a server roll can advertise a new `version`). Telemetry\n * and per-version behaviour only: the host has no minimum client version,\n * so nothing about the status gates a send. Never called for\n * pre-declaration servers (their snapshots carry no lane) — absence of a\n * call means \"no advertisement\", not \"compatible\".\n */\n onProtocolChange?: (status: DeepAgentProtocolStatus) => void;\n}\n\n/** One thread's replicated running state, keyed so a switch between two\n * threads with the same status still re-notifies (the host page clears its\n * per-thread state on selection, mirroring the connection dedupe below). */\nexport interface RunningSnapshot {\n threadId: string;\n isRunning: boolean;\n}\n\n/** Whether the thread's `session` asset exists, read off a statewire state, or\n * `null` when the state does not carry the flag.\n *\n * Absence is not absence of the asset: a snapshot from a host that predates\n * the flag has no such key, and reading that as \"the asset does not exist\"\n * would gate a read the client is entitled to make, with nothing left to\n * un-gate it. A new thread's preload seeds `false` (see `initialState`), so\n * the pre-attach pass of a chat that cannot have an asset yet still gates.\n *\n * Hosts pass this to `useStatewireState` so the flag and the thread it belongs\n * to are read in one component — a thread switch then cannot pair one thread's\n * id with the other's flag. */\nexport function readSessionPersisted(state: unknown): boolean | null {\n const flag = (state as { sessionPersisted?: unknown } | null)?.sessionPersisted;\n return typeof flag === 'boolean' ? flag : null;\n}\n\n/** Whether a converter pass must notify `onRunningChange`.\n *\n * The mount's very first status notifies only when it is `true` (a snapshot\n * carrying a live run) — an initial `false` before the snapshot must stay\n * silent so it cannot clear a still-valid indicator. After that, every\n * transition notifies, and so does the first status after a thread switch\n * (the host page clears its per-thread state on selection, so a switch\n * between two threads with the same status must still re-notify). */\nexport function shouldNotifyRunningChange(\n previous: RunningSnapshot | null,\n next: RunningSnapshot\n): boolean {\n if (previous === null) return next.isRunning;\n return previous.threadId !== next.threadId || previous.isRunning !== next.isRunning;\n}\n\n/** Whether two transcripts hold the very same message objects, in order. */\nfunction isSameMessageArray(\n previous: readonly LangChainMessage[],\n next: readonly LangChainMessage[]\n): boolean {\n return (\n previous.length === next.length && previous.every((message, index) => message === next[index])\n );\n}\n\n/**\n * The shared deep-agent Statewire thread.\n *\n * `StatewireThread` (from `@assistant-ui/react-statewire`) attaches to the\n * agora-hosted thread at `${baseUrl}/${threadId}` (WebSocket by default,\n * with SSE retained only as a host-selected compatibility switch): the backend\n * hosts the thread state and this client\n * replicates it live, so the server snapshot is the single source of history\n * (no local import, no `/status` resume probing) and run scheduling — queueing,\n * steering, stop, edit rewinds — rides the built-in `run/*` commands.\n *\n * The thread element is keyed by `threadId`, so a thread switch remounts the\n * session against the new URL instead of importing history in place.\n *\n * Returns the thread element for the host's own `useAui({ thread })` — web\n * hosts take `useAui` from `@assistant-ui/react`, React Native hosts from\n * `@assistant-ui/react-native`; this package imports neither.\n */\nexport function useDeepAgentThread({\n threadId,\n baseUrl,\n sse = false,\n headers,\n sessionStore,\n storage,\n isNewChat = false,\n attachKey,\n suspended = false,\n capabilities,\n laneProjection = 'both',\n selfAuthor = null,\n getMessageMetadata,\n adapters,\n diagnostics,\n snapshotCache,\n messageWindow,\n toolOutputs,\n withdrawnTurns,\n prewarmPool,\n onAttachTiming,\n onAttachSource,\n onError,\n onStateChange,\n onCommandChange,\n onRawConnectionChange,\n onConnectionChange,\n onRunningChange,\n onServerRunConfig,\n onOutOfBandRunActive,\n onSessionPersistedChange,\n onProtocolChange,\n}: UseDeepAgentThreadOptions) {\n const onRunningChangeRef = useRef(onRunningChange);\n onRunningChangeRef.current = onRunningChange;\n const onSessionPersistedChangeRef = useRef(onSessionPersistedChange);\n onSessionPersistedChangeRef.current = onSessionPersistedChange;\n const onConnectionChangeRef = useRef(onConnectionChange);\n onConnectionChangeRef.current = onConnectionChange;\n const onServerRunConfigRef = useRef(onServerRunConfig);\n onServerRunConfigRef.current = onServerRunConfig;\n const onOutOfBandRunActiveRef = useRef(onOutOfBandRunActive);\n onOutOfBandRunActiveRef.current = onOutOfBandRunActive;\n const onProtocolChangeRef = useRef(onProtocolChange);\n onProtocolChangeRef.current = onProtocolChange;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const onStateChangeRef = useRef(onStateChange);\n onStateChangeRef.current = onStateChange;\n const onCommandChangeRef = useRef(onCommandChange);\n onCommandChangeRef.current = onCommandChange;\n const onRawConnectionChangeRef = useRef(onRawConnectionChange);\n onRawConnectionChangeRef.current = onRawConnectionChange;\n const headersRef = useRef(headers);\n headersRef.current = headers;\n const messageWindowRef = useRef(messageWindow);\n messageWindowRef.current = messageWindow;\n // The head interest is checked once per connected session, after the hello\n // negotiated the lane (a statement before that would be minted durable):\n // the hello carries the host's head — the attach header's size, or what\n // this client id held — and a set goes out only to widen it.\n const interestRef = useRef({ attachId: '', stated: false });\n // The last joined transcript, held across the gap between a hello and its\n // interest answer (and across a reconnect) so the thread never blanks.\n const lastMessagesRef = useRef<{ attachId: string; messages: LangChainMessage[] } | null>(null);\n // A fetched tool output must re-run the converter (the store is read inside\n // it); the version is the memo's signal that the store's contents moved.\n const [toolOutputsVersion, setToolOutputsVersion] = useState(0);\n useEffect(() => {\n if (!toolOutputs) return undefined;\n return toolOutputs.subscribe(() => setToolOutputsVersion((version) => version + 1));\n }, [toolOutputs]);\n const [withdrawnTurnsVersion, setWithdrawnTurnsVersion] = useState(0);\n useEffect(() => {\n if (!withdrawnTurns) return undefined;\n return withdrawnTurns.subscribe(() => setWithdrawnTurnsVersion((version) => version + 1));\n }, [withdrawnTurns]);\n const diagnosticsRef = useRef(diagnostics);\n diagnosticsRef.current = diagnostics;\n const onAttachTimingRef = useRef(onAttachTiming);\n onAttachTimingRef.current = onAttachTiming;\n const onAttachSourceRef = useRef(onAttachSource);\n onAttachSourceRef.current = onAttachSource;\n\n const lastRunningRef = useRef<RunningSnapshot | null>(null);\n // Out-of-band run activity (`outOfBandRunActive`), change-notified with the\n // same semantics as the running flag above.\n const lastOutOfBandRunActiveRef = useRef<RunningSnapshot | null>(null);\n // The session-asset lifecycle flag last notified, keyed by attach so every\n // attach's first pass notifies (a host holding a read back until it hears\n // from the mounted thread must always hear from it).\n const lastSessionPersistedRef = useRef<{\n attachId: string;\n threadId: string;\n sessionPersisted: boolean | null;\n } | null>(null);\n // The last wire-contract status notified, keyed by attach so a re-attach\n // re-notifies (the new snapshot may advertise a different version).\n // `status: null` = nothing advertised yet on this attach.\n const lastProtocolRef = useRef<{\n attachId: string;\n status: DeepAgentProtocolStatus | null;\n } | null>(null);\n // The thread whose statewire-carried runConfig has been surfaced to the host\n // (once per thread; later snapshots must not clobber edits).\n const appliedStateRunConfigThreadRef = useRef<string | null>(null);\n // The attach that already notified `onServerRunConfig(null)` (snapshot\n // arrived carrying no persisted config) — at most once per attach.\n const absentStateRunConfigAttachRef = useRef<string | null>(null);\n // Live thread id for the callbacks: they are created per render but may\n // settle after a switch, so they compare against the current id.\n const threadIdRef = useRef(threadId);\n threadIdRef.current = threadId;\n // Identity of the current attach. Every per-thread latch keys off this, so a\n // re-attach of the same thread (a bumped `attachKey`) re-notifies the host\n // exactly like a switch would — the host clears its per-thread state on\n // re-attach, so a snapshot that repeats the previous status must not dedupe.\n const attachId: string = attachKey === undefined ? threadId : `${threadId}:${attachKey}`;\n const attachIdRef = useRef(attachId);\n attachIdRef.current = attachId;\n\n // Auth-denial park: the server fins every denied attach `unauthorized` and\n // the reconnect loop would otherwise retry it every 30s forever (prod tabs\n // looped for hours against revoked/workspace-less credentials). After a\n // streak of denials the live transport is swapped for a parked one; a new\n // attach (thread switch, bumped attachKey) or the parked connection's\n // `reconnect()` re-arms it.\n const [authParked, setAuthParked] = useState<{\n attachId: string;\n message: string | undefined;\n } | null>(null);\n const authDenialRef = useRef<{ attachId: string; state: AuthDenialTrackerState }>({\n attachId,\n state: initialAuthDenialTrackerState(),\n });\n useEffect(() => {\n setAuthParked((prev) => (prev !== null && prev.attachId !== attachId ? null : prev));\n }, [attachId]);\n\n // Field-wise stable identity for the viewer stamp, so a host that rebuilds\n // the author object per render does not rebuild the converter (and with it\n // every message) per render. Adjusting state during render is React's\n // sanctioned derived-state pattern: it re-renders once with the new value.\n const [stableSelfAuthor, setStableSelfAuthor] = useState(selfAuthor);\n if (!isSameMessageAuthor(stableSelfAuthor, selfAuthor)) setStableSelfAuthor(selfAuthor);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: toolOutputsVersion / withdrawnTurnsVersion are the stores' change signals — the converter reads the stores' contents, not the counters.\n const converter = useMemo(\n () => (state: unknown, isRunning: boolean, conversionCache: DeepAgentMessageConversionCache) => {\n // Statewire snapshots carry the thread's persisted panel config (the\n // backend seeds `runConfig` in `_load_history` and mirrors it on run\n // start). Surface it once per thread so the host can hydrate its config\n // store.\n const stateRunConfig = (state as { runConfig?: unknown } | null)?.runConfig;\n if (\n stateRunConfig &&\n typeof stateRunConfig === 'object' &&\n !Array.isArray(stateRunConfig) &&\n appliedStateRunConfigThreadRef.current !== attachIdRef.current\n ) {\n appliedStateRunConfigThreadRef.current = attachIdRef.current;\n const notifyRunConfig = onServerRunConfigRef.current;\n if (notifyRunConfig) {\n queueMicrotask(() => notifyRunConfig(stateRunConfig as Record<string, unknown>));\n }\n } else if (\n !stateRunConfig &&\n appliedStateRunConfigThreadRef.current !== attachIdRef.current &&\n absentStateRunConfigAttachRef.current !== attachIdRef.current &&\n projectDeepAgentProtocol(state) !== null\n ) {\n // No persisted config on a SERVER state: the protocol lane rides every\n // attach snapshot, so its presence distinguishes \"the server answered\n // without a config\" from the pre-attach `initialState` (which must not\n // end the host's hydration wait).\n absentStateRunConfigAttachRef.current = attachIdRef.current;\n const notifyRunConfig = onServerRunConfigRef.current;\n if (notifyRunConfig) {\n queueMicrotask(() => notifyRunConfig(null));\n }\n }\n // Out-of-band run activity: the host live-refreshes a bare-namespace\n // (AOP / HTTP-route) thread's transcript while its run is active and\n // flags the wire state so the page can reflect it.\n const stateOutOfBandRunActive =\n (state as { outOfBandRunActive?: unknown } | null)?.outOfBandRunActive === true;\n const outOfBandRunActiveSnapshot = {\n threadId: attachIdRef.current,\n isRunning: stateOutOfBandRunActive,\n };\n if (shouldNotifyRunningChange(lastOutOfBandRunActiveRef.current, outOfBandRunActiveSnapshot)) {\n lastOutOfBandRunActiveRef.current = outOfBandRunActiveSnapshot;\n const observedAttachId = attachIdRef.current;\n queueMicrotask(() => {\n // A re-attach or newer snapshot between the converter pass and this\n // microtask owns the channel now — a stale flag must not leak into\n // the new attach's per-thread state.\n if (\n attachIdRef.current !== observedAttachId ||\n lastOutOfBandRunActiveRef.current !== outOfBandRunActiveSnapshot\n ) {\n return;\n }\n onOutOfBandRunActiveRef.current?.(stateOutOfBandRunActive);\n });\n }\n // Wire-contract advertisement: the host publishes the `protocol` lane in\n // every attach snapshot. Notify on first advertisement and on change\n // (dedupe by value, re-keyed per attach), with the same stale-guard\n // microtask as the other observers.\n const protocolStatus = projectDeepAgentProtocol(state);\n if (protocolStatus !== null) {\n const previous =\n lastProtocolRef.current?.attachId === attachIdRef.current\n ? lastProtocolRef.current.status\n : null;\n if (previous === null || previous.protocolVersion !== protocolStatus.protocolVersion) {\n const update = { attachId: attachIdRef.current, status: protocolStatus };\n lastProtocolRef.current = update;\n queueMicrotask(() => {\n if (lastProtocolRef.current !== update || attachIdRef.current !== update.attachId) {\n return;\n }\n onProtocolChangeRef.current?.(protocolStatus);\n });\n }\n }\n const runningSnapshot = { threadId: attachIdRef.current, isRunning };\n if (shouldNotifyRunningChange(lastRunningRef.current, runningSnapshot)) {\n lastRunningRef.current = runningSnapshot;\n const notify = onRunningChangeRef.current;\n if (notify) queueMicrotask(() => notify(isRunning));\n }\n return {\n ...convertDeepAgentState(state, {\n laneProjection,\n selfAuthor: stableSelfAuthor,\n toolOutputs,\n withdrawnTurns,\n conversionCache,\n }),\n state: state as StatewireThread.State['state'],\n };\n },\n [\n laneProjection,\n stableSelfAuthor,\n toolOutputs,\n toolOutputsVersion,\n withdrawnTurns,\n withdrawnTurnsVersion,\n ]\n );\n const materialize = useMemo(\n () => createDeepAgentMaterialize({ selfAuthor: stableSelfAuthor }),\n [stableSelfAuthor]\n );\n\n // Surface the statewire connection status through `onConnectionChange` (the\n // converter re-runs on connection changes), and clear it when the runtime\n // unmounts so an indicator never shows a stale status. Dedup is keyed by\n // thread: the runtime stays mounted across idle thread switches, so the new\n // thread's first status must notify even when it equals the previous\n // thread's last one.\n const lastConnectionRef = useRef<{\n threadId: string;\n connection: DeepAgentConnectionState;\n } | null>(null);\n useEffect(\n () => () => {\n lastConnectionRef.current = null;\n onConnectionChangeRef.current?.(null);\n },\n []\n );\n\n // The preload decision pins at thread entry: `isNewChat` flips once the\n // thread persists, but the mount that began as a new thread stays preloaded.\n const preloadRef = useRef({ threadId, preload: isNewChat });\n if (preloadRef.current.threadId !== threadId)\n preloadRef.current = { threadId, preload: isNewChat };\n\n const snapshotCacheRef = useRef(snapshotCache);\n snapshotCacheRef.current = snapshotCache;\n // The snapshot seed pins at attach identity, like the preload decision: the\n // cache is read once per mount, so a mid-session cache write (this thread's\n // own states being remembered) never changes what `initialState` was.\n //\n // A suspended attach never seeds: the suspended transport never dials, so a\n // seed would be served indefinitely — under a view-as lens that would paint\n // thread content the parked transport exists to withhold (the lens must\n // show what the LENSED identity is authorized to see, and only the server\n // can decide that).\n //\n // The pooled hello is taken the same way: exactly once, at the attach's\n // first render (the pool disposes its root in that step).\n const snapshotSeedRef = useRef<{\n attachId: string;\n seed: DeepAgentStreamValues | undefined;\n } | null>(null);\n if (snapshotSeedRef.current === null || snapshotSeedRef.current.attachId !== attachId) {\n const preload = preloadRef.current.preload;\n let pooledState: DeepAgentStreamValues | undefined;\n if (prewarmPool?.has(threadId)) {\n if (preload || suspended) {\n // This mount attaches on its own terms (or not at all): the pooled\n // dial must not linger as a second socket to the same session.\n prewarmPool.discard(threadId);\n } else {\n pooledState = prewarmPool.take(threadId)?.state;\n }\n }\n // The pooled hello outranks a remembered snapshot (it is newer by\n // construction); a pooled dial that had not landed seeds like a plain\n // attach and reconciles when this attach's own hello lands.\n const remembered =\n preload || suspended ? undefined : (pooledState ?? snapshotCache?.take(threadId));\n const seed = remembered ? toThreadSnapshotSeed(remembered) : undefined;\n snapshotSeedRef.current = { attachId, seed };\n const source: DeepAgentAttachSource =\n pooledState !== undefined ? 'prewarm' : seed ? 'snapshot' : 'none';\n const notifySource = onAttachSourceRef.current;\n if (notifySource) queueMicrotask(() => notifySource({ threadId, source }));\n }\n\n // The conversion memory pins at attach identity like the snapshot seed: an\n // unchanged message converts to the identical thread message on every pass\n // of this attach, and a switch or re-attach starts from an empty memory, so\n // one thread's converted messages can never be served for another.\n const conversionCacheRef = useRef<{\n attachId: string;\n cache: DeepAgentMessageConversionCache;\n } | null>(null);\n if (conversionCacheRef.current === null || conversionCacheRef.current.attachId !== attachId) {\n conversionCacheRef.current = { attachId, cache: createDeepAgentMessageConversionCache() };\n }\n const conversionCache = conversionCacheRef.current.cache;\n // The last pass's joined transcript, reused when a packet moved no message\n // (a run-status flip, a todo, another document) so readers memoized on\n // `state.messages` skip that pass.\n const lastStateMessagesRef = useRef<{ attachId: string; messages: LangChainMessage[] } | null>(\n null\n );\n\n // react-statewire memoizes the converted thread on this function's\n // identity, so an inline closure would re-run `convertDeepAgentState` over\n // the whole transcript on every host render. Keyed on the attach identity (a\n // re-attach re-keys its per-thread latches); everything else the body needs\n // is read through the per-render refs above.\n const threadConverter = useCallback<ThreadOptions['converter']>(\n (wireState, meta) => {\n // The wire main document carries no messages: join the interest window\n // off the mounted documents, fold the dispatch record onto it, and hand\n // the composite on as the thread state every reader sees.\n const values = readDeepAgentStreamValues(wireState);\n const window = readDeepAgentMessageWindow(meta.mounted);\n const held =\n lastMessagesRef.current?.attachId === attachId ? lastMessagesRef.current.messages : null;\n const messages = window?.messages ?? values.messages ?? held ?? [];\n if (window !== null || messages.length > 0) lastMessagesRef.current = { attachId, messages };\n const state: DeepAgentStreamValues = { ...values, messages: [...messages] };\n materialize(state);\n const joined: LangChainMessage[] = state.messages ?? [];\n const previousJoined = lastStateMessagesRef.current;\n if (\n previousJoined !== null &&\n previousJoined.attachId === attachId &&\n isSameMessageArray(previousJoined.messages, joined)\n ) {\n state.messages = previousJoined.messages;\n } else {\n lastStateMessagesRef.current = { attachId, messages: joined };\n }\n if (window !== null && isDeepAgentStateHydrated(values)) {\n snapshotCacheRef.current?.remember(threadId, state);\n }\n if (interestRef.current.attachId !== attachId) {\n interestRef.current = { attachId, stated: false };\n }\n if (meta.connection.status !== 'connected') {\n interestRef.current.stated = false;\n } else if (!interestRef.current.stated) {\n interestRef.current.stated = true;\n const wanted = headInterestRequest(messageWindowRef.current?.size);\n const head = window?.requests[0];\n // The hello's head is kept whenever it is at least what this surface\n // wants (a remembered client's wider view, the declared header):\n // stating a narrower head would shrink what the viewer holds. A\n // narrower head — or none, a host without the lane — is widened, the\n // hello's pages kept alongside.\n const preloaded = head !== undefined && head.at === undefined && head.before >= wanted.before;\n if (!preloaded) {\n const requests = [\n wanted,\n ...(window?.requests.filter((request) => request.at !== undefined) ?? []),\n ];\n queueMicrotask(() => {\n if (attachIdRef.current !== attachId) return;\n meta\n .invoke(DEEP_AGENT_INTEREST_PROTOCOL, 'set', [requests])\n .catch((error: unknown) => {\n onErrorRef.current?.(error instanceof Error ? error : new Error(String(error)));\n });\n });\n }\n }\n // Projected once per pass through the single seam; every fold below\n // consumes the projection (the recorder projects the raw connection\n // itself, so any host observer can feed it).\n const connection = projectDeepAgentConnection(meta.connection);\n // Transition-deduped inside the recorder, so this per-pass observation\n // is free while the connection is unchanged.\n diagnosticsRef.current?.observeConnection(meta.connection);\n // Fold this pass's connection into the denial streak (the converter\n // re-runs on every reconnect-attempt bump). Parking is deferred to a\n // microtask like every other notification here.\n if (authDenialRef.current.attachId !== attachIdRef.current) {\n authDenialRef.current = {\n attachId: attachIdRef.current,\n state: initialAuthDenialTrackerState(),\n };\n }\n const denial = observeAuthDenial(authDenialRef.current.state, connection);\n authDenialRef.current.state = denial.state;\n if (denial.park) {\n const parkAttachId = attachIdRef.current;\n const parkMessage = denial.state.message;\n // The server refused authorization for this thread: any remembered\n // snapshot must not warm-paint it on a later mount (permissions may\n // have been revoked since the state was captured).\n snapshotCacheRef.current?.forget(threadId);\n queueMicrotask(() => {\n if (attachIdRef.current !== parkAttachId) return;\n setAuthParked((prev) =>\n prev?.attachId === parkAttachId\n ? prev\n : { attachId: parkAttachId, message: parkMessage }\n );\n });\n }\n const previous = lastConnectionRef.current;\n if (\n previous?.threadId !== attachId ||\n !Object.keys({ ...previous.connection, ...connection }).every(\n (key) => Reflect.get(previous.connection, key) === Reflect.get(connection, key)\n )\n ) {\n const update = { threadId: attachId, connection };\n lastConnectionRef.current = update;\n queueMicrotask(() => {\n // A newer projection, a thread switch, or the unmount cleanup owns\n // the channel now.\n if (lastConnectionRef.current !== update || attachIdRef.current !== attachId) return;\n onConnectionChangeRef.current?.(connection);\n });\n }\n // Session-asset lifecycle, paired with THIS attach's thread by closure:\n // the state converted here is the state of the thread the element was\n // built for, so the pair can never straddle a switch (a client-store\n // read would). Deduped by value per attach. A pass from an attach the\n // host has already replaced never touches the latch — it could otherwise\n // cancel the current attach's still-queued verdict — and the microtask\n // guard drops a pass whose attach is replaced before it settles.\n if (attachIdRef.current === attachId) {\n const sessionPersisted = readSessionPersisted(state);\n const lastSession = lastSessionPersistedRef.current;\n if (\n lastSession?.attachId !== attachId ||\n lastSession.sessionPersisted !== sessionPersisted\n ) {\n const sessionUpdate = { attachId, threadId, sessionPersisted };\n lastSessionPersistedRef.current = sessionUpdate;\n queueMicrotask(() => {\n if (\n lastSessionPersistedRef.current !== sessionUpdate ||\n attachIdRef.current !== attachId\n ) {\n return;\n }\n onSessionPersistedChangeRef.current?.({ threadId, sessionPersisted });\n });\n }\n }\n // The replicated run status IS the running signal: the lib's run-dialect\n // fold flips it to \"running\" on the send, before the app converter runs,\n // so the optimistic window needs no hand-tracked flag.\n return converter(state, state.runs?.[0]?.status === 'running', conversionCache);\n },\n [attachId, conversionCache, converter, materialize, threadId]\n );\n\n return StatewireThread<DeepAgentStreamValues>({\n // The transport stamps this protocol on every command; the thread client\n // must declare it too or the core skips the optimistic folds and a send\n // stays invisible until the server frame lands.\n protocol: DEEP_AGENT_STATEWIRE_PROTOCOL,\n // New threads preload an empty runs mount and report `deferred` — the\n // composer is interactive before the stream attaches and pre-attach sends\n // render through the optimistic folds. Existing threads omit the runs\n // mount and project \"loading\" until the attach snapshot: the server seeds\n // messages/todos/runConfig in `_load_history`.\n //\n // The preload also seeds `sessionPersisted: false`: a never-started chat\n // provably has no `session` asset until its first run mints one, so the\n // wire carries that from the first render and a host reading the flag off\n // the state needs no separate \"is this a new chat\" knowledge. An existing\n // thread leaves it absent (unknown) so its asset read is never gated.\n initialState:\n snapshotSeedRef.current.seed ??\n ({\n messages: [],\n todos: [],\n ...(preloadRef.current.preload && { runs: [], sessionPersisted: false }),\n } satisfies DeepAgentStreamValues),\n // Keyed by thread: a switch unmounts the previous thread's session and\n // remounts against the new URL, so the converter never sees the previous\n // thread's snapshot (a new thread serves its preload again, an existing\n // one loads until its snapshot). A host-suspended or auth-parked attach\n // swaps in the never-dialing transport instead.\n transport: withKey(\n attachId,\n (() => {\n if (suspended) return StatewireSuspended({ message: suspended.reason });\n if (authParked !== null && authParked.attachId === attachId) {\n return StatewireSuspended({\n message: authParked.message ?? 'Session authorization was refused.',\n onReconnectRequested: () => {\n authDenialRef.current = {\n attachId: attachIdRef.current,\n state: initialAuthDenialTrackerState(),\n };\n setAuthParked(null);\n },\n });\n }\n // The shared recipe (URL, auth + wire-contract headers, session lane,\n // attach instrumentation, retry-hint floor) — the same one the prewarm\n // pool dials with, so the instance a pooled attach warmed is the one\n // this dial reaches. A never-started chat dials nothing until its\n // first send.\n return createDeepAgentAttachTransport<DeepAgentStreamValues>({\n baseUrl,\n threadId,\n sse,\n isNew: preloadRef.current.preload,\n headers: (ctx) => headersRef.current(ctx),\n messageWindow: messageWindowRef.current,\n sessionStore,\n onAuthResolve: (ctx) => diagnosticsRef.current?.observeAuthResolve(ctx),\n onAttachTiming: (event) => onAttachTimingRef.current?.({ threadId, event }),\n });\n })()\n ),\n // Survives the transport remounts above: a bumped attachKey re-attaches the\n // same lane, and a persistent session storage carries it across reloads.\n ...(storage && { storage }),\n // The run subsystem (status, lanes, input requests, runId) is mounted on\n // the state root and always replicated by react-statewire >= 0.14 (the\n // former `runs: true` opt-in is gone) — the converter only maps app-owned\n // keys, including the `run/stop` runId stamp the lib projects itself.\n converter: threadConverter,\n // Native message editing: an edited turn is resubmitted as a `run/edit`\n // command, and the deep-agent backend rewinds the checkpointed thread to\n // the edited message's parent before appending (route `plan_rewind`).\n capabilities: capabilities ?? { edit: true },\n ...(getMessageMetadata && { getMessageMetadata }),\n ...(adapters && { adapters }),\n contextSync: 'command-send',\n // The Stop control is the only `cancelRun()` caller — teardown paths\n // unmount the keyed transport instead — so every `run/stop` is a\n // deliberate user stop.\n stopPayload: () => ({ reason: 'user_stop' }),\n onError: (error) => {\n diagnosticsRef.current?.observeError(error);\n onErrorRef.current?.(error);\n },\n ...(onStateChange && {\n // The lib types the observed state `NonNullable`, but the runtime\n // delivers `undefined` where the wire has no snapshot (pre-attach and\n // replay boundaries republish it) — normalize so the type is true and\n // host observers never crash on a field read.\n onStateChange: ((state, ctx) => {\n onStateChangeRef.current?.(readDeepAgentStreamValues(state), ctx);\n }) satisfies ThreadOptions['onStateChange'],\n }),\n ...((onCommandChange || diagnostics) && {\n onCommandChange: ((update, ctx) => {\n diagnosticsRef.current?.observeCommand(update);\n onCommandChangeRef.current?.(update, ctx);\n }) satisfies ThreadOptions['onCommandChange'],\n }),\n ...(onRawConnectionChange && {\n onConnectionChange: ((connection) =>\n onRawConnectionChangeRef.current?.(\n connection\n )) satisfies ThreadOptions['onConnectionChange'],\n }),\n });\n}\n"],"names":["conversionCache","_a"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- const version = "0.26.6";
3
+ const version = "0.28.0";
4
4
  const packageJson = {
5
5
  version
6
6
  };
@@ -1,4 +1,4 @@
1
- const version = "0.26.6";
1
+ const version = "0.28.0";
2
2
  const packageJson = {
3
3
  version
4
4
  };
@@ -444,6 +444,9 @@ function AthenaProvider({
444
444
  if (!bridge.ready) {
445
445
  return null;
446
446
  }
447
+ if (bridge.error && !effectiveToken && configuredGetToken === void 0 && !configuredApiKey) {
448
+ return null;
449
+ }
447
450
  athenaUrls.assertHostMintedStatewireMount({
448
451
  hostAnswered: bridge.hostAnswered,
449
452
  hostStatewireSyncUrl: bridge.statewireSyncUrl,
@@ -1 +1 @@
1
- {"version":3,"file":"AthenaProvider.cjs","sources":["../../src/provider/AthenaProvider.tsx"],"sourcesContent":["import { AuiProvider, useAui } from '@assistant-ui/react';\nimport {\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useReducer,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport type { AssistantClient, Toolkit } from '@assistant-ui/react';\nimport {\n createDeepAgentThreadSnapshotCache,\n createDeepAgentToolOutputStore,\n DeepAgentConnectionContext,\n type DeepAgentThreadSnapshotCache,\n type DeepAgentToolOutputStore,\n} from '@athenaintel/agent-runtime';\nimport {\n assertHostMintedStatewireMount,\n deriveAthenaAppUrl,\n getAthenaEnvironmentUrls,\n resolveStatewireSyncUrl,\n type AthenaEnvironment,\n} from '../lib/athena-urls';\nimport { getAthenaApiBaseUrl } from '../collab/mint';\nimport { useParentBridge } from '../runtime/auth';\nimport { AthenaAuthContext } from '../auth/AthenaAuthContext';\nimport { AthenaCredentialSourceContext } from '../auth/AthenaCredentialSourceContext';\nimport {\n createAthenaCredentialSource,\n type AthenaCredentialInputs,\n} from '../auth/credential-source';\nimport { useRestartAfterAuthRefusal } from '../runtime/auth-refusal-restart';\nimport {\n useAthenaStatewireRuntime,\n useStatewireClientTools,\n} from '../runtime/useAthenaStatewireRuntime';\nimport {\n athenaStatewireErrorNotice,\n type AthenaStatewireLifecycleState,\n initialStatewireLifecycle,\n statewireLifecycleReducer,\n} from '../runtime/statewire-lifecycle';\nimport type { AthenaStatewireTokenGetter } from '../runtime/statewire-auth-headers';\nimport { resolveAgentProp } from '../runtime/statewire-run-config';\nimport { mintThreadId } from '../threads/mint-thread-id';\nimport { AthenaStatewireLifecycleContext } from './statewire-lifecycle-context';\nimport {\n ComposerHandoffContext,\n clearComposerHandoff,\n createComposerHandoffStore,\n drainComposerHandoff,\n useComposerHandoffStore,\n useComposerReady,\n} from '../composer/composer-handoff';\nimport { StatewireToolOutputsContext } from './statewire-window-context';\nimport { StatewireClientToolBridge } from '../chat/StatewireClientToolBridge';\nimport {\n athenaDiagnostics,\n debugPropToDiagnosticsConfig,\n installAthenaDiagnosticsGlobal,\n type AthenaDiagnosticEvent,\n type AthenaDiagnosticLevel,\n type AthenaDiagnosticsConfig,\n} from '../diagnostics/athena-diagnostics';\nimport { AthenaSdkError } from '../diagnostics/errors';\nimport {\n backendDeclaredFrontendToolIds,\n resolveClientToolSurface,\n} from '../chat/statewire-client-tools';\nimport { TooltipProvider } from '../ui/tooltip';\nimport { DEFAULT_AUTO_OPEN_TOOLS } from '../tools/auto-open-tools';\nimport { AthenaContext, type AthenaConfig } from './AthenaContext';\nimport type { AthenaProviderConfig } from './config';\nimport type {\n AthenaCitationLinkOptions,\n AthenaLinkClickOptions,\n} from './citation-links';\nimport {\n AthenaStatewireThreadIdContext,\n AthenaThreadIdContext,\n useAthenaStatewireThreadId,\n} from '../threads/thread-id-context';\nimport {\n AthenaStatewireThreadListProvider,\n StatewireThreadTitlePoller,\n useAthenaStatewireThreadList,\n} from '../threads/statewire-thread-list';\nimport { useAssetPanelStore } from '../assets/asset-panel-store';\nimport { themeToStyleVars, type AthenaTheme } from '../theme';\nimport { AthenaThemeStyleContext } from './theme-style-context';\nimport { PostHogProvider, type PostHogConfig } from './PostHogProvider';\n\nexport interface AthenaProviderProps {\n children: ReactNode;\n\n /** Preferred structured config for auth and Athena endpoint settings. */\n config?: AthenaProviderConfig;\n\n /** @deprecated Prefer `config.apiKey`. API key for authentication in standalone mode. */\n apiKey?: string;\n\n /** @deprecated Prefer `config.token`. PropelAuth token. If provided, takes priority over apiKey. If omitted, the SDK\n * will automatically listen for a token from the parent window via PostMessage. */\n token?: string | null;\n\n /** Run the thread AS a published collab agent. The only accepted shape is\n * `collab_agent:<asset_id>`: the thread then uses that agent's prompt,\n * tools, and model default, and the caller must have view access to the\n * agent asset. Omit it (or pass a blank string) to run the Athena deep agent.\n *\n * Any other non-blank value throws at render — the statewire host cannot\n * honour named agents, and a selector that is silently dropped would let a\n * misconfigured deployment answer as the wrong agent. */\n agent?: string;\n\n /** Collab-agent channel id — a built-in channel (`email`, `sms`, …) or a\n * user-defined custom channel id from the agent's Channels tab. Selects\n * that channel's configuration overrides and stamps the session's origin.\n * Only meaningful together with a `collab_agent:<asset_id>` `agent`; sent\n * as `collab_channel_id`. An unknown or disabled channel rejects the run\n * with a structured, teaching error. */\n channel?: string;\n\n /** LLM model identifier. Defaults to the deep-agent default model\n * (`DEFAULT_STATEWIRE_MODEL`) — or, when a collab agent is selected, to\n * the model its author configured. */\n model?: string;\n\n /** Backend toolkit IDs to enable (e.g. 'document_toolkit', 'web_search_browse_toolkit'). */\n tools?: string[];\n\n /** Frontend tools that execute in the browser. The agent can invoke these.\n * Merged on top of the SDK's default auto-open tools; entries here take\n * precedence over defaults with the same name. Tools with a local\n * `execute` are declared to the backend as `client_tools` and run through\n * the statewire client-tool bridge. */\n frontendTools?: Toolkit;\n\n /** Disable the SDK's default auto-open behavior for created/touched assets. */\n disableAutoOpen?: boolean;\n\n /** @deprecated Prefer `config.apiUrl`. URL on the Iris host fronting the\n * deployment; its origin derives the statewire sync mount when\n * `statewireSyncUrl` is not set. */\n apiUrl?: string;\n\n /** @deprecated Prefer `config.backendUrl`. URL for the Athena backend API. */\n backendUrl?: string;\n\n /** @deprecated Prefer `config.appUrl`. URL for the Athena frontend app origin. */\n appUrl?: string;\n\n /** @deprecated Prefer `config.environment`. Athena environment preset used when URLs are not explicitly provided. */\n environment?: AthenaEnvironment;\n\n /** Resolve the latest auth token immediately before a request (for\n * expiring clients). Takes priority over `token` when it resolves.\n * Prefer `config.getToken` (see its `force` contract for refused\n * credentials). */\n getToken?: AthenaStatewireTokenGetter;\n\n /** Additional fields merged into runConfig.custom. Prefer\n * `config.extraRunConfig`. */\n extraRunConfig?: Record<string, unknown>;\n\n /** Statewire sync base URL override (the `…/v2/threads` mount). Defaults to\n * the mount a Marathon host mints, then the effective `apiUrl` host +\n * `/v2/threads`. Prefer `config.statewireSyncUrl`. */\n statewireSyncUrl?: string;\n\n /** Asset IDs to include in the workbench. */\n workbench?: string[];\n\n /** Knowledge base IDs for RAG context. */\n knowledgeBase?: string[];\n\n /** System prompt override. */\n systemPrompt?: string;\n\n /** Client app identifier for session filtering.\n * Sessions created with this ID can be filtered in the thread list.\n * E.g. \"olympus\", \"athena-app\", or a computer asset ID like \"asset_<uuid>\". */\n appId?: string;\n\n /** Thread ID override. Auto-generated if not provided. */\n threadId?: string;\n\n /** Enable thread list management (sidebar thread switching). */\n enableThreadList?: boolean;\n\n /** Ask the thread list for live pull-request state on each session\n * (`include_pull_requests`), which `SessionList` renders as chips.\n * Defaults to `true` in thread-list mode; turn it off in a host that never\n * shows them to spare the server the lookup. */\n threadListIncludePullRequests?: boolean;\n\n /** Theme configuration. Pass a preset from `themes` or a custom `AthenaTheme` object.\n * Injects CSS variables on a wrapper element — no CSS files needed.\n *\n * @example\n * import { themes } from '@athenaintel/react';\n * <AthenaProvider theme={themes.dark}>\n *\n * @example\n * <AthenaProvider theme={{ primary: '#8b5cf6', radius: '1rem' }}>\n *\n * @example\n * <AthenaProvider theme={{ ...themes.dark, primary: '#22c55e' }}>\n */\n theme?: AthenaTheme;\n\n /** Customize how rendered chat links behave. */\n linkClicks?: AthenaLinkClickOptions;\n\n /** @deprecated Prefer `linkClicks`. Customize how Athena citation links rendered in chat messages behave. */\n citationLinks?: AthenaCitationLinkOptions;\n\n /** PostHog analytics configuration. When omitted or keys are missing, PostHog is silently disabled.\n * Prefer `config.posthog` for structured configuration. */\n posthog?: PostHogConfig;\n\n /** SDK diagnostics.\n *\n * - `true` / a level: echo structured `[AthenaSDK]` events to the console\n * at that level (`true` = 'debug').\n * - An object: full diagnostics config (console level, PostHog timing\n * forwarding, buffer size).\n *\n * Independent of the prop, `localStorage.setItem('athena:debug','debug')`\n * (or `window.__ATHENA_SDK__.diagnostics.enableConsole()`) turns console\n * echo on at runtime without a rebuild. Errors log once even when off. */\n debug?: boolean | AthenaDiagnosticLevel | Partial<AthenaDiagnosticsConfig>;\n\n /** Receives every diagnostics event (timings, warnings, errors) — the hook\n * for shipping SDK telemetry to the host app's own pipeline. */\n onDiagnostic?: (event: AthenaDiagnosticEvent) => void;\n\n /** Receives every SDK error as a typed `AthenaSdkError` (stable `code`,\n * `hint`, structured server `detail`). Fires in addition to the UI's own\n * error handling, so integrations never fail silently. */\n onError?: (error: AthenaSdkError, event: AthenaDiagnosticEvent) => void;\n}\n\nconst resolveTokenOverride = ({\n config,\n token,\n}: {\n config?: AthenaProviderConfig;\n token?: string | null;\n}): string | null | undefined => {\n if (config?.token !== undefined) {\n return config.token;\n }\n return token;\n};\n\nconst useAthenaConfigValue = ({\n backendUrl,\n appUrl,\n apiKey,\n token,\n getToken,\n enabledToolkits,\n linkClicks,\n citationLinks,\n}: {\n backendUrl: string;\n appUrl: string;\n apiKey?: string;\n token?: string | null;\n getToken?: AthenaStatewireTokenGetter;\n enabledToolkits: string[];\n linkClicks?: AthenaLinkClickOptions;\n citationLinks?: AthenaCitationLinkOptions;\n}): AthenaConfig => {\n const linkClicksRef = useRef(linkClicks);\n linkClicksRef.current = linkClicks;\n const citationLinksRef = useRef(citationLinks);\n citationLinksRef.current = citationLinks;\n // Keep token in a ref so its value can update without invalidating the\n // config object identity. PropelAuth rotates tokens on window focus —\n // if token were a memo dep, every rotation would publish a new config\n // object to context and force every consumer (e.g. AssetIframe) to\n // re-render, causing asset panel flicker.\n const tokenRef = useRef(token);\n tokenRef.current = token;\n const getTokenRef = useRef(getToken);\n getTokenRef.current = getToken;\n\n return useMemo(\n () => ({\n backendUrl,\n appUrl,\n apiKey,\n enabledToolkits,\n get token() {\n return tokenRef.current;\n },\n get getToken() {\n return getTokenRef.current;\n },\n get linkClicks() {\n return linkClicksRef.current;\n },\n get citationLinks() {\n return citationLinksRef.current;\n },\n }),\n [backendUrl, appUrl, apiKey, enabledToolkits],\n );\n};\n\n/**\n * Delivers composer writes that were made before this mount was ready\n * (`useAppendToComposer` / `useSendMessage` queue them in the provider-level\n * store, which outlives the keyed per-thread mount). Lives under the\n * `AuiProvider` so it can read the thread's own loading state.\n */\nfunction ComposerHandoffDrain(): null {\n const aui = useAui();\n const store = useComposerHandoffStore();\n const threadId = useContext(AthenaStatewireThreadIdContext);\n const ready = useComposerReady();\n useEffect(() => {\n if (!ready || !store) return;\n // Writes bound to another thread are dropped here, not applied.\n drainComposerHandoff({ store, target: aui, threadId });\n }, [aui, ready, store, threadId]);\n return null;\n}\n\n// ─── Standalone Mode ──────────────────────────────────────────────────\n\n/** Everything the per-thread runtime needs to attach and run a thread. */\ninterface AthenaStatewireRuntimeProps {\n syncUrl: string;\n apiKey?: string;\n token?: string | null;\n getToken?: AthenaStatewireTokenGetter;\n model?: string;\n agent?: string;\n channel?: string;\n tools: string[];\n frontendToolIds: string[];\n frontendTools: Toolkit;\n workbench?: string[];\n knowledgeBase?: string[];\n systemPrompt?: string;\n appId?: string;\n extraRunConfig?: Record<string, unknown>;\n /** The provider-owned snapshot cache (see `AthenaProvider`). */\n snapshotCache: DeepAgentThreadSnapshotCache;\n /** The provider-owned store of fetched-back cut tool outputs (see `AthenaProvider`). */\n toolOutputs: DeepAgentToolOutputStore;\n}\n\ninterface AthenaStatewireStandaloneProps extends AthenaStatewireRuntimeProps {\n children: ReactNode;\n backendUrl: string;\n appUrl: string;\n threadId?: string;\n /**\n * Thread-list mode. The list owns the active id and alone knows whether the\n * backend has listed it yet: `isNewChat` overrides the \"new chat\"\n * derivation (the list mints ids for brand-new chats, which must still load\n * as new), and the scope publishes `AthenaThreadIdContext` — the backend id,\n * withheld while the chat is unpersisted. Absent outside thread-list mode,\n * where that context stays untouched.\n */\n threadList?: { isNewChat: boolean };\n linkClicks?: AthenaLinkClickOptions;\n citationLinks?: AthenaCitationLinkOptions;\n}\n\n/**\n * What one per-thread runtime mount hands to the stable scope around the\n * host's children: the assistant client attached to `threadId` and the\n * transport lifecycle observed on that attach. Published as ONE value so the\n * scope can never pair a thread's id with another thread's client.\n */\ninterface AthenaStatewireRuntimeSnapshot {\n threadId: string;\n isNewChat: boolean;\n client: AssistantClient;\n lifecycle: AthenaStatewireLifecycleState;\n}\n\n/**\n * The per-thread half of the statewire lane: owns the runtime hook (statewire\n * client, pending-message lane, `useAui` client) and the lifecycle reducer\n * behind the connection/error banners, and renders nothing itself. Mounted\n * under `key={threadId}` so a switch — or a new chat — gets a fresh instance\n * of everything here, exactly as when the whole provider subtree was keyed,\n * without remounting the host's UI.\n *\n * An assistant client's readable state only advances when its tap fibers\n * commit (in effects), so an in-place `threadId` change on one mounted hook\n * would leave a commit in which the new id is published but `useAuiState`\n * still reads the previous thread's committed state; a fresh mount publishes\n * its own state on its first render. That is why the runtime is remounted per\n * thread rather than switched in place.\n *\n * The snapshot is published from a layout effect: React flushes the state\n * update a layout effect schedules synchronously, before the browser paints,\n * so the scope re-renders against this client in the same task as this\n * mount's commit — the previous client is never painted under the new id.\n */\nfunction AthenaStatewireRuntimeMount({\n threadId,\n isNewChat,\n onPublish,\n syncUrl,\n apiKey,\n token,\n getToken,\n model,\n agent,\n channel,\n tools,\n frontendToolIds,\n frontendTools,\n workbench,\n knowledgeBase,\n systemPrompt,\n appId,\n extraRunConfig,\n snapshotCache,\n toolOutputs,\n}: AthenaStatewireRuntimeProps & {\n threadId: string;\n isNewChat: boolean;\n onPublish: (snapshot: AthenaStatewireRuntimeSnapshot) => void;\n}): null {\n const [lifecycle, dispatchLifecycle] = useReducer(\n statewireLifecycleReducer,\n initialStatewireLifecycle,\n );\n\n const client = useAthenaStatewireRuntime({\n syncUrl,\n threadId,\n isNewChat,\n apiKey,\n token,\n getToken,\n model,\n agent,\n channel,\n tools,\n frontendToolIds,\n frontendToolkit: frontendTools,\n workbench,\n knowledgeBase,\n systemPrompt,\n appId,\n extraRunConfig,\n snapshotCache,\n toolOutputs,\n // The runtime already records every transport error on the diagnostics\n // bus (with the channel-teardown split), so this layer only maps it to\n // the banner notice.\n onError: (error) => {\n const notice = athenaStatewireErrorNotice(error);\n if (notice) dispatchLifecycle({ type: 'error', error: notice });\n },\n onConnectionChange: (connection) => {\n dispatchLifecycle({ type: 'connection', connection });\n },\n onRawConnectionChange: (connection) => {\n dispatchLifecycle({ type: 'raw-connection', reconnect: connection.reconnect });\n },\n });\n\n // A thread the host stopped for refusing its credential reconnects as soon\n // as a new token exists, instead of waiting for a retry click.\n useRestartAfterAuthRefusal({\n connection: lifecycle.connection,\n reconnect: lifecycle.reconnect,\n });\n\n const dismissError = useCallback(\n () => dispatchLifecycle({ type: 'error', error: null }),\n [],\n );\n const lifecycleValue = useMemo<AthenaStatewireLifecycleState>(\n () => ({\n connection: lifecycle.connection,\n error: lifecycle.error,\n reconnect: lifecycle.reconnect,\n dismissError,\n }),\n [lifecycle, dismissError],\n );\n\n const snapshot = useMemo<AthenaStatewireRuntimeSnapshot>(\n () => ({ threadId, isNewChat, client, lifecycle: lifecycleValue }),\n [threadId, isNewChat, client, lifecycleValue],\n );\n useLayoutEffect(() => {\n onPublish(snapshot);\n }, [onPublish, snapshot]);\n\n return null;\n}\n\n/**\n * The stable half of the statewire lane: the scope around the host's\n * `children`. It mounts one `AthenaStatewireRuntimeMount` per thread beside\n * them and provides whatever that mount last published — client, thread ids,\n * lifecycle — so a thread switch swaps the client under the host's UI instead\n * of remounting it. Until the first mount has published, the children are\n * withheld: they need a client, and the first publication lands in the same\n * task as the mount's commit.\n *\n * A server render runs no effects, so it would withhold the children too.\n * That changes nothing today: `AthenaProvider` renders `null` until the parent\n * bridge reports ready, which only ever happens in an effect (`useParentBridge`\n * starts `ready: false`), so the SDK has never server-rendered the host UI —\n * it hydrates it. A future SSR-ready bridge would need the first publication\n * to happen in render as well.\n */\nfunction AthenaStatewireStandalone({\n children,\n backendUrl,\n appUrl,\n threadId: threadIdProp,\n threadList,\n linkClicks,\n citationLinks,\n ...runtimeProps\n}: AthenaStatewireStandaloneProps) {\n // Statewire attaches to `${syncUrl}/${threadId}`, so a thread ID must exist\n // up front. An auto-generated ID is by definition a never-started local chat.\n const generatedIdRef = useRef<string | null>(null);\n if (generatedIdRef.current === null) {\n generatedIdRef.current = mintThreadId();\n }\n const threadId = threadIdProp ?? generatedIdRef.current;\n const isNewChat = threadList?.isNewChat ?? !threadIdProp;\n\n const [published, setPublished] = useState<AthenaStatewireRuntimeSnapshot | null>(null);\n\n const clientTools = useStatewireClientTools(runtimeProps.frontendTools);\n\n // The runtime binds `client_tools` only for a recognised `app_id`; with none\n // it drops every declaration without telling the client, and the model then\n // sees \"not a valid tool\". Say so here, once per configuration, as an error\n // so it reaches `onError` and the console even with diagnostics off.\n const clientToolNamesKey = clientTools.map((tool) => tool.definition.name).join(',');\n const clientToolAppId = runtimeProps.appId;\n useEffect(() => {\n if (clientTools.length === 0 || resolveClientToolSurface(clientToolAppId) !== null) return;\n athenaDiagnostics.emit('sdk.config.warning', {\n level: 'error',\n error: new AthenaSdkError({\n code: 'config_invalid',\n message: `frontendTools with an execute() need a recognised appId; ${clientTools.length} tool(s) will not be bound.`,\n hint:\n \"Pass appId={publicAppId} on <AthenaProvider> (a computer-asset app reads it from athena-public-config.json as computer_asset_<uuid>). Without it the deep-agent runtime drops every client tool.\",\n context: { appId: clientToolAppId ?? null, tools: clientToolNamesKey.split(',') },\n }),\n data: { appId: clientToolAppId ?? null, tools: clientToolNamesKey.split(',') },\n });\n // clientToolNamesKey is the value-stable form of the tool list.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [clientToolAppId, clientToolNamesKey]);\n\n const athenaConfig = useAthenaConfigValue({\n backendUrl,\n appUrl,\n apiKey: runtimeProps.apiKey,\n token: runtimeProps.token,\n getToken: runtimeProps.getToken,\n enabledToolkits: runtimeProps.tools,\n linkClicks,\n citationLinks,\n });\n\n const scope = published && (\n <AuiProvider value={published.client}>\n <AthenaContext.Provider value={athenaConfig}>\n <AthenaStatewireThreadIdContext.Provider value={published.threadId}>\n <AthenaStatewireLifecycleContext.Provider value={published.lifecycle}>\n <DeepAgentConnectionContext.Provider value={published.lifecycle.connection}>\n <StatewireToolOutputsContext.Provider value={runtimeProps.toolOutputs}>\n <TooltipProvider>\n <StatewireClientToolBridge tools={clientTools} threadId={published.threadId} />\n <ComposerHandoffDrain />\n {children}\n </TooltipProvider>\n </StatewireToolOutputsContext.Provider>\n </DeepAgentConnectionContext.Provider>\n </AthenaStatewireLifecycleContext.Provider>\n </AthenaStatewireThreadIdContext.Provider>\n </AthenaContext.Provider>\n </AuiProvider>\n );\n\n return (\n <>\n <AthenaStatewireRuntimeMount\n key={threadId}\n threadId={threadId}\n isNewChat={isNewChat}\n onPublish={setPublished}\n {...runtimeProps}\n />\n {/* The backend id rides the same snapshot as the client, so\n history-gated UI (e.g. the loading overlay) never judges one thread\n by another's state; it is undefined for a never-started chat, which\n must not read as pending history. */}\n {threadList && published ? (\n <AthenaThreadIdContext.Provider\n value={published.isNewChat ? undefined : published.threadId}\n >\n {scope}\n </AthenaThreadIdContext.Provider>\n ) : (\n scope\n )}\n </>\n );\n}\n\n// ─── Thread List Mode ─────────────────────────────────────────────────\n\nfunction AthenaStatewireWithThreadList({\n children,\n backendUrl,\n syncUrl,\n appId,\n apiKey,\n token,\n getToken,\n initialThreadId,\n includePullRequests,\n ...standaloneProps\n}: Omit<AthenaStatewireStandaloneProps, 'threadId' | 'threadList'> & {\n initialThreadId?: string;\n includePullRequests?: boolean;\n}) {\n return (\n <AthenaStatewireThreadListProvider\n backendUrl={backendUrl}\n syncUrl={syncUrl}\n apiKey={apiKey}\n token={token}\n getToken={getToken}\n appId={appId}\n initialThreadId={initialThreadId}\n includePullRequests={includePullRequests}\n // The list's hover prefetch warms the same cache the active-thread\n // mount seeds from, so a hovered-then-selected session paints at once.\n snapshotCache={standaloneProps.snapshotCache}\n >\n <AthenaStatewireActiveThreadHost\n backendUrl={backendUrl}\n syncUrl={syncUrl}\n appId={appId}\n apiKey={apiKey}\n token={token}\n getToken={getToken}\n {...standaloneProps}\n >\n {children}\n </AthenaStatewireActiveThreadHost>\n </AthenaStatewireThreadListProvider>\n );\n}\n\nfunction AthenaStatewireActiveThreadHost({\n children,\n ...standaloneProps\n}: Omit<AthenaStatewireStandaloneProps, 'threadId' | 'threadList'>) {\n const list = useAthenaStatewireThreadList();\n if (!list) return null;\n\n // Not keyed: the scope keeps the host's children mounted across a switch\n // and remounts only its per-thread runtime against the new\n // `…/v2/threads/{id}` URL (see `AthenaStatewireStandalone`).\n return (\n <AthenaStatewireStandalone\n threadId={list.activeThreadId}\n threadList={{ isNewChat: list.isNewChat }}\n {...standaloneProps}\n >\n <StatewireThreadTitlePoller />\n <AssetPanelThreadSync />\n {children}\n </AthenaStatewireStandalone>\n );\n}\n\n/**\n * Syncs the active thread ID into the asset panel store so that open asset\n * tabs are scoped per-thread automatically.\n *\n * Scoped by the attached thread's minted id from creation onward — NOT by\n * `useAthenaThreadManager().activeThreadId`, which is deliberately `null`\n * while a new chat is unpersisted (so URL sync never names it). The minted id\n * is the id the thread persists under, so tabs opened in a brand-new chat\n * stay put when the backend first lists it instead of being left behind in a\n * `null` scope the store never restores. Read from the statewire scope (the\n * id published with its client) rather than the list's selection, which runs\n * one commit ahead of the client during a switch.\n */\nfunction AssetPanelThreadSync() {\n const threadId = useAthenaStatewireThreadId();\n const setCurrentThread = useAssetPanelStore((s) => s.setCurrentThread);\n\n useEffect(() => {\n setCurrentThread(threadId);\n }, [threadId, setCurrentThread]);\n\n return null;\n}\n\n// ─── Main Provider ────────────────────────────────────────────────────\n\nexport function AthenaProvider({\n children,\n config,\n apiKey,\n token: tokenProp,\n agent,\n channel,\n model,\n tools = [],\n frontendTools = {},\n disableAutoOpen = false,\n apiUrl,\n backendUrl,\n appUrl,\n environment,\n statewireSyncUrl,\n getToken,\n extraRunConfig,\n workbench,\n knowledgeBase,\n systemPrompt,\n appId,\n threadId: threadIdProp,\n enableThreadList = false,\n threadListIncludePullRequests = true,\n theme,\n linkClicks,\n citationLinks,\n posthog: posthogProp,\n debug,\n onDiagnostic,\n onError,\n}: AthenaProviderProps) {\n // Fail loud before any effect, bridge wait, or network call: an `agent`\n // outside the collab_agent namespace can never apply, so a misconfigured\n // deployment must die at first render rather than answer as the wrong agent.\n resolveAgentProp({ agent });\n\n // Diagnostics wiring first, so everything below is observable. Callbacks\n // ride refs: a per-render closure must not re-register the consumer. Each\n // provider registers its OWN consumer (additive, cleaned up on unmount), so\n // two mounted providers never clobber each other's onDiagnostic/onError —\n // only the console/PostHog/buffer settings are global (last writer wins).\n const onDiagnosticRef = useRef(onDiagnostic);\n onDiagnosticRef.current = onDiagnostic;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n useEffect(() => {\n installAthenaDiagnosticsGlobal();\n return athenaDiagnostics.addConsumer({\n onEvent: (event) => onDiagnosticRef.current?.(event),\n onError: (error, event) => onErrorRef.current?.(error, event),\n });\n }, []);\n const debugKey = JSON.stringify(debugPropToDiagnosticsConfig(debug));\n useEffect(() => {\n athenaDiagnostics.configure(debugPropToDiagnosticsConfig(debug));\n // debugKey is the value-stable form of `debug` (consumers pass literals).\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [debugKey]);\n // Only declarations WITHOUT a local `execute` ride `enabled_tools`: they name\n // registry tools the backend binds itself. Executable tools are declared\n // through `client_tools` instead — listing them here too would switch on a\n // backend toolkit owning a tool of the same name, and the backend wins that\n // collision (the client tool is silently dropped).\n const frontendToolNames = useMemo(\n () => backendDeclaredFrontendToolIds(frontendTools),\n [frontendTools],\n );\n // Merge SDK auto-open defaults under the consumer's frontendTools. Consumer\n // entries win on name collision; auto-open tool names are NOT added to\n // frontendToolIds (they are already backend-advertised by their toolkits).\n const effectiveFrontendTools = useMemo<Toolkit>(\n () => (disableAutoOpen ? frontendTools : { ...DEFAULT_AUTO_OPEN_TOOLS, ...frontendTools }),\n [disableAutoOpen, frontendTools],\n );\n const themeStyleVars = useMemo(() => theme ? themeToStyleVars(theme) : undefined, [theme]);\n const configuredEnvironment = config?.environment ?? environment;\n const environmentUrls = useMemo(\n () => getAthenaEnvironmentUrls({ environment: configuredEnvironment }),\n [configuredEnvironment],\n );\n const configuredApiKey = config?.apiKey ?? apiKey;\n const configuredToken = resolveTokenOverride({ config, token: tokenProp });\n const configuredApiUrl = config?.apiUrl ?? apiUrl;\n const configuredBackendUrl = config?.backendUrl ?? backendUrl;\n const configuredAppUrl = config?.appUrl ?? appUrl;\n const configuredStatewireSyncUrl = config?.statewireSyncUrl ?? statewireSyncUrl;\n const configuredGetToken = config?.getToken ?? getToken;\n const configuredExtraRunConfig = config?.extraRunConfig ?? extraRunConfig;\n const configuredTrustedParentOrigins = config?.trustedParentOrigins;\n const posthogConfig: PostHogConfig | undefined = config?.posthog ?? posthogProp;\n\n // Statewire is the SDK's only chat transport; the gauge/event stay on the\n // diagnostics contract so dashboards keyed on them keep reading a value.\n useEffect(() => {\n athenaDiagnostics.gauge('sdk.transport', 'statewire');\n athenaDiagnostics.emit('sdk.transport', {\n level: 'debug',\n data: { transport: 'statewire', thread_list: enableThreadList },\n });\n }, [enableThreadList]);\n\n const bridge = useParentBridge({\n trustedOrigins: configuredTrustedParentOrigins,\n });\n\n // If an AthenaAuthProvider is present above us, use its access token automatically.\n const authContext = useContext(AthenaAuthContext);\n const authProviderToken = authContext?.accessToken ?? null;\n\n // Per-provider snapshot cache: a switch back to a recently-visited thread\n // mounts with its last-known snapshot instead of a loading spinner. Owned\n // here, above the per-thread keyed mount, so it survives switches; cleared\n // when the acting identity changes so a snapshot captured under one account\n // never seeds a mount under another.\n const [snapshotCache] = useState(() => createDeepAgentThreadSnapshotCache());\n // Composer writes that arrive before the per-thread mount is ready wait\n // here, above that mount, so a thread-list remount cannot drop them.\n const [composerHandoff] = useState(createComposerHandoffStore);\n // The windowed wire's fetched-back tool outputs, owned alongside the cache\n // for the same reasons: shared across the provider's thread switches (a\n // tool message id is unique across threads), dropped with the identity.\n const [toolOutputs] = useState(() => createDeepAgentToolOutputStore());\n const principal = authContext?.user?.userId ?? '';\n useEffect(() => {\n snapshotCache.clear();\n toolOutputs.clear();\n // A draft or send queued under the previous identity must never land in\n // this one's composer.\n clearComposerHandoff({ store: composerHandoff, reason: 'the signed-in identity changed' });\n }, [snapshotCache, toolOutputs, composerHandoff, principal, configuredApiKey]);\n // Nothing drains after the provider is gone: settle what still waits so no\n // `useSendMessage` caller hangs.\n useEffect(\n () => () => clearComposerHandoff({ store: composerHandoff, reason: 'the chat provider unmounted' }),\n [composerHandoff],\n );\n\n const effectiveToken = configuredToken !== undefined\n ? configuredToken\n : authProviderToken ?? bridge.token;\n\n // One credential source for every network path below: it presents the\n // token chosen above and renews it the way its origin can. A host's own\n // `getToken` owns renewal; a host's static `token` never renews; a sign-in\n // provider's token renews through its getter (PropelAuth, SSO); a host\n // bridge token through the bridge (a Marathon re-mint, or the parent\n // window's next `athena-auth`).\n const authProviderGetToken = authContext?.getToken;\n const credentialInputsRef = useRef<AthenaCredentialInputs>({ token: null });\n credentialInputsRef.current = {\n hostGetToken: configuredGetToken,\n token: effectiveToken,\n renew:\n configuredToken !== undefined\n ? undefined\n : authProviderToken !== null\n ? authProviderGetToken\n ? async ({ force }) => (await authProviderGetToken({ force })) ?? null\n : undefined\n : bridge.token !== null\n ? bridge.renewToken\n : undefined,\n };\n const [credentials] = useState(() =>\n createAthenaCredentialSource(() => credentialInputsRef.current),\n );\n useEffect(() => {\n credentials.notifyTokenChanged();\n }, [credentials, effectiveToken]);\n // Only a provider that holds a token (or a host getter) hands one out, so\n // \"has credentials\" checks downstream keep meaning what they did.\n const credentialGetToken =\n configuredGetToken !== undefined || effectiveToken ? credentials.getToken : undefined;\n // Explicit config wins. A Marathon host mints the statewire mount, the bare\n // Agora base and the app origin outright (`/_athena/auth`, or a trusted\n // parent's `athena-config`); the environment preset is the last resort, and\n // the sync mount derives from the `apiUrl` host when no host minted one.\n const effectiveApiUrl = configuredApiUrl ?? environmentUrls.apiUrl;\n // Published as the bare Agora base: a historical `…/api/assistant-ui` value\n // is trimmed here once rather than by each REST helper.\n const effectiveBackendUrl = getAthenaApiBaseUrl(\n configuredBackendUrl ?? bridge.backendBaseUrl ?? environmentUrls.backendUrl,\n );\n const hostStatewireSyncUrl = configuredStatewireSyncUrl ?? bridge.statewireSyncUrl ?? undefined;\n const effectiveAppUrl = configuredAppUrl\n ?? bridge.appUrl\n ?? deriveAthenaAppUrl({ apiUrl: effectiveApiUrl, backendUrl: effectiveBackendUrl })\n ?? environmentUrls.appUrl;\n\n // Wait for the parent bridge to deliver config/auth before rendering.\n // This prevents the thread list from fetching with wrong URLs or no token.\n // Falls back after a short timeout (2s) if no bridge responds.\n if (!bridge.ready) {\n return null;\n }\n\n // Both throw on an unresolvable configuration instead of falling back to an\n // Athena default — a custom deployment's credentials must never be sent to\n // a host the consumer didn't configure. A host that answered the bridge\n // without minting the statewire mount is that case: its token would\n // otherwise ride the environment preset.\n assertHostMintedStatewireMount({\n hostAnswered: bridge.hostAnswered,\n hostStatewireSyncUrl: bridge.statewireSyncUrl,\n statewireSyncUrl: configuredStatewireSyncUrl,\n apiUrl: configuredApiUrl,\n });\n const effectiveStatewireSyncUrl = resolveStatewireSyncUrl({\n statewireSyncUrl: hostStatewireSyncUrl,\n apiUrl: effectiveApiUrl,\n });\n\n const statewireProps = {\n syncUrl: effectiveStatewireSyncUrl,\n backendUrl: effectiveBackendUrl,\n appUrl: effectiveAppUrl,\n apiKey: configuredApiKey,\n token: effectiveToken,\n getToken: credentialGetToken,\n model,\n agent,\n channel,\n tools,\n frontendToolIds: frontendToolNames,\n frontendTools: effectiveFrontendTools,\n workbench,\n knowledgeBase,\n systemPrompt,\n appId,\n extraRunConfig: configuredExtraRunConfig,\n snapshotCache,\n toolOutputs,\n linkClicks,\n citationLinks,\n };\n\n const inner: ReactNode = enableThreadList ? (\n <AthenaStatewireWithThreadList\n {...statewireProps}\n initialThreadId={threadIdProp}\n includePullRequests={threadListIncludePullRequests}\n >\n {children}\n </AthenaStatewireWithThreadList>\n ) : (\n <AthenaStatewireStandalone {...statewireProps} threadId={threadIdProp}>\n {children}\n </AthenaStatewireStandalone>\n );\n\n // The .athena-sdk wrapper (display: contents) anchors the SDK's design\n // tokens and scoped preflight from styles.css, so the stylesheet works\n // in hosts without their own Tailwind build. PostHog gracefully no-ops\n // when its config is missing.\n return (\n <div\n className={themeStyleVars ? \"athena-sdk athena-themed\" : \"athena-sdk\"}\n style={themeStyleVars as React.CSSProperties | undefined}\n >\n <PostHogProvider config={posthogConfig}>\n <ComposerHandoffContext.Provider value={composerHandoff}>\n <AthenaThemeStyleContext.Provider value={themeStyleVars}>\n <AthenaCredentialSourceContext.Provider value={credentials}>\n {inner}\n </AthenaCredentialSourceContext.Provider>\n </AthenaThemeStyleContext.Provider>\n </ComposerHandoffContext.Provider>\n </PostHogProvider>\n </div>\n );\n}\n"],"names":["useRef","useMemo","useAui","useComposerHandoffStore","useContext","AthenaStatewireThreadIdContext","useComposerReady","useEffect","drainComposerHandoff","toolOutputs","useReducer","statewireLifecycleReducer","initialStatewireLifecycle","useAthenaStatewireRuntime","athenaStatewireErrorNotice","useRestartAfterAuthRefusal","useCallback","useLayoutEffect","mintThreadId","useState","useStatewireClientTools","resolveClientToolSurface","athenaDiagnostics","AthenaSdkError","jsx","AuiProvider","AthenaContext","AthenaStatewireLifecycleContext","DeepAgentConnectionContext","StatewireToolOutputsContext","TooltipProvider","StatewireClientToolBridge","jsxs","Fragment","AthenaThreadIdContext","AthenaStatewireThreadListProvider","useAthenaStatewireThreadList","StatewireThreadTitlePoller","useAthenaStatewireThreadId","useAssetPanelStore","resolveAgentProp","installAthenaDiagnosticsGlobal","_a","debugPropToDiagnosticsConfig","backendDeclaredFrontendToolIds","DEFAULT_AUTO_OPEN_TOOLS","themeToStyleVars","getAthenaEnvironmentUrls","useParentBridge","AthenaAuthContext","createDeepAgentThreadSnapshotCache","composerHandoff","createComposerHandoffStore","createDeepAgentToolOutputStore","clearComposerHandoff","createAthenaCredentialSource","getAthenaApiBaseUrl","deriveAthenaAppUrl","assertHostMintedStatewireMount","resolveStatewireSyncUrl","PostHogProvider","ComposerHandoffContext","AthenaThemeStyleContext","AthenaCredentialSourceContext"],"mappings":"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"}
1
+ {"version":3,"file":"AthenaProvider.cjs","sources":["../../src/provider/AthenaProvider.tsx"],"sourcesContent":["import { AuiProvider, useAui } from '@assistant-ui/react';\nimport {\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useReducer,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport type { AssistantClient, Toolkit } from '@assistant-ui/react';\nimport {\n createDeepAgentThreadSnapshotCache,\n createDeepAgentToolOutputStore,\n DeepAgentConnectionContext,\n type DeepAgentThreadSnapshotCache,\n type DeepAgentToolOutputStore,\n} from '@athenaintel/agent-runtime';\nimport {\n assertHostMintedStatewireMount,\n deriveAthenaAppUrl,\n getAthenaEnvironmentUrls,\n resolveStatewireSyncUrl,\n type AthenaEnvironment,\n} from '../lib/athena-urls';\nimport { getAthenaApiBaseUrl } from '../collab/mint';\nimport { useParentBridge } from '../runtime/auth';\nimport { AthenaAuthContext } from '../auth/AthenaAuthContext';\nimport { AthenaCredentialSourceContext } from '../auth/AthenaCredentialSourceContext';\nimport {\n createAthenaCredentialSource,\n type AthenaCredentialInputs,\n} from '../auth/credential-source';\nimport { useRestartAfterAuthRefusal } from '../runtime/auth-refusal-restart';\nimport {\n useAthenaStatewireRuntime,\n useStatewireClientTools,\n} from '../runtime/useAthenaStatewireRuntime';\nimport {\n athenaStatewireErrorNotice,\n type AthenaStatewireLifecycleState,\n initialStatewireLifecycle,\n statewireLifecycleReducer,\n} from '../runtime/statewire-lifecycle';\nimport type { AthenaStatewireTokenGetter } from '../runtime/statewire-auth-headers';\nimport { resolveAgentProp } from '../runtime/statewire-run-config';\nimport { mintThreadId } from '../threads/mint-thread-id';\nimport { AthenaStatewireLifecycleContext } from './statewire-lifecycle-context';\nimport {\n ComposerHandoffContext,\n clearComposerHandoff,\n createComposerHandoffStore,\n drainComposerHandoff,\n useComposerHandoffStore,\n useComposerReady,\n} from '../composer/composer-handoff';\nimport { StatewireToolOutputsContext } from './statewire-window-context';\nimport { StatewireClientToolBridge } from '../chat/StatewireClientToolBridge';\nimport {\n athenaDiagnostics,\n debugPropToDiagnosticsConfig,\n installAthenaDiagnosticsGlobal,\n type AthenaDiagnosticEvent,\n type AthenaDiagnosticLevel,\n type AthenaDiagnosticsConfig,\n} from '../diagnostics/athena-diagnostics';\nimport { AthenaSdkError } from '../diagnostics/errors';\nimport {\n backendDeclaredFrontendToolIds,\n resolveClientToolSurface,\n} from '../chat/statewire-client-tools';\nimport { TooltipProvider } from '../ui/tooltip';\nimport { DEFAULT_AUTO_OPEN_TOOLS } from '../tools/auto-open-tools';\nimport { AthenaContext, type AthenaConfig } from './AthenaContext';\nimport type { AthenaProviderConfig } from './config';\nimport type {\n AthenaCitationLinkOptions,\n AthenaLinkClickOptions,\n} from './citation-links';\nimport {\n AthenaStatewireThreadIdContext,\n AthenaThreadIdContext,\n useAthenaStatewireThreadId,\n} from '../threads/thread-id-context';\nimport {\n AthenaStatewireThreadListProvider,\n StatewireThreadTitlePoller,\n useAthenaStatewireThreadList,\n} from '../threads/statewire-thread-list';\nimport { useAssetPanelStore } from '../assets/asset-panel-store';\nimport { themeToStyleVars, type AthenaTheme } from '../theme';\nimport { AthenaThemeStyleContext } from './theme-style-context';\nimport { PostHogProvider, type PostHogConfig } from './PostHogProvider';\n\nexport interface AthenaProviderProps {\n children: ReactNode;\n\n /** Preferred structured config for auth and Athena endpoint settings. */\n config?: AthenaProviderConfig;\n\n /** @deprecated Prefer `config.apiKey`. API key for authentication in standalone mode. */\n apiKey?: string;\n\n /** @deprecated Prefer `config.token`. PropelAuth token. If provided, takes priority over apiKey. If omitted, the SDK\n * will automatically listen for a token from the parent window via PostMessage. */\n token?: string | null;\n\n /** Run the thread AS a published collab agent. The only accepted shape is\n * `collab_agent:<asset_id>`: the thread then uses that agent's prompt,\n * tools, and model default, and the caller must have view access to the\n * agent asset. Omit it (or pass a blank string) to run the Athena deep agent.\n *\n * Any other non-blank value throws at render — the statewire host cannot\n * honour named agents, and a selector that is silently dropped would let a\n * misconfigured deployment answer as the wrong agent. */\n agent?: string;\n\n /** Collab-agent channel id — a built-in channel (`email`, `sms`, …) or a\n * user-defined custom channel id from the agent's Channels tab. Selects\n * that channel's configuration overrides and stamps the session's origin.\n * Only meaningful together with a `collab_agent:<asset_id>` `agent`; sent\n * as `collab_channel_id`. An unknown or disabled channel rejects the run\n * with a structured, teaching error. */\n channel?: string;\n\n /** LLM model identifier. Defaults to the deep-agent default model\n * (`DEFAULT_STATEWIRE_MODEL`) — or, when a collab agent is selected, to\n * the model its author configured. */\n model?: string;\n\n /** Backend toolkit IDs to enable (e.g. 'document_toolkit', 'web_search_browse_toolkit'). */\n tools?: string[];\n\n /** Frontend tools that execute in the browser. The agent can invoke these.\n * Merged on top of the SDK's default auto-open tools; entries here take\n * precedence over defaults with the same name. Tools with a local\n * `execute` are declared to the backend as `client_tools` and run through\n * the statewire client-tool bridge. */\n frontendTools?: Toolkit;\n\n /** Disable the SDK's default auto-open behavior for created/touched assets. */\n disableAutoOpen?: boolean;\n\n /** @deprecated Prefer `config.apiUrl`. URL on the Iris host fronting the\n * deployment; its origin derives the statewire sync mount when\n * `statewireSyncUrl` is not set. */\n apiUrl?: string;\n\n /** @deprecated Prefer `config.backendUrl`. URL for the Athena backend API. */\n backendUrl?: string;\n\n /** @deprecated Prefer `config.appUrl`. URL for the Athena frontend app origin. */\n appUrl?: string;\n\n /** @deprecated Prefer `config.environment`. Athena environment preset used when URLs are not explicitly provided. */\n environment?: AthenaEnvironment;\n\n /** Resolve the latest auth token immediately before a request (for\n * expiring clients). Takes priority over `token` when it resolves.\n * Prefer `config.getToken` (see its `force` contract for refused\n * credentials). */\n getToken?: AthenaStatewireTokenGetter;\n\n /** Additional fields merged into runConfig.custom. Prefer\n * `config.extraRunConfig`. */\n extraRunConfig?: Record<string, unknown>;\n\n /** Statewire sync base URL override (the `…/v2/threads` mount). Defaults to\n * the mount a Marathon host mints, then the effective `apiUrl` host +\n * `/v2/threads`. Prefer `config.statewireSyncUrl`. */\n statewireSyncUrl?: string;\n\n /** Asset IDs to include in the workbench. */\n workbench?: string[];\n\n /** Knowledge base IDs for RAG context. */\n knowledgeBase?: string[];\n\n /** System prompt override. */\n systemPrompt?: string;\n\n /** Client app identifier for session filtering.\n * Sessions created with this ID can be filtered in the thread list.\n * E.g. \"olympus\", \"athena-app\", or a computer asset ID like \"asset_<uuid>\". */\n appId?: string;\n\n /** Thread ID override. Auto-generated if not provided. */\n threadId?: string;\n\n /** Enable thread list management (sidebar thread switching). */\n enableThreadList?: boolean;\n\n /** Ask the thread list for live pull-request state on each session\n * (`include_pull_requests`), which `SessionList` renders as chips.\n * Defaults to `true` in thread-list mode; turn it off in a host that never\n * shows them to spare the server the lookup. */\n threadListIncludePullRequests?: boolean;\n\n /** Theme configuration. Pass a preset from `themes` or a custom `AthenaTheme` object.\n * Injects CSS variables on a wrapper element — no CSS files needed.\n *\n * @example\n * import { themes } from '@athenaintel/react';\n * <AthenaProvider theme={themes.dark}>\n *\n * @example\n * <AthenaProvider theme={{ primary: '#8b5cf6', radius: '1rem' }}>\n *\n * @example\n * <AthenaProvider theme={{ ...themes.dark, primary: '#22c55e' }}>\n */\n theme?: AthenaTheme;\n\n /** Customize how rendered chat links behave. */\n linkClicks?: AthenaLinkClickOptions;\n\n /** @deprecated Prefer `linkClicks`. Customize how Athena citation links rendered in chat messages behave. */\n citationLinks?: AthenaCitationLinkOptions;\n\n /** PostHog analytics configuration. When omitted or keys are missing, PostHog is silently disabled.\n * Prefer `config.posthog` for structured configuration. */\n posthog?: PostHogConfig;\n\n /** SDK diagnostics.\n *\n * - `true` / a level: echo structured `[AthenaSDK]` events to the console\n * at that level (`true` = 'debug').\n * - An object: full diagnostics config (console level, PostHog timing\n * forwarding, buffer size).\n *\n * Independent of the prop, `localStorage.setItem('athena:debug','debug')`\n * (or `window.__ATHENA_SDK__.diagnostics.enableConsole()`) turns console\n * echo on at runtime without a rebuild. Errors log once even when off. */\n debug?: boolean | AthenaDiagnosticLevel | Partial<AthenaDiagnosticsConfig>;\n\n /** Receives every diagnostics event (timings, warnings, errors) — the hook\n * for shipping SDK telemetry to the host app's own pipeline. */\n onDiagnostic?: (event: AthenaDiagnosticEvent) => void;\n\n /** Receives every SDK error as a typed `AthenaSdkError` (stable `code`,\n * `hint`, structured server `detail`). Fires in addition to the UI's own\n * error handling, so integrations never fail silently. */\n onError?: (error: AthenaSdkError, event: AthenaDiagnosticEvent) => void;\n}\n\nconst resolveTokenOverride = ({\n config,\n token,\n}: {\n config?: AthenaProviderConfig;\n token?: string | null;\n}): string | null | undefined => {\n if (config?.token !== undefined) {\n return config.token;\n }\n return token;\n};\n\nconst useAthenaConfigValue = ({\n backendUrl,\n appUrl,\n apiKey,\n token,\n getToken,\n enabledToolkits,\n linkClicks,\n citationLinks,\n}: {\n backendUrl: string;\n appUrl: string;\n apiKey?: string;\n token?: string | null;\n getToken?: AthenaStatewireTokenGetter;\n enabledToolkits: string[];\n linkClicks?: AthenaLinkClickOptions;\n citationLinks?: AthenaCitationLinkOptions;\n}): AthenaConfig => {\n const linkClicksRef = useRef(linkClicks);\n linkClicksRef.current = linkClicks;\n const citationLinksRef = useRef(citationLinks);\n citationLinksRef.current = citationLinks;\n // Keep token in a ref so its value can update without invalidating the\n // config object identity. PropelAuth rotates tokens on window focus —\n // if token were a memo dep, every rotation would publish a new config\n // object to context and force every consumer (e.g. AssetIframe) to\n // re-render, causing asset panel flicker.\n const tokenRef = useRef(token);\n tokenRef.current = token;\n const getTokenRef = useRef(getToken);\n getTokenRef.current = getToken;\n\n return useMemo(\n () => ({\n backendUrl,\n appUrl,\n apiKey,\n enabledToolkits,\n get token() {\n return tokenRef.current;\n },\n get getToken() {\n return getTokenRef.current;\n },\n get linkClicks() {\n return linkClicksRef.current;\n },\n get citationLinks() {\n return citationLinksRef.current;\n },\n }),\n [backendUrl, appUrl, apiKey, enabledToolkits],\n );\n};\n\n/**\n * Delivers composer writes that were made before this mount was ready\n * (`useAppendToComposer` / `useSendMessage` queue them in the provider-level\n * store, which outlives the keyed per-thread mount). Lives under the\n * `AuiProvider` so it can read the thread's own loading state.\n */\nfunction ComposerHandoffDrain(): null {\n const aui = useAui();\n const store = useComposerHandoffStore();\n const threadId = useContext(AthenaStatewireThreadIdContext);\n const ready = useComposerReady();\n useEffect(() => {\n if (!ready || !store) return;\n // Writes bound to another thread are dropped here, not applied.\n drainComposerHandoff({ store, target: aui, threadId });\n }, [aui, ready, store, threadId]);\n return null;\n}\n\n// ─── Standalone Mode ──────────────────────────────────────────────────\n\n/** Everything the per-thread runtime needs to attach and run a thread. */\ninterface AthenaStatewireRuntimeProps {\n syncUrl: string;\n apiKey?: string;\n token?: string | null;\n getToken?: AthenaStatewireTokenGetter;\n model?: string;\n agent?: string;\n channel?: string;\n tools: string[];\n frontendToolIds: string[];\n frontendTools: Toolkit;\n workbench?: string[];\n knowledgeBase?: string[];\n systemPrompt?: string;\n appId?: string;\n extraRunConfig?: Record<string, unknown>;\n /** The provider-owned snapshot cache (see `AthenaProvider`). */\n snapshotCache: DeepAgentThreadSnapshotCache;\n /** The provider-owned store of fetched-back cut tool outputs (see `AthenaProvider`). */\n toolOutputs: DeepAgentToolOutputStore;\n}\n\ninterface AthenaStatewireStandaloneProps extends AthenaStatewireRuntimeProps {\n children: ReactNode;\n backendUrl: string;\n appUrl: string;\n threadId?: string;\n /**\n * Thread-list mode. The list owns the active id and alone knows whether the\n * backend has listed it yet: `isNewChat` overrides the \"new chat\"\n * derivation (the list mints ids for brand-new chats, which must still load\n * as new), and the scope publishes `AthenaThreadIdContext` — the backend id,\n * withheld while the chat is unpersisted. Absent outside thread-list mode,\n * where that context stays untouched.\n */\n threadList?: { isNewChat: boolean };\n linkClicks?: AthenaLinkClickOptions;\n citationLinks?: AthenaCitationLinkOptions;\n}\n\n/**\n * What one per-thread runtime mount hands to the stable scope around the\n * host's children: the assistant client attached to `threadId` and the\n * transport lifecycle observed on that attach. Published as ONE value so the\n * scope can never pair a thread's id with another thread's client.\n */\ninterface AthenaStatewireRuntimeSnapshot {\n threadId: string;\n isNewChat: boolean;\n client: AssistantClient;\n lifecycle: AthenaStatewireLifecycleState;\n}\n\n/**\n * The per-thread half of the statewire lane: owns the runtime hook (statewire\n * client, pending-message lane, `useAui` client) and the lifecycle reducer\n * behind the connection/error banners, and renders nothing itself. Mounted\n * under `key={threadId}` so a switch — or a new chat — gets a fresh instance\n * of everything here, exactly as when the whole provider subtree was keyed,\n * without remounting the host's UI.\n *\n * An assistant client's readable state only advances when its tap fibers\n * commit (in effects), so an in-place `threadId` change on one mounted hook\n * would leave a commit in which the new id is published but `useAuiState`\n * still reads the previous thread's committed state; a fresh mount publishes\n * its own state on its first render. That is why the runtime is remounted per\n * thread rather than switched in place.\n *\n * The snapshot is published from a layout effect: React flushes the state\n * update a layout effect schedules synchronously, before the browser paints,\n * so the scope re-renders against this client in the same task as this\n * mount's commit — the previous client is never painted under the new id.\n */\nfunction AthenaStatewireRuntimeMount({\n threadId,\n isNewChat,\n onPublish,\n syncUrl,\n apiKey,\n token,\n getToken,\n model,\n agent,\n channel,\n tools,\n frontendToolIds,\n frontendTools,\n workbench,\n knowledgeBase,\n systemPrompt,\n appId,\n extraRunConfig,\n snapshotCache,\n toolOutputs,\n}: AthenaStatewireRuntimeProps & {\n threadId: string;\n isNewChat: boolean;\n onPublish: (snapshot: AthenaStatewireRuntimeSnapshot) => void;\n}): null {\n const [lifecycle, dispatchLifecycle] = useReducer(\n statewireLifecycleReducer,\n initialStatewireLifecycle,\n );\n\n const client = useAthenaStatewireRuntime({\n syncUrl,\n threadId,\n isNewChat,\n apiKey,\n token,\n getToken,\n model,\n agent,\n channel,\n tools,\n frontendToolIds,\n frontendToolkit: frontendTools,\n workbench,\n knowledgeBase,\n systemPrompt,\n appId,\n extraRunConfig,\n snapshotCache,\n toolOutputs,\n // The runtime already records every transport error on the diagnostics\n // bus (with the channel-teardown split), so this layer only maps it to\n // the banner notice.\n onError: (error) => {\n const notice = athenaStatewireErrorNotice(error);\n if (notice) dispatchLifecycle({ type: 'error', error: notice });\n },\n onConnectionChange: (connection) => {\n dispatchLifecycle({ type: 'connection', connection });\n },\n onRawConnectionChange: (connection) => {\n dispatchLifecycle({ type: 'raw-connection', reconnect: connection.reconnect });\n },\n });\n\n // A thread the host stopped for refusing its credential reconnects as soon\n // as a new token exists, instead of waiting for a retry click.\n useRestartAfterAuthRefusal({\n connection: lifecycle.connection,\n reconnect: lifecycle.reconnect,\n });\n\n const dismissError = useCallback(\n () => dispatchLifecycle({ type: 'error', error: null }),\n [],\n );\n const lifecycleValue = useMemo<AthenaStatewireLifecycleState>(\n () => ({\n connection: lifecycle.connection,\n error: lifecycle.error,\n reconnect: lifecycle.reconnect,\n dismissError,\n }),\n [lifecycle, dismissError],\n );\n\n const snapshot = useMemo<AthenaStatewireRuntimeSnapshot>(\n () => ({ threadId, isNewChat, client, lifecycle: lifecycleValue }),\n [threadId, isNewChat, client, lifecycleValue],\n );\n useLayoutEffect(() => {\n onPublish(snapshot);\n }, [onPublish, snapshot]);\n\n return null;\n}\n\n/**\n * The stable half of the statewire lane: the scope around the host's\n * `children`. It mounts one `AthenaStatewireRuntimeMount` per thread beside\n * them and provides whatever that mount last published — client, thread ids,\n * lifecycle — so a thread switch swaps the client under the host's UI instead\n * of remounting it. Until the first mount has published, the children are\n * withheld: they need a client, and the first publication lands in the same\n * task as the mount's commit.\n *\n * A server render runs no effects, so it would withhold the children too.\n * That changes nothing today: `AthenaProvider` renders `null` until the parent\n * bridge reports ready, which only ever happens in an effect (`useParentBridge`\n * starts `ready: false`), so the SDK has never server-rendered the host UI —\n * it hydrates it. A future SSR-ready bridge would need the first publication\n * to happen in render as well.\n */\nfunction AthenaStatewireStandalone({\n children,\n backendUrl,\n appUrl,\n threadId: threadIdProp,\n threadList,\n linkClicks,\n citationLinks,\n ...runtimeProps\n}: AthenaStatewireStandaloneProps) {\n // Statewire attaches to `${syncUrl}/${threadId}`, so a thread ID must exist\n // up front. An auto-generated ID is by definition a never-started local chat.\n const generatedIdRef = useRef<string | null>(null);\n if (generatedIdRef.current === null) {\n generatedIdRef.current = mintThreadId();\n }\n const threadId = threadIdProp ?? generatedIdRef.current;\n const isNewChat = threadList?.isNewChat ?? !threadIdProp;\n\n const [published, setPublished] = useState<AthenaStatewireRuntimeSnapshot | null>(null);\n\n const clientTools = useStatewireClientTools(runtimeProps.frontendTools);\n\n // The runtime binds `client_tools` only for a recognised `app_id`; with none\n // it drops every declaration without telling the client, and the model then\n // sees \"not a valid tool\". Say so here, once per configuration, as an error\n // so it reaches `onError` and the console even with diagnostics off.\n const clientToolNamesKey = clientTools.map((tool) => tool.definition.name).join(',');\n const clientToolAppId = runtimeProps.appId;\n useEffect(() => {\n if (clientTools.length === 0 || resolveClientToolSurface(clientToolAppId) !== null) return;\n athenaDiagnostics.emit('sdk.config.warning', {\n level: 'error',\n error: new AthenaSdkError({\n code: 'config_invalid',\n message: `frontendTools with an execute() need a recognised appId; ${clientTools.length} tool(s) will not be bound.`,\n hint:\n \"Pass appId={publicAppId} on <AthenaProvider> (a computer-asset app reads it from athena-public-config.json as computer_asset_<uuid>). Without it the deep-agent runtime drops every client tool.\",\n context: { appId: clientToolAppId ?? null, tools: clientToolNamesKey.split(',') },\n }),\n data: { appId: clientToolAppId ?? null, tools: clientToolNamesKey.split(',') },\n });\n // clientToolNamesKey is the value-stable form of the tool list.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [clientToolAppId, clientToolNamesKey]);\n\n const athenaConfig = useAthenaConfigValue({\n backendUrl,\n appUrl,\n apiKey: runtimeProps.apiKey,\n token: runtimeProps.token,\n getToken: runtimeProps.getToken,\n enabledToolkits: runtimeProps.tools,\n linkClicks,\n citationLinks,\n });\n\n const scope = published && (\n <AuiProvider value={published.client}>\n <AthenaContext.Provider value={athenaConfig}>\n <AthenaStatewireThreadIdContext.Provider value={published.threadId}>\n <AthenaStatewireLifecycleContext.Provider value={published.lifecycle}>\n <DeepAgentConnectionContext.Provider value={published.lifecycle.connection}>\n <StatewireToolOutputsContext.Provider value={runtimeProps.toolOutputs}>\n <TooltipProvider>\n <StatewireClientToolBridge tools={clientTools} threadId={published.threadId} />\n <ComposerHandoffDrain />\n {children}\n </TooltipProvider>\n </StatewireToolOutputsContext.Provider>\n </DeepAgentConnectionContext.Provider>\n </AthenaStatewireLifecycleContext.Provider>\n </AthenaStatewireThreadIdContext.Provider>\n </AthenaContext.Provider>\n </AuiProvider>\n );\n\n return (\n <>\n <AthenaStatewireRuntimeMount\n key={threadId}\n threadId={threadId}\n isNewChat={isNewChat}\n onPublish={setPublished}\n {...runtimeProps}\n />\n {/* The backend id rides the same snapshot as the client, so\n history-gated UI (e.g. the loading overlay) never judges one thread\n by another's state; it is undefined for a never-started chat, which\n must not read as pending history. */}\n {threadList && published ? (\n <AthenaThreadIdContext.Provider\n value={published.isNewChat ? undefined : published.threadId}\n >\n {scope}\n </AthenaThreadIdContext.Provider>\n ) : (\n scope\n )}\n </>\n );\n}\n\n// ─── Thread List Mode ─────────────────────────────────────────────────\n\nfunction AthenaStatewireWithThreadList({\n children,\n backendUrl,\n syncUrl,\n appId,\n apiKey,\n token,\n getToken,\n initialThreadId,\n includePullRequests,\n ...standaloneProps\n}: Omit<AthenaStatewireStandaloneProps, 'threadId' | 'threadList'> & {\n initialThreadId?: string;\n includePullRequests?: boolean;\n}) {\n return (\n <AthenaStatewireThreadListProvider\n backendUrl={backendUrl}\n syncUrl={syncUrl}\n apiKey={apiKey}\n token={token}\n getToken={getToken}\n appId={appId}\n initialThreadId={initialThreadId}\n includePullRequests={includePullRequests}\n // The list's hover prefetch warms the same cache the active-thread\n // mount seeds from, so a hovered-then-selected session paints at once.\n snapshotCache={standaloneProps.snapshotCache}\n >\n <AthenaStatewireActiveThreadHost\n backendUrl={backendUrl}\n syncUrl={syncUrl}\n appId={appId}\n apiKey={apiKey}\n token={token}\n getToken={getToken}\n {...standaloneProps}\n >\n {children}\n </AthenaStatewireActiveThreadHost>\n </AthenaStatewireThreadListProvider>\n );\n}\n\nfunction AthenaStatewireActiveThreadHost({\n children,\n ...standaloneProps\n}: Omit<AthenaStatewireStandaloneProps, 'threadId' | 'threadList'>) {\n const list = useAthenaStatewireThreadList();\n if (!list) return null;\n\n // Not keyed: the scope keeps the host's children mounted across a switch\n // and remounts only its per-thread runtime against the new\n // `…/v2/threads/{id}` URL (see `AthenaStatewireStandalone`).\n return (\n <AthenaStatewireStandalone\n threadId={list.activeThreadId}\n threadList={{ isNewChat: list.isNewChat }}\n {...standaloneProps}\n >\n <StatewireThreadTitlePoller />\n <AssetPanelThreadSync />\n {children}\n </AthenaStatewireStandalone>\n );\n}\n\n/**\n * Syncs the active thread ID into the asset panel store so that open asset\n * tabs are scoped per-thread automatically.\n *\n * Scoped by the attached thread's minted id from creation onward — NOT by\n * `useAthenaThreadManager().activeThreadId`, which is deliberately `null`\n * while a new chat is unpersisted (so URL sync never names it). The minted id\n * is the id the thread persists under, so tabs opened in a brand-new chat\n * stay put when the backend first lists it instead of being left behind in a\n * `null` scope the store never restores. Read from the statewire scope (the\n * id published with its client) rather than the list's selection, which runs\n * one commit ahead of the client during a switch.\n */\nfunction AssetPanelThreadSync() {\n const threadId = useAthenaStatewireThreadId();\n const setCurrentThread = useAssetPanelStore((s) => s.setCurrentThread);\n\n useEffect(() => {\n setCurrentThread(threadId);\n }, [threadId, setCurrentThread]);\n\n return null;\n}\n\n// ─── Main Provider ────────────────────────────────────────────────────\n\nexport function AthenaProvider({\n children,\n config,\n apiKey,\n token: tokenProp,\n agent,\n channel,\n model,\n tools = [],\n frontendTools = {},\n disableAutoOpen = false,\n apiUrl,\n backendUrl,\n appUrl,\n environment,\n statewireSyncUrl,\n getToken,\n extraRunConfig,\n workbench,\n knowledgeBase,\n systemPrompt,\n appId,\n threadId: threadIdProp,\n enableThreadList = false,\n threadListIncludePullRequests = true,\n theme,\n linkClicks,\n citationLinks,\n posthog: posthogProp,\n debug,\n onDiagnostic,\n onError,\n}: AthenaProviderProps) {\n // Fail loud before any effect, bridge wait, or network call: an `agent`\n // outside the collab_agent namespace can never apply, so a misconfigured\n // deployment must die at first render rather than answer as the wrong agent.\n resolveAgentProp({ agent });\n\n // Diagnostics wiring first, so everything below is observable. Callbacks\n // ride refs: a per-render closure must not re-register the consumer. Each\n // provider registers its OWN consumer (additive, cleaned up on unmount), so\n // two mounted providers never clobber each other's onDiagnostic/onError —\n // only the console/PostHog/buffer settings are global (last writer wins).\n const onDiagnosticRef = useRef(onDiagnostic);\n onDiagnosticRef.current = onDiagnostic;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n useEffect(() => {\n installAthenaDiagnosticsGlobal();\n return athenaDiagnostics.addConsumer({\n onEvent: (event) => onDiagnosticRef.current?.(event),\n onError: (error, event) => onErrorRef.current?.(error, event),\n });\n }, []);\n const debugKey = JSON.stringify(debugPropToDiagnosticsConfig(debug));\n useEffect(() => {\n athenaDiagnostics.configure(debugPropToDiagnosticsConfig(debug));\n // debugKey is the value-stable form of `debug` (consumers pass literals).\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [debugKey]);\n // Only declarations WITHOUT a local `execute` ride `enabled_tools`: they name\n // registry tools the backend binds itself. Executable tools are declared\n // through `client_tools` instead — listing them here too would switch on a\n // backend toolkit owning a tool of the same name, and the backend wins that\n // collision (the client tool is silently dropped).\n const frontendToolNames = useMemo(\n () => backendDeclaredFrontendToolIds(frontendTools),\n [frontendTools],\n );\n // Merge SDK auto-open defaults under the consumer's frontendTools. Consumer\n // entries win on name collision; auto-open tool names are NOT added to\n // frontendToolIds (they are already backend-advertised by their toolkits).\n const effectiveFrontendTools = useMemo<Toolkit>(\n () => (disableAutoOpen ? frontendTools : { ...DEFAULT_AUTO_OPEN_TOOLS, ...frontendTools }),\n [disableAutoOpen, frontendTools],\n );\n const themeStyleVars = useMemo(() => theme ? themeToStyleVars(theme) : undefined, [theme]);\n const configuredEnvironment = config?.environment ?? environment;\n const environmentUrls = useMemo(\n () => getAthenaEnvironmentUrls({ environment: configuredEnvironment }),\n [configuredEnvironment],\n );\n const configuredApiKey = config?.apiKey ?? apiKey;\n const configuredToken = resolveTokenOverride({ config, token: tokenProp });\n const configuredApiUrl = config?.apiUrl ?? apiUrl;\n const configuredBackendUrl = config?.backendUrl ?? backendUrl;\n const configuredAppUrl = config?.appUrl ?? appUrl;\n const configuredStatewireSyncUrl = config?.statewireSyncUrl ?? statewireSyncUrl;\n const configuredGetToken = config?.getToken ?? getToken;\n const configuredExtraRunConfig = config?.extraRunConfig ?? extraRunConfig;\n const configuredTrustedParentOrigins = config?.trustedParentOrigins;\n const posthogConfig: PostHogConfig | undefined = config?.posthog ?? posthogProp;\n\n // Statewire is the SDK's only chat transport; the gauge/event stay on the\n // diagnostics contract so dashboards keyed on them keep reading a value.\n useEffect(() => {\n athenaDiagnostics.gauge('sdk.transport', 'statewire');\n athenaDiagnostics.emit('sdk.transport', {\n level: 'debug',\n data: { transport: 'statewire', thread_list: enableThreadList },\n });\n }, [enableThreadList]);\n\n const bridge = useParentBridge({\n trustedOrigins: configuredTrustedParentOrigins,\n });\n\n // If an AthenaAuthProvider is present above us, use its access token automatically.\n const authContext = useContext(AthenaAuthContext);\n const authProviderToken = authContext?.accessToken ?? null;\n\n // Per-provider snapshot cache: a switch back to a recently-visited thread\n // mounts with its last-known snapshot instead of a loading spinner. Owned\n // here, above the per-thread keyed mount, so it survives switches; cleared\n // when the acting identity changes so a snapshot captured under one account\n // never seeds a mount under another.\n const [snapshotCache] = useState(() => createDeepAgentThreadSnapshotCache());\n // Composer writes that arrive before the per-thread mount is ready wait\n // here, above that mount, so a thread-list remount cannot drop them.\n const [composerHandoff] = useState(createComposerHandoffStore);\n // The windowed wire's fetched-back tool outputs, owned alongside the cache\n // for the same reasons: shared across the provider's thread switches (a\n // tool message id is unique across threads), dropped with the identity.\n const [toolOutputs] = useState(() => createDeepAgentToolOutputStore());\n const principal = authContext?.user?.userId ?? '';\n useEffect(() => {\n snapshotCache.clear();\n toolOutputs.clear();\n // A draft or send queued under the previous identity must never land in\n // this one's composer.\n clearComposerHandoff({ store: composerHandoff, reason: 'the signed-in identity changed' });\n }, [snapshotCache, toolOutputs, composerHandoff, principal, configuredApiKey]);\n // Nothing drains after the provider is gone: settle what still waits so no\n // `useSendMessage` caller hangs.\n useEffect(\n () => () => clearComposerHandoff({ store: composerHandoff, reason: 'the chat provider unmounted' }),\n [composerHandoff],\n );\n\n const effectiveToken = configuredToken !== undefined\n ? configuredToken\n : authProviderToken ?? bridge.token;\n\n // One credential source for every network path below: it presents the\n // token chosen above and renews it the way its origin can. A host's own\n // `getToken` owns renewal; a host's static `token` never renews; a sign-in\n // provider's token renews through its getter (PropelAuth, SSO); a host\n // bridge token through the bridge (a Marathon re-mint, or the parent\n // window's next `athena-auth`).\n const authProviderGetToken = authContext?.getToken;\n const credentialInputsRef = useRef<AthenaCredentialInputs>({ token: null });\n credentialInputsRef.current = {\n hostGetToken: configuredGetToken,\n token: effectiveToken,\n renew:\n configuredToken !== undefined\n ? undefined\n : authProviderToken !== null\n ? authProviderGetToken\n ? async ({ force }) => (await authProviderGetToken({ force })) ?? null\n : undefined\n : bridge.token !== null\n ? bridge.renewToken\n : undefined,\n };\n const [credentials] = useState(() =>\n createAthenaCredentialSource(() => credentialInputsRef.current),\n );\n useEffect(() => {\n credentials.notifyTokenChanged();\n }, [credentials, effectiveToken]);\n // Only a provider that holds a token (or a host getter) hands one out, so\n // \"has credentials\" checks downstream keep meaning what they did.\n const credentialGetToken =\n configuredGetToken !== undefined || effectiveToken ? credentials.getToken : undefined;\n // Explicit config wins. A Marathon host mints the statewire mount, the bare\n // Agora base and the app origin outright (`/_athena/auth`, or a trusted\n // parent's `athena-config`); the environment preset is the last resort, and\n // the sync mount derives from the `apiUrl` host when no host minted one.\n const effectiveApiUrl = configuredApiUrl ?? environmentUrls.apiUrl;\n // Published as the bare Agora base: a historical `…/api/assistant-ui` value\n // is trimmed here once rather than by each REST helper.\n const effectiveBackendUrl = getAthenaApiBaseUrl(\n configuredBackendUrl ?? bridge.backendBaseUrl ?? environmentUrls.backendUrl,\n );\n const hostStatewireSyncUrl = configuredStatewireSyncUrl ?? bridge.statewireSyncUrl ?? undefined;\n const effectiveAppUrl = configuredAppUrl\n ?? bridge.appUrl\n ?? deriveAthenaAppUrl({ apiUrl: effectiveApiUrl, backendUrl: effectiveBackendUrl })\n ?? environmentUrls.appUrl;\n\n // Wait for the parent bridge to deliver config/auth before rendering.\n // This prevents the thread list from fetching with wrong URLs or no token.\n // An iframe bridge falls back after a short timeout (2s) if no parent\n // answers; a Marathon mint is ready once its bounded retry cycle ends.\n if (!bridge.ready) {\n return null;\n }\n\n // Fail closed when the host's mint gave up and nothing else can\n // authenticate: the chat would otherwise attach with no credential (and to\n // the environment preset, since no host minted a mount). The bridge has\n // already reported the typed `auth_bridge_failed` / `auth_bridge_timeout`\n // error to `onError`; remounting the provider starts a new bounded mint.\n if (\n bridge.error &&\n !effectiveToken &&\n configuredGetToken === undefined &&\n !configuredApiKey\n ) {\n return null;\n }\n\n // Both throw on an unresolvable configuration instead of falling back to an\n // Athena default — a custom deployment's credentials must never be sent to\n // a host the consumer didn't configure. A host that answered the bridge\n // without minting the statewire mount is that case: its token would\n // otherwise ride the environment preset.\n assertHostMintedStatewireMount({\n hostAnswered: bridge.hostAnswered,\n hostStatewireSyncUrl: bridge.statewireSyncUrl,\n statewireSyncUrl: configuredStatewireSyncUrl,\n apiUrl: configuredApiUrl,\n });\n const effectiveStatewireSyncUrl = resolveStatewireSyncUrl({\n statewireSyncUrl: hostStatewireSyncUrl,\n apiUrl: effectiveApiUrl,\n });\n\n const statewireProps = {\n syncUrl: effectiveStatewireSyncUrl,\n backendUrl: effectiveBackendUrl,\n appUrl: effectiveAppUrl,\n apiKey: configuredApiKey,\n token: effectiveToken,\n getToken: credentialGetToken,\n model,\n agent,\n channel,\n tools,\n frontendToolIds: frontendToolNames,\n frontendTools: effectiveFrontendTools,\n workbench,\n knowledgeBase,\n systemPrompt,\n appId,\n extraRunConfig: configuredExtraRunConfig,\n snapshotCache,\n toolOutputs,\n linkClicks,\n citationLinks,\n };\n\n const inner: ReactNode = enableThreadList ? (\n <AthenaStatewireWithThreadList\n {...statewireProps}\n initialThreadId={threadIdProp}\n includePullRequests={threadListIncludePullRequests}\n >\n {children}\n </AthenaStatewireWithThreadList>\n ) : (\n <AthenaStatewireStandalone {...statewireProps} threadId={threadIdProp}>\n {children}\n </AthenaStatewireStandalone>\n );\n\n // The .athena-sdk wrapper (display: contents) anchors the SDK's design\n // tokens and scoped preflight from styles.css, so the stylesheet works\n // in hosts without their own Tailwind build. PostHog gracefully no-ops\n // when its config is missing.\n return (\n <div\n className={themeStyleVars ? \"athena-sdk athena-themed\" : \"athena-sdk\"}\n style={themeStyleVars as React.CSSProperties | undefined}\n >\n <PostHogProvider config={posthogConfig}>\n <ComposerHandoffContext.Provider value={composerHandoff}>\n <AthenaThemeStyleContext.Provider value={themeStyleVars}>\n <AthenaCredentialSourceContext.Provider value={credentials}>\n {inner}\n </AthenaCredentialSourceContext.Provider>\n </AthenaThemeStyleContext.Provider>\n </ComposerHandoffContext.Provider>\n </PostHogProvider>\n </div>\n );\n}\n"],"names":["useRef","useMemo","useAui","useComposerHandoffStore","useContext","AthenaStatewireThreadIdContext","useComposerReady","useEffect","drainComposerHandoff","toolOutputs","useReducer","statewireLifecycleReducer","initialStatewireLifecycle","useAthenaStatewireRuntime","athenaStatewireErrorNotice","useRestartAfterAuthRefusal","useCallback","useLayoutEffect","mintThreadId","useState","useStatewireClientTools","resolveClientToolSurface","athenaDiagnostics","AthenaSdkError","jsx","AuiProvider","AthenaContext","AthenaStatewireLifecycleContext","DeepAgentConnectionContext","StatewireToolOutputsContext","TooltipProvider","StatewireClientToolBridge","jsxs","Fragment","AthenaThreadIdContext","AthenaStatewireThreadListProvider","useAthenaStatewireThreadList","StatewireThreadTitlePoller","useAthenaStatewireThreadId","useAssetPanelStore","resolveAgentProp","installAthenaDiagnosticsGlobal","_a","debugPropToDiagnosticsConfig","backendDeclaredFrontendToolIds","DEFAULT_AUTO_OPEN_TOOLS","themeToStyleVars","getAthenaEnvironmentUrls","useParentBridge","AthenaAuthContext","createDeepAgentThreadSnapshotCache","composerHandoff","createComposerHandoffStore","createDeepAgentToolOutputStore","clearComposerHandoff","createAthenaCredentialSource","getAthenaApiBaseUrl","deriveAthenaAppUrl","assertHostMintedStatewireMount","resolveStatewireSyncUrl","PostHogProvider","ComposerHandoffContext","AthenaThemeStyleContext","AthenaCredentialSourceContext"],"mappings":"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"}
@@ -442,6 +442,9 @@ function AthenaProvider({
442
442
  if (!bridge.ready) {
443
443
  return null;
444
444
  }
445
+ if (bridge.error && !effectiveToken && configuredGetToken === void 0 && !configuredApiKey) {
446
+ return null;
447
+ }
445
448
  assertHostMintedStatewireMount({
446
449
  hostAnswered: bridge.hostAnswered,
447
450
  hostStatewireSyncUrl: bridge.statewireSyncUrl,