Skip to content

perf(agent): per-request session effort override skips the runtime rebuild / 思考强度切换走每请求覆盖免重建 - #9866

Open
Linearl wants to merge 1 commit into
esengine:main-v2from
Linearl:perf/effort-per-request-override
Open

perf(agent): per-request session effort override skips the runtime rebuild / 思考强度切换走每请求覆盖免重建#9866
Linearl wants to merge 1 commit into
esengine:main-v2from
Linearl:perf/effort-per-request-override

Conversation

@Linearl

@Linearl Linearl commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Switching the reasoning effort no longer rebuilds the runtime when the running provider accepts per-request depth: Agent.SetSessionEffortOverride stores a session-scoped override and every sampling request carries it via the existing provider.Request.EffortOverride channel, so the switch costs milliseconds instead of a full build+swap (session snapshot, lease re-arm, provider re-init, history carry) — the multi-second stall users see in the effort menu.
  • Governor priority: a governor engaged mid-run wins over the session override (effortOverrideForRequest), so a running guard cannot be outbid by a session-level depth bump.
  • Conservative fallback: providers that cannot vary depth per request (no PerRequestEfforts probe / empty vocabulary) decline the override and the desktop switch falls back to today's exact rebuild path; recovery-forked sessions also decline on purpose, so their reanchor semantics (forked file sealed, fresh branch anchored) stay on the rebuild path.

Issues-Fixes

None.

Verification

  • go build ./... (root) and go build ./... (desktop module) — clean.
  • go test ./internal/agent -run "SessionEffortOverride|EffortOverrideForRequest|Governor|Sampling" -count=1 — ok. New tests: vocabulary gate (listed level accepted, out-of-vocabulary rejected, clear always succeeds), non-varying provider rejection, governor-beats-session priority.
  • go test ./internal/provider/openai -run Effort -count=1 — ok.
  • go test ./internal/control -run "Session|Controller" -count=1 — ok (controller forwards to the agent; nil executor declines).
  • go test . -run Effort -count=1 (desktop) — ok, including TestSetEffortForTabReanchorsDepthCapRecoveryBranch: a recovery-forked session declines the fast path and keeps today's rebuild + reanchor behavior.

Documentation-impact

None — no config keys, CLI flags, or docs surface changes. The effort switch behaves the same from the user's perspective (faster).

Cache-impact

None — the prompt bytes never change: EffortOverride only selects the reasoning-depth fields on the wire (reasoning_effort / thinking), and the openai adapter already resolved per-request overrides this way (see requestEffort, session_title/vision_summary per-request EffortOverride: "low"). Distinct requests after a switch were already cache-compatible in those paths.

Cache-guard

Not applicable — no system prompt, tool schema, or message-history changes; the override travels on the request object only.

System-prompt-review

None — no system prompt changes; effort affects reasoning-depth wire fields only.

Notes

…build

Switching the reasoning effort currently pays for the full desktop
build+swap rebuild (session snapshot, lease re-arm, provider re-init,
history carry) even though providers already resolve effort per request:
provider.Request.EffortOverride exists and the openai adapter resolves it
against the endpoint's effort vocabulary on every call.

Wire that existing channel to the UI switch. Agent.SetSessionEffortOverride
stores a session-scoped override (atomic.Value, following the
responseLanguage precedent) and accepts a level only when the running
provider lists it in its per-request vocabulary (new optional probe
PerRequestEfforts). Sampling requests merge it behind the governor's
engaged override so a running guard cannot be outbid by a session-level
depth bump. The desktop effort switch tries the fast path first and falls
back to the rebuild for providers or sessions that decline it —
recovery-forked sessions decline on purpose so their reanchor semantics
(forked file sealed, fresh branch anchored) stay on the rebuild path.

Frontends whose provider lacks per-request depth see no behavior change;
the fast path degrades to the exact rebuild flow they use today.
Copilot AI lite review requested due to automatic review settings September 6, 2026 16:21
@github-actions github-actions Bot added v2 Go rewrite (1.x) — main-v2 branch, active development desktop Wails desktop app (desktop/**) agent Core agent loop (internal/agent, internal/control) provider Model providers & selection (internal/provider) labels Sep 6, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new fast path misses state persistence and there are a couple of correctness/safety gaps (recovery-meta error handling and slice exposure) that should be addressed before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR introduces a session-scoped reasoning-effort override that can be applied per request (via provider.Request.EffortOverride) so effort switches can skip the expensive runtime rebuild when the active provider supports request-scoped effort vocabularies.

Changes:

  • Add Agent.SetSessionEffortOverride and request-time selection logic (effortOverrideForRequest) so the governor override still takes priority.
  • Expose provider capability via PerRequestEfforts() (OpenAI adapter) and plumb an override setter through control.Controller.
  • Add a desktop fast path in SetEffortForTab that attempts the no-rebuild override before falling back to the existing build+swap path; add agent tests for vocab gating and governor priority.
File summaries
File Description
internal/provider/openai/effort.go Exposes OpenAI endpoint request-scoped effort vocabulary via PerRequestEfforts().
internal/control/controller.go Adds Controller.SetSessionEffortOverride to forward session overrides to the executor agent.
internal/agent/sampling_request.go Switches sampling requests to use effortOverrideForRequest() instead of governor-only overrides.
internal/agent/effort_override.go Implements session-scoped override storage, provider vocab gating, recovery-branch rejection, and governor priority.
internal/agent/effort_override_test.go Adds tests for vocab gating, non-varying provider rejection, and governor priority.
internal/agent/agent.go Adds the sessionEffort field to the agent runtime state.
desktop/app.go Adds a per-request fast path for effort switching (no rebuild) with fallback to existing rebuild flow.
Review details
  • Files reviewed: 7/7 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread desktop/app.go
Comment on lines +9880 to +9883
a.mu.Lock()
tab.effort = &effort
a.mu.Unlock()
return nil
Comment on lines +44 to +48
if path := strings.TrimSpace(a.sess.path); path != "" {
if meta, ok, err := LoadBranchMeta(path); err == nil && ok && meta.Recovered {
return false
}
}
Comment on lines +114 to +119
// PerRequestEfforts reports the depth levels a request-scoped EffortOverride
// may take on this endpoint (see requestEffort). Nil or empty means the
// endpoint cannot vary depth per request, so frontends that fix effort at
// boot must keep using the configured depth (or rebuild the runtime) instead
// of writing a per-request override that would silently degrade on the wire.
func (c *client) PerRequestEfforts() []string { return c.requestEfforts }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent Core agent loop (internal/agent, internal/control) desktop Wails desktop app (desktop/**) provider Model providers & selection (internal/provider) v2 Go rewrite (1.x) — main-v2 branch, active development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants