Skip to content

fix: filter out orphaned tool results from history and current context#269

Merged
luispater merged 1 commit intorouter-for-me:mainfrom
ClubWeGo:fix/filterOrphanedToolResults
Feb 24, 2026
Merged

fix: filter out orphaned tool results from history and current context#269
luispater merged 1 commit intorouter-for-me:mainfrom
ClubWeGo:fix/filterOrphanedToolResults

Conversation

@Darley-Wey
Copy link

When history is truncated, tool_result entries may reference tool_use IDs from assistant turns that were dropped. This causes Kiro API to return 'Improperly formed request' errors.
This fix:

  • Collects all valid tool_use IDs from retained history
  • Filters out orphaned tool_results in both history and currentMessage
  • Prevents mismatched tool_use/tool_result pairs from reaching the Kiro API

Copilot AI review requested due to automatic review settings February 23, 2026 06:39
@gemini-code-assist
Copy link

Summary of Changes

Hello @Darley-Wey, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a crucial mechanism to maintain the integrity of tool-related data within conversation history. By proactively identifying and removing tool results that have become disassociated from their corresponding tool uses due to history truncation, it ensures that the Kiro API receives well-formed requests, thereby enhancing the robustness and reliability of the system's interaction with external tools.

Highlights

  • Orphaned Tool Result Filtering: Implemented a new function, filterOrphanedToolResults, to identify and remove tool_result entries that no longer have a corresponding tool_use ID in the retained conversation history. This addresses issues where history truncation could lead to tool_result entries referencing tool_use IDs that were dropped.
  • History Processing Integration: Integrated the filterOrphanedToolResults function into the processOpenAIMessages flow, ensuring that orphaned tool results are removed from both the historical messages and the current message's tool results after history truncation, but before sending the request to the Kiro API.
  • Kiro API Error Prevention: The primary goal of this fix is to prevent 'Improperly formed request' errors from the Kiro API, which occur when tool_result entries are sent without a matching tool_use from the assistant's turn.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • internal/translator/kiro/openai/kiro_openai_request.go
    • Added a call to filterOrphanedToolResults after history truncation.
    • Implemented the filterOrphanedToolResults function to remove tool results without matching tool use IDs from both history and current messages.
  • internal/translator/kiro/openai/kiro_openai_request_test.go
    • Added TestFilterOrphanedToolResults_RemovesHistoryAndCurrentOrphans to verify the correct filtering of orphaned tool results in various scenarios.
Activity
  • No specific activity (comments, reviews, or progress updates) has been recorded for this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request correctly addresses a bug where orphaned tool_result entries could cause API errors after history truncation. The new filterOrphanedToolResults function effectively cleans up both the history and the current message. The added unit test is comprehensive and validates the fix. I've included a couple of suggestions to improve performance by using in-place slice filtering, which is more memory-efficient.

Comment on lines +620 to +628
filtered := make([]KiroToolResult, 0, len(ctx.ToolResults))
for _, tr := range ctx.ToolResults {
if validToolUseIDs[tr.ToolUseID] {
filtered = append(filtered, tr)
continue
}
log.Debugf("kiro-openai: dropping orphaned tool_result in history[%d]: toolUseId=%s (no matching tool_use)", i, tr.ToolUseID)
}
ctx.ToolResults = filtered

Choose a reason for hiding this comment

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

medium

For better performance, you can filter the ctx.ToolResults slice in-place. This avoids allocating a new filtered slice on each call, which is more memory-efficient, especially for long histories. This is a common Go idiom for slice filtering.

n := 0
		for _, tr := range ctx.ToolResults {
			if validToolUseIDs[tr.ToolUseID] {
				ctx.ToolResults[n] = tr
				n++
			} else {
				log.Debugf("kiro-openai: dropping orphaned tool_result in history[%d]: toolUseId=%s (no matching tool_use)", i, tr.ToolUseID)
			}
		}
		ctx.ToolResults = ctx.ToolResults[:n]

Comment on lines +635 to +646
filtered := make([]KiroToolResult, 0, len(currentToolResults))
for _, tr := range currentToolResults {
if validToolUseIDs[tr.ToolUseID] {
filtered = append(filtered, tr)
continue
}
log.Debugf("kiro-openai: dropping orphaned tool_result in currentMessage: toolUseId=%s (no matching tool_use)", tr.ToolUseID)
}
if len(filtered) != len(currentToolResults) {
log.Infof("kiro-openai: dropped %d orphaned tool_result(s) from currentMessage", len(currentToolResults)-len(filtered))
}
currentToolResults = filtered

Choose a reason for hiding this comment

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

medium

Similar to the history filtering, currentToolResults can also be filtered in-place to avoid allocating a new slice. This improves efficiency by reducing memory allocations.

originalLen := len(currentToolResults)
		n := 0
		for _, tr := range currentToolResults {
			if validToolUseIDs[tr.ToolUseID] {
				currentToolResults[n] = tr
				n++
			} else {
				log.Debugf("kiro-openai: dropping orphaned tool_result in currentMessage: toolUseId=%s (no matching tool_use)", tr.ToolUseID)
			}
		}

		if n < originalLen {
			log.Infof("kiro-openai: dropped %d orphaned tool_result(s) from currentMessage", originalLen-n)
		}
		currentToolResults = currentToolResults[:n]

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes malformed Kiro API requests caused by truncated history leaving tool_result entries that reference tool_use IDs from dropped assistant turns. It ensures only valid tool result entries (those with a matching retained tool_use) are sent onward.

Changes:

  • Collect valid toolUseId values from retained assistant history.
  • Filter out orphaned tool_result entries from both retained history contexts and the current message tool results.
  • Add a focused unit test covering mixed/fully-orphaned history contexts and current tool results.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
internal/translator/kiro/openai/kiro_openai_request.go Adds post-truncation filtering to drop orphaned tool results from history and current tool results before building the Kiro payload.
internal/translator/kiro/openai/kiro_openai_request_test.go Adds a unit test validating orphan filtering behavior for both history and current tool results.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@KooshaPari
Copy link

Moved to fork for completion and continued work there. Fork PRs:
#208 (source ci-compile-fix-clean-single)
#209 (from pr-271-migrate)
#210 (from pr-269-migrate)
#211 (from pr-11-migrate)

@KooshaPari
Copy link

Superseded by fork migration. This PR has been moved to KooshaPari/cliproxyapi-plusplus as #210. Please close this upstream PR to keep the queue clean.

@luispater luispater merged commit e6626c6 into router-for-me:main Feb 24, 2026
4 of 6 checks passed
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.

4 participants