@opencode/ai 0.0.0-dev-19708 → 0.0.0-dev-19710

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.
@@ -38,7 +38,15 @@ export const isContextOverflowFailure = (failure) => failure instanceof AIError
38
38
  ? failure.reason._tag === "InvalidRequest" && failure.reason.classification === "context-overflow"
39
39
  : Schema.is(ProviderErrorEvent)(failure) && failure.classification === "context-overflow";
40
40
  const decodeJson = Schema.decodeUnknownOption(Schema.fromJsonString(Schema.Unknown));
41
- const QUOTA_CODES = new Set(["insufficient_quota", "usage_not_included", "billing_error"]);
41
+ // OpenCode Zen reports account caps as typed 429/402 errors that are not throttles.
42
+ const QUOTA_CODES = new Set([
43
+ "insufficient_quota",
44
+ "usage_not_included",
45
+ "billing_error",
46
+ "gousagelimiterror",
47
+ "freeusagelimiterror",
48
+ "creditlimitexceeded",
49
+ ]);
42
50
  const AUTH_CODES = new Set(["authentication_error", "permission_error"]);
43
51
  const SERVER_CODES = new Set([
44
52
  "api_error",
@@ -66,7 +74,8 @@ const CONTENT_POLICY_CODES = new Set([
66
74
  // as a `[code]` label at the start of the rewritten message.
67
75
  const GATEWAY_CODE_LABEL = /^[^:\n]+: \[([A-Za-z0-9_.-]+)\]/;
68
76
  const RATE_LIMIT_TEXT = /rate increased too quickly|rate[-_\s]?limit|too[_\s]?many[_\s]?requests/i;
69
- const QUOTA_TEXT = /insufficient[-_\s]?quota|quota[-_\s]?exceeded/i;
77
+ // Only consulted on 429, where throttles and account caps share a status.
78
+ const QUOTA_TEXT = /insufficient[-_\s]?quota|quota[-_\s]?exceeded|budget exceeded|usage limit/i;
70
79
  // Policy rejections without a dedicated code, matched against the provider's own
71
80
  // explanation only. OpenAI reuses `invalid_prompt` for usage-policy rejections while
72
81
  // Bedrock Mantle reuses it for schema validation; Anthropic reports blocked output
@@ -102,7 +111,9 @@ export function classifyProviderFailure(input) {
102
111
  return new InvalidRequestError({ ...details, classification: "payload-too-large" });
103
112
  if (codes.some((code) => CONTENT_POLICY_CODES.has(code)) || (clientScoped && CONTENT_POLICY_TEXT.test(input.message)))
104
113
  return new ContentPolicyError(details);
105
- if (codes.some((code) => QUOTA_CODES.has(code)) || (input.status === 429 && QUOTA_TEXT.test(text)))
114
+ if (input.status === 402 ||
115
+ codes.some((code) => QUOTA_CODES.has(code)) ||
116
+ (input.status === 429 && QUOTA_TEXT.test(text)))
106
117
  return new QuotaExceededError(details);
107
118
  if (input.status === 401 || input.status === 403 || codes.some((code) => AUTH_CODES.has(code)))
108
119
  return new AuthenticationError(details);
@@ -117,10 +128,12 @@ export function classifyProviderFailure(input) {
117
128
  if (input.status === 408 ||
118
129
  input.status === 409 ||
119
130
  (input.status !== undefined && input.status >= 500) ||
131
+ // Server codes and phrasing only decide when no HTTP status contradicts them:
132
+ // gateways such as OpenCode Zen substitute `server_error` for codes they do
133
+ // not forward, so a 4xx with a server code is still a rejected request.
120
134
  ((input.status === undefined || input.status < 400) &&
121
- !codes.some((code) => INVALID_REQUEST_CODES.has(code)) &&
122
- SERVER_ERROR_TEXT.test(text)) ||
123
- codes.some((code) => SERVER_CODES.has(code) || code.includes("exhausted") || code.includes("unavailable")))
135
+ ((!codes.some((code) => INVALID_REQUEST_CODES.has(code)) && SERVER_ERROR_TEXT.test(text)) ||
136
+ codes.some((code) => SERVER_CODES.has(code) || code.includes("exhausted") || code.includes("unavailable")))))
124
137
  return new ProviderInternalError({
125
138
  ...details,
126
139
  retryAfterMs: input.retryAfterMs,
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-19708",
3
+ "version": "0.0.0-dev-19710",
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": "0.0.0-dev-19708",
33
+ "@opencode/http-recorder": "0.0.0-dev-19710",
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": "0.0.0-dev-19708",
43
+ "@opencode/schema": "0.0.0-dev-19710",
44
44
  "aws4fetch": "1.0.20",
45
45
  "effect": "4.0.0-rc.112",
46
46
  "google-auth-library": "10.5.0"