refactor(provider): flow branded ProviderID/ModelID through internal signatures (#17182)

This commit is contained in:
Kit Langton
2026-03-12 10:48:17 -04:00
committed by GitHub
parent a4f8d66a9b
commit 1cb7df7159
24 changed files with 227 additions and 205 deletions

View File

@@ -35,7 +35,7 @@ import { Hash } from "../util/hash"
import { ACPSessionManager } from "./session"
import type { ACPConfig } from "./types"
import { Provider } from "../provider/provider"
import { ProviderID } from "../provider/schema"
import { ModelID, ProviderID } from "../provider/schema"
import { Agent as AgentModule } from "../agent/agent"
import { Installation } from "@/installation"
import { MessageV2 } from "@/session/message-v2"
@@ -56,8 +56,8 @@ export namespace ACP {
async function getContextLimit(
sdk: OpencodeClient,
providerID: string,
modelID: string,
providerID: ProviderID,
modelID: ModelID,
directory: string,
): Promise<number | null> {
const providers = await sdk.config
@@ -97,7 +97,8 @@ export namespace ACP {
if (!lastAssistant) return
const msg = lastAssistant.info
const size = await getContextLimit(sdk, msg.providerID, msg.modelID, directory)
if (!msg.providerID || !msg.modelID) return
const size = await getContextLimit(sdk, ProviderID.make(msg.providerID), ModelID.make(msg.modelID), directory)
if (!size) {
// Cannot calculate usage without known context size
@@ -637,8 +638,8 @@ export namespace ACP {
if (lastUser?.role === "user") {
result.models.currentModelId = `${lastUser.model.providerID}/${lastUser.model.modelID}`
this.sessionManager.setModel(sessionId, {
providerID: lastUser.model.providerID,
modelID: lastUser.model.modelID,
providerID: ProviderID.make(lastUser.model.providerID),
modelID: ModelID.make(lastUser.model.modelID),
})
if (result.modes?.availableModes.some((m) => m.id === lastUser.agent)) {
result.modes.currentModeId = lastUser.agent
@@ -1526,7 +1527,7 @@ export namespace ACP {
}
}
async function defaultModel(config: ACPConfig, cwd?: string) {
async function defaultModel(config: ACPConfig, cwd?: string): Promise<{ providerID: ProviderID; modelID: ModelID }> {
const sdk = config.sdk
const configured = config.defaultModel
if (configured) return configured
@@ -1538,11 +1539,7 @@ export namespace ACP {
.then((resp) => {
const cfg = resp.data
if (!cfg || !cfg.model) return undefined
const parsed = Provider.parseModel(cfg.model)
return {
providerID: parsed.providerID,
modelID: parsed.modelID,
}
return Provider.parseModel(cfg.model)
})
.catch((error) => {
log.error("failed to load user config for default model", { error })
@@ -1567,13 +1564,13 @@ export namespace ACP {
const opencodeProvider = providers.find((p) => p.id === "opencode")
if (opencodeProvider) {
if (opencodeProvider.models["big-pickle"]) {
return { providerID: "opencode", modelID: "big-pickle" }
return { providerID: ProviderID.opencode, modelID: ModelID.make("big-pickle") }
}
const [best] = Provider.sort(Object.values(opencodeProvider.models))
if (best) {
return {
providerID: best.providerID,
modelID: best.id,
providerID: ProviderID.make(best.providerID),
modelID: ModelID.make(best.id),
}
}
}
@@ -1582,14 +1579,14 @@ export namespace ACP {
const [best] = Provider.sort(models)
if (best) {
return {
providerID: best.providerID,
modelID: best.id,
providerID: ProviderID.make(best.providerID),
modelID: ModelID.make(best.id),
}
}
if (specified) return specified
return { providerID: "opencode", modelID: "big-pickle" }
return { providerID: ProviderID.opencode, modelID: ModelID.make("big-pickle") }
}
function parseUri(
@@ -1652,7 +1649,7 @@ export namespace ACP {
function modelVariantsFromProviders(
providers: Array<{ id: string; models: Record<string, { variants?: Record<string, any> }> }>,
model: { providerID: string; modelID: string },
model: { providerID: ProviderID; modelID: ModelID },
): string[] {
const provider = providers.find((entry) => entry.id === model.providerID)
if (!provider) return []
@@ -1688,7 +1685,7 @@ export namespace ACP {
}
function formatModelIdWithVariant(
model: { providerID: string; modelID: string },
model: { providerID: ProviderID; modelID: ModelID },
variant: string | undefined,
availableVariants: string[],
includeVariant: boolean,
@@ -1699,7 +1696,7 @@ export namespace ACP {
}
function buildVariantMeta(input: {
model: { providerID: string; modelID: string }
model: { providerID: ProviderID; modelID: ModelID }
variant?: string
availableVariants: string[]
}) {
@@ -1715,7 +1712,7 @@ export namespace ACP {
function parseModelSelection(
modelId: string,
providers: Array<{ id: string; models: Record<string, { variants?: Record<string, any> }> }>,
): { model: { providerID: string; modelID: string }; variant?: string } {
): { model: { providerID: ProviderID; modelID: ModelID }; variant?: string } {
const parsed = Provider.parseModel(modelId)
const provider = providers.find((p) => p.id === parsed.providerID)
if (!provider) {
@@ -1735,7 +1732,7 @@ export namespace ACP {
const baseModelInfo = provider.models[baseModelId]
if (baseModelInfo?.variants && candidateVariant in baseModelInfo.variants) {
return {
model: { providerID: parsed.providerID, modelID: baseModelId },
model: { providerID: parsed.providerID, modelID: ModelID.make(baseModelId) },
variant: candidateVariant,
}
}

View File

@@ -1,5 +1,6 @@
import type { McpServer } from "@agentclientprotocol/sdk"
import type { OpencodeClient } from "@opencode-ai/sdk/v2"
import type { ProviderID, ModelID } from "../provider/schema"
export interface ACPSessionState {
id: string
@@ -7,8 +8,8 @@ export interface ACPSessionState {
mcpServers: McpServer[]
createdAt: Date
model?: {
providerID: string
modelID: string
providerID: ProviderID
modelID: ModelID
}
variant?: string
modeId?: string
@@ -17,7 +18,7 @@ export interface ACPSessionState {
export interface ACPConfig {
sdk: OpencodeClient
defaultModel?: {
providerID: string
modelID: string
providerID: ProviderID
modelID: ModelID
}
}