Sessions
Start a session and get a handle that polls, messages, and stops it. The handle is sugar over the generated session methods.
A session is one run of an agent. Starting it returns immediately: the agent works in a cloud sandbox while your code decides whether to wait, watch, or walk away.
Start and wait
sessions.run() starts a session and returns a SessionHandle over it. wait() polls until the session settles:
import os
from ellipsis import Ellipsis
client = Ellipsis(api_key=os.environ["ELLIPSIS_API_TOKEN"])
handle = client.sessions.run(
prompt="Fix the flaky test in ci/",
repository="acme/api",
)
session = handle.wait(timeout=900)
print(session.status)run() takes exactly the arguments sessions.start() takes, and handle.session holds the newest snapshot the handle has seen. handle.id is the session id, which is what you store if you want to pick the session back up later.
What "settled" means
wait() returns when the session reaches a terminal status, completed, error, cancelled, or stopped, or when a keyed conversation parks with session_state of idle or closed. Parking matters: a durable conversation finishes each turn with a terminal per-execution status while the conversation itself is still alive, so waiting only on status would return early on the first turn and never on the last.
wait() polls every 3 seconds by default. Pass poll_interval to change that, and timeout in seconds to bound the wait; exceeding it raises TimeoutError, which leaves the session running.
Message a running session
send() posts into the session's inbox. The message is delivered at the next turn boundary, and it wakes a parked session:
handle.send("Also update the changelog")Pass idempotency_key to make a retried send safe:
handle.send("Also update the changelog", idempotency_key="changelog-ask-1")Stop, refresh, and read records
handle.refresh() # re-fetch the session snapshot
page = handle.records(limit=50) # the session's record log
handle.stop() # stop the agent nowstop() ends the run; the session's history stays readable afterward.
Pick up an existing session
sessions.handle() builds a handle over a session you already have the id of, which is how a second process resumes watching:
handle = client.sessions.handle("session_7Hq2mX4p")
print(handle.session.status)Without the handle
run() and handle() are the only two methods on this namespace that are not generated from the spec. Everything else is a direct call, and the handle is optional:
response = client.sessions.start(prompt="Fix the flaky test in ci/")
session_id = response.session.idThe full list of session operations, with each one's parameters and response, is in the API reference.
Async
The async client mirrors this surface with await, and its handle adds stream() for live frames:
import os
from ellipsis import AsyncEllipsis
async with AsyncEllipsis(api_key=os.environ["ELLIPSIS_API_TOKEN"]) as client:
handle = await client.sessions.run(prompt="Fix the flaky test in ci/")
await handle.stream(on_frame=print)See Streaming.