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.
Files changed (46) hide show
  1. cydeai_client-0.1.0/MANIFEST.in +8 -0
  2. cydeai_client-0.1.0/PKG-INFO +491 -0
  3. cydeai_client-0.1.0/README.md +464 -0
  4. cydeai_client-0.1.0/TEST_MATRIX.md +67 -0
  5. cydeai_client-0.1.0/docs/design_docs/client-integration.md +368 -0
  6. cydeai_client-0.1.0/docs/design_docs/multiplex-protocol.md +219 -0
  7. cydeai_client-0.1.0/docs/design_docs/server-endpoint.md +34 -0
  8. cydeai_client-0.1.0/docs/gateway-test-report.md +1090 -0
  9. cydeai_client-0.1.0/docs/how_to_run_manually.md +309 -0
  10. cydeai_client-0.1.0/docs/implementation-report.md +217 -0
  11. cydeai_client-0.1.0/docs/pypi_release.md +141 -0
  12. cydeai_client-0.1.0/examples/config.toml +27 -0
  13. cydeai_client-0.1.0/pyproject.toml +47 -0
  14. cydeai_client-0.1.0/setup.cfg +4 -0
  15. cydeai_client-0.1.0/src/cydeai/__init__.py +2 -0
  16. cydeai_client-0.1.0/src/cydeai/checks.py +113 -0
  17. cydeai_client-0.1.0/src/cydeai/cli.py +536 -0
  18. cydeai_client-0.1.0/src/cydeai/client.py +204 -0
  19. cydeai_client-0.1.0/src/cydeai/config.py +178 -0
  20. cydeai_client-0.1.0/src/cydeai/hardware.py +256 -0
  21. cydeai_client-0.1.0/src/cydeai/models.py +151 -0
  22. cydeai_client-0.1.0/src/cydeai/processes.py +63 -0
  23. cydeai_client-0.1.0/src/cydeai/protocol.py +152 -0
  24. cydeai_client-0.1.0/src/cydeai/streams.py +270 -0
  25. cydeai_client-0.1.0/src/cydeai/tunnel.py +591 -0
  26. cydeai_client-0.1.0/src/cydeai/validation.py +84 -0
  27. cydeai_client-0.1.0/src/cydeai/vllm_proxy.py +74 -0
  28. cydeai_client-0.1.0/src/cydeai/worker_identity.py +35 -0
  29. cydeai_client-0.1.0/src/cydeai_client.egg-info/PKG-INFO +491 -0
  30. cydeai_client-0.1.0/src/cydeai_client.egg-info/SOURCES.txt +44 -0
  31. cydeai_client-0.1.0/src/cydeai_client.egg-info/dependency_links.txt +1 -0
  32. cydeai_client-0.1.0/src/cydeai_client.egg-info/entry_points.txt +2 -0
  33. cydeai_client-0.1.0/src/cydeai_client.egg-info/requires.txt +6 -0
  34. cydeai_client-0.1.0/src/cydeai_client.egg-info/top_level.txt +1 -0
  35. cydeai_client-0.1.0/tests/test_checks.py +140 -0
  36. cydeai_client-0.1.0/tests/test_cli.py +529 -0
  37. cydeai_client-0.1.0/tests/test_client.py +150 -0
  38. cydeai_client-0.1.0/tests/test_config.py +141 -0
  39. cydeai_client-0.1.0/tests/test_hardware.py +109 -0
  40. cydeai_client-0.1.0/tests/test_hardware_checks.py +178 -0
  41. cydeai_client-0.1.0/tests/test_packaging.py +33 -0
  42. cydeai_client-0.1.0/tests/test_protocol.py +75 -0
  43. cydeai_client-0.1.0/tests/test_streams.py +176 -0
  44. cydeai_client-0.1.0/tests/test_tunnel.py +539 -0
  45. cydeai_client-0.1.0/tests/test_vllm_proxy.py +103 -0
  46. cydeai_client-0.1.0/tests/test_worker_identity.py +25 -0
@@ -0,0 +1,8 @@
1
+ include README.md
2
+ include pyproject.toml
3
+ include TEST_MATRIX.md
4
+ include examples/*.toml
5
+ recursive-include docs *.md
6
+ recursive-exclude docs/codex_prompts *
7
+ global-exclude .DS_Store
8
+ global-exclude ._*
@@ -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