@langchain/openrouter 0.1.10 → 0.2.1
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 +18 -0
- package/README.md +3 -1
- package/dist/chat_models/index.cjs +24 -8
- package/dist/chat_models/index.cjs.map +1 -1
- package/dist/chat_models/index.d.cts +14 -1
- package/dist/chat_models/index.d.cts.map +1 -1
- package/dist/chat_models/index.d.ts +14 -1
- package/dist/chat_models/index.d.ts.map +1 -1
- package/dist/chat_models/index.js +24 -8
- package/dist/chat_models/index.js.map +1 -1
- package/dist/chat_models/types.d.cts +14 -1
- package/dist/chat_models/types.d.cts.map +1 -1
- package/dist/chat_models/types.d.ts +14 -1
- package/dist/chat_models/types.d.ts.map +1 -1
- package/dist/utils/errors.cjs.map +1 -1
- package/dist/utils/errors.js.map +1 -1
- package/package.json +6 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @langchain/openrouter
|
|
2
2
|
|
|
3
|
+
## 0.2.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`6b8ef6c`](https://github.com/langchain-ai/langchainjs/commit/6b8ef6c95e061af47af206926598c983d878f72a)]:
|
|
8
|
+
- @langchain/openai@1.4.3
|
|
9
|
+
|
|
10
|
+
## 0.2.0
|
|
11
|
+
|
|
12
|
+
### Minor Changes
|
|
13
|
+
|
|
14
|
+
- [#10559](https://github.com/langchain-ai/langchainjs/pull/10559) [`17aedaa`](https://github.com/langchain-ai/langchainjs/commit/17aedaabfca680a9f8bb8f858395ee1ee4f152a1) Thanks [@mdrxy](https://github.com/mdrxy)! - Add `appCategories` field for OpenRouter marketplace attribution (`X-OpenRouter-Categories` header) and update default `siteUrl`/`siteName` values. Attribution headers are now only sent when set.
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Updated dependencies [[`d6bf4fc`](https://github.com/langchain-ai/langchainjs/commit/d6bf4fc91b2c2eb931bf3bc7606b1817632bc8c1)]:
|
|
19
|
+
- @langchain/openai@1.4.2
|
|
20
|
+
|
|
3
21
|
## 0.1.10
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -54,7 +54,9 @@ import { ChatOpenRouter } from "@langchain/openrouter";
|
|
|
54
54
|
const model = new ChatOpenRouter({
|
|
55
55
|
model: "openai/gpt-4o",
|
|
56
56
|
});
|
|
57
|
-
const response = await model.invoke([
|
|
57
|
+
const response = await model.invoke([
|
|
58
|
+
{ role: "user", content: "Hello world!" },
|
|
59
|
+
]);
|
|
58
60
|
```
|
|
59
61
|
|
|
60
62
|
### Streaming
|
|
@@ -113,15 +113,28 @@ var ChatOpenRouter = class extends _langchain_core_language_models_chat_models.B
|
|
|
113
113
|
/**
|
|
114
114
|
* Application URL for OpenRouter attribution. Maps to `HTTP-Referer` header.
|
|
115
115
|
*
|
|
116
|
+
* Defaults to LangChain docs URL. Set this to your app's URL to get
|
|
117
|
+
* attribution for API usage in the OpenRouter dashboard.
|
|
118
|
+
*
|
|
116
119
|
* See https://openrouter.ai/docs/app-attribution for details.
|
|
117
120
|
*/
|
|
118
121
|
siteUrl;
|
|
119
122
|
/**
|
|
120
123
|
* Application title for OpenRouter attribution. Maps to `X-Title` header.
|
|
121
124
|
*
|
|
125
|
+
* Defaults to `'LangChain'`. Set this to your app's name to get attribution
|
|
126
|
+
* for API usage in the OpenRouter dashboard.
|
|
127
|
+
*
|
|
122
128
|
* See https://openrouter.ai/docs/app-attribution for details.
|
|
123
129
|
*/
|
|
124
130
|
siteName;
|
|
131
|
+
/**
|
|
132
|
+
* Marketplace categories for OpenRouter attribution.
|
|
133
|
+
* Maps to `X-OpenRouter-Categories` header.
|
|
134
|
+
*
|
|
135
|
+
* See https://openrouter.ai/docs/app-attribution for recognized categories.
|
|
136
|
+
*/
|
|
137
|
+
appCategories;
|
|
125
138
|
/** Extra params passed through to the API body. */
|
|
126
139
|
modelKwargs;
|
|
127
140
|
/** Whether to include token usage in streaming chunks. Defaults to `true`. */
|
|
@@ -132,7 +145,7 @@ var ChatOpenRouter = class extends _langchain_core_language_models_chat_models.B
|
|
|
132
145
|
model: modelOrFields
|
|
133
146
|
} : modelOrFields;
|
|
134
147
|
super(fields);
|
|
135
|
-
this._addVersion("@langchain/openrouter", "0.1
|
|
148
|
+
this._addVersion("@langchain/openrouter", "0.2.1");
|
|
136
149
|
const apiKey = fields.apiKey ?? (0, _langchain_core_utils_env.getEnvironmentVariable)("OPENROUTER_API_KEY");
|
|
137
150
|
if (!apiKey) throw new require_errors.OpenRouterAuthError("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.");
|
|
138
151
|
this.apiKey = apiKey;
|
|
@@ -158,8 +171,9 @@ var ChatOpenRouter = class extends _langchain_core_language_models_chat_models.B
|
|
|
158
171
|
this.route = fields.route;
|
|
159
172
|
this.provider = fields.provider;
|
|
160
173
|
this.plugins = fields.plugins;
|
|
161
|
-
this.siteUrl = fields.siteUrl ?? "https://docs.langchain.com
|
|
162
|
-
this.siteName = fields.siteName ?? "
|
|
174
|
+
this.siteUrl = fields.siteUrl ?? "https://docs.langchain.com";
|
|
175
|
+
this.siteName = fields.siteName ?? "LangChain";
|
|
176
|
+
this.appCategories = fields.appCategories;
|
|
163
177
|
this.modelKwargs = fields.modelKwargs;
|
|
164
178
|
this.streamUsage = fields.streamUsage ?? true;
|
|
165
179
|
}
|
|
@@ -170,14 +184,16 @@ var ChatOpenRouter = class extends _langchain_core_language_models_chat_models.B
|
|
|
170
184
|
get profile() {
|
|
171
185
|
return require_profiles.default[this.model] ?? {};
|
|
172
186
|
}
|
|
173
|
-
/** Builds auth + content-type headers, plus optional
|
|
187
|
+
/** Builds auth + content-type headers, plus optional attribution headers. */
|
|
174
188
|
buildHeaders() {
|
|
175
|
-
|
|
189
|
+
const headers = {
|
|
176
190
|
Authorization: `Bearer ${this.apiKey}`,
|
|
177
|
-
"Content-Type": "application/json"
|
|
178
|
-
"HTTP-Referer": this.siteUrl,
|
|
179
|
-
"X-Title": this.siteName
|
|
191
|
+
"Content-Type": "application/json"
|
|
180
192
|
};
|
|
193
|
+
if (this.siteUrl) headers["HTTP-Referer"] = this.siteUrl;
|
|
194
|
+
if (this.siteName) headers["X-Title"] = this.siteName;
|
|
195
|
+
if (this.appCategories && this.appCategories.length > 0) headers["X-OpenRouter-Categories"] = this.appCategories.join(",");
|
|
196
|
+
return headers;
|
|
181
197
|
}
|
|
182
198
|
/** Returns the full chat-completions endpoint URL. */
|
|
183
199
|
buildUrl() {
|
|
@@ -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"],"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 { Runnable } from \"@langchain/core/runnables\";\nimport { toJsonSchema } from \"@langchain/core/utils/json_schema\";\nimport {\n type InteropZodType,\n getSchemaDescription,\n isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\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\";\nimport {\n isSerializableSchema,\n SerializableSchema,\n} from \"@langchain/core/utils/standard_schema\";\nimport {\n assembleStructuredOutputPipeline,\n createContentParser,\n createFunctionCallingParser,\n} from \"@langchain/core/language_models/structured_output\";\n\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(model: string, fields?: Omit<ChatOpenRouterParams, \"model\">);\n constructor(fields: ChatOpenRouterParams);\n constructor(\n modelOrFields: string | ChatOpenRouterParams,\n fieldsArg?: Omit<ChatOpenRouterParams, \"model\">\n ) {\n const fields =\n typeof modelOrFields === \"string\"\n ? { ...(fieldsArg ?? {}), model: modelOrFields }\n : modelOrFields;\n super(fields);\n this._addVersion(\"@langchain/openrouter\", __PKG_VERSION__);\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(\n text,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: generationChunk }\n );\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 | SerializableSchema<RunOutput>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<false>\n ): Runnable<BaseLanguageModelInput, RunOutput>;\n\n withStructuredOutput<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n | SerializableSchema<RunOutput>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<true>\n ): Runnable<BaseLanguageModelInput, { raw: BaseMessage; parsed: RunOutput }>;\n\n withStructuredOutput<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n | SerializableSchema<RunOutput>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<boolean>\n ):\n | Runnable<BaseLanguageModelInput, RunOutput>\n | Runnable<BaseLanguageModelInput, { raw: BaseMessage; parsed: RunOutput }>;\n\n withStructuredOutput<\n RunOutput extends Record<string, unknown> = Record<string, unknown>\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n | SerializableSchema<RunOutput>\n | 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 = createContentParser(schema);\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 outputParser = createContentParser(schema);\n } else {\n let functionName = name ?? \"extract\";\n if (\n !isInteropZodSchema(schema) &&\n !isSerializableSchema(schema) &&\n \"name\" in (schema as Record<string, unknown>)\n ) {\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 = createFunctionCallingParser(schema, functionName);\n }\n\n return assembleStructuredOutputPipeline(\n llm,\n outputParser,\n includeRaw,\n \"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"],"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 { Runnable } from \"@langchain/core/runnables\";\nimport { toJsonSchema } from \"@langchain/core/utils/json_schema\";\nimport {\n type InteropZodType,\n getSchemaDescription,\n isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\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\";\nimport {\n isSerializableSchema,\n SerializableSchema,\n} from \"@langchain/core/utils/standard_schema\";\nimport {\n assembleStructuredOutputPipeline,\n createContentParser,\n createFunctionCallingParser,\n} from \"@langchain/core/language_models/structured_output\";\n\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 * Defaults to LangChain docs URL. Set this to your app's URL to get\n * attribution for API usage in the OpenRouter dashboard.\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 * Defaults to `'LangChain'`. Set this to your app's name to get attribution\n * for API usage in the OpenRouter dashboard.\n *\n * See https://openrouter.ai/docs/app-attribution for details.\n */\n siteName: string;\n\n /**\n * Marketplace categories for OpenRouter attribution.\n * Maps to `X-OpenRouter-Categories` header.\n *\n * See https://openrouter.ai/docs/app-attribution for recognized categories.\n */\n appCategories?: 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(model: string, fields?: Omit<ChatOpenRouterParams, \"model\">);\n constructor(fields: ChatOpenRouterParams);\n constructor(\n modelOrFields: string | ChatOpenRouterParams,\n fieldsArg?: Omit<ChatOpenRouterParams, \"model\">\n ) {\n const fields =\n typeof modelOrFields === \"string\"\n ? { ...(fieldsArg ?? {}), model: modelOrFields }\n : modelOrFields;\n super(fields);\n this._addVersion(\"@langchain/openrouter\", __PKG_VERSION__);\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\";\n this.siteName = fields.siteName ?? \"LangChain\";\n this.appCategories = fields.appCategories;\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 attribution headers. */\n private buildHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n };\n if (this.siteUrl) {\n headers[\"HTTP-Referer\"] = this.siteUrl;\n }\n if (this.siteName) {\n headers[\"X-Title\"] = this.siteName;\n }\n if (this.appCategories && this.appCategories.length > 0) {\n headers[\"X-OpenRouter-Categories\"] = this.appCategories.join(\",\");\n }\n return headers;\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(\n text,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: generationChunk }\n );\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 // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>,\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n | SerializableSchema<RunOutput>\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<false>\n ): Runnable<BaseLanguageModelInput, RunOutput>;\n\n withStructuredOutput<\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>,\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n | SerializableSchema<RunOutput>\n // oxlint-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 // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>,\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n | SerializableSchema<RunOutput>\n // oxlint-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:\n | InteropZodType<RunOutput>\n | SerializableSchema<RunOutput>\n | 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 = createContentParser(schema);\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 outputParser = createContentParser(schema);\n } else {\n let functionName = name ?? \"extract\";\n if (\n !isInteropZodSchema(schema) &&\n !isSerializableSchema(schema) &&\n \"name\" in (schema as Record<string, unknown>)\n ) {\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 = createFunctionCallingParser(schema, functionName);\n }\n\n return assembleStructuredOutputPipeline(\n llm,\n outputParser,\n includeRaw,\n \"ChatOpenRouterStructuredOutput\"\n );\n }\n}\n"],"mappings":"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"}
|
|
@@ -97,15 +97,28 @@ declare class ChatOpenRouter extends BaseChatModel<ChatOpenRouterCallOptions, AI
|
|
|
97
97
|
/**
|
|
98
98
|
* Application URL for OpenRouter attribution. Maps to `HTTP-Referer` header.
|
|
99
99
|
*
|
|
100
|
+
* Defaults to LangChain docs URL. Set this to your app's URL to get
|
|
101
|
+
* attribution for API usage in the OpenRouter dashboard.
|
|
102
|
+
*
|
|
100
103
|
* See https://openrouter.ai/docs/app-attribution for details.
|
|
101
104
|
*/
|
|
102
105
|
siteUrl: string;
|
|
103
106
|
/**
|
|
104
107
|
* Application title for OpenRouter attribution. Maps to `X-Title` header.
|
|
105
108
|
*
|
|
109
|
+
* Defaults to `'LangChain'`. Set this to your app's name to get attribution
|
|
110
|
+
* for API usage in the OpenRouter dashboard.
|
|
111
|
+
*
|
|
106
112
|
* See https://openrouter.ai/docs/app-attribution for details.
|
|
107
113
|
*/
|
|
108
114
|
siteName: string;
|
|
115
|
+
/**
|
|
116
|
+
* Marketplace categories for OpenRouter attribution.
|
|
117
|
+
* Maps to `X-OpenRouter-Categories` header.
|
|
118
|
+
*
|
|
119
|
+
* See https://openrouter.ai/docs/app-attribution for recognized categories.
|
|
120
|
+
*/
|
|
121
|
+
appCategories?: string[];
|
|
109
122
|
/** Extra params passed through to the API body. */
|
|
110
123
|
modelKwargs?: Record<string, unknown>;
|
|
111
124
|
/** Whether to include token usage in streaming chunks. Defaults to `true`. */
|
|
@@ -115,7 +128,7 @@ declare class ChatOpenRouter extends BaseChatModel<ChatOpenRouterCallOptions, AI
|
|
|
115
128
|
_llmType(): string;
|
|
116
129
|
/** Static capability profile (context size, tool support, etc.) for the current model. */
|
|
117
130
|
get profile(): ModelProfile;
|
|
118
|
-
/** Builds auth + content-type headers, plus optional
|
|
131
|
+
/** Builds auth + content-type headers, plus optional attribution headers. */
|
|
119
132
|
private buildHeaders;
|
|
120
133
|
/** Returns the full chat-completions endpoint URL. */
|
|
121
134
|
private buildUrl;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/chat_models/index.ts"],"mappings":";;;;;;;;;;;;;;;;;AAgCkD;;;;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;;;;;;;;;cAoCW,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;
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/chat_models/index.ts"],"mappings":"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"}
|
|
@@ -97,15 +97,28 @@ declare class ChatOpenRouter extends BaseChatModel<ChatOpenRouterCallOptions, AI
|
|
|
97
97
|
/**
|
|
98
98
|
* Application URL for OpenRouter attribution. Maps to `HTTP-Referer` header.
|
|
99
99
|
*
|
|
100
|
+
* Defaults to LangChain docs URL. Set this to your app's URL to get
|
|
101
|
+
* attribution for API usage in the OpenRouter dashboard.
|
|
102
|
+
*
|
|
100
103
|
* See https://openrouter.ai/docs/app-attribution for details.
|
|
101
104
|
*/
|
|
102
105
|
siteUrl: string;
|
|
103
106
|
/**
|
|
104
107
|
* Application title for OpenRouter attribution. Maps to `X-Title` header.
|
|
105
108
|
*
|
|
109
|
+
* Defaults to `'LangChain'`. Set this to your app's name to get attribution
|
|
110
|
+
* for API usage in the OpenRouter dashboard.
|
|
111
|
+
*
|
|
106
112
|
* See https://openrouter.ai/docs/app-attribution for details.
|
|
107
113
|
*/
|
|
108
114
|
siteName: string;
|
|
115
|
+
/**
|
|
116
|
+
* Marketplace categories for OpenRouter attribution.
|
|
117
|
+
* Maps to `X-OpenRouter-Categories` header.
|
|
118
|
+
*
|
|
119
|
+
* See https://openrouter.ai/docs/app-attribution for recognized categories.
|
|
120
|
+
*/
|
|
121
|
+
appCategories?: string[];
|
|
109
122
|
/** Extra params passed through to the API body. */
|
|
110
123
|
modelKwargs?: Record<string, unknown>;
|
|
111
124
|
/** Whether to include token usage in streaming chunks. Defaults to `true`. */
|
|
@@ -115,7 +128,7 @@ declare class ChatOpenRouter extends BaseChatModel<ChatOpenRouterCallOptions, AI
|
|
|
115
128
|
_llmType(): string;
|
|
116
129
|
/** Static capability profile (context size, tool support, etc.) for the current model. */
|
|
117
130
|
get profile(): ModelProfile;
|
|
118
|
-
/** Builds auth + content-type headers, plus optional
|
|
131
|
+
/** Builds auth + content-type headers, plus optional attribution headers. */
|
|
119
132
|
private buildHeaders;
|
|
120
133
|
/** Returns the full chat-completions endpoint URL. */
|
|
121
134
|
private buildUrl;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/chat_models/index.ts"],"mappings":";;;;;;;;;;;;;;;;;AAgCkD;;;;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;;;;;;;;;cAoCW,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;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/chat_models/index.ts"],"mappings":"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"}
|
|
@@ -113,15 +113,28 @@ var ChatOpenRouter = class extends BaseChatModel {
|
|
|
113
113
|
/**
|
|
114
114
|
* Application URL for OpenRouter attribution. Maps to `HTTP-Referer` header.
|
|
115
115
|
*
|
|
116
|
+
* Defaults to LangChain docs URL. Set this to your app's URL to get
|
|
117
|
+
* attribution for API usage in the OpenRouter dashboard.
|
|
118
|
+
*
|
|
116
119
|
* See https://openrouter.ai/docs/app-attribution for details.
|
|
117
120
|
*/
|
|
118
121
|
siteUrl;
|
|
119
122
|
/**
|
|
120
123
|
* Application title for OpenRouter attribution. Maps to `X-Title` header.
|
|
121
124
|
*
|
|
125
|
+
* Defaults to `'LangChain'`. Set this to your app's name to get attribution
|
|
126
|
+
* for API usage in the OpenRouter dashboard.
|
|
127
|
+
*
|
|
122
128
|
* See https://openrouter.ai/docs/app-attribution for details.
|
|
123
129
|
*/
|
|
124
130
|
siteName;
|
|
131
|
+
/**
|
|
132
|
+
* Marketplace categories for OpenRouter attribution.
|
|
133
|
+
* Maps to `X-OpenRouter-Categories` header.
|
|
134
|
+
*
|
|
135
|
+
* See https://openrouter.ai/docs/app-attribution for recognized categories.
|
|
136
|
+
*/
|
|
137
|
+
appCategories;
|
|
125
138
|
/** Extra params passed through to the API body. */
|
|
126
139
|
modelKwargs;
|
|
127
140
|
/** Whether to include token usage in streaming chunks. Defaults to `true`. */
|
|
@@ -132,7 +145,7 @@ var ChatOpenRouter = class extends BaseChatModel {
|
|
|
132
145
|
model: modelOrFields
|
|
133
146
|
} : modelOrFields;
|
|
134
147
|
super(fields);
|
|
135
|
-
this._addVersion("@langchain/openrouter", "0.1
|
|
148
|
+
this._addVersion("@langchain/openrouter", "0.2.1");
|
|
136
149
|
const apiKey = fields.apiKey ?? getEnvironmentVariable("OPENROUTER_API_KEY");
|
|
137
150
|
if (!apiKey) throw new OpenRouterAuthError("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.");
|
|
138
151
|
this.apiKey = apiKey;
|
|
@@ -158,8 +171,9 @@ var ChatOpenRouter = class extends BaseChatModel {
|
|
|
158
171
|
this.route = fields.route;
|
|
159
172
|
this.provider = fields.provider;
|
|
160
173
|
this.plugins = fields.plugins;
|
|
161
|
-
this.siteUrl = fields.siteUrl ?? "https://docs.langchain.com
|
|
162
|
-
this.siteName = fields.siteName ?? "
|
|
174
|
+
this.siteUrl = fields.siteUrl ?? "https://docs.langchain.com";
|
|
175
|
+
this.siteName = fields.siteName ?? "LangChain";
|
|
176
|
+
this.appCategories = fields.appCategories;
|
|
163
177
|
this.modelKwargs = fields.modelKwargs;
|
|
164
178
|
this.streamUsage = fields.streamUsage ?? true;
|
|
165
179
|
}
|
|
@@ -170,14 +184,16 @@ var ChatOpenRouter = class extends BaseChatModel {
|
|
|
170
184
|
get profile() {
|
|
171
185
|
return PROFILES[this.model] ?? {};
|
|
172
186
|
}
|
|
173
|
-
/** Builds auth + content-type headers, plus optional
|
|
187
|
+
/** Builds auth + content-type headers, plus optional attribution headers. */
|
|
174
188
|
buildHeaders() {
|
|
175
|
-
|
|
189
|
+
const headers = {
|
|
176
190
|
Authorization: `Bearer ${this.apiKey}`,
|
|
177
|
-
"Content-Type": "application/json"
|
|
178
|
-
"HTTP-Referer": this.siteUrl,
|
|
179
|
-
"X-Title": this.siteName
|
|
191
|
+
"Content-Type": "application/json"
|
|
180
192
|
};
|
|
193
|
+
if (this.siteUrl) headers["HTTP-Referer"] = this.siteUrl;
|
|
194
|
+
if (this.siteName) headers["X-Title"] = this.siteName;
|
|
195
|
+
if (this.appCategories && this.appCategories.length > 0) headers["X-OpenRouter-Categories"] = this.appCategories.join(",");
|
|
196
|
+
return headers;
|
|
181
197
|
}
|
|
182
198
|
/** Returns the full chat-completions endpoint URL. */
|
|
183
199
|
buildUrl() {
|
|
@@ -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 { Runnable } from \"@langchain/core/runnables\";\nimport { toJsonSchema } from \"@langchain/core/utils/json_schema\";\nimport {\n type InteropZodType,\n getSchemaDescription,\n isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\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\";\nimport {\n isSerializableSchema,\n SerializableSchema,\n} from \"@langchain/core/utils/standard_schema\";\nimport {\n assembleStructuredOutputPipeline,\n createContentParser,\n createFunctionCallingParser,\n} from \"@langchain/core/language_models/structured_output\";\n\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(model: string, fields?: Omit<ChatOpenRouterParams, \"model\">);\n constructor(fields: ChatOpenRouterParams);\n constructor(\n modelOrFields: string | ChatOpenRouterParams,\n fieldsArg?: Omit<ChatOpenRouterParams, \"model\">\n ) {\n const fields =\n typeof modelOrFields === \"string\"\n ? { ...(fieldsArg ?? {}), model: modelOrFields }\n : modelOrFields;\n super(fields);\n this._addVersion(\"@langchain/openrouter\", __PKG_VERSION__);\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(\n text,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: generationChunk }\n );\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 | SerializableSchema<RunOutput>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<false>\n ): Runnable<BaseLanguageModelInput, RunOutput>;\n\n withStructuredOutput<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n | SerializableSchema<RunOutput>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<true>\n ): Runnable<BaseLanguageModelInput, { raw: BaseMessage; parsed: RunOutput }>;\n\n withStructuredOutput<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n | SerializableSchema<RunOutput>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<boolean>\n ):\n | Runnable<BaseLanguageModelInput, RunOutput>\n | Runnable<BaseLanguageModelInput, { raw: BaseMessage; parsed: RunOutput }>;\n\n withStructuredOutput<\n RunOutput extends Record<string, unknown> = Record<string, unknown>\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n | SerializableSchema<RunOutput>\n | 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 = createContentParser(schema);\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 outputParser = createContentParser(schema);\n } else {\n let functionName = name ?? \"extract\";\n if (\n !isInteropZodSchema(schema) &&\n !isSerializableSchema(schema) &&\n \"name\" in (schema as Record<string, unknown>)\n ) {\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 = createFunctionCallingParser(schema, functionName);\n }\n\n return assembleStructuredOutputPipeline(\n llm,\n outputParser,\n includeRaw,\n \"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 { Runnable } from \"@langchain/core/runnables\";\nimport { toJsonSchema } from \"@langchain/core/utils/json_schema\";\nimport {\n type InteropZodType,\n getSchemaDescription,\n isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\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\";\nimport {\n isSerializableSchema,\n SerializableSchema,\n} from \"@langchain/core/utils/standard_schema\";\nimport {\n assembleStructuredOutputPipeline,\n createContentParser,\n createFunctionCallingParser,\n} from \"@langchain/core/language_models/structured_output\";\n\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 * Defaults to LangChain docs URL. Set this to your app's URL to get\n * attribution for API usage in the OpenRouter dashboard.\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 * Defaults to `'LangChain'`. Set this to your app's name to get attribution\n * for API usage in the OpenRouter dashboard.\n *\n * See https://openrouter.ai/docs/app-attribution for details.\n */\n siteName: string;\n\n /**\n * Marketplace categories for OpenRouter attribution.\n * Maps to `X-OpenRouter-Categories` header.\n *\n * See https://openrouter.ai/docs/app-attribution for recognized categories.\n */\n appCategories?: 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(model: string, fields?: Omit<ChatOpenRouterParams, \"model\">);\n constructor(fields: ChatOpenRouterParams);\n constructor(\n modelOrFields: string | ChatOpenRouterParams,\n fieldsArg?: Omit<ChatOpenRouterParams, \"model\">\n ) {\n const fields =\n typeof modelOrFields === \"string\"\n ? { ...(fieldsArg ?? {}), model: modelOrFields }\n : modelOrFields;\n super(fields);\n this._addVersion(\"@langchain/openrouter\", __PKG_VERSION__);\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\";\n this.siteName = fields.siteName ?? \"LangChain\";\n this.appCategories = fields.appCategories;\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 attribution headers. */\n private buildHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n };\n if (this.siteUrl) {\n headers[\"HTTP-Referer\"] = this.siteUrl;\n }\n if (this.siteName) {\n headers[\"X-Title\"] = this.siteName;\n }\n if (this.appCategories && this.appCategories.length > 0) {\n headers[\"X-OpenRouter-Categories\"] = this.appCategories.join(\",\");\n }\n return headers;\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(\n text,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: generationChunk }\n );\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 // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>,\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n | SerializableSchema<RunOutput>\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<false>\n ): Runnable<BaseLanguageModelInput, RunOutput>;\n\n withStructuredOutput<\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>,\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n | SerializableSchema<RunOutput>\n // oxlint-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 // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>,\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n | SerializableSchema<RunOutput>\n // oxlint-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:\n | InteropZodType<RunOutput>\n | SerializableSchema<RunOutput>\n | 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 = createContentParser(schema);\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 outputParser = createContentParser(schema);\n } else {\n let functionName = name ?? \"extract\";\n if (\n !isInteropZodSchema(schema) &&\n !isSerializableSchema(schema) &&\n \"name\" in (schema as Record<string, unknown>)\n ) {\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 = createFunctionCallingParser(schema, functionName);\n }\n\n return assembleStructuredOutputPipeline(\n llm,\n outputParser,\n includeRaw,\n \"ChatOpenRouterStructuredOutput\"\n );\n }\n}\n"],"mappings":"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"}
|
|
@@ -70,11 +70,24 @@ interface ChatOpenRouterParams extends BaseChatModelParams, ChatOpenRouterFields
|
|
|
70
70
|
siteUrl?: string;
|
|
71
71
|
/**
|
|
72
72
|
* Application title for OpenRouter attribution. Maps to `X-Title` header.
|
|
73
|
-
* Defaults to `"
|
|
73
|
+
* Defaults to `"LangChain"`. Set this to your app's name to get attribution
|
|
74
|
+
* for API usage in the OpenRouter dashboard.
|
|
74
75
|
*
|
|
75
76
|
* See https://openrouter.ai/docs/app-attribution for details.
|
|
76
77
|
*/
|
|
77
78
|
siteName?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Marketplace categories for OpenRouter attribution.
|
|
81
|
+
* Maps to `X-OpenRouter-Categories` header. Pass a list of lowercase,
|
|
82
|
+
* hyphen-separated category strings (max 30 characters each),
|
|
83
|
+
* e.g. `['cli-agent', 'programming-app']`.
|
|
84
|
+
*
|
|
85
|
+
* Only recognized categories are accepted (unrecognized values are silently
|
|
86
|
+
* dropped by OpenRouter).
|
|
87
|
+
*
|
|
88
|
+
* See https://openrouter.ai/docs/app-attribution for recognized categories.
|
|
89
|
+
*/
|
|
90
|
+
appCategories?: string[];
|
|
78
91
|
/** Stable identifier for end-users, used for abuse detection. */
|
|
79
92
|
user?: string;
|
|
80
93
|
/** Extra params passed through to the API body. */
|
|
@@ -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;
|
|
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;EA8CR;EA5Cd,OAAA,GAAU,gBAAA;AAAA;;;;UAMK,oBAAA,SACP,mBAAA,EAAqB,oBAAA;EAE7B;EAAA,KAAA;EAIA;EAFA,MAAA;EAiBA;EAfA,OAAA;EA6BA;;;;;;EAtBA,OAAA;EAiCA;;;;;;;EAzBA,QAAA;EAyBsD;;;;;;;;;;;EAbtD,aAAA;EAyBA;EAvBA,IAAA;EAuBoB;EArBpB,WAAA,GAAc,MAAA;;EAEd,WAAA;AAAA;;;;UAMe,yBAAA,SACP,wBAAA,EAA0B,oBAAA;;EAElC,KAAA,GAAQ,cAAA;;EAER,eAAA,GAAkB,wBAAA;;EAElB,MAAA;;EAEA,UAAA;IAAe,IAAA;IAAiB,OAAA;EAAA;;EAEhC,IAAA;;EAEA,MAAA,GAAS,WAAA;AAAA"}
|
|
@@ -70,11 +70,24 @@ interface ChatOpenRouterParams extends BaseChatModelParams, ChatOpenRouterFields
|
|
|
70
70
|
siteUrl?: string;
|
|
71
71
|
/**
|
|
72
72
|
* Application title for OpenRouter attribution. Maps to `X-Title` header.
|
|
73
|
-
* Defaults to `"
|
|
73
|
+
* Defaults to `"LangChain"`. Set this to your app's name to get attribution
|
|
74
|
+
* for API usage in the OpenRouter dashboard.
|
|
74
75
|
*
|
|
75
76
|
* See https://openrouter.ai/docs/app-attribution for details.
|
|
76
77
|
*/
|
|
77
78
|
siteName?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Marketplace categories for OpenRouter attribution.
|
|
81
|
+
* Maps to `X-OpenRouter-Categories` header. Pass a list of lowercase,
|
|
82
|
+
* hyphen-separated category strings (max 30 characters each),
|
|
83
|
+
* e.g. `['cli-agent', 'programming-app']`.
|
|
84
|
+
*
|
|
85
|
+
* Only recognized categories are accepted (unrecognized values are silently
|
|
86
|
+
* dropped by OpenRouter).
|
|
87
|
+
*
|
|
88
|
+
* See https://openrouter.ai/docs/app-attribution for recognized categories.
|
|
89
|
+
*/
|
|
90
|
+
appCategories?: string[];
|
|
78
91
|
/** Stable identifier for end-users, used for abuse detection. */
|
|
79
92
|
user?: string;
|
|
80
93
|
/** Extra params passed through to the API body. */
|
|
@@ -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;
|
|
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;EA8CR;EA5Cd,OAAA,GAAU,gBAAA;AAAA;;;;UAMK,oBAAA,SACP,mBAAA,EAAqB,oBAAA;EAE7B;EAAA,KAAA;EAIA;EAFA,MAAA;EAiBA;EAfA,OAAA;EA6BA;;;;;;EAtBA,OAAA;EAiCA;;;;;;;EAzBA,QAAA;EAyBsD;;;;;;;;;;;EAbtD,aAAA;EAyBA;EAvBA,IAAA;EAuBoB;EArBpB,WAAA,GAAc,MAAA;;EAEd,WAAA;AAAA;;;;UAMe,yBAAA,SACP,wBAAA,EAA0B,oBAAA;;EAElC,KAAA,GAAQ,cAAA;;EAER,eAAA,GAAkB,wBAAA;;EAElB,MAAA;;EAEA,UAAA;IAAe,IAAA;IAAiB,OAAA;EAAA;;EAEhC,IAAA;;EAEA,MAAA,GAAS,WAAA;AAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.cjs","names":["baseNs","LangChainError"],"sources":["../../src/utils/errors.ts"],"sourcesContent":["import { ns as baseNs, LangChainError } from \"@langchain/core/errors\";\n\nconst ns = baseNs.sub(\"openrouter\");\n\n/**\n * Base error for all OpenRouter API errors.\n *\n * Subclasses ({@link OpenRouterAuthError}, {@link OpenRouterRateLimitError})\n * represent specific failure modes. Use the static {@link fromResponse}\n * factory to let the library pick the right subclass from an HTTP response,\n * or throw this class directly for generic API failures.\n *\n * Type-check errors with `OpenRouterError.isInstance(err)` rather than\n * `instanceof` — this avoids cross-realm / duplicate-package pitfalls.\n */\nexport class OpenRouterError extends ns.brand(LangChainError) {\n readonly name: string = \"OpenRouterError\";\n\n /** HTTP or API error code, if available. */\n code?: number;\n\n /** Additional error metadata returned by the API, if available. */\n metadata?: Record<string, unknown>;\n\n constructor(\n message: string,\n code?: number,\n metadata?: Record<string, unknown>\n ) {\n super(message);\n this.code = code;\n this.metadata = metadata;\n }\n\n /**\n * Creates a typed error from an HTTP `Response`.\n *\n * Attempts to parse the body as JSON (OpenRouter's standard\n * `{ error: { message, code, metadata } }` shape). Falls back to the\n * raw HTTP status text when the body is missing or unparseable.\n *\n * Status-code mapping:\n * - 401 / 403 -> {@link OpenRouterAuthError}\n * - 429 -> {@link OpenRouterRateLimitError}\n * - anything else -> {@link OpenRouterError}\n */\n static async fromResponse(response: Response): Promise<OpenRouterError> {\n let body: Record<string, unknown> = {};\n try {\n body = (await response.json()) as Record<string, unknown>;\n } catch {\n // response may not be JSON\n }\n\n const error = body?.error as\n | { message?: string; code?: number; metadata?: Record<string, unknown> }\n | undefined;\n\n const baseMessage =\n error?.message ?? `HTTP ${response.status}: ${response.statusText}`;\n const metadataStr = error?.metadata\n ? ` | metadata: ${JSON.stringify(error.metadata)}`\n : \"\";\n const message = `${baseMessage}${metadataStr}`;\n const code = error?.code ?? response.status;\n\n if (response.status === 401 || response.status === 403) {\n //
|
|
1
|
+
{"version":3,"file":"errors.cjs","names":["baseNs","LangChainError"],"sources":["../../src/utils/errors.ts"],"sourcesContent":["import { ns as baseNs, LangChainError } from \"@langchain/core/errors\";\n\nconst ns = baseNs.sub(\"openrouter\");\n\n/**\n * Base error for all OpenRouter API errors.\n *\n * Subclasses ({@link OpenRouterAuthError}, {@link OpenRouterRateLimitError})\n * represent specific failure modes. Use the static {@link fromResponse}\n * factory to let the library pick the right subclass from an HTTP response,\n * or throw this class directly for generic API failures.\n *\n * Type-check errors with `OpenRouterError.isInstance(err)` rather than\n * `instanceof` — this avoids cross-realm / duplicate-package pitfalls.\n */\nexport class OpenRouterError extends ns.brand(LangChainError) {\n readonly name: string = \"OpenRouterError\";\n\n /** HTTP or API error code, if available. */\n code?: number;\n\n /** Additional error metadata returned by the API, if available. */\n metadata?: Record<string, unknown>;\n\n constructor(\n message: string,\n code?: number,\n metadata?: Record<string, unknown>\n ) {\n super(message);\n this.code = code;\n this.metadata = metadata;\n }\n\n /**\n * Creates a typed error from an HTTP `Response`.\n *\n * Attempts to parse the body as JSON (OpenRouter's standard\n * `{ error: { message, code, metadata } }` shape). Falls back to the\n * raw HTTP status text when the body is missing or unparseable.\n *\n * Status-code mapping:\n * - 401 / 403 -> {@link OpenRouterAuthError}\n * - 429 -> {@link OpenRouterRateLimitError}\n * - anything else -> {@link OpenRouterError}\n */\n static async fromResponse(response: Response): Promise<OpenRouterError> {\n let body: Record<string, unknown> = {};\n try {\n body = (await response.json()) as Record<string, unknown>;\n } catch {\n // response may not be JSON\n }\n\n const error = body?.error as\n | { message?: string; code?: number; metadata?: Record<string, unknown> }\n | undefined;\n\n const baseMessage =\n error?.message ?? `HTTP ${response.status}: ${response.statusText}`;\n const metadataStr = error?.metadata\n ? ` | metadata: ${JSON.stringify(error.metadata)}`\n : \"\";\n const message = `${baseMessage}${metadataStr}`;\n const code = error?.code ?? response.status;\n\n if (response.status === 401 || response.status === 403) {\n // oxlint-disable-next-line @typescript-eslint/no-use-before-define\n return new OpenRouterAuthError(message, code, error?.metadata);\n }\n if (response.status === 429) {\n // oxlint-disable-next-line @typescript-eslint/no-use-before-define\n return new OpenRouterRateLimitError(message, code, error?.metadata);\n }\n\n return new OpenRouterError(message, code, error?.metadata);\n }\n}\n\n/**\n * Thrown on authentication or authorization failures.\n *\n * Created automatically by {@link OpenRouterError.fromResponse} for\n * HTTP 401/403 responses, and thrown directly by the constructor when\n * no API key is provided.\n */\nexport class OpenRouterAuthError extends ns.brand(OpenRouterError, \"auth\") {\n readonly name = \"OpenRouterAuthError\";\n\n constructor(\n message: string,\n code?: number,\n metadata?: Record<string, unknown>\n ) {\n super(message, code, metadata);\n }\n}\n\n/**\n * Thrown when the API returns HTTP 429 (Too Many Requests).\n *\n * Callers can catch this specifically to implement back-off / retry\n * logic without catching unrelated API errors.\n */\nexport class OpenRouterRateLimitError extends ns.brand(\n OpenRouterError,\n \"rate_limit\"\n) {\n readonly name = \"OpenRouterRateLimitError\";\n\n constructor(\n message: string,\n code?: number,\n metadata?: Record<string, unknown>\n ) {\n super(message, code, metadata);\n }\n}\n"],"mappings":";;AAEA,MAAM,KAAKA,uBAAAA,GAAO,IAAI,aAAa;;;;;;;;;;;;AAanC,IAAa,kBAAb,MAAa,wBAAwB,GAAG,MAAMC,uBAAAA,eAAe,CAAC;CAC5D,OAAwB;;CAGxB;;CAGA;CAEA,YACE,SACA,MACA,UACA;AACA,QAAM,QAAQ;AACd,OAAK,OAAO;AACZ,OAAK,WAAW;;;;;;;;;;;;;;CAelB,aAAa,aAAa,UAA8C;EACtE,IAAI,OAAgC,EAAE;AACtC,MAAI;AACF,UAAQ,MAAM,SAAS,MAAM;UACvB;EAIR,MAAM,QAAQ,MAAM;EASpB,MAAM,UAAU,GAJd,OAAO,WAAW,QAAQ,SAAS,OAAO,IAAI,SAAS,eACrC,OAAO,WACvB,gBAAgB,KAAK,UAAU,MAAM,SAAS,KAC9C;EAEJ,MAAM,OAAO,OAAO,QAAQ,SAAS;AAErC,MAAI,SAAS,WAAW,OAAO,SAAS,WAAW,IAEjD,QAAO,IAAI,oBAAoB,SAAS,MAAM,OAAO,SAAS;AAEhE,MAAI,SAAS,WAAW,IAEtB,QAAO,IAAI,yBAAyB,SAAS,MAAM,OAAO,SAAS;AAGrE,SAAO,IAAI,gBAAgB,SAAS,MAAM,OAAO,SAAS;;;;;;;;;;AAW9D,IAAa,sBAAb,cAAyC,GAAG,MAAM,iBAAiB,OAAO,CAAC;CACzE,OAAgB;CAEhB,YACE,SACA,MACA,UACA;AACA,QAAM,SAAS,MAAM,SAAS;;;;;;;;;AAUlC,IAAa,2BAAb,cAA8C,GAAG,MAC/C,iBACA,aACD,CAAC;CACA,OAAgB;CAEhB,YACE,SACA,MACA,UACA;AACA,QAAM,SAAS,MAAM,SAAS"}
|
package/dist/utils/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","names":["ns","baseNs"],"sources":["../../src/utils/errors.ts"],"sourcesContent":["import { ns as baseNs, LangChainError } from \"@langchain/core/errors\";\n\nconst ns = baseNs.sub(\"openrouter\");\n\n/**\n * Base error for all OpenRouter API errors.\n *\n * Subclasses ({@link OpenRouterAuthError}, {@link OpenRouterRateLimitError})\n * represent specific failure modes. Use the static {@link fromResponse}\n * factory to let the library pick the right subclass from an HTTP response,\n * or throw this class directly for generic API failures.\n *\n * Type-check errors with `OpenRouterError.isInstance(err)` rather than\n * `instanceof` — this avoids cross-realm / duplicate-package pitfalls.\n */\nexport class OpenRouterError extends ns.brand(LangChainError) {\n readonly name: string = \"OpenRouterError\";\n\n /** HTTP or API error code, if available. */\n code?: number;\n\n /** Additional error metadata returned by the API, if available. */\n metadata?: Record<string, unknown>;\n\n constructor(\n message: string,\n code?: number,\n metadata?: Record<string, unknown>\n ) {\n super(message);\n this.code = code;\n this.metadata = metadata;\n }\n\n /**\n * Creates a typed error from an HTTP `Response`.\n *\n * Attempts to parse the body as JSON (OpenRouter's standard\n * `{ error: { message, code, metadata } }` shape). Falls back to the\n * raw HTTP status text when the body is missing or unparseable.\n *\n * Status-code mapping:\n * - 401 / 403 -> {@link OpenRouterAuthError}\n * - 429 -> {@link OpenRouterRateLimitError}\n * - anything else -> {@link OpenRouterError}\n */\n static async fromResponse(response: Response): Promise<OpenRouterError> {\n let body: Record<string, unknown> = {};\n try {\n body = (await response.json()) as Record<string, unknown>;\n } catch {\n // response may not be JSON\n }\n\n const error = body?.error as\n | { message?: string; code?: number; metadata?: Record<string, unknown> }\n | undefined;\n\n const baseMessage =\n error?.message ?? `HTTP ${response.status}: ${response.statusText}`;\n const metadataStr = error?.metadata\n ? ` | metadata: ${JSON.stringify(error.metadata)}`\n : \"\";\n const message = `${baseMessage}${metadataStr}`;\n const code = error?.code ?? response.status;\n\n if (response.status === 401 || response.status === 403) {\n //
|
|
1
|
+
{"version":3,"file":"errors.js","names":["ns","baseNs"],"sources":["../../src/utils/errors.ts"],"sourcesContent":["import { ns as baseNs, LangChainError } from \"@langchain/core/errors\";\n\nconst ns = baseNs.sub(\"openrouter\");\n\n/**\n * Base error for all OpenRouter API errors.\n *\n * Subclasses ({@link OpenRouterAuthError}, {@link OpenRouterRateLimitError})\n * represent specific failure modes. Use the static {@link fromResponse}\n * factory to let the library pick the right subclass from an HTTP response,\n * or throw this class directly for generic API failures.\n *\n * Type-check errors with `OpenRouterError.isInstance(err)` rather than\n * `instanceof` — this avoids cross-realm / duplicate-package pitfalls.\n */\nexport class OpenRouterError extends ns.brand(LangChainError) {\n readonly name: string = \"OpenRouterError\";\n\n /** HTTP or API error code, if available. */\n code?: number;\n\n /** Additional error metadata returned by the API, if available. */\n metadata?: Record<string, unknown>;\n\n constructor(\n message: string,\n code?: number,\n metadata?: Record<string, unknown>\n ) {\n super(message);\n this.code = code;\n this.metadata = metadata;\n }\n\n /**\n * Creates a typed error from an HTTP `Response`.\n *\n * Attempts to parse the body as JSON (OpenRouter's standard\n * `{ error: { message, code, metadata } }` shape). Falls back to the\n * raw HTTP status text when the body is missing or unparseable.\n *\n * Status-code mapping:\n * - 401 / 403 -> {@link OpenRouterAuthError}\n * - 429 -> {@link OpenRouterRateLimitError}\n * - anything else -> {@link OpenRouterError}\n */\n static async fromResponse(response: Response): Promise<OpenRouterError> {\n let body: Record<string, unknown> = {};\n try {\n body = (await response.json()) as Record<string, unknown>;\n } catch {\n // response may not be JSON\n }\n\n const error = body?.error as\n | { message?: string; code?: number; metadata?: Record<string, unknown> }\n | undefined;\n\n const baseMessage =\n error?.message ?? `HTTP ${response.status}: ${response.statusText}`;\n const metadataStr = error?.metadata\n ? ` | metadata: ${JSON.stringify(error.metadata)}`\n : \"\";\n const message = `${baseMessage}${metadataStr}`;\n const code = error?.code ?? response.status;\n\n if (response.status === 401 || response.status === 403) {\n // oxlint-disable-next-line @typescript-eslint/no-use-before-define\n return new OpenRouterAuthError(message, code, error?.metadata);\n }\n if (response.status === 429) {\n // oxlint-disable-next-line @typescript-eslint/no-use-before-define\n return new OpenRouterRateLimitError(message, code, error?.metadata);\n }\n\n return new OpenRouterError(message, code, error?.metadata);\n }\n}\n\n/**\n * Thrown on authentication or authorization failures.\n *\n * Created automatically by {@link OpenRouterError.fromResponse} for\n * HTTP 401/403 responses, and thrown directly by the constructor when\n * no API key is provided.\n */\nexport class OpenRouterAuthError extends ns.brand(OpenRouterError, \"auth\") {\n readonly name = \"OpenRouterAuthError\";\n\n constructor(\n message: string,\n code?: number,\n metadata?: Record<string, unknown>\n ) {\n super(message, code, metadata);\n }\n}\n\n/**\n * Thrown when the API returns HTTP 429 (Too Many Requests).\n *\n * Callers can catch this specifically to implement back-off / retry\n * logic without catching unrelated API errors.\n */\nexport class OpenRouterRateLimitError extends ns.brand(\n OpenRouterError,\n \"rate_limit\"\n) {\n readonly name = \"OpenRouterRateLimitError\";\n\n constructor(\n message: string,\n code?: number,\n metadata?: Record<string, unknown>\n ) {\n super(message, code, metadata);\n }\n}\n"],"mappings":";;AAEA,MAAMA,OAAKC,GAAO,IAAI,aAAa;;;;;;;;;;;;AAanC,IAAa,kBAAb,MAAa,wBAAwBD,KAAG,MAAM,eAAe,CAAC;CAC5D,OAAwB;;CAGxB;;CAGA;CAEA,YACE,SACA,MACA,UACA;AACA,QAAM,QAAQ;AACd,OAAK,OAAO;AACZ,OAAK,WAAW;;;;;;;;;;;;;;CAelB,aAAa,aAAa,UAA8C;EACtE,IAAI,OAAgC,EAAE;AACtC,MAAI;AACF,UAAQ,MAAM,SAAS,MAAM;UACvB;EAIR,MAAM,QAAQ,MAAM;EASpB,MAAM,UAAU,GAJd,OAAO,WAAW,QAAQ,SAAS,OAAO,IAAI,SAAS,eACrC,OAAO,WACvB,gBAAgB,KAAK,UAAU,MAAM,SAAS,KAC9C;EAEJ,MAAM,OAAO,OAAO,QAAQ,SAAS;AAErC,MAAI,SAAS,WAAW,OAAO,SAAS,WAAW,IAEjD,QAAO,IAAI,oBAAoB,SAAS,MAAM,OAAO,SAAS;AAEhE,MAAI,SAAS,WAAW,IAEtB,QAAO,IAAI,yBAAyB,SAAS,MAAM,OAAO,SAAS;AAGrE,SAAO,IAAI,gBAAgB,SAAS,MAAM,OAAO,SAAS;;;;;;;;;;AAW9D,IAAa,sBAAb,cAAyCA,KAAG,MAAM,iBAAiB,OAAO,CAAC;CACzE,OAAgB;CAEhB,YACE,SACA,MACA,UACA;AACA,QAAM,SAAS,MAAM,SAAS;;;;;;;;;AAUlC,IAAa,2BAAb,cAA8CA,KAAG,MAC/C,iBACA,aACD,CAAC;CACA,OAAgB;CAEhB,YACE,SACA,MACA,UACA;AACA,QAAM,SAAS,MAAM,SAAS"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@langchain/openrouter",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
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.4.
|
|
19
|
+
"@langchain/openai": "1.4.3"
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|
|
22
22
|
"@langchain/core": "^1.0.0"
|
|
@@ -24,16 +24,13 @@
|
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@tsconfig/recommended": "^1.0.10",
|
|
26
26
|
"dpdm": "^3.14.0",
|
|
27
|
-
"eslint": "^9.34.0",
|
|
28
|
-
"prettier": "^2.8.3",
|
|
29
27
|
"sparktype": "^0.1.3",
|
|
30
28
|
"typescript": "~5.8.3",
|
|
31
|
-
"vitest": "^
|
|
29
|
+
"vitest": "^4.1.2",
|
|
32
30
|
"zod": "^3.25.76 || ^4",
|
|
33
|
-
"zod-to-json-schema": "^3.
|
|
34
|
-
"@langchain/core": "^1.1.
|
|
35
|
-
"@langchain/
|
|
36
|
-
"@langchain/openai": "^1.4.1",
|
|
31
|
+
"zod-to-json-schema": "^3.25.2",
|
|
32
|
+
"@langchain/core": "^1.1.39",
|
|
33
|
+
"@langchain/openai": "^1.4.3",
|
|
37
34
|
"@langchain/standard-tests": "0.0.23"
|
|
38
35
|
},
|
|
39
36
|
"publishConfig": {
|
|
@@ -65,10 +62,6 @@
|
|
|
65
62
|
"scripts": {
|
|
66
63
|
"build": "turbo build:compile --filter @langchain/openrouter --output-logs new-only",
|
|
67
64
|
"build:compile": "tsdown",
|
|
68
|
-
"lint:eslint": "eslint --cache src/",
|
|
69
|
-
"lint:dpdm": "dpdm --skip-dynamic-imports circular --exit-code circular:1 --no-warning --no-tree src/**/*.ts",
|
|
70
|
-
"lint": "pnpm lint:eslint && pnpm lint:dpdm",
|
|
71
|
-
"lint:fix": "pnpm lint:eslint --fix && pnpm lint:dpdm",
|
|
72
65
|
"clean": "rm -rf .turbo dist/",
|
|
73
66
|
"test": "vitest run",
|
|
74
67
|
"test:watch": "vitest",
|
|
@@ -76,8 +69,6 @@
|
|
|
76
69
|
"test:standard:unit": "vitest run --mode standard-unit",
|
|
77
70
|
"test:standard:int": "vitest run --mode standard-int",
|
|
78
71
|
"test:standard": "pnpm test:standard:unit && pnpm test:standard:int",
|
|
79
|
-
"format": "prettier --write \"src\"",
|
|
80
|
-
"format:check": "prettier --check \"src\"",
|
|
81
72
|
"typegen": "pnpm run typegen:sparktype && pnpm run typegen:profiles",
|
|
82
73
|
"typegen:sparktype": "sparktype generate",
|
|
83
74
|
"typegen:profiles": "pnpm --filter @langchain/model-profiles make --config profiles.toml",
|