Răsfoiți Sursa

feat: switch xai provider to responses API (#18175)

Co-authored-by: Jaaneek <[email protected]>
Jaaneek 4 săptămâni în urmă
părinte
comite
b3d0446d13
4 a modificat fișierele cu 120 adăugiri și 1 ștergeri
  1. 1 0
      bun.lock
  2. 2 1
      package.json
  3. 9 0
      packages/opencode/src/provider/provider.ts
  4. 108 0
      patches/@ai-sdk%[email protected]

+ 1 - 0
bun.lock

@@ -586,6 +586,7 @@
   ],
   "patchedDependencies": {
     "@openrouter/[email protected]": "patches/@openrouter%[email protected]",
+    "@ai-sdk/[email protected]": "patches/@ai-sdk%[email protected]",
     "@standard-community/[email protected]": "patches/@standard-community%[email protected]",
   },
   "overrides": {

+ 2 - 1
package.json

@@ -112,6 +112,7 @@
   },
   "patchedDependencies": {
     "@standard-community/[email protected]": "patches/@standard-community%[email protected]",
-    "@openrouter/[email protected]": "patches/@openrouter%[email protected]"
+    "@openrouter/[email protected]": "patches/@openrouter%[email protected]",
+    "@ai-sdk/[email protected]": "patches/@ai-sdk%[email protected]"
   }
 }

+ 9 - 0
packages/opencode/src/provider/provider.ts

@@ -184,6 +184,15 @@ export namespace Provider {
         options: {},
       }
     },
+    xai: async () => {
+      return {
+        autoload: false,
+        async getModel(sdk: any, modelID: string, _options?: Record<string, any>) {
+          return sdk.responses(modelID)
+        },
+        options: {},
+      }
+    },
     "github-copilot": async () => {
       return {
         autoload: false,

+ 108 - 0
patches/@ai-sdk%[email protected]

@@ -0,0 +1,108 @@
+diff --git a/dist/index.mjs b/dist/index.mjs
+--- a/dist/index.mjs
++++ b/dist/index.mjs
+@@ -959,7 +959,7 @@
+   model: z4.string().nullish(),
+   object: z4.literal("response"),
+   output: z4.array(outputItemSchema),
+-  usage: xaiResponsesUsageSchema,
++  usage: xaiResponsesUsageSchema.nullish(),
+   status: z4.string()
+ });
+ var xaiResponsesChunkSchema = z4.union([
+\ No newline at end of file
+@@ -1143,6 +1143,18 @@
+   z4.object({
+     type: z4.literal("response.completed"),
+     response: xaiResponsesResponseSchema
++  }),
++  z4.object({
++    type: z4.literal("response.function_call_arguments.delta"),
++    item_id: z4.string(),
++    output_index: z4.number(),
++    delta: z4.string()
++  }),
++  z4.object({
++    type: z4.literal("response.function_call_arguments.done"),
++    item_id: z4.string(),
++    output_index: z4.number(),
++    arguments: z4.string()
+   })
+ ]);
+ 
+\ No newline at end of file
+@@ -1940,6 +1952,9 @@
+               if (response2.status) {
+                 finishReason = mapXaiResponsesFinishReason(response2.status);
+               }
++              if (seenToolCalls.size > 0 && finishReason !== "tool-calls") {
++                finishReason = "tool-calls";
++              }
+               return;
+             }
+             if (event.type === "response.output_item.added" || event.type === "response.output_item.done") {
+\ No newline at end of file
+@@ -2024,7 +2039,7 @@
+                   }
+                 }
+               } else if (part.type === "function_call") {
+-                if (!seenToolCalls.has(part.call_id)) {
++                if (event.type === "response.output_item.done" && !seenToolCalls.has(part.call_id)) {
+                   seenToolCalls.add(part.call_id);
+                   controller.enqueue({
+                     type: "tool-input-start",
+\ No newline at end of file
+diff --git a/dist/index.js b/dist/index.js
+--- a/dist/index.js
++++ b/dist/index.js
+@@ -964,7 +964,7 @@
+   model: import_v44.z.string().nullish(),
+   object: import_v44.z.literal("response"),
+   output: import_v44.z.array(outputItemSchema),
+-  usage: xaiResponsesUsageSchema,
++  usage: xaiResponsesUsageSchema.nullish(),
+   status: import_v44.z.string()
+ });
+ var xaiResponsesChunkSchema = import_v44.z.union([
+\ No newline at end of file
+@@ -1148,6 +1148,18 @@
+   import_v44.z.object({
+     type: import_v44.z.literal("response.completed"),
+     response: xaiResponsesResponseSchema
++  }),
++  import_v44.z.object({
++    type: import_v44.z.literal("response.function_call_arguments.delta"),
++    item_id: import_v44.z.string(),
++    output_index: import_v44.z.number(),
++    delta: import_v44.z.string()
++  }),
++  import_v44.z.object({
++    type: import_v44.z.literal("response.function_call_arguments.done"),
++    item_id: import_v44.z.string(),
++    output_index: import_v44.z.number(),
++    arguments: import_v44.z.string()
+   })
+ ]);
+ 
+\ No newline at end of file
+@@ -1935,6 +1947,9 @@
+               if (response2.status) {
+                 finishReason = mapXaiResponsesFinishReason(response2.status);
+               }
++              if (seenToolCalls.size > 0 && finishReason !== "tool-calls") {
++                finishReason = "tool-calls";
++              }
+               return;
+             }
+             if (event.type === "response.output_item.added" || event.type === "response.output_item.done") {
+\ No newline at end of file
+@@ -2019,7 +2034,7 @@
+                   }
+                 }
+               } else if (part.type === "function_call") {
+-                if (!seenToolCalls.has(part.call_id)) {
++                if (event.type === "response.output_item.done" && !seenToolCalls.has(part.call_id)) {
+                   seenToolCalls.add(part.call_id);
+                   controller.enqueue({
+                     type: "tool-input-start",
+\ No newline at end of file