Files
opencode/packages/opencode/src/cli/cmd/models.ts

89 lines
2.9 KiB
TypeScript

import type { Argv } from "yargs"
import { Instance } from "../../project/instance"
import { Provider } from "../../provider"
import { ProviderID } from "../../provider/schema"
import { ModelsDev } from "../../provider/models"
import { cmd } from "./cmd"
import { UI } from "../ui"
import { EOL } from "os"
import { AppRuntime } from "@/effect/app-runtime"
import { Effect } from "effect"
export const ModelsCommand = cmd({
command: "models [provider]",
describe: "list all available models",
builder: (yargs: Argv) => {
return yargs
.positional("provider", {
describe: "provider ID to filter models by",
type: "string",
array: false,
})
.option("verbose", {
describe: "use more verbose model output (includes metadata like costs)",
type: "boolean",
})
.option("refresh", {
describe: "refresh the models cache from models.dev",
type: "boolean",
})
},
handler: async (args) => {
if (args.refresh) {
await ModelsDev.refresh(true)
UI.println(UI.Style.TEXT_SUCCESS_BOLD + "Models cache refreshed" + UI.Style.TEXT_NORMAL)
}
await Instance.provide({
directory: process.cwd(),
async fn() {
await AppRuntime.runPromise(
Effect.gen(function* () {
const svc = yield* Provider.Service
const providers = yield* svc.list()
const print = (providerID: ProviderID, verbose?: boolean) => {
const provider = providers[providerID]
const sorted = Object.entries(provider.models).sort(([a], [b]) => a.localeCompare(b))
for (const [modelID, model] of sorted) {
process.stdout.write(`${providerID}/${modelID}`)
process.stdout.write(EOL)
if (verbose) {
process.stdout.write(JSON.stringify(model, null, 2))
process.stdout.write(EOL)
}
}
}
if (args.provider) {
const providerID = ProviderID.make(args.provider)
const provider = providers[providerID]
if (!provider) {
yield* Effect.sync(() => UI.error(`Provider not found: ${args.provider}`))
return
}
yield* Effect.sync(() => print(providerID, args.verbose))
return
}
const ids = Object.keys(providers).sort((a, b) => {
const aIsOpencode = a.startsWith("opencode")
const bIsOpencode = b.startsWith("opencode")
if (aIsOpencode && !bIsOpencode) return -1
if (!aIsOpencode && bIsOpencode) return 1
return a.localeCompare(b)
})
yield* Effect.sync(() => {
for (const providerID of ids) {
print(ProviderID.make(providerID), args.verbose)
}
})
}),
)
},
})
},
})