Skip to main content
The SDK is an MCP client for the local server the Nexus app exposes. Everything has a sync and an async form: Client / AsyncClient and Run / AsyncRun. The async methods are awaited; both share the same handlers and error types.

Client

Use it as a context manager. Interactivity is set here, by whether you pass handlers — supplying on_question / on_confirm makes runs interactive; omitting both runs the agent unattended. Use one client per thread (one per event loop for AsyncClient).
Callable[[Question], str]
Answer an ask_user. Passing it declares the elicitation capability. Omit to run unattended (the agent is never offered questions). Answer within ~2 minutes (Question.expires_in carries the exact window) — after that the question auto-dismisses, the agent proceeds on its own judgment, and the SDK stops waiting on your handler. Return a non-empty string: an empty answer reads as “no answer” and the agent proceeds immediately — re-prompt your human instead (the app disables its submit button on empty text for the same reason).
Callable[[Confirmation], bool]
Approve or deny a confirm_action. Omit to auto-resolve (approve safe, decline dangerous). Undecided for ~2 minutes counts as a decline.
float
default:"600.0"
Seconds a single run may take. Expiry cancels the run server-side (nothing keeps working behind your back) and raises CosmonTimeoutError. There is no server-side cap — set it as high as your longest solve.
str
Override where the app’s descriptor is read from (defaults to the per-OS path; or the COSMON_SDK_DESCRIPTOR environment variable).
str
Connect explicitly instead of discovering the app (mainly for tests).

Methods

Run
Start a one-shot agent run; returns a Run.
Session
Open a multi-turn Session (see below). agent picks the entry agent for the first turn; ephemeral=True deletes the conversation when the session closes; id resumes an earlier session’s conversation (a previous session’s .id).
DiscoverInfo
Login state, account, available agents, default agent, active model, and runtime readiness.
list[ChatInfo]
The conversations your scripts left on the server (SDK-owned only — never the app user’s own chats), newest first. Each ChatInfo has id (resume with session(id=...)), title (from the first prompt), and updated_at.
None
Disconnect. Done automatically by the context manager.

run() options

str
Target platform agent, e.g. "solidworks", "abaqus", "fluent". Omit for the default.
list[str]
File paths to attach to the prompt (read on the machine running the app). Relative paths are resolved against your current working directory.
bool
default:"False"
Delete the conversation (transcript + agent history) when the run finishes, instead of persisting it server-side.

Run

The handle for one run — single-use: iterate it or drain it once.
str
Drive the run to completion and return its transcript — the agent’s answer with each tool step inline as a ▶ <summary> line. live=True also prints the run while it works (tokens to stdout, steps and [agent] labels to stderr); the returned string stays the authoritative version. On AsyncRun, await run.text(). Raises CosmonRunError if the run failed.
Iterator[RunEvent]
Stream the run: yields ToolCall / TextChunk events as they happen (async for on AsyncRun). Raises CosmonRunError if the run fails mid-stream.

Session

A multi-turn conversation over one stable id — open it with client.session(...). Every run on it reuses the id, so the runtime resumes the same thread (it remembers earlier turns). Use it as a context manager so it’s ended on exit.
Run
Run the next turn. The entry agent is sent only on the first turn; later turns follow the agent in control (so a handoff carries into the next turn). Returns a Run — same handle as client.run.
str
The session id shared across the conversation’s turns.
None
End the session. The conversation persists server-side and can be picked up again with client.session(id=chat.id) — an ephemeral session is deleted here instead. Idempotent; also called on with-block exit. On AsyncSession, await chat.close().
None
Delete the conversation entirely (transcript + agent history), then end the session. The explicit destructive act — close() never deletes. Idempotent. On AsyncSession, await chat.delete().
A one-shot client.run(...) (no session) leaves its history server-side unless run with ephemeral=True; SDK runs don’t appear in the app’s chat list. AsyncClient.session(...) returns an AsyncSessionasync with it and await chat.run(...).text().

Events (RunEvent)

What iterating a run yields. A small discriminated union — isinstance-match it.
pydantic model
The agent invoked a tool. name: str, summary: str (human-readable), finished: bool (emitted False on start, True on finish), agent: str — which agent ran it (a run can span a handoff chain; "" from older apps). images: tuple[str, ...] — image data: URIs the tool produced for the user (e.g. a CAD screenshot), carried on the finished=True event; () when the tool produced none, and from apps that predate the field. See the Images from tools example.
pydantic model
text: str — a piece of the agent’s answer, as it streams; agent: str — who said it. Concatenate the chunks to rebuild the answer text.

Interaction handlers

Passed to the client; called as the agent needs input (the respond side — kept out of the event stream because the agent blocks on the returned value).
pydantic model
prompt: str — the question. options: list[str] — the offered choices, or [] for a free-form answer (custom answers outside the options are fine). expires_in: float — seconds before the prompt auto-dismisses and the agent proceeds without you (~120; render it if a human is answering). on_question returns the chosen/typed string.
pydantic model
summary: str — what the agent wants to do. expires_in: float — seconds before an undecided gate counts as declined (~120). on_confirm returns True to approve, False to deny.
The two handlers are independent: with only on_confirm, the run is question-free (the agent is never offered ask_user) while every confirmation gate reaches your handler; with only on_question, questions reach you while confirmations auto-resolve (approve safe, decline dangerous).

ChatInfo

Returned by chats(): id: str, title: str, updated_at: str (ISO timestamp of the last activity). Resume one with client.session(id=info.id); remove one with that session’s delete().

DiscoverInfo

Returned by discover(): logged_in: bool, account: str | None, agents: list[str], default_agent: str, model: str, runtime_ready: bool, tool_server_ready: bool (reported True by older apps that predate the field).

Async

AsyncClient mirrors Client for pipelines, FastAPI, notebooks, etc. It’s the native form (the sync Client wraps it on a background event loop).

Errors

All inherit from CosmonError — catch that to handle any SDK failure in one place. There are two channels: errors opening the client (connection, auth, protocol) and failures during a run (run failure, timeout, a dropped connection). Each concrete error below.

CosmonError

The base class every other SDK error subclasses. Catch it as a catch-all; catch the specific subclasses below when you want to branch on the cause.

CosmonConnectionError

The app can’t be reached. Raised opening the client when the app isn’t running or Developer access is off — and during a run if the connection drops mid-flight (the app quit, or Developer access was turned off). Fix: make sure Nexus is running, signed in, with Developer access on.

CosmonAuthError

The server rejected the bearer token — raised opening the client. Happens when Developer access is off, or the per-launch token rotated (the app restarted). Fix: toggle Developer access off and back on to reissue the token.

CosmonProtocolError

The app speaks a gateway protocol version the SDK can’t drive — raised opening the client. Fix: update the SDK and the app to compatible versions.

CosmonTimeoutError

A run exceeded the client’s timeoutraised during the run. The run is cancelled server-side (nothing keeps working behind your back). Fix: raise timeout on the client for long solves, or shorten the task.

CosmonRunError

The run itself failed — raised during the run — including provider errors like being out of credits. Its code attribute lets you branch without parsing the message:

Command line

The SDK also installs the cosmon command — doctor, run, and chats. It has its own page: Command line.