-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Description
DevUI multi-turn conversation, session isn't being honored. E.g.
user: "my name is Joe"
agent: "Hi Joe, nice to meet you!"
user: "what is my name"
agent: "I don’t know your name yet—you haven’t told me. What would you like me to call you?"
This is occurring in 1.0.0b260219 and 1.0.0rc1; 1.0.0b260130 works fine (although uses ChatAgent instead of Agent). Examples and potential fix below:
Fails in 1.0.0b260219 and 1.0.0rc1:
from agent_framework import Agent, tool
from agent_framework.openai import OpenAIChatClient
from agent_framework.devui import serve
@tool
def get_weather(location: str) -> str:
"""Get weather for a location."""
return f"Weather in {location}: 72F and sunny"
# Create your agent
agent = Agent(
name="WeatherAgent",
client=OpenAIChatClient(),
tools=[get_weather],
)
# Launch DevUI
serve(entities=[agent], auto_open=True)
# Opens browser to http://localhost:8080Works in 1.0.0b260130 (note older syntax)
from agent_framework import ChatAgent, tool
from agent_framework.openai import OpenAIChatClient
from agent_framework.devui import serve
@tool
def get_weather(location: str) -> str:
"""Get weather for a location."""
return f"Weather in {location}: 72F and sunny"
# Create your agent
agent = ChatAgent(
name="WeatherAgent",
chat_client=OpenAIChatClient(),
tools=[get_weather],
)
# Launch DevUI
serve(entities=[agent], auto_open=True)
# Opens browser to http://localhost:8080the following monkey patch demonstrates a potential fix the issue (sorry heading to work - no time to test and put in a PR, no idea what else this might break); key add was to finalize the stream before yielding the event.
# ---------------------------------------------------------------------------
# Workaround: DevUI streams agent.run() but never calls get_final_response(),
# so the result-hook that runs after_run providers (InMemoryHistoryProvider
# save_messages) never fires. Monkey-patch _execute_agent to finalize the
# stream after iteration so session history is persisted across turns.
# ---------------------------------------------------------------------------
import agent_framework_devui._executor as _executor_mod
from agent_framework._clients import ResponseStream
from agent_framework_devui.models._openai_custom import (
AgentStartedEvent,
AgentCompletedEvent,
AgentFailedEvent,
)
_orig_execute_agent = _executor_mod.AgentFrameworkExecutor._execute_agent
async def _patched_execute_agent(self, agent, request, trace_collector):
"""Wrap _execute_agent to call get_final_response() after streaming."""
conversation_id = request._get_conversation_id()
session = self.conversation_store.get_session(conversation_id) if conversation_id else None
if not session:
# No session — fall back to original (no history to persist)
async for event in _orig_execute_agent(self, agent, request, trace_collector):
yield event
return
# Session-aware path: capture stream ref so we can finalize it
try:
yield AgentStartedEvent()
user_message = self._convert_input_to_chat_message(request.input)
await self._ensure_mcp_connections(agent)
stream = agent.run(user_message, stream=True, session=session)
async for update in stream:
for trace_event in trace_collector.get_pending_events():
yield trace_event
yield update
# KEY FIX: finalize the stream so result-hooks (after_run) execute,
# which persists conversation history to session.state.
if isinstance(stream, ResponseStream):
await stream.get_final_response()
yield AgentCompletedEvent()
except Exception as e:
try:
yield AgentFailedEvent(error=e)
except Exception:
pass
yield {"type": "error", "message": f"Agent execution error: {e!s}"}
_executor_mod.AgentFrameworkExecutor._execute_agent = _patched_execute_agentCode Sample
Error Messages / Stack Traces
Package Versions
agent-framework: 1.0.0rc1, agent-framework-devui: 1.0.0b260219
Python Version
Python 3.13
Additional Context
No response
Metadata
Metadata
Assignees
Labels
Type
Projects
Status