@openrouter/ai-sdk-provider 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,1056 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __objRest = (source, exclude) => {
21
+ var target = {};
22
+ for (var prop in source)
23
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
24
+ target[prop] = source[prop];
25
+ if (source != null && __getOwnPropSymbols)
26
+ for (var prop of __getOwnPropSymbols(source)) {
27
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
28
+ target[prop] = source[prop];
29
+ }
30
+ return target;
31
+ };
32
+
33
+ // src/openrouter-facade.ts
34
+ import { loadApiKey, withoutTrailingSlash } from "@ai-sdk/provider-utils";
35
+
36
+ // src/openrouter-chat-language-model.ts
37
+ import {
38
+ InvalidResponseDataError,
39
+ UnsupportedFunctionalityError
40
+ } from "@ai-sdk/provider";
41
+ import {
42
+ combineHeaders,
43
+ createEventSourceResponseHandler,
44
+ createJsonResponseHandler,
45
+ generateId,
46
+ isParsableJson,
47
+ postJsonToApi
48
+ } from "@ai-sdk/provider-utils";
49
+ import { z as z2 } from "zod";
50
+
51
+ // src/convert-to-openrouter-chat-messages.ts
52
+ import { convertUint8ArrayToBase64 } from "@ai-sdk/provider-utils";
53
+ function convertToOpenRouterChatMessages(prompt) {
54
+ var _a;
55
+ const messages = [];
56
+ for (const { role, content } of prompt) {
57
+ switch (role) {
58
+ case "system": {
59
+ messages.push({ role: "system", content });
60
+ break;
61
+ }
62
+ case "user": {
63
+ if (content.length === 1 && ((_a = content[0]) == null ? void 0 : _a.type) === "text") {
64
+ messages.push({ role: "user", content: content[0].text });
65
+ break;
66
+ }
67
+ messages.push({
68
+ role: "user",
69
+ content: content.map((part) => {
70
+ var _a2;
71
+ switch (part.type) {
72
+ case "text": {
73
+ return { type: "text", text: part.text };
74
+ }
75
+ case "image": {
76
+ return {
77
+ type: "image_url",
78
+ image_url: {
79
+ url: part.image instanceof URL ? part.image.toString() : `data:${(_a2 = part.mimeType) != null ? _a2 : "image/jpeg"};base64,${convertUint8ArrayToBase64(part.image)}`
80
+ }
81
+ };
82
+ }
83
+ }
84
+ })
85
+ });
86
+ break;
87
+ }
88
+ case "assistant": {
89
+ let text = "";
90
+ const toolCalls = [];
91
+ for (const part of content) {
92
+ switch (part.type) {
93
+ case "text": {
94
+ text += part.text;
95
+ break;
96
+ }
97
+ case "tool-call": {
98
+ toolCalls.push({
99
+ id: part.toolCallId,
100
+ type: "function",
101
+ function: {
102
+ name: part.toolName,
103
+ arguments: JSON.stringify(part.args)
104
+ }
105
+ });
106
+ break;
107
+ }
108
+ default: {
109
+ const _exhaustiveCheck = part;
110
+ throw new Error(`Unsupported part: ${_exhaustiveCheck}`);
111
+ }
112
+ }
113
+ }
114
+ messages.push({
115
+ role: "assistant",
116
+ content: text,
117
+ tool_calls: toolCalls.length > 0 ? toolCalls : void 0
118
+ });
119
+ break;
120
+ }
121
+ case "tool": {
122
+ for (const toolResponse of content) {
123
+ messages.push({
124
+ role: "tool",
125
+ tool_call_id: toolResponse.toolCallId,
126
+ content: JSON.stringify(toolResponse.result)
127
+ });
128
+ }
129
+ break;
130
+ }
131
+ default: {
132
+ const _exhaustiveCheck = role;
133
+ throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
134
+ }
135
+ }
136
+ }
137
+ return messages;
138
+ }
139
+
140
+ // src/map-openrouter-chat-logprobs.ts
141
+ function mapOpenRouterChatLogProbsOutput(logprobs) {
142
+ var _a, _b;
143
+ return (_b = (_a = logprobs == null ? void 0 : logprobs.content) == null ? void 0 : _a.map(({ token, logprob, top_logprobs }) => ({
144
+ token,
145
+ logprob,
146
+ topLogprobs: top_logprobs ? top_logprobs.map(({ token: token2, logprob: logprob2 }) => ({
147
+ token: token2,
148
+ logprob: logprob2
149
+ })) : []
150
+ }))) != null ? _b : void 0;
151
+ }
152
+
153
+ // src/map-openrouter-finish-reason.ts
154
+ function mapOpenRouterFinishReason(finishReason) {
155
+ switch (finishReason) {
156
+ case "stop":
157
+ return "stop";
158
+ case "length":
159
+ return "length";
160
+ case "content_filter":
161
+ return "content-filter";
162
+ case "function_call":
163
+ case "tool_calls":
164
+ return "tool-calls";
165
+ default:
166
+ return "unknown";
167
+ }
168
+ }
169
+
170
+ // src/openrouter-error.ts
171
+ import { z } from "zod";
172
+ import { createJsonErrorResponseHandler } from "@ai-sdk/provider-utils";
173
+ var openAIErrorDataSchema = z.object({
174
+ error: z.object({
175
+ message: z.string(),
176
+ type: z.string(),
177
+ param: z.any().nullable(),
178
+ code: z.string().nullable()
179
+ })
180
+ });
181
+ var openrouterFailedResponseHandler = createJsonErrorResponseHandler({
182
+ errorSchema: openAIErrorDataSchema,
183
+ errorToMessage: (data) => data.error.message
184
+ });
185
+
186
+ // src/openrouter-chat-language-model.ts
187
+ var OpenRouterChatLanguageModel = class {
188
+ constructor(modelId, settings, config) {
189
+ this.specificationVersion = "v1";
190
+ this.defaultObjectGenerationMode = "tool";
191
+ this.modelId = modelId;
192
+ this.settings = settings;
193
+ this.config = config;
194
+ }
195
+ get provider() {
196
+ return this.config.provider;
197
+ }
198
+ getArgs({
199
+ mode,
200
+ prompt,
201
+ maxTokens,
202
+ temperature,
203
+ topP,
204
+ frequencyPenalty,
205
+ presencePenalty,
206
+ seed
207
+ }) {
208
+ const type = mode.type;
209
+ const baseArgs = {
210
+ // model id:
211
+ model: this.modelId,
212
+ // model specific settings:
213
+ logit_bias: this.settings.logitBias,
214
+ logprobs: this.settings.logprobs === true || typeof this.settings.logprobs === "number" ? true : void 0,
215
+ top_logprobs: typeof this.settings.logprobs === "number" ? this.settings.logprobs : typeof this.settings.logprobs === "boolean" ? this.settings.logprobs ? 0 : void 0 : void 0,
216
+ user: this.settings.user,
217
+ parallel_tool_calls: this.settings.parallelToolCalls,
218
+ // standardized settings:
219
+ max_tokens: maxTokens,
220
+ temperature,
221
+ top_p: topP,
222
+ frequency_penalty: frequencyPenalty,
223
+ presence_penalty: presencePenalty,
224
+ seed,
225
+ // messages:
226
+ messages: convertToOpenRouterChatMessages(prompt)
227
+ };
228
+ switch (type) {
229
+ case "regular": {
230
+ return __spreadValues(__spreadValues({}, baseArgs), prepareToolsAndToolChoice(mode));
231
+ }
232
+ case "object-json": {
233
+ return __spreadProps(__spreadValues({}, baseArgs), {
234
+ response_format: { type: "json_object" }
235
+ });
236
+ }
237
+ case "object-tool": {
238
+ return __spreadProps(__spreadValues({}, baseArgs), {
239
+ tool_choice: { type: "function", function: { name: mode.tool.name } },
240
+ tools: [
241
+ {
242
+ type: "function",
243
+ function: {
244
+ name: mode.tool.name,
245
+ description: mode.tool.description,
246
+ parameters: mode.tool.parameters
247
+ }
248
+ }
249
+ ]
250
+ });
251
+ }
252
+ case "object-grammar": {
253
+ throw new UnsupportedFunctionalityError({
254
+ functionality: "object-grammar mode"
255
+ });
256
+ }
257
+ default: {
258
+ const _exhaustiveCheck = type;
259
+ throw new Error(`Unsupported type: ${_exhaustiveCheck}`);
260
+ }
261
+ }
262
+ }
263
+ async doGenerate(options) {
264
+ var _b, _c;
265
+ const args = this.getArgs(options);
266
+ const { responseHeaders, value: response } = await postJsonToApi({
267
+ url: this.config.url({
268
+ path: "/chat/completions",
269
+ modelId: this.modelId
270
+ }),
271
+ headers: combineHeaders(this.config.headers(), options.headers),
272
+ body: args,
273
+ failedResponseHandler: openrouterFailedResponseHandler,
274
+ successfulResponseHandler: createJsonResponseHandler(
275
+ openAIChatResponseSchema
276
+ ),
277
+ abortSignal: options.abortSignal,
278
+ fetch: this.config.fetch
279
+ });
280
+ const _a = args, { messages: rawPrompt } = _a, rawSettings = __objRest(_a, ["messages"]);
281
+ const choice = response.choices[0];
282
+ if (choice == null) {
283
+ throw new Error("No choice in response");
284
+ }
285
+ return {
286
+ text: (_b = choice.message.content) != null ? _b : void 0,
287
+ toolCalls: (_c = choice.message.tool_calls) == null ? void 0 : _c.map((toolCall) => {
288
+ var _a2;
289
+ return {
290
+ toolCallType: "function",
291
+ toolCallId: (_a2 = toolCall.id) != null ? _a2 : generateId(),
292
+ toolName: toolCall.function.name,
293
+ args: toolCall.function.arguments
294
+ };
295
+ }),
296
+ finishReason: mapOpenRouterFinishReason(choice.finish_reason),
297
+ usage: {
298
+ promptTokens: response.usage.prompt_tokens,
299
+ completionTokens: response.usage.completion_tokens
300
+ },
301
+ rawCall: { rawPrompt, rawSettings },
302
+ rawResponse: { headers: responseHeaders },
303
+ warnings: [],
304
+ logprobs: mapOpenRouterChatLogProbsOutput(choice.logprobs)
305
+ };
306
+ }
307
+ async doStream(options) {
308
+ const args = this.getArgs(options);
309
+ const { responseHeaders, value: response } = await postJsonToApi({
310
+ url: this.config.url({
311
+ path: "/chat/completions",
312
+ modelId: this.modelId
313
+ }),
314
+ headers: combineHeaders(this.config.headers(), options.headers),
315
+ body: __spreadProps(__spreadValues({}, args), {
316
+ stream: true,
317
+ // only include stream_options when in strict compatibility mode:
318
+ stream_options: this.config.compatibility === "strict" ? { include_usage: true } : void 0
319
+ }),
320
+ failedResponseHandler: openrouterFailedResponseHandler,
321
+ successfulResponseHandler: createEventSourceResponseHandler(
322
+ openrouterChatChunkSchema
323
+ ),
324
+ abortSignal: options.abortSignal,
325
+ fetch: this.config.fetch
326
+ });
327
+ const _a = args, { messages: rawPrompt } = _a, rawSettings = __objRest(_a, ["messages"]);
328
+ const toolCalls = [];
329
+ let finishReason = "other";
330
+ let usage = {
331
+ promptTokens: Number.NaN,
332
+ completionTokens: Number.NaN
333
+ };
334
+ let logprobs;
335
+ return {
336
+ stream: response.pipeThrough(
337
+ new TransformStream({
338
+ transform(chunk, controller) {
339
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
340
+ if (!chunk.success) {
341
+ finishReason = "error";
342
+ controller.enqueue({ type: "error", error: chunk.error });
343
+ return;
344
+ }
345
+ const value = chunk.value;
346
+ if ("error" in value) {
347
+ finishReason = "error";
348
+ controller.enqueue({ type: "error", error: value.error });
349
+ return;
350
+ }
351
+ if (value.usage != null) {
352
+ usage = {
353
+ promptTokens: value.usage.prompt_tokens,
354
+ completionTokens: value.usage.completion_tokens
355
+ };
356
+ }
357
+ const choice = value.choices[0];
358
+ if ((choice == null ? void 0 : choice.finish_reason) != null) {
359
+ finishReason = mapOpenRouterFinishReason(choice.finish_reason);
360
+ }
361
+ if ((choice == null ? void 0 : choice.delta) == null) {
362
+ return;
363
+ }
364
+ const delta = choice.delta;
365
+ if (delta.content != null) {
366
+ controller.enqueue({
367
+ type: "text-delta",
368
+ textDelta: delta.content
369
+ });
370
+ }
371
+ const mappedLogprobs = mapOpenRouterChatLogProbsOutput(
372
+ choice == null ? void 0 : choice.logprobs
373
+ );
374
+ if (mappedLogprobs == null ? void 0 : mappedLogprobs.length) {
375
+ if (logprobs === void 0) logprobs = [];
376
+ logprobs.push(...mappedLogprobs);
377
+ }
378
+ if (delta.tool_calls != null) {
379
+ for (const toolCallDelta of delta.tool_calls) {
380
+ const index = toolCallDelta.index;
381
+ if (toolCalls[index] == null) {
382
+ if (toolCallDelta.type !== "function") {
383
+ throw new InvalidResponseDataError({
384
+ data: toolCallDelta,
385
+ message: `Expected 'function' type.`
386
+ });
387
+ }
388
+ if (toolCallDelta.id == null) {
389
+ throw new InvalidResponseDataError({
390
+ data: toolCallDelta,
391
+ message: `Expected 'id' to be a string.`
392
+ });
393
+ }
394
+ if (((_a2 = toolCallDelta.function) == null ? void 0 : _a2.name) == null) {
395
+ throw new InvalidResponseDataError({
396
+ data: toolCallDelta,
397
+ message: `Expected 'function.name' to be a string.`
398
+ });
399
+ }
400
+ toolCalls[index] = {
401
+ id: toolCallDelta.id,
402
+ type: "function",
403
+ function: {
404
+ name: toolCallDelta.function.name,
405
+ arguments: (_b = toolCallDelta.function.arguments) != null ? _b : ""
406
+ }
407
+ };
408
+ const toolCall2 = toolCalls[index];
409
+ if (toolCall2 == null) {
410
+ throw new Error("Tool call is missing");
411
+ }
412
+ if (((_c = toolCall2.function) == null ? void 0 : _c.name) != null && ((_d = toolCall2.function) == null ? void 0 : _d.arguments) != null && isParsableJson(toolCall2.function.arguments)) {
413
+ controller.enqueue({
414
+ type: "tool-call-delta",
415
+ toolCallType: "function",
416
+ toolCallId: toolCall2.id,
417
+ toolName: toolCall2.function.name,
418
+ argsTextDelta: toolCall2.function.arguments
419
+ });
420
+ controller.enqueue({
421
+ type: "tool-call",
422
+ toolCallType: "function",
423
+ toolCallId: (_e = toolCall2.id) != null ? _e : generateId(),
424
+ toolName: toolCall2.function.name,
425
+ args: toolCall2.function.arguments
426
+ });
427
+ }
428
+ continue;
429
+ }
430
+ const toolCall = toolCalls[index];
431
+ if (toolCall == null) {
432
+ throw new Error("Tool call is missing");
433
+ }
434
+ if (((_f = toolCallDelta.function) == null ? void 0 : _f.arguments) != null) {
435
+ toolCall.function.arguments += (_h = (_g = toolCallDelta.function) == null ? void 0 : _g.arguments) != null ? _h : "";
436
+ }
437
+ controller.enqueue({
438
+ type: "tool-call-delta",
439
+ toolCallType: "function",
440
+ toolCallId: toolCall.id,
441
+ toolName: toolCall.function.name,
442
+ argsTextDelta: (_i = toolCallDelta.function.arguments) != null ? _i : ""
443
+ });
444
+ if (((_j = toolCall.function) == null ? void 0 : _j.name) != null && ((_k = toolCall.function) == null ? void 0 : _k.arguments) != null && isParsableJson(toolCall.function.arguments)) {
445
+ controller.enqueue({
446
+ type: "tool-call",
447
+ toolCallType: "function",
448
+ toolCallId: (_l = toolCall.id) != null ? _l : generateId(),
449
+ toolName: toolCall.function.name,
450
+ args: toolCall.function.arguments
451
+ });
452
+ }
453
+ }
454
+ }
455
+ },
456
+ flush(controller) {
457
+ controller.enqueue({
458
+ type: "finish",
459
+ finishReason,
460
+ logprobs,
461
+ usage
462
+ });
463
+ }
464
+ })
465
+ ),
466
+ rawCall: { rawPrompt, rawSettings },
467
+ rawResponse: { headers: responseHeaders },
468
+ warnings: []
469
+ };
470
+ }
471
+ };
472
+ var openAIChatResponseSchema = z2.object({
473
+ choices: z2.array(
474
+ z2.object({
475
+ message: z2.object({
476
+ role: z2.literal("assistant"),
477
+ content: z2.string().nullable().optional(),
478
+ tool_calls: z2.array(
479
+ z2.object({
480
+ id: z2.string().optional().nullable(),
481
+ type: z2.literal("function"),
482
+ function: z2.object({
483
+ name: z2.string(),
484
+ arguments: z2.string()
485
+ })
486
+ })
487
+ ).optional()
488
+ }),
489
+ index: z2.number(),
490
+ logprobs: z2.object({
491
+ content: z2.array(
492
+ z2.object({
493
+ token: z2.string(),
494
+ logprob: z2.number(),
495
+ top_logprobs: z2.array(
496
+ z2.object({
497
+ token: z2.string(),
498
+ logprob: z2.number()
499
+ })
500
+ )
501
+ })
502
+ ).nullable()
503
+ }).nullable().optional(),
504
+ finish_reason: z2.string().optional().nullable()
505
+ })
506
+ ),
507
+ usage: z2.object({
508
+ prompt_tokens: z2.number(),
509
+ completion_tokens: z2.number()
510
+ })
511
+ });
512
+ var openrouterChatChunkSchema = z2.union([
513
+ z2.object({
514
+ choices: z2.array(
515
+ z2.object({
516
+ delta: z2.object({
517
+ role: z2.enum(["assistant"]).optional(),
518
+ content: z2.string().nullish(),
519
+ tool_calls: z2.array(
520
+ z2.object({
521
+ index: z2.number(),
522
+ id: z2.string().nullish(),
523
+ type: z2.literal("function").optional(),
524
+ function: z2.object({
525
+ name: z2.string().nullish(),
526
+ arguments: z2.string().nullish()
527
+ })
528
+ })
529
+ ).nullish()
530
+ }).nullish(),
531
+ logprobs: z2.object({
532
+ content: z2.array(
533
+ z2.object({
534
+ token: z2.string(),
535
+ logprob: z2.number(),
536
+ top_logprobs: z2.array(
537
+ z2.object({
538
+ token: z2.string(),
539
+ logprob: z2.number()
540
+ })
541
+ )
542
+ })
543
+ ).nullable()
544
+ }).nullish(),
545
+ finish_reason: z2.string().nullable().optional(),
546
+ index: z2.number()
547
+ })
548
+ ),
549
+ usage: z2.object({
550
+ prompt_tokens: z2.number(),
551
+ completion_tokens: z2.number()
552
+ }).nullish()
553
+ }),
554
+ openAIErrorDataSchema
555
+ ]);
556
+ function prepareToolsAndToolChoice(mode) {
557
+ var _a;
558
+ const tools = ((_a = mode.tools) == null ? void 0 : _a.length) ? mode.tools : void 0;
559
+ if (tools == null) {
560
+ return { tools: void 0, tool_choice: void 0 };
561
+ }
562
+ const mappedTools = tools.map((tool) => ({
563
+ type: "function",
564
+ function: {
565
+ name: tool.name,
566
+ description: tool.description,
567
+ parameters: tool.parameters
568
+ }
569
+ }));
570
+ const toolChoice = mode.toolChoice;
571
+ if (toolChoice == null) {
572
+ return { tools: mappedTools, tool_choice: void 0 };
573
+ }
574
+ const type = toolChoice.type;
575
+ switch (type) {
576
+ case "auto":
577
+ case "none":
578
+ case "required":
579
+ return { tools: mappedTools, tool_choice: type };
580
+ case "tool":
581
+ return {
582
+ tools: mappedTools,
583
+ tool_choice: {
584
+ type: "function",
585
+ function: {
586
+ name: toolChoice.toolName
587
+ }
588
+ }
589
+ };
590
+ default: {
591
+ const _exhaustiveCheck = type;
592
+ throw new Error(`Unsupported tool choice type: ${_exhaustiveCheck}`);
593
+ }
594
+ }
595
+ }
596
+
597
+ // src/openrouter-completion-language-model.ts
598
+ import {
599
+ UnsupportedFunctionalityError as UnsupportedFunctionalityError3
600
+ } from "@ai-sdk/provider";
601
+ import {
602
+ combineHeaders as combineHeaders2,
603
+ createEventSourceResponseHandler as createEventSourceResponseHandler2,
604
+ createJsonResponseHandler as createJsonResponseHandler2,
605
+ postJsonToApi as postJsonToApi2
606
+ } from "@ai-sdk/provider-utils";
607
+ import { z as z3 } from "zod";
608
+
609
+ // src/convert-to-openrouter-completion-prompt.ts
610
+ import {
611
+ InvalidPromptError,
612
+ UnsupportedFunctionalityError as UnsupportedFunctionalityError2
613
+ } from "@ai-sdk/provider";
614
+ function convertToOpenRouterCompletionPrompt({
615
+ prompt,
616
+ inputFormat,
617
+ user = "user",
618
+ assistant = "assistant"
619
+ }) {
620
+ if (inputFormat === "prompt" && prompt.length === 1 && prompt[0] && prompt[0].role === "user" && prompt[0].content.length === 1 && prompt[0].content[0] && prompt[0].content[0].type === "text") {
621
+ return { prompt: prompt[0].content[0].text };
622
+ }
623
+ let text = "";
624
+ if (prompt[0] && prompt[0].role === "system") {
625
+ text += `${prompt[0].content}
626
+
627
+ `;
628
+ prompt = prompt.slice(1);
629
+ }
630
+ for (const { role, content } of prompt) {
631
+ switch (role) {
632
+ case "system": {
633
+ throw new InvalidPromptError({
634
+ message: "Unexpected system message in prompt: ${content}",
635
+ prompt
636
+ });
637
+ }
638
+ case "user": {
639
+ const userMessage = content.map((part) => {
640
+ switch (part.type) {
641
+ case "text": {
642
+ return part.text;
643
+ }
644
+ case "image": {
645
+ throw new UnsupportedFunctionalityError2({
646
+ functionality: "images"
647
+ });
648
+ }
649
+ }
650
+ }).join("");
651
+ text += `${user}:
652
+ ${userMessage}
653
+
654
+ `;
655
+ break;
656
+ }
657
+ case "assistant": {
658
+ const assistantMessage = content.map((part) => {
659
+ switch (part.type) {
660
+ case "text": {
661
+ return part.text;
662
+ }
663
+ case "tool-call": {
664
+ throw new UnsupportedFunctionalityError2({
665
+ functionality: "tool-call messages"
666
+ });
667
+ }
668
+ }
669
+ }).join("");
670
+ text += `${assistant}:
671
+ ${assistantMessage}
672
+
673
+ `;
674
+ break;
675
+ }
676
+ case "tool": {
677
+ throw new UnsupportedFunctionalityError2({
678
+ functionality: "tool messages"
679
+ });
680
+ }
681
+ default: {
682
+ const _exhaustiveCheck = role;
683
+ throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
684
+ }
685
+ }
686
+ }
687
+ text += `${assistant}:
688
+ `;
689
+ return {
690
+ prompt: text,
691
+ stopSequences: [`
692
+ ${user}:`]
693
+ };
694
+ }
695
+
696
+ // src/map-openrouter-completion-logprobs.ts
697
+ function mapOpenRouterCompletionLogProbs(logprobs) {
698
+ return logprobs == null ? void 0 : logprobs.tokens.map((token, index) => {
699
+ var _a, _b;
700
+ return {
701
+ token,
702
+ logprob: (_a = logprobs.token_logprobs[index]) != null ? _a : 0,
703
+ topLogprobs: logprobs.top_logprobs ? Object.entries((_b = logprobs.top_logprobs[index]) != null ? _b : {}).map(
704
+ ([token2, logprob]) => ({
705
+ token: token2,
706
+ logprob
707
+ })
708
+ ) : []
709
+ };
710
+ });
711
+ }
712
+
713
+ // src/openrouter-completion-language-model.ts
714
+ var OpenRouterCompletionLanguageModel = class {
715
+ constructor(modelId, settings, config) {
716
+ this.specificationVersion = "v1";
717
+ this.defaultObjectGenerationMode = void 0;
718
+ this.modelId = modelId;
719
+ this.settings = settings;
720
+ this.config = config;
721
+ }
722
+ get provider() {
723
+ return this.config.provider;
724
+ }
725
+ getArgs({
726
+ mode,
727
+ inputFormat,
728
+ prompt,
729
+ maxTokens,
730
+ temperature,
731
+ topP,
732
+ frequencyPenalty,
733
+ presencePenalty,
734
+ seed
735
+ }) {
736
+ var _a;
737
+ const type = mode.type;
738
+ const { prompt: completionPrompt, stopSequences } = convertToOpenRouterCompletionPrompt({ prompt, inputFormat });
739
+ const baseArgs = {
740
+ // model id:
741
+ model: this.modelId,
742
+ // model specific settings:
743
+ echo: this.settings.echo,
744
+ logit_bias: this.settings.logitBias,
745
+ logprobs: typeof this.settings.logprobs === "number" ? this.settings.logprobs : typeof this.settings.logprobs === "boolean" ? this.settings.logprobs ? 0 : void 0 : void 0,
746
+ suffix: this.settings.suffix,
747
+ user: this.settings.user,
748
+ // standardized settings:
749
+ max_tokens: maxTokens,
750
+ temperature,
751
+ top_p: topP,
752
+ frequency_penalty: frequencyPenalty,
753
+ presence_penalty: presencePenalty,
754
+ seed,
755
+ // prompt:
756
+ prompt: completionPrompt,
757
+ // stop sequences:
758
+ stop: stopSequences
759
+ };
760
+ switch (type) {
761
+ case "regular": {
762
+ if ((_a = mode.tools) == null ? void 0 : _a.length) {
763
+ throw new UnsupportedFunctionalityError3({
764
+ functionality: "tools"
765
+ });
766
+ }
767
+ if (mode.toolChoice) {
768
+ throw new UnsupportedFunctionalityError3({
769
+ functionality: "toolChoice"
770
+ });
771
+ }
772
+ return baseArgs;
773
+ }
774
+ case "object-json": {
775
+ throw new UnsupportedFunctionalityError3({
776
+ functionality: "object-json mode"
777
+ });
778
+ }
779
+ case "object-tool": {
780
+ throw new UnsupportedFunctionalityError3({
781
+ functionality: "object-tool mode"
782
+ });
783
+ }
784
+ case "object-grammar": {
785
+ throw new UnsupportedFunctionalityError3({
786
+ functionality: "object-grammar mode"
787
+ });
788
+ }
789
+ default: {
790
+ const _exhaustiveCheck = type;
791
+ throw new Error(`Unsupported type: ${_exhaustiveCheck}`);
792
+ }
793
+ }
794
+ }
795
+ async doGenerate(options) {
796
+ const args = this.getArgs(options);
797
+ const { responseHeaders, value: response } = await postJsonToApi2({
798
+ url: this.config.url({
799
+ path: "/completions",
800
+ modelId: this.modelId
801
+ }),
802
+ headers: combineHeaders2(this.config.headers(), options.headers),
803
+ body: args,
804
+ failedResponseHandler: openrouterFailedResponseHandler,
805
+ successfulResponseHandler: createJsonResponseHandler2(
806
+ openAICompletionResponseSchema
807
+ ),
808
+ abortSignal: options.abortSignal,
809
+ fetch: this.config.fetch
810
+ });
811
+ const _a = args, { prompt: rawPrompt } = _a, rawSettings = __objRest(_a, ["prompt"]);
812
+ const choice = response.choices[0];
813
+ if (!choice) {
814
+ throw new Error("No choice in OpenRouter completion response");
815
+ }
816
+ return {
817
+ text: choice.text,
818
+ usage: {
819
+ promptTokens: response.usage.prompt_tokens,
820
+ completionTokens: response.usage.completion_tokens
821
+ },
822
+ finishReason: mapOpenRouterFinishReason(choice.finish_reason),
823
+ logprobs: mapOpenRouterCompletionLogProbs(choice.logprobs),
824
+ rawCall: { rawPrompt, rawSettings },
825
+ rawResponse: { headers: responseHeaders },
826
+ warnings: []
827
+ };
828
+ }
829
+ async doStream(options) {
830
+ const args = this.getArgs(options);
831
+ const { responseHeaders, value: response } = await postJsonToApi2({
832
+ url: this.config.url({
833
+ path: "/completions",
834
+ modelId: this.modelId
835
+ }),
836
+ headers: combineHeaders2(this.config.headers(), options.headers),
837
+ body: __spreadProps(__spreadValues({}, this.getArgs(options)), {
838
+ stream: true,
839
+ // only include stream_options when in strict compatibility mode:
840
+ stream_options: this.config.compatibility === "strict" ? { include_usage: true } : void 0
841
+ }),
842
+ failedResponseHandler: openrouterFailedResponseHandler,
843
+ successfulResponseHandler: createEventSourceResponseHandler2(
844
+ openrouterCompletionChunkSchema
845
+ ),
846
+ abortSignal: options.abortSignal,
847
+ fetch: this.config.fetch
848
+ });
849
+ const _a = args, { prompt: rawPrompt } = _a, rawSettings = __objRest(_a, ["prompt"]);
850
+ let finishReason = "other";
851
+ let usage = {
852
+ promptTokens: Number.NaN,
853
+ completionTokens: Number.NaN
854
+ };
855
+ let logprobs;
856
+ return {
857
+ stream: response.pipeThrough(
858
+ new TransformStream({
859
+ transform(chunk, controller) {
860
+ if (!chunk.success) {
861
+ finishReason = "error";
862
+ controller.enqueue({ type: "error", error: chunk.error });
863
+ return;
864
+ }
865
+ const value = chunk.value;
866
+ if ("error" in value) {
867
+ finishReason = "error";
868
+ controller.enqueue({ type: "error", error: value.error });
869
+ return;
870
+ }
871
+ if (value.usage != null) {
872
+ usage = {
873
+ promptTokens: value.usage.prompt_tokens,
874
+ completionTokens: value.usage.completion_tokens
875
+ };
876
+ }
877
+ const choice = value.choices[0];
878
+ if ((choice == null ? void 0 : choice.finish_reason) != null) {
879
+ finishReason = mapOpenRouterFinishReason(choice.finish_reason);
880
+ }
881
+ if ((choice == null ? void 0 : choice.text) != null) {
882
+ controller.enqueue({
883
+ type: "text-delta",
884
+ textDelta: choice.text
885
+ });
886
+ }
887
+ const mappedLogprobs = mapOpenRouterCompletionLogProbs(
888
+ choice == null ? void 0 : choice.logprobs
889
+ );
890
+ if (mappedLogprobs == null ? void 0 : mappedLogprobs.length) {
891
+ if (logprobs === void 0) logprobs = [];
892
+ logprobs.push(...mappedLogprobs);
893
+ }
894
+ },
895
+ flush(controller) {
896
+ controller.enqueue({
897
+ type: "finish",
898
+ finishReason,
899
+ logprobs,
900
+ usage
901
+ });
902
+ }
903
+ })
904
+ ),
905
+ rawCall: { rawPrompt, rawSettings },
906
+ rawResponse: { headers: responseHeaders },
907
+ warnings: []
908
+ };
909
+ }
910
+ };
911
+ var openAICompletionResponseSchema = z3.object({
912
+ choices: z3.array(
913
+ z3.object({
914
+ text: z3.string(),
915
+ finish_reason: z3.string(),
916
+ logprobs: z3.object({
917
+ tokens: z3.array(z3.string()),
918
+ token_logprobs: z3.array(z3.number()),
919
+ top_logprobs: z3.array(z3.record(z3.string(), z3.number())).nullable()
920
+ }).nullable().optional()
921
+ })
922
+ ),
923
+ usage: z3.object({
924
+ prompt_tokens: z3.number(),
925
+ completion_tokens: z3.number()
926
+ })
927
+ });
928
+ var openrouterCompletionChunkSchema = z3.union([
929
+ z3.object({
930
+ choices: z3.array(
931
+ z3.object({
932
+ text: z3.string(),
933
+ finish_reason: z3.string().nullish(),
934
+ index: z3.number(),
935
+ logprobs: z3.object({
936
+ tokens: z3.array(z3.string()),
937
+ token_logprobs: z3.array(z3.number()),
938
+ top_logprobs: z3.array(z3.record(z3.string(), z3.number())).nullable()
939
+ }).nullable().optional()
940
+ })
941
+ ),
942
+ usage: z3.object({
943
+ prompt_tokens: z3.number(),
944
+ completion_tokens: z3.number()
945
+ }).optional().nullable()
946
+ }),
947
+ openAIErrorDataSchema
948
+ ]);
949
+
950
+ // src/openrouter-facade.ts
951
+ var OpenRouter = class {
952
+ /**
953
+ * Creates a new OpenRouter provider instance.
954
+ */
955
+ constructor(options = {}) {
956
+ var _a, _b;
957
+ this.baseURL = (_b = withoutTrailingSlash((_a = options.baseURL) != null ? _a : options.baseUrl)) != null ? _b : "https://openrouter.ai/api/v1";
958
+ this.apiKey = options.apiKey;
959
+ this.organization = options.organization;
960
+ this.project = options.project;
961
+ this.headers = options.headers;
962
+ }
963
+ get baseConfig() {
964
+ return {
965
+ organization: this.organization,
966
+ baseURL: this.baseURL,
967
+ headers: () => __spreadValues({
968
+ Authorization: `Bearer ${loadApiKey({
969
+ apiKey: this.apiKey,
970
+ environmentVariableName: "OPENAI_API_KEY",
971
+ description: "OpenRouter"
972
+ })}`,
973
+ "OpenRouter-Organization": this.organization,
974
+ "OpenRouter-Project": this.project
975
+ }, this.headers)
976
+ };
977
+ }
978
+ chat(modelId, settings = {}) {
979
+ return new OpenRouterChatLanguageModel(modelId, settings, __spreadProps(__spreadValues({
980
+ provider: "openrouter.chat"
981
+ }, this.baseConfig), {
982
+ compatibility: "strict",
983
+ url: ({ path }) => `${this.baseURL}${path}`
984
+ }));
985
+ }
986
+ completion(modelId, settings = {}) {
987
+ return new OpenRouterCompletionLanguageModel(modelId, settings, __spreadProps(__spreadValues({
988
+ provider: "openrouter.completion"
989
+ }, this.baseConfig), {
990
+ compatibility: "strict",
991
+ url: ({ path }) => `${this.baseURL}${path}`
992
+ }));
993
+ }
994
+ };
995
+
996
+ // src/openrouter-provider.ts
997
+ import { loadApiKey as loadApiKey2, withoutTrailingSlash as withoutTrailingSlash2 } from "@ai-sdk/provider-utils";
998
+ function createOpenRouter(options = {}) {
999
+ var _a, _b, _c;
1000
+ const baseURL = (_b = withoutTrailingSlash2((_a = options.baseURL) != null ? _a : options.baseUrl)) != null ? _b : "https://openrouter.ai/api/v1";
1001
+ const compatibility = (_c = options.compatibility) != null ? _c : "compatible";
1002
+ const getHeaders = () => __spreadValues({
1003
+ Authorization: `Bearer ${loadApiKey2({
1004
+ apiKey: options.apiKey,
1005
+ environmentVariableName: "OPENAI_API_KEY",
1006
+ description: "OpenRouter"
1007
+ })}`,
1008
+ "OpenRouter-Organization": options.organization,
1009
+ "OpenRouter-Project": options.project
1010
+ }, options.headers);
1011
+ const createChatModel = (modelId, settings = {}) => new OpenRouterChatLanguageModel(modelId, settings, {
1012
+ provider: "openrouter.chat",
1013
+ url: ({ path }) => `${baseURL}${path}`,
1014
+ headers: getHeaders,
1015
+ compatibility,
1016
+ fetch: options.fetch
1017
+ });
1018
+ const createCompletionModel = (modelId, settings = {}) => new OpenRouterCompletionLanguageModel(modelId, settings, {
1019
+ provider: "openrouter.completion",
1020
+ url: ({ path }) => `${baseURL}${path}`,
1021
+ headers: getHeaders,
1022
+ compatibility,
1023
+ fetch: options.fetch
1024
+ });
1025
+ const createLanguageModel = (modelId, settings) => {
1026
+ if (new.target) {
1027
+ throw new Error(
1028
+ "The OpenRouter model function cannot be called with the new keyword."
1029
+ );
1030
+ }
1031
+ if (modelId === "openai/gpt-3.5-turbo-instruct") {
1032
+ return createCompletionModel(
1033
+ modelId,
1034
+ settings
1035
+ );
1036
+ }
1037
+ return createChatModel(modelId, settings);
1038
+ };
1039
+ const provider = function(modelId, settings) {
1040
+ return createLanguageModel(modelId, settings);
1041
+ };
1042
+ provider.languageModel = createLanguageModel;
1043
+ provider.chat = createChatModel;
1044
+ provider.completion = createCompletionModel;
1045
+ return provider;
1046
+ }
1047
+ var openrouter = createOpenRouter({
1048
+ compatibility: "strict"
1049
+ // strict for OpenRouter API
1050
+ });
1051
+ export {
1052
+ OpenRouter,
1053
+ createOpenRouter,
1054
+ openrouter
1055
+ };
1056
+ //# sourceMappingURL=index.mjs.map