Open
Description
Question
This is a demo,the main feature is return the stream response after the agent do the tool calling,the fault is the finally response is empty string.The target function is query
.
import fastapi
from fastapi.responses import StreamingResponse,FileResponse,JSONResponse
import time
import logfire
from pathlib import Path
from typing import Annotated,Any
import random
from pydantic_ai.providers.openai import OpenAIProvider
from pydantic_ai.models.openai import OpenAIModel
from dotenv import load_dotenv
import os
from pydantic_ai import Agent,RunContext,Tool
import json
load_dotenv()
deepseek_key=os.getenv("DEEPSEEK_API")
base_url=os.getenv("DEEPSEEK_API_BASE")
system_prompt ="""\
You're a dice game, you should roll the die and see if the number
you get back matches the user's guess. If so, tell them they're a winner.
Use the player's name in the response.
"""
def roll_die()-> str:
"""Roll a six sided die and return the result."""
return str(random.randint(1,6))
def get_player_name(ctx:RunContext[str])-> str:
"""Get the player's name"""
return ctx.deps
model=OpenAIModel(
"deepseek-chat",
provider=OpenAIProvider(base_url=base_url,api_key=deepseek_key)
)
agent =Agent(
model,
system_prompt=system_prompt,
deps_type=str,
tools=[roll_die,Tool(get_player_name,takes_ctx=True)],
instrument=True
)
logfire.configure(send_to_logfire='if-token-present')
app = fastapi.FastAPI()
logfire.instrument_fastapi(app,capture_headers=True)
THIS_DIR=Path(__file__).parent
def generate_large_text(turns:int):
for i in range(turns):
yield f"This is line {i+1}\n"
time.sleep(0.5)
@app.get("/stream/{turns}")
async def stream_response(turns:int):
return StreamingResponse(generate_large_text(turns),media_type="text/plain")
@app.get("/")
async def index():
return FileResponse((THIS_DIR/"agent_home.html"),media_type="text/html")
# this is the main function
@app.post("/query")
async def query(prompt:Annotated[str,fastapi.Form()],uname:Annotated[str,fastapi.Form()])-> StreamingResponse:
async def stream_messages(randInt:int=0):
async with agent.run_stream(prompt,deps=uname) as result:
async for text in result.stream(debounce_by=0.01):
print("text:",text)
yield json.dumps({"id":randInt,"text":text}).encode('utf-8')+b'\n'
ranInt = random.randint(0,199)
print({"uname":uname,"prompt":prompt})
return StreamingResponse(stream_messages(ranInt),media_type='text/plain')
if __name__=="__main__":
import uvicorn
uvicorn.run("agnet_api_demo:app",host="0.0.0.0",reload=True,port=7474)
This is the log.u can see the tool calling is after stream response.
How can i return the content after tool calling with stream response?
Additional Context
pydantic 2.11.3
pydantic-ai 0.0.46
pydantic-ai-examples 0.0.46
pydantic-ai-slim 0.0.46
pydantic_core 2.33.1
pydantic-graph 0.0.46
pydantic-settings 2.8.1
python 3.10.12
LLM deepseek-chat