chore(opencode): suppress dead v1 model types

This commit is contained in:
Dax Raad 2026-07-09 13:14:51 -04:00
parent a2718177be
commit c91604d519
10 changed files with 54 additions and 2 deletions

View file

@ -167,6 +167,7 @@ export const githubInstall = Effect.fn("Cli.github.install")(function* () {
const providers = await Effect.runPromise(modelsDev.get()).then((p) => {
// TODO: add guide for copilot, for now just hide it
// @ts-expect-error dead V1 expects the pre-normalized ModelsDev provider record.
delete p["github-copilot"]
return p
})
@ -187,6 +188,7 @@ export const githubInstall = Effect.fn("Cli.github.install")(function* () {
step2 = [
` 2. Add the following secrets in org or repo (${app.owner}/${app.repo}) settings`,
"",
// @ts-expect-error dead V1 expects provider env fields instead of normalized snapshots.
...providers[provider].env.map((e) => ` - ${e}`),
].join("\n")
}
@ -238,12 +240,17 @@ export const githubInstall = Effect.fn("Cli.github.install")(function* () {
providers,
values(),
sortBy(
// @ts-expect-error dead V1 expects provider IDs on the ModelsDev record values.
(x) => priority[x.id] ?? 99,
// @ts-expect-error dead V1 expects provider names on the ModelsDev record values.
(x) => x.name ?? x.id,
),
map((x) => ({
// @ts-expect-error dead V1 expects provider names on the ModelsDev record values.
label: x.name,
// @ts-expect-error dead V1 expects provider IDs on the ModelsDev record values.
value: x.id,
// @ts-expect-error dead V1 expects provider IDs on the ModelsDev record values.
hint: priority[x.id] === 0 ? "recommended" : undefined,
})),
),
@ -330,6 +337,7 @@ export const githubInstall = Effect.fn("Cli.github.install")(function* () {
const envStr =
provider === "amazon-bedrock"
? ""
// @ts-expect-error dead V1 expects provider env fields instead of normalized snapshots.
: `\n env:${providers[provider].env.map((e) => `\n ${e}: \${{ secrets.${e} }}`).join("")}`
await Filesystem.write(

View file

@ -264,6 +264,7 @@ export const ProvidersListCommand = effectCmd({
const database = yield* modelsDev.get()
for (const [providerID, result] of results) {
// @ts-expect-error dead V1 indexes the normalized ModelsDev snapshot array by provider ID.
const name = database[providerID]?.name || providerID
yield* Prompt.log.info(`${name} ${UI.Style.TEXT_DIM}${result.type}`)
}
@ -273,9 +274,11 @@ export const ProvidersListCommand = effectCmd({
const activeEnvVars: Array<{ provider: string; envVar: string }> = []
for (const [providerID, provider] of Object.entries(database)) {
// @ts-expect-error dead V1 expects provider env fields instead of normalized snapshots.
for (const envVar of provider.env) {
if (process.env[envVar]) {
activeEnvVars.push({
// @ts-expect-error dead V1 expects provider names instead of normalized snapshot info.
provider: provider.name || providerID,
envVar,
})
@ -362,6 +365,7 @@ export const ProvidersLoginCommand = effectCmd({
const enabled = config.enabled_providers ? new Set(config.enabled_providers) : undefined
const allProviders = yield* modelsDev.get()
// @ts-expect-error dead V1 expects a provider-keyed record, not normalized ModelsDev snapshots.
const providers: Record<string, (typeof allProviders)[string]> = {}
for (const [key, value] of Object.entries(allProviders)) {
if ((enabled ? enabled.has(key) : true) && !disabled.has(key)) providers[key] = value
@ -395,6 +399,7 @@ export const ProvidersLoginCommand = effectCmd({
map((x) => ({
label: x.name,
value: x.id,
// @ts-expect-error dead V1 provider IDs come from pre-normalized ModelsDev records.
hint: {
opencode: "recommended",
openai: "ChatGPT Plus/Pro or API key",
@ -419,6 +424,7 @@ export const ProvidersLoginCommand = effectCmd({
}
provider = match.value
} else {
// @ts-expect-error dead V1 selection values come from pre-normalized ModelsDev records.
provider = yield* promptValue(
yield* Prompt.autocomplete({
message: "Select provider",
@ -511,6 +517,7 @@ export const ProvidersLogoutCommand = effectCmd({
}
const database = yield* modelsDev.get()
const options = credentials.map(([key, value]) => ({
// @ts-expect-error dead V1 indexes the normalized ModelsDev snapshot array by provider ID.
label: (database[key]?.name || key) + UI.Style.TEXT_DIM + " (" + value.type + ")",
value: key,
}))
@ -518,6 +525,7 @@ export const ProvidersLogoutCommand = effectCmd({
? options.find(
(option) =>
option.value === args.provider ||
// @ts-expect-error dead V1 indexes the normalized ModelsDev snapshot array by provider ID.
database[option.value]?.name?.toLowerCase() === args.provider?.toLowerCase(),
)?.value
: yield* promptValue(

View file

@ -1,5 +1,6 @@
import { Schema } from "effect"
// @ts-expect-error dead V1 retains the former value-style ModelsDev status re-export.
export { CatalogModelStatus } from "@opencode-ai/core/models-dev"
export const ModelStatus = Schema.Literals(["alpha", "beta", "deprecated", "active"])

View file

@ -1156,6 +1156,7 @@ export class Service extends Context.Service<Service, Interface>()("@opencode/Pr
export const use = serviceUse(Service)
// @ts-expect-error dead V1 consumes the removed pre-normalized ModelsDev model type.
function cost(c: ModelsDev.Model["cost"]): Model["cost"] {
const result: Model["cost"] = {
input: c?.input ?? 0,
@ -1166,6 +1167,7 @@ function cost(c: ModelsDev.Model["cost"]): Model["cost"] {
},
}
if (c?.tiers) {
// @ts-expect-error dead V1 relies on the removed ModelsDev cost tier context.
result.tiers = c.tiers.map((item) => ({
input: item.input,
output: item.output,
@ -1189,6 +1191,7 @@ function cost(c: ModelsDev.Model["cost"]): Model["cost"] {
return result
}
// @ts-expect-error dead V1 consumes removed provider and model types instead of snapshots.
function fromModelsDevModel(provider: ModelsDev.Provider, model: ModelsDev.Model): Model {
const base: Model = {
id: ModelV2.ID.make(model.id),
@ -1240,26 +1243,34 @@ function fromModelsDevModel(provider: ModelsDev.Provider, model: ModelsDev.Model
}
}
// @ts-expect-error dead V1 consumes the removed pre-normalized ModelsDev provider type.
export function fromModelsDevProvider(provider: ModelsDev.Provider): Info {
const models: Record<string, Model> = {}
for (const [key, model] of Object.entries(provider.models)) {
models[key] = fromModelsDevModel(provider, model)
// @ts-expect-error dead V1 expects raw model metadata inside a provider instead of normalized snapshots.
for (const [mode, opts] of Object.entries(model.experimental?.modes ?? {})) {
// @ts-expect-error dead V1 expects raw model IDs inside normalized ModelsDev data.
const id = `${model.id}-${mode}`
const base = fromModelsDevModel(provider, model)
models[id] = {
...base,
id: ModelV2.ID.make(id),
// @ts-expect-error dead V1 expects raw model names and mode options.
name: `${model.name} ${mode[0].toUpperCase()}${mode.slice(1)}`,
// @ts-expect-error dead V1 expects raw mode costs inside normalized ModelsDev data.
cost: opts.cost ? mergeDeep(base.cost, cost(opts.cost)) : base.cost,
// @ts-expect-error dead V1 expects raw mode provider bodies inside normalized ModelsDev data.
options: opts.provider?.body
? Object.fromEntries(
// @ts-expect-error dead V1 expects raw mode provider bodies inside normalized ModelsDev data.
Object.entries(opts.provider.body).map(([k, v]) => [
k.replace(/_([a-z])/g, (_, c) => c.toUpperCase()),
v,
]),
)
: base.options,
// @ts-expect-error dead V1 expects raw mode headers inside normalized ModelsDev data.
headers: opts.provider?.headers ?? base.headers,
}
}
@ -1344,13 +1355,13 @@ const layer = Layer.effect(
function mergeProvider(providerID: ProviderV2.ID, provider: Partial<Info>) {
const existing = providers[providerID]
if (existing) {
// @ts-expect-error
// @ts-expect-error dead V1 merges partial provider records with legacy semantics.
providers[providerID] = mergeDeep(existing, provider)
return
}
// @ts-expect-error dead V1 indexes the normalized ModelsDev snapshot array by provider ID.
const match = database[providerID]
if (!match) return
// @ts-expect-error
providers[providerID] = mergeDeep(match, provider)
}
@ -1376,6 +1387,7 @@ const layer = Layer.effect(
const providerID = ProviderV2.ID.make(p.id)
if (disabled.has(providerID)) continue
// @ts-expect-error dead V1 indexes the normalized ModelsDev snapshot array by provider ID.
const provider = database[providerID]
if (!provider) continue
const pluginAuth = yield* auth.get(providerID).pipe(Effect.orDie)
@ -1397,6 +1409,7 @@ const layer = Layer.effect(
// extend database from config
for (const [providerID, provider] of configProviders) {
// @ts-expect-error dead V1 indexes the normalized ModelsDev snapshot array by provider ID.
const existing = database[providerID]
const parsed: Info = {
id: ProviderV2.ID.make(providerID),
@ -1414,6 +1427,7 @@ const layer = Layer.effect(
model.provider?.npm ??
provider.npm ??
existingModel?.api.npm ??
// @ts-expect-error dead V1 indexes normalized ModelsDev snapshots for raw provider fields.
modelsDev[providerID]?.npm ??
"@ai-sdk/openai-compatible"
const name = iife(() => {
@ -1426,6 +1440,7 @@ const layer = Layer.effect(
api: {
id: apiID,
npm: apiNpm,
// @ts-expect-error dead V1 indexes normalized ModelsDev snapshots for raw provider fields.
url: model.provider?.api ?? provider?.api ?? existingModel?.api.url ?? modelsDev[providerID]?.api ?? "",
},
status: model.status ?? existingModel?.status ?? "active",
@ -1486,6 +1501,7 @@ const layer = Layer.effect(
)
parsed.models[modelID] = parsedModel
}
// @ts-expect-error dead V1 mutates a provider-keyed record, not normalized snapshots.
database[providerID] = parsed
}
@ -1528,6 +1544,7 @@ const layer = Layer.effect(
const options = yield* Effect.promise(() =>
plugin.auth!.loader!(
() => bridge.promise(auth.get(providerID).pipe(Effect.orDie)) as any,
// @ts-expect-error dead V1 indexes the normalized ModelsDev snapshot array by provider ID.
toPublicInfo(database[plugin.auth!.provider]),
),
)
@ -1539,6 +1556,7 @@ const layer = Layer.effect(
for (const [id, fn] of Object.entries(custom(dep))) {
const providerID = ProviderV2.ID.make(id)
if (disabled.has(providerID)) continue
// @ts-expect-error dead V1 indexes the normalized ModelsDev snapshot array by provider ID.
const data = database[providerID]
if (!data) {
continue

View file

@ -5,6 +5,7 @@ import type * as Provider from "./provider"
import type * as ModelsDev from "@opencode-ai/core/models-dev"
import { iife } from "@/util/iife"
// @ts-expect-error dead V1 consumes the removed pre-normalized ModelsDev model type.
type Modality = NonNullable<ModelsDev.Model["modalities"]>["input"][number]
function mimeToModality(mime: string): Modality | undefined {
@ -396,6 +397,7 @@ function unsupportedParts(msgs: ModelMessage[], model: Provider.Model): ModelMes
const filename = part.type === "file" ? part.filename : undefined
const modality = mimeToModality(mime)
if (!modality) return part
// @ts-expect-error dead V1 modality typing came from the removed ModelsDev model schema.
if (model.capabilities.input[modality]) return part
const name = filename ? `"${filename}"` : modality

View file

@ -42,6 +42,7 @@ export const providerHandlers = HttpApiBuilder.group(InstanceHttpApi, "provider"
const all = yield* ModelsDev.Service.use((s) => s.get())
const disabled = new Set(config.disabled_providers ?? [])
const enabled = config.enabled_providers ? new Set(config.enabled_providers) : undefined
// @ts-expect-error dead V1 expects a provider-keyed record, not normalized ModelsDev snapshots.
const filtered: Record<string, (typeof all)[string]> = {}
for (const [key, value] of Object.entries(all)) {
if ((enabled ? enabled.has(key) : true) && !disabled.has(key)) filtered[key] = value

View file

@ -1,13 +1,16 @@
import { describe, expect, test } from "bun:test"
import { Schema } from "effect"
import { ConfigProviderV1 } from "@opencode-ai/core/v1/config/provider"
// @ts-expect-error dead V1 test retains the former value-style ModelsDev status import.
import { CatalogModelStatus, ModelStatus } from "@/provider/model-status"
import { ModelsDev } from "@opencode-ai/core/models-dev"
import { Provider } from "@/provider/provider"
describe("provider model status schemas", () => {
test("keeps catalog status separate from normalized provider status", () => {
// @ts-expect-error dead V1 test treats the normalized catalog status type as a schema value.
expect(Schema.decodeUnknownSync(CatalogModelStatus)("deprecated")).toBe("deprecated")
// @ts-expect-error dead V1 test treats the normalized catalog status type as a schema value.
expect(() => Schema.decodeUnknownSync(CatalogModelStatus)("active")).toThrow()
expect(Schema.decodeUnknownSync(ModelStatus)("active")).toBe("active")
})
@ -15,6 +18,7 @@ describe("provider model status schemas", () => {
test("accepts active status across public provider schemas", () => {
expect(Schema.decodeUnknownSync(ConfigProviderV1.Model)({ status: "active" }).status).toBe("active")
expect(
// @ts-expect-error dead V1 test consumes the removed ModelsDev model schema value.
Schema.decodeUnknownSync(ModelsDev.Model)({
id: "test-model",
name: "Test Model",

View file

@ -1386,6 +1386,7 @@ test("mode cost preserves over-200k pricing from base model", () => {
},
},
},
// @ts-expect-error dead V1 fixture uses the removed pre-normalized ModelsDev provider type.
} as unknown as ModelsDev.Provider
const model = Provider.fromModelsDevProvider(provider).models["gpt-5.4-fast"]
@ -1415,6 +1416,7 @@ test("models.dev normalization fills required response fields", () => {
limit: { context: 1_050_000, input: 922_000, output: 128_000 },
},
},
// @ts-expect-error dead V1 fixture uses the removed pre-normalized ModelsDev provider type.
} as unknown as ModelsDev.Provider
const model = Provider.fromModelsDevProvider(provider).models["gpt-5.4"]

View file

@ -49,9 +49,11 @@ type RecordedScenario = {
readonly recordAuth?: () => Auth.Info | undefined
readonly replayAuth?: Auth.Info
readonly stableID?: string
// @ts-expect-error dead V1 fixture uses the removed pre-normalized ModelsDev provider type.
readonly config: (model: ModelsDev.Provider["models"][string]) => Partial<ConfigV1.Info>
}
// @ts-expect-error dead V1 fixture uses the removed pre-normalized ModelsDev provider type.
const cloneModel = (model: ModelsDev.Provider["models"][string]) => {
const cloned = structuredClone(model)
const { experimental, ...rest } = cloned
@ -94,6 +96,7 @@ const providerConfig = (input: {
readonly env: string[]
readonly npm: string
readonly api: string
// @ts-expect-error dead V1 fixture uses the removed pre-normalized ModelsDev provider type.
readonly model: ModelsDev.Provider["models"][string]
readonly options: Record<string, unknown>
}): Partial<ConfigV1.Info> => ({
@ -254,6 +257,7 @@ async function loadFixture(providerID: string, modelID: string) {
return model
}
// @ts-expect-error dead V1 fixture uses the removed pre-normalized ModelsDev provider type.
const modelsFixture = Filesystem.readJson<Record<string, ModelsDev.Provider>>(
path.join(import.meta.dir, "../tool/fixtures/models-api.json"),
)
@ -283,6 +287,7 @@ function recordedNativeLLMLayer(scenario: RecordedScenario) {
])
}
// @ts-expect-error dead V1 fixture uses the removed pre-normalized ModelsDev provider type.
const writeConfig = (directory: string, scenario: RecordedScenario, model: ModelsDev.Provider["models"][string]) =>
Effect.promise(() =>
Bun.write(

View file

@ -30,6 +30,7 @@ import { LayerNodePlatform } from "@opencode-ai/core/effect/app-node-platform"
type ConfigModel = NonNullable<NonNullable<ConfigV1.Info["provider"]>[string]["models"]>[string]
// @ts-expect-error dead V1 fixture uses the removed pre-normalized ModelsDev provider type.
const openAIConfig = (model: ModelsDev.Provider["models"][string], baseURL: string): Partial<ConfigV1.Info> => {
const { experimental: _experimental, ...configModel } = model
return {
@ -700,6 +701,7 @@ function createChatStream(text: string) {
const MODELS_FIXTURE = JSON.parse(
await Bun.file(path.join(import.meta.dir, "../tool/fixtures/models-api.json")).text(),
// @ts-expect-error dead V1 fixture uses the removed pre-normalized ModelsDev provider type.
) as Record<string, ModelsDev.Provider>
function loadFixture(providerID: string, modelID: string) {
@ -710,6 +712,7 @@ function loadFixture(providerID: string, modelID: string) {
return { provider, model }
}
// @ts-expect-error dead V1 fixture uses the removed pre-normalized ModelsDev model type.
function configModel(model: ModelsDev.Model) {
return {
id: model.id,