You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
.NET: Python: [Bug]: Multi-turn tool calls fail with both Responses API and Chat Completions API when used via agent-framework-ag-ui (Foundry project endpoint) #5941
Using agent-framework-ag-ui from Python with a Microsoft Foundry project inference endpoint, the first turn of a tool-calling chat works correctly, but any second or later turn that follows a tool call fails with a 400 from the upstream OpenAI API.
The failure mode differs by client type but both surface a consistent root cause: when AG-UI replays conversation history on subsequent turns, the messages produced by the prior tool-calling turn are not paired correctly with their tool results before being sent back to the LLM.
This affects all four AG-UI features we tested (Agentic Chat, Human-in-the-Loop, Shared State, Agentic Generative UI) as soon as the agent has invoked any tool at least once.
Code Sample
## Reproduction
Minimal server (full repo: <will-be-linked>):
import os
from agent_framework import Agent, tool
from agent_framework.openai import OpenAIChatClient # or OpenAIChatCompletionClient — both fail
from agent_framework_ag_ui import add_agent_framework_fastapi_endpoint
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from dotenv import load_dotenv
load_dotenv()
@tool
def search_cars(car_class: str | None = None) -> list[dict]:
return [{"car_id": "SUV-001", "class": "suv", "daily_jpy": 12800}]
client = OpenAIChatClient( # also tried OpenAIChatCompletionClient — same outcome, different error
model=os.environ["FOUNDRY_MODEL"],
base_url=os.environ["FOUNDRY_BASE_URL"], # ".../openai/v1"
api_key=os.environ["FOUNDRY_API_KEY"],
)
agent = Agent(
name="ShirokumaChat",
instructions="You are a car rental booking assistant.",
client=client,
tools=[search_cars],
)
app = FastAPI()
app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"])
add_agent_framework_fastapi_endpoint(app, agent, "/agentic_chat")
Steps:
1. Start the server on `localhost:8888`.
2. In AG-UI Dojo (running locally), open the Agentic Chat tab for `Microsoft Agent Framework (Python)`.
3. Send turn 1: "Show me your SUV cars" → tool is called, response streams correctly. ✅
4. Send turn 2 in the **same** chat session (anything, e.g. "What's the price?") → server returns 200 but the stream contains a `RUN_ERROR` and no text response. ❌
Error Messages / Stack Traces
## Expected behavior
Subsequent turns should continue the conversation, with the agent having access to the tool result from the previous turn.
## Actual behavior### With `OpenAIChatClient` (Responses API)
openai.BadRequestError: Error code: 400 - {
'error': {
'message': 'No tool output found for function call call_cLJJ7tsAQL9j7ZK3J1g8ca30.',
'type': 'invalid_request_error',
'param': 'input',
'code': None
}
}
Full traceback (abridged):
File ".venv/Lib/site-packages/agent_framework_openai/_chat_client.py", line 647, in _stream
async for chunk in await client.responses.create(stream=True, **run_options):
File ".venv/Lib/site-packages/openai/resources/responses/responses.py", line 2626, in create
return await self._post(...)
agent_framework.exceptions.ChatClientException: OpenAIChatClient service failed to complete the prompt: 400 - No tool output found for function call call_cLJJ7tsAQL9j7ZK3J1g8ca30.
### With `OpenAIChatCompletionClient` (Chat Completions API)
openai.BadRequestError: Error code: 400 - {
'error': {
'message': "An assistant message with 'tool_calls' must be followed by tool messages responding to each 'tool_call_id'. The following tool_call_ids did not have response messages: call_7jOeA41CWTxLIyheCJnxqr6G, call_cWxiZjHImVV1KTq6ajOqTbnB",
'type': 'invalid_request_error',
'param': 'messages.[3].role',
'code': None
}
}
Full traceback (abridged):
File ".venv/Lib/site-packages/agent_framework_openai/_chat_completion_client.py", line 522, in _stream
async for chunk in await client.chat.completions.create(stream=True, **options_dict):
agent_framework.exceptions.ChatClientException: OpenAIChatCompletionClient service failed to complete the prompt:
An assistant message with 'tool_calls' must be followed by tool messages responding to each 'tool_call_id'.
Frontend: AG-UI Dojo (apps/dojo in ag-ui-protocol/ag-ui, latest main), integration = Microsoft Agent Framework (Python), pointed at our local server via AGENT_FRAMEWORK_PYTHON_URL=http://localhost:8888.
Backend endpoint: Microsoft Foundry project inference URL of the form https://<resource>.services.ai.azure.com/api/projects/<project>/openai/v1
authenticated with an API key.
Why both APIs fail (analysis)
Both errors point at the same root cause from different angles:
Chat Completions strictly requires (assistant{tool_calls}, tool{tool_call_id}) pairs to be interleaved in the messages array. The 400 says the tool role messages are missing from the replayed history.
Responses API expects function call results to be presented as function_call_output items in input. The 400 says the output for a specific call_id is missing.
In both cases, AG-UI's HttpAgent (or whatever produces the replayed history sent to the Python backend) is dropping or mis-pairing the tool result messages from the previous turn. The server-side agent-framework-ag-ui pipeline appears to pass this incomplete history through to the chat client without reconstructing the missing pairs.
This issue intentionally reports the end-to-end symptom on Python + Foundry with both client types, because the existing issues are scattered (per-API, per-platform, per-feature) and the impression from a user's perspective is that AG-UI is currently unusable for any multi-turn tool-calling scenario in Python — which is not made visible in the AG-UI integration docs or the Microsoft Community Hub announcement post.
Requests
Confirm whether the root cause is server-side (agent-framework-ag-ui history reconstruction) or client-side (AG-UI Dojo / HttpAgent not sending tool results back) — or both.
Add a documentation note about the current limitation on the AG-UI integration page until fixed.
We are evaluating the workaround suggested in CopilotKit#3884: subclass AgentFrameworkAgent to scan input messages and inject synthetic tool (or function_call_output) entries for any tool_call_id that lacks a matching result before handing off to the chat client. Will follow up here with results.
Description
Summary
Using
agent-framework-ag-uifrom Python with a Microsoft Foundry project inference endpoint, the first turn of a tool-calling chat works correctly, but any second or later turn that follows a tool call fails with a 400 from the upstream OpenAI API.The failure mode differs by client type but both surface a consistent root cause: when AG-UI replays conversation history on subsequent turns, the messages produced by the prior tool-calling turn are not paired correctly with their tool results before being sent back to the LLM.
This affects all four AG-UI features we tested (Agentic Chat, Human-in-the-Loop, Shared State, Agentic Generative UI) as soon as the agent has invoked any tool at least once.
Code Sample
Error Messages / Stack Traces
Package Versions
agent-framework-core 1.4.0,agent-framework-ag-ui 1.0.0rc1,agent-framework-openai 1.4.0,ag-ui-protocol 0.1.18,openai 2.37.0,fastapi 0.133.0,pydantic 2.13.4Python Version
3.12.11
Additional Context
Frontend: AG-UI Dojo (
apps/dojoinag-ui-protocol/ag-ui, latestmain), integration =Microsoft Agent Framework (Python), pointed at our local server viaAGENT_FRAMEWORK_PYTHON_URL=http://localhost:8888.Backend endpoint: Microsoft Foundry project inference URL of the form
https://<resource>.services.ai.azure.com/api/projects/<project>/openai/v1authenticated with an API key.
Why both APIs fail (analysis)
Both errors point at the same root cause from different angles:
(assistant{tool_calls}, tool{tool_call_id})pairs to be interleaved in themessagesarray. The 400 says thetoolrole messages are missing from the replayed history.function_call_outputitems ininput. The 400 says the output for a specificcall_idis missing.In both cases, AG-UI's
HttpAgent(or whatever produces the replayed history sent to the Python backend) is dropping or mis-pairing the tool result messages from the previous turn. The server-sideagent-framework-ag-uipipeline appears to pass this incomplete history through to the chat client without reconstructing the missing pairs.Related issues
with_plan_reviewin Magentic workflow + AG-UIThis issue intentionally reports the end-to-end symptom on Python + Foundry with both client types, because the existing issues are scattered (per-API, per-platform, per-feature) and the impression from a user's perspective is that AG-UI is currently unusable for any multi-turn tool-calling scenario in Python — which is not made visible in the AG-UI integration docs or the Microsoft Community Hub announcement post.
Requests
agent-framework-ag-uihistory reconstruction) or client-side (AG-UI Dojo /HttpAgentnot sending tool results back) — or both.Workaround tried
We are evaluating the workaround suggested in CopilotKit#3884: subclass
AgentFrameworkAgentto scan input messages and inject synthetictool(orfunction_call_output) entries for anytool_call_idthat lacks a matching result before handing off to the chat client. Will follow up here with results.