Something went wrong. Try again.
opencode v2 mirror
Something went wrong. Try again.
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162export * as Model from "./model.js"
import { Schema } from "effect"import { optional, statics } from "./schema.js"import { Provider } from "./provider.js"import { Money } from "./money.js"import { ephemeral, inventory } from "./event.js"
export const ID = Schema.String.pipe(Schema.brand("Model.ID"))export type ID = typeof ID.Type
const Updated = ephemeral({ type: "model.updated", schema: {} })export const Event = { Updated, Definitions: inventory(Updated) }
export const VariantID = Schema.String.pipe(Schema.brand("Model.VariantID"))export type VariantID = typeof VariantID.Type
export const Ref = Schema.Struct({ id: ID, providerID: Provider.ID, variant: VariantID.pipe(optional),}) .annotate({ identifier: "Model.Ref" }) .pipe( statics((schema) => ({ parse: (input: string) => { const providerEnd = input.indexOf("/") if (providerEnd <= 0) throw new Error(`Invalid model reference: ${input}`) const providerID = input.slice(0, providerEnd) const variantStart = input.indexOf("#", providerEnd + 1) const id = input.slice(providerEnd + 1, variantStart === -1 ? undefined : variantStart) const variant = variantStart === -1 ? undefined : input.slice(variantStart + 1) if (!id || providerID.includes("#") || (variant !== undefined && (!variant || variant.includes("#")))) throw new Error(`Invalid model reference: ${input}`) return schema.make({ providerID: Provider.ID.make(providerID), id: ID.make(id), ...(variant ? { variant: VariantID.make(variant) } : {}), }) }, })), )export interface Ref extends Schema.Schema.Type<typeof Ref> {}
export const Family = Schema.String.pipe(Schema.brand("Model.Family"))export type Family = typeof Family.Type
export type ReasoningField = "reasoning" | "reasoning_content" | "reasoning_text" | (string & {})export const ReasoningField: Schema.Codec<ReasoningField> = Schema.Union([ Schema.Literals(["reasoning", "reasoning_content", "reasoning_text"]), Schema.String,]).annotate({ identifier: "Model.ReasoningField" })
export const MaxTokensField = Schema.Literals(["max_completion_tokens", "max_tokens"]).annotate({ identifier: "Model.MaxTokensField",})export type MaxTokensField = typeof MaxTokensField.Type
export const Settings = Schema.StructWithRest( Schema.Struct({ compaction: Provider.Compaction.pipe(optional), }), // Provider packages may define arbitrary model-level options beyond OpenCode's shared compaction policy. [Schema.Record(Schema.String, Schema.Any)],).annotate({ identifier: "Model.Settings" })export type Settings = typeof Settings.Type
export const Overlays = { settings: Settings.pipe(optional), headers: Schema.Record(Schema.String, Schema.String).pipe(optional), body: Schema.Record(Schema.String, Schema.Any).pipe(optional),}
export interface Compatibility extends Schema.Schema.Type<typeof Compatibility> {}export const Compatibility = Schema.Struct({ reasoningField: ReasoningField.pipe(optional), /** Require every assistant message to include its reasoning field, even when empty. */ requireReasoning: Schema.Boolean.pipe(optional), maxTokensField: MaxTokensField.pipe(optional), requireFinishReason: Schema.Boolean.pipe(optional), requireAssistantAfterTool: Schema.Boolean.pipe(optional), supportsPromptCacheKey: Schema.Boolean.pipe(optional),}).annotate({ identifier: "Model.Compatibility" })
export interface Capabilities extends Schema.Schema.Type<typeof Capabilities> {}export const Capabilities = Schema.Struct({ tools: Schema.Boolean, input: Schema.Array(Schema.String), output: Schema.Array(Schema.String),}) .annotate({ identifier: "Model.Capabilities" }) .pipe( statics(() => ({ default: () => ({ tools: true, input: ["text", "image"], output: ["text"] }) satisfies Capabilities, })), )
export interface Cost extends Schema.Schema.Type<typeof Cost> {}export const Cost = Schema.Struct({ tier: Schema.Struct({ type: Schema.tag("context"), size: Schema.Int, }).pipe(optional), input: Money.USDPerMillionTokens, output: Money.USDPerMillionTokens, cache: Schema.Struct({ read: Money.USDPerMillionTokens, write: Money.USDPerMillionTokens, }),}).annotate({ identifier: "Model.Cost" })
export interface Variant extends Schema.Schema.Type<typeof Variant> {}export const Variant = Schema.Struct({ id: VariantID, ...Overlays,}).annotate({ identifier: "Model.Variant" })
export interface Info extends Schema.Schema.Type<typeof Info> {}export const Info = Schema.Struct({ id: ID, modelID: ID, providerID: Provider.ID, canonical: Provider.ID.pipe(optional), family: Family.pipe(optional), name: Schema.String, compatibility: Compatibility.pipe(optional), package: Provider.Package.pipe(optional), ...Overlays, capabilities: Capabilities, variants: Schema.Array(Variant), time: Schema.Struct({ released: Schema.Finite, }), cost: Schema.Array(Cost), status: Schema.Literals(["alpha", "beta", "deprecated", "active"]), enabled: Schema.Boolean, limit: Schema.Struct({ context: Schema.Int, input: Schema.Int.pipe(optional), output: Schema.Int, }),}) .annotate({ identifier: "Model.Info" }) .pipe( statics(() => ({ default: (providerID: Provider.ID, id: ID) => ({ id, modelID: id, providerID, name: id, capabilities: Capabilities.default(), variants: [], time: { released: 0 }, cost: [], status: "active", enabled: true, limit: { context: 200_000, output: 32_000 }, }) satisfies Info, })), )