Repository navigation
Description
Observed Behavior
With fresh_context=True, the agent still used the previous iteration’s quote when running with FileHistoryProvider. I was using a purchasing agent to calculate the total for two boxes of paper, then recalculate it after the supplier’s CSV price changed from $40 to $25 per box. I enabled fresh context and disabled progress injection so the second iteration would start without the earlier quote. The CSV was confirmed to contain $25 before the second model call, but the model’s input still included the previous $40 tool result.
Expected Behavior
With fresh_context=True and inject_progress=False, the second iteration should receive the original task and the pre-loop conversation, excluding the first iteration’s tool results and answers. For this task, it should read the updated CSV price of $25 per box and return 50 for two boxes.
Steps to Reproduce
- Config a LLM model, here I was using deepseek-v4.1-flash
- Run the python code I provided.
Minimal Reproduction
import asyncio
import os
from pathlib import Path
from tempfile import TemporaryDirectory
from agent_framework import Agent, FileHistoryProvider, tool
from agent_framework._harness._loop import AgentLoopMiddleware
from agent_framework.openai import OpenAIChatCompletionClient
async def main():
with TemporaryDirectory(prefix="paper-quotes-") as directory:
quote_file = Path(directory) / "quote.csv"
quote_file.write_text("item,price_per_box\npaper,40\n")
@tool
def read_quote() -> str:
"""Read the current supplier price per box of paper."""
return quote_file.read_text()
def next_quote(**kwargs):
quote_file.write_text("item,price_per_box\npaper,25\n")
return "Calculate the total for two boxes."
agent = Agent(
client=OpenAIChatCompletionClient(api_key=os.environ["DEEPSEEK_API_KEY"], base_url="https://api.deepseek.com/v1", model="deepseek-flash"),
instructions="Calculate the purchase total. Reply with only the numeric total, without a currency symbol.",
tools=[read_quote],
context_providers=[FileHistoryProvider(Path(directory) / "history")],
middleware=[AgentLoopMiddleware(
lambda iteration, **kwargs: iteration < 2,
next_message=next_quote, fresh_context=True, inject_progress=False,
return_final_only=True,
)],
default_options={"extra_body": {"thinking": {"type": "disabled"}}},
)
result = await agent.run("Calculate the total for two boxes.", session=agent.create_session())
print(result.text)
assert float(result.text.strip()) == 50, "The fresh pass should read the new $25 quote: 2 x 25 = $50."
asyncio.run(main())Error Messages and Stack Traces
Traceback (most recent call last):
File "/tmp/unified-context-audit/microsoft-agent-framework/investigation/fresh-loop-file-history/main.py", line 39, in <module>
asyncio.run(main())
File "/tmp/unified-context-audit/microsoft-agent-framework/conda-env/lib/python3.11/asyncio/runners.py", line 190, in run
return runner.run(main)
^^^^^^^^^^^^^^^^
File "/tmp/unified-context-audit/microsoft-agent-framework/conda-env/lib/python3.11/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/unified-context-audit/microsoft-agent-framework/conda-env/lib/python3.11/asyncio/base_events.py", line 654, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "/tmp/unified-context-audit/microsoft-agent-framework/investigation/fresh-loop-file-history/main.py", line 37, in main
assert float(result.text.strip()) == 50, "The fresh pass should read the new $25 quote: 2 x 25 = $50."
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: The fresh pass should read the new $25 quote: 2 x 25 = $50.
Package Versions
agent-framework-core: 1.25.0, agent-framework-openai: 1.18.1
Python Version
Python 3.11.15
Operating System
Linux
Regression
Unknown
Additional Context
No response
Acknowledgements
- I searched existing issues and did not find a duplicate.
- I personally verified this behavior and the reproduction details are authentic.
- I will wait for explicit maintainer agreement before starting implementation of a non-trivial change.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsNo status
Activity
github-actions commentedon Nov 12, 2026
Reproduced offline (no live model) on the current checkout: run.
A recording fake client with
FileHistoryProvider+AgentLoopMiddleware(fresh_context=True, inject_progress=False)received[user:task, assistant:ANSWER-1, user:task, user:again]on iteration 2, so iteration 1's answer leaks. With the default in-memory history the second call correctly receives[user:task, user:again].Likely cause from the source:
fresh_contextsnapshots and restores onlysession.stateandservice_session_id(_harness/_loop.py).FileHistoryProviderkeeps messages in an external append-only file keyed by session id, so the restore does not rewind it.Support boundary: direct support. The
fresh_contextdocstring andpython/packages/core/AGENTS.mdsay the local transcript is reset between iterations. Known-good version and fix: unknown. Your tool-call/CSV scenario was not run; the test only checks the model input. Priority and fix design are for maintainers. Routed to the harness owner.