{"version":3,"file":"chat_models.cjs","names":["BaseChatModel","Ollama","AIMessage","convertToOllamaMessages","ChatGenerationChunk","convertOllamaMessagesToLangChain","AIMessageChunk"],"sources":["../src/chat_models.ts"],"sourcesContent":["import {\n  AIMessage,\n  AIMessageChunk,\n  UsageMetadata,\n  type BaseMessage,\n} from \"@langchain/core/messages\";\nimport {\n  BaseLanguageModelInput,\n  StructuredOutputMethodOptions,\n  FunctionDefinition,\n} from \"@langchain/core/language_models/base\";\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport {\n  type BaseChatModelParams,\n  BaseChatModel,\n  LangSmithParams,\n  BaseChatModelCallOptions,\n  BindToolsInput,\n} from \"@langchain/core/language_models/chat_models\";\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore CJS type resolution workaround\nimport { Ollama } from \"ollama/browser\";\nimport { ChatGenerationChunk, ChatResult } from \"@langchain/core/outputs\";\nimport type {\n  ChatRequest as OllamaChatRequest,\n  ChatResponse as OllamaChatResponse,\n  Message as OllamaMessage,\n  Tool as OllamaTool,\n} from \"ollama\";\nimport { Runnable } from \"@langchain/core/runnables\";\nimport { convertToOpenAITool } from \"@langchain/core/utils/function_calling\";\nimport { concat } from \"@langchain/core/utils/stream\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport {\n  InteropZodType,\n  isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\nimport { toJsonSchema } from \"@langchain/core/utils/json_schema\";\nimport {\n  convertOllamaMessagesToLangChain,\n  convertToOllamaMessages,\n} from \"./utils.js\";\nimport { OllamaCamelCaseOptions } from \"./types.js\";\nimport {\n  isSerializableSchema,\n  SerializableSchema,\n} from \"@langchain/core/utils/standard_schema\";\nimport {\n  assembleStructuredOutputPipeline,\n  createContentParser,\n  createFunctionCallingParser,\n} from \"@langchain/core/language_models/structured_output\";\n\nexport interface ChatOllamaCallOptions extends BaseChatModelCallOptions {\n  /**\n   * An array of strings to stop on.\n   */\n  stop?: string[];\n  tools?: BindToolsInput[];\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  format?: string | Record<string, any>;\n  /** @deprecated Tool choice is not supported for ChatOllama */\n  tool_choice?: never;\n}\n\nexport interface PullModelOptions {\n  /**\n   * Whether or not to stream the download.\n   * @default true\n   */\n  stream?: boolean;\n  insecure?: boolean;\n  /**\n   * Whether or not to log the status of the download\n   * to the console.\n   * @default false\n   */\n  logProgress?: boolean;\n}\n\n/**\n * Input to chat model class.\n */\nexport interface ChatOllamaInput\n  extends BaseChatModelParams, OllamaCamelCaseOptions {\n  /**\n   * The model to invoke. If the model does not exist, it\n   * will be pulled.\n   * @default \"llama3\"\n   */\n  model?: OllamaChatRequest[\"model\"];\n  /**\n   * The host URL of the Ollama server.\n   * Defaults to `OLLAMA_BASE_URL` if set.\n   * @default \"http://127.0.0.1:11434\"\n   */\n  baseUrl?: string;\n  /**\n   * Optional HTTP Headers to include in the request.\n   */\n  headers?: Headers | Record<string, string>;\n  /**\n   * Whether or not to check the model exists on the local machine before\n   * invoking it. If set to `true`, the model will be pulled if it does not\n   * exist.\n   * @default false\n   */\n  checkOrPullModel?: boolean;\n  streaming?: boolean;\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  format?: string | Record<string, any>;\n  /**\n   * The fetch function to use.\n   * @default fetch\n   */\n  fetch?: typeof fetch;\n  think?: boolean;\n}\n\n/**\n * Ollama chat model integration.\n *\n * Setup:\n * Install `@langchain/ollama` and the Ollama app.\n *\n * ```bash\n * npm install @langchain/ollama\n * export OLLAMA_BASE_URL=\"http://127.0.0.1:11434\" # Optional; defaults to http://127.0.0.1:11434 if not set\n * ```\n *\n * ## [Constructor args](https://api.js.langchain.com/classes/_langchain_ollama.ChatOllama.html#constructor)\n *\n * ## [Runtime args](https://api.js.langchain.com/interfaces/_langchain_ollama.ChatOllamaCallOptions.html)\n *\n * Runtime args can be passed as the second argument to any of the base runnable methods `.invoke`. `.stream`, `.batch`, etc.\n * They can also be passed via `.withConfig`, or the second arg in `.bindTools`, like shown in the examples below:\n *\n * ```typescript\n * // When calling `.withConfig`, call options should be passed via the first argument\n * const llmWithArgsBound = llm.withConfig({\n *   stop: [\"\\n\"],\n * });\n *\n * // When calling `.bindTools`, call options should be passed via the second argument\n * const llmWithTools = llm.bindTools(\n *   [...],\n *   {\n *     stop: [\"\\n\"],\n *   }\n * );\n * ```\n *\n * ## Examples\n *\n * <details open>\n * <summary><strong>Instantiate</strong></summary>\n *\n * ```typescript\n * import { ChatOllama } from '@langchain/ollama';\n *\n * const llm = new ChatOllama({\n *   model: \"llama-3.1:8b\",\n *   temperature: 0,\n *   // other params...\n * });\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Invoking</strong></summary>\n *\n * ```typescript\n * const input = `Translate \"I love programming\" into French.`;\n *\n * // Models also accept a list of chat messages or a formatted prompt\n * const result = await llm.invoke(input);\n * console.log(result);\n * ```\n *\n * ```txt\n * AIMessage {\n *   \"content\": \"The translation of \\\"I love programming\\\" into French is:\\n\\n\\\"J'adore programmer.\\\"\",\n *   \"additional_kwargs\": {},\n *   \"response_metadata\": {\n *     \"model\": \"llama3.1:8b\",\n *     \"created_at\": \"2024-08-12T22:12:23.09468Z\",\n *     \"done_reason\": \"stop\",\n *     \"done\": true,\n *     \"total_duration\": 3715571291,\n *     \"load_duration\": 35244375,\n *     \"prompt_eval_count\": 19,\n *     \"prompt_eval_duration\": 3092116000,\n *     \"eval_count\": 20,\n *     \"eval_duration\": 585789000\n *   },\n *   \"tool_calls\": [],\n *   \"invalid_tool_calls\": [],\n *   \"usage_metadata\": {\n *     \"input_tokens\": 19,\n *     \"output_tokens\": 20,\n *     \"total_tokens\": 39\n *   }\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Streaming Chunks</strong></summary>\n *\n * ```typescript\n * for await (const chunk of await llm.stream(input)) {\n *   console.log(chunk);\n * }\n * ```\n *\n * ```txt\n * AIMessageChunk {\n *   \"content\": \"The\",\n *   \"additional_kwargs\": {},\n *   \"response_metadata\": {},\n *   \"tool_calls\": [],\n *   \"tool_call_chunks\": [],\n *   \"invalid_tool_calls\": []\n * }\n * AIMessageChunk {\n *   \"content\": \" translation\",\n *   \"additional_kwargs\": {},\n *   \"response_metadata\": {},\n *   \"tool_calls\": [],\n *   \"tool_call_chunks\": [],\n *   \"invalid_tool_calls\": []\n * }\n * AIMessageChunk {\n *   \"content\": \" of\",\n *   \"additional_kwargs\": {},\n *   \"response_metadata\": {},\n *   \"tool_calls\": [],\n *   \"tool_call_chunks\": [],\n *   \"invalid_tool_calls\": []\n * }\n * AIMessageChunk {\n *   \"content\": \" \\\"\",\n *   \"additional_kwargs\": {},\n *   \"response_metadata\": {},\n *   \"tool_calls\": [],\n *   \"tool_call_chunks\": [],\n *   \"invalid_tool_calls\": []\n * }\n * AIMessageChunk {\n *   \"content\": \"I\",\n *   \"additional_kwargs\": {},\n *   \"response_metadata\": {},\n *   \"tool_calls\": [],\n *   \"tool_call_chunks\": [],\n *   \"invalid_tool_calls\": []\n * }\n * ...\n * AIMessageChunk {\n *   \"content\": \"\",\n *   \"additional_kwargs\": {},\n *   \"response_metadata\": {},\n *   \"tool_calls\": [],\n *   \"tool_call_chunks\": [],\n *   \"invalid_tool_calls\": []\n * }\n * AIMessageChunk {\n *   \"content\": \"\",\n *   \"additional_kwargs\": {},\n *   \"response_metadata\": {\n *     \"model\": \"llama3.1:8b\",\n *     \"created_at\": \"2024-08-12T22:13:22.22423Z\",\n *     \"done_reason\": \"stop\",\n *     \"done\": true,\n *     \"total_duration\": 8599883208,\n *     \"load_duration\": 35975875,\n *     \"prompt_eval_count\": 19,\n *     \"prompt_eval_duration\": 7918195000,\n *     \"eval_count\": 20,\n *     \"eval_duration\": 643569000\n *   },\n *   \"tool_calls\": [],\n *   \"tool_call_chunks\": [],\n *   \"invalid_tool_calls\": [],\n *   \"usage_metadata\": {\n *     \"input_tokens\": 19,\n *     \"output_tokens\": 20,\n *     \"total_tokens\": 39\n *   }\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Bind tools</strong></summary>\n *\n * ```typescript\n * import { z } from 'zod';\n *\n * const GetWeather = {\n *   name: \"GetWeather\",\n *   description: \"Get the current weather in a given location\",\n *   schema: z.object({\n *     location: z.string().describe(\"The city and state, e.g. San Francisco, CA\")\n *   }),\n * }\n *\n * const GetPopulation = {\n *   name: \"GetPopulation\",\n *   description: \"Get the current population in a given location\",\n *   schema: z.object({\n *     location: z.string().describe(\"The city and state, e.g. San Francisco, CA\")\n *   }),\n * }\n *\n * const llmWithTools = llm.bindTools([GetWeather, GetPopulation]);\n * const aiMsg = await llmWithTools.invoke(\n *   \"Which city is hotter today and which is bigger: LA or NY?\"\n * );\n * console.log(aiMsg.tool_calls);\n * ```\n *\n * ```txt\n * [\n *   {\n *     name: 'GetWeather',\n *     args: { location: 'Los Angeles, CA' },\n *     id: '49410cad-2163-415e-bdcd-d26938a9c8c5',\n *     type: 'tool_call'\n *   },\n *   {\n *     name: 'GetPopulation',\n *     args: { location: 'New York, NY' },\n *     id: '39e230e4-63ec-4fae-9df0-21c3abe735ad',\n *     type: 'tool_call'\n *   }\n * ]\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Structured Output</strong></summary>\n *\n * ```typescript\n * import { z } from 'zod';\n *\n * const Joke = z.object({\n *   setup: z.string().describe(\"The setup of the joke\"),\n *   punchline: z.string().describe(\"The punchline to the joke\"),\n *   rating: z.number().optional().describe(\"How funny the joke is, from 1 to 10\")\n * }).describe('Joke to tell user.');\n *\n * const structuredLlm = llm.withStructuredOutput(Joke, { name: \"Joke\" });\n * const jokeResult = await structuredLlm.invoke(\"Tell me a joke about cats\");\n * console.log(jokeResult);\n * ```\n *\n * ```txt\n * {\n *   punchline: 'Why did the cat join a band? Because it wanted to be the purr-cussionist!',\n *   rating: 8,\n *   setup: 'A cat walks into a music store and asks the owner...'\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Usage Metadata</strong></summary>\n *\n * ```typescript\n * const aiMsgForMetadata = await llm.invoke(input);\n * console.log(aiMsgForMetadata.usage_metadata);\n * ```\n *\n * ```txt\n * { input_tokens: 19, output_tokens: 20, total_tokens: 39 }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Response Metadata</strong></summary>\n *\n * ```typescript\n * const aiMsgForResponseMetadata = await llm.invoke(input);\n * console.log(aiMsgForResponseMetadata.response_metadata);\n * ```\n *\n * ```txt\n * {\n *   model: 'llama3.1:8b',\n *   created_at: '2024-08-12T22:17:42.274795Z',\n *   done_reason: 'stop',\n *   done: true,\n *   total_duration: 6767071209,\n *   load_duration: 31628209,\n *   prompt_eval_count: 19,\n *   prompt_eval_duration: 6124504000,\n *   eval_count: 20,\n *   eval_duration: 608785000\n * }\n * ```\n * </details>\n *\n * <br />\n */\nexport class ChatOllama\n  extends BaseChatModel<ChatOllamaCallOptions, AIMessageChunk>\n  implements ChatOllamaInput\n{\n  // Used for tracing, replace with the same name as your class\n  static lc_name() {\n    return \"ChatOllama\";\n  }\n\n  model = \"llama3\";\n\n  numa?: boolean;\n\n  numCtx?: number;\n\n  numBatch?: number;\n\n  numGpu?: number;\n\n  mainGpu?: number;\n\n  lowVram?: boolean;\n\n  f16Kv?: boolean;\n\n  logitsAll?: boolean;\n\n  vocabOnly?: boolean;\n\n  useMmap?: boolean;\n\n  useMlock?: boolean;\n\n  embeddingOnly?: boolean;\n\n  numThread?: number;\n\n  numKeep?: number;\n\n  seed?: number;\n\n  numPredict?: number;\n\n  topK?: number;\n\n  topP?: number;\n\n  tfsZ?: number;\n\n  typicalP?: number;\n\n  repeatLastN?: number;\n\n  temperature?: number;\n\n  repeatPenalty?: number;\n\n  presencePenalty?: number;\n\n  frequencyPenalty?: number;\n\n  mirostat?: number;\n\n  mirostatTau?: number;\n\n  mirostatEta?: number;\n\n  penalizeNewline?: boolean;\n\n  streaming?: boolean;\n\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  format?: string | Record<string, any>;\n\n  keepAlive?: string | number;\n\n  client: Ollama;\n\n  checkOrPullModel = false;\n\n  baseUrl = \"http://127.0.0.1:11434\";\n\n  think?: boolean;\n\n  constructor(\n    model: OllamaChatRequest[\"model\"],\n    fields?: Omit<ChatOllamaInput, \"model\">\n  );\n  constructor(fields?: ChatOllamaInput);\n  constructor(\n    modelOrFields?: string | ChatOllamaInput,\n    fieldsArg?: Omit<ChatOllamaInput, \"model\">\n  ) {\n    const fields =\n      typeof modelOrFields === \"string\"\n        ? { ...(fieldsArg ?? {}), model: modelOrFields }\n        : (modelOrFields ?? {});\n    super(fields);\n    this._addVersion(\"@langchain/ollama\", __PKG_VERSION__);\n\n    this.baseUrl =\n      fields.baseUrl ??\n      getEnvironmentVariable(\"OLLAMA_BASE_URL\") ??\n      this.baseUrl;\n\n    this.client = new Ollama({\n      fetch: fields.fetch,\n      host: this.baseUrl,\n      headers: fields.headers,\n    });\n\n    this.model = fields.model ?? this.model;\n    this.numa = fields.numa;\n    this.numCtx = fields.numCtx;\n    this.numBatch = fields.numBatch;\n    this.numGpu = fields.numGpu;\n    this.mainGpu = fields.mainGpu;\n    this.lowVram = fields.lowVram;\n    this.f16Kv = fields.f16Kv;\n    this.logitsAll = fields.logitsAll;\n    this.vocabOnly = fields.vocabOnly;\n    this.useMmap = fields.useMmap;\n    this.useMlock = fields.useMlock;\n    this.embeddingOnly = fields.embeddingOnly;\n    this.numThread = fields.numThread;\n    this.numKeep = fields.numKeep;\n    this.seed = fields.seed;\n    this.numPredict = fields.numPredict;\n    this.topK = fields.topK;\n    this.topP = fields.topP;\n    this.tfsZ = fields.tfsZ;\n    this.typicalP = fields.typicalP;\n    this.repeatLastN = fields.repeatLastN;\n    this.temperature = fields.temperature;\n    this.repeatPenalty = fields.repeatPenalty;\n    this.presencePenalty = fields.presencePenalty;\n    this.frequencyPenalty = fields.frequencyPenalty;\n    this.mirostat = fields.mirostat;\n    this.mirostatTau = fields.mirostatTau;\n    this.mirostatEta = fields.mirostatEta;\n    this.penalizeNewline = fields.penalizeNewline;\n    this.streaming = fields.streaming;\n    this.format = fields.format;\n    this.keepAlive = fields.keepAlive;\n    this.think = fields.think;\n    this.checkOrPullModel = fields.checkOrPullModel ?? this.checkOrPullModel;\n  }\n\n  // Replace\n  _llmType() {\n    return \"ollama\";\n  }\n\n  /**\n   * Download a model onto the local machine.\n   *\n   * @param {string} model The name of the model to download.\n   * @param {PullModelOptions | undefined} options Options for pulling the model.\n   * @returns {Promise<void>}\n   */\n  async pull(model: string, options?: PullModelOptions): Promise<void> {\n    const { stream, insecure, logProgress } = {\n      stream: true,\n      ...options,\n    };\n\n    if (stream) {\n      for await (const chunk of await this.client.pull({\n        model,\n        insecure,\n        stream,\n      })) {\n        if (logProgress) {\n          console.log(chunk);\n        }\n      }\n    } else {\n      const response = await this.client.pull({ model, insecure });\n      if (logProgress) {\n        console.log(response);\n      }\n    }\n  }\n\n  override bindTools(\n    tools: BindToolsInput[],\n    kwargs?: Partial<this[\"ParsedCallOptions\"]>\n  ): Runnable<BaseLanguageModelInput, AIMessageChunk, ChatOllamaCallOptions> {\n    return this.withConfig({\n      tools: tools.map((tool) => convertToOpenAITool(tool)),\n      ...kwargs,\n    });\n  }\n\n  getLsParams(options: this[\"ParsedCallOptions\"]): LangSmithParams {\n    const params = this.invocationParams(options);\n    return {\n      ls_provider: \"ollama\",\n      ls_model_name: this.model,\n      ls_model_type: \"chat\",\n      ls_temperature: params.options?.temperature ?? undefined,\n      ls_max_tokens: params.options?.num_predict ?? undefined,\n      ls_stop: options.stop,\n    };\n  }\n\n  invocationParams(\n    options?: this[\"ParsedCallOptions\"]\n  ): Omit<OllamaChatRequest, \"messages\"> {\n    return {\n      model: this.model,\n      format: options?.format ?? this.format,\n      keep_alive: this.keepAlive,\n      think: this.think,\n      options: {\n        numa: this.numa,\n        num_ctx: this.numCtx,\n        num_batch: this.numBatch,\n        num_gpu: this.numGpu,\n        main_gpu: this.mainGpu,\n        low_vram: this.lowVram,\n        f16_kv: this.f16Kv,\n        logits_all: this.logitsAll,\n        vocab_only: this.vocabOnly,\n        use_mmap: this.useMmap,\n        use_mlock: this.useMlock,\n        embedding_only: this.embeddingOnly,\n        num_thread: this.numThread,\n        num_keep: this.numKeep,\n        seed: this.seed,\n        num_predict: this.numPredict,\n        top_k: this.topK,\n        top_p: this.topP,\n        tfs_z: this.tfsZ,\n        typical_p: this.typicalP,\n        repeat_last_n: this.repeatLastN,\n        temperature: this.temperature,\n        repeat_penalty: this.repeatPenalty,\n        presence_penalty: this.presencePenalty,\n        frequency_penalty: this.frequencyPenalty,\n        mirostat: this.mirostat,\n        mirostat_tau: this.mirostatTau,\n        mirostat_eta: this.mirostatEta,\n        penalize_newline: this.penalizeNewline,\n        stop: options?.stop,\n      },\n      tools: options?.tools?.length\n        ? (options.tools.map((tool) =>\n            convertToOpenAITool(tool)\n          ) as OllamaTool[])\n        : undefined,\n    };\n  }\n\n  /**\n   * Check if a model exists on the local machine.\n   *\n   * @param {string} model The name of the model to check.\n   * @returns {Promise<boolean>} Whether or not the model exists.\n   */\n  private async checkModelExistsOnMachine(model: string): Promise<boolean> {\n    const { models } = await this.client.list();\n    return !!models.find(\n      (m: { name: string }) => m.name === model || m.name === `${model}:latest`\n    );\n  }\n\n  async _generate(\n    messages: BaseMessage[],\n    options: this[\"ParsedCallOptions\"],\n    runManager?: CallbackManagerForLLMRun\n  ): Promise<ChatResult> {\n    options.signal?.throwIfAborted();\n    if (this.checkOrPullModel) {\n      if (!(await this.checkModelExistsOnMachine(this.model))) {\n        await this.pull(this.model, {\n          logProgress: true,\n        });\n      }\n    }\n\n    let finalChunk: AIMessageChunk | undefined;\n    for await (const chunk of this._streamResponseChunks(\n      messages,\n      options,\n      runManager\n    )) {\n      if (!finalChunk) {\n        finalChunk = chunk.message as AIMessageChunk;\n      } else {\n        finalChunk = concat(finalChunk, chunk.message as AIMessageChunk);\n      }\n    }\n\n    // Convert from AIMessageChunk to AIMessage since `generate` expects AIMessage.\n    const nonChunkMessage = new AIMessage({\n      id: finalChunk?.id,\n      content: finalChunk?.content ?? \"\",\n      additional_kwargs: finalChunk?.additional_kwargs,\n      tool_calls: finalChunk?.tool_calls,\n      response_metadata: finalChunk?.response_metadata,\n      usage_metadata: finalChunk?.usage_metadata,\n    });\n    return {\n      generations: [\n        {\n          text:\n            typeof nonChunkMessage.content === \"string\"\n              ? nonChunkMessage.content\n              : \"\",\n          message: nonChunkMessage,\n        },\n      ],\n    };\n  }\n\n  async *_streamResponseChunks(\n    messages: BaseMessage[],\n    options: this[\"ParsedCallOptions\"],\n    runManager?: CallbackManagerForLLMRun\n  ): AsyncGenerator<ChatGenerationChunk> {\n    if (this.checkOrPullModel) {\n      if (!(await this.checkModelExistsOnMachine(this.model))) {\n        await this.pull(this.model, {\n          logProgress: true,\n        });\n      }\n    }\n\n    const params = this.invocationParams(options);\n    // TODO: remove cast after SDK adds support for tool calls\n    const ollamaMessages = convertToOllamaMessages(messages) as OllamaMessage[];\n\n    const usageMetadata: UsageMetadata = {\n      input_tokens: 0,\n      output_tokens: 0,\n      total_tokens: 0,\n    };\n\n    const stream = await this.client.chat({\n      ...params,\n      messages: ollamaMessages,\n      stream: true,\n    });\n\n    let lastMetadata: Omit<OllamaChatResponse, \"message\"> | undefined;\n\n    for await (const streamChunk of stream) {\n      if (options.signal?.aborted) {\n        this.client.abort();\n        return;\n      }\n      const { message: responseMessage, ...rest } = streamChunk;\n      usageMetadata.input_tokens += rest.prompt_eval_count ?? 0;\n      usageMetadata.output_tokens += rest.eval_count ?? 0;\n      usageMetadata.total_tokens =\n        usageMetadata.input_tokens + usageMetadata.output_tokens;\n      lastMetadata = rest;\n\n      // when think is enabled, try thinking first\n      const token = this.think\n        ? (responseMessage.thinking ?? responseMessage.content ?? \"\")\n        : (responseMessage.content ?? \"\");\n\n      const chunk = new ChatGenerationChunk({\n        text: token,\n        message: convertOllamaMessagesToLangChain(responseMessage),\n      });\n      yield chunk;\n      await runManager?.handleLLMNewToken(\n        token,\n        undefined,\n        undefined,\n        undefined,\n        undefined,\n        { chunk }\n      );\n    }\n\n    // Yield the `response_metadata` as the final chunk.\n    yield new ChatGenerationChunk({\n      text: \"\",\n      message: new AIMessageChunk({\n        content: \"\",\n        response_metadata: {\n          ...lastMetadata,\n          model_provider: \"ollama\",\n        },\n        usage_metadata: usageMetadata,\n      }),\n    });\n  }\n\n  withStructuredOutput<\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    RunOutput extends Record<string, any> = Record<string, any>,\n  >(\n    outputSchema:\n      | InteropZodType<RunOutput>\n      | SerializableSchema<RunOutput>\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      | Record<string, any>,\n    config?: StructuredOutputMethodOptions<false>\n  ): Runnable<BaseLanguageModelInput, RunOutput>;\n\n  withStructuredOutput<\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    RunOutput extends Record<string, any> = Record<string, any>,\n  >(\n    outputSchema:\n      | InteropZodType<RunOutput>\n      | SerializableSchema<RunOutput>\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      | Record<string, any>,\n    config?: StructuredOutputMethodOptions<true>\n  ): Runnable<BaseLanguageModelInput, { raw: BaseMessage; parsed: RunOutput }>;\n\n  withStructuredOutput<\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    RunOutput extends Record<string, any> = Record<string, any>,\n  >(\n    outputSchema:\n      | InteropZodType<RunOutput>\n      | SerializableSchema<RunOutput>\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      | Record<string, any>,\n    config?: StructuredOutputMethodOptions<boolean>\n  ):\n    | Runnable<BaseLanguageModelInput, RunOutput>\n    | Runnable<\n        BaseLanguageModelInput,\n        {\n          raw: BaseMessage;\n          parsed: RunOutput;\n        }\n      >;\n\n  withStructuredOutput<\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    RunOutput extends Record<string, any> = Record<string, any>,\n  >(\n    outputSchema:\n      | InteropZodType<RunOutput>\n      | SerializableSchema<RunOutput>\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      | Record<string, any>,\n    config?: StructuredOutputMethodOptions<boolean>\n  ):\n    | Runnable<BaseLanguageModelInput, RunOutput>\n    | Runnable<\n        BaseLanguageModelInput,\n        {\n          raw: BaseMessage;\n          parsed: RunOutput;\n        }\n      > {\n    let llm: Runnable<BaseLanguageModelInput>;\n    let outputParser: Runnable<AIMessageChunk, RunOutput>;\n\n    const { schema, name, includeRaw } = {\n      ...config,\n      schema: outputSchema,\n    };\n    const method = config?.method ?? \"jsonSchema\";\n\n    if (method === \"functionCalling\") {\n      let functionName = name ?? \"extract\";\n      let toolFunction: FunctionDefinition;\n      const jsonSchema = toJsonSchema(schema);\n\n      if (isInteropZodSchema(schema) || isSerializableSchema(schema)) {\n        toolFunction = {\n          name: functionName,\n          description: jsonSchema.description,\n          parameters: jsonSchema,\n        };\n      } else if (\n        typeof schema.name === \"string\" &&\n        typeof schema.parameters === \"object\" &&\n        schema.parameters != null\n      ) {\n        toolFunction = schema as FunctionDefinition;\n        functionName = schema.name;\n      } else {\n        toolFunction = {\n          name: functionName,\n          description: schema.description ?? \"\",\n          parameters: schema,\n        };\n      }\n\n      llm = this.bindTools([\n        { type: \"function\", function: toolFunction },\n      ]).withConfig({\n        ls_structured_output_format: {\n          kwargs: { method },\n          schema:\n            isInteropZodSchema(schema) || isSerializableSchema(schema)\n              ? jsonSchema\n              : schema,\n        },\n      } as Partial<ChatOllamaCallOptions>);\n\n      outputParser = createFunctionCallingParser(schema, functionName);\n    } else if (method === \"jsonMode\" || method === \"jsonSchema\") {\n      outputParser = createContentParser(schema);\n      const jsonSchema = toJsonSchema(schema);\n      llm = this.withConfig({\n        format: method === \"jsonMode\" ? \"json\" : jsonSchema,\n        ls_structured_output_format: {\n          kwargs: { method },\n          schema: jsonSchema,\n        },\n      } as Partial<ChatOllamaCallOptions>);\n    } else {\n      throw new TypeError(\n        `Unrecognized structured output method '${method}'. Expected one of 'functionCalling', 'jsonMode', or 'jsonSchema'`\n      );\n    }\n\n    return assembleStructuredOutputPipeline(\n      llm,\n      outputParser,\n      includeRaw,\n      includeRaw ? \"StructuredOutputRunnable\" : \"ChatOllamaStructuredOutput\"\n    );\n  }\n}\n"],"mappings":"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"}