Skip to content

Interrupted tool calls leave invalid assistant message on retry #920

Description

@undo76

Summary

  • When interrupting mid tool call (Ctrl+C) and then sending a new prompt, the provider rejects the conversation
    history because an unfinished assistant tool call is resent without a corresponding tool result.

Steps To Reproduce

  • Start Crush with an OpenAI-style provider (e.g., DeepSeek/OpenAI/Azure OpenAI/OpenRouter).
  • Prompt: “Use grep to find ‘TODO’ in the repo and summarize.”
  • As soon as the tool starts, press Ctrl+C to interrupt.
  • Send a new prompt (e.g., “hi”).

Actual Behavior

  • Provider returns 400 invalid request (example from DeepSeek):
    • “Invalid assistant message: content or tool_calls must be set”
  • Root cause: assistant message includes a tool call that wasn’t finished (no tool result), or becomes empty
    after filtering.

Expected Behavior

  • Crush should sanitize history after interruption so the next request proceeds normally.

Environment

  • Crush version: latest main (or specify)
  • Provider: OpenAI-compatible (e.g., DeepSeek)
  • OS: macOS/Linux/Windows
  • Reproducible: always

Logs / Error

Proposed Fix

  • In provider converters for assistant messages:
    • Include only finished tool calls (ToolCall.Finished == true) when serializing.
    • Skip appending an empty assistant message if both content is empty and there are no finished tool calls.
  • Files/functions:
    • internal/llm/provider/openai.go: convertMessages (assistant case)
    • internal/llm/provider/anthropic.go: convertMessages (already skips empty; still filter unfinished calls)
    • internal/llm/provider/gemini.go: convertMessages (already skips empty; still filter unfinished calls)
  • Optional: central “sanitize history” step prior to provider calls to remove unfinished tool calls.

Acceptance Criteria

  • After interrupting mid tool call, sending a new prompt no longer produces provider errors.
  • Works across OpenAI, Azure OpenAI, DeepSeek, OpenRouter; Anthropic/Gemini unaffected or improved.

Metadata

Metadata

Assignees

No one assigned

    Type

    No fields configured for bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions