@opencode/ai 2.0.21 → 2.0.22

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.
Files changed (37) hide show
  1. package/dist/cache-policy.js +9 -2
  2. package/dist/llm.d.ts +4 -0
  3. package/dist/promise.d.ts +8 -0
  4. package/dist/protocols/alibaba-chat.d.ts +4 -0
  5. package/dist/protocols/alibaba-chat.js +2 -1
  6. package/dist/protocols/anthropic-messages.js +14 -12
  7. package/dist/protocols/bedrock-converse.js +30 -1
  8. package/dist/protocols/open-responses.d.ts +4 -0
  9. package/dist/protocols/openai-chat.d.ts +8 -0
  10. package/dist/protocols/openai-chat.js +9 -5
  11. package/dist/protocols/openai-responses.js +4 -3
  12. package/dist/protocols/utils/cache.d.ts +5 -0
  13. package/dist/protocols/utils/cache.js +9 -1
  14. package/dist/protocols/utils/tool-stream.d.ts +12 -0
  15. package/dist/protocols/zai-chat.d.ts +4 -0
  16. package/dist/protocols/zai-chat.js +6 -3
  17. package/dist/provider-error.js +20 -6
  18. package/dist/providers/digitalocean.d.ts +469 -0
  19. package/dist/providers/digitalocean.js +53 -0
  20. package/dist/providers/google-vertex-messages.js +1 -1
  21. package/dist/providers/groq.d.ts +4 -0
  22. package/dist/providers/groq.js +1 -1
  23. package/dist/providers/index.d.ts +1 -0
  24. package/dist/providers/index.js +1 -0
  25. package/dist/providers/openrouter.d.ts +4 -0
  26. package/dist/providers/openrouter.js +1 -13
  27. package/dist/route/client.d.ts +4 -0
  28. package/dist/route/executor.js +13 -6
  29. package/dist/route/transport/http.d.ts +2 -1
  30. package/dist/route/transport/http.js +28 -6
  31. package/dist/schema/events.d.ts +176 -0
  32. package/dist/schema/events.js +4 -0
  33. package/dist/schema/options.d.ts +11 -0
  34. package/dist/schema/options.js +15 -2
  35. package/dist/testing.d.ts +32 -0
  36. package/dist/tool-history.js +17 -3
  37. package/package.json +3 -3
@@ -0,0 +1,469 @@
1
+ import type { ProviderPackage } from "../provider-package.js";
2
+ import { OpenAIChat } from "../protocols/openai-chat.js";
3
+ import { type ProviderAuthOption } from "../route/auth-options.js";
4
+ import { Route, type RouteDefaultsInput } from "../route/client.js";
5
+ import { Protocol } from "../route/protocol.js";
6
+ import { type ModelID } from "../schema/index.js";
7
+ import type { OpenAIProviderOptionsInput } from "./openai-options.js";
8
+ export declare const id: string & import("effect/Brand").Brand<"AI.ProviderID">;
9
+ export type LanguageModelOptions = Omit<RouteDefaultsInput, "providerOptions"> & ProviderAuthOption<"optional"> & {
10
+ readonly baseURL?: string;
11
+ readonly providerOptions?: OpenAIProviderOptionsInput;
12
+ };
13
+ export type Settings = ProviderPackage.Settings & OpenAIProviderOptionsInput & {
14
+ readonly apiKey?: string;
15
+ };
16
+ export declare const protocol: Protocol<{
17
+ readonly model: string;
18
+ readonly messages: readonly ({
19
+ readonly role: "system";
20
+ readonly content: string | readonly ({
21
+ readonly type: "text";
22
+ readonly text: string;
23
+ readonly cache_control?: {
24
+ readonly type: "ephemeral";
25
+ readonly ttl?: string | undefined;
26
+ } | undefined;
27
+ } | {
28
+ readonly type: "image_url";
29
+ readonly image_url: {
30
+ readonly url: string;
31
+ };
32
+ } | {
33
+ readonly type: "file";
34
+ readonly file: {
35
+ readonly filename: string;
36
+ readonly file_data: string;
37
+ };
38
+ })[];
39
+ } | {
40
+ readonly role: "user";
41
+ readonly content: string | readonly ({
42
+ readonly type: "text";
43
+ readonly text: string;
44
+ readonly cache_control?: {
45
+ readonly type: "ephemeral";
46
+ readonly ttl?: string | undefined;
47
+ } | undefined;
48
+ } | {
49
+ readonly type: "image_url";
50
+ readonly image_url: {
51
+ readonly url: string;
52
+ };
53
+ } | {
54
+ readonly type: "file";
55
+ readonly file: {
56
+ readonly filename: string;
57
+ readonly file_data: string;
58
+ };
59
+ })[];
60
+ } | {
61
+ readonly [x: string]: unknown;
62
+ readonly content: string | readonly {
63
+ readonly type: "text";
64
+ readonly text: string;
65
+ readonly cache_control?: {
66
+ readonly type: "ephemeral";
67
+ readonly ttl?: string | undefined;
68
+ } | undefined;
69
+ }[] | null;
70
+ readonly role: "assistant";
71
+ readonly reasoning?: string | undefined;
72
+ readonly reasoning_content?: string | undefined;
73
+ readonly reasoning_text?: string | undefined;
74
+ readonly tool_calls?: readonly {
75
+ readonly function: {
76
+ readonly name: string;
77
+ readonly arguments: string;
78
+ };
79
+ readonly id: string;
80
+ readonly type: "function";
81
+ readonly extra_content?: {
82
+ readonly google: {
83
+ readonly thought_signature: string;
84
+ };
85
+ } | undefined;
86
+ }[] | undefined;
87
+ readonly reasoning_details?: unknown;
88
+ } | {
89
+ readonly role: "tool";
90
+ readonly tool_call_id: string;
91
+ readonly content: string | readonly {
92
+ readonly type: "text";
93
+ readonly text: string;
94
+ readonly cache_control?: {
95
+ readonly type: "ephemeral";
96
+ readonly ttl?: string | undefined;
97
+ } | undefined;
98
+ }[];
99
+ })[];
100
+ readonly stream: true;
101
+ readonly max_completion_tokens?: number | undefined;
102
+ readonly max_tokens?: number | undefined;
103
+ readonly tools?: readonly {
104
+ readonly function: {
105
+ readonly description: string;
106
+ readonly name: string;
107
+ readonly parameters: {
108
+ readonly [x: string]: unknown;
109
+ };
110
+ readonly strict?: boolean | undefined;
111
+ };
112
+ readonly type: "function";
113
+ readonly cache_control?: {
114
+ readonly type: "ephemeral";
115
+ readonly ttl?: string | undefined;
116
+ } | undefined;
117
+ }[] | undefined;
118
+ readonly stop?: readonly string[] | undefined;
119
+ readonly temperature?: number | undefined;
120
+ readonly seed?: number | undefined;
121
+ readonly tool_choice?: "required" | "auto" | "none" | {
122
+ readonly type: "function";
123
+ readonly function: {
124
+ readonly name: string;
125
+ };
126
+ } | undefined;
127
+ readonly top_p?: number | undefined;
128
+ readonly frequency_penalty?: number | undefined;
129
+ readonly presence_penalty?: number | undefined;
130
+ readonly prompt_cache_key?: string | undefined;
131
+ readonly reasoning_effort?: import("../schema/options.js").ReasoningEffort | undefined;
132
+ readonly store?: boolean | undefined;
133
+ readonly stream_options?: {
134
+ readonly include_usage: boolean;
135
+ } | undefined;
136
+ readonly tool_stream?: boolean | undefined;
137
+ }, string, "[DONE]" | {
138
+ readonly [x: string]: unknown;
139
+ readonly error?: {
140
+ readonly [x: string]: unknown;
141
+ readonly message: string;
142
+ readonly code?: string | number | null | undefined;
143
+ } | null | undefined;
144
+ readonly usage?: {
145
+ readonly [x: string]: unknown;
146
+ readonly cache_read_input_tokens?: number | null | undefined;
147
+ readonly cached_tokens?: number | null | undefined;
148
+ readonly prompt_tokens?: number | null | undefined;
149
+ readonly completion_tokens?: number | null | undefined;
150
+ readonly total_tokens?: number | null | undefined;
151
+ readonly prompt_tokens_details?: {
152
+ readonly [x: string]: unknown;
153
+ readonly cached_tokens?: number | null | undefined;
154
+ readonly cache_write_tokens?: number | null | undefined;
155
+ } | null | undefined;
156
+ readonly prompt_cache_hit_tokens?: number | null | undefined;
157
+ readonly cache_created_input_tokens?: number | null | undefined;
158
+ readonly completion_tokens_details?: {
159
+ readonly [x: string]: unknown;
160
+ readonly reasoning_tokens?: number | null | undefined;
161
+ readonly accepted_prediction_tokens?: number | null | undefined;
162
+ readonly rejected_prediction_tokens?: number | null | undefined;
163
+ } | null | undefined;
164
+ } | null | undefined;
165
+ readonly choices?: readonly {
166
+ readonly [x: string]: unknown;
167
+ readonly delta?: {
168
+ readonly [x: string]: unknown;
169
+ readonly reasoning?: string | null | undefined;
170
+ readonly reasoning_content?: string | null | undefined;
171
+ readonly reasoning_text?: string | null | undefined;
172
+ readonly content?: string | null | undefined;
173
+ readonly refusal?: string | null | undefined;
174
+ readonly tool_calls?: readonly {
175
+ readonly function?: {
176
+ readonly name?: string | null | undefined;
177
+ readonly arguments?: string | null | undefined;
178
+ } | null | undefined;
179
+ readonly id?: string | null | undefined;
180
+ readonly index?: number | null | undefined;
181
+ readonly extra_content?: unknown;
182
+ }[] | null | undefined;
183
+ readonly reasoning_details?: unknown;
184
+ } | null | undefined;
185
+ readonly usage?: {
186
+ readonly [x: string]: unknown;
187
+ readonly cache_read_input_tokens?: number | null | undefined;
188
+ readonly cached_tokens?: number | null | undefined;
189
+ readonly prompt_tokens?: number | null | undefined;
190
+ readonly completion_tokens?: number | null | undefined;
191
+ readonly total_tokens?: number | null | undefined;
192
+ readonly prompt_tokens_details?: {
193
+ readonly [x: string]: unknown;
194
+ readonly cached_tokens?: number | null | undefined;
195
+ readonly cache_write_tokens?: number | null | undefined;
196
+ } | null | undefined;
197
+ readonly prompt_cache_hit_tokens?: number | null | undefined;
198
+ readonly cache_created_input_tokens?: number | null | undefined;
199
+ readonly completion_tokens_details?: {
200
+ readonly [x: string]: unknown;
201
+ readonly reasoning_tokens?: number | null | undefined;
202
+ readonly accepted_prediction_tokens?: number | null | undefined;
203
+ readonly rejected_prediction_tokens?: number | null | undefined;
204
+ } | null | undefined;
205
+ } | null | undefined;
206
+ readonly finish_reason?: string | null | undefined;
207
+ readonly native_finish_reason?: string | null | undefined;
208
+ }[] | null | undefined;
209
+ }, OpenAIChat.ParserState>;
210
+ export declare const route: Route<{
211
+ readonly model: string;
212
+ readonly messages: readonly ({
213
+ readonly role: "system";
214
+ readonly content: string | readonly ({
215
+ readonly type: "text";
216
+ readonly text: string;
217
+ readonly cache_control?: {
218
+ readonly type: "ephemeral";
219
+ readonly ttl?: string | undefined;
220
+ } | undefined;
221
+ } | {
222
+ readonly type: "image_url";
223
+ readonly image_url: {
224
+ readonly url: string;
225
+ };
226
+ } | {
227
+ readonly type: "file";
228
+ readonly file: {
229
+ readonly filename: string;
230
+ readonly file_data: string;
231
+ };
232
+ })[];
233
+ } | {
234
+ readonly role: "user";
235
+ readonly content: string | readonly ({
236
+ readonly type: "text";
237
+ readonly text: string;
238
+ readonly cache_control?: {
239
+ readonly type: "ephemeral";
240
+ readonly ttl?: string | undefined;
241
+ } | undefined;
242
+ } | {
243
+ readonly type: "image_url";
244
+ readonly image_url: {
245
+ readonly url: string;
246
+ };
247
+ } | {
248
+ readonly type: "file";
249
+ readonly file: {
250
+ readonly filename: string;
251
+ readonly file_data: string;
252
+ };
253
+ })[];
254
+ } | {
255
+ readonly [x: string]: unknown;
256
+ readonly content: string | readonly {
257
+ readonly type: "text";
258
+ readonly text: string;
259
+ readonly cache_control?: {
260
+ readonly type: "ephemeral";
261
+ readonly ttl?: string | undefined;
262
+ } | undefined;
263
+ }[] | null;
264
+ readonly role: "assistant";
265
+ readonly reasoning?: string | undefined;
266
+ readonly reasoning_content?: string | undefined;
267
+ readonly reasoning_text?: string | undefined;
268
+ readonly tool_calls?: readonly {
269
+ readonly function: {
270
+ readonly name: string;
271
+ readonly arguments: string;
272
+ };
273
+ readonly id: string;
274
+ readonly type: "function";
275
+ readonly extra_content?: {
276
+ readonly google: {
277
+ readonly thought_signature: string;
278
+ };
279
+ } | undefined;
280
+ }[] | undefined;
281
+ readonly reasoning_details?: unknown;
282
+ } | {
283
+ readonly role: "tool";
284
+ readonly tool_call_id: string;
285
+ readonly content: string | readonly {
286
+ readonly type: "text";
287
+ readonly text: string;
288
+ readonly cache_control?: {
289
+ readonly type: "ephemeral";
290
+ readonly ttl?: string | undefined;
291
+ } | undefined;
292
+ }[];
293
+ })[];
294
+ readonly stream: true;
295
+ readonly max_completion_tokens?: number | undefined;
296
+ readonly max_tokens?: number | undefined;
297
+ readonly tools?: readonly {
298
+ readonly function: {
299
+ readonly description: string;
300
+ readonly name: string;
301
+ readonly parameters: {
302
+ readonly [x: string]: unknown;
303
+ };
304
+ readonly strict?: boolean | undefined;
305
+ };
306
+ readonly type: "function";
307
+ readonly cache_control?: {
308
+ readonly type: "ephemeral";
309
+ readonly ttl?: string | undefined;
310
+ } | undefined;
311
+ }[] | undefined;
312
+ readonly stop?: readonly string[] | undefined;
313
+ readonly temperature?: number | undefined;
314
+ readonly seed?: number | undefined;
315
+ readonly tool_choice?: "required" | "auto" | "none" | {
316
+ readonly type: "function";
317
+ readonly function: {
318
+ readonly name: string;
319
+ };
320
+ } | undefined;
321
+ readonly top_p?: number | undefined;
322
+ readonly frequency_penalty?: number | undefined;
323
+ readonly presence_penalty?: number | undefined;
324
+ readonly prompt_cache_key?: string | undefined;
325
+ readonly reasoning_effort?: import("../schema/options.js").ReasoningEffort | undefined;
326
+ readonly store?: boolean | undefined;
327
+ readonly stream_options?: {
328
+ readonly include_usage: boolean;
329
+ } | undefined;
330
+ readonly tool_stream?: boolean | undefined;
331
+ }, import("../route/transport/http.js").HttpPrepared<string>, import("../route/client.js").CompactionOperations | undefined>;
332
+ export declare const routes: Route<{
333
+ readonly model: string;
334
+ readonly messages: readonly ({
335
+ readonly role: "system";
336
+ readonly content: string | readonly ({
337
+ readonly type: "text";
338
+ readonly text: string;
339
+ readonly cache_control?: {
340
+ readonly type: "ephemeral";
341
+ readonly ttl?: string | undefined;
342
+ } | undefined;
343
+ } | {
344
+ readonly type: "image_url";
345
+ readonly image_url: {
346
+ readonly url: string;
347
+ };
348
+ } | {
349
+ readonly type: "file";
350
+ readonly file: {
351
+ readonly filename: string;
352
+ readonly file_data: string;
353
+ };
354
+ })[];
355
+ } | {
356
+ readonly role: "user";
357
+ readonly content: string | readonly ({
358
+ readonly type: "text";
359
+ readonly text: string;
360
+ readonly cache_control?: {
361
+ readonly type: "ephemeral";
362
+ readonly ttl?: string | undefined;
363
+ } | undefined;
364
+ } | {
365
+ readonly type: "image_url";
366
+ readonly image_url: {
367
+ readonly url: string;
368
+ };
369
+ } | {
370
+ readonly type: "file";
371
+ readonly file: {
372
+ readonly filename: string;
373
+ readonly file_data: string;
374
+ };
375
+ })[];
376
+ } | {
377
+ readonly [x: string]: unknown;
378
+ readonly content: string | readonly {
379
+ readonly type: "text";
380
+ readonly text: string;
381
+ readonly cache_control?: {
382
+ readonly type: "ephemeral";
383
+ readonly ttl?: string | undefined;
384
+ } | undefined;
385
+ }[] | null;
386
+ readonly role: "assistant";
387
+ readonly reasoning?: string | undefined;
388
+ readonly reasoning_content?: string | undefined;
389
+ readonly reasoning_text?: string | undefined;
390
+ readonly tool_calls?: readonly {
391
+ readonly function: {
392
+ readonly name: string;
393
+ readonly arguments: string;
394
+ };
395
+ readonly id: string;
396
+ readonly type: "function";
397
+ readonly extra_content?: {
398
+ readonly google: {
399
+ readonly thought_signature: string;
400
+ };
401
+ } | undefined;
402
+ }[] | undefined;
403
+ readonly reasoning_details?: unknown;
404
+ } | {
405
+ readonly role: "tool";
406
+ readonly tool_call_id: string;
407
+ readonly content: string | readonly {
408
+ readonly type: "text";
409
+ readonly text: string;
410
+ readonly cache_control?: {
411
+ readonly type: "ephemeral";
412
+ readonly ttl?: string | undefined;
413
+ } | undefined;
414
+ }[];
415
+ })[];
416
+ readonly stream: true;
417
+ readonly max_completion_tokens?: number | undefined;
418
+ readonly max_tokens?: number | undefined;
419
+ readonly tools?: readonly {
420
+ readonly function: {
421
+ readonly description: string;
422
+ readonly name: string;
423
+ readonly parameters: {
424
+ readonly [x: string]: unknown;
425
+ };
426
+ readonly strict?: boolean | undefined;
427
+ };
428
+ readonly type: "function";
429
+ readonly cache_control?: {
430
+ readonly type: "ephemeral";
431
+ readonly ttl?: string | undefined;
432
+ } | undefined;
433
+ }[] | undefined;
434
+ readonly stop?: readonly string[] | undefined;
435
+ readonly temperature?: number | undefined;
436
+ readonly seed?: number | undefined;
437
+ readonly tool_choice?: "required" | "auto" | "none" | {
438
+ readonly type: "function";
439
+ readonly function: {
440
+ readonly name: string;
441
+ };
442
+ } | undefined;
443
+ readonly top_p?: number | undefined;
444
+ readonly frequency_penalty?: number | undefined;
445
+ readonly presence_penalty?: number | undefined;
446
+ readonly prompt_cache_key?: string | undefined;
447
+ readonly reasoning_effort?: import("../schema/options.js").ReasoningEffort | undefined;
448
+ readonly store?: boolean | undefined;
449
+ readonly stream_options?: {
450
+ readonly include_usage: boolean;
451
+ } | undefined;
452
+ readonly tool_stream?: boolean | undefined;
453
+ }, import("../route/transport/http.js").HttpPrepared<string>, import("../route/client.js").CompactionOperations | undefined>[];
454
+ export declare const configure: (input?: LanguageModelOptions) => {
455
+ id: string & import("effect/Brand").Brand<"AI.ProviderID">;
456
+ model: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput, import("../route/client.js").CompactionOperations | undefined>;
457
+ configure: (input?: LanguageModelOptions) => /*elided*/ any;
458
+ };
459
+ export declare const provider: {
460
+ id: string & import("effect/Brand").Brand<"AI.ProviderID">;
461
+ model: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput, import("../route/client.js").CompactionOperations | undefined>;
462
+ configure: (input?: LanguageModelOptions) => {
463
+ id: string & import("effect/Brand").Brand<"AI.ProviderID">;
464
+ model: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput, import("../route/client.js").CompactionOperations | undefined>;
465
+ configure: /*elided*/ any;
466
+ };
467
+ };
468
+ export declare const model: ProviderPackage.Definition<Settings, OpenAIProviderOptionsInput>["model"];
469
+ export * as DigitalOcean from "./digitalocean.js";
@@ -0,0 +1,53 @@
1
+ import { OpenAIChat } from "../protocols/openai-chat.js";
2
+ import { cacheControl } from "../protocols/utils/cache.js";
3
+ import { AuthOptions } from "../route/auth-options.js";
4
+ import { Route } from "../route/client.js";
5
+ import { Endpoint } from "../route/endpoint.js";
6
+ import { Protocol } from "../route/protocol.js";
7
+ import { ProviderID } from "../schema/index.js";
8
+ export const id = ProviderID.make("digitalocean");
9
+ const baseURL = "https://inference.do-ai.run/v1";
10
+ export const protocol = Protocol.make({
11
+ id: "digitalocean-chat",
12
+ body: {
13
+ schema: OpenAIChat.protocol.body.schema,
14
+ from: (request) => OpenAIChat.fromRequest(request, { cacheControl: cacheControl() }),
15
+ },
16
+ stream: OpenAIChat.protocol.stream,
17
+ });
18
+ export const route = Route.make({
19
+ id: "digitalocean",
20
+ provider: id,
21
+ providerMetadataKey: "digitalocean",
22
+ protocol,
23
+ endpoint: Endpoint.path("/chat/completions", { baseURL }),
24
+ framing: OpenAIChat.framing,
25
+ });
26
+ export const routes = [route];
27
+ export const configure = (input = {}) => {
28
+ const { apiKey: _apiKey, auth: _auth, baseURL: endpoint, ...defaults } = input;
29
+ const configured = route.with({
30
+ ...defaults,
31
+ endpoint: { baseURL: endpoint ?? baseURL },
32
+ auth: AuthOptions.bearer(input, ["DIGITALOCEAN_ACCESS_TOKEN", "DIGITALOCEAN_API_KEY", "DO_INFERENCE_API_KEY"]),
33
+ });
34
+ return {
35
+ id,
36
+ model: (modelID) => configured.model({
37
+ id: modelID,
38
+ compatibility: {
39
+ supportsPromptCacheKey: true,
40
+ },
41
+ }),
42
+ configure,
43
+ };
44
+ };
45
+ export const provider = configure();
46
+ export const model = (modelID, { apiKey, baseURL, body, headers, ...providerOptions }) => configure({
47
+ apiKey,
48
+ baseURL,
49
+ headers,
50
+ http: { body },
51
+ providerOptions,
52
+ }).model(modelID);
53
+ export * as DigitalOcean from "./digitalocean.js";
@@ -12,7 +12,7 @@ export const id = ProviderID.make("google-vertex");
12
12
  const route = Route.make({
13
13
  id: "google-vertex-messages",
14
14
  provider: id,
15
- providerMetadataKey: "anthropic",
15
+ providerMetadataKey: "vertex",
16
16
  protocol: Protocol.make({
17
17
  id: AnthropicMessages.protocol.id,
18
18
  body: {
@@ -156,6 +156,7 @@ export declare const protocol: Protocol<{
156
156
  } | null | undefined;
157
157
  readonly usage?: {
158
158
  readonly [x: string]: unknown;
159
+ readonly cache_read_input_tokens?: number | null | undefined;
159
160
  readonly cached_tokens?: number | null | undefined;
160
161
  readonly prompt_tokens?: number | null | undefined;
161
162
  readonly completion_tokens?: number | null | undefined;
@@ -166,6 +167,7 @@ export declare const protocol: Protocol<{
166
167
  readonly cache_write_tokens?: number | null | undefined;
167
168
  } | null | undefined;
168
169
  readonly prompt_cache_hit_tokens?: number | null | undefined;
170
+ readonly cache_created_input_tokens?: number | null | undefined;
169
171
  readonly completion_tokens_details?: {
170
172
  readonly [x: string]: unknown;
171
173
  readonly reasoning_tokens?: number | null | undefined;
@@ -195,6 +197,7 @@ export declare const protocol: Protocol<{
195
197
  } | null | undefined;
196
198
  readonly usage?: {
197
199
  readonly [x: string]: unknown;
200
+ readonly cache_read_input_tokens?: number | null | undefined;
198
201
  readonly cached_tokens?: number | null | undefined;
199
202
  readonly prompt_tokens?: number | null | undefined;
200
203
  readonly completion_tokens?: number | null | undefined;
@@ -205,6 +208,7 @@ export declare const protocol: Protocol<{
205
208
  readonly cache_write_tokens?: number | null | undefined;
206
209
  } | null | undefined;
207
210
  readonly prompt_cache_hit_tokens?: number | null | undefined;
211
+ readonly cache_created_input_tokens?: number | null | undefined;
208
212
  readonly completion_tokens_details?: {
209
213
  readonly [x: string]: unknown;
210
214
  readonly reasoning_tokens?: number | null | undefined;
@@ -43,7 +43,7 @@ export const protocol = Protocol.make({
43
43
  export const route = Route.make({
44
44
  id: "groq-chat",
45
45
  provider: id,
46
- providerMetadataKey: "openai",
46
+ providerMetadataKey: "groq",
47
47
  protocol,
48
48
  endpoint: Endpoint.path("/chat/completions", { baseURL }),
49
49
  framing: OpenAIChat.framing,
@@ -14,6 +14,7 @@ export * as CloudflareWorkersAI from "./cloudflare-workers-ai.js";
14
14
  export * as DeepInfra from "./deepinfra.js";
15
15
  export * as Deepgram from "./deepgram.js";
16
16
  export * as DeepSeek from "./deepseek.js";
17
+ export * as DigitalOcean from "./digitalocean.js";
17
18
  export * as ElevenLabs from "./elevenlabs.js";
18
19
  export * as Fal from "./fal.js";
19
20
  export * as Fireworks from "./fireworks.js";
@@ -14,6 +14,7 @@ export * as CloudflareWorkersAI from "./cloudflare-workers-ai.js";
14
14
  export * as DeepInfra from "./deepinfra.js";
15
15
  export * as Deepgram from "./deepgram.js";
16
16
  export * as DeepSeek from "./deepseek.js";
17
+ export * as DigitalOcean from "./digitalocean.js";
17
18
  export * as ElevenLabs from "./elevenlabs.js";
18
19
  export * as Fal from "./fal.js";
19
20
  export * as Fireworks from "./fireworks.js";
@@ -338,6 +338,7 @@ export declare const protocol: Protocol<{
338
338
  } | null | undefined;
339
339
  readonly usage?: {
340
340
  readonly [x: string]: unknown;
341
+ readonly cache_read_input_tokens?: number | null | undefined;
341
342
  readonly cached_tokens?: number | null | undefined;
342
343
  readonly prompt_tokens?: number | null | undefined;
343
344
  readonly completion_tokens?: number | null | undefined;
@@ -348,6 +349,7 @@ export declare const protocol: Protocol<{
348
349
  readonly cache_write_tokens?: number | null | undefined;
349
350
  } | null | undefined;
350
351
  readonly prompt_cache_hit_tokens?: number | null | undefined;
352
+ readonly cache_created_input_tokens?: number | null | undefined;
351
353
  readonly completion_tokens_details?: {
352
354
  readonly [x: string]: unknown;
353
355
  readonly reasoning_tokens?: number | null | undefined;
@@ -377,6 +379,7 @@ export declare const protocol: Protocol<{
377
379
  } | null | undefined;
378
380
  readonly usage?: {
379
381
  readonly [x: string]: unknown;
382
+ readonly cache_read_input_tokens?: number | null | undefined;
380
383
  readonly cached_tokens?: number | null | undefined;
381
384
  readonly prompt_tokens?: number | null | undefined;
382
385
  readonly completion_tokens?: number | null | undefined;
@@ -387,6 +390,7 @@ export declare const protocol: Protocol<{
387
390
  readonly cache_write_tokens?: number | null | undefined;
388
391
  } | null | undefined;
389
392
  readonly prompt_cache_hit_tokens?: number | null | undefined;
393
+ readonly cache_created_input_tokens?: number | null | undefined;
390
394
  readonly completion_tokens_details?: {
391
395
  readonly [x: string]: unknown;
392
396
  readonly reasoning_tokens?: number | null | undefined;
@@ -6,7 +6,7 @@ import { AuthOptions } from "../route/auth-options.js";
6
6
  import { HttpOptions, ProviderID } from "../schema/index.js";
7
7
  import { SystemOne } from "../experimental/system-one.js";
8
8
  import { OpenAIChat } from "../protocols/openai-chat.js";
9
- import { newBreakpoints, ttlBucket } from "../protocols/utils/cache.js";
9
+ import { cacheControl } from "../protocols/utils/cache.js";
10
10
  import { isRecord, ProviderShared } from "../protocols/shared.js";
11
11
  export const id = ProviderID.make("openrouter");
12
12
  const baseURL = "https://openrouter.ai/api/v1";
@@ -47,18 +47,6 @@ export const protocol = Protocol.make({
47
47
  },
48
48
  stream: OpenAIChat.protocol.stream,
49
49
  });
50
- const cacheControl = () => {
51
- const breakpoints = newBreakpoints(4);
52
- return (cache) => {
53
- if (cache === undefined || breakpoints.remaining === 0)
54
- return undefined;
55
- breakpoints.remaining -= 1;
56
- return {
57
- type: "ephemeral",
58
- ...(ttlBucket(cache.ttlSeconds) === "1h" ? { ttl: "1h" } : {}),
59
- };
60
- };
61
- };
62
50
  // OpenRouter forwards `reasoning.max_tokens` as the upstream thinking budget. Upstreams such as Anthropic and Alibaba
63
51
  // reject one that is not below the output limit; 1,024 is Anthropic's minimum budget.
64
52
  const fitReasoning = (reasoning, maxTokens) => typeof reasoning.max_tokens === "number"
@@ -396,6 +396,8 @@ export declare const streamRequest: (request: LLMRequest, options?: StreamOption
396
396
  readonly reason: {
397
397
  readonly normalized: "length" | "stop" | "tool-calls" | "content-filter" | "error" | "unknown";
398
398
  readonly raw?: string | undefined;
399
+ readonly category?: string | undefined;
400
+ readonly explanation?: string | undefined;
399
401
  };
400
402
  readonly index: number;
401
403
  readonly providerMetadata?: {
@@ -409,6 +411,8 @@ export declare const streamRequest: (request: LLMRequest, options?: StreamOption
409
411
  readonly reason: {
410
412
  readonly normalized: "length" | "stop" | "tool-calls" | "content-filter" | "error" | "unknown";
411
413
  readonly raw?: string | undefined;
414
+ readonly category?: string | undefined;
415
+ readonly explanation?: string | undefined;
412
416
  };
413
417
  readonly providerMetadata?: {
414
418
  readonly [x: string]: {