diff --git a/README.md b/README.md index 6e08d7cc..6439b8ab 100644 --- a/README.md +++ b/README.md @@ -114,43 +114,6 @@ messages_last = "ctrl+alt+g" app_exit = "ctrl+c,q" ``` -#### Models.dev - -You can also extend the models.dev database with your own providers by mirroring the structure found [here](https://github.com/sst/models.dev/tree/dev/providers/anthropic) - -Start with a `provider.toml` file in `~/.config/opencode/providers` - -```toml -# ~/.config/opencode/providers/openrouter/provider.toml -[provider] -name = "OpenRouter" -env = ["OPENROUTER_API_KEY"] -npm = "@openrouter/ai-sdk-provider" - -[options] -baseURL = "https://api.openrouter.ai" # optional settings -``` - -And models in `~/.config/opencode/providers/openrouter/models/[model-id]` - -```toml -# ~/.config/opencode/providers/openrouter/models/anthropic/claude-3.5-sonnet.toml -name = "Claude 4 Sonnet" -attachment = true -reasoning = false -temperature = true - -[cost] -input = 3.00 -output = 15.00 -inputCached = 3.75 -outputCached = 0.30 - -[limit] -context = 200_000 -output = 50_000 -``` - ### Project Config Project configuration is optional. You can place an `opencode.json` file in the root of your repo and is meant to be checked in and shared with your team. @@ -230,9 +193,7 @@ OpenRouter is not in the Models.dev database yet, but you can configure it manua "openrouter": { "npm": "@openrouter/ai-sdk-provider", "name": "OpenRouter", - "options": { - "apiKey": "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - }, + "options": {}, "models": { "anthropic/claude-3.5-sonnet": { "name": "Claude 3.5 Sonnet" @@ -243,6 +204,8 @@ OpenRouter is not in the Models.dev database yet, but you can configure it manua } ``` +And then to configure an api key you can do `opencode auth login` and select "Other -> 'openrouter'" + #### How is this different than Claude Code? It's very similar to Claude Code in terms of capability. Here are the key differences: diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 4623f9cd..74c21c7e 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -1,14 +1,20 @@ import { Log } from "../util/log" +import path from "path" import { z } from "zod" import { App } from "../app/app" import { Filesystem } from "../util/filesystem" import { ModelsDev } from "../provider/models" +import { mergeDeep } from "remeda" +import { Global } from "../global" export namespace Config { const log = Log.create({ service: "config" }) export const state = App.state("config", async (app) => { - let result: Info = {} + let result = await Bun.file(path.join(Global.Path.config, "config.json")) + .json() + .then((mod) => Info.parse(mod)) + .catch(() => ({}) as Info) for (const file of ["opencode.jsonc", "opencode.json"]) { const [resolved] = await Filesystem.findUp( file, @@ -17,7 +23,10 @@ export namespace Config { ) if (!resolved) continue try { - result = await import(resolved).then((mod) => Info.parse(mod.default)) + result = mergeDeep( + result, + await import(resolved).then((mod) => Info.parse(mod.default)), + ) log.info("found", { path: resolved }) break } catch (e) { diff --git a/packages/opencode/src/provider/models.ts b/packages/opencode/src/provider/models.ts index 40d8328d..26255808 100644 --- a/packages/opencode/src/provider/models.ts +++ b/packages/opencode/src/provider/models.ts @@ -32,6 +32,7 @@ export namespace ModelsDev { export const Provider = z .object({ + api: z.string().optional(), name: z.string(), env: z.array(z.string()), id: z.string(), diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index 0a2a6582..17090233 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -103,6 +103,7 @@ export namespace Provider { if (!provider) { const info = database[id] if (!info) return + if (info.api) options["baseURL"] = info.api providers[id] = { source, info,