-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
Description
What happens
With an agent configured with a history provider that disables loading/storing messages (for example InMemoryHistoryProvider(load_messages=False, store_inputs=False, store_outputs=False)), behavior differs by client:
- Chat-style client: forgets previous turns (expected)
- Responses-style client: still remembers previous turns (unexpected)
This also causes usage/token accounting confusion because previous messages are not visible e.g. in OTEL logs, but still influence the model.
Expected behavior
When context providers are configured, they should be the only source of message history unless explicitly overridden by runtime options.
In particular, if a history provider disables load/store, subsequent runs in the same session should not implicitly include prior conversation state.
Found root cause
In agent_framework/_agents.py, Agent._prepare_run_context always forwards session.service_session_id to conversation_id.
For Responses-style clients, that becomes previous_response_id, which reattaches server-side history regardless of history provider policy.
Proposed fix direction
Only forward session.service_session_id implicitly when no history provider is configured (or when explicitly requested), and always honor explicit runtime conversation_id overrides. I have a
Packages
Tested with 1.0.0rc3 and the main branch with hash ded32f3
MWE
See below. The agent is tasked with creating a recipe and recalling the ingredients in a later conversation turn. Since the memory provider discards all messages, this shouldn't be possible. It works however in the responses client in contrast to the chat client.
Code Sample
from agent_framework.openai import OpenAIChatClient, OpenAIResponsesClient
from agent_framework import InMemoryHistoryProvider
import asyncio
async def test_auto_compaction():
forgetful_provider = InMemoryHistoryProvider(load_messages=False, store_inputs=False, store_context_messages=False, store_outputs=False)
#agent = OpenAIChatClient().as_agent(context_providers=[forgetful_provider]) # <- This will not remember the history
agent = OpenAIResponsesClient().as_agent(context_providers=[forgetful_provider]) # <- This will remember the history
session = agent.create_session()
print(await agent.run("Hi, just respond with `hi!`", session=session))
print(await agent.run("Write me lasagna recipe in two paragraphs", session=session))
print(await agent.run("Please provide an exact bullet list of the ingredients you gave previously. If you don't see it anymore in the conversation, tell me so, don't start making up things.", session=session))
print(await agent.run("Do you see duplicate messages in the conversation (1:1 copies only)?", session=session))
return
if __name__ == "__main__":
from dotenv import load_dotenv
load_dotenv()
# Activate if you want to observe the traces on Langfuse
# from agent_framework.observability import enable_instrumentation
# from langfuse import get_client
# langfuse_client = get_client()
# assert langfuse_client.auth_check(), "Langfuse auth failed"
# enable_instrumentation(enable_sensitive_data=True)
asyncio.run(test_auto_compaction())Error Messages / Stack Traces
# Chat client output:
hi!
For a classic 9x13-inch lasagna (about 6–8 servings) gather: 12 lasagna noodles (or one 12-oz package no-boil noodles), 1 lb (450 g) [...rest of the recipe omitted]
I don't see any previous ingredient list in this conversation. I won't make one up. If you paste the original text or tell me which recipe or message you mean, I'll provide an exact bullet list.
No — I don't see any exact 1:1 duplicate messages in this conversation. The system message and the user message are distinct. Would you like me to check a longer chat history or look for near-duplicates (paraphrases)?# Responses client output:
hi!
For 6–8 servings: 1 lb (450 g) ground beef or a mix of beef and pork, 1 medium onion (finely chopped), 2–3 garlic cloves (minced), 28 oz (800 g) canned crushed tomatoes, [...rest of the recipe omitted]
- 1 lb (450 g) ground beef or a mix of beef and pork
- 1 medium onion (finely chopped)
- 2–3 garlic cloves (minced)
- 28 oz (800 g) canned crushed tomatoes
- 6 oz (170 g) tomato paste
- 1/2 cup (120 ml) red wine (optional)
- 1 tsp sugar
- 1 tsp dried oregano
- 1 tsp dried basil
- salt and pepper to taste
- 2 tbsp olive oil
- 9–12 lasagna noodles (regular or no-boil)
- 15 oz (425 g) ricotta cheese (or cottage cheese)
- 1 large egg
- 1/4 cup grated Parmesan
- 2–3 cups shredded mozzarella plus extra for topping
- Optional béchamel: 3 tbsp butter, 3 tbsp flour, 2 cups milk, pinch of nutmeg
No — I don't see any 1:1 duplicate messages in this conversation.Package Versions
agent-framework-1.0.0rc3
Python Version
Python 3.12.10
Additional Context
Tested with OpenAI gpt-5-mini
Metadata
Metadata
Assignees
Labels
Type
Projects
Status