diff --git a/packages/opencode/src/cli/cmd/github.handler.ts b/packages/opencode/src/cli/cmd/github.handler.ts index edaecb7b52..a36d4743ff 100644 --- a/packages/opencode/src/cli/cmd/github.handler.ts +++ b/packages/opencode/src/cli/cmd/github.handler.ts @@ -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( diff --git a/packages/opencode/src/cli/cmd/providers.ts b/packages/opencode/src/cli/cmd/providers.ts index 3775123d83..2d5a0ceaf7 100644 --- a/packages/opencode/src/cli/cmd/providers.ts +++ b/packages/opencode/src/cli/cmd/providers.ts @@ -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 = {} 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( diff --git a/packages/opencode/src/provider/model-status.ts b/packages/opencode/src/provider/model-status.ts index 77bc329aee..ba0467d260 100644 --- a/packages/opencode/src/provider/model-status.ts +++ b/packages/opencode/src/provider/model-status.ts @@ -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"]) diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index c979fc4465..dae82870f8 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -1156,6 +1156,7 @@ export class Service extends Context.Service()("@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 = {} 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) { 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 diff --git a/packages/opencode/src/provider/transform.ts b/packages/opencode/src/provider/transform.ts index f42e14139f..bf65a8a2e6 100644 --- a/packages/opencode/src/provider/transform.ts +++ b/packages/opencode/src/provider/transform.ts @@ -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["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 diff --git a/packages/opencode/src/server/routes/instance/httpapi/handlers/provider.ts b/packages/opencode/src/server/routes/instance/httpapi/handlers/provider.ts index e1377b6f75..19087c01f6 100644 --- a/packages/opencode/src/server/routes/instance/httpapi/handlers/provider.ts +++ b/packages/opencode/src/server/routes/instance/httpapi/handlers/provider.ts @@ -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 = {} for (const [key, value] of Object.entries(all)) { if ((enabled ? enabled.has(key) : true) && !disabled.has(key)) filtered[key] = value diff --git a/packages/opencode/test/provider/model-status.test.ts b/packages/opencode/test/provider/model-status.test.ts index 35a859120b..2bfbffe1e8 100644 --- a/packages/opencode/test/provider/model-status.test.ts +++ b/packages/opencode/test/provider/model-status.test.ts @@ -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", diff --git a/packages/opencode/test/provider/provider.test.ts b/packages/opencode/test/provider/provider.test.ts index 18ec8f9fbe..53fe8bac20 100644 --- a/packages/opencode/test/provider/provider.test.ts +++ b/packages/opencode/test/provider/provider.test.ts @@ -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"] diff --git a/packages/opencode/test/session/llm-native-recorded.test.ts b/packages/opencode/test/session/llm-native-recorded.test.ts index 36853a6d26..b4864d14ac 100644 --- a/packages/opencode/test/session/llm-native-recorded.test.ts +++ b/packages/opencode/test/session/llm-native-recorded.test.ts @@ -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 } +// @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 }): Partial => ({ @@ -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>( 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( diff --git a/packages/opencode/test/session/llm.test.ts b/packages/opencode/test/session/llm.test.ts index 5574d29356..15e2251b75 100644 --- a/packages/opencode/test/session/llm.test.ts +++ b/packages/opencode/test/session/llm.test.ts @@ -30,6 +30,7 @@ import { LayerNodePlatform } from "@opencode-ai/core/effect/app-node-platform" type ConfigModel = NonNullable[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 => { 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 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,