@effect/ai-openai-compat 4.0.0-beta.9 → 4.0.0-beta.91

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 (41) hide show
  1. package/dist/OpenAiClient.d.ts +264 -52
  2. package/dist/OpenAiClient.d.ts.map +1 -1
  3. package/dist/OpenAiClient.js +97 -9
  4. package/dist/OpenAiClient.js.map +1 -1
  5. package/dist/OpenAiConfig.d.ts +68 -10
  6. package/dist/OpenAiConfig.d.ts.map +1 -1
  7. package/dist/OpenAiConfig.js +36 -7
  8. package/dist/OpenAiConfig.js.map +1 -1
  9. package/dist/OpenAiEmbeddingModel.d.ts +186 -0
  10. package/dist/OpenAiEmbeddingModel.d.ts.map +1 -0
  11. package/dist/OpenAiEmbeddingModel.js +190 -0
  12. package/dist/OpenAiEmbeddingModel.js.map +1 -0
  13. package/dist/OpenAiError.d.ts +109 -35
  14. package/dist/OpenAiError.d.ts.map +1 -1
  15. package/dist/OpenAiError.js +14 -1
  16. package/dist/OpenAiLanguageModel.d.ts +304 -20
  17. package/dist/OpenAiLanguageModel.d.ts.map +1 -1
  18. package/dist/OpenAiLanguageModel.js +157 -27
  19. package/dist/OpenAiLanguageModel.js.map +1 -1
  20. package/dist/OpenAiTelemetry.d.ts +76 -26
  21. package/dist/OpenAiTelemetry.d.ts.map +1 -1
  22. package/dist/OpenAiTelemetry.js +22 -10
  23. package/dist/OpenAiTelemetry.js.map +1 -1
  24. package/dist/index.d.ts +10 -17
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +10 -17
  27. package/dist/index.js.map +1 -1
  28. package/dist/internal/errors.js +4 -4
  29. package/dist/internal/errors.js.map +1 -1
  30. package/dist/internal/utilities.js +0 -6
  31. package/dist/internal/utilities.js.map +1 -1
  32. package/package.json +3 -3
  33. package/src/OpenAiClient.ts +273 -50
  34. package/src/OpenAiConfig.ts +69 -11
  35. package/src/OpenAiEmbeddingModel.ts +332 -0
  36. package/src/OpenAiError.ts +111 -35
  37. package/src/OpenAiLanguageModel.ts +426 -43
  38. package/src/OpenAiTelemetry.ts +81 -32
  39. package/src/index.ts +11 -17
  40. package/src/internal/errors.ts +4 -4
  41. package/src/internal/utilities.ts +0 -9
@@ -1,35 +1,57 @@
1
1
  /**
2
- * @since 1.0.0
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
3
8
  */
9
+ import * as Context from "effect/Context"
4
10
  import * as Effect from "effect/Effect"
5
11
  import { dual } from "effect/Function"
6
- import * as ServiceMap from "effect/ServiceMap"
7
12
  import type { HttpClient } from "effect/unstable/http/HttpClient"
8
13
 
9
14
  /**
10
- * @since 1.0.0
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
+ *
11
25
  * @category services
26
+ * @since 4.0.0
12
27
  */
13
- export class OpenAiConfig extends ServiceMap.Service<
28
+ export class OpenAiConfig extends Context.Service<
14
29
  OpenAiConfig,
15
30
  OpenAiConfig.Service
16
31
  >()("@effect/ai-openai-compat/OpenAiConfig") {
17
32
  /**
18
- * @since 1.0.0
33
+ * Gets the configured OpenAI-compatible service from the current context when present.
34
+ *
35
+ * @since 4.0.0
19
36
  */
20
37
  static readonly getOrUndefined: Effect.Effect<typeof OpenAiConfig.Service | undefined> = Effect.map(
21
- Effect.services<never>(),
38
+ Effect.context<never>(),
22
39
  (context) => context.mapUnsafe.get(OpenAiConfig.key)
23
40
  )
24
41
  }
25
42
 
26
43
  /**
27
- * @since 1.0.0
44
+ * Types associated with the `OpenAiConfig` context service.
45
+ *
46
+ * @since 4.0.0
28
47
  */
29
48
  export declare namespace OpenAiConfig {
30
49
  /**
31
- * @since 1.0.
50
+ * Configuration consumed by OpenAI-compatible clients when they build or
51
+ * resolve the underlying HTTP client.
52
+ *
32
53
  * @category models
54
+ * @since 4.0.0
33
55
  */
34
56
  export interface Service {
35
57
  readonly transformClient?: ((client: HttpClient) => HttpClient) | undefined
@@ -37,18 +59,54 @@ export declare namespace OpenAiConfig {
37
59
  }
38
60
 
39
61
  /**
40
- * @since 1.0.0
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
+ *
41
74
  * @category configuration
75
+ * @since 4.0.0
42
76
  */
43
77
  export const withClientTransform: {
44
78
  /**
45
- * @since 1.0.0
79
+ * Provides an HTTP client transform for the supplied effect.
80
+ *
81
+ * **When to use**
82
+ *
83
+ * Use to add provider-specific OpenAI-compatible HTTP behavior, such as
84
+ * headers, retries, instrumentation, or proxy routing.
85
+ *
86
+ * **Details**
87
+ *
88
+ * OpenAI-compatible provider services read the transform from the
89
+ * `OpenAiConfig` context.
90
+ *
46
91
  * @category configuration
92
+ * @since 4.0.0
47
93
  */
48
94
  (transform: (client: HttpClient) => HttpClient): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>
49
95
  /**
50
- * @since 1.0.0
96
+ * Provides an HTTP client transform for the supplied effect.
97
+ *
98
+ * **When to use**
99
+ *
100
+ * Use to add provider-specific OpenAI-compatible HTTP behavior, such as
101
+ * headers, retries, instrumentation, or proxy routing.
102
+ *
103
+ * **Details**
104
+ *
105
+ * OpenAI-compatible provider services read the transform from the
106
+ * `OpenAiConfig` context.
107
+ *
51
108
  * @category configuration
109
+ * @since 4.0.0
52
110
  */
53
111
  <A, E, R>(
54
112
  self: Effect.Effect<A, E, R>,
@@ -0,0 +1,332 @@
1
+ /**
2
+ * The `OpenAiEmbeddingModel` module adapts OpenAI-compatible embeddings
3
+ * endpoints to Effect's embedding model service. It sends embedding requests
4
+ * through {@link OpenAiClient}, exposes constructors for layers and `AiModel`
5
+ * values, supports scoped request configuration overrides, and checks that the
6
+ * provider returns one numeric vector for each requested input.
7
+ *
8
+ * @since 4.0.0
9
+ */
10
+ import * as Context from "effect/Context"
11
+ import * as Effect from "effect/Effect"
12
+ import { dual } from "effect/Function"
13
+ import * as Layer from "effect/Layer"
14
+ import type { Simplify } from "effect/Types"
15
+ import * as AiError from "effect/unstable/ai/AiError"
16
+ import * as EmbeddingModel from "effect/unstable/ai/EmbeddingModel"
17
+ import * as AiModel from "effect/unstable/ai/Model"
18
+ import type { CreateEmbedding200, CreateEmbeddingRequestJson } from "./OpenAiClient.ts"
19
+ import { OpenAiClient } from "./OpenAiClient.ts"
20
+
21
+ /**
22
+ * A model identifier accepted by an OpenAI-compatible embeddings endpoint.
23
+ *
24
+ * @category models
25
+ * @since 4.0.0
26
+ */
27
+ export type Model = string
28
+
29
+ /**
30
+ * Context service for OpenAI embedding model configuration.
31
+ *
32
+ * **When to use**
33
+ *
34
+ * Use when you need to provide shared default request options for
35
+ * OpenAI-compatible embedding operations through the Effect context, such as
36
+ * `dimensions`, `encoding_format`, or `user`.
37
+ *
38
+ * **Details**
39
+ *
40
+ * The service stores the embedding request payload without `input`. Requests
41
+ * combine the selected model, layer or constructor config, and scoped context
42
+ * config, with scoped context config taking precedence.
43
+ *
44
+ * @see {@link withConfigOverride} for scoping embedding request overrides
45
+ *
46
+ * @category context
47
+ * @since 4.0.0
48
+ */
49
+ export class Config extends Context.Service<
50
+ Config,
51
+ Simplify<
52
+ & Partial<
53
+ Omit<
54
+ CreateEmbeddingRequestJson,
55
+ "input"
56
+ >
57
+ >
58
+ & {
59
+ readonly [x: string]: unknown
60
+ }
61
+ >
62
+ >()("@effect/ai-openai-compat/OpenAiEmbeddingModel/Config") {}
63
+
64
+ /**
65
+ * Creates an `AiModel` for an OpenAI-compatible embedding model with its configured vector dimensions.
66
+ *
67
+ * **When to use**
68
+ *
69
+ * Use to provide an OpenAI-compatible `EmbeddingModel` and its `Dimensions`
70
+ * service to an Effect program.
71
+ *
72
+ * @see {@link layer} for providing only the embedding model service
73
+ * @see {@link withConfigOverride} for scoped request configuration overrides
74
+ *
75
+ * @category constructors
76
+ * @since 4.0.0
77
+ */
78
+ export const model = (
79
+ model: string,
80
+ options: {
81
+ readonly dimensions: number
82
+ readonly config?: Omit<typeof Config.Service, "model" | "dimensions">
83
+ }
84
+ ): AiModel.Model<"openai", EmbeddingModel.EmbeddingModel | EmbeddingModel.Dimensions, OpenAiClient> =>
85
+ AiModel.make(
86
+ "openai",
87
+ model,
88
+ Layer.merge(
89
+ layer({
90
+ model,
91
+ config: {
92
+ ...options.config,
93
+ dimensions: options.dimensions
94
+ }
95
+ }),
96
+ Layer.succeed(EmbeddingModel.Dimensions, options.dimensions)
97
+ )
98
+ )
99
+
100
+ /**
101
+ * Creates an OpenAI-compatible embedding model service backed by `OpenAiClient`.
102
+ *
103
+ * **When to use**
104
+ *
105
+ * Use when you need to build or provide an `EmbeddingModel` service directly
106
+ * from an existing `OpenAiClient`.
107
+ *
108
+ * **Details**
109
+ *
110
+ * The service sends embedding requests through `OpenAiClient.createEmbedding`.
111
+ * Request config is merged as the selected model, constructor config, then
112
+ * scoped `Config`, so scoped overrides take precedence. Provider usage
113
+ * `prompt_tokens` is exposed as `usage.inputTokens`.
114
+ *
115
+ * **Gotchas**
116
+ *
117
+ * Provider responses must contain one numeric vector for every requested input
118
+ * with unique, in-range `index` values; otherwise embedding operations fail with
119
+ * `AiError.InvalidOutputError`.
120
+ *
121
+ * @see {@link model} for the higher-level `AiModel` descriptor that also provides `EmbeddingModel.Dimensions`
122
+ * @see {@link layer} for providing the service as a `Layer`
123
+ * @see {@link withConfigOverride} for scoping embedding request overrides
124
+ *
125
+ * @category constructors
126
+ * @since 4.0.0
127
+ */
128
+ export const make = Effect.fnUntraced(function*({ model, config: providerConfig }: {
129
+ readonly model: string
130
+ readonly config?: Omit<typeof Config.Service, "model"> | undefined
131
+ }): Effect.fn.Return<EmbeddingModel.Service, never, OpenAiClient> {
132
+ const client = yield* OpenAiClient
133
+
134
+ const makeConfig = Effect.gen(function*() {
135
+ const services = yield* Effect.context<never>()
136
+ return { model, ...providerConfig, ...services.mapUnsafe.get(Config.key) }
137
+ })
138
+
139
+ return yield* EmbeddingModel.make({
140
+ embedMany: Effect.fnUntraced(function*({ inputs }) {
141
+ const config = yield* makeConfig
142
+ const response = yield* client.createEmbedding({ ...config, input: inputs })
143
+ return yield* mapProviderResponse(inputs.length, response)
144
+ })
145
+ })
146
+ })
147
+
148
+ /**
149
+ * Creates a layer for an OpenAI-compatible embedding model service.
150
+ *
151
+ * **When to use**
152
+ *
153
+ * Use when composing application layers and you want an OpenAI-compatible
154
+ * embeddings endpoint to satisfy `EmbeddingModel.EmbeddingModel` while
155
+ * supplying `OpenAiClient` from another layer.
156
+ *
157
+ * @see {@link make} for constructing the embedding model service effectfully
158
+ * @see {@link model} for creating an `AiModel` with configured dimensions
159
+ *
160
+ * @category layers
161
+ * @since 4.0.0
162
+ */
163
+ export const layer = (options: {
164
+ readonly model: string
165
+ readonly config?: Omit<typeof Config.Service, "model"> | undefined
166
+ }): Layer.Layer<EmbeddingModel.EmbeddingModel, never, OpenAiClient> =>
167
+ Layer.effect(EmbeddingModel.EmbeddingModel, make(options))
168
+
169
+ /**
170
+ * Provides scoped request config overrides for OpenAI-compatible embedding model operations.
171
+ *
172
+ * **When to use**
173
+ *
174
+ * Use to apply embedding request options to one effect without changing the
175
+ * model's default configuration.
176
+ *
177
+ * **Details**
178
+ *
179
+ * The overrides are merged with any existing `Config` service for the duration
180
+ * of the supplied effect. Fields in `overrides` take precedence over existing
181
+ * config, and the helper supports both `effect.pipe(withConfigOverride(overrides))`
182
+ * and `withConfigOverride(effect, overrides)`.
183
+ *
184
+ * @see {@link Config} for available OpenAI-compatible embedding request configuration fields
185
+ *
186
+ * @category configuration
187
+ * @since 4.0.0
188
+ */
189
+ export const withConfigOverride: {
190
+ /**
191
+ * Provides scoped request config overrides for OpenAI-compatible embedding model operations.
192
+ *
193
+ * **When to use**
194
+ *
195
+ * Use to apply embedding request options to one effect without changing the
196
+ * model's default configuration.
197
+ *
198
+ * **Details**
199
+ *
200
+ * The overrides are merged with any existing `Config` service for the duration
201
+ * of the supplied effect. Fields in `overrides` take precedence over existing
202
+ * config, and the helper supports both `effect.pipe(withConfigOverride(overrides))`
203
+ * and `withConfigOverride(effect, overrides)`.
204
+ *
205
+ * @see {@link Config} for available OpenAI-compatible embedding request configuration fields
206
+ *
207
+ * @category configuration
208
+ * @since 4.0.0
209
+ */
210
+ (overrides: typeof Config.Service): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, Config>>
211
+ /**
212
+ * Provides scoped request config overrides for OpenAI-compatible embedding model operations.
213
+ *
214
+ * **When to use**
215
+ *
216
+ * Use to apply embedding request options to one effect without changing the
217
+ * model's default configuration.
218
+ *
219
+ * **Details**
220
+ *
221
+ * The overrides are merged with any existing `Config` service for the duration
222
+ * of the supplied effect. Fields in `overrides` take precedence over existing
223
+ * config, and the helper supports both `effect.pipe(withConfigOverride(overrides))`
224
+ * and `withConfigOverride(effect, overrides)`.
225
+ *
226
+ * @see {@link Config} for available OpenAI-compatible embedding request configuration fields
227
+ *
228
+ * @category configuration
229
+ * @since 4.0.0
230
+ */
231
+ <A, E, R>(self: Effect.Effect<A, E, R>, overrides: typeof Config.Service): Effect.Effect<A, E, Exclude<R, Config>>
232
+ } = dual<
233
+ /**
234
+ * Provides scoped request config overrides for OpenAI-compatible embedding model operations.
235
+ *
236
+ * **When to use**
237
+ *
238
+ * Use to apply embedding request options to one effect without changing the
239
+ * model's default configuration.
240
+ *
241
+ * **Details**
242
+ *
243
+ * The overrides are merged with any existing `Config` service for the duration
244
+ * of the supplied effect. Fields in `overrides` take precedence over existing
245
+ * config, and the helper supports both `effect.pipe(withConfigOverride(overrides))`
246
+ * and `withConfigOverride(effect, overrides)`.
247
+ *
248
+ * @see {@link Config} for available OpenAI-compatible embedding request configuration fields
249
+ *
250
+ * @category configuration
251
+ * @since 4.0.0
252
+ */
253
+ (overrides: typeof Config.Service) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, Config>>,
254
+ /**
255
+ * Provides scoped request config overrides for OpenAI-compatible embedding model operations.
256
+ *
257
+ * **When to use**
258
+ *
259
+ * Use to apply embedding request options to one effect without changing the
260
+ * model's default configuration.
261
+ *
262
+ * **Details**
263
+ *
264
+ * The overrides are merged with any existing `Config` service for the duration
265
+ * of the supplied effect. Fields in `overrides` take precedence over existing
266
+ * config, and the helper supports both `effect.pipe(withConfigOverride(overrides))`
267
+ * and `withConfigOverride(effect, overrides)`.
268
+ *
269
+ * @see {@link Config} for available OpenAI-compatible embedding request configuration fields
270
+ *
271
+ * @category configuration
272
+ * @since 4.0.0
273
+ */
274
+ <A, E, R>(self: Effect.Effect<A, E, R>, overrides: typeof Config.Service) => Effect.Effect<A, E, Exclude<R, Config>>
275
+ >(2, (self, overrides) =>
276
+ Effect.flatMap(
277
+ Effect.serviceOption(Config),
278
+ (config) =>
279
+ Effect.provideService(self, Config, {
280
+ ...(config._tag === "Some" ? config.value : {}),
281
+ ...overrides
282
+ })
283
+ ))
284
+
285
+ const mapProviderResponse = (
286
+ inputLength: number,
287
+ response: CreateEmbedding200
288
+ ): Effect.Effect<EmbeddingModel.ProviderResponse, AiError.AiError> => {
289
+ if (response.data.length !== inputLength) {
290
+ return Effect.fail(
291
+ invalidOutput(`Provider returned ${response.data.length} embeddings but expected ${inputLength}`)
292
+ )
293
+ }
294
+
295
+ const results = new Array<Array<number>>(inputLength)
296
+ const seen = new Set<number>()
297
+
298
+ for (const entry of response.data) {
299
+ if (!Number.isInteger(entry.index) || entry.index < 0 || entry.index >= inputLength) {
300
+ return Effect.fail(invalidOutput(`Provider returned invalid embedding index: ${entry.index}`))
301
+ }
302
+ if (seen.has(entry.index)) {
303
+ return Effect.fail(invalidOutput(`Provider returned duplicate embedding index: ${entry.index}`))
304
+ }
305
+ if (!Array.isArray(entry.embedding)) {
306
+ return Effect.fail(invalidOutput(`Provider returned non-vector embedding at index ${entry.index}`))
307
+ }
308
+
309
+ seen.add(entry.index)
310
+ results[entry.index] = [...entry.embedding]
311
+ }
312
+
313
+ if (seen.size !== inputLength) {
314
+ return Effect.fail(
315
+ invalidOutput(`Provider returned embeddings for ${seen.size} inputs but expected ${inputLength}`)
316
+ )
317
+ }
318
+
319
+ return Effect.succeed({
320
+ results,
321
+ usage: {
322
+ inputTokens: response.usage?.prompt_tokens
323
+ }
324
+ })
325
+ }
326
+
327
+ const invalidOutput = (description: string): AiError.AiError =>
328
+ AiError.make({
329
+ module: "OpenAiEmbeddingModel",
330
+ method: "embedMany",
331
+ reason: new AiError.InvalidOutputError({ description })
332
+ })
@@ -1,12 +1,25 @@
1
1
  /**
2
- * @since 1.0.0
2
+ * The `OpenAiError` module defines OpenAI-specific metadata that can be
3
+ * attached to the shared `AiError` error types used by the AI packages. It is
4
+ * primarily used by OpenAI-compatible clients to preserve provider details
5
+ * such as error codes, error types, request IDs, and rate limit headers while
6
+ * still exposing errors through the provider-neutral Effect AI error model.
7
+ *
8
+ * Use this module when mapping OpenAI API failures into `AiError` values and
9
+ * when consumers need enough structured metadata to debug failed requests,
10
+ * inspect quota or rate limit responses, or correlate an error with OpenAI
11
+ * support. The exported types are metadata shapes only; the module augmentation
12
+ * makes those shapes available on the corresponding shared AI error metadata
13
+ * interfaces without defining new runtime error classes.
14
+ *
15
+ * @since 4.0.0
3
16
  */
4
17
 
5
18
  /**
6
19
  * OpenAI-specific error metadata fields.
7
20
  *
8
- * @since 1.0.0
9
21
  * @category models
22
+ * @since 4.0.0
10
23
  */
11
24
  export type OpenAiErrorMetadata = {
12
25
  /**
@@ -26,11 +39,13 @@ export type OpenAiErrorMetadata = {
26
39
  /**
27
40
  * OpenAI-specific rate limit metadata fields.
28
41
  *
42
+ * **Details**
43
+ *
29
44
  * Extends base error metadata with rate limit specific information from
30
45
  * OpenAI's rate limit headers.
31
46
  *
32
- * @since 1.0.0
33
47
  * @category models
48
+ * @since 4.0.0
34
49
  */
35
50
  export type OpenAiRateLimitMetadata = OpenAiErrorMetadata & {
36
51
  /**
@@ -52,51 +67,112 @@ export type OpenAiRateLimitMetadata = OpenAiErrorMetadata & {
52
67
  }
53
68
 
54
69
  declare module "effect/unstable/ai/AiError" {
55
- export interface RateLimitError {
56
- readonly metadata: {
57
- readonly openai?: OpenAiRateLimitMetadata | null
58
- }
70
+ /**
71
+ * Metadata attached to rate limit errors returned by OpenAI-compatible APIs.
72
+ *
73
+ * @category models
74
+ * @since 4.0.0
75
+ */
76
+ export interface RateLimitErrorMetadata {
77
+ readonly openai?: OpenAiRateLimitMetadata | null
59
78
  }
60
79
 
61
- export interface QuotaExhaustedError {
62
- readonly metadata: {
63
- readonly openai?: OpenAiErrorMetadata | null
64
- }
80
+ /**
81
+ * Metadata attached when an OpenAI-compatible provider reports that quota or
82
+ * billing limits have been exhausted.
83
+ *
84
+ * @category models
85
+ * @since 4.0.0
86
+ */
87
+ export interface QuotaExhaustedErrorMetadata {
88
+ readonly openai?: OpenAiErrorMetadata | null
65
89
  }
66
90
 
67
- export interface AuthenticationError {
68
- readonly metadata: {
69
- readonly openai?: OpenAiErrorMetadata | null
70
- }
91
+ /**
92
+ * Metadata attached to authentication failures from OpenAI-compatible APIs,
93
+ * such as invalid, missing, or unauthorized API credentials.
94
+ *
95
+ * @category models
96
+ * @since 4.0.0
97
+ */
98
+ export interface AuthenticationErrorMetadata {
99
+ readonly openai?: OpenAiErrorMetadata | null
71
100
  }
72
101
 
73
- export interface ContentPolicyError {
74
- readonly metadata: {
75
- readonly openai?: OpenAiErrorMetadata | null
76
- }
102
+ /**
103
+ * Metadata attached when an OpenAI-compatible provider rejects content because
104
+ * it violates a safety or usage policy.
105
+ *
106
+ * @category models
107
+ * @since 4.0.0
108
+ */
109
+ export interface ContentPolicyErrorMetadata {
110
+ readonly openai?: OpenAiErrorMetadata | null
77
111
  }
78
112
 
79
- export interface InvalidRequestError {
80
- readonly metadata: {
81
- readonly openai?: OpenAiErrorMetadata | null
82
- }
113
+ /**
114
+ * Metadata attached to malformed or unsupported requests rejected by an
115
+ * OpenAI-compatible API before model execution.
116
+ *
117
+ * @category models
118
+ * @since 4.0.0
119
+ */
120
+ export interface InvalidRequestErrorMetadata {
121
+ readonly openai?: OpenAiErrorMetadata | null
83
122
  }
84
123
 
85
- export interface InternalProviderError {
86
- readonly metadata: {
87
- readonly openai?: OpenAiErrorMetadata | null
88
- }
124
+ /**
125
+ * Metadata attached to unexpected server-side failures reported by an
126
+ * OpenAI-compatible provider.
127
+ *
128
+ * @category models
129
+ * @since 4.0.0
130
+ */
131
+ export interface InternalProviderErrorMetadata {
132
+ readonly openai?: OpenAiErrorMetadata | null
89
133
  }
90
134
 
91
- export interface InvalidOutputError {
92
- readonly metadata: {
93
- readonly openai?: OpenAiErrorMetadata | null
94
- }
135
+ /**
136
+ * Metadata attached when an OpenAI-compatible response cannot be converted
137
+ * into the expected AI package output shape.
138
+ *
139
+ * @category models
140
+ * @since 4.0.0
141
+ */
142
+ export interface InvalidOutputErrorMetadata {
143
+ readonly openai?: OpenAiErrorMetadata | null
144
+ }
145
+
146
+ /**
147
+ * Metadata attached when an OpenAI-compatible structured output response does
148
+ * not satisfy the requested schema or parsing constraints.
149
+ *
150
+ * @category models
151
+ * @since 4.0.0
152
+ */
153
+ export interface StructuredOutputErrorMetadata {
154
+ readonly openai?: OpenAiErrorMetadata | null
95
155
  }
96
156
 
97
- export interface UnknownError {
98
- readonly metadata: {
99
- readonly openai?: OpenAiErrorMetadata | null
100
- }
157
+ /**
158
+ * Metadata attached when an OpenAI-compatible provider cannot support the
159
+ * schema supplied for structured output or tool definitions.
160
+ *
161
+ * @category models
162
+ * @since 4.0.0
163
+ */
164
+ export interface UnsupportedSchemaErrorMetadata {
165
+ readonly openai?: OpenAiErrorMetadata | null
166
+ }
167
+
168
+ /**
169
+ * Metadata attached when an OpenAI-compatible error response cannot be mapped
170
+ * to a more specific shared AI error category.
171
+ *
172
+ * @category models
173
+ * @since 4.0.0
174
+ */
175
+ export interface UnknownErrorMetadata {
176
+ readonly openai?: OpenAiErrorMetadata | null
101
177
  }
102
178
  }