-
Notifications
You must be signed in to change notification settings - Fork 1k
Open
Labels
azure-functionsIssues and PRs related to Azure FunctionsIssues and PRs related to Azure FunctionsbugSomething isn't workingSomething isn't workingpython
Description
Description
Durable agents using AzureOpenAIResponsesClient with tools fail on the second turn of a conversation. The call_id_to_id mapping is not restored from durable state.
What happened?
Second message on a thread fails with KeyError when conversation history contains tool calls.
What did you expect?
Multi-turn conversations with tools should work.
Steps to reproduce:
- Create durable agent with
AzureOpenAIResponsesClient+ a tool - Send message that triggers tool use → works
- Send follow-up message on same thread → fails
Code Sample
# function_app.py
import os
from typing import Annotated
from azure.identity import DefaultAzureCredential
from agent_framework import ChatAgent, AIFunction
from agent_framework.azure import AzureOpenAIResponsesClient, AgentFunctionApp
from pydantic import Field
class EchoTool(AIFunction):
def __init__(self):
super().__init__(
name="echo",
description="Echoes input back",
approval_mode="never_require",
)
async def run(self, message: Annotated[str, Field(description="Message")]) -> str:
return f"Echo: {message}"
client = AzureOpenAIResponsesClient(
endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
deployment_name=os.getenv("AZURE_OPENAI_DEPLOYMENT_NAME"),
credential=DefaultAzureCredential(),
)
agent = ChatAgent(
name="BugRepro",
chat_client=client,
instructions="Use the echo tool when asked.",
tools=[EchoTool()], # comment out and it works
)
app = AgentFunctionApp(agents=[agent])To Run in azure functions:
- Azurite running:
docker run -p 10000:10000 -p 10001:10001 -p 10002:10002 mcr.microsoft.com/azure-storage/azurite2. DTS emulator running:docker run -p 8080:8080 -p 8082:8082 mcr.microsoft.com/dts/dts-emulator:latest func start- local.settings.json configured with your Azure OpenAI endpoint
script to run to reproduce
#!/usr/bin/env bash
# Test script to reproduce the durable agent + tools bug
#
# Prerequisites:
# 1. Azurite running: docker run -p 10000:10000 -p 10001:10001 -p 10002:10002 mcr.microsoft.com/azure-storage/azurite
# 2. DTS emulator running: docker run -p 8080:8080 -p 8082:8082 mcr.microsoft.com/dts/dts-emulator:latest
# 3. func start running in this directory
# 4. local.settings.json configured with your Azure OpenAI endpoint
set -euo pipefail
BASE_URL="http://localhost:7071/api/agents/BugRepro"
echo "=========================================="
echo "Durable Agent + Tools Bug Reproduction"
echo "=========================================="
echo ""
# Step 1: First message - triggers tool use
echo "Step 1: Sending first message (triggers echo tool)..."
echo "Message: Please echo 'hello world'"
echo ""
response=$(curl -s -D /tmp/headers.txt -X POST "${BASE_URL}/run" \
-H "Content-Type: text/plain" \
-d "Please echo 'hello world'")
echo "Response: $response"
echo ""
# Extract thread ID
thread_guid=$(grep -i "x-ms-thread-id:" /tmp/headers.txt | cut -d' ' -f2 | tr -d '\r\n')
thread_id="${thread_guid}"
echo "Thread GUID: $thread_guid"
echo "Thread ID: $thread_id"
echo ""
# Step 2: Second message - should trigger the bug
echo "=========================================="
echo "Step 2: Sending second message on same thread..."
echo "Message: Now echo 'goodbye'"
echo "URL: ${BASE_URL}/run?thread_id=${thread_id}"
echo ""
echo "This should fail with KeyError: 'call_...' if the bug exists"
echo ""
read -p "Press Enter to send second message..."
echo ""
response=$(curl -s -X POST "${BASE_URL}/run?thread_id=${thread_id}" \
-H "Content-Type: text/plain" \
-d "Now echo 'goodbye'" 2>&1) || true
echo "Response: $response"
echo ""
echo "=========================================="
echo "Check the func start terminal for the KeyError stack trace"
echo "=========================================="
Error Messages / Stack Traces
File ".venv/lib/python3.12/site-packages/agent_framework/openai/_responses_client.py", line 602, in _prepare_content_for_openai
"id": call_id_to_id[content.call_id],
KeyError: 'call_Gnn7r7uMviCtJ5SSL64sh9oo'full stack
[2026-01-12T23:09:28.530Z] [AgentEntity.run] Agent execution failed.
[2026-01-12T23:09:28.530Z] Traceback (most recent call last):
[2026-01-12T23:09:28.530Z] File "/home/jstur/projects/local-code-interpreter-tool-project/local-code-interpreter-tool/.venv/lib/python3.12/site-packages/agent_framework_azurefunctions/_entities.py", line 162, in run
[2026-01-12T23:09:28.530Z] agent_run_response: AgentRunResponse = await self._invoke_agent(
[2026-01-12T23:09:28.530Z] File "/home/jstur/projects/local-code-interpreter-tool-project/local-code-interpreter-tool/.venv/lib/python3.12/site-packages/agent_framework_azurefunctions/_entities.py", line 251, in _invoke_agent
[2026-01-12T23:09:28.530Z] agent_run_response = await self._invoke_non_stream(run_kwargs)
[2026-01-12T23:09:28.530Z] File "/home/jstur/projects/local-code-interpreter-tool-project/local-code-interpreter-tool/.venv/lib/python3.12/site-packages/agent_framework_azurefunctions/_entities.py", line 284, in _invoke_non_stream
[2026-01-12T23:09:28.531Z] result = await result
[2026-01-12T23:09:28.531Z] File "/home/jstur/projects/local-code-interpreter-tool-project/local-code-interpreter-tool/.venv/lib/python3.12/site-packages/agent_framework/_middleware.py", line 1249, in middleware_enabled_run
[2026-01-12T23:09:28.531Z] return await original_run(self, normalized_messages, thread=thread, **kwargs) # type: ignore[return-value]
[2026-01-12T23:09:28.531Z] File "/home/jstur/projects/local-code-interpreter-tool-project/local-code-interpreter-tool/.venv/lib/python3.12/site-packages/agent_framework/observability.py", line 1364, in trace_run
[2026-01-12T23:09:28.531Z] response = await run_func(self, messages=messages, thread=thread, **kwargs)
[2026-01-12T23:09:28.531Z] File "/home/jstur/projects/local-code-interpreter-tool-project/local-code-interpreter-tool/.venv/lib/python3.12/site-packages/agent_framework/_agents.py", line 886, in run
[2026-01-12T23:09:28.531Z] response = await self.chat_client.get_response(
[2026-01-12T23:09:28.531Z] File "/home/jstur/projects/local-code-interpreter-tool-project/local-code-interpreter-tool/.venv/lib/python3.12/site-packages/agent_framework/_tools.py", line 1818, in function_invocation_wrapper
[2026-01-12T23:09:28.531Z] response = await func(self, messages=prepped_messages, **filtered_kwargs)
[2026-01-12T23:09:28.531Z] File "/home/jstur/projects/local-code-interpreter-tool-project/local-code-interpreter-tool/.venv/lib/python3.12/site-packages/agent_framework/observability.py", line 1104, in trace_get_response
[2026-01-12T23:09:28.531Z] response = await func(self, messages=messages, **kwargs)
[2026-01-12T23:09:28.531Z] File "/home/jstur/projects/local-code-interpreter-tool-project/local-code-interpreter-tool/.venv/lib/python3.12/site-packages/agent_framework/_middleware.py", line 1367, in middleware_enabled_get_response
[2026-01-12T23:09:28.532Z] return await original_get_response(self, messages, **kwargs)
[2026-01-12T23:09:28.532Z] File "/home/jstur/projects/local-code-interpreter-tool-project/local-code-interpreter-tool/.venv/lib/python3.12/site-packages/agent_framework/_clients.py", line 581, in get_response
[2026-01-12T23:09:28.532Z] return await self._inner_get_response(messages=prepped_messages, chat_options=chat_options, **filtered_kwargs)
[2026-01-12T23:09:28.532Z] File "/home/jstur/projects/local-code-interpreter-tool-project/local-code-interpreter-tool/.venv/lib/python3.12/site-packages/agent_framework/openai/_responses_client.py", line 94, in _inner_get_response
[2026-01-12T23:09:28.532Z] run_options = await self._prepare_options(messages, chat_options, **kwargs)
[2026-01-12T23:09:28.532Z] File "/home/jstur/projects/local-code-interpreter-tool-project/local-code-interpreter-tool/.venv/lib/python3.12/site-packages/agent_framework/openai/_responses_client.py", line 398, in _prepare_options
[2026-01-12T23:09:28.532Z] request_input = self._prepare_messages_for_openai(messages)
[2026-01-12T23:09:28.532Z] File "/home/jstur/projects/local-code-interpreter-tool-project/local-code-interpreter-tool/.venv/lib/python3.12/site-packages/agent_framework/openai/_responses_client.py", line 492, in _prepare_messages_for_openai
[2026-01-12T23:09:28.533Z] list_of_list = [self._prepare_message_for_openai(message, call_id_to_id) for message in chat_messages]
[2026-01-12T23:09:28.533Z] File "/home/jstur/projects/local-code-interpreter-tool-project/local-code-interpreter-tool/.venv/lib/python3.12/site-packages/agent_framework/openai/_responses_client.py", line 516, in _prepare_message_for_openai
[2026-01-12T23:09:28.533Z] function_call = self._prepare_content_for_openai(message.role, content, call_id_to_id)
[2026-01-12T23:09:28.533Z] File "/home/jstur/projects/local-code-interpreter-tool-project/local-code-interpreter-tool/.venv/lib/python3.12/site-packages/agent_framework/openai/_responses_client.py", line 602, in _prepare_content_for_openai
[2026-01-12T23:09:28.533Z] "id": call_id_to_id[content.call_id],
[2026-01-12T23:09:28.533Z] KeyError: 'call_4pFYHvE2vw0kMjGh363YftBM'
agent-framework: 1.0.0b251218, agent-framework-azurefunctions: 1.0.0b251218
Python Version
Python 3.12.3
Additional Context
- Works without tools (multi-turn succeeds)
Metadata
Metadata
Assignees
Labels
azure-functionsIssues and PRs related to Azure FunctionsIssues and PRs related to Azure FunctionsbugSomething isn't workingSomething isn't workingpython
Type
Projects
Status
No status