mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-07 16:09:43 +02:00
feat(claude): advisor tool support, per session and as an App Settings default
Claude Code's advisor tool (code.claude.com/docs/en/advisor) lets the session's main model consult a second, stronger model at decision points: before committing to an approach, on a recurring error, and before declaring a task done. Codeman can now start claude sessions with one. - `advisorModel` field on POST /api/sessions, /api/quick-start and /api/ralph-loop/start (fable, opus, sonnet or a full model id in those families; haiku cannot advise and is refused). Stored on the session and persisted, so respawn, boot restore and reboot restore keep it. Remote and docker quick-starts refuse it, as they refuse effort. - App Settings, Models, "Advisor" segment (Default / Sonnet / Opus / Fable), synced as `claudeAdvisorModel`. Run, resume and the Ralph wizard send it. Default sends nothing, leaving the CLI's own /advisor choice in charge. - Carried as the `advisorModel` key in the launch's single --settings JSON, merged with ultracode and the statusLine exporter, never the --advisor flag: `claude --advisor haiku` exits 1 at launch, which would leave a dead pane on every respawn, while the settings key degrades to no advisor. A launch without an advisor is byte-identical to before. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -169,6 +169,17 @@ Object.assign(CodemanApp.prototype, {
|
||||
return valid.includes(effort) ? effort : undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* Resolve the advisor model for new Claude sessions from global settings.
|
||||
* Returns 'fable' | 'opus' | 'sonnet', or undefined (= leave it to the CLI's own
|
||||
* /advisor choice). Sent as the `advisorModel` payload field; the backend merges it
|
||||
* into the launch's `claude --settings` JSON, so /advisor still switches it in-session.
|
||||
*/
|
||||
getAdvisorSetting(globalSettings) {
|
||||
const advisor = globalSettings?.claudeAdvisorModel;
|
||||
return ['fable', 'opus', 'sonnet'].includes(advisor) ? advisor : undefined;
|
||||
},
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
// Quick Start
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
@@ -1965,6 +1976,7 @@ Object.assign(CodemanApp.prototype, {
|
||||
const envOverrides = this.buildEnvOverrides(caseSettings, globalSettings);
|
||||
const hasEnvOverrides = Object.keys(envOverrides).length > 0;
|
||||
const effort = this.getEffortSetting(globalSettings);
|
||||
const advisorModel = this.getAdvisorSetting(globalSettings);
|
||||
// Explicit Claude Model choice (App Settings) wins over the legacy 1M Opus
|
||||
// toggles; both flow as `modelOverride` → the case's .claude/settings.local.json
|
||||
const useOpus1m = caseSettings.opusContext1m || globalSettings.opusContext1mEnabled;
|
||||
@@ -1980,6 +1992,7 @@ Object.assign(CodemanApp.prototype, {
|
||||
workingDir, name,
|
||||
...(hasEnvOverrides ? { envOverrides } : {}),
|
||||
...(effort ? { effort } : {}),
|
||||
...(advisorModel ? { advisorModel } : {}),
|
||||
...(modelOverride !== undefined ? { modelOverride } : {}),
|
||||
})
|
||||
}).then(r => r.json())
|
||||
|
||||
Reference in New Issue
Block a user