Skip to main content

Conversations

Use client.conversations to list conversation metadata and create or resume interactive AsyncConversation objects.

Listing conversations

page = await client.conversations.list(limit=20)

for conv in page.conversations:
    count = "unknown" if conv.message_count is None else conv.message_count
    print(f"{conv.title or 'Untitled'} - {count} messages")
page.total is the full count matching the list filters, not just the number returned on the current page. Use agent_id, source_ref_id, source, and exclude_source to narrow list results. Tenant-wide all_users=True requires source_ref_id.

Searching conversations

matches = await client.conversations.search("Acme renewal", limit=10)

for conv in matches.conversations:
    print(conv.title, conv.updated_at)

Creating and sending

agent_id = (await client.agents.by_name("MainAgent")).id
conversation = await client.conversations.create(agent_id=agent_id)

result = await conversation.send("What open opportunities do we have?")
print(result.text)

Streaming

from agentflow.events import FinalResponse, TextDelta

async for event in conversation.stream("Summarize the last answer"):
    if isinstance(event, TextDelta):
        print(event.text, end="", flush=True)
    elif isinstance(event, FinalResponse):
        print(event.text)
For cancellable background-style consumption, create a run handle:
run = conversation.run_handle("Analyze Acme")

async for event in run:
    if should_stop(event):
        await run.cancel()
        break

Watching for reconnects

async for event in client.conversations.watch(conversation.id):
    if event.type == "conversation_update":
        render(event.content)
Conversation watches recover from durable snapshots. AgentFlow emits SSE id: fields for snapshots; pass the last one as last_event_id on reconnect.

Retrieving a conversation

conversation = await client.conversations.resume("conv_abc123")
detail = await conversation.refresh()

for msg in detail.messages:
    print(f"[{msg.role}] {msg.content[:100]}...")

Title management

title = await client.conversations.generate_title(
    conversation.id,
    seed_message="What does our Q3 pipeline look like?",
    force=True,
)

await conversation.set_title("Q3 Revenue Analysis")

Deleting conversations

await client.conversations.delete("conv_abc123")

Message dataclass

FieldTypeDescription
idstrMessage ID
rolestr"user" or "assistant" for flat conversation messages
contentstrMessage text content
timestamp`datetimeNone`When the message was created