Skip to content

refactor(task): append environment details into existing blocks#11437

Open
roomote[bot] wants to merge 2 commits intomainfrom
refactor/append-environment-details
Open

refactor(task): append environment details into existing blocks#11437
roomote[bot] wants to merge 2 commits intomainfrom
refactor/append-environment-details

Conversation

@roomote
Copy link
Contributor

@roomote roomote bot commented Feb 12, 2026

Related GitHub Issue

Closes: #11200

Description

Re-applies the changes from #11198 (which was reverted) with adaptations for the AI SDK type migration that happened since.

The core change: instead of adding <environment_details> as a standalone trailing text block, we now append it into the last text block or tool_result block. This avoids message shapes that break interleaved-thinking models like DeepSeek reasoner, which expect specific message structures.

Key implementation details:

  • Added appendEnvironmentDetails() helper in src/core/task/appendEnvironmentDetails.ts that merges environment details into the last suitable content block
  • Added removeEnvironmentDetailsBlocks() and stripAppendedEnvironmentDetails() helpers for cleaning up existing env details
  • Updated Task.resumeAfterDelegation() and Task.recursivelyMakeClineRequests() to use the new helpers
  • Adapted types from Anthropic SDK (ContentBlockParam) to AI SDK types (UserContentPart, LegacyToolResultBlock, TextPart) to match the codebase's current type system

Test Procedure

  • 25 unit tests covering all edge cases: empty content, text blocks, tool_result blocks (string/array/undefined content), mixed content, image-only content, mutation safety, is_error preservation
  • Run: cd src && npx vitest run core/task/__tests__/appendEnvironmentDetails.spec.ts
  • TypeScript compilation passes cleanly (tsc --noEmit)
  • All monorepo lint and type-check tasks pass

Pre-Submission Checklist

  • Issue Linked: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
  • Scope: My changes are focused on the linked issue (one major feature/fix per PR).
  • Self-Review: I have performed a thorough self-review of my code.
  • Testing: New and/or updated tests have been added to cover my changes (if applicable).
  • Documentation Impact: I have considered if my changes require documentation updates (see "Documentation Updates" section below).
  • Contribution Guidelines: I have read and agree to the Contributor Guidelines.

Documentation Updates

  • No documentation updates are required.

Additional Notes

This is a re-application of #11198 with type adaptations. The original PR used Anthropic SDK types (Anthropic.Messages.ContentBlockParam, Anthropic.Messages.ToolResultBlockParam), but the codebase has since migrated to AI SDK types (UserContentPart, LegacyToolResultBlock, TextPart from ai). The logic is identical; only the type signatures changed.

Add appendEnvironmentDetails() helper that merges environment details
into the last text block or tool_result instead of adding a standalone
trailing text block.

This avoids message shapes that can break interleaved-thinking models
like DeepSeek reasoner, which expect specific message structures.

Changes:
- Add appendEnvironmentDetails() and removeEnvironmentDetailsBlocks() helpers
- Update Task.resumeAfterDelegation() to use the helper
- Update Task.recursivelyMakeClineRequests() to use the helper
- Adapt types to use AI SDK UserContentPart instead of Anthropic SDK types
- Add comprehensive unit tests (25 test cases)

Re-applies #11198 with type adaptations for the AI SDK migration.
@dosubot dosubot bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label Feb 12, 2026
@roomote
Copy link
Contributor Author

roomote bot commented Feb 12, 2026

Rooviewer Clock   See task

All previously flagged issues have been resolved in 963082f. No new issues found.

  • Both call sites in Task.ts use removeEnvironmentDetailsBlocks() which only removes standalone env_details blocks. Since env details are now appended into existing blocks, they won't be cleaned up on subsequent calls (e.g., task resume), causing accumulation. Use the already-implemented stripAppendedEnvironmentDetails() instead.
Previous reviews

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

// then append env details to the last text or tool_result block.
// This avoids creating standalone trailing text blocks which can break
// interleaved-thinking models like DeepSeek reasoner.
const contentWithoutEnvDetails = removeEnvironmentDetailsBlocks(lastUserMsg.content)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

removeEnvironmentDetailsBlocks only removes standalone env_details text blocks (where the entire trimmed text starts/ends with the tags). Since appendEnvironmentDetails now embeds env details into the last text or tool_result block (e.g., "User message\n\n<environment_details>...") rather than as a standalone block, this cleanup can't find them on subsequent calls. In resumeAfterDelegation, which mutates the last user message in conversation history, this means env details will accumulate on each resume.

The PR already has stripAppendedEnvironmentDetails() that handles both standalone and appended env details, but it's only tested, never called. Both this line and the equivalent at line ~2802 should use stripAppendedEnvironmentDetails instead (and update the import accordingly).

Suggested change
const contentWithoutEnvDetails = removeEnvironmentDetailsBlocks(lastUserMsg.content)
const contentWithoutEnvDetails = stripAppendedEnvironmentDetails(lastUserMsg.content)

Fix it with Roo Code or mention @roomote and request a fix.

}
return true
})
const contentWithoutEnvDetails = removeEnvironmentDetailsBlocks(parsedUserContent)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same issue as above: removeEnvironmentDetailsBlocks won't clean up env details that were previously appended into an existing block. Use stripAppendedEnvironmentDetails here as well.

Suggested change
const contentWithoutEnvDetails = removeEnvironmentDetailsBlocks(parsedUserContent)
const contentWithoutEnvDetails = stripAppendedEnvironmentDetails(parsedUserContent)

Fix it with Roo Code or mention @roomote and request a fix.

import { MessageManager } from "../message-manager"
import { validateAndFixToolResultIds } from "./validateToolResultIds"
import { mergeConsecutiveApiMessages } from "./mergeConsecutiveApiMessages"
import { appendEnvironmentDetails, removeEnvironmentDetailsBlocks } from "./appendEnvironmentDetails"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The import needs to include stripAppendedEnvironmentDetails (which supersedes removeEnvironmentDetailsBlocks at both call sites). removeEnvironmentDetailsBlocks can be dropped from the import since stripAppendedEnvironmentDetails calls it internally.

Suggested change
import { appendEnvironmentDetails, removeEnvironmentDetailsBlocks } from "./appendEnvironmentDetails"
import { appendEnvironmentDetails, stripAppendedEnvironmentDetails } from "./appendEnvironmentDetails"

Fix it with Roo Code or mention @roomote and request a fix.

…ulation

Replace removeEnvironmentDetailsBlocks with stripAppendedEnvironmentDetails
at both call sites in Task.ts. Since appendEnvironmentDetails now embeds
env details into existing blocks rather than standalone blocks,
removeEnvironmentDetailsBlocks cannot find them on subsequent calls
(e.g., task resume), causing accumulation. stripAppendedEnvironmentDetails
handles both standalone and appended env details.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

task: append environment details into existing blocks

1 participant