Skip to content

Conversation

samuelcolvin
Copy link
Member

@samuelcolvin samuelcolvin commented Sep 16, 2025

This adds support for Vercel AI Elements streams to Pydantic AI.

There's an example frontend in a separate repo github.com/pydantic/pydantic-ai-chat the plan is to either make that into a more complete template, or release a pydantic-ai-chat python library which contains a pre-built react frontend.

@DouweM we should rename this to use the proper terminology of the "Vercel AI Data Stream Protocol"

Here's a demo of basic usage:

pydantic-ai-chat.mp4

Copy link

Docs Preview

commit: 0018e11
Preview URL: https://bd697eba-pydantic-ai-previews.pydantic.workers.dev

@DouweM DouweM self-assigned this Sep 16, 2025
@edwinjosechittilappilly

This would be a wonderful addon, looking forward to see it soon in main.

@edwinjosechittilappilly

@samuelcolvin can you add it to docs such that it would be integrated as chat service in existing Fullstack apps that uses pydantic-ai as Agent stack.

Copy link
Member Author

Choose a reason for hiding this comment

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

I guess we rename the directory to just vercel_ai to keep things simple.

Copy link

@183amir 183amir left a comment

Choose a reason for hiding this comment

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

Thanks a lot for this! I left some comments on the code and I will try to test this and get back.

messages: list[UIMessage]

model: str
web_search: bool
Copy link

Choose a reason for hiding this comment

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

From what I understand you can have arbitrary body and metadata in the request: https://ai-sdk.dev/docs/ai-sdk-ui/chatbot#request-configuration
The examples show model and web_search in the body but this is arbitrary.


__all__ = 'sse_stream', 'VERCEL_AI_ELEMENTS_HEADERS', 'EventStreamer'
# no idea if this is important, but vercel sends it, therefore so am I
VERCEL_AI_ELEMENTS_HEADERS = {'x-vercel-ai-ui-message-stream': 'v1'}
Copy link

Choose a reason for hiding this comment

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

from ..tools import AgentDepsT
from . import response_types as _t

__all__ = 'sse_stream', 'VERCEL_AI_ELEMENTS_HEADERS', 'EventStreamer'
Copy link

Choose a reason for hiding this comment

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

technically these events are for the "AI SDK UI"'s data stream protocol and not necessarily Vercel AI elements. https://ai-sdk.dev/docs/ai-sdk-ui/stream-protocol

if not isinstance(event, AgentRunResultEvent):
async for chunk in event_streamer.event_to_chunks(event):
yield chunk.sse()
async for chunk in event_streamer.finish():
Copy link

Choose a reason for hiding this comment

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

You are not sending any EndChunk like TextEndChunk or ReasoningEndChunk. Not sure how important that is. I had them in my implementation: https://gist.github.com/183amir/ce45cf52f034b493fac0bb4b1838236a#file-vercel_ai-py-L497

class DataUIPart(CamelBaseModel):
"""Data part with dynamic type based on data name."""

type: str # Will be f"data-{NAME}"
Copy link

Choose a reason for hiding this comment

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

Maybe we can have type: str = pydantic.Field(pattern=r"^data-.*$")

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