@athenaintel/react 0.55.0 → 0.57.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.
- package/README.md +84 -1
- package/dist/agent-runtime/src/answer-label.cjs +8 -2
- package/dist/agent-runtime/src/answer-label.cjs.map +1 -1
- package/dist/agent-runtime/src/answer-label.d.ts +10 -4
- package/dist/agent-runtime/src/answer-label.js +8 -2
- package/dist/agent-runtime/src/answer-label.js.map +1 -1
- package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs +6 -3
- package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs.map +1 -1
- package/dist/agent-runtime/src/deep-agent-transport-recipe.js +6 -3
- package/dist/agent-runtime/src/deep-agent-transport-recipe.js.map +1 -1
- package/dist/agent-runtime/src/edit-command.cjs +40 -19
- package/dist/agent-runtime/src/edit-command.cjs.map +1 -1
- package/dist/agent-runtime/src/edit-command.d.ts +2 -0
- package/dist/agent-runtime/src/edit-command.js +41 -20
- package/dist/agent-runtime/src/edit-command.js.map +1 -1
- package/dist/agent-runtime/src/generated/runconfig-contract.cjs +8 -0
- package/dist/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
- package/dist/agent-runtime/src/generated/runconfig-contract.d.ts +9 -0
- package/dist/agent-runtime/src/generated/runconfig-contract.js +8 -0
- package/dist/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
- package/dist/agent-runtime/src/history-store.cjs +426 -0
- package/dist/agent-runtime/src/history-store.cjs.map +1 -0
- package/dist/agent-runtime/src/history-store.d.ts +282 -0
- package/dist/agent-runtime/src/history-store.js +426 -0
- package/dist/agent-runtime/src/history-store.js.map +1 -0
- package/dist/agent-runtime/src/inbound-channel.cjs +96 -0
- package/dist/agent-runtime/src/inbound-channel.cjs.map +1 -0
- package/dist/agent-runtime/src/inbound-channel.d.ts +75 -0
- package/dist/agent-runtime/src/inbound-channel.js +96 -0
- package/dist/agent-runtime/src/inbound-channel.js.map +1 -0
- package/dist/agent-runtime/src/index.d.ts +6 -5
- package/dist/agent-runtime/src/interrupts.cjs +45 -3
- package/dist/agent-runtime/src/interrupts.cjs.map +1 -1
- package/dist/agent-runtime/src/interrupts.d.ts +51 -4
- package/dist/agent-runtime/src/interrupts.js +46 -4
- package/dist/agent-runtime/src/interrupts.js.map +1 -1
- package/dist/agent-runtime/src/message-window.cjs +43 -5
- package/dist/agent-runtime/src/message-window.cjs.map +1 -1
- package/dist/agent-runtime/src/message-window.d.ts +26 -2
- package/dist/agent-runtime/src/message-window.js +44 -6
- package/dist/agent-runtime/src/message-window.js.map +1 -1
- package/dist/agent-runtime/src/offline-status.cjs.map +1 -1
- package/dist/agent-runtime/src/offline-status.d.ts +110 -4
- package/dist/agent-runtime/src/offline-status.js.map +1 -1
- package/dist/agent-runtime/src/runtime.d.ts +1 -0
- package/dist/agent-runtime/src/thread-handoff-flow-machine.d.ts +8 -8
- package/dist/agent-runtime/src/tool-metadata.cjs +16 -0
- package/dist/agent-runtime/src/tool-metadata.cjs.map +1 -1
- package/dist/agent-runtime/src/tool-metadata.js +16 -0
- package/dist/agent-runtime/src/tool-metadata.js.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-thread.cjs +8 -16
- package/dist/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-thread.d.ts +1 -9
- package/dist/agent-runtime/src/use-deep-agent-thread.js +9 -17
- package/dist/agent-runtime/src/use-deep-agent-thread.js.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-window-sync.cjs +86 -79
- package/dist/agent-runtime/src/use-deep-agent-window-sync.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-window-sync.d.ts +2 -27
- package/dist/agent-runtime/src/use-deep-agent-window-sync.js +89 -82
- package/dist/agent-runtime/src/use-deep-agent-window-sync.js.map +1 -1
- package/dist/auth/AthenaSSOProvider.cjs +54 -12
- package/dist/auth/AthenaSSOProvider.cjs.map +1 -1
- package/dist/auth/AthenaSSOProvider.d.ts +23 -2
- package/dist/auth/AthenaSSOProvider.js +54 -12
- package/dist/auth/AthenaSSOProvider.js.map +1 -1
- package/dist/auth/index.cjs +2 -0
- package/dist/auth/index.cjs.map +1 -1
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.js +2 -0
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/sign-back-in.cjs +141 -0
- package/dist/auth/sign-back-in.cjs.map +1 -0
- package/dist/auth/sign-back-in.d.ts +117 -0
- package/dist/auth/sign-back-in.js +141 -0
- package/dist/auth/sign-back-in.js.map +1 -0
- package/dist/chat/AthenaChat.cjs +7 -2
- package/dist/chat/AthenaChat.cjs.map +1 -1
- package/dist/chat/AthenaChat.js +7 -2
- package/dist/chat/AthenaChat.js.map +1 -1
- package/dist/chat/StatewireApprovalCard.cjs +6 -2
- package/dist/chat/StatewireApprovalCard.cjs.map +1 -1
- package/dist/chat/StatewireApprovalCard.d.ts +8 -1
- package/dist/chat/StatewireApprovalCard.js +7 -3
- package/dist/chat/StatewireApprovalCard.js.map +1 -1
- package/dist/chat/super-grouping/CollapsibleGroup.cjs +1 -1
- package/dist/chat/super-grouping/CollapsibleGroup.cjs.map +1 -1
- package/dist/chat/super-grouping/CollapsibleGroup.d.ts +6 -5
- package/dist/chat/super-grouping/CollapsibleGroup.js +1 -1
- package/dist/chat/super-grouping/CollapsibleGroup.js.map +1 -1
- package/dist/chat/super-grouping/earlier-steps-button.cjs +5 -6
- package/dist/chat/super-grouping/earlier-steps-button.cjs.map +1 -1
- package/dist/chat/super-grouping/earlier-steps-button.d.ts +6 -6
- package/dist/chat/super-grouping/earlier-steps-button.js +5 -6
- package/dist/chat/super-grouping/earlier-steps-button.js.map +1 -1
- package/dist/chat/super-grouping/toolkit-map.cjs +1 -0
- package/dist/chat/super-grouping/toolkit-map.cjs.map +1 -1
- package/dist/chat/super-grouping/toolkit-map.js +1 -0
- package/dist/chat/super-grouping/toolkit-map.js.map +1 -1
- package/dist/chat/super-grouping/use-turn-steps.cjs +3 -3
- package/dist/chat/super-grouping/use-turn-steps.js +1 -1
- package/dist/chat-ui/index.cjs +4 -0
- package/dist/chat-ui/index.cjs.map +1 -1
- package/dist/chat-ui/index.d.ts +1 -0
- package/dist/chat-ui/index.js +5 -1
- package/dist/chat-ui/index.js.map +1 -1
- package/dist/chat-ui/messages/inbound-channel-message.cjs +219 -0
- package/dist/chat-ui/messages/inbound-channel-message.cjs.map +1 -0
- package/dist/chat-ui/messages/inbound-channel-message.d.ts +60 -0
- package/dist/chat-ui/messages/inbound-channel-message.js +219 -0
- package/dist/chat-ui/messages/inbound-channel-message.js.map +1 -0
- package/dist/chat-ui/messages/inbound-channel-reader.cjs +184 -0
- package/dist/chat-ui/messages/inbound-channel-reader.cjs.map +1 -0
- package/dist/chat-ui/messages/inbound-channel-reader.d.ts +65 -0
- package/dist/chat-ui/messages/inbound-channel-reader.js +184 -0
- package/dist/chat-ui/messages/inbound-channel-reader.js.map +1 -0
- package/dist/chat-ui/messages/message-components.cjs +18 -14
- package/dist/chat-ui/messages/message-components.cjs.map +1 -1
- package/dist/chat-ui/messages/message-components.d.ts +7 -0
- package/dist/chat-ui/messages/message-components.js +19 -15
- package/dist/chat-ui/messages/message-components.js.map +1 -1
- package/dist/chat-ui/thread/statewire-history-edge.cjs +0 -4
- package/dist/chat-ui/thread/statewire-history-edge.cjs.map +1 -1
- package/dist/chat-ui/thread/statewire-history-edge.d.ts +5 -7
- package/dist/chat-ui/thread/statewire-history-edge.js +1 -5
- package/dist/chat-ui/thread/statewire-history-edge.js.map +1 -1
- package/dist/composer/sign-back-in-draft.cjs +62 -0
- package/dist/composer/sign-back-in-draft.cjs.map +1 -0
- package/dist/composer/sign-back-in-draft.d.ts +34 -0
- package/dist/composer/sign-back-in-draft.js +62 -0
- package/dist/composer/sign-back-in-draft.js.map +1 -0
- package/dist/diagnostics/athena-diagnostics.cjs.map +1 -1
- package/dist/diagnostics/athena-diagnostics.d.ts +6 -1
- package/dist/diagnostics/athena-diagnostics.js.map +1 -1
- package/dist/index.cjs +8 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/provider/AthenaProvider.cjs +60 -14
- package/dist/provider/AthenaProvider.cjs.map +1 -1
- package/dist/provider/AthenaProvider.js +60 -14
- package/dist/provider/AthenaProvider.js.map +1 -1
- package/dist/provider/statewire-window-context.cjs.map +1 -1
- package/dist/provider/statewire-window-context.d.ts +8 -8
- package/dist/provider/statewire-window-context.js.map +1 -1
- package/dist/react/package.json.cjs +1 -1
- package/dist/react/package.json.js +1 -1
- package/dist/runtime/auth.cjs +11 -0
- package/dist/runtime/auth.cjs.map +1 -1
- package/dist/runtime/auth.d.ts +18 -1
- package/dist/runtime/auth.js +11 -0
- package/dist/runtime/auth.js.map +1 -1
- package/dist/runtime/useAthenaStatewireRuntime.cjs +0 -2
- package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
- package/dist/runtime/useAthenaStatewireRuntime.d.ts +5 -5
- package/dist/runtime/useAthenaStatewireRuntime.js +0 -2
- package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/dist/agent-runtime/src/history-pages.cjs +0 -279
- package/dist/agent-runtime/src/history-pages.cjs.map +0 -1
- package/dist/agent-runtime/src/history-pages.d.ts +0 -252
- package/dist/agent-runtime/src/history-pages.js +0 -279
- package/dist/agent-runtime/src/history-pages.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-deep-agent-window-sync.cjs","sources":["../../../../agent-runtime/src/use-deep-agent-window-sync.ts"],"sourcesContent":["import type { StatewireThread } from '@assistant-ui/react-statewire';\nimport { useAuiState } from '@assistant-ui/store';\nimport { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';\nimport {\n DEEP_AGENT_HISTORY_PAGE_PROTOCOL_VERSION,\n DEEP_AGENT_INTEREST_PROTOCOL,\n DEEP_AGENT_MAX_MESSAGE_WINDOW,\n DEEP_AGENT_OVERSIZED_INTEREST_CODE,\n} from './generated/runconfig-contract';\nimport {\n DEEP_AGENT_HISTORY_PAGE_TURNS,\n type DeepAgentHistorySnapshot,\n type DeepAgentHistoryStore,\n} from './history-pages';\nimport {\n buildToolOutputCommand,\n type DeepAgentInterestRequest,\n type DeepAgentMessageWindow,\n messageWindowCarries,\n pageInterestRequests,\n readDeepAgentMessageWindow,\n readToolOutputResult,\n readTruncatedToolOutputArtifact,\n restatedInterestRequests,\n} from './message-window';\nimport { readDeepAgentProtocol } from './protocol';\nimport { hasStatewireThreadExtras } from './thread-extras';\nimport type { DeepAgentToolOutputStore } from './tool-outputs';\n\n/**\n * Pages of older history chained per approach to the top. A renderer lowers\n * its near-top level once prepended content has pushed the first message out\n * of its band; this bounds the case where it cannot (no viewport to scroll,\n * a list too short to overflow) so a 2,000-message thread never streams whole.\n */\nexport const DEEP_AGENT_MAX_CHAINED_HISTORY_LOADS = 3;\n\n/**\n * Pages of older history that add no converted message — every message on\n * them folds into the first loaded turn, such as one agent run's hundreds of\n * tool steps — loaded on top of a request (or an approach's chain) before it\n * stops. Such a page changes nothing the user can see, so it neither answers\n * an ask nor counts against the per-approach chain.\n *\n * A page loaded while the oldest loaded message is a reply lands inside that\n * reply's turn, so it asks for the host's largest window\n * (`DEEP_AGENT_MAX_MESSAGE_WINDOW`) instead of the thread's: a run of 373\n * tool calls is about 750 messages, nineteen round trips at the default\n * window and four at the largest, and the turn shows nothing new until its\n * prompt does. A page above a prompt keeps the thread's window.\n */\nexport const DEEP_AGENT_MAX_UNSEEN_HISTORY_LOADS = 25;\n\n/** The converted thread messages the tool-output half scans (web and native `ThreadMessage` both satisfy it). */\nexport interface DeepAgentWindowSyncMessage {\n readonly id: string;\n /** The converted role; lets the opening fill tell a turn's prompt from its reply. */\n readonly role?: string;\n readonly content: readonly { readonly type: string; readonly artifact?: unknown }[];\n}\n\n/** One page interest round trip, for the host's telemetry. */\nexport interface DeepAgentHistoryLoadEvent {\n /** The page's ordinal (`1` extends the head). */\n page: number;\n request: DeepAgentInterestRequest;\n durationMs: number;\n}\n\n/** One `history/page` round trip, for the host's telemetry. */\nexport interface DeepAgentHistoryPageEvent {\n /** The message the page was asked before. */\n before: string;\n /** Turns asked for, and answered. */\n turns: number;\n answered: number;\n durationMs: number;\n}\n\nexport interface UseDeepAgentWindowSyncOptions {\n /**\n * The converted thread messages — read by the host through its platform\n * `useAuiState((s) => s.thread.messages)`, so this hook imports neither\n * `@assistant-ui/react` nor `@assistant-ui/react-native`.\n */\n messages: readonly DeepAgentWindowSyncMessage[];\n /** Messages per page; the thread's window size by default. */\n pageSize?: number;\n /**\n * Full tool outputs fetched back for cut tool messages; the same store the\n * thread converts with (`useDeepAgentThread({ toolOutputs })`). Omitted, the\n * tool-output half is inert (a surface that never shows a cut output whole).\n */\n toolOutputs?: DeepAgentToolOutputStore | undefined;\n /**\n * The renderer's report that the top of the LOADED history is near — a\n * level, not an edge: while it holds and older messages exist, pages load\n * one after another (bounded by `maxChainedLoads` per approach). Omitted for\n * hosts with only a manual affordance (`loadOlder`).\n */\n nearTop?: boolean;\n /** Bumped on every rise of `nearTop` (and every explicit request), so the chain bound is per approach. */\n nearTopEpoch?: number;\n /**\n * Whether a message's content is mounted right now, so lazy fetches (cut\n * tool outputs) target what the user can see rather than the whole loaded\n * history. Omitted: every message counts as mounted (the flat renderers).\n */\n isMessageMounted?: ((messageId: string) => boolean) | undefined;\n /**\n * Cut tool outputs this mount reads at once; the rest wait for one to\n * settle. One mounted message can hold a whole agent run — a hundred tool\n * steps — and the host rate-limits a client's frames, so a reader that sends\n * them all together gets refusals back for most of them. Omitted: every\n * mounted output is asked for together (renderers whose mounted set is\n * already small).\n */\n maxConcurrentToolOutputs?: number;\n maxChainedLoads?: number;\n /** Pages adding no converted message loaded per request before it stops; see {@link DEEP_AGENT_MAX_UNSEEN_HISTORY_LOADS}. */\n maxUnseenLoads?: number;\n /** A page interest resolved (telemetry). */\n onHistoryLoad?: ((event: DeepAgentHistoryLoadEvent) => void) | undefined;\n /**\n * Older turns paged by command (`history/page`, protocol 3) into this store:\n * the same one the thread joins in front of its live window\n * (`useDeepAgentThread({ historyStore })`). Used only against a host that\n * advertises `DEEP_AGENT_HISTORY_PAGE_PROTOCOL_VERSION`; there every older\n * page (the button, the near-top chain, the opening fill) is a `history/page`\n * of whole turns and no interest page is stated, so the attach's view stays\n * the head however far back the reader goes. Omitted, or an older host:\n * interest pages, as before.\n */\n historyPages?: DeepAgentHistoryStore | undefined;\n /** Turns one history page asks for. */\n historyPageTurns?: number;\n /** A history page resolved (telemetry). */\n onHistoryPage?: ((event: DeepAgentHistoryPageEvent) => void) | undefined;\n /** A read failed; the sync itself recovers (the pending marks are released). */\n onError?:\n | ((error: unknown, command: 'athena/interest' | 'history/page' | 'history/tool_output') => void)\n | undefined;\n now?: () => number;\n}\n\nexport interface DeepAgentWindowSyncState {\n /** The joined window, or `null` while the head interest has not resolved (both halves are inert). */\n window: DeepAgentMessageWindow | null;\n /** Whether the host holds messages older than the loaded window. */\n hasOlder: boolean;\n /**\n * Whether the next page can be asked for: older messages exist and the\n * view has room for them. `hasOlder && !canLoadOlder` is the depth limit —\n * an edge row says so instead of offering a dead button. The host bounds\n * one attach's view twice: `MAX_INTERESTS` requests, and an interest\n * document that lists every loaded message within a byte budget (about a\n * thousand messages). The second is found when the host refuses a page as\n * `oversized-interest` ({@link isOversizedInterestRejection}).\n */\n canLoadOlder: boolean;\n /** A page of older history is in flight. */\n loading: boolean;\n /** Ask for the next page of older history now (an edge row's button, a keypress). A no-op before the head resolved, at the beginning, or once `canLoadOlder` is false. */\n loadOlder: () => void;\n}\n\n/**\n * Whether an `athena/interest` `set` came back refused because the windows it\n * states resolve past what one attach's interest document carries: the view\n * is as deep as this connection can load, and asking again only gets the same\n * refusal.\n */\nexport function isOversizedInterestRejection(error: unknown): boolean {\n const failure = (error as { failure?: { fate?: unknown; code?: unknown } } | null | undefined)\n ?.failure;\n return failure?.fate === 'rejected' && failure.code === DEEP_AGENT_OVERSIZED_INTEREST_CODE;\n}\n\nconst everyMessageMounted = (): boolean => true;\nconst defaultNow = (): number => Date.now();\nconst noopSubscribe = () => () => {};\n\n/** The statewire extras of the nearest aui thread; throws on a non-statewire thread like the library's own hooks. */\nconst useStatewireExtras = (): StatewireThread.Extras =>\n useAuiState((s) => {\n if (!hasStatewireThreadExtras(s.thread.extras)) {\n throw new Error('useDeepAgentWindowSync requires a statewire thread');\n }\n return s.thread.extras as StatewireThread.Extras;\n });\n\n/** The joined interest window of the nearest statewire thread. */\nexport function useDeepAgentMessageWindow(): DeepAgentMessageWindow | null {\n const documents = useStatewireExtras().documents;\n const mounted = useSyncExternalStore(\n documents?.subscribe ?? noopSubscribe,\n () => documents?.list(),\n () => documents?.list()\n );\n return useMemo(() => readDeepAgentMessageWindow(mounted), [mounted]);\n}\n\n/**\n * The client half of the interest window, shared by every surface — mounted\n * once per runtime, inside its aui provider.\n *\n * - **Older history.** While the host renderer reports the top of the loaded\n * history near (`nearTop`) and the window says older messages exist, this\n * re-states the interests with one more page (anchored at the window's\n * first message) — the host mounts its documents for this client alone —\n * chaining at most `maxChainedLoads` pages per approach; `loadOlder` asks\n * for one page on demand (an edge row's button). Never two loads in flight.\n * A re-attach's hello carries the view the client declares on the attach\n * (`useDeepAgentThread`), every page in it however it was loaded (this\n * hook, a handover's or a search's reveal, an edit's parent). A hello that\n * does not carry the view the last connected session held — a host that\n * reads no declaration and has no memo of the client id — gets it stated\n * again ({@link restatedInterestRequests}).\n * - **Cut tool outputs.** Tool cards whose output the wire carried cut\n * (`artifact._athena_content_truncated`) get it fetched whole through\n * `history/tool_output` once their message is mounted, at most\n * `maxConcurrentToolOutputs` at a time; the converter puts it back\n * (`toolOutputs`), so the card re-renders complete. An output the host\n * replaced since (the marker's `chars` changed) is fetched again.\n */\n/**\n * Whether an older page put a new converted message ahead of the thread's\n * first one. Older history only ever merges into or lands before the first\n * converted message, so the second one is a stable landmark: it moved down iff\n * the page showed something. A new tail message does not move it. Without a\n * second message (or once it is gone) the converted count decides.\n */\nfunction pageShowedEarlierMessage(\n from: { count: number; secondId: string | undefined },\n messages: readonly DeepAgentWindowSyncMessage[]\n): boolean {\n if (from.secondId !== undefined) {\n const index = messages.findIndex((message) => message.id === from.secondId);\n if (index !== -1) return index > 1;\n }\n return messages.length > from.count;\n}\n\n/** Whether a converted message is a turn's reply rather than its prompt (unknown without a role). */\nfunction isReply(message: DeepAgentWindowSyncMessage | undefined): boolean {\n return message?.role !== undefined && message.role !== 'user';\n}\n\n/**\n * Whether the loaded thread still opens without context: it should open on a\n * prompt and hold at least one earlier turn, so the newest turn shows with the\n * one before it (a turn is a prompt followed by its reply). Queued and live\n * prompts land at the tail with no reply yet, so they never count; prompts\n * alone need nothing. Without roles, a lone converted message stands in for it.\n */\nfunction opensMidTurn(messages: readonly DeepAgentWindowSyncMessage[]): boolean {\n const first = messages[0];\n if (first === undefined) return false;\n if (messages.every((message) => message.role === undefined)) return messages.length < 2;\n if (first.role !== 'user') return true;\n if (messages.every((message) => message.role === 'user')) return false;\n let turns = 0;\n for (let index = 1; index < messages.length; index += 1) {\n if (messages[index - 1]!.role === 'user' && messages[index]!.role !== 'user') turns += 1;\n }\n return turns < 2;\n}\n\nexport function useDeepAgentWindowSync({\n messages,\n pageSize,\n toolOutputs,\n nearTop = false,\n nearTopEpoch = 0,\n isMessageMounted = everyMessageMounted,\n maxConcurrentToolOutputs = Number.POSITIVE_INFINITY,\n maxChainedLoads = DEEP_AGENT_MAX_CHAINED_HISTORY_LOADS,\n maxUnseenLoads = DEEP_AGENT_MAX_UNSEEN_HISTORY_LOADS,\n onHistoryLoad,\n historyPages,\n historyPageTurns = DEEP_AGENT_HISTORY_PAGE_TURNS,\n onHistoryPage,\n onError,\n now = defaultNow,\n}: UseDeepAgentWindowSyncOptions): DeepAgentWindowSyncState {\n const { sendCommand, invoke, connection } = useStatewireExtras();\n const window = useDeepAgentMessageWindow();\n const hostVersion = useAuiState((s) => {\n const extras = s.thread.extras as Partial<StatewireThread.Extras> | undefined;\n return readDeepAgentProtocol(extras?.state)?.version ?? 0;\n });\n // Older history comes by command when the surface keeps a store for it and\n // the host answers it; the view then stays the head.\n const pagesByCommand =\n historyPages !== undefined && hostVersion >= DEEP_AGENT_HISTORY_PAGE_PROTOCOL_VERSION;\n const historySnapshot = useSyncExternalStore(\n historyPages?.subscribe ?? noopSubscribe,\n () => historyPages?.getSnapshot() ?? null,\n () => historyPages?.getSnapshot() ?? null\n );\n const liveIds = useMemo(() => new Set(window?.chain.map((entry) => entry.id) ?? []), [window]);\n // The pages that still meet the live window; a detached store is cleared below.\n const history: DeepAgentHistorySnapshot | null =\n historySnapshot !== null &&\n window !== null &&\n historyPages !== undefined &&\n !historyPages.isDetached({ threadId: window.threadId, liveIds })\n ? historySnapshot\n : null;\n const onHistoryPageRef = useRef(onHistoryPage);\n onHistoryPageRef.current = onHistoryPage;\n const [loading, setLoading] = useState(false);\n // The view the host refused a page over as deeper than one attach holds\n // (`oversized-interest`): its conversation and how many messages it covered.\n // A view at least that large gets the same refusal (a run's appends only\n // grow it); one that shrank — an edit rewound the transcript, a re-attach\n // came back smaller — may fit a page again.\n const [spentDepth, setSpentDepth] = useState<{ threadId: string | undefined; loaded: number } | null>(\n null\n );\n const depthSpent =\n spentDepth !== null &&\n window !== null &&\n spentDepth.threadId === window.threadId &&\n window.chain.length >= spentDepth.loaded;\n const [requests, setRequests] = useState(0);\n const servedRequestsRef = useRef(0);\n const inflightRef = useRef(false);\n const chainRef = useRef({ epoch: 0, loads: 0, unseen: 0, requested: false });\n // Pages loaded to show the opening turn's prompt; `null` once it shows, the\n // user took over, or a page failed — never re-armed for this mount.\n const openingFillRef = useRef<number | null>(0);\n // The converted thread when the in-flight page was stated; `null` once its\n // settle was judged (or it failed).\n const pageFromRef = useRef<{ count: number; secondId: string | undefined } | null>(null);\n const aliveRef = useRef(true);\n // The window the last connected session held, whoever paged it in, and the\n // session whose hello it was last checked against (a hello resets the\n // documents to what the host seeded).\n const heldRef = useRef<DeepAgentMessageWindow | null>(null);\n const restatedConnectionRef = useRef<unknown>(null);\n // Outputs already asked for and answered by this mount — fetched, refused,\n // or failed — by the `chars` they were asked for. The converter re-runs on\n // every wire change, and the store is a bounded LRU: without this memory a\n // refused read would leave on every pass, and once a transcript holds more\n // cut outputs than the store retains, each fetch would evict a still-loaded\n // output and the next pass would fetch it again, forever. An evicted output\n // renders its cut text (the REST display limit) rather than re-entering the\n // loop; a marker whose `chars` moved (the host replaced the output) is asked\n // for again.\n const answeredRef = useRef(new Map<string, number>());\n // Reads this mount has in flight, and whether a pass left outputs waiting\n // for one to settle (`maxConcurrentToolOutputs`): only then does a settle\n // re-run the pass, so an unbounded mount renders no more than before.\n const toolOutputsInFlightRef = useRef(0);\n const toolOutputsWaitingRef = useRef(false);\n const [toolOutputSettles, setToolOutputSettles] = useState(0);\n const onHistoryLoadRef = useRef(onHistoryLoad);\n onHistoryLoadRef.current = onHistoryLoad;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const nowRef = useRef(now);\n nowRef.current = now;\n useEffect(() => {\n aliveRef.current = true;\n return () => {\n aliveRef.current = false;\n };\n }, []);\n\n // Pages that no longer meet the live window (another conversation, or an\n // edit rewound past their anchor) describe another transcript: drop them,\n // and the edge offers older history again from the window's first message.\n useEffect(() => {\n if (historyPages === undefined || historySnapshot === null || window === null) return;\n if (window.chain.length === 0) return;\n if (historyPages.isDetached({ threadId: window.threadId, liveIds })) historyPages.clear();\n }, [historyPages, historySnapshot, window, liveIds]);\n\n useEffect(() => {\n if (connection.status !== 'connected' || window === null) return;\n if (restatedConnectionRef.current === connection) {\n heldRef.current = window;\n return;\n }\n // Decided once per connected session, on the hello's interest document.\n restatedConnectionRef.current = connection;\n const held = heldRef.current;\n heldRef.current = window;\n // A page still in flight was stated over the held window: it restates it.\n if (held === null || inflightRef.current || messageWindowCarries({ hello: window, held })) return;\n // Another conversation's hello (the runtime switched threads under this mount).\n if (held.threadId !== undefined && window.threadId !== undefined && held.threadId !== window.threadId) {\n return;\n }\n // Held like a page, so no page is stated over it while it is in flight.\n inflightRef.current = true;\n setLoading(true);\n invoke(DEEP_AGENT_INTEREST_PROTOCOL, 'set', [restatedInterestRequests({ held, hello: window })])\n .catch((error: unknown) => {\n onErrorRef.current?.(error, 'athena/interest');\n })\n .finally(() => {\n inflightRef.current = false;\n if (aliveRef.current) setLoading(false);\n });\n }, [connection, invoke, window]);\n\n useEffect(() => {\n if (window === null || inflightRef.current) return;\n // Older turns by command when this surface keeps a store and the host\n // answers it (whole turns before the oldest message held, outside the\n // view); interest pages otherwise. The asks are the same either way.\n const store = pagesByCommand ? historyPages : undefined;\n if (depthSpent && store === undefined) {\n // An ask now would get the same refusal: answer it here, so it never\n // reaches another conversation this mount switches to.\n servedRequestsRef.current = requests;\n pageFromRef.current = null;\n return;\n }\n const from = pageFromRef.current;\n pageFromRef.current = null;\n // A page by command always shows a turn's prompt (it never sets `from`).\n const lastPageUnseen =\n from !== null && from.count > 0 && !pageShowedEarlierMessage(from, messages);\n const pageRequests = store === undefined ? pageInterestRequests(window, pageSize) : null;\n if (store === undefined ? pageRequests === null : !(history?.more ?? window.hasOlder)) return;\n const requested = requests !== servedRequestsRef.current;\n const chain = chainRef.current;\n let fillPage = false;\n if (\n openingFillRef.current !== null &&\n (requested || nearTop || (messages.length > 0 && !opensMidTurn(messages)))\n ) {\n openingFillRef.current = null;\n }\n if (requested) {\n // An explicit ask re-arms the chain for this approach.\n servedRequestsRef.current = requests;\n chainRef.current = { epoch: nearTopEpoch, loads: 1, unseen: 0, requested: true };\n } else if (lastPageUnseen && (chain.requested || (nearTop && chain.epoch === nearTopEpoch))) {\n // The page landed inside the first loaded turn: keep going until one shows.\n if (chain.unseen >= maxUnseenLoads) return;\n chain.unseen += 1;\n } else if (openingFillRef.current !== null && opensMidTurn(messages)) {\n if (openingFillRef.current >= maxUnseenLoads) return;\n openingFillRef.current += 1;\n fillPage = true;\n } else {\n if (!nearTop) return;\n if (chain.epoch !== nearTopEpoch) {\n chainRef.current = { epoch: nearTopEpoch, loads: 0, unseen: 0, requested: false };\n }\n if (chainRef.current.loads >= maxChainedLoads) return;\n chainRef.current.loads += 1;\n }\n const startedAt = nowRef.current();\n const durationMs = () => Math.max(0, Math.round(nowRef.current() - startedAt));\n const settle = () => {\n inflightRef.current = false;\n if (aliveRef.current) setLoading(false);\n };\n if (store !== undefined) {\n const before = history?.turns[0]?.id ?? window.chain[0]?.id;\n if (before === undefined) return;\n inflightRef.current = true;\n setLoading(true);\n store\n .requestOlder({\n send: sendCommand,\n threadId: window.threadId ?? '',\n before,\n beforeIsPrompt:\n history !== null || window.messages.find((message) => message.id === before)?.type === 'human',\n turns: historyPageTurns,\n })\n .then((answered) => {\n onHistoryPageRef.current?.({ before, turns: historyPageTurns, answered, durationMs: durationMs() });\n })\n .catch((error: unknown) => {\n if (fillPage) openingFillRef.current = null;\n onErrorRef.current?.(error, 'history/page');\n })\n .finally(settle);\n return;\n }\n if (pageRequests === null) return;\n // The page continues the oldest loaded turn (see DEEP_AGENT_MAX_UNSEEN_HISTORY_LOADS).\n const insideTurn = lastPageUnseen || isReply(messages[0]);\n const stated =\n (insideTurn && pageInterestRequests(window, DEEP_AGENT_MAX_MESSAGE_WINDOW)) || pageRequests;\n pageFromRef.current = { count: messages.length, secondId: messages[1]?.id };\n const page = window.pages + 1;\n const request = stated[stated.length - 1] as DeepAgentInterestRequest;\n inflightRef.current = true;\n setLoading(true);\n invoke(DEEP_AGENT_INTEREST_PROTOCOL, 'set', [stated])\n .then(() => {\n onHistoryLoadRef.current?.({ page, request, durationMs: durationMs() });\n })\n .catch((error: unknown) => {\n pageFromRef.current = null;\n if (fillPage) openingFillRef.current = null;\n if (isOversizedInterestRejection(error) && aliveRef.current) {\n setSpentDepth({ threadId: window.threadId, loaded: window.chain.length });\n }\n onErrorRef.current?.(error, 'athena/interest');\n })\n .finally(settle);\n // `loading` re-arms the chain once a page settled after its documents moved the window.\n }, [\n nearTop,\n nearTopEpoch,\n requests,\n window,\n loading,\n messages,\n invoke,\n maxChainedLoads,\n maxUnseenLoads,\n pageSize,\n depthSpent,\n pagesByCommand,\n historyPages,\n history,\n historyPageTurns,\n sendCommand,\n ]);\n\n useEffect(() => {\n if (window === null || toolOutputs === undefined) return;\n toolOutputsWaitingRef.current = false;\n for (const message of messages) {\n if (!isMessageMounted(message.id)) continue;\n for (const part of message.content) {\n if (part.type !== 'tool-call') continue;\n const marker = readTruncatedToolOutputArtifact(part.artifact);\n if (marker === null || toolOutputs.isPending(marker.messageId)) continue;\n // Fetched for this very length already; a different length means the\n // host replaced the output under the same id since.\n if (toolOutputs.entry(marker.messageId)?.chars === marker.chars) continue;\n if (answeredRef.current.get(marker.messageId) === marker.chars) continue;\n if (toolOutputsInFlightRef.current >= maxConcurrentToolOutputs) {\n toolOutputsWaitingRef.current = true;\n return;\n }\n const { messageId, chars } = marker;\n toolOutputsInFlightRef.current += 1;\n toolOutputs.markPending(messageId);\n Promise.resolve(sendCommand(buildToolOutputCommand({ messageId })))\n .then((payload) => {\n answeredRef.current.set(messageId, chars);\n const result = readToolOutputResult(payload);\n if (result === null) {\n toolOutputs.clearPending(messageId);\n return;\n }\n toolOutputs.set(result.messageId, { content: result.content, chars });\n })\n .catch((error: unknown) => {\n answeredRef.current.set(messageId, chars);\n toolOutputs.clearPending(messageId);\n onErrorRef.current?.(error, 'history/tool_output');\n })\n .finally(() => {\n toolOutputsInFlightRef.current -= 1;\n if (toolOutputsWaitingRef.current && aliveRef.current) {\n setToolOutputSettles((count) => count + 1);\n }\n });\n }\n }\n }, [\n messages,\n isMessageMounted,\n window,\n sendCommand,\n toolOutputs,\n maxConcurrentToolOutputs,\n toolOutputSettles,\n ]);\n\n const loadOlder = useCallback(() => {\n setRequests((count) => count + 1);\n }, []);\n\n // By command, the host bounds nothing but the transcript's start: older\n // turns exist while the pages say so (the window's own edge before any).\n const hasOlder = pagesByCommand\n ? history !== null\n ? history.more\n : (window?.hasOlder ?? false)\n : (window?.hasOlder ?? false);\n const canLoadOlder = useMemo(\n () =>\n pagesByCommand\n ? window !== null && hasOlder\n : window !== null && !depthSpent && pageInterestRequests(window, pageSize) !== null,\n [pagesByCommand, hasOlder, window, pageSize, depthSpent]\n );\n\n return { window, hasOlder, canLoadOlder, loading, loadOlder };\n}\n"],"names":["DEEP_AGENT_OVERSIZED_INTEREST_CODE","useAuiState","hasStatewireThreadExtras","useSyncExternalStore","useMemo","readDeepAgentMessageWindow","historyPages","DEEP_AGENT_HISTORY_PAGE_TURNS","readDeepAgentProtocol","DEEP_AGENT_HISTORY_PAGE_PROTOCOL_VERSION","useRef","useState","useEffect","messageWindowCarries","DEEP_AGENT_INTEREST_PROTOCOL","restatedInterestRequests","store","pageInterestRequests","_a","DEEP_AGENT_MAX_MESSAGE_WINDOW","readTruncatedToolOutputArtifact","buildToolOutputCommand","readToolOutputResult","useCallback"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-deep-agent-window-sync.cjs","sources":["../../../../agent-runtime/src/use-deep-agent-window-sync.ts"],"sourcesContent":["import type { StatewireThread } from '@assistant-ui/react-statewire';\nimport { useAuiState } from '@assistant-ui/store';\nimport { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';\nimport {\n DEEP_AGENT_INTEREST_PROTOCOL,\n DEEP_AGENT_MAX_MESSAGE_WINDOW,\n DEEP_AGENT_OVERSIZED_INTEREST_CODE,\n} from './generated/runconfig-contract';\nimport {\n buildHistoryPageCommand,\n deepAgentHistoryStore,\n deepAgentHistoryVersion,\n type HistoryPageCommand,\n historyPageAsInterestRequest,\n isHistoryPageUnserved,\n peekDeepAgentHistoryStore,\n readHistoryPageResult,\n subscribeDeepAgentHistory,\n} from './history-store';\nimport {\n buildToolOutputCommand,\n type DeepAgentInterestRequest,\n type DeepAgentMessageWindow,\n messageWindowCarries,\n pageInterestRequests,\n readDeepAgentMessageWindow,\n readToolOutputResult,\n readTruncatedToolOutputArtifact,\n restatedInterestRequests,\n} from './message-window';\nimport { hasStatewireThreadExtras } from './thread-extras';\nimport type { DeepAgentToolOutputStore } from './tool-outputs';\n\n/**\n * Pages of older history chained per approach to the top. A renderer lowers\n * its near-top level once prepended content has pushed the first message out\n * of its band; this bounds the case where it cannot (no viewport to scroll,\n * a list too short to overflow) so a 2,000-message thread never streams whole.\n */\nexport const DEEP_AGENT_MAX_CHAINED_HISTORY_LOADS = 3;\n\n/**\n * Pages of older history that add no converted message — every message on\n * them folds into the first loaded turn, such as one agent run's hundreds of\n * tool steps — loaded on top of a request (or an approach's chain) before it\n * stops. Such a page changes nothing the user can see, so it neither answers\n * an ask nor counts against the per-approach chain.\n *\n * A page loaded while the oldest loaded message is a reply lands inside that\n * reply's turn, so it asks for the host's largest window\n * (`DEEP_AGENT_MAX_MESSAGE_WINDOW`) instead of the thread's: a run of 373\n * tool calls is about 750 messages, nineteen round trips at the default\n * window and four at the largest, and the turn shows nothing new until its\n * prompt does. A page above a prompt keeps the thread's window.\n */\nexport const DEEP_AGENT_MAX_UNSEEN_HISTORY_LOADS = 25;\n\n/** The converted thread messages the tool-output half scans (web and native `ThreadMessage` both satisfy it). */\nexport interface DeepAgentWindowSyncMessage {\n readonly id: string;\n /** The converted role; lets the opening fill tell a turn's prompt from its reply. */\n readonly role?: string;\n readonly content: readonly { readonly type: string; readonly artifact?: unknown }[];\n}\n\n/** One page interest round trip, for the host's telemetry. */\nexport interface DeepAgentHistoryLoadEvent {\n /** The page's ordinal (`1` extends the head). */\n page: number;\n request: DeepAgentInterestRequest;\n durationMs: number;\n}\n\nexport interface UseDeepAgentWindowSyncOptions {\n /**\n * The converted thread messages — read by the host through its platform\n * `useAuiState((s) => s.thread.messages)`, so this hook imports neither\n * `@assistant-ui/react` nor `@assistant-ui/react-native`.\n */\n messages: readonly DeepAgentWindowSyncMessage[];\n /** Messages per page; the thread's window size by default. */\n pageSize?: number;\n /**\n * Full tool outputs fetched back for cut tool messages; the same store the\n * thread converts with (`useDeepAgentThread({ toolOutputs })`). Omitted, the\n * tool-output half is inert (a surface that never shows a cut output whole).\n */\n toolOutputs?: DeepAgentToolOutputStore | undefined;\n /**\n * The renderer's report that the top of the LOADED history is near — a\n * level, not an edge: while it holds and older messages exist, pages load\n * one after another (bounded by `maxChainedLoads` per approach). Omitted for\n * hosts with only a manual affordance (`loadOlder`).\n */\n nearTop?: boolean;\n /** Bumped on every rise of `nearTop` (and every explicit request), so the chain bound is per approach. */\n nearTopEpoch?: number;\n /**\n * Whether a message's content is mounted right now, so lazy fetches (cut\n * tool outputs) target what the user can see rather than the whole loaded\n * history. Omitted: every message counts as mounted (the flat renderers).\n */\n isMessageMounted?: ((messageId: string) => boolean) | undefined;\n /**\n * Cut tool outputs this mount reads at once; the rest wait for one to\n * settle. One mounted message can hold a whole agent run — a hundred tool\n * steps — and the host rate-limits a client's frames, so a reader that sends\n * them all together gets refusals back for most of them. Omitted: every\n * mounted output is asked for together (renderers whose mounted set is\n * already small).\n */\n maxConcurrentToolOutputs?: number;\n maxChainedLoads?: number;\n /** Pages adding no converted message loaded per request before it stops; see {@link DEEP_AGENT_MAX_UNSEEN_HISTORY_LOADS}. */\n maxUnseenLoads?: number;\n /** A page interest resolved (telemetry). */\n onHistoryLoad?: ((event: DeepAgentHistoryLoadEvent) => void) | undefined;\n /** A read failed; the sync itself recovers (the pending marks are released). */\n onError?:\n | ((error: unknown, command: 'athena/interest' | 'history/page' | 'history/tool_output') => void)\n | undefined;\n now?: () => number;\n}\n\nexport interface DeepAgentWindowSyncState {\n /** The joined window, or `null` while the head interest has not resolved (both halves are inert). */\n window: DeepAgentMessageWindow | null;\n /** Whether the host holds messages older than the loaded window. */\n hasOlder: boolean;\n /**\n * Whether the next page can be asked for: older messages exist and the\n * view has room for them. `hasOlder && !canLoadOlder` is the depth limit —\n * an edge row says so instead of offering a dead button. The host bounds\n * one attach's view twice: `MAX_INTERESTS` requests, and an interest\n * document that lists every loaded message within a byte budget (about a\n * thousand messages). The second is found when the host refuses a page as\n * `oversized-interest` ({@link isOversizedInterestRejection}).\n */\n canLoadOlder: boolean;\n /** A page of older history is in flight. */\n loading: boolean;\n /** Ask for the next page of older history now (an edge row's button, a keypress). A no-op before the head resolved, at the beginning, or once `canLoadOlder` is false. */\n loadOlder: () => void;\n}\n\n/**\n * Whether an `athena/interest` `set` came back refused because the windows it\n * states resolve past what one attach's interest document carries: the view\n * is as deep as this connection can load, and asking again only gets the same\n * refusal.\n */\nexport function isOversizedInterestRejection(error: unknown): boolean {\n const failure = (error as { failure?: { fate?: unknown; code?: unknown } } | null | undefined)\n ?.failure;\n return failure?.fate === 'rejected' && failure.code === DEEP_AGENT_OVERSIZED_INTEREST_CODE;\n}\n\nconst everyMessageMounted = (): boolean => true;\nconst defaultNow = (): number => Date.now();\nconst noopSubscribe = () => () => {};\n\n/** The statewire extras of the nearest aui thread; throws on a non-statewire thread like the library's own hooks. */\nconst useStatewireExtras = (): StatewireThread.Extras =>\n useAuiState((s) => {\n if (!hasStatewireThreadExtras(s.thread.extras)) {\n throw new Error('useDeepAgentWindowSync requires a statewire thread');\n }\n return s.thread.extras as StatewireThread.Extras;\n });\n\n/** The joined interest window of the nearest statewire thread, older history from its store included. */\nexport function useDeepAgentMessageWindow(): DeepAgentMessageWindow | null {\n const documents = useStatewireExtras().documents;\n const mounted = useSyncExternalStore(\n documents?.subscribe ?? noopSubscribe,\n () => documents?.list(),\n () => documents?.list()\n );\n const history = useSyncExternalStore(\n subscribeDeepAgentHistory,\n deepAgentHistoryVersion,\n deepAgentHistoryVersion\n );\n // biome-ignore lint/correctness/useExhaustiveDependencies: `history` is the stores' change signal; the read consults the store itself.\n return useMemo(() => readDeepAgentMessageWindow(mounted), [mounted, history]);\n}\n\n/** One page of older history to load: a `history/page` read, or (older hosts) an interest restatement. */\ntype DeepAgentHistoryPageLoad =\n | { kind: 'command'; command: HistoryPageCommand; threadId: string }\n | { kind: 'interest'; requests: DeepAgentInterestRequest[] };\n\nfunction nextHistoryPage(\n window: DeepAgentMessageWindow,\n paged: boolean,\n size: number | undefined\n): DeepAgentHistoryPageLoad | null {\n if (!paged) {\n const requests = pageInterestRequests(window, size);\n return requests === null ? null : { kind: 'interest', requests };\n }\n const before = window.chain[0]?.id;\n if (before === undefined || !window.hasOlder || window.threadId === undefined) return null;\n return {\n kind: 'command',\n // Turns, not messages: a page always reaches a prompt, however long the run.\n command: buildHistoryPageCommand({ before }),\n threadId: window.threadId,\n };\n}\n\n/**\n * The client half of the interest window, shared by every surface — mounted\n * once per runtime, inside its aui provider.\n *\n * - **Older history.** While the host renderer reports the top of the loaded\n * history near (`nearTop`) and the window says older messages exist, this\n * loads one more page below the window's first message, chaining at most\n * `maxChainedLoads` pages per approach; `loadOlder` asks for one page on\n * demand (an edge row's button). Never two loads in flight. On a host that\n * serves `history/page` (`window.historyPaged`) the page is that read, into\n * the conversation's history store, and no interest is stated; a host that\n * refuses it pages by interest for the rest of that connection. On older\n * hosts the page re-states the interests with one more page anchored at\n * the window's first message (the host mounts its documents for this\n * client alone).\n * A re-attach's hello carries the view the client declares on the attach\n * (`useDeepAgentThread`), every page in it however it was loaded (this\n * hook, a handover's or a search's reveal, an edit's parent). A hello that\n * does not carry the view the last connected session held — a host that\n * reads no declaration and has no memo of the client id — gets it stated\n * again ({@link restatedInterestRequests}).\n * - **Cut tool outputs.** Tool cards whose output the wire carried cut\n * (`artifact._athena_content_truncated`) get it fetched whole through\n * `history/tool_output` once their message is mounted, at most\n * `maxConcurrentToolOutputs` at a time; the converter puts it back\n * (`toolOutputs`), so the card re-renders complete. An output the host\n * replaced since (the marker's `chars` changed) is fetched again.\n */\n/**\n * Whether an older page put a new converted message ahead of the thread's\n * first one. Older history only ever merges into or lands before the first\n * converted message, so the second one is a stable landmark: it moved down iff\n * the page showed something. A new tail message does not move it. Without a\n * second message (or once it is gone) the converted count decides.\n */\nfunction pageShowedEarlierMessage(\n from: { count: number; secondId: string | undefined },\n messages: readonly DeepAgentWindowSyncMessage[]\n): boolean {\n if (from.secondId !== undefined) {\n const index = messages.findIndex((message) => message.id === from.secondId);\n if (index !== -1) return index > 1;\n }\n return messages.length > from.count;\n}\n\n/** Whether a converted message is a turn's reply rather than its prompt (unknown without a role). */\nfunction isReply(message: DeepAgentWindowSyncMessage | undefined): boolean {\n return message?.role !== undefined && message.role !== 'user';\n}\n\n/**\n * Whether the loaded thread still opens without context: it should open on a\n * prompt and hold at least one earlier turn, so the newest turn shows with the\n * one before it (a turn is a prompt followed by its reply). Queued and live\n * prompts land at the tail with no reply yet, so they never count; prompts\n * alone need nothing. Without roles, a lone converted message stands in for it.\n */\nfunction opensMidTurn(messages: readonly DeepAgentWindowSyncMessage[]): boolean {\n const first = messages[0];\n if (first === undefined) return false;\n if (messages.every((message) => message.role === undefined)) return messages.length < 2;\n if (first.role !== 'user') return true;\n if (messages.every((message) => message.role === 'user')) return false;\n let turns = 0;\n for (let index = 1; index < messages.length; index += 1) {\n if (messages[index - 1]!.role === 'user' && messages[index]!.role !== 'user') turns += 1;\n }\n return turns < 2;\n}\n\nexport function useDeepAgentWindowSync({\n messages,\n pageSize,\n toolOutputs,\n nearTop = false,\n nearTopEpoch = 0,\n isMessageMounted = everyMessageMounted,\n maxConcurrentToolOutputs = Number.POSITIVE_INFINITY,\n maxChainedLoads = DEEP_AGENT_MAX_CHAINED_HISTORY_LOADS,\n maxUnseenLoads = DEEP_AGENT_MAX_UNSEEN_HISTORY_LOADS,\n onHistoryLoad,\n onError,\n now = defaultNow,\n}: UseDeepAgentWindowSyncOptions): DeepAgentWindowSyncState {\n const { sendCommand, invoke, connection } = useStatewireExtras();\n const window = useDeepAgentMessageWindow();\n const paged = window?.historyPaged === true;\n const pagesRef = useRef(0);\n const [loading, setLoading] = useState(false);\n // The view the host refused a page over as deeper than one attach holds\n // (`oversized-interest`): its conversation and how many messages it covered.\n // A view at least that large gets the same refusal (a run's appends only\n // grow it); one that shrank — an edit rewound the transcript, a re-attach\n // came back smaller — may fit a page again.\n const [spentDepth, setSpentDepth] = useState<{ threadId: string | undefined; loaded: number } | null>(\n null\n );\n const depthSpent =\n !paged &&\n spentDepth !== null &&\n window !== null &&\n spentDepth.threadId === window.threadId &&\n window.chain.length >= spentDepth.loaded;\n const [requests, setRequests] = useState(0);\n const servedRequestsRef = useRef(0);\n const inflightRef = useRef(false);\n const chainRef = useRef({ epoch: 0, loads: 0, unseen: 0, requested: false });\n // Pages loaded to show the opening turn's prompt; `null` once it shows, the\n // user took over, or a page failed — never re-armed for this mount.\n const openingFillRef = useRef<number | null>(0);\n // The converted thread when the in-flight page was stated; `null` once its\n // settle was judged (or it failed).\n const pageFromRef = useRef<{\n count: number;\n secondId: string | undefined;\n /** Whether a pass already waited for the converted thread to show the page. */\n waited: boolean;\n } | null>(null);\n const aliveRef = useRef(true);\n // The window the last connected session held, whoever paged it in, and the\n // session whose hello it was last checked against (a hello resets the\n // documents to what the host seeded).\n const heldRef = useRef<DeepAgentMessageWindow | null>(null);\n const restatedConnectionRef = useRef<unknown>(null);\n // Outputs already asked for and answered by this mount — fetched, refused,\n // or failed — by the `chars` they were asked for. The converter re-runs on\n // every wire change, and the store is a bounded LRU: without this memory a\n // refused read would leave on every pass, and once a transcript holds more\n // cut outputs than the store retains, each fetch would evict a still-loaded\n // output and the next pass would fetch it again, forever. An evicted output\n // renders its cut text (the REST display limit) rather than re-entering the\n // loop; a marker whose `chars` moved (the host replaced the output) is asked\n // for again.\n const answeredRef = useRef(new Map<string, number>());\n // Reads this mount has in flight, and whether a pass left outputs waiting\n // for one to settle (`maxConcurrentToolOutputs`): only then does a settle\n // re-run the pass, so an unbounded mount renders no more than before.\n const toolOutputsInFlightRef = useRef(0);\n const toolOutputsWaitingRef = useRef(false);\n const [toolOutputSettles, setToolOutputSettles] = useState(0);\n const onHistoryLoadRef = useRef(onHistoryLoad);\n onHistoryLoadRef.current = onHistoryLoad;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const nowRef = useRef(now);\n nowRef.current = now;\n useEffect(() => {\n aliveRef.current = true;\n return () => {\n aliveRef.current = false;\n };\n }, []);\n\n // A host that refused `history/page` although it advertises it leaves the\n // conversation's store reading the live view alone (and paging by\n // interest) for that connection only: a later one may land on a host that\n // serves it. The store keeps which connection refused, so a remounted edge\n // (or the edit path's refusal) is judged the same way.\n const storeThreadId = window?.threadId;\n useEffect(() => {\n if (storeThreadId === undefined) return;\n const store = peekDeepAgentHistoryStore(storeThreadId);\n if (store?.unserved && store.unservedBy !== connection) store.markServed();\n }, [connection, storeThreadId]);\n\n useEffect(() => {\n if (connection.status !== 'connected' || window === null) return;\n // Older history lives in the conversation's store, not the view: the\n // hello needs nothing restated to show it.\n if (paged) {\n restatedConnectionRef.current = connection;\n heldRef.current = window;\n return;\n }\n if (restatedConnectionRef.current === connection) {\n heldRef.current = window;\n return;\n }\n // Decided once per connected session, on the hello's interest document.\n restatedConnectionRef.current = connection;\n const held = heldRef.current;\n heldRef.current = window;\n // A page still in flight was stated over the held window: it restates it.\n if (held === null || inflightRef.current || messageWindowCarries({ hello: window, held })) return;\n // Another conversation's hello (the runtime switched threads under this mount).\n if (held.threadId !== undefined && window.threadId !== undefined && held.threadId !== window.threadId) {\n return;\n }\n // Held like a page, so no page is stated over it while it is in flight.\n inflightRef.current = true;\n setLoading(true);\n invoke(DEEP_AGENT_INTEREST_PROTOCOL, 'set', [restatedInterestRequests({ held, hello: window })])\n .catch((error: unknown) => {\n onErrorRef.current?.(error, 'athena/interest');\n })\n .finally(() => {\n inflightRef.current = false;\n if (aliveRef.current) setLoading(false);\n });\n }, [connection, invoke, window, paged]);\n\n useEffect(() => {\n if (window === null || inflightRef.current) return;\n if (depthSpent) {\n // An ask now would get the same refusal: answer it here, so it never\n // reaches another conversation this mount switches to.\n servedRequestsRef.current = requests;\n pageFromRef.current = null;\n return;\n }\n const from = pageFromRef.current;\n const requestedNow = requests !== servedRequestsRef.current;\n if (\n paged &&\n from !== null &&\n !from.waited &&\n !requestedNow &&\n from.count > 0 &&\n !pageShowedEarlierMessage(from, messages)\n ) {\n // A page read by command lands in the history store, which the\n // converter reads on a pass of its own: a thread that shows nothing of\n // it yet may simply not have converted it. Judge it on the next pass.\n from.waited = true;\n return;\n }\n pageFromRef.current = null;\n const lastPageUnseen =\n from !== null && from.count > 0 && !pageShowedEarlierMessage(from, messages);\n const nextPage = nextHistoryPage(window, paged, pageSize);\n if (nextPage === null) return;\n const requested = requests !== servedRequestsRef.current;\n const chain = chainRef.current;\n let fillPage = false;\n if (\n openingFillRef.current !== null &&\n (requested || nearTop || (messages.length > 0 && !opensMidTurn(messages)))\n ) {\n openingFillRef.current = null;\n }\n if (requested) {\n // An explicit ask re-arms the chain for this approach.\n servedRequestsRef.current = requests;\n chainRef.current = { epoch: nearTopEpoch, loads: 1, unseen: 0, requested: true };\n } else if (lastPageUnseen && (chain.requested || (nearTop && chain.epoch === nearTopEpoch))) {\n // The page landed inside the first loaded turn: keep going until one shows.\n if (chain.unseen >= maxUnseenLoads) return;\n chain.unseen += 1;\n } else if (openingFillRef.current !== null && opensMidTurn(messages)) {\n if (openingFillRef.current >= maxUnseenLoads) return;\n openingFillRef.current += 1;\n fillPage = true;\n } else {\n if (!nearTop) return;\n if (chain.epoch !== nearTopEpoch) {\n chainRef.current = { epoch: nearTopEpoch, loads: 0, unseen: 0, requested: false };\n }\n if (chainRef.current.loads >= maxChainedLoads) return;\n chainRef.current.loads += 1;\n }\n // The page continues the oldest loaded turn (see DEEP_AGENT_MAX_UNSEEN_HISTORY_LOADS).\n const insideTurn = lastPageUnseen || isReply(messages[0]);\n const stated =\n (insideTurn && nextHistoryPage(window, paged, DEEP_AGENT_MAX_MESSAGE_WINDOW)) || nextPage;\n pageFromRef.current = {\n count: messages.length,\n secondId: messages[1]?.id,\n waited: false,\n };\n const page = stated.kind === 'command' ? pagesRef.current + 1 : window.pages + 1;\n const request =\n stated.kind === 'command'\n ? historyPageAsInterestRequest(stated.command)\n : (stated.requests[stated.requests.length - 1] as DeepAgentInterestRequest);\n inflightRef.current = true;\n setLoading(true);\n const startedAt = nowRef.current();\n const load =\n stated.kind === 'command'\n ? Promise.resolve(sendCommand(stated.command)).then((payload) => {\n const result = readHistoryPageResult(payload, stated.command.before);\n if (result === null) throw new Error('history/page answered a malformed page');\n pagesRef.current += 1;\n deepAgentHistoryStore(stated.threadId).addPage(result);\n })\n : invoke(DEEP_AGENT_INTEREST_PROTOCOL, 'set', [stated.requests]);\n load\n .then(() => {\n onHistoryLoadRef.current?.({\n page,\n request,\n durationMs: Math.max(0, Math.round(nowRef.current() - startedAt)),\n });\n })\n .catch((error: unknown) => {\n pageFromRef.current = null;\n if (fillPage) openingFillRef.current = null;\n if (stated.kind === 'command') {\n // A host that does not serve the command pages by interest instead.\n if (isHistoryPageUnserved(error)) {\n deepAgentHistoryStore(stated.threadId).markUnserved(connection);\n }\n onErrorRef.current?.(error, 'history/page');\n return;\n }\n if (isOversizedInterestRejection(error) && aliveRef.current) {\n setSpentDepth({ threadId: window.threadId, loaded: window.chain.length });\n }\n onErrorRef.current?.(error, 'athena/interest');\n })\n .finally(() => {\n inflightRef.current = false;\n if (aliveRef.current) setLoading(false);\n });\n // `loading` re-arms the chain once a page settled after its documents moved the window.\n }, [\n nearTop,\n nearTopEpoch,\n requests,\n window,\n loading,\n messages,\n invoke,\n sendCommand,\n connection,\n paged,\n maxChainedLoads,\n maxUnseenLoads,\n pageSize,\n depthSpent,\n ]);\n\n useEffect(() => {\n if (window === null || toolOutputs === undefined) return;\n toolOutputsWaitingRef.current = false;\n for (const message of messages) {\n if (!isMessageMounted(message.id)) continue;\n for (const part of message.content) {\n if (part.type !== 'tool-call') continue;\n const marker = readTruncatedToolOutputArtifact(part.artifact);\n if (marker === null || toolOutputs.isPending(marker.messageId)) continue;\n // Fetched for this very length already; a different length means the\n // host replaced the output under the same id since.\n if (toolOutputs.entry(marker.messageId)?.chars === marker.chars) continue;\n if (answeredRef.current.get(marker.messageId) === marker.chars) continue;\n if (toolOutputsInFlightRef.current >= maxConcurrentToolOutputs) {\n toolOutputsWaitingRef.current = true;\n return;\n }\n const { messageId, chars } = marker;\n toolOutputsInFlightRef.current += 1;\n toolOutputs.markPending(messageId);\n Promise.resolve(sendCommand(buildToolOutputCommand({ messageId })))\n .then((payload) => {\n answeredRef.current.set(messageId, chars);\n const result = readToolOutputResult(payload);\n if (result === null) {\n toolOutputs.clearPending(messageId);\n return;\n }\n toolOutputs.set(result.messageId, { content: result.content, chars });\n })\n .catch((error: unknown) => {\n answeredRef.current.set(messageId, chars);\n toolOutputs.clearPending(messageId);\n onErrorRef.current?.(error, 'history/tool_output');\n })\n .finally(() => {\n toolOutputsInFlightRef.current -= 1;\n if (toolOutputsWaitingRef.current && aliveRef.current) {\n setToolOutputSettles((count) => count + 1);\n }\n });\n }\n }\n }, [\n messages,\n isMessageMounted,\n window,\n sendCommand,\n toolOutputs,\n maxConcurrentToolOutputs,\n toolOutputSettles,\n ]);\n\n const loadOlder = useCallback(() => {\n setRequests((count) => count + 1);\n }, []);\n\n const canLoadOlder = useMemo(\n () =>\n window !== null &&\n !depthSpent &&\n nextHistoryPage(window, paged, pageSize) !== null,\n [window, pageSize, depthSpent, paged]\n );\n\n return { window, hasOlder: window?.hasOlder ?? false, canLoadOlder, loading, loadOlder };\n}\n"],"names":["DEEP_AGENT_OVERSIZED_INTEREST_CODE","useAuiState","hasStatewireThreadExtras","useSyncExternalStore","subscribeDeepAgentHistory","deepAgentHistoryVersion","useMemo","readDeepAgentMessageWindow","pageInterestRequests","buildHistoryPageCommand","useRef","useState","useEffect","store","peekDeepAgentHistoryStore","messageWindowCarries","DEEP_AGENT_INTEREST_PROTOCOL","restatedInterestRequests","DEEP_AGENT_MAX_MESSAGE_WINDOW","historyPageAsInterestRequest","readHistoryPageResult","deepAgentHistoryStore","_a","isHistoryPageUnserved","readTruncatedToolOutputArtifact","buildToolOutputCommand","readToolOutputResult","useCallback"],"mappings":"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"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type DeepAgentHistoryStore } from './history-pages';
|
|
2
1
|
import { type DeepAgentInterestRequest, type DeepAgentMessageWindow } from './message-window';
|
|
3
2
|
import type { DeepAgentToolOutputStore } from './tool-outputs';
|
|
4
3
|
/**
|
|
@@ -40,15 +39,6 @@ export interface DeepAgentHistoryLoadEvent {
|
|
|
40
39
|
request: DeepAgentInterestRequest;
|
|
41
40
|
durationMs: number;
|
|
42
41
|
}
|
|
43
|
-
/** One `history/page` round trip, for the host's telemetry. */
|
|
44
|
-
export interface DeepAgentHistoryPageEvent {
|
|
45
|
-
/** The message the page was asked before. */
|
|
46
|
-
before: string;
|
|
47
|
-
/** Turns asked for, and answered. */
|
|
48
|
-
turns: number;
|
|
49
|
-
answered: number;
|
|
50
|
-
durationMs: number;
|
|
51
|
-
}
|
|
52
42
|
export interface UseDeepAgentWindowSyncOptions {
|
|
53
43
|
/**
|
|
54
44
|
* The converted thread messages — read by the host through its platform
|
|
@@ -93,21 +83,6 @@ export interface UseDeepAgentWindowSyncOptions {
|
|
|
93
83
|
maxUnseenLoads?: number;
|
|
94
84
|
/** A page interest resolved (telemetry). */
|
|
95
85
|
onHistoryLoad?: ((event: DeepAgentHistoryLoadEvent) => void) | undefined;
|
|
96
|
-
/**
|
|
97
|
-
* Older turns paged by command (`history/page`, protocol 3) into this store:
|
|
98
|
-
* the same one the thread joins in front of its live window
|
|
99
|
-
* (`useDeepAgentThread({ historyStore })`). Used only against a host that
|
|
100
|
-
* advertises `DEEP_AGENT_HISTORY_PAGE_PROTOCOL_VERSION`; there every older
|
|
101
|
-
* page (the button, the near-top chain, the opening fill) is a `history/page`
|
|
102
|
-
* of whole turns and no interest page is stated, so the attach's view stays
|
|
103
|
-
* the head however far back the reader goes. Omitted, or an older host:
|
|
104
|
-
* interest pages, as before.
|
|
105
|
-
*/
|
|
106
|
-
historyPages?: DeepAgentHistoryStore | undefined;
|
|
107
|
-
/** Turns one history page asks for. */
|
|
108
|
-
historyPageTurns?: number;
|
|
109
|
-
/** A history page resolved (telemetry). */
|
|
110
|
-
onHistoryPage?: ((event: DeepAgentHistoryPageEvent) => void) | undefined;
|
|
111
86
|
/** A read failed; the sync itself recovers (the pending marks are released). */
|
|
112
87
|
onError?: ((error: unknown, command: 'athena/interest' | 'history/page' | 'history/tool_output') => void) | undefined;
|
|
113
88
|
now?: () => number;
|
|
@@ -139,6 +114,6 @@ export interface DeepAgentWindowSyncState {
|
|
|
139
114
|
* refusal.
|
|
140
115
|
*/
|
|
141
116
|
export declare function isOversizedInterestRejection(error: unknown): boolean;
|
|
142
|
-
/** The joined interest window of the nearest statewire thread. */
|
|
117
|
+
/** The joined interest window of the nearest statewire thread, older history from its store included. */
|
|
143
118
|
export declare function useDeepAgentMessageWindow(): DeepAgentMessageWindow | null;
|
|
144
|
-
export declare function useDeepAgentWindowSync({ messages, pageSize, toolOutputs, nearTop, nearTopEpoch, isMessageMounted, maxConcurrentToolOutputs, maxChainedLoads, maxUnseenLoads, onHistoryLoad,
|
|
119
|
+
export declare function useDeepAgentWindowSync({ messages, pageSize, toolOutputs, nearTop, nearTopEpoch, isMessageMounted, maxConcurrentToolOutputs, maxChainedLoads, maxUnseenLoads, onHistoryLoad, onError, now, }: UseDeepAgentWindowSyncOptions): DeepAgentWindowSyncState;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { useAuiState } from "@assistant-ui/store";
|
|
2
|
-
import {
|
|
3
|
-
import { DEEP_AGENT_INTEREST_PROTOCOL, DEEP_AGENT_OVERSIZED_INTEREST_CODE,
|
|
4
|
-
import {
|
|
5
|
-
import { messageWindowCarries, restatedInterestRequests,
|
|
6
|
-
import { readDeepAgentProtocol } from "./protocol.js";
|
|
2
|
+
import { useRef, useState, useEffect, useCallback, useMemo, useSyncExternalStore } from "react";
|
|
3
|
+
import { DEEP_AGENT_INTEREST_PROTOCOL, DEEP_AGENT_OVERSIZED_INTEREST_CODE, DEEP_AGENT_MAX_MESSAGE_WINDOW } from "./generated/runconfig-contract.js";
|
|
4
|
+
import { peekDeepAgentHistoryStore, historyPageAsInterestRequest, readHistoryPageResult, deepAgentHistoryStore, isHistoryPageUnserved, subscribeDeepAgentHistory, deepAgentHistoryVersion, buildHistoryPageCommand } from "./history-store.js";
|
|
5
|
+
import { messageWindowCarries, restatedInterestRequests, readTruncatedToolOutputArtifact, buildToolOutputCommand, readToolOutputResult, readDeepAgentMessageWindow, pageInterestRequests } from "./message-window.js";
|
|
7
6
|
import { hasStatewireThreadExtras } from "./thread-extras.js";
|
|
8
7
|
const DEEP_AGENT_MAX_CHAINED_HISTORY_LOADS = 3;
|
|
9
8
|
const DEEP_AGENT_MAX_UNSEEN_HISTORY_LOADS = 25;
|
|
@@ -28,7 +27,27 @@ function useDeepAgentMessageWindow() {
|
|
|
28
27
|
() => documents == null ? void 0 : documents.list(),
|
|
29
28
|
() => documents == null ? void 0 : documents.list()
|
|
30
29
|
);
|
|
31
|
-
|
|
30
|
+
const history = useSyncExternalStore(
|
|
31
|
+
subscribeDeepAgentHistory,
|
|
32
|
+
deepAgentHistoryVersion,
|
|
33
|
+
deepAgentHistoryVersion
|
|
34
|
+
);
|
|
35
|
+
return useMemo(() => readDeepAgentMessageWindow(mounted), [mounted, history]);
|
|
36
|
+
}
|
|
37
|
+
function nextHistoryPage(window, paged, size) {
|
|
38
|
+
var _a;
|
|
39
|
+
if (!paged) {
|
|
40
|
+
const requests = pageInterestRequests(window, size);
|
|
41
|
+
return requests === null ? null : { kind: "interest", requests };
|
|
42
|
+
}
|
|
43
|
+
const before = (_a = window.chain[0]) == null ? void 0 : _a.id;
|
|
44
|
+
if (before === void 0 || !window.hasOlder || window.threadId === void 0) return null;
|
|
45
|
+
return {
|
|
46
|
+
kind: "command",
|
|
47
|
+
// Turns, not messages: a page always reaches a prompt, however long the run.
|
|
48
|
+
command: buildHistoryPageCommand({ before }),
|
|
49
|
+
threadId: window.threadId
|
|
50
|
+
};
|
|
32
51
|
}
|
|
33
52
|
function pageShowedEarlierMessage(from, messages) {
|
|
34
53
|
if (from.secondId !== void 0) {
|
|
@@ -63,34 +82,18 @@ function useDeepAgentWindowSync({
|
|
|
63
82
|
maxChainedLoads = DEEP_AGENT_MAX_CHAINED_HISTORY_LOADS,
|
|
64
83
|
maxUnseenLoads = DEEP_AGENT_MAX_UNSEEN_HISTORY_LOADS,
|
|
65
84
|
onHistoryLoad,
|
|
66
|
-
historyPages,
|
|
67
|
-
historyPageTurns = DEEP_AGENT_HISTORY_PAGE_TURNS,
|
|
68
|
-
onHistoryPage,
|
|
69
85
|
onError,
|
|
70
86
|
now = defaultNow
|
|
71
87
|
}) {
|
|
72
88
|
const { sendCommand, invoke, connection } = useStatewireExtras();
|
|
73
89
|
const window = useDeepAgentMessageWindow();
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
const extras = s.thread.extras;
|
|
77
|
-
return ((_a = readDeepAgentProtocol(extras == null ? void 0 : extras.state)) == null ? void 0 : _a.version) ?? 0;
|
|
78
|
-
});
|
|
79
|
-
const pagesByCommand = historyPages !== void 0 && hostVersion >= DEEP_AGENT_HISTORY_PAGE_PROTOCOL_VERSION;
|
|
80
|
-
const historySnapshot = useSyncExternalStore(
|
|
81
|
-
(historyPages == null ? void 0 : historyPages.subscribe) ?? noopSubscribe,
|
|
82
|
-
() => (historyPages == null ? void 0 : historyPages.getSnapshot()) ?? null,
|
|
83
|
-
() => (historyPages == null ? void 0 : historyPages.getSnapshot()) ?? null
|
|
84
|
-
);
|
|
85
|
-
const liveIds = useMemo(() => new Set((window == null ? void 0 : window.chain.map((entry) => entry.id)) ?? []), [window]);
|
|
86
|
-
const history = historySnapshot !== null && window !== null && historyPages !== void 0 && !historyPages.isDetached({ threadId: window.threadId, liveIds }) ? historySnapshot : null;
|
|
87
|
-
const onHistoryPageRef = useRef(onHistoryPage);
|
|
88
|
-
onHistoryPageRef.current = onHistoryPage;
|
|
90
|
+
const paged = (window == null ? void 0 : window.historyPaged) === true;
|
|
91
|
+
const pagesRef = useRef(0);
|
|
89
92
|
const [loading, setLoading] = useState(false);
|
|
90
93
|
const [spentDepth, setSpentDepth] = useState(
|
|
91
94
|
null
|
|
92
95
|
);
|
|
93
|
-
const depthSpent = spentDepth !== null && window !== null && spentDepth.threadId === window.threadId && window.chain.length >= spentDepth.loaded;
|
|
96
|
+
const depthSpent = !paged && spentDepth !== null && window !== null && spentDepth.threadId === window.threadId && window.chain.length >= spentDepth.loaded;
|
|
94
97
|
const [requests, setRequests] = useState(0);
|
|
95
98
|
const servedRequestsRef = useRef(0);
|
|
96
99
|
const inflightRef = useRef(false);
|
|
@@ -116,13 +119,19 @@ function useDeepAgentWindowSync({
|
|
|
116
119
|
aliveRef.current = false;
|
|
117
120
|
};
|
|
118
121
|
}, []);
|
|
122
|
+
const storeThreadId = window == null ? void 0 : window.threadId;
|
|
119
123
|
useEffect(() => {
|
|
120
|
-
if (
|
|
121
|
-
|
|
122
|
-
if (
|
|
123
|
-
}, [
|
|
124
|
+
if (storeThreadId === void 0) return;
|
|
125
|
+
const store = peekDeepAgentHistoryStore(storeThreadId);
|
|
126
|
+
if ((store == null ? void 0 : store.unserved) && store.unservedBy !== connection) store.markServed();
|
|
127
|
+
}, [connection, storeThreadId]);
|
|
124
128
|
useEffect(() => {
|
|
125
129
|
if (connection.status !== "connected" || window === null) return;
|
|
130
|
+
if (paged) {
|
|
131
|
+
restatedConnectionRef.current = connection;
|
|
132
|
+
heldRef.current = window;
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
126
135
|
if (restatedConnectionRef.current === connection) {
|
|
127
136
|
heldRef.current = window;
|
|
128
137
|
return;
|
|
@@ -143,21 +152,25 @@ function useDeepAgentWindowSync({
|
|
|
143
152
|
inflightRef.current = false;
|
|
144
153
|
if (aliveRef.current) setLoading(false);
|
|
145
154
|
});
|
|
146
|
-
}, [connection, invoke, window]);
|
|
155
|
+
}, [connection, invoke, window, paged]);
|
|
147
156
|
useEffect(() => {
|
|
148
|
-
var _a
|
|
157
|
+
var _a;
|
|
149
158
|
if (window === null || inflightRef.current) return;
|
|
150
|
-
|
|
151
|
-
if (depthSpent && store === void 0) {
|
|
159
|
+
if (depthSpent) {
|
|
152
160
|
servedRequestsRef.current = requests;
|
|
153
161
|
pageFromRef.current = null;
|
|
154
162
|
return;
|
|
155
163
|
}
|
|
156
164
|
const from = pageFromRef.current;
|
|
165
|
+
const requestedNow = requests !== servedRequestsRef.current;
|
|
166
|
+
if (paged && from !== null && !from.waited && !requestedNow && from.count > 0 && !pageShowedEarlierMessage(from, messages)) {
|
|
167
|
+
from.waited = true;
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
157
170
|
pageFromRef.current = null;
|
|
158
171
|
const lastPageUnseen = from !== null && from.count > 0 && !pageShowedEarlierMessage(from, messages);
|
|
159
|
-
const
|
|
160
|
-
if (
|
|
172
|
+
const nextPage = nextHistoryPage(window, paged, pageSize);
|
|
173
|
+
if (nextPage === null) return;
|
|
161
174
|
const requested = requests !== servedRequestsRef.current;
|
|
162
175
|
const chain = chainRef.current;
|
|
163
176
|
let fillPage = false;
|
|
@@ -182,53 +195,50 @@ function useDeepAgentWindowSync({
|
|
|
182
195
|
if (chainRef.current.loads >= maxChainedLoads) return;
|
|
183
196
|
chainRef.current.loads += 1;
|
|
184
197
|
}
|
|
185
|
-
const startedAt = nowRef.current();
|
|
186
|
-
const durationMs = () => Math.max(0, Math.round(nowRef.current() - startedAt));
|
|
187
|
-
const settle = () => {
|
|
188
|
-
inflightRef.current = false;
|
|
189
|
-
if (aliveRef.current) setLoading(false);
|
|
190
|
-
};
|
|
191
|
-
if (store !== void 0) {
|
|
192
|
-
const before = ((_a = history == null ? void 0 : history.turns[0]) == null ? void 0 : _a.id) ?? ((_b = window.chain[0]) == null ? void 0 : _b.id);
|
|
193
|
-
if (before === void 0) return;
|
|
194
|
-
inflightRef.current = true;
|
|
195
|
-
setLoading(true);
|
|
196
|
-
store.requestOlder({
|
|
197
|
-
send: sendCommand,
|
|
198
|
-
threadId: window.threadId ?? "",
|
|
199
|
-
before,
|
|
200
|
-
beforeIsPrompt: history !== null || ((_c = window.messages.find((message) => message.id === before)) == null ? void 0 : _c.type) === "human",
|
|
201
|
-
turns: historyPageTurns
|
|
202
|
-
}).then((answered) => {
|
|
203
|
-
var _a2;
|
|
204
|
-
(_a2 = onHistoryPageRef.current) == null ? void 0 : _a2.call(onHistoryPageRef, { before, turns: historyPageTurns, answered, durationMs: durationMs() });
|
|
205
|
-
}).catch((error) => {
|
|
206
|
-
var _a2;
|
|
207
|
-
if (fillPage) openingFillRef.current = null;
|
|
208
|
-
(_a2 = onErrorRef.current) == null ? void 0 : _a2.call(onErrorRef, error, "history/page");
|
|
209
|
-
}).finally(settle);
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
if (pageRequests === null) return;
|
|
213
198
|
const insideTurn = lastPageUnseen || isReply(messages[0]);
|
|
214
|
-
const stated = insideTurn &&
|
|
215
|
-
pageFromRef.current = {
|
|
216
|
-
|
|
217
|
-
|
|
199
|
+
const stated = insideTurn && nextHistoryPage(window, paged, DEEP_AGENT_MAX_MESSAGE_WINDOW) || nextPage;
|
|
200
|
+
pageFromRef.current = {
|
|
201
|
+
count: messages.length,
|
|
202
|
+
secondId: (_a = messages[1]) == null ? void 0 : _a.id,
|
|
203
|
+
waited: false
|
|
204
|
+
};
|
|
205
|
+
const page = stated.kind === "command" ? pagesRef.current + 1 : window.pages + 1;
|
|
206
|
+
const request = stated.kind === "command" ? historyPageAsInterestRequest(stated.command) : stated.requests[stated.requests.length - 1];
|
|
218
207
|
inflightRef.current = true;
|
|
219
208
|
setLoading(true);
|
|
220
|
-
|
|
209
|
+
const startedAt = nowRef.current();
|
|
210
|
+
const load = stated.kind === "command" ? Promise.resolve(sendCommand(stated.command)).then((payload) => {
|
|
211
|
+
const result = readHistoryPageResult(payload, stated.command.before);
|
|
212
|
+
if (result === null) throw new Error("history/page answered a malformed page");
|
|
213
|
+
pagesRef.current += 1;
|
|
214
|
+
deepAgentHistoryStore(stated.threadId).addPage(result);
|
|
215
|
+
}) : invoke(DEEP_AGENT_INTEREST_PROTOCOL, "set", [stated.requests]);
|
|
216
|
+
load.then(() => {
|
|
221
217
|
var _a2;
|
|
222
|
-
(_a2 = onHistoryLoadRef.current) == null ? void 0 : _a2.call(onHistoryLoadRef, {
|
|
218
|
+
(_a2 = onHistoryLoadRef.current) == null ? void 0 : _a2.call(onHistoryLoadRef, {
|
|
219
|
+
page,
|
|
220
|
+
request,
|
|
221
|
+
durationMs: Math.max(0, Math.round(nowRef.current() - startedAt))
|
|
222
|
+
});
|
|
223
223
|
}).catch((error) => {
|
|
224
|
-
var _a2;
|
|
224
|
+
var _a2, _b;
|
|
225
225
|
pageFromRef.current = null;
|
|
226
226
|
if (fillPage) openingFillRef.current = null;
|
|
227
|
+
if (stated.kind === "command") {
|
|
228
|
+
if (isHistoryPageUnserved(error)) {
|
|
229
|
+
deepAgentHistoryStore(stated.threadId).markUnserved(connection);
|
|
230
|
+
}
|
|
231
|
+
(_a2 = onErrorRef.current) == null ? void 0 : _a2.call(onErrorRef, error, "history/page");
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
227
234
|
if (isOversizedInterestRejection(error) && aliveRef.current) {
|
|
228
235
|
setSpentDepth({ threadId: window.threadId, loaded: window.chain.length });
|
|
229
236
|
}
|
|
230
|
-
(
|
|
231
|
-
}).finally(
|
|
237
|
+
(_b = onErrorRef.current) == null ? void 0 : _b.call(onErrorRef, error, "athena/interest");
|
|
238
|
+
}).finally(() => {
|
|
239
|
+
inflightRef.current = false;
|
|
240
|
+
if (aliveRef.current) setLoading(false);
|
|
241
|
+
});
|
|
232
242
|
}, [
|
|
233
243
|
nearTop,
|
|
234
244
|
nearTopEpoch,
|
|
@@ -237,15 +247,13 @@ function useDeepAgentWindowSync({
|
|
|
237
247
|
loading,
|
|
238
248
|
messages,
|
|
239
249
|
invoke,
|
|
250
|
+
sendCommand,
|
|
251
|
+
connection,
|
|
252
|
+
paged,
|
|
240
253
|
maxChainedLoads,
|
|
241
254
|
maxUnseenLoads,
|
|
242
255
|
pageSize,
|
|
243
|
-
depthSpent
|
|
244
|
-
pagesByCommand,
|
|
245
|
-
historyPages,
|
|
246
|
-
history,
|
|
247
|
-
historyPageTurns,
|
|
248
|
-
sendCommand
|
|
256
|
+
depthSpent
|
|
249
257
|
]);
|
|
250
258
|
useEffect(() => {
|
|
251
259
|
var _a;
|
|
@@ -299,12 +307,11 @@ function useDeepAgentWindowSync({
|
|
|
299
307
|
const loadOlder = useCallback(() => {
|
|
300
308
|
setRequests((count) => count + 1);
|
|
301
309
|
}, []);
|
|
302
|
-
const hasOlder = pagesByCommand ? history !== null ? history.more : (window == null ? void 0 : window.hasOlder) ?? false : (window == null ? void 0 : window.hasOlder) ?? false;
|
|
303
310
|
const canLoadOlder = useMemo(
|
|
304
|
-
() =>
|
|
305
|
-
[
|
|
311
|
+
() => window !== null && !depthSpent && nextHistoryPage(window, paged, pageSize) !== null,
|
|
312
|
+
[window, pageSize, depthSpent, paged]
|
|
306
313
|
);
|
|
307
|
-
return { window, hasOlder, canLoadOlder, loading, loadOlder };
|
|
314
|
+
return { window, hasOlder: (window == null ? void 0 : window.hasOlder) ?? false, canLoadOlder, loading, loadOlder };
|
|
308
315
|
}
|
|
309
316
|
export {
|
|
310
317
|
DEEP_AGENT_MAX_CHAINED_HISTORY_LOADS,
|