Chat Sessions
Overview
Tasks (run_tasks_until_done) are fire-and-forget, not interactive. A chat session is a long-lived conversation with an agent that keeps its sandbox, its workspace files, and its message history across turns.
from edison_client import EdisonClient
client = EdisonClient() # reads EDISON_API_KEYChat lives on ChatMethods, mixed into EdisonClient, and is backed by the /v0.1/chat and /v0.1/conversations endpoints. Every method has an a-prefixed async twin (asend_chat_message, aget_conversation, …).
send_chat_message(project_id, message, ...)
Send a turn; opens a session if session_id is omitted
get_conversation(session_id, ...)
Read message history for one session
get_conversations(...)
List sessions the caller can see
queue_chat_message(session_id, project_id, message)
Inject a message into a turn already running
recover_chat_session(session_id, project_id, ...)
Warm a session back up after its sandbox expired
store_conversation_message(session_id, message, ...)
Append a message to history without dispatching a turn
send_chat_message returns as soon as the turn is dispatched to a sandbox — a session_id and a pending status — not the agent's answer.
first = client.send_chat_message(
project_id,
"Which of the attached patent figures contain R-group variability?",
job_name="job-futurehouse-data-analysis-crow-high",
)
first.session_id # UUID(...) — the handle for every call below
first.status # ChatDispatchStatus.PENDINGStarting a session
A chat session lives inside a project. Create one, or reuse an existing project_id:
Omit session_id on the first message and the platform opens a session for you; the response tells you which one. Pass that session_id back on later messages and the same sandbox is reused, with its TTL reset — the agent keeps its workspace and history.
send_chat_message parameters
project_id
UUID
required
Project to chat within
message
str
required
User message content
session_id
UUID | None
None
Existing session, or None to open a new one
job_name
str | None
None
Which deployed agent to talk to — a built-in JobNames entry or one of your own deployments (see configuration.md)
data_storage_ids
list[str | UUID] | None
None
Data storage entries to attach to this turn
ttl_seconds
int | None
None
Sandbox idle TTL override, 60–86400
timeout
int | None
None
Per-turn execution timeout override, 30–172800
channel
str
"app"
Tags message provenance; use "api" for SDK traffic
ttl_seconds and timeout are validated against those bounds client-side, so an out-of-range value raises before the request is sent.
Waiting for a reply
There is no completion signal over REST and no wait_for_reply in the SDK. Poll get_conversation and either treat "an assistant message with no pending tool calls" as the end of a turn -- or calling the submit_answer tool. An example is shown here:
To wait on a follow-up turn, pass the count of messages you have already seen:
Attaching data
data_storage_ids accepts bare UUIDs or data_entry:<uuid> URIs from the data storage service (the data_entry: prefix is stripped for you). The entries are mounted into the agent's workspace for that turn.
See File management for the upload side.
Steering a turn that is already running
send_chat_message on a busy session waits its turn. queue_chat_message injects into the running rollout instead — the agent picks the message up at its next step. This is the "actually, also check X" affordance while the agent is mid-work.
Reading history
limit=None fetches the whole conversation, following pagination and reassembling messages the API had to split into content blocks.
Or one page at a time, most recent first by sort_order:
limit defaults to 50. offset requires limit — passing offset with limit=None raises ValueError.
Messages convert to aviary types when you want to replay them into an LLM:
List sessions the caller can see (limit default 25, max 200):
Sandbox knobs
Defaults ususally work for interactive use, though raising timeouts may be necessary for long autonomous turns.
These override the agent profile's deploy-time timeouts for this session only,
Chatting with an agent you deployed yourself is the same call — job_name takes any job you can reach:
A deployment with MIN_REPLICAS=0 scales to zero, so the first message to an idle custom agent pays a cold start. Deploy with at least one replica for anything interactive.
Response models
Import from edison_client.models.chat.
ChatMessageResponse
session_id
UUID
New or existing session
status
ChatDispatchStatus
Dispatch lifecycle status
claim_name
str | None
Kubernetes SandboxClaim name; internal users only
pod_name
str | None
Pod serving the sandbox; internal users only
logs_url
str | None
Console logs URL; internal users only
ChatDispatchStatus is a StrEnum: pending, dispatched, processing, completed, failed. It describes dispatch, not the agent's progress — a completed dispatch means the turn was accepted, not answered.
ConversationDetail
messages
list[ConversationMessage]
Ordered oldest → newest
session_id
UUID
Use for follow-up messages
has_more
bool
Older messages exist beyond this page
continuation_cursor
ConversationContinuationCursor | None
message_id + block_index
ConversationMessage
role
str
user, assistant, tool, system
content
str | list[dict]
Text, or content blocks
tool_calls
list[dict] | None
Present on assistant tool-request messages
tool_call_id
str | None
Present on tool-response messages
name
str | None
Tool name on tool-response messages
info
dict | None
Aviary Message.info — carries channel and data_storage_ids
metadata
dict | None
Caller-supplied metadata
message_id
UUID | None
Stable ID
content_block_start / _end / _total
int | None
Set when the API split one message across pages
to_aviary_message() converts to Message / ToolRequestMessage / ToolResponseMessage.
QueueMessageResponse
id
UUID — pending message ID
target_id
UUID — session (chat) or trajectory (run)
Errors
Writes raise ChatError; reads raise ChatFetchError (a subclass). Connection errors are retried three times with exponential backoff before surfacing.
Async: fan out across sessions
Each session gets its own sandbox, so parallel sessions genuinely run in parallel — the useful shape for batch work from a notebook or service.
Stopping and resetting
queue_chat_message steers a turn; these two stop it.
interrupt_chat_session halts the current turn and leaves the session usable — the sandbox, workspace, and history survive, so the next send_chat_message continues normally.
reset_chat_sandbox is the heavier hammer and is keyed on the project, not the session: it discards the chat sandbox entirely. Conversation history is durable, so the session survives and recovers on the next message, but anything the agent left in an ephemeral workspace is gone. Reach for it when a sandbox is wedged rather than when a turn went wrong.
Last updated
