{"version":3,"sources":["../src/agent-core.ts"],"sourcesContent":["/**\n * Copyright 2026 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Transport-agnostic agent client core.\n *\n * This module is browser-safe: it has **no** runtime dependency on the rest of\n * `@genkit-ai/ai` (it only imports types, which are erased at compile time) and\n * no Node-specific APIs. Both the in-process server agent (`ai.defineAgent`)\n * and the HTTP `remoteAgent` client compose the same {@link AgentChatImpl} /\n * {@link createAgentAPI} core over a transport that implements\n * {@link AgentTransport}.\n *\n * @module agent-core\n */\n\nimport type {\n  AgentInit,\n  AgentInput,\n  AgentOutput,\n  AgentStreamChunk,\n} from './agent.mjs';\nimport { applyPatch, type JsonPatch } from './json-patch.mjs';\nimport type { MessageData } from './model-types.mjs';\nimport type {\n  Media,\n  Part,\n  ToolRequestPart,\n  ToolResponsePart,\n} from './parts.mjs';\nimport type {\n  AgentFinishReason,\n  Artifact,\n  SessionSnapshot,\n  SessionState,\n} from './session.mjs';\n\n// ---------------------------------------------------------------------------\n// Public interfaces\n// ---------------------------------------------------------------------------\n\n/**\n * Identifies a snapshot to load: an exact `snapshotId`, or a `sessionId` (the\n * session's latest leaf snapshot). Provide exactly one.\n */\nexport type SnapshotLookup = { snapshotId: string } | { sessionId: string };\n\n/**\n * The transport-agnostic surface for talking to an agent. The same shape is\n * returned by `ai.defineAgent(...)` on the server and by `remoteAgent(...)` on\n * the client.\n */\n\nexport interface AgentAPI<State = unknown> {\n  /** Starts a new chat, or attaches to one via init. */\n  chat(init?: AgentInit<State>): AgentChat<State>;\n\n  /**\n   * Loads a server snapshot and returns a chat with history restored. Accepts\n   * either a `snapshotId` (an exact snapshot) or a `sessionId` (the session's\n   * latest snapshot).\n   */\n  loadChat(opts: SnapshotLookup): Promise<AgentChat<State>>;\n\n  /**\n   * Reads a snapshot without starting a chat. Requires a server store. Accepts\n   * a `snapshotId` string, or a lookup object (`{ snapshotId }` /\n   * `{ sessionId }`).\n   */\n  getSnapshot(\n    lookup: string | SnapshotLookup\n  ): Promise<SessionSnapshot<State> | undefined>;\n\n  /** Aborts a running snapshot. Requires a server store. */\n  abort(snapshotId: string): Promise<SessionSnapshot['status'] | undefined>;\n}\n\n/**\n * A stateful conversation with an agent. Tracks state across turns so callers\n * do not have to thread `snapshotId`/`state` by hand.\n */\nexport interface AgentChat<State = unknown> {\n  /**\n   * Runs a single turn and resolves with the completed {@link AgentResponse}.\n   * The non-streaming analog of {@link generate}; for incremental chunks use\n   * {@link sendStream}.\n   */\n  send(\n    input: string | AgentInput,\n    opts?: { abortSignal?: AbortSignal }\n  ): Promise<AgentResponse<State>>;\n\n  /**\n   * Runs a single turn and returns an {@link AgentTurn} exposing `.stream` and\n   * `.response`. The streaming analog of {@link generateStream}.\n   */\n  sendStream(\n    input: string | AgentInput,\n    opts?: { abortSignal?: AbortSignal }\n  ): AgentTurn<State>;\n\n  /** Resumes after an interrupt. Sugar for `send({ resume })`. */\n  resume(\n    resume: AgentInput['resume'],\n    opts?: { abortSignal?: AbortSignal }\n  ): Promise<AgentResponse<State>>;\n\n  /** Streaming resume. Sugar for `sendStream({ resume })`. */\n  resumeStream(\n    resume: AgentInput['resume'],\n    opts?: { abortSignal?: AbortSignal }\n  ): AgentTurn<State>;\n\n  /** Submits a detached (background) turn. */\n  detach(input: string | AgentInput): Promise<DetachedTask<State>>;\n\n  /** Aborts the current snapshot. */\n  abort(): Promise<SessionSnapshot['status'] | undefined>;\n\n  readonly snapshotId?: string;\n  /** Stable identifier correlating snapshots/turns of this conversation. */\n  readonly sessionId?: string;\n  readonly state?: State;\n  readonly messages: MessageData[];\n  readonly artifacts: Artifact[];\n}\n\n/**\n * A single in-flight turn - the analog of `ai.generateStream`'s\n * `{ stream, response }`.\n */\nexport interface AgentTurn<State = unknown, O = unknown> {\n  /** Chunks as the turn progresses. */\n  readonly stream: AsyncIterable<AgentChunk<State>>;\n\n  /** The completed turn, with generate-style accessors. */\n  readonly response: Promise<AgentResponse<State, O>>;\n\n  /** Aborts this in-flight turn. */\n  abort(): void;\n}\n\n/**\n * The completed result of a turn. Mirrors `GenerateResponse` and adds the\n * agent fields (`snapshotId`, `state`, `artifacts`).\n */\nexport interface AgentResponse<State = unknown, O = unknown> {\n  readonly message?: MessageData;\n  readonly text: string;\n  readonly reasoning: string;\n  readonly media: Media | null;\n  readonly data: O | null;\n  readonly toolRequests: ToolRequestPart[];\n  readonly interrupts: AgentInterrupt[];\n  readonly messages: MessageData[];\n  readonly finishReason: AgentFinishReason;\n  readonly finishMessage?: string;\n  readonly raw: AgentOutput<State>;\n  assertValid(): void;\n\n  readonly snapshotId?: string;\n  /** Stable identifier correlating snapshots/turns of this conversation. */\n  readonly sessionId?: string;\n  readonly state?: State;\n  readonly artifacts: Artifact[];\n}\n\n/**\n * A streamed chunk. Mirrors `GenerateResponseChunk` and adds the agent fields\n * (`artifact`, `custom`).\n */\nexport interface AgentChunk<State = unknown> {\n  readonly text: string;\n  readonly reasoning: string;\n  readonly accumulatedText: string;\n  readonly toolRequests: ToolRequestPart[];\n  readonly data: unknown;\n  readonly media: Media | null;\n\n  readonly artifact?: Artifact;\n  /**\n   * The full, post-patch custom state. Present only on chunks that carry a\n   * custom-state update; `undefined` on text / model chunks. Each value is a\n   * fresh object reference (the client applies the streamed RFC 6902 JSON Patch\n   * onto a clone), so it is safe to use for `===` change detection in UI\n   * frameworks. Equivalent to the value {@link AgentChat.state} returns at the\n   * moment this chunk is yielded.\n   */\n  readonly custom?: State;\n  readonly raw: AgentStreamChunk;\n}\n\n/**\n * A single tool request a turn paused on. `respond`/`restart` are builders:\n * they return the part to put into a `resume` payload, they do not send.\n */\nexport interface AgentInterrupt<Input = unknown, Output = unknown> {\n  name: string;\n  ref?: string;\n  input: Input;\n\n  /** Builds a `respond` entry for this interrupt. Does not send. */\n  respond(output: Output): ToolResponsePart;\n\n  /** Builds a `restart` entry re-issuing the original tool request. */\n  restart(): ToolRequestPart;\n}\n\n/**\n * A handle to a background (detached) task.\n */\nexport interface DetachedTask<State = unknown> {\n  readonly snapshotId: string;\n\n  /** Yields status until a terminal state. */\n  poll(opts?: { intervalMs?: number }): AsyncIterable<SessionSnapshot<State>>;\n\n  /** Resolves when the task reaches a terminal state. */\n  wait(opts?: { intervalMs?: number }): Promise<SessionSnapshot<State>>;\n\n  /** Aborts the task. */\n  abort(): Promise<SessionSnapshot['status'] | undefined>;\n}\n\n/**\n * Thrown when a turn fails. Carries the last-good state so the session is\n * recoverable.\n */\nexport class AgentError<State = unknown> extends Error {\n  readonly status: string;\n  readonly details?: unknown;\n  readonly state?: State;\n  readonly snapshotId?: string;\n  readonly response: AgentResponse<State>;\n\n  constructor(opts: {\n    message: string;\n    status: string;\n    details?: unknown;\n    state?: State;\n    snapshotId?: string;\n    response: AgentResponse<State>;\n  }) {\n    super(opts.message);\n    this.name = 'AgentError';\n    this.status = opts.status;\n    this.details = opts.details;\n    this.state = opts.state;\n    this.snapshotId = opts.snapshotId;\n    this.response = opts.response;\n    // Restore prototype chain for `instanceof` across transpilation targets.\n    Object.setPrototypeOf(this, AgentError.prototype);\n  }\n}\n\n// ---------------------------------------------------------------------------\n// Transport\n// ---------------------------------------------------------------------------\n\n/**\n * The pluggable backend the agent-client core runs over. Implementations exist\n * for the in-process server agent (driving the agent action directly) and for\n * the HTTP `remoteAgent` (driving `streamFlow`/`runFlow`).\n */\nexport interface AgentTransport {\n  /** Declares server- vs client-managed state; auto-detected when omitted. */\n  stateManagement?: 'server' | 'client';\n\n  /**\n   * Runs a single turn. Returns the streamed chunks plus a promise for the\n   * final, non-throwing {@link AgentOutput} (failures resolve with\n   * `finishReason: 'failed'`).\n   */\n  runTurn(\n    input: AgentInput,\n    init: AgentInit,\n    opts: { abortSignal: AbortSignal }\n  ): {\n    stream: AsyncIterable<AgentStreamChunk>;\n    output: Promise<AgentOutput>;\n  };\n\n  /** Reads a snapshot. Requires a server store. */\n  getSnapshot(\n    lookup: SnapshotLookup\n  ): Promise<SessionSnapshot<any> | undefined>;\n\n  /** Aborts a running snapshot. Requires a server store. */\n  abort(snapshotId: string): Promise<SessionSnapshot['status'] | undefined>;\n}\n\nconst TERMINAL_STATUSES = new Set([\n  'completed',\n  'failed',\n  'aborted',\n  'expired',\n]);\n\nfunction sleep(ms: number): Promise<void> {\n  return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction toAgentInput(input: string | AgentInput): AgentInput {\n  if (typeof input === 'string') {\n    return { message: { role: 'user', content: [{ text: input }] } };\n  }\n  return input;\n}\n\n// ── Message-derived accessor helpers (mirroring generate) ──────────────────\n\nfunction partsText(parts?: Part[]): string {\n  return (parts ?? []).map((p) => p.text ?? '').join('');\n}\n\nfunction partsReasoning(parts?: Part[]): string {\n  return (parts ?? [])\n    .filter((p) => p.reasoning !== undefined)\n    .map((p) => p.reasoning ?? '')\n    .join('');\n}\n\nfunction firstMedia(parts?: Part[]): Media | null {\n  const p = (parts ?? []).find((p) => !!p.media);\n  return p?.media\n    ? { url: p.media.url, contentType: p.media.contentType }\n    : null;\n}\n\nfunction firstData(parts?: Part[]): any {\n  const p = (parts ?? []).find((p) => p.data !== undefined);\n  return p?.data ?? null;\n}\n\nfunction toolRequestParts(parts?: Part[]): ToolRequestPart[] {\n  return (parts ?? []).filter((p) => !!p.toolRequest) as ToolRequestPart[];\n}\n\n// ---------------------------------------------------------------------------\n// AgentInterrupt\n// ---------------------------------------------------------------------------\n\nclass AgentInterruptImpl<Input = unknown, Output = unknown>\n  implements AgentInterrupt<Input, Output>\n{\n  readonly name: string;\n  readonly ref?: string;\n  readonly input: Input;\n\n  constructor(part: ToolRequestPart) {\n    this.name = part.toolRequest.name;\n    this.ref = part.toolRequest.ref;\n    this.input = part.toolRequest.input as Input;\n  }\n\n  respond(output: Output): ToolResponsePart {\n    return {\n      toolResponse: {\n        name: this.name,\n        ...(this.ref !== undefined && { ref: this.ref }),\n        output,\n      },\n    } as ToolResponsePart;\n  }\n\n  restart(): ToolRequestPart {\n    return {\n      toolRequest: {\n        name: this.name,\n        ...(this.ref !== undefined && { ref: this.ref }),\n        input: this.input,\n      },\n    } as ToolRequestPart;\n  }\n}\n\n// ---------------------------------------------------------------------------\n// AgentResponse\n// ---------------------------------------------------------------------------\n\nclass AgentResponseImpl<State = unknown, O = unknown>\n  implements AgentResponse<State, O>\n{\n  constructor(\n    private readonly _raw: AgentOutput<State>,\n    private readonly _messages: MessageData[],\n    /**\n     * Fallback custom-state getter. Server-managed agents (with a store) do not\n     * return `state` on the wire - they return a `snapshotId` and the chat\n     * tracks custom state locally (via streamed `customPatch` chunks). In that\n     * case `_raw.state` is undefined, so we fall back to the chat's tracked\n     * custom state here, ensuring `res.state` matches `chat.state` as documented.\n     */\n    private readonly _fallbackState?: () => State | undefined,\n    /**\n     * Fallback sessionId getter. Server-managed agents may not echo `sessionId`\n     * on every wire frame; fall back to the chat's tracked sessionId so\n     * `res.sessionId` matches `chat.sessionId` as documented.\n     */\n    private readonly _fallbackSessionId?: () => string | undefined\n  ) {}\n\n  get message(): MessageData | undefined {\n    return this._raw.message;\n  }\n\n  get text(): string {\n    return partsText(this._raw.message?.content);\n  }\n\n  get reasoning(): string {\n    return partsReasoning(this._raw.message?.content);\n  }\n\n  get media(): Media | null {\n    return firstMedia(this._raw.message?.content);\n  }\n\n  get data(): O | null {\n    return firstData(this._raw.message?.content) as O | null;\n  }\n\n  get toolRequests(): ToolRequestPart[] {\n    return toolRequestParts(this._raw.message?.content);\n  }\n\n  get interrupts(): AgentInterrupt[] {\n    return this.toolRequests\n      .filter((p) => !!(p as any).metadata?.interrupt)\n      .map((p) => new AgentInterruptImpl(p));\n  }\n\n  get messages(): MessageData[] {\n    return this._messages;\n  }\n\n  get finishReason(): AgentFinishReason {\n    return (this._raw.finishReason ?? 'unknown') as AgentFinishReason;\n  }\n\n  get finishMessage(): string | undefined {\n    return this._raw.error?.message;\n  }\n\n  get raw(): AgentOutput<State> {\n    return this._raw;\n  }\n\n  get snapshotId(): string | undefined {\n    return this._raw.snapshotId;\n  }\n\n  get sessionId(): string | undefined {\n    return this._raw.sessionId ?? this._fallbackSessionId?.();\n  }\n\n  get state(): State | undefined {\n    const fromWire = this._raw.state?.custom as State | undefined;\n    // Server-managed agents omit `state` on the wire; fall back to the chat's\n    // locally tracked custom state so `res.state === chat.state` as documented.\n    return fromWire !== undefined ? fromWire : this._fallbackState?.();\n  }\n\n  get artifacts(): Artifact[] {\n    return this._raw.artifacts ?? this._raw.state?.artifacts ?? [];\n  }\n\n  assertValid(): void {\n    if (this.finishReason === 'blocked') {\n      throw new Error(\n        `Generation blocked${this.finishMessage ? `: ${this.finishMessage}` : ''}.`\n      );\n    }\n    if (!this._raw.message) {\n      throw new Error('Agent response has no message.');\n    }\n  }\n}\n\n// ---------------------------------------------------------------------------\n// AgentChunk\n// ---------------------------------------------------------------------------\n\nclass AgentChunkImpl<State = unknown> implements AgentChunk<State> {\n  /**\n   * The post-patch custom state, set by the {@link AgentChatImpl.sendStream}\n   * generator after it applies this chunk's `customPatch`. Left `undefined` on\n   * chunks that do not carry a custom-state update.\n   */\n  private _custom?: State;\n\n  constructor(\n    private readonly _raw: AgentStreamChunk,\n    private readonly _previousText: string\n  ) {}\n\n  /** Internal: records the post-patch custom state this chunk reports. */\n  _setCustom(custom: State | undefined): void {\n    this._custom = custom;\n  }\n\n  private get _content(): Part[] | undefined {\n    return this._raw.modelChunk?.content as Part[] | undefined;\n  }\n\n  get text(): string {\n    return partsText(this._content);\n  }\n\n  get reasoning(): string {\n    return partsReasoning(this._content);\n  }\n\n  get accumulatedText(): string {\n    return this._previousText + this.text;\n  }\n\n  get toolRequests(): ToolRequestPart[] {\n    return toolRequestParts(this._content);\n  }\n\n  get data(): unknown {\n    return firstData(this._content);\n  }\n\n  get media(): Media | null {\n    return firstMedia(this._content);\n  }\n\n  get artifact(): Artifact | undefined {\n    return this._raw.artifact;\n  }\n\n  get custom(): State | undefined {\n    return this._custom;\n  }\n\n  get raw(): AgentStreamChunk {\n    return this._raw;\n  }\n}\n\n// ---------------------------------------------------------------------------\n// DetachedTask\n// ---------------------------------------------------------------------------\n\nclass DetachedTaskImpl<State = unknown> implements DetachedTask<State> {\n  constructor(\n    readonly snapshotId: string,\n    private readonly transport: AgentTransport\n  ) {}\n\n  async *poll(opts?: {\n    intervalMs?: number;\n  }): AsyncIterable<SessionSnapshot<State>> {\n    const intervalMs = opts?.intervalMs ?? 1000;\n    while (true) {\n      const snap = (await this.transport.getSnapshot({\n        snapshotId: this.snapshotId,\n      })) as SessionSnapshot<State> | undefined;\n\n      if (snap) {\n        yield snap;\n        if (snap.status && TERMINAL_STATUSES.has(snap.status)) {\n          return;\n        }\n      }\n      await sleep(intervalMs);\n    }\n  }\n\n  async wait(opts?: { intervalMs?: number }): Promise<SessionSnapshot<State>> {\n    let last: SessionSnapshot<State> | undefined;\n    for await (const snap of this.poll(opts)) {\n      last = snap;\n    }\n    if (!last) {\n      throw new Error(\n        `Detached task ${this.snapshotId} did not produce a snapshot.`\n      );\n    }\n    return last;\n  }\n\n  abort(): Promise<SessionSnapshot['status'] | undefined> {\n    return this.transport.abort(this.snapshotId);\n  }\n}\n\n// ---------------------------------------------------------------------------\n// AgentChat\n// ---------------------------------------------------------------------------\n\nexport class AgentChatImpl<State = unknown> implements AgentChat<State> {\n  snapshotId?: string;\n  sessionId?: string;\n  messages: MessageData[] = [];\n  artifacts: Artifact[] = [];\n\n  private clientState?: SessionState<State>;\n\n  constructor(\n    private readonly transport: AgentTransport,\n    private readonly connectInit?: AgentInit<State>\n  ) {\n    if (connectInit?.snapshotId) {\n      this.snapshotId = connectInit.snapshotId;\n    }\n    if (connectInit?.sessionId) {\n      this.sessionId = connectInit.sessionId;\n    }\n    if (connectInit?.state) {\n      this.hydrateFromState(connectInit.state);\n    }\n  }\n\n  get state(): State | undefined {\n    return this.clientState?.custom as State | undefined;\n  }\n\n  /**\n   * Replaces the tracked `clientState`/`messages`/`artifacts` aggregates with\n   * (copies of) those carried by a session state.\n   */\n  private hydrateFromState(state: SessionState<State> | undefined): void {\n    this.clientState = state;\n    this.messages = state?.messages ? [...state.messages] : [];\n    this.artifacts = state?.artifacts ? [...state.artifacts] : [];\n    if (state?.sessionId) {\n      this.sessionId = state.sessionId;\n    }\n  }\n\n  /** Loads aggregates from a server snapshot (used by `loadChat`). */\n  _loadFromSnapshot(snapshot: SessionSnapshot<State>): void {\n    this.snapshotId = snapshot.snapshotId;\n    this.hydrateFromState(snapshot.state);\n  }\n\n  /**\n   * Builds the init for the next turn from tracked aggregates. Always returns\n   * an object (never `undefined`) because the agent validates `init` against\n   * `AgentInitSchema` - an empty object is the valid \"fresh session\" init.\n   */\n  private buildInit(): AgentInit<State> {\n    if (this.snapshotId) {\n      return { snapshotId: this.snapshotId };\n    }\n    if (this.clientState) {\n      return { state: this.clientState };\n    }\n    return this.connectInit ?? {};\n  }\n\n  /** Applies a completed turn's output to the running aggregates. */\n  private applyOutput(raw: AgentOutput<State>): void {\n    if (raw.snapshotId !== undefined) {\n      this.snapshotId = raw.snapshotId;\n    }\n    if (raw.sessionId !== undefined) {\n      this.sessionId = raw.sessionId;\n    }\n\n    if (raw.state !== undefined) {\n      this.clientState = raw.state;\n    }\n    if (this.transport.stateManagement === undefined) {\n      if (raw.snapshotId !== undefined) {\n        this.transport.stateManagement = 'server';\n      } else if (raw.state !== undefined) {\n        this.transport.stateManagement = 'client';\n      }\n    }\n    if (raw.state?.messages !== undefined) {\n      this.messages = [...raw.state.messages];\n    } else if (raw.message) {\n      this.messages.push(raw.message);\n    }\n    if (raw.state?.artifacts !== undefined) {\n      this.artifacts = [...raw.state.artifacts];\n    } else if (raw.artifacts?.length) {\n      for (const a of raw.artifacts) {\n        const idx = a.name\n          ? this.artifacts.findIndex((x) => x.name === a.name)\n          : -1;\n        if (idx >= 0) {\n          this.artifacts[idx] = a;\n        } else {\n          this.artifacts.push(a);\n        }\n      }\n    }\n  }\n\n  /**\n   * Wires an optional external abort signal to a fresh {@link AbortController}\n   * and returns it alongside a getter for whether the turn was aborted.\n   */\n  private setupAbort(opts?: { abortSignal?: AbortSignal }): {\n    controller: AbortController;\n    isAborted: () => boolean;\n  } {\n    const controller = new AbortController();\n    let aborted = false;\n    if (opts?.abortSignal) {\n      if (opts.abortSignal.aborted) {\n        controller.abort();\n        aborted = true;\n      } else {\n        opts.abortSignal.addEventListener('abort', () => {\n          aborted = true;\n          controller.abort();\n        });\n      }\n    }\n    return {\n      controller,\n      isAborted: () => aborted || controller.signal.aborted,\n    };\n  }\n\n  /**\n   * Resolves a turn's raw `output` into an {@link AgentResponse}, applying it to\n   * the running aggregates and throwing an {@link AgentError} on a failed turn.\n   * Aborted turns resolve to a synthetic `aborted` response. Shared by both\n   * {@link send} and {@link sendStream}.\n   */\n  private buildResponse(\n    output: Promise<AgentOutput>,\n    isAborted: () => boolean,\n    messageCountBeforeTurn: number\n  ): Promise<AgentResponse<State>> {\n    return (async (): Promise<AgentResponse<State>> => {\n      let raw: AgentOutput<State>;\n      try {\n        raw = (await output) as AgentOutput<State>;\n      } catch (e) {\n        if (isAborted()) {\n          raw = { finishReason: 'aborted' as AgentFinishReason };\n        } else {\n          throw this.toAgentError(e);\n        }\n      }\n      // A failed/aborted turn that returns no authoritative messages leaves the\n      // eagerly-pushed user message (see `sendStream`) orphaned in `this.messages`\n      // with no reply. Roll it back so it isn't re-sent on the next turn. When the\n      // turn returns authoritative `state.messages`, `applyOutput` replaces the\n      // array wholesale, so this rollback is a no-op for the success path.\n      if (\n        (raw.finishReason === 'failed' || raw.finishReason === 'aborted') &&\n        raw.state?.messages === undefined &&\n        !raw.message\n      ) {\n        this.messages.length = messageCountBeforeTurn;\n      }\n      this.applyOutput(raw);\n      const response = new AgentResponseImpl<State>(\n        raw,\n        [...this.messages],\n        () => this.state,\n        () => this.sessionId\n      );\n      if (raw.finishReason === 'failed') {\n        throw new AgentError<State>({\n          message: raw.error?.message ?? 'Agent turn failed.',\n          status: raw.error?.status ?? 'UNKNOWN',\n          details: raw.error?.details,\n          state: raw.state?.custom as State | undefined,\n          snapshotId: raw.snapshotId,\n          response,\n        });\n      }\n      return response;\n    })();\n  }\n\n  async send(\n    input: string | AgentInput,\n    opts?: { abortSignal?: AbortSignal }\n  ): Promise<AgentResponse<State>> {\n    // `send()` is a non-streaming veneer over the streaming path: we run the\n    // turn via `sendStream` and drain its stream internally before resolving.\n    //\n    // Draining matters for server-managed agents (with a store): they do not\n    // return custom `state` on the wire (only a `snapshotId`); the chat's\n    // tracked custom state is kept live by applying the streamed `customPatch`\n    // chunks. A non-streaming path would skip those chunks and leave\n    // `chat.state` (and the `res.state` fallback) stale after a `send()`.\n    // Consuming the stream here keeps `send()` and `sendStream()` consistent.\n    // Client-managed agents are unaffected (they round-trip full state on the\n    // wire either way).\n    const turn = this.sendStream(input, opts);\n    // Drain the stream so custom-state patches are applied to the chat.\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    for await (const _ of turn.stream) {\n      // no-op: side effects (custom-state patches) happen as we iterate.\n    }\n    return turn.response;\n  }\n\n  sendStream(\n    input: string | AgentInput,\n    opts?: { abortSignal?: AbortSignal }\n  ): AgentTurn<State> {\n    const agentInput = toAgentInput(input);\n\n    // Bail before pushing the message or dispatching the turn if the caller's\n    // signal is already aborted: there's no point starting work, and we must\n    // not leave an orphaned user message in `this.messages`.\n    if (opts?.abortSignal?.aborted) {\n      const aborted = (async (): Promise<AgentResponse<State>> => {\n        return new AgentResponseImpl<State>(\n          { finishReason: 'aborted' as AgentFinishReason },\n          [...this.messages],\n          () => this.state,\n          () => this.sessionId\n        );\n      })();\n      aborted.catch(() => {});\n      return {\n        stream: (async function* (): AsyncIterable<AgentChunk<State>> {})(),\n        response: aborted as Promise<AgentResponse<State, unknown>>,\n        abort() {},\n      };\n    }\n\n    // Remember the message count so a failed/aborted turn that returns no\n    // authoritative messages can roll back the eager push below (see\n    // `buildResponse`). Note: turns are assumed single-flight - this client\n    // does not guard against overlapping `send`/`sendStream` calls on the same\n    // chat (they would race on `messages`/`snapshotId`/`clientState`).\n    const messageCountBeforeTurn = this.messages.length;\n    if (agentInput.message) {\n      this.messages.push(agentInput.message);\n    }\n    const init = this.buildInit();\n\n    const { controller, isAborted } = this.setupAbort(opts);\n\n    const { stream: rawStream, output } = this.transport.runTurn(\n      agentInput,\n      init,\n      { abortSignal: controller.signal }\n    );\n\n    const responsePromise = this.buildResponse(\n      output,\n      isAborted,\n      messageCountBeforeTurn\n    );\n    // Avoid unhandled-rejection warnings when only the stream is consumed.\n    responsePromise.catch(() => {});\n\n    const self = this;\n    const stream = (async function* (): AsyncIterable<AgentChunk<State>> {\n      let previousText = '';\n      try {\n        for await (const raw of rawStream) {\n          const chunk = new AgentChunkImpl<State>(raw, previousText);\n          previousText = chunk.accumulatedText;\n          // Keep the locally tracked custom state live mid-stream by applying\n          // each streamed JSON Patch to it, then surface the resulting\n          // post-patch custom state on the chunk as `chunk.custom` so consumers\n          // get an explicit change notification (with a fresh object reference\n          // for `===`-based change detection). The first patch of a turn is a\n          // whole-document replace that re-bases us onto the server baseline.\n          if (raw.customPatch) {\n            self.applyCustomPatch(raw.customPatch);\n            chunk._setCustom(self.state);\n          }\n          yield chunk;\n        }\n      } catch (e) {\n        if (!isAborted()) {\n          // Surface a failed turn / transport error as an AgentError.\n          await responsePromise;\n          throw self.toAgentError(e);\n        }\n      }\n      // Re-surface a failed turn (which resolves the wire, but rejects here).\n      await responsePromise;\n    })();\n\n    return {\n      stream,\n      response: responsePromise as Promise<AgentResponse<State, unknown>>,\n      abort() {\n        controller.abort();\n      },\n    };\n  }\n\n  resume(\n    resume: AgentInput['resume'],\n    opts?: { abortSignal?: AbortSignal }\n  ): Promise<AgentResponse<State>> {\n    return this.send({ resume }, opts);\n  }\n\n  resumeStream(\n    resume: AgentInput['resume'],\n    opts?: { abortSignal?: AbortSignal }\n  ): AgentTurn<State> {\n    return this.sendStream({ resume }, opts);\n  }\n\n  /**\n   * Applies a streamed RFC 6902 JSON Patch to the locally tracked custom\n   * state, keeping {@link state} live as the turn streams. The first patch of\n   * a turn is a whole-document replace (rooted at `\"\"`) that re-bases the\n   * client onto the server's current baseline.\n   *\n   * Transport requirement: `customPatch` chunks carry no sequence number and\n   * are applied positionally, so the transport MUST deliver them in order with\n   * no loss. The in-order SSE channel used today satisfies this; a lossy or\n   * reordering transport would yield silently-wrong state (each turn does begin\n   * with a whole-document replace, so corruption cannot persist past a turn\n   * boundary).\n   */\n  private applyCustomPatch(patch: JsonPatch): void {\n    const current = this.clientState?.custom;\n    const next = applyPatch(current, patch) as State;\n    if (this.clientState) {\n      this.clientState = { ...this.clientState, custom: next };\n    } else {\n      this.clientState = { custom: next } as SessionState<State>;\n    }\n  }\n\n  async detach(input: string | AgentInput): Promise<DetachedTask<State>> {\n    const agentInput: AgentInput = { ...toAgentInput(input), detach: true };\n    if (agentInput.message) {\n      this.messages.push(agentInput.message);\n    }\n    const init = this.buildInit();\n    const controller = new AbortController();\n    const { output } = this.transport.runTurn(agentInput, init, {\n      abortSignal: controller.signal,\n    });\n    const raw = (await output) as AgentOutput<State>;\n    this.applyOutput(raw);\n    if (!raw.snapshotId) {\n      throw new Error('detach did not return a snapshotId.');\n    }\n    return new DetachedTaskImpl<State>(raw.snapshotId, this.transport);\n  }\n\n  async abort(): Promise<SessionSnapshot['status'] | undefined> {\n    if (!this.snapshotId) {\n      return undefined;\n    }\n    return this.transport.abort(this.snapshotId);\n  }\n\n  private toAgentError(e: unknown): AgentError<State> {\n    if (e instanceof AgentError) {\n      return e;\n    }\n    const message = e instanceof Error ? e.message : String(e);\n    const match = /^([A-Z_]+):/.exec(message);\n    const status = match ? match[1] : 'UNKNOWN';\n    const raw: AgentOutput<State> = {\n      finishReason: 'failed' as AgentFinishReason,\n      error: { status, message },\n    };\n    const response = new AgentResponseImpl<State>(\n      raw,\n      [...this.messages],\n      () => this.clientState?.custom as State | undefined,\n      () => this.sessionId\n    );\n    return new AgentError<State>({\n      message,\n      status,\n      details: e,\n      state: this.clientState?.custom as State | undefined,\n      snapshotId: this.snapshotId,\n      response,\n    });\n  }\n}\n\n// ---------------------------------------------------------------------------\n// createAgentAPI - builds the AgentAPI surface over any transport.\n// ---------------------------------------------------------------------------\n\n/**\n * Composes the {@link AgentAPI} surface (`chat`/`loadChat`/`getSnapshot`/\n * `abort`) over a {@link AgentTransport}. Shared by the in-process server agent\n * and the HTTP `remoteAgent`.\n */\nexport function createAgentAPI<State = unknown>(\n  transport: AgentTransport\n): AgentAPI<State> {\n  return {\n    chat(init?: AgentInit<State>): AgentChat<State> {\n      return new AgentChatImpl<State>(transport, init);\n    },\n\n    async loadChat(opts: SnapshotLookup): Promise<AgentChat<State>> {\n      const snapshot = (await transport.getSnapshot(opts)) as\n        | SessionSnapshot<State>\n        | undefined;\n      if (!snapshot) {\n        const id =\n          'snapshotId' in opts ? opts.snapshotId : `session ${opts.sessionId}`;\n        throw new Error(`Snapshot ${id} not found.`);\n      }\n      const chat = new AgentChatImpl<State>(transport);\n      chat._loadFromSnapshot(snapshot);\n      return chat;\n    },\n\n    getSnapshot(\n      lookup: string | SnapshotLookup\n    ): Promise<SessionSnapshot<State> | undefined> {\n      const normalized: SnapshotLookup =\n        typeof lookup === 'string' ? { snapshotId: lookup } : lookup;\n      return transport.getSnapshot(normalized) as Promise<\n        SessionSnapshot<State> | undefined\n      >;\n    },\n\n    abort(snapshotId: string): Promise<SessionSnapshot['status'] | undefined> {\n      return transport.abort(snapshotId);\n    },\n  };\n}\n"],"mappings":"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","names":["p"]}