chat: surface OpenCode models in the picker (Phase 2)

list-models.ts now merges the OpenCode catalog (from `opencode models`, cached;
ids are providerID/modelID) with the static Claude tiers, so /chat/models returns
both. invalidateModelCache clears the OpenCode cache for real now.

Adds the 'opencode' → 'OpenCode Zen' provider label in the /models response and the
ModelSelector's PROVIDER_DISPLAY. The existing useModels visibility gates already
pass non-claude-code providers through, so no gate changes are needed — Super Admin
sees all models. Selecting any non-claude-code model routes the turn to the OpenCode
harness (Phase 1).

Default model stays 'claude-code'. 58 OpenCode Zen models currently list; curating to
a flagship subset is an easy follow-up if the full catalog is unwieldy.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-24 16:32:12 +00:00
co-authored by Claude Opus 4.8
parent ad32c7516e
commit 025c5dd38c
3 changed files with 49 additions and 4 deletions
+1 -1
View File
@@ -62,7 +62,7 @@ chatRouter.patch('/sessions/:id/title', async (ctx) => {
chatRouter.get('/models', async (ctx: Context) => {
try {
const models = await listChatModels();
const providerNames: Record<string, string> = { 'claude-code': 'Claude Code' };
const providerNames: Record<string, string> = { 'claude-code': 'Claude Code', opencode: 'OpenCode Zen' };
return ctx.json({ models, providerNames, hostHome: process.env.HOME ?? '' });
} catch (err) {
logger.error('Failed to list models', { error: String(err) });