Multi-turn Conversations
Mango preserves conversation history across ask() calls. Follow-up questions work without repeating context.
Example
r1 = await agent.ask("How many orders were placed last week?")
print(r1.answer)
# → "1,247 orders were placed in the last 7 days."
r2 = await agent.ask("And how many of those were delivered?")
print(r2.answer)
# → "Of last week's 1,247 orders, 891 (71%) have been delivered."
r3 = await agent.ask("Which customer placed the most?")
print(r3.answer)
# → "Alice Johnson placed 8 orders last week, the highest of any customer."
The agent remembers that "those" refers to last week's orders and "the most" refers to the same context.
Conversation pruning
History is automatically trimmed to max_turns complete turns to keep token usage stable:
agent = MangoAgent(..., max_turns=5) # keep last 5 turns (default)
Pruning always removes complete turns — never splits a tool call from its result, which would cause API errors.
At the start of each new turn, historical tool results longer than 600 characters are also compacted in place to row_count plus 3 sample rows (the tool-call pairing is untouched). This keeps token usage flat; a follow-up that needs the raw rows makes the agent re-run the query. Set MANGO_COMPACT_TOOL_RESULTS=0 to disable.
Check conversation length
print(agent.conversation_length) # number of messages in history
Reset conversation
agent.reset_conversation() # clear history, start fresh
Multiple sessions from one agent
Use new_session() to get independent conversation threads that share the same schema and configuration:
# One agent, two independent sessions
session_a = agent.new_session()
session_b = agent.new_session()
await session_a.ask("How many users are in the EU?")
await session_b.ask("What is the average order value?")
# session_a and session_b have separate histories
This is efficient — schema introspection and system prompt are computed once and shared. The middleware chain is shared too, so agent.use(...) after startup applies to every session.
Session management in a server
MangoFastAPIServer ships a SessionManager that does this for you: one new_session() per session_id, idle sessions evicted after 1800 s, at most 1000 live sessions (LRU), each session bound to the user it was created for — see FastAPI Server. If you run your own server, the minimal version is:
from fastapi import FastAPI
import uuid
app = FastAPI()
sessions: dict[str, MangoAgent] = {}
@app.post("/ask")
async def ask(body: dict):
session_id = body.get("session_id") or str(uuid.uuid4())
if session_id not in sessions:
sessions[session_id] = agent.new_session()
response = await sessions[session_id].ask(body["question"])
return {"answer": response.answer, "session_id": session_id}