Skip to content

Commit 0660582

Browse files
authored
fix: Make session list inputs auto-append by default (#2282)
1 parent 675a091 commit 0660582

File tree

2 files changed

+13
-25
lines changed

2 files changed

+13
-25
lines changed

src/agents/run.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2056,23 +2056,15 @@ async def _prepare_input_with_session(
20562056
if session is None:
20572057
return input
20582058

2059-
# If the user doesn't specify an input callback and pass a list as input
2060-
if isinstance(input, list) and not session_input_callback:
2061-
raise UserError(
2062-
"When using session memory, list inputs require a "
2063-
"`RunConfig.session_input_callback` to define how they should be merged "
2064-
"with the conversation history. If you don't want to use a callback, "
2065-
"provide your input as a string instead, or disable session memory "
2066-
"(session=None) and pass a list to manage the history manually."
2067-
)
2068-
20692059
# Get previous conversation history
20702060
history = await session.get_items()
20712061

20722062
# Convert input to list format
20732063
new_input_list = ItemHelpers.input_to_new_input_list(input)
20742064

20752065
if session_input_callback is None:
2066+
# Historically we rejected list inputs without an explicit callback to avoid
2067+
# ambiguous merges; the default now appends new items to history for ergonomics.
20762068
return history + new_input_list
20772069
elif callable(session_input_callback):
20782070
res = session_input_callback(history, new_input_list)

tests/test_session.py

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import pytest
88

99
from agents import Agent, RunConfig, Runner, SQLiteSession, TResponseInputItem
10-
from agents.exceptions import UserError
1110

1211
from .fake_model import FakeModel
1312
from .test_responses import get_text_message
@@ -371,10 +370,8 @@ async def test_sqlite_session_get_items_with_limit():
371370

372371
@pytest.mark.parametrize("runner_method", ["run", "run_sync", "run_streamed"])
373372
@pytest.mark.asyncio
374-
async def test_session_memory_rejects_both_session_and_list_input(runner_method):
375-
"""Test that passing both a session and list input raises a UserError across all runner
376-
methods.
377-
"""
373+
async def test_session_memory_appends_list_input_by_default(runner_method):
374+
"""Test that list inputs are appended to session history when no callback is provided."""
378375
with tempfile.TemporaryDirectory() as temp_dir:
379376
db_path = Path(temp_dir) / "test_validation.db"
380377
session_id = "test_validation_parametrized"
@@ -383,19 +380,18 @@ async def test_session_memory_rejects_both_session_and_list_input(runner_method)
383380
model = FakeModel()
384381
agent = Agent(name="test", model=model)
385382

386-
# Test that providing both a session and a list input raises a UserError
387-
model.set_next_output([get_text_message("This shouldn't run")])
388-
389-
list_input = [
390-
{"role": "user", "content": "Test message"},
383+
initial_history: list[TResponseInputItem] = [
384+
{"role": "user", "content": "Earlier message"},
385+
{"role": "assistant", "content": "Saved reply"},
391386
]
387+
await session.add_items(initial_history)
388+
389+
list_input = [{"role": "user", "content": "Test message"}]
392390

393-
with pytest.raises(UserError) as exc_info:
394-
await run_agent_async(runner_method, agent, list_input, session=session)
391+
model.set_next_output([get_text_message("This should run")])
392+
await run_agent_async(runner_method, agent, list_input, session=session)
395393

396-
# Verify the error message explains the issue
397-
assert "list inputs require a `RunConfig.session_input_callback" in str(exc_info.value)
398-
assert "to manage the history manually" in str(exc_info.value)
394+
assert model.last_turn_args["input"] == initial_history + list_input
399395

400396
session.close()
401397

0 commit comments

Comments
 (0)