@opencode/ai 0.0.0-dev-20332 → 0.0.0-dev-20334

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.
@@ -7,13 +7,20 @@ export const authEnvVars = ["CLOUDFLARE_API_TOKEN", "CF_AIG_TOKEN"];
7
7
  export const baseURL = (input) => {
8
8
  if (input.baseURL)
9
9
  return input.baseURL;
10
- if (!input.accountId)
11
- throw new ProviderConfigurationError({
12
- provider: id,
13
- message: "CloudflareAIGateway.configure requires accountId unless baseURL is supplied",
14
- });
15
- return `https://api.cloudflare.com/client/v4/accounts/${encodeURIComponent(input.accountId)}/ai/v1`;
10
+ return `https://api.cloudflare.com/client/v4/accounts/${encodeURIComponent(requireAccountId(input))}/ai/v1`;
16
11
  };
12
+ // Cloudflare's REST API rejects parts of the Anthropic Messages and OpenAI Responses request shapes, such as
13
+ // system prompt blocks and `minimal` reasoning effort, so these models use the provider-native gateway endpoints.
14
+ const passthroughURL = (input, provider) => `https://gateway.ai.cloudflare.com/v1/${encodeURIComponent(requireAccountId(input))}/${encodeURIComponent(gatewayId(input))}/${provider}`;
15
+ const requireAccountId = (input) => {
16
+ if (input.accountId)
17
+ return input.accountId;
18
+ throw new ProviderConfigurationError({
19
+ provider: id,
20
+ message: "CloudflareAIGateway.configure requires accountId unless baseURL is supplied",
21
+ });
22
+ };
23
+ const gatewayId = (input) => input.gatewayId?.trim() || "default";
17
24
  export const responsesRoute = OpenAIResponses.route.with({
18
25
  id: "cloudflare-ai-gateway-responses",
19
26
  provider: id,
@@ -30,16 +37,10 @@ export const route = OpenAIChat.route.with({
30
37
  endpoint: { baseURL: undefined },
31
38
  });
32
39
  export const routes = [responsesRoute, messagesRoute, route];
33
- const auth = (input) => {
34
- if ("auth" in input && input.auth)
35
- return input.auth;
36
- return Auth.optional(input.gatewayApiKey ?? ("apiKey" in input ? input.apiKey : undefined), "apiKey")
37
- .orElse(Auth.config(authEnvVars[0]))
38
- .orElse(Auth.config(authEnvVars[1]))
39
- .bearer();
40
- };
40
+ const credential = (input) => Auth.optional(input.gatewayApiKey ?? ("apiKey" in input ? input.apiKey : undefined), "apiKey")
41
+ .orElse(Auth.config(authEnvVars[0]))
42
+ .orElse(Auth.config(authEnvVars[1]));
41
43
  const headers = (input) => ({
42
- ...(input.gatewayId === undefined ? {} : { "cf-aig-gateway-id": input.gatewayId.trim() || "default" }),
43
44
  ...(input.metadata === undefined
44
45
  ? {}
45
46
  : { "cf-aig-metadata": Schema.encodeSync(Schema.fromJsonString(Schema.Unknown))(input.metadata) }),
@@ -49,34 +50,41 @@ const headers = (input) => ({
49
50
  ...(input.collectLog === undefined ? {} : { "cf-aig-collect-log": String(input.collectLog) }),
50
51
  ...input.headers,
51
52
  });
52
- const modelID = (input) => {
53
- const value = String(input);
54
- if (value.startsWith("workers-ai/"))
55
- return value.slice("workers-ai/".length);
56
- if (value.startsWith("anthropic/"))
57
- return `anthropic/${value.slice("anthropic/".length).replaceAll(".", "-")}`;
58
- return value;
59
- };
60
53
  export const configure = (input) => {
61
- const defaults = {
54
+ const custom = "auth" in input && input.auth ? input.auth : undefined;
55
+ const rest = {
62
56
  endpoint: { baseURL: baseURL(input) },
63
- auth: auth(input),
64
- headers: headers(input),
57
+ auth: custom ?? credential(input).bearer(),
58
+ headers: { "cf-aig-gateway-id": gatewayId(input), ...headers(input) },
65
59
  http: input.http,
66
60
  providerOptions: input.providerOptions,
67
61
  };
68
- const responses = responsesRoute.with(defaults);
69
- const messages = messagesRoute.with(defaults);
70
- const chat = route.with(defaults);
62
+ // A custom baseURL stands in for the REST API, so every model keeps using it with gateway model IDs.
63
+ const native = input.baseURL === undefined;
64
+ const passthrough = (provider) => native
65
+ ? {
66
+ ...rest,
67
+ endpoint: { baseURL: passthroughURL(input, provider) },
68
+ auth: custom ?? Auth.bearerHeader("cf-aig-authorization", credential(input)),
69
+ headers: headers(input),
70
+ }
71
+ : rest;
72
+ const responses = responsesRoute.with(passthrough("openai"));
73
+ const messages = messagesRoute.with(passthrough("anthropic/v1"));
74
+ const chat = route.with(rest);
71
75
  return {
72
76
  id,
73
77
  model: (input) => {
74
- const wire = modelID(input);
75
- if (String(input).startsWith("openai/"))
76
- return responses.model({ id: wire });
77
- if (String(input).startsWith("anthropic/"))
78
- return messages.model({ id: wire });
79
- return chat.model({ id: wire });
78
+ const value = String(input);
79
+ if (value.startsWith("openai/"))
80
+ return responses.model({ id: native ? value.slice("openai/".length) : value });
81
+ if (value.startsWith("anthropic/"))
82
+ return messages.model({
83
+ id: native ? value.slice("anthropic/".length).replaceAll(".", "-") : value,
84
+ });
85
+ if (value.startsWith("workers-ai/"))
86
+ return chat.model({ id: value.slice("workers-ai/".length) });
87
+ return chat.model({ id: value });
80
88
  },
81
89
  configure,
82
90
  };
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-20332",
3
+ "version": "0.0.0-dev-20334",
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-20332",
37
+ "@opencode/http-recorder": "0.0.0-dev-20334",
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-20332",
47
+ "@opencode/schema": "0.0.0-dev-20334",
48
48
  "aws4fetch": "1.0.20",
49
49
  "effect": "4.0.0-rc.112",
50
50
  "google-auth-library": "10.5.0"