runninghub-cli 0.1.0__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.
- runninghub_cli-0.1.0/HANDOFF.md +290 -0
- runninghub_cli-0.1.0/MANIFEST.in +3 -0
- runninghub_cli-0.1.0/PKG-INFO +219 -0
- runninghub_cli-0.1.0/SKILL.md +184 -0
- runninghub_cli-0.1.0/data/capabilities.json +12460 -0
- runninghub_cli-0.1.0/rh/__init__.py +2 -0
- runninghub_cli-0.1.0/rh/catalog.py +16 -0
- runninghub_cli-0.1.0/rh/cli.py +41 -0
- runninghub_cli-0.1.0/rh/client.py +544 -0
- runninghub_cli-0.1.0/rh/commands/__init__.py +0 -0
- runninghub_cli-0.1.0/rh/commands/account.py +21 -0
- runninghub_cli-0.1.0/rh/commands/app.py +177 -0
- runninghub_cli-0.1.0/rh/commands/model.py +139 -0
- runninghub_cli-0.1.0/rh/commands/task.py +42 -0
- runninghub_cli-0.1.0/rh/output.py +11 -0
- runninghub_cli-0.1.0/runninghub_cli.egg-info/PKG-INFO +219 -0
- runninghub_cli-0.1.0/runninghub_cli.egg-info/SOURCES.txt +25 -0
- runninghub_cli-0.1.0/runninghub_cli.egg-info/dependency_links.txt +1 -0
- runninghub_cli-0.1.0/runninghub_cli.egg-info/entry_points.txt +2 -0
- runninghub_cli-0.1.0/runninghub_cli.egg-info/requires.txt +1 -0
- runninghub_cli-0.1.0/runninghub_cli.egg-info/top_level.txt +2 -0
- runninghub_cli-0.1.0/setup.cfg +4 -0
- runninghub_cli-0.1.0/setup.py +44 -0
- runninghub_cli-0.1.0/tests/__init__.py +0 -0
- runninghub_cli-0.1.0/tests/test_catalog.py +61 -0
- runninghub_cli-0.1.0/tests/test_cli.py +109 -0
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# RunningHub CLI (`rh`) — AI Handoff Document
|
|
2
|
+
|
|
3
|
+
> **For:** Next AI agent or developer taking over this project
|
|
4
|
+
> **Written by:** Claude (claude-opus-4-5) after completing initial implementation + live API validation
|
|
5
|
+
> **Date:** 2026-04-12
|
|
6
|
+
> **Status:** v0.1.0 — fully working, all smoke tests passed
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 1. What Was Built and Why
|
|
11
|
+
|
|
12
|
+
`rh` is an agent-native CLI for [RunningHub](https://www.runninghub.cn) — a cloud ComfyUI platform.
|
|
13
|
+
|
|
14
|
+
**Origin:** Two existing projects existed but were not usable by AI agents:
|
|
15
|
+
- `OpenClaw_RH_Skills/` — Python scripts covering 209 standard model endpoints, written as a conversational persona tool (OpenClaw), not a CLI
|
|
16
|
+
- `RunningHub-AI-Client/` — React/TypeScript/Tauri desktop GUI with clean `services/api.ts` layer
|
|
17
|
+
|
|
18
|
+
This CLI distils both into a single `rh` command following CLI-Anything methodology: every command prints JSON to stdout, errors go to stderr with exit code 1.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 2. Critical Architecture: Two Completely Separate API Systems
|
|
23
|
+
|
|
24
|
+
> **This is the most important thing to understand.** The two API systems have different auth, different upload endpoints, different response shapes, and different polling protocols. They cannot be mixed.
|
|
25
|
+
|
|
26
|
+
### System A — Standard Model API
|
|
27
|
+
|
|
28
|
+
| Property | Value |
|
|
29
|
+
|----------|-------|
|
|
30
|
+
| Purpose | 209 pre-built model endpoints (image/video/audio/3D) |
|
|
31
|
+
| Base URL | `https://www.runninghub.cn/openapi/v2` |
|
|
32
|
+
| Auth | `Authorization: Bearer <apiKey>` header |
|
|
33
|
+
| Run endpoint | `POST /openapi/v2/{model}/{task}` |
|
|
34
|
+
| Poll endpoint | `POST /openapi/v2/query` with body `{"taskId":"..."}` |
|
|
35
|
+
| Poll response | `{"taskId":"..","status":"SUCCESS|FAILED|QUEUED|RUNNING","results":[...],"errorCode":"","errorMessage":""}` |
|
|
36
|
+
| Upload endpoint | `POST /openapi/v2/media/upload/binary` (multipart, Bearer auth) |
|
|
37
|
+
| Upload returns | `{"code":0,"data":{"download_url":"https://cdn..."}}` |
|
|
38
|
+
| Key type required | **SHARED / enterprise key only** (NORMAL keys return code=1014) |
|
|
39
|
+
| Key field in poll | Bearer header |
|
|
40
|
+
|
|
41
|
+
**IMPORTANT:** Standard model run response is NOT a `{"code":0,"data":{}}` envelope. It directly returns `{"taskId":"..","errorCode":"..","errorMessage":"..","results":null}`. The `errorCode` field signals errors (non-empty and non-"0" = error).
|
|
42
|
+
|
|
43
|
+
### System B — AI Apps API
|
|
44
|
+
|
|
45
|
+
| Property | Value |
|
|
46
|
+
|----------|-------|
|
|
47
|
+
| Purpose | Custom ComfyUI workflow apps (user-created) |
|
|
48
|
+
| Auth | `apiKey` field **inside the JSON body** (no Authorization header) |
|
|
49
|
+
| Run endpoint | `POST /task/openapi/ai-app/run` with `{"webappId":"..","apiKey":"..","nodeInfoList":[...]}` |
|
|
50
|
+
| Poll endpoint | `POST /task/openapi/outputs` with body `{"apiKey":"..","taskId":"..."}` |
|
|
51
|
+
| Poll response | `{"code":804,...}` = running; `{"code":0,"data":[{fileUrl,fileType},...]}` = done |
|
|
52
|
+
| Upload endpoint | `POST /task/openapi/upload` (multipart, `apiKey` + `fileType` in form fields) |
|
|
53
|
+
| Upload returns | `{"code":0,"data":{"fileName":"abc.png"}}` — use `fileName` as fieldValue |
|
|
54
|
+
| Key type required | Works with NORMAL key |
|
|
55
|
+
| App list | `POST /api/webapp/list` (no auth, public catalog) |
|
|
56
|
+
| App info | `GET /api/webapp/apiCallDemo?apiKey=...&webappId=...` |
|
|
57
|
+
|
|
58
|
+
**IMPORTANT:** AI Apps poll `data` is a **list** directly, not `{"outputs":[...]}`. `code=804` means still running; loop until `code=0`.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 3. Project Structure
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
runninghub-cli/
|
|
66
|
+
├── rh/
|
|
67
|
+
│ ├── __init__.py # version = "0.1.0"
|
|
68
|
+
│ ├── cli.py # Click entry point, registers 4 command groups
|
|
69
|
+
│ ├── client.py # ALL HTTP logic — the most critical file
|
|
70
|
+
│ ├── catalog.py # Loads data/capabilities.json; unwraps {"endpoints":[...]} wrapper
|
|
71
|
+
│ ├── output.py # JSON stdout + stderr progress dots
|
|
72
|
+
│ └── commands/
|
|
73
|
+
│ ├── account.py # rh account status
|
|
74
|
+
│ ├── model.py # rh model list/info/run/auto
|
|
75
|
+
│ ├── app.py # rh app list/info/run/batch
|
|
76
|
+
│ └── task.py # rh task status/outputs
|
|
77
|
+
├── data/
|
|
78
|
+
│ └── capabilities.json # 209 endpoints, shape: {"endpoints":[...],"total":209,"version":"..."}
|
|
79
|
+
├── tests/
|
|
80
|
+
│ ├── test_catalog.py # 8 tests
|
|
81
|
+
│ └── test_cli.py # 9 tests — 17 total, all passing
|
|
82
|
+
├── setup.py # entry_points: rh=rh.cli:main
|
|
83
|
+
├── SKILL.md # Agent discovery — command reference and JSON schemas
|
|
84
|
+
└── HANDOFF.md # ← this file
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 4. Key Implementation Details in `client.py`
|
|
90
|
+
|
|
91
|
+
### API Key Resolution (priority order)
|
|
92
|
+
```python
|
|
93
|
+
def _resolve_api_key(api_key=None):
|
|
94
|
+
1. explicit --api-key argument
|
|
95
|
+
2. RH_API_KEY environment variable ← recommended
|
|
96
|
+
3. ~/.rh/config.json → {"apiKey": "..."}
|
|
97
|
+
→ raises RunningHubError("auth_missing", ...) if none found
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### File Upload Logic
|
|
101
|
+
Two separate upload functions — **never mix them**:
|
|
102
|
+
- `_upload_file_for_model(api_key, path)` → Standard API → returns CDN `download_url` (https://...)
|
|
103
|
+
- `_upload_file_for_app(api_key, path)` → AI Apps API → returns `fileName` (short string)
|
|
104
|
+
|
|
105
|
+
For standard model, small images can be base64-encoded inline (`data:image/png;base64,...`).
|
|
106
|
+
Videos and files ≥5 MB are always uploaded to CDN first (threshold: `FILE_UPLOAD_THRESHOLD_MB = 5`).
|
|
107
|
+
|
|
108
|
+
### `_resolve_key()` — The `--image` → `imageUrls` Problem
|
|
109
|
+
CLI accepts `--image`, `--video`, `--audio` as convenience flags, but the actual endpoint schema parameter key may be `imageUrls`, `imageUrl`, `videoInput`, etc.
|
|
110
|
+
|
|
111
|
+
The function in `run_model()` builds a `media_type_to_key` map from the catalog schema and remaps CLI names to actual keys:
|
|
112
|
+
```python
|
|
113
|
+
# Example: endpoint uses {"key":"imageUrls","type":"IMAGE","multiple":true}
|
|
114
|
+
# CLI: --image photo.jpg → resolves to {"imageUrls": ["https://cdn.../photo.jpg"]}
|
|
115
|
+
```
|
|
116
|
+
Also handles `multiple: true` params by wrapping single values in a list.
|
|
117
|
+
|
|
118
|
+
### Polling Timeouts
|
|
119
|
+
- `MAX_POLL_SECONDS = 1200` (20 minutes)
|
|
120
|
+
- `POLL_INTERVAL = 5` seconds
|
|
121
|
+
- Both pollers tolerate up to 5 consecutive HTTP errors before giving up
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## 5. `capabilities.json` — Catalog Format
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"endpoints": [
|
|
130
|
+
{
|
|
131
|
+
"endpoint": "rhart-image-n-pro/text-to-image",
|
|
132
|
+
"name_cn": "...",
|
|
133
|
+
"name_en": "...",
|
|
134
|
+
"task": "text-to-image",
|
|
135
|
+
"output_type": "image",
|
|
136
|
+
"popularity": 1,
|
|
137
|
+
"tags": ["official"],
|
|
138
|
+
"params": [
|
|
139
|
+
{"key": "prompt", "type": "STRING", "required": true},
|
|
140
|
+
{"key": "imageUrls", "type": "IMAGE", "required": false, "multiple": true, "maxSizeMB": 10},
|
|
141
|
+
{"key": "aspectRatio", "type": "LIST", "required": false, "options": ["1:1","16:9"], "default": "1:1"}
|
|
142
|
+
]
|
|
143
|
+
}
|
|
144
|
+
],
|
|
145
|
+
"total": 209,
|
|
146
|
+
"version": "..."
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
`catalog.py` must unwrap the `{"endpoints":[...]}` wrapper — do NOT pass the raw dict to list functions.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## 6. Known Catalog Validity Issues
|
|
155
|
+
|
|
156
|
+
**Not all 209 catalog entries are live.** Some return `code=1001 "Invalid URL"` from the API.
|
|
157
|
+
|
|
158
|
+
Confirmed WORKING endpoints (tested 2026-04-12):
|
|
159
|
+
- `rhart-image-n-pro/text-to-image` ✅
|
|
160
|
+
- `rhart-video-v3.1-fast/text-to-video` ✅ (103s, SHARED key)
|
|
161
|
+
- `rhart-video-v3.1-fast/image-to-video` ✅ (129s, SHARED key)
|
|
162
|
+
- `rhart-video-v3.1-fast-official/video-extend` ✅ (119s, SHARED key, "video-to-video")
|
|
163
|
+
- AI Apps (any `webappId` from `rh app list`) ✅ (NORMAL key works)
|
|
164
|
+
|
|
165
|
+
Confirmed BROKEN endpoints:
|
|
166
|
+
- `rhart-video-s/text-to-video` → code=1001 "Invalid URL"
|
|
167
|
+
|
|
168
|
+
When an endpoint returns 1001, try the next endpoint for the same task type (`rh model list --task <X>` and pick one with low popularity number).
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## 7. Live Test Results Summary
|
|
173
|
+
|
|
174
|
+
| Test | Mode | Key Type | Result | Time |
|
|
175
|
+
|------|------|----------|--------|------|
|
|
176
|
+
| `rh account status` | Standard | NORMAL | ✅ coins balance | <1s |
|
|
177
|
+
| `rh app list` | AI Apps | — | ✅ 20 apps | <1s |
|
|
178
|
+
| `rh app run` (全能图片2.0) | AI Apps | NORMAL | ✅ `test_robot_cat.png` | ~30s |
|
|
179
|
+
| `rh model run rhart-video-v3.1-fast/text-to-video` | Standard | SHARED | ✅ `test_t2v.mp4` | 103s |
|
|
180
|
+
| `rh model run rhart-video-v3.1-fast/image-to-video` | Standard | SHARED | ✅ `test_i2v.mp4` | 129s |
|
|
181
|
+
| `rh model run rhart-video-v3.1-fast-official/video-extend` | Standard | SHARED | ✅ `test_v2v.mp4` | 119s |
|
|
182
|
+
| `pytest tests/` | — | — | ✅ 17/17 | 0.03s |
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## 8. API Response Field Mapping Gotchas
|
|
187
|
+
|
|
188
|
+
These field names differ from what you might assume — all were discovered by live testing:
|
|
189
|
+
|
|
190
|
+
| Context | Expected | Actual |
|
|
191
|
+
|---------|----------|--------|
|
|
192
|
+
| App list record ID | `webappId` | `id` |
|
|
193
|
+
| App list record name | `webappName` | `name` |
|
|
194
|
+
| App list description | `description` | `intro` |
|
|
195
|
+
| App info node list | `nodeList` or `nodes` | `nodeInfoList` |
|
|
196
|
+
| App info English desc | `description` | `descriptionEn` |
|
|
197
|
+
| Standard model error | `code`, `message` | `errorCode`, `errorMessage` |
|
|
198
|
+
| Standard model results | `data.outputs` | `results` (top-level array) |
|
|
199
|
+
| AI Apps outputs | `data.outputs` | `data` is the list itself |
|
|
200
|
+
| Standard upload URL | `/task/openapi/upload` | `/openapi/v2/media/upload/binary` |
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## 9. Security
|
|
205
|
+
|
|
206
|
+
- **Zero API keys hardcoded** anywhere in `rh/` source code
|
|
207
|
+
- Keys only come from: env var `RH_API_KEY`, `--api-key` flag, or `~/.rh/config.json`
|
|
208
|
+
- `.claude/settings.local.json` was cleaned after testing — now uses wildcard rules only
|
|
209
|
+
|
|
210
|
+
**For new environments:**
|
|
211
|
+
```bash
|
|
212
|
+
# Option A — env var (recommended)
|
|
213
|
+
export RH_API_KEY=your_key_here
|
|
214
|
+
|
|
215
|
+
# Option B — config file
|
|
216
|
+
mkdir -p ~/.rh && echo '{"apiKey":"your_key_here"}' > ~/.rh/config.json
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## 10. Installation
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
cd runninghub-cli
|
|
225
|
+
pip install -e . # dev install, editable
|
|
226
|
+
# OR
|
|
227
|
+
pip install . # production install
|
|
228
|
+
|
|
229
|
+
rh --help # verify
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Requires Python ≥ 3.8. Only external dependency: `click>=8.0`.
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## 11. Running Tests
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
cd runninghub-cli
|
|
240
|
+
python -m pytest tests/ -q
|
|
241
|
+
# Expected: 17 passed in ~0.03s (no network calls, all mocked/unit)
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## 12. Suggested Next Steps
|
|
247
|
+
|
|
248
|
+
### High Priority
|
|
249
|
+
1. **`rh model auto` endpoint validation** — `auto` picks by popularity rank, but some top-ranked endpoints return 1001. Add live probe/fallback: try the endpoint, if 1001 try next one in ranked list.
|
|
250
|
+
2. **`~/.rh/config.json` init command** — `rh config set-key YOUR_KEY` to avoid users manually writing JSON.
|
|
251
|
+
3. **`rh model list` live filter** — currently filters only from catalog (static). Add `--live` flag that probes each endpoint with a dry run.
|
|
252
|
+
|
|
253
|
+
### Medium Priority
|
|
254
|
+
4. **Streaming progress** — currently just prints dots to stderr. A `--progress` flag with JSON-lines progress events would help agents track long video jobs.
|
|
255
|
+
5. **Batch mode for `rh model`** — `rh model batch` analogous to `rh app batch`, for running the same model on many inputs from CSV.
|
|
256
|
+
6. **Update capabilities.json** — the catalog is a static snapshot. A `rh catalog update` command could fetch the live list from RunningHub and regenerate it.
|
|
257
|
+
|
|
258
|
+
### Low Priority
|
|
259
|
+
7. **Windows path handling** — tested on Windows; `Path()` objects work, but `~/.rh/` resolves to `C:\Users\<user>\.rh\`. Works correctly.
|
|
260
|
+
8. **Async polling** — currently blocking. For batch use, `asyncio` would allow concurrent polls.
|
|
261
|
+
9. **`rh app batch` CSV encoding** — currently assumes UTF-8. Add `--encoding` flag.
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## 13. Important URLs
|
|
266
|
+
|
|
267
|
+
| Resource | URL |
|
|
268
|
+
|----------|-----|
|
|
269
|
+
| RunningHub platform | https://www.runninghub.cn |
|
|
270
|
+
| API key page | https://www.runninghub.cn/enterprise-api/sharedApi |
|
|
271
|
+
| Official API docs | https://www.runninghub.cn/runninghub-api-doc-cn/ |
|
|
272
|
+
| Pricing | https://www.runninghub.cn/third-party-fees |
|
|
273
|
+
| Membership tiers | https://www.runninghub.cn/vip-rights/2 |
|
|
274
|
+
| API Reference (agent-readable) | `../RUNNINGHUB_API_REFERENCE.md` (in parent dir) |
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## 14. Key Type Reference
|
|
279
|
+
|
|
280
|
+
| API | NORMAL key | SHARED/enterprise key |
|
|
281
|
+
|-----|-----------|----------------------|
|
|
282
|
+
| AI Apps (`rh app *`) | ✅ works | ✅ works |
|
|
283
|
+
| Standard Models (`rh model *`) | ❌ code=1014 | ✅ required |
|
|
284
|
+
| Account status (`rh account *`) | ✅ works | ✅ works |
|
|
285
|
+
|
|
286
|
+
To get a SHARED key: RunningHub enterprise plan → https://www.runninghub.cn/enterprise-api/sharedApi
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
*End of handoff. The codebase is clean, tested, and ready for Git push.*
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: runninghub-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Agent-native CLI for RunningHub AI platform (image/video/audio/3D generation)
|
|
5
|
+
Home-page: https://cnb.cool/101ya/runninghub-cli
|
|
6
|
+
Author: 101ya
|
|
7
|
+
License: MIT
|
|
8
|
+
Keywords: runninghub ai image video generation comfyui cli agent
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Multimedia :: Graphics
|
|
19
|
+
Classifier: Topic :: Multimedia :: Sound/Audio
|
|
20
|
+
Classifier: Topic :: Multimedia :: Video
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
22
|
+
Requires-Python: >=3.8
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
Requires-Dist: click>=8.0
|
|
25
|
+
Dynamic: author
|
|
26
|
+
Dynamic: classifier
|
|
27
|
+
Dynamic: description
|
|
28
|
+
Dynamic: description-content-type
|
|
29
|
+
Dynamic: home-page
|
|
30
|
+
Dynamic: keywords
|
|
31
|
+
Dynamic: license
|
|
32
|
+
Dynamic: requires-dist
|
|
33
|
+
Dynamic: requires-python
|
|
34
|
+
Dynamic: summary
|
|
35
|
+
|
|
36
|
+
# RunningHub CLI (`rh`) — Agent Skill
|
|
37
|
+
|
|
38
|
+
## What This Tool Does
|
|
39
|
+
|
|
40
|
+
`rh` is a command-line interface for the [RunningHub AI platform](https://www.runninghub.cn) — a cloud ComfyUI service with 209+ built-in AI model endpoints and support for custom ComfyUI workflow apps.
|
|
41
|
+
|
|
42
|
+
Use `rh` to:
|
|
43
|
+
- Generate images, videos, audio, and 3D models from text/image prompts
|
|
44
|
+
- Browse and run custom ComfyUI AI App workflows
|
|
45
|
+
- Check task status and download outputs
|
|
46
|
+
- Monitor account balance
|
|
47
|
+
|
|
48
|
+
## Setup
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
export RH_API_KEY=your_runninghub_api_key
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Or pass `--api-key KEY` to any command.
|
|
55
|
+
|
|
56
|
+
Get a key at: https://www.runninghub.cn/enterprise-api/sharedApi
|
|
57
|
+
|
|
58
|
+
## Command Reference
|
|
59
|
+
|
|
60
|
+
### Account
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
rh account status
|
|
64
|
+
# → {"remainCoins": "150.0", "currentTaskCounts": "0", "apiType": "coins"}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Built-in Models (`rh model`)
|
|
68
|
+
|
|
69
|
+
For quick AI generation using RunningHub's 209 pre-built models.
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# List available models
|
|
73
|
+
rh model list --type image
|
|
74
|
+
rh model list --task text-to-image --top 5
|
|
75
|
+
rh model list --type video
|
|
76
|
+
|
|
77
|
+
# Get parameter schema for an endpoint
|
|
78
|
+
rh model info rhart-image-n-pro/text-to-image
|
|
79
|
+
|
|
80
|
+
# Auto-select best model for a task (recommended for agents)
|
|
81
|
+
rh model auto --task text-to-image --prompt "a sunset over mountains" --output out.png
|
|
82
|
+
rh model auto --task image-to-video --image input.jpg --output out.mp4
|
|
83
|
+
rh model auto --task text-to-speech --prompt "Hello world" --output out.mp3
|
|
84
|
+
rh model auto --task text-to-3d --prompt "a ceramic teapot" --output model.glb
|
|
85
|
+
|
|
86
|
+
# Run a specific endpoint
|
|
87
|
+
rh model run rhart-image-n-pro/text-to-image --prompt "anime cat" --output cat.png
|
|
88
|
+
rh model run kling-video-o3-pro/image-to-video --image photo.jpg --output video.mp4
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Available task types:**
|
|
92
|
+
- `text-to-image`, `image-to-image`, `image-upscale`
|
|
93
|
+
- `text-to-video`, `image-to-video`, `reference-to-video`, `start-end-to-video`
|
|
94
|
+
- `text-to-speech`, `music-generation`, `voice-clone`
|
|
95
|
+
- `text-to-3d`, `image-to-3d`, `multi-image-to-3d`
|
|
96
|
+
|
|
97
|
+
### Custom AI Apps (`rh app`)
|
|
98
|
+
|
|
99
|
+
For custom ComfyUI workflows. Each app has a `webappId` and modifiable input nodes.
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# Browse public apps
|
|
103
|
+
rh app list --search "anime portrait" --sort RECOMMEND
|
|
104
|
+
rh app list --sort HOTTEST --size 10
|
|
105
|
+
|
|
106
|
+
# Inspect an app's input schema before running
|
|
107
|
+
rh app info 1234567890
|
|
108
|
+
# → {"webappId": "...", "name": "...", "nodes": [{"nodeId": "6", "fieldName": "prompt", "fieldType": "STRING", ...}]}
|
|
109
|
+
|
|
110
|
+
# Run an app
|
|
111
|
+
rh app run 1234567890 \
|
|
112
|
+
--node "6:prompt=a samurai cat warrior" \
|
|
113
|
+
--output result.mp4
|
|
114
|
+
|
|
115
|
+
# Run with a file input
|
|
116
|
+
rh app run 1234567890 \
|
|
117
|
+
--node "6:prompt=enhance this portrait" \
|
|
118
|
+
--file "10:image=/path/to/photo.jpg" \
|
|
119
|
+
--output enhanced.png
|
|
120
|
+
|
|
121
|
+
# Batch run from CSV
|
|
122
|
+
rh app batch 1234567890 --input params.csv --concurrency 3 --output-dir ./results/
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Batch CSV format:**
|
|
126
|
+
```csv
|
|
127
|
+
6:prompt,10:image
|
|
128
|
+
"a ninja dog",/path/to/dog.jpg
|
|
129
|
+
"a robot cat",/path/to/cat.jpg
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Task Management
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
# Check status of a task
|
|
136
|
+
rh task status abc123
|
|
137
|
+
|
|
138
|
+
# Get outputs for a completed task
|
|
139
|
+
rh task outputs abc123 --output result.png
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## JSON Output Schema
|
|
143
|
+
|
|
144
|
+
All commands output JSON. Agents should parse stdout directly.
|
|
145
|
+
|
|
146
|
+
**`rh model auto` / `rh model run` success:**
|
|
147
|
+
```json
|
|
148
|
+
{
|
|
149
|
+
"taskId": "abc123",
|
|
150
|
+
"status": "SUCCESS",
|
|
151
|
+
"outputs": [{"fileUrl": "https://cdn.runninghub.cn/...", "fileType": "image/png"}],
|
|
152
|
+
"cost": {"duration_s": 8},
|
|
153
|
+
"savedTo": "/path/to/out.png",
|
|
154
|
+
"selectedEndpoint": "rhart-image-n-pro/text-to-image"
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**`rh app run` success:**
|
|
159
|
+
```json
|
|
160
|
+
{
|
|
161
|
+
"taskId": "xyz789",
|
|
162
|
+
"status": "SUCCESS",
|
|
163
|
+
"outputs": [{"fileUrl": "https://...", "fileType": "video/mp4"}],
|
|
164
|
+
"savedTo": "/path/to/result.mp4"
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Errors (exit code 1):**
|
|
169
|
+
```json
|
|
170
|
+
{"error": "auth_failed", "message": "Invalid API key or unauthorized"}
|
|
171
|
+
{"error": "insufficient_balance", "message": "Account balance is 0"}
|
|
172
|
+
{"error": "task_failed", "message": "Task failed: ..."}
|
|
173
|
+
{"error": "timeout", "message": "Task exceeded 20 minute timeout"}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Typical Agent Workflows
|
|
177
|
+
|
|
178
|
+
### 1. Generate an image
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
rh model auto --task text-to-image --prompt "a photorealistic sunset over the ocean" --output sunset.png
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### 2. Generate a video from an image
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
rh model auto --task image-to-video --image portrait.jpg --output animation.mp4
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### 3. Discover and run a custom ComfyUI app
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
# Step 1: find apps
|
|
194
|
+
rh app list --search "anime portrait" --size 5
|
|
195
|
+
|
|
196
|
+
# Step 2: check the app's inputs
|
|
197
|
+
rh app info <webappId>
|
|
198
|
+
|
|
199
|
+
# Step 3: run it
|
|
200
|
+
rh app run <webappId> --node "6:prompt=anime warrior" --file "10:image=photo.jpg" --output result.png
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### 4. Check balance before running
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
rh account status | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['remainCoins'])"
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Error Handling
|
|
210
|
+
|
|
211
|
+
- All errors produce JSON with an `error` key and exit code 1
|
|
212
|
+
- Progress is written to **stderr** (polling dots); final JSON is on **stdout**
|
|
213
|
+
- Separate stderr from stdout: `rh model auto ... 2>/dev/null`
|
|
214
|
+
|
|
215
|
+
## Notes
|
|
216
|
+
|
|
217
|
+
- Tasks may take 5 seconds to 20 minutes depending on the model
|
|
218
|
+
- Video generation is slower than image generation
|
|
219
|
+
- The `--instance plus` flag (for `rh app run`) uses premium compute
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# RunningHub CLI (`rh`) — Agent Skill
|
|
2
|
+
|
|
3
|
+
## What This Tool Does
|
|
4
|
+
|
|
5
|
+
`rh` is a command-line interface for the [RunningHub AI platform](https://www.runninghub.cn) — a cloud ComfyUI service with 209+ built-in AI model endpoints and support for custom ComfyUI workflow apps.
|
|
6
|
+
|
|
7
|
+
Use `rh` to:
|
|
8
|
+
- Generate images, videos, audio, and 3D models from text/image prompts
|
|
9
|
+
- Browse and run custom ComfyUI AI App workflows
|
|
10
|
+
- Check task status and download outputs
|
|
11
|
+
- Monitor account balance
|
|
12
|
+
|
|
13
|
+
## Setup
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
export RH_API_KEY=your_runninghub_api_key
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Or pass `--api-key KEY` to any command.
|
|
20
|
+
|
|
21
|
+
Get a key at: https://www.runninghub.cn/enterprise-api/sharedApi
|
|
22
|
+
|
|
23
|
+
## Command Reference
|
|
24
|
+
|
|
25
|
+
### Account
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
rh account status
|
|
29
|
+
# → {"remainCoins": "150.0", "currentTaskCounts": "0", "apiType": "coins"}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Built-in Models (`rh model`)
|
|
33
|
+
|
|
34
|
+
For quick AI generation using RunningHub's 209 pre-built models.
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# List available models
|
|
38
|
+
rh model list --type image
|
|
39
|
+
rh model list --task text-to-image --top 5
|
|
40
|
+
rh model list --type video
|
|
41
|
+
|
|
42
|
+
# Get parameter schema for an endpoint
|
|
43
|
+
rh model info rhart-image-n-pro/text-to-image
|
|
44
|
+
|
|
45
|
+
# Auto-select best model for a task (recommended for agents)
|
|
46
|
+
rh model auto --task text-to-image --prompt "a sunset over mountains" --output out.png
|
|
47
|
+
rh model auto --task image-to-video --image input.jpg --output out.mp4
|
|
48
|
+
rh model auto --task text-to-speech --prompt "Hello world" --output out.mp3
|
|
49
|
+
rh model auto --task text-to-3d --prompt "a ceramic teapot" --output model.glb
|
|
50
|
+
|
|
51
|
+
# Run a specific endpoint
|
|
52
|
+
rh model run rhart-image-n-pro/text-to-image --prompt "anime cat" --output cat.png
|
|
53
|
+
rh model run kling-video-o3-pro/image-to-video --image photo.jpg --output video.mp4
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Available task types:**
|
|
57
|
+
- `text-to-image`, `image-to-image`, `image-upscale`
|
|
58
|
+
- `text-to-video`, `image-to-video`, `reference-to-video`, `start-end-to-video`
|
|
59
|
+
- `text-to-speech`, `music-generation`, `voice-clone`
|
|
60
|
+
- `text-to-3d`, `image-to-3d`, `multi-image-to-3d`
|
|
61
|
+
|
|
62
|
+
### Custom AI Apps (`rh app`)
|
|
63
|
+
|
|
64
|
+
For custom ComfyUI workflows. Each app has a `webappId` and modifiable input nodes.
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Browse public apps
|
|
68
|
+
rh app list --search "anime portrait" --sort RECOMMEND
|
|
69
|
+
rh app list --sort HOTTEST --size 10
|
|
70
|
+
|
|
71
|
+
# Inspect an app's input schema before running
|
|
72
|
+
rh app info 1234567890
|
|
73
|
+
# → {"webappId": "...", "name": "...", "nodes": [{"nodeId": "6", "fieldName": "prompt", "fieldType": "STRING", ...}]}
|
|
74
|
+
|
|
75
|
+
# Run an app
|
|
76
|
+
rh app run 1234567890 \
|
|
77
|
+
--node "6:prompt=a samurai cat warrior" \
|
|
78
|
+
--output result.mp4
|
|
79
|
+
|
|
80
|
+
# Run with a file input
|
|
81
|
+
rh app run 1234567890 \
|
|
82
|
+
--node "6:prompt=enhance this portrait" \
|
|
83
|
+
--file "10:image=/path/to/photo.jpg" \
|
|
84
|
+
--output enhanced.png
|
|
85
|
+
|
|
86
|
+
# Batch run from CSV
|
|
87
|
+
rh app batch 1234567890 --input params.csv --concurrency 3 --output-dir ./results/
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Batch CSV format:**
|
|
91
|
+
```csv
|
|
92
|
+
6:prompt,10:image
|
|
93
|
+
"a ninja dog",/path/to/dog.jpg
|
|
94
|
+
"a robot cat",/path/to/cat.jpg
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Task Management
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# Check status of a task
|
|
101
|
+
rh task status abc123
|
|
102
|
+
|
|
103
|
+
# Get outputs for a completed task
|
|
104
|
+
rh task outputs abc123 --output result.png
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## JSON Output Schema
|
|
108
|
+
|
|
109
|
+
All commands output JSON. Agents should parse stdout directly.
|
|
110
|
+
|
|
111
|
+
**`rh model auto` / `rh model run` success:**
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"taskId": "abc123",
|
|
115
|
+
"status": "SUCCESS",
|
|
116
|
+
"outputs": [{"fileUrl": "https://cdn.runninghub.cn/...", "fileType": "image/png"}],
|
|
117
|
+
"cost": {"duration_s": 8},
|
|
118
|
+
"savedTo": "/path/to/out.png",
|
|
119
|
+
"selectedEndpoint": "rhart-image-n-pro/text-to-image"
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**`rh app run` success:**
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"taskId": "xyz789",
|
|
127
|
+
"status": "SUCCESS",
|
|
128
|
+
"outputs": [{"fileUrl": "https://...", "fileType": "video/mp4"}],
|
|
129
|
+
"savedTo": "/path/to/result.mp4"
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Errors (exit code 1):**
|
|
134
|
+
```json
|
|
135
|
+
{"error": "auth_failed", "message": "Invalid API key or unauthorized"}
|
|
136
|
+
{"error": "insufficient_balance", "message": "Account balance is 0"}
|
|
137
|
+
{"error": "task_failed", "message": "Task failed: ..."}
|
|
138
|
+
{"error": "timeout", "message": "Task exceeded 20 minute timeout"}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Typical Agent Workflows
|
|
142
|
+
|
|
143
|
+
### 1. Generate an image
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
rh model auto --task text-to-image --prompt "a photorealistic sunset over the ocean" --output sunset.png
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### 2. Generate a video from an image
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
rh model auto --task image-to-video --image portrait.jpg --output animation.mp4
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### 3. Discover and run a custom ComfyUI app
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
# Step 1: find apps
|
|
159
|
+
rh app list --search "anime portrait" --size 5
|
|
160
|
+
|
|
161
|
+
# Step 2: check the app's inputs
|
|
162
|
+
rh app info <webappId>
|
|
163
|
+
|
|
164
|
+
# Step 3: run it
|
|
165
|
+
rh app run <webappId> --node "6:prompt=anime warrior" --file "10:image=photo.jpg" --output result.png
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### 4. Check balance before running
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
rh account status | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['remainCoins'])"
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Error Handling
|
|
175
|
+
|
|
176
|
+
- All errors produce JSON with an `error` key and exit code 1
|
|
177
|
+
- Progress is written to **stderr** (polling dots); final JSON is on **stdout**
|
|
178
|
+
- Separate stderr from stdout: `rh model auto ... 2>/dev/null`
|
|
179
|
+
|
|
180
|
+
## Notes
|
|
181
|
+
|
|
182
|
+
- Tasks may take 5 seconds to 20 minutes depending on the model
|
|
183
|
+
- Video generation is slower than image generation
|
|
184
|
+
- The `--instance plus` flag (for `rh app run`) uses premium compute
|