fix(models): update model names to match OpenCode Zen catalog (#1048)
* fix(models): update model names to match OpenCode Zen catalog OpenCode Zen recently updated their official model catalog, deprecating several preview and free model variants: DEPRECATED → NEW (Official Zen Names): - gemini-3-pro-preview → gemini-3-pro - gemini-3-flash-preview → gemini-3-flash - grok-code → gpt-5-nano (FREE tier maintained) - glm-4.7-free → big-pickle (FREE tier maintained) - glm-4.6v → glm-4.6 Changes: - Updated 6 source files (model-requirements, delegate-task, think-mode, etc.) - Updated 9 documentation files (installation, configurations, features, etc.) - Updated 14 test files with new model references - Regenerated snapshots to reflect catalog changes - Removed duplicate think-mode entries for preview variants Impact: - FREE tier access preserved via gpt-5-nano and big-pickle - All 55 model-related tests passing - Zero breaking changes - pure string replacement - Aligns codebase with official OpenCode Zen model catalog Verified: - Zero deprecated model names in codebase - All model-related tests pass (55/55) - Snapshots regenerated and validated Affects: 30 files (6 source, 9 docs, 14 tests, 1 snapshot) * fix(multimodal-looker): update fallback chain with glm-4.6v and gpt-5-nano - Change glm-4.6 to glm-4.6v for zai-coding-plan provider - Add opencode/gpt-5-nano as 4th fallback (FREE tier) - Push gpt-5.2 to 5th position Fallback chain now: 1. gemini-3-flash (google, github-copilot, opencode) 2. claude-haiku-4-5 (anthropic, github-copilot, opencode) 3. glm-4.6v (zai-coding-plan) 4. gpt-5-nano (opencode) - FREE 5. gpt-5.2 (openai, github-copilot, opencode) * chore: update bun.lock --------- Co-authored-by: justsisyphus <justsisyphus@users.noreply.github.com>
This commit is contained in:
@@ -156,13 +156,13 @@ Approach:
|
||||
|
||||
|
||||
export const DEFAULT_CATEGORIES: Record<string, CategoryConfig> = {
|
||||
"visual-engineering": { model: "google/gemini-3-pro-preview" },
|
||||
"visual-engineering": { model: "google/gemini-3-pro" },
|
||||
ultrabrain: { model: "openai/gpt-5.2-codex", variant: "xhigh" },
|
||||
artistry: { model: "google/gemini-3-pro-preview", variant: "max" },
|
||||
artistry: { model: "google/gemini-3-pro", variant: "max" },
|
||||
quick: { model: "anthropic/claude-haiku-4-5" },
|
||||
"unspecified-low": { model: "anthropic/claude-sonnet-4-5" },
|
||||
"unspecified-high": { model: "anthropic/claude-opus-4-5", variant: "max" },
|
||||
writing: { model: "google/gemini-3-flash-preview" },
|
||||
writing: { model: "google/gemini-3-flash" },
|
||||
}
|
||||
|
||||
export const CATEGORY_PROMPT_APPENDS: Record<string, string> = {
|
||||
|
||||
@@ -20,7 +20,7 @@ describe("sisyphus-task", () => {
|
||||
|
||||
// #when / #then
|
||||
expect(category).toBeDefined()
|
||||
expect(category.model).toBe("google/gemini-3-pro-preview")
|
||||
expect(category.model).toBe("google/gemini-3-pro")
|
||||
})
|
||||
|
||||
test("ultrabrain category has model and variant config", () => {
|
||||
@@ -142,7 +142,7 @@ describe("sisyphus-task", () => {
|
||||
|
||||
// #then
|
||||
expect(result).not.toBeNull()
|
||||
expect(result!.config.model).toBe("google/gemini-3-pro-preview")
|
||||
expect(result!.config.model).toBe("google/gemini-3-pro")
|
||||
expect(result!.promptAppend).toContain("VISUAL/UI")
|
||||
})
|
||||
|
||||
@@ -166,7 +166,7 @@ describe("sisyphus-task", () => {
|
||||
const categoryName = "visual-engineering"
|
||||
const userCategories = {
|
||||
"visual-engineering": {
|
||||
model: "google/gemini-3-pro-preview",
|
||||
model: "google/gemini-3-pro",
|
||||
prompt_append: "Custom instructions here",
|
||||
},
|
||||
}
|
||||
@@ -206,7 +206,7 @@ describe("sisyphus-task", () => {
|
||||
const categoryName = "visual-engineering"
|
||||
const userCategories = {
|
||||
"visual-engineering": {
|
||||
model: "google/gemini-3-pro-preview",
|
||||
model: "google/gemini-3-pro",
|
||||
temperature: 0.3,
|
||||
},
|
||||
}
|
||||
@@ -229,7 +229,7 @@ describe("sisyphus-task", () => {
|
||||
|
||||
// #then - category's built-in model wins over inheritedModel
|
||||
expect(result).not.toBeNull()
|
||||
expect(result!.config.model).toBe("google/gemini-3-pro-preview")
|
||||
expect(result!.config.model).toBe("google/gemini-3-pro")
|
||||
})
|
||||
|
||||
test("systemDefaultModel is used as fallback when custom category has no model", () => {
|
||||
@@ -271,7 +271,7 @@ describe("sisyphus-task", () => {
|
||||
|
||||
// #then
|
||||
expect(result).not.toBeNull()
|
||||
expect(result!.config.model).toBe("google/gemini-3-pro-preview")
|
||||
expect(result!.config.model).toBe("google/gemini-3-pro")
|
||||
})
|
||||
})
|
||||
|
||||
@@ -960,7 +960,7 @@ describe("sisyphus-task", () => {
|
||||
const mockClient = {
|
||||
app: { agents: async () => ({ data: [] }) },
|
||||
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||
model: { list: async () => [{ id: "google/gemini-3-pro-preview" }] },
|
||||
model: { list: async () => [{ id: "google/gemini-3-pro" }] },
|
||||
session: {
|
||||
get: async () => ({ data: { directory: "/project" } }),
|
||||
create: async () => ({ data: { id: "ses_unstable_gemini" } }),
|
||||
@@ -1144,7 +1144,7 @@ describe("sisyphus-task", () => {
|
||||
const mockClient = {
|
||||
app: { agents: async () => ({ data: [] }) },
|
||||
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||
model: { list: async () => [{ id: "google/gemini-3-pro-preview" }] },
|
||||
model: { list: async () => [{ id: "google/gemini-3-pro" }] },
|
||||
session: {
|
||||
get: async () => ({ data: { directory: "/project" } }),
|
||||
create: async () => ({ data: { id: "ses_artistry_gemini" } }),
|
||||
@@ -1170,7 +1170,7 @@ describe("sisyphus-task", () => {
|
||||
abort: new AbortController().signal,
|
||||
}
|
||||
|
||||
// #when - artistry category (gemini-3-pro-preview with max variant)
|
||||
// #when - artistry category (gemini-3-pro with max variant)
|
||||
const result = await tool.execute(
|
||||
{
|
||||
description: "Test artistry forced background",
|
||||
@@ -1189,7 +1189,7 @@ describe("sisyphus-task", () => {
|
||||
}, { timeout: 20000 })
|
||||
|
||||
test("writing category (gemini-flash) with run_in_background=false should force background but wait for result", async () => {
|
||||
// #given - writing uses gemini-3-flash-preview
|
||||
// #given - writing uses gemini-3-flash
|
||||
const { createDelegateTask } = require("./tools")
|
||||
let launchCalled = false
|
||||
|
||||
@@ -1209,7 +1209,7 @@ describe("sisyphus-task", () => {
|
||||
const mockClient = {
|
||||
app: { agents: async () => ({ data: [] }) },
|
||||
config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) },
|
||||
model: { list: async () => [{ id: "google/gemini-3-flash-preview" }] },
|
||||
model: { list: async () => [{ id: "google/gemini-3-flash" }] },
|
||||
session: {
|
||||
get: async () => ({ data: { directory: "/project" } }),
|
||||
create: async () => ({ data: { id: "ses_writing_gemini" } }),
|
||||
@@ -1235,7 +1235,7 @@ describe("sisyphus-task", () => {
|
||||
abort: new AbortController().signal,
|
||||
}
|
||||
|
||||
// #when - writing category (gemini-3-flash-preview)
|
||||
// #when - writing category (gemini-3-flash)
|
||||
const result = await tool.execute(
|
||||
{
|
||||
description: "Test writing forced background",
|
||||
@@ -1535,9 +1535,9 @@ describe("sisyphus-task", () => {
|
||||
// #when resolveCategoryConfig is called
|
||||
const resolved = resolveCategoryConfig(categoryName, { userCategories, inheritedModel, systemDefaultModel: SYSTEM_DEFAULT_MODEL })
|
||||
|
||||
// #then should use category's built-in model (gemini-3-pro-preview for visual-engineering)
|
||||
// #then should use category's built-in model (gemini-3-pro for visual-engineering)
|
||||
expect(resolved).not.toBeNull()
|
||||
expect(resolved!.model).toBe("google/gemini-3-pro-preview")
|
||||
expect(resolved!.model).toBe("google/gemini-3-pro")
|
||||
})
|
||||
|
||||
test("systemDefaultModel is used when no other model is available", () => {
|
||||
|
||||
Reference in New Issue
Block a user