Skip to content

fix(ThinkingBudget): extract maxOutputTokensControl to resolve undefined reference in binary reasoning path#332

Open
proyectoauraorg wants to merge 2 commits into
Zoo-Code-Org:mainfrom
proyectoauraorg:fix/thinking-budget-max-output-tokens
Open

fix(ThinkingBudget): extract maxOutputTokensControl to resolve undefined reference in binary reasoning path#332
proyectoauraorg wants to merge 2 commits into
Zoo-Code-Org:mainfrom
proyectoauraorg:fix/thinking-budget-max-output-tokens

Conversation

@proyectoauraorg
Copy link
Copy Markdown
Contributor

@proyectoauraorg proyectoauraorg commented May 26, 2026

Summary

Extracts the maxOutputTokensControl JSX fragment as a named variable declared before both the binary reasoning and budget reasoning conditional branches in ThinkingBudget.tsx.

This fixes a scoping issue where the max output tokens slider was only defined inside the budget reasoning block, making it unavailable (and would crash at runtime) for models using supportsReasoningBinary (binary reasoning toggle).

Changes

  • Extracted maxOutputTokensControl as a standalone JSX variable at line 167, before the binary/budget conditional branches
  • Added {maxOutputTokensControl} inside the binary reasoning <div> so the slider appears for both reasoning modes

Motivation

This fix addresses a bug reported in PR #274 by @edelauna: models using binary reasoning mode (e.g., Zhipu GLM via supportsReasoningBinary) could not configure modelMaxTokens because the slider control was scoped only within the budget reasoning conditional path.

Related

  • Fixes issue described in PR #274
  • Addresses @edelauna's code review comment about modelMaxTokens bug

Summary by CodeRabbit

  • New Features
    • Thinking budget settings now show the max output‑tokens control in the binary reasoning option when reasoning effort is enabled.
  • Tests
    • Added tests covering binary reasoning: verifies the reasoning toggle shows the slider only when enabled and that adjusting the slider updates the model output‑token setting.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8ddad80a-7048-4a6c-88f2-cffe2bc8edbe

📥 Commits

Reviewing files that changed from the base of the PR and between 0801635 and 21ece1c.

📒 Files selected for processing (2)
  • webview-ui/src/components/settings/ThinkingBudget.tsx
  • webview-ui/src/components/settings/__tests__/ThinkingBudget.spec.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • webview-ui/src/components/settings/ThinkingBudget.tsx

📝 Walkthrough

Walkthrough

ThinkingBudget extracts a reusable maxOutputTokensControl JSX fragment (label + slider for modelMaxTokens) and integrates it into the binary reasoning UI branch. The slider computes its maximum from model capabilities and allows users to configure token limits alongside the reasoning toggle.

Changes

Binary Reasoning Tokens Control

Layer / File(s) Summary
Shared max tokens control and binary reasoning integration
webview-ui/src/components/settings/ThinkingBudget.tsx
A maxOutputTokensControl fragment is defined with a "max tokens" label and Slider bound to setApiConfigurationField("modelMaxTokens", ...), computing slider bounds from modelInfo.maxTokens, customMaxOutputTokens, and DEFAULT_HYBRID_REASONING_MODEL_MAX_TOKENS. The fragment is then rendered in the binary reasoning conditional branch to expose token configuration alongside the reasoning enable/disable checkbox.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A slider hops into binary's nest,
max tokens now reign from east to west,
shared control—one fragment, reused with care,
reasoning and budgets dance a pair! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description is well-structured with summary, changes, and motivation sections. However, the required template sections (Related GitHub Issue with Closes number, Test Procedure, Pre-Submission Checklist) are not completed. Complete the missing template sections: add 'Closes: #' reference, detail test procedure steps, and fill out the pre-submission checklist to confirm quality criteria are met.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main fix: extracting a JSX fragment to resolve a scoping issue in the binary reasoning path.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

webview-ui/src/components/settings/ThinkingBudget.tsx

ESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox.

webview-ui/src/components/settings/__tests__/ThinkingBudget.spec.tsx

ESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 26, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
webview-ui/src/components/settings/ThinkingBudget.tsx (1)

220-235: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Reuse the extracted maxOutputTokensControl to eliminate duplication.

The slider markup here is identical to the extracted maxOutputTokensControl defined at lines 167-186. Reusing the extracted control ensures a single source of truth and simplifies future maintenance.

♻️ Proposed refactor to reuse extracted control
-			<div className="flex flex-col gap-1">
-				<div className="font-medium">{t("settings:thinkingBudget.maxTokens")}</div>
-				<div className="flex items-center gap-1">
-					<Slider
-						min={8192}
-						max={Math.max(
-							modelInfo.maxTokens || 8192,
-							customMaxOutputTokens,
-							DEFAULT_HYBRID_REASONING_MODEL_MAX_TOKENS,
-						)}
-						step={1024}
-						value={[customMaxOutputTokens]}
-						onValueChange={([value]) => setApiConfigurationField("modelMaxTokens", value)}
-					/>
-					<div className="w-12 text-sm text-center">{customMaxOutputTokens}</div>
-				</div>
-			</div>
+			{maxOutputTokensControl}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webview-ui/src/components/settings/ThinkingBudget.tsx` around lines 220 -
235, The duplicated Slider block should be replaced with the already extracted
maxOutputTokensControl to avoid duplication: locate the JSX where
customMaxOutputTokens, modelInfo, DEFAULT_HYBRID_REASONING_MODEL_MAX_TOKENS,
Slider and setApiConfigurationField are used (the current Slider block in
ThinkingBudget.tsx) and swap that markup to render the pre-defined
maxOutputTokensControl variable/component instead, ensuring the same props/state
(customMaxOutputTokens and setApiConfigurationField) remain connected so
behavior is unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@webview-ui/src/components/settings/ThinkingBudget.tsx`:
- Around line 167-186: Add a data-testid to the maxOutputTokensControl slider
container (the JSX that renders Slider inside maxOutputTokensControl) so tests
can target it, ensure the Slider component props (min, max calculation using
modelInfo.maxTokens, customMaxOutputTokens,
DEFAULT_HYBRID_REASONING_MODEL_MAX_TOKENS, step, value and onValueChange) remain
unchanged, and then add Vitest React tests under webview-ui/src/**/__tests__
that render the binary reasoning branch and assert: the slider element (by the
data-testid) is present, changing its value triggers
setApiConfigurationField("modelMaxTokens", ...) with the new value, and the
computed max bound respects modelInfo.maxTokens vs customMaxOutputTokens vs
DEFAULT_HYBRID_REASONING_MODEL_MAX_TOKENS.

---

Outside diff comments:
In `@webview-ui/src/components/settings/ThinkingBudget.tsx`:
- Around line 220-235: The duplicated Slider block should be replaced with the
already extracted maxOutputTokensControl to avoid duplication: locate the JSX
where customMaxOutputTokens, modelInfo,
DEFAULT_HYBRID_REASONING_MODEL_MAX_TOKENS, Slider and setApiConfigurationField
are used (the current Slider block in ThinkingBudget.tsx) and swap that markup
to render the pre-defined maxOutputTokensControl variable/component instead,
ensuring the same props/state (customMaxOutputTokens and
setApiConfigurationField) remain connected so behavior is unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 16a179b8-3c4a-4a96-8192-5fce85e035f4

📥 Commits

Reviewing files that changed from the base of the PR and between b761a0a and 0801635.

📒 Files selected for processing (1)
  • webview-ui/src/components/settings/ThinkingBudget.tsx

Comment on lines +167 to +186
// Max output tokens control used by both binary reasoning and budget reasoning paths.
const maxOutputTokensControl = (
<div className="flex flex-col gap-1">
<div className="font-medium">{t("settings:thinkingBudget.maxTokens")}</div>
<div className="flex items-center gap-1">
<Slider
min={8192}
max={Math.max(
modelInfo.maxTokens || 8192,
customMaxOutputTokens,
DEFAULT_HYBRID_REASONING_MODEL_MAX_TOKENS,
)}
step={1024}
value={[customMaxOutputTokens]}
onValueChange={([value]) => setApiConfigurationField("modelMaxTokens", value)}
/>
<div className="w-12 text-sm text-center">{customMaxOutputTokens}</div>
</div>
</div>
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy lift

Add test coverage and data-testid for the new max tokens slider.

The extracted maxOutputTokensControl is now rendered in the binary reasoning branch (line 199), introducing new component rendering and prop wiring behavior. Consider adding a data-testid attribute to the slider container to facilitate testing, and adding Vitest test coverage under webview-ui/src/**/__tests__ to verify:

  • Slider renders correctly for binary reasoning models
  • Value changes call setApiConfigurationField("modelMaxTokens", ...) correctly
  • Slider bounds respect model capabilities

As per coding guidelines, prefer local webview-ui tests for React/webview behavior such as component rendering, local state, hooks, form dirty-state, validation, or prop wiring.

📋 Example: Adding data-testid
 const maxOutputTokensControl = (
-	<div className="flex flex-col gap-1">
+	<div className="flex flex-col gap-1" data-testid="max-output-tokens">
 		<div className="font-medium">{t("settings:thinkingBudget.maxTokens")}</div>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Max output tokens control used by both binary reasoning and budget reasoning paths.
const maxOutputTokensControl = (
<div className="flex flex-col gap-1">
<div className="font-medium">{t("settings:thinkingBudget.maxTokens")}</div>
<div className="flex items-center gap-1">
<Slider
min={8192}
max={Math.max(
modelInfo.maxTokens || 8192,
customMaxOutputTokens,
DEFAULT_HYBRID_REASONING_MODEL_MAX_TOKENS,
)}
step={1024}
value={[customMaxOutputTokens]}
onValueChange={([value]) => setApiConfigurationField("modelMaxTokens", value)}
/>
<div className="w-12 text-sm text-center">{customMaxOutputTokens}</div>
</div>
</div>
)
// Max output tokens control used by both binary reasoning and budget reasoning paths.
const maxOutputTokensControl = (
<div className="flex flex-col gap-1" data-testid="max-output-tokens">
<div className="font-medium">{t("settings:thinkingBudget.maxTokens")}</div>
<div className="flex items-center gap-1">
<Slider
min={8192}
max={Math.max(
modelInfo.maxTokens || 8192,
customMaxOutputTokens,
DEFAULT_HYBRID_REASONING_MODEL_MAX_TOKENS,
)}
step={1024}
value={[customMaxOutputTokens]}
onValueChange={([value]) => setApiConfigurationField("modelMaxTokens", value)}
/>
<div className="w-12 text-sm text-center">{customMaxOutputTokens}</div>
</div>
</div>
)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webview-ui/src/components/settings/ThinkingBudget.tsx` around lines 167 -
186, Add a data-testid to the maxOutputTokensControl slider container (the JSX
that renders Slider inside maxOutputTokensControl) so tests can target it,
ensure the Slider component props (min, max calculation using
modelInfo.maxTokens, customMaxOutputTokens,
DEFAULT_HYBRID_REASONING_MODEL_MAX_TOKENS, step, value and onValueChange) remain
unchanged, and then add Vitest React tests under webview-ui/src/**/__tests__
that render the binary reasoning branch and assert: the slider element (by the
data-testid) is present, changing its value triggers
setApiConfigurationField("modelMaxTokens", ...) with the new value, and the
computed max bound respects modelInfo.maxTokens vs customMaxOutputTokens vs
DEFAULT_HYBRID_REASONING_MODEL_MAX_TOKENS.

Copy link
Copy Markdown
Contributor

@edelauna edelauna left a comment

Choose a reason for hiding this comment

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

Nice - thanks for adding this, would it be possible to write an e2e or integration test verifying the component works as intended?

Also could you include a screenshot

Comment thread webview-ui/src/components/settings/ThinkingBudget.tsx Outdated
In the binary-reasoning path the max-output-tokens slider rendered even with
reasoning off, but getModelMaxOutputTokens then ignores the value (returns the
model default), so the control was interactive yet silently ignored. Guard it
with enableReasoningEffort to match the budget path, and add tests covering both
states. Addresses PR Zoo-Code-Org#332 review (edelauna).
@proyectoauraorg
Copy link
Copy Markdown
Contributor Author

Applied your suggestion — the max-output-tokens slider is now gated behind enableReasoningEffort in the binary-reasoning path, so it no longer appears interactive while being silently ignored by getModelMaxOutputTokens. Added tests covering both states (hidden when reasoning is off, shown + wired when on). Screenshot incoming. Thanks @edelauna! 🦓

return null
}

// Max output tokens control used by both binary reasoning and budget reasoning paths.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The comment says "used by both binary reasoning and budget reasoning paths", but the budget path (around line 222) still has its own copy of this same slider JSX. Could maxOutputTokensControl replace that block there too?

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.

2 participants