{"version":3,"sources":["../../shared/src/utils/tool-utils.ts","../../shared/src/utils/warnings.ts","../../shared/src/tool-calling/build-json-system-prompt.ts","../../shared/src/tool-calling/format-tool-results.ts","../../shared/src/tool-calling/parse-json-function-calls.ts","../../shared/src/streaming/tool-call-detector.ts","../../shared/src/streaming/tool-call-stream-utils.ts","../../shared/src/streaming/stream-processor.ts","../src/utils/convert-to-browser-ai-messages.ts","../src/utils/warnings.ts","../src/utils/prompt-utils.ts","../src/chat/session-manager.ts","../src/chat/browser-ai-language-model.ts","../src/embedding/browser-ai-embedding-model.ts","../src/browser-ai-provider.ts"],"sourcesContent":["/**\n * Utilities for working with AI SDK tools\n */\n\nimport type {\n  LanguageModelV3FunctionTool,\n  LanguageModelV3ProviderTool,\n} from \"@ai-sdk/provider\";\n\n/**\n * Type guard to check if a tool is a function tool\n *\n * @param tool - The tool to check\n * @returns true if the tool is a LanguageModelV3FunctionTool\n */\nexport function isFunctionTool(\n  tool: LanguageModelV3FunctionTool | LanguageModelV3ProviderTool,\n): tool is LanguageModelV3FunctionTool {\n  return tool.type === \"function\";\n}\n","/**\n * Warning generation utilities for unsupported settings and tools\n */\n\nimport type {\n  SharedV3Warning,\n  LanguageModelV3ProviderTool,\n} from \"@ai-sdk/provider\";\n\n/**\n * Creates a warning for an unsupported setting\n *\n * @param setting - Name of the setting that is not supported\n * @param details - Additional details about why it's not supported\n * @returns A call warning object\n *\n * @example\n * ```typescript\n * const warning = createUnsupportedSettingWarning(\n *   \"maxOutputTokens\",\n *   \"maxOutputTokens is not supported by this provider\"\n * );\n * ```\n */\nexport function createUnsupportedSettingWarning(\n  feature: string,\n  details: string,\n): SharedV3Warning {\n  return {\n    type: \"unsupported\",\n    feature,\n    details,\n  };\n}\n\n/**\n * Creates a warning for an unsupported tool type\n *\n * @param tool - The provider-defined tool that is not supported\n * @param details - Additional details about why it's not supported\n * @returns A call warning object\n *\n * @example\n * ```typescript\n * const warning = createUnsupportedToolWarning(\n *   providerTool,\n *   \"Only function tools are supported\"\n * );\n * ```\n */\nexport function createUnsupportedToolWarning(\n  tool: LanguageModelV3ProviderTool,\n  details: string,\n): SharedV3Warning {\n  return {\n    type: \"unsupported\",\n    feature: `tool:${tool.name}`,\n    details,\n  };\n}\n","import type {\n  JSONSchema7,\n  LanguageModelV3FunctionTool,\n} from \"@ai-sdk/provider\";\nimport type { ToolDefinition } from \"../types\";\n\n/**\n * Builds an enhanced system prompt for JSON-based tool calling.\n * The model receives JSON schemas and is expected to return JSON tool calls.\n *\n * @param originalSystemPrompt - The original system prompt (if any)\n * @param tools - Array of available tool definitions\n * @param options - Configuration options for tool calling behavior (unused, kept for backwards compatibility)\n * @returns Enhanced system prompt with JSON tool calling instructions\n */\nexport function buildJsonToolSystemPrompt(\n  originalSystemPrompt: string | undefined,\n  tools: Array<ToolDefinition | LanguageModelV3FunctionTool>,\n  options?: { allowParallelToolCalls?: boolean },\n): string {\n  if (!tools || tools.length === 0) {\n    return originalSystemPrompt || \"\";\n  }\n\n  const parallelInstruction =\n    \"Only request one tool call at a time. Wait for tool results before asking for another tool.\";\n\n  const toolSchemas = tools.map((tool) => {\n    const schema = getParameters(tool);\n    return {\n      name: tool.name,\n      description: tool.description ?? \"No description provided.\",\n      parameters: schema || { type: \"object\", properties: {} },\n    };\n  });\n\n  const toolsJson = JSON.stringify(toolSchemas, null, 2);\n\n  const instructionBody = `You are a helpful AI assistant with access to tools.\n\n# Available Tools\n${toolsJson}\n\n# Tool Calling Instructions\n${parallelInstruction}\n\nTo call a tool, output JSON in this exact format inside a \\`\\`\\`tool_call code fence:\n\n\\`\\`\\`tool_call\n{\"name\": \"tool_name\", \"arguments\": {\"param1\": \"value1\", \"param2\": \"value2\"}}\n\\`\\`\\`\n\nTool responses will be provided in \\`\\`\\`tool_result fences. Each line contains JSON like:\n\\`\\`\\`tool_result\n{\"id\": \"call_123\", \"name\": \"tool_name\", \"result\": {...}, \"error\": false}\n\\`\\`\\`\nUse the \\`result\\` payload (and treat \\`error\\` as a boolean flag) when continuing the conversation.\n\nImportant:\n- Use exact tool and parameter names from the schema above\n- Arguments must be a valid JSON object matching the tool's parameters\n- You can include brief reasoning before or after the tool call\n- If no tool is needed, respond directly without tool_call fences`;\n\n  if (originalSystemPrompt?.trim()) {\n    return `${originalSystemPrompt.trim()}\\n\\n${instructionBody}`;\n  }\n\n  return instructionBody;\n}\n\n/**\n * Extracts the parameters/input schema from a tool definition.\n * Handles both ToolDefinition (parameters field) and LanguageModelV3FunctionTool (inputSchema field).\n *\n * @param tool - The tool definition to extract parameters from\n * @returns The JSON Schema for the tool's parameters, or undefined if not present\n */\nfunction getParameters(\n  tool: ToolDefinition | LanguageModelV3FunctionTool,\n): JSONSchema7 | undefined {\n  if (\"parameters\" in tool) {\n    return tool.parameters;\n  }\n\n  return tool.inputSchema as JSONSchema7 | undefined;\n}\n","import type { ToolResult } from \"../types\";\n\n/**\n * Builds a JSON-serializable payload for a single tool result.\n * Includes tool name, result data, error flag, and optional call ID.\n *\n * @param result - The tool execution result to format\n * @returns Object containing formatted result data ready for JSON serialization\n */\nfunction buildResultPayload(result: ToolResult): Record<string, unknown> {\n  const payload: Record<string, unknown> = {\n    name: result.toolName,\n    result: result.result ?? null,\n    error: Boolean(result.isError),\n  };\n\n  if (result.toolCallId) {\n    payload.id = result.toolCallId;\n  }\n\n  return payload;\n}\n\n/**\n * Formats tool execution results as JSON for continuation in the conversation.\n *\n * Each result is serialized as a single JSON object. Multiple results (for parallel\n * execution scenarios) are emitted on separate lines within a ```tool_result code fence.\n *\n * @param results - Array of tool execution results to format\n * @returns Formatted string with results in tool_result code fence, or empty string if no results\n * @example\n * ```typescript\n * formatToolResults([\n *   { toolCallId: \"call_123\", toolName: \"search\", result: { data: \"...\" } }\n * ])\n * // Returns: ```tool_result\\n{\"id\":\"call_123\",\"name\":\"search\",\"result\":{...},\"error\":false}\\n```\n * ```\n */\nexport function formatToolResults(results: ToolResult[]): string {\n  if (!results || results.length === 0) {\n    return \"\";\n  }\n\n  const payloads = results.map((result) =>\n    JSON.stringify(buildResultPayload(result)),\n  );\n\n  return `\\`\\`\\`tool_result\n${payloads.join(\"\\n\")}\n\\`\\`\\``;\n}\n\n/**\n * Formats a single tool result.\n * Convenience wrapper around formatToolResults for single result scenarios.\n *\n * @param result - The tool execution result to format\n * @returns Formatted string with result in tool_result code fence\n */\nexport function formatSingleToolResult(result: ToolResult): string {\n  return formatToolResults([result]);\n}\n","import type { ParsedResponse, ParsedToolCall } from \"../types\";\n\n/**\n * Options for configuring the JSON function call parser\n */\nexport interface ParseJsonFunctionCallsOptions {\n  /** Support XML-style tags: <tool_call>...</tool_call> */\n  supportXmlTags?: boolean;\n  /** Support Python-style: [functionName(arg=\"value\")] */\n  supportPythonStyle?: boolean;\n  /** Support \"parameters\" as alias for \"arguments\" (Llama format) */\n  supportParametersField?: boolean;\n  /** Support call:name{key:value} style delimited with <|tool_call>...<tool_call|> */\n  supportCallColonStyle?: boolean;\n}\n\nconst DEFAULT_OPTIONS: ParseJsonFunctionCallsOptions = {\n  supportXmlTags: true,\n  supportPythonStyle: true,\n  supportParametersField: true,\n  supportCallColonStyle: true,\n};\n\nfunction generateToolCallId(): string {\n  return `call_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\n}\n\n/**\n * Parses key:value parameter pairs from the call:name{key:value,...} format.\n * Values are coerced to numbers/booleans/null when possible.\n */\nfunction parseCallColonParams(params: string): Record<string, unknown> {\n  const args: Record<string, unknown> = {};\n  if (!params || !params.trim()) return args;\n\n  const pairs = params.split(\",\").map((s) => s.trim());\n  for (const pair of pairs) {\n    const colonIndex = pair.indexOf(\":\");\n    if (colonIndex > 0) {\n      const key = pair.substring(0, colonIndex).trim();\n      const rawValue = pair.substring(colonIndex + 1).trim();\n      if (rawValue === \"true\") {\n        args[key] = true;\n      } else if (rawValue === \"false\") {\n        args[key] = false;\n      } else if (rawValue === \"null\") {\n        args[key] = null;\n      } else {\n        const numValue = Number(rawValue);\n        args[key] = !isNaN(numValue) && rawValue !== \"\" ? numValue : rawValue;\n      }\n    }\n  }\n  return args;\n}\n\nfunction buildRegex(options: ParseJsonFunctionCallsOptions): RegExp {\n  const patterns: string[] = [];\n\n  // Always support markdown fences\n  patterns.push(\"```tool[_-]?call\\\\s*([\\\\s\\\\S]*?)```\");\n\n  if (options.supportXmlTags) {\n    patterns.push(\"<tool_call>\\\\s*([\\\\s\\\\S]*?)\\\\s*</tool_call>\");\n  }\n\n  if (options.supportPythonStyle) {\n    patterns.push(\"\\\\[(\\\\w+)\\\\(([^)]*)\\\\)\\\\]\");\n  }\n\n  if (options.supportCallColonStyle) {\n    patterns.push(\"<\\\\|tool_call>\\\\s*([\\\\s\\\\S]*?)\\\\s*<tool_call\\\\|>\");\n  }\n\n  return new RegExp(patterns.join(\"|\"), \"gi\");\n}\n\n/**\n * Parses JSON-formatted tool calls from model response.\n * Supports multiple formats:\n * 1. Single object: {\"name\": \"tool\", \"arguments\": {...}} or {\"name\": \"tool\", \"parameters\": {...}}\n * 2. Array: [{\"name\": \"tool1\", ...}, {\"name\": \"tool2\", ...}]\n * 3. Newline-separated objects:\n *    {\"name\": \"tool1\", \"arguments\": {...}}\n *    {\"name\": \"tool2\", \"arguments\": {...}}\n *\n * Note: Handles both \"arguments\" (OpenAI/Mistral format) and \"parameters\" (Llama format)\n *\n * @param response - The model's response text to parse\n * @param options - Configuration options for parsing\n * @returns Object containing parsed tool calls and remaining text content\n */\nexport function parseJsonFunctionCalls(\n  response: string,\n  options: ParseJsonFunctionCallsOptions = DEFAULT_OPTIONS,\n): ParsedResponse {\n  const mergedOptions = { ...DEFAULT_OPTIONS, ...options };\n  const regex = buildRegex(mergedOptions);\n\n  const matches = Array.from(response.matchAll(regex));\n  regex.lastIndex = 0;\n\n  if (matches.length === 0) {\n    return { toolCalls: [], textContent: response };\n  }\n\n  const toolCalls: ParsedToolCall[] = [];\n  let textContent = response;\n\n  for (const match of matches) {\n    const fullMatch = match[0];\n    textContent = textContent.replace(fullMatch, \"\");\n\n    try {\n      // Check for Python-style match: [functionName(args)]\n      if (mergedOptions.supportPythonStyle && match[0].startsWith(\"[\")) {\n        const pythonMatch = /\\[(\\w+)\\(([^)]*)\\)\\]/.exec(match[0]);\n        if (pythonMatch) {\n          const [, funcName, pythonArgs] = pythonMatch;\n          const args: Record<string, unknown> = {};\n\n          if (pythonArgs && pythonArgs.trim()) {\n            const argPairs = pythonArgs.split(\",\").map((s) => s.trim());\n            for (const pair of argPairs) {\n              const equalIndex = pair.indexOf(\"=\");\n              if (equalIndex > 0) {\n                const key = pair.substring(0, equalIndex).trim();\n                let value = pair.substring(equalIndex + 1).trim();\n                if (\n                  (value.startsWith('\"') && value.endsWith('\"')) ||\n                  (value.startsWith(\"'\") && value.endsWith(\"'\"))\n                ) {\n                  value = value.substring(1, value.length - 1);\n                }\n                args[key] = value;\n              }\n            }\n          }\n\n          toolCalls.push({\n            type: \"tool-call\",\n            toolCallId: generateToolCallId(),\n            toolName: funcName,\n            args: args,\n          });\n          continue;\n        }\n      }\n\n      // Check for call:name{params} style (inside <|tool_call> delimiters)\n      if (mergedOptions.supportCallColonStyle) {\n        const callMatch = fullMatch.match(/call:(\\w+)\\{([^}]*)\\}/);\n        if (callMatch) {\n          const [, funcName, params] = callMatch;\n          toolCalls.push({\n            type: \"tool-call\",\n            toolCallId: generateToolCallId(),\n            toolName: funcName,\n            args: parseCallColonParams(params),\n          });\n          continue;\n        }\n      }\n\n      // Get the captured content from the first capturing group\n      const innerContent = match.slice(1).find((g) => g !== undefined) || \"\";\n      const trimmed = innerContent.trim();\n\n      if (!trimmed) continue;\n\n      // Try parsing as a single JSON value first (object or array)\n      try {\n        const parsed = JSON.parse(trimmed);\n        const callsArray = Array.isArray(parsed) ? parsed : [parsed];\n\n        for (const call of callsArray) {\n          if (!call.name) continue;\n\n          let args =\n            call.arguments ||\n            (mergedOptions.supportParametersField ? call.parameters : null) ||\n            {};\n\n          // If args is a string, try to parse it as JSON\n          if (typeof args === \"string\") {\n            try {\n              args = JSON.parse(args);\n            } catch {\n              // If parsing fails, keep it as string\n            }\n          }\n\n          toolCalls.push({\n            type: \"tool-call\",\n            toolCallId: call.id || generateToolCallId(),\n            toolName: call.name,\n            args: args,\n          });\n        }\n      } catch {\n        // If single JSON parsing fails, try parsing as newline-separated JSON objects\n        const lines = trimmed.split(\"\\n\").filter((line) => line.trim());\n\n        for (const line of lines) {\n          try {\n            const call = JSON.parse(line.trim());\n            if (!call.name) continue;\n\n            let args =\n              call.arguments ||\n              (mergedOptions.supportParametersField ? call.parameters : null) ||\n              {};\n\n            if (typeof args === \"string\") {\n              try {\n                args = JSON.parse(args);\n              } catch {\n                // If parsing fails, keep it as string\n              }\n            }\n\n            toolCalls.push({\n              type: \"tool-call\",\n              toolCallId: call.id || generateToolCallId(),\n              toolName: call.name,\n              args: args,\n            });\n          } catch {\n            // Skip invalid JSON lines\n            continue;\n          }\n        }\n      }\n    } catch (error) {\n      console.warn(\"Failed to parse JSON tool call:\", error);\n      continue;\n    }\n  }\n\n  textContent = textContent.replace(/\\n{2,}/g, \"\\n\");\n\n  return { toolCalls, textContent: textContent.trim() };\n}\n\n/**\n * Checks if a response contains JSON function calls\n */\nexport function hasJsonFunctionCalls(\n  response: string,\n  options: ParseJsonFunctionCallsOptions = DEFAULT_OPTIONS,\n): boolean {\n  const regex = buildRegex({ ...DEFAULT_OPTIONS, ...options });\n  const hasMatch = regex.test(response);\n  regex.lastIndex = 0;\n  return hasMatch;\n}\n\n/**\n * Extracts the first JSON function call block from a response\n */\nexport function extractJsonFunctionCallsBlock(\n  response: string,\n  options: ParseJsonFunctionCallsOptions = DEFAULT_OPTIONS,\n): string | null {\n  const regex = buildRegex({ ...DEFAULT_OPTIONS, ...options });\n  const match = regex.exec(response);\n  regex.lastIndex = 0;\n  return match ? match[0] : null;\n}\n","/**\n * ToolCallFenceDetector - Detects and extracts tool call fences from streaming text\n *\n * This module handles the complex task of detecting tool call fences in a stream\n * where fences might be split across multiple chunks. It uses overlap detection\n * to avoid emitting text that might be the beginning of a fence.\n */\n\n/**\n * Result of fence detection operation\n */\nexport interface FenceDetectionResult {\n  fence: string | null;\n  prefixText: string;\n  remainingText: string;\n  /** Length of potential partial fence at buffer end */\n  overlapLength: number;\n}\n\n/**\n * Result of streaming fence content detection\n */\nexport interface StreamingFenceResult {\n  inFence: boolean;\n  /** Content that can be safely emitted (either as text or tool-input-delta) */\n  safeContent: string;\n  completeFence: string | null;\n  textAfterFence: string;\n}\n\n/**\n * Fence pattern configuration\n */\nexport interface FencePattern {\n  start: string;\n  end: string;\n  reconstructStart: string;\n  isRegex?: boolean;\n  matchedStart?: string;\n}\n\n/**\n * Options for configuring the ToolCallFenceDetector\n */\nexport interface ToolCallFenceDetectorOptions {\n  /** Custom fence patterns to use instead of defaults */\n  patterns?: FencePattern[];\n  /** Enable Python-style function call detection: [functionName(args)] */\n  enablePythonStyle?: boolean;\n}\n\n/**\n * Default fence patterns for tool call detection\n */\nexport const DEFAULT_FENCE_PATTERNS: FencePattern[] = [\n  { start: \"```tool_call\", end: \"```\", reconstructStart: \"```tool_call\\n\" },\n  { start: \"```tool-call\", end: \"```\", reconstructStart: \"```tool-call\\n\" },\n];\n\n/**\n * Extended fence patterns including XML-style tags\n */\nexport const EXTENDED_FENCE_PATTERNS: FencePattern[] = [\n  ...DEFAULT_FENCE_PATTERNS,\n  {\n    start: \"<tool_call>\",\n    end: \"</tool_call>\",\n    reconstructStart: \"<tool_call>\",\n  },\n  {\n    start: \"<|tool_call>\",\n    end: \"<tool_call|>\",\n    reconstructStart: \"<|tool_call>\",\n  },\n];\n\n/**\n * Detects tool call fences in streaming text with support for partial matches\n */\nexport class ToolCallFenceDetector {\n  private readonly fencePatterns: FencePattern[];\n  private readonly enablePythonStyle: boolean;\n  private readonly pythonStyleRegex = /\\[(\\w+)\\(/g;\n  private readonly fenceStarts: string[];\n  private buffer = \"\";\n\n  private inFence = false;\n  private fenceStartBuffer = \"\"; // Accumulated fence content\n  private currentFencePattern: FencePattern | null = null;\n\n  constructor(options: ToolCallFenceDetectorOptions = {}) {\n    this.fencePatterns = options.patterns ?? EXTENDED_FENCE_PATTERNS;\n    this.enablePythonStyle = options.enablePythonStyle ?? true;\n    this.fenceStarts = this.fencePatterns.map((p) => p.start);\n  }\n\n  addChunk(chunk: string): void {\n    this.buffer += chunk;\n  }\n\n  getBuffer(): string {\n    return this.buffer;\n  }\n\n  clearBuffer(): void {\n    this.buffer = \"\";\n  }\n\n  /**\n   * Detects if there's a complete fence in the buffer\n   * @returns Detection result with fence info and safe text\n   */\n  detectFence(): FenceDetectionResult {\n    const {\n      index: startIdx,\n      prefix: matchedPrefix,\n      pattern,\n    } = this.findFenceStart(this.buffer);\n\n    // No fence start found\n    if (startIdx === -1) {\n      // Compute how much of the buffer end might be a partial fence start\n      const overlap = this.computeOverlapLength(this.buffer, this.fenceStarts);\n      const safeTextLength = this.buffer.length - overlap;\n\n      const prefixText =\n        safeTextLength > 0 ? this.buffer.slice(0, safeTextLength) : \"\";\n      const remaining = overlap > 0 ? this.buffer.slice(-overlap) : \"\";\n\n      // Update buffer to keep only the overlap\n      this.buffer = remaining;\n\n      return {\n        fence: null,\n        prefixText,\n        remainingText: \"\",\n        overlapLength: overlap,\n      };\n    }\n\n    const prefixText = this.buffer.slice(0, startIdx);\n    this.buffer = this.buffer.slice(startIdx);\n\n    // Look for closing fence using the matched pattern's end marker\n    const prefixLength = matchedPrefix?.length ?? 0;\n    const fenceEnd = pattern?.end ?? \"```\";\n    const closingIdx = this.buffer.indexOf(fenceEnd, prefixLength);\n\n    // Fence not complete yet\n    if (closingIdx === -1) {\n      // Keep the buffer as-is, waiting for more data\n      return {\n        fence: null,\n        prefixText,\n        remainingText: \"\",\n        overlapLength: 0,\n      };\n    }\n\n    // Complete fence found!\n    const endPos = closingIdx + fenceEnd.length;\n    const fence = this.buffer.slice(0, endPos);\n    const remainingText = this.buffer.slice(endPos);\n\n    // Clear the buffer since we extracted everything\n    this.buffer = \"\";\n\n    return {\n      fence,\n      prefixText,\n      remainingText,\n      overlapLength: 0,\n    };\n  }\n\n  /**\n   * Finds the first occurrence of any fence start marker\n   *\n   * @param text - Text to search in\n   * @returns Index of first fence start and which pattern matched\n   * @private\n   */\n  private findFenceStart(text: string): {\n    index: number;\n    prefix: string | null;\n    pattern: FencePattern | null;\n  } {\n    let bestIndex = -1;\n    let matchedPrefix: string | null = null;\n    let matchedPattern: FencePattern | null = null;\n\n    for (const pattern of this.fencePatterns) {\n      const idx = text.indexOf(pattern.start);\n      if (idx !== -1 && (bestIndex === -1 || idx < bestIndex)) {\n        bestIndex = idx;\n        matchedPrefix = pattern.start;\n        matchedPattern = pattern;\n      }\n    }\n\n    if (this.enablePythonStyle) {\n      this.pythonStyleRegex.lastIndex = 0;\n      const pythonMatch = this.pythonStyleRegex.exec(text);\n      if (pythonMatch && (bestIndex === -1 || pythonMatch.index < bestIndex)) {\n        bestIndex = pythonMatch.index;\n        matchedPrefix = pythonMatch[0];\n        matchedPattern = {\n          start: pythonMatch[0],\n          end: \")]\",\n          reconstructStart: pythonMatch[0],\n          isRegex: true,\n        };\n      }\n    }\n\n    return { index: bestIndex, prefix: matchedPrefix, pattern: matchedPattern };\n  }\n\n  /**\n   * Computes the maximum overlap between the end of text and the start of any prefix\n   * @param text - Text to check for overlap\n   * @param prefixes - List of prefixes to check against\n   * @returns Length of the maximum overlap found\n   */\n  private computeOverlapLength(text: string, prefixes: string[]): number {\n    let overlap = 0;\n\n    for (const prefix of prefixes) {\n      const maxLength = Math.min(text.length, prefix.length - 1);\n\n      for (let size = maxLength; size > 0; size -= 1) {\n        // Check if the last 'size' characters of text match the first 'size' characters of prefix\n        if (prefix.startsWith(text.slice(-size))) {\n          overlap = Math.max(overlap, size);\n          break;\n        }\n      }\n    }\n\n    return overlap;\n  }\n\n  /**\n   * Checks if the buffer currently contains any text\n   */\n  hasContent(): boolean {\n    return this.buffer.length > 0;\n  }\n\n  /**\n   * Gets the buffer size\n   */\n  getBufferSize(): number {\n    return this.buffer.length;\n  }\n\n  /**\n   * Detect and stream fence content in real-time for true incremental streaming\n   * @returns Streaming result with current state and safe content to emit\n   */\n  detectStreamingFence(): StreamingFenceResult {\n    if (!this.inFence) {\n      // Look for fence start\n      const {\n        index: startIdx,\n        prefix: matchedPrefix,\n        pattern,\n      } = this.findFenceStart(this.buffer);\n\n      if (startIdx === -1) {\n        // No fence start found - emit safe text\n        const overlap = this.computeOverlapLength(\n          this.buffer,\n          this.fenceStarts,\n        );\n        const safeTextLength = this.buffer.length - overlap;\n        const safeContent =\n          safeTextLength > 0 ? this.buffer.slice(0, safeTextLength) : \"\";\n        this.buffer = this.buffer.slice(safeTextLength);\n\n        return {\n          inFence: false,\n          safeContent,\n          completeFence: null,\n          textAfterFence: \"\",\n        };\n      }\n\n      // Found fence start!\n      const prefixText = this.buffer.slice(0, startIdx);\n      const fenceStartLength = matchedPrefix?.length ?? 0;\n\n      // Move buffer past the fence start marker\n      this.buffer = this.buffer.slice(startIdx + fenceStartLength);\n\n      if (\n        pattern &&\n        pattern.start.startsWith(\"```\") &&\n        this.buffer.startsWith(\"\\n\")\n      ) {\n        this.buffer = this.buffer.slice(1);\n      }\n\n      this.inFence = true;\n      this.fenceStartBuffer = \"\";\n      this.currentFencePattern = pattern;\n\n      return {\n        inFence: true,\n        safeContent: prefixText, // Emit any text before the fence\n        completeFence: null,\n        textAfterFence: \"\",\n      };\n    }\n\n    // We're inside a fence - look for fence end using the current pattern\n    const fenceEnd = this.currentFencePattern?.end ?? \"```\";\n    const closingIdx = this.buffer.indexOf(fenceEnd);\n\n    if (closingIdx === -1) {\n      // No fence end yet - emit safe content (leaving potential fence end marker)\n      const overlap = this.computeOverlapLength(this.buffer, [fenceEnd]);\n      const safeContentLength = this.buffer.length - overlap;\n\n      if (safeContentLength > 0) {\n        const safeContent = this.buffer.slice(0, safeContentLength);\n        this.fenceStartBuffer += safeContent;\n        this.buffer = this.buffer.slice(safeContentLength);\n\n        return {\n          inFence: true,\n          safeContent,\n          completeFence: null,\n          textAfterFence: \"\",\n        };\n      }\n\n      // Nothing safe to emit yet\n      return {\n        inFence: true,\n        safeContent: \"\",\n        completeFence: null,\n        textAfterFence: \"\",\n      };\n    }\n\n    // Found fence end!\n    const fenceContent = this.buffer.slice(0, closingIdx);\n    this.fenceStartBuffer += fenceContent;\n\n    // Reconstruct complete fence using the current pattern\n    const reconstructStart =\n      this.currentFencePattern?.reconstructStart ?? \"```tool_call\\n\";\n    const completeFence = `${reconstructStart}${this.fenceStartBuffer}${fenceEnd}`;\n\n    // Get text after fence\n    const textAfterFence = this.buffer.slice(closingIdx + fenceEnd.length);\n\n    // Reset state\n    this.inFence = false;\n    this.fenceStartBuffer = \"\";\n    this.currentFencePattern = null;\n    this.buffer = textAfterFence;\n\n    return {\n      inFence: false,\n      safeContent: fenceContent, // Emit the last bit of fence content\n      completeFence,\n      textAfterFence,\n    };\n  }\n\n  isInFence(): boolean {\n    return this.inFence;\n  }\n\n  resetStreamingState(): void {\n    this.inFence = false;\n    this.fenceStartBuffer = \"\";\n    this.currentFencePattern = null;\n  }\n}\n\n/**\n * Creates a basic ToolCallFenceDetector with default markdown fence patterns\n */\nexport function createBasicDetector(): ToolCallFenceDetector {\n  return new ToolCallFenceDetector({\n    patterns: DEFAULT_FENCE_PATTERNS,\n    enablePythonStyle: false,\n  });\n}\n\n/**\n * Creates an extended ToolCallFenceDetector with all fence patterns\n */\nexport function createExtendedDetector(): ToolCallFenceDetector {\n  return new ToolCallFenceDetector({\n    patterns: EXTENDED_FENCE_PATTERNS,\n    enablePythonStyle: true,\n  });\n}\n","/**\n * Extracts tool name from partial fence content for early tool-input-start emission.\n * Expects a JSON fragment like: {\"name\":\"toolName\"\n */\nexport function extractToolName(content: string): string | null {\n  const jsonMatch = content.match(/\\{\\s*\"name\"\\s*:\\s*\"([^\"]+)\"/);\n  if (jsonMatch) {\n    return jsonMatch[1];\n  }\n  const callColonMatch = content.match(/call:(\\w+)\\{/);\n  if (callColonMatch) {\n    return callColonMatch[1];\n  }\n  return null;\n}\n\nexport interface ArgumentsStreamState {\n  searchFrom: number;\n  valueStartIndex: number | null;\n  parseIndex: number;\n  started: boolean;\n  depth: number;\n  inString: boolean;\n  escaped: boolean;\n  complete: boolean;\n}\n\nconst ARGUMENTS_FIELD_REGEX = /\"arguments\"\\s*:\\s*/g;\nconst ARGUMENTS_SEARCH_OVERLAP = 32;\n\nexport function createArgumentsStreamState(): ArgumentsStreamState {\n  return {\n    searchFrom: 0,\n    valueStartIndex: null,\n    parseIndex: 0,\n    started: false,\n    depth: 0,\n    inString: false,\n    escaped: false,\n    complete: false,\n  };\n}\n\n/**\n * Incrementally extracts only new argument content from a streaming tool call fence.\n */\nexport function extractArgumentsDelta(\n  content: string,\n  state: ArgumentsStreamState,\n): string {\n  if (state.complete) {\n    return \"\";\n  }\n\n  if (state.valueStartIndex === null) {\n    ARGUMENTS_FIELD_REGEX.lastIndex = state.searchFrom;\n    const match = ARGUMENTS_FIELD_REGEX.exec(content);\n    ARGUMENTS_FIELD_REGEX.lastIndex = 0;\n\n    if (!match || match.index === undefined) {\n      state.searchFrom = Math.max(0, content.length - ARGUMENTS_SEARCH_OVERLAP);\n      return \"\";\n    }\n\n    state.valueStartIndex = match.index + match[0].length;\n    state.parseIndex = state.valueStartIndex;\n    state.searchFrom = state.valueStartIndex;\n  }\n\n  if (state.parseIndex >= content.length) {\n    return \"\";\n  }\n\n  let delta = \"\";\n  for (let i = state.parseIndex; i < content.length; i++) {\n    const char = content[i];\n    delta += char;\n\n    if (!state.started) {\n      if (!/\\s/.test(char)) {\n        state.started = true;\n        if (char === \"{\" || char === \"[\") {\n          state.depth = 1;\n        }\n      }\n      continue;\n    }\n\n    if (state.escaped) {\n      state.escaped = false;\n      continue;\n    }\n\n    if (char === \"\\\\\") {\n      state.escaped = true;\n      continue;\n    }\n\n    if (char === '\"') {\n      state.inString = !state.inString;\n      continue;\n    }\n\n    if (!state.inString) {\n      if (char === \"{\" || char === \"[\") {\n        state.depth += 1;\n      } else if (char === \"}\" || char === \"]\") {\n        if (state.depth > 0) {\n          state.depth -= 1;\n          if (state.depth === 0) {\n            state.parseIndex = i + 1;\n            state.complete = true;\n            return delta;\n          }\n        }\n      }\n    }\n  }\n\n  state.parseIndex = content.length;\n  return delta;\n}\n","import type { LanguageModelV3StreamPart } from \"@ai-sdk/provider\";\nimport { ToolCallFenceDetector } from \"./tool-call-detector\";\nimport {\n  createArgumentsStreamState,\n  extractArgumentsDelta,\n  extractToolName,\n} from \"./tool-call-stream-utils\";\nimport { parseJsonFunctionCalls } from \"../tool-calling/parse-json-function-calls\";\nimport type { ParsedToolCall } from \"../types\";\n\nexport interface ToolCallStreamResult {\n  toolCallDetected: boolean;\n  toolCalls: ParsedToolCall[];\n  /** Text appearing after the tool call fence — caller decides when to emit it */\n  trailingText: string;\n}\n\nexport function generateToolCallId(): string {\n  return `call_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\n}\n\n/**\n * Processes an async iterable of string chunks, detecting tool call fences and\n * emitting the appropriate stream events via `controller` and `emitTextDelta`.\n *\n * When `stopEarlyOnToolCall` is true the function stops consuming chunks as soon as\n * a tool call is detected (useful when the caller needs to cancel the source).\n * When false (the default) the function continues draining remaining chunks without\n * processing them, allowing the underlying stream/engine to conclude normally.\n */\nexport async function processToolCallStream(\n  chunks: AsyncIterable<string>,\n  emitTextDelta: (delta: string) => void,\n  controller: ReadableStreamDefaultController<LanguageModelV3StreamPart>,\n  options?: { stopEarlyOnToolCall?: boolean },\n): Promise<ToolCallStreamResult> {\n  const fenceDetector = new ToolCallFenceDetector();\n\n  let currentToolCallId: string | null = null;\n  let toolInputStartEmitted = false;\n  let accumulatedFenceContent = \"\";\n  let argumentsStreamState = createArgumentsStreamState();\n  let insideFence = false;\n\n  let toolCallDetected = false;\n  let toolCalls: ParsedToolCall[] = [];\n  let trailingText = \"\";\n\n  const resetFenceState = () => {\n    currentToolCallId = null;\n    toolInputStartEmitted = false;\n    accumulatedFenceContent = \"\";\n    argumentsStreamState = createArgumentsStreamState();\n    insideFence = false;\n  };\n\n  for await (const chunk of chunks) {\n    if (toolCallDetected) {\n      // Drain without processing so the underlying stream/engine can conclude.\n      continue;\n    }\n\n    fenceDetector.addChunk(chunk);\n\n    while (fenceDetector.hasContent()) {\n      const wasInsideFence = insideFence;\n      const result = fenceDetector.detectStreamingFence();\n      insideFence = result.inFence;\n\n      let madeProgress = false;\n\n      if (!wasInsideFence && result.inFence) {\n        if (result.safeContent) {\n          emitTextDelta(result.safeContent);\n          madeProgress = true;\n        }\n\n        currentToolCallId = generateToolCallId();\n        toolInputStartEmitted = false;\n        accumulatedFenceContent = \"\";\n        argumentsStreamState = createArgumentsStreamState();\n        insideFence = true;\n\n        continue;\n      }\n\n      if (result.completeFence) {\n        madeProgress = true;\n        if (result.safeContent) {\n          accumulatedFenceContent += result.safeContent;\n        }\n\n        if (toolInputStartEmitted && currentToolCallId) {\n          const delta = extractArgumentsDelta(\n            accumulatedFenceContent,\n            argumentsStreamState,\n          );\n          if (delta.length > 0) {\n            controller.enqueue({\n              type: \"tool-input-delta\",\n              id: currentToolCallId,\n              delta,\n            });\n          }\n        }\n\n        const parsed = parseJsonFunctionCalls(result.completeFence);\n        const selectedToolCalls = parsed.toolCalls.slice(0, 1);\n\n        if (selectedToolCalls.length === 0) {\n          emitTextDelta(result.completeFence);\n          if (result.textAfterFence) {\n            emitTextDelta(result.textAfterFence);\n          }\n          resetFenceState();\n          continue;\n        }\n\n        if (currentToolCallId) {\n          selectedToolCalls[0].toolCallId = currentToolCallId;\n        }\n\n        for (const [index, call] of selectedToolCalls.entries()) {\n          const toolCallId =\n            index === 0 && currentToolCallId\n              ? currentToolCallId\n              : call.toolCallId;\n          const toolName = call.toolName;\n          const argsJson = JSON.stringify(call.args ?? {});\n\n          if (toolCallId === currentToolCallId) {\n            if (!toolInputStartEmitted) {\n              controller.enqueue({\n                type: \"tool-input-start\",\n                id: toolCallId,\n                toolName,\n              });\n              toolInputStartEmitted = true;\n            }\n\n            const delta = extractArgumentsDelta(\n              accumulatedFenceContent,\n              argumentsStreamState,\n            );\n            if (delta.length > 0) {\n              controller.enqueue({\n                type: \"tool-input-delta\",\n                id: toolCallId,\n                delta,\n              });\n            }\n          } else {\n            controller.enqueue({\n              type: \"tool-input-start\",\n              id: toolCallId,\n              toolName,\n            });\n            if (argsJson.length > 0) {\n              controller.enqueue({\n                type: \"tool-input-delta\",\n                id: toolCallId,\n                delta: argsJson,\n              });\n            }\n          }\n\n          controller.enqueue({ type: \"tool-input-end\", id: toolCallId });\n          controller.enqueue({\n            type: \"tool-call\",\n            toolCallId,\n            toolName,\n            input: argsJson,\n            providerExecuted: false,\n          });\n        }\n\n        trailingText = result.textAfterFence ?? \"\";\n        toolCalls = selectedToolCalls;\n        toolCallDetected = true;\n        resetFenceState();\n        break; // stop processing inner buffer\n      }\n\n      if (insideFence) {\n        if (result.safeContent) {\n          accumulatedFenceContent += result.safeContent;\n          madeProgress = true;\n\n          const toolName = extractToolName(accumulatedFenceContent);\n          if (toolName && !toolInputStartEmitted && currentToolCallId) {\n            controller.enqueue({\n              type: \"tool-input-start\",\n              id: currentToolCallId,\n              toolName,\n            });\n            toolInputStartEmitted = true;\n          }\n\n          if (toolInputStartEmitted && currentToolCallId) {\n            const delta = extractArgumentsDelta(\n              accumulatedFenceContent,\n              argumentsStreamState,\n            );\n            if (delta.length > 0) {\n              controller.enqueue({\n                type: \"tool-input-delta\",\n                id: currentToolCallId,\n                delta,\n              });\n            }\n          }\n        }\n\n        continue;\n      }\n\n      if (!insideFence && result.safeContent) {\n        emitTextDelta(result.safeContent);\n        madeProgress = true;\n      }\n\n      if (!madeProgress) {\n        break;\n      }\n    }\n\n    if (toolCallDetected && options?.stopEarlyOnToolCall) {\n      break; // caller will cancel/drain the underlying source\n    }\n  }\n\n  // Flush any remaining buffer when no tool call was detected\n  if (!toolCallDetected && fenceDetector.hasContent()) {\n    emitTextDelta(fenceDetector.getBuffer());\n    fenceDetector.clearBuffer();\n  }\n\n  return { toolCallDetected, toolCalls, trailingText };\n}\n","import {\n  LanguageModelV3Prompt,\n  LanguageModelV3ToolCallPart,\n  LanguageModelV3ToolResultPart,\n  LanguageModelV3ToolResultOutput,\n  UnsupportedFunctionalityError,\n} from \"@ai-sdk/provider\";\nimport { formatToolResults, type ToolResult } from \"@browser-ai/shared\";\nexport interface ConvertedMessages {\n  systemMessage?: string;\n  messages: LanguageModelMessage[];\n}\n\n/**\n * Convert base64 string to Uint8Array for browser AI compatibility\n * Browser AI supports BufferSource (including Uint8Array) for image/audio data\n */\nfunction convertBase64ToUint8Array(base64: string): Uint8Array {\n  try {\n    const binaryString = atob(base64);\n    return Uint8Array.from(binaryString, (c) => c.charCodeAt(0));\n  } catch (error) {\n    throw new Error(`Failed to convert base64 to Uint8Array: ${error}`);\n  }\n}\n\n/**\n * Convert file data to the appropriate format for browser AI\n * Browser AI supports: Blob, BufferSource (Uint8Array), URLs\n */\nfunction convertFileData(\n  data: URL | Uint8Array | string,\n  mediaType: string,\n): Uint8Array | string {\n  // Handle different data types from Vercel AI SDK\n  if (data instanceof URL) {\n    // URLs - keep as string (if supported by provider)\n    return data.toString();\n  }\n\n  if (data instanceof Uint8Array) {\n    // Already in correct format\n    return data;\n  }\n\n  if (typeof data === \"string\") {\n    // Base64 string from AI SDK - convert to Uint8Array\n    return convertBase64ToUint8Array(data);\n  }\n\n  // Exhaustive check - this should never happen with the union type\n  const exhaustiveCheck: never = data;\n  throw new Error(`Unexpected data type for ${mediaType}: ${exhaustiveCheck}`);\n}\n\nfunction normalizeToolArguments(input: unknown): unknown {\n  if (input === undefined) {\n    return {};\n  }\n\n  if (typeof input === \"string\") {\n    try {\n      return JSON.parse(input);\n    } catch {\n      return input;\n    }\n  }\n\n  return input ?? {};\n}\n\nfunction formatToolCallsJson(parts: LanguageModelV3ToolCallPart[]): string {\n  if (!parts.length) {\n    return \"\";\n  }\n\n  const payloads = parts.map((call) => {\n    const payload: Record<string, unknown> = {\n      name: call.toolName,\n      arguments: normalizeToolArguments(call.input),\n    };\n\n    if (call.toolCallId) {\n      payload.id = call.toolCallId;\n    }\n\n    return JSON.stringify(payload);\n  });\n\n  return `\\`\\`\\`tool_call\n${payloads.join(\"\\n\")}\n\\`\\`\\``;\n}\n\nfunction convertToolResultOutput(output: LanguageModelV3ToolResultOutput): {\n  value: unknown;\n  isError: boolean;\n} {\n  switch (output.type) {\n    case \"text\":\n      return { value: output.value, isError: false };\n    case \"json\":\n      return { value: output.value, isError: false };\n    case \"error-text\":\n      return { value: output.value, isError: true };\n    case \"error-json\":\n      return { value: output.value, isError: true };\n    case \"content\":\n      return { value: output.value, isError: false };\n    case \"execution-denied\":\n      return { value: output.reason, isError: true };\n    default: {\n      const exhaustiveCheck: never = output;\n      return { value: exhaustiveCheck, isError: false };\n    }\n  }\n}\n\nfunction toToolResult(part: LanguageModelV3ToolResultPart): ToolResult {\n  const { value, isError } = convertToolResultOutput(part.output);\n  return {\n    toolCallId: part.toolCallId,\n    toolName: part.toolName,\n    result: value,\n    isError,\n  };\n}\n\n/**\n * Convert Vercel AI SDK prompt format to browser AI Prompt API format\n * Returns system message (for initialPrompts) and regular messages (for prompt method)\n */\nexport function convertToBrowserAIMessages(\n  prompt: LanguageModelV3Prompt,\n): ConvertedMessages {\n  const normalizedPrompt = prompt.slice();\n\n  let systemMessage: string | undefined;\n  const messages: LanguageModelMessage[] = [];\n\n  for (const message of normalizedPrompt) {\n    switch (message.role) {\n      case \"system\": {\n        // There's only ever one system message from AI SDK\n        systemMessage = message.content;\n        break;\n      }\n\n      case \"user\": {\n        messages.push({\n          role: \"user\",\n          content: message.content.map((part) => {\n            switch (part.type) {\n              case \"text\": {\n                return {\n                  type: \"text\",\n                  value: part.text,\n                } as LanguageModelMessageContent;\n              }\n\n              case \"file\": {\n                const { mediaType, data } = part;\n\n                if (mediaType?.startsWith(\"image/\")) {\n                  const convertedData = convertFileData(data, mediaType);\n\n                  return {\n                    type: \"image\",\n                    value: convertedData,\n                  } as LanguageModelMessageContent;\n                } else if (mediaType?.startsWith(\"audio/\")) {\n                  const convertedData = convertFileData(data, mediaType);\n\n                  return {\n                    type: \"audio\",\n                    value: convertedData,\n                  } as LanguageModelMessageContent;\n                } else {\n                  throw new UnsupportedFunctionalityError({\n                    functionality: `file type: ${mediaType}`,\n                  });\n                }\n              }\n\n              default: {\n                const exhaustiveCheck: never = part;\n                throw new UnsupportedFunctionalityError({\n                  functionality: `content type: ${(exhaustiveCheck as { type?: string }).type ?? \"unknown\"}`,\n                });\n              }\n            }\n          }),\n        } as LanguageModelMessage);\n        break;\n      }\n\n      case \"assistant\": {\n        let text = \"\";\n        const toolCallParts: LanguageModelV3ToolCallPart[] = [];\n\n        for (const part of message.content) {\n          switch (part.type) {\n            case \"text\": {\n              text += part.text;\n              break;\n            }\n            case \"reasoning\": {\n              text += part.text;\n              break;\n            }\n            case \"tool-call\": {\n              toolCallParts.push(part);\n              break;\n            }\n            case \"file\": {\n              throw new UnsupportedFunctionalityError({\n                functionality: \"assistant file attachments\",\n              });\n            }\n            case \"tool-result\": {\n              throw new UnsupportedFunctionalityError({\n                functionality:\n                  \"tool-result parts in assistant messages (should be in tool messages)\",\n              });\n            }\n            default: {\n              const exhaustiveCheck: never = part;\n              throw new UnsupportedFunctionalityError({\n                functionality: `assistant part type: ${(exhaustiveCheck as { type?: string }).type ?? \"unknown\"}`,\n              });\n            }\n          }\n        }\n\n        const toolCallJson = formatToolCallsJson(toolCallParts);\n        const contentSegments: string[] = [];\n\n        if (text.trim().length > 0) {\n          contentSegments.push(text);\n        } else if (text.length > 0) {\n          // preserve purely whitespace responses so we don't lose formatting\n          contentSegments.push(text);\n        }\n\n        if (toolCallJson) {\n          contentSegments.push(toolCallJson);\n        }\n\n        const content =\n          contentSegments.length > 0 ? contentSegments.join(\"\\n\") : \"\";\n\n        messages.push({\n          role: \"assistant\",\n          content,\n        } as LanguageModelMessage);\n        break;\n      }\n\n      case \"tool\": {\n        const toolParts = message.content as LanguageModelV3ToolResultPart[];\n        const results: ToolResult[] = toolParts.map(toToolResult);\n        const toolResultsJson = formatToolResults(results);\n\n        messages.push({\n          role: \"user\",\n          content: toolResultsJson,\n        } as LanguageModelMessage);\n        break;\n      }\n\n      default: {\n        const exhaustiveCheck: never = message;\n        throw new Error(\n          `Unsupported role: ${(exhaustiveCheck as { role?: string }).role ?? \"unknown\"}`,\n        );\n      }\n    }\n  }\n\n  return { systemMessage, messages };\n}\n","/**\n * Warning generation utilities for unsupported settings and tools\n */\n\nimport type { SharedV3Warning } from \"@ai-sdk/provider\";\nimport { createUnsupportedSettingWarning } from \"@browser-ai/shared\";\n\n// Re-export shared utilities\nexport {\n  createUnsupportedSettingWarning,\n  createUnsupportedToolWarning,\n} from \"@browser-ai/shared\";\n\n/**\n * Gathers all warnings for unsupported call options (Prompt API specific)\n *\n * @param options - The call options to check\n * @returns Array of warnings for any unsupported settings\n *\n * @example\n * ```typescript\n * const warnings = gatherUnsupportedSettingWarnings({\n *   maxOutputTokens: 100,\n *   topP: 0.9,\n *   temperature: 0.7,\n * });\n * // Returns warnings for maxOutputTokens and topP\n * ```\n */\nexport function gatherUnsupportedSettingWarnings(options: {\n  maxOutputTokens?: number;\n  stopSequences?: string[];\n  topP?: number;\n  presencePenalty?: number;\n  frequencyPenalty?: number;\n  seed?: number;\n  toolChoice?: unknown;\n}): SharedV3Warning[] {\n  const warnings: SharedV3Warning[] = [];\n\n  if (options.maxOutputTokens != null) {\n    warnings.push(\n      createUnsupportedSettingWarning(\n        \"maxOutputTokens\",\n        \"maxOutputTokens is not supported by Prompt API\",\n      ),\n    );\n  }\n\n  if (options.stopSequences != null) {\n    warnings.push(\n      createUnsupportedSettingWarning(\n        \"stopSequences\",\n        \"stopSequences is not supported by Prompt API\",\n      ),\n    );\n  }\n\n  if (options.topP != null) {\n    warnings.push(\n      createUnsupportedSettingWarning(\n        \"topP\",\n        \"topP is not supported by Prompt API\",\n      ),\n    );\n  }\n\n  if (options.presencePenalty != null) {\n    warnings.push(\n      createUnsupportedSettingWarning(\n        \"presencePenalty\",\n        \"presencePenalty is not supported by Prompt API\",\n      ),\n    );\n  }\n\n  if (options.frequencyPenalty != null) {\n    warnings.push(\n      createUnsupportedSettingWarning(\n        \"frequencyPenalty\",\n        \"frequencyPenalty is not supported by Prompt API\",\n      ),\n    );\n  }\n\n  if (options.seed != null) {\n    warnings.push(\n      createUnsupportedSettingWarning(\n        \"seed\",\n        \"seed is not supported by Prompt API\",\n      ),\n    );\n  }\n\n  if (options.toolChoice != null) {\n    warnings.push(\n      createUnsupportedSettingWarning(\n        \"toolChoice\",\n        \"toolChoice is not supported by Prompt API\",\n      ),\n    );\n  }\n\n  return warnings;\n}\n","/**\n * Utilities for prompt processing and transformation\n */\n\nimport type { LanguageModelV3Prompt } from \"@ai-sdk/provider\";\n\n/**\n * Detect multimodal content and collect expected input types in a single pass.\n *\n * @param prompt - The prompt to analyze\n * @returns hasMultiModalInput flag and the expectedInputs array (undefined when text-only)\n */\nexport function getMultimodalInfo(prompt: LanguageModelV3Prompt): {\n  hasMultiModalInput: boolean;\n  expectedInputs: Array<{ type: \"text\" | \"image\" | \"audio\" }> | undefined;\n} {\n  const inputs = new Set<\"image\" | \"audio\">();\n\n  for (const message of prompt) {\n    if (message.role === \"user\") {\n      for (const part of message.content) {\n        if (part.type === \"file\") {\n          if (part.mediaType?.startsWith(\"image/\")) {\n            inputs.add(\"image\");\n          } else if (part.mediaType?.startsWith(\"audio/\")) {\n            inputs.add(\"audio\");\n          }\n        }\n      }\n    }\n  }\n\n  const hasMultiModalInput = inputs.size > 0;\n  return {\n    hasMultiModalInput,\n    expectedInputs: hasMultiModalInput\n      ? Array.from(inputs, (type) => ({ type }))\n      : undefined,\n  };\n}\n\n/**\n * Prepends a system prompt to the first user message in the conversation.\n *\n * This is necessary because the Prompt API doesn't support separate system messages,\n * so we inject the system prompt into the first user message instead.\n * Creates a shallow copy of messages to avoid mutating the original array.\n *\n * @param messages - The messages array to modify (not mutated, a copy is returned)\n * @param systemPrompt - The system prompt to prepend\n * @returns New messages array with system prompt prepended to first user message\n * @example\n * ```typescript\n * const messages = [{ role: \"user\", content: \"Hello\" }];\n * const updated = prependSystemPromptToMessages(messages, \"You are a helpful assistant.\");\n * // Returns: [{ role: \"user\", content: \"You are a helpful assistant.\\n\\nHello\" }]\n * ```\n */\nexport function prependSystemPromptToMessages(\n  messages: LanguageModelMessage[],\n  systemPrompt: string,\n): LanguageModelMessage[] {\n  if (!systemPrompt.trim()) {\n    return messages;\n  }\n\n  const prompts = messages.map((message) => ({ ...message }));\n  const firstUserIndex = prompts.findIndex(\n    (message) => message.role === \"user\",\n  );\n\n  if (firstUserIndex !== -1) {\n    const firstUserMessage = prompts[firstUserIndex];\n\n    if (Array.isArray(firstUserMessage.content)) {\n      const content = firstUserMessage.content.slice();\n      content.unshift({\n        type: \"text\",\n        value: `${systemPrompt}\\n\\n`,\n      });\n      prompts[firstUserIndex] = {\n        ...firstUserMessage,\n        content,\n      } as LanguageModelMessage;\n    } else if (typeof firstUserMessage.content === \"string\") {\n      prompts[firstUserIndex] = {\n        ...firstUserMessage,\n        content: `${systemPrompt}\\n\\n${firstUserMessage.content}`,\n      } as LanguageModelMessage;\n    }\n  } else {\n    prompts.unshift({\n      role: \"user\",\n      content: systemPrompt,\n    });\n  }\n\n  return prompts;\n}\n","/**\n * SessionManager handles the lifecycle of browser AI sessions\n * Manages session creation, caching, availability checks, and progress monitoring\n */\n\nimport { LoadSettingError } from \"@ai-sdk/provider\";\nimport type { DownloadProgressCallback } from \"@browser-ai/shared\";\n\n/**\n * Custom provider options that extend the standard API\n */\ninterface CustomProviderOptions {\n  /**\n   * Callback invoked when the model context window is exceeded.\n   * Replaces the deprecated `onQuotaOverflow`.\n   */\n  onContextOverflow?: (event: Event) => void;\n  /**\n   * @deprecated Use `onContextOverflow` instead.\n   */\n  onQuotaOverflow?: (event: Event) => void;\n}\n\n/**\n * Options for creating a new session\n */\nexport interface SessionCreateOptions\n  extends LanguageModelCreateOptions, CustomProviderOptions {\n  systemMessage?: string;\n  expectedInputs?: Array<{ type: \"text\" | \"image\" | \"audio\" }>;\n  onDownloadProgress?: DownloadProgressCallback;\n}\n\n/**\n * Manages browser AI session lifecycle\n *\n * Responsibilities:\n * - Create and cache AI sessions\n * - Check model availability\n * - Monitor download progress\n * - Handle session options and configuration\n *\n * @example\n * ```typescript\n * const manager = new SessionManager(config);\n *\n * // Check availability first\n * const status = await manager.checkAvailability();\n *\n * // Create session with progress tracking\n * const session = await manager.getSession({\n *   temperature: 0.7,\n *   onDownloadProgress: (progress) => console.log(`${progress * 100}%`)\n * });\n * ```\n */\nexport class SessionManager {\n  private session: LanguageModel | null = null;\n  private baseOptions: LanguageModelCreateOptions &\n    Partial<CustomProviderOptions>;\n\n  /**\n   * Creates a new SessionManager\n   *\n   * @param baseOptions - Base configuration options for all sessions\n   */\n  constructor(\n    baseOptions: LanguageModelCreateOptions & Partial<CustomProviderOptions>,\n  ) {\n    // Filter out our custom options that aren't part of LanguageModelCreateOptions\n    this.baseOptions = baseOptions;\n  }\n\n  /**\n   * Gets or creates a session with the specified options\n   *\n   * If a session already exists, it will be reused unless force create is needed.\n   *\n   * @param options - Optional session creation options\n   * @returns Promise resolving to a LanguageModel session\n   * @throws {LoadSettingError} When Prompt API is not available or model is unavailable\n   *\n   * @example\n   * ```typescript\n   * const session = await manager.getSession({\n   *   systemMessage: \"You are a helpful assistant\",\n   *   expectedInputs: [{ type: \"image\" }],\n   *   temperature: 0.8\n   * });\n   * ```\n   */\n  async getSession(options?: SessionCreateOptions): Promise<LanguageModel> {\n    // Check if LanguageModel API is available\n    if (typeof LanguageModel === \"undefined\") {\n      throw new LoadSettingError({\n        message:\n          \"Prompt API is not available. This library requires Chrome or Edge browser with browser AI capabilities.\",\n      });\n    }\n\n    // Return existing session if available\n    if (this.session) {\n      return this.session;\n    }\n\n    // Check availability before attempting to create\n    const availability = await LanguageModel.availability(\n      this.prepareAvailabilityOptions(options),\n    );\n    if (availability === \"unavailable\") {\n      throw new LoadSettingError({\n        message: \"Built-in model not available in this browser\",\n      });\n    }\n\n    // Prepare session options\n    const sessionOptions = this.prepareSessionOptions(options);\n    // Create the session\n    this.session = await LanguageModel.create(sessionOptions);\n\n    // Resolve overflow handler: onContextOverflow takes precedence, onQuotaOverflow is the deprecated alias\n    const onOverflow =\n      options?.onContextOverflow ||\n      this.baseOptions.onContextOverflow ||\n      options?.onQuotaOverflow ||\n      this.baseOptions.onQuotaOverflow;\n\n    const overflowHandler =\n      onOverflow ??\n      (() => {\n        console.warn(\n          \"Model context window exceeded. Consider handling the 'contextoverflow' event.\",\n        );\n      });\n\n    // Register on the new event name; fall back to the old name for older Chrome builds.\n    // Cast to `object` in the `in` check to prevent TypeScript narrowing `this.session`\n    // to `never` in the else branch (our augmentation declares oncontextoverflow on all\n    // LanguageModel instances, but older builds may not have it at runtime).\n    const session = this.session;\n    if (\"oncontextoverflow\" in (session as object)) {\n      session.addEventListener(\"contextoverflow\", overflowHandler);\n    } else {\n      session.addEventListener(\"quotaoverflow\", overflowHandler);\n    }\n    return this.session;\n  }\n\n  /**\n   * Creates a session with download progress monitoring\n   *\n   * This is a convenience method for users who want explicit progress tracking.\n   *\n   * @param onDownloadProgress - Optional callback receiving progress values from 0 to 1\n   * @returns Promise resolving to a LanguageModel session\n   * @throws {LoadSettingError} When Prompt API is not available or model is unavailable\n   *\n   * @example\n   * ```typescript\n   * const session = await manager.createSessionWithProgress(\n   *   (progress) => {\n   *     console.log(`Download: ${Math.round(progress * 100)}%`);\n   *   }\n   * );\n   * ```\n   */\n  async createSessionWithProgress(\n    onDownloadProgress?: DownloadProgressCallback,\n  ): Promise<LanguageModel> {\n    return this.getSession({ onDownloadProgress });\n  }\n\n  /**\n   * Checks the availability status of the browser AI model\n   *\n   * @returns Promise resolving to availability status\n   * - \"unavailable\": Model is not supported\n   * - \"downloadable\": Model needs to be downloaded\n   * - \"downloading\": Model is currently downloading\n   * - \"available\": Model is ready to use\n   *\n   * @example\n   * ```typescript\n   * const status = await manager.checkAvailability();\n   * if (status === \"downloadable\") {\n   *   console.log(\"Model needs to be downloaded first\");\n   * }\n   * ```\n   */\n  async checkAvailability(\n    options?: SessionCreateOptions,\n  ): Promise<Availability> {\n    if (typeof LanguageModel === \"undefined\") {\n      return \"unavailable\";\n    }\n    return LanguageModel.availability(this.prepareAvailabilityOptions(options));\n  }\n\n  /**\n   * Gets the current session if it exists\n   *\n   * @returns The current session or null if none exists\n   */\n  getCurrentSession(): LanguageModel | null {\n    return this.session;\n  }\n\n  /**\n   * Destroys the current session\n   *\n   * Use this when you want to force creation of a new session\n   * with different options on the next getSession call.\n   */\n  destroySession(): void {\n    if (this.session && typeof this.session.destroy === \"function\") {\n      this.session.destroy();\n    }\n    this.session = null;\n  }\n\n  /**\n   * Gets the context window size (token limit) for the current session, if available.\n   * @returns The context window size or undefined if not available\n   */\n  getContextWindow(): number | undefined {\n    const session = this.getCurrentSession();\n    if (!session) return undefined;\n    // contextWindow is the new name; fall back to inputQuota for older Chrome builds\n    return (session as LanguageModel).contextWindow ?? session.inputQuota;\n  }\n\n  /**\n   * Gets the current context usage (tokens consumed) for the current session, if available.\n   * @returns The context usage or undefined if not available\n   */\n  getContextUsage(): number | undefined {\n    const session = this.getCurrentSession();\n    if (!session) return undefined;\n    // contextUsage is the new name; fall back to inputUsage for older Chrome builds\n    return (session as LanguageModel).contextUsage ?? session.inputUsage;\n  }\n\n  /**\n   * @deprecated Use {@link getContextWindow} instead.\n   */\n  getInputQuota(): number | undefined {\n    return this.getContextWindow();\n  }\n\n  /**\n   * @deprecated Use {@link getContextUsage} instead.\n   */\n  getInputUsage(): number | undefined {\n    return this.getContextUsage();\n  }\n\n  /**\n   * Prepares merged availability options from base config and request options\n   *\n   * @param options - Optional request-specific options\n   * @returns Merged and sanitized core options ready for LanguageModel.availability()\n   * @private\n   */\n  private prepareAvailabilityOptions(\n    options?: SessionCreateOptions,\n  ): LanguageModelCreateCoreOptions {\n    const mergedOptions = { ...this.baseOptions, ...options };\n    const availabilityOptions: LanguageModelCreateCoreOptions = {};\n\n    if (mergedOptions.topK !== undefined) {\n      availabilityOptions.topK = mergedOptions.topK;\n    }\n\n    if (mergedOptions.temperature !== undefined) {\n      availabilityOptions.temperature = mergedOptions.temperature;\n    }\n\n    if (mergedOptions.expectedInputs !== undefined) {\n      availabilityOptions.expectedInputs = mergedOptions.expectedInputs;\n    }\n\n    if (mergedOptions.expectedOutputs !== undefined) {\n      availabilityOptions.expectedOutputs = mergedOptions.expectedOutputs;\n    }\n\n    if (mergedOptions.tools !== undefined) {\n      availabilityOptions.tools = mergedOptions.tools;\n    }\n\n    return availabilityOptions;\n  }\n\n  /**\n   * Prepares merged session options from base config and request options\n   *\n   * @param options - Optional request-specific options\n   * @returns Merged and sanitized options ready for LanguageModel.create()\n   * @private\n   */\n  private prepareSessionOptions(\n    options?: SessionCreateOptions,\n  ): LanguageModelCreateOptions {\n    // Start with base options\n    const mergedOptions: LanguageModelCreateOptions &\n      Partial<CustomProviderOptions> = { ...this.baseOptions };\n\n    // Merge in request-specific options if provided\n    if (options) {\n      const {\n        systemMessage,\n        expectedInputs,\n        onDownloadProgress,\n        onContextOverflow: _onContextOverflow,\n        onQuotaOverflow: _onQuotaOverflow,\n        ...createOptions\n      } = options;\n\n      // Merge standard create options\n      Object.assign(mergedOptions, createOptions);\n\n      // Handle system message\n      if (systemMessage) {\n        mergedOptions.initialPrompts = [\n          { role: \"system\", content: systemMessage },\n        ];\n      }\n\n      // Handle expected inputs (for multimodal)\n      if (expectedInputs && expectedInputs.length > 0) {\n        mergedOptions.expectedInputs = expectedInputs;\n      }\n\n      // Handle download progress monitoring\n      if (onDownloadProgress) {\n        mergedOptions.monitor = (m: CreateMonitor) => {\n          m.addEventListener(\"downloadprogress\", (e: ProgressEvent) => {\n            onDownloadProgress(e.loaded); // e.loaded is between 0 and 1\n          });\n        };\n      }\n    }\n\n    return mergedOptions;\n  }\n}\n","import {\n  LanguageModelV3,\n  LanguageModelV3CallOptions,\n  SharedV3Warning,\n  LanguageModelV3Content,\n  LanguageModelV3FinishReason,\n  LanguageModelV3ProviderTool,\n  LanguageModelV3StreamPart,\n  LanguageModelV3ToolCall,\n  JSONValue,\n  LanguageModelV3GenerateResult,\n  LanguageModelV3StreamResult,\n} from \"@ai-sdk/provider\";\nimport {\n  buildJsonToolSystemPrompt,\n  parseJsonFunctionCalls,\n  createUnsupportedToolWarning,\n  isFunctionTool,\n  processToolCallStream,\n  type DownloadProgressCallback,\n} from \"@browser-ai/shared\";\nimport { convertToBrowserAIMessages } from \"../utils/convert-to-browser-ai-messages\";\nimport { gatherUnsupportedSettingWarnings } from \"../utils/warnings\";\nimport { getMultimodalInfo } from \"../utils/prompt-utils\";\nimport { SessionManager } from \"./session-manager\";\n\nexport type BrowserAIChatModelId = \"text\";\n\nexport interface BrowserAIChatSettings extends Omit<\n  LanguageModelCreateOptions,\n  \"initialPrompts\"\n> {\n  /**\n   * Expected input types for the session, for multimodal inputs.\n   */\n  expectedInputs?: Array<{\n    type: \"text\" | \"image\" | \"audio\";\n    languages?: string[];\n  }>;\n\n  /**\n   * Callback invoked when the model context window is exceeded.\n   * Replaces the deprecated `onQuotaOverflow`.\n   * @see [Prompt API Context Overflow](https://github.com/webmachinelearning/prompt-api?tab=readme-ov-file#tokenization-context-window-length-limits-and-overflow)\n   */\n  onContextOverflow?: (event: Event) => void;\n\n  /**\n   * @deprecated Use `onContextOverflow` instead.\n   * @see [Prompt API Quota Overflow](https://github.com/webmachinelearning/prompt-api?tab=readme-ov-file#tokenization-context-window-length-limits-and-overflow)\n   * @param event\n   */\n  onQuotaOverflow?: (event: Event) => void;\n}\n\n/**\n * Check if the browser supports the browser AI API\n * @returns true if the browser supports the browser AI API, false otherwise\n */\nexport function doesBrowserSupportBrowserAI(): boolean {\n  return typeof LanguageModel !== \"undefined\";\n}\n\ntype BrowserAIConfig = {\n  provider: string;\n  modelId: BrowserAIChatModelId;\n  options: BrowserAIChatSettings;\n};\n\nexport class BrowserAIChatLanguageModel implements LanguageModelV3 {\n  readonly specificationVersion = \"v3\";\n  readonly modelId: BrowserAIChatModelId;\n  readonly provider = \"browser-ai\";\n\n  private readonly config: BrowserAIConfig;\n  private readonly sessionManager: SessionManager;\n\n  constructor(\n    modelId: BrowserAIChatModelId,\n    options: BrowserAIChatSettings = {},\n  ) {\n    this.modelId = modelId;\n    this.config = {\n      provider: this.provider,\n      modelId,\n      options,\n    };\n    this.sessionManager = new SessionManager(options);\n  }\n\n  readonly supportedUrls: Record<string, RegExp[]> = {\n    \"image/*\": [/^https?:\\/\\/.+$/],\n    \"audio/*\": [/^https?:\\/\\/.+$/],\n  };\n\n  /**\n   * Gets a session with the specified options\n   * Delegates to SessionManager for all session lifecycle management\n   * @private\n   */\n  private async getSession(\n    options?: LanguageModelCreateOptions,\n    expectedInputs?: Array<{ type: \"text\" | \"image\" | \"audio\" }>,\n    systemMessage?: string,\n    onDownloadProgress?: DownloadProgressCallback,\n  ): Promise<LanguageModel> {\n    return this.sessionManager.getSession({\n      ...options,\n      expectedInputs,\n      systemMessage,\n      onDownloadProgress,\n    });\n  }\n\n  private getArgs(callOptions: Parameters<LanguageModelV3[\"doGenerate\"]>[0]) {\n    const {\n      prompt,\n      maxOutputTokens,\n      temperature,\n      topP,\n      topK,\n      frequencyPenalty,\n      presencePenalty,\n      stopSequences,\n      responseFormat,\n      seed,\n      tools,\n      toolChoice,\n      providerOptions,\n    } = callOptions;\n    const warnings: SharedV3Warning[] = [];\n\n    // Gather warnings for unsupported settings\n    warnings.push(\n      ...gatherUnsupportedSettingWarnings({\n        maxOutputTokens,\n        stopSequences,\n        topP,\n        presencePenalty,\n        frequencyPenalty,\n        seed,\n        toolChoice,\n      }),\n    );\n\n    // Filter and warn about unsupported tools\n    const functionTools = (tools ?? []).filter(isFunctionTool);\n\n    const unsupportedTools = (tools ?? []).filter(\n      (tool): tool is LanguageModelV3ProviderTool => !isFunctionTool(tool),\n    );\n\n    for (const tool of unsupportedTools) {\n      warnings.push(\n        createUnsupportedToolWarning(\n          tool,\n          \"Only function tools are supported by the Prompt API polyfill\",\n        ),\n      );\n    }\n\n    // Detect multimodal content and collect expected inputs in one pass\n    const { hasMultiModalInput, expectedInputs } = getMultimodalInfo(prompt);\n\n    // Convert messages to the DOM API format\n    const { systemMessage, messages } = convertToBrowserAIMessages(prompt);\n\n    // Handle response format for Prompt API\n    const promptOptions: LanguageModelPromptOptions = {};\n    if (responseFormat?.type === \"json\") {\n      promptOptions.responseConstraint = responseFormat.schema as Record<\n        string,\n        JSONValue\n      >;\n    }\n\n    // Map supported settings\n    const sessionOptions: LanguageModelCreateCoreOptions = {};\n    if (temperature !== undefined) {\n      sessionOptions.temperature = temperature;\n    }\n\n    if (topK !== undefined) {\n      sessionOptions.topK = topK;\n    }\n\n    return {\n      systemMessage,\n      messages,\n      warnings,\n      promptOptions,\n      sessionOptions,\n      hasMultiModalInput,\n      expectedInputs,\n      functionTools,\n    };\n  }\n\n  /**\n   * Generates a complete text response using the browser's built-in Prompt API\n   * @param options\n   * @returns Promise resolving to the generated content with finish reason, usage stats, and any warnings\n   * @throws {LoadSettingError} When the Prompt API is not available or model needs to be downloaded\n   * @throws {UnsupportedFunctionalityError} When unsupported features like file input are used\n   */\n  public async doGenerate(\n    options: LanguageModelV3CallOptions,\n  ): Promise<LanguageModelV3GenerateResult> {\n    const converted = this.getArgs(options);\n    const {\n      systemMessage,\n      messages,\n      warnings,\n      promptOptions,\n      sessionOptions,\n      expectedInputs,\n      functionTools,\n    } = converted;\n\n    const systemPrompt = buildJsonToolSystemPrompt(\n      systemMessage,\n      functionTools,\n      {\n        allowParallelToolCalls: false,\n      },\n    );\n\n    const session = await this.getSession(\n      { ...sessionOptions, signal: options.abortSignal },\n      expectedInputs,\n      systemPrompt || undefined,\n    );\n\n    const promptCallOptions = {\n      ...promptOptions,\n      signal: options.abortSignal,\n    };\n\n    const rawResponse = await session.prompt(messages, promptCallOptions);\n\n    // Parse JSON tool calls from response\n    const { toolCalls, textContent } = parseJsonFunctionCalls(rawResponse);\n\n    if (toolCalls.length > 0) {\n      const toolCallsToEmit = toolCalls.slice(0, 1);\n\n      const parts: LanguageModelV3Content[] = [];\n\n      if (textContent) {\n        parts.push({\n          type: \"text\",\n          text: textContent,\n        });\n      }\n\n      for (const call of toolCallsToEmit) {\n        parts.push({\n          type: \"tool-call\",\n          toolCallId: call.toolCallId,\n          toolName: call.toolName,\n          input: JSON.stringify(call.args ?? {}),\n        } satisfies LanguageModelV3ToolCall);\n      }\n\n      return {\n        content: parts,\n        finishReason: { unified: \"tool-calls\", raw: \"tool-calls\" },\n        usage: {\n          inputTokens: {\n            total: undefined,\n            noCache: undefined,\n            cacheRead: undefined,\n            cacheWrite: undefined,\n          },\n          outputTokens: {\n            total: undefined,\n            text: undefined,\n            reasoning: undefined,\n          },\n        },\n        request: { body: { messages, options: promptOptions } },\n        warnings,\n      };\n    }\n\n    const content: LanguageModelV3Content[] = [\n      {\n        type: \"text\",\n        text: textContent || rawResponse,\n      },\n    ];\n\n    return {\n      content,\n      finishReason: { unified: \"stop\", raw: \"stop\" },\n      usage: {\n        inputTokens: {\n          total: undefined,\n          noCache: undefined,\n          cacheRead: undefined,\n          cacheWrite: undefined,\n        },\n        outputTokens: {\n          total: undefined,\n          text: undefined,\n          reasoning: undefined,\n        },\n      },\n      request: { body: { messages, options: promptOptions } },\n      warnings,\n    };\n  }\n\n  /**\n   * Gets the current context usage (tokens consumed) for the current session, if available\n   * @returns The context usage or undefined if not available\n   */\n  public getContextUsage(): number | undefined {\n    return this.sessionManager.getContextUsage();\n  }\n\n  /**\n   * Gets the context window size (token limit) for the current session, if available\n   * @returns The context window size or undefined if not available\n   */\n  public getContextWindow(): number | undefined {\n    return this.sessionManager.getContextWindow();\n  }\n\n  /**\n   * @deprecated Use {@link getContextUsage} instead.\n   */\n  public getInputUsage(): number | undefined {\n    return this.getContextUsage();\n  }\n\n  /**\n   * @deprecated Use {@link getContextWindow} instead.\n   */\n  public getInputQuota(): number | undefined {\n    return this.getContextWindow();\n  }\n\n  /**\n   * Check the availability of the browser AI model\n   * @returns Promise resolving to \"unavailable\", \"available\", or \"available-after-download\"\n   */\n  public async availability(): Promise<Availability> {\n    return this.sessionManager.checkAvailability();\n  }\n\n  /**\n   * Creates a session with download progress monitoring.\n   *\n   * @example\n   * ```typescript\n   * const session = await model.createSessionWithProgress(\n   *   (progress) => {\n   *     console.log(`Download progress: ${Math.round(progress * 100)}%`);\n   *   }\n   * );\n   * ```\n   *\n   * @param onDownloadProgress Optional callback receiving progress values from 0 to 1\n   * @returns Promise resolving to the model instance\n   * @throws {LoadSettingError} When the Prompt API is not available or model is unavailable\n   */\n  public async createSessionWithProgress(\n    onDownloadProgress?: DownloadProgressCallback,\n  ): Promise<BrowserAIChatLanguageModel> {\n    await this.sessionManager.createSessionWithProgress(onDownloadProgress);\n    return this;\n  }\n\n  /**\n   * Generates a streaming text response using the browser's built-in Prompt API\n   * @param options\n   * @returns Promise resolving to a readable stream of text chunks and request metadata\n   * @throws {LoadSettingError} When the Prompt API is not available or model needs to be downloaded\n   * @throws {UnsupportedFunctionalityError} When unsupported features like file input are used\n   */\n  public async doStream(\n    options: LanguageModelV3CallOptions,\n  ): Promise<LanguageModelV3StreamResult> {\n    const converted = this.getArgs(options);\n    const {\n      systemMessage,\n      messages,\n      warnings,\n      promptOptions,\n      sessionOptions,\n      expectedInputs,\n      functionTools,\n    } = converted;\n\n    // Build system prompt with JSON tool calling instructions\n    const systemPrompt = buildJsonToolSystemPrompt(\n      systemMessage,\n      functionTools,\n      {\n        allowParallelToolCalls: false,\n      },\n    );\n\n    const session = await this.getSession(\n      { ...sessionOptions, signal: options.abortSignal },\n      expectedInputs,\n      systemPrompt || undefined,\n    );\n\n    // Pass abort signal to the native streaming method\n    const streamOptions = {\n      ...promptOptions,\n      signal: options.abortSignal,\n    };\n    const conversationHistory = [...messages];\n    const textId = \"text-0\";\n\n    const stream = new ReadableStream<LanguageModelV3StreamPart>({\n      start: async (controller) => {\n        controller.enqueue({\n          type: \"stream-start\",\n          warnings,\n        });\n\n        let textStarted = false;\n        let finished = false;\n        let aborted = false;\n        let currentReader: ReadableStreamDefaultReader<string> | null = null;\n\n        const ensureTextStart = () => {\n          if (!textStarted) {\n            controller.enqueue({\n              type: \"text-start\",\n              id: textId,\n            });\n            textStarted = true;\n          }\n        };\n\n        const emitTextDelta = (delta: string) => {\n          if (!delta) return;\n          ensureTextStart();\n          controller.enqueue({\n            type: \"text-delta\",\n            id: textId,\n            delta,\n          });\n        };\n\n        const emitTextEndIfNeeded = () => {\n          if (!textStarted) return;\n          controller.enqueue({\n            type: \"text-end\",\n            id: textId,\n          });\n          textStarted = false;\n        };\n\n        const finishStream = (finishReason: LanguageModelV3FinishReason) => {\n          if (finished) return;\n          finished = true;\n          emitTextEndIfNeeded();\n          controller.enqueue({\n            type: \"finish\",\n            finishReason,\n            usage: {\n              inputTokens: {\n                total:\n                  (session as LanguageModel).contextUsage ?? session.inputUsage,\n                noCache: undefined,\n                cacheRead: undefined,\n                cacheWrite: undefined,\n              },\n              outputTokens: {\n                total: undefined,\n                text: undefined,\n                reasoning: undefined,\n              },\n            },\n          });\n          controller.close();\n        };\n\n        const abortHandler = () => {\n          if (aborted) {\n            return;\n          }\n          aborted = true;\n          if (currentReader) {\n            currentReader.cancel().catch(() => undefined);\n          }\n          finishStream({ unified: \"stop\", raw: \"aborted\" });\n        };\n\n        if (options.abortSignal) {\n          options.abortSignal.addEventListener(\"abort\", abortHandler);\n        }\n\n        try {\n          const promptStream = session.promptStreaming(\n            conversationHistory,\n            streamOptions,\n          );\n          currentReader = promptStream.getReader();\n\n          const chunks = (async function* () {\n            while (!aborted) {\n              const { done, value } = await currentReader!.read();\n              if (done) break;\n              yield value;\n            }\n          })();\n\n          const result = await processToolCallStream(\n            chunks,\n            emitTextDelta,\n            controller,\n            { stopEarlyOnToolCall: true },\n          );\n\n          if (result.toolCallDetected && currentReader) {\n            await currentReader.cancel().catch(() => undefined);\n          }\n          currentReader = null;\n\n          if (aborted) {\n            return;\n          }\n\n          if (!result.toolCallDetected || result.toolCalls.length === 0) {\n            finishStream({ unified: \"stop\", raw: \"stop\" });\n            return;\n          }\n\n          if (result.trailingText) {\n            emitTextDelta(result.trailingText);\n          }\n\n          finishStream({ unified: \"tool-calls\", raw: \"tool-calls\" });\n        } catch (error) {\n          controller.enqueue({ type: \"error\", error });\n          controller.close();\n        } finally {\n          if (options.abortSignal) {\n            options.abortSignal.removeEventListener(\"abort\", abortHandler);\n          }\n        }\n      },\n    });\n\n    return {\n      stream,\n      request: { body: { messages, options: promptOptions } },\n    };\n  }\n}\n","import {\n  EmbeddingModelV3,\n  EmbeddingModelV3CallOptions,\n  EmbeddingModelV3Result,\n} from \"@ai-sdk/provider\";\nimport { TextEmbedder } from \"@mediapipe/tasks-text\";\n\nexport interface BrowserAIEmbeddingModelSettings {\n  /**\n   * An optional base path to specify the directory the Wasm files should be loaded from.\n   * @default 'https://pub-ddcfe353995744e89b8002f16bf98575.r2.dev/text_wasm_internal.js'\n   */\n  wasmLoaderPath?: string;\n  /**\n   * It's about 6mb before gzip.\n   * @default 'https://pub-ddcfe353995744e89b8002f16bf98575.r2.dev/text_wasm_internal.wasm'\n   */\n  wasmBinaryPath?: string;\n  /**\n   * The model path to the model asset file.\n   * It's about 6.1mb before gzip.\n   * @default 'https://pub-ddcfe353995744e89b8002f16bf98575.r2.dev/universal_sentence_encoder.tflite'\n   */\n  modelAssetPath?: string;\n  /**\n   * Whether to normalize the returned feature vector with L2 norm. Use this\n   * option only if the model does not already contain a native L2_NORMALIZATION\n   * TF Lite Op. In most cases, this is already the case and L2 norm is thus\n   * achieved through TF Lite inference.\n   * @default false\n   */\n  l2Normalize?: boolean;\n  /**\n   * Whether the returned embedding should be quantized to bytes via scalar\n   * quantization. Embeddings are implicitly assumed to be unit-norm and\n   * therefore any dimension is guaranteed to have a value in [-1.0, 1.0]. Use\n   * the l2_normalize option if this is not the case.\n   * @default false\n   */\n  quantize?: boolean;\n  /**\n   * Overrides the default backend to use for the provided model.\n   */\n  delegate?: \"CPU\" | \"GPU\";\n}\n\n// See more:\n// - https://github.com/google-ai-edge/mediapipe\n// - https://ai.google.dev/edge/mediapipe/solutions/text/text_embedder/web_js\nexport class BrowserAIEmbeddingModel implements EmbeddingModelV3 {\n  readonly specificationVersion = \"v3\";\n  readonly provider = \"google-mediapipe\";\n  readonly modelId: string = \"embedding\";\n  readonly supportsParallelCalls = true;\n  readonly maxEmbeddingsPerCall = undefined;\n\n  private settings: BrowserAIEmbeddingModelSettings = {\n    wasmLoaderPath:\n      \"https://pub-ddcfe353995744e89b8002f16bf98575.r2.dev/text_wasm_internal.js\",\n    wasmBinaryPath:\n      \"https://pub-ddcfe353995744e89b8002f16bf98575.r2.dev/text_wasm_internal.wasm\",\n    modelAssetPath:\n      \"https://pub-ddcfe353995744e89b8002f16bf98575.r2.dev/universal_sentence_encoder.tflite\",\n    l2Normalize: false,\n    quantize: false,\n  };\n  private modelAssetBuffer!: Promise<ReadableStreamDefaultReader>;\n  private textEmbedder!: Promise<TextEmbedder>;\n\n  public constructor(settings: BrowserAIEmbeddingModelSettings = {}) {\n    this.settings = { ...this.settings, ...settings };\n    this.modelAssetBuffer = fetch(this.settings.modelAssetPath!).then(\n      (response) => response.body!.getReader(),\n    )!;\n    this.textEmbedder = this.getTextEmbedder();\n  }\n\n  protected getTextEmbedder = async (): Promise<TextEmbedder> => {\n    return TextEmbedder.createFromOptions(\n      {\n        wasmBinaryPath: this.settings.wasmBinaryPath!,\n        wasmLoaderPath: this.settings.wasmLoaderPath!,\n      },\n      {\n        baseOptions: {\n          modelAssetBuffer: await this.modelAssetBuffer,\n          delegate: this.settings.delegate,\n        },\n        l2Normalize: this.settings.l2Normalize,\n        quantize: this.settings.quantize,\n      },\n    );\n  };\n\n  public doEmbed = async (\n    options: EmbeddingModelV3CallOptions,\n  ): Promise<EmbeddingModelV3Result> => {\n    // Note: abortSignal is not supported by MediaPipe TextEmbedder\n    if (options.abortSignal?.aborted) {\n      throw new Error(\"Operation was aborted\");\n    }\n\n    const embedder = await this.textEmbedder;\n    const embeddings = options.values.map((text) => {\n      const embedderResult = embedder.embed(text);\n      const [embedding] = embedderResult.embeddings;\n      return embedding?.floatEmbedding ?? [];\n    });\n\n    return {\n      embeddings,\n      providerMetadata: {\n        mediapipe: {\n          model: \"universal_sentence_encoder\",\n          provider: \"google-mediapipe\",\n          processed_texts: options.values.length,\n        },\n      },\n      warnings: [],\n    };\n  };\n}\n","import {\n  EmbeddingModelV3,\n  NoSuchModelError,\n  ProviderV3,\n} from \"@ai-sdk/provider\";\nimport {\n  BrowserAIChatLanguageModel,\n  BrowserAIChatModelId,\n  BrowserAIChatSettings,\n} from \"./chat/browser-ai-language-model\";\nimport {\n  BrowserAIEmbeddingModel,\n  BrowserAIEmbeddingModelSettings,\n} from \"./embedding/browser-ai-embedding-model\";\n\nexport interface BrowserAIProvider extends ProviderV3 {\n  (\n    modelId?: BrowserAIChatModelId,\n    settings?: BrowserAIChatSettings,\n  ): BrowserAIChatLanguageModel;\n\n  /**\n   * Creates a model for text generation.\n   */\n  languageModel(\n    modelId: BrowserAIChatModelId,\n    settings?: BrowserAIChatSettings,\n  ): BrowserAIChatLanguageModel;\n\n  /**\n   * Creates a model for text generation.\n   */\n  chat(\n    modelId: BrowserAIChatModelId,\n    settings?: BrowserAIChatSettings,\n  ): BrowserAIChatLanguageModel;\n\n  embedding(\n    modelId: \"embedding\",\n    settings?: BrowserAIEmbeddingModelSettings,\n  ): EmbeddingModelV3;\n\n  embeddingModel: (\n    modelId: \"embedding\",\n    settings?: BrowserAIEmbeddingModelSettings,\n  ) => EmbeddingModelV3;\n\n  // Not implemented\n  imageModel(modelId: string): never;\n  speechModel(modelId: string): never;\n  transcriptionModel(modelId: string): never;\n}\n\nexport interface BrowserAIProviderSettings {\n  // Currently empty - provider settings are minimal for BrowserAI\n  // Future provider-level settings can be added here\n}\n\n/**\n * Create a BrowserAI provider instance.\n */\nexport function createBrowserAI(\n  options: BrowserAIProviderSettings = {},\n): BrowserAIProvider {\n  const createChatModel = (\n    modelId: BrowserAIChatModelId,\n    settings?: BrowserAIChatSettings,\n  ) => {\n    return new BrowserAIChatLanguageModel(modelId, settings);\n  };\n\n  const createEmbeddingModel = (\n    modelId: \"embedding\",\n    settings?: BrowserAIEmbeddingModelSettings,\n  ) => {\n    return new BrowserAIEmbeddingModel(settings);\n  };\n\n  const provider = function (\n    modelId: BrowserAIChatModelId = \"text\",\n    settings?: BrowserAIChatSettings,\n  ) {\n    if (new.target) {\n      throw new Error(\n        \"The BrowserAI model function cannot be called with the new keyword.\",\n      );\n    }\n\n    return createChatModel(modelId, settings);\n  };\n\n  provider.specificationVersion = \"v3\" as const;\n  provider.languageModel = createChatModel;\n  provider.chat = createChatModel;\n  provider.embedding = createEmbeddingModel;\n  provider.embeddingModel = createEmbeddingModel;\n\n  provider.imageModel = (modelId: string) => {\n    throw new NoSuchModelError({ modelId, modelType: \"imageModel\" });\n  };\n\n  provider.speechModel = (modelId: string) => {\n    throw new NoSuchModelError({ modelId, modelType: \"speechModel\" });\n  };\n\n  provider.transcriptionModel = (modelId: string) => {\n    throw new NoSuchModelError({ modelId, modelType: \"transcriptionModel\" });\n  };\n\n  return provider;\n}\n\n/**\n * Default BrowserAI provider instance.\n */\nexport const browserAI = createBrowserAI();\n"],"mappings":"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","names":["prefixText","generateToolCallId"]}