Răsfoiți Sursa

fix(core): parse models.dev reasoning options (#34618)

Aiden Cline 1 lună în urmă
părinte
comite
75715e2115
2 a modificat fișierele cu 39 adăugiri și 1 ștergeri
  1. 16 0
      packages/core/src/models-dev.ts
  2. 23 1
      packages/core/test/models.test.ts

+ 16 - 0
packages/core/src/models-dev.ts

@@ -44,6 +44,21 @@ const Cost = Schema.Struct({
   ),
 })
 
+const ReasoningOption = Schema.Union([
+  Schema.Struct({
+    type: Schema.Literal("effort"),
+    values: Schema.Array(Schema.String),
+  }),
+  Schema.Struct({
+    type: Schema.Literal("toggle"),
+  }),
+  Schema.Struct({
+    type: Schema.Literal("budget_tokens"),
+    min: Schema.optional(Schema.Finite),
+    max: Schema.optional(Schema.Finite),
+  }),
+])
+
 export const Model = Schema.Struct({
   id: Schema.String,
   name: Schema.String,
@@ -51,6 +66,7 @@ export const Model = Schema.Struct({
   release_date: Schema.String,
   attachment: Schema.Boolean,
   reasoning: Schema.Boolean,
+  reasoning_options: Schema.optional(Schema.Array(ReasoningOption)),
   temperature: Schema.Boolean,
   tool_call: Schema.Boolean,
   interleaved: Schema.optional(

+ 23 - 1
packages/core/test/models.test.ts

@@ -1,5 +1,5 @@
 import { describe, expect, beforeAll, beforeEach, afterAll } from "bun:test"
-import { Effect, Layer, Ref } from "effect"
+import { Effect, Layer, Ref, Schema } from "effect"
 import { HttpClient, HttpClientResponse } from "effect/unstable/http"
 import { FSUtil } from "@opencode-ai/core/fs-util"
 import { Flag } from "@opencode-ai/core/flag/flag"
@@ -126,6 +126,28 @@ const initialState: MockState = {
 }
 
 describe("ModelsDev Service", () => {
+  it.effect("decodes known reasoning options", () =>
+    Effect.sync(() => {
+      const result = Schema.decodeUnknownSync(ModelsDev.Model)({
+        id: "reasoning-model",
+        name: "Reasoning Model",
+        release_date: "2026-01-01",
+        attachment: false,
+        reasoning: true,
+        reasoning_options: [
+          { type: "effort", values: ["low", "high"] },
+          { type: "budget_tokens", min: 1024, max: 8192 },
+          { type: "toggle" },
+        ],
+        temperature: true,
+        tool_call: true,
+        limit: { context: 128000, output: 8192 },
+      })
+
+      expect(result.reasoning_options?.map((item) => item.type)).toEqual(["effort", "budget_tokens", "toggle"])
+    }),
+  )
+
   it.live("get() returns providers from disk when cache file exists", () =>
     Effect.gen(function* () {
       yield* writeCache(fixture)