Cron/hook thinking-effort: downgrade only under OAuth proxy#14
Merged
Conversation
Previous version added `agent.cron_thinking` and `agent.cron_effort` config fields, both defaulting to `high`, applied to every cron/hook session regardless of provider. That changed behavior for API users who configure `effort=max` / `thinking=max` and accept it on every model — they got silently downgraded. Artem's review on ClickHouse#129: keep `max` by default and switch to `high` only when OAuth subscription is in use. OAuth in nerve is gated by the local cli-proxy-api wrapping the user's subscription credentials — i.e. `config.proxy.enabled`. The helper now reads that flag and only downgrades when source is cron/hook AND proxy is enabled. API users (no proxy) keep their configured value untouched, even for cron sessions. Changes: * `nerve/config.py`: remove `cron_thinking` / `cron_effort` fields and from_dict entries. Defaults stay at `max` / `max`. * `nerve/agent/engine.py`: rewrite `_select_thinking_effort` to take the full Config (not just agent_config) and cap `max` -> `high` for cron/hook only when `config.proxy.enabled`. Update the single call site. * `nerve/bootstrap.py`: remove the two SetupWizard defaults. * `config.example.yaml`: drop the two keys, replace comment with a note that the cap is automatic under OAuth. * `docs/config.md`: drop the two doc rows, fold the OAuth+cron note into the existing `thinking` / `effort` rows. * `tests/test_engine_options.py`: rewrite around the new OAuth gate. 21 tests covering OAuth on/off × cron/hook/interactive × max/lower values, plus the from_dict backwards-compat (legacy cron_thinking/ cron_effort keys are silently ignored). Tests: 21/21 in tests/test_engine_options.py. Full suite: 1306 passed, 2 skipped, 0 failed. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Addresses the review feedback on ClickHouse/nerve#129:
The original implementation introduced
agent.cron_thinkingandagent.cron_effortconfig fields defaulting tohigh, applied unconditionally to every cron/hook session. That silently downgraded API users who explicitly configureeffort=max/thinking=maxand acceptmaxon every model.Fix
OAuth in nerve is gated by the local cli-proxy-api wrapping the user's subscription credentials —
config.proxy.enabledis the single source of truth. The helper now reads that flag and only downgrades when the session is cron/hook AND proxy is enabled. API users (no proxy) and interactive sessions keep their configured value unchanged.Changes:
nerve/config.py— removecron_thinking/cron_effortfields fromAgentConfigand the matchingfrom_dictlines. Defaults stay atthinking=max/effort=maxfor everyone.nerve/agent/engine.py—_select_thinking_effort(config, source)now takes the fullNerveConfig(wasAgentConfig) and applies a max-only cap: whensource in ("cron", "hook")andconfig.proxy.enabled,max→high(lower values pass through). Single call site updated.nerve/bootstrap.py— drop the twoSetupWizarddefaults.config.example.yaml— drop the two keys; replace the multi-line comment with a note that the cap is automatic under OAuth.docs/config.md— drop the two doc rows; fold the OAuth+cron caveat into the existingthinking/effortrows.Composes cleanly with the existing model-aware
_effective_effort(which already caps Sonnet athigh) — this layer handles thethinkingside (which is otherwise rejected by the CLI as a string-levelmax) and is explicit about the OAuth trigger.Tests
tests/test_engine_options.pyrewritten around the OAuth gate (21 tests, all passing):cron/hook+max,max→("high","high")(the bug being fixed).cron/hook+ lower values → unchanged (cap, not force).cron/hook+ mixed → each knob capped independently.web/telegram/discord/api/"") +max,max→ unchanged (main model accepts max under OAuth).max,max→ unchanged (Artem's exact requirement).AgentConfig.from_dict({"cron_thinking": "high", "cron_effort": "high"})silently ignores the legacy keys (backwards-compat).AgentConfigno longer hascron_thinking/cron_effortattributes (asserted withhasattr).Verification
pytest tests/test_engine_options.py -v— 21/21 pass.pytest -q— 1306 passed, 2 skipped, 0 failed.Notes for the upstream PR
Phase 1: this PR opens against the fork (
constkolesnyak/nerve:main) for review. Phase 2 (separate) will push the same change toupstream/cron-effort-oauthand updateClickHouse/nerve#129.🤖 Generated with Claude Code