Python client for the Tandem autonomous agent engine HTTP + SSE API
Project description
tandem-client
Python client for the Tandem autonomous agent engine HTTP + SSE API.
Install
pip install tandem-client
Python 3.10+ required.
Quick start
import asyncio
from tandem_client import TandemClient
async def main():
async with TandemClient(
base_url="http://localhost:39731",
token="your-engine-token", # from `tandem-engine token generate`
) as client:
# 1. Create a session
session_id = await client.sessions.create(
title="My agent",
directory="/path/to/my/project",
)
# 2. Start an async run
run = await client.sessions.prompt_async(
session_id, "Summarize the README and list the top 3 TODOs"
)
# 3. Stream the response
async for event in client.stream(session_id, run.run_id):
if event.type == "session.response":
print(event.properties.get("delta", ""), end="", flush=True)
if event.type in ("run.complete", "run.failed"):
break
asyncio.run(main())
Sync usage (scripts)
from tandem_client import SyncTandemClient
client = SyncTandemClient(base_url="http://localhost:39731", token="...")
session_id = client.sessions.create(title="My agent")
run = client.sessions.prompt_async(session_id, "Analyze this folder")
print(f"Run started: {run.run_id}")
# Note: stream() is async-only; use the async client to receive events
client.close()
API
TandemClient(base_url, token, *, timeout=20.0)
Use as an async context manager or call await client.aclose() manually.
| Method | Description |
|---|---|
await client.health() |
Check engine readiness |
client.stream(session_id, run_id?) |
Async generator of EngineEvent |
client.global_stream() |
Stream all engine events |
await client.list_tool_ids() |
List all registered tool IDs |
client.sessions
| Method | Description |
|---|---|
create(title?, directory?, provider?, model?) |
Create session, returns session_id |
list(q?, page?, page_size?, archived?, scope?, workspace?) |
List sessions |
get(session_id) |
Get session details |
delete(session_id) |
Delete a session |
messages(session_id) |
Get message history |
active_run(session_id) |
Get active run state |
prompt_async(session_id, prompt) |
Start async run, returns PromptAsyncResult(run_id) |
client.routines
| Method | Description |
|---|---|
list(family?) |
List routines or automations |
create(options, family?) |
Create a scheduled routine |
delete(routine_id, family?) |
Delete a routine |
run_now(routine_id, family?) |
Trigger a routine immediately |
list_runs(family?, limit?) |
List recent run records |
list_artifacts(run_id, family?) |
List run artifacts |
Create a cron routine:
await client.routines.create({
"name": "Daily digest",
"schedule": "0 8 * * *",
"prompt": "Summarize today's activity and write a report to daily-digest.md",
"allowed_tools": ["read", "write", "websearch"],
})
client.mcp
await client.mcp.add("arcade", "https://mcp.arcade.ai/mcp")
await client.mcp.connect("arcade")
tools = await client.mcp.list_tools()
| Method | Description |
|---|---|
list() |
List registered MCP servers |
list_tools() |
List discovered tools |
add(name, transport, *, headers?, enabled?) |
Register an MCP server |
connect(name) |
Connect and discover tools |
disconnect(name) |
Disconnect |
refresh(name) |
Re-discover tools |
set_enabled(name, enabled) |
Enable/disable |
client.channels
await client.channels.put("telegram", {"token": "bot:xxx", "allowed_users": ["@you"]})
status = await client.channels.status()
print(status.telegram.connected)
client.permissions
snapshot = await client.permissions.list()
for req in snapshot.requests:
await client.permissions.reply(req.id, "allow")
client.providers
catalog = await client.providers.catalog()
await client.providers.set_defaults("openrouter", "anthropic/claude-3.7-sonnet")
await client.providers.set_api_key("openrouter", "sk-or-...")
Common event types
event.type |
Description |
|---|---|
session.response |
Text delta in event.properties["delta"] |
session.tool_call |
Tool invocation |
session.tool_result |
Tool result |
run.complete |
Run finished successfully |
run.failed |
Run failed |
permission.request |
Approval needed |
License
MIT
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 tandem_client-0.3.24.tar.gz.
File metadata
- Download URL: tandem_client-0.3.24.tar.gz
- Upload date:
- Size: 14.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b258dbf02f33f2efe771a921cb74199b0fa6ef7cdbd45198dda01441bf8a6318
|
|
| MD5 |
f801f7b3d62044aedb942e385df68b72
|
|
| BLAKE2b-256 |
c27fd87b318be085b1b11eef7ec34d858a05da5b4dcfb1420479eb4a39ded1ef
|
Provenance
The following attestation bundles were made for tandem_client-0.3.24.tar.gz:
Publisher:
publish-registries.yml on frumu-ai/tandem
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tandem_client-0.3.24.tar.gz -
Subject digest:
b258dbf02f33f2efe771a921cb74199b0fa6ef7cdbd45198dda01441bf8a6318 - Sigstore transparency entry: 1004514347
- Sigstore integration time:
-
Permalink:
frumu-ai/tandem@dac39399363f44db05e1a84a0940b37f88d1ac26 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/frumu-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-registries.yml@dac39399363f44db05e1a84a0940b37f88d1ac26 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file tandem_client-0.3.24-py3-none-any.whl.
File metadata
- Download URL: tandem_client-0.3.24-py3-none-any.whl
- Upload date:
- Size: 15.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5282fe87b1ac86ecfb6842636f55acb3b04124e633a166b54c77bb54525d02d2
|
|
| MD5 |
a0226c037d19a1d75a353705780d4d0e
|
|
| BLAKE2b-256 |
5de54183bcb4b58057820102c9860b47e5e2f02b3de951ad8cc94b5a8506d64a
|
Provenance
The following attestation bundles were made for tandem_client-0.3.24-py3-none-any.whl:
Publisher:
publish-registries.yml on frumu-ai/tandem
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tandem_client-0.3.24-py3-none-any.whl -
Subject digest:
5282fe87b1ac86ecfb6842636f55acb3b04124e633a166b54c77bb54525d02d2 - Sigstore transparency entry: 1004514349
- Sigstore integration time:
-
Permalink:
frumu-ai/tandem@dac39399363f44db05e1a84a0940b37f88d1ac26 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/frumu-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-registries.yml@dac39399363f44db05e1a84a0940b37f88d1ac26 -
Trigger Event:
workflow_dispatch
-
Statement type: