@copilotkit/core 1.73.3 → 1.75.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/dist/index.cjs +42 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +42 -17
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +42 -17
- package/dist/index.umd.js.map +1 -1
- package/package.json +2 -2
package/dist/index.umd.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.umd.js","names":["Subject","AGUIConnectNotImplementedError","EMPTY","Observable","Socket","NEVER","EMPTY","AbstractAgent","EMPTY","EventType","Notification","isAbortError","EMPTY","HttpAgent","RUNTIME_MODE_SSE","RUNTIME_MODE_INTELLIGENCE","isAbortError","isAbortError","RUNTIME_MODE_SSE","HttpAgent","HttpAgent","isAbortError","Subscription","BehaviorSubject","Subject","asapScheduler","REQUEST_TIMEOUT_MS","MAX_SOCKET_RETRIES","Observable","EMPTY","asapScheduler","ɵcreateMemoryStore","Throttler","Observable","on"],"sources":["../src/utils/connect-replay.ts","../src/utils/phoenix-observable.ts","../src/intelligence-agent.ts","../src/utils/runtime-info-error.ts","../src/core/message-filter.ts","../src/agent.ts","../src/utils/abort-error.ts","../src/utils/runtime-request.ts","../src/utils/single-route-resource-request.ts","../src/core/agent-registry.ts","../src/core/context-store.ts","../src/core/suggestion-engine.ts","../src/core/tool-result-content.ts","../src/core/tool-schema.ts","../src/core/webmcp.ts","../src/core/run-handler.ts","../src/core/state-manager.ts","../src/core/thread-store-registry.ts","../src/utils/micro-redux.ts","../src/memory-errors.ts","../src/memory.ts","../src/core/core.ts","../src/types.ts","../src/utils/markdown.ts","../src/threads.ts","../src/features.ts","../src/interrupt-state.ts","../src/inspector-thread-bridge.ts"],"sourcesContent":["import type {\n AbstractAgent,\n AgentSubscriber,\n BaseEvent,\n RunAgentParameters,\n RunAgentResult,\n} from \"@ag-ui/client\";\nimport {\n AGUIConnectNotImplementedError,\n randomUUID,\n structuredClone_,\n transformChunks,\n} from \"@ag-ui/client\";\nimport type { Observable } from \"rxjs\";\nimport { EMPTY, Subject, defer, lastValueFrom } from \"rxjs\";\nimport { catchError, finalize, takeUntil } from \"rxjs/operators\";\n\n/**\n * Runs an agent's `connect()` stream through the AbstractAgent apply pipeline\n * with the `verifyEvents` step omitted.\n *\n * `verifyEvents` enforces AG-UI's *single run* lifecycle rules: exactly one\n * RUN_STARTED opening the stream, no events after a terminal RUN_FINISHED /\n * RUN_ERROR. Those rules are correct for `/run`, but a `/connect` response is a\n * replay of a thread's history and can legitimately carry several past runs\n * back to back — including a run that ended in RUN_ERROR followed by a later\n * RUN_STARTED. Verifying a replay against single-run rules makes hydration of\n * an existing thread fail outright:\n *\n * Cannot send event type 'RUN_STARTED': The run has already errored with\n * 'RUN_ERROR'. No further events can be sent.\n *\n * `transformChunks` is still applied — message reassembly is needed either way.\n *\n * This mirrors the base `AbstractAgent.connectAgent` implementation exactly\n * apart from that omission, so callers keep the same subscriber notifications,\n * detach semantics, and `{ result, newMessages }` return shape.\n *\n * TODO: Remove this in favour of the base implementation once AG-UI's\n * AbstractAgent supports opting out of `verifyEvents` for transports whose\n * connection life-cycle isn't a single run. As of `@ag-ui/client@0.0.57`\n * `connectAgent(parameters?, subscriber?)` takes no such option.\n *\n * @param agent - The agent whose `connect()` stream should be consumed.\n * @param parameters - Run parameters, forwarded to `prepareRunAgentInput`.\n * @param subscriber - Optional one-shot subscriber for this connect call.\n */\nexport async function ɵconnectWithoutEventVerification(\n agent: AbstractAgent,\n parameters?: RunAgentParameters,\n subscriber?: AgentSubscriber,\n): Promise<RunAgentResult> {\n // Access protected/private members through a type escape hatch — they are\n // set and read by the base class and must be managed identically to the\n // original implementation. `any` is required because these fields are\n // private in AbstractAgent, and intersecting private+public members of the\n // same name produces `never`.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const self = agent as any;\n\n try {\n agent.isRunning = true;\n agent.agentId = agent.agentId ?? randomUUID();\n\n const input = self.prepareRunAgentInput(parameters);\n let result: RunAgentResult[\"result\"];\n const previousMessageIds = new Set(agent.messages.map((m) => m.id));\n const subscribers: AgentSubscriber[] = [\n {\n onRunFinishedEvent: (event) => {\n if (event.outcome === \"success\") {\n result = event.result;\n }\n },\n },\n ...agent.subscribers,\n subscriber ?? {},\n ];\n\n await self.onInitialize(input, subscribers);\n\n self.activeRunDetach$ = new Subject<void>();\n let resolveCompletion: (() => void) | undefined;\n self.activeRunCompletionPromise = new Promise<void>((resolve) => {\n resolveCompletion = resolve;\n });\n\n const source$ = defer(\n () => self.connect(input) as Observable<BaseEvent>,\n ).pipe(\n // transformChunks reassembles partial/streamed messages — still needed.\n transformChunks(self.debugLogger),\n // NOTE: verifyEvents is intentionally omitted here. See JSDoc above.\n takeUntil(self.activeRunDetach$),\n );\n\n const applied$ = self.apply(input, source$, subscribers);\n const processed$ = self.processApplyEvents(input, applied$, subscribers);\n\n await lastValueFrom(\n processed$.pipe(\n catchError((error: unknown) => {\n agent.isRunning = false;\n // An agent that doesn't implement connect() is not an error worth\n // surfacing: the base pipeline swallows it, and callers rely on that.\n // `CopilotKitCore` awaits `detachActiveRun()` before every run, which\n // only resolves because this path still reaches the finalize block\n // below (see the historical note in run-handler.ts). Routing it\n // through onError would also fire run-failure callbacks on every\n // subscriber for a benign condition.\n if (error instanceof AGUIConnectNotImplementedError) {\n return EMPTY;\n }\n return self.onError(input, error, subscribers);\n }),\n finalize(() => {\n agent.isRunning = false;\n void self.onFinalize(input, subscribers);\n resolveCompletion?.();\n resolveCompletion = undefined;\n self.activeRunCompletionPromise = undefined;\n self.activeRunDetach$ = undefined;\n }),\n ),\n { defaultValue: undefined },\n );\n\n const newMessages = structuredClone_(agent.messages).filter(\n (m) => !previousMessageIds.has(m.id),\n );\n return { result, newMessages };\n } finally {\n agent.isRunning = false;\n }\n}\n","import { Socket } from \"phoenix\";\nimport { EMPTY, NEVER, Observable, concat, defer, of, throwError } from \"rxjs\";\nimport {\n filter,\n finalize,\n mergeMap,\n scan,\n shareReplay,\n switchMap,\n take,\n} from \"rxjs/operators\";\n\n/**\n * Minimal Phoenix push contract used by the observable adapters.\n */\nexport interface ɵPhoenixPushLike {\n receive(\n status: string,\n callback: (payload?: unknown) => unknown,\n ): ɵPhoenixPushLike;\n}\n\n/**\n * Minimal Phoenix channel contract used by the observable adapters.\n */\nexport interface ɵPhoenixChannelLike {\n on(event: string, callback: (payload: unknown) => void): number;\n off(event: string, ref?: number): void;\n onError?(callback: (reason?: unknown) => void): unknown;\n join(params?: Record<string, unknown>): ɵPhoenixPushLike;\n push?(event: string, payload: unknown): ɵPhoenixPushLike;\n leave(): void;\n}\n\n/**\n * Minimal Phoenix socket contract used by the observable adapters.\n */\nexport interface ɵPhoenixSocketLike {\n connect(): void;\n disconnect(): void;\n channel(topic: string, params?: Record<string, unknown>): ɵPhoenixChannelLike;\n onError(callback: (error?: unknown) => void): unknown;\n onOpen(callback: () => void): unknown;\n}\n\n/**\n * Socket lifecycle notifications exposed by {@link ɵphoenixSocket$}.\n */\nexport type ɵPhoenixSocketSignal =\n | { type: \"open\" }\n | { type: \"error\"; error?: unknown };\n\n/**\n * Terminal outcomes of a Phoenix channel join attempt.\n */\nexport type ɵPhoenixJoinOutcome =\n | { type: \"joined\" }\n | { type: \"error\"; response?: unknown }\n | { type: \"timeout\" };\n\n/**\n * Active Phoenix socket session plus its derived lifecycle stream.\n */\nexport interface ɵPhoenixSocketSession {\n socket: ɵPhoenixSocketLike;\n signals$: Observable<ɵPhoenixSocketSignal>;\n}\n\n/**\n * Active Phoenix channel session plus its derived join-outcome stream.\n */\nexport interface ɵPhoenixChannelSession {\n channel: ɵPhoenixChannelLike;\n joinOutcome$: Observable<ɵPhoenixJoinOutcome>;\n}\n\n/**\n * Options for creating a cold Phoenix socket session stream.\n */\nexport interface ɵPhoenixSocketOptions {\n url: string;\n options?: Record<string, unknown>;\n}\n\n/**\n * Options for creating a cold Phoenix channel session stream from a socket stream.\n */\nexport interface ɵPhoenixChannelOptions {\n socket$: Observable<ɵPhoenixSocketSession>;\n topic: string;\n params?: Record<string, unknown>;\n leaveOnUnsubscribe?: boolean;\n}\n\n/**\n * Adapt Phoenix socket open/error callbacks into an observable signal stream.\n *\n * The returned observable is shared and replayable by the caller when needed,\n * but this helper itself does not own socket connection teardown.\n */\nfunction ɵcreatePhoenixSocketSignals$(\n socket: ɵPhoenixSocketLike,\n): Observable<ɵPhoenixSocketSignal> {\n return new Observable<ɵPhoenixSocketSignal>((observer) => {\n socket.onOpen(() => observer.next({ type: \"open\" }));\n socket.onError((error) => observer.next({ type: \"error\", error }));\n });\n}\n\n/**\n * Adapt a Phoenix channel join attempt into a single-outcome observable.\n */\nfunction ɵcreatePhoenixJoinOutcome$(\n channel: ɵPhoenixChannelLike,\n): Observable<ɵPhoenixJoinOutcome> {\n return new Observable<ɵPhoenixJoinOutcome>((observer) => {\n channel\n .join()\n .receive(\"ok\", () => {\n observer.next({ type: \"joined\" });\n observer.complete();\n })\n .receive(\"error\", (response?: unknown) => {\n observer.next({ type: \"error\", response });\n observer.complete();\n })\n .receive(\"timeout\", () => {\n observer.next({ type: \"timeout\" });\n observer.complete();\n });\n });\n}\n\n/**\n * Create a cold Phoenix socket session.\n *\n * The socket is constructed and connected on subscription, and disconnected on\n * teardown. Each subscription creates an isolated socket instance.\n */\nexport function ɵphoenixSocket$(\n options: ɵPhoenixSocketOptions,\n): Observable<ɵPhoenixSocketSession> {\n return defer(() => {\n const socket = new Socket(\n options.url,\n options.options as ConstructorParameters<typeof Socket>[1],\n ) as ɵPhoenixSocketLike;\n const signals$ = ɵcreatePhoenixSocketSignals$(socket).pipe(\n shareReplay({ bufferSize: 1, refCount: true }),\n );\n\n socket.connect();\n\n return concat(\n of({\n socket,\n signals$,\n }),\n NEVER,\n ).pipe(finalize(() => socket.disconnect()));\n });\n}\n\n/**\n * Create a cold Phoenix channel session from a socket session stream.\n *\n * A channel is created and joined for each active socket session. If the\n * upstream socket session changes, the previous channel is left before the\n * next one becomes active.\n */\nexport function ɵphoenixChannel$(\n options: ɵPhoenixChannelOptions,\n): Observable<ɵPhoenixChannelSession> {\n return options.socket$.pipe(\n switchMap(({ socket }) =>\n defer(() => {\n const channel = socket.channel(options.topic, options.params);\n const joinOutcome$ = ɵcreatePhoenixJoinOutcome$(channel).pipe(\n shareReplay({ bufferSize: 1, refCount: true }),\n );\n\n return concat(\n of({\n channel,\n joinOutcome$,\n }),\n NEVER,\n ).pipe(\n finalize(() => {\n if (options.leaveOnUnsubscribe !== false) {\n channel.leave();\n }\n }),\n );\n }),\n ),\n );\n}\n\n/**\n * Observe a named Phoenix channel event as an observable payload stream.\n */\nexport function ɵobservePhoenixEvent$<T>(\n channel: ɵPhoenixChannelLike,\n eventName: string,\n): Observable<T> {\n return new Observable<T>((observer) => {\n const ref = channel.on(eventName, (payload) => observer.next(payload as T));\n\n return () => {\n channel.off(eventName, ref);\n };\n });\n}\n\n/**\n * Flatten channel sessions into their join-outcome stream.\n */\nexport function ɵobservePhoenixJoinOutcome$(\n channel$: Observable<ɵPhoenixChannelSession>,\n): Observable<ɵPhoenixJoinOutcome> {\n return channel$.pipe(switchMap((session) => session.joinOutcome$));\n}\n\n/**\n * Complete when a channel joins successfully, or error if the join fails.\n */\nexport function ɵjoinPhoenixChannel$(\n channel$: Observable<ɵPhoenixChannelSession>,\n): Observable<never> {\n return ɵobservePhoenixJoinOutcome$(channel$).pipe(\n take(1),\n mergeMap((outcome) => {\n if (outcome.type === \"joined\") {\n return EMPTY;\n }\n\n throw outcome.type === \"timeout\"\n ? new Error(\"Timed out joining channel\")\n : new Error(\n `Failed to join channel: ${JSON.stringify(outcome.response)}`,\n );\n }),\n );\n}\n\n/**\n * Flatten socket sessions into their lifecycle signal stream.\n */\nexport function ɵobservePhoenixSocketSignals$(\n socket$: Observable<ɵPhoenixSocketSession>,\n): Observable<ɵPhoenixSocketSignal> {\n return socket$.pipe(switchMap((session) => session.signals$));\n}\n\n/**\n * Error after a socket emits the configured number of consecutive error\n * signals, resetting the counter after each successful open signal.\n */\nexport function ɵobservePhoenixSocketHealth$(\n socketSignals$: Observable<ɵPhoenixSocketSignal>,\n maxConsecutiveErrors: number,\n): Observable<never> {\n return socketSignals$.pipe(\n scan(\n (consecutiveErrors, signal) =>\n signal.type === \"open\" ? 0 : consecutiveErrors + 1,\n 0,\n ),\n filter((consecutiveErrors) => consecutiveErrors >= maxConsecutiveErrors),\n take(1),\n mergeMap((consecutiveErrors) =>\n throwError(\n () =>\n new Error(\n `WebSocket connection failed after ${consecutiveErrors} consecutive errors`,\n ),\n ),\n ),\n );\n}\n","import type {\n RunAgentInput,\n RunAgentParameters,\n RunAgentResult,\n AgentSubscriber,\n BaseEvent,\n} from \"@ag-ui/client\";\nimport { AbstractAgent, EventType } from \"@ag-ui/client\";\n\nimport {\n EMPTY,\n Notification,\n combineLatest,\n defer,\n dematerialize,\n merge,\n switchMap,\n throwError,\n} from \"rxjs\";\nimport type { ObservableNotification, Observable } from \"rxjs\";\nimport {\n catchError,\n delay,\n endWith,\n filter,\n finalize,\n ignoreElements,\n mergeMap,\n share,\n shareReplay,\n switchMap as switchMapOperator,\n take,\n takeUntil,\n tap,\n} from \"rxjs/operators\";\nimport { phoenixExponentialBackoff } from \"@copilotkit/shared\";\nimport { ɵconnectWithoutEventVerification } from \"./utils/connect-replay\";\nimport {\n ɵphoenixChannel$,\n ɵphoenixSocket$,\n ɵjoinPhoenixChannel$,\n ɵobservePhoenixSocketSignals$,\n ɵobservePhoenixSocketHealth$,\n ɵobservePhoenixEvent$,\n} from \"./utils/phoenix-observable\";\nimport type {\n ɵPhoenixChannelLike,\n ɵPhoenixChannelSession,\n ɵPhoenixPushLike,\n ɵPhoenixSocketLike,\n ɵPhoenixSocketSession,\n} from \"./utils/phoenix-observable\";\n\n/**\n * Structural Phoenix socket/channel contracts used by this agent, derived from\n * the minimal `*Like` interfaces in {@link ./utils/phoenix-observable}.\n */\ntype Socket = ɵPhoenixSocketLike;\n\ninterface Channel extends ɵPhoenixChannelLike {\n push(event: string, payload: unknown): ɵPhoenixPushLike;\n}\n\nconst globalFetch: typeof fetch = (...args) => fetch(...args);\n\nconst CLIENT_AG_UI_EVENT = \"ag_ui_event\";\nconst REPLAY_COMPLETE_EVENT = \"replay_complete\";\nconst STREAM_IDLE_EVENT = \"stream_idle\";\nconst STOP_RUN_EVENT = \"stop_run\";\nconst CONNECT_STREAM_IDLE_REPLAY_FALLBACK_MS = 100;\n\ninterface IntelligenceAgentSharedState {\n lastSeenEventIds: Map<string, string>;\n}\n\ninterface RealtimeConnectionInfo {\n clientUrl: string;\n topic: string;\n}\n\ninterface ThreadJoinCredentials {\n threadId: string;\n runId: string | null;\n joinToken: string;\n realtime: RealtimeConnectionInfo;\n}\n\nexport class AgentThreadLockedError extends Error {\n constructor(threadId?: string) {\n super(threadId ? `Thread ${threadId} is locked` : \"Thread is locked\");\n this.name = \"AgentThreadLockedError\";\n }\n}\n\n/**\n * Typed contract for agents that expose the completion promise of their\n * currently in-flight run.\n *\n * `IntelligenceAgent` resolves this promise once a run's observable pipeline\n * finalizes (see {@link IntelligenceAgent.connectAgent}). Consumers (e.g. the\n * v2 `CopilotChat` send-serialization path) await it to let an in-flight run —\n * notably an interrupt RESUME — finish before dispatching a new run, instead\n * of pre-empting it.\n *\n * The base `AbstractAgent` from `@ag-ui/client` only declares this property\n * privately, so it is reachable only through this contract plus the\n * {@link isRunCompletionAware} type guard. This keeps callers off `as unknown`\n * casts while still degrading safely for agents that don't implement it.\n */\nexport interface RunCompletionAware {\n /**\n * Resolves when the active run's pipeline finalizes (completes, errors, or is\n * detached). `undefined` when no run is in flight.\n */\n readonly activeRunCompletionPromise?: Promise<void>;\n}\n\n/**\n * Type guard for {@link RunCompletionAware}. Returns true when `agent` exposes\n * an `activeRunCompletionPromise` property, so callers can await an in-flight\n * run without an `as unknown as` cast. Returns false for agents that don't\n * implement the contract, letting the caller skip the await and degrade safely.\n */\nexport function isRunCompletionAware(\n agent: unknown,\n): agent is RunCompletionAware {\n return (\n typeof agent === \"object\" &&\n agent !== null &&\n \"activeRunCompletionPromise\" in agent\n );\n}\n\nexport interface IntelligenceAgentConfig {\n /** Phoenix websocket URL, e.g. \"ws://localhost:4000/socket\" */\n url: string;\n /** Runtime base URL, e.g. \"http://localhost:4000\" */\n runtimeUrl: string;\n /** HTTP transport for run/connect requests. Defaults to REST. */\n transport?: \"rest\" | \"single\";\n /** Agent identifier for REST endpoints */\n agentId: string;\n /** Optional params sent on socket connect (e.g. auth token) */\n socketParams?: Record<string, string>;\n /** Optional headers sent with REST requests */\n headers?: Record<string, string>;\n /** Optional credentials mode for fetch requests */\n credentials?: RequestCredentials;\n fetch?: typeof fetch;\n}\n\nexport class IntelligenceAgent extends AbstractAgent {\n private config: IntelligenceAgentConfig;\n private socket: Socket | null = null;\n private activeChannel: Channel | null = null;\n private canonicalRunId: string | null = null;\n private sharedState: IntelligenceAgentSharedState;\n\n constructor(\n config: IntelligenceAgentConfig,\n sharedState: IntelligenceAgentSharedState = {\n lastSeenEventIds: new Map<string, string>(),\n },\n ) {\n super();\n this.config = config;\n this.sharedState = sharedState;\n }\n\n /**\n * Headers sent with the REST join requests (`/connect`, `/run`).\n *\n * Deliberately a public accessor pair rather than a plain read of `config`.\n * `ProxiedCopilotRuntimeAgent` builds its delegate once and caches it for the\n * proxy's lifetime, so a header that changes later (a tenant switch, a\n * rotated bearer) would otherwise never reach the gateway. The accessor is\n * what closes that gap: `syncDelegate` refreshes the delegate before every\n * join, and its `hasHeaders` probe is an `\"headers\" in agent` check — which a\n * prototype accessor satisfies but a `private config` does not.\n *\n * The setter replaces the config object instead of mutating it because\n * `clone()` hands the same config reference to the copy. An in-place write\n * would therefore have a per-thread clone's headers land on the original's\n * config too. The join path itself would survive that (`syncDelegate`\n * rewrites the headers just before every join), but the re-acquisition inside\n * an already-running pipeline does not go through `syncDelegate` — so a\n * clone's tenant could ride out on the original's socket-error refresh. That\n * is the same cross-tenant leak this accessor exists to prevent.\n */\n get headers(): Record<string, string> | undefined {\n return this.config.headers;\n }\n\n set headers(headers: Record<string, string> | undefined) {\n this.config = { ...this.config, headers };\n }\n\n /** Credentials mode for the REST join requests. Live for the same reason as {@link headers}. */\n get credentials(): RequestCredentials | undefined {\n return this.config.credentials;\n }\n\n set credentials(credentials: RequestCredentials | undefined) {\n this.config = { ...this.config, credentials };\n }\n\n clone(): IntelligenceAgent {\n return new IntelligenceAgent(this.config, this.sharedState);\n }\n\n /**\n * Override of AbstractAgent.connectAgent that removes the `verifyEvents` step.\n *\n * IntelligenceAgent uses long-lived WebSocket connections rather than\n * request-scoped SSE streams. When connecting to replay historical messages\n * for an existing thread, the connection semantics don't map to a single\n * agent run start/stop cycle: the replayed events may omit the\n * RUN_STARTED/RUN_FINISHED bookends, or carry events from several past runs,\n * either of which makes `verifyEvents` stall or error out.\n *\n * See {@link ɵconnectWithoutEventVerification} for the pipeline itself, which\n * the self-hosted `/connect` path shares for the same reason.\n */\n override async connectAgent(\n parameters?: RunAgentParameters,\n subscriber?: AgentSubscriber,\n ): Promise<RunAgentResult> {\n // A run already in flight owns the canonical run id; reuse it so the\n // replay is attributed to that run rather than minting a new one.\n const effectiveParameters =\n parameters?.runId || !this.canonicalRunId\n ? parameters\n : {\n ...parameters,\n runId: this.canonicalRunId,\n };\n\n return ɵconnectWithoutEventVerification(\n this,\n effectiveParameters,\n subscriber,\n );\n }\n\n abortRun(): void {\n if (this.activeChannel && this.canonicalRunId) {\n // Defer cleanup until the push is acknowledged so socket.disconnect()\n // doesn't clear the push buffer before the stop signal is sent.\n // The 5-second fallback handles the case where the socket is down and\n // Phoenix never flushes the buffered push (its .receive(\"timeout\") only\n // fires for pushes that were actually sent but not replied to).\n // detachActiveRun() gracefully tears down the connectAgent() pipeline;\n // cleanup() follows as a safety net for the run() path.\n const fallback = setTimeout(() => clear(), 5_000);\n const clear = () => {\n clearTimeout(fallback);\n void this.detachActiveRun();\n this.cleanup();\n };\n\n this.activeChannel\n .push(STOP_RUN_EVENT, { run_id: this.canonicalRunId })\n .receive(\"ok\", clear)\n .receive(\"error\", clear)\n .receive(\"timeout\", clear);\n } else {\n void this.detachActiveRun();\n this.cleanup();\n }\n }\n\n /**\n * Trigger the run via REST, then join the realtime thread channel and relay\n * server-pushed AG-UI events to the Observable subscriber.\n */\n run(input: RunAgentInput): Observable<BaseEvent> {\n this.threadId = input.threadId;\n this.canonicalRunId = input.runId;\n\n return defer(() => this.requestJoinCredentials$(\"run\", input)).pipe(\n switchMap((credentials) => {\n if (credentials === null) {\n return throwError(\n () => new Error(\"REST run request returned no credentials\"),\n );\n }\n\n const canonicalInput = this.applyCanonicalRunIdentity(\n input,\n credentials,\n { fallbackToInputRunId: true },\n );\n\n return this.observeThread$(canonicalInput, credentials, {\n completeOnRunError: false,\n streamMode: \"run\",\n });\n }),\n );\n }\n\n /**\n * Reconnect to an existing thread by fetching websocket credentials and\n * joining the realtime thread channel.\n */\n /**\n * Reconnect to an existing thread by fetching websocket credentials\n * and joining the realtime thread channel.\n *\n * Note: this method does NOT clear the replay cursor. Whether to\n * request a full historical replay vs. resume from\n * `lastSeenEventId` is a decision the caller (typically\n * `RunHandler.connectAgent`) makes by calling\n * {@link clearReconnectCursor} ahead of time on a fresh thread\n * restore. Same-thread churn re-connects preserve the cursor so the\n * gateway only streams events past it instead of replaying the\n * entire history every time the chat re-opens a socket.\n */\n protected connect(input: RunAgentInput): Observable<BaseEvent> {\n this.threadId = input.threadId;\n this.canonicalRunId = null;\n const replayCursor = this.getReconnectCursor(input);\n\n return defer(() =>\n this.requestJoinCredentials$(\"connect\", input, replayCursor),\n ).pipe(\n switchMap((credentials) => {\n if (credentials === null) {\n return EMPTY;\n }\n\n const canonicalInput = this.applyCanonicalRunIdentity(\n input,\n credentials,\n { fallbackToInputRunId: false },\n );\n\n return this.observeThread$(canonicalInput, credentials, {\n completeOnRunError: false,\n streamMode: \"connect\",\n replayCursor,\n });\n }),\n );\n }\n\n /**\n * Tear down a specific channel + socket pair that belongs to one pipeline.\n * Only nulls instance references when they still point to the owned resource,\n * so a concurrent pipeline's resources are never clobbered.\n */\n private cleanupOwned(\n ownChannel: Channel | null,\n ownSocket: Socket | null,\n ): void {\n if (ownChannel) {\n ownChannel.leave();\n if (this.activeChannel === ownChannel) {\n this.activeChannel = null;\n }\n }\n if (ownSocket) {\n ownSocket.disconnect();\n if (this.socket === ownSocket) {\n this.socket = null;\n }\n }\n this.canonicalRunId = null;\n }\n\n private cleanup(): void {\n this.cleanupOwned(this.activeChannel, this.socket);\n }\n\n private requestJoinCredentials$(\n mode: \"run\" | \"connect\",\n input: RunAgentInput,\n replayCursor?: string | null,\n ): Observable<ThreadJoinCredentials | null> {\n return defer(async () => {\n try {\n const requestFetch = this.config.fetch ?? globalFetch;\n const body = {\n ...input,\n ...(mode === \"connect\"\n ? {\n lastSeenEventId:\n replayCursor === undefined\n ? this.getReconnectCursor(input)\n : replayCursor,\n }\n : {}),\n };\n const single = this.config.transport === \"single\";\n const response = await requestFetch(\n single ? this.config.runtimeUrl : this.buildRuntimeUrl(mode),\n {\n method: \"POST\",\n redirect: \"error\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.headers,\n },\n // Post the whole RunAgentInput rather than naming each field, so a\n // protocol field such as `resume` cannot be dropped here again.\n body: JSON.stringify(\n single\n ? {\n method: `agent/${mode}`,\n params: { agentId: this.config.agentId },\n body,\n }\n : body,\n ),\n ...(this.credentials ? { credentials: this.credentials } : {}),\n },\n );\n\n if (response.status === 204 && mode === \"connect\") {\n return null;\n }\n\n if (response.status === 409 && mode === \"run\") {\n throw new AgentThreadLockedError(input.threadId);\n }\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n throw new Error(\n text || response.statusText || String(response.status),\n );\n }\n\n return this.normalizeJoinCredentials(await response.json(), input);\n } catch (error) {\n if (error instanceof AgentThreadLockedError) {\n throw error;\n }\n throw new Error(\n `REST ${mode} request failed: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error },\n );\n }\n });\n }\n\n private normalizeJoinCredentials(\n payload: unknown,\n input: RunAgentInput,\n ): ThreadJoinCredentials {\n const envelope =\n payload && typeof payload === \"object\"\n ? (payload as Record<string, unknown>)\n : null;\n const realtime =\n envelope?.realtime && typeof envelope.realtime === \"object\"\n ? (envelope.realtime as Record<string, unknown>)\n : null;\n\n if (typeof envelope?.joinToken !== \"string\" || !envelope.joinToken) {\n throw new Error(\"missing joinToken\");\n }\n\n if (typeof realtime?.clientUrl !== \"string\" || !realtime.clientUrl) {\n throw new Error(\"missing realtime.clientUrl\");\n }\n\n if (typeof realtime.topic !== \"string\" || !realtime.topic) {\n throw new Error(\"missing realtime.topic\");\n }\n\n return {\n threadId:\n typeof envelope.threadId === \"string\" && envelope.threadId\n ? envelope.threadId\n : input.threadId,\n runId:\n typeof envelope.runId === \"string\" && envelope.runId\n ? envelope.runId\n : null,\n joinToken: envelope.joinToken,\n realtime: {\n clientUrl: realtime.clientUrl,\n topic: realtime.topic,\n },\n };\n }\n\n private observeThread$(\n input: RunAgentInput,\n credentials: ThreadJoinCredentials,\n options: {\n completeOnRunError: boolean;\n streamMode: \"run\" | \"connect\";\n channelMode?: \"run\" | \"connect\";\n replayCursor?: string | null;\n },\n ): Observable<BaseEvent> {\n return this.observeThreadSession$(input, credentials, options).pipe(\n catchError((error) => {\n if (!this.isSocketReconnectExhaustedError(error)) {\n return throwError(() => error);\n }\n\n const replayCursor = this.getReconnectCursor(input);\n return this.requestJoinCredentials$(\n \"connect\",\n input,\n replayCursor,\n ).pipe(\n switchMap((refreshedCredentials) =>\n refreshedCredentials === null\n ? EMPTY\n : this.observeThread$(\n this.applyCanonicalRunIdentity(input, refreshedCredentials, {\n fallbackToInputRunId: options.streamMode === \"run\",\n }),\n refreshedCredentials,\n {\n ...options,\n channelMode: \"connect\",\n replayCursor,\n },\n ),\n ),\n );\n }),\n );\n }\n\n private observeThreadSession$(\n input: RunAgentInput,\n credentials: ThreadJoinCredentials,\n options: {\n completeOnRunError: boolean;\n streamMode: \"run\" | \"connect\";\n channelMode?: \"run\" | \"connect\";\n replayCursor?: string | null;\n },\n ): Observable<BaseEvent> {\n return defer(() => {\n // Capture references to the socket and channel created by THIS pipeline\n // so the finalize closure only tears down its own resources. Without\n // this, a fire-and-forget detachActiveRun() from run-handler can race:\n // the old pipeline's deferred cleanup reads from `this.socket` /\n // `this.activeChannel`, which by then may already point to the NEW\n // pipeline's resources — destroying the live connection and preventing\n // the stop signal from ever reaching the backend.\n let ownSocket: Socket | null = null;\n let ownChannel: Channel | null = null;\n\n const socket$ = ɵphoenixSocket$({\n url: credentials.realtime.clientUrl,\n options: {\n params: {\n ...this.config.socketParams,\n join_token: credentials.joinToken,\n },\n reconnectAfterMs: phoenixExponentialBackoff(100, 10_000),\n rejoinAfterMs: phoenixExponentialBackoff(1_000, 30_000),\n },\n }).pipe(\n tap(({ socket }) => {\n ownSocket = socket as Socket;\n this.socket = ownSocket;\n }),\n shareReplay({ bufferSize: 1, refCount: true }),\n );\n const params = this.createThreadChannelParams(\n input,\n options.channelMode ?? options.streamMode,\n options.replayCursor,\n );\n const channel$ = ɵphoenixChannel$({\n socket$,\n topic: credentials.realtime.topic,\n params,\n }).pipe(\n tap(({ channel }) => {\n ownChannel = channel as Channel;\n this.activeChannel = ownChannel;\n }),\n shareReplay({ bufferSize: 1, refCount: true }),\n );\n const reconnectCursor = this.readDurableEventId(\n options.replayCursor ?? this.getReconnectCursor(input),\n );\n let latestObservedReplayCursor: string | null = null;\n const threadEvents$ = this.observeThreadEvents$(\n input.threadId,\n channel$,\n options,\n ).pipe(\n tap((payload) => {\n latestObservedReplayCursor =\n this.readEventId(payload) ?? latestObservedReplayCursor;\n }),\n share(),\n );\n const replayComplete$ = this.observeControlEvent$(\n input.threadId,\n channel$,\n REPLAY_COMPLETE_EVENT,\n ).pipe(shareReplay({ bufferSize: 1, refCount: true }));\n const streamIdle$ = this.observeControlEvent$(\n input.threadId,\n channel$,\n STREAM_IDLE_EVENT,\n ).pipe(shareReplay({ bufferSize: 1, refCount: true }));\n const streamIdleCompletion$ =\n options.streamMode === \"connect\"\n ? merge(\n combineLatest([\n replayComplete$.pipe(take(1)),\n streamIdle$.pipe(take(1)),\n ]),\n streamIdle$.pipe(\n take(1),\n filter((payload) =>\n this.canFallbackCompleteConnect(\n payload,\n reconnectCursor,\n latestObservedReplayCursor,\n ),\n ),\n delay(CONNECT_STREAM_IDLE_REPLAY_FALLBACK_MS),\n ),\n ).pipe(take(1))\n : EMPTY;\n const threadCompleted$ = threadEvents$.pipe(\n ignoreElements(),\n endWith(null),\n take(1),\n );\n const terminal$ = merge(threadCompleted$, streamIdleCompletion$);\n\n return merge(\n this.joinThreadChannel$(channel$),\n this.observeSocketHealth$(socket$).pipe(takeUntil(terminal$)),\n threadEvents$.pipe(takeUntil(streamIdleCompletion$)),\n replayComplete$.pipe(ignoreElements(), takeUntil(terminal$)),\n streamIdleCompletion$.pipe(\n ignoreElements(),\n takeUntil(threadCompleted$),\n ),\n ).pipe(finalize(() => this.cleanupOwned(ownChannel, ownSocket)));\n });\n }\n\n private joinThreadChannel$(\n channel$: Observable<ɵPhoenixChannelSession>,\n ): Observable<never> {\n return ɵjoinPhoenixChannel$(channel$);\n }\n\n private observeSocketHealth$(\n socket$: Observable<ɵPhoenixSocketSession>,\n ): Observable<never> {\n return ɵobservePhoenixSocketHealth$(\n ɵobservePhoenixSocketSignals$(socket$),\n 5,\n );\n }\n\n private observeThreadEvents$(\n threadId: string,\n channel$: Observable<ɵPhoenixChannelSession>,\n options: { completeOnRunError: boolean; streamMode: \"run\" | \"connect\" },\n ): Observable<BaseEvent> {\n return channel$.pipe(\n switchMapOperator(({ channel }) =>\n this.observeChannelEvent$<BaseEvent>(channel, CLIENT_AG_UI_EVENT),\n ),\n tap((payload) => {\n this.updateLastSeenEventId(threadId, payload);\n }),\n mergeMap(\n (payload) =>\n this.createThreadNotifications(payload, {\n completeOnRunError: options.completeOnRunError,\n completeOnRunFinished: options.streamMode === \"run\",\n errorOnRunError: options.streamMode === \"run\",\n }) as ObservableNotification<BaseEvent>[],\n ),\n dematerialize(),\n );\n }\n\n private observeControlEvent$(\n threadId: string,\n channel$: Observable<ɵPhoenixChannelSession>,\n eventName: string,\n ): Observable<unknown> {\n return channel$.pipe(\n switchMapOperator(({ channel }) =>\n this.observeChannelEvent$<unknown>(channel, eventName),\n ),\n tap((payload) =>\n this.updateLastSeenEventIdFromControl(threadId, payload),\n ),\n );\n }\n\n private observeChannelEvent$<T>(\n channel: ɵPhoenixChannelLike,\n eventName: string,\n ): Observable<T> {\n return ɵobservePhoenixEvent$<T>(channel, eventName);\n }\n\n private createThreadNotifications(\n payload: BaseEvent,\n options: {\n completeOnRunError: boolean;\n completeOnRunFinished: boolean;\n errorOnRunError: boolean;\n },\n ): Array<Notification<BaseEvent>> {\n if (payload.type === EventType.RUN_FINISHED) {\n return options.completeOnRunFinished\n ? [Notification.createNext(payload), Notification.createComplete()]\n : [Notification.createNext(payload)];\n }\n\n if (payload.type === EventType.RUN_ERROR) {\n const errorMessage =\n (payload as BaseEvent & { message?: string }).message ?? \"Run error\";\n\n return options.completeOnRunError\n ? [Notification.createNext(payload), Notification.createComplete()]\n : options.errorOnRunError\n ? [\n Notification.createNext(payload),\n Notification.createError(new Error(errorMessage)),\n ]\n : [Notification.createNext(payload)];\n }\n\n return [Notification.createNext(payload)];\n }\n\n private buildRuntimeUrl(mode: \"run\" | \"connect\"): string {\n const path = `${this.config.runtimeUrl}/agent/${encodeURIComponent(this.config.agentId)}/${mode}`;\n const origin =\n typeof window !== \"undefined\" && window.location\n ? window.location.origin\n : \"http://localhost\";\n\n return new URL(path, new URL(this.config.runtimeUrl, origin)).toString();\n }\n\n private createThreadChannelParams(\n input: RunAgentInput,\n streamMode: \"run\" | \"connect\",\n replayCursor?: string | null,\n ): Record<string, unknown> {\n return streamMode === \"run\"\n ? {\n stream_mode: \"run\",\n run_id: input.runId,\n }\n : {\n stream_mode: \"connect\",\n last_seen_event_id:\n replayCursor === undefined\n ? this.getReconnectCursor(input)\n : replayCursor,\n };\n }\n\n private getLastSeenEventId(threadId: string): string | null {\n return this.sharedState.lastSeenEventIds.get(threadId) ?? null;\n }\n\n private getReconnectCursor(input: RunAgentInput): string | null {\n return this.getLastSeenEventId(input.threadId);\n }\n\n /**\n * Drop the cached `lastSeenEventId` cursor for `threadId` so the\n * next connect to that topic asks the gateway for a full historical\n * replay (rather than resuming). Public because\n * `RunHandler.connectAgent` calls it on a detected thread switch\n * to rebuild local state from scratch, and skips it on same-thread\n * churn so the gateway can resume.\n */\n public clearReconnectCursor(threadId: string): void {\n this.sharedState.lastSeenEventIds.delete(threadId);\n }\n\n private updateLastSeenEventId(threadId: string, payload: BaseEvent): void {\n const eventId = this.readEventId(payload);\n if (!eventId) {\n return;\n }\n\n this.advanceLastSeenEventId(threadId, eventId);\n }\n\n private updateLastSeenEventIdFromControl(\n threadId: string,\n payload: unknown,\n ): void {\n const eventId = this.readControlEventId(payload);\n if (!eventId) {\n return;\n }\n\n this.advanceLastSeenEventId(threadId, eventId);\n }\n\n private advanceLastSeenEventId(threadId: string, eventId: string): void {\n this.sharedState.lastSeenEventIds.set(threadId, eventId);\n }\n\n private readEventId(payload: BaseEvent): string | null {\n const metadata = (payload as BaseEvent & { metadata?: unknown }).metadata;\n if (!metadata || typeof metadata !== \"object\") {\n return null;\n }\n\n const eventMetadata = metadata as { cpki_event_id?: unknown };\n return this.readDurableEventId(eventMetadata.cpki_event_id);\n }\n\n private readControlEventId(payload: unknown): string | null {\n if (!payload || typeof payload !== \"object\") {\n return null;\n }\n\n const controlPayload = payload as {\n latestEventId?: unknown;\n latest_event_id?: unknown;\n };\n const latestEventId =\n controlPayload.latestEventId ?? controlPayload.latest_event_id;\n return this.readDurableEventId(latestEventId);\n }\n\n private readDurableEventId(eventId: unknown): string | null {\n if (typeof eventId !== \"string\" || eventId.trim() === \"\") {\n return null;\n }\n\n return eventId.startsWith(\"cpki_ingested\") ? null : eventId;\n }\n\n private canFallbackCompleteConnect(\n streamIdlePayload: unknown,\n reconnectCursor: string | null,\n latestObservedReplayCursor: string | null,\n ): boolean {\n const idleCursor = this.readControlEventId(streamIdlePayload);\n if (!idleCursor) {\n return true;\n }\n\n return (\n idleCursor === reconnectCursor ||\n idleCursor === latestObservedReplayCursor\n );\n }\n\n private applyCanonicalRunIdentity(\n input: RunAgentInput,\n credentials: ThreadJoinCredentials,\n options: { fallbackToInputRunId: boolean },\n ): RunAgentInput {\n this.threadId = credentials.threadId;\n const runId =\n credentials.runId ?? (options.fallbackToInputRunId ? input.runId : null);\n this.canonicalRunId = runId;\n\n return {\n ...input,\n threadId: credentials.threadId,\n ...(runId === null ? {} : { runId }),\n };\n }\n\n private isSocketReconnectExhaustedError(error: unknown): boolean {\n return (\n error instanceof Error &&\n error.message.includes(\"WebSocket connection failed after\")\n );\n }\n}\n","/**\n * Build the error for a failed runtime `/info` response, folding in whatever\n * explanation the runtime sent back.\n *\n * The status alone cannot distinguish a wrong `runtimeUrl` from a transport\n * mismatch, so the runtime answers the latter with a body naming the cause\n * (see the handler's `single_route_envelope_against_multi_route_runtime`\n * diagnostic). Discarding that body — as every `/info` caller used to — left\n * the developer with a bare 404 and nothing to act on (OSS-882).\n *\n * A body that isn't JSON, or carries no string `message`, contributes nothing:\n * the status is then the whole error.\n */\nexport async function runtimeInfoError(\n response: Response,\n): Promise<RuntimeInfoRequestError> {\n const base = `Runtime info request failed with status ${response.status}`;\n\n let detail: string | undefined;\n try {\n const body: unknown = await response.clone().json();\n const message = (body as { message?: unknown } | null)?.message;\n if (typeof message === \"string\" && message.trim().length > 0) {\n detail = message.trim();\n }\n } catch {\n // Unparseable or already-consumed body — fall back to the status.\n }\n\n const error = new Error(\n detail ? `${base}: ${detail}` : base,\n ) as RuntimeInfoRequestError;\n error.runtimeInfoStatus = response.status;\n return error;\n}\n\nexport interface RuntimeInfoRequestError extends Error {\n runtimeInfoStatus: number;\n}\n\nexport function isRuntimeInfoRequestError(\n error: unknown,\n): error is RuntimeInfoRequestError {\n return (\n typeof error === \"object\" &&\n error !== null &&\n typeof (error as { runtimeInfoStatus?: unknown }).runtimeInfoStatus ===\n \"number\"\n );\n}\n","import type { Message } from \"@ag-ui/client\";\n\n/**\n * Rewrites the message list a runtime agent sends on each run.\n *\n * CopilotKit sends the whole thread on every request. When the backend already\n * stores the conversation (a LangGraph checkpointer, a Mastra memory store, a\n * Strands `SessionManager`, an Agent Framework chat history provider), that\n * history is dead weight: the payload grows without bound, and an agent that\n * merges the inbound list with its own store can show the model every turn\n * twice. See https://github.com/CopilotKit/CopilotKit/issues/1482.\n *\n * The filter runs on the outbound payload only. It never touches the messages\n * the UI renders, so trimming here does not shorten the visible transcript.\n *\n * Return the messages to send. Returning an empty array is valid and means\n * \"send nothing but the run metadata\".\n *\n * @param messages - The thread as the client holds it, in order, with\n * `activity`-role messages already removed.\n * @param context - Which agent is about to run.\n */\nexport type CopilotKitMessageFilter = (\n messages: Message[],\n context: { agentId: string },\n) => Message[];\n\ninterface AssistantToolCall {\n id: string;\n}\n\nfunction toolCallIdsOf(message: Message): string[] {\n const calls = (message as { toolCalls?: AssistantToolCall[] }).toolCalls;\n if (!Array.isArray(calls)) return [];\n return calls.map((call) => call.id).filter((id): id is string => Boolean(id));\n}\n\nfunction resultCallIdOf(message: Message): string | undefined {\n if (message.role !== \"tool\") return undefined;\n return (message as { toolCallId?: string }).toolCallId;\n}\n\n/**\n * Repair the tool-call pairs a filter broke.\n *\n * Every provider rejects a half pair. A tool result whose call is gone reads as\n * a reply to nothing, and an assistant tool call whose result is gone leaves\n * the turn unanswered — the failure reporters hit on #1482 when a trimmed\n * history landed mid-HITL and Anthropic answered \"a tool result is expected\".\n * A filter written as `messages.slice(-1)` cannot know this, so the repair runs\n * for every filter rather than being something each caller opts into.\n *\n * Both repairs restore, never discard, and both are anchored on the untrimmed\n * thread:\n *\n * - A kept tool result whose assistant call was trimmed away gets that call put\n * back in front of it. Dropping the result instead would be protocol-safe and\n * semantically wrong: on a human-in-the-loop turn the result IS the new\n * information, and a backend that already holds the call would be asked to\n * resume with nothing.\n * - A kept assistant call whose result was trimmed gets that result restored,\n * placed directly after the call.\n *\n * Restoring a call pulls in every result for that call, not only the one the\n * filter kept. Providers reject an assistant turn with a parallel tool call\n * left unanswered, so a half-answered set is as invalid as a missing one.\n *\n * A call with no result anywhere in `full` is left alone. That is an open call\n * (a pending frontend tool, an unanswered interrupt), not a broken pair. A\n * result whose call is nowhere in `full` is left alone too: it was already\n * unpaired before the filter ran, so it is not this function's to fix.\n *\n * The filter's own ordering is preserved. Restorations are the only insertions,\n * and messages the filter synthesized (absent from `full`) pass through\n * untouched.\n */\nexport function ɵrepairToolCallPairs(\n kept: Message[],\n full: Message[],\n): Message[] {\n // Both maps are built from the untrimmed thread: the repair has to reason\n // about pairs the filter already broke, so the kept list cannot answer\n // \"did this call have a result\".\n const callIdToIssuer = new Map<string, Message>();\n const callIdToResult = new Map<string, Message>();\n for (const message of full) {\n for (const callId of toolCallIdsOf(message)) {\n callIdToIssuer.set(callId, message);\n }\n const resultCallId = resultCallIdOf(message);\n if (resultCallId !== undefined) {\n callIdToResult.set(resultCallId, message);\n }\n }\n\n const repaired: Message[] = [];\n const emitted = new Set<string>();\n\n const emit = (message: Message) => {\n if (emitted.has(message.id)) return;\n emitted.add(message.id);\n repaired.push(message);\n };\n\n /** Emit an assistant turn together with every result it is owed. */\n const emitWithResults = (message: Message) => {\n emit(message);\n for (const callId of toolCallIdsOf(message)) {\n const result = callIdToResult.get(callId);\n if (result) emit(result);\n }\n };\n\n for (const message of kept) {\n const resultCallId = resultCallIdOf(message);\n if (resultCallId === undefined) {\n emitWithResults(message);\n continue;\n }\n\n const issuer = callIdToIssuer.get(resultCallId);\n if (issuer) {\n // Emits the issuer first, then this result along with its siblings.\n emitWithResults(issuer);\n continue;\n }\n emit(message);\n }\n\n return repaired;\n}\n","import type {\n AbstractAgent,\n AgentCapabilities,\n AgentSubscriber,\n BaseEvent,\n HttpAgentConfig,\n RunAgentInput,\n RunAgentParameters,\n RunAgentResult,\n} from \"@ag-ui/client\";\nimport {\n HttpAgent,\n runHttpRequest,\n structuredClone_,\n transformHttpEventStream,\n} from \"@ag-ui/client\";\nimport type { Observable } from \"rxjs\";\nimport { EMPTY, defer, from } from \"rxjs\";\nimport { catchError, finalize, switchMap } from \"rxjs/operators\";\nimport {\n RUNTIME_MODE_SSE,\n RUNTIME_MODE_INTELLIGENCE,\n} from \"@copilotkit/shared\";\nimport type {\n IntelligenceRuntimeInfo,\n RuntimeInfo,\n RuntimeMode,\n ResolvedDebugConfig,\n} from \"@copilotkit/shared\";\nimport { IntelligenceAgent } from \"./intelligence-agent\";\nimport type { CopilotRuntimeTransport } from \"./types\";\nimport { runtimeInfoError } from \"./utils/runtime-info-error\";\nimport { ɵconnectWithoutEventVerification } from \"./utils/connect-replay\";\nimport type { CopilotKitMessageFilter } from \"./core/message-filter\";\nimport { ɵrepairToolCallPairs } from \"./core/message-filter\";\n\ntype ResolvedRuntimeMode = RuntimeMode | \"pending\";\n\ninterface RunnableAgent {\n connect(input: RunAgentInput): Observable<BaseEvent>;\n run(input: RunAgentInput): Observable<BaseEvent>;\n}\n\nfunction hasHeaders(\n agent: AbstractAgent,\n): agent is AbstractAgent & { headers?: Record<string, string> } {\n return \"headers\" in agent;\n}\n\nfunction hasCredentials(\n agent: AbstractAgent,\n): agent is AbstractAgent & { credentials?: RequestCredentials } {\n return \"credentials\" in agent;\n}\n\nfunction isZodError(error: unknown): boolean {\n return (\n error !== null &&\n typeof error === \"object\" &&\n \"name\" in error &&\n (error as { name: string }).name === \"ZodError\"\n );\n}\n\nfunction isAbortError(error: unknown): boolean {\n return (\n (error instanceof DOMException || error instanceof Error) &&\n (error as Error).name === \"AbortError\"\n );\n}\n\nfunction withAbortErrorHandling(\n observable: Observable<BaseEvent>,\n): Observable<BaseEvent> {\n return observable.pipe(\n catchError((error) => {\n if (isZodError(error) || isAbortError(error)) {\n return EMPTY;\n }\n throw error;\n }),\n );\n}\n\nexport interface ProxiedCopilotRuntimeAgentConfig extends Omit<\n HttpAgentConfig,\n \"url\"\n> {\n runtimeUrl?: string;\n transport?: CopilotRuntimeTransport;\n credentials?: RequestCredentials;\n runtimeMode?: ResolvedRuntimeMode;\n intelligence?: IntelligenceRuntimeInfo;\n capabilities?: AgentCapabilities;\n debug?: ResolvedDebugConfig;\n /**\n * When set, runtime requests (HTTP path, single-route envelope, intelligence\n * delegate) are routed to this agent on the runtime instead of `agentId`.\n * The local `agentId` remains the registry key used for subscriber\n * bookkeeping; only outbound routing is overridden.\n */\n runtimeAgentId?: string;\n /**\n * Rewrites the outbound message list on every run. See\n * {@link CopilotKitMessageFilter}. Not applied in Intelligence mode.\n */\n messageFilter?: CopilotKitMessageFilter;\n}\n\nexport class ProxiedCopilotRuntimeAgent extends HttpAgent {\n runtimeUrl?: string;\n credentials?: RequestCredentials;\n // `readonly` because `super.url` is baked at construction; mutating\n // `runtimeAgentId` post-construction would desync the REST `run` URL\n // (already captured) from `routedAgentId()` (consulted per-call by\n // stop/connect/single-route paths).\n readonly runtimeAgentId?: string;\n private transport: CopilotRuntimeTransport;\n /**\n * The runtime URL exactly as the caller supplied it. `runtimeUrl` is the\n * slash-stripped form used for path joins; the single-route endpoint (run,\n * connect, stop, info envelopes) is this verbatim value, because a trailing\n * slash can select a different proxy location.\n */\n private readonly runtimeEndpointUrl?: string;\n private singleEndpointUrl?: string;\n private runtimeMode: ResolvedRuntimeMode;\n private intelligence?: IntelligenceRuntimeInfo;\n private _capabilities?: AgentCapabilities;\n private delegate?: AbstractAgent;\n private runtimeInfoPromise?: Promise<void>;\n private _messageFilter?: CopilotKitMessageFilter;\n /**\n * The HTTP `run` this agent started and has not yet seen finish, as the\n * exact `{ threadId, runId }` it POSTed. `abortRun` narrows `/stop` to this\n * run only while `threadId` still matches: `threadId` is a public field the\n * host may reassign under a live run, and a runId from another thread must\n * not be sent as if it were this thread's. Released when the run stream\n * finalizes, cleared on `connect` (a reconnected thread may run under a\n * runId this client never saw) and never copied by `clone`. Without a\n * provable active run the stop stays thread-wide.\n */\n private activeRun?: { threadId: string; runId: string };\n\n constructor(config: ProxiedCopilotRuntimeAgentConfig) {\n const normalizedRuntimeUrl = config.runtimeUrl\n ? config.runtimeUrl.replace(/\\/$/, \"\")\n : undefined;\n const transport = config.transport ?? \"auto\";\n const routedId = config.runtimeAgentId ?? config.agentId ?? \"\";\n // The single endpoint is the caller's URL exactly as given: a trailing\n // slash can select a different proxy location, so it must survive. Only\n // the path joins (`/agent/…`, `/info`) use the slash-stripped form.\n const runUrl =\n transport === \"single\"\n ? (config.runtimeUrl ?? \"\")\n : `${normalizedRuntimeUrl ?? config.runtimeUrl}/agent/${encodeURIComponent(routedId)}/run`;\n\n if (!runUrl) {\n throw new Error(\n \"ProxiedCopilotRuntimeAgent requires a runtimeUrl when transport is set to 'single'.\",\n );\n }\n\n super({\n ...config,\n url: runUrl,\n });\n this.runtimeUrl = normalizedRuntimeUrl ?? config.runtimeUrl;\n this.runtimeEndpointUrl = config.runtimeUrl;\n this.credentials = config.credentials;\n this.runtimeAgentId = config.runtimeAgentId;\n this.transport = transport;\n this.runtimeMode = config.runtimeMode ?? RUNTIME_MODE_SSE;\n this.intelligence = config.intelligence;\n this._capabilities = config.capabilities;\n this._messageFilter = config.messageFilter;\n if (config.debug) {\n this.debug = config.debug;\n }\n if (this.transport === \"single\") {\n this.singleEndpointUrl = this.runtimeEndpointUrl;\n }\n }\n\n /**\n * Adopt the runtime mode a fresh `/info` just reported.\n *\n * A live proxy outlives the runtime configuration that minted it: a\n * redeploy, an env-var change or a rollback can flip `intelligence` → `sse`\n * under a page that is already open. The registry preserves the proxy across\n * that re-sync on purpose — it is backing an open conversation — so the new\n * mode is pushed onto the instance here instead of replacing it.\n *\n * Without this the mode was decided once, at construction, and `run()` kept\n * taking the delegate path against a runtime serving plain SSE, where\n * `response.json()` on a `text/event-stream` body throws for the rest of the\n * page's life. See #7130.\n *\n * A delegate built for the old mode is torn down: it speaks a protocol the\n * runtime no longer serves, and it may be holding a websocket open. The\n * memoized `/info` promise goes with it — it answered for the old\n * configuration, so a later `ensureRuntimeConfiguration()` must re-ask\n * rather than treat that answer as current.\n *\n * Only `wsUrl` is compared on the Intelligence metadata, because that is the\n * one field the delegate bakes in at construction.\n */\n adoptRuntimeMode(\n runtimeMode: ResolvedRuntimeMode,\n intelligence: IntelligenceRuntimeInfo | undefined,\n ): void {\n const unchanged =\n this.runtimeMode === runtimeMode &&\n this.intelligence?.wsUrl === intelligence?.wsUrl;\n\n this.runtimeMode = runtimeMode;\n this.intelligence = intelligence;\n\n if (unchanged) {\n return;\n }\n this.runtimeInfoPromise = undefined;\n const staleDelegate = this.delegate;\n this.delegate = undefined;\n if (staleDelegate) {\n staleDelegate.abortRun();\n // A re-sync can land mid-run, so the proxy's own pipeline has to be\n // detached as well: aborting only the delegate would leave `isRunning`\n // true and `onRunFinalized` unfired, and the UI would spin forever.\n // This mirrors what `abortRun()` does for its delegate branch, minus\n // the delegate detach that clearing the field above already skips.\n void this.detachActiveRun();\n }\n }\n\n /**\n * The agent id used for outbound runtime requests — `runtimeAgentId` when\n * set (manually-registered proxy), otherwise `agentId` (registry id\n * matches runtime id). Subscriber bookkeeping keeps using `agentId`\n * directly.\n *\n * Throws when both are unset: a proxy reaching an HTTP path with no\n * routable id is a bug, and a missing id would otherwise produce a\n * malformed `/agent//run` or `/agent/undefined/connect` URL silently.\n */\n private routedAgentId(): string {\n const id = this.runtimeAgentId ?? this.agentId;\n if (!id) {\n throw new Error(\n \"ProxiedCopilotRuntimeAgent: cannot make a runtime request without an agentId or runtimeAgentId.\",\n );\n }\n return id;\n }\n\n get capabilities(): AgentCapabilities | undefined {\n return this._capabilities;\n }\n\n /**\n * The filter applied to the outbound message list on every run.\n *\n * Registry-owned. `AgentRegistry` writes it whenever the core-level filter\n * changes, so an agent discovered before the app configured one still picks\n * it up — and so a value written here by hand is replaced on the registry's\n * next sweep. Configure it through `CopilotKitCore` instead.\n */\n get messageFilter(): CopilotKitMessageFilter | undefined {\n return this._messageFilter;\n }\n\n set messageFilter(filter: CopilotKitMessageFilter | undefined) {\n this._messageFilter = filter;\n }\n\n /**\n * Narrow the outbound payload with the configured message filter.\n *\n * **Called from the HTTP paths only, and that placement is the Intelligence\n * exemption.** An earlier revision applied the filter in\n * `prepareRunAgentInput`, which runs before the runtime mode is resolved:\n * with the default `\"auto\"` transport, or on a proxy still `\"pending\"` its\n * first `/info`, `run()` prepared the input, *then* resolved the mode, then\n * handed that already-filtered input to `#runViaDelegate` — so a managed\n * runtime received a truncated thread despite the exemption. Filtering here\n * makes that unreachable by construction: `#runViaHttp` and\n * `#connectViaHttp` are only entered once the mode is known not to be\n * Intelligence. Do not move this back up the call chain.\n *\n * The managed runtime is the store of record for the thread — the threads\n * drawer and the Slack transcript read from it — so a client-side truncation\n * there has a blast radius nobody asked for. Every reporter on #1482 is\n * self-hosted.\n *\n * `prepareRunAgentInput` has already deep-cloned the thread and stripped\n * `activity` messages by the time the input reaches here, so the filter\n * cannot reach the messages the UI renders no matter what it does with the\n * array it is handed. The filter gets a *second* deep clone on top of that,\n * because `input.messages` is also the repair baseline and the untrimmed\n * fallback: sharing the message objects let a filter that mutates a kept\n * message's `toolCallId` corrupt the baseline, and an orphaned tool result\n * then went out on the wire — a payload the provider rejects, which is\n * exactly the failure this whole mechanism exists to prevent.\n */\n #applyMessageFilter(input: RunAgentInput): RunAgentInput {\n const filter = this._messageFilter;\n if (!filter) return input;\n\n // A filter that throws, returns the wrong shape, or hands back entries the\n // repair cannot read falls back to the untrimmed thread rather than\n // failing the run. Trimming is an optimization, and taking the user's\n // message down with it would be the worse outcome; the warning is what\n // surfaces the bug.\n try {\n const kept = filter(structuredClone_(input.messages), {\n agentId: this.agentId ?? \"\",\n });\n if (!Array.isArray(kept)) {\n console.warn(\n \"ProxiedCopilotRuntimeAgent: messageFilter returned a non-array value; sending the full message history instead.\",\n );\n return input;\n }\n return { ...input, messages: ɵrepairToolCallPairs(kept, input.messages) };\n } catch (error) {\n console.warn(\n \"ProxiedCopilotRuntimeAgent: messageFilter failed; sending the full message history instead.\",\n error,\n );\n return input;\n }\n }\n\n override requestInit(input: RunAgentInput): RequestInit {\n const baseInit = super.requestInit(input);\n return {\n ...baseInit,\n ...(this.credentials ? { credentials: this.credentials } : {}),\n };\n }\n\n async getCapabilities(): Promise<AgentCapabilities> {\n return this._capabilities ?? {};\n }\n\n override async detachActiveRun(): Promise<void> {\n if (this.delegate) {\n await this.delegate.detachActiveRun();\n }\n await super.detachActiveRun();\n }\n\n abortRun(): void {\n if (this.delegate) {\n this.syncDelegate(this.delegate);\n this.delegate.abortRun();\n // Also detach the proxy's own runAgent pipeline so the proxy's\n // isRunning resets and onRunFinalized fires even if the delegate's\n // observable doesn't propagate a clean completion.\n void this.detachActiveRun();\n return;\n }\n\n if (!this.agentId || !this.threadId) {\n return;\n }\n\n if (typeof fetch === \"undefined\") {\n return;\n }\n\n const routedId = this.routedAgentId();\n const runId =\n this.activeRun?.threadId === this.threadId\n ? this.activeRun.runId\n : undefined;\n\n if (this.transport === \"single\") {\n if (!this.singleEndpointUrl) {\n return;\n }\n\n const headers = new Headers({\n ...this.headers,\n \"Content-Type\": \"application/json\",\n });\n void fetch(this.singleEndpointUrl, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n method: \"agent/stop\",\n params: {\n agentId: routedId,\n threadId: this.threadId,\n },\n ...(runId === undefined ? {} : { body: { runId } }),\n }),\n ...(this.credentials ? { credentials: this.credentials } : {}),\n }).catch((error) => {\n console.error(\"ProxiedCopilotRuntimeAgent: stop request failed\", error);\n });\n return;\n }\n\n if (!this.runtimeUrl) {\n return;\n }\n\n const stopPath = `${this.runtimeUrl}/agent/${encodeURIComponent(routedId)}/stop/${encodeURIComponent(this.threadId)}`;\n const origin =\n typeof window !== \"undefined\" && window.location\n ? window.location.origin\n : \"http://localhost\";\n const base = new URL(this.runtimeUrl, origin);\n const stopUrl = new URL(stopPath, base);\n\n void fetch(stopUrl.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.headers,\n },\n ...(runId === undefined ? {} : { body: JSON.stringify({ runId }) }),\n ...(this.credentials ? { credentials: this.credentials } : {}),\n }).catch((error) => {\n console.error(\"ProxiedCopilotRuntimeAgent: stop request failed\", error);\n });\n }\n\n override async connectAgent(\n parameters?: RunAgentParameters,\n subscriber?: AgentSubscriber,\n ): Promise<RunAgentResult> {\n if (this.runtimeMode !== RUNTIME_MODE_INTELLIGENCE) {\n // A self-hosted `/connect` response replays the thread's history, so it\n // can carry several past runs — including one that ended in RUN_ERROR\n // followed by a later RUN_STARTED. The base pipeline's `verifyEvents`\n // step enforces single-run lifecycle rules and rejects that stream\n // outright, so an existing thread never hydrates (#4943).\n return ɵconnectWithoutEventVerification(this, parameters, subscriber);\n }\n\n // If the delegate already has an active run (e.g. from a previous\n // connectAgent call that hasn't finished yet), detach it first. This\n // ensures only one run is active on the delegate at a time — without it,\n // two parallel runs would both pump events into the shared delegate,\n // and both bridge subscriptions would copy the interleaved messages to\n // the proxy, causing the UI to flicker between the two conversations.\n if (this.delegate) {\n await this.delegate.detachActiveRun();\n }\n\n // Ensure the delegate exists and is synced with the proxy's current state.\n await this.resolveDelegate();\n const delegate = this.delegate!;\n\n // Subscribe a bridging observer FIRST so it fires before the forwarded\n // UI subscribers. This keeps proxy.messages in sync with the delegate\n // in real-time — otherwise the UI re-renders (triggered by the\n // forwarded onMessagesChanged) but reads stale proxy.messages because\n // the final sync only happens after connectAgent resolves.\n const bridgeSub = delegate.subscribe({\n onMessagesChanged: () => {\n this.setMessages([...delegate.messages]);\n },\n onStateChanged: () => {\n this.setState({ ...delegate.state });\n },\n // Mirror isRunning so the proxy reflects the delegate's run lifecycle.\n // Without this, UI components read proxy.isRunning (always false) even\n // though the delegate is actively running, causing the stop button to\n // never appear.\n onRunInitialized: () => {\n this.isRunning = true;\n },\n onRunFinalized: () => {\n this.isRunning = false;\n },\n // Local exception (network error, deserialization failure, etc.)\n onRunFailed: () => {\n this.isRunning = false;\n },\n // Protocol-level RUN_ERROR event from the backend\n onRunErrorEvent: () => {\n this.isRunning = false;\n },\n });\n\n // Forward the proxy's subscribers to the delegate so that UI hooks\n // (e.g. useAgent's onMessagesChanged) receive real-time updates as\n // the delegate processes events during connectAgent.\n const forwardedSubs = this.subscribers.map((s) => delegate.subscribe(s));\n\n try {\n const result = await delegate.connectAgent(parameters, subscriber);\n\n // Final sync to guarantee the proxy reflects the delegate's end state.\n this.setMessages([...delegate.messages]);\n this.setState({ ...delegate.state });\n\n return result;\n } finally {\n // Ensure the proxy's isRunning is reset — the bridging subscription\n // may have already handled this, but if the delegate threw before\n // firing onRunFinalized the proxy would be stuck in isRunning=true.\n this.isRunning = false;\n // Remove forwarded subscribers to avoid duplicate notifications on\n // subsequent calls (they'll be re-forwarded next time).\n bridgeSub.unsubscribe();\n for (const sub of forwardedSubs) {\n sub.unsubscribe();\n }\n }\n }\n\n connect(input: RunAgentInput): Observable<BaseEvent> {\n if (\n this.runtimeMode === \"pending\" ||\n (this.transport === \"auto\" &&\n this.runtimeMode !== RUNTIME_MODE_INTELLIGENCE)\n ) {\n return defer(() => from(this.ensureRuntimeConfiguration())).pipe(\n switchMap(() => this.connect(input)),\n );\n }\n if (this.runtimeMode === RUNTIME_MODE_INTELLIGENCE) {\n return this.#connectViaDelegate(input);\n }\n return this.#connectViaHttp(input);\n }\n\n public run(input: RunAgentInput): Observable<BaseEvent> {\n if (\n this.runtimeMode === \"pending\" ||\n (this.transport === \"auto\" &&\n this.runtimeMode !== RUNTIME_MODE_INTELLIGENCE)\n ) {\n return defer(() => from(this.ensureRuntimeConfiguration())).pipe(\n switchMap(() => this.run(input)),\n );\n }\n if (this.runtimeMode === RUNTIME_MODE_INTELLIGENCE) {\n return this.#runViaDelegate(input);\n }\n return this.#runViaHttp(input);\n }\n\n #connectViaDelegate(input: RunAgentInput): Observable<BaseEvent> {\n return defer(() => from(this.resolveDelegate())).pipe(\n switchMap((delegate) => withAbortErrorHandling(delegate.connect(input))),\n );\n }\n\n #connectViaHttp(unfiltered: RunAgentInput): Observable<BaseEvent> {\n const input = this.#applyMessageFilter(unfiltered);\n this.activeRun = undefined;\n const routedId = this.routedAgentId();\n if (this.transport === \"single\") {\n if (!this.singleEndpointUrl) {\n throw new Error(\"Single endpoint transport requires a runtimeUrl\");\n }\n\n const requestInit = this.createSingleRouteRequestInit(\n input,\n \"agent/connect\",\n {\n agentId: routedId,\n },\n );\n const httpEvents = runHttpRequest(() =>\n this.fetch(this.singleEndpointUrl!, requestInit),\n );\n return withAbortErrorHandling(transformHttpEventStream(httpEvents));\n }\n\n const connectUrl = `${this.runtimeUrl}/agent/${routedId}/connect`;\n const connectRequestInit = this.requestInit(input);\n const httpEvents = runHttpRequest(() =>\n this.fetch(connectUrl, connectRequestInit),\n );\n return withAbortErrorHandling(transformHttpEventStream(httpEvents));\n }\n\n #runViaDelegate(input: RunAgentInput): Observable<BaseEvent> {\n return defer(() => from(this.resolveDelegate())).pipe(\n switchMap((delegate) => withAbortErrorHandling(delegate.run(input))),\n );\n }\n\n #runViaHttp(unfiltered: RunAgentInput): Observable<BaseEvent> {\n const input = this.#applyMessageFilter(unfiltered);\n const activeRun = { threadId: input.threadId, runId: input.runId };\n // Hold this run's identity for as long as its stream lives. The identity\n // check keeps a late-finalizing stream from releasing a newer run.\n const trackActiveRun = (source: Observable<BaseEvent>) => {\n this.activeRun = activeRun;\n return source.pipe(\n finalize(() => {\n if (this.activeRun === activeRun) this.activeRun = undefined;\n }),\n );\n };\n if (this.transport === \"single\") {\n if (!this.singleEndpointUrl) {\n throw new Error(\"Single endpoint transport requires a runtimeUrl\");\n }\n\n const requestInit = this.createSingleRouteRequestInit(\n input,\n \"agent/run\",\n {\n agentId: this.routedAgentId(),\n },\n );\n const httpEvents = runHttpRequest(() =>\n this.fetch(this.singleEndpointUrl!, requestInit),\n );\n return trackActiveRun(\n withAbortErrorHandling(transformHttpEventStream(httpEvents)),\n );\n }\n\n return trackActiveRun(withAbortErrorHandling(super.run(input)));\n }\n\n public override clone(): ProxiedCopilotRuntimeAgent {\n const cloned = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: this.runtimeEndpointUrl ?? this.runtimeUrl,\n agentId: this.agentId,\n runtimeAgentId: this.runtimeAgentId,\n description: this.description,\n headers: { ...this.headers },\n credentials: this.credentials,\n transport: this.transport,\n runtimeMode: this.runtimeMode,\n intelligence: this.intelligence,\n capabilities: this._capabilities,\n debug: this.debug,\n fetch: this.fetch,\n messageFilter: this._messageFilter,\n });\n cloned.threadId = this.threadId;\n cloned.setState(this.state);\n cloned.setMessages(this.messages);\n if (this.delegate) {\n const clonedDelegate: AbstractAgent = this.delegate.clone();\n cloned.delegate = clonedDelegate;\n cloned.syncDelegate(clonedDelegate);\n }\n return cloned;\n }\n\n /**\n * Drop the delegate's cached `lastSeenEventId` for this thread so\n * the next connect requests a full historical replay from the\n * gateway. Used by `RunHandler.connectAgent` on a detected thread\n * switch (the chat moved between threads, so its local\n * messages/state are about to be cleared and need rebuilding from\n * the gateway). Skipped on same-thread churn re-connects so the\n * gateway can resume from the cursor instead.\n *\n * No-op for non-Intelligence runtime modes — the HTTP transport\n * doesn't replay.\n */\n public clearReplayCursor(threadId: string): void {\n if (this.runtimeMode !== RUNTIME_MODE_INTELLIGENCE) return;\n const delegate = this.delegate as\n | { clearReconnectCursor?: (id: string) => void }\n | null\n | undefined;\n delegate?.clearReconnectCursor?.(threadId);\n }\n\n private async resolveDelegate(): Promise<RunnableAgent> {\n await this.ensureRuntimeConfiguration();\n\n if (!this.delegate) {\n if (this.runtimeMode !== RUNTIME_MODE_INTELLIGENCE) {\n throw new Error(\"A delegate is only created for Intelligence mode\");\n }\n this.delegate = this.createIntelligenceDelegate();\n }\n\n this.syncDelegate(this.delegate);\n\n // AbstractAgent declares connect() as protected, but concrete delegates\n // (IntelligenceAgent, HttpAgent) expose both connect() and run() publicly.\n return this.delegate as unknown as RunnableAgent;\n }\n\n /** Resolve transport and runtime mode before the first outbound request. */\n private async ensureRuntimeConfiguration(): Promise<void> {\n if (\n this.runtimeMode === RUNTIME_MODE_INTELLIGENCE ||\n (this.runtimeMode !== \"pending\" && this.transport !== \"auto\")\n ) {\n return;\n }\n\n if (!this.runtimeUrl) {\n throw new Error(\"Runtime URL is not set\");\n }\n\n const runtimeInfoPromise =\n this.runtimeInfoPromise ??\n this.fetchRuntimeInfo().then((runtimeInfo) => {\n this.runtimeMode = runtimeInfo.mode ?? RUNTIME_MODE_SSE;\n this.intelligence = runtimeInfo.intelligence;\n });\n this.runtimeInfoPromise = runtimeInfoPromise;\n\n try {\n await runtimeInfoPromise;\n } catch (error) {\n if (this.runtimeInfoPromise === runtimeInfoPromise) {\n this.runtimeInfoPromise = undefined;\n }\n throw error;\n }\n }\n\n private async fetchRuntimeInfo(): Promise<RuntimeInfo> {\n const headers: Record<string, string> = {\n ...this.headers,\n };\n\n if (this.transport === \"auto\") {\n return this.fetchRuntimeInfoAutoDetect(headers);\n }\n\n let init: RequestInit;\n let url: string;\n\n if (this.transport === \"single\") {\n if (!this.singleEndpointUrl) {\n throw new Error(\"Single endpoint transport requires a runtimeUrl\");\n }\n if (!headers[\"Content-Type\"]) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n url = this.singleEndpointUrl;\n init = { method: \"POST\", body: JSON.stringify({ method: \"info\" }) };\n } else {\n url = `${this.runtimeUrl}/info`;\n init = {};\n }\n\n const response = await this.fetch(url, {\n ...init,\n headers,\n ...(this.credentials ? { credentials: this.credentials } : {}),\n });\n if (!response.ok) {\n throw await runtimeInfoError(response);\n }\n return (await response.json()) as RuntimeInfo;\n }\n\n private async fetchRuntimeInfoAutoDetect(\n headers: Record<string, string>,\n ): Promise<RuntimeInfo> {\n // Try REST first (GET /info)\n try {\n const response = await this.fetch(`${this.runtimeUrl}/info`, {\n headers: { ...headers },\n ...(this.credentials ? { credentials: this.credentials } : {}),\n });\n // Only treat a successful (2xx) response as a valid REST runtime.\n // 404/405 means the endpoint doesn't exist; other non-2xx errors\n // (500, 403, etc.) should also fall through to single-endpoint.\n if (response.status >= 200 && response.status < 300) {\n this.transport = \"rest\";\n return (await response.json()) as RuntimeInfo;\n }\n } catch {\n // REST failed — fall through to single-endpoint attempt\n }\n\n // Try single-endpoint (POST with { method: \"info\" })\n const singleHeaders = { ...headers };\n if (!singleHeaders[\"Content-Type\"]) {\n singleHeaders[\"Content-Type\"] = \"application/json\";\n }\n const endpointUrl = this.runtimeEndpointUrl ?? this.runtimeUrl!;\n const response = await this.fetch(endpointUrl, {\n method: \"POST\",\n headers: singleHeaders,\n body: JSON.stringify({ method: \"info\" }),\n ...(this.credentials ? { credentials: this.credentials } : {}),\n });\n if (!response.ok) {\n throw await runtimeInfoError(response);\n }\n this.transport = \"single\";\n this.singleEndpointUrl = endpointUrl;\n return (await response.json()) as RuntimeInfo;\n }\n\n private createSingleRouteRequestInit(\n input: RunAgentInput,\n method: string,\n params?: Record<string, string>,\n ): RequestInit {\n if (!this.agentId) {\n throw new Error(\n \"ProxiedCopilotRuntimeAgent requires agentId to make runtime requests\",\n );\n }\n\n const baseInit = super.requestInit(input);\n const headers = new Headers(baseInit.headers ?? {});\n headers.set(\"Content-Type\", \"application/json\");\n headers.set(\"Accept\", headers.get(\"Accept\") ?? \"text/event-stream\");\n\n let originalBody: unknown = undefined;\n if (typeof baseInit.body === \"string\") {\n try {\n originalBody = JSON.parse(baseInit.body);\n } catch (error) {\n console.warn(\n \"ProxiedCopilotRuntimeAgent: failed to parse request body for single route transport\",\n error,\n );\n }\n }\n\n const envelope: Record<string, unknown> = { method };\n\n if (params && Object.keys(params).length > 0) {\n envelope.params = params;\n }\n\n if (originalBody !== undefined) {\n envelope.body = originalBody;\n }\n\n return {\n ...baseInit,\n headers,\n body: JSON.stringify(envelope),\n ...(this.credentials ? { credentials: this.credentials } : {}),\n };\n }\n\n private createIntelligenceDelegate(): AbstractAgent {\n const routedId = this.routedAgentId();\n if (!this.runtimeUrl || !routedId || !this.intelligence?.wsUrl) {\n throw new Error(\n \"Intelligence mode requires runtimeUrl, agentId, and intelligence websocket metadata\",\n );\n }\n\n const single = this.transport === \"single\";\n\n return new IntelligenceAgent({\n url: this.intelligence.wsUrl,\n // Single-route posts to the endpoint itself, so it needs the caller's URL\n // verbatim: a trailing slash can select a different proxy location\n // (issue #7028). REST needs the slash-stripped form, because it joins\n // `/agent/:id/:mode` onto it.\n runtimeUrl: single\n ? (this.runtimeEndpointUrl ?? this.runtimeUrl)\n : this.runtimeUrl,\n transport: single ? \"single\" : \"rest\",\n agentId: routedId,\n headers: { ...this.headers },\n credentials: this.credentials,\n fetch: this.fetch as typeof fetch,\n });\n }\n\n private syncDelegate(delegate: AbstractAgent): void {\n // Delegate is the IntelligenceAgent that talks to the runtime — it must\n // use the routed id so that requests reach the right runtime agent.\n delegate.agentId = this.routedAgentId();\n delegate.description = this.description;\n delegate.threadId = this.threadId;\n delegate.setMessages(this.messages);\n delegate.setState(this.state);\n\n if (hasHeaders(delegate)) {\n delegate.headers = { ...this.headers };\n }\n\n if (hasCredentials(delegate)) {\n delegate.credentials = this.credentials;\n }\n }\n}\n","const ABORT_MESSAGES: ReadonlySet<string> = new Set([\n \"Fetch is aborted\",\n \"signal is aborted without reason\",\n \"component unmounted\",\n]);\n\nexport function isAbortError(error: unknown): boolean {\n if (typeof error !== \"object\" || error === null) {\n return false;\n }\n const { name, message } = error as { name?: unknown; message?: unknown };\n if (name === \"AbortError\") {\n return true;\n }\n return typeof message === \"string\" && ABORT_MESSAGES.has(message);\n}\n","export const RUNTIME_REQUEST_WATCHDOG_MS = 10_000;\n\nexport interface RuntimeRequestMeta {\n nonCritical?: boolean;\n selfBounded?: boolean;\n timedOut?: boolean;\n}\n\nexport interface RuntimeRequestInit extends RequestInit {\n ɵruntimeRequest?: RuntimeRequestMeta;\n}\n\nexport function runtimeRequestMeta(\n init?: RequestInit,\n): RuntimeRequestMeta | undefined {\n return (init as RuntimeRequestInit | undefined)?.ɵruntimeRequest;\n}\n","interface SingleRouteResourceRequest {\n input: RequestInfo | URL;\n init: RequestInit;\n}\n\n/** Returns true when a path belongs to an Intelligence resource API. */\nfunction isIntelligenceResourcePath(path: string): boolean {\n return (\n path === \"/threads\" ||\n path.startsWith(\"/threads/\") ||\n path === \"/memories\" ||\n path.startsWith(\"/memories/\") ||\n path === \"/annotate\"\n );\n}\n\n/** Reads a JSON resource body without changing invalid JSON error behavior. */\nasync function readResourceBody(\n input: RequestInfo | URL,\n init: RequestInit | undefined,\n headers: Headers,\n method: string,\n): Promise<unknown | undefined> {\n if (method === \"GET\" || method === \"HEAD\") return undefined;\n\n let text: string | undefined;\n if (init?.body != null) {\n text = await new Response(init.body).text();\n } else if (input instanceof Request) {\n text = await input.clone().text();\n }\n if (!text) return undefined;\n\n if (headers.get(\"content-type\")?.toLowerCase().includes(\"application/json\")) {\n try {\n return JSON.parse(text) as unknown;\n } catch {\n return text;\n }\n }\n return text;\n}\n\n/**\n * Converts one Runtime resource fetch into a single-route JSON envelope.\n * Requests outside the mounted Runtime or outside its resource APIs pass\n * through unchanged.\n */\nexport async function createSingleRouteResourceRequest(\n input: RequestInfo | URL,\n init: RequestInit | undefined,\n runtimeUrl: string,\n): Promise<SingleRouteResourceRequest | null> {\n const baseUrl =\n typeof window !== \"undefined\" && window.location?.href\n ? window.location.href\n : \"http://localhost\";\n const runtime = new URL(runtimeUrl, baseUrl);\n const inputUrl =\n input instanceof Request\n ? input.url\n : input instanceof URL\n ? input.href\n : input;\n const target = new URL(inputUrl, baseUrl);\n const runtimePath = runtime.pathname.replace(/\\/$/, \"\");\n if (target.origin !== runtime.origin) return null;\n if (!target.pathname.startsWith(`${runtimePath}/`)) return null;\n\n const resourcePath = target.pathname.slice(runtimePath.length);\n if (!isIntelligenceResourcePath(resourcePath)) return null;\n\n const method = (\n init?.method ?? (input instanceof Request ? input.method : \"GET\")\n ).toUpperCase();\n const headers = new Headers(\n init?.headers ?? (input instanceof Request ? input.headers : undefined),\n );\n const body = await readResourceBody(input, init, headers, method);\n headers.set(\"content-type\", \"application/json\");\n headers.delete(\"content-length\");\n\n const requestDefaults: RequestInit =\n input instanceof Request\n ? {\n cache: input.cache,\n credentials: input.credentials,\n integrity: input.integrity,\n keepalive: input.keepalive,\n mode: input.mode,\n redirect: input.redirect,\n referrer: input.referrer,\n referrerPolicy: input.referrerPolicy,\n signal: input.signal,\n }\n : {};\n\n return {\n input: runtimeUrl,\n init: {\n ...requestDefaults,\n ...init,\n method: \"POST\",\n headers,\n body: JSON.stringify({\n method: \"resource/request\",\n params: {\n path: `${resourcePath}${target.search}`,\n httpMethod: method,\n },\n ...(body === undefined ? {} : { body }),\n }),\n },\n };\n}\n","import type { AbstractAgent } from \"@ag-ui/client\";\nimport { HttpAgent } from \"@ag-ui/client\";\nimport type {\n RuntimeInfo,\n RuntimeMode,\n RuntimeLicenseStatus,\n RuntimeEntitlementResponse,\n IntelligenceRuntimeInfo,\n InspectorMetadataV1,\n ThreadEndpointRuntimeInfo,\n} from \"@copilotkit/shared\";\nimport {\n logger,\n parseInspectorMetadataV1,\n RUNTIME_MODE_SSE,\n resolveDebugConfig,\n} from \"@copilotkit/shared\";\nimport { ProxiedCopilotRuntimeAgent } from \"../agent\";\nimport type { CopilotKitCore, CopilotKitCoreFriendsAccess } from \"./core\";\nimport {\n CopilotKitCoreErrorCode,\n CopilotKitCoreRuntimeConnectionStatus,\n} from \"./core\";\nimport type { CopilotRuntimeTransport } from \"../types\";\nimport {\n isRuntimeInfoRequestError,\n runtimeInfoError,\n} from \"../utils/runtime-info-error\";\nimport { isAbortError } from \"../utils/abort-error\";\nimport type { RuntimeRequestMeta } from \"../utils/runtime-request\";\nimport {\n RUNTIME_REQUEST_WATCHDOG_MS,\n runtimeRequestMeta,\n} from \"../utils/runtime-request\";\nimport { createSingleRouteResourceRequest } from \"../utils/single-route-resource-request\";\n\ntype ResolvedCopilotRuntimeTransport = Exclude<CopilotRuntimeTransport, \"auto\">;\n\ntype RuntimeInfoFetchResult = {\n runtimeInfo: RuntimeInfo;\n resolvedTransport: ResolvedCopilotRuntimeTransport;\n};\n\n/** Maximum wait for optional Inspector metadata before degrading to absence. */\nconst INSPECTOR_METADATA_REQUEST_TIMEOUT_MS = 5_000;\n\nexport const ɵRUNTIME_PROBE_TIMEOUT_MS = 5_000;\n\ntype RuntimeRequestOutcome = \"ok\" | \"failed\" | \"aborted\" | \"ignored\";\n\nfunction classifyRuntimeRequestFailure(\n error: unknown,\n meta: RuntimeRequestMeta | undefined,\n): RuntimeRequestOutcome {\n if (meta?.nonCritical) {\n return \"ignored\";\n }\n if (isAbortError(error) && !meta?.timedOut) {\n return \"aborted\";\n }\n return \"failed\";\n}\n\ninterface RuntimeConnectionOptions {\n preserveOnFailure?: boolean;\n recovery?: boolean;\n}\n\n/** Build case-insensitive JSON headers without mutating the Core snapshot. */\nfunction withJsonContentType(headers: Record<string, string>): Headers {\n const requestHeaders = new Headers(headers);\n if (!requestHeaders.has(\"content-type\")) {\n requestHeaders.set(\"content-type\", \"application/json\");\n }\n return requestHeaders;\n}\n\nconst RUNTIME_ENTITLEMENT_RETRY_DELAY_MS = 5_000;\n\ninterface RuntimeConnectionAttempt {\n key: string;\n generation: number;\n}\n\ninterface RuntimeAgentConnection {\n runtimeUrl: string;\n /** The caller-supplied URL the proxy was built with (trailing slash intact). */\n endpointUrl?: string;\n transport: CopilotRuntimeTransport;\n}\n\nexport interface CopilotKitCoreAddAgentParams {\n id: string;\n agent: AbstractAgent;\n}\n\n/**\n * Parameters for registering a proxied agent against an existing runtime agent.\n */\nexport interface CopilotKitCoreRegisterProxiedAgentParams {\n /**\n * The local registry id under which the proxy is registered. Used by\n * `useAgent`, state-manager subscriptions, and all subscriber bookkeeping.\n * Must not collide with any existing local or runtime-discovered agent id.\n */\n agentId: string;\n /**\n * The id of the runtime agent that this proxy routes outbound HTTP requests\n * to. Invisible to subscribers — only affects URL paths and single-route\n * envelopes.\n */\n runtimeAgentId: string;\n}\n\nexport interface CopilotKitCoreRegisterProxiedAgentResult {\n agent: ProxiedCopilotRuntimeAgent;\n unregister: () => void;\n}\n\n/**\n * Manages agent registration, lifecycle, and runtime connectivity for CopilotKitCore.\n * Handles both local development agents and remote runtime agents.\n */\nexport class AgentRegistry {\n private _agents: Record<string, AbstractAgent> = {};\n private localAgents: Record<string, AbstractAgent> = {};\n private remoteAgents: Record<string, AbstractAgent> = {};\n\n private readonly mintedThreadIds = new WeakMap<AbstractAgent, string>();\n\n private _runtimeUrl?: string;\n /** The runtime URL as the caller supplied it; the single-route endpoint uses it verbatim. */\n private _runtimeEndpointUrl?: string;\n // Tracks an in-flight `/info` connection so concurrent calls targeting the\n // same runtime (url + requested transport) collapse to a single request\n // instead of each firing their own. See #5801.\n private _connectionInFlight?: {\n attempt: RuntimeConnectionAttempt;\n promise: Promise<void>;\n };\n private _runtimeConnectionGeneration = 0;\n private _activeRuntimeConnectionAttempt?: RuntimeConnectionAttempt;\n private _runtimeEntitlementRetryTimer?: ReturnType<typeof setTimeout>;\n private _runtimeEntitlementRetryAttemptedKey?: string;\n private _runtimeEntitlementRetryPendingKey?: string;\n private _runtimeVersion?: string;\n private _runtimeConnectionStatus: CopilotKitCoreRuntimeConnectionStatus =\n CopilotKitCoreRuntimeConnectionStatus.Disconnected;\n private _runtimeTransport: CopilotRuntimeTransport = \"auto\";\n // The transport MODE last requested via `setRuntimeTransport` (e.g. \"auto\").\n // Distinct from `_runtimeTransport`, which auto-detect overwrites with the\n // RESOLVED value (\"rest\"/\"single\"). The idempotency guard compares against\n // this so re-applying the same mode (the provider effect re-applies \"auto\"\n // on every render) is a no-op instead of re-running the /info handshake.\n private _requestedTransport: CopilotRuntimeTransport = \"auto\";\n private _audioFileTranscriptionEnabled: boolean = false;\n private _runtimeMode: RuntimeMode = RUNTIME_MODE_SSE;\n private _intelligence?: IntelligenceRuntimeInfo;\n private _threadEndpoints?: ThreadEndpointRuntimeInfo;\n private _singleRouteResourceOperations = false;\n private _suggestions?: boolean;\n private _inspectorLearning: boolean = false;\n private _inspectorMetadata?: InspectorMetadataV1;\n private _inspectorMetadataSupported: boolean = false;\n private inspectorMetadataRefreshReady: boolean = false;\n private inspectorMetadataConnectionGeneration: number = 0;\n private inspectorMetadataGeneration: number = 0;\n private inspectorMetadataHeadersGeneration: number = 0;\n private inspectorMetadataCredentialsGeneration: number = 0;\n private inspectorMetadataAbortController?: AbortController;\n private inspectorMetadataNotificationQueue: Promise<void> = Promise.resolve();\n private _a2uiEnabled: boolean = false;\n private _a2uiAgents?: string[];\n private _openGenerativeUIEnabled: boolean = false;\n private _licenseStatus?: RuntimeLicenseStatus;\n private _runtimeEntitlements?: RuntimeEntitlementResponse;\n private _telemetryDisabled: boolean = false;\n private remoteAgentConnections = new WeakMap<\n ProxiedCopilotRuntimeAgent,\n RuntimeAgentConnection\n >();\n\n private runtimeFetch?: typeof fetch;\n private runtimeProbeInFlight: boolean = false;\n private runtimeProbeToken: number = 0;\n private runtimeProbeAbortController?: AbortController;\n private runtimeRecoveryRunning: boolean = false;\n private runtimeRecoveryPending: boolean = false;\n private runtimeHealthGeneration: number = 0;\n\n /**\n * The headers each HttpAgent was constructed with, captured on the first\n * `applyHeadersToAgent` call for that agent (which, for agents the registry\n * owns, happens at registration before any core headers are applied). Core\n * headers are merged ON TOP of this baseline so that headers configured\n * directly on an agent (e.g. an `Authorization` for a self-hosted backend)\n * survive registration instead of being silently replaced. The baseline is\n * captured once and never re-captured, so a later direct mutation of\n * `agent.headers` is not folded into it. See #5635.\n */\n private agentOwnHeaders = new WeakMap<HttpAgent, Record<string, string>>();\n\n constructor(private core: CopilotKitCore) {}\n\n /**\n * Get all agents as a readonly record\n */\n get agents(): Readonly<Record<string, AbstractAgent>> {\n return this._agents;\n }\n\n get runtimeUrl(): string | undefined {\n return this._runtimeUrl;\n }\n\n get runtimeVersion(): string | undefined {\n return this._runtimeVersion;\n }\n\n get runtimeConnectionStatus(): CopilotKitCoreRuntimeConnectionStatus {\n return this._runtimeConnectionStatus;\n }\n\n get runtimeTransport(): CopilotRuntimeTransport {\n return this._runtimeTransport;\n }\n\n get audioFileTranscriptionEnabled(): boolean {\n return this._audioFileTranscriptionEnabled;\n }\n\n get runtimeMode(): RuntimeMode {\n return this._runtimeMode;\n }\n\n get intelligence(): IntelligenceRuntimeInfo | undefined {\n return this._intelligence;\n }\n\n get threadEndpoints(): ThreadEndpointRuntimeInfo | undefined {\n return this._threadEndpoints;\n }\n\n get suggestions(): boolean | undefined {\n return this._suggestions;\n }\n\n get inspectorLearning(): boolean {\n return this._inspectorLearning;\n }\n\n get inspectorMetadata(): InspectorMetadataV1 | undefined {\n return this._inspectorMetadata;\n }\n\n get a2uiEnabled(): boolean {\n return this._a2uiEnabled;\n }\n\n /**\n * Agent ids the runtime applies A2UI to (#5369). `undefined` means A2UI\n * applies to every agent — or is disabled entirely; check `a2uiEnabled`.\n */\n get a2uiAgents(): string[] | undefined {\n return this._a2uiAgents;\n }\n\n get openGenerativeUIEnabled(): boolean {\n return this._openGenerativeUIEnabled;\n }\n\n get licenseStatus(): RuntimeLicenseStatus | undefined {\n return this._licenseStatus;\n }\n\n /** Structured Runtime entitlement authority advertised by `/info`. */\n get runtimeEntitlements(): RuntimeEntitlementResponse | undefined {\n return this._runtimeEntitlements;\n }\n\n get runtimeEntitlementRetryPending(): boolean {\n return (\n this._runtimeEntitlementRetryPendingKey === this.runtimeConnectionKey()\n );\n }\n\n get telemetryDisabled(): boolean {\n return this._telemetryDisabled;\n }\n\n /**\n * Initialize agents from configuration\n */\n initialize(agents: Record<string, AbstractAgent>): void {\n this.localAgents = this.assignAgentIds(agents);\n this.applyHeadersToAgents(this.localAgents);\n this.applyCredentialsToAgents(this.localAgents);\n this.applyMessageFilterToAgents(this.localAgents);\n this.applyRuntimeFetchToAgents(this.localAgents);\n this._agents = this.localAgents;\n }\n\n /**\n * Set the runtime URL and update connection\n */\n setRuntimeUrl(\n runtimeUrl: string | undefined,\n options?: { deferConnection?: boolean },\n ): void {\n const normalizedRuntimeUrl = runtimeUrl\n ? runtimeUrl.replace(/\\/$/, \"\")\n : undefined;\n const runtimeEndpointUrl = runtimeUrl || undefined;\n\n if (\n this._runtimeUrl === normalizedRuntimeUrl &&\n this._runtimeEndpointUrl === runtimeEndpointUrl\n ) {\n return;\n }\n\n this.invalidateInspectorMetadataConnection();\n this.abandonRuntimeHealthProbe();\n this.resetRuntimeEntitlementRetry();\n // Runtime authority is scoped to the target that advertised it. Clear it\n // before subscribers observe the replacement target connecting.\n this._licenseStatus = undefined;\n this._runtimeEntitlements = undefined;\n this._singleRouteResourceOperations = false;\n this._runtimeUrl = normalizedRuntimeUrl;\n this._runtimeEndpointUrl = runtimeEndpointUrl;\n\n // Deferred construction (see CopilotKitCore.connect / #5801): record the URL\n // so getters/hooks see it synchronously, but do NOT start the `/info` fetch\n // here. The host starts it from a commit-phase effect via `connect()`, so\n // renders discarded before commit never issue a request.\n if (options?.deferConnection) {\n return;\n }\n\n void this.updateRuntimeConnection({\n preserveOnFailure: this.hasLiveRuntimeKnowledgeToProtect(),\n });\n }\n\n /**\n * Start the initial runtime connection if it has not been started yet.\n *\n * Backs {@link CopilotKitCore.connect}. Idempotent: it only kicks off a fetch\n * when a `runtimeUrl` is set and the connection is still `Disconnected` (its\n * state before any connect attempt). `updateRuntimeConnection` flips the\n * status to `Connecting` synchronously, so a second call — e.g. React\n * StrictMode double-invoking the mount effect — bails here. A genuine config\n * change still reconnects through `setRuntimeUrl`/`setRuntimeTransport`. See\n * #5801.\n */\n connectRuntime(): void {\n if (typeof window === \"undefined\") {\n return;\n }\n if (!this._runtimeUrl) {\n return;\n }\n if (\n this._runtimeConnectionStatus !==\n CopilotKitCoreRuntimeConnectionStatus.Disconnected\n ) {\n return;\n }\n void this.updateRuntimeConnection();\n }\n\n setRuntimeTransport(runtimeTransport: CopilotRuntimeTransport): void {\n // Guard on the requested MODE, not the resolved value: after auto-detect\n // writes `_runtimeTransport = \"rest\"`, re-applying the same requested\n // \"auto\" must not be treated as a change (otherwise every provider\n // re-render re-runs the /info handshake and rebuilds agents).\n if (this._requestedTransport === runtimeTransport) {\n return;\n }\n\n this.invalidateInspectorMetadataConnection();\n this.abandonRuntimeHealthProbe();\n this.resetRuntimeEntitlementRetry();\n this._requestedTransport = runtimeTransport;\n this._runtimeTransport = runtimeTransport;\n this._singleRouteResourceOperations = false;\n void this.updateRuntimeConnection({\n preserveOnFailure: this.hasLiveRuntimeKnowledgeToProtect(),\n });\n }\n\n private hasLiveRuntimeKnowledgeToProtect(): boolean {\n if (Object.keys(this.remoteAgents).length === 0) {\n return false;\n }\n return (\n this._runtimeConnectionStatus !==\n CopilotKitCoreRuntimeConnectionStatus.Connected\n );\n }\n\n private reconcileRecoveredAgents(\n reported: Record<string, AbstractAgent>,\n ): Record<string, AbstractAgent> {\n const merged = { ...this.remoteAgents, ...reported };\n if (Object.keys(reported).length === 0) {\n return merged;\n }\n for (const [id, agent] of Object.entries(merged)) {\n if (Object.prototype.hasOwnProperty.call(reported, id)) {\n continue;\n }\n if (this.carriesConversationState(agent)) {\n continue;\n }\n delete merged[id];\n }\n return merged;\n }\n\n private carriesConversationState(agent: AbstractAgent): boolean {\n if (agent.messages.length > 0) {\n return true;\n }\n const mintedThreadId = this.mintedThreadIds.get(agent);\n return mintedThreadId === undefined || agent.threadId !== mintedThreadId;\n }\n\n private abandonRuntimeHealthProbe(): void {\n this.runtimeProbeToken += 1;\n this.runtimeProbeInFlight = false;\n this.runtimeHealthGeneration += 1;\n this.runtimeProbeAbortController?.abort();\n this.runtimeProbeAbortController = undefined;\n }\n\n /**\n * Set all agents at once (for development use)\n */\n setAgents__unsafe_dev_only(agents: Record<string, AbstractAgent>): void {\n // Validate all agents before making any changes\n Object.entries(agents).forEach(([id, agent]) => {\n if (agent) {\n this.validateAndAssignAgentId(id, agent);\n }\n });\n this.localAgents = agents;\n this._agents = { ...this.localAgents, ...this.remoteAgents };\n this.applyHeadersToAgents(this._agents);\n this.applyCredentialsToAgents(this._agents);\n this.applyMessageFilterToAgents(this._agents);\n this.applyRuntimeFetchToAgents(this._agents);\n void this.notifyAgentsChanged();\n }\n\n /**\n * Add a single agent (for development use)\n */\n addAgent__unsafe_dev_only({ id, agent }: CopilotKitCoreAddAgentParams): void {\n this.validateAndAssignAgentId(id, agent);\n this.localAgents[id] = agent;\n this.applyHeadersToAgent(agent);\n this.applyCredentialsToAgent(agent);\n this.applyRuntimeFetchToAgent(agent);\n this._agents = { ...this.localAgents, ...this.remoteAgents };\n void this.notifyAgentsChanged();\n }\n\n /**\n * Remove an agent by ID (for development use)\n */\n removeAgent__unsafe_dev_only(id: string): void {\n delete this.localAgents[id];\n this._agents = { ...this.localAgents, ...this.remoteAgents };\n void this.notifyAgentsChanged();\n }\n\n /**\n * Register a proxied agent that routes outbound runtime requests to an\n * existing runtime agent (`runtimeAgentId`) while exposing a distinct local\n * registry id (`agentId`). Throws if `agentId` is already taken by either a\n * local or runtime-discovered agent.\n *\n * Use this to mount multiple frontend agents against a single runtime\n * agent (e.g. a chat-1 / chat-2 pair both proxying to \"default\") without\n * implicit per-thread cloning. The returned `unregister` removes the proxy\n * from the registry and emits `onAgentsChanged`.\n */\n registerProxiedAgent({\n agentId,\n runtimeAgentId,\n }: CopilotKitCoreRegisterProxiedAgentParams): CopilotKitCoreRegisterProxiedAgentResult {\n // Use hasOwnProperty rather than `in`: `in` walks the prototype chain,\n // so an agentId of \"__proto__\", \"constructor\", \"toString\" etc. would\n // falsely test as already-registered.\n if (Object.prototype.hasOwnProperty.call(this._agents, agentId)) {\n throw new Error(\n `CopilotKitCore.registerProxiedAgent: agentId \"${agentId}\" is already registered. ` +\n `Pick a different agentId, or unregister the existing agent first.`,\n );\n }\n\n const friends = this.core as unknown as CopilotKitCoreFriendsAccess;\n const debug = friends.debug;\n const agent = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: this._runtimeEndpointUrl ?? this._runtimeUrl,\n agentId,\n runtimeAgentId,\n transport: this._runtimeTransport,\n credentials: friends.credentials,\n // If runtime info has already synced, mirror its mode/intelligence so\n // the proxy doesn't have to re-resolve. Otherwise stay \"pending\" until\n // /info lands.\n runtimeMode: this._runtimeUrl\n ? this._runtimeConnectionStatus ===\n CopilotKitCoreRuntimeConnectionStatus.Connected\n ? this._runtimeMode\n : \"pending\"\n : RUNTIME_MODE_SSE,\n intelligence: this._intelligence,\n debug: debug ? resolveDebugConfig(debug) : undefined,\n messageFilter: friends.messageFilter,\n });\n this.applyHeadersToAgent(agent);\n this.applyRuntimeFetchToAgent(agent);\n\n this.localAgents[agentId] = agent;\n this._agents = { ...this.localAgents, ...this.remoteAgents };\n void this.notifyAgentsChanged();\n\n return {\n agent,\n unregister: () => {\n // Only unregister if the same instance is still in place — guards\n // against double-unregister or against unregistering after a\n // subsequent register replaced the slot.\n if (this.localAgents[agentId] === agent) {\n delete this.localAgents[agentId];\n this._agents = { ...this.localAgents, ...this.remoteAgents };\n void this.notifyAgentsChanged();\n }\n },\n };\n }\n\n /**\n * Get an agent by ID\n */\n getAgent(id: string): AbstractAgent | undefined {\n if (id in this._agents) {\n return this._agents[id] as AbstractAgent;\n }\n\n // Silently return undefined if we're still loading runtime agents\n if (\n this.runtimeUrl !== undefined &&\n (this.runtimeConnectionStatus ===\n CopilotKitCoreRuntimeConnectionStatus.Disconnected ||\n this.runtimeConnectionStatus ===\n CopilotKitCoreRuntimeConnectionStatus.Connecting)\n ) {\n return undefined;\n }\n\n console.warn(`Agent ${id} not found`);\n return undefined;\n }\n\n /**\n * Apply current core headers to an agent, merged ON TOP of the agent's own\n * construction-time headers (the per-agent baseline in `agentOwnHeaders`).\n * Core wins on a key conflict. Non-`HttpAgent` agents are left untouched\n * because only `HttpAgent` carries a `headers` field. See #5635.\n */\n applyHeadersToAgent(agent: AbstractAgent): void {\n if (agent instanceof HttpAgent) {\n // Capture the agent's construction-time headers once, before any core\n // headers overwrite them. On every subsequent apply we rebuild from this\n // baseline so re-applying core headers (e.g. via setHeaders) never loses\n // the agent's own headers.\n if (!this.agentOwnHeaders.has(agent)) {\n this.agentOwnHeaders.set(agent, { ...agent.headers });\n }\n agent.headers = {\n ...this.agentOwnHeaders.get(agent),\n ...(this.core as unknown as CopilotKitCoreFriendsAccess).headers,\n };\n }\n }\n\n /**\n * Apply current headers to all agents\n */\n applyHeadersToAgents(agents: Record<string, AbstractAgent>): void {\n Object.values(agents).forEach((agent) => {\n this.applyHeadersToAgent(agent);\n });\n }\n\n /**\n * Apply current credentials to an agent\n */\n applyCredentialsToAgent(agent: AbstractAgent): void {\n if (agent instanceof ProxiedCopilotRuntimeAgent) {\n agent.credentials = (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).credentials;\n }\n }\n\n /**\n * Apply current credentials to all agents\n */\n applyCredentialsToAgents(agents: Record<string, AbstractAgent>): void {\n Object.values(agents).forEach((agent) => {\n this.applyCredentialsToAgent(agent);\n });\n }\n\n /**\n * Carry the mode a fresh `/info` reported onto a proxy this re-sync kept.\n *\n * `canReuseRuntimeAgent` deliberately ignores the mode: a preserved proxy is\n * backing an open conversation, and replacing the instance to change one\n * field would drop it. The mode is therefore pushed onto the survivor here,\n * the same way headers and credentials are. Without it the mode was fixed at\n * construction, so a runtime that flipped `intelligence` → `sse` under an\n * open page left every later run on the delegate path. See #7130.\n */\n applyRuntimeModeToAgent(\n agent: AbstractAgent,\n runtimeInfo: RuntimeInfo,\n ): void {\n if (agent instanceof ProxiedCopilotRuntimeAgent) {\n agent.adoptRuntimeMode(\n runtimeInfo.mode ?? RUNTIME_MODE_SSE,\n runtimeInfo.intelligence,\n );\n }\n }\n\n /**\n * Apply the core's message filter to an agent.\n *\n * The test is the class, not which bucket the agent is registered in: every\n * `ProxiedCopilotRuntimeAgent` gets the core filter, whether it came from\n * `/info` or from `registerProxiedAgent` (which files its proxy under\n * `localAgents`). Agents of any other class are left untouched — an\n * `AbstractAgent` the app built has no such hook, and its owner already has\n * the AG-UI middleware seam.\n *\n * This is the sole writer of `agent.messageFilter` in normal operation. The\n * public setter exists for the registry and for tests; a value written\n * directly onto an agent is replaced the next time the registry sweeps, the\n * same way per-agent credentials are.\n */\n applyMessageFilterToAgent(agent: AbstractAgent): void {\n if (agent instanceof ProxiedCopilotRuntimeAgent) {\n agent.messageFilter = (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).messageFilter;\n }\n }\n\n /**\n * Apply the core's message filter to all agents\n */\n applyMessageFilterToAgents(agents: Record<string, AbstractAgent>): void {\n Object.values(agents).forEach((agent) => {\n this.applyMessageFilterToAgent(agent);\n });\n }\n\n createRuntimeFetch(): typeof fetch {\n if (!this.runtimeFetch) {\n this.runtimeFetch = (async (\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> => {\n const meta = () => runtimeRequestMeta(init);\n const watchdog = this.armRuntimeRequestWatchdog(meta());\n try {\n const singleRouteRequest =\n this._runtimeTransport === \"single\" &&\n this._singleRouteResourceOperations &&\n this._runtimeUrl\n ? await createSingleRouteResourceRequest(\n input,\n init,\n // The endpoint itself is the POST target here, so it has to be\n // the caller's URL verbatim - a trailing slash can select a\n // different proxy location. `_runtimeUrl` is the slash-stripped\n // form kept for path joins (issue #7028).\n this._runtimeEndpointUrl ?? this._runtimeUrl,\n )\n : null;\n const response = singleRouteRequest\n ? await fetch(singleRouteRequest.input, singleRouteRequest.init)\n : await fetch(input, init);\n watchdog.clear();\n this.handleRuntimeRequestOutcome(\n response.ok ? \"ok\" : meta()?.nonCritical ? \"ignored\" : \"failed\",\n watchdog.checked,\n );\n return response;\n } catch (error) {\n watchdog.clear();\n this.handleRuntimeRequestOutcome(\n classifyRuntimeRequestFailure(error, meta()),\n watchdog.checked,\n );\n throw error;\n }\n }) as typeof fetch;\n }\n return this.runtimeFetch;\n }\n\n private armRuntimeRequestWatchdog(meta: RuntimeRequestMeta | undefined): {\n clear: () => void;\n checked: () => boolean;\n } {\n if (\n typeof window === \"undefined\" ||\n meta?.nonCritical ||\n meta?.selfBounded\n ) {\n return { clear: () => {}, checked: () => false };\n }\n let checked = false;\n const timeoutId = setTimeout(() => {\n checked = this.handleRuntimeRequestOutcome(\"failed\");\n }, RUNTIME_REQUEST_WATCHDOG_MS);\n return {\n clear: () => clearTimeout(timeoutId),\n checked: () => checked,\n };\n }\n\n applyRuntimeFetchToAgent(agent: AbstractAgent): void {\n if (agent instanceof ProxiedCopilotRuntimeAgent) {\n agent.fetch = this.createRuntimeFetch();\n }\n }\n\n applyRuntimeFetchToAgents(agents: Record<string, AbstractAgent>): void {\n Object.values(agents).forEach((agent) => {\n this.applyRuntimeFetchToAgent(agent);\n });\n }\n\n /** Refresh metadata after the Core header snapshot changes. */\n handleHeadersChanged(): void {\n this.inspectorMetadataHeadersGeneration += 1;\n this.setInspectorMetadata(undefined);\n void this.refreshInspectorMetadata();\n }\n\n /** Refresh metadata after the Core credentials mode changes. */\n handleCredentialsChanged(): void {\n this.inspectorMetadataCredentialsGeneration += 1;\n this.setInspectorMetadata(undefined);\n void this.refreshInspectorMetadata();\n }\n\n /**\n * Fetch trusted inspector metadata independently from runtime discovery.\n * Optional-route failures degrade to absent metadata and never affect the\n * runtime connection state.\n */\n async refreshInspectorMetadata(): Promise<void> {\n const generation = ++this.inspectorMetadataGeneration;\n this.inspectorMetadataAbortController?.abort();\n this.inspectorMetadataAbortController = undefined;\n\n if (\n !this._inspectorMetadataSupported ||\n !this.inspectorMetadataRefreshReady ||\n !this.runtimeUrl ||\n this._runtimeConnectionStatus !==\n CopilotKitCoreRuntimeConnectionStatus.Connected\n ) {\n this.setInspectorMetadata(undefined);\n return;\n }\n\n const runtimeUrl = this.runtimeUrl;\n const requestedTransport = this._requestedTransport;\n const resolvedTransport = this._runtimeTransport;\n const headersGeneration = this.inspectorMetadataHeadersGeneration;\n const credentialsGeneration = this.inspectorMetadataCredentialsGeneration;\n const friends = this.core as unknown as CopilotKitCoreFriendsAccess;\n const headers = { ...friends.headers };\n const credentials = friends.credentials;\n const abortController = new AbortController();\n this.inspectorMetadataAbortController = abortController;\n\n let timedOut = false;\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n let rejectForAbort: ((reason: Error) => void) | undefined;\n const aborted = new Promise<never>((_resolve, reject) => {\n rejectForAbort = reject;\n });\n const handleAbort = () => {\n rejectForAbort?.(new Error(\"Inspector metadata request aborted\"));\n };\n abortController.signal.addEventListener(\"abort\", handleAbort, {\n once: true,\n });\n const timeout = new Promise<never>((_resolve, reject) => {\n timeoutId = setTimeout(() => {\n timedOut = true;\n reject(new Error(\"Inspector metadata request timed out\"));\n abortController.abort();\n }, INSPECTOR_METADATA_REQUEST_TIMEOUT_MS);\n });\n\n let nextMetadata: InspectorMetadataV1 | undefined;\n try {\n const request = (async () => {\n const response =\n resolvedTransport === \"single\"\n ? await this.fetchInspectorMetadataSingle({\n runtimeUrl: this.singleEndpointUrlFor(runtimeUrl),\n headers,\n credentials,\n signal: abortController.signal,\n })\n : await this.fetchInspectorMetadataRest({\n runtimeUrl,\n headers,\n credentials,\n signal: abortController.signal,\n });\n\n if (response.status === 204 || !response.ok) {\n return undefined;\n }\n return parseInspectorMetadataV1(await response.json());\n })();\n nextMetadata = await Promise.race([request, aborted, timeout]);\n } catch {\n nextMetadata = undefined;\n } finally {\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n }\n abortController.signal.removeEventListener(\"abort\", handleAbort);\n }\n\n if (\n !this.isInspectorMetadataRequestCurrent({\n generation,\n runtimeUrl,\n requestedTransport,\n resolvedTransport,\n headersGeneration,\n credentialsGeneration,\n signal: abortController.signal,\n allowAbortedSignal: timedOut,\n })\n ) {\n return;\n }\n\n this.inspectorMetadataAbortController = undefined;\n this.setInspectorMetadata(nextMetadata);\n }\n\n private async fetchInspectorMetadataRest({\n runtimeUrl,\n headers,\n credentials,\n signal,\n }: {\n runtimeUrl: string;\n headers: Record<string, string>;\n credentials: RequestCredentials | undefined;\n signal: AbortSignal;\n }): Promise<Response> {\n return fetch(`${runtimeUrl}/inspector-metadata`, {\n method: \"GET\",\n headers,\n ...(credentials ? { credentials } : {}),\n signal,\n });\n }\n\n private async fetchInspectorMetadataSingle({\n runtimeUrl,\n headers,\n credentials,\n signal,\n }: {\n runtimeUrl: string;\n headers: Record<string, string>;\n credentials: RequestCredentials | undefined;\n signal: AbortSignal;\n }): Promise<Response> {\n return fetch(runtimeUrl, {\n method: \"POST\",\n headers: withJsonContentType(headers),\n body: JSON.stringify({ method: \"inspector/metadata\" }),\n ...(credentials ? { credentials } : {}),\n signal,\n });\n }\n\n private isInspectorMetadataRequestCurrent({\n generation,\n runtimeUrl,\n requestedTransport,\n resolvedTransport,\n headersGeneration,\n credentialsGeneration,\n signal,\n allowAbortedSignal = false,\n }: {\n generation: number;\n runtimeUrl: string;\n requestedTransport: CopilotRuntimeTransport;\n resolvedTransport: CopilotRuntimeTransport;\n headersGeneration: number;\n credentialsGeneration: number;\n signal: AbortSignal;\n allowAbortedSignal?: boolean;\n }): boolean {\n return (\n (allowAbortedSignal || !signal.aborted) &&\n generation === this.inspectorMetadataGeneration &&\n runtimeUrl === this.runtimeUrl &&\n requestedTransport === this._requestedTransport &&\n resolvedTransport === this._runtimeTransport &&\n headersGeneration === this.inspectorMetadataHeadersGeneration &&\n credentialsGeneration === this.inspectorMetadataCredentialsGeneration &&\n this._inspectorMetadataSupported &&\n this.inspectorMetadataRefreshReady &&\n this._runtimeConnectionStatus ===\n CopilotKitCoreRuntimeConnectionStatus.Connected\n );\n }\n\n private invalidateInspectorMetadataConnection(): void {\n this._inspectorMetadataSupported = false;\n this._inspectorLearning = false;\n this.inspectorMetadataRefreshReady = false;\n this.inspectorMetadataConnectionGeneration += 1;\n this.inspectorMetadataGeneration += 1;\n this.inspectorMetadataAbortController?.abort();\n this.inspectorMetadataAbortController = undefined;\n this.setInspectorMetadata(undefined);\n }\n\n /**\n * Publish one state transition without making refreshes wait on subscribers.\n * Each queued callback closes over its readonly snapshot so reentrant changes\n * cannot replace the value that an older publication is still delivering.\n */\n private setInspectorMetadata(\n inspectorMetadata: InspectorMetadataV1 | undefined,\n ): void {\n if (\n JSON.stringify(this._inspectorMetadata) ===\n JSON.stringify(inspectorMetadata)\n ) {\n return;\n }\n\n this._inspectorMetadata = inspectorMetadata;\n const snapshot = inspectorMetadata;\n this.inspectorMetadataNotificationQueue =\n this.inspectorMetadataNotificationQueue\n .then(() => this.notifyInspectorMetadataChanged(snapshot))\n .catch((error: unknown) => {\n console.error(\n \"Subscriber onInspectorMetadataChanged queue error:\",\n error,\n );\n });\n }\n\n private setRuntimeConnectionStatus(\n status: CopilotKitCoreRuntimeConnectionStatus,\n ): void {\n this._runtimeConnectionStatus = status;\n this.runtimeHealthGeneration += 1;\n }\n\n private handleRuntimeRequestOutcome(\n outcome: RuntimeRequestOutcome,\n alreadyChecked: () => boolean = () => false,\n ): boolean {\n if (outcome === \"aborted\" || outcome === \"ignored\") {\n return false;\n }\n if (outcome === \"failed\" && alreadyChecked()) {\n return false;\n }\n if (typeof window === \"undefined\") {\n return false;\n }\n if (!this._runtimeUrl) {\n return false;\n }\n\n if (outcome === \"ok\") {\n this.runtimeHealthGeneration += 1;\n if (this.runtimeRecoveryRunning) {\n this.runtimeRecoveryPending = true;\n }\n if (\n this._runtimeConnectionStatus ===\n CopilotKitCoreRuntimeConnectionStatus.Error\n ) {\n void this.recoverRuntimeConnection();\n }\n return false;\n }\n\n if (\n this._runtimeConnectionStatus !==\n CopilotKitCoreRuntimeConnectionStatus.Connected\n ) {\n return false;\n }\n if (this.runtimeProbeInFlight) {\n return false;\n }\n void this.probeRuntimeReachability();\n return true;\n }\n\n private async fetchRuntimeInfoWithTimeout(\n abortController: AbortController,\n runtimeUrl = this.runtimeUrl,\n runtimeTransport = this._runtimeTransport,\n ): Promise<RuntimeInfoFetchResult> {\n if (!runtimeUrl) {\n throw new Error(\"Runtime URL is not set\");\n }\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const request = this.fetchRuntimeInfo(\n runtimeUrl,\n runtimeTransport,\n abortController.signal,\n );\n void request.catch(() => {});\n try {\n const timedOut = new Promise<never>((_resolve, reject) => {\n timeoutId = setTimeout(() => {\n abortController.abort();\n reject(\n new Error(\n `Runtime did not answer within ${ɵRUNTIME_PROBE_TIMEOUT_MS}ms`,\n ),\n );\n }, ɵRUNTIME_PROBE_TIMEOUT_MS);\n });\n return await Promise.race([request, timedOut]);\n } finally {\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n }\n }\n }\n\n private async probeRuntimeReachability(): Promise<void> {\n const generation = this.runtimeHealthGeneration;\n const token = ++this.runtimeProbeToken;\n this.runtimeProbeInFlight = true;\n const abortController = new AbortController();\n this.runtimeProbeAbortController = abortController;\n try {\n await this.fetchRuntimeInfoWithTimeout(abortController);\n } catch (error) {\n if (generation !== this.runtimeHealthGeneration) {\n return;\n }\n await this.markRuntimeUnreachable(\n error instanceof Error ? error : new Error(String(error)),\n );\n } finally {\n if (this.runtimeProbeAbortController === abortController) {\n this.runtimeProbeAbortController = undefined;\n }\n if (this.runtimeProbeToken === token) {\n this.runtimeProbeInFlight = false;\n }\n }\n }\n\n private async markRuntimeUnreachable(error: Error): Promise<void> {\n this.setRuntimeConnectionStatus(\n CopilotKitCoreRuntimeConnectionStatus.Error,\n );\n await this.notifyRuntimeStatusChanged(\n CopilotKitCoreRuntimeConnectionStatus.Error,\n );\n\n const runtimeStatus = isRuntimeInfoRequestError(error)\n ? error.runtimeInfoStatus\n : undefined;\n logger.warn(\n runtimeStatus === undefined\n ? `Runtime did not answer the identification request (${this._runtimeUrl}/info): ${error.message}. The runtime appears to be unreachable.`\n : `Runtime answered the identification request with status ${runtimeStatus} (${this._runtimeUrl}/info): ${error.message}. The runtime is reachable but refused the request — check credentials and authorisation before addresses and ports.`,\n );\n await (this.core as unknown as CopilotKitCoreFriendsAccess).emitError({\n error,\n code: CopilotKitCoreErrorCode.RUNTIME_INFO_FETCH_FAILED,\n context: {\n runtimeUrl: this._runtimeUrl,\n reason: runtimeStatus === undefined ? \"no-answer\" : \"answered\",\n ...(runtimeStatus === undefined ? {} : { runtimeStatus }),\n },\n });\n }\n\n private async recoverRuntimeConnection(): Promise<void> {\n if (this.runtimeRecoveryRunning) {\n this.runtimeRecoveryPending = true;\n return;\n }\n this.runtimeRecoveryRunning = true;\n try {\n do {\n this.runtimeRecoveryPending = false;\n await this.updateRuntimeConnection({\n preserveOnFailure: true,\n recovery: true,\n });\n } while (\n this.runtimeRecoveryPending &&\n this._runtimeConnectionStatus !==\n CopilotKitCoreRuntimeConnectionStatus.Connected\n );\n } finally {\n this.runtimeRecoveryRunning = false;\n this.runtimeRecoveryPending = false;\n }\n }\n\n /**\n * Update runtime connection and fetch remote agents\n */\n private async updateRuntimeConnection(\n options?: RuntimeConnectionOptions,\n ): Promise<void> {\n // Skip fetching on the server (SSR)\n if (typeof window === \"undefined\") {\n return;\n }\n\n // In-flight guard: if a connection to the same target (runtime url +\n // requested transport) is already running, reuse it instead of starting a\n // second `/info` request. A change to a different target supersedes it. See\n // #5801.\n const key = this.runtimeConnectionKey();\n const inFlight = this._connectionInFlight;\n if (\n inFlight &&\n inFlight.attempt.key === key &&\n this.isCurrentRuntimeConnection(inFlight.attempt)\n ) {\n return inFlight.promise;\n }\n\n const attempt = {\n key,\n generation: ++this._runtimeConnectionGeneration,\n };\n this._activeRuntimeConnectionAttempt = attempt;\n const promise = this.performRuntimeConnection({\n attempt,\n runtimeUrl: this._runtimeUrl,\n transport: this._runtimeTransport,\n options,\n });\n this._connectionInFlight = { attempt, promise };\n void promise.finally(() => {\n if (this._connectionInFlight?.promise === promise) {\n this._connectionInFlight = undefined;\n }\n });\n return promise;\n }\n\n /** Return the stable key that scopes connection and entitlement retries. */\n private runtimeConnectionKey(): string {\n // The endpoint URL is part of the identity: a change that only adds or\n // drops the trailing slash targets a different single-route endpoint.\n return `${this._runtimeEndpointUrl ?? this._runtimeUrl ?? \"\"}::${this._requestedTransport}`;\n }\n\n /** Return whether a proxy still targets this Runtime connection. */\n private canReuseRuntimeAgent(\n agent: ProxiedCopilotRuntimeAgent,\n runtimeUrl: string | undefined,\n transport: CopilotRuntimeTransport,\n ): boolean {\n if (!runtimeUrl) {\n return false;\n }\n const connection = this.remoteAgentConnections.get(agent);\n return (\n connection?.runtimeUrl === runtimeUrl.replace(/\\/$/, \"\") &&\n connection.endpointUrl === this._runtimeEndpointUrl &&\n connection.transport === transport\n );\n }\n\n /** Return whether an async attempt still owns the active Runtime state. */\n private isCurrentRuntimeConnection(\n attempt: RuntimeConnectionAttempt,\n ): boolean {\n return (\n this._activeRuntimeConnectionAttempt?.generation === attempt.generation &&\n this.runtimeConnectionKey() === attempt.key\n );\n }\n\n /** Cancel a pending entitlement retry and allow a new target to retry. */\n private resetRuntimeEntitlementRetry(): void {\n if (this._runtimeEntitlementRetryTimer !== undefined) {\n clearTimeout(this._runtimeEntitlementRetryTimer);\n this._runtimeEntitlementRetryTimer = undefined;\n }\n this._runtimeEntitlementRetryAttemptedKey = undefined;\n this._runtimeEntitlementRetryPendingKey = undefined;\n }\n\n /** Schedule one retry after Runtime's short failed-entitlement cache. */\n private updateRuntimeEntitlementRetry(\n runtimeEntitlements: RuntimeEntitlementResponse | undefined,\n attempt: RuntimeConnectionAttempt,\n ): void {\n if (!this.isCurrentRuntimeConnection(attempt)) {\n return;\n }\n const { key } = attempt;\n if (\n runtimeEntitlements?.status === \"ready\" ||\n runtimeEntitlements?.error.retryable !== true\n ) {\n this.resetRuntimeEntitlementRetry();\n return;\n }\n if (this._runtimeEntitlementRetryTimer !== undefined) {\n return;\n }\n if (this._runtimeEntitlementRetryAttemptedKey === key) {\n this._runtimeEntitlementRetryPendingKey = undefined;\n return;\n }\n\n this._runtimeEntitlementRetryAttemptedKey = key;\n this._runtimeEntitlementRetryPendingKey = key;\n this._runtimeEntitlementRetryTimer = setTimeout(() => {\n this._runtimeEntitlementRetryTimer = undefined;\n void this.executeRuntimeEntitlementRetry(attempt).catch(\n (error: unknown) => {\n const message =\n error instanceof Error ? error.message : JSON.stringify(error);\n logger.warn(\n `Failed to retry runtime info (${this.runtimeUrl}/info): ${message}`,\n );\n },\n );\n }, RUNTIME_ENTITLEMENT_RETRY_DELAY_MS);\n }\n\n /** Start the bounded retry after the original connection has settled. */\n private async executeRuntimeEntitlementRetry(\n attempt: RuntimeConnectionAttempt,\n ): Promise<void> {\n const inFlight = this._connectionInFlight;\n if (inFlight?.attempt.generation === attempt.generation) {\n await inFlight.promise;\n }\n if (!this._runtimeUrl || !this.isCurrentRuntimeConnection(attempt)) {\n return;\n }\n await this.updateRuntimeConnection();\n }\n\n private async performRuntimeConnection({\n attempt,\n runtimeUrl,\n transport,\n options,\n }: {\n attempt: RuntimeConnectionAttempt;\n runtimeUrl: string | undefined;\n transport: CopilotRuntimeTransport;\n options?: RuntimeConnectionOptions;\n }): Promise<void> {\n const { key } = attempt;\n if (!runtimeUrl) {\n this.invalidateInspectorMetadataConnection();\n this.setRuntimeConnectionStatus(\n CopilotKitCoreRuntimeConnectionStatus.Disconnected,\n );\n this._runtimeVersion = undefined;\n this._audioFileTranscriptionEnabled = false;\n this._runtimeMode = RUNTIME_MODE_SSE;\n this._intelligence = undefined;\n this._threadEndpoints = undefined;\n this._singleRouteResourceOperations = false;\n this._suggestions = undefined;\n this._inspectorLearning = false;\n this._a2uiEnabled = false;\n this._a2uiAgents = undefined;\n this._openGenerativeUIEnabled = false;\n this._licenseStatus = undefined;\n this._runtimeEntitlements = undefined;\n this.remoteAgents = {};\n this._agents = this.localAgents;\n\n await this.notifyRuntimeStatusChanged(\n CopilotKitCoreRuntimeConnectionStatus.Disconnected,\n );\n if (!this.isCurrentRuntimeConnection(attempt)) {\n return;\n }\n await this.notifyAgentsChanged();\n return;\n }\n\n const inspectorMetadataConnectionGeneration =\n this.inspectorMetadataConnectionGeneration;\n\n this.setRuntimeConnectionStatus(\n CopilotKitCoreRuntimeConnectionStatus.Connecting,\n );\n const runtimeHealthGeneration = this.runtimeHealthGeneration;\n await this.notifyRuntimeStatusChanged(\n CopilotKitCoreRuntimeConnectionStatus.Connecting,\n );\n if (!this.isCurrentRuntimeConnection(attempt)) {\n return;\n }\n\n try {\n if (\n inspectorMetadataConnectionGeneration !==\n this.inspectorMetadataConnectionGeneration\n ) {\n return;\n }\n const { runtimeInfo: runtimeInfoResponse, resolvedTransport } =\n options?.recovery\n ? await this.fetchRuntimeInfoWithTimeout(\n new AbortController(),\n runtimeUrl,\n transport,\n )\n : await this.fetchRuntimeInfo(runtimeUrl, transport);\n if (\n !this.isCurrentRuntimeConnection(attempt) ||\n inspectorMetadataConnectionGeneration !==\n this.inspectorMetadataConnectionGeneration\n ) {\n return;\n }\n\n this._runtimeTransport = resolvedTransport;\n const { version, ...runtimeInfo } = runtimeInfoResponse;\n\n const credentials = (this.core as unknown as CopilotKitCoreFriendsAccess)\n .credentials;\n const rawDebug = (this.core as unknown as CopilotKitCoreFriendsAccess)\n .debug;\n const agents: Record<string, AbstractAgent> = Object.fromEntries(\n Object.entries(runtimeInfo.agents).map(\n ([id, { description, capabilities }]) => {\n // Preserve a live proxy only when its baked request routes still\n // match this connection. A new Runtime URL or resolved transport\n // needs a new proxy so agent traffic cannot keep using the old\n // target.\n const existing = Object.prototype.hasOwnProperty.call(\n this.remoteAgents,\n id,\n )\n ? this.remoteAgents[id]\n : undefined;\n if (\n existing instanceof ProxiedCopilotRuntimeAgent &&\n this.canReuseRuntimeAgent(\n existing,\n runtimeUrl,\n this._runtimeTransport,\n )\n ) {\n this.applyHeadersToAgent(existing);\n this.applyCredentialsToAgent(existing);\n this.applyMessageFilterToAgent(existing);\n this.applyRuntimeFetchToAgent(existing);\n this.applyRuntimeModeToAgent(existing, runtimeInfoResponse);\n return [id, existing];\n }\n const agent = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: this._runtimeEndpointUrl ?? runtimeUrl,\n agentId: id, // Runtime agents always have their ID set correctly\n description: description,\n transport: this._runtimeTransport,\n credentials,\n runtimeMode: runtimeInfoResponse.mode ?? RUNTIME_MODE_SSE,\n intelligence: runtimeInfoResponse.intelligence,\n capabilities,\n debug: rawDebug ? resolveDebugConfig(rawDebug) : undefined,\n messageFilter: (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).messageFilter,\n });\n this.applyHeadersToAgent(agent);\n this.applyRuntimeFetchToAgent(agent);\n this.mintedThreadIds.set(agent, agent.threadId);\n if (options?.preserveOnFailure === true && existing) {\n agent.threadId = existing.threadId;\n agent.setState(existing.state);\n agent.setMessages([...existing.messages]);\n }\n this.remoteAgentConnections.set(agent, {\n runtimeUrl,\n endpointUrl: this._runtimeEndpointUrl,\n transport: this._runtimeTransport,\n });\n return [id, agent];\n },\n ),\n );\n\n this.remoteAgents = options?.recovery\n ? this.reconcileRecoveredAgents(agents)\n : agents;\n this._agents = { ...this.localAgents, ...this.remoteAgents };\n this.setRuntimeConnectionStatus(\n CopilotKitCoreRuntimeConnectionStatus.Connected,\n );\n this._runtimeVersion = version;\n this._audioFileTranscriptionEnabled =\n runtimeInfoResponse.audioFileTranscriptionEnabled ?? false;\n this._runtimeMode = runtimeInfoResponse.mode ?? RUNTIME_MODE_SSE;\n this._intelligence = runtimeInfoResponse.intelligence;\n this._singleRouteResourceOperations =\n resolvedTransport === \"single\" &&\n runtimeInfoResponse.singleRoute?.resourceOperations === true;\n this._threadEndpoints = this._singleRouteResourceOperations\n ? runtimeInfoResponse.singleRoute?.threadEndpoints\n : runtimeInfoResponse.threadEndpoints;\n this._suggestions = runtimeInfoResponse.suggestions;\n this._inspectorLearning = runtimeInfoResponse.inspectorLearning === true;\n this._inspectorMetadataSupported =\n runtimeInfoResponse.inspectorMetadata === true;\n this.inspectorMetadataRefreshReady = false;\n if (!this._inspectorMetadataSupported) {\n this.setInspectorMetadata(undefined);\n }\n const a2uiInfo = runtimeInfoResponse.a2ui;\n this._a2uiEnabled =\n a2uiInfo?.enabled ?? runtimeInfoResponse.a2uiEnabled ?? false;\n this._a2uiAgents = a2uiInfo?.enabled ? a2uiInfo.agents : undefined;\n this._openGenerativeUIEnabled =\n runtimeInfoResponse.openGenerativeUIEnabled ?? false;\n this._licenseStatus = runtimeInfoResponse.licenseStatus;\n this._runtimeEntitlements = runtimeInfoResponse.runtimeEntitlements;\n this.updateRuntimeEntitlementRetry(\n runtimeInfoResponse.runtimeEntitlements,\n attempt,\n );\n this._telemetryDisabled = runtimeInfoResponse.telemetryDisabled ?? false;\n\n await this.notifyRuntimeStatusChanged(\n CopilotKitCoreRuntimeConnectionStatus.Connected,\n );\n if (!this.isCurrentRuntimeConnection(attempt)) {\n return;\n }\n await this.notifyAgentsChanged();\n if (\n inspectorMetadataConnectionGeneration !==\n this.inspectorMetadataConnectionGeneration ||\n this._runtimeConnectionStatus !==\n CopilotKitCoreRuntimeConnectionStatus.Connected\n ) {\n return;\n }\n this.inspectorMetadataRefreshReady = true;\n if (this._inspectorMetadataSupported) {\n void this.refreshInspectorMetadata();\n }\n } catch (error) {\n if (\n !this.isCurrentRuntimeConnection(attempt) ||\n inspectorMetadataConnectionGeneration !==\n this.inspectorMetadataConnectionGeneration\n ) {\n return;\n }\n const boundedEntitlementRetryFailed =\n this._runtimeEntitlementRetryTimer === undefined &&\n this._runtimeEntitlementRetryAttemptedKey === key &&\n this._runtimeEntitlementRetryPendingKey === key;\n if (boundedEntitlementRetryFailed) {\n this._runtimeEntitlementRetryPendingKey = undefined;\n }\n if (options?.preserveOnFailure) {\n if (\n options?.recovery &&\n runtimeHealthGeneration !== this.runtimeHealthGeneration\n ) {\n return;\n }\n this.setRuntimeConnectionStatus(\n CopilotKitCoreRuntimeConnectionStatus.Error,\n );\n await this.notifyRuntimeStatusChanged(\n CopilotKitCoreRuntimeConnectionStatus.Error,\n );\n } else {\n this.invalidateInspectorMetadataConnection();\n this.setRuntimeConnectionStatus(\n CopilotKitCoreRuntimeConnectionStatus.Error,\n );\n this._runtimeVersion = undefined;\n this._audioFileTranscriptionEnabled = false;\n this._runtimeMode = RUNTIME_MODE_SSE;\n this._intelligence = undefined;\n this._threadEndpoints = undefined;\n this._singleRouteResourceOperations = false;\n this._suggestions = undefined;\n this._inspectorLearning = false;\n this._a2uiEnabled = false;\n this._a2uiAgents = undefined;\n this._openGenerativeUIEnabled = false;\n // A failed bounded retry must settle the authority that caused it. Keep\n // that retryable result so consumers can distinguish terminal denial\n // from the initial loading window. Other connection failures still\n // clear stale Runtime authority.\n if (!boundedEntitlementRetryFailed) {\n this._licenseStatus = undefined;\n this._runtimeEntitlements = undefined;\n }\n this.remoteAgents = {};\n this._agents = this.localAgents;\n\n await this.notifyRuntimeStatusChanged(\n CopilotKitCoreRuntimeConnectionStatus.Error,\n );\n await this.notifyAgentsChanged();\n }\n\n const message =\n error instanceof Error ? error.message : JSON.stringify(error);\n logger.warn(\n `Failed to load runtime info (${runtimeUrl}/info): ${message}`,\n );\n const runtimeError =\n error instanceof Error ? error : new Error(String(error));\n await (this.core as unknown as CopilotKitCoreFriendsAccess).emitError({\n error: runtimeError,\n code: CopilotKitCoreErrorCode.RUNTIME_INFO_FETCH_FAILED,\n context: {\n runtimeUrl,\n },\n });\n }\n }\n\n private async fetchRuntimeInfo(\n runtimeUrl: string,\n runtimeTransport: CopilotRuntimeTransport,\n signal?: AbortSignal,\n ): Promise<RuntimeInfoFetchResult> {\n const baseHeaders = (this.core as unknown as CopilotKitCoreFriendsAccess)\n .headers;\n const credentials = (this.core as unknown as CopilotKitCoreFriendsAccess)\n .credentials;\n const headers: Record<string, string> = {\n ...baseHeaders,\n };\n\n if (runtimeTransport === \"single\") {\n return {\n runtimeInfo: await this.fetchRuntimeInfoSingle(\n this.singleEndpointUrlFor(runtimeUrl),\n headers,\n credentials,\n signal,\n ),\n resolvedTransport: \"single\",\n };\n }\n\n if (runtimeTransport === \"auto\") {\n return this.fetchRuntimeInfoAutoDetect(\n runtimeUrl,\n headers,\n credentials,\n signal,\n );\n }\n\n // REST transport\n const response = await fetch(`${runtimeUrl}/info`, {\n headers,\n ...(credentials ? { credentials } : {}),\n ...(signal ? { signal } : {}),\n });\n if (!response.ok) {\n throw await runtimeInfoError(response);\n }\n return {\n runtimeInfo: (await response.json()) as RuntimeInfo,\n resolvedTransport: \"rest\",\n };\n }\n\n /**\n * The URL a single-route request targets: the runtime URL as the caller\n * supplied it. `runtimeUrl` is the slash-stripped form used for path joins;\n * a trailing slash can select a different proxy location, so the endpoint\n * itself keeps it.\n */\n private singleEndpointUrlFor(runtimeUrl: string): string {\n return this._runtimeEndpointUrl !== undefined &&\n this._runtimeUrl === runtimeUrl\n ? this._runtimeEndpointUrl\n : runtimeUrl;\n }\n\n private async fetchRuntimeInfoSingle(\n runtimeUrl: string,\n headers: Record<string, string>,\n credentials: RequestCredentials | undefined,\n signal?: AbortSignal,\n ): Promise<RuntimeInfo> {\n const response = await fetch(runtimeUrl, {\n method: \"POST\",\n headers: withJsonContentType(headers),\n body: JSON.stringify({ method: \"info\" }),\n ...(credentials ? { credentials } : {}),\n ...(signal ? { signal } : {}),\n });\n if (!response.ok) {\n throw await runtimeInfoError(response);\n }\n return (await response.json()) as RuntimeInfo;\n }\n\n /**\n * Auto-detect transport by trying REST first, then falling back to single-endpoint.\n * The caller commits the detected transport only after confirming this\n * connection attempt is still current.\n */\n private async fetchRuntimeInfoAutoDetect(\n runtimeUrl: string,\n headers: Record<string, string>,\n credentials: RequestCredentials | undefined,\n signal?: AbortSignal,\n ): Promise<RuntimeInfoFetchResult> {\n // Try REST first (GET /info)\n try {\n const response = await fetch(`${runtimeUrl}/info`, {\n headers: { ...headers },\n ...(credentials ? { credentials } : {}),\n ...(signal ? { signal } : {}),\n });\n // Only treat a successful (2xx) response as a valid REST runtime.\n // 404/405 means the endpoint doesn't exist; other non-2xx errors\n // (500, 403, etc.) should also fall through to single-endpoint.\n if (response.status >= 200 && response.status < 300) {\n return {\n runtimeInfo: (await response.json()) as RuntimeInfo,\n resolvedTransport: \"rest\",\n };\n }\n // Non-2xx — try single-endpoint below\n } catch {\n // REST failed (network error, etc.) — fall through to single-endpoint attempt\n }\n\n const runtimeInfo = await this.fetchRuntimeInfoSingle(\n this.singleEndpointUrlFor(runtimeUrl),\n { ...headers },\n credentials,\n signal,\n );\n return { runtimeInfo, resolvedTransport: \"single\" };\n }\n\n /**\n * Assign agent IDs to a record of agents\n */\n private assignAgentIds(\n agents: Record<string, AbstractAgent>,\n ): Record<string, AbstractAgent> {\n Object.entries(agents).forEach(([id, agent]) => {\n if (agent) {\n this.validateAndAssignAgentId(id, agent);\n }\n });\n return agents;\n }\n\n /**\n * Validate and assign an agent ID\n */\n private validateAndAssignAgentId(\n registrationId: string,\n agent: AbstractAgent,\n ): void {\n if (agent.agentId && agent.agentId !== registrationId) {\n throw new Error(\n `Agent registration mismatch: Agent with ID \"${agent.agentId}\" cannot be registered under key \"${registrationId}\". ` +\n `The agent ID must match the registration key or be undefined.`,\n );\n }\n if (!agent.agentId) {\n agent.agentId = registrationId;\n }\n }\n\n /**\n * Notify subscribers of runtime status changes\n */\n private async notifyRuntimeStatusChanged(\n status: CopilotKitCoreRuntimeConnectionStatus,\n ): Promise<void> {\n await (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).notifySubscribers(\n (subscriber) =>\n subscriber.onRuntimeConnectionStatusChanged?.({\n copilotkit: this.core,\n status,\n }),\n \"Error in CopilotKitCore subscriber (onRuntimeConnectionStatusChanged):\",\n );\n }\n\n /**\n * Notify subscribers of agent changes\n */\n private async notifyAgentsChanged(): Promise<void> {\n await (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).notifySubscribers(\n (subscriber) =>\n subscriber.onAgentsChanged?.({\n copilotkit: this.core,\n agents: this._agents,\n }),\n \"Subscriber onAgentsChanged error:\",\n );\n }\n\n private async notifyInspectorMetadataChanged(\n inspectorMetadata: InspectorMetadataV1 | undefined,\n ): Promise<void> {\n await (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).notifySubscribers(\n (subscriber) =>\n subscriber.onInspectorMetadataChanged?.({\n copilotkit: this.core,\n inspectorMetadata,\n }),\n \"Subscriber onInspectorMetadataChanged error:\",\n );\n }\n}\n","import type { Context } from \"@ag-ui/client\";\nimport { randomUUID } from \"@copilotkit/shared\";\nimport type { CopilotKitCore } from \"./core\";\nimport type { CopilotKitCoreFriendsAccess } from \"./core\";\n\n/**\n * A context entry with optional per-agent scoping.\n * When `agentIds` is set, the entry is forwarded only to runs of those agents;\n * when omitted, the entry is forwarded to every agent run.\n */\nexport interface ScopedContext extends Context {\n agentIds?: string[];\n}\n\n/**\n * Manages context storage and lifecycle for CopilotKitCore.\n * Context represents additional information available to agents during execution.\n */\nexport class ContextStore {\n private _context: Record<string, ScopedContext> = {};\n\n constructor(private core: CopilotKitCore) {}\n\n /**\n * Get all context entries as a readonly record\n */\n get context(): Readonly<Record<string, ScopedContext>> {\n return this._context;\n }\n\n /**\n * Add a new context entry. Pass `agentIds` to restrict the entry to runs of\n * specific agents (#5369); omit it for context every agent should receive.\n * @returns The ID of the created context entry\n */\n addContext({ description, value, agentIds }: ScopedContext): string {\n const id = randomUUID();\n this._context[id] = {\n description,\n value,\n ...(agentIds ? { agentIds } : {}),\n };\n void this.notifySubscribers();\n return id;\n }\n\n /**\n * Build the context array for a run of the given agent: entries scoped to\n * other agents are dropped, and the scoping metadata is stripped so only\n * protocol-shaped `{ description, value }` entries go over the wire.\n */\n getContextForAgent(agentId?: string): Context[] {\n return Object.values(this._context)\n .filter(\n (entry) =>\n !entry.agentIds ||\n (agentId !== undefined && entry.agentIds.includes(agentId)),\n )\n .map(({ description, value }) => ({ description, value }));\n }\n\n /**\n * Remove a context entry by ID\n */\n removeContext(id: string): void {\n delete this._context[id];\n void this.notifySubscribers();\n }\n\n /**\n * Notify all subscribers of context changes\n */\n private async notifySubscribers(): Promise<void> {\n await (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).notifySubscribers(\n (subscriber) =>\n subscriber.onContextChanged?.({\n copilotkit: this.core,\n context: this._context,\n }),\n \"Subscriber onContextChanged error:\",\n );\n }\n}\n","import type { AbstractAgent, Message, Tool } from \"@ag-ui/client\";\nimport { HttpAgent } from \"@ag-ui/client\";\nimport { ProxiedCopilotRuntimeAgent } from \"../agent\";\nimport { randomUUID, partialJSONParse } from \"@copilotkit/shared\";\nimport type { CopilotKitCore } from \"./core\";\nimport type { CopilotKitCoreGetSuggestionsResult } from \"./core\";\nimport type { CopilotKitCoreFriendsAccess } from \"./core\";\nimport type {\n DynamicSuggestionsConfig,\n StaticSuggestionsConfig,\n Suggestion,\n SuggestionsConfig,\n} from \"../types\";\n\n/**\n * The minimal cancellation surface a running suggestion generation exposes.\n * Both a cloned `AbstractAgent` (via `abortRun`) and the stateless fetch shim\n * (which aborts an `AbortController`) satisfy this, so `clearSuggestions` can\n * cancel either uniformly.\n */\ninterface AbortableSuggestionRun {\n abortRun(): void;\n}\n\n/**\n * Manages suggestion generation, streaming, and lifecycle for CopilotKitCore.\n * Handles both dynamic (AI-generated) and static suggestions.\n */\nexport class SuggestionEngine {\n private _suggestionsConfig: Record<string, SuggestionsConfig> = {};\n private _suggestions: Record<string, Record<string, Suggestion[]>> = {};\n private _runningSuggestions: Record<string, AbortableSuggestionRun[]> = {};\n\n constructor(private core: CopilotKitCore) {}\n\n /**\n * Initialize with suggestion configs\n */\n initialize(suggestionsConfig: SuggestionsConfig[]): void {\n for (const config of suggestionsConfig) {\n this._suggestionsConfig[randomUUID()] = config;\n }\n }\n\n /**\n * Add a suggestion configuration\n * @returns The ID of the created config\n */\n addSuggestionsConfig(config: SuggestionsConfig): string {\n const id = randomUUID();\n this._suggestionsConfig[id] = config;\n void this.notifySuggestionsConfigChanged();\n return id;\n }\n\n /**\n * Remove a suggestion configuration by ID\n */\n removeSuggestionsConfig(id: string): void {\n delete this._suggestionsConfig[id];\n void this.notifySuggestionsConfigChanged();\n }\n\n /**\n * Reload suggestions for a specific agent\n * This triggers generation of new suggestions based on current configs\n */\n public reloadSuggestions(agentId: string): void {\n this.clearSuggestions(agentId);\n\n // The agent may legitimately be missing here (e.g. runtime info still loading,\n // or the consumer agent is configured but not yet registered) — static suggestions\n // don't need it, only dynamic generation does. Treat that case as \"no messages yet\"\n // and process static configs anyway.\n const agent = (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).getAgent(agentId);\n\n const messageCount = agent?.messages?.length ?? 0;\n let hasAnySuggestions = false;\n\n for (const config of Object.values(this._suggestionsConfig)) {\n // Check if config applies to this agent\n if (\n config.consumerAgentId !== undefined &&\n config.consumerAgentId !== \"*\" &&\n config.consumerAgentId !== agentId\n ) {\n continue;\n }\n\n // Check availability based on message count\n if (!this.shouldShowSuggestions(config, messageCount)) {\n continue;\n }\n\n const suggestionId = randomUUID();\n\n if (isDynamicSuggestionsConfig(config)) {\n // Dynamic suggestions need a real agent (provider + consumer messages).\n // Skip when the agent isn't ready yet — `reloadSuggestions` will be\n // called again once it is.\n if (!agent) {\n continue;\n }\n if (!hasAnySuggestions) {\n hasAnySuggestions = true;\n void this.notifySuggestionsStartedLoading(agentId);\n }\n void this.generateSuggestions(suggestionId, config, agentId);\n } else if (isStaticSuggestionsConfig(config)) {\n this.addStaticSuggestions(suggestionId, config, agentId);\n }\n }\n }\n\n /**\n * Clear all suggestions for a specific agent\n */\n public clearSuggestions(agentId: string): void {\n const runningAgents = this._runningSuggestions[agentId];\n if (runningAgents) {\n for (const agent of runningAgents) {\n agent.abortRun();\n }\n delete this._runningSuggestions[agentId];\n }\n this._suggestions[agentId] = {};\n\n void this.notifySuggestionsChanged(agentId, []);\n }\n\n /**\n * Get current suggestions for an agent\n */\n public getSuggestions(agentId: string): CopilotKitCoreGetSuggestionsResult {\n const suggestions = Object.values(this._suggestions[agentId] ?? {}).flat();\n const isLoading = (this._runningSuggestions[agentId]?.length ?? 0) > 0;\n return { suggestions, isLoading };\n }\n\n /**\n * Generate suggestions by running a provider agent and extracting the\n * `copilotkitSuggest` tool call from its streamed messages.\n *\n * Two transports, one set of mechanics: both seed an agent with the\n * consumer's messages + state and the instruction, then `runAgent` with\n * forced `copilotkitSuggest` tool choice, parsing suggestions as messages\n * stream in via `onMessagesChanged`.\n *\n * - **Stateless** (runtime advertises `suggestions` and transport isn't\n * `single`): a stock `HttpAgent` pointed at `/agent/:id/suggest`. That\n * endpoint runs the provider directly and streams AG-UI SSE **without**\n * persisting a thread, and a plain `HttpAgent` only ever speaks REST SSE —\n * it never routes through the Intelligence websocket delegate (which would\n * persist a thread). This is the path that removes the thread flood.\n * - **Fallback** (capability absent → old runtime, or `single` transport):\n * clone the provider agent and run it client-side, as before.\n *\n * Gated to non-`single` transports because this client only builds the\n * multi-route `/agent/:id/suggest` URL; single-route deployments (not the\n * persisting-thread/Intelligence case) fall through to the clone fallback.\n */\n private async generateSuggestions(\n suggestionId: string,\n config: DynamicSuggestionsConfig,\n consumerAgentId: string,\n ): Promise<void> {\n // The cancellable handle for this generation, removed from the running set\n // in `finally`. `abortRun` flips `aborted` before cancelling the underlying\n // agent so the `catch` can distinguish a deliberate clear/reload from a real\n // failure — some engines (undici, some React Native) reject an aborted run\n // with a non-\"AbortError\" error that `isAbortError` alone would misclassify.\n let runHandle: AbortableSuggestionRun | undefined = undefined;\n let aborted = false;\n try {\n const friends = this.core as unknown as CopilotKitCoreFriendsAccess;\n const resolvedProviderAgentId = config.providerAgentId ?? \"default\";\n const suggestionsProviderAgent = friends.getAgent(\n resolvedProviderAgentId,\n );\n if (!suggestionsProviderAgent) {\n throw new Error(\n `Suggestions provider agent not found: ${resolvedProviderAgentId}`,\n );\n }\n const suggestionsConsumerAgent = friends.getAgent(consumerAgentId);\n if (!suggestionsConsumerAgent) {\n throw new Error(\n `Suggestions consumer agent not found: ${consumerAgentId}`,\n );\n }\n\n const instructionContent = [\n `Suggest what the user could say next. Provide clear, highly relevant suggestions by calling the \\`copilotkitSuggest\\` tool.`,\n `Provide at least ${config.minSuggestions ?? 1} and at most ${\n config.maxSuggestions ?? 3\n } suggestions.`,\n `The user has the following tools available: ${JSON.stringify(\n friends.buildFrontendTools(consumerAgentId),\n )}.`,\n ` ${config.instructions}`,\n ].join(\"\\n\");\n\n // Initialize suggestion storage for this agent/suggestion combo\n this._suggestions[consumerAgentId] = {\n ...this._suggestions[consumerAgentId],\n [suggestionId]: [],\n };\n\n // Deep-clone the consumer's messages + state so the suggestion run sees\n // the same context a real turn would, without sharing mutable references.\n const seededMessages: Message[] = JSON.parse(\n JSON.stringify(suggestionsConsumerAgent.messages),\n );\n const seededState: unknown = JSON.parse(\n JSON.stringify(suggestionsConsumerAgent.state ?? {}),\n );\n\n const useStateless =\n this.core.suggestions === true &&\n this.core.runtimeTransport !== \"single\";\n\n let suggestionAgent: AbstractAgent;\n if (useStateless) {\n const suggestUrl = `${this.core.runtimeUrl}/agent/${encodeURIComponent(\n resolvedProviderAgentId,\n )}/suggest`;\n const credentials = this.core.credentials;\n suggestionAgent = new HttpAgent({\n agentId: resolvedProviderAgentId,\n url: suggestUrl,\n headers: { ...this.core.headers },\n // `HttpAgentConfig` has no `credentials` field; inject it via a fetch\n // wrapper so cookie-based / self-hosted auth still rides along on the\n // `/suggest` request.\n ...(credentials\n ? {\n fetch: (url: string, requestInit: RequestInit) =>\n fetch(url, { ...requestInit, credentials }),\n }\n : {}),\n });\n } else {\n suggestionAgent = suggestionsProviderAgent.clone();\n // A suggestion run gets a brand-new thread id, so no backend store can\n // fill in history the client withheld. An app-level `messageFilter`\n // trimmed for a persisted conversation would therefore leave the\n // provider with only the tail of the seeded context and generate\n // suggestions about nothing. The seeded messages ARE the context here.\n if (suggestionAgent instanceof ProxiedCopilotRuntimeAgent) {\n suggestionAgent.messageFilter = undefined;\n }\n }\n\n suggestionAgent.threadId = suggestionId;\n suggestionAgent.setMessages(seededMessages);\n suggestionAgent.setState(seededState);\n\n runHandle = {\n abortRun: () => {\n aborted = true;\n suggestionAgent.abortRun();\n },\n };\n this._runningSuggestions[consumerAgentId] = [\n ...(this._runningSuggestions[consumerAgentId] ?? []),\n runHandle,\n ];\n\n suggestionAgent.addMessage({\n id: suggestionId,\n role: \"user\",\n content: instructionContent,\n });\n\n await suggestionAgent.runAgent(\n {\n context: friends.getContextForAgent(consumerAgentId),\n forwardedProps: {\n ...friends.properties,\n toolChoice: {\n type: \"function\",\n function: { name: \"copilotkitSuggest\" },\n },\n },\n tools: [SUGGEST_TOOL],\n },\n {\n onMessagesChanged: ({ messages }) => {\n this.extractSuggestions(\n messages,\n suggestionId,\n consumerAgentId,\n true,\n );\n },\n },\n );\n } catch (error) {\n // An abort is expected when suggestions are cleared/reloaded mid-flight;\n // swallow it quietly rather than surfacing it as a failure. `isAbortError`\n // is the primary (name-based) check; `aborted` covers engines that reject\n // an aborted run with a differently-named error (or a `TypeError`).\n if (!isAbortError(error) && !aborted) {\n console.warn(\"Error generating suggestions:\", error);\n }\n } finally {\n // Finalize suggestions by marking them as no longer loading\n this.finalizeSuggestions(suggestionId, consumerAgentId);\n\n // Remove this run from the running set. `runHandle` may be undefined when\n // generation threw before it was assigned (e.g. provider/consumer agent\n // lookup failed); still perform cleanup so the loading balance holds. If\n // no runs remain for this consumer, emit finished-loading — otherwise a\n // subscriber that saw `started` would hang in the loading state.\n const runningAgents = this._runningSuggestions[consumerAgentId];\n const remaining = runHandle\n ? (runningAgents ?? []).filter((a) => a !== runHandle)\n : (runningAgents ?? []);\n\n if (remaining.length === 0) {\n delete this._runningSuggestions[consumerAgentId];\n await this.notifySuggestionsFinishedLoading(consumerAgentId);\n } else {\n this._runningSuggestions[consumerAgentId] = remaining;\n }\n }\n }\n\n /**\n * Finalize suggestions by marking them as no longer loading\n */\n private finalizeSuggestions(\n suggestionId: string,\n consumerAgentId: string,\n ): void {\n const agentSuggestions = this._suggestions[consumerAgentId];\n const currentSuggestions = agentSuggestions?.[suggestionId];\n\n if (\n agentSuggestions &&\n currentSuggestions &&\n currentSuggestions.length > 0\n ) {\n // Filter out empty suggestions and mark remaining as no longer loading\n const finalizedSuggestions = currentSuggestions\n .filter(\n (suggestion) => suggestion.title !== \"\" || suggestion.message !== \"\",\n )\n .map((suggestion) => ({\n ...suggestion,\n isLoading: false,\n }));\n\n if (finalizedSuggestions.length > 0) {\n agentSuggestions[suggestionId] = finalizedSuggestions;\n } else {\n delete agentSuggestions[suggestionId];\n }\n\n // Get all aggregated suggestions for this agent\n const allSuggestions = Object.values(\n this._suggestions[consumerAgentId] ?? {},\n ).flat();\n\n void this.notifySuggestionsChanged(\n consumerAgentId,\n allSuggestions,\n \"finalized\",\n );\n }\n }\n\n /**\n * Extract suggestions from messages (called during streaming)\n */\n extractSuggestions(\n messages: readonly Message[],\n suggestionId: string,\n consumerAgentId: string,\n isRunning: boolean,\n ): void {\n const idx = messages.findIndex((message) => message.id === suggestionId);\n if (idx == -1) {\n return;\n }\n\n const suggestions: Suggestion[] = [];\n const newMessages = messages.slice(idx + 1);\n\n for (const message of newMessages) {\n if (message.role === \"assistant\" && message.toolCalls) {\n for (const toolCall of message.toolCalls) {\n if (toolCall.function.name === \"copilotkitSuggest\") {\n // Join all argument chunks into a single string for parsing\n // arguments can be either a string or an array of strings\n const fullArgs = Array.isArray(toolCall.function.arguments)\n ? toolCall.function.arguments.join(\"\")\n : toolCall.function.arguments;\n const parsed = partialJSONParse(fullArgs);\n if (\n parsed &&\n typeof parsed === \"object\" &&\n \"suggestions\" in parsed\n ) {\n const parsedSuggestions = (parsed as any).suggestions;\n if (Array.isArray(parsedSuggestions)) {\n for (const item of parsedSuggestions) {\n if (item && typeof item === \"object\" && \"title\" in item) {\n suggestions.push({\n title: item.title ?? \"\",\n message: item.message ?? \"\",\n // Defaults to false; only the trailing item is flipped to\n // true below, and only while a streaming run is in flight.\n isLoading: false,\n });\n }\n }\n }\n }\n }\n }\n }\n }\n\n // Set isLoading for the last suggestion if still running\n if (isRunning && suggestions.length > 0) {\n suggestions[suggestions.length - 1]!.isLoading = true;\n }\n\n const agentSuggestions = this._suggestions[consumerAgentId];\n if (agentSuggestions) {\n agentSuggestions[suggestionId] = suggestions;\n\n // Get all aggregated suggestions for this agent\n const allSuggestions = Object.values(\n this._suggestions[consumerAgentId] ?? {},\n ).flat();\n\n void this.notifySuggestionsChanged(\n consumerAgentId,\n allSuggestions,\n \"suggestions changed\",\n );\n }\n }\n\n /**\n * Notify subscribers of suggestions config changes\n */\n private async notifySuggestionsConfigChanged(): Promise<void> {\n await (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).notifySubscribers(\n (subscriber) =>\n subscriber.onSuggestionsConfigChanged?.({\n copilotkit: this.core,\n suggestionsConfig: this._suggestionsConfig,\n }),\n \"Subscriber onSuggestionsConfigChanged error:\",\n );\n }\n\n /**\n * Notify subscribers of suggestions changes\n */\n private async notifySuggestionsChanged(\n agentId: string,\n suggestions: Suggestion[],\n context: string = \"\",\n ): Promise<void> {\n await (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).notifySubscribers(\n (subscriber) =>\n subscriber.onSuggestionsChanged?.({\n copilotkit: this.core,\n agentId,\n suggestions,\n }),\n `Subscriber onSuggestionsChanged error: ${context}`,\n );\n }\n\n /**\n * Notify subscribers that suggestions started loading\n */\n private async notifySuggestionsStartedLoading(\n agentId: string,\n ): Promise<void> {\n await (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).notifySubscribers(\n (subscriber) =>\n subscriber.onSuggestionsStartedLoading?.({\n copilotkit: this.core,\n agentId,\n }),\n \"Subscriber onSuggestionsStartedLoading error:\",\n );\n }\n\n /**\n * Notify subscribers that suggestions finished loading\n */\n private async notifySuggestionsFinishedLoading(\n agentId: string,\n ): Promise<void> {\n await (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).notifySubscribers(\n (subscriber) =>\n subscriber.onSuggestionsFinishedLoading?.({\n copilotkit: this.core,\n agentId,\n }),\n \"Subscriber onSuggestionsFinishedLoading error:\",\n );\n }\n\n /**\n * Check if suggestions should be shown based on availability and message count\n */\n private shouldShowSuggestions(\n config: SuggestionsConfig,\n messageCount: number,\n ): boolean {\n const availability = config.available;\n\n // Default behavior if no availability specified\n if (!availability) {\n if (isDynamicSuggestionsConfig(config)) {\n return messageCount > 0; // Default: after-first-message\n } else {\n return messageCount === 0; // Default: before-first-message\n }\n }\n\n switch (availability) {\n case \"disabled\":\n return false;\n case \"before-first-message\":\n return messageCount === 0;\n case \"after-first-message\":\n return messageCount > 0;\n case \"always\":\n return true;\n default:\n return false;\n }\n }\n\n /**\n * Add static suggestions directly without AI generation\n */\n private addStaticSuggestions(\n suggestionId: string,\n config: StaticSuggestionsConfig,\n consumerAgentId: string,\n ): void {\n // Mark all as not loading since they're static\n const suggestions = config.suggestions.map((s) => ({\n ...s,\n isLoading: false,\n }));\n\n // Store suggestions\n this._suggestions[consumerAgentId] = {\n ...this._suggestions[consumerAgentId],\n [suggestionId]: suggestions,\n };\n\n // Notify subscribers\n const allSuggestions = Object.values(\n this._suggestions[consumerAgentId] ?? {},\n ).flat();\n\n void this.notifySuggestionsChanged(\n consumerAgentId,\n allSuggestions,\n \"static suggestions added\",\n );\n }\n}\n\n/**\n * Detects an `AbortController`-driven cancellation so the stateless path can\n * treat it as an expected (non-error) outcome on clear/reload.\n */\nexport function isAbortError(error: unknown): boolean {\n // Detect purely by name: a `DOMException` is NOT `instanceof Error` in Safari\n // and older engines, so gating on `instanceof Error` would misclassify a real\n // user abort as a failure in the browser (this package runs client-side).\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"name\" in error &&\n (error as { name?: unknown }).name === \"AbortError\"\n );\n}\n\n/**\n * Type guard for dynamic suggestions config\n */\nfunction isDynamicSuggestionsConfig(\n config: SuggestionsConfig,\n): config is DynamicSuggestionsConfig {\n return \"instructions\" in config;\n}\n\n/**\n * Type guard for static suggestions config\n */\nfunction isStaticSuggestionsConfig(\n config: SuggestionsConfig,\n): config is StaticSuggestionsConfig {\n return \"suggestions\" in config;\n}\n\n/**\n * The tool definition for AI-generated suggestions\n */\nconst SUGGEST_TOOL: Tool = {\n name: \"copilotkitSuggest\",\n description: \"Suggest what the user could say next\",\n parameters: {\n type: \"object\",\n properties: {\n suggestions: {\n type: \"array\",\n description: \"List of suggestions shown to the user as buttons.\",\n items: {\n type: \"object\",\n properties: {\n title: {\n type: \"string\",\n description:\n \"The title of the suggestion. This is shown as a button and should be short.\",\n },\n message: {\n type: \"string\",\n description:\n \"The message to send when the suggestion is clicked. This should be a clear, complete sentence \" +\n \"and will be sent as an instruction to the AI.\",\n },\n },\n required: [\"title\", \"message\"],\n },\n },\n },\n required: [\"suggestions\"],\n },\n};\n","/**\n * Single authority for the forwarded-to-client sentinel used by StateManager\n * and RunHandler.\n */\nexport const FORWARDED_TO_CLIENT = \"Forwarded to client\";\n\nexport function normalizeToolResultContent(content: unknown): string | null {\n if (typeof content === \"string\") return content.trim();\n\n if (Array.isArray(content)) {\n const text = content\n .flatMap((part) => {\n if (typeof part === \"string\") return [part];\n if (\n part &&\n typeof part === \"object\" &&\n \"text\" in part &&\n typeof (part as { text?: unknown }).text === \"string\"\n ) {\n return [(part as { text: string }).text];\n }\n return [];\n })\n .join(\"\")\n .trim();\n return text.length > 0 ? text : null;\n }\n\n if (\n content &&\n typeof content === \"object\" &&\n \"text\" in content &&\n typeof (content as { text?: unknown }).text === \"string\"\n ) {\n return (content as { text: string }).text.trim();\n }\n\n return null;\n}\n\nexport function isForwardedToClientPlaceholder(content: unknown): boolean {\n return normalizeToolResultContent(content) === FORWARDED_TO_CLIENT;\n}\n","import { schemaToJsonSchema } from \"@copilotkit/shared\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\nimport type { FrontendTool } from \"../types\";\n\n/**\n * Empty tool schema constant\n */\nconst EMPTY_TOOL_SCHEMA = {\n type: \"object\",\n properties: {},\n} as const satisfies Record<string, unknown>;\n\n/**\n * Create a JSON schema from a tool's parameters\n */\nexport function createToolSchema(\n tool: FrontendTool<any>,\n): Record<string, unknown> {\n if (!tool.parameters) {\n return { ...EMPTY_TOOL_SCHEMA };\n }\n\n const rawSchema = schemaToJsonSchema(tool.parameters, {\n zodToJsonSchema: (schema, options) =>\n zodToJsonSchema(\n schema as Parameters<typeof zodToJsonSchema>[0],\n options as Parameters<typeof zodToJsonSchema>[1],\n ),\n });\n\n if (!rawSchema || typeof rawSchema !== \"object\") {\n return { ...EMPTY_TOOL_SCHEMA };\n }\n\n const { $schema: _$schema, ...schema } = rawSchema as Record<string, unknown>;\n\n if (typeof schema.type !== \"string\") {\n schema.type = \"object\";\n }\n if (typeof schema.properties !== \"object\" || schema.properties === null) {\n schema.properties = {};\n }\n\n stripAdditionalProperties(schema);\n return schema;\n}\n\n/**\n * Remove every `additionalProperties` key from a JSON schema tree, in place.\n * Some LLM providers reject schemas that carry it.\n */\nfunction stripAdditionalProperties(schema: unknown): void {\n if (!schema || typeof schema !== \"object\") {\n return;\n }\n\n if (Array.isArray(schema)) {\n schema.forEach(stripAdditionalProperties);\n return;\n }\n\n const record = schema as Record<string, unknown>;\n\n if (record.additionalProperties !== undefined) {\n delete record.additionalProperties;\n }\n\n for (const value of Object.values(record)) {\n stripAdditionalProperties(value);\n }\n}\n","import type { ToolCall } from \"@ag-ui/client\";\nimport { logger, randomUUID } from \"@copilotkit/shared\";\nimport type { FrontendTool, WebMCPToolAnnotations } from \"../types\";\nimport { createToolSchema } from \"./tool-schema\";\n\n/**\n * The subset of the WebMCP `ModelContext` API\n * (https://webmachinelearning.github.io/webmcp/) that the registry depends on.\n * Kept structural so the code works against the real browser API and test\n * doubles alike. Aborting the registration signal unregisters the tool.\n */\nexport interface WebMCPModelContext {\n registerTool(\n tool: {\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n execute: (\n args: Record<string, unknown>,\n options: { signal?: AbortSignal },\n ) => Promise<unknown>;\n annotations?: WebMCPToolAnnotations;\n },\n options: { signal: AbortSignal },\n ): Promise<undefined>;\n}\n\n/**\n * Return the page's `document.modelContext`, or null when WebMCP is not\n * available (SSR, React Native, browsers without the API enabled).\n */\nexport function getWebMCPModelContext(): WebMCPModelContext | null {\n if (typeof document === \"undefined\") {\n return null;\n }\n const modelContext = (\n document as Document & { modelContext?: WebMCPModelContext }\n ).modelContext;\n return modelContext ?? null;\n}\n\ninterface WebMCPRegistryEntry {\n tool: FrontendTool<any>;\n controller: AbortController;\n}\n\n/**\n * Keeps a set of frontend tools registered on the page's WebMCP model context.\n *\n * `sync(desired)` reconciles the registrations with the desired set: tools that\n * are gone (or were re-registered with a new tool object) are unregistered by\n * aborting their registration signal, and new tools are registered with an\n * `execute` that delegates to the frontend tool's own handler.\n *\n * All WebMCP-API constraints live here so callers only supply the desired set:\n * a tool without a description is skipped with a warning (the spec rejects\n * empty descriptions), and failures from `registerTool` (duplicate name,\n * unsupported context, ...) are warned rather than thrown.\n */\nexport class WebMCPRegistry {\n private entries = new Map<string, WebMCPRegistryEntry>();\n private warnedNames = new Set<string>();\n\n /** Names currently kept registered on the model context. */\n get registeredNames(): string[] {\n return [...this.entries.keys()];\n }\n\n /** Reconcile the registered tools with the desired set. */\n sync(desired: Map<string, FrontendTool<any>>): void {\n const modelContext = getWebMCPModelContext();\n if (!modelContext) {\n return;\n }\n\n for (const [name, entry] of [...this.entries]) {\n if (desired.get(name) !== entry.tool) {\n entry.controller.abort();\n this.entries.delete(name);\n }\n }\n\n for (const [name, tool] of desired) {\n if (this.entries.has(name)) {\n continue;\n }\n if (!tool.description) {\n this.warnOnce(\n name,\n `Skipping WebMCP registration for tool '${name}': WebMCP requires a description.`,\n );\n continue;\n }\n\n const controller = new AbortController();\n this.entries.set(name, { tool, controller });\n modelContext\n .registerTool(\n this.buildModelContextTool(\n tool as FrontendTool<any> & { description: string },\n ),\n { signal: controller.signal },\n )\n .catch((error) => {\n // Registration failed (duplicate name, insecure context, permission\n // policy, ...). Drop the bookkeeping; the browser never registered.\n // Only delete while this is still the active registration: an\n // aborted registration can reject after a newer one already replaced\n // it, and that replacement's bookkeeping must survive.\n if (this.entries.get(name)?.controller !== controller) {\n return;\n }\n this.entries.delete(name);\n const message =\n error instanceof Error ? error.message : String(error);\n this.warnOnce(\n name,\n `WebMCP registration failed for tool '${name}': ${message}`,\n );\n });\n }\n }\n\n /**\n * Build the WebMCP model-context tool for a frontend tool. The `execute`\n * callback delegates to the frontend tool's own handler, so a browser agent\n * call runs the same application code as an agent call.\n */\n private buildModelContextTool(\n tool: FrontendTool<any> & { description: string },\n ): {\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n execute: (\n args: Record<string, unknown>,\n options: { signal?: AbortSignal },\n ) => Promise<unknown>;\n annotations?: WebMCPToolAnnotations;\n } {\n const annotations =\n typeof tool.webmcp === \"object\" ? tool.webmcp.annotations : undefined;\n return {\n name: tool.name,\n description: tool.description,\n inputSchema: createToolSchema(tool),\n execute: async (args, options) => {\n if (!tool.handler) {\n // Mirrors core's empty tool result for a display-only tool.\n return \"\";\n }\n const toolCall: ToolCall = {\n id: randomUUID(),\n type: \"function\",\n function: {\n name: tool.name,\n arguments: JSON.stringify(args ?? {}),\n },\n };\n return await tool.handler(args as any, {\n toolCall,\n signal: options?.signal,\n });\n },\n ...(annotations ? { annotations } : {}),\n };\n }\n\n /** Log `message` once per tool name. Repeated syncs must not spam the log. */\n private warnOnce(name: string, message: string): void {\n if (this.warnedNames.has(name)) {\n return;\n }\n this.warnedNames.add(name);\n logger.warn(`[CopilotKit] ${message}`);\n }\n}\n","import type {\n AbstractAgent,\n AgentSubscriber,\n Message,\n RunAgentResult,\n ResumeEntry,\n Tool,\n ToolCall,\n} from \"@ag-ui/client\";\nimport { randomUUID, logger } from \"@copilotkit/shared\";\nimport type { CopilotKitCore, CopilotKitCoreFriendsAccess } from \"./core\";\nimport { CopilotKitCoreErrorCode } from \"./core\";\nimport { AgentThreadLockedError } from \"../intelligence-agent\";\nimport type { FrontendTool } from \"../types\";\nimport { isAbortError } from \"../utils/abort-error\";\nimport type { CopilotKitCoreContinuationHandoff } from \"./state-manager\";\nimport { isForwardedToClientPlaceholder } from \"./tool-result-content\";\nimport { createToolSchema } from \"./tool-schema\";\nimport { WebMCPRegistry } from \"./webmcp\";\n\n/**\n * Live approvals cancelled by stopping their own run, keyed by the handler's\n * signal. The value reports whether that stop is still current: no reconnect\n * has started and the thread is unchanged, so nothing will restore the call.\n *\n * Kept here rather than in `AbortSignal.reason`: React Native's global\n * `AbortController` is the `abort-controller@3` polyfill, whose `abort()`\n * takes no reason and whose signals never expose one.\n */\nconst liveHITLStops = new WeakMap<AbortSignal, () => boolean>();\n\n// Explicitly stopping a live approval must retain its error result. History\n// restoration and thread-switch cancellation instead discard the old result.\nfunction discardAbortedResult(\n signal: AbortSignal | undefined,\n discardOnAbort: boolean,\n errorMessage?: string,\n): boolean {\n return !!(\n discardOnAbort &&\n signal?.aborted &&\n !(liveHITLStops.get(signal)?.() && errorMessage)\n );\n}\n\nexport interface CopilotKitCoreRunAgentParams {\n agent: AbstractAgent;\n forwardedProps?: Record<string, unknown>;\n /**\n * Optional caller-supplied run identifier forwarded to the underlying AG-UI\n * agent. When omitted, the agent creates one.\n */\n runId?: string;\n /**\n * Per-interrupt responses addressing every open AG-UI interrupt from the\n * previous run. Forwarded to the agent as the standard `resume` array.\n */\n resume?: ResumeEntry[];\n}\n\nexport interface CopilotKitCoreConnectAgentParams {\n agent: AbstractAgent;\n}\n\nexport interface CopilotKitCoreGetToolParams {\n toolName: string;\n agentId?: string;\n}\n\n/**\n * Parameters for programmatic tool execution via `copilotkit.runTool()`.\n */\nexport interface CopilotKitCoreRunToolParams {\n /** Name of the registered frontend tool to execute. */\n name: string;\n /** Optional agent ID. If omitted, uses the default agent lookup. */\n agentId?: string;\n /** Parameters to pass to the tool handler. */\n parameters?: Record<string, unknown>;\n /**\n * Whether to trigger an LLM follow-up after tool execution.\n * - `false` (default): execute tool, add messages to history, done.\n * - `\"generate\"`: after execution, trigger another agent run so the LLM responds to the tool result.\n * - Any other string: add a user message with this text, then trigger another agent run.\n */\n followUp?: string | false;\n}\n\n/**\n * Result of programmatic tool execution via `copilotkit.runTool()`.\n */\nexport interface CopilotKitCoreRunToolResult {\n /** The unique ID of the tool call. */\n toolCallId: string;\n /** The stringified result from the tool handler. */\n result: string;\n /** Error message if the handler failed. */\n error?: string;\n}\n\n/**\n * Internal result from the shared tool handler execution logic.\n */\ninterface ExecuteToolHandlerResult {\n result: string;\n error?: string;\n isArgumentError: boolean;\n}\n\n/**\n * A registered A2UI catalog component, as exposed to the inspector via\n * `CopilotKitCore.catalogComponents`. `schema` is an opaque JSON-schema-ish\n * value (the built catalog's Zod schema or a serialized form); the inspector\n * treats it as unknown. `description` is optional because the built\n * `ComponentApi` does not carry descriptions.\n */\nexport interface CopilotKitCoreCatalogComponent {\n name: string;\n description?: string;\n schema: unknown;\n}\n\n/**\n * Absolute safety cap on the depth of recursive follow-up runs triggered by\n * `processAgentResult`. Without this, any scenario that keeps\n * `needsFollowUp = true` (e.g. the LLM repeatedly calling the same tool, a\n * backend that errors after receiving tool results, or input processors that\n * reprocess tool messages) would loop indefinitely, silently consuming API\n * quota and potentially DOS'ing the backend.\n *\n * The cap is deliberately high so that legitimate multi-step agent workflows\n * (search → fill form → confirm → update → send email, etc.) are never\n * affected; it only trips on runaway recursion.\n */\nconst MAX_FOLLOW_UP_DEPTH = 100;\n\n/**\n * Name of the catch-all frontend tool. A tool registered under this name\n * handles any tool call that has no exact match (see `executeWildcardTool`),\n * and is never advertised to the agent.\n */\nconst WILDCARD_TOOL_NAME = \"*\";\n\n/**\n * Handles agent execution, tool calling, and agent connectivity for CopilotKitCore.\n * Manages the complete lifecycle of agent runs including tool execution and follow-ups.\n */\nexport class RunHandler {\n /**\n * Tools owned by the framework provider, replaced wholesale by\n * {@link initialize} and {@link setTools} whenever the provider re-syncs its\n * props or runtime feature flags.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _propTools: FrontendTool<any>[] = [];\n\n /**\n * Tools registered imperatively via {@link addTool} — `useFrontendTool`,\n * `useHumanInTheLoop`, and direct `core.addTool()` callers. Held separately\n * from {@link _propTools} so a provider re-sync cannot wipe them: they shared\n * one array before, so the `/info` response flipping `openGenerativeUI` (or\n * any other provider-prop change) silently dropped every hook-registered\n * tool (#4952). Key = `capabilityKey(name, agentId)`.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _hookTools: Map<string, FrontendTool<any>> = new Map();\n\n /**\n * Memoized merge of both buckets, invalidated on every registry write.\n *\n * This is about identity, not speed: `tools` is public and used to return the\n * same array instance until something mutated the registry, so consumers can\n * hold it or use it as an effect dependency. Rebuilding the merge on every\n * read would hand out a new array each time.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _cachedMergedTools: FrontendTool<any>[] | null = null;\n\n /**\n * The full list of A2UI catalog components registered by the provider.\n * Order is preserved for display in the inspector.\n */\n private _catalogComponents: CopilotKitCoreCatalogComponent[] = [];\n\n /**\n * Names of catalog components the caller has explicitly disabled. A name\n * absent from this set is enabled (default). Survives re-registration so a\n * catalog identity change does not silently re-enable a disabled component.\n */\n private _disabledCatalogComponents: Set<string> = new Set();\n\n /**\n * Keys of frontend tools explicitly disabled at runtime via the Inspector's\n * Capabilities tool (`setToolEnabled`). Kept independently of each tool's own\n * `available` flag so a hook re-registering the tool (which resets\n * `available`) does not clobber the override. Key = `capabilityKey(name, agentId)`.\n */\n private _disabledToolKeys = new Set<string>();\n\n /**\n * Registry keys already reported by {@link warnOnMissingToolParameters}.\n * Development only, and per instance rather than per module so tests and\n * multiple cores stay independent. Deliberately NOT cleared by\n * {@link removeTool}: `useFrontendTool` tears down and re-registers on every\n * dependency change, so clearing it would turn one warning into one per\n * render. Key = `capabilityKey(name, agentId)`.\n */\n private _warnedMissingToolParameters = new Set<string>();\n\n /**\n * Tracks whether the current run (including in-flight tool execution)\n * has been aborted via `stopAgent()` or `agent.abortRun()`. Created\n * fresh in `runAgent()`, aborted by `abortCurrentRun()`.\n */\n private _runAbortController: AbortController | null = null;\n\n /**\n * Tracks recursive `runAgent` depth so that the abort controller and\n * `agent.abortRun()` intercept are only set up / torn down at the\n * top-level call, not on follow-up recursive calls from\n * `processAgentResult`.\n */\n private _runDepth = 0;\n\n /**\n * Keeps tools that opt in via `webmcp` registered on the page's WebMCP model\n * context (`document.modelContext`), in addition to the normal agent\n * registration. Reconciled on every tool registry mutation.\n */\n private _webmcpRegistry = new WebMCPRegistry();\n\n /**\n * Tracks the threadId of the most recent `connectAgent` call so we\n * can distinguish a fresh thread restore (different threadId than\n * last time — chat is rebuilding state from scratch, must clear\n * messages/state and ask the gateway for a full replay) from a\n * same-thread churn re-connect (effect-dep churn or transient\n * disconnect — local messages/state are still meaningful, must\n * preserve them and let the gateway resume from\n * `lastSeenEventId`).\n *\n * Tyler's bug fired because every `connectAgent` was treated as a\n * fresh restore, which forced the gateway to replay the full\n * thread history on every churn re-connect and amplified the\n * downstream churn into duplicate `cpki_event_id` rows in the\n * inspector and intermittent \"Message not found\" toasts.\n */\n private _lastConnectedThreadIdsByAgent = new Map<string, string | null>();\n private _anonymousAgentIds = new WeakMap<AbstractAgent, string>();\n private _nextAnonymousAgentId = 0;\n\n /** Prevent reconnects from starting an interaction already executing locally. */\n private _executingToolCalls = new WeakMap<AbstractAgent, Set<string>>();\n\n private _connectionGenerations = new WeakMap<AbstractAgent, object>();\n\n private _interactionAbortControllers = new WeakMap<\n AbstractAgent,\n {\n threadId: string | null;\n controllers: Set<AbortController>;\n }\n >();\n\n constructor(private core: CopilotKitCore) {}\n\n /**\n * Abort the current run. Called by `CopilotKitCore.stopAgent()` to signal\n * that in-flight tool handlers should stop and `processAgentResult` should\n * not start a follow-up run.\n */\n abortCurrentRun(agent: AbstractAgent): void {\n this._runAbortController?.abort();\n const replay = this._interactionAbortControllers.get(agent);\n if (replay) {\n for (const controller of replay.controllers) controller.abort();\n this._interactionAbortControllers.delete(agent);\n // Cancellation is cooperative: an old handler may never settle. Let a\n // reconnect restore it without waiting for its execution marker to clear.\n this._executingToolCalls.delete(agent);\n }\n }\n\n /**\n * Typed access to CopilotKitCore's internal (\"friend\") methods.\n * Centralises the single unavoidable cast so call-sites stay clean.\n */\n private get _internal(): CopilotKitCoreFriendsAccess {\n return this.core as unknown as CopilotKitCoreFriendsAccess;\n }\n\n /**\n * Return a stable restore-tracking key for the logical agent being\n * connected. Named agents share their last-thread marker across proxy\n * instances; anonymous agents fall back to object identity.\n */\n private getConnectRestoreKey(agent: AbstractAgent): string {\n if (agent.agentId) {\n return `agent:${agent.agentId}`;\n }\n\n const existing = this._anonymousAgentIds.get(agent);\n if (existing) {\n return existing;\n }\n\n const anonymousId = `anonymous:${this._nextAnonymousAgentId}`;\n this._nextAnonymousAgentId += 1;\n this._anonymousAgentIds.set(agent, anonymousId);\n return anonymousId;\n }\n\n /**\n * Get all tools as a readonly array: provider-owned tools in registration\n * order, with imperatively-added tools appended and taking precedence over a\n * provider tool of the same name + agentId.\n */\n get tools(): Readonly<FrontendTool<any>[]> {\n if (this._hookTools.size === 0) {\n return this._propTools;\n }\n if (this._cachedMergedTools) {\n return this._cachedMergedTools;\n }\n // Merge: hook entries override prop entries with the same key. Overriding\n // an existing key keeps the prop entry's position, so provider order is\n // preserved and only genuinely new hook tools land at the end.\n const merged = new Map<string, FrontendTool<any>>();\n for (const tool of this._propTools) {\n merged.set(this.capabilityKey(tool.name, tool.agentId), tool);\n }\n for (const [key, tool] of this._hookTools) {\n merged.set(key, tool);\n }\n this._cachedMergedTools = Array.from(merged.values());\n return this._cachedMergedTools;\n }\n\n /**\n * Initialize with tools\n */\n initialize(tools: FrontendTool<any>[]): void {\n // Copied, like `setTools` does: the merged view is memoized, so holding the\n // caller's array would let an in-place mutation of it go unnoticed. (It\n // also used to be mutated from this side — `addTool` pushed straight onto\n // the array the provider passed in.)\n this._propTools = [...tools];\n this._cachedMergedTools = null;\n this.warnOnMissingToolParameters(this._propTools);\n this.syncWebMCP();\n }\n\n /**\n * Add a tool to the registry. Survives provider re-syncs ({@link setTools}),\n * and shadows a provider tool of the same name + agentId.\n */\n addTool<T extends Record<string, unknown> = Record<string, unknown>>(\n tool: FrontendTool<T>,\n ): void {\n const key = this.capabilityKey(tool.name, tool.agentId);\n\n // Only a competing imperative registration is a conflict. A provider tool\n // of the same name is shadowed rather than treated as a duplicate — hooks\n // mount after the provider and are the more specific registration.\n if (this._hookTools.has(key)) {\n logger.warn(\n `Tool already exists: '${tool.name}' for agent '${tool.agentId || \"global\"}', skipping.`,\n );\n return;\n }\n\n this._hookTools.set(key, tool);\n this._cachedMergedTools = null;\n this.warnOnMissingToolParameters([tool]);\n this.syncWebMCP();\n }\n\n /**\n * Report, once per tool and at development time only, a tool registered with\n * no `parameters` schema.\n *\n * `createToolSchema` substitutes `{ type: \"object\", properties: {} }` for a\n * missing `parameters` and returns silently, and `parameters` is optional on\n * `FrontendTool`, so nothing — not the compiler, not the runtime — tells the\n * developer that the model was handed a tool with nothing to fill in. It then\n * calls the tool with no arguments. `useComponent`, `useFrontendTool` and\n * `useHumanInTheLoop` all funnel into {@link addTool}; the provider's `tools`\n * prop funnels into {@link initialize} and {@link setTools}.\n *\n * A parameterless tool is legitimate (a HITL confirm dialog, say), so this\n * stays a warning rather than an error. An explicit empty schema\n * (`parameters: z.object({})`) is the way to say \"takes none on purpose\": it\n * satisfies the check below and `createToolSchema` reduces it to the same\n * advertised `{ type: \"object\", properties: {} }` that omitting `parameters`\n * produces, so silencing the warning costs nothing on the wire.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private warnOnMissingToolParameters(tools: FrontendTool<any>[]): void {\n if (process.env.NODE_ENV === \"production\") {\n return;\n }\n\n for (const tool of tools) {\n if (tool.parameters) {\n continue;\n }\n const key = this.capabilityKey(tool.name, tool.agentId);\n if (this._warnedMissingToolParameters.has(key)) {\n continue;\n }\n this._warnedMissingToolParameters.add(key);\n logger.warn(\n `Tool has no parameters schema: '${tool.name}' for agent '${tool.agentId || \"global\"}'. ` +\n `The model is told it takes no arguments and will call it with none. ` +\n `Add \\`parameters\\` (a Zod or Standard Schema object) if it should ` +\n `receive arguments, or \\`parameters: z.object({})\\` to declare that it ` +\n `takes none and silence this warning.`,\n );\n }\n }\n\n /**\n * Remove a tool by name and optionally by agentId\n */\n removeTool(id: string, agentId?: string): void {\n this._hookTools.delete(this.capabilityKey(id, agentId));\n this._propTools = this._propTools.filter((tool) => {\n // Remove tool if both name and agentId match\n if (agentId !== undefined) {\n return !(tool.name === id && tool.agentId === agentId);\n }\n // If no agentId specified, only remove global tools with matching name\n return !(tool.name === id && !tool.agentId);\n });\n this._cachedMergedTools = null;\n this.syncWebMCP();\n }\n\n /**\n * Get a tool by name and optionally by agentId.\n * If agentId is provided, it will first look for an agent-specific tool,\n * then fall back to a global tool with the same name.\n */\n getTool(params: CopilotKitCoreGetToolParams): FrontendTool<any> | undefined {\n const { toolName, agentId } = params;\n const tools = this.tools;\n\n // If agentId is provided, first look for agent-specific tool\n if (agentId) {\n const agentTool = tools.find(\n (tool) => tool.name === toolName && tool.agentId === agentId,\n );\n if (agentTool) {\n return agentTool;\n }\n }\n\n // Fall back to global tool (no agentId)\n return tools.find((tool) => tool.name === toolName && !tool.agentId);\n }\n\n /**\n * Set all provider-owned tools at once. Replaces the previous provider set;\n * tools registered via {@link addTool} are unaffected.\n */\n setTools(tools: FrontendTool<any>[]): void {\n this._propTools = [...tools];\n this._cachedMergedTools = null;\n this.warnOnMissingToolParameters(this._propTools);\n this.syncWebMCP();\n }\n\n /**\n * Return the registered A2UI catalog components (readonly).\n */\n get catalogComponents(): ReadonlyArray<CopilotKitCoreCatalogComponent> {\n return this._catalogComponents;\n }\n\n /**\n * Replace the registered catalog component list. Preserves the disabled set\n * (by name) so re-registration does not re-enable disabled components.\n */\n setCatalogComponents(components: CopilotKitCoreCatalogComponent[]): void {\n this._catalogComponents = [...components];\n }\n\n /**\n * Enable or disable a catalog component by name.\n */\n setCatalogComponentEnabled(name: string, enabled: boolean): void {\n if (enabled) {\n this._disabledCatalogComponents.delete(name);\n } else {\n this._disabledCatalogComponents.add(name);\n }\n }\n\n /**\n * Whether a catalog component is enabled. Unknown names default to enabled.\n */\n isCatalogComponentEnabled(name: string): boolean {\n return !this._disabledCatalogComponents.has(name);\n }\n\n /**\n * Connect an agent (establish initial connection)\n */\n async connectAgent({\n agent,\n }: CopilotKitCoreConnectAgentParams): Promise<RunAgentResult> {\n this._connectionGenerations.set(agent, {});\n const incomingThreadId = agent.threadId ?? null;\n const previousReplay = this._interactionAbortControllers.get(agent);\n if (previousReplay && previousReplay.threadId !== incomingThreadId) {\n for (const controller of previousReplay.controllers) controller.abort();\n this._interactionAbortControllers.delete(agent);\n // Old handlers retain their own set until they settle. They must not\n // prevent a fresh restoration when navigating back to this thread.\n this._executingToolCalls.delete(agent);\n }\n try {\n const restoreKey = this.getConnectRestoreKey(agent);\n const isFreshRestore =\n incomingThreadId !==\n (this._lastConnectedThreadIdsByAgent.get(restoreKey) ?? null);\n this._lastConnectedThreadIdsByAgent.set(restoreKey, incomingThreadId);\n\n // Detach any active run before connecting to avoid previous runs\n // interfering. This stays unconditional — both fresh restores and\n // churn re-connects need the previous socket torn down before a new\n // one can open.\n await agent.detachActiveRun();\n\n // State reset + replay-cursor clear are gated on actually moving\n // to a different thread. On same-thread churn, the local\n // messages/state are still the right view of the thread, and the\n // gateway can resume from `lastSeenEventId` instead of replaying\n // the full history.\n if (isFreshRestore) {\n agent.setMessages([]);\n agent.setState({});\n const cursorAware = agent as {\n clearReconnectCursor?: (id: string) => void;\n clearReplayCursor?: (id: string) => void;\n };\n if (incomingThreadId) {\n if (typeof cursorAware.clearReplayCursor === \"function\") {\n cursorAware.clearReplayCursor(incomingThreadId);\n }\n if (typeof cursorAware.clearReconnectCursor === \"function\") {\n cursorAware.clearReconnectCursor(incomingThreadId);\n }\n }\n }\n\n // Re-apply core headers (merged on top of the agent's own headers) so a\n // late header update is picked up without clobbering per-agent headers.\n this._internal.applyHeadersToAgent(agent);\n\n // Notify subscribers (e.g. the inspector) about the agent that is about\n // to run. Per-thread clones are not in the agent registry, so\n // onAgentsChanged never fires for them and they would otherwise be\n // invisible to subscribers.\n await this._internal.notifySubscribers(\n (subscriber) =>\n subscriber.onAgentRunStarted?.({\n copilotkit: this.core,\n agent,\n }),\n \"Subscriber onAgentRunStarted error:\",\n );\n\n const runAgentResult = await agent.connectAgent(\n {\n forwardedProps: this._internal.properties,\n tools: this.buildFrontendTools(agent.agentId),\n context: this._internal.getContextForAgent(agent.agentId),\n },\n this.createAgentErrorSubscriber(agent),\n );\n\n // Connecting ends when history is restored, not when a human answers.\n // Keeping this promise open would block run-activity reconnects while\n // another client answers the same interaction.\n if ((agent.threadId ?? null) !== incomingThreadId) return runAgentResult;\n const controller = new AbortController();\n const replay = this._interactionAbortControllers.get(agent) ?? {\n threadId: incomingThreadId,\n controllers: new Set<AbortController>(),\n };\n replay.controllers.add(controller);\n this._interactionAbortControllers.set(agent, replay);\n void this.processAgentResult({\n runAgentResult,\n agent,\n toolExecutionMode: \"human-in-the-loop\",\n signal: controller.signal,\n })\n .catch(async (error: unknown) => {\n await this._internal.emitError({\n error: error instanceof Error ? error : new Error(String(error)),\n code: CopilotKitCoreErrorCode.AGENT_CONNECT_FAILED,\n context: { agentId: agent.agentId, threadId: incomingThreadId },\n });\n })\n .finally(() => {\n replay.controllers.delete(controller);\n if (\n replay.controllers.size === 0 &&\n this._interactionAbortControllers.get(agent) === replay\n ) {\n this._interactionAbortControllers.delete(agent);\n }\n });\n return runAgentResult;\n } catch (error) {\n const connectError =\n error instanceof Error ? error : new Error(String(error));\n // Silently ignore abort errors (e.g. from navigation during active\n // requests).\n if (!isAbortError(connectError)) {\n const context: Record<string, any> = {};\n if (agent.agentId) {\n context.agentId = agent.agentId;\n }\n if (incomingThreadId) {\n context.threadId = incomingThreadId;\n }\n await this._internal.emitError({\n error: connectError,\n code: CopilotKitCoreErrorCode.AGENT_CONNECT_FAILED,\n context,\n });\n }\n return { result: undefined, newMessages: [] };\n }\n }\n\n /**\n * Run an agent\n */\n async runAgent(\n { agent, forwardedProps, resume, runId }: CopilotKitCoreRunAgentParams,\n continuationHandoff?: CopilotKitCoreContinuationHandoff,\n ): Promise<RunAgentResult> {\n // Agent ID is guaranteed to be set by validateAndAssignAgentId\n if (agent.agentId) {\n void this._internal.suggestionEngine.clearSuggestions(agent.agentId);\n }\n\n // Re-apply core headers (merged on top of the agent's own headers) so a\n // late header update is picked up without clobbering per-agent headers.\n this._internal.applyHeadersToAgent(agent);\n\n // Detach any active run (e.g. a long-lived connectAgent pipeline) before\n // starting a new run. We await the detach to ensure the previous pipeline\n // has fully finalized — its activeRunCompletionPromise resolves once the\n // observable finalize block runs, which happens synchronously after the\n // takeUntil signal completes the chain. This prevents a race where the new\n // runAgent() overwrites activeRunDetach$ / activeRunCompletionPromise before\n // the old pipeline can clean up, causing dropped runs.\n //\n // Historical note: an earlier version used fire-and-forget (`void`) here\n // because awaiting caused a deadlock when connectAgent's\n // ConnectNotImplementedError cleanup was still in-flight. That deadlock\n // was resolved in @ag-ui/client ≥0.0.42 where the catchError path\n // (ConnectNotImplementedError → EMPTY) always runs the finalize block,\n // so the completion promise now resolves reliably.\n if (agent.detachActiveRun) {\n try {\n await agent.detachActiveRun();\n } catch (error) {\n continuationHandoff?.cancel();\n throw error;\n }\n }\n\n // Set up abort controller and agent.abortRun() intercept only for the\n // top-level call. Recursive follow-up calls from processAgentResult\n // reuse the same controller.\n const isTopLevel = this._runDepth === 0;\n let originalAbortRun: (() => void) | undefined;\n\n if (isTopLevel) {\n this._runAbortController = new AbortController();\n\n // Intercept agent.abortRun() so that calling it directly (not via\n // stopAgent) also aborts in-flight tool execution and prevents\n // follow-up runs.\n const controller = this._runAbortController;\n originalAbortRun = agent.abortRun.bind(agent);\n agent.abortRun = () => {\n controller.abort();\n originalAbortRun!();\n };\n\n // Notify subscribers (e.g. the inspector) about the agent that is about\n // to run. Per-thread clones are not in the agent registry, so\n // onAgentsChanged never fires for them and they would otherwise be\n // invisible to subscribers. Fired once per top-level run; recursive\n // follow-up runs reuse the same instance and need no re-notification.\n await this._internal.notifySubscribers(\n (subscriber) =>\n subscriber.onAgentRunStarted?.({\n copilotkit: this.core,\n agent,\n }),\n \"Subscriber onAgentRunStarted error:\",\n );\n }\n\n this._runDepth++;\n\n try {\n let logicalRunId = runId;\n const agentSubscriber = this.createAgentErrorSubscriber(agent);\n let started = false;\n const onRunStartedEvent = agentSubscriber.onRunStartedEvent;\n const onRunInitialized = agentSubscriber.onRunInitialized;\n agentSubscriber.onRunInitialized = async (params) => {\n continuationHandoff?.bind(params.input);\n return onRunInitialized?.(params);\n };\n agentSubscriber.onRunStartedEvent = async (params) => {\n started = true;\n // A continuation keeps reporting under the run it continues; only an\n // ordinary run adopts the id the transport assigned it.\n if (!continuationHandoff) {\n logicalRunId = params.input.runId;\n }\n return onRunStartedEvent?.(params);\n };\n // An internal continuation (a human-in-the-loop tool resolved and this is\n // the recursive follow-up) deliberately does NOT pin the originating run\n // id on the wire. Pinning it made the transport treat the follow-up as a\n // resumption of a run it had already completed: it re-delivered that\n // run's applied half — duplicating every tool call already on the\n // message, each duplicate carrying empty arguments — and the follow-up's\n // own tool call never reached client state, so its card never rendered.\n //\n // One logical run is still what everything downstream sees: the state\n // manager re-stamps the continuation's events onto `runId` (passed to\n // markNextRunAsContinuation), and `logicalRunId` below keeps the result\n // reported under it. So external tracing still gets a single run without\n // the wire having to lie about which invocation this is.\n const pinRunIdOnWire = runId !== undefined && !continuationHandoff;\n const agentRunInput = {\n forwardedProps: {\n ...this._internal.properties,\n ...forwardedProps,\n },\n ...(resume !== undefined ? { resume } : {}),\n ...(pinRunIdOnWire ? { runId } : {}),\n tools: this.buildFrontendTools(agent.agentId),\n context: this._internal.getContextForAgent(agent.agentId),\n };\n const runAgentResult = await agent.runAgent(\n agentRunInput,\n agentSubscriber,\n );\n if (!started) {\n continuationHandoff?.cancel();\n }\n return await this.processAgentResult({\n runAgentResult,\n agent,\n runId: logicalRunId,\n });\n } catch (error) {\n continuationHandoff?.cancel();\n const runError =\n error instanceof Error ? error : new Error(String(error));\n const context: Record<string, any> = {};\n if (agent.agentId) {\n context.agentId = agent.agentId;\n }\n await this._internal.emitError({\n error: runError,\n code: CopilotKitCoreErrorCode.AGENT_RUN_FAILED,\n context,\n });\n return { result: undefined, newMessages: [] };\n } finally {\n this._runDepth--;\n // Restore original abortRun when the entire chain (including\n // recursive follow-ups) is complete.\n if (isTopLevel && originalAbortRun) {\n agent.abortRun = originalAbortRun;\n }\n }\n }\n\n /**\n * Process agent result and execute tools\n */\n private async processAgentResult({\n runAgentResult,\n agent,\n runId,\n toolExecutionMode = \"all\",\n signal = this._runAbortController?.signal,\n }: {\n runAgentResult: RunAgentResult;\n agent: AbstractAgent;\n runId?: string;\n toolExecutionMode?: \"all\" | \"human-in-the-loop\";\n signal?: AbortSignal;\n }): Promise<RunAgentResult> {\n const { newMessages } = runAgentResult;\n // Agent ID is guaranteed to be set by validateAndAssignAgentId\n const agentId = agent.agentId!;\n\n let needsFollowUp = false;\n\n const threadId = agent.threadId;\n const executing = this._executingToolCalls.get(agent) ?? new Set<string>();\n this._executingToolCalls.set(agent, executing);\n\n // One restoration pass owns the pending sequence. Skipping only the first\n // executing call would start later calls concurrently and replace a HITL\n // hook's response resolver. A saved remote answer releases this barrier.\n if (\n toolExecutionMode === \"human-in-the-loop\" &&\n agent.messages.some(\n (message) =>\n message.role === \"assistant\" &&\n message.toolCalls?.some(\n (call) =>\n executing.has(JSON.stringify([threadId, call.id])) &&\n !agent.messages.some(\n (result) =>\n result.role === \"tool\" &&\n result.toolCallId === call.id &&\n !this.isFrontendPlaceholderResult(result),\n ),\n ),\n )\n ) {\n return runAgentResult;\n }\n\n // Reconnect deltas omit messages already hydrated by earlier replays.\n // Reconcile the current history so a remote answer can unblock a pending\n // call that was already present. Snapshot it because handlers insert results.\n const messagesToProcess =\n toolExecutionMode === \"human-in-the-loop\"\n ? [...agent.messages]\n : newMessages;\n for (const message of messagesToProcess) {\n if (message.role === \"assistant\") {\n for (const toolCall of message.toolCalls || []) {\n const tool = this.getTool({\n toolName: toolCall.function.name,\n agentId: agent.agentId,\n });\n\n let wildcardTool: FrontendTool<any> | undefined;\n const getWildcardTool = () => {\n if (tool || wildcardTool) {\n return wildcardTool;\n }\n wildcardTool = this.getTool({\n toolName: WILDCARD_TOOL_NAME,\n agentId: agent.agentId,\n });\n return wildcardTool;\n };\n\n const executableTool = tool ?? getWildcardTool();\n if (\n toolExecutionMode === \"human-in-the-loop\" &&\n (executableTool?.type !== \"human-in-the-loop\" ||\n !executableTool.handler)\n ) {\n continue;\n }\n const executionKey = JSON.stringify([threadId, toolCall.id]);\n if (\n signal?.aborted ||\n agent.threadId !== threadId ||\n executing.has(executionKey)\n ) {\n continue;\n }\n\n const existingResultIndex = newMessages.findIndex(\n (m) => m.role === \"tool\" && m.toolCallId === toolCall.id,\n );\n // Live messages may contain a remote answer received while an\n // earlier handler awaited input; never replace it with stale replay.\n let existingResult =\n agent.messages.find(\n (m) => m.role === \"tool\" && m.toolCallId === toolCall.id,\n ) ?? newMessages[existingResultIndex];\n\n if (\n existingResult &&\n executableTool?.handler &&\n this.isFrontendPlaceholderResult(existingResult)\n ) {\n if (existingResultIndex !== -1)\n newMessages.splice(existingResultIndex, 1);\n existingResult = undefined;\n\n const agentMsgIdx = agent.messages.findIndex(\n (m) => m.role === \"tool\" && m.toolCallId === toolCall.id,\n );\n if (agentMsgIdx !== -1) {\n agent.messages.splice(agentMsgIdx, 1);\n }\n }\n\n if (!existingResult) {\n executing.add(executionKey);\n // Live HITL handlers need the same thread-switch cancellation as\n // restored ones, so returning to this thread can open a fresh UI.\n const interactionController =\n toolExecutionMode === \"all\" &&\n executableTool?.type === \"human-in-the-loop\"\n ? new AbortController()\n : undefined;\n const interactions = this._interactionAbortControllers.get(\n agent,\n ) ?? {\n threadId: threadId ?? null,\n controllers: new Set<AbortController>(),\n };\n const abortInteraction = () => {\n if (!interactionController) return;\n const connectionGeneration =\n this._connectionGenerations.get(agent);\n liveHITLStops.set(\n interactionController.signal,\n () =>\n this._connectionGenerations.get(agent) ===\n connectionGeneration && agent.threadId === threadId,\n );\n interactionController.abort();\n };\n if (interactionController) {\n interactions.controllers.add(interactionController);\n this._interactionAbortControllers.set(agent, interactions);\n signal?.addEventListener(\"abort\", abortInteraction, {\n once: true,\n });\n if (signal?.aborted) abortInteraction();\n }\n const executionSignal = interactionController?.signal ?? signal;\n const discardOnAbort =\n toolExecutionMode === \"human-in-the-loop\" ||\n !!interactionController;\n try {\n if (tool) {\n const followUp = await this.executeSpecificTool(\n tool,\n toolCall,\n message,\n agent,\n agentId,\n executionSignal,\n discardOnAbort,\n );\n if (followUp) {\n needsFollowUp = true;\n }\n } else {\n const fallbackTool = getWildcardTool();\n if (fallbackTool) {\n const followUp = await this.executeWildcardTool(\n fallbackTool,\n toolCall,\n message,\n agent,\n agentId,\n executionSignal,\n discardOnAbort,\n );\n if (followUp) {\n needsFollowUp = true;\n }\n }\n }\n } finally {\n executing.delete(executionKey);\n if (interactionController) {\n signal?.removeEventListener(\"abort\", abortInteraction);\n interactions.controllers.delete(interactionController);\n if (\n interactions.controllers.size === 0 &&\n this._interactionAbortControllers.get(agent) === interactions\n ) {\n this._interactionAbortControllers.delete(agent);\n }\n }\n }\n if (interactionController?.signal.aborted) return runAgentResult;\n }\n }\n }\n }\n\n if (needsFollowUp && agent.threadId === threadId && !signal?.aborted) {\n // Circuit breaker: bail out instead of recursing once the follow-up\n // chain exceeds an absolute safety cap. `_runDepth` reflects the current\n // depth of nested runAgent calls (it is incremented in runAgent and\n // decremented in its finally block), so a runaway loop — repeated\n // identical tool calls, a backend that keeps erroring after tool\n // results, reprocessed tool messages, etc. — eventually trips this\n // guard rather than looping forever and exhausting API quota.\n if (this._runDepth >= MAX_FOLLOW_UP_DEPTH) {\n logger.warn(\n `[CopilotKit] Follow-up depth limit (${MAX_FOLLOW_UP_DEPTH}) reached for agent \"${agentId}\". ` +\n `Stopping recursive follow-up runs to prevent an infinite loop. ` +\n `This usually indicates a tool that keeps requesting a follow-up (e.g. the LLM repeatedly ` +\n `calling the same tool). Consider setting \"followUp: false\" on the offending tool.`,\n );\n } else {\n // Yield to the framework scheduler before the follow-up run so that any\n // deferred state updates (e.g. React useEffect in useAgentContext) can\n // complete and write fresh values into the context store before runAgent\n // reads it. The base implementation is a no-op; React overrides this.\n await this._internal.waitForPendingFrameworkUpdates();\n const continuationHandoff =\n this._internal.stateManager.markNextRunAsContinuation(agent, runId);\n return await this.runAgent(\n {\n agent,\n ...(runId !== undefined ? { runId } : {}),\n },\n continuationHandoff,\n );\n }\n }\n\n void this._internal.suggestionEngine.reloadSuggestions(agentId);\n\n return runAgentResult;\n }\n\n private isFrontendPlaceholderResult(message: Message): boolean {\n return (\n message.role === \"tool\" && isForwardedToClientPlaceholder(message.content)\n );\n }\n\n /**\n * Shared handler execution logic used by executeSpecificTool, executeWildcardTool, and runTool.\n * Handles arg parsing, subscriber notifications, handler invocation, result stringification,\n * and error handling.\n */\n private async executeToolHandler({\n tool,\n toolCall,\n agent,\n agentId,\n handlerArgs,\n toolType,\n messageId,\n signal = this._runAbortController?.signal,\n discardOnAbort = false,\n }: {\n tool: FrontendTool<any>;\n toolCall: { id: string; function: { name: string; arguments: string } };\n agent: AbstractAgent;\n agentId: string;\n handlerArgs: unknown;\n toolType: string;\n messageId?: string;\n signal?: AbortSignal;\n discardOnAbort?: boolean;\n }): Promise<ExecuteToolHandlerResult> {\n let toolCallResult = \"\";\n let errorMessage: string | undefined;\n let isArgumentError = false;\n\n let parsedArgs: unknown;\n try {\n parsedArgs = parseToolArguments(handlerArgs, toolCall.function.name);\n } catch (error) {\n const parseError =\n error instanceof Error ? error : new Error(String(error));\n errorMessage = parseError.message;\n isArgumentError = true;\n await this._internal.emitError({\n error: parseError,\n code: CopilotKitCoreErrorCode.TOOL_ARGUMENT_PARSE_FAILED,\n context: {\n agentId,\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n rawArguments: handlerArgs,\n toolType,\n ...(messageId ? { messageId } : {}),\n },\n });\n }\n\n await this._internal.notifySubscribers(\n (subscriber) =>\n subscriber.onToolExecutionStart?.({\n copilotkit: this.core,\n toolCallId: toolCall.id,\n agentId,\n toolName: toolCall.function.name,\n args: parsedArgs,\n }),\n \"Subscriber onToolExecutionStart error:\",\n );\n\n if (!errorMessage) {\n try {\n const result = await tool.handler!(parsedArgs as any, {\n toolCall: toolCall as any,\n agent,\n signal,\n });\n if (result === undefined || result === null) {\n toolCallResult = \"\";\n } else if (typeof result === \"string\") {\n toolCallResult = result;\n } else {\n toolCallResult = JSON.stringify(result);\n }\n } catch (error) {\n const handlerError =\n error instanceof Error ? error : new Error(String(error));\n errorMessage = handlerError.message;\n if (!discardAbortedResult(signal, discardOnAbort, errorMessage)) {\n await this._internal.emitError({\n error: handlerError,\n code: CopilotKitCoreErrorCode.TOOL_HANDLER_FAILED,\n context: {\n agentId,\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n parsedArgs,\n toolType,\n ...(messageId ? { messageId } : {}),\n },\n });\n }\n }\n }\n\n if (errorMessage) {\n toolCallResult = `Error: ${errorMessage}`;\n }\n\n await this._internal.notifySubscribers(\n (subscriber) =>\n subscriber.onToolExecutionEnd?.({\n copilotkit: this.core,\n toolCallId: toolCall.id,\n agentId,\n toolName: toolCall.function.name,\n result: errorMessage ? \"\" : toolCallResult,\n error: errorMessage,\n }),\n \"Subscriber onToolExecutionEnd error:\",\n );\n\n return { result: toolCallResult, error: errorMessage, isArgumentError };\n }\n\n /**\n * Execute a specific tool\n */\n private async executeSpecificTool(\n tool: FrontendTool<any>,\n toolCall: ToolCall,\n message: Message,\n agent: AbstractAgent,\n agentId: string,\n signal?: AbortSignal,\n discardOnAbort = false,\n ): Promise<boolean> {\n const threadId = agent.threadId;\n // Check if tool is constrained to a specific agent\n if (tool?.agentId && tool.agentId !== agent.agentId) {\n // Tool is not available for this agent, skip it\n return false;\n }\n\n let handlerResult: ExecuteToolHandlerResult = {\n result: \"\",\n error: undefined,\n isArgumentError: false,\n };\n\n if (tool?.handler) {\n handlerResult = await this.executeToolHandler({\n tool,\n toolCall,\n agent,\n agentId,\n handlerArgs: toolCall.function.arguments,\n toolType: \"specific\",\n messageId: message.id,\n signal,\n discardOnAbort,\n });\n }\n\n {\n const messageIndex = agent.messages.findIndex((m) => m.id === message.id);\n if (\n discardAbortedResult(signal, discardOnAbort, handlerResult.error) ||\n agent.threadId !== threadId ||\n messageIndex === -1 ||\n agent.messages.some(\n (m) =>\n m.role === \"tool\" &&\n m.toolCallId === toolCall.id &&\n !this.isFrontendPlaceholderResult(m),\n )\n ) {\n // The interaction was removed, the thread changed, or another client\n // already answered. Do not insert a stale answer or start a follow-up.\n return false;\n }\n // Find the correct insertion point: after the parent assistant message\n // and any tool-result messages already inserted for earlier tool calls\n // in the same batch. This preserves tool-result ordering relative to\n // the toolCalls array, which some providers (OpenAI) require.\n let insertAt = messageIndex + 1;\n while (\n insertAt < agent.messages.length &&\n agent.messages[insertAt]?.role === \"tool\"\n ) {\n insertAt++;\n }\n const toolMessage = {\n id: randomUUID(),\n role: \"tool\" as const,\n toolCallId: toolCall.id,\n content: handlerResult.result,\n };\n agent.messages.splice(insertAt, 0, toolMessage);\n\n if (!handlerResult.error && tool?.followUp !== false) {\n return true; // Needs follow-up\n }\n }\n\n return false;\n }\n\n /**\n * Execute a wildcard tool.\n * Wildcard tools receive args wrapped as `{toolName, args}`, which differs from\n * specific tools, so this method keeps its own arg-wrapping logic rather than\n * delegating to `executeToolHandler`.\n */\n private async executeWildcardTool(\n wildcardTool: FrontendTool<any>,\n toolCall: ToolCall,\n message: Message,\n agent: AbstractAgent,\n agentId: string,\n signal?: AbortSignal,\n discardOnAbort = false,\n ): Promise<boolean> {\n const threadId = agent.threadId;\n // Check if wildcard tool is constrained to a specific agent\n if (wildcardTool?.agentId && wildcardTool.agentId !== agent.agentId) {\n // Wildcard tool is not available for this agent, skip it\n return false;\n }\n\n let toolCallResult = \"\";\n let errorMessage: string | undefined;\n\n if (wildcardTool?.handler) {\n let parsedArgs: unknown;\n try {\n parsedArgs = parseToolArguments(\n toolCall.function.arguments,\n toolCall.function.name,\n );\n } catch (error) {\n const parseError =\n error instanceof Error ? error : new Error(String(error));\n errorMessage = parseError.message;\n await this._internal.emitError({\n error: parseError,\n code: CopilotKitCoreErrorCode.TOOL_ARGUMENT_PARSE_FAILED,\n context: {\n agentId: agentId,\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n rawArguments: toolCall.function.arguments,\n toolType: \"wildcard\",\n messageId: message.id,\n },\n });\n }\n\n const wildcardArgs = {\n toolName: toolCall.function.name,\n args: parsedArgs,\n };\n\n await this._internal.notifySubscribers(\n (subscriber) =>\n subscriber.onToolExecutionStart?.({\n copilotkit: this.core,\n toolCallId: toolCall.id,\n agentId: agentId,\n toolName: toolCall.function.name,\n args: wildcardArgs,\n }),\n \"Subscriber onToolExecutionStart error:\",\n );\n\n if (!errorMessage) {\n try {\n const result = await wildcardTool.handler(wildcardArgs as any, {\n toolCall,\n agent,\n // Use the same execution signal as named tools, including the\n // replay-specific signal when restoring a wildcard HITL handler.\n signal,\n });\n if (result === undefined || result === null) {\n toolCallResult = \"\";\n } else if (typeof result === \"string\") {\n toolCallResult = result;\n } else {\n toolCallResult = JSON.stringify(result);\n }\n } catch (error) {\n const handlerError =\n error instanceof Error ? error : new Error(String(error));\n errorMessage = handlerError.message;\n if (!discardAbortedResult(signal, discardOnAbort, errorMessage)) {\n await this._internal.emitError({\n error: handlerError,\n code: CopilotKitCoreErrorCode.TOOL_HANDLER_FAILED,\n context: {\n agentId: agentId,\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n parsedArgs: wildcardArgs,\n toolType: \"wildcard\",\n messageId: message.id,\n },\n });\n }\n }\n }\n\n if (errorMessage) {\n toolCallResult = `Error: ${errorMessage}`;\n }\n\n await this._internal.notifySubscribers(\n (subscriber) =>\n subscriber.onToolExecutionEnd?.({\n copilotkit: this.core,\n toolCallId: toolCall.id,\n agentId: agentId,\n toolName: toolCall.function.name,\n result: errorMessage ? \"\" : toolCallResult,\n error: errorMessage,\n }),\n \"Subscriber onToolExecutionEnd error:\",\n );\n }\n\n {\n const messageIndex = agent.messages.findIndex((m) => m.id === message.id);\n if (\n discardAbortedResult(signal, discardOnAbort, errorMessage) ||\n agent.threadId !== threadId ||\n messageIndex === -1 ||\n agent.messages.some(\n (m) =>\n m.role === \"tool\" &&\n m.toolCallId === toolCall.id &&\n !this.isFrontendPlaceholderResult(m),\n )\n ) {\n // The interaction was removed, the thread changed, or another client\n // already answered. Do not insert a stale answer or start a follow-up.\n return false;\n }\n // Find the correct insertion point: after the parent assistant message\n // and any tool-result messages already inserted for earlier tool calls\n // in the same batch. This preserves tool-result ordering relative to\n // the toolCalls array, which some providers (OpenAI) require.\n let insertAt = messageIndex + 1;\n while (\n insertAt < agent.messages.length &&\n agent.messages[insertAt]?.role === \"tool\"\n ) {\n insertAt++;\n }\n const toolMessage = {\n id: randomUUID(),\n role: \"tool\" as const,\n toolCallId: toolCall.id,\n content: toolCallResult,\n };\n agent.messages.splice(insertAt, 0, toolMessage);\n\n if (!errorMessage && wildcardTool?.followUp !== false) {\n return true; // Needs follow-up\n }\n }\n\n return false;\n }\n\n /**\n * Programmatically execute a registered frontend tool without going through an LLM turn.\n * The handler runs, render components show up in the UI, and both the tool call and\n * result messages are added to `agent.messages`.\n */\n async runTool(\n params: CopilotKitCoreRunToolParams,\n ): Promise<CopilotKitCoreRunToolResult> {\n const { name, agentId, parameters = {}, followUp = false } = params;\n\n // 1. Look up the tool\n const tool = this.getTool({ toolName: name, agentId });\n if (!tool) {\n const error = new Error(`Tool not found: ${name}`);\n await this._internal.emitError({\n error,\n code: CopilotKitCoreErrorCode.TOOL_NOT_FOUND,\n context: { toolName: name, agentId },\n });\n throw error;\n }\n\n // 2. Look up the agent\n const resolvedAgentId = agentId ?? \"default\";\n const agent = this._internal.getAgent(resolvedAgentId);\n if (!agent) {\n const error = new Error(`Agent not found: ${resolvedAgentId}`);\n await this._internal.emitError({\n error,\n code: CopilotKitCoreErrorCode.AGENT_NOT_FOUND,\n context: { agentId: resolvedAgentId },\n });\n throw error;\n }\n\n // 3. Create assistant message with tool call\n const toolCallId = randomUUID();\n const assistantToolCall = {\n id: toolCallId,\n type: \"function\" as const,\n function: {\n name,\n arguments: JSON.stringify(parameters),\n },\n };\n const assistantMessage: Message = {\n id: randomUUID(),\n role: \"assistant\",\n content: \"\",\n toolCalls: [assistantToolCall],\n };\n\n // 4. Push assistant message into agent's messages\n agent.messages.push(assistantMessage);\n\n // 5. Execute the tool handler (if it has one)\n let handlerResult: ExecuteToolHandlerResult = {\n result: \"\",\n error: undefined,\n isArgumentError: false,\n };\n\n if (tool.handler) {\n handlerResult = await this.executeToolHandler({\n tool,\n toolCall: assistantToolCall,\n agent,\n agentId: resolvedAgentId,\n handlerArgs: parameters,\n toolType: \"runTool\",\n });\n }\n\n // 6. Create and insert tool result message\n const toolResultMessage: Message = {\n id: randomUUID(),\n role: \"tool\",\n toolCallId,\n content: handlerResult.result,\n };\n\n const assistantIndex = agent.messages.findIndex(\n (m) => m.id === assistantMessage.id,\n );\n if (assistantIndex !== -1) {\n agent.messages.splice(assistantIndex + 1, 0, toolResultMessage);\n } else {\n // Fallback: push to end if assistant message was removed\n agent.messages.push(toolResultMessage);\n }\n\n // 7. Handle followUp (only if no error)\n if (!handlerResult.error && followUp !== false) {\n if (typeof followUp === \"string\" && followUp !== \"generate\") {\n // Custom text: add a user message first\n const userMessage: Message = {\n id: randomUUID(),\n role: \"user\",\n content: followUp,\n };\n agent.messages.push(userMessage);\n }\n // Yield to the framework scheduler so deferred state updates (e.g. React\n // useEffect in useAgentContext) can complete before the follow-up run reads\n // the context store. Mirrors the same yield in processAgentResult.\n await this._internal.waitForPendingFrameworkUpdates();\n // Trigger agent run for both \"generate\" and custom text\n await this.runAgent({ agent });\n }\n\n // 8. Return result\n return {\n toolCallId,\n result: handlerResult.result,\n error: handlerResult.error,\n };\n }\n\n /** Stable identity for a tool override: agent-scope + name (NUL-separated). */\n private capabilityKey(name: string, agentId?: string): string {\n return `${agentId ?? \"\"}\\u0000${name}`;\n }\n\n /**\n * Enable/disable a registered frontend tool at runtime without unregistering\n * it. A disabled tool is omitted from {@link buildFrontendTools}, so the agent\n * never receives it. Unlike the per-tool `available` flag, this override\n * survives the tool being re-registered.\n */\n setToolEnabled(name: string, enabled: boolean, agentId?: string): void {\n const key = this.capabilityKey(name, agentId);\n if (enabled) {\n this._disabledToolKeys.delete(key);\n } else {\n this._disabledToolKeys.add(key);\n }\n this.syncWebMCP();\n }\n\n /** Whether a tool is currently enabled (not overridden off). Defaults true. */\n isToolEnabled(name: string, agentId?: string): boolean {\n return !this._disabledToolKeys.has(this.capabilityKey(name, agentId));\n }\n\n /**\n * Build frontend tools for an agent\n */\n buildFrontendTools(agentId?: string): Tool[] {\n return this.tools\n .filter(\n (tool) =>\n // A wildcard tool is a local catch-all handler (see\n // `executeWildcardTool`), not something the model can call —\n // advertising it would offer the agent a tool named `*`.\n tool.name !== WILDCARD_TOOL_NAME &&\n tool.available !== false &&\n (tool.available as boolean | string | undefined) !== \"disabled\" &&\n (!tool.agentId || tool.agentId === agentId) &&\n this.isToolEnabled(tool.name, tool.agentId),\n )\n .map((tool) => ({\n name: tool.name,\n description: tool.description ?? \"\",\n parameters: createToolSchema(tool),\n }));\n }\n\n /**\n * Reconcile the WebMCP registrations with the current tool registry. Tools\n * opt in via `webmcp: true` or `webmcp: { annotations }`; the same\n * availability rules as `buildFrontendTools` apply. WebMCP tools are\n * page-level, so unlike the agent tool list they are not filtered by\n * agentId — a name collision across agentIds keeps the first registration.\n */\n private syncWebMCP(): void {\n const desired = new Map<string, FrontendTool<any>>();\n const warnedCollisions = new Set<string>();\n for (const tool of this.tools) {\n if (!tool.webmcp) {\n continue;\n }\n if (tool.name === WILDCARD_TOOL_NAME) {\n continue;\n }\n if (\n tool.available === false ||\n (tool.available as boolean | string | undefined) === \"disabled\"\n ) {\n continue;\n }\n if (!this.isToolEnabled(tool.name, tool.agentId)) {\n continue;\n }\n if (desired.has(tool.name)) {\n if (!warnedCollisions.has(tool.name)) {\n warnedCollisions.add(tool.name);\n logger.warn(\n `[CopilotKit] Multiple WebMCP tools share the name '${tool.name}'. ` +\n `Only the first registration is exposed to browser agents.`,\n );\n }\n continue;\n }\n desired.set(tool.name, tool);\n }\n this._webmcpRegistry.sync(desired);\n }\n\n /**\n * Create an agent error subscriber\n */\n private createAgentErrorSubscriber(agent: AbstractAgent): AgentSubscriber {\n const emitAgentError = async (\n error: Error,\n code: CopilotKitCoreErrorCode,\n extraContext: Record<string, any> = {},\n ) => {\n const context: Record<string, any> = { ...extraContext };\n if (agent.agentId) {\n context.agentId = agent.agentId;\n }\n await this._internal.emitError({\n error,\n code,\n context,\n });\n };\n\n return {\n onRunFailed: async ({ error }: { error: Error }) => {\n const code =\n error instanceof AgentThreadLockedError\n ? CopilotKitCoreErrorCode.AGENT_THREAD_LOCKED\n : CopilotKitCoreErrorCode.AGENT_RUN_FAILED_EVENT;\n await emitAgentError(error, code, {\n source: \"onRunFailed\",\n });\n },\n onRunErrorEvent: async ({ event }) => {\n // A user-initiated stop (stopAgent / agent.abortRun) makes the agent\n // emit a terminal RUN_ERROR — often code \"abort\" — as its cancellation\n // signal. That is expected, not a failure: surfacing it would pop an\n // error banner on Stop (#5966, follow-up to #5812). Mirror the\n // local-abort suppression on the runAgent/connectAgent paths and skip\n // it. Prefer the abort controller (the client's own record that it\n // initiated the stop) over the agent-supplied `code`, which is not\n // standardized across agents.\n const runWasAborted = this._runAbortController?.signal.aborted === true;\n if (runWasAborted || event?.code === \"abort\") {\n return;\n }\n\n const eventError =\n event?.rawEvent instanceof Error\n ? event.rawEvent\n : event?.rawEvent?.error instanceof Error\n ? event.rawEvent.error\n : undefined;\n\n const errorMessage =\n typeof event?.rawEvent?.error === \"string\"\n ? event.rawEvent.error\n : (event?.message ?? \"Agent run error\");\n\n const rawError = eventError ?? new Error(errorMessage);\n\n if (event?.code && !(rawError as any).code) {\n (rawError as any).code = event.code;\n }\n\n await emitAgentError(\n rawError,\n CopilotKitCoreErrorCode.AGENT_RUN_ERROR_EVENT,\n {\n source: \"onRunErrorEvent\",\n event,\n runtimeErrorCode: event?.code,\n },\n );\n },\n };\n }\n}\n\n/**\n * Ensures parsed tool arguments are a plain object.\n * Throws for non-object values so the caller's catch block can emit\n * a structured TOOL_ARGUMENT_PARSE_FAILED error.\n *\n * @internal Exported for testing only.\n */\nexport function ensureObjectArgs(\n parsed: unknown,\n toolName: string,\n): Record<string, unknown> {\n if (typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n throw new Error(\n `Tool arguments for ${toolName} parsed to non-object (${typeof parsed})`,\n );\n}\n\n/**\n * Parses raw tool call arguments into a validated object.\n *\n * Some LLM providers (e.g. @ai-sdk/openai-compatible) may send empty string \"\",\n * null, or undefined instead of \"{}\". This function normalises those cases to an\n * empty object so callers don't crash on JSON.parse(\"\").\n *\n * A debug-level warning is emitted when the fallback triggers so silent coercion\n * is observable in logs.\n *\n * @internal Exported for testing only.\n */\nexport function parseToolArguments(\n rawArgs: unknown,\n toolName: string,\n): Record<string, unknown> {\n if (rawArgs === \"\" || rawArgs === null || rawArgs === undefined) {\n logger.debug(\n `[parseToolArguments] Tool \"${toolName}\" received empty/null/undefined arguments — defaulting to {}`,\n );\n return {};\n }\n const parsed = typeof rawArgs === \"string\" ? JSON.parse(rawArgs) : rawArgs;\n return ensureObjectArgs(parsed, toolName);\n}\n","import type {\n AbstractAgent,\n Message,\n State,\n RunAgentInput,\n StateSnapshotEvent,\n StateDeltaEvent,\n MessagesSnapshotEvent,\n TextMessageStartEvent,\n ToolCallResultEvent,\n ToolMessage,\n} from \"@ag-ui/client\";\nimport { randomUUID, structuredClone_ } from \"@ag-ui/client\";\nimport type { CopilotKitCore } from \"./core\";\nimport { isForwardedToClientPlaceholder } from \"./tool-result-content\";\n\nconst isContinuation = (input: RunAgentInput): boolean =>\n input.resume !== undefined ||\n Object.prototype.hasOwnProperty.call(\n (input.forwardedProps as { command?: object } | undefined)?.command ?? {},\n \"resume\",\n );\n\nexport interface CopilotKitCoreContinuationHandoff {\n cancel(): void;\n bind(input: object): void;\n}\n\ninterface PendingContinuation extends CopilotKitCoreContinuationHandoff {\n expectedInput?: object;\n active: boolean;\n /**\n * The logical run id this continuation belongs to. Events arriving on the\n * continuation are re-stamped with it, so the run reads as ONE run to\n * everything downstream (state/message association, external tracing) even\n * though the transport minted a fresh id for the follow-up invocation.\n */\n expectedRunId?: string;\n}\n\n/**\n * Manages state and message tracking by run for CopilotKitCore.\n * Tracks agent state snapshots and message-to-run associations.\n */\nexport class StateManager {\n // State tracking: agentId -> threadId -> runId -> state\n private stateByRun: Map<string, Map<string, Map<string, State>>> = new Map();\n\n // Message tracking: agentId -> threadId -> messageId -> runId\n private messageToRun: Map<string, Map<string, Map<string, string>>> =\n new Map();\n\n // Direct text-start metadata: agentId -> threadId -> messageId -> rawEvent\n private rawEventByMessage: Map<string, Map<string, Map<string, unknown>>> =\n new Map();\n\n // Active run tracking: `agentId:threadId` -> runId (used when messages arrive without input)\n private activeRun: Map<string, string> = new Map();\n\n private agentSubscriptions: Map<\n string,\n { agent: AbstractAgent; unsubscribe: () => void }\n > = new Map();\n\n // Internal follow-ups are marked in memory so the marker never reaches a\n // runtime or becomes user-controlled forwardedProps data.\n private pendingContinuations = new WeakMap<\n AbstractAgent,\n Set<PendingContinuation>\n >();\n\n constructor(private core: CopilotKitCore) {}\n\n /**\n * Initialize state tracking for an agent\n */\n initialize(): void {\n // Will be called when CopilotKitCore is initialized\n }\n\n markNextRunAsContinuation(\n agent: AbstractAgent,\n expectedRunId?: string,\n ): CopilotKitCoreContinuationHandoff {\n let pendingForAgent = this.pendingContinuations.get(agent);\n if (!pendingForAgent) {\n pendingForAgent = new Set();\n this.pendingContinuations.set(agent, pendingForAgent);\n }\n\n const pending: PendingContinuation = {\n active: true,\n expectedRunId,\n bind: (input) => {\n if (pending.active) pending.expectedInput = input;\n },\n cancel: () => {\n if (!pending.active) return;\n pending.active = false;\n pendingForAgent!.delete(pending);\n if (pendingForAgent!.size === 0) {\n this.pendingContinuations.delete(agent);\n }\n },\n };\n pendingForAgent.add(pending);\n return pending;\n }\n\n /**\n * Subscribe to an agent's events to track state and messages.\n */\n subscribeToAgent(agent: AbstractAgent): void {\n if (!agent.agentId) {\n return; // Skip agents without IDs\n }\n\n const agentId = agent.agentId;\n\n const existing = this.agentSubscriptions.get(agentId);\n if (existing) {\n if (existing.agent === agent) {\n return;\n }\n existing.unsubscribe();\n this.agentSubscriptions.delete(agentId);\n }\n\n // Subscribe to agent events.\n //\n // Two invariants this subscription must uphold:\n //\n // 1. Revocation: the ag-ui pipeline captures `o = [...agent.subscribers]` at\n // runAgent() start. If this subscription is replaced by a newer one before\n // the pipeline finishes, the old pipeline may still call these callbacks\n // with the old input.runId. `revoked = true` turns them into no-ops once\n // the replacement subscription is in place. Only a replacement revokes —\n // see the same-instance guard above.\n //\n // 2. Run isolation within one subscription: in tests (and edge cases), a new\n // run's events can arrive through the same subscription before the new\n // pipeline is set up. An explicit standard or legacy resume input is a\n // continuation, so only an ordinary new run gets a fresh ID after\n // RUN_FINISHED.\n let revoked = false;\n let subRunId: string | undefined; // runId assigned to the current logical run\n let runFinished = false; // true after RUN_FINISHED, reset on next RUN_STARTED\n const pendingResults = new WeakMap<\n RunAgentInput,\n Map<string, ToolCallResultEvent>\n >();\n\n const reconcilePendingResults = (\n historyMessages: readonly Message[],\n input: RunAgentInput,\n ): { messages: Message[] } | undefined => {\n const events = pendingResults.get(input);\n if (!events) return undefined;\n\n const messages = [...historyMessages];\n let changed = false;\n\n for (const event of events.values()) {\n const ownerIndex = messages.findIndex(\n (message) =>\n message.role === \"assistant\" &&\n message.toolCalls?.some(\n (toolCall) => toolCall.id === event.toolCallId,\n ),\n );\n if (ownerIndex < 0) continue;\n\n const matchingIndexes = messages.reduce<number[]>(\n (indexes, message, index) => {\n if (\n message.role === \"tool\" &&\n message.toolCallId === event.toolCallId\n ) {\n indexes.push(index);\n }\n return indexes;\n },\n [],\n );\n const realIndex = matchingIndexes.find(\n (index) => !isForwardedToClientPlaceholder(messages[index]?.content),\n );\n if (realIndex !== undefined) {\n for (const duplicateIndex of matchingIndexes\n .filter((candidateIndex) => candidateIndex !== realIndex)\n .sort((a, b) => b - a)) {\n messages.splice(duplicateIndex, 1);\n changed = true;\n }\n continue;\n }\n\n const placeholderIndex = matchingIndexes.find((index) =>\n isForwardedToClientPlaceholder(messages[index]?.content),\n );\n if (placeholderIndex !== undefined) {\n if (isForwardedToClientPlaceholder(event.content)) {\n for (const duplicateIndex of matchingIndexes\n .slice(1)\n .sort((a, b) => b - a)) {\n messages.splice(duplicateIndex, 1);\n changed = true;\n }\n continue;\n }\n messages[placeholderIndex] = {\n ...messages[placeholderIndex],\n id: event.messageId,\n content: event.content,\n } as ToolMessage;\n changed = true;\n for (const duplicateIndex of matchingIndexes\n .filter(\n (candidateIndex) =>\n candidateIndex !== placeholderIndex &&\n isForwardedToClientPlaceholder(\n messages[candidateIndex]?.content,\n ),\n )\n .sort((a, b) => b - a)) {\n messages.splice(duplicateIndex, 1);\n }\n continue;\n }\n\n const result: ToolMessage = {\n id: event.messageId,\n role: \"tool\",\n toolCallId: event.toolCallId,\n content: event.content,\n };\n let insertIndex = ownerIndex + 1;\n while (messages[insertIndex]?.role === \"tool\") insertIndex++;\n messages.splice(insertIndex, 0, result);\n changed = true;\n }\n\n return changed ? { messages } : undefined;\n };\n\n const clearPendingResults = (input: RunAgentInput): void => {\n pendingResults.delete(input);\n };\n\n const effectiveInput = (input: RunAgentInput): RunAgentInput => ({\n ...input,\n runId: subRunId ?? input.runId,\n });\n\n const { unsubscribe } = agent.subscribe({\n onRunStartedEvent: ({ event, input, state }) => {\n if (revoked) return;\n const pendingForAgent = this.pendingContinuations.get(agent);\n const internalContinuation = [...(pendingForAgent ?? [])].find(\n (pending) => pending.expectedInput === input,\n );\n internalContinuation?.cancel();\n\n if (internalContinuation) {\n // An internal continuation re-stamps onto the run id it continues, so\n // the follow-up does not have to reuse that id on the wire.\n subRunId =\n internalContinuation.expectedRunId ?? event.runId ?? input.runId;\n } else if (\n runFinished &&\n input.runId === subRunId &&\n !isContinuation(input) &&\n (event.runId == null || event.runId === subRunId)\n ) {\n // A new logical run's events are arriving through this same (old)\n // subscription. This happens when the test emits events before\n // copilotkit.runAgent() has had a chance to set up the new pipeline:\n // the old pipeline reuses input1.runId for all events, so\n // input.runId equals the previous run's runId. Generate a fresh\n // runId so the new run's state doesn't collide with the old one.\n subRunId = randomUUID();\n } else {\n // A connect replay may contain multiple server runs under one input.runId.\n subRunId = event.runId || input.runId;\n }\n runFinished = false;\n this.handleRunStarted(agent, effectiveInput(input), state);\n },\n onRunFinishedEvent: ({ input, state, messages }) => {\n if (revoked) return;\n runFinished = true;\n const effective = effectiveInput(input);\n const mutation = reconcilePendingResults(messages, input);\n clearPendingResults(input);\n this.handleRunFinished(agent, effective, state);\n return mutation;\n },\n // A run error terminates the run — treat identically to finished for cleanup\n onRunErrorEvent: ({ input, state, messages }) => {\n if (revoked) return;\n runFinished = true;\n const effective = effectiveInput(input);\n const mutation = reconcilePendingResults(messages, input);\n this.handleRunFinished(agent, effective, state);\n return mutation;\n },\n onRunFailed: ({ input, messages }) => {\n if (revoked) return;\n return reconcilePendingResults(messages, input);\n },\n onRunFinalized: ({ input }) => {\n if (revoked) return;\n clearPendingResults(input);\n },\n onToolCallResultEvent: ({ event, input }) => {\n if (revoked) return;\n let events = pendingResults.get(input);\n if (!events) {\n events = new Map();\n pendingResults.set(input, events);\n }\n events.set(event.toolCallId, event);\n },\n onStateSnapshotEvent: ({ event, input, state }) => {\n if (revoked) return;\n this.handleStateSnapshot(agent, event, effectiveInput(input), state);\n },\n onStateDeltaEvent: ({ event, input, state }) => {\n if (revoked) return;\n this.handleStateDelta(agent, event, effectiveInput(input), state);\n },\n onTextMessageStartEvent: ({ event, input }) => {\n if (revoked) return;\n this.handleTextMessageStart(agent, event, effectiveInput(input));\n },\n onMessagesSnapshotEvent: ({ event, input, messages }) => {\n if (revoked) return;\n this.handleMessagesSnapshot(\n agent,\n event,\n effectiveInput(input),\n messages,\n );\n this.pruneRawEvents(\n agent.agentId!,\n input.threadId,\n event.messages,\n effectiveInput(input),\n );\n },\n onNewMessage: ({ message, input }) => {\n if (revoked) return;\n this.handleNewMessage(\n agent,\n message,\n input ? effectiveInput(input) : undefined,\n );\n },\n onMessagesChanged: ({ messages, input }) => {\n if (revoked) return;\n if (!input) {\n this.pruneRawEvents(agent.agentId!, agent.threadId, messages);\n }\n },\n });\n\n this.agentSubscriptions.set(agentId, {\n agent,\n unsubscribe: () => {\n revoked = true;\n this.pendingContinuations.delete(agent);\n unsubscribe();\n },\n });\n }\n\n /**\n * Unsubscribe an agent's subscription.\n */\n unsubscribeFromAgent(agentId: string): void {\n const existing = this.agentSubscriptions.get(agentId);\n if (existing) {\n existing.unsubscribe();\n this.agentSubscriptions.delete(agentId);\n }\n this.rawEventByMessage.delete(agentId);\n }\n\n /**\n * Get state for a specific run\n * Returns a deep copy to prevent external mutations\n */\n getStateByRun(\n agentId: string,\n threadId: string,\n runId: string,\n ): State | undefined {\n const state = this.stateByRun.get(agentId)?.get(threadId)?.get(runId);\n if (!state) return undefined;\n // Return a deep copy to prevent mutations\n return JSON.parse(JSON.stringify(state));\n }\n\n /**\n * Get runId associated with a message\n */\n getRunIdForMessage(\n agentId: string,\n threadId: string,\n messageId: string,\n ): string | undefined {\n return this.messageToRun.get(agentId)?.get(threadId)?.get(messageId);\n }\n\n /**\n * Get direct text-start metadata associated with a message.\n */\n getRawEventForMessage(\n agentId: string,\n threadId: string,\n messageId: string,\n ): unknown {\n const rawEvent = this.rawEventByMessage\n .get(agentId)\n ?.get(threadId)\n ?.get(messageId);\n return rawEvent === undefined ? undefined : structuredClone_(rawEvent);\n }\n\n /**\n * Get all states for an agent's thread\n */\n getStatesForThread(agentId: string, threadId: string): Map<string, State> {\n return this.stateByRun.get(agentId)?.get(threadId) ?? new Map();\n }\n\n /**\n * Get all run IDs for an agent's thread\n */\n getRunIdsForThread(agentId: string, threadId: string): string[] {\n const threadStates = this.stateByRun.get(agentId)?.get(threadId);\n return threadStates ? Array.from(threadStates.keys()) : [];\n }\n\n /**\n * Handle run started event\n */\n private handleRunStarted(\n agent: AbstractAgent,\n input: RunAgentInput,\n state: State,\n ): void {\n if (!agent.agentId) return;\n\n const { threadId, runId } = input;\n this.activeRun.set(`${agent.agentId}:${threadId}`, runId);\n // Only persist state when it carries real data. An empty {} from an\n // initial-state-less run would cause getStateByRun to return {} instead\n // of undefined, breaking renderers that rely on undefined to mean \"no\n // state snapshot received yet\".\n if (state && Object.keys(state).length > 0) {\n this.saveState(agent.agentId, threadId, runId, state);\n }\n }\n\n /**\n * Handle run finished event\n */\n private handleRunFinished(\n agent: AbstractAgent,\n input: RunAgentInput,\n state: State,\n ): void {\n if (!agent.agentId) return;\n\n const { threadId, runId } = input;\n this.activeRun.delete(`${agent.agentId}:${threadId}`);\n if (state && Object.keys(state).length > 0) {\n this.saveState(agent.agentId, threadId, runId, state);\n }\n }\n\n /**\n * Handle state snapshot event\n */\n private handleStateSnapshot(\n agent: AbstractAgent,\n event: StateSnapshotEvent,\n input: RunAgentInput,\n state: State,\n ): void {\n if (!agent.agentId) return;\n\n const { threadId, runId } = input;\n // Merge snapshot into current state\n const mergedState = { ...state, ...event.snapshot };\n this.saveState(agent.agentId, threadId, runId, mergedState);\n }\n\n /**\n * Handle state delta event\n */\n private handleStateDelta(\n agent: AbstractAgent,\n event: StateDeltaEvent,\n input: RunAgentInput,\n state: State,\n ): void {\n if (!agent.agentId) return;\n\n const { threadId, runId } = input;\n // State is already updated by the agent, just save it\n this.saveState(agent.agentId, threadId, runId, state);\n }\n\n /**\n * Capture only defined metadata from a normalized direct text-start event.\n */\n private handleTextMessageStart(\n agent: AbstractAgent,\n event: TextMessageStartEvent,\n input: RunAgentInput,\n ): void {\n if (!agent.agentId) return;\n\n const { threadId } = input;\n if (event.rawEvent === undefined) {\n const threadEvents = this.rawEventByMessage\n .get(agent.agentId)\n ?.get(threadId);\n threadEvents?.delete(event.messageId);\n if (threadEvents?.size === 0) {\n this.rawEventByMessage.get(agent.agentId)?.delete(threadId);\n }\n if (this.rawEventByMessage.get(agent.agentId)?.size === 0) {\n this.rawEventByMessage.delete(agent.agentId);\n }\n return;\n }\n\n if (!this.rawEventByMessage.has(agent.agentId)) {\n this.rawEventByMessage.set(agent.agentId, new Map());\n }\n const agentEvents = this.rawEventByMessage.get(agent.agentId)!;\n if (!agentEvents.has(threadId)) {\n agentEvents.set(threadId, new Map());\n }\n agentEvents.get(threadId)!.set(event.messageId, event.rawEvent);\n }\n\n /**\n * Handle messages snapshot event\n */\n private handleMessagesSnapshot(\n agent: AbstractAgent,\n event: MessagesSnapshotEvent,\n input: RunAgentInput,\n _messages: readonly Message[],\n ): void {\n if (!agent.agentId) return;\n\n const { threadId, runId } = input;\n\n // Cumulative snapshots repeat messages from earlier runs, so only assign\n // messages that do not already have a run association.\n for (const message of event.messages) {\n if (\n this.getRunIdForMessage(agent.agentId, threadId, message.id) ===\n undefined\n ) {\n this.associateMessageWithRun(\n agent.agentId,\n threadId,\n message.id,\n runId,\n );\n }\n }\n }\n\n /**\n * Handle new message event\n */\n private handleNewMessage(\n agent: AbstractAgent,\n message: Message,\n input?: RunAgentInput,\n ): void {\n if (!agent.agentId) return;\n\n if (!input) {\n // ag-ui calls addMessage() without input, so input is undefined here.\n // Fall back to the currently-active run for this agent's thread.\n const threadId = agent.threadId ?? \"\";\n const runId = this.activeRun.get(`${agent.agentId}:${threadId}`);\n if (runId) {\n this.associateMessageWithRun(\n agent.agentId,\n threadId,\n message.id,\n runId,\n );\n }\n return;\n }\n\n const { threadId, runId } = input;\n this.associateMessageWithRun(agent.agentId, threadId, message.id, runId);\n }\n\n /**\n * Save state for a specific run\n */\n private saveState(\n agentId: string,\n threadId: string,\n runId: string,\n state: State,\n ): void {\n // Ensure nested maps exist\n if (!this.stateByRun.has(agentId)) {\n this.stateByRun.set(agentId, new Map());\n }\n const agentStates = this.stateByRun.get(agentId)!;\n\n if (!agentStates.has(threadId)) {\n agentStates.set(threadId, new Map());\n }\n const threadStates = agentStates.get(threadId)!;\n\n // Deep copy the state to prevent mutations\n threadStates.set(runId, JSON.parse(JSON.stringify(state)));\n }\n\n /**\n * Associate a message with a run\n */\n private associateMessageWithRun(\n agentId: string,\n threadId: string,\n messageId: string,\n runId: string,\n ): void {\n // Ensure nested maps exist\n if (!this.messageToRun.has(agentId)) {\n this.messageToRun.set(agentId, new Map());\n }\n const agentMessages = this.messageToRun.get(agentId)!;\n\n if (!agentMessages.has(threadId)) {\n agentMessages.set(threadId, new Map());\n }\n const threadMessages = agentMessages.get(threadId)!;\n\n threadMessages.set(messageId, runId);\n }\n\n private pruneRawEvents(\n agentId: string,\n fallbackThreadId: string | undefined,\n messages: ReadonlyArray<Readonly<Message>>,\n input?: RunAgentInput,\n ): void {\n const threadId = input?.threadId ?? fallbackThreadId;\n if (!threadId) return;\n\n const threadEvents = this.rawEventByMessage.get(agentId)?.get(threadId);\n if (!threadEvents) return;\n\n const messageIds = new Set(messages.map((message) => message.id));\n for (const messageId of threadEvents.keys()) {\n if (!messageIds.has(messageId)) threadEvents.delete(messageId);\n }\n if (threadEvents.size === 0) {\n this.rawEventByMessage.get(agentId)?.delete(threadId);\n }\n if (this.rawEventByMessage.get(agentId)?.size === 0) {\n this.rawEventByMessage.delete(agentId);\n }\n }\n\n /**\n * Clear all state for an agent\n */\n clearAgentState(agentId: string): void {\n this.stateByRun.delete(agentId);\n this.messageToRun.delete(agentId);\n this.rawEventByMessage.delete(agentId);\n }\n\n /**\n * Clear all state for a thread\n */\n clearThreadState(agentId: string, threadId: string): void {\n this.stateByRun.get(agentId)?.delete(threadId);\n this.messageToRun.get(agentId)?.delete(threadId);\n this.rawEventByMessage.get(agentId)?.delete(threadId);\n }\n}\n","import { type ɵThreadStore } from \"../threads\";\nimport type { CopilotKitCore } from \"./core\";\nimport { CopilotKitCoreFriendsAccess, CopilotKitCoreSubscriber } from \"./core\";\n\nexport class ThreadStoreRegistry {\n private _stores: Record<string, ɵThreadStore> = {};\n // Cached frozen snapshot of `_stores`. Invalidated to `null` on every\n // `register`/`unregister` so the next `getAll()` rebuilds it. Stable\n // references between mutations matter for `useSyncExternalStore` consumers\n // that compare snapshot identity to decide whether to re-render.\n private _snapshot: Readonly<Record<string, ɵThreadStore>> | null = null;\n\n constructor(private core: CopilotKitCore) {}\n\n register(agentId: string, store: ɵThreadStore): void {\n if (agentId in this._stores) {\n // Capture the previous store before deleting it. `notifyUnregistered`\n // dispatches via `Promise.all` and returns control to this synchronous\n // body before async subscribers resume — by then `this._stores[agentId]`\n // already holds the new store, so the previous store must be forwarded\n // explicitly via the payload. Subscribers MUST NOT call\n // `registry.get(agentId)` from `onThreadStoreUnregistered` to recover\n // the previous store; use the `prevStore` field on the payload instead.\n const prevStore = this._stores[agentId]!;\n delete this._stores[agentId];\n this._snapshot = null;\n this.notifyUnregistered(agentId, prevStore).catch((err) => {\n console.error(\"ThreadStoreRegistry notifyUnregistered failed:\", err);\n });\n }\n this._stores[agentId] = store;\n this._snapshot = null;\n this.notifyRegistered(agentId, store).catch((err) => {\n console.error(\"ThreadStoreRegistry notifyRegistered failed:\", err);\n });\n }\n\n unregister(agentId: string): void {\n if (!(agentId in this._stores)) return;\n // Capture before delete for the same reason as `register()` above.\n const prevStore = this._stores[agentId]!;\n delete this._stores[agentId];\n this._snapshot = null;\n this.notifyUnregistered(agentId, prevStore).catch((err) => {\n console.error(\"ThreadStoreRegistry notifyUnregistered failed:\", err);\n });\n }\n\n get(agentId: string): ɵThreadStore | undefined {\n return this._stores[agentId];\n }\n\n getAll(): Readonly<Record<string, ɵThreadStore>> {\n // Cache a frozen snapshot so consecutive calls return the same reference.\n // `useSyncExternalStore` and other identity-comparing consumers depend on\n // this stability to skip re-renders when nothing has actually changed.\n // `Object.freeze` makes the `Readonly<>` claim true at runtime, not just\n // at the type level — attempts to mutate the snapshot throw in strict\n // mode and are silently ignored in sloppy mode (rather than corrupting\n // the registry). Invalidated to `null` by `register`/`unregister`.\n if (this._snapshot === null) {\n this._snapshot = Object.freeze({ ...this._stores });\n }\n return this._snapshot;\n }\n\n private async notifyRegistered(\n agentId: string,\n store: ɵThreadStore,\n ): Promise<void> {\n await (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).notifySubscribers(\n (subscriber: CopilotKitCoreSubscriber) =>\n subscriber.onThreadStoreRegistered?.({\n copilotkit: this.core,\n agentId,\n store,\n }),\n \"Subscriber onThreadStoreRegistered error:\",\n );\n }\n\n private async notifyUnregistered(\n agentId: string,\n prevStore: ɵThreadStore,\n ): Promise<void> {\n await (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).notifySubscribers(\n (subscriber: CopilotKitCoreSubscriber) =>\n subscriber.onThreadStoreUnregistered?.({\n copilotkit: this.core,\n agentId,\n prevStore,\n }),\n \"Subscriber onThreadStoreUnregistered error:\",\n );\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n BehaviorSubject,\n Observable,\n OperatorFunction,\n Subject,\n Subscription,\n asapScheduler,\n} from \"rxjs\";\nimport { distinctUntilChanged, filter, map, observeOn } from \"rxjs/operators\";\n\n/**\n * The minimal action shape used by this micro-redux implementation.\n */\nexport interface AnyAction {\n type: string;\n}\n\n/**\n * A typed action creator function with a `type` literal and runtime matcher.\n */\nexport type ActionCreator<\n Type extends string,\n Args extends unknown[] = unknown[],\n Action extends AnyAction & { type: Type } = { type: Type },\n> = ((...args: Args) => Action) & {\n type: Type;\n match(action: AnyAction): action is Action;\n};\n\n/**\n * Extracts the action type produced by an action creator.\n */\nexport type ActionFromCreator<T> = T extends (...args: any[]) => infer A\n ? A\n : never;\n\n/**\n * Extracts a union of actions produced by a tuple/array of action creators.\n */\nexport type ActionFromCreators<\n Creators extends readonly ActionCreator<string, any[], any>[],\n> = ActionFromCreator<Creators[number]>;\n\n/**\n * A reducer transforms state in response to actions.\n */\nexport type Reducer<State, Action extends AnyAction = AnyAction> = (\n state: State | undefined,\n action: Action,\n) => State;\n\n/**\n * A selector derives a value from state.\n */\nexport type Selector<State, Result> = (state: State) => Result;\n\n/**\n * Marker config for action creators that accept no payload.\n */\nexport interface EmptyActionConfig {\n readonly kind: \"empty\";\n}\n\nconst PROPS_MARKER: unique symbol = Symbol(\"props_marker\");\n\n/**\n * Marker config for action creators that require payload props.\n */\nexport interface PropsActionConfig<Props extends Record<string, unknown>> {\n readonly kind: \"props\";\n readonly [PROPS_MARKER]?: Props;\n}\n\n/**\n * Supported action creator config node in an action group.\n */\nexport type ActionConfig =\n | EmptyActionConfig\n | PropsActionConfig<Record<string, unknown>>;\n\n/**\n * Shape of an action group declaration object.\n */\nexport type ActionGroupConfig = Record<string, ActionConfig>;\n\n/**\n * Maps an action group declaration to a strongly typed action-creator object.\n */\nexport type ActionGroupResult<\n Source extends string,\n Config extends ActionGroupConfig,\n> = {\n [K in keyof Config & string]: Config[K] extends PropsActionConfig<infer P>\n ? ActionCreator<`[${Source}] ${K}`, [P], { type: `[${Source}] ${K}` } & P>\n : ActionCreator<`[${Source}] ${K}`, [], { type: `[${Source}] ${K}` }>;\n};\n\ninterface OnReducerEntry<\n State,\n Action extends AnyAction = AnyAction,\n Creators extends readonly ActionCreator<string, any[], any>[] =\n readonly ActionCreator<string, any[], any>[],\n> {\n creators: Creators;\n reducer: (state: State, action: Action) => State;\n}\n\ntype ActionFromOnReducerEntry<TEntry> =\n TEntry extends OnReducerEntry<any, infer TAction, any> ? TAction : never;\n\n/**\n * Effect contract for streams that emit actions to dispatch.\n */\nexport interface DispatchingEffect<\n State,\n InputAction extends AnyAction = AnyAction,\n OutputAction extends AnyAction = AnyAction,\n> {\n run: (\n actions$: Observable<InputAction>,\n state$: Observable<State>,\n ) => Observable<OutputAction>;\n dispatch: true;\n}\n\n/**\n * Effect contract for side-effect-only streams whose emissions are ignored.\n */\nexport interface NonDispatchingEffect<\n State,\n InputAction extends AnyAction = AnyAction,\n> {\n run: (\n actions$: Observable<InputAction>,\n state$: Observable<State>,\n ) => Observable<unknown>;\n dispatch: false;\n}\n\n/**\n * Union of supported effect shapes.\n */\nexport type Effect<\n State,\n InputAction extends AnyAction = AnyAction,\n OutputAction extends AnyAction = AnyAction,\n> =\n | DispatchingEffect<State, InputAction, OutputAction>\n | NonDispatchingEffect<State, InputAction>;\n\n/**\n * Lifecycle actions dispatched by the store.\n */\nexport type StoreLifecycleAction =\n | { type: \"@@micro-redux/init\" }\n | { type: \"@@micro-redux/stop\" };\n\n/**\n * Options for a dispatching effect.\n */\nexport interface DispatchingEffectOptions {\n dispatch?: true;\n}\n\n/**\n * Options for a non-dispatching effect.\n */\nexport interface NonDispatchingEffectOptions {\n dispatch: false;\n}\n\nconst INTERNAL_ACTION_TYPES = {\n boot: \"@@micro-redux/boot\",\n init: \"@@micro-redux/init\",\n stop: \"@@micro-redux/stop\",\n} as const;\n\nconst INTERNAL_BOOT_ACTION: AnyAction = { type: INTERNAL_ACTION_TYPES.boot };\n\n/**\n * Builds a typed action creator from a type string and payload factory.\n */\nfunction createTypedActionCreator<\n Type extends string,\n Args extends unknown[],\n Payload extends Record<string, unknown>,\n>(\n type: Type,\n factory: (...args: Args) => Payload,\n): ActionCreator<Type, Args, { type: Type } & Payload> {\n const creator = ((...args: Args) => ({\n ...factory(...args),\n type,\n })) as ActionCreator<Type, Args, { type: Type } & Payload>;\n\n creator.type = type;\n creator.match = (action: AnyAction): action is { type: Type } & Payload =>\n action.type === type;\n\n return creator;\n}\n\n/**\n * Declares a payload-based action config for `createActionGroup`.\n *\n * @example\n * ```ts\n * const actions = createActionGroup(\"User\", {\n * loaded: props<{ id: string }>(),\n * });\n * ```\n */\nexport function props<\n Props extends Record<string, unknown>,\n>(): PropsActionConfig<Props> {\n return { kind: \"props\" };\n}\n\n/**\n * Declares a no-payload action config for `createActionGroup`.\n *\n * @example\n * ```ts\n * const actions = createActionGroup(\"User\", {\n * reset: empty(),\n * });\n * ```\n */\nexport function empty(): EmptyActionConfig {\n return { kind: \"empty\" };\n}\n\n/**\n * Creates a namespaced group of typed action creators.\n *\n * Action types are formatted as: `[Source] actionName`.\n */\nexport function createActionGroup<\n const Source extends string,\n const Config extends ActionGroupConfig,\n>(source: Source, config: Config): ActionGroupResult<Source, Config> {\n const group = {} as ActionGroupResult<Source, Config>;\n\n for (const eventName of Object.keys(config) as Array<keyof Config & string>) {\n const eventConfig = config[eventName];\n if (!eventConfig) {\n continue;\n }\n\n const actionType = `[${source}] ${eventName}` as const;\n\n if (eventConfig.kind === \"props\") {\n group[eventName] = createTypedActionCreator(\n actionType,\n (payload: Record<string, unknown>) => ({ ...payload }),\n ) as ActionGroupResult<Source, Config>[typeof eventName];\n continue;\n }\n\n group[eventName] = createTypedActionCreator(\n actionType,\n () => ({}),\n ) as ActionGroupResult<Source, Config>[typeof eventName];\n }\n\n return group;\n}\n\n/**\n * Registers one reducer handler for one or more action creators.\n *\n * @throws Error when called without at least one action creator and reducer.\n */\nexport function on<\n State,\n const Creators extends readonly ActionCreator<string, any[], any>[],\n Action extends ActionFromCreators<Creators>,\n>(\n ...args: [\n ...creators: Creators,\n reducer: (state: State, action: Action) => State,\n ]\n): OnReducerEntry<State, Action, Creators> {\n if (args.length < 2) {\n throw new Error(\"on requires at least one action creator and one reducer\");\n }\n\n const reducer = args[args.length - 1] as (\n state: State,\n action: Action,\n ) => State;\n const creators = args.slice(0, -1) as unknown as Creators;\n\n return {\n creators,\n reducer,\n };\n}\n\n/**\n * Creates a reducer from an initial state and `on(...)` handler entries.\n *\n * Unknown action types return the current state unchanged.\n */\nexport function createReducer<\n State,\n const Entries extends readonly OnReducerEntry<any, any, any>[],\n>(\n initialState: State,\n ...entries: Entries\n): Reducer<State, ActionFromOnReducerEntry<Entries[number]>> {\n type ReducerAction = ActionFromOnReducerEntry<Entries[number]>;\n\n const reducerMap = new Map<\n string,\n Array<(state: State, action: ReducerAction) => State>\n >();\n\n for (const entry of entries) {\n for (const creator of entry.creators) {\n const handlers = reducerMap.get(creator.type) ?? [];\n handlers.push(\n entry.reducer as unknown as (\n state: State,\n action: ReducerAction,\n ) => State,\n );\n reducerMap.set(creator.type, handlers);\n }\n }\n\n return (state: State | undefined, action: ReducerAction): State => {\n const currentState = state ?? initialState;\n const handlers = reducerMap.get(action.type);\n\n if (!handlers || handlers.length === 0) {\n return currentState;\n }\n\n let nextState = currentState;\n for (const handler of handlers) {\n nextState = handler(nextState, action);\n }\n return nextState;\n };\n}\n\n/**\n * Creates a memoized selector from a single projector.\n */\nexport function createSelector<State, Result>(\n projector: (state: State) => Result,\n): Selector<State, Result>;\n\n/**\n * Creates a memoized selector from input selectors and a projector.\n *\n * Memoization uses one-entry caching over the latest input selector values.\n */\nexport function createSelector<\n State,\n const Selectors extends readonly Selector<State, unknown>[],\n Result,\n>(\n ...args: [\n ...selectors: Selectors,\n projector: (\n ...inputs: { [K in keyof Selectors]: ReturnType<Selectors[K]> }\n ) => Result,\n ]\n): Selector<State, Result>;\n\n/**\n * Creates a selector that caches and reuses the last computed result\n * when all input references are unchanged.\n */\nexport function createSelector<State, Result>(\n ...args:\n | [(state: State) => Result]\n | [\n ...selectors: Array<Selector<State, unknown>>,\n projector: (...inputs: unknown[]) => Result,\n ]\n): Selector<State, Result> {\n if (args.length === 1) {\n const projector = args[0] as (state: State) => Result;\n let hasCached = false;\n let lastState: State | undefined;\n let lastResult: Result;\n\n return (state: State): Result => {\n if (hasCached && state === lastState) {\n return lastResult;\n }\n\n lastState = state;\n lastResult = projector(state);\n hasCached = true;\n return lastResult;\n };\n }\n\n const projector = args[args.length - 1] as (...inputs: unknown[]) => Result;\n const selectors = args.slice(0, -1) as Array<Selector<State, unknown>>;\n\n let hasCached = false;\n let lastInputs: unknown[] = [];\n let lastResult: Result;\n\n return (state: State): Result => {\n const inputs = selectors.map((selector) => selector(state));\n\n if (\n hasCached &&\n inputs.length === lastInputs.length &&\n inputs.every((value, index) => value === lastInputs[index])\n ) {\n return lastResult;\n }\n\n lastInputs = inputs;\n lastResult = projector(...inputs);\n hasCached = true;\n return lastResult;\n };\n}\n\n/**\n * RxJS operator that maps state emissions through a selector and suppresses\n * unchanged projected values via reference equality.\n */\nexport function select<State, Result>(\n selector: Selector<State, Result>,\n): OperatorFunction<State, Result> {\n return (source$) => source$.pipe(map(selector), distinctUntilChanged());\n}\n\n/**\n * RxJS operator that filters an action stream by action creators and narrows\n * the output action type to the matched creator union.\n *\n * @throws Error when called without at least one action creator.\n */\nexport function ofType<\n const Creators extends readonly ActionCreator<string, any[], AnyAction>[],\n>(\n ...creators: Creators\n): OperatorFunction<AnyAction, ActionFromCreators<Creators>> {\n if (creators.length === 0) {\n throw new Error(\"ofType requires at least one action creator\");\n }\n\n const actionTypes = new Set(creators.map((creator) => creator.type));\n return (source$) => {\n return source$.pipe(\n filter((action: AnyAction): action is ActionFromCreators<Creators> => {\n return actionTypes.has(action.type);\n }),\n );\n };\n}\n\n/**\n * Creates a dispatching effect. Emitted actions are automatically dispatched.\n */\nexport function createEffect<\n State,\n InputAction extends AnyAction,\n OutputAction extends AnyAction,\n>(\n factory: (\n actions$: Observable<InputAction>,\n state$: Observable<State>,\n ) => Observable<OutputAction>,\n options?: DispatchingEffectOptions,\n): DispatchingEffect<State, InputAction, OutputAction>;\n\n/**\n * Creates a non-dispatching effect. Emitted values are ignored.\n */\nexport function createEffect<State, InputAction extends AnyAction>(\n factory: (\n actions$: Observable<InputAction>,\n state$: Observable<State>,\n ) => Observable<unknown>,\n options: NonDispatchingEffectOptions,\n): NonDispatchingEffect<State, InputAction>;\n\n/**\n * Creates an effect descriptor consumed by `createStore`.\n */\nexport function createEffect<\n State,\n InputAction extends AnyAction,\n OutputAction extends AnyAction,\n>(\n factory: (\n actions$: Observable<InputAction>,\n state$: Observable<State>,\n ) => Observable<OutputAction>,\n options: DispatchingEffectOptions | NonDispatchingEffectOptions = {},\n): Effect<State, InputAction, OutputAction> {\n if (options.dispatch === false) {\n return {\n run: factory,\n dispatch: false,\n };\n }\n\n return {\n run: factory,\n dispatch: true,\n };\n}\n\n/**\n * Store interface returned by `createStore`.\n */\nexport interface Store<State, Action extends AnyAction = AnyAction> {\n dispatch(action: Action): void;\n getState(): State;\n readonly state$: Observable<State>;\n readonly actions$: Observable<Action | StoreLifecycleAction>;\n select<Result>(selector: Selector<State, Result>): Observable<Result>;\n init(): void;\n stop(): void;\n}\n\n/**\n * Creates a small observable store with reducer + effects.\n *\n * Behavior:\n * - `init()` starts effects and dispatches `@@micro-redux/init`.\n * - `stop()` dispatches `@@micro-redux/stop` and unsubscribes all effects.\n * - Effect action observation is scheduled on `asapScheduler` to avoid\n * synchronous re-entrancy in the effect loop.\n * - Any effect error triggers fail-fast teardown and errors both `actions$`\n * and `state$`.\n */\nexport function createStore<\n State,\n Action extends AnyAction = AnyAction,\n>(options: {\n reducer: Reducer<State, Action | StoreLifecycleAction>;\n effects?: Array<Effect<State, Action | StoreLifecycleAction, Action>>;\n}): Store<State, Action> {\n const reducer = options.reducer;\n const effects = options.effects ?? [];\n\n let hasFatalError = false;\n let isRunning = false;\n let effectSubscriptions = new Subscription();\n\n let currentState = reducer(\n undefined,\n INTERNAL_BOOT_ACTION as Action | StoreLifecycleAction,\n );\n const stateSubject = new BehaviorSubject<State>(currentState);\n const actionsSubject = new Subject<Action | StoreLifecycleAction>();\n\n const dispatchInternal = (action: Action | StoreLifecycleAction): void => {\n if (hasFatalError) {\n throw new Error(\"Store is in a failed state due to an effect error\");\n }\n\n currentState = reducer(currentState, action);\n stateSubject.next(currentState);\n actionsSubject.next(action);\n };\n\n const failFast = (error: unknown): void => {\n if (hasFatalError) {\n return;\n }\n\n hasFatalError = true;\n isRunning = false;\n effectSubscriptions.unsubscribe();\n effectSubscriptions = new Subscription();\n\n actionsSubject.error(error);\n stateSubject.error(error);\n };\n\n const startEffects = (): void => {\n for (const effect of effects) {\n const scheduledActions$ = actionsSubject\n .asObservable()\n .pipe(observeOn(asapScheduler));\n const state$ = stateSubject.asObservable();\n\n if (effect.dispatch) {\n const subscription = effect.run(scheduledActions$, state$).subscribe({\n next: (effectAction) => {\n if (hasFatalError) {\n return;\n }\n dispatchInternal(effectAction);\n },\n error: (error) => {\n failFast(error);\n },\n });\n\n effectSubscriptions.add(subscription);\n continue;\n }\n\n const subscription = effect.run(scheduledActions$, state$).subscribe({\n error: (error) => {\n failFast(error);\n },\n });\n\n effectSubscriptions.add(subscription);\n }\n };\n\n return {\n dispatch(action: Action): void {\n dispatchInternal(action);\n },\n getState(): State {\n return currentState;\n },\n get state$(): Observable<State> {\n return stateSubject.asObservable();\n },\n get actions$(): Observable<Action | StoreLifecycleAction> {\n return actionsSubject.asObservable();\n },\n select<Result>(selector: Selector<State, Result>): Observable<Result> {\n return stateSubject.asObservable().pipe(select(selector));\n },\n init(): void {\n if (hasFatalError || isRunning) {\n return;\n }\n\n isRunning = true;\n startEffects();\n\n if (hasFatalError) {\n return;\n }\n\n dispatchInternal({ type: INTERNAL_ACTION_TYPES.init });\n },\n stop(): void {\n if (hasFatalError || !isRunning) {\n return;\n }\n\n dispatchInternal({ type: INTERNAL_ACTION_TYPES.stop });\n effectSubscriptions.unsubscribe();\n effectSubscriptions = new Subscription();\n isRunning = false;\n },\n };\n}\n","/**\n * Memory error registry — stable codes for the errors the memory store throws.\n *\n * The memory store (`memory.ts`) used to throw bare `new Error(\"Failed to fetch\n * memories: 500\")` / `\"Request timed out\"` / `\"Request failed: <status>\"`. Those\n * reach the `error` selector (and the consumer UI via `useMemories` /\n * `injectMemories`) verbatim, with no machine-readable `code`/`category`/\n * `retryable`, so they cannot be grouped in observability or branched on by\n * consumers.\n *\n * Per the repo's error-handling architecture standard (AGENTS.md: \"Each project\n * must maintain an explicit error registry\"), this file is the explicit registry\n * for the memory feature. It is deliberately scoped to memory — not a repo-wide\n * registry refactor — because `packages/core` has no pre-existing\n * code/category/retryable registry convention to plug into (the runtime's\n * `lib/error-messages.ts` is a message-templating table, not a typed\n * code/category/retryable registry). It mirrors the existing\n * `AgentThreadLockedError extends Error` precedent in\n * `intelligence-agent.ts`: a real `Error` subclass so `instanceof Error` holds\n * and the public `MemoryState.error: Error | null` contract is preserved.\n *\n * `docsPath` is recorded per entry per the standard; there is no\n * `docs/errors/<project>.md` in this repo, so this docblock plus the registry\n * are the source of truth.\n *\n * Each registry entry carries:\n * - `code`: stable identifier (e.g. `MEMORY_LIST_FAILED`).\n * - `category`: one of the standard categories\n * (`validation`|`auth`|`permission`|`not_found`|`conflict`|`rate_limit`|`internal`|`dependency`).\n * - `retryable`: whether a retry could plausibly succeed (timeouts + transient\n * dependency failures are retryable; client-caused 4xx are not).\n * - `message`: the default human-readable message (callers may override with a\n * status-bearing string to preserve the prior wording).\n * - `docsPath`: documentation pointer for the code.\n */\n\n/** Standard error categories from the repo error-handling architecture. */\nexport type MemoryErrorCategory =\n | \"validation\"\n | \"auth\"\n | \"permission\"\n | \"not_found\"\n | \"conflict\"\n | \"rate_limit\"\n | \"internal\"\n | \"dependency\";\n\n/** Stable codes for the memory store's surfaced errors. */\nexport type MemoryErrorCode =\n | \"MEMORY_LIST_FAILED\"\n | \"MEMORY_RECALL_FAILED\"\n | \"MEMORY_CREDENTIALS_FAILED\"\n | \"MEMORY_MUTATION_FAILED\"\n | \"MEMORY_REQUEST_TIMEOUT\";\n\n/** A single registry entry describing one memory error code. */\nexport interface MemoryErrorRegistryEntry {\n readonly code: MemoryErrorCode;\n readonly category: MemoryErrorCategory;\n readonly retryable: boolean;\n readonly message: string;\n readonly docsPath: string;\n}\n\n/**\n * The memory error registry: the single source of truth for memory error\n * metadata. Keyed by `code` so a code maps to exactly one category/retryable\n * default.\n *\n * Categories/retryable rationale:\n * - List/credentials/mutation failures are `dependency` (the runtime/platform\n * the store calls failed). A 5xx is transient (`retryable: true`); a 4xx is\n * caller-caused, so the helpers below downgrade those to non-retryable.\n * - Timeouts are `dependency` and `retryable: true` (the request may simply be\n * slow).\n */\nexport const MEMORY_ERROR_REGISTRY: Readonly<\n Record<MemoryErrorCode, MemoryErrorRegistryEntry>\n> = Object.freeze({\n MEMORY_LIST_FAILED: {\n code: \"MEMORY_LIST_FAILED\",\n category: \"dependency\",\n retryable: true,\n message: \"Failed to fetch memories\",\n docsPath: \"docs/errors/memory.md#memory_list_failed\",\n },\n MEMORY_RECALL_FAILED: {\n code: \"MEMORY_RECALL_FAILED\",\n category: \"dependency\",\n retryable: true,\n message: \"Failed to recall memories\",\n docsPath: \"docs/errors/memory.md#memory_recall_failed\",\n },\n MEMORY_CREDENTIALS_FAILED: {\n code: \"MEMORY_CREDENTIALS_FAILED\",\n category: \"dependency\",\n retryable: true,\n message: \"Failed to fetch memory subscribe credentials\",\n docsPath: \"docs/errors/memory.md#memory_credentials_failed\",\n },\n MEMORY_MUTATION_FAILED: {\n code: \"MEMORY_MUTATION_FAILED\",\n category: \"dependency\",\n retryable: true,\n message: \"Memory mutation request failed\",\n docsPath: \"docs/errors/memory.md#memory_mutation_failed\",\n },\n MEMORY_REQUEST_TIMEOUT: {\n code: \"MEMORY_REQUEST_TIMEOUT\",\n category: \"dependency\",\n retryable: true,\n message: \"Request timed out\",\n docsPath: \"docs/errors/memory.md#memory_request_timeout\",\n },\n});\n\n/**\n * An `Error` carrying a stable memory error `code`, `category`, and `retryable`\n * flag so consumers and observability can branch on it without string-matching\n * the message.\n *\n * It is a real `Error` subclass: `instanceof Error` is true, so the public\n * `MemoryState.error: Error | null` contract (and the `error: Error | null`\n * surfaced by `useMemories` / `injectMemories`) holds unchanged. Existing\n * consumers that only read `.message` keep working; the richer fields are\n * additive.\n */\nexport class MemoryError extends Error {\n /** Stable, machine-readable error identifier. */\n readonly code: MemoryErrorCode;\n /** Coarse error category for grouping/observability. */\n readonly category: MemoryErrorCategory;\n /** Whether retrying the operation could plausibly succeed. */\n readonly retryable: boolean;\n\n /**\n * @param code - Registry code identifying this error.\n * @param options - Optional overrides:\n * - `message`: human-readable message (defaults to the registry message;\n * callers pass a status-bearing string to preserve prior wording).\n * - `retryable`: overrides the registry default (e.g. a 4xx list failure is\n * not retryable even though the code's default is).\n * - `cause`: the underlying error, preserved for debugging.\n */\n constructor(\n code: MemoryErrorCode,\n options?: { message?: string; retryable?: boolean; cause?: unknown },\n ) {\n const entry = MEMORY_ERROR_REGISTRY[code];\n super(options?.message ?? entry.message, { cause: options?.cause });\n this.name = \"MemoryError\";\n this.code = code;\n this.category = entry.category;\n this.retryable = options?.retryable ?? entry.retryable;\n // Restore the prototype chain for environments that downlevel `extends`\n // (matches the pattern the SDK relies on for cross-target `instanceof`).\n Object.setPrototypeOf(this, MemoryError.prototype);\n }\n}\n\n/**\n * Narrows an HTTP status to whether the failure is worth retrying: a 5xx (or a\n * missing/0 status) is a transient dependency failure and retryable; a 4xx is\n * caller-caused and not. Used so a `MEMORY_LIST_FAILED`/`MEMORY_MUTATION_FAILED`\n * carries an accurate `retryable` flag derived from the response status.\n */\nexport function isRetryableStatus(status: number): boolean {\n return !(Number.isInteger(status) && status >= 400 && status <= 499);\n}\n","import { phoenixExponentialBackoff } from \"@copilotkit/shared\";\nimport {\n EMPTY,\n asapScheduler,\n defer,\n firstValueFrom,\n from,\n merge,\n Observable,\n observeOn,\n of,\n} from \"rxjs\";\nimport {\n catchError,\n concatWith,\n filter,\n finalize,\n map,\n mergeMap,\n share,\n shareReplay,\n switchMap,\n take,\n takeUntil,\n timeout,\n withLatestFrom,\n} from \"rxjs/operators\";\nimport {\n createActionGroup,\n createEffect,\n createReducer,\n createSelector,\n createStore,\n empty,\n ofType,\n on,\n props,\n} from \"./utils/micro-redux\";\nimport type { Reducer, Store } from \"./utils/micro-redux\";\nimport { MemoryError, isRetryableStatus } from \"./memory-errors\";\nimport {\n ɵphoenixChannel$,\n ɵphoenixSocket$,\n ɵjoinPhoenixChannel$,\n ɵobservePhoenixEvent$,\n ɵobservePhoenixSocketHealth$,\n ɵobservePhoenixSocketSignals$,\n} from \"./utils/phoenix-observable\";\nimport type { ɵPhoenixChannelSession } from \"./utils/phoenix-observable\";\n\n// Runtime-relative path, mirroring the thread store's `/threads` (NOT\n// `/api/threads`): `runtimeUrl` is the CopilotKit runtime mount (e.g.\n// `/api/copilotkit`), and the runtime maps `/memories` to the app-api's\n// `/api/memories` the same way it maps `/threads` -> `/api/threads`.\nconst MEMORIES_PATH = \"/memories\";\nconst MEMORIES_SUBSCRIBE_PATH = \"/memories/subscribe\";\nconst MEMORIES_RECALL_PATH = \"/memories/recall\";\nconst REQUEST_TIMEOUT_MS = 15_000;\n/** Consecutive socket errors tolerated before the realtime stream gives up. */\nconst MAX_SOCKET_RETRIES = 5;\n/**\n * HTTP status codes that indicate memory routes are not configured (non-fatal).\n * 404/501 mean the route is absent/unimplemented; 422 is the runtime's\n * MISSING_INTELLIGENCE signal (intelligence not configured on the deployment —\n * see packages/runtime/.../handlers/intelligence/memories.ts). All three map to\n * the graceful \"not available\" locked-teaser path, not a hard error.\n */\nconst ROUTE_UNAVAILABLE_STATUSES = new Set([404, 422, 501]);\n/**\n * Thrown when a memory route returns a 404/422/501 — treated as \"not\n * configured\" (422 is the runtime's MISSING_INTELLIGENCE signal).\n */\nclass MemoryRouteUnavailableError extends Error {}\n\n/** Public, customer-facing memory kind vocabulary (single taxonomy, no mapping). */\nexport type MemoryKind = \"topical\" | \"episodic\" | \"operational\";\n\n/** Visibility scope of a memory. */\nexport type MemoryScope = \"user\" | \"project\";\n\n/**\n * Health of the realtime (`user_meta:memories:<code>`) connection that streams\n * live `memory_metadata` deltas. Distinct from `available`/`error`, which\n * describe the REST list route: `realtimeStatus` reports ONLY whether the\n * realtime socket/channel is live so the UI can stop showing a \"live\" indicator\n * over a frozen snapshot once the socket permanently gives up.\n *\n * - `\"connecting\"` — fetching join credentials / opening the socket / joining\n * the channel (the default, and the state every `contextChanged`/`stopped`\n * resets to).\n * - `\"connected\"` — the channel join succeeded; live deltas are flowing.\n * - `\"unavailable\"` — the socket exhausted its retries or the join failed\n * permanently; the snapshot is frozen and no deltas will arrive. This is a\n * silent degrade for `available`/`error` (those stay untouched) — only this\n * signal flips.\n */\nexport type MemoryRealtimeStatus = \"connecting\" | \"connected\" | \"unavailable\";\n\n/**\n * A memory as projected across the public REST/realtime boundary — the minimal\n * shape the SDK surfaces. Mirrors the server's `PublicMemory` projection.\n */\nexport interface Memory {\n id: string;\n kind: MemoryKind;\n scope: MemoryScope;\n content: string;\n sourceThreadIds: readonly string[];\n invalidatedAt: string | null;\n /** Relevance score from a `recall()` (hybrid RAG) query; `undefined` for list/realtime/mutation memories. */\n score?: number;\n}\n\n/** Input for creating a memory; `scope` defaults to `\"user\"` (v1 is user-scoped). */\nexport interface NewMemory {\n content: string;\n kind: MemoryKind;\n scope?: MemoryScope;\n sourceThreadIds?: readonly string[];\n}\n\n/**\n * New values for superseding (updating) a memory — same shape as create.\n *\n * Supersede is a FULL replacement, not a partial patch: this is the complete\n * definition of the new memory that replaces the old one. `content` and `kind`\n * are required and must be re-supplied, and an omitted `sourceThreadIds` resets\n * the new memory's source threads to `[]` — it does NOT preserve the prior\n * memory's value.\n */\nexport type MemoryChanges = NewMemory;\n\n/** Outcome of a mutation, tracked so the caller's promise resolves/rejects. */\ntype MemoryMutationOutcome =\n | { requestId: string; sessionId: number; ok: true; memory: Memory | null }\n | { requestId: string; sessionId: number; ok: false; error: Error };\n\n/**\n * Runtime wiring for the memory store: where to reach the REST surface and the\n * headers (auth + `X-Cpki-User-Id`) to send. Scoped to the current user; v1\n * surfaces user-scoped memories only.\n */\ninterface MemoryRuntimeContext {\n runtimeUrl: string;\n /** WebSocket URL for the realtime gateway (e.g. `wss://gw.example.com/client`). */\n wsUrl: string;\n headers: Record<string, string>;\n includeInvalidated?: boolean;\n}\n\n/**\n * In-memory state for the memory store. Session-guarded like the thread store:\n * `sessionId` is bumped whenever the runtime context changes so that responses\n * and realtime deltas from a previous context are ignored.\n */\ninterface MemoryState {\n memories: Memory[];\n isLoading: boolean;\n inFlightMutationCount: number;\n error: Error | null;\n context: MemoryRuntimeContext | null;\n sessionId: number;\n available: boolean;\n realtimeStatus: MemoryRealtimeStatus;\n}\n\n// Deep-frozen so `getServerState()` (which returns this exact reference) cannot\n// be mutated by any caller; a single in-place write would otherwise corrupt\n// every SSR snapshot process-wide. The freeze covers the nested `memories`\n// array too — a shallow `Object.freeze` would leave `getServerState().memories`\n// mutable (`.push(...)` would silently succeed), so the empty array is frozen\n// before being sealed into the state. The reducers always build NEW state\n// objects/arrays (they spread, never mutate in place), so they are unaffected\n// and runtime behavior is unchanged.\nconst initialMemoryState: MemoryState = Object.freeze({\n memories: Object.freeze([]) as unknown as Memory[],\n isLoading: false,\n inFlightMutationCount: 0,\n error: null,\n context: null,\n sessionId: 0,\n available: true,\n realtimeStatus: \"connecting\",\n});\n\nconst memoryAdapterEvents = createActionGroup(\"Memory Adapter\", {\n started: empty(),\n stopped: empty(),\n contextChanged: props<{ context: MemoryRuntimeContext | null }>(),\n addRequested: props<{ requestId: string; input: NewMemory }>(),\n updateRequested: props<{\n requestId: string;\n id: string;\n changes: MemoryChanges;\n }>(),\n removeRequested: props<{ requestId: string; id: string }>(),\n});\n\nconst memoryRestEvents = createActionGroup(\"Memory REST\", {\n listRequested: props<{ sessionId: number }>(),\n listSucceeded: props<{ sessionId: number; memories: Memory[] }>(),\n listFailed: props<{ sessionId: number; error: Error }>(),\n listUnavailable: props<{ sessionId: number }>(),\n mutationFinished: props<{ outcome: MemoryMutationOutcome }>(),\n credentialsRequested: props<{ sessionId: number }>(),\n credentialsSucceeded: props<{\n sessionId: number;\n joinToken?: string;\n joinCode?: string;\n // Optional project-scoped realtime credentials. Present only when the\n // caller's API key resolves a project scope (B1b `/memories/subscribe`\n // returns them alongside the user credentials); omitted otherwise. When\n // present, the socket effect opens a SECOND `project_meta:memories:<code>`\n // channel so project rows stay live. Absent -> user-only (silent degrade).\n projectJoinToken?: string;\n projectJoinCode?: string;\n }>(),\n // Credentials outcomes are a SILENT degrade: they feed only the realtime\n // socket effect and deliberately do NOT touch the reducer's `available`/\n // `error`, which describe the REST list route. See the reducer note near the\n // list handlers.\n credentialsFailed: props<{ sessionId: number; error: Error }>(),\n credentialsUnavailable: props<{ sessionId: number }>(),\n});\n\nconst memoryDomainEvents = createActionGroup(\"Memory Domain\", {\n memoryUpserted: props<{ sessionId: number; memory: Memory }>(),\n memoryInvalidated: props<{ sessionId: number; memoryId: string }>(),\n // Realtime-connection health transitions, session-stamped like every other\n // realtime delta so the reducer's session guard drops transitions left over\n // from a superseded context. These flip ONLY `realtimeStatus`; they never\n // touch `available`/`error` (the realtime path is a silent degrade for those).\n realtimeConnecting: props<{ sessionId: number }>(),\n realtimeConnected: props<{ sessionId: number }>(),\n realtimeUnavailable: props<{ sessionId: number }>(),\n});\n\n/** Wire shape of a memory inside a `memory_metadata` payload (carries tenant ids). */\ninterface MemoryMetadataPayloadMemory extends Memory {\n organizationId: string;\n projectId: string;\n}\n\n/**\n * The realtime `memory_metadata` event broadcast on a memory channel:\n * `created`/`updated` carry the full memory, `invalidated` carries only its id.\n * The same wire shape is delivered on both the user channel\n * (`user_meta:memories:<code>`, current user's memories) and the optional\n * project channel (`project_meta:memories:<code>`, memories shared across the\n * project); the store reduces both into one id-keyed list.\n */\ntype MemoryMetadataEvent =\n | {\n operation: \"created\" | \"updated\";\n memoryId: string;\n organizationId: string;\n projectId: string;\n occurredAt: string;\n memory: MemoryMetadataPayloadMemory;\n }\n | {\n operation: \"invalidated\";\n memoryId: string;\n organizationId: string;\n projectId: string;\n occurredAt: string;\n invalidated: { id: string };\n };\n\n/** Projects a wire memory to the public {@link Memory} shape (drops tenant ids). */\nfunction toMemory(memory: MemoryMetadataPayloadMemory): Memory {\n return {\n id: memory.id,\n kind: memory.kind,\n scope: memory.scope,\n content: memory.content,\n sourceThreadIds: memory.sourceThreadIds,\n invalidatedAt: memory.invalidatedAt,\n };\n}\n\n/**\n * Maps a realtime `memory_metadata` event to the domain action that applies it:\n * `created`/`updated` upsert the projected memory, `invalidated` removes it by\n * id. Carries the current `sessionId` so the reducer's session guard can drop\n * deltas left over from a previous context.\n */\nfunction mapMemoryMetadataEvent(\n event: MemoryMetadataEvent,\n sessionId: number,\n):\n | ReturnType<typeof memoryDomainEvents.memoryUpserted>\n | ReturnType<typeof memoryDomainEvents.memoryInvalidated> {\n if (event.operation === \"invalidated\") {\n return memoryDomainEvents.memoryInvalidated({\n sessionId,\n memoryId: event.invalidated.id,\n });\n }\n\n return memoryDomainEvents.memoryUpserted({\n sessionId,\n memory: toMemory(event.memory),\n });\n}\n\n/**\n * Inserts or replaces a memory by id. A new memory is prepended (newest first,\n * matching the REST list's `created_at DESC` ordering without needing a date\n * field on the public projection); an existing memory is replaced in place.\n */\nfunction upsertMemory(memories: Memory[], memory: Memory): Memory[] {\n const existingIndex = memories.findIndex((item) => item.id === memory.id);\n if (existingIndex === -1) {\n return [memory, ...memories];\n }\n\n const next = [...memories];\n next[existingIndex] = memory;\n return next;\n}\n\nconst memoryReducer = createReducer(\n initialMemoryState,\n on(memoryAdapterEvents.contextChanged, (state: MemoryState, { context }) => ({\n ...state,\n context,\n sessionId: state.sessionId + 1,\n memories: [],\n isLoading: Boolean(context),\n inFlightMutationCount: 0,\n error: null,\n available: true,\n // A new context re-opens the realtime socket from scratch, so the connection\n // is \"connecting\" again until the new channel joins.\n realtimeStatus: \"connecting\" as MemoryRealtimeStatus,\n })),\n on(memoryAdapterEvents.stopped, (state: MemoryState) => ({\n ...state,\n memories: [],\n isLoading: false,\n inFlightMutationCount: 0,\n error: null,\n // Reset to the default (`true`), matching `contextChanged`. Otherwise a\n // `stop()` then `start()` WITHOUT a new `setContext` would retain a stale\n // `available: false` from a prior unconfigured session.\n available: true,\n // Reset to the default (\"connecting\"), matching `contextChanged`. A later\n // `start()` re-opens the socket; a stale \"unavailable\"/\"connected\" from the\n // prior session must not leak into the next.\n realtimeStatus: \"connecting\" as MemoryRealtimeStatus,\n })),\n on(memoryRestEvents.listRequested, (state: MemoryState, { sessionId }) => {\n if (sessionId !== state.sessionId || !state.context) {\n return state;\n }\n\n return {\n ...state,\n isLoading: true,\n error: null,\n available: true,\n };\n }),\n on(\n memoryRestEvents.listFailed,\n (state: MemoryState, { sessionId, error }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n isLoading: false,\n error,\n };\n },\n ),\n on(memoryRestEvents.listUnavailable, (state: MemoryState, { sessionId }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n memories: [],\n isLoading: false,\n error: null,\n available: false,\n };\n }),\n on(\n memoryAdapterEvents.addRequested,\n memoryAdapterEvents.updateRequested,\n memoryAdapterEvents.removeRequested,\n (state: MemoryState) => ({\n ...state,\n inFlightMutationCount: state.inFlightMutationCount + 1,\n }),\n ),\n on(memoryRestEvents.mutationFinished, (state: MemoryState, { outcome }) => {\n // Drop results from a superseded session. `contextChanged`/`stopped` already\n // reset `inFlightMutationCount`, so a mutation that resolves after the\n // context switched must not write a stale error into the new session.\n // Mirrors every other session-scoped handler (and threads.ts).\n if (outcome.sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n inFlightMutationCount: Math.max(0, state.inFlightMutationCount - 1),\n // On success clear any previously surfaced mutation error so a later\n // successful mutation does not leave a phantom sticky error banner.\n error: outcome.ok ? null : outcome.error,\n };\n }),\n on(\n memoryRestEvents.listSucceeded,\n (state: MemoryState, { sessionId, memories }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n memories,\n isLoading: false,\n error: null,\n // A successful list proves the memory route is available.\n available: true,\n };\n },\n ),\n // NOTE: `credentialsFailed` and `credentialsUnavailable` intentionally have NO\n // reducer cases. `available`/`error` describe the REST list route only and are\n // driven exclusively by the list events above. The credentials/realtime path\n // is a silent degrade by design: a missing/unconfigured `/memories/subscribe`\n // route (404/501/422) or a credentials error must not flip `available` or\n // surface an `error`, because the list route can still be perfectly healthy.\n // Otherwise `available` would be order-dependent on whichever of the two\n // concurrent `contextChanged` bootstraps responds last. Realtime failures are\n // handled where they occur (the socket effect retries and gives up via\n // console.warn); they do not belong in the REST availability state.\n on(\n memoryDomainEvents.memoryUpserted,\n (state: MemoryState, { sessionId, memory }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n memories: upsertMemory(state.memories, memory),\n };\n },\n ),\n on(\n memoryDomainEvents.memoryInvalidated,\n (state: MemoryState, { sessionId, memoryId }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n memories: state.memories.filter((memory) => memory.id !== memoryId),\n };\n },\n ),\n // Realtime-connection health. Session-guarded so a transition from a\n // superseded context is ignored. These flip ONLY `realtimeStatus`; `available`\n // and `error` describe the REST list route and are intentionally untouched.\n on(\n memoryDomainEvents.realtimeConnecting,\n (state: MemoryState, { sessionId }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n realtimeStatus: \"connecting\" as MemoryRealtimeStatus,\n };\n },\n ),\n on(\n memoryDomainEvents.realtimeConnected,\n (state: MemoryState, { sessionId }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n realtimeStatus: \"connected\" as MemoryRealtimeStatus,\n };\n },\n ),\n on(\n memoryDomainEvents.realtimeUnavailable,\n (state: MemoryState, { sessionId }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n realtimeStatus: \"unavailable\" as MemoryRealtimeStatus,\n };\n },\n ),\n) as Reducer<MemoryState>;\n\nconst selectMemories = createSelector((state: MemoryState) => state.memories);\nconst selectMemoriesIsLoading = createSelector(\n (state: MemoryState) => state.isLoading,\n);\nconst selectMemoriesError = createSelector((state: MemoryState) => state.error);\n/**\n * Reports whether at least one mutation is in flight. Derived from\n * `inFlightMutationCount` so concurrent mutations stay correct: the boolean\n * only clears once every in-flight mutation has settled.\n */\nconst selectMemoriesIsMutating = createSelector(\n (state: MemoryState) => state.inFlightMutationCount > 0,\n);\n/**\n * Reports whether the memory routes are available. Becomes `false` after a\n * 404, 422 (the runtime's MISSING_INTELLIGENCE signal), or 501 response during\n * an auto-activation read; defaults to `true`.\n */\nconst selectMemoriesAvailable = createSelector(\n (state: MemoryState) => state.available,\n);\n/**\n * Reports the realtime-connection health (see {@link MemoryRealtimeStatus}).\n * Distinct from `available`/`error`: it reflects ONLY the live socket/channel,\n * so the UI can suppress a \"live\" indicator once realtime permanently dies even\n * while the REST list route stays healthy. Defaults to `\"connecting\"`.\n */\nconst selectMemoriesRealtimeStatus = createSelector(\n (state: MemoryState) => state.realtimeStatus,\n);\n\n/**\n * Dependencies injected into the memory store. The store opens its own\n * `user_meta:memories:<joinCode>` socket/channel and does not share the\n * thread store's socket, so only a `fetch` implementation is required.\n */\ninterface MemoryEnvironment {\n fetch: typeof fetch;\n}\n\ninterface MemoryStore {\n start(): void;\n stop(): void;\n setContext(context: MemoryRuntimeContext | null): void;\n /**\n * Re-fetches the REST snapshot without clearing the current list. Resolves\n * once the re-pull settles (success or failure) for the current context, so\n * callers (e.g. a `useMemories` `refresh()`) can await it. Resolves\n * immediately when no context is set.\n */\n refresh(): Promise<void>;\n /**\n * Semantically recalls memories via `POST {runtimeUrl}/memories/recall`\n * (hybrid RAG). Returns memories ordered by relevance, each carrying a\n * `score`. Does NOT mutate the snapshot — a one-shot query. Rejects when no\n * context is set or the request fails.\n */\n recall(\n query: string,\n opts?: { limit?: number; scope?: MemoryScope },\n ): Promise<Memory[]>;\n /** Creates a memory; resolves to the stored memory (server-authoritative). */\n addMemory(input: NewMemory): Promise<Memory>;\n /** Supersedes a memory; resolves to the new memory (its id changes). */\n updateMemory(id: string, changes: MemoryChanges): Promise<Memory>;\n /** Retires a memory (non-lossy delete). */\n removeMemory(id: string): Promise<void>;\n getState(): MemoryState;\n /**\n * Stable, render-safe state for SSR/prerender. React's\n * `useSyncExternalStore` requires a `getServerSnapshot` during SSR/prerender\n * (e.g. Next.js); without one React throws \"Missing getServerSnapshot\". The\n * returned reference is stable across calls so React does not loop. There is\n * no client-side memory data during prerender, so this is the empty initial\n * state (no memories, not loading, no error).\n */\n getServerState(): MemoryState;\n select: Store<MemoryState>[\"select\"];\n}\n\nconst MEMORY_METADATA_EVENT = \"memory_metadata\";\n\n/** Runs a memory request through the injected fetch and aborts on unsubscribe. */\nfunction memoryFromFetch<T>(\n input: string,\n init: RequestInit & {\n selector: (response: Response) => Promise<T>;\n fetch: typeof fetch;\n },\n): Observable<T> {\n const {\n selector,\n fetch: fetchImplementation,\n signal: outerSignal,\n ...requestInit\n } = init;\n\n return new Observable<T>((subscriber) => {\n const controller = new AbortController();\n const abort = () => controller.abort();\n if (outerSignal?.aborted) {\n controller.abort();\n } else {\n outerSignal?.addEventListener(\"abort\", abort);\n }\n\n const subscription = from(\n fetchImplementation(input, {\n ...requestInit,\n signal: controller.signal,\n }),\n )\n .pipe(mergeMap((response) => from(selector(response))))\n .subscribe(subscriber);\n\n return () => {\n outerSignal?.removeEventListener(\"abort\", abort);\n controller.abort();\n subscription.unsubscribe();\n };\n });\n}\n\n/**\n * Fetches the memory snapshot and maps it to a success/failure action. Both\n * user- and project-scoped rows are kept: the store now opens a second\n * `project_meta:memories:<code>` realtime channel (when project credentials are\n * available) that keeps project rows in sync, so surfacing them in the snapshot\n * no longer risks a stale list. Rows are keyed by id across both channels, so\n * realtime deltas reconcile either scope idempotently.\n */\nfunction createMemoryFetchObservable(\n environment: MemoryEnvironment,\n context: MemoryRuntimeContext,\n sessionId: number,\n): Observable<\n | ReturnType<typeof memoryRestEvents.listSucceeded>\n | ReturnType<typeof memoryRestEvents.listFailed>\n | ReturnType<typeof memoryRestEvents.listUnavailable>\n> {\n return defer(() => {\n const qs = context.includeInvalidated ? \"?includeInvalidated=true\" : \"\";\n return memoryFromFetch(`${context.runtimeUrl}${MEMORIES_PATH}${qs}`, {\n selector: (response) => {\n if (!response.ok) {\n if (ROUTE_UNAVAILABLE_STATUSES.has(response.status)) {\n throw new MemoryRouteUnavailableError(String(response.status));\n }\n throw new MemoryError(\"MEMORY_LIST_FAILED\", {\n message: `Failed to fetch memories: ${response.status}`,\n retryable: isRetryableStatus(response.status),\n });\n }\n\n return response.json() as Promise<{ memories: Memory[] }>;\n },\n fetch: environment.fetch,\n method: \"GET\",\n headers: { ...context.headers },\n }).pipe(\n timeout({\n first: REQUEST_TIMEOUT_MS,\n with: () => {\n throw new MemoryError(\"MEMORY_REQUEST_TIMEOUT\");\n },\n }),\n map((data) =>\n memoryRestEvents.listSucceeded({\n sessionId,\n memories: data.memories,\n }),\n ),\n catchError((error) => {\n if (error instanceof MemoryRouteUnavailableError) {\n return of(memoryRestEvents.listUnavailable({ sessionId }));\n }\n return of(\n memoryRestEvents.listFailed({\n sessionId,\n error: error instanceof Error ? error : new Error(String(error)),\n }),\n );\n }),\n );\n });\n}\n\n/**\n * Fetches join credentials from the `/memories/subscribe` endpoint and maps\n * the response to a success/failure action. Requires both `joinToken` and\n * `joinCode` to be non-empty strings; throws otherwise so the `catchError`\n * path emits `credentialsFailed`.\n */\nfunction createMemoryCredentialsFetchObservable(\n environment: MemoryEnvironment,\n context: MemoryRuntimeContext,\n sessionId: number,\n): Observable<\n | ReturnType<typeof memoryRestEvents.credentialsSucceeded>\n | ReturnType<typeof memoryRestEvents.credentialsFailed>\n | ReturnType<typeof memoryRestEvents.credentialsUnavailable>\n> {\n return defer(() =>\n memoryFromFetch(`${context.runtimeUrl}${MEMORIES_SUBSCRIBE_PATH}`, {\n selector: async (response) => {\n if (!response.ok) {\n if (ROUTE_UNAVAILABLE_STATUSES.has(response.status)) {\n throw new MemoryRouteUnavailableError(String(response.status));\n }\n throw new MemoryError(\"MEMORY_CREDENTIALS_FAILED\", {\n message: `Failed to fetch memory subscribe credentials: ${response.status}`,\n retryable: isRetryableStatus(response.status),\n });\n }\n\n return response.json() as Promise<{\n joinToken?: string;\n joinCode?: string;\n projectJoinToken?: string;\n projectJoinCode?: string;\n }>;\n },\n fetch: environment.fetch,\n method: \"POST\",\n headers: { ...context.headers, \"Content-Type\": \"application/json\" },\n body: JSON.stringify({}),\n }).pipe(\n timeout({\n first: REQUEST_TIMEOUT_MS,\n with: () => {\n throw new MemoryError(\"MEMORY_REQUEST_TIMEOUT\");\n },\n }),\n map((data) => {\n const hasUserCreds =\n typeof data.joinToken === \"string\" &&\n data.joinToken.length > 0 &&\n typeof data.joinCode === \"string\" &&\n data.joinCode.length > 0;\n\n // Project credentials are optional and only forwarded when BOTH are\n // non-empty strings (the silent-degrade contract): a partial/malformed\n // pair is treated as \"no project scope\", so the store falls back to the\n // user channel only rather than erroring. A missing project scope must\n // never fail credentials — the user channel is the baseline.\n const hasProjectCreds =\n typeof data.projectJoinToken === \"string\" &&\n data.projectJoinToken.length > 0 &&\n typeof data.projectJoinCode === \"string\" &&\n data.projectJoinCode.length > 0;\n if (!hasUserCreds && !hasProjectCreds) {\n throw new Error(\"missing memory realtime credentials\");\n }\n\n return memoryRestEvents.credentialsSucceeded({\n sessionId,\n ...(hasUserCreds\n ? { joinToken: data.joinToken, joinCode: data.joinCode }\n : {}),\n ...(hasProjectCreds\n ? {\n projectJoinToken: data.projectJoinToken,\n projectJoinCode: data.projectJoinCode,\n }\n : {}),\n });\n }),\n catchError((error) => {\n if (error instanceof MemoryRouteUnavailableError) {\n return of(memoryRestEvents.credentialsUnavailable({ sessionId }));\n }\n return of(\n memoryRestEvents.credentialsFailed({\n sessionId,\n error: error instanceof Error ? error : new Error(String(error)),\n }),\n );\n }),\n ),\n );\n}\n\ntype MemoryMutationAction =\n | ReturnType<typeof memoryDomainEvents.memoryUpserted>\n | ReturnType<typeof memoryDomainEvents.memoryInvalidated>\n | ReturnType<typeof memoryRestEvents.mutationFinished>;\n\ntype MemoryMutationRequest =\n | {\n requestId: string;\n sessionId: number;\n kind: \"add\";\n body: Record<string, unknown>;\n }\n | {\n requestId: string;\n sessionId: number;\n kind: \"update\";\n id: string;\n body: Record<string, unknown>;\n }\n | { requestId: string; sessionId: number; kind: \"remove\"; id: string };\n\n/** Projects a REST mutation response to the public {@link Memory} shape. */\nfunction responseToMemory(data: {\n id: string;\n kind: MemoryKind;\n scope: MemoryScope;\n content: string;\n sourceThreadIds: readonly string[];\n invalidatedAt: string | null;\n}): Memory {\n return {\n id: data.id,\n kind: data.kind,\n scope: data.scope,\n content: data.content,\n sourceThreadIds: data.sourceThreadIds,\n invalidatedAt: data.invalidatedAt,\n };\n}\n\n/**\n * Projects a recall REST response memory (which carries a relevance `score`)\n * to the public {@link Memory} shape. `score` is copied through when supplied.\n */\nfunction recallResponseToMemory(data: {\n id: string;\n kind: MemoryKind;\n scope: MemoryScope;\n content: string;\n sourceThreadIds: readonly string[];\n invalidatedAt: string | null;\n score?: number;\n}): Memory {\n return {\n id: data.id,\n kind: data.kind,\n scope: data.scope,\n content: data.content,\n sourceThreadIds: data.sourceThreadIds,\n invalidatedAt: data.invalidatedAt,\n ...(typeof data.score === \"number\" ? { score: data.score } : {}),\n };\n}\n\nconst MEMORY_KINDS: ReadonlySet<string> = new Set([\n \"topical\",\n \"episodic\",\n \"operational\",\n]);\nconst MEMORY_SCOPES: ReadonlySet<string> = new Set([\"user\", \"project\"]);\n\n/**\n * Validates the required fields of a create/supersede REST response before it is\n * projected to a {@link Memory}. Returns an `Error` describing the first\n * missing/invalid field, or `null` when the body is well-formed. Without this a\n * malformed 200 body yields a Memory with undefined fields that gets upserted.\n */\nfunction validateMutationResponse(\n data: Record<string, unknown> | null,\n): Error | null {\n if (!data || typeof data !== \"object\") {\n return new Error(\"memory mutation response missing/invalid body\");\n }\n if (typeof data.id !== \"string\" || data.id.length === 0) {\n return new Error(\"memory mutation response missing/invalid id\");\n }\n if (typeof data.kind !== \"string\" || !MEMORY_KINDS.has(data.kind)) {\n return new Error(\"memory mutation response missing/invalid kind\");\n }\n if (typeof data.scope !== \"string\" || !MEMORY_SCOPES.has(data.scope)) {\n return new Error(\"memory mutation response missing/invalid scope\");\n }\n if (typeof data.content !== \"string\") {\n return new Error(\"memory mutation response missing/invalid content\");\n }\n // `sourceThreadIds` is `readonly string[]` on the public Memory; a malformed\n // 200 that omits it (or sends a non-array) would otherwise yield a Memory\n // whose `sourceThreadIds` is `undefined`, violating the type for every\n // consumer that maps over it.\n if (\n !Array.isArray(data.sourceThreadIds) ||\n !data.sourceThreadIds.every((id) => typeof id === \"string\")\n ) {\n return new Error(\n \"memory mutation response missing/invalid sourceThreadIds\",\n );\n }\n // `invalidatedAt` is `string | null`; reject any other type so it is not\n // copied through as `undefined`.\n if (data.invalidatedAt !== null && typeof data.invalidatedAt !== \"string\") {\n return new Error(\"memory mutation response missing/invalid invalidatedAt\");\n }\n return null;\n}\n\n/**\n * Request body for create/supersede. `scope` is forwarded only when the caller\n * supplies it: the platform owns the default (`scope` defaults to `\"user\"` in\n * the `/api/memories` schema), so the store does not second-guess it here —\n * one default, at the contract owner. `sourceThreadIds` defaults to `[]`.\n */\nfunction toMutationBody(input: NewMemory): Record<string, unknown> {\n return {\n content: input.content,\n kind: input.kind,\n ...(input.scope !== undefined ? { scope: input.scope } : {}),\n sourceThreadIds: input.sourceThreadIds ?? [],\n };\n}\n\n/**\n * Builds the actions a successful mutation dispatches (server-authoritative):\n * the REST response is applied to local state immediately, and the realtime\n * event reconciles idempotently (upsert-by-id). `mutationFinished` resolves the\n * caller's promise.\n */\nfunction buildMutationSuccessActions(\n request: MemoryMutationRequest,\n data: Record<string, unknown> | null,\n): MemoryMutationAction[] {\n const { requestId, sessionId } = request;\n\n if (request.kind === \"remove\") {\n // The platform's DELETE returns a bare 204 with NO body (the runtime\n // handler responds `new Response(null, { status: 204 })` and the client's\n // `removeMemory` is `Promise<void>`), so there is no confirmation field to\n // validate here — removal is status-code-confirmed. We optimistically remove\n // the row locally on any 2xx; the realtime `memory_metadata` `invalidated`\n // event (and the next REST refresh) reconcile idempotently.\n return [\n memoryDomainEvents.memoryInvalidated({ sessionId, memoryId: request.id }),\n memoryRestEvents.mutationFinished({\n outcome: { requestId, sessionId, ok: true, memory: null },\n }),\n ];\n }\n\n // Validate the required fields before projecting. A malformed 200 body would\n // otherwise yield a Memory with undefined fields that gets upserted into\n // state. Fail the mutation instead, mirroring the `retiredId` validation\n // below and the credentials path's joinToken/joinCode validation.\n const validationError = validateMutationResponse(data);\n if (validationError) {\n return [\n memoryRestEvents.mutationFinished({\n outcome: { requestId, sessionId, ok: false, error: validationError },\n }),\n ];\n }\n\n const memory = responseToMemory(\n data as Parameters<typeof responseToMemory>[0],\n );\n\n if (request.kind === \"update\") {\n // `retiredId` is optional on the server type. Without it the\n // `memoryInvalidated` would be a no-op (no id to remove), leaving the old\n // memory as a duplicate next to the new one. Validate it like the\n // credentials path validates joinToken/joinCode, and fail the mutation\n // rather than apply a half-baked supersede.\n const retiredId = (data as { retiredId?: string }).retiredId;\n if (typeof retiredId !== \"string\" || retiredId.length === 0) {\n return [\n memoryRestEvents.mutationFinished({\n outcome: {\n requestId,\n sessionId,\n ok: false,\n error: new Error(\"supersede response missing retiredId\"),\n },\n }),\n ];\n }\n\n return [\n memoryDomainEvents.memoryInvalidated({ sessionId, memoryId: retiredId }),\n memoryDomainEvents.memoryUpserted({ sessionId, memory }),\n memoryRestEvents.mutationFinished({\n outcome: { requestId, sessionId, ok: true, memory },\n }),\n ];\n }\n\n return [\n memoryDomainEvents.memoryUpserted({ sessionId, memory }),\n memoryRestEvents.mutationFinished({\n outcome: { requestId, sessionId, ok: true, memory },\n }),\n ];\n}\n\n/** Performs a create/supersede/retire HTTP call and emits its resulting actions. */\nfunction createMemoryMutationObservable(\n environment: MemoryEnvironment,\n context: MemoryRuntimeContext,\n request: MemoryMutationRequest,\n): Observable<MemoryMutationAction> {\n const method =\n request.kind === \"add\"\n ? \"POST\"\n : request.kind === \"update\"\n ? \"PATCH\"\n : \"DELETE\";\n const path =\n request.kind === \"add\"\n ? MEMORIES_PATH\n : `${MEMORIES_PATH}/${encodeURIComponent(request.id)}`;\n\n return defer(() =>\n memoryFromFetch(`${context.runtimeUrl}${path}`, {\n selector: async (response) => {\n if (!response.ok) {\n throw new MemoryError(\"MEMORY_MUTATION_FAILED\", {\n message: `Request failed: ${response.status}`,\n retryable: isRetryableStatus(response.status),\n });\n }\n\n return request.kind === \"remove\"\n ? null\n : ((await response.json()) as Record<string, unknown>);\n },\n fetch: environment.fetch,\n method,\n headers: { ...context.headers, \"Content-Type\": \"application/json\" },\n body:\n request.kind === \"remove\" ? undefined : JSON.stringify(request.body),\n }).pipe(\n timeout({\n first: REQUEST_TIMEOUT_MS,\n with: () => {\n throw new MemoryError(\"MEMORY_REQUEST_TIMEOUT\");\n },\n }),\n mergeMap((data) => of(...buildMutationSuccessActions(request, data))),\n catchError((error) =>\n of(\n memoryRestEvents.mutationFinished({\n outcome: {\n requestId: request.requestId,\n sessionId: request.sessionId,\n ok: false,\n error: error instanceof Error ? error : new Error(String(error)),\n },\n }),\n ),\n ),\n ),\n );\n}\n\n/**\n * Creates the framework-agnostic memory store: a REST snapshot on `setContext`,\n * server-authoritative add/update/remove mutations, and realtime\n * `memory_metadata` deltas off the injected `user_meta` event source — all\n * reduced into observable state.\n */\nfunction createMemoryStore(environment: MemoryEnvironment): MemoryStore {\n // Per-store request-id counter. Kept as a closure variable (not a\n // module-level global) so each store instance has its own monotonic sequence:\n // sharing one global across instances is a latent cross-instance/SSR hazard\n // and makes request ids non-reproducible in tests that reset a single store.\n let memoryRequestId = 0;\n const createMemoryRequestId = (): string => {\n memoryRequestId += 1;\n return `memory-request-${memoryRequestId}`;\n };\n\n const bootstrapEffect = createEffect(\n (actions$, state$: Observable<MemoryState>) =>\n actions$.pipe(\n ofType(memoryAdapterEvents.contextChanged),\n withLatestFrom(state$),\n filter(([, state]) => Boolean(state.context)),\n map(([, state]) =>\n memoryRestEvents.listRequested({ sessionId: state.sessionId }),\n ),\n ),\n );\n\n const credentialsBootstrapEffect = createEffect(\n (actions$, state$: Observable<MemoryState>) =>\n actions$.pipe(\n ofType(memoryAdapterEvents.contextChanged),\n withLatestFrom(state$),\n filter(([, state]) => Boolean(state.context)),\n map(([, state]) =>\n memoryRestEvents.credentialsRequested({ sessionId: state.sessionId }),\n ),\n ),\n );\n\n const credentialsFetchEffect = createEffect(\n (actions$, state$: Observable<MemoryState>) =>\n actions$.pipe(\n ofType(memoryRestEvents.credentialsRequested),\n switchMap((action) =>\n state$.pipe(\n map((state) => state.context),\n filter((context): context is MemoryRuntimeContext =>\n Boolean(context),\n ),\n take(1),\n map((context) => ({ action, context })),\n takeUntil(\n actions$.pipe(\n ofType(\n memoryAdapterEvents.contextChanged,\n memoryAdapterEvents.stopped,\n ),\n ),\n ),\n switchMap(({ action: currentAction, context }) =>\n createMemoryCredentialsFetchObservable(\n environment,\n context,\n currentAction.sessionId,\n ),\n ),\n ),\n ),\n ),\n );\n\n const fetchEffect = createEffect(\n (actions$, state$: Observable<MemoryState>) =>\n actions$.pipe(\n ofType(memoryRestEvents.listRequested),\n switchMap((action) =>\n state$.pipe(\n map((state) => state.context),\n filter((context): context is MemoryRuntimeContext =>\n Boolean(context),\n ),\n take(1),\n map((context) => ({ action, context })),\n takeUntil(\n actions$.pipe(\n ofType(\n memoryAdapterEvents.contextChanged,\n memoryAdapterEvents.stopped,\n ),\n ),\n ),\n switchMap(({ action: currentAction, context }) =>\n createMemoryFetchObservable(\n environment,\n context,\n currentAction.sessionId,\n ),\n ),\n ),\n ),\n ),\n );\n\n const mutationEffect = createEffect(\n (actions$, state$: Observable<MemoryState>) =>\n actions$.pipe(\n ofType(\n memoryAdapterEvents.addRequested,\n memoryAdapterEvents.updateRequested,\n memoryAdapterEvents.removeRequested,\n ),\n withLatestFrom(state$),\n mergeMap(([action, state]) => {\n const context = state.context;\n const sessionId = state.sessionId;\n if (!context?.runtimeUrl) {\n return of(\n memoryRestEvents.mutationFinished({\n outcome: {\n requestId: action.requestId,\n sessionId,\n ok: false,\n error: new Error(\"Runtime URL is not configured\"),\n },\n }),\n );\n }\n\n if (memoryAdapterEvents.addRequested.match(action)) {\n return createMemoryMutationObservable(environment, context, {\n requestId: action.requestId,\n sessionId,\n kind: \"add\",\n body: toMutationBody(action.input),\n });\n }\n if (memoryAdapterEvents.updateRequested.match(action)) {\n return createMemoryMutationObservable(environment, context, {\n requestId: action.requestId,\n sessionId,\n kind: \"update\",\n id: action.id,\n body: toMutationBody(action.changes),\n });\n }\n return createMemoryMutationObservable(environment, context, {\n requestId: action.requestId,\n sessionId,\n kind: \"remove\",\n id: action.id,\n });\n }),\n ),\n );\n\n const socketEffect = createEffect(\n (actions$, state$: Observable<MemoryState>) =>\n actions$.pipe(\n ofType(memoryRestEvents.credentialsSucceeded),\n withLatestFrom(state$),\n filter(([action, state]) => {\n return (\n action.sessionId === state.sessionId &&\n Boolean(state.context?.wsUrl)\n );\n }),\n switchMap(([action, state]) => {\n const context = state.context as MemoryRuntimeContext;\n const { joinToken, joinCode, projectJoinToken, projectJoinCode } =\n action;\n const primaryJoinToken = joinToken ?? projectJoinToken!;\n const primaryTopic =\n joinToken && joinCode\n ? `user_meta:memories:${joinCode}`\n : `project_meta:memories:${projectJoinCode!}`;\n const sessionId = action.sessionId;\n const shutdown$ = actions$.pipe(\n ofType(\n memoryAdapterEvents.contextChanged,\n memoryAdapterEvents.stopped,\n ),\n );\n\n // Builds the live `memory_metadata` delta stream for one realtime\n // channel (its own socket, keyed by that channel's join token). Both\n // the user channel and the optional project channel feed the SAME\n // reducer through this, and — critically — both stamp their deltas\n // with the SAME `sessionId` (the D4 landmine): the reducer's\n // superseded-context guard therefore drops stale deltas from BOTH\n // channels identically the moment the context changes. The reducer's\n // upsert/invalidate already key by memory id, so interleaving user\n // and project rows is safe (no per-channel bookkeeping needed).\n const channelMetadata$ = (\n channelJoinToken: string,\n topic: string,\n ): Observable<\n | ReturnType<typeof memoryDomainEvents.memoryUpserted>\n | ReturnType<typeof memoryDomainEvents.memoryInvalidated>\n > => {\n const socket$ = ɵphoenixSocket$({\n url: context.wsUrl,\n options: {\n params: { join_token: channelJoinToken },\n reconnectAfterMs: phoenixExponentialBackoff(100, 10_000),\n rejoinAfterMs: phoenixExponentialBackoff(1_000, 30_000),\n },\n }).pipe(shareReplay({ bufferSize: 1, refCount: true }));\n const channel$ = ɵphoenixChannel$({ socket$, topic }).pipe(\n shareReplay({ bufferSize: 1, refCount: true }),\n );\n const metadata$ = channel$.pipe(\n switchMap(({ channel }: ɵPhoenixChannelSession) =>\n ɵobservePhoenixEvent$<MemoryMetadataEvent>(\n channel,\n MEMORY_METADATA_EVENT,\n ),\n ),\n map((event) => mapMemoryMetadataEvent(event, sessionId)),\n );\n // Drive the join (see the user-channel note below) but swallow its\n // outcome: the project channel deliberately does NOT emit realtime\n // status deltas — `realtimeStatus` is owned by the user channel so\n // a project-channel join failure never regresses the user-facing\n // \"live\" indicator (silent degrade). On failure the metadata stream\n // stays alive for Phoenix's automatic rejoin on reconnect.\n const join$ = ɵjoinPhoenixChannel$(channel$).pipe(\n catchError((error) => {\n console.warn(`[memory] failed to join ${topic}`, error);\n return EMPTY;\n }),\n );\n return merge(metadata$, join$);\n };\n\n return defer(() => {\n const socket$ = ɵphoenixSocket$({\n url: context.wsUrl,\n options: {\n params: { join_token: primaryJoinToken },\n reconnectAfterMs: phoenixExponentialBackoff(100, 10_000),\n rejoinAfterMs: phoenixExponentialBackoff(1_000, 30_000),\n },\n }).pipe(shareReplay({ bufferSize: 1, refCount: true }));\n const channel$ = ɵphoenixChannel$({\n socket$,\n topic: primaryTopic,\n }).pipe(shareReplay({ bufferSize: 1, refCount: true }));\n const socketSignals$ =\n ɵobservePhoenixSocketSignals$(socket$).pipe(share());\n // The socket give-up signal: completes the realtime stream after the\n // health check throws. ALSO surfaces the give-up as a status delta\n // (`realtimeUnavailable`) so the UI can drop its \"live\" indicator —\n // this is the permanent-death signal that was previously only a\n // `console.warn`. `available`/`error` stay untouched by design (the\n // realtime path is a silent degrade for the REST list route).\n const fatalSocketShutdown$ = ɵobservePhoenixSocketHealth$(\n socketSignals$,\n MAX_SOCKET_RETRIES,\n ).pipe(\n catchError(() => {\n console.warn(\n `[memory] WebSocket failed after ${MAX_SOCKET_RETRIES} attempts, giving up`,\n );\n return of(undefined);\n }),\n share(),\n );\n // The give-up mapped to a status delta. Emitted from the merged stream\n // (not the `takeUntil` notifier) so the `realtimeUnavailable` action is\n // dispatched BEFORE teardown: the merged stream is `takeUntil`'d by a\n // microtask-deferred copy of the give-up signal, so this synchronous\n // emission always wins the race and the action reaches the reducer.\n const fatalStatus$ = fatalSocketShutdown$.pipe(\n map(() => memoryDomainEvents.realtimeUnavailable({ sessionId })),\n );\n const metadata$ = channel$.pipe(\n switchMap(({ channel }: ɵPhoenixChannelSession) =>\n ɵobservePhoenixEvent$<MemoryMetadataEvent>(\n channel,\n MEMORY_METADATA_EVENT,\n ),\n ),\n map((event) => mapMemoryMetadataEvent(event, action.sessionId)),\n );\n\n // Drives the actual `channel.join()` AND maps the join outcome to a\n // realtime-status delta. `ɵphoenixChannel$` only creates the channel +\n // a lazy join-outcome stream; the join is sent when that stream is\n // subscribed. Observing channel events (`metadata$`) alone does NOT\n // subscribe it, so without this the socket connects but never joins\n // `user_meta:memories:<code>` and no realtime deltas arrive. The thread\n // store joins for the same reason (its merged `joinOutcome$`).\n //\n // On a successful join -> `realtimeConnected` (the \"live\" signal). On a\n // failed/timed-out join we KEEP the `console.warn` and emit\n // `realtimeUnavailable`, then swallow the error so a transient\n // rejection doesn't tear down the metadata stream (Phoenix re-attempts\n // the join on socket reconnect); the next successful join re-emits\n // `realtimeConnected`.\n const join$ = ɵjoinPhoenixChannel$(channel$).pipe(\n // `ɵjoinPhoenixChannel$` emits `never` (it completes on success), so\n // this concat surfaces the connected status once the join resolves.\n concatWith(\n of(memoryDomainEvents.realtimeConnected({ sessionId })),\n ),\n catchError((error) => {\n console.warn(`[memory] failed to join ${primaryTopic}`, error);\n return of(\n memoryDomainEvents.realtimeUnavailable({ sessionId }),\n );\n }),\n );\n\n // Open the project channel alongside the user channel when project\n // credentials are present. It feeds the SAME reducer with the SAME\n // session stamp (see `channelMetadata$`), so project rows stay live\n // without going stale. Absent project creds -> `EMPTY`: user-only,\n // no second socket, no status regression (silent degrade).\n const projectMetadata$ =\n joinToken && joinCode && projectJoinToken && projectJoinCode\n ? channelMetadata$(\n projectJoinToken,\n `project_meta:memories:${projectJoinCode}`,\n )\n : EMPTY;\n\n return merge(\n // Surface \"connecting\" immediately when the realtime stream starts\n // (credentials succeeded -> socket subscribing/joining). Reset to\n // this on every (re)subscribe so a prior session's terminal status\n // can't bleed through before the new join resolves.\n of(memoryDomainEvents.realtimeConnecting({ sessionId })),\n metadata$,\n join$,\n projectMetadata$,\n fatalStatus$,\n ).pipe(\n takeUntil(\n merge(\n shutdown$,\n // Defer the give-up teardown by a microtask so `fatalStatus$`'s\n // synchronous `realtimeUnavailable` emission is dispatched before\n // the stream is torn down. `observeOn(asapScheduler)` schedules\n // the teardown after the current microtask drains.\n fatalSocketShutdown$.pipe(observeOn(asapScheduler)),\n ),\n ),\n finalize(() => {\n // Socket/channel teardown is handled by the `finalize` operators\n // inside `ɵphoenixSocket$`/`ɵphoenixChannel$`; this hook exists to\n // mirror the thread store's socket-effect lifecycle shape.\n }),\n );\n });\n }),\n ),\n );\n\n const store = createStore<MemoryState>({\n reducer: memoryReducer,\n effects: [\n bootstrapEffect,\n credentialsBootstrapEffect,\n fetchEffect,\n credentialsFetchEffect,\n mutationEffect,\n socketEffect,\n ],\n });\n\n function trackMutation<T>(\n dispatchAction:\n | ReturnType<typeof memoryAdapterEvents.addRequested>\n | ReturnType<typeof memoryAdapterEvents.updateRequested>\n | ReturnType<typeof memoryAdapterEvents.removeRequested>,\n extract: (outcome: Extract<MemoryMutationOutcome, { ok: true }>) => T,\n ): Promise<T> {\n const { requestId } = dispatchAction;\n const completion$ = merge(\n store.actions$.pipe(\n ofType(memoryRestEvents.mutationFinished),\n filter((action) => action.outcome.requestId === requestId),\n map((action) => action.outcome),\n ),\n store.actions$.pipe(\n ofType(memoryAdapterEvents.stopped),\n map(\n () =>\n ({\n requestId,\n sessionId: store.getState().sessionId,\n ok: false,\n error: new Error(\n \"Memory store stopped before mutation completed\",\n ),\n }) satisfies MemoryMutationOutcome,\n ),\n ),\n ).pipe(take(1));\n\n const resultPromise = firstValueFrom(completion$).then((outcome) => {\n if (!outcome.ok) {\n throw outcome.error;\n }\n return extract(outcome);\n });\n\n store.dispatch(dispatchAction);\n return resultPromise;\n }\n\n return {\n start(): void {\n store.init();\n store.dispatch(memoryAdapterEvents.started());\n },\n stop(): void {\n store.dispatch(memoryAdapterEvents.stopped());\n store.stop();\n },\n setContext(context: MemoryRuntimeContext | null): void {\n store.dispatch(memoryAdapterEvents.contextChanged({ context }));\n },\n refresh(): Promise<void> {\n const { sessionId, context } = store.getState();\n if (!context) return Promise.resolve();\n\n // Settle when the re-pulled snapshot completes for this session (success\n // or failure), or if the store is stopped first. Subscribe before\n // dispatching so the resulting list action can't slip past, mirroring\n // trackMutation.\n const completion$ = merge(\n store.actions$.pipe(\n ofType(\n memoryRestEvents.listSucceeded,\n memoryRestEvents.listFailed,\n // `listUnavailable` (404/501/422) is the third terminal outcome of\n // the list fetch. Without it `await refresh()` would hang forever\n // against an unconfigured route.\n memoryRestEvents.listUnavailable,\n ),\n filter((action) => action.sessionId === sessionId),\n ),\n store.actions$.pipe(ofType(memoryAdapterEvents.stopped)),\n // The list `fetchEffect` has `takeUntil(contextChanged, stopped)`, so a\n // `contextChanged` fired after this `listRequested` but before the fetch\n // settles tears down the fetch with NO terminal list action for our\n // session — `await refresh()` would hang forever. Settle on it too.\n store.actions$.pipe(ofType(memoryAdapterEvents.contextChanged)),\n ).pipe(take(1));\n\n // `await refresh()` resolving must mean the snapshot actually refreshed,\n // so reject on anything that isn't a successful re-pull — a failed list\n // (its error also lands in the `error` selector) or the store being\n // stopped mid-flight. This keeps `refresh` fully symmetric with the\n // mutation methods, which reject on both failure and stop via\n // `trackMutation`.\n const done = firstValueFrom(completion$).then((action) => {\n if (memoryRestEvents.listFailed.match(action)) {\n throw action.error;\n }\n if (memoryAdapterEvents.stopped.match(action)) {\n throw new Error(\"Memory store stopped before refresh completed\");\n }\n // A `contextChanged` superseded this refresh: a new context is loading\n // its own snapshot, so this refresh is moot. RESOLVE (do not reject) —\n // resolving is the least-surprising outcome for a superseded refresh.\n if (memoryAdapterEvents.contextChanged.match(action)) {\n return;\n }\n // `listSucceeded` and `listUnavailable` both RESOLVE: an unavailable\n // (not-configured) route is a non-fatal terminal state, consistent with\n // the auto-load path which leaves `available: false` without erroring.\n });\n store.dispatch(memoryRestEvents.listRequested({ sessionId }));\n return done;\n },\n recall(\n query: string,\n opts?: { limit?: number; scope?: MemoryScope },\n ): Promise<Memory[]> {\n const { context } = store.getState();\n if (!context?.runtimeUrl) {\n return Promise.reject(new Error(\"Runtime URL is not configured\"));\n }\n const body: Record<string, unknown> = { query };\n if (opts?.limit !== undefined) body.limit = opts.limit;\n if (opts?.scope !== undefined) body.scope = opts.scope;\n\n const recall$ = memoryFromFetch(\n `${context.runtimeUrl}${MEMORIES_RECALL_PATH}`,\n {\n selector: async (response) => {\n if (!response.ok) {\n throw new MemoryError(\"MEMORY_RECALL_FAILED\", {\n message: `Failed to recall memories: ${response.status}`,\n retryable: isRetryableStatus(response.status),\n });\n }\n return (await response.json()) as { memories: unknown[] };\n },\n fetch: environment.fetch,\n method: \"POST\",\n headers: { ...context.headers, \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n },\n ).pipe(\n timeout({\n first: REQUEST_TIMEOUT_MS,\n with: () => {\n throw new MemoryError(\"MEMORY_REQUEST_TIMEOUT\");\n },\n }),\n map((data) =>\n (data.memories ?? []).map((m) =>\n recallResponseToMemory(\n m as Parameters<typeof recallResponseToMemory>[0],\n ),\n ),\n ),\n );\n return firstValueFrom(recall$);\n },\n addMemory(input: NewMemory): Promise<Memory> {\n return trackMutation(\n memoryAdapterEvents.addRequested({\n requestId: createMemoryRequestId(),\n input,\n }),\n (outcome) => {\n if (outcome.memory == null) {\n throw new Error(\"add resolved without a memory\");\n }\n return outcome.memory;\n },\n );\n },\n updateMemory(id: string, changes: MemoryChanges): Promise<Memory> {\n return trackMutation(\n memoryAdapterEvents.updateRequested({\n requestId: createMemoryRequestId(),\n id,\n changes,\n }),\n (outcome) => {\n if (outcome.memory == null) {\n throw new Error(\"update resolved without a memory\");\n }\n return outcome.memory;\n },\n );\n },\n removeMemory(id: string): Promise<void> {\n return trackMutation(\n memoryAdapterEvents.removeRequested({\n requestId: createMemoryRequestId(),\n id,\n }),\n () => undefined,\n );\n },\n getState(): MemoryState {\n return store.getState();\n },\n getServerState(): MemoryState {\n return initialMemoryState;\n },\n select: store.select.bind(store),\n };\n}\n\n// `Memory`, `MemoryKind`, `MemoryScope`, `NewMemory`, and `MemoryChanges` are\n// the consumer-facing memory types surfaced by the framework hooks\n// (`useMemories` / `injectMemories`); they are exported unprefixed from their\n// declarations above. The remaining memory internals keep the `ɵ` prefix.\n// The memory error registry surface is consumer-facing: `MemoryError` is what\n// `MemoryState.error` (and the `error: Error | null` from `useMemories` /\n// `injectMemories`) carries on a failure, and consumers branch on its\n// `code`/`category`/`retryable`. Re-exported unprefixed here so it ships through\n// `index.ts` (`export * from \"./memory\"`) alongside the memory types.\nexport {\n MemoryError,\n MEMORY_ERROR_REGISTRY,\n isRetryableStatus as ɵisRetryableMemoryStatus,\n} from \"./memory-errors\";\nexport type {\n MemoryErrorCode,\n MemoryErrorCategory,\n MemoryErrorRegistryEntry,\n} from \"./memory-errors\";\n\nexport type ɵMemoryState = MemoryState;\nexport type ɵMemoryRuntimeContext = MemoryRuntimeContext;\nexport type ɵMemoryMetadataEvent = MemoryMetadataEvent;\nexport type ɵMemoryEnvironment = MemoryEnvironment;\nexport type ɵMemoryStore = MemoryStore;\nexport const ɵmemoryAdapterEvents = memoryAdapterEvents;\nexport const ɵmemoryRestEvents = memoryRestEvents;\nexport const ɵmemoryDomainEvents = memoryDomainEvents;\nexport const ɵmemoryReducer = memoryReducer;\nexport const ɵmapMemoryMetadataEvent = mapMemoryMetadataEvent;\nexport const ɵselectMemories = selectMemories;\nexport const ɵselectMemoriesIsLoading = selectMemoriesIsLoading;\nexport const ɵselectMemoriesError = selectMemoriesError;\nexport const ɵselectMemoriesIsMutating = selectMemoriesIsMutating;\nexport const ɵselectMemoriesAvailable = selectMemoriesAvailable;\nexport const ɵselectMemoriesRealtimeStatus = selectMemoriesRealtimeStatus;\nexport { createMemoryStore as ɵcreateMemoryStore };\n","import type { AbstractAgent, Context, State } from \"@ag-ui/client\";\nimport type { AgentSubscriber } from \"@ag-ui/client\";\nimport { Throttler } from \"@tanstack/pacer\";\nimport type {\n FrontendTool,\n SuggestionsConfig,\n Suggestion,\n CopilotRuntimeTransport,\n RuntimeMode,\n RuntimeLicenseStatus,\n IntelligenceRuntimeInfo,\n InspectorMetadataV1,\n ThreadEndpointRuntimeInfo,\n} from \"../types\";\nimport type {\n CopilotKitCoreAddAgentParams,\n CopilotKitCoreRegisterProxiedAgentParams,\n CopilotKitCoreRegisterProxiedAgentResult,\n} from \"./agent-registry\";\nimport type { CopilotKitMessageFilter } from \"./message-filter\";\nimport { AgentRegistry } from \"./agent-registry\";\nimport type { ScopedContext } from \"./context-store\";\nimport { ContextStore } from \"./context-store\";\nimport { SuggestionEngine } from \"./suggestion-engine\";\nimport type {\n CopilotKitCoreRunAgentParams,\n CopilotKitCoreConnectAgentParams,\n CopilotKitCoreGetToolParams,\n CopilotKitCoreRunToolParams,\n CopilotKitCoreRunToolResult,\n CopilotKitCoreCatalogComponent,\n} from \"./run-handler\";\nimport { RunHandler } from \"./run-handler\";\nimport type {\n DebugConfig,\n RuntimeEntitlementResponse,\n} from \"@copilotkit/shared\";\nimport { StateManager } from \"./state-manager\";\nimport type { CopilotKitCoreContinuationHandoff } from \"./state-manager\";\nimport { ThreadStoreRegistry } from \"./thread-store-registry\";\nimport type { ɵThreadStore } from \"../threads\";\nimport { ɵcreateMemoryStore } from \"../memory\";\nimport type { ɵMemoryStore } from \"../memory\";\n\n/** Configuration options for `CopilotKitCore`. */\nexport interface CopilotKitCoreConfig {\n /** The endpoint of the CopilotRuntime. */\n runtimeUrl?: string;\n /** Transport style for CopilotRuntime endpoints. Defaults to REST. */\n runtimeTransport?: CopilotRuntimeTransport;\n /**\n * When true, the constructor sets the runtime config but does NOT start the\n * `/info` connection. Call {@link CopilotKitCore.connect} to start it —\n * typically from a host's commit-phase effect. This prevents a burst of\n * duplicate `/info` requests when a host constructs (and discards) the core\n * during render, e.g. React concurrent rendering / Suspense / StrictMode.\n * See https://github.com/CopilotKit/CopilotKit/issues/5801.\n */\n deferInitialConnection?: boolean;\n /** Mapping from agent name to its `AbstractAgent` instance. For development only - production requires CopilotRuntime. */\n agents__unsafe_dev_only?: Record<string, AbstractAgent>;\n /**\n * Headers sent with every runtime request and merged on top of each\n * `HttpAgent`'s own headers (the core value wins on a key conflict). See\n * `setHeaders`.\n */\n headers?: Record<string, string>;\n /** Credentials mode for fetch requests (e.g., \"include\" for HTTP-only cookies). */\n credentials?: RequestCredentials;\n /**\n * Rewrites the message list sent to runtime agents on every run. Use it when\n * the backend already stores the conversation and re-sending it is waste or\n * duplication. See `setMessageFilter` and {@link CopilotKitMessageFilter}.\n */\n messageFilter?: CopilotKitMessageFilter;\n /** Properties sent as `forwardedProps` to the AG-UI agent. */\n properties?: Record<string, unknown>;\n /** Ordered collection of frontend tools available to the core. */\n tools?: FrontendTool<any>[];\n /** Suggestions config for the core. */\n suggestionsConfig?: SuggestionsConfig[];\n /** Enable debug logging for the client-side event pipeline. */\n debug?: DebugConfig;\n}\n\nexport type { CopilotKitMessageFilter } from \"./message-filter\";\n\nexport type {\n CopilotKitCoreAddAgentParams,\n CopilotKitCoreRegisterProxiedAgentParams,\n CopilotKitCoreRegisterProxiedAgentResult,\n};\nexport type {\n CopilotKitCoreRunAgentParams,\n CopilotKitCoreConnectAgentParams,\n CopilotKitCoreGetToolParams,\n CopilotKitCoreRunToolParams,\n CopilotKitCoreRunToolResult,\n CopilotKitCoreCatalogComponent,\n};\n\nexport interface CopilotKitCoreStopAgentParams {\n agent: AbstractAgent;\n}\n\nexport type CopilotKitCoreGetSuggestionsResult = {\n suggestions: Suggestion[];\n isLoading: boolean;\n};\n\nexport enum CopilotKitCoreErrorCode {\n RUNTIME_INFO_FETCH_FAILED = \"runtime_info_fetch_failed\",\n AGENT_CONNECT_FAILED = \"agent_connect_failed\",\n AGENT_RUN_FAILED = \"agent_run_failed\",\n AGENT_RUN_FAILED_EVENT = \"agent_run_failed_event\",\n AGENT_RUN_ERROR_EVENT = \"agent_run_error_event\",\n TOOL_ARGUMENT_PARSE_FAILED = \"tool_argument_parse_failed\",\n TOOL_HANDLER_FAILED = \"tool_handler_failed\",\n TOOL_NOT_FOUND = \"tool_not_found\",\n AGENT_NOT_FOUND = \"agent_not_found\",\n /**\n * Emitted when an agent run fails because the thread is already locked\n * by another active run.\n *\n * @example\n * ```tsx\n * <CopilotKitProvider\n * onError={({ code, error, context }) => {\n * if (code === \"agent_thread_locked\") {\n * // Show \"Agent is busy, retry?\" UI\n * }\n * }}\n * />\n * ```\n */\n AGENT_THREAD_LOCKED = \"agent_thread_locked\",\n // Transcription errors\n TRANSCRIPTION_FAILED = \"transcription_failed\",\n TRANSCRIPTION_SERVICE_NOT_CONFIGURED = \"transcription_service_not_configured\",\n TRANSCRIPTION_INVALID_AUDIO = \"transcription_invalid_audio\",\n TRANSCRIPTION_RATE_LIMITED = \"transcription_rate_limited\",\n TRANSCRIPTION_AUTH_FAILED = \"transcription_auth_failed\",\n TRANSCRIPTION_NETWORK_ERROR = \"transcription_network_error\",\n SUBSCRIBER_CALLBACK_FAILED = \"subscriber_callback_failed\",\n}\n\nexport interface CopilotKitCoreSubscriber {\n onRuntimeConnectionStatusChanged?: (event: {\n copilotkit: CopilotKitCore;\n status: CopilotKitCoreRuntimeConnectionStatus;\n }) => void | Promise<void>;\n onToolExecutionStart?: (event: {\n copilotkit: CopilotKitCore;\n toolCallId: string;\n agentId: string;\n toolName: string;\n args: unknown;\n }) => void | Promise<void>;\n onToolExecutionEnd?: (event: {\n copilotkit: CopilotKitCore;\n toolCallId: string;\n agentId: string;\n toolName: string;\n result: string;\n error?: string;\n }) => void | Promise<void>;\n onAgentsChanged?: (event: {\n copilotkit: CopilotKitCore;\n agents: Readonly<Record<string, AbstractAgent>>;\n }) => void | Promise<void>;\n /**\n * Fired when an agent run or connect begins. The `agent` may be a per-thread\n * clone that is not present in `core.agents`, so `onAgentsChanged` never fires\n * for it. Subscribers (e.g. the inspector) can use this to subscribe to the\n * running instance's AG-UI events.\n */\n onAgentRunStarted?: (event: {\n copilotkit: CopilotKitCore;\n agent: AbstractAgent;\n }) => void | Promise<void>;\n onContextChanged?: (event: {\n copilotkit: CopilotKitCore;\n context: Readonly<Record<string, Context>>;\n }) => void | Promise<void>;\n /**\n * Fired when the A2UI catalog component list changes (registration) or when\n * a component is enabled/disabled. Consumers (the provider, the inspector)\n * re-derive the filtered catalog from this event.\n */\n onCatalogComponentsChanged?: (event: {\n copilotkit: CopilotKitCore;\n catalogComponents: ReadonlyArray<CopilotKitCoreCatalogComponent>;\n }) => void | Promise<void>;\n onSuggestionsConfigChanged?: (event: {\n copilotkit: CopilotKitCore;\n suggestionsConfig: Readonly<Record<string, SuggestionsConfig>>;\n }) => void | Promise<void>;\n onSuggestionsChanged?: (event: {\n copilotkit: CopilotKitCore;\n agentId: string;\n suggestions: Suggestion[];\n }) => void | Promise<void>;\n onSuggestionsStartedLoading?: (event: {\n copilotkit: CopilotKitCore;\n agentId: string;\n }) => void | Promise<void>;\n onSuggestionsFinishedLoading?: (event: {\n copilotkit: CopilotKitCore;\n agentId: string;\n }) => void | Promise<void>;\n onPropertiesChanged?: (event: {\n copilotkit: CopilotKitCore;\n properties: Readonly<Record<string, unknown>>;\n }) => void | Promise<void>;\n onHeadersChanged?: (event: {\n copilotkit: CopilotKitCore;\n headers: Readonly<Record<string, string>>;\n }) => void | Promise<void>;\n onInspectorMetadataChanged?: (event: {\n copilotkit: CopilotKitCore;\n inspectorMetadata: InspectorMetadataV1 | undefined;\n }) => void | Promise<void>;\n onError?: (event: {\n copilotkit: CopilotKitCore;\n error: Error;\n code: CopilotKitCoreErrorCode;\n context: Record<string, any>;\n }) => void | Promise<void>;\n onThreadStoreRegistered?: (event: {\n copilotkit: CopilotKitCore;\n agentId: string;\n store: ɵThreadStore;\n }) => void | Promise<void>;\n /**\n * Fired when a thread store is removed from the registry, either by an\n * explicit `unregister()` call or by a `register()` call that replaces an\n * existing store for the same `agentId`.\n *\n * The previous store is delivered via `prevStore` so subscribers can tear\n * down state that depends on the concrete instance (e.g. cancel an active\n * subscription) without consulting the registry. By the time async\n * subscribers resume after an `await`, a replacement `register()` may have\n * already installed the new store under the same key, so calling\n * `registry.get(agentId)` inside this callback is unsafe and may return\n * the new store instead of the unregistered one.\n */\n onThreadStoreUnregistered?: (event: {\n copilotkit: CopilotKitCore;\n agentId: string;\n prevStore: ɵThreadStore;\n }) => void | Promise<void>;\n}\n\n// Subscription object returned by subscribe() and subscribeToAgentWithOptions()\nexport interface CopilotKitCoreSubscription {\n unsubscribe: () => void;\n}\n\n/**\n * The callback keys accepted by {@link CopilotKitCore.subscribeToAgentWithOptions}.\n * This tuple is the single source of truth — both the\n * `SubscribeToAgentSubscriber` type and the runtime `ALLOWED_KEYS` set\n * are derived from it, so they cannot desynchronise.\n */\nconst SUBSCRIBE_TO_AGENT_KEYS = [\n \"onMessagesChanged\",\n \"onStateChanged\",\n \"onRunInitialized\",\n \"onRunFinalized\",\n \"onRunFailed\",\n \"onRunErrorEvent\",\n] as const satisfies readonly (keyof AgentSubscriber)[];\n\n/**\n * Runtime allowlist derived from {@link SUBSCRIBE_TO_AGENT_KEYS}. Hoisted\n * to module scope so the Set is allocated once, not per-subscription.\n */\nconst ALLOWED_KEYS: ReadonlySet<(typeof SUBSCRIBE_TO_AGENT_KEYS)[number]> =\n new Set(SUBSCRIBE_TO_AGENT_KEYS);\n\n/**\n * The subset of `AgentSubscriber` callbacks accepted by\n * {@link CopilotKitCore.subscribeToAgentWithOptions}. Only the callbacks\n * listed in {@link SUBSCRIBE_TO_AGENT_KEYS} are supported:\n * `onMessagesChanged`, `onStateChanged`, and the four run lifecycle\n * callbacks (`onRunInitialized`, `onRunFinalized`, `onRunFailed`,\n * `onRunErrorEvent`).\n *\n * Two categories of `AgentSubscriber` members are excluded:\n *\n * - **AG-UI event handlers** (`onEvent`, `onToolCallStartEvent`, etc.)\n * return `AgentStateMutation` with `stopPropagation` — semantics that\n * the throttle and error-protection wrappers cannot safely mediate.\n *\n * - **Per-item notification callbacks** (`onNewMessage`, `onNewToolCall`)\n * return `void` and have no mutation concerns, but are excluded to keep\n * the surface area minimal — `onMessagesChanged` already covers the\n * same data at a coarser granularity, and throttling per-item callbacks\n * would have different semantic expectations.\n *\n * `onRunErrorEvent` is technically an AG-UI event handler (its return type\n * includes `stopPropagation`), but it is included here because all\n * framework consumers need it to reset `isRunning` on protocol-level\n * `RUN_ERROR` events — distinct from `onRunFailed` which handles local\n * exceptions like network errors. In practice, consumers return `void`\n * from this callback, so the `stopPropagation` semantics are unused.\n *\n * Note: the included lifecycle callbacks return\n * `Omit<AgentStateMutation, \"stopPropagation\">` (or full\n * `AgentStateMutation` in the case of `onRunErrorEvent`). On the error\n * path, `safeCall` discards those return values (see its inline\n * documentation).\n *\n * Use `agent.subscribe()` directly when event mutation or per-item\n * notification semantics are needed.\n */\nexport type SubscribeToAgentSubscriber = Pick<\n AgentSubscriber,\n (typeof SUBSCRIBE_TO_AGENT_KEYS)[number]\n>;\n\n/** Options for {@link CopilotKitCore.subscribeToAgentWithOptions}. */\nexport interface SubscribeToAgentOptions {\n /**\n * Throttle interval (ms) for `onMessagesChanged` / `onStateChanged`.\n * Non-negative finite number; `0` explicitly disables throttling.\n * Falls back to `defaultThrottleMs` when `undefined`.\n */\n throttleMs?: number;\n}\n\nexport enum CopilotKitCoreRuntimeConnectionStatus {\n Disconnected = \"disconnected\",\n Connected = \"connected\",\n Connecting = \"connecting\",\n Error = \"error\",\n}\n\n/**\n * Internal interface for delegate classes to access CopilotKitCore methods.\n * This provides type safety while allowing controlled access to private functionality.\n */\nexport interface CopilotKitCoreFriendsAccess {\n // Notification methods\n notifySubscribers(\n handler: (subscriber: CopilotKitCoreSubscriber) => void | Promise<void>,\n errorMessage: string,\n ): Promise<void>;\n\n emitError(params: {\n error: Error;\n code: CopilotKitCoreErrorCode;\n context?: Record<string, any>;\n }): Promise<void>;\n\n // Getters for internal state\n readonly headers: Readonly<Record<string, string>>;\n readonly credentials: RequestCredentials | undefined;\n readonly messageFilter: CopilotKitMessageFilter | undefined;\n readonly properties: Readonly<Record<string, unknown>>;\n readonly context: Readonly<Record<string, Context>>;\n readonly debug?: DebugConfig;\n\n // Internal methods\n buildFrontendTools(agentId?: string): import(\"@ag-ui/client\").Tool[];\n getContextForAgent(agentId?: string): Context[];\n getAgent(id: string): AbstractAgent | undefined;\n /**\n * Re-apply the current core headers to a single agent, merged on top of the\n * headers the agent was constructed with. The single source of truth for\n * header application; the run handler uses it so a run never clobbers\n * per-agent headers (see #5635).\n */\n applyHeadersToAgent(agent: AbstractAgent): void;\n\n // References to delegate subsystems\n readonly suggestionEngine: {\n clearSuggestions(agentId: string): void;\n reloadSuggestions(agentId: string): void;\n };\n\n /**\n * Called before each follow-up agent run (after tool execution).\n * See CopilotKitCore.waitForPendingFrameworkUpdates for details.\n */\n waitForPendingFrameworkUpdates(): Promise<void>;\n\n readonly stateManager: {\n markNextRunAsContinuation(\n agent: AbstractAgent,\n expectedRunId?: string,\n ): CopilotKitCoreContinuationHandoff;\n };\n}\n\n/**\n * Normalize a header map to the internal invariant: a `Record<string, string>`\n * with no `null`/`undefined` values. Entries whose value is `null`/`undefined`\n * are dropped (this is how a header is cleared). Shared by the constructor and\n * `setHeaders` so both write paths into `_headers` enforce the same invariant.\n */\nfunction normalizeHeaders(\n headers: Record<string, string | null | undefined>,\n): Record<string, string> {\n return Object.fromEntries(\n Object.entries(headers).filter(\n (entry): entry is [string, string] => entry[1] != null,\n ),\n );\n}\n\nexport class CopilotKitCore {\n private _headers: Record<string, string>;\n private _credentials?: RequestCredentials;\n private _messageFilter?: CopilotKitMessageFilter;\n private _properties: Record<string, unknown>;\n private _defaultThrottleMs?: number;\n private _debug?: DebugConfig;\n\n private subscribers: Set<CopilotKitCoreSubscriber> = new Set();\n\n // Delegate classes\n private agentRegistry: AgentRegistry;\n private contextStore: ContextStore;\n private suggestionEngine: SuggestionEngine;\n private runHandler: RunHandler;\n private stateManager: StateManager;\n private threadStoreRegistry: ThreadStoreRegistry;\n /**\n * The single core-owned memory store, created lazily on first\n * `getMemoryStore()` and kept user-scoped for the lifetime of the core.\n * Its runtime context is wired by the core itself (see `syncMemoryContext`),\n * so callers never register or look it up by `agentId`.\n */\n private _memoryStore?: ɵMemoryStore;\n /**\n * Tracks the agent IDs from the most recent `onAgentsChanged` notification.\n * Used to gate thread-store auto-unregister so the FIRST empty-agents\n * notification (before published agents are merged in) does not rip out a\n * store that was registered prior to that initial notification.\n */\n private previousAgentIds: Set<string> = new Set();\n\n constructor({\n runtimeUrl,\n runtimeTransport = \"auto\",\n deferInitialConnection = false,\n headers = {},\n credentials,\n messageFilter,\n properties = {},\n agents__unsafe_dev_only = {},\n tools = [],\n suggestionsConfig = [],\n debug,\n }: CopilotKitCoreConfig) {\n this._headers = normalizeHeaders(headers);\n this._credentials = credentials;\n this._messageFilter = messageFilter;\n this._properties = properties;\n this._debug = debug;\n\n // Initialize delegate classes\n this.agentRegistry = new AgentRegistry(this);\n this.contextStore = new ContextStore(this);\n this.suggestionEngine = new SuggestionEngine(this);\n this.runHandler = new RunHandler(this);\n this.stateManager = new StateManager(this);\n this.threadStoreRegistry = new ThreadStoreRegistry(this);\n\n // Initialize each subsystem\n this.agentRegistry.initialize(agents__unsafe_dev_only);\n this.runHandler.initialize(tools);\n this.suggestionEngine.initialize(suggestionsConfig);\n this.stateManager.initialize();\n\n this.agentRegistry.setRuntimeTransport(runtimeTransport);\n this.agentRegistry.setRuntimeUrl(runtimeUrl, {\n deferConnection: deferInitialConnection,\n });\n\n // Seed the previous-agents snapshot from the constructor-supplied agents.\n // `agentRegistry.initialize` does not emit `onAgentsChanged`, so the\n // subscriber below would otherwise see its first non-empty notification\n // as an \"addition\" relative to an empty baseline — and a later removal\n // of those same agents would NOT trigger the auto-unregister branch\n // because the guard would think the agentId was never previously\n // present. Seeding the set here keeps the guard honest.\n this.previousAgentIds = new Set(Object.keys(agents__unsafe_dev_only));\n\n // Subscribe to agent changes to track state for new agents\n this.subscribe({\n // Re-sync the memory store's runtime context whenever the runtime\n // connection status changes. The `/info` fetch sets the connection\n // status and `intelligence` together before firing this notification,\n // so this single hook covers both connection and intelligence changes.\n // Guarded so we never instantiate the store just to sync it.\n onRuntimeConnectionStatusChanged: () => {\n if (this._memoryStore) this.syncMemoryContext();\n },\n onAgentsChanged: ({ agents }) => {\n Object.values(agents).forEach((agent) => {\n if (agent.agentId) {\n this.stateManager.subscribeToAgent(agent);\n }\n });\n\n // Unregister thread stores for agents that have been removed.\n //\n // Critically, only unregister an agentId that was present in the\n // PREVIOUS agents snapshot AND is missing from the new one. Without\n // the \"previously had\" guard, the FIRST `onAgentsChanged({ agents: {} })`\n // delivered to a freshly-published core would tear out a thread store\n // that a consumer (e.g. useThreads) just registered — `core.agents`\n // is asynchronously populated and the empty-map notification fires\n // before the published agents are merged in.\n const currentAgentIds = new Set(Object.keys(agents));\n // Each iteration is wrapped so a throw on one id does not stall\n // cleanup for the rest of the set. Both registries' unregister\n // paths are idempotent, so re-attempts on the next\n // onAgentsChanged are safe.\n for (const agentId of Object.keys(this.threadStoreRegistry.getAll())) {\n if (\n this.previousAgentIds.has(agentId) &&\n !currentAgentIds.has(agentId)\n ) {\n try {\n this.threadStoreRegistry.unregister(agentId);\n } catch (err) {\n console.error(\n `CopilotKitCore.onAgentsChanged: threadStoreRegistry.unregister failed for \"${agentId}\":`,\n err,\n );\n }\n }\n }\n\n // Symmetric cleanup for state-manager subscriptions: any agentId\n // that disappeared from the registry (e.g. via `unregister()` from\n // a registerProxiedAgent caller) should release its StateManager\n // subscription. Without this, the subscription leaks — events from\n // a still-running observable on the removed agent would continue\n // to populate stateByRun/messageToRun for the dead id.\n for (const agentId of this.previousAgentIds) {\n if (!currentAgentIds.has(agentId)) {\n try {\n this.stateManager.unsubscribeFromAgent(agentId);\n } catch (err) {\n console.error(\n `CopilotKitCore.onAgentsChanged: stateManager.unsubscribeFromAgent failed for \"${agentId}\":`,\n err,\n );\n }\n }\n }\n\n this.previousAgentIds = currentAgentIds;\n },\n });\n }\n\n /**\n * Internal method used by delegate classes and subclasses to notify subscribers\n */\n protected async notifySubscribers(\n handler: (subscriber: CopilotKitCoreSubscriber) => void | Promise<void>,\n errorMessage: string,\n ): Promise<void> {\n await Promise.all(\n Array.from(this.subscribers).map(async (subscriber) => {\n try {\n await handler(subscriber);\n } catch (error) {\n console.error(errorMessage, error);\n }\n }),\n );\n }\n\n /**\n * Internal method used by delegate classes to emit errors\n */\n private async emitError({\n error,\n code,\n context = {},\n }: {\n error: Error;\n code: CopilotKitCoreErrorCode;\n context?: Record<string, any>;\n }): Promise<void> {\n await this.notifySubscribers(\n (subscriber) =>\n subscriber.onError?.({\n copilotkit: this,\n error,\n code,\n context,\n }),\n \"Subscriber onError error:\",\n );\n }\n\n /**\n * Log a message to the console and emit an error to subscribers.\n * Catches failures from `emitError` itself to prevent unhandled rejections.\n */\n private logAndEmitError(\n message: string,\n params: {\n error: Error;\n code: CopilotKitCoreErrorCode;\n context?: Record<string, any>;\n },\n logLevel: \"error\" | \"warn\" = \"error\",\n ): void {\n console[logLevel](message, params.error);\n this.emitError(params).catch((emitErr: unknown) => {\n console.error(message + \" — emitError itself failed:\", emitErr);\n });\n }\n\n /**\n * Snapshot accessors\n */\n get context(): Readonly<Record<string, ScopedContext>> {\n return this.contextStore.context;\n }\n\n get agents(): Readonly<Record<string, AbstractAgent>> {\n return this.agentRegistry.agents;\n }\n\n get tools(): Readonly<FrontendTool<any>[]> {\n return this.runHandler.tools;\n }\n\n get catalogComponents(): ReadonlyArray<CopilotKitCoreCatalogComponent> {\n return this.runHandler.catalogComponents;\n }\n\n get runtimeUrl(): string | undefined {\n return this.agentRegistry.runtimeUrl;\n }\n\n setRuntimeUrl(runtimeUrl: string | undefined): void {\n this.agentRegistry.setRuntimeUrl(runtimeUrl);\n }\n\n /**\n * Start the runtime `/info` connection if it has not been started yet.\n *\n * Intended to be driven from a host's commit-phase effect when the core was\n * constructed with {@link CopilotKitCoreConfig.deferInitialConnection}. Safe\n * to call repeatedly — it is a no-op once a connection is in progress or\n * settled, so a double-invoked mount effect (React StrictMode) collapses to a\n * single request. See #5801.\n */\n connect(): void {\n this.agentRegistry.connectRuntime();\n }\n\n get runtimeTransport(): CopilotRuntimeTransport {\n return this.agentRegistry.runtimeTransport;\n }\n\n setRuntimeTransport(runtimeTransport: CopilotRuntimeTransport): void {\n this.agentRegistry.setRuntimeTransport(runtimeTransport);\n }\n\n get runtimeVersion(): string | undefined {\n return this.agentRegistry.runtimeVersion;\n }\n\n get headers(): Readonly<Record<string, string>> {\n return this._headers;\n }\n\n get credentials(): RequestCredentials | undefined {\n return this._credentials;\n }\n\n get messageFilter(): CopilotKitMessageFilter | undefined {\n return this._messageFilter;\n }\n\n get properties(): Readonly<Record<string, unknown>> {\n return this._properties;\n }\n\n /**\n * Default throttle interval (ms) used by `subscribeToAgentWithOptions()`\n * when the caller does not specify an explicit `throttleMs`.\n * `undefined` means no default is configured; `0` means no throttling.\n */\n get defaultThrottleMs(): number | undefined {\n return this._defaultThrottleMs;\n }\n\n /**\n * Set the default throttle interval (ms) for `subscribeToAgentWithOptions()`.\n *\n * Accepts a non-negative finite number or `undefined` (to clear the\n * default). Invalid values (NaN, Infinity, negative) are logged as\n * errors and ignored — the previous valid value is preserved.\n */\n setDefaultThrottleMs(value: number | undefined): void {\n if (value !== undefined && (!Number.isFinite(value) || value < 0)) {\n this.logAndEmitError(\n `CopilotKitCore.setDefaultThrottleMs: value must be a non-negative finite number or undefined, ` +\n `got ${value}. Keeping current value (${this._defaultThrottleMs}).`,\n {\n error: new Error(\n `setDefaultThrottleMs: invalid value (${value}), keeping current value (${this._defaultThrottleMs})`,\n ),\n code: CopilotKitCoreErrorCode.SUBSCRIBER_CALLBACK_FAILED,\n context: { value, currentValue: this._defaultThrottleMs },\n },\n );\n return;\n }\n this._defaultThrottleMs = value;\n }\n\n get debug(): DebugConfig | undefined {\n return this._debug;\n }\n\n setDebug(debug: DebugConfig | undefined): void {\n this._debug = debug;\n }\n\n get runtimeConnectionStatus(): CopilotKitCoreRuntimeConnectionStatus {\n return this.agentRegistry.runtimeConnectionStatus;\n }\n\n get ɵruntimeFetch(): typeof fetch {\n return this.agentRegistry.createRuntimeFetch();\n }\n\n get audioFileTranscriptionEnabled(): boolean {\n return this.agentRegistry.audioFileTranscriptionEnabled;\n }\n\n get runtimeMode(): RuntimeMode {\n return this.agentRegistry.runtimeMode;\n }\n\n get intelligence(): IntelligenceRuntimeInfo | undefined {\n return this.agentRegistry.intelligence;\n }\n\n get threadEndpoints(): ThreadEndpointRuntimeInfo | undefined {\n return this.agentRegistry.threadEndpoints;\n }\n\n get suggestions(): boolean | undefined {\n return this.agentRegistry.suggestions;\n }\n\n /** Whether the connected Runtime exposes debug-authorized Learning data. */\n get inspectorLearning(): boolean {\n return this.agentRegistry.inspectorLearning;\n }\n\n /** Trusted, optional metadata advertised by the connected runtime. */\n get inspectorMetadata(): InspectorMetadataV1 | undefined {\n return this.agentRegistry.inspectorMetadata;\n }\n\n /** Refresh trusted inspector metadata without reconnecting runtime agents. */\n async refreshInspectorMetadata(): Promise<void> {\n await this.agentRegistry.refreshInspectorMetadata();\n }\n\n get a2uiEnabled(): boolean {\n return this.agentRegistry.a2uiEnabled;\n }\n\n /**\n * Agent ids the runtime applies A2UI to. `undefined` means A2UI applies to\n * every agent (or is disabled — check `a2uiEnabled`).\n */\n get a2uiAgents(): string[] | undefined {\n return this.agentRegistry.a2uiAgents;\n }\n\n get openGenerativeUIEnabled(): boolean {\n return this.agentRegistry.openGenerativeUIEnabled;\n }\n\n get licenseStatus(): RuntimeLicenseStatus | undefined {\n return this.agentRegistry.licenseStatus;\n }\n\n /** Structured Runtime entitlement authority advertised by `/info`. */\n get runtimeEntitlements(): RuntimeEntitlementResponse | undefined {\n return this.agentRegistry.runtimeEntitlements;\n }\n\n /** Whether Core still has a bounded Runtime entitlement retry to settle. */\n get runtimeEntitlementRetryPending(): boolean {\n return this.agentRegistry.runtimeEntitlementRetryPending;\n }\n\n get telemetryDisabled(): boolean {\n return this.agentRegistry.telemetryDisabled;\n }\n\n /**\n * Configuration updates\n */\n /**\n * Replace the headers sent with every runtime request.\n *\n * This is an overwrite, not a merge — the supplied object becomes the\n * complete header set. Entries whose value is `null` or `undefined` are\n * dropped, which is how you clear a header (e.g. removing `Authorization`\n * on logout) without leaving an empty-string value behind:\n *\n * ```ts\n * copilotkit.setHeaders({\n * ...copilotkit.headers,\n * Authorization: token ? `Bearer ${token}` : null,\n * });\n * ```\n *\n * The resulting header set is also re-applied to every agent in the registry\n * and `onHeadersChanged` subscribers are notified. These headers are merged\n * ON TOP of the headers each `HttpAgent` was constructed with, so per-agent\n * headers (e.g. an `Authorization` for a self-hosted backend) are preserved;\n * on a key conflict the core-level value wins.\n *\n * Because the agent's construction-time headers form the merge baseline, this\n * method can override a per-agent header but cannot REMOVE one: clearing a\n * core key here only drops the core-level override, after which the agent's\n * own value (if any) re-surfaces. To change a header an agent was constructed\n * with, set it at the provider/core level instead of on the agent, or update\n * it on the agent directly. The clear-on-logout pattern above is for\n * core-level headers.\n */\n setHeaders(headers: Record<string, string | null | undefined>): void {\n this._headers = normalizeHeaders(headers);\n if (this._memoryStore) this.syncMemoryContext();\n this.agentRegistry.applyHeadersToAgents(\n this.agentRegistry.agents as Record<string, AbstractAgent>,\n );\n this.agentRegistry.handleHeadersChanged();\n void this.notifySubscribers(\n (subscriber) =>\n subscriber.onHeadersChanged?.({\n copilotkit: this,\n headers: this.headers,\n }),\n \"Subscriber onHeadersChanged error:\",\n );\n }\n\n setCredentials(credentials: RequestCredentials | undefined): void {\n this._credentials = credentials;\n this.agentRegistry.applyCredentialsToAgents(\n this.agentRegistry.agents as Record<string, AbstractAgent>,\n );\n this.agentRegistry.handleCredentialsChanged();\n }\n\n /**\n * Replace the message filter applied to every runtime agent.\n *\n * Applies to agents already discovered as well as ones discovered later, so\n * a filter set before `/info` lands is not lost. Pass `undefined` to go back\n * to sending the full thread.\n */\n setMessageFilter(messageFilter: CopilotKitMessageFilter | undefined): void {\n this._messageFilter = messageFilter;\n this.agentRegistry.applyMessageFilterToAgents(\n this.agentRegistry.agents as Record<string, AbstractAgent>,\n );\n }\n\n setProperties(properties: Record<string, unknown>): void {\n this._properties = properties;\n void this.notifySubscribers(\n (subscriber) =>\n subscriber.onPropertiesChanged?.({\n copilotkit: this,\n properties: this.properties,\n }),\n \"Subscriber onPropertiesChanged error:\",\n );\n }\n\n /**\n * Agent management (delegated to AgentRegistry)\n */\n setAgents__unsafe_dev_only(agents: Record<string, AbstractAgent>): void {\n this.agentRegistry.setAgents__unsafe_dev_only(agents);\n }\n\n addAgent__unsafe_dev_only(params: CopilotKitCoreAddAgentParams): void {\n this.agentRegistry.addAgent__unsafe_dev_only(params);\n }\n\n removeAgent__unsafe_dev_only(id: string): void {\n this.agentRegistry.removeAgent__unsafe_dev_only(id);\n }\n\n /**\n * Register a proxied agent against an existing runtime agent. The proxy is\n * exposed under `agentId` (local registry id) and routes outbound runtime\n * requests to `runtimeAgentId`. Throws if `agentId` is already taken.\n *\n * Returns the minted proxy and an `unregister` handle for cleanup.\n *\n * Use this to mount multiple frontend agents against a single runtime\n * agent (e.g. one per chat window) without implicit per-thread cloning.\n *\n * @example\n * const { agent, unregister } = copilotkit.registerProxiedAgent({\n * agentId: \"chat-1\",\n * runtimeAgentId: \"default\",\n * });\n * // ... <CopilotChat agentId=\"chat-1\" />\n * // on cleanup:\n * unregister();\n */\n registerProxiedAgent(\n params: CopilotKitCoreRegisterProxiedAgentParams,\n ): CopilotKitCoreRegisterProxiedAgentResult {\n return this.agentRegistry.registerProxiedAgent(params);\n }\n\n getAgent(id: string): AbstractAgent | undefined {\n return this.agentRegistry.getAgent(id);\n }\n\n /**\n * Re-apply the current headers to a single agent (delegated to\n * AgentRegistry). Core headers are merged on top of the agent's own\n * construction-time headers rather than replacing them, so headers\n * configured directly on an `HttpAgent` (e.g. an `Authorization` for a\n * self-hosted backend) survive header updates instead of being silently\n * dropped (see #5635). On a key conflict the core-level value wins.\n *\n * The merge baseline is the agent's headers as captured the first time the\n * agent is applied (at registration), so the way to change headers\n * afterwards is `setHeaders` (which re-applies to every agent), not mutating\n * `agent.headers` directly — a direct mutation is overwritten on the next\n * re-apply.\n */\n applyHeadersToAgent(agent: AbstractAgent): void {\n this.agentRegistry.applyHeadersToAgent(agent);\n }\n\n /**\n * Context management (delegated to ContextStore).\n * Pass `agentIds` to restrict the entry to runs of specific agents;\n * omit it for context every agent should receive.\n */\n addContext(context: ScopedContext): string {\n return this.contextStore.addContext(context);\n }\n\n removeContext(id: string): void {\n this.contextStore.removeContext(id);\n }\n\n /**\n * Build the context array for a run of the given agent, dropping entries\n * scoped to other agents and stripping the scoping metadata.\n */\n getContextForAgent(agentId?: string): Context[] {\n return this.contextStore.getContextForAgent(agentId);\n }\n\n /**\n * Thread store registry (delegated to ThreadStoreRegistry)\n */\n registerThreadStore(agentId: string, store: ɵThreadStore): void {\n this.threadStoreRegistry.register(agentId, store);\n }\n\n unregisterThreadStore(agentId: string): void {\n this.threadStoreRegistry.unregister(agentId);\n }\n\n getThreadStore(agentId: string): ɵThreadStore | undefined {\n return this.threadStoreRegistry.get(agentId);\n }\n\n getThreadStores(): Readonly<Record<string, ɵThreadStore>> {\n return this.threadStoreRegistry.getAll();\n }\n\n /**\n * Returns the single core-owned, user-scoped memory store, creating and\n * starting it on first access. Unlike thread stores, memory is not scoped per\n * agent: there is exactly one store whose runtime context the core wires\n * itself (see `syncMemoryContext`), so consumers (e.g. a `useMemories`\n * binding) just read this store rather than registering one.\n */\n getMemoryStore(): ɵMemoryStore {\n return this.ensureMemoryStore();\n }\n\n /**\n * Lazily creates, starts, and context-syncs the core-owned memory store on\n * first access, then returns it. Subsequent calls return the existing store.\n * The store uses the Core Runtime fetch so REST and single-route transports\n * share the same resource behavior. Its Runtime context is synced at once.\n */\n private ensureMemoryStore(): ɵMemoryStore {\n if (!this._memoryStore) {\n this._memoryStore = ɵcreateMemoryStore({\n fetch: this.ɵruntimeFetch,\n });\n this._memoryStore.start();\n this.syncMemoryContext();\n }\n return this._memoryStore;\n }\n\n /**\n * Pushes the current runtime wiring into the memory store. When the runtime\n * is connected and both the intelligence WebSocket URL and runtime URL are\n * available, the store receives a context (runtime URL, WebSocket URL, and a\n * copy of the current headers); otherwise its context is cleared. No-op when\n * the store has not been created yet.\n */\n private syncMemoryContext(): void {\n if (!this._memoryStore) return;\n if (\n this.runtimeConnectionStatus ===\n CopilotKitCoreRuntimeConnectionStatus.Connected &&\n this.intelligence?.wsUrl &&\n this.runtimeUrl\n ) {\n this._memoryStore.setContext({\n runtimeUrl: this.runtimeUrl,\n wsUrl: this.intelligence.wsUrl,\n headers: { ...this.headers },\n });\n } else {\n this._memoryStore.setContext(null);\n }\n }\n\n /**\n * Suggestions management (delegated to SuggestionEngine)\n */\n addSuggestionsConfig(config: SuggestionsConfig): string {\n return this.suggestionEngine.addSuggestionsConfig(config);\n }\n\n removeSuggestionsConfig(id: string): void {\n this.suggestionEngine.removeSuggestionsConfig(id);\n }\n\n reloadSuggestions(agentId: string): void {\n this.suggestionEngine.reloadSuggestions(agentId);\n }\n\n clearSuggestions(agentId: string): void {\n this.suggestionEngine.clearSuggestions(agentId);\n }\n\n getSuggestions(agentId: string): CopilotKitCoreGetSuggestionsResult {\n return this.suggestionEngine.getSuggestions(agentId);\n }\n\n /**\n * Tool management (delegated to RunHandler)\n */\n addTool<T extends Record<string, unknown> = Record<string, unknown>>(\n tool: FrontendTool<T>,\n ): void {\n this.runHandler.addTool(tool);\n }\n\n removeTool(id: string, agentId?: string): void {\n this.runHandler.removeTool(id, agentId);\n }\n\n getTool(params: CopilotKitCoreGetToolParams): FrontendTool<any> | undefined {\n return this.runHandler.getTool(params);\n }\n\n setTools(tools: FrontendTool<any>[]): void {\n this.runHandler.setTools(tools);\n }\n\n /**\n * Enable/disable a registered frontend tool at runtime without unregistering\n * it (Inspector \"Capabilities\" tool). A disabled tool is omitted from the\n * tool list sent to the agent on the next run. The override is keyed by name\n * (+ optional agentId) and survives the tool being re-registered.\n */\n setToolEnabled(name: string, enabled: boolean, agentId?: string): void {\n this.runHandler.setToolEnabled(name, enabled, agentId);\n }\n\n /** Whether a registered tool is currently enabled (defaults true). */\n isToolEnabled(name: string, agentId?: string): boolean {\n return this.runHandler.isToolEnabled(name, agentId);\n }\n\n /**\n * A2UI catalog component management (delegated to RunHandler).\n * Registers the full component list and controls per-component enablement.\n */\n setCatalogComponents(components: CopilotKitCoreCatalogComponent[]): void {\n this.runHandler.setCatalogComponents(components);\n void this.notifySubscribers(\n (subscriber) =>\n subscriber.onCatalogComponentsChanged?.({\n copilotkit: this,\n catalogComponents: this.runHandler.catalogComponents,\n }),\n \"Subscriber onCatalogComponentsChanged error:\",\n );\n }\n\n setCatalogComponentEnabled(name: string, enabled: boolean): void {\n this.runHandler.setCatalogComponentEnabled(name, enabled);\n void this.notifySubscribers(\n (subscriber) =>\n subscriber.onCatalogComponentsChanged?.({\n copilotkit: this,\n catalogComponents: this.runHandler.catalogComponents,\n }),\n \"Subscriber onCatalogComponentsChanged error:\",\n );\n }\n\n isCatalogComponentEnabled(name: string): boolean {\n return this.runHandler.isCatalogComponentEnabled(name);\n }\n\n /**\n * Subscription lifecycle\n */\n subscribe(subscriber: CopilotKitCoreSubscriber): CopilotKitCoreSubscription {\n this.subscribers.add(subscriber);\n\n // Return subscription with unsubscribe method\n return {\n unsubscribe: () => {\n this.subscribers.delete(subscriber);\n },\n };\n }\n\n /**\n * Subscribe to an agent's notification and lifecycle events with\n * optional configuration (e.g. throttling).\n *\n * Wraps every callback with error protection (`safeCall`) and applies\n * the options before delegating to `agent.subscribe()`.\n *\n * See {@link SubscribeToAgentSubscriber} for the accepted callback subset\n * and the rationale for excluding AG-UI event handlers.\n */\n subscribeToAgentWithOptions(\n agent: AbstractAgent,\n subscriber: SubscribeToAgentSubscriber,\n options?: SubscribeToAgentOptions,\n ): CopilotKitCoreSubscription {\n const resolved = options?.throttleMs ?? this._defaultThrottleMs ?? 0;\n\n let effectiveMs = 0;\n if (!Number.isFinite(resolved) || resolved < 0) {\n const source =\n options?.throttleMs !== undefined ? \"throttleMs\" : \"defaultThrottleMs\";\n this.logAndEmitError(\n `CopilotKitCore.subscribeToAgentWithOptions: ${source} must be a non-negative finite number, ` +\n `got ${resolved}. Falling back to unthrottled.`,\n {\n error: new Error(\n `subscribeToAgentWithOptions: invalid ${source} (${resolved}), falling back to unthrottled`,\n ),\n code: CopilotKitCoreErrorCode.SUBSCRIBER_CALLBACK_FAILED,\n context: { agentId: agent.agentId, source, value: resolved },\n },\n );\n } else {\n effectiveMs = resolved;\n }\n\n const agentLabel = agent.agentId || \"(unknown agent)\";\n\n // Wraps a callback so that synchronous throws and async rejections are\n // caught, logged, and emitted — preventing one failing callback from\n // corrupting the agent's notification loop.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const safeCall = <F extends (...args: any[]) => any>(\n label: string,\n fn: F,\n ...args: Parameters<F>\n ): any => {\n const reportError = (err: unknown, verb: string) => {\n this.logAndEmitError(\n `CopilotKitCore.subscribeToAgentWithOptions[${agentLabel}]: ${label} callback ${verb}:`,\n {\n error: err instanceof Error ? err : new Error(String(err)),\n code: CopilotKitCoreErrorCode.SUBSCRIBER_CALLBACK_FAILED,\n context: { agentId: agent.agentId, callback: label },\n },\n );\n };\n try {\n const result = fn(...args);\n if (result instanceof Promise) {\n return result.catch((err: unknown) => {\n reportError(err, \"rejected\");\n });\n }\n return result;\n } catch (err) {\n reportError(err, \"threw\");\n }\n };\n\n const guardAll = (\n sub: SubscribeToAgentSubscriber,\n ): SubscribeToAgentSubscriber => {\n const guarded: SubscribeToAgentSubscriber = {};\n if (sub.onMessagesChanged) {\n const fn = sub.onMessagesChanged;\n guarded.onMessagesChanged = (params) =>\n safeCall(\"onMessagesChanged\", fn, params);\n }\n if (sub.onStateChanged) {\n const fn = sub.onStateChanged;\n guarded.onStateChanged = (params) =>\n safeCall(\"onStateChanged\", fn, params);\n }\n if (sub.onRunInitialized) {\n const fn = sub.onRunInitialized;\n guarded.onRunInitialized = (params) =>\n safeCall(\"onRunInitialized\", fn, params);\n }\n if (sub.onRunFinalized) {\n const fn = sub.onRunFinalized;\n guarded.onRunFinalized = (params) =>\n safeCall(\"onRunFinalized\", fn, params);\n }\n if (sub.onRunFailed) {\n const fn = sub.onRunFailed;\n guarded.onRunFailed = (params) => safeCall(\"onRunFailed\", fn, params);\n }\n if (sub.onRunErrorEvent) {\n const fn = sub.onRunErrorEvent;\n guarded.onRunErrorEvent = (params) =>\n safeCall(\"onRunErrorEvent\", fn, params);\n }\n return guarded;\n };\n\n // Warn about unsupported keys so JS / `as any` consumers get diagnostics.\n for (const key of Object.keys(subscriber)) {\n if (\n typeof (subscriber as Record<string, unknown>)[key] === \"function\" &&\n !(ALLOWED_KEYS as ReadonlySet<string>).has(key)\n ) {\n const message =\n `CopilotKitCore.subscribeToAgentWithOptions[${agentLabel}]: callback \"${key}\" is not supported ` +\n `and was dropped. Supported callbacks: ${Array.from(ALLOWED_KEYS).join(\", \")}. ` +\n `Use agent.subscribe() directly for event handlers and per-item notifications.`;\n this.logAndEmitError(\n message,\n {\n error: new Error(message),\n code: CopilotKitCoreErrorCode.SUBSCRIBER_CALLBACK_FAILED,\n context: { agentId: agent.agentId, droppedCallback: key },\n },\n \"warn\",\n );\n }\n }\n\n // No throttle — guard callbacks and subscribe directly.\n if (effectiveMs <= 0) {\n const subscription = agent.subscribe(guardAll(subscriber));\n return { unsubscribe: () => subscription.unsubscribe() };\n }\n\n // Throttled path: lifecycle callbacks fire immediately; onMessagesChanged\n // and onStateChanged share a single Throttler that flushes the latest\n // params for both channels.\n let active = true;\n let latestMessagesParams:\n | Parameters<\n NonNullable<SubscribeToAgentSubscriber[\"onMessagesChanged\"]>\n >[0]\n | null = null;\n let latestStateParams:\n | Parameters<NonNullable<SubscribeToAgentSubscriber[\"onStateChanged\"]>>[0]\n | null = null;\n\n const flushPending = () => {\n if (active && subscriber.onMessagesChanged && latestMessagesParams) {\n const params = latestMessagesParams;\n latestMessagesParams = null;\n safeCall(\"onMessagesChanged\", subscriber.onMessagesChanged, params);\n }\n if (active && subscriber.onStateChanged && latestStateParams) {\n const params = latestStateParams;\n latestStateParams = null;\n safeCall(\"onStateChanged\", subscriber.onStateChanged, params);\n }\n };\n\n const throttler = new Throttler(flushPending, {\n wait: effectiveMs,\n leading: true,\n trailing: true,\n });\n\n // Lifecycle callbacks are guarded but never throttled.\n const lifecycleOnly: SubscribeToAgentSubscriber = {};\n if (subscriber.onRunInitialized)\n lifecycleOnly.onRunInitialized = subscriber.onRunInitialized;\n if (subscriber.onRunFinalized)\n lifecycleOnly.onRunFinalized = subscriber.onRunFinalized;\n if (subscriber.onRunFailed)\n lifecycleOnly.onRunFailed = subscriber.onRunFailed;\n if (subscriber.onRunErrorEvent)\n lifecycleOnly.onRunErrorEvent = subscriber.onRunErrorEvent;\n\n const wrappedSubscriber: SubscribeToAgentSubscriber =\n guardAll(lifecycleOnly);\n\n if (subscriber.onMessagesChanged) {\n wrappedSubscriber.onMessagesChanged = (params) => {\n latestMessagesParams = params;\n throttler.maybeExecute();\n };\n }\n\n if (subscriber.onStateChanged) {\n wrappedSubscriber.onStateChanged = (params) => {\n latestStateParams = params;\n throttler.maybeExecute();\n };\n }\n\n const subscription = agent.subscribe(wrappedSubscriber);\n\n return {\n unsubscribe: () => {\n active = false;\n throttler.cancel();\n subscription.unsubscribe();\n },\n };\n }\n\n /**\n * Agent connectivity (delegated to RunHandler)\n */\n async connectAgent(\n params: CopilotKitCoreConnectAgentParams,\n ): Promise<import(\"@ag-ui/client\").RunAgentResult> {\n return this.runHandler.connectAgent(params);\n }\n\n stopAgent(params: CopilotKitCoreStopAgentParams): void {\n this.runHandler.abortCurrentRun(params.agent);\n params.agent.abortRun();\n }\n\n async runAgent(\n params: CopilotKitCoreRunAgentParams,\n ): Promise<import(\"@ag-ui/client\").RunAgentResult> {\n return this.runHandler.runAgent(params);\n }\n\n /**\n * Programmatically execute a registered frontend tool without going through an LLM turn.\n * The handler runs, render components show up in the UI, and both the tool call and\n * result messages are added to `agent.messages`.\n */\n async runTool(\n params: CopilotKitCoreRunToolParams,\n ): Promise<CopilotKitCoreRunToolResult> {\n return this.runHandler.runTool(params);\n }\n\n /**\n * State management (delegated to StateManager)\n */\n getStateByRun(\n agentId: string,\n threadId: string,\n runId: string,\n ): State | undefined {\n return this.stateManager.getStateByRun(agentId, threadId, runId);\n }\n\n getRunIdForMessage(\n agentId: string,\n threadId: string,\n messageId: string,\n ): string | undefined {\n return this.stateManager.getRunIdForMessage(agentId, threadId, messageId);\n }\n\n getRawEventForMessage(\n agentId: string,\n threadId: string,\n messageId: string,\n ): unknown {\n return this.stateManager.getRawEventForMessage(\n agentId,\n threadId,\n messageId,\n );\n }\n\n getRunIdsForThread(agentId: string, threadId: string): string[] {\n return this.stateManager.getRunIdsForThread(agentId, threadId);\n }\n\n /**\n * Internal method used by RunHandler to build frontend tools\n */\n private buildFrontendTools(agentId?: string): import(\"@ag-ui/client\").Tool[] {\n return this.runHandler.buildFrontendTools(agentId);\n }\n\n /**\n * Called before each follow-up agent run (after tool execution).\n *\n * When a frontend tool handler calls framework state setters (e.g. React's\n * setState), those updates are batched and deferred — they do not take effect\n * until the framework's scheduler runs (React uses MessageChannel).\n * useAgentContext registers context via useLayoutEffect, which runs\n * synchronously after React commits that deferred batch.\n *\n * Without yielding here, the follow-up runAgent reads the context store\n * synchronously while the deferred updates are still pending, producing stale\n * context for the next agent turn.\n *\n * Override in framework-specific subclasses to yield to the framework\n * scheduler before the follow-up run. The base implementation is a no-op\n * because non-React environments have no deferred state to flush.\n */\n async waitForPendingFrameworkUpdates(): Promise<void> {}\n}\n","import type { AbstractAgent, ToolCall } from \"@ag-ui/client\";\nimport type {\n InspectorMetadataV1,\n IntelligenceRuntimeInfo,\n RuntimeMode,\n RuntimeLicenseStatus,\n ThreadEndpointRuntimeInfo,\n} from \"@copilotkit/shared\";\nimport type { StandardSchemaV1 } from \"@copilotkit/shared\";\n\n/**\n * Status of a tool call execution\n */\nexport enum ToolCallStatus {\n InProgress = \"inProgress\",\n Executing = \"executing\",\n Complete = \"complete\",\n}\n\nexport type CopilotRuntimeTransport = \"rest\" | \"single\" | \"auto\";\nexport type {\n InspectorMetadataV1,\n RuntimeMode,\n IntelligenceRuntimeInfo,\n RuntimeLicenseStatus,\n ThreadEndpointRuntimeInfo,\n};\n\n/**\n * Context passed to a frontend tool handler\n */\nexport type FrontendToolHandlerContext = {\n toolCall: ToolCall;\n /**\n * The agent that invoked the tool. Absent when the tool is invoked through\n * the WebMCP browser API (`document.modelContext`), which has no agent.\n */\n agent?: AbstractAgent;\n /** Aborted when `stopAgent()` is called. Handlers can check `signal.aborted`\n * or pass the signal to fetch/setTimeout to cooperatively cancel. */\n signal?: AbortSignal;\n};\n\n/**\n * Annotations for a WebMCP tool, passed through to\n * `document.modelContext.registerTool`. Mirrors the WebMCP spec's tool\n * annotations. These are hints for browser agents only — they do not enforce\n * any policy on their own.\n */\nexport type WebMCPToolAnnotations = {\n /**\n * Hint that the tool does not modify state. Defaults to false.\n * Set it for read-only tools (search, status lookup, ...).\n */\n readOnlyHint?: boolean;\n /**\n * Hint that the tool's output may contain untrusted content\n * (e.g. user-generated or external content). Defaults to false.\n */\n untrustedContentHint?: boolean;\n};\n\n/**\n * WebMCP registration options for a frontend tool.\n */\nexport type WebMCPToolConfig = {\n /** Hints that tell browser agents how the tool behaves. */\n annotations?: WebMCPToolAnnotations;\n};\n\nexport type FrontendTool<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = {\n /**\n * @internal Classifies local execution. Omitted means an ordinary frontend\n * tool. Only human-in-the-loop handlers may be restored from history replay.\n * This field is not sent to the agent as part of the tool schema.\n */\n type?: \"frontend\" | \"human-in-the-loop\";\n name: string;\n description?: string;\n parameters?: StandardSchemaV1<any, T>;\n handler?: (args: T, context: FrontendToolHandlerContext) => Promise<unknown>;\n followUp?: boolean;\n /**\n * Optional agent ID to constrain this tool to a specific agent.\n * If specified, this tool will only be available to the specified agent.\n */\n agentId?: string;\n /**\n * Whether this tool is available to the agent.\n * Set to false to hide the tool from the agent without unregistering it.\n * Defaults to true when not specified.\n */\n available?: boolean;\n /**\n * Also expose this tool to browser agents through the WebMCP API\n * (`document.modelContext`) while keeping the normal agent registration.\n *\n * - `true` — register with default annotations.\n * - `{ annotations }` — register with the given WebMCP annotations.\n * - `false` / `undefined` — do not register.\n *\n * The tool's `handler` runs when a browser agent calls the tool; the handler\n * context then has no `agent`. No-op in environments without WebMCP support\n * (e.g. React Native, or browsers without the API enabled).\n */\n webmcp?: boolean | WebMCPToolConfig;\n};\n\nexport type Suggestion = {\n title: string;\n message: string;\n /** Indicates whether this suggestion is still being generated. */\n isLoading: boolean;\n /** Optional CSS class name applied to the suggestion pill. */\n className?: string;\n};\n\nexport type SuggestionAvailability =\n | \"before-first-message\"\n | \"after-first-message\"\n | \"always\"\n | \"disabled\";\n\nexport type DynamicSuggestionsConfig = {\n /**\n * A prompt or instructions for the GPT to generate suggestions.\n */\n instructions: string;\n /**\n * The minimum number of suggestions to generate. Defaults to `1`.\n * @default 1\n */\n minSuggestions?: number;\n /**\n * The maximum number of suggestions to generate. Defaults to `3`.\n * @default 1\n */\n maxSuggestions?: number;\n\n /**\n * When the suggestions are available. Defaults to \"after-first-message\".\n */\n available?: SuggestionAvailability;\n\n /**\n * The agent ID of the provider of the suggestions. Defaults to `\"default\"`.\n */\n providerAgentId?: string;\n\n /**\n * The agent ID of the consumer of the suggestions. Defaults to `\"*\"` (all agents).\n */\n consumerAgentId?: string;\n};\n\nexport type StaticSuggestionsConfig = {\n /**\n * The suggestions to display.\n */\n suggestions: Omit<Suggestion, \"isLoading\">[];\n\n /**\n * When the suggestions are available. Defaults to \"before-first-message\".\n */\n available?: SuggestionAvailability;\n\n /**\n * The agent ID of the consumer of the suggestions. Defaults to `\"*\"` (all agents).\n */\n consumerAgentId?: string;\n};\n\nexport type SuggestionsConfig =\n | DynamicSuggestionsConfig\n | StaticSuggestionsConfig;\n","export function completePartialMarkdown(input: string): string {\n let s = input;\n\n // Handle code fences first - use FIRST unmatched fence for proper nesting\n const fenceMatches = Array.from(s.matchAll(/^(\\s*)(`{3,}|~{3,})/gm));\n if (fenceMatches.length % 2 === 1) {\n const [, indent, fence] = fenceMatches[0]!;\n s += `\\n${indent}${fence}`;\n }\n\n // Identify incomplete links at the end and close them\n const incompleteLinkMatch = s.match(/\\[([^\\]]*)\\]\\(([^)]*)$/);\n if (incompleteLinkMatch) {\n s += \")\";\n }\n\n // State-based parsing\n interface OpenElement {\n type: string;\n marker: string;\n position: number;\n }\n\n const openElements: OpenElement[] = [];\n const chars = Array.from(s);\n\n // First pass: identify code block boundaries and inline code to avoid processing their content\n const codeBlockRanges: Array<{ start: number; end: number }> = [];\n const inlineCodeRanges: Array<{ start: number; end: number }> = [];\n\n // Find code block ranges\n let tempCodeFenceCount = 0;\n let currentCodeBlockStart = -1;\n\n for (let i = 0; i < chars.length; i++) {\n if (i === 0 || chars[i - 1] === \"\\n\") {\n const lineMatch = s.substring(i).match(/^(\\s*)(`{3,}|~{3,})/);\n if (lineMatch) {\n tempCodeFenceCount++;\n if (tempCodeFenceCount % 2 === 1) {\n currentCodeBlockStart = i;\n } else if (currentCodeBlockStart !== -1) {\n codeBlockRanges.push({\n start: currentCodeBlockStart,\n end: i + lineMatch[0].length,\n });\n currentCodeBlockStart = -1;\n }\n i += lineMatch[0].length - 1;\n }\n }\n }\n\n // Find inline code ranges\n for (let i = 0; i < chars.length; i++) {\n if (chars[i] === \"`\") {\n // Check if escaped\n let backslashCount = 0;\n for (let j = i - 1; j >= 0 && chars[j] === \"\\\\\"; j--) {\n backslashCount++;\n }\n if (backslashCount % 2 === 0) {\n // Not escaped - find the closing backtick\n for (let j = i + 1; j < chars.length; j++) {\n if (chars[j] === \"`\") {\n let closingBackslashCount = 0;\n for (let k = j - 1; k >= 0 && chars[k] === \"\\\\\"; k--) {\n closingBackslashCount++;\n }\n if (closingBackslashCount % 2 === 0) {\n inlineCodeRanges.push({ start: i, end: j + 1 });\n i = j;\n break;\n }\n }\n }\n }\n }\n }\n\n // Helper function to check if position is in code\n const isInCode = (pos: number): boolean => {\n return (\n codeBlockRanges.some((range) => pos >= range.start && pos < range.end) ||\n inlineCodeRanges.some((range) => pos >= range.start && pos < range.end)\n );\n };\n\n // Second pass: process markdown elements, skipping code regions\n for (let i = 0; i < chars.length; i++) {\n const char = chars[i];\n const nextChar = chars[i + 1];\n const prevChar = chars[i - 1];\n\n if (isInCode(i)) {\n continue;\n }\n\n // Handle brackets (but not if they're part of already-complete links)\n if (char === \"[\") {\n // Check if this is part of a complete link [text](url)\n let isCompleteLink = false;\n let bracketDepth = 1;\n let j = i + 1;\n\n // Find the matching ]\n while (j < chars.length && bracketDepth > 0) {\n if (chars[j] === \"[\" && !isInCode(j)) bracketDepth++;\n if (chars[j] === \"]\" && !isInCode(j)) bracketDepth--;\n j++;\n }\n\n // Check if followed by (\n if (bracketDepth === 0 && chars[j] === \"(\") {\n // Find the closing )\n let parenDepth = 1;\n j++;\n while (j < chars.length && parenDepth > 0) {\n if (chars[j] === \"(\" && !isInCode(j)) parenDepth++;\n if (chars[j] === \")\" && !isInCode(j)) parenDepth--;\n j++;\n }\n if (parenDepth === 0) {\n isCompleteLink = true;\n i = j - 1;\n continue;\n }\n }\n\n // This is a standalone bracket, treat as markdown\n if (!isCompleteLink) {\n const existingIndex = openElements.findIndex(\n (el) => el.type === \"bracket\",\n );\n if (existingIndex !== -1) {\n openElements.splice(existingIndex, 1);\n } else {\n openElements.push({ type: \"bracket\", marker: \"[\", position: i });\n }\n }\n }\n\n // Handle double emphasis first (**, __, ~~) - these take precedence\n else if (char === \"*\" && nextChar === \"*\") {\n const existingIndex = openElements.findIndex(\n (el) => el.type === \"bold_star\",\n );\n if (existingIndex !== -1) {\n openElements.splice(existingIndex, 1);\n } else {\n openElements.push({ type: \"bold_star\", marker: \"**\", position: i });\n }\n i++; // Skip next character\n } else if (char === \"_\" && nextChar === \"_\") {\n const existingIndex = openElements.findIndex(\n (el) => el.type === \"bold_underscore\",\n );\n if (existingIndex !== -1) {\n openElements.splice(existingIndex, 1);\n } else {\n openElements.push({\n type: \"bold_underscore\",\n marker: \"__\",\n position: i,\n });\n }\n i++; // Skip next character\n } else if (char === \"~\" && nextChar === \"~\") {\n const existingIndex = openElements.findIndex(\n (el) => el.type === \"strike\",\n );\n if (existingIndex !== -1) {\n openElements.splice(existingIndex, 1);\n } else {\n openElements.push({ type: \"strike\", marker: \"~~\", position: i });\n }\n i++; // Skip next character\n }\n\n // Handle single emphasis (*, _) - only if not part of double\n else if (char === \"*\" && prevChar !== \"*\" && nextChar !== \"*\") {\n const existingIndex = openElements.findIndex(\n (el) => el.type === \"italic_star\",\n );\n if (existingIndex !== -1) {\n openElements.splice(existingIndex, 1);\n } else {\n openElements.push({ type: \"italic_star\", marker: \"*\", position: i });\n }\n } else if (char === \"_\" && prevChar !== \"_\" && nextChar !== \"_\") {\n const existingIndex = openElements.findIndex(\n (el) => el.type === \"italic_underscore\",\n );\n if (existingIndex !== -1) {\n openElements.splice(existingIndex, 1);\n } else {\n openElements.push({\n type: \"italic_underscore\",\n marker: \"_\",\n position: i,\n });\n }\n }\n }\n\n // Handle remaining unmatched backticks (outside of inline code ranges)\n let backtickCount = 0;\n for (let i = 0; i < chars.length; i++) {\n if (chars[i] === \"`\" && !isInCode(i)) {\n backtickCount++;\n }\n }\n if (backtickCount % 2 === 1) {\n s += \"`\";\n }\n\n // Close remaining open elements in reverse order (LIFO stack semantics)\n openElements.sort((a, b) => b.position - a.position);\n\n const closers = openElements.map((el) => {\n switch (el.type) {\n case \"bracket\":\n return \"]\";\n case \"bold_star\":\n return \"**\";\n case \"bold_underscore\":\n return \"__\";\n case \"strike\":\n return \"~~\";\n case \"italic_star\":\n return \"*\";\n case \"italic_underscore\":\n return \"_\";\n default:\n return \"\";\n }\n });\n\n let result = s + closers.join(\"\");\n\n // Handle parentheses ONLY if not inside code\n const finalFenceMatches = Array.from(\n result.matchAll(/^(\\s*)(`{3,}|~{3,})/gm),\n );\n const hasUnclosedBacktick = (result.match(/`/g) || []).length % 2 === 1;\n const hasUnclosedCodeFence = finalFenceMatches.length % 2 === 1;\n\n let shouldCloseParens = !hasUnclosedBacktick && !hasUnclosedCodeFence;\n\n if (shouldCloseParens) {\n const lastOpenParen = result.lastIndexOf(\"(\");\n if (lastOpenParen !== -1) {\n // Check if this paren is inside a backtick pair\n const beforeParen = result.substring(0, lastOpenParen);\n const backticksBeforeParen = (beforeParen.match(/`/g) || []).length;\n if (backticksBeforeParen % 2 === 1) {\n shouldCloseParens = false;\n }\n }\n }\n\n if (shouldCloseParens) {\n const openParens = (result.match(/\\(/g) || []).length;\n const closeParens = (result.match(/\\)/g) || []).length;\n if (openParens > closeParens) {\n result += \")\".repeat(openParens - closeParens);\n }\n }\n\n return result;\n}\n","import { phoenixExponentialBackoff } from \"@copilotkit/shared\";\nimport type { Subscription } from \"rxjs\";\nimport { defer, firstValueFrom, merge, Observable, of } from \"rxjs\";\nimport {\n catchError,\n filter,\n map,\n mergeMap,\n share,\n shareReplay,\n switchMap,\n take,\n takeUntil,\n tap,\n withLatestFrom,\n} from \"rxjs/operators\";\nimport {\n createActionGroup,\n createEffect,\n createReducer,\n createSelector,\n createStore,\n empty,\n ofType,\n on,\n props,\n} from \"./utils/micro-redux\";\nimport type { Reducer, Store } from \"./utils/micro-redux\";\nimport type {\n RuntimeRequestInit,\n RuntimeRequestMeta,\n} from \"./utils/runtime-request\";\nimport {\n ɵphoenixChannel$,\n ɵphoenixSocket$,\n ɵobservePhoenixEvent$,\n ɵobservePhoenixJoinOutcome$,\n ɵobservePhoenixSocketHealth$,\n ɵobservePhoenixSocketSignals$,\n} from \"./utils/phoenix-observable\";\nimport type { ɵPhoenixChannelSession } from \"./utils/phoenix-observable\";\n\nconst THREADS_CHANNEL_EVENT = \"thread_metadata\";\nconst THREAD_RUN_ACTIVITY_CHANNEL_EVENT = \"thread_run_activity\";\nconst THREAD_SUBSCRIBE_PATH = \"/threads/subscribe\";\nconst MAX_SOCKET_RETRIES = 5;\nconst REQUEST_TIMEOUT_MS = 15_000;\n\ninterface ThreadRecord {\n id: string;\n organizationId: string;\n agentId: string;\n createdById: string;\n name: string | null;\n archived: boolean;\n createdAt: string;\n updatedAt: string;\n lastRunAt?: string;\n}\n\ninterface ThreadRuntimeContext {\n runtimeUrl: string;\n headers: Record<string, string>;\n wsUrl?: string;\n agentId: string;\n includeArchived?: boolean;\n limit?: number;\n}\n\ntype ThreadMetadataEvent =\n | {\n operation: \"created\" | \"renamed\" | \"archived\" | \"unarchived\" | \"updated\";\n threadId: string;\n userId: string;\n organizationId: string;\n occurredAt: string;\n thread: ThreadRecord;\n }\n | {\n operation: \"deleted\";\n threadId: string;\n userId: string;\n organizationId: string;\n occurredAt: string;\n deleted: {\n id: string;\n };\n };\n\n/**\n * Internal notification emitted when Intelligence observes new run activity\n * for a thread without changing that thread's metadata row.\n */\nexport type ThreadRunActivityNotification = {\n type: \"thread_run_activity\";\n threadId: string;\n agentId?: string;\n runId?: string;\n eventType: string;\n latestEventId?: string;\n};\n\ntype ThreadRunActivityGatewayPayload = {\n threadId?: unknown;\n thread_id?: unknown;\n agentId?: unknown;\n agent_id?: unknown;\n runId?: unknown;\n run_id?: unknown;\n eventType?: unknown;\n event_type?: unknown;\n latestEventId?: unknown;\n latest_event_id?: unknown;\n};\n\ninterface ThreadListResponse {\n threads: ThreadRecord[];\n joinCode?: string | null;\n nextCursor?: string | null;\n}\n\ninterface ThreadMetadataCredentialsResponse {\n joinToken: string;\n}\n\ninterface MutationRequest {\n requestId: string;\n /** Session the mutation was dispatched in; stale results are dropped. */\n sessionId: number;\n path: string;\n method: \"PATCH\" | \"POST\" | \"DELETE\";\n body: Record<string, unknown>;\n}\n\ntype MutationOutcome =\n | { requestId: string; sessionId: number; ok: true }\n | { requestId: string; sessionId: number; ok: false; error: Error };\n\ninterface ThreadEnvironment {\n fetch: typeof fetch;\n /**\n * Optional callback invoked whenever a thread mutation (rename, archive,\n * unarchive, delete) is rejected by the server. Lets framework wrappers\n * surface a transient error toast without subscribing to the error\n * selector. The error is also recorded in `state.error` regardless.\n *\n * Fired after any rollback (delete) has been applied to local state.\n */\n onError?: (error: Error) => void;\n}\n\ninterface ThreadState {\n threads: ThreadRecord[];\n isLoading: boolean;\n isFetchingNextPage: boolean;\n error: Error | null;\n /**\n * Error from the most recent failed next-page (`fetchMore`) load, or `null`.\n * Tracked SEPARATELY from `error` so a paginated-load failure surfaces an\n * inline \"couldn't load more\" affordance without replacing the already-loaded\n * list with a full-panel error. Cleared when a fetch-more is retried or when\n * one succeeds; reset on context change / stop.\n */\n fetchMoreError: Error | null;\n context: ThreadRuntimeContext | null;\n sessionId: number;\n metadataCredentialsRequested: boolean;\n metadataJoinCode: string | null;\n nextCursor: string | null;\n /** Number of thread mutations currently awaiting a server response. */\n inFlightMutationCount: number;\n /**\n * Rows optimistically removed by an in-flight `delete`, keyed by the\n * originating request id. DELETE is the one mutation that rolls back on\n * rejection, so the removed row is parked here and restored if the server\n * rejects. Rename/archive/unarchive are optimistic no-rollback and do not\n * populate this map.\n */\n pendingDeletes: Record<string, ThreadRecord>;\n}\n\nconst initialThreadState: ThreadState = {\n threads: [],\n isLoading: false,\n isFetchingNextPage: false,\n error: null,\n fetchMoreError: null,\n context: null,\n sessionId: 0,\n metadataCredentialsRequested: false,\n metadataJoinCode: null,\n nextCursor: null,\n inFlightMutationCount: 0,\n pendingDeletes: {},\n};\n\nconst threadAdapterEvents = createActionGroup(\"Thread Adapter\", {\n started: empty(),\n stopped: empty(),\n contextChanged: props<{ context: ThreadRuntimeContext | null }>(),\n fetchNextPageRequested: empty(),\n renameRequested: props<{\n requestId: string;\n threadId: string;\n name: string;\n }>(),\n archiveRequested: props<{ requestId: string; threadId: string }>(),\n unarchiveRequested: props<{ requestId: string; threadId: string }>(),\n deleteRequested: props<{ requestId: string; threadId: string }>(),\n newThreadStarted: empty(),\n});\n\nconst threadRestEvents = createActionGroup(\"Thread REST\", {\n listRequested: props<{ sessionId: number }>(),\n listSucceeded: props<{\n sessionId: number;\n threads: ThreadRecord[];\n joinCode: string | null;\n nextCursor: string | null;\n }>(),\n listFailed: props<{ sessionId: number; error: Error }>(),\n nextPageSucceeded: props<{\n sessionId: number;\n threads: ThreadRecord[];\n nextCursor: string | null;\n }>(),\n nextPageFailed: props<{ sessionId: number; error: Error }>(),\n metadataCredentialsRequested: props<{ sessionId: number }>(),\n metadataCredentialsSucceeded: props<{\n sessionId: number;\n joinToken: string;\n }>(),\n metadataCredentialsFailed: props<{ sessionId: number; error: Error }>(),\n mutationFinished: props<{ outcome: MutationOutcome }>(),\n});\n\nconst threadSocketEvents = createActionGroup(\"Thread Socket\", {\n opened: props<{ sessionId: number }>(),\n errored: props<{ sessionId: number }>(),\n joinFailed: props<{ sessionId: number }>(),\n joinTimedOut: props<{ sessionId: number }>(),\n metadataReceived: props<{\n sessionId: number;\n payload: ThreadMetadataEvent;\n }>(),\n runActivityReceived: props<{\n sessionId: number;\n notification: ThreadRunActivityNotification;\n }>(),\n});\n\nconst threadDomainEvents = createActionGroup(\"Thread Domain\", {\n threadUpserted: props<{ sessionId: number; thread: ThreadRecord }>(),\n threadDeleted: props<{ sessionId: number; threadId: string }>(),\n});\n\nfunction sortThreadsByRecency(threads: ThreadRecord[]): ThreadRecord[] {\n // Prefer lastRunAt so the order reflects actual agent activity and stays\n // stable when a user performs metadata-only actions like archive or rename.\n // Fall back to updatedAt (and then createdAt) for threads that have never run.\n return [...threads].sort((left, right) => {\n const leftKey = left.lastRunAt ?? left.updatedAt ?? left.createdAt;\n const rightKey = right.lastRunAt ?? right.updatedAt ?? right.createdAt;\n return rightKey.localeCompare(leftKey);\n });\n}\n\nfunction upsertThread(\n threads: ThreadRecord[],\n thread: ThreadRecord,\n): ThreadRecord[] {\n const existingIndex = threads.findIndex((item) => item.id === thread.id);\n if (existingIndex === -1) {\n return sortThreadsByRecency([...threads, thread]);\n }\n\n const next = [...threads];\n next[existingIndex] = thread;\n return sortThreadsByRecency(next);\n}\n\n/**\n * Returns a non-empty string payload field or undefined for absent fields.\n */\nfunction optionalString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\n/**\n * REST `/threads` is agent-scoped. The Phoenix `user_meta` channel is not.\n * Drop live upserts that belong to a different agent, or one Inspector\n * `all-agents` flatten shows the same thread twice until a hard refresh.\n */\nfunction threadMetadataTargetsAgent(\n payload: ThreadMetadataEvent,\n agentId: string | undefined,\n): boolean {\n if (!agentId || payload.operation === \"deleted\") {\n return true;\n }\n\n const threadAgentId = optionalString(payload.thread.agentId);\n return !threadAgentId || threadAgentId === agentId;\n}\n\n/**\n * Converts gateway run-activity payloads into the internal TypeScript shape.\n */\nfunction normalizeThreadRunActivityNotification(\n payload: ThreadRunActivityGatewayPayload,\n): ThreadRunActivityNotification | null {\n const threadId = optionalString(payload.threadId ?? payload.thread_id);\n const eventType = optionalString(payload.eventType ?? payload.event_type);\n\n if (!threadId || !eventType) {\n return null;\n }\n\n return {\n type: \"thread_run_activity\",\n threadId,\n agentId: optionalString(payload.agentId ?? payload.agent_id),\n runId: optionalString(payload.runId ?? payload.run_id),\n eventType,\n latestEventId: optionalString(\n payload.latestEventId ?? payload.latest_event_id,\n ),\n };\n}\n\nconst threadReducer = createReducer(\n initialThreadState,\n on(threadAdapterEvents.contextChanged, (state: ThreadState, { context }) => ({\n ...state,\n context,\n sessionId: state.sessionId + 1,\n threads: [],\n isLoading: Boolean(context),\n isFetchingNextPage: false,\n error: null,\n fetchMoreError: null,\n metadataCredentialsRequested: false,\n metadataJoinCode: null,\n nextCursor: null,\n inFlightMutationCount: 0,\n pendingDeletes: {},\n })),\n on(threadAdapterEvents.stopped, (state: ThreadState) => ({\n ...state,\n threads: [],\n isLoading: false,\n isFetchingNextPage: false,\n error: null,\n fetchMoreError: null,\n metadataCredentialsRequested: false,\n metadataJoinCode: null,\n nextCursor: null,\n inFlightMutationCount: 0,\n pendingDeletes: {},\n })),\n on(threadRestEvents.listRequested, (state: ThreadState, { sessionId }) => {\n if (sessionId !== state.sessionId || !state.context) {\n return state;\n }\n\n return {\n ...state,\n isLoading: true,\n error: null,\n // A full-list refetch supersedes any prior fetch-more failure: the whole\n // list is being reloaded, so the stale inline \"couldn't load more\" banner\n // must not survive onto the fresh list.\n fetchMoreError: null,\n };\n }),\n on(\n threadRestEvents.listSucceeded,\n (state: ThreadState, { sessionId, threads, joinCode, nextCursor }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n const joinCodeChanged = joinCode !== state.metadataJoinCode;\n\n return {\n ...state,\n threads: sortThreadsByRecency(threads),\n isLoading: false,\n error: null,\n // The fresh full list also clears any lingering fetch-more error, in\n // case the list arrived without passing through `listRequested`.\n fetchMoreError: null,\n metadataJoinCode: joinCode,\n metadataCredentialsRequested: joinCodeChanged\n ? false\n : state.metadataCredentialsRequested,\n nextCursor,\n };\n },\n ),\n on(\n threadRestEvents.listFailed,\n (state: ThreadState, { sessionId, error }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n isLoading: false,\n error,\n };\n },\n ),\n on(\n threadRestEvents.nextPageSucceeded,\n (state: ThreadState, { sessionId, threads, nextCursor }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n let merged = state.threads;\n for (const thread of threads) {\n merged = upsertThread(merged, thread);\n }\n\n return {\n ...state,\n threads: merged,\n isFetchingNextPage: false,\n // A successful next page clears any prior fetch-more error.\n fetchMoreError: null,\n nextCursor,\n };\n },\n ),\n on(\n threadRestEvents.nextPageFailed,\n (state: ThreadState, { sessionId, error }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n // A failed next-page load records the error on the DEDICATED fetch-more\n // channel — NOT `state.error` — so the already-loaded list is preserved\n // and the drawer renders an inline \"couldn't load more — retry\" panel\n // rather than replacing the whole list with a full-panel error.\n return {\n ...state,\n isFetchingNextPage: false,\n fetchMoreError: error,\n };\n },\n ),\n on(\n threadRestEvents.metadataCredentialsFailed,\n (state: ThreadState, { sessionId }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n // Non-fatal: the metadata-credentials (realtime join-token) fetch runs\n // AFTER the thread list has already loaded and only powers the realtime\n // channel. A failure means realtime won't connect, but the fetched list\n // is still valid — so we do NOT write `state.error` (which would replace\n // the whole list with a \"couldn't load\" panel). The failure is surfaced\n // as a diagnostic warning instead (socketDiagnosticsEffect), mirroring the\n // stay-stale handling of a realtime channel join failure. Clear the\n // request latch so a later list refresh can retry realtime setup.\n return {\n ...state,\n metadataCredentialsRequested: false,\n };\n },\n ),\n on(\n threadRestEvents.metadataCredentialsRequested,\n (state: ThreadState, { sessionId }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n metadataCredentialsRequested: true,\n };\n },\n ),\n on(threadAdapterEvents.fetchNextPageRequested, (state: ThreadState) => {\n if (!state.nextCursor || state.isFetchingNextPage) {\n return state;\n }\n\n return {\n ...state,\n isFetchingNextPage: true,\n // Clear any prior fetch-more error so a retry dismisses the inline panel\n // immediately while the next-page request is in flight.\n fetchMoreError: null,\n };\n }),\n on(\n threadAdapterEvents.renameRequested,\n (state: ThreadState, { threadId, name }) => {\n // Optimistic, no-rollback: reflect the new name immediately. A failure\n // surfaces via `error`/`onError` but the local row is left as-is; a\n // realtime metadata event or refetch reconciles the true server state.\n const existing = state.threads.find((thread) => thread.id === threadId);\n const inFlightMutationCount = state.inFlightMutationCount + 1;\n if (!existing) {\n return { ...state, inFlightMutationCount };\n }\n\n return {\n ...state,\n threads: upsertThread(state.threads, { ...existing, name }),\n inFlightMutationCount,\n };\n },\n ),\n on(\n threadAdapterEvents.archiveRequested,\n (state: ThreadState, { threadId }) => {\n // Optimistic, no-rollback. When archived threads are hidden, drop the\n // row; otherwise flip the flag in place. Note: archiving the active\n // thread is non-destructive — the wrapper keeps viewing it.\n const existing = state.threads.find((thread) => thread.id === threadId);\n const inFlightMutationCount = state.inFlightMutationCount + 1;\n if (!existing) {\n return { ...state, inFlightMutationCount };\n }\n\n if (!state.context?.includeArchived) {\n return {\n ...state,\n threads: state.threads.filter((thread) => thread.id !== threadId),\n inFlightMutationCount,\n };\n }\n\n return {\n ...state,\n threads: upsertThread(state.threads, { ...existing, archived: true }),\n inFlightMutationCount,\n };\n },\n ),\n on(\n threadAdapterEvents.unarchiveRequested,\n (state: ThreadState, { threadId }) => {\n // Optimistic, no-rollback.\n const existing = state.threads.find((thread) => thread.id === threadId);\n const inFlightMutationCount = state.inFlightMutationCount + 1;\n if (!existing) {\n return { ...state, inFlightMutationCount };\n }\n\n return {\n ...state,\n threads: upsertThread(state.threads, { ...existing, archived: false }),\n inFlightMutationCount,\n };\n },\n ),\n on(\n threadAdapterEvents.deleteRequested,\n (state: ThreadState, { requestId, threadId }) => {\n // Optimistic WITH rollback: remove the row now, but park it under the\n // request id so it can be restored if the server rejects the delete.\n const existing = state.threads.find((thread) => thread.id === threadId);\n const inFlightMutationCount = state.inFlightMutationCount + 1;\n if (!existing) {\n return { ...state, inFlightMutationCount };\n }\n\n return {\n ...state,\n threads: state.threads.filter((thread) => thread.id !== threadId),\n pendingDeletes: { ...state.pendingDeletes, [requestId]: existing },\n inFlightMutationCount,\n };\n },\n ),\n on(threadAdapterEvents.newThreadStarted, (state: ThreadState) => ({\n // Lazy creation: a fresh client-side thread does NOT add a phantom row —\n // it only materializes once its first run persists server-side. The\n // store-side concern is purely to clear any stale error so the welcome\n // screen renders cleanly; the wrapper owns the active/explicit threadId.\n ...state,\n error: null,\n })),\n on(threadRestEvents.mutationFinished, (state: ThreadState, { outcome }) => {\n // Drop results from a superseded session. `contextChanged`/`stopped` already\n // reset `threads`, `pendingDeletes`, and `inFlightMutationCount`, so a\n // mutation that resolves after the context switched must not write an error,\n // fire onError (guarded in subscribeErrors), or roll a stale row back into\n // the new list. Mirrors every other session-scoped handler.\n if (outcome.sessionId !== state.sessionId) {\n return state;\n }\n\n const inFlightMutationCount = Math.max(0, state.inFlightMutationCount - 1);\n\n if (outcome.ok) {\n // Success: drop any parked delete-rollback snapshot for this request.\n if (state.pendingDeletes[outcome.requestId] === undefined) {\n return { ...state, inFlightMutationCount };\n }\n\n const { [outcome.requestId]: _settled, ...rest } = state.pendingDeletes;\n return { ...state, inFlightMutationCount, pendingDeletes: rest };\n }\n\n // Failure: surface the error. For a rejected delete, restore the row that\n // was optimistically removed (rollback). Other mutations are no-rollback.\n const rolledBack = state.pendingDeletes[outcome.requestId];\n if (rolledBack === undefined) {\n return { ...state, inFlightMutationCount, error: outcome.error };\n }\n\n const { [outcome.requestId]: _restored, ...rest } = state.pendingDeletes;\n return {\n ...state,\n threads: upsertThread(state.threads, rolledBack),\n pendingDeletes: rest,\n inFlightMutationCount,\n error: outcome.error,\n };\n }),\n on(\n threadDomainEvents.threadUpserted,\n (state: ThreadState, { sessionId, thread }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n threads: upsertThread(state.threads, thread),\n };\n },\n ),\n on(\n threadDomainEvents.threadDeleted,\n (state: ThreadState, { sessionId, threadId }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n threads: state.threads.filter((thread) => thread.id !== threadId),\n };\n },\n ),\n) as Reducer<ThreadState>;\n\n/**\n * The set of memoized thread selectors bound to a single store instance.\n *\n * @see createThreadSelectors\n */\ninterface ThreadSelectors {\n threads: (state: ThreadState) => ThreadRecord[];\n isLoading: (state: ThreadState) => boolean;\n error: (state: ThreadState) => Error | null;\n fetchMoreError: (state: ThreadState) => Error | null;\n hasNextPage: (state: ThreadState) => boolean;\n isFetchingNextPage: (state: ThreadState) => boolean;\n isMutating: (state: ThreadState) => boolean;\n}\n\n/**\n * Builds a fresh set of memoized thread selectors.\n *\n * Each `createSelector` closure owns a private one-entry cache. Sharing a\n * single module-level selector instance across multiple concurrent stores\n * (e.g. a `<CopilotThreadsDrawer>` plus an independent `useThreads`) makes every\n * cross-store emission a cache miss, defeating memoization and risking\n * emission instability for any future selector that allocates a new\n * object/array. Creating a per-store instance keeps each store's cache\n * isolated so concurrent stores never thrash one another.\n */\nfunction createThreadSelectors(): ThreadSelectors {\n return {\n threads: createSelector((state: ThreadState) => state.threads),\n isLoading: createSelector((state: ThreadState) => state.isLoading),\n error: createSelector((state: ThreadState) => state.error),\n fetchMoreError: createSelector(\n (state: ThreadState) => state.fetchMoreError,\n ),\n hasNextPage: createSelector(\n (state: ThreadState) => state.nextCursor != null,\n ),\n isFetchingNextPage: createSelector(\n (state: ThreadState) => state.isFetchingNextPage,\n ),\n isMutating: createSelector(\n (state: ThreadState) => state.inFlightMutationCount > 0,\n ),\n };\n}\n\n// Standalone selector instances retained for callers that read a one-off\n// snapshot (e.g. `selectThreads(store.getState())`) where cross-store memo\n// isolation is irrelevant. Subscriptions through `store.select(...)` should\n// prefer the per-store `ThreadStore.selectors` bundle below.\nconst standaloneSelectors = createThreadSelectors();\nconst selectThreads = standaloneSelectors.threads;\nconst selectThreadsIsLoading = standaloneSelectors.isLoading;\nconst selectThreadsError = standaloneSelectors.error;\nconst selectFetchMoreError = standaloneSelectors.fetchMoreError;\nconst selectHasNextPage = standaloneSelectors.hasNextPage;\nconst selectIsFetchingNextPage = standaloneSelectors.isFetchingNextPage;\nconst selectIsMutating = standaloneSelectors.isMutating;\n\ninterface ThreadStore {\n start(): void;\n stop(): void;\n setContext(context: ThreadRuntimeContext | null): void;\n /** Re-fetches the thread list without resetting the current list to empty. */\n refresh(): void;\n /**\n * Re-fetches the thread list without resetting the current list to empty.\n *\n * Public, design-named alias of {@link refresh} used by the drawer's\n * error-state Retry affordance and the Active/All filter-change refetch.\n */\n refetchThreads(): void;\n /**\n * Resets to a fresh, client-side thread so the welcome screen can show.\n *\n * Lazy creation: no phantom row is added to the list — the new thread only\n * materializes once its first run persists server-side. This is distinct\n * from selecting an existing thread (which the wrapper marks *explicit*,\n * suppressing the welcome screen): the thread produced here is NOT explicit.\n */\n startNewThread(): void;\n fetchNextPage(): void;\n renameThread(threadId: string, name: string): Promise<void>;\n archiveThread(threadId: string): Promise<void>;\n unarchiveThread(threadId: string): Promise<void>;\n deleteThread(threadId: string): Promise<void>;\n /**\n * Subscribes to synthetic run-activity notifications without changing the\n * thread metadata list.\n */\n subscribeToRunActivity?(\n callback: (notification: ThreadRunActivityNotification) => void,\n ): Subscription;\n getState(): ThreadState;\n /**\n * Returns a stable initial snapshot for server-side rendering.\n *\n * `useSyncExternalStore` requires a `getServerSnapshot` during SSR/prerender\n * (e.g. Next.js); without one React throws \"Missing getServerSnapshot\". The\n * returned reference is stable across calls so React does not loop. There is\n * no client-side thread data during prerender, so this is the empty initial\n * state.\n */\n getServerState(): ThreadState;\n select: Store<ThreadState>[\"select\"];\n /**\n * Memoized selectors bound to THIS store instance.\n *\n * Subscriptions should pass these to {@link select} (e.g.\n * `store.select(store.selectors.threads)`) so each store keeps its own\n * one-entry memo cache. Sharing the module-level singletons across\n * concurrent stores defeats memoization and risks emission instability.\n */\n selectors: ThreadSelectors;\n}\n\nlet threadRequestId = 0;\n\nfunction createThreadRequestId(): string {\n threadRequestId += 1;\n return `thread-request-${threadRequestId}`;\n}\n\nfunction threadFromFetch<T>(\n input: string,\n init: RequestInit & {\n selector: (response: Response) => Promise<T>;\n fetch: typeof fetch;\n timeoutMs?: number;\n nonCritical?: boolean;\n },\n): Observable<T> {\n return new Observable<T>((subscriber) => {\n const {\n fetch: fetchImpl,\n selector,\n signal,\n timeoutMs,\n nonCritical,\n ...requestInit\n } = init;\n const controller = new AbortController();\n const runtimeRequest: RuntimeRequestMeta = {\n ...(nonCritical ? { nonCritical: true } : {}),\n ...(timeoutMs === undefined ? {} : { selfBounded: true }),\n };\n let timedOut = false;\n const abortRequest = () => controller.abort();\n\n if (signal?.aborted) {\n abortRequest();\n } else {\n signal?.addEventListener(\"abort\", abortRequest, { once: true });\n }\n\n const timeoutId =\n timeoutMs === undefined\n ? undefined\n : setTimeout(() => {\n timedOut = true;\n runtimeRequest.timedOut = true;\n abortRequest();\n }, timeoutMs);\n\n const requestInitWithMeta: RuntimeRequestInit = {\n ...requestInit,\n signal: controller.signal,\n ɵruntimeRequest: runtimeRequest,\n };\n\n fetchImpl(input, requestInitWithMeta)\n .then((response) => selector(response))\n .then((value) => {\n if (subscriber.closed) return;\n subscriber.next(value);\n subscriber.complete();\n })\n .catch((error: unknown) => {\n if (!subscriber.closed) {\n subscriber.error(\n timedOut ? new Error(\"Request timed out\") : (error as Error),\n );\n }\n });\n\n return () => {\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n }\n signal?.removeEventListener(\"abort\", abortRequest);\n abortRequest();\n };\n });\n}\n\nfunction createThreadFetchObservable(\n environment: ThreadEnvironment,\n context: ThreadRuntimeContext,\n sessionId: number,\n): Observable<\n | ReturnType<typeof threadRestEvents.listSucceeded>\n | ReturnType<typeof threadRestEvents.listFailed>\n> {\n return defer(() => {\n const params: Record<string, string> = {\n agentId: context.agentId,\n };\n if (context.includeArchived) params.includeArchived = \"true\";\n if (context.limit != null) params.limit = String(context.limit);\n\n const qs = new URLSearchParams(params);\n return threadFromFetch(`${context.runtimeUrl}/threads?${qs.toString()}`, {\n selector: (response) => {\n if (!response.ok) {\n throw new Error(`Failed to fetch threads: ${response.status}`);\n }\n\n return response.json() as Promise<ThreadListResponse>;\n },\n fetch: environment.fetch,\n timeoutMs: REQUEST_TIMEOUT_MS,\n method: \"GET\",\n headers: { ...context.headers },\n }).pipe(\n map((data) =>\n threadRestEvents.listSucceeded({\n sessionId,\n threads: data.threads,\n joinCode:\n typeof data.joinCode === \"string\" && data.joinCode.length > 0\n ? data.joinCode\n : null,\n nextCursor: data.nextCursor ?? null,\n }),\n ),\n catchError((error) => {\n return of(\n threadRestEvents.listFailed({\n sessionId,\n error: error instanceof Error ? error : new Error(String(error)),\n }),\n );\n }),\n );\n });\n}\n\nfunction createThreadMetadataCredentialsObservable(\n environment: ThreadEnvironment,\n context: ThreadRuntimeContext,\n sessionId: number,\n): Observable<\n | ReturnType<typeof threadRestEvents.metadataCredentialsSucceeded>\n | ReturnType<typeof threadRestEvents.metadataCredentialsFailed>\n> {\n return defer(() => {\n return threadFromFetch(`${context.runtimeUrl}${THREAD_SUBSCRIBE_PATH}`, {\n selector: async (response) => {\n if (!response.ok) {\n throw new Error(\n `Failed to fetch thread metadata credentials: ${response.status}`,\n );\n }\n\n return response.json() as Promise<ThreadMetadataCredentialsResponse>;\n },\n fetch: environment.fetch,\n timeoutMs: REQUEST_TIMEOUT_MS,\n nonCritical: true,\n method: \"POST\",\n headers: {\n ...context.headers,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({}),\n }).pipe(\n map((data) => {\n if (typeof data.joinToken !== \"string\" || data.joinToken.length === 0) {\n throw new Error(\"missing joinToken\");\n }\n\n return threadRestEvents.metadataCredentialsSucceeded({\n sessionId,\n joinToken: data.joinToken,\n });\n }),\n catchError((error) => {\n return of(\n threadRestEvents.metadataCredentialsFailed({\n sessionId,\n error: error instanceof Error ? error : new Error(String(error)),\n }),\n );\n }),\n );\n });\n}\n\nfunction createThreadMutationObservable(\n environment: ThreadEnvironment,\n context: ThreadRuntimeContext,\n request: MutationRequest,\n): Observable<ReturnType<typeof threadRestEvents.mutationFinished>> {\n return defer(() => {\n return threadFromFetch(`${context.runtimeUrl}${request.path}`, {\n selector: async (response) => {\n if (!response.ok) {\n throw new Error(`Request failed: ${response.status}`);\n }\n\n return null;\n },\n fetch: environment.fetch,\n method: request.method,\n headers: {\n ...context.headers,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(request.body),\n }).pipe(\n map(() =>\n threadRestEvents.mutationFinished({\n outcome: {\n requestId: request.requestId,\n sessionId: request.sessionId,\n ok: true,\n },\n }),\n ),\n catchError((error) => {\n return of(\n threadRestEvents.mutationFinished({\n outcome: {\n requestId: request.requestId,\n sessionId: request.sessionId,\n ok: false,\n error: error instanceof Error ? error : new Error(String(error)),\n },\n }),\n );\n }),\n );\n });\n}\n\nfunction createThreadStore(environment: ThreadEnvironment): ThreadStore {\n // Per-store selector instances keep this store's memo cache isolated from\n // any other concurrent store (see createThreadSelectors).\n const selectors = createThreadSelectors();\n\n const bootstrapEffect = createEffect(\n (\n actions$,\n state$: Observable<ThreadState>,\n ): Observable<ReturnType<typeof threadRestEvents.listRequested>> =>\n actions$.pipe(\n ofType(threadAdapterEvents.contextChanged),\n withLatestFrom(state$),\n filter(([, state]) => Boolean(state.context)),\n map(([, state]) =>\n threadRestEvents.listRequested({ sessionId: state.sessionId }),\n ),\n ),\n );\n\n const fetchEffect = createEffect(\n (actions$, state$: Observable<ThreadState>) =>\n actions$.pipe(\n ofType(threadRestEvents.listRequested),\n switchMap((action) =>\n state$.pipe(\n map((state) => state.context),\n filter((context): context is ThreadRuntimeContext =>\n Boolean(context),\n ),\n take(1),\n map((context) => ({ action, context })),\n takeUntil(\n actions$.pipe(\n ofType(\n threadAdapterEvents.contextChanged,\n threadAdapterEvents.stopped,\n ),\n ),\n ),\n switchMap(({ action: currentAction, context }) =>\n createThreadFetchObservable(\n environment,\n context,\n currentAction.sessionId,\n ),\n ),\n ),\n ),\n ),\n );\n\n const metadataCredentialsEffect = createEffect(\n (actions$, state$: Observable<ThreadState>) =>\n actions$.pipe(\n ofType(threadRestEvents.listSucceeded),\n withLatestFrom(state$),\n filter(([action, state]) => {\n return (\n action.sessionId === state.sessionId &&\n !state.metadataCredentialsRequested &&\n Boolean(state.context?.wsUrl) &&\n Boolean(state.metadataJoinCode)\n );\n }),\n map(([action]) =>\n threadRestEvents.metadataCredentialsRequested({\n sessionId: action.sessionId,\n }),\n ),\n ),\n );\n\n const metadataCredentialsFetchEffect = createEffect(\n (actions$, state$: Observable<ThreadState>) =>\n actions$.pipe(\n ofType(threadRestEvents.metadataCredentialsRequested),\n switchMap((action) =>\n state$.pipe(\n map((state) => state.context),\n filter((context): context is ThreadRuntimeContext =>\n Boolean(context),\n ),\n take(1),\n map((context) => ({ action, context })),\n takeUntil(\n actions$.pipe(\n ofType(\n threadAdapterEvents.contextChanged,\n threadAdapterEvents.stopped,\n ),\n ),\n ),\n switchMap(({ action: currentAction, context }) =>\n createThreadMetadataCredentialsObservable(\n environment,\n context,\n currentAction.sessionId,\n ),\n ),\n ),\n ),\n ),\n );\n\n const socketEffect = createEffect(\n (actions$, state$: Observable<ThreadState>) =>\n actions$.pipe(\n ofType(threadRestEvents.metadataCredentialsSucceeded),\n withLatestFrom(state$),\n filter(([action, state]) => {\n return (\n action.sessionId === state.sessionId &&\n Boolean(state.context?.wsUrl)\n );\n }),\n switchMap(([action, state]) => {\n const context = state.context as ThreadRuntimeContext;\n const joinToken = action.joinToken as string;\n const joinCode = state.metadataJoinCode as string;\n const shutdown$ = actions$.pipe(\n ofType(\n threadAdapterEvents.contextChanged,\n threadAdapterEvents.stopped,\n ),\n );\n\n return defer(() => {\n const socket$ = ɵphoenixSocket$({\n url: context.wsUrl!,\n options: {\n params: { join_token: joinToken },\n reconnectAfterMs: phoenixExponentialBackoff(100, 10_000),\n rejoinAfterMs: phoenixExponentialBackoff(1_000, 30_000),\n },\n }).pipe(shareReplay({ bufferSize: 1, refCount: true }));\n const channel$ = ɵphoenixChannel$({\n socket$,\n topic: `user_meta:${joinCode}`,\n }).pipe(shareReplay({ bufferSize: 1, refCount: true }));\n const socketSignals$ =\n ɵobservePhoenixSocketSignals$(socket$).pipe(share());\n const fatalSocketShutdown$ = ɵobservePhoenixSocketHealth$(\n socketSignals$,\n MAX_SOCKET_RETRIES,\n ).pipe(\n catchError(() => {\n console.warn(\n `[threads] WebSocket failed after ${MAX_SOCKET_RETRIES} attempts, giving up`,\n );\n return of(undefined);\n }),\n share(),\n );\n const socketLifecycle$ = socketSignals$.pipe(\n map((signal) =>\n signal.type === \"open\"\n ? threadSocketEvents.opened({ sessionId: action.sessionId })\n : threadSocketEvents.errored({ sessionId: action.sessionId }),\n ),\n );\n const metadata$ = channel$.pipe(\n switchMap(({ channel }: ɵPhoenixChannelSession) =>\n ɵobservePhoenixEvent$<ThreadMetadataEvent>(\n channel,\n THREADS_CHANNEL_EVENT,\n ),\n ),\n map((payload) =>\n threadSocketEvents.metadataReceived({\n sessionId: action.sessionId,\n payload,\n }),\n ),\n );\n const runActivity$ = channel$.pipe(\n switchMap(({ channel }: ɵPhoenixChannelSession) =>\n ɵobservePhoenixEvent$<ThreadRunActivityGatewayPayload>(\n channel,\n THREAD_RUN_ACTIVITY_CHANNEL_EVENT,\n ),\n ),\n map((payload) => normalizeThreadRunActivityNotification(payload)),\n filter(\n (notification): notification is ThreadRunActivityNotification =>\n notification !== null,\n ),\n map((notification) =>\n threadSocketEvents.runActivityReceived({\n sessionId: action.sessionId,\n notification,\n }),\n ),\n );\n const joinOutcome$ = ɵobservePhoenixJoinOutcome$(channel$).pipe(\n filter((outcome) => outcome.type !== \"joined\"),\n map((outcome) =>\n outcome.type === \"timeout\"\n ? threadSocketEvents.joinTimedOut({\n sessionId: action.sessionId,\n })\n : threadSocketEvents.joinFailed({\n sessionId: action.sessionId,\n }),\n ),\n );\n\n return merge(\n socketLifecycle$,\n metadata$,\n runActivity$,\n joinOutcome$,\n ).pipe(takeUntil(merge(shutdown$, fatalSocketShutdown$)));\n });\n }),\n ),\n );\n\n const realtimeMappingEffect = createEffect(\n (actions$, state$: Observable<ThreadState>) =>\n actions$.pipe(\n ofType(threadSocketEvents.metadataReceived),\n withLatestFrom(state$),\n filter(\n ([action, state]) =>\n action.sessionId === state.sessionId &&\n threadMetadataTargetsAgent(action.payload, state.context?.agentId),\n ),\n map(([action, state]) => {\n if (action.payload.operation === \"deleted\") {\n return threadDomainEvents.threadDeleted({\n sessionId: action.sessionId,\n threadId: action.payload.deleted.id,\n });\n }\n\n // When includeArchived is false, an \"archived\" event should remove\n // the thread from the local list rather than upserting it.\n if (\n action.payload.operation === \"archived\" &&\n !state.context?.includeArchived\n ) {\n return threadDomainEvents.threadDeleted({\n sessionId: action.sessionId,\n threadId: action.payload.threadId,\n });\n }\n\n return threadDomainEvents.threadUpserted({\n sessionId: action.sessionId,\n thread: action.payload.thread,\n });\n }),\n ),\n );\n\n // Observability-only effect for realtime-join health. The socket effect\n // dispatches `joinFailed`/`joinTimedOut`/`errored` but the reducer has no\n // handler for them by design: a transient WS drop while the (already\n // fetched) list is present must NOT become a hard list error — the user\n // keeps the stale list. Previously these actions were silently swallowed,\n // leaving a realtime-join failure with zero signal. This effect emits a\n // non-fatal warning (mirroring the MAX_SOCKET_RETRIES warn) so the failure\n // is diagnosable. Session-guarded so a superseded session stays quiet.\n const socketDiagnosticsEffect = createEffect(\n (actions$, state$: Observable<ThreadState>) =>\n actions$.pipe(\n ofType(\n threadSocketEvents.joinFailed,\n threadSocketEvents.joinTimedOut,\n threadSocketEvents.errored,\n threadRestEvents.metadataCredentialsFailed,\n ),\n withLatestFrom(state$),\n filter(([action, state]) => action.sessionId === state.sessionId),\n tap(([action]) => {\n const reason = threadSocketEvents.joinTimedOut.match(action)\n ? \"channel join timed out\"\n : threadSocketEvents.joinFailed.match(action)\n ? \"channel join was rejected\"\n : threadRestEvents.metadataCredentialsFailed.match(action)\n ? \"metadata credentials fetch failed\"\n : \"socket errored\";\n console.warn(\n `[threads] realtime ${reason}; the thread list may be stale until reconnect`,\n );\n }),\n ),\n { dispatch: false },\n );\n\n const fetchNextPageEffect = createEffect(\n (actions$, state$: Observable<ThreadState>) =>\n actions$.pipe(\n ofType(threadAdapterEvents.fetchNextPageRequested),\n withLatestFrom(state$),\n filter(\n ([, state]) => Boolean(state.context) && Boolean(state.nextCursor),\n ),\n switchMap(([, state]) => {\n const context = state.context as ThreadRuntimeContext;\n const params: Record<string, string> = {\n agentId: context.agentId,\n cursor: state.nextCursor!,\n };\n if (context.includeArchived) params.includeArchived = \"true\";\n if (context.limit != null) params.limit = String(context.limit);\n\n return threadFromFetch(\n `${context.runtimeUrl}/threads?${new URLSearchParams(params).toString()}`,\n {\n selector: (response) => {\n if (!response.ok) {\n throw new Error(\n `Failed to fetch next page: ${response.status}`,\n );\n }\n\n return response.json() as Promise<ThreadListResponse>;\n },\n fetch: environment.fetch,\n timeoutMs: REQUEST_TIMEOUT_MS,\n method: \"GET\",\n headers: { ...context.headers },\n },\n ).pipe(\n map((data) =>\n threadRestEvents.nextPageSucceeded({\n sessionId: state.sessionId,\n threads: data.threads,\n nextCursor: data.nextCursor ?? null,\n }),\n ),\n catchError((error) =>\n of(\n threadRestEvents.nextPageFailed({\n sessionId: state.sessionId,\n error:\n error instanceof Error ? error : new Error(String(error)),\n }),\n ),\n ),\n takeUntil(\n actions$.pipe(\n ofType(\n threadAdapterEvents.contextChanged,\n threadAdapterEvents.stopped,\n ),\n ),\n ),\n );\n }),\n ),\n );\n\n const mutationEffect = createEffect(\n (actions$, state$: Observable<ThreadState>) =>\n actions$.pipe(\n ofType(\n threadAdapterEvents.renameRequested,\n threadAdapterEvents.archiveRequested,\n threadAdapterEvents.unarchiveRequested,\n threadAdapterEvents.deleteRequested,\n ),\n withLatestFrom(state$),\n mergeMap(([action, state]) => {\n // Capture the dispatching session so a result that resolves after a\n // `contextChanged` is dropped by the reducer instead of leaking an\n // error/onError/rollback into the new session. The mergeMap is not\n // cancelled on context change, so the session tag is the guard.\n const sessionId = state.sessionId;\n const context = state.context;\n if (!context?.runtimeUrl) {\n const requestId = action.requestId;\n return of(\n threadRestEvents.mutationFinished({\n outcome: {\n requestId,\n sessionId,\n ok: false,\n error: new Error(\"Runtime URL is not configured\"),\n },\n }),\n );\n }\n\n const commonBody = {\n agentId: context.agentId,\n };\n\n if (threadAdapterEvents.renameRequested.match(action)) {\n return createThreadMutationObservable(environment, context, {\n requestId: action.requestId,\n sessionId,\n method: \"PATCH\",\n path: `/threads/${encodeURIComponent(action.threadId)}`,\n body: {\n ...commonBody,\n name: action.name,\n },\n });\n }\n\n if (threadAdapterEvents.archiveRequested.match(action)) {\n return createThreadMutationObservable(environment, context, {\n requestId: action.requestId,\n sessionId,\n method: \"POST\",\n path: `/threads/${encodeURIComponent(action.threadId)}/archive`,\n body: commonBody,\n });\n }\n\n if (threadAdapterEvents.unarchiveRequested.match(action)) {\n return createThreadMutationObservable(environment, context, {\n requestId: action.requestId,\n sessionId,\n method: \"PATCH\",\n path: `/threads/${encodeURIComponent(action.threadId)}`,\n body: {\n ...commonBody,\n archived: false,\n },\n });\n }\n\n return createThreadMutationObservable(environment, context, {\n requestId: action.requestId,\n sessionId,\n method: \"DELETE\",\n path: `/threads/${encodeURIComponent(action.threadId)}`,\n body: commonBody,\n });\n }),\n ),\n );\n\n const store = createStore<ThreadState>({\n reducer: threadReducer,\n effects: [\n bootstrapEffect,\n fetchEffect,\n metadataCredentialsEffect,\n metadataCredentialsFetchEffect,\n socketEffect,\n realtimeMappingEffect,\n socketDiagnosticsEffect,\n fetchNextPageEffect,\n mutationEffect,\n ],\n });\n\n function trackMutation(\n dispatchAction:\n | ReturnType<typeof threadAdapterEvents.renameRequested>\n | ReturnType<typeof threadAdapterEvents.archiveRequested>\n | ReturnType<typeof threadAdapterEvents.unarchiveRequested>\n | ReturnType<typeof threadAdapterEvents.deleteRequested>,\n ): Promise<void> {\n const completion$ = merge(\n store.actions$.pipe(\n ofType(threadRestEvents.mutationFinished),\n filter(\n (action) => action.outcome.requestId === dispatchAction.requestId,\n ),\n map((action) => action.outcome),\n ),\n store.actions$.pipe(\n ofType(threadAdapterEvents.stopped),\n map(\n () =>\n ({\n requestId: dispatchAction.requestId,\n sessionId: store.getState().sessionId,\n ok: false,\n error: new Error(\n \"Thread store stopped before mutation completed\",\n ),\n }) satisfies MutationOutcome,\n ),\n ),\n ).pipe(take(1));\n\n const resultPromise = firstValueFrom(completion$).then((outcome) => {\n if (outcome.ok) {\n return;\n }\n\n throw outcome.error;\n });\n\n store.dispatch(dispatchAction);\n return resultPromise;\n }\n\n // Surface mutation rejections to the optional environment callback. The\n // reducer has already applied any delete rollback by the time this fires\n // (the store reduces state before re-emitting the action), so consumers see\n // a consistent list when they react to the error.\n let errorSubscription: Subscription | null = null;\n const subscribeErrors = (): void => {\n if (!environment.onError || errorSubscription) {\n return;\n }\n\n errorSubscription = store.actions$\n .pipe(\n ofType(threadRestEvents.mutationFinished),\n // Drop stale-session failures: a mutation that rejects after a\n // `contextChanged` belongs to a context the user already left, so\n // surfacing it would fire onError for the wrong session. The reducer\n // applies the same guard before writing `state.error`.\n filter(\n (action) =>\n !action.outcome.ok &&\n action.outcome.sessionId === store.getState().sessionId,\n ),\n )\n .subscribe((action) => {\n if (!action.outcome.ok) {\n environment.onError?.(action.outcome.error);\n }\n });\n };\n\n return {\n start(): void {\n store.init();\n subscribeErrors();\n store.dispatch(threadAdapterEvents.started());\n },\n stop(): void {\n store.dispatch(threadAdapterEvents.stopped());\n errorSubscription?.unsubscribe();\n errorSubscription = null;\n store.stop();\n },\n setContext(context: ThreadRuntimeContext | null): void {\n store.dispatch(threadAdapterEvents.contextChanged({ context }));\n },\n refresh(): void {\n const { sessionId, context } = store.getState();\n if (!context) return;\n store.dispatch(threadRestEvents.listRequested({ sessionId }));\n },\n refetchThreads(): void {\n const { sessionId, context } = store.getState();\n if (!context) return;\n store.dispatch(threadRestEvents.listRequested({ sessionId }));\n },\n startNewThread(): void {\n store.dispatch(threadAdapterEvents.newThreadStarted());\n },\n fetchNextPage(): void {\n store.dispatch(threadAdapterEvents.fetchNextPageRequested());\n },\n renameThread(threadId: string, name: string): Promise<void> {\n return trackMutation(\n threadAdapterEvents.renameRequested({\n requestId: createThreadRequestId(),\n threadId,\n name,\n }),\n );\n },\n archiveThread(threadId: string): Promise<void> {\n return trackMutation(\n threadAdapterEvents.archiveRequested({\n requestId: createThreadRequestId(),\n threadId,\n }),\n );\n },\n unarchiveThread(threadId: string): Promise<void> {\n return trackMutation(\n threadAdapterEvents.unarchiveRequested({\n requestId: createThreadRequestId(),\n threadId,\n }),\n );\n },\n deleteThread(threadId: string): Promise<void> {\n return trackMutation(\n threadAdapterEvents.deleteRequested({\n requestId: createThreadRequestId(),\n threadId,\n }),\n );\n },\n subscribeToRunActivity(\n callback: (notification: ThreadRunActivityNotification) => void,\n ): Subscription {\n return store.actions$\n .pipe(\n ofType(threadSocketEvents.runActivityReceived),\n filter((action) => action.sessionId === store.getState().sessionId),\n map((action) => action.notification),\n )\n .subscribe(callback);\n },\n getState(): ThreadState {\n return store.getState();\n },\n getServerState(): ThreadState {\n return initialThreadState;\n },\n select: store.select.bind(store),\n selectors,\n };\n}\n\nexport type ɵThread = ThreadRecord;\nexport type ɵThreadRuntimeContext = ThreadRuntimeContext;\nexport type ɵThreadMetadataEvent = ThreadMetadataEvent;\nexport type ɵThreadEnvironment = ThreadEnvironment;\nexport type ɵThreadStore = ThreadStore;\nexport type ɵThreadSelectors = ThreadSelectors;\nexport const ɵthreadAdapterEvents = threadAdapterEvents;\nexport const ɵcreateThreadSelectors = createThreadSelectors;\nexport const ɵselectThreads = selectThreads;\nexport const ɵselectThreadsIsLoading = selectThreadsIsLoading;\nexport const ɵselectThreadsError = selectThreadsError;\nexport const ɵselectFetchMoreError = selectFetchMoreError;\nexport const ɵselectHasNextPage = selectHasNextPage;\nexport const ɵselectIsFetchingNextPage = selectIsFetchingNextPage;\nexport const ɵselectIsMutating = selectIsMutating;\nexport { createThreadStore as ɵcreateThreadStore };\n/**\n * Number of consecutive WebSocket connection failures after which the\n * threads channel tears itself down rather than retrying indefinitely.\n * Exposed for tests so they can assert teardown semantics without\n * hardcoding the threshold separately from production.\n */\nexport const ɵMAX_SOCKET_RETRIES = MAX_SOCKET_RETRIES;\n/**\n * How long a thread REST request is given before the store gives up on it.\n * Exposed for tests for the same reason as {@link ɵMAX_SOCKET_RETRIES}: a\n * separately hardcoded copy silently drifts away from this one.\n */\nexport const ɵTHREAD_REQUEST_TIMEOUT_MS = REQUEST_TIMEOUT_MS;\n","/**\n * Central registry of CopilotKit feature names.\n *\n * Feature names are the strings passed to a license context's `checkFeature`\n * (see `@copilotkit/shared`'s `LicenseContextValue`). Historically the only\n * features referenced by literal were the chat surfaces (`chat`, `sidebar`,\n * `popup`); this module makes the set explicit and typed so new surfaces —\n * such as the threads drawer — register a real, discoverable feature name\n * rather than an ad-hoc string scattered across components.\n *\n * `checkFeature` itself still accepts any `string` for backward compatibility;\n * this registry simply documents and types the names CopilotKit recognises.\n */\n\n/**\n * The set of feature names CopilotKit recognises.\n *\n * Frozen so the array cannot be mutated at runtime. Add new surfaces here when\n * they begin gating behaviour on `checkFeature`.\n */\nexport const ɵCOPILOTKIT_FEATURES = Object.freeze([\n \"chat\",\n \"sidebar\",\n \"popup\",\n \"threads\",\n] as const);\n\n/**\n * Union of recognised CopilotKit feature names.\n */\nexport type ɵCopilotKitFeature = (typeof ɵCOPILOTKIT_FEATURES)[number];\n\nconst FEATURE_SET: ReadonlySet<string> = new Set(ɵCOPILOTKIT_FEATURES);\n\n/**\n * Type guard: returns `true` when `name` is a recognised CopilotKit feature.\n *\n * @param name - Candidate feature name.\n * @returns Whether `name` is a registered feature.\n *\n * @example\n * ```ts\n * if (ɵisCopilotKitFeature(\"threads\")) {\n * // narrowed to ɵCopilotKitFeature\n * }\n * ```\n */\nexport function ɵisCopilotKitFeature(name: string): name is ɵCopilotKitFeature {\n return FEATURE_SET.has(name);\n}\n","import { buildResumeArray, isInterruptExpired } from \"@ag-ui/client\";\nimport type { Interrupt, ResumeEntry } from \"@ag-ui/client\";\n\ntype ResumeResponse =\n | { status: \"resolved\"; payload?: unknown }\n | { status: \"cancelled\" };\n\n/** @internal Application authors must not depend on this contract. */\nexport interface ɵInterruptEvent<TValue = unknown> {\n name: string;\n value: TValue;\n}\n\n/** @internal Application authors must not depend on this contract. */\nexport type ɵPendingInterrupt<TValue = unknown> =\n | { kind: \"legacy\"; event: ɵInterruptEvent<TValue> }\n | { kind: \"standard\"; interrupts: readonly Interrupt[] };\n\n/** @internal Application authors must not depend on this contract. */\nexport interface ɵInterruptToolResult {\n toolCallId: string;\n content: string;\n}\n\n/** @internal Application authors must not depend on this contract. */\nexport type ɵInterruptDecision =\n | { kind: \"ignored\" }\n | { kind: \"waiting\" }\n | { kind: \"dismiss\" }\n | {\n kind: \"expired\";\n interrupt: Interrupt;\n }\n | {\n kind: \"legacy-resume\";\n payload: unknown;\n interruptValue: unknown;\n }\n | {\n kind: \"resume\";\n resume: ResumeEntry[];\n toolResults: ɵInterruptToolResult[];\n };\n\nfunction toolResultContent(response: ResumeResponse): string {\n if (response.status === \"cancelled\") {\n return JSON.stringify({ status: \"cancelled\" });\n }\n return JSON.stringify(response.payload ?? { status: \"resolved\" });\n}\n\n/**\n * @internal Framework-neutral interrupt response state shared by framework\n * adapters. Application authors must not depend on this API.\n */\nexport class ɵInterruptState<TValue = unknown> {\n readonly #responses: Record<string, ResumeResponse> = {};\n #pending: ɵPendingInterrupt<TValue> | null = null;\n #sealed = false;\n\n /** Return the active normalized interrupt without exposing mutable state. */\n get pending(): ɵPendingInterrupt<TValue> | null {\n const pending = this.#pending;\n if (pending?.kind === \"standard\") {\n return { kind: \"standard\", interrupts: [...pending.interrupts] };\n }\n return pending;\n }\n\n /** Replace the current interrupt with a legacy custom-event interrupt. */\n setLegacy(event: ɵInterruptEvent<TValue>): void {\n this.#replace({ kind: \"legacy\", event });\n }\n\n /** Replace the current interrupt with an AG-UI standard interrupt set. */\n setStandard(interrupts: readonly Interrupt[]): void {\n this.#replace({ kind: \"standard\", interrupts: [...interrupts] });\n }\n\n /** Clear all pending interrupt data and accumulated responses. */\n clear(): void {\n this.#pending = null;\n this.#sealed = false;\n for (const id of Object.keys(this.#responses)) delete this.#responses[id];\n }\n\n /** Record a resolved response and return the next framework action. */\n resolve(payload?: unknown, interruptId?: string): ɵInterruptDecision {\n const pending = this.#pending;\n if (!pending || this.#sealed) return { kind: \"ignored\" };\n if (pending.kind === \"legacy\") {\n this.#sealed = true;\n return {\n kind: \"legacy-resume\",\n payload,\n interruptValue: pending.event.value,\n };\n }\n return this.#respond(pending.interrupts, interruptId, {\n status: \"resolved\",\n payload,\n });\n }\n\n /** Record a cancelled response and return the next framework action. */\n cancel(interruptId?: string): ɵInterruptDecision {\n const pending = this.#pending;\n if (!pending || this.#sealed) return { kind: \"ignored\" };\n if (pending.kind === \"legacy\") {\n this.#sealed = true;\n return { kind: \"dismiss\" };\n }\n return this.#respond(pending.interrupts, interruptId, {\n status: \"cancelled\",\n });\n }\n\n #replace(pending: ɵPendingInterrupt<TValue>): void {\n this.clear();\n this.#pending = pending;\n }\n\n #respond(\n interrupts: readonly Interrupt[],\n interruptId: string | undefined,\n response: ResumeResponse,\n ): ɵInterruptDecision {\n const id = interruptId ?? interrupts[0]?.id;\n if (!id || !interrupts.some((interrupt) => interrupt.id === id)) {\n return { kind: \"ignored\" };\n }\n this.#responses[id] = response;\n if (!interrupts.every((interrupt) => this.#responses[interrupt.id])) {\n return { kind: \"waiting\" };\n }\n\n const expired = interrupts.find((interrupt) =>\n isInterruptExpired(interrupt),\n );\n if (expired) {\n this.#sealed = true;\n return { kind: \"expired\", interrupt: expired };\n }\n\n const mutableInterrupts = [...interrupts];\n const resume = buildResumeArray(mutableInterrupts, this.#responses);\n const toolResults = mutableInterrupts.flatMap((interrupt) => {\n if (!interrupt.toolCallId || interrupt.reason !== \"tool_call\") return [];\n return [\n {\n toolCallId: interrupt.toolCallId,\n content: toolResultContent(this.#responses[interrupt.id]!),\n },\n ];\n });\n this.#sealed = true;\n return { kind: \"resume\", resume, toolResults };\n }\n}\n","export const INSPECTOR_THREAD_BRIDGE_PLUGIN_ID =\n \"cpk-inspector-thread\" as const;\n\nconst EVENT_PREFIX = `copilotkit:${INSPECTOR_THREAD_BRIDGE_PLUGIN_ID}`;\n\ntype InspectorBridgeGlobal = typeof globalThis & {\n __COPILOTKIT_INSPECTOR_THREAD_EVENT_TARGET__?: EventTarget;\n};\n\nexport type InspectorViewThreadPayload = {\n requestId: string;\n threadId: string;\n agentId: string;\n};\n\nexport type InspectorStopViewingPayload = {\n requestId: string;\n agentId: string;\n};\n\nexport type InspectorActiveThreadPayload = {\n requestId: string;\n threadId: string;\n agentId: string;\n source: \"app\" | \"override\";\n};\n\nexport type InspectorViewThreadResultPayload =\n | {\n requestId: string;\n threadId: string;\n agentId: string;\n ok: true;\n }\n | {\n requestId: string;\n threadId: string;\n agentId: string;\n ok: false;\n reason: \"connect-failed\";\n };\n\ntype InspectorThreadBridgeEvents = {\n \"stop-viewing\": InspectorStopViewingPayload;\n \"active-thread\": InspectorActiveThreadPayload;\n \"view-thread-result\": InspectorViewThreadResultPayload;\n};\n\ntype ClaimableViewThreadEvent = {\n payload: InspectorViewThreadPayload;\n claimed: boolean;\n};\n\nfunction eventName(suffix: string): string {\n return `${EVENT_PREFIX}:${suffix}`;\n}\n\nfunction getEventTarget(): EventTarget | null {\n if (\n typeof window !== \"undefined\" &&\n typeof window.addEventListener === \"function\"\n ) {\n return window;\n }\n if (typeof EventTarget === \"undefined\") return null;\n // Shared by duplicate @copilotkit/core copies in non-browser test realms.\n // Browser copies use window itself as the shared event target.\n const sharedGlobal = globalThis as InspectorBridgeGlobal;\n sharedGlobal.__COPILOTKIT_INSPECTOR_THREAD_EVENT_TARGET__ ??=\n new EventTarget();\n return sharedGlobal.__COPILOTKIT_INSPECTOR_THREAD_EVENT_TARGET__;\n}\n\nfunction createDetailEvent<T>(name: string, detail: T): Event {\n if (typeof CustomEvent !== \"undefined\") {\n return new CustomEvent(name, { detail });\n }\n const event = new Event(name);\n Object.defineProperty(event, \"detail\", { value: detail });\n return event;\n}\n\nfunction detailFromEvent<T>(event: Event): T {\n return (event as Event & { detail: T }).detail;\n}\n\n/** The Inspector thread bridge is development-only. */\nexport function isInspectorThreadBridgeEnabled(): boolean {\n return process.env.NODE_ENV !== \"production\";\n}\n\nexport function createInspectorThreadRequestId(): string {\n if (typeof crypto !== \"undefined\" && \"randomUUID\" in crypto) {\n return crypto.randomUUID();\n }\n return `inspector-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n}\n\nfunction dispatch<K extends keyof InspectorThreadBridgeEvents>(\n suffix: K,\n payload: InspectorThreadBridgeEvents[K],\n): void {\n if (!isInspectorThreadBridgeEnabled()) return;\n const target = getEventTarget();\n if (!target) return;\n target.dispatchEvent(createDetailEvent(eventName(suffix), payload));\n}\n\nfunction on<K extends keyof InspectorThreadBridgeEvents>(\n suffix: K,\n handler: (payload: InspectorThreadBridgeEvents[K]) => void,\n): () => void {\n if (!isInspectorThreadBridgeEnabled()) return () => undefined;\n const target = getEventTarget();\n if (!target) return () => undefined;\n const listener = (event: Event) => {\n handler(detailFromEvent<InspectorThreadBridgeEvents[K]>(event));\n };\n const name = eventName(suffix);\n target.addEventListener(name, listener);\n return () => target.removeEventListener(name, listener);\n}\n\n/**\n * Ask the first mounted official chat for the matching agent to load a thread.\n * Returns false when no chat claims the request synchronously.\n */\nexport function emitInspectorViewThread(\n payload: InspectorViewThreadPayload,\n): boolean {\n if (!isInspectorThreadBridgeEnabled()) return false;\n const target = getEventTarget();\n if (!target) return false;\n const detail: ClaimableViewThreadEvent = { payload, claimed: false };\n target.dispatchEvent(createDetailEvent(eventName(\"view-thread\"), detail));\n return detail.claimed;\n}\n\nexport function emitInspectorStopViewing(\n payload: InspectorStopViewingPayload,\n): void {\n dispatch(\"stop-viewing\", payload);\n}\n\nexport function emitInspectorActiveThread(\n payload: InspectorActiveThreadPayload,\n): void {\n dispatch(\"active-thread\", payload);\n}\n\nexport function emitInspectorViewThreadResult(\n payload: InspectorViewThreadResultPayload,\n): void {\n dispatch(\"view-thread-result\", payload);\n}\n\nexport function onInspectorViewThread(\n handler: (payload: InspectorViewThreadPayload) => boolean,\n): () => void {\n if (!isInspectorThreadBridgeEnabled()) return () => undefined;\n const target = getEventTarget();\n if (!target) return () => undefined;\n const listener = (event: Event) => {\n const detail = detailFromEvent<ClaimableViewThreadEvent>(event);\n if (detail.claimed) return;\n detail.claimed = handler(detail.payload);\n };\n const name = eventName(\"view-thread\");\n target.addEventListener(name, listener);\n return () => target.removeEventListener(name, listener);\n}\n\nexport function onInspectorStopViewing(\n handler: (payload: InspectorStopViewingPayload) => void,\n): () => void {\n return on(\"stop-viewing\", handler);\n}\n\nexport function onInspectorActiveThread(\n handler: (payload: InspectorActiveThreadPayload) => void,\n): () => void {\n return on(\"active-thread\", handler);\n}\n\nexport function onInspectorViewThreadResult(\n handler: (payload: InspectorViewThreadResultPayload) => void,\n): () => void {\n return on(\"view-thread-result\", handler);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.umd.js","names":["Subject","AGUIConnectNotImplementedError","EMPTY","Observable","Socket","NEVER","EMPTY","AbstractAgent","EMPTY","EventType","Notification","isAbortError","EMPTY","HttpAgent","RUNTIME_MODE_SSE","RUNTIME_MODE_INTELLIGENCE","isAbortError","isAbortError","RUNTIME_MODE_SSE","HttpAgent","HttpAgent","isAbortError","Subscription","BehaviorSubject","Subject","asapScheduler","REQUEST_TIMEOUT_MS","MAX_SOCKET_RETRIES","Observable","EMPTY","asapScheduler","ɵcreateMemoryStore","Throttler","Observable","on"],"sources":["../src/utils/connect-replay.ts","../src/utils/phoenix-observable.ts","../src/intelligence-agent.ts","../src/utils/runtime-info-error.ts","../src/core/message-filter.ts","../src/agent.ts","../src/utils/abort-error.ts","../src/utils/runtime-request.ts","../src/utils/single-route-resource-request.ts","../src/core/agent-registry.ts","../src/core/context-store.ts","../src/core/suggestion-engine.ts","../src/core/tool-result-content.ts","../src/core/tool-schema.ts","../src/core/webmcp.ts","../src/core/run-handler.ts","../src/core/state-manager.ts","../src/core/thread-store-registry.ts","../src/utils/micro-redux.ts","../src/memory-errors.ts","../src/memory.ts","../src/core/core.ts","../src/types.ts","../src/utils/markdown.ts","../src/threads.ts","../src/features.ts","../src/interrupt-state.ts","../src/inspector-thread-bridge.ts"],"sourcesContent":["import type {\n AbstractAgent,\n AgentSubscriber,\n BaseEvent,\n RunAgentParameters,\n RunAgentResult,\n} from \"@ag-ui/client\";\nimport {\n AGUIConnectNotImplementedError,\n randomUUID,\n structuredClone_,\n transformChunks,\n} from \"@ag-ui/client\";\nimport type { Observable } from \"rxjs\";\nimport { EMPTY, Subject, defer, lastValueFrom } from \"rxjs\";\nimport { catchError, finalize, takeUntil } from \"rxjs/operators\";\n\n/**\n * Runs an agent's `connect()` stream through the AbstractAgent apply pipeline\n * with the `verifyEvents` step omitted.\n *\n * `verifyEvents` enforces AG-UI's *single run* lifecycle rules: exactly one\n * RUN_STARTED opening the stream, no events after a terminal RUN_FINISHED /\n * RUN_ERROR. Those rules are correct for `/run`, but a `/connect` response is a\n * replay of a thread's history and can legitimately carry several past runs\n * back to back — including a run that ended in RUN_ERROR followed by a later\n * RUN_STARTED. Verifying a replay against single-run rules makes hydration of\n * an existing thread fail outright:\n *\n * Cannot send event type 'RUN_STARTED': The run has already errored with\n * 'RUN_ERROR'. No further events can be sent.\n *\n * `transformChunks` is still applied — message reassembly is needed either way.\n *\n * This mirrors the base `AbstractAgent.connectAgent` implementation exactly\n * apart from that omission, so callers keep the same subscriber notifications,\n * detach semantics, and `{ result, newMessages }` return shape.\n *\n * TODO: Remove this in favour of the base implementation once AG-UI's\n * AbstractAgent supports opting out of `verifyEvents` for transports whose\n * connection life-cycle isn't a single run. As of `@ag-ui/client@0.0.57`\n * `connectAgent(parameters?, subscriber?)` takes no such option.\n *\n * @param agent - The agent whose `connect()` stream should be consumed.\n * @param parameters - Run parameters, forwarded to `prepareRunAgentInput`.\n * @param subscriber - Optional one-shot subscriber for this connect call.\n */\nexport async function ɵconnectWithoutEventVerification(\n agent: AbstractAgent,\n parameters?: RunAgentParameters,\n subscriber?: AgentSubscriber,\n): Promise<RunAgentResult> {\n // Access protected/private members through a type escape hatch — they are\n // set and read by the base class and must be managed identically to the\n // original implementation. `any` is required because these fields are\n // private in AbstractAgent, and intersecting private+public members of the\n // same name produces `never`.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const self = agent as any;\n\n try {\n agent.isRunning = true;\n agent.agentId = agent.agentId ?? randomUUID();\n\n const input = self.prepareRunAgentInput(parameters);\n let result: RunAgentResult[\"result\"];\n const previousMessageIds = new Set(agent.messages.map((m) => m.id));\n const subscribers: AgentSubscriber[] = [\n {\n onRunFinishedEvent: (event) => {\n if (event.outcome === \"success\") {\n result = event.result;\n }\n },\n },\n ...agent.subscribers,\n subscriber ?? {},\n ];\n\n await self.onInitialize(input, subscribers);\n\n self.activeRunDetach$ = new Subject<void>();\n let resolveCompletion: (() => void) | undefined;\n self.activeRunCompletionPromise = new Promise<void>((resolve) => {\n resolveCompletion = resolve;\n });\n\n const source$ = defer(\n () => self.connect(input) as Observable<BaseEvent>,\n ).pipe(\n // transformChunks reassembles partial/streamed messages — still needed.\n transformChunks(self.debugLogger),\n // NOTE: verifyEvents is intentionally omitted here. See JSDoc above.\n takeUntil(self.activeRunDetach$),\n );\n\n const applied$ = self.apply(input, source$, subscribers);\n const processed$ = self.processApplyEvents(input, applied$, subscribers);\n\n await lastValueFrom(\n processed$.pipe(\n catchError((error: unknown) => {\n agent.isRunning = false;\n // An agent that doesn't implement connect() is not an error worth\n // surfacing: the base pipeline swallows it, and callers rely on that.\n // `CopilotKitCore` awaits `detachActiveRun()` before every run, which\n // only resolves because this path still reaches the finalize block\n // below (see the historical note in run-handler.ts). Routing it\n // through onError would also fire run-failure callbacks on every\n // subscriber for a benign condition.\n if (error instanceof AGUIConnectNotImplementedError) {\n return EMPTY;\n }\n return self.onError(input, error, subscribers);\n }),\n finalize(() => {\n agent.isRunning = false;\n void self.onFinalize(input, subscribers);\n resolveCompletion?.();\n resolveCompletion = undefined;\n self.activeRunCompletionPromise = undefined;\n self.activeRunDetach$ = undefined;\n }),\n ),\n { defaultValue: undefined },\n );\n\n const newMessages = structuredClone_(agent.messages).filter(\n (m) => !previousMessageIds.has(m.id),\n );\n return { result, newMessages };\n } finally {\n agent.isRunning = false;\n }\n}\n","import { Socket } from \"phoenix\";\nimport { EMPTY, NEVER, Observable, concat, defer, of, throwError } from \"rxjs\";\nimport {\n filter,\n finalize,\n mergeMap,\n scan,\n shareReplay,\n switchMap,\n take,\n} from \"rxjs/operators\";\n\n/**\n * Minimal Phoenix push contract used by the observable adapters.\n */\nexport interface ɵPhoenixPushLike {\n receive(\n status: string,\n callback: (payload?: unknown) => unknown,\n ): ɵPhoenixPushLike;\n}\n\n/**\n * Minimal Phoenix channel contract used by the observable adapters.\n */\nexport interface ɵPhoenixChannelLike {\n on(event: string, callback: (payload: unknown) => void): number;\n off(event: string, ref?: number): void;\n onError?(callback: (reason?: unknown) => void): unknown;\n join(params?: Record<string, unknown>): ɵPhoenixPushLike;\n push?(event: string, payload: unknown): ɵPhoenixPushLike;\n leave(): void;\n}\n\n/**\n * Minimal Phoenix socket contract used by the observable adapters.\n */\nexport interface ɵPhoenixSocketLike {\n connect(): void;\n disconnect(): void;\n channel(topic: string, params?: Record<string, unknown>): ɵPhoenixChannelLike;\n onError(callback: (error?: unknown) => void): unknown;\n onOpen(callback: () => void): unknown;\n}\n\n/**\n * Socket lifecycle notifications exposed by {@link ɵphoenixSocket$}.\n */\nexport type ɵPhoenixSocketSignal =\n | { type: \"open\" }\n | { type: \"error\"; error?: unknown };\n\n/**\n * Terminal outcomes of a Phoenix channel join attempt.\n */\nexport type ɵPhoenixJoinOutcome =\n | { type: \"joined\" }\n | { type: \"error\"; response?: unknown }\n | { type: \"timeout\" };\n\n/**\n * Active Phoenix socket session plus its derived lifecycle stream.\n */\nexport interface ɵPhoenixSocketSession {\n socket: ɵPhoenixSocketLike;\n signals$: Observable<ɵPhoenixSocketSignal>;\n}\n\n/**\n * Active Phoenix channel session plus its derived join-outcome stream.\n */\nexport interface ɵPhoenixChannelSession {\n channel: ɵPhoenixChannelLike;\n joinOutcome$: Observable<ɵPhoenixJoinOutcome>;\n}\n\n/**\n * Options for creating a cold Phoenix socket session stream.\n */\nexport interface ɵPhoenixSocketOptions {\n url: string;\n options?: Record<string, unknown>;\n}\n\n/**\n * Options for creating a cold Phoenix channel session stream from a socket stream.\n */\nexport interface ɵPhoenixChannelOptions {\n socket$: Observable<ɵPhoenixSocketSession>;\n topic: string;\n params?: Record<string, unknown>;\n leaveOnUnsubscribe?: boolean;\n}\n\n/**\n * Adapt Phoenix socket open/error callbacks into an observable signal stream.\n *\n * The returned observable is shared and replayable by the caller when needed,\n * but this helper itself does not own socket connection teardown.\n */\nfunction ɵcreatePhoenixSocketSignals$(\n socket: ɵPhoenixSocketLike,\n): Observable<ɵPhoenixSocketSignal> {\n return new Observable<ɵPhoenixSocketSignal>((observer) => {\n socket.onOpen(() => observer.next({ type: \"open\" }));\n socket.onError((error) => observer.next({ type: \"error\", error }));\n });\n}\n\n/**\n * Adapt a Phoenix channel join attempt into a single-outcome observable.\n */\nfunction ɵcreatePhoenixJoinOutcome$(\n channel: ɵPhoenixChannelLike,\n): Observable<ɵPhoenixJoinOutcome> {\n return new Observable<ɵPhoenixJoinOutcome>((observer) => {\n channel\n .join()\n .receive(\"ok\", () => {\n observer.next({ type: \"joined\" });\n observer.complete();\n })\n .receive(\"error\", (response?: unknown) => {\n observer.next({ type: \"error\", response });\n observer.complete();\n })\n .receive(\"timeout\", () => {\n observer.next({ type: \"timeout\" });\n observer.complete();\n });\n });\n}\n\n/**\n * Create a cold Phoenix socket session.\n *\n * The socket is constructed and connected on subscription, and disconnected on\n * teardown. Each subscription creates an isolated socket instance.\n */\nexport function ɵphoenixSocket$(\n options: ɵPhoenixSocketOptions,\n): Observable<ɵPhoenixSocketSession> {\n return defer(() => {\n const socket = new Socket(\n options.url,\n options.options as ConstructorParameters<typeof Socket>[1],\n ) as ɵPhoenixSocketLike;\n const signals$ = ɵcreatePhoenixSocketSignals$(socket).pipe(\n shareReplay({ bufferSize: 1, refCount: true }),\n );\n\n socket.connect();\n\n return concat(\n of({\n socket,\n signals$,\n }),\n NEVER,\n ).pipe(finalize(() => socket.disconnect()));\n });\n}\n\n/**\n * Create a cold Phoenix channel session from a socket session stream.\n *\n * A channel is created and joined for each active socket session. If the\n * upstream socket session changes, the previous channel is left before the\n * next one becomes active.\n */\nexport function ɵphoenixChannel$(\n options: ɵPhoenixChannelOptions,\n): Observable<ɵPhoenixChannelSession> {\n return options.socket$.pipe(\n switchMap(({ socket }) =>\n defer(() => {\n const channel = socket.channel(options.topic, options.params);\n const joinOutcome$ = ɵcreatePhoenixJoinOutcome$(channel).pipe(\n shareReplay({ bufferSize: 1, refCount: true }),\n );\n\n return concat(\n of({\n channel,\n joinOutcome$,\n }),\n NEVER,\n ).pipe(\n finalize(() => {\n if (options.leaveOnUnsubscribe !== false) {\n channel.leave();\n }\n }),\n );\n }),\n ),\n );\n}\n\n/**\n * Observe a named Phoenix channel event as an observable payload stream.\n */\nexport function ɵobservePhoenixEvent$<T>(\n channel: ɵPhoenixChannelLike,\n eventName: string,\n): Observable<T> {\n return new Observable<T>((observer) => {\n const ref = channel.on(eventName, (payload) => observer.next(payload as T));\n\n return () => {\n channel.off(eventName, ref);\n };\n });\n}\n\n/**\n * Flatten channel sessions into their join-outcome stream.\n */\nexport function ɵobservePhoenixJoinOutcome$(\n channel$: Observable<ɵPhoenixChannelSession>,\n): Observable<ɵPhoenixJoinOutcome> {\n return channel$.pipe(switchMap((session) => session.joinOutcome$));\n}\n\n/**\n * Complete when a channel joins successfully, or error if the join fails.\n */\nexport function ɵjoinPhoenixChannel$(\n channel$: Observable<ɵPhoenixChannelSession>,\n): Observable<never> {\n return ɵobservePhoenixJoinOutcome$(channel$).pipe(\n take(1),\n mergeMap((outcome) => {\n if (outcome.type === \"joined\") {\n return EMPTY;\n }\n\n throw outcome.type === \"timeout\"\n ? new Error(\"Timed out joining channel\")\n : new Error(\n `Failed to join channel: ${JSON.stringify(outcome.response)}`,\n );\n }),\n );\n}\n\n/**\n * Flatten socket sessions into their lifecycle signal stream.\n */\nexport function ɵobservePhoenixSocketSignals$(\n socket$: Observable<ɵPhoenixSocketSession>,\n): Observable<ɵPhoenixSocketSignal> {\n return socket$.pipe(switchMap((session) => session.signals$));\n}\n\n/**\n * Error after a socket emits the configured number of consecutive error\n * signals, resetting the counter after each successful open signal.\n */\nexport function ɵobservePhoenixSocketHealth$(\n socketSignals$: Observable<ɵPhoenixSocketSignal>,\n maxConsecutiveErrors: number,\n): Observable<never> {\n return socketSignals$.pipe(\n scan(\n (consecutiveErrors, signal) =>\n signal.type === \"open\" ? 0 : consecutiveErrors + 1,\n 0,\n ),\n filter((consecutiveErrors) => consecutiveErrors >= maxConsecutiveErrors),\n take(1),\n mergeMap((consecutiveErrors) =>\n throwError(\n () =>\n new Error(\n `WebSocket connection failed after ${consecutiveErrors} consecutive errors`,\n ),\n ),\n ),\n );\n}\n","import type {\n RunAgentInput,\n RunAgentParameters,\n RunAgentResult,\n AgentSubscriber,\n BaseEvent,\n} from \"@ag-ui/client\";\nimport { AbstractAgent, EventType } from \"@ag-ui/client\";\n\nimport {\n EMPTY,\n Notification,\n combineLatest,\n defer,\n dematerialize,\n merge,\n switchMap,\n throwError,\n} from \"rxjs\";\nimport type { ObservableNotification, Observable } from \"rxjs\";\nimport {\n catchError,\n delay,\n endWith,\n filter,\n finalize,\n ignoreElements,\n mergeMap,\n share,\n shareReplay,\n switchMap as switchMapOperator,\n take,\n takeUntil,\n tap,\n} from \"rxjs/operators\";\nimport { phoenixExponentialBackoff } from \"@copilotkit/shared\";\nimport { ɵconnectWithoutEventVerification } from \"./utils/connect-replay\";\nimport {\n ɵphoenixChannel$,\n ɵphoenixSocket$,\n ɵjoinPhoenixChannel$,\n ɵobservePhoenixSocketSignals$,\n ɵobservePhoenixSocketHealth$,\n ɵobservePhoenixEvent$,\n} from \"./utils/phoenix-observable\";\nimport type {\n ɵPhoenixChannelLike,\n ɵPhoenixChannelSession,\n ɵPhoenixPushLike,\n ɵPhoenixSocketLike,\n ɵPhoenixSocketSession,\n} from \"./utils/phoenix-observable\";\n\n/**\n * Structural Phoenix socket/channel contracts used by this agent, derived from\n * the minimal `*Like` interfaces in {@link ./utils/phoenix-observable}.\n */\ntype Socket = ɵPhoenixSocketLike;\n\ninterface Channel extends ɵPhoenixChannelLike {\n push(event: string, payload: unknown): ɵPhoenixPushLike;\n}\n\nconst globalFetch: typeof fetch = (...args) => fetch(...args);\n\nconst CLIENT_AG_UI_EVENT = \"ag_ui_event\";\nconst REPLAY_COMPLETE_EVENT = \"replay_complete\";\nconst REPLAY_FAILED_EVENT = \"replay_failed\";\nconst STREAM_IDLE_EVENT = \"stream_idle\";\nconst STOP_RUN_EVENT = \"stop_run\";\nconst CONNECT_STREAM_IDLE_REPLAY_FALLBACK_MS = 100;\n// Credential refreshes allowed in a row for sockets that never opened. Past this,\n// the run fails instead of waiting on a realtime endpoint that is not answering.\nconst MAX_UNOPENED_CREDENTIAL_REFRESHES = 2;\n\ninterface IntelligenceAgentSharedState {\n lastSeenEventIds: Map<string, string>;\n}\n\n/** Control-frame cursor state for one channel join. */\ninterface ControlCursorState {\n /** The last `latestEventId` that this join saved as the reconnect cursor. */\n applied: string | null;\n /** True after `replay_failed`. The gateway then repeats the prior cursor on purpose. */\n replayFailed: boolean;\n}\n\ninterface RealtimeConnectionInfo {\n clientUrl: string;\n topic: string;\n}\n\ninterface ThreadJoinCredentials {\n threadId: string;\n runId: string | null;\n joinToken: string;\n realtime: RealtimeConnectionInfo;\n}\n\nexport class AgentThreadLockedError extends Error {\n constructor(threadId?: string) {\n super(threadId ? `Thread ${threadId} is locked` : \"Thread is locked\");\n this.name = \"AgentThreadLockedError\";\n }\n}\n\n/**\n * Typed contract for agents that expose the completion promise of their\n * currently in-flight run.\n *\n * `IntelligenceAgent` resolves this promise once a run's observable pipeline\n * finalizes (see {@link IntelligenceAgent.connectAgent}). Consumers (e.g. the\n * v2 `CopilotChat` send-serialization path) await it to let an in-flight run —\n * notably an interrupt RESUME — finish before dispatching a new run, instead\n * of pre-empting it.\n *\n * The base `AbstractAgent` from `@ag-ui/client` only declares this property\n * privately, so it is reachable only through this contract plus the\n * {@link isRunCompletionAware} type guard. This keeps callers off `as unknown`\n * casts while still degrading safely for agents that don't implement it.\n */\nexport interface RunCompletionAware {\n /**\n * Resolves when the active run's pipeline finalizes (completes, errors, or is\n * detached). `undefined` when no run is in flight.\n */\n readonly activeRunCompletionPromise?: Promise<void>;\n}\n\n/**\n * Type guard for {@link RunCompletionAware}. Returns true when `agent` exposes\n * an `activeRunCompletionPromise` property, so callers can await an in-flight\n * run without an `as unknown as` cast. Returns false for agents that don't\n * implement the contract, letting the caller skip the await and degrade safely.\n */\nexport function isRunCompletionAware(\n agent: unknown,\n): agent is RunCompletionAware {\n return (\n typeof agent === \"object\" &&\n agent !== null &&\n \"activeRunCompletionPromise\" in agent\n );\n}\n\nexport interface IntelligenceAgentConfig {\n /** Phoenix websocket URL, e.g. \"ws://localhost:4000/socket\" */\n url: string;\n /** Runtime base URL, e.g. \"http://localhost:4000\" */\n runtimeUrl: string;\n /** HTTP transport for run/connect requests. Defaults to REST. */\n transport?: \"rest\" | \"single\";\n /** Agent identifier for REST endpoints */\n agentId: string;\n /** Optional params sent on socket connect (e.g. auth token) */\n socketParams?: Record<string, string>;\n /** Optional headers sent with REST requests */\n headers?: Record<string, string>;\n /** Optional credentials mode for fetch requests */\n credentials?: RequestCredentials;\n fetch?: typeof fetch;\n}\n\nexport class IntelligenceAgent extends AbstractAgent {\n private config: IntelligenceAgentConfig;\n private socket: Socket | null = null;\n private activeChannel: Channel | null = null;\n private canonicalRunId: string | null = null;\n private sharedState: IntelligenceAgentSharedState;\n\n constructor(\n config: IntelligenceAgentConfig,\n sharedState: IntelligenceAgentSharedState = {\n lastSeenEventIds: new Map<string, string>(),\n },\n ) {\n super();\n this.config = config;\n this.sharedState = sharedState;\n }\n\n /**\n * Headers sent with the REST join requests (`/connect`, `/run`).\n *\n * Deliberately a public accessor pair rather than a plain read of `config`.\n * `ProxiedCopilotRuntimeAgent` builds its delegate once and caches it for the\n * proxy's lifetime, so a header that changes later (a tenant switch, a\n * rotated bearer) would otherwise never reach the gateway. The accessor is\n * what closes that gap: `syncDelegate` refreshes the delegate before every\n * join, and its `hasHeaders` probe is an `\"headers\" in agent` check — which a\n * prototype accessor satisfies but a `private config` does not.\n *\n * The setter replaces the config object instead of mutating it because\n * `clone()` hands the same config reference to the copy. An in-place write\n * would therefore have a per-thread clone's headers land on the original's\n * config too. The join path itself would survive that (`syncDelegate`\n * rewrites the headers just before every join), but the re-acquisition inside\n * an already-running pipeline does not go through `syncDelegate` — so a\n * clone's tenant could ride out on the original's socket-error refresh. That\n * is the same cross-tenant leak this accessor exists to prevent.\n */\n get headers(): Record<string, string> | undefined {\n return this.config.headers;\n }\n\n set headers(headers: Record<string, string> | undefined) {\n this.config = { ...this.config, headers };\n }\n\n /** Credentials mode for the REST join requests. Live for the same reason as {@link headers}. */\n get credentials(): RequestCredentials | undefined {\n return this.config.credentials;\n }\n\n set credentials(credentials: RequestCredentials | undefined) {\n this.config = { ...this.config, credentials };\n }\n\n clone(): IntelligenceAgent {\n return new IntelligenceAgent(this.config, this.sharedState);\n }\n\n /**\n * Override of AbstractAgent.connectAgent that removes the `verifyEvents` step.\n *\n * IntelligenceAgent uses long-lived WebSocket connections rather than\n * request-scoped SSE streams. When connecting to replay historical messages\n * for an existing thread, the connection semantics don't map to a single\n * agent run start/stop cycle: the replayed events may omit the\n * RUN_STARTED/RUN_FINISHED bookends, or carry events from several past runs,\n * either of which makes `verifyEvents` stall or error out.\n *\n * See {@link ɵconnectWithoutEventVerification} for the pipeline itself, which\n * the self-hosted `/connect` path shares for the same reason.\n */\n override async connectAgent(\n parameters?: RunAgentParameters,\n subscriber?: AgentSubscriber,\n ): Promise<RunAgentResult> {\n // A run already in flight owns the canonical run id; reuse it so the\n // replay is attributed to that run rather than minting a new one.\n const effectiveParameters =\n parameters?.runId || !this.canonicalRunId\n ? parameters\n : {\n ...parameters,\n runId: this.canonicalRunId,\n };\n\n return ɵconnectWithoutEventVerification(\n this,\n effectiveParameters,\n subscriber,\n );\n }\n\n abortRun(): void {\n if (this.activeChannel && this.canonicalRunId) {\n // Defer cleanup until the push is acknowledged so socket.disconnect()\n // doesn't clear the push buffer before the stop signal is sent.\n // The 5-second fallback handles the case where the socket is down and\n // Phoenix never flushes the buffered push (its .receive(\"timeout\") only\n // fires for pushes that were actually sent but not replied to).\n // detachActiveRun() gracefully tears down the connectAgent() pipeline;\n // cleanup() follows as a safety net for the run() path.\n const fallback = setTimeout(() => clear(), 5_000);\n const clear = () => {\n clearTimeout(fallback);\n void this.detachActiveRun();\n this.cleanup();\n };\n\n this.activeChannel\n .push(STOP_RUN_EVENT, { run_id: this.canonicalRunId })\n .receive(\"ok\", clear)\n .receive(\"error\", clear)\n .receive(\"timeout\", clear);\n } else {\n void this.detachActiveRun();\n this.cleanup();\n }\n }\n\n /**\n * Trigger the run via REST, then join the realtime thread channel and relay\n * server-pushed AG-UI events to the Observable subscriber.\n */\n run(input: RunAgentInput): Observable<BaseEvent> {\n this.threadId = input.threadId;\n this.canonicalRunId = input.runId;\n\n return defer(() => this.requestJoinCredentials$(\"run\", input)).pipe(\n switchMap((credentials) => {\n if (credentials === null) {\n return throwError(\n () => new Error(\"REST run request returned no credentials\"),\n );\n }\n\n const canonicalInput = this.applyCanonicalRunIdentity(\n input,\n credentials,\n { fallbackToInputRunId: true },\n );\n\n return this.observeThread$(canonicalInput, credentials, {\n completeOnRunError: false,\n streamMode: \"run\",\n });\n }),\n );\n }\n\n /**\n * Reconnect to an existing thread by fetching websocket credentials and\n * joining the realtime thread channel.\n */\n /**\n * Reconnect to an existing thread by fetching websocket credentials\n * and joining the realtime thread channel.\n *\n * Note: this method does NOT clear the replay cursor. Whether to\n * request a full historical replay vs. resume from\n * `lastSeenEventId` is a decision the caller (typically\n * `RunHandler.connectAgent`) makes by calling\n * {@link clearReconnectCursor} ahead of time on a fresh thread\n * restore. Same-thread churn re-connects preserve the cursor so the\n * gateway only streams events past it instead of replaying the\n * entire history every time the chat re-opens a socket.\n */\n protected connect(input: RunAgentInput): Observable<BaseEvent> {\n this.threadId = input.threadId;\n this.canonicalRunId = null;\n const replayCursor = this.getReconnectCursor(input);\n\n return defer(() =>\n this.requestJoinCredentials$(\"connect\", input, replayCursor),\n ).pipe(\n switchMap((credentials) => {\n if (credentials === null) {\n return EMPTY;\n }\n\n const canonicalInput = this.applyCanonicalRunIdentity(\n input,\n credentials,\n { fallbackToInputRunId: false },\n );\n\n return this.observeThread$(canonicalInput, credentials, {\n completeOnRunError: false,\n streamMode: \"connect\",\n replayCursor,\n });\n }),\n );\n }\n\n /**\n * Tear down a specific channel + socket pair that belongs to one pipeline.\n * Only nulls instance references when they still point to the owned resource,\n * so a concurrent pipeline's resources are never clobbered.\n */\n private cleanupOwned(\n ownChannel: Channel | null,\n ownSocket: Socket | null,\n ): void {\n if (ownChannel) {\n ownChannel.leave();\n if (this.activeChannel === ownChannel) {\n this.activeChannel = null;\n }\n }\n if (ownSocket) {\n ownSocket.disconnect();\n if (this.socket === ownSocket) {\n this.socket = null;\n }\n }\n this.canonicalRunId = null;\n }\n\n private cleanup(): void {\n this.cleanupOwned(this.activeChannel, this.socket);\n }\n\n private requestJoinCredentials$(\n mode: \"run\" | \"connect\",\n input: RunAgentInput,\n replayCursor?: string | null,\n ): Observable<ThreadJoinCredentials | null> {\n return defer(async () => {\n try {\n const requestFetch = this.config.fetch ?? globalFetch;\n const body = {\n ...input,\n ...(mode === \"connect\"\n ? {\n lastSeenEventId:\n replayCursor === undefined\n ? this.getReconnectCursor(input)\n : replayCursor,\n }\n : {}),\n };\n const single = this.config.transport === \"single\";\n const response = await requestFetch(\n single ? this.config.runtimeUrl : this.buildRuntimeUrl(mode),\n {\n method: \"POST\",\n redirect: \"error\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.headers,\n },\n // Post the whole RunAgentInput rather than naming each field, so a\n // protocol field such as `resume` cannot be dropped here again.\n body: JSON.stringify(\n single\n ? {\n method: `agent/${mode}`,\n params: { agentId: this.config.agentId },\n body,\n }\n : body,\n ),\n ...(this.credentials ? { credentials: this.credentials } : {}),\n },\n );\n\n if (response.status === 204 && mode === \"connect\") {\n return null;\n }\n\n if (response.status === 409 && mode === \"run\") {\n throw new AgentThreadLockedError(input.threadId);\n }\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n throw new Error(\n text || response.statusText || String(response.status),\n );\n }\n\n return this.normalizeJoinCredentials(await response.json(), input);\n } catch (error) {\n if (error instanceof AgentThreadLockedError) {\n throw error;\n }\n throw new Error(\n `REST ${mode} request failed: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error },\n );\n }\n });\n }\n\n private normalizeJoinCredentials(\n payload: unknown,\n input: RunAgentInput,\n ): ThreadJoinCredentials {\n const envelope =\n payload && typeof payload === \"object\"\n ? (payload as Record<string, unknown>)\n : null;\n const realtime =\n envelope?.realtime && typeof envelope.realtime === \"object\"\n ? (envelope.realtime as Record<string, unknown>)\n : null;\n\n if (typeof envelope?.joinToken !== \"string\" || !envelope.joinToken) {\n throw new Error(\"missing joinToken\");\n }\n\n if (typeof realtime?.clientUrl !== \"string\" || !realtime.clientUrl) {\n throw new Error(\"missing realtime.clientUrl\");\n }\n\n if (typeof realtime.topic !== \"string\" || !realtime.topic) {\n throw new Error(\"missing realtime.topic\");\n }\n\n return {\n threadId:\n typeof envelope.threadId === \"string\" && envelope.threadId\n ? envelope.threadId\n : input.threadId,\n runId:\n typeof envelope.runId === \"string\" && envelope.runId\n ? envelope.runId\n : null,\n joinToken: envelope.joinToken,\n realtime: {\n clientUrl: realtime.clientUrl,\n topic: realtime.topic,\n },\n };\n }\n\n private observeThread$(\n input: RunAgentInput,\n credentials: ThreadJoinCredentials,\n options: {\n completeOnRunError: boolean;\n streamMode: \"run\" | \"connect\";\n channelMode?: \"run\" | \"connect\";\n replayCursor?: string | null;\n unopenedRefreshes?: number;\n },\n ): Observable<BaseEvent> {\n const { unopenedRefreshes: previousUnopened = 0, ...sessionOptions } =\n options;\n return defer(() => {\n let socketOpened = false;\n return this.observeThreadSession$(input, credentials, {\n ...sessionOptions,\n onSocketOpen: () => {\n socketOpened = true;\n },\n }).pipe(\n catchError((error) => {\n if (!this.isSocketReconnectExhaustedError(error)) {\n return throwError(() => error);\n }\n\n // A session whose socket opened was a real connection that dropped, so\n // it restarts the count. Sessions that never open mean the realtime\n // endpoint is unavailable, and fresh credentials will not fix that.\n // Only a run is capped: a developer is waiting on its turn. A connect\n // restores history in the background, and nothing retries it after it\n // fails, so it keeps reconnecting until the endpoint recovers.\n const unopenedRefreshes = socketOpened ? 0 : previousUnopened + 1;\n if (\n options.streamMode === \"run\" &&\n unopenedRefreshes > MAX_UNOPENED_CREDENTIAL_REFRESHES\n ) {\n return throwError(\n () =>\n new Error(\n `Realtime connection to ${credentials.realtime.clientUrl} never opened ` +\n `in ${unopenedRefreshes} connection attempts. ` +\n `The realtime endpoint is unavailable.`,\n ),\n );\n }\n\n const replayCursor = this.getReconnectCursor(input);\n return this.requestJoinCredentials$(\n \"connect\",\n input,\n replayCursor,\n ).pipe(\n switchMap((refreshedCredentials) =>\n refreshedCredentials === null\n ? EMPTY\n : this.observeThread$(\n this.applyCanonicalRunIdentity(\n input,\n refreshedCredentials,\n {\n fallbackToInputRunId: options.streamMode === \"run\",\n },\n ),\n refreshedCredentials,\n {\n ...sessionOptions,\n channelMode: \"connect\",\n replayCursor,\n unopenedRefreshes,\n },\n ),\n ),\n );\n }),\n );\n });\n }\n\n private observeThreadSession$(\n input: RunAgentInput,\n credentials: ThreadJoinCredentials,\n options: {\n completeOnRunError: boolean;\n streamMode: \"run\" | \"connect\";\n channelMode?: \"run\" | \"connect\";\n replayCursor?: string | null;\n onSocketOpen?: () => void;\n },\n ): Observable<BaseEvent> {\n return defer(() => {\n // Capture references to the socket and channel created by THIS pipeline\n // so the finalize closure only tears down its own resources. Without\n // this, a fire-and-forget detachActiveRun() from run-handler can race:\n // the old pipeline's deferred cleanup reads from `this.socket` /\n // `this.activeChannel`, which by then may already point to the NEW\n // pipeline's resources — destroying the live connection and preventing\n // the stop signal from ever reaching the backend.\n let ownSocket: Socket | null = null;\n let ownChannel: Channel | null = null;\n\n const socket$ = ɵphoenixSocket$({\n url: credentials.realtime.clientUrl,\n options: {\n params: {\n ...this.config.socketParams,\n join_token: credentials.joinToken,\n },\n reconnectAfterMs: phoenixExponentialBackoff(100, 10_000),\n rejoinAfterMs: phoenixExponentialBackoff(1_000, 30_000),\n },\n }).pipe(\n tap(({ socket }) => {\n ownSocket = socket as Socket;\n this.socket = ownSocket;\n }),\n shareReplay({ bufferSize: 1, refCount: true }),\n );\n const params = this.createThreadChannelParams(\n input,\n options.channelMode ?? options.streamMode,\n options.replayCursor,\n );\n const channel$ = ɵphoenixChannel$({\n socket$,\n topic: credentials.realtime.topic,\n params,\n }).pipe(\n tap(({ channel }) => {\n ownChannel = channel as Channel;\n this.activeChannel = ownChannel;\n }),\n shareReplay({ bufferSize: 1, refCount: true }),\n );\n const reconnectCursor = this.readDurableEventId(\n options.replayCursor ?? this.getReconnectCursor(input),\n );\n let latestObservedReplayCursor: string | null = null;\n const threadEvents$ = this.observeThreadEvents$(\n input.threadId,\n channel$,\n options,\n ).pipe(\n tap((payload) => {\n latestObservedReplayCursor =\n this.readEventId(payload) ?? latestObservedReplayCursor;\n }),\n share(),\n );\n const controlCursor: ControlCursorState = {\n applied: null,\n replayFailed: false,\n };\n const replayFailed$ = channel$.pipe(\n switchMapOperator(({ channel }) =>\n this.observeChannelEvent$<unknown>(channel, REPLAY_FAILED_EVENT),\n ),\n tap(() => {\n controlCursor.replayFailed = true;\n }),\n );\n const replayComplete$ = this.observeControlEvent$(\n input.threadId,\n channel$,\n REPLAY_COMPLETE_EVENT,\n controlCursor,\n ).pipe(shareReplay({ bufferSize: 1, refCount: true }));\n const streamIdle$ = this.observeControlEvent$(\n input.threadId,\n channel$,\n STREAM_IDLE_EVENT,\n controlCursor,\n ).pipe(shareReplay({ bufferSize: 1, refCount: true }));\n const streamIdleCompletion$ =\n options.streamMode === \"connect\"\n ? merge(\n combineLatest([\n replayComplete$.pipe(take(1)),\n streamIdle$.pipe(take(1)),\n ]),\n streamIdle$.pipe(\n take(1),\n filter((payload) =>\n this.canFallbackCompleteConnect(\n payload,\n reconnectCursor,\n latestObservedReplayCursor,\n ),\n ),\n delay(CONNECT_STREAM_IDLE_REPLAY_FALLBACK_MS),\n ),\n ).pipe(take(1))\n : EMPTY;\n const threadCompleted$ = threadEvents$.pipe(\n ignoreElements(),\n endWith(null),\n take(1),\n );\n const terminal$ = merge(threadCompleted$, streamIdleCompletion$);\n\n return merge(\n this.joinThreadChannel$(channel$),\n this.observeSocketHealth$(socket$, options.onSocketOpen).pipe(\n takeUntil(terminal$),\n ),\n threadEvents$.pipe(takeUntil(streamIdleCompletion$)),\n replayFailed$.pipe(ignoreElements(), takeUntil(terminal$)),\n replayComplete$.pipe(ignoreElements(), takeUntil(terminal$)),\n streamIdleCompletion$.pipe(\n ignoreElements(),\n takeUntil(threadCompleted$),\n ),\n ).pipe(finalize(() => this.cleanupOwned(ownChannel, ownSocket)));\n });\n }\n\n private joinThreadChannel$(\n channel$: Observable<ɵPhoenixChannelSession>,\n ): Observable<never> {\n return ɵjoinPhoenixChannel$(channel$);\n }\n\n private observeSocketHealth$(\n socket$: Observable<ɵPhoenixSocketSession>,\n onSocketOpen?: () => void,\n ): Observable<never> {\n return ɵobservePhoenixSocketHealth$(\n ɵobservePhoenixSocketSignals$(socket$).pipe(\n tap((signal) => {\n if (signal.type === \"open\") onSocketOpen?.();\n }),\n ),\n 5,\n );\n }\n\n private observeThreadEvents$(\n threadId: string,\n channel$: Observable<ɵPhoenixChannelSession>,\n options: { completeOnRunError: boolean; streamMode: \"run\" | \"connect\" },\n ): Observable<BaseEvent> {\n return channel$.pipe(\n switchMapOperator(({ channel }) =>\n this.observeChannelEvent$<BaseEvent>(channel, CLIENT_AG_UI_EVENT),\n ),\n tap((payload) => {\n this.updateLastSeenEventId(threadId, payload);\n }),\n mergeMap(\n (payload) =>\n this.createThreadNotifications(payload, {\n completeOnRunError: options.completeOnRunError,\n completeOnRunFinished: options.streamMode === \"run\",\n errorOnRunError: options.streamMode === \"run\",\n }) as ObservableNotification<BaseEvent>[],\n ),\n dematerialize(),\n );\n }\n\n private observeControlEvent$(\n threadId: string,\n channel$: Observable<ɵPhoenixChannelSession>,\n eventName: string,\n controlCursor: ControlCursorState,\n ): Observable<unknown> {\n return channel$.pipe(\n switchMapOperator(({ channel }) =>\n this.observeChannelEvent$<unknown>(channel, eventName),\n ),\n tap((payload) =>\n this.updateLastSeenEventIdFromControl(threadId, payload, controlCursor),\n ),\n );\n }\n\n private observeChannelEvent$<T>(\n channel: ɵPhoenixChannelLike,\n eventName: string,\n ): Observable<T> {\n return ɵobservePhoenixEvent$<T>(channel, eventName);\n }\n\n private createThreadNotifications(\n payload: BaseEvent,\n options: {\n completeOnRunError: boolean;\n completeOnRunFinished: boolean;\n errorOnRunError: boolean;\n },\n ): Array<Notification<BaseEvent>> {\n if (payload.type === EventType.RUN_FINISHED) {\n return options.completeOnRunFinished\n ? [Notification.createNext(payload), Notification.createComplete()]\n : [Notification.createNext(payload)];\n }\n\n if (payload.type === EventType.RUN_ERROR) {\n const errorMessage =\n (payload as BaseEvent & { message?: string }).message ?? \"Run error\";\n\n return options.completeOnRunError\n ? [Notification.createNext(payload), Notification.createComplete()]\n : options.errorOnRunError\n ? [\n Notification.createNext(payload),\n Notification.createError(new Error(errorMessage)),\n ]\n : [Notification.createNext(payload)];\n }\n\n return [Notification.createNext(payload)];\n }\n\n private buildRuntimeUrl(mode: \"run\" | \"connect\"): string {\n const path = `${this.config.runtimeUrl}/agent/${encodeURIComponent(this.config.agentId)}/${mode}`;\n const origin =\n typeof window !== \"undefined\" && window.location\n ? window.location.origin\n : \"http://localhost\";\n\n return new URL(path, new URL(this.config.runtimeUrl, origin)).toString();\n }\n\n private createThreadChannelParams(\n input: RunAgentInput,\n streamMode: \"run\" | \"connect\",\n replayCursor?: string | null,\n ): Record<string, unknown> {\n return streamMode === \"run\"\n ? {\n stream_mode: \"run\",\n run_id: input.runId,\n }\n : {\n stream_mode: \"connect\",\n last_seen_event_id:\n replayCursor === undefined\n ? this.getReconnectCursor(input)\n : replayCursor,\n };\n }\n\n private getLastSeenEventId(threadId: string): string | null {\n return this.sharedState.lastSeenEventIds.get(threadId) ?? null;\n }\n\n private getReconnectCursor(input: RunAgentInput): string | null {\n return this.getLastSeenEventId(input.threadId);\n }\n\n /**\n * Drop the cached `lastSeenEventId` cursor for `threadId` so the\n * next connect to that topic asks the gateway for a full historical\n * replay (rather than resuming). Public because\n * `RunHandler.connectAgent` calls it on a detected thread switch\n * to rebuild local state from scratch, and skips it on same-thread\n * churn so the gateway can resume.\n */\n public clearReconnectCursor(threadId: string): void {\n this.sharedState.lastSeenEventIds.delete(threadId);\n }\n\n private updateLastSeenEventId(threadId: string, payload: BaseEvent): void {\n const eventId = this.readEventId(payload);\n if (!eventId) {\n return;\n }\n\n this.advanceLastSeenEventId(threadId, eventId);\n }\n\n private updateLastSeenEventIdFromControl(\n threadId: string,\n payload: unknown,\n controlCursor: ControlCursorState,\n ): void {\n const eventId = this.readControlEventId(payload);\n if (!eventId) {\n return;\n }\n\n // An older gateway repeats the join's history checkpoint on every control\n // frame, also on stream_idle after live events moved past it. A repeat is\n // stale and must not replace the newer event cursor, or the next join\n // replays those live events again. After replay_failed the gateway repeats\n // the prior cursor on purpose, so the next join retries the failed history.\n if (eventId === controlCursor.applied && !controlCursor.replayFailed) {\n return;\n }\n\n controlCursor.applied = eventId;\n this.advanceLastSeenEventId(threadId, eventId);\n }\n\n private advanceLastSeenEventId(threadId: string, eventId: string): void {\n this.sharedState.lastSeenEventIds.set(threadId, eventId);\n }\n\n private readEventId(payload: BaseEvent): string | null {\n const metadata = (payload as BaseEvent & { metadata?: unknown }).metadata;\n if (!metadata || typeof metadata !== \"object\") {\n return null;\n }\n\n const eventMetadata = metadata as { cpki_event_id?: unknown };\n return this.readDurableEventId(eventMetadata.cpki_event_id);\n }\n\n private readControlEventId(payload: unknown): string | null {\n if (!payload || typeof payload !== \"object\") {\n return null;\n }\n\n const controlPayload = payload as {\n latestEventId?: unknown;\n latest_event_id?: unknown;\n };\n const latestEventId =\n controlPayload.latestEventId ?? controlPayload.latest_event_id;\n return this.readDurableEventId(latestEventId);\n }\n\n private readDurableEventId(eventId: unknown): string | null {\n if (typeof eventId !== \"string\" || eventId.trim() === \"\") {\n return null;\n }\n\n return eventId.startsWith(\"cpki_ingested\") ? null : eventId;\n }\n\n private canFallbackCompleteConnect(\n streamIdlePayload: unknown,\n reconnectCursor: string | null,\n latestObservedReplayCursor: string | null,\n ): boolean {\n const idleCursor = this.readControlEventId(streamIdlePayload);\n if (!idleCursor) {\n return true;\n }\n\n return (\n idleCursor === reconnectCursor ||\n idleCursor === latestObservedReplayCursor\n );\n }\n\n private applyCanonicalRunIdentity(\n input: RunAgentInput,\n credentials: ThreadJoinCredentials,\n options: { fallbackToInputRunId: boolean },\n ): RunAgentInput {\n this.threadId = credentials.threadId;\n const runId =\n credentials.runId ?? (options.fallbackToInputRunId ? input.runId : null);\n this.canonicalRunId = runId;\n\n return {\n ...input,\n threadId: credentials.threadId,\n ...(runId === null ? {} : { runId }),\n };\n }\n\n private isSocketReconnectExhaustedError(error: unknown): boolean {\n return (\n error instanceof Error &&\n error.message.includes(\"WebSocket connection failed after\")\n );\n }\n}\n","/**\n * Build the error for a failed runtime `/info` response, folding in whatever\n * explanation the runtime sent back.\n *\n * The status alone cannot distinguish a wrong `runtimeUrl` from a transport\n * mismatch, so the runtime answers the latter with a body naming the cause\n * (see the handler's `single_route_envelope_against_multi_route_runtime`\n * diagnostic). Discarding that body — as every `/info` caller used to — left\n * the developer with a bare 404 and nothing to act on (OSS-882).\n *\n * A body that isn't JSON, or carries no string `message`, contributes nothing:\n * the status is then the whole error.\n */\nexport async function runtimeInfoError(\n response: Response,\n): Promise<RuntimeInfoRequestError> {\n const base = `Runtime info request failed with status ${response.status}`;\n\n let detail: string | undefined;\n try {\n const body: unknown = await response.clone().json();\n const message = (body as { message?: unknown } | null)?.message;\n if (typeof message === \"string\" && message.trim().length > 0) {\n detail = message.trim();\n }\n } catch {\n // Unparseable or already-consumed body — fall back to the status.\n }\n\n const error = new Error(\n detail ? `${base}: ${detail}` : base,\n ) as RuntimeInfoRequestError;\n error.runtimeInfoStatus = response.status;\n return error;\n}\n\nexport interface RuntimeInfoRequestError extends Error {\n runtimeInfoStatus: number;\n}\n\nexport function isRuntimeInfoRequestError(\n error: unknown,\n): error is RuntimeInfoRequestError {\n return (\n typeof error === \"object\" &&\n error !== null &&\n typeof (error as { runtimeInfoStatus?: unknown }).runtimeInfoStatus ===\n \"number\"\n );\n}\n","import type { Message } from \"@ag-ui/client\";\n\n/**\n * Rewrites the message list a runtime agent sends on each run.\n *\n * CopilotKit sends the whole thread on every request. When the backend already\n * stores the conversation (a LangGraph checkpointer, a Mastra memory store, a\n * Strands `SessionManager`, an Agent Framework chat history provider), that\n * history is dead weight: the payload grows without bound, and an agent that\n * merges the inbound list with its own store can show the model every turn\n * twice. See https://github.com/CopilotKit/CopilotKit/issues/1482.\n *\n * The filter runs on the outbound payload only. It never touches the messages\n * the UI renders, so trimming here does not shorten the visible transcript.\n *\n * Return the messages to send. Returning an empty array is valid and means\n * \"send nothing but the run metadata\".\n *\n * @param messages - The thread as the client holds it, in order, with\n * `activity`-role messages already removed.\n * @param context - Which agent is about to run.\n */\nexport type CopilotKitMessageFilter = (\n messages: Message[],\n context: { agentId: string },\n) => Message[];\n\ninterface AssistantToolCall {\n id: string;\n}\n\nfunction toolCallIdsOf(message: Message): string[] {\n const calls = (message as { toolCalls?: AssistantToolCall[] }).toolCalls;\n if (!Array.isArray(calls)) return [];\n return calls.map((call) => call.id).filter((id): id is string => Boolean(id));\n}\n\nfunction resultCallIdOf(message: Message): string | undefined {\n if (message.role !== \"tool\") return undefined;\n return (message as { toolCallId?: string }).toolCallId;\n}\n\n/**\n * Repair the tool-call pairs a filter broke.\n *\n * Every provider rejects a half pair. A tool result whose call is gone reads as\n * a reply to nothing, and an assistant tool call whose result is gone leaves\n * the turn unanswered — the failure reporters hit on #1482 when a trimmed\n * history landed mid-HITL and Anthropic answered \"a tool result is expected\".\n * A filter written as `messages.slice(-1)` cannot know this, so the repair runs\n * for every filter rather than being something each caller opts into.\n *\n * Both repairs restore, never discard, and both are anchored on the untrimmed\n * thread:\n *\n * - A kept tool result whose assistant call was trimmed away gets that call put\n * back in front of it. Dropping the result instead would be protocol-safe and\n * semantically wrong: on a human-in-the-loop turn the result IS the new\n * information, and a backend that already holds the call would be asked to\n * resume with nothing.\n * - A kept assistant call whose result was trimmed gets that result restored,\n * placed directly after the call.\n *\n * Restoring a call pulls in every result for that call, not only the one the\n * filter kept. Providers reject an assistant turn with a parallel tool call\n * left unanswered, so a half-answered set is as invalid as a missing one.\n *\n * A call with no result anywhere in `full` is left alone. That is an open call\n * (a pending frontend tool, an unanswered interrupt), not a broken pair. A\n * result whose call is nowhere in `full` is left alone too: it was already\n * unpaired before the filter ran, so it is not this function's to fix.\n *\n * The filter's own ordering is preserved. Restorations are the only insertions,\n * and messages the filter synthesized (absent from `full`) pass through\n * untouched.\n */\nexport function ɵrepairToolCallPairs(\n kept: Message[],\n full: Message[],\n): Message[] {\n // Both maps are built from the untrimmed thread: the repair has to reason\n // about pairs the filter already broke, so the kept list cannot answer\n // \"did this call have a result\".\n const callIdToIssuer = new Map<string, Message>();\n const callIdToResult = new Map<string, Message>();\n for (const message of full) {\n for (const callId of toolCallIdsOf(message)) {\n callIdToIssuer.set(callId, message);\n }\n const resultCallId = resultCallIdOf(message);\n if (resultCallId !== undefined) {\n callIdToResult.set(resultCallId, message);\n }\n }\n\n const repaired: Message[] = [];\n const emitted = new Set<string>();\n\n const emit = (message: Message) => {\n if (emitted.has(message.id)) return;\n emitted.add(message.id);\n repaired.push(message);\n };\n\n /** Emit an assistant turn together with every result it is owed. */\n const emitWithResults = (message: Message) => {\n emit(message);\n for (const callId of toolCallIdsOf(message)) {\n const result = callIdToResult.get(callId);\n if (result) emit(result);\n }\n };\n\n for (const message of kept) {\n const resultCallId = resultCallIdOf(message);\n if (resultCallId === undefined) {\n emitWithResults(message);\n continue;\n }\n\n const issuer = callIdToIssuer.get(resultCallId);\n if (issuer) {\n // Emits the issuer first, then this result along with its siblings.\n emitWithResults(issuer);\n continue;\n }\n emit(message);\n }\n\n return repaired;\n}\n","import type {\n AbstractAgent,\n AgentCapabilities,\n AgentSubscriber,\n BaseEvent,\n HttpAgentConfig,\n RunAgentInput,\n RunAgentParameters,\n RunAgentResult,\n} from \"@ag-ui/client\";\nimport {\n HttpAgent,\n runHttpRequest,\n structuredClone_,\n transformHttpEventStream,\n} from \"@ag-ui/client\";\nimport type { Observable } from \"rxjs\";\nimport { EMPTY, defer, from } from \"rxjs\";\nimport { catchError, finalize, switchMap } from \"rxjs/operators\";\nimport {\n RUNTIME_MODE_SSE,\n RUNTIME_MODE_INTELLIGENCE,\n} from \"@copilotkit/shared\";\nimport type {\n IntelligenceRuntimeInfo,\n RuntimeInfo,\n RuntimeMode,\n ResolvedDebugConfig,\n} from \"@copilotkit/shared\";\nimport { IntelligenceAgent } from \"./intelligence-agent\";\nimport type { CopilotRuntimeTransport } from \"./types\";\nimport { runtimeInfoError } from \"./utils/runtime-info-error\";\nimport { ɵconnectWithoutEventVerification } from \"./utils/connect-replay\";\nimport type { CopilotKitMessageFilter } from \"./core/message-filter\";\nimport { ɵrepairToolCallPairs } from \"./core/message-filter\";\n\ntype ResolvedRuntimeMode = RuntimeMode | \"pending\";\n\ninterface RunnableAgent {\n connect(input: RunAgentInput): Observable<BaseEvent>;\n run(input: RunAgentInput): Observable<BaseEvent>;\n}\n\nfunction hasHeaders(\n agent: AbstractAgent,\n): agent is AbstractAgent & { headers?: Record<string, string> } {\n return \"headers\" in agent;\n}\n\nfunction hasCredentials(\n agent: AbstractAgent,\n): agent is AbstractAgent & { credentials?: RequestCredentials } {\n return \"credentials\" in agent;\n}\n\nfunction isZodError(error: unknown): boolean {\n return (\n error !== null &&\n typeof error === \"object\" &&\n \"name\" in error &&\n (error as { name: string }).name === \"ZodError\"\n );\n}\n\nfunction isAbortError(error: unknown): boolean {\n return (\n (error instanceof DOMException || error instanceof Error) &&\n (error as Error).name === \"AbortError\"\n );\n}\n\nfunction withAbortErrorHandling(\n observable: Observable<BaseEvent>,\n): Observable<BaseEvent> {\n return observable.pipe(\n catchError((error) => {\n if (isZodError(error) || isAbortError(error)) {\n return EMPTY;\n }\n throw error;\n }),\n );\n}\n\nexport interface ProxiedCopilotRuntimeAgentConfig extends Omit<\n HttpAgentConfig,\n \"url\"\n> {\n runtimeUrl?: string;\n transport?: CopilotRuntimeTransport;\n credentials?: RequestCredentials;\n runtimeMode?: ResolvedRuntimeMode;\n intelligence?: IntelligenceRuntimeInfo;\n capabilities?: AgentCapabilities;\n debug?: ResolvedDebugConfig;\n /**\n * When set, runtime requests (HTTP path, single-route envelope, intelligence\n * delegate) are routed to this agent on the runtime instead of `agentId`.\n * The local `agentId` remains the registry key used for subscriber\n * bookkeeping; only outbound routing is overridden.\n */\n runtimeAgentId?: string;\n /**\n * Rewrites the outbound message list on every run. See\n * {@link CopilotKitMessageFilter}. Not applied in Intelligence mode.\n */\n messageFilter?: CopilotKitMessageFilter;\n}\n\nexport class ProxiedCopilotRuntimeAgent extends HttpAgent {\n runtimeUrl?: string;\n credentials?: RequestCredentials;\n // `readonly` because `super.url` is baked at construction; mutating\n // `runtimeAgentId` post-construction would desync the REST `run` URL\n // (already captured) from `routedAgentId()` (consulted per-call by\n // stop/connect/single-route paths).\n readonly runtimeAgentId?: string;\n private transport: CopilotRuntimeTransport;\n /**\n * The runtime URL exactly as the caller supplied it. `runtimeUrl` is the\n * slash-stripped form used for path joins; the single-route endpoint (run,\n * connect, stop, info envelopes) is this verbatim value, because a trailing\n * slash can select a different proxy location.\n */\n private readonly runtimeEndpointUrl?: string;\n private singleEndpointUrl?: string;\n private runtimeMode: ResolvedRuntimeMode;\n private intelligence?: IntelligenceRuntimeInfo;\n private _capabilities?: AgentCapabilities;\n private delegate?: AbstractAgent;\n private runtimeInfoPromise?: Promise<void>;\n private _messageFilter?: CopilotKitMessageFilter;\n /**\n * The HTTP `run` this agent started and has not yet seen finish, as the\n * exact `{ threadId, runId }` it POSTed. `abortRun` narrows `/stop` to this\n * run only while `threadId` still matches: `threadId` is a public field the\n * host may reassign under a live run, and a runId from another thread must\n * not be sent as if it were this thread's. Released when the run stream\n * finalizes, cleared on `connect` (a reconnected thread may run under a\n * runId this client never saw) and never copied by `clone`. Without a\n * provable active run the stop stays thread-wide.\n */\n private activeRun?: { threadId: string; runId: string };\n\n constructor(config: ProxiedCopilotRuntimeAgentConfig) {\n const normalizedRuntimeUrl = config.runtimeUrl\n ? config.runtimeUrl.replace(/\\/$/, \"\")\n : undefined;\n const transport = config.transport ?? \"auto\";\n const routedId = config.runtimeAgentId ?? config.agentId ?? \"\";\n // The single endpoint is the caller's URL exactly as given: a trailing\n // slash can select a different proxy location, so it must survive. Only\n // the path joins (`/agent/…`, `/info`) use the slash-stripped form.\n const runUrl =\n transport === \"single\"\n ? (config.runtimeUrl ?? \"\")\n : `${normalizedRuntimeUrl ?? config.runtimeUrl}/agent/${encodeURIComponent(routedId)}/run`;\n\n if (!runUrl) {\n throw new Error(\n \"ProxiedCopilotRuntimeAgent requires a runtimeUrl when transport is set to 'single'.\",\n );\n }\n\n super({\n ...config,\n url: runUrl,\n });\n this.runtimeUrl = normalizedRuntimeUrl ?? config.runtimeUrl;\n this.runtimeEndpointUrl = config.runtimeUrl;\n this.credentials = config.credentials;\n this.runtimeAgentId = config.runtimeAgentId;\n this.transport = transport;\n this.runtimeMode = config.runtimeMode ?? RUNTIME_MODE_SSE;\n this.intelligence = config.intelligence;\n this._capabilities = config.capabilities;\n this._messageFilter = config.messageFilter;\n if (config.debug) {\n this.debug = config.debug;\n }\n if (this.transport === \"single\") {\n this.singleEndpointUrl = this.runtimeEndpointUrl;\n }\n }\n\n /**\n * Adopt the runtime mode a fresh `/info` just reported.\n *\n * A live proxy outlives the runtime configuration that minted it: a\n * redeploy, an env-var change or a rollback can flip `intelligence` → `sse`\n * under a page that is already open. The registry preserves the proxy across\n * that re-sync on purpose — it is backing an open conversation — so the new\n * mode is pushed onto the instance here instead of replacing it.\n *\n * Without this the mode was decided once, at construction, and `run()` kept\n * taking the delegate path against a runtime serving plain SSE, where\n * `response.json()` on a `text/event-stream` body throws for the rest of the\n * page's life. See #7130.\n *\n * A delegate built for the old mode is torn down: it speaks a protocol the\n * runtime no longer serves, and it may be holding a websocket open. The\n * memoized `/info` promise goes with it — it answered for the old\n * configuration, so a later `ensureRuntimeConfiguration()` must re-ask\n * rather than treat that answer as current.\n *\n * Only `wsUrl` is compared on the Intelligence metadata, because that is the\n * one field the delegate bakes in at construction.\n */\n adoptRuntimeMode(\n runtimeMode: ResolvedRuntimeMode,\n intelligence: IntelligenceRuntimeInfo | undefined,\n ): void {\n const unchanged =\n this.runtimeMode === runtimeMode &&\n this.intelligence?.wsUrl === intelligence?.wsUrl;\n\n this.runtimeMode = runtimeMode;\n this.intelligence = intelligence;\n\n if (unchanged) {\n return;\n }\n this.runtimeInfoPromise = undefined;\n const staleDelegate = this.delegate;\n this.delegate = undefined;\n if (staleDelegate) {\n staleDelegate.abortRun();\n // A re-sync can land mid-run, so the proxy's own pipeline has to be\n // detached as well: aborting only the delegate would leave `isRunning`\n // true and `onRunFinalized` unfired, and the UI would spin forever.\n // This mirrors what `abortRun()` does for its delegate branch, minus\n // the delegate detach that clearing the field above already skips.\n void this.detachActiveRun();\n }\n }\n\n /**\n * The agent id used for outbound runtime requests — `runtimeAgentId` when\n * set (manually-registered proxy), otherwise `agentId` (registry id\n * matches runtime id). Subscriber bookkeeping keeps using `agentId`\n * directly.\n *\n * Throws when both are unset: a proxy reaching an HTTP path with no\n * routable id is a bug, and a missing id would otherwise produce a\n * malformed `/agent//run` or `/agent/undefined/connect` URL silently.\n */\n private routedAgentId(): string {\n const id = this.runtimeAgentId ?? this.agentId;\n if (!id) {\n throw new Error(\n \"ProxiedCopilotRuntimeAgent: cannot make a runtime request without an agentId or runtimeAgentId.\",\n );\n }\n return id;\n }\n\n get capabilities(): AgentCapabilities | undefined {\n return this._capabilities;\n }\n\n /**\n * The filter applied to the outbound message list on every run.\n *\n * Registry-owned. `AgentRegistry` writes it whenever the core-level filter\n * changes, so an agent discovered before the app configured one still picks\n * it up — and so a value written here by hand is replaced on the registry's\n * next sweep. Configure it through `CopilotKitCore` instead.\n */\n get messageFilter(): CopilotKitMessageFilter | undefined {\n return this._messageFilter;\n }\n\n set messageFilter(filter: CopilotKitMessageFilter | undefined) {\n this._messageFilter = filter;\n }\n\n /**\n * Narrow the outbound payload with the configured message filter.\n *\n * **Called from the HTTP paths only, and that placement is the Intelligence\n * exemption.** An earlier revision applied the filter in\n * `prepareRunAgentInput`, which runs before the runtime mode is resolved:\n * with the default `\"auto\"` transport, or on a proxy still `\"pending\"` its\n * first `/info`, `run()` prepared the input, *then* resolved the mode, then\n * handed that already-filtered input to `#runViaDelegate` — so a managed\n * runtime received a truncated thread despite the exemption. Filtering here\n * makes that unreachable by construction: `#runViaHttp` and\n * `#connectViaHttp` are only entered once the mode is known not to be\n * Intelligence. Do not move this back up the call chain.\n *\n * The managed runtime is the store of record for the thread — the threads\n * drawer and the Slack transcript read from it — so a client-side truncation\n * there has a blast radius nobody asked for. Every reporter on #1482 is\n * self-hosted.\n *\n * `prepareRunAgentInput` has already deep-cloned the thread and stripped\n * `activity` messages by the time the input reaches here, so the filter\n * cannot reach the messages the UI renders no matter what it does with the\n * array it is handed. The filter gets a *second* deep clone on top of that,\n * because `input.messages` is also the repair baseline and the untrimmed\n * fallback: sharing the message objects let a filter that mutates a kept\n * message's `toolCallId` corrupt the baseline, and an orphaned tool result\n * then went out on the wire — a payload the provider rejects, which is\n * exactly the failure this whole mechanism exists to prevent.\n */\n #applyMessageFilter(input: RunAgentInput): RunAgentInput {\n const filter = this._messageFilter;\n if (!filter) return input;\n\n // A filter that throws, returns the wrong shape, or hands back entries the\n // repair cannot read falls back to the untrimmed thread rather than\n // failing the run. Trimming is an optimization, and taking the user's\n // message down with it would be the worse outcome; the warning is what\n // surfaces the bug.\n try {\n const kept = filter(structuredClone_(input.messages), {\n agentId: this.agentId ?? \"\",\n });\n if (!Array.isArray(kept)) {\n console.warn(\n \"ProxiedCopilotRuntimeAgent: messageFilter returned a non-array value; sending the full message history instead.\",\n );\n return input;\n }\n return { ...input, messages: ɵrepairToolCallPairs(kept, input.messages) };\n } catch (error) {\n console.warn(\n \"ProxiedCopilotRuntimeAgent: messageFilter failed; sending the full message history instead.\",\n error,\n );\n return input;\n }\n }\n\n override requestInit(input: RunAgentInput): RequestInit {\n const baseInit = super.requestInit(input);\n return {\n ...baseInit,\n ...(this.credentials ? { credentials: this.credentials } : {}),\n };\n }\n\n async getCapabilities(): Promise<AgentCapabilities> {\n return this._capabilities ?? {};\n }\n\n override async detachActiveRun(): Promise<void> {\n if (this.delegate) {\n await this.delegate.detachActiveRun();\n }\n await super.detachActiveRun();\n }\n\n abortRun(): void {\n if (this.delegate) {\n this.syncDelegate(this.delegate);\n this.delegate.abortRun();\n // Also detach the proxy's own runAgent pipeline so the proxy's\n // isRunning resets and onRunFinalized fires even if the delegate's\n // observable doesn't propagate a clean completion.\n void this.detachActiveRun();\n return;\n }\n\n if (!this.agentId || !this.threadId) {\n return;\n }\n\n if (typeof fetch === \"undefined\") {\n return;\n }\n\n const routedId = this.routedAgentId();\n const runId =\n this.activeRun?.threadId === this.threadId\n ? this.activeRun.runId\n : undefined;\n\n if (this.transport === \"single\") {\n if (!this.singleEndpointUrl) {\n return;\n }\n\n const headers = new Headers({\n ...this.headers,\n \"Content-Type\": \"application/json\",\n });\n void fetch(this.singleEndpointUrl, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n method: \"agent/stop\",\n params: {\n agentId: routedId,\n threadId: this.threadId,\n },\n ...(runId === undefined ? {} : { body: { runId } }),\n }),\n ...(this.credentials ? { credentials: this.credentials } : {}),\n }).catch((error) => {\n console.error(\"ProxiedCopilotRuntimeAgent: stop request failed\", error);\n });\n return;\n }\n\n if (!this.runtimeUrl) {\n return;\n }\n\n const stopPath = `${this.runtimeUrl}/agent/${encodeURIComponent(routedId)}/stop/${encodeURIComponent(this.threadId)}`;\n const origin =\n typeof window !== \"undefined\" && window.location\n ? window.location.origin\n : \"http://localhost\";\n const base = new URL(this.runtimeUrl, origin);\n const stopUrl = new URL(stopPath, base);\n\n void fetch(stopUrl.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.headers,\n },\n ...(runId === undefined ? {} : { body: JSON.stringify({ runId }) }),\n ...(this.credentials ? { credentials: this.credentials } : {}),\n }).catch((error) => {\n console.error(\"ProxiedCopilotRuntimeAgent: stop request failed\", error);\n });\n }\n\n override async connectAgent(\n parameters?: RunAgentParameters,\n subscriber?: AgentSubscriber,\n ): Promise<RunAgentResult> {\n if (this.runtimeMode !== RUNTIME_MODE_INTELLIGENCE) {\n // A self-hosted `/connect` response replays the thread's history, so it\n // can carry several past runs — including one that ended in RUN_ERROR\n // followed by a later RUN_STARTED. The base pipeline's `verifyEvents`\n // step enforces single-run lifecycle rules and rejects that stream\n // outright, so an existing thread never hydrates (#4943).\n return ɵconnectWithoutEventVerification(this, parameters, subscriber);\n }\n\n // If the delegate already has an active run (e.g. from a previous\n // connectAgent call that hasn't finished yet), detach it first. This\n // ensures only one run is active on the delegate at a time — without it,\n // two parallel runs would both pump events into the shared delegate,\n // and both bridge subscriptions would copy the interleaved messages to\n // the proxy, causing the UI to flicker between the two conversations.\n if (this.delegate) {\n await this.delegate.detachActiveRun();\n }\n\n // Ensure the delegate exists and is synced with the proxy's current state.\n await this.resolveDelegate();\n const delegate = this.delegate!;\n\n // Subscribe a bridging observer FIRST so it fires before the forwarded\n // UI subscribers. This keeps proxy.messages in sync with the delegate\n // in real-time — otherwise the UI re-renders (triggered by the\n // forwarded onMessagesChanged) but reads stale proxy.messages because\n // the final sync only happens after connectAgent resolves.\n const bridgeSub = delegate.subscribe({\n onMessagesChanged: () => {\n this.setMessages([...delegate.messages]);\n },\n onStateChanged: () => {\n this.setState({ ...delegate.state });\n },\n // Mirror isRunning so the proxy reflects the delegate's run lifecycle.\n // Without this, UI components read proxy.isRunning (always false) even\n // though the delegate is actively running, causing the stop button to\n // never appear.\n onRunInitialized: () => {\n this.isRunning = true;\n },\n onRunFinalized: () => {\n this.isRunning = false;\n },\n // Local exception (network error, deserialization failure, etc.)\n onRunFailed: () => {\n this.isRunning = false;\n },\n // Protocol-level RUN_ERROR event from the backend\n onRunErrorEvent: () => {\n this.isRunning = false;\n },\n });\n\n // Forward the proxy's subscribers to the delegate so that UI hooks\n // (e.g. useAgent's onMessagesChanged) receive real-time updates as\n // the delegate processes events during connectAgent.\n const forwardedSubs = this.subscribers.map((s) => delegate.subscribe(s));\n\n try {\n const result = await delegate.connectAgent(parameters, subscriber);\n\n // Final sync to guarantee the proxy reflects the delegate's end state.\n this.setMessages([...delegate.messages]);\n this.setState({ ...delegate.state });\n\n return result;\n } finally {\n // Ensure the proxy's isRunning is reset — the bridging subscription\n // may have already handled this, but if the delegate threw before\n // firing onRunFinalized the proxy would be stuck in isRunning=true.\n this.isRunning = false;\n // Remove forwarded subscribers to avoid duplicate notifications on\n // subsequent calls (they'll be re-forwarded next time).\n bridgeSub.unsubscribe();\n for (const sub of forwardedSubs) {\n sub.unsubscribe();\n }\n }\n }\n\n connect(input: RunAgentInput): Observable<BaseEvent> {\n if (\n this.runtimeMode === \"pending\" ||\n (this.transport === \"auto\" &&\n this.runtimeMode !== RUNTIME_MODE_INTELLIGENCE)\n ) {\n return defer(() => from(this.ensureRuntimeConfiguration())).pipe(\n switchMap(() => this.connect(input)),\n );\n }\n if (this.runtimeMode === RUNTIME_MODE_INTELLIGENCE) {\n return this.#connectViaDelegate(input);\n }\n return this.#connectViaHttp(input);\n }\n\n public run(input: RunAgentInput): Observable<BaseEvent> {\n if (\n this.runtimeMode === \"pending\" ||\n (this.transport === \"auto\" &&\n this.runtimeMode !== RUNTIME_MODE_INTELLIGENCE)\n ) {\n return defer(() => from(this.ensureRuntimeConfiguration())).pipe(\n switchMap(() => this.run(input)),\n );\n }\n if (this.runtimeMode === RUNTIME_MODE_INTELLIGENCE) {\n return this.#runViaDelegate(input);\n }\n return this.#runViaHttp(input);\n }\n\n #connectViaDelegate(input: RunAgentInput): Observable<BaseEvent> {\n return defer(() => from(this.resolveDelegate())).pipe(\n switchMap((delegate) => withAbortErrorHandling(delegate.connect(input))),\n );\n }\n\n #connectViaHttp(unfiltered: RunAgentInput): Observable<BaseEvent> {\n const input = this.#applyMessageFilter(unfiltered);\n this.activeRun = undefined;\n const routedId = this.routedAgentId();\n if (this.transport === \"single\") {\n if (!this.singleEndpointUrl) {\n throw new Error(\"Single endpoint transport requires a runtimeUrl\");\n }\n\n const requestInit = this.createSingleRouteRequestInit(\n input,\n \"agent/connect\",\n {\n agentId: routedId,\n },\n );\n const httpEvents = runHttpRequest(() =>\n this.fetch(this.singleEndpointUrl!, requestInit),\n );\n return withAbortErrorHandling(transformHttpEventStream(httpEvents));\n }\n\n const connectUrl = `${this.runtimeUrl}/agent/${routedId}/connect`;\n const connectRequestInit = this.requestInit(input);\n const httpEvents = runHttpRequest(() =>\n this.fetch(connectUrl, connectRequestInit),\n );\n return withAbortErrorHandling(transformHttpEventStream(httpEvents));\n }\n\n #runViaDelegate(input: RunAgentInput): Observable<BaseEvent> {\n return defer(() => from(this.resolveDelegate())).pipe(\n switchMap((delegate) => withAbortErrorHandling(delegate.run(input))),\n );\n }\n\n #runViaHttp(unfiltered: RunAgentInput): Observable<BaseEvent> {\n const input = this.#applyMessageFilter(unfiltered);\n const activeRun = { threadId: input.threadId, runId: input.runId };\n // Hold this run's identity for as long as its stream lives. The identity\n // check keeps a late-finalizing stream from releasing a newer run.\n const trackActiveRun = (source: Observable<BaseEvent>) => {\n this.activeRun = activeRun;\n return source.pipe(\n finalize(() => {\n if (this.activeRun === activeRun) this.activeRun = undefined;\n }),\n );\n };\n if (this.transport === \"single\") {\n if (!this.singleEndpointUrl) {\n throw new Error(\"Single endpoint transport requires a runtimeUrl\");\n }\n\n const requestInit = this.createSingleRouteRequestInit(\n input,\n \"agent/run\",\n {\n agentId: this.routedAgentId(),\n },\n );\n const httpEvents = runHttpRequest(() =>\n this.fetch(this.singleEndpointUrl!, requestInit),\n );\n return trackActiveRun(\n withAbortErrorHandling(transformHttpEventStream(httpEvents)),\n );\n }\n\n return trackActiveRun(withAbortErrorHandling(super.run(input)));\n }\n\n public override clone(): ProxiedCopilotRuntimeAgent {\n const cloned = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: this.runtimeEndpointUrl ?? this.runtimeUrl,\n agentId: this.agentId,\n runtimeAgentId: this.runtimeAgentId,\n description: this.description,\n headers: { ...this.headers },\n credentials: this.credentials,\n transport: this.transport,\n runtimeMode: this.runtimeMode,\n intelligence: this.intelligence,\n capabilities: this._capabilities,\n debug: this.debug,\n fetch: this.fetch,\n messageFilter: this._messageFilter,\n });\n cloned.threadId = this.threadId;\n cloned.setState(this.state);\n cloned.setMessages(this.messages);\n if (this.delegate) {\n const clonedDelegate: AbstractAgent = this.delegate.clone();\n cloned.delegate = clonedDelegate;\n cloned.syncDelegate(clonedDelegate);\n }\n return cloned;\n }\n\n /**\n * Drop the delegate's cached `lastSeenEventId` for this thread so\n * the next connect requests a full historical replay from the\n * gateway. Used by `RunHandler.connectAgent` on a detected thread\n * switch (the chat moved between threads, so its local\n * messages/state are about to be cleared and need rebuilding from\n * the gateway). Skipped on same-thread churn re-connects so the\n * gateway can resume from the cursor instead.\n *\n * No-op for non-Intelligence runtime modes — the HTTP transport\n * doesn't replay.\n */\n public clearReplayCursor(threadId: string): void {\n if (this.runtimeMode !== RUNTIME_MODE_INTELLIGENCE) return;\n const delegate = this.delegate as\n | { clearReconnectCursor?: (id: string) => void }\n | null\n | undefined;\n delegate?.clearReconnectCursor?.(threadId);\n }\n\n private async resolveDelegate(): Promise<RunnableAgent> {\n await this.ensureRuntimeConfiguration();\n\n if (!this.delegate) {\n if (this.runtimeMode !== RUNTIME_MODE_INTELLIGENCE) {\n throw new Error(\"A delegate is only created for Intelligence mode\");\n }\n this.delegate = this.createIntelligenceDelegate();\n }\n\n this.syncDelegate(this.delegate);\n\n // AbstractAgent declares connect() as protected, but concrete delegates\n // (IntelligenceAgent, HttpAgent) expose both connect() and run() publicly.\n return this.delegate as unknown as RunnableAgent;\n }\n\n /** Resolve transport and runtime mode before the first outbound request. */\n private async ensureRuntimeConfiguration(): Promise<void> {\n if (\n this.runtimeMode === RUNTIME_MODE_INTELLIGENCE ||\n (this.runtimeMode !== \"pending\" && this.transport !== \"auto\")\n ) {\n return;\n }\n\n if (!this.runtimeUrl) {\n throw new Error(\"Runtime URL is not set\");\n }\n\n const runtimeInfoPromise =\n this.runtimeInfoPromise ??\n this.fetchRuntimeInfo().then((runtimeInfo) => {\n this.runtimeMode = runtimeInfo.mode ?? RUNTIME_MODE_SSE;\n this.intelligence = runtimeInfo.intelligence;\n });\n this.runtimeInfoPromise = runtimeInfoPromise;\n\n try {\n await runtimeInfoPromise;\n } catch (error) {\n if (this.runtimeInfoPromise === runtimeInfoPromise) {\n this.runtimeInfoPromise = undefined;\n }\n throw error;\n }\n }\n\n private async fetchRuntimeInfo(): Promise<RuntimeInfo> {\n const headers: Record<string, string> = {\n ...this.headers,\n };\n\n if (this.transport === \"auto\") {\n return this.fetchRuntimeInfoAutoDetect(headers);\n }\n\n let init: RequestInit;\n let url: string;\n\n if (this.transport === \"single\") {\n if (!this.singleEndpointUrl) {\n throw new Error(\"Single endpoint transport requires a runtimeUrl\");\n }\n if (!headers[\"Content-Type\"]) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n url = this.singleEndpointUrl;\n init = { method: \"POST\", body: JSON.stringify({ method: \"info\" }) };\n } else {\n url = `${this.runtimeUrl}/info`;\n init = {};\n }\n\n const response = await this.fetch(url, {\n ...init,\n headers,\n ...(this.credentials ? { credentials: this.credentials } : {}),\n });\n if (!response.ok) {\n throw await runtimeInfoError(response);\n }\n return (await response.json()) as RuntimeInfo;\n }\n\n private async fetchRuntimeInfoAutoDetect(\n headers: Record<string, string>,\n ): Promise<RuntimeInfo> {\n // Try REST first (GET /info)\n try {\n const response = await this.fetch(`${this.runtimeUrl}/info`, {\n headers: { ...headers },\n ...(this.credentials ? { credentials: this.credentials } : {}),\n });\n // Only treat a successful (2xx) response as a valid REST runtime.\n // 404/405 means the endpoint doesn't exist; other non-2xx errors\n // (500, 403, etc.) should also fall through to single-endpoint.\n if (response.status >= 200 && response.status < 300) {\n this.transport = \"rest\";\n return (await response.json()) as RuntimeInfo;\n }\n } catch {\n // REST failed — fall through to single-endpoint attempt\n }\n\n // Try single-endpoint (POST with { method: \"info\" })\n const singleHeaders = { ...headers };\n if (!singleHeaders[\"Content-Type\"]) {\n singleHeaders[\"Content-Type\"] = \"application/json\";\n }\n const endpointUrl = this.runtimeEndpointUrl ?? this.runtimeUrl!;\n const response = await this.fetch(endpointUrl, {\n method: \"POST\",\n headers: singleHeaders,\n body: JSON.stringify({ method: \"info\" }),\n ...(this.credentials ? { credentials: this.credentials } : {}),\n });\n if (!response.ok) {\n throw await runtimeInfoError(response);\n }\n this.transport = \"single\";\n this.singleEndpointUrl = endpointUrl;\n return (await response.json()) as RuntimeInfo;\n }\n\n private createSingleRouteRequestInit(\n input: RunAgentInput,\n method: string,\n params?: Record<string, string>,\n ): RequestInit {\n if (!this.agentId) {\n throw new Error(\n \"ProxiedCopilotRuntimeAgent requires agentId to make runtime requests\",\n );\n }\n\n const baseInit = super.requestInit(input);\n const headers = new Headers(baseInit.headers ?? {});\n headers.set(\"Content-Type\", \"application/json\");\n headers.set(\"Accept\", headers.get(\"Accept\") ?? \"text/event-stream\");\n\n let originalBody: unknown = undefined;\n if (typeof baseInit.body === \"string\") {\n try {\n originalBody = JSON.parse(baseInit.body);\n } catch (error) {\n console.warn(\n \"ProxiedCopilotRuntimeAgent: failed to parse request body for single route transport\",\n error,\n );\n }\n }\n\n const envelope: Record<string, unknown> = { method };\n\n if (params && Object.keys(params).length > 0) {\n envelope.params = params;\n }\n\n if (originalBody !== undefined) {\n envelope.body = originalBody;\n }\n\n return {\n ...baseInit,\n headers,\n body: JSON.stringify(envelope),\n ...(this.credentials ? { credentials: this.credentials } : {}),\n };\n }\n\n private createIntelligenceDelegate(): AbstractAgent {\n const routedId = this.routedAgentId();\n if (!this.runtimeUrl || !routedId || !this.intelligence?.wsUrl) {\n throw new Error(\n \"Intelligence mode requires runtimeUrl, agentId, and intelligence websocket metadata\",\n );\n }\n\n const single = this.transport === \"single\";\n\n return new IntelligenceAgent({\n url: this.intelligence.wsUrl,\n // Single-route posts to the endpoint itself, so it needs the caller's URL\n // verbatim: a trailing slash can select a different proxy location\n // (issue #7028). REST needs the slash-stripped form, because it joins\n // `/agent/:id/:mode` onto it.\n runtimeUrl: single\n ? (this.runtimeEndpointUrl ?? this.runtimeUrl)\n : this.runtimeUrl,\n transport: single ? \"single\" : \"rest\",\n agentId: routedId,\n headers: { ...this.headers },\n credentials: this.credentials,\n fetch: this.fetch as typeof fetch,\n });\n }\n\n private syncDelegate(delegate: AbstractAgent): void {\n // Delegate is the IntelligenceAgent that talks to the runtime — it must\n // use the routed id so that requests reach the right runtime agent.\n delegate.agentId = this.routedAgentId();\n delegate.description = this.description;\n delegate.threadId = this.threadId;\n delegate.setMessages(this.messages);\n delegate.setState(this.state);\n\n if (hasHeaders(delegate)) {\n delegate.headers = { ...this.headers };\n }\n\n if (hasCredentials(delegate)) {\n delegate.credentials = this.credentials;\n }\n }\n}\n","const ABORT_MESSAGES: ReadonlySet<string> = new Set([\n \"Fetch is aborted\",\n \"signal is aborted without reason\",\n \"component unmounted\",\n]);\n\nexport function isAbortError(error: unknown): boolean {\n if (typeof error !== \"object\" || error === null) {\n return false;\n }\n const { name, message } = error as { name?: unknown; message?: unknown };\n if (name === \"AbortError\") {\n return true;\n }\n return typeof message === \"string\" && ABORT_MESSAGES.has(message);\n}\n","export const RUNTIME_REQUEST_WATCHDOG_MS = 10_000;\n\nexport interface RuntimeRequestMeta {\n nonCritical?: boolean;\n selfBounded?: boolean;\n timedOut?: boolean;\n}\n\nexport interface RuntimeRequestInit extends RequestInit {\n ɵruntimeRequest?: RuntimeRequestMeta;\n}\n\nexport function runtimeRequestMeta(\n init?: RequestInit,\n): RuntimeRequestMeta | undefined {\n return (init as RuntimeRequestInit | undefined)?.ɵruntimeRequest;\n}\n","interface SingleRouteResourceRequest {\n input: RequestInfo | URL;\n init: RequestInit;\n}\n\n/** Returns true when a path belongs to an Intelligence resource API. */\nfunction isIntelligenceResourcePath(path: string): boolean {\n return (\n path === \"/threads\" ||\n path.startsWith(\"/threads/\") ||\n path === \"/memories\" ||\n path.startsWith(\"/memories/\") ||\n path === \"/annotate\"\n );\n}\n\n/** Reads a JSON resource body without changing invalid JSON error behavior. */\nasync function readResourceBody(\n input: RequestInfo | URL,\n init: RequestInit | undefined,\n headers: Headers,\n method: string,\n): Promise<unknown | undefined> {\n if (method === \"GET\" || method === \"HEAD\") return undefined;\n\n let text: string | undefined;\n if (init?.body != null) {\n text = await new Response(init.body).text();\n } else if (input instanceof Request) {\n text = await input.clone().text();\n }\n if (!text) return undefined;\n\n if (headers.get(\"content-type\")?.toLowerCase().includes(\"application/json\")) {\n try {\n return JSON.parse(text) as unknown;\n } catch {\n return text;\n }\n }\n return text;\n}\n\n/**\n * Converts one Runtime resource fetch into a single-route JSON envelope.\n * Requests outside the mounted Runtime or outside its resource APIs pass\n * through unchanged.\n */\nexport async function createSingleRouteResourceRequest(\n input: RequestInfo | URL,\n init: RequestInit | undefined,\n runtimeUrl: string,\n): Promise<SingleRouteResourceRequest | null> {\n const baseUrl =\n typeof window !== \"undefined\" && window.location?.href\n ? window.location.href\n : \"http://localhost\";\n const runtime = new URL(runtimeUrl, baseUrl);\n const inputUrl =\n input instanceof Request\n ? input.url\n : input instanceof URL\n ? input.href\n : input;\n const target = new URL(inputUrl, baseUrl);\n const runtimePath = runtime.pathname.replace(/\\/$/, \"\");\n if (target.origin !== runtime.origin) return null;\n if (!target.pathname.startsWith(`${runtimePath}/`)) return null;\n\n const resourcePath = target.pathname.slice(runtimePath.length);\n if (!isIntelligenceResourcePath(resourcePath)) return null;\n\n const method = (\n init?.method ?? (input instanceof Request ? input.method : \"GET\")\n ).toUpperCase();\n const headers = new Headers(\n init?.headers ?? (input instanceof Request ? input.headers : undefined),\n );\n const body = await readResourceBody(input, init, headers, method);\n headers.set(\"content-type\", \"application/json\");\n headers.delete(\"content-length\");\n\n const requestDefaults: RequestInit =\n input instanceof Request\n ? {\n cache: input.cache,\n credentials: input.credentials,\n integrity: input.integrity,\n keepalive: input.keepalive,\n mode: input.mode,\n redirect: input.redirect,\n referrer: input.referrer,\n referrerPolicy: input.referrerPolicy,\n signal: input.signal,\n }\n : {};\n\n return {\n input: runtimeUrl,\n init: {\n ...requestDefaults,\n ...init,\n method: \"POST\",\n headers,\n body: JSON.stringify({\n method: \"resource/request\",\n params: {\n path: `${resourcePath}${target.search}`,\n httpMethod: method,\n },\n ...(body === undefined ? {} : { body }),\n }),\n },\n };\n}\n","import type { AbstractAgent } from \"@ag-ui/client\";\nimport { HttpAgent } from \"@ag-ui/client\";\nimport type {\n RuntimeInfo,\n RuntimeMode,\n RuntimeLicenseStatus,\n RuntimeEntitlementResponse,\n IntelligenceRuntimeInfo,\n InspectorMetadataV1,\n ThreadEndpointRuntimeInfo,\n} from \"@copilotkit/shared\";\nimport {\n logger,\n parseInspectorMetadataV1,\n RUNTIME_MODE_SSE,\n resolveDebugConfig,\n} from \"@copilotkit/shared\";\nimport { ProxiedCopilotRuntimeAgent } from \"../agent\";\nimport type { CopilotKitCore, CopilotKitCoreFriendsAccess } from \"./core\";\nimport {\n CopilotKitCoreErrorCode,\n CopilotKitCoreRuntimeConnectionStatus,\n} from \"./core\";\nimport type { CopilotRuntimeTransport } from \"../types\";\nimport {\n isRuntimeInfoRequestError,\n runtimeInfoError,\n} from \"../utils/runtime-info-error\";\nimport { isAbortError } from \"../utils/abort-error\";\nimport type { RuntimeRequestMeta } from \"../utils/runtime-request\";\nimport {\n RUNTIME_REQUEST_WATCHDOG_MS,\n runtimeRequestMeta,\n} from \"../utils/runtime-request\";\nimport { createSingleRouteResourceRequest } from \"../utils/single-route-resource-request\";\n\ntype ResolvedCopilotRuntimeTransport = Exclude<CopilotRuntimeTransport, \"auto\">;\n\ntype RuntimeInfoFetchResult = {\n runtimeInfo: RuntimeInfo;\n resolvedTransport: ResolvedCopilotRuntimeTransport;\n};\n\n/** Maximum wait for optional Inspector metadata before degrading to absence. */\nconst INSPECTOR_METADATA_REQUEST_TIMEOUT_MS = 5_000;\n\nexport const ɵRUNTIME_PROBE_TIMEOUT_MS = 5_000;\n\ntype RuntimeRequestOutcome = \"ok\" | \"failed\" | \"aborted\" | \"ignored\";\n\nfunction classifyRuntimeRequestFailure(\n error: unknown,\n meta: RuntimeRequestMeta | undefined,\n): RuntimeRequestOutcome {\n if (meta?.nonCritical) {\n return \"ignored\";\n }\n if (isAbortError(error) && !meta?.timedOut) {\n return \"aborted\";\n }\n return \"failed\";\n}\n\ninterface RuntimeConnectionOptions {\n preserveOnFailure?: boolean;\n recovery?: boolean;\n}\n\n/** Build case-insensitive JSON headers without mutating the Core snapshot. */\nfunction withJsonContentType(headers: Record<string, string>): Headers {\n const requestHeaders = new Headers(headers);\n if (!requestHeaders.has(\"content-type\")) {\n requestHeaders.set(\"content-type\", \"application/json\");\n }\n return requestHeaders;\n}\n\nconst RUNTIME_ENTITLEMENT_RETRY_DELAY_MS = 5_000;\n\ninterface RuntimeConnectionAttempt {\n key: string;\n generation: number;\n}\n\ninterface RuntimeAgentConnection {\n runtimeUrl: string;\n /** The caller-supplied URL the proxy was built with (trailing slash intact). */\n endpointUrl?: string;\n transport: CopilotRuntimeTransport;\n}\n\nexport interface CopilotKitCoreAddAgentParams {\n id: string;\n agent: AbstractAgent;\n}\n\n/**\n * Parameters for registering a proxied agent against an existing runtime agent.\n */\nexport interface CopilotKitCoreRegisterProxiedAgentParams {\n /**\n * The local registry id under which the proxy is registered. Used by\n * `useAgent`, state-manager subscriptions, and all subscriber bookkeeping.\n * Must not collide with any existing local or runtime-discovered agent id.\n */\n agentId: string;\n /**\n * The id of the runtime agent that this proxy routes outbound HTTP requests\n * to. Invisible to subscribers — only affects URL paths and single-route\n * envelopes.\n */\n runtimeAgentId: string;\n}\n\nexport interface CopilotKitCoreRegisterProxiedAgentResult {\n agent: ProxiedCopilotRuntimeAgent;\n unregister: () => void;\n}\n\n/**\n * Manages agent registration, lifecycle, and runtime connectivity for CopilotKitCore.\n * Handles both local development agents and remote runtime agents.\n */\nexport class AgentRegistry {\n private _agents: Record<string, AbstractAgent> = {};\n private localAgents: Record<string, AbstractAgent> = {};\n private remoteAgents: Record<string, AbstractAgent> = {};\n\n private readonly mintedThreadIds = new WeakMap<AbstractAgent, string>();\n\n private _runtimeUrl?: string;\n /** The runtime URL as the caller supplied it; the single-route endpoint uses it verbatim. */\n private _runtimeEndpointUrl?: string;\n // Tracks an in-flight `/info` connection so concurrent calls targeting the\n // same runtime (url + requested transport) collapse to a single request\n // instead of each firing their own. See #5801.\n private _connectionInFlight?: {\n attempt: RuntimeConnectionAttempt;\n promise: Promise<void>;\n };\n private _runtimeConnectionGeneration = 0;\n private _activeRuntimeConnectionAttempt?: RuntimeConnectionAttempt;\n private _runtimeEntitlementRetryTimer?: ReturnType<typeof setTimeout>;\n private _runtimeEntitlementRetryAttemptedKey?: string;\n private _runtimeEntitlementRetryPendingKey?: string;\n private _runtimeVersion?: string;\n private _runtimeConnectionStatus: CopilotKitCoreRuntimeConnectionStatus =\n CopilotKitCoreRuntimeConnectionStatus.Disconnected;\n private _runtimeTransport: CopilotRuntimeTransport = \"auto\";\n // The transport MODE last requested via `setRuntimeTransport` (e.g. \"auto\").\n // Distinct from `_runtimeTransport`, which auto-detect overwrites with the\n // RESOLVED value (\"rest\"/\"single\"). The idempotency guard compares against\n // this so re-applying the same mode (the provider effect re-applies \"auto\"\n // on every render) is a no-op instead of re-running the /info handshake.\n private _requestedTransport: CopilotRuntimeTransport = \"auto\";\n private _audioFileTranscriptionEnabled: boolean = false;\n private _runtimeMode: RuntimeMode = RUNTIME_MODE_SSE;\n private _intelligence?: IntelligenceRuntimeInfo;\n private _threadEndpoints?: ThreadEndpointRuntimeInfo;\n private _singleRouteResourceOperations = false;\n private _suggestions?: boolean;\n private _inspectorLearning: boolean = false;\n private _inspectorMetadata?: InspectorMetadataV1;\n private _inspectorMetadataSupported: boolean = false;\n private inspectorMetadataRefreshReady: boolean = false;\n private inspectorMetadataConnectionGeneration: number = 0;\n private inspectorMetadataGeneration: number = 0;\n private inspectorMetadataHeadersGeneration: number = 0;\n private inspectorMetadataCredentialsGeneration: number = 0;\n private inspectorMetadataAbortController?: AbortController;\n private inspectorMetadataNotificationQueue: Promise<void> = Promise.resolve();\n private _a2uiEnabled: boolean = false;\n private _a2uiAgents?: string[];\n private _openGenerativeUIEnabled: boolean = false;\n private _licenseStatus?: RuntimeLicenseStatus;\n private _runtimeEntitlements?: RuntimeEntitlementResponse;\n private _telemetryDisabled: boolean = false;\n private remoteAgentConnections = new WeakMap<\n ProxiedCopilotRuntimeAgent,\n RuntimeAgentConnection\n >();\n\n private runtimeFetch?: typeof fetch;\n private runtimeProbeInFlight: boolean = false;\n private runtimeProbeToken: number = 0;\n private runtimeProbeAbortController?: AbortController;\n private runtimeRecoveryRunning: boolean = false;\n private runtimeRecoveryPending: boolean = false;\n private runtimeHealthGeneration: number = 0;\n\n /**\n * The headers each HttpAgent was constructed with, captured on the first\n * `applyHeadersToAgent` call for that agent (which, for agents the registry\n * owns, happens at registration before any core headers are applied). Core\n * headers are merged ON TOP of this baseline so that headers configured\n * directly on an agent (e.g. an `Authorization` for a self-hosted backend)\n * survive registration instead of being silently replaced. The baseline is\n * captured once and never re-captured, so a later direct mutation of\n * `agent.headers` is not folded into it. See #5635.\n */\n private agentOwnHeaders = new WeakMap<HttpAgent, Record<string, string>>();\n\n constructor(private core: CopilotKitCore) {}\n\n /**\n * Get all agents as a readonly record\n */\n get agents(): Readonly<Record<string, AbstractAgent>> {\n return this._agents;\n }\n\n get runtimeUrl(): string | undefined {\n return this._runtimeUrl;\n }\n\n get runtimeVersion(): string | undefined {\n return this._runtimeVersion;\n }\n\n get runtimeConnectionStatus(): CopilotKitCoreRuntimeConnectionStatus {\n return this._runtimeConnectionStatus;\n }\n\n get runtimeTransport(): CopilotRuntimeTransport {\n return this._runtimeTransport;\n }\n\n get audioFileTranscriptionEnabled(): boolean {\n return this._audioFileTranscriptionEnabled;\n }\n\n get runtimeMode(): RuntimeMode {\n return this._runtimeMode;\n }\n\n get intelligence(): IntelligenceRuntimeInfo | undefined {\n return this._intelligence;\n }\n\n get threadEndpoints(): ThreadEndpointRuntimeInfo | undefined {\n return this._threadEndpoints;\n }\n\n get suggestions(): boolean | undefined {\n return this._suggestions;\n }\n\n get inspectorLearning(): boolean {\n return this._inspectorLearning;\n }\n\n get inspectorMetadata(): InspectorMetadataV1 | undefined {\n return this._inspectorMetadata;\n }\n\n get a2uiEnabled(): boolean {\n return this._a2uiEnabled;\n }\n\n /**\n * Agent ids the runtime applies A2UI to (#5369). `undefined` means A2UI\n * applies to every agent — or is disabled entirely; check `a2uiEnabled`.\n */\n get a2uiAgents(): string[] | undefined {\n return this._a2uiAgents;\n }\n\n get openGenerativeUIEnabled(): boolean {\n return this._openGenerativeUIEnabled;\n }\n\n get licenseStatus(): RuntimeLicenseStatus | undefined {\n return this._licenseStatus;\n }\n\n /** Structured Runtime entitlement authority advertised by `/info`. */\n get runtimeEntitlements(): RuntimeEntitlementResponse | undefined {\n return this._runtimeEntitlements;\n }\n\n get runtimeEntitlementRetryPending(): boolean {\n return (\n this._runtimeEntitlementRetryPendingKey === this.runtimeConnectionKey()\n );\n }\n\n get telemetryDisabled(): boolean {\n return this._telemetryDisabled;\n }\n\n /**\n * Initialize agents from configuration\n */\n initialize(agents: Record<string, AbstractAgent>): void {\n this.localAgents = this.assignAgentIds(agents);\n this.applyHeadersToAgents(this.localAgents);\n this.applyCredentialsToAgents(this.localAgents);\n this.applyMessageFilterToAgents(this.localAgents);\n this.applyRuntimeFetchToAgents(this.localAgents);\n this._agents = this.localAgents;\n }\n\n /**\n * Set the runtime URL and update connection\n */\n setRuntimeUrl(\n runtimeUrl: string | undefined,\n options?: { deferConnection?: boolean },\n ): void {\n const normalizedRuntimeUrl = runtimeUrl\n ? runtimeUrl.replace(/\\/$/, \"\")\n : undefined;\n const runtimeEndpointUrl = runtimeUrl || undefined;\n\n if (\n this._runtimeUrl === normalizedRuntimeUrl &&\n this._runtimeEndpointUrl === runtimeEndpointUrl\n ) {\n return;\n }\n\n this.invalidateInspectorMetadataConnection();\n this.abandonRuntimeHealthProbe();\n this.resetRuntimeEntitlementRetry();\n // Runtime authority is scoped to the target that advertised it. Clear it\n // before subscribers observe the replacement target connecting.\n this._licenseStatus = undefined;\n this._runtimeEntitlements = undefined;\n this._singleRouteResourceOperations = false;\n this._runtimeUrl = normalizedRuntimeUrl;\n this._runtimeEndpointUrl = runtimeEndpointUrl;\n\n // Deferred construction (see CopilotKitCore.connect / #5801): record the URL\n // so getters/hooks see it synchronously, but do NOT start the `/info` fetch\n // here. The host starts it from a commit-phase effect via `connect()`, so\n // renders discarded before commit never issue a request.\n if (options?.deferConnection) {\n return;\n }\n\n void this.updateRuntimeConnection({\n preserveOnFailure: this.hasLiveRuntimeKnowledgeToProtect(),\n });\n }\n\n /**\n * Start the initial runtime connection if it has not been started yet.\n *\n * Backs {@link CopilotKitCore.connect}. Idempotent: it only kicks off a fetch\n * when a `runtimeUrl` is set and the connection is still `Disconnected` (its\n * state before any connect attempt). `updateRuntimeConnection` flips the\n * status to `Connecting` synchronously, so a second call — e.g. React\n * StrictMode double-invoking the mount effect — bails here. A genuine config\n * change still reconnects through `setRuntimeUrl`/`setRuntimeTransport`. See\n * #5801.\n */\n connectRuntime(): void {\n if (typeof window === \"undefined\") {\n return;\n }\n if (!this._runtimeUrl) {\n return;\n }\n if (\n this._runtimeConnectionStatus !==\n CopilotKitCoreRuntimeConnectionStatus.Disconnected\n ) {\n return;\n }\n void this.updateRuntimeConnection();\n }\n\n setRuntimeTransport(runtimeTransport: CopilotRuntimeTransport): void {\n // Guard on the requested MODE, not the resolved value: after auto-detect\n // writes `_runtimeTransport = \"rest\"`, re-applying the same requested\n // \"auto\" must not be treated as a change (otherwise every provider\n // re-render re-runs the /info handshake and rebuilds agents).\n if (this._requestedTransport === runtimeTransport) {\n return;\n }\n\n this.invalidateInspectorMetadataConnection();\n this.abandonRuntimeHealthProbe();\n this.resetRuntimeEntitlementRetry();\n this._requestedTransport = runtimeTransport;\n this._runtimeTransport = runtimeTransport;\n this._singleRouteResourceOperations = false;\n void this.updateRuntimeConnection({\n preserveOnFailure: this.hasLiveRuntimeKnowledgeToProtect(),\n });\n }\n\n private hasLiveRuntimeKnowledgeToProtect(): boolean {\n if (Object.keys(this.remoteAgents).length === 0) {\n return false;\n }\n return (\n this._runtimeConnectionStatus !==\n CopilotKitCoreRuntimeConnectionStatus.Connected\n );\n }\n\n private reconcileRecoveredAgents(\n reported: Record<string, AbstractAgent>,\n ): Record<string, AbstractAgent> {\n const merged = { ...this.remoteAgents, ...reported };\n if (Object.keys(reported).length === 0) {\n return merged;\n }\n for (const [id, agent] of Object.entries(merged)) {\n if (Object.prototype.hasOwnProperty.call(reported, id)) {\n continue;\n }\n if (this.carriesConversationState(agent)) {\n continue;\n }\n delete merged[id];\n }\n return merged;\n }\n\n private carriesConversationState(agent: AbstractAgent): boolean {\n if (agent.messages.length > 0) {\n return true;\n }\n const mintedThreadId = this.mintedThreadIds.get(agent);\n return mintedThreadId === undefined || agent.threadId !== mintedThreadId;\n }\n\n private abandonRuntimeHealthProbe(): void {\n this.runtimeProbeToken += 1;\n this.runtimeProbeInFlight = false;\n this.runtimeHealthGeneration += 1;\n this.runtimeProbeAbortController?.abort();\n this.runtimeProbeAbortController = undefined;\n }\n\n /**\n * Set all agents at once (for development use)\n */\n setAgents__unsafe_dev_only(agents: Record<string, AbstractAgent>): void {\n // Validate all agents before making any changes\n Object.entries(agents).forEach(([id, agent]) => {\n if (agent) {\n this.validateAndAssignAgentId(id, agent);\n }\n });\n this.localAgents = agents;\n this._agents = { ...this.localAgents, ...this.remoteAgents };\n this.applyHeadersToAgents(this._agents);\n this.applyCredentialsToAgents(this._agents);\n this.applyMessageFilterToAgents(this._agents);\n this.applyRuntimeFetchToAgents(this._agents);\n void this.notifyAgentsChanged();\n }\n\n /**\n * Add a single agent (for development use)\n */\n addAgent__unsafe_dev_only({ id, agent }: CopilotKitCoreAddAgentParams): void {\n this.validateAndAssignAgentId(id, agent);\n this.localAgents[id] = agent;\n this.applyHeadersToAgent(agent);\n this.applyCredentialsToAgent(agent);\n this.applyRuntimeFetchToAgent(agent);\n this._agents = { ...this.localAgents, ...this.remoteAgents };\n void this.notifyAgentsChanged();\n }\n\n /**\n * Remove an agent by ID (for development use)\n */\n removeAgent__unsafe_dev_only(id: string): void {\n delete this.localAgents[id];\n this._agents = { ...this.localAgents, ...this.remoteAgents };\n void this.notifyAgentsChanged();\n }\n\n /**\n * Register a proxied agent that routes outbound runtime requests to an\n * existing runtime agent (`runtimeAgentId`) while exposing a distinct local\n * registry id (`agentId`). Throws if `agentId` is already taken by either a\n * local or runtime-discovered agent.\n *\n * Use this to mount multiple frontend agents against a single runtime\n * agent (e.g. a chat-1 / chat-2 pair both proxying to \"default\") without\n * implicit per-thread cloning. The returned `unregister` removes the proxy\n * from the registry and emits `onAgentsChanged`.\n */\n registerProxiedAgent({\n agentId,\n runtimeAgentId,\n }: CopilotKitCoreRegisterProxiedAgentParams): CopilotKitCoreRegisterProxiedAgentResult {\n // Use hasOwnProperty rather than `in`: `in` walks the prototype chain,\n // so an agentId of \"__proto__\", \"constructor\", \"toString\" etc. would\n // falsely test as already-registered.\n if (Object.prototype.hasOwnProperty.call(this._agents, agentId)) {\n throw new Error(\n `CopilotKitCore.registerProxiedAgent: agentId \"${agentId}\" is already registered. ` +\n `Pick a different agentId, or unregister the existing agent first.`,\n );\n }\n\n const friends = this.core as unknown as CopilotKitCoreFriendsAccess;\n const debug = friends.debug;\n const agent = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: this._runtimeEndpointUrl ?? this._runtimeUrl,\n agentId,\n runtimeAgentId,\n transport: this._runtimeTransport,\n credentials: friends.credentials,\n // If runtime info has already synced, mirror its mode/intelligence so\n // the proxy doesn't have to re-resolve. Otherwise stay \"pending\" until\n // /info lands.\n runtimeMode: this._runtimeUrl\n ? this._runtimeConnectionStatus ===\n CopilotKitCoreRuntimeConnectionStatus.Connected\n ? this._runtimeMode\n : \"pending\"\n : RUNTIME_MODE_SSE,\n intelligence: this._intelligence,\n debug: debug ? resolveDebugConfig(debug) : undefined,\n messageFilter: friends.messageFilter,\n });\n this.applyHeadersToAgent(agent);\n this.applyRuntimeFetchToAgent(agent);\n\n this.localAgents[agentId] = agent;\n this._agents = { ...this.localAgents, ...this.remoteAgents };\n void this.notifyAgentsChanged();\n\n return {\n agent,\n unregister: () => {\n // Only unregister if the same instance is still in place — guards\n // against double-unregister or against unregistering after a\n // subsequent register replaced the slot.\n if (this.localAgents[agentId] === agent) {\n delete this.localAgents[agentId];\n this._agents = { ...this.localAgents, ...this.remoteAgents };\n void this.notifyAgentsChanged();\n }\n },\n };\n }\n\n /**\n * Get an agent by ID\n */\n getAgent(id: string): AbstractAgent | undefined {\n if (id in this._agents) {\n return this._agents[id] as AbstractAgent;\n }\n\n // Silently return undefined if we're still loading runtime agents\n if (\n this.runtimeUrl !== undefined &&\n (this.runtimeConnectionStatus ===\n CopilotKitCoreRuntimeConnectionStatus.Disconnected ||\n this.runtimeConnectionStatus ===\n CopilotKitCoreRuntimeConnectionStatus.Connecting)\n ) {\n return undefined;\n }\n\n console.warn(`Agent ${id} not found`);\n return undefined;\n }\n\n /**\n * Apply current core headers to an agent, merged ON TOP of the agent's own\n * construction-time headers (the per-agent baseline in `agentOwnHeaders`).\n * Core wins on a key conflict. Non-`HttpAgent` agents are left untouched\n * because only `HttpAgent` carries a `headers` field. See #5635.\n */\n applyHeadersToAgent(agent: AbstractAgent): void {\n if (agent instanceof HttpAgent) {\n // Capture the agent's construction-time headers once, before any core\n // headers overwrite them. On every subsequent apply we rebuild from this\n // baseline so re-applying core headers (e.g. via setHeaders) never loses\n // the agent's own headers.\n if (!this.agentOwnHeaders.has(agent)) {\n this.agentOwnHeaders.set(agent, { ...agent.headers });\n }\n agent.headers = {\n ...this.agentOwnHeaders.get(agent),\n ...(this.core as unknown as CopilotKitCoreFriendsAccess).headers,\n };\n }\n }\n\n /**\n * Apply current headers to all agents\n */\n applyHeadersToAgents(agents: Record<string, AbstractAgent>): void {\n Object.values(agents).forEach((agent) => {\n this.applyHeadersToAgent(agent);\n });\n }\n\n /**\n * Apply current credentials to an agent\n */\n applyCredentialsToAgent(agent: AbstractAgent): void {\n if (agent instanceof ProxiedCopilotRuntimeAgent) {\n agent.credentials = (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).credentials;\n }\n }\n\n /**\n * Apply current credentials to all agents\n */\n applyCredentialsToAgents(agents: Record<string, AbstractAgent>): void {\n Object.values(agents).forEach((agent) => {\n this.applyCredentialsToAgent(agent);\n });\n }\n\n /**\n * Carry the mode a fresh `/info` reported onto a proxy this re-sync kept.\n *\n * `canReuseRuntimeAgent` deliberately ignores the mode: a preserved proxy is\n * backing an open conversation, and replacing the instance to change one\n * field would drop it. The mode is therefore pushed onto the survivor here,\n * the same way headers and credentials are. Without it the mode was fixed at\n * construction, so a runtime that flipped `intelligence` → `sse` under an\n * open page left every later run on the delegate path. See #7130.\n */\n applyRuntimeModeToAgent(\n agent: AbstractAgent,\n runtimeInfo: RuntimeInfo,\n ): void {\n if (agent instanceof ProxiedCopilotRuntimeAgent) {\n agent.adoptRuntimeMode(\n runtimeInfo.mode ?? RUNTIME_MODE_SSE,\n runtimeInfo.intelligence,\n );\n }\n }\n\n /**\n * Apply the core's message filter to an agent.\n *\n * The test is the class, not which bucket the agent is registered in: every\n * `ProxiedCopilotRuntimeAgent` gets the core filter, whether it came from\n * `/info` or from `registerProxiedAgent` (which files its proxy under\n * `localAgents`). Agents of any other class are left untouched — an\n * `AbstractAgent` the app built has no such hook, and its owner already has\n * the AG-UI middleware seam.\n *\n * This is the sole writer of `agent.messageFilter` in normal operation. The\n * public setter exists for the registry and for tests; a value written\n * directly onto an agent is replaced the next time the registry sweeps, the\n * same way per-agent credentials are.\n */\n applyMessageFilterToAgent(agent: AbstractAgent): void {\n if (agent instanceof ProxiedCopilotRuntimeAgent) {\n agent.messageFilter = (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).messageFilter;\n }\n }\n\n /**\n * Apply the core's message filter to all agents\n */\n applyMessageFilterToAgents(agents: Record<string, AbstractAgent>): void {\n Object.values(agents).forEach((agent) => {\n this.applyMessageFilterToAgent(agent);\n });\n }\n\n createRuntimeFetch(): typeof fetch {\n if (!this.runtimeFetch) {\n this.runtimeFetch = (async (\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> => {\n const meta = () => runtimeRequestMeta(init);\n const watchdog = this.armRuntimeRequestWatchdog(meta());\n try {\n const singleRouteRequest =\n this._runtimeTransport === \"single\" &&\n this._singleRouteResourceOperations &&\n this._runtimeUrl\n ? await createSingleRouteResourceRequest(\n input,\n init,\n // The endpoint itself is the POST target here, so it has to be\n // the caller's URL verbatim - a trailing slash can select a\n // different proxy location. `_runtimeUrl` is the slash-stripped\n // form kept for path joins (issue #7028).\n this._runtimeEndpointUrl ?? this._runtimeUrl,\n )\n : null;\n const response = singleRouteRequest\n ? await fetch(singleRouteRequest.input, singleRouteRequest.init)\n : await fetch(input, init);\n watchdog.clear();\n this.handleRuntimeRequestOutcome(\n response.ok ? \"ok\" : meta()?.nonCritical ? \"ignored\" : \"failed\",\n watchdog.checked,\n );\n return response;\n } catch (error) {\n watchdog.clear();\n this.handleRuntimeRequestOutcome(\n classifyRuntimeRequestFailure(error, meta()),\n watchdog.checked,\n );\n throw error;\n }\n }) as typeof fetch;\n }\n return this.runtimeFetch;\n }\n\n private armRuntimeRequestWatchdog(meta: RuntimeRequestMeta | undefined): {\n clear: () => void;\n checked: () => boolean;\n } {\n if (\n typeof window === \"undefined\" ||\n meta?.nonCritical ||\n meta?.selfBounded\n ) {\n return { clear: () => {}, checked: () => false };\n }\n let checked = false;\n const timeoutId = setTimeout(() => {\n checked = this.handleRuntimeRequestOutcome(\"failed\");\n }, RUNTIME_REQUEST_WATCHDOG_MS);\n return {\n clear: () => clearTimeout(timeoutId),\n checked: () => checked,\n };\n }\n\n applyRuntimeFetchToAgent(agent: AbstractAgent): void {\n if (agent instanceof ProxiedCopilotRuntimeAgent) {\n agent.fetch = this.createRuntimeFetch();\n }\n }\n\n applyRuntimeFetchToAgents(agents: Record<string, AbstractAgent>): void {\n Object.values(agents).forEach((agent) => {\n this.applyRuntimeFetchToAgent(agent);\n });\n }\n\n /** Refresh metadata after the Core header snapshot changes. */\n handleHeadersChanged(): void {\n this.inspectorMetadataHeadersGeneration += 1;\n this.setInspectorMetadata(undefined);\n void this.refreshInspectorMetadata();\n }\n\n /** Refresh metadata after the Core credentials mode changes. */\n handleCredentialsChanged(): void {\n this.inspectorMetadataCredentialsGeneration += 1;\n this.setInspectorMetadata(undefined);\n void this.refreshInspectorMetadata();\n }\n\n /**\n * Fetch trusted inspector metadata independently from runtime discovery.\n * Optional-route failures degrade to absent metadata and never affect the\n * runtime connection state.\n */\n async refreshInspectorMetadata(): Promise<void> {\n const generation = ++this.inspectorMetadataGeneration;\n this.inspectorMetadataAbortController?.abort();\n this.inspectorMetadataAbortController = undefined;\n\n if (\n !this._inspectorMetadataSupported ||\n !this.inspectorMetadataRefreshReady ||\n !this.runtimeUrl ||\n this._runtimeConnectionStatus !==\n CopilotKitCoreRuntimeConnectionStatus.Connected\n ) {\n this.setInspectorMetadata(undefined);\n return;\n }\n\n const runtimeUrl = this.runtimeUrl;\n const requestedTransport = this._requestedTransport;\n const resolvedTransport = this._runtimeTransport;\n const headersGeneration = this.inspectorMetadataHeadersGeneration;\n const credentialsGeneration = this.inspectorMetadataCredentialsGeneration;\n const friends = this.core as unknown as CopilotKitCoreFriendsAccess;\n const headers = { ...friends.headers };\n const credentials = friends.credentials;\n const abortController = new AbortController();\n this.inspectorMetadataAbortController = abortController;\n\n let timedOut = false;\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n let rejectForAbort: ((reason: Error) => void) | undefined;\n const aborted = new Promise<never>((_resolve, reject) => {\n rejectForAbort = reject;\n });\n const handleAbort = () => {\n rejectForAbort?.(new Error(\"Inspector metadata request aborted\"));\n };\n abortController.signal.addEventListener(\"abort\", handleAbort, {\n once: true,\n });\n const timeout = new Promise<never>((_resolve, reject) => {\n timeoutId = setTimeout(() => {\n timedOut = true;\n reject(new Error(\"Inspector metadata request timed out\"));\n abortController.abort();\n }, INSPECTOR_METADATA_REQUEST_TIMEOUT_MS);\n });\n\n let nextMetadata: InspectorMetadataV1 | undefined;\n try {\n const request = (async () => {\n const response =\n resolvedTransport === \"single\"\n ? await this.fetchInspectorMetadataSingle({\n runtimeUrl: this.singleEndpointUrlFor(runtimeUrl),\n headers,\n credentials,\n signal: abortController.signal,\n })\n : await this.fetchInspectorMetadataRest({\n runtimeUrl,\n headers,\n credentials,\n signal: abortController.signal,\n });\n\n if (response.status === 204 || !response.ok) {\n return undefined;\n }\n return parseInspectorMetadataV1(await response.json());\n })();\n nextMetadata = await Promise.race([request, aborted, timeout]);\n } catch {\n nextMetadata = undefined;\n } finally {\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n }\n abortController.signal.removeEventListener(\"abort\", handleAbort);\n }\n\n if (\n !this.isInspectorMetadataRequestCurrent({\n generation,\n runtimeUrl,\n requestedTransport,\n resolvedTransport,\n headersGeneration,\n credentialsGeneration,\n signal: abortController.signal,\n allowAbortedSignal: timedOut,\n })\n ) {\n return;\n }\n\n this.inspectorMetadataAbortController = undefined;\n this.setInspectorMetadata(nextMetadata);\n }\n\n private async fetchInspectorMetadataRest({\n runtimeUrl,\n headers,\n credentials,\n signal,\n }: {\n runtimeUrl: string;\n headers: Record<string, string>;\n credentials: RequestCredentials | undefined;\n signal: AbortSignal;\n }): Promise<Response> {\n return fetch(`${runtimeUrl}/inspector-metadata`, {\n method: \"GET\",\n headers,\n ...(credentials ? { credentials } : {}),\n signal,\n });\n }\n\n private async fetchInspectorMetadataSingle({\n runtimeUrl,\n headers,\n credentials,\n signal,\n }: {\n runtimeUrl: string;\n headers: Record<string, string>;\n credentials: RequestCredentials | undefined;\n signal: AbortSignal;\n }): Promise<Response> {\n return fetch(runtimeUrl, {\n method: \"POST\",\n headers: withJsonContentType(headers),\n body: JSON.stringify({ method: \"inspector/metadata\" }),\n ...(credentials ? { credentials } : {}),\n signal,\n });\n }\n\n private isInspectorMetadataRequestCurrent({\n generation,\n runtimeUrl,\n requestedTransport,\n resolvedTransport,\n headersGeneration,\n credentialsGeneration,\n signal,\n allowAbortedSignal = false,\n }: {\n generation: number;\n runtimeUrl: string;\n requestedTransport: CopilotRuntimeTransport;\n resolvedTransport: CopilotRuntimeTransport;\n headersGeneration: number;\n credentialsGeneration: number;\n signal: AbortSignal;\n allowAbortedSignal?: boolean;\n }): boolean {\n return (\n (allowAbortedSignal || !signal.aborted) &&\n generation === this.inspectorMetadataGeneration &&\n runtimeUrl === this.runtimeUrl &&\n requestedTransport === this._requestedTransport &&\n resolvedTransport === this._runtimeTransport &&\n headersGeneration === this.inspectorMetadataHeadersGeneration &&\n credentialsGeneration === this.inspectorMetadataCredentialsGeneration &&\n this._inspectorMetadataSupported &&\n this.inspectorMetadataRefreshReady &&\n this._runtimeConnectionStatus ===\n CopilotKitCoreRuntimeConnectionStatus.Connected\n );\n }\n\n private invalidateInspectorMetadataConnection(): void {\n this._inspectorMetadataSupported = false;\n this._inspectorLearning = false;\n this.inspectorMetadataRefreshReady = false;\n this.inspectorMetadataConnectionGeneration += 1;\n this.inspectorMetadataGeneration += 1;\n this.inspectorMetadataAbortController?.abort();\n this.inspectorMetadataAbortController = undefined;\n this.setInspectorMetadata(undefined);\n }\n\n /**\n * Publish one state transition without making refreshes wait on subscribers.\n * Each queued callback closes over its readonly snapshot so reentrant changes\n * cannot replace the value that an older publication is still delivering.\n */\n private setInspectorMetadata(\n inspectorMetadata: InspectorMetadataV1 | undefined,\n ): void {\n if (\n JSON.stringify(this._inspectorMetadata) ===\n JSON.stringify(inspectorMetadata)\n ) {\n return;\n }\n\n this._inspectorMetadata = inspectorMetadata;\n const snapshot = inspectorMetadata;\n this.inspectorMetadataNotificationQueue =\n this.inspectorMetadataNotificationQueue\n .then(() => this.notifyInspectorMetadataChanged(snapshot))\n .catch((error: unknown) => {\n console.error(\n \"Subscriber onInspectorMetadataChanged queue error:\",\n error,\n );\n });\n }\n\n private setRuntimeConnectionStatus(\n status: CopilotKitCoreRuntimeConnectionStatus,\n ): void {\n this._runtimeConnectionStatus = status;\n this.runtimeHealthGeneration += 1;\n }\n\n private handleRuntimeRequestOutcome(\n outcome: RuntimeRequestOutcome,\n alreadyChecked: () => boolean = () => false,\n ): boolean {\n if (outcome === \"aborted\" || outcome === \"ignored\") {\n return false;\n }\n if (outcome === \"failed\" && alreadyChecked()) {\n return false;\n }\n if (typeof window === \"undefined\") {\n return false;\n }\n if (!this._runtimeUrl) {\n return false;\n }\n\n if (outcome === \"ok\") {\n this.runtimeHealthGeneration += 1;\n if (this.runtimeRecoveryRunning) {\n this.runtimeRecoveryPending = true;\n }\n if (\n this._runtimeConnectionStatus ===\n CopilotKitCoreRuntimeConnectionStatus.Error\n ) {\n void this.recoverRuntimeConnection();\n }\n return false;\n }\n\n if (\n this._runtimeConnectionStatus !==\n CopilotKitCoreRuntimeConnectionStatus.Connected\n ) {\n return false;\n }\n if (this.runtimeProbeInFlight) {\n return false;\n }\n void this.probeRuntimeReachability();\n return true;\n }\n\n private async fetchRuntimeInfoWithTimeout(\n abortController: AbortController,\n runtimeUrl = this.runtimeUrl,\n runtimeTransport = this._runtimeTransport,\n ): Promise<RuntimeInfoFetchResult> {\n if (!runtimeUrl) {\n throw new Error(\"Runtime URL is not set\");\n }\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const request = this.fetchRuntimeInfo(\n runtimeUrl,\n runtimeTransport,\n abortController.signal,\n );\n void request.catch(() => {});\n try {\n const timedOut = new Promise<never>((_resolve, reject) => {\n timeoutId = setTimeout(() => {\n abortController.abort();\n reject(\n new Error(\n `Runtime did not answer within ${ɵRUNTIME_PROBE_TIMEOUT_MS}ms`,\n ),\n );\n }, ɵRUNTIME_PROBE_TIMEOUT_MS);\n });\n return await Promise.race([request, timedOut]);\n } finally {\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n }\n }\n }\n\n private async probeRuntimeReachability(): Promise<void> {\n const generation = this.runtimeHealthGeneration;\n const token = ++this.runtimeProbeToken;\n this.runtimeProbeInFlight = true;\n const abortController = new AbortController();\n this.runtimeProbeAbortController = abortController;\n try {\n await this.fetchRuntimeInfoWithTimeout(abortController);\n } catch (error) {\n if (generation !== this.runtimeHealthGeneration) {\n return;\n }\n await this.markRuntimeUnreachable(\n error instanceof Error ? error : new Error(String(error)),\n );\n } finally {\n if (this.runtimeProbeAbortController === abortController) {\n this.runtimeProbeAbortController = undefined;\n }\n if (this.runtimeProbeToken === token) {\n this.runtimeProbeInFlight = false;\n }\n }\n }\n\n private async markRuntimeUnreachable(error: Error): Promise<void> {\n this.setRuntimeConnectionStatus(\n CopilotKitCoreRuntimeConnectionStatus.Error,\n );\n await this.notifyRuntimeStatusChanged(\n CopilotKitCoreRuntimeConnectionStatus.Error,\n );\n\n const runtimeStatus = isRuntimeInfoRequestError(error)\n ? error.runtimeInfoStatus\n : undefined;\n logger.warn(\n runtimeStatus === undefined\n ? `Runtime did not answer the identification request (${this._runtimeUrl}/info): ${error.message}. The runtime appears to be unreachable.`\n : `Runtime answered the identification request with status ${runtimeStatus} (${this._runtimeUrl}/info): ${error.message}. The runtime is reachable but refused the request — check credentials and authorisation before addresses and ports.`,\n );\n await (this.core as unknown as CopilotKitCoreFriendsAccess).emitError({\n error,\n code: CopilotKitCoreErrorCode.RUNTIME_INFO_FETCH_FAILED,\n context: {\n runtimeUrl: this._runtimeUrl,\n reason: runtimeStatus === undefined ? \"no-answer\" : \"answered\",\n ...(runtimeStatus === undefined ? {} : { runtimeStatus }),\n },\n });\n }\n\n private async recoverRuntimeConnection(): Promise<void> {\n if (this.runtimeRecoveryRunning) {\n this.runtimeRecoveryPending = true;\n return;\n }\n this.runtimeRecoveryRunning = true;\n try {\n do {\n this.runtimeRecoveryPending = false;\n await this.updateRuntimeConnection({\n preserveOnFailure: true,\n recovery: true,\n });\n } while (\n this.runtimeRecoveryPending &&\n this._runtimeConnectionStatus !==\n CopilotKitCoreRuntimeConnectionStatus.Connected\n );\n } finally {\n this.runtimeRecoveryRunning = false;\n this.runtimeRecoveryPending = false;\n }\n }\n\n /**\n * Update runtime connection and fetch remote agents\n */\n private async updateRuntimeConnection(\n options?: RuntimeConnectionOptions,\n ): Promise<void> {\n // Skip fetching on the server (SSR)\n if (typeof window === \"undefined\") {\n return;\n }\n\n // In-flight guard: if a connection to the same target (runtime url +\n // requested transport) is already running, reuse it instead of starting a\n // second `/info` request. A change to a different target supersedes it. See\n // #5801.\n const key = this.runtimeConnectionKey();\n const inFlight = this._connectionInFlight;\n if (\n inFlight &&\n inFlight.attempt.key === key &&\n this.isCurrentRuntimeConnection(inFlight.attempt)\n ) {\n return inFlight.promise;\n }\n\n const attempt = {\n key,\n generation: ++this._runtimeConnectionGeneration,\n };\n this._activeRuntimeConnectionAttempt = attempt;\n const promise = this.performRuntimeConnection({\n attempt,\n runtimeUrl: this._runtimeUrl,\n transport: this._runtimeTransport,\n options,\n });\n this._connectionInFlight = { attempt, promise };\n void promise.finally(() => {\n if (this._connectionInFlight?.promise === promise) {\n this._connectionInFlight = undefined;\n }\n });\n return promise;\n }\n\n /** Return the stable key that scopes connection and entitlement retries. */\n private runtimeConnectionKey(): string {\n // The endpoint URL is part of the identity: a change that only adds or\n // drops the trailing slash targets a different single-route endpoint.\n return `${this._runtimeEndpointUrl ?? this._runtimeUrl ?? \"\"}::${this._requestedTransport}`;\n }\n\n /** Return whether a proxy still targets this Runtime connection. */\n private canReuseRuntimeAgent(\n agent: ProxiedCopilotRuntimeAgent,\n runtimeUrl: string | undefined,\n transport: CopilotRuntimeTransport,\n ): boolean {\n if (!runtimeUrl) {\n return false;\n }\n const connection = this.remoteAgentConnections.get(agent);\n return (\n connection?.runtimeUrl === runtimeUrl.replace(/\\/$/, \"\") &&\n connection.endpointUrl === this._runtimeEndpointUrl &&\n connection.transport === transport\n );\n }\n\n /** Return whether an async attempt still owns the active Runtime state. */\n private isCurrentRuntimeConnection(\n attempt: RuntimeConnectionAttempt,\n ): boolean {\n return (\n this._activeRuntimeConnectionAttempt?.generation === attempt.generation &&\n this.runtimeConnectionKey() === attempt.key\n );\n }\n\n /** Cancel a pending entitlement retry and allow a new target to retry. */\n private resetRuntimeEntitlementRetry(): void {\n if (this._runtimeEntitlementRetryTimer !== undefined) {\n clearTimeout(this._runtimeEntitlementRetryTimer);\n this._runtimeEntitlementRetryTimer = undefined;\n }\n this._runtimeEntitlementRetryAttemptedKey = undefined;\n this._runtimeEntitlementRetryPendingKey = undefined;\n }\n\n /** Schedule one retry after Runtime's short failed-entitlement cache. */\n private updateRuntimeEntitlementRetry(\n runtimeEntitlements: RuntimeEntitlementResponse | undefined,\n attempt: RuntimeConnectionAttempt,\n ): void {\n if (!this.isCurrentRuntimeConnection(attempt)) {\n return;\n }\n const { key } = attempt;\n if (\n runtimeEntitlements?.status === \"ready\" ||\n runtimeEntitlements?.error.retryable !== true\n ) {\n this.resetRuntimeEntitlementRetry();\n return;\n }\n if (this._runtimeEntitlementRetryTimer !== undefined) {\n return;\n }\n if (this._runtimeEntitlementRetryAttemptedKey === key) {\n this._runtimeEntitlementRetryPendingKey = undefined;\n return;\n }\n\n this._runtimeEntitlementRetryAttemptedKey = key;\n this._runtimeEntitlementRetryPendingKey = key;\n this._runtimeEntitlementRetryTimer = setTimeout(() => {\n this._runtimeEntitlementRetryTimer = undefined;\n void this.executeRuntimeEntitlementRetry(attempt).catch(\n (error: unknown) => {\n const message =\n error instanceof Error ? error.message : JSON.stringify(error);\n logger.warn(\n `Failed to retry runtime info (${this.runtimeUrl}/info): ${message}`,\n );\n },\n );\n }, RUNTIME_ENTITLEMENT_RETRY_DELAY_MS);\n }\n\n /** Start the bounded retry after the original connection has settled. */\n private async executeRuntimeEntitlementRetry(\n attempt: RuntimeConnectionAttempt,\n ): Promise<void> {\n const inFlight = this._connectionInFlight;\n if (inFlight?.attempt.generation === attempt.generation) {\n await inFlight.promise;\n }\n if (!this._runtimeUrl || !this.isCurrentRuntimeConnection(attempt)) {\n return;\n }\n await this.updateRuntimeConnection();\n }\n\n private async performRuntimeConnection({\n attempt,\n runtimeUrl,\n transport,\n options,\n }: {\n attempt: RuntimeConnectionAttempt;\n runtimeUrl: string | undefined;\n transport: CopilotRuntimeTransport;\n options?: RuntimeConnectionOptions;\n }): Promise<void> {\n const { key } = attempt;\n if (!runtimeUrl) {\n this.invalidateInspectorMetadataConnection();\n this.setRuntimeConnectionStatus(\n CopilotKitCoreRuntimeConnectionStatus.Disconnected,\n );\n this._runtimeVersion = undefined;\n this._audioFileTranscriptionEnabled = false;\n this._runtimeMode = RUNTIME_MODE_SSE;\n this._intelligence = undefined;\n this._threadEndpoints = undefined;\n this._singleRouteResourceOperations = false;\n this._suggestions = undefined;\n this._inspectorLearning = false;\n this._a2uiEnabled = false;\n this._a2uiAgents = undefined;\n this._openGenerativeUIEnabled = false;\n this._licenseStatus = undefined;\n this._runtimeEntitlements = undefined;\n this.remoteAgents = {};\n this._agents = this.localAgents;\n\n await this.notifyRuntimeStatusChanged(\n CopilotKitCoreRuntimeConnectionStatus.Disconnected,\n );\n if (!this.isCurrentRuntimeConnection(attempt)) {\n return;\n }\n await this.notifyAgentsChanged();\n return;\n }\n\n const inspectorMetadataConnectionGeneration =\n this.inspectorMetadataConnectionGeneration;\n\n this.setRuntimeConnectionStatus(\n CopilotKitCoreRuntimeConnectionStatus.Connecting,\n );\n const runtimeHealthGeneration = this.runtimeHealthGeneration;\n await this.notifyRuntimeStatusChanged(\n CopilotKitCoreRuntimeConnectionStatus.Connecting,\n );\n if (!this.isCurrentRuntimeConnection(attempt)) {\n return;\n }\n\n try {\n if (\n inspectorMetadataConnectionGeneration !==\n this.inspectorMetadataConnectionGeneration\n ) {\n return;\n }\n const { runtimeInfo: runtimeInfoResponse, resolvedTransport } =\n options?.recovery\n ? await this.fetchRuntimeInfoWithTimeout(\n new AbortController(),\n runtimeUrl,\n transport,\n )\n : await this.fetchRuntimeInfo(runtimeUrl, transport);\n if (\n !this.isCurrentRuntimeConnection(attempt) ||\n inspectorMetadataConnectionGeneration !==\n this.inspectorMetadataConnectionGeneration\n ) {\n return;\n }\n\n this._runtimeTransport = resolvedTransport;\n const { version, ...runtimeInfo } = runtimeInfoResponse;\n\n const credentials = (this.core as unknown as CopilotKitCoreFriendsAccess)\n .credentials;\n const rawDebug = (this.core as unknown as CopilotKitCoreFriendsAccess)\n .debug;\n const agents: Record<string, AbstractAgent> = Object.fromEntries(\n Object.entries(runtimeInfo.agents).map(\n ([id, { description, capabilities }]) => {\n // Preserve a live proxy only when its baked request routes still\n // match this connection. A new Runtime URL or resolved transport\n // needs a new proxy so agent traffic cannot keep using the old\n // target.\n const existing = Object.prototype.hasOwnProperty.call(\n this.remoteAgents,\n id,\n )\n ? this.remoteAgents[id]\n : undefined;\n if (\n existing instanceof ProxiedCopilotRuntimeAgent &&\n this.canReuseRuntimeAgent(\n existing,\n runtimeUrl,\n this._runtimeTransport,\n )\n ) {\n this.applyHeadersToAgent(existing);\n this.applyCredentialsToAgent(existing);\n this.applyMessageFilterToAgent(existing);\n this.applyRuntimeFetchToAgent(existing);\n this.applyRuntimeModeToAgent(existing, runtimeInfoResponse);\n return [id, existing];\n }\n const agent = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: this._runtimeEndpointUrl ?? runtimeUrl,\n agentId: id, // Runtime agents always have their ID set correctly\n description: description,\n transport: this._runtimeTransport,\n credentials,\n runtimeMode: runtimeInfoResponse.mode ?? RUNTIME_MODE_SSE,\n intelligence: runtimeInfoResponse.intelligence,\n capabilities,\n debug: rawDebug ? resolveDebugConfig(rawDebug) : undefined,\n messageFilter: (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).messageFilter,\n });\n this.applyHeadersToAgent(agent);\n this.applyRuntimeFetchToAgent(agent);\n this.mintedThreadIds.set(agent, agent.threadId);\n if (options?.preserveOnFailure === true && existing) {\n agent.threadId = existing.threadId;\n agent.setState(existing.state);\n agent.setMessages([...existing.messages]);\n }\n this.remoteAgentConnections.set(agent, {\n runtimeUrl,\n endpointUrl: this._runtimeEndpointUrl,\n transport: this._runtimeTransport,\n });\n return [id, agent];\n },\n ),\n );\n\n this.remoteAgents = options?.recovery\n ? this.reconcileRecoveredAgents(agents)\n : agents;\n this._agents = { ...this.localAgents, ...this.remoteAgents };\n this.setRuntimeConnectionStatus(\n CopilotKitCoreRuntimeConnectionStatus.Connected,\n );\n this._runtimeVersion = version;\n this._audioFileTranscriptionEnabled =\n runtimeInfoResponse.audioFileTranscriptionEnabled ?? false;\n this._runtimeMode = runtimeInfoResponse.mode ?? RUNTIME_MODE_SSE;\n this._intelligence = runtimeInfoResponse.intelligence;\n this._singleRouteResourceOperations =\n resolvedTransport === \"single\" &&\n runtimeInfoResponse.singleRoute?.resourceOperations === true;\n this._threadEndpoints = this._singleRouteResourceOperations\n ? runtimeInfoResponse.singleRoute?.threadEndpoints\n : runtimeInfoResponse.threadEndpoints;\n this._suggestions = runtimeInfoResponse.suggestions;\n this._inspectorLearning = runtimeInfoResponse.inspectorLearning === true;\n this._inspectorMetadataSupported =\n runtimeInfoResponse.inspectorMetadata === true;\n this.inspectorMetadataRefreshReady = false;\n if (!this._inspectorMetadataSupported) {\n this.setInspectorMetadata(undefined);\n }\n const a2uiInfo = runtimeInfoResponse.a2ui;\n this._a2uiEnabled =\n a2uiInfo?.enabled ?? runtimeInfoResponse.a2uiEnabled ?? false;\n this._a2uiAgents = a2uiInfo?.enabled ? a2uiInfo.agents : undefined;\n this._openGenerativeUIEnabled =\n runtimeInfoResponse.openGenerativeUIEnabled ?? false;\n this._licenseStatus = runtimeInfoResponse.licenseStatus;\n this._runtimeEntitlements = runtimeInfoResponse.runtimeEntitlements;\n this.updateRuntimeEntitlementRetry(\n runtimeInfoResponse.runtimeEntitlements,\n attempt,\n );\n this._telemetryDisabled = runtimeInfoResponse.telemetryDisabled ?? false;\n\n await this.notifyRuntimeStatusChanged(\n CopilotKitCoreRuntimeConnectionStatus.Connected,\n );\n if (!this.isCurrentRuntimeConnection(attempt)) {\n return;\n }\n await this.notifyAgentsChanged();\n if (\n inspectorMetadataConnectionGeneration !==\n this.inspectorMetadataConnectionGeneration ||\n this._runtimeConnectionStatus !==\n CopilotKitCoreRuntimeConnectionStatus.Connected\n ) {\n return;\n }\n this.inspectorMetadataRefreshReady = true;\n if (this._inspectorMetadataSupported) {\n void this.refreshInspectorMetadata();\n }\n } catch (error) {\n if (\n !this.isCurrentRuntimeConnection(attempt) ||\n inspectorMetadataConnectionGeneration !==\n this.inspectorMetadataConnectionGeneration\n ) {\n return;\n }\n const boundedEntitlementRetryFailed =\n this._runtimeEntitlementRetryTimer === undefined &&\n this._runtimeEntitlementRetryAttemptedKey === key &&\n this._runtimeEntitlementRetryPendingKey === key;\n if (boundedEntitlementRetryFailed) {\n this._runtimeEntitlementRetryPendingKey = undefined;\n }\n if (options?.preserveOnFailure) {\n if (\n options?.recovery &&\n runtimeHealthGeneration !== this.runtimeHealthGeneration\n ) {\n return;\n }\n this.setRuntimeConnectionStatus(\n CopilotKitCoreRuntimeConnectionStatus.Error,\n );\n await this.notifyRuntimeStatusChanged(\n CopilotKitCoreRuntimeConnectionStatus.Error,\n );\n } else {\n this.invalidateInspectorMetadataConnection();\n this.setRuntimeConnectionStatus(\n CopilotKitCoreRuntimeConnectionStatus.Error,\n );\n this._runtimeVersion = undefined;\n this._audioFileTranscriptionEnabled = false;\n this._runtimeMode = RUNTIME_MODE_SSE;\n this._intelligence = undefined;\n this._threadEndpoints = undefined;\n this._singleRouteResourceOperations = false;\n this._suggestions = undefined;\n this._inspectorLearning = false;\n this._a2uiEnabled = false;\n this._a2uiAgents = undefined;\n this._openGenerativeUIEnabled = false;\n // A failed bounded retry must settle the authority that caused it. Keep\n // that retryable result so consumers can distinguish terminal denial\n // from the initial loading window. Other connection failures still\n // clear stale Runtime authority.\n if (!boundedEntitlementRetryFailed) {\n this._licenseStatus = undefined;\n this._runtimeEntitlements = undefined;\n }\n this.remoteAgents = {};\n this._agents = this.localAgents;\n\n await this.notifyRuntimeStatusChanged(\n CopilotKitCoreRuntimeConnectionStatus.Error,\n );\n await this.notifyAgentsChanged();\n }\n\n const message =\n error instanceof Error ? error.message : JSON.stringify(error);\n logger.warn(\n `Failed to load runtime info (${runtimeUrl}/info): ${message}`,\n );\n const runtimeError =\n error instanceof Error ? error : new Error(String(error));\n await (this.core as unknown as CopilotKitCoreFriendsAccess).emitError({\n error: runtimeError,\n code: CopilotKitCoreErrorCode.RUNTIME_INFO_FETCH_FAILED,\n context: {\n runtimeUrl,\n },\n });\n }\n }\n\n private async fetchRuntimeInfo(\n runtimeUrl: string,\n runtimeTransport: CopilotRuntimeTransport,\n signal?: AbortSignal,\n ): Promise<RuntimeInfoFetchResult> {\n const baseHeaders = (this.core as unknown as CopilotKitCoreFriendsAccess)\n .headers;\n const credentials = (this.core as unknown as CopilotKitCoreFriendsAccess)\n .credentials;\n const headers: Record<string, string> = {\n ...baseHeaders,\n };\n\n if (runtimeTransport === \"single\") {\n return {\n runtimeInfo: await this.fetchRuntimeInfoSingle(\n this.singleEndpointUrlFor(runtimeUrl),\n headers,\n credentials,\n signal,\n ),\n resolvedTransport: \"single\",\n };\n }\n\n if (runtimeTransport === \"auto\") {\n return this.fetchRuntimeInfoAutoDetect(\n runtimeUrl,\n headers,\n credentials,\n signal,\n );\n }\n\n // REST transport\n const response = await fetch(`${runtimeUrl}/info`, {\n headers,\n ...(credentials ? { credentials } : {}),\n ...(signal ? { signal } : {}),\n });\n if (!response.ok) {\n throw await runtimeInfoError(response);\n }\n return {\n runtimeInfo: (await response.json()) as RuntimeInfo,\n resolvedTransport: \"rest\",\n };\n }\n\n /**\n * The URL a single-route request targets: the runtime URL as the caller\n * supplied it. `runtimeUrl` is the slash-stripped form used for path joins;\n * a trailing slash can select a different proxy location, so the endpoint\n * itself keeps it.\n */\n private singleEndpointUrlFor(runtimeUrl: string): string {\n return this._runtimeEndpointUrl !== undefined &&\n this._runtimeUrl === runtimeUrl\n ? this._runtimeEndpointUrl\n : runtimeUrl;\n }\n\n private async fetchRuntimeInfoSingle(\n runtimeUrl: string,\n headers: Record<string, string>,\n credentials: RequestCredentials | undefined,\n signal?: AbortSignal,\n ): Promise<RuntimeInfo> {\n const response = await fetch(runtimeUrl, {\n method: \"POST\",\n headers: withJsonContentType(headers),\n body: JSON.stringify({ method: \"info\" }),\n ...(credentials ? { credentials } : {}),\n ...(signal ? { signal } : {}),\n });\n if (!response.ok) {\n throw await runtimeInfoError(response);\n }\n return (await response.json()) as RuntimeInfo;\n }\n\n /**\n * Auto-detect transport by trying REST first, then falling back to single-endpoint.\n * The caller commits the detected transport only after confirming this\n * connection attempt is still current.\n */\n private async fetchRuntimeInfoAutoDetect(\n runtimeUrl: string,\n headers: Record<string, string>,\n credentials: RequestCredentials | undefined,\n signal?: AbortSignal,\n ): Promise<RuntimeInfoFetchResult> {\n // Try REST first (GET /info)\n try {\n const response = await fetch(`${runtimeUrl}/info`, {\n headers: { ...headers },\n ...(credentials ? { credentials } : {}),\n ...(signal ? { signal } : {}),\n });\n // Only treat a successful (2xx) response as a valid REST runtime.\n // 404/405 means the endpoint doesn't exist; other non-2xx errors\n // (500, 403, etc.) should also fall through to single-endpoint.\n if (response.status >= 200 && response.status < 300) {\n return {\n runtimeInfo: (await response.json()) as RuntimeInfo,\n resolvedTransport: \"rest\",\n };\n }\n // Non-2xx — try single-endpoint below\n } catch {\n // REST failed (network error, etc.) — fall through to single-endpoint attempt\n }\n\n const runtimeInfo = await this.fetchRuntimeInfoSingle(\n this.singleEndpointUrlFor(runtimeUrl),\n { ...headers },\n credentials,\n signal,\n );\n return { runtimeInfo, resolvedTransport: \"single\" };\n }\n\n /**\n * Assign agent IDs to a record of agents\n */\n private assignAgentIds(\n agents: Record<string, AbstractAgent>,\n ): Record<string, AbstractAgent> {\n Object.entries(agents).forEach(([id, agent]) => {\n if (agent) {\n this.validateAndAssignAgentId(id, agent);\n }\n });\n return agents;\n }\n\n /**\n * Validate and assign an agent ID\n */\n private validateAndAssignAgentId(\n registrationId: string,\n agent: AbstractAgent,\n ): void {\n if (agent.agentId && agent.agentId !== registrationId) {\n throw new Error(\n `Agent registration mismatch: Agent with ID \"${agent.agentId}\" cannot be registered under key \"${registrationId}\". ` +\n `The agent ID must match the registration key or be undefined.`,\n );\n }\n if (!agent.agentId) {\n agent.agentId = registrationId;\n }\n }\n\n /**\n * Notify subscribers of runtime status changes\n */\n private async notifyRuntimeStatusChanged(\n status: CopilotKitCoreRuntimeConnectionStatus,\n ): Promise<void> {\n await (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).notifySubscribers(\n (subscriber) =>\n subscriber.onRuntimeConnectionStatusChanged?.({\n copilotkit: this.core,\n status,\n }),\n \"Error in CopilotKitCore subscriber (onRuntimeConnectionStatusChanged):\",\n );\n }\n\n /**\n * Notify subscribers of agent changes\n */\n private async notifyAgentsChanged(): Promise<void> {\n await (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).notifySubscribers(\n (subscriber) =>\n subscriber.onAgentsChanged?.({\n copilotkit: this.core,\n agents: this._agents,\n }),\n \"Subscriber onAgentsChanged error:\",\n );\n }\n\n private async notifyInspectorMetadataChanged(\n inspectorMetadata: InspectorMetadataV1 | undefined,\n ): Promise<void> {\n await (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).notifySubscribers(\n (subscriber) =>\n subscriber.onInspectorMetadataChanged?.({\n copilotkit: this.core,\n inspectorMetadata,\n }),\n \"Subscriber onInspectorMetadataChanged error:\",\n );\n }\n}\n","import type { Context } from \"@ag-ui/client\";\nimport { randomUUID } from \"@copilotkit/shared\";\nimport type { CopilotKitCore } from \"./core\";\nimport type { CopilotKitCoreFriendsAccess } from \"./core\";\n\n/**\n * A context entry with optional per-agent scoping.\n * When `agentIds` is set, the entry is forwarded only to runs of those agents;\n * when omitted, the entry is forwarded to every agent run.\n */\nexport interface ScopedContext extends Context {\n agentIds?: string[];\n}\n\n/**\n * Manages context storage and lifecycle for CopilotKitCore.\n * Context represents additional information available to agents during execution.\n */\nexport class ContextStore {\n private _context: Record<string, ScopedContext> = {};\n\n constructor(private core: CopilotKitCore) {}\n\n /**\n * Get all context entries as a readonly record\n */\n get context(): Readonly<Record<string, ScopedContext>> {\n return this._context;\n }\n\n /**\n * Add a new context entry. Pass `agentIds` to restrict the entry to runs of\n * specific agents (#5369); omit it for context every agent should receive.\n * @returns The ID of the created context entry\n */\n addContext({ description, value, agentIds }: ScopedContext): string {\n const id = randomUUID();\n this._context[id] = {\n description,\n value,\n ...(agentIds ? { agentIds } : {}),\n };\n void this.notifySubscribers();\n return id;\n }\n\n /**\n * Build the context array for a run of the given agent: entries scoped to\n * other agents are dropped, and the scoping metadata is stripped so only\n * protocol-shaped `{ description, value }` entries go over the wire.\n */\n getContextForAgent(agentId?: string): Context[] {\n return Object.values(this._context)\n .filter(\n (entry) =>\n !entry.agentIds ||\n (agentId !== undefined && entry.agentIds.includes(agentId)),\n )\n .map(({ description, value }) => ({ description, value }));\n }\n\n /**\n * Remove a context entry by ID\n */\n removeContext(id: string): void {\n delete this._context[id];\n void this.notifySubscribers();\n }\n\n /**\n * Notify all subscribers of context changes\n */\n private async notifySubscribers(): Promise<void> {\n await (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).notifySubscribers(\n (subscriber) =>\n subscriber.onContextChanged?.({\n copilotkit: this.core,\n context: this._context,\n }),\n \"Subscriber onContextChanged error:\",\n );\n }\n}\n","import type { AbstractAgent, Message, Tool } from \"@ag-ui/client\";\nimport { HttpAgent } from \"@ag-ui/client\";\nimport { ProxiedCopilotRuntimeAgent } from \"../agent\";\nimport { randomUUID, partialJSONParse } from \"@copilotkit/shared\";\nimport type { CopilotKitCore } from \"./core\";\nimport type { CopilotKitCoreGetSuggestionsResult } from \"./core\";\nimport type { CopilotKitCoreFriendsAccess } from \"./core\";\nimport type {\n DynamicSuggestionsConfig,\n StaticSuggestionsConfig,\n Suggestion,\n SuggestionsConfig,\n} from \"../types\";\n\n/**\n * The minimal cancellation surface a running suggestion generation exposes.\n * Both a cloned `AbstractAgent` (via `abortRun`) and the stateless fetch shim\n * (which aborts an `AbortController`) satisfy this, so `clearSuggestions` can\n * cancel either uniformly.\n */\ninterface AbortableSuggestionRun {\n abortRun(): void;\n}\n\n/**\n * Manages suggestion generation, streaming, and lifecycle for CopilotKitCore.\n * Handles both dynamic (AI-generated) and static suggestions.\n */\nexport class SuggestionEngine {\n private _suggestionsConfig: Record<string, SuggestionsConfig> = {};\n private _suggestions: Record<string, Record<string, Suggestion[]>> = {};\n private _runningSuggestions: Record<string, AbortableSuggestionRun[]> = {};\n\n constructor(private core: CopilotKitCore) {}\n\n /**\n * Initialize with suggestion configs\n */\n initialize(suggestionsConfig: SuggestionsConfig[]): void {\n for (const config of suggestionsConfig) {\n this._suggestionsConfig[randomUUID()] = config;\n }\n }\n\n /**\n * Add a suggestion configuration\n * @returns The ID of the created config\n */\n addSuggestionsConfig(config: SuggestionsConfig): string {\n const id = randomUUID();\n this._suggestionsConfig[id] = config;\n void this.notifySuggestionsConfigChanged();\n return id;\n }\n\n /**\n * Remove a suggestion configuration by ID\n */\n removeSuggestionsConfig(id: string): void {\n delete this._suggestionsConfig[id];\n void this.notifySuggestionsConfigChanged();\n }\n\n /**\n * Reload suggestions for a specific agent\n * This triggers generation of new suggestions based on current configs\n */\n public reloadSuggestions(agentId: string): void {\n this.clearSuggestions(agentId);\n\n // The agent may legitimately be missing here (e.g. runtime info still loading,\n // or the consumer agent is configured but not yet registered) — static suggestions\n // don't need it, only dynamic generation does. Treat that case as \"no messages yet\"\n // and process static configs anyway.\n const agent = (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).getAgent(agentId);\n\n const messageCount = agent?.messages?.length ?? 0;\n let hasAnySuggestions = false;\n\n for (const config of Object.values(this._suggestionsConfig)) {\n // Check if config applies to this agent\n if (\n config.consumerAgentId !== undefined &&\n config.consumerAgentId !== \"*\" &&\n config.consumerAgentId !== agentId\n ) {\n continue;\n }\n\n // Check availability based on message count\n if (!this.shouldShowSuggestions(config, messageCount)) {\n continue;\n }\n\n const suggestionId = randomUUID();\n\n if (isDynamicSuggestionsConfig(config)) {\n // Dynamic suggestions need a real agent (provider + consumer messages).\n // Skip when the agent isn't ready yet — `reloadSuggestions` will be\n // called again once it is.\n if (!agent) {\n continue;\n }\n if (!hasAnySuggestions) {\n hasAnySuggestions = true;\n void this.notifySuggestionsStartedLoading(agentId);\n }\n void this.generateSuggestions(suggestionId, config, agentId);\n } else if (isStaticSuggestionsConfig(config)) {\n this.addStaticSuggestions(suggestionId, config, agentId);\n }\n }\n }\n\n /**\n * Clear all suggestions for a specific agent\n */\n public clearSuggestions(agentId: string): void {\n const runningAgents = this._runningSuggestions[agentId];\n if (runningAgents) {\n for (const agent of runningAgents) {\n agent.abortRun();\n }\n delete this._runningSuggestions[agentId];\n }\n this._suggestions[agentId] = {};\n\n void this.notifySuggestionsChanged(agentId, []);\n }\n\n /**\n * Get current suggestions for an agent\n */\n public getSuggestions(agentId: string): CopilotKitCoreGetSuggestionsResult {\n const suggestions = Object.values(this._suggestions[agentId] ?? {}).flat();\n const isLoading = (this._runningSuggestions[agentId]?.length ?? 0) > 0;\n return { suggestions, isLoading };\n }\n\n /**\n * Generate suggestions by running a provider agent and extracting the\n * `copilotkitSuggest` tool call from its streamed messages.\n *\n * Two transports, one set of mechanics: both seed an agent with the\n * consumer's messages + state and the instruction, then `runAgent` with\n * forced `copilotkitSuggest` tool choice, parsing suggestions as messages\n * stream in via `onMessagesChanged`.\n *\n * - **Stateless** (runtime advertises `suggestions` and transport isn't\n * `single`): a stock `HttpAgent` pointed at `/agent/:id/suggest`. That\n * endpoint runs the provider directly and streams AG-UI SSE **without**\n * persisting a thread, and a plain `HttpAgent` only ever speaks REST SSE —\n * it never routes through the Intelligence websocket delegate (which would\n * persist a thread). This is the path that removes the thread flood.\n * - **Fallback** (capability absent → old runtime, or `single` transport):\n * clone the provider agent and run it client-side, as before.\n *\n * Gated to non-`single` transports because this client only builds the\n * multi-route `/agent/:id/suggest` URL; single-route deployments (not the\n * persisting-thread/Intelligence case) fall through to the clone fallback.\n */\n private async generateSuggestions(\n suggestionId: string,\n config: DynamicSuggestionsConfig,\n consumerAgentId: string,\n ): Promise<void> {\n // The cancellable handle for this generation, removed from the running set\n // in `finally`. `abortRun` flips `aborted` before cancelling the underlying\n // agent so the `catch` can distinguish a deliberate clear/reload from a real\n // failure — some engines (undici, some React Native) reject an aborted run\n // with a non-\"AbortError\" error that `isAbortError` alone would misclassify.\n let runHandle: AbortableSuggestionRun | undefined = undefined;\n let aborted = false;\n try {\n const friends = this.core as unknown as CopilotKitCoreFriendsAccess;\n const resolvedProviderAgentId = config.providerAgentId ?? \"default\";\n const suggestionsProviderAgent = friends.getAgent(\n resolvedProviderAgentId,\n );\n if (!suggestionsProviderAgent) {\n throw new Error(\n `Suggestions provider agent not found: ${resolvedProviderAgentId}`,\n );\n }\n const suggestionsConsumerAgent = friends.getAgent(consumerAgentId);\n if (!suggestionsConsumerAgent) {\n throw new Error(\n `Suggestions consumer agent not found: ${consumerAgentId}`,\n );\n }\n\n const instructionContent = [\n `Suggest what the user could say next. Provide clear, highly relevant suggestions by calling the \\`copilotkitSuggest\\` tool.`,\n `Provide at least ${config.minSuggestions ?? 1} and at most ${\n config.maxSuggestions ?? 3\n } suggestions.`,\n `The user has the following tools available: ${JSON.stringify(\n friends.buildFrontendTools(consumerAgentId),\n )}.`,\n ` ${config.instructions}`,\n ].join(\"\\n\");\n\n // Initialize suggestion storage for this agent/suggestion combo\n this._suggestions[consumerAgentId] = {\n ...this._suggestions[consumerAgentId],\n [suggestionId]: [],\n };\n\n // Deep-clone the consumer's messages + state so the suggestion run sees\n // the same context a real turn would, without sharing mutable references.\n const seededMessages: Message[] = JSON.parse(\n JSON.stringify(suggestionsConsumerAgent.messages),\n );\n const seededState: unknown = JSON.parse(\n JSON.stringify(suggestionsConsumerAgent.state ?? {}),\n );\n\n const useStateless =\n this.core.suggestions === true &&\n this.core.runtimeTransport !== \"single\";\n\n let suggestionAgent: AbstractAgent;\n if (useStateless) {\n const suggestUrl = `${this.core.runtimeUrl}/agent/${encodeURIComponent(\n resolvedProviderAgentId,\n )}/suggest`;\n const credentials = this.core.credentials;\n suggestionAgent = new HttpAgent({\n agentId: resolvedProviderAgentId,\n url: suggestUrl,\n headers: { ...this.core.headers },\n // `HttpAgentConfig` has no `credentials` field; inject it via a fetch\n // wrapper so cookie-based / self-hosted auth still rides along on the\n // `/suggest` request.\n ...(credentials\n ? {\n fetch: (url: string, requestInit: RequestInit) =>\n fetch(url, { ...requestInit, credentials }),\n }\n : {}),\n });\n } else {\n suggestionAgent = suggestionsProviderAgent.clone();\n // A suggestion run gets a brand-new thread id, so no backend store can\n // fill in history the client withheld. An app-level `messageFilter`\n // trimmed for a persisted conversation would therefore leave the\n // provider with only the tail of the seeded context and generate\n // suggestions about nothing. The seeded messages ARE the context here.\n if (suggestionAgent instanceof ProxiedCopilotRuntimeAgent) {\n suggestionAgent.messageFilter = undefined;\n }\n }\n\n suggestionAgent.threadId = suggestionId;\n suggestionAgent.setMessages(seededMessages);\n suggestionAgent.setState(seededState);\n\n runHandle = {\n abortRun: () => {\n aborted = true;\n suggestionAgent.abortRun();\n },\n };\n this._runningSuggestions[consumerAgentId] = [\n ...(this._runningSuggestions[consumerAgentId] ?? []),\n runHandle,\n ];\n\n suggestionAgent.addMessage({\n id: suggestionId,\n role: \"user\",\n content: instructionContent,\n });\n\n await suggestionAgent.runAgent(\n {\n context: friends.getContextForAgent(consumerAgentId),\n forwardedProps: {\n ...friends.properties,\n toolChoice: {\n type: \"function\",\n function: { name: \"copilotkitSuggest\" },\n },\n },\n tools: [SUGGEST_TOOL],\n },\n {\n onMessagesChanged: ({ messages }) => {\n this.extractSuggestions(\n messages,\n suggestionId,\n consumerAgentId,\n true,\n );\n },\n },\n );\n } catch (error) {\n // An abort is expected when suggestions are cleared/reloaded mid-flight;\n // swallow it quietly rather than surfacing it as a failure. `isAbortError`\n // is the primary (name-based) check; `aborted` covers engines that reject\n // an aborted run with a differently-named error (or a `TypeError`).\n if (!isAbortError(error) && !aborted) {\n console.warn(\"Error generating suggestions:\", error);\n }\n } finally {\n // Finalize suggestions by marking them as no longer loading\n this.finalizeSuggestions(suggestionId, consumerAgentId);\n\n // Remove this run from the running set. `runHandle` may be undefined when\n // generation threw before it was assigned (e.g. provider/consumer agent\n // lookup failed); still perform cleanup so the loading balance holds. If\n // no runs remain for this consumer, emit finished-loading — otherwise a\n // subscriber that saw `started` would hang in the loading state.\n const runningAgents = this._runningSuggestions[consumerAgentId];\n const remaining = runHandle\n ? (runningAgents ?? []).filter((a) => a !== runHandle)\n : (runningAgents ?? []);\n\n if (remaining.length === 0) {\n delete this._runningSuggestions[consumerAgentId];\n await this.notifySuggestionsFinishedLoading(consumerAgentId);\n } else {\n this._runningSuggestions[consumerAgentId] = remaining;\n }\n }\n }\n\n /**\n * Finalize suggestions by marking them as no longer loading\n */\n private finalizeSuggestions(\n suggestionId: string,\n consumerAgentId: string,\n ): void {\n const agentSuggestions = this._suggestions[consumerAgentId];\n const currentSuggestions = agentSuggestions?.[suggestionId];\n\n if (\n agentSuggestions &&\n currentSuggestions &&\n currentSuggestions.length > 0\n ) {\n // Filter out empty suggestions and mark remaining as no longer loading\n const finalizedSuggestions = currentSuggestions\n .filter(\n (suggestion) => suggestion.title !== \"\" || suggestion.message !== \"\",\n )\n .map((suggestion) => ({\n ...suggestion,\n isLoading: false,\n }));\n\n if (finalizedSuggestions.length > 0) {\n agentSuggestions[suggestionId] = finalizedSuggestions;\n } else {\n delete agentSuggestions[suggestionId];\n }\n\n // Get all aggregated suggestions for this agent\n const allSuggestions = Object.values(\n this._suggestions[consumerAgentId] ?? {},\n ).flat();\n\n void this.notifySuggestionsChanged(\n consumerAgentId,\n allSuggestions,\n \"finalized\",\n );\n }\n }\n\n /**\n * Extract suggestions from messages (called during streaming)\n */\n extractSuggestions(\n messages: readonly Message[],\n suggestionId: string,\n consumerAgentId: string,\n isRunning: boolean,\n ): void {\n const idx = messages.findIndex((message) => message.id === suggestionId);\n if (idx == -1) {\n return;\n }\n\n const suggestions: Suggestion[] = [];\n const newMessages = messages.slice(idx + 1);\n\n for (const message of newMessages) {\n if (message.role === \"assistant\" && message.toolCalls) {\n for (const toolCall of message.toolCalls) {\n if (toolCall.function.name === \"copilotkitSuggest\") {\n // Join all argument chunks into a single string for parsing\n // arguments can be either a string or an array of strings\n const fullArgs = Array.isArray(toolCall.function.arguments)\n ? toolCall.function.arguments.join(\"\")\n : toolCall.function.arguments;\n const parsed = partialJSONParse(fullArgs);\n if (\n parsed &&\n typeof parsed === \"object\" &&\n \"suggestions\" in parsed\n ) {\n const parsedSuggestions = (parsed as any).suggestions;\n if (Array.isArray(parsedSuggestions)) {\n for (const item of parsedSuggestions) {\n if (item && typeof item === \"object\" && \"title\" in item) {\n suggestions.push({\n title: item.title ?? \"\",\n message: item.message ?? \"\",\n // Defaults to false; only the trailing item is flipped to\n // true below, and only while a streaming run is in flight.\n isLoading: false,\n });\n }\n }\n }\n }\n }\n }\n }\n }\n\n // Set isLoading for the last suggestion if still running\n if (isRunning && suggestions.length > 0) {\n suggestions[suggestions.length - 1]!.isLoading = true;\n }\n\n const agentSuggestions = this._suggestions[consumerAgentId];\n if (agentSuggestions) {\n agentSuggestions[suggestionId] = suggestions;\n\n // Get all aggregated suggestions for this agent\n const allSuggestions = Object.values(\n this._suggestions[consumerAgentId] ?? {},\n ).flat();\n\n void this.notifySuggestionsChanged(\n consumerAgentId,\n allSuggestions,\n \"suggestions changed\",\n );\n }\n }\n\n /**\n * Notify subscribers of suggestions config changes\n */\n private async notifySuggestionsConfigChanged(): Promise<void> {\n await (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).notifySubscribers(\n (subscriber) =>\n subscriber.onSuggestionsConfigChanged?.({\n copilotkit: this.core,\n suggestionsConfig: this._suggestionsConfig,\n }),\n \"Subscriber onSuggestionsConfigChanged error:\",\n );\n }\n\n /**\n * Notify subscribers of suggestions changes\n */\n private async notifySuggestionsChanged(\n agentId: string,\n suggestions: Suggestion[],\n context: string = \"\",\n ): Promise<void> {\n await (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).notifySubscribers(\n (subscriber) =>\n subscriber.onSuggestionsChanged?.({\n copilotkit: this.core,\n agentId,\n suggestions,\n }),\n `Subscriber onSuggestionsChanged error: ${context}`,\n );\n }\n\n /**\n * Notify subscribers that suggestions started loading\n */\n private async notifySuggestionsStartedLoading(\n agentId: string,\n ): Promise<void> {\n await (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).notifySubscribers(\n (subscriber) =>\n subscriber.onSuggestionsStartedLoading?.({\n copilotkit: this.core,\n agentId,\n }),\n \"Subscriber onSuggestionsStartedLoading error:\",\n );\n }\n\n /**\n * Notify subscribers that suggestions finished loading\n */\n private async notifySuggestionsFinishedLoading(\n agentId: string,\n ): Promise<void> {\n await (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).notifySubscribers(\n (subscriber) =>\n subscriber.onSuggestionsFinishedLoading?.({\n copilotkit: this.core,\n agentId,\n }),\n \"Subscriber onSuggestionsFinishedLoading error:\",\n );\n }\n\n /**\n * Check if suggestions should be shown based on availability and message count\n */\n private shouldShowSuggestions(\n config: SuggestionsConfig,\n messageCount: number,\n ): boolean {\n const availability = config.available;\n\n // Default behavior if no availability specified\n if (!availability) {\n if (isDynamicSuggestionsConfig(config)) {\n return messageCount > 0; // Default: after-first-message\n } else {\n return messageCount === 0; // Default: before-first-message\n }\n }\n\n switch (availability) {\n case \"disabled\":\n return false;\n case \"before-first-message\":\n return messageCount === 0;\n case \"after-first-message\":\n return messageCount > 0;\n case \"always\":\n return true;\n default:\n return false;\n }\n }\n\n /**\n * Add static suggestions directly without AI generation\n */\n private addStaticSuggestions(\n suggestionId: string,\n config: StaticSuggestionsConfig,\n consumerAgentId: string,\n ): void {\n // Mark all as not loading since they're static\n const suggestions = config.suggestions.map((s) => ({\n ...s,\n isLoading: false,\n }));\n\n // Store suggestions\n this._suggestions[consumerAgentId] = {\n ...this._suggestions[consumerAgentId],\n [suggestionId]: suggestions,\n };\n\n // Notify subscribers\n const allSuggestions = Object.values(\n this._suggestions[consumerAgentId] ?? {},\n ).flat();\n\n void this.notifySuggestionsChanged(\n consumerAgentId,\n allSuggestions,\n \"static suggestions added\",\n );\n }\n}\n\n/**\n * Detects an `AbortController`-driven cancellation so the stateless path can\n * treat it as an expected (non-error) outcome on clear/reload.\n */\nexport function isAbortError(error: unknown): boolean {\n // Detect purely by name: a `DOMException` is NOT `instanceof Error` in Safari\n // and older engines, so gating on `instanceof Error` would misclassify a real\n // user abort as a failure in the browser (this package runs client-side).\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"name\" in error &&\n (error as { name?: unknown }).name === \"AbortError\"\n );\n}\n\n/**\n * Type guard for dynamic suggestions config\n */\nfunction isDynamicSuggestionsConfig(\n config: SuggestionsConfig,\n): config is DynamicSuggestionsConfig {\n return \"instructions\" in config;\n}\n\n/**\n * Type guard for static suggestions config\n */\nfunction isStaticSuggestionsConfig(\n config: SuggestionsConfig,\n): config is StaticSuggestionsConfig {\n return \"suggestions\" in config;\n}\n\n/**\n * The tool definition for AI-generated suggestions\n */\nconst SUGGEST_TOOL: Tool = {\n name: \"copilotkitSuggest\",\n description: \"Suggest what the user could say next\",\n parameters: {\n type: \"object\",\n properties: {\n suggestions: {\n type: \"array\",\n description: \"List of suggestions shown to the user as buttons.\",\n items: {\n type: \"object\",\n properties: {\n title: {\n type: \"string\",\n description:\n \"The title of the suggestion. This is shown as a button and should be short.\",\n },\n message: {\n type: \"string\",\n description:\n \"The message to send when the suggestion is clicked. This should be a clear, complete sentence \" +\n \"and will be sent as an instruction to the AI.\",\n },\n },\n required: [\"title\", \"message\"],\n },\n },\n },\n required: [\"suggestions\"],\n },\n};\n","/**\n * Single authority for the forwarded-to-client sentinel used by StateManager\n * and RunHandler.\n */\nexport const FORWARDED_TO_CLIENT = \"Forwarded to client\";\n\nexport function normalizeToolResultContent(content: unknown): string | null {\n if (typeof content === \"string\") return content.trim();\n\n if (Array.isArray(content)) {\n const text = content\n .flatMap((part) => {\n if (typeof part === \"string\") return [part];\n if (\n part &&\n typeof part === \"object\" &&\n \"text\" in part &&\n typeof (part as { text?: unknown }).text === \"string\"\n ) {\n return [(part as { text: string }).text];\n }\n return [];\n })\n .join(\"\")\n .trim();\n return text.length > 0 ? text : null;\n }\n\n if (\n content &&\n typeof content === \"object\" &&\n \"text\" in content &&\n typeof (content as { text?: unknown }).text === \"string\"\n ) {\n return (content as { text: string }).text.trim();\n }\n\n return null;\n}\n\nexport function isForwardedToClientPlaceholder(content: unknown): boolean {\n return normalizeToolResultContent(content) === FORWARDED_TO_CLIENT;\n}\n","import { schemaToJsonSchema } from \"@copilotkit/shared\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\nimport type { FrontendTool } from \"../types\";\n\n/**\n * Empty tool schema constant\n */\nconst EMPTY_TOOL_SCHEMA = {\n type: \"object\",\n properties: {},\n} as const satisfies Record<string, unknown>;\n\n/**\n * Create a JSON schema from a tool's parameters\n */\nexport function createToolSchema(\n tool: FrontendTool<any>,\n): Record<string, unknown> {\n if (!tool.parameters) {\n return { ...EMPTY_TOOL_SCHEMA };\n }\n\n const rawSchema = schemaToJsonSchema(tool.parameters, {\n zodToJsonSchema: (schema, options) =>\n zodToJsonSchema(\n schema as Parameters<typeof zodToJsonSchema>[0],\n options as Parameters<typeof zodToJsonSchema>[1],\n ),\n });\n\n if (!rawSchema || typeof rawSchema !== \"object\") {\n return { ...EMPTY_TOOL_SCHEMA };\n }\n\n const { $schema: _$schema, ...schema } = rawSchema as Record<string, unknown>;\n\n if (typeof schema.type !== \"string\") {\n schema.type = \"object\";\n }\n if (typeof schema.properties !== \"object\" || schema.properties === null) {\n schema.properties = {};\n }\n\n stripAdditionalProperties(schema);\n return schema;\n}\n\n/**\n * Remove every `additionalProperties` key from a JSON schema tree, in place.\n * Some LLM providers reject schemas that carry it.\n */\nfunction stripAdditionalProperties(schema: unknown): void {\n if (!schema || typeof schema !== \"object\") {\n return;\n }\n\n if (Array.isArray(schema)) {\n schema.forEach(stripAdditionalProperties);\n return;\n }\n\n const record = schema as Record<string, unknown>;\n\n if (record.additionalProperties !== undefined) {\n delete record.additionalProperties;\n }\n\n for (const value of Object.values(record)) {\n stripAdditionalProperties(value);\n }\n}\n","import type { ToolCall } from \"@ag-ui/client\";\nimport { logger, randomUUID } from \"@copilotkit/shared\";\nimport type { FrontendTool, WebMCPToolAnnotations } from \"../types\";\nimport { createToolSchema } from \"./tool-schema\";\n\n/**\n * The subset of the WebMCP `ModelContext` API\n * (https://webmachinelearning.github.io/webmcp/) that the registry depends on.\n * Kept structural so the code works against the real browser API and test\n * doubles alike. Aborting the registration signal unregisters the tool.\n */\nexport interface WebMCPModelContext {\n registerTool(\n tool: {\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n execute: (\n args: Record<string, unknown>,\n options: { signal?: AbortSignal },\n ) => Promise<unknown>;\n annotations?: WebMCPToolAnnotations;\n },\n options: { signal: AbortSignal },\n ): Promise<undefined>;\n}\n\n/**\n * Return the page's `document.modelContext`, or null when WebMCP is not\n * available (SSR, React Native, browsers without the API enabled).\n */\nexport function getWebMCPModelContext(): WebMCPModelContext | null {\n if (typeof document === \"undefined\") {\n return null;\n }\n const modelContext = (\n document as Document & { modelContext?: WebMCPModelContext }\n ).modelContext;\n return modelContext ?? null;\n}\n\ninterface WebMCPRegistryEntry {\n tool: FrontendTool<any>;\n controller: AbortController;\n}\n\n/**\n * Keeps a set of frontend tools registered on the page's WebMCP model context.\n *\n * `sync(desired)` reconciles the registrations with the desired set: tools that\n * are gone (or were re-registered with a new tool object) are unregistered by\n * aborting their registration signal, and new tools are registered with an\n * `execute` that delegates to the frontend tool's own handler.\n *\n * All WebMCP-API constraints live here so callers only supply the desired set:\n * a tool without a description is skipped with a warning (the spec rejects\n * empty descriptions), and failures from `registerTool` (duplicate name,\n * unsupported context, ...) are warned rather than thrown.\n */\nexport class WebMCPRegistry {\n private entries = new Map<string, WebMCPRegistryEntry>();\n private warnedNames = new Set<string>();\n\n /** Names currently kept registered on the model context. */\n get registeredNames(): string[] {\n return [...this.entries.keys()];\n }\n\n /** Reconcile the registered tools with the desired set. */\n sync(desired: Map<string, FrontendTool<any>>): void {\n const modelContext = getWebMCPModelContext();\n if (!modelContext) {\n return;\n }\n\n for (const [name, entry] of [...this.entries]) {\n if (desired.get(name) !== entry.tool) {\n entry.controller.abort();\n this.entries.delete(name);\n }\n }\n\n for (const [name, tool] of desired) {\n if (this.entries.has(name)) {\n continue;\n }\n if (!tool.description) {\n this.warnOnce(\n name,\n `Skipping WebMCP registration for tool '${name}': WebMCP requires a description.`,\n );\n continue;\n }\n\n const controller = new AbortController();\n this.entries.set(name, { tool, controller });\n modelContext\n .registerTool(\n this.buildModelContextTool(\n tool as FrontendTool<any> & { description: string },\n ),\n { signal: controller.signal },\n )\n .catch((error) => {\n // Registration failed (duplicate name, insecure context, permission\n // policy, ...). Drop the bookkeeping; the browser never registered.\n // Only delete while this is still the active registration: an\n // aborted registration can reject after a newer one already replaced\n // it, and that replacement's bookkeeping must survive.\n if (this.entries.get(name)?.controller !== controller) {\n return;\n }\n this.entries.delete(name);\n const message =\n error instanceof Error ? error.message : String(error);\n this.warnOnce(\n name,\n `WebMCP registration failed for tool '${name}': ${message}`,\n );\n });\n }\n }\n\n /**\n * Build the WebMCP model-context tool for a frontend tool. The `execute`\n * callback delegates to the frontend tool's own handler, so a browser agent\n * call runs the same application code as an agent call.\n */\n private buildModelContextTool(\n tool: FrontendTool<any> & { description: string },\n ): {\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n execute: (\n args: Record<string, unknown>,\n options: { signal?: AbortSignal },\n ) => Promise<unknown>;\n annotations?: WebMCPToolAnnotations;\n } {\n const annotations =\n typeof tool.webmcp === \"object\" ? tool.webmcp.annotations : undefined;\n return {\n name: tool.name,\n description: tool.description,\n inputSchema: createToolSchema(tool),\n execute: async (args, options) => {\n if (!tool.handler) {\n // Mirrors core's empty tool result for a display-only tool.\n return \"\";\n }\n const toolCall: ToolCall = {\n id: randomUUID(),\n type: \"function\",\n function: {\n name: tool.name,\n arguments: JSON.stringify(args ?? {}),\n },\n };\n return await tool.handler(args as any, {\n toolCall,\n signal: options?.signal,\n });\n },\n ...(annotations ? { annotations } : {}),\n };\n }\n\n /** Log `message` once per tool name. Repeated syncs must not spam the log. */\n private warnOnce(name: string, message: string): void {\n if (this.warnedNames.has(name)) {\n return;\n }\n this.warnedNames.add(name);\n logger.warn(`[CopilotKit] ${message}`);\n }\n}\n","import type {\n AbstractAgent,\n AgentSubscriber,\n Message,\n RunAgentResult,\n ResumeEntry,\n Tool,\n ToolCall,\n} from \"@ag-ui/client\";\nimport { randomUUID, logger } from \"@copilotkit/shared\";\nimport type { CopilotKitCore, CopilotKitCoreFriendsAccess } from \"./core\";\nimport { CopilotKitCoreErrorCode } from \"./core\";\nimport { AgentThreadLockedError } from \"../intelligence-agent\";\nimport type { FrontendTool } from \"../types\";\nimport { isAbortError } from \"../utils/abort-error\";\nimport type { CopilotKitCoreContinuationHandoff } from \"./state-manager\";\nimport { isForwardedToClientPlaceholder } from \"./tool-result-content\";\nimport { createToolSchema } from \"./tool-schema\";\nimport { WebMCPRegistry } from \"./webmcp\";\n\n/**\n * Live approvals cancelled by stopping their own run, keyed by the handler's\n * signal. The value reports whether that stop is still current: no reconnect\n * has started and the thread is unchanged, so nothing will restore the call.\n *\n * Kept here rather than in `AbortSignal.reason`: React Native's global\n * `AbortController` is the `abort-controller@3` polyfill, whose `abort()`\n * takes no reason and whose signals never expose one.\n */\nconst liveHITLStops = new WeakMap<AbortSignal, () => boolean>();\n\n// Explicitly stopping a live approval must retain its error result. History\n// restoration and thread-switch cancellation instead discard the old result.\nfunction discardAbortedResult(\n signal: AbortSignal | undefined,\n discardOnAbort: boolean,\n errorMessage?: string,\n): boolean {\n return !!(\n discardOnAbort &&\n signal?.aborted &&\n !(liveHITLStops.get(signal)?.() && errorMessage)\n );\n}\n\nexport interface CopilotKitCoreRunAgentParams {\n agent: AbstractAgent;\n forwardedProps?: Record<string, unknown>;\n /**\n * Optional caller-supplied run identifier forwarded to the underlying AG-UI\n * agent. When omitted, the agent creates one.\n */\n runId?: string;\n /**\n * Per-interrupt responses addressing every open AG-UI interrupt from the\n * previous run. Forwarded to the agent as the standard `resume` array.\n */\n resume?: ResumeEntry[];\n}\n\nexport interface CopilotKitCoreConnectAgentParams {\n agent: AbstractAgent;\n}\n\nexport interface CopilotKitCoreGetToolParams {\n toolName: string;\n agentId?: string;\n}\n\n/**\n * Parameters for programmatic tool execution via `copilotkit.runTool()`.\n */\nexport interface CopilotKitCoreRunToolParams {\n /** Name of the registered frontend tool to execute. */\n name: string;\n /** Optional agent ID. If omitted, uses the default agent lookup. */\n agentId?: string;\n /** Parameters to pass to the tool handler. */\n parameters?: Record<string, unknown>;\n /**\n * Whether to trigger an LLM follow-up after tool execution.\n * - `false` (default): execute tool, add messages to history, done.\n * - `\"generate\"`: after execution, trigger another agent run so the LLM responds to the tool result.\n * - Any other string: add a user message with this text, then trigger another agent run.\n */\n followUp?: string | false;\n}\n\n/**\n * Result of programmatic tool execution via `copilotkit.runTool()`.\n */\nexport interface CopilotKitCoreRunToolResult {\n /** The unique ID of the tool call. */\n toolCallId: string;\n /** The stringified result from the tool handler. */\n result: string;\n /** Error message if the handler failed. */\n error?: string;\n}\n\n/**\n * Internal result from the shared tool handler execution logic.\n */\ninterface ExecuteToolHandlerResult {\n result: string;\n error?: string;\n isArgumentError: boolean;\n}\n\n/**\n * A registered A2UI catalog component, as exposed to the inspector via\n * `CopilotKitCore.catalogComponents`. `schema` is an opaque JSON-schema-ish\n * value (the built catalog's Zod schema or a serialized form); the inspector\n * treats it as unknown. `description` is optional because the built\n * `ComponentApi` does not carry descriptions.\n */\nexport interface CopilotKitCoreCatalogComponent {\n name: string;\n description?: string;\n schema: unknown;\n}\n\n/**\n * Absolute safety cap on the depth of recursive follow-up runs triggered by\n * `processAgentResult`. Without this, any scenario that keeps\n * `needsFollowUp = true` (e.g. the LLM repeatedly calling the same tool, a\n * backend that errors after receiving tool results, or input processors that\n * reprocess tool messages) would loop indefinitely, silently consuming API\n * quota and potentially DOS'ing the backend.\n *\n * The cap is deliberately high so that legitimate multi-step agent workflows\n * (search → fill form → confirm → update → send email, etc.) are never\n * affected; it only trips on runaway recursion.\n */\nconst MAX_FOLLOW_UP_DEPTH = 100;\n\n/**\n * Name of the catch-all frontend tool. A tool registered under this name\n * handles any tool call that has no exact match (see `executeWildcardTool`),\n * and is never advertised to the agent.\n */\nconst WILDCARD_TOOL_NAME = \"*\";\n\n/**\n * Handles agent execution, tool calling, and agent connectivity for CopilotKitCore.\n * Manages the complete lifecycle of agent runs including tool execution and follow-ups.\n */\nexport class RunHandler {\n /**\n * Tools owned by the framework provider, replaced wholesale by\n * {@link initialize} and {@link setTools} whenever the provider re-syncs its\n * props or runtime feature flags.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _propTools: FrontendTool<any>[] = [];\n\n /**\n * Tools registered imperatively via {@link addTool} — `useFrontendTool`,\n * `useHumanInTheLoop`, and direct `core.addTool()` callers. Held separately\n * from {@link _propTools} so a provider re-sync cannot wipe them: they shared\n * one array before, so the `/info` response flipping `openGenerativeUI` (or\n * any other provider-prop change) silently dropped every hook-registered\n * tool (#4952). Key = `capabilityKey(name, agentId)`.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _hookTools: Map<string, FrontendTool<any>> = new Map();\n\n /**\n * Memoized merge of both buckets, invalidated on every registry write.\n *\n * This is about identity, not speed: `tools` is public and used to return the\n * same array instance until something mutated the registry, so consumers can\n * hold it or use it as an effect dependency. Rebuilding the merge on every\n * read would hand out a new array each time.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _cachedMergedTools: FrontendTool<any>[] | null = null;\n\n /**\n * The full list of A2UI catalog components registered by the provider.\n * Order is preserved for display in the inspector.\n */\n private _catalogComponents: CopilotKitCoreCatalogComponent[] = [];\n\n /**\n * Names of catalog components the caller has explicitly disabled. A name\n * absent from this set is enabled (default). Survives re-registration so a\n * catalog identity change does not silently re-enable a disabled component.\n */\n private _disabledCatalogComponents: Set<string> = new Set();\n\n /**\n * Keys of frontend tools explicitly disabled at runtime via the Inspector's\n * Capabilities tool (`setToolEnabled`). Kept independently of each tool's own\n * `available` flag so a hook re-registering the tool (which resets\n * `available`) does not clobber the override. Key = `capabilityKey(name, agentId)`.\n */\n private _disabledToolKeys = new Set<string>();\n\n /**\n * Registry keys already reported by {@link warnOnMissingToolParameters}.\n * Development only, and per instance rather than per module so tests and\n * multiple cores stay independent. Deliberately NOT cleared by\n * {@link removeTool}: `useFrontendTool` tears down and re-registers on every\n * dependency change, so clearing it would turn one warning into one per\n * render. Key = `capabilityKey(name, agentId)`.\n */\n private _warnedMissingToolParameters = new Set<string>();\n\n /**\n * Tracks whether the current run (including in-flight tool execution)\n * has been aborted via `stopAgent()` or `agent.abortRun()`. Created\n * fresh in `runAgent()`, aborted by `abortCurrentRun()`.\n */\n private _runAbortController: AbortController | null = null;\n\n /**\n * Tracks recursive `runAgent` depth so that the abort controller and\n * `agent.abortRun()` intercept are only set up / torn down at the\n * top-level call, not on follow-up recursive calls from\n * `processAgentResult`.\n */\n private _runDepth = 0;\n\n /**\n * Keeps tools that opt in via `webmcp` registered on the page's WebMCP model\n * context (`document.modelContext`), in addition to the normal agent\n * registration. Reconciled on every tool registry mutation.\n */\n private _webmcpRegistry = new WebMCPRegistry();\n\n /**\n * Tracks the threadId of the most recent `connectAgent` call so we\n * can distinguish a fresh thread restore (different threadId than\n * last time — chat is rebuilding state from scratch, must clear\n * messages/state and ask the gateway for a full replay) from a\n * same-thread churn re-connect (effect-dep churn or transient\n * disconnect — local messages/state are still meaningful, must\n * preserve them and let the gateway resume from\n * `lastSeenEventId`).\n *\n * Tyler's bug fired because every `connectAgent` was treated as a\n * fresh restore, which forced the gateway to replay the full\n * thread history on every churn re-connect and amplified the\n * downstream churn into duplicate `cpki_event_id` rows in the\n * inspector and intermittent \"Message not found\" toasts.\n */\n private _lastConnectedThreadIdsByAgent = new Map<string, string | null>();\n private _anonymousAgentIds = new WeakMap<AbstractAgent, string>();\n private _nextAnonymousAgentId = 0;\n\n /** Prevent reconnects from starting an interaction already executing locally. */\n private _executingToolCalls = new WeakMap<AbstractAgent, Set<string>>();\n\n private _connectionGenerations = new WeakMap<AbstractAgent, object>();\n\n private _interactionAbortControllers = new WeakMap<\n AbstractAgent,\n {\n threadId: string | null;\n controllers: Set<AbortController>;\n }\n >();\n\n constructor(private core: CopilotKitCore) {}\n\n /**\n * Abort the current run. Called by `CopilotKitCore.stopAgent()` to signal\n * that in-flight tool handlers should stop and `processAgentResult` should\n * not start a follow-up run.\n */\n abortCurrentRun(agent: AbstractAgent): void {\n this._runAbortController?.abort();\n const replay = this._interactionAbortControllers.get(agent);\n if (replay) {\n for (const controller of replay.controllers) controller.abort();\n this._interactionAbortControllers.delete(agent);\n // Cancellation is cooperative: an old handler may never settle. Let a\n // reconnect restore it without waiting for its execution marker to clear.\n this._executingToolCalls.delete(agent);\n }\n }\n\n /**\n * Typed access to CopilotKitCore's internal (\"friend\") methods.\n * Centralises the single unavoidable cast so call-sites stay clean.\n */\n private get _internal(): CopilotKitCoreFriendsAccess {\n return this.core as unknown as CopilotKitCoreFriendsAccess;\n }\n\n /**\n * Return a stable restore-tracking key for the logical agent being\n * connected. Named agents share their last-thread marker across proxy\n * instances; anonymous agents fall back to object identity.\n */\n private getConnectRestoreKey(agent: AbstractAgent): string {\n if (agent.agentId) {\n return `agent:${agent.agentId}`;\n }\n\n const existing = this._anonymousAgentIds.get(agent);\n if (existing) {\n return existing;\n }\n\n const anonymousId = `anonymous:${this._nextAnonymousAgentId}`;\n this._nextAnonymousAgentId += 1;\n this._anonymousAgentIds.set(agent, anonymousId);\n return anonymousId;\n }\n\n /**\n * Get all tools as a readonly array: provider-owned tools in registration\n * order, with imperatively-added tools appended and taking precedence over a\n * provider tool of the same name + agentId.\n */\n get tools(): Readonly<FrontendTool<any>[]> {\n if (this._hookTools.size === 0) {\n return this._propTools;\n }\n if (this._cachedMergedTools) {\n return this._cachedMergedTools;\n }\n // Merge: hook entries override prop entries with the same key. Overriding\n // an existing key keeps the prop entry's position, so provider order is\n // preserved and only genuinely new hook tools land at the end.\n const merged = new Map<string, FrontendTool<any>>();\n for (const tool of this._propTools) {\n merged.set(this.capabilityKey(tool.name, tool.agentId), tool);\n }\n for (const [key, tool] of this._hookTools) {\n merged.set(key, tool);\n }\n this._cachedMergedTools = Array.from(merged.values());\n return this._cachedMergedTools;\n }\n\n /**\n * Initialize with tools\n */\n initialize(tools: FrontendTool<any>[]): void {\n // Copied, like `setTools` does: the merged view is memoized, so holding the\n // caller's array would let an in-place mutation of it go unnoticed. (It\n // also used to be mutated from this side — `addTool` pushed straight onto\n // the array the provider passed in.)\n this._propTools = [...tools];\n this._cachedMergedTools = null;\n this.warnOnMissingToolParameters(this._propTools);\n this.syncWebMCP();\n }\n\n /**\n * Add a tool to the registry. Survives provider re-syncs ({@link setTools}),\n * and shadows a provider tool of the same name + agentId.\n */\n addTool<T extends Record<string, unknown> = Record<string, unknown>>(\n tool: FrontendTool<T>,\n ): void {\n const key = this.capabilityKey(tool.name, tool.agentId);\n\n // Only a competing imperative registration is a conflict. A provider tool\n // of the same name is shadowed rather than treated as a duplicate — hooks\n // mount after the provider and are the more specific registration.\n if (this._hookTools.has(key)) {\n logger.warn(\n `Tool already exists: '${tool.name}' for agent '${tool.agentId || \"global\"}', skipping.`,\n );\n return;\n }\n\n this._hookTools.set(key, tool);\n this._cachedMergedTools = null;\n this.warnOnMissingToolParameters([tool]);\n this.syncWebMCP();\n }\n\n /**\n * Report, once per tool and at development time only, a tool registered with\n * no `parameters` schema.\n *\n * `createToolSchema` substitutes `{ type: \"object\", properties: {} }` for a\n * missing `parameters` and returns silently, and `parameters` is optional on\n * `FrontendTool`, so nothing — not the compiler, not the runtime — tells the\n * developer that the model was handed a tool with nothing to fill in. It then\n * calls the tool with no arguments. `useComponent`, `useFrontendTool` and\n * `useHumanInTheLoop` all funnel into {@link addTool}; the provider's `tools`\n * prop funnels into {@link initialize} and {@link setTools}.\n *\n * A parameterless tool is legitimate (a HITL confirm dialog, say), so this\n * stays a warning rather than an error. An explicit empty schema\n * (`parameters: z.object({})`) is the way to say \"takes none on purpose\": it\n * satisfies the check below and `createToolSchema` reduces it to the same\n * advertised `{ type: \"object\", properties: {} }` that omitting `parameters`\n * produces, so silencing the warning costs nothing on the wire.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private warnOnMissingToolParameters(tools: FrontendTool<any>[]): void {\n if (process.env.NODE_ENV === \"production\") {\n return;\n }\n\n for (const tool of tools) {\n if (tool.parameters) {\n continue;\n }\n const key = this.capabilityKey(tool.name, tool.agentId);\n if (this._warnedMissingToolParameters.has(key)) {\n continue;\n }\n this._warnedMissingToolParameters.add(key);\n logger.warn(\n `Tool has no parameters schema: '${tool.name}' for agent '${tool.agentId || \"global\"}'. ` +\n `The model is told it takes no arguments and will call it with none. ` +\n `Add \\`parameters\\` (a Zod or Standard Schema object) if it should ` +\n `receive arguments, or \\`parameters: z.object({})\\` to declare that it ` +\n `takes none and silence this warning.`,\n );\n }\n }\n\n /**\n * Remove a tool by name and optionally by agentId\n */\n removeTool(id: string, agentId?: string): void {\n this._hookTools.delete(this.capabilityKey(id, agentId));\n this._propTools = this._propTools.filter((tool) => {\n // Remove tool if both name and agentId match\n if (agentId !== undefined) {\n return !(tool.name === id && tool.agentId === agentId);\n }\n // If no agentId specified, only remove global tools with matching name\n return !(tool.name === id && !tool.agentId);\n });\n this._cachedMergedTools = null;\n this.syncWebMCP();\n }\n\n /**\n * Get a tool by name and optionally by agentId.\n * If agentId is provided, it will first look for an agent-specific tool,\n * then fall back to a global tool with the same name.\n */\n getTool(params: CopilotKitCoreGetToolParams): FrontendTool<any> | undefined {\n const { toolName, agentId } = params;\n const tools = this.tools;\n\n // If agentId is provided, first look for agent-specific tool\n if (agentId) {\n const agentTool = tools.find(\n (tool) => tool.name === toolName && tool.agentId === agentId,\n );\n if (agentTool) {\n return agentTool;\n }\n }\n\n // Fall back to global tool (no agentId)\n return tools.find((tool) => tool.name === toolName && !tool.agentId);\n }\n\n /**\n * Set all provider-owned tools at once. Replaces the previous provider set;\n * tools registered via {@link addTool} are unaffected.\n */\n setTools(tools: FrontendTool<any>[]): void {\n this._propTools = [...tools];\n this._cachedMergedTools = null;\n this.warnOnMissingToolParameters(this._propTools);\n this.syncWebMCP();\n }\n\n /**\n * Return the registered A2UI catalog components (readonly).\n */\n get catalogComponents(): ReadonlyArray<CopilotKitCoreCatalogComponent> {\n return this._catalogComponents;\n }\n\n /**\n * Replace the registered catalog component list. Preserves the disabled set\n * (by name) so re-registration does not re-enable disabled components.\n */\n setCatalogComponents(components: CopilotKitCoreCatalogComponent[]): void {\n this._catalogComponents = [...components];\n }\n\n /**\n * Enable or disable a catalog component by name.\n */\n setCatalogComponentEnabled(name: string, enabled: boolean): void {\n if (enabled) {\n this._disabledCatalogComponents.delete(name);\n } else {\n this._disabledCatalogComponents.add(name);\n }\n }\n\n /**\n * Whether a catalog component is enabled. Unknown names default to enabled.\n */\n isCatalogComponentEnabled(name: string): boolean {\n return !this._disabledCatalogComponents.has(name);\n }\n\n /**\n * Connect an agent (establish initial connection)\n */\n async connectAgent({\n agent,\n }: CopilotKitCoreConnectAgentParams): Promise<RunAgentResult> {\n this._connectionGenerations.set(agent, {});\n const incomingThreadId = agent.threadId ?? null;\n const previousReplay = this._interactionAbortControllers.get(agent);\n if (previousReplay && previousReplay.threadId !== incomingThreadId) {\n for (const controller of previousReplay.controllers) controller.abort();\n this._interactionAbortControllers.delete(agent);\n // Old handlers retain their own set until they settle. They must not\n // prevent a fresh restoration when navigating back to this thread.\n this._executingToolCalls.delete(agent);\n }\n try {\n const restoreKey = this.getConnectRestoreKey(agent);\n const isFreshRestore =\n incomingThreadId !==\n (this._lastConnectedThreadIdsByAgent.get(restoreKey) ?? null);\n this._lastConnectedThreadIdsByAgent.set(restoreKey, incomingThreadId);\n\n // Detach any active run before connecting to avoid previous runs\n // interfering. This stays unconditional — both fresh restores and\n // churn re-connects need the previous socket torn down before a new\n // one can open.\n await agent.detachActiveRun();\n\n // State reset + replay-cursor clear are gated on actually moving\n // to a different thread. On same-thread churn, the local\n // messages/state are still the right view of the thread, and the\n // gateway can resume from `lastSeenEventId` instead of replaying\n // the full history.\n if (isFreshRestore) {\n agent.setMessages([]);\n agent.setState({});\n const cursorAware = agent as {\n clearReconnectCursor?: (id: string) => void;\n clearReplayCursor?: (id: string) => void;\n };\n if (incomingThreadId) {\n if (typeof cursorAware.clearReplayCursor === \"function\") {\n cursorAware.clearReplayCursor(incomingThreadId);\n }\n if (typeof cursorAware.clearReconnectCursor === \"function\") {\n cursorAware.clearReconnectCursor(incomingThreadId);\n }\n }\n }\n\n // Re-apply core headers (merged on top of the agent's own headers) so a\n // late header update is picked up without clobbering per-agent headers.\n this._internal.applyHeadersToAgent(agent);\n\n // Notify subscribers (e.g. the inspector) about the agent that is about\n // to run. Per-thread clones are not in the agent registry, so\n // onAgentsChanged never fires for them and they would otherwise be\n // invisible to subscribers.\n await this._internal.notifySubscribers(\n (subscriber) =>\n subscriber.onAgentRunStarted?.({\n copilotkit: this.core,\n agent,\n }),\n \"Subscriber onAgentRunStarted error:\",\n );\n\n const runAgentResult = await agent.connectAgent(\n {\n forwardedProps: this._internal.properties,\n tools: this.buildFrontendTools(agent.agentId),\n context: this._internal.getContextForAgent(agent.agentId),\n },\n this.createAgentErrorSubscriber(agent),\n );\n\n // Connecting ends when history is restored, not when a human answers.\n // Keeping this promise open would block run-activity reconnects while\n // another client answers the same interaction.\n if ((agent.threadId ?? null) !== incomingThreadId) return runAgentResult;\n const controller = new AbortController();\n const replay = this._interactionAbortControllers.get(agent) ?? {\n threadId: incomingThreadId,\n controllers: new Set<AbortController>(),\n };\n replay.controllers.add(controller);\n this._interactionAbortControllers.set(agent, replay);\n void this.processAgentResult({\n runAgentResult,\n agent,\n toolExecutionMode: \"human-in-the-loop\",\n signal: controller.signal,\n })\n .catch(async (error: unknown) => {\n await this._internal.emitError({\n error: error instanceof Error ? error : new Error(String(error)),\n code: CopilotKitCoreErrorCode.AGENT_CONNECT_FAILED,\n context: { agentId: agent.agentId, threadId: incomingThreadId },\n });\n })\n .finally(() => {\n replay.controllers.delete(controller);\n if (\n replay.controllers.size === 0 &&\n this._interactionAbortControllers.get(agent) === replay\n ) {\n this._interactionAbortControllers.delete(agent);\n }\n });\n return runAgentResult;\n } catch (error) {\n const connectError =\n error instanceof Error ? error : new Error(String(error));\n // Silently ignore abort errors (e.g. from navigation during active\n // requests).\n if (!isAbortError(connectError)) {\n const context: Record<string, any> = {};\n if (agent.agentId) {\n context.agentId = agent.agentId;\n }\n if (incomingThreadId) {\n context.threadId = incomingThreadId;\n }\n await this._internal.emitError({\n error: connectError,\n code: CopilotKitCoreErrorCode.AGENT_CONNECT_FAILED,\n context,\n });\n }\n return { result: undefined, newMessages: [] };\n }\n }\n\n /**\n * Run an agent\n */\n async runAgent(\n { agent, forwardedProps, resume, runId }: CopilotKitCoreRunAgentParams,\n continuationHandoff?: CopilotKitCoreContinuationHandoff,\n ): Promise<RunAgentResult> {\n // Agent ID is guaranteed to be set by validateAndAssignAgentId\n if (agent.agentId) {\n void this._internal.suggestionEngine.clearSuggestions(agent.agentId);\n }\n\n // Re-apply core headers (merged on top of the agent's own headers) so a\n // late header update is picked up without clobbering per-agent headers.\n this._internal.applyHeadersToAgent(agent);\n\n // Detach any active run (e.g. a long-lived connectAgent pipeline) before\n // starting a new run. We await the detach to ensure the previous pipeline\n // has fully finalized — its activeRunCompletionPromise resolves once the\n // observable finalize block runs, which happens synchronously after the\n // takeUntil signal completes the chain. This prevents a race where the new\n // runAgent() overwrites activeRunDetach$ / activeRunCompletionPromise before\n // the old pipeline can clean up, causing dropped runs.\n //\n // Historical note: an earlier version used fire-and-forget (`void`) here\n // because awaiting caused a deadlock when connectAgent's\n // ConnectNotImplementedError cleanup was still in-flight. That deadlock\n // was resolved in @ag-ui/client ≥0.0.42 where the catchError path\n // (ConnectNotImplementedError → EMPTY) always runs the finalize block,\n // so the completion promise now resolves reliably.\n if (agent.detachActiveRun) {\n try {\n await agent.detachActiveRun();\n } catch (error) {\n continuationHandoff?.cancel();\n throw error;\n }\n }\n\n // Set up abort controller and agent.abortRun() intercept only for the\n // top-level call. Recursive follow-up calls from processAgentResult\n // reuse the same controller.\n const isTopLevel = this._runDepth === 0;\n let originalAbortRun: (() => void) | undefined;\n\n if (isTopLevel) {\n this._runAbortController = new AbortController();\n\n // Intercept agent.abortRun() so that calling it directly (not via\n // stopAgent) also aborts in-flight tool execution and prevents\n // follow-up runs.\n const controller = this._runAbortController;\n originalAbortRun = agent.abortRun.bind(agent);\n agent.abortRun = () => {\n controller.abort();\n originalAbortRun!();\n };\n\n // Notify subscribers (e.g. the inspector) about the agent that is about\n // to run. Per-thread clones are not in the agent registry, so\n // onAgentsChanged never fires for them and they would otherwise be\n // invisible to subscribers. Fired once per top-level run; recursive\n // follow-up runs reuse the same instance and need no re-notification.\n await this._internal.notifySubscribers(\n (subscriber) =>\n subscriber.onAgentRunStarted?.({\n copilotkit: this.core,\n agent,\n }),\n \"Subscriber onAgentRunStarted error:\",\n );\n }\n\n this._runDepth++;\n\n try {\n let logicalRunId = runId;\n const agentSubscriber = this.createAgentErrorSubscriber(agent);\n let started = false;\n const onRunStartedEvent = agentSubscriber.onRunStartedEvent;\n const onRunInitialized = agentSubscriber.onRunInitialized;\n agentSubscriber.onRunInitialized = async (params) => {\n continuationHandoff?.bind(params.input);\n return onRunInitialized?.(params);\n };\n agentSubscriber.onRunStartedEvent = async (params) => {\n started = true;\n // A continuation keeps reporting under the run it continues; only an\n // ordinary run adopts the id the transport assigned it.\n if (!continuationHandoff) {\n logicalRunId = params.input.runId;\n }\n return onRunStartedEvent?.(params);\n };\n // An internal continuation (a human-in-the-loop tool resolved and this is\n // the recursive follow-up) deliberately does NOT pin the originating run\n // id on the wire. Pinning it made the transport treat the follow-up as a\n // resumption of a run it had already completed: it re-delivered that\n // run's applied half — duplicating every tool call already on the\n // message, each duplicate carrying empty arguments — and the follow-up's\n // own tool call never reached client state, so its card never rendered.\n //\n // One logical run is still what everything downstream sees: the state\n // manager re-stamps the continuation's events onto `runId` (passed to\n // markNextRunAsContinuation), and `logicalRunId` below keeps the result\n // reported under it. So external tracing still gets a single run without\n // the wire having to lie about which invocation this is.\n const pinRunIdOnWire = runId !== undefined && !continuationHandoff;\n const agentRunInput = {\n forwardedProps: {\n ...this._internal.properties,\n ...forwardedProps,\n },\n ...(resume !== undefined ? { resume } : {}),\n ...(pinRunIdOnWire ? { runId } : {}),\n tools: this.buildFrontendTools(agent.agentId),\n context: this._internal.getContextForAgent(agent.agentId),\n };\n const runAgentResult = await agent.runAgent(\n agentRunInput,\n agentSubscriber,\n );\n if (!started) {\n continuationHandoff?.cancel();\n }\n return await this.processAgentResult({\n runAgentResult,\n agent,\n runId: logicalRunId,\n });\n } catch (error) {\n continuationHandoff?.cancel();\n const runError =\n error instanceof Error ? error : new Error(String(error));\n const context: Record<string, any> = {};\n if (agent.agentId) {\n context.agentId = agent.agentId;\n }\n await this._internal.emitError({\n error: runError,\n code: CopilotKitCoreErrorCode.AGENT_RUN_FAILED,\n context,\n });\n return { result: undefined, newMessages: [] };\n } finally {\n this._runDepth--;\n // Restore original abortRun when the entire chain (including\n // recursive follow-ups) is complete.\n if (isTopLevel && originalAbortRun) {\n agent.abortRun = originalAbortRun;\n }\n }\n }\n\n /**\n * Process agent result and execute tools\n */\n private async processAgentResult({\n runAgentResult,\n agent,\n runId,\n toolExecutionMode = \"all\",\n signal = this._runAbortController?.signal,\n }: {\n runAgentResult: RunAgentResult;\n agent: AbstractAgent;\n runId?: string;\n toolExecutionMode?: \"all\" | \"human-in-the-loop\";\n signal?: AbortSignal;\n }): Promise<RunAgentResult> {\n const { newMessages } = runAgentResult;\n // Agent ID is guaranteed to be set by validateAndAssignAgentId\n const agentId = agent.agentId!;\n\n let needsFollowUp = false;\n\n const threadId = agent.threadId;\n const executing = this._executingToolCalls.get(agent) ?? new Set<string>();\n this._executingToolCalls.set(agent, executing);\n\n // One restoration pass owns the pending sequence. Skipping only the first\n // executing call would start later calls concurrently and replace a HITL\n // hook's response resolver. A saved remote answer releases this barrier.\n if (\n toolExecutionMode === \"human-in-the-loop\" &&\n agent.messages.some(\n (message) =>\n message.role === \"assistant\" &&\n message.toolCalls?.some(\n (call) =>\n executing.has(JSON.stringify([threadId, call.id])) &&\n !agent.messages.some(\n (result) =>\n result.role === \"tool\" &&\n result.toolCallId === call.id &&\n !this.isFrontendPlaceholderResult(result),\n ),\n ),\n )\n ) {\n return runAgentResult;\n }\n\n // Reconnect deltas omit messages already hydrated by earlier replays.\n // Reconcile the current history so a remote answer can unblock a pending\n // call that was already present. Snapshot it because handlers insert results.\n const messagesToProcess =\n toolExecutionMode === \"human-in-the-loop\"\n ? [...agent.messages]\n : newMessages;\n for (const message of messagesToProcess) {\n if (message.role === \"assistant\") {\n for (const toolCall of message.toolCalls || []) {\n const tool = this.getTool({\n toolName: toolCall.function.name,\n agentId: agent.agentId,\n });\n\n let wildcardTool: FrontendTool<any> | undefined;\n const getWildcardTool = () => {\n if (tool || wildcardTool) {\n return wildcardTool;\n }\n wildcardTool = this.getTool({\n toolName: WILDCARD_TOOL_NAME,\n agentId: agent.agentId,\n });\n return wildcardTool;\n };\n\n const executableTool = tool ?? getWildcardTool();\n if (\n toolExecutionMode === \"human-in-the-loop\" &&\n (executableTool?.type !== \"human-in-the-loop\" ||\n !executableTool.handler)\n ) {\n continue;\n }\n const executionKey = JSON.stringify([threadId, toolCall.id]);\n if (\n signal?.aborted ||\n agent.threadId !== threadId ||\n executing.has(executionKey)\n ) {\n continue;\n }\n\n const existingResultIndex = newMessages.findIndex(\n (m) => m.role === \"tool\" && m.toolCallId === toolCall.id,\n );\n // Live messages may contain a remote answer received while an\n // earlier handler awaited input; never replace it with stale replay.\n let existingResult =\n agent.messages.find(\n (m) => m.role === \"tool\" && m.toolCallId === toolCall.id,\n ) ?? newMessages[existingResultIndex];\n\n if (\n existingResult &&\n executableTool?.handler &&\n this.isFrontendPlaceholderResult(existingResult)\n ) {\n if (existingResultIndex !== -1)\n newMessages.splice(existingResultIndex, 1);\n existingResult = undefined;\n\n const agentMsgIdx = agent.messages.findIndex(\n (m) => m.role === \"tool\" && m.toolCallId === toolCall.id,\n );\n if (agentMsgIdx !== -1) {\n agent.messages.splice(agentMsgIdx, 1);\n }\n }\n\n if (!existingResult) {\n executing.add(executionKey);\n // Live HITL handlers need the same thread-switch cancellation as\n // restored ones, so returning to this thread can open a fresh UI.\n const interactionController =\n toolExecutionMode === \"all\" &&\n executableTool?.type === \"human-in-the-loop\"\n ? new AbortController()\n : undefined;\n const interactions = this._interactionAbortControllers.get(\n agent,\n ) ?? {\n threadId: threadId ?? null,\n controllers: new Set<AbortController>(),\n };\n const abortInteraction = () => {\n if (!interactionController) return;\n const connectionGeneration =\n this._connectionGenerations.get(agent);\n liveHITLStops.set(\n interactionController.signal,\n () =>\n this._connectionGenerations.get(agent) ===\n connectionGeneration && agent.threadId === threadId,\n );\n interactionController.abort();\n };\n if (interactionController) {\n interactions.controllers.add(interactionController);\n this._interactionAbortControllers.set(agent, interactions);\n signal?.addEventListener(\"abort\", abortInteraction, {\n once: true,\n });\n if (signal?.aborted) abortInteraction();\n }\n const executionSignal = interactionController?.signal ?? signal;\n const discardOnAbort =\n toolExecutionMode === \"human-in-the-loop\" ||\n !!interactionController;\n try {\n if (tool) {\n const followUp = await this.executeSpecificTool(\n tool,\n toolCall,\n message,\n agent,\n agentId,\n executionSignal,\n discardOnAbort,\n );\n if (followUp) {\n needsFollowUp = true;\n }\n } else {\n const fallbackTool = getWildcardTool();\n if (fallbackTool) {\n const followUp = await this.executeWildcardTool(\n fallbackTool,\n toolCall,\n message,\n agent,\n agentId,\n executionSignal,\n discardOnAbort,\n );\n if (followUp) {\n needsFollowUp = true;\n }\n }\n }\n } finally {\n executing.delete(executionKey);\n if (interactionController) {\n signal?.removeEventListener(\"abort\", abortInteraction);\n interactions.controllers.delete(interactionController);\n if (\n interactions.controllers.size === 0 &&\n this._interactionAbortControllers.get(agent) === interactions\n ) {\n this._interactionAbortControllers.delete(agent);\n }\n }\n }\n if (interactionController?.signal.aborted) return runAgentResult;\n }\n }\n }\n }\n\n if (needsFollowUp && agent.threadId === threadId && !signal?.aborted) {\n // Circuit breaker: bail out instead of recursing once the follow-up\n // chain exceeds an absolute safety cap. `_runDepth` reflects the current\n // depth of nested runAgent calls (it is incremented in runAgent and\n // decremented in its finally block), so a runaway loop — repeated\n // identical tool calls, a backend that keeps erroring after tool\n // results, reprocessed tool messages, etc. — eventually trips this\n // guard rather than looping forever and exhausting API quota.\n if (this._runDepth >= MAX_FOLLOW_UP_DEPTH) {\n logger.warn(\n `[CopilotKit] Follow-up depth limit (${MAX_FOLLOW_UP_DEPTH}) reached for agent \"${agentId}\". ` +\n `Stopping recursive follow-up runs to prevent an infinite loop. ` +\n `This usually indicates a tool that keeps requesting a follow-up (e.g. the LLM repeatedly ` +\n `calling the same tool). Consider setting \"followUp: false\" on the offending tool.`,\n );\n } else {\n // Yield to the framework scheduler before the follow-up run so that any\n // deferred state updates (e.g. React useEffect in useAgentContext) can\n // complete and write fresh values into the context store before runAgent\n // reads it. The base implementation is a no-op; React overrides this.\n await this._internal.waitForPendingFrameworkUpdates();\n const continuationHandoff =\n this._internal.stateManager.markNextRunAsContinuation(agent, runId);\n return await this.runAgent(\n {\n agent,\n ...(runId !== undefined ? { runId } : {}),\n },\n continuationHandoff,\n );\n }\n }\n\n void this._internal.suggestionEngine.reloadSuggestions(agentId);\n\n return runAgentResult;\n }\n\n private isFrontendPlaceholderResult(message: Message): boolean {\n return (\n message.role === \"tool\" && isForwardedToClientPlaceholder(message.content)\n );\n }\n\n /**\n * Shared handler execution logic used by executeSpecificTool, executeWildcardTool, and runTool.\n * Handles arg parsing, subscriber notifications, handler invocation, result stringification,\n * and error handling.\n */\n private async executeToolHandler({\n tool,\n toolCall,\n agent,\n agentId,\n handlerArgs,\n toolType,\n messageId,\n signal = this._runAbortController?.signal,\n discardOnAbort = false,\n }: {\n tool: FrontendTool<any>;\n toolCall: { id: string; function: { name: string; arguments: string } };\n agent: AbstractAgent;\n agentId: string;\n handlerArgs: unknown;\n toolType: string;\n messageId?: string;\n signal?: AbortSignal;\n discardOnAbort?: boolean;\n }): Promise<ExecuteToolHandlerResult> {\n let toolCallResult = \"\";\n let errorMessage: string | undefined;\n let isArgumentError = false;\n\n let parsedArgs: unknown;\n try {\n parsedArgs = parseToolArguments(handlerArgs, toolCall.function.name);\n } catch (error) {\n const parseError =\n error instanceof Error ? error : new Error(String(error));\n errorMessage = parseError.message;\n isArgumentError = true;\n await this._internal.emitError({\n error: parseError,\n code: CopilotKitCoreErrorCode.TOOL_ARGUMENT_PARSE_FAILED,\n context: {\n agentId,\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n rawArguments: handlerArgs,\n toolType,\n ...(messageId ? { messageId } : {}),\n },\n });\n }\n\n await this._internal.notifySubscribers(\n (subscriber) =>\n subscriber.onToolExecutionStart?.({\n copilotkit: this.core,\n toolCallId: toolCall.id,\n agentId,\n toolName: toolCall.function.name,\n args: parsedArgs,\n }),\n \"Subscriber onToolExecutionStart error:\",\n );\n\n if (!errorMessage) {\n try {\n const result = await tool.handler!(parsedArgs as any, {\n toolCall: toolCall as any,\n agent,\n signal,\n });\n if (result === undefined || result === null) {\n toolCallResult = \"\";\n } else if (typeof result === \"string\") {\n toolCallResult = result;\n } else {\n toolCallResult = JSON.stringify(result);\n }\n } catch (error) {\n const handlerError =\n error instanceof Error ? error : new Error(String(error));\n errorMessage = handlerError.message;\n if (!discardAbortedResult(signal, discardOnAbort, errorMessage)) {\n await this._internal.emitError({\n error: handlerError,\n code: CopilotKitCoreErrorCode.TOOL_HANDLER_FAILED,\n context: {\n agentId,\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n parsedArgs,\n toolType,\n ...(messageId ? { messageId } : {}),\n },\n });\n }\n }\n }\n\n if (errorMessage) {\n toolCallResult = `Error: ${errorMessage}`;\n }\n\n await this._internal.notifySubscribers(\n (subscriber) =>\n subscriber.onToolExecutionEnd?.({\n copilotkit: this.core,\n toolCallId: toolCall.id,\n agentId,\n toolName: toolCall.function.name,\n result: errorMessage ? \"\" : toolCallResult,\n error: errorMessage,\n }),\n \"Subscriber onToolExecutionEnd error:\",\n );\n\n return { result: toolCallResult, error: errorMessage, isArgumentError };\n }\n\n /**\n * Execute a specific tool\n */\n private async executeSpecificTool(\n tool: FrontendTool<any>,\n toolCall: ToolCall,\n message: Message,\n agent: AbstractAgent,\n agentId: string,\n signal?: AbortSignal,\n discardOnAbort = false,\n ): Promise<boolean> {\n const threadId = agent.threadId;\n // Check if tool is constrained to a specific agent\n if (tool?.agentId && tool.agentId !== agent.agentId) {\n // Tool is not available for this agent, skip it\n return false;\n }\n\n let handlerResult: ExecuteToolHandlerResult = {\n result: \"\",\n error: undefined,\n isArgumentError: false,\n };\n\n if (tool?.handler) {\n handlerResult = await this.executeToolHandler({\n tool,\n toolCall,\n agent,\n agentId,\n handlerArgs: toolCall.function.arguments,\n toolType: \"specific\",\n messageId: message.id,\n signal,\n discardOnAbort,\n });\n }\n\n {\n const messageIndex = agent.messages.findIndex((m) => m.id === message.id);\n if (\n discardAbortedResult(signal, discardOnAbort, handlerResult.error) ||\n agent.threadId !== threadId ||\n messageIndex === -1 ||\n agent.messages.some(\n (m) =>\n m.role === \"tool\" &&\n m.toolCallId === toolCall.id &&\n !this.isFrontendPlaceholderResult(m),\n )\n ) {\n // The interaction was removed, the thread changed, or another client\n // already answered. Do not insert a stale answer or start a follow-up.\n return false;\n }\n // Find the correct insertion point: after the parent assistant message\n // and any tool-result messages already inserted for earlier tool calls\n // in the same batch. This preserves tool-result ordering relative to\n // the toolCalls array, which some providers (OpenAI) require.\n let insertAt = messageIndex + 1;\n while (\n insertAt < agent.messages.length &&\n agent.messages[insertAt]?.role === \"tool\"\n ) {\n insertAt++;\n }\n const toolMessage = {\n id: randomUUID(),\n role: \"tool\" as const,\n toolCallId: toolCall.id,\n content: handlerResult.result,\n };\n agent.messages.splice(insertAt, 0, toolMessage);\n\n if (!handlerResult.error && tool?.followUp !== false) {\n return true; // Needs follow-up\n }\n }\n\n return false;\n }\n\n /**\n * Execute a wildcard tool.\n * Wildcard tools receive args wrapped as `{toolName, args}`, which differs from\n * specific tools, so this method keeps its own arg-wrapping logic rather than\n * delegating to `executeToolHandler`.\n */\n private async executeWildcardTool(\n wildcardTool: FrontendTool<any>,\n toolCall: ToolCall,\n message: Message,\n agent: AbstractAgent,\n agentId: string,\n signal?: AbortSignal,\n discardOnAbort = false,\n ): Promise<boolean> {\n const threadId = agent.threadId;\n // Check if wildcard tool is constrained to a specific agent\n if (wildcardTool?.agentId && wildcardTool.agentId !== agent.agentId) {\n // Wildcard tool is not available for this agent, skip it\n return false;\n }\n\n let toolCallResult = \"\";\n let errorMessage: string | undefined;\n\n if (wildcardTool?.handler) {\n let parsedArgs: unknown;\n try {\n parsedArgs = parseToolArguments(\n toolCall.function.arguments,\n toolCall.function.name,\n );\n } catch (error) {\n const parseError =\n error instanceof Error ? error : new Error(String(error));\n errorMessage = parseError.message;\n await this._internal.emitError({\n error: parseError,\n code: CopilotKitCoreErrorCode.TOOL_ARGUMENT_PARSE_FAILED,\n context: {\n agentId: agentId,\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n rawArguments: toolCall.function.arguments,\n toolType: \"wildcard\",\n messageId: message.id,\n },\n });\n }\n\n const wildcardArgs = {\n toolName: toolCall.function.name,\n args: parsedArgs,\n };\n\n await this._internal.notifySubscribers(\n (subscriber) =>\n subscriber.onToolExecutionStart?.({\n copilotkit: this.core,\n toolCallId: toolCall.id,\n agentId: agentId,\n toolName: toolCall.function.name,\n args: wildcardArgs,\n }),\n \"Subscriber onToolExecutionStart error:\",\n );\n\n if (!errorMessage) {\n try {\n const result = await wildcardTool.handler(wildcardArgs as any, {\n toolCall,\n agent,\n // Use the same execution signal as named tools, including the\n // replay-specific signal when restoring a wildcard HITL handler.\n signal,\n });\n if (result === undefined || result === null) {\n toolCallResult = \"\";\n } else if (typeof result === \"string\") {\n toolCallResult = result;\n } else {\n toolCallResult = JSON.stringify(result);\n }\n } catch (error) {\n const handlerError =\n error instanceof Error ? error : new Error(String(error));\n errorMessage = handlerError.message;\n if (!discardAbortedResult(signal, discardOnAbort, errorMessage)) {\n await this._internal.emitError({\n error: handlerError,\n code: CopilotKitCoreErrorCode.TOOL_HANDLER_FAILED,\n context: {\n agentId: agentId,\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n parsedArgs: wildcardArgs,\n toolType: \"wildcard\",\n messageId: message.id,\n },\n });\n }\n }\n }\n\n if (errorMessage) {\n toolCallResult = `Error: ${errorMessage}`;\n }\n\n await this._internal.notifySubscribers(\n (subscriber) =>\n subscriber.onToolExecutionEnd?.({\n copilotkit: this.core,\n toolCallId: toolCall.id,\n agentId: agentId,\n toolName: toolCall.function.name,\n result: errorMessage ? \"\" : toolCallResult,\n error: errorMessage,\n }),\n \"Subscriber onToolExecutionEnd error:\",\n );\n }\n\n {\n const messageIndex = agent.messages.findIndex((m) => m.id === message.id);\n if (\n discardAbortedResult(signal, discardOnAbort, errorMessage) ||\n agent.threadId !== threadId ||\n messageIndex === -1 ||\n agent.messages.some(\n (m) =>\n m.role === \"tool\" &&\n m.toolCallId === toolCall.id &&\n !this.isFrontendPlaceholderResult(m),\n )\n ) {\n // The interaction was removed, the thread changed, or another client\n // already answered. Do not insert a stale answer or start a follow-up.\n return false;\n }\n // Find the correct insertion point: after the parent assistant message\n // and any tool-result messages already inserted for earlier tool calls\n // in the same batch. This preserves tool-result ordering relative to\n // the toolCalls array, which some providers (OpenAI) require.\n let insertAt = messageIndex + 1;\n while (\n insertAt < agent.messages.length &&\n agent.messages[insertAt]?.role === \"tool\"\n ) {\n insertAt++;\n }\n const toolMessage = {\n id: randomUUID(),\n role: \"tool\" as const,\n toolCallId: toolCall.id,\n content: toolCallResult,\n };\n agent.messages.splice(insertAt, 0, toolMessage);\n\n if (!errorMessage && wildcardTool?.followUp !== false) {\n return true; // Needs follow-up\n }\n }\n\n return false;\n }\n\n /**\n * Programmatically execute a registered frontend tool without going through an LLM turn.\n * The handler runs, render components show up in the UI, and both the tool call and\n * result messages are added to `agent.messages`.\n */\n async runTool(\n params: CopilotKitCoreRunToolParams,\n ): Promise<CopilotKitCoreRunToolResult> {\n const { name, agentId, parameters = {}, followUp = false } = params;\n\n // 1. Look up the tool\n const tool = this.getTool({ toolName: name, agentId });\n if (!tool) {\n const error = new Error(`Tool not found: ${name}`);\n await this._internal.emitError({\n error,\n code: CopilotKitCoreErrorCode.TOOL_NOT_FOUND,\n context: { toolName: name, agentId },\n });\n throw error;\n }\n\n // 2. Look up the agent\n const resolvedAgentId = agentId ?? \"default\";\n const agent = this._internal.getAgent(resolvedAgentId);\n if (!agent) {\n const error = new Error(`Agent not found: ${resolvedAgentId}`);\n await this._internal.emitError({\n error,\n code: CopilotKitCoreErrorCode.AGENT_NOT_FOUND,\n context: { agentId: resolvedAgentId },\n });\n throw error;\n }\n\n // 3. Create assistant message with tool call\n const toolCallId = randomUUID();\n const assistantToolCall = {\n id: toolCallId,\n type: \"function\" as const,\n function: {\n name,\n arguments: JSON.stringify(parameters),\n },\n };\n const assistantMessage: Message = {\n id: randomUUID(),\n role: \"assistant\",\n content: \"\",\n toolCalls: [assistantToolCall],\n };\n\n // 4. Push assistant message into agent's messages\n agent.messages.push(assistantMessage);\n\n // 5. Execute the tool handler (if it has one)\n let handlerResult: ExecuteToolHandlerResult = {\n result: \"\",\n error: undefined,\n isArgumentError: false,\n };\n\n if (tool.handler) {\n handlerResult = await this.executeToolHandler({\n tool,\n toolCall: assistantToolCall,\n agent,\n agentId: resolvedAgentId,\n handlerArgs: parameters,\n toolType: \"runTool\",\n });\n }\n\n // 6. Create and insert tool result message\n const toolResultMessage: Message = {\n id: randomUUID(),\n role: \"tool\",\n toolCallId,\n content: handlerResult.result,\n };\n\n const assistantIndex = agent.messages.findIndex(\n (m) => m.id === assistantMessage.id,\n );\n if (assistantIndex !== -1) {\n agent.messages.splice(assistantIndex + 1, 0, toolResultMessage);\n } else {\n // Fallback: push to end if assistant message was removed\n agent.messages.push(toolResultMessage);\n }\n\n // 7. Handle followUp (only if no error)\n if (!handlerResult.error && followUp !== false) {\n if (typeof followUp === \"string\" && followUp !== \"generate\") {\n // Custom text: add a user message first\n const userMessage: Message = {\n id: randomUUID(),\n role: \"user\",\n content: followUp,\n };\n agent.messages.push(userMessage);\n }\n // Yield to the framework scheduler so deferred state updates (e.g. React\n // useEffect in useAgentContext) can complete before the follow-up run reads\n // the context store. Mirrors the same yield in processAgentResult.\n await this._internal.waitForPendingFrameworkUpdates();\n // Trigger agent run for both \"generate\" and custom text\n await this.runAgent({ agent });\n }\n\n // 8. Return result\n return {\n toolCallId,\n result: handlerResult.result,\n error: handlerResult.error,\n };\n }\n\n /** Stable identity for a tool override: agent-scope + name (NUL-separated). */\n private capabilityKey(name: string, agentId?: string): string {\n return `${agentId ?? \"\"}\\u0000${name}`;\n }\n\n /**\n * Enable/disable a registered frontend tool at runtime without unregistering\n * it. A disabled tool is omitted from {@link buildFrontendTools}, so the agent\n * never receives it. Unlike the per-tool `available` flag, this override\n * survives the tool being re-registered.\n */\n setToolEnabled(name: string, enabled: boolean, agentId?: string): void {\n const key = this.capabilityKey(name, agentId);\n if (enabled) {\n this._disabledToolKeys.delete(key);\n } else {\n this._disabledToolKeys.add(key);\n }\n this.syncWebMCP();\n }\n\n /** Whether a tool is currently enabled (not overridden off). Defaults true. */\n isToolEnabled(name: string, agentId?: string): boolean {\n return !this._disabledToolKeys.has(this.capabilityKey(name, agentId));\n }\n\n /**\n * Build frontend tools for an agent\n */\n buildFrontendTools(agentId?: string): Tool[] {\n return this.tools\n .filter(\n (tool) =>\n // A wildcard tool is a local catch-all handler (see\n // `executeWildcardTool`), not something the model can call —\n // advertising it would offer the agent a tool named `*`.\n tool.name !== WILDCARD_TOOL_NAME &&\n tool.available !== false &&\n (tool.available as boolean | string | undefined) !== \"disabled\" &&\n (!tool.agentId || tool.agentId === agentId) &&\n this.isToolEnabled(tool.name, tool.agentId),\n )\n .map((tool) => ({\n name: tool.name,\n description: tool.description ?? \"\",\n parameters: createToolSchema(tool),\n }));\n }\n\n /**\n * Reconcile the WebMCP registrations with the current tool registry. Tools\n * opt in via `webmcp: true` or `webmcp: { annotations }`; the same\n * availability rules as `buildFrontendTools` apply. WebMCP tools are\n * page-level, so unlike the agent tool list they are not filtered by\n * agentId — a name collision across agentIds keeps the first registration.\n */\n private syncWebMCP(): void {\n const desired = new Map<string, FrontendTool<any>>();\n const warnedCollisions = new Set<string>();\n for (const tool of this.tools) {\n if (!tool.webmcp) {\n continue;\n }\n if (tool.name === WILDCARD_TOOL_NAME) {\n continue;\n }\n if (\n tool.available === false ||\n (tool.available as boolean | string | undefined) === \"disabled\"\n ) {\n continue;\n }\n if (!this.isToolEnabled(tool.name, tool.agentId)) {\n continue;\n }\n if (desired.has(tool.name)) {\n if (!warnedCollisions.has(tool.name)) {\n warnedCollisions.add(tool.name);\n logger.warn(\n `[CopilotKit] Multiple WebMCP tools share the name '${tool.name}'. ` +\n `Only the first registration is exposed to browser agents.`,\n );\n }\n continue;\n }\n desired.set(tool.name, tool);\n }\n this._webmcpRegistry.sync(desired);\n }\n\n /**\n * Create an agent error subscriber\n */\n private createAgentErrorSubscriber(agent: AbstractAgent): AgentSubscriber {\n const emitAgentError = async (\n error: Error,\n code: CopilotKitCoreErrorCode,\n extraContext: Record<string, any> = {},\n ) => {\n const context: Record<string, any> = { ...extraContext };\n if (agent.agentId) {\n context.agentId = agent.agentId;\n }\n await this._internal.emitError({\n error,\n code,\n context,\n });\n };\n\n return {\n onRunFailed: async ({ error }: { error: Error }) => {\n const code =\n error instanceof AgentThreadLockedError\n ? CopilotKitCoreErrorCode.AGENT_THREAD_LOCKED\n : CopilotKitCoreErrorCode.AGENT_RUN_FAILED_EVENT;\n await emitAgentError(error, code, {\n source: \"onRunFailed\",\n });\n },\n onRunErrorEvent: async ({ event }) => {\n // A user-initiated stop (stopAgent / agent.abortRun) makes the agent\n // emit a terminal RUN_ERROR — often code \"abort\" — as its cancellation\n // signal. That is expected, not a failure: surfacing it would pop an\n // error banner on Stop (#5966, follow-up to #5812). Mirror the\n // local-abort suppression on the runAgent/connectAgent paths and skip\n // it. Prefer the abort controller (the client's own record that it\n // initiated the stop) over the agent-supplied `code`, which is not\n // standardized across agents.\n const runWasAborted = this._runAbortController?.signal.aborted === true;\n if (runWasAborted || event?.code === \"abort\") {\n return;\n }\n\n const eventError =\n event?.rawEvent instanceof Error\n ? event.rawEvent\n : event?.rawEvent?.error instanceof Error\n ? event.rawEvent.error\n : undefined;\n\n const errorMessage =\n typeof event?.rawEvent?.error === \"string\"\n ? event.rawEvent.error\n : (event?.message ?? \"Agent run error\");\n\n const rawError = eventError ?? new Error(errorMessage);\n\n if (event?.code && !(rawError as any).code) {\n (rawError as any).code = event.code;\n }\n\n await emitAgentError(\n rawError,\n CopilotKitCoreErrorCode.AGENT_RUN_ERROR_EVENT,\n {\n source: \"onRunErrorEvent\",\n event,\n runtimeErrorCode: event?.code,\n },\n );\n },\n };\n }\n}\n\n/**\n * Ensures parsed tool arguments are a plain object.\n * Throws for non-object values so the caller's catch block can emit\n * a structured TOOL_ARGUMENT_PARSE_FAILED error.\n *\n * @internal Exported for testing only.\n */\nexport function ensureObjectArgs(\n parsed: unknown,\n toolName: string,\n): Record<string, unknown> {\n if (typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n throw new Error(\n `Tool arguments for ${toolName} parsed to non-object (${typeof parsed})`,\n );\n}\n\n/**\n * Parses raw tool call arguments into a validated object.\n *\n * Some LLM providers (e.g. @ai-sdk/openai-compatible) may send empty string \"\",\n * null, or undefined instead of \"{}\". This function normalises those cases to an\n * empty object so callers don't crash on JSON.parse(\"\").\n *\n * A debug-level warning is emitted when the fallback triggers so silent coercion\n * is observable in logs.\n *\n * @internal Exported for testing only.\n */\nexport function parseToolArguments(\n rawArgs: unknown,\n toolName: string,\n): Record<string, unknown> {\n if (rawArgs === \"\" || rawArgs === null || rawArgs === undefined) {\n logger.debug(\n `[parseToolArguments] Tool \"${toolName}\" received empty/null/undefined arguments — defaulting to {}`,\n );\n return {};\n }\n const parsed = typeof rawArgs === \"string\" ? JSON.parse(rawArgs) : rawArgs;\n return ensureObjectArgs(parsed, toolName);\n}\n","import type {\n AbstractAgent,\n Message,\n State,\n RunAgentInput,\n StateSnapshotEvent,\n StateDeltaEvent,\n MessagesSnapshotEvent,\n TextMessageStartEvent,\n ToolCallResultEvent,\n ToolMessage,\n} from \"@ag-ui/client\";\nimport { randomUUID, structuredClone_ } from \"@ag-ui/client\";\nimport type { CopilotKitCore } from \"./core\";\nimport { isForwardedToClientPlaceholder } from \"./tool-result-content\";\n\nconst isContinuation = (input: RunAgentInput): boolean =>\n input.resume !== undefined ||\n Object.prototype.hasOwnProperty.call(\n (input.forwardedProps as { command?: object } | undefined)?.command ?? {},\n \"resume\",\n );\n\nexport interface CopilotKitCoreContinuationHandoff {\n cancel(): void;\n bind(input: object): void;\n}\n\ninterface PendingContinuation extends CopilotKitCoreContinuationHandoff {\n expectedInput?: object;\n active: boolean;\n /**\n * The logical run id this continuation belongs to. Events arriving on the\n * continuation are re-stamped with it, so the run reads as ONE run to\n * everything downstream (state/message association, external tracing) even\n * though the transport minted a fresh id for the follow-up invocation.\n */\n expectedRunId?: string;\n}\n\n/**\n * Manages state and message tracking by run for CopilotKitCore.\n * Tracks agent state snapshots and message-to-run associations.\n */\nexport class StateManager {\n // State tracking: agentId -> threadId -> runId -> state\n private stateByRun: Map<string, Map<string, Map<string, State>>> = new Map();\n\n // Message tracking: agentId -> threadId -> messageId -> runId\n private messageToRun: Map<string, Map<string, Map<string, string>>> =\n new Map();\n\n // Direct text-start metadata: agentId -> threadId -> messageId -> rawEvent\n private rawEventByMessage: Map<string, Map<string, Map<string, unknown>>> =\n new Map();\n\n // Active run tracking: `agentId:threadId` -> runId (used when messages arrive without input)\n private activeRun: Map<string, string> = new Map();\n\n private agentSubscriptions: Map<\n string,\n { agent: AbstractAgent; unsubscribe: () => void }\n > = new Map();\n\n // Internal follow-ups are marked in memory so the marker never reaches a\n // runtime or becomes user-controlled forwardedProps data.\n private pendingContinuations = new WeakMap<\n AbstractAgent,\n Set<PendingContinuation>\n >();\n\n constructor(private core: CopilotKitCore) {}\n\n /**\n * Initialize state tracking for an agent\n */\n initialize(): void {\n // Will be called when CopilotKitCore is initialized\n }\n\n markNextRunAsContinuation(\n agent: AbstractAgent,\n expectedRunId?: string,\n ): CopilotKitCoreContinuationHandoff {\n let pendingForAgent = this.pendingContinuations.get(agent);\n if (!pendingForAgent) {\n pendingForAgent = new Set();\n this.pendingContinuations.set(agent, pendingForAgent);\n }\n\n const pending: PendingContinuation = {\n active: true,\n expectedRunId,\n bind: (input) => {\n if (pending.active) pending.expectedInput = input;\n },\n cancel: () => {\n if (!pending.active) return;\n pending.active = false;\n pendingForAgent!.delete(pending);\n if (pendingForAgent!.size === 0) {\n this.pendingContinuations.delete(agent);\n }\n },\n };\n pendingForAgent.add(pending);\n return pending;\n }\n\n /**\n * Subscribe to an agent's events to track state and messages.\n */\n subscribeToAgent(agent: AbstractAgent): void {\n if (!agent.agentId) {\n return; // Skip agents without IDs\n }\n\n const agentId = agent.agentId;\n\n const existing = this.agentSubscriptions.get(agentId);\n if (existing) {\n if (existing.agent === agent) {\n return;\n }\n existing.unsubscribe();\n this.agentSubscriptions.delete(agentId);\n }\n\n // Subscribe to agent events.\n //\n // Two invariants this subscription must uphold:\n //\n // 1. Revocation: the ag-ui pipeline captures `o = [...agent.subscribers]` at\n // runAgent() start. If this subscription is replaced by a newer one before\n // the pipeline finishes, the old pipeline may still call these callbacks\n // with the old input.runId. `revoked = true` turns them into no-ops once\n // the replacement subscription is in place. Only a replacement revokes —\n // see the same-instance guard above.\n //\n // 2. Run isolation within one subscription: in tests (and edge cases), a new\n // run's events can arrive through the same subscription before the new\n // pipeline is set up. An explicit standard or legacy resume input is a\n // continuation, so only an ordinary new run gets a fresh ID after\n // RUN_FINISHED.\n let revoked = false;\n let subRunId: string | undefined; // runId assigned to the current logical run\n let runFinished = false; // true after RUN_FINISHED, reset on next RUN_STARTED\n const pendingResults = new WeakMap<\n RunAgentInput,\n Map<string, ToolCallResultEvent>\n >();\n\n const reconcilePendingResults = (\n historyMessages: readonly Message[],\n input: RunAgentInput,\n ): { messages: Message[] } | undefined => {\n const events = pendingResults.get(input);\n if (!events) return undefined;\n\n const messages = [...historyMessages];\n let changed = false;\n\n for (const event of events.values()) {\n const ownerIndex = messages.findIndex(\n (message) =>\n message.role === \"assistant\" &&\n message.toolCalls?.some(\n (toolCall) => toolCall.id === event.toolCallId,\n ),\n );\n if (ownerIndex < 0) continue;\n\n const matchingIndexes = messages.reduce<number[]>(\n (indexes, message, index) => {\n if (\n message.role === \"tool\" &&\n message.toolCallId === event.toolCallId\n ) {\n indexes.push(index);\n }\n return indexes;\n },\n [],\n );\n const realIndex = matchingIndexes.find(\n (index) => !isForwardedToClientPlaceholder(messages[index]?.content),\n );\n if (realIndex !== undefined) {\n for (const duplicateIndex of matchingIndexes\n .filter((candidateIndex) => candidateIndex !== realIndex)\n .sort((a, b) => b - a)) {\n messages.splice(duplicateIndex, 1);\n changed = true;\n }\n continue;\n }\n\n const placeholderIndex = matchingIndexes.find((index) =>\n isForwardedToClientPlaceholder(messages[index]?.content),\n );\n if (placeholderIndex !== undefined) {\n if (isForwardedToClientPlaceholder(event.content)) {\n for (const duplicateIndex of matchingIndexes\n .slice(1)\n .sort((a, b) => b - a)) {\n messages.splice(duplicateIndex, 1);\n changed = true;\n }\n continue;\n }\n messages[placeholderIndex] = {\n ...messages[placeholderIndex],\n id: event.messageId,\n content: event.content,\n } as ToolMessage;\n changed = true;\n for (const duplicateIndex of matchingIndexes\n .filter(\n (candidateIndex) =>\n candidateIndex !== placeholderIndex &&\n isForwardedToClientPlaceholder(\n messages[candidateIndex]?.content,\n ),\n )\n .sort((a, b) => b - a)) {\n messages.splice(duplicateIndex, 1);\n }\n continue;\n }\n\n const result: ToolMessage = {\n id: event.messageId,\n role: \"tool\",\n toolCallId: event.toolCallId,\n content: event.content,\n };\n let insertIndex = ownerIndex + 1;\n while (messages[insertIndex]?.role === \"tool\") insertIndex++;\n messages.splice(insertIndex, 0, result);\n changed = true;\n }\n\n return changed ? { messages } : undefined;\n };\n\n const clearPendingResults = (input: RunAgentInput): void => {\n pendingResults.delete(input);\n };\n\n const effectiveInput = (input: RunAgentInput): RunAgentInput => ({\n ...input,\n runId: subRunId ?? input.runId,\n });\n\n const { unsubscribe } = agent.subscribe({\n onRunStartedEvent: ({ event, input, state }) => {\n if (revoked) return;\n const pendingForAgent = this.pendingContinuations.get(agent);\n const internalContinuation = [...(pendingForAgent ?? [])].find(\n (pending) => pending.expectedInput === input,\n );\n internalContinuation?.cancel();\n\n if (internalContinuation) {\n // An internal continuation re-stamps onto the run id it continues, so\n // the follow-up does not have to reuse that id on the wire.\n subRunId =\n internalContinuation.expectedRunId ?? event.runId ?? input.runId;\n } else if (\n runFinished &&\n input.runId === subRunId &&\n !isContinuation(input) &&\n (event.runId == null || event.runId === subRunId)\n ) {\n // A new logical run's events are arriving through this same (old)\n // subscription. This happens when the test emits events before\n // copilotkit.runAgent() has had a chance to set up the new pipeline:\n // the old pipeline reuses input1.runId for all events, so\n // input.runId equals the previous run's runId. Generate a fresh\n // runId so the new run's state doesn't collide with the old one.\n subRunId = randomUUID();\n } else {\n // A connect replay may contain multiple server runs under one input.runId.\n subRunId = event.runId || input.runId;\n }\n runFinished = false;\n this.handleRunStarted(agent, effectiveInput(input), state);\n },\n onRunFinishedEvent: ({ input, state, messages }) => {\n if (revoked) return;\n runFinished = true;\n const effective = effectiveInput(input);\n const mutation = reconcilePendingResults(messages, input);\n clearPendingResults(input);\n this.handleRunFinished(agent, effective, state);\n return mutation;\n },\n // A run error terminates the run — treat identically to finished for cleanup\n onRunErrorEvent: ({ input, state, messages }) => {\n if (revoked) return;\n runFinished = true;\n const effective = effectiveInput(input);\n const mutation = reconcilePendingResults(messages, input);\n this.handleRunFinished(agent, effective, state);\n return mutation;\n },\n onRunFailed: ({ input, messages }) => {\n if (revoked) return;\n return reconcilePendingResults(messages, input);\n },\n onRunFinalized: ({ input }) => {\n if (revoked) return;\n clearPendingResults(input);\n },\n onToolCallResultEvent: ({ event, input }) => {\n if (revoked) return;\n let events = pendingResults.get(input);\n if (!events) {\n events = new Map();\n pendingResults.set(input, events);\n }\n events.set(event.toolCallId, event);\n },\n onStateSnapshotEvent: ({ event, input, state }) => {\n if (revoked) return;\n this.handleStateSnapshot(agent, event, effectiveInput(input), state);\n },\n onStateDeltaEvent: ({ event, input, state }) => {\n if (revoked) return;\n this.handleStateDelta(agent, event, effectiveInput(input), state);\n },\n onTextMessageStartEvent: ({ event, input }) => {\n if (revoked) return;\n this.handleTextMessageStart(agent, event, effectiveInput(input));\n },\n onMessagesSnapshotEvent: ({ event, input, messages }) => {\n if (revoked) return;\n this.handleMessagesSnapshot(\n agent,\n event,\n effectiveInput(input),\n messages,\n );\n this.pruneRawEvents(\n agent.agentId!,\n input.threadId,\n event.messages,\n effectiveInput(input),\n );\n },\n onNewMessage: ({ message, input }) => {\n if (revoked) return;\n this.handleNewMessage(\n agent,\n message,\n input ? effectiveInput(input) : undefined,\n );\n },\n onMessagesChanged: ({ messages, input }) => {\n if (revoked) return;\n if (!input) {\n this.pruneRawEvents(agent.agentId!, agent.threadId, messages);\n }\n },\n });\n\n this.agentSubscriptions.set(agentId, {\n agent,\n unsubscribe: () => {\n revoked = true;\n this.pendingContinuations.delete(agent);\n unsubscribe();\n },\n });\n }\n\n /**\n * Unsubscribe an agent's subscription.\n */\n unsubscribeFromAgent(agentId: string): void {\n const existing = this.agentSubscriptions.get(agentId);\n if (existing) {\n existing.unsubscribe();\n this.agentSubscriptions.delete(agentId);\n }\n this.rawEventByMessage.delete(agentId);\n }\n\n /**\n * Get state for a specific run\n * Returns a deep copy to prevent external mutations\n */\n getStateByRun(\n agentId: string,\n threadId: string,\n runId: string,\n ): State | undefined {\n const state = this.stateByRun.get(agentId)?.get(threadId)?.get(runId);\n if (!state) return undefined;\n // Return a deep copy to prevent mutations\n return JSON.parse(JSON.stringify(state));\n }\n\n /**\n * Get runId associated with a message\n */\n getRunIdForMessage(\n agentId: string,\n threadId: string,\n messageId: string,\n ): string | undefined {\n return this.messageToRun.get(agentId)?.get(threadId)?.get(messageId);\n }\n\n /**\n * Get direct text-start metadata associated with a message.\n */\n getRawEventForMessage(\n agentId: string,\n threadId: string,\n messageId: string,\n ): unknown {\n const rawEvent = this.rawEventByMessage\n .get(agentId)\n ?.get(threadId)\n ?.get(messageId);\n return rawEvent === undefined ? undefined : structuredClone_(rawEvent);\n }\n\n /**\n * Get all states for an agent's thread\n */\n getStatesForThread(agentId: string, threadId: string): Map<string, State> {\n return this.stateByRun.get(agentId)?.get(threadId) ?? new Map();\n }\n\n /**\n * Get all run IDs for an agent's thread\n */\n getRunIdsForThread(agentId: string, threadId: string): string[] {\n const threadStates = this.stateByRun.get(agentId)?.get(threadId);\n return threadStates ? Array.from(threadStates.keys()) : [];\n }\n\n /**\n * Handle run started event\n */\n private handleRunStarted(\n agent: AbstractAgent,\n input: RunAgentInput,\n state: State,\n ): void {\n if (!agent.agentId) return;\n\n const { threadId, runId } = input;\n this.activeRun.set(`${agent.agentId}:${threadId}`, runId);\n // Only persist state when it carries real data. An empty {} from an\n // initial-state-less run would cause getStateByRun to return {} instead\n // of undefined, breaking renderers that rely on undefined to mean \"no\n // state snapshot received yet\".\n if (state && Object.keys(state).length > 0) {\n this.saveState(agent.agentId, threadId, runId, state);\n }\n }\n\n /**\n * Handle run finished event\n */\n private handleRunFinished(\n agent: AbstractAgent,\n input: RunAgentInput,\n state: State,\n ): void {\n if (!agent.agentId) return;\n\n const { threadId, runId } = input;\n this.activeRun.delete(`${agent.agentId}:${threadId}`);\n if (state && Object.keys(state).length > 0) {\n this.saveState(agent.agentId, threadId, runId, state);\n }\n }\n\n /**\n * Handle state snapshot event\n */\n private handleStateSnapshot(\n agent: AbstractAgent,\n event: StateSnapshotEvent,\n input: RunAgentInput,\n state: State,\n ): void {\n if (!agent.agentId) return;\n\n const { threadId, runId } = input;\n // Merge snapshot into current state\n const mergedState = { ...state, ...event.snapshot };\n this.saveState(agent.agentId, threadId, runId, mergedState);\n }\n\n /**\n * Handle state delta event\n */\n private handleStateDelta(\n agent: AbstractAgent,\n event: StateDeltaEvent,\n input: RunAgentInput,\n state: State,\n ): void {\n if (!agent.agentId) return;\n\n const { threadId, runId } = input;\n // State is already updated by the agent, just save it\n this.saveState(agent.agentId, threadId, runId, state);\n }\n\n /**\n * Capture only defined metadata from a normalized direct text-start event.\n */\n private handleTextMessageStart(\n agent: AbstractAgent,\n event: TextMessageStartEvent,\n input: RunAgentInput,\n ): void {\n if (!agent.agentId) return;\n\n const { threadId } = input;\n if (event.rawEvent === undefined) {\n const threadEvents = this.rawEventByMessage\n .get(agent.agentId)\n ?.get(threadId);\n threadEvents?.delete(event.messageId);\n if (threadEvents?.size === 0) {\n this.rawEventByMessage.get(agent.agentId)?.delete(threadId);\n }\n if (this.rawEventByMessage.get(agent.agentId)?.size === 0) {\n this.rawEventByMessage.delete(agent.agentId);\n }\n return;\n }\n\n if (!this.rawEventByMessage.has(agent.agentId)) {\n this.rawEventByMessage.set(agent.agentId, new Map());\n }\n const agentEvents = this.rawEventByMessage.get(agent.agentId)!;\n if (!agentEvents.has(threadId)) {\n agentEvents.set(threadId, new Map());\n }\n agentEvents.get(threadId)!.set(event.messageId, event.rawEvent);\n }\n\n /**\n * Handle messages snapshot event\n */\n private handleMessagesSnapshot(\n agent: AbstractAgent,\n event: MessagesSnapshotEvent,\n input: RunAgentInput,\n _messages: readonly Message[],\n ): void {\n if (!agent.agentId) return;\n\n const { threadId, runId } = input;\n\n // Cumulative snapshots repeat messages from earlier runs, so only assign\n // messages that do not already have a run association.\n for (const message of event.messages) {\n if (\n this.getRunIdForMessage(agent.agentId, threadId, message.id) ===\n undefined\n ) {\n this.associateMessageWithRun(\n agent.agentId,\n threadId,\n message.id,\n runId,\n );\n }\n }\n }\n\n /**\n * Handle new message event\n */\n private handleNewMessage(\n agent: AbstractAgent,\n message: Message,\n input?: RunAgentInput,\n ): void {\n if (!agent.agentId) return;\n\n if (!input) {\n // ag-ui calls addMessage() without input, so input is undefined here.\n // Fall back to the currently-active run for this agent's thread.\n const threadId = agent.threadId ?? \"\";\n const runId = this.activeRun.get(`${agent.agentId}:${threadId}`);\n if (runId) {\n this.associateMessageWithRun(\n agent.agentId,\n threadId,\n message.id,\n runId,\n );\n }\n return;\n }\n\n const { threadId, runId } = input;\n this.associateMessageWithRun(agent.agentId, threadId, message.id, runId);\n }\n\n /**\n * Save state for a specific run\n */\n private saveState(\n agentId: string,\n threadId: string,\n runId: string,\n state: State,\n ): void {\n // Ensure nested maps exist\n if (!this.stateByRun.has(agentId)) {\n this.stateByRun.set(agentId, new Map());\n }\n const agentStates = this.stateByRun.get(agentId)!;\n\n if (!agentStates.has(threadId)) {\n agentStates.set(threadId, new Map());\n }\n const threadStates = agentStates.get(threadId)!;\n\n // Deep copy the state to prevent mutations\n threadStates.set(runId, JSON.parse(JSON.stringify(state)));\n }\n\n /**\n * Associate a message with a run\n */\n private associateMessageWithRun(\n agentId: string,\n threadId: string,\n messageId: string,\n runId: string,\n ): void {\n // Ensure nested maps exist\n if (!this.messageToRun.has(agentId)) {\n this.messageToRun.set(agentId, new Map());\n }\n const agentMessages = this.messageToRun.get(agentId)!;\n\n if (!agentMessages.has(threadId)) {\n agentMessages.set(threadId, new Map());\n }\n const threadMessages = agentMessages.get(threadId)!;\n\n threadMessages.set(messageId, runId);\n }\n\n private pruneRawEvents(\n agentId: string,\n fallbackThreadId: string | undefined,\n messages: ReadonlyArray<Readonly<Message>>,\n input?: RunAgentInput,\n ): void {\n const threadId = input?.threadId ?? fallbackThreadId;\n if (!threadId) return;\n\n const threadEvents = this.rawEventByMessage.get(agentId)?.get(threadId);\n if (!threadEvents) return;\n\n const messageIds = new Set(messages.map((message) => message.id));\n for (const messageId of threadEvents.keys()) {\n if (!messageIds.has(messageId)) threadEvents.delete(messageId);\n }\n if (threadEvents.size === 0) {\n this.rawEventByMessage.get(agentId)?.delete(threadId);\n }\n if (this.rawEventByMessage.get(agentId)?.size === 0) {\n this.rawEventByMessage.delete(agentId);\n }\n }\n\n /**\n * Clear all state for an agent\n */\n clearAgentState(agentId: string): void {\n this.stateByRun.delete(agentId);\n this.messageToRun.delete(agentId);\n this.rawEventByMessage.delete(agentId);\n }\n\n /**\n * Clear all state for a thread\n */\n clearThreadState(agentId: string, threadId: string): void {\n this.stateByRun.get(agentId)?.delete(threadId);\n this.messageToRun.get(agentId)?.delete(threadId);\n this.rawEventByMessage.get(agentId)?.delete(threadId);\n }\n}\n","import { type ɵThreadStore } from \"../threads\";\nimport type { CopilotKitCore } from \"./core\";\nimport { CopilotKitCoreFriendsAccess, CopilotKitCoreSubscriber } from \"./core\";\n\nexport class ThreadStoreRegistry {\n private _stores: Record<string, ɵThreadStore> = {};\n // Cached frozen snapshot of `_stores`. Invalidated to `null` on every\n // `register`/`unregister` so the next `getAll()` rebuilds it. Stable\n // references between mutations matter for `useSyncExternalStore` consumers\n // that compare snapshot identity to decide whether to re-render.\n private _snapshot: Readonly<Record<string, ɵThreadStore>> | null = null;\n\n constructor(private core: CopilotKitCore) {}\n\n register(agentId: string, store: ɵThreadStore): void {\n if (agentId in this._stores) {\n // Capture the previous store before deleting it. `notifyUnregistered`\n // dispatches via `Promise.all` and returns control to this synchronous\n // body before async subscribers resume — by then `this._stores[agentId]`\n // already holds the new store, so the previous store must be forwarded\n // explicitly via the payload. Subscribers MUST NOT call\n // `registry.get(agentId)` from `onThreadStoreUnregistered` to recover\n // the previous store; use the `prevStore` field on the payload instead.\n const prevStore = this._stores[agentId]!;\n delete this._stores[agentId];\n this._snapshot = null;\n this.notifyUnregistered(agentId, prevStore).catch((err) => {\n console.error(\"ThreadStoreRegistry notifyUnregistered failed:\", err);\n });\n }\n this._stores[agentId] = store;\n this._snapshot = null;\n this.notifyRegistered(agentId, store).catch((err) => {\n console.error(\"ThreadStoreRegistry notifyRegistered failed:\", err);\n });\n }\n\n unregister(agentId: string): void {\n if (!(agentId in this._stores)) return;\n // Capture before delete for the same reason as `register()` above.\n const prevStore = this._stores[agentId]!;\n delete this._stores[agentId];\n this._snapshot = null;\n this.notifyUnregistered(agentId, prevStore).catch((err) => {\n console.error(\"ThreadStoreRegistry notifyUnregistered failed:\", err);\n });\n }\n\n get(agentId: string): ɵThreadStore | undefined {\n return this._stores[agentId];\n }\n\n getAll(): Readonly<Record<string, ɵThreadStore>> {\n // Cache a frozen snapshot so consecutive calls return the same reference.\n // `useSyncExternalStore` and other identity-comparing consumers depend on\n // this stability to skip re-renders when nothing has actually changed.\n // `Object.freeze` makes the `Readonly<>` claim true at runtime, not just\n // at the type level — attempts to mutate the snapshot throw in strict\n // mode and are silently ignored in sloppy mode (rather than corrupting\n // the registry). Invalidated to `null` by `register`/`unregister`.\n if (this._snapshot === null) {\n this._snapshot = Object.freeze({ ...this._stores });\n }\n return this._snapshot;\n }\n\n private async notifyRegistered(\n agentId: string,\n store: ɵThreadStore,\n ): Promise<void> {\n await (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).notifySubscribers(\n (subscriber: CopilotKitCoreSubscriber) =>\n subscriber.onThreadStoreRegistered?.({\n copilotkit: this.core,\n agentId,\n store,\n }),\n \"Subscriber onThreadStoreRegistered error:\",\n );\n }\n\n private async notifyUnregistered(\n agentId: string,\n prevStore: ɵThreadStore,\n ): Promise<void> {\n await (\n this.core as unknown as CopilotKitCoreFriendsAccess\n ).notifySubscribers(\n (subscriber: CopilotKitCoreSubscriber) =>\n subscriber.onThreadStoreUnregistered?.({\n copilotkit: this.core,\n agentId,\n prevStore,\n }),\n \"Subscriber onThreadStoreUnregistered error:\",\n );\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n BehaviorSubject,\n Observable,\n OperatorFunction,\n Subject,\n Subscription,\n asapScheduler,\n} from \"rxjs\";\nimport { distinctUntilChanged, filter, map, observeOn } from \"rxjs/operators\";\n\n/**\n * The minimal action shape used by this micro-redux implementation.\n */\nexport interface AnyAction {\n type: string;\n}\n\n/**\n * A typed action creator function with a `type` literal and runtime matcher.\n */\nexport type ActionCreator<\n Type extends string,\n Args extends unknown[] = unknown[],\n Action extends AnyAction & { type: Type } = { type: Type },\n> = ((...args: Args) => Action) & {\n type: Type;\n match(action: AnyAction): action is Action;\n};\n\n/**\n * Extracts the action type produced by an action creator.\n */\nexport type ActionFromCreator<T> = T extends (...args: any[]) => infer A\n ? A\n : never;\n\n/**\n * Extracts a union of actions produced by a tuple/array of action creators.\n */\nexport type ActionFromCreators<\n Creators extends readonly ActionCreator<string, any[], any>[],\n> = ActionFromCreator<Creators[number]>;\n\n/**\n * A reducer transforms state in response to actions.\n */\nexport type Reducer<State, Action extends AnyAction = AnyAction> = (\n state: State | undefined,\n action: Action,\n) => State;\n\n/**\n * A selector derives a value from state.\n */\nexport type Selector<State, Result> = (state: State) => Result;\n\n/**\n * Marker config for action creators that accept no payload.\n */\nexport interface EmptyActionConfig {\n readonly kind: \"empty\";\n}\n\nconst PROPS_MARKER: unique symbol = Symbol(\"props_marker\");\n\n/**\n * Marker config for action creators that require payload props.\n */\nexport interface PropsActionConfig<Props extends Record<string, unknown>> {\n readonly kind: \"props\";\n readonly [PROPS_MARKER]?: Props;\n}\n\n/**\n * Supported action creator config node in an action group.\n */\nexport type ActionConfig =\n | EmptyActionConfig\n | PropsActionConfig<Record<string, unknown>>;\n\n/**\n * Shape of an action group declaration object.\n */\nexport type ActionGroupConfig = Record<string, ActionConfig>;\n\n/**\n * Maps an action group declaration to a strongly typed action-creator object.\n */\nexport type ActionGroupResult<\n Source extends string,\n Config extends ActionGroupConfig,\n> = {\n [K in keyof Config & string]: Config[K] extends PropsActionConfig<infer P>\n ? ActionCreator<`[${Source}] ${K}`, [P], { type: `[${Source}] ${K}` } & P>\n : ActionCreator<`[${Source}] ${K}`, [], { type: `[${Source}] ${K}` }>;\n};\n\ninterface OnReducerEntry<\n State,\n Action extends AnyAction = AnyAction,\n Creators extends readonly ActionCreator<string, any[], any>[] =\n readonly ActionCreator<string, any[], any>[],\n> {\n creators: Creators;\n reducer: (state: State, action: Action) => State;\n}\n\ntype ActionFromOnReducerEntry<TEntry> =\n TEntry extends OnReducerEntry<any, infer TAction, any> ? TAction : never;\n\n/**\n * Effect contract for streams that emit actions to dispatch.\n */\nexport interface DispatchingEffect<\n State,\n InputAction extends AnyAction = AnyAction,\n OutputAction extends AnyAction = AnyAction,\n> {\n run: (\n actions$: Observable<InputAction>,\n state$: Observable<State>,\n ) => Observable<OutputAction>;\n dispatch: true;\n}\n\n/**\n * Effect contract for side-effect-only streams whose emissions are ignored.\n */\nexport interface NonDispatchingEffect<\n State,\n InputAction extends AnyAction = AnyAction,\n> {\n run: (\n actions$: Observable<InputAction>,\n state$: Observable<State>,\n ) => Observable<unknown>;\n dispatch: false;\n}\n\n/**\n * Union of supported effect shapes.\n */\nexport type Effect<\n State,\n InputAction extends AnyAction = AnyAction,\n OutputAction extends AnyAction = AnyAction,\n> =\n | DispatchingEffect<State, InputAction, OutputAction>\n | NonDispatchingEffect<State, InputAction>;\n\n/**\n * Lifecycle actions dispatched by the store.\n */\nexport type StoreLifecycleAction =\n | { type: \"@@micro-redux/init\" }\n | { type: \"@@micro-redux/stop\" };\n\n/**\n * Options for a dispatching effect.\n */\nexport interface DispatchingEffectOptions {\n dispatch?: true;\n}\n\n/**\n * Options for a non-dispatching effect.\n */\nexport interface NonDispatchingEffectOptions {\n dispatch: false;\n}\n\nconst INTERNAL_ACTION_TYPES = {\n boot: \"@@micro-redux/boot\",\n init: \"@@micro-redux/init\",\n stop: \"@@micro-redux/stop\",\n} as const;\n\nconst INTERNAL_BOOT_ACTION: AnyAction = { type: INTERNAL_ACTION_TYPES.boot };\n\n/**\n * Builds a typed action creator from a type string and payload factory.\n */\nfunction createTypedActionCreator<\n Type extends string,\n Args extends unknown[],\n Payload extends Record<string, unknown>,\n>(\n type: Type,\n factory: (...args: Args) => Payload,\n): ActionCreator<Type, Args, { type: Type } & Payload> {\n const creator = ((...args: Args) => ({\n ...factory(...args),\n type,\n })) as ActionCreator<Type, Args, { type: Type } & Payload>;\n\n creator.type = type;\n creator.match = (action: AnyAction): action is { type: Type } & Payload =>\n action.type === type;\n\n return creator;\n}\n\n/**\n * Declares a payload-based action config for `createActionGroup`.\n *\n * @example\n * ```ts\n * const actions = createActionGroup(\"User\", {\n * loaded: props<{ id: string }>(),\n * });\n * ```\n */\nexport function props<\n Props extends Record<string, unknown>,\n>(): PropsActionConfig<Props> {\n return { kind: \"props\" };\n}\n\n/**\n * Declares a no-payload action config for `createActionGroup`.\n *\n * @example\n * ```ts\n * const actions = createActionGroup(\"User\", {\n * reset: empty(),\n * });\n * ```\n */\nexport function empty(): EmptyActionConfig {\n return { kind: \"empty\" };\n}\n\n/**\n * Creates a namespaced group of typed action creators.\n *\n * Action types are formatted as: `[Source] actionName`.\n */\nexport function createActionGroup<\n const Source extends string,\n const Config extends ActionGroupConfig,\n>(source: Source, config: Config): ActionGroupResult<Source, Config> {\n const group = {} as ActionGroupResult<Source, Config>;\n\n for (const eventName of Object.keys(config) as Array<keyof Config & string>) {\n const eventConfig = config[eventName];\n if (!eventConfig) {\n continue;\n }\n\n const actionType = `[${source}] ${eventName}` as const;\n\n if (eventConfig.kind === \"props\") {\n group[eventName] = createTypedActionCreator(\n actionType,\n (payload: Record<string, unknown>) => ({ ...payload }),\n ) as ActionGroupResult<Source, Config>[typeof eventName];\n continue;\n }\n\n group[eventName] = createTypedActionCreator(\n actionType,\n () => ({}),\n ) as ActionGroupResult<Source, Config>[typeof eventName];\n }\n\n return group;\n}\n\n/**\n * Registers one reducer handler for one or more action creators.\n *\n * @throws Error when called without at least one action creator and reducer.\n */\nexport function on<\n State,\n const Creators extends readonly ActionCreator<string, any[], any>[],\n Action extends ActionFromCreators<Creators>,\n>(\n ...args: [\n ...creators: Creators,\n reducer: (state: State, action: Action) => State,\n ]\n): OnReducerEntry<State, Action, Creators> {\n if (args.length < 2) {\n throw new Error(\"on requires at least one action creator and one reducer\");\n }\n\n const reducer = args[args.length - 1] as (\n state: State,\n action: Action,\n ) => State;\n const creators = args.slice(0, -1) as unknown as Creators;\n\n return {\n creators,\n reducer,\n };\n}\n\n/**\n * Creates a reducer from an initial state and `on(...)` handler entries.\n *\n * Unknown action types return the current state unchanged.\n */\nexport function createReducer<\n State,\n const Entries extends readonly OnReducerEntry<any, any, any>[],\n>(\n initialState: State,\n ...entries: Entries\n): Reducer<State, ActionFromOnReducerEntry<Entries[number]>> {\n type ReducerAction = ActionFromOnReducerEntry<Entries[number]>;\n\n const reducerMap = new Map<\n string,\n Array<(state: State, action: ReducerAction) => State>\n >();\n\n for (const entry of entries) {\n for (const creator of entry.creators) {\n const handlers = reducerMap.get(creator.type) ?? [];\n handlers.push(\n entry.reducer as unknown as (\n state: State,\n action: ReducerAction,\n ) => State,\n );\n reducerMap.set(creator.type, handlers);\n }\n }\n\n return (state: State | undefined, action: ReducerAction): State => {\n const currentState = state ?? initialState;\n const handlers = reducerMap.get(action.type);\n\n if (!handlers || handlers.length === 0) {\n return currentState;\n }\n\n let nextState = currentState;\n for (const handler of handlers) {\n nextState = handler(nextState, action);\n }\n return nextState;\n };\n}\n\n/**\n * Creates a memoized selector from a single projector.\n */\nexport function createSelector<State, Result>(\n projector: (state: State) => Result,\n): Selector<State, Result>;\n\n/**\n * Creates a memoized selector from input selectors and a projector.\n *\n * Memoization uses one-entry caching over the latest input selector values.\n */\nexport function createSelector<\n State,\n const Selectors extends readonly Selector<State, unknown>[],\n Result,\n>(\n ...args: [\n ...selectors: Selectors,\n projector: (\n ...inputs: { [K in keyof Selectors]: ReturnType<Selectors[K]> }\n ) => Result,\n ]\n): Selector<State, Result>;\n\n/**\n * Creates a selector that caches and reuses the last computed result\n * when all input references are unchanged.\n */\nexport function createSelector<State, Result>(\n ...args:\n | [(state: State) => Result]\n | [\n ...selectors: Array<Selector<State, unknown>>,\n projector: (...inputs: unknown[]) => Result,\n ]\n): Selector<State, Result> {\n if (args.length === 1) {\n const projector = args[0] as (state: State) => Result;\n let hasCached = false;\n let lastState: State | undefined;\n let lastResult: Result;\n\n return (state: State): Result => {\n if (hasCached && state === lastState) {\n return lastResult;\n }\n\n lastState = state;\n lastResult = projector(state);\n hasCached = true;\n return lastResult;\n };\n }\n\n const projector = args[args.length - 1] as (...inputs: unknown[]) => Result;\n const selectors = args.slice(0, -1) as Array<Selector<State, unknown>>;\n\n let hasCached = false;\n let lastInputs: unknown[] = [];\n let lastResult: Result;\n\n return (state: State): Result => {\n const inputs = selectors.map((selector) => selector(state));\n\n if (\n hasCached &&\n inputs.length === lastInputs.length &&\n inputs.every((value, index) => value === lastInputs[index])\n ) {\n return lastResult;\n }\n\n lastInputs = inputs;\n lastResult = projector(...inputs);\n hasCached = true;\n return lastResult;\n };\n}\n\n/**\n * RxJS operator that maps state emissions through a selector and suppresses\n * unchanged projected values via reference equality.\n */\nexport function select<State, Result>(\n selector: Selector<State, Result>,\n): OperatorFunction<State, Result> {\n return (source$) => source$.pipe(map(selector), distinctUntilChanged());\n}\n\n/**\n * RxJS operator that filters an action stream by action creators and narrows\n * the output action type to the matched creator union.\n *\n * @throws Error when called without at least one action creator.\n */\nexport function ofType<\n const Creators extends readonly ActionCreator<string, any[], AnyAction>[],\n>(\n ...creators: Creators\n): OperatorFunction<AnyAction, ActionFromCreators<Creators>> {\n if (creators.length === 0) {\n throw new Error(\"ofType requires at least one action creator\");\n }\n\n const actionTypes = new Set(creators.map((creator) => creator.type));\n return (source$) => {\n return source$.pipe(\n filter((action: AnyAction): action is ActionFromCreators<Creators> => {\n return actionTypes.has(action.type);\n }),\n );\n };\n}\n\n/**\n * Creates a dispatching effect. Emitted actions are automatically dispatched.\n */\nexport function createEffect<\n State,\n InputAction extends AnyAction,\n OutputAction extends AnyAction,\n>(\n factory: (\n actions$: Observable<InputAction>,\n state$: Observable<State>,\n ) => Observable<OutputAction>,\n options?: DispatchingEffectOptions,\n): DispatchingEffect<State, InputAction, OutputAction>;\n\n/**\n * Creates a non-dispatching effect. Emitted values are ignored.\n */\nexport function createEffect<State, InputAction extends AnyAction>(\n factory: (\n actions$: Observable<InputAction>,\n state$: Observable<State>,\n ) => Observable<unknown>,\n options: NonDispatchingEffectOptions,\n): NonDispatchingEffect<State, InputAction>;\n\n/**\n * Creates an effect descriptor consumed by `createStore`.\n */\nexport function createEffect<\n State,\n InputAction extends AnyAction,\n OutputAction extends AnyAction,\n>(\n factory: (\n actions$: Observable<InputAction>,\n state$: Observable<State>,\n ) => Observable<OutputAction>,\n options: DispatchingEffectOptions | NonDispatchingEffectOptions = {},\n): Effect<State, InputAction, OutputAction> {\n if (options.dispatch === false) {\n return {\n run: factory,\n dispatch: false,\n };\n }\n\n return {\n run: factory,\n dispatch: true,\n };\n}\n\n/**\n * Store interface returned by `createStore`.\n */\nexport interface Store<State, Action extends AnyAction = AnyAction> {\n dispatch(action: Action): void;\n getState(): State;\n readonly state$: Observable<State>;\n readonly actions$: Observable<Action | StoreLifecycleAction>;\n select<Result>(selector: Selector<State, Result>): Observable<Result>;\n init(): void;\n stop(): void;\n}\n\n/**\n * Creates a small observable store with reducer + effects.\n *\n * Behavior:\n * - `init()` starts effects and dispatches `@@micro-redux/init`.\n * - `stop()` dispatches `@@micro-redux/stop` and unsubscribes all effects.\n * - Effect action observation is scheduled on `asapScheduler` to avoid\n * synchronous re-entrancy in the effect loop.\n * - Any effect error triggers fail-fast teardown and errors both `actions$`\n * and `state$`.\n */\nexport function createStore<\n State,\n Action extends AnyAction = AnyAction,\n>(options: {\n reducer: Reducer<State, Action | StoreLifecycleAction>;\n effects?: Array<Effect<State, Action | StoreLifecycleAction, Action>>;\n}): Store<State, Action> {\n const reducer = options.reducer;\n const effects = options.effects ?? [];\n\n let hasFatalError = false;\n let isRunning = false;\n let effectSubscriptions = new Subscription();\n\n let currentState = reducer(\n undefined,\n INTERNAL_BOOT_ACTION as Action | StoreLifecycleAction,\n );\n const stateSubject = new BehaviorSubject<State>(currentState);\n const actionsSubject = new Subject<Action | StoreLifecycleAction>();\n\n const dispatchInternal = (action: Action | StoreLifecycleAction): void => {\n if (hasFatalError) {\n throw new Error(\"Store is in a failed state due to an effect error\");\n }\n\n currentState = reducer(currentState, action);\n stateSubject.next(currentState);\n actionsSubject.next(action);\n };\n\n const failFast = (error: unknown): void => {\n if (hasFatalError) {\n return;\n }\n\n hasFatalError = true;\n isRunning = false;\n effectSubscriptions.unsubscribe();\n effectSubscriptions = new Subscription();\n\n actionsSubject.error(error);\n stateSubject.error(error);\n };\n\n const startEffects = (): void => {\n for (const effect of effects) {\n const scheduledActions$ = actionsSubject\n .asObservable()\n .pipe(observeOn(asapScheduler));\n const state$ = stateSubject.asObservable();\n\n if (effect.dispatch) {\n const subscription = effect.run(scheduledActions$, state$).subscribe({\n next: (effectAction) => {\n if (hasFatalError) {\n return;\n }\n dispatchInternal(effectAction);\n },\n error: (error) => {\n failFast(error);\n },\n });\n\n effectSubscriptions.add(subscription);\n continue;\n }\n\n const subscription = effect.run(scheduledActions$, state$).subscribe({\n error: (error) => {\n failFast(error);\n },\n });\n\n effectSubscriptions.add(subscription);\n }\n };\n\n return {\n dispatch(action: Action): void {\n dispatchInternal(action);\n },\n getState(): State {\n return currentState;\n },\n get state$(): Observable<State> {\n return stateSubject.asObservable();\n },\n get actions$(): Observable<Action | StoreLifecycleAction> {\n return actionsSubject.asObservable();\n },\n select<Result>(selector: Selector<State, Result>): Observable<Result> {\n return stateSubject.asObservable().pipe(select(selector));\n },\n init(): void {\n if (hasFatalError || isRunning) {\n return;\n }\n\n isRunning = true;\n startEffects();\n\n if (hasFatalError) {\n return;\n }\n\n dispatchInternal({ type: INTERNAL_ACTION_TYPES.init });\n },\n stop(): void {\n if (hasFatalError || !isRunning) {\n return;\n }\n\n dispatchInternal({ type: INTERNAL_ACTION_TYPES.stop });\n effectSubscriptions.unsubscribe();\n effectSubscriptions = new Subscription();\n isRunning = false;\n },\n };\n}\n","/**\n * Memory error registry — stable codes for the errors the memory store throws.\n *\n * The memory store (`memory.ts`) used to throw bare `new Error(\"Failed to fetch\n * memories: 500\")` / `\"Request timed out\"` / `\"Request failed: <status>\"`. Those\n * reach the `error` selector (and the consumer UI via `useMemories` /\n * `injectMemories`) verbatim, with no machine-readable `code`/`category`/\n * `retryable`, so they cannot be grouped in observability or branched on by\n * consumers.\n *\n * Per the repo's error-handling architecture standard (AGENTS.md: \"Each project\n * must maintain an explicit error registry\"), this file is the explicit registry\n * for the memory feature. It is deliberately scoped to memory — not a repo-wide\n * registry refactor — because `packages/core` has no pre-existing\n * code/category/retryable registry convention to plug into (the runtime's\n * `lib/error-messages.ts` is a message-templating table, not a typed\n * code/category/retryable registry). It mirrors the existing\n * `AgentThreadLockedError extends Error` precedent in\n * `intelligence-agent.ts`: a real `Error` subclass so `instanceof Error` holds\n * and the public `MemoryState.error: Error | null` contract is preserved.\n *\n * `docsPath` is recorded per entry per the standard; there is no\n * `docs/errors/<project>.md` in this repo, so this docblock plus the registry\n * are the source of truth.\n *\n * Each registry entry carries:\n * - `code`: stable identifier (e.g. `MEMORY_LIST_FAILED`).\n * - `category`: one of the standard categories\n * (`validation`|`auth`|`permission`|`not_found`|`conflict`|`rate_limit`|`internal`|`dependency`).\n * - `retryable`: whether a retry could plausibly succeed (timeouts + transient\n * dependency failures are retryable; client-caused 4xx are not).\n * - `message`: the default human-readable message (callers may override with a\n * status-bearing string to preserve the prior wording).\n * - `docsPath`: documentation pointer for the code.\n */\n\n/** Standard error categories from the repo error-handling architecture. */\nexport type MemoryErrorCategory =\n | \"validation\"\n | \"auth\"\n | \"permission\"\n | \"not_found\"\n | \"conflict\"\n | \"rate_limit\"\n | \"internal\"\n | \"dependency\";\n\n/** Stable codes for the memory store's surfaced errors. */\nexport type MemoryErrorCode =\n | \"MEMORY_LIST_FAILED\"\n | \"MEMORY_RECALL_FAILED\"\n | \"MEMORY_CREDENTIALS_FAILED\"\n | \"MEMORY_MUTATION_FAILED\"\n | \"MEMORY_REQUEST_TIMEOUT\";\n\n/** A single registry entry describing one memory error code. */\nexport interface MemoryErrorRegistryEntry {\n readonly code: MemoryErrorCode;\n readonly category: MemoryErrorCategory;\n readonly retryable: boolean;\n readonly message: string;\n readonly docsPath: string;\n}\n\n/**\n * The memory error registry: the single source of truth for memory error\n * metadata. Keyed by `code` so a code maps to exactly one category/retryable\n * default.\n *\n * Categories/retryable rationale:\n * - List/credentials/mutation failures are `dependency` (the runtime/platform\n * the store calls failed). A 5xx is transient (`retryable: true`); a 4xx is\n * caller-caused, so the helpers below downgrade those to non-retryable.\n * - Timeouts are `dependency` and `retryable: true` (the request may simply be\n * slow).\n */\nexport const MEMORY_ERROR_REGISTRY: Readonly<\n Record<MemoryErrorCode, MemoryErrorRegistryEntry>\n> = Object.freeze({\n MEMORY_LIST_FAILED: {\n code: \"MEMORY_LIST_FAILED\",\n category: \"dependency\",\n retryable: true,\n message: \"Failed to fetch memories\",\n docsPath: \"docs/errors/memory.md#memory_list_failed\",\n },\n MEMORY_RECALL_FAILED: {\n code: \"MEMORY_RECALL_FAILED\",\n category: \"dependency\",\n retryable: true,\n message: \"Failed to recall memories\",\n docsPath: \"docs/errors/memory.md#memory_recall_failed\",\n },\n MEMORY_CREDENTIALS_FAILED: {\n code: \"MEMORY_CREDENTIALS_FAILED\",\n category: \"dependency\",\n retryable: true,\n message: \"Failed to fetch memory subscribe credentials\",\n docsPath: \"docs/errors/memory.md#memory_credentials_failed\",\n },\n MEMORY_MUTATION_FAILED: {\n code: \"MEMORY_MUTATION_FAILED\",\n category: \"dependency\",\n retryable: true,\n message: \"Memory mutation request failed\",\n docsPath: \"docs/errors/memory.md#memory_mutation_failed\",\n },\n MEMORY_REQUEST_TIMEOUT: {\n code: \"MEMORY_REQUEST_TIMEOUT\",\n category: \"dependency\",\n retryable: true,\n message: \"Request timed out\",\n docsPath: \"docs/errors/memory.md#memory_request_timeout\",\n },\n});\n\n/**\n * An `Error` carrying a stable memory error `code`, `category`, and `retryable`\n * flag so consumers and observability can branch on it without string-matching\n * the message.\n *\n * It is a real `Error` subclass: `instanceof Error` is true, so the public\n * `MemoryState.error: Error | null` contract (and the `error: Error | null`\n * surfaced by `useMemories` / `injectMemories`) holds unchanged. Existing\n * consumers that only read `.message` keep working; the richer fields are\n * additive.\n */\nexport class MemoryError extends Error {\n /** Stable, machine-readable error identifier. */\n readonly code: MemoryErrorCode;\n /** Coarse error category for grouping/observability. */\n readonly category: MemoryErrorCategory;\n /** Whether retrying the operation could plausibly succeed. */\n readonly retryable: boolean;\n\n /**\n * @param code - Registry code identifying this error.\n * @param options - Optional overrides:\n * - `message`: human-readable message (defaults to the registry message;\n * callers pass a status-bearing string to preserve prior wording).\n * - `retryable`: overrides the registry default (e.g. a 4xx list failure is\n * not retryable even though the code's default is).\n * - `cause`: the underlying error, preserved for debugging.\n */\n constructor(\n code: MemoryErrorCode,\n options?: { message?: string; retryable?: boolean; cause?: unknown },\n ) {\n const entry = MEMORY_ERROR_REGISTRY[code];\n super(options?.message ?? entry.message, { cause: options?.cause });\n this.name = \"MemoryError\";\n this.code = code;\n this.category = entry.category;\n this.retryable = options?.retryable ?? entry.retryable;\n // Restore the prototype chain for environments that downlevel `extends`\n // (matches the pattern the SDK relies on for cross-target `instanceof`).\n Object.setPrototypeOf(this, MemoryError.prototype);\n }\n}\n\n/**\n * Narrows an HTTP status to whether the failure is worth retrying: a 5xx (or a\n * missing/0 status) is a transient dependency failure and retryable; a 4xx is\n * caller-caused and not. Used so a `MEMORY_LIST_FAILED`/`MEMORY_MUTATION_FAILED`\n * carries an accurate `retryable` flag derived from the response status.\n */\nexport function isRetryableStatus(status: number): boolean {\n return !(Number.isInteger(status) && status >= 400 && status <= 499);\n}\n","import { phoenixExponentialBackoff } from \"@copilotkit/shared\";\nimport {\n EMPTY,\n asapScheduler,\n defer,\n firstValueFrom,\n from,\n merge,\n Observable,\n observeOn,\n of,\n} from \"rxjs\";\nimport {\n catchError,\n concatWith,\n filter,\n finalize,\n map,\n mergeMap,\n share,\n shareReplay,\n switchMap,\n take,\n takeUntil,\n timeout,\n withLatestFrom,\n} from \"rxjs/operators\";\nimport {\n createActionGroup,\n createEffect,\n createReducer,\n createSelector,\n createStore,\n empty,\n ofType,\n on,\n props,\n} from \"./utils/micro-redux\";\nimport type { Reducer, Store } from \"./utils/micro-redux\";\nimport { MemoryError, isRetryableStatus } from \"./memory-errors\";\nimport {\n ɵphoenixChannel$,\n ɵphoenixSocket$,\n ɵjoinPhoenixChannel$,\n ɵobservePhoenixEvent$,\n ɵobservePhoenixSocketHealth$,\n ɵobservePhoenixSocketSignals$,\n} from \"./utils/phoenix-observable\";\nimport type { ɵPhoenixChannelSession } from \"./utils/phoenix-observable\";\n\n// Runtime-relative path, mirroring the thread store's `/threads` (NOT\n// `/api/threads`): `runtimeUrl` is the CopilotKit runtime mount (e.g.\n// `/api/copilotkit`), and the runtime maps `/memories` to the app-api's\n// `/api/memories` the same way it maps `/threads` -> `/api/threads`.\nconst MEMORIES_PATH = \"/memories\";\nconst MEMORIES_SUBSCRIBE_PATH = \"/memories/subscribe\";\nconst MEMORIES_RECALL_PATH = \"/memories/recall\";\nconst REQUEST_TIMEOUT_MS = 15_000;\n/** Consecutive socket errors tolerated before the realtime stream gives up. */\nconst MAX_SOCKET_RETRIES = 5;\n/**\n * HTTP status codes that indicate memory routes are not configured (non-fatal).\n * 404/501 mean the route is absent/unimplemented; 422 is the runtime's\n * MISSING_INTELLIGENCE signal (intelligence not configured on the deployment —\n * see packages/runtime/.../handlers/intelligence/memories.ts). All three map to\n * the graceful \"not available\" locked-teaser path, not a hard error.\n */\nconst ROUTE_UNAVAILABLE_STATUSES = new Set([404, 422, 501]);\n/**\n * Thrown when a memory route returns a 404/422/501 — treated as \"not\n * configured\" (422 is the runtime's MISSING_INTELLIGENCE signal).\n */\nclass MemoryRouteUnavailableError extends Error {}\n\n/** Public, customer-facing memory kind vocabulary (single taxonomy, no mapping). */\nexport type MemoryKind = \"topical\" | \"episodic\" | \"operational\";\n\n/** Visibility scope of a memory. */\nexport type MemoryScope = \"user\" | \"project\";\n\n/**\n * Health of the realtime (`user_meta:memories:<code>`) connection that streams\n * live `memory_metadata` deltas. Distinct from `available`/`error`, which\n * describe the REST list route: `realtimeStatus` reports ONLY whether the\n * realtime socket/channel is live so the UI can stop showing a \"live\" indicator\n * over a frozen snapshot once the socket permanently gives up.\n *\n * - `\"connecting\"` — fetching join credentials / opening the socket / joining\n * the channel (the default, and the state every `contextChanged`/`stopped`\n * resets to).\n * - `\"connected\"` — the channel join succeeded; live deltas are flowing.\n * - `\"unavailable\"` — the socket exhausted its retries or the join failed\n * permanently; the snapshot is frozen and no deltas will arrive. This is a\n * silent degrade for `available`/`error` (those stay untouched) — only this\n * signal flips.\n */\nexport type MemoryRealtimeStatus = \"connecting\" | \"connected\" | \"unavailable\";\n\n/**\n * A memory as projected across the public REST/realtime boundary — the minimal\n * shape the SDK surfaces. Mirrors the server's `PublicMemory` projection.\n */\nexport interface Memory {\n id: string;\n kind: MemoryKind;\n scope: MemoryScope;\n content: string;\n sourceThreadIds: readonly string[];\n invalidatedAt: string | null;\n /** Relevance score from a `recall()` (hybrid RAG) query; `undefined` for list/realtime/mutation memories. */\n score?: number;\n}\n\n/** Input for creating a memory; `scope` defaults to `\"user\"` (v1 is user-scoped). */\nexport interface NewMemory {\n content: string;\n kind: MemoryKind;\n scope?: MemoryScope;\n sourceThreadIds?: readonly string[];\n}\n\n/**\n * New values for superseding (updating) a memory — same shape as create.\n *\n * Supersede is a FULL replacement, not a partial patch: this is the complete\n * definition of the new memory that replaces the old one. `content` and `kind`\n * are required and must be re-supplied, and an omitted `sourceThreadIds` resets\n * the new memory's source threads to `[]` — it does NOT preserve the prior\n * memory's value.\n */\nexport type MemoryChanges = NewMemory;\n\n/** Outcome of a mutation, tracked so the caller's promise resolves/rejects. */\ntype MemoryMutationOutcome =\n | { requestId: string; sessionId: number; ok: true; memory: Memory | null }\n | { requestId: string; sessionId: number; ok: false; error: Error };\n\n/**\n * Runtime wiring for the memory store: where to reach the REST surface and the\n * headers (auth + `X-Cpki-User-Id`) to send. Scoped to the current user; v1\n * surfaces user-scoped memories only.\n */\ninterface MemoryRuntimeContext {\n runtimeUrl: string;\n /** WebSocket URL for the realtime gateway (e.g. `wss://gw.example.com/client`). */\n wsUrl: string;\n headers: Record<string, string>;\n includeInvalidated?: boolean;\n}\n\n/**\n * In-memory state for the memory store. Session-guarded like the thread store:\n * `sessionId` is bumped whenever the runtime context changes so that responses\n * and realtime deltas from a previous context are ignored.\n */\ninterface MemoryState {\n memories: Memory[];\n isLoading: boolean;\n inFlightMutationCount: number;\n error: Error | null;\n context: MemoryRuntimeContext | null;\n sessionId: number;\n available: boolean;\n realtimeStatus: MemoryRealtimeStatus;\n}\n\n// Deep-frozen so `getServerState()` (which returns this exact reference) cannot\n// be mutated by any caller; a single in-place write would otherwise corrupt\n// every SSR snapshot process-wide. The freeze covers the nested `memories`\n// array too — a shallow `Object.freeze` would leave `getServerState().memories`\n// mutable (`.push(...)` would silently succeed), so the empty array is frozen\n// before being sealed into the state. The reducers always build NEW state\n// objects/arrays (they spread, never mutate in place), so they are unaffected\n// and runtime behavior is unchanged.\nconst initialMemoryState: MemoryState = Object.freeze({\n memories: Object.freeze([]) as unknown as Memory[],\n isLoading: false,\n inFlightMutationCount: 0,\n error: null,\n context: null,\n sessionId: 0,\n available: true,\n realtimeStatus: \"connecting\",\n});\n\nconst memoryAdapterEvents = createActionGroup(\"Memory Adapter\", {\n started: empty(),\n stopped: empty(),\n contextChanged: props<{ context: MemoryRuntimeContext | null }>(),\n addRequested: props<{ requestId: string; input: NewMemory }>(),\n updateRequested: props<{\n requestId: string;\n id: string;\n changes: MemoryChanges;\n }>(),\n removeRequested: props<{ requestId: string; id: string }>(),\n});\n\nconst memoryRestEvents = createActionGroup(\"Memory REST\", {\n listRequested: props<{ sessionId: number }>(),\n listSucceeded: props<{ sessionId: number; memories: Memory[] }>(),\n listFailed: props<{ sessionId: number; error: Error }>(),\n listUnavailable: props<{ sessionId: number }>(),\n mutationFinished: props<{ outcome: MemoryMutationOutcome }>(),\n credentialsRequested: props<{ sessionId: number }>(),\n credentialsSucceeded: props<{\n sessionId: number;\n joinToken?: string;\n joinCode?: string;\n // Optional project-scoped realtime credentials. Present only when the\n // caller's API key resolves a project scope (B1b `/memories/subscribe`\n // returns them alongside the user credentials); omitted otherwise. When\n // present, the socket effect opens a SECOND `project_meta:memories:<code>`\n // channel so project rows stay live. Absent -> user-only (silent degrade).\n projectJoinToken?: string;\n projectJoinCode?: string;\n }>(),\n // Credentials outcomes are a SILENT degrade: they feed only the realtime\n // socket effect and deliberately do NOT touch the reducer's `available`/\n // `error`, which describe the REST list route. See the reducer note near the\n // list handlers.\n credentialsFailed: props<{ sessionId: number; error: Error }>(),\n credentialsUnavailable: props<{ sessionId: number }>(),\n});\n\nconst memoryDomainEvents = createActionGroup(\"Memory Domain\", {\n memoryUpserted: props<{ sessionId: number; memory: Memory }>(),\n memoryInvalidated: props<{ sessionId: number; memoryId: string }>(),\n // Realtime-connection health transitions, session-stamped like every other\n // realtime delta so the reducer's session guard drops transitions left over\n // from a superseded context. These flip ONLY `realtimeStatus`; they never\n // touch `available`/`error` (the realtime path is a silent degrade for those).\n realtimeConnecting: props<{ sessionId: number }>(),\n realtimeConnected: props<{ sessionId: number }>(),\n realtimeUnavailable: props<{ sessionId: number }>(),\n});\n\n/** Wire shape of a memory inside a `memory_metadata` payload (carries tenant ids). */\ninterface MemoryMetadataPayloadMemory extends Memory {\n organizationId: string;\n projectId: string;\n}\n\n/**\n * The realtime `memory_metadata` event broadcast on a memory channel:\n * `created`/`updated` carry the full memory, `invalidated` carries only its id.\n * The same wire shape is delivered on both the user channel\n * (`user_meta:memories:<code>`, current user's memories) and the optional\n * project channel (`project_meta:memories:<code>`, memories shared across the\n * project); the store reduces both into one id-keyed list.\n */\ntype MemoryMetadataEvent =\n | {\n operation: \"created\" | \"updated\";\n memoryId: string;\n organizationId: string;\n projectId: string;\n occurredAt: string;\n memory: MemoryMetadataPayloadMemory;\n }\n | {\n operation: \"invalidated\";\n memoryId: string;\n organizationId: string;\n projectId: string;\n occurredAt: string;\n invalidated: { id: string };\n };\n\n/** Projects a wire memory to the public {@link Memory} shape (drops tenant ids). */\nfunction toMemory(memory: MemoryMetadataPayloadMemory): Memory {\n return {\n id: memory.id,\n kind: memory.kind,\n scope: memory.scope,\n content: memory.content,\n sourceThreadIds: memory.sourceThreadIds,\n invalidatedAt: memory.invalidatedAt,\n };\n}\n\n/**\n * Maps a realtime `memory_metadata` event to the domain action that applies it:\n * `created`/`updated` upsert the projected memory, `invalidated` removes it by\n * id. Carries the current `sessionId` so the reducer's session guard can drop\n * deltas left over from a previous context.\n */\nfunction mapMemoryMetadataEvent(\n event: MemoryMetadataEvent,\n sessionId: number,\n):\n | ReturnType<typeof memoryDomainEvents.memoryUpserted>\n | ReturnType<typeof memoryDomainEvents.memoryInvalidated> {\n if (event.operation === \"invalidated\") {\n return memoryDomainEvents.memoryInvalidated({\n sessionId,\n memoryId: event.invalidated.id,\n });\n }\n\n return memoryDomainEvents.memoryUpserted({\n sessionId,\n memory: toMemory(event.memory),\n });\n}\n\n/**\n * Inserts or replaces a memory by id. A new memory is prepended (newest first,\n * matching the REST list's `created_at DESC` ordering without needing a date\n * field on the public projection); an existing memory is replaced in place.\n */\nfunction upsertMemory(memories: Memory[], memory: Memory): Memory[] {\n const existingIndex = memories.findIndex((item) => item.id === memory.id);\n if (existingIndex === -1) {\n return [memory, ...memories];\n }\n\n const next = [...memories];\n next[existingIndex] = memory;\n return next;\n}\n\nconst memoryReducer = createReducer(\n initialMemoryState,\n on(memoryAdapterEvents.contextChanged, (state: MemoryState, { context }) => ({\n ...state,\n context,\n sessionId: state.sessionId + 1,\n memories: [],\n isLoading: Boolean(context),\n inFlightMutationCount: 0,\n error: null,\n available: true,\n // A new context re-opens the realtime socket from scratch, so the connection\n // is \"connecting\" again until the new channel joins.\n realtimeStatus: \"connecting\" as MemoryRealtimeStatus,\n })),\n on(memoryAdapterEvents.stopped, (state: MemoryState) => ({\n ...state,\n memories: [],\n isLoading: false,\n inFlightMutationCount: 0,\n error: null,\n // Reset to the default (`true`), matching `contextChanged`. Otherwise a\n // `stop()` then `start()` WITHOUT a new `setContext` would retain a stale\n // `available: false` from a prior unconfigured session.\n available: true,\n // Reset to the default (\"connecting\"), matching `contextChanged`. A later\n // `start()` re-opens the socket; a stale \"unavailable\"/\"connected\" from the\n // prior session must not leak into the next.\n realtimeStatus: \"connecting\" as MemoryRealtimeStatus,\n })),\n on(memoryRestEvents.listRequested, (state: MemoryState, { sessionId }) => {\n if (sessionId !== state.sessionId || !state.context) {\n return state;\n }\n\n return {\n ...state,\n isLoading: true,\n error: null,\n available: true,\n };\n }),\n on(\n memoryRestEvents.listFailed,\n (state: MemoryState, { sessionId, error }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n isLoading: false,\n error,\n };\n },\n ),\n on(memoryRestEvents.listUnavailable, (state: MemoryState, { sessionId }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n memories: [],\n isLoading: false,\n error: null,\n available: false,\n };\n }),\n on(\n memoryAdapterEvents.addRequested,\n memoryAdapterEvents.updateRequested,\n memoryAdapterEvents.removeRequested,\n (state: MemoryState) => ({\n ...state,\n inFlightMutationCount: state.inFlightMutationCount + 1,\n }),\n ),\n on(memoryRestEvents.mutationFinished, (state: MemoryState, { outcome }) => {\n // Drop results from a superseded session. `contextChanged`/`stopped` already\n // reset `inFlightMutationCount`, so a mutation that resolves after the\n // context switched must not write a stale error into the new session.\n // Mirrors every other session-scoped handler (and threads.ts).\n if (outcome.sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n inFlightMutationCount: Math.max(0, state.inFlightMutationCount - 1),\n // On success clear any previously surfaced mutation error so a later\n // successful mutation does not leave a phantom sticky error banner.\n error: outcome.ok ? null : outcome.error,\n };\n }),\n on(\n memoryRestEvents.listSucceeded,\n (state: MemoryState, { sessionId, memories }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n memories,\n isLoading: false,\n error: null,\n // A successful list proves the memory route is available.\n available: true,\n };\n },\n ),\n // NOTE: `credentialsFailed` and `credentialsUnavailable` intentionally have NO\n // reducer cases. `available`/`error` describe the REST list route only and are\n // driven exclusively by the list events above. The credentials/realtime path\n // is a silent degrade by design: a missing/unconfigured `/memories/subscribe`\n // route (404/501/422) or a credentials error must not flip `available` or\n // surface an `error`, because the list route can still be perfectly healthy.\n // Otherwise `available` would be order-dependent on whichever of the two\n // concurrent `contextChanged` bootstraps responds last. Realtime failures are\n // handled where they occur (the socket effect retries and gives up via\n // console.warn); they do not belong in the REST availability state.\n on(\n memoryDomainEvents.memoryUpserted,\n (state: MemoryState, { sessionId, memory }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n memories: upsertMemory(state.memories, memory),\n };\n },\n ),\n on(\n memoryDomainEvents.memoryInvalidated,\n (state: MemoryState, { sessionId, memoryId }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n memories: state.memories.filter((memory) => memory.id !== memoryId),\n };\n },\n ),\n // Realtime-connection health. Session-guarded so a transition from a\n // superseded context is ignored. These flip ONLY `realtimeStatus`; `available`\n // and `error` describe the REST list route and are intentionally untouched.\n on(\n memoryDomainEvents.realtimeConnecting,\n (state: MemoryState, { sessionId }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n realtimeStatus: \"connecting\" as MemoryRealtimeStatus,\n };\n },\n ),\n on(\n memoryDomainEvents.realtimeConnected,\n (state: MemoryState, { sessionId }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n realtimeStatus: \"connected\" as MemoryRealtimeStatus,\n };\n },\n ),\n on(\n memoryDomainEvents.realtimeUnavailable,\n (state: MemoryState, { sessionId }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n realtimeStatus: \"unavailable\" as MemoryRealtimeStatus,\n };\n },\n ),\n) as Reducer<MemoryState>;\n\nconst selectMemories = createSelector((state: MemoryState) => state.memories);\nconst selectMemoriesIsLoading = createSelector(\n (state: MemoryState) => state.isLoading,\n);\nconst selectMemoriesError = createSelector((state: MemoryState) => state.error);\n/**\n * Reports whether at least one mutation is in flight. Derived from\n * `inFlightMutationCount` so concurrent mutations stay correct: the boolean\n * only clears once every in-flight mutation has settled.\n */\nconst selectMemoriesIsMutating = createSelector(\n (state: MemoryState) => state.inFlightMutationCount > 0,\n);\n/**\n * Reports whether the memory routes are available. Becomes `false` after a\n * 404, 422 (the runtime's MISSING_INTELLIGENCE signal), or 501 response during\n * an auto-activation read; defaults to `true`.\n */\nconst selectMemoriesAvailable = createSelector(\n (state: MemoryState) => state.available,\n);\n/**\n * Reports the realtime-connection health (see {@link MemoryRealtimeStatus}).\n * Distinct from `available`/`error`: it reflects ONLY the live socket/channel,\n * so the UI can suppress a \"live\" indicator once realtime permanently dies even\n * while the REST list route stays healthy. Defaults to `\"connecting\"`.\n */\nconst selectMemoriesRealtimeStatus = createSelector(\n (state: MemoryState) => state.realtimeStatus,\n);\n\n/**\n * Dependencies injected into the memory store. The store opens its own\n * `user_meta:memories:<joinCode>` socket/channel and does not share the\n * thread store's socket, so only a `fetch` implementation is required.\n */\ninterface MemoryEnvironment {\n fetch: typeof fetch;\n}\n\ninterface MemoryStore {\n start(): void;\n stop(): void;\n setContext(context: MemoryRuntimeContext | null): void;\n /**\n * Re-fetches the REST snapshot without clearing the current list. Resolves\n * once the re-pull settles (success or failure) for the current context, so\n * callers (e.g. a `useMemories` `refresh()`) can await it. Resolves\n * immediately when no context is set.\n */\n refresh(): Promise<void>;\n /**\n * Semantically recalls memories via `POST {runtimeUrl}/memories/recall`\n * (hybrid RAG). Returns memories ordered by relevance, each carrying a\n * `score`. Does NOT mutate the snapshot — a one-shot query. Rejects when no\n * context is set or the request fails.\n */\n recall(\n query: string,\n opts?: { limit?: number; scope?: MemoryScope },\n ): Promise<Memory[]>;\n /** Creates a memory; resolves to the stored memory (server-authoritative). */\n addMemory(input: NewMemory): Promise<Memory>;\n /** Supersedes a memory; resolves to the new memory (its id changes). */\n updateMemory(id: string, changes: MemoryChanges): Promise<Memory>;\n /** Retires a memory (non-lossy delete). */\n removeMemory(id: string): Promise<void>;\n getState(): MemoryState;\n /**\n * Stable, render-safe state for SSR/prerender. React's\n * `useSyncExternalStore` requires a `getServerSnapshot` during SSR/prerender\n * (e.g. Next.js); without one React throws \"Missing getServerSnapshot\". The\n * returned reference is stable across calls so React does not loop. There is\n * no client-side memory data during prerender, so this is the empty initial\n * state (no memories, not loading, no error).\n */\n getServerState(): MemoryState;\n select: Store<MemoryState>[\"select\"];\n}\n\nconst MEMORY_METADATA_EVENT = \"memory_metadata\";\n\n/** Runs a memory request through the injected fetch and aborts on unsubscribe. */\nfunction memoryFromFetch<T>(\n input: string,\n init: RequestInit & {\n selector: (response: Response) => Promise<T>;\n fetch: typeof fetch;\n },\n): Observable<T> {\n const {\n selector,\n fetch: fetchImplementation,\n signal: outerSignal,\n ...requestInit\n } = init;\n\n return new Observable<T>((subscriber) => {\n const controller = new AbortController();\n const abort = () => controller.abort();\n if (outerSignal?.aborted) {\n controller.abort();\n } else {\n outerSignal?.addEventListener(\"abort\", abort);\n }\n\n const subscription = from(\n fetchImplementation(input, {\n ...requestInit,\n signal: controller.signal,\n }),\n )\n .pipe(mergeMap((response) => from(selector(response))))\n .subscribe(subscriber);\n\n return () => {\n outerSignal?.removeEventListener(\"abort\", abort);\n controller.abort();\n subscription.unsubscribe();\n };\n });\n}\n\n/**\n * Fetches the memory snapshot and maps it to a success/failure action. Both\n * user- and project-scoped rows are kept: the store now opens a second\n * `project_meta:memories:<code>` realtime channel (when project credentials are\n * available) that keeps project rows in sync, so surfacing them in the snapshot\n * no longer risks a stale list. Rows are keyed by id across both channels, so\n * realtime deltas reconcile either scope idempotently.\n */\nfunction createMemoryFetchObservable(\n environment: MemoryEnvironment,\n context: MemoryRuntimeContext,\n sessionId: number,\n): Observable<\n | ReturnType<typeof memoryRestEvents.listSucceeded>\n | ReturnType<typeof memoryRestEvents.listFailed>\n | ReturnType<typeof memoryRestEvents.listUnavailable>\n> {\n return defer(() => {\n const qs = context.includeInvalidated ? \"?includeInvalidated=true\" : \"\";\n return memoryFromFetch(`${context.runtimeUrl}${MEMORIES_PATH}${qs}`, {\n selector: (response) => {\n if (!response.ok) {\n if (ROUTE_UNAVAILABLE_STATUSES.has(response.status)) {\n throw new MemoryRouteUnavailableError(String(response.status));\n }\n throw new MemoryError(\"MEMORY_LIST_FAILED\", {\n message: `Failed to fetch memories: ${response.status}`,\n retryable: isRetryableStatus(response.status),\n });\n }\n\n return response.json() as Promise<{ memories: Memory[] }>;\n },\n fetch: environment.fetch,\n method: \"GET\",\n headers: { ...context.headers },\n }).pipe(\n timeout({\n first: REQUEST_TIMEOUT_MS,\n with: () => {\n throw new MemoryError(\"MEMORY_REQUEST_TIMEOUT\");\n },\n }),\n map((data) =>\n memoryRestEvents.listSucceeded({\n sessionId,\n memories: data.memories,\n }),\n ),\n catchError((error) => {\n if (error instanceof MemoryRouteUnavailableError) {\n return of(memoryRestEvents.listUnavailable({ sessionId }));\n }\n return of(\n memoryRestEvents.listFailed({\n sessionId,\n error: error instanceof Error ? error : new Error(String(error)),\n }),\n );\n }),\n );\n });\n}\n\n/**\n * Fetches join credentials from the `/memories/subscribe` endpoint and maps\n * the response to a success/failure action. Requires both `joinToken` and\n * `joinCode` to be non-empty strings; throws otherwise so the `catchError`\n * path emits `credentialsFailed`.\n */\nfunction createMemoryCredentialsFetchObservable(\n environment: MemoryEnvironment,\n context: MemoryRuntimeContext,\n sessionId: number,\n): Observable<\n | ReturnType<typeof memoryRestEvents.credentialsSucceeded>\n | ReturnType<typeof memoryRestEvents.credentialsFailed>\n | ReturnType<typeof memoryRestEvents.credentialsUnavailable>\n> {\n return defer(() =>\n memoryFromFetch(`${context.runtimeUrl}${MEMORIES_SUBSCRIBE_PATH}`, {\n selector: async (response) => {\n if (!response.ok) {\n if (ROUTE_UNAVAILABLE_STATUSES.has(response.status)) {\n throw new MemoryRouteUnavailableError(String(response.status));\n }\n throw new MemoryError(\"MEMORY_CREDENTIALS_FAILED\", {\n message: `Failed to fetch memory subscribe credentials: ${response.status}`,\n retryable: isRetryableStatus(response.status),\n });\n }\n\n return response.json() as Promise<{\n joinToken?: string;\n joinCode?: string;\n projectJoinToken?: string;\n projectJoinCode?: string;\n }>;\n },\n fetch: environment.fetch,\n method: \"POST\",\n headers: { ...context.headers, \"Content-Type\": \"application/json\" },\n body: JSON.stringify({}),\n }).pipe(\n timeout({\n first: REQUEST_TIMEOUT_MS,\n with: () => {\n throw new MemoryError(\"MEMORY_REQUEST_TIMEOUT\");\n },\n }),\n map((data) => {\n const hasUserCreds =\n typeof data.joinToken === \"string\" &&\n data.joinToken.length > 0 &&\n typeof data.joinCode === \"string\" &&\n data.joinCode.length > 0;\n\n // Project credentials are optional and only forwarded when BOTH are\n // non-empty strings (the silent-degrade contract): a partial/malformed\n // pair is treated as \"no project scope\", so the store falls back to the\n // user channel only rather than erroring. A missing project scope must\n // never fail credentials — the user channel is the baseline.\n const hasProjectCreds =\n typeof data.projectJoinToken === \"string\" &&\n data.projectJoinToken.length > 0 &&\n typeof data.projectJoinCode === \"string\" &&\n data.projectJoinCode.length > 0;\n if (!hasUserCreds && !hasProjectCreds) {\n throw new Error(\"missing memory realtime credentials\");\n }\n\n return memoryRestEvents.credentialsSucceeded({\n sessionId,\n ...(hasUserCreds\n ? { joinToken: data.joinToken, joinCode: data.joinCode }\n : {}),\n ...(hasProjectCreds\n ? {\n projectJoinToken: data.projectJoinToken,\n projectJoinCode: data.projectJoinCode,\n }\n : {}),\n });\n }),\n catchError((error) => {\n if (error instanceof MemoryRouteUnavailableError) {\n return of(memoryRestEvents.credentialsUnavailable({ sessionId }));\n }\n return of(\n memoryRestEvents.credentialsFailed({\n sessionId,\n error: error instanceof Error ? error : new Error(String(error)),\n }),\n );\n }),\n ),\n );\n}\n\ntype MemoryMutationAction =\n | ReturnType<typeof memoryDomainEvents.memoryUpserted>\n | ReturnType<typeof memoryDomainEvents.memoryInvalidated>\n | ReturnType<typeof memoryRestEvents.mutationFinished>;\n\ntype MemoryMutationRequest =\n | {\n requestId: string;\n sessionId: number;\n kind: \"add\";\n body: Record<string, unknown>;\n }\n | {\n requestId: string;\n sessionId: number;\n kind: \"update\";\n id: string;\n body: Record<string, unknown>;\n }\n | { requestId: string; sessionId: number; kind: \"remove\"; id: string };\n\n/** Projects a REST mutation response to the public {@link Memory} shape. */\nfunction responseToMemory(data: {\n id: string;\n kind: MemoryKind;\n scope: MemoryScope;\n content: string;\n sourceThreadIds: readonly string[];\n invalidatedAt: string | null;\n}): Memory {\n return {\n id: data.id,\n kind: data.kind,\n scope: data.scope,\n content: data.content,\n sourceThreadIds: data.sourceThreadIds,\n invalidatedAt: data.invalidatedAt,\n };\n}\n\n/**\n * Projects a recall REST response memory (which carries a relevance `score`)\n * to the public {@link Memory} shape. `score` is copied through when supplied.\n */\nfunction recallResponseToMemory(data: {\n id: string;\n kind: MemoryKind;\n scope: MemoryScope;\n content: string;\n sourceThreadIds: readonly string[];\n invalidatedAt: string | null;\n score?: number;\n}): Memory {\n return {\n id: data.id,\n kind: data.kind,\n scope: data.scope,\n content: data.content,\n sourceThreadIds: data.sourceThreadIds,\n invalidatedAt: data.invalidatedAt,\n ...(typeof data.score === \"number\" ? { score: data.score } : {}),\n };\n}\n\nconst MEMORY_KINDS: ReadonlySet<string> = new Set([\n \"topical\",\n \"episodic\",\n \"operational\",\n]);\nconst MEMORY_SCOPES: ReadonlySet<string> = new Set([\"user\", \"project\"]);\n\n/**\n * Validates the required fields of a create/supersede REST response before it is\n * projected to a {@link Memory}. Returns an `Error` describing the first\n * missing/invalid field, or `null` when the body is well-formed. Without this a\n * malformed 200 body yields a Memory with undefined fields that gets upserted.\n */\nfunction validateMutationResponse(\n data: Record<string, unknown> | null,\n): Error | null {\n if (!data || typeof data !== \"object\") {\n return new Error(\"memory mutation response missing/invalid body\");\n }\n if (typeof data.id !== \"string\" || data.id.length === 0) {\n return new Error(\"memory mutation response missing/invalid id\");\n }\n if (typeof data.kind !== \"string\" || !MEMORY_KINDS.has(data.kind)) {\n return new Error(\"memory mutation response missing/invalid kind\");\n }\n if (typeof data.scope !== \"string\" || !MEMORY_SCOPES.has(data.scope)) {\n return new Error(\"memory mutation response missing/invalid scope\");\n }\n if (typeof data.content !== \"string\") {\n return new Error(\"memory mutation response missing/invalid content\");\n }\n // `sourceThreadIds` is `readonly string[]` on the public Memory; a malformed\n // 200 that omits it (or sends a non-array) would otherwise yield a Memory\n // whose `sourceThreadIds` is `undefined`, violating the type for every\n // consumer that maps over it.\n if (\n !Array.isArray(data.sourceThreadIds) ||\n !data.sourceThreadIds.every((id) => typeof id === \"string\")\n ) {\n return new Error(\n \"memory mutation response missing/invalid sourceThreadIds\",\n );\n }\n // `invalidatedAt` is `string | null`; reject any other type so it is not\n // copied through as `undefined`.\n if (data.invalidatedAt !== null && typeof data.invalidatedAt !== \"string\") {\n return new Error(\"memory mutation response missing/invalid invalidatedAt\");\n }\n return null;\n}\n\n/**\n * Request body for create/supersede. `scope` is forwarded only when the caller\n * supplies it: the platform owns the default (`scope` defaults to `\"user\"` in\n * the `/api/memories` schema), so the store does not second-guess it here —\n * one default, at the contract owner. `sourceThreadIds` defaults to `[]`.\n */\nfunction toMutationBody(input: NewMemory): Record<string, unknown> {\n return {\n content: input.content,\n kind: input.kind,\n ...(input.scope !== undefined ? { scope: input.scope } : {}),\n sourceThreadIds: input.sourceThreadIds ?? [],\n };\n}\n\n/**\n * Builds the actions a successful mutation dispatches (server-authoritative):\n * the REST response is applied to local state immediately, and the realtime\n * event reconciles idempotently (upsert-by-id). `mutationFinished` resolves the\n * caller's promise.\n */\nfunction buildMutationSuccessActions(\n request: MemoryMutationRequest,\n data: Record<string, unknown> | null,\n): MemoryMutationAction[] {\n const { requestId, sessionId } = request;\n\n if (request.kind === \"remove\") {\n // The platform's DELETE returns a bare 204 with NO body (the runtime\n // handler responds `new Response(null, { status: 204 })` and the client's\n // `removeMemory` is `Promise<void>`), so there is no confirmation field to\n // validate here — removal is status-code-confirmed. We optimistically remove\n // the row locally on any 2xx; the realtime `memory_metadata` `invalidated`\n // event (and the next REST refresh) reconcile idempotently.\n return [\n memoryDomainEvents.memoryInvalidated({ sessionId, memoryId: request.id }),\n memoryRestEvents.mutationFinished({\n outcome: { requestId, sessionId, ok: true, memory: null },\n }),\n ];\n }\n\n // Validate the required fields before projecting. A malformed 200 body would\n // otherwise yield a Memory with undefined fields that gets upserted into\n // state. Fail the mutation instead, mirroring the `retiredId` validation\n // below and the credentials path's joinToken/joinCode validation.\n const validationError = validateMutationResponse(data);\n if (validationError) {\n return [\n memoryRestEvents.mutationFinished({\n outcome: { requestId, sessionId, ok: false, error: validationError },\n }),\n ];\n }\n\n const memory = responseToMemory(\n data as Parameters<typeof responseToMemory>[0],\n );\n\n if (request.kind === \"update\") {\n // `retiredId` is optional on the server type. Without it the\n // `memoryInvalidated` would be a no-op (no id to remove), leaving the old\n // memory as a duplicate next to the new one. Validate it like the\n // credentials path validates joinToken/joinCode, and fail the mutation\n // rather than apply a half-baked supersede.\n const retiredId = (data as { retiredId?: string }).retiredId;\n if (typeof retiredId !== \"string\" || retiredId.length === 0) {\n return [\n memoryRestEvents.mutationFinished({\n outcome: {\n requestId,\n sessionId,\n ok: false,\n error: new Error(\"supersede response missing retiredId\"),\n },\n }),\n ];\n }\n\n return [\n memoryDomainEvents.memoryInvalidated({ sessionId, memoryId: retiredId }),\n memoryDomainEvents.memoryUpserted({ sessionId, memory }),\n memoryRestEvents.mutationFinished({\n outcome: { requestId, sessionId, ok: true, memory },\n }),\n ];\n }\n\n return [\n memoryDomainEvents.memoryUpserted({ sessionId, memory }),\n memoryRestEvents.mutationFinished({\n outcome: { requestId, sessionId, ok: true, memory },\n }),\n ];\n}\n\n/** Performs a create/supersede/retire HTTP call and emits its resulting actions. */\nfunction createMemoryMutationObservable(\n environment: MemoryEnvironment,\n context: MemoryRuntimeContext,\n request: MemoryMutationRequest,\n): Observable<MemoryMutationAction> {\n const method =\n request.kind === \"add\"\n ? \"POST\"\n : request.kind === \"update\"\n ? \"PATCH\"\n : \"DELETE\";\n const path =\n request.kind === \"add\"\n ? MEMORIES_PATH\n : `${MEMORIES_PATH}/${encodeURIComponent(request.id)}`;\n\n return defer(() =>\n memoryFromFetch(`${context.runtimeUrl}${path}`, {\n selector: async (response) => {\n if (!response.ok) {\n throw new MemoryError(\"MEMORY_MUTATION_FAILED\", {\n message: `Request failed: ${response.status}`,\n retryable: isRetryableStatus(response.status),\n });\n }\n\n return request.kind === \"remove\"\n ? null\n : ((await response.json()) as Record<string, unknown>);\n },\n fetch: environment.fetch,\n method,\n headers: { ...context.headers, \"Content-Type\": \"application/json\" },\n body:\n request.kind === \"remove\" ? undefined : JSON.stringify(request.body),\n }).pipe(\n timeout({\n first: REQUEST_TIMEOUT_MS,\n with: () => {\n throw new MemoryError(\"MEMORY_REQUEST_TIMEOUT\");\n },\n }),\n mergeMap((data) => of(...buildMutationSuccessActions(request, data))),\n catchError((error) =>\n of(\n memoryRestEvents.mutationFinished({\n outcome: {\n requestId: request.requestId,\n sessionId: request.sessionId,\n ok: false,\n error: error instanceof Error ? error : new Error(String(error)),\n },\n }),\n ),\n ),\n ),\n );\n}\n\n/**\n * Creates the framework-agnostic memory store: a REST snapshot on `setContext`,\n * server-authoritative add/update/remove mutations, and realtime\n * `memory_metadata` deltas off the injected `user_meta` event source — all\n * reduced into observable state.\n */\nfunction createMemoryStore(environment: MemoryEnvironment): MemoryStore {\n // Per-store request-id counter. Kept as a closure variable (not a\n // module-level global) so each store instance has its own monotonic sequence:\n // sharing one global across instances is a latent cross-instance/SSR hazard\n // and makes request ids non-reproducible in tests that reset a single store.\n let memoryRequestId = 0;\n const createMemoryRequestId = (): string => {\n memoryRequestId += 1;\n return `memory-request-${memoryRequestId}`;\n };\n\n const bootstrapEffect = createEffect(\n (actions$, state$: Observable<MemoryState>) =>\n actions$.pipe(\n ofType(memoryAdapterEvents.contextChanged),\n withLatestFrom(state$),\n filter(([, state]) => Boolean(state.context)),\n map(([, state]) =>\n memoryRestEvents.listRequested({ sessionId: state.sessionId }),\n ),\n ),\n );\n\n const credentialsBootstrapEffect = createEffect(\n (actions$, state$: Observable<MemoryState>) =>\n actions$.pipe(\n ofType(memoryAdapterEvents.contextChanged),\n withLatestFrom(state$),\n filter(([, state]) => Boolean(state.context)),\n map(([, state]) =>\n memoryRestEvents.credentialsRequested({ sessionId: state.sessionId }),\n ),\n ),\n );\n\n const credentialsFetchEffect = createEffect(\n (actions$, state$: Observable<MemoryState>) =>\n actions$.pipe(\n ofType(memoryRestEvents.credentialsRequested),\n switchMap((action) =>\n state$.pipe(\n map((state) => state.context),\n filter((context): context is MemoryRuntimeContext =>\n Boolean(context),\n ),\n take(1),\n map((context) => ({ action, context })),\n takeUntil(\n actions$.pipe(\n ofType(\n memoryAdapterEvents.contextChanged,\n memoryAdapterEvents.stopped,\n ),\n ),\n ),\n switchMap(({ action: currentAction, context }) =>\n createMemoryCredentialsFetchObservable(\n environment,\n context,\n currentAction.sessionId,\n ),\n ),\n ),\n ),\n ),\n );\n\n const fetchEffect = createEffect(\n (actions$, state$: Observable<MemoryState>) =>\n actions$.pipe(\n ofType(memoryRestEvents.listRequested),\n switchMap((action) =>\n state$.pipe(\n map((state) => state.context),\n filter((context): context is MemoryRuntimeContext =>\n Boolean(context),\n ),\n take(1),\n map((context) => ({ action, context })),\n takeUntil(\n actions$.pipe(\n ofType(\n memoryAdapterEvents.contextChanged,\n memoryAdapterEvents.stopped,\n ),\n ),\n ),\n switchMap(({ action: currentAction, context }) =>\n createMemoryFetchObservable(\n environment,\n context,\n currentAction.sessionId,\n ),\n ),\n ),\n ),\n ),\n );\n\n const mutationEffect = createEffect(\n (actions$, state$: Observable<MemoryState>) =>\n actions$.pipe(\n ofType(\n memoryAdapterEvents.addRequested,\n memoryAdapterEvents.updateRequested,\n memoryAdapterEvents.removeRequested,\n ),\n withLatestFrom(state$),\n mergeMap(([action, state]) => {\n const context = state.context;\n const sessionId = state.sessionId;\n if (!context?.runtimeUrl) {\n return of(\n memoryRestEvents.mutationFinished({\n outcome: {\n requestId: action.requestId,\n sessionId,\n ok: false,\n error: new Error(\"Runtime URL is not configured\"),\n },\n }),\n );\n }\n\n if (memoryAdapterEvents.addRequested.match(action)) {\n return createMemoryMutationObservable(environment, context, {\n requestId: action.requestId,\n sessionId,\n kind: \"add\",\n body: toMutationBody(action.input),\n });\n }\n if (memoryAdapterEvents.updateRequested.match(action)) {\n return createMemoryMutationObservable(environment, context, {\n requestId: action.requestId,\n sessionId,\n kind: \"update\",\n id: action.id,\n body: toMutationBody(action.changes),\n });\n }\n return createMemoryMutationObservable(environment, context, {\n requestId: action.requestId,\n sessionId,\n kind: \"remove\",\n id: action.id,\n });\n }),\n ),\n );\n\n const socketEffect = createEffect(\n (actions$, state$: Observable<MemoryState>) =>\n actions$.pipe(\n ofType(memoryRestEvents.credentialsSucceeded),\n withLatestFrom(state$),\n filter(([action, state]) => {\n return (\n action.sessionId === state.sessionId &&\n Boolean(state.context?.wsUrl)\n );\n }),\n switchMap(([action, state]) => {\n const context = state.context as MemoryRuntimeContext;\n const { joinToken, joinCode, projectJoinToken, projectJoinCode } =\n action;\n const primaryJoinToken = joinToken ?? projectJoinToken!;\n const primaryTopic =\n joinToken && joinCode\n ? `user_meta:memories:${joinCode}`\n : `project_meta:memories:${projectJoinCode!}`;\n const sessionId = action.sessionId;\n const shutdown$ = actions$.pipe(\n ofType(\n memoryAdapterEvents.contextChanged,\n memoryAdapterEvents.stopped,\n ),\n );\n\n // Builds the live `memory_metadata` delta stream for one realtime\n // channel (its own socket, keyed by that channel's join token). Both\n // the user channel and the optional project channel feed the SAME\n // reducer through this, and — critically — both stamp their deltas\n // with the SAME `sessionId` (the D4 landmine): the reducer's\n // superseded-context guard therefore drops stale deltas from BOTH\n // channels identically the moment the context changes. The reducer's\n // upsert/invalidate already key by memory id, so interleaving user\n // and project rows is safe (no per-channel bookkeeping needed).\n const channelMetadata$ = (\n channelJoinToken: string,\n topic: string,\n ): Observable<\n | ReturnType<typeof memoryDomainEvents.memoryUpserted>\n | ReturnType<typeof memoryDomainEvents.memoryInvalidated>\n > => {\n const socket$ = ɵphoenixSocket$({\n url: context.wsUrl,\n options: {\n params: { join_token: channelJoinToken },\n reconnectAfterMs: phoenixExponentialBackoff(100, 10_000),\n rejoinAfterMs: phoenixExponentialBackoff(1_000, 30_000),\n },\n }).pipe(shareReplay({ bufferSize: 1, refCount: true }));\n const channel$ = ɵphoenixChannel$({ socket$, topic }).pipe(\n shareReplay({ bufferSize: 1, refCount: true }),\n );\n const metadata$ = channel$.pipe(\n switchMap(({ channel }: ɵPhoenixChannelSession) =>\n ɵobservePhoenixEvent$<MemoryMetadataEvent>(\n channel,\n MEMORY_METADATA_EVENT,\n ),\n ),\n map((event) => mapMemoryMetadataEvent(event, sessionId)),\n );\n // Drive the join (see the user-channel note below) but swallow its\n // outcome: the project channel deliberately does NOT emit realtime\n // status deltas — `realtimeStatus` is owned by the user channel so\n // a project-channel join failure never regresses the user-facing\n // \"live\" indicator (silent degrade). On failure the metadata stream\n // stays alive for Phoenix's automatic rejoin on reconnect.\n const join$ = ɵjoinPhoenixChannel$(channel$).pipe(\n catchError((error) => {\n console.warn(`[memory] failed to join ${topic}`, error);\n return EMPTY;\n }),\n );\n return merge(metadata$, join$);\n };\n\n return defer(() => {\n const socket$ = ɵphoenixSocket$({\n url: context.wsUrl,\n options: {\n params: { join_token: primaryJoinToken },\n reconnectAfterMs: phoenixExponentialBackoff(100, 10_000),\n rejoinAfterMs: phoenixExponentialBackoff(1_000, 30_000),\n },\n }).pipe(shareReplay({ bufferSize: 1, refCount: true }));\n const channel$ = ɵphoenixChannel$({\n socket$,\n topic: primaryTopic,\n }).pipe(shareReplay({ bufferSize: 1, refCount: true }));\n const socketSignals$ =\n ɵobservePhoenixSocketSignals$(socket$).pipe(share());\n // The socket give-up signal: completes the realtime stream after the\n // health check throws. ALSO surfaces the give-up as a status delta\n // (`realtimeUnavailable`) so the UI can drop its \"live\" indicator —\n // this is the permanent-death signal that was previously only a\n // `console.warn`. `available`/`error` stay untouched by design (the\n // realtime path is a silent degrade for the REST list route).\n const fatalSocketShutdown$ = ɵobservePhoenixSocketHealth$(\n socketSignals$,\n MAX_SOCKET_RETRIES,\n ).pipe(\n catchError(() => {\n console.warn(\n `[memory] WebSocket failed after ${MAX_SOCKET_RETRIES} attempts, giving up`,\n );\n return of(undefined);\n }),\n share(),\n );\n // The give-up mapped to a status delta. Emitted from the merged stream\n // (not the `takeUntil` notifier) so the `realtimeUnavailable` action is\n // dispatched BEFORE teardown: the merged stream is `takeUntil`'d by a\n // microtask-deferred copy of the give-up signal, so this synchronous\n // emission always wins the race and the action reaches the reducer.\n const fatalStatus$ = fatalSocketShutdown$.pipe(\n map(() => memoryDomainEvents.realtimeUnavailable({ sessionId })),\n );\n const metadata$ = channel$.pipe(\n switchMap(({ channel }: ɵPhoenixChannelSession) =>\n ɵobservePhoenixEvent$<MemoryMetadataEvent>(\n channel,\n MEMORY_METADATA_EVENT,\n ),\n ),\n map((event) => mapMemoryMetadataEvent(event, action.sessionId)),\n );\n\n // Drives the actual `channel.join()` AND maps the join outcome to a\n // realtime-status delta. `ɵphoenixChannel$` only creates the channel +\n // a lazy join-outcome stream; the join is sent when that stream is\n // subscribed. Observing channel events (`metadata$`) alone does NOT\n // subscribe it, so without this the socket connects but never joins\n // `user_meta:memories:<code>` and no realtime deltas arrive. The thread\n // store joins for the same reason (its merged `joinOutcome$`).\n //\n // On a successful join -> `realtimeConnected` (the \"live\" signal). On a\n // failed/timed-out join we KEEP the `console.warn` and emit\n // `realtimeUnavailable`, then swallow the error so a transient\n // rejection doesn't tear down the metadata stream (Phoenix re-attempts\n // the join on socket reconnect); the next successful join re-emits\n // `realtimeConnected`.\n const join$ = ɵjoinPhoenixChannel$(channel$).pipe(\n // `ɵjoinPhoenixChannel$` emits `never` (it completes on success), so\n // this concat surfaces the connected status once the join resolves.\n concatWith(\n of(memoryDomainEvents.realtimeConnected({ sessionId })),\n ),\n catchError((error) => {\n console.warn(`[memory] failed to join ${primaryTopic}`, error);\n return of(\n memoryDomainEvents.realtimeUnavailable({ sessionId }),\n );\n }),\n );\n\n // Open the project channel alongside the user channel when project\n // credentials are present. It feeds the SAME reducer with the SAME\n // session stamp (see `channelMetadata$`), so project rows stay live\n // without going stale. Absent project creds -> `EMPTY`: user-only,\n // no second socket, no status regression (silent degrade).\n const projectMetadata$ =\n joinToken && joinCode && projectJoinToken && projectJoinCode\n ? channelMetadata$(\n projectJoinToken,\n `project_meta:memories:${projectJoinCode}`,\n )\n : EMPTY;\n\n return merge(\n // Surface \"connecting\" immediately when the realtime stream starts\n // (credentials succeeded -> socket subscribing/joining). Reset to\n // this on every (re)subscribe so a prior session's terminal status\n // can't bleed through before the new join resolves.\n of(memoryDomainEvents.realtimeConnecting({ sessionId })),\n metadata$,\n join$,\n projectMetadata$,\n fatalStatus$,\n ).pipe(\n takeUntil(\n merge(\n shutdown$,\n // Defer the give-up teardown by a microtask so `fatalStatus$`'s\n // synchronous `realtimeUnavailable` emission is dispatched before\n // the stream is torn down. `observeOn(asapScheduler)` schedules\n // the teardown after the current microtask drains.\n fatalSocketShutdown$.pipe(observeOn(asapScheduler)),\n ),\n ),\n finalize(() => {\n // Socket/channel teardown is handled by the `finalize` operators\n // inside `ɵphoenixSocket$`/`ɵphoenixChannel$`; this hook exists to\n // mirror the thread store's socket-effect lifecycle shape.\n }),\n );\n });\n }),\n ),\n );\n\n const store = createStore<MemoryState>({\n reducer: memoryReducer,\n effects: [\n bootstrapEffect,\n credentialsBootstrapEffect,\n fetchEffect,\n credentialsFetchEffect,\n mutationEffect,\n socketEffect,\n ],\n });\n\n function trackMutation<T>(\n dispatchAction:\n | ReturnType<typeof memoryAdapterEvents.addRequested>\n | ReturnType<typeof memoryAdapterEvents.updateRequested>\n | ReturnType<typeof memoryAdapterEvents.removeRequested>,\n extract: (outcome: Extract<MemoryMutationOutcome, { ok: true }>) => T,\n ): Promise<T> {\n const { requestId } = dispatchAction;\n const completion$ = merge(\n store.actions$.pipe(\n ofType(memoryRestEvents.mutationFinished),\n filter((action) => action.outcome.requestId === requestId),\n map((action) => action.outcome),\n ),\n store.actions$.pipe(\n ofType(memoryAdapterEvents.stopped),\n map(\n () =>\n ({\n requestId,\n sessionId: store.getState().sessionId,\n ok: false,\n error: new Error(\n \"Memory store stopped before mutation completed\",\n ),\n }) satisfies MemoryMutationOutcome,\n ),\n ),\n ).pipe(take(1));\n\n const resultPromise = firstValueFrom(completion$).then((outcome) => {\n if (!outcome.ok) {\n throw outcome.error;\n }\n return extract(outcome);\n });\n\n store.dispatch(dispatchAction);\n return resultPromise;\n }\n\n return {\n start(): void {\n store.init();\n store.dispatch(memoryAdapterEvents.started());\n },\n stop(): void {\n store.dispatch(memoryAdapterEvents.stopped());\n store.stop();\n },\n setContext(context: MemoryRuntimeContext | null): void {\n store.dispatch(memoryAdapterEvents.contextChanged({ context }));\n },\n refresh(): Promise<void> {\n const { sessionId, context } = store.getState();\n if (!context) return Promise.resolve();\n\n // Settle when the re-pulled snapshot completes for this session (success\n // or failure), or if the store is stopped first. Subscribe before\n // dispatching so the resulting list action can't slip past, mirroring\n // trackMutation.\n const completion$ = merge(\n store.actions$.pipe(\n ofType(\n memoryRestEvents.listSucceeded,\n memoryRestEvents.listFailed,\n // `listUnavailable` (404/501/422) is the third terminal outcome of\n // the list fetch. Without it `await refresh()` would hang forever\n // against an unconfigured route.\n memoryRestEvents.listUnavailable,\n ),\n filter((action) => action.sessionId === sessionId),\n ),\n store.actions$.pipe(ofType(memoryAdapterEvents.stopped)),\n // The list `fetchEffect` has `takeUntil(contextChanged, stopped)`, so a\n // `contextChanged` fired after this `listRequested` but before the fetch\n // settles tears down the fetch with NO terminal list action for our\n // session — `await refresh()` would hang forever. Settle on it too.\n store.actions$.pipe(ofType(memoryAdapterEvents.contextChanged)),\n ).pipe(take(1));\n\n // `await refresh()` resolving must mean the snapshot actually refreshed,\n // so reject on anything that isn't a successful re-pull — a failed list\n // (its error also lands in the `error` selector) or the store being\n // stopped mid-flight. This keeps `refresh` fully symmetric with the\n // mutation methods, which reject on both failure and stop via\n // `trackMutation`.\n const done = firstValueFrom(completion$).then((action) => {\n if (memoryRestEvents.listFailed.match(action)) {\n throw action.error;\n }\n if (memoryAdapterEvents.stopped.match(action)) {\n throw new Error(\"Memory store stopped before refresh completed\");\n }\n // A `contextChanged` superseded this refresh: a new context is loading\n // its own snapshot, so this refresh is moot. RESOLVE (do not reject) —\n // resolving is the least-surprising outcome for a superseded refresh.\n if (memoryAdapterEvents.contextChanged.match(action)) {\n return;\n }\n // `listSucceeded` and `listUnavailable` both RESOLVE: an unavailable\n // (not-configured) route is a non-fatal terminal state, consistent with\n // the auto-load path which leaves `available: false` without erroring.\n });\n store.dispatch(memoryRestEvents.listRequested({ sessionId }));\n return done;\n },\n recall(\n query: string,\n opts?: { limit?: number; scope?: MemoryScope },\n ): Promise<Memory[]> {\n const { context } = store.getState();\n if (!context?.runtimeUrl) {\n return Promise.reject(new Error(\"Runtime URL is not configured\"));\n }\n const body: Record<string, unknown> = { query };\n if (opts?.limit !== undefined) body.limit = opts.limit;\n if (opts?.scope !== undefined) body.scope = opts.scope;\n\n const recall$ = memoryFromFetch(\n `${context.runtimeUrl}${MEMORIES_RECALL_PATH}`,\n {\n selector: async (response) => {\n if (!response.ok) {\n throw new MemoryError(\"MEMORY_RECALL_FAILED\", {\n message: `Failed to recall memories: ${response.status}`,\n retryable: isRetryableStatus(response.status),\n });\n }\n return (await response.json()) as { memories: unknown[] };\n },\n fetch: environment.fetch,\n method: \"POST\",\n headers: { ...context.headers, \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n },\n ).pipe(\n timeout({\n first: REQUEST_TIMEOUT_MS,\n with: () => {\n throw new MemoryError(\"MEMORY_REQUEST_TIMEOUT\");\n },\n }),\n map((data) =>\n (data.memories ?? []).map((m) =>\n recallResponseToMemory(\n m as Parameters<typeof recallResponseToMemory>[0],\n ),\n ),\n ),\n );\n return firstValueFrom(recall$);\n },\n addMemory(input: NewMemory): Promise<Memory> {\n return trackMutation(\n memoryAdapterEvents.addRequested({\n requestId: createMemoryRequestId(),\n input,\n }),\n (outcome) => {\n if (outcome.memory == null) {\n throw new Error(\"add resolved without a memory\");\n }\n return outcome.memory;\n },\n );\n },\n updateMemory(id: string, changes: MemoryChanges): Promise<Memory> {\n return trackMutation(\n memoryAdapterEvents.updateRequested({\n requestId: createMemoryRequestId(),\n id,\n changes,\n }),\n (outcome) => {\n if (outcome.memory == null) {\n throw new Error(\"update resolved without a memory\");\n }\n return outcome.memory;\n },\n );\n },\n removeMemory(id: string): Promise<void> {\n return trackMutation(\n memoryAdapterEvents.removeRequested({\n requestId: createMemoryRequestId(),\n id,\n }),\n () => undefined,\n );\n },\n getState(): MemoryState {\n return store.getState();\n },\n getServerState(): MemoryState {\n return initialMemoryState;\n },\n select: store.select.bind(store),\n };\n}\n\n// `Memory`, `MemoryKind`, `MemoryScope`, `NewMemory`, and `MemoryChanges` are\n// the consumer-facing memory types surfaced by the framework hooks\n// (`useMemories` / `injectMemories`); they are exported unprefixed from their\n// declarations above. The remaining memory internals keep the `ɵ` prefix.\n// The memory error registry surface is consumer-facing: `MemoryError` is what\n// `MemoryState.error` (and the `error: Error | null` from `useMemories` /\n// `injectMemories`) carries on a failure, and consumers branch on its\n// `code`/`category`/`retryable`. Re-exported unprefixed here so it ships through\n// `index.ts` (`export * from \"./memory\"`) alongside the memory types.\nexport {\n MemoryError,\n MEMORY_ERROR_REGISTRY,\n isRetryableStatus as ɵisRetryableMemoryStatus,\n} from \"./memory-errors\";\nexport type {\n MemoryErrorCode,\n MemoryErrorCategory,\n MemoryErrorRegistryEntry,\n} from \"./memory-errors\";\n\nexport type ɵMemoryState = MemoryState;\nexport type ɵMemoryRuntimeContext = MemoryRuntimeContext;\nexport type ɵMemoryMetadataEvent = MemoryMetadataEvent;\nexport type ɵMemoryEnvironment = MemoryEnvironment;\nexport type ɵMemoryStore = MemoryStore;\nexport const ɵmemoryAdapterEvents = memoryAdapterEvents;\nexport const ɵmemoryRestEvents = memoryRestEvents;\nexport const ɵmemoryDomainEvents = memoryDomainEvents;\nexport const ɵmemoryReducer = memoryReducer;\nexport const ɵmapMemoryMetadataEvent = mapMemoryMetadataEvent;\nexport const ɵselectMemories = selectMemories;\nexport const ɵselectMemoriesIsLoading = selectMemoriesIsLoading;\nexport const ɵselectMemoriesError = selectMemoriesError;\nexport const ɵselectMemoriesIsMutating = selectMemoriesIsMutating;\nexport const ɵselectMemoriesAvailable = selectMemoriesAvailable;\nexport const ɵselectMemoriesRealtimeStatus = selectMemoriesRealtimeStatus;\nexport { createMemoryStore as ɵcreateMemoryStore };\n","import type { AbstractAgent, Context, State } from \"@ag-ui/client\";\nimport type { AgentSubscriber } from \"@ag-ui/client\";\nimport { Throttler } from \"@tanstack/pacer\";\nimport type {\n FrontendTool,\n SuggestionsConfig,\n Suggestion,\n CopilotRuntimeTransport,\n RuntimeMode,\n RuntimeLicenseStatus,\n IntelligenceRuntimeInfo,\n InspectorMetadataV1,\n ThreadEndpointRuntimeInfo,\n} from \"../types\";\nimport type {\n CopilotKitCoreAddAgentParams,\n CopilotKitCoreRegisterProxiedAgentParams,\n CopilotKitCoreRegisterProxiedAgentResult,\n} from \"./agent-registry\";\nimport type { CopilotKitMessageFilter } from \"./message-filter\";\nimport { AgentRegistry } from \"./agent-registry\";\nimport type { ScopedContext } from \"./context-store\";\nimport { ContextStore } from \"./context-store\";\nimport { SuggestionEngine } from \"./suggestion-engine\";\nimport type {\n CopilotKitCoreRunAgentParams,\n CopilotKitCoreConnectAgentParams,\n CopilotKitCoreGetToolParams,\n CopilotKitCoreRunToolParams,\n CopilotKitCoreRunToolResult,\n CopilotKitCoreCatalogComponent,\n} from \"./run-handler\";\nimport { RunHandler } from \"./run-handler\";\nimport type {\n DebugConfig,\n RuntimeEntitlementResponse,\n} from \"@copilotkit/shared\";\nimport { StateManager } from \"./state-manager\";\nimport type { CopilotKitCoreContinuationHandoff } from \"./state-manager\";\nimport { ThreadStoreRegistry } from \"./thread-store-registry\";\nimport type { ɵThreadStore } from \"../threads\";\nimport { ɵcreateMemoryStore } from \"../memory\";\nimport type { ɵMemoryStore } from \"../memory\";\n\n/** Configuration options for `CopilotKitCore`. */\nexport interface CopilotKitCoreConfig {\n /** The endpoint of the CopilotRuntime. */\n runtimeUrl?: string;\n /** Transport style for CopilotRuntime endpoints. Defaults to REST. */\n runtimeTransport?: CopilotRuntimeTransport;\n /**\n * When true, the constructor sets the runtime config but does NOT start the\n * `/info` connection. Call {@link CopilotKitCore.connect} to start it —\n * typically from a host's commit-phase effect. This prevents a burst of\n * duplicate `/info` requests when a host constructs (and discards) the core\n * during render, e.g. React concurrent rendering / Suspense / StrictMode.\n * See https://github.com/CopilotKit/CopilotKit/issues/5801.\n */\n deferInitialConnection?: boolean;\n /** Mapping from agent name to its `AbstractAgent` instance. For development only - production requires CopilotRuntime. */\n agents__unsafe_dev_only?: Record<string, AbstractAgent>;\n /**\n * Headers sent with every runtime request and merged on top of each\n * `HttpAgent`'s own headers (the core value wins on a key conflict). See\n * `setHeaders`.\n */\n headers?: Record<string, string>;\n /** Credentials mode for fetch requests (e.g., \"include\" for HTTP-only cookies). */\n credentials?: RequestCredentials;\n /**\n * Rewrites the message list sent to runtime agents on every run. Use it when\n * the backend already stores the conversation and re-sending it is waste or\n * duplication. See `setMessageFilter` and {@link CopilotKitMessageFilter}.\n */\n messageFilter?: CopilotKitMessageFilter;\n /** Properties sent as `forwardedProps` to the AG-UI agent. */\n properties?: Record<string, unknown>;\n /** Ordered collection of frontend tools available to the core. */\n tools?: FrontendTool<any>[];\n /** Suggestions config for the core. */\n suggestionsConfig?: SuggestionsConfig[];\n /** Enable debug logging for the client-side event pipeline. */\n debug?: DebugConfig;\n}\n\nexport type { CopilotKitMessageFilter } from \"./message-filter\";\n\nexport type {\n CopilotKitCoreAddAgentParams,\n CopilotKitCoreRegisterProxiedAgentParams,\n CopilotKitCoreRegisterProxiedAgentResult,\n};\nexport type {\n CopilotKitCoreRunAgentParams,\n CopilotKitCoreConnectAgentParams,\n CopilotKitCoreGetToolParams,\n CopilotKitCoreRunToolParams,\n CopilotKitCoreRunToolResult,\n CopilotKitCoreCatalogComponent,\n};\n\nexport interface CopilotKitCoreStopAgentParams {\n agent: AbstractAgent;\n}\n\nexport type CopilotKitCoreGetSuggestionsResult = {\n suggestions: Suggestion[];\n isLoading: boolean;\n};\n\nexport enum CopilotKitCoreErrorCode {\n RUNTIME_INFO_FETCH_FAILED = \"runtime_info_fetch_failed\",\n AGENT_CONNECT_FAILED = \"agent_connect_failed\",\n AGENT_RUN_FAILED = \"agent_run_failed\",\n AGENT_RUN_FAILED_EVENT = \"agent_run_failed_event\",\n AGENT_RUN_ERROR_EVENT = \"agent_run_error_event\",\n TOOL_ARGUMENT_PARSE_FAILED = \"tool_argument_parse_failed\",\n TOOL_HANDLER_FAILED = \"tool_handler_failed\",\n TOOL_NOT_FOUND = \"tool_not_found\",\n AGENT_NOT_FOUND = \"agent_not_found\",\n /**\n * Emitted when an agent run fails because the thread is already locked\n * by another active run.\n *\n * @example\n * ```tsx\n * <CopilotKitProvider\n * onError={({ code, error, context }) => {\n * if (code === \"agent_thread_locked\") {\n * // Show \"Agent is busy, retry?\" UI\n * }\n * }}\n * />\n * ```\n */\n AGENT_THREAD_LOCKED = \"agent_thread_locked\",\n // Transcription errors\n TRANSCRIPTION_FAILED = \"transcription_failed\",\n TRANSCRIPTION_SERVICE_NOT_CONFIGURED = \"transcription_service_not_configured\",\n TRANSCRIPTION_INVALID_AUDIO = \"transcription_invalid_audio\",\n TRANSCRIPTION_RATE_LIMITED = \"transcription_rate_limited\",\n TRANSCRIPTION_AUTH_FAILED = \"transcription_auth_failed\",\n TRANSCRIPTION_NETWORK_ERROR = \"transcription_network_error\",\n SUBSCRIBER_CALLBACK_FAILED = \"subscriber_callback_failed\",\n}\n\nexport interface CopilotKitCoreSubscriber {\n onRuntimeConnectionStatusChanged?: (event: {\n copilotkit: CopilotKitCore;\n status: CopilotKitCoreRuntimeConnectionStatus;\n }) => void | Promise<void>;\n onToolExecutionStart?: (event: {\n copilotkit: CopilotKitCore;\n toolCallId: string;\n agentId: string;\n toolName: string;\n args: unknown;\n }) => void | Promise<void>;\n onToolExecutionEnd?: (event: {\n copilotkit: CopilotKitCore;\n toolCallId: string;\n agentId: string;\n toolName: string;\n result: string;\n error?: string;\n }) => void | Promise<void>;\n onAgentsChanged?: (event: {\n copilotkit: CopilotKitCore;\n agents: Readonly<Record<string, AbstractAgent>>;\n }) => void | Promise<void>;\n /**\n * Fired when an agent run or connect begins. The `agent` may be a per-thread\n * clone that is not present in `core.agents`, so `onAgentsChanged` never fires\n * for it. Subscribers (e.g. the inspector) can use this to subscribe to the\n * running instance's AG-UI events.\n */\n onAgentRunStarted?: (event: {\n copilotkit: CopilotKitCore;\n agent: AbstractAgent;\n }) => void | Promise<void>;\n onContextChanged?: (event: {\n copilotkit: CopilotKitCore;\n context: Readonly<Record<string, Context>>;\n }) => void | Promise<void>;\n /**\n * Fired when the A2UI catalog component list changes (registration) or when\n * a component is enabled/disabled. Consumers (the provider, the inspector)\n * re-derive the filtered catalog from this event.\n */\n onCatalogComponentsChanged?: (event: {\n copilotkit: CopilotKitCore;\n catalogComponents: ReadonlyArray<CopilotKitCoreCatalogComponent>;\n }) => void | Promise<void>;\n onSuggestionsConfigChanged?: (event: {\n copilotkit: CopilotKitCore;\n suggestionsConfig: Readonly<Record<string, SuggestionsConfig>>;\n }) => void | Promise<void>;\n onSuggestionsChanged?: (event: {\n copilotkit: CopilotKitCore;\n agentId: string;\n suggestions: Suggestion[];\n }) => void | Promise<void>;\n onSuggestionsStartedLoading?: (event: {\n copilotkit: CopilotKitCore;\n agentId: string;\n }) => void | Promise<void>;\n onSuggestionsFinishedLoading?: (event: {\n copilotkit: CopilotKitCore;\n agentId: string;\n }) => void | Promise<void>;\n onPropertiesChanged?: (event: {\n copilotkit: CopilotKitCore;\n properties: Readonly<Record<string, unknown>>;\n }) => void | Promise<void>;\n onHeadersChanged?: (event: {\n copilotkit: CopilotKitCore;\n headers: Readonly<Record<string, string>>;\n }) => void | Promise<void>;\n onInspectorMetadataChanged?: (event: {\n copilotkit: CopilotKitCore;\n inspectorMetadata: InspectorMetadataV1 | undefined;\n }) => void | Promise<void>;\n onError?: (event: {\n copilotkit: CopilotKitCore;\n error: Error;\n code: CopilotKitCoreErrorCode;\n context: Record<string, any>;\n }) => void | Promise<void>;\n onThreadStoreRegistered?: (event: {\n copilotkit: CopilotKitCore;\n agentId: string;\n store: ɵThreadStore;\n }) => void | Promise<void>;\n /**\n * Fired when a thread store is removed from the registry, either by an\n * explicit `unregister()` call or by a `register()` call that replaces an\n * existing store for the same `agentId`.\n *\n * The previous store is delivered via `prevStore` so subscribers can tear\n * down state that depends on the concrete instance (e.g. cancel an active\n * subscription) without consulting the registry. By the time async\n * subscribers resume after an `await`, a replacement `register()` may have\n * already installed the new store under the same key, so calling\n * `registry.get(agentId)` inside this callback is unsafe and may return\n * the new store instead of the unregistered one.\n */\n onThreadStoreUnregistered?: (event: {\n copilotkit: CopilotKitCore;\n agentId: string;\n prevStore: ɵThreadStore;\n }) => void | Promise<void>;\n}\n\n// Subscription object returned by subscribe() and subscribeToAgentWithOptions()\nexport interface CopilotKitCoreSubscription {\n unsubscribe: () => void;\n}\n\n/**\n * The callback keys accepted by {@link CopilotKitCore.subscribeToAgentWithOptions}.\n * This tuple is the single source of truth — both the\n * `SubscribeToAgentSubscriber` type and the runtime `ALLOWED_KEYS` set\n * are derived from it, so they cannot desynchronise.\n */\nconst SUBSCRIBE_TO_AGENT_KEYS = [\n \"onMessagesChanged\",\n \"onStateChanged\",\n \"onRunInitialized\",\n \"onRunFinalized\",\n \"onRunFailed\",\n \"onRunErrorEvent\",\n] as const satisfies readonly (keyof AgentSubscriber)[];\n\n/**\n * Runtime allowlist derived from {@link SUBSCRIBE_TO_AGENT_KEYS}. Hoisted\n * to module scope so the Set is allocated once, not per-subscription.\n */\nconst ALLOWED_KEYS: ReadonlySet<(typeof SUBSCRIBE_TO_AGENT_KEYS)[number]> =\n new Set(SUBSCRIBE_TO_AGENT_KEYS);\n\n/**\n * The subset of `AgentSubscriber` callbacks accepted by\n * {@link CopilotKitCore.subscribeToAgentWithOptions}. Only the callbacks\n * listed in {@link SUBSCRIBE_TO_AGENT_KEYS} are supported:\n * `onMessagesChanged`, `onStateChanged`, and the four run lifecycle\n * callbacks (`onRunInitialized`, `onRunFinalized`, `onRunFailed`,\n * `onRunErrorEvent`).\n *\n * Two categories of `AgentSubscriber` members are excluded:\n *\n * - **AG-UI event handlers** (`onEvent`, `onToolCallStartEvent`, etc.)\n * return `AgentStateMutation` with `stopPropagation` — semantics that\n * the throttle and error-protection wrappers cannot safely mediate.\n *\n * - **Per-item notification callbacks** (`onNewMessage`, `onNewToolCall`)\n * return `void` and have no mutation concerns, but are excluded to keep\n * the surface area minimal — `onMessagesChanged` already covers the\n * same data at a coarser granularity, and throttling per-item callbacks\n * would have different semantic expectations.\n *\n * `onRunErrorEvent` is technically an AG-UI event handler (its return type\n * includes `stopPropagation`), but it is included here because all\n * framework consumers need it to reset `isRunning` on protocol-level\n * `RUN_ERROR` events — distinct from `onRunFailed` which handles local\n * exceptions like network errors. In practice, consumers return `void`\n * from this callback, so the `stopPropagation` semantics are unused.\n *\n * Note: the included lifecycle callbacks return\n * `Omit<AgentStateMutation, \"stopPropagation\">` (or full\n * `AgentStateMutation` in the case of `onRunErrorEvent`). On the error\n * path, `safeCall` discards those return values (see its inline\n * documentation).\n *\n * Use `agent.subscribe()` directly when event mutation or per-item\n * notification semantics are needed.\n */\nexport type SubscribeToAgentSubscriber = Pick<\n AgentSubscriber,\n (typeof SUBSCRIBE_TO_AGENT_KEYS)[number]\n>;\n\n/** Options for {@link CopilotKitCore.subscribeToAgentWithOptions}. */\nexport interface SubscribeToAgentOptions {\n /**\n * Throttle interval (ms) for `onMessagesChanged` / `onStateChanged`.\n * Non-negative finite number; `0` explicitly disables throttling.\n * Falls back to `defaultThrottleMs` when `undefined`.\n */\n throttleMs?: number;\n}\n\nexport enum CopilotKitCoreRuntimeConnectionStatus {\n Disconnected = \"disconnected\",\n Connected = \"connected\",\n Connecting = \"connecting\",\n Error = \"error\",\n}\n\n/**\n * Internal interface for delegate classes to access CopilotKitCore methods.\n * This provides type safety while allowing controlled access to private functionality.\n */\nexport interface CopilotKitCoreFriendsAccess {\n // Notification methods\n notifySubscribers(\n handler: (subscriber: CopilotKitCoreSubscriber) => void | Promise<void>,\n errorMessage: string,\n ): Promise<void>;\n\n emitError(params: {\n error: Error;\n code: CopilotKitCoreErrorCode;\n context?: Record<string, any>;\n }): Promise<void>;\n\n // Getters for internal state\n readonly headers: Readonly<Record<string, string>>;\n readonly credentials: RequestCredentials | undefined;\n readonly messageFilter: CopilotKitMessageFilter | undefined;\n readonly properties: Readonly<Record<string, unknown>>;\n readonly context: Readonly<Record<string, Context>>;\n readonly debug?: DebugConfig;\n\n // Internal methods\n buildFrontendTools(agentId?: string): import(\"@ag-ui/client\").Tool[];\n getContextForAgent(agentId?: string): Context[];\n getAgent(id: string): AbstractAgent | undefined;\n /**\n * Re-apply the current core headers to a single agent, merged on top of the\n * headers the agent was constructed with. The single source of truth for\n * header application; the run handler uses it so a run never clobbers\n * per-agent headers (see #5635).\n */\n applyHeadersToAgent(agent: AbstractAgent): void;\n\n // References to delegate subsystems\n readonly suggestionEngine: {\n clearSuggestions(agentId: string): void;\n reloadSuggestions(agentId: string): void;\n };\n\n /**\n * Called before each follow-up agent run (after tool execution).\n * See CopilotKitCore.waitForPendingFrameworkUpdates for details.\n */\n waitForPendingFrameworkUpdates(): Promise<void>;\n\n readonly stateManager: {\n markNextRunAsContinuation(\n agent: AbstractAgent,\n expectedRunId?: string,\n ): CopilotKitCoreContinuationHandoff;\n };\n}\n\n/**\n * Normalize a header map to the internal invariant: a `Record<string, string>`\n * with no `null`/`undefined` values. Entries whose value is `null`/`undefined`\n * are dropped (this is how a header is cleared). Shared by the constructor and\n * `setHeaders` so both write paths into `_headers` enforce the same invariant.\n */\nfunction normalizeHeaders(\n headers: Record<string, string | null | undefined>,\n): Record<string, string> {\n return Object.fromEntries(\n Object.entries(headers).filter(\n (entry): entry is [string, string] => entry[1] != null,\n ),\n );\n}\n\nexport class CopilotKitCore {\n private _headers: Record<string, string>;\n private _credentials?: RequestCredentials;\n private _messageFilter?: CopilotKitMessageFilter;\n private _properties: Record<string, unknown>;\n private _defaultThrottleMs?: number;\n private _debug?: DebugConfig;\n\n private subscribers: Set<CopilotKitCoreSubscriber> = new Set();\n\n // Delegate classes\n private agentRegistry: AgentRegistry;\n private contextStore: ContextStore;\n private suggestionEngine: SuggestionEngine;\n private runHandler: RunHandler;\n private stateManager: StateManager;\n private threadStoreRegistry: ThreadStoreRegistry;\n /**\n * The single core-owned memory store, created lazily on first\n * `getMemoryStore()` and kept user-scoped for the lifetime of the core.\n * Its runtime context is wired by the core itself (see `syncMemoryContext`),\n * so callers never register or look it up by `agentId`.\n */\n private _memoryStore?: ɵMemoryStore;\n /**\n * Tracks the agent IDs from the most recent `onAgentsChanged` notification.\n * Used to gate thread-store auto-unregister so the FIRST empty-agents\n * notification (before published agents are merged in) does not rip out a\n * store that was registered prior to that initial notification.\n */\n private previousAgentIds: Set<string> = new Set();\n\n constructor({\n runtimeUrl,\n runtimeTransport = \"auto\",\n deferInitialConnection = false,\n headers = {},\n credentials,\n messageFilter,\n properties = {},\n agents__unsafe_dev_only = {},\n tools = [],\n suggestionsConfig = [],\n debug,\n }: CopilotKitCoreConfig) {\n this._headers = normalizeHeaders(headers);\n this._credentials = credentials;\n this._messageFilter = messageFilter;\n this._properties = properties;\n this._debug = debug;\n\n // Initialize delegate classes\n this.agentRegistry = new AgentRegistry(this);\n this.contextStore = new ContextStore(this);\n this.suggestionEngine = new SuggestionEngine(this);\n this.runHandler = new RunHandler(this);\n this.stateManager = new StateManager(this);\n this.threadStoreRegistry = new ThreadStoreRegistry(this);\n\n // Initialize each subsystem\n this.agentRegistry.initialize(agents__unsafe_dev_only);\n this.runHandler.initialize(tools);\n this.suggestionEngine.initialize(suggestionsConfig);\n this.stateManager.initialize();\n\n this.agentRegistry.setRuntimeTransport(runtimeTransport);\n this.agentRegistry.setRuntimeUrl(runtimeUrl, {\n deferConnection: deferInitialConnection,\n });\n\n // Seed the previous-agents snapshot from the constructor-supplied agents.\n // `agentRegistry.initialize` does not emit `onAgentsChanged`, so the\n // subscriber below would otherwise see its first non-empty notification\n // as an \"addition\" relative to an empty baseline — and a later removal\n // of those same agents would NOT trigger the auto-unregister branch\n // because the guard would think the agentId was never previously\n // present. Seeding the set here keeps the guard honest.\n this.previousAgentIds = new Set(Object.keys(agents__unsafe_dev_only));\n\n // Subscribe to agent changes to track state for new agents\n this.subscribe({\n // Re-sync the memory store's runtime context whenever the runtime\n // connection status changes. The `/info` fetch sets the connection\n // status and `intelligence` together before firing this notification,\n // so this single hook covers both connection and intelligence changes.\n // Guarded so we never instantiate the store just to sync it.\n onRuntimeConnectionStatusChanged: () => {\n if (this._memoryStore) this.syncMemoryContext();\n },\n onAgentsChanged: ({ agents }) => {\n Object.values(agents).forEach((agent) => {\n if (agent.agentId) {\n this.stateManager.subscribeToAgent(agent);\n }\n });\n\n // Unregister thread stores for agents that have been removed.\n //\n // Critically, only unregister an agentId that was present in the\n // PREVIOUS agents snapshot AND is missing from the new one. Without\n // the \"previously had\" guard, the FIRST `onAgentsChanged({ agents: {} })`\n // delivered to a freshly-published core would tear out a thread store\n // that a consumer (e.g. useThreads) just registered — `core.agents`\n // is asynchronously populated and the empty-map notification fires\n // before the published agents are merged in.\n const currentAgentIds = new Set(Object.keys(agents));\n // Each iteration is wrapped so a throw on one id does not stall\n // cleanup for the rest of the set. Both registries' unregister\n // paths are idempotent, so re-attempts on the next\n // onAgentsChanged are safe.\n for (const agentId of Object.keys(this.threadStoreRegistry.getAll())) {\n if (\n this.previousAgentIds.has(agentId) &&\n !currentAgentIds.has(agentId)\n ) {\n try {\n this.threadStoreRegistry.unregister(agentId);\n } catch (err) {\n console.error(\n `CopilotKitCore.onAgentsChanged: threadStoreRegistry.unregister failed for \"${agentId}\":`,\n err,\n );\n }\n }\n }\n\n // Symmetric cleanup for state-manager subscriptions: any agentId\n // that disappeared from the registry (e.g. via `unregister()` from\n // a registerProxiedAgent caller) should release its StateManager\n // subscription. Without this, the subscription leaks — events from\n // a still-running observable on the removed agent would continue\n // to populate stateByRun/messageToRun for the dead id.\n for (const agentId of this.previousAgentIds) {\n if (!currentAgentIds.has(agentId)) {\n try {\n this.stateManager.unsubscribeFromAgent(agentId);\n } catch (err) {\n console.error(\n `CopilotKitCore.onAgentsChanged: stateManager.unsubscribeFromAgent failed for \"${agentId}\":`,\n err,\n );\n }\n }\n }\n\n this.previousAgentIds = currentAgentIds;\n },\n });\n }\n\n /**\n * Internal method used by delegate classes and subclasses to notify subscribers\n */\n protected async notifySubscribers(\n handler: (subscriber: CopilotKitCoreSubscriber) => void | Promise<void>,\n errorMessage: string,\n ): Promise<void> {\n await Promise.all(\n Array.from(this.subscribers).map(async (subscriber) => {\n try {\n await handler(subscriber);\n } catch (error) {\n console.error(errorMessage, error);\n }\n }),\n );\n }\n\n /**\n * Internal method used by delegate classes to emit errors\n */\n private async emitError({\n error,\n code,\n context = {},\n }: {\n error: Error;\n code: CopilotKitCoreErrorCode;\n context?: Record<string, any>;\n }): Promise<void> {\n await this.notifySubscribers(\n (subscriber) =>\n subscriber.onError?.({\n copilotkit: this,\n error,\n code,\n context,\n }),\n \"Subscriber onError error:\",\n );\n }\n\n /**\n * Log a message to the console and emit an error to subscribers.\n * Catches failures from `emitError` itself to prevent unhandled rejections.\n */\n private logAndEmitError(\n message: string,\n params: {\n error: Error;\n code: CopilotKitCoreErrorCode;\n context?: Record<string, any>;\n },\n logLevel: \"error\" | \"warn\" = \"error\",\n ): void {\n console[logLevel](message, params.error);\n this.emitError(params).catch((emitErr: unknown) => {\n console.error(message + \" — emitError itself failed:\", emitErr);\n });\n }\n\n /**\n * Snapshot accessors\n */\n get context(): Readonly<Record<string, ScopedContext>> {\n return this.contextStore.context;\n }\n\n get agents(): Readonly<Record<string, AbstractAgent>> {\n return this.agentRegistry.agents;\n }\n\n get tools(): Readonly<FrontendTool<any>[]> {\n return this.runHandler.tools;\n }\n\n get catalogComponents(): ReadonlyArray<CopilotKitCoreCatalogComponent> {\n return this.runHandler.catalogComponents;\n }\n\n get runtimeUrl(): string | undefined {\n return this.agentRegistry.runtimeUrl;\n }\n\n setRuntimeUrl(runtimeUrl: string | undefined): void {\n this.agentRegistry.setRuntimeUrl(runtimeUrl);\n }\n\n /**\n * Start the runtime `/info` connection if it has not been started yet.\n *\n * Intended to be driven from a host's commit-phase effect when the core was\n * constructed with {@link CopilotKitCoreConfig.deferInitialConnection}. Safe\n * to call repeatedly — it is a no-op once a connection is in progress or\n * settled, so a double-invoked mount effect (React StrictMode) collapses to a\n * single request. See #5801.\n */\n connect(): void {\n this.agentRegistry.connectRuntime();\n }\n\n get runtimeTransport(): CopilotRuntimeTransport {\n return this.agentRegistry.runtimeTransport;\n }\n\n setRuntimeTransport(runtimeTransport: CopilotRuntimeTransport): void {\n this.agentRegistry.setRuntimeTransport(runtimeTransport);\n }\n\n get runtimeVersion(): string | undefined {\n return this.agentRegistry.runtimeVersion;\n }\n\n get headers(): Readonly<Record<string, string>> {\n return this._headers;\n }\n\n get credentials(): RequestCredentials | undefined {\n return this._credentials;\n }\n\n get messageFilter(): CopilotKitMessageFilter | undefined {\n return this._messageFilter;\n }\n\n get properties(): Readonly<Record<string, unknown>> {\n return this._properties;\n }\n\n /**\n * Default throttle interval (ms) used by `subscribeToAgentWithOptions()`\n * when the caller does not specify an explicit `throttleMs`.\n * `undefined` means no default is configured; `0` means no throttling.\n */\n get defaultThrottleMs(): number | undefined {\n return this._defaultThrottleMs;\n }\n\n /**\n * Set the default throttle interval (ms) for `subscribeToAgentWithOptions()`.\n *\n * Accepts a non-negative finite number or `undefined` (to clear the\n * default). Invalid values (NaN, Infinity, negative) are logged as\n * errors and ignored — the previous valid value is preserved.\n */\n setDefaultThrottleMs(value: number | undefined): void {\n if (value !== undefined && (!Number.isFinite(value) || value < 0)) {\n this.logAndEmitError(\n `CopilotKitCore.setDefaultThrottleMs: value must be a non-negative finite number or undefined, ` +\n `got ${value}. Keeping current value (${this._defaultThrottleMs}).`,\n {\n error: new Error(\n `setDefaultThrottleMs: invalid value (${value}), keeping current value (${this._defaultThrottleMs})`,\n ),\n code: CopilotKitCoreErrorCode.SUBSCRIBER_CALLBACK_FAILED,\n context: { value, currentValue: this._defaultThrottleMs },\n },\n );\n return;\n }\n this._defaultThrottleMs = value;\n }\n\n get debug(): DebugConfig | undefined {\n return this._debug;\n }\n\n setDebug(debug: DebugConfig | undefined): void {\n this._debug = debug;\n }\n\n get runtimeConnectionStatus(): CopilotKitCoreRuntimeConnectionStatus {\n return this.agentRegistry.runtimeConnectionStatus;\n }\n\n get ɵruntimeFetch(): typeof fetch {\n return this.agentRegistry.createRuntimeFetch();\n }\n\n get audioFileTranscriptionEnabled(): boolean {\n return this.agentRegistry.audioFileTranscriptionEnabled;\n }\n\n get runtimeMode(): RuntimeMode {\n return this.agentRegistry.runtimeMode;\n }\n\n get intelligence(): IntelligenceRuntimeInfo | undefined {\n return this.agentRegistry.intelligence;\n }\n\n get threadEndpoints(): ThreadEndpointRuntimeInfo | undefined {\n return this.agentRegistry.threadEndpoints;\n }\n\n get suggestions(): boolean | undefined {\n return this.agentRegistry.suggestions;\n }\n\n /** Whether the connected Runtime exposes debug-authorized Learning data. */\n get inspectorLearning(): boolean {\n return this.agentRegistry.inspectorLearning;\n }\n\n /** Trusted, optional metadata advertised by the connected runtime. */\n get inspectorMetadata(): InspectorMetadataV1 | undefined {\n return this.agentRegistry.inspectorMetadata;\n }\n\n /** Refresh trusted inspector metadata without reconnecting runtime agents. */\n async refreshInspectorMetadata(): Promise<void> {\n await this.agentRegistry.refreshInspectorMetadata();\n }\n\n get a2uiEnabled(): boolean {\n return this.agentRegistry.a2uiEnabled;\n }\n\n /**\n * Agent ids the runtime applies A2UI to. `undefined` means A2UI applies to\n * every agent (or is disabled — check `a2uiEnabled`).\n */\n get a2uiAgents(): string[] | undefined {\n return this.agentRegistry.a2uiAgents;\n }\n\n get openGenerativeUIEnabled(): boolean {\n return this.agentRegistry.openGenerativeUIEnabled;\n }\n\n get licenseStatus(): RuntimeLicenseStatus | undefined {\n return this.agentRegistry.licenseStatus;\n }\n\n /** Structured Runtime entitlement authority advertised by `/info`. */\n get runtimeEntitlements(): RuntimeEntitlementResponse | undefined {\n return this.agentRegistry.runtimeEntitlements;\n }\n\n /** Whether Core still has a bounded Runtime entitlement retry to settle. */\n get runtimeEntitlementRetryPending(): boolean {\n return this.agentRegistry.runtimeEntitlementRetryPending;\n }\n\n get telemetryDisabled(): boolean {\n return this.agentRegistry.telemetryDisabled;\n }\n\n /**\n * Configuration updates\n */\n /**\n * Replace the headers sent with every runtime request.\n *\n * This is an overwrite, not a merge — the supplied object becomes the\n * complete header set. Entries whose value is `null` or `undefined` are\n * dropped, which is how you clear a header (e.g. removing `Authorization`\n * on logout) without leaving an empty-string value behind:\n *\n * ```ts\n * copilotkit.setHeaders({\n * ...copilotkit.headers,\n * Authorization: token ? `Bearer ${token}` : null,\n * });\n * ```\n *\n * The resulting header set is also re-applied to every agent in the registry\n * and `onHeadersChanged` subscribers are notified. These headers are merged\n * ON TOP of the headers each `HttpAgent` was constructed with, so per-agent\n * headers (e.g. an `Authorization` for a self-hosted backend) are preserved;\n * on a key conflict the core-level value wins.\n *\n * Because the agent's construction-time headers form the merge baseline, this\n * method can override a per-agent header but cannot REMOVE one: clearing a\n * core key here only drops the core-level override, after which the agent's\n * own value (if any) re-surfaces. To change a header an agent was constructed\n * with, set it at the provider/core level instead of on the agent, or update\n * it on the agent directly. The clear-on-logout pattern above is for\n * core-level headers.\n */\n setHeaders(headers: Record<string, string | null | undefined>): void {\n this._headers = normalizeHeaders(headers);\n if (this._memoryStore) this.syncMemoryContext();\n this.agentRegistry.applyHeadersToAgents(\n this.agentRegistry.agents as Record<string, AbstractAgent>,\n );\n this.agentRegistry.handleHeadersChanged();\n void this.notifySubscribers(\n (subscriber) =>\n subscriber.onHeadersChanged?.({\n copilotkit: this,\n headers: this.headers,\n }),\n \"Subscriber onHeadersChanged error:\",\n );\n }\n\n setCredentials(credentials: RequestCredentials | undefined): void {\n this._credentials = credentials;\n this.agentRegistry.applyCredentialsToAgents(\n this.agentRegistry.agents as Record<string, AbstractAgent>,\n );\n this.agentRegistry.handleCredentialsChanged();\n }\n\n /**\n * Replace the message filter applied to every runtime agent.\n *\n * Applies to agents already discovered as well as ones discovered later, so\n * a filter set before `/info` lands is not lost. Pass `undefined` to go back\n * to sending the full thread.\n */\n setMessageFilter(messageFilter: CopilotKitMessageFilter | undefined): void {\n this._messageFilter = messageFilter;\n this.agentRegistry.applyMessageFilterToAgents(\n this.agentRegistry.agents as Record<string, AbstractAgent>,\n );\n }\n\n setProperties(properties: Record<string, unknown>): void {\n this._properties = properties;\n void this.notifySubscribers(\n (subscriber) =>\n subscriber.onPropertiesChanged?.({\n copilotkit: this,\n properties: this.properties,\n }),\n \"Subscriber onPropertiesChanged error:\",\n );\n }\n\n /**\n * Agent management (delegated to AgentRegistry)\n */\n setAgents__unsafe_dev_only(agents: Record<string, AbstractAgent>): void {\n this.agentRegistry.setAgents__unsafe_dev_only(agents);\n }\n\n addAgent__unsafe_dev_only(params: CopilotKitCoreAddAgentParams): void {\n this.agentRegistry.addAgent__unsafe_dev_only(params);\n }\n\n removeAgent__unsafe_dev_only(id: string): void {\n this.agentRegistry.removeAgent__unsafe_dev_only(id);\n }\n\n /**\n * Register a proxied agent against an existing runtime agent. The proxy is\n * exposed under `agentId` (local registry id) and routes outbound runtime\n * requests to `runtimeAgentId`. Throws if `agentId` is already taken.\n *\n * Returns the minted proxy and an `unregister` handle for cleanup.\n *\n * Use this to mount multiple frontend agents against a single runtime\n * agent (e.g. one per chat window) without implicit per-thread cloning.\n *\n * @example\n * const { agent, unregister } = copilotkit.registerProxiedAgent({\n * agentId: \"chat-1\",\n * runtimeAgentId: \"default\",\n * });\n * // ... <CopilotChat agentId=\"chat-1\" />\n * // on cleanup:\n * unregister();\n */\n registerProxiedAgent(\n params: CopilotKitCoreRegisterProxiedAgentParams,\n ): CopilotKitCoreRegisterProxiedAgentResult {\n return this.agentRegistry.registerProxiedAgent(params);\n }\n\n getAgent(id: string): AbstractAgent | undefined {\n return this.agentRegistry.getAgent(id);\n }\n\n /**\n * Re-apply the current headers to a single agent (delegated to\n * AgentRegistry). Core headers are merged on top of the agent's own\n * construction-time headers rather than replacing them, so headers\n * configured directly on an `HttpAgent` (e.g. an `Authorization` for a\n * self-hosted backend) survive header updates instead of being silently\n * dropped (see #5635). On a key conflict the core-level value wins.\n *\n * The merge baseline is the agent's headers as captured the first time the\n * agent is applied (at registration), so the way to change headers\n * afterwards is `setHeaders` (which re-applies to every agent), not mutating\n * `agent.headers` directly — a direct mutation is overwritten on the next\n * re-apply.\n */\n applyHeadersToAgent(agent: AbstractAgent): void {\n this.agentRegistry.applyHeadersToAgent(agent);\n }\n\n /**\n * Context management (delegated to ContextStore).\n * Pass `agentIds` to restrict the entry to runs of specific agents;\n * omit it for context every agent should receive.\n */\n addContext(context: ScopedContext): string {\n return this.contextStore.addContext(context);\n }\n\n removeContext(id: string): void {\n this.contextStore.removeContext(id);\n }\n\n /**\n * Build the context array for a run of the given agent, dropping entries\n * scoped to other agents and stripping the scoping metadata.\n */\n getContextForAgent(agentId?: string): Context[] {\n return this.contextStore.getContextForAgent(agentId);\n }\n\n /**\n * Thread store registry (delegated to ThreadStoreRegistry)\n */\n registerThreadStore(agentId: string, store: ɵThreadStore): void {\n this.threadStoreRegistry.register(agentId, store);\n }\n\n unregisterThreadStore(agentId: string): void {\n this.threadStoreRegistry.unregister(agentId);\n }\n\n getThreadStore(agentId: string): ɵThreadStore | undefined {\n return this.threadStoreRegistry.get(agentId);\n }\n\n getThreadStores(): Readonly<Record<string, ɵThreadStore>> {\n return this.threadStoreRegistry.getAll();\n }\n\n /**\n * Returns the single core-owned, user-scoped memory store, creating and\n * starting it on first access. Unlike thread stores, memory is not scoped per\n * agent: there is exactly one store whose runtime context the core wires\n * itself (see `syncMemoryContext`), so consumers (e.g. a `useMemories`\n * binding) just read this store rather than registering one.\n */\n getMemoryStore(): ɵMemoryStore {\n return this.ensureMemoryStore();\n }\n\n /**\n * Lazily creates, starts, and context-syncs the core-owned memory store on\n * first access, then returns it. Subsequent calls return the existing store.\n * The store uses the Core Runtime fetch so REST and single-route transports\n * share the same resource behavior. Its Runtime context is synced at once.\n */\n private ensureMemoryStore(): ɵMemoryStore {\n if (!this._memoryStore) {\n this._memoryStore = ɵcreateMemoryStore({\n fetch: this.ɵruntimeFetch,\n });\n this._memoryStore.start();\n this.syncMemoryContext();\n }\n return this._memoryStore;\n }\n\n /**\n * Pushes the current runtime wiring into the memory store. When the runtime\n * is connected and both the intelligence WebSocket URL and runtime URL are\n * available, the store receives a context (runtime URL, WebSocket URL, and a\n * copy of the current headers); otherwise its context is cleared. No-op when\n * the store has not been created yet.\n */\n private syncMemoryContext(): void {\n if (!this._memoryStore) return;\n if (\n this.runtimeConnectionStatus ===\n CopilotKitCoreRuntimeConnectionStatus.Connected &&\n this.intelligence?.wsUrl &&\n this.runtimeUrl\n ) {\n this._memoryStore.setContext({\n runtimeUrl: this.runtimeUrl,\n wsUrl: this.intelligence.wsUrl,\n headers: { ...this.headers },\n });\n } else {\n this._memoryStore.setContext(null);\n }\n }\n\n /**\n * Suggestions management (delegated to SuggestionEngine)\n */\n addSuggestionsConfig(config: SuggestionsConfig): string {\n return this.suggestionEngine.addSuggestionsConfig(config);\n }\n\n removeSuggestionsConfig(id: string): void {\n this.suggestionEngine.removeSuggestionsConfig(id);\n }\n\n reloadSuggestions(agentId: string): void {\n this.suggestionEngine.reloadSuggestions(agentId);\n }\n\n clearSuggestions(agentId: string): void {\n this.suggestionEngine.clearSuggestions(agentId);\n }\n\n getSuggestions(agentId: string): CopilotKitCoreGetSuggestionsResult {\n return this.suggestionEngine.getSuggestions(agentId);\n }\n\n /**\n * Tool management (delegated to RunHandler)\n */\n addTool<T extends Record<string, unknown> = Record<string, unknown>>(\n tool: FrontendTool<T>,\n ): void {\n this.runHandler.addTool(tool);\n }\n\n removeTool(id: string, agentId?: string): void {\n this.runHandler.removeTool(id, agentId);\n }\n\n getTool(params: CopilotKitCoreGetToolParams): FrontendTool<any> | undefined {\n return this.runHandler.getTool(params);\n }\n\n setTools(tools: FrontendTool<any>[]): void {\n this.runHandler.setTools(tools);\n }\n\n /**\n * Enable/disable a registered frontend tool at runtime without unregistering\n * it (Inspector \"Capabilities\" tool). A disabled tool is omitted from the\n * tool list sent to the agent on the next run. The override is keyed by name\n * (+ optional agentId) and survives the tool being re-registered.\n */\n setToolEnabled(name: string, enabled: boolean, agentId?: string): void {\n this.runHandler.setToolEnabled(name, enabled, agentId);\n }\n\n /** Whether a registered tool is currently enabled (defaults true). */\n isToolEnabled(name: string, agentId?: string): boolean {\n return this.runHandler.isToolEnabled(name, agentId);\n }\n\n /**\n * A2UI catalog component management (delegated to RunHandler).\n * Registers the full component list and controls per-component enablement.\n */\n setCatalogComponents(components: CopilotKitCoreCatalogComponent[]): void {\n this.runHandler.setCatalogComponents(components);\n void this.notifySubscribers(\n (subscriber) =>\n subscriber.onCatalogComponentsChanged?.({\n copilotkit: this,\n catalogComponents: this.runHandler.catalogComponents,\n }),\n \"Subscriber onCatalogComponentsChanged error:\",\n );\n }\n\n setCatalogComponentEnabled(name: string, enabled: boolean): void {\n this.runHandler.setCatalogComponentEnabled(name, enabled);\n void this.notifySubscribers(\n (subscriber) =>\n subscriber.onCatalogComponentsChanged?.({\n copilotkit: this,\n catalogComponents: this.runHandler.catalogComponents,\n }),\n \"Subscriber onCatalogComponentsChanged error:\",\n );\n }\n\n isCatalogComponentEnabled(name: string): boolean {\n return this.runHandler.isCatalogComponentEnabled(name);\n }\n\n /**\n * Subscription lifecycle\n */\n subscribe(subscriber: CopilotKitCoreSubscriber): CopilotKitCoreSubscription {\n this.subscribers.add(subscriber);\n\n // Return subscription with unsubscribe method\n return {\n unsubscribe: () => {\n this.subscribers.delete(subscriber);\n },\n };\n }\n\n /**\n * Subscribe to an agent's notification and lifecycle events with\n * optional configuration (e.g. throttling).\n *\n * Wraps every callback with error protection (`safeCall`) and applies\n * the options before delegating to `agent.subscribe()`.\n *\n * See {@link SubscribeToAgentSubscriber} for the accepted callback subset\n * and the rationale for excluding AG-UI event handlers.\n */\n subscribeToAgentWithOptions(\n agent: AbstractAgent,\n subscriber: SubscribeToAgentSubscriber,\n options?: SubscribeToAgentOptions,\n ): CopilotKitCoreSubscription {\n const resolved = options?.throttleMs ?? this._defaultThrottleMs ?? 0;\n\n let effectiveMs = 0;\n if (!Number.isFinite(resolved) || resolved < 0) {\n const source =\n options?.throttleMs !== undefined ? \"throttleMs\" : \"defaultThrottleMs\";\n this.logAndEmitError(\n `CopilotKitCore.subscribeToAgentWithOptions: ${source} must be a non-negative finite number, ` +\n `got ${resolved}. Falling back to unthrottled.`,\n {\n error: new Error(\n `subscribeToAgentWithOptions: invalid ${source} (${resolved}), falling back to unthrottled`,\n ),\n code: CopilotKitCoreErrorCode.SUBSCRIBER_CALLBACK_FAILED,\n context: { agentId: agent.agentId, source, value: resolved },\n },\n );\n } else {\n effectiveMs = resolved;\n }\n\n const agentLabel = agent.agentId || \"(unknown agent)\";\n\n // Wraps a callback so that synchronous throws and async rejections are\n // caught, logged, and emitted — preventing one failing callback from\n // corrupting the agent's notification loop.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const safeCall = <F extends (...args: any[]) => any>(\n label: string,\n fn: F,\n ...args: Parameters<F>\n ): any => {\n const reportError = (err: unknown, verb: string) => {\n this.logAndEmitError(\n `CopilotKitCore.subscribeToAgentWithOptions[${agentLabel}]: ${label} callback ${verb}:`,\n {\n error: err instanceof Error ? err : new Error(String(err)),\n code: CopilotKitCoreErrorCode.SUBSCRIBER_CALLBACK_FAILED,\n context: { agentId: agent.agentId, callback: label },\n },\n );\n };\n try {\n const result = fn(...args);\n if (result instanceof Promise) {\n return result.catch((err: unknown) => {\n reportError(err, \"rejected\");\n });\n }\n return result;\n } catch (err) {\n reportError(err, \"threw\");\n }\n };\n\n const guardAll = (\n sub: SubscribeToAgentSubscriber,\n ): SubscribeToAgentSubscriber => {\n const guarded: SubscribeToAgentSubscriber = {};\n if (sub.onMessagesChanged) {\n const fn = sub.onMessagesChanged;\n guarded.onMessagesChanged = (params) =>\n safeCall(\"onMessagesChanged\", fn, params);\n }\n if (sub.onStateChanged) {\n const fn = sub.onStateChanged;\n guarded.onStateChanged = (params) =>\n safeCall(\"onStateChanged\", fn, params);\n }\n if (sub.onRunInitialized) {\n const fn = sub.onRunInitialized;\n guarded.onRunInitialized = (params) =>\n safeCall(\"onRunInitialized\", fn, params);\n }\n if (sub.onRunFinalized) {\n const fn = sub.onRunFinalized;\n guarded.onRunFinalized = (params) =>\n safeCall(\"onRunFinalized\", fn, params);\n }\n if (sub.onRunFailed) {\n const fn = sub.onRunFailed;\n guarded.onRunFailed = (params) => safeCall(\"onRunFailed\", fn, params);\n }\n if (sub.onRunErrorEvent) {\n const fn = sub.onRunErrorEvent;\n guarded.onRunErrorEvent = (params) =>\n safeCall(\"onRunErrorEvent\", fn, params);\n }\n return guarded;\n };\n\n // Warn about unsupported keys so JS / `as any` consumers get diagnostics.\n for (const key of Object.keys(subscriber)) {\n if (\n typeof (subscriber as Record<string, unknown>)[key] === \"function\" &&\n !(ALLOWED_KEYS as ReadonlySet<string>).has(key)\n ) {\n const message =\n `CopilotKitCore.subscribeToAgentWithOptions[${agentLabel}]: callback \"${key}\" is not supported ` +\n `and was dropped. Supported callbacks: ${Array.from(ALLOWED_KEYS).join(\", \")}. ` +\n `Use agent.subscribe() directly for event handlers and per-item notifications.`;\n this.logAndEmitError(\n message,\n {\n error: new Error(message),\n code: CopilotKitCoreErrorCode.SUBSCRIBER_CALLBACK_FAILED,\n context: { agentId: agent.agentId, droppedCallback: key },\n },\n \"warn\",\n );\n }\n }\n\n // No throttle — guard callbacks and subscribe directly.\n if (effectiveMs <= 0) {\n const subscription = agent.subscribe(guardAll(subscriber));\n return { unsubscribe: () => subscription.unsubscribe() };\n }\n\n // Throttled path: lifecycle callbacks fire immediately; onMessagesChanged\n // and onStateChanged share a single Throttler that flushes the latest\n // params for both channels.\n let active = true;\n let latestMessagesParams:\n | Parameters<\n NonNullable<SubscribeToAgentSubscriber[\"onMessagesChanged\"]>\n >[0]\n | null = null;\n let latestStateParams:\n | Parameters<NonNullable<SubscribeToAgentSubscriber[\"onStateChanged\"]>>[0]\n | null = null;\n\n const flushPending = () => {\n if (active && subscriber.onMessagesChanged && latestMessagesParams) {\n const params = latestMessagesParams;\n latestMessagesParams = null;\n safeCall(\"onMessagesChanged\", subscriber.onMessagesChanged, params);\n }\n if (active && subscriber.onStateChanged && latestStateParams) {\n const params = latestStateParams;\n latestStateParams = null;\n safeCall(\"onStateChanged\", subscriber.onStateChanged, params);\n }\n };\n\n const throttler = new Throttler(flushPending, {\n wait: effectiveMs,\n leading: true,\n trailing: true,\n });\n\n // Lifecycle callbacks are guarded but never throttled.\n const lifecycleOnly: SubscribeToAgentSubscriber = {};\n if (subscriber.onRunInitialized)\n lifecycleOnly.onRunInitialized = subscriber.onRunInitialized;\n if (subscriber.onRunFinalized)\n lifecycleOnly.onRunFinalized = subscriber.onRunFinalized;\n if (subscriber.onRunFailed)\n lifecycleOnly.onRunFailed = subscriber.onRunFailed;\n if (subscriber.onRunErrorEvent)\n lifecycleOnly.onRunErrorEvent = subscriber.onRunErrorEvent;\n\n const wrappedSubscriber: SubscribeToAgentSubscriber =\n guardAll(lifecycleOnly);\n\n if (subscriber.onMessagesChanged) {\n wrappedSubscriber.onMessagesChanged = (params) => {\n latestMessagesParams = params;\n throttler.maybeExecute();\n };\n }\n\n if (subscriber.onStateChanged) {\n wrappedSubscriber.onStateChanged = (params) => {\n latestStateParams = params;\n throttler.maybeExecute();\n };\n }\n\n const subscription = agent.subscribe(wrappedSubscriber);\n\n return {\n unsubscribe: () => {\n active = false;\n throttler.cancel();\n subscription.unsubscribe();\n },\n };\n }\n\n /**\n * Agent connectivity (delegated to RunHandler)\n */\n async connectAgent(\n params: CopilotKitCoreConnectAgentParams,\n ): Promise<import(\"@ag-ui/client\").RunAgentResult> {\n return this.runHandler.connectAgent(params);\n }\n\n stopAgent(params: CopilotKitCoreStopAgentParams): void {\n this.runHandler.abortCurrentRun(params.agent);\n params.agent.abortRun();\n }\n\n async runAgent(\n params: CopilotKitCoreRunAgentParams,\n ): Promise<import(\"@ag-ui/client\").RunAgentResult> {\n return this.runHandler.runAgent(params);\n }\n\n /**\n * Programmatically execute a registered frontend tool without going through an LLM turn.\n * The handler runs, render components show up in the UI, and both the tool call and\n * result messages are added to `agent.messages`.\n */\n async runTool(\n params: CopilotKitCoreRunToolParams,\n ): Promise<CopilotKitCoreRunToolResult> {\n return this.runHandler.runTool(params);\n }\n\n /**\n * State management (delegated to StateManager)\n */\n getStateByRun(\n agentId: string,\n threadId: string,\n runId: string,\n ): State | undefined {\n return this.stateManager.getStateByRun(agentId, threadId, runId);\n }\n\n getRunIdForMessage(\n agentId: string,\n threadId: string,\n messageId: string,\n ): string | undefined {\n return this.stateManager.getRunIdForMessage(agentId, threadId, messageId);\n }\n\n getRawEventForMessage(\n agentId: string,\n threadId: string,\n messageId: string,\n ): unknown {\n return this.stateManager.getRawEventForMessage(\n agentId,\n threadId,\n messageId,\n );\n }\n\n getRunIdsForThread(agentId: string, threadId: string): string[] {\n return this.stateManager.getRunIdsForThread(agentId, threadId);\n }\n\n /**\n * Internal method used by RunHandler to build frontend tools\n */\n private buildFrontendTools(agentId?: string): import(\"@ag-ui/client\").Tool[] {\n return this.runHandler.buildFrontendTools(agentId);\n }\n\n /**\n * Called before each follow-up agent run (after tool execution).\n *\n * When a frontend tool handler calls framework state setters (e.g. React's\n * setState), those updates are batched and deferred — they do not take effect\n * until the framework's scheduler runs (React uses MessageChannel).\n * useAgentContext registers context via useLayoutEffect, which runs\n * synchronously after React commits that deferred batch.\n *\n * Without yielding here, the follow-up runAgent reads the context store\n * synchronously while the deferred updates are still pending, producing stale\n * context for the next agent turn.\n *\n * Override in framework-specific subclasses to yield to the framework\n * scheduler before the follow-up run. The base implementation is a no-op\n * because non-React environments have no deferred state to flush.\n */\n async waitForPendingFrameworkUpdates(): Promise<void> {}\n}\n","import type { AbstractAgent, ToolCall } from \"@ag-ui/client\";\nimport type {\n InspectorMetadataV1,\n IntelligenceRuntimeInfo,\n RuntimeMode,\n RuntimeLicenseStatus,\n ThreadEndpointRuntimeInfo,\n} from \"@copilotkit/shared\";\nimport type { StandardSchemaV1 } from \"@copilotkit/shared\";\n\n/**\n * Status of a tool call execution\n */\nexport enum ToolCallStatus {\n InProgress = \"inProgress\",\n Executing = \"executing\",\n Complete = \"complete\",\n}\n\nexport type CopilotRuntimeTransport = \"rest\" | \"single\" | \"auto\";\nexport type {\n InspectorMetadataV1,\n RuntimeMode,\n IntelligenceRuntimeInfo,\n RuntimeLicenseStatus,\n ThreadEndpointRuntimeInfo,\n};\n\n/**\n * Context passed to a frontend tool handler\n */\nexport type FrontendToolHandlerContext = {\n toolCall: ToolCall;\n /**\n * The agent that invoked the tool. Absent when the tool is invoked through\n * the WebMCP browser API (`document.modelContext`), which has no agent.\n */\n agent?: AbstractAgent;\n /** Aborted when `stopAgent()` is called. Handlers can check `signal.aborted`\n * or pass the signal to fetch/setTimeout to cooperatively cancel. */\n signal?: AbortSignal;\n};\n\n/**\n * Annotations for a WebMCP tool, passed through to\n * `document.modelContext.registerTool`. Mirrors the WebMCP spec's tool\n * annotations. These are hints for browser agents only — they do not enforce\n * any policy on their own.\n */\nexport type WebMCPToolAnnotations = {\n /**\n * Hint that the tool does not modify state. Defaults to false.\n * Set it for read-only tools (search, status lookup, ...).\n */\n readOnlyHint?: boolean;\n /**\n * Hint that the tool's output may contain untrusted content\n * (e.g. user-generated or external content). Defaults to false.\n */\n untrustedContentHint?: boolean;\n};\n\n/**\n * WebMCP registration options for a frontend tool.\n */\nexport type WebMCPToolConfig = {\n /** Hints that tell browser agents how the tool behaves. */\n annotations?: WebMCPToolAnnotations;\n};\n\nexport type FrontendTool<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = {\n /**\n * @internal Classifies local execution. Omitted means an ordinary frontend\n * tool. Only human-in-the-loop handlers may be restored from history replay.\n * This field is not sent to the agent as part of the tool schema.\n */\n type?: \"frontend\" | \"human-in-the-loop\";\n name: string;\n description?: string;\n parameters?: StandardSchemaV1<any, T>;\n handler?: (args: T, context: FrontendToolHandlerContext) => Promise<unknown>;\n followUp?: boolean;\n /**\n * Optional agent ID to constrain this tool to a specific agent.\n * If specified, this tool will only be available to the specified agent.\n */\n agentId?: string;\n /**\n * Whether this tool is available to the agent.\n * Set to false to hide the tool from the agent without unregistering it.\n * Defaults to true when not specified.\n */\n available?: boolean;\n /**\n * Also expose this tool to browser agents through the WebMCP API\n * (`document.modelContext`) while keeping the normal agent registration.\n *\n * - `true` — register with default annotations.\n * - `{ annotations }` — register with the given WebMCP annotations.\n * - `false` / `undefined` — do not register.\n *\n * The tool's `handler` runs when a browser agent calls the tool; the handler\n * context then has no `agent`. No-op in environments without WebMCP support\n * (e.g. React Native, or browsers without the API enabled).\n */\n webmcp?: boolean | WebMCPToolConfig;\n};\n\nexport type Suggestion = {\n title: string;\n message: string;\n /** Indicates whether this suggestion is still being generated. */\n isLoading: boolean;\n /** Optional CSS class name applied to the suggestion pill. */\n className?: string;\n};\n\nexport type SuggestionAvailability =\n | \"before-first-message\"\n | \"after-first-message\"\n | \"always\"\n | \"disabled\";\n\nexport type DynamicSuggestionsConfig = {\n /**\n * A prompt or instructions for the GPT to generate suggestions.\n */\n instructions: string;\n /**\n * The minimum number of suggestions to generate. Defaults to `1`.\n * @default 1\n */\n minSuggestions?: number;\n /**\n * The maximum number of suggestions to generate. Defaults to `3`.\n * @default 1\n */\n maxSuggestions?: number;\n\n /**\n * When the suggestions are available. Defaults to \"after-first-message\".\n */\n available?: SuggestionAvailability;\n\n /**\n * The agent ID of the provider of the suggestions. Defaults to `\"default\"`.\n */\n providerAgentId?: string;\n\n /**\n * The agent ID of the consumer of the suggestions. Defaults to `\"*\"` (all agents).\n */\n consumerAgentId?: string;\n};\n\nexport type StaticSuggestionsConfig = {\n /**\n * The suggestions to display.\n */\n suggestions: Omit<Suggestion, \"isLoading\">[];\n\n /**\n * When the suggestions are available. Defaults to \"before-first-message\".\n */\n available?: SuggestionAvailability;\n\n /**\n * The agent ID of the consumer of the suggestions. Defaults to `\"*\"` (all agents).\n */\n consumerAgentId?: string;\n};\n\nexport type SuggestionsConfig =\n | DynamicSuggestionsConfig\n | StaticSuggestionsConfig;\n","export function completePartialMarkdown(input: string): string {\n let s = input;\n\n // Handle code fences first - use FIRST unmatched fence for proper nesting\n const fenceMatches = Array.from(s.matchAll(/^(\\s*)(`{3,}|~{3,})/gm));\n if (fenceMatches.length % 2 === 1) {\n const [, indent, fence] = fenceMatches[0]!;\n s += `\\n${indent}${fence}`;\n }\n\n // Identify incomplete links at the end and close them\n const incompleteLinkMatch = s.match(/\\[([^\\]]*)\\]\\(([^)]*)$/);\n if (incompleteLinkMatch) {\n s += \")\";\n }\n\n // State-based parsing\n interface OpenElement {\n type: string;\n marker: string;\n position: number;\n }\n\n const openElements: OpenElement[] = [];\n const chars = Array.from(s);\n\n // First pass: identify code block boundaries and inline code to avoid processing their content\n const codeBlockRanges: Array<{ start: number; end: number }> = [];\n const inlineCodeRanges: Array<{ start: number; end: number }> = [];\n\n // Find code block ranges\n let tempCodeFenceCount = 0;\n let currentCodeBlockStart = -1;\n\n for (let i = 0; i < chars.length; i++) {\n if (i === 0 || chars[i - 1] === \"\\n\") {\n const lineMatch = s.substring(i).match(/^(\\s*)(`{3,}|~{3,})/);\n if (lineMatch) {\n tempCodeFenceCount++;\n if (tempCodeFenceCount % 2 === 1) {\n currentCodeBlockStart = i;\n } else if (currentCodeBlockStart !== -1) {\n codeBlockRanges.push({\n start: currentCodeBlockStart,\n end: i + lineMatch[0].length,\n });\n currentCodeBlockStart = -1;\n }\n i += lineMatch[0].length - 1;\n }\n }\n }\n\n // Find inline code ranges\n for (let i = 0; i < chars.length; i++) {\n if (chars[i] === \"`\") {\n // Check if escaped\n let backslashCount = 0;\n for (let j = i - 1; j >= 0 && chars[j] === \"\\\\\"; j--) {\n backslashCount++;\n }\n if (backslashCount % 2 === 0) {\n // Not escaped - find the closing backtick\n for (let j = i + 1; j < chars.length; j++) {\n if (chars[j] === \"`\") {\n let closingBackslashCount = 0;\n for (let k = j - 1; k >= 0 && chars[k] === \"\\\\\"; k--) {\n closingBackslashCount++;\n }\n if (closingBackslashCount % 2 === 0) {\n inlineCodeRanges.push({ start: i, end: j + 1 });\n i = j;\n break;\n }\n }\n }\n }\n }\n }\n\n // Helper function to check if position is in code\n const isInCode = (pos: number): boolean => {\n return (\n codeBlockRanges.some((range) => pos >= range.start && pos < range.end) ||\n inlineCodeRanges.some((range) => pos >= range.start && pos < range.end)\n );\n };\n\n // Second pass: process markdown elements, skipping code regions\n for (let i = 0; i < chars.length; i++) {\n const char = chars[i];\n const nextChar = chars[i + 1];\n const prevChar = chars[i - 1];\n\n if (isInCode(i)) {\n continue;\n }\n\n // Handle brackets (but not if they're part of already-complete links)\n if (char === \"[\") {\n // Check if this is part of a complete link [text](url)\n let isCompleteLink = false;\n let bracketDepth = 1;\n let j = i + 1;\n\n // Find the matching ]\n while (j < chars.length && bracketDepth > 0) {\n if (chars[j] === \"[\" && !isInCode(j)) bracketDepth++;\n if (chars[j] === \"]\" && !isInCode(j)) bracketDepth--;\n j++;\n }\n\n // Check if followed by (\n if (bracketDepth === 0 && chars[j] === \"(\") {\n // Find the closing )\n let parenDepth = 1;\n j++;\n while (j < chars.length && parenDepth > 0) {\n if (chars[j] === \"(\" && !isInCode(j)) parenDepth++;\n if (chars[j] === \")\" && !isInCode(j)) parenDepth--;\n j++;\n }\n if (parenDepth === 0) {\n isCompleteLink = true;\n i = j - 1;\n continue;\n }\n }\n\n // This is a standalone bracket, treat as markdown\n if (!isCompleteLink) {\n const existingIndex = openElements.findIndex(\n (el) => el.type === \"bracket\",\n );\n if (existingIndex !== -1) {\n openElements.splice(existingIndex, 1);\n } else {\n openElements.push({ type: \"bracket\", marker: \"[\", position: i });\n }\n }\n }\n\n // Handle double emphasis first (**, __, ~~) - these take precedence\n else if (char === \"*\" && nextChar === \"*\") {\n const existingIndex = openElements.findIndex(\n (el) => el.type === \"bold_star\",\n );\n if (existingIndex !== -1) {\n openElements.splice(existingIndex, 1);\n } else {\n openElements.push({ type: \"bold_star\", marker: \"**\", position: i });\n }\n i++; // Skip next character\n } else if (char === \"_\" && nextChar === \"_\") {\n const existingIndex = openElements.findIndex(\n (el) => el.type === \"bold_underscore\",\n );\n if (existingIndex !== -1) {\n openElements.splice(existingIndex, 1);\n } else {\n openElements.push({\n type: \"bold_underscore\",\n marker: \"__\",\n position: i,\n });\n }\n i++; // Skip next character\n } else if (char === \"~\" && nextChar === \"~\") {\n const existingIndex = openElements.findIndex(\n (el) => el.type === \"strike\",\n );\n if (existingIndex !== -1) {\n openElements.splice(existingIndex, 1);\n } else {\n openElements.push({ type: \"strike\", marker: \"~~\", position: i });\n }\n i++; // Skip next character\n }\n\n // Handle single emphasis (*, _) - only if not part of double\n else if (char === \"*\" && prevChar !== \"*\" && nextChar !== \"*\") {\n const existingIndex = openElements.findIndex(\n (el) => el.type === \"italic_star\",\n );\n if (existingIndex !== -1) {\n openElements.splice(existingIndex, 1);\n } else {\n openElements.push({ type: \"italic_star\", marker: \"*\", position: i });\n }\n } else if (char === \"_\" && prevChar !== \"_\" && nextChar !== \"_\") {\n const existingIndex = openElements.findIndex(\n (el) => el.type === \"italic_underscore\",\n );\n if (existingIndex !== -1) {\n openElements.splice(existingIndex, 1);\n } else {\n openElements.push({\n type: \"italic_underscore\",\n marker: \"_\",\n position: i,\n });\n }\n }\n }\n\n // Handle remaining unmatched backticks (outside of inline code ranges)\n let backtickCount = 0;\n for (let i = 0; i < chars.length; i++) {\n if (chars[i] === \"`\" && !isInCode(i)) {\n backtickCount++;\n }\n }\n if (backtickCount % 2 === 1) {\n s += \"`\";\n }\n\n // Close remaining open elements in reverse order (LIFO stack semantics)\n openElements.sort((a, b) => b.position - a.position);\n\n const closers = openElements.map((el) => {\n switch (el.type) {\n case \"bracket\":\n return \"]\";\n case \"bold_star\":\n return \"**\";\n case \"bold_underscore\":\n return \"__\";\n case \"strike\":\n return \"~~\";\n case \"italic_star\":\n return \"*\";\n case \"italic_underscore\":\n return \"_\";\n default:\n return \"\";\n }\n });\n\n let result = s + closers.join(\"\");\n\n // Handle parentheses ONLY if not inside code\n const finalFenceMatches = Array.from(\n result.matchAll(/^(\\s*)(`{3,}|~{3,})/gm),\n );\n const hasUnclosedBacktick = (result.match(/`/g) || []).length % 2 === 1;\n const hasUnclosedCodeFence = finalFenceMatches.length % 2 === 1;\n\n let shouldCloseParens = !hasUnclosedBacktick && !hasUnclosedCodeFence;\n\n if (shouldCloseParens) {\n const lastOpenParen = result.lastIndexOf(\"(\");\n if (lastOpenParen !== -1) {\n // Check if this paren is inside a backtick pair\n const beforeParen = result.substring(0, lastOpenParen);\n const backticksBeforeParen = (beforeParen.match(/`/g) || []).length;\n if (backticksBeforeParen % 2 === 1) {\n shouldCloseParens = false;\n }\n }\n }\n\n if (shouldCloseParens) {\n const openParens = (result.match(/\\(/g) || []).length;\n const closeParens = (result.match(/\\)/g) || []).length;\n if (openParens > closeParens) {\n result += \")\".repeat(openParens - closeParens);\n }\n }\n\n return result;\n}\n","import { phoenixExponentialBackoff } from \"@copilotkit/shared\";\nimport type { Subscription } from \"rxjs\";\nimport { defer, firstValueFrom, merge, Observable, of } from \"rxjs\";\nimport {\n catchError,\n filter,\n map,\n mergeMap,\n share,\n shareReplay,\n switchMap,\n take,\n takeUntil,\n tap,\n withLatestFrom,\n} from \"rxjs/operators\";\nimport {\n createActionGroup,\n createEffect,\n createReducer,\n createSelector,\n createStore,\n empty,\n ofType,\n on,\n props,\n} from \"./utils/micro-redux\";\nimport type { Reducer, Store } from \"./utils/micro-redux\";\nimport type {\n RuntimeRequestInit,\n RuntimeRequestMeta,\n} from \"./utils/runtime-request\";\nimport {\n ɵphoenixChannel$,\n ɵphoenixSocket$,\n ɵobservePhoenixEvent$,\n ɵobservePhoenixJoinOutcome$,\n ɵobservePhoenixSocketHealth$,\n ɵobservePhoenixSocketSignals$,\n} from \"./utils/phoenix-observable\";\nimport type { ɵPhoenixChannelSession } from \"./utils/phoenix-observable\";\n\nconst THREADS_CHANNEL_EVENT = \"thread_metadata\";\nconst THREAD_RUN_ACTIVITY_CHANNEL_EVENT = \"thread_run_activity\";\nconst THREAD_SUBSCRIBE_PATH = \"/threads/subscribe\";\nconst MAX_SOCKET_RETRIES = 5;\nconst REQUEST_TIMEOUT_MS = 15_000;\n\ninterface ThreadRecord {\n id: string;\n organizationId: string;\n agentId: string;\n createdById: string;\n name: string | null;\n archived: boolean;\n createdAt: string;\n updatedAt: string;\n lastRunAt?: string;\n}\n\ninterface ThreadRuntimeContext {\n runtimeUrl: string;\n headers: Record<string, string>;\n wsUrl?: string;\n agentId: string;\n includeArchived?: boolean;\n limit?: number;\n}\n\ntype ThreadMetadataEvent =\n | {\n operation: \"created\" | \"renamed\" | \"archived\" | \"unarchived\" | \"updated\";\n threadId: string;\n userId: string;\n organizationId: string;\n occurredAt: string;\n thread: ThreadRecord;\n }\n | {\n operation: \"deleted\";\n threadId: string;\n userId: string;\n organizationId: string;\n occurredAt: string;\n deleted: {\n id: string;\n };\n };\n\n/**\n * Internal notification emitted when Intelligence observes new run activity\n * for a thread without changing that thread's metadata row.\n */\nexport type ThreadRunActivityNotification = {\n type: \"thread_run_activity\";\n threadId: string;\n agentId?: string;\n runId?: string;\n eventType: string;\n latestEventId?: string;\n};\n\ntype ThreadRunActivityGatewayPayload = {\n threadId?: unknown;\n thread_id?: unknown;\n agentId?: unknown;\n agent_id?: unknown;\n runId?: unknown;\n run_id?: unknown;\n eventType?: unknown;\n event_type?: unknown;\n latestEventId?: unknown;\n latest_event_id?: unknown;\n};\n\ninterface ThreadListResponse {\n threads: ThreadRecord[];\n joinCode?: string | null;\n nextCursor?: string | null;\n}\n\ninterface ThreadMetadataCredentialsResponse {\n joinToken: string;\n}\n\ninterface MutationRequest {\n requestId: string;\n /** Session the mutation was dispatched in; stale results are dropped. */\n sessionId: number;\n path: string;\n method: \"PATCH\" | \"POST\" | \"DELETE\";\n body: Record<string, unknown>;\n}\n\ntype MutationOutcome =\n | { requestId: string; sessionId: number; ok: true }\n | { requestId: string; sessionId: number; ok: false; error: Error };\n\ninterface ThreadEnvironment {\n fetch: typeof fetch;\n /**\n * Optional callback invoked whenever a thread mutation (rename, archive,\n * unarchive, delete) is rejected by the server. Lets framework wrappers\n * surface a transient error toast without subscribing to the error\n * selector. The error is also recorded in `state.error` regardless.\n *\n * Fired after any rollback (delete) has been applied to local state.\n */\n onError?: (error: Error) => void;\n}\n\ninterface ThreadState {\n threads: ThreadRecord[];\n isLoading: boolean;\n isFetchingNextPage: boolean;\n error: Error | null;\n /**\n * Error from the most recent failed next-page (`fetchMore`) load, or `null`.\n * Tracked SEPARATELY from `error` so a paginated-load failure surfaces an\n * inline \"couldn't load more\" affordance without replacing the already-loaded\n * list with a full-panel error. Cleared when a fetch-more is retried or when\n * one succeeds; reset on context change / stop.\n */\n fetchMoreError: Error | null;\n context: ThreadRuntimeContext | null;\n sessionId: number;\n metadataCredentialsRequested: boolean;\n metadataJoinCode: string | null;\n nextCursor: string | null;\n /** Number of thread mutations currently awaiting a server response. */\n inFlightMutationCount: number;\n /**\n * Rows optimistically removed by an in-flight `delete`, keyed by the\n * originating request id. DELETE is the one mutation that rolls back on\n * rejection, so the removed row is parked here and restored if the server\n * rejects. Rename/archive/unarchive are optimistic no-rollback and do not\n * populate this map.\n */\n pendingDeletes: Record<string, ThreadRecord>;\n}\n\nconst initialThreadState: ThreadState = {\n threads: [],\n isLoading: false,\n isFetchingNextPage: false,\n error: null,\n fetchMoreError: null,\n context: null,\n sessionId: 0,\n metadataCredentialsRequested: false,\n metadataJoinCode: null,\n nextCursor: null,\n inFlightMutationCount: 0,\n pendingDeletes: {},\n};\n\nconst threadAdapterEvents = createActionGroup(\"Thread Adapter\", {\n started: empty(),\n stopped: empty(),\n contextChanged: props<{ context: ThreadRuntimeContext | null }>(),\n fetchNextPageRequested: empty(),\n renameRequested: props<{\n requestId: string;\n threadId: string;\n name: string;\n }>(),\n archiveRequested: props<{ requestId: string; threadId: string }>(),\n unarchiveRequested: props<{ requestId: string; threadId: string }>(),\n deleteRequested: props<{ requestId: string; threadId: string }>(),\n newThreadStarted: empty(),\n});\n\nconst threadRestEvents = createActionGroup(\"Thread REST\", {\n listRequested: props<{ sessionId: number }>(),\n listSucceeded: props<{\n sessionId: number;\n threads: ThreadRecord[];\n joinCode: string | null;\n nextCursor: string | null;\n }>(),\n listFailed: props<{ sessionId: number; error: Error }>(),\n nextPageSucceeded: props<{\n sessionId: number;\n threads: ThreadRecord[];\n nextCursor: string | null;\n }>(),\n nextPageFailed: props<{ sessionId: number; error: Error }>(),\n metadataCredentialsRequested: props<{ sessionId: number }>(),\n metadataCredentialsSucceeded: props<{\n sessionId: number;\n joinToken: string;\n }>(),\n metadataCredentialsFailed: props<{ sessionId: number; error: Error }>(),\n mutationFinished: props<{ outcome: MutationOutcome }>(),\n});\n\nconst threadSocketEvents = createActionGroup(\"Thread Socket\", {\n opened: props<{ sessionId: number }>(),\n errored: props<{ sessionId: number }>(),\n joinFailed: props<{ sessionId: number }>(),\n joinTimedOut: props<{ sessionId: number }>(),\n metadataReceived: props<{\n sessionId: number;\n payload: ThreadMetadataEvent;\n }>(),\n runActivityReceived: props<{\n sessionId: number;\n notification: ThreadRunActivityNotification;\n }>(),\n});\n\nconst threadDomainEvents = createActionGroup(\"Thread Domain\", {\n threadUpserted: props<{ sessionId: number; thread: ThreadRecord }>(),\n threadDeleted: props<{ sessionId: number; threadId: string }>(),\n});\n\nfunction sortThreadsByRecency(threads: ThreadRecord[]): ThreadRecord[] {\n // Prefer lastRunAt so the order reflects actual agent activity and stays\n // stable when a user performs metadata-only actions like archive or rename.\n // Fall back to updatedAt (and then createdAt) for threads that have never run.\n return [...threads].sort((left, right) => {\n const leftKey = left.lastRunAt ?? left.updatedAt ?? left.createdAt;\n const rightKey = right.lastRunAt ?? right.updatedAt ?? right.createdAt;\n return rightKey.localeCompare(leftKey);\n });\n}\n\nfunction upsertThread(\n threads: ThreadRecord[],\n thread: ThreadRecord,\n): ThreadRecord[] {\n const existingIndex = threads.findIndex((item) => item.id === thread.id);\n if (existingIndex === -1) {\n return sortThreadsByRecency([...threads, thread]);\n }\n\n const next = [...threads];\n next[existingIndex] = thread;\n return sortThreadsByRecency(next);\n}\n\n/**\n * Returns a non-empty string payload field or undefined for absent fields.\n */\nfunction optionalString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\n/**\n * REST `/threads` is agent-scoped. The Phoenix `user_meta` channel is not.\n * Drop live upserts that belong to a different agent, or one Inspector\n * `all-agents` flatten shows the same thread twice until a hard refresh.\n */\nfunction threadMetadataTargetsAgent(\n payload: ThreadMetadataEvent,\n agentId: string | undefined,\n): boolean {\n if (!agentId || payload.operation === \"deleted\") {\n return true;\n }\n\n const threadAgentId = optionalString(payload.thread.agentId);\n return !threadAgentId || threadAgentId === agentId;\n}\n\n/**\n * Converts gateway run-activity payloads into the internal TypeScript shape.\n */\nfunction normalizeThreadRunActivityNotification(\n payload: ThreadRunActivityGatewayPayload,\n): ThreadRunActivityNotification | null {\n const threadId = optionalString(payload.threadId ?? payload.thread_id);\n const eventType = optionalString(payload.eventType ?? payload.event_type);\n\n if (!threadId || !eventType) {\n return null;\n }\n\n return {\n type: \"thread_run_activity\",\n threadId,\n agentId: optionalString(payload.agentId ?? payload.agent_id),\n runId: optionalString(payload.runId ?? payload.run_id),\n eventType,\n latestEventId: optionalString(\n payload.latestEventId ?? payload.latest_event_id,\n ),\n };\n}\n\nconst threadReducer = createReducer(\n initialThreadState,\n on(threadAdapterEvents.contextChanged, (state: ThreadState, { context }) => ({\n ...state,\n context,\n sessionId: state.sessionId + 1,\n threads: [],\n isLoading: Boolean(context),\n isFetchingNextPage: false,\n error: null,\n fetchMoreError: null,\n metadataCredentialsRequested: false,\n metadataJoinCode: null,\n nextCursor: null,\n inFlightMutationCount: 0,\n pendingDeletes: {},\n })),\n on(threadAdapterEvents.stopped, (state: ThreadState) => ({\n ...state,\n threads: [],\n isLoading: false,\n isFetchingNextPage: false,\n error: null,\n fetchMoreError: null,\n metadataCredentialsRequested: false,\n metadataJoinCode: null,\n nextCursor: null,\n inFlightMutationCount: 0,\n pendingDeletes: {},\n })),\n on(threadRestEvents.listRequested, (state: ThreadState, { sessionId }) => {\n if (sessionId !== state.sessionId || !state.context) {\n return state;\n }\n\n return {\n ...state,\n isLoading: true,\n error: null,\n // A full-list refetch supersedes any prior fetch-more failure: the whole\n // list is being reloaded, so the stale inline \"couldn't load more\" banner\n // must not survive onto the fresh list.\n fetchMoreError: null,\n };\n }),\n on(\n threadRestEvents.listSucceeded,\n (state: ThreadState, { sessionId, threads, joinCode, nextCursor }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n const joinCodeChanged = joinCode !== state.metadataJoinCode;\n\n return {\n ...state,\n threads: sortThreadsByRecency(threads),\n isLoading: false,\n error: null,\n // The fresh full list also clears any lingering fetch-more error, in\n // case the list arrived without passing through `listRequested`.\n fetchMoreError: null,\n metadataJoinCode: joinCode,\n metadataCredentialsRequested: joinCodeChanged\n ? false\n : state.metadataCredentialsRequested,\n nextCursor,\n };\n },\n ),\n on(\n threadRestEvents.listFailed,\n (state: ThreadState, { sessionId, error }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n isLoading: false,\n error,\n };\n },\n ),\n on(\n threadRestEvents.nextPageSucceeded,\n (state: ThreadState, { sessionId, threads, nextCursor }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n let merged = state.threads;\n for (const thread of threads) {\n merged = upsertThread(merged, thread);\n }\n\n return {\n ...state,\n threads: merged,\n isFetchingNextPage: false,\n // A successful next page clears any prior fetch-more error.\n fetchMoreError: null,\n nextCursor,\n };\n },\n ),\n on(\n threadRestEvents.nextPageFailed,\n (state: ThreadState, { sessionId, error }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n // A failed next-page load records the error on the DEDICATED fetch-more\n // channel — NOT `state.error` — so the already-loaded list is preserved\n // and the drawer renders an inline \"couldn't load more — retry\" panel\n // rather than replacing the whole list with a full-panel error.\n return {\n ...state,\n isFetchingNextPage: false,\n fetchMoreError: error,\n };\n },\n ),\n on(\n threadRestEvents.metadataCredentialsFailed,\n (state: ThreadState, { sessionId }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n // Non-fatal: the metadata-credentials (realtime join-token) fetch runs\n // AFTER the thread list has already loaded and only powers the realtime\n // channel. A failure means realtime won't connect, but the fetched list\n // is still valid — so we do NOT write `state.error` (which would replace\n // the whole list with a \"couldn't load\" panel). The failure is surfaced\n // as a diagnostic warning instead (socketDiagnosticsEffect), mirroring the\n // stay-stale handling of a realtime channel join failure. Clear the\n // request latch so a later list refresh can retry realtime setup.\n return {\n ...state,\n metadataCredentialsRequested: false,\n };\n },\n ),\n on(\n threadRestEvents.metadataCredentialsRequested,\n (state: ThreadState, { sessionId }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n metadataCredentialsRequested: true,\n };\n },\n ),\n on(threadAdapterEvents.fetchNextPageRequested, (state: ThreadState) => {\n if (!state.nextCursor || state.isFetchingNextPage) {\n return state;\n }\n\n return {\n ...state,\n isFetchingNextPage: true,\n // Clear any prior fetch-more error so a retry dismisses the inline panel\n // immediately while the next-page request is in flight.\n fetchMoreError: null,\n };\n }),\n on(\n threadAdapterEvents.renameRequested,\n (state: ThreadState, { threadId, name }) => {\n // Optimistic, no-rollback: reflect the new name immediately. A failure\n // surfaces via `error`/`onError` but the local row is left as-is; a\n // realtime metadata event or refetch reconciles the true server state.\n const existing = state.threads.find((thread) => thread.id === threadId);\n const inFlightMutationCount = state.inFlightMutationCount + 1;\n if (!existing) {\n return { ...state, inFlightMutationCount };\n }\n\n return {\n ...state,\n threads: upsertThread(state.threads, { ...existing, name }),\n inFlightMutationCount,\n };\n },\n ),\n on(\n threadAdapterEvents.archiveRequested,\n (state: ThreadState, { threadId }) => {\n // Optimistic, no-rollback. When archived threads are hidden, drop the\n // row; otherwise flip the flag in place. Note: archiving the active\n // thread is non-destructive — the wrapper keeps viewing it.\n const existing = state.threads.find((thread) => thread.id === threadId);\n const inFlightMutationCount = state.inFlightMutationCount + 1;\n if (!existing) {\n return { ...state, inFlightMutationCount };\n }\n\n if (!state.context?.includeArchived) {\n return {\n ...state,\n threads: state.threads.filter((thread) => thread.id !== threadId),\n inFlightMutationCount,\n };\n }\n\n return {\n ...state,\n threads: upsertThread(state.threads, { ...existing, archived: true }),\n inFlightMutationCount,\n };\n },\n ),\n on(\n threadAdapterEvents.unarchiveRequested,\n (state: ThreadState, { threadId }) => {\n // Optimistic, no-rollback.\n const existing = state.threads.find((thread) => thread.id === threadId);\n const inFlightMutationCount = state.inFlightMutationCount + 1;\n if (!existing) {\n return { ...state, inFlightMutationCount };\n }\n\n return {\n ...state,\n threads: upsertThread(state.threads, { ...existing, archived: false }),\n inFlightMutationCount,\n };\n },\n ),\n on(\n threadAdapterEvents.deleteRequested,\n (state: ThreadState, { requestId, threadId }) => {\n // Optimistic WITH rollback: remove the row now, but park it under the\n // request id so it can be restored if the server rejects the delete.\n const existing = state.threads.find((thread) => thread.id === threadId);\n const inFlightMutationCount = state.inFlightMutationCount + 1;\n if (!existing) {\n return { ...state, inFlightMutationCount };\n }\n\n return {\n ...state,\n threads: state.threads.filter((thread) => thread.id !== threadId),\n pendingDeletes: { ...state.pendingDeletes, [requestId]: existing },\n inFlightMutationCount,\n };\n },\n ),\n on(threadAdapterEvents.newThreadStarted, (state: ThreadState) => ({\n // Lazy creation: a fresh client-side thread does NOT add a phantom row —\n // it only materializes once its first run persists server-side. The\n // store-side concern is purely to clear any stale error so the welcome\n // screen renders cleanly; the wrapper owns the active/explicit threadId.\n ...state,\n error: null,\n })),\n on(threadRestEvents.mutationFinished, (state: ThreadState, { outcome }) => {\n // Drop results from a superseded session. `contextChanged`/`stopped` already\n // reset `threads`, `pendingDeletes`, and `inFlightMutationCount`, so a\n // mutation that resolves after the context switched must not write an error,\n // fire onError (guarded in subscribeErrors), or roll a stale row back into\n // the new list. Mirrors every other session-scoped handler.\n if (outcome.sessionId !== state.sessionId) {\n return state;\n }\n\n const inFlightMutationCount = Math.max(0, state.inFlightMutationCount - 1);\n\n if (outcome.ok) {\n // Success: drop any parked delete-rollback snapshot for this request.\n if (state.pendingDeletes[outcome.requestId] === undefined) {\n return { ...state, inFlightMutationCount };\n }\n\n const { [outcome.requestId]: _settled, ...rest } = state.pendingDeletes;\n return { ...state, inFlightMutationCount, pendingDeletes: rest };\n }\n\n // Failure: surface the error. For a rejected delete, restore the row that\n // was optimistically removed (rollback). Other mutations are no-rollback.\n const rolledBack = state.pendingDeletes[outcome.requestId];\n if (rolledBack === undefined) {\n return { ...state, inFlightMutationCount, error: outcome.error };\n }\n\n const { [outcome.requestId]: _restored, ...rest } = state.pendingDeletes;\n return {\n ...state,\n threads: upsertThread(state.threads, rolledBack),\n pendingDeletes: rest,\n inFlightMutationCount,\n error: outcome.error,\n };\n }),\n on(\n threadDomainEvents.threadUpserted,\n (state: ThreadState, { sessionId, thread }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n threads: upsertThread(state.threads, thread),\n };\n },\n ),\n on(\n threadDomainEvents.threadDeleted,\n (state: ThreadState, { sessionId, threadId }) => {\n if (sessionId !== state.sessionId) {\n return state;\n }\n\n return {\n ...state,\n threads: state.threads.filter((thread) => thread.id !== threadId),\n };\n },\n ),\n) as Reducer<ThreadState>;\n\n/**\n * The set of memoized thread selectors bound to a single store instance.\n *\n * @see createThreadSelectors\n */\ninterface ThreadSelectors {\n threads: (state: ThreadState) => ThreadRecord[];\n isLoading: (state: ThreadState) => boolean;\n error: (state: ThreadState) => Error | null;\n fetchMoreError: (state: ThreadState) => Error | null;\n hasNextPage: (state: ThreadState) => boolean;\n isFetchingNextPage: (state: ThreadState) => boolean;\n isMutating: (state: ThreadState) => boolean;\n}\n\n/**\n * Builds a fresh set of memoized thread selectors.\n *\n * Each `createSelector` closure owns a private one-entry cache. Sharing a\n * single module-level selector instance across multiple concurrent stores\n * (e.g. a `<CopilotThreadsDrawer>` plus an independent `useThreads`) makes every\n * cross-store emission a cache miss, defeating memoization and risking\n * emission instability for any future selector that allocates a new\n * object/array. Creating a per-store instance keeps each store's cache\n * isolated so concurrent stores never thrash one another.\n */\nfunction createThreadSelectors(): ThreadSelectors {\n return {\n threads: createSelector((state: ThreadState) => state.threads),\n isLoading: createSelector((state: ThreadState) => state.isLoading),\n error: createSelector((state: ThreadState) => state.error),\n fetchMoreError: createSelector(\n (state: ThreadState) => state.fetchMoreError,\n ),\n hasNextPage: createSelector(\n (state: ThreadState) => state.nextCursor != null,\n ),\n isFetchingNextPage: createSelector(\n (state: ThreadState) => state.isFetchingNextPage,\n ),\n isMutating: createSelector(\n (state: ThreadState) => state.inFlightMutationCount > 0,\n ),\n };\n}\n\n// Standalone selector instances retained for callers that read a one-off\n// snapshot (e.g. `selectThreads(store.getState())`) where cross-store memo\n// isolation is irrelevant. Subscriptions through `store.select(...)` should\n// prefer the per-store `ThreadStore.selectors` bundle below.\nconst standaloneSelectors = createThreadSelectors();\nconst selectThreads = standaloneSelectors.threads;\nconst selectThreadsIsLoading = standaloneSelectors.isLoading;\nconst selectThreadsError = standaloneSelectors.error;\nconst selectFetchMoreError = standaloneSelectors.fetchMoreError;\nconst selectHasNextPage = standaloneSelectors.hasNextPage;\nconst selectIsFetchingNextPage = standaloneSelectors.isFetchingNextPage;\nconst selectIsMutating = standaloneSelectors.isMutating;\n\ninterface ThreadStore {\n start(): void;\n stop(): void;\n setContext(context: ThreadRuntimeContext | null): void;\n /** Re-fetches the thread list without resetting the current list to empty. */\n refresh(): void;\n /**\n * Re-fetches the thread list without resetting the current list to empty.\n *\n * Public, design-named alias of {@link refresh} used by the drawer's\n * error-state Retry affordance and the Active/All filter-change refetch.\n */\n refetchThreads(): void;\n /**\n * Resets to a fresh, client-side thread so the welcome screen can show.\n *\n * Lazy creation: no phantom row is added to the list — the new thread only\n * materializes once its first run persists server-side. This is distinct\n * from selecting an existing thread (which the wrapper marks *explicit*,\n * suppressing the welcome screen): the thread produced here is NOT explicit.\n */\n startNewThread(): void;\n fetchNextPage(): void;\n renameThread(threadId: string, name: string): Promise<void>;\n archiveThread(threadId: string): Promise<void>;\n unarchiveThread(threadId: string): Promise<void>;\n deleteThread(threadId: string): Promise<void>;\n /**\n * Subscribes to synthetic run-activity notifications without changing the\n * thread metadata list.\n */\n subscribeToRunActivity?(\n callback: (notification: ThreadRunActivityNotification) => void,\n ): Subscription;\n getState(): ThreadState;\n /**\n * Returns a stable initial snapshot for server-side rendering.\n *\n * `useSyncExternalStore` requires a `getServerSnapshot` during SSR/prerender\n * (e.g. Next.js); without one React throws \"Missing getServerSnapshot\". The\n * returned reference is stable across calls so React does not loop. There is\n * no client-side thread data during prerender, so this is the empty initial\n * state.\n */\n getServerState(): ThreadState;\n select: Store<ThreadState>[\"select\"];\n /**\n * Memoized selectors bound to THIS store instance.\n *\n * Subscriptions should pass these to {@link select} (e.g.\n * `store.select(store.selectors.threads)`) so each store keeps its own\n * one-entry memo cache. Sharing the module-level singletons across\n * concurrent stores defeats memoization and risks emission instability.\n */\n selectors: ThreadSelectors;\n}\n\nlet threadRequestId = 0;\n\nfunction createThreadRequestId(): string {\n threadRequestId += 1;\n return `thread-request-${threadRequestId}`;\n}\n\nfunction threadFromFetch<T>(\n input: string,\n init: RequestInit & {\n selector: (response: Response) => Promise<T>;\n fetch: typeof fetch;\n timeoutMs?: number;\n nonCritical?: boolean;\n },\n): Observable<T> {\n return new Observable<T>((subscriber) => {\n const {\n fetch: fetchImpl,\n selector,\n signal,\n timeoutMs,\n nonCritical,\n ...requestInit\n } = init;\n const controller = new AbortController();\n const runtimeRequest: RuntimeRequestMeta = {\n ...(nonCritical ? { nonCritical: true } : {}),\n ...(timeoutMs === undefined ? {} : { selfBounded: true }),\n };\n let timedOut = false;\n const abortRequest = () => controller.abort();\n\n if (signal?.aborted) {\n abortRequest();\n } else {\n signal?.addEventListener(\"abort\", abortRequest, { once: true });\n }\n\n const timeoutId =\n timeoutMs === undefined\n ? undefined\n : setTimeout(() => {\n timedOut = true;\n runtimeRequest.timedOut = true;\n abortRequest();\n }, timeoutMs);\n\n const requestInitWithMeta: RuntimeRequestInit = {\n ...requestInit,\n signal: controller.signal,\n ɵruntimeRequest: runtimeRequest,\n };\n\n fetchImpl(input, requestInitWithMeta)\n .then((response) => selector(response))\n .then((value) => {\n if (subscriber.closed) return;\n subscriber.next(value);\n subscriber.complete();\n })\n .catch((error: unknown) => {\n if (!subscriber.closed) {\n subscriber.error(\n timedOut ? new Error(\"Request timed out\") : (error as Error),\n );\n }\n });\n\n return () => {\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n }\n signal?.removeEventListener(\"abort\", abortRequest);\n abortRequest();\n };\n });\n}\n\nfunction createThreadFetchObservable(\n environment: ThreadEnvironment,\n context: ThreadRuntimeContext,\n sessionId: number,\n): Observable<\n | ReturnType<typeof threadRestEvents.listSucceeded>\n | ReturnType<typeof threadRestEvents.listFailed>\n> {\n return defer(() => {\n const params: Record<string, string> = {\n agentId: context.agentId,\n };\n if (context.includeArchived) params.includeArchived = \"true\";\n if (context.limit != null) params.limit = String(context.limit);\n\n const qs = new URLSearchParams(params);\n return threadFromFetch(`${context.runtimeUrl}/threads?${qs.toString()}`, {\n selector: (response) => {\n if (!response.ok) {\n throw new Error(`Failed to fetch threads: ${response.status}`);\n }\n\n return response.json() as Promise<ThreadListResponse>;\n },\n fetch: environment.fetch,\n timeoutMs: REQUEST_TIMEOUT_MS,\n method: \"GET\",\n headers: { ...context.headers },\n }).pipe(\n map((data) =>\n threadRestEvents.listSucceeded({\n sessionId,\n threads: data.threads,\n joinCode:\n typeof data.joinCode === \"string\" && data.joinCode.length > 0\n ? data.joinCode\n : null,\n nextCursor: data.nextCursor ?? null,\n }),\n ),\n catchError((error) => {\n return of(\n threadRestEvents.listFailed({\n sessionId,\n error: error instanceof Error ? error : new Error(String(error)),\n }),\n );\n }),\n );\n });\n}\n\nfunction createThreadMetadataCredentialsObservable(\n environment: ThreadEnvironment,\n context: ThreadRuntimeContext,\n sessionId: number,\n): Observable<\n | ReturnType<typeof threadRestEvents.metadataCredentialsSucceeded>\n | ReturnType<typeof threadRestEvents.metadataCredentialsFailed>\n> {\n return defer(() => {\n return threadFromFetch(`${context.runtimeUrl}${THREAD_SUBSCRIBE_PATH}`, {\n selector: async (response) => {\n if (!response.ok) {\n throw new Error(\n `Failed to fetch thread metadata credentials: ${response.status}`,\n );\n }\n\n return response.json() as Promise<ThreadMetadataCredentialsResponse>;\n },\n fetch: environment.fetch,\n timeoutMs: REQUEST_TIMEOUT_MS,\n nonCritical: true,\n method: \"POST\",\n headers: {\n ...context.headers,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({}),\n }).pipe(\n map((data) => {\n if (typeof data.joinToken !== \"string\" || data.joinToken.length === 0) {\n throw new Error(\"missing joinToken\");\n }\n\n return threadRestEvents.metadataCredentialsSucceeded({\n sessionId,\n joinToken: data.joinToken,\n });\n }),\n catchError((error) => {\n return of(\n threadRestEvents.metadataCredentialsFailed({\n sessionId,\n error: error instanceof Error ? error : new Error(String(error)),\n }),\n );\n }),\n );\n });\n}\n\nfunction createThreadMutationObservable(\n environment: ThreadEnvironment,\n context: ThreadRuntimeContext,\n request: MutationRequest,\n): Observable<ReturnType<typeof threadRestEvents.mutationFinished>> {\n return defer(() => {\n return threadFromFetch(`${context.runtimeUrl}${request.path}`, {\n selector: async (response) => {\n if (!response.ok) {\n throw new Error(`Request failed: ${response.status}`);\n }\n\n return null;\n },\n fetch: environment.fetch,\n method: request.method,\n headers: {\n ...context.headers,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(request.body),\n }).pipe(\n map(() =>\n threadRestEvents.mutationFinished({\n outcome: {\n requestId: request.requestId,\n sessionId: request.sessionId,\n ok: true,\n },\n }),\n ),\n catchError((error) => {\n return of(\n threadRestEvents.mutationFinished({\n outcome: {\n requestId: request.requestId,\n sessionId: request.sessionId,\n ok: false,\n error: error instanceof Error ? error : new Error(String(error)),\n },\n }),\n );\n }),\n );\n });\n}\n\nfunction createThreadStore(environment: ThreadEnvironment): ThreadStore {\n // Per-store selector instances keep this store's memo cache isolated from\n // any other concurrent store (see createThreadSelectors).\n const selectors = createThreadSelectors();\n\n const bootstrapEffect = createEffect(\n (\n actions$,\n state$: Observable<ThreadState>,\n ): Observable<ReturnType<typeof threadRestEvents.listRequested>> =>\n actions$.pipe(\n ofType(threadAdapterEvents.contextChanged),\n withLatestFrom(state$),\n filter(([, state]) => Boolean(state.context)),\n map(([, state]) =>\n threadRestEvents.listRequested({ sessionId: state.sessionId }),\n ),\n ),\n );\n\n const fetchEffect = createEffect(\n (actions$, state$: Observable<ThreadState>) =>\n actions$.pipe(\n ofType(threadRestEvents.listRequested),\n switchMap((action) =>\n state$.pipe(\n map((state) => state.context),\n filter((context): context is ThreadRuntimeContext =>\n Boolean(context),\n ),\n take(1),\n map((context) => ({ action, context })),\n takeUntil(\n actions$.pipe(\n ofType(\n threadAdapterEvents.contextChanged,\n threadAdapterEvents.stopped,\n ),\n ),\n ),\n switchMap(({ action: currentAction, context }) =>\n createThreadFetchObservable(\n environment,\n context,\n currentAction.sessionId,\n ),\n ),\n ),\n ),\n ),\n );\n\n const metadataCredentialsEffect = createEffect(\n (actions$, state$: Observable<ThreadState>) =>\n actions$.pipe(\n ofType(threadRestEvents.listSucceeded),\n withLatestFrom(state$),\n filter(([action, state]) => {\n return (\n action.sessionId === state.sessionId &&\n !state.metadataCredentialsRequested &&\n Boolean(state.context?.wsUrl) &&\n Boolean(state.metadataJoinCode)\n );\n }),\n map(([action]) =>\n threadRestEvents.metadataCredentialsRequested({\n sessionId: action.sessionId,\n }),\n ),\n ),\n );\n\n const metadataCredentialsFetchEffect = createEffect(\n (actions$, state$: Observable<ThreadState>) =>\n actions$.pipe(\n ofType(threadRestEvents.metadataCredentialsRequested),\n switchMap((action) =>\n state$.pipe(\n map((state) => state.context),\n filter((context): context is ThreadRuntimeContext =>\n Boolean(context),\n ),\n take(1),\n map((context) => ({ action, context })),\n takeUntil(\n actions$.pipe(\n ofType(\n threadAdapterEvents.contextChanged,\n threadAdapterEvents.stopped,\n ),\n ),\n ),\n switchMap(({ action: currentAction, context }) =>\n createThreadMetadataCredentialsObservable(\n environment,\n context,\n currentAction.sessionId,\n ),\n ),\n ),\n ),\n ),\n );\n\n const socketEffect = createEffect(\n (actions$, state$: Observable<ThreadState>) =>\n actions$.pipe(\n ofType(threadRestEvents.metadataCredentialsSucceeded),\n withLatestFrom(state$),\n filter(([action, state]) => {\n return (\n action.sessionId === state.sessionId &&\n Boolean(state.context?.wsUrl)\n );\n }),\n switchMap(([action, state]) => {\n const context = state.context as ThreadRuntimeContext;\n const joinToken = action.joinToken as string;\n const joinCode = state.metadataJoinCode as string;\n const shutdown$ = actions$.pipe(\n ofType(\n threadAdapterEvents.contextChanged,\n threadAdapterEvents.stopped,\n ),\n );\n\n return defer(() => {\n const socket$ = ɵphoenixSocket$({\n url: context.wsUrl!,\n options: {\n params: { join_token: joinToken },\n reconnectAfterMs: phoenixExponentialBackoff(100, 10_000),\n rejoinAfterMs: phoenixExponentialBackoff(1_000, 30_000),\n },\n }).pipe(shareReplay({ bufferSize: 1, refCount: true }));\n const channel$ = ɵphoenixChannel$({\n socket$,\n topic: `user_meta:${joinCode}`,\n }).pipe(shareReplay({ bufferSize: 1, refCount: true }));\n const socketSignals$ =\n ɵobservePhoenixSocketSignals$(socket$).pipe(share());\n const fatalSocketShutdown$ = ɵobservePhoenixSocketHealth$(\n socketSignals$,\n MAX_SOCKET_RETRIES,\n ).pipe(\n catchError(() => {\n console.warn(\n `[threads] WebSocket failed after ${MAX_SOCKET_RETRIES} attempts, giving up`,\n );\n return of(undefined);\n }),\n share(),\n );\n const socketLifecycle$ = socketSignals$.pipe(\n map((signal) =>\n signal.type === \"open\"\n ? threadSocketEvents.opened({ sessionId: action.sessionId })\n : threadSocketEvents.errored({ sessionId: action.sessionId }),\n ),\n );\n const metadata$ = channel$.pipe(\n switchMap(({ channel }: ɵPhoenixChannelSession) =>\n ɵobservePhoenixEvent$<ThreadMetadataEvent>(\n channel,\n THREADS_CHANNEL_EVENT,\n ),\n ),\n map((payload) =>\n threadSocketEvents.metadataReceived({\n sessionId: action.sessionId,\n payload,\n }),\n ),\n );\n const runActivity$ = channel$.pipe(\n switchMap(({ channel }: ɵPhoenixChannelSession) =>\n ɵobservePhoenixEvent$<ThreadRunActivityGatewayPayload>(\n channel,\n THREAD_RUN_ACTIVITY_CHANNEL_EVENT,\n ),\n ),\n map((payload) => normalizeThreadRunActivityNotification(payload)),\n filter(\n (notification): notification is ThreadRunActivityNotification =>\n notification !== null,\n ),\n map((notification) =>\n threadSocketEvents.runActivityReceived({\n sessionId: action.sessionId,\n notification,\n }),\n ),\n );\n const joinOutcome$ = ɵobservePhoenixJoinOutcome$(channel$).pipe(\n filter((outcome) => outcome.type !== \"joined\"),\n map((outcome) =>\n outcome.type === \"timeout\"\n ? threadSocketEvents.joinTimedOut({\n sessionId: action.sessionId,\n })\n : threadSocketEvents.joinFailed({\n sessionId: action.sessionId,\n }),\n ),\n );\n\n return merge(\n socketLifecycle$,\n metadata$,\n runActivity$,\n joinOutcome$,\n ).pipe(takeUntil(merge(shutdown$, fatalSocketShutdown$)));\n });\n }),\n ),\n );\n\n const realtimeMappingEffect = createEffect(\n (actions$, state$: Observable<ThreadState>) =>\n actions$.pipe(\n ofType(threadSocketEvents.metadataReceived),\n withLatestFrom(state$),\n filter(\n ([action, state]) =>\n action.sessionId === state.sessionId &&\n threadMetadataTargetsAgent(action.payload, state.context?.agentId),\n ),\n map(([action, state]) => {\n if (action.payload.operation === \"deleted\") {\n return threadDomainEvents.threadDeleted({\n sessionId: action.sessionId,\n threadId: action.payload.deleted.id,\n });\n }\n\n // When includeArchived is false, an \"archived\" event should remove\n // the thread from the local list rather than upserting it.\n if (\n action.payload.operation === \"archived\" &&\n !state.context?.includeArchived\n ) {\n return threadDomainEvents.threadDeleted({\n sessionId: action.sessionId,\n threadId: action.payload.threadId,\n });\n }\n\n return threadDomainEvents.threadUpserted({\n sessionId: action.sessionId,\n thread: action.payload.thread,\n });\n }),\n ),\n );\n\n // Observability-only effect for realtime-join health. The socket effect\n // dispatches `joinFailed`/`joinTimedOut`/`errored` but the reducer has no\n // handler for them by design: a transient WS drop while the (already\n // fetched) list is present must NOT become a hard list error — the user\n // keeps the stale list. Previously these actions were silently swallowed,\n // leaving a realtime-join failure with zero signal. This effect emits a\n // non-fatal warning (mirroring the MAX_SOCKET_RETRIES warn) so the failure\n // is diagnosable. Session-guarded so a superseded session stays quiet.\n const socketDiagnosticsEffect = createEffect(\n (actions$, state$: Observable<ThreadState>) =>\n actions$.pipe(\n ofType(\n threadSocketEvents.joinFailed,\n threadSocketEvents.joinTimedOut,\n threadSocketEvents.errored,\n threadRestEvents.metadataCredentialsFailed,\n ),\n withLatestFrom(state$),\n filter(([action, state]) => action.sessionId === state.sessionId),\n tap(([action]) => {\n const reason = threadSocketEvents.joinTimedOut.match(action)\n ? \"channel join timed out\"\n : threadSocketEvents.joinFailed.match(action)\n ? \"channel join was rejected\"\n : threadRestEvents.metadataCredentialsFailed.match(action)\n ? \"metadata credentials fetch failed\"\n : \"socket errored\";\n console.warn(\n `[threads] realtime ${reason}; the thread list may be stale until reconnect`,\n );\n }),\n ),\n { dispatch: false },\n );\n\n const fetchNextPageEffect = createEffect(\n (actions$, state$: Observable<ThreadState>) =>\n actions$.pipe(\n ofType(threadAdapterEvents.fetchNextPageRequested),\n withLatestFrom(state$),\n filter(\n ([, state]) => Boolean(state.context) && Boolean(state.nextCursor),\n ),\n switchMap(([, state]) => {\n const context = state.context as ThreadRuntimeContext;\n const params: Record<string, string> = {\n agentId: context.agentId,\n cursor: state.nextCursor!,\n };\n if (context.includeArchived) params.includeArchived = \"true\";\n if (context.limit != null) params.limit = String(context.limit);\n\n return threadFromFetch(\n `${context.runtimeUrl}/threads?${new URLSearchParams(params).toString()}`,\n {\n selector: (response) => {\n if (!response.ok) {\n throw new Error(\n `Failed to fetch next page: ${response.status}`,\n );\n }\n\n return response.json() as Promise<ThreadListResponse>;\n },\n fetch: environment.fetch,\n timeoutMs: REQUEST_TIMEOUT_MS,\n method: \"GET\",\n headers: { ...context.headers },\n },\n ).pipe(\n map((data) =>\n threadRestEvents.nextPageSucceeded({\n sessionId: state.sessionId,\n threads: data.threads,\n nextCursor: data.nextCursor ?? null,\n }),\n ),\n catchError((error) =>\n of(\n threadRestEvents.nextPageFailed({\n sessionId: state.sessionId,\n error:\n error instanceof Error ? error : new Error(String(error)),\n }),\n ),\n ),\n takeUntil(\n actions$.pipe(\n ofType(\n threadAdapterEvents.contextChanged,\n threadAdapterEvents.stopped,\n ),\n ),\n ),\n );\n }),\n ),\n );\n\n const mutationEffect = createEffect(\n (actions$, state$: Observable<ThreadState>) =>\n actions$.pipe(\n ofType(\n threadAdapterEvents.renameRequested,\n threadAdapterEvents.archiveRequested,\n threadAdapterEvents.unarchiveRequested,\n threadAdapterEvents.deleteRequested,\n ),\n withLatestFrom(state$),\n mergeMap(([action, state]) => {\n // Capture the dispatching session so a result that resolves after a\n // `contextChanged` is dropped by the reducer instead of leaking an\n // error/onError/rollback into the new session. The mergeMap is not\n // cancelled on context change, so the session tag is the guard.\n const sessionId = state.sessionId;\n const context = state.context;\n if (!context?.runtimeUrl) {\n const requestId = action.requestId;\n return of(\n threadRestEvents.mutationFinished({\n outcome: {\n requestId,\n sessionId,\n ok: false,\n error: new Error(\"Runtime URL is not configured\"),\n },\n }),\n );\n }\n\n const commonBody = {\n agentId: context.agentId,\n };\n\n if (threadAdapterEvents.renameRequested.match(action)) {\n return createThreadMutationObservable(environment, context, {\n requestId: action.requestId,\n sessionId,\n method: \"PATCH\",\n path: `/threads/${encodeURIComponent(action.threadId)}`,\n body: {\n ...commonBody,\n name: action.name,\n },\n });\n }\n\n if (threadAdapterEvents.archiveRequested.match(action)) {\n return createThreadMutationObservable(environment, context, {\n requestId: action.requestId,\n sessionId,\n method: \"POST\",\n path: `/threads/${encodeURIComponent(action.threadId)}/archive`,\n body: commonBody,\n });\n }\n\n if (threadAdapterEvents.unarchiveRequested.match(action)) {\n return createThreadMutationObservable(environment, context, {\n requestId: action.requestId,\n sessionId,\n method: \"PATCH\",\n path: `/threads/${encodeURIComponent(action.threadId)}`,\n body: {\n ...commonBody,\n archived: false,\n },\n });\n }\n\n return createThreadMutationObservable(environment, context, {\n requestId: action.requestId,\n sessionId,\n method: \"DELETE\",\n path: `/threads/${encodeURIComponent(action.threadId)}`,\n body: commonBody,\n });\n }),\n ),\n );\n\n const store = createStore<ThreadState>({\n reducer: threadReducer,\n effects: [\n bootstrapEffect,\n fetchEffect,\n metadataCredentialsEffect,\n metadataCredentialsFetchEffect,\n socketEffect,\n realtimeMappingEffect,\n socketDiagnosticsEffect,\n fetchNextPageEffect,\n mutationEffect,\n ],\n });\n\n function trackMutation(\n dispatchAction:\n | ReturnType<typeof threadAdapterEvents.renameRequested>\n | ReturnType<typeof threadAdapterEvents.archiveRequested>\n | ReturnType<typeof threadAdapterEvents.unarchiveRequested>\n | ReturnType<typeof threadAdapterEvents.deleteRequested>,\n ): Promise<void> {\n const completion$ = merge(\n store.actions$.pipe(\n ofType(threadRestEvents.mutationFinished),\n filter(\n (action) => action.outcome.requestId === dispatchAction.requestId,\n ),\n map((action) => action.outcome),\n ),\n store.actions$.pipe(\n ofType(threadAdapterEvents.stopped),\n map(\n () =>\n ({\n requestId: dispatchAction.requestId,\n sessionId: store.getState().sessionId,\n ok: false,\n error: new Error(\n \"Thread store stopped before mutation completed\",\n ),\n }) satisfies MutationOutcome,\n ),\n ),\n ).pipe(take(1));\n\n const resultPromise = firstValueFrom(completion$).then((outcome) => {\n if (outcome.ok) {\n return;\n }\n\n throw outcome.error;\n });\n\n store.dispatch(dispatchAction);\n return resultPromise;\n }\n\n // Surface mutation rejections to the optional environment callback. The\n // reducer has already applied any delete rollback by the time this fires\n // (the store reduces state before re-emitting the action), so consumers see\n // a consistent list when they react to the error.\n let errorSubscription: Subscription | null = null;\n const subscribeErrors = (): void => {\n if (!environment.onError || errorSubscription) {\n return;\n }\n\n errorSubscription = store.actions$\n .pipe(\n ofType(threadRestEvents.mutationFinished),\n // Drop stale-session failures: a mutation that rejects after a\n // `contextChanged` belongs to a context the user already left, so\n // surfacing it would fire onError for the wrong session. The reducer\n // applies the same guard before writing `state.error`.\n filter(\n (action) =>\n !action.outcome.ok &&\n action.outcome.sessionId === store.getState().sessionId,\n ),\n )\n .subscribe((action) => {\n if (!action.outcome.ok) {\n environment.onError?.(action.outcome.error);\n }\n });\n };\n\n return {\n start(): void {\n store.init();\n subscribeErrors();\n store.dispatch(threadAdapterEvents.started());\n },\n stop(): void {\n store.dispatch(threadAdapterEvents.stopped());\n errorSubscription?.unsubscribe();\n errorSubscription = null;\n store.stop();\n },\n setContext(context: ThreadRuntimeContext | null): void {\n store.dispatch(threadAdapterEvents.contextChanged({ context }));\n },\n refresh(): void {\n const { sessionId, context } = store.getState();\n if (!context) return;\n store.dispatch(threadRestEvents.listRequested({ sessionId }));\n },\n refetchThreads(): void {\n const { sessionId, context } = store.getState();\n if (!context) return;\n store.dispatch(threadRestEvents.listRequested({ sessionId }));\n },\n startNewThread(): void {\n store.dispatch(threadAdapterEvents.newThreadStarted());\n },\n fetchNextPage(): void {\n store.dispatch(threadAdapterEvents.fetchNextPageRequested());\n },\n renameThread(threadId: string, name: string): Promise<void> {\n return trackMutation(\n threadAdapterEvents.renameRequested({\n requestId: createThreadRequestId(),\n threadId,\n name,\n }),\n );\n },\n archiveThread(threadId: string): Promise<void> {\n return trackMutation(\n threadAdapterEvents.archiveRequested({\n requestId: createThreadRequestId(),\n threadId,\n }),\n );\n },\n unarchiveThread(threadId: string): Promise<void> {\n return trackMutation(\n threadAdapterEvents.unarchiveRequested({\n requestId: createThreadRequestId(),\n threadId,\n }),\n );\n },\n deleteThread(threadId: string): Promise<void> {\n return trackMutation(\n threadAdapterEvents.deleteRequested({\n requestId: createThreadRequestId(),\n threadId,\n }),\n );\n },\n subscribeToRunActivity(\n callback: (notification: ThreadRunActivityNotification) => void,\n ): Subscription {\n return store.actions$\n .pipe(\n ofType(threadSocketEvents.runActivityReceived),\n filter((action) => action.sessionId === store.getState().sessionId),\n map((action) => action.notification),\n )\n .subscribe(callback);\n },\n getState(): ThreadState {\n return store.getState();\n },\n getServerState(): ThreadState {\n return initialThreadState;\n },\n select: store.select.bind(store),\n selectors,\n };\n}\n\nexport type ɵThread = ThreadRecord;\nexport type ɵThreadRuntimeContext = ThreadRuntimeContext;\nexport type ɵThreadMetadataEvent = ThreadMetadataEvent;\nexport type ɵThreadEnvironment = ThreadEnvironment;\nexport type ɵThreadStore = ThreadStore;\nexport type ɵThreadSelectors = ThreadSelectors;\nexport const ɵthreadAdapterEvents = threadAdapterEvents;\nexport const ɵcreateThreadSelectors = createThreadSelectors;\nexport const ɵselectThreads = selectThreads;\nexport const ɵselectThreadsIsLoading = selectThreadsIsLoading;\nexport const ɵselectThreadsError = selectThreadsError;\nexport const ɵselectFetchMoreError = selectFetchMoreError;\nexport const ɵselectHasNextPage = selectHasNextPage;\nexport const ɵselectIsFetchingNextPage = selectIsFetchingNextPage;\nexport const ɵselectIsMutating = selectIsMutating;\nexport { createThreadStore as ɵcreateThreadStore };\n/**\n * Number of consecutive WebSocket connection failures after which the\n * threads channel tears itself down rather than retrying indefinitely.\n * Exposed for tests so they can assert teardown semantics without\n * hardcoding the threshold separately from production.\n */\nexport const ɵMAX_SOCKET_RETRIES = MAX_SOCKET_RETRIES;\n/**\n * How long a thread REST request is given before the store gives up on it.\n * Exposed for tests for the same reason as {@link ɵMAX_SOCKET_RETRIES}: a\n * separately hardcoded copy silently drifts away from this one.\n */\nexport const ɵTHREAD_REQUEST_TIMEOUT_MS = REQUEST_TIMEOUT_MS;\n","/**\n * Central registry of CopilotKit feature names.\n *\n * Feature names are the strings passed to a license context's `checkFeature`\n * (see `@copilotkit/shared`'s `LicenseContextValue`). Historically the only\n * features referenced by literal were the chat surfaces (`chat`, `sidebar`,\n * `popup`); this module makes the set explicit and typed so new surfaces —\n * such as the threads drawer — register a real, discoverable feature name\n * rather than an ad-hoc string scattered across components.\n *\n * `checkFeature` itself still accepts any `string` for backward compatibility;\n * this registry simply documents and types the names CopilotKit recognises.\n */\n\n/**\n * The set of feature names CopilotKit recognises.\n *\n * Frozen so the array cannot be mutated at runtime. Add new surfaces here when\n * they begin gating behaviour on `checkFeature`.\n */\nexport const ɵCOPILOTKIT_FEATURES = Object.freeze([\n \"chat\",\n \"sidebar\",\n \"popup\",\n \"threads\",\n] as const);\n\n/**\n * Union of recognised CopilotKit feature names.\n */\nexport type ɵCopilotKitFeature = (typeof ɵCOPILOTKIT_FEATURES)[number];\n\nconst FEATURE_SET: ReadonlySet<string> = new Set(ɵCOPILOTKIT_FEATURES);\n\n/**\n * Type guard: returns `true` when `name` is a recognised CopilotKit feature.\n *\n * @param name - Candidate feature name.\n * @returns Whether `name` is a registered feature.\n *\n * @example\n * ```ts\n * if (ɵisCopilotKitFeature(\"threads\")) {\n * // narrowed to ɵCopilotKitFeature\n * }\n * ```\n */\nexport function ɵisCopilotKitFeature(name: string): name is ɵCopilotKitFeature {\n return FEATURE_SET.has(name);\n}\n","import { buildResumeArray, isInterruptExpired } from \"@ag-ui/client\";\nimport type { Interrupt, ResumeEntry } from \"@ag-ui/client\";\n\ntype ResumeResponse =\n | { status: \"resolved\"; payload?: unknown }\n | { status: \"cancelled\" };\n\n/** @internal Application authors must not depend on this contract. */\nexport interface ɵInterruptEvent<TValue = unknown> {\n name: string;\n value: TValue;\n}\n\n/** @internal Application authors must not depend on this contract. */\nexport type ɵPendingInterrupt<TValue = unknown> =\n | { kind: \"legacy\"; event: ɵInterruptEvent<TValue> }\n | { kind: \"standard\"; interrupts: readonly Interrupt[] };\n\n/** @internal Application authors must not depend on this contract. */\nexport interface ɵInterruptToolResult {\n toolCallId: string;\n content: string;\n}\n\n/** @internal Application authors must not depend on this contract. */\nexport type ɵInterruptDecision =\n | { kind: \"ignored\" }\n | { kind: \"waiting\" }\n | { kind: \"dismiss\" }\n | {\n kind: \"expired\";\n interrupt: Interrupt;\n }\n | {\n kind: \"legacy-resume\";\n payload: unknown;\n interruptValue: unknown;\n }\n | {\n kind: \"resume\";\n resume: ResumeEntry[];\n toolResults: ɵInterruptToolResult[];\n };\n\nfunction toolResultContent(response: ResumeResponse): string {\n if (response.status === \"cancelled\") {\n return JSON.stringify({ status: \"cancelled\" });\n }\n return JSON.stringify(response.payload ?? { status: \"resolved\" });\n}\n\n/**\n * @internal Framework-neutral interrupt response state shared by framework\n * adapters. Application authors must not depend on this API.\n */\nexport class ɵInterruptState<TValue = unknown> {\n readonly #responses: Record<string, ResumeResponse> = {};\n #pending: ɵPendingInterrupt<TValue> | null = null;\n #sealed = false;\n\n /** Return the active normalized interrupt without exposing mutable state. */\n get pending(): ɵPendingInterrupt<TValue> | null {\n const pending = this.#pending;\n if (pending?.kind === \"standard\") {\n return { kind: \"standard\", interrupts: [...pending.interrupts] };\n }\n return pending;\n }\n\n /** Replace the current interrupt with a legacy custom-event interrupt. */\n setLegacy(event: ɵInterruptEvent<TValue>): void {\n this.#replace({ kind: \"legacy\", event });\n }\n\n /** Replace the current interrupt with an AG-UI standard interrupt set. */\n setStandard(interrupts: readonly Interrupt[]): void {\n this.#replace({ kind: \"standard\", interrupts: [...interrupts] });\n }\n\n /** Clear all pending interrupt data and accumulated responses. */\n clear(): void {\n this.#pending = null;\n this.#sealed = false;\n for (const id of Object.keys(this.#responses)) delete this.#responses[id];\n }\n\n /** Record a resolved response and return the next framework action. */\n resolve(payload?: unknown, interruptId?: string): ɵInterruptDecision {\n const pending = this.#pending;\n if (!pending || this.#sealed) return { kind: \"ignored\" };\n if (pending.kind === \"legacy\") {\n this.#sealed = true;\n return {\n kind: \"legacy-resume\",\n payload,\n interruptValue: pending.event.value,\n };\n }\n return this.#respond(pending.interrupts, interruptId, {\n status: \"resolved\",\n payload,\n });\n }\n\n /** Record a cancelled response and return the next framework action. */\n cancel(interruptId?: string): ɵInterruptDecision {\n const pending = this.#pending;\n if (!pending || this.#sealed) return { kind: \"ignored\" };\n if (pending.kind === \"legacy\") {\n this.#sealed = true;\n return { kind: \"dismiss\" };\n }\n return this.#respond(pending.interrupts, interruptId, {\n status: \"cancelled\",\n });\n }\n\n #replace(pending: ɵPendingInterrupt<TValue>): void {\n this.clear();\n this.#pending = pending;\n }\n\n #respond(\n interrupts: readonly Interrupt[],\n interruptId: string | undefined,\n response: ResumeResponse,\n ): ɵInterruptDecision {\n const id = interruptId ?? interrupts[0]?.id;\n if (!id || !interrupts.some((interrupt) => interrupt.id === id)) {\n return { kind: \"ignored\" };\n }\n this.#responses[id] = response;\n if (!interrupts.every((interrupt) => this.#responses[interrupt.id])) {\n return { kind: \"waiting\" };\n }\n\n const expired = interrupts.find((interrupt) =>\n isInterruptExpired(interrupt),\n );\n if (expired) {\n this.#sealed = true;\n return { kind: \"expired\", interrupt: expired };\n }\n\n const mutableInterrupts = [...interrupts];\n const resume = buildResumeArray(mutableInterrupts, this.#responses);\n const toolResults = mutableInterrupts.flatMap((interrupt) => {\n if (!interrupt.toolCallId || interrupt.reason !== \"tool_call\") return [];\n return [\n {\n toolCallId: interrupt.toolCallId,\n content: toolResultContent(this.#responses[interrupt.id]!),\n },\n ];\n });\n this.#sealed = true;\n return { kind: \"resume\", resume, toolResults };\n }\n}\n","export const INSPECTOR_THREAD_BRIDGE_PLUGIN_ID =\n \"cpk-inspector-thread\" as const;\n\nconst EVENT_PREFIX = `copilotkit:${INSPECTOR_THREAD_BRIDGE_PLUGIN_ID}`;\n\ntype InspectorBridgeGlobal = typeof globalThis & {\n __COPILOTKIT_INSPECTOR_THREAD_EVENT_TARGET__?: EventTarget;\n};\n\nexport type InspectorViewThreadPayload = {\n requestId: string;\n threadId: string;\n agentId: string;\n};\n\nexport type InspectorStopViewingPayload = {\n requestId: string;\n agentId: string;\n};\n\nexport type InspectorActiveThreadPayload = {\n requestId: string;\n threadId: string;\n agentId: string;\n source: \"app\" | \"override\";\n};\n\nexport type InspectorViewThreadResultPayload =\n | {\n requestId: string;\n threadId: string;\n agentId: string;\n ok: true;\n }\n | {\n requestId: string;\n threadId: string;\n agentId: string;\n ok: false;\n reason: \"connect-failed\";\n };\n\ntype InspectorThreadBridgeEvents = {\n \"stop-viewing\": InspectorStopViewingPayload;\n \"active-thread\": InspectorActiveThreadPayload;\n \"view-thread-result\": InspectorViewThreadResultPayload;\n};\n\ntype ClaimableViewThreadEvent = {\n payload: InspectorViewThreadPayload;\n claimed: boolean;\n};\n\nfunction eventName(suffix: string): string {\n return `${EVENT_PREFIX}:${suffix}`;\n}\n\nfunction getEventTarget(): EventTarget | null {\n if (\n typeof window !== \"undefined\" &&\n typeof window.addEventListener === \"function\"\n ) {\n return window;\n }\n if (typeof EventTarget === \"undefined\") return null;\n // Shared by duplicate @copilotkit/core copies in non-browser test realms.\n // Browser copies use window itself as the shared event target.\n const sharedGlobal = globalThis as InspectorBridgeGlobal;\n sharedGlobal.__COPILOTKIT_INSPECTOR_THREAD_EVENT_TARGET__ ??=\n new EventTarget();\n return sharedGlobal.__COPILOTKIT_INSPECTOR_THREAD_EVENT_TARGET__;\n}\n\nfunction createDetailEvent<T>(name: string, detail: T): Event {\n if (typeof CustomEvent !== \"undefined\") {\n return new CustomEvent(name, { detail });\n }\n const event = new Event(name);\n Object.defineProperty(event, \"detail\", { value: detail });\n return event;\n}\n\nfunction detailFromEvent<T>(event: Event): T {\n return (event as Event & { detail: T }).detail;\n}\n\n/** The Inspector thread bridge is development-only. */\nexport function isInspectorThreadBridgeEnabled(): boolean {\n return process.env.NODE_ENV !== \"production\";\n}\n\nexport function createInspectorThreadRequestId(): string {\n if (typeof crypto !== \"undefined\" && \"randomUUID\" in crypto) {\n return crypto.randomUUID();\n }\n return `inspector-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n}\n\nfunction dispatch<K extends keyof InspectorThreadBridgeEvents>(\n suffix: K,\n payload: InspectorThreadBridgeEvents[K],\n): void {\n if (!isInspectorThreadBridgeEnabled()) return;\n const target = getEventTarget();\n if (!target) return;\n target.dispatchEvent(createDetailEvent(eventName(suffix), payload));\n}\n\nfunction on<K extends keyof InspectorThreadBridgeEvents>(\n suffix: K,\n handler: (payload: InspectorThreadBridgeEvents[K]) => void,\n): () => void {\n if (!isInspectorThreadBridgeEnabled()) return () => undefined;\n const target = getEventTarget();\n if (!target) return () => undefined;\n const listener = (event: Event) => {\n handler(detailFromEvent<InspectorThreadBridgeEvents[K]>(event));\n };\n const name = eventName(suffix);\n target.addEventListener(name, listener);\n return () => target.removeEventListener(name, listener);\n}\n\n/**\n * Ask the first mounted official chat for the matching agent to load a thread.\n * Returns false when no chat claims the request synchronously.\n */\nexport function emitInspectorViewThread(\n payload: InspectorViewThreadPayload,\n): boolean {\n if (!isInspectorThreadBridgeEnabled()) return false;\n const target = getEventTarget();\n if (!target) return false;\n const detail: ClaimableViewThreadEvent = { payload, claimed: false };\n target.dispatchEvent(createDetailEvent(eventName(\"view-thread\"), detail));\n return detail.claimed;\n}\n\nexport function emitInspectorStopViewing(\n payload: InspectorStopViewingPayload,\n): void {\n dispatch(\"stop-viewing\", payload);\n}\n\nexport function emitInspectorActiveThread(\n payload: InspectorActiveThreadPayload,\n): void {\n dispatch(\"active-thread\", payload);\n}\n\nexport function emitInspectorViewThreadResult(\n payload: InspectorViewThreadResultPayload,\n): void {\n dispatch(\"view-thread-result\", payload);\n}\n\nexport function onInspectorViewThread(\n handler: (payload: InspectorViewThreadPayload) => boolean,\n): () => void {\n if (!isInspectorThreadBridgeEnabled()) return () => undefined;\n const target = getEventTarget();\n if (!target) return () => undefined;\n const listener = (event: Event) => {\n const detail = detailFromEvent<ClaimableViewThreadEvent>(event);\n if (detail.claimed) return;\n detail.claimed = handler(detail.payload);\n };\n const name = eventName(\"view-thread\");\n target.addEventListener(name, listener);\n return () => target.removeEventListener(name, listener);\n}\n\nexport function onInspectorStopViewing(\n handler: (payload: InspectorStopViewingPayload) => void,\n): () => void {\n return on(\"stop-viewing\", handler);\n}\n\nexport function onInspectorActiveThread(\n handler: (payload: InspectorActiveThreadPayload) => void,\n): () => void {\n return on(\"active-thread\", handler);\n}\n\nexport function onInspectorViewThreadResult(\n handler: (payload: InspectorViewThreadResultPayload) => void,\n): () => void {\n return on(\"view-thread-result\", handler);\n}\n"],"mappings":"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"}
|