Skip to content

.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

@nomhiro

Description

@nomhiro

Description

Summary

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'.

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.4

Python Version

3.12.11

Additional Context

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.

Related issues

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

  1. 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.
  2. Add a documentation note about the current limitation on the AG-UI integration page until fixed.
  3. Coordinate with CopilotKit#3884 / PR .NET: AF version bump 12-feb #3885 if the fix needs to land on both sides.

Workaround tried

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.

Metadata

Metadata

Assignees

Type

No fields configured for Bug.

Projects

Status

No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions