@effect/ai-openrouter 4.0.0-beta.66 → 4.0.0-beta.68

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.
@@ -1,5 +1,25 @@
1
1
  /**
2
- * @since 1.0.0
2
+ * The `OpenRouterLanguageModel` module provides constructors for using
3
+ * OpenRouter chat completion models through the Effect AI `LanguageModel`
4
+ * interface. It adapts Effect prompts, tools, structured output schemas, file
5
+ * parts, reasoning details, cache-control hints, and telemetry annotations into
6
+ * the OpenRouter request and response formats.
7
+ *
8
+ * Use this module when an application wants to select an OpenRouter model by
9
+ * name while keeping the rest of its AI workflow provider-agnostic. The
10
+ * exported layer and model constructors install a `LanguageModel` service backed
11
+ * by `OpenRouterClient`, and `withConfigOverride` can scope per-request
12
+ * OpenRouter options such as sampling, routing, tool use, or JSON schema
13
+ * behavior.
14
+ *
15
+ * OpenRouter routes requests to many underlying providers, so model support for
16
+ * images, files, tools, structured outputs, caching, and reasoning metadata can
17
+ * vary. Provider-specific prompt and response metadata is preserved under the
18
+ * `openrouter` option namespace so multi-turn conversations can round-trip
19
+ * details such as reasoning blocks and file annotations when the selected model
20
+ * supports them.
21
+ *
22
+ * @since 4.0.0
3
23
  */
4
24
  /** @effect-diagnostics preferSchemaOverJson:skip-file */
5
25
  import * as Arr from "effect/Array"
@@ -40,8 +60,8 @@ import { type ChatStreamingResponseChunkData, OpenRouterClient } from "./OpenRou
40
60
  /**
41
61
  * Service definition for OpenRouter language model configuration.
42
62
  *
43
- * @since 1.0.0
44
63
  * @category services
64
+ * @since 4.0.0
45
65
  */
46
66
  export class Config extends Context.Service<
47
67
  Config,
@@ -69,14 +89,20 @@ export class Config extends Context.Service<
69
89
  // =============================================================================
70
90
 
71
91
  /**
72
- * @since 1.0.0
92
+ * OpenRouter assistant reasoning detail blocks preserved for multi-turn
93
+ * conversations.
94
+ *
73
95
  * @category models
96
+ * @since 4.0.0
74
97
  */
75
98
  export type ReasoningDetails = Exclude<typeof Generated.AssistantMessage.Encoded["reasoning_details"], undefined>
76
99
 
77
100
  /**
78
- * @since 1.0.0
101
+ * File annotations emitted on OpenRouter assistant messages and exposed in
102
+ * finish metadata.
103
+ *
79
104
  * @category models
105
+ * @since 4.0.0
80
106
  */
81
107
  export type FileAnnotation = Extract<
82
108
  NonNullable<typeof Generated.AssistantMessage.fields.annotations.Type>[number],
@@ -84,7 +110,19 @@ export type FileAnnotation = Extract<
84
110
  >
85
111
 
86
112
  declare module "effect/unstable/ai/Prompt" {
113
+ /**
114
+ * OpenRouter-specific options for system messages.
115
+ *
116
+ * These options are used when translating system instructions into
117
+ * OpenRouter chat messages.
118
+ *
119
+ * @category request
120
+ * @since 4.0.0
121
+ */
87
122
  export interface SystemMessageOptions extends ProviderOptions {
123
+ /**
124
+ * Provider-specific options sent to OpenRouter for the system message.
125
+ */
88
126
  readonly openrouter?: {
89
127
  /**
90
128
  * A breakpoint which marks the end of reusable content eligible for caching.
@@ -93,7 +131,19 @@ declare module "effect/unstable/ai/Prompt" {
93
131
  } | null
94
132
  }
95
133
 
134
+ /**
135
+ * OpenRouter-specific options for user messages.
136
+ *
137
+ * These options are used when translating user content into OpenRouter chat
138
+ * messages.
139
+ *
140
+ * @category request
141
+ * @since 4.0.0
142
+ */
96
143
  export interface UserMessageOptions extends ProviderOptions {
144
+ /**
145
+ * Provider-specific options sent to OpenRouter for the user message.
146
+ */
97
147
  readonly openrouter?: {
98
148
  /**
99
149
  * A breakpoint which marks the end of reusable content eligible for caching.
@@ -102,7 +152,19 @@ declare module "effect/unstable/ai/Prompt" {
102
152
  } | null
103
153
  }
104
154
 
155
+ /**
156
+ * OpenRouter-specific options for assistant messages.
157
+ *
158
+ * Preserves reasoning metadata when assistant messages are replayed in later
159
+ * OpenRouter requests.
160
+ *
161
+ * @category request
162
+ * @since 4.0.0
163
+ */
105
164
  export interface AssistantMessageOptions extends ProviderOptions {
165
+ /**
166
+ * Provider-specific options sent to OpenRouter for the assistant message.
167
+ */
106
168
  readonly openrouter?: {
107
169
  /**
108
170
  * A breakpoint which marks the end of reusable content eligible for caching.
@@ -115,7 +177,19 @@ declare module "effect/unstable/ai/Prompt" {
115
177
  } | null
116
178
  }
117
179
 
180
+ /**
181
+ * OpenRouter-specific options for tool messages.
182
+ *
183
+ * These options are used when converting tool results into OpenRouter chat
184
+ * messages.
185
+ *
186
+ * @category request
187
+ * @since 4.0.0
188
+ */
118
189
  export interface ToolMessageOptions extends ProviderOptions {
190
+ /**
191
+ * Provider-specific options sent to OpenRouter for the tool message.
192
+ */
119
193
  readonly openrouter?: {
120
194
  /**
121
195
  * A breakpoint which marks the end of reusable content eligible for caching.
@@ -124,7 +198,18 @@ declare module "effect/unstable/ai/Prompt" {
124
198
  } | null
125
199
  }
126
200
 
201
+ /**
202
+ * OpenRouter-specific options for text prompt parts.
203
+ *
204
+ * Use these options to control how text content is sent to OpenRouter.
205
+ *
206
+ * @category request
207
+ * @since 4.0.0
208
+ */
127
209
  export interface TextPartOptions extends ProviderOptions {
210
+ /**
211
+ * Provider-specific options sent to OpenRouter for the text part.
212
+ */
128
213
  readonly openrouter?: {
129
214
  /**
130
215
  * A breakpoint which marks the end of reusable content eligible for caching.
@@ -133,7 +218,19 @@ declare module "effect/unstable/ai/Prompt" {
133
218
  } | null
134
219
  }
135
220
 
221
+ /**
222
+ * OpenRouter-specific options for reasoning prompt parts.
223
+ *
224
+ * Preserves provider reasoning blocks so reasoning-aware conversations can
225
+ * continue across OpenRouter requests.
226
+ *
227
+ * @category request
228
+ * @since 4.0.0
229
+ */
136
230
  export interface ReasoningPartOptions extends ProviderOptions {
231
+ /**
232
+ * Provider-specific options sent to OpenRouter for the reasoning part.
233
+ */
137
234
  readonly openrouter?: {
138
235
  /**
139
236
  * A breakpoint which marks the end of reusable content eligible for caching.
@@ -146,7 +243,18 @@ declare module "effect/unstable/ai/Prompt" {
146
243
  } | null
147
244
  }
148
245
 
246
+ /**
247
+ * OpenRouter-specific options for file prompt parts.
248
+ *
249
+ * Controls file naming and prompt caching for files sent to OpenRouter.
250
+ *
251
+ * @category request
252
+ * @since 4.0.0
253
+ */
149
254
  export interface FilePartOptions extends ProviderOptions {
255
+ /**
256
+ * Provider-specific options sent to OpenRouter for the file part.
257
+ */
150
258
  readonly openrouter?: {
151
259
  /**
152
260
  * The name to give to the file. Will be prioritized over the file name
@@ -160,7 +268,19 @@ declare module "effect/unstable/ai/Prompt" {
160
268
  } | null
161
269
  }
162
270
 
271
+ /**
272
+ * OpenRouter-specific options for tool call prompt parts.
273
+ *
274
+ * Preserves reasoning details associated with tool calls when a conversation
275
+ * is sent back to OpenRouter.
276
+ *
277
+ * @category request
278
+ * @since 4.0.0
279
+ */
163
280
  export interface ToolCallPartOptions extends ProviderOptions {
281
+ /**
282
+ * Provider-specific options sent to OpenRouter for the tool call part.
283
+ */
164
284
  readonly openrouter?: {
165
285
  /**
166
286
  * Reasoning details associated with the tool call part.
@@ -169,7 +289,18 @@ declare module "effect/unstable/ai/Prompt" {
169
289
  } | null
170
290
  }
171
291
 
292
+ /**
293
+ * OpenRouter-specific options for tool result prompt parts.
294
+ *
295
+ * Controls prompt caching for tool results sent to OpenRouter.
296
+ *
297
+ * @category request
298
+ * @since 4.0.0
299
+ */
172
300
  export interface ToolResultPartOptions extends ProviderOptions {
301
+ /**
302
+ * Provider-specific options sent to OpenRouter for the tool result part.
303
+ */
173
304
  readonly openrouter?: {
174
305
  /**
175
306
  * A breakpoint which marks the end of reusable content eligible for caching.
@@ -180,43 +311,145 @@ declare module "effect/unstable/ai/Prompt" {
180
311
  }
181
312
 
182
313
  declare module "effect/unstable/ai/Response" {
314
+ /**
315
+ * OpenRouter metadata attached to completed reasoning response parts.
316
+ *
317
+ * Preserves provider reasoning details that can be sent back in later turns.
318
+ *
319
+ * @category response
320
+ * @since 4.0.0
321
+ */
183
322
  export interface ReasoningPartMetadata extends ProviderMetadata {
323
+ /**
324
+ * Provider-specific metadata returned for the reasoning part.
325
+ */
184
326
  readonly openrouter?: {
327
+ /**
328
+ * Reasoning details emitted by the underlying provider for this part.
329
+ */
185
330
  readonly reasoningDetails?: ReasoningDetails | null
186
331
  } | null
187
332
  }
188
333
 
334
+ /**
335
+ * OpenRouter metadata emitted when a streamed reasoning part starts.
336
+ *
337
+ * Carries the first reasoning detail chunk when OpenRouter exposes one.
338
+ *
339
+ * @category response
340
+ * @since 4.0.0
341
+ */
189
342
  export interface ReasoningStartPartMetadata extends ProviderMetadata {
343
+ /**
344
+ * Provider-specific metadata returned for the streamed reasoning start.
345
+ */
190
346
  readonly openrouter?: {
347
+ /**
348
+ * Reasoning details emitted by the underlying provider for this part.
349
+ */
191
350
  readonly reasoningDetails?: ReasoningDetails | null
192
351
  } | null
193
352
  }
194
353
 
354
+ /**
355
+ * OpenRouter metadata emitted for streamed reasoning deltas.
356
+ *
357
+ * Carries provider reasoning detail chunks as they arrive from OpenRouter.
358
+ *
359
+ * @category response
360
+ * @since 4.0.0
361
+ */
195
362
  export interface ReasoningDeltaPartMetadata extends ProviderMetadata {
363
+ /**
364
+ * Provider-specific metadata returned for the streamed reasoning delta.
365
+ */
196
366
  readonly openrouter?: {
367
+ /**
368
+ * Reasoning details emitted by the underlying provider for this delta.
369
+ */
197
370
  readonly reasoningDetails?: ReasoningDetails | null
198
371
  } | null
199
372
  }
200
373
 
374
+ /**
375
+ * OpenRouter metadata attached to tool-call response parts.
376
+ *
377
+ * Associates tool calls with provider reasoning details when the model emits
378
+ * reasoning and tool calls together.
379
+ *
380
+ * @category response
381
+ * @since 4.0.0
382
+ */
201
383
  export interface ToolCallPartMetadata extends ProviderMetadata {
384
+ /**
385
+ * Provider-specific metadata returned for the tool call.
386
+ */
202
387
  readonly openrouter?: {
388
+ /**
389
+ * Reasoning details associated with this tool call.
390
+ */
203
391
  readonly reasoningDetails?: ReasoningDetails | null
204
392
  } | null
205
393
  }
206
394
 
395
+ /**
396
+ * OpenRouter metadata attached to URL source citations.
397
+ *
398
+ * Includes citation text and offsets returned by providers that support URL
399
+ * annotations.
400
+ *
401
+ * @category response
402
+ * @since 4.0.0
403
+ */
207
404
  export interface UrlSourcePartMetadata extends ProviderMetadata {
405
+ /**
406
+ * Provider-specific citation metadata returned for the URL source.
407
+ */
208
408
  readonly openrouter?: {
409
+ /**
410
+ * The cited source content returned by the provider.
411
+ */
209
412
  readonly content?: string | null
413
+ /**
414
+ * The zero-based start index of the citation in the generated text.
415
+ */
210
416
  readonly startIndex?: number | null
417
+ /**
418
+ * The zero-based end index of the citation in the generated text.
419
+ */
211
420
  readonly endIndex?: number | null
212
421
  } | null
213
422
  }
214
423
 
424
+ /**
425
+ * OpenRouter metadata attached to finish response parts.
426
+ *
427
+ * Exposes provider response details that are not represented by the common
428
+ * Effect AI finish part fields.
429
+ *
430
+ * @category response
431
+ * @since 4.0.0
432
+ */
215
433
  export interface FinishPartMetadata extends ProviderMetadata {
434
+ /**
435
+ * Provider-specific metadata returned when the OpenRouter response finishes.
436
+ */
216
437
  readonly openrouter?: {
438
+ /**
439
+ * Provider fingerprint for the backend configuration that served the request.
440
+ */
217
441
  readonly systemFingerprint?: string | null
442
+ /**
443
+ * Raw token usage reported by OpenRouter.
444
+ */
218
445
  readonly usage?: typeof Generated.ChatGenerationTokenUsage.Encoded | null
446
+ /**
447
+ * File annotations returned by the provider.
448
+ */
219
449
  readonly annotations?: ReadonlyArray<FileAnnotation> | null
450
+ /**
451
+ * The OpenRouter provider that served the request, when reported.
452
+ */
220
453
  readonly provider?: string | null
221
454
  } | null
222
455
  }
@@ -227,8 +460,10 @@ declare module "effect/unstable/ai/Response" {
227
460
  // =============================================================================
228
461
 
229
462
  /**
230
- * @since 1.0.0
463
+ * Creates an AI model descriptor for an OpenRouter language model.
464
+ *
231
465
  * @category constructors
466
+ * @since 4.0.0
232
467
  */
233
468
  export const model = (
234
469
  model: string,
@@ -239,8 +474,8 @@ export const model = (
239
474
  /**
240
475
  * Creates an OpenRouter language model service.
241
476
  *
242
- * @since 1.0.0
243
477
  * @category constructors
478
+ * @since 4.0.0
244
479
  */
245
480
  export const make = Effect.fnUntraced(function*({ model, config: providerConfig }: {
246
481
  readonly model: string
@@ -308,8 +543,8 @@ export const make = Effect.fnUntraced(function*({ model, config: providerConfig
308
543
  /**
309
544
  * Creates a layer for the OpenRouter language model.
310
545
  *
311
- * @since 1.0.0
312
546
  * @category layers
547
+ * @since 4.0.0
313
548
  */
314
549
  export const layer = (options: {
315
550
  readonly model: string
@@ -320,37 +555,37 @@ export const layer = (options: {
320
555
  /**
321
556
  * Provides config overrides for OpenRouter language model operations.
322
557
  *
323
- * @since 1.0.0
324
558
  * @category configuration
559
+ * @since 4.0.0
325
560
  */
326
561
  export const withConfigOverride: {
327
562
  /**
328
563
  * Provides config overrides for OpenRouter language model operations.
329
564
  *
330
- * @since 1.0.0
331
565
  * @category configuration
566
+ * @since 4.0.0
332
567
  */
333
568
  (overrides: typeof Config.Service): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, Config>>
334
569
  /**
335
570
  * Provides config overrides for OpenRouter language model operations.
336
571
  *
337
- * @since 1.0.0
338
572
  * @category configuration
573
+ * @since 4.0.0
339
574
  */
340
575
  <A, E, R>(self: Effect.Effect<A, E, R>, overrides: typeof Config.Service): Effect.Effect<A, E, Exclude<R, Config>>
341
576
  } = dual<
342
577
  /**
343
578
  * Provides config overrides for OpenRouter language model operations.
344
579
  *
345
- * @since 1.0.0
346
580
  * @category configuration
581
+ * @since 4.0.0
347
582
  */
348
583
  (overrides: typeof Config.Service) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, Config>>,
349
584
  /**
350
585
  * Provides config overrides for OpenRouter language model operations.
351
586
  *
352
- * @since 1.0.0
353
587
  * @category configuration
588
+ * @since 4.0.0
354
589
  */
355
590
  <A, E, R>(self: Effect.Effect<A, E, R>, overrides: typeof Config.Service) => Effect.Effect<A, E, Exclude<R, Config>>
356
591
  >(2, (self, overrides) =>
package/src/index.ts CHANGED
@@ -1,21 +1,61 @@
1
1
  /**
2
- * @since 1.0.0
2
+ * @since 4.0.0
3
3
  */
4
4
 
5
5
  // @barrel: Auto-generated exports. Do not edit manually.
6
6
 
7
7
  /**
8
- * @since 1.0.0
8
+ * @since 4.0.0
9
9
  */
10
10
  export * as Generated from "./Generated.ts"
11
11
 
12
12
  /**
13
- * @since 1.0.0
13
+ * The `OpenRouterClient` module provides an Effect service for calling
14
+ * OpenRouter's chat completions API. It wraps the generated OpenRouter HTTP
15
+ * client with Effect-native constructors, layers, typed errors, and streaming
16
+ * support.
17
+ *
18
+ * **Common tasks**
19
+ *
20
+ * - Build a client from explicit options with {@link make}
21
+ * - Provide the client to an application with {@link layer} or {@link layerConfig}
22
+ * - Create non-streaming chat completions with {@link Service.createChatCompletion}
23
+ * - Create server-sent event chat completion streams with
24
+ * {@link Service.createChatCompletionStream}
25
+ * - Customize authentication, base URL, OpenRouter ranking headers, or the
26
+ * underlying HTTP client through {@link Options}
27
+ *
28
+ * **Gotchas**
29
+ *
30
+ * - Streaming requests are sent directly to `/chat/completions` with `stream`
31
+ * and `stream_options.include_usage` enabled by this module.
32
+ * - OpenRouter API failures, HTTP client failures, and schema decoding failures
33
+ * are mapped into `AiError` values for the exported service methods.
34
+ *
35
+ * @since 4.0.0
14
36
  */
15
37
  export * as OpenRouterClient from "./OpenRouterClient.ts"
16
38
 
17
39
  /**
18
- * @since 1.0.0
40
+ * The `OpenRouterConfig` module provides contextual configuration for the
41
+ * OpenRouter provider integration. It is used to customize the HTTP client that
42
+ * backs OpenRouter requests without rebuilding the provider layer itself.
43
+ *
44
+ * Use {@link withClientTransform} when a single effect, workflow, or scoped
45
+ * portion of an application needs to add cross-cutting HTTP client behavior
46
+ * such as request logging, retries, proxy routing, additional headers, or test
47
+ * doubles. The configuration is read from the current Effect context, so the
48
+ * transform only applies where the returned effect is run with that context.
49
+ *
50
+ * **Gotchas**
51
+ *
52
+ * - Each call to {@link withClientTransform} replaces the current client
53
+ * transform for the provided effect; compose transforms manually when both
54
+ * behaviors should apply.
55
+ * - The transform receives and returns an `HttpClient`, so it should preserve
56
+ * the OpenRouter client contract while adding behavior around it.
57
+ *
58
+ * @since 4.0.0
19
59
  */
20
60
  export * as OpenRouterConfig from "./OpenRouterConfig.ts"
21
61
 
@@ -25,11 +65,31 @@ export * as OpenRouterConfig from "./OpenRouterConfig.ts"
25
65
  * Provides OpenRouter-specific metadata fields for AI error types through
26
66
  * module augmentation, enabling typed access to OpenRouter error details.
27
67
  *
28
- * @since 1.0.0
68
+ * @since 4.0.0
29
69
  */
30
70
  export * as OpenRouterError from "./OpenRouterError.ts"
31
71
 
32
72
  /**
33
- * @since 1.0.0
73
+ * The `OpenRouterLanguageModel` module provides constructors for using
74
+ * OpenRouter chat completion models through the Effect AI `LanguageModel`
75
+ * interface. It adapts Effect prompts, tools, structured output schemas, file
76
+ * parts, reasoning details, cache-control hints, and telemetry annotations into
77
+ * the OpenRouter request and response formats.
78
+ *
79
+ * Use this module when an application wants to select an OpenRouter model by
80
+ * name while keeping the rest of its AI workflow provider-agnostic. The
81
+ * exported layer and model constructors install a `LanguageModel` service backed
82
+ * by `OpenRouterClient`, and `withConfigOverride` can scope per-request
83
+ * OpenRouter options such as sampling, routing, tool use, or JSON schema
84
+ * behavior.
85
+ *
86
+ * OpenRouter routes requests to many underlying providers, so model support for
87
+ * images, files, tools, structured outputs, caching, and reasoning metadata can
88
+ * vary. Provider-specific prompt and response metadata is preserved under the
89
+ * `openrouter` option namespace so multi-turn conversations can round-trip
90
+ * details such as reasoning blocks and file annotations when the selected model
91
+ * supports them.
92
+ *
93
+ * @since 4.0.0
34
94
  */
35
95
  export * as OpenRouterLanguageModel from "./OpenRouterLanguageModel.ts"
@@ -41,7 +41,6 @@ export class ReasoningDetailsDuplicateTracker {
41
41
  /**
42
42
  * Attempts to track a detail.
43
43
  *
44
- * @returns `true` if this is a NEW detail (not seen before and has valid key),
45
44
  * or `false` if it was skipped (no valid key) or already seen (duplicate).
46
45
  */
47
46
  upsert(detail: ReasoningDetails[number]): boolean {