Skip to content

Conversation

@vinitkadam03
Copy link
Contributor

@vinitkadam03 vinitkadam03 commented Dec 23, 2025

Description

Add StepStartEvent and StepFinishEvent to All Streaming Providers

Description

This PR adds StepStartEvent and StepFinishEvent to the streaming handlers of all providers, aligning with the AI SDK step event implementation. This enables consumers to track the lifecycle of individual processing steps during multi-step conversations (e.g., when tool calls are involved).

Motivation

In multi-step conversations (especially those involving multiple tool calls), streaming responses without step boundaries can flatten execution into a single assistant turn in subsequent requests sent by frontend after calling convertToModelMessages. This leads to:

  • Models losing the correct sequence of execution
  • Incorrect message history being sent back to the model in subsequent requests

Step events introduce explicit boundaries between execution steps, ensuring deterministic ordering and correct state management.

Problem Illustration

Without step events (flattened execution)

[
  {
    "role": "assistant",
    "content": [
      { "type": "text", "text": "Some message" },
      { "type": "tool-call", "toolCallId": "1", "input": { "param": "1" } },
      { "type": "text", "text": "Next message" },
      { "type": "tool-call", "toolCallId": "2", "input": { "param": "2" } }
    ]
  },
  {
    "role": "tool",
    "content": [
      { "type": "tool-result", "toolCallId": "1", "output": "abc" },
      { "type": "tool-result", "toolCallId": "2", "output": "pqr" }
    ]
  }
]

In this case, tool calls and text from different logical steps are merged, making it difficult for the model to reason about execution order in subsequent requests sent after converting UI Messages to model messages using convertToModelMessages

With step events (explicit sequencing)

[
  {
    "role": "assistant",
    "content": [
      { "type": "text", "text": "Some message" },
      { "type": "tool-call", "toolCallId": "1", "input": { "param": "1" } }
    ]
  },
  {
    "role": "tool",
    "content": [
      { "type": "tool-result", "toolCallId": "1", "output": "abc" }
    ]
  },
  {
    "role": "assistant",
    "content": [
      { "type": "text", "text": "Next message" },
      { "type": "tool-call", "toolCallId": "2", "input": { "param": "2" } }
    ]
  },
  {
    "role": "tool",
    "content": [
      { "type": "tool-result", "toolCallId": "2", "output": "pqr" }
    ]
  }
]

Each logical step is clearly separated, preserving execution order and allowing consumers to correctly replay or resend message history.

Event Lifecycle

StreamStartEvent
  └── StepStartEvent          ← Step 1 begins
        └── TextStart/TextDelta/ToolCall/ToolResult events...
        └── StepFinishEvent   ← Step 1 ends (e.g., tool call completed)
  └── StepStartEvent          ← Step 2 begins
        └── TextStart/TextDelta/TextComplete events...
        └── StepFinishEvent   ← Step 2 ends
StreamEndEvent

Breaking Changes

None. This is a purely additive change. Existing code will continue to work - consumers can simply ignore the new events if not needed.

@sixlive
Copy link
Contributor

sixlive commented Dec 29, 2025

I'm sorry, I found a bug in streaming events and the fix created a bunch of conflicts. If you wouldn't mind resolving the conflicts I'd be interested in merging this!

@vinitkadam03 vinitkadam03 force-pushed the feat/step-events branch 2 times, most recently from 5ab2eff to fc9cfa2 Compare December 31, 2025 10:54
@vinitkadam03
Copy link
Contributor Author

Raised a PR for a bug related to stream start and end events in anthropic and gemini. #817. Will rebase this again once that is merged

@vinitkadam03 vinitkadam03 marked this pull request as draft December 31, 2025 10:56
@sixlive
Copy link
Contributor

sixlive commented Dec 31, 2025

I merged #817

@vinitkadam03 vinitkadam03 marked this pull request as ready for review December 31, 2025 19:22
@vinitkadam03
Copy link
Contributor Author

vinitkadam03 commented Dec 31, 2025

@sixlive Rebased and ready for review

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