Python SDK for the Agent Orchestration API.
Project description
trelent-agents
Python SDK for the Trelent Agent Orchestration API.
Installation
pip install trelent-agents
Quick Start
Without authentication
from trelent_agents import Client
client = Client(api_url="http://localhost:8000")
sandboxes = client.sandboxes.list()
print(sandboxes)
run = client.runs.create(
sandbox="example-agent:latest",
prompt="Create hello.txt with a greeting",
)
print(run.id, run.status, run.harness.kind)
With authentication
When the API has authentication enabled, provide your OAuth2 client credentials:
from trelent_agents import Client
client = Client(
api_url="https://agents.trelent.com",
client_id="your-client-id",
client_secret="your-client-secret",
)
sandboxes = client.sandboxes.list()
run = client.runs.create(
sandbox="my-sandbox:latest",
prompt="Do something useful",
)
The SDK handles token acquisition automatically — it exchanges your client credentials for a JWT via the API's /token endpoint before making authenticated requests.
If you need to call the token proxy directly, use client.tokens.create(...).
The client also supports context manager usage:
with Client(api_url="https://agents.trelent.com", client_id="...", client_secret="...") as client:
runs = client.runs.list()
Client Options
client = Client(
api_url="https://agents.trelent.com", # API base URL (default: https://agents.trelent.com)
client_id="...", # OAuth2 client ID (optional)
client_secret="...", # OAuth2 client secret (optional)
scope="...", # Override default OAuth2 scope (optional)
)
Both client_id and client_secret must be provided together, or both omitted.
Resources
client.sandboxes
sandboxes = client.sandboxes.list()
# => list[RegistrySandbox] — [RegistrySandbox(name="my-sandbox", tags=["latest", "v1"])]
When auth is enabled, sandboxes are automatically filtered to your namespace. Sandbox names are returned without the namespace prefix.
client.tokens
token = client.tokens.create(
client_id="your-client-id",
client_secret="your-client-secret",
scope="AgentOrchestrator:runs:list",
)
client.runs
from trelent_agents import ClaudeCodeHarnessSpec, LocalImporter, RunSecretBinding, S3Exporter
# Create a run
run = client.runs.create(
sandbox="my-sandbox:latest",
prompt="Build a web server",
harness=ClaudeCodeHarnessSpec(), # optional, default: ClaudeCodeHarnessSpec()
workdir="/workspace", # optional, default: image WORKDIR or /workspace
timeout_seconds=3600, # optional, default: 3600
imports=[LocalImporter(path="./data")], # optional
exports=[S3Exporter()], # optional
secrets=[ # optional
RunSecretBinding(name="openai", env_var="OPENAI_API_KEY"),
],
)
# List runs (optionally filter by sandbox)
runs = client.runs.list()
filtered = client.runs.list(sandbox="my-sandbox:latest")
# Get a specific run
run = client.runs.get("run-id")
# Check status
status = client.runs.get_status("run-id")
# Cancel a run
cancel = client.runs.cancel("run-id")
# Get checkpoints
chain = client.runs.get_checkpoint_chain("run-id")
checkpoint = client.runs.get_checkpoint("run-id", "checkpoint-id")
Run operations
# Fork (resume from checkpoint)
forked = run.fork(
"Continue from where you left off",
workdir="/workspace/project",
timeout_seconds=1800,
)
# Refresh run state
run.refresh()
print(run.status) # updated status
Streaming Events
Subscribe to real-time events from a run using Server-Sent Events (SSE). Events are streamed as the agent executes, providing live visibility into reasoning, messages, and tool usage.
Basic streaming
from trelent_agents import Client, EventType
client = Client(api_url=api_url, client_id=client_id, client_secret=client_secret)
run = client.runs.create(
sandbox="my-sandbox:latest",
prompt="Build a simple web server",
)
# Subscribe to the event stream
for event in run.stream():
match event.type:
case EventType.MESSAGE_DELTA:
print(event.data.delta.text, end="", flush=True)
case EventType.TOOL_CALL_STARTED:
print(f"\nTool: {event.data.name}")
case EventType.SESSION_COMPLETED:
print(f"\nCompleted with exit code: {event.data.exit_code}")
Streaming via client
You can also stream using the run ID directly:
for event in client.runs.stream_events("run-abc123"):
print(event.type, event.seq)
Event types
| Event Type | Description |
|---|---|
SESSION_STARTED |
Agent session initialized |
SESSION_COMPLETED |
Session finished (includes exit_code and usage) |
TURN_STARTED |
New conversation turn began |
TURN_COMPLETED |
Turn finished |
TURN_FAILED |
Turn failed with error |
MESSAGE_STARTED |
Assistant message started |
MESSAGE_DELTA |
Incremental text content |
MESSAGE_COMPLETED |
Full message content available |
REASONING_STARTED |
Extended thinking started |
REASONING_DELTA |
Incremental reasoning text |
REASONING_COMPLETED |
Reasoning block finished |
TOOL_CALL_STARTED |
Tool invocation started (includes name and kind) |
TOOL_CALL_INPUT_DELTA |
Streaming tool input JSON |
TOOL_CALL_INPUT_COMPLETE |
Full tool input available |
TOOL_CALL_OUTPUT_DELTA |
Streaming tool output |
TOOL_CALL_COMPLETED |
Tool execution finished (includes exit_code) |
ERROR |
Error occurred |
Event structure
Every event has a common envelope:
class CommonEvent(BaseModel):
seq: int # Sequence number (monotonically increasing)
timestamp: str # ISO 8601 timestamp
type: EventType # Event type discriminator
data: EventData # Type-specific payload
client.health()
health = client.health()
# => HealthResponse(status="ok")
Connectors
Importing local files
from trelent_agents import LocalImporter
run = client.runs.create(
sandbox="my-sandbox:latest",
prompt="Process the data",
imports=[LocalImporter(path="./my-data-dir")],
)
The LocalImporter tarballs and base64-encodes the local path, sending it inline with the request. The API stages large payloads onto a shared volume server-side, so the run-creation request itself stays the only network hop you need.
Exporting to S3
from trelent_agents import S3Exporter
run = client.runs.create(
sandbox="my-sandbox:latest",
prompt="Generate a report",
exports=[S3Exporter(bucket="my-bucket", path="reports/")],
)
Shared workspaces
Shared workspaces mount a user-scoped shared directory into the sandbox at
/mnt/shared/<name>.
from trelent_agents import SharedWorkspaceExporter, SharedWorkspaceImporter
run = client.runs.create(
sandbox="my-sandbox:latest",
prompt="Read and write files in /mnt/shared/my-drive",
imports=[SharedWorkspaceImporter(name="my-drive")],
exports=[SharedWorkspaceExporter(name="my-drive")],
)
To export a subdirectory from the shared workspace:
exports=[SharedWorkspaceExporter(name="my-drive", directory="reports")]
Secrets
Create a user-scoped secret once. The API stores the value in the deployment's configured secret backend and only stores metadata in the database.
client.secrets.create("openai", "sk-...")
secrets = client.secrets.list()
secret = client.secrets.get("openai")
client.secrets.update("openai", "sk-new")
client.secrets.delete("openai")
Use secrets in runs by logical name. A string shorthand injects the secret as an environment variable with the same name:
run = client.runs.create(
sandbox="my-sandbox:latest",
prompt="Use the injected secret",
secrets=["openai"],
)
For a custom environment variable:
from trelent_agents import RunSecretBinding
secrets=[RunSecretBinding(name="openai", env_var="OPENAI_API_KEY")]
To mount a secret as a file instead of an env var:
secrets=[RunSecretBinding(name="openai", mount=True)]
The runner writes mounted secrets to /mnt/secrets/<secret_name> inside the
sandbox. You can also set both env_var and mount=True to expose both forms.
Docker Registry Setup
When auth is enabled, push sandbox images to your user namespace on the registry:
# Login with your OAuth2 credentials
docker login registry.example.com -u <client_id> -p <client_secret>
# Push to your namespace
docker tag my-sandbox:latest registry.example.com/<client_id>/my-sandbox:latest
docker push registry.example.com/<client_id>/my-sandbox:latest
When creating runs via the SDK, just use the sandbox name without the namespace prefix:
run = client.runs.create(
sandbox="my-sandbox:latest", # not "<client_id>/my-sandbox:latest"
prompt="...",
)
The API resolves the full registry path automatically based on your authenticated identity.
Types
The SDK exports the following types:
from trelent_agents import (
Client,
ClaudeCodeHarnessSpec,
CodexHarnessSpec,
CommonEvent,
EventType,
Run,
RunStatus,
RunResult,
RunStatusResponse,
RegistrySandbox,
CheckpointResponse,
CancelRunResponse,
ChatHistoryEntry,
FileOutput,
OutputFile,
HealthResponse,
HarnessInfo,
HarnessKind,
HarnessSpec,
TokenRequest,
TokenResponse,
ToolKind,
WorkflowIds,
LocalImporter,
SharedWorkspaceExporter,
SharedWorkspaceImporter,
S3Exporter,
RunSecretBinding,
SecretResponse,
APIError,
NotFoundError,
ValidationError,
)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file trelent_agents-0.2.8.tar.gz.
File metadata
- Download URL: trelent_agents-0.2.8.tar.gz
- Upload date:
- Size: 14.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e709418f596d0c31c394f89fdb8ffeda782baa5870014e16fa795abf810d6ab8
|
|
| MD5 |
5e9ba2b97cdc1e59c5e13ced00df6823
|
|
| BLAKE2b-256 |
6491b4473716b07678be105364776e01a0b3e13ebe72897f49158bc7e8e348b4
|
File details
Details for the file trelent_agents-0.2.8-py3-none-any.whl.
File metadata
- Download URL: trelent_agents-0.2.8-py3-none-any.whl
- Upload date:
- Size: 23.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
90fbb8893125d01b0e72fac1f6a36f165f0d12d82096301ef0d0a48f2d6e0602
|
|
| MD5 |
8024bbe7e2138a605ad6b8134487f3e8
|
|
| BLAKE2b-256 |
155a3ea3dc3d5e33f362369e5536ad23b6af5eead9aac1ae1bba22199ca5fa91
|