@providerprotocol/ai 0.0.15 → 0.0.17
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/README.md +111 -8
- package/dist/anthropic/index.d.ts +1 -1
- package/dist/google/index.d.ts +29 -2
- package/dist/google/index.js +102 -1
- package/dist/google/index.js.map +1 -1
- package/dist/http/index.d.ts +2 -2
- package/dist/index.d.ts +223 -5
- package/dist/index.js +152 -2
- package/dist/index.js.map +1 -1
- package/dist/ollama/index.d.ts +26 -2
- package/dist/ollama/index.js +96 -1
- package/dist/ollama/index.js.map +1 -1
- package/dist/openai/index.d.ts +29 -3
- package/dist/openai/index.js +106 -1
- package/dist/openai/index.js.map +1 -1
- package/dist/openrouter/index.d.ts +74 -3
- package/dist/openrouter/index.js +191 -18
- package/dist/openrouter/index.js.map +1 -1
- package/dist/{provider-Bi0nyNhA.d.ts → provider-D5MO3-pS.d.ts} +66 -1
- package/dist/{retry-BatS2hjD.d.ts → retry-DZ4Sqmxp.d.ts} +1 -1
- package/dist/xai/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,29 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { d as Provider, f as ModelReference, b as LLMHandler, c as EmbeddingHandler } from '../provider-D5MO3-pS.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview OpenRouter Embeddings API Handler
|
|
5
|
+
*
|
|
6
|
+
* This module implements the embedding handler for OpenRouter's embeddings API.
|
|
7
|
+
* OpenRouter provides access to multiple embedding providers through an OpenAI-compatible endpoint.
|
|
8
|
+
*
|
|
9
|
+
* @see {@link https://openrouter.ai/docs/api/reference/embeddings OpenRouter Embeddings API Reference}
|
|
10
|
+
* @module providers/openrouter/embed
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* OpenRouter embedding parameters.
|
|
15
|
+
* Passed through unchanged to the API.
|
|
16
|
+
*/
|
|
17
|
+
interface OpenRouterEmbedParams {
|
|
18
|
+
/** Output dimensions (model-dependent) */
|
|
19
|
+
dimensions?: number;
|
|
20
|
+
/** Encoding format: 'float' or 'base64' */
|
|
21
|
+
encoding_format?: 'float' | 'base64';
|
|
22
|
+
/** A unique identifier representing your end-user */
|
|
23
|
+
user?: string;
|
|
24
|
+
/** Input type hint for some models */
|
|
25
|
+
input_type?: string;
|
|
26
|
+
}
|
|
2
27
|
|
|
3
28
|
/**
|
|
4
29
|
* OpenRouter-specific types for the Unified Provider Protocol.
|
|
@@ -53,6 +78,18 @@ interface OpenRouterCompletionsParams {
|
|
|
53
78
|
parallel_tool_calls?: boolean;
|
|
54
79
|
/** Response format for structured output */
|
|
55
80
|
response_format?: OpenRouterResponseFormat;
|
|
81
|
+
/**
|
|
82
|
+
* Output modalities for multimodal generation.
|
|
83
|
+
* Set to `['text', 'image']` to enable image generation with compatible models.
|
|
84
|
+
* @see {@link https://openrouter.ai/docs/guides/overview/multimodal/image-generation}
|
|
85
|
+
*/
|
|
86
|
+
modalities?: Array<'text' | 'image'>;
|
|
87
|
+
/**
|
|
88
|
+
* Image generation configuration for Gemini models.
|
|
89
|
+
* Only applies when `modalities` includes 'image'.
|
|
90
|
+
* @see {@link https://openrouter.ai/docs/guides/overview/multimodal/image-generation}
|
|
91
|
+
*/
|
|
92
|
+
image_config?: OpenRouterImageConfig;
|
|
56
93
|
/**
|
|
57
94
|
* Prompt transforms to apply
|
|
58
95
|
* See: https://openrouter.ai/docs/guides/features/message-transforms
|
|
@@ -87,6 +124,27 @@ interface OpenRouterCompletionsParams {
|
|
|
87
124
|
echo_upstream_body?: boolean;
|
|
88
125
|
};
|
|
89
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* Image generation configuration for OpenRouter.
|
|
129
|
+
*
|
|
130
|
+
* Used with Gemini image generation models to control output dimensions.
|
|
131
|
+
*
|
|
132
|
+
* @see {@link https://openrouter.ai/docs/guides/overview/multimodal/image-generation}
|
|
133
|
+
*/
|
|
134
|
+
interface OpenRouterImageConfig {
|
|
135
|
+
/**
|
|
136
|
+
* Aspect ratio for generated images.
|
|
137
|
+
* Supported values range from '1:1' (1024×1024) to '21:9' (1536×672).
|
|
138
|
+
*/
|
|
139
|
+
aspect_ratio?: string;
|
|
140
|
+
/**
|
|
141
|
+
* Resolution level for generated images.
|
|
142
|
+
* - '1K': Standard resolution
|
|
143
|
+
* - '2K': Higher resolution
|
|
144
|
+
* - '4K': Highest resolution
|
|
145
|
+
*/
|
|
146
|
+
image_size?: '1K' | '2K' | '4K';
|
|
147
|
+
}
|
|
90
148
|
/**
|
|
91
149
|
* Parameters for OpenRouter's Responses API (beta).
|
|
92
150
|
*
|
|
@@ -111,6 +169,18 @@ interface OpenRouterResponsesParams {
|
|
|
111
169
|
reasoning?: {
|
|
112
170
|
effort?: 'low' | 'medium' | 'high';
|
|
113
171
|
};
|
|
172
|
+
/**
|
|
173
|
+
* Output modalities for multimodal generation.
|
|
174
|
+
* Set to `['text', 'image']` to enable image generation with compatible models.
|
|
175
|
+
* @see {@link https://openrouter.ai/docs/guides/overview/multimodal/image-generation}
|
|
176
|
+
*/
|
|
177
|
+
modalities?: Array<'text' | 'image'>;
|
|
178
|
+
/**
|
|
179
|
+
* Image generation configuration.
|
|
180
|
+
* Only applies when `modalities` includes 'image'.
|
|
181
|
+
* @see {@link https://openrouter.ai/docs/guides/overview/multimodal/image-generation}
|
|
182
|
+
*/
|
|
183
|
+
image_config?: OpenRouterImageConfig;
|
|
114
184
|
}
|
|
115
185
|
/**
|
|
116
186
|
* API mode selection for OpenRouter provider.
|
|
@@ -244,10 +314,11 @@ interface OpenRouterProvider extends Provider<OpenRouterProviderOptions> {
|
|
|
244
314
|
readonly version: string;
|
|
245
315
|
/**
|
|
246
316
|
* Supported modalities for this provider.
|
|
247
|
-
* OpenRouter
|
|
317
|
+
* OpenRouter supports LLM (text generation) and Embedding.
|
|
248
318
|
*/
|
|
249
319
|
readonly modalities: {
|
|
250
320
|
llm: LLMHandler<OpenRouterLLMParamsUnion>;
|
|
321
|
+
embedding: EmbeddingHandler<OpenRouterEmbedParams>;
|
|
251
322
|
};
|
|
252
323
|
}
|
|
253
324
|
/**
|
|
@@ -301,4 +372,4 @@ interface OpenRouterProvider extends Provider<OpenRouterProviderOptions> {
|
|
|
301
372
|
*/
|
|
302
373
|
declare const openrouter: OpenRouterProvider;
|
|
303
374
|
|
|
304
|
-
export { type OpenRouterAPIMode, type OpenRouterCompletionsParams, type OpenRouterConfig, type OpenRouterModelOptions, type OpenRouterModelReference, type OpenRouterProviderPreferences, type OpenRouterResponsesParams, openrouter };
|
|
375
|
+
export { type OpenRouterAPIMode, type OpenRouterCompletionsParams, type OpenRouterConfig, type OpenRouterEmbedParams, type OpenRouterModelOptions, type OpenRouterModelReference, type OpenRouterProviderPreferences, type OpenRouterResponsesParams, openrouter };
|
package/dist/openrouter/index.js
CHANGED
|
@@ -190,15 +190,23 @@ function transformResponse(data) {
|
|
|
190
190
|
if (!choice) {
|
|
191
191
|
throw new Error("No choices in OpenRouter response");
|
|
192
192
|
}
|
|
193
|
-
const
|
|
193
|
+
const content = [];
|
|
194
194
|
let structuredData;
|
|
195
195
|
if (choice.message.content) {
|
|
196
|
-
|
|
196
|
+
content.push({ type: "text", text: choice.message.content });
|
|
197
197
|
try {
|
|
198
198
|
structuredData = JSON.parse(choice.message.content);
|
|
199
199
|
} catch {
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
|
+
if (choice.message.images && choice.message.images.length > 0) {
|
|
203
|
+
for (const image of choice.message.images) {
|
|
204
|
+
const imageBlock = parseGeneratedImage(image.image_url.url);
|
|
205
|
+
if (imageBlock) {
|
|
206
|
+
content.push(imageBlock);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
202
210
|
const toolCalls = [];
|
|
203
211
|
if (choice.message.tool_calls) {
|
|
204
212
|
for (const call of choice.message.tool_calls) {
|
|
@@ -215,7 +223,7 @@ function transformResponse(data) {
|
|
|
215
223
|
}
|
|
216
224
|
}
|
|
217
225
|
const message = new AssistantMessage(
|
|
218
|
-
|
|
226
|
+
content,
|
|
219
227
|
toolCalls.length > 0 ? toolCalls : void 0,
|
|
220
228
|
{
|
|
221
229
|
id: data.id,
|
|
@@ -257,12 +265,28 @@ function transformResponse(data) {
|
|
|
257
265
|
data: structuredData
|
|
258
266
|
};
|
|
259
267
|
}
|
|
268
|
+
function parseGeneratedImage(dataUrl) {
|
|
269
|
+
const match = dataUrl.match(/^data:(image\/[^;]+);base64,(.+)$/);
|
|
270
|
+
if (!match) {
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
const [, mimeType, data] = match;
|
|
274
|
+
if (!mimeType || !data) {
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
return {
|
|
278
|
+
type: "image",
|
|
279
|
+
mimeType,
|
|
280
|
+
source: { type: "base64", data }
|
|
281
|
+
};
|
|
282
|
+
}
|
|
260
283
|
function createStreamState() {
|
|
261
284
|
return {
|
|
262
285
|
id: "",
|
|
263
286
|
model: "",
|
|
264
287
|
text: "",
|
|
265
288
|
toolCalls: /* @__PURE__ */ new Map(),
|
|
289
|
+
images: [],
|
|
266
290
|
finishReason: null,
|
|
267
291
|
inputTokens: 0,
|
|
268
292
|
outputTokens: 0,
|
|
@@ -316,6 +340,11 @@ function transformStreamEvent(chunk, state) {
|
|
|
316
340
|
}
|
|
317
341
|
}
|
|
318
342
|
}
|
|
343
|
+
if (choice.delta.images) {
|
|
344
|
+
for (const image of choice.delta.images) {
|
|
345
|
+
state.images.push(image.image_url.url);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
319
348
|
if (choice.finish_reason) {
|
|
320
349
|
state.finishReason = choice.finish_reason;
|
|
321
350
|
events.push({ type: "message_stop", index: 0, delta: {} });
|
|
@@ -329,15 +358,21 @@ function transformStreamEvent(chunk, state) {
|
|
|
329
358
|
return events;
|
|
330
359
|
}
|
|
331
360
|
function buildResponseFromState(state) {
|
|
332
|
-
const
|
|
361
|
+
const content = [];
|
|
333
362
|
let structuredData;
|
|
334
363
|
if (state.text) {
|
|
335
|
-
|
|
364
|
+
content.push({ type: "text", text: state.text });
|
|
336
365
|
try {
|
|
337
366
|
structuredData = JSON.parse(state.text);
|
|
338
367
|
} catch {
|
|
339
368
|
}
|
|
340
369
|
}
|
|
370
|
+
for (const imageUrl of state.images) {
|
|
371
|
+
const imageBlock = parseGeneratedImage(imageUrl);
|
|
372
|
+
if (imageBlock) {
|
|
373
|
+
content.push(imageBlock);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
341
376
|
const toolCalls = [];
|
|
342
377
|
for (const [, toolCall] of state.toolCalls) {
|
|
343
378
|
let args = {};
|
|
@@ -354,7 +389,7 @@ function buildResponseFromState(state) {
|
|
|
354
389
|
});
|
|
355
390
|
}
|
|
356
391
|
const message = new AssistantMessage(
|
|
357
|
-
|
|
392
|
+
content,
|
|
358
393
|
toolCalls.length > 0 ? toolCalls : void 0,
|
|
359
394
|
{
|
|
360
395
|
id: state.id,
|
|
@@ -403,6 +438,7 @@ var OPENROUTER_CAPABILITIES = {
|
|
|
403
438
|
tools: true,
|
|
404
439
|
structuredOutput: true,
|
|
405
440
|
imageInput: true,
|
|
441
|
+
imageOutput: true,
|
|
406
442
|
videoInput: false,
|
|
407
443
|
audioInput: false
|
|
408
444
|
};
|
|
@@ -742,7 +778,7 @@ function transformTool2(tool) {
|
|
|
742
778
|
};
|
|
743
779
|
}
|
|
744
780
|
function transformResponse2(data) {
|
|
745
|
-
const
|
|
781
|
+
const content = [];
|
|
746
782
|
const toolCalls = [];
|
|
747
783
|
const functionCallItems = [];
|
|
748
784
|
let hadRefusal = false;
|
|
@@ -750,17 +786,17 @@ function transformResponse2(data) {
|
|
|
750
786
|
for (const item of data.output) {
|
|
751
787
|
if (item.type === "message") {
|
|
752
788
|
const messageItem = item;
|
|
753
|
-
for (const
|
|
754
|
-
if (
|
|
755
|
-
|
|
789
|
+
for (const part of messageItem.content) {
|
|
790
|
+
if (part.type === "output_text") {
|
|
791
|
+
content.push({ type: "text", text: part.text });
|
|
756
792
|
if (structuredData === void 0) {
|
|
757
793
|
try {
|
|
758
|
-
structuredData = JSON.parse(
|
|
794
|
+
structuredData = JSON.parse(part.text);
|
|
759
795
|
} catch {
|
|
760
796
|
}
|
|
761
797
|
}
|
|
762
|
-
} else if (
|
|
763
|
-
|
|
798
|
+
} else if (part.type === "refusal") {
|
|
799
|
+
content.push({ type: "text", text: part.refusal });
|
|
764
800
|
hadRefusal = true;
|
|
765
801
|
}
|
|
766
802
|
}
|
|
@@ -782,10 +818,19 @@ function transformResponse2(data) {
|
|
|
782
818
|
name: functionCall.name,
|
|
783
819
|
arguments: functionCall.arguments
|
|
784
820
|
});
|
|
821
|
+
} else if (item.type === "image_generation_call") {
|
|
822
|
+
const imageGen = item;
|
|
823
|
+
if (imageGen.result) {
|
|
824
|
+
content.push({
|
|
825
|
+
type: "image",
|
|
826
|
+
mimeType: "image/png",
|
|
827
|
+
source: { type: "base64", data: imageGen.result }
|
|
828
|
+
});
|
|
829
|
+
}
|
|
785
830
|
}
|
|
786
831
|
}
|
|
787
832
|
const message = new AssistantMessage(
|
|
788
|
-
|
|
833
|
+
content,
|
|
789
834
|
toolCalls.length > 0 ? toolCalls : void 0,
|
|
790
835
|
{
|
|
791
836
|
id: data.id,
|
|
@@ -831,6 +876,7 @@ function createStreamState2() {
|
|
|
831
876
|
model: "",
|
|
832
877
|
textByIndex: /* @__PURE__ */ new Map(),
|
|
833
878
|
toolCalls: /* @__PURE__ */ new Map(),
|
|
879
|
+
images: /* @__PURE__ */ new Map(),
|
|
834
880
|
status: "in_progress",
|
|
835
881
|
inputTokens: 0,
|
|
836
882
|
outputTokens: 0,
|
|
@@ -927,6 +973,11 @@ function transformStreamEvent2(event, state) {
|
|
|
927
973
|
}
|
|
928
974
|
}
|
|
929
975
|
}
|
|
976
|
+
} else if (event.item.type === "image_generation_call") {
|
|
977
|
+
const imageGen = event.item;
|
|
978
|
+
if (imageGen.result) {
|
|
979
|
+
state.images.set(event.output_index, imageGen.result);
|
|
980
|
+
}
|
|
930
981
|
}
|
|
931
982
|
events.push({
|
|
932
983
|
type: "content_block_stop",
|
|
@@ -1022,11 +1073,11 @@ function transformStreamEvent2(event, state) {
|
|
|
1022
1073
|
return events;
|
|
1023
1074
|
}
|
|
1024
1075
|
function buildResponseFromState2(state) {
|
|
1025
|
-
const
|
|
1076
|
+
const content = [];
|
|
1026
1077
|
let structuredData;
|
|
1027
1078
|
for (const [, text] of state.textByIndex) {
|
|
1028
1079
|
if (text) {
|
|
1029
|
-
|
|
1080
|
+
content.push({ type: "text", text });
|
|
1030
1081
|
if (structuredData === void 0) {
|
|
1031
1082
|
try {
|
|
1032
1083
|
structuredData = JSON.parse(text);
|
|
@@ -1035,6 +1086,15 @@ function buildResponseFromState2(state) {
|
|
|
1035
1086
|
}
|
|
1036
1087
|
}
|
|
1037
1088
|
}
|
|
1089
|
+
for (const [, imageData] of state.images) {
|
|
1090
|
+
if (imageData) {
|
|
1091
|
+
content.push({
|
|
1092
|
+
type: "image",
|
|
1093
|
+
mimeType: "image/png",
|
|
1094
|
+
source: { type: "base64", data: imageData }
|
|
1095
|
+
});
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1038
1098
|
const toolCalls = [];
|
|
1039
1099
|
const functionCallItems = [];
|
|
1040
1100
|
for (const [, toolCall] of state.toolCalls) {
|
|
@@ -1063,7 +1123,7 @@ function buildResponseFromState2(state) {
|
|
|
1063
1123
|
}
|
|
1064
1124
|
}
|
|
1065
1125
|
const message = new AssistantMessage(
|
|
1066
|
-
|
|
1126
|
+
content,
|
|
1067
1127
|
toolCalls.length > 0 ? toolCalls : void 0,
|
|
1068
1128
|
{
|
|
1069
1129
|
id: state.id,
|
|
@@ -1109,6 +1169,7 @@ var OPENROUTER_CAPABILITIES2 = {
|
|
|
1109
1169
|
tools: true,
|
|
1110
1170
|
structuredOutput: true,
|
|
1111
1171
|
imageInput: true,
|
|
1172
|
+
imageOutput: true,
|
|
1112
1173
|
videoInput: false,
|
|
1113
1174
|
audioInput: false
|
|
1114
1175
|
};
|
|
@@ -1275,11 +1336,121 @@ function createResponsesLLMHandler() {
|
|
|
1275
1336
|
};
|
|
1276
1337
|
}
|
|
1277
1338
|
|
|
1339
|
+
// src/providers/openrouter/embed.ts
|
|
1340
|
+
var OPENROUTER_EMBEDDINGS_API_URL = "https://openrouter.ai/api/v1/embeddings";
|
|
1341
|
+
function getDefaultDimensions(modelId) {
|
|
1342
|
+
if (modelId.includes("text-embedding-3-large")) {
|
|
1343
|
+
return 3072;
|
|
1344
|
+
}
|
|
1345
|
+
if (modelId.includes("text-embedding-3-small") || modelId.includes("ada-002")) {
|
|
1346
|
+
return 1536;
|
|
1347
|
+
}
|
|
1348
|
+
if (modelId.includes("gemini-embedding")) {
|
|
1349
|
+
return 3072;
|
|
1350
|
+
}
|
|
1351
|
+
return 1536;
|
|
1352
|
+
}
|
|
1353
|
+
function createEmbeddingHandler() {
|
|
1354
|
+
let providerRef = null;
|
|
1355
|
+
return {
|
|
1356
|
+
supportedInputs: ["text"],
|
|
1357
|
+
_setProvider(provider) {
|
|
1358
|
+
providerRef = provider;
|
|
1359
|
+
},
|
|
1360
|
+
bind(modelId) {
|
|
1361
|
+
if (!providerRef) {
|
|
1362
|
+
throw new UPPError(
|
|
1363
|
+
"Provider reference not set. Handler must be used with createProvider().",
|
|
1364
|
+
"INVALID_REQUEST",
|
|
1365
|
+
"openrouter",
|
|
1366
|
+
"embedding"
|
|
1367
|
+
);
|
|
1368
|
+
}
|
|
1369
|
+
const model = {
|
|
1370
|
+
modelId,
|
|
1371
|
+
maxBatchSize: 2048,
|
|
1372
|
+
maxInputLength: 8191,
|
|
1373
|
+
dimensions: getDefaultDimensions(modelId),
|
|
1374
|
+
get provider() {
|
|
1375
|
+
return providerRef;
|
|
1376
|
+
},
|
|
1377
|
+
async embed(request) {
|
|
1378
|
+
const apiKey = await resolveApiKey(
|
|
1379
|
+
request.config,
|
|
1380
|
+
"OPENROUTER_API_KEY",
|
|
1381
|
+
"openrouter",
|
|
1382
|
+
"embedding"
|
|
1383
|
+
);
|
|
1384
|
+
const baseUrl = request.config.baseUrl ?? OPENROUTER_EMBEDDINGS_API_URL;
|
|
1385
|
+
const inputTexts = request.inputs.map((input) => {
|
|
1386
|
+
if (typeof input === "string") {
|
|
1387
|
+
return input;
|
|
1388
|
+
}
|
|
1389
|
+
if ("text" in input) {
|
|
1390
|
+
return input.text;
|
|
1391
|
+
}
|
|
1392
|
+
throw new UPPError(
|
|
1393
|
+
"OpenRouter embeddings only support text input",
|
|
1394
|
+
"INVALID_REQUEST",
|
|
1395
|
+
"openrouter",
|
|
1396
|
+
"embedding"
|
|
1397
|
+
);
|
|
1398
|
+
});
|
|
1399
|
+
const body = {
|
|
1400
|
+
model: modelId,
|
|
1401
|
+
input: inputTexts
|
|
1402
|
+
};
|
|
1403
|
+
if (request.params?.dimensions !== void 0) {
|
|
1404
|
+
body.dimensions = request.params.dimensions;
|
|
1405
|
+
}
|
|
1406
|
+
if (request.params?.encoding_format !== void 0) {
|
|
1407
|
+
body.encoding_format = request.params.encoding_format;
|
|
1408
|
+
}
|
|
1409
|
+
if (request.params?.user !== void 0) {
|
|
1410
|
+
body.user = request.params.user;
|
|
1411
|
+
}
|
|
1412
|
+
if (request.params?.input_type !== void 0) {
|
|
1413
|
+
body.input_type = request.params.input_type;
|
|
1414
|
+
}
|
|
1415
|
+
const headers = {
|
|
1416
|
+
"Content-Type": "application/json",
|
|
1417
|
+
Authorization: `Bearer ${apiKey}`
|
|
1418
|
+
};
|
|
1419
|
+
if (request.config.headers) {
|
|
1420
|
+
for (const [key, value] of Object.entries(request.config.headers)) {
|
|
1421
|
+
if (value !== void 0) {
|
|
1422
|
+
headers[key] = value;
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
const response = await doFetch(baseUrl, {
|
|
1427
|
+
method: "POST",
|
|
1428
|
+
headers,
|
|
1429
|
+
body: JSON.stringify(body),
|
|
1430
|
+
signal: request.signal
|
|
1431
|
+
}, request.config, "openrouter", "embedding");
|
|
1432
|
+
const data = await response.json();
|
|
1433
|
+
return {
|
|
1434
|
+
embeddings: data.data.map((d) => ({
|
|
1435
|
+
vector: d.embedding,
|
|
1436
|
+
index: d.index
|
|
1437
|
+
})),
|
|
1438
|
+
usage: { totalTokens: data.usage.total_tokens },
|
|
1439
|
+
metadata: data.usage.cost !== void 0 ? { cost: data.usage.cost } : void 0
|
|
1440
|
+
};
|
|
1441
|
+
}
|
|
1442
|
+
};
|
|
1443
|
+
return model;
|
|
1444
|
+
}
|
|
1445
|
+
};
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1278
1448
|
// src/providers/openrouter/index.ts
|
|
1279
1449
|
function createOpenRouterProvider() {
|
|
1280
1450
|
let currentApiMode = "completions";
|
|
1281
1451
|
const completionsHandler = createCompletionsLLMHandler();
|
|
1282
1452
|
const responsesHandler = createResponsesLLMHandler();
|
|
1453
|
+
const embeddingHandler = createEmbeddingHandler();
|
|
1283
1454
|
const fn = function(modelId, options) {
|
|
1284
1455
|
const apiMode = options?.api ?? "completions";
|
|
1285
1456
|
currentApiMode = apiMode;
|
|
@@ -1288,7 +1459,8 @@ function createOpenRouterProvider() {
|
|
|
1288
1459
|
const modalities = {
|
|
1289
1460
|
get llm() {
|
|
1290
1461
|
return currentApiMode === "responses" ? responsesHandler : completionsHandler;
|
|
1291
|
-
}
|
|
1462
|
+
},
|
|
1463
|
+
embedding: embeddingHandler
|
|
1292
1464
|
};
|
|
1293
1465
|
Object.defineProperties(fn, {
|
|
1294
1466
|
name: {
|
|
@@ -1310,6 +1482,7 @@ function createOpenRouterProvider() {
|
|
|
1310
1482
|
const provider = fn;
|
|
1311
1483
|
completionsHandler._setProvider?.(provider);
|
|
1312
1484
|
responsesHandler._setProvider?.(provider);
|
|
1485
|
+
embeddingHandler._setProvider?.(provider);
|
|
1313
1486
|
return provider;
|
|
1314
1487
|
}
|
|
1315
1488
|
var openrouter = createOpenRouterProvider();
|