Problem:
- Clicking Terminate during streaming caused the entire chat view to blink
- Task would close, user pushed to home, then back into the task
- Cancel → Resume flow would grey the Resume button but not restart the loop
- Input would become disabled and messages couldn't be sent
Root causes:
1. Hard abort (abandoned=true) was disposing the task instance immediately
2. Provider was rehydrating a new task instance from disk after abort
3. Abort flags stayed set (abort=true) preventing loop resumption
4. No deterministic spinner stopping on cancellation
5. Streaming state wasn't reset on resume
Solution:
- Soft-interrupt: Cancel now uses abortTask(false) to keep instance alive
- No rehydration: Provider skips task recreation for user_cancelled aborts
- Resume pipeline: Added presentResumableAsk() for in-place resume flow
- Abort state reset: Clear abort flags and streaming state before resuming
- Spinner determinism: Inject cancelReason into last api_req_started
- Transactional UI: Pause state updates during checkpoint operations
Changes:
- Task.presentResumableAsk(): New method for soft-interrupt resume
- Task.resumeTaskFromHistory(): Reset abort/streaming state after user confirms
- Task.abortTask(): Distinguish soft (keep alive) vs hard abort (dispose)
- ClineProvider.cancelTask(): Soft abort + schedule presentResumableAsk()
- ClineProvider.onTaskAborted: Skip rehydration for user_cancelled
- ChatView: Handle cancelReason for deterministic streaming state
Tests:
- Task.presentResumableAsk.abort-reset.spec.ts: Verify abort flag reset
- ClineProvider.cancelTask.present-ask.spec.ts: Verify soft-interrupt flow
- Task.spec.ts: Updated abort semantics (soft vs hard)
Result:
- No UI flicker or navigation on Cancel
- Resume button successfully restarts the agent loop
- Input remains enabled throughout cancel/resume cycle
- Spinner stops deterministically on cancellation
- Task history stable, no duplicate entries
- Update McpView.tsx to use "logs" tab ID instead of "errors"
- Rename translation key from tabs.errors to tabs.logs in all locales
- Change empty state message from "No errors found" to "No logs yet"
This better reflects that the tab shows all server messages (info, warnings, errors), not just errors.
Fixes#8893
Co-authored-by: Roo Code <roomote@roocode.com>
* feat: Add supportsReasoning property for Z.ai GLM binary thinking mode
- Add supportsReasoning to ModelInfo schema for binary reasoning models
- Update GLM-4.5 and GLM-4.6 models to use supportsReasoning: true
- Implement thinking parameter support in ZAiHandler for Deep Thinking API
- Update ThinkingBudget component to show simple toggle for supportsReasoning models
- Add comprehensive tests for binary reasoning functionality
Closes#8465
* refactor: rename supportsReasoning to supportsReasoningBinary for clarity
- Rename supportsReasoning -> supportsReasoningBinary in model schema
- Update Z.AI GLM model configurations to use supportsReasoningBinary
- Update Z.AI provider logic in createStream and completePrompt methods
- Update ThinkingBudget UI component and tests
- Update all test comments and expectations
This change improves naming clarity by distinguishing between:
- supportsReasoningBinary: Simple on/off reasoning toggle
- supportsReasoningBudget: Advanced reasoning with token budget controls
- supportsReasoningEffort: Advanced reasoning with effort levels
- Add responsive breakpoint at 300px for compact view
- Icon correctly reflects state (X when off, ✓ when on) at all screen sizes
- Show abbreviated labels on very narrow screens (< 300px)
- Add triggerLabelOffShort translation key to all locales
Fixes issues from PR #8152:
- Icon always showing checkmark on narrow screens
- Breakpoint activating too early (was 400px)
- Incorrect Tailwind class ordering
* feat: add telemetry tracking to DismissibleUpsell component
- Added UPSELL_DISMISSED and UPSELL_CLICKED events to TelemetryEventName enum
- Updated DismissibleUpsell component to track clicks and dismissals with telemetry
- Added telemetry tests to DismissibleUpsell test suite
- Events include upsellId in the payload for tracking specific upsells
* refactor(webview): make handleDismiss synchronous in DismissibleUpsell
test(webview): add scenario where dismissOnClick=true without onClick tracks only UPSELL_DISMISSED; update tests; all tests passing locally
---------
Co-authored-by: Roo Code <roomote@roocode.com>