commanders run on Sonnet, not the account default
every new commander came up on whatever the owner last picked in a chat — Fable, currently. that default is chosen for interactive work, and a commander is the opposite: long-running, mostly repeating one settled job, and started by a button rather than by somebody thinking about which model they want. COMMANDER_DEFAULT_MODEL, in both places, because the two ways of starting a commander do not share code — the server's /commanders/new route and the detail component's own first turn. per-surface defaults belong in settings eventually. "commanders default to Sonnet" is the decision; this is where it lives until there is a better place for it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043
This commit is contained in:
@@ -47,6 +47,20 @@ import { snapshotClaudeUsage } from './usage-store';
|
||||
// Default model when no user preference is set
|
||||
export const DEFAULT_MODEL = 'claude-code';
|
||||
|
||||
/**
|
||||
* What a commander runs on, regardless of the account's default.
|
||||
*
|
||||
* A commander is long-running and mostly does the same settled thing over and over, so it is the one
|
||||
* surface where the account default — chosen for interactive work — is the wrong answer. Pinned here
|
||||
* rather than left to the picker so a commander created today does not depend on what the owner last
|
||||
* selected for a chat.
|
||||
*
|
||||
* Temporary in the sense that per-surface defaults belong in settings; permanent in the sense that
|
||||
* "commanders default to Sonnet" is the decision, and this is where it lives until there is a better
|
||||
* place for it.
|
||||
*/
|
||||
export const COMMANDER_DEFAULT_MODEL = 'claude-code/sonnet';
|
||||
|
||||
// Harness selection: the `claude-code` provider runs through the Claude sidecar; every other provider
|
||||
// (opencode/anthropic/openai/… — all `providerID/modelID` ids) runs through the OpenCode server.
|
||||
const isClaudeModel = (model: string): boolean => model.startsWith('claude-code');
|
||||
|
||||
@@ -28,7 +28,7 @@ import {
|
||||
type ChatIdentity,
|
||||
type ClaudeSessionSummary,
|
||||
} from '../chat/claude-sessions';
|
||||
import { collectRunningTasks, startClaudeTurn, getUserDefaultModel, DEFAULT_MODEL } from '../chat/websocket';
|
||||
import { collectRunningTasks, startClaudeTurn, COMMANDER_DEFAULT_MODEL } from '../chat/websocket';
|
||||
import {
|
||||
listCommandHqCategories,
|
||||
createCommandHqCategory,
|
||||
@@ -373,7 +373,8 @@ commandHqRouter.post('/commanders/new', async (ctx) => {
|
||||
if (credentialError) console.warn(`[command-hq] ${row.dirName}: no credential minted — ${credentialError}`);
|
||||
|
||||
const sessionId = randomUUID();
|
||||
const model = (await getUserDefaultModel(user.id)) || DEFAULT_MODEL;
|
||||
// Not the account default: a commander runs on Sonnet — see COMMANDER_DEFAULT_MODEL.
|
||||
const model = COMMANDER_DEFAULT_MODEL;
|
||||
|
||||
const outcome = await new Promise<{ ok: true; transcriptId: string } | { ok: false; error: string }>((resolve) => {
|
||||
// 30s covers a slow spawn (member login checks, a cold sidecar) without holding an HTTP connection
|
||||
|
||||
Reference in New Issue
Block a user