@opencode/ai 0.0.0-dev-20541 → 0.0.0-dev-20543

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.
@@ -40,6 +40,7 @@ const RESPECTS_INLINE_HINTS = new Set([
40
40
  "alibaba-messages",
41
41
  "anthropic-messages",
42
42
  "anthropic-compatible-messages",
43
+ "bedrock-mantle-messages",
43
44
  "cloudflare-ai-gateway-messages",
44
45
  "google-vertex-messages",
45
46
  "meta-messages",
@@ -850,6 +850,9 @@ const lowerMessages = Effect.fnUntraced(function* (request, breakpoints) {
850
850
  }
851
851
  return messages;
852
852
  });
853
+ // TODO: Move per-model capability heuristics (`supportsEffortUpdates`, `supportsNativeSystemUpdates`,
854
+ // `supportsThinkingBlockBinding`) into explicit model/provider `compatibility` metadata so the protocol
855
+ // only reads `request.model.compatibility`.
853
856
  // Per-turn effort started with Claude Opus 5 and every Claude 5.1 model; later versions of any family inherit it.
854
857
  const supportsEffortUpdates = (model) => {
855
858
  const override = model.compatibility?.supportsEffortUpdates;
@@ -0,0 +1,2 @@
1
+ export { messagesModel as model } from "../../amazon-bedrock-mantle.js";
2
+ export type { MessagesSettings as Settings } from "../../amazon-bedrock-mantle.js";
@@ -0,0 +1 @@
1
+ export { messagesModel as model } from "../../amazon-bedrock-mantle.js";
@@ -1,10 +1,13 @@
1
1
  import { Route, type RouteDefaultsInput } from "../route/client.js";
2
2
  import type { ProviderPackage } from "../provider-package.js";
3
+ import { AnthropicMessages } from "../protocols/anthropic-messages.js";
3
4
  import { type Credentials } from "../protocols/utils/bedrock-auth.js";
4
5
  import { type ModelID } from "../schema/index.js";
5
6
  import { type OpenAIProviderOptionsInput } from "./openai-options.js";
6
7
  export declare const id: string & import("effect/Brand").Brand<"AI.ProviderID">;
7
- export type Config = RouteDefaultsInput & {
8
+ export type OpenAIOptionsInput = OpenAIProviderOptionsInput;
9
+ export type MessagesOptionsInput = AnthropicMessages.ProviderOptionsInput;
10
+ export type Config = Omit<RouteDefaultsInput, "providerOptions"> & {
8
11
  /** Bedrock API key. Falls back to `AWS_BEARER_TOKEN_BEDROCK`; bearer auth takes precedence over SigV4. */
9
12
  readonly apiKey?: string;
10
13
  /** `sigv4` ignores `apiKey` fallbacks from the environment; `bearer` requires a token. */
@@ -15,9 +18,9 @@ export type Config = RouteDefaultsInput & {
15
18
  /** Shared config profile for the default credential chain. */
16
19
  readonly profile?: string;
17
20
  readonly region?: string;
18
- readonly providerOptions?: OpenAIProviderOptionsInput;
21
+ readonly providerOptions?: OpenAIProviderOptionsInput | AnthropicMessages.ProviderOptionsInput;
19
22
  };
20
- export type Settings = ProviderPackage.Settings & OpenAIProviderOptionsInput & {
23
+ export type Settings<Options = OpenAIProviderOptionsInput> = ProviderPackage.Settings & Options & {
21
24
  readonly apiKey?: string;
22
25
  readonly auth?: "bearer" | "sigv4";
23
26
  readonly baseURL?: string;
@@ -26,7 +29,280 @@ export type Settings = ProviderPackage.Settings & OpenAIProviderOptionsInput & {
26
29
  readonly region?: string;
27
30
  readonly topP?: number;
28
31
  };
32
+ export type MessagesSettings = Settings<AnthropicMessages.ProviderOptionsInput>;
29
33
  export declare const routes: (Route<{
34
+ readonly max_tokens: number;
35
+ readonly model: string;
36
+ readonly messages: readonly ({
37
+ readonly role: "user";
38
+ readonly content: readonly ({
39
+ readonly type: "text";
40
+ readonly text: string;
41
+ readonly cache_control?: {
42
+ readonly type: "ephemeral";
43
+ readonly ttl?: "1h" | "5m" | undefined;
44
+ } | undefined;
45
+ } | {
46
+ readonly type: "image";
47
+ readonly source: {
48
+ readonly type: "base64";
49
+ readonly media_type: string;
50
+ readonly data: string;
51
+ } | {
52
+ readonly type: "url";
53
+ readonly url: string;
54
+ } | {
55
+ readonly type: "file";
56
+ readonly file_id: string;
57
+ };
58
+ readonly cache_control?: {
59
+ readonly type: "ephemeral";
60
+ readonly ttl?: "1h" | "5m" | undefined;
61
+ } | undefined;
62
+ readonly transformations?: {
63
+ readonly oversized_image?: "error" | "downsize" | undefined;
64
+ } | undefined;
65
+ } | {
66
+ readonly type: "document";
67
+ readonly source: {
68
+ readonly type: "base64";
69
+ readonly media_type: "application/pdf";
70
+ readonly data: string;
71
+ } | {
72
+ readonly type: "text";
73
+ readonly media_type: "text/plain";
74
+ readonly data: string;
75
+ } | {
76
+ readonly type: "url";
77
+ readonly url: string;
78
+ } | {
79
+ readonly type: "file";
80
+ readonly file_id: string;
81
+ };
82
+ readonly title?: string | undefined;
83
+ readonly context?: string | undefined;
84
+ readonly cache_control?: {
85
+ readonly type: "ephemeral";
86
+ readonly ttl?: "1h" | "5m" | undefined;
87
+ } | undefined;
88
+ readonly citations?: {
89
+ readonly enabled: boolean;
90
+ } | undefined;
91
+ } | {
92
+ readonly type: "tool_result";
93
+ readonly content: string | readonly ({
94
+ readonly type: "text";
95
+ readonly text: string;
96
+ readonly cache_control?: {
97
+ readonly type: "ephemeral";
98
+ readonly ttl?: "1h" | "5m" | undefined;
99
+ } | undefined;
100
+ } | {
101
+ readonly type: "image";
102
+ readonly source: {
103
+ readonly type: "base64";
104
+ readonly media_type: string;
105
+ readonly data: string;
106
+ } | {
107
+ readonly type: "url";
108
+ readonly url: string;
109
+ } | {
110
+ readonly type: "file";
111
+ readonly file_id: string;
112
+ };
113
+ readonly cache_control?: {
114
+ readonly type: "ephemeral";
115
+ readonly ttl?: "1h" | "5m" | undefined;
116
+ } | undefined;
117
+ readonly transformations?: {
118
+ readonly oversized_image?: "error" | "downsize" | undefined;
119
+ } | undefined;
120
+ } | {
121
+ readonly type: "document";
122
+ readonly source: {
123
+ readonly type: "base64";
124
+ readonly media_type: "application/pdf";
125
+ readonly data: string;
126
+ } | {
127
+ readonly type: "text";
128
+ readonly media_type: "text/plain";
129
+ readonly data: string;
130
+ } | {
131
+ readonly type: "url";
132
+ readonly url: string;
133
+ } | {
134
+ readonly type: "file";
135
+ readonly file_id: string;
136
+ };
137
+ readonly title?: string | undefined;
138
+ readonly context?: string | undefined;
139
+ readonly cache_control?: {
140
+ readonly type: "ephemeral";
141
+ readonly ttl?: "1h" | "5m" | undefined;
142
+ } | undefined;
143
+ readonly citations?: {
144
+ readonly enabled: boolean;
145
+ } | undefined;
146
+ })[];
147
+ readonly tool_use_id: string;
148
+ readonly cache_control?: {
149
+ readonly type: "ephemeral";
150
+ readonly ttl?: "1h" | "5m" | undefined;
151
+ } | undefined;
152
+ readonly is_error?: boolean | undefined;
153
+ })[];
154
+ } | {
155
+ readonly role: "assistant";
156
+ readonly content: readonly ({
157
+ readonly type: "text";
158
+ readonly text: string;
159
+ readonly cache_control?: {
160
+ readonly type: "ephemeral";
161
+ readonly ttl?: "1h" | "5m" | undefined;
162
+ } | undefined;
163
+ } | {
164
+ readonly id: string;
165
+ readonly type: "tool_use";
166
+ readonly name: string;
167
+ readonly input: unknown;
168
+ readonly cache_control?: {
169
+ readonly type: "ephemeral";
170
+ readonly ttl?: "1h" | "5m" | undefined;
171
+ } | undefined;
172
+ } | {
173
+ readonly id: string;
174
+ readonly type: "server_tool_use";
175
+ readonly name: string;
176
+ readonly input: unknown;
177
+ readonly cache_control?: {
178
+ readonly type: "ephemeral";
179
+ readonly ttl?: "1h" | "5m" | undefined;
180
+ } | undefined;
181
+ } | {
182
+ readonly type: "web_search_tool_result" | "code_execution_tool_result" | "web_fetch_tool_result";
183
+ readonly content: unknown;
184
+ readonly tool_use_id: string;
185
+ readonly cache_control?: {
186
+ readonly type: "ephemeral";
187
+ readonly ttl?: "1h" | "5m" | undefined;
188
+ } | undefined;
189
+ } | {
190
+ readonly type: "thinking";
191
+ readonly thinking: string;
192
+ readonly signature: string;
193
+ readonly cache_control?: {
194
+ readonly type: "ephemeral";
195
+ readonly ttl?: "1h" | "5m" | undefined;
196
+ } | undefined;
197
+ } | {
198
+ readonly data: string;
199
+ readonly type: "redacted_thinking";
200
+ readonly cache_control?: {
201
+ readonly type: "ephemeral";
202
+ readonly ttl?: "1h" | "5m" | undefined;
203
+ } | undefined;
204
+ } | {
205
+ readonly type: "compaction";
206
+ readonly content: string | null;
207
+ })[];
208
+ } | {
209
+ readonly content: readonly {
210
+ readonly type: "text";
211
+ readonly text: string;
212
+ readonly cache_control?: {
213
+ readonly type: "ephemeral";
214
+ readonly ttl?: "1h" | "5m" | undefined;
215
+ } | undefined;
216
+ }[];
217
+ readonly role: "system";
218
+ readonly output_config?: {
219
+ readonly effort: string;
220
+ } | undefined;
221
+ })[];
222
+ readonly stream: true;
223
+ readonly metadata?: {
224
+ readonly user_id?: string | null | undefined;
225
+ } | undefined;
226
+ readonly tools?: readonly {
227
+ readonly description: string;
228
+ readonly name: string;
229
+ readonly input_schema: {
230
+ readonly [x: string]: unknown;
231
+ };
232
+ readonly cache_control?: {
233
+ readonly type: "ephemeral";
234
+ readonly ttl?: "1h" | "5m" | undefined;
235
+ } | undefined;
236
+ }[] | undefined;
237
+ readonly system?: readonly {
238
+ readonly type: "text";
239
+ readonly text: string;
240
+ readonly cache_control?: {
241
+ readonly type: "ephemeral";
242
+ readonly ttl?: "1h" | "5m" | undefined;
243
+ } | undefined;
244
+ }[] | undefined;
245
+ readonly temperature?: number | undefined;
246
+ readonly thinking?: {
247
+ readonly type: "enabled";
248
+ readonly budget_tokens: number;
249
+ readonly display?: import("../schema/options.js").OpenString<"summarized" | "omitted"> | undefined;
250
+ readonly block_binding?: {
251
+ readonly prefix_mismatch_behavior?: import("../schema/options.js").OpenString<"error" | "drop_block"> | undefined;
252
+ } | undefined;
253
+ } | {
254
+ readonly type: "adaptive";
255
+ readonly display?: import("../schema/options.js").OpenString<"summarized" | "omitted"> | undefined;
256
+ readonly block_binding?: {
257
+ readonly prefix_mismatch_behavior?: import("../schema/options.js").OpenString<"error" | "drop_block"> | undefined;
258
+ } | undefined;
259
+ } | {
260
+ readonly type: "disabled";
261
+ } | undefined;
262
+ readonly service_tier?: import("../schema/options.js").OpenString<"auto" | "standard_only"> | undefined;
263
+ readonly container?: string | {
264
+ readonly id?: string | null | undefined;
265
+ readonly skills?: readonly {
266
+ readonly [x: string]: unknown;
267
+ }[] | null | undefined;
268
+ } | null | undefined;
269
+ readonly inference_geo?: string | null | undefined;
270
+ readonly cache_control?: {
271
+ readonly type: "ephemeral";
272
+ readonly ttl?: "1h" | "5m" | undefined;
273
+ } | undefined;
274
+ readonly output_config?: {
275
+ readonly format?: {
276
+ readonly type: "json_schema";
277
+ readonly schema: {
278
+ readonly [x: string]: unknown;
279
+ };
280
+ } | null | undefined;
281
+ readonly effort?: string | undefined;
282
+ } | undefined;
283
+ readonly context_management?: {
284
+ readonly edits: readonly {
285
+ readonly type: "compact_20260112";
286
+ readonly instructions?: string | undefined;
287
+ readonly trigger?: {
288
+ readonly type: "input_tokens";
289
+ readonly value: number;
290
+ } | undefined;
291
+ readonly pause_after_compaction?: boolean | undefined;
292
+ }[];
293
+ } | undefined;
294
+ readonly tool_choice?: {
295
+ readonly type: "auto" | "none" | "any";
296
+ readonly disable_parallel_tool_use?: boolean | undefined;
297
+ } | {
298
+ readonly type: "tool";
299
+ readonly name: string;
300
+ readonly disable_parallel_tool_use?: boolean | undefined;
301
+ } | undefined;
302
+ readonly top_p?: number | undefined;
303
+ readonly top_k?: number | undefined;
304
+ readonly stop_sequences?: readonly string[] | undefined;
305
+ }, import("../route/transport/http.js").HttpPrepared<string>, import("../route/client.js").CompactionOperations | undefined> | Route<{
30
306
  readonly model: string;
31
307
  readonly messages: readonly ({
32
308
  readonly role: "system";
@@ -329,6 +605,7 @@ export declare const configure: (input?: Config) => {
329
605
  id: string & import("effect/Brand").Brand<"AI.ProviderID">;
330
606
  model: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput, import("../route/client.js").CompactionOperations | undefined>;
331
607
  chat: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput, import("../route/client.js").CompactionOperations | undefined>;
608
+ messages: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<AnthropicMessages.OptionsInput, import("../route/client.js").CompactionOperations | undefined>;
332
609
  responses: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput, import("../route/client.js").CompactionOperations | undefined>;
333
610
  configure: (input?: Config) => /*elided*/ any;
334
611
  };
@@ -336,15 +613,18 @@ export declare const provider: {
336
613
  id: string & import("effect/Brand").Brand<"AI.ProviderID">;
337
614
  model: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput, import("../route/client.js").CompactionOperations | undefined>;
338
615
  chat: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput, import("../route/client.js").CompactionOperations | undefined>;
616
+ messages: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<AnthropicMessages.OptionsInput, import("../route/client.js").CompactionOperations | undefined>;
339
617
  responses: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput, import("../route/client.js").CompactionOperations | undefined>;
340
618
  configure: (input?: Config) => {
341
619
  id: string & import("effect/Brand").Brand<"AI.ProviderID">;
342
620
  model: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput, import("../route/client.js").CompactionOperations | undefined>;
343
621
  chat: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput, import("../route/client.js").CompactionOperations | undefined>;
622
+ messages: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<AnthropicMessages.OptionsInput, import("../route/client.js").CompactionOperations | undefined>;
344
623
  responses: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput, import("../route/client.js").CompactionOperations | undefined>;
345
624
  configure: /*elided*/ any;
346
625
  };
347
626
  };
348
627
  export declare const chatModel: ProviderPackage.Definition<Settings, OpenAIProviderOptionsInput>["model"];
628
+ export declare const messagesModel: ProviderPackage.Definition<MessagesSettings, AnthropicMessages.ProviderOptionsInput>["model"];
349
629
  export declare const responsesModel: ProviderPackage.Definition<Settings, OpenAIProviderOptionsInput>["model"];
350
- export declare const model: (modelID: string, settings: Settings) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput, import("../route/client.js").CompactionOperations | undefined>;
630
+ export declare const model: (modelID: string, settings: Settings<import("./openai-options.js").OpenAIOptionsInput>) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput, import("../route/client.js").CompactionOperations | undefined>;
@@ -1,8 +1,10 @@
1
1
  import { Route } from "../route/client.js";
2
2
  import { Endpoint } from "../route/endpoint.js";
3
+ import { AnthropicMessages } from "../protocols/anthropic-messages.js";
3
4
  import { OpenAIChat } from "../protocols/openai-chat.js";
4
5
  import { OpenResponses } from "../protocols/open-responses.js";
5
6
  import { BedrockAuth } from "../protocols/utils/bedrock-auth.js";
7
+ import { claudeVersion } from "../protocols/utils/claude-model.js";
6
8
  import { ProviderConfigurationError, ProviderID } from "../schema/index.js";
7
9
  import { withOpenAIOptions } from "./openai-options.js";
8
10
  export const id = ProviderID.make("amazon-bedrock");
@@ -20,11 +22,30 @@ const chatRoute = OpenAIChat.route.with({
20
22
  provider: id,
21
23
  providerMetadataKey: "mantle",
22
24
  });
23
- export const routes = [responsesRoute, chatRoute];
24
- const configuredRoute = (route, input) => {
25
+ const messagesRoute = Route.make({
26
+ id: "bedrock-mantle-messages",
27
+ provider: id,
28
+ providerMetadataKey: "mantle",
29
+ protocol: {
30
+ ...AnthropicMessages.protocol,
31
+ // Mantle rejects mid-conversation `output_config` on Opus 5.0; support starts at 5.1+.
32
+ supportsEffortUpdates: (request) => {
33
+ const override = request.model.compatibility?.supportsEffortUpdates;
34
+ if (override !== undefined)
35
+ return override;
36
+ const version = claudeVersion(request.model.id);
37
+ return version !== undefined && (version.major > 5 || (version.major === 5 && version.minor >= 1));
38
+ },
39
+ },
40
+ endpoint: Endpoint.path(AnthropicMessages.PATH),
41
+ transport: AnthropicMessages.transport(),
42
+ headers: () => ({ "anthropic-version": "2023-06-01" }),
43
+ });
44
+ export const routes = [responsesRoute, chatRoute, messagesRoute];
45
+ const configuredRoute = (route, input, defaultBaseURL = (region) => `https://bedrock-mantle.${region}.api.aws/v1`) => {
25
46
  const region = BedrockAuth.resolveRegion(input);
26
47
  return route.with({
27
- endpoint: { baseURL: input.baseURL ?? `https://bedrock-mantle.${region}.api.aws/v1` },
48
+ endpoint: { baseURL: input.baseURL ?? defaultBaseURL(region) },
28
49
  auth: BedrockAuth.resolveAuth(input, region, {
29
50
  service: "bedrock-mantle",
30
51
  name: "Bedrock Mantle",
@@ -46,6 +67,7 @@ export const configure = (input = {}) => {
46
67
  });
47
68
  const configuredResponsesRoute = configuredRoute(responsesRoute, input);
48
69
  const configuredChatRoute = configuredRoute(chatRoute, input);
70
+ const configuredMessagesRoute = configuredRoute(messagesRoute, input, (region) => `https://bedrock-mantle.${region}.api.aws/anthropic/v1`);
49
71
  const modelDefaults = defaults(input);
50
72
  const responses = (modelID) => configuredResponsesRoute
51
73
  .with(withOpenAIOptions(modelID, modelDefaults))
@@ -53,10 +75,12 @@ export const configure = (input = {}) => {
53
75
  const chat = (modelID) => configuredChatRoute
54
76
  .with(withOpenAIOptions(modelID, modelDefaults))
55
77
  .model({ id: modelID });
78
+ const messages = (modelID) => configuredMessagesRoute.with(modelDefaults).model({ id: modelID });
56
79
  return {
57
80
  id,
58
81
  model: responses,
59
82
  chat,
83
+ messages,
60
84
  responses,
61
85
  configure,
62
86
  };
@@ -75,5 +99,6 @@ const fromSettings = ({ apiKey, auth, baseURL, body, credentials, headers, profi
75
99
  region,
76
100
  });
77
101
  export const chatModel = (modelID, settings) => fromSettings(settings).chat(modelID);
102
+ export const messagesModel = (modelID, settings) => fromSettings(settings).messages(modelID);
78
103
  export const responsesModel = (modelID, settings) => fromSettings(settings).responses(modelID);
79
104
  export const model = responsesModel;
@@ -13,7 +13,7 @@ export type OpenAIProviderOptionsInput = OpenAIOptionsInput;
13
13
  export declare const gpt5DefaultOptions: (modelID: string) => ProviderOptions | undefined;
14
14
  export declare const openAIDefaultOptions: (modelID: string) => ProviderOptions | undefined;
15
15
  export declare const withOpenAIOptions: <Options extends {
16
- readonly providerOptions?: OpenAIProviderOptionsInput;
16
+ readonly providerOptions?: ProviderOptions;
17
17
  }>(modelID: string, options: Options) => Omit<Options, "providerOptions"> & {
18
18
  readonly providerOptions?: ProviderOptions;
19
19
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
- "version": "0.0.0-dev-20541",
3
+ "version": "0.0.0-dev-20543",
4
4
  "name": "@opencode/ai",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -34,7 +34,7 @@
34
34
  "devDependencies": {
35
35
  "@clack/prompts": "1.0.0-alpha.1",
36
36
  "@effect/platform-node": "4.0.0-rc.112",
37
- "@opencode/http-recorder": "0.0.0-dev-20541",
37
+ "@opencode/http-recorder": "0.0.0-dev-20543",
38
38
  "@tsconfig/bun": "1.0.9",
39
39
  "@types/bun": "1.4.0",
40
40
  "@typescript/native-preview": "7.0.0-dev.20251207.1",
@@ -44,7 +44,7 @@
44
44
  "@aws-sdk/credential-providers": "3.1057.0",
45
45
  "@smithy/eventstream-codec": "4.2.14",
46
46
  "@smithy/util-utf8": "4.2.2",
47
- "@opencode/schema": "0.0.0-dev-20541",
47
+ "@opencode/schema": "0.0.0-dev-20543",
48
48
  "aws4fetch": "1.0.20",
49
49
  "effect": "4.0.0-rc.112",
50
50
  "google-auth-library": "10.5.0"