Your agent answered turn one. Turn two arrives. How do you pass the earlier exchange into the next call so the model knows what was just said?
Append the old turns to the new prompt somehow? Or is there a structured slot for history?
Simplest form — keep a Python list of strings, alternating user inputs and agent replies, and include it in the prompt every call. The smallest multi-turn call:
history = ["I'm planning a trip to Tokyo.", "Tokyo is beautiful — when are you going?"]
new_input = "Late September."
prompt = chr(10).join(history + [new_input])
reply = Agent(model).run_sync(prompt).output
print(reply)So history is just a list I append to each turn, and the whole history plus the new message is the prompt for the next call?
That is the minimal stateful pattern. The return value should be both the reply and the updated history — so the caller can pass it back on the next turn:
def stateful_response(history: list, new_input: str) -> dict:
prompt = chr(10).join(history + [new_input])
reply = Agent(model).run_sync(prompt).output
updated = history + [new_input, reply]
return {"response": reply, "updated_history": updated}Why return a dict with both fields instead of just the reply?
Because the caller needs the updated history to pass into turn three. If you only return the reply, the caller has to rebuild history itself. One dict with two keys keeps the contract tight — the agent owns what state flowed through this call.
So the function is pure — history in, {response, updated_history} out, and the caller loops as many turns as they want?
Pure and looping. State flows through the return value, not through a global. That is how stateful agents stay testable — every call is a function of its inputs and returns everything the next call needs.
TL;DR: join history + new input into one prompt; return {response, updated_history}.
history — list of alternating user and agent stringsnew_input — the user's next turnupdated_history — history + [new_input, reply]| Approach | Problem |
|---|---|
| Return reply only | Caller rebuilds state |
| Return dict | State flows with the call |
Pure functions make multi-turn agents testable — same inputs, same outputs, every turn.
Your agent answered turn one. Turn two arrives. How do you pass the earlier exchange into the next call so the model knows what was just said?
Append the old turns to the new prompt somehow? Or is there a structured slot for history?
Simplest form — keep a Python list of strings, alternating user inputs and agent replies, and include it in the prompt every call. The smallest multi-turn call:
history = ["I'm planning a trip to Tokyo.", "Tokyo is beautiful — when are you going?"]
new_input = "Late September."
prompt = chr(10).join(history + [new_input])
reply = Agent(model).run_sync(prompt).output
print(reply)So history is just a list I append to each turn, and the whole history plus the new message is the prompt for the next call?
That is the minimal stateful pattern. The return value should be both the reply and the updated history — so the caller can pass it back on the next turn:
def stateful_response(history: list, new_input: str) -> dict:
prompt = chr(10).join(history + [new_input])
reply = Agent(model).run_sync(prompt).output
updated = history + [new_input, reply]
return {"response": reply, "updated_history": updated}Why return a dict with both fields instead of just the reply?
Because the caller needs the updated history to pass into turn three. If you only return the reply, the caller has to rebuild history itself. One dict with two keys keeps the contract tight — the agent owns what state flowed through this call.
So the function is pure — history in, {response, updated_history} out, and the caller loops as many turns as they want?
Pure and looping. State flows through the return value, not through a global. That is how stateful agents stay testable — every call is a function of its inputs and returns everything the next call needs.
TL;DR: join history + new input into one prompt; return {response, updated_history}.
history — list of alternating user and agent stringsnew_input — the user's next turnupdated_history — history + [new_input, reply]| Approach | Problem |
|---|---|
| Return reply only | Caller rebuilds state |
| Return dict | State flows with the call |
Pure functions make multi-turn agents testable — same inputs, same outputs, every turn.
Create a free account to get started. Paid plans unlock all tracks.