fix(copilot): honor advertised model endpoints (#34958)
This commit is contained in:
@@ -1,19 +1,11 @@
|
||||
import { Effect } from "effect"
|
||||
import { ModelV2 } from "../../model"
|
||||
import { define } from "../internal"
|
||||
import { ProviderV2 } from "../../provider"
|
||||
import type { PluginContext } from "@opencode-ai/plugin/v2/effect"
|
||||
|
||||
function shouldUseResponses(modelID: string) {
|
||||
// Copilot supports Responses for GPT-5 class models, except mini variants
|
||||
// which still need the chat-completions endpoint.
|
||||
const match = /^gpt-(\d+)/.exec(modelID)
|
||||
if (!match) return false
|
||||
return Number(match[1]) >= 5 && !modelID.startsWith("gpt-5-mini")
|
||||
}
|
||||
|
||||
export const GithubCopilotPlugin = define({
|
||||
export const GithubCopilotPlugin = {
|
||||
id: "github-copilot",
|
||||
effect: Effect.fn(function* (ctx) {
|
||||
effect: Effect.fn(function* (ctx: PluginContext) {
|
||||
yield* ctx.catalog.transform(
|
||||
Effect.fn(function* (evt) {
|
||||
const item = evt.provider.get(ProviderV2.ID.githubCopilot)
|
||||
@@ -39,10 +31,22 @@ export const GithubCopilotPlugin = define({
|
||||
evt.language = evt.sdk.languageModel(evt.model.api.id)
|
||||
return
|
||||
}
|
||||
evt.language = shouldUseResponses(evt.model.api.id)
|
||||
? evt.sdk.responses(evt.model.api.id)
|
||||
: evt.sdk.chat(evt.model.api.id)
|
||||
if (evt.options.endpoint === "responses" && evt.sdk.responses) {
|
||||
evt.language = evt.sdk.responses(evt.model.api.id)
|
||||
return
|
||||
}
|
||||
if (evt.options.endpoint === "chat" && evt.sdk.chat) {
|
||||
evt.language = evt.sdk.chat(evt.model.api.id)
|
||||
return
|
||||
}
|
||||
const match = /^gpt-(\d+)/.exec(evt.model.api.id)
|
||||
// Copilot supports Responses for GPT-5 class models, except mini variants
|
||||
// which still need the chat-completions endpoint.
|
||||
evt.language =
|
||||
match && Number(match[1]) >= 5 && !evt.model.api.id.startsWith("gpt-5-mini") && evt.sdk.responses
|
||||
? evt.sdk.responses(evt.model.api.id)
|
||||
: evt.sdk.chat(evt.model.api.id)
|
||||
}),
|
||||
)
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -157,6 +157,42 @@ describe("GithubCopilotPlugin", () => {
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("uses advertised Copilot endpoint metadata before model ID fallbacks", () =>
|
||||
Effect.gen(function* () {
|
||||
const plugin = yield* PluginV2.Service
|
||||
const aisdk = yield* AISDK.Service
|
||||
const calls: string[] = []
|
||||
yield* addPlugin()
|
||||
yield* aisdk.runLanguage({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("mai-code-1-flash-picker")),
|
||||
api: {
|
||||
id: ModelV2.ID.make("mai-code-1-flash-picker"),
|
||||
type: "aisdk",
|
||||
package: "test-provider",
|
||||
settings: { endpoint: "responses" },
|
||||
},
|
||||
}),
|
||||
sdk: fakeSelectorSdk(calls),
|
||||
options: { endpoint: "responses" },
|
||||
})
|
||||
yield* aisdk.runLanguage({
|
||||
model: ModelV2.Info.make({
|
||||
...ModelV2.Info.empty(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("gpt-5")),
|
||||
api: {
|
||||
id: ModelV2.ID.make("gpt-5"),
|
||||
type: "aisdk",
|
||||
package: "test-provider",
|
||||
settings: { endpoint: "chat" },
|
||||
},
|
||||
}),
|
||||
sdk: fakeSelectorSdk(calls),
|
||||
options: { endpoint: "chat" },
|
||||
})
|
||||
expect(calls).toEqual(["responses:mai-code-1-flash-picker", "chat:gpt-5"])
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("uses the API model ID when selecting responses or chat", () =>
|
||||
Effect.gen(function* () {
|
||||
const plugin = yield* PluginV2.Service
|
||||
|
||||
Reference in New Issue
Block a user