Summary
Cyrus currently has no way to configure the Claude Agent SDK's reasoning effort level (low / medium / high / max). The capability exists in every layer beneath cyrus, but the edge worker doesn't plumb it through.
Current state (v0.2.44)
| Layer |
Supports effort? |
| Claude Code CLI |
✅ --effort <level> |
@anthropic-ai/claude-agent-sdk |
✅ effort query option + extraArgs passthrough |
cyrus-claude-runner |
✅ Forwards config.extraArgs → SDK query options |
cyrus-edge-worker |
❌ Hardcodes extraArgs: { chrome: null } in RunnerConfigBuilder.ts |
So the whole stack could carry an effort value — cyrus just never reads one from config.
Also, RunnerSelectionService.determineRunnerSelection() only parses [agent=...] and [model=...] description tags — no effort tag.
Proposed change
Match the existing model selection precedence:
- Description tag —
[effort=low|medium|high|max] in the Linear issue description
- Issue label —
effort-low, effort-medium, effort-high, effort-max
- Per-repository config —
repository.extraArgs.effort (or a dedicated repository.effort field) in ~/.cyrus/config.json
- (Optional) Global default —
claudeDefaultEffort alongside claudeDefaultModel
Only applies to the Claude runner (the SDK's effort knob is Claude-specific).
Proposed code changes
RunnerSelectionService.ts — parse effort from description/labels and return it:
const descriptionEffortTagRaw = this.parseDescriptionTag(normalizedDescription, "effort");
const resolveEffortFromLabel = (lowercaseLabels: string[]) => {
for (const lvl of ["low", "medium", "high", "max"] as const) {
if (lowercaseLabels.includes(`effort-${lvl}`)) return lvl;
}
return undefined;
};
let effortOverride = (descriptionEffortTagRaw || "").toLowerCase().trim()
|| resolveEffortFromLabel(normalizedLabels);
if (effortOverride && !["low","medium","high","max"].includes(effortOverride)) {
effortOverride = undefined;
}
if (runnerType !== "claude") effortOverride = undefined;
return { runnerType, modelOverride, fallbackModelOverride, effortOverride };
RunnerConfigBuilder.ts — stop hardcoding extraArgs, merge from repo config and selector:
...(runnerType === "claude" && {
extraArgs: {
chrome: null,
...(input.repository.extraArgs || {}),
...(runnerSelection.effortOverride ? { effort: runnerSelection.effortOverride } : {}),
},
}),
This also unlocks repository.extraArgs as a general escape hatch for any future Claude Code CLI flag (--agent, --betas, etc.) without needing code changes each time.
Use cases
- A user on a Max plan wants Opus +
effort=max for heavy refactoring on one repo, and Sonnet + effort=low for routine triage on another.
- Per-issue: a one-off research task tagged
[effort=max] vs typical issues defaulting to high.
- Cost control: teams running many concurrent sessions can default to
effort=medium globally while letting specific hard issues opt into max via description tag.
Notes
I've applied this patch locally to cyrus-edge-worker/dist/ in my install and verified it works end-to-end with pm2 restart cyrus (status endpoint clean, no runtime errors). Happy to turn this into a PR if the approach looks right.
Summary
Cyrus currently has no way to configure the Claude Agent SDK's reasoning effort level (
low/medium/high/max). The capability exists in every layer beneath cyrus, but the edge worker doesn't plumb it through.Current state (v0.2.44)
--effort <level>@anthropic-ai/claude-agent-sdkeffortquery option +extraArgspassthroughcyrus-claude-runnerconfig.extraArgs→ SDK query optionscyrus-edge-workerextraArgs: { chrome: null }inRunnerConfigBuilder.tsSo the whole stack could carry an effort value — cyrus just never reads one from config.
Also,
RunnerSelectionService.determineRunnerSelection()only parses[agent=...]and[model=...]description tags — no effort tag.Proposed change
Match the existing
modelselection precedence:[effort=low|medium|high|max]in the Linear issue descriptioneffort-low,effort-medium,effort-high,effort-maxrepository.extraArgs.effort(or a dedicatedrepository.effortfield) in~/.cyrus/config.jsonclaudeDefaultEffortalongsideclaudeDefaultModelOnly applies to the Claude runner (the SDK's
effortknob is Claude-specific).Proposed code changes
RunnerSelectionService.ts— parse effort from description/labels and return it:RunnerConfigBuilder.ts— stop hardcoding extraArgs, merge from repo config and selector:This also unlocks
repository.extraArgsas a general escape hatch for any future Claude Code CLI flag (--agent,--betas, etc.) without needing code changes each time.Use cases
effort=maxfor heavy refactoring on one repo, and Sonnet +effort=lowfor routine triage on another.[effort=max]vs typical issues defaulting tohigh.effort=mediumglobally while letting specific hard issues opt intomaxvia description tag.Notes
I've applied this patch locally to
cyrus-edge-worker/dist/in my install and verified it works end-to-end withpm2 restart cyrus(status endpoint clean, no runtime errors). Happy to turn this into a PR if the approach looks right.