Staso Docs
Guides

Conversations

Group related traces together — conversations, workflows, whatever makes sense for your use case.

Usage

with st.conversation("conversation-42"):
    run_agent("What's my balance?")
    run_agent("Transfer $50")

Both runs and all their child spans get tagged with conversation-42.

Auto-Generated IDs

If you don't have a conversation ID, omit it — the SDK generates a UUID for you:

with st.conversation():
    run_agent("Hello!")

User Tracking

Associate a conversation with a user:

with st.conversation("conv-42", user_id="user-alice"):
    run_agent("What's my balance?")

All spans created within this context carry both the conversation ID and the user ID.

Common Patterns

# Conversations
with st.conversation(f"conv-{conversation_id}"):
    for message in messages:
        run_agent(message)

# Conversations with user tracking
with st.conversation(f"conv-{conversation_id}", user_id=current_user.id):
    run_agent(message)

# Workflows
with st.conversation(f"workflow-{job_id}"):
    step_1()
    step_2()

# Per-request
with st.conversation(request_id):
    handle_request(payload)

Propagation

Conversation IDs flow automatically through your entire call stack, including async code. You don't pass them around:

with st.conversation("my-conversation"):
    run_agent("hello")
    # Every @tool, @trace, and LLM call inside
    # is automatically tagged with "my-conversation"

Optional

Conversations are optional. Without them, traces still work — they just aren't grouped on the dashboard.

Nesting

Innermost conversation wins:

with st.conversation("outer"):
    run_agent("A")           # conversation = "outer"
    with st.conversation("inner"):
        run_agent("B")       # conversation = "inner"
    run_agent("C")           # conversation = "outer"

Parameters

ParameterTypeDefaultDescription
conversation_idstr | NoneNoneConversation identifier. Auto-generated UUID if omitted.
user_idstr | NoneNoneUser identifier. Attached to all spans in this context.