Skip to content

fix: give the agent a per-turn effort recommendation - #25

Closed
BaconDroid wants to merge 6 commits into
ian-pascoe:mainfrom
BaconDroid:feat/effort-recommendation
Closed

BaconDroid wants to merge 6 commits into
ian-pascoe:mainfrom
BaconDroid:feat/effort-recommendation

Conversation

@BaconDroid

@BaconDroid BaconDroid commented Oct 19, 2026 •

Copy link
Copy Markdown

Summary

Addresses #22.

The report describes two failure modes: spurious set_reasoning_effort calls when the plugin pushed a separate imperative system message, and no calls at all when the guidance lived in AGENTS.md. #23 removes the second system message by merging into system[0]. This PR addresses the remaining behavior.

Changes

  • On every user turn, chat.message classifies the prompt (sharing src/complexity.ts with feat: select reasoning effort from request complexity #24) and stores a recommendation for the turn.
  • The system guidance now carries a concrete instruction instead of a generic imperative:
    • recommendation differs from the current level: This turn suggests high effort (current: low). Call set_reasoning_effort with high before proceeding.
    • recommendation matches: The current level fits this request; call set_reasoning_effort only if the work grows beyond it.
    • no recommendation: Call set_reasoning_effort only when the current level no longer fits the task.
  • The default prompt is shortened: the blanket "reassess every turn / never leave the level unchanged" wording is replaced with guidance that relies on the per-turn recommendation while keeping a mid-turn reassessment clause. This is the part aimed at the spurious calls.
  • The recommendation is cleared on session.idle, so a shell turn or a text-less turn cannot inherit the previous turn's advice.
  • With autoSelect enabled (feat: select reasoning effort from request complexity #24), the plugin manages the level and the prompt says so, so the tool becomes an explicit override.

Stacked on #23 and #24. This branch is based on feat/auto-effort; review/merge #23 and #24 first. The diff will shrink after they land.

Tests

  • Recommendation differs, matches, clears at the end of a turn, and survives a later text turn only when recomputed.
  • Managed-mode instruction when autoSelect is enabled.
  • pnpm verify passes (24 tests, format, lint, typecheck, build).

No prompt change can guarantee that a model calls a tool. This change makes the cue specific to the turn and removes the blanket instruction that correlated with spurious changes in the report.

Repeated set_reasoning_effort calls in one turn could reset to an
intermediate level, or cancel the reset entirely when the same level was
set twice, because the baseline was re-read after the override.

Keep the first reset target, read session history once per call with a
bounded query, cache provider variants, merge guidance into an existing
system prompt, and replace Zod config parsing with a small validator.
Fall back to the cached current level when the recent history window
carries no variant, and read model identity and variants from assistant
messages too. Reuse the SDK provider type for the cached provider list.
Add an opt-in autoSelect mode. The chat.message hook classifies each
user request and writes the chosen variant onto the message, which
OpenCode persists and uses for the turn. The level is carried across
turns until the agent changes it or the model changes.
Respect a variant supplied with the request and treat image-only prompts
as no signal. Document that autoSelect classifies the first request and
carries the level instead of reclassifying every turn.
Classify each user turn and inject a specific instruction: call the
tool with the recommended level when it differs, or do not call when
the current level fits. Replace the blanket reassessment guidance with
a shorter prompt that relies on the recommendation.
Clear the recommendation on session idle, keep mid-turn reassessment in
the default guidance, and honor explicit variants as an override only in
autoSelect. Raise the changeset to minor for the default prompt change.
@BaconDroid

Copy link
Copy Markdown
Author

Closing: depends on the classifier added in #24, which is being removed.

@BaconDroid BaconDroid closed this Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant