refactor(migration): split model and category helpers (#1561)

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
YeonGyu-Kim
2026-02-07 19:51:15 +09:00
parent 3ccef5d9b3
commit 817c593e12
2 changed files with 109 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
/**
* @deprecated LEGACY MIGRATION ONLY
*
* This map exists solely for migrating old configs that used hardcoded model strings.
* It maps legacy model strings to semantic category names, allowing users to migrate
* from explicit model configs to category-based configs.
*
* DO NOT add new entries here. New agents should use:
* - Category-based config (preferred): { category: "unspecified-high" }
* - Or inherit from OpenCode's config.model
*
* This map will be removed in a future major version once migration period ends.
*/
export const MODEL_TO_CATEGORY_MAP: Record<string, string> = {
"google/gemini-3-pro": "visual-engineering",
"google/gemini-3-flash": "writing",
"openai/gpt-5.2": "ultrabrain",
"anthropic/claude-haiku-4-5": "quick",
"anthropic/claude-opus-4-6": "unspecified-high",
"anthropic/claude-sonnet-4-5": "unspecified-low",
}
export function migrateAgentConfigToCategory(config: Record<string, unknown>): {
migrated: Record<string, unknown>
changed: boolean
} {
const { model, ...rest } = config
if (typeof model !== "string") {
return { migrated: config, changed: false }
}
const category = MODEL_TO_CATEGORY_MAP[model]
if (!category) {
return { migrated: config, changed: false }
}
return {
migrated: { category, ...rest },
changed: true,
}
}
export function shouldDeleteAgentConfig(
config: Record<string, unknown>,
category: string
): boolean {
const { DEFAULT_CATEGORIES } = require("../../tools/delegate-task/constants")
const defaults = DEFAULT_CATEGORIES[category]
if (!defaults) return false
const keys = Object.keys(config).filter((k) => k !== "category")
if (keys.length === 0) return true
for (const key of keys) {
if (config[key] !== (defaults as Record<string, unknown>)[key]) {
return false
}
}
return true
}

View File

@@ -0,0 +1,49 @@
/**
* Model version migration map: old full model strings → new full model strings.
* Used to auto-upgrade hardcoded model versions in user configs when the plugin
* bumps to newer model versions.
*
* Keys are full "provider/model" strings. Only openai and anthropic entries needed.
*/
export const MODEL_VERSION_MAP: Record<string, string> = {
"openai/gpt-5.2-codex": "openai/gpt-5.3-codex",
"anthropic/claude-opus-4-5": "anthropic/claude-opus-4-6",
}
function migrationKey(oldModel: string, newModel: string): string {
return `model-version:${oldModel}->${newModel}`
}
export function migrateModelVersions(
configs: Record<string, unknown>,
appliedMigrations?: Set<string>
): { migrated: Record<string, unknown>; changed: boolean; newMigrations: string[] } {
const migrated: Record<string, unknown> = {}
let changed = false
const newMigrations: string[] = []
for (const [key, value] of Object.entries(configs)) {
if (value && typeof value === "object" && !Array.isArray(value)) {
const config = value as Record<string, unknown>
if (typeof config.model === "string" && MODEL_VERSION_MAP[config.model]) {
const oldModel = config.model
const newModel = MODEL_VERSION_MAP[oldModel]
const mKey = migrationKey(oldModel, newModel)
// Skip if this migration was already applied (user may have reverted)
if (appliedMigrations?.has(mKey)) {
migrated[key] = value
continue
}
migrated[key] = { ...config, model: newModel }
changed = true
newMigrations.push(mKey)
continue
}
}
migrated[key] = value
}
return { migrated, changed, newMigrations }
}