@effect/ai-openrouter 4.0.0-beta.7 → 4.0.0-beta.70

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/src/Generated.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @since 1.0.0
2
+ * @since 4.0.0
3
3
  */
4
4
 
5
5
  import * as Data from "effect/Data"
@@ -678,6 +678,7 @@ export type ProviderName =
678
678
  | "Inceptron"
679
679
  | "InferenceNet"
680
680
  | "Infermatic"
681
+ | "Io Net"
681
682
  | "Inflection"
682
683
  | "Liquid"
683
684
  | "Mara"
@@ -751,6 +752,7 @@ export const ProviderName = Schema.Literals([
751
752
  "Inceptron",
752
753
  "InferenceNet",
753
754
  "Infermatic",
755
+ "Io Net",
754
756
  "Inflection",
755
757
  "Liquid",
756
758
  "Mara",
@@ -2583,6 +2585,7 @@ export type __schema5 = ReadonlyArray<
2583
2585
  | "Inceptron"
2584
2586
  | "InferenceNet"
2585
2587
  | "Infermatic"
2588
+ | "Io Net"
2586
2589
  | "Inflection"
2587
2590
  | "Liquid"
2588
2591
  | "Mara"
@@ -2660,6 +2663,7 @@ export const __schema5 = Schema.Array(
2660
2663
  "Inceptron",
2661
2664
  "InferenceNet",
2662
2665
  "Infermatic",
2666
+ "Io Net",
2663
2667
  "Inflection",
2664
2668
  "Liquid",
2665
2669
  "Mara",
@@ -2705,9 +2709,9 @@ export type __schema11 = number
2705
2709
  export const __schema11 = Schema.Number.check(Schema.isFinite())
2706
2710
  export type __schema13 = unknown
2707
2711
  export const __schema13 = Schema.Unknown
2708
- export type __schema20 = string | null
2709
- export const __schema20 = Schema.Union([Schema.String, Schema.Null])
2710
- export type __schema21 =
2712
+ export type __schema21 = string | null
2713
+ export const __schema21 = Schema.Union([Schema.String, Schema.Null])
2714
+ export type __schema22 =
2711
2715
  | "unknown"
2712
2716
  | "openai-responses-v1"
2713
2717
  | "azure-openai-responses-v1"
@@ -2715,7 +2719,7 @@ export type __schema21 =
2715
2719
  | "anthropic-claude-v1"
2716
2720
  | "google-gemini-v1"
2717
2721
  | null
2718
- export const __schema21 = Schema.Union([
2722
+ export const __schema22 = Schema.Union([
2719
2723
  Schema.Literals([
2720
2724
  "unknown",
2721
2725
  "openai-responses-v1",
@@ -2850,24 +2854,6 @@ export const ChatMessageContentItemCacheControl = Schema.Struct({
2850
2854
  "type": Schema.Literal("ephemeral"),
2851
2855
  "ttl": Schema.optionalKey(Schema.Literals(["5m", "1h"]))
2852
2856
  })
2853
- export type ToolDefinitionJson = {
2854
- readonly "type": "function"
2855
- readonly "function": {
2856
- readonly "name": string
2857
- readonly "description"?: string
2858
- readonly "parameters"?: {}
2859
- readonly "strict"?: boolean | null
2860
- }
2861
- }
2862
- export const ToolDefinitionJson = Schema.Struct({
2863
- "type": Schema.Literal("function"),
2864
- "function": Schema.Struct({
2865
- "name": Schema.String.check(Schema.isMaxLength(64)),
2866
- "description": Schema.optionalKey(Schema.String),
2867
- "parameters": Schema.optionalKey(Schema.Struct({}).check(Schema.isPropertyNames(Schema.String))),
2868
- "strict": Schema.optionalKey(Schema.Union([Schema.Boolean, Schema.Null]))
2869
- })
2870
- })
2871
2857
  export type NamedToolChoice = { readonly "type": "function"; readonly "function": { readonly "name": string } }
2872
2858
  export const NamedToolChoice = Schema.Struct({
2873
2859
  "type": Schema.Literal("function"),
@@ -2877,16 +2863,19 @@ export type ChatStreamOptions = { readonly "include_usage"?: boolean }
2877
2863
  export const ChatStreamOptions = Schema.Struct({ "include_usage": Schema.optionalKey(Schema.Boolean) })
2878
2864
  export type ChatStreamingMessageToolCall = {
2879
2865
  readonly "index": number
2880
- readonly "id"?: string
2881
- readonly "type"?: "function"
2882
- readonly "function"?: { readonly "name"?: string; readonly "arguments"?: string }
2866
+ readonly "id"?: string | null
2867
+ readonly "type"?: "function" | null
2868
+ readonly "function"?: { readonly "name"?: string | null; readonly "arguments"?: string }
2883
2869
  }
2884
2870
  export const ChatStreamingMessageToolCall = Schema.Struct({
2885
2871
  "index": Schema.Number.check(Schema.isFinite()),
2886
- "id": Schema.optionalKey(Schema.String),
2887
- "type": Schema.optionalKey(Schema.Literal("function")),
2872
+ "id": Schema.optionalKey(Schema.Union([Schema.String, Schema.Null])),
2873
+ "type": Schema.optionalKey(Schema.Union([Schema.Literal("function"), Schema.Null])),
2888
2874
  "function": Schema.optionalKey(
2889
- Schema.Struct({ "name": Schema.optionalKey(Schema.String), "arguments": Schema.optionalKey(Schema.String) })
2875
+ Schema.Struct({
2876
+ "name": Schema.optionalKey(Schema.Union([Schema.String, Schema.Null])),
2877
+ "arguments": Schema.optionalKey(Schema.String)
2878
+ })
2890
2879
  )
2891
2880
  })
2892
2881
  export type ChatError = {
@@ -3551,47 +3540,47 @@ export const PublicEndpoint = Schema.Struct({
3551
3540
  "Throughput percentiles in tokens per second over the last 30 minutes. Throughput measures output token generation speed. Only visible when authenticated with an API key or cookie; returns null for unauthenticated requests."
3552
3541
  })
3553
3542
  }).annotate({ "description": "Information about a specific model endpoint" })
3554
- export type __schema19 = {
3543
+ export type __schema20 = {
3555
3544
  readonly "type": "reasoning.summary"
3556
3545
  readonly "summary": string
3557
- readonly "id"?: __schema20
3558
- readonly "format"?: __schema21
3546
+ readonly "id"?: __schema21
3547
+ readonly "format"?: __schema22
3559
3548
  readonly "index"?: __schema11
3560
3549
  } | {
3561
3550
  readonly "type": "reasoning.encrypted"
3562
3551
  readonly "data": string
3563
- readonly "id"?: __schema20
3564
- readonly "format"?: __schema21
3552
+ readonly "id"?: __schema21
3553
+ readonly "format"?: __schema22
3565
3554
  readonly "index"?: __schema11
3566
3555
  } | {
3567
3556
  readonly "type": "reasoning.text"
3568
3557
  readonly "text"?: string | null
3569
3558
  readonly "signature"?: string | null
3570
- readonly "id"?: __schema20
3571
- readonly "format"?: __schema21
3559
+ readonly "id"?: __schema21
3560
+ readonly "format"?: __schema22
3572
3561
  readonly "index"?: __schema11
3573
3562
  }
3574
- export const __schema19 = Schema.Union([
3563
+ export const __schema20 = Schema.Union([
3575
3564
  Schema.Struct({
3576
3565
  "type": Schema.Literal("reasoning.summary"),
3577
3566
  "summary": Schema.String,
3578
- "id": Schema.optionalKey(__schema20),
3579
- "format": Schema.optionalKey(__schema21),
3567
+ "id": Schema.optionalKey(__schema21),
3568
+ "format": Schema.optionalKey(__schema22),
3580
3569
  "index": Schema.optionalKey(__schema11)
3581
3570
  }),
3582
3571
  Schema.Struct({
3583
3572
  "type": Schema.Literal("reasoning.encrypted"),
3584
3573
  "data": Schema.String,
3585
- "id": Schema.optionalKey(__schema20),
3586
- "format": Schema.optionalKey(__schema21),
3574
+ "id": Schema.optionalKey(__schema21),
3575
+ "format": Schema.optionalKey(__schema22),
3587
3576
  "index": Schema.optionalKey(__schema11)
3588
3577
  }),
3589
3578
  Schema.Struct({
3590
3579
  "type": Schema.Literal("reasoning.text"),
3591
3580
  "text": Schema.optionalKey(Schema.Union([Schema.String, Schema.Null])),
3592
3581
  "signature": Schema.optionalKey(Schema.Union([Schema.String, Schema.Null])),
3593
- "id": Schema.optionalKey(__schema20),
3594
- "format": Schema.optionalKey(__schema21),
3582
+ "id": Schema.optionalKey(__schema21),
3583
+ "format": Schema.optionalKey(__schema22),
3595
3584
  "index": Schema.optionalKey(__schema11)
3596
3585
  })
3597
3586
  ], { mode: "oneOf" })
@@ -3605,8 +3594,8 @@ export const ChatMessageTokenLogprobs = Schema.Struct({
3605
3594
  "content": Schema.Union([Schema.Array(ChatMessageTokenLogprob), Schema.Null]),
3606
3595
  "refusal": Schema.Union([Schema.Array(ChatMessageTokenLogprob), Schema.Null])
3607
3596
  })
3608
- export type __schema25 = ChatCompletionFinishReason | null
3609
- export const __schema25 = Schema.Union([ChatCompletionFinishReason, Schema.Null])
3597
+ export type __schema26 = ChatCompletionFinishReason | null
3598
+ export const __schema26 = Schema.Union([ChatCompletionFinishReason, Schema.Null])
3610
3599
  export type ResponseFormatJSONSchema = { readonly "type": "json_schema"; readonly "json_schema": JSONSchemaConfig }
3611
3600
  export const ResponseFormatJSONSchema = Schema.Struct({
3612
3601
  "type": Schema.Literal("json_schema"),
@@ -3622,6 +3611,26 @@ export const ChatMessageContentItemText = Schema.Struct({
3622
3611
  "text": Schema.String,
3623
3612
  "cache_control": Schema.optionalKey(ChatMessageContentItemCacheControl)
3624
3613
  })
3614
+ export type ToolDefinitionJson = {
3615
+ readonly "type": "function"
3616
+ readonly "function": {
3617
+ readonly "name": string
3618
+ readonly "description"?: string
3619
+ readonly "parameters"?: {}
3620
+ readonly "strict"?: boolean | null
3621
+ }
3622
+ readonly "cache_control"?: ChatMessageContentItemCacheControl
3623
+ }
3624
+ export const ToolDefinitionJson = Schema.Struct({
3625
+ "type": Schema.Literal("function"),
3626
+ "function": Schema.Struct({
3627
+ "name": Schema.String.check(Schema.isMaxLength(64)),
3628
+ "description": Schema.optionalKey(Schema.String),
3629
+ "parameters": Schema.optionalKey(Schema.Struct({}).check(Schema.isPropertyNames(Schema.String))),
3630
+ "strict": Schema.optionalKey(Schema.Union([Schema.Boolean, Schema.Null]))
3631
+ }),
3632
+ "cache_control": Schema.optionalKey(ChatMessageContentItemCacheControl)
3633
+ })
3625
3634
  export type ToolChoiceOption = "none" | "auto" | "required" | NamedToolChoice
3626
3635
  export const ToolChoiceOption = Schema.Union([
3627
3636
  Schema.Literal("none"),
@@ -3970,6 +3979,13 @@ export type AnthropicMessagesRequest = {
3970
3979
  readonly "route"?: "fallback" | "sort"
3971
3980
  readonly "user"?: string
3972
3981
  readonly "session_id"?: string
3982
+ readonly "trace"?: {
3983
+ readonly "trace_id"?: string
3984
+ readonly "trace_name"?: string
3985
+ readonly "span_name"?: string
3986
+ readonly "generation_name"?: string
3987
+ readonly "parent_span_id"?: string
3988
+ }
3973
3989
  readonly "models"?: ReadonlyArray<string>
3974
3990
  readonly "output_config"?: AnthropicOutputConfig
3975
3991
  }
@@ -4257,6 +4273,18 @@ export const AnthropicMessagesRequest = Schema.Struct({
4257
4273
  "A unique identifier for grouping related requests (e.g., a conversation or agent workflow) for observability. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 128 characters."
4258
4274
  }).check(Schema.isMaxLength(128))
4259
4275
  ),
4276
+ "trace": Schema.optionalKey(
4277
+ Schema.Struct({
4278
+ "trace_id": Schema.optionalKey(Schema.String),
4279
+ "trace_name": Schema.optionalKey(Schema.String),
4280
+ "span_name": Schema.optionalKey(Schema.String),
4281
+ "generation_name": Schema.optionalKey(Schema.String),
4282
+ "parent_span_id": Schema.optionalKey(Schema.String)
4283
+ }).annotate({
4284
+ "description":
4285
+ "Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations."
4286
+ })
4287
+ ),
4260
4288
  "models": Schema.optionalKey(Schema.Array(Schema.String)),
4261
4289
  "output_config": Schema.optionalKey(AnthropicOutputConfig)
4262
4290
  }).annotate({ "description": "Request schema for Anthropic Messages API endpoint" })
@@ -4440,7 +4468,7 @@ export type ChatStreamingMessageChunk = {
4440
4468
  readonly "reasoning"?: string | null
4441
4469
  readonly "refusal"?: string | null
4442
4470
  readonly "tool_calls"?: ReadonlyArray<ChatStreamingMessageToolCall>
4443
- readonly "reasoning_details"?: ReadonlyArray<__schema19>
4471
+ readonly "reasoning_details"?: ReadonlyArray<__schema20>
4444
4472
  readonly "images"?:
4445
4473
  | ReadonlyArray<{ readonly "type": "image_url"; readonly "image_url": { readonly "url": string } }>
4446
4474
  | null
@@ -4475,7 +4503,7 @@ export const ChatStreamingMessageChunk = Schema.Struct({
4475
4503
  "reasoning": Schema.optionalKey(Schema.Union([Schema.String, Schema.Null])),
4476
4504
  "refusal": Schema.optionalKey(Schema.Union([Schema.String, Schema.Null])),
4477
4505
  "tool_calls": Schema.optionalKey(Schema.Array(ChatStreamingMessageToolCall)),
4478
- "reasoning_details": Schema.optionalKey(Schema.Array(__schema19)),
4506
+ "reasoning_details": Schema.optionalKey(Schema.Array(__schema20)),
4479
4507
  "images": Schema.optionalKey(
4480
4508
  Schema.Union([
4481
4509
  Schema.Array(
@@ -4609,13 +4637,13 @@ export type ModelsListResponseData = ReadonlyArray<Model>
4609
4637
  export const ModelsListResponseData = Schema.Array(Model).annotate({ "description": "List of available models" })
4610
4638
  export type ChatStreamingChoice = {
4611
4639
  readonly "delta": ChatStreamingMessageChunk
4612
- readonly "finish_reason": __schema25
4640
+ readonly "finish_reason"?: __schema26
4613
4641
  readonly "index": number
4614
4642
  readonly "logprobs"?: ChatMessageTokenLogprobs | null
4615
4643
  }
4616
4644
  export const ChatStreamingChoice = Schema.Struct({
4617
4645
  "delta": ChatStreamingMessageChunk,
4618
- "finish_reason": __schema25,
4646
+ "finish_reason": Schema.optionalKey(__schema26),
4619
4647
  "index": Schema.Number.check(Schema.isFinite()),
4620
4648
  "logprobs": Schema.optionalKey(Schema.Union([ChatMessageTokenLogprobs, Schema.Null]))
4621
4649
  })
@@ -4636,7 +4664,7 @@ export type AssistantMessage = {
4636
4664
  readonly "tool_calls"?: ReadonlyArray<ChatMessageToolCall>
4637
4665
  readonly "refusal"?: string | null
4638
4666
  readonly "reasoning"?: string | null
4639
- readonly "reasoning_details"?: ReadonlyArray<__schema19>
4667
+ readonly "reasoning_details"?: ReadonlyArray<__schema20>
4640
4668
  readonly "images"?:
4641
4669
  | ReadonlyArray<{ readonly "type": "image_url"; readonly "image_url": { readonly "url": string } }>
4642
4670
  | null
@@ -4674,7 +4702,7 @@ export const AssistantMessage = Schema.Struct({
4674
4702
  "tool_calls": Schema.optionalKey(Schema.Array(ChatMessageToolCall)),
4675
4703
  "refusal": Schema.optionalKey(Schema.Union([Schema.String, Schema.Null])),
4676
4704
  "reasoning": Schema.optionalKey(Schema.Union([Schema.String, Schema.Null])),
4677
- "reasoning_details": Schema.optionalKey(Schema.Array(__schema19)),
4705
+ "reasoning_details": Schema.optionalKey(Schema.Array(__schema20)),
4678
4706
  "images": Schema.optionalKey(
4679
4707
  Schema.Union([
4680
4708
  Schema.Array(
@@ -4915,13 +4943,13 @@ export const ChatStreamingResponseChunk = Schema.Struct({
4915
4943
  })
4916
4944
  })
4917
4945
  export type ChatResponseChoice = {
4918
- readonly "finish_reason": __schema25
4946
+ readonly "finish_reason": __schema26
4919
4947
  readonly "index": number
4920
4948
  readonly "message": AssistantMessage
4921
4949
  readonly "logprobs"?: ChatMessageTokenLogprobs | null
4922
4950
  }
4923
4951
  export const ChatResponseChoice = Schema.Struct({
4924
- "finish_reason": __schema25,
4952
+ "finish_reason": __schema26,
4925
4953
  "index": Schema.Number.check(Schema.isFinite()),
4926
4954
  "message": AssistantMessage,
4927
4955
  "logprobs": Schema.optionalKey(Schema.Union([ChatMessageTokenLogprobs, Schema.Null]))
@@ -6299,6 +6327,13 @@ export type OpenResponsesRequest = {
6299
6327
  readonly "route"?: "fallback" | "sort"
6300
6328
  readonly "user"?: string
6301
6329
  readonly "session_id"?: string
6330
+ readonly "trace"?: {
6331
+ readonly "trace_id"?: string
6332
+ readonly "trace_name"?: string
6333
+ readonly "span_name"?: string
6334
+ readonly "generation_name"?: string
6335
+ readonly "parent_span_id"?: string
6336
+ }
6302
6337
  }
6303
6338
  export const OpenResponsesRequest = Schema.Struct({
6304
6339
  "input": Schema.optionalKey(OpenResponsesInput),
@@ -6504,6 +6539,18 @@ export const OpenResponsesRequest = Schema.Struct({
6504
6539
  "description":
6505
6540
  "A unique identifier for grouping related requests (e.g., a conversation or agent workflow) for observability. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 128 characters."
6506
6541
  }).check(Schema.isMaxLength(128))
6542
+ ),
6543
+ "trace": Schema.optionalKey(
6544
+ Schema.Struct({
6545
+ "trace_id": Schema.optionalKey(Schema.String),
6546
+ "trace_name": Schema.optionalKey(Schema.String),
6547
+ "span_name": Schema.optionalKey(Schema.String),
6548
+ "generation_name": Schema.optionalKey(Schema.String),
6549
+ "parent_span_id": Schema.optionalKey(Schema.String)
6550
+ }).annotate({
6551
+ "description":
6552
+ "Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations."
6553
+ })
6507
6554
  )
6508
6555
  }).annotate({ "description": "Request schema for Responses endpoint" })
6509
6556
  export type ChatGenerationParams = {
@@ -6560,6 +6607,13 @@ export type ChatGenerationParams = {
6560
6607
  readonly "route"?: "fallback" | "sort" | null
6561
6608
  readonly "user"?: string
6562
6609
  readonly "session_id"?: string
6610
+ readonly "trace"?: {
6611
+ readonly "trace_id"?: string
6612
+ readonly "trace_name"?: string
6613
+ readonly "span_name"?: string
6614
+ readonly "generation_name"?: string
6615
+ readonly "parent_span_id"?: string
6616
+ }
6563
6617
  readonly "messages": ReadonlyArray<Message>
6564
6618
  readonly "model"?: ModelName
6565
6619
  readonly "models"?: ReadonlyArray<ModelName>
@@ -6586,6 +6640,7 @@ export type ChatGenerationParams = {
6586
6640
  readonly "stream"?: boolean
6587
6641
  readonly "stream_options"?: ChatStreamOptions | null
6588
6642
  readonly "temperature"?: number | null
6643
+ readonly "parallel_tool_calls"?: boolean | null
6589
6644
  readonly "tool_choice"?: ToolChoiceOption
6590
6645
  readonly "tools"?: ReadonlyArray<ToolDefinitionJson>
6591
6646
  readonly "top_p"?: number | null
@@ -6734,6 +6789,18 @@ export const ChatGenerationParams = Schema.Struct({
6734
6789
  "A unique identifier for grouping related requests (e.g., a conversation or agent workflow) for observability. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 128 characters."
6735
6790
  }).check(Schema.isMaxLength(128))
6736
6791
  ),
6792
+ "trace": Schema.optionalKey(
6793
+ Schema.Struct({
6794
+ "trace_id": Schema.optionalKey(Schema.String),
6795
+ "trace_name": Schema.optionalKey(Schema.String),
6796
+ "span_name": Schema.optionalKey(Schema.String),
6797
+ "generation_name": Schema.optionalKey(Schema.String),
6798
+ "parent_span_id": Schema.optionalKey(Schema.String)
6799
+ }).annotate({
6800
+ "description":
6801
+ "Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations."
6802
+ })
6803
+ ),
6737
6804
  "messages": Schema.Array(Message).check(Schema.isMinLength(1)),
6738
6805
  "model": Schema.optionalKey(ModelName),
6739
6806
  "models": Schema.optionalKey(Schema.Array(ModelName)),
@@ -6810,6 +6877,7 @@ export const ChatGenerationParams = Schema.Struct({
6810
6877
  Schema.Null
6811
6878
  ])
6812
6879
  ),
6880
+ "parallel_tool_calls": Schema.optionalKey(Schema.Union([Schema.Boolean, Schema.Null])),
6813
6881
  "tool_choice": Schema.optionalKey(ToolChoiceOption),
6814
6882
  "tools": Schema.optionalKey(Schema.Array(ToolDefinitionJson)),
6815
6883
  "top_p": Schema.optionalKey(
@@ -7342,6 +7410,7 @@ export type GetGeneration200 = {
7342
7410
  | "Inceptron"
7343
7411
  | "InferenceNet"
7344
7412
  | "Infermatic"
7413
+ | "Io Net"
7345
7414
  | "Inflection"
7346
7415
  | "Liquid"
7347
7416
  | "Mara"
@@ -7522,6 +7591,7 @@ export const GetGeneration200 = Schema.Struct({
7522
7591
  "Inceptron",
7523
7592
  "InferenceNet",
7524
7593
  "Infermatic",
7594
+ "Io Net",
7525
7595
  "Inflection",
7526
7596
  "Liquid",
7527
7597
  "Mara",
@@ -1,14 +1,36 @@
1
1
  /**
2
- * @since 1.0.0
2
+ * The `OpenRouterClient` module provides an Effect service for calling
3
+ * OpenRouter's chat completions API. It wraps the generated OpenRouter HTTP
4
+ * client with Effect-native constructors, layers, typed errors, and streaming
5
+ * support.
6
+ *
7
+ * **Common tasks**
8
+ *
9
+ * - Build a client from explicit options with {@link make}
10
+ * - Provide the client to an application with {@link layer} or {@link layerConfig}
11
+ * - Create non-streaming chat completions with {@link Service.createChatCompletion}
12
+ * - Create server-sent event chat completion streams with
13
+ * {@link Service.createChatCompletionStream}
14
+ * - Customize authentication, base URL, OpenRouter ranking headers, or the
15
+ * underlying HTTP client through {@link Options}
16
+ *
17
+ * **Gotchas**
18
+ *
19
+ * - Streaming requests are sent directly to `/chat/completions` with `stream`
20
+ * and `stream_options.include_usage` enabled by this module.
21
+ * - OpenRouter API failures, HTTP client failures, and schema decoding failures
22
+ * are mapped into `AiError` values for the exported service methods.
23
+ *
24
+ * @since 4.0.0
3
25
  */
4
26
  import type * as Config from "effect/Config"
27
+ import * as Context from "effect/Context"
5
28
  import * as Effect from "effect/Effect"
6
29
  import { identity } from "effect/Function"
7
30
  import * as Layer from "effect/Layer"
8
31
  import * as Predicate from "effect/Predicate"
9
32
  import type * as Redacted from "effect/Redacted"
10
33
  import * as Schema from "effect/Schema"
11
- import * as ServiceMap from "effect/ServiceMap"
12
34
  import * as Stream from "effect/Stream"
13
35
  import type * as AiError from "effect/unstable/ai/AiError"
14
36
  import * as Sse from "effect/unstable/encoding/Sse"
@@ -27,11 +49,13 @@ import { OpenRouterConfig } from "./OpenRouterConfig.ts"
27
49
  /**
28
50
  * The OpenRouter client service interface.
29
51
  *
52
+ * **Details**
53
+ *
30
54
  * Provides methods for interacting with OpenRouter's Chat Completions API,
31
55
  * including both synchronous and streaming message creation.
32
56
  *
33
- * @since 1.0.0
34
57
  * @category models
58
+ * @since 4.0.0
35
59
  */
36
60
  export interface Service {
37
61
  readonly client: Generated.OpenRouterClient
@@ -55,8 +79,15 @@ export interface Service {
55
79
  }
56
80
 
57
81
  /**
58
- * @since 1.0.0
59
- * @category Models
82
+ * Decoded `data` payload from an OpenRouter chat completion streaming chunk.
83
+ *
84
+ * **Details**
85
+ *
86
+ * The payload contains streamed choices, model metadata, optional usage, and may
87
+ * include an OpenRouter error object for a streamed response.
88
+ *
89
+ * @category models
90
+ * @since 4.0.0
60
91
  */
61
92
  export type ChatStreamingResponseChunkData = typeof Generated.ChatStreamingResponseChunk.fields.data.Type
62
93
 
@@ -67,10 +98,10 @@ export type ChatStreamingResponseChunkData = typeof Generated.ChatStreamingRespo
67
98
  /**
68
99
  * Service identifier for the OpenRouter client.
69
100
  *
70
- * @since 1.0.0
71
- * @category service
101
+ * @category services
102
+ * @since 4.0.0
72
103
  */
73
- export class OpenRouterClient extends ServiceMap.Service<
104
+ export class OpenRouterClient extends Context.Service<
74
105
  OpenRouterClient,
75
106
  Service
76
107
  >()("@effect/ai-openrouter/OpenRouterClient") {}
@@ -82,8 +113,8 @@ export class OpenRouterClient extends ServiceMap.Service<
82
113
  /**
83
114
  * Configuration options for creating an OpenRouter client.
84
115
  *
85
- * @since 1.0.0
86
116
  * @category models
117
+ * @since 4.0.0
87
118
  */
88
119
  export type Options = {
89
120
  readonly apiKey?: Redacted.Redacted<string> | undefined
@@ -103,6 +134,8 @@ export type Options = {
103
134
  /**
104
135
  * Optional transformer for the underlying HTTP client.
105
136
  *
137
+ * **When to use**
138
+ *
106
139
  * Use this to add middleware, logging, or custom request/response handling.
107
140
  */
108
141
  readonly transformClient?: ((client: HttpClient.HttpClient) => HttpClient.HttpClient) | undefined
@@ -115,8 +148,8 @@ export type Options = {
115
148
  /**
116
149
  * Creates an OpenRouter client service with the given options.
117
150
  *
118
- * @since 1.0.0
119
151
  * @category constructors
152
+ * @since 4.0.0
120
153
  */
121
154
  export const make = Effect.fnUntraced(
122
155
  function*(options: Options): Effect.fn.Return<Service, never, HttpClient.HttpClient> {
@@ -127,7 +160,7 @@ export const make = Effect.fnUntraced(
127
160
  request.pipe(
128
161
  HttpClientRequest.prependUrl(options.apiUrl ?? "https://openrouter.ai/api/v1"),
129
162
  options.apiKey ? HttpClientRequest.bearerToken(options.apiKey) : identity,
130
- options.siteReferrer ? HttpClientRequest.setHeader("HTTP-Referrer", options.siteReferrer) : identity,
163
+ options.siteReferrer ? HttpClientRequest.setHeader("HTTP-Referer", options.siteReferrer) : identity,
131
164
  options.siteTitle ? HttpClientRequest.setHeader("X-Title", options.siteTitle) : identity,
132
165
  HttpClientRequest.acceptJson
133
166
  )
@@ -212,8 +245,8 @@ export const make = Effect.fnUntraced(
212
245
  /**
213
246
  * Creates a layer for the OpenRouter client with the given options.
214
247
  *
215
- * @since 1.0.0
216
248
  * @category layers
249
+ * @since 4.0.0
217
250
  */
218
251
  export const layer = (options: Options): Layer.Layer<OpenRouterClient, never, HttpClient.HttpClient> =>
219
252
  Layer.effect(OpenRouterClient, make(options))
@@ -222,14 +255,14 @@ export const layer = (options: Options): Layer.Layer<OpenRouterClient, never, Ht
222
255
  * Creates a layer for the OpenRouter client, loading the requisite
223
256
  * configuration via Effect's `Config` module.
224
257
  *
225
- * @since 1.0.0
226
258
  * @category layers
259
+ * @since 4.0.0
227
260
  */
228
261
  export const layerConfig = (options?: {
229
262
  /**
230
263
  * The config value to load for the API key.
231
264
  */
232
- readonly apiKey?: Config.Config<Redacted.Redacted<string>> | undefined
265
+ readonly apiKey?: Config.Config<Redacted.Redacted<string> | undefined> | undefined
233
266
 
234
267
  /**
235
268
  * The config value to load for the API URL.
@@ -1,35 +1,63 @@
1
1
  /**
2
- * @since 1.0.0
2
+ * The `OpenRouterConfig` module provides contextual configuration for the
3
+ * OpenRouter provider integration. It is used to customize the HTTP client that
4
+ * backs OpenRouter requests without rebuilding the provider layer itself.
5
+ *
6
+ * Use {@link withClientTransform} when a single effect, workflow, or scoped
7
+ * portion of an application needs to add cross-cutting HTTP client behavior
8
+ * such as request logging, retries, proxy routing, additional headers, or test
9
+ * doubles. The configuration is read from the current Effect context, so the
10
+ * transform only applies where the returned effect is run with that context.
11
+ *
12
+ * **Gotchas**
13
+ *
14
+ * - Each call to {@link withClientTransform} replaces the current client
15
+ * transform for the provided effect; compose transforms manually when both
16
+ * behaviors should apply.
17
+ * - The transform receives and returns an `HttpClient`, so it should preserve
18
+ * the OpenRouter client contract while adding behavior around it.
19
+ *
20
+ * @since 4.0.0
3
21
  */
22
+ import * as Context from "effect/Context"
4
23
  import * as Effect from "effect/Effect"
5
24
  import { dual } from "effect/Function"
6
- import * as ServiceMap from "effect/ServiceMap"
7
25
  import type { HttpClient } from "effect/unstable/http/HttpClient"
8
26
 
9
27
  /**
10
- * @since 1.0.0
28
+ * Context service carrying scoped OpenRouter provider configuration for client
29
+ * operations.
30
+ *
11
31
  * @category services
32
+ * @since 4.0.0
12
33
  */
13
- export class OpenRouterConfig extends ServiceMap.Service<
34
+ export class OpenRouterConfig extends Context.Service<
14
35
  OpenRouterConfig,
15
36
  OpenRouterConfig.Service
16
37
  >()("@effect/ai-openrouter/OpenRouterConfig") {
17
38
  /**
18
- * @since 1.0.0
39
+ * Gets the configured OpenRouter service from the current context when present.
40
+ *
41
+ * @since 4.0.0
19
42
  */
20
43
  static readonly getOrUndefined: Effect.Effect<typeof OpenRouterConfig.Service | undefined> = Effect.map(
21
- Effect.services<never>(),
44
+ Effect.context<never>(),
22
45
  (services) => services.mapUnsafe.get(OpenRouterConfig.key)
23
46
  )
24
47
  }
25
48
 
26
49
  /**
27
- * @since 1.0.0
50
+ * Types associated with the `OpenRouterConfig` context service.
51
+ *
52
+ * @since 4.0.0
28
53
  */
29
54
  export declare namespace OpenRouterConfig {
30
55
  /**
31
- * @since 1.0.0
56
+ * Configuration values read by OpenRouter provider operations when resolving
57
+ * the generated HTTP client.
58
+ *
32
59
  * @category models
60
+ * @since 4.0.0
33
61
  */
34
62
  export interface Service {
35
63
  readonly transformClient?: ((client: HttpClient) => HttpClient) | undefined
@@ -37,18 +65,27 @@ export declare namespace OpenRouterConfig {
37
65
  }
38
66
 
39
67
  /**
40
- * @since 1.0.0
68
+ * Provides a scoped transform for the OpenRouter HTTP client used by provider
69
+ * operations.
70
+ *
41
71
  * @category configuration
72
+ * @since 4.0.0
42
73
  */
43
74
  export const withClientTransform: {
44
75
  /**
45
- * @since 1.0.0
76
+ * Provides a scoped transform for the OpenRouter HTTP client used by provider
77
+ * operations.
78
+ *
46
79
  * @category configuration
80
+ * @since 4.0.0
47
81
  */
48
82
  (transform: (client: HttpClient) => HttpClient): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>
49
83
  /**
50
- * @since 1.0.0
84
+ * Provides a scoped transform for the OpenRouter HTTP client used by provider
85
+ * operations.
86
+ *
51
87
  * @category configuration
88
+ * @since 4.0.0
52
89
  */
53
90
  <A, E, R>(
54
91
  self: Effect.Effect<A, E, R>,
@@ -56,13 +93,19 @@ export const withClientTransform: {
56
93
  ): Effect.Effect<A, E, R>
57
94
  } = dual<
58
95
  /**
59
- * @since 1.0.0
96
+ * Provides a scoped transform for the OpenRouter HTTP client used by provider
97
+ * operations.
98
+ *
60
99
  * @category configuration
100
+ * @since 4.0.0
61
101
  */
62
102
  (transform: (client: HttpClient) => HttpClient) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>,
63
103
  /**
64
- * @since 1.0.0
104
+ * Provides a scoped transform for the OpenRouter HTTP client used by provider
105
+ * operations.
106
+ *
65
107
  * @category configuration
108
+ * @since 4.0.0
66
109
  */
67
110
  <A, E, R>(
68
111
  self: Effect.Effect<A, E, R>,