query() launches the bundled qodercli locally. Pass options.experimental_cloud_agent and the SDK switches to the Qoder Cloud Agent runtime instead — the agent and session run in a Qoder Cloud container, while the local process only sends requests and consumes the SSE event stream.
Status: experimental / unstable. The API shape may change between minor versions; do not depend on unreleased fields in production code paths.
When to use
- You don’t want to manage qodercli, the bundled binary, or a local runtime
- You need a long-lived agent reused across machines (the agent is persisted in the Cloud)
- You want session context to live in the Cloud so multiple processes / hosts can resume it
mcp_servers / settings / hooks / plugins / local permissions / checkpoint — are not available under the Cloud runtime; passing any of them throws synchronously.
Prerequisites
- Personal Access Token (PAT): generated at qoder.com/account/integrations; see SDK Authentication. The Cloud runtime accepts only
access_token()/access_token_from_env(). Passingqodercli_auth()/job_token()throws synchronously. - Cloud
environment_id: required when creating a session. Get it from the Qoder console or the management API.
First call: create agent + create session
The most common entry path — create a new Cloud Agent and immediately open a session for it to run a prompt:session_id from the final ResultMessage — later turns use it to resume the same session (see Multi-turn: resuming a session).
Built-in tool allowlist
tools[].enabled_tools currently supports: bash, write, glob, web_fetch, read, edit, grep, web_search. Omit tools to give the agent no tools.
Mounting files into a session
After uploading a file via the Files API, mount it into the session container withsession.create.resources:
Reusing an existing agent
If you already have anagent.id (created via the console or a previous call), pass agent: {"id": ...} and skip create:
Multi-turn: resuming a session
Once you have asession_id from the first turn, the next call passes only session: {"id": ...} — do not include agent. The session already binds an agent, and combining the two throws synchronously.
session_id, you can resume.
Using QoderSDKClient for multi-turn conversations
QoderSDKClient provides a higher-level Cloud session management — connect() creates/resolves the Cloud session, subsequent query() calls reuse it per turn, without needing to manually track session_id:
Note: The Cloud runtime does not supportclient.set_model(),client.reload_plugins(), MCP OAuth, or other local-CLI control methods — calling them raisesValueError.
Consuming SSE events
The Cloud runtime streams session events back over SSE. The SDK wraps each event as aCloudAgentEventMessage message:
CloudAgentEventMessage fields):
| Field | Description |
|---|---|
event | Cloud event name (e.g. user.message, agent.message, session.status_idle) |
id | Event ID in the SSE stream; usable as a replay anchor |
data | Cloud event payload (includes turn_id and other fields) |
uuid | SDK-generated unique ID for deduplication |
session_id | Cloud session ID this event belongs to |
History replay isolation
When resuming an existing session, the SSE stream first replays history events. The SDK isolates byturn_id: only the current turn’s session.status_idle triggers the ResultMessage terminal — historical events will not end your query early.
SSE tuning
Compatibility:afterId/deltaFlushIntervalMs(camelCase) are also accepted at runtime.
Abnormal close
If SSE disconnects before the current turn reaches a terminal event, the SDK synthesizes an errorResultMessage (subtype != 'success', is_error=True) so callers can handle it uniformly.
The ResultMessage terminal
| Field | Description |
|---|---|
subtype | "success" or an error subtype |
is_error | Boolean; whether the turn ended abnormally |
session_id | Cloud session ID (backfilled by the SDK on the create branch) |
result | Agent’s text reply for the turn (multiple text blocks are concatenated) |
usage / model_usage / total_cost_usd | Backfilled from the current turn’s span.model_request_end.usage |
Constraints at a glance
agentandsessioneach have their ownid/create— they are mutually exclusive.- When passing an existing
session["id"], do not also passagent. session["create"]must includeenvironment_idexplicitly.- The Cloud runtime rejects local-CLI-only top-level options:
model,agent,mcp_servers,settings,hooks,plugins,permission_mode, etc. Passing any of them throws synchronously. - The Cloud runtime does not support
QoderSDKClient.set_model(),reload_plugins(), MCP OAuth, etc. Onlyasync forconsumption andclose()are guaranteed.
Error codes
| Exception class | When it triggers |
|---|---|
CloudAgentUnsupportedAuthError | Non-PAT auth was used (e.g. qodercli_auth() / job_token()) |
CloudAgentApiError | Cloud OpenAPI returned non-2xx, or the SSE channel failed |
Related docs
- SDK Authentication — PAT acquisition and environment variables
- Multi-turn Conversation — multi-turn under the local runtime
- SDK References — full fields for
QoderAgentOptions.experimental_cloud_agentandCloudAgentEventMessage