{"version":3,"file":"index.cjs","names":["messages: BaseMessage[]","content: UserContent","content: AssistantContent","output: ToolResultOutput","content: ToolContent","result: GenerateTextResult<ToolSet, any>","AIMessage","generation: ChatGeneration","result: StreamTextResult<ToolSet, any>","partialToolCalls: Map<string, { toolName: string; input: string; index: number }>","streamedToolCallIds: Set<string>","ChatGenerationChunk","AIMessageChunk","finishMessage: {\n          content: string;\n          usage_metadata?: {\n            input_tokens: number;\n            output_tokens: number;\n            total_tokens: number;\n          };\n        }","schema: unknown","ZodType","tools: BindToolsInput[]","toolSet: ToolSet","BaseChatModel","fields: ChatDatabricksInput","Config","messages: BaseMessage[]","options: this[\"ParsedCallOptions\"]","runManager?: CallbackManagerForLLMRun","tools: BindToolsInput[]","kwargs?: Partial<ChatDatabricksCallOptions>","config: Config","_clientInfo: OAuthClientInformationMixed","_scope?: string","_tokens: OAuthTokens","_authorizationUrl: URL","_codeVerifier: string","config: BaseMCPServerConfig","url: string","config: StreamableHTTPConnection","config: MCPServerConfig","config: DatabricksMCPServerConfig","Config","catalog: string","schema: string","functionName?: string","options: { auth?: DatabricksConfigOptions; timeout?: number }","indexName?: string","spaceId: string","servers: ServerInstance[]","config: Record<string, StreamableHTTPConnection>"],"sources":["../src/utils/messages.ts","../src/utils/tools.ts","../src/chat_models.ts","../src/mcp/databricks_oauth_provider.ts","../src/mcp/mcp_server.ts","../src/mcp/databricks_mcp_client.ts"],"sourcesContent":["/**\n * Message conversion utilities between LangChain and AI SDK formats\n */\n\nimport { JSONValue } from \"@ai-sdk/provider\";\nimport {\n  BaseMessage,\n  AIMessage,\n  AIMessageChunk,\n  HumanMessage,\n  SystemMessage,\n  ToolMessage,\n} from \"@langchain/core/messages\";\nimport { ChatResult, ChatGeneration, ChatGenerationChunk } from \"@langchain/core/outputs\";\nimport {\n  type GenerateTextResult,\n  type ToolSet,\n  type ModelMessage,\n  type StreamTextResult,\n} from \"ai\";\n\ntype UserContent = Extract<ModelMessage, { role: \"user\" }>[\"content\"];\ntype AssistantContent = Extract<ModelMessage, { role: \"assistant\" }>[\"content\"];\ntype ToolContent = Extract<ModelMessage, { role: \"tool\" }>[\"content\"];\n/**\n * Convert LangChain messages to AI SDK ModelMessage format\n */\nexport function convertLangChainToModelMessages(messages: BaseMessage[]): ModelMessage[] {\n  return messages.map((msg) => {\n    if (SystemMessage.isInstance(msg)) {\n      return {\n        role: \"system\" as const,\n        content: String(msg.content),\n      };\n    }\n\n    if (HumanMessage.isInstance(msg)) {\n      const content: UserContent = [];\n      if (typeof msg.content === \"string\") {\n        content.push({ type: \"text\", text: msg.content });\n      } else if (Array.isArray(msg.content)) {\n        for (const part of msg.content) {\n          if (typeof part === \"string\") {\n            content.push({ type: \"text\", text: part });\n          } else if (part.type === \"text\") {\n            content.push({ type: \"text\", text: String(part.text) });\n          } else if (part.type === \"image_url\") {\n            throw new Error(\n              \"Image content is not yet supported in ChatDatabricks. \" +\n                \"Please use text-only messages.\"\n            );\n          }\n        }\n      }\n      return {\n        role: \"user\" as const,\n        content,\n      };\n    }\n\n    if (AIMessage.isInstance(msg)) {\n      const content: AssistantContent = [];\n\n      // Add text content\n      if (typeof msg.content === \"string\" && msg.content) {\n        content.push({ type: \"text\", text: msg.content });\n      } else if (Array.isArray(msg.content)) {\n        for (const part of msg.content) {\n          if (typeof part === \"string\") {\n            content.push({ type: \"text\", text: part });\n          } else if (part.type === \"text\") {\n            content.push({ type: \"text\", text: String(part.text) });\n          }\n        }\n      }\n\n      // Add tool calls\n      if (msg.tool_calls && msg.tool_calls.length > 0) {\n        for (const tc of msg.tool_calls) {\n          content.push({\n            type: \"tool-call\",\n            toolCallId: tc.id ?? `tool-call-${tc.name}`,\n            toolName: tc.name,\n            input: tc.args,\n          });\n        }\n      }\n\n      return {\n        role: \"assistant\" as const,\n        content,\n      };\n    }\n\n    if (ToolMessage.isInstance(msg)) {\n      // Convert LangChain tool message content to LanguageModelV3ToolResultOutput\n      type ToolResultOutput = { type: \"text\"; value: string } | { type: \"json\"; value: JSONValue };\n      let output: ToolResultOutput;\n      if (typeof msg.content === \"string\") {\n        // Try to parse as JSON, otherwise use as text\n        try {\n          const parsed = JSON.parse(msg.content);\n          output = { type: \"json\", value: parsed as JSONValue };\n        } catch {\n          output = { type: \"text\", value: msg.content };\n        }\n      } else {\n        // For complex content, treat as JSON\n        output = { type: \"json\", value: msg.content as JSONValue };\n      }\n\n      const content: ToolContent = [\n        {\n          type: \"tool-result\",\n          toolCallId: msg.tool_call_id,\n          toolName: msg.name ?? \"unknown\",\n          output,\n        },\n      ];\n      return {\n        role: \"tool\" as const,\n        content,\n      };\n    }\n\n    // Default: treat as user message\n    return {\n      role: \"user\" as const,\n      content: [{ type: \"text\", text: String(msg.content) }],\n    };\n  });\n}\n\n/**\n * Convert AI SDK generateText result to LangChain ChatResult\n */\nexport function convertGenerateTextResultToChatResult(\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  result: GenerateTextResult<ToolSet, any>\n): ChatResult {\n  const text = result.text;\n\n  // Extract tool calls from the result\n  const toolCalls =\n    result.toolCalls?.map((tc) => ({\n      id: tc.toolCallId,\n      name: tc.toolName,\n      args: tc.input as Record<string, unknown>, // AI SDK uses 'input', LangChain uses 'args'\n      type: \"tool_call\" as const,\n    })) ?? [];\n\n  const message = new AIMessage({\n    content: text,\n    tool_calls: toolCalls.length > 0 ? toolCalls : undefined,\n  });\n\n  const generation: ChatGeneration = {\n    text,\n    message,\n    generationInfo: {\n      finish_reason: result.finishReason,\n    },\n  };\n\n  return {\n    generations: [generation],\n    llmOutput: {\n      tokenUsage: result.usage\n        ? {\n            promptTokens: result.usage.inputTokens ?? 0,\n            completionTokens: result.usage.outputTokens ?? 0,\n            totalTokens: result.usage.totalTokens ?? 0,\n          }\n        : undefined,\n    },\n  };\n}\n\n/**\n * Convert AI SDK streamText result to async generator of LangChain ChatGenerationChunk\n *\n * This function handles the TextStreamPart events from streamText's fullStream,\n * which provides normalized events across all providers.\n */\nexport async function* convertStreamTextResultToChunks(\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  result: StreamTextResult<ToolSet, any>\n): AsyncGenerator<ChatGenerationChunk> {\n  // Track accumulated tool calls for streaming\n  const partialToolCalls: Map<string, { toolName: string; input: string; index: number }> =\n    new Map();\n  // Track tool call IDs that were already processed via tool-input-start (streaming)\n  // to avoid duplicates when tool-call events arrive for the same tool call\n  const streamedToolCallIds: Set<string> = new Set();\n  // Track tool call indices - each unique tool call ID gets an incrementing index\n  let nextToolCallIndex = 0;\n\n  for await (const part of result.fullStream) {\n    switch (part.type) {\n      case \"text-delta\":\n        yield new ChatGenerationChunk({\n          message: new AIMessageChunk({\n            content: part.text,\n          }),\n          text: part.text,\n        });\n        break;\n\n      case \"tool-call\": {\n        // Complete tool call from streamText\n        // This is the authoritative source for tool calls - always use it\n        // If we previously saw tool-input-start/delta, use the index we assigned\n        const toolName = part.toolName;\n        const existingPartial = partialToolCalls.get(part.toolCallId);\n        const toolIndex = existingPartial?.index ?? nextToolCallIndex++;\n        const argsString = typeof part.input === \"string\" ? part.input : JSON.stringify(part.input);\n\n        // Mark as processed to avoid duplicates\n        streamedToolCallIds.add(part.toolCallId);\n\n        yield new ChatGenerationChunk({\n          message: new AIMessageChunk({\n            content: \"\",\n            tool_call_chunks: [\n              {\n                index: toolIndex,\n                id: part.toolCallId,\n                name: toolName,\n                args: argsString,\n                type: \"tool_call_chunk\" as const,\n              },\n            ],\n          }),\n          text: \"\",\n        });\n        break;\n      }\n\n      case \"tool-input-start\": {\n        // Initialize partial tool call tracking - we'll emit the full call on tool-call event\n        const toolIndex = nextToolCallIndex++;\n        partialToolCalls.set(part.id, {\n          toolName: part.toolName,\n          input: \"\",\n          index: toolIndex,\n        });\n        // Don't emit yet - wait for tool-call event which has complete args\n        break;\n      }\n\n      case \"tool-input-delta\": {\n        // Track accumulated args but don't emit - wait for tool-call event\n        const partial = partialToolCalls.get(part.id);\n        if (partial) {\n          partial.input += part.delta;\n        }\n        break;\n      }\n\n      case \"finish\": {\n        // Note: We construct the message without tool_calls fields to avoid\n        // overwriting tool_calls from previous chunks during concatenation.\n        // LangChain's concat() will overwrite arrays even if the new value is empty.\n        const finishMessage: {\n          content: string;\n          usage_metadata?: {\n            input_tokens: number;\n            output_tokens: number;\n            total_tokens: number;\n          };\n        } = {\n          content: \"\",\n        };\n        if (part.totalUsage) {\n          finishMessage.usage_metadata = {\n            input_tokens: part.totalUsage.inputTokens ?? 0,\n            output_tokens: part.totalUsage.outputTokens ?? 0,\n            total_tokens: part.totalUsage.totalTokens ?? 0,\n          };\n        }\n        yield new ChatGenerationChunk({\n          message: new AIMessageChunk(finishMessage),\n          text: \"\",\n          generationInfo: {\n            finish_reason: part.finishReason,\n          },\n        });\n        break;\n      }\n\n      case \"error\":\n        yield new ChatGenerationChunk({\n          message: new AIMessageChunk({\n            content: \"\",\n          }),\n          text: \"\",\n          generationInfo: {\n            error: part.error,\n          },\n        });\n        break;\n\n      // Skip parts that don't produce content for LangChain\n      case \"start\":\n      case \"start-step\":\n      case \"finish-step\":\n      case \"text-start\":\n      case \"text-end\":\n      case \"reasoning-start\":\n      case \"reasoning-end\":\n      case \"reasoning-delta\":\n      case \"tool-input-end\":\n      case \"tool-result\":\n      case \"tool-error\":\n      case \"source\":\n      case \"file\":\n      case \"abort\":\n      case \"raw\":\n      default:\n        // These don't need to be converted to LangChain chunks\n        break;\n    }\n  }\n}\n","/**\n * Tool conversion utilities between LangChain and AI SDK formats\n */\n\nimport {\n  isStructuredTool,\n  isRunnableToolLike,\n  isStructuredToolParams,\n} from \"@langchain/core/tools\";\nimport { isOpenAITool } from \"@langchain/core/language_models/base\";\nimport { BindToolsInput } from \"@langchain/core/language_models/chat_models\";\nimport { tool, jsonSchema, type ToolSet } from \"ai\";\nimport { ZodType } from \"zod/v4\";\n\n/**\n * Convert a schema (Zod or JSON Schema) to JSON Schema format\n */\nfunction convertSchemaToJsonSchema(schema: unknown): Record<string, unknown> {\n  if (!schema) {\n    return { type: \"object\", properties: {} };\n  }\n  if (schema instanceof ZodType) {\n    return schema.toJSONSchema();\n  }\n  // Already a JSON schema object\n  return schema as Record<string, unknown>;\n}\n\n/**\n * Convert LangChain tools to AI SDK ToolSet format\n *\n * Supports all BindToolsInput types:\n * - StructuredToolInterface (LangChain StructuredTool)\n * - RunnableToolLike (Runnable converted to tool via .asTool())\n * - StructuredToolParams (minimal tool definition with name, schema, extras)\n * - ToolDefinition (OpenAI format: { type: \"function\", function: {...} })\n * - Record<string, any> (generic object with name and parameters)\n *\n * The AI SDK expects tools as a Record<string, Tool> where each Tool\n * is created using the tool() helper function.\n */\nexport function convertToAISDKToolSet(tools: BindToolsInput[]): ToolSet {\n  const toolSet: ToolSet = {};\n\n  for (const toolInput of tools) {\n    // OpenAI format: { type: \"function\", function: { name, description, parameters } }\n    if (isOpenAITool(toolInput)) {\n      const name = toolInput.function.name;\n      const schema = toolInput.function.parameters ?? { type: \"object\", properties: {} };\n\n      toolSet[name] = tool({\n        description: toolInput.function.description,\n        inputSchema: jsonSchema(schema as Parameters<typeof jsonSchema>[0]),\n      });\n      continue;\n    }\n\n    // RunnableToolLike: Runnable converted to tool via .asTool()\n    // Has: name, description?, schema\n    if (isRunnableToolLike(toolInput)) {\n      const name = toolInput.name;\n      const schema = convertSchemaToJsonSchema(toolInput.schema);\n\n      toolSet[name] = tool({\n        description: toolInput.description,\n        inputSchema: jsonSchema(schema as Parameters<typeof jsonSchema>[0]),\n      });\n      continue;\n    }\n\n    // StructuredToolInterface: LangChain StructuredTool\n    // Has: name, description, schema, returnDirect, extras?\n    if (isStructuredTool(toolInput)) {\n      const name = toolInput.name;\n      const schema = convertSchemaToJsonSchema(toolInput.schema);\n\n      toolSet[name] = tool({\n        description: toolInput.description,\n        inputSchema: jsonSchema(schema as Parameters<typeof jsonSchema>[0]),\n      });\n      continue;\n    }\n\n    // StructuredToolParams: Minimal tool definition\n    // Has: name, schema, extras?, description?\n    if (isStructuredToolParams(toolInput)) {\n      const name = toolInput.name;\n      const schema = convertSchemaToJsonSchema(toolInput.schema);\n\n      toolSet[name] = tool({\n        description: toolInput.description,\n        inputSchema: jsonSchema(schema as Parameters<typeof jsonSchema>[0]),\n      });\n      continue;\n    }\n\n    // Generic Record<string, any> - fallback for plain objects\n    // Try to extract name, description, and parameters/schema\n    if (typeof toolInput === \"object\" && toolInput !== null && \"name\" in toolInput) {\n      const name = String(toolInput.name);\n\n      // Look for schema in various forms: parameters, schema, inputSchema\n      const rawSchema = toolInput.parameters ?? toolInput.schema ?? toolInput.inputSchema;\n      const schema = convertSchemaToJsonSchema(rawSchema);\n\n      toolSet[name] = tool({\n        description: toolInput.description as string | undefined,\n        inputSchema: jsonSchema(schema as Parameters<typeof jsonSchema>[0]),\n      });\n      continue;\n    }\n\n    throw new Error(`Unsupported tool type: ${JSON.stringify(toolInput)}`);\n  }\n\n  return toolSet;\n}\n","/**\n * ChatDatabricks - LangChain chat model integration for Databricks Model Serving\n *\n * Uses the Databricks AI SDK Provider internally to support multiple endpoint APIs:\n * - chat-completions: OpenAI-compatible chat completions API\n * - chat-agent: Databricks agent chat completion\n * - responses: Rich output with reasoning, citations, function calls\n */\n\nimport {\n  BaseChatModel,\n  BaseChatModelParams,\n  BaseChatModelCallOptions,\n  BindToolsInput,\n} from \"@langchain/core/language_models/chat_models\";\nimport { BaseMessage } from \"@langchain/core/messages\";\nimport { ChatResult, ChatGenerationChunk } from \"@langchain/core/outputs\";\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport type { LanguageModel } from \"ai\";\nimport { generateText, streamText } from \"ai\";\nimport { createDatabricksProvider, type DatabricksProvider } from \"@databricks/ai-sdk-provider\";\nimport { Config } from \"@databricks/sdk-experimental\";\n\nimport {\n  convertLangChainToModelMessages,\n  convertGenerateTextResultToChatResult,\n  convertStreamTextResultToChunks,\n} from \"./utils/messages.js\";\nimport { convertToAISDKToolSet } from \"./utils/tools.js\";\n\n/**\n * Endpoint API determines which Databricks API protocol to use\n */\nexport type EndpointAPI = \"responses\" | \"chat-completions\" | \"chat-agent\";\n\n/**\n * Authentication options for Databricks\n */\ntype DatabricksSdkConfig = ConstructorParams<typeof Config>[0];\ntype ConstructorParams<T> = T extends new (...args: infer A) => any ? A : never;\n\n/**\n * Options that can be passed at call time\n */\nexport interface ChatDatabricksCallOptions extends BaseChatModelCallOptions {\n  /** Temperature (0.0 - 2.0) */\n  temperature?: number;\n\n  /** Max tokens to generate */\n  maxTokens?: number;\n\n  /** Stop sequences */\n  stop?: string[];\n\n  /** Tools to use for this call */\n  tools?: BindToolsInput[];\n\n  /** Tool choice for this call */\n  toolChoice?: \"auto\" | \"none\" | \"required\" | \"any\" | string;\n\n  /** Extra parameters to pass to the model */\n  extraParams?: Record<string, unknown>;\n}\n\n/**\n * Input parameters for ChatDatabricks constructor\n */\nexport interface ChatDatabricksInput extends BaseChatModelParams {\n  /** Model serving endpoint name */\n  model: string;\n\n  /**\n   * Whether to use the Responses API or Chat Completions API\n   *\n   * - Chat Completions: See https://docs.databricks.com/aws/en/machine-learning/foundation-model-apis/api-reference#chat-completions-api\n   * - Responses: See https://docs.databricks.com/aws/en/machine-learning/foundation-model-apis/api-reference#responses-api\n   *\n   * @default false\n   */\n  useResponsesApi?: boolean;\n\n  /**\n   * Authentication credentials for Databricks SDK.\n   * If not provided Databricks SDK with automatically\n   * attempt authentication using environment variables or CLI\n   */\n  auth?: DatabricksSdkConfig;\n\n  /** Temperature (0.0 - 2.0) */\n  temperature?: number;\n\n  /** Max tokens to generate */\n  maxTokens?: number;\n\n  /** Stop sequences */\n  stop?: string[];\n\n  /** Extra parameters to pass to the model */\n  extraParams?: Record<string, unknown>;\n}\n\n/**\n * ChatDatabricks - Chat model integration for Databricks Model Serving\n *\n * Supports Chat Completions or Responses via `useResponsesApi`:\n *\n * @example Chat Completions\n * ```typescript\n * const llm = new ChatDatabricks({\n *   model: \"databricks-claude-sonnet-4-5\",\n *   useResponsesApi: false, // can be omitted\n * });\n * const response = await llm.invoke(\"Hello!\");\n * ```\n *\n * @example Responses\n * ```typescript\n * const llm = new ChatDatabricks({\n *   model: \"databricks-gpt-5-2\",\n *   useResponsesApi: true,\n * });\n * const response = await llm.invoke(\"Hello!\");\n * ```\n *\n * @example With explicit authentication\n * ```typescript\n * const llm = new ChatDatabricks({\n *   model: \"databricks-claude-sonnet-4-5\",\n *   auth: {\n *     host: \"https://your-workspace.databricks.com\",\n *     token: \"dapi...\",\n *   },\n * });\n * ```\n */\nexport class ChatDatabricks extends BaseChatModel<ChatDatabricksCallOptions> {\n  static lc_name() {\n    return \"ChatDatabricks\";\n  }\n\n  lc_serializable = true;\n\n  /** Model serving endpoint name */\n  model: string;\n\n  /** Whether to use the Responses API or Chat Completions API */\n  useResponsesApi?: boolean;\n\n  /** Temperature (0.0 - 2.0) */\n  temperature?: number;\n\n  /** Max tokens to generate */\n  maxTokens?: number;\n\n  /** Stop sequences */\n  stop?: string[];\n\n  /** Extra parameters */\n  extraParams?: Record<string, unknown>;\n\n  /** Authentication credentials */\n  private auth?: DatabricksSdkConfig;\n\n  /** Databricks AI SDK Provider */\n  private provider: Promise<DatabricksProvider>;\n\n  /** AI SDK Language Model */\n  private languageModel: Promise<LanguageModel>;\n\n  /** Bound tools */\n  private boundTools?: BindToolsInput[];\n\n  /** Bound tool choice */\n  private boundToolChoice?: \"auto\" | \"none\" | \"required\" | \"any\" | string;\n\n  constructor(fields: ChatDatabricksInput) {\n    super(fields);\n\n    this.model = fields.model;\n    this.useResponsesApi = fields.useResponsesApi;\n    this.temperature = fields.temperature;\n    this.maxTokens = fields.maxTokens;\n    this.stop = fields.stop;\n    this.extraParams = fields.extraParams;\n    this.auth = fields.auth;\n\n    // Create Databricks AI SDK Provider\n    this.provider = this.createProvider();\n\n    // Get appropriate language model based on model\n    this.languageModel = this.getLanguageModel();\n  }\n\n  /**\n   * Create the Databricks AI SDK Provider with authentication\n   */\n  private async createProvider(): Promise<DatabricksProvider> {\n    const config = new Config(this.auth ?? {});\n\n    await config.ensureResolved();\n\n    // Capture the global fetch to avoid recursion when passing custom fetch to the provider\n    const globalFetch = globalThis.fetch;\n\n    return createDatabricksProvider({\n      baseURL: `${config.host}/serving-endpoints`,\n      // Custom fetch that uses SDK authentication\n      fetch: async (url, options) => {\n        // Ensure config is resolved (handles async auth like OAuth)\n        await config.ensureResolved();\n\n        // Create headers and add authentication\n        const headers = new Headers(options?.headers as Record<string, string>);\n        await config.authenticate(headers);\n\n        // Make the request using the global fetch (not the custom one to avoid recursion)\n        const response = await globalFetch(url, {\n          ...options,\n          headers,\n        });\n\n        return response;\n      },\n    });\n  }\n\n  private async getLanguageModel(): Promise<LanguageModel> {\n    const provider = await this.provider;\n    if (this.useResponsesApi) {\n      return provider.responses(this.model) as LanguageModel;\n    }\n    return provider.chatCompletions(this.model) as LanguageModel;\n  }\n\n  _llmType(): string {\n    return \"chat-databricks\";\n  }\n\n  /**\n   * Non-streaming chat completion\n   */\n  async _generate(\n    messages: BaseMessage[],\n    options: this[\"ParsedCallOptions\"],\n    runManager?: CallbackManagerForLLMRun\n  ): Promise<ChatResult> {\n    const modelMessages = convertLangChainToModelMessages(messages);\n\n    // Merge tools from bound tools and call options\n    const tools = options.tools ?? this.boundTools;\n    const aiSdkTools = tools ? convertToAISDKToolSet(tools) : undefined;\n\n    // Merge tool choice from call options and bound tool choice\n    const toolChoice = options.toolChoice ?? this.boundToolChoice;\n\n    // Merge stop sequences from instance and options\n    const stopSequences = options.stop ?? this.stop;\n\n    // Merge extra params from instance and options\n    const extraParams = { ...this.extraParams, ...options.extraParams };\n\n    const languageModel = await this.languageModel;\n\n    // Use generateText from AI SDK\n    const result = await generateText({\n      model: languageModel,\n      messages: modelMessages,\n      tools: aiSdkTools,\n      toolChoice: toolChoice as \"auto\" | \"none\" | \"required\" | undefined,\n      temperature: options.temperature ?? this.temperature,\n      maxOutputTokens: options.maxTokens ?? this.maxTokens,\n      stopSequences,\n      abortSignal: options.signal,\n      ...extraParams,\n    });\n\n    const chatResult = convertGenerateTextResultToChatResult(result);\n\n    // Report to callbacks for observability (LangSmith, etc.)\n    if (runManager && chatResult.generations.length > 0) {\n      const generation = chatResult.generations[0];\n      await runManager.handleLLMNewToken(generation.text ?? \"\");\n    }\n\n    return chatResult;\n  }\n\n  /**\n   * Streaming chat completion\n   */\n  async *_streamResponseChunks(\n    messages: BaseMessage[],\n    options: this[\"ParsedCallOptions\"],\n    runManager?: CallbackManagerForLLMRun\n  ): AsyncGenerator<ChatGenerationChunk> {\n    const modelMessages = convertLangChainToModelMessages(messages);\n\n    // Merge tools from bound tools and call options\n    const tools = options.tools ?? this.boundTools;\n    const aiSdkTools = tools ? convertToAISDKToolSet(tools) : undefined;\n\n    // Merge tool choice from call options and bound tool choice\n    const toolChoice = options.toolChoice ?? this.boundToolChoice;\n\n    // Merge stop sequences from instance and options\n    const stopSequences = options.stop ?? this.stop;\n\n    // Merge extra params from instance and options\n    const extraParams = { ...this.extraParams, ...options.extraParams };\n\n    const languageModel = await this.languageModel;\n\n    // Use streamText from AI SDK for high-level streaming with normalized events\n    const result = streamText({\n      model: languageModel,\n      messages: modelMessages,\n      tools: aiSdkTools,\n      toolChoice: toolChoice as \"auto\" | \"none\" | \"required\" | undefined,\n      temperature: options.temperature ?? this.temperature,\n      maxOutputTokens: options.maxTokens ?? this.maxTokens,\n      stopSequences,\n      abortSignal: options.signal,\n      ...extraParams,\n    });\n\n    // Iterate over the stream and convert to LangChain chunks\n    for await (const chunk of convertStreamTextResultToChunks(result)) {\n      // Check for abort\n      if (options.signal?.aborted) {\n        throw new Error(\"AbortError: Request was aborted\");\n      }\n\n      yield chunk;\n\n      // Report to callbacks\n      await runManager?.handleLLMNewToken(\n        chunk.text ?? \"\",\n        undefined,\n        undefined,\n        undefined,\n        undefined,\n        { chunk }\n      );\n    }\n  }\n\n  /**\n   * Bind tools to this model for function calling\n   */\n  bindTools(\n    tools: BindToolsInput[],\n    kwargs?: Partial<ChatDatabricksCallOptions>\n  ): InstanceType<typeof ChatDatabricks> {\n    // Create a new instance with bound tools\n    const bound = new ChatDatabricks({\n      model: this.model,\n      useResponsesApi: this.useResponsesApi,\n      auth: this.auth,\n      temperature: this.temperature,\n      maxTokens: this.maxTokens,\n      stop: this.stop,\n      extraParams: this.extraParams,\n    });\n\n    bound.boundTools = tools;\n    bound.boundToolChoice = kwargs?.toolChoice;\n\n    return bound;\n  }\n\n  /**\n   * Get the identifying parameters for this model\n   */\n  get identifyingParams(): Record<string, unknown> {\n    return {\n      model: this.model,\n      useResponsesApi: this.useResponsesApi,\n      temperature: this.temperature,\n      maxTokens: this.maxTokens,\n    };\n  }\n\n  get lc_secrets(): { [key: string]: string } {\n    return {\n      token: \"DATABRICKS_TOKEN\",\n    };\n  }\n\n  get lc_aliases(): { [key: string]: string } {\n    return {\n      model: \"endpoint\",\n    };\n  }\n}\n","/**\n * OAuth provider for Databricks authentication with MCP servers.\n *\n * Bridges Databricks SDK authentication to MCP's OAuth interface,\n * allowing MCP servers to use Databricks authentication methods\n * (PAT, OAuth, Azure MSI, etc.) transparently.\n *\n * Based on the Python implementation at:\n * https://github.com/databricks/databricks-ai-bridge/blob/main/databricks_mcp/src/databricks_mcp/oauth_provider.py\n */\n\nimport type { Config } from \"@databricks/sdk-experimental\";\nimport type { OAuthClientProvider } from \"@modelcontextprotocol/sdk/client/auth.js\";\nimport type {\n  OAuthClientMetadata,\n  OAuthTokens,\n  OAuthClientInformationMixed,\n} from \"@modelcontextprotocol/sdk/shared/auth.js\";\n\nconst TOKEN_EXPIRATION_SECONDS = 60;\n\n/**\n * DatabricksOAuthClientProvider bridges Databricks SDK authentication to MCP.\n *\n * This class implements the MCP SDK's OAuthClientProvider interface using\n * Databricks SDK authentication. It provides Bearer tokens from the Databricks\n * SDK's authentication chain (PAT, OAuth, Azure MSI, etc.) without requiring\n * interactive OAuth flows.\n *\n * The implementation mirrors the Python DatabricksOAuthClientProvider which\n * uses a similar token storage pattern to provide pre-authenticated tokens.\n *\n * @example\n * ```typescript\n * import { Config } from \"@databricks/sdk-experimental\";\n * import { DatabricksOAuthClientProvider } from \"@databricks/langchainjs\";\n *\n * const config = new Config();\n * const authProvider = new DatabricksOAuthClientProvider(config);\n * ```\n */\nexport class DatabricksOAuthClientProvider implements OAuthClientProvider {\n  private config: Config;\n\n  constructor(config: Config) {\n    this.config = config;\n  }\n\n  /**\n   * Returns undefined to indicate non-interactive flow.\n   * This disables the redirect-based OAuth flow.\n   */\n  get redirectUrl(): undefined {\n    return undefined;\n  }\n\n  /**\n   * Returns null/undefined client metadata to skip OAuth client registration.\n   * The Python implementation passes client_metadata=None to achieve this.\n   */\n  get clientMetadata(): OAuthClientMetadata {\n    // Return minimal metadata - the key is that we provide tokens() directly\n    // so the OAuth flow doesn't need to do client registration\n    return { redirect_uris: [] };\n  }\n\n  /**\n   * Returns a dummy client information object to skip OAuth client registration.\n   *\n   * When this returns a value (not undefined), the MCP SDK skips the dynamic\n   * client registration step and proceeds directly with token handling.\n   * Since we provide tokens via tokens(), we don't need real client credentials.\n   */\n  clientInformation(): OAuthClientInformationMixed | undefined {\n    // Return a dummy client_id to skip registration\n    // The actual auth is done via Bearer tokens from tokens()\n    return {\n      client_id: \"databricks-sdk-client\",\n    };\n  }\n\n  /**\n   * No-op - we don't save client info for Bearer token auth.\n   */\n  saveClientInformation(_clientInfo: OAuthClientInformationMixed): void {\n    // No-op\n  }\n\n  /**\n   * Prepares token request parameters for non-interactive flows.\n   *\n   * This enables the SDK to use client_credentials grant type, which\n   * will use our clientInformation to authenticate. However, the actual\n   * tokens come from our tokens() method via the Databricks SDK.\n   */\n  prepareTokenRequest(_scope?: string): URLSearchParams | undefined {\n    // Return client_credentials grant parameters\n    // The actual token endpoint call may fail, but our tokens() method\n    // provides the real tokens for Authorization headers\n    const params = new URLSearchParams({\n      grant_type: \"client_credentials\",\n    });\n    return params;\n  }\n\n  /**\n   * Returns current OAuth tokens from Databricks authentication.\n   *\n   * This is the key method - it provides tokens directly from the Databricks SDK,\n   * bypassing the need for OAuth discovery and client registration.\n   */\n  async tokens(): Promise<OAuthTokens | undefined> {\n    // Ensure config is resolved (handles async auth like OAuth)\n    await this.config.ensureResolved();\n\n    // Create headers and authenticate using the SDK\n    const headers = new Headers();\n    await this.config.authenticate(headers);\n\n    const authHeader = headers.get(\"Authorization\");\n    if (!authHeader?.startsWith(\"Bearer \")) {\n      throw new Error(\"Invalid authentication token format. Expected Bearer token.\");\n    }\n\n    const token = authHeader.split(\"Bearer \")[1];\n    return {\n      access_token: token,\n      token_type: \"Bearer\",\n      // Short expiration ensures regular token refresh\n      expires_in: TOKEN_EXPIRATION_SECONDS,\n    };\n  }\n\n  /**\n   * No-op - Databricks SDK manages its own token lifecycle.\n   */\n  saveTokens(_tokens: OAuthTokens): void {\n    // No-op\n  }\n\n  /**\n   * Throws - redirect-based OAuth not supported.\n   */\n  redirectToAuthorization(_authorizationUrl: URL): void {\n    throw new Error(\"Redirect-based OAuth not supported for Databricks authentication\");\n  }\n\n  /**\n   * No-op - PKCE not used for Bearer token auth.\n   */\n  saveCodeVerifier(_codeVerifier: string): void {\n    // No-op\n  }\n\n  /**\n   * Returns empty string - PKCE not used for Bearer token auth.\n   */\n  codeVerifier(): string {\n    return \"\";\n  }\n}\n\nexport type { OAuthClientProvider };\n","/**\n * MCP Server configuration classes\n *\n * Provides MCPServer for generic MCP servers and DatabricksMCPServer\n * for servers requiring Databricks OAuth authentication.\n */\n\nimport { Config } from \"@databricks/sdk-experimental\";\nimport type { StreamableHTTPConnection } from \"@langchain/mcp-adapters\";\nimport type {\n  BaseMCPServerConfig,\n  MCPServerConfig,\n  DatabricksMCPServerConfig,\n  DatabricksConfigOptions,\n} from \"./types.js\";\nimport { DatabricksOAuthClientProvider } from \"./databricks_oauth_provider.js\";\n\n/**\n * Abstract base class for MCP server configurations.\n *\n * Provides common properties and the interface for connection config generation.\n * Subclasses implement `toConnectionConfig()` to provide transport-specific configuration.\n */\nabstract class BaseMCPServer {\n  readonly name: string;\n  readonly headers?: Record<string, string>;\n  readonly timeout?: number;\n  readonly sseReadTimeout?: number;\n\n  constructor(config: BaseMCPServerConfig) {\n    this.name = config.name;\n    this.headers = config.headers;\n    this.timeout = config.timeout;\n    this.sseReadTimeout = config.sseReadTimeout;\n  }\n\n  /**\n   * Convert to connection dictionary for MultiServerMCPClient.\n   * Returns the format expected by @langchain/mcp-adapters.\n   */\n  abstract toConnectionConfig(): Promise<StreamableHTTPConnection>;\n\n  /**\n   * Build base connection config with common properties.\n   */\n  protected buildBaseConfig(url: string): StreamableHTTPConnection {\n    const config: StreamableHTTPConnection = {\n      transport: \"http\",\n      url,\n    };\n\n    if (this.headers) {\n      config.headers = this.headers;\n    }\n    if (this.timeout !== undefined) {\n      config.defaultToolTimeout = this.timeout * 1000; // Convert seconds to milliseconds\n    }\n\n    return config;\n  }\n}\n\n/**\n * MCP server configuration for streamable HTTP transport.\n *\n * Use this for generic (non-Databricks) MCP servers where you have a full URL.\n *\n * @example\n * ```typescript\n * import { MCPServer, DatabricksMultiServerMCPClient } from \"@databricks/langchainjs\";\n *\n * const server = new MCPServer({\n *   name: \"my-mcp-server\",\n *   url: \"https://my-mcp-server.com/mcp\",\n *   headers: { \"X-API-Key\": \"secret\" },\n *   timeout: 30,\n * });\n *\n * const client = new DatabricksMultiServerMCPClient([server]);\n * const tools = await client.getTools();\n * ```\n */\nexport class MCPServer extends BaseMCPServer {\n  readonly url: string;\n\n  constructor(config: MCPServerConfig) {\n    super(config);\n    this.url = config.url;\n  }\n\n  override async toConnectionConfig(): Promise<StreamableHTTPConnection> {\n    return this.buildBaseConfig(this.url);\n  }\n}\n\n/**\n * MCP server with Databricks OAuth authentication.\n *\n * Automatically configures OAuth authentication using the Databricks SDK.\n * This handles all Databricks authentication methods (PAT, OAuth, Azure MSI, etc.)\n * transparently through the SDK's authentication chain.\n *\n * The host is resolved lazily from the Databricks SDK config (via DATABRICKS_HOST\n * environment variable, CLI config, or explicit auth config).\n *\n * @example\n * ```typescript\n * import { DatabricksMCPServer, DatabricksMultiServerMCPClient } from \"@databricks/langchainjs\";\n *\n * // Host resolved from DATABRICKS_HOST env var or auth config\n * const server = new DatabricksMCPServer({\n *   name: \"databricks-mcp\",\n *   path: \"/api/2.0/mcp/sql\",\n * });\n *\n * // With explicit auth (host resolved from auth config)\n * const serverWithAuth = new DatabricksMCPServer({\n *   name: \"databricks-mcp\",\n *   path: \"/api/2.0/mcp/sql\",\n *   auth: {\n *     host: \"https://my-workspace.databricks.com\",\n *     token: \"dapi...\",\n *   },\n * });\n *\n * const client = new DatabricksMultiServerMCPClient([server]);\n * const tools = await client.getTools();\n * ```\n */\nexport class DatabricksMCPServer extends BaseMCPServer {\n  private readonly sdkConfig: Config;\n  private readonly authProvider: DatabricksOAuthClientProvider;\n  private readonly path: string;\n  private resolvedUrl?: string;\n\n  constructor(config: DatabricksMCPServerConfig) {\n    super(config);\n\n    // Normalize and store path\n    this.path = config.path.startsWith(\"/\") ? config.path : `/${config.path}`;\n\n    // Initialize Databricks SDK config from options\n    this.sdkConfig = new Config(config.auth ?? {});\n\n    // Create OAuth provider for MCP authentication\n    this.authProvider = new DatabricksOAuthClientProvider(this.sdkConfig);\n  }\n\n  /**\n   * Resolve the full URL by combining the host from SDK config with the path.\n   */\n  private async resolveUrl(): Promise<string> {\n    if (this.resolvedUrl) {\n      return this.resolvedUrl;\n    }\n\n    const host = (await this.sdkConfig.getHost())?.toString().replace(/\\/$/, \"\");\n    if (!host) {\n      throw new Error(\n        \"Databricks host not configured. Set DATABRICKS_HOST environment variable or provide host in auth.\"\n      );\n    }\n\n    this.resolvedUrl = `${host}${this.path}`;\n    return this.resolvedUrl;\n  }\n\n  /**\n   * Convert to connection dictionary using headers-based authentication.\n   * This resolves the URL and adds the Bearer token directly to headers.\n   * Use this when connecting to servers that don't support OAuth discovery.\n   */\n  override async toConnectionConfig(): Promise<StreamableHTTPConnection> {\n    const resolvedUrl = await this.resolveUrl();\n\n    const config = this.buildBaseConfig(resolvedUrl);\n\n    // Attach the auth provider to the config\n    config.authProvider = this.authProvider;\n\n    return config;\n  }\n\n  /**\n   * Factory method to create a DatabricksMCPServer for a Unity Catalog function.\n   *\n   * @param catalog - UC catalog name\n   * @param schema - UC schema name\n   * @param functionName - UC function name (optional, for specific function)\n   * @param options - Additional server configuration options\n   * @returns DatabricksMCPServer configured for the UC function\n   *\n   * @example\n   * ```typescript\n   * const server = DatabricksMCPServer.fromUCFunction(\n   *   \"my_catalog\",\n   *   \"my_schema\",\n   *   \"my_function\"\n   * );\n   * ```\n   */\n  static fromUCFunction(\n    catalog: string,\n    schema: string,\n    functionName?: string,\n    options: { auth?: DatabricksConfigOptions; timeout?: number } = {}\n  ): DatabricksMCPServer {\n    const functionPath = functionName\n      ? `${catalog}/${schema}/${functionName}`\n      : `${catalog}/${schema}`;\n\n    const name = functionName\n      ? `uc-function-${catalog}-${schema}-${functionName}`\n      : `uc-functions-${catalog}-${schema}`;\n\n    return new DatabricksMCPServer({\n      name,\n      path: `/api/2.0/mcp/functions/${functionPath}`,\n      ...options,\n    });\n  }\n\n  /**\n   * Factory method to create a DatabricksMCPServer for a Vector Search index.\n   *\n   * @param catalog - UC catalog name\n   * @param schema - UC schema name\n   * @param indexName - Vector Search index name (optional, for specific index)\n   * @param options - Additional server configuration options\n   * @returns DatabricksMCPServer configured for the Vector Search index\n   *\n   * @example\n   * ```typescript\n   * const server = DatabricksMCPServer.fromVectorSearch(\n   *   \"my_catalog\",\n   *   \"my_schema\",\n   *   \"my_index\"\n   * );\n   * ```\n   */\n  static fromVectorSearch(\n    catalog: string,\n    schema: string,\n    indexName?: string,\n    options: { auth?: DatabricksConfigOptions; timeout?: number } = {}\n  ): DatabricksMCPServer {\n    const indexPath = indexName ? `${catalog}/${schema}/${indexName}` : `${catalog}/${schema}`;\n\n    const name = indexName\n      ? `vector-search-${catalog}-${schema}-${indexName}`\n      : `vector-search-${catalog}-${schema}`;\n\n    return new DatabricksMCPServer({\n      name,\n      path: `/api/2.0/mcp/vector-search/${indexPath}`,\n      ...options,\n    });\n  }\n\n  /**\n   * Factory method to create a DatabricksMCPServer for a Genie Space.\n   *\n   * @param spaceId - Genie Space ID\n   * @param options - Additional server configuration options\n   * @returns DatabricksMCPServer configured for the Genie Space\n   *\n   * @example\n   * ```typescript\n   * const server = DatabricksMCPServer.fromGenieSpace(\n   *   \"01ef19c578b21dc6af6e10983fb1e3f9\"\n   * );\n   * ```\n   */\n  static fromGenieSpace(\n    spaceId: string,\n    options: { auth?: DatabricksConfigOptions; timeout?: number } = {}\n  ): DatabricksMCPServer {\n    const name = `genie-space-${spaceId}`;\n\n    return new DatabricksMCPServer({\n      name,\n      path: `/api/2.0/mcp/genie/${spaceId}`,\n      ...options,\n    });\n  }\n}\n","/**\n * Helper utilities for building MCP client configurations with Databricks authentication.\n */\n\nimport type { StreamableHTTPConnection } from \"@langchain/mcp-adapters\";\nimport { MCPServer, DatabricksMCPServer } from \"./mcp_server.js\";\n\nexport type ServerInstance = MCPServer | DatabricksMCPServer;\n\n/**\n * Build MCP server configuration from an array of server instances.\n *\n * This helper converts `MCPServer` and `DatabricksMCPServer` instances into\n * the configuration format expected by `@langchain/mcp-adapters` `MultiServerMCPClient`.\n *\n * For `DatabricksMCPServer` instances, this resolves the URL from the Databricks SDK\n * config and adds authentication headers.\n *\n * @param servers - Array of MCPServer or DatabricksMCPServer instances\n * @returns Configuration object for MultiServerMCPClient's `mcpServers` option\n *\n * @example\n * ```typescript\n * import { MultiServerMCPClient } from \"@langchain/mcp-adapters\";\n * import {\n *   buildMCPServerConfig,\n *   DatabricksMCPServer,\n *   MCPServer,\n * } from \"@databricks/langchainjs\";\n *\n * // Create server instances\n * const servers = [\n *   new DatabricksMCPServer({\n *     name: \"databricks-sql\",\n *     path: \"/api/2.0/mcp/sql\",\n *   }),\n *   // Generic MCP server with custom auth\n *   new MCPServer({\n *     name: \"other\",\n *     url: \"https://other-server.com/mcp\",\n *     headers: { \"Authorization\": \"Bearer token\" },\n *   }),\n * ];\n *\n * // Build config and create client\n * const mcpServers = await buildMCPServerConfig(servers);\n * const client = new MultiServerMCPClient({ mcpServers });\n *\n * // Use the client\n * const tools = await client.getTools();\n *\n * // Clean up\n * await client.close();\n * ```\n */\nexport async function buildMCPServerConfig(\n  servers: ServerInstance[]\n): Promise<Record<string, StreamableHTTPConnection>> {\n  const config: Record<string, StreamableHTTPConnection> = {};\n\n  for (const server of servers) {\n    config[server.name] = await server.toConnectionConfig();\n  }\n\n  return config;\n}\n"],"mappings":"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"}