@langchain/openrouter 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @langchain/openrouter
2
2
 
3
+ ## 0.1.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`62ba83e`](https://github.com/langchain-ai/langchainjs/commit/62ba83edd5206c86d8da8d1b608a2493ee4f3da8)]:
8
+ - @langchain/openai@1.2.10
9
+
10
+ ## 0.1.2
11
+
12
+ ### Patch Changes
13
+
14
+ - [#10109](https://github.com/langchain-ai/langchainjs/pull/10109) [`630890a`](https://github.com/langchain-ai/langchainjs/commit/630890a1f5b4a85054b2d0cfab41e8780da5e91e) Thanks [@hntrl](https://github.com/hntrl)! - feat(openrouter): default OpenRouter attribution headers
15
+
16
+ `ChatOpenRouter` now sends `HTTP-Referer` and `X-Title` headers by default for OpenRouter app attribution. `siteUrl` defaults to `"https://docs.langchain.com/oss"` and `siteName` defaults to `"langchain"`. Users can still override both values.
17
+
3
18
  ## 0.1.1
4
19
 
5
20
  ### Patch Changes
@@ -112,9 +112,17 @@ var ChatOpenRouter = class extends _langchain_core_language_models_chat_models.B
112
112
  provider;
113
113
  /** OpenRouter plugins to enable (e.g. web search). */
114
114
  plugins;
115
- /** Your site URL — used for rankings on openrouter.ai. */
115
+ /**
116
+ * Application URL for OpenRouter attribution. Maps to `HTTP-Referer` header.
117
+ *
118
+ * See https://openrouter.ai/docs/app-attribution for details.
119
+ */
116
120
  siteUrl;
117
- /** Your site/app name — used for rankings on openrouter.ai. */
121
+ /**
122
+ * Application title for OpenRouter attribution. Maps to `X-Title` header.
123
+ *
124
+ * See https://openrouter.ai/docs/app-attribution for details.
125
+ */
118
126
  siteName;
119
127
  /** Extra params passed through to the API body. */
120
128
  modelKwargs;
@@ -147,8 +155,8 @@ var ChatOpenRouter = class extends _langchain_core_language_models_chat_models.B
147
155
  this.route = fields.route;
148
156
  this.provider = fields.provider;
149
157
  this.plugins = fields.plugins;
150
- this.siteUrl = fields.siteUrl;
151
- this.siteName = fields.siteName;
158
+ this.siteUrl = fields.siteUrl ?? "https://docs.langchain.com/oss";
159
+ this.siteName = fields.siteName ?? "langchain";
152
160
  this.modelKwargs = fields.modelKwargs;
153
161
  this.streamUsage = fields.streamUsage ?? true;
154
162
  }
@@ -164,8 +172,8 @@ var ChatOpenRouter = class extends _langchain_core_language_models_chat_models.B
164
172
  return {
165
173
  Authorization: `Bearer ${this.apiKey}`,
166
174
  "Content-Type": "application/json",
167
- ...this.siteUrl ? { "HTTP-Referer": this.siteUrl } : {},
168
- ...this.siteName ? { "X-Title": this.siteName } : {}
175
+ "HTTP-Referer": this.siteUrl,
176
+ "X-Title": this.siteName
169
177
  };
170
178
  }
171
179
  /** Returns the full chat-completions endpoint URL. */
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["BaseChatModel","OpenRouterAuthError","PROFILES","convertToolsToOpenRouter","formatToolChoice","convertMessagesToOpenRouterParams","OpenRouterError","convertOpenRouterResponseToBaseMessage","AIMessage","convertUsageMetadata","EventSourceParserStream","OpenRouterJsonParseStream","convertOpenRouterDeltaToBaseMessageChunk","AIMessageChunk","ChatGenerationChunk","resolveOpenRouterStructuredOutputMethod","StructuredOutputParser","JsonOutputParser","JsonOutputKeyToolsParser","RunnablePassthrough","RunnableSequence"],"sources":["../../src/chat_models/index.ts"],"sourcesContent":["import {\n BaseChatModel,\n type BindToolsInput,\n type LangSmithParams,\n} from \"@langchain/core/language_models/chat_models\";\nimport type { ModelProfile } from \"@langchain/core/language_models/profile\";\nimport type {\n BaseLanguageModelInput,\n StructuredOutputMethodOptions,\n} from \"@langchain/core/language_models/base\";\nimport {\n AIMessage,\n AIMessageChunk,\n BaseMessage,\n} from \"@langchain/core/messages\";\nimport { ChatGenerationChunk, type ChatResult } from \"@langchain/core/outputs\";\nimport type { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport {\n Runnable,\n RunnablePassthrough,\n RunnableSequence,\n} from \"@langchain/core/runnables\";\nimport { toJsonSchema } from \"@langchain/core/utils/json_schema\";\nimport {\n type InteropZodType,\n isInteropZodSchema,\n getSchemaDescription,\n} from \"@langchain/core/utils/types\";\nimport {\n JsonOutputParser,\n StructuredOutputParser,\n} from \"@langchain/core/output_parsers\";\nimport { JsonOutputKeyToolsParser } from \"@langchain/core/output_parsers/openai_tools\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport { EventSourceParserStream } from \"eventsource-parser/stream\";\n\nimport type {\n ChatOpenRouterParams,\n ChatOpenRouterCallOptions,\n} from \"./types.js\";\nimport type { OpenAI as OpenAIClient } from \"openai\";\nimport type { OpenRouter } from \"../api-types.js\";\n\n/**\n * Full request body sent to the OpenRouter `/chat/completions` endpoint.\n *\n * Extends the base generation params with OpenRouter-specific sampling\n * knobs (`top_k`, `min_p`, etc.) and features (`prediction`, `transforms`)\n * that aren't part of the standard OpenAI spec.\n */\ntype OpenRouterRequestBody = Omit<\n OpenRouter.ChatGenerationParams,\n \"messages\"\n> & {\n messages: OpenAIClient.Chat.Completions.ChatCompletionMessageParam[];\n top_k?: number | null;\n repetition_penalty?: number | null;\n min_p?: number | null;\n top_a?: number | null;\n prediction?: { type: \"content\"; content: string };\n transforms?: string[];\n};\nimport {\n convertMessagesToOpenRouterParams,\n convertOpenRouterResponseToBaseMessage,\n convertOpenRouterDeltaToBaseMessageChunk,\n convertUsageMetadata,\n} from \"../converters/messages.js\";\nimport {\n convertToolsToOpenRouter,\n formatToolChoice,\n} from \"../converters/tools.js\";\nimport { OpenRouterError, OpenRouterAuthError } from \"../utils/errors.js\";\nimport { resolveOpenRouterStructuredOutputMethod } from \"../utils/structured_output.js\";\nimport { OpenRouterJsonParseStream } from \"../utils/stream.js\";\nimport PROFILES from \"../profiles.js\";\n\nconst DEFAULT_BASE_URL = \"https://openrouter.ai/api/v1\";\n\n/**\n * OpenRouter chat model integration.\n *\n * Talks directly to the OpenRouter REST API via `fetch` (no SDK dependency)\n * and supports tool calling, structured output, and streaming. Any model\n * available on OpenRouter can be used by passing its identifier (e.g.\n * `\"anthropic/claude-4-sonnet\"`) as the `model` param.\n */\nexport class ChatOpenRouter extends BaseChatModel<\n ChatOpenRouterCallOptions,\n AIMessageChunk\n> {\n static lc_name() {\n return \"ChatOpenRouter\";\n }\n\n lc_serializable = true;\n\n /** Maps secret fields to the environment variable they can be loaded from. */\n get lc_secrets(): { [key: string]: string } | undefined {\n return {\n apiKey: \"OPENROUTER_API_KEY\",\n };\n }\n\n /** Allows serialized JSON to use `modelName` as an alias for `model`. */\n get lc_aliases(): Record<string, string> {\n return {\n modelName: \"model\",\n };\n }\n\n /** Fields that may be overridden per-call via `.bind()` / `.withConfig()`. */\n get callKeys(): string[] {\n return [\n ...super.callKeys,\n \"tools\",\n \"tool_choice\",\n \"response_format\",\n \"seed\",\n \"strict\",\n \"temperature\",\n \"maxTokens\",\n \"topP\",\n \"topK\",\n \"frequencyPenalty\",\n \"presencePenalty\",\n \"repetitionPenalty\",\n \"minP\",\n \"topA\",\n \"stop\",\n \"logitBias\",\n \"topLogprobs\",\n \"user\",\n \"transforms\",\n \"models\",\n \"route\",\n \"provider\",\n \"plugins\",\n \"prediction\",\n ];\n }\n\n /** Model identifier, e.g. `\"anthropic/claude-4-sonnet\"`. */\n model: string;\n\n /** OpenRouter API key. Falls back to the `OPENROUTER_API_KEY` env var. */\n apiKey: string;\n\n /** Base URL for the API. Defaults to `\"https://openrouter.ai/api/v1\"`. */\n baseURL: string;\n\n /** Sampling temperature (0–2). */\n temperature?: number;\n\n /** Maximum number of tokens to generate. */\n maxTokens?: number;\n\n /** Nucleus sampling cutoff probability. */\n topP?: number;\n\n /** Top-K sampling: only consider the K most likely tokens. */\n topK?: number;\n\n /** Additive penalty based on how often a token has appeared so far (−2 to 2). */\n frequencyPenalty?: number;\n\n /** Additive penalty based on whether a token has appeared at all (−2 to 2). */\n presencePenalty?: number;\n\n /** Multiplicative penalty applied to repeated token logits (0 to 2). */\n repetitionPenalty?: number;\n\n /** Minimum probability threshold for token sampling. */\n minP?: number;\n\n /** Top-A sampling threshold. */\n topA?: number;\n\n /** Random seed for deterministic generation. */\n seed?: number;\n\n /** Stop sequences that halt generation. */\n stop?: string[];\n\n /** Token-level biases to apply during sampling. */\n logitBias?: Record<string, number>;\n\n /** Number of most-likely log-probabilities to return per token. */\n topLogprobs?: number;\n\n /** Stable identifier for end-users, used for abuse detection. */\n user?: string;\n\n /** OpenRouter-specific transformations to apply to the request. */\n transforms?: string[];\n\n /** OpenRouter-specific list of models for routing. */\n models?: string[];\n\n /** OpenRouter-specific routing strategy. */\n route?: \"fallback\";\n\n /** OpenRouter-specific provider preferences and ordering. */\n provider?: OpenRouter.ProviderPreferences;\n\n /** OpenRouter plugins to enable (e.g. web search). */\n plugins?: ChatOpenRouterParams[\"plugins\"];\n\n /** Your site URL — used for rankings on openrouter.ai. */\n siteUrl?: string;\n\n /** Your site/app name — used for rankings on openrouter.ai. */\n siteName?: string;\n\n /** Extra params passed through to the API body. */\n modelKwargs?: Record<string, unknown>;\n\n /** Whether to include token usage in streaming chunks. Defaults to `true`. */\n streamUsage: boolean;\n\n constructor(fields: ChatOpenRouterParams) {\n super(fields);\n const apiKey =\n fields.apiKey ?? getEnvironmentVariable(\"OPENROUTER_API_KEY\");\n if (!apiKey) {\n throw new OpenRouterAuthError(\n \"OpenRouter API key is required. Get one at https://openrouter.ai/keys and set it via the `apiKey` parameter or the OPENROUTER_API_KEY environment variable.\"\n );\n }\n this.apiKey = apiKey;\n if (!fields.model) {\n throw new Error(\n 'ChatOpenRouter requires a `model` parameter, e.g. \"openai/gpt-4o-mini\".'\n );\n }\n this.model = fields.model;\n this.baseURL = fields.baseURL ?? DEFAULT_BASE_URL;\n this.temperature = fields.temperature;\n this.maxTokens = fields.maxTokens;\n this.topP = fields.topP;\n this.topK = fields.topK;\n this.frequencyPenalty = fields.frequencyPenalty;\n this.presencePenalty = fields.presencePenalty;\n this.repetitionPenalty = fields.repetitionPenalty;\n this.minP = fields.minP;\n this.topA = fields.topA;\n this.seed = fields.seed;\n this.stop = fields.stop;\n this.logitBias = fields.logitBias;\n this.topLogprobs = fields.topLogprobs;\n this.user = fields.user;\n this.transforms = fields.transforms;\n this.models = fields.models;\n this.route = fields.route;\n this.provider = fields.provider;\n this.plugins = fields.plugins;\n this.siteUrl = fields.siteUrl;\n this.siteName = fields.siteName;\n this.modelKwargs = fields.modelKwargs;\n this.streamUsage = fields.streamUsage ?? true;\n }\n\n _llmType(): string {\n return \"openrouter\";\n }\n\n /** Static capability profile (context size, tool support, etc.) for the current model. */\n get profile(): ModelProfile {\n return PROFILES[this.model] ?? {};\n }\n\n /** Builds auth + content-type headers, plus optional site attribution headers. */\n private buildHeaders(): Record<string, string> {\n return {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n ...(this.siteUrl ? { \"HTTP-Referer\": this.siteUrl } : {}),\n ...(this.siteName ? { \"X-Title\": this.siteName } : {}),\n };\n }\n\n /** Returns the full chat-completions endpoint URL. */\n private buildUrl(): string {\n return `${this.baseURL}/chat/completions`;\n }\n\n /**\n * Merges constructor-level defaults with per-call overrides into the\n * API request body (everything except `messages`, which is added later).\n */\n override invocationParams(\n options: this[\"ParsedCallOptions\"]\n ): Omit<OpenRouterRequestBody, \"messages\"> {\n const tools = options.tools\n ? convertToolsToOpenRouter(options.tools, { strict: options.strict })\n : undefined;\n const toolChoice = formatToolChoice(options.tool_choice);\n\n return {\n model: this.model,\n temperature: options.temperature ?? this.temperature,\n max_tokens: options.maxTokens ?? this.maxTokens,\n top_p: options.topP ?? this.topP,\n top_k: options.topK ?? this.topK,\n frequency_penalty: options.frequencyPenalty ?? this.frequencyPenalty,\n presence_penalty: options.presencePenalty ?? this.presencePenalty,\n repetition_penalty: options.repetitionPenalty ?? this.repetitionPenalty,\n min_p: options.minP ?? this.minP,\n top_a: options.topA ?? this.topA,\n seed: options.seed ?? this.seed,\n stop: options.stop ?? this.stop,\n logit_bias: options.logitBias ?? this.logitBias,\n top_logprobs: options.topLogprobs ?? this.topLogprobs,\n user: options.user ?? this.user,\n tools,\n tool_choice: toolChoice,\n response_format: options.response_format,\n ...(options.prediction ? { prediction: options.prediction } : {}),\n transforms: options.transforms ?? this.transforms,\n models: options.models ?? this.models,\n route: options.route ?? this.route,\n provider: options.provider ?? this.provider,\n plugins: options.plugins ?? this.plugins,\n ...this.modelKwargs,\n };\n }\n\n /** Returns metadata for LangSmith tracing (provider, model name, temperature, etc.). */\n override getLsParams(options: this[\"ParsedCallOptions\"]): LangSmithParams {\n const params = this.invocationParams(options);\n return {\n ls_provider: \"openrouter\",\n ls_model_name: this.model,\n ls_model_type: \"chat\",\n ls_temperature: params.temperature ?? undefined,\n ls_max_tokens: params.max_tokens ?? undefined,\n ls_stop: options.stop,\n };\n }\n\n /**\n * Non-streaming generation. Sends a single request and returns the\n * complete response with the generated message and token usage.\n */\n async _generate(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n const body: OpenRouterRequestBody = {\n ...this.invocationParams(options),\n messages: convertMessagesToOpenRouterParams(messages, this.model),\n stream: false,\n };\n\n const response = await fetch(this.buildUrl(), {\n method: \"POST\",\n headers: this.buildHeaders(),\n body: JSON.stringify(body),\n signal: options.signal,\n });\n\n if (!response.ok) {\n throw await OpenRouterError.fromResponse(response);\n }\n\n const data: OpenRouter.ChatResponse = await response.json();\n const choice = data.choices[0];\n\n if (!choice) {\n throw new OpenRouterError(\"No choices returned in response.\");\n }\n\n const message = convertOpenRouterResponseToBaseMessage(choice, data);\n if (AIMessage.isInstance(message)) {\n message.usage_metadata = convertUsageMetadata(data.usage);\n }\n\n const text = typeof message.content === \"string\" ? message.content : \"\";\n\n await runManager?.handleLLMNewToken(text);\n\n return {\n generations: [\n {\n text,\n message,\n generationInfo: {\n finish_reason: choice.finish_reason,\n },\n },\n ],\n llmOutput: { tokenUsage: data.usage },\n };\n }\n\n /**\n * Streaming generation. Opens an SSE connection and yields one\n * `ChatGenerationChunk` per delta received from the API. The stream\n * pipeline is: raw bytes -> text -> SSE events -> JSON-parsed deltas.\n */\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const body: OpenRouterRequestBody = {\n ...this.invocationParams(options),\n messages: convertMessagesToOpenRouterParams(messages, this.model),\n stream: true,\n };\n\n const response = await fetch(this.buildUrl(), {\n method: \"POST\",\n headers: this.buildHeaders(),\n body: JSON.stringify(body),\n signal: options.signal,\n });\n\n if (!response.ok) {\n throw await OpenRouterError.fromResponse(response);\n }\n\n if (!response.body) {\n return;\n }\n\n const stream = response.body\n .pipeThrough(new TextDecoderStream())\n .pipeThrough(new EventSourceParserStream())\n .pipeThrough(new OpenRouterJsonParseStream());\n\n const reader = stream.getReader();\n let defaultRole: string | undefined;\n\n try {\n while (true) {\n const { done, value: data } = await reader.read();\n if (done) break;\n if (!data) continue;\n\n const choice = data.choices?.[0];\n if (!choice?.delta) continue;\n\n const chunk = convertOpenRouterDeltaToBaseMessageChunk(\n choice.delta,\n data,\n defaultRole\n );\n defaultRole = choice.delta.role ?? defaultRole;\n\n if (\n data.usage &&\n this.streamUsage &&\n AIMessageChunk.isInstance(chunk)\n ) {\n chunk.usage_metadata = convertUsageMetadata(data.usage);\n }\n\n const text = typeof chunk.content === \"string\" ? chunk.content : \"\";\n\n const generationChunk = new ChatGenerationChunk({\n message: chunk,\n text,\n generationInfo: {\n ...(choice.finish_reason\n ? { finish_reason: choice.finish_reason }\n : {}),\n },\n });\n\n yield generationChunk;\n await runManager?.handleLLMNewToken(text);\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n /**\n * Returns a new Runnable with the given tools bound into every call.\n * Equivalent to `.withConfig({ tools, ...kwargs })`.\n */\n override bindTools(\n tools: BindToolsInput[],\n kwargs?: Partial<ChatOpenRouterCallOptions>\n ): Runnable<\n BaseLanguageModelInput,\n AIMessageChunk,\n ChatOpenRouterCallOptions\n > {\n return this.withConfig({\n ...kwargs,\n tools,\n } as Partial<ChatOpenRouterCallOptions>);\n }\n\n /**\n * Returns a Runnable that forces the model to produce output conforming\n * to `outputSchema` (a Zod schema or plain JSON Schema object).\n *\n * The extraction strategy (JSON Schema response format, function calling,\n * or JSON mode) is chosen automatically based on model capabilities —\n * see {@link resolveOpenRouterStructuredOutputMethod}. You can override\n * this via `config.method`.\n *\n * When `config.includeRaw` is `true` the returned object contains both\n * the raw `BaseMessage` and the parsed output, with a fallback that\n * sets `parsed: null` if the parser throws.\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 // 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 // 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 // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<boolean>\n ):\n | Runnable<BaseLanguageModelInput, RunOutput>\n | Runnable<BaseLanguageModelInput, { raw: BaseMessage; parsed: RunOutput }>;\n\n withStructuredOutput<\n RunOutput extends Record<string, unknown> = Record<string, unknown>\n >(\n outputSchema: InteropZodType<RunOutput> | Record<string, unknown>,\n config?: StructuredOutputMethodOptions<boolean>\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\n const method = resolveOpenRouterStructuredOutputMethod({\n model: this.model,\n method: config?.method,\n profile: this.profile,\n models: this.models,\n route: this.route,\n });\n\n const asJsonSchema = toJsonSchema(schema);\n\n if (method === \"jsonSchema\") {\n const schemaName = name ?? \"extract\";\n llm = this.withConfig({\n response_format: {\n type: \"json_schema\",\n json_schema: {\n name: schemaName,\n description: getSchemaDescription(schema),\n schema: asJsonSchema,\n strict: config?.strict,\n },\n },\n ls_structured_output_format: {\n kwargs: { method: \"json_schema\" },\n schema: {\n title: schemaName,\n description: getSchemaDescription(schema),\n ...asJsonSchema,\n },\n },\n } as Partial<ChatOpenRouterCallOptions>);\n\n outputParser = isInteropZodSchema(schema)\n ? StructuredOutputParser.fromZodSchema(schema)\n : new JsonOutputParser<RunOutput>();\n } else if (method === \"jsonMode\") {\n llm = this.withConfig({\n response_format: { type: \"json_object\" },\n ls_structured_output_format: {\n kwargs: { method: \"json_mode\" },\n schema: { title: name ?? \"extract\", ...asJsonSchema },\n },\n } as Partial<ChatOpenRouterCallOptions>);\n\n outputParser = isInteropZodSchema(schema)\n ? StructuredOutputParser.fromZodSchema(schema)\n : new JsonOutputParser<RunOutput>();\n } else {\n let functionName = name ?? \"extract\";\n if (\"name\" in (schema as Record<string, unknown>)) {\n functionName = (schema as Record<string, unknown>).name as string;\n }\n\n llm = this.withConfig({\n tools: [\n {\n type: \"function\" as const,\n function: {\n name: functionName,\n description: getSchemaDescription(schema) ?? \"\",\n parameters: asJsonSchema,\n },\n },\n ],\n tool_choice: {\n type: \"function\" as const,\n function: { name: functionName },\n },\n ls_structured_output_format: {\n kwargs: { method: \"function_calling\" },\n schema: { title: functionName, ...asJsonSchema },\n },\n ...(config?.strict !== undefined ? { strict: config.strict } : {}),\n } as Partial<ChatOpenRouterCallOptions>);\n\n outputParser = isInteropZodSchema(schema)\n ? new JsonOutputKeyToolsParser({\n returnSingle: true,\n keyName: functionName,\n zodSchema: schema,\n })\n : new JsonOutputKeyToolsParser<RunOutput>({\n returnSingle: true,\n keyName: functionName,\n });\n }\n\n if (!includeRaw) {\n return llm.pipe(outputParser).withConfig({\n runName: \"ChatOpenRouterStructuredOutput\",\n }) as Runnable<BaseLanguageModelInput, RunOutput>;\n }\n\n const parserAssign = RunnablePassthrough.assign({\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n parsed: (input: any, config) => outputParser.invoke(input.raw, config),\n });\n const parserNone = RunnablePassthrough.assign({\n parsed: () => null,\n });\n const parsedWithFallback = parserAssign.withFallbacks({\n fallbacks: [parserNone],\n });\n return RunnableSequence.from<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n >([{ raw: llm }, parsedWithFallback]).withConfig({\n runName: \"ChatOpenRouterStructuredOutput\",\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["BaseChatModel","OpenRouterAuthError","PROFILES","convertToolsToOpenRouter","formatToolChoice","convertMessagesToOpenRouterParams","OpenRouterError","convertOpenRouterResponseToBaseMessage","AIMessage","convertUsageMetadata","EventSourceParserStream","OpenRouterJsonParseStream","convertOpenRouterDeltaToBaseMessageChunk","AIMessageChunk","ChatGenerationChunk","resolveOpenRouterStructuredOutputMethod","StructuredOutputParser","JsonOutputParser","JsonOutputKeyToolsParser","RunnablePassthrough","RunnableSequence"],"sources":["../../src/chat_models/index.ts"],"sourcesContent":["import {\n BaseChatModel,\n type BindToolsInput,\n type LangSmithParams,\n} from \"@langchain/core/language_models/chat_models\";\nimport type { ModelProfile } from \"@langchain/core/language_models/profile\";\nimport type {\n BaseLanguageModelInput,\n StructuredOutputMethodOptions,\n} from \"@langchain/core/language_models/base\";\nimport {\n AIMessage,\n AIMessageChunk,\n BaseMessage,\n} from \"@langchain/core/messages\";\nimport { ChatGenerationChunk, type ChatResult } from \"@langchain/core/outputs\";\nimport type { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport {\n Runnable,\n RunnablePassthrough,\n RunnableSequence,\n} from \"@langchain/core/runnables\";\nimport { toJsonSchema } from \"@langchain/core/utils/json_schema\";\nimport {\n type InteropZodType,\n isInteropZodSchema,\n getSchemaDescription,\n} from \"@langchain/core/utils/types\";\nimport {\n JsonOutputParser,\n StructuredOutputParser,\n} from \"@langchain/core/output_parsers\";\nimport { JsonOutputKeyToolsParser } from \"@langchain/core/output_parsers/openai_tools\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport { EventSourceParserStream } from \"eventsource-parser/stream\";\n\nimport type {\n ChatOpenRouterParams,\n ChatOpenRouterCallOptions,\n} from \"./types.js\";\nimport type { OpenAI as OpenAIClient } from \"openai\";\nimport type { OpenRouter } from \"../api-types.js\";\n\n/**\n * Full request body sent to the OpenRouter `/chat/completions` endpoint.\n *\n * Extends the base generation params with OpenRouter-specific sampling\n * knobs (`top_k`, `min_p`, etc.) and features (`prediction`, `transforms`)\n * that aren't part of the standard OpenAI spec.\n */\ntype OpenRouterRequestBody = Omit<\n OpenRouter.ChatGenerationParams,\n \"messages\"\n> & {\n messages: OpenAIClient.Chat.Completions.ChatCompletionMessageParam[];\n top_k?: number | null;\n repetition_penalty?: number | null;\n min_p?: number | null;\n top_a?: number | null;\n prediction?: { type: \"content\"; content: string };\n transforms?: string[];\n};\nimport {\n convertMessagesToOpenRouterParams,\n convertOpenRouterResponseToBaseMessage,\n convertOpenRouterDeltaToBaseMessageChunk,\n convertUsageMetadata,\n} from \"../converters/messages.js\";\nimport {\n convertToolsToOpenRouter,\n formatToolChoice,\n} from \"../converters/tools.js\";\nimport { OpenRouterError, OpenRouterAuthError } from \"../utils/errors.js\";\nimport { resolveOpenRouterStructuredOutputMethod } from \"../utils/structured_output.js\";\nimport { OpenRouterJsonParseStream } from \"../utils/stream.js\";\nimport PROFILES from \"../profiles.js\";\n\nconst DEFAULT_BASE_URL = \"https://openrouter.ai/api/v1\";\n\n/**\n * OpenRouter chat model integration.\n *\n * Talks directly to the OpenRouter REST API via `fetch` (no SDK dependency)\n * and supports tool calling, structured output, and streaming. Any model\n * available on OpenRouter can be used by passing its identifier (e.g.\n * `\"anthropic/claude-4-sonnet\"`) as the `model` param.\n */\nexport class ChatOpenRouter extends BaseChatModel<\n ChatOpenRouterCallOptions,\n AIMessageChunk\n> {\n static lc_name() {\n return \"ChatOpenRouter\";\n }\n\n lc_serializable = true;\n\n /** Maps secret fields to the environment variable they can be loaded from. */\n get lc_secrets(): { [key: string]: string } | undefined {\n return {\n apiKey: \"OPENROUTER_API_KEY\",\n };\n }\n\n /** Allows serialized JSON to use `modelName` as an alias for `model`. */\n get lc_aliases(): Record<string, string> {\n return {\n modelName: \"model\",\n };\n }\n\n /** Fields that may be overridden per-call via `.bind()` / `.withConfig()`. */\n get callKeys(): string[] {\n return [\n ...super.callKeys,\n \"tools\",\n \"tool_choice\",\n \"response_format\",\n \"seed\",\n \"strict\",\n \"temperature\",\n \"maxTokens\",\n \"topP\",\n \"topK\",\n \"frequencyPenalty\",\n \"presencePenalty\",\n \"repetitionPenalty\",\n \"minP\",\n \"topA\",\n \"stop\",\n \"logitBias\",\n \"topLogprobs\",\n \"user\",\n \"transforms\",\n \"models\",\n \"route\",\n \"provider\",\n \"plugins\",\n \"prediction\",\n ];\n }\n\n /** Model identifier, e.g. `\"anthropic/claude-4-sonnet\"`. */\n model: string;\n\n /** OpenRouter API key. Falls back to the `OPENROUTER_API_KEY` env var. */\n apiKey: string;\n\n /** Base URL for the API. Defaults to `\"https://openrouter.ai/api/v1\"`. */\n baseURL: string;\n\n /** Sampling temperature (0–2). */\n temperature?: number;\n\n /** Maximum number of tokens to generate. */\n maxTokens?: number;\n\n /** Nucleus sampling cutoff probability. */\n topP?: number;\n\n /** Top-K sampling: only consider the K most likely tokens. */\n topK?: number;\n\n /** Additive penalty based on how often a token has appeared so far (−2 to 2). */\n frequencyPenalty?: number;\n\n /** Additive penalty based on whether a token has appeared at all (−2 to 2). */\n presencePenalty?: number;\n\n /** Multiplicative penalty applied to repeated token logits (0 to 2). */\n repetitionPenalty?: number;\n\n /** Minimum probability threshold for token sampling. */\n minP?: number;\n\n /** Top-A sampling threshold. */\n topA?: number;\n\n /** Random seed for deterministic generation. */\n seed?: number;\n\n /** Stop sequences that halt generation. */\n stop?: string[];\n\n /** Token-level biases to apply during sampling. */\n logitBias?: Record<string, number>;\n\n /** Number of most-likely log-probabilities to return per token. */\n topLogprobs?: number;\n\n /** Stable identifier for end-users, used for abuse detection. */\n user?: string;\n\n /** OpenRouter-specific transformations to apply to the request. */\n transforms?: string[];\n\n /** OpenRouter-specific list of models for routing. */\n models?: string[];\n\n /** OpenRouter-specific routing strategy. */\n route?: \"fallback\";\n\n /** OpenRouter-specific provider preferences and ordering. */\n provider?: OpenRouter.ProviderPreferences;\n\n /** OpenRouter plugins to enable (e.g. web search). */\n plugins?: ChatOpenRouterParams[\"plugins\"];\n\n /**\n * Application URL for OpenRouter attribution. Maps to `HTTP-Referer` header.\n *\n * See https://openrouter.ai/docs/app-attribution for details.\n */\n siteUrl: string;\n\n /**\n * Application title for OpenRouter attribution. Maps to `X-Title` header.\n *\n * See https://openrouter.ai/docs/app-attribution for details.\n */\n siteName: string;\n\n /** Extra params passed through to the API body. */\n modelKwargs?: Record<string, unknown>;\n\n /** Whether to include token usage in streaming chunks. Defaults to `true`. */\n streamUsage: boolean;\n\n constructor(fields: ChatOpenRouterParams) {\n super(fields);\n const apiKey =\n fields.apiKey ?? getEnvironmentVariable(\"OPENROUTER_API_KEY\");\n if (!apiKey) {\n throw new OpenRouterAuthError(\n \"OpenRouter API key is required. Get one at https://openrouter.ai/keys and set it via the `apiKey` parameter or the OPENROUTER_API_KEY environment variable.\"\n );\n }\n this.apiKey = apiKey;\n if (!fields.model) {\n throw new Error(\n 'ChatOpenRouter requires a `model` parameter, e.g. \"openai/gpt-4o-mini\".'\n );\n }\n this.model = fields.model;\n this.baseURL = fields.baseURL ?? DEFAULT_BASE_URL;\n this.temperature = fields.temperature;\n this.maxTokens = fields.maxTokens;\n this.topP = fields.topP;\n this.topK = fields.topK;\n this.frequencyPenalty = fields.frequencyPenalty;\n this.presencePenalty = fields.presencePenalty;\n this.repetitionPenalty = fields.repetitionPenalty;\n this.minP = fields.minP;\n this.topA = fields.topA;\n this.seed = fields.seed;\n this.stop = fields.stop;\n this.logitBias = fields.logitBias;\n this.topLogprobs = fields.topLogprobs;\n this.user = fields.user;\n this.transforms = fields.transforms;\n this.models = fields.models;\n this.route = fields.route;\n this.provider = fields.provider;\n this.plugins = fields.plugins;\n this.siteUrl = fields.siteUrl ?? \"https://docs.langchain.com/oss\";\n this.siteName = fields.siteName ?? \"langchain\";\n this.modelKwargs = fields.modelKwargs;\n this.streamUsage = fields.streamUsage ?? true;\n }\n\n _llmType(): string {\n return \"openrouter\";\n }\n\n /** Static capability profile (context size, tool support, etc.) for the current model. */\n get profile(): ModelProfile {\n return PROFILES[this.model] ?? {};\n }\n\n /** Builds auth + content-type headers, plus optional site attribution headers. */\n private buildHeaders(): Record<string, string> {\n return {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n \"HTTP-Referer\": this.siteUrl,\n \"X-Title\": this.siteName,\n };\n }\n\n /** Returns the full chat-completions endpoint URL. */\n private buildUrl(): string {\n return `${this.baseURL}/chat/completions`;\n }\n\n /**\n * Merges constructor-level defaults with per-call overrides into the\n * API request body (everything except `messages`, which is added later).\n */\n override invocationParams(\n options: this[\"ParsedCallOptions\"]\n ): Omit<OpenRouterRequestBody, \"messages\"> {\n const tools = options.tools\n ? convertToolsToOpenRouter(options.tools, { strict: options.strict })\n : undefined;\n const toolChoice = formatToolChoice(options.tool_choice);\n\n return {\n model: this.model,\n temperature: options.temperature ?? this.temperature,\n max_tokens: options.maxTokens ?? this.maxTokens,\n top_p: options.topP ?? this.topP,\n top_k: options.topK ?? this.topK,\n frequency_penalty: options.frequencyPenalty ?? this.frequencyPenalty,\n presence_penalty: options.presencePenalty ?? this.presencePenalty,\n repetition_penalty: options.repetitionPenalty ?? this.repetitionPenalty,\n min_p: options.minP ?? this.minP,\n top_a: options.topA ?? this.topA,\n seed: options.seed ?? this.seed,\n stop: options.stop ?? this.stop,\n logit_bias: options.logitBias ?? this.logitBias,\n top_logprobs: options.topLogprobs ?? this.topLogprobs,\n user: options.user ?? this.user,\n tools,\n tool_choice: toolChoice,\n response_format: options.response_format,\n ...(options.prediction ? { prediction: options.prediction } : {}),\n transforms: options.transforms ?? this.transforms,\n models: options.models ?? this.models,\n route: options.route ?? this.route,\n provider: options.provider ?? this.provider,\n plugins: options.plugins ?? this.plugins,\n ...this.modelKwargs,\n };\n }\n\n /** Returns metadata for LangSmith tracing (provider, model name, temperature, etc.). */\n override getLsParams(options: this[\"ParsedCallOptions\"]): LangSmithParams {\n const params = this.invocationParams(options);\n return {\n ls_provider: \"openrouter\",\n ls_model_name: this.model,\n ls_model_type: \"chat\",\n ls_temperature: params.temperature ?? undefined,\n ls_max_tokens: params.max_tokens ?? undefined,\n ls_stop: options.stop,\n };\n }\n\n /**\n * Non-streaming generation. Sends a single request and returns the\n * complete response with the generated message and token usage.\n */\n async _generate(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n const body: OpenRouterRequestBody = {\n ...this.invocationParams(options),\n messages: convertMessagesToOpenRouterParams(messages, this.model),\n stream: false,\n };\n\n const response = await fetch(this.buildUrl(), {\n method: \"POST\",\n headers: this.buildHeaders(),\n body: JSON.stringify(body),\n signal: options.signal,\n });\n\n if (!response.ok) {\n throw await OpenRouterError.fromResponse(response);\n }\n\n const data: OpenRouter.ChatResponse = await response.json();\n const choice = data.choices[0];\n\n if (!choice) {\n throw new OpenRouterError(\"No choices returned in response.\");\n }\n\n const message = convertOpenRouterResponseToBaseMessage(choice, data);\n if (AIMessage.isInstance(message)) {\n message.usage_metadata = convertUsageMetadata(data.usage);\n }\n\n const text = typeof message.content === \"string\" ? message.content : \"\";\n\n await runManager?.handleLLMNewToken(text);\n\n return {\n generations: [\n {\n text,\n message,\n generationInfo: {\n finish_reason: choice.finish_reason,\n },\n },\n ],\n llmOutput: { tokenUsage: data.usage },\n };\n }\n\n /**\n * Streaming generation. Opens an SSE connection and yields one\n * `ChatGenerationChunk` per delta received from the API. The stream\n * pipeline is: raw bytes -> text -> SSE events -> JSON-parsed deltas.\n */\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const body: OpenRouterRequestBody = {\n ...this.invocationParams(options),\n messages: convertMessagesToOpenRouterParams(messages, this.model),\n stream: true,\n };\n\n const response = await fetch(this.buildUrl(), {\n method: \"POST\",\n headers: this.buildHeaders(),\n body: JSON.stringify(body),\n signal: options.signal,\n });\n\n if (!response.ok) {\n throw await OpenRouterError.fromResponse(response);\n }\n\n if (!response.body) {\n return;\n }\n\n const stream = response.body\n .pipeThrough(new TextDecoderStream())\n .pipeThrough(new EventSourceParserStream())\n .pipeThrough(new OpenRouterJsonParseStream());\n\n const reader = stream.getReader();\n let defaultRole: string | undefined;\n\n try {\n while (true) {\n const { done, value: data } = await reader.read();\n if (done) break;\n if (!data) continue;\n\n const choice = data.choices?.[0];\n if (!choice?.delta) continue;\n\n const chunk = convertOpenRouterDeltaToBaseMessageChunk(\n choice.delta,\n data,\n defaultRole\n );\n defaultRole = choice.delta.role ?? defaultRole;\n\n if (\n data.usage &&\n this.streamUsage &&\n AIMessageChunk.isInstance(chunk)\n ) {\n chunk.usage_metadata = convertUsageMetadata(data.usage);\n }\n\n const text = typeof chunk.content === \"string\" ? chunk.content : \"\";\n\n const generationChunk = new ChatGenerationChunk({\n message: chunk,\n text,\n generationInfo: {\n ...(choice.finish_reason\n ? { finish_reason: choice.finish_reason }\n : {}),\n },\n });\n\n yield generationChunk;\n await runManager?.handleLLMNewToken(text);\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n /**\n * Returns a new Runnable with the given tools bound into every call.\n * Equivalent to `.withConfig({ tools, ...kwargs })`.\n */\n override bindTools(\n tools: BindToolsInput[],\n kwargs?: Partial<ChatOpenRouterCallOptions>\n ): Runnable<\n BaseLanguageModelInput,\n AIMessageChunk,\n ChatOpenRouterCallOptions\n > {\n return this.withConfig({\n ...kwargs,\n tools,\n } as Partial<ChatOpenRouterCallOptions>);\n }\n\n /**\n * Returns a Runnable that forces the model to produce output conforming\n * to `outputSchema` (a Zod schema or plain JSON Schema object).\n *\n * The extraction strategy (JSON Schema response format, function calling,\n * or JSON mode) is chosen automatically based on model capabilities —\n * see {@link resolveOpenRouterStructuredOutputMethod}. You can override\n * this via `config.method`.\n *\n * When `config.includeRaw` is `true` the returned object contains both\n * the raw `BaseMessage` and the parsed output, with a fallback that\n * sets `parsed: null` if the parser throws.\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 // 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 // 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 // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<boolean>\n ):\n | Runnable<BaseLanguageModelInput, RunOutput>\n | Runnable<BaseLanguageModelInput, { raw: BaseMessage; parsed: RunOutput }>;\n\n withStructuredOutput<\n RunOutput extends Record<string, unknown> = Record<string, unknown>\n >(\n outputSchema: InteropZodType<RunOutput> | Record<string, unknown>,\n config?: StructuredOutputMethodOptions<boolean>\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\n const method = resolveOpenRouterStructuredOutputMethod({\n model: this.model,\n method: config?.method,\n profile: this.profile,\n models: this.models,\n route: this.route,\n });\n\n const asJsonSchema = toJsonSchema(schema);\n\n if (method === \"jsonSchema\") {\n const schemaName = name ?? \"extract\";\n llm = this.withConfig({\n response_format: {\n type: \"json_schema\",\n json_schema: {\n name: schemaName,\n description: getSchemaDescription(schema),\n schema: asJsonSchema,\n strict: config?.strict,\n },\n },\n ls_structured_output_format: {\n kwargs: { method: \"json_schema\" },\n schema: {\n title: schemaName,\n description: getSchemaDescription(schema),\n ...asJsonSchema,\n },\n },\n } as Partial<ChatOpenRouterCallOptions>);\n\n outputParser = isInteropZodSchema(schema)\n ? StructuredOutputParser.fromZodSchema(schema)\n : new JsonOutputParser<RunOutput>();\n } else if (method === \"jsonMode\") {\n llm = this.withConfig({\n response_format: { type: \"json_object\" },\n ls_structured_output_format: {\n kwargs: { method: \"json_mode\" },\n schema: { title: name ?? \"extract\", ...asJsonSchema },\n },\n } as Partial<ChatOpenRouterCallOptions>);\n\n outputParser = isInteropZodSchema(schema)\n ? StructuredOutputParser.fromZodSchema(schema)\n : new JsonOutputParser<RunOutput>();\n } else {\n let functionName = name ?? \"extract\";\n if (\"name\" in (schema as Record<string, unknown>)) {\n functionName = (schema as Record<string, unknown>).name as string;\n }\n\n llm = this.withConfig({\n tools: [\n {\n type: \"function\" as const,\n function: {\n name: functionName,\n description: getSchemaDescription(schema) ?? \"\",\n parameters: asJsonSchema,\n },\n },\n ],\n tool_choice: {\n type: \"function\" as const,\n function: { name: functionName },\n },\n ls_structured_output_format: {\n kwargs: { method: \"function_calling\" },\n schema: { title: functionName, ...asJsonSchema },\n },\n ...(config?.strict !== undefined ? { strict: config.strict } : {}),\n } as Partial<ChatOpenRouterCallOptions>);\n\n outputParser = isInteropZodSchema(schema)\n ? new JsonOutputKeyToolsParser({\n returnSingle: true,\n keyName: functionName,\n zodSchema: schema,\n })\n : new JsonOutputKeyToolsParser<RunOutput>({\n returnSingle: true,\n keyName: functionName,\n });\n }\n\n if (!includeRaw) {\n return llm.pipe(outputParser).withConfig({\n runName: \"ChatOpenRouterStructuredOutput\",\n }) as Runnable<BaseLanguageModelInput, RunOutput>;\n }\n\n const parserAssign = RunnablePassthrough.assign({\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n parsed: (input: any, config) => outputParser.invoke(input.raw, config),\n });\n const parserNone = RunnablePassthrough.assign({\n parsed: () => null,\n });\n const parsedWithFallback = parserAssign.withFallbacks({\n fallbacks: [parserNone],\n });\n return RunnableSequence.from<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n >([{ raw: llm }, parsedWithFallback]).withConfig({\n runName: \"ChatOpenRouterStructuredOutput\",\n });\n }\n}\n"],"mappings":"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"}
@@ -93,10 +93,18 @@ declare class ChatOpenRouter extends BaseChatModel<ChatOpenRouterCallOptions, AI
93
93
  provider?: OpenRouter.ProviderPreferences;
94
94
  /** OpenRouter plugins to enable (e.g. web search). */
95
95
  plugins?: ChatOpenRouterParams["plugins"];
96
- /** Your site URL — used for rankings on openrouter.ai. */
97
- siteUrl?: string;
98
- /** Your site/app name — used for rankings on openrouter.ai. */
99
- siteName?: string;
96
+ /**
97
+ * Application URL for OpenRouter attribution. Maps to `HTTP-Referer` header.
98
+ *
99
+ * See https://openrouter.ai/docs/app-attribution for details.
100
+ */
101
+ siteUrl: string;
102
+ /**
103
+ * Application title for OpenRouter attribution. Maps to `X-Title` header.
104
+ *
105
+ * See https://openrouter.ai/docs/app-attribution for details.
106
+ */
107
+ siteName: string;
100
108
  /** Extra params passed through to the API body. */
101
109
  modelKwargs?: Record<string, unknown>;
102
110
  /** Whether to include token usage in streaming chunks. Defaults to `true`. */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/chat_models/index.ts"],"mappings":";;;;;;;;;;;;;;;AAyCkD;;;;;KAS7C,qBAAA,GAAwB,IAAA,CAC3B,UAAA,CAAW,oBAAA;EAGX,QAAA,EAAU,MAAA,CAAa,IAAA,CAAK,WAAA,CAAY,0BAAA;EACxC,KAAA;EACA,kBAAA;EACA,KAAA;EACA,KAAA;EACA,UAAA;IAAe,IAAA;IAAiB,OAAA;EAAA;EAChC,UAAA;AAAA;;;;;;;;;cA2BW,cAAA,SAAuB,aAAA,CAClC,yBAAA,EACA,cAAA;EAAA,OAEO,OAAA,CAAA;EAIP,eAAA;EAR0B;EAAA,IAWtB,UAAA,CAAA;IAAA,CAAiB,GAAA;EAAA;EAuFT;EAAA,IAhFR,UAAA,CAAA,GAAc,MAAA;EAqGR;EAAA,IA9FN,QAAA,CAAA;EA4GgB;EA7EpB,KAAA;EAqJQ;EAlJR,MAAA;EAsL0D;EAnL1D,OAAA;EAsMe;EAnMf,WAAA;EAoMG;EAjMH,SAAA;EAyPe;EAtPf,IAAA;EAuPG;EApPH,IAAA;EAoUmB;EAjUnB,gBAAA;EAmUE;EAhUF,eAAA;EAkUE;EA/TF,iBAAA;EAsVoB;EAnVpB,IAAA;EAsVqB;EAnVrB,IAAA;EAqVM;EAlVN,IAAA;EAoVY;EAjVZ,IAAA;EAiVG;EA9UH,SAAA,GAAY,MAAA;EAkV8B;EA/U1C,WAAA;EAkVM;EA/UN,IAAA;EAkVW;EA/UX,UAAA;EAgV2C;EA7U3C,MAAA;EA6UG;EA1UH,KAAA;EA8U0C;EA3U1C,QAAA,GAAW,UAAA,CAAW,mBAAA;EA8UhB;EA3UN,OAAA,GAAU,oBAAA;EA8UC;EA3UX,OAAA;EA6UqC;EA1UrC,QAAA;EA2Ua;EAxUb,WAAA,GAAc,MAAA;EAwUmD;EArUjE,WAAA;EAEA,WAAA,CAAY,MAAA,EAAQ,oBAAA;EA0CpB,QAAA,CAAA;EA/K+C;EAAA,IAoL3C,OAAA,CAAA,GAAW,YAAA;EAnLf;EAAA,QAwLQ,YAAA;EArLD;EAAA,QA+LC,QAAA;EAxLJ;;;;EAgMK,gBAAA,CACP,OAAA,8BACC,IAAA,CAAK,qBAAA;EArJR;EAyLS,WAAA,CAAY,OAAA,8BAAqC,eAAA;EAnL1D;;;;EAmMM,SAAA,CACJ,QAAA,EAAU,WAAA,IACV,OAAA,6BACA,UAAA,GAAa,wBAAA,GACZ,OAAA,CAAQ,UAAA;EAxLX;;;;;EA6OO,qBAAA,CACL,QAAA,EAAU,WAAA,IACV,OAAA,6BACA,UAAA,GAAa,wBAAA,GACZ,cAAA,CAAe,mBAAA;EA/NlB;;;;EA6SS,SAAA,CACP,KAAA,EAAO,cAAA,IACP,MAAA,GAAS,OAAA,CAAQ,yBAAA,IAChB,QAAA,CACD,sBAAA,EACA,cAAA,EACA,yBAAA;EAvSF;;;;;;;;;;;;;EA4TA,oBAAA,mBAEoB,MAAA,gBAAsB,MAAA,cAAA,CAExC,YAAA,EACI,cAAA,CAAe,SAAA,IAEf,MAAA,eACJ,MAAA,GAAS,6BAAA,UACR,QAAA,CAAS,sBAAA,EAAwB,SAAA;EAEpC,oBAAA,mBAEoB,MAAA,gBAAsB,MAAA,cAAA,CAExC,YAAA,EACI,cAAA,CAAe,SAAA,IAEf,MAAA,eACJ,MAAA,GAAS,6BAAA,SACR,QAAA,CAAS,sBAAA;IAA0B,GAAA,EAAK,WAAA;IAAa,MAAA,EAAQ,SAAA;EAAA;EAEhE,oBAAA,mBAEoB,MAAA,gBAAsB,MAAA,cAAA,CAExC,YAAA,EACI,cAAA,CAAe,SAAA,IAEf,MAAA,eACJ,MAAA,GAAS,6BAAA,YAEP,QAAA,CAAS,sBAAA,EAAwB,SAAA,IACjC,QAAA,CAAS,sBAAA;IAA0B,GAAA,EAAK,WAAA;IAAa,MAAA,EAAQ,SAAA;EAAA;AAAA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/chat_models/index.ts"],"mappings":";;;;;;;;;;;;;;;AAyCkD;;;;;KAS7C,qBAAA,GAAwB,IAAA,CAC3B,UAAA,CAAW,oBAAA;EAGX,QAAA,EAAU,MAAA,CAAa,IAAA,CAAK,WAAA,CAAY,0BAAA;EACxC,KAAA;EACA,kBAAA;EACA,KAAA;EACA,KAAA;EACA,UAAA;IAAe,IAAA;IAAiB,OAAA;EAAA;EAChC,UAAA;AAAA;;;;;;;;;cA2BW,cAAA,SAAuB,aAAA,CAClC,yBAAA,EACA,cAAA;EAAA,OAEO,OAAA,CAAA;EAIP,eAAA;EAR0B;EAAA,IAWtB,UAAA,CAAA;IAAA,CAAiB,GAAA;EAAA;EAuFT;EAAA,IAhFR,UAAA,CAAA,GAAc,MAAA;EAqGR;EAAA,IA9FN,QAAA,CAAA;EAoHgB;EArFpB,KAAA;EA6JQ;EA1JR,MAAA;EA8L0D;EA3L1D,OAAA;EA8Me;EA3Mf,WAAA;EA4MG;EAzMH,SAAA;EAiQe;EA9Pf,IAAA;EA+PG;EA5PH,IAAA;EA4UmB;EAzUnB,gBAAA;EA2UE;EAxUF,eAAA;EA0UE;EAvUF,iBAAA;EA8VoB;EA3VpB,IAAA;EA8VqB;EA3VrB,IAAA;EA6VM;EA1VN,IAAA;EA4VY;EAzVZ,IAAA;EAyVG;EAtVH,SAAA,GAAY,MAAA;EA0V8B;EAvV1C,WAAA;EA0VM;EAvVN,IAAA;EA0VW;EAvVX,UAAA;EAwV2C;EArV3C,MAAA;EAqVG;EAlVH,KAAA;EAsV0C;EAnV1C,QAAA,GAAW,UAAA,CAAW,mBAAA;EAsVhB;EAnVN,OAAA,GAAU,oBAAA;EAsVC;;;;;EA/UX,OAAA;EAkViE;;;;;EA3UjE,QAAA;EApIA;EAuIA,WAAA,GAAc,MAAA;EApIP;EAuIP,WAAA;EAEA,WAAA,CAAY,MAAA,EAAQ,oBAAA;EA0CpB,QAAA,CAAA;EArKI;EAAA,IA0KA,OAAA,CAAA,GAAW,YAAA;EAnKX;EAAA,QAwKI,YAAA;EAtIR;EAAA,QAgJQ,QAAA;EA1IR;;;;EAkJS,gBAAA,CACP,OAAA,8BACC,IAAA,CAAK,qBAAA;EArIR;EAyKS,WAAA,CAAY,OAAA,8BAAqC,eAAA;EAnK1D;;;;EAmLM,SAAA,CACJ,QAAA,EAAU,WAAA,IACV,OAAA,6BACA,UAAA,GAAa,wBAAA,GACZ,OAAA,CAAQ,UAAA;EA3KC;;;;;EAgOL,qBAAA,CACL,QAAA,EAAU,WAAA,IACV,OAAA,6BACA,UAAA,GAAa,wBAAA,GACZ,cAAA,CAAe,mBAAA;EAlNlB;;;;EAgSS,SAAA,CACP,KAAA,EAAO,cAAA,IACP,MAAA,GAAS,OAAA,CAAQ,yBAAA,IAChB,QAAA,CACD,sBAAA,EACA,cAAA,EACA,yBAAA;EA5RF;;;;;;;;;;;;;EAiTA,oBAAA,mBAEoB,MAAA,gBAAsB,MAAA,cAAA,CAExC,YAAA,EACI,cAAA,CAAe,SAAA,IAEf,MAAA,eACJ,MAAA,GAAS,6BAAA,UACR,QAAA,CAAS,sBAAA,EAAwB,SAAA;EAEpC,oBAAA,mBAEoB,MAAA,gBAAsB,MAAA,cAAA,CAExC,YAAA,EACI,cAAA,CAAe,SAAA,IAEf,MAAA,eACJ,MAAA,GAAS,6BAAA,SACR,QAAA,CAAS,sBAAA;IAA0B,GAAA,EAAK,WAAA;IAAa,MAAA,EAAQ,SAAA;EAAA;EAEhE,oBAAA,mBAEoB,MAAA,gBAAsB,MAAA,cAAA,CAExC,YAAA,EACI,cAAA,CAAe,SAAA,IAEf,MAAA,eACJ,MAAA,GAAS,6BAAA,YAEP,QAAA,CAAS,sBAAA,EAAwB,SAAA,IACjC,QAAA,CAAS,sBAAA;IAA0B,GAAA,EAAK,WAAA;IAAa,MAAA,EAAQ,SAAA;EAAA;AAAA"}
@@ -93,10 +93,18 @@ declare class ChatOpenRouter extends BaseChatModel<ChatOpenRouterCallOptions, AI
93
93
  provider?: OpenRouter.ProviderPreferences;
94
94
  /** OpenRouter plugins to enable (e.g. web search). */
95
95
  plugins?: ChatOpenRouterParams["plugins"];
96
- /** Your site URL — used for rankings on openrouter.ai. */
97
- siteUrl?: string;
98
- /** Your site/app name — used for rankings on openrouter.ai. */
99
- siteName?: string;
96
+ /**
97
+ * Application URL for OpenRouter attribution. Maps to `HTTP-Referer` header.
98
+ *
99
+ * See https://openrouter.ai/docs/app-attribution for details.
100
+ */
101
+ siteUrl: string;
102
+ /**
103
+ * Application title for OpenRouter attribution. Maps to `X-Title` header.
104
+ *
105
+ * See https://openrouter.ai/docs/app-attribution for details.
106
+ */
107
+ siteName: string;
100
108
  /** Extra params passed through to the API body. */
101
109
  modelKwargs?: Record<string, unknown>;
102
110
  /** Whether to include token usage in streaming chunks. Defaults to `true`. */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/chat_models/index.ts"],"mappings":";;;;;;;;;;;;;;;AAyCkD;;;;;KAS7C,qBAAA,GAAwB,IAAA,CAC3B,UAAA,CAAW,oBAAA;EAGX,QAAA,EAAU,MAAA,CAAa,IAAA,CAAK,WAAA,CAAY,0BAAA;EACxC,KAAA;EACA,kBAAA;EACA,KAAA;EACA,KAAA;EACA,UAAA;IAAe,IAAA;IAAiB,OAAA;EAAA;EAChC,UAAA;AAAA;;;;;;;;;cA2BW,cAAA,SAAuB,aAAA,CAClC,yBAAA,EACA,cAAA;EAAA,OAEO,OAAA,CAAA;EAIP,eAAA;EAR0B;EAAA,IAWtB,UAAA,CAAA;IAAA,CAAiB,GAAA;EAAA;EAuFT;EAAA,IAhFR,UAAA,CAAA,GAAc,MAAA;EAqGR;EAAA,IA9FN,QAAA,CAAA;EA4GgB;EA7EpB,KAAA;EAqJQ;EAlJR,MAAA;EAsL0D;EAnL1D,OAAA;EAsMe;EAnMf,WAAA;EAoMG;EAjMH,SAAA;EAyPe;EAtPf,IAAA;EAuPG;EApPH,IAAA;EAoUmB;EAjUnB,gBAAA;EAmUE;EAhUF,eAAA;EAkUE;EA/TF,iBAAA;EAsVoB;EAnVpB,IAAA;EAsVqB;EAnVrB,IAAA;EAqVM;EAlVN,IAAA;EAoVY;EAjVZ,IAAA;EAiVG;EA9UH,SAAA,GAAY,MAAA;EAkV8B;EA/U1C,WAAA;EAkVM;EA/UN,IAAA;EAkVW;EA/UX,UAAA;EAgV2C;EA7U3C,MAAA;EA6UG;EA1UH,KAAA;EA8U0C;EA3U1C,QAAA,GAAW,UAAA,CAAW,mBAAA;EA8UhB;EA3UN,OAAA,GAAU,oBAAA;EA8UC;EA3UX,OAAA;EA6UqC;EA1UrC,QAAA;EA2Ua;EAxUb,WAAA,GAAc,MAAA;EAwUmD;EArUjE,WAAA;EAEA,WAAA,CAAY,MAAA,EAAQ,oBAAA;EA0CpB,QAAA,CAAA;EA/K+C;EAAA,IAoL3C,OAAA,CAAA,GAAW,YAAA;EAnLf;EAAA,QAwLQ,YAAA;EArLD;EAAA,QA+LC,QAAA;EAxLJ;;;;EAgMK,gBAAA,CACP,OAAA,8BACC,IAAA,CAAK,qBAAA;EArJR;EAyLS,WAAA,CAAY,OAAA,8BAAqC,eAAA;EAnL1D;;;;EAmMM,SAAA,CACJ,QAAA,EAAU,WAAA,IACV,OAAA,6BACA,UAAA,GAAa,wBAAA,GACZ,OAAA,CAAQ,UAAA;EAxLX;;;;;EA6OO,qBAAA,CACL,QAAA,EAAU,WAAA,IACV,OAAA,6BACA,UAAA,GAAa,wBAAA,GACZ,cAAA,CAAe,mBAAA;EA/NlB;;;;EA6SS,SAAA,CACP,KAAA,EAAO,cAAA,IACP,MAAA,GAAS,OAAA,CAAQ,yBAAA,IAChB,QAAA,CACD,sBAAA,EACA,cAAA,EACA,yBAAA;EAvSF;;;;;;;;;;;;;EA4TA,oBAAA,mBAEoB,MAAA,gBAAsB,MAAA,cAAA,CAExC,YAAA,EACI,cAAA,CAAe,SAAA,IAEf,MAAA,eACJ,MAAA,GAAS,6BAAA,UACR,QAAA,CAAS,sBAAA,EAAwB,SAAA;EAEpC,oBAAA,mBAEoB,MAAA,gBAAsB,MAAA,cAAA,CAExC,YAAA,EACI,cAAA,CAAe,SAAA,IAEf,MAAA,eACJ,MAAA,GAAS,6BAAA,SACR,QAAA,CAAS,sBAAA;IAA0B,GAAA,EAAK,WAAA;IAAa,MAAA,EAAQ,SAAA;EAAA;EAEhE,oBAAA,mBAEoB,MAAA,gBAAsB,MAAA,cAAA,CAExC,YAAA,EACI,cAAA,CAAe,SAAA,IAEf,MAAA,eACJ,MAAA,GAAS,6BAAA,YAEP,QAAA,CAAS,sBAAA,EAAwB,SAAA,IACjC,QAAA,CAAS,sBAAA;IAA0B,GAAA,EAAK,WAAA;IAAa,MAAA,EAAQ,SAAA;EAAA;AAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/chat_models/index.ts"],"mappings":";;;;;;;;;;;;;;;AAyCkD;;;;;KAS7C,qBAAA,GAAwB,IAAA,CAC3B,UAAA,CAAW,oBAAA;EAGX,QAAA,EAAU,MAAA,CAAa,IAAA,CAAK,WAAA,CAAY,0BAAA;EACxC,KAAA;EACA,kBAAA;EACA,KAAA;EACA,KAAA;EACA,UAAA;IAAe,IAAA;IAAiB,OAAA;EAAA;EAChC,UAAA;AAAA;;;;;;;;;cA2BW,cAAA,SAAuB,aAAA,CAClC,yBAAA,EACA,cAAA;EAAA,OAEO,OAAA,CAAA;EAIP,eAAA;EAR0B;EAAA,IAWtB,UAAA,CAAA;IAAA,CAAiB,GAAA;EAAA;EAuFT;EAAA,IAhFR,UAAA,CAAA,GAAc,MAAA;EAqGR;EAAA,IA9FN,QAAA,CAAA;EAoHgB;EArFpB,KAAA;EA6JQ;EA1JR,MAAA;EA8L0D;EA3L1D,OAAA;EA8Me;EA3Mf,WAAA;EA4MG;EAzMH,SAAA;EAiQe;EA9Pf,IAAA;EA+PG;EA5PH,IAAA;EA4UmB;EAzUnB,gBAAA;EA2UE;EAxUF,eAAA;EA0UE;EAvUF,iBAAA;EA8VoB;EA3VpB,IAAA;EA8VqB;EA3VrB,IAAA;EA6VM;EA1VN,IAAA;EA4VY;EAzVZ,IAAA;EAyVG;EAtVH,SAAA,GAAY,MAAA;EA0V8B;EAvV1C,WAAA;EA0VM;EAvVN,IAAA;EA0VW;EAvVX,UAAA;EAwV2C;EArV3C,MAAA;EAqVG;EAlVH,KAAA;EAsV0C;EAnV1C,QAAA,GAAW,UAAA,CAAW,mBAAA;EAsVhB;EAnVN,OAAA,GAAU,oBAAA;EAsVC;;;;;EA/UX,OAAA;EAkViE;;;;;EA3UjE,QAAA;EApIA;EAuIA,WAAA,GAAc,MAAA;EApIP;EAuIP,WAAA;EAEA,WAAA,CAAY,MAAA,EAAQ,oBAAA;EA0CpB,QAAA,CAAA;EArKI;EAAA,IA0KA,OAAA,CAAA,GAAW,YAAA;EAnKX;EAAA,QAwKI,YAAA;EAtIR;EAAA,QAgJQ,QAAA;EA1IR;;;;EAkJS,gBAAA,CACP,OAAA,8BACC,IAAA,CAAK,qBAAA;EArIR;EAyKS,WAAA,CAAY,OAAA,8BAAqC,eAAA;EAnK1D;;;;EAmLM,SAAA,CACJ,QAAA,EAAU,WAAA,IACV,OAAA,6BACA,UAAA,GAAa,wBAAA,GACZ,OAAA,CAAQ,UAAA;EA3KC;;;;;EAgOL,qBAAA,CACL,QAAA,EAAU,WAAA,IACV,OAAA,6BACA,UAAA,GAAa,wBAAA,GACZ,cAAA,CAAe,mBAAA;EAlNlB;;;;EAgSS,SAAA,CACP,KAAA,EAAO,cAAA,IACP,MAAA,GAAS,OAAA,CAAQ,yBAAA,IAChB,QAAA,CACD,sBAAA,EACA,cAAA,EACA,yBAAA;EA5RF;;;;;;;;;;;;;EAiTA,oBAAA,mBAEoB,MAAA,gBAAsB,MAAA,cAAA,CAExC,YAAA,EACI,cAAA,CAAe,SAAA,IAEf,MAAA,eACJ,MAAA,GAAS,6BAAA,UACR,QAAA,CAAS,sBAAA,EAAwB,SAAA;EAEpC,oBAAA,mBAEoB,MAAA,gBAAsB,MAAA,cAAA,CAExC,YAAA,EACI,cAAA,CAAe,SAAA,IAEf,MAAA,eACJ,MAAA,GAAS,6BAAA,SACR,QAAA,CAAS,sBAAA;IAA0B,GAAA,EAAK,WAAA;IAAa,MAAA,EAAQ,SAAA;EAAA;EAEhE,oBAAA,mBAEoB,MAAA,gBAAsB,MAAA,cAAA,CAExC,YAAA,EACI,cAAA,CAAe,SAAA,IAEf,MAAA,eACJ,MAAA,GAAS,6BAAA,YAEP,QAAA,CAAS,sBAAA,EAAwB,SAAA,IACjC,QAAA,CAAS,sBAAA;IAA0B,GAAA,EAAK,WAAA;IAAa,MAAA,EAAQ,SAAA;EAAA;AAAA"}
@@ -112,9 +112,17 @@ var ChatOpenRouter = class extends BaseChatModel {
112
112
  provider;
113
113
  /** OpenRouter plugins to enable (e.g. web search). */
114
114
  plugins;
115
- /** Your site URL — used for rankings on openrouter.ai. */
115
+ /**
116
+ * Application URL for OpenRouter attribution. Maps to `HTTP-Referer` header.
117
+ *
118
+ * See https://openrouter.ai/docs/app-attribution for details.
119
+ */
116
120
  siteUrl;
117
- /** Your site/app name — used for rankings on openrouter.ai. */
121
+ /**
122
+ * Application title for OpenRouter attribution. Maps to `X-Title` header.
123
+ *
124
+ * See https://openrouter.ai/docs/app-attribution for details.
125
+ */
118
126
  siteName;
119
127
  /** Extra params passed through to the API body. */
120
128
  modelKwargs;
@@ -147,8 +155,8 @@ var ChatOpenRouter = class extends BaseChatModel {
147
155
  this.route = fields.route;
148
156
  this.provider = fields.provider;
149
157
  this.plugins = fields.plugins;
150
- this.siteUrl = fields.siteUrl;
151
- this.siteName = fields.siteName;
158
+ this.siteUrl = fields.siteUrl ?? "https://docs.langchain.com/oss";
159
+ this.siteName = fields.siteName ?? "langchain";
152
160
  this.modelKwargs = fields.modelKwargs;
153
161
  this.streamUsage = fields.streamUsage ?? true;
154
162
  }
@@ -164,8 +172,8 @@ var ChatOpenRouter = class extends BaseChatModel {
164
172
  return {
165
173
  Authorization: `Bearer ${this.apiKey}`,
166
174
  "Content-Type": "application/json",
167
- ...this.siteUrl ? { "HTTP-Referer": this.siteUrl } : {},
168
- ...this.siteName ? { "X-Title": this.siteName } : {}
175
+ "HTTP-Referer": this.siteUrl,
176
+ "X-Title": this.siteName
169
177
  };
170
178
  }
171
179
  /** Returns the full chat-completions endpoint URL. */
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/chat_models/index.ts"],"sourcesContent":["import {\n BaseChatModel,\n type BindToolsInput,\n type LangSmithParams,\n} from \"@langchain/core/language_models/chat_models\";\nimport type { ModelProfile } from \"@langchain/core/language_models/profile\";\nimport type {\n BaseLanguageModelInput,\n StructuredOutputMethodOptions,\n} from \"@langchain/core/language_models/base\";\nimport {\n AIMessage,\n AIMessageChunk,\n BaseMessage,\n} from \"@langchain/core/messages\";\nimport { ChatGenerationChunk, type ChatResult } from \"@langchain/core/outputs\";\nimport type { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport {\n Runnable,\n RunnablePassthrough,\n RunnableSequence,\n} from \"@langchain/core/runnables\";\nimport { toJsonSchema } from \"@langchain/core/utils/json_schema\";\nimport {\n type InteropZodType,\n isInteropZodSchema,\n getSchemaDescription,\n} from \"@langchain/core/utils/types\";\nimport {\n JsonOutputParser,\n StructuredOutputParser,\n} from \"@langchain/core/output_parsers\";\nimport { JsonOutputKeyToolsParser } from \"@langchain/core/output_parsers/openai_tools\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport { EventSourceParserStream } from \"eventsource-parser/stream\";\n\nimport type {\n ChatOpenRouterParams,\n ChatOpenRouterCallOptions,\n} from \"./types.js\";\nimport type { OpenAI as OpenAIClient } from \"openai\";\nimport type { OpenRouter } from \"../api-types.js\";\n\n/**\n * Full request body sent to the OpenRouter `/chat/completions` endpoint.\n *\n * Extends the base generation params with OpenRouter-specific sampling\n * knobs (`top_k`, `min_p`, etc.) and features (`prediction`, `transforms`)\n * that aren't part of the standard OpenAI spec.\n */\ntype OpenRouterRequestBody = Omit<\n OpenRouter.ChatGenerationParams,\n \"messages\"\n> & {\n messages: OpenAIClient.Chat.Completions.ChatCompletionMessageParam[];\n top_k?: number | null;\n repetition_penalty?: number | null;\n min_p?: number | null;\n top_a?: number | null;\n prediction?: { type: \"content\"; content: string };\n transforms?: string[];\n};\nimport {\n convertMessagesToOpenRouterParams,\n convertOpenRouterResponseToBaseMessage,\n convertOpenRouterDeltaToBaseMessageChunk,\n convertUsageMetadata,\n} from \"../converters/messages.js\";\nimport {\n convertToolsToOpenRouter,\n formatToolChoice,\n} from \"../converters/tools.js\";\nimport { OpenRouterError, OpenRouterAuthError } from \"../utils/errors.js\";\nimport { resolveOpenRouterStructuredOutputMethod } from \"../utils/structured_output.js\";\nimport { OpenRouterJsonParseStream } from \"../utils/stream.js\";\nimport PROFILES from \"../profiles.js\";\n\nconst DEFAULT_BASE_URL = \"https://openrouter.ai/api/v1\";\n\n/**\n * OpenRouter chat model integration.\n *\n * Talks directly to the OpenRouter REST API via `fetch` (no SDK dependency)\n * and supports tool calling, structured output, and streaming. Any model\n * available on OpenRouter can be used by passing its identifier (e.g.\n * `\"anthropic/claude-4-sonnet\"`) as the `model` param.\n */\nexport class ChatOpenRouter extends BaseChatModel<\n ChatOpenRouterCallOptions,\n AIMessageChunk\n> {\n static lc_name() {\n return \"ChatOpenRouter\";\n }\n\n lc_serializable = true;\n\n /** Maps secret fields to the environment variable they can be loaded from. */\n get lc_secrets(): { [key: string]: string } | undefined {\n return {\n apiKey: \"OPENROUTER_API_KEY\",\n };\n }\n\n /** Allows serialized JSON to use `modelName` as an alias for `model`. */\n get lc_aliases(): Record<string, string> {\n return {\n modelName: \"model\",\n };\n }\n\n /** Fields that may be overridden per-call via `.bind()` / `.withConfig()`. */\n get callKeys(): string[] {\n return [\n ...super.callKeys,\n \"tools\",\n \"tool_choice\",\n \"response_format\",\n \"seed\",\n \"strict\",\n \"temperature\",\n \"maxTokens\",\n \"topP\",\n \"topK\",\n \"frequencyPenalty\",\n \"presencePenalty\",\n \"repetitionPenalty\",\n \"minP\",\n \"topA\",\n \"stop\",\n \"logitBias\",\n \"topLogprobs\",\n \"user\",\n \"transforms\",\n \"models\",\n \"route\",\n \"provider\",\n \"plugins\",\n \"prediction\",\n ];\n }\n\n /** Model identifier, e.g. `\"anthropic/claude-4-sonnet\"`. */\n model: string;\n\n /** OpenRouter API key. Falls back to the `OPENROUTER_API_KEY` env var. */\n apiKey: string;\n\n /** Base URL for the API. Defaults to `\"https://openrouter.ai/api/v1\"`. */\n baseURL: string;\n\n /** Sampling temperature (0–2). */\n temperature?: number;\n\n /** Maximum number of tokens to generate. */\n maxTokens?: number;\n\n /** Nucleus sampling cutoff probability. */\n topP?: number;\n\n /** Top-K sampling: only consider the K most likely tokens. */\n topK?: number;\n\n /** Additive penalty based on how often a token has appeared so far (−2 to 2). */\n frequencyPenalty?: number;\n\n /** Additive penalty based on whether a token has appeared at all (−2 to 2). */\n presencePenalty?: number;\n\n /** Multiplicative penalty applied to repeated token logits (0 to 2). */\n repetitionPenalty?: number;\n\n /** Minimum probability threshold for token sampling. */\n minP?: number;\n\n /** Top-A sampling threshold. */\n topA?: number;\n\n /** Random seed for deterministic generation. */\n seed?: number;\n\n /** Stop sequences that halt generation. */\n stop?: string[];\n\n /** Token-level biases to apply during sampling. */\n logitBias?: Record<string, number>;\n\n /** Number of most-likely log-probabilities to return per token. */\n topLogprobs?: number;\n\n /** Stable identifier for end-users, used for abuse detection. */\n user?: string;\n\n /** OpenRouter-specific transformations to apply to the request. */\n transforms?: string[];\n\n /** OpenRouter-specific list of models for routing. */\n models?: string[];\n\n /** OpenRouter-specific routing strategy. */\n route?: \"fallback\";\n\n /** OpenRouter-specific provider preferences and ordering. */\n provider?: OpenRouter.ProviderPreferences;\n\n /** OpenRouter plugins to enable (e.g. web search). */\n plugins?: ChatOpenRouterParams[\"plugins\"];\n\n /** Your site URL — used for rankings on openrouter.ai. */\n siteUrl?: string;\n\n /** Your site/app name — used for rankings on openrouter.ai. */\n siteName?: string;\n\n /** Extra params passed through to the API body. */\n modelKwargs?: Record<string, unknown>;\n\n /** Whether to include token usage in streaming chunks. Defaults to `true`. */\n streamUsage: boolean;\n\n constructor(fields: ChatOpenRouterParams) {\n super(fields);\n const apiKey =\n fields.apiKey ?? getEnvironmentVariable(\"OPENROUTER_API_KEY\");\n if (!apiKey) {\n throw new OpenRouterAuthError(\n \"OpenRouter API key is required. Get one at https://openrouter.ai/keys and set it via the `apiKey` parameter or the OPENROUTER_API_KEY environment variable.\"\n );\n }\n this.apiKey = apiKey;\n if (!fields.model) {\n throw new Error(\n 'ChatOpenRouter requires a `model` parameter, e.g. \"openai/gpt-4o-mini\".'\n );\n }\n this.model = fields.model;\n this.baseURL = fields.baseURL ?? DEFAULT_BASE_URL;\n this.temperature = fields.temperature;\n this.maxTokens = fields.maxTokens;\n this.topP = fields.topP;\n this.topK = fields.topK;\n this.frequencyPenalty = fields.frequencyPenalty;\n this.presencePenalty = fields.presencePenalty;\n this.repetitionPenalty = fields.repetitionPenalty;\n this.minP = fields.minP;\n this.topA = fields.topA;\n this.seed = fields.seed;\n this.stop = fields.stop;\n this.logitBias = fields.logitBias;\n this.topLogprobs = fields.topLogprobs;\n this.user = fields.user;\n this.transforms = fields.transforms;\n this.models = fields.models;\n this.route = fields.route;\n this.provider = fields.provider;\n this.plugins = fields.plugins;\n this.siteUrl = fields.siteUrl;\n this.siteName = fields.siteName;\n this.modelKwargs = fields.modelKwargs;\n this.streamUsage = fields.streamUsage ?? true;\n }\n\n _llmType(): string {\n return \"openrouter\";\n }\n\n /** Static capability profile (context size, tool support, etc.) for the current model. */\n get profile(): ModelProfile {\n return PROFILES[this.model] ?? {};\n }\n\n /** Builds auth + content-type headers, plus optional site attribution headers. */\n private buildHeaders(): Record<string, string> {\n return {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n ...(this.siteUrl ? { \"HTTP-Referer\": this.siteUrl } : {}),\n ...(this.siteName ? { \"X-Title\": this.siteName } : {}),\n };\n }\n\n /** Returns the full chat-completions endpoint URL. */\n private buildUrl(): string {\n return `${this.baseURL}/chat/completions`;\n }\n\n /**\n * Merges constructor-level defaults with per-call overrides into the\n * API request body (everything except `messages`, which is added later).\n */\n override invocationParams(\n options: this[\"ParsedCallOptions\"]\n ): Omit<OpenRouterRequestBody, \"messages\"> {\n const tools = options.tools\n ? convertToolsToOpenRouter(options.tools, { strict: options.strict })\n : undefined;\n const toolChoice = formatToolChoice(options.tool_choice);\n\n return {\n model: this.model,\n temperature: options.temperature ?? this.temperature,\n max_tokens: options.maxTokens ?? this.maxTokens,\n top_p: options.topP ?? this.topP,\n top_k: options.topK ?? this.topK,\n frequency_penalty: options.frequencyPenalty ?? this.frequencyPenalty,\n presence_penalty: options.presencePenalty ?? this.presencePenalty,\n repetition_penalty: options.repetitionPenalty ?? this.repetitionPenalty,\n min_p: options.minP ?? this.minP,\n top_a: options.topA ?? this.topA,\n seed: options.seed ?? this.seed,\n stop: options.stop ?? this.stop,\n logit_bias: options.logitBias ?? this.logitBias,\n top_logprobs: options.topLogprobs ?? this.topLogprobs,\n user: options.user ?? this.user,\n tools,\n tool_choice: toolChoice,\n response_format: options.response_format,\n ...(options.prediction ? { prediction: options.prediction } : {}),\n transforms: options.transforms ?? this.transforms,\n models: options.models ?? this.models,\n route: options.route ?? this.route,\n provider: options.provider ?? this.provider,\n plugins: options.plugins ?? this.plugins,\n ...this.modelKwargs,\n };\n }\n\n /** Returns metadata for LangSmith tracing (provider, model name, temperature, etc.). */\n override getLsParams(options: this[\"ParsedCallOptions\"]): LangSmithParams {\n const params = this.invocationParams(options);\n return {\n ls_provider: \"openrouter\",\n ls_model_name: this.model,\n ls_model_type: \"chat\",\n ls_temperature: params.temperature ?? undefined,\n ls_max_tokens: params.max_tokens ?? undefined,\n ls_stop: options.stop,\n };\n }\n\n /**\n * Non-streaming generation. Sends a single request and returns the\n * complete response with the generated message and token usage.\n */\n async _generate(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n const body: OpenRouterRequestBody = {\n ...this.invocationParams(options),\n messages: convertMessagesToOpenRouterParams(messages, this.model),\n stream: false,\n };\n\n const response = await fetch(this.buildUrl(), {\n method: \"POST\",\n headers: this.buildHeaders(),\n body: JSON.stringify(body),\n signal: options.signal,\n });\n\n if (!response.ok) {\n throw await OpenRouterError.fromResponse(response);\n }\n\n const data: OpenRouter.ChatResponse = await response.json();\n const choice = data.choices[0];\n\n if (!choice) {\n throw new OpenRouterError(\"No choices returned in response.\");\n }\n\n const message = convertOpenRouterResponseToBaseMessage(choice, data);\n if (AIMessage.isInstance(message)) {\n message.usage_metadata = convertUsageMetadata(data.usage);\n }\n\n const text = typeof message.content === \"string\" ? message.content : \"\";\n\n await runManager?.handleLLMNewToken(text);\n\n return {\n generations: [\n {\n text,\n message,\n generationInfo: {\n finish_reason: choice.finish_reason,\n },\n },\n ],\n llmOutput: { tokenUsage: data.usage },\n };\n }\n\n /**\n * Streaming generation. Opens an SSE connection and yields one\n * `ChatGenerationChunk` per delta received from the API. The stream\n * pipeline is: raw bytes -> text -> SSE events -> JSON-parsed deltas.\n */\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const body: OpenRouterRequestBody = {\n ...this.invocationParams(options),\n messages: convertMessagesToOpenRouterParams(messages, this.model),\n stream: true,\n };\n\n const response = await fetch(this.buildUrl(), {\n method: \"POST\",\n headers: this.buildHeaders(),\n body: JSON.stringify(body),\n signal: options.signal,\n });\n\n if (!response.ok) {\n throw await OpenRouterError.fromResponse(response);\n }\n\n if (!response.body) {\n return;\n }\n\n const stream = response.body\n .pipeThrough(new TextDecoderStream())\n .pipeThrough(new EventSourceParserStream())\n .pipeThrough(new OpenRouterJsonParseStream());\n\n const reader = stream.getReader();\n let defaultRole: string | undefined;\n\n try {\n while (true) {\n const { done, value: data } = await reader.read();\n if (done) break;\n if (!data) continue;\n\n const choice = data.choices?.[0];\n if (!choice?.delta) continue;\n\n const chunk = convertOpenRouterDeltaToBaseMessageChunk(\n choice.delta,\n data,\n defaultRole\n );\n defaultRole = choice.delta.role ?? defaultRole;\n\n if (\n data.usage &&\n this.streamUsage &&\n AIMessageChunk.isInstance(chunk)\n ) {\n chunk.usage_metadata = convertUsageMetadata(data.usage);\n }\n\n const text = typeof chunk.content === \"string\" ? chunk.content : \"\";\n\n const generationChunk = new ChatGenerationChunk({\n message: chunk,\n text,\n generationInfo: {\n ...(choice.finish_reason\n ? { finish_reason: choice.finish_reason }\n : {}),\n },\n });\n\n yield generationChunk;\n await runManager?.handleLLMNewToken(text);\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n /**\n * Returns a new Runnable with the given tools bound into every call.\n * Equivalent to `.withConfig({ tools, ...kwargs })`.\n */\n override bindTools(\n tools: BindToolsInput[],\n kwargs?: Partial<ChatOpenRouterCallOptions>\n ): Runnable<\n BaseLanguageModelInput,\n AIMessageChunk,\n ChatOpenRouterCallOptions\n > {\n return this.withConfig({\n ...kwargs,\n tools,\n } as Partial<ChatOpenRouterCallOptions>);\n }\n\n /**\n * Returns a Runnable that forces the model to produce output conforming\n * to `outputSchema` (a Zod schema or plain JSON Schema object).\n *\n * The extraction strategy (JSON Schema response format, function calling,\n * or JSON mode) is chosen automatically based on model capabilities —\n * see {@link resolveOpenRouterStructuredOutputMethod}. You can override\n * this via `config.method`.\n *\n * When `config.includeRaw` is `true` the returned object contains both\n * the raw `BaseMessage` and the parsed output, with a fallback that\n * sets `parsed: null` if the parser throws.\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 // 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 // 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 // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<boolean>\n ):\n | Runnable<BaseLanguageModelInput, RunOutput>\n | Runnable<BaseLanguageModelInput, { raw: BaseMessage; parsed: RunOutput }>;\n\n withStructuredOutput<\n RunOutput extends Record<string, unknown> = Record<string, unknown>\n >(\n outputSchema: InteropZodType<RunOutput> | Record<string, unknown>,\n config?: StructuredOutputMethodOptions<boolean>\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\n const method = resolveOpenRouterStructuredOutputMethod({\n model: this.model,\n method: config?.method,\n profile: this.profile,\n models: this.models,\n route: this.route,\n });\n\n const asJsonSchema = toJsonSchema(schema);\n\n if (method === \"jsonSchema\") {\n const schemaName = name ?? \"extract\";\n llm = this.withConfig({\n response_format: {\n type: \"json_schema\",\n json_schema: {\n name: schemaName,\n description: getSchemaDescription(schema),\n schema: asJsonSchema,\n strict: config?.strict,\n },\n },\n ls_structured_output_format: {\n kwargs: { method: \"json_schema\" },\n schema: {\n title: schemaName,\n description: getSchemaDescription(schema),\n ...asJsonSchema,\n },\n },\n } as Partial<ChatOpenRouterCallOptions>);\n\n outputParser = isInteropZodSchema(schema)\n ? StructuredOutputParser.fromZodSchema(schema)\n : new JsonOutputParser<RunOutput>();\n } else if (method === \"jsonMode\") {\n llm = this.withConfig({\n response_format: { type: \"json_object\" },\n ls_structured_output_format: {\n kwargs: { method: \"json_mode\" },\n schema: { title: name ?? \"extract\", ...asJsonSchema },\n },\n } as Partial<ChatOpenRouterCallOptions>);\n\n outputParser = isInteropZodSchema(schema)\n ? StructuredOutputParser.fromZodSchema(schema)\n : new JsonOutputParser<RunOutput>();\n } else {\n let functionName = name ?? \"extract\";\n if (\"name\" in (schema as Record<string, unknown>)) {\n functionName = (schema as Record<string, unknown>).name as string;\n }\n\n llm = this.withConfig({\n tools: [\n {\n type: \"function\" as const,\n function: {\n name: functionName,\n description: getSchemaDescription(schema) ?? \"\",\n parameters: asJsonSchema,\n },\n },\n ],\n tool_choice: {\n type: \"function\" as const,\n function: { name: functionName },\n },\n ls_structured_output_format: {\n kwargs: { method: \"function_calling\" },\n schema: { title: functionName, ...asJsonSchema },\n },\n ...(config?.strict !== undefined ? { strict: config.strict } : {}),\n } as Partial<ChatOpenRouterCallOptions>);\n\n outputParser = isInteropZodSchema(schema)\n ? new JsonOutputKeyToolsParser({\n returnSingle: true,\n keyName: functionName,\n zodSchema: schema,\n })\n : new JsonOutputKeyToolsParser<RunOutput>({\n returnSingle: true,\n keyName: functionName,\n });\n }\n\n if (!includeRaw) {\n return llm.pipe(outputParser).withConfig({\n runName: \"ChatOpenRouterStructuredOutput\",\n }) as Runnable<BaseLanguageModelInput, RunOutput>;\n }\n\n const parserAssign = RunnablePassthrough.assign({\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n parsed: (input: any, config) => outputParser.invoke(input.raw, config),\n });\n const parserNone = RunnablePassthrough.assign({\n parsed: () => null,\n });\n const parsedWithFallback = parserAssign.withFallbacks({\n fallbacks: [parserNone],\n });\n return RunnableSequence.from<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n >([{ raw: llm }, parsedWithFallback]).withConfig({\n runName: \"ChatOpenRouterStructuredOutput\",\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/chat_models/index.ts"],"sourcesContent":["import {\n BaseChatModel,\n type BindToolsInput,\n type LangSmithParams,\n} from \"@langchain/core/language_models/chat_models\";\nimport type { ModelProfile } from \"@langchain/core/language_models/profile\";\nimport type {\n BaseLanguageModelInput,\n StructuredOutputMethodOptions,\n} from \"@langchain/core/language_models/base\";\nimport {\n AIMessage,\n AIMessageChunk,\n BaseMessage,\n} from \"@langchain/core/messages\";\nimport { ChatGenerationChunk, type ChatResult } from \"@langchain/core/outputs\";\nimport type { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport {\n Runnable,\n RunnablePassthrough,\n RunnableSequence,\n} from \"@langchain/core/runnables\";\nimport { toJsonSchema } from \"@langchain/core/utils/json_schema\";\nimport {\n type InteropZodType,\n isInteropZodSchema,\n getSchemaDescription,\n} from \"@langchain/core/utils/types\";\nimport {\n JsonOutputParser,\n StructuredOutputParser,\n} from \"@langchain/core/output_parsers\";\nimport { JsonOutputKeyToolsParser } from \"@langchain/core/output_parsers/openai_tools\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport { EventSourceParserStream } from \"eventsource-parser/stream\";\n\nimport type {\n ChatOpenRouterParams,\n ChatOpenRouterCallOptions,\n} from \"./types.js\";\nimport type { OpenAI as OpenAIClient } from \"openai\";\nimport type { OpenRouter } from \"../api-types.js\";\n\n/**\n * Full request body sent to the OpenRouter `/chat/completions` endpoint.\n *\n * Extends the base generation params with OpenRouter-specific sampling\n * knobs (`top_k`, `min_p`, etc.) and features (`prediction`, `transforms`)\n * that aren't part of the standard OpenAI spec.\n */\ntype OpenRouterRequestBody = Omit<\n OpenRouter.ChatGenerationParams,\n \"messages\"\n> & {\n messages: OpenAIClient.Chat.Completions.ChatCompletionMessageParam[];\n top_k?: number | null;\n repetition_penalty?: number | null;\n min_p?: number | null;\n top_a?: number | null;\n prediction?: { type: \"content\"; content: string };\n transforms?: string[];\n};\nimport {\n convertMessagesToOpenRouterParams,\n convertOpenRouterResponseToBaseMessage,\n convertOpenRouterDeltaToBaseMessageChunk,\n convertUsageMetadata,\n} from \"../converters/messages.js\";\nimport {\n convertToolsToOpenRouter,\n formatToolChoice,\n} from \"../converters/tools.js\";\nimport { OpenRouterError, OpenRouterAuthError } from \"../utils/errors.js\";\nimport { resolveOpenRouterStructuredOutputMethod } from \"../utils/structured_output.js\";\nimport { OpenRouterJsonParseStream } from \"../utils/stream.js\";\nimport PROFILES from \"../profiles.js\";\n\nconst DEFAULT_BASE_URL = \"https://openrouter.ai/api/v1\";\n\n/**\n * OpenRouter chat model integration.\n *\n * Talks directly to the OpenRouter REST API via `fetch` (no SDK dependency)\n * and supports tool calling, structured output, and streaming. Any model\n * available on OpenRouter can be used by passing its identifier (e.g.\n * `\"anthropic/claude-4-sonnet\"`) as the `model` param.\n */\nexport class ChatOpenRouter extends BaseChatModel<\n ChatOpenRouterCallOptions,\n AIMessageChunk\n> {\n static lc_name() {\n return \"ChatOpenRouter\";\n }\n\n lc_serializable = true;\n\n /** Maps secret fields to the environment variable they can be loaded from. */\n get lc_secrets(): { [key: string]: string } | undefined {\n return {\n apiKey: \"OPENROUTER_API_KEY\",\n };\n }\n\n /** Allows serialized JSON to use `modelName` as an alias for `model`. */\n get lc_aliases(): Record<string, string> {\n return {\n modelName: \"model\",\n };\n }\n\n /** Fields that may be overridden per-call via `.bind()` / `.withConfig()`. */\n get callKeys(): string[] {\n return [\n ...super.callKeys,\n \"tools\",\n \"tool_choice\",\n \"response_format\",\n \"seed\",\n \"strict\",\n \"temperature\",\n \"maxTokens\",\n \"topP\",\n \"topK\",\n \"frequencyPenalty\",\n \"presencePenalty\",\n \"repetitionPenalty\",\n \"minP\",\n \"topA\",\n \"stop\",\n \"logitBias\",\n \"topLogprobs\",\n \"user\",\n \"transforms\",\n \"models\",\n \"route\",\n \"provider\",\n \"plugins\",\n \"prediction\",\n ];\n }\n\n /** Model identifier, e.g. `\"anthropic/claude-4-sonnet\"`. */\n model: string;\n\n /** OpenRouter API key. Falls back to the `OPENROUTER_API_KEY` env var. */\n apiKey: string;\n\n /** Base URL for the API. Defaults to `\"https://openrouter.ai/api/v1\"`. */\n baseURL: string;\n\n /** Sampling temperature (0–2). */\n temperature?: number;\n\n /** Maximum number of tokens to generate. */\n maxTokens?: number;\n\n /** Nucleus sampling cutoff probability. */\n topP?: number;\n\n /** Top-K sampling: only consider the K most likely tokens. */\n topK?: number;\n\n /** Additive penalty based on how often a token has appeared so far (−2 to 2). */\n frequencyPenalty?: number;\n\n /** Additive penalty based on whether a token has appeared at all (−2 to 2). */\n presencePenalty?: number;\n\n /** Multiplicative penalty applied to repeated token logits (0 to 2). */\n repetitionPenalty?: number;\n\n /** Minimum probability threshold for token sampling. */\n minP?: number;\n\n /** Top-A sampling threshold. */\n topA?: number;\n\n /** Random seed for deterministic generation. */\n seed?: number;\n\n /** Stop sequences that halt generation. */\n stop?: string[];\n\n /** Token-level biases to apply during sampling. */\n logitBias?: Record<string, number>;\n\n /** Number of most-likely log-probabilities to return per token. */\n topLogprobs?: number;\n\n /** Stable identifier for end-users, used for abuse detection. */\n user?: string;\n\n /** OpenRouter-specific transformations to apply to the request. */\n transforms?: string[];\n\n /** OpenRouter-specific list of models for routing. */\n models?: string[];\n\n /** OpenRouter-specific routing strategy. */\n route?: \"fallback\";\n\n /** OpenRouter-specific provider preferences and ordering. */\n provider?: OpenRouter.ProviderPreferences;\n\n /** OpenRouter plugins to enable (e.g. web search). */\n plugins?: ChatOpenRouterParams[\"plugins\"];\n\n /**\n * Application URL for OpenRouter attribution. Maps to `HTTP-Referer` header.\n *\n * See https://openrouter.ai/docs/app-attribution for details.\n */\n siteUrl: string;\n\n /**\n * Application title for OpenRouter attribution. Maps to `X-Title` header.\n *\n * See https://openrouter.ai/docs/app-attribution for details.\n */\n siteName: string;\n\n /** Extra params passed through to the API body. */\n modelKwargs?: Record<string, unknown>;\n\n /** Whether to include token usage in streaming chunks. Defaults to `true`. */\n streamUsage: boolean;\n\n constructor(fields: ChatOpenRouterParams) {\n super(fields);\n const apiKey =\n fields.apiKey ?? getEnvironmentVariable(\"OPENROUTER_API_KEY\");\n if (!apiKey) {\n throw new OpenRouterAuthError(\n \"OpenRouter API key is required. Get one at https://openrouter.ai/keys and set it via the `apiKey` parameter or the OPENROUTER_API_KEY environment variable.\"\n );\n }\n this.apiKey = apiKey;\n if (!fields.model) {\n throw new Error(\n 'ChatOpenRouter requires a `model` parameter, e.g. \"openai/gpt-4o-mini\".'\n );\n }\n this.model = fields.model;\n this.baseURL = fields.baseURL ?? DEFAULT_BASE_URL;\n this.temperature = fields.temperature;\n this.maxTokens = fields.maxTokens;\n this.topP = fields.topP;\n this.topK = fields.topK;\n this.frequencyPenalty = fields.frequencyPenalty;\n this.presencePenalty = fields.presencePenalty;\n this.repetitionPenalty = fields.repetitionPenalty;\n this.minP = fields.minP;\n this.topA = fields.topA;\n this.seed = fields.seed;\n this.stop = fields.stop;\n this.logitBias = fields.logitBias;\n this.topLogprobs = fields.topLogprobs;\n this.user = fields.user;\n this.transforms = fields.transforms;\n this.models = fields.models;\n this.route = fields.route;\n this.provider = fields.provider;\n this.plugins = fields.plugins;\n this.siteUrl = fields.siteUrl ?? \"https://docs.langchain.com/oss\";\n this.siteName = fields.siteName ?? \"langchain\";\n this.modelKwargs = fields.modelKwargs;\n this.streamUsage = fields.streamUsage ?? true;\n }\n\n _llmType(): string {\n return \"openrouter\";\n }\n\n /** Static capability profile (context size, tool support, etc.) for the current model. */\n get profile(): ModelProfile {\n return PROFILES[this.model] ?? {};\n }\n\n /** Builds auth + content-type headers, plus optional site attribution headers. */\n private buildHeaders(): Record<string, string> {\n return {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n \"HTTP-Referer\": this.siteUrl,\n \"X-Title\": this.siteName,\n };\n }\n\n /** Returns the full chat-completions endpoint URL. */\n private buildUrl(): string {\n return `${this.baseURL}/chat/completions`;\n }\n\n /**\n * Merges constructor-level defaults with per-call overrides into the\n * API request body (everything except `messages`, which is added later).\n */\n override invocationParams(\n options: this[\"ParsedCallOptions\"]\n ): Omit<OpenRouterRequestBody, \"messages\"> {\n const tools = options.tools\n ? convertToolsToOpenRouter(options.tools, { strict: options.strict })\n : undefined;\n const toolChoice = formatToolChoice(options.tool_choice);\n\n return {\n model: this.model,\n temperature: options.temperature ?? this.temperature,\n max_tokens: options.maxTokens ?? this.maxTokens,\n top_p: options.topP ?? this.topP,\n top_k: options.topK ?? this.topK,\n frequency_penalty: options.frequencyPenalty ?? this.frequencyPenalty,\n presence_penalty: options.presencePenalty ?? this.presencePenalty,\n repetition_penalty: options.repetitionPenalty ?? this.repetitionPenalty,\n min_p: options.minP ?? this.minP,\n top_a: options.topA ?? this.topA,\n seed: options.seed ?? this.seed,\n stop: options.stop ?? this.stop,\n logit_bias: options.logitBias ?? this.logitBias,\n top_logprobs: options.topLogprobs ?? this.topLogprobs,\n user: options.user ?? this.user,\n tools,\n tool_choice: toolChoice,\n response_format: options.response_format,\n ...(options.prediction ? { prediction: options.prediction } : {}),\n transforms: options.transforms ?? this.transforms,\n models: options.models ?? this.models,\n route: options.route ?? this.route,\n provider: options.provider ?? this.provider,\n plugins: options.plugins ?? this.plugins,\n ...this.modelKwargs,\n };\n }\n\n /** Returns metadata for LangSmith tracing (provider, model name, temperature, etc.). */\n override getLsParams(options: this[\"ParsedCallOptions\"]): LangSmithParams {\n const params = this.invocationParams(options);\n return {\n ls_provider: \"openrouter\",\n ls_model_name: this.model,\n ls_model_type: \"chat\",\n ls_temperature: params.temperature ?? undefined,\n ls_max_tokens: params.max_tokens ?? undefined,\n ls_stop: options.stop,\n };\n }\n\n /**\n * Non-streaming generation. Sends a single request and returns the\n * complete response with the generated message and token usage.\n */\n async _generate(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n const body: OpenRouterRequestBody = {\n ...this.invocationParams(options),\n messages: convertMessagesToOpenRouterParams(messages, this.model),\n stream: false,\n };\n\n const response = await fetch(this.buildUrl(), {\n method: \"POST\",\n headers: this.buildHeaders(),\n body: JSON.stringify(body),\n signal: options.signal,\n });\n\n if (!response.ok) {\n throw await OpenRouterError.fromResponse(response);\n }\n\n const data: OpenRouter.ChatResponse = await response.json();\n const choice = data.choices[0];\n\n if (!choice) {\n throw new OpenRouterError(\"No choices returned in response.\");\n }\n\n const message = convertOpenRouterResponseToBaseMessage(choice, data);\n if (AIMessage.isInstance(message)) {\n message.usage_metadata = convertUsageMetadata(data.usage);\n }\n\n const text = typeof message.content === \"string\" ? message.content : \"\";\n\n await runManager?.handleLLMNewToken(text);\n\n return {\n generations: [\n {\n text,\n message,\n generationInfo: {\n finish_reason: choice.finish_reason,\n },\n },\n ],\n llmOutput: { tokenUsage: data.usage },\n };\n }\n\n /**\n * Streaming generation. Opens an SSE connection and yields one\n * `ChatGenerationChunk` per delta received from the API. The stream\n * pipeline is: raw bytes -> text -> SSE events -> JSON-parsed deltas.\n */\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const body: OpenRouterRequestBody = {\n ...this.invocationParams(options),\n messages: convertMessagesToOpenRouterParams(messages, this.model),\n stream: true,\n };\n\n const response = await fetch(this.buildUrl(), {\n method: \"POST\",\n headers: this.buildHeaders(),\n body: JSON.stringify(body),\n signal: options.signal,\n });\n\n if (!response.ok) {\n throw await OpenRouterError.fromResponse(response);\n }\n\n if (!response.body) {\n return;\n }\n\n const stream = response.body\n .pipeThrough(new TextDecoderStream())\n .pipeThrough(new EventSourceParserStream())\n .pipeThrough(new OpenRouterJsonParseStream());\n\n const reader = stream.getReader();\n let defaultRole: string | undefined;\n\n try {\n while (true) {\n const { done, value: data } = await reader.read();\n if (done) break;\n if (!data) continue;\n\n const choice = data.choices?.[0];\n if (!choice?.delta) continue;\n\n const chunk = convertOpenRouterDeltaToBaseMessageChunk(\n choice.delta,\n data,\n defaultRole\n );\n defaultRole = choice.delta.role ?? defaultRole;\n\n if (\n data.usage &&\n this.streamUsage &&\n AIMessageChunk.isInstance(chunk)\n ) {\n chunk.usage_metadata = convertUsageMetadata(data.usage);\n }\n\n const text = typeof chunk.content === \"string\" ? chunk.content : \"\";\n\n const generationChunk = new ChatGenerationChunk({\n message: chunk,\n text,\n generationInfo: {\n ...(choice.finish_reason\n ? { finish_reason: choice.finish_reason }\n : {}),\n },\n });\n\n yield generationChunk;\n await runManager?.handleLLMNewToken(text);\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n /**\n * Returns a new Runnable with the given tools bound into every call.\n * Equivalent to `.withConfig({ tools, ...kwargs })`.\n */\n override bindTools(\n tools: BindToolsInput[],\n kwargs?: Partial<ChatOpenRouterCallOptions>\n ): Runnable<\n BaseLanguageModelInput,\n AIMessageChunk,\n ChatOpenRouterCallOptions\n > {\n return this.withConfig({\n ...kwargs,\n tools,\n } as Partial<ChatOpenRouterCallOptions>);\n }\n\n /**\n * Returns a Runnable that forces the model to produce output conforming\n * to `outputSchema` (a Zod schema or plain JSON Schema object).\n *\n * The extraction strategy (JSON Schema response format, function calling,\n * or JSON mode) is chosen automatically based on model capabilities —\n * see {@link resolveOpenRouterStructuredOutputMethod}. You can override\n * this via `config.method`.\n *\n * When `config.includeRaw` is `true` the returned object contains both\n * the raw `BaseMessage` and the parsed output, with a fallback that\n * sets `parsed: null` if the parser throws.\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 // 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 // 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 // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<boolean>\n ):\n | Runnable<BaseLanguageModelInput, RunOutput>\n | Runnable<BaseLanguageModelInput, { raw: BaseMessage; parsed: RunOutput }>;\n\n withStructuredOutput<\n RunOutput extends Record<string, unknown> = Record<string, unknown>\n >(\n outputSchema: InteropZodType<RunOutput> | Record<string, unknown>,\n config?: StructuredOutputMethodOptions<boolean>\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\n const method = resolveOpenRouterStructuredOutputMethod({\n model: this.model,\n method: config?.method,\n profile: this.profile,\n models: this.models,\n route: this.route,\n });\n\n const asJsonSchema = toJsonSchema(schema);\n\n if (method === \"jsonSchema\") {\n const schemaName = name ?? \"extract\";\n llm = this.withConfig({\n response_format: {\n type: \"json_schema\",\n json_schema: {\n name: schemaName,\n description: getSchemaDescription(schema),\n schema: asJsonSchema,\n strict: config?.strict,\n },\n },\n ls_structured_output_format: {\n kwargs: { method: \"json_schema\" },\n schema: {\n title: schemaName,\n description: getSchemaDescription(schema),\n ...asJsonSchema,\n },\n },\n } as Partial<ChatOpenRouterCallOptions>);\n\n outputParser = isInteropZodSchema(schema)\n ? StructuredOutputParser.fromZodSchema(schema)\n : new JsonOutputParser<RunOutput>();\n } else if (method === \"jsonMode\") {\n llm = this.withConfig({\n response_format: { type: \"json_object\" },\n ls_structured_output_format: {\n kwargs: { method: \"json_mode\" },\n schema: { title: name ?? \"extract\", ...asJsonSchema },\n },\n } as Partial<ChatOpenRouterCallOptions>);\n\n outputParser = isInteropZodSchema(schema)\n ? StructuredOutputParser.fromZodSchema(schema)\n : new JsonOutputParser<RunOutput>();\n } else {\n let functionName = name ?? \"extract\";\n if (\"name\" in (schema as Record<string, unknown>)) {\n functionName = (schema as Record<string, unknown>).name as string;\n }\n\n llm = this.withConfig({\n tools: [\n {\n type: \"function\" as const,\n function: {\n name: functionName,\n description: getSchemaDescription(schema) ?? \"\",\n parameters: asJsonSchema,\n },\n },\n ],\n tool_choice: {\n type: \"function\" as const,\n function: { name: functionName },\n },\n ls_structured_output_format: {\n kwargs: { method: \"function_calling\" },\n schema: { title: functionName, ...asJsonSchema },\n },\n ...(config?.strict !== undefined ? { strict: config.strict } : {}),\n } as Partial<ChatOpenRouterCallOptions>);\n\n outputParser = isInteropZodSchema(schema)\n ? new JsonOutputKeyToolsParser({\n returnSingle: true,\n keyName: functionName,\n zodSchema: schema,\n })\n : new JsonOutputKeyToolsParser<RunOutput>({\n returnSingle: true,\n keyName: functionName,\n });\n }\n\n if (!includeRaw) {\n return llm.pipe(outputParser).withConfig({\n runName: \"ChatOpenRouterStructuredOutput\",\n }) as Runnable<BaseLanguageModelInput, RunOutput>;\n }\n\n const parserAssign = RunnablePassthrough.assign({\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n parsed: (input: any, config) => outputParser.invoke(input.raw, config),\n });\n const parserNone = RunnablePassthrough.assign({\n parsed: () => null,\n });\n const parsedWithFallback = parserAssign.withFallbacks({\n fallbacks: [parserNone],\n });\n return RunnableSequence.from<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n >([{ raw: llm }, parsedWithFallback]).withConfig({\n runName: \"ChatOpenRouterStructuredOutput\",\n });\n }\n}\n"],"mappings":"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"}
@@ -61,9 +61,19 @@ interface ChatOpenRouterParams extends BaseChatModelParams, ChatOpenRouterFields
61
61
  apiKey?: string;
62
62
  /** Base URL for the API. Defaults to "https://openrouter.ai/api/v1". */
63
63
  baseURL?: string;
64
- /** Your site URL — used for OpenRouter rankings / rate limits. */
64
+ /**
65
+ * Application URL for OpenRouter attribution. Maps to `HTTP-Referer` header.
66
+ * Defaults to `"https://docs.langchain.com/oss"`.
67
+ *
68
+ * See https://openrouter.ai/docs/app-attribution for details.
69
+ */
65
70
  siteUrl?: string;
66
- /** Your site name — shown on the OpenRouter leaderboard. */
71
+ /**
72
+ * Application title for OpenRouter attribution. Maps to `X-Title` header.
73
+ * Defaults to `"langchain"`.
74
+ *
75
+ * See https://openrouter.ai/docs/app-attribution for details.
76
+ */
67
77
  siteName?: string;
68
78
  /** Stable identifier for end-users, used for abuse detection. */
69
79
  user?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.cts","names":[],"sources":["../../src/chat_models/types.ts"],"mappings":";;;;KAOY,wBAAA,GACV,UAAA,CAAW,oBAAA;AADb;;;AAAA,UAMiB,gBAAA;EACf,EAAA;EAAA,CAEC,GAAA;AAAA;;;;UAMc,oBAAA;EAAoB;EAEnC,WAAA;EAsBY;EApBZ,SAAA;EAgCU;EA9BV,IAAA;EA8B0B;EA5B1B,IAAA;EAJA;EAMA,gBAAA;EAFA;EAIA,eAAA;EAAA;EAEA,iBAAA;EAEA;EAAA,IAAA;EAIA;EAFA,IAAA;EAMA;EAJA,IAAA;EAMA;EAJA,IAAA;EAQA;EANA,SAAA,GAAY,MAAA;EAUZ;EARA,WAAA;EAQsB;EANtB,UAAA;EAQU;EANV,MAAA;EAM0B;EAJ1B,KAAA;EAWA;EATA,QAAA,GAAW,UAAA,CAAW,mBAAA;EAwBR;EAtBd,OAAA,GAAU,gBAAA;AAAA;;;;UAMK,oBAAA,SACP,mBAAA,EACN,oBAAA;EAEF;EAAA,KAAA;EAIA;EAFA,MAAA;EAMA;EAJA,OAAA;EAQA;EANA,OAAA;EAQA;EANA,QAAA;EAMW;EAJX,IAAA;EAWA;EATA,WAAA,GAAc,MAAA;EAYN;EAVR,WAAA;AAAA;;;;UAMe,yBAAA,SACP,wBAAA,EACN,oBAAA;EADM;EAGR,KAAA,GAAQ,cAAA;EAAR;EAEA,eAAA,GAAkB,wBAAA;EAAlB;EAEA,MAAA;EAAA;EAEA,UAAA;IAAe,IAAA;IAAiB,OAAA;EAAA;EAIhC;EAFA,IAAA;EAEoB;EAApB,MAAA,GAAS,WAAA;AAAA"}
1
+ {"version":3,"file":"types.d.cts","names":[],"sources":["../../src/chat_models/types.ts"],"mappings":";;;;KAOY,wBAAA,GACV,UAAA,CAAW,oBAAA;AADb;;;AAAA,UAMiB,gBAAA;EACf,EAAA;EAAA,CAEC,GAAA;AAAA;;;;UAMc,oBAAA;EAAoB;EAEnC,WAAA;EAsBY;EApBZ,SAAA;EAgCU;EA9BV,IAAA;EA8B0B;EA5B1B,IAAA;EAJA;EAMA,gBAAA;EAFA;EAIA,eAAA;EAAA;EAEA,iBAAA;EAEA;EAAA,IAAA;EAIA;EAFA,IAAA;EAMA;EAJA,IAAA;EAMA;EAJA,IAAA;EAQA;EANA,SAAA,GAAY,MAAA;EAUZ;EARA,WAAA;EAQsB;EANtB,UAAA;EAQU;EANV,MAAA;EAM0B;EAJ1B,KAAA;EAWA;EATA,QAAA,GAAW,UAAA,CAAW,mBAAA;EAkCR;EAhCd,OAAA,GAAU,gBAAA;AAAA;;;;UAMK,oBAAA,SACP,mBAAA,EACN,oBAAA;EAEF;EAAA,KAAA;EAIA;EAFA,MAAA;EAgBA;EAdA,OAAA;EAkBA;;;;;AAQF;EAnBE,OAAA;;;;;;;EAOA,QAAA;EAcsB;EAZtB,IAAA;EAYE;EAVF,WAAA,GAAc,MAAA;EAYN;EAVR,WAAA;AAAA;;;;UAMe,yBAAA,SACP,wBAAA,EACN,oBAAA;EAUF;EARA,KAAA,GAAQ,cAAA;EAUC;EART,eAAA,GAAkB,wBAAA;EAQE;EANpB,MAAA;;EAEA,UAAA;IAAe,IAAA;IAAiB,OAAA;EAAA;;EAEhC,IAAA;;EAEA,MAAA,GAAS,WAAA;AAAA"}
@@ -61,9 +61,19 @@ interface ChatOpenRouterParams extends BaseChatModelParams, ChatOpenRouterFields
61
61
  apiKey?: string;
62
62
  /** Base URL for the API. Defaults to "https://openrouter.ai/api/v1". */
63
63
  baseURL?: string;
64
- /** Your site URL — used for OpenRouter rankings / rate limits. */
64
+ /**
65
+ * Application URL for OpenRouter attribution. Maps to `HTTP-Referer` header.
66
+ * Defaults to `"https://docs.langchain.com/oss"`.
67
+ *
68
+ * See https://openrouter.ai/docs/app-attribution for details.
69
+ */
65
70
  siteUrl?: string;
66
- /** Your site name — shown on the OpenRouter leaderboard. */
71
+ /**
72
+ * Application title for OpenRouter attribution. Maps to `X-Title` header.
73
+ * Defaults to `"langchain"`.
74
+ *
75
+ * See https://openrouter.ai/docs/app-attribution for details.
76
+ */
67
77
  siteName?: string;
68
78
  /** Stable identifier for end-users, used for abuse detection. */
69
79
  user?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/chat_models/types.ts"],"mappings":";;;;KAOY,wBAAA,GACV,UAAA,CAAW,oBAAA;AADb;;;AAAA,UAMiB,gBAAA;EACf,EAAA;EAAA,CAEC,GAAA;AAAA;;;;UAMc,oBAAA;EAAoB;EAEnC,WAAA;EAsBY;EApBZ,SAAA;EAgCU;EA9BV,IAAA;EA8B0B;EA5B1B,IAAA;EAJA;EAMA,gBAAA;EAFA;EAIA,eAAA;EAAA;EAEA,iBAAA;EAEA;EAAA,IAAA;EAIA;EAFA,IAAA;EAMA;EAJA,IAAA;EAMA;EAJA,IAAA;EAQA;EANA,SAAA,GAAY,MAAA;EAUZ;EARA,WAAA;EAQsB;EANtB,UAAA;EAQU;EANV,MAAA;EAM0B;EAJ1B,KAAA;EAWA;EATA,QAAA,GAAW,UAAA,CAAW,mBAAA;EAwBR;EAtBd,OAAA,GAAU,gBAAA;AAAA;;;;UAMK,oBAAA,SACP,mBAAA,EACN,oBAAA;EAEF;EAAA,KAAA;EAIA;EAFA,MAAA;EAMA;EAJA,OAAA;EAQA;EANA,OAAA;EAQA;EANA,QAAA;EAMW;EAJX,IAAA;EAWA;EATA,WAAA,GAAc,MAAA;EAYN;EAVR,WAAA;AAAA;;;;UAMe,yBAAA,SACP,wBAAA,EACN,oBAAA;EADM;EAGR,KAAA,GAAQ,cAAA;EAAR;EAEA,eAAA,GAAkB,wBAAA;EAAlB;EAEA,MAAA;EAAA;EAEA,UAAA;IAAe,IAAA;IAAiB,OAAA;EAAA;EAIhC;EAFA,IAAA;EAEoB;EAApB,MAAA,GAAS,WAAA;AAAA"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/chat_models/types.ts"],"mappings":";;;;KAOY,wBAAA,GACV,UAAA,CAAW,oBAAA;AADb;;;AAAA,UAMiB,gBAAA;EACf,EAAA;EAAA,CAEC,GAAA;AAAA;;;;UAMc,oBAAA;EAAoB;EAEnC,WAAA;EAsBY;EApBZ,SAAA;EAgCU;EA9BV,IAAA;EA8B0B;EA5B1B,IAAA;EAJA;EAMA,gBAAA;EAFA;EAIA,eAAA;EAAA;EAEA,iBAAA;EAEA;EAAA,IAAA;EAIA;EAFA,IAAA;EAMA;EAJA,IAAA;EAMA;EAJA,IAAA;EAQA;EANA,SAAA,GAAY,MAAA;EAUZ;EARA,WAAA;EAQsB;EANtB,UAAA;EAQU;EANV,MAAA;EAM0B;EAJ1B,KAAA;EAWA;EATA,QAAA,GAAW,UAAA,CAAW,mBAAA;EAkCR;EAhCd,OAAA,GAAU,gBAAA;AAAA;;;;UAMK,oBAAA,SACP,mBAAA,EACN,oBAAA;EAEF;EAAA,KAAA;EAIA;EAFA,MAAA;EAgBA;EAdA,OAAA;EAkBA;;;;;AAQF;EAnBE,OAAA;;;;;;;EAOA,QAAA;EAcsB;EAZtB,IAAA;EAYE;EAVF,WAAA,GAAc,MAAA;EAYN;EAVR,WAAA;AAAA;;;;UAMe,yBAAA,SACP,wBAAA,EACN,oBAAA;EAUF;EARA,KAAA,GAAQ,cAAA;EAUC;EART,eAAA,GAAkB,wBAAA;EAQE;EANpB,MAAA;;EAEA,UAAA;IAAe,IAAA;IAAiB,OAAA;EAAA;;EAEhC,IAAA;;EAEA,MAAA,GAAS,WAAA;AAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/openrouter",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "OpenRouter integration for LangChain.js",
5
5
  "author": "LangChain",
6
6
  "license": "MIT",
@@ -16,7 +16,7 @@
16
16
  "dependencies": {
17
17
  "eventsource-parser": "^3.0.6",
18
18
  "openai": "^6.22.0",
19
- "@langchain/openai": "1.2.9"
19
+ "@langchain/openai": "1.2.10"
20
20
  },
21
21
  "peerDependencies": {
22
22
  "@langchain/core": "^1.0.0"
@@ -31,9 +31,9 @@
31
31
  "vitest": "^3.2.4",
32
32
  "zod": "^3.25.76 || ^4",
33
33
  "zod-to-json-schema": "^3.24.6",
34
- "@langchain/core": "^1.1.27",
34
+ "@langchain/core": "^1.1.28",
35
35
  "@langchain/eslint": "0.1.1",
36
- "@langchain/openai": "^1.2.9",
36
+ "@langchain/openai": "^1.2.10",
37
37
  "@langchain/standard-tests": "0.0.23"
38
38
  },
39
39
  "publishConfig": {