@dereekb/openrouter 13.37.0
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/LICENSE +21 -0
- package/README.md +195 -0
- package/firebase/index.cjs.default.js +1 -0
- package/firebase/index.cjs.js +666 -0
- package/firebase/index.cjs.mjs +2 -0
- package/firebase/index.d.ts +1 -0
- package/firebase/index.esm.js +626 -0
- package/firebase/package.json +25 -0
- package/firebase/src/index.d.ts +1 -0
- package/firebase/src/lib/index.d.ts +4 -0
- package/firebase/src/lib/openrouter.api.d.ts +226 -0
- package/firebase/src/lib/openrouter.id.d.ts +56 -0
- package/firebase/src/lib/openrouter.model.d.ts +609 -0
- package/firebase/src/lib/openrouter.query.d.ts +121 -0
- package/firebase-server/index.cjs.default.js +1 -0
- package/firebase-server/index.cjs.js +4520 -0
- package/firebase-server/index.cjs.mjs +2 -0
- package/firebase-server/index.d.ts +1 -0
- package/firebase-server/index.esm.js +4466 -0
- package/firebase-server/package.json +38 -0
- package/firebase-server/src/index.d.ts +1 -0
- package/firebase-server/src/lib/index.d.ts +10 -0
- package/firebase-server/src/lib/openrouter.action.server.d.ts +196 -0
- package/firebase-server/src/lib/openrouter.broadcast.d.ts +93 -0
- package/firebase-server/src/lib/openrouter.call.inline.d.ts +57 -0
- package/firebase-server/src/lib/openrouter.file.attachment.d.ts +97 -0
- package/firebase-server/src/lib/openrouter.module.d.ts +65 -0
- package/firebase-server/src/lib/openrouter.prompt.service.d.ts +109 -0
- package/firebase-server/src/lib/openrouter.runtask.handle.d.ts +56 -0
- package/firebase-server/src/lib/openrouter.runtask.service.d.ts +380 -0
- package/firebase-server/src/lib/openrouter.runtask.sweep.d.ts +170 -0
- package/firebase-server/src/lib/openrouter.state.accessor.d.ts +106 -0
- package/firebase-server/src/test/openrouter.fake.d.ts +134 -0
- package/index.cjs.default.js +1 -0
- package/index.cjs.js +1867 -0
- package/index.cjs.mjs +2 -0
- package/index.d.ts +1 -0
- package/index.esm.js +1771 -0
- package/package.json +32 -0
- package/src/index.d.ts +1 -0
- package/src/lib/index.d.ts +10 -0
- package/src/lib/openrouter.call.d.ts +268 -0
- package/src/lib/openrouter.config.d.ts +314 -0
- package/src/lib/openrouter.embedding.d.ts +87 -0
- package/src/lib/openrouter.generation.d.ts +46 -0
- package/src/lib/openrouter.input.d.ts +238 -0
- package/src/lib/openrouter.prompt.d.ts +79 -0
- package/src/lib/openrouter.request.d.ts +91 -0
- package/src/lib/openrouter.sdk.d.ts +37 -0
- package/src/lib/openrouter.tool.d.ts +99 -0
- package/src/lib/openrouter.type.d.ts +125 -0
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dereekb/openrouter",
|
|
3
|
+
"version": "13.37.0",
|
|
4
|
+
"exports": {
|
|
5
|
+
"./firebase": {
|
|
6
|
+
"module": "./firebase/index.esm.js",
|
|
7
|
+
"types": "./firebase/index.d.ts",
|
|
8
|
+
"import": "./firebase/index.cjs.mjs",
|
|
9
|
+
"default": "./firebase/index.cjs.js"
|
|
10
|
+
},
|
|
11
|
+
"./firebase-server": {
|
|
12
|
+
"module": "./firebase-server/index.esm.js",
|
|
13
|
+
"types": "./firebase-server/index.d.ts",
|
|
14
|
+
"import": "./firebase-server/index.cjs.mjs",
|
|
15
|
+
"default": "./firebase-server/index.cjs.js"
|
|
16
|
+
},
|
|
17
|
+
"./package.json": "./package.json",
|
|
18
|
+
".": {
|
|
19
|
+
"module": "./index.esm.js",
|
|
20
|
+
"types": "./index.d.ts",
|
|
21
|
+
"import": "./index.cjs.mjs",
|
|
22
|
+
"default": "./index.cjs.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"@dereekb/util": "13.37.0",
|
|
27
|
+
"@openrouter/sdk": "^1.2.26"
|
|
28
|
+
},
|
|
29
|
+
"module": "./index.esm.js",
|
|
30
|
+
"main": "./index.cjs.js",
|
|
31
|
+
"types": "./index.d.ts"
|
|
32
|
+
}
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './lib';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './openrouter.call';
|
|
2
|
+
export * from './openrouter.config';
|
|
3
|
+
export * from './openrouter.embedding';
|
|
4
|
+
export * from './openrouter.generation';
|
|
5
|
+
export * from './openrouter.input';
|
|
6
|
+
export * from './openrouter.prompt';
|
|
7
|
+
export * from './openrouter.request';
|
|
8
|
+
export * from './openrouter.sdk';
|
|
9
|
+
export * from './openrouter.tool';
|
|
10
|
+
export * from './openrouter.type';
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { type Maybe } from '@dereekb/util';
|
|
2
|
+
import { type CallModelInput, type OpenResponsesResult, type OpenRouterCore, type RequestOptions, type StateAccessor, type Tool, ModelResult } from './openrouter.sdk';
|
|
3
|
+
import { type OpenRouterHostedToolConfig, type OpenRouterModelConfig } from './openrouter.config';
|
|
4
|
+
import { type OpenRouterPromptRequest } from './openrouter.request';
|
|
5
|
+
import { type OpenRouterGenerationId, type OpenRouterRunError, type OpenRouterRunUsage } from './openrouter.type';
|
|
6
|
+
/**
|
|
7
|
+
* A model config split into the part that goes on the request and the part that controls how the
|
|
8
|
+
* request is executed.
|
|
9
|
+
*/
|
|
10
|
+
export interface OpenRouterSplitModelConfig {
|
|
11
|
+
/**
|
|
12
|
+
* The parameters to spread onto the request.
|
|
13
|
+
*/
|
|
14
|
+
readonly requestConfig: Record<string, unknown>;
|
|
15
|
+
/**
|
|
16
|
+
* Ceiling on tool-call steps, when the config set one.
|
|
17
|
+
*/
|
|
18
|
+
readonly maxSteps?: Maybe<number>;
|
|
19
|
+
/**
|
|
20
|
+
* Per-request wall-clock timeout, when the config set one.
|
|
21
|
+
*/
|
|
22
|
+
readonly requestTimeoutMs?: Maybe<number>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Splits a model config into request parameters and execution controls.
|
|
26
|
+
*
|
|
27
|
+
* Forwarding one of ours is not harmless: OpenRouter validates the request body, so leaving `maxSteps` on
|
|
28
|
+
* it risks a 400 on the whole call. Which keys are ours is expressed by naming them in a rest-destructure
|
|
29
|
+
* rather than in a list of strings, so TypeScript checks the names against
|
|
30
|
+
* {@link OpenRouterModelConfig} and a rename cannot leave a stale entry behind.
|
|
31
|
+
*
|
|
32
|
+
* @param config - The merged model config.
|
|
33
|
+
* @returns The split config.
|
|
34
|
+
*/
|
|
35
|
+
export declare function splitOpenRouterModelConfig(config: Maybe<OpenRouterModelConfig>): OpenRouterSplitModelConfig;
|
|
36
|
+
/**
|
|
37
|
+
* The hosted (server-executed) tool entries a config carries, e.g. `file_search`, `web_search`, `mcp`.
|
|
38
|
+
*
|
|
39
|
+
* These are NOT client tools and must never be handed to `callModel`: it destructures `tools` off the
|
|
40
|
+
* request and runs every entry through `convertToolsToAPIFormat`, which reads `tool.function.name` — so
|
|
41
|
+
* a hosted entry is dropped outright when no client tools are present and throws a
|
|
42
|
+
* `Cannot read properties of undefined` from inside the SDK when they are. They are dispatched instead
|
|
43
|
+
* by {@link sendOpenRouterResponsesRequest} or merged in after conversion by
|
|
44
|
+
* {@link openRouterModelResultForRequest}.
|
|
45
|
+
*
|
|
46
|
+
* @param config - The merged model config.
|
|
47
|
+
* @returns The hosted tool entries, or an empty array.
|
|
48
|
+
*
|
|
49
|
+
* @__NO_SIDE_EFFECTS__
|
|
50
|
+
*/
|
|
51
|
+
export declare function openRouterHostedTools(config: Maybe<OpenRouterModelConfig>): OpenRouterHostedToolConfig[];
|
|
52
|
+
/**
|
|
53
|
+
* A normalized result of one OpenRouter call.
|
|
54
|
+
*
|
|
55
|
+
* Deliberately flat and provider-agnostic: this is what a run task stores and what a caller reads,
|
|
56
|
+
* so it must not require the caller to walk the SDK's response union.
|
|
57
|
+
*/
|
|
58
|
+
export interface OpenRouterCallResult {
|
|
59
|
+
/**
|
|
60
|
+
* The output text.
|
|
61
|
+
*/
|
|
62
|
+
readonly outputText?: Maybe<string>;
|
|
63
|
+
/**
|
|
64
|
+
* The output parsed as JSON, when it parsed as an object.
|
|
65
|
+
*/
|
|
66
|
+
readonly outputJson?: Maybe<Record<string, unknown>>;
|
|
67
|
+
/**
|
|
68
|
+
* Generation ids produced by the call, for auditing via `getGeneration` / `listGenerationContent`.
|
|
69
|
+
*
|
|
70
|
+
* OpenRouter can reload a generation's output later, keyed by generation id — but that surface is
|
|
71
|
+
* tied to account logging settings (nothing is retained under ZDR / logging-disabled) and its
|
|
72
|
+
* retention is undocumented. Treat it as audit/debug, never the system of record.
|
|
73
|
+
*/
|
|
74
|
+
readonly generationIds: OpenRouterGenerationId[];
|
|
75
|
+
/**
|
|
76
|
+
* Token/cost usage.
|
|
77
|
+
*/
|
|
78
|
+
readonly usage?: Maybe<OpenRouterRunUsage>;
|
|
79
|
+
/**
|
|
80
|
+
* The model that actually served the request.
|
|
81
|
+
*/
|
|
82
|
+
readonly model?: Maybe<string>;
|
|
83
|
+
/**
|
|
84
|
+
* The error reported by OpenRouter, when the response carried one.
|
|
85
|
+
*/
|
|
86
|
+
readonly error?: Maybe<OpenRouterRunError>;
|
|
87
|
+
/**
|
|
88
|
+
* The raw response, for anything the normalized shape drops.
|
|
89
|
+
*/
|
|
90
|
+
readonly response: OpenResponsesResult;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Params for {@link openRouterCallModelInput}.
|
|
94
|
+
*/
|
|
95
|
+
export interface OpenRouterCallModelInputParams<TTools extends readonly Tool[] = readonly Tool[]> {
|
|
96
|
+
/**
|
|
97
|
+
* The built request.
|
|
98
|
+
*/
|
|
99
|
+
readonly request: OpenRouterPromptRequest;
|
|
100
|
+
/**
|
|
101
|
+
* Client-side tools to make available.
|
|
102
|
+
*/
|
|
103
|
+
readonly tools?: Maybe<TTools>;
|
|
104
|
+
/**
|
|
105
|
+
* Conversation state backend, for a multi-step or deferred-tool run.
|
|
106
|
+
*/
|
|
107
|
+
readonly state?: Maybe<StateAccessor<TTools>>;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Converts a built request into the `/responses` request body.
|
|
111
|
+
*
|
|
112
|
+
* This is the whole wire body minus the SDK-only keys (`tools`/`state`/`stopWhen` on the `callModel`
|
|
113
|
+
* path), so both dispatch paths assemble the request the same way and cannot drift.
|
|
114
|
+
*
|
|
115
|
+
* @param request - The built request.
|
|
116
|
+
* @returns The request body, in the SDK's camelCase request surface.
|
|
117
|
+
*/
|
|
118
|
+
export declare function openRouterResponsesRequestBody(request: OpenRouterPromptRequest): Record<string, unknown>;
|
|
119
|
+
/**
|
|
120
|
+
* Converts a built request into the `callModel` input.
|
|
121
|
+
*
|
|
122
|
+
* Any hosted tools on the config are STRIPPED here rather than passed through: `callModel` owns the
|
|
123
|
+
* `tools` key and converts every entry as a client function tool. Hosted entries are re-attached after
|
|
124
|
+
* that conversion by {@link openRouterModelResultForRequest}.
|
|
125
|
+
*
|
|
126
|
+
* @param params - The request, tools, and state accessor.
|
|
127
|
+
* @returns The `callModel` input.
|
|
128
|
+
*/
|
|
129
|
+
export declare function openRouterCallModelInput<TTools extends readonly Tool[] = readonly Tool[]>(params: OpenRouterCallModelInputParams<TTools>): CallModelInput<TTools>;
|
|
130
|
+
/**
|
|
131
|
+
* Params for {@link callModelForOpenRouterRequest}.
|
|
132
|
+
*/
|
|
133
|
+
export interface CallModelForOpenRouterRequestParams<TTools extends readonly Tool[] = readonly Tool[]> extends OpenRouterCallModelInputParams<TTools> {
|
|
134
|
+
/**
|
|
135
|
+
* The OpenRouter client.
|
|
136
|
+
*/
|
|
137
|
+
readonly client: OpenRouterCore;
|
|
138
|
+
/**
|
|
139
|
+
* Additional request options, merged under the config's `requestTimeoutMs`.
|
|
140
|
+
*/
|
|
141
|
+
readonly options?: Maybe<RequestOptions>;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Header `callModel` stamps on every request it dispatches, so OpenRouter can tell an agent-loop request
|
|
145
|
+
* apart from a plain one. Replicated on the merged hosted-tool path, which is a `callModel` request in
|
|
146
|
+
* everything but the entry point.
|
|
147
|
+
*/
|
|
148
|
+
export declare const OPENROUTER_CALL_MODEL_HEADER = "x-openrouter-callmodel";
|
|
149
|
+
/**
|
|
150
|
+
* Params for {@link sendOpenRouterResponsesRequest}.
|
|
151
|
+
*/
|
|
152
|
+
export interface SendOpenRouterResponsesRequestParams {
|
|
153
|
+
/**
|
|
154
|
+
* The OpenRouter client.
|
|
155
|
+
*/
|
|
156
|
+
readonly client: OpenRouterCore;
|
|
157
|
+
/**
|
|
158
|
+
* The built request.
|
|
159
|
+
*/
|
|
160
|
+
readonly request: OpenRouterPromptRequest;
|
|
161
|
+
/**
|
|
162
|
+
* Additional request options, merged under the config's `requestTimeoutMs`.
|
|
163
|
+
*/
|
|
164
|
+
readonly options?: Maybe<RequestOptions>;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Sends a built request straight to `/responses`, bypassing `callModel` entirely.
|
|
168
|
+
*
|
|
169
|
+
* This is the path hosted (server-executed) tools take. `callModel` cannot carry them — it converts
|
|
170
|
+
* every `tools` entry as a client function tool — and there is nothing for its loop to do on a run whose
|
|
171
|
+
* tools are executed upstream anyway. Going direct also keeps the response VERBATIM: the request is
|
|
172
|
+
* non-streaming, so the returned `OpenResponsesResult` is the body OpenRouter sent rather than one
|
|
173
|
+
* reassembled from stream events, which is what preserves hosted-tool output items such as a
|
|
174
|
+
* `file_search_call` and the chunks `include: ['file_search_call.results']` asked for.
|
|
175
|
+
*
|
|
176
|
+
* @param params - The client, request, and options.
|
|
177
|
+
* @returns The response.
|
|
178
|
+
* @throws {Error} When the request fails, or when a streaming response comes back for a non-streaming request.
|
|
179
|
+
*/
|
|
180
|
+
export declare function sendOpenRouterResponsesRequest(params: SendOpenRouterResponsesRequestParams): Promise<OpenResponsesResult>;
|
|
181
|
+
/**
|
|
182
|
+
* Starts a call for a built request and returns the SDK's `ModelResult` without consuming it.
|
|
183
|
+
*
|
|
184
|
+
* Use this when the caller needs the streaming / tool-event surface. Most callers want
|
|
185
|
+
* {@link callModelForOpenRouterRequest}, which consumes the result into a normalized value.
|
|
186
|
+
*
|
|
187
|
+
* Hosted tools and client tools are NOT mutually exclusive here. When a config carries hosted tools this
|
|
188
|
+
* assembles the `ModelResult` itself — client tools converted to API format exactly as `callModel` would,
|
|
189
|
+
* with the hosted entries appended after that conversion — so a run can search a vector store AND drive
|
|
190
|
+
* the client-side tool loop. `callModel` cannot express that: it owns the `tools` key and there is no
|
|
191
|
+
* seam between its conversion and dispatch. Everything else about the run is unchanged, including the
|
|
192
|
+
* `x-openrouter-callmodel` header and the `stopWhen` step ceiling.
|
|
193
|
+
*
|
|
194
|
+
* @param params - The client, request, tools, state, and options.
|
|
195
|
+
* @returns The in-flight model result.
|
|
196
|
+
*/
|
|
197
|
+
export declare function openRouterModelResultForRequest<TTools extends readonly Tool[] = readonly Tool[]>(params: CallModelForOpenRouterRequestParams<TTools>): ModelResult<TTools>;
|
|
198
|
+
/**
|
|
199
|
+
* Runs a built request to completion and normalizes the response.
|
|
200
|
+
*
|
|
201
|
+
* Routes to the direct `/responses` path for a hosted-tool run that needs no client-side tool loop, and
|
|
202
|
+
* to `ModelResult` otherwise. The caller does not choose: which transport a request needs is a property
|
|
203
|
+
* of the request, and making it a parameter would only create a way to get it wrong.
|
|
204
|
+
*
|
|
205
|
+
* @param params - The client, request, tools, state, and options.
|
|
206
|
+
* @returns The normalized call result.
|
|
207
|
+
*/
|
|
208
|
+
export declare function callModelForOpenRouterRequest<TTools extends readonly Tool[] = readonly Tool[]>(params: CallModelForOpenRouterRequestParams<TTools>): Promise<OpenRouterCallResult>;
|
|
209
|
+
/**
|
|
210
|
+
* Normalizes an OpenRouter response into an {@link OpenRouterCallResult}.
|
|
211
|
+
*
|
|
212
|
+
* @param response - The response to normalize.
|
|
213
|
+
* @returns The normalized result.
|
|
214
|
+
*/
|
|
215
|
+
export declare function openRouterCallResultFromResponse(response: OpenResponsesResult): OpenRouterCallResult;
|
|
216
|
+
/**
|
|
217
|
+
* Reads the assistant text out of a response.
|
|
218
|
+
*
|
|
219
|
+
* The convenience `output_text` field is NOT populated by OpenRouter's `/responses` API — verified live,
|
|
220
|
+
* on both a streaming and a non-streaming request: the body carries `output` items (`reasoning`, then
|
|
221
|
+
* `message`) and no `output_text` at all. Reading that field alone therefore returns undefined for every
|
|
222
|
+
* real call, so a run task would store an empty `o` on a call that answered perfectly well and was
|
|
223
|
+
* charged for.
|
|
224
|
+
*
|
|
225
|
+
* Text is concatenated across ALL message items rather than just the first, since nothing guarantees a
|
|
226
|
+
* response is limited to one.
|
|
227
|
+
*
|
|
228
|
+
* @param response - The response.
|
|
229
|
+
* @returns The output text, or undefined when the response carried none.
|
|
230
|
+
*/
|
|
231
|
+
export declare function openRouterOutputTextFromResponse(response: OpenResponsesResult): Maybe<string>;
|
|
232
|
+
/**
|
|
233
|
+
* Flattens the SDK's nested usage object.
|
|
234
|
+
*
|
|
235
|
+
* A measurement the response did not report is OMITTED rather than carried as `undefined` or `null`.
|
|
236
|
+
*
|
|
237
|
+
* @param usage - The SDK usage object.
|
|
238
|
+
* @returns The flattened usage.
|
|
239
|
+
*
|
|
240
|
+
* @__NO_SIDE_EFFECTS__
|
|
241
|
+
*/
|
|
242
|
+
export declare function openRouterRunUsageFromResponseUsage(usage: NonNullable<OpenResponsesResult['usage']>): OpenRouterRunUsage;
|
|
243
|
+
/**
|
|
244
|
+
* Flattens the error an OpenRouter response reports in its body.
|
|
245
|
+
*
|
|
246
|
+
* Named rather than inlined at the one call site for the same reason
|
|
247
|
+
* {@link openRouterRunUsageFromResponseUsage} is: a library that exports `OpenRouterRunError` as a type
|
|
248
|
+
* should let a caller holding a raw `OpenResponsesResult` produce one without transcribing its shape.
|
|
249
|
+
*
|
|
250
|
+
* `code` goes through `String()` because OpenRouter reports a NUMERIC code here (the HTTP status), while
|
|
251
|
+
* `OpenRouterRunError.code` is a string — the same field an SDK-thrown error fills with `ECONNRESET`.
|
|
252
|
+
*
|
|
253
|
+
* @param error - The error reported on the response.
|
|
254
|
+
* @returns The flattened error.
|
|
255
|
+
*
|
|
256
|
+
* @__NO_SIDE_EFFECTS__
|
|
257
|
+
*/
|
|
258
|
+
export declare function openRouterRunErrorFromResponseError(error: NonNullable<OpenResponsesResult['error']>): OpenRouterRunError;
|
|
259
|
+
/**
|
|
260
|
+
* Parses model output as a JSON object.
|
|
261
|
+
*
|
|
262
|
+
* Returns undefined rather than throwing on anything that is not a JSON object: a model asked for
|
|
263
|
+
* text can and will return prose, and that is not an error.
|
|
264
|
+
*
|
|
265
|
+
* @param outputText - The output text.
|
|
266
|
+
* @returns The parsed object, or undefined when the output is not a JSON object.
|
|
267
|
+
*/
|
|
268
|
+
export declare function parseOpenRouterJsonOutput(outputText: Maybe<string>): Maybe<Record<string, unknown>>;
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import { type Maybe } from '@dereekb/util';
|
|
2
|
+
import { type OpenRouterModelId } from './openrouter.type';
|
|
3
|
+
/**
|
|
4
|
+
* Reasoning effort accepted by OpenRouter's `reasoning.effort`.
|
|
5
|
+
*/
|
|
6
|
+
export type OpenRouterReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';
|
|
7
|
+
/**
|
|
8
|
+
* Reasoning mode accepted by OpenRouter's `reasoning.mode`.
|
|
9
|
+
*/
|
|
10
|
+
export type OpenRouterReasoningMode = 'standard' | 'pro';
|
|
11
|
+
/**
|
|
12
|
+
* Reasoning summary verbosity accepted by OpenRouter's `reasoning.summary`.
|
|
13
|
+
*/
|
|
14
|
+
export type OpenRouterReasoningSummary = 'auto' | 'concise' | 'detailed';
|
|
15
|
+
/**
|
|
16
|
+
* Output verbosity accepted by OpenRouter's `text.verbosity`.
|
|
17
|
+
*
|
|
18
|
+
* This is the OpenAI-dashboard "Verbosity" control.
|
|
19
|
+
*/
|
|
20
|
+
export type OpenRouterVerbosity = 'low' | 'medium' | 'high' | 'xhigh' | 'max';
|
|
21
|
+
/**
|
|
22
|
+
* Reasoning configuration. Replaces the OpenAI dashboard's reasoning mode / effort / summary
|
|
23
|
+
* controls.
|
|
24
|
+
*/
|
|
25
|
+
export interface OpenRouterReasoningConfig {
|
|
26
|
+
readonly enabled?: Maybe<boolean>;
|
|
27
|
+
readonly effort?: Maybe<OpenRouterReasoningEffort>;
|
|
28
|
+
readonly mode?: Maybe<OpenRouterReasoningMode>;
|
|
29
|
+
readonly summary?: Maybe<OpenRouterReasoningSummary>;
|
|
30
|
+
/**
|
|
31
|
+
* Named `max_tokens` on the wire — the SDK does not camelCase this one.
|
|
32
|
+
*/
|
|
33
|
+
readonly max_tokens?: Maybe<number>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* A JSON-schema output format, replacing the OpenAI dashboard's structured-output setting.
|
|
37
|
+
*/
|
|
38
|
+
export interface OpenRouterJsonSchemaFormat {
|
|
39
|
+
readonly type: 'json_schema';
|
|
40
|
+
readonly name: string;
|
|
41
|
+
readonly strict?: Maybe<boolean>;
|
|
42
|
+
readonly schema: Record<string, unknown>;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Output format, replacing the OpenAI dashboard's "Text format" setting.
|
|
46
|
+
*/
|
|
47
|
+
export type OpenRouterTextFormat = {
|
|
48
|
+
readonly type: 'text';
|
|
49
|
+
} | {
|
|
50
|
+
readonly type: 'json_object';
|
|
51
|
+
} | OpenRouterJsonSchemaFormat;
|
|
52
|
+
/**
|
|
53
|
+
* Text/output configuration — OpenRouter's `text` object.
|
|
54
|
+
*/
|
|
55
|
+
export interface OpenRouterTextConfig {
|
|
56
|
+
readonly format?: Maybe<OpenRouterTextFormat>;
|
|
57
|
+
readonly verbosity?: Maybe<OpenRouterVerbosity>;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Provider routing configuration — OpenRouter's `provider` object.
|
|
61
|
+
*
|
|
62
|
+
* Pinning matters more than it looks: without `requireParameters`, OpenRouter's docs state
|
|
63
|
+
* "providers will receive only the parameters they support, and ignore the rest", so an unpinned
|
|
64
|
+
* call can silently drop a parameter and return a confidently wrong answer with no error.
|
|
65
|
+
*/
|
|
66
|
+
export interface OpenRouterProviderConfig {
|
|
67
|
+
readonly only?: Maybe<string[]>;
|
|
68
|
+
readonly order?: Maybe<string[]>;
|
|
69
|
+
readonly ignore?: Maybe<string[]>;
|
|
70
|
+
readonly allowFallbacks?: Maybe<boolean>;
|
|
71
|
+
readonly requireParameters?: Maybe<boolean>;
|
|
72
|
+
readonly dataCollection?: Maybe<'allow' | 'deny'>;
|
|
73
|
+
readonly sort?: Maybe<string | Record<string, unknown>>;
|
|
74
|
+
readonly quantizations?: Maybe<string[]>;
|
|
75
|
+
readonly zdr?: Maybe<boolean>;
|
|
76
|
+
readonly maxPrice?: Maybe<Record<string, string>>;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* PDF parsing engine for the `file-parser` plugin.
|
|
80
|
+
*
|
|
81
|
+
* - `native` — the model provider parses the PDF itself (OpenAI, on our BYOK key), billed as input
|
|
82
|
+
* tokens, with no image cap. ONLY valid on a model with native file input: OpenRouter forwards the
|
|
83
|
+
* raw file part upstream, and a text-only model rejects the whole request with a 400
|
|
84
|
+
* (`Provider returned error`, wrapping the provider's own `Unknown part type: file`). Verified live
|
|
85
|
+
* against `nvidia/nemotron-nano-9b-v2:free`.
|
|
86
|
+
* - `pdf-text` — OpenRouter extracts the PDF's embedded text itself. Free, and valid on EVERY model
|
|
87
|
+
* because the model only ever sees text. Yields nothing for a scanned/image-only PDF, so the model
|
|
88
|
+
* answers ungrounded with no error — which is why it is not the default.
|
|
89
|
+
* - `mistral-ocr` — Mistral's OCR service, billed by OpenRouter per page, capped at 8 images per PDF
|
|
90
|
+
* with the surplus silently dropped.
|
|
91
|
+
* - `cloudflare-ai` — Cloudflare Workers AI, free, PDF to markdown.
|
|
92
|
+
*/
|
|
93
|
+
export type OpenRouterPdfParserEngine = 'native' | 'pdf-text' | 'mistral-ocr' | 'cloudflare-ai';
|
|
94
|
+
/**
|
|
95
|
+
* The `file-parser` plugin. Replaces OpenAI's code-interpreter/file-upload path for PDF input.
|
|
96
|
+
*/
|
|
97
|
+
export interface OpenRouterFileParserPluginConfig {
|
|
98
|
+
readonly id: 'file-parser';
|
|
99
|
+
readonly enabled?: Maybe<boolean>;
|
|
100
|
+
readonly pdf?: Maybe<{
|
|
101
|
+
readonly engine?: Maybe<OpenRouterPdfParserEngine>;
|
|
102
|
+
}>;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Any OpenRouter plugin entry. Only `file-parser` is modeled precisely; the rest are passed through.
|
|
106
|
+
*/
|
|
107
|
+
export type OpenRouterPluginConfig = OpenRouterFileParserPluginConfig | ({
|
|
108
|
+
readonly id: string;
|
|
109
|
+
} & Record<string, unknown>);
|
|
110
|
+
/**
|
|
111
|
+
* A hosted (server-executed) tool entry, e.g. a `file_search` or `mcp` tool.
|
|
112
|
+
*/
|
|
113
|
+
export type OpenRouterHostedToolConfig = {
|
|
114
|
+
readonly type: string;
|
|
115
|
+
} & Record<string, unknown>;
|
|
116
|
+
/**
|
|
117
|
+
* The hosted `file_search` tool.
|
|
118
|
+
*
|
|
119
|
+
* Field names are CAMELCASE, matching the SDK's request surface rather than the wire. That is not a
|
|
120
|
+
* style choice: `@openrouter/sdk` validates the request body against a closed schema that names this
|
|
121
|
+
* field `vectorStoreIds` and remaps it to `vector_store_ids` on the way out — so a config authored with
|
|
122
|
+
* the wire name is dropped during serialization, and the call goes out with a `file_search` tool that
|
|
123
|
+
* searches nothing. OpenRouter answers it anyway, confidently and ungrounded, with no error.
|
|
124
|
+
*/
|
|
125
|
+
export interface OpenRouterFileSearchToolConfig {
|
|
126
|
+
readonly type: 'file_search';
|
|
127
|
+
/**
|
|
128
|
+
* The OpenAI vector stores to search. A `vs_…` id resolves only for the org that owns it, so this
|
|
129
|
+
* works only where OpenRouter authenticates upstream with a BYOK key from that org.
|
|
130
|
+
*
|
|
131
|
+
* The passthrough itself is verified: OpenRouter forwards the tool to OpenAI, which resolves the id.
|
|
132
|
+
* See `openrouter.filesearch.spike.spec.ts`.
|
|
133
|
+
*/
|
|
134
|
+
readonly vectorStoreIds: string[];
|
|
135
|
+
readonly maxNumResults?: Maybe<number>;
|
|
136
|
+
readonly rankingOptions?: Maybe<{
|
|
137
|
+
readonly ranker?: Maybe<string>;
|
|
138
|
+
readonly scoreThreshold?: Maybe<number>;
|
|
139
|
+
}>;
|
|
140
|
+
readonly filters?: Maybe<Record<string, unknown>>;
|
|
141
|
+
/**
|
|
142
|
+
* Passthrough for anything the hosted tool grows that this interface does not yet name.
|
|
143
|
+
*/
|
|
144
|
+
readonly [key: string]: unknown;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Builds a hosted `file_search` tool entry with the field names the SDK actually forwards.
|
|
148
|
+
*
|
|
149
|
+
* @param vectorStoreIds - The `vs_…` ids to search.
|
|
150
|
+
* @param maxNumResults - Optional cap on returned chunks.
|
|
151
|
+
* @returns The hosted tool entry.
|
|
152
|
+
*
|
|
153
|
+
* @__NO_SIDE_EFFECTS__
|
|
154
|
+
*/
|
|
155
|
+
export declare function openRouterFileSearchTool(vectorStoreIds: string[], maxNumResults?: Maybe<number>): OpenRouterFileSearchToolConfig;
|
|
156
|
+
/**
|
|
157
|
+
* The default PDF parser engine this package pins.
|
|
158
|
+
*
|
|
159
|
+
* Pinned because the alternative is silent: with no engine named, OpenRouter downgrades any model it
|
|
160
|
+
* believes lacks native file support to `mistral-ocr`, inheriting its 8-image cap and per-page billing with
|
|
161
|
+
* no error — which on a multi-page document quietly truncates content.
|
|
162
|
+
*
|
|
163
|
+
* `native` rather than the equally-free `pdf-text` because it fails LOUDLY. It requires a model with
|
|
164
|
+
* native file input and 400s on one without, where `pdf-text` would hand a scanned PDF to the model as
|
|
165
|
+
* empty text and let it answer ungrounded. A caller on a text-only model wants
|
|
166
|
+
* `openRouterFileParserPlugin('pdf-text')` — see {@link OpenRouterPdfParserEngine}.
|
|
167
|
+
*/
|
|
168
|
+
export declare const DEFAULT_OPENROUTER_PDF_PARSER_ENGINE: OpenRouterPdfParserEngine;
|
|
169
|
+
/**
|
|
170
|
+
* The `file-parser` plugin entry with the PDF engine pinned.
|
|
171
|
+
*
|
|
172
|
+
* @param engine - Engine to pin. Defaults to {@link DEFAULT_OPENROUTER_PDF_PARSER_ENGINE}.
|
|
173
|
+
* @returns The plugin config entry.
|
|
174
|
+
*
|
|
175
|
+
* @__NO_SIDE_EFFECTS__
|
|
176
|
+
*/
|
|
177
|
+
export declare function openRouterFileParserPlugin(engine?: OpenRouterPdfParserEngine): OpenRouterFileParserPluginConfig;
|
|
178
|
+
/**
|
|
179
|
+
* A provider config that pins routing to a single provider with fallbacks off and parameter support
|
|
180
|
+
* required — the configuration that makes a BYOK request actually reach the intended upstream with
|
|
181
|
+
* every parameter intact.
|
|
182
|
+
*
|
|
183
|
+
* @param provider - The provider slug to pin to (e.g. `openai`).
|
|
184
|
+
* @returns The provider routing config.
|
|
185
|
+
*
|
|
186
|
+
* @__NO_SIDE_EFFECTS__
|
|
187
|
+
*/
|
|
188
|
+
export declare function openRouterProviderPinnedTo(provider: string): OpenRouterProviderConfig;
|
|
189
|
+
/**
|
|
190
|
+
* Model configuration for an OpenRouter prompt version, or a per-run override of one.
|
|
191
|
+
*
|
|
192
|
+
* Field names follow the `@openrouter/sdk` request surface (camelCase), because a merged config is
|
|
193
|
+
* spread directly into `callModel`. The SDK converts them to the wire's snake_case names.
|
|
194
|
+
*
|
|
195
|
+
* This interface exists for autocomplete and optional call-time validation ONLY — the persisted
|
|
196
|
+
* value is passthrough JSON, deliberately not a strict Firestore converter. OpenRouter's parameter
|
|
197
|
+
* surface moves fast (the previously pinned `0.12.79` SDK was already missing several params present
|
|
198
|
+
* in `1.2.x`), and a strict converter would silently drop unknown fields on every release. Strict
|
|
199
|
+
* types in code, loose storage: hence the index signature.
|
|
200
|
+
*
|
|
201
|
+
* Concepts with no OpenRouter equivalent are deliberately absent. OpenAI's "Store logs" is one —
|
|
202
|
+
* OpenRouter is stateless and `store` is type-pinned to `false`.
|
|
203
|
+
*/
|
|
204
|
+
export interface OpenRouterModelConfig {
|
|
205
|
+
/**
|
|
206
|
+
* Primary model to route to.
|
|
207
|
+
*/
|
|
208
|
+
readonly model?: Maybe<OpenRouterModelId>;
|
|
209
|
+
/**
|
|
210
|
+
* Fallback chain, tried in order when the primary model is unavailable.
|
|
211
|
+
*/
|
|
212
|
+
readonly models?: Maybe<OpenRouterModelId[]>;
|
|
213
|
+
/**
|
|
214
|
+
* Output format + verbosity.
|
|
215
|
+
*/
|
|
216
|
+
readonly text?: Maybe<OpenRouterTextConfig>;
|
|
217
|
+
/**
|
|
218
|
+
* Reasoning mode / effort / summary.
|
|
219
|
+
*/
|
|
220
|
+
readonly reasoning?: Maybe<OpenRouterReasoningConfig>;
|
|
221
|
+
/**
|
|
222
|
+
* Provider routing — where BYOK pinning goes.
|
|
223
|
+
*/
|
|
224
|
+
readonly provider?: Maybe<OpenRouterProviderConfig>;
|
|
225
|
+
/**
|
|
226
|
+
* Plugins: `file-parser`, `web`, `context-compression`.
|
|
227
|
+
*/
|
|
228
|
+
readonly plugins?: Maybe<OpenRouterPluginConfig[]>;
|
|
229
|
+
/**
|
|
230
|
+
* Hosted (server-executed) tools, e.g. `file_search`, `mcp`, `web_search`.
|
|
231
|
+
*
|
|
232
|
+
* A config carrying any of these is dispatched off the `callModel` path — `callModel` converts every
|
|
233
|
+
* `tools` entry as a client function tool — and goes either straight to `/responses` or through a
|
|
234
|
+
* `ModelResult` that appends them after client-tool conversion. See `openRouterHostedTools`.
|
|
235
|
+
*/
|
|
236
|
+
readonly tools?: Maybe<OpenRouterHostedToolConfig[]>;
|
|
237
|
+
readonly toolChoice?: Maybe<unknown>;
|
|
238
|
+
readonly parallelToolCalls?: Maybe<boolean>;
|
|
239
|
+
readonly maxToolCalls?: Maybe<number>;
|
|
240
|
+
/**
|
|
241
|
+
* Extra response parts to include, e.g. `file_search_call.results`.
|
|
242
|
+
*/
|
|
243
|
+
readonly include?: Maybe<string[]>;
|
|
244
|
+
readonly maxOutputTokens?: Maybe<number>;
|
|
245
|
+
readonly temperature?: Maybe<number>;
|
|
246
|
+
readonly topP?: Maybe<number>;
|
|
247
|
+
readonly topK?: Maybe<number>;
|
|
248
|
+
readonly seed?: Maybe<number>;
|
|
249
|
+
readonly stop?: Maybe<string | string[]>;
|
|
250
|
+
readonly frequencyPenalty?: Maybe<number>;
|
|
251
|
+
readonly presencePenalty?: Maybe<number>;
|
|
252
|
+
readonly promptCacheKey?: Maybe<string>;
|
|
253
|
+
readonly truncation?: Maybe<string>;
|
|
254
|
+
readonly user?: Maybe<string>;
|
|
255
|
+
/**
|
|
256
|
+
* Ceiling on tool-call steps, passed to the Agent SDK's `stopWhen`.
|
|
257
|
+
*
|
|
258
|
+
* NOTE: this bounds the number of tool-call rounds, NOT the duration of one inference. A single
|
|
259
|
+
* inference is atomic and cannot be interrupted — use {@link requestTimeoutMs} for that.
|
|
260
|
+
*/
|
|
261
|
+
readonly maxSteps?: Maybe<number>;
|
|
262
|
+
/**
|
|
263
|
+
* Per-request wall-clock timeout in milliseconds.
|
|
264
|
+
*
|
|
265
|
+
* The one bound on a single inference. Required in practice for the run-task sweeper: without it,
|
|
266
|
+
* one unusually slow call can overrun the sweep's time budget and delay every other workload
|
|
267
|
+
* sharing the runner.
|
|
268
|
+
*/
|
|
269
|
+
readonly requestTimeoutMs?: Maybe<number>;
|
|
270
|
+
/**
|
|
271
|
+
* Passthrough for parameters this interface does not yet name.
|
|
272
|
+
*/
|
|
273
|
+
readonly [key: string]: unknown;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Merges model configs left-to-right, so the last input wins.
|
|
277
|
+
*
|
|
278
|
+
* Merging is SHALLOW by key: an override that supplies `provider` replaces the whole provider object
|
|
279
|
+
* rather than merging into it. That is the behaviour a caller wants — a half-overridden `provider`
|
|
280
|
+
* (say, `only` from the override and `allowFallbacks` from the version) is a configuration nobody
|
|
281
|
+
* wrote down and nobody can reason about.
|
|
282
|
+
*
|
|
283
|
+
* `undefined` values do not overwrite; an explicit `null` does (it is how a caller clears a value
|
|
284
|
+
* the version set).
|
|
285
|
+
*
|
|
286
|
+
* @param configs - Configs to merge, lowest priority first.
|
|
287
|
+
* @returns The merged config.
|
|
288
|
+
*/
|
|
289
|
+
export declare function mergeOpenRouterModelConfig(configs: Maybe<OpenRouterModelConfig>[]): OpenRouterModelConfig;
|
|
290
|
+
/**
|
|
291
|
+
* Result of validating an {@link OpenRouterModelConfig}.
|
|
292
|
+
*/
|
|
293
|
+
export interface OpenRouterModelConfigValidation {
|
|
294
|
+
/**
|
|
295
|
+
* Whether the config is usable as-is.
|
|
296
|
+
*/
|
|
297
|
+
readonly valid: boolean;
|
|
298
|
+
/**
|
|
299
|
+
* Problems that make the config unusable.
|
|
300
|
+
*/
|
|
301
|
+
readonly errors: string[];
|
|
302
|
+
/**
|
|
303
|
+
* Problems that do not prevent the call but will very likely produce a wrong result.
|
|
304
|
+
*/
|
|
305
|
+
readonly warnings: string[];
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Validates a merged model config, catching the misconfigurations that fail silently at runtime
|
|
309
|
+
* rather than loudly.
|
|
310
|
+
*
|
|
311
|
+
* @param config - The merged config to check.
|
|
312
|
+
* @returns The validation result.
|
|
313
|
+
*/
|
|
314
|
+
export declare function validateOpenRouterModelConfig(config: Maybe<OpenRouterModelConfig>): OpenRouterModelConfigValidation;
|