@ag-ui/client 0.1.1-canary.beta.0 → 1.0.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.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["EMPTY","EventType","jsonpatch","AGUIError","EventType","Observable","Subject","Subject","proto","Subject","ReplaySubject","proto","EventSchemas","EventType","z","EventType","jsonpatch","EventType","ReplaySubject","EventType","EventType","packageJson.version","Subject","AGUIConnectNotImplementedError","EMPTY","AGUIError","EventType","jsonpatch"],"sources":["../src/utils.ts","../src/agent/subscriber.ts","../src/agent/types.ts","../src/debug-logger.ts","../src/apply/default.ts","../src/verify/verify.ts","../src/run/http-request.ts","../src/transform/sse.ts","../src/transform/proto.ts","../src/transform/http.ts","../src/legacy/types.ts","../src/legacy/convert.ts","../src/chunks/transform.ts","../src/interrupts/index.ts","../src/middleware/middleware.ts","../src/middleware/filter-tool-calls.ts","../src/middleware/backward-compatibility-0-0-39.ts","../src/middleware/backward-compatibility-0-0-45.ts","../src/middleware/backward-compatibility-0-0-47.ts","../package.json","../src/agent/agent.ts","../src/agent/http.ts","../src/compact/compact.ts"],"sourcesContent":["import { v4 as uuidv4 } from \"uuid\";\n\nexport const structuredClone_ = <T>(obj: T): T => {\n if (typeof structuredClone === \"function\") {\n return structuredClone(obj);\n }\n\n try {\n return JSON.parse(JSON.stringify(obj));\n } catch (err) {\n // Preserve array vs object type in shallow fallback\n if (Array.isArray(obj)) {\n return [...obj] as unknown as T;\n }\n return { ...obj } as T;\n }\n};\n\n/**\n * Generate a random UUID v4\n * Cross-platform compatible (Node.js, browsers, React Native)\n */\nexport function randomUUID(): string {\n return uuidv4();\n}\n\n// Note: semver helpers were removed in favor of using\n// the external `compare-versions` library directly at call sites.\n\n/**\n * Parses a semantic version string into its numeric components.\n * Supports incomplete versions (e.g. \"1\", \"1.2\") by defaulting missing segments to zero.\n *\n * @throws If the version string is not a valid semantic version.\n */\n// (Intentionally left minimal.)\n","import {\n BaseEvent,\n Interrupt,\n Message,\n RunAgentInput,\n RunErrorEvent,\n RunFinishedEvent,\n RunStartedEvent,\n State,\n StateDeltaEvent,\n StateSnapshotEvent,\n StepFinishedEvent,\n StepStartedEvent,\n TextMessageContentEvent,\n TextMessageEndEvent,\n TextMessageStartEvent,\n ToolCallArgsEvent,\n ToolCallEndEvent,\n ToolCallResultEvent,\n ToolCallStartEvent,\n MessagesSnapshotEvent,\n RawEvent,\n CustomEvent,\n ToolCall,\n ActivitySnapshotEvent,\n ActivityDeltaEvent,\n ActivityMessage,\n ReasoningStartEvent,\n ReasoningMessageStartEvent,\n ReasoningMessageContentEvent,\n ReasoningMessageEndEvent,\n ReasoningEndEvent,\n ReasoningEncryptedValueEvent,\n} from \"@ag-ui/core\";\nimport { AbstractAgent } from \"./agent\";\nimport { structuredClone_ } from \"@/utils\";\n\nexport interface AgentStateMutation {\n messages?: Message[];\n state?: State;\n stopPropagation?: boolean;\n}\n\nexport interface AgentSubscriberParams {\n messages: ReadonlyArray<Readonly<Message>>;\n // NOTE: State resolves to `any` at the type level (z.infer<typeof z.any()>), so Readonly<State>\n // provides no compile-time mutation protection. Runtime enforcement via deepFreeze in\n // dev/test mode is the only guard against in-place mutation of state.\n state: Readonly<State>;\n agent: AbstractAgent;\n input: RunAgentInput;\n}\n\n// Utility type to allow callbacks to be implemented either synchronously or asynchronously.\nexport type MaybePromise<T> = T | Promise<T>;\n\nexport interface AgentSubscriber {\n // Request lifecycle\n onRunInitialized?(\n params: AgentSubscriberParams,\n ): MaybePromise<Omit<AgentStateMutation, \"stopPropagation\"> | void>;\n onRunFailed?(\n params: { error: Error } & AgentSubscriberParams,\n ): MaybePromise<Omit<AgentStateMutation, \"stopPropagation\"> | void>;\n onRunFinalized?(\n params: AgentSubscriberParams,\n ): MaybePromise<Omit<AgentStateMutation, \"stopPropagation\"> | void>;\n\n // Events\n onEvent?(\n params: { event: BaseEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onRunStartedEvent?(\n params: { event: RunStartedEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n onRunFinishedEvent?(\n params: (\n | { event: RunFinishedEvent; outcome: \"success\"; result?: unknown }\n | { event: RunFinishedEvent; outcome: \"interrupt\"; interrupts: Interrupt[] }\n ) &\n AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n onRunErrorEvent?(\n params: { event: RunErrorEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onStepStartedEvent?(\n params: { event: StepStartedEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n onStepFinishedEvent?(\n params: { event: StepFinishedEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onTextMessageStartEvent?(\n params: { event: TextMessageStartEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n onTextMessageContentEvent?(\n params: {\n event: TextMessageContentEvent;\n textMessageBuffer: string;\n } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n onTextMessageEndEvent?(\n params: { event: TextMessageEndEvent; textMessageBuffer: string } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onToolCallStartEvent?(\n params: { event: ToolCallStartEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n onToolCallArgsEvent?(\n params: {\n event: ToolCallArgsEvent;\n toolCallBuffer: string;\n toolCallName: string;\n partialToolCallArgs: Record<string, any>;\n } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n onToolCallEndEvent?(\n params: {\n event: ToolCallEndEvent;\n toolCallName: string;\n toolCallArgs: Record<string, any>;\n } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onToolCallResultEvent?(\n params: { event: ToolCallResultEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onStateSnapshotEvent?(\n params: { event: StateSnapshotEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onStateDeltaEvent?(\n params: { event: StateDeltaEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onMessagesSnapshotEvent?(\n params: { event: MessagesSnapshotEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onActivitySnapshotEvent?(\n params: {\n event: ActivitySnapshotEvent;\n activityMessage?: ActivityMessage;\n existingMessage?: Message;\n } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onActivityDeltaEvent?(\n params: {\n event: ActivityDeltaEvent;\n activityMessage?: ActivityMessage;\n } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onRawEvent?(\n params: { event: RawEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onCustomEvent?(\n params: { event: CustomEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n // Reasoning events\n onReasoningStartEvent?(\n params: { event: ReasoningStartEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onReasoningMessageStartEvent?(\n params: { event: ReasoningMessageStartEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onReasoningMessageContentEvent?(\n params: {\n event: ReasoningMessageContentEvent;\n reasoningMessageBuffer: string;\n } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onReasoningMessageEndEvent?(\n params: {\n event: ReasoningMessageEndEvent;\n reasoningMessageBuffer: string;\n } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onReasoningEndEvent?(\n params: { event: ReasoningEndEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onReasoningEncryptedValueEvent?(\n params: { event: ReasoningEncryptedValueEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n // State changes\n onMessagesChanged?(\n params: Omit<AgentSubscriberParams, \"input\"> & { input?: RunAgentInput },\n ): MaybePromise<void>;\n onStateChanged?(\n params: Omit<AgentSubscriberParams, \"input\"> & { input?: RunAgentInput },\n ): MaybePromise<void>;\n onNewMessage?(\n params: { message: Message } & Omit<AgentSubscriberParams, \"input\"> & {\n input?: RunAgentInput;\n },\n ): MaybePromise<void>;\n onNewToolCall?(\n params: { toolCall: ToolCall } & Omit<AgentSubscriberParams, \"input\"> & {\n input?: RunAgentInput;\n },\n ): MaybePromise<void>;\n}\n\nfunction deepFreeze<T>(obj: T): T {\n Object.freeze(obj);\n if (obj !== null && typeof obj === \"object\") {\n for (const value of Object.values(obj)) {\n if (value !== null && typeof value === \"object\" && !Object.isFrozen(value)) {\n deepFreeze(value);\n }\n }\n }\n return obj;\n}\n\n// Above this many string characters across messages+state, the dev-only\n// clone+deepFreeze guard is skipped. That guard exists to surface accidental\n// in-place mutation during development — it is NOT required for correctness.\n// Paying a full recursive structuredClone + deepFreeze of the entire messages\n// array AND state object on every streamed event is what exhausts the renderer\n// heap when tool-call arguments stream large payloads (V8 fatal:\n// \"JavaScript heap out of memory\" from structuredClone).\nconst DEV_FREEZE_CHAR_LIMIT = 512 * 1024;\n\n// Cheap, bounded size probe: returns true as soon as the combined string length\n// of messages+state (counting both string values AND object key names, since\n// keys also contribute to clone cost) exceeds `limit`. Does NOT recursively\n// structuredClone or materialize copies — only a bounded iterative traversal\n// stack plus a visited-set guard, so it is safe for arbitrarily nested or\n// cyclic structures. (`State` is typed `any`, so cycles are possible.)\nfunction payloadExceeds(messages: unknown, state: unknown, limit: number): boolean {\n let chars = 0;\n const stack: unknown[] = [messages, state];\n const seen = new WeakSet<object>();\n while (stack.length > 0) {\n const value = stack.pop();\n if (typeof value === \"string\") {\n chars += value.length;\n if (chars > limit) return true;\n } else if (value !== null && typeof value === \"object\") {\n if (seen.has(value as object)) continue;\n seen.add(value as object);\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) stack.push(value[i]);\n } else {\n // Own enumerable keys only — avoids walking the prototype chain and\n // triggering inherited getters (matches deepFreeze's Object.values).\n const keys = Object.keys(value as Record<string, unknown>);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n // Key names contribute to clone cost too; count them as we go.\n chars += key.length;\n if (chars > limit) return true;\n stack.push((value as Record<string, unknown>)[key]);\n }\n }\n }\n }\n return false;\n}\n\nexport async function runSubscribersWithMutation(\n subscribers: AgentSubscriber[],\n initialMessages: Message[],\n initialState: State,\n executor: (\n subscriber: AgentSubscriber,\n messages: ReadonlyArray<Readonly<Message>>,\n state: Readonly<State>,\n ) => MaybePromise<AgentStateMutation | void>,\n): Promise<AgentStateMutation> {\n const hasProcess = typeof process !== \"undefined\" && typeof process.env !== \"undefined\";\n const isTestEnvironment =\n hasProcess && (process.env.NODE_ENV === \"test\" || Boolean(process.env.VITEST_WORKER_ID));\n const isDev =\n hasProcess &&\n (process.env.NODE_ENV === \"development\" ||\n process.env.NODE_ENV === \"test\" ||\n Boolean(process.env.VITEST_WORKER_ID));\n\n // The dev-only clone+deepFreeze guard (which surfaces accidental in-place\n // mutation) is the dominant per-event allocation. Skip it in production, and\n // in dev when the payload is large — otherwise streaming large tool-call\n // arguments deep-clones the whole messages+state on every event and exhausts\n // the heap (V8 fatal: \"JavaScript heap out of memory\" from structuredClone).\n let freezeInputs = isDev && !payloadExceeds(initialMessages, initialState, DEV_FREEZE_CHAR_LIMIT);\n\n // Only the freeze path needs an isolated baseline copy. Otherwise pass the\n // inputs through and lazily clone only when a subscriber actually returns a\n // mutation — so the common \"no mutation\" event costs zero clones.\n let messages: Message[] = freezeInputs ? structuredClone_(initialMessages) : initialMessages;\n let state: State = freezeInputs ? structuredClone_(initialState) : initialState;\n let messagesMutated = false;\n let stateMutated = false;\n\n let stopPropagation: boolean | undefined = undefined;\n\n for (const subscriber of subscribers) {\n try {\n // Subscribers receive shared references and must not mutate them in-place.\n // Mutations should only be communicated via the return value.\n // In dev/test mode (small payloads): deep-freeze inputs so accidental\n // in-place mutations surface as TypeErrors immediately.\n if (freezeInputs) {\n deepFreeze(messages);\n deepFreeze(state);\n }\n const mutation = await executor(subscriber, messages, state);\n\n if (mutation === undefined) {\n // Nothing returned – keep going\n continue;\n }\n\n // Replace with a defensive copy of the subscriber's mutation,\n // but skip if the subscriber returned the same reference (no-op).\n let payloadChanged = false;\n if (mutation.messages !== undefined && mutation.messages !== messages) {\n messages = structuredClone_(mutation.messages);\n messagesMutated = true;\n payloadChanged = true;\n }\n\n if (mutation.state !== undefined && mutation.state !== state) {\n state = structuredClone_(mutation.state);\n stateMutated = true;\n payloadChanged = true;\n }\n\n // If a subscriber's mutation has grown the payload past the limit, drop\n // the freeze guard for the remaining iterations. Otherwise we'd pay a\n // full deepFreeze + final unfreeze-clone of the now-huge structure on\n // every later subscriber — exactly the cost this PR removes.\n if (freezeInputs && payloadChanged) {\n if (payloadExceeds(messages, state, DEV_FREEZE_CHAR_LIMIT)) {\n freezeInputs = false;\n }\n }\n\n stopPropagation = mutation.stopPropagation;\n\n if (stopPropagation === true) {\n break;\n }\n } catch (error) {\n if (isDev && error instanceof TypeError) {\n // Likely a freeze violation: subscriber attempted to mutate frozen inputs in-place.\n // In test environments, re-throw so tests fail fast and the violation is visible.\n // In development (non-test), log a specific message to distinguish freeze violations\n // from ordinary subscriber errors.\n if (isTestEnvironment) {\n throw error;\n }\n console.error(\n \"AG-UI: Subscriber attempted to mutate frozen inputs in-place. \" +\n \"Return mutations via AgentStateMutation instead of mutating directly.\",\n error,\n );\n } else if (!isTestEnvironment) {\n console.error(\"Subscriber error:\", error);\n }\n // Skip this subscriber's mutation and continue\n continue;\n }\n }\n\n // A mutated copy may have been frozen in-place on a later subscriber pass;\n // clone it before returning so callers receive a mutable copy.\n return {\n ...(messagesMutated\n ? { messages: Object.isFrozen(messages) ? structuredClone_(messages) : messages }\n : {}),\n ...(stateMutated\n ? { state: Object.isFrozen(state) ? structuredClone_(state) : state }\n : {}),\n ...(stopPropagation !== undefined ? { stopPropagation } : {}),\n };\n}\n","import { Message, ResumeEntry, RunAgentInput, State } from \"@ag-ui/core\";\n\n/** Normalized debug configuration for the AG-UI agent. */\nexport interface ResolvedAgentDebugConfig {\n enabled: boolean;\n events: boolean;\n lifecycle: boolean;\n verbose: boolean;\n}\n\n/** Debug input — boolean shorthand or granular config. */\nexport type AgentDebugConfig =\n | boolean\n | {\n events?: boolean;\n lifecycle?: boolean;\n verbose?: boolean;\n };\n\n/** Resolves an AgentDebugConfig into a normalized ResolvedAgentDebugConfig. */\nexport function resolveAgentDebugConfig(\n debug: AgentDebugConfig | undefined,\n): ResolvedAgentDebugConfig {\n if (!debug) return { enabled: false, events: false, lifecycle: false, verbose: false };\n if (debug === true) return { enabled: true, events: true, lifecycle: true, verbose: true };\n\n const events = debug.events ?? true;\n const lifecycle = debug.lifecycle ?? true;\n const verbose = debug.verbose ?? false;\n return { enabled: events || lifecycle, events, lifecycle, verbose };\n}\n\nexport interface AgentConfig {\n agentId?: string;\n description?: string;\n threadId?: string;\n initialMessages?: Message[];\n initialState?: State;\n debug?: AgentDebugConfig;\n}\n\nexport type HttpAgentFetchFn = (url: string, requestInit: RequestInit) => Promise<Response>;\n\nexport interface HttpAgentConfig extends AgentConfig {\n url: string;\n headers?: Record<string, string>;\n fetch?: HttpAgentFetchFn;\n}\n\nexport interface RunAgentParameters\n extends Partial<Pick<RunAgentInput, \"runId\" | \"tools\" | \"context\" | \"forwardedProps\">> {\n /** Per-interrupt responses addressing every open interrupt from the previous run. */\n resume?: ResumeEntry[];\n}\n","import { ResolvedAgentDebugConfig, resolveAgentDebugConfig } from \"@/agent/types\";\n\n/** Accepted input wherever a debug logger can be provided. */\nexport type DebugLoggerInput = DebugLogger | boolean | null | undefined;\n\n/**\n * Resolves a DebugLoggerInput into a DebugLogger or undefined.\n * - `true` → creates a new DebugLogger with all logging enabled\n * - `DebugLogger` instance → returned as-is\n * - `false`, `null`, `undefined` → returns undefined\n */\nexport function resolveDebugLogger(input: DebugLoggerInput): DebugLogger | undefined {\n if (input instanceof DebugLogger) return input;\n if (input === true) return new DebugLogger(resolveAgentDebugConfig(true));\n return undefined;\n}\n\n/**\n * Centralized debug logger for the AG-UI event pipeline.\n * Handles verbose vs summary output based on config.\n */\nexport class DebugLogger {\n constructor(private config: ResolvedAgentDebugConfig) {}\n\n /**\n * Log an event-level debug message.\n * Only logs when `config.events` is enabled.\n * In verbose mode, logs the full data; otherwise logs the summary.\n */\n event(prefix: string, label: string, data: unknown, summary?: Record<string, unknown>): void {\n if (!this.config.events) return;\n if (this.config.verbose) {\n console.debug(`[${prefix}] ${label}`, typeof data === \"string\" ? data : JSON.stringify(data));\n } else {\n console.debug(`[${prefix}] ${label}`, summary ?? data);\n }\n }\n\n /**\n * Log a lifecycle-level debug message.\n * Only logs when `config.lifecycle` is enabled.\n */\n lifecycle(prefix: string, label: string, data?: Record<string, unknown>): void {\n if (!this.config.lifecycle) return;\n if (data) {\n console.debug(`[${prefix}] ${label}`, data);\n } else {\n console.debug(`[${prefix}] ${label}`);\n }\n }\n\n /** Whether event-level logging is enabled. */\n get eventsEnabled(): boolean {\n return this.config.events;\n }\n\n /** Whether lifecycle-level logging is enabled. */\n get lifecycleEnabled(): boolean {\n return this.config.lifecycle;\n }\n\n /** Whether any logging is enabled. */\n get enabled(): boolean {\n return this.config.enabled;\n }\n}\n\n/**\n * Creates a DebugLogger if debug is enabled, otherwise returns undefined.\n * This allows consumers to pass it around cheaply when debug is off.\n */\nexport function createDebugLogger(config: ResolvedAgentDebugConfig): DebugLogger | undefined {\n return config.enabled ? new DebugLogger(config) : undefined;\n}\n","import type { AbstractAgent } from \"@/agent/agent\";\nimport {\n type AgentStateMutation,\n type AgentSubscriber,\n runSubscribersWithMutation,\n} from \"@/agent/subscriber\";\nimport {\n type ActivityDeltaEvent,\n type ActivityMessage,\n type ActivitySnapshotEvent,\n type AssistantMessage,\n type BaseEvent,\n type CustomEvent,\n DeveloperMessage,\n EventType,\n type Message,\n type MessagesSnapshotEvent,\n type RawEvent,\n type ReasoningEncryptedValueEvent,\n type ReasoningEndEvent,\n type ReasoningMessage,\n type ReasoningMessageContentEvent,\n type ReasoningMessageEndEvent,\n type ReasoningMessageStartEvent,\n type ReasoningStartEvent,\n type RunAgentInput,\n type RunErrorEvent,\n type RunFinishedEvent,\n type RunStartedEvent,\n type StateDeltaEvent,\n type StateSnapshotEvent,\n type StepFinishedEvent,\n type StepStartedEvent,\n SystemMessage,\n type TextMessageContentEvent,\n type TextMessageEndEvent,\n type TextMessageStartEvent,\n type ToolCallArgsEvent,\n type ToolCallEndEvent,\n type ToolCallResultEvent,\n type ToolCallStartEvent,\n type ToolMessage,\n UserMessage,\n} from \"@ag-ui/core\";\nimport jsonpatch from \"fast-json-patch\";\nimport { EMPTY, of } from \"rxjs\";\nimport type { Observable } from \"rxjs\";\nimport { concatMap, defaultIfEmpty, mergeAll, mergeMap } from \"rxjs/operators\";\nimport untruncateJson from \"untruncate-json\";\nimport { structuredClone_ } from \"../utils\";\nimport { type DebugLoggerInput, resolveDebugLogger } from \"@/debug-logger\";\n\n/**\n * Resolves (or creates) the assistant message that a tool call should attach to.\n *\n * Resolution order:\n * 1. `parentMessageId` matches an existing assistant message — return it.\n * 2. `parentMessageId` matches a non-assistant message (collision) — create new, keyed by `toolCallId`.\n * 3. `parentMessageId` not found — create new, keyed by `parentMessageId`.\n * 4. No `parentMessageId` — create new, keyed by `toolCallId`.\n */\nfunction resolveOrCreateAssistantMessage(\n messages: Message[],\n parentMessageId: string | undefined,\n toolCallId: string,\n): AssistantMessage {\n if (parentMessageId) {\n const existing = messages.find((m) => m.id === parentMessageId);\n if (existing?.role === \"assistant\") {\n return existing as AssistantMessage;\n }\n\n if (existing) {\n console.warn(\n `TOOL_CALL_START: parentMessageId '${parentMessageId}' matches a '${existing.role}' message, ` +\n `not assistant — falling back to toolCallId`,\n );\n }\n\n const created: AssistantMessage = {\n id: existing ? toolCallId : parentMessageId,\n role: \"assistant\",\n toolCalls: [],\n };\n messages.push(created);\n return created;\n }\n\n const created: AssistantMessage = { id: toolCallId, role: \"assistant\", toolCalls: [] };\n messages.push(created);\n return created;\n}\n\nexport const defaultApplyEvents = (\n input: RunAgentInput,\n events$: Observable<BaseEvent>,\n agent: AbstractAgent,\n subscribers: AgentSubscriber[],\n debugLogger?: DebugLoggerInput,\n): Observable<AgentStateMutation> => {\n const log = resolveDebugLogger(debugLogger);\n let messages = structuredClone_(agent.messages);\n let state = structuredClone_(input.state);\n let currentMutation: AgentStateMutation = {};\n\n const applyMutation = (mutation: AgentStateMutation) => {\n if (mutation.messages !== undefined) {\n messages = mutation.messages;\n currentMutation.messages = mutation.messages;\n }\n if (mutation.state !== undefined) {\n state = mutation.state;\n currentMutation.state = mutation.state;\n }\n };\n\n const emitUpdates = () => {\n const result = structuredClone_(currentMutation) as AgentStateMutation;\n currentMutation = {};\n if (result.messages !== undefined || result.state !== undefined) {\n return of(result);\n }\n return EMPTY;\n };\n\n return events$.pipe(\n concatMap(async (event) => {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onEvent?.({ event, agent, input, messages, state }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation === true) {\n log?.event(\"APPLY\", \"Event dropped:\", event, {\n type: event.type,\n reason: \"stopPropagation by subscriber\",\n });\n } else {\n log?.event(\"APPLY\", \"Event applied:\", event, {\n type: event.type,\n subscribers: subscribers.length,\n });\n }\n\n if (mutation.stopPropagation === true) {\n return emitUpdates();\n }\n\n switch (event.type) {\n case EventType.TEXT_MESSAGE_START: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onTextMessageStartEvent?.({\n event: event as TextMessageStartEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n const { messageId, role = \"assistant\", name } = event as TextMessageStartEvent;\n\n // Check if a message with this ID already exists (e.g., created by TOOL_CALL_START\n // with the same parentMessageId)\n const existingMessage = messages.find((m) => m.id === messageId);\n\n if (!existingMessage) {\n // Create a new message using properties from the event\n // Text messages can be developer, system, assistant, or user (not tool)\n const newMessage: Message = {\n id: messageId,\n role: role,\n content: \"\",\n ...(name !== undefined && { name }),\n };\n\n // Add the new message to the messages array\n messages.push(newMessage);\n applyMutation({ messages });\n }\n // If message already exists, we don't need to create a new one\n // The TEXT_MESSAGE_CONTENT events will update the existing message's content\n }\n return emitUpdates();\n }\n\n case EventType.TEXT_MESSAGE_CONTENT: {\n const { messageId, delta } = event as TextMessageContentEvent;\n\n // Find the target message by ID\n const targetMessage = messages.find((m) => m.id === messageId);\n if (!targetMessage) {\n console.warn(`TEXT_MESSAGE_CONTENT: No message found with ID '${messageId}'`);\n return emitUpdates();\n }\n\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onTextMessageContentEvent?.({\n event: event as TextMessageContentEvent,\n messages,\n state,\n agent,\n input,\n textMessageBuffer:\n typeof targetMessage.content === \"string\" ? targetMessage.content : \"\",\n }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n // Append content to the correct message by ID\n const existingContent =\n typeof targetMessage.content === \"string\" ? targetMessage.content : \"\";\n targetMessage.content = `${existingContent}${delta}`;\n applyMutation({ messages });\n }\n\n return emitUpdates();\n }\n\n case EventType.TEXT_MESSAGE_END: {\n const { messageId } = event as TextMessageEndEvent;\n\n // Find the target message by ID\n const targetMessage = messages.find((m) => m.id === messageId);\n if (!targetMessage) {\n console.warn(`TEXT_MESSAGE_END: No message found with ID '${messageId}'`);\n return emitUpdates();\n }\n\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onTextMessageEndEvent?.({\n event: event as TextMessageEndEvent,\n messages,\n state,\n agent,\n input,\n textMessageBuffer:\n typeof targetMessage.content === \"string\" ? targetMessage.content : \"\",\n }),\n );\n applyMutation(mutation);\n\n await Promise.all(\n subscribers.map((subscriber) => {\n subscriber.onNewMessage?.({\n message: targetMessage,\n messages,\n state,\n agent,\n input,\n });\n }),\n );\n\n return emitUpdates();\n }\n\n case EventType.TOOL_CALL_START: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onToolCallStartEvent?.({\n event: event as ToolCallStartEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n const { toolCallId, toolCallName, parentMessageId } = event as ToolCallStartEvent;\n\n const targetMessage = resolveOrCreateAssistantMessage(\n messages,\n parentMessageId,\n toolCallId,\n );\n\n targetMessage.toolCalls ??= [];\n\n // Add the new tool call\n targetMessage.toolCalls.push({\n id: toolCallId,\n type: \"function\",\n function: {\n name: toolCallName,\n arguments: \"\",\n },\n });\n\n applyMutation({ messages });\n }\n\n return emitUpdates();\n }\n\n case EventType.TOOL_CALL_ARGS: {\n const { toolCallId, delta } = event as ToolCallArgsEvent;\n\n // Find the message containing this tool call\n const targetMessage = messages.find((m) =>\n (m as AssistantMessage).toolCalls?.some((tc) => tc.id === toolCallId),\n ) as AssistantMessage;\n\n if (!targetMessage) {\n console.warn(\n `TOOL_CALL_ARGS: No message found containing tool call with ID '${toolCallId}'`,\n );\n return emitUpdates();\n }\n\n // Find the specific tool call\n const targetToolCall = targetMessage.toolCalls?.find((tc) => tc.id === toolCallId);\n if (!targetToolCall) {\n console.warn(`TOOL_CALL_ARGS: No tool call found with ID '${toolCallId}'`);\n return emitUpdates();\n }\n\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) => {\n const toolCallBuffer = targetToolCall.function.arguments;\n const toolCallName = targetToolCall.function.name;\n let partialToolCallArgs = {};\n try {\n // Parse from toolCallBuffer only (before current delta is applied)\n partialToolCallArgs = untruncateJson(toolCallBuffer);\n } catch (error) {}\n\n return subscriber.onToolCallArgsEvent?.({\n event: event as ToolCallArgsEvent,\n messages,\n state,\n agent,\n input,\n toolCallBuffer,\n toolCallName,\n partialToolCallArgs,\n });\n },\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n // Append the arguments to the correct tool call by ID\n targetToolCall.function.arguments += delta;\n applyMutation({ messages });\n }\n\n return emitUpdates();\n }\n\n case EventType.TOOL_CALL_END: {\n const { toolCallId } = event as ToolCallEndEvent;\n\n // Find the message containing this tool call\n const targetMessage = messages.find((m) =>\n (m as AssistantMessage).toolCalls?.some((tc) => tc.id === toolCallId),\n ) as AssistantMessage;\n\n if (!targetMessage) {\n console.warn(\n `TOOL_CALL_END: No message found containing tool call with ID '${toolCallId}'`,\n );\n return emitUpdates();\n }\n\n // Find the specific tool call\n const targetToolCall = targetMessage.toolCalls?.find((tc) => tc.id === toolCallId);\n if (!targetToolCall) {\n console.warn(`TOOL_CALL_END: No tool call found with ID '${toolCallId}'`);\n return emitUpdates();\n }\n\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) => {\n const toolCallArgsString = targetToolCall.function.arguments;\n const toolCallName = targetToolCall.function.name;\n let toolCallArgs = {};\n try {\n toolCallArgs = JSON.parse(toolCallArgsString);\n } catch (error) {}\n return subscriber.onToolCallEndEvent?.({\n event: event as ToolCallEndEvent,\n messages,\n state,\n agent,\n input,\n toolCallName,\n toolCallArgs,\n });\n },\n );\n applyMutation(mutation);\n\n await Promise.all(\n subscribers.map((subscriber) => {\n subscriber.onNewToolCall?.({\n toolCall: targetToolCall,\n messages,\n state,\n agent,\n input,\n });\n }),\n );\n\n return emitUpdates();\n }\n\n case EventType.TOOL_CALL_RESULT: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onToolCallResultEvent?.({\n event: event as ToolCallResultEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n const { messageId, toolCallId, content, role } = event as ToolCallResultEvent;\n\n const toolMessage: ToolMessage = {\n id: messageId,\n toolCallId,\n role: role || \"tool\",\n content: content,\n };\n\n // Place the tool result immediately after the assistant message that\n // issued the matching tool call — not at the end. A result event can\n // arrive after a trailing assistant text message (e.g. a\n // chat -> tool -> chat loop streams the follow-up text before the\n // result is recorded). Appending would leave the history as\n // assistant(tool_call) -> text -> tool, which violates the provider\n // contract that an assistant tool_call is immediately followed by its\n // tool result and surfaces downstream as a 400. Skip past any tool\n // results already recorded for the same assistant so parallel results\n // keep their order. Fall back to append when no owner is found.\n const ownerIndex = messages.findIndex(\n (m) =>\n m.role === \"assistant\" &&\n (m as AssistantMessage).toolCalls?.some((tc) => tc.id === toolCallId),\n );\n if (ownerIndex === -1) {\n messages.push(toolMessage);\n } else {\n let insertAt = ownerIndex + 1;\n while (insertAt < messages.length && messages[insertAt].role === \"tool\") {\n insertAt++;\n }\n messages.splice(insertAt, 0, toolMessage);\n }\n\n await Promise.all(\n subscribers.map((subscriber) => {\n subscriber.onNewMessage?.({\n message: toolMessage,\n messages,\n state,\n agent,\n input,\n });\n }),\n );\n\n applyMutation({ messages });\n }\n\n return emitUpdates();\n }\n\n case EventType.STATE_SNAPSHOT: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onStateSnapshotEvent?.({\n event: event as StateSnapshotEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n const { snapshot } = event as StateSnapshotEvent;\n\n // Replace state with the literal snapshot\n state = snapshot;\n\n applyMutation({ state });\n }\n\n return emitUpdates();\n }\n\n case EventType.STATE_DELTA: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onStateDeltaEvent?.({\n event: event as StateDeltaEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n const { delta } = event as StateDeltaEvent;\n\n try {\n // Apply the JSON Patch operations to the current state without mutating the original\n const result = jsonpatch.applyPatch(state, delta, true, false);\n state = result.newDocument;\n applyMutation({ state });\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.warn(\n `Failed to apply state patch:\\nCurrent state: ${JSON.stringify(state, null, 2)}\\nPatch operations: ${JSON.stringify(delta, null, 2)}\\nError: ${errorMessage}`,\n );\n // If patch failed, only emit updates if there were subscriber mutations\n // This prevents emitting updates when both patch fails AND no subscriber mutations\n }\n }\n\n return emitUpdates();\n }\n\n case EventType.MESSAGES_SNAPSHOT: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onMessagesSnapshotEvent?.({\n event: event as MessagesSnapshotEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n const { messages: newMessages } = event as MessagesSnapshotEvent;\n\n // Edit-based merge: update existing messages with snapshot data while\n // preserving client-only messages the backend leaves out of the\n // snapshot.\n const snapshotMap = new Map(newMessages.map((m) => [m.id, m]));\n\n // `activity` messages are only sometimes client-only. They never\n // travel back to the backend — `prepareRunAgentInput` strips them\n // from RunAgentInput — so a backend that does not track them cannot\n // put them in the snapshot, and the local copies must be preserved.\n // But a backend that does track them re-delivers the whole set it\n // owns. Since a MESSAGES_SNAPSHOT is a snapshot of every message,\n // once it carries any activity the backend is declaring the complete\n // activity set, and one it leaves out has been removed — preserving\n // it would make the local copy undeletable. So when the snapshot\n // itself carries activity, treat it as the source of truth for\n // activity messages and apply the normal replace semantics.\n //\n // `reasoning` messages are only sometimes client-only. Most backends\n // never include reasoning in the snapshot (it exists purely as\n // streamed REASONING_* events), so dropping local reasoning here\n // would lose it. But a backend that round-trips reasoning (e.g.\n // LangGraph re-deriving it from checkpointed content blocks)\n // re-delivers the streamed reasoning under its own canonical id —\n // message ids are generally NOT stable between streamed events and\n // the snapshot. Preserving the streamed copy next to the snapshot\n // copy would render the same reasoning twice. So when the snapshot\n // itself carries reasoning, treat it as the source of truth for\n // reasoning messages too and apply the normal replace semantics.\n const snapshotHasActivity = newMessages.some((m) => m.role === \"activity\");\n const snapshotHasReasoning = newMessages.some((m) => m.role === \"reasoning\");\n const isPreservedClientOnly = (m: Message) =>\n (m.role === \"activity\" && !snapshotHasActivity) ||\n (m.role === \"reasoning\" && !snapshotHasReasoning);\n\n // Step 1 + 2: Keep preserved client-only messages as-is, keep\n // messages present in the snapshot (replaced with snapshot version),\n // drop everything else.\n messages = messages\n .filter((m) => isPreservedClientOnly(m) || snapshotMap.has(m.id))\n .map((m) => (isPreservedClientOnly(m) ? m : snapshotMap.get(m.id)!));\n\n // Step 3: Append messages from the snapshot that we don't have yet.\n const existingIds = new Set(messages.map((m) => m.id));\n for (const snapshotMsg of newMessages) {\n if (!existingIds.has(snapshotMsg.id)) {\n messages.push(snapshotMsg);\n }\n }\n\n applyMutation({ messages });\n }\n\n return emitUpdates();\n }\n\n case EventType.ACTIVITY_SNAPSHOT: {\n const activityEvent = event as ActivitySnapshotEvent;\n const existingIndex = messages.findIndex((m) => m.id === activityEvent.messageId);\n const existingMessage = existingIndex >= 0 ? messages[existingIndex] : undefined;\n const existingActivityMessage =\n existingMessage?.role === \"activity\" ? (existingMessage as ActivityMessage) : undefined;\n const replace = activityEvent.replace ?? true;\n\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onActivitySnapshotEvent?.({\n event: activityEvent,\n messages,\n state,\n agent,\n input,\n activityMessage: existingActivityMessage,\n existingMessage,\n }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n const activityMessage: ActivityMessage = {\n id: activityEvent.messageId,\n role: \"activity\",\n activityType: activityEvent.activityType,\n content: structuredClone_(activityEvent.content),\n };\n\n let createdMessage: ActivityMessage | undefined;\n\n if (existingIndex === -1) {\n messages.push(activityMessage);\n createdMessage = activityMessage;\n } else if (existingActivityMessage) {\n if (replace) {\n messages[existingIndex] = {\n ...existingActivityMessage,\n activityType: activityEvent.activityType,\n content: structuredClone_(activityEvent.content),\n };\n }\n } else if (replace) {\n messages[existingIndex] = activityMessage;\n createdMessage = activityMessage;\n }\n\n applyMutation({ messages });\n\n if (createdMessage) {\n await Promise.all(\n subscribers.map((subscriber) =>\n subscriber.onNewMessage?.({\n message: createdMessage,\n messages,\n state,\n agent,\n input,\n }),\n ),\n );\n }\n }\n\n return emitUpdates();\n }\n\n case EventType.ACTIVITY_DELTA: {\n const activityEvent = event as ActivityDeltaEvent;\n const existingIndex = messages.findIndex((m) => m.id === activityEvent.messageId);\n if (existingIndex === -1) {\n return emitUpdates();\n }\n\n const existingMessage = messages[existingIndex];\n if (existingMessage.role !== \"activity\") {\n console.warn(\n `ACTIVITY_DELTA: Message '${activityEvent.messageId}' is not an activity message`,\n );\n return emitUpdates();\n }\n\n const existingActivityMessage = existingMessage as ActivityMessage;\n\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onActivityDeltaEvent?.({\n event: activityEvent,\n messages,\n state,\n agent,\n input,\n activityMessage: existingActivityMessage,\n }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n try {\n const baseContent = structuredClone_(existingActivityMessage.content ?? {});\n\n const result = jsonpatch.applyPatch(\n baseContent,\n activityEvent.patch ?? [],\n true,\n false,\n );\n const updatedContent = result.newDocument as ActivityMessage[\"content\"];\n\n messages[existingIndex] = {\n ...existingActivityMessage,\n content: structuredClone_(updatedContent),\n activityType: activityEvent.activityType,\n };\n\n applyMutation({ messages });\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.warn(\n `Failed to apply activity patch for '${activityEvent.messageId}': ${errorMessage}`,\n );\n }\n }\n\n return emitUpdates();\n }\n\n case EventType.RAW: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onRawEvent?.({\n event: event as RawEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n return emitUpdates();\n }\n\n case EventType.CUSTOM: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onCustomEvent?.({\n event: event as CustomEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n return emitUpdates();\n }\n\n case EventType.RUN_STARTED: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onRunStartedEvent?.({\n event: event as RunStartedEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n // Handle input.messages if present and stopPropagation is not set\n if (mutation.stopPropagation !== true) {\n const runStartedEvent = event as RunStartedEvent;\n\n // Check if the event contains input with messages\n if (runStartedEvent.input?.messages) {\n // Add messages that aren't already present (checked by ID)\n for (const message of runStartedEvent.input.messages) {\n const existingMessage = messages.find((m) => m.id === message.id);\n if (!existingMessage) {\n messages.push(message);\n }\n }\n\n // Apply mutation to emit the updated messages\n applyMutation({ messages });\n }\n }\n\n return emitUpdates();\n }\n\n case EventType.RUN_FINISHED: {\n const e = event as RunFinishedEvent;\n const finishedParams =\n e.outcome?.type === \"interrupt\"\n ? ({\n event: e,\n outcome: \"interrupt\" as const,\n interrupts: e.outcome.interrupts,\n } as const)\n : ({ event: e, outcome: \"success\" as const, result: e.result } as const);\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onRunFinishedEvent?.({\n ...finishedParams,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n // Update pending interrupts AFTER subscribers run, and only if no\n // subscriber suppressed the event — matches the lifecycle pattern\n // used by every other case in this switch. Defensive-copy the\n // interrupt list so consumers that hold the original event payload\n // can't mutate the agent's tracked state through array aliasing.\n if (mutation.stopPropagation !== true) {\n agent.pendingInterrupts =\n finishedParams.outcome === \"interrupt\" ? [...finishedParams.interrupts] : [];\n }\n\n return emitUpdates();\n }\n\n case EventType.RUN_ERROR: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onRunErrorEvent?.({\n event: event as RunErrorEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n return emitUpdates();\n }\n\n case EventType.STEP_STARTED: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onStepStartedEvent?.({\n event: event as StepStartedEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n return emitUpdates();\n }\n\n case EventType.STEP_FINISHED: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onStepFinishedEvent?.({\n event: event as StepFinishedEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n return emitUpdates();\n }\n\n case EventType.TEXT_MESSAGE_CHUNK: {\n throw new Error(\"TEXT_MESSAGE_CHUNK must be tranformed before being applied\");\n }\n\n case EventType.TOOL_CALL_CHUNK: {\n throw new Error(\"TOOL_CALL_CHUNK must be tranformed before being applied\");\n }\n\n case EventType.THINKING_START: {\n return emitUpdates();\n }\n\n case EventType.THINKING_END: {\n return emitUpdates();\n }\n\n case EventType.THINKING_TEXT_MESSAGE_START: {\n return emitUpdates();\n }\n\n case EventType.THINKING_TEXT_MESSAGE_CONTENT: {\n return emitUpdates();\n }\n\n case EventType.THINKING_TEXT_MESSAGE_END: {\n return emitUpdates();\n }\n\n case EventType.REASONING_START: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onReasoningStartEvent?.({\n event: event as ReasoningStartEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n return emitUpdates();\n }\n\n case EventType.REASONING_MESSAGE_START: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onReasoningMessageStartEvent?.({\n event: event as ReasoningMessageStartEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n const { messageId } = event as ReasoningMessageStartEvent;\n const existingMessage = messages.find((m) => m.id === messageId);\n\n if (!existingMessage) {\n const newMessage: ReasoningMessage = {\n id: messageId,\n role: \"reasoning\",\n content: \"\",\n };\n messages.push(newMessage);\n applyMutation({ messages });\n }\n }\n return emitUpdates();\n }\n\n case EventType.REASONING_MESSAGE_CONTENT: {\n const { messageId, delta } = event as ReasoningMessageContentEvent;\n\n const targetMessage = messages.find((m) => m.id === messageId);\n if (!targetMessage) {\n console.warn(`REASONING_MESSAGE_CONTENT: No message found with ID '${messageId}'`);\n return emitUpdates();\n }\n\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onReasoningMessageContentEvent?.({\n event: event as ReasoningMessageContentEvent,\n messages,\n state,\n agent,\n input,\n reasoningMessageBuffer:\n typeof targetMessage.content === \"string\" ? targetMessage.content : \"\",\n }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n const existingContent =\n typeof targetMessage.content === \"string\" ? targetMessage.content : \"\";\n targetMessage.content = `${existingContent}${delta}`;\n applyMutation({ messages });\n }\n return emitUpdates();\n }\n\n case EventType.REASONING_MESSAGE_END: {\n const { messageId } = event as ReasoningMessageEndEvent;\n\n const targetMessage = messages.find((m) => m.id === messageId);\n if (!targetMessage) {\n console.warn(`REASONING_MESSAGE_END: No message found with ID '${messageId}'`);\n return emitUpdates();\n }\n\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onReasoningMessageEndEvent?.({\n event: event as ReasoningMessageEndEvent,\n messages,\n state,\n agent,\n input,\n reasoningMessageBuffer:\n typeof targetMessage.content === \"string\" ? targetMessage.content : \"\",\n }),\n );\n applyMutation(mutation);\n\n await Promise.all(\n subscribers.map((subscriber) => {\n subscriber.onNewMessage?.({\n message: targetMessage,\n messages,\n state,\n agent,\n input,\n });\n }),\n );\n\n return emitUpdates();\n }\n\n case EventType.REASONING_MESSAGE_CHUNK: {\n throw new Error(\"REASONING_MESSAGE_CHUNK must be transformed before being applied\");\n }\n\n case EventType.REASONING_END: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onReasoningEndEvent?.({\n event: event as ReasoningEndEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n return emitUpdates();\n }\n\n case EventType.REASONING_ENCRYPTED_VALUE: {\n const { subtype, entityId, encryptedValue } = event as ReasoningEncryptedValueEvent;\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onReasoningEncryptedValueEvent?.({\n event: event as ReasoningEncryptedValueEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n if (mutation.stopPropagation !== true) {\n let entityUpdated = false;\n if (subtype === \"tool-call\") {\n // Find tool call by entityId and set encryptedValue\n for (const message of messages) {\n if (message.role === \"assistant\" && message.toolCalls) {\n const toolCall = message.toolCalls.find((tc) => tc.id === entityId);\n if (toolCall) {\n toolCall.encryptedValue = encryptedValue;\n entityUpdated = true;\n break;\n }\n }\n }\n } else {\n // subtype is \"message\"\n // Find message by entityId and set encryptedValue\n const message = messages.find((m) => m.id === entityId);\n // Activity messages do not have encryptedValue\n if (message?.role !== \"activity\" && message) {\n message.encryptedValue = encryptedValue;\n entityUpdated = true;\n }\n }\n if (entityUpdated) {\n currentMutation.messages = messages;\n }\n }\n return emitUpdates();\n }\n }\n\n // This makes TypeScript check that the switch is exhaustive\n // If a new EventType is added, this will cause a compile error\n const _exhaustiveCheck: never = event.type;\n return emitUpdates();\n }),\n mergeAll(),\n // Only use defaultIfEmpty when there are subscribers to avoid emitting empty updates\n // when patches fail and there are no subscribers (like in state patching test)\n subscribers.length > 0 ? defaultIfEmpty({} as AgentStateMutation) : (stream: any) => stream,\n );\n};\n","import { BaseEvent, EventType, AGUIError } from \"@ag-ui/core\";\nimport { Observable, throwError, of } from \"rxjs\";\nimport { mergeMap } from \"rxjs/operators\";\nimport { type DebugLoggerInput, resolveDebugLogger } from \"@/debug-logger\";\n\nexport const verifyEvents =\n (debugLogger?: DebugLoggerInput) =>\n (source$: Observable<BaseEvent>): Observable<BaseEvent> => {\n const log = resolveDebugLogger(debugLogger);\n // Declare variables in closure to maintain state across events\n let activeMessages = new Map<string, boolean>(); // Map of message ID -> active status\n let activeToolCalls = new Map<string, boolean>(); // Map of tool call ID -> active status\n let runFinished = false;\n let runError = false; // New flag to track if RUN_ERROR has been sent\n // New flags to track first/last event requirements\n let firstEventReceived = false;\n // Track active steps\n let activeSteps = new Map<string, boolean>(); // Map of step name -> active status\n let activeThinkingStep = false;\n let activeThinkingStepMessage = false;\n let runStarted = false; // Track if a run has started\n\n // Function to reset state for a new run\n const resetRunState = () => {\n activeMessages.clear();\n activeToolCalls.clear();\n activeSteps.clear();\n activeThinkingStep = false;\n activeThinkingStepMessage = false;\n runFinished = false;\n runError = false;\n runStarted = true;\n };\n\n return source$.pipe(\n // Process each event through our state machine\n mergeMap((event) => {\n const eventType = event.type;\n\n log?.event(\"VERIFY\", \"Event:\", event, { type: event.type });\n\n // Check if run has errored\n if (runError) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send event type '${eventType}': The run has already errored with 'RUN_ERROR'. No further events can be sent.`,\n ),\n );\n }\n\n // Check if run has already finished (but allow new RUN_STARTED to start a new run)\n if (\n runFinished &&\n eventType !== EventType.RUN_ERROR &&\n eventType !== EventType.RUN_STARTED\n ) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send event type '${eventType}': The run has already finished with 'RUN_FINISHED'. Start a new run with 'RUN_STARTED'.`,\n ),\n );\n }\n\n // Handle first event requirement and sequential RUN_STARTED\n if (!firstEventReceived) {\n firstEventReceived = true;\n if (eventType !== EventType.RUN_STARTED && eventType !== EventType.RUN_ERROR) {\n return throwError(() => new AGUIError(`First event must be 'RUN_STARTED'`));\n }\n } else if (eventType === EventType.RUN_STARTED) {\n // Allow RUN_STARTED after RUN_FINISHED (new run), but not during an active run\n if (runStarted && !runFinished) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'RUN_STARTED' while a run is still active. The previous run must be finished with 'RUN_FINISHED' before starting a new run.`,\n ),\n );\n }\n // If we're here, it's either the first RUN_STARTED or a new run after RUN_FINISHED\n if (runFinished) {\n // This is a new run after the previous one finished, reset state\n resetRunState();\n }\n }\n\n // Validate event based on type and current state\n switch (eventType) {\n // Text message flow\n case EventType.TEXT_MESSAGE_START: {\n const messageId = (event as any).messageId;\n\n // Check if this message is already in progress\n if (activeMessages.has(messageId)) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'TEXT_MESSAGE_START' event: A text message with ID '${messageId}' is already in progress. Complete it with 'TEXT_MESSAGE_END' first.`,\n ),\n );\n }\n\n activeMessages.set(messageId, true);\n return of(event);\n }\n\n case EventType.TEXT_MESSAGE_CONTENT: {\n const messageId = (event as any).messageId;\n\n // Must be in a message with this ID\n if (!activeMessages.has(messageId)) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'TEXT_MESSAGE_CONTENT' event: No active text message found with ID '${messageId}'. Start a text message with 'TEXT_MESSAGE_START' first.`,\n ),\n );\n }\n\n return of(event);\n }\n\n case EventType.TEXT_MESSAGE_END: {\n const messageId = (event as any).messageId;\n\n // Must be in a message with this ID\n if (!activeMessages.has(messageId)) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'TEXT_MESSAGE_END' event: No active text message found with ID '${messageId}'. A 'TEXT_MESSAGE_START' event must be sent first.`,\n ),\n );\n }\n\n // Remove message from active set\n activeMessages.delete(messageId);\n return of(event);\n }\n\n // Tool call flow\n case EventType.TOOL_CALL_START: {\n const toolCallId = (event as any).toolCallId;\n\n // Check if this tool call is already in progress\n if (activeToolCalls.has(toolCallId)) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'TOOL_CALL_START' event: A tool call with ID '${toolCallId}' is already in progress. Complete it with 'TOOL_CALL_END' first.`,\n ),\n );\n }\n\n activeToolCalls.set(toolCallId, true);\n return of(event);\n }\n\n case EventType.TOOL_CALL_ARGS: {\n const toolCallId = (event as any).toolCallId;\n\n // Must be in a tool call with this ID\n if (!activeToolCalls.has(toolCallId)) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'TOOL_CALL_ARGS' event: No active tool call found with ID '${toolCallId}'. Start a tool call with 'TOOL_CALL_START' first.`,\n ),\n );\n }\n\n return of(event);\n }\n\n case EventType.TOOL_CALL_END: {\n const toolCallId = (event as any).toolCallId;\n\n // Must be in a tool call with this ID\n if (!activeToolCalls.has(toolCallId)) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'TOOL_CALL_END' event: No active tool call found with ID '${toolCallId}'. A 'TOOL_CALL_START' event must be sent first.`,\n ),\n );\n }\n\n // Remove tool call from active set\n activeToolCalls.delete(toolCallId);\n return of(event);\n }\n\n // Step flow\n case EventType.STEP_STARTED: {\n const stepName = (event as any).stepName;\n if (activeSteps.has(stepName)) {\n return throwError(\n () => new AGUIError(`Step \"${stepName}\" is already active for 'STEP_STARTED'`),\n );\n }\n activeSteps.set(stepName, true);\n return of(event);\n }\n\n case EventType.STEP_FINISHED: {\n const stepName = (event as any).stepName;\n if (!activeSteps.has(stepName)) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'STEP_FINISHED' for step \"${stepName}\" that was not started`,\n ),\n );\n }\n activeSteps.delete(stepName);\n return of(event);\n }\n\n // Run flow\n case EventType.RUN_STARTED: {\n // We've already validated this above\n runStarted = true;\n return of(event);\n }\n\n case EventType.RUN_FINISHED: {\n // Can't be the first event (already checked)\n // and can't happen after already being finished (already checked)\n\n // Check that all steps are finished before run ends\n if (activeSteps.size > 0) {\n const unfinishedSteps = Array.from(activeSteps.keys()).join(\", \");\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'RUN_FINISHED' while steps are still active: ${unfinishedSteps}`,\n ),\n );\n }\n\n // Check that all messages are finished before run ends\n if (activeMessages.size > 0) {\n const unfinishedMessages = Array.from(activeMessages.keys()).join(\", \");\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'RUN_FINISHED' while text messages are still active: ${unfinishedMessages}`,\n ),\n );\n }\n\n // Check that all tool calls are finished before run ends\n if (activeToolCalls.size > 0) {\n const unfinishedToolCalls = Array.from(activeToolCalls.keys()).join(\", \");\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'RUN_FINISHED' while tool calls are still active: ${unfinishedToolCalls}`,\n ),\n );\n }\n\n runFinished = true;\n return of(event);\n }\n\n case EventType.RUN_ERROR: {\n // RUN_ERROR can happen at any time\n runError = true; // Set flag to prevent any further events\n return of(event);\n }\n\n case EventType.CUSTOM: {\n return of(event);\n }\n\n // Text message flow\n case EventType.THINKING_TEXT_MESSAGE_START: {\n if (!activeThinkingStep) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'THINKING_TEXT_MESSAGE_START' event: A thinking step is not in progress. Create one with 'THINKING_START' first.`,\n ),\n );\n }\n // Can't start a message if one is already in progress\n if (activeThinkingStepMessage) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'THINKING_TEXT_MESSAGE_START' event: A thinking message is already in progress. Complete it with 'THINKING_TEXT_MESSAGE_END' first.`,\n ),\n );\n }\n\n activeThinkingStepMessage = true;\n return of(event);\n }\n\n case EventType.THINKING_TEXT_MESSAGE_CONTENT: {\n // Must be in a message and IDs must match\n if (!activeThinkingStepMessage) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'THINKING_TEXT_MESSAGE_CONTENT' event: No active thinking message found. Start a message with 'THINKING_TEXT_MESSAGE_START' first.`,\n ),\n );\n }\n\n return of(event);\n }\n\n case EventType.THINKING_TEXT_MESSAGE_END: {\n // Must be in a message and IDs must match\n if (!activeThinkingStepMessage) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'THINKING_TEXT_MESSAGE_END' event: No active thinking message found. A 'THINKING_TEXT_MESSAGE_START' event must be sent first.`,\n ),\n );\n }\n\n // Reset message state\n activeThinkingStepMessage = false;\n return of(event);\n }\n\n case EventType.THINKING_START: {\n if (activeThinkingStep) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'THINKING_START' event: A thinking step is already in progress. End it with 'THINKING_END' first.`,\n ),\n );\n }\n\n activeThinkingStep = true;\n return of(event);\n }\n\n case EventType.THINKING_END: {\n // Must be in a message and IDs must match\n if (!activeThinkingStep) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'THINKING_END' event: No active thinking step found. A 'THINKING_START' event must be sent first.`,\n ),\n );\n }\n\n // Reset message state\n activeThinkingStep = false;\n return of(event);\n }\n\n default: {\n return of(event);\n }\n }\n }),\n );\n };\n","import { Observable, from, defer, throwError } from \"rxjs\";\nimport { mergeMap, switchMap } from \"rxjs/operators\";\n\nexport enum HttpEventType {\n HEADERS = \"headers\",\n DATA = \"data\",\n}\n\nexport interface HttpDataEvent {\n type: HttpEventType.DATA;\n data?: Uint8Array;\n}\n\nexport interface HttpHeadersEvent {\n type: HttpEventType.HEADERS;\n status: number;\n headers: Headers;\n}\n\nexport type HttpEvent = HttpDataEvent | HttpHeadersEvent;\n\nexport const runHttpRequest = (\n fetchResponse: () => Promise<Response>,\n): Observable<HttpEvent> => {\n // Defer the fetch so that it's executed when subscribed to\n return defer(() => from(fetchResponse())).pipe(\n switchMap((response) => {\n if (!response.ok) {\n const contentType = response.headers.get(\"content-type\") || \"\";\n // Read the (small) error body once, then error the stream\n return from(response.text()).pipe(\n mergeMap((text) => {\n let payload: unknown = text;\n if (contentType.includes(\"application/json\")) {\n try { payload = JSON.parse(text); } catch {/* keep raw text */}\n }\n const err: any = new Error(\n `HTTP ${response.status}: ${typeof payload === \"string\" ? payload : JSON.stringify(payload)}`\n );\n err.status = response.status;\n err.payload = payload;\n return throwError(() => err);\n })\n );\n }\n // Emit headers event first\n const headersEvent: HttpHeadersEvent = {\n type: HttpEventType.HEADERS,\n status: response.status,\n headers: response.headers,\n };\n\n const reader = response.body?.getReader();\n if (!reader) {\n return throwError(() => new Error(\"Failed to getReader() from response\"));\n }\n\n return new Observable<HttpEvent>((subscriber) => {\n // Emit headers event first\n subscriber.next(headersEvent);\n\n (async () => {\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n // Emit data event instead of raw Uint8Array\n const dataEvent: HttpDataEvent = {\n type: HttpEventType.DATA,\n data: value,\n };\n subscriber.next(dataEvent);\n }\n subscriber.complete();\n } catch (error) {\n subscriber.error(error);\n }\n })();\n\n return () => {\n reader.cancel().catch((error) => {\n if ((error as DOMException)?.name === \"AbortError\") {\n return;\n }\n\n throw error;\n });\n };\n });\n }),\n );\n};\n","import { Observable, Subject } from \"rxjs\";\nimport { HttpEvent, HttpEventType } from \"../run/http-request\";\nimport { type DebugLoggerInput, resolveDebugLogger } from \"@/debug-logger\";\n\n/**\n * Parses a stream of HTTP events into a stream of JSON objects using Server-Sent Events (SSE) format.\n * Strictly follows the SSE standard where:\n * - Events are separated by double newlines ('\\n\\n')\n * - Only 'data:' prefixed lines are processed\n * - Multi-line data events are supported and joined\n * - Non-data fields (event, id, retry) are ignored\n */\nexport const parseSSEStream = (\n source$: Observable<HttpEvent>,\n debugLogger?: DebugLoggerInput,\n): Observable<any> => {\n const log = resolveDebugLogger(debugLogger);\n const jsonSubject = new Subject<any>();\n // Create TextDecoder with stream option set to true to handle split UTF-8 characters\n const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n let buffer = \"\";\n\n // Subscribe to the source once and multicast to all subscribers\n source$.subscribe({\n next: (event: HttpEvent) => {\n if (event.type === HttpEventType.HEADERS) {\n return;\n }\n\n if (event.type === HttpEventType.DATA && event.data) {\n // Decode chunk carefully to handle UTF-8\n const text = decoder.decode(event.data, { stream: true });\n buffer += text;\n\n // Process complete events (separated by double newlines)\n const events = buffer.split(/\\n\\n/);\n // Keep the last potentially incomplete event in buffer\n buffer = events.pop() || \"\";\n\n for (const event of events) {\n processSSEEvent(event);\n }\n }\n },\n error: (err) => jsonSubject.error(err),\n complete: () => {\n // Use the final call to decoder.decode() to flush any remaining bytes\n if (buffer) {\n buffer += decoder.decode();\n // Process any remaining SSE event data\n processSSEEvent(buffer);\n }\n jsonSubject.complete();\n },\n });\n\n /**\n * Helper function to process an SSE event.\n * Extracts and joins data lines, then parses the result as JSON.\n *\n * Follows the SSE spec by processing lines starting with 'data:',\n * ignoring a single space if it is present after the colon.\n *\n * @param eventText The raw event text to process\n */\n function processSSEEvent(eventText: string) {\n const lines = eventText.split(\"\\n\");\n const dataLines: string[] = [];\n\n for (const line of lines) {\n if (line.startsWith(\"data:\")) {\n // Remove 'data:' prefix, and optionally a single space afterwards\n dataLines.push(line.slice(5).replace(/^ /, \"\"));\n }\n }\n\n // Only process if we have data lines\n if (dataLines.length > 0) {\n try {\n // Join multi-line data and parse JSON\n const jsonStr = dataLines.join(\"\\n\");\n const json = JSON.parse(jsonStr);\n log?.event(\"SSE\", \"Event received:\", json, { type: json.type });\n jsonSubject.next(json);\n } catch (err) {\n jsonSubject.error(err);\n }\n }\n }\n\n return jsonSubject.asObservable();\n};\n","import { Observable, Subject } from \"rxjs\";\nimport { HttpEvent, HttpEventType } from \"../run/http-request\";\nimport { BaseEvent } from \"@ag-ui/core\";\nimport * as proto from \"@ag-ui/proto\";\n\n/**\n * Parses a stream of HTTP events into a stream of BaseEvent objects using Protocol Buffer format.\n * Each message is prefixed with a 4-byte length header (uint32 in big-endian format)\n * followed by the protocol buffer encoded message.\n */\nexport const parseProtoStream = (source$: Observable<HttpEvent>): Observable<BaseEvent> => {\n const eventSubject = new Subject<BaseEvent>();\n let buffer = new Uint8Array(0);\n\n source$.subscribe({\n next: (event: HttpEvent) => {\n if (event.type === HttpEventType.HEADERS) {\n return;\n }\n\n if (event.type === HttpEventType.DATA && event.data) {\n // Append the new data to our buffer\n const newBuffer = new Uint8Array(buffer.length + event.data.length);\n newBuffer.set(buffer, 0);\n newBuffer.set(event.data, buffer.length);\n buffer = newBuffer;\n\n // Process as many complete messages as possible\n processBuffer();\n }\n },\n error: (err) => eventSubject.error(err),\n complete: () => {\n // Try to process any remaining data in the buffer\n if (buffer.length > 0) {\n try {\n processBuffer();\n } catch (error: unknown) {\n console.warn(\"Incomplete or invalid protocol buffer data at stream end\");\n }\n }\n eventSubject.complete();\n },\n });\n\n /**\n * Process as many complete messages as possible from the buffer\n */\n function processBuffer() {\n // Keep processing while we have enough data for at least a header (4 bytes)\n while (buffer.length >= 4) {\n // Read message length from the first 4 bytes (big-endian uint32)\n const view = new DataView(buffer.buffer, buffer.byteOffset, 4);\n const messageLength = view.getUint32(0, false); // false = big-endian\n\n // Check if we have the complete message (header + message body)\n const totalLength = 4 + messageLength;\n if (buffer.length < totalLength) {\n // Not enough data yet, wait for more\n break;\n }\n\n try {\n // Extract the message (skipping the 4-byte header)\n const message = buffer.slice(4, totalLength);\n\n // Decode the protocol buffer message using the imported decode function\n const event = proto.decode(message);\n\n // Emit the parsed event\n eventSubject.next(event);\n\n // Remove the processed message from the buffer\n buffer = buffer.slice(totalLength);\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n eventSubject.error(new Error(`Failed to decode protocol buffer message: ${errorMessage}`));\n return;\n }\n }\n }\n\n return eventSubject.asObservable();\n};\n","import type { BaseEvent } from \"@ag-ui/core\";\nimport { EventType } from \"@ag-ui/core\";\nimport { EventSchemas } from \"@ag-ui/core/schemas\";\nimport { Subject, ReplaySubject, Observable } from \"rxjs\";\nimport { HttpEvent, HttpEventType } from \"../run/http-request\";\nimport { parseSSEStream } from \"./sse\";\nimport { parseProtoStream } from \"./proto\";\nimport * as proto from \"@ag-ui/proto\";\nimport { type DebugLoggerInput, resolveDebugLogger } from \"@/debug-logger\";\n\n/**\n * Transforms HTTP events into BaseEvents using the appropriate format parser based on content type.\n */\nexport const transformHttpEventStream = (\n source$: Observable<HttpEvent>,\n debugLogger?: DebugLoggerInput,\n): Observable<BaseEvent> => {\n const log = resolveDebugLogger(debugLogger);\n const eventSubject = new Subject<BaseEvent>();\n\n // Use ReplaySubject to buffer events until we decide on the parser\n const bufferSubject = new ReplaySubject<HttpEvent>();\n\n // Flag to track whether we've set up the parser\n let parserInitialized = false;\n\n // Subscribe to source and buffer events while we determine the content type\n source$.subscribe({\n next: (event: HttpEvent) => {\n // Forward event to buffer\n bufferSubject.next(event);\n\n // If we get headers and haven't initialized a parser yet, check content type\n if (event.type === HttpEventType.HEADERS && !parserInitialized) {\n parserInitialized = true;\n const contentType = event.headers.get(\"content-type\");\n\n log?.lifecycle(\"HTTP\", \"Stream format detected:\", {\n contentType,\n parser: contentType === proto.AGUI_MEDIA_TYPE ? \"protobuf\" : \"sse\",\n });\n\n // Choose parser based on content type\n if (contentType === proto.AGUI_MEDIA_TYPE) {\n // Use protocol buffer parser\n parseProtoStream(bufferSubject).subscribe({\n next: (event) => eventSubject.next(event),\n error: (err) => eventSubject.error(err),\n complete: () => eventSubject.complete(),\n });\n } else {\n // Use SSE JSON parser for all other cases\n parseSSEStream(bufferSubject, log).subscribe({\n next: (json) => {\n try {\n const parsedEvent = EventSchemas.parse(json);\n log?.event(\"HTTP\", \"Event validated:\", parsedEvent, {\n type: parsedEvent.type,\n valid: true,\n });\n eventSubject.next(parsedEvent as BaseEvent);\n } catch (err) {\n log?.event(\"HTTP\", \"Event invalid:\", { json, error: String(err) });\n eventSubject.error(err);\n }\n },\n error: (err) => {\n if ((err as DOMException)?.name === \"AbortError\") {\n eventSubject.next({\n type: EventType.RUN_ERROR,\n message: (err as DOMException).message || \"Request aborted\",\n code: \"abort\",\n rawEvent: err,\n });\n eventSubject.complete();\n return;\n }\n return eventSubject.error(err);\n },\n complete: () => eventSubject.complete(),\n });\n }\n } else if (!parserInitialized) {\n eventSubject.error(new Error(\"No headers event received before data events\"));\n }\n },\n error: (err) => {\n bufferSubject.error(err);\n eventSubject.error(err);\n },\n complete: () => {\n bufferSubject.complete();\n },\n });\n\n return eventSubject.asObservable();\n};\n","import { z } from \"zod/v4\";\n\n// Protocol Events\nexport const LegacyRuntimeEventTypes = z.enum([\n \"TextMessageStart\",\n \"TextMessageContent\",\n \"TextMessageEnd\",\n \"ActionExecutionStart\",\n \"ActionExecutionArgs\",\n \"ActionExecutionEnd\",\n \"ActionExecutionResult\",\n \"AgentStateMessage\",\n \"MetaEvent\",\n \"RunStarted\",\n \"RunFinished\",\n \"RunError\",\n \"NodeStarted\",\n \"NodeFinished\",\n]);\n\nexport const LegacyRuntimeMetaEventName = z.enum([\n \"LangGraphInterruptEvent\",\n \"PredictState\",\n \"Exit\",\n]);\n\nexport const LegacyTextMessageStart = z.object({\n type: z.literal(LegacyRuntimeEventTypes.enum.TextMessageStart),\n messageId: z.string(),\n parentMessageId: z.string().optional(),\n role: z.string().optional(),\n});\n\nexport const LegacyTextMessageContent = z.object({\n type: z.literal(LegacyRuntimeEventTypes.enum.TextMessageContent),\n messageId: z.string(),\n content: z.string(),\n});\n\nexport const LegacyTextMessageEnd = z.object({\n type: z.literal(LegacyRuntimeEventTypes.enum.TextMessageEnd),\n messageId: z.string(),\n});\n\nexport const LegacyActionExecutionStart = z.object({\n type: z.literal(LegacyRuntimeEventTypes.enum.ActionExecutionStart),\n actionExecutionId: z.string(),\n actionName: z.string(),\n parentMessageId: z.string().optional(),\n});\n\nexport const LegacyActionExecutionArgs = z.object({\n type: z.literal(LegacyRuntimeEventTypes.enum.ActionExecutionArgs),\n actionExecutionId: z.string(),\n args: z.string(),\n});\n\nexport const LegacyActionExecutionEnd = z.object({\n type: z.literal(LegacyRuntimeEventTypes.enum.ActionExecutionEnd),\n actionExecutionId: z.string(),\n});\n\nexport const LegacyActionExecutionResult = z.object({\n type: z.literal(LegacyRuntimeEventTypes.enum.ActionExecutionResult),\n actionName: z.string(),\n actionExecutionId: z.string(),\n result: z.string(),\n});\n\nexport const LegacyAgentStateMessage = z.object({\n type: z.literal(LegacyRuntimeEventTypes.enum.AgentStateMessage),\n threadId: z.string(),\n agentName: z.string(),\n nodeName: z.string(),\n runId: z.string(),\n active: z.boolean(),\n role: z.string(),\n state: z.string(),\n running: z.boolean(),\n});\n\nexport const LegacyMetaEvent = z.object({\n type: z.literal(LegacyRuntimeEventTypes.enum.MetaEvent),\n name: LegacyRuntimeMetaEventName,\n value: z.any(),\n});\n\n\nexport const LegacyRunError = z.object({\n type: z.literal(LegacyRuntimeEventTypes.enum.RunError),\n message: z.string(),\n code: z.string().optional(),\n});\n\nexport const LegacyRuntimeProtocolEvent = z.discriminatedUnion(\"type\", [\n LegacyTextMessageStart,\n LegacyTextMessageContent,\n LegacyTextMessageEnd,\n LegacyActionExecutionStart,\n LegacyActionExecutionArgs,\n LegacyActionExecutionEnd,\n LegacyActionExecutionResult,\n LegacyAgentStateMessage,\n LegacyMetaEvent,\n LegacyRunError,\n]);\n\n// Protocol Event type exports\nexport type RuntimeEventTypes = z.infer<typeof LegacyRuntimeEventTypes>;\nexport type RuntimeMetaEventName = z.infer<typeof LegacyRuntimeMetaEventName>;\nexport type LegacyTextMessageStart = z.infer<typeof LegacyTextMessageStart>;\nexport type LegacyTextMessageContent = z.infer<typeof LegacyTextMessageContent>;\nexport type LegacyTextMessageEnd = z.infer<typeof LegacyTextMessageEnd>;\nexport type LegacyActionExecutionStart = z.infer<typeof LegacyActionExecutionStart>;\nexport type LegacyActionExecutionArgs = z.infer<typeof LegacyActionExecutionArgs>;\nexport type LegacyActionExecutionEnd = z.infer<typeof LegacyActionExecutionEnd>;\nexport type LegacyActionExecutionResult = z.infer<typeof LegacyActionExecutionResult>;\nexport type LegacyAgentStateMessage = z.infer<typeof LegacyAgentStateMessage>;\nexport type LegacyMetaEvent = z.infer<typeof LegacyMetaEvent>;\nexport type LegacyRuntimeProtocolEvent = z.infer<typeof LegacyRuntimeProtocolEvent>;\nexport type LegacyRunError = z.infer<typeof LegacyRunError>;\n\n// Message schemas (with kind discriminator)\nexport const LegacyTextMessageSchema = z.object({\n id: z.string(),\n role: z.string(),\n content: z.string(),\n parentMessageId: z.string().optional(),\n});\n\nexport const LegacyActionExecutionMessageSchema = z.object({\n id: z.string(),\n name: z.string(),\n arguments: z.any(),\n parentMessageId: z.string().optional(),\n});\n\nexport const LegacyResultMessageSchema = z.object({\n id: z.string(),\n result: z.any(),\n actionExecutionId: z.string(),\n actionName: z.string(),\n});\n\n// Message type exports\nexport type LegacyTextMessage = z.infer<typeof LegacyTextMessageSchema>;\nexport type LegacyActionExecutionMessage = z.infer<typeof LegacyActionExecutionMessageSchema>;\nexport type LegacyResultMessage = z.infer<typeof LegacyResultMessageSchema>;\nexport type LegacyMessage = LegacyTextMessage | LegacyActionExecutionMessage | LegacyResultMessage;\n","import { mergeMap } from \"rxjs/operators\";\nimport jsonpatch from \"fast-json-patch\";\n\nimport {\n BaseEvent,\n EventType,\n TextMessageStartEvent,\n TextMessageContentEvent,\n TextMessageEndEvent,\n ToolCallStartEvent,\n ToolCallArgsEvent,\n ToolCallEndEvent,\n ToolCallResultEvent,\n CustomEvent,\n StateSnapshotEvent,\n StepStartedEvent,\n Message,\n StateDeltaEvent,\n MessagesSnapshotEvent,\n ToolCall,\n RunErrorEvent,\n} from \"@ag-ui/core\";\nimport { Observable } from \"rxjs\";\nimport {\n LegacyTextMessageStart,\n LegacyTextMessageContent,\n LegacyTextMessageEnd,\n LegacyActionExecutionStart,\n LegacyActionExecutionArgs,\n LegacyActionExecutionEnd,\n LegacyRuntimeEventTypes,\n LegacyRuntimeProtocolEvent,\n LegacyMetaEvent,\n LegacyAgentStateMessage,\n LegacyMessage,\n LegacyTextMessage,\n LegacyActionExecutionMessage,\n LegacyResultMessage,\n LegacyActionExecutionResult,\n LegacyRunError\n} from \"./types\";\nimport untruncateJson from \"untruncate-json\";\n\nconst flattenMessageContentToText = (content: Message[\"content\"]) => {\n if (typeof content === \"string\") {\n return content;\n }\n\n if (!Array.isArray(content)) {\n return undefined;\n }\n\n const textParts = content\n .filter((part): part is { type: \"text\"; text: string } => part.type === \"text\")\n .map((part) => part.text)\n .filter((text) => text.length > 0);\n\n if (textParts.length === 0) {\n return undefined;\n }\n\n return textParts.join(\"\\n\");\n};\n\ninterface PredictStateValue {\n state_key: string;\n tool: string;\n tool_argument: string;\n}\n\nexport const convertToLegacyEvents =\n (threadId: string, runId: string, agentName: string) =>\n (events$: Observable<BaseEvent>): Observable<LegacyRuntimeProtocolEvent> => {\n let currentState: any = {};\n let running = true;\n let active = true;\n let nodeName = \"\";\n let syncedMessages: Message[] | null = null;\n let predictState: PredictStateValue[] | null = null;\n let currentToolCalls: ToolCall[] = [];\n let toolCallNames: Record<string, string> = {};\n\n const updateCurrentState = (newState: any) => {\n // the legacy protocol will only support object state\n if (typeof newState === \"object\" && newState !== null) {\n if (\"messages\" in newState) {\n delete newState.messages;\n }\n currentState = newState;\n }\n };\n\n return events$.pipe(\n mergeMap((event) => {\n switch (event.type) {\n case EventType.TEXT_MESSAGE_START: {\n const startEvent = event as TextMessageStartEvent;\n return [\n {\n type: LegacyRuntimeEventTypes.enum.TextMessageStart,\n messageId: startEvent.messageId,\n role: startEvent.role,\n } as LegacyTextMessageStart,\n ];\n }\n case EventType.TEXT_MESSAGE_CONTENT: {\n const contentEvent = event as TextMessageContentEvent;\n return [\n {\n type: LegacyRuntimeEventTypes.enum.TextMessageContent,\n messageId: contentEvent.messageId,\n content: contentEvent.delta,\n } as LegacyTextMessageContent,\n ];\n }\n case EventType.TEXT_MESSAGE_END: {\n const endEvent = event as TextMessageEndEvent;\n return [\n {\n type: LegacyRuntimeEventTypes.enum.TextMessageEnd,\n messageId: endEvent.messageId,\n } as LegacyTextMessageEnd,\n ];\n }\n case EventType.TOOL_CALL_START: {\n const startEvent = event as ToolCallStartEvent;\n\n currentToolCalls.push({\n id: startEvent.toolCallId,\n type: \"function\",\n function: {\n name: startEvent.toolCallName,\n arguments: \"\",\n },\n });\n\n active = true;\n toolCallNames[startEvent.toolCallId] = startEvent.toolCallName;\n\n return [\n {\n type: LegacyRuntimeEventTypes.enum.ActionExecutionStart,\n actionExecutionId: startEvent.toolCallId,\n actionName: startEvent.toolCallName,\n parentMessageId: startEvent.parentMessageId,\n } as LegacyActionExecutionStart,\n ];\n }\n case EventType.TOOL_CALL_ARGS: {\n const argsEvent = event as ToolCallArgsEvent;\n\n // Find the tool call by ID instead of using the last one\n const currentToolCall = currentToolCalls.find((tc) => tc.id === argsEvent.toolCallId);\n if (!currentToolCall) {\n console.warn(`TOOL_CALL_ARGS: No tool call found with ID '${argsEvent.toolCallId}'`);\n return [];\n }\n\n currentToolCall.function.arguments += argsEvent.delta;\n let didUpdateState = false;\n\n if (predictState) {\n let currentPredictState = predictState.find(\n (s) => s.tool == currentToolCall.function.name,\n );\n\n if (currentPredictState) {\n try {\n const currentArgs = JSON.parse(\n untruncateJson(currentToolCall.function.arguments),\n );\n if (\n currentPredictState.tool_argument &&\n currentPredictState.tool_argument in currentArgs\n ) {\n updateCurrentState({\n ...currentState,\n [currentPredictState.state_key]:\n currentArgs[currentPredictState.tool_argument],\n });\n didUpdateState = true;\n } else if (!currentPredictState.tool_argument) {\n updateCurrentState({\n ...currentState,\n [currentPredictState.state_key]: currentArgs,\n });\n didUpdateState = true;\n }\n } catch (e) {}\n }\n }\n\n return [\n {\n type: LegacyRuntimeEventTypes.enum.ActionExecutionArgs,\n actionExecutionId: argsEvent.toolCallId,\n args: argsEvent.delta,\n } as LegacyActionExecutionArgs,\n ...(didUpdateState\n ? [\n {\n type: LegacyRuntimeEventTypes.enum.AgentStateMessage,\n threadId,\n agentName,\n nodeName,\n runId,\n running,\n role: \"assistant\",\n state: JSON.stringify(currentState),\n active,\n },\n ]\n : []),\n ];\n }\n case EventType.TOOL_CALL_END: {\n const endEvent = event as ToolCallEndEvent;\n return [\n {\n type: LegacyRuntimeEventTypes.enum.ActionExecutionEnd,\n actionExecutionId: endEvent.toolCallId,\n } as LegacyActionExecutionEnd,\n ];\n }\n case EventType.TOOL_CALL_RESULT: {\n const resultEvent = event as ToolCallResultEvent;\n return [\n {\n type: LegacyRuntimeEventTypes.enum.ActionExecutionResult,\n actionExecutionId: resultEvent.toolCallId,\n result: resultEvent.content,\n actionName: toolCallNames[resultEvent.toolCallId] || \"unknown\",\n } as LegacyActionExecutionResult,\n ];\n }\n case EventType.RAW: {\n // The legacy protocol doesn't support raw events\n return [];\n }\n case EventType.CUSTOM: {\n const customEvent = event as CustomEvent;\n switch (customEvent.name) {\n case \"Exit\":\n running = false;\n break;\n case \"PredictState\":\n predictState = customEvent.value as PredictStateValue[];\n break;\n }\n\n return [\n {\n type: LegacyRuntimeEventTypes.enum.MetaEvent,\n name: customEvent.name,\n value: customEvent.value,\n } as LegacyMetaEvent,\n ];\n }\n case EventType.STATE_SNAPSHOT: {\n const stateEvent = event as StateSnapshotEvent;\n updateCurrentState(stateEvent.snapshot);\n\n return [\n {\n type: LegacyRuntimeEventTypes.enum.AgentStateMessage,\n threadId,\n agentName,\n nodeName,\n runId,\n running,\n role: \"assistant\",\n state: JSON.stringify(currentState),\n active,\n } as LegacyAgentStateMessage,\n ];\n }\n case EventType.STATE_DELTA: {\n const deltaEvent = event as StateDeltaEvent;\n const result = jsonpatch.applyPatch(currentState, deltaEvent.delta, true, false);\n if (!result) {\n return [];\n }\n updateCurrentState(result.newDocument);\n\n return [\n {\n type: LegacyRuntimeEventTypes.enum.AgentStateMessage,\n threadId,\n agentName,\n nodeName,\n runId,\n running,\n role: \"assistant\",\n state: JSON.stringify(currentState),\n active,\n } as LegacyAgentStateMessage,\n ];\n }\n case EventType.MESSAGES_SNAPSHOT: {\n const messagesSnapshot = event as MessagesSnapshotEvent;\n syncedMessages = messagesSnapshot.messages;\n return [\n {\n type: LegacyRuntimeEventTypes.enum.AgentStateMessage,\n threadId,\n agentName,\n nodeName,\n runId,\n running,\n role: \"assistant\",\n state: JSON.stringify({\n ...currentState,\n ...(syncedMessages ? { messages: syncedMessages } : {}),\n }),\n active: true,\n } as LegacyAgentStateMessage,\n ];\n }\n case EventType.RUN_STARTED: {\n // There is nothing to do in the legacy protocol\n return [];\n }\n case EventType.RUN_FINISHED: {\n if (syncedMessages) {\n currentState.messages = syncedMessages;\n }\n\n // Only do an update if state is not empty\n if (Object.keys(currentState).length === 0) {\n return [];\n }\n\n return [\n {\n type: LegacyRuntimeEventTypes.enum.AgentStateMessage,\n threadId,\n agentName,\n nodeName,\n runId,\n running,\n role: \"assistant\",\n state: JSON.stringify({\n ...currentState,\n ...(syncedMessages\n ? {\n messages: convertMessagesToLegacyFormat(syncedMessages),\n }\n : {}),\n }),\n active: false,\n } as LegacyAgentStateMessage,\n ];\n }\n case EventType.RUN_ERROR: {\n const errorEvent = event as RunErrorEvent;\n return [\n {\n type: LegacyRuntimeEventTypes.enum.RunError,\n message: errorEvent.message,\n code: errorEvent.code,\n } as LegacyRunError,\n ];\n }\n case EventType.STEP_STARTED: {\n const stepStarted = event as StepStartedEvent;\n nodeName = stepStarted.stepName;\n\n currentToolCalls = [];\n predictState = null;\n\n return [\n {\n type: LegacyRuntimeEventTypes.enum.AgentStateMessage,\n threadId,\n agentName,\n nodeName,\n runId,\n running,\n role: \"assistant\",\n state: JSON.stringify(currentState),\n active: true,\n } as LegacyAgentStateMessage,\n ];\n }\n case EventType.STEP_FINISHED: {\n currentToolCalls = [];\n predictState = null;\n\n return [\n {\n type: LegacyRuntimeEventTypes.enum.AgentStateMessage,\n threadId,\n agentName,\n nodeName,\n runId,\n running,\n role: \"assistant\",\n state: JSON.stringify(currentState),\n active: false,\n } as LegacyAgentStateMessage,\n ];\n }\n default: {\n return [];\n }\n }\n }),\n );\n };\n\nexport function convertMessagesToLegacyFormat(messages: Message[]): LegacyMessage[] {\n const result: LegacyMessage[] = [];\n\n for (const message of messages) {\n if (message.role === \"assistant\" || message.role === \"user\" || message.role === \"system\") {\n const textContent = flattenMessageContentToText(message.content);\n if (textContent) {\n const textMessage: LegacyTextMessage = {\n id: message.id,\n role: message.role,\n content: textContent,\n };\n result.push(textMessage);\n }\n if (message.role === \"assistant\" && message.toolCalls && message.toolCalls.length > 0) {\n for (const toolCall of message.toolCalls) {\n const actionExecutionMessage: LegacyActionExecutionMessage = {\n id: toolCall.id,\n name: toolCall.function.name,\n arguments: JSON.parse(toolCall.function.arguments),\n parentMessageId: message.id,\n };\n result.push(actionExecutionMessage);\n }\n }\n } else if (message.role === \"tool\") {\n let actionName = \"unknown\";\n for (const m of messages) {\n if (m.role === \"assistant\" && m.toolCalls?.length) {\n for (const toolCall of m.toolCalls) {\n if (toolCall.id === message.toolCallId) {\n actionName = toolCall.function.name;\n break;\n }\n }\n }\n }\n const toolMessage: LegacyResultMessage = {\n id: message.id,\n result: message.content,\n actionExecutionId: message.toolCallId,\n actionName,\n };\n result.push(toolMessage);\n }\n }\n\n return result;\n}\n","import { mergeMap, Observable, finalize } from \"rxjs\";\nimport {\n BaseEvent,\n TextMessageChunkEvent,\n TextMessageContentEvent,\n TextMessageEndEvent,\n TextMessageStartEvent,\n ToolCallArgsEvent,\n ToolCallChunkEvent,\n ToolCallEndEvent,\n ToolCallStartEvent,\n ReasoningMessageChunkEvent,\n ReasoningMessageContentEvent,\n ReasoningMessageEndEvent,\n ReasoningMessageStartEvent,\n} from \"@ag-ui/core\";\nimport { EventType } from \"@ag-ui/core\";\nimport { type DebugLoggerInput, resolveDebugLogger } from \"@/debug-logger\";\n\ninterface TextMessageFields {\n messageId: string;\n name?: string;\n}\n\ninterface ToolCallFields {\n toolCallId: string;\n toolCallName: string;\n parentMessageId?: string;\n}\n\ninterface ReasoningMessageFields {\n messageId: string;\n}\n\nexport const transformChunks =\n (debugLogger?: DebugLoggerInput) =>\n (events$: Observable<BaseEvent>): Observable<BaseEvent> => {\n const log = resolveDebugLogger(debugLogger);\n let textMessageFields: TextMessageFields | undefined;\n let toolCallFields: ToolCallFields | undefined;\n let reasoningMessageFields: ReasoningMessageFields | undefined;\n let mode: \"text\" | \"tool\" | \"reasoning\" | undefined;\n\n const closeTextMessage = () => {\n if (!textMessageFields || mode !== \"text\") {\n throw new Error(\"No text message to close\");\n }\n const event = {\n type: EventType.TEXT_MESSAGE_END,\n messageId: textMessageFields.messageId,\n } as TextMessageEndEvent;\n mode = undefined;\n textMessageFields = undefined;\n\n log?.event(\"TRANSFORM\", \"TEXT_MESSAGE_END\", event, {\n messageId: event.messageId,\n });\n\n return event;\n };\n\n const closeToolCall = () => {\n if (!toolCallFields || mode !== \"tool\") {\n throw new Error(\"No tool call to close\");\n }\n const event = {\n type: EventType.TOOL_CALL_END,\n toolCallId: toolCallFields.toolCallId,\n } as ToolCallEndEvent;\n mode = undefined;\n toolCallFields = undefined;\n\n log?.event(\"TRANSFORM\", \"TOOL_CALL_END\", event, {\n toolCallId: event.toolCallId,\n });\n\n return event;\n };\n\n const closeReasoningMessage = () => {\n if (!reasoningMessageFields || mode !== \"reasoning\") {\n throw new Error(\"No reasoning message to close\");\n }\n const event = {\n type: EventType.REASONING_MESSAGE_END,\n messageId: reasoningMessageFields.messageId,\n } as ReasoningMessageEndEvent;\n mode = undefined;\n reasoningMessageFields = undefined;\n\n log?.event(\"TRANSFORM\", \"REASONING_MESSAGE_END\", event, {\n messageId: event.messageId,\n });\n\n return event;\n };\n\n const closePendingEvent = () => {\n if (mode === \"text\") {\n return [closeTextMessage()];\n }\n if (mode === \"tool\") {\n return [closeToolCall()];\n }\n if (mode === \"reasoning\") {\n return [closeReasoningMessage()];\n }\n return [];\n };\n\n return events$.pipe(\n mergeMap((event) => {\n switch (event.type) {\n case EventType.TEXT_MESSAGE_START:\n case EventType.TEXT_MESSAGE_CONTENT:\n case EventType.TEXT_MESSAGE_END:\n case EventType.TOOL_CALL_START:\n case EventType.TOOL_CALL_ARGS:\n case EventType.TOOL_CALL_END:\n case EventType.TOOL_CALL_RESULT:\n case EventType.STATE_SNAPSHOT:\n case EventType.STATE_DELTA:\n case EventType.MESSAGES_SNAPSHOT:\n case EventType.CUSTOM:\n case EventType.RUN_STARTED:\n case EventType.RUN_FINISHED:\n case EventType.RUN_ERROR:\n case EventType.STEP_STARTED:\n case EventType.STEP_FINISHED:\n case EventType.THINKING_START:\n case EventType.THINKING_END:\n case EventType.THINKING_TEXT_MESSAGE_START:\n case EventType.THINKING_TEXT_MESSAGE_CONTENT:\n case EventType.THINKING_TEXT_MESSAGE_END:\n case EventType.REASONING_START:\n case EventType.REASONING_MESSAGE_START:\n case EventType.REASONING_MESSAGE_CONTENT:\n case EventType.REASONING_MESSAGE_END:\n case EventType.REASONING_END:\n return [...closePendingEvent(), event];\n case EventType.RAW:\n case EventType.ACTIVITY_SNAPSHOT:\n case EventType.ACTIVITY_DELTA:\n case EventType.REASONING_ENCRYPTED_VALUE:\n return [event];\n case EventType.TEXT_MESSAGE_CHUNK:\n const messageChunkEvent = event as TextMessageChunkEvent;\n const textMessageResult = [];\n if (\n // we are not in a text message\n mode !== \"text\" ||\n // or the message id is different\n (messageChunkEvent.messageId !== undefined &&\n messageChunkEvent.messageId !== textMessageFields?.messageId)\n ) {\n // close the current message if any\n textMessageResult.push(...closePendingEvent());\n }\n\n // we are not in a text message, start a new one\n if (mode !== \"text\") {\n if (messageChunkEvent.messageId === undefined) {\n throw new Error(\"First TEXT_MESSAGE_CHUNK must have a messageId\");\n }\n\n textMessageFields = {\n messageId: messageChunkEvent.messageId,\n name: messageChunkEvent.name,\n };\n mode = \"text\";\n\n const textMessageStartEvent = {\n type: EventType.TEXT_MESSAGE_START,\n messageId: messageChunkEvent.messageId,\n role: messageChunkEvent.role || \"assistant\",\n ...(messageChunkEvent.name !== undefined && { name: messageChunkEvent.name }),\n } as TextMessageStartEvent;\n\n textMessageResult.push(textMessageStartEvent);\n\n log?.event(\"TRANSFORM\", \"TEXT_MESSAGE_START\", textMessageStartEvent, {\n messageId: messageChunkEvent.messageId,\n });\n }\n\n if (messageChunkEvent.delta !== undefined) {\n const textMessageContentEvent = {\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId: textMessageFields!.messageId,\n delta: messageChunkEvent.delta,\n } as TextMessageContentEvent;\n\n textMessageResult.push(textMessageContentEvent);\n\n log?.event(\"TRANSFORM\", \"TEXT_MESSAGE_CONTENT\", textMessageContentEvent, {\n messageId: textMessageFields!.messageId,\n });\n }\n\n return textMessageResult;\n case EventType.TOOL_CALL_CHUNK:\n const toolCallChunkEvent = event as ToolCallChunkEvent;\n const toolMessageResult = [];\n if (\n // we are not in a text message\n mode !== \"tool\" ||\n // or the tool call id is different\n (toolCallChunkEvent.toolCallId !== undefined &&\n toolCallChunkEvent.toolCallId !== toolCallFields?.toolCallId)\n ) {\n // close the current message if any\n toolMessageResult.push(...closePendingEvent());\n }\n\n if (mode !== \"tool\") {\n if (toolCallChunkEvent.toolCallId === undefined) {\n throw new Error(\"First TOOL_CALL_CHUNK must have a toolCallId\");\n }\n if (toolCallChunkEvent.toolCallName === undefined) {\n throw new Error(\"First TOOL_CALL_CHUNK must have a toolCallName\");\n }\n toolCallFields = {\n toolCallId: toolCallChunkEvent.toolCallId,\n toolCallName: toolCallChunkEvent.toolCallName,\n parentMessageId: toolCallChunkEvent.parentMessageId,\n };\n mode = \"tool\";\n\n const toolCallStartEvent = {\n type: EventType.TOOL_CALL_START,\n toolCallId: toolCallChunkEvent.toolCallId,\n toolCallName: toolCallChunkEvent.toolCallName,\n parentMessageId: toolCallChunkEvent.parentMessageId,\n } as ToolCallStartEvent;\n\n toolMessageResult.push(toolCallStartEvent);\n\n log?.event(\"TRANSFORM\", \"TOOL_CALL_START\", toolCallStartEvent, {\n toolCallId: toolCallChunkEvent.toolCallId,\n toolCallName: toolCallChunkEvent.toolCallName,\n });\n }\n\n if (toolCallChunkEvent.delta !== undefined) {\n const toolCallArgsEvent = {\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: toolCallFields!.toolCallId,\n delta: toolCallChunkEvent.delta,\n } as ToolCallArgsEvent;\n\n toolMessageResult.push(toolCallArgsEvent);\n\n log?.event(\"TRANSFORM\", \"TOOL_CALL_ARGS\", toolCallArgsEvent, {\n toolCallId: toolCallFields!.toolCallId,\n });\n }\n\n return toolMessageResult;\n case EventType.REASONING_MESSAGE_CHUNK:\n const reasoningChunkEvent = event as ReasoningMessageChunkEvent;\n const reasoningMessageResult = [];\n if (\n // we are not in a reasoning message\n mode !== \"reasoning\" ||\n // or the message id is different\n (reasoningChunkEvent.messageId &&\n reasoningChunkEvent.messageId !== reasoningMessageFields?.messageId)\n ) {\n // close the current message if any\n reasoningMessageResult.push(...closePendingEvent());\n }\n\n // we are not in a reasoning message, start a new one\n if (mode !== \"reasoning\") {\n if (reasoningChunkEvent.messageId === undefined) {\n throw new Error(\"First REASONING_MESSAGE_CHUNK must have a messageId\");\n }\n\n reasoningMessageFields = {\n messageId: reasoningChunkEvent.messageId,\n };\n mode = \"reasoning\";\n\n const reasoningMessageStartEvent = {\n type: EventType.REASONING_MESSAGE_START,\n messageId: reasoningChunkEvent.messageId,\n } as ReasoningMessageStartEvent;\n reasoningMessageResult.push(reasoningMessageStartEvent);\n\n log?.event(\"TRANSFORM\", \"REASONING_MESSAGE_START\", reasoningMessageStartEvent, {\n messageId: reasoningChunkEvent.messageId,\n });\n }\n\n if (reasoningChunkEvent.delta !== undefined) {\n const reasoningMessageContentEvent = {\n type: EventType.REASONING_MESSAGE_CONTENT,\n messageId: reasoningMessageFields!.messageId,\n delta: reasoningChunkEvent.delta,\n } as ReasoningMessageContentEvent;\n\n reasoningMessageResult.push(reasoningMessageContentEvent);\n\n log?.event(\"TRANSFORM\", \"REASONING_MESSAGE_CONTENT\", reasoningMessageContentEvent, {\n messageId: reasoningMessageFields!.messageId,\n });\n }\n\n return reasoningMessageResult;\n }\n const _exhaustiveCheck: never = event.type;\n return [];\n }),\n finalize(() => {\n // This ensures that we close any pending events when the source observable completes\n closePendingEvent();\n }),\n );\n };\n","import type {\n Interrupt,\n ResumeEntry,\n RunFinishedEvent,\n RunFinishedOutcome,\n} from \"@ag-ui/core\";\n\nexport function getRunOutcome(event: RunFinishedEvent): RunFinishedOutcome | undefined {\n return event.outcome;\n}\n\nexport function isInterruptExpired(interrupt: Interrupt, now: Date = new Date()): boolean {\n if (interrupt.expiresAt === undefined) return false;\n return new Date(interrupt.expiresAt) <= now;\n}\n\ntype ResumeResponse =\n | { status: \"resolved\"; payload?: unknown }\n | { status: \"cancelled\" };\n\nexport function buildResumeArray(\n interrupts: Interrupt[],\n responses: Record<string, ResumeResponse>,\n): ResumeEntry[] {\n const openIds = new Set(interrupts.map((i) => i.id));\n const responseIds = new Set(Object.keys(responses));\n\n const missing = [...openIds].filter((id) => !responseIds.has(id));\n if (missing.length > 0) {\n throw new Error(`buildResumeArray: missing responses for open interrupts: ${missing.join(\", \")}`);\n }\n\n const unknown = [...responseIds].filter((id) => !openIds.has(id));\n if (unknown.length > 0) {\n throw new Error(`buildResumeArray: responses reference unknown interrupt ids: ${unknown.join(\", \")}`);\n }\n\n return interrupts.map((i) => {\n const r = responses[i.id];\n if (r.status === \"resolved\") {\n const entry: ResumeEntry = { interruptId: i.id, status: \"resolved\" };\n if (r.payload !== undefined) entry.payload = r.payload;\n return entry;\n }\n return { interruptId: i.id, status: \"cancelled\" };\n });\n}\n","import { AbstractAgent } from \"@/agent\";\nimport { RunAgentInput, BaseEvent, Message } from \"@ag-ui/core\";\nimport { Observable, ReplaySubject } from \"rxjs\";\nimport { concatMap } from \"rxjs/operators\";\nimport { transformChunks } from \"@/chunks\";\nimport { defaultApplyEvents } from \"@/apply\";\nimport { structuredClone_ } from \"@/utils\";\n\nexport type MiddlewareFunction = (\n input: RunAgentInput,\n next: AbstractAgent,\n) => Observable<BaseEvent>;\n\nexport interface EventWithState {\n event: BaseEvent;\n messages: Message[];\n state: any;\n}\n\nexport abstract class Middleware {\n abstract run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent>;\n\n /**\n * Runs the next agent in the chain with automatic chunk transformation.\n */\n protected runNext(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\n return next.run(input).pipe(\n transformChunks(false), // Always transform chunks to full events\n );\n }\n\n /**\n * Runs the next agent and tracks state, providing current messages and state with each event.\n * The messages and state represent the state AFTER the event has been applied.\n */\n protected runNextWithState(\n input: RunAgentInput,\n next: AbstractAgent,\n ): Observable<EventWithState> {\n let currentMessages = structuredClone_(input.messages || []);\n let currentState = structuredClone_(input.state || {});\n\n // Use a ReplaySubject to feed events one by one\n const eventSubject = new ReplaySubject<BaseEvent>();\n\n // Set up defaultApplyEvents to process events\n const mutations$ = defaultApplyEvents(input, eventSubject, next, []);\n\n // Subscribe to track state changes\n mutations$.subscribe((mutation) => {\n if (mutation.messages !== undefined) {\n currentMessages = mutation.messages;\n }\n if (mutation.state !== undefined) {\n currentState = mutation.state;\n }\n });\n\n return this.runNext(input, next).pipe(\n concatMap(async (event) => {\n // Feed the event to defaultApplyEvents and wait for it to process\n eventSubject.next(event);\n\n // Give defaultApplyEvents a chance to process\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n // Return event with current state\n return {\n event,\n messages: structuredClone_(currentMessages),\n state: structuredClone_(currentState),\n };\n }),\n );\n }\n}\n\n// Wrapper class to convert a function into a Middleware instance\nexport class FunctionMiddleware extends Middleware {\n constructor(private fn: MiddlewareFunction) {\n super();\n }\n\n run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\n return this.fn(input, next);\n }\n}\n","import { Middleware } from \"./middleware\";\nimport { AbstractAgent } from \"@/agent\";\nimport {\n RunAgentInput,\n BaseEvent,\n EventType,\n ToolCallStartEvent,\n ToolCallArgsEvent,\n ToolCallEndEvent,\n ToolCallResultEvent,\n} from \"@ag-ui/core\";\nimport { Observable } from \"rxjs\";\nimport { filter } from \"rxjs/operators\";\n\ntype FilterToolCallsConfig =\n | { allowedToolCalls: string[]; disallowedToolCalls?: never }\n | { disallowedToolCalls: string[]; allowedToolCalls?: never };\n\nexport class FilterToolCallsMiddleware extends Middleware {\n private blockedToolCallIds = new Set<string>();\n private readonly allowedTools?: Set<string>;\n private readonly disallowedTools?: Set<string>;\n\n constructor(config: FilterToolCallsConfig) {\n super();\n\n // Runtime validation (belt and suspenders approach)\n if (config.allowedToolCalls && config.disallowedToolCalls) {\n throw new Error(\"Cannot specify both allowedToolCalls and disallowedToolCalls\");\n }\n\n if (!config.allowedToolCalls && !config.disallowedToolCalls) {\n throw new Error(\"Must specify either allowedToolCalls or disallowedToolCalls\");\n }\n\n if (config.allowedToolCalls) {\n this.allowedTools = new Set(config.allowedToolCalls);\n } else if (config.disallowedToolCalls) {\n this.disallowedTools = new Set(config.disallowedToolCalls);\n }\n }\n\n run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\n // Use runNext which already includes transformChunks\n return this.runNext(input, next).pipe(\n filter((event) => {\n // Handle TOOL_CALL_START events\n if (event.type === EventType.TOOL_CALL_START) {\n const toolCallStartEvent = event as ToolCallStartEvent;\n const shouldFilter = this.shouldFilterTool(toolCallStartEvent.toolCallName);\n\n if (shouldFilter) {\n // Track this tool call ID as blocked\n this.blockedToolCallIds.add(toolCallStartEvent.toolCallId);\n return false; // Filter out this event\n }\n\n return true; // Allow this event\n }\n\n // Handle TOOL_CALL_ARGS events\n if (event.type === EventType.TOOL_CALL_ARGS) {\n const toolCallArgsEvent = event as ToolCallArgsEvent;\n return !this.blockedToolCallIds.has(toolCallArgsEvent.toolCallId);\n }\n\n // Handle TOOL_CALL_END events\n if (event.type === EventType.TOOL_CALL_END) {\n const toolCallEndEvent = event as ToolCallEndEvent;\n return !this.blockedToolCallIds.has(toolCallEndEvent.toolCallId);\n }\n\n // Handle TOOL_CALL_RESULT events\n if (event.type === EventType.TOOL_CALL_RESULT) {\n const toolCallResultEvent = event as ToolCallResultEvent;\n const isBlocked = this.blockedToolCallIds.has(toolCallResultEvent.toolCallId);\n\n if (isBlocked) {\n // Clean up the blocked ID after the last event\n this.blockedToolCallIds.delete(toolCallResultEvent.toolCallId);\n return false;\n }\n\n return true;\n }\n\n // Allow all other events through\n return true;\n }),\n );\n }\n\n private shouldFilterTool(toolName: string): boolean {\n if (this.allowedTools) {\n // If using allowed list, filter out tools NOT in the list\n return !this.allowedTools.has(toolName);\n } else if (this.disallowedTools) {\n // If using disallowed list, filter out tools IN the list\n return this.disallowedTools.has(toolName);\n }\n\n return false;\n }\n}\n","import { Middleware } from \"./middleware\";\nimport { AbstractAgent } from \"@/agent\";\nimport type { RunAgentInput, BaseEvent } from \"@ag-ui/core\";\nimport type { Observable } from \"rxjs\";\n\ntype InputMessage = RunAgentInput[\"messages\"][number];\n\nfunction sanitizeMessageContent(message: InputMessage): InputMessage {\n const rawContent = (message as { content?: unknown }).content;\n\n if (Array.isArray(rawContent)) {\n const concatenatedContent = rawContent\n .filter(\n (part): part is { type: \"text\"; text: string } =>\n typeof part === \"object\" &&\n part !== null &&\n \"type\" in part &&\n (part as { type: unknown }).type === \"text\" &&\n typeof (part as { text?: unknown }).text === \"string\",\n )\n .map((part) => part.text)\n .join(\"\");\n\n return {\n ...message,\n content: concatenatedContent,\n } as InputMessage;\n }\n\n if (typeof rawContent === \"string\") {\n return message;\n }\n\n return {\n ...message,\n content: \"\",\n } as InputMessage;\n}\n\n/**\n * Middleware placeholder that maintains compatibility with AG-UI 0.0.39 flows.\n * Currently it simply forwards all events to the next middleware/agent.\n */\nexport class BackwardCompatibility_0_0_39 extends Middleware {\n override run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\n const { parentRunId: _parentRunId, ...rest } = input;\n const sanitizedInput: RunAgentInput = {\n ...rest,\n messages: rest.messages.map(sanitizeMessageContent),\n } as RunAgentInput;\n\n return this.runNext(sanitizedInput, next);\n }\n}\n","import { Middleware } from \"./middleware\";\nimport { AbstractAgent } from \"@/agent\";\nimport type { RunAgentInput, BaseEvent } from \"@ag-ui/core\";\nimport { EventType } from \"@ag-ui/core\";\nimport type { Observable } from \"rxjs\";\nimport { map } from \"rxjs/operators\";\nimport { randomUUID } from \"@/utils\";\n\n// Event type strings for THINKING events (deprecated)\nconst THINKING_START = \"THINKING_START\";\nconst THINKING_END = \"THINKING_END\";\nconst THINKING_TEXT_MESSAGE_START = \"THINKING_TEXT_MESSAGE_START\";\nconst THINKING_TEXT_MESSAGE_CONTENT = \"THINKING_TEXT_MESSAGE_CONTENT\";\nconst THINKING_TEXT_MESSAGE_END = \"THINKING_TEXT_MESSAGE_END\";\n\n/**\n * Middleware that maps deprecated THINKING events to the new REASONING events.\n *\n * This ensures backward compatibility for agents that still emit legacy THINKING\n * events (THINKING_START, THINKING_END, THINKING_TEXT_MESSAGE_START, etc.)\n * by transforming them into the corresponding REASONING events.\n *\n * Event mapping:\n * - THINKING_START → REASONING_START\n * - THINKING_TEXT_MESSAGE_START → REASONING_MESSAGE_START\n * - THINKING_TEXT_MESSAGE_CONTENT → REASONING_MESSAGE_CONTENT\n * - THINKING_TEXT_MESSAGE_END → REASONING_MESSAGE_END\n * - THINKING_END → REASONING_END\n *\n */\nexport class BackwardCompatibility_0_0_45 extends Middleware {\n private currentReasoningId: string | null = null;\n private currentMessageId: string | null = null;\n\n private warnAboutTransformation(from: string, to: string) {\n if (\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.SUPPRESS_TRANSFORMATION_WARNINGS\n )\n return;\n console.warn(\n `AG-UI is converting ${from} to ${to}. To remove this warning, upgrade your AG-UI integration package (e.g. @ag-ui/langgraph). To surpress it, set SUPPRESS_TRANSFORMATION_WARNINGS=true in your .env file.`,\n );\n }\n override run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\n // Reset state for each run\n this.currentReasoningId = null;\n this.currentMessageId = null;\n\n return this.runNext(input, next).pipe(map((event) => this.transformEvent(event)));\n }\n\n private transformEvent(event: BaseEvent): BaseEvent {\n const eventType = event.type as string;\n\n switch (eventType) {\n case THINKING_START: {\n this.currentReasoningId = randomUUID();\n const { title, ...rest } = event as BaseEvent & { title?: string };\n this.warnAboutTransformation(THINKING_START, EventType.REASONING_START);\n return {\n ...rest,\n type: EventType.REASONING_START,\n messageId: this.currentReasoningId,\n };\n }\n\n case THINKING_TEXT_MESSAGE_START: {\n this.currentMessageId = randomUUID();\n this.warnAboutTransformation(\n THINKING_TEXT_MESSAGE_START,\n EventType.REASONING_MESSAGE_START,\n );\n return {\n ...event,\n type: EventType.REASONING_MESSAGE_START,\n messageId: this.currentMessageId,\n role: \"assistant\" as const,\n };\n }\n\n case THINKING_TEXT_MESSAGE_CONTENT: {\n const { delta, ...rest } = event as BaseEvent & { delta: string };\n this.warnAboutTransformation(\n THINKING_TEXT_MESSAGE_CONTENT,\n EventType.REASONING_MESSAGE_CONTENT,\n );\n return {\n ...rest,\n type: EventType.REASONING_MESSAGE_CONTENT,\n messageId: this.currentMessageId ?? randomUUID(),\n delta,\n };\n }\n\n case THINKING_TEXT_MESSAGE_END: {\n const messageId = this.currentMessageId ?? randomUUID();\n this.warnAboutTransformation(THINKING_TEXT_MESSAGE_END, EventType.REASONING_MESSAGE_END);\n return {\n ...event,\n type: EventType.REASONING_MESSAGE_END,\n messageId,\n };\n }\n\n case THINKING_END: {\n const reasoningId = this.currentReasoningId ?? randomUUID();\n this.warnAboutTransformation(THINKING_END, EventType.REASONING_END);\n return {\n ...event,\n type: EventType.REASONING_END,\n messageId: reasoningId,\n };\n }\n\n default:\n return event;\n }\n }\n}\n","import { Middleware } from \"./middleware\";\nimport { AbstractAgent } from \"@/agent\";\nimport type { RunAgentInput, BaseEvent } from \"@ag-ui/core\";\nimport type { Observable } from \"rxjs\";\n\ntype InputMessage = RunAgentInput[\"messages\"][number];\n\ninterface LegacyBinaryContent {\n type: \"binary\";\n mimeType: string;\n id?: string;\n url?: string;\n data?: string;\n filename?: string;\n}\n\ninterface NewContentPart {\n type: \"image\" | \"audio\" | \"video\" | \"document\";\n source: { type: \"data\"; value: string; mimeType: string } | { type: \"url\"; value: string; mimeType: string };\n metadata?: unknown;\n}\n\nfunction mimeTypeToContentType(mimeType: string): \"image\" | \"audio\" | \"video\" | \"document\" {\n if (mimeType.startsWith(\"image/\")) return \"image\";\n if (mimeType.startsWith(\"audio/\")) return \"audio\";\n if (mimeType.startsWith(\"video/\")) return \"video\";\n return \"document\";\n}\n\nfunction isLegacyBinaryContent(part: unknown): part is LegacyBinaryContent {\n return (\n typeof part === \"object\" &&\n part !== null &&\n \"type\" in part &&\n (part as { type: unknown }).type === \"binary\" &&\n \"mimeType\" in part &&\n typeof (part as { mimeType: unknown }).mimeType === \"string\"\n );\n}\n\nfunction convertBinaryToNewFormat(binary: LegacyBinaryContent): NewContentPart | LegacyBinaryContent {\n const contentType = mimeTypeToContentType(binary.mimeType);\n\n if (binary.data) {\n return {\n type: contentType,\n source: { type: \"data\", value: binary.data, mimeType: binary.mimeType },\n ...(binary.filename ? { metadata: { filename: binary.filename } } : {}),\n };\n }\n\n if (binary.url) {\n return {\n type: contentType,\n source: { type: \"url\", value: binary.url, mimeType: binary.mimeType },\n ...(binary.filename ? { metadata: { filename: binary.filename } } : {}),\n };\n }\n\n // If only `id` is present, we can't map to the new source format.\n // Return as-is — the schema still accepts BinaryInputContent.\n return binary;\n}\n\nfunction upgradeMessageContent(message: InputMessage): InputMessage {\n const rawContent = (message as { content?: unknown }).content;\n\n if (!Array.isArray(rawContent)) {\n return message;\n }\n\n const upgraded = rawContent.map((part: unknown) => {\n if (isLegacyBinaryContent(part)) {\n return convertBinaryToNewFormat(part);\n }\n return part;\n });\n\n return { ...message, content: upgraded } as InputMessage;\n}\n\n/**\n * Middleware that converts legacy BinaryInputContent entries (type: \"binary\")\n * to the new dedicated content types (image, audio, video, document) with\n * source discriminator.\n *\n * Old format (v0.0.47 and below):\n * { type: \"binary\", mimeType: \"image/png\", data: \"base64...\" }\n *\n * New format (v0.0.48+):\n * { type: \"image\", source: { type: \"data\", value: \"base64...\", mimeType: \"image/png\" } }\n *\n * Plain string content and TextInputContent pass through unchanged.\n * BinaryInputContent entries that only have `id` (no data/url) are left as-is\n * since they can't be mapped to the new source format.\n */\nexport class BackwardCompatibility_0_0_47 extends Middleware {\n override run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\n const upgradedInput: RunAgentInput = {\n ...input,\n messages: input.messages.map(upgradeMessageContent),\n };\n\n return this.runNext(upgradedInput, next);\n }\n}\n","","import { defaultApplyEvents } from \"@/apply/default\";\nimport {\n Message,\n State,\n RunAgentInput,\n BaseEvent,\n ToolCall,\n AssistantMessage,\n AgentCapabilities,\n Interrupt,\n} from \"@ag-ui/core\";\n\nimport {\n AgentConfig,\n AgentDebugConfig,\n RunAgentParameters,\n ResolvedAgentDebugConfig,\n resolveAgentDebugConfig,\n} from \"./types\";\nimport { DebugLogger, createDebugLogger } from \"@/debug-logger\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { structuredClone_ } from \"@/utils\";\nimport { compareVersions } from \"compare-versions\";\nimport { catchError, map, tap } from \"rxjs/operators\";\nimport { finalize } from \"rxjs/operators\";\nimport { takeUntil } from \"rxjs/operators\";\nimport { pipe, Observable, from, of, EMPTY, Subject, defer } from \"rxjs\";\nimport { verifyEvents } from \"@/verify\";\nimport { convertToLegacyEvents } from \"@/legacy/convert\";\nimport { LegacyRuntimeProtocolEvent } from \"@/legacy/types\";\nimport { lastValueFrom } from \"rxjs\";\nimport { transformChunks } from \"@/chunks\";\nimport { AgentStateMutation, AgentSubscriber, runSubscribersWithMutation } from \"./subscriber\";\nimport { AGUIConnectNotImplementedError, AGUIError } from \"@ag-ui/core\";\nimport { isInterruptExpired } from \"@/interrupts\";\nimport {\n Middleware,\n MiddlewareFunction,\n FunctionMiddleware,\n BackwardCompatibility_0_0_39,\n BackwardCompatibility_0_0_45,\n BackwardCompatibility_0_0_47,\n} from \"@/middleware\";\nimport packageJson from \"../../package.json\";\n\nexport interface RunAgentResult {\n result: any;\n newMessages: Message[];\n}\n\nexport abstract class AbstractAgent {\n public agentId?: string;\n public description: string;\n public threadId: string;\n public messages: Message[];\n public state: State;\n private _debug: ResolvedAgentDebugConfig;\n private _debugLogger: DebugLogger | undefined;\n public subscribers: AgentSubscriber[] = [];\n public isRunning: boolean = false;\n /** Interrupts emitted by the most recent run that have not yet been resolved.\n * Populated when RUN_FINISHED arrives with outcome.type === \"interrupt\".\n * Cleared when a subsequent run completes successfully. */\n public pendingInterrupts: Interrupt[] = [];\n private middlewares: Middleware[] = [];\n // Emits to immediately detach from the active run (stop processing its stream)\n private activeRunDetach$?: Subject<void>;\n private activeRunCompletionPromise?: Promise<void>;\n\n get maxVersion() {\n return packageJson.version;\n }\n\n get debug(): ResolvedAgentDebugConfig {\n return this._debug;\n }\n\n set debug(value: AgentDebugConfig | ResolvedAgentDebugConfig) {\n this._debug = resolveAgentDebugConfig(value as AgentDebugConfig);\n this._debugLogger = createDebugLogger(this._debug);\n }\n\n get debugLogger(): DebugLogger | undefined {\n return this._debugLogger;\n }\n\n set debugLogger(value: DebugLogger | boolean | undefined) {\n if (typeof value === \"boolean\") {\n this._debugLogger = value\n ? createDebugLogger(resolveAgentDebugConfig(true))\n : undefined;\n } else {\n this._debugLogger = value;\n }\n }\n\n constructor({\n agentId,\n description,\n threadId,\n initialMessages,\n initialState,\n debug,\n }: AgentConfig = {}) {\n this.agentId = agentId;\n this.description = description ?? \"\";\n this.threadId = threadId ?? uuidv4();\n this.messages = structuredClone_(initialMessages ?? []);\n this.state = structuredClone_(initialState ?? {});\n this._debug = resolveAgentDebugConfig(debug);\n this._debugLogger = createDebugLogger(this._debug);\n\n if (compareVersions(this.maxVersion, \"0.0.39\") <= 0) {\n this.middlewares.unshift(new BackwardCompatibility_0_0_39());\n }\n\n // Auto-insert BackwardCompatibility_0_0_45 for backward compatibility\n // with legacy THINKING events (deprecated, will be removed in 1.0.0)\n if (compareVersions(this.maxVersion, \"0.0.45\") <= 0) {\n this.middlewares.unshift(new BackwardCompatibility_0_0_45());\n }\n\n // Auto-insert BackwardCompatibility_0_0_47 for backward compatibility\n // with legacy BinaryInputContent (maps to dedicated image/audio/video/document types)\n if (compareVersions(this.maxVersion, \"0.0.47\") <= 0) {\n this.middlewares.unshift(new BackwardCompatibility_0_0_47());\n }\n\n }\n\n public subscribe(subscriber: AgentSubscriber) {\n this.subscribers.push(subscriber);\n return {\n unsubscribe: () => {\n this.subscribers = this.subscribers.filter((s) => s !== subscriber);\n },\n };\n }\n\n abstract run(input: RunAgentInput): Observable<BaseEvent>;\n\n /**\n * Returns the agent's current capabilities.\n * Optional — subclasses implement this to advertise what they support.\n */\n getCapabilities?(): Promise<AgentCapabilities>;\n\n public use(...middlewares: (Middleware | MiddlewareFunction)[]): this {\n const normalizedMiddlewares = middlewares.map((middleware) =>\n typeof middleware === \"function\" ? new FunctionMiddleware(middleware) : middleware,\n );\n this.middlewares.push(...normalizedMiddlewares);\n return this;\n }\n\n public async runAgent(\n parameters?: RunAgentParameters,\n subscriber?: AgentSubscriber,\n ): Promise<RunAgentResult> {\n try {\n this.isRunning = true;\n this.agentId = this.agentId ?? uuidv4();\n const input = this.prepareRunAgentInput(parameters);\n\n this.debugLogger?.lifecycle(\"LIFECYCLE\", \"Run started:\", {\n agentId: this.agentId,\n threadId: this.threadId,\n });\n\n let result: any = undefined;\n const currentMessageIds = new Set(this.messages.map((message) => message.id));\n\n const subscribers: AgentSubscriber[] = [\n {\n onRunFinishedEvent: (params) => {\n if (params.outcome === \"success\") {\n result = params.result;\n }\n },\n },\n ...this.subscribers,\n subscriber ?? {},\n ];\n\n await this.onInitialize(input, subscribers);\n\n // Per-run detachment signal + completion promise\n this.activeRunDetach$ = new Subject<void>();\n let resolveActiveRunCompletion: (() => void) | undefined;\n this.activeRunCompletionPromise = new Promise<void>((resolve) => {\n resolveActiveRunCompletion = resolve;\n });\n\n const pipeline = pipe(\n () => {\n // Build middleware chain using reduceRight so middlewares can intercept runs.\n if (this.middlewares.length === 0) {\n return this.run(input);\n }\n\n const chainedAgent = this.middlewares.reduceRight(\n (nextAgent: AbstractAgent, middleware) =>\n ({\n run: (i: RunAgentInput) => middleware.run(i, nextAgent),\n get messages() {\n return nextAgent.messages;\n },\n get state() {\n return nextAgent.state;\n },\n }) as AbstractAgent,\n this, // Original agent is the final 'next'\n );\n\n return chainedAgent.run(input);\n },\n transformChunks(this.debugLogger),\n verifyEvents(this.debugLogger),\n // Stop processing immediately when this run is detached\n (source$) => source$.pipe(takeUntil(this.activeRunDetach$!)),\n (source$) => this.apply(input, source$, subscribers),\n (source$) => this.processApplyEvents(input, source$, subscribers),\n catchError((error) => {\n this.debugLogger?.lifecycle(\"LIFECYCLE\", \"Run errored:\", {\n agentId: this.agentId,\n error: error instanceof Error ? error.message : String(error),\n });\n this.isRunning = false;\n return this.onError(input, error, subscribers);\n }),\n finalize(() => {\n this.debugLogger?.lifecycle(\"LIFECYCLE\", \"Run finished:\", {\n agentId: this.agentId,\n threadId: this.threadId,\n });\n this.isRunning = false;\n void this.onFinalize(input, subscribers);\n resolveActiveRunCompletion?.();\n resolveActiveRunCompletion = undefined;\n this.activeRunCompletionPromise = undefined;\n this.activeRunDetach$ = undefined;\n }),\n );\n\n await lastValueFrom(pipeline(of(null)));\n const newMessages = structuredClone_(this.messages).filter(\n (message: Message) => !currentMessageIds.has(message.id),\n );\n return { result, newMessages };\n } finally {\n this.isRunning = false;\n }\n }\n\n protected connect(input: RunAgentInput): Observable<BaseEvent> {\n throw new AGUIConnectNotImplementedError();\n }\n public async connectAgent(\n parameters?: RunAgentParameters,\n subscriber?: AgentSubscriber,\n ): Promise<RunAgentResult> {\n try {\n this.isRunning = true;\n this.agentId = this.agentId ?? uuidv4();\n const input = this.prepareRunAgentInput(parameters);\n let result: any = undefined;\n const currentMessageIds = new Set(this.messages.map((message) => message.id));\n\n const subscribers: AgentSubscriber[] = [\n {\n onRunFinishedEvent: (params) => {\n if (params.outcome === \"success\") {\n result = params.result;\n }\n },\n },\n ...this.subscribers,\n subscriber ?? {},\n ];\n\n await this.onInitialize(input, subscribers);\n\n // Per-run detachment signal + completion promise\n this.activeRunDetach$ = new Subject<void>();\n let resolveActiveRunCompletion: (() => void) | undefined;\n this.activeRunCompletionPromise = new Promise<void>((resolve) => {\n resolveActiveRunCompletion = resolve;\n });\n\n const pipeline = pipe(\n () => defer(() => this.connect(input)),\n transformChunks(this.debugLogger),\n verifyEvents(this.debugLogger),\n // Stop processing immediately when this run is detached\n (source$) => source$.pipe(takeUntil(this.activeRunDetach$!)),\n (source$) => this.apply(input, source$, subscribers),\n (source$) => this.processApplyEvents(input, source$, subscribers),\n catchError((error) => {\n this.isRunning = false;\n if (!(error instanceof AGUIConnectNotImplementedError)) {\n return this.onError(input, error, subscribers);\n }\n return EMPTY;\n }),\n finalize(() => {\n this.isRunning = false;\n void this.onFinalize(input, subscribers);\n resolveActiveRunCompletion?.();\n resolveActiveRunCompletion = undefined;\n this.activeRunCompletionPromise = undefined;\n this.activeRunDetach$ = undefined;\n }),\n );\n\n // defaultValue prevents EmptyError when catchError returns EMPTY\n // (e.g. ConnectNotImplementedError path)\n await lastValueFrom(pipeline(of(null)), { defaultValue: undefined });\n const newMessages = structuredClone_(this.messages).filter(\n (message: Message) => !currentMessageIds.has(message.id),\n );\n return { result, newMessages };\n } finally {\n this.isRunning = false;\n }\n }\n\n public abortRun() {}\n\n public async detachActiveRun(): Promise<void> {\n if (!this.activeRunDetach$) {\n return;\n }\n const completion = this.activeRunCompletionPromise ?? Promise.resolve();\n this.activeRunDetach$.next();\n this.activeRunDetach$?.complete();\n await completion;\n }\n\n protected apply(\n input: RunAgentInput,\n events$: Observable<BaseEvent>,\n subscribers: AgentSubscriber[],\n ): Observable<AgentStateMutation> {\n return defaultApplyEvents(input, events$, this, subscribers, this.debugLogger);\n }\n\n protected processApplyEvents(\n input: RunAgentInput,\n events$: Observable<AgentStateMutation>,\n subscribers: AgentSubscriber[],\n ): Observable<AgentStateMutation> {\n return events$.pipe(\n tap((event) => {\n if (event.messages) {\n this.messages = event.messages;\n subscribers.forEach((subscriber) => {\n subscriber.onMessagesChanged?.({\n messages: this.messages,\n state: this.state,\n agent: this,\n input,\n });\n });\n }\n if (event.state) {\n this.state = event.state;\n subscribers.forEach((subscriber) => {\n subscriber.onStateChanged?.({\n state: this.state,\n messages: this.messages,\n agent: this,\n input,\n });\n });\n }\n }),\n );\n }\n\n protected prepareRunAgentInput(parameters?: RunAgentParameters): RunAgentInput {\n const clonedMessages = structuredClone_(this.messages) as Message[];\n const messagesWithoutActivity = clonedMessages.filter((message) => message.role !== \"activity\");\n\n return {\n threadId: this.threadId,\n runId: parameters?.runId || uuidv4(),\n tools: structuredClone_(parameters?.tools ?? []),\n context: structuredClone_(parameters?.context ?? []),\n forwardedProps: structuredClone_(parameters?.forwardedProps ?? {}),\n state: structuredClone_(this.state),\n messages: messagesWithoutActivity,\n ...(parameters?.resume !== undefined ? { resume: structuredClone_(parameters.resume) } : {}),\n };\n }\n\n protected async onInitialize(input: RunAgentInput, subscribers: AgentSubscriber[]) {\n if (this.pendingInterrupts.length > 0) {\n const resumeIds = new Set((input.resume ?? []).map((r) => r.interruptId));\n const uncovered = this.pendingInterrupts\n .map((i) => i.id)\n .filter((id) => !resumeIds.has(id));\n if (uncovered.length > 0) {\n throw new AGUIError(\n `Thread has ${uncovered.length} pending interrupt(s) not addressed by resume: ${uncovered.join(\", \")}`,\n );\n }\n for (const i of this.pendingInterrupts) {\n if (isInterruptExpired(i)) {\n throw new AGUIError(`Interrupt ${i.id} expired at ${i.expiresAt}`);\n }\n }\n }\n\n const onRunInitializedMutation = await runSubscribersWithMutation(\n subscribers,\n this.messages,\n this.state,\n (subscriber, messages, state) =>\n subscriber.onRunInitialized?.({ messages, state, agent: this, input }),\n );\n if (\n onRunInitializedMutation.messages !== undefined ||\n onRunInitializedMutation.state !== undefined\n ) {\n if (onRunInitializedMutation.messages) {\n this.messages = onRunInitializedMutation.messages;\n input.messages = onRunInitializedMutation.messages;\n subscribers.forEach((subscriber) => {\n subscriber.onMessagesChanged?.({\n messages: this.messages,\n state: this.state,\n agent: this,\n input,\n });\n });\n }\n if (onRunInitializedMutation.state) {\n this.state = onRunInitializedMutation.state;\n input.state = onRunInitializedMutation.state;\n subscribers.forEach((subscriber) => {\n subscriber.onStateChanged?.({\n state: this.state,\n messages: this.messages,\n agent: this,\n input,\n });\n });\n }\n }\n }\n\n protected onError(input: RunAgentInput, error: Error, subscribers: AgentSubscriber[]) {\n return from(\n runSubscribersWithMutation(\n subscribers,\n this.messages,\n this.state,\n (subscriber, messages, state) =>\n subscriber.onRunFailed?.({ error, messages, state, agent: this, input }),\n ),\n ).pipe(\n map((onRunFailedMutation) => {\n const mutation = onRunFailedMutation as AgentStateMutation;\n if (mutation.messages !== undefined || mutation.state !== undefined) {\n if (mutation.messages !== undefined) {\n this.messages = mutation.messages;\n subscribers.forEach((subscriber) => {\n subscriber.onMessagesChanged?.({\n messages: this.messages,\n state: this.state,\n agent: this,\n input,\n });\n });\n }\n if (mutation.state !== undefined) {\n this.state = mutation.state;\n subscribers.forEach((subscriber) => {\n subscriber.onStateChanged?.({\n state: this.state,\n messages: this.messages,\n agent: this,\n input,\n });\n });\n }\n }\n\n if (mutation.stopPropagation !== true) {\n // Silently ignore abort errors (e.g. from navigation during active requests).\n // AbortController.abort(reason) can produce:\n // - A DOMException with name \"AbortError\"\n // - The reason value itself as a plain string (e.g. \"component unmounted\")\n const errStr = String(error);\n const isAbort =\n error.name === \"AbortError\" ||\n error.message === \"Fetch is aborted\" ||\n error.message === \"signal is aborted without reason\" ||\n error.message === \"component unmounted\" ||\n errStr === \"component unmounted\";\n if (!isAbort) {\n console.error(\"Agent execution failed:\", error);\n throw error;\n }\n }\n\n // Return an empty mutation instead of null to prevent EmptyError\n return {} as AgentStateMutation;\n }),\n );\n }\n\n protected async onFinalize(input: RunAgentInput, subscribers: AgentSubscriber[]) {\n const onRunFinalizedMutation = await runSubscribersWithMutation(\n subscribers,\n this.messages,\n this.state,\n (subscriber, messages, state) =>\n subscriber.onRunFinalized?.({ messages, state, agent: this, input }),\n );\n\n if (\n onRunFinalizedMutation.messages !== undefined ||\n onRunFinalizedMutation.state !== undefined\n ) {\n if (onRunFinalizedMutation.messages !== undefined) {\n this.messages = onRunFinalizedMutation.messages;\n subscribers.forEach((subscriber) => {\n subscriber.onMessagesChanged?.({\n messages: this.messages,\n state: this.state,\n agent: this,\n input,\n });\n });\n }\n if (onRunFinalizedMutation.state !== undefined) {\n this.state = onRunFinalizedMutation.state;\n subscribers.forEach((subscriber) => {\n subscriber.onStateChanged?.({\n state: this.state,\n messages: this.messages,\n agent: this,\n input,\n });\n });\n }\n }\n }\n\n public clone() {\n const cloned = Object.create(Object.getPrototypeOf(this));\n\n cloned.agentId = this.agentId;\n cloned.description = this.description;\n cloned.threadId = this.threadId;\n cloned.messages = structuredClone_(this.messages);\n cloned.state = structuredClone_(this.state);\n cloned._debug = this._debug;\n cloned._debugLogger = this._debugLogger;\n cloned.isRunning = this.isRunning;\n cloned.subscribers = [...this.subscribers];\n cloned.middlewares = [...this.middlewares];\n cloned.pendingInterrupts = structuredClone_(this.pendingInterrupts);\n\n return cloned;\n }\n\n public addMessage(message: Message) {\n // Add message to the messages array\n this.messages.push(message);\n\n // Notify subscribers sequentially in the background\n (async () => {\n // Fire onNewMessage sequentially\n for (const subscriber of this.subscribers) {\n await subscriber.onNewMessage?.({\n message,\n messages: this.messages,\n state: this.state,\n agent: this,\n });\n }\n\n // Fire onNewToolCall if the message is from assistant and contains tool calls\n if (message.role === \"assistant\" && message.toolCalls) {\n for (const toolCall of message.toolCalls) {\n for (const subscriber of this.subscribers) {\n await subscriber.onNewToolCall?.({\n toolCall,\n messages: this.messages,\n state: this.state,\n agent: this,\n });\n }\n }\n }\n\n // Fire onMessagesChanged sequentially\n for (const subscriber of this.subscribers) {\n await subscriber.onMessagesChanged?.({\n messages: this.messages,\n state: this.state,\n agent: this,\n });\n }\n })();\n }\n\n public addMessages(messages: Message[]) {\n // Add all messages to the messages array\n this.messages.push(...messages);\n\n // Notify subscribers sequentially in the background\n (async () => {\n // Fire onNewMessage and onNewToolCall for each message sequentially\n for (const message of messages) {\n // Fire onNewMessage sequentially\n for (const subscriber of this.subscribers) {\n await subscriber.onNewMessage?.({\n message,\n messages: this.messages,\n state: this.state,\n agent: this,\n });\n }\n\n // Fire onNewToolCall if the message is from assistant and contains tool calls\n if (message.role === \"assistant\" && message.toolCalls) {\n for (const toolCall of message.toolCalls) {\n for (const subscriber of this.subscribers) {\n await subscriber.onNewToolCall?.({\n toolCall,\n messages: this.messages,\n state: this.state,\n agent: this,\n });\n }\n }\n }\n }\n\n // Fire onMessagesChanged once at the end sequentially\n for (const subscriber of this.subscribers) {\n await subscriber.onMessagesChanged?.({\n messages: this.messages,\n state: this.state,\n agent: this,\n });\n }\n })();\n }\n\n public setMessages(messages: Message[]) {\n // Replace the entire messages array\n this.messages = structuredClone_(messages);\n\n // Notify subscribers sequentially in the background\n (async () => {\n // Fire onMessagesChanged sequentially\n for (const subscriber of this.subscribers) {\n await subscriber.onMessagesChanged?.({\n messages: this.messages,\n state: this.state,\n agent: this,\n });\n }\n })();\n }\n\n public setState(state: State) {\n // Replace the entire state\n this.state = structuredClone_(state);\n\n // Notify subscribers sequentially in the background\n (async () => {\n // Fire onStateChanged sequentially\n for (const subscriber of this.subscribers) {\n await subscriber.onStateChanged?.({\n messages: this.messages,\n state: this.state,\n agent: this,\n });\n }\n })();\n }\n\n public legacy_to_be_removed_runAgentBridged(\n config?: RunAgentParameters,\n ): Observable<LegacyRuntimeProtocolEvent> {\n this.agentId = this.agentId ?? uuidv4();\n const input = this.prepareRunAgentInput(config);\n\n // Build middleware chain for legacy bridge\n const runObservable = (() => {\n if (this.middlewares.length === 0) {\n return this.run(input);\n }\n\n const chainedAgent = this.middlewares.reduceRight(\n (nextAgent: AbstractAgent, middleware) =>\n ({\n run: (i: RunAgentInput) => middleware.run(i, nextAgent),\n get messages() {\n return nextAgent.messages;\n },\n get state() {\n return nextAgent.state;\n },\n }) as AbstractAgent,\n this,\n );\n\n return chainedAgent.run(input);\n })();\n\n return runObservable.pipe(\n transformChunks(this.debugLogger),\n verifyEvents(this.debugLogger),\n convertToLegacyEvents(this.threadId, input.runId, this.agentId),\n (events$: Observable<LegacyRuntimeProtocolEvent>) => {\n return events$.pipe(\n map((event) => {\n this.debugLogger?.event(\"LEGACY\", \"Event:\", event, { type: event.type });\n return event;\n }),\n );\n },\n );\n }\n}\n","import { AbstractAgent, RunAgentResult } from \"./agent\";\nimport { runHttpRequest } from \"@/run/http-request\";\nimport { HttpAgentConfig, HttpAgentFetchFn, RunAgentParameters } from \"./types\";\nimport { RunAgentInput, BaseEvent } from \"@ag-ui/core\";\nimport { structuredClone_ } from \"@/utils\";\nimport { transformHttpEventStream } from \"@/transform/http\";\nimport { Observable } from \"rxjs\";\nimport { AgentSubscriber } from \"./subscriber\";\n\ninterface RunHttpAgentConfig extends RunAgentParameters {\n abortController?: AbortController;\n}\n\nexport class HttpAgent extends AbstractAgent {\n public url: string;\n public headers: Record<string, string>;\n public fetch: HttpAgentFetchFn;\n public abortController: AbortController = new AbortController();\n\n /**\n * Returns the fetch config for the http request.\n * Override this to customize the request.\n *\n * @returns The fetch config for the http request.\n */\n protected requestInit(input: RunAgentInput): RequestInit {\n return {\n method: \"POST\",\n headers: {\n ...this.headers,\n \"Content-Type\": \"application/json\",\n Accept: \"text/event-stream\",\n },\n body: JSON.stringify(input),\n signal: this.abortController.signal,\n };\n }\n\n public runAgent(\n parameters?: RunHttpAgentConfig,\n subscriber?: AgentSubscriber,\n ): Promise<RunAgentResult> {\n this.abortController = parameters?.abortController ?? new AbortController();\n return super.runAgent(parameters, subscriber);\n }\n\n abortRun() {\n this.abortController.abort();\n super.abortRun();\n }\n\n constructor(config: HttpAgentConfig) {\n super(config);\n this.url = config.url;\n this.headers = structuredClone_(config.headers ?? {});\n // Bind the default fetch to the global object. Storing the bare `fetch`\n // and later invoking it as `this.fetch(...)` sets the receiver to the agent\n // instance; a browser's native fetch is a checked-receiver method and throws\n // \"Illegal invocation\" when not called with `window` as `this`. (Node's fetch\n // tolerates any receiver, so this only surfaces in the browser.)\n this.fetch = config.fetch ?? ((url, requestInit) => fetch(url, requestInit));\n }\n\n run(input: RunAgentInput): Observable<BaseEvent> {\n const httpEvents = runHttpRequest(() => this.fetch(this.url, this.requestInit(input)));\n return transformHttpEventStream(httpEvents, this.debugLogger);\n }\n\n public clone(): HttpAgent {\n const cloned = super.clone() as HttpAgent;\n cloned.url = this.url;\n cloned.headers = structuredClone_(this.headers ?? {});\n cloned.fetch = this.fetch;\n\n const newController = new AbortController();\n const originalSignal = this.abortController.signal as AbortSignal & { reason?: unknown };\n if (originalSignal.aborted) {\n newController.abort(originalSignal.reason);\n }\n cloned.abortController = newController;\n\n return cloned;\n }\n}\n","import {\n BaseEvent,\n EventType,\n TextMessageStartEvent,\n TextMessageContentEvent,\n TextMessageEndEvent,\n ToolCallStartEvent,\n ToolCallArgsEvent,\n ToolCallEndEvent,\n StateSnapshotEvent,\n StateDeltaEvent,\n} from \"@ag-ui/core\";\nimport jsonpatch from \"fast-json-patch\";\nimport { structuredClone_ } from \"../utils\";\n\n/**\n * Compacts streaming events by consolidating multiple deltas into single events.\n * For text messages: multiple content deltas become one concatenated delta.\n * For tool calls: multiple args deltas become one concatenated delta.\n * For state: all STATE_SNAPSHOT and STATE_DELTA events within a run are compacted\n * into a single STATE_SNAPSHOT representing the final state.\n * Events between related streaming events are reordered to keep streaming events together.\n *\n * @param events - Array of events to compact\n * @returns Compacted array of events\n */\nexport function compactEvents(events: BaseEvent[]): BaseEvent[] {\n const compacted: BaseEvent[] = [];\n const pendingTextMessages = new Map<\n string,\n {\n start?: TextMessageStartEvent;\n contents: TextMessageContentEvent[];\n end?: TextMessageEndEvent;\n otherEvents: BaseEvent[];\n }\n >();\n const pendingToolCalls = new Map<\n string,\n {\n start?: ToolCallStartEvent;\n args: ToolCallArgsEvent[];\n end?: ToolCallEndEvent;\n otherEvents: BaseEvent[];\n }\n >();\n\n // State compaction: collects state events, flushed at RUN_STARTED (pre-run/inter-run), RUN_FINISHED/RUN_ERROR (in-run), and at end (trailing)\n let stateEvents: (StateSnapshotEvent | StateDeltaEvent)[] = [];\n\n for (const event of events) {\n // Handle text message streaming events\n if (event.type === EventType.TEXT_MESSAGE_START) {\n const startEvent = event as TextMessageStartEvent;\n const messageId = startEvent.messageId;\n\n if (!pendingTextMessages.has(messageId)) {\n pendingTextMessages.set(messageId, {\n contents: [],\n otherEvents: [],\n });\n }\n\n const pending = pendingTextMessages.get(messageId)!;\n pending.start = startEvent;\n } else if (event.type === EventType.TEXT_MESSAGE_CONTENT) {\n const contentEvent = event as TextMessageContentEvent;\n const messageId = contentEvent.messageId;\n\n if (!pendingTextMessages.has(messageId)) {\n pendingTextMessages.set(messageId, {\n contents: [],\n otherEvents: [],\n });\n }\n\n const pending = pendingTextMessages.get(messageId)!;\n pending.contents.push(contentEvent);\n } else if (event.type === EventType.TEXT_MESSAGE_END) {\n const endEvent = event as TextMessageEndEvent;\n const messageId = endEvent.messageId;\n\n if (!pendingTextMessages.has(messageId)) {\n pendingTextMessages.set(messageId, {\n contents: [],\n otherEvents: [],\n });\n }\n\n const pending = pendingTextMessages.get(messageId)!;\n pending.end = endEvent;\n\n // Flush this message's events\n flushTextMessage(messageId, pending, compacted);\n pendingTextMessages.delete(messageId);\n } else if (event.type === EventType.TOOL_CALL_START) {\n const startEvent = event as ToolCallStartEvent;\n const toolCallId = startEvent.toolCallId;\n\n if (!pendingToolCalls.has(toolCallId)) {\n pendingToolCalls.set(toolCallId, {\n args: [],\n otherEvents: [],\n });\n }\n\n const pending = pendingToolCalls.get(toolCallId)!;\n pending.start = startEvent;\n } else if (event.type === EventType.TOOL_CALL_ARGS) {\n const argsEvent = event as ToolCallArgsEvent;\n const toolCallId = argsEvent.toolCallId;\n\n if (!pendingToolCalls.has(toolCallId)) {\n pendingToolCalls.set(toolCallId, {\n args: [],\n otherEvents: [],\n });\n }\n\n const pending = pendingToolCalls.get(toolCallId)!;\n pending.args.push(argsEvent);\n } else if (event.type === EventType.TOOL_CALL_END) {\n const endEvent = event as ToolCallEndEvent;\n const toolCallId = endEvent.toolCallId;\n\n if (!pendingToolCalls.has(toolCallId)) {\n pendingToolCalls.set(toolCallId, {\n args: [],\n otherEvents: [],\n });\n }\n\n const pending = pendingToolCalls.get(toolCallId)!;\n pending.end = endEvent;\n\n // Flush this tool call's events\n flushToolCall(toolCallId, pending, compacted);\n pendingToolCalls.delete(toolCallId);\n } else if (event.type === EventType.RUN_STARTED) {\n // Flush any pre-run state events before starting a new run\n flushState(stateEvents, compacted);\n stateEvents = [];\n compacted.push(event);\n } else if (\n event.type === EventType.RUN_FINISHED ||\n event.type === EventType.RUN_ERROR\n ) {\n // Flush compacted state into output before the run boundary event\n flushState(stateEvents, compacted);\n stateEvents = [];\n compacted.push(event);\n } else if (\n event.type === EventType.STATE_SNAPSHOT ||\n event.type === EventType.STATE_DELTA\n ) {\n // Collect state events for compaction\n stateEvents.push(event as StateSnapshotEvent | StateDeltaEvent);\n } else {\n // For non-streaming events, check if we're in the middle of any streaming sequences\n let addedToBuffer = false;\n\n // Check text messages\n for (const [messageId, pending] of pendingTextMessages) {\n // If we have a start but no end yet, this event is \"in between\"\n if (pending.start && !pending.end) {\n pending.otherEvents.push(event);\n addedToBuffer = true;\n break;\n }\n }\n\n // Check tool calls if not already buffered\n if (!addedToBuffer) {\n for (const [toolCallId, pending] of pendingToolCalls) {\n // If we have a start but no end yet, this event is \"in between\"\n if (pending.start && !pending.end) {\n pending.otherEvents.push(event);\n addedToBuffer = true;\n break;\n }\n }\n }\n\n // If not in the middle of any streaming sequence, add directly to compacted\n if (!addedToBuffer) {\n compacted.push(event);\n }\n }\n }\n\n // Flush any remaining incomplete messages\n for (const [messageId, pending] of pendingTextMessages) {\n flushTextMessage(messageId, pending, compacted);\n }\n\n // Flush any remaining incomplete tool calls\n for (const [toolCallId, pending] of pendingToolCalls) {\n flushToolCall(toolCallId, pending, compacted);\n }\n\n // Flush any remaining state events (incomplete run or events outside runs)\n flushState(stateEvents, compacted);\n\n return compacted;\n}\n\nfunction flushTextMessage(\n messageId: string,\n pending: {\n start?: TextMessageStartEvent;\n contents: TextMessageContentEvent[];\n end?: TextMessageEndEvent;\n otherEvents: BaseEvent[];\n },\n compacted: BaseEvent[],\n): void {\n // Add start event if present\n if (pending.start) {\n compacted.push(pending.start);\n }\n\n // Compact all content events into one\n if (pending.contents.length > 0) {\n const concatenatedDelta = pending.contents.map((c) => c.delta).join(\"\");\n\n const compactedContent: TextMessageContentEvent = {\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId: messageId,\n delta: concatenatedDelta,\n };\n\n compacted.push(compactedContent);\n }\n\n // Add end event if present\n if (pending.end) {\n compacted.push(pending.end);\n }\n\n // Add any events that were in between\n for (const otherEvent of pending.otherEvents) {\n compacted.push(otherEvent);\n }\n}\n\nfunction flushToolCall(\n toolCallId: string,\n pending: {\n start?: ToolCallStartEvent;\n args: ToolCallArgsEvent[];\n end?: ToolCallEndEvent;\n otherEvents: BaseEvent[];\n },\n compacted: BaseEvent[],\n): void {\n // Add start event if present\n if (pending.start) {\n compacted.push(pending.start);\n }\n\n // Compact all args events into one\n if (pending.args.length > 0) {\n const concatenatedArgs = pending.args.map((a) => a.delta).join(\"\");\n\n const compactedArgs: ToolCallArgsEvent = {\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: toolCallId,\n delta: concatenatedArgs,\n };\n\n compacted.push(compactedArgs);\n }\n\n // Add end event if present\n if (pending.end) {\n compacted.push(pending.end);\n }\n\n // Add any events that were in between\n for (const otherEvent of pending.otherEvents) {\n compacted.push(otherEvent);\n }\n}\n\nfunction flushState(\n stateEvents: (StateSnapshotEvent | StateDeltaEvent)[],\n compacted: BaseEvent[],\n): void {\n if (stateEvents.length === 0) {\n return;\n }\n\n let state: any = {};\n\n for (const event of stateEvents) {\n if (event.type === EventType.STATE_SNAPSHOT) {\n state = structuredClone_(event.snapshot);\n } else {\n const result = jsonpatch.applyPatch(state, structuredClone_(event.delta), true, false);\n state = result.newDocument;\n }\n }\n\n const compactedSnapshot: StateSnapshotEvent = {\n type: EventType.STATE_SNAPSHOT,\n snapshot: state,\n };\n\n compacted.push(compactedSnapshot);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["EMPTY","EventType","jsonpatch","AGUIError","EventType","Observable","MAX_BUFFER_SIZE","Subject","Subject","proto","Subject","ReplaySubject","proto","EventType","EventType","jsonpatch","TextMessageChunkEventSchema","ToolCallChunkEventSchema","ReasoningMessageChunkEventSchema","EventType","z","EventType","EventSchema","suppressed","EMPTY","RunAgentInputSchema","ReplaySubject","THINKING_START","THINKING_END","THINKING_TEXT_MESSAGE_START","THINKING_TEXT_MESSAGE_CONTENT","THINKING_TEXT_MESSAGE_END","EventType","EventType","EventType","EventType","PROTOCOL_VERSION","packageJson.version","AGUIError","Subject","AGUIConnectNotImplementedError","EMPTY","EventType","jsonpatch"],"sources":["../src/activity-history.ts","../src/utils.ts","../src/agent/subscriber.ts","../src/agent/types.ts","../src/debug-logger.ts","../src/apply/default.ts","../src/verify/verify.ts","../src/run/http-request.ts","../src/transform/sse.ts","../src/transform/proto.ts","../src/transform/http.ts","../src/legacy/types.ts","../src/legacy/convert.ts","../src/chunks/transform.ts","../src/enforce/strip.ts","../src/enforce/enforce.ts","../src/middleware/middleware.ts","../src/middleware/legacy-content.ts","../src/middleware/compatibility-boundary.ts","../src/interrupts/index.ts","../src/middleware/filter-tool-calls.ts","../src/middleware/backward-compatibility-0-0-39.ts","../src/middleware/backward-compatibility-0-0-45.ts","../src/middleware/backward-compatibility-0-0-57.ts","../package.json","../src/agent/agent.ts","../src/agent/http.ts","../src/compact/compact.ts"],"sourcesContent":["import { MessagesSnapshotEvent } from \"@ag-ui/core\";\n\n/** Package-owned convention. The protocol-reserved `ag-ui` namespace is untouched. */\nexport const ACTIVITY_HISTORY_METADATA = \"@ag-ui/client\";\n\n/**\n * Null owns all types; arrays own their types. Absent declarations use legacy\n * inference, while invalid declarations grant no omission-based deletion.\n */\nexport function authoritativeActivityTypes(\n event: MessagesSnapshotEvent,\n): string[] | null | undefined {\n if (\n !event.metadata ||\n !Object.prototype.hasOwnProperty.call(event.metadata, ACTIVITY_HISTORY_METADATA)\n )\n return undefined;\n const value = event.metadata?.[ACTIVITY_HISTORY_METADATA];\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return [];\n if (!Object.prototype.hasOwnProperty.call(value, \"authoritativeActivityTypes\")) return undefined;\n const types = (value as Record<string, unknown>).authoritativeActivityTypes;\n if (types === null) return null;\n return Array.isArray(types) && types.every((type): type is string => typeof type === \"string\")\n ? types\n : [];\n}\n\n/**\n * Add a projector scope, preserving full authority. Call on the incoming snapshot\n * before replacing its messages so inferred authority describes the original set.\n */\nexport function withAuthoritativeActivityTypes(\n event: MessagesSnapshotEvent,\n activityTypes: readonly string[],\n): MessagesSnapshotEvent {\n const prior = event.metadata?.[ACTIVITY_HISTORY_METADATA];\n const scope = authoritativeActivityTypes(event);\n const ownsAll =\n scope === null ||\n (scope === undefined && event.messages.some((message) => message.role === \"activity\"));\n return {\n ...event,\n metadata: {\n ...event.metadata,\n [ACTIVITY_HISTORY_METADATA]: {\n ...(prior && typeof prior === \"object\" && !Array.isArray(prior) ? prior : {}),\n authoritativeActivityTypes: ownsAll\n ? null\n : [...new Set([...(scope ?? []), ...activityTypes])],\n },\n },\n };\n}\n","import { v4 as uuidv4 } from \"uuid\";\n\nexport const structuredClone_ = <T>(obj: T): T => {\n if (typeof structuredClone === \"function\") {\n return structuredClone(obj);\n }\n\n try {\n return JSON.parse(JSON.stringify(obj));\n } catch (_err) {\n // Preserve array vs object type in shallow fallback\n if (Array.isArray(obj)) {\n return [...obj] as unknown as T;\n }\n return { ...obj } as T;\n }\n};\n\n/**\n * Generate a random UUID v4\n * Cross-platform compatible (Node.js, browsers, React Native)\n */\nexport function randomUUID(): string {\n return uuidv4();\n}\n\n// Note: semver helpers were removed in favor of using\n// the external `compare-versions` library directly at call sites.\n\n/**\n * Parses a semantic version string into its numeric components.\n * Supports incomplete versions (e.g. \"1\", \"1.2\") by defaulting missing segments to zero.\n *\n * @throws If the version string is not a valid semantic version.\n */\n// (Intentionally left minimal.)\n","import {\n BaseEvent,\n Interrupt,\n Message,\n RunAgentInput,\n RunErrorEvent,\n RunFinishedEvent,\n RunStartedEvent,\n State,\n StateDeltaEvent,\n StateSnapshotEvent,\n StepFinishedEvent,\n StepStartedEvent,\n TextMessageContentEvent,\n TextMessageEndEvent,\n TextMessageStartEvent,\n ToolCallArgsEvent,\n ToolCallEndEvent,\n ToolCallResultEvent,\n ToolCallStartEvent,\n MessagesSnapshotEvent,\n RawEvent,\n CustomEvent,\n ToolCall,\n ActivitySnapshotEvent,\n ActivityDeltaEvent,\n ActivityMessage,\n ReasoningStartEvent,\n ReasoningMessageStartEvent,\n ReasoningMessageContentEvent,\n ReasoningMessageEndEvent,\n ReasoningEndEvent,\n ReasoningEncryptedValueEvent,\n SubagentStartedEvent,\n SubagentFinishedEvent,\n SubagentErrorEvent,\n} from \"@ag-ui/core\";\nimport { AbstractAgent } from \"./agent\";\nimport { structuredClone_ } from \"@/utils\";\n\nexport interface AgentStateMutation {\n messages?: Message[];\n state?: State;\n stopPropagation?: boolean;\n}\n\nexport interface AgentSubscriberParams {\n messages: ReadonlyArray<Readonly<Message>>;\n // NOTE: State resolves to `any` at the type level (z.infer<typeof z.any()>), so Readonly<State>\n // provides no compile-time mutation protection. Runtime enforcement via deepFreeze in\n // dev/test mode is the only guard against in-place mutation of state.\n state: Readonly<State>;\n agent: AbstractAgent;\n input: RunAgentInput;\n}\n\n// Utility type to allow callbacks to be implemented either synchronously or asynchronously.\nexport type MaybePromise<T> = T | Promise<T>;\n\nexport interface AgentSubscriber {\n // Request lifecycle\n onRunInitialized?(\n params: AgentSubscriberParams,\n ): MaybePromise<Omit<AgentStateMutation, \"stopPropagation\"> | void>;\n onRunFailed?(\n params: { error: Error } & AgentSubscriberParams,\n ): MaybePromise<Omit<AgentStateMutation, \"stopPropagation\"> | void>;\n onRunFinalized?(\n params: AgentSubscriberParams,\n ): MaybePromise<Omit<AgentStateMutation, \"stopPropagation\"> | void>;\n\n // Events\n onEvent?(\n params: { event: BaseEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onRunStartedEvent?(\n params: { event: RunStartedEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n onRunFinishedEvent?(\n params: (\n | {\n event: RunFinishedEvent;\n outcome: \"success\";\n result?: unknown;\n /**\n * Tool calls the run left for the application to answer, in order.\n * The producer's `outcome.pendingToolCallIds` when it named them;\n * otherwise derived from the stream: every tool call this run\n * started that received no TOOL_CALL_RESULT.\n */\n pendingToolCallIds: string[];\n }\n | { event: RunFinishedEvent; outcome: \"interrupt\"; interrupts: Interrupt[] }\n | { event: RunFinishedEvent; outcome: \"cancelled\" }\n ) &\n AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n onRunErrorEvent?(\n params: { event: RunErrorEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onStepStartedEvent?(\n params: { event: StepStartedEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n onStepFinishedEvent?(\n params: { event: StepFinishedEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onSubagentStartedEvent?(\n params: { event: SubagentStartedEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n onSubagentFinishedEvent?(\n params: { event: SubagentFinishedEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n onSubagentErrorEvent?(\n params: { event: SubagentErrorEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onTextMessageStartEvent?(\n params: { event: TextMessageStartEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n onTextMessageContentEvent?(\n params: {\n event: TextMessageContentEvent;\n textMessageBuffer: string;\n } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n onTextMessageEndEvent?(\n params: { event: TextMessageEndEvent; textMessageBuffer: string } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onToolCallStartEvent?(\n params: { event: ToolCallStartEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n onToolCallArgsEvent?(\n params: {\n event: ToolCallArgsEvent;\n toolCallBuffer: string;\n toolCallName: string;\n // DEFERRED (PNI-272): narrowing this to `unknown` would force casts in\n // every consumer's subscriber callback. Public API decision, not lint.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n partialToolCallArgs: Record<string, any>;\n } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n onToolCallEndEvent?(\n params: {\n event: ToolCallEndEvent;\n toolCallName: string;\n // DEFERRED (PNI-272): see `partialToolCallArgs` above.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n toolCallArgs: Record<string, any>;\n } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onToolCallResultEvent?(\n params: { event: ToolCallResultEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onStateSnapshotEvent?(\n params: { event: StateSnapshotEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onStateDeltaEvent?(\n params: { event: StateDeltaEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onMessagesSnapshotEvent?(\n params: { event: MessagesSnapshotEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onActivitySnapshotEvent?(\n params: {\n event: ActivitySnapshotEvent;\n activityMessage?: ActivityMessage;\n existingMessage?: Message;\n } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onActivityDeltaEvent?(\n params: {\n event: ActivityDeltaEvent;\n activityMessage?: ActivityMessage;\n } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onRawEvent?(\n params: { event: RawEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onCustomEvent?(\n params: { event: CustomEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n // Reasoning events\n onReasoningStartEvent?(\n params: { event: ReasoningStartEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onReasoningMessageStartEvent?(\n params: { event: ReasoningMessageStartEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onReasoningMessageContentEvent?(\n params: {\n event: ReasoningMessageContentEvent;\n reasoningMessageBuffer: string;\n } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onReasoningMessageEndEvent?(\n params: {\n event: ReasoningMessageEndEvent;\n reasoningMessageBuffer: string;\n } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onReasoningEndEvent?(\n params: { event: ReasoningEndEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n onReasoningEncryptedValueEvent?(\n params: { event: ReasoningEncryptedValueEvent } & AgentSubscriberParams,\n ): MaybePromise<AgentStateMutation | void>;\n\n // State changes\n onMessagesChanged?(\n params: Omit<AgentSubscriberParams, \"input\"> & { input?: RunAgentInput },\n ): MaybePromise<void>;\n onStateChanged?(\n params: Omit<AgentSubscriberParams, \"input\"> & { input?: RunAgentInput },\n ): MaybePromise<void>;\n onNewMessage?(\n params: { message: Message } & Omit<AgentSubscriberParams, \"input\"> & {\n input?: RunAgentInput;\n },\n ): MaybePromise<void>;\n onNewToolCall?(\n params: { toolCall: ToolCall } & Omit<AgentSubscriberParams, \"input\"> & {\n input?: RunAgentInput;\n },\n ): MaybePromise<void>;\n}\n\n/**\n * Whether an exception is the freeze guard firing rather than an ordinary bug.\n *\n * Matched on the message because that is the only thing the engines expose:\n * a write to a frozen property, an addition to a non-extensible object and a\n * delete from one all raise a plain TypeError, indistinguishable by type from\n * `Cannot read properties of undefined`. The wordings differ per engine, so\n * the fragments below cover the three this library ships to — V8 (Chrome,\n * Node, Edge), SpiderMonkey (Firefox) and JavaScriptCore (Safari) — rather\n * than V8's alone. It is a table of what those engines say TODAY, not a\n * closed set: an engine is free to reword, and a spelling missing from here\n * shows up as a freeze violation reported as an ordinary subscriber error.\n * subscriber-errors.test.ts pins the current wordings one engine at a time.\n */\nfunction isFrozenWriteError(error: unknown): boolean {\n if (!(error instanceof TypeError)) return false;\n // `can't be deleted` is SpiderMonkey's delete-from-frozen wording and\n // `unable to delete property` is JavaScriptCore's; neither shares any\n // fragment with V8's `cannot delete property`, so both were read as\n // ordinary bugs on Firefox and Safari — the exact mis-attribution this\n // guard exists to end, pointing the other way.\n return /read[- ]?only|not extensible|cannot add property|cannot delete property|can't be deleted|unable to delete property|object is frozen|is not writable/i.test(\n error.message,\n );\n}\n\nfunction deepFreeze<T>(obj: T): T {\n Object.freeze(obj);\n if (obj !== null && typeof obj === \"object\") {\n for (const value of Object.values(obj)) {\n if (value !== null && typeof value === \"object\" && !Object.isFrozen(value)) {\n deepFreeze(value);\n }\n }\n }\n return obj;\n}\n\n// Above this many string characters across messages+state, the dev-only\n// clone+deepFreeze guard is skipped. That guard exists to surface accidental\n// in-place mutation during development — it is NOT required for correctness.\n// Paying a full recursive structuredClone + deepFreeze of the entire messages\n// array AND state object on every streamed event is what exhausts the renderer\n// heap when tool-call arguments stream large payloads (V8 fatal:\n// \"JavaScript heap out of memory\" from structuredClone).\nconst DEV_FREEZE_CHAR_LIMIT = 512 * 1024;\n\n// Cheap, bounded size probe: returns true as soon as the combined string length\n// of messages+state (counting both string values AND object key names, since\n// keys also contribute to clone cost) exceeds `limit`. Does NOT recursively\n// structuredClone or materialize copies — only a bounded iterative traversal\n// stack plus a visited-set guard, so it is safe for arbitrarily nested or\n// cyclic structures. (`State` is typed `any`, so cycles are possible.)\nfunction payloadExceeds(messages: unknown, state: unknown, limit: number): boolean {\n let chars = 0;\n const stack: unknown[] = [messages, state];\n const seen = new WeakSet<object>();\n while (stack.length > 0) {\n const value = stack.pop();\n if (typeof value === \"string\") {\n chars += value.length;\n if (chars > limit) return true;\n } else if (value !== null && typeof value === \"object\") {\n if (seen.has(value as object)) continue;\n seen.add(value as object);\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) stack.push(value[i]);\n } else {\n // Own enumerable keys only — avoids walking the prototype chain and\n // triggering inherited getters (matches deepFreeze's Object.values).\n const keys = Object.keys(value as Record<string, unknown>);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n // Key names contribute to clone cost too; count them as we go.\n chars += key.length;\n if (chars > limit) return true;\n stack.push((value as Record<string, unknown>)[key]);\n }\n }\n }\n }\n return false;\n}\n\nexport async function runSubscribersWithMutation(\n subscribers: AgentSubscriber[],\n initialMessages: Message[],\n initialState: State,\n executor: (\n subscriber: AgentSubscriber,\n messages: ReadonlyArray<Readonly<Message>>,\n state: Readonly<State>,\n ) => MaybePromise<AgentStateMutation | void>,\n): Promise<AgentStateMutation> {\n const hasProcess = typeof process !== \"undefined\" && typeof process.env !== \"undefined\";\n const isTestEnvironment =\n hasProcess && (process.env.NODE_ENV === \"test\" || Boolean(process.env.VITEST_WORKER_ID));\n const isDev =\n hasProcess &&\n (process.env.NODE_ENV === \"development\" ||\n process.env.NODE_ENV === \"test\" ||\n Boolean(process.env.VITEST_WORKER_ID));\n\n // The dev-only clone+deepFreeze guard (which surfaces accidental in-place\n // mutation) is the dominant per-event allocation. Skip it in production, and\n // in dev when the payload is large — otherwise streaming large tool-call\n // arguments deep-clones the whole messages+state on every event and exhausts\n // the heap (V8 fatal: \"JavaScript heap out of memory\" from structuredClone).\n let freezeInputs = isDev && !payloadExceeds(initialMessages, initialState, DEV_FREEZE_CHAR_LIMIT);\n\n // Only the freeze path needs an isolated baseline copy. Otherwise pass the\n // inputs through and lazily clone only when a subscriber actually returns a\n // mutation — so the common \"no mutation\" event costs zero clones.\n let messages: Message[] = freezeInputs ? structuredClone_(initialMessages) : initialMessages;\n let state: State = freezeInputs ? structuredClone_(initialState) : initialState;\n let messagesMutated = false;\n let stateMutated = false;\n\n let stopPropagation: boolean | undefined = undefined;\n\n for (const subscriber of subscribers) {\n try {\n // Subscribers receive shared references and must not mutate them in-place.\n // Mutations should only be communicated via the return value.\n // In dev/test mode (small payloads): deep-freeze inputs so accidental\n // in-place mutations surface as TypeErrors immediately.\n if (freezeInputs) {\n deepFreeze(messages);\n deepFreeze(state);\n }\n const mutation = await executor(subscriber, messages, state);\n\n if (mutation === undefined) {\n // Nothing returned – keep going\n continue;\n }\n\n // Replace with a defensive copy of the subscriber's mutation,\n // but skip if the subscriber returned the same reference (no-op).\n let payloadChanged = false;\n if (mutation.messages !== undefined && mutation.messages !== messages) {\n messages = structuredClone_(mutation.messages);\n messagesMutated = true;\n payloadChanged = true;\n }\n\n if (mutation.state !== undefined && mutation.state !== state) {\n state = structuredClone_(mutation.state);\n stateMutated = true;\n payloadChanged = true;\n }\n\n // If a subscriber's mutation has grown the payload past the limit, drop\n // the freeze guard for the remaining iterations. Otherwise we'd pay a\n // full deepFreeze + final unfreeze-clone of the now-huge structure on\n // every later subscriber — exactly the cost this PR removes.\n if (freezeInputs && payloadChanged) {\n if (payloadExceeds(messages, state, DEV_FREEZE_CHAR_LIMIT)) {\n freezeInputs = false;\n }\n }\n\n stopPropagation = mutation.stopPropagation;\n\n if (stopPropagation === true) {\n break;\n }\n } catch (error) {\n // Preserve the test-mode failure policy independently of the freeze guard:\n // ordinary callback bugs must reject even when inputs are too large to freeze.\n if (isTestEnvironment && error instanceof TypeError) {\n throw error;\n }\n\n // Two different failures used to be conflated here. `error instanceof\n // TypeError` alone attributed EVERY TypeError to the freeze guard --\n // including the everyday `Cannot read properties of undefined`, which\n // has nothing to do with it -- and told the author to stop mutating\n // inputs they never touched. Only an actual write to a frozen or\n // non-extensible object is a freeze violation, and the engine says so in\n // the message.\n if (freezeInputs && isDev && isFrozenWriteError(error)) {\n // In development (non-test), log a specific message to distinguish freeze violations\n // from ordinary subscriber errors.\n console.error(\n \"AG-UI: Subscriber attempted to mutate frozen inputs in-place. \" +\n \"Return mutations via AgentStateMutation instead of mutating directly.\",\n error,\n );\n } else {\n // Logged in EVERY environment. Suppressing this under vitest meant a\n // subscriber that threw was neither logged nor rethrown, so a broken\n // subscriber looked exactly like one that never ran.\n console.error(\"Subscriber error:\", error);\n }\n // Skip this subscriber's mutation and continue\n continue;\n }\n }\n\n // A mutated copy may have been frozen in-place on a later subscriber pass;\n // clone it before returning so callers receive a mutable copy.\n return {\n ...(messagesMutated\n ? { messages: Object.isFrozen(messages) ? structuredClone_(messages) : messages }\n : {}),\n ...(stateMutated ? { state: Object.isFrozen(state) ? structuredClone_(state) : state } : {}),\n ...(stopPropagation !== undefined ? { stopPropagation } : {}),\n };\n}\n","import { Message, ResumeEntry, RunAgentInput, State } from \"@ag-ui/core\";\n\n/** Normalized debug configuration for the AG-UI agent. */\nexport interface ResolvedAgentDebugConfig {\n enabled: boolean;\n events: boolean;\n lifecycle: boolean;\n verbose: boolean;\n}\n\n/** Debug input — boolean shorthand or granular config. */\nexport type AgentDebugConfig =\n | boolean\n | {\n events?: boolean;\n lifecycle?: boolean;\n verbose?: boolean;\n };\n\n/** Resolves an AgentDebugConfig into a normalized ResolvedAgentDebugConfig. */\nexport function resolveAgentDebugConfig(\n debug: AgentDebugConfig | undefined,\n): ResolvedAgentDebugConfig {\n if (!debug) return { enabled: false, events: false, lifecycle: false, verbose: false };\n if (debug === true) return { enabled: true, events: true, lifecycle: true, verbose: true };\n\n const events = debug.events ?? true;\n const lifecycle = debug.lifecycle ?? true;\n const verbose = debug.verbose ?? false;\n return { enabled: events || lifecycle, events, lifecycle, verbose };\n}\n\nexport interface AgentConfig {\n agentId?: string;\n description?: string;\n threadId?: string;\n initialMessages?: Message[];\n initialState?: State;\n debug?: AgentDebugConfig;\n}\n\nexport type HttpAgentFetchFn = (url: string, requestInit: RequestInit) => Promise<Response>;\n\nexport interface HttpAgentConfig extends AgentConfig {\n url: string;\n headers?: Record<string, string>;\n fetch?: HttpAgentFetchFn;\n}\n\nexport interface RunAgentParameters\n extends Partial<Pick<RunAgentInput, \"runId\" | \"tools\" | \"context\" | \"forwardedProps\">> {\n /** Per-interrupt responses addressing every open interrupt from the previous run. */\n resume?: ResumeEntry[];\n}\n","import { ResolvedAgentDebugConfig, resolveAgentDebugConfig } from \"@/agent/types\";\n\n/** Accepted input wherever a debug logger can be provided. */\nexport type DebugLoggerInput = DebugLogger | boolean | null | undefined;\n\n/**\n * Resolves a DebugLoggerInput into a DebugLogger or undefined.\n * - `true` → creates a new DebugLogger with all logging enabled\n * - `DebugLogger` instance → returned as-is\n * - `false`, `null`, `undefined` → returns undefined\n */\nexport function resolveDebugLogger(input: DebugLoggerInput): DebugLogger | undefined {\n if (input instanceof DebugLogger) return input;\n if (input === true) return new DebugLogger(resolveAgentDebugConfig(true));\n return undefined;\n}\n\n/**\n * Centralized debug logger for the AG-UI event pipeline.\n * Handles verbose vs summary output based on config.\n */\nexport class DebugLogger {\n constructor(private config: ResolvedAgentDebugConfig) {}\n\n /**\n * Log an event-level debug message.\n * Only logs when `config.events` is enabled.\n * In verbose mode, logs the full data; otherwise logs the summary.\n */\n event(prefix: string, label: string, data: unknown, summary?: Record<string, unknown>): void {\n if (!this.config.events) return;\n if (this.config.verbose) {\n console.debug(`[${prefix}] ${label}`, typeof data === \"string\" ? data : JSON.stringify(data));\n } else {\n console.debug(`[${prefix}] ${label}`, summary ?? data);\n }\n }\n\n /**\n * Log a lifecycle-level debug message.\n * Only logs when `config.lifecycle` is enabled.\n */\n lifecycle(prefix: string, label: string, data?: Record<string, unknown>): void {\n if (!this.config.lifecycle) return;\n if (data) {\n console.debug(`[${prefix}] ${label}`, data);\n } else {\n console.debug(`[${prefix}] ${label}`);\n }\n }\n\n /** Whether event-level logging is enabled. */\n get eventsEnabled(): boolean {\n return this.config.events;\n }\n\n /** Whether lifecycle-level logging is enabled. */\n get lifecycleEnabled(): boolean {\n return this.config.lifecycle;\n }\n\n /** Whether any logging is enabled. */\n get enabled(): boolean {\n return this.config.enabled;\n }\n}\n\n/**\n * Creates a DebugLogger if debug is enabled, otherwise returns undefined.\n * This allows consumers to pass it around cheaply when debug is off.\n */\nexport function createDebugLogger(config: ResolvedAgentDebugConfig): DebugLogger | undefined {\n return config.enabled ? new DebugLogger(config) : undefined;\n}\n","import { authoritativeActivityTypes } from \"../activity-history\";\nimport type { AbstractAgent } from \"@/agent/agent\";\nimport {\n type AgentStateMutation,\n type AgentSubscriber,\n runSubscribersWithMutation,\n} from \"@/agent/subscriber\";\nimport {\n type ActivityDeltaEvent,\n type ActivityMessage,\n type ActivitySnapshotEvent,\n type AssistantMessage,\n type BaseEvent,\n type CustomEvent,\n EventType,\n type Message,\n type MessagesSnapshotEvent,\n type Metadata,\n mergeMetadata,\n type RawEvent,\n type ReasoningEncryptedValueEvent,\n type ReasoningEndEvent,\n type ReasoningMessage,\n type ReasoningMessageContentEvent,\n type ReasoningMessageEndEvent,\n type ReasoningMessageStartEvent,\n type ReasoningStartEvent,\n type RunAgentInput,\n type RunErrorEvent,\n type RunFinishedEvent,\n type RunStartedEvent,\n type StateDeltaEvent,\n type StateSnapshotEvent,\n type StepFinishedEvent,\n type StepStartedEvent,\n type SubagentErrorEvent,\n type SubagentFinishedEvent,\n type SubagentStartedEvent,\n type TextMessageContentEvent,\n type TextMessageEndEvent,\n type TextMessageStartEvent,\n type ToolCallArgsEvent,\n type ToolCallEndEvent,\n type ToolCallResultEvent,\n type ToolCall,\n type ToolCallStartEvent,\n type ToolMessage,\n} from \"@ag-ui/core\";\nimport jsonpatch from \"fast-json-patch\";\nimport { EMPTY, of } from \"rxjs\";\nimport type { Observable } from \"rxjs\";\nimport { concatMap, defaultIfEmpty, mergeAll } from \"rxjs/operators\";\nimport untruncateJson from \"untruncate-json\";\nimport { structuredClone_ } from \"../utils\";\nimport { type DebugLoggerInput, resolveDebugLogger } from \"@/debug-logger\";\n\n/**\n * Resolves (or creates) the assistant message that a tool call should attach to.\n *\n * Resolution order:\n * 1. `parentMessageId` matches an existing assistant message — return it.\n * 2. `parentMessageId` matches a non-assistant message (collision) — create new, keyed by `toolCallId`.\n * 3. `parentMessageId` not found — create new, keyed by `parentMessageId`.\n * 4. No `parentMessageId` — create new, keyed by `toolCallId`.\n */\nfunction resolveOrCreateAssistantMessage(\n messages: Message[],\n parentMessageId: string | undefined,\n toolCallId: string,\n): AssistantMessage {\n if (parentMessageId) {\n const existing = messages.find((m) => m.id === parentMessageId);\n if (existing?.role === \"assistant\") {\n return existing as AssistantMessage;\n }\n\n if (existing) {\n console.warn(\n `TOOL_CALL_START: parentMessageId '${parentMessageId}' matches a '${existing.role}' message, ` +\n `not assistant — falling back to toolCallId`,\n );\n }\n\n const created: AssistantMessage = {\n id: existing ? toolCallId : parentMessageId,\n role: \"assistant\",\n toolCalls: [],\n };\n messages.push(created);\n return created;\n }\n\n const created: AssistantMessage = { id: toolCallId, role: \"assistant\", toolCalls: [] };\n messages.push(created);\n return created;\n}\n\n/**\n * Folds an event's metadata into the thing that event builds, key by key, with\n * the last write winning.\n *\n * The target is a message, or a tool call for the TOOL_CALL_* events — a tool\n * call is not a message, and several can share one parent assistant message, so\n * folding theirs into that parent would make the result depend on their relative\n * order. Metadata on a run-, step- or state-level event belongs to that event\n * and never reaches either.\n *\n * Values are cloned so the event payload can't alias into the message array and\n * be mutated later through the caller's copy of the event.\n *\n * Returns whether anything changed, so callers only emit a mutation when it did.\n *\n * Known limitation, deliberately not fixed here. Handlers resolve their target\n * before running subscribers, so a subscriber that returns a replacement\n * `messages` array leaves that reference pointing into the discarded one and\n * this write is lost. Review has raised it repeatedly; it is not fixed because\n * the cure is worse than the disease. Re-resolving by id costs an O(n) scan on\n * TEXT_MESSAGE_CONTENT, which fires per streamed token, to fix a case that needs\n * a subscriber replacing the array from that specific hook — and the same\n * staleness already loses the content append on `main`, so it is a pre-existing\n * reducer issue rather than a metadata one. Fixing it belongs in its own change,\n * conditional on `mutation.messages !== undefined` so the hot path pays nothing.\n */\nfunction applyEventMetadata(\n target: { metadata?: Metadata } | undefined,\n event: BaseEvent,\n): boolean {\n if (!target || event.metadata === undefined) {\n return false;\n }\n target.metadata = mergeMetadata(target.metadata, structuredClone_(event.metadata));\n return true;\n}\n\nexport const defaultApplyEvents = (\n input: RunAgentInput,\n events$: Observable<BaseEvent>,\n agent: AbstractAgent,\n subscribers: AgentSubscriber[],\n debugLogger?: DebugLoggerInput,\n): Observable<AgentStateMutation> => {\n const log = resolveDebugLogger(debugLogger);\n let messages = structuredClone_(agent.messages);\n let state = structuredClone_(input.state);\n let currentMutation: AgentStateMutation = {};\n\n // The tool calls this run has started and answered so far. RUN_FINISHED\n // reads them when the success outcome names no `pendingToolCallIds`: the\n // specification lets a consumer derive the pending list from the stream —\n // every call the run started that got no TOOL_CALL_RESULT — and a producer\n // that names the list is trusted over the tally.\n let runToolCallIds: string[] = [];\n let answeredToolCallIds = new Set<string>();\n const pendingToolCallIdsOf = (e: RunFinishedEvent): string[] => {\n const named = e.outcome?.type === \"success\" ? e.outcome.pendingToolCallIds : undefined;\n if (named !== undefined && named.length > 0) return [...named];\n return runToolCallIds.filter((id) => !answeredToolCallIds.has(id));\n };\n\n const applyMutation = (mutation: AgentStateMutation) => {\n if (mutation.messages !== undefined) {\n messages = mutation.messages;\n currentMutation.messages = mutation.messages;\n }\n if (mutation.state !== undefined) {\n state = mutation.state;\n currentMutation.state = mutation.state;\n }\n };\n\n const emitUpdates = () => {\n const result = structuredClone_(currentMutation) as AgentStateMutation;\n currentMutation = {};\n if (result.messages !== undefined || result.state !== undefined) {\n return of(result);\n }\n return EMPTY;\n };\n\n return events$.pipe(\n concatMap(async (event) => {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onEvent?.({ event, agent, input, messages, state }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation === true) {\n log?.event(\"APPLY\", \"Event dropped:\", event, {\n type: event.type,\n reason: \"stopPropagation by subscriber\",\n });\n } else {\n log?.event(\"APPLY\", \"Event applied:\", event, {\n type: event.type,\n subscribers: subscribers.length,\n });\n }\n\n if (mutation.stopPropagation === true) {\n return emitUpdates();\n }\n\n switch (event.type) {\n case EventType.TEXT_MESSAGE_START: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onTextMessageStartEvent?.({\n event: event as TextMessageStartEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n const {\n messageId,\n role = \"assistant\",\n name,\n subagentRunId,\n } = event as TextMessageStartEvent;\n\n // Check if a message with this ID already exists (e.g., created by TOOL_CALL_START\n // with the same parentMessageId)\n const existingMessage = messages.find((m) => m.id === messageId);\n\n if (existingMessage?.role === \"activity\") {\n // Message ids are unique across the conversation, so an activity message under\n // this id means the producer reused it. Streaming text into it would overwrite\n // its structured content with a string. Leave it alone and drop the text — and\n // with it the event's metadata, which describes a text message that never exists.\n console.warn(\n `TEXT_MESSAGE_START: Message '${messageId}' is an activity message — ` +\n `message ids must be unique across activity and text messages`,\n );\n return emitUpdates();\n }\n\n // Annotated: the guard above narrows `existingMessage` to the non-activity\n // members, while the message created below is a full `Message`.\n let targetMessage: Message | undefined = existingMessage;\n\n if (!targetMessage) {\n // Create a new message using properties from the event\n // Text messages can be developer, system, assistant, or user (not tool)\n const newMessage: Message = {\n id: messageId,\n role: role,\n content: \"\",\n ...(name !== undefined && { name }),\n ...(subagentRunId != null && { subagentRunId }),\n };\n\n // Add the new message to the messages array\n messages.push(newMessage);\n targetMessage = newMessage;\n }\n // If message already exists, we don't need to create a new one\n // The TEXT_MESSAGE_CONTENT events will update the existing message's content\n\n const metadataChanged = applyEventMetadata(targetMessage, event);\n if (!existingMessage || metadataChanged) {\n applyMutation({ messages });\n }\n }\n return emitUpdates();\n }\n\n case EventType.TEXT_MESSAGE_CONTENT: {\n const { messageId, delta } = event as TextMessageContentEvent;\n\n // Find the target message by ID\n const targetMessage = messages.find((m) => m.id === messageId);\n if (!targetMessage) {\n console.warn(`TEXT_MESSAGE_CONTENT: No message found with ID '${messageId}'`);\n return emitUpdates();\n }\n if (targetMessage.role === \"activity\") {\n // Appending here would replace the activity message's structured content with a\n // string, leaving it no longer a valid ActivityMessage.\n console.warn(\n `TEXT_MESSAGE_CONTENT: Message '${messageId}' is an activity message — ` +\n `message ids must be unique across activity and text messages`,\n );\n return emitUpdates();\n }\n\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onTextMessageContentEvent?.({\n event: event as TextMessageContentEvent,\n messages,\n state,\n agent,\n input,\n textMessageBuffer:\n typeof targetMessage.content === \"string\" ? targetMessage.content : \"\",\n }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n // Append content to the correct message by ID\n const existingContent =\n typeof targetMessage.content === \"string\" ? targetMessage.content : \"\";\n targetMessage.content = `${existingContent}${delta}`;\n applyEventMetadata(targetMessage, event);\n applyMutation({ messages });\n }\n\n return emitUpdates();\n }\n\n case EventType.TEXT_MESSAGE_END: {\n const { messageId } = event as TextMessageEndEvent;\n\n // Find the target message by ID\n const targetMessage = messages.find((m) => m.id === messageId);\n if (!targetMessage) {\n console.warn(`TEXT_MESSAGE_END: No message found with ID '${messageId}'`);\n return emitUpdates();\n }\n if (targetMessage.role === \"activity\") {\n // The matching TEXT_MESSAGE_START was dropped for the same reason, so there is no\n // text message to finish — don't announce the activity message as a new one.\n console.warn(\n `TEXT_MESSAGE_END: Message '${messageId}' is an activity message — ` +\n `message ids must be unique across activity and text messages`,\n );\n return emitUpdates();\n }\n\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onTextMessageEndEvent?.({\n event: event as TextMessageEndEvent,\n messages,\n state,\n agent,\n input,\n textMessageBuffer:\n typeof targetMessage.content === \"string\" ? targetMessage.content : \"\",\n }),\n );\n applyMutation(mutation);\n\n // Merge before onNewMessage so subscribers see the completed message.\n // An end event is where late-known values — token usage, finish\n // reason — typically arrive.\n if (mutation.stopPropagation !== true && applyEventMetadata(targetMessage, event)) {\n applyMutation({ messages });\n }\n\n await Promise.all(\n subscribers.map((subscriber) => {\n subscriber.onNewMessage?.({\n message: targetMessage,\n messages,\n state,\n agent,\n input,\n });\n }),\n );\n\n return emitUpdates();\n }\n\n case EventType.TOOL_CALL_START: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onToolCallStartEvent?.({\n event: event as ToolCallStartEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n const { toolCallId, toolCallName, parentMessageId, subagentRunId } =\n event as ToolCallStartEvent;\n if (!runToolCallIds.includes(toolCallId)) runToolCallIds.push(toolCallId);\n\n // Applying a start event must be idempotent. The same start can\n // reach this reducer twice — a tool call already carried in\n // `agent.messages` from an earlier run and then replayed by the\n // backend (the HITL path does this when the run re-syncs after\n // `respond()`), or one stream re-delivered over two transports.\n // Appending unconditionally would leave the assistant message\n // holding the id twice, and the second copy stays empty because\n // TOOL_CALL_ARGS resolves to the first match. That malformed\n // message is then what travels back to the provider on the next\n // turn. Resolve the existing entry the same way TOOL_CALL_ARGS\n // does, and do it before resolveOrCreateAssistantMessage so a\n // replay can't append a stray empty assistant message either.\n const ownerMessage = messages.find((m) =>\n (m as AssistantMessage).toolCalls?.some((tc) => tc.id === toolCallId),\n ) as AssistantMessage | undefined;\n const existingToolCall = ownerMessage?.toolCalls?.find((tc) => tc.id === toolCallId);\n\n if (existingToolCall) {\n // Update the existing entry instead of pushing a second one, and\n // leave `arguments` untouched — a start event carries none, so\n // the copy already in state holds the only streamed args.\n const renamed = existingToolCall.function.name !== toolCallName;\n if (renamed) {\n console.warn(\n `TOOL_CALL_START: tool call '${toolCallId}' already exists with name ` +\n `'${existingToolCall.function.name}' — updating it to '${toolCallName}'`,\n );\n existingToolCall.function.name = toolCallName;\n }\n\n if (applyEventMetadata(existingToolCall, event) || renamed) {\n applyMutation({ messages });\n }\n\n return emitUpdates();\n }\n\n const preexistingIds = new Set(messages.map((m) => m.id));\n const targetMessage = resolveOrCreateAssistantMessage(\n messages,\n parentMessageId,\n toolCallId,\n );\n const wasCreated = !preexistingIds.has(targetMessage.id);\n if (wasCreated && subagentRunId != null && targetMessage.subagentRunId === undefined) {\n targetMessage.subagentRunId = subagentRunId;\n }\n\n targetMessage.toolCalls ??= [];\n\n // Add the new tool call\n const newToolCall: ToolCall = {\n id: toolCallId,\n type: \"function\",\n function: {\n name: toolCallName,\n arguments: \"\",\n },\n };\n targetMessage.toolCalls.push(newToolCall);\n\n applyEventMetadata(newToolCall, event);\n\n applyMutation({ messages });\n }\n\n return emitUpdates();\n }\n\n case EventType.TOOL_CALL_ARGS: {\n const { toolCallId, delta } = event as ToolCallArgsEvent;\n\n // Find the message containing this tool call\n const targetMessage = messages.find((m) =>\n (m as AssistantMessage).toolCalls?.some((tc) => tc.id === toolCallId),\n ) as AssistantMessage;\n\n if (!targetMessage) {\n console.warn(\n `TOOL_CALL_ARGS: No message found containing tool call with ID '${toolCallId}'`,\n );\n return emitUpdates();\n }\n\n // Find the specific tool call\n const targetToolCall = targetMessage.toolCalls?.find((tc) => tc.id === toolCallId);\n if (!targetToolCall) {\n console.warn(`TOOL_CALL_ARGS: No tool call found with ID '${toolCallId}'`);\n return emitUpdates();\n }\n\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) => {\n const toolCallBuffer = targetToolCall.function.arguments;\n const toolCallName = targetToolCall.function.name;\n let partialToolCallArgs = {};\n try {\n // Parse from toolCallBuffer only (before current delta is applied)\n partialToolCallArgs = untruncateJson(toolCallBuffer);\n } catch (_error) {\n // Streaming args are mid-flight and frequently unparseable;\n // fall through with the last good partial object.\n }\n\n return subscriber.onToolCallArgsEvent?.({\n event: event as ToolCallArgsEvent,\n messages,\n state,\n agent,\n input,\n toolCallBuffer,\n toolCallName,\n partialToolCallArgs,\n });\n },\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n // Append the arguments to the correct tool call by ID\n targetToolCall.function.arguments += delta;\n applyEventMetadata(targetToolCall, event);\n applyMutation({ messages });\n }\n\n return emitUpdates();\n }\n\n case EventType.TOOL_CALL_END: {\n const { toolCallId } = event as ToolCallEndEvent;\n\n // Find the message containing this tool call\n const targetMessage = messages.find((m) =>\n (m as AssistantMessage).toolCalls?.some((tc) => tc.id === toolCallId),\n ) as AssistantMessage;\n\n if (!targetMessage) {\n console.warn(\n `TOOL_CALL_END: No message found containing tool call with ID '${toolCallId}'`,\n );\n return emitUpdates();\n }\n\n // Find the specific tool call\n const targetToolCall = targetMessage.toolCalls?.find((tc) => tc.id === toolCallId);\n if (!targetToolCall) {\n console.warn(`TOOL_CALL_END: No tool call found with ID '${toolCallId}'`);\n return emitUpdates();\n }\n\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) => {\n const toolCallArgsString = targetToolCall.function.arguments;\n const toolCallName = targetToolCall.function.name;\n let toolCallArgs = {};\n try {\n toolCallArgs = JSON.parse(toolCallArgsString);\n } catch (_error) {\n // A malformed final payload must not abort the run; downstream\n // sees the empty object.\n }\n return subscriber.onToolCallEndEvent?.({\n event: event as ToolCallEndEvent,\n messages,\n state,\n agent,\n input,\n toolCallName,\n toolCallArgs,\n });\n },\n );\n applyMutation(mutation);\n\n // Merge before onNewToolCall, for the same reason as TEXT_MESSAGE_END:\n // an end event carries the values only known once the call is closed.\n if (mutation.stopPropagation !== true && applyEventMetadata(targetToolCall, event)) {\n applyMutation({ messages });\n }\n\n await Promise.all(\n subscribers.map((subscriber) => {\n subscriber.onNewToolCall?.({\n toolCall: targetToolCall,\n messages,\n state,\n agent,\n input,\n });\n }),\n );\n\n return emitUpdates();\n }\n\n case EventType.TOOL_CALL_RESULT: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onToolCallResultEvent?.({\n event: event as ToolCallResultEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n const { messageId, toolCallId, content, role, subagentRunId } =\n event as ToolCallResultEvent;\n answeredToolCallIds.add(toolCallId);\n\n const toolMessage: ToolMessage = {\n id: messageId,\n toolCallId,\n role: role || \"tool\",\n content: content,\n ...(subagentRunId != null && { subagentRunId }),\n };\n\n applyEventMetadata(toolMessage, event);\n\n // Place the tool result immediately after the assistant message that\n // issued the matching tool call — not at the end. A result event can\n // arrive after a trailing assistant text message (e.g. a\n // chat -> tool -> chat loop streams the follow-up text before the\n // result is recorded). Appending would leave the history as\n // assistant(tool_call) -> text -> tool, which violates the provider\n // contract that an assistant tool_call is immediately followed by its\n // tool result and surfaces downstream as a 400. Skip past any tool\n // results already recorded for the same assistant so parallel results\n // keep their order. Fall back to append when no owner is found.\n const ownerIndex = messages.findIndex(\n (m) =>\n m.role === \"assistant\" &&\n (m as AssistantMessage).toolCalls?.some((tc) => tc.id === toolCallId),\n );\n if (ownerIndex === -1) {\n messages.push(toolMessage);\n } else {\n let insertAt = ownerIndex + 1;\n while (insertAt < messages.length && messages[insertAt].role === \"tool\") {\n insertAt++;\n }\n messages.splice(insertAt, 0, toolMessage);\n }\n\n await Promise.all(\n subscribers.map((subscriber) => {\n subscriber.onNewMessage?.({\n message: toolMessage,\n messages,\n state,\n agent,\n input,\n });\n }),\n );\n\n applyMutation({ messages });\n }\n\n return emitUpdates();\n }\n\n case EventType.STATE_SNAPSHOT: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onStateSnapshotEvent?.({\n event: event as StateSnapshotEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n const { snapshot } = event as StateSnapshotEvent;\n\n // Replace state with the literal snapshot\n state = snapshot;\n\n applyMutation({ state });\n }\n\n return emitUpdates();\n }\n\n case EventType.STATE_DELTA: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onStateDeltaEvent?.({\n event: event as StateDeltaEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n const { delta } = event as StateDeltaEvent;\n\n try {\n // Apply the JSON Patch operations to the current state without mutating the original\n const result = jsonpatch.applyPatch(state, delta, true, false);\n state = result.newDocument;\n applyMutation({ state });\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.warn(\n `Failed to apply state patch:\\nCurrent state: ${JSON.stringify(state, null, 2)}\\nPatch operations: ${JSON.stringify(delta, null, 2)}\\nError: ${errorMessage}`,\n );\n // If patch failed, only emit updates if there were subscriber mutations\n // This prevents emitting updates when both patch fails AND no subscriber mutations\n }\n }\n\n return emitUpdates();\n }\n\n case EventType.MESSAGES_SNAPSHOT: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onMessagesSnapshotEvent?.({\n event: event as MessagesSnapshotEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n const { messages: rawNewMessages } = event as MessagesSnapshotEvent;\n // A runtime null tag reads as absent — it must not persist into state\n // and ride the next run's serialized input (the schemas forbid null;\n // this reducer also runs on unverified inputs).\n const newMessages = rawNewMessages.map((m) => {\n if ((m as { subagentRunId?: string | null }).subagentRunId !== null) return m;\n // Spread + delete: Message is a union, so rest-destructuring is a\n // tsc error (TS2700).\n const copy = { ...m } as typeof m & { subagentRunId?: string | null };\n delete copy.subagentRunId;\n return copy as typeof m;\n });\n\n // Update existing messages in place and append new snapshot messages,\n // preserving client-only messages the backend leaves out.\n const snapshotMap = new Map(newMessages.map((m) => [m.id, m]));\n\n // `activity` messages are only sometimes client-only. They never\n // travel back to the backend — `prepareRunAgentInput` strips them\n // from RunAgentInput — so a backend that does not track them cannot\n // put them in the snapshot, and the local copies must be preserved.\n // But a backend that does track them re-delivers the whole set it\n // owns. Since a MESSAGES_SNAPSHOT is a snapshot of every message,\n // once it carries any activity the backend is declaring the complete\n // activity set, and one it leaves out has been removed — preserving\n // it would make the local copy undeletable. So when the snapshot\n // itself carries activity, treat it as the source of truth for\n // activity messages and apply the normal replace semantics.\n //\n // `reasoning` messages are only sometimes client-only. Most backends\n // never include reasoning in the snapshot (it exists purely as\n // streamed REASONING_* events), so dropping local reasoning here\n // would lose it. But a backend that round-trips reasoning (e.g.\n // LangGraph re-deriving it from checkpointed content blocks)\n // re-delivers the streamed reasoning under its own canonical id —\n // message ids are generally NOT stable between streamed events and\n // the snapshot. Preserving the streamed copy next to the snapshot\n // copy would render the same reasoning twice. So when the snapshot\n // itself carries reasoning, treat it as the source of truth for\n // reasoning messages too and apply the normal replace semantics.\n // Explicit null replaces all types, including an empty activity set.\n // Arrays replace only their types; absent declarations use the rule above.\n // Invalid declarations own no types. Matching IDs always update.\n const ownedActivityTypes = authoritativeActivityTypes(event as MessagesSnapshotEvent);\n const snapshotHasActivity = newMessages.some((m) => m.role === \"activity\");\n const snapshotHasReasoning = newMessages.some((m) => m.role === \"reasoning\");\n const isPreservedClientOnly = (m: Message) =>\n (m.role === \"activity\" &&\n (ownedActivityTypes\n ? !ownedActivityTypes.includes(m.activityType)\n : ownedActivityTypes !== null && !snapshotHasActivity)) ||\n (m.role === \"reasoning\" && !snapshotHasReasoning);\n\n // A matching ID updates even when this snapshot cannot delete that\n // activity type. Authority applies only to messages omitted from it.\n messages = messages\n .filter((m) => snapshotMap.has(m.id) || isPreservedClientOnly(m))\n .map((m) => snapshotMap.get(m.id) ?? m);\n\n const existingIds = new Set(messages.map((m) => m.id));\n for (const snapshotMsg of newMessages) {\n if (!existingIds.has(snapshotMsg.id)) {\n messages.push(snapshotMsg);\n }\n }\n\n applyMutation({ messages });\n }\n\n return emitUpdates();\n }\n\n case EventType.ACTIVITY_SNAPSHOT: {\n const activityEvent = event as ActivitySnapshotEvent;\n const existingIndex = messages.findIndex((m) => m.id === activityEvent.messageId);\n const existingMessage = existingIndex >= 0 ? messages[existingIndex] : undefined;\n const existingActivityMessage =\n existingMessage?.role === \"activity\" ? (existingMessage as ActivityMessage) : undefined;\n const replace = activityEvent.replace ?? true;\n\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onActivitySnapshotEvent?.({\n event: activityEvent,\n messages,\n state,\n agent,\n input,\n activityMessage: existingActivityMessage,\n existingMessage,\n }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n const activityMessage: ActivityMessage = {\n id: activityEvent.messageId,\n role: \"activity\",\n activityType: activityEvent.activityType,\n content: structuredClone_(activityEvent.content),\n ...(activityEvent.subagentRunId != null && {\n subagentRunId: activityEvent.subagentRunId,\n }),\n };\n\n let createdMessage: ActivityMessage | undefined;\n let mergeTarget: Message | undefined;\n\n if (existingIndex === -1) {\n messages.push(activityMessage);\n createdMessage = activityMessage;\n mergeTarget = activityMessage;\n } else if (existingActivityMessage) {\n if (replace) {\n // Spread carries the accumulated metadata across the replace —\n // a snapshot replaces content, not the metadata built up so far.\n // Attribution is the exception: a replace snapshot re-mints the\n // activity, so it brings its own subagentRunId with it (D4: a\n // creation event's tag transfers to the message it mints). Keeping\n // the old owner here left a subagent's replacement parent-owned —\n // and, in the other direction, a parent snapshot could never\n // reclaim an activity a subagent had taken.\n messages[existingIndex] = {\n ...existingActivityMessage,\n activityType: activityEvent.activityType,\n content: structuredClone_(activityEvent.content),\n subagentRunId: activityEvent.subagentRunId,\n };\n if (activityEvent.subagentRunId == null) {\n delete (messages[existingIndex] as { subagentRunId?: string }).subagentRunId;\n }\n }\n mergeTarget = messages[existingIndex];\n } else if (replace) {\n messages[existingIndex] = activityMessage;\n createdMessage = activityMessage;\n mergeTarget = activityMessage;\n }\n\n applyEventMetadata(mergeTarget, activityEvent);\n\n applyMutation({ messages });\n\n if (createdMessage) {\n await Promise.all(\n subscribers.map((subscriber) =>\n subscriber.onNewMessage?.({\n message: createdMessage,\n messages,\n state,\n agent,\n input,\n }),\n ),\n );\n }\n }\n\n return emitUpdates();\n }\n\n case EventType.ACTIVITY_DELTA: {\n const activityEvent = event as ActivityDeltaEvent;\n const existingIndex = messages.findIndex((m) => m.id === activityEvent.messageId);\n if (existingIndex === -1) {\n return emitUpdates();\n }\n\n const existingMessage = messages[existingIndex];\n if (existingMessage.role !== \"activity\") {\n console.warn(\n `ACTIVITY_DELTA: Message '${activityEvent.messageId}' is not an activity message`,\n );\n return emitUpdates();\n }\n\n const existingActivityMessage = existingMessage as ActivityMessage;\n\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onActivityDeltaEvent?.({\n event: activityEvent,\n messages,\n state,\n agent,\n input,\n activityMessage: existingActivityMessage,\n }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n try {\n // Metadata does not depend on the patch succeeding — a stale path\n // should not cost the message its usage or trace keys — so merge\n // it before attempting the patch and emit it either way.\n if (applyEventMetadata(existingActivityMessage, activityEvent)) {\n applyMutation({ messages });\n }\n\n const baseContent = structuredClone_(existingActivityMessage.content ?? {});\n\n const result = jsonpatch.applyPatch(\n baseContent,\n activityEvent.patch ?? [],\n true,\n false,\n );\n const updatedContent = result.newDocument as ActivityMessage[\"content\"];\n\n // The spread carries the metadata merged above.\n messages[existingIndex] = {\n ...existingActivityMessage,\n content: structuredClone_(updatedContent),\n activityType: activityEvent.activityType,\n };\n\n applyMutation({ messages });\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.warn(\n `Failed to apply activity patch for '${activityEvent.messageId}': ${errorMessage}`,\n );\n }\n }\n\n return emitUpdates();\n }\n\n case EventType.RAW: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onRawEvent?.({\n event: event as RawEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n return emitUpdates();\n }\n\n case EventType.CUSTOM: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onCustomEvent?.({\n event: event as CustomEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n return emitUpdates();\n }\n\n case EventType.RUN_STARTED: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onRunStartedEvent?.({\n event: event as RunStartedEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n // A new run starts a new tally: pending calls are run-scoped.\n runToolCallIds = [];\n answeredToolCallIds = new Set<string>();\n\n // Handle input.messages if present and stopPropagation is not set\n if (mutation.stopPropagation !== true) {\n const runStartedEvent = event as RunStartedEvent;\n\n // Check if the event contains input with messages\n if (runStartedEvent.input?.messages) {\n // Add messages that aren't already present (checked by ID)\n for (const rawMessage of runStartedEvent.input.messages) {\n // Same null-as-absent rule as the snapshot merge above.\n let message = rawMessage;\n if ((rawMessage as { subagentRunId?: string | null }).subagentRunId === null) {\n const copy = { ...rawMessage } as typeof rawMessage & {\n subagentRunId?: string | null;\n };\n delete copy.subagentRunId;\n message = copy as typeof rawMessage;\n }\n const existingMessage = messages.find((m) => m.id === message.id);\n if (!existingMessage) {\n messages.push(message);\n }\n }\n\n // Apply mutation to emit the updated messages\n applyMutation({ messages });\n }\n }\n\n return emitUpdates();\n }\n\n case EventType.RUN_FINISHED: {\n const e = event as RunFinishedEvent;\n // Absent means success; a cancelled run carries neither a result nor\n // anything to answer, so its params are the bare event.\n const finishedParams =\n e.outcome?.type === \"interrupt\"\n ? ({\n event: e,\n outcome: \"interrupt\" as const,\n interrupts: e.outcome.interrupts,\n } as const)\n : e.outcome?.type === \"cancelled\"\n ? ({ event: e, outcome: \"cancelled\" as const } as const)\n : ({\n event: e,\n outcome: \"success\" as const,\n result: e.result,\n pendingToolCallIds: pendingToolCallIdsOf(e),\n } as const);\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onRunFinishedEvent?.({\n ...finishedParams,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n // Update pending interrupts AFTER subscribers run, and only if no\n // subscriber suppressed the event — matches the lifecycle pattern\n // used by every other case in this switch. Defensive-copy the\n // interrupt list so consumers that hold the original event payload\n // can't mutate the agent's tracked state through array aliasing.\n if (mutation.stopPropagation !== true) {\n agent.pendingInterrupts =\n finishedParams.outcome === \"interrupt\"\n ? finishedParams.interrupts.map((interrupt) => {\n if ((interrupt as { subagentRunId?: string | null }).subagentRunId !== null) {\n return interrupt;\n }\n const copy = { ...interrupt } as typeof interrupt & {\n subagentRunId?: string | null;\n };\n delete copy.subagentRunId;\n return copy as typeof interrupt;\n })\n : [];\n }\n\n return emitUpdates();\n }\n\n case EventType.RUN_ERROR: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onRunErrorEvent?.({\n event: event as RunErrorEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n return emitUpdates();\n }\n\n case EventType.STEP_STARTED: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onStepStartedEvent?.({\n event: event as StepStartedEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n return emitUpdates();\n }\n\n case EventType.STEP_FINISHED: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onStepFinishedEvent?.({\n event: event as StepFinishedEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n return emitUpdates();\n }\n\n case EventType.TEXT_MESSAGE_CHUNK: {\n throw new Error(\"TEXT_MESSAGE_CHUNK must be transformed before being applied\");\n }\n\n case EventType.TOOL_CALL_CHUNK: {\n throw new Error(\"TOOL_CALL_CHUNK must be transformed before being applied\");\n }\n\n case EventType.REASONING_START: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onReasoningStartEvent?.({\n event: event as ReasoningStartEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n return emitUpdates();\n }\n\n case EventType.REASONING_MESSAGE_START: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onReasoningMessageStartEvent?.({\n event: event as ReasoningMessageStartEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n const { messageId, subagentRunId } = event as ReasoningMessageStartEvent;\n const existingMessage = messages.find((m) => m.id === messageId);\n\n if (existingMessage?.role === \"activity\") {\n // Message ids are unique across the conversation, so an activity message under\n // this id means the producer reused it. Streaming reasoning into it would\n // overwrite its structured content with a string. Leave it alone and drop the\n // event — and with it its metadata, which describes a reasoning message that\n // never exists.\n console.warn(\n `REASONING_MESSAGE_START: Message '${messageId}' is an activity message — ` +\n `message ids must be unique across activity and reasoning messages`,\n );\n return emitUpdates();\n }\n\n let targetMessage = existingMessage;\n\n if (!targetMessage) {\n const newMessage: ReasoningMessage = {\n id: messageId,\n role: \"reasoning\",\n content: \"\",\n ...(subagentRunId != null && { subagentRunId }),\n };\n messages.push(newMessage);\n targetMessage = newMessage;\n }\n\n const metadataChanged = applyEventMetadata(targetMessage, event);\n if (!existingMessage || metadataChanged) {\n applyMutation({ messages });\n }\n }\n return emitUpdates();\n }\n\n case EventType.REASONING_MESSAGE_CONTENT: {\n const { messageId, delta } = event as ReasoningMessageContentEvent;\n\n const targetMessage = messages.find((m) => m.id === messageId);\n if (!targetMessage) {\n console.warn(`REASONING_MESSAGE_CONTENT: No message found with ID '${messageId}'`);\n return emitUpdates();\n }\n if (targetMessage.role === \"activity\") {\n // Appending here would replace the activity message's structured content with a\n // string, leaving it no longer a valid ActivityMessage.\n console.warn(\n `REASONING_MESSAGE_CONTENT: Message '${messageId}' is an activity message — ` +\n `message ids must be unique across activity and reasoning messages`,\n );\n return emitUpdates();\n }\n\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onReasoningMessageContentEvent?.({\n event: event as ReasoningMessageContentEvent,\n messages,\n state,\n agent,\n input,\n reasoningMessageBuffer:\n typeof targetMessage.content === \"string\" ? targetMessage.content : \"\",\n }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true) {\n const existingContent =\n typeof targetMessage.content === \"string\" ? targetMessage.content : \"\";\n targetMessage.content = `${existingContent}${delta}`;\n applyEventMetadata(targetMessage, event);\n applyMutation({ messages });\n }\n return emitUpdates();\n }\n\n case EventType.REASONING_MESSAGE_END: {\n const { messageId } = event as ReasoningMessageEndEvent;\n\n const targetMessage = messages.find((m) => m.id === messageId);\n if (!targetMessage) {\n console.warn(`REASONING_MESSAGE_END: No message found with ID '${messageId}'`);\n return emitUpdates();\n }\n if (targetMessage.role === \"activity\") {\n // The matching REASONING_MESSAGE_START was dropped for the same reason, so there\n // is no reasoning message to finish — don't announce the activity message as one.\n console.warn(\n `REASONING_MESSAGE_END: Message '${messageId}' is an activity message — ` +\n `message ids must be unique across activity and reasoning messages`,\n );\n return emitUpdates();\n }\n\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onReasoningMessageEndEvent?.({\n event: event as ReasoningMessageEndEvent,\n messages,\n state,\n agent,\n input,\n reasoningMessageBuffer:\n typeof targetMessage.content === \"string\" ? targetMessage.content : \"\",\n }),\n );\n applyMutation(mutation);\n\n if (mutation.stopPropagation !== true && applyEventMetadata(targetMessage, event)) {\n applyMutation({ messages });\n }\n\n await Promise.all(\n subscribers.map((subscriber) => {\n subscriber.onNewMessage?.({\n message: targetMessage,\n messages,\n state,\n agent,\n input,\n });\n }),\n );\n\n return emitUpdates();\n }\n\n case EventType.REASONING_MESSAGE_CHUNK: {\n throw new Error(\"REASONING_MESSAGE_CHUNK must be transformed before being applied\");\n }\n\n case EventType.REASONING_END: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onReasoningEndEvent?.({\n event: event as ReasoningEndEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n return emitUpdates();\n }\n\n // REASONING_ENCRYPTED_VALUE attaches an encrypted blob to an entity that\n // already exists; it does not build one, so its metadata stays on the\n // event, like REASONING_START and REASONING_END. That also keeps the\n // compaction invariant intact: `compactEvents` buffers an event arriving\n // mid-stream and flushes it *after* the END it originally preceded, so\n // merging its metadata into the same entity would make a compacted\n // replay disagree with the original stream.\n case EventType.REASONING_ENCRYPTED_VALUE: {\n const { subtype, entityId, encryptedValue } = event as ReasoningEncryptedValueEvent;\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onReasoningEncryptedValueEvent?.({\n event: event as ReasoningEncryptedValueEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n if (mutation.stopPropagation !== true) {\n let entityUpdated = false;\n if (subtype === \"tool-call\") {\n // Find tool call by entityId and set encryptedValue\n for (const message of messages) {\n if (message.role === \"assistant\" && message.toolCalls) {\n const toolCall = message.toolCalls.find((tc) => tc.id === entityId);\n if (toolCall) {\n toolCall.encryptedValue = encryptedValue;\n entityUpdated = true;\n break;\n }\n }\n }\n } else {\n // subtype is \"message\"\n // Find message by entityId and set encryptedValue\n const message = messages.find((m) => m.id === entityId);\n // Activity messages do not have encryptedValue\n if (message?.role !== \"activity\" && message) {\n message.encryptedValue = encryptedValue;\n entityUpdated = true;\n }\n }\n if (entityUpdated) {\n currentMutation.messages = messages;\n }\n }\n return emitUpdates();\n }\n\n case EventType.SUBAGENT_STARTED: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onSubagentStartedEvent?.({\n event: event as SubagentStartedEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n return emitUpdates();\n }\n\n case EventType.SUBAGENT_FINISHED: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onSubagentFinishedEvent?.({\n event: event as SubagentFinishedEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n return emitUpdates();\n }\n\n case EventType.SUBAGENT_ERROR: {\n const mutation = await runSubscribersWithMutation(\n subscribers,\n messages,\n state,\n (subscriber, messages, state) =>\n subscriber.onSubagentErrorEvent?.({\n event: event as SubagentErrorEvent,\n messages,\n state,\n agent,\n input,\n }),\n );\n applyMutation(mutation);\n return emitUpdates();\n }\n }\n\n // This makes TypeScript check that the switch is exhaustive\n // If a new EventType is added, this will cause a compile error\n const _exhaustiveCheck: never = event.type;\n return emitUpdates();\n }),\n mergeAll(),\n // Only use defaultIfEmpty when there are subscribers to avoid emitting empty updates\n // when patches fail and there are no subscribers (like in state patching test)\n subscribers.length > 0 ? defaultIfEmpty({} as AgentStateMutation) : <T>(stream: T) => stream,\n );\n};\n","import { BaseEvent, EventType, AGUIError } from \"@ag-ui/core\";\nimport { Observable, throwError, of } from \"rxjs\";\nimport { mergeMap } from \"rxjs/operators\";\nimport { type DebugLoggerInput, resolveDebugLogger } from \"@/debug-logger\";\n\nexport const verifyEvents =\n (debugLogger?: DebugLoggerInput) =>\n (source$: Observable<BaseEvent>): Observable<BaseEvent> => {\n const log = resolveDebugLogger(debugLogger);\n // Declare variables in closure to maintain state across events.\n // The four sets below hold IDS ONLY: membership answers \"is this entity still open?\"\n // (for activities, which have no close event, \"has it been seen at all?\"). Ownership\n // is NOT here — it lives in `owners` below, which is what every attribution check\n // reads, openers included.\n const activeMessages = new Set<string>(); // open text message IDs\n const activeToolCalls = new Set<string>(); // open tool call IDs\n // Activity messages are keyed by their own messageId and continued by\n // ACTIVITY_DELTA, so they need an owner tracked for them just like text messages —\n // see `owners.activity`. This set only records that the activity exists, which is\n // what tells a replacing snapshot from a first one.\n // Reasoning has TWO bracketed entities, not one. A SPAN is opened by\n // REASONING_START and closed by REASONING_END; a reasoning MESSAGE is opened by\n // REASONING_MESSAGE_START and closed by REASONING_MESSAGE_END. The specification\n // says the span's identifier \"namespaces nothing\" and the messages inside carry\n // their own ids, so the two are tracked separately — which also means one id may\n // legitimately name both, as several producers spell it, without either opener\n // reading as a re-open of the other.\n //\n // Both sets are membership-only (\"is this still open?\"). A single shared set was\n // kept before, and never read by anything: reasoning was the one streaming entity\n // whose open/close discipline went unverified, so a content event with no opener,\n // a message never closed, and a span closed without being opened all passed.\n // Ownership is separate again and lives in `owners.reasoning` below, deliberately\n // shared across both kinds so a span and the message inside it cannot be claimed\n // by different producers.\n //\n // REASONING_ENCRYPTED_VALUE also continues a reasoning message, but it is keyed by\n // `entityId`, its `subtype` may route it to a different bucket entirely, and it\n // opens and closes nothing — so it is checked for ownership only.\n const activeReasoningSpans = new Set<string>(); // open REASONING_START ids\n const activeReasoningMessages = new Set<string>(); // open REASONING_MESSAGE_START ids\n // Owners, retained for the whole run, in one bucket PER ENTITY KIND. An id is only\n // unique within a kind: a message and a tool call may both be called \"x\" with no\n // conflict. A single bucket let the tool-call write overwrite the message's owner, so\n // a later encrypted value naming that id was checked against the wrong owner and\n // accepted. .NET already keeps separate maps per kind; this matches it.\n //\n // Retained rather than cleared on close, because a continuation can legitimately\n // arrive after its entity closed -- REASONING_ENCRYPTED_VALUE with subtype\n // \"tool-call\" after TOOL_CALL_END is the case in point, and nothing requires it to\n // precede the close. Losing the owner there made the mismatch unmatchable and\n // accepted a wrong one. The active* sets above stay purely \"is this entity open?\".\n type Owner = { subagentRunId?: string };\n const owners = {\n message: new Map<string, Owner>(),\n toolCall: new Map<string, Owner>(),\n activity: new Map<string, Owner>(),\n reasoning: new Map<string, Owner>(),\n };\n let runFinished = false;\n let runError = false; // New flag to track if RUN_ERROR has been sent\n // New flags to track first/last event requirements\n let firstEventReceived = false;\n // Track active steps, keyed by OWNER + name rather than name alone. A step name is\n // only unique within one agent: a subagent routinely runs the same graph shape as its\n // parent, so both legitimately have a step called \"tools\" open at once (the parent's\n // wraps the delegation, the subagent's is its own inner work). Keying by name alone\n // rejected that valid nesting with `Step \"tools\" is already active`, while ACCEPTING a\n // STEP_FINISHED that closed the parent's step under the subagent's tag -- the exact\n // shape a design partner reported from a real deepagents run.\n // owner -> stepName -> true. Kept as a NESTED map rather than one joined key:\n // joining the owner and the name with a separator made the parent (no owner) collide\n // with a subagent whose id is the empty string, which is a legal opaque id -- so that\n // subagent could close the parent's step. .NET keys on a (owner, name) tuple and so\n // never had the problem; nesting matches it. A Map distinguishes the `undefined` key\n // from the \"\" key, which is exactly the distinction that was lost.\n const activeSteps = new Map<string | undefined, Map<string, true>>();\n const stepsFor = (owner: string | undefined) => {\n let m = activeSteps.get(owner);\n if (!m) {\n m = new Map<string, true>();\n activeSteps.set(owner, m);\n }\n return m;\n };\n const anyStepsActive = () => {\n for (const m of activeSteps.values()) if (m.size > 0) return true;\n return false;\n };\n const activeSubagents = new Map<string, boolean>(); // Map of subagent ID -> active status\n // Ids closed by a SUBAGENT_FINISHED / SUBAGENT_ERROR in this run. Needed because\n // \"no duplicate SUBAGENT_STARTED for the same subagentRunId\" has to hold for the whole\n // run: a subagentRunId is a unique handle for ONE invocation, so tracking only the\n // ACTIVE set made `STARTED(s1), FINISHED(s1), STARTED(s1)` legal and gave a single\n // invocation two starts and two terminals.\n //\n // Deliberately NOT used to reject later events tagged with a closed id. The rule is\n // that a continuation must not DISAGREE with its opener; requiring the tag to name a\n // still-live subagent was explicitly rejected when this was designed, so that\n // attribution-only producers (which tag events but never send SUBAGENT_*) stay\n // valid. Cleared per run, like every other map here.\n const closedSubagents = new Set<string>();\n let runStarted = false; // Track if a run has started\n\n // Function to reset state for a new run\n const resetRunState = () => {\n activeMessages.clear();\n activeToolCalls.clear();\n activeReasoningSpans.clear();\n activeReasoningMessages.clear();\n owners.message.clear();\n owners.toolCall.clear();\n owners.activity.clear();\n owners.reasoning.clear();\n activeSteps.clear();\n activeSubagents.clear();\n closedSubagents.clear();\n runFinished = false;\n runError = false;\n runStarted = true;\n };\n\n // Ownership seeded from replayed history: MESSAGES_SNAPSHOT and the\n // RUN_STARTED input echo both put messages on the wire that later events can\n // reference, so their owners (absent = the parent agent) go on record like an\n // opener's would — and each assistant message's tool calls under the\n // message's owner, since a ToolCall carries no owner field of its own.\n // Without this, reopening a replayed id under a DIFFERENT owner was accepted\n // and the reducer appended the new producer's content into the recorded\n // owner's message: silent misattribution via the replay door.\n //\n // `authoritative` distinguishes the two sources. A snapshot restates the\n // whole conversation and the reducer REPLACES the message, so its owner\n // replaces the recorded one — keeping the old map entry while the document\n // moved on left the verifier contradicting the reducer. The RUN_STARTED\n // input echo is plain history: it seeds only ids nothing else has claimed\n // (the maps were just reset for the run anyway).\n //\n // Initial history handed to an agent OUTSIDE the event stream\n // (RunAgentInput.messages without the RUN_STARTED echo) never passes this\n // operator and cannot be seeded; producers replaying such ids must tag\n // consistently with that history.\n const seedOwnersFromMessages = (\n rawMessages: unknown,\n authoritative: boolean,\n ): AGUIError | undefined => {\n const messages = (rawMessages ?? []) as Array<{\n id?: string;\n role?: string;\n subagentRunId?: string | null;\n toolCalls?: Array<{ id?: string }>;\n }>;\n if (!Array.isArray(messages)) return undefined;\n for (const msg of messages) {\n if (!msg || typeof msg.id !== \"string\") continue;\n // Null is rejected on nested message tags for the same reason as on the\n // event's own tag above: the schemas forbid it, in-process producers\n // bypass them, and a seeded null otherwise persists into state and onto\n // the next run's serialized input.\n if (msg.subagentRunId === null) {\n return new AGUIError(\n `Cannot send a message (id '${msg.id}') with 'subagentRunId: null'. The field is optional — omit it entirely.`,\n );\n }\n // Owners are per entity KIND (see `owners` above), so the message must\n // seed the bucket its role streams through — a reasoning message's\n // continuations are checked against `owners.reasoning`, not `.message`.\n const bucket =\n msg.role === \"reasoning\"\n ? owners.reasoning\n : msg.role === \"activity\"\n ? owners.activity\n : owners.message;\n if (authoritative || !bucket.has(msg.id)) {\n bucket.set(msg.id, { subagentRunId: msg.subagentRunId });\n }\n for (const tc of msg.toolCalls ?? []) {\n if (tc && typeof tc.id === \"string\" && (authoritative || !owners.toolCall.has(tc.id))) {\n owners.toolCall.set(tc.id, { subagentRunId: msg.subagentRunId ?? undefined });\n }\n }\n }\n return undefined;\n };\n\n // Subagent attribution consistency: a continuation/close event must not\n // disagree with the subagent that owns its message / tool call (the opener).\n // An absent tag is always allowed (the field is optional, and Phase-1\n // attribution may be used without Phase-2 SUBAGENT_* lifecycle events — so we\n // deliberately do NOT require the tag to reference an \"active\" subagent here,\n // which would reject valid attribution-only streams).\n const subagentTagError = (\n evType: EventType,\n evSubagentRunId: string | undefined,\n owner: { subagentRunId?: string } | undefined,\n entityKind: string,\n entityId: string,\n ): AGUIError | undefined => {\n if (evSubagentRunId === undefined) return undefined;\n // An opener with no tag means the entity belongs to the PARENT, which is just as\n // much an owner as a subagent is — so a tagged continuation on it is still a\n // disagreement. Comparing only when the recorded owner had an id let\n // `TEXT_MESSAGE_START(m1)` then `TEXT_MESSAGE_CONTENT(m1, subagentRunId: \"s1\")`\n // through, and the reducer would append a subagent's text to a parent-owned\n // message. `owner` being present at all is what matters; its id being undefined\n // is the parent, not \"unknown\".\n if (owner && owner.subagentRunId !== evSubagentRunId) {\n return new AGUIError(\n `Cannot send '${evType}': subagentRunId '${evSubagentRunId}' does not match the ${entityKind} '${entityId}' opener's subagent '${owner.subagentRunId ?? \"(the parent agent)\"}'.`,\n );\n }\n return undefined;\n };\n\n return source$.pipe(\n // Process each event through our state machine\n mergeMap((event) => {\n const eventType = event.type;\n\n log?.event(\"VERIFY\", \"Event:\", event, { type: event.type });\n\n // Check if run has errored (but allow a new RUN_STARTED to start a new run, exactly as\n // RUN_FINISHED does below). A stream can legitimately carry more than one run, a replay of\n // a stored thread being the common case, and a run that errored is over rather than active.\n if (runError && eventType !== EventType.RUN_STARTED) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send event type '${eventType}': The run has already errored with 'RUN_ERROR'. No further events can be sent.`,\n ),\n );\n }\n\n // Check if run has already finished (but allow new RUN_STARTED to start a new run)\n if (\n runFinished &&\n eventType !== EventType.RUN_ERROR &&\n eventType !== EventType.RUN_STARTED\n ) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send event type '${eventType}': The run has already finished with 'RUN_FINISHED'. Start a new run with 'RUN_STARTED'.`,\n ),\n );\n }\n\n // Handle first event requirement and sequential RUN_STARTED\n if (!firstEventReceived) {\n firstEventReceived = true;\n if (eventType !== EventType.RUN_STARTED && eventType !== EventType.RUN_ERROR) {\n return throwError(() => new AGUIError(`First event must be 'RUN_STARTED'`));\n }\n } else if (eventType === EventType.RUN_STARTED) {\n // Allow RUN_STARTED after RUN_FINISHED or RUN_ERROR (new run), but not during an active run\n if (runStarted && !runFinished && !runError) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'RUN_STARTED' while a run is still active. The previous run must be finished with 'RUN_FINISHED' before starting a new run.`,\n ),\n );\n }\n // If we're here, it's either the first RUN_STARTED or a new run after the previous one\n // ended, whether that end was RUN_FINISHED or RUN_ERROR\n if (runFinished || runError) {\n // This is a new run after the previous one ended, reset state\n resetRunState();\n }\n }\n\n // The subagent surface has NO null tolerance (PNI-199 alignment): the zod\n // schemas already reject these on the wire, but in-process producers hand\n // plain objects straight to this verifier — the same bypass the lifecycle\n // required-field checks below exist for. A null tag that slipped through\n // here persisted into message state and was re-serialized onto the next\n // run's input. Absent is the only spelling; the three grandfathered legacy\n // tolerances (PNI-207) are elsewhere and untouched.\n if ((event as { subagentRunId?: unknown }).subagentRunId === null) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send '${eventType}' with 'subagentRunId: null'. The field is optional — omit it entirely.`,\n ),\n );\n }\n if (\n eventType === EventType.SUBAGENT_STARTED ||\n eventType === EventType.SUBAGENT_FINISHED ||\n eventType === EventType.SUBAGENT_ERROR\n ) {\n const lifecycleOptionals: ReadonlyArray<string> =\n eventType === EventType.SUBAGENT_STARTED\n ? [\"description\", \"parentSubagentRunId\", \"parentToolCallId\", \"parentMessageId\"]\n : eventType === EventType.SUBAGENT_FINISHED\n ? [\"outcome\"]\n : [\"code\"];\n for (const field of lifecycleOptionals) {\n if ((event as Record<string, unknown>)[field] === null) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send '${eventType}' with '${field}: null'. The field is optional — omit it entirely.`,\n ),\n );\n }\n }\n // One level deeper: the outcome's discriminant is schema-required — the\n // union only has two members, so anything else (including null) is the\n // same in-process bypass as the field-level nulls above.\n const finishedOutcome = (event as {\n outcome?: { type?: unknown; interruptIds?: unknown } | null;\n }).outcome;\n // Only undefined is absent; every PRESENT value must be a valid outcome\n // (`finishedOutcome &&` let \"\" / false / 0 through — null is rejected by\n // the field-level check above, kept out of this condition so the two\n // checks stay order-independent).\n if (\n finishedOutcome !== undefined &&\n finishedOutcome !== null &&\n (finishedOutcome as { type?: unknown }).type !== \"success\" &&\n (finishedOutcome as { type?: unknown }).type !== \"suspended\"\n ) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send '${eventType}' with outcome type '${String(finishedOutcome.type)}'. The outcome is either { type: \"success\" } or { type: \"suspended\" }.`,\n ),\n );\n }\n if (finishedOutcome && finishedOutcome.interruptIds === null) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send '${eventType}' with 'outcome.interruptIds: null'. The field is optional — omit it entirely.`,\n ),\n );\n }\n if (\n finishedOutcome &&\n Array.isArray(finishedOutcome.interruptIds) &&\n (finishedOutcome.interruptIds as unknown[]).some((id) => typeof id !== \"string\")\n ) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send '${eventType}' with a non-string entry in 'outcome.interruptIds'. Interrupt ids are strings.`,\n ),\n );\n }\n }\n if (eventType === EventType.RUN_FINISHED) {\n // Interrupt attribution is per interrupt inside the outcome; the same\n // no-null rule applies there (the reducer copies these into\n // agent.pendingInterrupts verbatim).\n const outcome = (event as {\n outcome?: { type?: string; interrupts?: Array<{ id?: string; subagentRunId?: unknown }> } | null;\n }).outcome;\n if (outcome?.type === \"interrupt\" && Array.isArray(outcome.interrupts)) {\n for (const interrupt of outcome.interrupts) {\n if (interrupt && interrupt.subagentRunId === null) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'RUN_FINISHED' with an interrupt (id '${interrupt.id}') carrying 'subagentRunId: null'. The field is optional — omit it entirely.`,\n ),\n );\n }\n }\n }\n }\n\n // Validate event based on type and current state\n switch (eventType) {\n // Text message flow\n case EventType.TEXT_MESSAGE_START: {\n const messageId = (event.messageId as string);\n\n // Check if this message is already in progress\n if (activeMessages.has(messageId)) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'TEXT_MESSAGE_START' event: A text message with ID '${messageId}' is already in progress. Complete it with 'TEXT_MESSAGE_END' first.`,\n ),\n );\n }\n\n // First writer wins, exactly as for the reasoning opener below. Owners are\n // retained for the run, so a message this id already had is still on record\n // after its TEXT_MESSAGE_END -- and a DIFFERENT producer reopening that id is\n // a contradiction, since the reducer appends the second producer's content\n // into the first producer's message. Passing `undefined` as the owner here\n // made the check a no-op and accepted exactly that.\n const existingMessageOwner = owners.message.get(messageId);\n if (existingMessageOwner) {\n const subErr = subagentTagError(\n eventType, (event.subagentRunId as string | undefined), existingMessageOwner, \"message\", messageId,\n );\n if (subErr) return throwError(() => subErr);\n }\n activeMessages.add(messageId);\n // Only when there is no entry yet: an UNTAGGED reopen agrees with any owner\n // (an absent tag never disagrees), but it must not overwrite an s1 record\n // with `undefined` and hand the message to the parent.\n if (!existingMessageOwner) {\n owners.message.set(messageId, { subagentRunId: (event.subagentRunId as string | undefined) });\n }\n return of(event);\n }\n\n case EventType.TEXT_MESSAGE_CONTENT: {\n const messageId = (event.messageId as string);\n\n // Must be in a message with this ID\n if (!activeMessages.has(messageId)) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'TEXT_MESSAGE_CONTENT' event: No active text message found with ID '${messageId}'. Start a text message with 'TEXT_MESSAGE_START' first.`,\n ),\n );\n }\n\n const subErr = subagentTagError(\n eventType, (event.subagentRunId as string | undefined), owners.message.get(messageId), \"message\", messageId,\n );\n if (subErr) return throwError(() => subErr);\n return of(event);\n }\n\n case EventType.TEXT_MESSAGE_END: {\n const messageId = (event.messageId as string);\n\n // Must be in a message with this ID\n if (!activeMessages.has(messageId)) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'TEXT_MESSAGE_END' event: No active text message found with ID '${messageId}'. A 'TEXT_MESSAGE_START' event must be sent first.`,\n ),\n );\n }\n\n const subErr = subagentTagError(\n eventType, (event.subagentRunId as string | undefined), owners.message.get(messageId), \"message\", messageId,\n );\n if (subErr) return throwError(() => subErr);\n // Remove message from active set\n activeMessages.delete(messageId);\n return of(event);\n }\n\n // Tool call flow\n case EventType.TOOL_CALL_START: {\n const toolCallId = (event.toolCallId as string);\n\n // Check if this tool call is already in progress\n if (activeToolCalls.has(toolCallId)) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'TOOL_CALL_START' event: A tool call with ID '${toolCallId}' is already in progress. Complete it with 'TOOL_CALL_END' first.`,\n ),\n );\n }\n\n // A tool call lives INSIDE the assistant message parentMessageId names, and\n // ToolCall itself carries no attribution field — so a call whose explicit tag\n // disagrees with that message's owner cannot be represented: the reducer\n // would record it in the other owner's message and the tag would be lost\n // from every snapshot and round-trip. Rejected, rather than silently\n // reattributed. An untagged call inherits the parent message's owner (the\n // continuation rule: absent means \"whoever owns the surrounding entity\"),\n // which is also what the reducer effectively does.\n const parentMessageId = (event.parentMessageId as string | undefined);\n const eventTag = (event.subagentRunId as string | undefined);\n let inheritedOwner: { subagentRunId?: string } | undefined;\n if (parentMessageId !== undefined) {\n const parentOwner = owners.message.get(parentMessageId);\n if (parentOwner) {\n if (eventTag !== undefined && eventTag !== parentOwner.subagentRunId) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'TOOL_CALL_START': subagentRunId '${eventTag}' does not match its parent message '${parentMessageId}' owner '${parentOwner.subagentRunId ?? \"(the parent agent)\"}'. A tool call belongs to the message that carries it.`,\n ),\n );\n }\n inheritedOwner = parentOwner;\n }\n }\n\n // First writer wins, for the same reason as TEXT_MESSAGE_START above: the\n // retained owner still names whoever opened this id, and a different producer\n // reopening it would have its args appended to the first producer's call.\n const existingToolCallOwner = owners.toolCall.get(toolCallId);\n if (existingToolCallOwner) {\n const subErr = subagentTagError(\n eventType, eventTag, existingToolCallOwner, \"tool call\", toolCallId,\n );\n if (subErr) return throwError(() => subErr);\n // An untagged reopen's EFFECTIVE owner is the one it inherits from\n // its parent message — comparing only the (absent) raw tag let a\n // reopen under a different parent slip through: the reducer keeps\n // the call inside the first parent and appends the new call's args\n // there, so the new parent ends up with no call at all.\n if (\n eventTag === undefined &&\n inheritedOwner &&\n inheritedOwner.subagentRunId !== existingToolCallOwner.subagentRunId\n ) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'TOOL_CALL_START': tool call '${toolCallId}' is owned by '${existingToolCallOwner.subagentRunId ?? \"(the parent agent)\"}' but its parent message '${parentMessageId}' is owned by '${inheritedOwner.subagentRunId ?? \"(the parent agent)\"}'. A tool call belongs to the message that carries it.`,\n ),\n );\n }\n }\n activeToolCalls.add(toolCallId);\n if (!existingToolCallOwner) {\n owners.toolCall.set(\n toolCallId,\n eventTag !== undefined\n ? { subagentRunId: eventTag }\n : inheritedOwner ?? { subagentRunId: undefined },\n );\n }\n return of(event);\n }\n\n case EventType.TOOL_CALL_ARGS: {\n const toolCallId = (event.toolCallId as string);\n\n // Must be in a tool call with this ID\n if (!activeToolCalls.has(toolCallId)) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'TOOL_CALL_ARGS' event: No active tool call found with ID '${toolCallId}'. Start a tool call with 'TOOL_CALL_START' first.`,\n ),\n );\n }\n\n const subErr = subagentTagError(\n eventType, (event.subagentRunId as string | undefined), owners.toolCall.get(toolCallId), \"tool call\", toolCallId,\n );\n if (subErr) return throwError(() => subErr);\n return of(event);\n }\n\n case EventType.TOOL_CALL_END: {\n const toolCallId = (event.toolCallId as string);\n\n // Must be in a tool call with this ID\n if (!activeToolCalls.has(toolCallId)) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'TOOL_CALL_END' event: No active tool call found with ID '${toolCallId}'. A 'TOOL_CALL_START' event must be sent first.`,\n ),\n );\n }\n\n const subErr = subagentTagError(\n eventType, (event.subagentRunId as string | undefined), owners.toolCall.get(toolCallId), \"tool call\", toolCallId,\n );\n if (subErr) return throwError(() => subErr);\n // Remove tool call from active set\n activeToolCalls.delete(toolCallId);\n return of(event);\n }\n\n // Step flow\n case EventType.STEP_STARTED: {\n const stepName = (event.stepName as string);\n const stepOwner = (event.subagentRunId as string | undefined);\n if (stepsFor(stepOwner).has(stepName)) {\n return throwError(\n () =>\n new AGUIError(\n `Step \"${stepName}\" is already active for 'STEP_STARTED'${\n stepOwner !== undefined ? ` in subagent '${stepOwner}'` : \"\"\n }`,\n ),\n );\n }\n stepsFor(stepOwner).set(stepName, true);\n return of(event);\n }\n\n case EventType.STEP_FINISHED: {\n const stepName = (event.stepName as string);\n const stepOwner = (event.subagentRunId as string | undefined);\n if (!stepsFor(stepOwner).has(stepName)) {\n // A step with this name IS open, but under a different owner. Reported\n // separately because it is a distinct and much more likely mistake than a\n // step that was never started: a producer that stamps its attribution from\n // \"whichever subagent is currently active\" closes the PARENT's step under a\n // subagent's tag, and closes a SUBAGENT's step untagged once the subagent\n // has been popped. Both were observed in the same real run. The generic\n // \"was not started\" message sent the reader looking for a missing\n // STEP_STARTED that is in fact right there.\n // Find the owner that DOES hold a step of this name, if any.\n let otherOwner: string | undefined;\n let foundOther = false;\n for (const [owner, names] of activeSteps) {\n if (owner !== stepOwner && names.has(stepName)) {\n otherOwner = owner;\n foundOther = true;\n break;\n }\n }\n if (foundOther) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'STEP_FINISHED' for step \"${stepName}\" attributed to ${\n stepOwner !== undefined ? `subagent '${stepOwner}'` : \"the parent agent\"\n }: that step is open under ${\n otherOwner !== undefined ? `subagent '${otherOwner}'` : \"the parent agent\"\n }. A step must be finished by whoever started it.`,\n ),\n );\n }\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'STEP_FINISHED' for step \"${stepName}\" that was not started`,\n ),\n );\n }\n stepsFor(stepOwner).delete(stepName);\n return of(event);\n }\n\n // STATE_SNAPSHOT and STATE_DELTA are attributable, and attribution on them\n // is PROVENANCE, not ownership: it records which subagent produced the\n // update, while the state itself stays run-scoped and is applied\n // run-scoped. That is the same meaning attribution has on the other\n // standalone events (STEP_*, CUSTOM, RAW) — nobody reads an attributed\n // CUSTOM event as the subagent having private custom events.\n //\n // An earlier revision rejected an attributed state event here on the\n // grounds that only the parent owns state. That was a rule this verifier\n // invented: the protocol design lists STATE_SNAPSHOT / STATE_DELTA as\n // carrying attribution, so rejecting them made this client stricter than\n // the protocol and would throw on a conforming producer. Deliberately no\n // check — state events fall through to the generic handling below.\n\n // Activity messages are opened by ACTIVITY_SNAPSHOT and continued by\n // ACTIVITY_DELTA against the same messageId, so an owner change between\n // the two silently patches an activity attributed to someone else —\n // the same defect the text-message and tool-call checks prevent.\n case EventType.ACTIVITY_SNAPSHOT: {\n const messageId = (event.messageId as string);\n // Only a REPLACING snapshot re-mints the activity and so re-owns it. With\n // replace:false the reducer leaves the existing message alone, so overwriting\n // the tracked owner here would let a following ACTIVITY_DELTA under the new\n // tag patch a message still owned by someone else.\n // \"Known\" is the owners map itself — .NET gates on its activityOwners the\n // same way. A separate known-ids set that MESSAGES_SNAPSHOT seeding never\n // filled let a replace:false snapshot re-own a seeded activity: the seeded\n // owner was overwritten and a following delta under the new tag patched a\n // message the reducer still attributes to the original owner.\n const isNew = !owners.activity.has(messageId);\n if (isNew || (event.replace as boolean | undefined) !== false) {\n owners.activity.set(messageId, { subagentRunId: (event.subagentRunId as string | undefined) });\n }\n return of(event);\n }\n\n case EventType.TOOL_CALL_RESULT: {\n // A creation event: it mints the tool message the reducer inserts, so the\n // minted id must be on record — otherwise reopening it through another\n // producer's text events passed and appended their content into this\n // message. Recorded unconditionally, mirroring .NET: TOOL_CALL_RESULT\n // carries its own attribution (the executor can differ from the caller),\n // and an untagged result mints a parent-owned message, so the newest mint\n // wins rather than the first writer.\n const resultMessageId = (event.messageId as string | undefined);\n if (typeof resultMessageId === \"string\") {\n owners.message.set(resultMessageId, { subagentRunId: (event.subagentRunId as string | undefined) });\n }\n return of(event);\n }\n\n case EventType.REASONING_START:\n case EventType.REASONING_MESSAGE_START: {\n const messageId = (event.messageId as string);\n const isSpan = eventType === EventType.REASONING_START;\n const open = isSpan ? activeReasoningSpans : activeReasoningMessages;\n\n // \"A producer MUST NOT open a span whose messageId is already open\", and\n // the streaming pattern says the same of a message. Checked against the\n // opener's OWN set: a span and the message inside it may share an id, so\n // one set for both would have rejected the canonical shape.\n if (open.has(messageId)) {\n return throwError(\n () =>\n new AGUIError(\n isSpan\n ? `Cannot send 'REASONING_START' event: A reasoning span with ID '${messageId}' is already in progress. Complete it with 'REASONING_END' first.`\n : `Cannot send 'REASONING_MESSAGE_START' event: A reasoning message with ID '${messageId}' is already in progress. Complete it with 'REASONING_MESSAGE_END' first.`,\n ),\n );\n }\n\n // First writer records the owner. REASONING_START brackets the outer\n // reasoning and REASONING_MESSAGE_START the inner message, usually under the\n // same id, so whichever arrives first establishes it.\n // A second opener that DISAGREES is a contradiction, not something to\n // silently ignore: the verifier kept the first owner while the reducer mints\n // the message from the second, so content then appended to a message owned by\n // someone else and passed verification.\n const existingReasoningOwner = owners.reasoning.get(messageId);\n if (existingReasoningOwner) {\n const subErr = subagentTagError(\n eventType, (event.subagentRunId as string | undefined), existingReasoningOwner, \"reasoning message\", messageId,\n );\n if (subErr) return throwError(() => subErr);\n }\n open.add(messageId);\n // Only the first writer records the owner, and the owner outlives the close --\n // so an untagged reopen after REASONING_END does not hand the reasoning back\n // to the parent either.\n if (!existingReasoningOwner) {\n owners.reasoning.set(messageId, { subagentRunId: (event.subagentRunId as string | undefined) });\n }\n return of(event);\n }\n\n case EventType.REASONING_MESSAGE_CONTENT:\n case EventType.REASONING_MESSAGE_END:\n case EventType.REASONING_END: {\n const messageId = (event.messageId as string);\n const isSpan = eventType === EventType.REASONING_END;\n const open = isSpan ? activeReasoningSpans : activeReasoningMessages;\n\n // A continuation must name something that is open, exactly as for text\n // messages and tool calls. Without this the reducer was left to invent a\n // message for an orphaned fragment, or to append to one that had closed.\n if (!open.has(messageId)) {\n return throwError(\n () =>\n new AGUIError(\n isSpan\n ? `Cannot send 'REASONING_END' event: No active reasoning span found with ID '${messageId}'. A 'REASONING_START' event must be sent first.`\n : `Cannot send '${eventType}' event: No active reasoning message found with ID '${messageId}'. Start a reasoning message with 'REASONING_MESSAGE_START' first.`,\n ),\n );\n }\n\n const subErr = subagentTagError(\n eventType,\n (event.subagentRunId as string | undefined),\n owners.reasoning.get(messageId),\n \"reasoning message\",\n messageId,\n );\n if (subErr) return throwError(() => subErr);\n // Each terminal closes only its own entity. What is dropped here is only\n // the OPEN flag — `owners.reasoning` is retained for the rest of the run,\n // so a later REASONING_ENCRYPTED_VALUE naming this id still has an owner to\n // check, and an untagged reopen cannot hand the id back to the parent.\n if (eventType === EventType.REASONING_END || eventType === EventType.REASONING_MESSAGE_END) {\n open.delete(messageId);\n }\n return of(event);\n }\n\n case EventType.REASONING_ENCRYPTED_VALUE: {\n // Continues an entity by entityId, and `subtype` says which kind: a\n // \"tool-call\" encrypted value belongs to a TOOL CALL, so looking only among\n // reasoning owners found none and accepted s2's value against s1's call.\n const entityId = (event.entityId as string);\n const subtype = (event.subtype as string | undefined);\n // The \"message\" subtype spans BOTH message kinds: a text message opened by\n // TEXT_MESSAGE_START and a reasoning message opened by\n // REASONING_MESSAGE_START. Reading only `owners.message` covered the first and\n // missed the second -- and attaching an encrypted value to a REASONING message\n // is the documented, canonical use of this subtype, so the check silently never\n // fired for the case it exists for. Ids are unique per kind, so at most one of\n // the two buckets holds this id and consulting both cannot pick a wrong owner.\n const owner =\n subtype === \"tool-call\"\n ? owners.toolCall.get(entityId)\n : subtype === \"message\"\n ? (owners.message.get(entityId) ?? owners.reasoning.get(entityId))\n // Fallback only. The schema defines exactly \"tool-call\" and \"message\",\n // so this branch is unreachable for a schema-valid event; it treats an\n // unknown subtype as a plain reasoning continuation rather than skipping\n // the check.\n : owners.reasoning.get(entityId);\n const kindLabel =\n subtype === \"tool-call\" ? \"tool call\" : subtype === \"message\" ? \"message\" : \"reasoning message\";\n const subErr = subagentTagError(\n eventType,\n (event.subagentRunId as string | undefined),\n owner,\n kindLabel,\n entityId,\n );\n if (subErr) return throwError(() => subErr);\n return of(event);\n }\n\n case EventType.ACTIVITY_DELTA: {\n const messageId = (event.messageId as string);\n const subErr = subagentTagError(\n eventType,\n (event.subagentRunId as string | undefined),\n owners.activity.get(messageId),\n \"activity\",\n messageId,\n );\n if (subErr) return throwError(() => subErr);\n return of(event);\n }\n\n // Subagent flow\n case EventType.SUBAGENT_STARTED: {\n // Required on the lifecycle events -- this is the subagent's own identity,\n // not the optional attribution tag other events carry. The zod schema\n // requires these, but an in-process producer hands plain objects straight\n // to this verifier without wire parsing — and a Map happily keys on\n // `undefined`, so an id-less lifecycle silently corrupted the tracking\n // state a schema-checked stream could never produce. Python (pydantic)\n // and .NET (RequireProvided) both reject these; checking here keeps the\n // three SDKs interchangeable. Empty string is NOT rejected: it is a legal\n // opaque id everywhere else in this verifier.\n if (typeof event.subagentRunId !== \"string\") {\n return throwError(\n () => new AGUIError(`Cannot send 'SUBAGENT_STARTED' without a 'subagentRunId'.`),\n );\n }\n if (typeof (event as { name?: unknown }).name !== \"string\") {\n return throwError(\n () => new AGUIError(`Cannot send 'SUBAGENT_STARTED' without a 'name'.`),\n );\n }\n const subagentRunId = (event.subagentRunId as string);\n const parentSubagentRunId = (event.parentSubagentRunId as string | undefined);\n if (activeSubagents.has(subagentRunId)) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'SUBAGENT_STARTED': subagent '${subagentRunId}' is already active. Finish it with 'SUBAGENT_FINISHED' first.`,\n ),\n );\n }\n // Reopening a closed id would give one invocation two starts and two\n // terminals. Ids are per-invocation, so a genuinely new delegation\n // brings a new id; reuse within a run is a producer bug.\n if (closedSubagents.has(subagentRunId)) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'SUBAGENT_STARTED': subagent '${subagentRunId}' has already finished in this run. Subagent IDs are per-invocation and cannot be reused.`,\n ),\n );\n }\n if (\n parentSubagentRunId !== undefined &&\n !activeSubagents.has(parentSubagentRunId) &&\n !closedSubagents.has(parentSubagentRunId)\n ) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'SUBAGENT_STARTED': parentSubagentRunId '${parentSubagentRunId}' has not been started in this run.`,\n ),\n );\n }\n activeSubagents.set(subagentRunId, true);\n return of(event);\n }\n\n case EventType.SUBAGENT_FINISHED:\n case EventType.SUBAGENT_ERROR: {\n // Required here too, for the same reason as SUBAGENT_STARTED above.\n if (typeof event.subagentRunId !== \"string\") {\n return throwError(\n () => new AGUIError(`Cannot send '${eventType}' without a 'subagentRunId'.`),\n );\n }\n if (\n eventType === EventType.SUBAGENT_ERROR &&\n typeof (event as { message?: unknown }).message !== \"string\"\n ) {\n return throwError(\n () => new AGUIError(`Cannot send 'SUBAGENT_ERROR' without a 'message'.`),\n );\n }\n const subagentRunId = (event.subagentRunId as string);\n if (!activeSubagents.has(subagentRunId)) {\n return throwError(\n () =>\n new AGUIError(\n `Cannot send '${eventType}': no active subagent found with ID '${subagentRunId}'. A 'SUBAGENT_STARTED' event must be sent first.`,\n ),\n );\n }\n activeSubagents.delete(subagentRunId);\n closedSubagents.add(subagentRunId);\n return of(event);\n }\n\n case EventType.MESSAGES_SNAPSHOT: {\n // Authoritative: the snapshot restates the conversation and the reducer\n // replaces each message, so its owners replace recorded ones. See\n // seedOwnersFromMessages.\n {\n const seedErr = seedOwnersFromMessages((event as { messages?: unknown }).messages, true);\n if (seedErr) return throwError(() => seedErr);\n }\n return of(event);\n }\n\n // Run flow\n case EventType.RUN_STARTED: {\n // We've already validated this above\n runStarted = true;\n // The input echo carries replayed history the reducer applies, so it\n // seeds ownership like a snapshot does (non-authoritatively — it is\n // history, not a rewrite). See seedOwnersFromMessages.\n {\n const seedErr = seedOwnersFromMessages(\n ((event as { input?: { messages?: unknown } }).input ?? {}).messages,\n false,\n );\n if (seedErr) return throwError(() => seedErr);\n }\n return of(event);\n }\n\n case EventType.RUN_FINISHED: {\n // Can't be the first event (already checked)\n // and can't happen after already being finished (already checked)\n\n // Check that all steps are finished before run ends\n if (anyStepsActive()) {\n const parts: string[] = [];\n for (const [owner, names] of activeSteps) {\n for (const name of names.keys()) {\n parts.push(owner !== undefined ? `${name} (subagent '${owner}')` : name);\n }\n }\n const unfinishedSteps = parts.join(\", \");\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'RUN_FINISHED' while steps are still active: ${unfinishedSteps}`,\n ),\n );\n }\n\n // Check that all messages are finished before run ends\n if (activeMessages.size > 0) {\n const unfinishedMessages = Array.from(activeMessages.keys()).join(\", \");\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'RUN_FINISHED' while text messages are still active: ${unfinishedMessages}`,\n ),\n );\n }\n\n // Check that all reasoning messages and spans are finished before run ends\n if (activeReasoningMessages.size > 0) {\n const unfinished = Array.from(activeReasoningMessages.keys()).join(\", \");\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'RUN_FINISHED' while reasoning messages are still active: ${unfinished}`,\n ),\n );\n }\n\n if (activeReasoningSpans.size > 0) {\n const unfinished = Array.from(activeReasoningSpans.keys()).join(\", \");\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'RUN_FINISHED' while reasoning spans are still active: ${unfinished}`,\n ),\n );\n }\n\n // Check that all tool calls are finished before run ends\n if (activeToolCalls.size > 0) {\n const unfinishedToolCalls = Array.from(activeToolCalls.keys()).join(\", \");\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'RUN_FINISHED' while tool calls are still active: ${unfinishedToolCalls}`,\n ),\n );\n }\n\n // Check that all subagents are finished before run ends\n if (activeSubagents.size > 0) {\n const unfinishedSubagents = Array.from(activeSubagents.keys()).join(\", \");\n return throwError(\n () =>\n new AGUIError(\n `Cannot send 'RUN_FINISHED' while subagents are still active: ${unfinishedSubagents}`,\n ),\n );\n }\n\n runFinished = true;\n return of(event);\n }\n\n case EventType.RUN_ERROR: {\n // RUN_ERROR can happen at any time\n runError = true; // Set flag to prevent any further events\n return of(event);\n }\n\n case EventType.CUSTOM: {\n return of(event);\n }\n\n default: {\n return of(event);\n }\n }\n }),\n );\n };\n","import { Observable, from, defer, throwError } from \"rxjs\";\nimport { mergeMap, switchMap } from \"rxjs/operators\";\n\nexport enum HttpEventType {\n HEADERS = \"headers\",\n DATA = \"data\",\n}\n\nexport interface HttpDataEvent {\n type: HttpEventType.DATA;\n data?: Uint8Array;\n}\n\nexport interface HttpHeadersEvent {\n type: HttpEventType.HEADERS;\n status: number;\n headers: Headers;\n}\n\nexport type HttpEvent = HttpDataEvent | HttpHeadersEvent;\n\nexport const runHttpRequest = (\n fetchResponse: () => Promise<Response>,\n): Observable<HttpEvent> => {\n // Defer the fetch so that it's executed when subscribed to\n return defer(() => from(fetchResponse())).pipe(\n switchMap((response) => {\n if (!response.ok) {\n const contentType = response.headers.get(\"content-type\") || \"\";\n // Read the (small) error body once, then error the stream\n return from(response.text()).pipe(\n mergeMap((text) => {\n let payload: unknown = text;\n if (contentType.includes(\"application/json\")) {\n try { payload = JSON.parse(text); } catch {/* keep raw text */}\n }\n const err: Error & { status?: number; payload?: unknown } = new Error(\n `HTTP ${response.status}: ${typeof payload === \"string\" ? payload : JSON.stringify(payload)}`\n );\n err.status = response.status;\n err.payload = payload;\n return throwError(() => err);\n })\n );\n }\n // Emit headers event first\n const headersEvent: HttpHeadersEvent = {\n type: HttpEventType.HEADERS,\n status: response.status,\n headers: response.headers,\n };\n\n const reader = response.body?.getReader();\n if (!reader) {\n return throwError(() => new Error(\"Failed to getReader() from response\"));\n }\n\n return new Observable<HttpEvent>((subscriber) => {\n // Emit headers event first\n subscriber.next(headersEvent);\n\n (async () => {\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n // Emit data event instead of raw Uint8Array\n const dataEvent: HttpDataEvent = {\n type: HttpEventType.DATA,\n data: value,\n };\n subscriber.next(dataEvent);\n }\n subscriber.complete();\n } catch (error) {\n subscriber.error(error);\n }\n })();\n\n return () => {\n reader.cancel().catch((error) => {\n if ((error as DOMException)?.name === \"AbortError\") {\n return;\n }\n\n throw error;\n });\n };\n });\n }),\n );\n};\n","import { Observable, Subject } from \"rxjs\";\nimport { HttpEvent, HttpEventType } from \"../run/http-request\";\nimport { type DebugLoggerInput, resolveDebugLogger } from \"@/debug-logger\";\n\n/**\n * Maximum size the framing buffer is allowed to reach before the stream fails.\n *\n * The buffer holds the tail after the last \\n\\n, so a response that never sends a\n * boundary grows it to the size of the whole response. Mirrors\n * SseParser::kMaxBufferSize in the C++ SDK\n * (sdks/community/c++/src/stream/sse_parser.h), which caps the same\n * accumulation at 10 MB.\n *\n * Counted in decoded characters rather than bytes, because the buffer is\n * already a string at the point of the check.\n */\nexport const MAX_BUFFER_SIZE = 10 * 1024 * 1024;\n\n/**\n * Parses a stream of HTTP events into a stream of JSON objects using Server-Sent Events (SSE) format.\n * Strictly follows the SSE standard where:\n * - Events are separated by double newlines ('\\n\\n')\n * - Only 'data:' prefixed lines are processed\n * - Multi-line data events are supported and joined\n * - Non-data fields (event, id, retry) are ignored\n */\nexport const parseSSEStream = (\n source$: Observable<HttpEvent>,\n debugLogger?: DebugLoggerInput,\n // DEFERRED (PNI-272): this is the exported stream element type; changing it\n // to `unknown` ripples into every consumer of parseSSEStream.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): Observable<any> => {\n const log = resolveDebugLogger(debugLogger);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- matches the exported Observable<any> above\n const jsonSubject = new Subject<any>();\n // Create TextDecoder with stream option set to true to handle split UTF-8 characters\n const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n let buffer = \"\";\n\n // Subscribe to the source once and multicast to all subscribers\n source$.subscribe({\n next: (event: HttpEvent) => {\n if (event.type === HttpEventType.HEADERS) {\n return;\n }\n\n if (event.type === HttpEventType.DATA && event.data) {\n // Decode chunk carefully to handle UTF-8\n const text = decoder.decode(event.data, { stream: true });\n buffer += text;\n\n // Process complete events (separated by double newlines)\n const events = buffer.split(/\\n\\n/);\n // Keep the last potentially incomplete event in buffer\n buffer = events.pop() || \"\";\n\n for (const event of events) {\n processSSEEvent(event);\n }\n\n // Measured on the tail that is left once completed events have been\n // taken out, because that tail is the only thing here that can grow\n // without bound. Measuring the incoming chunk instead would fail a\n // read that merely carried two valid events across one boundary, and\n // whether that happens is decided by how the transport grouped its\n // reads rather than by anything the stream did wrong.\n if (buffer.length > MAX_BUFFER_SIZE) {\n jsonSubject.error(\n new Error(\n `SSE buffer size exceeded maximum limit of ${MAX_BUFFER_SIZE / (1024 * 1024)} MB`,\n ),\n );\n return;\n }\n }\n },\n error: (err) => jsonSubject.error(err),\n complete: () => {\n // Use the final call to decoder.decode() to flush any remaining bytes\n if (buffer) {\n buffer += decoder.decode();\n // Process any remaining SSE event data\n processSSEEvent(buffer);\n }\n jsonSubject.complete();\n },\n });\n\n /**\n * Helper function to process an SSE event.\n * Extracts and joins data lines, then parses the result as JSON.\n *\n * Follows the SSE spec by processing lines starting with 'data:',\n * ignoring a single space if it is present after the colon.\n *\n * @param eventText The raw event text to process\n */\n function processSSEEvent(eventText: string) {\n const lines = eventText.split(\"\\n\");\n const dataLines: string[] = [];\n\n for (const line of lines) {\n if (line.startsWith(\"data:\")) {\n // Remove 'data:' prefix, and optionally a single space afterwards\n dataLines.push(line.slice(5).replace(/^ /, \"\"));\n }\n }\n\n // Only process if we have data lines\n if (dataLines.length > 0) {\n try {\n // Join multi-line data and parse JSON\n const jsonStr = dataLines.join(\"\\n\");\n const json = JSON.parse(jsonStr);\n // `json` is whatever the frame held — `null` and primitives included,\n // so the type is read defensively: a throw here would surface as an\n // unhandled host error rather than as a stream failure.\n log?.event(\"SSE\", \"Event received:\", json, {\n type: (json as { type?: unknown } | null)?.type,\n });\n jsonSubject.next(json);\n } catch (err) {\n jsonSubject.error(err);\n }\n }\n }\n\n return jsonSubject.asObservable();\n};\n","import { Observable, Subject } from \"rxjs\";\nimport { HttpEvent, HttpEventType } from \"../run/http-request\";\nimport { BaseEvent } from \"@ag-ui/core\";\nimport * as proto from \"@ag-ui/proto\";\nimport { type DebugLoggerInput, resolveDebugLogger } from \"@/debug-logger\";\n\n/**\n * Maximum size the framing buffer is allowed to reach before the stream fails.\n *\n * processBuffer waits until the buffer holds the whole message named by the\n * 4-byte length prefix, so a prefix that is never satisfied grows the buffer\n * without bound. Enforced against the length each frame declares, which bounds\n * the buffer to a single frame. Mirrors SseParser::kMaxBufferSize in the C++\n * SDK (sdks/community/c++/src/stream/sse_parser.h), which caps the same\n * accumulation at 10 MB.\n */\nexport const MAX_BUFFER_SIZE = 10 * 1024 * 1024;\n\n/**\n * Parses a stream of HTTP events into a stream of BaseEvent objects using Protocol Buffer format.\n * Each message is prefixed with a 4-byte length header (uint32 in big-endian format)\n * followed by the protocol buffer encoded message.\n */\n// The same switch the enforcement stage reads, so one variable silences both\n// halves of what is really one decision about unrecognised material.\nconst suppressWarnings = (): boolean =>\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n Boolean(process.env.SUPPRESS_TRANSFORMATION_WARNINGS);\n\nexport const parseProtoStream = (\n source$: Observable<HttpEvent>,\n debugLogger?: DebugLoggerInput,\n): Observable<BaseEvent> => {\n const log = resolveDebugLogger(debugLogger);\n const eventSubject = new Subject<BaseEvent>();\n let buffer = new Uint8Array(0);\n // A decode failure leaves its frame in the buffer, so without this the\n // stream end would blame the leftovers on truncation and report the wrong\n // cause for a stream that had already failed for a different reason.\n let failed = false;\n\n source$.subscribe({\n next: (event: HttpEvent) => {\n if (event.type === HttpEventType.HEADERS) {\n return;\n }\n\n if (event.type === HttpEventType.DATA && event.data) {\n // Append the new data to our buffer\n const newBuffer = new Uint8Array(buffer.length + event.data.length);\n newBuffer.set(buffer, 0);\n newBuffer.set(event.data, buffer.length);\n buffer = newBuffer;\n\n // Process as many complete messages as possible\n processBuffer();\n }\n },\n error: (err) => eventSubject.error(err),\n complete: () => {\n // Drain whatever whole frames are left, then account for the remainder.\n // A short final frame never throws — the framing loop just breaks,\n // waiting for bytes that will not come — so nothing but this check can\n // notice it. Losing a message and completing anyway would report success\n // for a stream that was cut in half.\n processBuffer();\n if (failed) return;\n if (buffer.length > 0) {\n eventSubject.error(\n new Error(\n `The binary stream ended mid-frame: ${buffer.length} trailing bytes could not be read as a complete message.`,\n ),\n );\n return;\n }\n eventSubject.complete();\n },\n });\n\n /**\n * Process as many complete messages as possible from the buffer\n */\n function processBuffer() {\n // Once the stream has failed the undecodable frame is still at the head of\n // the buffer; re-entering would re-read it for every chunk that follows.\n if (failed) return;\n // Keep processing while we have enough data for at least a header (4 bytes)\n while (buffer.length >= 4) {\n // Read message length from the first 4 bytes (big-endian uint32)\n const view = new DataView(buffer.buffer, buffer.byteOffset, 4);\n const messageLength = view.getUint32(0, false); // false = big-endian\n\n // Check if we have the complete message (header + message body)\n const totalLength = 4 + messageLength;\n\n // A frame is judged by the size its own prefix declares, before waiting\n // for those bytes to arrive. That bounds the buffer to one frame and\n // rejects an unsatisfiable prefix on the first read that carries it,\n // where a check on the accumulated buffer would instead fail a read that\n // merely carried two valid messages at once.\n if (totalLength > MAX_BUFFER_SIZE) {\n eventSubject.error(\n new Error(\n `Protobuf message size exceeded maximum limit of ${MAX_BUFFER_SIZE / (1024 * 1024)} MB`,\n ),\n );\n return;\n }\n\n if (buffer.length < totalLength) {\n // Not enough data yet, wait for more\n break;\n }\n\n try {\n // Extract the message (skipping the 4-byte header)\n const message = buffer.slice(4, totalLength);\n\n // Decode the protocol buffer message using the imported decode function\n const event = proto.decode(message);\n\n // Emit the parsed event\n log?.event(\"PROTO\", \"Event received:\", event, { type: event.type });\n eventSubject.next(event);\n } catch (error: unknown) {\n // An event this build was never compiled against is not a failure. The\n // SSE reader hands the same event on to enforcement, which drops it\n // with a warning and leaves the run alive; the binary reader cannot\n // hand it on, because an unknown envelope arm carries no type string.\n // Dropping the frame here is that same answer spelled for this\n // transport — otherwise a producer that adds one event kills every\n // binary client while text clients carry on untouched.\n if (error instanceof proto.AGUIUnknownEventTypeError) {\n if (!suppressWarnings()) {\n console.warn(\n \"[ag-ui][proto] Dropped an event this build does not know: the protocol has a variant this SDK predates.\",\n );\n }\n } else {\n const errorMessage = error instanceof Error ? error.message : String(error);\n failed = true;\n eventSubject.error(\n new Error(`Failed to decode protocol buffer message: ${errorMessage}`),\n );\n return;\n }\n }\n\n // Remove the processed message from the buffer, dropped frames included:\n // leaving one in place would re-read it forever.\n buffer = buffer.slice(totalLength);\n }\n }\n\n return eventSubject.asObservable();\n};\n","import { BaseEvent } from \"@ag-ui/core\";\nimport { Subject, ReplaySubject, Observable, Subscription } from \"rxjs\";\nimport { HttpEvent, HttpEventType } from \"../run/http-request\";\nimport { parseSSEStream } from \"./sse\";\nimport { parseProtoStream } from \"./proto\";\nimport * as proto from \"@ag-ui/proto\";\nimport { EventType } from \"@ag-ui/core\";\nimport { type DebugLoggerInput, resolveDebugLogger } from \"@/debug-logger\";\n\n/**\n * Transforms HTTP events into BaseEvents using the appropriate format parser based on content type.\n */\nexport const transformHttpEventStream = (\n source$: Observable<HttpEvent>,\n debugLogger?: DebugLoggerInput,\n): Observable<BaseEvent> => {\n const log = resolveDebugLogger(debugLogger);\n const eventSubject = new Subject<BaseEvent>();\n\n // Buffers events until the parser is chosen. One is enough: the parser is\n // attached while the HEADERS event is being handled, so that event is all\n // there is to replay and everything after it is passed through live. Left\n // unbounded, this retained every chunk of the response — the whole download\n // held in memory for the life of the run, on a healthy stream as much as on\n // a failing one.\n const bufferSubject = new ReplaySubject<HttpEvent>(1);\n\n // Flag to track whether we've set up the parser\n let parserInitialized = false;\n\n // Erroring the output does not stop the upstream read on its own: the source\n // subscription owns the teardown that cancels the HTTP reader, so without\n // releasing it the transport keeps reading and the replay buffer keeps\n // retaining chunks that nothing will ever consume.\n //\n // The parser can fail synchronously from inside subscribe(), before the\n // handle below exists, so the intent is recorded and acted on as soon as it\n // does.\n let sourceSubscription: Subscription | undefined = undefined;\n let teardownRequested = false;\n\n const stopReading = () => {\n teardownRequested = true;\n sourceSubscription?.unsubscribe();\n };\n\n const failStream = (err: unknown) => {\n stopReading();\n eventSubject.error(err);\n };\n\n const finishStream = () => {\n stopReading();\n eventSubject.complete();\n };\n\n // Subscribe to source and buffer events while we determine the content type\n sourceSubscription = source$.subscribe({\n next: (event: HttpEvent) => {\n // Forward event to buffer\n bufferSubject.next(event);\n\n // If we get headers and haven't initialized a parser yet, check content type\n if (event.type === HttpEventType.HEADERS && !parserInitialized) {\n parserInitialized = true;\n const contentType = event.headers.get(\"content-type\");\n\n log?.lifecycle(\"HTTP\", \"Stream format detected:\", {\n contentType,\n parser: contentType === proto.AGUI_MEDIA_TYPE ? \"protobuf\" : \"sse\",\n });\n\n // Choose parser based on content type\n if (contentType === proto.AGUI_MEDIA_TYPE) {\n // Use protocol buffer parser\n parseProtoStream(bufferSubject, log).subscribe({\n next: (event) => eventSubject.next(event),\n error: (err) => failStream(err),\n complete: () => finishStream(),\n });\n } else {\n // Use SSE JSON parser for all other cases\n parseSSEStream(bufferSubject, log).subscribe({\n next: (json) => {\n // No schema enforcement here: validation runs AFTER the\n // middleware chain (the enforcement stage in the agent\n // pipeline), so a translator for a deprecated or unrecognised\n // event stays reachable. The transport only requires the one\n // thing nothing downstream can work without: a string type.\n // `null`, a number, a string and an array are all valid JSON\n // documents, and `JSON.parse` hands them on as readily as an\n // object. Reading `.type` off `null` throws inside this `next`\n // handler, where the throw is reported to the host rather than\n // to `eventSubject.error` — the run would then RESOLVE, claiming\n // success for a stream nobody read. So the shape is checked\n // before anything is read off it.\n if (typeof json !== \"object\" || json === null || Array.isArray(json)) {\n const err = new Error(\"Invalid event: the frame is not a JSON object.\");\n log?.event(\"HTTP\", \"Event invalid:\", { json, error: String(err) });\n failStream(err);\n return;\n }\n const record = json as { type?: unknown };\n if (typeof record.type !== \"string\" || record.type.length === 0) {\n const err = new Error(\"Invalid event: the frame carries no event type.\");\n log?.event(\"HTTP\", \"Event invalid:\", { json, error: String(err) });\n failStream(err);\n return;\n }\n log?.event(\"HTTP\", \"Event received:\", json, { type: record.type });\n eventSubject.next(json as BaseEvent);\n },\n error: (err) => {\n if ((err as DOMException)?.name === \"AbortError\") {\n eventSubject.next({\n type: EventType.RUN_ERROR,\n message: (err as DOMException).message || \"Request aborted\",\n code: \"abort\",\n rawEvent: err,\n });\n finishStream();\n return;\n }\n return failStream(err);\n },\n complete: () => finishStream(),\n });\n }\n } else if (!parserInitialized) {\n failStream(new Error(\"No headers event received before data events\"));\n }\n },\n error: (err) => {\n bufferSubject.error(err);\n failStream(err);\n },\n complete: () => {\n bufferSubject.complete();\n },\n });\n\n // Covers a parser that failed synchronously while subscribe() was still\n // running, when there was no handle to release yet.\n if (teardownRequested) {\n sourceSubscription.unsubscribe();\n }\n\n return eventSubject.asObservable();\n};\n","// Protocol Events\nexport const LegacyRuntimeEventTypes = {\n TextMessageStart: \"TextMessageStart\",\n TextMessageContent: \"TextMessageContent\",\n TextMessageEnd: \"TextMessageEnd\",\n ActionExecutionStart: \"ActionExecutionStart\",\n ActionExecutionArgs: \"ActionExecutionArgs\",\n ActionExecutionEnd: \"ActionExecutionEnd\",\n ActionExecutionResult: \"ActionExecutionResult\",\n AgentStateMessage: \"AgentStateMessage\",\n MetaEvent: \"MetaEvent\",\n RunStarted: \"RunStarted\",\n RunFinished: \"RunFinished\",\n RunError: \"RunError\",\n NodeStarted: \"NodeStarted\",\n NodeFinished: \"NodeFinished\",\n} as const;\n\nexport const LegacyRuntimeMetaEventName = {\n LangGraphInterruptEvent: \"LangGraphInterruptEvent\",\n PredictState: \"PredictState\",\n Exit: \"Exit\",\n} as const;\n\n// Protocol Event type exports\nexport type RuntimeEventTypes =\n (typeof LegacyRuntimeEventTypes)[keyof typeof LegacyRuntimeEventTypes];\nexport type RuntimeMetaEventName =\n (typeof LegacyRuntimeMetaEventName)[keyof typeof LegacyRuntimeMetaEventName];\n\nexport interface LegacyTextMessageStart {\n type: \"TextMessageStart\";\n messageId: string;\n parentMessageId?: string;\n role?: string;\n}\n\nexport interface LegacyTextMessageContent {\n type: \"TextMessageContent\";\n messageId: string;\n content: string;\n}\n\nexport interface LegacyTextMessageEnd {\n type: \"TextMessageEnd\";\n messageId: string;\n}\n\nexport interface LegacyActionExecutionStart {\n type: \"ActionExecutionStart\";\n actionExecutionId: string;\n actionName: string;\n parentMessageId?: string;\n}\n\nexport interface LegacyActionExecutionArgs {\n type: \"ActionExecutionArgs\";\n actionExecutionId: string;\n args: string;\n}\n\nexport interface LegacyActionExecutionEnd {\n type: \"ActionExecutionEnd\";\n actionExecutionId: string;\n}\n\nexport interface LegacyActionExecutionResult {\n type: \"ActionExecutionResult\";\n actionName: string;\n actionExecutionId: string;\n result: string;\n}\n\nexport interface LegacyAgentStateMessage {\n type: \"AgentStateMessage\";\n threadId: string;\n agentName: string;\n nodeName: string;\n runId: string;\n active: boolean;\n role: string;\n state: string;\n running: boolean;\n}\n\nexport interface LegacyMetaEvent {\n type: \"MetaEvent\";\n name: RuntimeMetaEventName;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- the legacy meta payload is opaque\n value?: any;\n}\n\nexport interface LegacyRunError {\n type: \"RunError\";\n message: string;\n code?: string;\n}\n\nexport type LegacyRuntimeProtocolEvent =\n | LegacyTextMessageStart\n | LegacyTextMessageContent\n | LegacyTextMessageEnd\n | LegacyActionExecutionStart\n | LegacyActionExecutionArgs\n | LegacyActionExecutionEnd\n | LegacyActionExecutionResult\n | LegacyAgentStateMessage\n | LegacyMetaEvent\n | LegacyRunError;\n\n// Message type exports. Undiscriminated: none of the three carries a `kind`\n// tag, so narrowing the union goes by which field is present — `content` for a\n// text message, `name` for an action execution, `result`/`actionExecutionId`\n// for a result. `name`, not `arguments`: `arguments` is optional on an action\n// execution, so its absence proves nothing, and a narrowing that tested it\n// would misread every argument-less tool call as some other shape.\nexport interface LegacyTextMessage {\n id: string;\n role: string;\n content: string;\n parentMessageId?: string;\n}\n\nexport interface LegacyActionExecutionMessage {\n id: string;\n name: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- parsed tool arguments are arbitrary JSON\n arguments?: any;\n parentMessageId?: string;\n}\n\nexport interface LegacyResultMessage {\n id: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- tool results are arbitrary JSON\n result?: any;\n actionExecutionId: string;\n actionName: string;\n}\n\nexport type LegacyMessage = LegacyTextMessage | LegacyActionExecutionMessage | LegacyResultMessage;\n","import { mergeMap } from \"rxjs/operators\";\nimport jsonpatch from \"fast-json-patch\";\n\nimport {\n BaseEvent,\n EventType,\n TextMessageStartEvent,\n TextMessageContentEvent,\n TextMessageEndEvent,\n ToolCallStartEvent,\n ToolCallArgsEvent,\n ToolCallEndEvent,\n ToolCallResultEvent,\n CustomEvent,\n StateSnapshotEvent,\n StepStartedEvent,\n Message,\n StateDeltaEvent,\n MessagesSnapshotEvent,\n ToolCall,\n ToolMessage,\n RunErrorEvent,\n contentHasMedia,\n contentToText,\n} from \"@ag-ui/core\";\nimport { Observable } from \"rxjs\";\nimport {\n LegacyTextMessageStart,\n LegacyTextMessageContent,\n LegacyTextMessageEnd,\n LegacyActionExecutionStart,\n LegacyActionExecutionArgs,\n LegacyActionExecutionEnd,\n LegacyRuntimeEventTypes,\n LegacyRuntimeProtocolEvent,\n LegacyMetaEvent,\n LegacyAgentStateMessage,\n LegacyMessage,\n LegacyTextMessage,\n LegacyActionExecutionMessage,\n LegacyResultMessage,\n LegacyActionExecutionResult,\n LegacyRunError,\n} from \"./types\";\nimport untruncateJson from \"untruncate-json\";\n\nconst flattenMessageContentToText = (content: Message[\"content\"]) => {\n if (typeof content === \"string\") {\n return content;\n }\n\n if (!Array.isArray(content)) {\n return undefined;\n }\n\n const textParts = content\n .filter((part): part is { type: \"text\"; text: string } => part.type === \"text\")\n .map((part) => part.text)\n .filter((text) => text.length > 0);\n\n if (textParts.length === 0) {\n return undefined;\n }\n\n return textParts.join(\"\\n\");\n};\n\n/**\n * Every warning this bridge emits, behind the same switch as the rest of the\n * package. `SUPPRESS_TRANSFORMATION_WARNINGS` is the one control an operator\n * has over transformation chatter (enforce.ts, transform/proto.ts and the\n * compatibility middlewares all honour it); a warning that ignored it was\n * unsilenceable, which in a per-chunk hot path is a reason to patch the\n * library out rather than to set the flag.\n */\n/**\n * The string the legacy ActionExecutionResult can hold, from content that may\n * be parts. Text parts are concatenated; anything else is dropped with a\n * warning naming the call, because the legacy consumer cannot receive it.\n */\nfunction flattenLegacyResult(toolCallId: string, content: ToolMessage[\"content\"]): string {\n if (contentHasMedia(content)) {\n warnLegacy(\n `[ag-ui][legacy] The result of tool call '${toolCallId}' carries content parts the legacy protocol cannot represent; only its text parts are bridged and the rest is dropped.`,\n );\n }\n return contentToText(content);\n}\n\nconst warnLegacy = (message: string): void => {\n if (\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n Boolean(process.env.SUPPRESS_TRANSFORMATION_WARNINGS)\n ) {\n return;\n }\n console.warn(message);\n};\n\ninterface PredictStateValue {\n state_key: string;\n tool: string;\n tool_argument: string;\n}\n\nexport const convertToLegacyEvents =\n (threadId: string, runId: string, agentName: string) =>\n (events$: Observable<BaseEvent>): Observable<LegacyRuntimeProtocolEvent> => {\n let currentState: Record<string, unknown> = {};\n let running = true;\n let active = true;\n let nodeName = \"\";\n let syncedMessages: Message[] | null = null;\n let predictState: PredictStateValue[] | null = null;\n let currentToolCalls: ToolCall[] = [];\n const toolCallNames: Record<string, string> = {};\n // RAW is a PER-CHUNK event for most providers, so warning per event turns\n // one lossy translation into thousands of identical lines and buries\n // everything else. What is lost is a property of the bridge rather than of\n // any one event, so it is stated once per stream. Per stream, not per\n // process: the flag lives in this closure, so a second bridge still\n // reports its own loss.\n let rawDropReported = false;\n\n const updateCurrentState = (newState: Record<string, unknown>) => {\n // the legacy protocol will only support object state\n if (typeof newState === \"object\" && newState !== null) {\n if (\"messages\" in newState) {\n delete newState.messages;\n }\n currentState = newState;\n }\n };\n\n return events$.pipe(\n mergeMap((event) => {\n switch (event.type) {\n case EventType.TEXT_MESSAGE_START: {\n const startEvent = event as TextMessageStartEvent;\n return [\n {\n type: LegacyRuntimeEventTypes.TextMessageStart,\n messageId: startEvent.messageId,\n role: startEvent.role,\n } as LegacyTextMessageStart,\n ];\n }\n case EventType.TEXT_MESSAGE_CONTENT: {\n const contentEvent = event as TextMessageContentEvent;\n return [\n {\n type: LegacyRuntimeEventTypes.TextMessageContent,\n messageId: contentEvent.messageId,\n content: contentEvent.delta,\n } as LegacyTextMessageContent,\n ];\n }\n case EventType.TEXT_MESSAGE_END: {\n const endEvent = event as TextMessageEndEvent;\n return [\n {\n type: LegacyRuntimeEventTypes.TextMessageEnd,\n messageId: endEvent.messageId,\n } as LegacyTextMessageEnd,\n ];\n }\n case EventType.TOOL_CALL_START: {\n const startEvent = event as ToolCallStartEvent;\n\n currentToolCalls.push({\n id: startEvent.toolCallId,\n type: \"function\",\n function: {\n name: startEvent.toolCallName,\n arguments: \"\",\n },\n });\n\n active = true;\n toolCallNames[startEvent.toolCallId] = startEvent.toolCallName;\n\n return [\n {\n type: LegacyRuntimeEventTypes.ActionExecutionStart,\n actionExecutionId: startEvent.toolCallId,\n actionName: startEvent.toolCallName,\n parentMessageId: startEvent.parentMessageId,\n } as LegacyActionExecutionStart,\n ];\n }\n case EventType.TOOL_CALL_ARGS: {\n const argsEvent = event as ToolCallArgsEvent;\n\n // Find the tool call by ID instead of using the last one\n const currentToolCall = currentToolCalls.find((tc) => tc.id === argsEvent.toolCallId);\n if (!currentToolCall) {\n // Through the gate like the rest of the bridge. TOOL_CALL_ARGS is\n // the per-chunk hot path that gate exists for: one line per\n // streamed token of a tool call's arguments, unsilenceable, is a\n // reason to patch the library out rather than to set the flag.\n warnLegacy(\n `[ag-ui][legacy] TOOL_CALL_ARGS: No tool call found with ID '${argsEvent.toolCallId}'`,\n );\n return [];\n }\n\n currentToolCall.function.arguments += argsEvent.delta;\n let didUpdateState = false;\n\n if (predictState) {\n const currentPredictState = predictState.find(\n (s) => s.tool == currentToolCall.function.name,\n );\n\n if (currentPredictState) {\n try {\n const currentArgs = JSON.parse(\n untruncateJson(currentToolCall.function.arguments),\n );\n if (\n currentPredictState.tool_argument &&\n currentPredictState.tool_argument in currentArgs\n ) {\n updateCurrentState({\n ...currentState,\n [currentPredictState.state_key]:\n currentArgs[currentPredictState.tool_argument],\n });\n didUpdateState = true;\n } else if (!currentPredictState.tool_argument) {\n updateCurrentState({\n ...currentState,\n [currentPredictState.state_key]: currentArgs,\n });\n didUpdateState = true;\n }\n } catch (_e) {\n // Partial predictive-state args are expected to be\n // unparseable until the tool call completes.\n }\n }\n }\n\n return [\n {\n type: LegacyRuntimeEventTypes.ActionExecutionArgs,\n actionExecutionId: argsEvent.toolCallId,\n args: argsEvent.delta,\n } as LegacyActionExecutionArgs,\n ...(didUpdateState\n ? [\n {\n type: LegacyRuntimeEventTypes.AgentStateMessage,\n threadId,\n agentName,\n nodeName,\n runId,\n running,\n role: \"assistant\",\n state: JSON.stringify(currentState),\n active,\n },\n ]\n : []),\n ];\n }\n case EventType.TOOL_CALL_END: {\n const endEvent = event as ToolCallEndEvent;\n return [\n {\n type: LegacyRuntimeEventTypes.ActionExecutionEnd,\n actionExecutionId: endEvent.toolCallId,\n } as LegacyActionExecutionEnd,\n ];\n }\n case EventType.TOOL_CALL_RESULT: {\n const resultEvent = event as ToolCallResultEvent;\n const knownName = toolCallNames[resultEvent.toolCallId];\n // `=== \"\"` as well as `=== undefined`, and `||` rather than `??`\n // on the substitution below. `toolCallName` is `z.string()`, so an\n // EMPTY name is a value a conformant producer may send — and the\n // legacy protocol routes on the action name, where \"\" names\n // nothing any more than an absent name does. Narrowing this to\n // `undefined` alone bridged `actionName: \"\"` in silence, which is\n // the same unroutable result as before minus the notice.\n if (knownName === undefined || knownName === \"\") {\n // \"unknown\" is a FABRICATED action name, and downstream consumers\n // of the legacy protocol route on it — an integration reported\n // exactly this reaching a renderer that then had no component to\n // pick. It happens when the result names a call whose\n // TOOL_CALL_START this bridge never saw: a result replayed from\n // history, or a producer that emits results without openers; or\n // when the opener named the call with the empty string.\n // Whatever the cause, the invention must not be silent.\n warnLegacy(\n `[ag-ui][legacy] No usable tool name was seen for tool call '${resultEvent.toolCallId}' (${knownName === undefined ? \"no TOOL_CALL_START reached this bridge\" : \"its TOOL_CALL_START carried an empty toolCallName\"}), so its result is being bridged with the fabricated action name \"unknown\". Downstream consumers route on that name.`,\n );\n }\n return [\n {\n type: LegacyRuntimeEventTypes.ActionExecutionResult,\n actionExecutionId: resultEvent.toolCallId,\n // The legacy protocol holds a string. A result carrying parts is\n // flattened to its text — the downgrade the versioning rules permit for\n // an older peer — and the loss is announced, since a dropped attachment\n // must never vanish quietly.\n result: flattenLegacyResult(resultEvent.toolCallId, resultEvent.content),\n // `||`, not `??`: see the guard above — an empty name is as\n // unroutable as an absent one, and the two must agree.\n actionName: knownName || \"unknown\",\n } as LegacyActionExecutionResult,\n ];\n }\n case EventType.RAW: {\n // The legacy protocol has no place for a provider payload, so it is\n // dropped — a lossy translation, which the versioning rules say has\n // to name what went. Once per stream; see `rawDropReported` above.\n if (!rawDropReported) {\n rawDropReported = true;\n warnLegacy(\n \"[ag-ui][legacy] Dropping RAW events: the legacy runtime protocol has no equivalent, so the provider payloads they carry do not reach the legacy stream. Reported once per stream.\",\n );\n }\n return [];\n }\n case EventType.CUSTOM: {\n const customEvent = event as CustomEvent;\n switch (customEvent.name) {\n case \"Exit\":\n running = false;\n break;\n case \"PredictState\":\n predictState = customEvent.value as PredictStateValue[];\n break;\n }\n\n return [\n {\n type: LegacyRuntimeEventTypes.MetaEvent,\n name: customEvent.name,\n value: customEvent.value,\n } as LegacyMetaEvent,\n ];\n }\n case EventType.STATE_SNAPSHOT: {\n const stateEvent = event as StateSnapshotEvent;\n updateCurrentState(stateEvent.snapshot);\n\n return [\n {\n type: LegacyRuntimeEventTypes.AgentStateMessage,\n threadId,\n agentName,\n nodeName,\n runId,\n running,\n role: \"assistant\",\n state: JSON.stringify(currentState),\n active,\n } as LegacyAgentStateMessage,\n ];\n }\n case EventType.STATE_DELTA: {\n const deltaEvent = event as StateDeltaEvent;\n // `validate = true` makes applyPatch THROW on a bad patch rather\n // than answer falsy, so the `if (!result) return []` that stood\n // here was dead code and one malformed delta tore the whole bridge\n // down mid-run. Caught and warned, matching what the reducer in\n // apply/default.ts does with the same failure.\n let patched: Record<string, unknown>;\n try {\n patched = jsonpatch.applyPatch(currentState, deltaEvent.delta, true, false)\n .newDocument;\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n warnLegacy(\n `[ag-ui][legacy] Failed to apply state patch:\\nCurrent state: ${JSON.stringify(currentState, null, 2)}\\nPatch operations: ${JSON.stringify(deltaEvent.delta, null, 2)}\\nError: ${errorMessage}`,\n );\n return [];\n }\n updateCurrentState(patched);\n\n return [\n {\n type: LegacyRuntimeEventTypes.AgentStateMessage,\n threadId,\n agentName,\n nodeName,\n runId,\n running,\n role: \"assistant\",\n state: JSON.stringify(currentState),\n active,\n } as LegacyAgentStateMessage,\n ];\n }\n case EventType.MESSAGES_SNAPSHOT: {\n const messagesSnapshot = event as MessagesSnapshotEvent;\n syncedMessages = messagesSnapshot.messages;\n return [\n {\n type: LegacyRuntimeEventTypes.AgentStateMessage,\n threadId,\n agentName,\n nodeName,\n runId,\n running,\n role: \"assistant\",\n state: JSON.stringify({\n ...currentState,\n ...(syncedMessages ? { messages: syncedMessages } : {}),\n }),\n active: true,\n } as LegacyAgentStateMessage,\n ];\n }\n case EventType.RUN_STARTED: {\n // There is nothing to do in the legacy protocol\n return [];\n }\n case EventType.RUN_FINISHED: {\n if (syncedMessages) {\n currentState.messages = syncedMessages;\n }\n\n // Only do an update if state is not empty\n if (Object.keys(currentState).length === 0) {\n return [];\n }\n\n let legacyMessages: LegacyMessage[] | null = null;\n if (syncedMessages) {\n try {\n legacyMessages = convertMessagesToLegacyFormat(syncedMessages);\n } catch (error) {\n // Surface the failure on the stream instead of tearing it down\n // with an opaque JSON parsing error.\n return [\n {\n type: LegacyRuntimeEventTypes.RunError,\n message: (error as Error).message,\n } as LegacyRunError,\n ];\n }\n }\n\n return [\n {\n type: LegacyRuntimeEventTypes.AgentStateMessage,\n threadId,\n agentName,\n nodeName,\n runId,\n running,\n role: \"assistant\",\n state: JSON.stringify({\n ...currentState,\n ...(legacyMessages ? { messages: legacyMessages } : {}),\n }),\n active: false,\n } as LegacyAgentStateMessage,\n ];\n }\n case EventType.RUN_ERROR: {\n const errorEvent = event as RunErrorEvent;\n return [\n {\n type: LegacyRuntimeEventTypes.RunError,\n message: errorEvent.message,\n code: errorEvent.code,\n } as LegacyRunError,\n ];\n }\n case EventType.STEP_STARTED: {\n const stepStarted = event as StepStartedEvent;\n nodeName = stepStarted.stepName;\n\n currentToolCalls = [];\n predictState = null;\n\n return [\n {\n type: LegacyRuntimeEventTypes.AgentStateMessage,\n threadId,\n agentName,\n nodeName,\n runId,\n running,\n role: \"assistant\",\n state: JSON.stringify(currentState),\n active: true,\n } as LegacyAgentStateMessage,\n ];\n }\n case EventType.STEP_FINISHED: {\n currentToolCalls = [];\n predictState = null;\n\n return [\n {\n type: LegacyRuntimeEventTypes.AgentStateMessage,\n threadId,\n agentName,\n nodeName,\n runId,\n running,\n role: \"assistant\",\n state: JSON.stringify(currentState),\n active: false,\n } as LegacyAgentStateMessage,\n ];\n }\n default: {\n return [];\n }\n }\n }),\n );\n };\n\nexport function convertMessagesToLegacyFormat(messages: Message[]): LegacyMessage[] {\n const result: LegacyMessage[] = [];\n\n for (const message of messages) {\n if (message.role === \"assistant\" || message.role === \"user\" || message.role === \"system\") {\n const textContent = flattenMessageContentToText(message.content);\n if (textContent) {\n const textMessage: LegacyTextMessage = {\n id: message.id,\n role: message.role,\n content: textContent,\n };\n result.push(textMessage);\n }\n if (message.role === \"assistant\" && message.toolCalls && message.toolCalls.length > 0) {\n for (const toolCall of message.toolCalls) {\n let parsedArguments: unknown;\n try {\n parsedArguments = JSON.parse(toolCall.function.arguments);\n } catch (error) {\n throw new Error(\n `Failed to parse arguments for tool call '${toolCall.id}' ` +\n `(${toolCall.function.name}): ${(error as Error).message}`,\n );\n }\n const actionExecutionMessage: LegacyActionExecutionMessage = {\n id: toolCall.id,\n name: toolCall.function.name,\n arguments: parsedArguments,\n parentMessageId: message.id,\n };\n result.push(actionExecutionMessage);\n }\n }\n } else if (message.role === \"tool\") {\n let actionName = \"unknown\";\n for (const m of messages) {\n if (m.role === \"assistant\" && m.toolCalls?.length) {\n for (const toolCall of m.toolCalls) {\n if (toolCall.id === message.toolCallId) {\n actionName = toolCall.function.name;\n break;\n }\n }\n }\n }\n const toolMessage: LegacyResultMessage = {\n id: message.id,\n // The same flattening the live TOOL_CALL_RESULT gets: a result must\n // not downgrade one way when streamed and another when replayed.\n result: flattenLegacyResult(message.toolCallId, message.content),\n actionExecutionId: message.toolCallId,\n actionName,\n };\n result.push(toolMessage);\n }\n }\n\n return result;\n}\n","import { mergeMap, Observable, finalize } from \"rxjs\";\nimport {\n BaseEvent,\n TextMessageChunkEvent,\n TextMessageContentEvent,\n TextMessageEndEvent,\n TextMessageStartEvent,\n ToolCallArgsEvent,\n ToolCallChunkEvent,\n ToolCallEndEvent,\n ToolCallStartEvent,\n ReasoningMessageChunkEvent,\n ReasoningMessageContentEvent,\n ReasoningMessageEndEvent,\n ReasoningMessageStartEvent,\n} from \"@ag-ui/core\";\nimport { EventType } from \"@ag-ui/core\";\nimport {\n TextMessageChunkEventSchema,\n ToolCallChunkEventSchema,\n ReasoningMessageChunkEventSchema,\n} from \"@ag-ui/core/schemas\";\nimport { type DebugLoggerInput, resolveDebugLogger } from \"@/debug-logger\";\n\ninterface TextMessageFields {\n messageId: string;\n // The role the opener ESTABLISHED — explicit, or the assistant default the\n // synthesized START carried. Kept so a later chunk that repeats the field\n // can be judged against what the stream already said.\n role: TextMessageStartEvent[\"role\"];\n name?: string;\n subagentRunId?: string;\n}\n\ninterface ToolCallFields {\n toolCallId: string;\n toolCallName: string;\n parentMessageId?: string;\n subagentRunId?: string;\n}\n\ninterface ReasoningMessageFields {\n messageId: string;\n subagentRunId?: string;\n}\n\n/**\n * The stream one lane is currently assembling from chunks. A lane holds at most one,\n * because the chunk shorthand identifies a continuation only by \"the same as before\".\n */\ntype PendingStream =\n | { kind: \"text\"; fields: TextMessageFields }\n | { kind: \"tool\"; fields: ToolCallFields }\n | { kind: \"reasoning\"; fields: ReasoningMessageFields };\n\n/** The id a pending stream is keyed by, whichever kind it is. */\nconst pendingEntityId = (pending: PendingStream): string =>\n pending.kind === \"tool\" ? pending.fields.toolCallId : pending.fields.messageId;\n\nconst missingIdFieldName = (kind: PendingStream[\"kind\"]) =>\n kind === \"tool\" ? \"toolCallId\" : \"messageId\";\n\n/**\n * A continuation chunk MAY repeat a field its opener established, but only with\n * the same value. A conflicting repeat is a malformed known value, and fatal —\n * the same judgment the continuation-owner rule passes on `subagentRunId`.\n * Rejected here rather than left to verifyEvents because the repeated field\n * never survives expansion: the synthesized content event does not carry it,\n * so downstream stages would never see the disagreement.\n */\nconst requireOpenerAgreement = (\n entityKind: string,\n entityId: string,\n field: string,\n incoming: string | undefined,\n established: string | undefined,\n): void => {\n if (incoming !== undefined && incoming !== established) {\n throw new Error(\n `Cannot continue ${entityKind} '${entityId}': chunk ${field} '${incoming}' does not match the open stream's ${field} ${established === undefined ? \"(absent)\" : `'${established}'`}.`,\n );\n }\n};\n\n/**\n * Spreads a chunk's metadata onto an event synthesized from that chunk.\n *\n * Applied to every event derived from a chunk, never to the synthetic `*_END`\n * that closes the *previous* message — that is what stops a chunk's metadata\n * leaking onto the message it is closing when one chunk ends one message and\n * begins another.\n *\n * A chunk that expands into both a start and a content event stamps the same\n * metadata twice. That is harmless: the merge is last-write-wins per key, so\n * applying an identical object twice is indistinguishable from applying it once,\n * and stamping both is what keeps the metadata attached when only one of the two\n * is emitted.\n */\nconst withChunkMetadata = <T extends BaseEvent>(event: T, chunk: BaseEvent): T =>\n chunk.metadata === undefined ? event : { ...event, metadata: chunk.metadata };\n\n/**\n * As above, plus the chunk's `rawEvent`.\n *\n * A chunk carries one provider payload, and expansion turns it into an opener\n * and a content event. The content event is the one that carries what the\n * producer actually sent, so the payload rides there; the opener is synthesised\n * here and claims no raw event of its own. Dropping it entirely — which is what\n * expansion used to do — silently lost every provider payload a chunked stream\n * carried, while the same stream sent unchunked kept them.\n */\nconst withChunkOrigin = <T extends BaseEvent>(event: T, chunk: BaseEvent): T => {\n const withMetadata = withChunkMetadata(event, chunk);\n return chunk.rawEvent === undefined\n ? withMetadata\n : { ...withMetadata, rawEvent: chunk.rawEvent };\n};\n\n/**\n * The properties each chunk shape actually describes, read once at module load\n * from the generated schema's own field list.\n *\n * DERIVED, not hand-copied. A copied set matches the schema on the day it is\n * written and nothing afterwards keeps it honest: a field added to a chunk in\n * a later protocol revision would arrive here as \"unrecognised\", ride onto the\n * synthesized event as remainder, and be stripped again by enforcement with a\n * warning naming a property the protocol had just adopted. That is the same\n * silent drift the remainder below exists to prevent, one layer up.\n *\n * Deriving is not the same as running enforcement here, which this stage\n * genuinely cannot do — it runs upstream of enforcement on the middleware\n * path. Nothing is validated or stripped at this line: it reads the list of\n * names the schema declares, once per shape at import time.\n * `@ag-ui/core/schemas` is already a runtime import of this package\n * (enforce/) and zod is already a hard dependency, so this adds no edge.\n */\nconst describedFields = (schema: { shape: Record<string, unknown> }): ReadonlySet<string> =>\n new Set(Object.keys(schema.shape));\n\nconst TEXT_CHUNK_FIELDS = describedFields(TextMessageChunkEventSchema);\nconst TOOL_CHUNK_FIELDS = describedFields(ToolCallChunkEventSchema);\nconst REASONING_CHUNK_FIELDS = describedFields(ReasoningMessageChunkEventSchema);\n\n/**\n * Whatever the chunk carries that this stage has no field for — a property\n * from a protocol version newer than this client, or a producer's mistake.\n *\n * Expansion builds the synthesized events field by field, so anything not\n * named above simply vanished. On the plain pipeline that is harmless, because\n * enforcement has already stripped the chunk's unrecognised material and\n * warned about it by the time expansion runs. On the middleware path\n * expansion runs FIRST — `Middleware.runNext` expands inside the chain,\n * because middleware written with `runNext` is written against whole events\n * rather than chunks (a middleware that wants the raw stream calls `next.run`\n * itself, as `CompatibilityBoundary` and `FunctionMiddleware` do) — so there\n * is nothing left for enforcement to find and the material disappeared in\n * silence. The guarantee is that nothing is dropped without a warning, so the\n * remainder rides through instead and enforcement judges it after the chain.\n *\n * Where it rides: the CONTENT event whenever the chunk produces one, for the\n * same reason `rawEvent` does — the content event is what the producer\n * actually sent, the opener is this stage's invention — and never both, which\n * would warn twice about one property. A chunk that produces no content event\n * at all is the remaining case; see `carryRemainderOnOpener` below.\n */\nconst unrecognisedChunkProperties = (\n chunk: BaseEvent,\n described: ReadonlySet<string>,\n): Record<string, unknown> | undefined => {\n let remainder: Record<string, unknown> | undefined;\n for (const key of Object.keys(chunk)) {\n if (described.has(key)) continue;\n (remainder ??= {})[key] = (chunk as unknown as Record<string, unknown>)[key];\n }\n return remainder;\n};\n\n/**\n * The opener's share of the same guarantee.\n *\n * \"It rides on the CONTENT event\" above holds only when there IS one. An\n * OPENING chunk pushes its synthesized `*_START` first, so the empty-result\n * fallback each arm ends with can never fire for it; and a chunk with neither\n * `delta` nor `rawEvent` synthesizes no content event to carry the remainder\n * either. Between the two, an opener-only chunk carrying an unrecognised\n * property expanded into a bare `*_START` and the property was gone — dropped\n * with nothing said, which is exactly what this whole mechanism exists to\n * prevent.\n *\n * So when nothing else took the remainder, it goes onto the last event\n * synthesized for the chunk — the `*_START` — and enforcement, running after\n * the middleware chain, strips it there and names it. Spread FIRST, like every\n * other site: a described field can never be shadowed by something the\n * producer also sent under that name.\n *\n * Spreading first has one cost, and it is announced rather than paid in\n * silence. When the OPENER declares a key the remainder also carries, the\n * opener's value wins and the producer's is overwritten before enforcement can\n * see it. Reachable on one arm today: REASONING_MESSAGE_START declares `role`\n * (set to \"reasoning\" below) while REASONING_MESSAGE_CHUNK does not declare\n * `role` at all, so a producer's `role` on such a chunk is remainder and\n * collides. The text and tool arms are safe — their opener's keys are a subset\n * of their chunk's.\n *\n * Letting the REMAINDER win instead is not the fix. The synthesized opener's\n * described value is this stage's own, and a producer value in its place would\n * be judged by enforcement — `role: \"wizard\"` on a REASONING_MESSAGE_START is a\n * malformed known field, so the run would fail behind a shim and succeed\n * without one. Same stream, two verdicts, which is exactly the divergence this\n * file exists to prevent. So the opener keeps its value and the collision is\n * reported, which is what \"nothing is dropped without a warning\" asks for.\n */\nconst warnChunkAside = (sentence: string): void => {\n if (\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n Boolean(process.env.SUPPRESS_TRANSFORMATION_WARNINGS)\n ) {\n return;\n }\n console.warn(\n `[ag-ui][transform] ${sentence} Set SUPPRESS_TRANSFORMATION_WARNINGS=true to silence.`,\n );\n};\n\nconst carryRemainderOnOpener = (\n synthesized: BaseEvent[],\n remainder: Record<string, unknown> | undefined,\n alreadyCarried: boolean,\n chunkType: string,\n): void => {\n if (remainder === undefined || alreadyCarried || synthesized.length === 0) return;\n const last = synthesized[synthesized.length - 1];\n\n // `hasOwnProperty`, not `in`. The spread below copies OWN enumerable\n // properties, so the opener's value wins only for keys the opener OWNS —\n // whereas `in` also answers true for everything on Object.prototype, and a\n // producer sending `toString` or `constructor` on a chunk would then be told\n // its value had been dropped when the spread had in fact kept it. A warning\n // has to describe what actually happened.\n const shadowed = Object.keys(remainder).filter((key) =>\n Object.prototype.hasOwnProperty.call(last, key),\n );\n if (shadowed.length > 0) {\n warnChunkAside(\n `A ${chunkType} carried ${shadowed.map((key) => `'${key}'`).join(\", \")}, which the synthesized ${String(last.type)} already describes. The synthesized value is kept and the chunk's is dropped — this stage does not judge a described field, so the producer's value cannot be substituted for its own.`,\n );\n }\n\n synthesized[synthesized.length - 1] = { ...remainder, ...last };\n};\n\nexport const transformChunks =\n (debugLogger?: DebugLoggerInput) =>\n (events$: Observable<BaseEvent>): Observable<BaseEvent> => {\n const log = resolveDebugLogger(debugLogger);\n\n // One pending stream per LANE, where a lane is the subagent its chunks are attributed\n // to and `undefined` is the parent agent. A single global slot meant only one stream\n // could be mid-assembly per run, so two subagents streaming concurrently destroyed\n // each other: the second chunk's opener closed the first's message, and because\n // continuation chunks omit the id, the first subagent's next chunk then failed\n // outright. Keyed by owner, each lane assembles independently. A run that never\n // attributes anything uses only the `undefined` lane, so its behaviour is unchanged.\n const lanes = new Map<string | undefined, PendingStream>();\n\n /** Emit the END for whatever `owner` has open, and clear the lane. */\n const closeLane = (owner: string | undefined): BaseEvent[] => {\n const pending = lanes.get(owner);\n if (!pending) return [];\n lanes.delete(owner);\n\n switch (pending.kind) {\n case \"text\": {\n const event = {\n type: EventType.TEXT_MESSAGE_END,\n messageId: pending.fields.messageId,\n // `!== undefined`, not `!= null`, matching every other site in\n // this file: an absent owner is absent, but a null one is a\n // violation the spec names, and dropping it here would hide it\n // from the stage that rejects it (see the note on the opener\n // below).\n ...(pending.fields.subagentRunId !== undefined && {\n subagentRunId: pending.fields.subagentRunId,\n }),\n } as TextMessageEndEvent;\n log?.event(\"TRANSFORM\", \"TEXT_MESSAGE_END\", event, { messageId: event.messageId });\n return [event];\n }\n case \"tool\": {\n const event = {\n type: EventType.TOOL_CALL_END,\n toolCallId: pending.fields.toolCallId,\n // `!== undefined`, not `!= null`, matching every other site in\n // this file: an absent owner is absent, but a null one is a\n // violation the spec names, and dropping it here would hide it\n // from the stage that rejects it (see the note on the opener\n // below).\n ...(pending.fields.subagentRunId !== undefined && {\n subagentRunId: pending.fields.subagentRunId,\n }),\n } as ToolCallEndEvent;\n log?.event(\"TRANSFORM\", \"TOOL_CALL_END\", event, { toolCallId: event.toolCallId });\n return [event];\n }\n case \"reasoning\": {\n const event = {\n type: EventType.REASONING_MESSAGE_END,\n messageId: pending.fields.messageId,\n // `!== undefined`, not `!= null`, matching every other site in\n // this file: an absent owner is absent, but a null one is a\n // violation the spec names, and dropping it here would hide it\n // from the stage that rejects it (see the note on the opener\n // below).\n ...(pending.fields.subagentRunId !== undefined && {\n subagentRunId: pending.fields.subagentRunId,\n }),\n } as ReasoningMessageEndEvent;\n log?.event(\"TRANSFORM\", \"REASONING_MESSAGE_END\", event, { messageId: event.messageId });\n return [event];\n }\n }\n };\n\n /**\n * Close every lane, in the order they opened. Used by the run-level events, which\n * describe the run as a whole rather than any one producer within it.\n */\n const closeAllLanes = (): BaseEvent[] =>\n [...lanes.keys()].flatMap((owner) => closeLane(owner));\n\n /** The lane holding an open stream of `kind` under `entityId`, if any. */\n const laneHolding = (kind: PendingStream[\"kind\"], entityId: string) => {\n for (const [owner, pending] of lanes) {\n if (pending.kind === kind && pendingEntityId(pending) === entityId) return { owner };\n }\n return undefined;\n };\n\n /**\n * Decide which lane a chunk belongs to. Every chunk carries its own `subagentRunId`,\n * which is what makes per-lane assembly possible at all — but the shorthand lets a\n * continuation omit both the id and the tag, so the lane has to be inferred.\n */\n const resolveLane = (\n kind: PendingStream[\"kind\"],\n entityId: string | undefined,\n tag: string | undefined,\n chunkType: string,\n entityKind: string,\n ): string | undefined => {\n if (entityId !== undefined) {\n // A named id continues wherever it is already open, regardless of who sends it,\n // so the id remains the strongest signal. A tag that disagrees with that lane is\n // the contradiction the continuation-owner rule forbids: rejected here rather\n // than left to verifyEvents, because a chunk carrying attribution but no delta\n // synthesizes nothing, so the disagreement would never reach the verifier.\n const holder = laneHolding(kind, entityId);\n if (holder) {\n if (tag !== undefined && tag !== holder.owner) {\n throw new Error(\n `Cannot continue ${entityKind} '${entityId}': chunk subagentRunId '${tag}' does not match the open stream's subagent '${holder.owner ?? \"(the parent agent)\"}'.`,\n );\n }\n return holder.owner;\n }\n // An id nobody holds opens a new stream, in the lane its own tag names.\n return tag;\n }\n\n // Continuation shorthand. A tag names its lane outright.\n if (tag !== undefined) return tag;\n\n // Untagged means the parent agent, so prefer the parent's own open stream.\n const parentPending = lanes.get(undefined);\n if (parentPending?.kind === kind) return undefined;\n\n // Otherwise fall back to the sole open stream of this kind, so producers that\n // attribute only the opening chunk keep working. This is not overriding the\n // untagged-means-parent rule above: an id-less chunk can never OPEN a stream\n // (a first chunk must carry its id — the caller throws), so when the parent has\n // no stream of this kind to continue, the sole open stream is the chunk's only\n // possible referent. The alternatives are continuing it or failing a stream\n // that is perfectly legal for an opener-only-tagging producer whose parent\n // happens to have a different-kind stream in flight.\n const candidates = [...lanes.entries()].filter(([, pending]) => pending.kind === kind);\n if (candidates.length === 1) return candidates[0][0];\n if (candidates.length > 1) {\n throw new Error(\n `Ambiguous ${chunkType}: it carries neither a ${missingIdFieldName(kind)} nor a subagentRunId, but ${candidates.length} lanes have an open ${entityKind}. Attribute the chunk to the subagent it belongs to.`,\n );\n }\n // No lane has an open stream of this kind, so there is nothing to continue: the\n // caller opens a new stream in the parent lane, or reports the missing id.\n return undefined;\n };\n\n return events$.pipe(\n mergeMap((event) => {\n switch (event.type) {\n case EventType.TEXT_MESSAGE_START:\n case EventType.TEXT_MESSAGE_CONTENT:\n case EventType.TEXT_MESSAGE_END:\n case EventType.TOOL_CALL_START:\n case EventType.TOOL_CALL_ARGS:\n case EventType.TOOL_CALL_END:\n case EventType.TOOL_CALL_RESULT:\n case EventType.STATE_SNAPSHOT:\n case EventType.STATE_DELTA:\n case EventType.CUSTOM:\n case EventType.STEP_STARTED:\n case EventType.STEP_FINISHED:\n case EventType.REASONING_START:\n case EventType.REASONING_MESSAGE_START:\n case EventType.REASONING_MESSAGE_CONTENT:\n case EventType.REASONING_MESSAGE_END:\n case EventType.REASONING_END:\n // An explicit event closes only ITS OWN lane's pending stream. Closing the\n // single global stream meant a parent's TEXT_MESSAGE_START ended a subagent's\n // half-assembled message — the same class of cross-lane damage as closing on\n // an unrelated subagent's terminal. Events that carry no tag read as the\n // parent lane, which is what they are.\n return [...closeLane((event as { subagentRunId?: string | null }).subagentRunId ?? undefined), event];\n // Run-level events describe the run as a whole rather than any one producer\n // within it, so every lane closes — otherwise a subagent's chunk stream would\n // outlive the run that carried it. MESSAGES_SNAPSHOT belongs here too: it\n // restates the entire conversation, and attributes per message rather than\n // carrying one owner of its own.\n case EventType.RUN_STARTED:\n case EventType.RUN_FINISHED:\n case EventType.RUN_ERROR:\n case EventType.MESSAGES_SNAPSHOT:\n return [...closeAllLanes(), event];\n case EventType.RAW:\n case EventType.ACTIVITY_SNAPSHOT:\n case EventType.ACTIVITY_DELTA:\n case EventType.REASONING_ENCRYPTED_VALUE:\n case EventType.SUBAGENT_STARTED:\n return [event];\n // A subagent's terminal event closes any stream still being assembled from\n // chunks. Passing these through untouched left the pending message open, so\n // its synthesized END — which carries the opener's subagentRunId — was emitted\n // later, by the run terminal or the next non-chunk event, i.e. after that\n // subagent had already finished. The verifier tolerates such a tag by\n // design, so this is not about validity: it is that a message this\n // transform synthesized should not be closed on behalf of an owner that\n // has already ended, since a consumer grouping by subagent would attach it\n // to a group it had already marked complete.\n case EventType.SUBAGENT_FINISHED:\n case EventType.SUBAGENT_ERROR: {\n // Its own lane only. A terminal with no id is malformed and must not be read\n // as closing the parent lane — a runtime null reads the same as absent.\n const terminalOwner = (event as { subagentRunId?: string | null }).subagentRunId;\n if (terminalOwner == null) return [event];\n return [...closeLane(terminalOwner), event];\n }\n case EventType.TEXT_MESSAGE_CHUNK: {\n const messageChunkEvent = event as TextMessageChunkEvent;\n const textChunkRemainder = unrecognisedChunkProperties(event, TEXT_CHUNK_FIELDS);\n const lane = resolveLane(\n \"text\",\n messageChunkEvent.messageId,\n messageChunkEvent.subagentRunId ?? undefined,\n \"TEXT_MESSAGE_CHUNK\",\n \"text message\",\n );\n const open = lanes.get(lane);\n const textMessageResult: BaseEvent[] = [];\n // Whether the remainder found a carrier below. Only the two\n // branches that spread it set this; see carryRemainderOnOpener.\n let textRemainderCarried = false;\n\n let textMessageFields: TextMessageFields;\n if (\n open?.kind === \"text\" &&\n // An absent id continues; a present one must be the same message.\n (messageChunkEvent.messageId === undefined ||\n messageChunkEvent.messageId === open.fields.messageId)\n ) {\n requireOpenerAgreement(\n \"text message\",\n open.fields.messageId,\n \"role\",\n messageChunkEvent.role,\n open.fields.role,\n );\n requireOpenerAgreement(\n \"text message\",\n open.fields.messageId,\n \"name\",\n messageChunkEvent.name,\n open.fields.name,\n );\n textMessageFields = open.fields;\n } else {\n // Whatever else this lane had open ends before the new stream begins.\n textMessageResult.push(...closeLane(lane));\n\n if (messageChunkEvent.messageId === undefined) {\n throw new Error(\"First TEXT_MESSAGE_CHUNK must have a messageId\");\n }\n\n textMessageFields = {\n messageId: messageChunkEvent.messageId,\n // Absent means assistant, which the spec states normatively\n // and the generated validator deliberately does not apply, so\n // materialising it here is real work nothing else does.\n //\n // ABSENT, though — not merely falsy, and not null. This stage\n // must not depend on enforcement having run first: it has, on\n // the three pipelines in agent.ts, but Middleware.runNext\n // expands INSIDE the middleware chain, upstream of it. So a\n // present-but-wrong role reaching here has not been judged\n // yet, and substituting for it would repair a producer defect\n // that is fatal when the same value is sent unchunked.\n role: messageChunkEvent.role === undefined ? \"assistant\" : messageChunkEvent.role,\n name: messageChunkEvent.name,\n subagentRunId: messageChunkEvent.subagentRunId,\n };\n lanes.set(lane, { kind: \"text\", fields: textMessageFields });\n\n const textMessageStartEvent = withChunkMetadata(\n {\n type: EventType.TEXT_MESSAGE_START,\n messageId: messageChunkEvent.messageId,\n role: textMessageFields.role,\n ...(messageChunkEvent.name !== undefined && { name: messageChunkEvent.name }),\n // `!== undefined`, not `!= null`: an absent owner is absent,\n // but a null one is a violation the spec names, and dropping\n // it here would hide it from the stage that rejects it.\n ...(messageChunkEvent.subagentRunId !== undefined && {\n subagentRunId: messageChunkEvent.subagentRunId,\n }),\n } as TextMessageStartEvent,\n messageChunkEvent,\n );\n\n textMessageResult.push(textMessageStartEvent);\n\n log?.event(\"TRANSFORM\", \"TEXT_MESSAGE_START\", textMessageStartEvent, {\n messageId: messageChunkEvent.messageId,\n });\n }\n\n // A content event is emitted when the chunk carries a delta OR a\n // provider payload — here and in the two branches below. The\n // synthesized START deliberately claims no rawEvent, so a first\n // chunk carrying rawEvent but no delta needs this event as the\n // payload's carrier, exactly as a continuation does.\n if (messageChunkEvent.delta !== undefined || messageChunkEvent.rawEvent !== undefined) {\n // `!== undefined`, not `??`, on the incoming tag — here and on\n // every continuation path below: a null tag is a violation the\n // spec names, and `??` read it as absence, so a continuation's\n // null fell back to the opener's owner and never reached the\n // stage that rejects it. Preserved, it rides the synthesized\n // event onward, exactly as an opener's null does.\n //\n // WHICH stage rejects it depends on the path, and both do:\n //\n // - Plain pipeline (`enforce -> expand`): ENFORCEMENT rejects,\n // and it rejects the raw CHUNK before this stage ever runs.\n // `SubagentRunIdSchema` is `z.string()`, so `null` is a\n // malformed value on a described field, which enforcement\n // keeps fatal. Nothing this stage synthesises is involved.\n // - `Middleware.runNext` (`expand` inside the chain, enforce\n // after it): expansion is handed the raw chunk, so preserving\n // the null is what lets enforcement — and then VERIFICATION\n // (verify.ts's \"'subagentRunId: null'. The field is optional\"\n // check) — see it at all.\n //\n // Reading it as absence with `??` is what removed it from the\n // second path entirely, which is the divergence this file\n // exists to prevent.\n const contentOwner =\n messageChunkEvent.subagentRunId !== undefined\n ? messageChunkEvent.subagentRunId\n : textMessageFields.subagentRunId;\n const textMessageContentEvent = withChunkOrigin(\n {\n // Spread FIRST so a described field can never be shadowed by\n // something the producer also sent under that name.\n ...textChunkRemainder,\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId: textMessageFields.messageId,\n // `=== undefined`, not `??` — exactly how the opener's `role` is\n // handled above. The gate that reached this line is itself\n // `!== undefined`, so a `delta: null` passes it, and `??` then\n // repaired the malformed value into \"\". That made the same\n // producer defect fatal when sent unchunked and invisible when\n // sent as a chunk behind a middleware. Preserved, it is fatal on\n // both paths.\n delta: messageChunkEvent.delta === undefined ? \"\" : messageChunkEvent.delta,\n // Prefer the INCOMING chunk's tag over the opener's, so a producer that\n // attributes every chunk sees its own attribution on the output rather\n // than a value this transform remembered.\n ...(contentOwner !== undefined && { subagentRunId: contentOwner }),\n } as TextMessageContentEvent,\n messageChunkEvent,\n );\n\n textMessageResult.push(textMessageContentEvent);\n textRemainderCarried = true;\n\n log?.event(\"TRANSFORM\", \"TEXT_MESSAGE_CONTENT\", textMessageContentEvent, {\n messageId: textMessageFields.messageId,\n });\n }\n\n // A continuation chunk carrying only metadata — a final chunk with\n // usage and a finish reason, the case the merge design exists for —\n // synthesizes nothing above. Emit a zero-delta content event so the\n // metadata still reaches the reducer. It cannot ride the synthetic\n // `*_END` instead: `finalize` discards the events it creates, so the\n // last message of a stream would lose it.\n //\n // The gate also fires for a chunk carrying only `rawEvent` — a\n // provider payload is content whichever field it rides — and for\n // one carrying only `subagentRunId: null`, whose violation must\n // reach the stage that rejects it rather than vanish with the\n // chunk.\n if (\n textMessageResult.length === 0 &&\n (messageChunkEvent.metadata !== undefined ||\n messageChunkEvent.rawEvent !== undefined ||\n messageChunkEvent.subagentRunId === null ||\n // A continuation carrying ONLY unrecognised material expanded\n // into nothing at all, so there was no event left for\n // enforcement to strip it from and warn about.\n textChunkRemainder !== undefined)\n ) {\n // Attribution follows the same rule as the delta path above: the\n // incoming chunk's tag first, the opener's owner as fallback —\n // a metadata-only continuation is still the lane's event.\n const metadataOwner =\n messageChunkEvent.subagentRunId !== undefined\n ? messageChunkEvent.subagentRunId\n : textMessageFields!.subagentRunId;\n textMessageResult.push({\n ...textChunkRemainder,\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId: textMessageFields!.messageId,\n delta: \"\",\n ...(messageChunkEvent.metadata !== undefined && { metadata: messageChunkEvent.metadata }),\n ...(messageChunkEvent.rawEvent !== undefined && {\n rawEvent: messageChunkEvent.rawEvent,\n }),\n ...(metadataOwner !== undefined && { subagentRunId: metadataOwner }),\n } as TextMessageContentEvent);\n textRemainderCarried = true;\n }\n\n carryRemainderOnOpener(\n textMessageResult,\n textChunkRemainder,\n textRemainderCarried,\n \"TEXT_MESSAGE_CHUNK\",\n );\n return textMessageResult;\n }\n case EventType.TOOL_CALL_CHUNK: {\n const toolCallChunkEvent = event as ToolCallChunkEvent;\n const toolChunkRemainder = unrecognisedChunkProperties(event, TOOL_CHUNK_FIELDS);\n const lane = resolveLane(\n \"tool\",\n toolCallChunkEvent.toolCallId,\n toolCallChunkEvent.subagentRunId ?? undefined,\n \"TOOL_CALL_CHUNK\",\n \"tool call\",\n );\n const open = lanes.get(lane);\n const toolMessageResult: BaseEvent[] = [];\n // As in the text arm above.\n let toolRemainderCarried = false;\n\n let toolCallFields: ToolCallFields;\n if (\n open?.kind === \"tool\" &&\n (toolCallChunkEvent.toolCallId === undefined ||\n toolCallChunkEvent.toolCallId === open.fields.toolCallId)\n ) {\n requireOpenerAgreement(\n \"tool call\",\n open.fields.toolCallId,\n \"toolCallName\",\n toolCallChunkEvent.toolCallName,\n open.fields.toolCallName,\n );\n requireOpenerAgreement(\n \"tool call\",\n open.fields.toolCallId,\n \"parentMessageId\",\n toolCallChunkEvent.parentMessageId,\n open.fields.parentMessageId,\n );\n toolCallFields = open.fields;\n } else {\n toolMessageResult.push(...closeLane(lane));\n\n if (toolCallChunkEvent.toolCallId === undefined) {\n throw new Error(\"First TOOL_CALL_CHUNK must have a toolCallId\");\n }\n if (toolCallChunkEvent.toolCallName === undefined) {\n throw new Error(\"First TOOL_CALL_CHUNK must have a toolCallName\");\n }\n toolCallFields = {\n toolCallId: toolCallChunkEvent.toolCallId,\n toolCallName: toolCallChunkEvent.toolCallName,\n parentMessageId: toolCallChunkEvent.parentMessageId,\n subagentRunId: toolCallChunkEvent.subagentRunId,\n };\n lanes.set(lane, { kind: \"tool\", fields: toolCallFields });\n\n const toolCallStartEvent = withChunkMetadata(\n {\n type: EventType.TOOL_CALL_START,\n toolCallId: toolCallChunkEvent.toolCallId,\n toolCallName: toolCallChunkEvent.toolCallName,\n // Conditional, like its siblings: set unconditionally this\n // wrote an explicit `parentMessageId: undefined` key onto\n // every synthesized opener, which is a present member with\n // no value rather than the absent field the schema means.\n ...(toolCallChunkEvent.parentMessageId !== undefined && {\n parentMessageId: toolCallChunkEvent.parentMessageId,\n }),\n // `!== undefined`, not `!= null`: an absent owner is absent,\n // but a null one is a violation the spec names, and dropping\n // it here would hide it from the stage that rejects it.\n ...(toolCallChunkEvent.subagentRunId !== undefined && {\n subagentRunId: toolCallChunkEvent.subagentRunId,\n }),\n } as ToolCallStartEvent,\n toolCallChunkEvent,\n );\n\n toolMessageResult.push(toolCallStartEvent);\n\n log?.event(\"TRANSFORM\", \"TOOL_CALL_START\", toolCallStartEvent, {\n toolCallId: toolCallChunkEvent.toolCallId,\n toolCallName: toolCallChunkEvent.toolCallName,\n });\n }\n\n if (toolCallChunkEvent.delta !== undefined || toolCallChunkEvent.rawEvent !== undefined) {\n const argsOwner =\n toolCallChunkEvent.subagentRunId !== undefined\n ? toolCallChunkEvent.subagentRunId\n : toolCallFields.subagentRunId;\n const toolCallArgsEvent = withChunkOrigin(\n {\n ...toolChunkRemainder,\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: toolCallFields.toolCallId,\n // `=== undefined`, not `??` — exactly how the opener's `role` is\n // handled above. The gate that reached this line is itself\n // `!== undefined`, so a `delta: null` passes it, and `??` then\n // repaired the malformed value into \"\". That made the same\n // producer defect fatal when sent unchunked and invisible when\n // sent as a chunk behind a middleware. Preserved, it is fatal on\n // both paths.\n delta: toolCallChunkEvent.delta === undefined ? \"\" : toolCallChunkEvent.delta,\n // Prefer the INCOMING chunk's tag over the opener's, so a producer that\n // attributes every chunk sees its own attribution on the output rather\n // than a value this transform remembered.\n ...(argsOwner !== undefined && { subagentRunId: argsOwner }),\n } as ToolCallArgsEvent,\n toolCallChunkEvent,\n );\n\n toolMessageResult.push(toolCallArgsEvent);\n toolRemainderCarried = true;\n\n log?.event(\"TRANSFORM\", \"TOOL_CALL_ARGS\", toolCallArgsEvent, {\n toolCallId: toolCallFields.toolCallId,\n });\n }\n\n // Same as the text case above.\n if (\n toolMessageResult.length === 0 &&\n (toolCallChunkEvent.metadata !== undefined ||\n toolCallChunkEvent.rawEvent !== undefined ||\n toolCallChunkEvent.subagentRunId === null ||\n toolChunkRemainder !== undefined)\n ) {\n // Same attribution rule as the args path above.\n const metadataOwner =\n toolCallChunkEvent.subagentRunId !== undefined\n ? toolCallChunkEvent.subagentRunId\n : toolCallFields!.subagentRunId;\n toolMessageResult.push({\n ...toolChunkRemainder,\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: toolCallFields!.toolCallId,\n delta: \"\",\n ...(toolCallChunkEvent.metadata !== undefined && { metadata: toolCallChunkEvent.metadata }),\n ...(toolCallChunkEvent.rawEvent !== undefined && {\n rawEvent: toolCallChunkEvent.rawEvent,\n }),\n ...(metadataOwner !== undefined && { subagentRunId: metadataOwner }),\n } as ToolCallArgsEvent);\n toolRemainderCarried = true;\n }\n\n carryRemainderOnOpener(\n toolMessageResult,\n toolChunkRemainder,\n toolRemainderCarried,\n \"TOOL_CALL_CHUNK\",\n );\n return toolMessageResult;\n }\n case EventType.REASONING_MESSAGE_CHUNK: {\n const reasoningChunkEvent = event as ReasoningMessageChunkEvent;\n const reasoningChunkRemainder = unrecognisedChunkProperties(event, REASONING_CHUNK_FIELDS);\n const lane = resolveLane(\n \"reasoning\",\n reasoningChunkEvent.messageId,\n reasoningChunkEvent.subagentRunId ?? undefined,\n \"REASONING_MESSAGE_CHUNK\",\n \"reasoning message\",\n );\n const open = lanes.get(lane);\n const reasoningMessageResult: BaseEvent[] = [];\n // As in the text arm above.\n let reasoningRemainderCarried = false;\n\n let reasoningMessageFields: ReasoningMessageFields;\n if (\n open?.kind === \"reasoning\" &&\n // `!== undefined`, not truthiness, to match the text and tool branches: an\n // explicitly empty id is a present id that denotes a NEW stream, and\n // treating it as absent left this pointing at the previous message and\n // stamped its content with the new chunk's owner.\n (reasoningChunkEvent.messageId === undefined ||\n reasoningChunkEvent.messageId === open.fields.messageId)\n ) {\n reasoningMessageFields = open.fields;\n } else {\n reasoningMessageResult.push(...closeLane(lane));\n\n if (reasoningChunkEvent.messageId === undefined) {\n throw new Error(\"First REASONING_MESSAGE_CHUNK must have a messageId\");\n }\n\n reasoningMessageFields = {\n messageId: reasoningChunkEvent.messageId,\n subagentRunId: reasoningChunkEvent.subagentRunId,\n };\n lanes.set(lane, { kind: \"reasoning\", fields: reasoningMessageFields });\n\n const reasoningMessageStartEvent = withChunkMetadata(\n {\n type: EventType.REASONING_MESSAGE_START,\n messageId: reasoningChunkEvent.messageId,\n role: \"reasoning\",\n // `!== undefined`, not `!= null`: an absent owner is absent,\n // but a null one is a violation the spec names, and dropping\n // it here would hide it from the stage that rejects it.\n ...(reasoningChunkEvent.subagentRunId !== undefined && {\n subagentRunId: reasoningChunkEvent.subagentRunId,\n }),\n } as ReasoningMessageStartEvent,\n reasoningChunkEvent,\n );\n reasoningMessageResult.push(reasoningMessageStartEvent);\n\n log?.event(\"TRANSFORM\", \"REASONING_MESSAGE_START\", reasoningMessageStartEvent, {\n messageId: reasoningChunkEvent.messageId,\n });\n }\n\n if (reasoningChunkEvent.delta !== undefined || reasoningChunkEvent.rawEvent !== undefined) {\n const contentOwner =\n reasoningChunkEvent.subagentRunId !== undefined\n ? reasoningChunkEvent.subagentRunId\n : reasoningMessageFields.subagentRunId;\n const reasoningMessageContentEvent = withChunkOrigin(\n {\n ...reasoningChunkRemainder,\n type: EventType.REASONING_MESSAGE_CONTENT,\n messageId: reasoningMessageFields.messageId,\n // `=== undefined`, not `??` — exactly how the opener's `role` is\n // handled above. The gate that reached this line is itself\n // `!== undefined`, so a `delta: null` passes it, and `??` then\n // repaired the malformed value into \"\". That made the same\n // producer defect fatal when sent unchunked and invisible when\n // sent as a chunk behind a middleware. Preserved, it is fatal on\n // both paths.\n delta: reasoningChunkEvent.delta === undefined ? \"\" : reasoningChunkEvent.delta,\n // Prefer the INCOMING chunk's tag over the opener's, so a producer that\n // attributes every chunk sees its own attribution on the output rather\n // than a value this transform remembered.\n ...(contentOwner !== undefined && { subagentRunId: contentOwner }),\n } as ReasoningMessageContentEvent,\n reasoningChunkEvent,\n );\n\n reasoningMessageResult.push(reasoningMessageContentEvent);\n reasoningRemainderCarried = true;\n\n log?.event(\"TRANSFORM\", \"REASONING_MESSAGE_CONTENT\", reasoningMessageContentEvent, {\n messageId: reasoningMessageFields.messageId,\n });\n }\n\n // Same as the text case above.\n if (\n reasoningMessageResult.length === 0 &&\n (reasoningChunkEvent.metadata !== undefined ||\n reasoningChunkEvent.rawEvent !== undefined ||\n reasoningChunkEvent.subagentRunId === null ||\n reasoningChunkRemainder !== undefined)\n ) {\n // Same attribution rule as the content path above.\n const metadataOwner =\n reasoningChunkEvent.subagentRunId !== undefined\n ? reasoningChunkEvent.subagentRunId\n : reasoningMessageFields!.subagentRunId;\n reasoningMessageResult.push({\n ...reasoningChunkRemainder,\n type: EventType.REASONING_MESSAGE_CONTENT,\n messageId: reasoningMessageFields!.messageId,\n delta: \"\",\n ...(reasoningChunkEvent.metadata !== undefined && { metadata: reasoningChunkEvent.metadata }),\n ...(reasoningChunkEvent.rawEvent !== undefined && {\n rawEvent: reasoningChunkEvent.rawEvent,\n }),\n ...(metadataOwner !== undefined && { subagentRunId: metadataOwner }),\n } as ReasoningMessageContentEvent);\n reasoningRemainderCarried = true;\n }\n\n carryRemainderOnOpener(\n reasoningMessageResult,\n reasoningChunkRemainder,\n reasoningRemainderCarried,\n \"REASONING_MESSAGE_CHUNK\",\n );\n return reasoningMessageResult;\n }\n }\n // Not a chunk event: a legacy type a compat middleware still\n // translates, a future one, or simply an event this stage has no\n // assembly to do for. Not this stage's to judge — it passes through\n // untouched and downstream layers decide. Dropping it here would\n // starve the middlewares, and closing lanes would end messages an\n // unrelated event never spoke about.\n const _exhaustiveCheck: never = event.type;\n return [event];\n }),\n finalize(() => {\n // Drops any lane still mid-assembly when the source completes. The END events\n // closeAllLanes() builds are DISCARDED here — finalize runs after the stream has\n // terminated and cannot emit — so this only clears the state, which matters for\n // an operator instance that outlives one subscription. A stream that ends without\n // a run terminal therefore has no synthesized END; the run-level cases above are\n // what actually emit them.\n closeAllLanes();\n }),\n );\n };\n","import { z } from \"zod/v4\";\n\n/**\n * Deep-strips material a schema does not describe, without judging what it\n * does describe.\n *\n * The tolerant validators deliberately keep unknown keys so middleware can\n * see them; this is the stage after middleware, where whatever nobody handled\n * is removed and reported. Three kinds of deviation are stripped, never\n * fatal:\n *\n * - an unknown property on a described object (dropped, path reported),\n * - an unrecognised member of a discriminated union (the element is dropped\n * from its array, or the key omitted, path reported),\n * - nothing else: a malformed VALUE on a described field is left in place for\n * the validator to reject fatally, because inventing a reading for it would\n * be data corruption.\n *\n * Arbitrary-JSON positions (state, metadata, rawEvent, forwardedProps, …) are\n * opaque schemas (z.any / z.custom), so their insides pass through untouched\n * — open-by-key means open.\n */\nexport interface StripResult<T> {\n value: T;\n /** JSON-pointer-ish paths of everything removed, for the deviation log. */\n stripped: string[];\n}\n\n/** Marks \"this whole value is unrecognisable here\" while unwinding. */\nconst DROP = Symbol(\"agui.strip.drop\");\n\nfunction unwrap(schema: z.ZodType): z.ZodType {\n let current: z.ZodType = schema;\n for (;;) {\n if (\n current instanceof z.ZodOptional ||\n current instanceof z.ZodNullable ||\n current instanceof z.ZodDefault ||\n current instanceof z.ZodReadonly ||\n current instanceof z.ZodCatch\n ) {\n current = (current as { unwrap(): unknown }).unwrap() as z.ZodType;\n continue;\n }\n // A pipe's INPUT side is the shape the wire data has; the output side\n // describes what the parse produces, which is not what is being stripped.\n if (current instanceof z.ZodPipe) {\n current = (current as unknown as { def: { in: z.ZodType } }).def.in;\n continue;\n }\n if (current instanceof z.ZodLazy) {\n current = (current as unknown as { def: { getter(): z.ZodType } }).def.getter();\n continue;\n }\n return current;\n }\n}\n\nfunction discriminatorOf(schema: z.ZodType): string | undefined {\n const def = (schema as { def?: { discriminator?: unknown } }).def;\n return typeof def?.discriminator === \"string\" ? def.discriminator : undefined;\n}\n\n/**\n * The single value a literal schema admits, read from `def.values` — the one\n * surface that is an array on every zod that ships `zod/v4`. The instance-level\n * `.values` is a Set on all of them, and the `.value` convenience getter only\n * exists from zod 3.25.7x on: a consumer holding an older copy of zod 3.25 (the\n * declared peer floor is 3.25.18) has literals with no `.value` at all, and a\n * reader that leaned on it silently keyed every event schema under\n * \"undefined\". Exported for enforce.ts, which builds its per-type map with it.\n */\nexport function literalValue(schema: z.ZodType): unknown {\n const probe = schema as unknown as {\n def?: { values?: unknown[] };\n values?: Iterable<unknown>;\n value?: unknown;\n };\n const values = Array.isArray(probe.def?.values)\n ? probe.def.values\n : probe.values\n ? Array.from(probe.values)\n : undefined;\n if (values && values.length === 1) return values[0];\n return probe.value;\n}\n\nfunction literalValueOf(schema: z.ZodType): unknown {\n const unwrapped = unwrap(schema);\n return unwrapped instanceof z.ZodLiteral ? literalValue(unwrapped) : undefined;\n}\n\nfunction stripAgainst(\n value: unknown,\n schema: z.ZodType,\n path: string,\n stripped: string[],\n): unknown {\n const target = unwrap(schema);\n\n if (target instanceof z.ZodObject) {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return value; // wrong shape: the validator's to reject, fatally\n }\n const shape = target.shape as Record<string, z.ZodType>;\n const record = value as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n // Every generated object is a looseObject, because the layers below\n // enforcement have to see unknown keys to translate them. That tolerance is\n // not the same as the SPEC leaving an object open, and only the schema can\n // tell the two apart, so the generator marks the ones it really does leave\n // open. Today those are the RFC 6902 operations, which the RFC requires to\n // ignore members they do not define rather than reject them: a remove\n // carrying a leftover value is a valid patch, and removing that member\n // while warning about it deletes conformant data and cries wolf.\n const specOpen =\n (target.meta() as { specOpen?: boolean } | undefined)?.specOpen === true;\n for (const key of Object.keys(record)) {\n // OWN property, not a plain `shape[key]`. The keys iterated here are the\n // PRODUCER's, and property access on a plain object walks the prototype\n // chain: `shape[\"toString\"]` answers with `Object.prototype.toString` —\n // a function, not `undefined` — so a producer key named `toString`,\n // `constructor`, `valueOf` or `hasOwnProperty` read as a field the\n // schema describes. It was then left in place and reported nowhere, and\n // an unrecognised property reached verification, subscribers and\n // application code in silence. Both halves of the guarantee at once.\n const field = Object.prototype.hasOwnProperty.call(shape, key)\n ? shape[key]\n : undefined;\n if (field === undefined) {\n if (specOpen) {\n result[key] = record[key];\n continue;\n }\n stripped.push(`${path}/${key}`);\n continue;\n }\n // Where the report stood before the descent. Anything the descent named\n // sits INSIDE this child, so if the child is dropped whole those paths\n // describe removals that never happened on their own — the enforcement\n // stage warns once per path, and would send an operator looking for a\n // key that was never the reason for anything.\n const mark = stripped.length;\n const child = stripAgainst(record[key], field, `${path}/${key}`, stripped);\n if (child === DROP) {\n stripped.length = mark;\n // An unrecognisable value in an OPTIONAL position is removable; in a\n // REQUIRED position the whole containing object is unrecognisable,\n // and the drop cascades — so a media part with a future source kind\n // removes the part, never leaving a sourceless part behind for the\n // validator to reject fatally.\n if (field.safeParse(undefined).success) {\n stripped.push(`${path}/${key}`);\n continue;\n }\n return DROP;\n }\n result[key] = child;\n }\n return result;\n }\n\n if (target instanceof z.ZodArray) {\n if (!Array.isArray(value)) return value;\n const element = target.element as z.ZodType;\n const result: unknown[] = [];\n value.forEach((entry, index) => {\n const mark = stripped.length;\n const child = stripAgainst(entry, element, `${path}/${index}`, stripped);\n if (child === DROP) {\n // The element goes whole, so the paths its descent named go with it.\n stripped.length = mark;\n stripped.push(`${path}/${index}`);\n return;\n }\n result.push(child);\n });\n return result;\n }\n\n if (target instanceof z.ZodRecord) {\n // A record describes every key, so no key here is ever \"unrecognised\" —\n // only a value can be, and it is removable exactly as an array element is.\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return value;\n const valueType = (target as unknown as { def: { valueType: z.ZodType } }).def.valueType;\n const record = value as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(record)) {\n const mark = stripped.length;\n const child = stripAgainst(record[key], valueType, `${path}/${key}`, stripped);\n if (child === DROP) {\n stripped.length = mark;\n stripped.push(`${path}/${key}`);\n continue;\n }\n result[key] = child;\n }\n return result;\n }\n\n if (target instanceof z.ZodUnion) {\n const options = target.options as z.ZodType[];\n const discriminator = discriminatorOf(target);\n if (discriminator !== undefined) {\n // Array.isArray, not just `typeof`: an array IS an \"object\", so without\n // this an array in a union slot reads its discriminator as undefined,\n // matches nothing, and is reported as removable — silently turning a\n // stream the validator would have rejected into a successful run with\n // the field quietly gone. It is a malformed VALUE on a described field,\n // which is the one deviation that stays fatal.\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return value;\n const tag = (value as Record<string, unknown>)[discriminator];\n for (const option of options) {\n const unwrapped = unwrap(option);\n if (!(unwrapped instanceof z.ZodObject)) continue;\n const shape = unwrapped.shape as Record<string, z.ZodType>;\n if (literalValueOf(shape[discriminator]) === tag) {\n return stripAgainst(value, option, path, stripped);\n }\n }\n // An unrecognised union member: removable, never fatal.\n return DROP;\n }\n // A structural union (e.g. string | array): recurse into the option whose\n // basic kind matches; if none does, the validator rejects fatally.\n //\n // With two or more OBJECT options there is no tag to read, so \"basic kind\"\n // picks whichever is listed first and then reports the other option's own\n // keys as unrecognised material — stripping exactly the fields that made\n // the value valid. Nothing generated has this shape today; leaving it\n // untouched hands the choice to the validator, which can actually make it.\n const objectOptions = options.filter((option) => unwrap(option) instanceof z.ZodObject);\n const isPlainObject = typeof value === \"object\" && value !== null && !Array.isArray(value);\n if (objectOptions.length > 1 && isPlainObject) return value;\n for (const option of options) {\n const unwrapped = unwrap(option);\n if (unwrapped instanceof z.ZodArray && Array.isArray(value)) {\n return stripAgainst(value, option, path, stripped);\n }\n if (unwrapped instanceof z.ZodObject && isPlainObject) {\n return stripAgainst(value, option, path, stripped);\n }\n }\n return value;\n }\n\n // Leaves (strings, numbers, enums, literals) and opaque schemas\n // (z.any, z.custom — the arbitrary-JSON positions) pass through whole.\n return value;\n}\n\n/** Deep-strips `value` against `schema`; see the module comment. */\nexport function stripUnknown<T>(value: T, schema: z.ZodType): StripResult<T> {\n const stripped: string[] = [];\n const result = stripAgainst(value, schema, \"\", stripped);\n if (result === DROP) {\n // Nothing generated can reach this: a required union member always sits\n // inside an array, whose element drop absorbs it. If a schema ever makes\n // the whole value unrecognisable, there is no honest answer to return —\n // handing back the untouched original alongside a list of removals would\n // describe a value the caller is not holding. So it is loud instead.\n throw new Error(\n \"Internal error: the stripper found the whole value unrecognisable, which the schemas are not supposed to allow — schema/stripper mismatch.\",\n );\n }\n return { value: result as T, stripped };\n}\n","import { BaseEvent, EventType, RunAgentInput, omitOptionalNulls } from \"@ag-ui/core\";\nimport { EventSchema, RunAgentInputSchema } from \"@ag-ui/core/schemas\";\nimport { z } from \"zod/v4\";\nimport { Observable, of, EMPTY } from \"rxjs\";\nimport { mergeMap } from \"rxjs/operators\";\nimport { type DebugLoggerInput, resolveDebugLogger } from \"@/debug-logger\";\nimport { literalValue, stripUnknown } from \"./strip\";\n\n/**\n * An event whose `type` the protocol does not know.\n *\n * Between the transport and enforcement, the stream can carry these — that is\n * the point of running enforcement AFTER middleware, so a translator for a\n * deprecated event stays reachable once the event leaves the schema. A\n * middleware that wants to handle one deliberately checks with\n * {@link isRecognizedEvent}; whatever nothing handles is dropped, with a\n * warning, at the enforcement stage. The loose type never survives past\n * verification: subscribers and application code only ever see known events.\n */\nexport type UnrecognizedEvent = {\n type: string;\n [key: string]: unknown;\n};\n\nconst KNOWN_EVENT_TYPES = new Set<string>(Object.values(EventType));\n\n/** Narrows an event back to the known set at the enforcement boundary. */\nexport function isRecognizedEvent(event: BaseEvent | UnrecognizedEvent): event is BaseEvent {\n return KNOWN_EVENT_TYPES.has(event.type as string);\n}\n\n// type discriminator -> that event's generated schema, for targeted stripping.\nconst EVENT_SCHEMA_BY_TYPE = new Map<string, z.ZodType>(\n (EventSchema.options as z.ZodType[]).map((option) => {\n const shape = (option as unknown as { shape: Record<string, z.ZodType> }).shape;\n return [String(literalValue(shape.type)), option];\n }),\n);\n\nconst suppressed = (): boolean =>\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n Boolean(process.env.SUPPRESS_TRANSFORMATION_WARNINGS);\n\nfunction warnDeviation(message: string): void {\n if (suppressed()) return;\n console.warn(`[ag-ui][enforce] ${message}`);\n}\n\n/**\n * The enforcement stage: on each of the agent's three pipelines — streaming,\n * binary and in-memory alike — it sits after the middleware chain and before\n * THAT PIPELINE's chunk expansion, and guarantees that nothing unrecognised\n * survives to verification, subscribers or application code.\n *\n * Both halves of that placement need a qualifier. Chunk expansion also happens\n * INSIDE the chain, in `Middleware.runNext`, and that expansion is upstream of\n * this stage rather than downstream — which is why chunks/transform.ts must\n * carry through whatever it cannot vouch for instead of repairing or dropping\n * it. And \"after the middleware chain\" says nothing on `connect`, where there\n * is no chain to be after: this stage still runs, on events arriving straight\n * off the transport.\n *\n * - An event whose type nothing translated is dropped, with a warning.\n * - Unknown properties and unrecognised union members on a known event are\n * stripped, each with a warning naming its path.\n * - A malformed value on a field the protocol DOES describe stays fatal:\n * the generated validator throws, and the run errors.\n */\nexport const enforceEvents =\n (debugLogger?: DebugLoggerInput) =>\n (source$: Observable<BaseEvent>): Observable<BaseEvent> => {\n const log = resolveDebugLogger(debugLogger);\n return source$.pipe(\n mergeMap((event) => {\n if (!isRecognizedEvent(event as BaseEvent | UnrecognizedEvent)) {\n warnDeviation(\n `Dropping unrecognised event '${String(event.type)}': no middleware translated it and the protocol does not describe it.`,\n );\n log?.event(\"ENFORCE\", \"Unrecognised event dropped:\", event, {\n type: event.type,\n });\n return EMPTY;\n }\n const schema = EVENT_SCHEMA_BY_TYPE.get(event.type as string);\n if (schema === undefined) {\n // Unreachable while EventType and the union are generated from the\n // same schema; guarded so a future drift fails loudly.\n throw new Error(`No validator for recognised event type '${String(event.type)}'`);\n }\n const { value, stripped } = stripUnknown(event, schema);\n for (const path of stripped) {\n warnDeviation(\n `Removed unrecognised material at '${path}' on ${String(event.type)}. Nothing handled it; see the repo-root DEPRECATIONS.md if it is a retired shape.`,\n );\n }\n // Malformed known fields are fatal, by design.\n return of(schema.parse(value) as BaseEvent);\n }),\n );\n };\n\n/**\n * The outgoing half of the same boundary: checked immediately before\n * transmission. Unknown properties are stripped with a warning; a malformed\n * known field is fatal before a byte leaves the process.\n */\nexport function enforceOutgoingInput(input: RunAgentInput): RunAgentInput {\n const { value, stripped } = stripUnknown(\n omitOptionalNulls(input, \"RunAgentInput\"),\n RunAgentInputSchema as unknown as z.ZodType,\n );\n for (const path of stripped) {\n warnDeviation(`Removed unrecognised material at '${path}' from the outgoing input.`);\n }\n // Unasserted on purpose: the generated schema's output and the generated\n // type are two files that must agree, and this is the one place where a\n // divergence between them can be made to fail the build rather than pass\n // silently through a cast.\n return RunAgentInputSchema.parse(value);\n}\n","import { AbstractAgent } from \"@/agent\";\nimport { RunAgentInput, BaseEvent, Message } from \"@ag-ui/core\";\nimport { Observable, ReplaySubject } from \"rxjs\";\nimport { concatMap } from \"rxjs/operators\";\nimport { transformChunks } from \"@/chunks\";\nimport { defaultApplyEvents } from \"@/apply\";\nimport { structuredClone_ } from \"@/utils\";\n\nexport type MiddlewareFunction = (\n input: RunAgentInput,\n next: AbstractAgent,\n) => Observable<BaseEvent>;\n\nexport interface EventWithState {\n event: BaseEvent;\n messages: Message[];\n // DEFERRED (PNI-272): tightening this to `unknown` is a breaking change for\n // consumers of a published package, not a lint repair. Left for a deliberate\n // API decision.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n state: any;\n}\n\nexport abstract class Middleware {\n abstract run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent>;\n\n /**\n * Runs the next agent in the chain with automatic chunk transformation.\n */\n protected runNext(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\n return next.run(input).pipe(\n transformChunks(false), // Always transform chunks to full events\n );\n }\n\n /**\n * Runs the next agent and tracks state, providing current messages and state with each event.\n * The messages and state represent the state AFTER the event has been applied.\n */\n protected runNextWithState(\n input: RunAgentInput,\n next: AbstractAgent,\n ): Observable<EventWithState> {\n let currentMessages = structuredClone_(input.messages || []);\n // `=== undefined`, not truthiness: State is any JSON value, so `false`,\n // `0`, `\"\"` and `null` are states a run legitimately starts from. Only a\n // genuinely absent state defaults to the empty object.\n let currentState = structuredClone_(input.state === undefined ? {} : input.state);\n\n // Use a ReplaySubject to feed events one by one\n const eventSubject = new ReplaySubject<BaseEvent>();\n\n // Set up defaultApplyEvents to process events\n const mutations$ = defaultApplyEvents(input, eventSubject, next, []);\n\n // Subscribe to track state changes.\n //\n // The `error` handler is deliberately empty, and deliberately present.\n // This reducer is a PRIVATE bookkeeping copy: its only job is to keep\n // `currentMessages`/`currentState` current for the events handed back\n // below. No event reaching it today can make it fail — a producer-sent\n // RUN_ERROR is applied like any other event, and the three sequences the\n // reducer refuses outright are the unexpanded chunks, which `runNext`\n // above has already expanded. The handler guards the shape of this\n // subscription rather than a live failure: a next-only observer would make\n // RxJS treat any future reducer failure as UNHANDLED, reported to\n // `reportUnhandledError`, which rethrows from a macrotask and takes the\n // host process down with an `uncaughtException` — from a bookkeeping copy\n // whose failure the caller neither sees nor needs. The caller's own stream\n // is a separate subscription that succeeds or fails on its own terms, and\n // there is nothing left to track once this one has ended.\n mutations$.subscribe({\n next: (mutation) => {\n if (mutation.messages !== undefined) {\n currentMessages = mutation.messages;\n }\n if (mutation.state !== undefined) {\n currentState = mutation.state;\n }\n },\n error: () => {},\n });\n\n return this.runNext(input, next).pipe(\n concatMap(async (event) => {\n // Feed the event to defaultApplyEvents and wait for it to process\n eventSubject.next(event);\n\n // Give defaultApplyEvents a chance to process\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n // Return event with current state\n return {\n event,\n messages: structuredClone_(currentMessages),\n state: structuredClone_(currentState),\n };\n }),\n );\n }\n}\n\n// Wrapper class to convert a function into a Middleware instance\nexport class FunctionMiddleware extends Middleware {\n constructor(private fn: MiddlewareFunction) {\n super();\n }\n\n run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\n return this.fn(input, next);\n }\n}\n","import type { RunAgentInput } from \"@ag-ui/core\";\n\ntype InputMessage = RunAgentInput[\"messages\"][number];\n\ninterface LegacyBinaryContent {\n type: \"binary\";\n mimeType: string;\n id?: string;\n url?: string;\n data?: string;\n filename?: string;\n}\n\ninterface NewContentPart {\n type: \"image\" | \"audio\" | \"video\" | \"document\";\n source:\n | { type: \"data\"; value: string; mimeType: string }\n | { type: \"url\"; value: string; mimeType: string };\n metadata?: unknown;\n}\n\nfunction mimeTypeToContentType(mimeType: string): \"image\" | \"audio\" | \"video\" | \"document\" {\n if (mimeType.startsWith(\"image/\")) return \"image\";\n if (mimeType.startsWith(\"audio/\")) return \"audio\";\n if (mimeType.startsWith(\"video/\")) return \"video\";\n return \"document\";\n}\n\nexport function isLegacyBinaryContent(part: unknown): part is LegacyBinaryContent {\n return (\n typeof part === \"object\" &&\n part !== null &&\n \"type\" in part &&\n (part as { type: unknown }).type === \"binary\" &&\n \"mimeType\" in part &&\n typeof (part as { mimeType: unknown }).mimeType === \"string\"\n );\n}\n\nexport function convertBinaryToNewFormat(\n binary: LegacyBinaryContent,\n): NewContentPart | LegacyBinaryContent {\n const contentType = mimeTypeToContentType(binary.mimeType);\n\n if (binary.data) {\n return {\n type: contentType,\n source: { type: \"data\", value: binary.data, mimeType: binary.mimeType },\n ...(binary.filename ? { metadata: { filename: binary.filename } } : {}),\n };\n }\n\n if (binary.url) {\n return {\n type: contentType,\n source: { type: \"url\", value: binary.url, mimeType: binary.mimeType },\n ...(binary.filename ? { metadata: { filename: binary.filename } } : {}),\n };\n }\n\n // If only `id` is present, we can't map to the new source format. The part\n // stays in its legacy shape — which the 1.0 contract no longer accepts —\n // so losing it downstream must not be silent.\n if (\n typeof process === \"undefined\" ||\n typeof process.env === \"undefined\" ||\n !process.env.SUPPRESS_TRANSFORMATION_WARNINGS\n ) {\n console.warn(\n `[ag-ui][compat] A binary content part carries only an id ('${binary.id ?? \"\"}') and cannot be converted to a modern media part; a 1.0 peer will not accept it. Provide data or a url. See the repo-root DEPRECATIONS.md.`,\n );\n }\n return binary;\n}\n\nfunction matchesModernPart(\n part: unknown,\n converted: NewContentPart,\n filename: string | undefined,\n): boolean {\n if (typeof part !== \"object\" || part === null || !(\"type\" in part)) return false;\n if (part.type !== converted.type || !(\"source\" in part)) return false;\n const source = part.source;\n if (typeof source !== \"object\" || source === null) return false;\n if (\n !(\"type\" in source) ||\n source.type !== converted.source.type ||\n !(\"value\" in source) ||\n source.value !== converted.source.value ||\n !(\"mimeType\" in source) ||\n source.mimeType !== converted.source.mimeType\n )\n return false;\n // A legacy filename is data too: only discard it if the modern part retains it.\n return (\n !filename ||\n (\"metadata\" in part &&\n typeof part.metadata === \"object\" &&\n part.metadata !== null &&\n \"filename\" in part.metadata &&\n part.metadata.filename === filename)\n );\n}\n\nexport function upgradeMessageContent(message: InputMessage): InputMessage {\n const rawContent = (message as { content?: unknown }).content;\n\n if (!Array.isArray(rawContent)) {\n return message;\n }\n\n const upgraded = rawContent.flatMap((part: unknown) => {\n if (isLegacyBinaryContent(part)) {\n const converted = convertBinaryToNewFormat(part);\n // Match against ORIGINAL modern parts, so repeated modern or legacy-only\n // attachments remain intentional repeats. A mirror can precede its original.\n if (\n converted.type !== \"binary\" &&\n rawContent.some((other: unknown) => matchesModernPart(other, converted, part.filename))\n )\n return [];\n return [converted];\n }\n return [part];\n });\n\n return { ...message, content: upgraded } as InputMessage;\n}\n","import { Middleware } from \"./middleware\";\nimport { AbstractAgent } from \"@/agent\";\nimport type { RunAgentInput, BaseEvent, Message } from \"@ag-ui/core\";\nimport { EventType } from \"@ag-ui/core\";\nimport { defer, type Observable } from \"rxjs\";\nimport { map } from \"rxjs/operators\";\nimport { randomUUID } from \"@/utils\";\nimport { upgradeMessageContent } from \"./legacy-content\";\n\n// Deprecated inbound shapes, retired from the 1.0 contract. Each entry here\n// has a row in the repo-root DEPRECATIONS.md — not this package's own\n// DEPRECATIONS.md, which tracks a different set under a different schema —\n// with its replacement and expiry date.\nconst THINKING_START = \"THINKING_START\";\nconst THINKING_END = \"THINKING_END\";\nconst THINKING_TEXT_MESSAGE_START = \"THINKING_TEXT_MESSAGE_START\";\nconst THINKING_TEXT_MESSAGE_CONTENT = \"THINKING_TEXT_MESSAGE_CONTENT\";\nconst THINKING_TEXT_MESSAGE_END = \"THINKING_TEXT_MESSAGE_END\";\n\nfunction warnCompatibility(what: string, replacement: string) {\n if (\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.SUPPRESS_TRANSFORMATION_WARNINGS\n )\n return;\n console.warn(\n `[ag-ui][compat] Converting deprecated ${what} to ${replacement}. The old shape leaves the protocol after its shim window — see the repo-root DEPRECATIONS.md. Set SUPPRESS_TRANSFORMATION_WARNINGS=true to silence.`,\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction omitLegacyNull(value: unknown, field: string, context: string): unknown {\n if (!isRecord(value) || value[field] !== null) return value;\n warnCompatibility(`${context}.${field}: null`, \"an absent field\");\n const { [field]: _null, ...rest } = value;\n return rest;\n}\n\nfunction mapProtocolArray(\n value: unknown,\n field: string,\n normalize: (entry: unknown) => unknown,\n): unknown {\n if (!isRecord(value) || !Array.isArray(value[field])) return value;\n const original = value[field];\n const entries = original.map(normalize);\n return entries.some((entry, index) => entry !== original[index])\n ? { ...value, [field]: entries }\n : value;\n}\n\nfunction normalizeLegacyMessageNulls(message: unknown): unknown {\n return mapProtocolArray(message, \"content\", (part) => {\n if (!isRecord(part)) return part;\n switch (part.type) {\n case \"image\":\n case \"audio\":\n case \"video\":\n case \"document\":\n return omitLegacyNull(part, \"metadata\", `${part.type} input content`);\n default:\n return part;\n }\n });\n}\n\n/**\n * Normalize only whole optional nulls accepted by pre-1.0 request parsers.\n * Used internally for RUN_STARTED.input; direct server request parsers do not\n * pass through this event boundary and must handle compatibility locally.\n * This does not validate input or walk opaque application data. Invalid\n * values, including nulls forbidden on main, remain for the validator to reject.\n * @internal\n */\nexport function normalizeLegacyRunAgentInput(input: unknown): unknown {\n let normalized = omitLegacyNull(input, \"forwardedProps\", \"RunAgentInput\");\n normalized = mapProtocolArray(normalized, \"tools\", (tool) =>\n omitLegacyNull(tool, \"parameters\", \"Tool\"),\n );\n normalized = mapProtocolArray(normalized, \"resume\", (entry) =>\n omitLegacyNull(entry, \"payload\", \"ResumeEntry\"),\n );\n return mapProtocolArray(normalized, \"messages\", normalizeLegacyMessageNulls);\n}\n\n/**\n * The always-on pre-1.0 compatibility boundary.\n *\n * With enforcement running AFTER middleware (PNI-205), anything nobody\n * translates is stripped with a warning. This middleware is the translator:\n * it upgrades every retired-but-understood inbound shape into its 1.0\n * equivalent, so no data an old peer sends is lost. It is deliberately NOT\n * version-gated — a legacy-shaped event arriving is itself the proof the\n * peer is old, and on a modern stream every branch below is a no-op.\n * Outgoing legacy binary attachments are also upgraded before the transport\n * validates or sends them. Their shape identifies the conversion regardless\n * of the peer ceiling; actual downgrades remain version-gated separately.\n *\n * Inbound conversions, each warned once per occurrence with a pointer to\n * the repo-root DEPRECATIONS.md:\n * - THINKING_* events -> their REASONING_* equivalents. The version-gated\n * BackwardCompatibility_0_0_45 runs the same state machine and keeps its\n * 0.0.45 threshold, but it is not untouched: its synthesized\n * REASONING_MESSAGE_START now says `role: \"reasoning\"` where it used to say\n * \"assistant\", the same correction made here, because enforcement moved\n * behind the middleware chain and made the invalid role fatal. In practice\n * only this translation runs: THIS middleware is appended innermost, so it\n * sees every thinking event first and the shim always finds nothing to do\n * (see the corpus README's \"A shim with no fixture\").\n * - Legacy binary content parts inside inbound messages (MESSAGES_SNAPSHOT,\n * RUN_STARTED input) -> the modern media parts.\n * - The three legacy nulls -> absent: parentMessageId on TOOL_CALL_START and\n * TOOL_CALL_CHUNK, and RUN_FINISHED.outcome.\n * - Optional JSON payload nulls accepted before 1.0 -> absent: rawEvent,\n * run/subagent result, media-part metadata, and optional JSON request fields\n * inside RUN_STARTED.input. Required and nested data nulls survive.\n */\nexport class CompatibilityBoundary extends Middleware {\n private currentReasoningId: string | null = null;\n private currentMessageId: string | null = null;\n\n private warn(what: string, replacement: string) {\n warnCompatibility(what, replacement);\n }\n\n /**\n * A THINKING_* continuation names nothing: the id it belongs to lives in\n * this middleware's state, put there by the matching opener. When no opener\n * preceded it, there is no id to reuse and one is MINTED — which turns a\n * producer's \"content with no start\" into a REASONING_* event naming an id\n * nothing ever opened. Verification rejects that a few stages later, with a\n * message about an id no producer ever wrote, so the mint is announced here:\n * without this line the rejection is untraceable to its cause.\n */\n private mintedContinuationId(from: string, established: string | null): string {\n if (established !== null) return established;\n const minted = randomUUID();\n this.warnAside(\n `Minting a messageId ('${minted}') for ${from}: no THINKING opener preceded it, so there was no id to continue. The id is this client's invention, not the producer's, and verification will reject the translated event for naming something nothing opened.`,\n );\n return minted;\n }\n\n /**\n * A conversion side effect the caller has to be told about in its own\n * sentence: something lost, or something invented. Separate from `warn`,\n * which only announces that a retired shape was translated — a reader who\n * saw only that would have no way to know the translation was not\n * information-preserving.\n */\n private warnAside(sentence: string) {\n if (\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.SUPPRESS_TRANSFORMATION_WARNINGS\n )\n return;\n console.warn(\n `[ag-ui][compat] ${sentence} Set SUPPRESS_TRANSFORMATION_WARNINGS=true to silence.`,\n );\n }\n\n override run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\n this.currentReasoningId = null;\n this.currentMessageId = null;\n // Deliberately next.run rather than runNext: runNext transforms chunks\n // before this middleware could see them, and the boundary must read the\n // RAW stream — a legacy null on a TOOL_CALL_CHUNK has to be converted\n // before chunk expansion discards or propagates it. The pipeline's own\n // chunk transformation still runs after the whole middleware chain.\n // Continuation handoffs can be bound to the lifecycle input's identity.\n // Replace its message list without mutating the original message content.\n input.messages = input.messages.map(upgradeMessageContent);\n return next.run(input).pipe(map((event) => this.transformEvent(event)));\n }\n\n private transformEvent(event: BaseEvent): BaseEvent {\n // Apply shared fields before event-specific translations so combined old\n // shapes (e.g. result:null plus outcome:null) are normalized in one pass.\n if (event.rawEvent === null) {\n this.warn(`${event.type}.rawEvent: null`, \"an absent field\");\n const { rawEvent: _null, ...rest } = event;\n event = rest;\n }\n if (\n (event.type === EventType.RUN_FINISHED || event.type === EventType.SUBAGENT_FINISHED) &&\n event.result === null\n ) {\n this.warn(`${event.type}.result: null`, \"an absent field\");\n const { result: _null, ...rest } = event;\n event = rest;\n }\n switch (event.type as string) {\n case THINKING_START: {\n this.currentReasoningId = randomUUID();\n const { title, ...rest } = event as BaseEvent & { title?: string };\n this.warn(THINKING_START, EventType.REASONING_START);\n // REASONING_START has no `title`, so the span's label is dropped here\n // and nothing downstream can recover it. Named separately from the\n // conversion notice above because it is a LOSS, not a translation, and\n // the versioning rules require a lossy downgrade to say what went.\n if (title !== undefined) {\n this.warnAside(\n `Dropping ${THINKING_START}.title ${JSON.stringify(title)}: ${EventType.REASONING_START} has no title field, so the span's label cannot be carried and nothing downstream can recover it.`,\n );\n }\n return {\n ...rest,\n type: EventType.REASONING_START,\n messageId: this.currentReasoningId,\n };\n }\n\n case THINKING_TEXT_MESSAGE_START: {\n this.currentMessageId = randomUUID();\n this.warn(THINKING_TEXT_MESSAGE_START, EventType.REASONING_MESSAGE_START);\n return {\n ...event,\n type: EventType.REASONING_MESSAGE_START,\n messageId: this.currentMessageId,\n // The schema pins this role to \"reasoning\"; the translation used to\n // say \"assistant\", which nothing validated until enforcement moved\n // behind the middleware chain and made the invalid output fatal.\n role: \"reasoning\" as const,\n };\n }\n\n case THINKING_TEXT_MESSAGE_CONTENT: {\n const { delta, ...rest } = event as BaseEvent & { delta: string };\n this.warn(THINKING_TEXT_MESSAGE_CONTENT, EventType.REASONING_MESSAGE_CONTENT);\n return {\n ...rest,\n type: EventType.REASONING_MESSAGE_CONTENT,\n messageId: this.mintedContinuationId(\n THINKING_TEXT_MESSAGE_CONTENT,\n this.currentMessageId,\n ),\n delta,\n };\n }\n\n case THINKING_TEXT_MESSAGE_END: {\n const messageId = this.mintedContinuationId(\n THINKING_TEXT_MESSAGE_END,\n this.currentMessageId,\n );\n this.currentMessageId = null;\n this.warn(THINKING_TEXT_MESSAGE_END, EventType.REASONING_MESSAGE_END);\n return {\n ...event,\n type: EventType.REASONING_MESSAGE_END,\n messageId,\n };\n }\n\n case THINKING_END: {\n const reasoningId = this.mintedContinuationId(THINKING_END, this.currentReasoningId);\n this.currentReasoningId = null;\n this.warn(THINKING_END, EventType.REASONING_END);\n return {\n ...event,\n type: EventType.REASONING_END,\n messageId: reasoningId,\n };\n }\n\n case EventType.TOOL_CALL_START:\n case EventType.TOOL_CALL_CHUNK: {\n const record = event as BaseEvent & { parentMessageId?: string | null };\n if (record.parentMessageId === null) {\n this.warn(`${event.type}.parentMessageId: null`, \"an absent field\");\n const { parentMessageId: _null, ...rest } = record;\n return rest as BaseEvent;\n }\n return event;\n }\n\n case EventType.RUN_FINISHED: {\n const record = event as BaseEvent & { outcome?: unknown };\n if (record.outcome === null) {\n this.warn(\"RUN_FINISHED.outcome: null\", \"an absent field\");\n const { outcome: _null, ...rest } = record;\n return rest as BaseEvent;\n }\n return event;\n }\n\n case EventType.MESSAGES_SNAPSHOT: {\n const record = event as BaseEvent & { messages?: Message[] };\n if (!Array.isArray(record.messages)) return event;\n return {\n ...record,\n messages: record.messages.map((message) => this.upgradeInboundMessage(message)),\n };\n }\n\n case EventType.RUN_STARTED: {\n const normalizedInput = normalizeLegacyRunAgentInput(event.input);\n const normalized =\n normalizedInput === event.input ? event : { ...event, input: normalizedInput };\n const record = normalized as BaseEvent & { input?: { messages?: Message[] } };\n if (!record.input || !Array.isArray(record.input.messages)) return normalized;\n return {\n ...record,\n input: {\n ...record.input,\n messages: record.input.messages.map((message) => this.upgradeInboundMessage(message)),\n },\n };\n }\n\n default:\n return event;\n }\n }\n\n private upgradeInboundMessage(message: Message): Message {\n // This helper changes only media-part metadata and preserves the rest of\n // the message shape; validation still happens after the boundary.\n message = normalizeLegacyMessageNulls(message) as Message;\n const content = (message as { content?: unknown }).content;\n if (!Array.isArray(content)) return message;\n const hasLegacyBinary = content.some(\n (part) =>\n typeof part === \"object\" && part !== null && (part as { type?: unknown }).type === \"binary\",\n );\n if (!hasLegacyBinary) return message;\n this.warn(\"binary input content\", \"the modern media content parts\");\n return upgradeMessageContent(message as never) as Message;\n }\n}\n\n/**\n * The boundary as a plain stream operator, for pipelines that have no\n * middleware chain to install it into (the connect/subscribe flow). A fresh\n * instance per subscription keeps the translation state per stream.\n */\nexport const compatibilityBoundaryOperator =\n () =>\n (source$: Observable<BaseEvent>): Observable<BaseEvent> =>\n defer(() => {\n const boundary = new CompatibilityBoundary();\n return source$.pipe(map((event) => boundary[\"transformEvent\"](event)));\n });\n","import type {\n Interrupt,\n Metadata,\n ResumeEntry,\n RunFinishedEvent,\n RunFinishedOutcome,\n} from \"@ag-ui/core\";\n\nexport function getRunOutcome(event: RunFinishedEvent): RunFinishedOutcome | undefined {\n return event.outcome;\n}\n\nexport function isInterruptExpired(interrupt: Interrupt, now: Date = new Date()): boolean {\n if (interrupt.expiresAt === undefined) return false;\n return new Date(interrupt.expiresAt) <= now;\n}\n\ntype ResumeResponse =\n | { status: \"resolved\"; payload?: unknown; metadata?: Metadata }\n | { status: \"cancelled\"; metadata?: Metadata };\n\nexport function buildResumeArray(\n interrupts: Interrupt[],\n responses: Record<string, ResumeResponse>,\n): ResumeEntry[] {\n const openIds = new Set(interrupts.map((i) => i.id));\n const responseIds = new Set(Object.keys(responses));\n\n const missing = [...openIds].filter((id) => !responseIds.has(id));\n if (missing.length > 0) {\n throw new Error(`buildResumeArray: missing responses for open interrupts: ${missing.join(\", \")}`);\n }\n\n const unknown = [...responseIds].filter((id) => !openIds.has(id));\n if (unknown.length > 0) {\n throw new Error(`buildResumeArray: responses reference unknown interrupt ids: ${unknown.join(\", \")}`);\n }\n\n return interrupts.map((i) => {\n const r = responses[i.id];\n const entry: ResumeEntry = { interruptId: i.id, status: r.status };\n if (r.status === \"resolved\" && r.payload !== undefined) entry.payload = r.payload;\n if (r.metadata !== undefined) entry.metadata = r.metadata;\n return entry;\n });\n}\n","import { Middleware } from \"./middleware\";\nimport { AbstractAgent } from \"@/agent\";\nimport {\n RunAgentInput,\n BaseEvent,\n EventType,\n ToolCallStartEvent,\n ToolCallArgsEvent,\n ToolCallEndEvent,\n ToolCallResultEvent,\n} from \"@ag-ui/core\";\nimport { defer, Observable } from \"rxjs\";\nimport { filter } from \"rxjs/operators\";\n\ntype FilterToolCallsConfig =\n | { allowedToolCalls: string[]; disallowedToolCalls?: never }\n | { disallowedToolCalls: string[]; allowedToolCalls?: never };\n\nexport class FilterToolCallsMiddleware extends Middleware {\n private readonly allowedTools?: Set<string>;\n private readonly disallowedTools?: Set<string>;\n\n constructor(config: FilterToolCallsConfig) {\n super();\n\n // Runtime validation (belt and suspenders approach)\n if (config.allowedToolCalls && config.disallowedToolCalls) {\n throw new Error(\"Cannot specify both allowedToolCalls and disallowedToolCalls\");\n }\n\n if (!config.allowedToolCalls && !config.disallowedToolCalls) {\n throw new Error(\"Must specify either allowedToolCalls or disallowedToolCalls\");\n }\n\n if (config.allowedToolCalls) {\n this.allowedTools = new Set(config.allowedToolCalls);\n } else if (config.disallowedToolCalls) {\n this.disallowedTools = new Set(config.disallowedToolCalls);\n }\n }\n\n /**\n * One middleware instance serves every run, so the set of blocked IDs cannot live on it.\n *\n * A stalled run whose subscription is still open is the case that makes this concrete: with the\n * set on the instance, the next run starting wipes the IDs that were still filtering the stalled\n * run's events, and its `TOOL_CALL_ARGS`, `TOOL_CALL_END` and `TOOL_CALL_RESULT` start coming\n * through for a tool the caller disallowed. Clearing at the end of a run has the same problem\n * from the other direction.\n *\n * `defer` gives each subscription its own set, and `RUN_STARTED` resets it, which is what covers\n * two runs arriving down one subscription: `run()` is called once there, so anything keyed to the\n * call rather than to the event never fires for the second run.\n */\n run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\n return defer(() => {\n const blockedToolCallIds = new Set<string>();\n\n // Use runNext which already includes transformChunks\n return this.runNext(input, next).pipe(\n filter((event) => {\n // A run boundary invalidates any IDs left over from a run that was interrupted before\n // its TOOL_CALL_RESULT arrived, and stops a reused tool call ID being shadowed by one.\n if (event.type === EventType.RUN_STARTED) {\n blockedToolCallIds.clear();\n return true;\n }\n\n // Handle TOOL_CALL_START events\n if (event.type === EventType.TOOL_CALL_START) {\n const toolCallStartEvent = event as ToolCallStartEvent;\n const shouldFilter = this.shouldFilterTool(toolCallStartEvent.toolCallName);\n\n if (shouldFilter) {\n // Track this tool call ID as blocked\n blockedToolCallIds.add(toolCallStartEvent.toolCallId);\n return false; // Filter out this event\n }\n\n return true; // Allow this event\n }\n\n // Handle TOOL_CALL_ARGS events\n if (event.type === EventType.TOOL_CALL_ARGS) {\n const toolCallArgsEvent = event as ToolCallArgsEvent;\n return !blockedToolCallIds.has(toolCallArgsEvent.toolCallId);\n }\n\n // Handle TOOL_CALL_END events\n if (event.type === EventType.TOOL_CALL_END) {\n const toolCallEndEvent = event as ToolCallEndEvent;\n return !blockedToolCallIds.has(toolCallEndEvent.toolCallId);\n }\n\n // Handle TOOL_CALL_RESULT events\n if (event.type === EventType.TOOL_CALL_RESULT) {\n const toolCallResultEvent = event as ToolCallResultEvent;\n const isBlocked = blockedToolCallIds.has(toolCallResultEvent.toolCallId);\n\n if (isBlocked) {\n // Clean up the blocked ID after the last event\n blockedToolCallIds.delete(toolCallResultEvent.toolCallId);\n return false;\n }\n\n return true;\n }\n\n // Allow all other events through\n return true;\n }),\n );\n });\n }\n\n private shouldFilterTool(toolName: string): boolean {\n if (this.allowedTools) {\n // If using allowed list, filter out tools NOT in the list\n return !this.allowedTools.has(toolName);\n } else if (this.disallowedTools) {\n // If using disallowed list, filter out tools IN the list\n return this.disallowedTools.has(toolName);\n }\n\n return false;\n }\n}\n","import { Middleware } from \"./middleware\";\nimport { AbstractAgent } from \"@/agent\";\nimport type { RunAgentInput, BaseEvent } from \"@ag-ui/core\";\nimport type { Observable } from \"rxjs\";\n\ntype InputMessage = RunAgentInput[\"messages\"][number];\n\nfunction suppressed(): boolean {\n return (\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n Boolean(process.env.SUPPRESS_TRANSFORMATION_WARNINGS)\n );\n}\n\nfunction warnDroppedParts(dropped: string[]): void {\n if (suppressed()) return;\n console.warn(\n `[ag-ui][compat] Flattening message content for a <=0.0.39 peer DROPS non-text parts (${dropped.join(\", \")}). The peer cannot receive them; upgrade it to keep media content. See the repo-root DEPRECATIONS.md.`,\n );\n}\n\nfunction warnMalformedTextPart(count: number): void {\n if (suppressed()) return;\n console.warn(\n `[ag-ui][compat] Not flattening message content for a <=0.0.39 peer: ${count} content part(s) claim type \"text\" but carry a malformed 'text' value. That is a defect in the message, not media the peer cannot represent, and a downgrade must not repair it — the content is passed on unchanged so the outgoing enforcement boundary reports it. See the repo-root DEPRECATIONS.md.`,\n );\n}\n\nfunction sanitizeMessageContent(message: InputMessage): InputMessage {\n const rawContent = (message as { content?: unknown }).content;\n\n if (Array.isArray(rawContent)) {\n // Two questions, deliberately separate. \"Does this part CLAIM to be text?\"\n // decides whether it is media the peer cannot represent; \"is its `text`\n // actually a string?\" decides whether it is well formed. Answering only\n // the second conflated the two, so a text part with `text: 42` was\n // flattened away AND announced as a dropped media part.\n const isTextPart = (part: unknown): part is { type: \"text\"; text?: unknown } =>\n typeof part === \"object\" &&\n part !== null &&\n \"type\" in part &&\n (part as { type: unknown }).type === \"text\";\n const isText = (part: unknown): part is { type: \"text\"; text: string } =>\n isTextPart(part) && typeof (part as { text?: unknown }).text === \"string\";\n\n // \"A downgrade MUST NOT repair a malformed value on the way past\"\n // (/spec/1.0/basic/versioning). A malformed text part is a defect in the\n // message; dropping it and flattening what is left produced acceptable\n // content out of unacceptable input, which is exactly the repair that\n // rule forbids. Hand the message on untouched instead — the outgoing\n // enforcement boundary rejects it fatally, the same as when no shim is\n // installed.\n const malformedTextParts = rawContent.filter((part) => isTextPart(part) && !isText(part));\n if (malformedTextParts.length > 0) {\n warnMalformedTextPart(malformedTextParts.length);\n return message;\n }\n\n // Losing content must never be silent: an image, audio, video, document\n // or binary part cannot survive the flattening a 0.0.39 peer requires.\n // Every part reaching here is either well-formed text or genuinely not\n // text, so this census now says only what it means.\n const dropped = rawContent\n .filter((part) => !isText(part))\n .map((part) =>\n typeof part === \"object\" && part !== null && \"type\" in part\n ? String((part as { type: unknown }).type)\n : typeof part,\n );\n if (dropped.length > 0) {\n warnDroppedParts(dropped);\n }\n\n const concatenatedContent = rawContent\n .filter(isText)\n .map((part) => part.text)\n .join(\"\");\n\n return {\n ...message,\n content: concatenatedContent,\n } as InputMessage;\n }\n\n if (typeof rawContent === \"string\") {\n return message;\n }\n\n // ABSENT content is the one value a downgrade may supply for: \"an empty\n // string where content is now absent\" is named as permitted reshaping by\n // the versioning rules, because the older schema requires the field.\n if (rawContent === undefined) {\n return {\n ...message,\n content: \"\",\n } as InputMessage;\n }\n\n // Anything else — null, a number, an object — is a known field holding a\n // value the schema rejects, and repairing it to \"\" hid a defect that is\n // fatal the moment the same message is sent to a modern peer. Untouched, so\n // the outgoing enforcement boundary reports it.\n return message;\n}\n\n/**\n * Middleware placeholder that maintains compatibility with AG-UI 0.0.39 flows.\n * Currently it simply forwards all events to the next middleware/agent.\n */\nexport class BackwardCompatibility_0_0_39 extends Middleware {\n override run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\n const { parentRunId: _parentRunId, ...rest } = input;\n const sanitizedInput: RunAgentInput = {\n ...rest,\n messages: rest.messages.map(sanitizeMessageContent),\n } as RunAgentInput;\n\n return this.runNext(sanitizedInput, next);\n }\n}\n","import { Middleware } from \"./middleware\";\nimport { AbstractAgent } from \"@/agent\";\nimport type { RunAgentInput, BaseEvent } from \"@ag-ui/core\";\nimport { EventType } from \"@ag-ui/core\";\nimport type { Observable } from \"rxjs\";\nimport { map } from \"rxjs/operators\";\nimport { randomUUID } from \"@/utils\";\n\n// Event type strings for THINKING events (deprecated)\nconst THINKING_START = \"THINKING_START\";\nconst THINKING_END = \"THINKING_END\";\nconst THINKING_TEXT_MESSAGE_START = \"THINKING_TEXT_MESSAGE_START\";\nconst THINKING_TEXT_MESSAGE_CONTENT = \"THINKING_TEXT_MESSAGE_CONTENT\";\nconst THINKING_TEXT_MESSAGE_END = \"THINKING_TEXT_MESSAGE_END\";\n\n/**\n * Middleware that maps deprecated THINKING events to the new REASONING events.\n *\n * This ensures backward compatibility for agents that still emit legacy THINKING\n * events (THINKING_START, THINKING_END, THINKING_TEXT_MESSAGE_START, etc.)\n * by transforming them into the corresponding REASONING events.\n *\n * Event mapping:\n * - THINKING_START → REASONING_START\n * - THINKING_TEXT_MESSAGE_START → REASONING_MESSAGE_START\n * - THINKING_TEXT_MESSAGE_CONTENT → REASONING_MESSAGE_CONTENT\n * - THINKING_TEXT_MESSAGE_END → REASONING_MESSAGE_END\n * - THINKING_END → REASONING_END\n *\n */\nexport class BackwardCompatibility_0_0_45 extends Middleware {\n private currentReasoningId: string | null = null;\n private currentMessageId: string | null = null;\n\n private warnAboutTransformation(from: string, to: string) {\n if (\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.SUPPRESS_TRANSFORMATION_WARNINGS\n )\n return;\n console.warn(\n `AG-UI is converting ${from} to ${to}. To remove this warning, upgrade your AG-UI integration package (e.g. @ag-ui/langgraph). To surpress it, set SUPPRESS_TRANSFORMATION_WARNINGS=true in your .env file.`,\n );\n }\n override run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\n // Reset state for each run\n this.currentReasoningId = null;\n this.currentMessageId = null;\n\n return this.runNext(input, next).pipe(map((event) => this.transformEvent(event)));\n }\n\n private transformEvent(event: BaseEvent): BaseEvent {\n const eventType = event.type as string;\n\n switch (eventType) {\n case THINKING_START: {\n this.currentReasoningId = randomUUID();\n const { title, ...rest } = event as BaseEvent & { title?: string };\n this.warnAboutTransformation(THINKING_START, EventType.REASONING_START);\n return {\n ...rest,\n type: EventType.REASONING_START,\n messageId: this.currentReasoningId,\n };\n }\n\n case THINKING_TEXT_MESSAGE_START: {\n this.currentMessageId = randomUUID();\n this.warnAboutTransformation(\n THINKING_TEXT_MESSAGE_START,\n EventType.REASONING_MESSAGE_START,\n );\n return {\n ...event,\n type: EventType.REASONING_MESSAGE_START,\n messageId: this.currentMessageId,\n // The schema pins this role to \"reasoning\"; the translation used to\n // say \"assistant\", which nothing validated until enforcement moved\n // behind the middleware chain and made the invalid output fatal.\n role: \"reasoning\" as const,\n };\n }\n\n case THINKING_TEXT_MESSAGE_CONTENT: {\n const { delta, ...rest } = event as BaseEvent & { delta: string };\n this.warnAboutTransformation(\n THINKING_TEXT_MESSAGE_CONTENT,\n EventType.REASONING_MESSAGE_CONTENT,\n );\n return {\n ...rest,\n type: EventType.REASONING_MESSAGE_CONTENT,\n messageId: this.currentMessageId ?? randomUUID(),\n delta,\n };\n }\n\n case THINKING_TEXT_MESSAGE_END: {\n const messageId = this.currentMessageId ?? randomUUID();\n this.warnAboutTransformation(THINKING_TEXT_MESSAGE_END, EventType.REASONING_MESSAGE_END);\n return {\n ...event,\n type: EventType.REASONING_MESSAGE_END,\n messageId,\n };\n }\n\n case THINKING_END: {\n const reasoningId = this.currentReasoningId ?? randomUUID();\n this.warnAboutTransformation(THINKING_END, EventType.REASONING_END);\n return {\n ...event,\n type: EventType.REASONING_END,\n messageId: reasoningId,\n };\n }\n\n default:\n return event;\n }\n }\n}\n","import { Middleware } from \"./middleware\";\nimport { AbstractAgent } from \"@/agent\";\nimport type { RunAgentInput, BaseEvent } from \"@ag-ui/core\";\nimport { EventType } from \"@ag-ui/core\";\nimport type { Observable } from \"rxjs\";\nimport { filter, map, tap } from \"rxjs/operators\";\n\n// Subagent lifecycle event types (introduced after 0.0.57). Referenced as string\n// literals so this shim keeps compiling even if the enum members are ever removed.\nconst SUBAGENT_STARTED = \"SUBAGENT_STARTED\";\nconst SUBAGENT_FINISHED = \"SUBAGENT_FINISHED\";\nconst SUBAGENT_ERROR = \"SUBAGENT_ERROR\";\n\ntype MessageLike = Record<string, unknown>;\n\n/**\n * Returns `obj` unchanged when it has no `subagentRunId`; otherwise returns a shallow\n * copy with the top-level `subagentRunId` key removed. Never mutates the input.\n * Only the top-level key is removed — nested message arrays are handled explicitly\n * by the caller (see `MESSAGES_SNAPSHOT` / `RUN_STARTED.input` handling below).\n */\nfunction stripSubagentRunId<T extends object>(obj: T): T {\n if (obj && typeof obj === \"object\" && \"subagentRunId\" in obj) {\n const { subagentRunId: _subagentRunId, ...rest } = obj as T & { subagentRunId?: unknown };\n return rest as T;\n }\n return obj;\n}\n\n/** Strips the top-level `subagentRunId` from each message in an array. */\nfunction stripMessages(messages: MessageLike[]): MessageLike[] {\n return messages.map((message) => stripSubagentRunId(message));\n}\n\n/**\n * Client middleware that removes subagent-support additions when the REMOTE AGENT is\n * pre-subagent (its `maxProtocolVersion` <= 0.0.57; the shim is auto-inserted by that gate).\n * The old party is the upstream agent, not the downstream consumer (the current client\n * supports subagents).\n *\n * - client → agent (the run input): strips `subagentRunId` from every top-level message so\n * a pre-subagent agent never receives attribution it doesn't understand. This is the\n * load-bearing half — the client's replayed message history can carry `subagentRunId`,\n * and this is what protects the old agent from it.\n * - agent → client (the event stream): defensive normalization. A genuinely pre-subagent\n * agent cannot emit `SUBAGENT_*` events or `subagentRunId`, and any `RUN_STARTED.input`\n * echo was already sanitized on the way in — so this path guards mixed/proxied\n * pipelines rather than doing load-bearing translation. It drops\n * SUBAGENT_STARTED/FINISHED/ERROR events and strips `subagentRunId` from every remaining\n * event, from MESSAGES_SNAPSHOT messages, and from RUN_STARTED `input` messages.\n *\n * Scope: this removes the protocol-level `subagentRunId` field and the SUBAGENT_* event\n * types only. It does NOT recurse into opaque application payloads (`RAW.event`,\n * `CUSTOM.value`, `STATE_SNAPSHOT.snapshot`, `STATE_DELTA.delta`, activity `content`,\n * etc.). Non-lifecycle events a subagent produced (TEXT_MESSAGE_*, TOOL_CALL_*, ...) are\n * kept with their `subagentRunId` stripped, so they flatten into the parent thread — the\n * intended downgrade, since subagent separation cannot be represented to a consumer with\n * no concept of it.\n *\n * The subagent feature is purely additive, so this shim is a pure removal in both\n * directions; there is no field/event to translate (unlike 0.0.45's THINKING->REASONING).\n *\n * Who this actually fires for: `maxProtocolVersion` defaults to this library's own\n * version, which sits above every era threshold, so the shim is installed only for an\n * agent subclass that OVERRIDES the ceiling to declare an older backend. As of this\n * writing exactly ONE integration in this repository does:\n * `integrations/community/spring-ai/typescript/src/index.ts`, pinned at 0.0.39.\n *\n * An earlier version of this note claimed six, naming llama-index, pydantic-ai, ag2,\n * agno and crew-ai alongside it. That census was wrong, and three of those integrations\n * now carry tests asserting the opposite -- llama-index's `multimodal-passthrough`,\n * and crew-ai's and agno's `no-content-flattening`, each of which fails if the agent\n * starts pinning a ceiling again. Do not trust this paragraph either: it is a snapshot\n * of code that lives outside this package and nothing keeps it honest. Re-check with\n * `grep -rn \"maxProtocolVersion\\|maxVersion\" integrations` before relying on it.\n *\n * Where the shim IS installed, the client → agent strip carries the weight: those\n * backends predate subagents, so a replayed history or a stored thread written by a\n * newer client must not deliver them attribution they cannot interpret. The\n * agent → client strip is the defensive counterpart described above.\n */\nexport class BackwardCompatibility_0_0_57 extends Middleware {\n private warnDroppedLifecycleEvent(eventType: string) {\n if (\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.SUPPRESS_TRANSFORMATION_WARNINGS\n )\n return;\n console.warn(\n `AG-UI is dropping ${eventType} because the target agent predates subagent support. ` +\n `To remove this warning, upgrade your AG-UI integration package. To suppress it, set ` +\n `SUPPRESS_TRANSFORMATION_WARNINGS=true in your .env file.`,\n );\n }\n\n override run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\n const sanitizedInput: RunAgentInput = {\n ...input,\n messages: (input.messages ?? []).map((message) => stripSubagentRunId(message)),\n } as RunAgentInput;\n\n return this.runNext(sanitizedInput, next).pipe(\n tap((event) => {\n const type = event.type as string;\n if (type === SUBAGENT_STARTED || type === SUBAGENT_FINISHED || type === SUBAGENT_ERROR) {\n this.warnDroppedLifecycleEvent(type);\n }\n }),\n filter((event) => {\n const type = event.type as string;\n return type !== SUBAGENT_STARTED && type !== SUBAGENT_FINISHED && type !== SUBAGENT_ERROR;\n }),\n map((event) => {\n const stripped = stripSubagentRunId(event);\n\n // MESSAGES_SNAPSHOT embeds a full message array.\n if (stripped.type === EventType.MESSAGES_SNAPSHOT) {\n const snapshot = stripped as BaseEvent & { messages?: MessageLike[] };\n if (Array.isArray(snapshot.messages)) {\n return { ...snapshot, messages: stripMessages(snapshot.messages) } as BaseEvent;\n }\n }\n\n // RUN_FINISHED's interrupt outcome attributes each interrupt to the subagent\n // that raised it (Interrupt.subagentRunId) — nested, so the shallow top-level\n // strip above never reaches it. A genuinely pre-subagent agent cannot emit it;\n // like the rest of this direction, this normalizes mixed/proxied pipelines so\n // no fragment of the subagent contract leaks without its lifecycle context.\n if (stripped.type === EventType.RUN_FINISHED) {\n const runFinished = stripped as BaseEvent & {\n outcome?: { type?: string; interrupts?: MessageLike[] };\n };\n if (runFinished.outcome && Array.isArray(runFinished.outcome.interrupts)) {\n return {\n ...runFinished,\n outcome: {\n ...runFinished.outcome,\n interrupts: runFinished.outcome.interrupts.map((interrupt) =>\n stripSubagentRunId(interrupt),\n ),\n },\n } as BaseEvent;\n }\n }\n\n // RUN_STARTED may echo the run input, whose messages also carry subagentRunId.\n if (stripped.type === EventType.RUN_STARTED) {\n const runStarted = stripped as BaseEvent & { input?: { messages?: MessageLike[] } };\n if (runStarted.input && Array.isArray(runStarted.input.messages)) {\n return {\n ...runStarted,\n input: { ...runStarted.input, messages: stripMessages(runStarted.input.messages) },\n } as BaseEvent;\n }\n }\n\n return stripped;\n }),\n );\n }\n}\n","","import { defaultApplyEvents } from \"@/apply/default\";\nimport {\n Message,\n State,\n RunAgentInput,\n BaseEvent,\n AgentCapabilities,\n Interrupt,\n // The version this client declares and judges a producer's declaration\n // against, generated from the schema's $id rather than written beside it.\n PROTOCOL_VERSION,\n} from \"@ag-ui/core\";\n\nimport {\n AgentConfig,\n AgentDebugConfig,\n RunAgentParameters,\n ResolvedAgentDebugConfig,\n resolveAgentDebugConfig,\n} from \"./types\";\nimport { DebugLogger, createDebugLogger } from \"@/debug-logger\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { structuredClone_ } from \"@/utils\";\nimport { compareVersions, validate as validateVersion } from \"compare-versions\";\nimport { catchError, map, tap } from \"rxjs/operators\";\nimport { finalize } from \"rxjs/operators\";\nimport { takeUntil } from \"rxjs/operators\";\nimport { pipe, Observable, from, of, EMPTY, Subject, defer } from \"rxjs\";\nimport { verifyEvents } from \"@/verify\";\nimport { convertToLegacyEvents } from \"@/legacy/convert\";\nimport { LegacyRuntimeProtocolEvent } from \"@/legacy/types\";\nimport { lastValueFrom } from \"rxjs\";\nimport { transformChunks } from \"@/chunks\";\nimport { enforceEvents } from \"@/enforce\";\nimport {\n CompatibilityBoundary,\n compatibilityBoundaryOperator,\n} from \"@/middleware/compatibility-boundary\";\nimport { AgentStateMutation, AgentSubscriber, runSubscribersWithMutation } from \"./subscriber\";\nimport { AGUIConnectNotImplementedError, AGUIError } from \"@ag-ui/core\";\nimport { isInterruptExpired } from \"@/interrupts\";\nimport {\n Middleware,\n MiddlewareFunction,\n FunctionMiddleware,\n BackwardCompatibility_0_0_39,\n BackwardCompatibility_0_0_45,\n BackwardCompatibility_0_0_57,\n} from \"@/middleware\";\nimport packageJson from \"../../package.json\";\n\n\n/** The maxVersion deprecation warns once per process, not once per call. */\nlet warnedDeprecatedMaxVersion = false;\n\n/**\n * The producer's RUN_STARTED declaration, judged against what this client\n * speaks. Older or absent is the downgrade signal the versioning rules expect\n * a consumer to notice quietly; NEWER means material this client may be\n * stripping, and that deserves a voice.\n *\n * The grammar is exactly the published one — two numeric components — checked\n * BEFORE any comparison: compareVersions would happily read \"1\", \"1.0.0\" or\n * \"1.x\" as equal to \"1.0\", and the spec says a value outside the grammar is\n * handled like a newer one, not silently accepted.\n */\nexport const compareDeclaredProtocol = (\n declared: string,\n spoken: string,\n): \"newer\" | \"not-newer\" | \"uninterpretable\" => {\n if (!/^\\d+\\.\\d+$/.test(declared)) return \"uninterpretable\";\n return compareVersions(declared, spoken) > 0 ? \"newer\" : \"not-newer\";\n};\n\nconst warnOnProducerDeclaration = (event: unknown): void => {\n const declared = (event as { protocolVersion?: string }).protocolVersion;\n if (declared === undefined || declared === PROTOCOL_VERSION) return;\n switch (compareDeclaredProtocol(declared, PROTOCOL_VERSION)) {\n case \"uninterpretable\":\n console.warn(\n `[ag-ui] The producer declared protocol version '${declared}', which this client cannot interpret.`,\n );\n return;\n case \"newer\":\n console.warn(\n `[ag-ui] The producer speaks protocol ${declared}; this client speaks ${PROTOCOL_VERSION}. Unrecognised material will be stripped with warnings.`,\n );\n return;\n case \"not-newer\":\n return;\n }\n};\n\nexport interface RunAgentResult {\n // DEFERRED (PNI-272): tightening this to `unknown` is a breaking change for\n // consumers of a published package, not a lint repair. Left for a deliberate\n // API decision.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n result: any;\n newMessages: Message[];\n}\n\nexport abstract class AbstractAgent {\n public agentId?: string;\n public description: string;\n public threadId: string;\n public messages: Message[];\n public state: State;\n private _debug: ResolvedAgentDebugConfig;\n private _debugLogger: DebugLogger | undefined;\n public subscribers: AgentSubscriber[] = [];\n public isRunning: boolean = false;\n /** Interrupts emitted by the most recent run that have not yet been resolved.\n * Populated when RUN_FINISHED arrives with outcome.type === \"interrupt\".\n * Cleared when a subsequent run completes successfully. */\n public pendingInterrupts: Interrupt[] = [];\n private middlewares: Middleware[] = [];\n // Emits to immediately detach from the active run (stop processing its stream)\n private activeRunDetach$?: Subject<void>;\n private activeRunCompletionPromise?: Promise<void>;\n\n /** Stops a legacy override that forwards to this.maxProtocolVersion. */\n private resolvingPeerCeiling = false;\n\n private resolvePeerCeiling(name: \"maxVersion\" | \"maxProtocolVersion\"): string {\n if (this.resolvingPeerCeiling) {\n return packageJson.version;\n }\n\n // Inspect descriptors without executing either public getter.\n let legacyOverride = Object.getOwnPropertyDescriptor(this, \"maxVersion\");\n let modernOverride = Object.getOwnPropertyDescriptor(this, \"maxProtocolVersion\");\n let proto = Object.getPrototypeOf(this);\n while (proto && proto !== AbstractAgent.prototype) {\n legacyOverride ??= Object.getOwnPropertyDescriptor(proto, \"maxVersion\");\n modernOverride ??= Object.getOwnPropertyDescriptor(proto, \"maxProtocolVersion\");\n proto = Object.getPrototypeOf(proto);\n }\n\n // With a legacy override, this base getter is reached via super.maxVersion.\n // Return the base ceiling instead of entering that override a second time.\n if (name === \"maxVersion\" && legacyOverride) {\n return packageJson.version;\n }\n const override = name === \"maxProtocolVersion\" ? legacyOverride : modernOverride;\n if (!override) {\n return packageJson.version;\n }\n\n this.resolvingPeerCeiling = true;\n try {\n return override.get ? override.get.call(this) : override.value;\n } finally {\n this.resolvingPeerCeiling = false;\n }\n }\n\n get maxProtocolVersion(): string {\n return this.resolvePeerCeiling(\"maxProtocolVersion\");\n }\n\n /**\n * @deprecated Use {@link maxProtocolVersion}. Same value, honest name: this\n * is the ceiling the PEER speaks, not which protocol this SDK implements —\n * that is the generated PROTOCOL_VERSION constant. Registered in the client\n * package's DEPRECATIONS.md; removal no earlier than 2.0.\n */\n get maxVersion(): string {\n if (!this.resolvingPeerCeiling && !warnedDeprecatedMaxVersion) {\n warnedDeprecatedMaxVersion = true;\n console.warn(\n \"[ag-ui] AbstractAgent.maxVersion is deprecated — use maxProtocolVersion. Same value; the new name says whose version it is and that it is a ceiling.\",\n );\n }\n return this.resolvePeerCeiling(\"maxVersion\");\n }\n\n get debug(): ResolvedAgentDebugConfig {\n return this._debug;\n }\n\n set debug(value: AgentDebugConfig | ResolvedAgentDebugConfig) {\n this._debug = resolveAgentDebugConfig(value as AgentDebugConfig);\n this._debugLogger = createDebugLogger(this._debug);\n }\n\n get debugLogger(): DebugLogger | undefined {\n return this._debugLogger;\n }\n\n set debugLogger(value: DebugLogger | boolean | undefined) {\n if (typeof value === \"boolean\") {\n this._debugLogger = value ? createDebugLogger(resolveAgentDebugConfig(true)) : undefined;\n } else {\n this._debugLogger = value;\n }\n }\n\n /**\n * The peer ceiling as the constructor's version gates need it: a string\n * compareVersions can actually read. A subclass getter is the only writer,\n * and it can answer with something unusable — most often `undefined`,\n * because class fields initialise after `super()` returns — so the value is\n * judged here rather than deep inside the comparison.\n */\n private resolvedCeilingDuringConstruction(): string {\n const ceiling: unknown = this.maxProtocolVersion;\n if (typeof ceiling !== \"string\" || !validateVersion(ceiling)) {\n throw new AGUIError(\n `maxProtocolVersion resolved to ${JSON.stringify(ceiling)} during construction, which is not a version this client can compare. A ceiling read from an instance field is not available yet — return a literal from the getter.`,\n );\n }\n return ceiling;\n }\n\n constructor({\n agentId,\n description,\n threadId,\n initialMessages,\n initialState,\n debug,\n }: AgentConfig = {}) {\n this.agentId = agentId;\n this.description = description ?? \"\";\n this.threadId = threadId ?? uuidv4();\n this.messages = structuredClone_(initialMessages ?? []);\n this.state = structuredClone_(initialState ?? {});\n this._debug = resolveAgentDebugConfig(debug);\n this._debugLogger = createDebugLogger(this._debug);\n\n // Resolved ONCE, and checked before it is compared. A subclass ceiling is\n // read through a getter, and this constructor runs before the subclass's\n // instance fields exist — so `get maxProtocolVersion() { return this.pin }`\n // hands back `undefined` here and compareVersions threw \"Invalid argument\n // expected string\", which named neither the getter nor the field.\n const peerCeiling = this.resolvedCeilingDuringConstruction();\n\n if (compareVersions(peerCeiling, \"0.0.39\") <= 0) {\n this.middlewares.unshift(new BackwardCompatibility_0_0_39());\n }\n\n // Auto-insert BackwardCompatibility_0_0_45 for backward compatibility with\n // the retired THINKING_* events. Registered in the repo-root\n // DEPRECATIONS.md (not this package's own, which tracks a different set\n // under a different schema) with an expiry of 2027-09-17, not removed in\n // 1.0 — see also the note on\n // CompatibilityBoundary, which translates the same shapes innermost and so\n // usually gets to them first.\n if (compareVersions(peerCeiling, \"0.0.45\") <= 0) {\n this.middlewares.unshift(new BackwardCompatibility_0_0_45());\n }\n\n // Auto-insert BackwardCompatibility_0_0_57 for backward compatibility with\n // pre-subagent agents: strips subagentRunId and drops SUBAGENT_* lifecycle events.\n if (compareVersions(peerCeiling, \"0.0.57\") <= 0) {\n this.middlewares.unshift(new BackwardCompatibility_0_0_57());\n }\n }\n\n public subscribe(subscriber: AgentSubscriber) {\n this.subscribers.push(subscriber);\n return {\n unsubscribe: () => {\n this.subscribers = this.subscribers.filter((s) => s !== subscriber);\n },\n };\n }\n\n abstract run(input: RunAgentInput): Observable<BaseEvent>;\n\n /**\n * Returns the agent's current capabilities.\n * Optional — subclasses implement this to advertise what they support.\n */\n getCapabilities?(): Promise<AgentCapabilities>;\n\n public use(...middlewares: (Middleware | MiddlewareFunction)[]): this {\n const normalizedMiddlewares = middlewares.map((middleware) =>\n typeof middleware === \"function\" ? new FunctionMiddleware(middleware) : middleware,\n );\n this.middlewares.push(...normalizedMiddlewares);\n return this;\n }\n\n public async runAgent(\n parameters?: RunAgentParameters,\n subscriber?: AgentSubscriber,\n ): Promise<RunAgentResult> {\n try {\n this.isRunning = true;\n this.agentId = this.agentId ?? uuidv4();\n const input = this.prepareRunAgentInput(parameters);\n\n this.debugLogger?.lifecycle(\"LIFECYCLE\", \"Run started:\", {\n agentId: this.agentId,\n threadId: this.threadId,\n });\n\n let result: unknown = undefined;\n const currentMessageIds = new Set(this.messages.map((message) => message.id));\n\n const subscribers: AgentSubscriber[] = [\n {\n onRunStartedEvent: ({ event }) => warnOnProducerDeclaration(event),\n onRunFinishedEvent: (params) => {\n if (params.outcome === \"success\") {\n result = params.result;\n }\n },\n },\n ...this.subscribers,\n subscriber ?? {},\n ];\n\n await this.onInitialize(input, subscribers);\n\n // Per-run detachment signal + completion promise\n this.activeRunDetach$ = new Subject<void>();\n let resolveActiveRunCompletion: (() => void) | undefined;\n this.activeRunCompletionPromise = new Promise<void>((resolve) => {\n resolveActiveRunCompletion = resolve;\n });\n\n const pipeline = pipe(\n () => {\n // Build middleware chain using reduceRight so middlewares can intercept runs.\n // The always-on inbound compatibility boundary runs innermost —\n // closest to the wire — so every other middleware and the\n // enforcement stage see 1.0-shaped events. Appended per run and\n // never stored, so it is installed exactly once regardless of\n // use() or clone().\n const chainedAgent = [...this.middlewares, new CompatibilityBoundary()].reduceRight(\n (nextAgent: AbstractAgent, middleware) =>\n ({\n run: (i: RunAgentInput) => middleware.run(i, nextAgent),\n get messages() {\n return nextAgent.messages;\n },\n get state() {\n return nextAgent.state;\n },\n }) as AbstractAgent,\n this, // Original agent is the final 'next'\n );\n\n return chainedAgent.run(input);\n },\n // Enforcement BEFORE expansion: a chunk is an event of its own, so it\n // is validated as one like any other, and expansion then only ever\n // reshapes values already known good. Expanding first handed this stage\n // repaired input — a malformed role arrived as \"assistant\" — so the\n // same defect was fatal when a producer sent it plainly and invisible\n // when it sent it as a chunk. Verification stays after expansion,\n // because what it checks (messages opening and closing, pairing) only\n // exists once the chunk has become a start and a content event.\n enforceEvents(this.debugLogger),\n transformChunks(this.debugLogger),\n verifyEvents(this.debugLogger),\n // Stop processing immediately when this run is detached\n (source$) => source$.pipe(takeUntil(this.activeRunDetach$!)),\n (source$) => this.apply(input, source$, subscribers),\n (source$) => this.processApplyEvents(input, source$, subscribers),\n catchError((error) => {\n this.debugLogger?.lifecycle(\"LIFECYCLE\", \"Run errored:\", {\n agentId: this.agentId,\n error: error instanceof Error ? error.message : String(error),\n });\n this.isRunning = false;\n return this.onError(input, error, subscribers);\n }),\n finalize(() => {\n this.debugLogger?.lifecycle(\"LIFECYCLE\", \"Run finished:\", {\n agentId: this.agentId,\n threadId: this.threadId,\n });\n this.isRunning = false;\n void this.onFinalize(input, subscribers);\n resolveActiveRunCompletion?.();\n resolveActiveRunCompletion = undefined;\n this.activeRunCompletionPromise = undefined;\n this.activeRunDetach$ = undefined;\n }),\n );\n\n await lastValueFrom(pipeline(of(null)));\n const newMessages = structuredClone_(this.messages).filter(\n (message: Message) => !currentMessageIds.has(message.id),\n );\n return { result, newMessages };\n } finally {\n this.isRunning = false;\n }\n }\n\n // `input` is part of the published signature: renaming it to `_input` changes\n // the emitted .d.ts that consumers see, so the directive goes here instead.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected connect(input: RunAgentInput): Observable<BaseEvent> {\n throw new AGUIConnectNotImplementedError();\n }\n public async connectAgent(\n parameters?: RunAgentParameters,\n subscriber?: AgentSubscriber,\n ): Promise<RunAgentResult> {\n try {\n this.isRunning = true;\n this.agentId = this.agentId ?? uuidv4();\n const input = this.prepareRunAgentInput(parameters);\n let result: unknown = undefined;\n const currentMessageIds = new Set(this.messages.map((message) => message.id));\n\n const subscribers: AgentSubscriber[] = [\n {\n onRunStartedEvent: ({ event }) => warnOnProducerDeclaration(event),\n onRunFinishedEvent: (params) => {\n if (params.outcome === \"success\") {\n result = params.result;\n }\n },\n },\n ...this.subscribers,\n subscriber ?? {},\n ];\n\n await this.onInitialize(input, subscribers);\n\n // Per-run detachment signal + completion promise\n this.activeRunDetach$ = new Subject<void>();\n let resolveActiveRunCompletion: (() => void) | undefined;\n this.activeRunCompletionPromise = new Promise<void>((resolve) => {\n resolveActiveRunCompletion = resolve;\n });\n\n const pipeline = pipe(\n () => defer(() => this.connect(input)),\n // The connect flow has no middleware chain, so the always-on inbound\n // boundary applies as a plain operator here (composed with enforcement:\n // rxjs pipe() runs out of typed arities beyond nine stages).\n (source$: Observable<BaseEvent>) =>\n enforceEvents(this.debugLogger)(compatibilityBoundaryOperator()(source$)),\n transformChunks(this.debugLogger),\n verifyEvents(this.debugLogger),\n // Stop processing immediately when this run is detached\n (source$) => source$.pipe(takeUntil(this.activeRunDetach$!)),\n (source$) => this.apply(input, source$, subscribers),\n (source$) => this.processApplyEvents(input, source$, subscribers),\n catchError((error) => {\n this.isRunning = false;\n if (!(error instanceof AGUIConnectNotImplementedError)) {\n return this.onError(input, error, subscribers);\n }\n return EMPTY;\n }),\n finalize(() => {\n this.isRunning = false;\n void this.onFinalize(input, subscribers);\n resolveActiveRunCompletion?.();\n resolveActiveRunCompletion = undefined;\n this.activeRunCompletionPromise = undefined;\n this.activeRunDetach$ = undefined;\n }),\n );\n\n // defaultValue prevents EmptyError when catchError returns EMPTY\n // (e.g. ConnectNotImplementedError path)\n await lastValueFrom(pipeline(of(null)), { defaultValue: undefined });\n const newMessages = structuredClone_(this.messages).filter(\n (message: Message) => !currentMessageIds.has(message.id),\n );\n return { result, newMessages };\n } finally {\n this.isRunning = false;\n }\n }\n\n public abortRun() {}\n\n public async detachActiveRun(): Promise<void> {\n if (!this.activeRunDetach$) {\n return;\n }\n const completion = this.activeRunCompletionPromise ?? Promise.resolve();\n this.activeRunDetach$.next();\n this.activeRunDetach$?.complete();\n await completion;\n }\n\n protected apply(\n input: RunAgentInput,\n events$: Observable<BaseEvent>,\n subscribers: AgentSubscriber[],\n ): Observable<AgentStateMutation> {\n return defaultApplyEvents(input, events$, this, subscribers, this.debugLogger);\n }\n\n protected processApplyEvents(\n input: RunAgentInput,\n events$: Observable<AgentStateMutation>,\n subscribers: AgentSubscriber[],\n ): Observable<AgentStateMutation> {\n return events$.pipe(\n tap((event) => {\n if (event.messages) {\n this.messages = event.messages;\n subscribers.forEach((subscriber) => {\n subscriber.onMessagesChanged?.({\n messages: this.messages,\n state: this.state,\n agent: this,\n input,\n });\n });\n }\n // `!== undefined`, not truthiness: State is any JSON value, so a\n // snapshot of `null`, `0`, `\"\"` or `false` is a replacement like any\n // other. The mutation channel only carries `state` when a stage\n // actually set it, so presence is the signal — a truthiness check\n // silently discarded every falsy replacement.\n if (event.state !== undefined) {\n this.state = event.state;\n subscribers.forEach((subscriber) => {\n subscriber.onStateChanged?.({\n state: this.state,\n messages: this.messages,\n agent: this,\n input,\n });\n });\n }\n }),\n );\n }\n\n protected prepareRunAgentInput(parameters?: RunAgentParameters): RunAgentInput {\n const clonedMessages = structuredClone_(this.messages) as Message[];\n // Egress chokepoint for the no-null rule on attribution (PNI-199 alignment):\n // the verifier and reducer keep event-derived state clean, but messages also\n // enter through the constructor's initialMessages and subscriber mutations,\n // neither of which is schema-checked. A null tag must never be serialized\n // onto the wire — the schemas forbid it, so a receiving agent would reject\n // the whole run. Absent is the only spelling.\n for (const message of clonedMessages) {\n if ((message as { subagentRunId?: string | null }).subagentRunId === null) {\n delete (message as { subagentRunId?: string | null }).subagentRunId;\n }\n }\n const messagesWithoutActivity = clonedMessages.filter((message) => message.role !== \"activity\");\n\n return {\n threadId: this.threadId,\n runId: parameters?.runId || uuidv4(),\n // Declared only when the peer's ceiling is not pinned below this\n // client: a downgraded peer predates the field, and an unknown input\n // member is exactly what a strict old parser could reject.\n ...(compareVersions(this.maxProtocolVersion, packageJson.version) >= 0 && {\n protocolVersion: PROTOCOL_VERSION,\n }),\n tools: structuredClone_(parameters?.tools ?? []),\n context: structuredClone_(parameters?.context ?? []),\n forwardedProps: structuredClone_(parameters?.forwardedProps ?? {}),\n state: structuredClone_(this.state),\n messages: messagesWithoutActivity,\n ...(parameters?.resume !== undefined ? { resume: structuredClone_(parameters.resume) } : {}),\n };\n }\n\n protected async onInitialize(input: RunAgentInput, subscribers: AgentSubscriber[]) {\n if (this.pendingInterrupts.length > 0) {\n const resumeIds = new Set((input.resume ?? []).map((r) => r.interruptId));\n const uncovered = this.pendingInterrupts.map((i) => i.id).filter((id) => !resumeIds.has(id));\n if (uncovered.length > 0) {\n throw new AGUIError(\n `Thread has ${uncovered.length} pending interrupt(s) not addressed by resume: ${uncovered.join(\", \")}`,\n );\n }\n for (const i of this.pendingInterrupts) {\n if (!isInterruptExpired(i)) continue;\n // Expiry forecloses ANSWERING, not resolving the thread: a cancelled\n // entry is the conforming way past an interrupt nobody answered in\n // time. Throwing on mere presence — which this once did — made an\n // expired interrupt block its thread forever, since coverage is\n // mandatory and no entry could ever satisfy this check.\n const entry = (input.resume ?? []).find((r) => r.interruptId === i.id);\n if (entry?.status !== \"cancelled\") {\n throw new AGUIError(\n `Interrupt ${i.id} expired at ${i.expiresAt} and can no longer be answered. Cancel it to continue the thread.`,\n );\n }\n }\n }\n\n const onRunInitializedMutation = await runSubscribersWithMutation(\n subscribers,\n this.messages,\n this.state,\n (subscriber, messages, state) =>\n subscriber.onRunInitialized?.({ messages, state, agent: this, input }),\n );\n if (\n onRunInitializedMutation.messages !== undefined ||\n onRunInitializedMutation.state !== undefined\n ) {\n if (onRunInitializedMutation.messages) {\n this.messages = onRunInitializedMutation.messages;\n // This assignment lands AFTER prepareRunAgentInput sanitized the input,\n // so the no-null rule must be re-applied here — a subscriber mutation is\n // the one writer that can still put a null tag on the wire.\n for (const message of onRunInitializedMutation.messages) {\n if ((message as { subagentRunId?: string | null }).subagentRunId === null) {\n delete (message as { subagentRunId?: string | null }).subagentRunId;\n }\n }\n // The activity filter from prepareRunAgentInput has to be re-applied\n // for the same reason the null-tag sanitisation above does: this\n // assignment lands AFTER that filter ran, and a subscriber replacing\n // the message list is the one writer that can still put an activity\n // message — the consumer's own display state, which no producer owns —\n // onto the wire. The AGENT keeps it; only the input copy is filtered.\n input.messages = onRunInitializedMutation.messages.filter(\n (message) => message.role !== \"activity\",\n );\n subscribers.forEach((subscriber) => {\n subscriber.onMessagesChanged?.({\n messages: this.messages,\n state: this.state,\n agent: this,\n input,\n });\n });\n }\n // `!== undefined`, as in apply(): a subscriber may legitimately set a\n // falsy state, and the mutation only carries the key when it did.\n if (onRunInitializedMutation.state !== undefined) {\n this.state = onRunInitializedMutation.state;\n input.state = onRunInitializedMutation.state;\n subscribers.forEach((subscriber) => {\n subscriber.onStateChanged?.({\n state: this.state,\n messages: this.messages,\n agent: this,\n input,\n });\n });\n }\n }\n }\n\n protected onError(input: RunAgentInput, error: Error, subscribers: AgentSubscriber[]) {\n return from(\n runSubscribersWithMutation(\n subscribers,\n this.messages,\n this.state,\n (subscriber, messages, state) =>\n subscriber.onRunFailed?.({ error, messages, state, agent: this, input }),\n ),\n ).pipe(\n map((onRunFailedMutation) => {\n const mutation = onRunFailedMutation as AgentStateMutation;\n if (mutation.messages !== undefined || mutation.state !== undefined) {\n if (mutation.messages !== undefined) {\n this.messages = mutation.messages;\n subscribers.forEach((subscriber) => {\n subscriber.onMessagesChanged?.({\n messages: this.messages,\n state: this.state,\n agent: this,\n input,\n });\n });\n }\n if (mutation.state !== undefined) {\n this.state = mutation.state;\n subscribers.forEach((subscriber) => {\n subscriber.onStateChanged?.({\n state: this.state,\n messages: this.messages,\n agent: this,\n input,\n });\n });\n }\n }\n\n if (mutation.stopPropagation !== true) {\n // Silently ignore abort errors (e.g. from navigation during active requests).\n // AbortController.abort(reason) can produce:\n // - A DOMException with name \"AbortError\"\n // - The reason value itself as a plain string (e.g. \"component unmounted\")\n const errStr = String(error);\n const isAbort =\n error.name === \"AbortError\" ||\n error.message === \"Fetch is aborted\" ||\n error.message === \"signal is aborted without reason\" ||\n error.message === \"component unmounted\" ||\n errStr === \"component unmounted\";\n if (!isAbort) {\n console.error(\"Agent execution failed:\", error);\n throw error;\n }\n }\n\n // Return an empty mutation instead of null to prevent EmptyError\n return {} as AgentStateMutation;\n }),\n );\n }\n\n protected async onFinalize(input: RunAgentInput, subscribers: AgentSubscriber[]) {\n const onRunFinalizedMutation = await runSubscribersWithMutation(\n subscribers,\n this.messages,\n this.state,\n (subscriber, messages, state) =>\n subscriber.onRunFinalized?.({ messages, state, agent: this, input }),\n );\n\n if (\n onRunFinalizedMutation.messages !== undefined ||\n onRunFinalizedMutation.state !== undefined\n ) {\n if (onRunFinalizedMutation.messages !== undefined) {\n this.messages = onRunFinalizedMutation.messages;\n subscribers.forEach((subscriber) => {\n subscriber.onMessagesChanged?.({\n messages: this.messages,\n state: this.state,\n agent: this,\n input,\n });\n });\n }\n if (onRunFinalizedMutation.state !== undefined) {\n this.state = onRunFinalizedMutation.state;\n subscribers.forEach((subscriber) => {\n subscriber.onStateChanged?.({\n state: this.state,\n messages: this.messages,\n agent: this,\n input,\n });\n });\n }\n }\n }\n\n public clone() {\n const cloned = Object.create(Object.getPrototypeOf(this));\n\n cloned.agentId = this.agentId;\n cloned.description = this.description;\n cloned.threadId = this.threadId;\n cloned.messages = structuredClone_(this.messages);\n cloned.state = structuredClone_(this.state);\n cloned._debug = this._debug;\n cloned._debugLogger = this._debugLogger;\n cloned.isRunning = this.isRunning;\n cloned.subscribers = [...this.subscribers];\n cloned.middlewares = [...this.middlewares];\n cloned.pendingInterrupts = structuredClone_(this.pendingInterrupts);\n\n return cloned;\n }\n\n public addMessage(message: Message) {\n // Add message to the messages array\n this.messages.push(message);\n\n // Notify subscribers sequentially in the background\n (async () => {\n // Fire onNewMessage sequentially\n for (const subscriber of this.subscribers) {\n await subscriber.onNewMessage?.({\n message,\n messages: this.messages,\n state: this.state,\n agent: this,\n });\n }\n\n // Fire onNewToolCall if the message is from assistant and contains tool calls\n if (message.role === \"assistant\" && message.toolCalls) {\n for (const toolCall of message.toolCalls) {\n for (const subscriber of this.subscribers) {\n await subscriber.onNewToolCall?.({\n toolCall,\n messages: this.messages,\n state: this.state,\n agent: this,\n });\n }\n }\n }\n\n // Fire onMessagesChanged sequentially\n for (const subscriber of this.subscribers) {\n await subscriber.onMessagesChanged?.({\n messages: this.messages,\n state: this.state,\n agent: this,\n });\n }\n })();\n }\n\n public addMessages(messages: Message[]) {\n // Add all messages to the messages array\n this.messages.push(...messages);\n\n // Notify subscribers sequentially in the background\n (async () => {\n // Fire onNewMessage and onNewToolCall for each message sequentially\n for (const message of messages) {\n // Fire onNewMessage sequentially\n for (const subscriber of this.subscribers) {\n await subscriber.onNewMessage?.({\n message,\n messages: this.messages,\n state: this.state,\n agent: this,\n });\n }\n\n // Fire onNewToolCall if the message is from assistant and contains tool calls\n if (message.role === \"assistant\" && message.toolCalls) {\n for (const toolCall of message.toolCalls) {\n for (const subscriber of this.subscribers) {\n await subscriber.onNewToolCall?.({\n toolCall,\n messages: this.messages,\n state: this.state,\n agent: this,\n });\n }\n }\n }\n }\n\n // Fire onMessagesChanged once at the end sequentially\n for (const subscriber of this.subscribers) {\n await subscriber.onMessagesChanged?.({\n messages: this.messages,\n state: this.state,\n agent: this,\n });\n }\n })();\n }\n\n public setMessages(messages: Message[]) {\n // Replace the entire messages array\n this.messages = structuredClone_(messages);\n\n // Notify subscribers sequentially in the background\n (async () => {\n // Fire onMessagesChanged sequentially\n for (const subscriber of this.subscribers) {\n await subscriber.onMessagesChanged?.({\n messages: this.messages,\n state: this.state,\n agent: this,\n });\n }\n })();\n }\n\n public setState(state: State) {\n // Replace the entire state\n this.state = structuredClone_(state);\n\n // Notify subscribers sequentially in the background\n (async () => {\n // Fire onStateChanged sequentially\n for (const subscriber of this.subscribers) {\n await subscriber.onStateChanged?.({\n messages: this.messages,\n state: this.state,\n agent: this,\n });\n }\n })();\n }\n\n public legacy_to_be_removed_runAgentBridged(\n config?: RunAgentParameters,\n ): Observable<LegacyRuntimeProtocolEvent> {\n this.agentId = this.agentId ?? uuidv4();\n const input = this.prepareRunAgentInput(config);\n\n // Build middleware chain for legacy bridge\n const runObservable = (() => {\n const chainedAgent = [...this.middlewares, new CompatibilityBoundary()].reduceRight(\n (nextAgent: AbstractAgent, middleware) =>\n ({\n run: (i: RunAgentInput) => middleware.run(i, nextAgent),\n get messages() {\n return nextAgent.messages;\n },\n get state() {\n return nextAgent.state;\n },\n }) as AbstractAgent,\n this,\n );\n\n return chainedAgent.run(input);\n })();\n\n return runObservable.pipe(\n enforceEvents(this.debugLogger),\n transformChunks(this.debugLogger),\n verifyEvents(this.debugLogger),\n convertToLegacyEvents(this.threadId, input.runId, this.agentId),\n (events$: Observable<LegacyRuntimeProtocolEvent>) => {\n return events$.pipe(\n map((event) => {\n this.debugLogger?.event(\"LEGACY\", \"Event:\", event, { type: event.type });\n return event;\n }),\n );\n },\n );\n }\n}\n","import { AbstractAgent, RunAgentResult } from \"./agent\";\nimport { runHttpRequest } from \"@/run/http-request\";\nimport { enforceOutgoingInput } from \"@/enforce\";\nimport { HttpAgentConfig, HttpAgentFetchFn, RunAgentParameters } from \"./types\";\nimport { RunAgentInput, BaseEvent } from \"@ag-ui/core\";\nimport { structuredClone_ } from \"@/utils\";\nimport { transformHttpEventStream } from \"@/transform/http\";\nimport { Observable } from \"rxjs\";\nimport { AgentSubscriber } from \"./subscriber\";\n\ninterface RunHttpAgentConfig extends RunAgentParameters {\n abortController?: AbortController;\n}\n\n/**\n * The TERMINAL egress guard for the no-null attribution rule (PNI-199\n * alignment). prepareRunAgentInput sanitizes what it assembles, but middlewares\n * and in-place onRunInitialized mutations write to the input AFTER it — this is\n * the last point before the bytes leave, so it is where the rule must hold. A\n * null tag on the wire is schema-invalid and kills the whole run on the\n * receiving side; absent is the only spelling. Non-mutating: messages are\n * shallow-copied only when a strip is needed.\n */\nfunction sanitizeOutgoingInput(input: RunAgentInput): RunAgentInput {\n if (!Array.isArray(input.messages)) return input;\n let changed = false;\n const messages = input.messages.map((message) => {\n if ((message as { subagentRunId?: string | null }).subagentRunId === null) {\n changed = true;\n // Spread + delete rather than rest-destructuring: Message is a union, and\n // rest types may only be created from object types under tsc.\n const copy = { ...message } as typeof message & { subagentRunId?: string | null };\n delete copy.subagentRunId;\n return copy as typeof message;\n }\n return message;\n });\n return changed ? { ...input, messages } : input;\n}\n\nexport class HttpAgent extends AbstractAgent {\n public url: string;\n public headers: Record<string, string>;\n public fetch: HttpAgentFetchFn;\n public abortController: AbortController = new AbortController();\n\n /**\n * Returns the fetch config for the http request.\n * Override this to customize the request.\n *\n * @returns The fetch config for the http request.\n */\n protected requestInit(input: RunAgentInput): RequestInit {\n return {\n method: \"POST\",\n headers: {\n ...this.headers,\n \"Content-Type\": \"application/json\",\n Accept: \"text/event-stream\",\n },\n body: JSON.stringify(sanitizeOutgoingInput(input)),\n signal: this.abortController.signal,\n };\n }\n\n public runAgent(\n parameters?: RunHttpAgentConfig,\n subscriber?: AgentSubscriber,\n ): Promise<RunAgentResult> {\n this.abortController = parameters?.abortController ?? new AbortController();\n return super.runAgent(parameters, subscriber);\n }\n\n abortRun() {\n this.abortController.abort();\n super.abortRun();\n }\n\n constructor(config: HttpAgentConfig) {\n super(config);\n this.url = config.url;\n this.headers = structuredClone_(config.headers ?? {});\n // Bind the default fetch to the global object. Storing the bare `fetch`\n // and later invoking it as `this.fetch(...)` sets the receiver to the agent\n // instance; a browser's native fetch is a checked-receiver method and throws\n // \"Illegal invocation\" when not called with `window` as `this`. (Node's fetch\n // tolerates any receiver, so this only surfaces in the browser.)\n this.fetch = config.fetch ?? ((url, requestInit) => fetch(url, requestInit));\n }\n\n run(input: RunAgentInput): Observable<BaseEvent> {\n // The outgoing half of the enforcement boundary: checked immediately\n // before transmission. Inside the deferred request thunk — not during\n // pipeline construction, where a throw would escape the run's catchError\n // and leave lifecycle callbacks and the completion promise hanging — and\n // before requestInit, so a subclass overriding the request shape still\n // transmits enforced input. Unknown material is stripped with a warning;\n // a malformed known field fails the run before a byte leaves the process.\n const httpEvents = runHttpRequest(() =>\n this.fetch(this.url, this.requestInit(enforceOutgoingInput(input))),\n );\n return transformHttpEventStream(httpEvents, this.debugLogger);\n }\n\n public clone(): HttpAgent {\n const cloned = super.clone() as HttpAgent;\n cloned.url = this.url;\n cloned.headers = structuredClone_(this.headers ?? {});\n cloned.fetch = this.fetch;\n\n const newController = new AbortController();\n const originalSignal = this.abortController.signal as AbortSignal & { reason?: unknown };\n if (originalSignal.aborted) {\n newController.abort(originalSignal.reason);\n }\n cloned.abortController = newController;\n\n return cloned;\n }\n}\n","import {\n BaseEvent,\n EventType,\n type Metadata,\n mergeMetadata,\n TextMessageStartEvent,\n TextMessageContentEvent,\n TextMessageEndEvent,\n ToolCallStartEvent,\n ToolCallArgsEvent,\n ToolCallEndEvent,\n StateSnapshotEvent,\n StateDeltaEvent,\n} from \"@ag-ui/core\";\nimport jsonpatch from \"fast-json-patch\";\nimport { structuredClone_ } from \"../utils\";\n\n/**\n * Folds the metadata of a run of events being replaced by one synthesized\n * event, so compacting a stream does not change the metadata a consumer ends up\n * with. Same last-write-wins, replace-wholesale rule the reducer applies, which\n * is what makes a compacted replay agree with the original stream.\n *\n * Ordering note. Compaction deliberately reorders events to keep each stream's\n * events together: a buffer flushes when its END arrives, and any non-streaming\n * event that arrived mid-stream is emitted after it.\n *\n * That reordering is not semantics-preserving in general, and this predates\n * metadata. A MESSAGES_SNAPSHOT interrupting a text stream is emitted after the\n * stream's own events, so on replay it overwrites what they produced — the\n * appended content as much as the merged metadata.\n *\n * What metadata does not add is any *new* order sensitivity. Every merge\n * destination is unique — each message has its own, and each tool call carries\n * its own rather than folding into the parent it may share — so two events that\n * merge into the same target are never reordered relative to each other.\n * Ordering within a buffer is preserved as well; see `postStartMetadata`, which\n * keeps deltas and replayed starts in arrival order.\n */\nfunction carryStartMetadata<T extends BaseEvent>(previous: T | undefined, next: T): T {\n if (previous === undefined) {\n return next;\n }\n\n // A start event can be replayed before its end — the HITL re-sync path does\n // this, which is why the reducer's start handling is idempotent. Uncompacted,\n // both starts merge into the message; keep that true after compaction instead\n // of letting the later start silently replace the earlier one's keys.\n const metadata = mergeMetadata(previous.metadata, next.metadata);\n return metadata === undefined ? next : { ...next, metadata };\n}\n\n/**\n * Applies a start replayed *after* deltas have been buffered.\n *\n * Its non-metadata fields win — the reducer deliberately renames an existing\n * tool call on such a replay, so dropping them would make a compacted replay\n * disagree. Its metadata does not ride the start, because compaction emits the\n * start ahead of the collapsed delta event; the caller stages that separately so\n * arrival order is preserved.\n */\nfunction replaceStartFields<T extends BaseEvent>(previous: T | undefined, next: T): T {\n const { metadata: _replayMetadata, ...fields } = next as T & { metadata?: Metadata };\n const carried = previous?.metadata;\n return (carried === undefined ? fields : { ...fields, metadata: carried }) as T;\n}\n\nfunction collapseMetadata(events: BaseEvent[]): Metadata | undefined {\n let merged: Metadata | undefined;\n for (const event of events) {\n merged = mergeMetadata(merged, event.metadata);\n }\n return merged;\n}\n\n/**\n * Compacts streaming events by consolidating multiple deltas into single events.\n * For text messages: multiple content deltas become one concatenated delta.\n * For tool calls: multiple args deltas become one concatenated delta.\n * For state: all STATE_SNAPSHOT and STATE_DELTA events within a run are compacted\n * into a single STATE_SNAPSHOT representing the final state.\n * Events between related streaming events are reordered to keep streaming events together.\n *\n * @param events - Array of events to compact\n * @returns Compacted array of events\n */\nexport function compactEvents(events: BaseEvent[]): BaseEvent[] {\n const compacted: BaseEvent[] = [];\n const pendingTextMessages = new Map<\n string,\n {\n start?: TextMessageStartEvent;\n contents: TextMessageContentEvent[];\n end?: TextMessageEndEvent;\n otherEvents: BaseEvent[];\n postStartMetadata?: Metadata;\n }\n >();\n const pendingToolCalls = new Map<\n string,\n {\n start?: ToolCallStartEvent;\n args: ToolCallArgsEvent[];\n end?: ToolCallEndEvent;\n otherEvents: BaseEvent[];\n postStartMetadata?: Metadata;\n }\n >();\n\n // State compaction: collects state events, flushed at RUN_STARTED (pre-run/inter-run), RUN_FINISHED/RUN_ERROR (in-run), and at end (trailing)\n let stateEvents: (StateSnapshotEvent | StateDeltaEvent)[] = [];\n\n for (const event of events) {\n // Handle text message streaming events\n if (event.type === EventType.TEXT_MESSAGE_START) {\n const startEvent = event as TextMessageStartEvent;\n const messageId = startEvent.messageId;\n\n if (!pendingTextMessages.has(messageId)) {\n pendingTextMessages.set(messageId, {\n contents: [],\n otherEvents: [],\n });\n }\n\n const pending = pendingTextMessages.get(messageId)!;\n if (pending.contents.length === 0) {\n pending.start = carryStartMetadata(pending.start, startEvent);\n } else {\n // Compaction hoists START ahead of the collapsed delta event, so a start\n // replayed after deltas keeps its fields but stages its metadata.\n pending.start = replaceStartFields(pending.start, startEvent);\n pending.postStartMetadata = mergeMetadata(pending.postStartMetadata, startEvent.metadata);\n }\n } else if (event.type === EventType.TEXT_MESSAGE_CONTENT) {\n const contentEvent = event as TextMessageContentEvent;\n const messageId = contentEvent.messageId;\n\n if (!pendingTextMessages.has(messageId)) {\n pendingTextMessages.set(messageId, {\n contents: [],\n otherEvents: [],\n });\n }\n\n const pending = pendingTextMessages.get(messageId)!;\n pending.contents.push(contentEvent);\n pending.postStartMetadata = mergeMetadata(pending.postStartMetadata, contentEvent.metadata);\n } else if (event.type === EventType.TEXT_MESSAGE_END) {\n const endEvent = event as TextMessageEndEvent;\n const messageId = endEvent.messageId;\n\n if (!pendingTextMessages.has(messageId)) {\n pendingTextMessages.set(messageId, {\n contents: [],\n otherEvents: [],\n });\n }\n\n const pending = pendingTextMessages.get(messageId)!;\n pending.end = endEvent;\n\n // Flush this message's events\n flushTextMessage(messageId, pending, compacted);\n pendingTextMessages.delete(messageId);\n } else if (event.type === EventType.TOOL_CALL_START) {\n const startEvent = event as ToolCallStartEvent;\n const toolCallId = startEvent.toolCallId;\n\n if (!pendingToolCalls.has(toolCallId)) {\n pendingToolCalls.set(toolCallId, {\n args: [],\n otherEvents: [],\n });\n }\n\n const pending = pendingToolCalls.get(toolCallId)!;\n if (pending.args.length === 0) {\n pending.start = carryStartMetadata(pending.start, startEvent);\n } else {\n // Same ordering rule as the text case above.\n pending.start = replaceStartFields(pending.start, startEvent);\n pending.postStartMetadata = mergeMetadata(pending.postStartMetadata, startEvent.metadata);\n }\n } else if (event.type === EventType.TOOL_CALL_ARGS) {\n const argsEvent = event as ToolCallArgsEvent;\n const toolCallId = argsEvent.toolCallId;\n\n if (!pendingToolCalls.has(toolCallId)) {\n pendingToolCalls.set(toolCallId, {\n args: [],\n otherEvents: [],\n });\n }\n\n const pending = pendingToolCalls.get(toolCallId)!;\n pending.args.push(argsEvent);\n pending.postStartMetadata = mergeMetadata(pending.postStartMetadata, argsEvent.metadata);\n } else if (event.type === EventType.TOOL_CALL_END) {\n const endEvent = event as ToolCallEndEvent;\n const toolCallId = endEvent.toolCallId;\n\n if (!pendingToolCalls.has(toolCallId)) {\n pendingToolCalls.set(toolCallId, {\n args: [],\n otherEvents: [],\n });\n }\n\n const pending = pendingToolCalls.get(toolCallId)!;\n pending.end = endEvent;\n\n // Flush this tool call's events\n flushToolCall(toolCallId, pending, compacted);\n pendingToolCalls.delete(toolCallId);\n } else if (event.type === EventType.RUN_STARTED) {\n // Flush any pre-run state events before starting a new run\n flushState(stateEvents, compacted);\n stateEvents = [];\n compacted.push(event);\n } else if (event.type === EventType.RUN_FINISHED || event.type === EventType.RUN_ERROR) {\n // Flush compacted state into output before the run boundary event\n flushState(stateEvents, compacted);\n stateEvents = [];\n compacted.push(event);\n } else if (event.type === EventType.STATE_SNAPSHOT || event.type === EventType.STATE_DELTA) {\n // Collect state events for compaction\n stateEvents.push(event as StateSnapshotEvent | StateDeltaEvent);\n } else {\n // For non-streaming events, check if we're in the middle of any streaming sequences\n let addedToBuffer = false;\n\n // Check text messages\n for (const [, pending] of pendingTextMessages) {\n // If we have a start but no end yet, this event is \"in between\"\n if (pending.start && !pending.end) {\n pending.otherEvents.push(event);\n addedToBuffer = true;\n break;\n }\n }\n\n // Check tool calls if not already buffered\n if (!addedToBuffer) {\n for (const [, pending] of pendingToolCalls) {\n // If we have a start but no end yet, this event is \"in between\"\n if (pending.start && !pending.end) {\n pending.otherEvents.push(event);\n addedToBuffer = true;\n break;\n }\n }\n }\n\n // If not in the middle of any streaming sequence, add directly to compacted\n if (!addedToBuffer) {\n compacted.push(event);\n }\n }\n }\n\n // Flush any remaining incomplete messages\n for (const [messageId, pending] of pendingTextMessages) {\n flushTextMessage(messageId, pending, compacted);\n }\n\n // Flush any remaining incomplete tool calls\n for (const [toolCallId, pending] of pendingToolCalls) {\n flushToolCall(toolCallId, pending, compacted);\n }\n\n // Flush any remaining state events (incomplete run or events outside runs)\n flushState(stateEvents, compacted);\n\n return compacted;\n}\n\nfunction flushTextMessage(\n messageId: string,\n pending: {\n start?: TextMessageStartEvent;\n contents: TextMessageContentEvent[];\n end?: TextMessageEndEvent;\n otherEvents: BaseEvent[];\n postStartMetadata?: Metadata;\n },\n compacted: BaseEvent[],\n): void {\n // Add start event if present\n if (pending.start) {\n compacted.push(pending.start);\n }\n\n // Compact all content events into one\n if (pending.contents.length > 0) {\n const concatenatedDelta = pending.contents.map((c) => c.delta).join(\"\");\n\n const collapsedMetadata = pending.postStartMetadata;\n\n const compactedContent: TextMessageContentEvent = {\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId: messageId,\n delta: concatenatedDelta,\n ...(collapsedMetadata !== undefined && { metadata: collapsedMetadata }),\n };\n\n compacted.push(compactedContent);\n }\n\n // Add end event if present\n if (pending.end) {\n compacted.push(pending.end);\n }\n\n // Add any events that were in between\n for (const otherEvent of pending.otherEvents) {\n compacted.push(otherEvent);\n }\n}\n\nfunction flushToolCall(\n toolCallId: string,\n pending: {\n start?: ToolCallStartEvent;\n args: ToolCallArgsEvent[];\n end?: ToolCallEndEvent;\n otherEvents: BaseEvent[];\n postStartMetadata?: Metadata;\n },\n compacted: BaseEvent[],\n): void {\n // Add start event if present\n if (pending.start) {\n compacted.push(pending.start);\n }\n\n // Compact all args events into one\n if (pending.args.length > 0) {\n const concatenatedArgs = pending.args.map((a) => a.delta).join(\"\");\n\n const collapsedMetadata = pending.postStartMetadata;\n\n const compactedArgs: ToolCallArgsEvent = {\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: toolCallId,\n delta: concatenatedArgs,\n ...(collapsedMetadata !== undefined && { metadata: collapsedMetadata }),\n };\n\n compacted.push(compactedArgs);\n }\n\n // Add end event if present\n if (pending.end) {\n compacted.push(pending.end);\n }\n\n // Add any events that were in between\n for (const otherEvent of pending.otherEvents) {\n compacted.push(otherEvent);\n }\n}\n\n/**\n * Compaction's warnings, behind the same switch as the rest of the package.\n * `SUPPRESS_TRANSFORMATION_WARNINGS` is the one control an operator has over\n * transformation chatter (enforce.ts, transform/proto.ts and the compatibility\n * middlewares all honour it); a warning that ignored it was unsilenceable.\n */\nconst warnCompact = (message: string): void => {\n if (\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n Boolean(process.env.SUPPRESS_TRANSFORMATION_WARNINGS)\n ) {\n return;\n }\n console.warn(message);\n};\n\nfunction flushState(\n stateEvents: (StateSnapshotEvent | StateDeltaEvent)[],\n compacted: BaseEvent[],\n): void {\n if (stateEvents.length === 0) {\n return;\n }\n\n // A window with no SNAPSHOT in it cannot be collapsed into one. Collapsing\n // `SNAPSHOT + deltas` is sound because the snapshot states the whole\n // document and the deltas refine it. Deltas ALONE are relative to a state\n // this window never saw, so seeding `{}` and calling the result a snapshot\n // manufactures an authoritative claim that everything else was absent —\n // replaying it wipes state the consumer legitimately holds from before the\n // window. Passed through unchanged instead: two deltas are barely worth\n // collapsing anyway, and correctness is not negotiable for the saving.\n // The LAST snapshot, not merely \"is there one\": everything before it is\n // unobservable by definition, because a snapshot restates the whole document\n // and replaces whatever the deltas ahead of it had built. Folding those\n // deltas anyway applied them to the seeded `{}`, where their paths do not\n // resolve — `applyPatch` validates, so it threw, and the catch below warned\n // about a patch whose failure changed nothing. Right answer, wrong\n // diagnosis. Starting at the last snapshot means the catch only ever fires\n // for a patch that genuinely could not be applied to the state it names.\n //\n // A reverse loop rather than `findLastIndex`: this package targets es2017,\n // and the method is ES2023.\n let lastSnapshot = -1;\n for (let index = stateEvents.length - 1; index >= 0; index--) {\n if (stateEvents[index].type === EventType.STATE_SNAPSHOT) {\n lastSnapshot = index;\n break;\n }\n }\n if (lastSnapshot === -1) {\n compacted.push(...stateEvents);\n return;\n }\n\n // From here the window DOES contain a snapshot, so it collapses exactly as\n // it always has: seeding `{}` is harmless because the snapshot replaces the\n // document wholesale before anything relative is applied to it.\n let state: Record<string, unknown> = {};\n\n for (const event of stateEvents.slice(lastSnapshot)) {\n if (event.type === EventType.STATE_SNAPSHOT) {\n state = structuredClone_(event.snapshot);\n } else {\n // Uncaught, a single unappliable patch took down every consumer that\n // compacts a stream — `applyPatch` validates, so it THROWS rather than\n // answering falsy. Warned and skipped, matching the reducer in\n // apply/default.ts, which faces exactly the same failure.\n try {\n state = jsonpatch.applyPatch(state, structuredClone_(event.delta), true, false)\n .newDocument;\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n warnCompact(\n `[ag-ui][compact] Failed to apply state patch while compacting:\\nCurrent state: ${JSON.stringify(state, null, 2)}\\nPatch operations: ${JSON.stringify(event.delta, null, 2)}\\nError: ${errorMessage}`,\n );\n }\n }\n }\n\n const collapsedMetadata = collapseMetadata(stateEvents);\n\n const compactedSnapshot: StateSnapshotEvent = {\n type: EventType.STATE_SNAPSHOT,\n snapshot: state,\n ...(collapsedMetadata !== undefined && { metadata: collapsedMetadata }),\n };\n\n compacted.push(compactedSnapshot);\n}\n"],"mappings":"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"}