1/**
2 * The `OpenAiConfig` module lets a workflow temporarily customize the HTTP
3 * client used by OpenAI-compatible request helpers. Model, embedding, and
4 * tool-calling code can use this scoped configuration to add middleware,
5 * instrumentation, or routing without rebuilding the client layer.
6 *
7 * @since 4.0.0
8 */
9import * as Context from "effect/Context"
10import * as Effect from "effect/Effect"
11import { dual } from "effect/Function"
12import type { HttpClient } from "effect/http/HttpClient"
13
14/**
15 * Context service for OpenAI-compatible client configuration in the current
16 * Effect scope.
17 *
18 * **When to use**
19 *
20 * Use as the context service for scoped OpenAI-compatible client configuration
21 * and HTTP client transforms.
22 *
23 * @see {@link withClientTransform} for scoping an HTTP client transformation
24 *
25 * @category services
26 * @since 4.0.0
27 */
28export class OpenAiConfig extends Context.Service<
29 OpenAiConfig,
30 OpenAiConfig.Service
31>()("@effect/ai-openai-compat/OpenAiConfig") {
32 /**
33 * Gets the configured OpenAI-compatible service from the current context when present.
34 *
35 * @since 4.0.0
36 */
37 static readonly getOrUndefined: Effect.Effect<typeof OpenAiConfig.Service | undefined> = Effect.map(
38 Effect.context<never>(),
39 Context.getOrUndefined(OpenAiConfig)
40 )
41}
42
43/**
44 * Types associated with the `OpenAiConfig` context service.
45 *
46 * @since 4.0.0
47 */
48export declare namespace OpenAiConfig {
49 /**
50 * Configuration consumed by OpenAI-compatible clients when they build or
51 * resolve the underlying HTTP client.
52 *
53 * @category services
54 * @since 4.0.0
55 */
56 export interface Service {
57 readonly transformClient?: ((client: HttpClient) => HttpClient) | undefined
58 }
59}
60
61/**
62 * Provides an HTTP client transform for the supplied effect.
63 *
64 * **When to use**
65 *
66 * Use to add provider-specific OpenAI-compatible HTTP behavior, such as
67 * headers, retries, instrumentation, or proxy routing.
68 *
69 * **Details**
70 *
71 * OpenAI-compatible provider services read the transform from the
72 * `OpenAiConfig` context.
73 *
74 * @category configuration
75 * @since 4.0.0
76 */
77export const withClientTransform: {
78 (transform: (client: HttpClient) => HttpClient): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>
79 <A, E, R>(self: Effect.Effect<A, E, R>, transform: (client: HttpClient) => HttpClient): Effect.Effect<A, E, R>
80} = dual(2, <A, E, R>(
81 self: Effect.Effect<A, E, R>,
82 transformClient: (client: HttpClient) => HttpClient
83) =>
84 Effect.flatMap(
85 OpenAiConfig.getOrUndefined,
86 (config) => Effect.provideService(self, OpenAiConfig, { ...config, transformClient })
87 ))