fix(core): preserve model request semantics (#30990)

This commit is contained in:
Kit Langton 2026-06-05 14:23:31 -04:00 committed by GitHub
commit 0bdd9aa494
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 525 additions and 48 deletions

View file

@ -479,7 +479,22 @@ describe("Config", () => {
npm: "@ai-sdk/openai",
options: { apiKey: "secret", organization: "org" },
models: {
model: { options: { reasoningEffort: "high", serviceTier: "priority" } },
model: {
options: { temperature: 0.3, reasoningEffort: "high", serviceTier: "priority" },
variants: { high: { reasoningEffort: "high", reasoningSummary: "auto" } },
},
},
},
anthropic: {
npm: "@ai-sdk/anthropic",
models: {
model: {
options: {
effort: "high",
taskBudget: 4096,
metadata: { userId: "user-1" },
},
},
},
},
},
@ -537,7 +552,26 @@ describe("Config", () => {
expect(documents[0]?.info.providers?.openai).toMatchObject({
api: { settings: {} },
request: { headers: { Authorization: "Bearer secret", "OpenAI-Organization": "org" } },
models: { model: { request: { body: { reasoning_effort: "high", service_tier: "priority" } } } },
models: {
model: {
request: {
body: { temperature: 0.3, reasoningEffort: "high", serviceTier: "priority" },
},
variants: [{ id: "high", body: { reasoningEffort: "high", reasoningSummary: "auto" } }],
},
},
})
expect(documents[0]?.info.providers?.anthropic).toMatchObject({
models: {
model: {
request: {
body: {
output_config: { effort: "high", task_budget: 4096 },
metadata: { user_id: "user-1" },
},
},
},
},
})
expect(documents[0]?.info.compaction).toEqual({
auto: true,

View file

@ -18,6 +18,118 @@ function request(headers: Record<string, string>, variant?: string) {
const decode = Schema.decodeUnknownSync(Config.Info)
describe("ConfigProviderPlugin.Plugin", () => {
it.effect("partitions existing model variant bodies without changing config shape", () =>
Effect.gen(function* () {
const catalog = yield* Catalog.Service
const plugin = yield* PluginV2.Service
const providerID = ProviderV2.ID.opencode
const modelID = ModelV2.ID.make("alpha-gpt-next")
const config = Config.Service.of({
entries: () =>
Effect.succeed([
new Config.Document({
type: "document",
info: decode({
providers: {
opencode: {
api: { type: "aisdk", package: "@ai-sdk/openai", url: "https://opencode.test/v1" },
models: {
"alpha-gpt-next": {
variants: [
{
id: "high",
body: {
reasoningEffort: "high",
reasoningSummary: "auto",
include: ["reasoning.encrypted_content"],
},
},
],
},
},
},
},
}),
}),
]),
})
yield* plugin.add({
...ConfigProviderPlugin.Plugin,
effect: ConfigProviderPlugin.Plugin.effect.pipe(
Effect.provideService(Config.Service, config),
Effect.provideService(Catalog.Service, catalog),
),
})
const model = yield* catalog.model.get(providerID, modelID)
expect(model.variants).toMatchObject([
{
id: "high",
body: {},
options: {
reasoningEffort: "high",
reasoningSummary: "auto",
include: ["reasoning.encrypted_content"],
},
},
])
}),
)
it.effect("uses the effective provider package across layered config", () =>
Effect.gen(function* () {
const catalog = yield* Catalog.Service
const plugin = yield* PluginV2.Service
const providerID = ProviderV2.ID.opencode
const modelID = ModelV2.ID.make("alpha-gpt-next")
const config = Config.Service.of({
entries: () =>
Effect.succeed([
new Config.Document({
type: "document",
info: decode({
providers: {
opencode: {
api: { type: "aisdk", package: "@ai-sdk/openai", url: "https://opencode.test/v1" },
},
},
}),
}),
new Config.Document({
type: "document",
info: decode({
providers: {
opencode: {
models: {
"alpha-gpt-next": {
variants: [{ id: "high", body: { reasoningEffort: "high" } }],
},
},
},
},
}),
}),
]),
})
yield* plugin.add({
...ConfigProviderPlugin.Plugin,
effect: ConfigProviderPlugin.Plugin.effect.pipe(
Effect.provideService(Config.Service, config),
Effect.provideService(Catalog.Service, catalog),
),
})
const model = yield* catalog.model.get(providerID, modelID)
expect(model.variants[0]).toMatchObject({
id: "high",
body: {},
options: { reasoningEffort: "high" },
})
}),
)
it.effect("loads configured providers and applies later model overrides", () =>
Effect.gen(function* () {
const catalog = yield* Catalog.Service