Python SDK
Conversations
st.conversation(...) groups related traces into one conversation for easier debugging and analytics. Every trace produced inside the context inherits the same conversation_id.
import staso as st
with st.conversation("user-42-chat-7", user_id="user-42"):
for turn in chat_turns:
run_agent(turn)Signature
st.conversation(
conversation_id: str | None = None,
*,
user_id: str | None = None,
) -> ContextManager[None]| Parameter | Type | Default | Description |
|---|---|---|---|
conversation_id | str | None | None | Your conversation identifier. If omitted, a new UUID is generated automatically. |
user_id | str | None | None | Optional end-user identifier. If provided, every trace inside inherits it. |
Behavior
- Every trace produced inside the
withblock — whether started by a decorator or a manual span — shares the sameconversation_id. - Nesting conversations is supported; the innermost scope wins.
- If you omit
conversation_id, the SDK generates a UUID. Use that when you just want to group a burst of calls without caring about the ID.
When to use
- Multi-turn chatbots — one conversation per chat thread, so every turn a user sends lands on the same timeline.
- Long-running agent tasks — one conversation for a single user request like "book me a flight to SFO", even when the agent takes 12 tool calls and 4 LLM calls to finish it.
- Background jobs — one conversation per job run, so every trace from that run lives under one ID.
Conversations compose with decorators and manual spans — nothing else in your code needs to change.
@st.agent
def chat_turn(message: str) -> str:
return llm.respond(message)
with st.conversation() as _: # auto-generated UUID
chat_turn("hi")
chat_turn("what can you do?")
chat_turn("book me a flight")