-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Support Vercel AI Data Stream Protocol #2923
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+8,328
−1,301
Merged
Changes from 5 commits
Commits
Show all changes
53 commits
Select commit
Hold shift + click to select a range
a2da46c
adding vercel AI chat
samuelcolvin 0018e11
fix sqlite
samuelcolvin e39612d
Merge branch 'main' into vercel-ai-chat
DouweM bdd321d
refactoring
DouweM f0a03d9
Claude-assisted refactoring to unify AG-UI and Vercel AI adapters and…
DouweM 6cae960
Flesh out Adapter and EventStream
DouweM 2acc1c3
fix typecheck, tests, linter
DouweM 2d7c781
Fix Vercel
DouweM 03862a5
cleanup
DouweM 6f51053
Refactor AG-UI streaming
DouweM 013c43b
Start fixing up Vercel events
DouweM 7d4b187
Improvements
DouweM eef9832
Merge branch 'main' into vercel-ai-chat
DouweM 365f14f
misc
DouweM 45e757e
Add PartEndEvent
DouweM 47a396b
Properly finish Vercel steps and messages
DouweM 7ba0cc7
Update tests for new PartEndEvent
DouweM f97d6c8
update snapshots
DouweM 6caa37e
Remove extra item in stream_output iteration
DouweM a09f6ce
resolve some todos
DouweM b9019e0
resolve some todos, fix snapshots
DouweM a5c205b
Deduplicate more stream_output messages
DouweM ab246e8
update snapshots
DouweM f02834c
add coverage todos
DouweM c9dec71
Add warning for scenario in https://github.com/pydantic/pydantic-ai/i…
DouweM 3ffd5ed
Start test UI Adapter and EventStream
DouweM 0bf0c97
Fix Groq thinking out of order
DouweM 42e39e2
coverage
DouweM 0b1dea3
tests
DouweM 4622eb5
tests
DouweM bd6cbc3
coverage
DouweM aebf039
Merge branch 'main' into vercel-ai-chat
DouweM 5544992
Set Content-Type header on StreamingResponse
DouweM 2b9b830
fix snapshots
DouweM 5bcc597
Fix 3.10 lint
DouweM 0871ac7
Add UIApp, AGUIApp, VercelAIApp
DouweM d9feb52
Refactoring
DouweM 5cf8802
Clean up Pydantic AI message building
DouweM e545e5c
fix lint
DouweM 40f4695
coverage
DouweM 7b50c11
Merge branch 'main' into vercel-ai-chat
DouweM f8be256
fix lint
DouweM d834583
Reset chat app example
DouweM 3d628b8
AG-UI docs
DouweM 7b4ad0d
Docs
DouweM d59fdac
coverage
DouweM 50b13ce
Merge branch 'main' into vercel-ai-chat
DouweM 9dbcee8
Remove UIApp
DouweM 92834a9
Merge branch 'main' into vercel-ai-chat
DouweM 1d56cb2
Docs
DouweM 81be052
fix docs
DouweM e770176
fix docs links
DouweM 52a0a15
Merge branch 'main' into vercel-ai-chat
DouweM File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| from __future__ import annotations as _annotations | ||
|
|
||
| import asyncio | ||
| import sqlite3 | ||
| from collections.abc import AsyncIterator, Callable | ||
| from concurrent.futures.thread import ThreadPoolExecutor | ||
| from contextlib import asynccontextmanager | ||
| from dataclasses import dataclass | ||
| from functools import partial | ||
| from pathlib import Path | ||
| from typing import Any, LiteralString, ParamSpec, TypeVar | ||
|
|
||
| import logfire | ||
|
|
||
| P = ParamSpec('P') | ||
| R = TypeVar('R') | ||
|
|
||
|
|
||
| @dataclass | ||
| class Database: | ||
| """Rudimentary database to store chat messages in SQLite. | ||
|
|
||
| The SQLite standard library package is synchronous, so we | ||
| use a thread pool executor to run queries asynchronously. | ||
| """ | ||
|
|
||
| con: sqlite3.Connection | ||
| _loop: asyncio.AbstractEventLoop | ||
| _executor: ThreadPoolExecutor | ||
|
|
||
| @classmethod | ||
| @asynccontextmanager | ||
| async def connect( | ||
| cls, schema_sql: str, file: Path = Path('.chat_app_messages.sqlite') | ||
| ) -> AsyncIterator[Database]: | ||
| with logfire.span('connect to DB'): | ||
| loop = asyncio.get_event_loop() | ||
| executor = ThreadPoolExecutor(max_workers=1) | ||
| con = await loop.run_in_executor(executor, cls._connect, schema_sql, file) | ||
| slf = cls(con, loop, executor) | ||
| try: | ||
| yield slf | ||
| finally: | ||
| await slf._asyncify(con.close) | ||
|
|
||
| @staticmethod | ||
| def _connect(schema_sql: str, file: Path) -> sqlite3.Connection: | ||
| con = sqlite3.connect(str(file)) | ||
| con = logfire.instrument_sqlite3(con) | ||
| cur = con.cursor() | ||
| cur.execute(schema_sql) | ||
| con.commit() | ||
| return con | ||
|
|
||
| async def execute(self, sql: LiteralString, *args: Any, commit: bool = False): | ||
| await self._asyncify(self._execute, sql, *args, commit=True) | ||
| if commit: | ||
| await self._asyncify(self.con.commit) | ||
|
|
||
| async def fetchall(self, sql: LiteralString, *args: Any) -> list[tuple[str, ...]]: | ||
| c = await self._asyncify(self._execute, sql, *args) | ||
| rows = await self._asyncify(c.fetchall) | ||
| return [tuple(row) for row in rows] | ||
|
|
||
| def _execute( | ||
| self, sql: LiteralString, *args: Any, commit: bool = False | ||
| ) -> sqlite3.Cursor: | ||
| cur = self.con.cursor() | ||
| cur.execute(sql, args) | ||
| if commit: | ||
| self.con.commit() | ||
| return cur | ||
|
|
||
| async def _asyncify( | ||
| self, func: Callable[P, R], *args: P.args, **kwargs: P.kwargs | ||
| ) -> R: | ||
| return await self._loop.run_in_executor( # type: ignore | ||
| self._executor, | ||
| partial(func, **kwargs), | ||
| *args, # type: ignore | ||
| ) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.