@opencode-ai/ai 0.0.0-dev-18660 → 0.0.0-dev-18663

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.
@@ -643,7 +643,12 @@ const mapFinishReason = Effect.fn("OpenAIChat.mapFinishReason")(function* (event
643
643
  case "tool_calls":
644
644
  return "tool-calls";
645
645
  default:
646
- return "unknown";
646
+ return yield* new AIError({
647
+ reason: new UnknownProviderError({
648
+ message: `Provider finish_reason: ${reason}`,
649
+ body: ProviderShared.encodeJson(event),
650
+ }),
651
+ });
647
652
  }
648
653
  });
649
654
  // OpenAI Chat reports `prompt_tokens` (inclusive total) with a
@@ -846,15 +851,15 @@ const step = (state, event) => Effect.gen(function* () {
846
851
  lifecycle = Lifecycle.stepStart(lifecycle, events);
847
852
  events.push(...result.events);
848
853
  }
849
- const contentFiltered = finishReason?.normalized === "content-filter";
854
+ const incompleteTools = finishReason?.normalized === "content-filter" || finishReason?.normalized === "length";
850
855
  if (finishReason !== undefined &&
851
- !contentFiltered &&
856
+ !incompleteTools &&
852
857
  state.finishReason === undefined &&
853
858
  Object.keys(pendingTools).length)
854
859
  return yield* ProviderShared.eventError(ADAPTER, "OpenAI Chat tool call delta is missing id or name", ProviderShared.encodeJson(event));
855
- // A content filter terminates the response without confirming pending tool calls.
860
+ // Filtering or truncation terminates the response without confirming pending tool calls.
856
861
  const finished = finishReason !== undefined &&
857
- !contentFiltered &&
862
+ !incompleteTools &&
858
863
  state.finishReason === undefined &&
859
864
  Object.keys(tools).length > 0
860
865
  ? yield* ToolStream.finishAll(ADAPTER, tools)
@@ -55,6 +55,7 @@ const INVALID_REQUEST_CODES = new Set(["invalid_prompt", "invalid_request_error"
55
55
  const RATE_LIMIT_TEXT = /rate increased too quickly|rate[-_\s]?limit|too[_\s]?many[_\s]?requests/i;
56
56
  const QUOTA_TEXT = /insufficient[-_\s]?quota|quota[-_\s]?exceeded/i;
57
57
  const CONTENT_POLICY_TEXT = /content[-_\s]?policy|content_filter|safety/i;
58
+ const SERVER_ERROR_TEXT = /\b(?:try again|(?:please |you can )?retry (?:the |this |your )?request|try (?:the |this |your )?request again|(?:currently |temporarily )?at capacity|overloaded|temporarily unavailable|service[-_\s]?unavailable|(?:server|internal)[-_\s]?error|server (?:is )?busy|provider returned (?:an )?error|resource[-_\s]?exhausted|upstream (?:connect|connection|request)|request buffer limit while retrying upstream)\b/i;
58
59
  // Classification records affirmative evidence about a failure. Deterministic
59
60
  // failures need positive identification (a 4xx status, quota/auth/policy
60
61
  // signals); anything unrecognized stays UnknownProvider, which the session
@@ -94,6 +95,9 @@ export function classifyProviderFailure(input) {
94
95
  if (input.status === 408 ||
95
96
  input.status === 409 ||
96
97
  (input.status !== undefined && input.status >= 500) ||
98
+ ((input.status === undefined || input.status < 400) &&
99
+ !codes.some((code) => INVALID_REQUEST_CODES.has(code)) &&
100
+ SERVER_ERROR_TEXT.test(text)) ||
97
101
  codes.some((code) => SERVER_CODES.has(code) || code.includes("exhausted") || code.includes("unavailable")))
98
102
  return new ProviderInternalError({
99
103
  ...details,
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-18660",
3
+ "version": "0.0.0-dev-18663",
4
4
  "name": "@opencode-ai/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-ai/http-recorder": "0.0.0-dev-18660",
33
+ "@opencode-ai/http-recorder": "0.0.0-dev-18663",
34
34
  "@tsconfig/bun": "1.0.9",
35
35
  "@types/bun": "1.3.13",
36
36
  "@typescript/native-preview": "7.0.0-dev.20251207.1",
@@ -39,7 +39,7 @@
39
39
  "dependencies": {
40
40
  "@smithy/eventstream-codec": "4.2.14",
41
41
  "@smithy/util-utf8": "4.2.2",
42
- "@opencode-ai/schema": "0.0.0-dev-18660",
42
+ "@opencode-ai/schema": "0.0.0-dev-18663",
43
43
  "aws4fetch": "1.0.20",
44
44
  "effect": "4.0.0-rc.112",
45
45
  "google-auth-library": "10.5.0"