{"version":3,"sources":["../src/index.ts","../src/goose-web-provider.ts","../src/goose-web-language-model.ts","../src/errors.ts"],"sourcesContent":["/**\n * Provider exports for creating and configuring Goose Web instances.\n * @module goose-web\n */\n\n/**\n * Creates a new Goose Web provider instance and the default provider instance.\n * @see {@link createGooseWeb} for creating custom provider instances\n * @see {@link gooseWeb} for the default provider instance\n */\nexport { createGooseWeb, gooseWeb } from \"./goose-web-provider.js\";\n\n/**\n * Type definitions for the Goose Web provider.\n * @see {@link GooseWebProvider} for the provider interface\n * @see {@link GooseWebProviderSettings} for provider configuration options\n */\nexport type {\n  GooseWebProvider,\n  GooseWebProviderSettings,\n} from \"./goose-web-provider.js\";\n\n/**\n * Language model implementation for Goose Web.\n * This class implements the AI SDK's LanguageModelV2 interface.\n */\nexport { GooseWebLanguageModel } from \"./goose-web-language-model.js\";\n\n/**\n * Standalone function to validate a Goose session.\n * Call this before creating a model to check if a session exists and get a valid session ID.\n *\n * @see {@link validateGooseSession} for session validation without creating a model instance\n */\nexport { validateGooseSession } from \"./goose-web-language-model.js\";\n\n/**\n * Type definitions for Goose Web language models.\n * @see {@link GooseWebModelId} for supported model identifiers\n * @see {@link GooseWebLanguageModelOptions} for model configuration options\n */\nexport type {\n  GooseWebModelId,\n  GooseWebLanguageModelOptions,\n} from \"./goose-web-language-model.js\";\n\n/**\n * Settings for configuring Goose Web behavior.\n * Includes options for customizing the WebSocket connection, timeouts, and session management.\n */\nexport type {\n  GooseWebSettings,\n  Logger,\n  GooseWebMessage,\n  GooseWebResponse,\n} from \"./types.js\";\n\n/**\n * Error handling utilities for Goose Web.\n * These functions help create and identify specific error types.\n *\n * @see {@link isConnectionError} to check for connection failures\n * @see {@link isTimeoutError} to check for timeout errors\n * @see {@link getErrorMetadata} to extract error metadata\n * @see {@link createAPICallError} to create general API errors\n * @see {@link createConnectionError} to create connection errors\n * @see {@link createTimeoutError} to create timeout errors\n */\nexport {\n  isConnectionError,\n  isTimeoutError,\n  getErrorMetadata,\n  createAPICallError,\n  createConnectionError,\n  createTimeoutError,\n} from \"./errors.js\";\n\n/**\n * Metadata associated with Goose Web errors.\n * Contains additional context about WebSocket connection failures.\n */\nexport type { GooseWebErrorMetadata } from \"./errors.js\";\n","import type { LanguageModelV2, ProviderV2 } from \"@ai-sdk/provider\";\nimport { NoSuchModelError } from \"@ai-sdk/provider\";\nimport {\n  GooseWebLanguageModel,\n  type GooseWebModelId,\n} from \"./goose-web-language-model.js\";\nimport type { GooseWebSettings } from \"./types.js\";\n\n/**\n * Goose Web provider interface that extends the AI SDK's ProviderV2.\n * Provides methods to create language models for interacting with Goose via WebSocket.\n *\n * @example\n * ```typescript\n * import { gooseWeb } from 'ai-sdk-provider-goose-web';\n *\n * // Create a model instance\n * const model = gooseWeb('goose');\n *\n * // Or use the explicit methods\n * const chatModel = gooseWeb.chat('goose');\n * const languageModel = gooseWeb.languageModel('goose', { wsUrl: 'ws://localhost:8080/ws' });\n * ```\n */\nexport interface GooseWebProvider extends ProviderV2 {\n  /**\n   * Creates a language model instance for the specified model ID.\n   * This is a shorthand for calling `languageModel()`.\n   *\n   * @param modelId - The Goose model to use (typically 'goose')\n   * @param settings - Optional settings to configure the model\n   * @returns A language model instance\n   */\n  (modelId: GooseWebModelId, settings?: GooseWebSettings): LanguageModelV2;\n\n  /**\n   * Creates a language model instance for text generation.\n   *\n   * @param modelId - The Goose model to use (typically 'goose')\n   * @param settings - Optional settings to configure the model\n   * @returns A language model instance\n   */\n  languageModel(\n    modelId: GooseWebModelId,\n    settings?: GooseWebSettings\n  ): LanguageModelV2;\n\n  /**\n   * Alias for `languageModel()` to maintain compatibility with AI SDK patterns.\n   *\n   * @param modelId - The Goose model to use (typically 'goose')\n   * @param settings - Optional settings to configure the model\n   * @returns A language model instance\n   */\n  chat(modelId: GooseWebModelId, settings?: GooseWebSettings): LanguageModelV2;\n\n  /**\n   * Text embedding models are not supported by Goose Web.\n   * @throws Always throws an error\n   */\n  textEmbeddingModel(modelId: string): never;\n\n  /**\n   * Image models are not supported by Goose Web.\n   * @throws Always throws an error\n   */\n  imageModel(modelId: string): never;\n}\n\n/**\n * Configuration settings for the Goose Web provider.\n */\nexport interface GooseWebProviderSettings extends GooseWebSettings {\n  // Add any provider-level settings here if needed\n}\n\n/**\n * Creates a new Goose Web provider instance.\n *\n * @param settings - Optional provider-level configuration\n * @returns A new Goose Web provider instance\n *\n * @example\n * ```typescript\n * import { createGooseWeb } from 'ai-sdk-provider-goose-web';\n *\n * const provider = createGooseWeb({\n *   wsUrl: 'ws://localhost:8080/ws',\n *   sessionId: 'my-session'\n * });\n *\n * const model = provider('goose');\n * ```\n */\nexport function createGooseWeb(\n  settings: GooseWebProviderSettings = {}\n): GooseWebProvider {\n  const createModel = (\n    modelId: GooseWebModelId,\n    modelSettings?: GooseWebSettings\n  ): LanguageModelV2 => {\n    // Validate model ID\n    if (modelId !== \"goose\" && typeof modelId !== \"string\") {\n      throw new NoSuchModelError({\n        modelId: String(modelId),\n        modelType: \"languageModel\",\n      });\n    }\n\n    // Merge provider and model settings\n    const mergedSettings: GooseWebSettings = {\n      ...settings,\n      ...modelSettings,\n    };\n\n    return new GooseWebLanguageModel({\n      id: modelId,\n      settings: mergedSettings,\n    });\n  };\n\n  const provider = Object.assign(createModel, {\n    languageModel: createModel,\n    chat: createModel,\n    textEmbeddingModel: (modelId: string): never => {\n      throw new NoSuchModelError({ modelId, modelType: \"textEmbeddingModel\" });\n    },\n    imageModel: (modelId: string): never => {\n      throw new NoSuchModelError({ modelId, modelType: \"imageModel\" });\n    },\n  });\n\n  return provider;\n}\n\n/**\n * Default Goose Web provider instance.\n * This is a convenience export that creates a provider with default settings.\n *\n * @example\n * ```typescript\n * import { gooseWeb } from 'ai-sdk-provider-goose-web';\n *\n * const model = gooseWeb('goose');\n * ```\n */\nexport const gooseWeb = createGooseWeb();\n","import type {\n  LanguageModelV2,\n  LanguageModelV2CallWarning,\n  LanguageModelV2FinishReason,\n  LanguageModelV2StreamPart,\n  LanguageModelV2Usage,\n  JSONValue,\n} from \"@ai-sdk/provider\";\nimport { APICallError } from \"@ai-sdk/provider\";\nimport { generateId } from \"@ai-sdk/provider-utils\";\nimport WebSocket from \"ws\";\nimport type {\n  GooseWebSettings,\n  Logger,\n  GooseWebMessage,\n  GooseWebResponse,\n} from \"./types.js\";\nimport {\n  createAPICallError,\n  createConnectionError,\n  createTimeoutError,\n} from \"./errors.js\";\n\n/**\n * Options for creating a Goose Web language model instance.\n */\nexport interface GooseWebLanguageModelOptions {\n  /**\n   * The model identifier to use.\n   */\n  id: GooseWebModelId;\n\n  /**\n   * Optional settings to configure the model behavior.\n   */\n  settings?: GooseWebSettings;\n}\n\n/**\n * Supported Goose model identifiers.\n */\nexport type GooseWebModelId = \"goose\" | (string & {});\n\n/**\n * Helper function to validate if a session exists.\n */\nasync function validateSessionExistsHelper(\n  wsUrl: string,\n  sessionId: string,\n  authToken?: string,\n  logger?: Logger\n): Promise<boolean> {\n  const httpUrl = wsUrl\n    .replace(/^wss:\\/\\//, \"https://\")\n    .replace(/^ws:\\/\\//, \"http://\")\n    .replace(/\\/ws$/, \"\");\n\n  const headers: Record<string, string> = {};\n  if (authToken) {\n    headers[\"Authorization\"] = `Bearer ${authToken}`;\n  }\n\n  try {\n    const response = await fetch(`${httpUrl}/api/sessions/${sessionId}`, {\n      method: \"GET\",\n      headers,\n    });\n\n    if (!response.ok) {\n      logger?.debug(\"Session validation failed - HTTP error\", {\n        sessionId,\n        status: response.status,\n      });\n      return false;\n    }\n\n    const data = await response.json();\n\n    logger?.debug(\"Session validation response\", {\n      sessionId,\n      status: response.status,\n      hasError: !!data.error,\n    });\n\n    return !data.error;\n  } catch (error) {\n    logger?.error(\"Failed to validate session\", {\n      sessionId,\n      error: error instanceof Error ? error.message : String(error),\n    });\n    return false;\n  }\n}\n\n/**\n * Helper function to create a new session.\n */\nasync function createNewSessionHelper(\n  wsUrl: string,\n  authToken?: string,\n  logger?: Logger\n): Promise<string> {\n  const httpUrl = wsUrl\n    .replace(/^wss:\\/\\//, \"https://\")\n    .replace(/^ws:\\/\\//, \"http://\")\n    .replace(/\\/ws$/, \"\");\n\n  logger?.debug(\"Creating session via REST API\", { wsUrl, httpUrl });\n\n  const headers: Record<string, string> = {};\n  if (authToken) {\n    headers[\"Authorization\"] = `Bearer ${authToken}`;\n  }\n\n  try {\n    const response = await fetch(httpUrl, {\n      method: \"GET\",\n      redirect: \"manual\",\n      headers,\n    });\n\n    logger?.debug(\"REST API response received\", {\n      status: response.status,\n      statusText: response.statusText,\n      headers: Object.fromEntries(response.headers.entries()),\n    });\n\n    const location = response.headers.get(\"location\");\n    logger?.debug(\"Location header\", { location });\n\n    if (location && location.startsWith(\"/session/\")) {\n      const newSessionId = location.replace(\"/session/\", \"\");\n      logger?.debug(\"Session created successfully\", {\n        sessionId: newSessionId,\n      });\n      return newSessionId;\n    } else {\n      logger?.error(\"No redirect received from REST API\", {\n        location,\n        responseStatus: response.status,\n      });\n      throw createConnectionError(\n        \"Failed to create session: No redirect received from REST API\",\n        { wsUrl: httpUrl, responseStatus: response.status }\n      );\n    }\n  } catch (error) {\n    const errorMessage = error instanceof Error ? error.message : String(error);\n    logger?.error(\"Failed to create session via REST API\", {\n      httpUrl,\n      error: errorMessage,\n    });\n    throw createConnectionError(\n      `Failed to create session via REST API: ${errorMessage}`,\n      { wsUrl: httpUrl }\n    );\n  }\n}\n\n/**\n * Language model implementation for Goose Web.\n * Connects to a Goose server via WebSocket for AI interactions.\n */\nexport class GooseWebLanguageModel implements LanguageModelV2 {\n  readonly specificationVersion = \"v2\" as const;\n  readonly defaultObjectGenerationMode = \"tool\" as const;\n  readonly provider = \"goose-web\" as const;\n  readonly modelId: GooseWebModelId;\n  readonly settings: GooseWebSettings;\n  readonly supportsImageUrls = false;\n  readonly supportedUrls = {};\n  readonly supportsStructuredOutputs = false;\n\n  private logger?: Logger;\n  private sessionId: string;\n  private sessionCreated: boolean;\n\n  constructor(options: GooseWebLanguageModelOptions) {\n    this.modelId = options.id;\n    this.settings = {\n      wsUrl: \"ws://localhost:8080/ws\",\n      connectionTimeout: 30000,\n      responseTimeout: 120000,\n      ...options.settings,\n    };\n    this.logger = this.settings.logger;\n    this.sessionId = this.settings.sessionId || \"\";\n    // If assumeSessionValid is true and sessionId is provided, skip validation\n    this.sessionCreated = !!(\n      this.settings.assumeSessionValid && this.settings.sessionId\n    );\n  }\n\n  private async validateSessionExists(sessionId: string): Promise<boolean> {\n    return validateSessionExistsHelper(\n      this.settings.wsUrl!,\n      sessionId,\n      this.settings.authToken,\n      this.logger\n    );\n  }\n\n  /**\n   * Ensures a valid session exists, creating one if needed.\n   * Call this immediately after model creation to validate the session\n   * before sending any messages. This allows you to know if an old session\n   * was invalidated so you can decide whether to include full conversation history.\n   *\n   * Note: If you've already validated the session using validateGooseSession(),\n   * you can pass assumeSessionValid: true to the model settings to skip re-validation.\n   *\n   * @returns Object containing the sessionId and whether an old session was invalidated\n   */\n  public async ensureSession(): Promise<{\n    sessionId: string;\n    oldSessionInvalidated: boolean;\n  }> {\n    this.logger?.debug(\"ensureSession called\", {\n      sessionCreated: this.sessionCreated,\n      sessionId: this.sessionId,\n      providedSessionId: this.settings.sessionId,\n    });\n\n    if (this.sessionCreated && this.sessionId) {\n      this.logger?.debug(\"Session already exists, skipping creation\");\n      return { sessionId: this.sessionId, oldSessionInvalidated: false };\n    }\n\n    // Track if we're replacing an invalid session\n    let oldSessionInvalidated = false;\n\n    // If sessionId provided in settings, validate it exists\n    if (this.settings.sessionId) {\n      const isValid = await this.validateSessionExists(this.settings.sessionId);\n\n      if (isValid) {\n        this.sessionId = this.settings.sessionId;\n        this.sessionCreated = true;\n        this.logger?.debug(\"Using provided session ID\", {\n          sessionId: this.sessionId,\n        });\n        return { sessionId: this.sessionId, oldSessionInvalidated: false };\n      } else {\n        this.logger?.warn(\n          \"Provided session ID is invalid, creating new session\",\n          {\n            oldSessionId: this.settings.sessionId,\n          }\n        );\n        // Fall through to create a new session, but remember we had an old one\n        oldSessionInvalidated = true;\n      }\n    }\n\n    // Create new session\n    this.sessionId = await createNewSessionHelper(\n      this.settings.wsUrl!,\n      this.settings.authToken,\n      this.logger\n    );\n    this.sessionCreated = true;\n\n    return { sessionId: this.sessionId, oldSessionInvalidated };\n  }\n\n  private createWebSocket(): Promise<WebSocket> {\n    return new Promise((resolve, reject) => {\n      const wsOptions: any = {};\n      if (this.settings.authToken) {\n        wsOptions.headers = {\n          Authorization: `Bearer ${this.settings.authToken}`,\n        };\n      }\n\n      const ws = new WebSocket(this.settings.wsUrl!, wsOptions);\n      const timeout = setTimeout(() => {\n        ws.close();\n        reject(\n          createConnectionError(\n            `Connection timeout after ${this.settings.connectionTimeout}ms`,\n            { wsUrl: this.settings.wsUrl, sessionId: this.sessionId }\n          )\n        );\n      }, this.settings.connectionTimeout);\n\n      ws.onopen = () => {\n        clearTimeout(timeout);\n        this.logger?.debug(\"WebSocket connected\", {\n          wsUrl: this.settings.wsUrl,\n        });\n        resolve(ws);\n      };\n\n      ws.onerror = (error) => {\n        clearTimeout(timeout);\n        this.logger?.error(\"WebSocket connection error\", error);\n        reject(\n          createConnectionError(\"Failed to connect to Goose server\", {\n            wsUrl: this.settings.wsUrl,\n            sessionId: this.sessionId,\n          })\n        );\n      };\n    });\n  }\n\n  async doGenerate(options: Parameters<LanguageModelV2[\"doGenerate\"]>[0]) {\n    const { prompt, responseFormat, ...rest } = options;\n\n    // Ensure session exists before creating WebSocket\n    await this.ensureSession();\n\n    // Convert messages to a single text prompt for Goose\n    let userMessage = this.convertPromptToText(prompt);\n\n    // Add JSON format instruction if needed\n    if (responseFormat?.type === \"json\") {\n      userMessage += \"\\n\\nPlease respond with valid JSON only.\";\n      if (responseFormat.schema) {\n        userMessage += ` Follow this JSON schema: ${JSON.stringify(\n          responseFormat.schema\n        )}`;\n      }\n    }\n\n    const ws = await this.createWebSocket();\n\n    try {\n      const result = await this.generateResponse(ws, userMessage, false);\n\n      // Extract JSON if responseFormat indicates JSON mode\n      if (\n        responseFormat?.type === \"json\" &&\n        result.content?.[0]?.type === \"text\"\n      ) {\n        const extractedJson = this.extractJson(result.content[0].text);\n        result.content[0].text = extractedJson;\n      }\n\n      return result;\n    } finally {\n      ws.close();\n    }\n  }\n\n  async doStream(\n    options: Parameters<LanguageModelV2[\"doStream\"]>[0]\n  ): Promise<Awaited<ReturnType<LanguageModelV2[\"doStream\"]>>> {\n    const { prompt, responseFormat, ...rest } = options;\n\n    // Ensure session exists before creating WebSocket\n    await this.ensureSession();\n\n    // Convert messages to a single text prompt for Goose\n    let userMessage = this.convertPromptToText(prompt);\n\n    // Add JSON format instruction if needed\n    if (responseFormat?.type === \"json\") {\n      userMessage += \"\\n\\nPlease respond with valid JSON only.\";\n      if (responseFormat.schema) {\n        userMessage += ` Follow this JSON schema: ${JSON.stringify(\n          responseFormat.schema\n        )}`;\n      }\n    }\n\n    const ws = await this.createWebSocket();\n\n    const stream = this.createStreamFromAsyncGenerator(\n      this.streamResponse(ws, userMessage),\n      responseFormat\n    );\n\n    return {\n      stream,\n      request: {\n        body: userMessage,\n      },\n    };\n  }\n\n  private convertPromptToText(\n    prompt: Parameters<LanguageModelV2[\"doGenerate\"]>[0][\"prompt\"]\n  ): string {\n    // Handle array of messages (most common case)\n    if (Array.isArray(prompt)) {\n      const messages: string[] = [];\n\n      for (const message of prompt) {\n        if (!message || typeof message !== \"object\") continue;\n\n        switch (message.role) {\n          case \"system\":\n            // Add system message as context\n            if (typeof message.content === \"string\") {\n              messages.unshift(`System: ${message.content}`);\n            }\n            break;\n\n          case \"user\":\n          case \"assistant\":\n            if (typeof message.content === \"string\") {\n              messages.push(message.content);\n            } else if (Array.isArray(message.content)) {\n              // Handle multi-part content\n              const textParts = message.content\n                .filter((part) => part && part.type === \"text\")\n                .map((part) => {\n                  // Type guard to ensure we have a text part\n                  if (part.type === \"text\" && \"text\" in part) {\n                    return part.text;\n                  }\n                  return \"\";\n                })\n                .filter(Boolean);\n              if (textParts.length > 0) {\n                messages.push(textParts.join(\" \"));\n              }\n            }\n            break;\n        }\n      }\n\n      return messages.join(\"\\n\\n\");\n    }\n\n    // Handle string prompt\n    if (typeof prompt === \"string\") {\n      return prompt;\n    }\n\n    // Fallback for unknown format\n    return String(prompt || \"\");\n  }\n\n  private async generateResponse(\n    ws: WebSocket,\n    message: string,\n    streaming: boolean\n  ) {\n    return new Promise<any>((resolve, reject) => {\n      let responseText = \"\";\n      let usage: LanguageModelV2Usage = {\n        inputTokens: 0,\n        outputTokens: 0,\n        totalTokens: 0,\n      };\n\n      const timeout = setTimeout(() => {\n        ws.close();\n        reject(\n          createTimeoutError(this.settings.responseTimeout!, {\n            wsUrl: this.settings.wsUrl,\n            sessionId: this.sessionId,\n            lastMessage: message,\n          })\n        );\n      }, this.settings.responseTimeout);\n\n      ws.onmessage = (event) => {\n        try {\n          const data: GooseWebResponse = JSON.parse(event.data.toString());\n          this.logger?.debug(\"Received WebSocket message\", data);\n\n          switch (data.type) {\n            case \"response\":\n              if (data.content) {\n                responseText += data.content;\n              }\n              break;\n\n            case \"complete\":\n              clearTimeout(timeout);\n              resolve({\n                content: [{ type: \"text\", text: responseText }],\n                finishReason: \"stop\" as LanguageModelV2FinishReason,\n                usage,\n                warnings: [],\n                response: {\n                  id: generateId(),\n                  timestamp: new Date(),\n                  modelId: this.modelId,\n                },\n                request: {\n                  body: message,\n                },\n                providerMetadata: {\n                  \"goose-web\": {\n                    sessionId: this.sessionId,\n                  },\n                },\n              });\n              break;\n\n            case \"error\":\n              clearTimeout(timeout);\n              reject(\n                createAPICallError(\n                  data.message || \"Unknown error from Goose server\",\n                  {\n                    wsUrl: this.settings.wsUrl,\n                    sessionId: this.sessionId,\n                    lastMessage: message,\n                  }\n                )\n              );\n              break;\n          }\n        } catch (error) {\n          this.logger?.error(\"Failed to parse WebSocket message\", error);\n        }\n      };\n\n      ws.onerror = (error) => {\n        clearTimeout(timeout);\n        reject(\n          createConnectionError(\"WebSocket error during generation\", {\n            wsUrl: this.settings.wsUrl,\n            sessionId: this.sessionId,\n          })\n        );\n      };\n\n      ws.onclose = (event) => {\n        if (event.code !== 1000) {\n          clearTimeout(timeout);\n          reject(\n            createConnectionError(\n              `WebSocket closed unexpectedly: ${event.code} ${event.reason}`,\n              { wsUrl: this.settings.wsUrl, sessionId: this.sessionId }\n            )\n          );\n        }\n      };\n\n      // Send the message\n      const gooseMessage: GooseWebMessage = {\n        type: \"message\",\n        content: message,\n        session_id: this.sessionId,\n        timestamp: Date.now(),\n      };\n\n      ws.send(JSON.stringify(gooseMessage));\n      this.logger?.debug(\"Sent message to Goose server\", gooseMessage);\n    });\n  }\n\n  private async *streamResponse(\n    ws: WebSocket,\n    message: string\n  ): AsyncGenerator<LanguageModelV2StreamPart> {\n    let responseText = \"\";\n    let finished = false;\n    let currentStreamingMessage: {\n      textPartId: string;\n      content: string;\n    } | null = null;\n    let textStartEmitted = false;\n\n    const messageQueue: LanguageModelV2StreamPart[] = [];\n    let resolveNext:\n      | ((value: IteratorResult<LanguageModelV2StreamPart>) => void)\n      | null = null;\n    let pendingTextStart: LanguageModelV2StreamPart | null = null;\n\n    const timeout = setTimeout(() => {\n      ws.close();\n      if (resolveNext) {\n        resolveNext({ done: true, value: undefined });\n      }\n    }, this.settings.responseTimeout);\n\n    const enqueueStreamPart = (part: LanguageModelV2StreamPart) => {\n      this.logger?.debug(\"Enqueueing stream part:\", part);\n\n      // Special handling for text-start: store it but don't yield immediately\n      if (part.type === \"text-start\") {\n        pendingTextStart = part;\n        return;\n      }\n\n      // For text-delta: yield text-start first if we have one\n      if (part.type === \"text-delta\" && pendingTextStart) {\n        // Always queue text-start first, then text-delta\n        messageQueue.push(pendingTextStart);\n        messageQueue.push(part);\n        pendingTextStart = null;\n\n        // Wake up the generator if it's waiting\n        if (resolveNext) {\n          const resolve = resolveNext;\n          resolveNext = null;\n          resolve({ done: false, value: null as any });\n        }\n        return;\n      }\n\n      // Default enqueueing: always add to queue and wake up generator\n      messageQueue.push(part);\n\n      if (resolveNext) {\n        this.logger?.debug(`Waking up generator for queued part: ${part.type}`);\n        const resolve = resolveNext;\n        resolveNext = null;\n        resolve({ done: false, value: null as any });\n      } else {\n        this.logger?.debug(`No resolveNext, part queued: ${part.type}`);\n      }\n    };\n\n    ws.onmessage = (event) => {\n      try {\n        const data: GooseWebResponse = JSON.parse(event.data.toString());\n        this.logger?.debug(\"Received WebSocket message\", data);\n\n        switch (data.type) {\n          case \"response\":\n            if (data.content) {\n              responseText += data.content;\n\n              // If this is the first chunk of any content, emit text-start once\n              if (!textStartEmitted) {\n                const textPartId = generateId();\n                currentStreamingMessage = {\n                  textPartId,\n                  content: data.content,\n                };\n                textStartEmitted = true;\n\n                // Start new text part\n                enqueueStreamPart({\n                  type: \"text-start\",\n                  id: textPartId,\n                });\n\n                enqueueStreamPart({\n                  type: \"text-delta\",\n                  id: textPartId,\n                  delta: data.content,\n                });\n              } else if (currentStreamingMessage) {\n                // Continue existing streaming message\n                currentStreamingMessage.content += data.content;\n\n                enqueueStreamPart({\n                  type: \"text-delta\",\n                  id: currentStreamingMessage.textPartId,\n                  delta: data.content,\n                });\n              }\n            }\n            break;\n\n          case \"tool_request\":\n            // End current streaming message if we were in the middle of one (matches Goose web client)\n            if (currentStreamingMessage) {\n              enqueueStreamPart({\n                type: \"text-end\",\n                id: currentStreamingMessage.textPartId,\n              });\n              // Reset streaming message so tool doesn't interfere with message flow\n              currentStreamingMessage = null;\n            }\n\n            // Reset textStartEmitted so that content after tools can create new text parts\n            textStartEmitted = false;\n\n            // Emit tool call\n            enqueueStreamPart({\n              type: \"tool-call\",\n              toolCallId: data.id || generateId(),\n              toolName: data.tool_name || \"unknown\",\n              input: JSON.stringify(data.arguments || {}),\n            });\n            break;\n\n          case \"tool_response\":\n            // Reset streaming message so next assistant response creates a new message (matches Goose web client)\n            currentStreamingMessage = null;\n            textStartEmitted = false; // Allow new text parts after tool calls\n\n            // Emit tool result if we have a matching tool call\n            if (data.result) {\n              const toolResult = Array.isArray(data.result)\n                ? data.result.map((r) => r.text || JSON.stringify(r)).join(\"\\n\")\n                : typeof data.result === \"string\"\n                ? data.result\n                : JSON.stringify(data.result);\n\n              enqueueStreamPart({\n                type: \"tool-result\",\n                toolCallId: data.id || generateId(),\n                toolName: data.tool_name || \"unknown\",\n                result: toolResult,\n              });\n            }\n            break;\n\n          case \"complete\":\n            clearTimeout(timeout);\n            finished = true;\n\n            // Finalize any streaming message (matches Goose web client)\n            if (currentStreamingMessage) {\n              enqueueStreamPart({\n                type: \"text-end\",\n                id: currentStreamingMessage.textPartId,\n              });\n              currentStreamingMessage = null;\n            }\n\n            // Emit finish\n            enqueueStreamPart({\n              type: \"finish\",\n              finishReason: \"stop\",\n              usage: {\n                inputTokens: 0,\n                outputTokens: 0,\n                totalTokens: 0,\n              },\n              providerMetadata: {\n                \"goose-web\": {\n                  sessionId: this.sessionId,\n                },\n              },\n            });\n            break;\n\n          case \"error\":\n            clearTimeout(timeout);\n            finished = true;\n\n            // End any streaming message if we were in the middle of one\n            if (currentStreamingMessage) {\n              enqueueStreamPart({\n                type: \"text-end\",\n                id: currentStreamingMessage.textPartId,\n              });\n              currentStreamingMessage = null;\n            }\n\n            enqueueStreamPart({\n              type: \"error\",\n              error: createAPICallError(\n                data.message || \"Unknown error from Goose server\",\n                {\n                  wsUrl: this.settings.wsUrl,\n                  sessionId: this.sessionId,\n                  lastMessage: message,\n                }\n              ),\n            });\n            break;\n        }\n      } catch (error) {\n        this.logger?.error(\"Failed to parse WebSocket message\", error);\n      }\n    };\n\n    ws.onerror = () => {\n      clearTimeout(timeout);\n      finished = true;\n      const errorPart: LanguageModelV2StreamPart = {\n        type: \"error\",\n        error: createConnectionError(\"WebSocket error during streaming\", {\n          wsUrl: this.settings.wsUrl,\n          sessionId: this.sessionId,\n        }),\n      };\n\n      if (resolveNext) {\n        resolveNext({ done: false, value: errorPart });\n        resolveNext = null;\n      } else {\n        messageQueue.push(errorPart);\n      }\n    };\n\n    // Send the message\n    const gooseMessage: GooseWebMessage = {\n      type: \"message\",\n      content: message,\n      session_id: this.sessionId,\n      timestamp: Date.now(),\n    };\n\n    ws.send(JSON.stringify(gooseMessage));\n    this.logger?.debug(\"Sent message to Goose server\", gooseMessage);\n\n    // Generator loop\n    while (!finished || messageQueue.length > 0) {\n      this.logger?.debug(\n        `Generator loop: finished=${finished}, queue length=${messageQueue.length}`\n      );\n      if (messageQueue.length > 0) {\n        const part = messageQueue.shift()!;\n        this.logger?.debug(`Yielding part: ${part.type}`);\n        yield part;\n      } else {\n        this.logger?.debug(\"Waiting for next message...\");\n        await new Promise<void>((resolve) => {\n          resolveNext = (result) => {\n            if (!result.done) {\n              resolve();\n            }\n          };\n        });\n        this.logger?.debug(\"Generator woken up, checking queue...\");\n      }\n    }\n\n    ws.close();\n  }\n\n  private createStreamFromAsyncGenerator(\n    generator: AsyncGenerator<LanguageModelV2StreamPart>,\n    responseFormat?: { type: \"json\"; schema?: unknown } | { type: \"text\" }\n  ): ReadableStream<LanguageModelV2StreamPart> {\n    const self = this;\n    let iteratorRunning = false;\n\n    return new ReadableStream<LanguageModelV2StreamPart>(\n      {\n        async start(controller) {\n          // Start consuming the generator immediately in the background\n          // This ensures we process WebSocket messages as they arrive\n          if (!iteratorRunning) {\n            iteratorRunning = true;\n            (async () => {\n              try {\n                let accumulatedText = \"\";\n\n                for await (const part of generator) {\n                  // Accumulate text for JSON extraction\n                  if (part.type === \"text-delta\") {\n                    accumulatedText += part.delta;\n                  }\n\n                  // Handle JSON extraction on finish for JSON mode\n                  if (\n                    part.type === \"finish\" &&\n                    responseFormat?.type === \"json\" &&\n                    accumulatedText\n                  ) {\n                    const extractedJson = self.extractJson(accumulatedText);\n                    if (extractedJson !== accumulatedText) {\n                      // Emit a new text sequence with just the JSON\n                      const jsonId = generateId();\n                      controller.enqueue({ type: \"text-start\", id: jsonId });\n                      controller.enqueue({\n                        type: \"text-delta\",\n                        id: jsonId,\n                        delta: extractedJson,\n                      });\n                      controller.enqueue({ type: \"text-end\", id: jsonId });\n                    }\n                  }\n\n                  // Skip text parts in JSON mode since we'll emit clean JSON\n                  if (\n                    responseFormat?.type === \"json\" &&\n                    (part.type === \"text-start\" ||\n                      part.type === \"text-delta\" ||\n                      part.type === \"text-end\")\n                  ) {\n                    continue;\n                  }\n\n                  controller.enqueue(part);\n                }\n\n                controller.close();\n              } catch (error) {\n                controller.error(error);\n              }\n            })();\n          }\n        },\n      },\n      // Add a high water mark to minimize buffering - parts should flow through immediately\n      new CountQueuingStrategy({ highWaterMark: 1 })\n    );\n  }\n\n  /**\n   * Extracts JSON from a text response that might contain other text.\n   * Looks for JSON objects or arrays and returns the first valid one found.\n   */\n  private extractJson(text: string): string {\n    // Try to find JSON in the text\n    const jsonMatch = text.match(/\\{[\\s\\S]*\\}|\\[[\\s\\S]*\\]/);\n    if (jsonMatch) {\n      try {\n        // Validate that it's valid JSON\n        JSON.parse(jsonMatch[0]);\n        return jsonMatch[0];\n      } catch (e) {\n        // If not valid JSON, return the original text\n        return text;\n      }\n    }\n\n    // If no JSON found, return original text\n    return text;\n  }\n}\n\n/**\n * Standalone function to validate a Goose session.\n * Call this before creating a model to check if a session exists and get a valid session ID.\n *\n * @param settings - Configuration including wsUrl and optional sessionId\n * @returns Object containing the sessionId and whether an old session was invalidated\n *\n * @example\n * ```typescript\n * const { sessionId, oldSessionInvalidated } = await validateGooseSession({\n *   wsUrl: \"ws://localhost:8080/ws\",\n *   sessionId: \"old_session_id\", // optional\n *   authToken: \"your-auth-token\", // optional\n * });\n *\n * if (oldSessionInvalidated) {\n *   // Send full conversation history\n * }\n *\n * // Pass assumeSessionValid: true to skip re-validation in the model\n * const model = gooseWeb(\"goose\", {\n *   wsUrl,\n *   sessionId,\n *   authToken,\n *   assumeSessionValid: true  // Skip validation since we just validated it\n * });\n * ```\n */\nexport async function validateGooseSession(settings: {\n  wsUrl: string;\n  sessionId?: string;\n  authToken?: string;\n  logger?: Logger;\n}): Promise<{ sessionId: string; oldSessionInvalidated: boolean }> {\n  const { wsUrl, sessionId, authToken, logger } = settings;\n\n  // Main validation logic\n  let oldSessionInvalidated = false;\n\n  if (sessionId) {\n    const isValid = await validateSessionExistsHelper(\n      wsUrl,\n      sessionId,\n      authToken,\n      logger\n    );\n\n    if (isValid) {\n      logger?.debug(\"Using provided session ID\", { sessionId });\n      return { sessionId, oldSessionInvalidated: false };\n    } else {\n      logger?.warn(\"Provided session ID is invalid, creating new session\", {\n        oldSessionId: sessionId,\n      });\n      oldSessionInvalidated = true;\n    }\n  }\n\n  // Create new session\n  const newSessionId = await createNewSessionHelper(wsUrl, authToken, logger);\n  return { sessionId: newSessionId, oldSessionInvalidated };\n}\n","import { APICallError } from \"@ai-sdk/provider\";\n\n/**\n * Metadata associated with Goose Web errors.\n */\nexport interface GooseWebErrorMetadata {\n  wsUrl?: string;\n  sessionId?: string;\n  lastMessage?: string;\n  connectionState?: \"connecting\" | \"connected\" | \"disconnected\" | \"error\";\n  responseStatus?: number;\n}\n\n/**\n * Creates a general API call error for Goose Web operations.\n */\nexport function createAPICallError(\n  message: string,\n  metadata?: GooseWebErrorMetadata\n): APICallError {\n  return new APICallError({\n    message,\n    url: metadata?.wsUrl || \"ws://unknown\",\n    requestBodyValues: metadata?.lastMessage\n      ? { message: metadata.lastMessage }\n      : undefined,\n    data: metadata,\n    isRetryable: false,\n  });\n}\n\n/**\n * Creates a connection error for WebSocket failures.\n */\nexport function createConnectionError(\n  message: string,\n  metadata?: GooseWebErrorMetadata\n): APICallError {\n  return new APICallError({\n    message: `Connection error: ${message}`,\n    url: metadata?.wsUrl || \"ws://unknown\",\n    requestBodyValues: metadata?.lastMessage\n      ? { message: metadata.lastMessage }\n      : undefined,\n    data: metadata,\n    isRetryable: true,\n  });\n}\n\n/**\n * Creates a timeout error for Goose Web operations.\n */\nexport function createTimeoutError(\n  timeoutMs: number,\n  metadata?: GooseWebErrorMetadata\n): APICallError {\n  return new APICallError({\n    message: `Request timed out after ${timeoutMs}ms`,\n    url: metadata?.wsUrl || \"ws://unknown\",\n    requestBodyValues: metadata?.lastMessage\n      ? { message: metadata.lastMessage }\n      : undefined,\n    data: metadata,\n    isRetryable: true,\n  });\n}\n\n/**\n * Checks if an error is a connection error.\n */\nexport function isConnectionError(error: unknown): boolean {\n  return (\n    error instanceof APICallError && error.message.includes(\"Connection error\")\n  );\n}\n\n/**\n * Checks if an error is a timeout error.\n */\nexport function isTimeoutError(error: unknown): boolean {\n  return error instanceof APICallError && error.message.includes(\"timed out\");\n}\n\n/**\n * Gets error metadata from a Goose Web error.\n */\nexport function getErrorMetadata(error: unknown): GooseWebErrorMetadata | null {\n  if (error instanceof APICallError && error.data) {\n    return error.data as GooseWebErrorMetadata;\n  }\n  return null;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,IAAAA,mBAAiC;;;ACOjC,IAAAC,mBAA6B;AAC7B,4BAA2B;AAC3B,gBAAsB;;;ACVtB,sBAA6B;AAgBtB,SAAS,mBACd,SACA,UACc;AACd,SAAO,IAAI,6BAAa;AAAA,IACtB;AAAA,IACA,KAAK,UAAU,SAAS;AAAA,IACxB,mBAAmB,UAAU,cACzB,EAAE,SAAS,SAAS,YAAY,IAChC;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf,CAAC;AACH;AAKO,SAAS,sBACd,SACA,UACc;AACd,SAAO,IAAI,6BAAa;AAAA,IACtB,SAAS,qBAAqB,OAAO;AAAA,IACrC,KAAK,UAAU,SAAS;AAAA,IACxB,mBAAmB,UAAU,cACzB,EAAE,SAAS,SAAS,YAAY,IAChC;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf,CAAC;AACH;AAKO,SAAS,mBACd,WACA,UACc;AACd,SAAO,IAAI,6BAAa;AAAA,IACtB,SAAS,2BAA2B,SAAS;AAAA,IAC7C,KAAK,UAAU,SAAS;AAAA,IACxB,mBAAmB,UAAU,cACzB,EAAE,SAAS,SAAS,YAAY,IAChC;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf,CAAC;AACH;AAKO,SAAS,kBAAkB,OAAyB;AACzD,SACE,iBAAiB,gCAAgB,MAAM,QAAQ,SAAS,kBAAkB;AAE9E;AAKO,SAAS,eAAe,OAAyB;AACtD,SAAO,iBAAiB,gCAAgB,MAAM,QAAQ,SAAS,WAAW;AAC5E;AAKO,SAAS,iBAAiB,OAA8C;AAC7E,MAAI,iBAAiB,gCAAgB,MAAM,MAAM;AAC/C,WAAO,MAAM;AAAA,EACf;AACA,SAAO;AACT;;;AD7CA,eAAe,4BACb,OACA,WACA,WACA,QACkB;AAClB,QAAM,UAAU,MACb,QAAQ,aAAa,UAAU,EAC/B,QAAQ,YAAY,SAAS,EAC7B,QAAQ,SAAS,EAAE;AAEtB,QAAM,UAAkC,CAAC;AACzC,MAAI,WAAW;AACb,YAAQ,eAAe,IAAI,UAAU,SAAS;AAAA,EAChD;AAEA,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,GAAG,OAAO,iBAAiB,SAAS,IAAI;AAAA,MACnE,QAAQ;AAAA,MACR;AAAA,IACF,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,cAAQ,MAAM,0CAA0C;AAAA,QACtD;AAAA,QACA,QAAQ,SAAS;AAAA,MACnB,CAAC;AACD,aAAO;AAAA,IACT;AAEA,UAAM,OAAO,MAAM,SAAS,KAAK;AAEjC,YAAQ,MAAM,+BAA+B;AAAA,MAC3C;AAAA,MACA,QAAQ,SAAS;AAAA,MACjB,UAAU,CAAC,CAAC,KAAK;AAAA,IACnB,CAAC;AAED,WAAO,CAAC,KAAK;AAAA,EACf,SAAS,OAAO;AACd,YAAQ,MAAM,8BAA8B;AAAA,MAC1C;AAAA,MACA,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,IAC9D,CAAC;AACD,WAAO;AAAA,EACT;AACF;AAKA,eAAe,uBACb,OACA,WACA,QACiB;AACjB,QAAM,UAAU,MACb,QAAQ,aAAa,UAAU,EAC/B,QAAQ,YAAY,SAAS,EAC7B,QAAQ,SAAS,EAAE;AAEtB,UAAQ,MAAM,iCAAiC,EAAE,OAAO,QAAQ,CAAC;AAEjE,QAAM,UAAkC,CAAC;AACzC,MAAI,WAAW;AACb,YAAQ,eAAe,IAAI,UAAU,SAAS;AAAA,EAChD;AAEA,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,SAAS;AAAA,MACpC,QAAQ;AAAA,MACR,UAAU;AAAA,MACV;AAAA,IACF,CAAC;AAED,YAAQ,MAAM,8BAA8B;AAAA,MAC1C,QAAQ,SAAS;AAAA,MACjB,YAAY,SAAS;AAAA,MACrB,SAAS,OAAO,YAAY,SAAS,QAAQ,QAAQ,CAAC;AAAA,IACxD,CAAC;AAED,UAAM,WAAW,SAAS,QAAQ,IAAI,UAAU;AAChD,YAAQ,MAAM,mBAAmB,EAAE,SAAS,CAAC;AAE7C,QAAI,YAAY,SAAS,WAAW,WAAW,GAAG;AAChD,YAAM,eAAe,SAAS,QAAQ,aAAa,EAAE;AACrD,cAAQ,MAAM,gCAAgC;AAAA,QAC5C,WAAW;AAAA,MACb,CAAC;AACD,aAAO;AAAA,IACT,OAAO;AACL,cAAQ,MAAM,sCAAsC;AAAA,QAClD;AAAA,QACA,gBAAgB,SAAS;AAAA,MAC3B,CAAC;AACD,YAAM;AAAA,QACJ;AAAA,QACA,EAAE,OAAO,SAAS,gBAAgB,SAAS,OAAO;AAAA,MACpD;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,UAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,YAAQ,MAAM,yCAAyC;AAAA,MACrD;AAAA,MACA,OAAO;AAAA,IACT,CAAC;AACD,UAAM;AAAA,MACJ,0CAA0C,YAAY;AAAA,MACtD,EAAE,OAAO,QAAQ;AAAA,IACnB;AAAA,EACF;AACF;AAMO,IAAM,wBAAN,MAAuD;AAAA,EACnD,uBAAuB;AAAA,EACvB,8BAA8B;AAAA,EAC9B,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA,oBAAoB;AAAA,EACpB,gBAAgB,CAAC;AAAA,EACjB,4BAA4B;AAAA,EAE7B;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,SAAuC;AACjD,SAAK,UAAU,QAAQ;AACvB,SAAK,WAAW;AAAA,MACd,OAAO;AAAA,MACP,mBAAmB;AAAA,MACnB,iBAAiB;AAAA,MACjB,GAAG,QAAQ;AAAA,IACb;AACA,SAAK,SAAS,KAAK,SAAS;AAC5B,SAAK,YAAY,KAAK,SAAS,aAAa;AAE5C,SAAK,iBAAiB,CAAC,EACrB,KAAK,SAAS,sBAAsB,KAAK,SAAS;AAAA,EAEtD;AAAA,EAEA,MAAc,sBAAsB,WAAqC;AACvE,WAAO;AAAA,MACL,KAAK,SAAS;AAAA,MACd;AAAA,MACA,KAAK,SAAS;AAAA,MACd,KAAK;AAAA,IACP;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAa,gBAGV;AACD,SAAK,QAAQ,MAAM,wBAAwB;AAAA,MACzC,gBAAgB,KAAK;AAAA,MACrB,WAAW,KAAK;AAAA,MAChB,mBAAmB,KAAK,SAAS;AAAA,IACnC,CAAC;AAED,QAAI,KAAK,kBAAkB,KAAK,WAAW;AACzC,WAAK,QAAQ,MAAM,2CAA2C;AAC9D,aAAO,EAAE,WAAW,KAAK,WAAW,uBAAuB,MAAM;AAAA,IACnE;AAGA,QAAI,wBAAwB;AAG5B,QAAI,KAAK,SAAS,WAAW;AAC3B,YAAM,UAAU,MAAM,KAAK,sBAAsB,KAAK,SAAS,SAAS;AAExE,UAAI,SAAS;AACX,aAAK,YAAY,KAAK,SAAS;AAC/B,aAAK,iBAAiB;AACtB,aAAK,QAAQ,MAAM,6BAA6B;AAAA,UAC9C,WAAW,KAAK;AAAA,QAClB,CAAC;AACD,eAAO,EAAE,WAAW,KAAK,WAAW,uBAAuB,MAAM;AAAA,MACnE,OAAO;AACL,aAAK,QAAQ;AAAA,UACX;AAAA,UACA;AAAA,YACE,cAAc,KAAK,SAAS;AAAA,UAC9B;AAAA,QACF;AAEA,gCAAwB;AAAA,MAC1B;AAAA,IACF;AAGA,SAAK,YAAY,MAAM;AAAA,MACrB,KAAK,SAAS;AAAA,MACd,KAAK,SAAS;AAAA,MACd,KAAK;AAAA,IACP;AACA,SAAK,iBAAiB;AAEtB,WAAO,EAAE,WAAW,KAAK,WAAW,sBAAsB;AAAA,EAC5D;AAAA,EAEQ,kBAAsC;AAC5C,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,YAAiB,CAAC;AACxB,UAAI,KAAK,SAAS,WAAW;AAC3B,kBAAU,UAAU;AAAA,UAClB,eAAe,UAAU,KAAK,SAAS,SAAS;AAAA,QAClD;AAAA,MACF;AAEA,YAAM,KAAK,IAAI,UAAAC,QAAU,KAAK,SAAS,OAAQ,SAAS;AACxD,YAAM,UAAU,WAAW,MAAM;AAC/B,WAAG,MAAM;AACT;AAAA,UACE;AAAA,YACE,4BAA4B,KAAK,SAAS,iBAAiB;AAAA,YAC3D,EAAE,OAAO,KAAK,SAAS,OAAO,WAAW,KAAK,UAAU;AAAA,UAC1D;AAAA,QACF;AAAA,MACF,GAAG,KAAK,SAAS,iBAAiB;AAElC,SAAG,SAAS,MAAM;AAChB,qBAAa,OAAO;AACpB,aAAK,QAAQ,MAAM,uBAAuB;AAAA,UACxC,OAAO,KAAK,SAAS;AAAA,QACvB,CAAC;AACD,gBAAQ,EAAE;AAAA,MACZ;AAEA,SAAG,UAAU,CAAC,UAAU;AACtB,qBAAa,OAAO;AACpB,aAAK,QAAQ,MAAM,8BAA8B,KAAK;AACtD;AAAA,UACE,sBAAsB,qCAAqC;AAAA,YACzD,OAAO,KAAK,SAAS;AAAA,YACrB,WAAW,KAAK;AAAA,UAClB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,WAAW,SAAuD;AACtE,UAAM,EAAE,QAAQ,gBAAgB,GAAG,KAAK,IAAI;AAG5C,UAAM,KAAK,cAAc;AAGzB,QAAI,cAAc,KAAK,oBAAoB,MAAM;AAGjD,QAAI,gBAAgB,SAAS,QAAQ;AACnC,qBAAe;AACf,UAAI,eAAe,QAAQ;AACzB,uBAAe,6BAA6B,KAAK;AAAA,UAC/C,eAAe;AAAA,QACjB,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,KAAK,MAAM,KAAK,gBAAgB;AAEtC,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,iBAAiB,IAAI,aAAa,KAAK;AAGjE,UACE,gBAAgB,SAAS,UACzB,OAAO,UAAU,CAAC,GAAG,SAAS,QAC9B;AACA,cAAM,gBAAgB,KAAK,YAAY,OAAO,QAAQ,CAAC,EAAE,IAAI;AAC7D,eAAO,QAAQ,CAAC,EAAE,OAAO;AAAA,MAC3B;AAEA,aAAO;AAAA,IACT,UAAE;AACA,SAAG,MAAM;AAAA,IACX;AAAA,EACF;AAAA,EAEA,MAAM,SACJ,SAC2D;AAC3D,UAAM,EAAE,QAAQ,gBAAgB,GAAG,KAAK,IAAI;AAG5C,UAAM,KAAK,cAAc;AAGzB,QAAI,cAAc,KAAK,oBAAoB,MAAM;AAGjD,QAAI,gBAAgB,SAAS,QAAQ;AACnC,qBAAe;AACf,UAAI,eAAe,QAAQ;AACzB,uBAAe,6BAA6B,KAAK;AAAA,UAC/C,eAAe;AAAA,QACjB,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,KAAK,MAAM,KAAK,gBAAgB;AAEtC,UAAM,SAAS,KAAK;AAAA,MAClB,KAAK,eAAe,IAAI,WAAW;AAAA,MACnC;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA,SAAS;AAAA,QACP,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,oBACN,QACQ;AAER,QAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,YAAM,WAAqB,CAAC;AAE5B,iBAAW,WAAW,QAAQ;AAC5B,YAAI,CAAC,WAAW,OAAO,YAAY,SAAU;AAE7C,gBAAQ,QAAQ,MAAM;AAAA,UACpB,KAAK;AAEH,gBAAI,OAAO,QAAQ,YAAY,UAAU;AACvC,uBAAS,QAAQ,WAAW,QAAQ,OAAO,EAAE;AAAA,YAC/C;AACA;AAAA,UAEF,KAAK;AAAA,UACL,KAAK;AACH,gBAAI,OAAO,QAAQ,YAAY,UAAU;AACvC,uBAAS,KAAK,QAAQ,OAAO;AAAA,YAC/B,WAAW,MAAM,QAAQ,QAAQ,OAAO,GAAG;AAEzC,oBAAM,YAAY,QAAQ,QACvB,OAAO,CAAC,SAAS,QAAQ,KAAK,SAAS,MAAM,EAC7C,IAAI,CAAC,SAAS;AAEb,oBAAI,KAAK,SAAS,UAAU,UAAU,MAAM;AAC1C,yBAAO,KAAK;AAAA,gBACd;AACA,uBAAO;AAAA,cACT,CAAC,EACA,OAAO,OAAO;AACjB,kBAAI,UAAU,SAAS,GAAG;AACxB,yBAAS,KAAK,UAAU,KAAK,GAAG,CAAC;AAAA,cACnC;AAAA,YACF;AACA;AAAA,QACJ;AAAA,MACF;AAEA,aAAO,SAAS,KAAK,MAAM;AAAA,IAC7B;AAGA,QAAI,OAAO,WAAW,UAAU;AAC9B,aAAO;AAAA,IACT;AAGA,WAAO,OAAO,UAAU,EAAE;AAAA,EAC5B;AAAA,EAEA,MAAc,iBACZ,IACA,SACA,WACA;AACA,WAAO,IAAI,QAAa,CAAC,SAAS,WAAW;AAC3C,UAAI,eAAe;AACnB,UAAI,QAA8B;AAAA,QAChC,aAAa;AAAA,QACb,cAAc;AAAA,QACd,aAAa;AAAA,MACf;AAEA,YAAM,UAAU,WAAW,MAAM;AAC/B,WAAG,MAAM;AACT;AAAA,UACE,mBAAmB,KAAK,SAAS,iBAAkB;AAAA,YACjD,OAAO,KAAK,SAAS;AAAA,YACrB,WAAW,KAAK;AAAA,YAChB,aAAa;AAAA,UACf,CAAC;AAAA,QACH;AAAA,MACF,GAAG,KAAK,SAAS,eAAe;AAEhC,SAAG,YAAY,CAAC,UAAU;AACxB,YAAI;AACF,gBAAM,OAAyB,KAAK,MAAM,MAAM,KAAK,SAAS,CAAC;AAC/D,eAAK,QAAQ,MAAM,8BAA8B,IAAI;AAErD,kBAAQ,KAAK,MAAM;AAAA,YACjB,KAAK;AACH,kBAAI,KAAK,SAAS;AAChB,gCAAgB,KAAK;AAAA,cACvB;AACA;AAAA,YAEF,KAAK;AACH,2BAAa,OAAO;AACpB,sBAAQ;AAAA,gBACN,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,aAAa,CAAC;AAAA,gBAC9C,cAAc;AAAA,gBACd;AAAA,gBACA,UAAU,CAAC;AAAA,gBACX,UAAU;AAAA,kBACR,QAAI,kCAAW;AAAA,kBACf,WAAW,oBAAI,KAAK;AAAA,kBACpB,SAAS,KAAK;AAAA,gBAChB;AAAA,gBACA,SAAS;AAAA,kBACP,MAAM;AAAA,gBACR;AAAA,gBACA,kBAAkB;AAAA,kBAChB,aAAa;AAAA,oBACX,WAAW,KAAK;AAAA,kBAClB;AAAA,gBACF;AAAA,cACF,CAAC;AACD;AAAA,YAEF,KAAK;AACH,2BAAa,OAAO;AACpB;AAAA,gBACE;AAAA,kBACE,KAAK,WAAW;AAAA,kBAChB;AAAA,oBACE,OAAO,KAAK,SAAS;AAAA,oBACrB,WAAW,KAAK;AAAA,oBAChB,aAAa;AAAA,kBACf;AAAA,gBACF;AAAA,cACF;AACA;AAAA,UACJ;AAAA,QACF,SAAS,OAAO;AACd,eAAK,QAAQ,MAAM,qCAAqC,KAAK;AAAA,QAC/D;AAAA,MACF;AAEA,SAAG,UAAU,CAAC,UAAU;AACtB,qBAAa,OAAO;AACpB;AAAA,UACE,sBAAsB,qCAAqC;AAAA,YACzD,OAAO,KAAK,SAAS;AAAA,YACrB,WAAW,KAAK;AAAA,UAClB,CAAC;AAAA,QACH;AAAA,MACF;AAEA,SAAG,UAAU,CAAC,UAAU;AACtB,YAAI,MAAM,SAAS,KAAM;AACvB,uBAAa,OAAO;AACpB;AAAA,YACE;AAAA,cACE,kCAAkC,MAAM,IAAI,IAAI,MAAM,MAAM;AAAA,cAC5D,EAAE,OAAO,KAAK,SAAS,OAAO,WAAW,KAAK,UAAU;AAAA,YAC1D;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAGA,YAAM,eAAgC;AAAA,QACpC,MAAM;AAAA,QACN,SAAS;AAAA,QACT,YAAY,KAAK;AAAA,QACjB,WAAW,KAAK,IAAI;AAAA,MACtB;AAEA,SAAG,KAAK,KAAK,UAAU,YAAY,CAAC;AACpC,WAAK,QAAQ,MAAM,gCAAgC,YAAY;AAAA,IACjE,CAAC;AAAA,EACH;AAAA,EAEA,OAAe,eACb,IACA,SAC2C;AAC3C,QAAI,eAAe;AACnB,QAAI,WAAW;AACf,QAAI,0BAGO;AACX,QAAI,mBAAmB;AAEvB,UAAM,eAA4C,CAAC;AACnD,QAAI,cAEO;AACX,QAAI,mBAAqD;AAEzD,UAAM,UAAU,WAAW,MAAM;AAC/B,SAAG,MAAM;AACT,UAAI,aAAa;AACf,oBAAY,EAAE,MAAM,MAAM,OAAO,OAAU,CAAC;AAAA,MAC9C;AAAA,IACF,GAAG,KAAK,SAAS,eAAe;AAEhC,UAAM,oBAAoB,CAAC,SAAoC;AAC7D,WAAK,QAAQ,MAAM,2BAA2B,IAAI;AAGlD,UAAI,KAAK,SAAS,cAAc;AAC9B,2BAAmB;AACnB;AAAA,MACF;AAGA,UAAI,KAAK,SAAS,gBAAgB,kBAAkB;AAElD,qBAAa,KAAK,gBAAgB;AAClC,qBAAa,KAAK,IAAI;AACtB,2BAAmB;AAGnB,YAAI,aAAa;AACf,gBAAM,UAAU;AAChB,wBAAc;AACd,kBAAQ,EAAE,MAAM,OAAO,OAAO,KAAY,CAAC;AAAA,QAC7C;AACA;AAAA,MACF;AAGA,mBAAa,KAAK,IAAI;AAEtB,UAAI,aAAa;AACf,aAAK,QAAQ,MAAM,wCAAwC,KAAK,IAAI,EAAE;AACtE,cAAM,UAAU;AAChB,sBAAc;AACd,gBAAQ,EAAE,MAAM,OAAO,OAAO,KAAY,CAAC;AAAA,MAC7C,OAAO;AACL,aAAK,QAAQ,MAAM,gCAAgC,KAAK,IAAI,EAAE;AAAA,MAChE;AAAA,IACF;AAEA,OAAG,YAAY,CAAC,UAAU;AACxB,UAAI;AACF,cAAM,OAAyB,KAAK,MAAM,MAAM,KAAK,SAAS,CAAC;AAC/D,aAAK,QAAQ,MAAM,8BAA8B,IAAI;AAErD,gBAAQ,KAAK,MAAM;AAAA,UACjB,KAAK;AACH,gBAAI,KAAK,SAAS;AAChB,8BAAgB,KAAK;AAGrB,kBAAI,CAAC,kBAAkB;AACrB,sBAAM,iBAAa,kCAAW;AAC9B,0CAA0B;AAAA,kBACxB;AAAA,kBACA,SAAS,KAAK;AAAA,gBAChB;AACA,mCAAmB;AAGnB,kCAAkB;AAAA,kBAChB,MAAM;AAAA,kBACN,IAAI;AAAA,gBACN,CAAC;AAED,kCAAkB;AAAA,kBAChB,MAAM;AAAA,kBACN,IAAI;AAAA,kBACJ,OAAO,KAAK;AAAA,gBACd,CAAC;AAAA,cACH,WAAW,yBAAyB;AAElC,wCAAwB,WAAW,KAAK;AAExC,kCAAkB;AAAA,kBAChB,MAAM;AAAA,kBACN,IAAI,wBAAwB;AAAA,kBAC5B,OAAO,KAAK;AAAA,gBACd,CAAC;AAAA,cACH;AAAA,YACF;AACA;AAAA,UAEF,KAAK;AAEH,gBAAI,yBAAyB;AAC3B,gCAAkB;AAAA,gBAChB,MAAM;AAAA,gBACN,IAAI,wBAAwB;AAAA,cAC9B,CAAC;AAED,wCAA0B;AAAA,YAC5B;AAGA,+BAAmB;AAGnB,8BAAkB;AAAA,cAChB,MAAM;AAAA,cACN,YAAY,KAAK,UAAM,kCAAW;AAAA,cAClC,UAAU,KAAK,aAAa;AAAA,cAC5B,OAAO,KAAK,UAAU,KAAK,aAAa,CAAC,CAAC;AAAA,YAC5C,CAAC;AACD;AAAA,UAEF,KAAK;AAEH,sCAA0B;AAC1B,+BAAmB;AAGnB,gBAAI,KAAK,QAAQ;AACf,oBAAM,aAAa,MAAM,QAAQ,KAAK,MAAM,IACxC,KAAK,OAAO,IAAI,CAAC,MAAM,EAAE,QAAQ,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,IAAI,IAC7D,OAAO,KAAK,WAAW,WACvB,KAAK,SACL,KAAK,UAAU,KAAK,MAAM;AAE9B,gCAAkB;AAAA,gBAChB,MAAM;AAAA,gBACN,YAAY,KAAK,UAAM,kCAAW;AAAA,gBAClC,UAAU,KAAK,aAAa;AAAA,gBAC5B,QAAQ;AAAA,cACV,CAAC;AAAA,YACH;AACA;AAAA,UAEF,KAAK;AACH,yBAAa,OAAO;AACpB,uBAAW;AAGX,gBAAI,yBAAyB;AAC3B,gCAAkB;AAAA,gBAChB,MAAM;AAAA,gBACN,IAAI,wBAAwB;AAAA,cAC9B,CAAC;AACD,wCAA0B;AAAA,YAC5B;AAGA,8BAAkB;AAAA,cAChB,MAAM;AAAA,cACN,cAAc;AAAA,cACd,OAAO;AAAA,gBACL,aAAa;AAAA,gBACb,cAAc;AAAA,gBACd,aAAa;AAAA,cACf;AAAA,cACA,kBAAkB;AAAA,gBAChB,aAAa;AAAA,kBACX,WAAW,KAAK;AAAA,gBAClB;AAAA,cACF;AAAA,YACF,CAAC;AACD;AAAA,UAEF,KAAK;AACH,yBAAa,OAAO;AACpB,uBAAW;AAGX,gBAAI,yBAAyB;AAC3B,gCAAkB;AAAA,gBAChB,MAAM;AAAA,gBACN,IAAI,wBAAwB;AAAA,cAC9B,CAAC;AACD,wCAA0B;AAAA,YAC5B;AAEA,8BAAkB;AAAA,cAChB,MAAM;AAAA,cACN,OAAO;AAAA,gBACL,KAAK,WAAW;AAAA,gBAChB;AAAA,kBACE,OAAO,KAAK,SAAS;AAAA,kBACrB,WAAW,KAAK;AAAA,kBAChB,aAAa;AAAA,gBACf;AAAA,cACF;AAAA,YACF,CAAC;AACD;AAAA,QACJ;AAAA,MACF,SAAS,OAAO;AACd,aAAK,QAAQ,MAAM,qCAAqC,KAAK;AAAA,MAC/D;AAAA,IACF;AAEA,OAAG,UAAU,MAAM;AACjB,mBAAa,OAAO;AACpB,iBAAW;AACX,YAAM,YAAuC;AAAA,QAC3C,MAAM;AAAA,QACN,OAAO,sBAAsB,oCAAoC;AAAA,UAC/D,OAAO,KAAK,SAAS;AAAA,UACrB,WAAW,KAAK;AAAA,QAClB,CAAC;AAAA,MACH;AAEA,UAAI,aAAa;AACf,oBAAY,EAAE,MAAM,OAAO,OAAO,UAAU,CAAC;AAC7C,sBAAc;AAAA,MAChB,OAAO;AACL,qBAAa,KAAK,SAAS;AAAA,MAC7B;AAAA,IACF;AAGA,UAAM,eAAgC;AAAA,MACpC,MAAM;AAAA,MACN,SAAS;AAAA,MACT,YAAY,KAAK;AAAA,MACjB,WAAW,KAAK,IAAI;AAAA,IACtB;AAEA,OAAG,KAAK,KAAK,UAAU,YAAY,CAAC;AACpC,SAAK,QAAQ,MAAM,gCAAgC,YAAY;AAG/D,WAAO,CAAC,YAAY,aAAa,SAAS,GAAG;AAC3C,WAAK,QAAQ;AAAA,QACX,4BAA4B,QAAQ,kBAAkB,aAAa,MAAM;AAAA,MAC3E;AACA,UAAI,aAAa,SAAS,GAAG;AAC3B,cAAM,OAAO,aAAa,MAAM;AAChC,aAAK,QAAQ,MAAM,kBAAkB,KAAK,IAAI,EAAE;AAChD,cAAM;AAAA,MACR,OAAO;AACL,aAAK,QAAQ,MAAM,6BAA6B;AAChD,cAAM,IAAI,QAAc,CAAC,YAAY;AACnC,wBAAc,CAAC,WAAW;AACxB,gBAAI,CAAC,OAAO,MAAM;AAChB,sBAAQ;AAAA,YACV;AAAA,UACF;AAAA,QACF,CAAC;AACD,aAAK,QAAQ,MAAM,uCAAuC;AAAA,MAC5D;AAAA,IACF;AAEA,OAAG,MAAM;AAAA,EACX;AAAA,EAEQ,+BACN,WACA,gBAC2C;AAC3C,UAAM,OAAO;AACb,QAAI,kBAAkB;AAEtB,WAAO,IAAI;AAAA,MACT;AAAA,QACE,MAAM,MAAM,YAAY;AAGtB,cAAI,CAAC,iBAAiB;AACpB,8BAAkB;AAClB,aAAC,YAAY;AACX,kBAAI;AACF,oBAAI,kBAAkB;AAEtB,iCAAiB,QAAQ,WAAW;AAElC,sBAAI,KAAK,SAAS,cAAc;AAC9B,uCAAmB,KAAK;AAAA,kBAC1B;AAGA,sBACE,KAAK,SAAS,YACd,gBAAgB,SAAS,UACzB,iBACA;AACA,0BAAM,gBAAgB,KAAK,YAAY,eAAe;AACtD,wBAAI,kBAAkB,iBAAiB;AAErC,4BAAM,aAAS,kCAAW;AAC1B,iCAAW,QAAQ,EAAE,MAAM,cAAc,IAAI,OAAO,CAAC;AACrD,iCAAW,QAAQ;AAAA,wBACjB,MAAM;AAAA,wBACN,IAAI;AAAA,wBACJ,OAAO;AAAA,sBACT,CAAC;AACD,iCAAW,QAAQ,EAAE,MAAM,YAAY,IAAI,OAAO,CAAC;AAAA,oBACrD;AAAA,kBACF;AAGA,sBACE,gBAAgB,SAAS,WACxB,KAAK,SAAS,gBACb,KAAK,SAAS,gBACd,KAAK,SAAS,aAChB;AACA;AAAA,kBACF;AAEA,6BAAW,QAAQ,IAAI;AAAA,gBACzB;AAEA,2BAAW,MAAM;AAAA,cACnB,SAAS,OAAO;AACd,2BAAW,MAAM,KAAK;AAAA,cACxB;AAAA,YACF,GAAG;AAAA,UACL;AAAA,QACF;AAAA,MACF;AAAA;AAAA,MAEA,IAAI,qBAAqB,EAAE,eAAe,EAAE,CAAC;AAAA,IAC/C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,YAAY,MAAsB;AAExC,UAAM,YAAY,KAAK,MAAM,yBAAyB;AACtD,QAAI,WAAW;AACb,UAAI;AAEF,aAAK,MAAM,UAAU,CAAC,CAAC;AACvB,eAAO,UAAU,CAAC;AAAA,MACpB,SAAS,GAAG;AAEV,eAAO;AAAA,MACT;AAAA,IACF;AAGA,WAAO;AAAA,EACT;AACF;AA8BA,eAAsB,qBAAqB,UAKwB;AACjE,QAAM,EAAE,OAAO,WAAW,WAAW,OAAO,IAAI;AAGhD,MAAI,wBAAwB;AAE5B,MAAI,WAAW;AACb,UAAM,UAAU,MAAM;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,QAAI,SAAS;AACX,cAAQ,MAAM,6BAA6B,EAAE,UAAU,CAAC;AACxD,aAAO,EAAE,WAAW,uBAAuB,MAAM;AAAA,IACnD,OAAO;AACL,cAAQ,KAAK,wDAAwD;AAAA,QACnE,cAAc;AAAA,MAChB,CAAC;AACD,8BAAwB;AAAA,IAC1B;AAAA,EACF;AAGA,QAAM,eAAe,MAAM,uBAAuB,OAAO,WAAW,MAAM;AAC1E,SAAO,EAAE,WAAW,cAAc,sBAAsB;AAC1D;;;AD32BO,SAAS,eACd,WAAqC,CAAC,GACpB;AAClB,QAAM,cAAc,CAClB,SACA,kBACoB;AAEpB,QAAI,YAAY,WAAW,OAAO,YAAY,UAAU;AACtD,YAAM,IAAI,kCAAiB;AAAA,QACzB,SAAS,OAAO,OAAO;AAAA,QACvB,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAGA,UAAM,iBAAmC;AAAA,MACvC,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAEA,WAAO,IAAI,sBAAsB;AAAA,MAC/B,IAAI;AAAA,MACJ,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AAEA,QAAM,WAAW,OAAO,OAAO,aAAa;AAAA,IAC1C,eAAe;AAAA,IACf,MAAM;AAAA,IACN,oBAAoB,CAAC,YAA2B;AAC9C,YAAM,IAAI,kCAAiB,EAAE,SAAS,WAAW,qBAAqB,CAAC;AAAA,IACzE;AAAA,IACA,YAAY,CAAC,YAA2B;AACtC,YAAM,IAAI,kCAAiB,EAAE,SAAS,WAAW,aAAa,CAAC;AAAA,IACjE;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAaO,IAAM,WAAW,eAAe;","names":["import_provider","import_provider","WebSocket"]}