feat(dte): dynamic thinking effort (series PRs 1-5 + e2e addenda + F7) - #1379
Open
easonLiangWorldedtech wants to merge 124 commits into
Open
feat(dte): dynamic thinking effort (series PRs 1-5 + e2e addenda + F7)#1379easonLiangWorldedtech wants to merge 124 commits into
easonLiangWorldedtech wants to merge 124 commits into
Conversation
…nd adaptive effort envelope DTE series 2/5 (part of Zoo-Code-Org#1329). - ApiHandlerCreateMessageMetadata.reasoningEffort: per-request override channel - resolveEffectiveReasoningEffort: single shared resolution point (override > settings > model default) - AnthropicHandler: adaptive output_config.effort envelope in both requestParams branches (in-range only) - Task: setRuntimeThinkingEffort/getRuntimeThinkingEffort with in-memory apiConfiguration merge/restore, per-request metadata at all four createMessage sites, dispose() reset; never persisted
DTE series 2/5 — addresses the CodeRabbit review finding on Zoo-Code-Org#1338: when a task-local thinking-effort override is active, updateApiConfiguration() now re-captures the incoming profile's reasoningEffort as the restore value and re-applies the override on top of the new in-memory copy, so clearing the override restores the NEW profile value instead of the stale one. Additive: activation and clearing semantics are otherwise unchanged. Adds two regression tests (override active + profile switch restores new value; inactive updateApiConfiguration unchanged behavior).
DTE series 2/5 — addresses the CodeRabbit docstring-coverage warning on Zoo-Code-Org#1338 (33.33% < 80% across the functions touched by the diff): - AnthropicHandler.createMessage: documents the shared effective-effort resolution and the adaptive output_config.effort envelope (in-range only). - Task.dispose: documents centralized teardown incl. the transient task-local override reset. - Task.updateApiConfiguration: documents the override-preservation behavior (re-captured restore value + re-applied override on the new in-memory copy). Comment-only change: 30/30 patch lines and 10/10 branches unchanged; 317/317 tests and tsc --noEmit re-verified green.
…/dte-3-native-tool
Add the set_thinking_effort native tool (DTE series 3/5): the model adjusts its own per-turn thinking effort mid-task with no approval gate. - Guardrails: one-line chat notification (success or refusal), escalation cap (max 3 upward changes per task), A->B->A oscillation refusal, hard clamp to the model capability array (ties toward the lower level). - Gating: dynamicThinkingEffort experiment + model supportsReasoningEffort (non-empty array or true), evaluated at task start so the tool list stays stable within a task (prompt-cache safety). - Display: webview ChatRow one-line row (applied / oscillation / escalation refusal), i18n keys in all 17 locales; partial streaming updates the same line. - Tests: executor (clamp/cap/oscillation/no-op/no-approval/display), parser (partial + complete), dispatch, gating matrix, schema wiring, ChatRow display. Stacked on DTE PR-1 (experiment flag) and PR-2 (task-local runtime effort state). Closes Zoo-Code-Org#1330.
Address PR review feedback on set_thinking_effort (DTE series 3/5): - Executor: seed the per-task guard history with the task's effective baseline so returning from a changed value to the original baseline is refused as oscillation (A -> B -> A); existing no-op behavior preserved. - Parser: only build nativeArgs when effort AND reason are strings; a non-string payload now fails at parse time and cannot reach the executor. - Gating: a supportsReasoningEffort array that only lists 'disable' no longer exposes the tool (it could apply no level). - i18n: translate the new thinkingEffort chat strings into all 17 non-English webview locales (placeholders preserved). - Tests: regression tests for each change plus branch-coverage for the previously partial lines (non-string args, 'disable'-only capability, baseline oscillation, partial streaming without params, description fallback, capability robustness). All touched patch lines are now fully branch-covered (codecov patch partials resolved). CodeRabbit: Zoo-Code-Org#1354
… post-mode-switch revalidation, ask prefill normalization)
…e, in-chat display
…tadata in say-rejection test
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.
Dynamic Thinking Effort — reviewer guide (trial VSIX included)
1. What's in the build
feat/dte-1-experimentdynamicThinkingEffortexperimental settingfeat/dte-2-task-statefeat/dte-3-native-toolset_thinking_effortnative tool (model-driven, no approval)feat/dte-4-webview-uifeat/dte-5-orchestratornew_taskthinking_effort (subtask start effort)feat/dte-3-e2eset_thinking_effortmid-task workflowfeat/dte-5-e2enew_taskthinking_effortfeat/dte-7-f7-openai-compatPatch coverage (combined trial tree, Codecov on
27a2e97df): 97.31% (checkcodecov/patchSuccessful, target 80% — pass) · webview patch 97.67% (checkcodecov/patch/webview-patch, target 70% — pass). The DTE diff has no fully-missing lines — Codecov's 5 missing lines sit on files outside this PR's diff (stale-base artifact) and the DTE files carry 5 partial branches only; line-level detail in §7.Trial branch:
feat/dte-trial-all@27a2e97df(all 8 heads merged, additive; includes the CodeRabbit review fixes, §7). The installable VSIX is the CI-builtzoo-code-vsix-pr-1379artifact from this PR's Code QA run on the current head — it already includes the review fixes (§2).2. Install (5 minutes)
Download the CI build from the PR's Code QA run (built on head
27a2e97df; the zip containszoo-code-3.80.0.vsix):zoo-code-vsix-pr-1379artifact (zip: 33,684,498 bytes · zip SHA256307100E9C745EEE1BC2A7040A7EC0F6185A5006A5AE70A2B276014927346926D). CI artifacts are retained for 7 days — if the link has expired, re-run theCode QA Roo Codeworkflow on this PR to get a fresh build at the same head.Install it:
…or in VS Code: Extensions view → ⋯ menu → Install from VSIX… → pick the file.
Reload the window (Command Palette →
Developer: Reload Window).Open the Zoo Code panel — you're ready.
3. How to use DTE
A. Managed providers (Anthropic / OpenAI / DeepSeek / …)
set_thinking_effortto change the effort itself (you can also change it at any time with the composer toggle). The change is task-local — it applies from the next request only and is never written to settings; it is stored with the task (like the task mode) and restored when the task is reopened from history.\n\n > Note: the model can only call the tool when the Dynamic Thinking Effort experimental setting is enabled (see 4.5) — the composer toggle, header chip and in-chat display do not require it.new_taskcan be given a starting effort; if you leave it unset it inherits the parent's effective effort.B. Self-hosted / OpenAI-compatible (F7)
supportedEffortLevelsmulti-select to declare which effort levels your model supports.C. Effort resolution (precedence, strongest first)
task-local override(composer selection,set_thinking_effort, subtask start effort fromnew_task— all stored with the task and restored when it reopens; none is ever written to settings) →settings.reasoningEffort→model default.disableis a UI off-switch (not a level, not sent).adaptiveis Anthropic's model-decides soft signal.4. New UI surfaces — screenshots & guide
Every new DTE surface, what it is, where it appears, and how to use it. (Captured from the real webview components; light + dark themes.)
4.1 Composer thinking-effort toggle (PR 4/5)
Bottom bar of the chat composer, next to the API-config selector. Renders only for models that advertise per-request effort support (registry capability, or an F7 declaration — see 4.6). The chip shows the current effective effort; open it to switch the task-local effort — the change applies from the next request and is never persisted to settings. If no task is open yet, the selection is parked and applied to the next top-level task you start (when that task's model supports the level; a stale selection never leaks into a later task).
Dark: menu · resting
4.2 Task header chip (PR 4/5)
Sits in the task header (top of the chat, next to the task title). Shows the current effective effort plus a source badge so you can tell where it came from:
Dark: you · default
4.3 In-chat effort display (PR 3/5 + 4/5)
One-line entries in the chat whenever the effort changes, so the switch is visible in the conversation:
set_thinking_effortwith a reason)Dark: in-chat lines
4.4 Settings — supported reasoning effort levels (F7, self-hosted)
New control in Settings → your OpenAI-compatible profile (custom OpenAI endpoint, LM Studio, Ollama, vLLM, SGLang). Self-hosted models don't advertise effort capability, so declare the levels your model accepts — this unlocks the whole DTE feature set for that profile. Values buffer in the settings form and persist on Save.
Dark: declared · undeclared
4.5 Settings — experimental toggle (PR 1/5)
Settings → Experimental → Dynamic Thinking Effort. This toggle gates model-driven mid-task switching only — when it is on, capable models are given the
set_thinking_efforttool so the model itself can change the effort during a task. The UI surfaces (composer toggle, header chip, in-chat display,new_taskselector, F7 settings) are gated by model capability, not by this experiment — they render without it. Turn it on to try the model-driven flow (step 4 of §3).Dark: experimental
4.6 Composer toggle — self-hosted model with F7 declaration (F7 + 4/5)
The same composer toggle for a self-hosted OpenAI-compatible model (Qwen3.8:27B) whose effort levels were declared in 4.4 — the declared levels appear in the menu (webview capability fill-in).
Dark: menu · resting
4.7 new_task start-effort selector (PR 5/5)
When the orchestrator asks to start a subtask (
new_task), the ask block shows a small Brain-icon effort selector next to the prompt (only when the target model supports effort). It is pre-filled with the parent task's effective effort and can be switched before entering the subtask; leave it as-is to inherit. (Rendered inline in the ask bar — see the e2e addendum #1356 for the wire-level proof.)5. Provider support & thinking-effort options
Which providers wire thinking effort into the request, the levels they accept, and the wire shape:
low · medium · high · xhigh · max(out-of-range → omitted → API default)output_config.effort(adaptive envelope)low · medium · high(model default + selected)reasoning_effort{ effort }supported_parametersminimal · low · medium · high(effort) /thinkingBudget(2.5)thinkingConfig.thinkingLevellow · high · maxreasoning_effortlow · medium · highreasoning: { effort }none · minimal · low · medium · high · xhigh · maxreasoning_effort+thinkingtogglereasoning: { enabled, effort }low · medium · high(or model-declared)reasoning_effortlow · medium · highreasoning_effortminimal · low · medium · high · xhigh · maxreasoning_effort(extended enum)low · medium · highreasoning_effortlow · medium · high(allow-listed)reasoning_effortlow · medium · high(allow-listed)reasoning_effortlow/medium/high(xhigh/max→high)think(bool or level)6. What to verify during the trial
set_thinking_effortmid-task: applied / no-op / refused transitions behave correctly (escalation cap = max 3 upward changes per task + oscillation refusal). Requires the DTE experiment enabled (4.5).new_task: explicit start effort honored; unset inherits the parent's effective effort.supportedEffortLevelson a self-hosted profile unlocks the UI; undeclared profiles are unchanged.Known limitations (by design, for this trial):
thinkwire — see §5).adaptiveis a soft guidance signal, not a concrete level.7. Provenance
feat/dte-trial-all@27a2e97df(fork).zoo-code-vsix-pr-1379(zip) from the Code QA run 32976523650 on head27a2e97df— zip SHA256307100E9C745EEE1BC2A7040A7EC0F6185A5006A5AE70A2B276014927346926D(33,684,498 bytes, 7-day retention). The earlier fork-release build (head310f0da97, VSIX SHA25604F6B33B847101E203CA098B2381087EA4C324B9DF904F90CDDADB007D9E7594) is superseded; the §4 UI screenshots remain hosted on that fork release.01394aeea+77ec064d3(cleared-effort persistence through the history-store merge; pre-dispose effort snapshot on the abort final save), feat(orchestrator): new_task thinking_effort — subtask start effort, switchable before entering (DTE series 5/5) #13552ab330e53+6eba686c1(unsupported-modelthinking_effortwording; capability-level normalization), feat(webview): thinking effort surfaces — header chip, composer toggle, in-chat display (DTE series 4/5) #135994928c2f5(typed webview spec doubles), test(e2e): set_thinking_effort mid-task workflow — e2e coverage (DTE series 3/5 addendum) #13617aeec7938+0b335c682(flow-scoped e2e fixtures; predicate-scoped continuation turns), feat(settings): let OpenAI-compatible profiles declare supported reasoning effort levels (DTE F7) #136662b3ba56c+65ee7b5e6(nl settings typo; native-Ollama per-request override threading).codecov/patchSuccessful, target 80% — pass) and 97.67% webview patch (checkcodecov/patch/webview-patch, target 70% — pass) on head27a2e97df; the DTE diff has zero fully-missing lines — Codecov's 5 missing lines are all on files not in the PR diff (its diff base is the branch fork point, so upstream main commits feat: Add Read+Write allowlists #1274/fix(openai-codex): complete prompts over the streaming transport #1243/[Fix] Terminal startup failures can leave commands unresolved #1351/[Fix] Background service failures can surface as unhandled rejections #1352 that landed after the fork count as "changes"), and the DTE files carry 5 partial branches only (ClineProvider.ts x3, webviewMessageHandler.ts x2)).Summary by CodeRabbit