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

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,19 @@ 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
+ * **When to use**
102
+ *
103
+ * Use when accessing or providing the OpenRouter client service through
104
+ * Effect's context.
105
+ *
106
+ * @see {@link make} for constructing an OpenRouter client effectfully
107
+ * @see {@link layer} for providing a client from explicit options
108
+ * @see {@link layerConfig} for providing a client from `Config`
109
+ *
110
+ * @category services
111
+ * @since 4.0.0
72
112
  */
73
- export class OpenRouterClient extends ServiceMap.Service<
113
+ export class OpenRouterClient extends Context.Service<
74
114
  OpenRouterClient,
75
115
  Service
76
116
  >()("@effect/ai-openrouter/OpenRouterClient") {}
@@ -82,8 +122,8 @@ export class OpenRouterClient extends ServiceMap.Service<
82
122
  /**
83
123
  * Configuration options for creating an OpenRouter client.
84
124
  *
85
- * @since 1.0.0
86
125
  * @category models
126
+ * @since 4.0.0
87
127
  */
88
128
  export type Options = {
89
129
  readonly apiKey?: Redacted.Redacted<string> | undefined
@@ -103,7 +143,9 @@ export type Options = {
103
143
  /**
104
144
  * Optional transformer for the underlying HTTP client.
105
145
  *
106
- * Use this to add middleware, logging, or custom request/response handling.
146
+ * **When to use**
147
+ *
148
+ * Use to add middleware, logging, or custom request/response handling.
107
149
  */
108
150
  readonly transformClient?: ((client: HttpClient.HttpClient) => HttpClient.HttpClient) | undefined
109
151
  }
@@ -113,10 +155,31 @@ export type Options = {
113
155
  // =============================================================================
114
156
 
115
157
  /**
116
- * Creates an OpenRouter client service with the given options.
158
+ * Creates an OpenRouter client service from explicit options.
159
+ *
160
+ * **When to use**
161
+ *
162
+ * Use to construct the OpenRouter client service inside an effect when you need
163
+ * the service value directly.
164
+ *
165
+ * **Details**
166
+ *
167
+ * The returned service uses the current `HttpClient`, prepends `apiUrl` or
168
+ * `https://openrouter.ai/api/v1`, adds the bearer token and optional
169
+ * `HTTP-Referer` and `X-Title` headers, accepts JSON responses, and applies
170
+ * `transformClient` when provided.
171
+ *
172
+ * **Gotchas**
173
+ *
174
+ * Scoped `OpenRouterConfig.withClientTransform` applies to generated client
175
+ * request methods. Streaming chat completion requests are sent directly by this
176
+ * module and do not read that scoped transform.
177
+ *
178
+ * @see {@link layer} for providing this client from explicit options
179
+ * @see {@link layerConfig} for loading client settings from `Config`
117
180
  *
118
- * @since 1.0.0
119
181
  * @category constructors
182
+ * @since 4.0.0
120
183
  */
121
184
  export const make = Effect.fnUntraced(
122
185
  function*(options: Options): Effect.fn.Return<Service, never, HttpClient.HttpClient> {
@@ -127,7 +190,7 @@ export const make = Effect.fnUntraced(
127
190
  request.pipe(
128
191
  HttpClientRequest.prependUrl(options.apiUrl ?? "https://openrouter.ai/api/v1"),
129
192
  options.apiKey ? HttpClientRequest.bearerToken(options.apiKey) : identity,
130
- options.siteReferrer ? HttpClientRequest.setHeader("HTTP-Referrer", options.siteReferrer) : identity,
193
+ options.siteReferrer ? HttpClientRequest.setHeader("HTTP-Referer", options.siteReferrer) : identity,
131
194
  options.siteTitle ? HttpClientRequest.setHeader("X-Title", options.siteTitle) : identity,
132
195
  HttpClientRequest.acceptJson
133
196
  )
@@ -212,24 +275,45 @@ export const make = Effect.fnUntraced(
212
275
  /**
213
276
  * Creates a layer for the OpenRouter client with the given options.
214
277
  *
215
- * @since 1.0.0
278
+ * **When to use**
279
+ *
280
+ * Use when you already have the OpenRouter client options in code and want to
281
+ * provide `OpenRouterClient` as a layer.
282
+ *
283
+ * @see {@link make} for constructing the client service effectfully
284
+ * @see {@link layerConfig} for loading client settings from `Config`
285
+ *
216
286
  * @category layers
287
+ * @since 4.0.0
217
288
  */
218
289
  export const layer = (options: Options): Layer.Layer<OpenRouterClient, never, HttpClient.HttpClient> =>
219
290
  Layer.effect(OpenRouterClient, make(options))
220
291
 
221
292
  /**
222
- * Creates a layer for the OpenRouter client, loading the requisite
223
- * configuration via Effect's `Config` module.
293
+ * Creates a layer for the OpenRouter client from provided `Config` values.
294
+ *
295
+ * **When to use**
296
+ *
297
+ * Use when OpenRouter client settings should be read from Effect `Config`
298
+ * values while providing `OpenRouterClient` as a layer.
299
+ *
300
+ * **Details**
301
+ *
302
+ * Only config values supplied in `options` are loaded. Omitted fields are
303
+ * passed to `make` as `undefined`, and `transformClient` is forwarded as a
304
+ * plain option.
305
+ *
306
+ * @see {@link make} for constructing the client service effectfully
307
+ * @see {@link layer} for providing the client from already-resolved options
224
308
  *
225
- * @since 1.0.0
226
309
  * @category layers
310
+ * @since 4.0.0
227
311
  */
228
312
  export const layerConfig = (options?: {
229
313
  /**
230
314
  * The config value to load for the API key.
231
315
  */
232
- readonly apiKey?: Config.Config<Redacted.Redacted<string>> | undefined
316
+ readonly apiKey?: Config.Config<Redacted.Redacted<string> | undefined> | undefined
233
317
 
234
318
  /**
235
319
  * The config value to load for the API URL.