fix(provider): widen interleaved reasoning fields (#39556)
Co-authored-by: Aiden Cline <rekram1-node@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
ecfff673a9
commit
ecc58c5fc2
@@ -15,6 +15,11 @@ import { httpClient } from "./effect/app-node-platform"
|
|||||||
export const CatalogModelStatus = Schema.Literals(["alpha", "beta", "deprecated"])
|
export const CatalogModelStatus = Schema.Literals(["alpha", "beta", "deprecated"])
|
||||||
export type CatalogModelStatus = typeof CatalogModelStatus.Type
|
export type CatalogModelStatus = typeof CatalogModelStatus.Type
|
||||||
|
|
||||||
|
const InterleavedField = Schema.Union([
|
||||||
|
Schema.Literals(["reasoning", "reasoning_content", "reasoning_text"]),
|
||||||
|
Schema.String,
|
||||||
|
])
|
||||||
|
|
||||||
const USER_AGENT = `opencode/${InstallationChannel}/${InstallationVersion}/${Flag.OPENCODE_CLIENT}`
|
const USER_AGENT = `opencode/${InstallationChannel}/${InstallationVersion}/${Flag.OPENCODE_CLIENT}`
|
||||||
|
|
||||||
const CostTier = Schema.Struct({
|
const CostTier = Schema.Struct({
|
||||||
@@ -71,9 +76,10 @@ export const Model = Schema.Struct({
|
|||||||
reasoning_options: Schema.optional(Schema.Array(ReasoningOption)),
|
reasoning_options: Schema.optional(Schema.Array(ReasoningOption)),
|
||||||
interleaved: Schema.optional(
|
interleaved: Schema.optional(
|
||||||
Schema.Union([
|
Schema.Union([
|
||||||
Schema.Literal(true),
|
Schema.Boolean,
|
||||||
|
InterleavedField,
|
||||||
Schema.Struct({
|
Schema.Struct({
|
||||||
field: Schema.Literals(["reasoning", "reasoning_content", "reasoning_details"]),
|
field: InterleavedField,
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -5,6 +5,11 @@ import { PositiveInt } from "../../schema"
|
|||||||
|
|
||||||
export const ModelStatus = Schema.Literals(["alpha", "beta", "deprecated", "active"])
|
export const ModelStatus = Schema.Literals(["alpha", "beta", "deprecated", "active"])
|
||||||
|
|
||||||
|
const InterleavedField = Schema.Union([
|
||||||
|
Schema.Literals(["reasoning", "reasoning_content", "reasoning_text"]),
|
||||||
|
Schema.String,
|
||||||
|
])
|
||||||
|
|
||||||
export const Model = Schema.Struct({
|
export const Model = Schema.Struct({
|
||||||
id: Schema.optional(Schema.String),
|
id: Schema.optional(Schema.String),
|
||||||
name: Schema.optional(Schema.String),
|
name: Schema.optional(Schema.String),
|
||||||
@@ -16,9 +21,10 @@ export const Model = Schema.Struct({
|
|||||||
tool_call: Schema.optional(Schema.Boolean),
|
tool_call: Schema.optional(Schema.Boolean),
|
||||||
interleaved: Schema.optional(
|
interleaved: Schema.optional(
|
||||||
Schema.Union([
|
Schema.Union([
|
||||||
Schema.Literal(true),
|
Schema.Boolean,
|
||||||
|
InterleavedField,
|
||||||
Schema.Struct({
|
Schema.Struct({
|
||||||
field: Schema.Literals(["reasoning", "reasoning_content", "reasoning_details"]),
|
field: InterleavedField,
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -976,10 +976,15 @@ const ProviderModalities = Schema.Struct({
|
|||||||
pdf: Schema.Boolean,
|
pdf: Schema.Boolean,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const ProviderInterleavedField = Schema.Union([
|
||||||
|
Schema.Literals(["reasoning", "reasoning_content", "reasoning_text"]),
|
||||||
|
Schema.String,
|
||||||
|
])
|
||||||
|
|
||||||
const ProviderInterleaved = Schema.Union([
|
const ProviderInterleaved = Schema.Union([
|
||||||
Schema.Boolean,
|
Schema.Boolean,
|
||||||
Schema.Struct({
|
Schema.Struct({
|
||||||
field: Schema.Literals(["reasoning", "reasoning_content", "reasoning_details"]),
|
field: ProviderInterleavedField,
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -1243,7 +1248,7 @@ function fromModelsDevModel(provider: ModelsDev.Provider, model: ModelsDev.Model
|
|||||||
video: model.modalities?.output?.includes("video") ?? false,
|
video: model.modalities?.output?.includes("video") ?? false,
|
||||||
pdf: model.modalities?.output?.includes("pdf") ?? false,
|
pdf: model.modalities?.output?.includes("pdf") ?? false,
|
||||||
},
|
},
|
||||||
interleaved: model.interleaved ?? false,
|
interleaved: typeof model.interleaved === "string" ? { field: model.interleaved } : (model.interleaved ?? false),
|
||||||
},
|
},
|
||||||
release_date: model.release_date ?? "",
|
release_date: model.release_date ?? "",
|
||||||
variants: {},
|
variants: {},
|
||||||
@@ -1475,7 +1480,7 @@ const layer = Layer.effect(
|
|||||||
pdf: model.modalities?.output?.includes("pdf") ?? existingModel?.capabilities.output.pdf ?? false,
|
pdf: model.modalities?.output?.includes("pdf") ?? existingModel?.capabilities.output.pdf ?? false,
|
||||||
},
|
},
|
||||||
interleaved:
|
interleaved:
|
||||||
model.interleaved ??
|
(typeof model.interleaved === "string" ? { field: model.interleaved } : model.interleaved) ??
|
||||||
existingModel?.capabilities.interleaved ??
|
existingModel?.capabilities.interleaved ??
|
||||||
(!existingModel && apiNpm === "@ai-sdk/openai-compatible" && apiID.includes("deepseek")
|
(!existingModel && apiNpm === "@ai-sdk/openai-compatible" && apiID.includes("deepseek")
|
||||||
? { field: "reasoning_content" }
|
? { field: "reasoning_content" }
|
||||||
|
|||||||
@@ -252,6 +252,8 @@ it.instance(
|
|||||||
const provider = providers[ProviderV2.ID.make("custom-provider")]
|
const provider = providers[ProviderV2.ID.make("custom-provider")]
|
||||||
expect(provider.models["deepseek-r1"].capabilities.interleaved).toEqual({ field: "reasoning_content" })
|
expect(provider.models["deepseek-r1"].capabilities.interleaved).toEqual({ field: "reasoning_content" })
|
||||||
expect(provider.models["deepseek-details"].capabilities.interleaved).toEqual({ field: "reasoning_details" })
|
expect(provider.models["deepseek-details"].capabilities.interleaved).toEqual({ field: "reasoning_details" })
|
||||||
|
expect(provider.models["deepseek-text"].capabilities.interleaved).toEqual({ field: "reasoning_text" })
|
||||||
|
expect(provider.models["custom-reasoning"].capabilities.interleaved).toEqual({ field: "vendor_reasoning" })
|
||||||
expect(provider.models["custom-model"].capabilities.interleaved).toBe(false)
|
expect(provider.models["custom-model"].capabilities.interleaved).toBe(false)
|
||||||
expect(
|
expect(
|
||||||
providers[ProviderV2.ID.make("custom-anthropic-provider")].models["deepseek-r1"].capabilities.interleaved,
|
providers[ProviderV2.ID.make("custom-anthropic-provider")].models["deepseek-r1"].capabilities.interleaved,
|
||||||
@@ -267,6 +269,8 @@ it.instance(
|
|||||||
models: {
|
models: {
|
||||||
"deepseek-r1": { name: "DeepSeek R1" },
|
"deepseek-r1": { name: "DeepSeek R1" },
|
||||||
"deepseek-details": { name: "DeepSeek Details", interleaved: { field: "reasoning_details" } },
|
"deepseek-details": { name: "DeepSeek Details", interleaved: { field: "reasoning_details" } },
|
||||||
|
"deepseek-text": { name: "DeepSeek Text", interleaved: "reasoning_text" },
|
||||||
|
"custom-reasoning": { name: "Custom Reasoning", interleaved: { field: "vendor_reasoning" } },
|
||||||
"custom-model": { name: "Custom Model" },
|
"custom-model": { name: "Custom Model" },
|
||||||
},
|
},
|
||||||
options: { apiKey: "custom-key" },
|
options: { apiKey: "custom-key" },
|
||||||
@@ -1462,6 +1466,7 @@ test("models.dev normalization fills required response fields", () => {
|
|||||||
id: "gpt-5.4",
|
id: "gpt-5.4",
|
||||||
name: "GPT-5.4",
|
name: "GPT-5.4",
|
||||||
family: "gpt",
|
family: "gpt",
|
||||||
|
interleaved: "reasoning_text",
|
||||||
cost: { input: 2.5, output: 15 },
|
cost: { input: 2.5, output: 15 },
|
||||||
limit: { context: 1_050_000, input: 922_000, output: 128_000 },
|
limit: { context: 1_050_000, input: 922_000, output: 128_000 },
|
||||||
},
|
},
|
||||||
@@ -1474,6 +1479,7 @@ test("models.dev normalization fills required response fields", () => {
|
|||||||
expect(model.capabilities.reasoning).toBe(false)
|
expect(model.capabilities.reasoning).toBe(false)
|
||||||
expect(model.capabilities.attachment).toBe(false)
|
expect(model.capabilities.attachment).toBe(false)
|
||||||
expect(model.capabilities.toolcall).toBe(true)
|
expect(model.capabilities.toolcall).toBe(true)
|
||||||
|
expect(model.capabilities.interleaved).toEqual({ field: "reasoning_text" })
|
||||||
expect(model.release_date).toBe("")
|
expect(model.release_date).toBe("")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1768,9 +1768,13 @@ export type ProviderConfig = {
|
|||||||
temperature?: boolean
|
temperature?: boolean
|
||||||
tool_call?: boolean
|
tool_call?: boolean
|
||||||
interleaved?:
|
interleaved?:
|
||||||
| true
|
| boolean
|
||||||
|
| "reasoning"
|
||||||
|
| "reasoning_content"
|
||||||
|
| "reasoning_text"
|
||||||
|
| string
|
||||||
| {
|
| {
|
||||||
field: "reasoning" | "reasoning_content" | "reasoning_details"
|
field: "reasoning" | "reasoning_content" | "reasoning_text" | string
|
||||||
}
|
}
|
||||||
cost?: {
|
cost?: {
|
||||||
input: number
|
input: number
|
||||||
@@ -2057,7 +2061,7 @@ export type Model = {
|
|||||||
interleaved:
|
interleaved:
|
||||||
| boolean
|
| boolean
|
||||||
| {
|
| {
|
||||||
field: "reasoning" | "reasoning_content" | "reasoning_details"
|
field: "reasoning" | "reasoning_content" | "reasoning_text" | string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cost: {
|
cost: {
|
||||||
|
|||||||
@@ -20820,15 +20820,28 @@
|
|||||||
"interleaved": {
|
"interleaved": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"type": "boolean",
|
"type": "boolean"
|
||||||
"enum": [true]
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["reasoning", "reasoning_content", "reasoning_text"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"field": {
|
"field": {
|
||||||
"type": "string",
|
"anyOf": [
|
||||||
"enum": ["reasoning", "reasoning_content", "reasoning_details"]
|
{
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["reasoning", "reasoning_content", "reasoning_text"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["field"],
|
"required": ["field"],
|
||||||
@@ -21641,8 +21654,15 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"field": {
|
"field": {
|
||||||
"type": "string",
|
"anyOf": [
|
||||||
"enum": ["reasoning", "reasoning_content", "reasoning_details"]
|
{
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["reasoning", "reasoning_content", "reasoning_text"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["field"],
|
"required": ["field"],
|
||||||
|
|||||||
Reference in New Issue
Block a user