Skip to main content
ManagedAgentsClient exposes five namespaces. They are named the same in Python and TypeScript, only cased to match each language. The Python client is imported from the package root (from celesto import ManagedAgentsClient) and lives at celesto.sdk.runtime. The TypeScript client is exported from the package root (import { ManagedAgentsClient } from "@celestoai/sdk") and from @celestoai/sdk/agents. Both clients read CELESTO_API_KEY from the environment when you do not pass a key. Use the Python client as a context manager, or call close() when you are done.

agents

Create and version the agents your end users run. An agent is a named pointer at an immutable definition. Every update cuts a new version and moves the pointer; runs pin the version they started with, so a change never rewrites history.

AgentConfig is a closed allowlist

config accepts only these keys. Any other key is refused before the request leaves your machine, so a typo raises ConfigKeyNotAllowedError rather than a 422 from the server: temperature, top_p, max_tokens, max_output_tokens, frequency_penalty, presence_penalty, seed, stop, reasoning_effort, verbosity, max_turns. In TypeScript these keys are camelCase (topP, maxTokens, reasoningEffort, and so on). The type also enforces them at compile time.

runs

Run an agent for one of your end users, and read what happened.

Two methods, not one flag

runs.create returns the settled run, including output and usage. runs.stream yields events. The return type never depends on an argument — there is no stream=True toggle. A failed run arrives as a run.failed event on the stream, not as an exception. Exceptions are reserved for runs that never started (BudgetExceededError, SessionBusyError, AgentArchivedError, and the others below).

Idempotency and retries

idempotency_key / idempotencyKey is a first-class argument on runs.create and runs.stream. Sending the same key again returns the run that already happened instead of running the agent — and charging your end user — twice. Sessions run one at a time. If a second run arrives while the first is still going, Celesto refuses it with SessionBusyError. Pass max_retries / maxRetries to wait and try again; the SDK generates an idempotency key for you when you ask for retries, so a session-busy retry cannot charge twice.

Run events

runs.stream yields RunEvent values. The known event names are:
  • run.started
  • message.delta — partial text, not stored, so it never appears on a replay.
  • message.completed
  • tool.call
  • tool.result
  • usage — token counts and cost for one generation.
  • run.completed
  • run.failed
Event names this SDK does not know are silently ignored, so a server that adds an event tomorrow does not break a client shipped today. In TypeScript, RunEvent is a discriminated union on name, so switching on event.name narrows event.data.

sessions

The conversations your end users have had. A session holds one end user’s transcript with one agent. Runs on the same session share history; runs without a session get a fresh one. Transcripts page backwards: the most recent messages come first, and before_seq / beforeSeq asks for what came before a message you already have.

end_users / endUsers

Your users, addressed by your own identifier. Celesto never stores a Celesto ID for them; the record is created the first time you run an agent for that string. The cap covers a rolling 30-day window that starts the first time that user runs anything. When it runs out, the next run raises BudgetExceededError, and a run already in flight stops at its next step with a run.failed event.

Money is exact

Reads return Decimal in Python (cost_usd, spent_usd, cap_usd) and DecimalString in TypeScript (costUsd, spentUsd, capUsd) — a string such as "0.000450", never a number. A single generation can cost a few millionths of a dollar, which a JavaScript number cannot hold exactly. Writes refuse floats. In Python, budget_cap_usd=0.1 raises TypeError; pass a Decimal or a string. In TypeScript, budgetCapUsd is typed string, so a number fails to compile, and passing one at runtime throws.

settings

Organization-wide defaults for managed agents. Pass None in Python or null in TypeScript to default_end_user_budget_usd / defaultEndUserBudgetUsd to remove the default, which leaves end users uncapped unless they have their own override.

Errors

The API answers a refused request with a machine-readable code, and each code gets its own exception class. Every one is still a CelestoError (Python) or CelestoApiError (TypeScript), so a single top-level catch keeps working. All classes below are exported from the package root — from celesto import ... in Python, import { ... } from "@celestoai/sdk" in TypeScript. Handle typed errors alongside the general Celesto errors:
errors.py
errors.ts
For general SDK errors (authentication, validation, not found, rate limit, server, network), see Error handling.
Last modified on August 14, 2026