diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 3cae1af4bd..b41e5d71c2 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 + 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 30901ea74f..0e2a26b4d9 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 diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index c3ca1b3852..a77ed1d8fe 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -909,8 +909,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 dc89db409e..41f72df06a 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" diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index 436847ed4e..5121f24527 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -756,7 +756,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the } const model = input.model ?? agent.model ?? (yield* lastModel(input.sessionID)) const userMsg: MessageV2.User = { - id: MessageID.ascending(), + id: input.messageID ?? MessageID.ascending(), sessionID: input.sessionID, time: { created: Date.now() }, role: "user", @@ -1827,6 +1827,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the export const ShellInput = z.object({ sessionID: SessionID.zod, + messageID: MessageID.zod.optional(), agent: z.string(), model: z .object({ diff --git a/packages/sdk/js/src/v2/gen/sdk.gen.ts b/packages/sdk/js/src/v2/gen/sdk.gen.ts index 527584e7e2..113b3ed0f8 100644 --- a/packages/sdk/js/src/v2/gen/sdk.gen.ts +++ b/packages/sdk/js/src/v2/gen/sdk.gen.ts @@ -2231,6 +2231,7 @@ export class Session2 extends HeyApiClient { sessionID: string directory?: string workspace?: string + messageID?: string agent?: string model?: { providerID: string @@ -2248,6 +2249,7 @@ export class Session2 extends HeyApiClient { { in: "path", key: "sessionID" }, { in: "query", key: "directory" }, { in: "query", key: "workspace" }, + { in: "body", key: "messageID" }, { in: "body", key: "agent" }, { in: "body", key: "model" }, { in: "body", key: "command" }, diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index 290c6fd5ec..6ac6af1439 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -3815,6 +3815,7 @@ export type SessionCommandResponse = SessionCommandResponses[keyof SessionComman export type SessionShellData = { body?: { + messageID?: string agent: string model?: { providerID: string @@ -4167,23 +4168,11 @@ export type ProviderListResponses = { input: Array<"text" | "audio" | "image" | "video" | "pdf"> output: Array<"text" | "audio" | "image" | "video" | "pdf"> } - experimental?: boolean status?: "alpha" | "beta" | "deprecated" - options: { - [key: string]: unknown - } - headers?: { - [key: string]: string - } provider?: { npm?: string api?: string } - variants?: { - [key: string]: { - [key: string]: unknown - } - } } } }> diff --git a/packages/sdk/openapi.json b/packages/sdk/openapi.json index ba7188af13..549fcc4fe1 100644 --- a/packages/sdk/openapi.json +++ b/packages/sdk/openapi.json @@ -3942,6 +3942,10 @@ "schema": { "type": "object", "properties": { + "messageID": { + "type": "string", + "pattern": "^msg.*" + }, "agent": { "type": "string" }, @@ -4740,29 +4744,10 @@ }, "required": ["input", "output"] }, - "experimental": { - "type": "boolean" - }, "status": { "type": "string", "enum": ["alpha", "beta", "deprecated"] }, - "options": { - "type": "object", - "propertyNames": { - "type": "string" - }, - "additionalProperties": {} - }, - "headers": { - "type": "object", - "propertyNames": { - "type": "string" - }, - "additionalProperties": { - "type": "string" - } - }, "provider": { "type": "object", "properties": { @@ -4773,19 +4758,6 @@ "type": "string" } } - }, - "variants": { - "type": "object", - "propertyNames": { - "type": "string" - }, - "additionalProperties": { - "type": "object", - "propertyNames": { - "type": "string" - }, - "additionalProperties": {} - } } }, "required": [ @@ -4796,8 +4768,7 @@ "reasoning", "temperature", "tool_call", - "limit", - "options" + "limit" ] } }