Uh oh!
There was an error while loading. Please reload this page.
feat: added Pydantic AI sync, async, temporal integration - #359
Merged
Conversation
michael-chou359force-pushed
the
mc/pydantic-ai-converter
branch
from
May 18, 2026 23:29
86e30bb to
739f1e5Comparemichael-chou359force-pushed
the
mc/pydantic-ai-converter
branch
from
May 18, 2026 23:33
739f1e5 to
bee0223CompareReview the following changes in direct dependencies. Learn more about Socket for GitHub.
|
michael-chou359force-pushed
the
mc/pydantic-ai-converter
branch
from
May 19, 2026 18:37
d0dd9fd to
305d98eCompare
danielmillerp
left a comment
Contributor
There was a problem hiding this comment.
overall looks good!! can you just add the new templates as well see: src/agentex/lib/cli/
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
danielmillerp
commented
May 19, 2026
Contributor
also please fix linting ! |
danielmillerp
commented
May 19, 2026
Contributor
danielmillerp
commented
May 19, 2026
Contributor
and address any greptile comments ! |
Uh oh!
There was an error while loading. Please reload this page.
michael-chou359force-pushed
the
mc/pydantic-ai-converter
branch
from
May 19, 2026 23:22
5a6f0e9 to
5e8e3a2Comparemichael-chou359force-pushed
the
mc/pydantic-ai-converter
branch
from
May 19, 2026 23:26
ab93d9c to
7b6d7b5Comparedanielmillerp
approved these changes
May 20, 2026
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
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
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.

Pydantic AI Temporal:
Temporal logs also properly populated:
Pydantic AI Sync:
Events Mapping:
Edits to streaming.py:
CoalescingBuffer.close() was cancelling the background flush ticker mid-await leading to a race condition bug. When the cancellation landed after Redis had already accepted the write but before the await returned, the in-flight batch was re-enqueued and republished by close's final drain, producing a duplicated tail on the live UI stream. Fix: stop cancelling the ticker — signal _closed, let it finish whatever flush it's mid-way through, and let it exit naturally after its next drain pass. Each delta is now published exactly once. This bug showed up constantly with pydantic ai but not with the other integrations like langgraph or open ai sdk. Also this fix shouldn't lead to more silent losses: the "await self._on_flush(u)" is no longer interrupted so we know that the write will happen exactly once.
✅1. Sync streaming converter + tests (this PR)
✅2. Sync hello-world example agent (text-only streaming)
✅3. Sync agent with tools (tool-call delta streaming)
✅4. Tracing wired to SGP
✅5. Sync CLI template (agentex new-agent --type sync-pydantic-ai)
✅6. Async (non-Temporal) example
✅7. Temporal example using TemporalAgent + PydanticAIPlugin)
✅8. Async, Sync, Temporal template
Greptile Summary
This PR adds full Pydantic AI support to the Agentex SDK — sync HTTP streaming, async Redis streaming, a Temporal-compatible integration, CLI scaffold templates, and a bug fix for a race condition in
CoalescingBuffer.close()that produced duplicate stream tails._pydantic_ai_sync.pyconverts the Pydantic AI event stream intoStreamTaskMessage*events for HTTP yield;_pydantic_ai_async.pydrivesadk.streamingcontexts andadk.messages.createfor Redis-based delivery — both wired intoadk/__init__.py._pydantic_ai_tracing.pyrecords one deterministic child span per tool call using a stateless span-ID derivation (uuid5(trace_id, tool_call_id)) so spans pair correctly across Temporal activity boundaries._run()now exits naturally after its next drain pass rather than being cancelled mid-await, eliminating the duplicate-tail symptom caused by a Redis write completing before theCancelledErrorlanded; the regression test is updated to assert exactly-once delivery.Confidence Score: 5/5
Safe to merge — no data loss, no incorrect message routing, and the CoalescingBuffer fix is well-tested.
The streaming race-condition fix is correct: the ticker exits naturally after its own drain pass, the final drain in close() catches any items enqueued after the last tick, and the updated regression test asserts exactly-once delivery end-to-end. Both new converters faithfully map every Pydantic AI event type and handle edge cases (initial PartStart content, empty ThinkingPartDelta, dict vs. string tool args, RetryPromptPart). The tracing handler's stateless span-ID derivation is the right approach for cross-activity Temporal runs. Coverage is thorough.
No files require special attention.
Important Files Changed
Sequence Diagram
Comments Outside Diff (1)
src/agentex/lib/adk/_modules/_pydantic_ai_sync.py, line 431-450 (link)TextContentinstead ofReasoningContentThe sync converter emits
StreamTaskMessageStart(content=TextContent(...))forThinkingPartevents (line 434–440), but immediately follows withStreamTaskMessageDelta(delta=ReasoningContentDelta(...))deltas. The async counterpart (_pydantic_ai_async.py) consistently usesReasoningContentas the initial content type for the same event. The type mismatch — aTextContentstart receivingReasoningContentDeltaupdates — means any server-side logic that requires the accumulated message type to match the delta type will either fail silently or render thinking content as a plain text bubble rather than a collapsible reasoning block.ReasoningContentis not imported in this file at all, confirming the type was never set intentionally.Prompt To Fix With AI
Reviews (9): Last reviewed commit: "Merge branch 'next' into mc/pydantic-ai-..." | Re-trigger Greptile