@opencode/ai 2.0.7 → 2.0.9

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.
@@ -4,7 +4,7 @@ import { OpenAIChat } from "./openai-chat.js";
4
4
  import { JsonObject, ProviderShared } from "./shared.js";
5
5
  import { OpenResponsesOptions } from "./utils/open-responses-options.js";
6
6
  const Options = Schema.Struct({
7
- reasoningEffort: OpenResponsesOptions.Options.fields.reasoningEffort,
7
+ reasoningEffort: Schema.optional(OpenResponsesOptions.ReasoningEffort),
8
8
  enableThinking: Schema.optional(Schema.Boolean),
9
9
  thinkingBudget: Schema.optional(Schema.Int),
10
10
  preserveThinking: Schema.optional(Schema.Boolean),
@@ -13,7 +13,7 @@ const Options = Schema.Struct({
13
13
  type: Schema.declare(Schema.is(Schema.String)),
14
14
  })),
15
15
  toolStream: Schema.optional(Schema.Boolean),
16
- parallelToolCalls: OpenResponsesOptions.Options.fields.parallelToolCalls,
16
+ parallelToolCalls: Schema.optional(Schema.Boolean),
17
17
  repetitionPenalty: Schema.optional(Schema.Number),
18
18
  responseFormat: Schema.optional(Schema.Struct({
19
19
  type: Schema.declare(Schema.is(Schema.String)),
@@ -228,7 +228,7 @@ export declare const protocol: Protocol<{
228
228
  readonly type: string;
229
229
  readonly budget_tokens?: number | undefined;
230
230
  } | undefined;
231
- readonly service_tier?: "auto" | "standard_only" | undefined;
231
+ readonly service_tier?: "auto" | (string & {}) | "standard_only" | undefined;
232
232
  readonly container?: string | {
233
233
  readonly id?: string | null | undefined;
234
234
  readonly skills?: readonly {
@@ -5,9 +5,9 @@ import { JsonObject, optionalArray, ProviderShared } from "./shared.js";
5
5
  import { OpenResponsesOptions } from "./utils/open-responses-options.js";
6
6
  import { ResponsesHostedTools } from "./utils/responses-hosted-tools.js";
7
7
  const Options = Schema.Struct({
8
- reasoningEffort: OpenResponsesOptions.Options.fields.reasoningEffort,
8
+ reasoningEffort: Schema.optional(OpenResponsesOptions.ReasoningEffort),
9
9
  enableThinking: Schema.optional(Schema.Boolean),
10
- store: OpenResponsesOptions.Options.fields.store,
10
+ store: Schema.optional(Schema.Boolean),
11
11
  previousResponseId: Schema.optional(Schema.String),
12
12
  conversation: Schema.optional(Schema.String),
13
13
  });
@@ -3,73 +3,17 @@ import { Route } from "../route/client.js";
3
3
  import { Framing } from "../route/framing.js";
4
4
  import { Protocol } from "../route/protocol.js";
5
5
  import { HttpTransport } from "../route/transport/index.js";
6
- import { AIError, LLMRequest } from "../schema/index.js";
6
+ import { AIError, LLMRequest, type ProviderOptions } from "../schema/index.js";
7
7
  import { Lifecycle } from "./utils/lifecycle.js";
8
8
  import { ToolStream } from "./utils/tool-stream.js";
9
9
  export declare const DEFAULT_BASE_URL = "https://api.anthropic.com/v1";
10
10
  export declare const PATH = "/messages";
11
11
  export declare const DEFAULT_MAX_TOKENS = 32000;
12
12
  export declare const framing: Framing.Definition<string>;
13
- export type ThinkingBlockBinding = {
14
- readonly prefix_mismatch_behavior?: "error" | "drop_block" | (string & {});
15
- };
16
- export type ThinkingInput = {
17
- readonly type: "adaptive";
18
- readonly display?: "summarized" | "omitted";
19
- readonly block_binding?: ThinkingBlockBinding;
20
- } | {
21
- readonly type: "disabled";
22
- } | ({
23
- readonly type: "enabled";
24
- readonly display?: "summarized" | "omitted";
25
- readonly block_binding?: ThinkingBlockBinding;
26
- } & ({
27
- readonly budgetTokens: number;
28
- readonly budget_tokens?: number;
29
- } | {
30
- readonly budgetTokens?: number;
31
- readonly budget_tokens: number;
32
- }));
33
- export interface OptionsInput {
34
- /** Advanced in-band compaction. The caller owns checkpoint persistence and recovery. */
35
- readonly contextManagement?: ContextManagement;
36
- readonly [key: string]: unknown;
37
- readonly thinking?: ThinkingInput;
38
- readonly effort?: string;
39
- readonly service_tier?: "auto" | "standard_only";
40
- readonly serviceTier?: "auto" | "standard_only";
41
- readonly metadata?: {
42
- readonly user_id?: string | null;
43
- };
44
- readonly container?: string | {
45
- readonly id?: string | null;
46
- readonly skills?: ReadonlyArray<Record<string, unknown>> | null;
47
- };
48
- readonly inference_geo?: string | null;
49
- readonly inferenceGeo?: string | null;
50
- readonly cache_control?: {
51
- readonly type: "ephemeral";
52
- readonly ttl?: "5m" | "1h";
53
- };
54
- readonly cacheControl?: {
55
- readonly type: "ephemeral";
56
- readonly ttl?: "5m" | "1h";
57
- };
58
- readonly output_config?: {
59
- readonly effort?: string | null;
60
- readonly format?: {
61
- readonly type: "json_schema";
62
- readonly schema: Record<string, unknown>;
63
- } | null;
64
- };
65
- readonly outputConfig?: {
66
- readonly effort?: string | null;
67
- readonly format?: {
68
- readonly type: "json_schema";
69
- readonly schema: Record<string, unknown>;
70
- } | null;
71
- };
72
- }
13
+ export type ThinkingBlockBinding = typeof AnthropicThinkingBlockBinding.Type;
14
+ export type ThinkingInput = typeof Thinking.Encoded;
15
+ /** Caller-facing provider options; unknown keys are accepted and ignored. `Options.Type` is the wire-ready form. */
16
+ export type OptionsInput = ProviderOptions & typeof Options.Encoded;
73
17
  export type ProviderOptionsInput = OptionsInput;
74
18
  export declare const ContextManagement: Schema.Struct<{
75
19
  readonly edits: Schema.$Array<Schema.Struct<{
@@ -83,6 +27,117 @@ export declare const ContextManagement: Schema.Struct<{
83
27
  }>>;
84
28
  }>;
85
29
  export type ContextManagement = typeof ContextManagement.Type;
30
+ declare const AnthropicThinkingBlockBinding: Schema.Struct<{
31
+ readonly prefix_mismatch_behavior: Schema.optional<Schema.declare<(string & {}) | "error" | "drop_block", (string & {}) | "error" | "drop_block">>;
32
+ }>;
33
+ declare const Thinking: Schema.Union<readonly [Schema.decodeTo<Schema.Struct<{
34
+ readonly display: Schema.optional<Schema.declare<(string & {}) | "summarized" | "omitted", (string & {}) | "summarized" | "omitted">>;
35
+ readonly block_binding: Schema.optional<Schema.Struct<{
36
+ readonly prefix_mismatch_behavior: Schema.optional<Schema.declare<(string & {}) | "error" | "drop_block", (string & {}) | "error" | "drop_block">>;
37
+ }>>;
38
+ readonly type: Schema.tag<"enabled">;
39
+ readonly budget_tokens: Schema.Number;
40
+ }>, Schema.Union<readonly [Schema.Struct<{
41
+ readonly display: Schema.optional<Schema.declare<(string & {}) | "summarized" | "omitted", (string & {}) | "summarized" | "omitted">>;
42
+ readonly block_binding: Schema.optional<Schema.Struct<{
43
+ readonly prefix_mismatch_behavior: Schema.optional<Schema.declare<(string & {}) | "error" | "drop_block", (string & {}) | "error" | "drop_block">>;
44
+ }>>;
45
+ readonly type: Schema.tag<"enabled">;
46
+ readonly budgetTokens: Schema.Number;
47
+ }>, Schema.Struct<{
48
+ readonly display: Schema.optional<Schema.declare<(string & {}) | "summarized" | "omitted", (string & {}) | "summarized" | "omitted">>;
49
+ readonly block_binding: Schema.optional<Schema.Struct<{
50
+ readonly prefix_mismatch_behavior: Schema.optional<Schema.declare<(string & {}) | "error" | "drop_block", (string & {}) | "error" | "drop_block">>;
51
+ }>>;
52
+ readonly type: Schema.tag<"enabled">;
53
+ readonly budget_tokens: Schema.Number;
54
+ }>]>, never, never>, Schema.Struct<{
55
+ readonly display: Schema.optional<Schema.declare<(string & {}) | "summarized" | "omitted", (string & {}) | "summarized" | "omitted">>;
56
+ readonly block_binding: Schema.optional<Schema.Struct<{
57
+ readonly prefix_mismatch_behavior: Schema.optional<Schema.declare<(string & {}) | "error" | "drop_block", (string & {}) | "error" | "drop_block">>;
58
+ }>>;
59
+ readonly type: Schema.tag<"adaptive">;
60
+ }>, Schema.Struct<{
61
+ readonly type: Schema.tag<"disabled">;
62
+ }>]>;
63
+ declare const Options: Schema.Struct<{
64
+ /** Advanced in-band compaction. The caller owns checkpoint persistence and recovery. */
65
+ readonly contextManagement: Schema.optional<Schema.Struct<{
66
+ readonly edits: Schema.$Array<Schema.Struct<{
67
+ readonly type: Schema.Literal<"compact_20260112">;
68
+ readonly trigger: Schema.optional<Schema.Struct<{
69
+ readonly type: Schema.Literal<"input_tokens">;
70
+ readonly value: Schema.Int;
71
+ }>>;
72
+ readonly pauseAfterCompaction: Schema.optional<Schema.Boolean>;
73
+ readonly instructions: Schema.optional<Schema.String>;
74
+ }>>;
75
+ }>>;
76
+ readonly thinking: Schema.optional<Schema.Union<readonly [Schema.decodeTo<Schema.Struct<{
77
+ readonly display: Schema.optional<Schema.declare<(string & {}) | "summarized" | "omitted", (string & {}) | "summarized" | "omitted">>;
78
+ readonly block_binding: Schema.optional<Schema.Struct<{
79
+ readonly prefix_mismatch_behavior: Schema.optional<Schema.declare<(string & {}) | "error" | "drop_block", (string & {}) | "error" | "drop_block">>;
80
+ }>>;
81
+ readonly type: Schema.tag<"enabled">;
82
+ readonly budget_tokens: Schema.Number;
83
+ }>, Schema.Union<readonly [Schema.Struct<{
84
+ readonly display: Schema.optional<Schema.declare<(string & {}) | "summarized" | "omitted", (string & {}) | "summarized" | "omitted">>;
85
+ readonly block_binding: Schema.optional<Schema.Struct<{
86
+ readonly prefix_mismatch_behavior: Schema.optional<Schema.declare<(string & {}) | "error" | "drop_block", (string & {}) | "error" | "drop_block">>;
87
+ }>>;
88
+ readonly type: Schema.tag<"enabled">;
89
+ readonly budgetTokens: Schema.Number;
90
+ }>, Schema.Struct<{
91
+ readonly display: Schema.optional<Schema.declare<(string & {}) | "summarized" | "omitted", (string & {}) | "summarized" | "omitted">>;
92
+ readonly block_binding: Schema.optional<Schema.Struct<{
93
+ readonly prefix_mismatch_behavior: Schema.optional<Schema.declare<(string & {}) | "error" | "drop_block", (string & {}) | "error" | "drop_block">>;
94
+ }>>;
95
+ readonly type: Schema.tag<"enabled">;
96
+ readonly budget_tokens: Schema.Number;
97
+ }>]>, never, never>, Schema.Struct<{
98
+ readonly display: Schema.optional<Schema.declare<(string & {}) | "summarized" | "omitted", (string & {}) | "summarized" | "omitted">>;
99
+ readonly block_binding: Schema.optional<Schema.Struct<{
100
+ readonly prefix_mismatch_behavior: Schema.optional<Schema.declare<(string & {}) | "error" | "drop_block", (string & {}) | "error" | "drop_block">>;
101
+ }>>;
102
+ readonly type: Schema.tag<"adaptive">;
103
+ }>, Schema.Struct<{
104
+ readonly type: Schema.tag<"disabled">;
105
+ }>]>>;
106
+ readonly effort: Schema.optional<Schema.String>;
107
+ readonly service_tier: Schema.optional<Schema.declare<"auto" | (string & {}) | "standard_only", "auto" | (string & {}) | "standard_only">>;
108
+ readonly serviceTier: Schema.optional<Schema.declare<"auto" | (string & {}) | "standard_only", "auto" | (string & {}) | "standard_only">>;
109
+ readonly metadata: Schema.optional<Schema.Struct<{
110
+ readonly user_id: Schema.optional<Schema.NullOr<Schema.String>>;
111
+ }>>;
112
+ readonly container: Schema.optional<Schema.Union<readonly [Schema.String, Schema.Struct<{
113
+ readonly id: Schema.optional<Schema.NullOr<Schema.String>>;
114
+ readonly skills: Schema.optional<Schema.NullOr<Schema.$Array<Schema.$Record<Schema.String, Schema.Unknown>>>>;
115
+ }>]>>;
116
+ readonly inference_geo: Schema.optional<Schema.NullOr<Schema.String>>;
117
+ readonly inferenceGeo: Schema.optional<Schema.NullOr<Schema.String>>;
118
+ readonly cache_control: Schema.optional<Schema.Struct<{
119
+ readonly type: Schema.tag<"ephemeral">;
120
+ readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
121
+ }>>;
122
+ readonly cacheControl: Schema.optional<Schema.Struct<{
123
+ readonly type: Schema.tag<"ephemeral">;
124
+ readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
125
+ }>>;
126
+ readonly output_config: Schema.optional<Schema.Struct<{
127
+ readonly effort: Schema.optional<Schema.NullOr<Schema.String>>;
128
+ readonly format: Schema.optional<Schema.NullOr<Schema.Struct<{
129
+ readonly type: Schema.Literal<"json_schema">;
130
+ readonly schema: Schema.$Record<Schema.String, Schema.Unknown>;
131
+ }>>>;
132
+ }>>;
133
+ readonly outputConfig: Schema.optional<Schema.Struct<{
134
+ readonly effort: Schema.optional<Schema.NullOr<Schema.String>>;
135
+ readonly format: Schema.optional<Schema.NullOr<Schema.Struct<{
136
+ readonly type: Schema.Literal<"json_schema">;
137
+ readonly schema: Schema.$Record<Schema.String, Schema.Unknown>;
138
+ }>>>;
139
+ }>>;
140
+ }>;
86
141
  export declare const AnthropicMessagesBody: Schema.Struct<{
87
142
  context_management: Schema.optional<Schema.Struct<{
88
143
  readonly edits: Schema.$Array<Schema.Struct<{
@@ -314,18 +369,18 @@ export declare const AnthropicMessagesBody: Schema.Struct<{
314
369
  top_k: Schema.optional<Schema.Number>;
315
370
  stop_sequences: Schema.optional<Schema.$Array<Schema.String>>;
316
371
  thinking: Schema.optional<Schema.Union<readonly [Schema.Struct<{
317
- readonly type: Schema.tag<"enabled">;
318
- readonly budget_tokens: Schema.Number;
319
- readonly display: Schema.optional<Schema.Literals<readonly ["summarized", "omitted"]>>;
372
+ readonly display: Schema.optional<Schema.declare<(string & {}) | "summarized" | "omitted", (string & {}) | "summarized" | "omitted">>;
320
373
  readonly block_binding: Schema.optional<Schema.Struct<{
321
- readonly prefix_mismatch_behavior: Schema.optional<Schema.String>;
374
+ readonly prefix_mismatch_behavior: Schema.optional<Schema.declare<(string & {}) | "error" | "drop_block", (string & {}) | "error" | "drop_block">>;
322
375
  }>>;
376
+ readonly type: Schema.tag<"enabled">;
377
+ readonly budget_tokens: Schema.Number;
323
378
  }>, Schema.Struct<{
324
- readonly type: Schema.tag<"adaptive">;
325
- readonly display: Schema.optional<Schema.Literals<readonly ["summarized", "omitted"]>>;
379
+ readonly display: Schema.optional<Schema.declare<(string & {}) | "summarized" | "omitted", (string & {}) | "summarized" | "omitted">>;
326
380
  readonly block_binding: Schema.optional<Schema.Struct<{
327
- readonly prefix_mismatch_behavior: Schema.optional<Schema.String>;
381
+ readonly prefix_mismatch_behavior: Schema.optional<Schema.declare<(string & {}) | "error" | "drop_block", (string & {}) | "error" | "drop_block">>;
328
382
  }>>;
383
+ readonly type: Schema.tag<"adaptive">;
329
384
  }>, Schema.Struct<{
330
385
  readonly type: Schema.tag<"disabled">;
331
386
  }>]>>;
@@ -348,7 +403,7 @@ export declare const AnthropicMessagesBody: Schema.Struct<{
348
403
  metadata: Schema.optional<Schema.Struct<{
349
404
  readonly user_id: Schema.optional<Schema.NullOr<Schema.String>>;
350
405
  }>>;
351
- service_tier: Schema.optional<Schema.Literals<readonly ["auto", "standard_only"]>>;
406
+ service_tier: Schema.optional<Schema.declare<"auto" | (string & {}) | "standard_only", "auto" | (string & {}) | "standard_only">>;
352
407
  }>;
353
408
  export type AnthropicMessagesBody = Schema.Schema.Type<typeof AnthropicMessagesBody>;
354
409
  /**
@@ -572,20 +627,20 @@ export declare const protocol: Protocol<{
572
627
  readonly thinking?: {
573
628
  readonly type: "enabled";
574
629
  readonly budget_tokens: number;
575
- readonly display?: "summarized" | "omitted" | undefined;
630
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
576
631
  readonly block_binding?: {
577
- readonly prefix_mismatch_behavior?: string | undefined;
632
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
578
633
  } | undefined;
579
634
  } | {
580
635
  readonly type: "adaptive";
581
- readonly display?: "summarized" | "omitted" | undefined;
636
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
582
637
  readonly block_binding?: {
583
- readonly prefix_mismatch_behavior?: string | undefined;
638
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
584
639
  } | undefined;
585
640
  } | {
586
641
  readonly type: "disabled";
587
642
  } | undefined;
588
- readonly service_tier?: "auto" | "standard_only" | undefined;
643
+ readonly service_tier?: "auto" | (string & {}) | "standard_only" | undefined;
589
644
  readonly container?: string | {
590
645
  readonly id?: string | null | undefined;
591
646
  readonly skills?: readonly {
@@ -929,20 +984,20 @@ export declare const route: Route<{
929
984
  readonly thinking?: {
930
985
  readonly type: "enabled";
931
986
  readonly budget_tokens: number;
932
- readonly display?: "summarized" | "omitted" | undefined;
987
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
933
988
  readonly block_binding?: {
934
- readonly prefix_mismatch_behavior?: string | undefined;
989
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
935
990
  } | undefined;
936
991
  } | {
937
992
  readonly type: "adaptive";
938
- readonly display?: "summarized" | "omitted" | undefined;
993
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
939
994
  readonly block_binding?: {
940
- readonly prefix_mismatch_behavior?: string | undefined;
995
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
941
996
  } | undefined;
942
997
  } | {
943
998
  readonly type: "disabled";
944
999
  } | undefined;
945
- readonly service_tier?: "auto" | "standard_only" | undefined;
1000
+ readonly service_tier?: "auto" | (string & {}) | "standard_only" | undefined;
946
1001
  readonly container?: string | {
947
1002
  readonly id?: string | null | undefined;
948
1003
  readonly skills?: readonly {
@@ -1,5 +1,5 @@
1
1
  import { Buffer } from "node:buffer";
2
- import { Effect, Option, Schema } from "effect";
2
+ import { Effect, Option, Schema, SchemaGetter } from "effect";
3
3
  import { Tool } from "@opencode/schema/tool";
4
4
  import { Route } from "../route/client.js";
5
5
  import { Auth } from "../route/auth.js";
@@ -9,7 +9,7 @@ import { Protocol } from "../route/protocol.js";
9
9
  import { Headers } from "effect/unstable/http";
10
10
  import { HttpTransport } from "../route/transport/index.js";
11
11
  import { AIError, HttpOptions, LLMRequest, LLMEvent, mergeJsonRecords, Usage, } from "../schema/index.js";
12
- import { JsonObject, optionalArray, optionalNull, ProviderShared } from "./shared.js";
12
+ import { JsonObject, knownString, optionalArray, optionalNull, ProviderShared } from "./shared.js";
13
13
  import { classifyProviderFailure } from "../provider-error.js";
14
14
  import { effortUpdate, resolveEffortUpdates } from "../effort-updates.js";
15
15
  import * as Cache from "./utils/cache.js";
@@ -51,6 +51,7 @@ const AnthropicCacheControl = Schema.Struct({
51
51
  type: Schema.tag("ephemeral"),
52
52
  ttl: Schema.optional(Schema.Literals(["5m", "1h"])),
53
53
  });
54
+ const AnthropicServiceTier = knownString();
54
55
  const AnthropicTextBlock = Schema.Struct({
55
56
  type: Schema.tag("text"),
56
57
  text: Schema.String,
@@ -209,24 +210,20 @@ const AnthropicToolChoice = Schema.Union([
209
210
  }),
210
211
  ]);
211
212
  const AnthropicThinkingBlockBinding = Schema.Struct({
212
- prefix_mismatch_behavior: Schema.optional(Schema.String),
213
+ prefix_mismatch_behavior: Schema.optional(knownString()),
213
214
  });
214
- const AnthropicThinking = Schema.Union([
215
- Schema.Struct({
216
- type: Schema.tag("enabled"),
217
- budget_tokens: Schema.Number,
218
- display: Schema.optional(Schema.Literals(["summarized", "omitted"])),
219
- block_binding: Schema.optional(AnthropicThinkingBlockBinding),
220
- }),
221
- Schema.Struct({
222
- type: Schema.tag("adaptive"),
223
- display: Schema.optional(Schema.Literals(["summarized", "omitted"])),
224
- block_binding: Schema.optional(AnthropicThinkingBlockBinding),
225
- }),
226
- Schema.Struct({
227
- type: Schema.tag("disabled"),
228
- }),
229
- ]);
215
+ const AnthropicThinkingFields = {
216
+ display: Schema.optional(knownString()),
217
+ block_binding: Schema.optional(AnthropicThinkingBlockBinding),
218
+ };
219
+ const AnthropicThinkingEnabled = Schema.Struct({
220
+ type: Schema.tag("enabled"),
221
+ budget_tokens: Schema.Number,
222
+ ...AnthropicThinkingFields,
223
+ });
224
+ const AnthropicThinkingAdaptive = Schema.Struct({ type: Schema.tag("adaptive"), ...AnthropicThinkingFields });
225
+ const AnthropicThinkingDisabled = Schema.Struct({ type: Schema.tag("disabled") });
226
+ const AnthropicThinking = Schema.Union([AnthropicThinkingEnabled, AnthropicThinkingAdaptive, AnthropicThinkingDisabled]);
230
227
  // SDK OutputConfig:2684 {effort?: "low"|"medium"|"high"|"xhigh"|"max"|null, format?: JSONOutputFormat:2399}
231
228
  const AnthropicJsonOutputFormat = Schema.Struct({
232
229
  type: Schema.Literal("json_schema"),
@@ -246,6 +243,48 @@ const AnthropicContainer = Schema.Union([
246
243
  skills: optionalNull(Schema.Array(JsonObject)),
247
244
  }),
248
245
  ]);
246
+ // =============================================================================
247
+ // Provider Options
248
+ // =============================================================================
249
+ // Callers spell the budget as `budgetTokens` or the wire `budget_tokens`; the
250
+ // keys are disjoint per variant so the input type requires exactly one and the
251
+ // transform can narrow on it. Decoding straight to the wire block keeps the
252
+ // alias out of the rest of the file.
253
+ const ThinkingEnabledInput = Schema.Union([
254
+ Schema.Struct({ type: Schema.tag("enabled"), budgetTokens: Schema.Number, ...AnthropicThinkingFields }),
255
+ Schema.Struct({ type: Schema.tag("enabled"), budget_tokens: Schema.Number, ...AnthropicThinkingFields }),
256
+ ]).pipe(Schema.decodeTo(AnthropicThinkingEnabled, {
257
+ decode: SchemaGetter.transform((input) => ({
258
+ type: "enabled",
259
+ budget_tokens: "budgetTokens" in input ? input.budgetTokens : input.budget_tokens,
260
+ display: input.display,
261
+ block_binding: input.block_binding,
262
+ })),
263
+ encode: SchemaGetter.passthrough({ strict: false }),
264
+ }));
265
+ const Thinking = Schema.Union([ThinkingEnabledInput, AnthropicThinkingAdaptive, AnthropicThinkingDisabled]);
266
+ const OutputConfigInput = Schema.Struct({
267
+ effort: optionalNull(Schema.String),
268
+ format: optionalNull(AnthropicJsonOutputFormat),
269
+ });
270
+ // Both key spellings are accepted; `fromRequest` prefers the snake_case one.
271
+ const Options = Schema.Struct({
272
+ /** Advanced in-band compaction. The caller owns checkpoint persistence and recovery. */
273
+ contextManagement: Schema.optional(ContextManagement),
274
+ thinking: Schema.optional(Thinking),
275
+ effort: Schema.optional(Schema.String),
276
+ service_tier: Schema.optional(AnthropicServiceTier),
277
+ serviceTier: Schema.optional(AnthropicServiceTier),
278
+ metadata: Schema.optional(AnthropicMetadata),
279
+ container: Schema.optional(AnthropicContainer),
280
+ inference_geo: optionalNull(Schema.String),
281
+ inferenceGeo: optionalNull(Schema.String),
282
+ cache_control: Schema.optional(AnthropicCacheControl),
283
+ cacheControl: Schema.optional(AnthropicCacheControl),
284
+ output_config: Schema.optional(OutputConfigInput),
285
+ outputConfig: Schema.optional(OutputConfigInput),
286
+ });
287
+ const decodeOptions = ProviderShared.validateWith(Schema.decodeUnknownEffect(Options));
249
288
  const AnthropicBodyFields = {
250
289
  context_management: Schema.optional(Schema.Struct({
251
290
  edits: Schema.Array(Schema.Struct({
@@ -273,7 +312,7 @@ const AnthropicBodyFields = {
273
312
  container: Schema.optional(Schema.NullOr(AnthropicContainer)),
274
313
  inference_geo: Schema.optional(Schema.NullOr(Schema.String)),
275
314
  metadata: Schema.optional(AnthropicMetadata),
276
- service_tier: Schema.optional(Schema.Literals(["auto", "standard_only"])),
315
+ service_tier: Schema.optional(AnthropicServiceTier),
277
316
  };
278
317
  export const AnthropicMessagesBody = Schema.Struct(AnthropicBodyFields);
279
318
  const AnthropicIterationUsage = Schema.StructWithRest(Schema.Struct({
@@ -821,51 +860,6 @@ const lowerMessages = Effect.fn("AnthropicMessages.lowerMessages")(function* (re
821
860
  }
822
861
  return messages;
823
862
  });
824
- const resolveOptions = Effect.fn("AnthropicMessages.resolveOptions")(function* (request) {
825
- const input = request.providerOptions;
826
- const rawServiceTier = input?.service_tier ??
827
- input?.serviceTier;
828
- const service_tier = rawServiceTier === "auto" || rawServiceTier === "standard_only"
829
- ? rawServiceTier
830
- : undefined;
831
- const rawMetadata = input?.metadata;
832
- const metadata = ProviderShared.isRecord(rawMetadata) && (typeof rawMetadata.user_id === "string" || rawMetadata.user_id === null)
833
- ? { user_id: rawMetadata.user_id }
834
- : undefined;
835
- const container = typeof input?.container === "string" ||
836
- ProviderShared.isRecord(input?.container)
837
- ? input.container
838
- : undefined;
839
- const rawInferenceGeo = input?.inference_geo ??
840
- input?.inferenceGeo;
841
- const inference_geo = typeof rawInferenceGeo === "string" ? rawInferenceGeo : undefined;
842
- const rawCacheControl = input?.cache_control ??
843
- input?.cacheControl;
844
- const cache_control = ProviderShared.isRecord(rawCacheControl) && rawCacheControl.type === "ephemeral"
845
- ? rawCacheControl
846
- : undefined;
847
- const rawOutputConfig = input?.output_config ??
848
- input?.outputConfig;
849
- const outputConfigEffort = typeof input?.effort === "string"
850
- ? input.effort
851
- : ProviderShared.isRecord(rawOutputConfig) && typeof rawOutputConfig.effort === "string"
852
- ? rawOutputConfig.effort
853
- : undefined;
854
- const outputConfigFormat = ProviderShared.isRecord(rawOutputConfig) && ProviderShared.isRecord(rawOutputConfig.format)
855
- ? rawOutputConfig.format
856
- : undefined;
857
- const thinking = yield* resolveThinking(input?.thinking);
858
- return {
859
- thinking: applyThinkingBindingDefault(request.model, thinking),
860
- effort: outputConfigEffort,
861
- format: outputConfigFormat,
862
- service_tier,
863
- metadata,
864
- container,
865
- inference_geo,
866
- cache_control,
867
- };
868
- });
869
863
  // Accept gateway namespaces and Vertex suffixes without treating a snapshot date as a minor version.
870
864
  const claudeVersion = (id) => {
871
865
  const match = /(?:^|[./])claude-(?<family>[a-z]+)-(?<major>\d+)(?:[.-](?<minor>\d{1,2}))?(?:$|[-:@])/.exec(id.toLowerCase())?.groups;
@@ -906,32 +900,12 @@ const applyThinkingBindingDefault = (model, thinking) => {
906
900
  },
907
901
  };
908
902
  };
909
- const resolveThinking = Effect.fn("AnthropicMessages.resolveThinking")(function* (input) {
910
- if (!ProviderShared.isRecord(input))
911
- return undefined;
912
- if (input.type === "disabled")
913
- return { type: "disabled" };
914
- if (input.type !== "adaptive" && input.type !== "enabled")
915
- return undefined;
916
- const block_binding = yield* ProviderShared.validateWith(Schema.decodeUnknownEffect(Schema.UndefinedOr(AnthropicThinkingBlockBinding)))(input.block_binding);
917
- const display = input.display === "summarized" || input.display === "omitted"
918
- ? input.display
919
- : undefined;
920
- if (input.type === "adaptive")
921
- return { type: "adaptive", display, block_binding };
922
- const budget = typeof input.budgetTokens === "number"
923
- ? input.budgetTokens
924
- : typeof input.budget_tokens === "number"
925
- ? input.budget_tokens
926
- : undefined;
927
- if (budget === undefined)
928
- return yield* ProviderShared.invalidRequest("Anthropic thinking provider option requires budgetTokens");
929
- return { type: "enabled", budget_tokens: budget, display, block_binding };
930
- });
931
903
  const fromRequest = Effect.fn("AnthropicMessages.fromRequest")(function* (request) {
932
- const management = yield* ProviderShared.validateWith(Schema.decodeUnknownEffect(Schema.UndefinedOr(ContextManagement)))(request.providerOptions?.contextManagement);
933
- const options = yield* resolveOptions(request);
934
- const updates = resolveEffortUpdates(request, options.effort);
904
+ const options = yield* decodeOptions(request.providerOptions ?? {});
905
+ const management = options.contextManagement;
906
+ const outputConfig = options.output_config ?? options.outputConfig;
907
+ const format = outputConfig?.format ?? undefined;
908
+ const updates = resolveEffortUpdates(request, options.effort ?? outputConfig?.effort ?? undefined);
935
909
  const generation = request.generation;
936
910
  const toolSchemaCompatibility = request.model.compatibility?.toolSchema;
937
911
  // Allocate the 4-breakpoint budget in invalidation order: tools → system →
@@ -956,12 +930,7 @@ const fromRequest = Effect.fn("AnthropicMessages.fromRequest")(function* (reques
956
930
  if (breakpoints.dropped > 0) {
957
931
  yield* Effect.logWarning(`Anthropic Messages: dropped ${breakpoints.dropped} cache breakpoint(s); the API allows at most ${ANTHROPIC_BREAKPOINT_CAP} per request.`);
958
932
  }
959
- const output_config = updates.effort === undefined && options.format === undefined
960
- ? undefined
961
- : {
962
- ...(updates.effort === undefined ? {} : { effort: updates.effort }),
963
- ...(options.format === undefined ? {} : { format: options.format }),
964
- };
933
+ const output_config = updates.effort === undefined && format === undefined ? undefined : { effort: updates.effort, format };
965
934
  const body = {
966
935
  model: request.model.id,
967
936
  system,
@@ -974,14 +943,14 @@ const fromRequest = Effect.fn("AnthropicMessages.fromRequest")(function* (reques
974
943
  top_p: generation?.topP,
975
944
  top_k: generation?.topK,
976
945
  stop_sequences: generation?.stop,
977
- thinking: options.thinking,
946
+ thinking: applyThinkingBindingDefault(request.model, options.thinking),
978
947
  output_config,
979
948
  // top-level passthrough per SDK MessageCreateParamsBase:4638,4643,4649,4654,4670
980
- cache_control: options.cache_control,
949
+ cache_control: options.cache_control ?? options.cacheControl,
981
950
  container: options.container,
982
- inference_geo: options.inference_geo,
951
+ inference_geo: options.inference_geo ?? options.inferenceGeo ?? undefined,
983
952
  metadata: options.metadata,
984
- service_tier: options.service_tier,
953
+ service_tier: options.service_tier ?? options.serviceTier,
985
954
  };
986
955
  if (!management)
987
956
  return body;
@@ -1,23 +1,25 @@
1
1
  import { Schema } from "effect";
2
2
  import { Route } from "../route/client.js";
3
3
  import { Protocol } from "../route/protocol.js";
4
+ import { type ProviderOptions } from "../schema/index.js";
4
5
  import { Lifecycle } from "./utils/lifecycle.js";
5
6
  export declare const DEFAULT_BASE_URL = "https://generativelanguage.googleapis.com/v1beta";
6
- export interface OptionsInput {
7
- readonly [key: string]: unknown;
8
- readonly cachedContent?: string;
9
- readonly safetySettings?: ReadonlyArray<{
10
- readonly category: "HARM_CATEGORY_UNSPECIFIED" | "HARM_CATEGORY_HATE_SPEECH" | "HARM_CATEGORY_DANGEROUS_CONTENT" | "HARM_CATEGORY_HARASSMENT" | "HARM_CATEGORY_SEXUALLY_EXPLICIT" | "HARM_CATEGORY_CIVIC_INTEGRITY" | (string & {});
11
- readonly threshold: "HARM_BLOCK_THRESHOLD_UNSPECIFIED" | "BLOCK_LOW_AND_ABOVE" | "BLOCK_MEDIUM_AND_ABOVE" | "BLOCK_ONLY_HIGH" | "BLOCK_NONE" | "OFF" | (string & {});
12
- }>;
13
- readonly serviceTier?: "standard" | "flex" | "priority" | (string & {});
14
- readonly thinkingConfig?: {
15
- readonly thinkingBudget?: number;
16
- readonly includeThoughts?: boolean;
17
- readonly thinkingLevel?: "minimal" | "low" | "medium" | "high" | (string & {});
18
- };
19
- }
7
+ /** Caller-facing provider options; unknown keys are accepted and ignored. */
8
+ export type OptionsInput = ProviderOptions & typeof Options.Encoded;
20
9
  export type ProviderOptionsInput = OptionsInput;
10
+ declare const Options: Schema.Struct<{
11
+ readonly cachedContent: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.String>, never>>;
12
+ readonly safetySettings: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.$Array<Schema.Struct<{
13
+ readonly category: Schema.declare<(string & {}) | "HARM_CATEGORY_UNSPECIFIED" | "HARM_CATEGORY_HATE_SPEECH" | "HARM_CATEGORY_DANGEROUS_CONTENT" | "HARM_CATEGORY_HARASSMENT" | "HARM_CATEGORY_SEXUALLY_EXPLICIT" | "HARM_CATEGORY_CIVIC_INTEGRITY", (string & {}) | "HARM_CATEGORY_UNSPECIFIED" | "HARM_CATEGORY_HATE_SPEECH" | "HARM_CATEGORY_DANGEROUS_CONTENT" | "HARM_CATEGORY_HARASSMENT" | "HARM_CATEGORY_SEXUALLY_EXPLICIT" | "HARM_CATEGORY_CIVIC_INTEGRITY">;
14
+ readonly threshold: Schema.declare<(string & {}) | "HARM_BLOCK_THRESHOLD_UNSPECIFIED" | "BLOCK_LOW_AND_ABOVE" | "BLOCK_MEDIUM_AND_ABOVE" | "BLOCK_ONLY_HIGH" | "BLOCK_NONE" | "OFF", (string & {}) | "HARM_BLOCK_THRESHOLD_UNSPECIFIED" | "BLOCK_LOW_AND_ABOVE" | "BLOCK_MEDIUM_AND_ABOVE" | "BLOCK_ONLY_HIGH" | "BLOCK_NONE" | "OFF">;
15
+ }>>>, never>>;
16
+ readonly serviceTier: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.declare<(string & {}) | "standard" | "flex" | "priority", (string & {}) | "standard" | "flex" | "priority">>, never>>;
17
+ readonly thinkingConfig: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.Struct<{
18
+ readonly thinkingBudget: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.Number>, never>>;
19
+ readonly includeThoughts: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.Boolean>, never>>;
20
+ readonly thinkingLevel: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.declare<(string & {}) | "minimal" | "low" | "medium" | "high", (string & {}) | "minimal" | "low" | "medium" | "high">>, never>>;
21
+ }>>, never>>;
22
+ }>;
21
23
  declare const GeminiBody: Schema.Struct<{
22
24
  cachedContent: Schema.optional<Schema.String>;
23
25
  contents: Schema.$Array<Schema.Struct<{
@@ -54,8 +56,8 @@ declare const GeminiBody: Schema.Struct<{
54
56
  }>>;
55
57
  labels: Schema.optional<Schema.$Record<Schema.String, Schema.String>>;
56
58
  safetySettings: Schema.optional<Schema.$Array<Schema.Struct<{
57
- readonly category: Schema.String;
58
- readonly threshold: Schema.String;
59
+ readonly category: Schema.declare<(string & {}) | "HARM_CATEGORY_UNSPECIFIED" | "HARM_CATEGORY_HATE_SPEECH" | "HARM_CATEGORY_DANGEROUS_CONTENT" | "HARM_CATEGORY_HARASSMENT" | "HARM_CATEGORY_SEXUALLY_EXPLICIT" | "HARM_CATEGORY_CIVIC_INTEGRITY", (string & {}) | "HARM_CATEGORY_UNSPECIFIED" | "HARM_CATEGORY_HATE_SPEECH" | "HARM_CATEGORY_DANGEROUS_CONTENT" | "HARM_CATEGORY_HARASSMENT" | "HARM_CATEGORY_SEXUALLY_EXPLICIT" | "HARM_CATEGORY_CIVIC_INTEGRITY">;
60
+ readonly threshold: Schema.declare<(string & {}) | "HARM_BLOCK_THRESHOLD_UNSPECIFIED" | "BLOCK_LOW_AND_ABOVE" | "BLOCK_MEDIUM_AND_ABOVE" | "BLOCK_ONLY_HIGH" | "BLOCK_NONE" | "OFF", (string & {}) | "HARM_BLOCK_THRESHOLD_UNSPECIFIED" | "BLOCK_LOW_AND_ABOVE" | "BLOCK_MEDIUM_AND_ABOVE" | "BLOCK_ONLY_HIGH" | "BLOCK_NONE" | "OFF">;
59
61
  }>>>;
60
62
  serviceTier: Schema.optional<Schema.String>;
61
63
  systemInstruction: Schema.optional<Schema.Struct<{
@@ -88,7 +90,7 @@ declare const GeminiBody: Schema.Struct<{
88
90
  readonly thinkingConfig: Schema.optional<Schema.Struct<{
89
91
  readonly thinkingBudget: Schema.optional<Schema.Number>;
90
92
  readonly includeThoughts: Schema.optional<Schema.Boolean>;
91
- readonly thinkingLevel: Schema.optional<Schema.String>;
93
+ readonly thinkingLevel: Schema.optional<Schema.declare<(string & {}) | "minimal" | "low" | "medium" | "high", (string & {}) | "minimal" | "low" | "medium" | "high">>;
92
94
  }>>;
93
95
  }>>;
94
96
  }>;
@@ -148,8 +150,8 @@ export declare const protocol: Protocol<{
148
150
  } | undefined;
149
151
  readonly cachedContent?: string | undefined;
150
152
  readonly safetySettings?: readonly {
151
- readonly category: string;
152
- readonly threshold: string;
153
+ readonly category: (string & {}) | "HARM_CATEGORY_UNSPECIFIED" | "HARM_CATEGORY_HATE_SPEECH" | "HARM_CATEGORY_DANGEROUS_CONTENT" | "HARM_CATEGORY_HARASSMENT" | "HARM_CATEGORY_SEXUALLY_EXPLICIT" | "HARM_CATEGORY_CIVIC_INTEGRITY";
154
+ readonly threshold: (string & {}) | "HARM_BLOCK_THRESHOLD_UNSPECIFIED" | "BLOCK_LOW_AND_ABOVE" | "BLOCK_MEDIUM_AND_ABOVE" | "BLOCK_ONLY_HIGH" | "BLOCK_NONE" | "OFF";
153
155
  }[] | undefined;
154
156
  readonly labels?: {
155
157
  readonly [x: string]: string;
@@ -170,7 +172,7 @@ export declare const protocol: Protocol<{
170
172
  readonly thinkingConfig?: {
171
173
  readonly thinkingBudget?: number | undefined;
172
174
  readonly includeThoughts?: boolean | undefined;
173
- readonly thinkingLevel?: string | undefined;
175
+ readonly thinkingLevel?: (string & {}) | "minimal" | "low" | "medium" | "high" | undefined;
174
176
  } | undefined;
175
177
  readonly maxOutputTokens?: number | undefined;
176
178
  } | undefined;
@@ -255,8 +257,8 @@ export declare const route: Route<{
255
257
  } | undefined;
256
258
  readonly cachedContent?: string | undefined;
257
259
  readonly safetySettings?: readonly {
258
- readonly category: string;
259
- readonly threshold: string;
260
+ readonly category: (string & {}) | "HARM_CATEGORY_UNSPECIFIED" | "HARM_CATEGORY_HATE_SPEECH" | "HARM_CATEGORY_DANGEROUS_CONTENT" | "HARM_CATEGORY_HARASSMENT" | "HARM_CATEGORY_SEXUALLY_EXPLICIT" | "HARM_CATEGORY_CIVIC_INTEGRITY";
261
+ readonly threshold: (string & {}) | "HARM_BLOCK_THRESHOLD_UNSPECIFIED" | "BLOCK_LOW_AND_ABOVE" | "BLOCK_MEDIUM_AND_ABOVE" | "BLOCK_ONLY_HIGH" | "BLOCK_NONE" | "OFF";
260
262
  }[] | undefined;
261
263
  readonly labels?: {
262
264
  readonly [x: string]: string;
@@ -277,7 +279,7 @@ export declare const route: Route<{
277
279
  readonly thinkingConfig?: {
278
280
  readonly thinkingBudget?: number | undefined;
279
281
  readonly includeThoughts?: boolean | undefined;
280
- readonly thinkingLevel?: string | undefined;
282
+ readonly thinkingLevel?: (string & {}) | "minimal" | "low" | "medium" | "high" | undefined;
281
283
  } | undefined;
282
284
  readonly maxOutputTokens?: number | undefined;
283
285
  } | undefined;
@@ -7,7 +7,7 @@ import { Framing } from "../route/framing.js";
7
7
  import { Protocol } from "../route/protocol.js";
8
8
  import { AIError, LLMEvent, Usage, } from "../schema/index.js";
9
9
  import { classifyProviderFailure } from "../provider-error.js";
10
- import { JsonObject, optionalArray, optionalNull, ProviderShared } from "./shared.js";
10
+ import { JsonObject, knownString, lenient, optionalArray, optionalNull, ProviderShared } from "./shared.js";
11
11
  import { GeminiToolSchema } from "./utils/gemini-tool-schema.js";
12
12
  import { Lifecycle } from "./utils/lifecycle.js";
13
13
  import { ToolSchemaProjection } from "./utils/tool-schema.js";
@@ -103,15 +103,33 @@ const GeminiToolConfig = Schema.Struct({
103
103
  allowedFunctionNames: optionalArray(Schema.String),
104
104
  }),
105
105
  });
106
+ const GeminiThinkingLevel = knownString();
106
107
  const GeminiThinkingConfig = Schema.Struct({
107
108
  thinkingBudget: Schema.optional(Schema.Number),
108
109
  includeThoughts: Schema.optional(Schema.Boolean),
109
- thinkingLevel: Schema.optional(Schema.String),
110
+ thinkingLevel: Schema.optional(GeminiThinkingLevel),
110
111
  });
111
112
  const GeminiSafetySetting = Schema.Struct({
112
- category: Schema.String,
113
- threshold: Schema.String,
113
+ category: knownString(),
114
+ threshold: knownString(),
114
115
  });
116
+ // =============================================================================
117
+ // Provider Options
118
+ // =============================================================================
119
+ // Malformed fields are dropped rather than failing the request; a `thinkingConfig`
120
+ // object that omits `includeThoughts` asks for thoughts.
121
+ const GeminiThinkingConfigInput = Schema.Struct({
122
+ thinkingBudget: lenient(Schema.Number),
123
+ includeThoughts: lenient(Schema.Boolean),
124
+ thinkingLevel: lenient(GeminiThinkingLevel),
125
+ });
126
+ const Options = Schema.Struct({
127
+ cachedContent: lenient(Schema.String),
128
+ safetySettings: lenient(Schema.Array(GeminiSafetySetting)),
129
+ serviceTier: lenient(knownString()),
130
+ thinkingConfig: lenient(GeminiThinkingConfigInput),
131
+ });
132
+ const decodeOptions = ProviderShared.validateWith(Schema.decodeUnknownEffect(Options));
115
133
  const GeminiGenerationConfig = Schema.Struct({
116
134
  maxOutputTokens: Schema.optional(Schema.Number),
117
135
  temperature: Schema.optional(Schema.Number),
@@ -334,38 +352,11 @@ const lowerMessages = Effect.fn("Gemini.lowerMessages")(function* (request) {
334
352
  flushMedia();
335
353
  return contents;
336
354
  });
337
- const resolveOptions = (request) => {
338
- const input = request.providerOptions;
339
- const value = input?.thinkingConfig;
340
- const thinkingConfig = {
341
- thinkingBudget: ProviderShared.isRecord(value) && typeof value.thinkingBudget === "number" ? value.thinkingBudget : undefined,
342
- includeThoughts: ProviderShared.isRecord(value) && typeof value.includeThoughts === "boolean"
343
- ? value.includeThoughts
344
- : ProviderShared.isRecord(value)
345
- ? true
346
- : undefined,
347
- thinkingLevel: ProviderShared.isRecord(value) && typeof value.thinkingLevel === "string" ? value.thinkingLevel : undefined,
348
- };
349
- return {
350
- cachedContent: typeof input?.cachedContent === "string" ? input.cachedContent : undefined,
351
- safetySettings: mapSafetySettings(input?.safetySettings),
352
- serviceTier: typeof input?.serviceTier === "string" ? input.serviceTier : undefined,
353
- thinkingConfig: Object.values(thinkingConfig).some((item) => item !== undefined) ? thinkingConfig : undefined,
354
- };
355
- };
356
- function mapSafetySettings(value) {
357
- if (!Array.isArray(value))
358
- return undefined;
359
- const settings = value.flatMap((item) => ProviderShared.isRecord(item) && typeof item.category === "string" && typeof item.threshold === "string"
360
- ? [{ category: item.category, threshold: item.threshold }]
361
- : []);
362
- return settings;
363
- }
364
355
  const fromRequest = Effect.fn("Gemini.fromRequest")(function* (request) {
365
356
  const flattened = ProviderShared.flattenToolRequest(request);
366
357
  const hasTools = flattened.tools.length > 0;
367
358
  const generation = request.generation;
368
- const options = resolveOptions(request);
359
+ const options = yield* decodeOptions(request.providerOptions ?? {});
369
360
  const toolSchemaCompatibility = request.model.compatibility?.toolSchema;
370
361
  const generationConfig = {
371
362
  maxOutputTokens: generation?.maxTokens,
@@ -376,7 +367,9 @@ const fromRequest = Effect.fn("Gemini.fromRequest")(function* (request) {
376
367
  presencePenalty: generation?.presencePenalty,
377
368
  seed: generation?.seed,
378
369
  stopSequences: generation?.stop,
379
- thinkingConfig: options.thinkingConfig,
370
+ thinkingConfig: options.thinkingConfig === undefined
371
+ ? undefined
372
+ : { ...options.thinkingConfig, includeThoughts: options.thinkingConfig.includeThoughts ?? true },
380
373
  };
381
374
  return {
382
375
  cachedContent: options.cachedContent,
@@ -221,20 +221,20 @@ export declare const protocol: Protocol<{
221
221
  readonly thinking?: {
222
222
  readonly type: "enabled";
223
223
  readonly budget_tokens: number;
224
- readonly display?: "summarized" | "omitted" | undefined;
224
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
225
225
  readonly block_binding?: {
226
- readonly prefix_mismatch_behavior?: string | undefined;
226
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
227
227
  } | undefined;
228
228
  } | {
229
229
  readonly type: "adaptive";
230
- readonly display?: "summarized" | "omitted" | undefined;
230
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
231
231
  readonly block_binding?: {
232
- readonly prefix_mismatch_behavior?: string | undefined;
232
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
233
233
  } | undefined;
234
234
  } | {
235
235
  readonly type: "disabled";
236
236
  } | undefined;
237
- readonly service_tier?: "auto" | "standard_only" | undefined;
237
+ readonly service_tier?: "auto" | (string & {}) | "standard_only" | undefined;
238
238
  readonly container?: string | {
239
239
  readonly id?: string | null | undefined;
240
240
  readonly skills?: readonly {
@@ -10,6 +10,10 @@ export declare const encodeJson: (input: unknown, options?: import("effect/Schem
10
10
  export declare const JsonObject: Schema.$Record<Schema.String, Schema.Unknown>;
11
11
  export declare const optionalArray: <const S extends Schema.Top>(schema: S) => Schema.optional<Schema.$Array<S>>;
12
12
  export declare const optionalNull: <const S extends Schema.Top>(schema: S) => Schema.optional<Schema.NullOr<S>>;
13
+ /** Optional field whose malformed value decodes to `undefined` instead of failing the enclosing struct. */
14
+ export declare const lenient: <const S extends Schema.Top>(schema: S) => Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<S>, S["DecodingServices"]>>;
15
+ /** Provider-defined string enum: known values for autocomplete, any string accepted at runtime. */
16
+ export declare const knownString: <Known extends string>() => Schema.declare<(string & {}) | Known, (string & {}) | Known>;
13
17
  export declare const OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH = 64;
14
18
  export declare const promptCacheKey: (request: LLMRequest) => string | undefined;
15
19
  /**
@@ -1,6 +1,6 @@
1
1
  import { Buffer } from "node:buffer";
2
2
  import { Tool } from "@opencode/schema/tool";
3
- import { Effect, Schema, Stream } from "effect";
3
+ import { Effect, Option, Schema, Stream } from "effect";
4
4
  import * as Sse from "effect/unstable/encoding/Sse";
5
5
  import { Headers, HttpClientRequest, HttpClientResponse } from "effect/unstable/http";
6
6
  import { InvalidProviderOutputError, InvalidRequestError, UnsupportedOperationError, AIError, HttpContext, LLMRequest, Message, ToolDefinition, } from "../schema/index.js";
@@ -13,6 +13,12 @@ const isJson = Schema.is(Schema.Json);
13
13
  export const JsonObject = Schema.Record(Schema.String, Schema.Unknown);
14
14
  export const optionalArray = (schema) => Schema.optional(Schema.Array(schema));
15
15
  export const optionalNull = (schema) => Schema.optional(Schema.NullOr(schema));
16
+ /** Optional field whose malformed value decodes to `undefined` instead of failing the enclosing struct. */
17
+ export const lenient = (schema) => Schema.optionalKey(Schema.UndefinedOr(schema).pipe(Schema.catchDecoding(() => Effect.succeed(Option.some(undefined)))));
18
+ /** Provider-defined string enum: known values for autocomplete, any string accepted at runtime. */
19
+ export const knownString = () => Schema.declare((value) => typeof value === "string", {
20
+ expected: "string",
21
+ });
16
22
  export const OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH = 64;
17
23
  // OpenAI limits `prompt_cache_key` to 64 chars; DeepSeek and Zai inherit the same
18
24
  // limit via their OpenAI-compatible APIs. Clamp with unicode-aware slicing.
@@ -24,25 +24,25 @@ export declare const StreamOptions: Schema.Struct<{
24
24
  readonly includeObfuscation: Schema.optional<Schema.Boolean>;
25
25
  }>;
26
26
  export declare const Options: Schema.Struct<{
27
- readonly store: Schema.optional<Schema.Boolean>;
28
- readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.String>>;
29
- readonly safetyIdentifier: Schema.optional<Schema.String>;
30
- readonly streamOptions: Schema.optional<Schema.Struct<{
27
+ readonly store: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.Boolean>, never>>;
28
+ readonly metadata: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.$Record<Schema.String, Schema.String>>, never>>;
29
+ readonly safetyIdentifier: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.String>, never>>;
30
+ readonly streamOptions: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.Struct<{
31
31
  readonly includeObfuscation: Schema.optional<Schema.Boolean>;
32
- }>>;
33
- readonly topLogprobs: Schema.optional<Schema.Int>;
34
- readonly reasoningEffort: Schema.optional<Schema.declare<ReasoningEffort, ReasoningEffort>>;
35
- readonly reasoningSummary: Schema.optional<Schema.Literals<readonly ["auto", "concise", "detailed"]>>;
36
- readonly include: Schema.optional<Schema.$Array<Schema.declare<ResponseIncludable, ResponseIncludable>>>;
37
- readonly textVerbosity: Schema.optional<Schema.declare<TextVerbosity, TextVerbosity>>;
38
- readonly serviceTier: Schema.optional<Schema.declare<ServiceTier, ServiceTier>>;
39
- readonly truncation: Schema.optional<Schema.Literals<readonly ["auto", "disabled"]>>;
40
- readonly allowedTools: Schema.optional<Schema.Struct<{
32
+ }>>, never>>;
33
+ readonly topLogprobs: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.Int>, never>>;
34
+ readonly reasoningEffort: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.declare<ReasoningEffort, ReasoningEffort>>, never>>;
35
+ readonly reasoningSummary: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.Literals<readonly ["auto", "concise", "detailed"]>>, never>>;
36
+ readonly include: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.$Array<Schema.declare<ResponseIncludable, ResponseIncludable>>>, never>>;
37
+ readonly textVerbosity: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.declare<TextVerbosity, TextVerbosity>>, never>>;
38
+ readonly serviceTier: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.declare<ServiceTier, ServiceTier>>, never>>;
39
+ readonly truncation: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.Literals<readonly ["auto", "disabled"]>>, never>>;
40
+ readonly allowedTools: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.Struct<{
41
41
  readonly toolNames: Schema.$Array<Schema.String>;
42
42
  readonly mode: Schema.optional<Schema.Literals<readonly ["auto", "none", "required"]>>;
43
- }>>;
44
- readonly maxToolCalls: Schema.optional<Schema.Int>;
45
- readonly parallelToolCalls: Schema.optional<Schema.Boolean>;
43
+ }>>, never>>;
44
+ readonly maxToolCalls: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.Int>, never>>;
45
+ readonly parallelToolCalls: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.Boolean>, never>>;
46
46
  }>;
47
47
  export type Options = typeof Options.Type;
48
48
  export type Resolved = Omit<Options, "allowedTools"> & {
@@ -1,5 +1,6 @@
1
- import { Option, Schema } from "effect";
1
+ import { Schema } from "effect";
2
2
  import { ReasoningEffort, ReasoningEfforts } from "../../schema/index.js";
3
+ import { lenient } from "../shared.js";
3
4
  export { ReasoningEffort, ReasoningEfforts };
4
5
  export const TextVerbosities = ["low", "medium", "high"];
5
6
  export const TextVerbosity = Schema.declare((value) => typeof value === "string", { title: "TextVerbosity" });
@@ -29,27 +30,26 @@ export const AllowedTools = Schema.Struct({
29
30
  export const StreamOptions = Schema.Struct({
30
31
  includeObfuscation: Schema.optional(Schema.Boolean),
31
32
  });
33
+ // Malformed options are dropped one at a time so a bad `topLogprobs` cannot discard `store` or `reasoningEffort`.
32
34
  export const Options = Schema.Struct({
33
- store: Schema.optional(Schema.Boolean),
34
- metadata: Schema.optional(Schema.Record(Schema.String, Schema.String)),
35
- safetyIdentifier: Schema.optional(Schema.String),
36
- streamOptions: Schema.optional(StreamOptions),
37
- topLogprobs: Schema.optional(Schema.Int.check(Schema.isBetween({ minimum: 0, maximum: 20 }))),
38
- reasoningEffort: Schema.optional(ReasoningEffort),
39
- reasoningSummary: Schema.optional(Schema.Literals(["auto", "concise", "detailed"])),
40
- include: Schema.optional(Schema.Array(ResponseIncludableSchema)),
41
- textVerbosity: Schema.optional(TextVerbositySchema),
42
- serviceTier: Schema.optional(ServiceTierSchema),
43
- truncation: Schema.optional(TruncationSchema),
44
- allowedTools: Schema.optional(AllowedTools),
45
- maxToolCalls: Schema.optional(Schema.Int),
46
- parallelToolCalls: Schema.optional(Schema.Boolean),
35
+ store: lenient(Schema.Boolean),
36
+ metadata: lenient(Schema.Record(Schema.String, Schema.String)),
37
+ safetyIdentifier: lenient(Schema.String),
38
+ streamOptions: lenient(StreamOptions),
39
+ topLogprobs: lenient(Schema.Int.check(Schema.isBetween({ minimum: 0, maximum: 20 }))),
40
+ reasoningEffort: lenient(ReasoningEffort),
41
+ reasoningSummary: lenient(Schema.Literals(["auto", "concise", "detailed"])),
42
+ include: lenient(Schema.Array(ResponseIncludableSchema)),
43
+ textVerbosity: lenient(TextVerbositySchema),
44
+ serviceTier: lenient(ServiceTierSchema),
45
+ truncation: lenient(TruncationSchema),
46
+ allowedTools: lenient(AllowedTools),
47
+ maxToolCalls: lenient(Schema.Int),
48
+ parallelToolCalls: lenient(Schema.Boolean),
47
49
  });
48
- const decodeOptions = Schema.decodeUnknownOption(Options);
50
+ const decodeOptions = Schema.decodeUnknownSync(Options);
49
51
  export const resolve = (request) => {
50
- const input = Option.getOrUndefined(decodeOptions(request.providerOptions));
51
- if (!input)
52
- return {};
52
+ const input = decodeOptions(request.providerOptions ?? {});
53
53
  return {
54
54
  ...input,
55
55
  include: input.include?.length ? input.include : undefined,
@@ -222,7 +222,7 @@ export declare const protocol: Protocol<{
222
222
  readonly thinking?: {
223
223
  readonly type: string;
224
224
  } | undefined;
225
- readonly service_tier?: "auto" | "standard_only" | undefined;
225
+ readonly service_tier?: "auto" | (string & {}) | "standard_only" | undefined;
226
226
  readonly container?: string | {
227
227
  readonly id?: string | null | undefined;
228
228
  readonly skills?: readonly {
@@ -360,7 +360,7 @@ export declare const routes: (Route<{
360
360
  readonly type: string;
361
361
  readonly budget_tokens?: number | undefined;
362
362
  } | undefined;
363
- readonly service_tier?: "auto" | "standard_only" | undefined;
363
+ readonly service_tier?: "auto" | (string & {}) | "standard_only" | undefined;
364
364
  readonly container?: string | {
365
365
  readonly id?: string | null | undefined;
366
366
  readonly skills?: readonly {
@@ -238,20 +238,20 @@ export declare const routes: import("../route/client.js").Route<{
238
238
  readonly thinking?: {
239
239
  readonly type: "enabled";
240
240
  readonly budget_tokens: number;
241
- readonly display?: "summarized" | "omitted" | undefined;
241
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
242
242
  readonly block_binding?: {
243
- readonly prefix_mismatch_behavior?: string | undefined;
243
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
244
244
  } | undefined;
245
245
  } | {
246
246
  readonly type: "adaptive";
247
- readonly display?: "summarized" | "omitted" | undefined;
247
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
248
248
  readonly block_binding?: {
249
- readonly prefix_mismatch_behavior?: string | undefined;
249
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
250
250
  } | undefined;
251
251
  } | {
252
252
  readonly type: "disabled";
253
253
  } | undefined;
254
- readonly service_tier?: "auto" | "standard_only" | undefined;
254
+ readonly service_tier?: "auto" | (string & {}) | "standard_only" | undefined;
255
255
  readonly container?: string | {
256
256
  readonly id?: string | null | undefined;
257
257
  readonly skills?: readonly {
@@ -223,20 +223,20 @@ export declare const routes: import("../route/client.js").Route<{
223
223
  readonly thinking?: {
224
224
  readonly type: "enabled";
225
225
  readonly budget_tokens: number;
226
- readonly display?: "summarized" | "omitted" | undefined;
226
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
227
227
  readonly block_binding?: {
228
- readonly prefix_mismatch_behavior?: string | undefined;
228
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
229
229
  } | undefined;
230
230
  } | {
231
231
  readonly type: "adaptive";
232
- readonly display?: "summarized" | "omitted" | undefined;
232
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
233
233
  readonly block_binding?: {
234
- readonly prefix_mismatch_behavior?: string | undefined;
234
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
235
235
  } | undefined;
236
236
  } | {
237
237
  readonly type: "disabled";
238
238
  } | undefined;
239
- readonly service_tier?: "auto" | "standard_only" | undefined;
239
+ readonly service_tier?: "auto" | (string & {}) | "standard_only" | undefined;
240
240
  readonly container?: string | {
241
241
  readonly id?: string | null | undefined;
242
242
  readonly skills?: readonly {
@@ -474,20 +474,20 @@ export declare const messagesRoute: import("../route/client.js").Route<{
474
474
  readonly thinking?: {
475
475
  readonly type: "enabled";
476
476
  readonly budget_tokens: number;
477
- readonly display?: "summarized" | "omitted" | undefined;
477
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
478
478
  readonly block_binding?: {
479
- readonly prefix_mismatch_behavior?: string | undefined;
479
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
480
480
  } | undefined;
481
481
  } | {
482
482
  readonly type: "adaptive";
483
- readonly display?: "summarized" | "omitted" | undefined;
483
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
484
484
  readonly block_binding?: {
485
- readonly prefix_mismatch_behavior?: string | undefined;
485
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
486
486
  } | undefined;
487
487
  } | {
488
488
  readonly type: "disabled";
489
489
  } | undefined;
490
- readonly service_tier?: "auto" | "standard_only" | undefined;
490
+ readonly service_tier?: "auto" | (string & {}) | "standard_only" | undefined;
491
491
  readonly container?: string | {
492
492
  readonly id?: string | null | undefined;
493
493
  readonly skills?: readonly {
@@ -846,20 +846,20 @@ export declare const routes: (import("../route/client.js").Route<{
846
846
  readonly thinking?: {
847
847
  readonly type: "enabled";
848
848
  readonly budget_tokens: number;
849
- readonly display?: "summarized" | "omitted" | undefined;
849
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
850
850
  readonly block_binding?: {
851
- readonly prefix_mismatch_behavior?: string | undefined;
851
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
852
852
  } | undefined;
853
853
  } | {
854
854
  readonly type: "adaptive";
855
- readonly display?: "summarized" | "omitted" | undefined;
855
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
856
856
  readonly block_binding?: {
857
- readonly prefix_mismatch_behavior?: string | undefined;
857
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
858
858
  } | undefined;
859
859
  } | {
860
860
  readonly type: "disabled";
861
861
  } | undefined;
862
- readonly service_tier?: "auto" | "standard_only" | undefined;
862
+ readonly service_tier?: "auto" | (string & {}) | "standard_only" | undefined;
863
863
  readonly container?: string | {
864
864
  readonly id?: string | null | undefined;
865
865
  readonly skills?: readonly {
@@ -236,20 +236,20 @@ export declare const routes: Route<{
236
236
  thinking?: {
237
237
  readonly type: "enabled";
238
238
  readonly budget_tokens: number;
239
- readonly display?: "summarized" | "omitted" | undefined;
239
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
240
240
  readonly block_binding?: {
241
- readonly prefix_mismatch_behavior?: string | undefined;
241
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
242
242
  } | undefined;
243
243
  } | {
244
244
  readonly type: "adaptive";
245
- readonly display?: "summarized" | "omitted" | undefined;
245
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
246
246
  readonly block_binding?: {
247
- readonly prefix_mismatch_behavior?: string | undefined;
247
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
248
248
  } | undefined;
249
249
  } | {
250
250
  readonly type: "disabled";
251
251
  } | undefined;
252
- service_tier?: "auto" | "standard_only" | undefined;
252
+ service_tier?: "auto" | (string & {}) | "standard_only" | undefined;
253
253
  container?: string | {
254
254
  readonly id?: string | null | undefined;
255
255
  readonly skills?: readonly {
@@ -76,8 +76,8 @@ export declare const routes: Route<{
76
76
  } | undefined;
77
77
  readonly cachedContent?: string | undefined;
78
78
  readonly safetySettings?: readonly {
79
- readonly category: string;
80
- readonly threshold: string;
79
+ readonly category: (string & {}) | "HARM_CATEGORY_UNSPECIFIED" | "HARM_CATEGORY_HATE_SPEECH" | "HARM_CATEGORY_DANGEROUS_CONTENT" | "HARM_CATEGORY_HARASSMENT" | "HARM_CATEGORY_SEXUALLY_EXPLICIT" | "HARM_CATEGORY_CIVIC_INTEGRITY";
80
+ readonly threshold: (string & {}) | "HARM_BLOCK_THRESHOLD_UNSPECIFIED" | "BLOCK_LOW_AND_ABOVE" | "BLOCK_MEDIUM_AND_ABOVE" | "BLOCK_ONLY_HIGH" | "BLOCK_NONE" | "OFF";
81
81
  }[] | undefined;
82
82
  readonly labels?: {
83
83
  readonly [x: string]: string;
@@ -98,7 +98,7 @@ export declare const routes: Route<{
98
98
  readonly thinkingConfig?: {
99
99
  readonly thinkingBudget?: number | undefined;
100
100
  readonly includeThoughts?: boolean | undefined;
101
- readonly thinkingLevel?: string | undefined;
101
+ readonly thinkingLevel?: (string & {}) | "minimal" | "low" | "medium" | "high" | undefined;
102
102
  } | undefined;
103
103
  readonly maxOutputTokens?: number | undefined;
104
104
  } | undefined;
@@ -58,8 +58,8 @@ export declare const routes: import("../route/client.js").Route<{
58
58
  } | undefined;
59
59
  readonly cachedContent?: string | undefined;
60
60
  readonly safetySettings?: readonly {
61
- readonly category: string;
62
- readonly threshold: string;
61
+ readonly category: (string & {}) | "HARM_CATEGORY_UNSPECIFIED" | "HARM_CATEGORY_HATE_SPEECH" | "HARM_CATEGORY_DANGEROUS_CONTENT" | "HARM_CATEGORY_HARASSMENT" | "HARM_CATEGORY_SEXUALLY_EXPLICIT" | "HARM_CATEGORY_CIVIC_INTEGRITY";
62
+ readonly threshold: (string & {}) | "HARM_BLOCK_THRESHOLD_UNSPECIFIED" | "BLOCK_LOW_AND_ABOVE" | "BLOCK_MEDIUM_AND_ABOVE" | "BLOCK_ONLY_HIGH" | "BLOCK_NONE" | "OFF";
63
63
  }[] | undefined;
64
64
  readonly labels?: {
65
65
  readonly [x: string]: string;
@@ -80,7 +80,7 @@ export declare const routes: import("../route/client.js").Route<{
80
80
  readonly thinkingConfig?: {
81
81
  readonly thinkingBudget?: number | undefined;
82
82
  readonly includeThoughts?: boolean | undefined;
83
- readonly thinkingLevel?: string | undefined;
83
+ readonly thinkingLevel?: (string & {}) | "minimal" | "low" | "medium" | "high" | undefined;
84
84
  } | undefined;
85
85
  readonly maxOutputTokens?: number | undefined;
86
86
  } | undefined;
@@ -548,20 +548,20 @@ export declare const routes: (Route<{
548
548
  readonly thinking?: {
549
549
  readonly type: "enabled";
550
550
  readonly budget_tokens: number;
551
- readonly display?: "summarized" | "omitted" | undefined;
551
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
552
552
  readonly block_binding?: {
553
- readonly prefix_mismatch_behavior?: string | undefined;
553
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
554
554
  } | undefined;
555
555
  } | {
556
556
  readonly type: "adaptive";
557
- readonly display?: "summarized" | "omitted" | undefined;
557
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
558
558
  readonly block_binding?: {
559
- readonly prefix_mismatch_behavior?: string | undefined;
559
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
560
560
  } | undefined;
561
561
  } | {
562
562
  readonly type: "disabled";
563
563
  } | undefined;
564
- readonly service_tier?: "auto" | "standard_only" | undefined;
564
+ readonly service_tier?: "auto" | (string & {}) | "standard_only" | undefined;
565
565
  readonly container?: string | {
566
566
  readonly id?: string | null | undefined;
567
567
  readonly skills?: readonly {
@@ -249,20 +249,20 @@ export declare const routes: (Route<{
249
249
  readonly thinking?: {
250
250
  readonly type: "enabled";
251
251
  readonly budget_tokens: number;
252
- readonly display?: "summarized" | "omitted" | undefined;
252
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
253
253
  readonly block_binding?: {
254
- readonly prefix_mismatch_behavior?: string | undefined;
254
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
255
255
  } | undefined;
256
256
  } | {
257
257
  readonly type: "adaptive";
258
- readonly display?: "summarized" | "omitted" | undefined;
258
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
259
259
  readonly block_binding?: {
260
- readonly prefix_mismatch_behavior?: string | undefined;
260
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
261
261
  } | undefined;
262
262
  } | {
263
263
  readonly type: "disabled";
264
264
  } | undefined;
265
- readonly service_tier?: "auto" | "standard_only" | undefined;
265
+ readonly service_tier?: "auto" | (string & {}) | "standard_only" | undefined;
266
266
  readonly container?: string | {
267
267
  readonly id?: string | null | undefined;
268
268
  readonly skills?: readonly {
@@ -247,20 +247,20 @@ export declare const routes: (Route<{
247
247
  readonly thinking?: {
248
248
  readonly type: "enabled";
249
249
  readonly budget_tokens: number;
250
- readonly display?: "summarized" | "omitted" | undefined;
250
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
251
251
  readonly block_binding?: {
252
- readonly prefix_mismatch_behavior?: string | undefined;
252
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
253
253
  } | undefined;
254
254
  } | {
255
255
  readonly type: "adaptive";
256
- readonly display?: "summarized" | "omitted" | undefined;
256
+ readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
257
257
  readonly block_binding?: {
258
- readonly prefix_mismatch_behavior?: string | undefined;
258
+ readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
259
259
  } | undefined;
260
260
  } | {
261
261
  readonly type: "disabled";
262
262
  } | undefined;
263
- readonly service_tier?: "auto" | "standard_only" | undefined;
263
+ readonly service_tier?: "auto" | (string & {}) | "standard_only" | undefined;
264
264
  readonly container?: string | {
265
265
  readonly id?: string | null | undefined;
266
266
  readonly skills?: readonly {
@@ -508,7 +508,7 @@ export declare const routes: (Route<{
508
508
  readonly thinking?: {
509
509
  readonly type: string;
510
510
  } | undefined;
511
- readonly service_tier?: "auto" | "standard_only" | undefined;
511
+ readonly service_tier?: "auto" | (string & {}) | "standard_only" | undefined;
512
512
  readonly container?: string | {
513
513
  readonly id?: string | null | undefined;
514
514
  readonly skills?: readonly {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
- "version": "2.0.7",
3
+ "version": "2.0.9",
4
4
  "name": "@opencode/ai",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -30,7 +30,7 @@
30
30
  "devDependencies": {
31
31
  "@clack/prompts": "1.0.0-alpha.1",
32
32
  "@effect/platform-node": "4.0.0-rc.112",
33
- "@opencode/http-recorder": "2.0.7",
33
+ "@opencode/http-recorder": "2.0.9",
34
34
  "@tsconfig/bun": "1.0.9",
35
35
  "@types/bun": "1.4.0",
36
36
  "@typescript/native-preview": "7.0.0-dev.20251207.1",
@@ -40,7 +40,7 @@
40
40
  "@aws-sdk/credential-providers": "3.1057.0",
41
41
  "@smithy/eventstream-codec": "4.2.14",
42
42
  "@smithy/util-utf8": "4.2.2",
43
- "@opencode/schema": "2.0.7",
43
+ "@opencode/schema": "2.0.9",
44
44
  "aws4fetch": "1.0.20",
45
45
  "effect": "4.0.0-rc.112",
46
46
  "google-auth-library": "10.5.0"