Skip to content
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

Use .iter() API to fully replace existing streaming implementation #951

Merged
merged 10 commits into from
Feb 27, 2025

Conversation

dmontagu
Copy link
Contributor

This is a work in progress on top of #833. I wanted to see this through to make sure that we had a plan for using the node streaming from #833 to replace our current streaming implementation APIs, and with this branch in the state it is, I feel pretty convinced that it's going to work and we'll be able to use the implementation here (perhaps with some tweaks) to achieve full capability parity with the existing APIs, while also being significantly more flexible and powerful.

I think we should merge #833 first without it being capable of fully replacing the Agent.run_stream API, etc., but once that is merged I think we should aim to merge this shortly after and use it to replace the streaming APIs more fully.

Copy link

github-actions bot commented Feb 20, 2025

Docs Preview

commit: e73b85b
Preview URL: https://f42c16c8-pydantic-ai-previews.pydantic.workers.dev

Base automatically changed from dmontagu/graph-run-object to main February 20, 2025 21:17
@dmontagu dmontagu force-pushed the dmontagu/graph-run-streaming branch from 302b8bf to 55ab7f0 Compare February 23, 2025 21:51
@dmontagu dmontagu marked this pull request as ready for review February 26, 2025 06:30
@dmontagu
Copy link
Contributor Author

I think this is basically ready to merge, but I have one question about API choice I'll call out in-line

docs/agents.md Outdated
# Begin a node-by-node, streaming iteration
with weather_agent.iter(user_prompt, deps=deps) as run:
async for node in run:
if Agent.is_model_request_node(node):
Copy link
Contributor Author

@dmontagu dmontagu Feb 26, 2025

Choose a reason for hiding this comment

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

I think the main question I have is whether we should have these node-narrowing typeguards as:

  • static methods on Agent, as I have here
  • static methods on AgentRun
  • static methods on the various node types (i.e., an is_type_of staticmethod; I'll note I tried this and felt it was worse/more confusing)
  • free-floating functions

so far I think static method on Agent is best, but I see merits to each of these, though I'll note that static methods on the node types was what I implemented first and was my least favorite of the alternatives for various reasons.

@@ -107,8 +107,31 @@ class GraphAgentDeps(Generic[DepsT, ResultDataT]):
run_span: logfire_api.LogfireSpan


class AgentNode(BaseNode[GraphAgentState, GraphAgentDeps[DepsT, Any], result.FinalResult[NodeRunEndT]]):
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried using a type-alias instead of a class here, and it caused some issues because I couldn't inherit from it.

I think may be possible to drop the AgentNode class and use a type alias (just inheriting from the non-aliased parametrized BaseNode), and either way I think it's not currently public, but I think having this type allows us to remove most references to BaseNode in agent.py, which I think ultimately makes a lot of types more readable.

Unless one of you really objects, I would prefer to keep it around for now rather than wrestle with the consequences of removing it (in terms of verbosity and/or type-checking challenges). Especially considering it isn't a public API anyway.

Comment on lines +276 to +279
# In case the user didn't manually consume the full stream, ensure it is fully consumed here,
# otherwise usage won't be properly counted:
async for _ in agent_stream:
pass
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Kludex not 100% sure if we should do this force-consume-the-stream (when there isn't an exception), but I think it's what we should do. (Unless we confirm that you don't get charged for streams you don't consume, but that seems unlikely.)

@dmontagu dmontagu force-pushed the dmontagu/graph-run-streaming branch 2 times, most recently from e736b47 to 54aff03 Compare February 27, 2025 23:24
@dmontagu dmontagu force-pushed the dmontagu/graph-run-streaming branch from 54aff03 to e73b85b Compare February 27, 2025 23:26
@dmontagu dmontagu merged commit 196d918 into main Feb 27, 2025
17 checks passed
@dmontagu dmontagu deleted the dmontagu/graph-run-streaming branch February 27, 2025 23:30
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.

None yet

1 participant