Async Python SDK for AgentOS APIs.
Project description
AgentOS SDK for Python
Async Python SDK for AgentOS APIs. The package is a thin client over AgentOS HTTP and SSE endpoints with small compatibility helpers for bearer tokens, stream callbacks, Pythonic method names, and request defaults.
Install
pip install agentos-sdk-python
For local development:
python3 -m venv .venv
.venv/bin/python -m pip install -e ".[dev]"
Quickstart
from agentos_sdk import AgentOSSDK
async def main():
async with AgentOSSDK(base_url="http://localhost:8888") as sdk:
version = await sdk.agentos.get_version()
print(version)
registration = await sdk.agentos.register_bundle(
{
"bundleId": "com.demo.app",
"appGroupId": "com.demo.group",
"opentoolServers": [
{"ref": "websearch", "name": "opentool-server-websearch"}
],
}
)
print(registration.get("opentoolServers", []))
tasks = await sdk.cronkit.list_tasks(limit=10)
print(tasks)
AgentOSSDK also exposes TS-style camelCase aliases for common migration paths, such as registerBundle, listTasks, chatSimple, listModels, and loadTool.
Transport
The SDK uses httpx.AsyncClient and defaults to http://localhost:8888.
from agentos_sdk import AgentOSSDK
sdk = AgentOSSDK(
base_url="http://localhost:8888",
connect_timeout=5.0,
receive_timeout=10.0,
)
Use async with AgentOSSDK(...) or call await sdk.aclose() when done.
Token Handling
sdk.agentos.register_bundle(...) stores the active app token. Protected facade methods in sdk.agentkit and sdk.cronkit use that token automatically.
If a protected call fails with HTTP 401, HTTP 403, or recognizable invalid-token text, the SDK re-runs registration for the same bundle once and retries the call. The cached bundle is a defensive copy and retains its opentoolServers declarations during refresh.
AgentOS Events
from agentos_sdk import AgentOSEventHandler, AgentOSSDK
class Handler(AgentOSEventHandler):
async def on_welcome(self, welcome):
print("welcome", welcome)
async def on_app_event(self, event):
if event["type"] == "toolkit.provision.succeeded":
print("tool ready", event["data"]["ref"], event["data"]["id"])
elif event["type"] == "toolkit.provision.failed":
print("tool failed", event["data"]["error"])
async def on_done(self):
print("subscription ended")
async def on_error(self, error):
raise error
async with AgentOSSDK() as sdk:
await sdk.agentos.register_bundle(
{
"bundleId": "com.demo.app",
"opentoolServers": [
{"ref": "websearch", "name": "opentool-server-websearch"}
],
}
)
await sdk.agentos.subscribe(Handler())
Registration statuses are running, starting, and notFound; only running includes a callable tool id. A starting declaration becomes callable after toolkit.provision.succeeded. Stop using a tool while it is toolkit.tool.unavailable and resume after toolkit.tool.available.
on_call_app / onCallApp were removed in 0.2.0. Use on_app_event / onAppEvent.
AgentKit
from agentos_sdk import AgentMessageHandler, AgentOSSDK, ToolReturn
class ChatHandler(AgentMessageHandler):
async def on_message(self, session_id, message):
print("message", session_id, message)
async def on_chunk(self, session_id, chunk):
print("chunk", session_id, chunk)
async def on_function_call(self, session_id, function_call):
return ToolReturn(function_call["id"], {"ok": True})
async def on_done(self):
print("done")
async def on_error(self, error):
raise error
async with AgentOSSDK() as sdk:
await sdk.agentos.register_bundle({"bundleId": "com.demo.app"})
session = await sdk.agentkit.init_session()
await sdk.agentkit.chat(
session,
{"content": [{"type": "text", "message": "Hello"}]},
ChatHandler(),
)
Summary-first history is available without loading every process message:
summaries = await sdk.agentkit.history_summary(session_id=session["sessionId"])
messages = await sdk.agentkit.history_process(
session_id=session["sessionId"],
original_task_id=summaries[0]["originalTaskId"],
)
history_summary defaults to page 1 with 30 items; history_process defaults to page 1 with 50 items. Page sizes must be between 1 and 200. CamelCase callers can use historySummary(sessionId=...) and historyProcess(sessionId=..., originalTaskId=...).
Message, chunk, and function-call handlers receive a child sessionId when the event supplies one, otherwise the root session ID. Function-call failures passed to on_error use FunctionCallLifecycleError with stage equal to function_call_parse_failed, function_call_handler_failed, or function_call_callback_failed.
Direct AgentKit methods include get_agent, create_agent, update_agent, delete_agent, init_session, init_simple, chat, chat_simple, history, history_summary, history_process, stop, clear, callback, and stream_callback.
CronKit
async with AgentOSSDK() as sdk:
await sdk.agentos.register_bundle({"bundleId": "com.demo.app"})
task = await sdk.cronkit.create_task(
request={
"name": "Daily summary",
"schedule": "0 9 * * *",
"spec": {
"systemPrompt": "You are a scheduled agent.",
"content": [{"type": "text", "message": "Summarize today."}],
},
}
)
await sdk.cronkit.run_task_now(cron_id=task["cronId"])
CronKit create requests default concurrency to skipIfRunning, enabled to True, and spec.timeoutSeconds to 3600.
ModelKit
async with AgentOSSDK() as sdk:
models = await sdk.modelkit.list_models()
chat_models = await sdk.modelkit.list_models_by_task("chat")
print(models[0]["capabilities"]["reasoning"])
completion = await sdk.modelkit.chat.create(
{
"model": "qwen3-1.7b",
"messages": [{"role": "user", "content": "Hello"}],
"maxTokens": 128,
}
)
async for chunk in sdk.modelkit.chat.create_stream(
{"model": "qwen3-1.7b", "messages": [{"role": "user", "content": "Stream"}]}
):
print(chunk)
Normalized model capabilities include vision, tool_call, stream, and
reasoning booleans. reasoning reflects only the server-provided
capabilities.reasoning value and defaults to False when omitted.
ModelKit also supports:
sdk.modelkit.embedding.create(...)sdk.modelkit.asr.transcribe(...)sdk.modelkit.tts.synthesize(...)sdk.modelkit.tts.list_voices()
ToolKit
async with AgentOSSDK() as sdk:
registration = await sdk.agentos.register_bundle(
{
"bundleId": "com.example.app",
"opentoolServers": [
{
"ref": "websearch",
"name": "opentool-server-websearch",
}
],
}
)
tools = await sdk.toolkit.list_tool()
websearch_tool = next(
(
tool
for tool in tools
if tool.get("status") == "running"
and (tool.get("server") or {}).get("name")
== "opentool-server-websearch"
),
None,
)
if websearch_tool is None:
raise RuntimeError("The registered websearch tool is not running")
tool_id = websearch_tool["id"]
definition = await sdk.toolkit.load_tool(tool_id)
raw_json = definition.to_json() if definition else None
result = await sdk.toolkit.call(
tool_id,
{
"id": "call-1",
"name": "websearch",
"arguments": {
"query": "AgentOS",
"max_results": 5,
},
},
)
print(result)
async for event in sdk.toolkit.subscribe_tool_events("daemon-api-key"):
print(event)
registration["opentoolServers"] also contains the resolved id when its
status is running; the example uses list_tool() so it can select the running
tool by server.name.
stream_call() is only appropriate for functions whose tool server explicitly
supports streamCall. For such a function, retain the stream and close it when
consumer work ends early:
async def consume_streaming_function(sdk, streaming_tool_id):
stream = sdk.toolkit.stream_call(
streaming_tool_id,
{"id": "call-2", "name": "streaming-function", "arguments": {}},
)
try:
async for event in stream:
print(event["event"], event["data"])
finally:
await stream.aclose()
The high-level ToolKit list, load, call, and stream-call methods use the bearer
token returned by register_bundle() and refresh it once after a 401/403
response. load_tool() returns an OpenToolDefinition wrapper that preserves
the raw JSON definition.
Direct Clients
The low-level clients are available for explicit-token or custom transport usage:
from agentos_sdk.clients import AgentKitClient, CronKitClient, ModelKitClient
from agentos_sdk.transport import ApiClient
api = ApiClient(base_url="http://localhost:8888")
agentkit = AgentKitClient(api)
agent = await agentkit.get_agent("bearer-token", "agent-id")
Development
.venv/bin/python -m compileall agentos_sdk
.venv/bin/python -m pytest -q
.venv/bin/ruff check .
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 agentos_sdk_python-0.2.0.tar.gz.
File metadata
- Download URL: agentos_sdk_python-0.2.0.tar.gz
- Upload date:
- Size: 32.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
79ca09b2fca4b47321c3b467a28804668de816f1bcdac9b11cfba510269e8aec
|
|
| MD5 |
80f915745c2ac18dbce7ab57bbd6903f
|
|
| BLAKE2b-256 |
7b210a2a40d68c15fe36fb31d271d081c6520754812c625df648f02572ee5db6
|
File details
Details for the file agentos_sdk_python-0.2.0-py3-none-any.whl.
File metadata
- Download URL: agentos_sdk_python-0.2.0-py3-none-any.whl
- Upload date:
- Size: 23.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3e4198a41e1508cabf6429421de0adc5f3740985680ee4e73013c83cba85daf0
|
|
| MD5 |
46c388cf836ef343e9c08bcfda571cc7
|
|
| BLAKE2b-256 |
20e239f51379c8da67de26c8a3e63d7a52a519929928d56fac2b62d0b9e4a3f8
|