Skip to content

Add handling of missing tool calls/tool call responses#172

Open
akavi wants to merge 1 commit intoakavi/websocket-providersfrom
akavi/handle-message-invariants
Open

Add handling of missing tool calls/tool call responses#172
akavi wants to merge 1 commit intoakavi/websocket-providersfrom
akavi/handle-message-invariants

Conversation

@akavi
Copy link
Collaborator

@akavi akavi commented Mar 9, 2026

What does this PR do?

Bug report from Balto

  1. Updates LlmProvider to correctly handle unpaired tool_call/tool_call_response
  2. Moved the other validation/normalization from LlmAgent -> LlmProvider. Feels like the more natural place for it.
    a) LlmAgent is about maintaining the state of the agent, LlmProvider is about wrapping the Llm conversation API in a consistent interface

Based off of #159 since that does a bunch of rework of the LlmProvider code, and I'd rather not deal with the rebase mess.

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation
  • Other: ___________

Testing

Unit tests

Checklist

  • I have read the contributing guidelines
  • I have added tests that prove my fix is effective or that my feature works
  • I have formatted my code with make format

Note

Medium Risk
Changes the pre-flight normalization for every LLM chat call (message filtering, terminal validation, and tool-call pairing), which could alter conversation history and tool execution in edge cases despite being defensive.

Overview
Centralizes message validation in LlmProvider by adding _normalize_messages and applying it in LlmProvider.chat, returning an empty stream when the conversation is empty/invalid.

Normalization now filters empty user/assistant messages, removes unpaired tool_calls and orphaned tool responses, and enforces terminal-message rules (can’t end on assistant; last user message must be non-empty), replacing the earlier skip logic previously done in LlmAgent.

LlmAgent no longer pre-validates message sequences before calling the provider, and _build_messages now preserves empty UserTextSent/AgentTextSent contents (as "") for the provider to handle.

Written by Cursor Bugbot for commit fa9635f. This will update automatically on new commits. Configure here.

@akavi akavi changed the base branch from main to akavi/websocket-providers March 9, 2026 22:30
@akavi akavi force-pushed the akavi/handle-message-invariants branch from 285e6ef to e75eba1 Compare March 9, 2026 22:55
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

@akavi akavi force-pushed the akavi/handle-message-invariants branch from e75eba1 to fa9635f Compare March 9, 2026 23:03
@sauhardjain sauhardjain self-requested a review March 9, 2026 23:08
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