fix(engine): pin evaluator EffortOff, inherit summarizer session effort - #125
Conversation
engine/goal.go's evaluator request and engine/compact.go's compaction summary request never set provider.Request.Effort, so both ran at EffortUnset. On openaicompat, unset omits reasoning_effort, and some gateway models reason by default, burning the evaluator's 256-token budget on reasoning before it emits a verdict. The evaluator is a classifier: pin message.EffortOff, never inherit the session's level. The summarizer is a writing task: inherit the session's current effort via Session.Effort(). Fixes #124
📦 Previous Review (superseded by newer review)Claude finished @andybons's task in 4m 6s —— View job Review complete
The evaluator change ( One substantive issue on the summarizer side, filed inline on Having Suggested direction: clamp the summarizer effort so the thinking budget can't exceed the summary cap, rather than forwarding Nothing else flagged — the diff is small, tests follow the TDD/red-verify rules, and AGENTS.md was updated in the same commit. |
Round-1 review of PR #125 found the evaluator's new comment and AGENTS.md overclaimed EffortOff's effect on openai Responses: reasoningEffort omits the reasoning object for EffortOff exactly as it does for EffortUnset, so a gpt-5-class model still reasons by default there. Correct the claim and name the residual explicitly. Also document two residuals the summarizer's effort inheritance surfaces (a non-off level can bypass compactionMaxTokens; folded history can newly hit the anthropic enable-direction thinking hazard) and file them as follow-ups (#126, #127) rather than expand this PR's scope.
📦 Previous Review (superseded by newer review)Claude finished @andybons's task in 3m 37s —— View job Review: PR #125 — pin evaluator EffortOff, inherit summarizer session effort
Verdict: LGTM. The two-way split is correct, well-tested, and the one real tradeoff is explicitly documented per AGENTS.md scope discipline. No blocking issues. What the change does right
On the prior review finding (thinking-budget vs the 1024 summary cap)The earlier review is right that a non-off effort lets the anthropic adapter bump
Minor / optional
Nothing here needs to change before merge. The follow-up issue for the summarizer cap/StopReason guard is the correct disposition. |
… notes Round-2 review of PR #125 found the residual notes for issues #126 and #127 named neither issue number and did not state the output-cap consequence in concrete terms. Add both citations and name the consequence: a cap raised from 1024 to ~20480 tokens at EffortHigh delivers far less context reduction, at the layer whose own failure runs to a hard overflow that clears an active goal.
|
Claude finished @andybons's task in 4m 38s —— View job Review complete
The production change is two lines: Evaluator change — correct and safe. The evaluator is a classifier with a 256-token budget; pinning Summarizer change — carries two documented residuals, both deferred; neither blocks merge. I re-derived both against the code and confirmed the prior rounds' conclusions:
Testing. The two new tests assert the I'm not filing new inline comments — the existing threads on One optional nit if you want to tighten the note: the AGENTS.md "Reasoning effort" residual for #126 states openaicompat "applies no cap floor at all" — true — but readers may miss that the silent part is the absent |
Summary
runEvaluator,engine/goal.go) and the compaction summarizer (runCompactionSummary,engine/compact.go) never setprovider.Request.Effort, so both ran atEffortUnsetregardless of the session's effort level.reasoning_effort, and several gateway models (kimi-k3, deepseek-v4) reason by default — the evaluator'sMaxTokens256 budget could be mostly spent on reasoning before it ever emitsMET/NOT MET.message.EffortOffunconditionally. The summarizer is a writing task, so it inherits the session's current effort viaSession.Effort().Test plan
TestPursueGoalEvaluatorRequestPinsEffortOff(engine/goal_test.go) drivesPursueGoalend to end with a fake provider, asserts the evaluator request'sEffort == EffortOffeven when the session's own effort is set toEffortHigh.TestCompactSummaryRequestInheritsSessionEffort(engine/compact_test.go) setsSetEffort(EffortMedium), drivesSession.Compactend to end, asserts the summarizer request'sEffort == EffortMedium.Effort:field (in isolation) fails only its own test, for the expected reason.go build ./...,go vet ./...,go test -race ./...all green.Fixes #124