State / the thread that holds a conversation
Adding conversation history to every call makes follow-up questions work. `state` grows unbounded with every turn — and vanishes completely when the session ends.
Architectural Position
- fn
- The LLM call, now receiving conversation history alongside query and context
- query_user
- The current user message
- state
- The conversation history — all prior turns in this session
- context
- Retrieved phone data injected for this turn
- response
- A contextually coherent response — aware of what was said before
Step by Step
# The failure from Layer 4
Turn 1: "show me phones for my mom"
→ Moto G84, Samsung A35, Pixel 9a
Turn 2: "what about the second one?"
→ Pipeline runs blind
→ Wrong phones returned
# Fix: pass conversation history to rewrite and respond
# fn(query_user, prompt_rewrite, schema, state) → query_structured
# fn(query_user, prompt_summarise, context, state) → responseWithout state, each turn is a fresh conversation. Follow-up questions lose all reference to prior results.
Implementation
What you build
- A
statemessage array that appends each turn (user + assistant) rewriteandrespondboth receive the fullstateon every call- UI: threaded summary where each turn appends below the previous
What it fixes
Follow-up questions resolve correctly. "What about the second one?" works because the prior turn is in the message array.
Key Concepts
- Message history
- The accumulated list of prior turns (user messages and assistant responses) in the current session. Passed to the model as part of every prompt.
- Session
- A bounded conversation — typically tied to a browser session or user login. State lives within a session; Memory persists across them.
- Sliding window
- Keeping only the last N turns of conversation history, discarding earlier turns to stay within the context budget.
- Summarisation buffer
- Compressing older turns into a rolling summary before they are dropped. Preserves meaning at the cost of precision.
The Failure
The Stateless LawModels are stateless by design. Everything they know about you lives in the window.
Turn 1 payload: [system, user_1, assistant_1] — ~800 tokens. Turn 3 payload: [system, user_1, assistant_1, user_2, assistant_2, user_3] — ~1500 tokens. By turn 10 the array is large. By turn 50 it has exceeded the context window or consumed most of the budget. And when the session ends, everything is gone. The user returns the next day and the system has no idea who they are.
What it reveals
state grows unbounded. Token costs increase every turn. Context window limits are hit at long conversations. Session end erases everything.