Skip to content

Conversation

@hannesrudolph
Copy link
Collaborator

@hannesrudolph hannesrudolph commented Dec 4, 2025

Summary

Implements the proposal from docs/proposals/message-manager-layer.md.

This introduces a MessageManager class that centralizes all conversation rewind operations, ensuring consistent handling of both UI (clineMessages) and API (apiConversationHistory) message histories.

Problem Solved

The codebase previously had two separate code paths for removing messages from conversation history:

  1. When restoring a checkpoint from before a context-management event, the API history is now properly rehydrated. Previously, messages tagged with condenseParent or truncationParent would remain hidden even though their parent Summary/marker no longer existed. Now, cleanupAfterTruncation() properly removes these orphaned tags, making the condensed/truncated messages visible again.
  2. Regular delete/edit operations via removeMessagesThisAndSubsequent() in webviewMessageHandler.ts
  3. Checkpoint restore operations via checkpointRestore() in checkpoints/index.ts

These paths handled message removal differently, leading to potential inconsistencies in how context-management events (condensing, truncation) were processed.

Key Bug Fix

Checkpoint restore now properly handles context-management events:

  • ✅ Collects condenseIds from removed condense_context messages
  • ✅ Collects truncationIds from removed sliding_window_truncation messages
  • ✅ Removes orphaned Summary messages from API history
  • ✅ Removes orphaned truncation markers from API history
  • ✅ Calls cleanupAfterTruncation() to clear orphaned parent tags

Changes

New Files

File Description
src/core/message-manager/index.ts MessageManager class with rewindToTimestamp(), rewindToIndex(), and internal methods
src/core/message-manager/index.spec.ts 22 comprehensive unit tests

Modified Files

File Changes
src/core/webview/webviewMessageHandler.ts Replaced 79-line inline removeMessagesThisAndSubsequent() with MessageManager calls
src/core/checkpoints/index.ts Refactored to use MessageManager (the critical bug fix)
src/core/task/Task.ts Added messageManager getter with lazy initialization
src/core/webview/__tests__/webviewMessageHandler.delete.spec.ts Updated 1 test for timestamp-based behavior

Testing

  • All 4508 tests pass with no regressions
  • 22 new MessageManager unit tests cover:
    • Basic rewind operations
    • Condense handling (preservation and removal)
    • Truncation handling (preservation and removal)
    • Checkpoint scenarios (the key bug fix)
    • Skip cleanup option
    • Combined scenarios and edge cases

Architecture

┌─────────────────────────────────────────────────────────────────────┐
│                        Message Operations                           │
├─────────────────┬─────────────────┬─────────────────────────────────┤
│  Delete Message │  Edit Message   │  Checkpoint Restore             │
│  (webview)      │  (webview)      │  (checkpoints)                  │
└────────┬────────┴────────┬────────┴───────────────┬─────────────────┘
         │                 │                        │
         └─────────────────┼────────────────────────┘
                           │
                           ▼
              ┌────────────────────────┐
              │    MessageManager      │
              │                        │
              │  • rewindToTimestamp() │
              │  • rewindToIndex()     │
              └───────────┬────────────┘
                          │
        ┌─────────────────┼─────────────────┐
        │                 │                 │
        ▼                 ▼                 ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ Collect IDs   │ │ Truncate      │ │ Cleanup       │
│ from removed  │ │ clineMessages │ │ orphaned      │
│ context events│ │ & apiHistory  │ │ tags          │
└───────────────┘ └───────────────┘ └───────────────┘

Important

Introduces MessageManager for centralized message history operations, ensuring consistent handling across UI and API paths, with comprehensive testing.

  • Behavior:
    • Introduces MessageManager class in src/core/message-manager/index.ts for centralized message history operations.
    • Replaces inline message removal logic in webviewMessageHandler.ts with MessageManager calls.
    • Ensures consistent handling of message histories across UI and API paths.
  • Bug Fix:
    • Fixes checkpoint restore handling of context-management events by removing orphaned tags and markers.
  • Testing:
    • Adds src/core/message-manager/index.spec.ts with 22 unit tests covering rewind operations, condense and truncation handling, and edge cases.
  • Misc:
    • Updates Task.ts to include a messageManager getter for lazy initialization.
    • Minor test updates in webviewMessageHandler.delete.spec.ts for timestamp-based behavior.

This description was created by Ellipsis for cef2492. You can customize this summary. It will automatically update as commits are pushed.

Implements the proposal from docs/proposals/message-manager-layer.md

This introduces a MessageManager class that centralizes all conversation
rewind operations, ensuring consistent handling of both UI (clineMessages)
and API (apiConversationHistory) message histories.

Key changes:
- Add MessageManager class with rewindToTimestamp() and rewindToIndex() methods
- Add 22 comprehensive unit tests for MessageManager
- Refactor webviewMessageHandler.ts to use MessageManager (removes 79-line inline function)
- Fix checkpoint restore to properly handle context-management events
- Add messageManager getter to Task class with lazy initialization

Bug fix: Checkpoint restore now properly:
- Collects condenseIds from removed condense_context messages
- Collects truncationIds from removed sliding_window_truncation messages
- Removes orphaned Summary messages from API history
- Removes orphaned truncation markers from API history
- Calls cleanupAfterTruncation() to clear orphaned parent tags

All 4508 tests pass with no regressions.
@dosubot dosubot bot added size:XXL This PR changes 1000+ lines, ignoring generated files. bug Something isn't working Enhancement New feature or request labels Dec 4, 2025
@roomote
Copy link
Contributor

roomote bot commented Dec 4, 2025

Oroocle Clock   Follow along on Roo Cloud

Review completed with one suggestion about consolidating MessageManager usage through the Task.messageManager getter for consistency and future extensibility.

  • Route all MessageManager usages through Task.messageManager to avoid multiple instances and keep a single coordination point.
Previous reviews

Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues.

@hannesrudolph hannesrudolph changed the title feat: add MessageManager layer for centralized history coordination FIX + feat: add MessageManager layer for centralized history coordination Dec 4, 2025
@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Dec 4, 2025
…r getter

Address PR review feedback from roomote to route all MessageManager usages
through Task.messageManager instead of creating new instances directly.
This ensures a single coordination point and avoids multiple instances.

Changes:
- checkpoints/index.ts: use task.messageManager instead of new MessageManager(task)
- webviewMessageHandler.ts: use currentCline.messageManager instead of new MessageManager(currentCline)
- Updated tests to support the messageManager property on mock task objects
Update Task.messageManager getter documentation to clarify that all MessageManager
operations must go through this getter rather than instantiating new instances directly.
This addresses the PR review feedback about updating class docs.
Comment on lines +270 to +272
await task.messageManager.rewindToTimestamp(ts, {
includeTargetMessage: operation === "edit",
})
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not a blocker, but I continue to think that it would be nice if we didn't need to special case edit in the way that we have been doing

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Tomorrow's problem?

@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Dec 5, 2025
@mrubens mrubens merged commit 630c8bc into main Dec 5, 2025
12 of 13 checks passed
@mrubens mrubens deleted the feat/message-manager-layer branch December 5, 2025 01:48
@github-project-automation github-project-automation bot moved this from New to Done in Roo Code Roadmap Dec 5, 2025
@github-project-automation github-project-automation bot moved this from Triage to Done in Roo Code Roadmap Dec 5, 2025
mini2s added a commit to zgsm-ai/costrict that referenced this pull request Dec 5, 2025
* Fix preserveReasoning flag to control API reasoning inclusion (RooCodeInc#9453)

* feat: store reasoning in conversation history for all providers

* refactor: address review feedback

- Move comments inside else block
- Combine reasoning checks into single if block
- Make comments more concise

* refactor: make comments more concise

* Fix preserveReasoning flag to control API reasoning inclusion

Changes:
1. Removed hardcoded <think> tag logic in streaming
   - Previously hardcoded reasoning into assistant message text
   - Now passes reasoning to addToApiConversationHistory as parameter

2. Updated buildCleanConversationHistory to respect preserveReasoning flag
   - When preserveReasoning: true → reasoning block included in API requests
   - When preserveReasoning: false/undefined → reasoning stripped from API
   - Reasoning stored in history for all cases

3. Added temporary debug logs to base-openai-compatible-provider.ts
   - Shows preserveReasoning flag value
   - Logs reasoning blocks in incoming messages
   - Logs <think> tags in converted messages sent to API

* Fix: Use api.getModel() directly instead of cachedStreamingModel

Addresses review comment: cachedStreamingModel is set during streaming but
buildCleanConversationHistory is called before streaming starts. Using the
cached value could cause stale model info when switching models between requests.

Now directly uses this.api.getModel().info.preserveReasoning to ensure we
always check the current model's flag, not a potentially stale cached value.

* Clean up comments in Task.ts

Removed outdated comment regarding model's preserveReasoning flag.

* fix: remove unnecessary reasoningBlock variable in task reasoning logic

* fix: send tool_result blocks for skipped tools in native protocol (RooCodeInc#9457)

* fix: improve markdown formatting and add reasoning support (RooCodeInc#9458)

* feat: implement Minimax as Anthropic-compatible provider (RooCodeInc#9455)

* fix: improve search and replace symbol parsing (RooCodeInc#9456)

* chore: add changeset for v3.33.3 (RooCodeInc#9459)

* Changeset version bump (RooCodeInc#9460)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Matt Rubens <[email protected]>

* feat(terminal): add inline shell integration with user input support

* Release: v1.87.0 (RooCodeInc#9477)

* refactor(terminal): remove inline shell integration callback and improve terminal process handling

* fix: add fallback to yield tool calls regardless of finish_reason (RooCodeInc#9476)

* Improvements to base openai compatible (RooCodeInc#9462)

Co-authored-by: Roo Code <[email protected]>

* Browser Use 2.0 (RooCodeInc#8941)

Co-authored-by: roomote[bot] <219738659+roomote[bot]@users.noreply.github.com>
Co-authored-by: daniel-lxs <[email protected]>

* fix: resolve apply_diff performance regression from PR RooCodeInc#9456 (RooCodeInc#9474)

* fix: implement model cache refresh to prevent stale disk cache (RooCodeInc#9478)

* fix: Make cancel button immediately responsive during streaming (RooCodeInc#9448)

* Test a provider-oriented welcome screen (RooCodeInc#9484)

Co-authored-by: roomote[bot] <219738659+roomote[bot]@users.noreply.github.com>

* (feat): Add Baseten Provider (RooCodeInc#9461)

Co-authored-by: roomote[bot] <219738659+roomote[bot]@users.noreply.github.com>
Co-authored-by: AlexKer <[email protected]>
Co-authored-by: Matt Rubens <[email protected]>

* fix: copy model-level capabilities to OpenRouter endpoint models (RooCodeInc#9483)

* Pin the Roo provider to the top of the list (RooCodeInc#9485)

* Wait to experiment until state is hydrated (RooCodeInc#9488)

* Change baseten default model to glm for now (RooCodeInc#9489)

* Revert "Wait to experiment until state is hydrated" (RooCodeInc#9491)

* Try to fix build (RooCodeInc#9490)

* Update webview-ui Vite config (RooCodeInc#9493)

* Enhance native tool descriptions with examples and clarifications (RooCodeInc#9486)

* Revert "Revert "Wait to experiment until state is hydrated"" (RooCodeInc#9494)

* chore: add changeset and announcement for v3.34.0 (RooCodeInc#9495)

* Changeset version bump (RooCodeInc#9496)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Matt Rubens <[email protected]>

* Enable the Roo Code Cloud provider in evals (RooCodeInc#9492)

* Show the prompt for image gen (RooCodeInc#9505)

* feat(chat): conditionally render UpdateTodoListToolBlock based on alwaysAllowUpdateTodoList flag

* fix(web-evals): update checkbox handler in new-run component

* Remove double todo list (RooCodeInc#9517)

* Track cloud synced messages (RooCodeInc#9518)

* 3.34.1 (RooCodeInc#9522)

* Changeset version bump (RooCodeInc#9523)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Matt Rubens <[email protected]>

* fix: support reasoning_details format for Gemini 3 models (RooCodeInc#9506)

* feat: update Cerebras models (RooCodeInc#9527)

Co-authored-by: Roo Code <[email protected]>

* fix: ensure XML parser state matches tool protocol on config update (RooCodeInc#9535)

* fix: flush LiteLLM cache when credentials change on refresh (RooCodeInc#9536)

* Add Roo Code Cloud as an imagegen provider (RooCodeInc#9528)

* fix: gracefully skip unsupported content blocks in Gemini transformer (RooCodeInc#9537)

Co-authored-by: Matt Rubens <[email protected]>

* feat: add claude-opus-4.5 to OpenRouter prompt caching and reasoning budget models (RooCodeInc#9540)

* feat: add claude-opus-4.5 to Anthropic and Vertex providers (RooCodeInc#9541)

* Release v3.34.2 (RooCodeInc#9545)

* Changeset version bump (RooCodeInc#9546)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Matt Rubens <[email protected]>

* Add support for Roo Code Cloud as an embeddings provider (RooCodeInc#9543)

* Switch from asdf to mise-en-place in bare-metal evals setup script (RooCodeInc#9548)

* feat: implement streaming for native tool calls (RooCodeInc#9542)

* Add Opus 4.5 to Claude Code provider (RooCodeInc#9560)

* Fix ask_followup_question streaming issue and add missing tool cases (RooCodeInc#9561)

* feat(auth): enhance login status logging and use dynamic plugin version

* refactor:  remove disable provider and add client id headers

* test(webview): remove disable  provider tests across multiple test files

* fix: enable caching for Opus 4.5 model (RooCodeInc#9568)

Added claude-opus-4-5-20251101 to the cache control switch statements
to enable prompt caching, matching the behavior of other Claude models.

Fixes RooCodeInc#9567

Co-authored-by: Roo Code <[email protected]>

* feat: Add contact links to About Roo Code settings page (RooCodeInc#9570)

* feat: add contact links to About settings page

* Tweaks

* i18n

* Update webview-ui/src/components/settings/__tests__/About.spec.tsx

Co-authored-by: roomote[bot] <219738659+roomote[bot]@users.noreply.github.com>

---------

Co-authored-by: Roo Code <[email protected]>
Co-authored-by: Bruno Bergher <[email protected]>
Co-authored-by: roomote[bot] <219738659+roomote[bot]@users.noreply.github.com>

* feat: add Claude Opus 4.5 model to Bedrock provider (RooCodeInc#9572)

Co-authored-by: Roo Code <[email protected]>
Co-authored-by: Matt Rubens <[email protected]>

* chore: add changeset for v3.34.3 (RooCodeInc#9578)

* Changeset version bump (RooCodeInc#9579)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Matt Rubens <[email protected]>

* fix: preserve dynamic MCP tool names in native mode API history (RooCodeInc#9559)

* fix: preserve tool_use blocks in summary message during condensing with native tools (RooCodeInc#9582)

* Add support for images api (RooCodeInc#9587)

* Make it clear that BFL Flux 2 is free (RooCodeInc#9588)

* Add BFL models to openrouter (RooCodeInc#9589)

* chore: add changeset for v3.34.4 (RooCodeInc#9590)

* Changeset version bump (RooCodeInc#9591)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Matt Rubens <[email protected]>

* feat: set native tools as default for minimax-m2 and claude-haiku-4.5 (RooCodeInc#9586)

* feat: enable multiple native tool calls per turn with failure guardrails (RooCodeInc#9273)

* feat: add Bedrock Opus 4.5 to global inference model list (RooCodeInc#9595)

Co-authored-by: Roo Code <[email protected]>

* fix: update API handler when toolProtocol changes (RooCodeInc#9599)

* Make single file read only apply to xml tools (RooCodeInc#9600)

* Revert "Add support for Roo Code Cloud as an embeddings provider" (RooCodeInc#9602)

* feat(web-evals): enhance dashboard with dynamic tool columns and UX improvements (RooCodeInc#9592)

Co-authored-by: Roo Code <[email protected]>

* fix(webview): pass taskId to finishSubTask when canceling or deleting tasks

* chore: add changeset for v3.34.5 (RooCodeInc#9603)

* Changeset version bump (RooCodeInc#9604)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Matt Rubens <[email protected]>

* Feature/bedrock embeddings support (RooCodeInc#9475)

* feat: add AWS Bedrock support for codebase indexing

- Add bedrock as a new EmbedderProvider type
- Add AWS Bedrock embedding model profiles (titan-embed-text models)
- Create BedrockEmbedder class with support for Titan and Cohere models
- Add Bedrock configuration support to config manager and interfaces
- Update service factory to create BedrockEmbedder instances
- Add comprehensive tests for BedrockEmbedder
- Add localization strings for Bedrock support

Closes RooCodeInc#8658

* fix: add missing bedrockOptions to loadConfiguration return type

* Fix various issues that the original PR missed.

* Remove debug logs

* Rename AWS Bedrock -> Amazon Bedrock

* Remove some 'as any's

* Revert README changes

* Add translations

* More translations

* Remove leftover code from a debugging session.

* fix: add bedrock to codebaseIndexModelsSchema and update brace-expansion override

- Add bedrock provider to codebaseIndexModelsSchema type definition to fix empty model dropdown in UI
- Update pnpm override for brace-expansion from '>=2.0.2' to '^2.0.2' to resolve ESM/CommonJS compatibility issues

* Improvements to AWS Bedrock embeddings support

- Enhanced bedrock.ts embedder implementation
- Added comprehensive test coverage in bedrock.spec.ts
- Updated config-manager.ts for better Bedrock configuration handling
- Improved service-factory.ts integration
- Updated embeddingModels.ts with Bedrock models
- Enhanced CodeIndexPopover.tsx UI for Bedrock options
- Added auto-populate test for CodeIndexPopover
- Updated pnpm-lock.yaml dependencies

* Restore openrouter config

* Remove debug log

* Fix config-manager.spec.ts unit test.

* Add translations for "optional"

* Revert unnecessary change related to open ia embedder

---------

Co-authored-by: Roo Code <[email protected]>
Co-authored-by: Matt Rubens <[email protected]>
Co-authored-by: Smartsheet-JB-Brown <[email protected]>

* fix: restore content undefined check in WriteToFileTool.handlePartial() (RooCodeInc#9614)

* fix: exclude access_mcp_resource tool when MCP has no resources (RooCodeInc#9615)

* fix: prevent model cache from persisting empty API responses (RooCodeInc#9623)

* fix: update default settings for inline terminal and codebase indexing (RooCodeInc#9622)

Co-authored-by: Roo Code <[email protected]>

* feat(mistral): add native tool calling support (RooCodeInc#9625)

* feat: wire MULTIPLE_NATIVE_TOOL_CALLS experiment to OpenAI parallel_tool_calls (RooCodeInc#9621)

* feat(bedrock): allow global inference selection when cross-region is enabled (RooCodeInc#9616)

Co-authored-by: Roo Code <[email protected]>

* fix: defer new_task tool_result until subtask completes for native protocol (RooCodeInc#9628)

* fix: convert line_ranges strings to lineRanges objects in native tool calls (RooCodeInc#9627)

* fix: filter non-Anthropic content blocks before sending to Vertex API (RooCodeInc#9618)

* Add fine grained tool streaming for OpenRouter Anthropic (RooCodeInc#9629)

* Release v3.34.6 (RooCodeInc#9631)

* Changeset version bump (RooCodeInc#9632)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Matt Rubens <[email protected]>

* fix: OpenRouter GPT-5 strict schema validation for read_file tool (RooCodeInc#9633)

* fix: create parent directories early in write_to_file to prevent ENOENT errors (RooCodeInc#9640)

* Fix openrouter tool calls (