cev-py 0.2.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.
- cev_py-0.2.0/.github/workflows/ci.yml +36 -0
- cev_py-0.2.0/.github/workflows/publish.yml +98 -0
- cev_py-0.2.0/.gitignore +10 -0
- cev_py-0.2.0/AGENTS.md +75 -0
- cev_py-0.2.0/CHANGELOG.md +46 -0
- cev_py-0.2.0/CLAUDE.md +1 -0
- cev_py-0.2.0/Cargo.lock +3064 -0
- cev_py-0.2.0/Cargo.toml +47 -0
- cev_py-0.2.0/LICENSE +176 -0
- cev_py-0.2.0/PKG-INFO +379 -0
- cev_py-0.2.0/README.md +358 -0
- cev_py-0.2.0/pyproject.toml +38 -0
- cev_py-0.2.0/python/cev/__init__.py +408 -0
- cev_py-0.2.0/python/cev/_native.pyi +17 -0
- cev_py-0.2.0/python/cev/_types.py +293 -0
- cev_py-0.2.0/python/cev/py.typed +0 -0
- cev_py-0.2.0/scripts/bench.py +89 -0
- cev_py-0.2.0/src/lib.rs +336 -0
- cev_py-0.2.0/tests/test_cev.py +243 -0
- cev_py-0.2.0/uv.lock +104 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
test:
|
|
13
|
+
strategy:
|
|
14
|
+
fail-fast: false
|
|
15
|
+
matrix:
|
|
16
|
+
os: [macos-latest, ubuntu-latest]
|
|
17
|
+
python: ['3.11', '3.13']
|
|
18
|
+
runs-on: ${{ matrix.os }}
|
|
19
|
+
name: Python ${{ matrix.python }} on ${{ matrix.os }}
|
|
20
|
+
steps:
|
|
21
|
+
# The engine comes from crates.io (pinned in Cargo.lock).
|
|
22
|
+
- uses: actions/checkout@v5
|
|
23
|
+
- uses: actions/setup-python@v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: ${{ matrix.python }}
|
|
26
|
+
- run: rustup toolchain install stable --profile minimal && rustup default stable
|
|
27
|
+
- uses: actions/cache@v4
|
|
28
|
+
with:
|
|
29
|
+
path: |
|
|
30
|
+
~/.cargo/registry
|
|
31
|
+
~/.cargo/git
|
|
32
|
+
target
|
|
33
|
+
key: cargo-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('Cargo.lock') }}
|
|
34
|
+
- run: pip install uv
|
|
35
|
+
- run: uv sync --python ${{ matrix.python }}
|
|
36
|
+
- run: uv run pytest
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
# Builds one abi3 wheel per platform (each covers every Python >= 3.11) and an
|
|
4
|
+
# sdist, tests every wheel against the mock backend, then uploads them with
|
|
5
|
+
# Trusted Publishing (OIDC): no PyPI token is stored in this repository. PyPI
|
|
6
|
+
# is configured to trust this repo + workflow ("publish.yml") + environment
|
|
7
|
+
# ("pypi") under the project's Publishing settings. A manual run only builds
|
|
8
|
+
# and tests.
|
|
9
|
+
on:
|
|
10
|
+
release:
|
|
11
|
+
types: [published]
|
|
12
|
+
workflow_dispatch:
|
|
13
|
+
|
|
14
|
+
permissions: {}
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
wheels:
|
|
18
|
+
strategy:
|
|
19
|
+
fail-fast: false
|
|
20
|
+
matrix:
|
|
21
|
+
include:
|
|
22
|
+
- target: macos-arm64
|
|
23
|
+
os: macos-latest
|
|
24
|
+
# manylinux_2_28 (glibc 2.28), so the wheels also load on older
|
|
25
|
+
# distributions than the runner's.
|
|
26
|
+
- target: linux-x86_64
|
|
27
|
+
os: ubuntu-latest
|
|
28
|
+
manylinux: '2_28'
|
|
29
|
+
- target: linux-aarch64
|
|
30
|
+
os: ubuntu-24.04-arm
|
|
31
|
+
manylinux: '2_28'
|
|
32
|
+
runs-on: ${{ matrix.os }}
|
|
33
|
+
name: ${{ matrix.target }}
|
|
34
|
+
permissions:
|
|
35
|
+
contents: read
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v5
|
|
38
|
+
- uses: actions/setup-python@v5
|
|
39
|
+
with:
|
|
40
|
+
python-version: '3.11'
|
|
41
|
+
- uses: PyO3/maturin-action@v1
|
|
42
|
+
with:
|
|
43
|
+
command: build
|
|
44
|
+
args: --release --out dist
|
|
45
|
+
manylinux: ${{ matrix.manylinux || 'auto' }}
|
|
46
|
+
- name: Test the wheel
|
|
47
|
+
run: |
|
|
48
|
+
python -m pip install --upgrade pip pytest
|
|
49
|
+
python -m pip install dist/*.whl
|
|
50
|
+
python -m pytest tests
|
|
51
|
+
- uses: actions/upload-artifact@v4
|
|
52
|
+
with:
|
|
53
|
+
name: wheel-${{ matrix.target }}
|
|
54
|
+
path: dist/*.whl
|
|
55
|
+
if-no-files-found: error
|
|
56
|
+
|
|
57
|
+
sdist:
|
|
58
|
+
runs-on: ubuntu-latest
|
|
59
|
+
permissions:
|
|
60
|
+
contents: read
|
|
61
|
+
steps:
|
|
62
|
+
- uses: actions/checkout@v5
|
|
63
|
+
- uses: PyO3/maturin-action@v1
|
|
64
|
+
with:
|
|
65
|
+
command: sdist
|
|
66
|
+
args: --out dist
|
|
67
|
+
- uses: actions/upload-artifact@v4
|
|
68
|
+
with:
|
|
69
|
+
name: sdist
|
|
70
|
+
path: dist/*.tar.gz
|
|
71
|
+
if-no-files-found: error
|
|
72
|
+
|
|
73
|
+
publish:
|
|
74
|
+
needs: [wheels, sdist]
|
|
75
|
+
if: github.event_name == 'release'
|
|
76
|
+
runs-on: ubuntu-latest
|
|
77
|
+
environment:
|
|
78
|
+
name: pypi
|
|
79
|
+
url: https://pypi.org/project/cev-py/
|
|
80
|
+
permissions:
|
|
81
|
+
id-token: write # mint the OIDC token PyPI exchanges for upload access
|
|
82
|
+
contents: read
|
|
83
|
+
steps:
|
|
84
|
+
- uses: actions/checkout@v5
|
|
85
|
+
- uses: actions/download-artifact@v4
|
|
86
|
+
with:
|
|
87
|
+
path: dist
|
|
88
|
+
merge-multiple: true
|
|
89
|
+
- name: Check the tag and the files
|
|
90
|
+
run: |
|
|
91
|
+
version=$(python3 -c 'import tomllib; print(tomllib.load(open("pyproject.toml", "rb"))["project"]["version"])')
|
|
92
|
+
test "v$version" = "$GITHUB_REF_NAME"
|
|
93
|
+
test -f "dist/cev_py-$version.tar.gz"
|
|
94
|
+
for plat in macosx_11_0_arm64 manylinux_2_28_x86_64 manylinux_2_28_aarch64; do
|
|
95
|
+
ls dist/cev_py-$version-cp311-abi3-*$plat*.whl
|
|
96
|
+
done
|
|
97
|
+
ls -l dist
|
|
98
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
cev_py-0.2.0/.gitignore
ADDED
cev_py-0.2.0/AGENTS.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
Guidance for AI coding agents working in this repository.
|
|
4
|
+
|
|
5
|
+
## What this is
|
|
6
|
+
|
|
7
|
+
A Python binding for [cev](https://github.com/CarterCole/rust-cev). The
|
|
8
|
+
engine, the decision log and the online learner are Rust crates in that
|
|
9
|
+
repository (`cev-core`, `cev-model`, `cev-runtime`) and are published on their
|
|
10
|
+
own. This repository holds only the glue: a PyO3 module and a typed Python
|
|
11
|
+
package. Nothing from the engine is copied here. A change to prompts, model
|
|
12
|
+
code, storage or learning belongs in rust-cev. The Node.js sibling,
|
|
13
|
+
[node-cev](https://github.com/neopunisher/node-cev), has the same shape; keep
|
|
14
|
+
the two APIs in step.
|
|
15
|
+
|
|
16
|
+
## Layout
|
|
17
|
+
|
|
18
|
+
- `src/lib.rs` — the native module `cev._native`: wraps `cev_runtime::Cev`
|
|
19
|
+
behind a class whose methods take and return JSON text, release the GIL, and
|
|
20
|
+
bound forward passes with `concurrency` permits. It also sizes rayon's global
|
|
21
|
+
pool (`threads`).
|
|
22
|
+
- `python/cev/__init__.py` — the public API: `Cev`, `CevError`, `info()`.
|
|
23
|
+
- `python/cev/_types.py` — `TypedDict`s for the wire format (cev's REST bodies).
|
|
24
|
+
- `python/cev/_native.pyi` — stub for the compiled module.
|
|
25
|
+
- `tests/test_cev.py` — pytest, against the mock backend.
|
|
26
|
+
- `scripts/bench.py` — latency and throughput for one configuration.
|
|
27
|
+
- `Cargo.toml` / `pyproject.toml` — the crate and the maturin build.
|
|
28
|
+
|
|
29
|
+
## Commands
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
uv sync # build the module (release) into .venv; the engine comes from crates.io
|
|
33
|
+
uv run pytest # no weights needed
|
|
34
|
+
uv run maturin develop --release # rebuild after changing src/lib.rs
|
|
35
|
+
CEV_TEST_MODEL=Qwen/Qwen3-0.6B uv run pytest # also run the real-model test
|
|
36
|
+
uv run python scripts/bench.py --device cpu --threads 8
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Run `uv run maturin develop --release && uv run pytest` before calling a
|
|
40
|
+
change done.
|
|
41
|
+
|
|
42
|
+
## Rules
|
|
43
|
+
|
|
44
|
+
- No runtime dependencies beyond the standard library.
|
|
45
|
+
- Python >= 3.11; the module is built against the stable ABI (`abi3-py311`).
|
|
46
|
+
- Requests and responses keep cev's wire format so they match the REST API and
|
|
47
|
+
the exported training rows. A new `Cev.load` option needs a field in
|
|
48
|
+
`Options` (`src/lib.rs`), a keyword in `load` (and `mock` if it applies to
|
|
49
|
+
the runtime), a docstring line and a README options-table row.
|
|
50
|
+
- Every native method that runs the model or touches SQLite goes through
|
|
51
|
+
`Cev::run`, which releases the GIL. Forward passes go through `Shared::pass`.
|
|
52
|
+
- Native errors are `RuntimeError("<code>: <message>")`; `__init__.py` turns
|
|
53
|
+
the code into `CevError.code`. Keep the two lists of codes in step.
|
|
54
|
+
- Tests must not need weights or the network: use `Cev.mock()`. Tests that
|
|
55
|
+
need a model are skipped unless `CEV_TEST_MODEL` is set.
|
|
56
|
+
- Benchmark numbers in the README come from `scripts/bench.py` on the machine
|
|
57
|
+
named there. Re-measure rather than extrapolate when changing them.
|
|
58
|
+
- User-visible changes get a `CHANGELOG.md` entry.
|
|
59
|
+
|
|
60
|
+
## Releasing
|
|
61
|
+
|
|
62
|
+
`.github/workflows/publish.yml` builds abi3 wheels (macOS arm64, manylinux_2_28
|
|
63
|
+
x86_64 and aarch64) and an sdist, tests each wheel, and uploads them to PyPI
|
|
64
|
+
as `cev-py` through Trusted Publishing when a GitHub release is published; no
|
|
65
|
+
token is stored. PyPI trusts this repository, workflow `publish.yml` and
|
|
66
|
+
environment `pypi`. To release: raise `version` in `pyproject.toml` and
|
|
67
|
+
`Cargo.toml` (keep them equal), date the `CHANGELOG.md` heading, commit, then
|
|
68
|
+
publish a release tagged `v<version>`; the job fails if the tag and version
|
|
69
|
+
differ. A manual run of the workflow only builds and tests.
|
|
70
|
+
|
|
71
|
+
The cev crates are on crates.io (pinned in `Cargo.lock`; take a new engine
|
|
72
|
+
release with `cargo update -p cev-core -p cev-model -p cev-runtime`, raising
|
|
73
|
+
the requirements in `Cargo.toml` first for a new minor version). To build
|
|
74
|
+
against an engine checkout, see "Building from source" in the README. The PyPI
|
|
75
|
+
names `cev` and `pycev` are taken; this distribution is `cev-py`.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.2.0 (2026-11-08)
|
|
4
|
+
|
|
5
|
+
Takes cev 0.2.1, now from crates.io: building no longer needs a rust-cev
|
|
6
|
+
checkout next to this repository. First version on PyPI, as `cev-py`, with
|
|
7
|
+
wheels for macOS arm64 and Linux x86_64/aarch64.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- `Cev.load(model)` runs the open decision models natively: Bespoke Nimble,
|
|
11
|
+
Kev, d3, d1 and d1-omni, plus Qwen3.5 checkpoints. Short names work
|
|
12
|
+
(`"kev:0.8b"`, `"d1-omni"`, `"nimble-v3"`, ...); the family is detected from
|
|
13
|
+
the repository's files.
|
|
14
|
+
- `images=` and `audio=` on `decide()`, and in `examples()`, as paths, bytes
|
|
15
|
+
or base64, for models that take them.
|
|
16
|
+
- `cev.model["family"]` and `cev.model["modalities"]`.
|
|
17
|
+
- Namespaces: `namespace=` on `decide()` and in `examples()` keeps feedback and
|
|
18
|
+
adapters apart. `tasks(namespace)`, `reset_task(task, namespace)`,
|
|
19
|
+
`decisions(namespace=)` and `export(namespace=)` read one namespace.
|
|
20
|
+
- `Cev.mock(media=True)`, which accepts images and audio.
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- `debias` defaults to `"auto"`: `"full"` for zero-shot code readouts as
|
|
24
|
+
before, `"none"` for the trained decision models.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
- The macOS module loads when built with Xcode 27: release builds are no
|
|
28
|
+
longer stripped, which made dyld reject the library ("mis-aligned LINKEDIT
|
|
29
|
+
string pool").
|
|
30
|
+
|
|
31
|
+
## 0.1.0 (2026-10-03)
|
|
32
|
+
|
|
33
|
+
First version: cev in-process for Python.
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
- `Cev.load()`: a Qwen3 checkpoint from a directory or the Hugging Face cache,
|
|
37
|
+
run by a native module over the cev Rust crates. Metal and Apple's Accelerate
|
|
38
|
+
BLAS on macOS, portable multi-threaded kernels elsewhere, CUDA as a build
|
|
39
|
+
feature. Every call releases the GIL.
|
|
40
|
+
- `decide()`, `feedback()`, `examples()`, `tasks()`, `reset_task()`: typed
|
|
41
|
+
decisions, labels, and the online adapters that learn from them.
|
|
42
|
+
- `decisions()`, `decision()`, `export()`, `export_ndjson()`, `stats()`: the
|
|
43
|
+
decision log, in memory or in a SQLite file (`db`).
|
|
44
|
+
- `Cev.mock()`: the whole API without weights, for tests.
|
|
45
|
+
- `threads` and `concurrency` options, `info()`, `TypedDict`s for the wire
|
|
46
|
+
format, and `scripts/bench.py`.
|
cev_py-0.2.0/CLAUDE.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|