hypercli-sdk 0.9.2__tar.gz → 0.9.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hypercli_sdk-0.9.5/.gitignore +33 -0
- hypercli_sdk-0.9.5/PKG-INFO +453 -0
- hypercli_sdk-0.9.5/README.md +415 -0
- hypercli_sdk-0.9.5/hypercli/__init__.py +360 -0
- hypercli_sdk-0.9.5/hypercli/acp.py +381 -0
- hypercli_sdk-0.9.5/hypercli/agent.py +1511 -0
- hypercli_sdk-0.9.5/hypercli/agents.py +4075 -0
- {hypercli_sdk-0.9.2 → hypercli_sdk-0.9.5}/hypercli/billing.py +13 -0
- hypercli_sdk-0.9.5/hypercli/chat_integrations.py +112 -0
- hypercli_sdk-0.9.5/hypercli/client.py +133 -0
- hypercli_sdk-0.9.5/hypercli/config.py +250 -0
- {hypercli_sdk-0.9.2 → hypercli_sdk-0.9.5}/hypercli/files.py +1 -156
- {hypercli_sdk-0.9.2 → hypercli_sdk-0.9.5}/hypercli/http.py +79 -17
- {hypercli_sdk-0.9.2 → hypercli_sdk-0.9.5}/hypercli/instances.py +2 -0
- {hypercli_sdk-0.9.2 → hypercli_sdk-0.9.5}/hypercli/job/base.py +8 -1
- hypercli_sdk-0.9.5/hypercli/jobs.py +555 -0
- hypercli_sdk-0.9.5/hypercli/keys.py +120 -0
- hypercli_sdk-0.9.5/hypercli/mcp.py +13 -0
- hypercli_sdk-0.9.5/hypercli/models.py +33 -0
- {hypercli_sdk-0.9.2 → hypercli_sdk-0.9.5}/hypercli/renders.py +143 -48
- hypercli_sdk-0.9.5/hypercli/routines.py +157 -0
- hypercli_sdk-0.9.5/hypercli/runners.py +126 -0
- hypercli_sdk-0.9.5/hypercli/sessions.py +55 -0
- hypercli_sdk-0.9.5/hypercli/shell.py +124 -0
- hypercli_sdk-0.9.5/hypercli/user.py +174 -0
- hypercli_sdk-0.9.5/hypercli/voice.py +109 -0
- hypercli_sdk-0.9.5/hypercli/voice_stream.py +251 -0
- hypercli_sdk-0.9.5/hypercli/voice_transcription.py +225 -0
- hypercli_sdk-0.9.5/hypercli/workspaces.py +1002 -0
- {hypercli_sdk-0.9.2 → hypercli_sdk-0.9.5}/hypercli/x402.py +16 -27
- {hypercli_sdk-0.9.2 → hypercli_sdk-0.9.5}/pyproject.toml +24 -6
- hypercli_sdk-0.9.5/tests/integration/conftest.py +49 -0
- hypercli_sdk-0.9.5/tests/integration/test_agents.py +120 -0
- hypercli_sdk-0.9.5/tests/integration/test_auth.py +13 -0
- hypercli_sdk-0.9.5/tests/integration/test_billing.py +10 -0
- hypercli_sdk-0.9.5/tests/integration/test_instances.py +21 -0
- hypercli_sdk-0.9.5/tests/integration/test_jobs_dryrun.py +57 -0
- hypercli_sdk-0.9.5/tests/integration/test_keys.py +83 -0
- hypercli_sdk-0.9.5/tests/integration/test_renders.py +11 -0
- hypercli_sdk-0.9.5/tests/test_acp.py +770 -0
- hypercli_sdk-0.9.5/tests/test_agent_files_source.py +60 -0
- hypercli_sdk-0.9.5/tests/test_agent_lifecycle.py +204 -0
- hypercli_sdk-0.9.5/tests/test_agents.py +2998 -0
- hypercli_sdk-0.9.5/tests/test_bootstrap_agents_e2e_user.py +243 -0
- hypercli_sdk-0.9.5/tests/test_bootstrap_console_test_key.py +99 -0
- hypercli_sdk-0.9.5/tests/test_bootstrap_dev_test_keys.py +256 -0
- hypercli_sdk-0.9.5/tests/test_chat_integrations.py +42 -0
- hypercli_sdk-0.9.5/tests/test_claw.py +1212 -0
- hypercli_sdk-0.9.5/tests/test_coding_agents.py +820 -0
- hypercli_sdk-0.9.5/tests/test_config.py +471 -0
- hypercli_sdk-0.9.5/tests/test_exec_shell_dryrun.py +503 -0
- hypercli_sdk-0.9.5/tests/test_file_transport.py +307 -0
- hypercli_sdk-0.9.5/tests/test_http.py +56 -0
- hypercli_sdk-0.9.5/tests/test_jobs.py +219 -0
- hypercli_sdk-0.9.5/tests/test_keys.py +238 -0
- hypercli_sdk-0.9.5/tests/test_models.py +27 -0
- hypercli_sdk-0.9.5/tests/test_parity_audit.py +469 -0
- hypercli_sdk-0.9.5/tests/test_public_surface.py +215 -0
- hypercli_sdk-0.9.5/tests/test_renders_subscription.py +204 -0
- hypercli_sdk-0.9.5/tests/test_repository_integrity.py +37 -0
- hypercli_sdk-0.9.5/tests/test_routines.py +319 -0
- hypercli_sdk-0.9.5/tests/test_runner_control_url.py +28 -0
- hypercli_sdk-0.9.5/tests/test_runner_placement.py +19 -0
- hypercli_sdk-0.9.5/tests/test_runners.py +171 -0
- hypercli_sdk-0.9.5/tests/test_sessions.py +132 -0
- hypercli_sdk-0.9.5/tests/test_status.py +27 -0
- hypercli_sdk-0.9.5/tests/test_voice.py +102 -0
- hypercli_sdk-0.9.5/tests/test_voice_stream.py +445 -0
- hypercli_sdk-0.9.5/tests/test_voice_transcription.py +128 -0
- hypercli_sdk-0.9.5/tests/test_workspaces.py +1009 -0
- hypercli_sdk-0.9.2/.gitignore +0 -51
- hypercli_sdk-0.9.2/PKG-INFO +0 -144
- hypercli_sdk-0.9.2/README.md +0 -114
- hypercli_sdk-0.9.2/hypercli/__init__.py +0 -77
- hypercli_sdk-0.9.2/hypercli/agents.py +0 -459
- hypercli_sdk-0.9.2/hypercli/claw.py +0 -303
- hypercli_sdk-0.9.2/hypercli/client.py +0 -66
- hypercli_sdk-0.9.2/hypercli/config.py +0 -70
- hypercli_sdk-0.9.2/hypercli/jobs.py +0 -293
- hypercli_sdk-0.9.2/hypercli/keys.py +0 -62
- hypercli_sdk-0.9.2/hypercli/user.py +0 -37
- hypercli_sdk-0.9.2/tests/test_claw.py +0 -153
- {hypercli_sdk-0.9.2 → hypercli_sdk-0.9.5}/hypercli/job/__init__.py +0 -0
- {hypercli_sdk-0.9.2 → hypercli_sdk-0.9.5}/hypercli/job/comfyui.py +0 -0
- {hypercli_sdk-0.9.2 → hypercli_sdk-0.9.5}/hypercli/job/gradio.py +0 -0
- {hypercli_sdk-0.9.2 → hypercli_sdk-0.9.5}/hypercli/logs.py +0 -0
- {hypercli_sdk-0.9.2 → hypercli_sdk-0.9.5}/tests/test_apply_params.py +0 -0
- {hypercli_sdk-0.9.2 → hypercli_sdk-0.9.5}/tests/test_graph_to_api.py +0 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Build output
|
|
2
|
+
dist/
|
|
3
|
+
build/
|
|
4
|
+
target/
|
|
5
|
+
out/
|
|
6
|
+
|
|
7
|
+
# Caches
|
|
8
|
+
__pycache__/
|
|
9
|
+
.pytest_cache/
|
|
10
|
+
.mypy_cache/
|
|
11
|
+
.ruff_cache/
|
|
12
|
+
.turbo/
|
|
13
|
+
*.tsbuildinfo
|
|
14
|
+
*.pyc
|
|
15
|
+
|
|
16
|
+
# Dependencies
|
|
17
|
+
node_modules/
|
|
18
|
+
.venv/
|
|
19
|
+
venv/
|
|
20
|
+
|
|
21
|
+
# Test/coverage artifacts
|
|
22
|
+
coverage/
|
|
23
|
+
htmlcov/
|
|
24
|
+
.coverage*
|
|
25
|
+
coverage.xml
|
|
26
|
+
|
|
27
|
+
# Secrets & env
|
|
28
|
+
.env
|
|
29
|
+
.env.*
|
|
30
|
+
!.env.example
|
|
31
|
+
|
|
32
|
+
# OS junk
|
|
33
|
+
.DS_Store
|
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: hypercli-sdk
|
|
3
|
+
Version: 0.9.5
|
|
4
|
+
Summary: Python SDK for HyperCLI - GPU orchestration and HyperAgent API
|
|
5
|
+
Project-URL: Homepage, https://hypercli.com
|
|
6
|
+
Project-URL: Documentation, https://docs.hypercli.com
|
|
7
|
+
Project-URL: Repository, https://github.com/HyperCLI/hypercli
|
|
8
|
+
Author-email: HyperCLI <support@hypercli.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Requires-Dist: agent-client-protocol[http]==1.0.0rc2
|
|
18
|
+
Requires-Dist: httpx>=0.28.1
|
|
19
|
+
Requires-Dist: websockets>=15.0.1
|
|
20
|
+
Provides-Extra: all
|
|
21
|
+
Requires-Dist: comfyui-workflow-templates-media-image>=0.3.0; extra == 'all'
|
|
22
|
+
Requires-Dist: comfyui-workflow-templates>=0.7.0; extra == 'all'
|
|
23
|
+
Requires-Dist: eth-account>=0.13.0; extra == 'all'
|
|
24
|
+
Requires-Dist: httpx>=0.28.1; extra == 'all'
|
|
25
|
+
Requires-Dist: x402[evm]==2.21.0; extra == 'all'
|
|
26
|
+
Provides-Extra: comfyui
|
|
27
|
+
Requires-Dist: comfyui-workflow-templates-media-image>=0.3.0; extra == 'comfyui'
|
|
28
|
+
Requires-Dist: comfyui-workflow-templates>=0.7.0; extra == 'comfyui'
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
32
|
+
Requires-Dist: ruff>=0.3.0; extra == 'dev'
|
|
33
|
+
Provides-Extra: wallet
|
|
34
|
+
Requires-Dist: eth-account>=0.13.0; extra == 'wallet'
|
|
35
|
+
Requires-Dist: httpx>=0.28.1; extra == 'wallet'
|
|
36
|
+
Requires-Dist: x402[evm]==2.21.0; extra == 'wallet'
|
|
37
|
+
Description-Content-Type: text/markdown
|
|
38
|
+
|
|
39
|
+
# HyperCLI SDK
|
|
40
|
+
|
|
41
|
+
Python SDK for [HyperCLI](https://hypercli.com) - GPU orchestration API.
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pip install hypercli-sdk
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Setup
|
|
50
|
+
|
|
51
|
+
Set your API key:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
export HYPER_API_KEY=your_api_key
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Or create `~/.hypercli/config`:
|
|
58
|
+
```
|
|
59
|
+
HYPER_API_KEY=your_api_key
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Or pass directly:
|
|
63
|
+
```python
|
|
64
|
+
client = HyperCLI(api_key="your_api_key")
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Usage
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from hypercli import HyperCLI
|
|
71
|
+
|
|
72
|
+
client = HyperCLI()
|
|
73
|
+
|
|
74
|
+
# Check balance
|
|
75
|
+
balance = client.billing.balance()
|
|
76
|
+
print(f"Balance: ${balance.total:.2f}")
|
|
77
|
+
print(f"Rewards: ${balance.rewards:.2f}")
|
|
78
|
+
|
|
79
|
+
# List transactions
|
|
80
|
+
for tx in client.billing.transactions(limit=10):
|
|
81
|
+
print(f"{tx.transaction_type}: ${tx.amount_usd:.4f}")
|
|
82
|
+
|
|
83
|
+
# Create a job
|
|
84
|
+
job = client.jobs.create(
|
|
85
|
+
image="nvidia/cuda:12.0",
|
|
86
|
+
command="python train.py",
|
|
87
|
+
gpu_type="l40s",
|
|
88
|
+
gpu_count=1,
|
|
89
|
+
)
|
|
90
|
+
print(f"Job ID: {job.job_id}")
|
|
91
|
+
print(f"State: {job.state}")
|
|
92
|
+
|
|
93
|
+
# List jobs
|
|
94
|
+
for job in client.jobs.list():
|
|
95
|
+
print(f"{job.job_id}: {job.state}")
|
|
96
|
+
|
|
97
|
+
# Get job details
|
|
98
|
+
job = client.jobs.get("job_id")
|
|
99
|
+
|
|
100
|
+
# Get job logs
|
|
101
|
+
logs = client.jobs.logs("job_id")
|
|
102
|
+
|
|
103
|
+
# Get GPU metrics
|
|
104
|
+
metrics = client.jobs.metrics("job_id")
|
|
105
|
+
for gpu in metrics.gpus:
|
|
106
|
+
print(f"GPU {gpu.index}: {gpu.utilization}% util, {gpu.temperature}°C")
|
|
107
|
+
|
|
108
|
+
# Cancel a job
|
|
109
|
+
client.jobs.cancel("job_id")
|
|
110
|
+
|
|
111
|
+
# Extend runtime
|
|
112
|
+
client.jobs.extend("job_id", runtime=7200)
|
|
113
|
+
|
|
114
|
+
# Get user info
|
|
115
|
+
user = client.user.get()
|
|
116
|
+
print(f"User: {user.email}")
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Hosted Agents & Inference
|
|
120
|
+
|
|
121
|
+
Use `client.agent` for discovery and plan metadata, and point the OpenAI SDK at
|
|
122
|
+
the hosted inference base URL for chat completions:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from hypercli import HyperCLI
|
|
126
|
+
from openai import OpenAI
|
|
127
|
+
|
|
128
|
+
sdk = HyperCLI(api_key="hyper_api_key", agent_api_key="hyper_api_agent_key")
|
|
129
|
+
plans = sdk.agent.plans()
|
|
130
|
+
trial = sdk.agent.create_stripe_trial_checkout()
|
|
131
|
+
activation = sdk.deployments.redeem_grant_code("PROMO123")
|
|
132
|
+
renewal = sdk.deployments.redeem_grant_code("PROMO123", extend_existing=True)
|
|
133
|
+
|
|
134
|
+
client = OpenAI(
|
|
135
|
+
api_key="your_hyperagent_api_key",
|
|
136
|
+
base_url="https://api.agents.hypercli.com/v1"
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
response = client.chat.completions.create(
|
|
140
|
+
model="kimi-k3",
|
|
141
|
+
messages=[{"role": "user", "content": "Hello!"}]
|
|
142
|
+
)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
`create_stripe_trial_checkout()` creates the account's one-time Team trial checkout session. `claim_trial_entitlement()` (the former bodyless `POST /agents/plans/trial` claim) is deprecated: the route no longer exists in the backends. `deployments.redeem_grant_code()` applies a promo/activation code to the current agents account and returns the created entitlement. Codes create new entitlements by default; pass `extend_existing=True` only for renewal/extension behavior.
|
|
146
|
+
|
|
147
|
+
Plan IDs are open strings on the wire so future and historical plans continue
|
|
148
|
+
to parse. `plan.canonical_id` recognizes the current `solo`, `team`, and `pro`
|
|
149
|
+
IDs. Plan access comes from the agents summary, including direct grants:
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
summary = sdk.agent.subscription_summary()
|
|
153
|
+
if summary.has_active_plan: # active subscription OR direct entitlement
|
|
154
|
+
print(summary.agent_slots)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Do not substitute the Orchestra `/api/auth/me` subscription flag. If the
|
|
158
|
+
summary request returns `401` or `403`, the selected key cannot establish plan
|
|
159
|
+
state; treat it as unknown rather than as no plan.
|
|
160
|
+
|
|
161
|
+
## OpenClaw Agents
|
|
162
|
+
|
|
163
|
+
OpenClaw uses the generic deployment launch surface. `registry_url`,
|
|
164
|
+
`registry_auth`, and `sync_root` are generic deployment options. A nonblank
|
|
165
|
+
`sync_root` enables Reef persistence; no separate `sync_enabled` field is
|
|
166
|
+
serialized. On generic create, no include/exclude policy means the complete
|
|
167
|
+
root; `sync_exclude=[]` also excludes nothing. `sync_include=[]` and
|
|
168
|
+
root-wide excludes such as `sync_exclude=["*"]` are invalid.
|
|
169
|
+
Steady Reef synchronization
|
|
170
|
+
is PVC-to-object-storage upload/overwrite, not a two-way mirror: ordinary
|
|
171
|
+
filesystem deletes are not propagated, and remote-to-PVC copying occurs only
|
|
172
|
+
during explicit cold restore. Each SDK file operation obtains a fresh
|
|
173
|
+
files-scoped credential from Backend, then lists, reads, writes, or deletes
|
|
174
|
+
directly against the retained Reef server; Backend never carries file bytes.
|
|
175
|
+
Per-file writes are limited to 100 MiB (`AGENT_FILE_WRITE_MAX_BYTES`, the
|
|
176
|
+
Cloudflare edge request-body cap on the agent hostname); split larger data
|
|
177
|
+
across files or sync it via the agent's own tooling.
|
|
178
|
+
File paths are relative to `sync_root`, and
|
|
179
|
+
`files_list("")` lists the complete root, including dot-directories.
|
|
180
|
+
`build_openclaw_desktop_route()` builds the protected `desktop` route for pro
|
|
181
|
+
launches; there is no public `openclaw` gateway route (the pod gateway binds
|
|
182
|
+
loopback with auth mode `none` as an ACP hop only). The canonical images are
|
|
183
|
+
`ghcr.io/hypercli/hypercli-openclaw:prod` for regular OpenClaw and
|
|
184
|
+
the same image for desktop-enabled OpenClaw — pass
|
|
185
|
+
the image, `sync_root`, and exclusion choices explicitly in the launch config.
|
|
186
|
+
`create_agent` instead injects the runtime-specific include defaults documented in
|
|
187
|
+
[`coding-runtimes.mdx`](../docs/agents/coding-runtimes.mdx); pass an explicit
|
|
188
|
+
nullable policy at create time to select the whole root.
|
|
189
|
+
Workspaces boot sync defaults on through `build_openclaw_workspaces_sync_env()`
|
|
190
|
+
— applied automatically by `create_agent` — with
|
|
191
|
+
`HYPER_WORKSPACES_DIR` defaulting to `/home/node/shared` unless the launch
|
|
192
|
+
`env` supplies one.
|
|
193
|
+
`build_openclaw_trusted_proxies_env([...])` builds the comma-separated
|
|
194
|
+
`OPENCLAW_TRUSTED_PROXIES` env, a full replacement for OpenClaw
|
|
195
|
+
`gateway.trustedProxies`.
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
launch_config = build_agent_config(
|
|
199
|
+
image="ghcr.io/example/agent:latest",
|
|
200
|
+
registry_url="registry.example.com",
|
|
201
|
+
registry_auth={"username": "ci", "password": "token"},
|
|
202
|
+
)
|
|
203
|
+
agent = client.deployments.create(
|
|
204
|
+
name="docs-demo",
|
|
205
|
+
image=launch_config["image"],
|
|
206
|
+
registry_url=launch_config["registry_url"],
|
|
207
|
+
registry_auth=launch_config["registry_auth"],
|
|
208
|
+
)
|
|
209
|
+
agent = client.deployments.wait_for_state(agent.id, {"stopped"}, timeout=330)
|
|
210
|
+
client.deployments.update(agent.id, launch_config=launch_config)
|
|
211
|
+
agent = client.deployments.start(agent.id)
|
|
212
|
+
agent = client.deployments.wait_running(agent.id, timeout=300)
|
|
213
|
+
|
|
214
|
+
capacity = client.deployments.list_with_capacity()
|
|
215
|
+
print(capacity.max_agents_per_account, capacity.running_agents)
|
|
216
|
+
for slot in capacity.agent_slots:
|
|
217
|
+
print(slot.size, slot.plan_id, slot.agent_id)
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
`start()` starts the Backend-stored launch config and does not accept launch
|
|
221
|
+
mutation options. Change launch settings through
|
|
222
|
+
`update(..., launch_config=...)` before starting.
|
|
223
|
+
|
|
224
|
+
`archive()` returns the accepted `ARCHIVING` Agent projection. `delete()` uses
|
|
225
|
+
HTTP 200 to accept a durable soft delete; cluster-local cleanup continues in
|
|
226
|
+
the background, so that response is not cleanup completion.
|
|
227
|
+
|
|
228
|
+
`list()` remains the compatibility list of agents. `list_with_capacity()`
|
|
229
|
+
preserves the full deployment envelope: saved/running account limits, pooled
|
|
230
|
+
TPD, aggregate slot inventory, and individual entitlement-backed agent slots.
|
|
231
|
+
|
|
232
|
+
For a long-lived UI, subscribe to thin invalidations and refresh REST in the
|
|
233
|
+
handler:
|
|
234
|
+
|
|
235
|
+
```python
|
|
236
|
+
import asyncio
|
|
237
|
+
|
|
238
|
+
async def changed(_event):
|
|
239
|
+
agents = await asyncio.to_thread(client.deployments.list)
|
|
240
|
+
render(agents)
|
|
241
|
+
|
|
242
|
+
async def snapshot():
|
|
243
|
+
agents = await asyncio.to_thread(client.deployments.list)
|
|
244
|
+
render(agents)
|
|
245
|
+
|
|
246
|
+
stop = asyncio.Event()
|
|
247
|
+
await client.deployments.subscribe(changed, stop_event=stop, on_ready=snapshot)
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
The `on_ready` callback runs after user-stream authentication and before event
|
|
251
|
+
frames are read; it repeats after reconnect so no transition can slip
|
|
252
|
+
between snapshot and subscription. Transition events carry `agent_id` for
|
|
253
|
+
local filtering plus `state`, `reason`, `error`, and `message`, but are not
|
|
254
|
+
resource snapshots and may be duplicated or coalesced; refresh REST for
|
|
255
|
+
authority.
|
|
256
|
+
|
|
257
|
+
Managed-agent lifecycle snapshots currently use `CREATING`, `STARTING`,
|
|
258
|
+
`RESTORING`, `RUNNING`, `STOPPING`, `STOPPED`, `ARCHIVING`, `ARCHIVED`,
|
|
259
|
+
`FAILED`, and `DELETED`. `CREATING` is fresh admission, `STARTING` resumes a
|
|
260
|
+
warm retained agent, and `RESTORING` hydrates a cold agent from its exact
|
|
261
|
+
archive checkpoint. `STOPPED` retains warm local storage. `ARCHIVING` is the
|
|
262
|
+
public transition to verified cold storage.
|
|
263
|
+
`ARCHIVED` is the Backend-persisted cold-restorable terminal projection after
|
|
264
|
+
Lagoon drops its agent task, namespace, PVC, and local S3 copy. `DELETED` is a
|
|
265
|
+
Backend-only terminal state and normally hidden from user lists. State values
|
|
266
|
+
remain open strings; use REST as authority instead of
|
|
267
|
+
recreating the server lifecycle machine in the client. Each snapshot may also
|
|
268
|
+
carry open-string diagnostics: `reason` is the stable cause such as `start`,
|
|
269
|
+
`api_stop`, `runtime_exit`, `timeout`, or `delete`, `error` is a failure code
|
|
270
|
+
when the transition failed, and `message` is human-readable context.
|
|
271
|
+
|
|
272
|
+
Persist desktop/browser configuration through `create(...)` or `update(..., launch_config=...)` (build the payload with `build_agent_config`). Use the standard OpenClaw image, a protected `desktop` route (the `desktop-<agent>.hypercli.app` host, port 3000, `auth=True`), and `HYPER_DESKTOP_ENABLED=1`.
|
|
273
|
+
|
|
274
|
+
Automatic memory indexing is off by default. Opt in by merging `build_openclaw_memory_index_env({"on_session_start": True, "on_search": True, "watch": True, "watch_debounce_ms": 30000, "interval_minutes": 0})` into the launch `env`.
|
|
275
|
+
|
|
276
|
+
## Hosted Coding Agents
|
|
277
|
+
|
|
278
|
+
Native Buzz Agent, OpenCode, Codex, Claude Code, Goose, and Kimi Code use
|
|
279
|
+
canonical managed-runtime images.
|
|
280
|
+
They have no public runtime port: lifecycle, exec, shell, workspace sync, and
|
|
281
|
+
authentication all use the existing authenticated deployment APIs. OpenCode
|
|
282
|
+
and Goose default to HyperCLI's Anthropic-native `default-anthropic` route (currently `kimi-k3-anthropic`).
|
|
283
|
+
Kimi Code keeps Moonshot's upstream device login and service.
|
|
284
|
+
Claude Code, Codex, and Kimi Code are native-login-first. For Buzz-managed
|
|
285
|
+
launches, `HYPERCLI_RUNTIME_INFERENCE=hypercli` is an explicit compatibility
|
|
286
|
+
switch for Claude and Kimi. The gateway now exposes `/v1/responses`, and Buzz
|
|
287
|
+
compatibility mode renders Codex with `wire_api="responses"`; a successful
|
|
288
|
+
HyperCLI-model Codex Responses E2E remains unvalidated, so that path is not yet
|
|
289
|
+
advertised as supported. See the
|
|
290
|
+
[runtime and persistence matrix](../docs/agents/coding-runtimes.mdx).
|
|
291
|
+
|
|
292
|
+
All coding runtimes share one launch contract, `create_agent(runtime, ...)`;
|
|
293
|
+
`runtime` selects the default image, sync includes, and harness env. Permission
|
|
294
|
+
policy is native session configuration; no allow-all preset is injected. A
|
|
295
|
+
caller's standard `session/request_permission` handler may present the offered
|
|
296
|
+
choices or select `allow_once` per request without changing runtime modes.
|
|
297
|
+
The accepted runtimes are `buzz-agent`, `opencode`,
|
|
298
|
+
`codex`, `claude-code`, `goose`, `kimi-code`, and `pi`.
|
|
299
|
+
`create_coding_agent` survives only as a deprecated alias that warns and
|
|
300
|
+
forwards to `create_agent`.
|
|
301
|
+
|
|
302
|
+
**Breaking API change:** `build_permissions_json` and the custom permission
|
|
303
|
+
preset catalog have been removed. Explicit legacy `permission_mode` launch
|
|
304
|
+
arguments fail with a retirement error; use advertised ACP session config options
|
|
305
|
+
or explicit native runtime launch configuration instead.
|
|
306
|
+
|
|
307
|
+
```python
|
|
308
|
+
buzz_agent = client.deployments.create_agent("buzz-agent", name="buzz-agent")
|
|
309
|
+
agent = client.deployments.create_agent("opencode", name="opencode")
|
|
310
|
+
codex = client.deployments.create_agent("codex", name="codex")
|
|
311
|
+
claude = client.deployments.create_agent("claude-code", name="claude")
|
|
312
|
+
goose = client.deployments.create_agent("goose", name="goose")
|
|
313
|
+
kimi = client.deployments.create_agent("kimi-code", name="kimi")
|
|
314
|
+
|
|
315
|
+
methods = codex.auth.methods()
|
|
316
|
+
status = codex.auth.status()
|
|
317
|
+
|
|
318
|
+
async with await codex.auth.login("device") as login:
|
|
319
|
+
print(login.verification_url, login.user_code)
|
|
320
|
+
await login.wait()
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
The login helper opens a short-lived, agent-bound shell WebSocket and runs the
|
|
324
|
+
runtime's native login command inside the managed runtime. It never puts an API key on
|
|
325
|
+
the command line. Runtime credentials and state live under the persistent
|
|
326
|
+
`/home/node` sync root.
|
|
327
|
+
|
|
328
|
+
Authentication is runtime-specific rather than one universal login protocol.
|
|
329
|
+
Native Buzz Agent has no separate login step and uses its injected model and
|
|
330
|
+
provider configuration. `methods()` returns supported native commands: OpenCode
|
|
331
|
+
provider login, Codex device login, and Claude Code's Claude.ai, Console and SSO
|
|
332
|
+
login. Status uses the native OpenCode, Codex or Claude command. Buzz, Goose,
|
|
333
|
+
Kimi and Pi status discovery is unsupported through this SDK surface and raises
|
|
334
|
+
an error; use their native runtime authentication interface. No plugin probe or
|
|
335
|
+
fallback `authenticate` command is launched. Goose and Kimi expose no
|
|
336
|
+
noninteractive logout through this surface.
|
|
337
|
+
|
|
338
|
+
The images default to a long-lived direct shell/exec container. The managed
|
|
339
|
+
platform (runner/Lagoon) injects consistent defaults for `HYPER_API_BASE`
|
|
340
|
+
(product/inference), `HYPER_AGENTS_API_BASE` (direct Agent control), the
|
|
341
|
+
appropriate ACP URL, and agent-scoped `HYPER_AGENTS_API_KEY`.
|
|
342
|
+
Customers may override either base and supply canonical `HYPER_API_KEY`
|
|
343
|
+
through launch `env` or `secrets`, including for managing other agents. Clients
|
|
344
|
+
prefer an explicit canonical credential, environment `HYPER_API_KEY`, then the
|
|
345
|
+
configured canonical key before the platform runtime fallback. The launch
|
|
346
|
+
owner's auth key is never automatically forwarded.
|
|
347
|
+
The Agents base never selects inference. External inference URLs/keys must not
|
|
348
|
+
implicitly redirect platform callbacks or reconnects. Explicit `HYPER_ACP_WS_URL`
|
|
349
|
+
wins; otherwise derive from the Agents base, using the product base only when
|
|
350
|
+
no Agents base is supplied. ACP authentication uses the separate runtime key.
|
|
351
|
+
|
|
352
|
+
The typed Buzz launch contract (`BuzzLaunchConfig`) is TS-SDK-only:
|
|
353
|
+
`create_agent` accepts no `buzz=` option, and passing a `buzz` keyword raises
|
|
354
|
+
`TypeError`. Use the TS SDK's `createAgent(runtime, { buzz: ... })` for a
|
|
355
|
+
Buzz-managed identity launch, or render the raw contract yourself over the
|
|
356
|
+
generic launch surface: put `BUZZ_PRIVATE_KEY` (and optionally
|
|
357
|
+
`NOSTR_PRIVATE_KEY`) in `env` — `create_agent` promotes both to launch
|
|
358
|
+
secrets — and pass the remaining `BUZZ_*` keys as launch environment for the
|
|
359
|
+
managed image to parse at boot.
|
|
360
|
+
|
|
361
|
+
Caller environment becomes raw deployment environment values.
|
|
362
|
+
The agents backend currently persists them in `Agent.launch_config`, and
|
|
363
|
+
authenticated deployment read, environment, or exec surfaces may expose them.
|
|
364
|
+
The default `RUST_LOG` filter disables `acp::stream` content logging; overriding
|
|
365
|
+
it can expose generated text in container logs.
|
|
366
|
+
|
|
367
|
+
Persisted launch environment values can be changed one key at a time while an
|
|
368
|
+
agent is stopped:
|
|
369
|
+
|
|
370
|
+
```python
|
|
371
|
+
agent.set_env("LOG_LEVEL", "debug")
|
|
372
|
+
agent.delete_env("LOG_LEVEL")
|
|
373
|
+
agent.set_secret("SERVICE_TOKEN", token)
|
|
374
|
+
agent.delete_secret("SERVICE_TOKEN")
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
These methods return `AgentLaunchValueMutation` metadata. Secret writes never
|
|
378
|
+
echo the secret value in their response.
|
|
379
|
+
|
|
380
|
+
## Platform session metadata
|
|
381
|
+
|
|
382
|
+
```python
|
|
383
|
+
from hypercli import HyperCLI, SessionRecord
|
|
384
|
+
|
|
385
|
+
client = HyperCLI()
|
|
386
|
+
# Platform ID from /ws/acp session/new or deployments.list_sessions(), not a leg ID.
|
|
387
|
+
session: SessionRecord = client.deployments.get_session(platform_session_id)
|
|
388
|
+
print(session.source, session.summary_text, session.participants)
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
`get_session()` calls `GET /agents/sessions/{id}` using the existing caller
|
|
392
|
+
credentials and the same `SessionRecord` decoder as `list_sessions()`, extended
|
|
393
|
+
with `import_outcome` and platform history state (`last_message_id`,
|
|
394
|
+
`message_count`, `head_seq`, per-message `receipts`). Nullable
|
|
395
|
+
source values are forward-compatible strings; the title is `summary_text`.
|
|
396
|
+
Timestamps and participant dictionaries retain the existing catalog shape.
|
|
397
|
+
Reads work offline without runtime connections. The backend advances the caller's
|
|
398
|
+
user read receipt to the session head on a best-effort basis. Platform history
|
|
399
|
+
and pagination remain separate from ACP attachment and live turns. HTTP
|
|
400
|
+
errors propagate as `APIError`: 404 unknown session, 403 outside participation
|
|
401
|
+
scope, 422 invalid UUID. No service impersonation or runtime-ID resolution occurs.
|
|
402
|
+
|
|
403
|
+
## ACP v1 conversation client
|
|
404
|
+
|
|
405
|
+
`hypercli.acp.ACPClient` connects to the backend `/ws/acp` authority using the
|
|
406
|
+
pinned upstream `agent-client-protocol[http]==1.0.0rc2` from PyPI
|
|
407
|
+
(schema-v1.23.0). Its `acp/` package matches Git commit
|
|
408
|
+
`9d07d7871ef4b220b8507e15fc4b1560f0950a64` byte-for-byte.
|
|
409
|
+
Product ACP traffic targets vanilla v1 throughout.
|
|
410
|
+
|
|
411
|
+
```python
|
|
412
|
+
from hypercli.acp import ACPClient, AmbiguousDeliveryError, RetryableACPError
|
|
413
|
+
|
|
414
|
+
async with await ACPClient.connect(proxy_url, token=api_key, on_update=handle_update) as acp:
|
|
415
|
+
session_id = await acp.new_session(cwd="/home/node")
|
|
416
|
+
result = await acp.prompt(session_id, "Summarize overnight mail")
|
|
417
|
+
print(result.stop_reason) # correlated native terminal response
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
Use `resume_session(id, cwd=...)` for supported native attachment. It never
|
|
421
|
+
falls back to full load or resubmits a turn. There is no client-side full
|
|
422
|
+
history load: managed native reconciliation belongs to Backend, which drives
|
|
423
|
+
`session/load` on its own import leg.
|
|
424
|
+
`cancel(id)` sends the standard notification, never a replacement prompt.
|
|
425
|
+
There are no replay/window cursor arguments. Both `prompt` and `submit_prompt`
|
|
426
|
+
wait for the native terminal response. `submit_prompt` returns the upstream typed
|
|
427
|
+
`PromptResponse`; `prompt` returns `ACPPromptResult`. Neither requires a receipt
|
|
428
|
+
reader or infers completion from notifications. Inspect stored evidence separately
|
|
429
|
+
through the sessions REST API.
|
|
430
|
+
|
|
431
|
+
Known pre-write failures raise `RetryableACPError`; uncertain post-write/foreground
|
|
432
|
+
outcomes raise `AmbiguousDeliveryError`. Neither is automatically retried. Protocol
|
|
433
|
+
errors preserve code, message and data through `ACPRequestError`. Metadata and read
|
|
434
|
+
receipts stay on the existing platform REST APIs, not ACP fields or `_meta`.
|
|
435
|
+
|
|
436
|
+
Python is one-shot: it does not reconnect or replay submissions automatically.
|
|
437
|
+
|
|
438
|
+
## Error Handling
|
|
439
|
+
|
|
440
|
+
```python
|
|
441
|
+
from hypercli import HyperCLI, APIError
|
|
442
|
+
|
|
443
|
+
client = HyperCLI()
|
|
444
|
+
|
|
445
|
+
try:
|
|
446
|
+
job = client.jobs.get("invalid_id")
|
|
447
|
+
except APIError as e:
|
|
448
|
+
print(f"Error {e.status_code}: {e.detail}")
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
## License
|
|
452
|
+
|
|
453
|
+
MIT
|