{"version":3,"file":"index.cjs","names":["z","AbstractAgent","Observable","EventType","StreamableHTTPClientTransport","SSEClientTransport","convertAISDKStream","convertTanStackStream"],"sources":["../../src/agent/index.ts"],"sourcesContent":["import {\n  AbstractAgent,\n  BaseEvent,\n  RunAgentInput,\n  EventType,\n  Message,\n  ReasoningEndEvent,\n  ReasoningMessageContentEvent,\n  ReasoningMessageEndEvent,\n  ReasoningMessageStartEvent,\n  ReasoningStartEvent,\n  RunFinishedEvent,\n  RunStartedEvent,\n  TextMessageChunkEvent,\n  ToolCallArgsEvent,\n  ToolCallEndEvent,\n  ToolCallStartEvent,\n  ToolCallResultEvent,\n  RunErrorEvent,\n  StateSnapshotEvent,\n  StateDeltaEvent,\n} from \"@ag-ui/client\";\nimport {\n  streamText,\n  LanguageModel,\n  ModelMessage,\n  AssistantModelMessage,\n  UserModelMessage,\n  ToolModelMessage,\n  SystemModelMessage,\n  ToolCallPart,\n  ToolResultPart,\n  TextPart,\n  ImagePart,\n  FilePart,\n  tool as createVercelAISDKTool,\n  ToolChoice,\n  ToolSet,\n  stepCountIs,\n} from \"ai\";\nimport { experimental_createMCPClient as createMCPClient } from \"@ai-sdk/mcp\";\nimport { Observable } from \"rxjs\";\nimport { createOpenAI } from \"@ai-sdk/openai\";\nimport { createAnthropic } from \"@ai-sdk/anthropic\";\nimport { createGoogleGenerativeAI } from \"@ai-sdk/google\";\nimport { createVertex } from \"@ai-sdk/google-vertex\";\nimport { safeParseToolArgs } from \"@copilotkit/shared\";\nimport { z } from \"zod\";\nimport type { StandardSchemaV1, InferSchemaOutput } from \"@copilotkit/shared\";\nimport { schemaToJsonSchema } from \"@copilotkit/shared\";\nimport { jsonSchema as aiJsonSchema } from \"ai\";\nimport { convertAISDKStream } from \"./converters/aisdk\";\nimport { convertTanStackStream } from \"./converters/tanstack\";\nimport {\n  StreamableHTTPClientTransport,\n  StreamableHTTPClientTransportOptions,\n} from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport { SSEClientTransport } from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport { randomUUID } from \"@copilotkit/shared\";\n\n/**\n * Properties that can be overridden by forwardedProps\n * These match the exact parameter names in streamText\n */\nexport type OverridableProperty =\n  | \"model\"\n  | \"toolChoice\"\n  | \"maxOutputTokens\"\n  | \"temperature\"\n  | \"topP\"\n  | \"topK\"\n  | \"presencePenalty\"\n  | \"frequencyPenalty\"\n  | \"stopSequences\"\n  | \"seed\"\n  | \"maxRetries\"\n  | \"prompt\"\n  | \"providerOptions\";\n\n/**\n * Supported model identifiers for BuiltInAgent\n */\nexport type BuiltInAgentModel =\n  // OpenAI models\n  | \"openai/gpt-5\"\n  | \"openai/gpt-5-mini\"\n  | \"openai/gpt-4.1\"\n  | \"openai/gpt-4.1-mini\"\n  | \"openai/gpt-4.1-nano\"\n  | \"openai/gpt-4o\"\n  | \"openai/gpt-4o-mini\"\n  // OpenAI reasoning series\n  | \"openai/o3\"\n  | \"openai/o3-mini\"\n  | \"openai/o4-mini\"\n  // Anthropic (Claude) models\n  | \"anthropic/claude-sonnet-4.5\"\n  | \"anthropic/claude-sonnet-4\"\n  | \"anthropic/claude-3.7-sonnet\"\n  | \"anthropic/claude-opus-4.1\"\n  | \"anthropic/claude-opus-4\"\n  | \"anthropic/claude-3.5-haiku\"\n  // Google (Gemini) models\n  | \"google/gemini-2.5-pro\"\n  | \"google/gemini-2.5-flash\"\n  | \"google/gemini-2.5-flash-lite\"\n  // Allow any LanguageModel instance\n  | (string & {});\n\n/**\n * Model specifier - can be a string like \"openai/gpt-4o\" or a LanguageModel instance\n */\nexport type ModelSpecifier = string | LanguageModel;\n\n/**\n * MCP Client configuration for HTTP transport\n */\nexport interface MCPClientConfigHTTP {\n  /**\n   * Type of MCP client\n   */\n  type: \"http\";\n  /**\n   * URL of the MCP server\n   */\n  url: string;\n  /**\n   * Optional transport options for HTTP client\n   */\n  options?: StreamableHTTPClientTransportOptions;\n}\n\n/**\n * MCP Client configuration for SSE transport\n */\nexport interface MCPClientConfigSSE {\n  /**\n   * Type of MCP client\n   */\n  type: \"sse\";\n  /**\n   * URL of the MCP server\n   */\n  url: string;\n  /**\n   * Optional HTTP headers (e.g., for authentication)\n   */\n  headers?: Record<string, string>;\n}\n\n/**\n * MCP Client configuration\n */\nexport type MCPClientConfig = MCPClientConfigHTTP | MCPClientConfigSSE;\n\n/**\n * A user-managed MCP client that provides tools to the agent.\n * The user is responsible for creating, configuring, and closing the client.\n * Compatible with the return type of @ai-sdk/mcp's createMCPClient().\n *\n * Unlike mcpServers, the agent does NOT create or close these clients.\n * This allows persistent connections, custom auth, and tool caching.\n */\nexport interface MCPClientProvider {\n  /** Return tools to be merged into the agent's tool set. */\n  tools(): Promise<ToolSet>;\n}\n\n/**\n * Resolves a model specifier to a LanguageModel instance\n * @param spec - Model string (e.g., \"openai/gpt-4o\") or LanguageModel instance\n * @param apiKey - Optional API key to use instead of environment variables\n * @returns LanguageModel instance\n */\nexport function resolveModel(\n  spec: ModelSpecifier,\n  apiKey?: string,\n): LanguageModel {\n  // If already a LanguageModel instance, pass through\n  if (typeof spec !== \"string\") {\n    return spec;\n  }\n\n  // Normalize \"provider/model\" or \"provider:model\" format\n  const normalized = spec.replace(\"/\", \":\").trim();\n  const parts = normalized.split(\":\");\n  const rawProvider = parts[0];\n  const rest = parts.slice(1);\n\n  if (!rawProvider) {\n    throw new Error(\n      `Invalid model string \"${spec}\". Use \"openai/gpt-5\", \"anthropic/claude-sonnet-4.5\", or \"google/gemini-2.5-pro\".`,\n    );\n  }\n\n  const provider = rawProvider.toLowerCase();\n  const model = rest.join(\":\").trim();\n\n  if (!model) {\n    throw new Error(\n      `Invalid model string \"${spec}\". Use \"openai/gpt-5\", \"anthropic/claude-sonnet-4.5\", or \"google/gemini-2.5-pro\".`,\n    );\n  }\n\n  switch (provider) {\n    case \"openai\": {\n      // Lazily create OpenAI provider\n      // Use provided apiKey, or fall back to environment variable\n      const openai = createOpenAI({\n        apiKey: apiKey || process.env.OPENAI_API_KEY!,\n      });\n      // Accepts any OpenAI model id, e.g. \"gpt-4o\", \"gpt-4.1-mini\", \"o3-mini\"\n      return openai(model);\n    }\n\n    case \"anthropic\": {\n      // Lazily create Anthropic provider\n      // Use provided apiKey, or fall back to environment variable\n      const anthropic = createAnthropic({\n        apiKey: apiKey || process.env.ANTHROPIC_API_KEY!,\n      });\n      // Accepts any Claude id, e.g. \"claude-3.7-sonnet\", \"claude-3.5-haiku\"\n      return anthropic(model);\n    }\n\n    case \"google\":\n    case \"gemini\":\n    case \"google-gemini\": {\n      // Lazily create Google provider\n      // Use provided apiKey, or fall back to environment variable\n      const google = createGoogleGenerativeAI({\n        apiKey: apiKey || process.env.GOOGLE_API_KEY!,\n      });\n      // Accepts any Gemini id, e.g. \"gemini-2.5-pro\", \"gemini-2.5-flash\"\n      return google(model);\n    }\n\n    case \"vertex\": {\n      const vertex = createVertex();\n      return vertex(model);\n    }\n\n    default:\n      throw new Error(\n        `Unknown provider \"${provider}\" in \"${spec}\". Supported: openai, anthropic, google (gemini).`,\n      );\n  }\n}\n\n/**\n * Tool definition for BuiltInAgent\n */\nexport interface ToolDefinition<\n  TParameters extends StandardSchemaV1 = StandardSchemaV1,\n> {\n  name: string;\n  description: string;\n  parameters: TParameters;\n  execute: (args: InferSchemaOutput<TParameters>) => Promise<unknown>;\n}\n\n/**\n * Define a tool for use with BuiltInAgent\n * @param name - The name of the tool\n * @param description - Description of what the tool does\n * @param parameters - Schema for the tool's input parameters (any Standard Schema V1 compatible library: Zod, Valibot, ArkType, etc.)\n * @param execute - Function to execute the tool server-side\n * @returns Tool definition\n */\nexport function defineTool<TParameters extends StandardSchemaV1>(config: {\n  name: string;\n  description: string;\n  parameters: TParameters;\n  execute: (args: InferSchemaOutput<TParameters>) => Promise<unknown>;\n}): ToolDefinition<TParameters> {\n  return {\n    name: config.name,\n    description: config.description,\n    parameters: config.parameters,\n    execute: config.execute,\n  };\n}\n\ntype AGUIUserMessage = Extract<Message, { role: \"user\" }>;\n\n/**\n * Converts AG-UI user message content to Vercel AI SDK UserContent format.\n * Handles plain strings, new modality-specific parts (image/audio/video/document),\n * and legacy BinaryInputContent for backward compatibility.\n */\nfunction convertUserMessageContent(\n  content: AGUIUserMessage[\"content\"],\n): string | Array<TextPart | ImagePart | FilePart> {\n  if (!content) {\n    return \"\";\n  }\n\n  if (typeof content === \"string\") {\n    return content;\n  }\n\n  const parts: Array<TextPart | ImagePart | FilePart> = [];\n\n  for (const part of content) {\n    if (!part || typeof part !== \"object\" || !(\"type\" in part)) {\n      continue;\n    }\n\n    switch (part.type) {\n      case \"text\": {\n        const text = (part as { text?: string }).text;\n        if (text) {\n          parts.push({ type: \"text\", text });\n        }\n        break;\n      }\n\n      case \"image\": {\n        const source = (part as { source?: any }).source;\n        if (!source) break;\n        if (source.type === \"data\") {\n          parts.push({\n            type: \"image\",\n            image: source.value,\n            mediaType: source.mimeType,\n          });\n        } else if (source.type === \"url\") {\n          try {\n            parts.push({\n              type: \"image\",\n              image: new URL(source.value),\n              mediaType: source.mimeType,\n            });\n          } catch {\n            console.error(\n              `[CopilotKit] convertUserMessageContent: invalid URL \"${source.value}\" in image part — skipping`,\n            );\n          }\n        }\n        break;\n      }\n\n      case \"audio\":\n      case \"video\":\n      case \"document\": {\n        const source = (part as { source?: any }).source;\n        if (!source) break;\n        if (source.type === \"data\") {\n          parts.push({\n            type: \"file\",\n            data: source.value,\n            mediaType: source.mimeType,\n          });\n        } else if (source.type === \"url\") {\n          try {\n            parts.push({\n              type: \"file\",\n              data: new URL(source.value),\n              mediaType: source.mimeType ?? \"application/octet-stream\",\n            });\n          } catch {\n            console.error(\n              `[CopilotKit] convertUserMessageContent: invalid URL \"${source.value}\" in ${part.type} part — skipping`,\n            );\n          }\n        }\n        break;\n      }\n\n      // Legacy BinaryInputContent backward compatibility\n      case \"binary\": {\n        const legacy = part as {\n          mimeType?: string;\n          data?: string;\n          url?: string;\n        };\n        const mimeType = legacy.mimeType ?? \"application/octet-stream\";\n        const isImage = mimeType.startsWith(\"image/\");\n\n        if (legacy.data) {\n          if (isImage) {\n            parts.push({\n              type: \"image\",\n              image: legacy.data,\n              mediaType: mimeType,\n            });\n          } else {\n            parts.push({\n              type: \"file\",\n              data: legacy.data,\n              mediaType: mimeType,\n            });\n          }\n        } else if (legacy.url) {\n          try {\n            const url = new URL(legacy.url);\n            if (isImage) {\n              parts.push({ type: \"image\", image: url, mediaType: mimeType });\n            } else {\n              parts.push({ type: \"file\", data: url, mediaType: mimeType });\n            }\n          } catch {\n            console.error(\n              `[CopilotKit] convertUserMessageContent: invalid URL \"${legacy.url}\" in binary part — skipping`,\n            );\n          }\n        }\n        break;\n      }\n\n      default: {\n        console.error(\n          `[CopilotKit] convertUserMessageContent: unrecognized content part type \"${(part as { type: string }).type}\" — skipping`,\n        );\n        break;\n      }\n    }\n  }\n\n  return parts.length > 0 ? parts : \"\";\n}\n\n/**\n * Options for converting AG-UI messages to Vercel AI SDK format\n */\nexport interface MessageConversionOptions {\n  forwardSystemMessages?: boolean;\n  forwardDeveloperMessages?: boolean;\n}\n\n/**\n * Converts AG-UI messages to Vercel AI SDK ModelMessage format\n */\nexport function convertMessagesToVercelAISDKMessages(\n  messages: Message[],\n  options: MessageConversionOptions = {},\n): ModelMessage[] {\n  const result: ModelMessage[] = [];\n\n  for (const message of messages) {\n    if (message.role === \"system\" && options.forwardSystemMessages) {\n      const systemMsg: SystemModelMessage = {\n        role: \"system\",\n        content: message.content ?? \"\",\n      };\n      result.push(systemMsg);\n    } else if (\n      message.role === \"developer\" &&\n      options.forwardDeveloperMessages\n    ) {\n      const systemMsg: SystemModelMessage = {\n        role: \"system\",\n        content: message.content ?? \"\",\n      };\n      result.push(systemMsg);\n    } else if (message.role === \"assistant\") {\n      const parts: Array<TextPart | ToolCallPart> = message.content\n        ? [{ type: \"text\", text: message.content }]\n        : [];\n\n      for (const toolCall of message.toolCalls ?? []) {\n        const toolCallPart: ToolCallPart = {\n          type: \"tool-call\",\n          toolCallId: toolCall.id,\n          toolName: toolCall.function.name,\n          input: safeParseToolArgs(toolCall.function.arguments),\n        };\n        parts.push(toolCallPart);\n      }\n\n      const assistantMsg: AssistantModelMessage = {\n        role: \"assistant\",\n        content: parts,\n      };\n      result.push(assistantMsg);\n    } else if (message.role === \"user\") {\n      const userMsg: UserModelMessage = {\n        role: \"user\",\n        content: convertUserMessageContent(message.content),\n      };\n      result.push(userMsg);\n    } else if (message.role === \"tool\") {\n      let toolName = \"unknown\";\n      // Find the tool name from the corresponding tool call\n      for (const msg of messages) {\n        if (msg.role === \"assistant\") {\n          for (const toolCall of msg.toolCalls ?? []) {\n            if (toolCall.id === message.toolCallId) {\n              toolName = toolCall.function.name;\n              break;\n            }\n          }\n        }\n      }\n\n      const toolResultPart: ToolResultPart = {\n        type: \"tool-result\",\n        toolCallId: message.toolCallId,\n        toolName: toolName,\n        output: {\n          type: \"text\",\n          value: message.content,\n        },\n      };\n\n      const toolMsg: ToolModelMessage = {\n        role: \"tool\",\n        content: [toolResultPart],\n      };\n      result.push(toolMsg);\n    }\n  }\n\n  return result;\n}\n\n/**\n * JSON Schema type definition\n */\ninterface JsonSchema {\n  type: \"object\" | \"string\" | \"number\" | \"integer\" | \"boolean\" | \"array\";\n  description?: string;\n  properties?: Record<string, JsonSchema>;\n  required?: string[];\n  items?: JsonSchema;\n  enum?: string[];\n}\n\n/**\n * Converts JSON Schema to Zod schema\n */\nexport function convertJsonSchemaToZodSchema(\n  jsonSchema: JsonSchema,\n  required: boolean,\n): z.ZodSchema {\n  // Handle empty schemas {} (no input required) - treat as empty object\n  if (!jsonSchema.type) {\n    return required ? z.object({}) : z.object({}).optional();\n  }\n  if (jsonSchema.type === \"object\") {\n    const spec: { [key: string]: z.ZodSchema } = {};\n\n    if (!jsonSchema.properties || !Object.keys(jsonSchema.properties).length) {\n      return !required ? z.object(spec).optional() : z.object(spec);\n    }\n\n    for (const [key, value] of Object.entries(jsonSchema.properties)) {\n      spec[key] = convertJsonSchemaToZodSchema(\n        value,\n        jsonSchema.required ? jsonSchema.required.includes(key) : false,\n      );\n    }\n    const schema = z.object(spec).describe(jsonSchema.description ?? \"\");\n    return required ? schema : schema.optional();\n  } else if (jsonSchema.type === \"string\") {\n    if (jsonSchema.enum && jsonSchema.enum.length > 0) {\n      const schema = z\n        .enum(jsonSchema.enum as [string, ...string[]])\n        .describe(jsonSchema.description ?? \"\");\n      return required ? schema : schema.optional();\n    }\n    const schema = z.string().describe(jsonSchema.description ?? \"\");\n    return required ? schema : schema.optional();\n  } else if (jsonSchema.type === \"number\" || jsonSchema.type === \"integer\") {\n    const schema = z.number().describe(jsonSchema.description ?? \"\");\n    return required ? schema : schema.optional();\n  } else if (jsonSchema.type === \"boolean\") {\n    const schema = z.boolean().describe(jsonSchema.description ?? \"\");\n    return required ? schema : schema.optional();\n  } else if (jsonSchema.type === \"array\") {\n    if (!jsonSchema.items) {\n      throw new Error(\"Array type must have items property\");\n    }\n    const itemSchema = convertJsonSchemaToZodSchema(jsonSchema.items, true);\n    const schema = z.array(itemSchema).describe(jsonSchema.description ?? \"\");\n    return required ? schema : schema.optional();\n  }\n  console.error(\"Invalid JSON schema:\", JSON.stringify(jsonSchema, null, 2));\n  throw new Error(\"Invalid JSON schema\");\n}\n\n/**\n * Converts AG-UI tools to Vercel AI SDK ToolSet\n */\nfunction isJsonSchema(obj: unknown): obj is JsonSchema {\n  if (typeof obj !== \"object\" || obj === null) return false;\n  const schema = obj as Record<string, unknown>;\n  // Empty objects {} are valid JSON schemas (no input required)\n  if (Object.keys(schema).length === 0) return true;\n  return (\n    typeof schema.type === \"string\" &&\n    [\"object\", \"string\", \"number\", \"integer\", \"boolean\", \"array\"].includes(\n      schema.type,\n    )\n  );\n}\n\nexport function convertToolsToVercelAITools(\n  tools: RunAgentInput[\"tools\"],\n): ToolSet {\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  const result: Record<string, any> = {};\n\n  for (const tool of tools) {\n    if (!isJsonSchema(tool.parameters)) {\n      throw new Error(`Invalid JSON schema for tool ${tool.name}`);\n    }\n    const zodSchema = convertJsonSchemaToZodSchema(tool.parameters, true);\n    result[tool.name] = createVercelAISDKTool({\n      description: tool.description,\n      inputSchema: zodSchema,\n    });\n  }\n\n  return result;\n}\n\n/**\n * Check whether a schema is a Zod schema by inspecting its Standard Schema vendor.\n */\nfunction isZodSchema(schema: StandardSchemaV1): boolean {\n  return schema[\"~standard\"]?.vendor === \"zod\";\n}\n\n/**\n * Converts ToolDefinition array to Vercel AI SDK ToolSet.\n *\n * For Zod schemas, passes them directly to the AI SDK (Zod satisfies FlexibleSchema).\n * For non-Zod schemas, converts to JSON Schema via schemaToJsonSchema() and wraps\n * with the AI SDK's jsonSchema() helper.\n */\nexport function convertToolDefinitionsToVercelAITools(\n  tools: ToolDefinition[],\n): ToolSet {\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  const result: Record<string, any> = {};\n\n  for (const tool of tools) {\n    if (isZodSchema(tool.parameters)) {\n      // Zod schemas can be passed directly to AI SDK (satisfies FlexibleSchema)\n      result[tool.name] = createVercelAISDKTool({\n        description: tool.description,\n        inputSchema: tool.parameters as any,\n        execute: tool.execute,\n      });\n    } else {\n      // Non-Zod: convert to JSON Schema and wrap with AI SDK's jsonSchema()\n      const jsonSchemaObj = schemaToJsonSchema(tool.parameters);\n      result[tool.name] = createVercelAISDKTool({\n        description: tool.description,\n        inputSchema: aiJsonSchema(jsonSchemaObj),\n        execute: tool.execute,\n      });\n    }\n  }\n\n  return result;\n}\n\n/**\n * Context passed to the user-supplied factory function in factory mode.\n */\nexport interface AgentFactoryContext {\n  input: RunAgentInput;\n  /**\n   * Prefer `abortSignal` for most use cases (AI SDK, fetch, custom backends).\n   * Provided for backends like TanStack AI that require the full AbortController.\n   * Do NOT call `.abort()` on this controller — use `abortRun()` on the agent instead.\n   */\n  abortController: AbortController;\n  abortSignal: AbortSignal;\n}\n\n/**\n * Factory config for AI SDK backend.\n * The factory must return an object with a `fullStream` async iterable\n * (compatible with the result of `streamText()` — only `fullStream` is consumed).\n */\nexport interface BuiltInAgentAISDKFactoryConfig {\n  type: \"aisdk\";\n  factory: (\n    ctx: AgentFactoryContext,\n  ) =>\n    | { fullStream: AsyncIterable<unknown> }\n    | Promise<{ fullStream: AsyncIterable<unknown> }>;\n}\n\n/**\n * Factory config for TanStack AI backend.\n * The factory must return an async iterable of TanStack AI stream chunks.\n */\nexport interface BuiltInAgentTanStackFactoryConfig {\n  type: \"tanstack\";\n  factory: (\n    ctx: AgentFactoryContext,\n  ) => AsyncIterable<unknown> | Promise<AsyncIterable<unknown>>;\n}\n\n/**\n * Factory config for a custom backend that directly yields AG-UI events.\n */\nexport interface BuiltInAgentCustomFactoryConfig {\n  type: \"custom\";\n  factory: (\n    ctx: AgentFactoryContext,\n  ) => AsyncIterable<BaseEvent> | Promise<AsyncIterable<BaseEvent>>;\n}\n\n/**\n * Union of all factory-mode configurations.\n */\nexport type BuiltInAgentFactoryConfig =\n  | BuiltInAgentAISDKFactoryConfig\n  | BuiltInAgentTanStackFactoryConfig\n  | BuiltInAgentCustomFactoryConfig;\n\n/**\n * Classic config — BuiltInAgent handles streamText, tools, MCP, state tools, prompt building.\n */\nexport interface BuiltInAgentClassicConfig {\n  /**\n   * The model to use\n   */\n  model: BuiltInAgentModel | LanguageModel;\n  /**\n   * API key for the model provider (OpenAI, Anthropic, Google)\n   * If not provided, falls back to environment variables:\n   * - OPENAI_API_KEY for OpenAI models\n   * - ANTHROPIC_API_KEY for Anthropic models\n   * - GOOGLE_API_KEY for Google models\n   */\n  apiKey?: string;\n  /**\n   * Maximum number of steps/iterations for tool calling (default: 1)\n   */\n  maxSteps?: number;\n  /**\n   * Tool choice setting - how tools are selected for execution (default: \"auto\")\n   */\n  toolChoice?: ToolChoice<Record<string, unknown>>;\n  /**\n   * Maximum number of tokens to generate\n   */\n  maxOutputTokens?: number;\n  /**\n   * Temperature setting (range depends on provider)\n   */\n  temperature?: number;\n  /**\n   * Nucleus sampling (topP)\n   */\n  topP?: number;\n  /**\n   * Top K sampling\n   */\n  topK?: number;\n  /**\n   * Presence penalty\n   */\n  presencePenalty?: number;\n  /**\n   * Frequency penalty\n   */\n  frequencyPenalty?: number;\n  /**\n   * Sequences that will stop the generation\n   */\n  stopSequences?: string[];\n  /**\n   * Seed for deterministic results\n   */\n  seed?: number;\n  /**\n   * Maximum number of retries\n   */\n  maxRetries?: number;\n  /**\n   * Prompt for the agent\n   */\n  prompt?: string;\n  /**\n   * List of properties that can be overridden by forwardedProps.\n   */\n  overridableProperties?: OverridableProperty[];\n  /**\n   * Optional list of MCP server configurations\n   */\n  mcpServers?: MCPClientConfig[];\n  /**\n   * Optional list of user-managed MCP clients.\n   * Unlike mcpServers, the agent does NOT create or close these clients.\n   * The user controls the lifecycle, persistence, auth, and caching.\n   *\n   * Compatible with @ai-sdk/mcp's createMCPClient() return type:\n   * ```typescript\n   * const client = await createMCPClient({ transport });\n   * const agent = new BuiltInAgent({ model: \"...\", mcpClients: [client] });\n   * ```\n   */\n  mcpClients?: MCPClientProvider[];\n  /**\n   * Optional tools available to the agent\n   */\n  tools?: ToolDefinition[];\n  /**\n   * Forward system-role messages from input to the LLM.\n   * Default: false\n   */\n  forwardSystemMessages?: boolean;\n  /**\n   * Forward developer-role messages from input to the LLM (as system messages).\n   * Default: false\n   */\n  forwardDeveloperMessages?: boolean;\n  /**\n   * Provider-specific options passed to the model (e.g., OpenAI reasoningEffort).\n   * Example: `{ openai: { reasoningEffort: \"high\" } }`\n   */\n  providerOptions?: Record<string, any>;\n}\n\n/**\n * Configuration for BuiltInAgent.\n *\n * Two modes:\n * - **Classic** (model + params): BuiltInAgent handles everything — streamText, tools, MCP, state tools.\n * - **Factory** (type + factory): You own the LLM call. BuiltInAgent handles lifecycle only.\n */\nexport type BuiltInAgentConfiguration =\n  | BuiltInAgentClassicConfig\n  | BuiltInAgentFactoryConfig;\n\n/**\n * Type guard: returns true if this is a factory-mode config.\n */\nfunction isFactoryConfig(\n  config: BuiltInAgentConfiguration,\n): config is BuiltInAgentFactoryConfig {\n  return \"factory\" in config;\n}\n\nexport class BuiltInAgent extends AbstractAgent {\n  private abortController?: AbortController;\n\n  constructor(private config: BuiltInAgentConfiguration) {\n    super();\n  }\n\n  /**\n   * Check if a property can be overridden by forwardedProps\n   */\n  canOverride(property: OverridableProperty): boolean {\n    if (isFactoryConfig(this.config)) return false;\n    return this.config?.overridableProperties?.includes(property) ?? false;\n  }\n\n  run(input: RunAgentInput): Observable<BaseEvent> {\n    if (isFactoryConfig(this.config)) {\n      return this.runFactory(input, this.config);\n    }\n\n    if (this.abortController) {\n      throw new Error(\n        \"Agent is already running. Call abortRun() first or create a new instance.\",\n      );\n    }\n\n    // Set synchronously before Observable creation to close TOCTOU window\n    this.abortController = new AbortController();\n    const abortController = this.abortController;\n\n    return new Observable<BaseEvent>((subscriber) => {\n      // Emit RUN_STARTED event\n      const startEvent: RunStartedEvent = {\n        type: EventType.RUN_STARTED,\n        threadId: input.threadId,\n        runId: input.runId,\n      };\n      subscriber.next(startEvent);\n\n      // Resolve the model, passing API key if provided\n      const model = resolveModel(this.config.model, this.config.apiKey);\n\n      // Build prompt based on conditions\n      let systemPrompt: string | undefined = undefined;\n\n      // Check if we should build a prompt:\n      // - config.prompt is set, OR\n      // - input.context is non-empty, OR\n      // - input.state is non-empty and not an empty object\n      const hasPrompt = !!this.config.prompt;\n      const hasContext = input.context && input.context.length > 0;\n      const hasState =\n        input.state !== undefined &&\n        input.state !== null &&\n        !(\n          typeof input.state === \"object\" &&\n          Object.keys(input.state).length === 0\n        );\n\n      if (hasPrompt || hasContext || hasState) {\n        const parts: string[] = [];\n\n        // First: the prompt if any\n        if (hasPrompt) {\n          parts.push(this.config.prompt!);\n        }\n\n        // Second: context from the application\n        if (hasContext) {\n          parts.push(\"\\n## Context from the application\\n\");\n          for (const ctx of input.context) {\n            parts.push(`${ctx.description}:\\n${ctx.value}\\n`);\n          }\n        }\n\n        // Third: state from the application that can be edited\n        if (hasState) {\n          parts.push(\n            \"\\n## Application State\\n\" +\n              \"This is state from the application that you can edit by calling AGUISendStateSnapshot or AGUISendStateDelta.\\n\" +\n              `\\`\\`\\`json\\n${JSON.stringify(input.state, null, 2)}\\n\\`\\`\\`\\n`,\n          );\n        }\n\n        systemPrompt = parts.join(\"\");\n      }\n\n      // Convert messages and prepend system message if we have a prompt\n      const messages = convertMessagesToVercelAISDKMessages(input.messages, {\n        forwardSystemMessages: this.config.forwardSystemMessages,\n        forwardDeveloperMessages: this.config.forwardDeveloperMessages,\n      });\n      if (systemPrompt) {\n        messages.unshift({\n          role: \"system\",\n          content: systemPrompt,\n        });\n      }\n\n      // Merge tools from input and config\n      let allTools: ToolSet = convertToolsToVercelAITools(input.tools);\n      if (this.config.tools && this.config.tools.length > 0) {\n        const configTools = convertToolDefinitionsToVercelAITools(\n          this.config.tools,\n        );\n        allTools = { ...allTools, ...configTools };\n      }\n\n      const streamTextParams: Parameters<typeof streamText>[0] = {\n        model,\n        messages,\n        tools: allTools,\n        toolChoice: this.config.toolChoice,\n        stopWhen: this.config.maxSteps\n          ? stepCountIs(this.config.maxSteps)\n          : undefined,\n        maxOutputTokens: this.config.maxOutputTokens,\n        temperature: this.config.temperature,\n        topP: this.config.topP,\n        topK: this.config.topK,\n        presencePenalty: this.config.presencePenalty,\n        frequencyPenalty: this.config.frequencyPenalty,\n        stopSequences: this.config.stopSequences,\n        seed: this.config.seed,\n        providerOptions: this.config.providerOptions,\n        maxRetries: this.config.maxRetries,\n      };\n\n      // Apply forwardedProps overrides (if allowed)\n      if (input.forwardedProps && typeof input.forwardedProps === \"object\") {\n        const props = input.forwardedProps as Record<string, unknown>;\n\n        // Check and apply each overridable property\n        if (props.model !== undefined && this.canOverride(\"model\")) {\n          if (\n            typeof props.model === \"string\" ||\n            typeof props.model === \"object\"\n          ) {\n            // Accept any string or LanguageModel instance for model override\n            // Use the configured API key when resolving overridden models\n            streamTextParams.model = resolveModel(\n              props.model as string | LanguageModel,\n              this.config.apiKey,\n            );\n          }\n        }\n        if (props.toolChoice !== undefined && this.canOverride(\"toolChoice\")) {\n          // ToolChoice can be 'auto', 'required', 'none', or { type: 'tool', toolName: string }\n          const toolChoice = props.toolChoice;\n          if (\n            toolChoice === \"auto\" ||\n            toolChoice === \"required\" ||\n            toolChoice === \"none\" ||\n            (typeof toolChoice === \"object\" &&\n              toolChoice !== null &&\n              \"type\" in toolChoice &&\n              toolChoice.type === \"tool\")\n          ) {\n            streamTextParams.toolChoice = toolChoice as ToolChoice<\n              Record<string, unknown>\n            >;\n          }\n        }\n        if (\n          typeof props.maxOutputTokens === \"number\" &&\n          this.canOverride(\"maxOutputTokens\")\n        ) {\n          streamTextParams.maxOutputTokens = props.maxOutputTokens;\n        }\n        if (\n          typeof props.temperature === \"number\" &&\n          this.canOverride(\"temperature\")\n        ) {\n          streamTextParams.temperature = props.temperature;\n        }\n        if (typeof props.topP === \"number\" && this.canOverride(\"topP\")) {\n          streamTextParams.topP = props.topP;\n        }\n        if (typeof props.topK === \"number\" && this.canOverride(\"topK\")) {\n          streamTextParams.topK = props.topK;\n        }\n        if (\n          typeof props.presencePenalty === \"number\" &&\n          this.canOverride(\"presencePenalty\")\n        ) {\n          streamTextParams.presencePenalty = props.presencePenalty;\n        }\n        if (\n          typeof props.frequencyPenalty === \"number\" &&\n          this.canOverride(\"frequencyPenalty\")\n        ) {\n          streamTextParams.frequencyPenalty = props.frequencyPenalty;\n        }\n        if (\n          Array.isArray(props.stopSequences) &&\n          this.canOverride(\"stopSequences\")\n        ) {\n          // Validate all elements are strings\n          if (\n            props.stopSequences.every(\n              (item): item is string => typeof item === \"string\",\n            )\n          ) {\n            streamTextParams.stopSequences = props.stopSequences;\n          }\n        }\n        if (typeof props.seed === \"number\" && this.canOverride(\"seed\")) {\n          streamTextParams.seed = props.seed;\n        }\n        if (\n          typeof props.maxRetries === \"number\" &&\n          this.canOverride(\"maxRetries\")\n        ) {\n          streamTextParams.maxRetries = props.maxRetries;\n        }\n        if (\n          props.providerOptions !== undefined &&\n          this.canOverride(\"providerOptions\")\n        ) {\n          if (\n            typeof props.providerOptions === \"object\" &&\n            props.providerOptions !== null\n          ) {\n            streamTextParams.providerOptions = props.providerOptions as Record<\n              string,\n              any\n            >;\n          }\n        }\n      }\n\n      // Set up MCP clients if configured and process the stream\n      const mcpClients: Array<{ close: () => Promise<void> }> = [];\n\n      (async () => {\n        let terminalEventEmitted = false;\n        let messageId = randomUUID();\n        let reasoningMessageId = randomUUID();\n        let isInReasoning = false;\n\n        // Auto-close an open reasoning lifecycle.\n        // Some AI SDK providers (notably @ai-sdk/anthropic) never emit \"reasoning-end\",\n        // which leaves downstream state machines stuck. This helper emits the\n        // missing REASONING_MESSAGE_END + REASONING_END events so the stream\n        // can transition to text, tool-call, or finish phases.\n        // Declared before try/catch so it is accessible in the catch block.\n        const closeReasoningIfOpen = () => {\n          if (!isInReasoning) return;\n          isInReasoning = false;\n          const reasoningMsgEnd: ReasoningMessageEndEvent = {\n            type: EventType.REASONING_MESSAGE_END,\n            messageId: reasoningMessageId,\n          };\n          subscriber.next(reasoningMsgEnd);\n          const reasoningEnd: ReasoningEndEvent = {\n            type: EventType.REASONING_END,\n            messageId: reasoningMessageId,\n          };\n          subscriber.next(reasoningEnd);\n        };\n\n        try {\n          // Add AG-UI state update tools\n          streamTextParams.tools = {\n            ...streamTextParams.tools,\n            AGUISendStateSnapshot: createVercelAISDKTool({\n              description:\n                \"Replace the entire application state with a new snapshot\",\n              inputSchema: z.object({\n                snapshot: z.any().describe(\"The complete new state object\"),\n              }),\n              execute: async ({ snapshot }) => {\n                return { success: true, snapshot };\n              },\n            }),\n            AGUISendStateDelta: createVercelAISDKTool({\n              description:\n                \"Apply incremental updates to application state using JSON Patch operations\",\n              inputSchema: z.object({\n                delta: z\n                  .array(\n                    z.object({\n                      op: z\n                        .enum([\"add\", \"replace\", \"remove\"])\n                        .describe(\"The operation to perform\"),\n                      path: z\n                        .string()\n                        .describe(\"JSON Pointer path (e.g., '/foo/bar')\"),\n                      value: z\n                        .any()\n                        .optional()\n                        .describe(\n                          \"The value to set. Required for 'add' and 'replace' operations, ignored for 'remove'.\",\n                        ),\n                    }),\n                  )\n                  .describe(\"Array of JSON Patch operations\"),\n              }),\n              execute: async ({ delta }) => {\n                return { success: true, delta };\n              },\n            }),\n          };\n\n          // Merge tools from user-managed MCP clients (user controls lifecycle)\n          if (this.config.mcpClients && this.config.mcpClients.length > 0) {\n            for (const client of this.config.mcpClients) {\n              const mcpTools = await client.tools();\n              streamTextParams.tools = {\n                ...streamTextParams.tools,\n                ...mcpTools,\n              } as ToolSet;\n            }\n          }\n\n          // Initialize MCP clients and get their tools\n          if (this.config.mcpServers && this.config.mcpServers.length > 0) {\n            for (const serverConfig of this.config.mcpServers) {\n              let transport;\n\n              if (serverConfig.type === \"http\") {\n                const url = new URL(serverConfig.url);\n                transport = new StreamableHTTPClientTransport(\n                  url,\n                  serverConfig.options,\n                );\n              } else if (serverConfig.type === \"sse\") {\n                transport = new SSEClientTransport(\n                  new URL(serverConfig.url),\n                  serverConfig.headers,\n                );\n              }\n\n              if (transport) {\n                const mcpClient = await createMCPClient({ transport });\n                mcpClients.push(mcpClient);\n\n                // Get tools from this MCP server and merge with existing tools\n                const mcpTools = await mcpClient.tools();\n                streamTextParams.tools = {\n                  ...streamTextParams.tools,\n                  ...mcpTools,\n                } as ToolSet;\n              }\n            }\n          }\n\n          // Call streamText and process the stream\n          const response = streamText({\n            ...streamTextParams,\n            abortSignal: abortController.signal,\n          });\n\n          const toolCallStates = new Map<\n            string,\n            {\n              started: boolean;\n              hasArgsDelta: boolean;\n              ended: boolean;\n              toolName?: string;\n            }\n          >();\n\n          const ensureToolCallState = (toolCallId: string) => {\n            let state = toolCallStates.get(toolCallId);\n            if (!state) {\n              state = { started: false, hasArgsDelta: false, ended: false };\n              toolCallStates.set(toolCallId, state);\n            }\n            return state;\n          };\n\n          // Process fullStream events\n          for await (const part of response.fullStream) {\n            // Close any open reasoning lifecycle on every event except\n            // reasoning-delta, which arrives mid-block and must not interrupt it.\n            if (part.type !== \"reasoning-delta\") {\n              closeReasoningIfOpen();\n            }\n\n            switch (part.type) {\n              case \"abort\": {\n                const abortEndEvent: RunFinishedEvent = {\n                  type: EventType.RUN_FINISHED,\n                  threadId: input.threadId,\n                  runId: input.runId,\n                };\n                subscriber.next(abortEndEvent);\n                terminalEventEmitted = true;\n\n                // Complete the observable\n                subscriber.complete();\n                break;\n              }\n              case \"reasoning-start\": {\n                // Use SDK-provided id, or generate a fresh UUID if id is falsy/\"0\"\n                // to prevent consecutive reasoning blocks from sharing a messageId\n                const providedId = \"id\" in part ? part.id : undefined;\n                reasoningMessageId =\n                  providedId && providedId !== \"0\"\n                    ? (providedId as typeof reasoningMessageId)\n                    : randomUUID();\n                const reasoningStartEvent: ReasoningStartEvent = {\n                  type: EventType.REASONING_START,\n                  messageId: reasoningMessageId,\n                };\n                subscriber.next(reasoningStartEvent);\n                const reasoningMessageStart: ReasoningMessageStartEvent = {\n                  type: EventType.REASONING_MESSAGE_START,\n                  messageId: reasoningMessageId,\n                  role: \"reasoning\",\n                };\n                subscriber.next(reasoningMessageStart);\n                isInReasoning = true;\n                break;\n              }\n              case \"reasoning-delta\": {\n                const delta = part.text ?? \"\";\n                if (!delta) break; // skip — @ag-ui/core schema requires delta to be non-empty\n                const reasoningDeltaEvent: ReasoningMessageContentEvent = {\n                  type: EventType.REASONING_MESSAGE_CONTENT,\n                  messageId: reasoningMessageId,\n                  delta,\n                };\n                subscriber.next(reasoningDeltaEvent);\n                break;\n              }\n              case \"reasoning-end\": {\n                // closeReasoningIfOpen() already called before the switch — no-op here\n                // if the SDK never emits this event (e.g. @ai-sdk/anthropic).\n                break;\n              }\n              case \"tool-input-start\": {\n                const toolCallId = part.id;\n                const state = ensureToolCallState(toolCallId);\n                state.toolName = part.toolName;\n                if (!state.started) {\n                  state.started = true;\n                  const startEvent: ToolCallStartEvent = {\n                    type: EventType.TOOL_CALL_START,\n                    parentMessageId: messageId,\n                    toolCallId,\n                    toolCallName: part.toolName,\n                  };\n                  subscriber.next(startEvent);\n                }\n                break;\n              }\n\n              case \"tool-input-delta\": {\n                const toolCallId = part.id;\n                const state = ensureToolCallState(toolCallId);\n                state.hasArgsDelta = true;\n                const argsEvent: ToolCallArgsEvent = {\n                  type: EventType.TOOL_CALL_ARGS,\n                  toolCallId,\n                  delta: part.delta,\n                };\n                subscriber.next(argsEvent);\n                break;\n              }\n\n              case \"tool-input-end\": {\n                // No direct event – the subsequent \"tool-call\" part marks completion.\n                break;\n              }\n\n              case \"text-start\": {\n                // New text message starting - use the SDK-provided id\n                // Use randomUUID() if part.id is falsy or \"0\" to prevent message merging issues\n                const providedId = \"id\" in part ? part.id : undefined;\n                messageId =\n                  providedId && providedId !== \"0\"\n                    ? (providedId as typeof messageId)\n                    : randomUUID();\n                break;\n              }\n\n              case \"text-delta\": {\n                // Accumulate text content - in AI SDK 5.0, the property is 'text'\n                const textDelta = \"text\" in part ? part.text : \"\";\n                // Emit text chunk event\n                const textEvent: TextMessageChunkEvent = {\n                  type: EventType.TEXT_MESSAGE_CHUNK,\n                  role: \"assistant\",\n                  messageId,\n                  delta: textDelta,\n                };\n                subscriber.next(textEvent);\n                break;\n              }\n\n              case \"tool-call\": {\n                const toolCallId = part.toolCallId;\n                const state = ensureToolCallState(toolCallId);\n                state.toolName = part.toolName ?? state.toolName;\n\n                if (!state.started) {\n                  state.started = true;\n                  const startEvent: ToolCallStartEvent = {\n                    type: EventType.TOOL_CALL_START,\n                    parentMessageId: messageId,\n                    toolCallId,\n                    toolCallName: part.toolName,\n                  };\n                  subscriber.next(startEvent);\n                }\n\n                if (\n                  !state.hasArgsDelta &&\n                  \"input\" in part &&\n                  part.input !== undefined\n                ) {\n                  let serializedInput = \"\";\n                  if (typeof part.input === \"string\") {\n                    serializedInput = part.input;\n                  } else {\n                    try {\n                      serializedInput = JSON.stringify(part.input);\n                    } catch {\n                      serializedInput = String(part.input);\n                    }\n                  }\n\n                  if (serializedInput.length > 0) {\n                    const argsEvent: ToolCallArgsEvent = {\n                      type: EventType.TOOL_CALL_ARGS,\n                      toolCallId,\n                      delta: serializedInput,\n                    };\n                    subscriber.next(argsEvent);\n                    state.hasArgsDelta = true;\n                  }\n                }\n\n                if (!state.ended) {\n                  state.ended = true;\n                  const endEvent: ToolCallEndEvent = {\n                    type: EventType.TOOL_CALL_END,\n                    toolCallId,\n                  };\n                  subscriber.next(endEvent);\n                }\n                break;\n              }\n\n              case \"tool-result\": {\n                const toolResult =\n                  \"output\" in part\n                    ? part.output\n                    : \"result\" in part\n                      ? part.result\n                      : null;\n                const toolName = \"toolName\" in part ? part.toolName : \"\";\n                toolCallStates.delete(part.toolCallId);\n\n                // Check if this is a state update tool\n                if (\n                  toolName === \"AGUISendStateSnapshot\" &&\n                  toolResult &&\n                  typeof toolResult === \"object\"\n                ) {\n                  const snapshot = toolResult.snapshot;\n                  if (snapshot !== undefined) {\n                    const stateSnapshotEvent: StateSnapshotEvent = {\n                      type: EventType.STATE_SNAPSHOT,\n                      snapshot,\n                    };\n                    subscriber.next(stateSnapshotEvent);\n                  }\n                } else if (\n                  toolName === \"AGUISendStateDelta\" &&\n                  toolResult &&\n                  typeof toolResult === \"object\"\n                ) {\n                  const delta = toolResult.delta;\n                  if (delta !== undefined) {\n                    const stateDeltaEvent: StateDeltaEvent = {\n                      type: EventType.STATE_DELTA,\n                      delta,\n                    };\n                    subscriber.next(stateDeltaEvent);\n                  }\n                }\n\n                // Always emit the tool result event for the LLM\n                let serializedResult: string;\n                try {\n                  serializedResult = JSON.stringify(toolResult);\n                } catch {\n                  serializedResult = `[Unserializable tool result from ${toolName || part.toolCallId}]`;\n                }\n                const resultEvent: ToolCallResultEvent = {\n                  type: EventType.TOOL_CALL_RESULT,\n                  role: \"tool\",\n                  messageId: randomUUID(),\n                  toolCallId: part.toolCallId,\n                  content: serializedResult,\n                };\n                subscriber.next(resultEvent);\n                break;\n              }\n\n              case \"finish\": {\n                // Emit run finished event\n                const finishedEvent: RunFinishedEvent = {\n                  type: EventType.RUN_FINISHED,\n                  threadId: input.threadId,\n                  runId: input.runId,\n                };\n                subscriber.next(finishedEvent);\n                terminalEventEmitted = true;\n\n                // Complete the observable\n                subscriber.complete();\n                break;\n              }\n\n              case \"error\": {\n                if (abortController.signal.aborted) {\n                  break;\n                }\n                const err = part.error ?? part.message ?? part.cause;\n                const runErrorEvent: RunErrorEvent = {\n                  type: EventType.RUN_ERROR,\n                  message:\n                    err instanceof Error\n                      ? err.message\n                      : typeof err === \"string\"\n                        ? err\n                        : `AI SDK stream error: ${JSON.stringify(part)}`,\n                  threadId: input.threadId,\n                  runId: input.runId,\n                } as RunErrorEvent;\n                subscriber.next(runErrorEvent);\n                terminalEventEmitted = true;\n\n                // Handle error\n                if (err instanceof Error) subscriber.error(err);\n                else\n                  subscriber.error(\n                    new Error(\n                      typeof err === \"string\" ? err : `AI SDK stream error`,\n                    ),\n                  );\n                break;\n              }\n            }\n          }\n\n          if (!terminalEventEmitted) {\n            closeReasoningIfOpen();\n            if (abortController.signal.aborted) {\n              // Let the runner finalize the stream on stop requests so it can\n              // inject consistent closing events and a RUN_FINISHED marker.\n            } else {\n              const finishedEvent: RunFinishedEvent = {\n                type: EventType.RUN_FINISHED,\n                threadId: input.threadId,\n                runId: input.runId,\n              };\n              subscriber.next(finishedEvent);\n            }\n\n            terminalEventEmitted = true;\n            subscriber.complete();\n          }\n        } catch (error) {\n          closeReasoningIfOpen();\n          if (abortController.signal.aborted) {\n            subscriber.complete();\n          } else {\n            const runErrorEvent: RunErrorEvent = {\n              type: EventType.RUN_ERROR,\n              message: error instanceof Error ? error.message : String(error),\n              threadId: input.threadId,\n              runId: input.runId,\n            } as RunErrorEvent;\n            subscriber.next(runErrorEvent);\n            terminalEventEmitted = true;\n            subscriber.error(error);\n          }\n        } finally {\n          this.abortController = undefined;\n          await Promise.all(mcpClients.map((client) => client.close()));\n        }\n      })();\n\n      // Cleanup function\n      return () => {\n        // Cleanup MCP clients if stream is unsubscribed\n        Promise.all(mcpClients.map((client) => client.close())).catch(() => {\n          // Ignore cleanup errors\n        });\n      };\n    });\n  }\n\n  private runFactory(\n    input: RunAgentInput,\n    config: BuiltInAgentFactoryConfig,\n  ): Observable<BaseEvent> {\n    if (this.abortController) {\n      throw new Error(\n        \"Agent is already running. Call abortRun() first or create a new instance.\",\n      );\n    }\n\n    // Set synchronously before Observable creation to close TOCTOU window\n    this.abortController = new AbortController();\n    const controller = this.abortController;\n\n    return new Observable<BaseEvent>((subscriber) => {\n      const startEvent: RunStartedEvent = {\n        type: EventType.RUN_STARTED,\n        threadId: input.threadId,\n        runId: input.runId,\n      };\n      subscriber.next(startEvent);\n\n      const ctx: AgentFactoryContext = {\n        input,\n        abortController: controller,\n        abortSignal: controller.signal,\n      };\n\n      (async () => {\n        try {\n          let events: AsyncIterable<BaseEvent>;\n\n          switch (config.type) {\n            case \"aisdk\": {\n              const result = await config.factory(ctx);\n              events = convertAISDKStream(result.fullStream, controller.signal);\n              break;\n            }\n            case \"tanstack\": {\n              const stream = await config.factory(ctx);\n              events = convertTanStackStream(stream, controller.signal);\n              break;\n            }\n            case \"custom\": {\n              events = await config.factory(ctx);\n              break;\n            }\n            default: {\n              const _exhaustive: never = config;\n              throw new Error(\n                `Unknown agent config type: ${(_exhaustive as BuiltInAgentFactoryConfig).type}`,\n              );\n            }\n          }\n\n          for await (const event of events) {\n            subscriber.next(event);\n          }\n\n          if (!controller.signal.aborted) {\n            const finishedEvent: RunFinishedEvent = {\n              type: EventType.RUN_FINISHED,\n              threadId: input.threadId,\n              runId: input.runId,\n            };\n            subscriber.next(finishedEvent);\n          }\n          subscriber.complete();\n        } catch (error) {\n          if (controller.signal.aborted) {\n            subscriber.complete();\n          } else {\n            const runErrorEvent: RunErrorEvent = {\n              type: EventType.RUN_ERROR,\n              message: error instanceof Error ? error.message : String(error),\n              threadId: input.threadId,\n              runId: input.runId,\n            } as RunErrorEvent;\n            subscriber.next(runErrorEvent);\n            subscriber.error(error);\n          }\n        } finally {\n          this.abortController = undefined;\n        }\n      })();\n\n      return () => {\n        controller.abort();\n      };\n    });\n  }\n\n  clone() {\n    const cloned = new BuiltInAgent(this.config);\n    // AbstractAgent.middlewares is private in @ag-ui/client — no public accessor exists.\n    // This coupling is intentional: clone() must preserve middleware chains.\n    // @ts-expect-error accessing private AbstractAgent.middlewares\n    cloned.middlewares = [...this.middlewares];\n    return cloned;\n  }\n\n  abortRun(): void {\n    this.abortController?.abort();\n  }\n}\n\n/**\n * @deprecated Use BuiltInAgent instead\n */\nexport class BasicAgent extends BuiltInAgent {\n  constructor(config: BuiltInAgentConfiguration) {\n    super(config);\n    console.warn(\"BasicAgent is deprecated, use BuiltInAgent instead\");\n  }\n}\n\n/** @deprecated Use BuiltInAgentClassicConfig instead */\nexport type BasicAgentConfiguration = BuiltInAgentClassicConfig;\n\nexport * from \"./converters\";\n"],"mappings":"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"}