cydeai-client 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.
- cydeai_client-0.1.0/MANIFEST.in +8 -0
- cydeai_client-0.1.0/PKG-INFO +491 -0
- cydeai_client-0.1.0/README.md +464 -0
- cydeai_client-0.1.0/TEST_MATRIX.md +67 -0
- cydeai_client-0.1.0/docs/design_docs/client-integration.md +368 -0
- cydeai_client-0.1.0/docs/design_docs/multiplex-protocol.md +219 -0
- cydeai_client-0.1.0/docs/design_docs/server-endpoint.md +34 -0
- cydeai_client-0.1.0/docs/gateway-test-report.md +1090 -0
- cydeai_client-0.1.0/docs/how_to_run_manually.md +309 -0
- cydeai_client-0.1.0/docs/implementation-report.md +217 -0
- cydeai_client-0.1.0/docs/pypi_release.md +141 -0
- cydeai_client-0.1.0/examples/config.toml +27 -0
- cydeai_client-0.1.0/pyproject.toml +47 -0
- cydeai_client-0.1.0/setup.cfg +4 -0
- cydeai_client-0.1.0/src/cydeai/__init__.py +2 -0
- cydeai_client-0.1.0/src/cydeai/checks.py +113 -0
- cydeai_client-0.1.0/src/cydeai/cli.py +536 -0
- cydeai_client-0.1.0/src/cydeai/client.py +204 -0
- cydeai_client-0.1.0/src/cydeai/config.py +178 -0
- cydeai_client-0.1.0/src/cydeai/hardware.py +256 -0
- cydeai_client-0.1.0/src/cydeai/models.py +151 -0
- cydeai_client-0.1.0/src/cydeai/processes.py +63 -0
- cydeai_client-0.1.0/src/cydeai/protocol.py +152 -0
- cydeai_client-0.1.0/src/cydeai/streams.py +270 -0
- cydeai_client-0.1.0/src/cydeai/tunnel.py +591 -0
- cydeai_client-0.1.0/src/cydeai/validation.py +84 -0
- cydeai_client-0.1.0/src/cydeai/vllm_proxy.py +74 -0
- cydeai_client-0.1.0/src/cydeai/worker_identity.py +35 -0
- cydeai_client-0.1.0/src/cydeai_client.egg-info/PKG-INFO +491 -0
- cydeai_client-0.1.0/src/cydeai_client.egg-info/SOURCES.txt +44 -0
- cydeai_client-0.1.0/src/cydeai_client.egg-info/dependency_links.txt +1 -0
- cydeai_client-0.1.0/src/cydeai_client.egg-info/entry_points.txt +2 -0
- cydeai_client-0.1.0/src/cydeai_client.egg-info/requires.txt +6 -0
- cydeai_client-0.1.0/src/cydeai_client.egg-info/top_level.txt +1 -0
- cydeai_client-0.1.0/tests/test_checks.py +140 -0
- cydeai_client-0.1.0/tests/test_cli.py +529 -0
- cydeai_client-0.1.0/tests/test_client.py +150 -0
- cydeai_client-0.1.0/tests/test_config.py +141 -0
- cydeai_client-0.1.0/tests/test_hardware.py +109 -0
- cydeai_client-0.1.0/tests/test_hardware_checks.py +178 -0
- cydeai_client-0.1.0/tests/test_packaging.py +33 -0
- cydeai_client-0.1.0/tests/test_protocol.py +75 -0
- cydeai_client-0.1.0/tests/test_streams.py +176 -0
- cydeai_client-0.1.0/tests/test_tunnel.py +539 -0
- cydeai_client-0.1.0/tests/test_vllm_proxy.py +103 -0
- cydeai_client-0.1.0/tests/test_worker_identity.py +25 -0
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cydeai-client
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: CLI client for Cysic decentralized AI providers
|
|
5
|
+
Author: Cysic
|
|
6
|
+
License-Expression: LicenseRef-Proprietary
|
|
7
|
+
Project-URL: Homepage, https://github.com/cysic-labs/cydeai-client
|
|
8
|
+
Project-URL: Documentation, https://github.com/cysic-labs/cydeai-client#readme
|
|
9
|
+
Project-URL: Issues, https://github.com/cysic-labs/cydeai-client/issues
|
|
10
|
+
Keywords: cysic,cydeai,vllm,gpu,cli
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: System :: Hardware
|
|
19
|
+
Classifier: Topic :: Utilities
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
Requires-Dist: websockets>=12
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
25
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
26
|
+
Requires-Dist: twine>=5; extra == "dev"
|
|
27
|
+
|
|
28
|
+
# cydeai
|
|
29
|
+
|
|
30
|
+
`cydeai` is the CLI client for Cysic decentralized AI providers. It is intended to run on provider GPU machines, collect hardware details, verify that vLLM is running on NVIDIA GPU memory, then connect the worker to `cydeai-server`.
|
|
31
|
+
|
|
32
|
+
The MVP is intentionally narrow: it does not start vLLM, install models, configure tunnels, interact with chain contracts, or manage system services.
|
|
33
|
+
|
|
34
|
+
The formal worker flow is `cydeai connect`: run local readiness checks, open the WebSocket worker tunnel, send the `register` control message on `stream_id=0`, then proxy inference streams to the local vLLM endpoint. The older `cydeai register` command is kept only as a legacy REST/compatibility path.
|
|
35
|
+
|
|
36
|
+
## Requirements
|
|
37
|
+
|
|
38
|
+
- Python 3.11 or newer.
|
|
39
|
+
- `nvidia-smi` on Linux GPU provider machines.
|
|
40
|
+
- A running vLLM process serving the configured model.
|
|
41
|
+
- A server-issued `api_key` for the provider.
|
|
42
|
+
- Network access to the configured `cydeai-server` inference router.
|
|
43
|
+
|
|
44
|
+
Development and unit tests must also work on macOS without NVIDIA GPU, `nvidia-smi`, vLLM, or a real server.
|
|
45
|
+
|
|
46
|
+
## Install
|
|
47
|
+
|
|
48
|
+
From a local checkout:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
python -m pip install -e ".[dev]"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
After installation, the CLI command should be available as:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
cydeai --help
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Build A Wheel
|
|
61
|
+
|
|
62
|
+
Install build tooling:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
python -m pip install -e ".[dev]"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Build wheel and source distribution:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
rm -rf dist build src/cydeai.egg-info
|
|
72
|
+
python -m build
|
|
73
|
+
python -m twine check dist/*
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Clean-install the wheel in a temporary environment:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
python -m venv /tmp/cydeai-wheel-test
|
|
80
|
+
. /tmp/cydeai-wheel-test/bin/activate
|
|
81
|
+
python -m pip install -U pip
|
|
82
|
+
python -m pip install dist/cydeai_client-*.whl
|
|
83
|
+
cydeai --help
|
|
84
|
+
cydeai check --json
|
|
85
|
+
deactivate
|
|
86
|
+
rm -rf /tmp/cydeai-wheel-test
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
On macOS, `cydeai check --json` may report a controlled failure because
|
|
90
|
+
`nvidia-smi` is unavailable. That is acceptable for packaging smoke tests.
|
|
91
|
+
|
|
92
|
+
See `docs/pypi_release.md` for the full TestPyPI/PyPI release process.
|
|
93
|
+
|
|
94
|
+
## Configuration
|
|
95
|
+
|
|
96
|
+
Configuration values are merged in this order:
|
|
97
|
+
|
|
98
|
+
```text
|
|
99
|
+
CLI args > environment variables > config file > defaults
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The default config path is:
|
|
103
|
+
|
|
104
|
+
```text
|
|
105
|
+
~/.config/cydeai/config.toml
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
An example file is provided at `examples/config.toml`.
|
|
109
|
+
|
|
110
|
+
Common options:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
--server-url
|
|
114
|
+
--provider-id
|
|
115
|
+
--address
|
|
116
|
+
--api-key
|
|
117
|
+
--worker-name
|
|
118
|
+
--model-name
|
|
119
|
+
--model-port
|
|
120
|
+
--router-url
|
|
121
|
+
--model-endpoint
|
|
122
|
+
--max-num-seqs
|
|
123
|
+
--initial-window-bytes
|
|
124
|
+
--config
|
|
125
|
+
--json
|
|
126
|
+
--dry-run
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
`cydeai connect` uses these values to build the WebSocket handshake and register control message. `cydeai register` uses the same compatibility options for the legacy REST payload.
|
|
130
|
+
|
|
131
|
+
Environment variable names should mirror the option names with a `CYDEAI_` prefix, for example:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
export CYDEAI_SERVER_URL="http://127.0.0.1:8000"
|
|
135
|
+
export CYDEAI_API_KEY="provider-api-key"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
For the WebSocket worker protocol, `api_key` is required. It is sent as the `PROVIDER_SIGN` handshake header. `address` is optional and, when provided, is sent as the `PROVIDER_ADDRESS` handshake header.
|
|
139
|
+
|
|
140
|
+
`provider_id` is not part of the current server WebSocket protocol. If kept in local config, it is only a local compatibility or display field and should not be treated as the formal server identity.
|
|
141
|
+
|
|
142
|
+
`worker_id` is generated automatically from the local machine hardware MAC
|
|
143
|
+
address. The client sends the normalized MAC-based id with this shape:
|
|
144
|
+
|
|
145
|
+
```text
|
|
146
|
+
w-<12 lowercase hex characters>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Users should not configure `worker_id`. Existing `worker_id` values in config
|
|
150
|
+
files or `CYDEAI_WORKER_ID` are ignored.
|
|
151
|
+
|
|
152
|
+
The ID is `w-` plus `normalized_mac`, where `normalized_mac` is the 48-bit MAC
|
|
153
|
+
address rendered as 12 lowercase hex characters without separators.
|
|
154
|
+
|
|
155
|
+
`model_name` is sent to the server in the register control message for scheduling. The client should only require it to be a non-empty string. It should not enforce a hardcoded local model allowlist, because the server is responsible for deciding whether a submitted model name is accepted or schedulable.
|
|
156
|
+
|
|
157
|
+
## Commands
|
|
158
|
+
|
|
159
|
+
### `cydeai info`
|
|
160
|
+
|
|
161
|
+
Prints detected hardware information:
|
|
162
|
+
|
|
163
|
+
- CPU model
|
|
164
|
+
- total memory
|
|
165
|
+
- GPU model and count
|
|
166
|
+
|
|
167
|
+
Example:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
cydeai info --json
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### `cydeai check`
|
|
174
|
+
|
|
175
|
+
Runs local readiness checks for the worker. This command only inspects the
|
|
176
|
+
local machine; it does not connect to the server.
|
|
177
|
+
|
|
178
|
+
It collects:
|
|
179
|
+
|
|
180
|
+
- CPU model.
|
|
181
|
+
- Total system memory.
|
|
182
|
+
- NVIDIA GPU model and count.
|
|
183
|
+
- Per-GPU memory total, used memory, and memory usage percentage.
|
|
184
|
+
- vLLM-related local processes.
|
|
185
|
+
- GPU process ownership from `nvidia-smi`.
|
|
186
|
+
|
|
187
|
+
The check passes only when all of the following are true:
|
|
188
|
+
|
|
189
|
+
- At least one NVIDIA GPU is detected.
|
|
190
|
+
- At least one GPU has memory usage greater than 10%.
|
|
191
|
+
- At least one vLLM process exists.
|
|
192
|
+
- At least one vLLM PID appears in the GPU process list returned by `nvidia-smi`.
|
|
193
|
+
|
|
194
|
+
If `nvidia-smi` is missing, vLLM is missing, GPU memory usage is too low, or the vLLM PID is not using GPU memory, the command must fail cleanly with a clear reason. It should not crash.
|
|
195
|
+
|
|
196
|
+
Example:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
cydeai check --json
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
On macOS development machines without NVIDIA GPU, this command is expected to report a controlled failure in structured JSON.
|
|
203
|
+
|
|
204
|
+
Successful output includes:
|
|
205
|
+
|
|
206
|
+
```json
|
|
207
|
+
{
|
|
208
|
+
"passed": true,
|
|
209
|
+
"reason": "vLLM is running and using NVIDIA GPU memory"
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Failure output includes a structured reason, for example:
|
|
214
|
+
|
|
215
|
+
```json
|
|
216
|
+
{
|
|
217
|
+
"passed": false,
|
|
218
|
+
"reason": "nvidia-smi is not available"
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
The purpose of this command is to gate `cydeai connect`: before the client joins
|
|
223
|
+
the network, it verifies that the machine is a real GPU/vLLM worker and that
|
|
224
|
+
vLLM is actually using NVIDIA GPU memory.
|
|
225
|
+
|
|
226
|
+
### `cydeai connect`
|
|
227
|
+
|
|
228
|
+
Official worker flow. `cydeai connect` first runs the same readiness checks as `cydeai check`. If GPU/vLLM validation fails, it prints a structured local failure and does not connect to the server.
|
|
229
|
+
|
|
230
|
+
After readiness passes, it establishes a WebSocket connection to:
|
|
231
|
+
|
|
232
|
+
```text
|
|
233
|
+
GET ws://<router-host>:8080/v1/provider/connect
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
The WebSocket handshake uses:
|
|
237
|
+
|
|
238
|
+
- `PROVIDER_SIGN`: required `api_key`
|
|
239
|
+
- `PROVIDER_ADDRESS`: optional `address`
|
|
240
|
+
|
|
241
|
+
Then it sends a `CONTROL` frame on `stream_id=0` with a `register` message:
|
|
242
|
+
|
|
243
|
+
```json
|
|
244
|
+
{
|
|
245
|
+
"type": "register",
|
|
246
|
+
"ts": 1716700000,
|
|
247
|
+
"payload": {
|
|
248
|
+
"worker_id": "w-aabbccddeeff",
|
|
249
|
+
"worker_name": "gpu-node-01",
|
|
250
|
+
"model_name": "llama-3.1-8b",
|
|
251
|
+
"max_num_seqs": 32,
|
|
252
|
+
"model_endpoint": "http://127.0.0.1:8000/v1"
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
The local hardware summary and check result are used as a client-side gate. They are not part of the documented WebSocket register payload unless the server protocol is extended later.
|
|
258
|
+
|
|
259
|
+
Normal output must not print the raw `api_key`; it should be masked.
|
|
260
|
+
|
|
261
|
+
Example:
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
cydeai connect \
|
|
265
|
+
--server-url ws://127.0.0.1:8080/v1/provider/connect \
|
|
266
|
+
--api-key provider-api-key \
|
|
267
|
+
--worker-name gpu-node-01 \
|
|
268
|
+
--model-name llama-3.1-8b \
|
|
269
|
+
--model-port 8000 \
|
|
270
|
+
--json
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### `cydeai register` legacy REST compatibility
|
|
274
|
+
|
|
275
|
+
`cydeai register` is not the formal worker connection path. It is retained for legacy REST compatibility and sends a payload to:
|
|
276
|
+
|
|
277
|
+
```text
|
|
278
|
+
POST {server_url}/api/v1/workers/register
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Legacy required fields:
|
|
282
|
+
|
|
283
|
+
- one of `provider_id`, `address`, or `api_key`
|
|
284
|
+
- automatically generated `worker_id`
|
|
285
|
+
- `worker_name`
|
|
286
|
+
- `model_name`
|
|
287
|
+
- `model_port`
|
|
288
|
+
- hardware summary
|
|
289
|
+
- check result
|
|
290
|
+
|
|
291
|
+
Dry run prints the legacy REST payload without sending an HTTP request:
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
cydeai register \
|
|
295
|
+
--dry-run \
|
|
296
|
+
--server-url http://127.0.0.1:8000 \
|
|
297
|
+
--api-key provider-api-key \
|
|
298
|
+
--worker-name gpu-node-01 \
|
|
299
|
+
--model-name llama-3.1-8b \
|
|
300
|
+
--model-port 8000 \
|
|
301
|
+
--json
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## Local Verification
|
|
305
|
+
|
|
306
|
+
Run these commands before claiming the client is complete:
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
python -m pip install -e ".[dev]"
|
|
310
|
+
pytest -q
|
|
311
|
+
cydeai --help
|
|
312
|
+
cydeai check --json
|
|
313
|
+
cydeai connect --dry-run --server-url ws://127.0.0.1:8080 --api-key test-secret --worker-name gpu-node-01 --model-name new-server-model --model-port 8000 --json
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
`cydeai check --json` may fail on macOS because there is no NVIDIA GPU, but it must fail cleanly with structured output.
|
|
317
|
+
|
|
318
|
+
## Start Client On A Linux GPU Machine
|
|
319
|
+
|
|
320
|
+
Use this flow on a provider GPU machine after vLLM is already running. The
|
|
321
|
+
client does not start vLLM, install models, or configure system services.
|
|
322
|
+
|
|
323
|
+
Enter the remote project directory and activate the virtual environment:
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
ssh shanxiTitan57
|
|
327
|
+
cd ~/cydeai-client-test
|
|
328
|
+
. .venv/bin/activate
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
If the `cydeai` command is not installed in the environment:
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
python -m pip install -e ".[dev]"
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
Verify the local GPU/vLLM gate before connecting to the server:
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
cydeai check --json
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
The command should return `"passed": true`. If it fails, fix the local GPU,
|
|
344
|
+
`nvidia-smi`, or vLLM state before starting the worker connection.
|
|
345
|
+
|
|
346
|
+
Set the server-issued worker API key. Avoid writing raw keys into files or
|
|
347
|
+
shell history when possible:
|
|
348
|
+
|
|
349
|
+
```bash
|
|
350
|
+
read -s WORKER_API_KEY
|
|
351
|
+
export WORKER_API_KEY
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
Start the client in the foreground:
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
PYTHONUNBUFFERED=1 cydeai connect \
|
|
358
|
+
--server-url https://api-testnet.prover.xyz/cysicdai \
|
|
359
|
+
--api-key "$WORKER_API_KEY" \
|
|
360
|
+
--address 0xtest0000000000000000000000000000000000 \
|
|
361
|
+
--worker-name gpu-node-01 \
|
|
362
|
+
--model-name qwen3-coder \
|
|
363
|
+
--model-port 8000 \
|
|
364
|
+
--json
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
Successful startup prints structured events similar to:
|
|
368
|
+
|
|
369
|
+
```json
|
|
370
|
+
{"attempt": 1, "connect_url": "wss://api-testnet.prover.xyz/cysicdai/v1/provider/connect", "event": "connect_attempt"}
|
|
371
|
+
{"attempt": 1, "event": "registered", "result": {"registered": true, "status": "available"}, "worker_id": "w-aabbccddeeff"}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
Use the `worker_id` from the `registered` event in the gateway path for manual
|
|
375
|
+
testing.
|
|
376
|
+
|
|
377
|
+
After registration, the client keeps the WebSocket open, sends application-level
|
|
378
|
+
CONTROL heartbeat every 30 seconds by default, proxies gateway streams to local
|
|
379
|
+
vLLM, and reconnects after reconnectable disconnects.
|
|
380
|
+
|
|
381
|
+
For temporary background testing, use `nohup`:
|
|
382
|
+
|
|
383
|
+
```bash
|
|
384
|
+
nohup env PYTHONUNBUFFERED=1 cydeai connect \
|
|
385
|
+
--server-url https://api-testnet.prover.xyz/cysicdai \
|
|
386
|
+
--api-key "$WORKER_API_KEY" \
|
|
387
|
+
--address 0xtest0000000000000000000000000000000000 \
|
|
388
|
+
--worker-name gpu-node-01 \
|
|
389
|
+
--model-name qwen3-coder \
|
|
390
|
+
--model-port 8000 \
|
|
391
|
+
--json > cydeai-worker.log 2>&1 &
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
Inspect and stop the temporary background process:
|
|
395
|
+
|
|
396
|
+
```bash
|
|
397
|
+
tail -f cydeai-worker.log
|
|
398
|
+
pgrep -af "cydeai connect"
|
|
399
|
+
pkill -f "cydeai connect"
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
This is only a temporary run method. A production deployment should use a
|
|
403
|
+
dedicated service manager configuration, such as a systemd unit, once that is
|
|
404
|
+
designed and approved.
|
|
405
|
+
|
|
406
|
+
## Remote Linux Verification
|
|
407
|
+
|
|
408
|
+
Use the Linux GPU machine only for integration testing. Do not make destructive changes, stop services, install system packages, or modify system configuration without explicit approval.
|
|
409
|
+
|
|
410
|
+
Prepared remote verification commands. Do not run these until remote validation is explicitly requested.
|
|
411
|
+
|
|
412
|
+
First verify the remote environment:
|
|
413
|
+
|
|
414
|
+
```bash
|
|
415
|
+
ssh shanxiTitan52 'python3 --version && command -v nvidia-smi && nvidia-smi'
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
Sync the checkout to a temporary remote directory with tar over SSH. This is preferred over `rsync` so macOS metadata can be disabled consistently:
|
|
419
|
+
|
|
420
|
+
```bash
|
|
421
|
+
ssh shanxiTitan52 'rm -rf ~/cydeai-client-test && mkdir -p ~/cydeai-client-test'
|
|
422
|
+
COPYFILE_DISABLE=1 tar \
|
|
423
|
+
--exclude .DS_Store \
|
|
424
|
+
--exclude '._*' \
|
|
425
|
+
--exclude .git \
|
|
426
|
+
--exclude .venv \
|
|
427
|
+
--exclude __pycache__ \
|
|
428
|
+
--exclude .pytest_cache \
|
|
429
|
+
--exclude '*.egg-info' \
|
|
430
|
+
-cf - . | ssh shanxiTitan52 'cd ~/cydeai-client-test && tar -xf -'
|
|
431
|
+
ssh shanxiTitan52 'cd ~/cydeai-client-test && find . \( -name ".DS_Store" -o -name "._*" \) -delete'
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
Run tests and CLI smoke checks remotely:
|
|
435
|
+
|
|
436
|
+
```bash
|
|
437
|
+
ssh shanxiTitan52 'cd ~/cydeai-client-test && python3 -m venv .venv && . .venv/bin/activate && python -m pip install -U pip && python -m pip install -e ".[dev]" && pytest'
|
|
438
|
+
ssh shanxiTitan52 'cd ~/cydeai-client-test && . .venv/bin/activate && cydeai --help'
|
|
439
|
+
ssh shanxiTitan52 'cd ~/cydeai-client-test && . .venv/bin/activate && cydeai check --json'
|
|
440
|
+
ssh shanxiTitan52 'cd ~/cydeai-client-test && . .venv/bin/activate && cydeai connect --dry-run --server-url ws://127.0.0.1:8080 --api-key test-secret --worker-name gpu-node-01 --model-name new-server-model --model-port 8000 --json'
|
|
441
|
+
ssh shanxiTitan52 'cd ~/cydeai-client-test && . .venv/bin/activate && cydeai register --dry-run --server-url http://127.0.0.1:8000 --provider-id provider123 --worker-name gpu-node-01 --model-name llama-3.1-8b --model-port 8000 --json'
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
## Development Notes
|
|
445
|
+
|
|
446
|
+
Keep system calls injectable or mockable. Do not execute system commands at import time.
|
|
447
|
+
|
|
448
|
+
Expected package layout:
|
|
449
|
+
|
|
450
|
+
```text
|
|
451
|
+
src/cydeai/
|
|
452
|
+
__init__.py
|
|
453
|
+
cli.py
|
|
454
|
+
config.py
|
|
455
|
+
hardware.py
|
|
456
|
+
checks.py
|
|
457
|
+
processes.py
|
|
458
|
+
models.py
|
|
459
|
+
validation.py
|
|
460
|
+
client.py
|
|
461
|
+
protocol.py
|
|
462
|
+
tunnel.py
|
|
463
|
+
streams.py
|
|
464
|
+
vllm_proxy.py
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
The `protocol.py`, `tunnel.py`, `streams.py`, and `vllm_proxy.py` modules are expected for the WebSocket worker protocol implementation:
|
|
468
|
+
|
|
469
|
+
- `protocol.py`: binary frame encode/decode and control message helpers.
|
|
470
|
+
- `tunnel.py`: WebSocket connection, handshake headers, register control message, read loop, and reconnect decisions.
|
|
471
|
+
- `streams.py`: stream lifecycle, per-stream window accounting, and frame dispatch.
|
|
472
|
+
- `vllm_proxy.py`: byte-level bridge between server streams and the local vLLM endpoint.
|
|
473
|
+
|
|
474
|
+
Recommended test coverage:
|
|
475
|
+
|
|
476
|
+
- config precedence
|
|
477
|
+
- GPU info parsing
|
|
478
|
+
- memory usage greater than 10% passes
|
|
479
|
+
- memory usage less than or equal to 10% fails
|
|
480
|
+
- missing `nvidia-smi` fails cleanly
|
|
481
|
+
- missing vLLM fails cleanly
|
|
482
|
+
- vLLM PID not in GPU process list fails
|
|
483
|
+
- valid and invalid worker IDs
|
|
484
|
+
- API key/address identity handling
|
|
485
|
+
- dry-run payload construction
|
|
486
|
+
- CLI help
|
|
487
|
+
- protocol frame encode/decode
|
|
488
|
+
- register control message construction
|
|
489
|
+
- WebSocket handshake headers mask raw API keys in output
|
|
490
|
+
- local check failure prevents server connection
|
|
491
|
+
- model name is required but not locally allowlisted
|