summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAiden Cline <[email protected]>2026-04-02 10:00:43 -0500
committerGitHub <[email protected]>2026-04-02 10:00:43 -0500
commit23c865608018a882a99149b7e979f4f6fbcc0600 (patch)
tree99066b87657c30a02ce088ff10a4bb84b25ad61d
parentec3ae17e4d6abb9685b1d558d5e51416c9bfad60 (diff)
downloadopencode-23c865608018a882a99149b7e979f4f6fbcc0600.tar.gz
opencode-23c865608018a882a99149b7e979f4f6fbcc0600.zip
refactor: split up models.dev and config model definitions to prevent coupling (#20605)
-rw-r--r--packages/opencode/src/config/config.ts85
-rw-r--r--packages/opencode/src/provider/models.ts4
-rw-r--r--packages/opencode/src/provider/provider.ts4
-rw-r--r--packages/opencode/src/session/llm.ts3
4 files changed, 70 insertions, 26 deletions
diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts
index 3cae1af4b..b41e5d71c 100644
--- a/packages/opencode/src/config/config.ts
+++ b/packages/opencode/src/config/config.ts
@@ -730,28 +730,77 @@ export namespace Config {
})
export type Layout = z.infer<typeof Layout>
+ export const Model = z
+ .object({
+ id: z.string(),
+ name: z.string(),
+ family: z.string().optional(),
+ release_date: z.string(),
+ attachment: z.boolean(),
+ reasoning: z.boolean(),
+ temperature: z.boolean(),
+ tool_call: z.boolean(),
+ interleaved: z
+ .union([
+ z.literal(true),
+ z
+ .object({
+ field: z.enum(["reasoning_content", "reasoning_details"]),
+ })
+ .strict(),
+ ])
+ .optional(),
+ cost: z
+ .object({
+ input: z.number(),
+ output: z.number(),
+ cache_read: z.number().optional(),
+ cache_write: z.number().optional(),
+ context_over_200k: z
+ .object({
+ input: z.number(),
+ output: z.number(),
+ cache_read: z.number().optional(),
+ cache_write: z.number().optional(),
+ })
+ .optional(),
+ })
+ .optional(),
+ limit: z.object({
+ context: z.number(),
+ input: z.number().optional(),
+ output: z.number(),
+ }),
+ modalities: z
+ .object({
+ input: z.array(z.enum(["text", "audio", "image", "video", "pdf"])),
+ output: z.array(z.enum(["text", "audio", "image", "video", "pdf"])),
+ })
+ .optional(),
+ experimental: z.boolean().optional(),
+ status: z.enum(["alpha", "beta", "deprecated"]).optional(),
+ options: z.record(z.string(), z.any()),
+ headers: z.record(z.string(), z.string()).optional(),
+ provider: z.object({ npm: z.string().optional(), api: z.string().optional() }).optional(),
+ variants: z
+ .record(
+ z.string(),
+ z
+ .object({
+ disabled: z.boolean().optional().describe("Disable this variant for the model"),
+ })
+ .catchall(z.any()),
+ )
+ .optional()
+ .describe("Variant-specific configuration"),
+ })
+ .partial()
+
export const Provider = ModelsDev.Provider.partial()
.extend({
whitelist: z.array(z.string()).optional(),
blacklist: z.array(z.string()).optional(),
- models: z
- .record(
- z.string(),
- ModelsDev.Model.partial().extend({
- variants: z
- .record(
- z.string(),
- z
- .object({
- disabled: z.boolean().optional().describe("Disable this variant for the model"),
- })
- .catchall(z.any()),
- )
- .optional()
- .describe("Variant-specific configuration"),
- }),
- )
- .optional(),
+ models: z.record(z.string(), Model).optional(),
options: z
.object({
apiKey: z.string().optional(),
diff --git a/packages/opencode/src/provider/models.ts b/packages/opencode/src/provider/models.ts
index 30901ea74..0e2a26b4d 100644
--- a/packages/opencode/src/provider/models.ts
+++ b/packages/opencode/src/provider/models.ts
@@ -61,12 +61,8 @@ export namespace ModelsDev {
output: z.array(z.enum(["text", "audio", "image", "video", "pdf"])),
})
.optional(),
- experimental: z.boolean().optional(),
status: z.enum(["alpha", "beta", "deprecated"]).optional(),
- options: z.record(z.string(), z.any()),
- headers: z.record(z.string(), z.string()).optional(),
provider: z.object({ npm: z.string().optional(), api: z.string().optional() }).optional(),
- variants: z.record(z.string(), z.record(z.string(), z.any())).optional(),
})
export type Model = z.infer<typeof Model>
diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts
index 441f84b90..c1b5e61d1 100644
--- a/packages/opencode/src/provider/provider.ts
+++ b/packages/opencode/src/provider/provider.ts
@@ -903,8 +903,8 @@ export namespace Provider {
npm: model.provider?.npm ?? provider.npm ?? "@ai-sdk/openai-compatible",
},
status: model.status ?? "active",
- headers: model.headers ?? {},
- options: model.options ?? {},
+ headers: {},
+ options: {},
cost: {
input: model.cost?.input ?? 0,
output: model.cost?.output ?? 0,
diff --git a/packages/opencode/src/session/llm.ts b/packages/opencode/src/session/llm.ts
index dc89db409..41f72df06 100644
--- a/packages/opencode/src/session/llm.ts
+++ b/packages/opencode/src/session/llm.ts
@@ -1,7 +1,6 @@
import { Provider } from "@/provider/provider"
import { Log } from "@/util/log"
-import { Cause, Effect, Layer, Record, ServiceMap } from "effect"
-import * as Queue from "effect/Queue"
+import { Effect, Layer, Record, ServiceMap } from "effect"
import * as Stream from "effect/Stream"
import { streamText, wrapLanguageModel, type ModelMessage, type Tool, tool, jsonSchema } from "ai"
import { mergeDeep, pipe } from "remeda"