mirror of
https://github.com/anomalyco/opencode.git
synced 2026-05-14 08:32:33 +00:00
refactor(provider): share model status schema (#26595)
Co-authored-by: Developer <temp@example.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { Schema } from "effect"
|
||||
import { zod } from "@opencode-ai/core/effect-zod"
|
||||
import { PositiveInt, withStatics } from "@opencode-ai/core/schema"
|
||||
import { ModelStatus } from "@/provider/model-status"
|
||||
|
||||
export const Model = Schema.Struct({
|
||||
id: Schema.optional(Schema.String),
|
||||
@@ -49,7 +50,7 @@ export const Model = Schema.Struct({
|
||||
}),
|
||||
),
|
||||
experimental: Schema.optional(Schema.Boolean),
|
||||
status: Schema.optional(Schema.Literals(["alpha", "beta", "deprecated", "active"])),
|
||||
status: Schema.optional(ModelStatus),
|
||||
provider: Schema.optional(
|
||||
Schema.Struct({ npm: Schema.optional(Schema.String), api: Schema.optional(Schema.String) }),
|
||||
),
|
||||
|
||||
9
packages/opencode/src/provider/model-status.ts
Normal file
9
packages/opencode/src/provider/model-status.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Schema } from "effect"
|
||||
|
||||
export const CatalogModelStatus = Schema.Literals(["alpha", "beta", "deprecated"])
|
||||
export type CatalogModelStatus = typeof CatalogModelStatus.Type
|
||||
|
||||
export const ModelStatus = Schema.Literals(["alpha", "beta", "deprecated", "active"])
|
||||
export type ModelStatus = typeof ModelStatus.Type
|
||||
|
||||
export * as ProviderModelStatus from "./model-status"
|
||||
@@ -8,6 +8,7 @@ import { Flock } from "@opencode-ai/core/util/flock"
|
||||
import { Hash } from "@opencode-ai/core/util/hash"
|
||||
import { AppFileSystem } from "@opencode-ai/core/filesystem"
|
||||
import { withTransientReadRetry } from "@/util/effect-http-client"
|
||||
import { CatalogModelStatus } from "./model-status"
|
||||
|
||||
const Cost = Schema.Struct({
|
||||
input: Schema.Finite,
|
||||
@@ -71,7 +72,7 @@ export const Model = Schema.Struct({
|
||||
),
|
||||
}),
|
||||
),
|
||||
status: Schema.optional(Schema.Literals(["alpha", "beta", "deprecated", "active"])),
|
||||
status: Schema.optional(CatalogModelStatus),
|
||||
provider: Schema.optional(
|
||||
Schema.Struct({ npm: Schema.optional(Schema.String), api: Schema.optional(Schema.String) }),
|
||||
),
|
||||
|
||||
@@ -28,6 +28,7 @@ import { optionalOmitUndefined, withStatics } from "@opencode-ai/core/schema"
|
||||
|
||||
import * as ProviderTransform from "./transform"
|
||||
import { ModelID, ProviderID } from "./schema"
|
||||
import { ModelStatus } from "./model-status"
|
||||
|
||||
const log = Log.create({ service: "provider" })
|
||||
|
||||
@@ -897,7 +898,7 @@ export const Model = Schema.Struct({
|
||||
capabilities: ProviderCapabilities,
|
||||
cost: ProviderCost,
|
||||
limit: ProviderLimit,
|
||||
status: Schema.Literals(["alpha", "beta", "deprecated", "active"]),
|
||||
status: ModelStatus,
|
||||
options: Schema.Record(Schema.String, Schema.Any),
|
||||
headers: Schema.Record(Schema.String, Schema.String),
|
||||
release_date: Schema.String,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { withStatics } from "@opencode-ai/core/schema"
|
||||
import { ModelStatus } from "@/provider/model-status"
|
||||
import { Array, Context, Effect, HashMap, Layer, Option, Order, pipe, Schema } from "effect"
|
||||
import { DateTimeUtcFromMillis } from "effect/Schema"
|
||||
|
||||
@@ -114,7 +115,7 @@ export class Info extends Schema.Class<Info>("Model.Info")({
|
||||
released: DateTimeUtcFromMillis,
|
||||
}),
|
||||
cost: Cost.pipe(Schema.Array),
|
||||
status: Schema.Literals(["alpha", "beta", "deprecated", "active"]),
|
||||
status: ModelStatus,
|
||||
limit: Schema.Struct({
|
||||
context: Schema.Int,
|
||||
input: Schema.Int.pipe(Schema.optional),
|
||||
|
||||
61
packages/opencode/test/provider/model-status.test.ts
Normal file
61
packages/opencode/test/provider/model-status.test.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import { Schema } from "effect"
|
||||
import { ConfigProvider } from "@/config/provider"
|
||||
import { CatalogModelStatus, ModelStatus } from "@/provider/model-status"
|
||||
import { ModelsDev } from "@/provider/models"
|
||||
import { Provider } from "@/provider/provider"
|
||||
|
||||
describe("provider model status schemas", () => {
|
||||
test("keeps catalog status separate from normalized provider status", () => {
|
||||
expect(Schema.decodeUnknownSync(CatalogModelStatus)("deprecated")).toBe("deprecated")
|
||||
expect(() => Schema.decodeUnknownSync(CatalogModelStatus)("active")).toThrow()
|
||||
expect(Schema.decodeUnknownSync(ModelStatus)("active")).toBe("active")
|
||||
})
|
||||
|
||||
test("accepts active status across public provider schemas", () => {
|
||||
expect(Schema.decodeUnknownSync(ConfigProvider.Model)({ status: "active" }).status).toBe("active")
|
||||
expect(
|
||||
Schema.decodeUnknownSync(ModelsDev.Model)({
|
||||
id: "test-model",
|
||||
name: "Test Model",
|
||||
release_date: "2026-01-01",
|
||||
attachment: false,
|
||||
reasoning: false,
|
||||
temperature: true,
|
||||
tool_call: true,
|
||||
limit: { context: 128000, output: 8192 },
|
||||
}).status,
|
||||
).toBeUndefined()
|
||||
expect(
|
||||
Schema.decodeUnknownSync(Provider.Model)({
|
||||
id: "test-model",
|
||||
providerID: "test-provider",
|
||||
api: {
|
||||
id: "test-model",
|
||||
url: "",
|
||||
npm: "@ai-sdk/openai-compatible",
|
||||
},
|
||||
name: "Test Model",
|
||||
capabilities: {
|
||||
temperature: true,
|
||||
reasoning: false,
|
||||
attachment: false,
|
||||
toolcall: true,
|
||||
input: { text: true, audio: false, image: false, video: false, pdf: false },
|
||||
output: { text: true, audio: false, image: false, video: false, pdf: false },
|
||||
interleaved: false,
|
||||
},
|
||||
cost: {
|
||||
input: 0,
|
||||
output: 0,
|
||||
cache: { read: 0, write: 0 },
|
||||
},
|
||||
limit: { context: 128000, output: 8192 },
|
||||
status: "active",
|
||||
options: {},
|
||||
headers: {},
|
||||
release_date: "2026-01-01",
|
||||
}).status,
|
||||
).toBe("active")
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user