State reset

Cancelling the task is not enough. If the old reply left half-spoken tokens in a TTS queue, an in-flight tool result about to land, or a partial conversation history, the next turn will feel incoherent. State reset is the cleanup layer that makes barge-in feel natural rather than glitchy.

agent.py
python
class VoiceAgent:
    def __init__(self, system_prompt=None):
        self.system_prompt = system_prompt or PHONE_AGENT_SYSTEM_PROMPT
        self._pending_tool_calls: dict = {}
        self._in_flight_reply: str = ""

    def reset_turn_state(self) -> None:
        """Drop anything that was tied to the previous agent turn."""
        self._pending_tool_calls.clear()
        self._in_flight_reply = ""

    def commit_completed_reply(self, text: str) -> None:
        """Only commit to conversation history when a reply finished without interruption."""
        self._in_flight_reply = text

Two disciplines matter here. Never commit to conversation history until the agent finishes speaking. And always have a named reset_turn_state method that discards transient state, so every caller who cancels the agent can call the same method.

Ordering exercise: Order the cleanup on a barge-in event

Loading practice…

Checkpoint: Real-time phone agent final checkpoint

Loading practice…