kaos-ml-core 0.1.0a1__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.
- kaos_ml_core-0.1.0a1/.github/CODEOWNERS +16 -0
- kaos_ml_core-0.1.0a1/.github/ISSUE_TEMPLATE/bug.yml +59 -0
- kaos_ml_core-0.1.0a1/.github/ISSUE_TEMPLATE/config.yml +5 -0
- kaos_ml_core-0.1.0a1/.github/ISSUE_TEMPLATE/feature.yml +26 -0
- kaos_ml_core-0.1.0a1/.github/PULL_REQUEST_TEMPLATE.md +23 -0
- kaos_ml_core-0.1.0a1/.github/dependabot.yml +56 -0
- kaos_ml_core-0.1.0a1/.github/workflows/ci.yml +270 -0
- kaos_ml_core-0.1.0a1/.github/workflows/release.yml +241 -0
- kaos_ml_core-0.1.0a1/.github/workflows/security.yml +113 -0
- kaos_ml_core-0.1.0a1/.gitignore +44 -0
- kaos_ml_core-0.1.0a1/.pre-commit-config.yaml +76 -0
- kaos_ml_core-0.1.0a1/CHANGELOG.md +158 -0
- kaos_ml_core-0.1.0a1/Cargo.lock +133 -0
- kaos_ml_core-0.1.0a1/Cargo.toml +44 -0
- kaos_ml_core-0.1.0a1/LICENSE +201 -0
- kaos_ml_core-0.1.0a1/NOTICE +8 -0
- kaos_ml_core-0.1.0a1/PKG-INFO +401 -0
- kaos_ml_core-0.1.0a1/README.md +355 -0
- kaos_ml_core-0.1.0a1/SECURITY.md +58 -0
- kaos_ml_core-0.1.0a1/deny.toml +58 -0
- kaos_ml_core-0.1.0a1/pyproject.toml +171 -0
- kaos_ml_core-0.1.0a1/python/kaos_ml_core/__init__.py +96 -0
- kaos_ml_core-0.1.0a1/python/kaos_ml_core/__main__.py +6 -0
- kaos_ml_core-0.1.0a1/python/kaos_ml_core/_rust/__init__.pyi +12 -0
- kaos_ml_core-0.1.0a1/python/kaos_ml_core/aggregate.py +267 -0
- kaos_ml_core-0.1.0a1/python/kaos_ml_core/cli.py +56 -0
- kaos_ml_core-0.1.0a1/python/kaos_ml_core/cluster.py +140 -0
- kaos_ml_core-0.1.0a1/python/kaos_ml_core/corpus.py +820 -0
- kaos_ml_core-0.1.0a1/python/kaos_ml_core/errors.py +45 -0
- kaos_ml_core-0.1.0a1/python/kaos_ml_core/features.py +96 -0
- kaos_ml_core-0.1.0a1/python/kaos_ml_core/index.py +498 -0
- kaos_ml_core-0.1.0a1/python/kaos_ml_core/label.py +123 -0
- kaos_ml_core-0.1.0a1/python/kaos_ml_core/metrics.py +389 -0
- kaos_ml_core-0.1.0a1/python/kaos_ml_core/pipeline.py +486 -0
- kaos_ml_core-0.1.0a1/python/kaos_ml_core/predict.py +135 -0
- kaos_ml_core-0.1.0a1/python/kaos_ml_core/py.typed +0 -0
- kaos_ml_core-0.1.0a1/python/kaos_ml_core/serve.py +20 -0
- kaos_ml_core-0.1.0a1/python/kaos_ml_core/settings.py +53 -0
- kaos_ml_core-0.1.0a1/python/kaos_ml_core/split.py +170 -0
- kaos_ml_core-0.1.0a1/python/kaos_ml_core/threshold.py +228 -0
- kaos_ml_core-0.1.0a1/python/kaos_ml_core/tools.py +1163 -0
- kaos_ml_core-0.1.0a1/python/kaos_ml_core/train.py +158 -0
- kaos_ml_core-0.1.0a1/rust/bindings/mod.rs +7 -0
- kaos_ml_core-0.1.0a1/rust/bindings/version.rs +15 -0
- kaos_ml_core-0.1.0a1/rust/core/mod.rs +8 -0
- kaos_ml_core-0.1.0a1/rust/core/version.rs +18 -0
- kaos_ml_core-0.1.0a1/rust/lib.rs +47 -0
- kaos_ml_core-0.1.0a1/tests/__init__.py +0 -0
- kaos_ml_core-0.1.0a1/tests/benchmarks/__init__.py +0 -0
- kaos_ml_core-0.1.0a1/tests/benchmarks/test_corpus_benchmarks.py +129 -0
- kaos_ml_core-0.1.0a1/tests/fixtures/__init__.py +0 -0
- kaos_ml_core-0.1.0a1/tests/fixtures/usc_corpus.py +252 -0
- kaos_ml_core-0.1.0a1/tests/integration/__init__.py +0 -0
- kaos_ml_core-0.1.0a1/tests/integration/_usc_helpers.py +314 -0
- kaos_ml_core-0.1.0a1/tests/integration/test_corpus_index_persistence.py +187 -0
- kaos_ml_core-0.1.0a1/tests/integration/test_usc_cold_start_endtoend.py +169 -0
- kaos_ml_core-0.1.0a1/tests/integration/test_usc_harder_pair.py +168 -0
- kaos_ml_core-0.1.0a1/tests/integration/test_usc_llm_label_quality.py +145 -0
- kaos_ml_core-0.1.0a1/tests/integration/test_usc_pipeline_integrity.py +114 -0
- kaos_ml_core-0.1.0a1/tests/integration/test_v0_vertical_slice.py +132 -0
- kaos_ml_core-0.1.0a1/tests/unit/__init__.py +0 -0
- kaos_ml_core-0.1.0a1/tests/unit/test_aggregate.py +180 -0
- kaos_ml_core-0.1.0a1/tests/unit/test_cluster.py +125 -0
- kaos_ml_core-0.1.0a1/tests/unit/test_corpus.py +774 -0
- kaos_ml_core-0.1.0a1/tests/unit/test_corpus_levels.py +111 -0
- kaos_ml_core-0.1.0a1/tests/unit/test_features.py +100 -0
- kaos_ml_core-0.1.0a1/tests/unit/test_index.py +218 -0
- kaos_ml_core-0.1.0a1/tests/unit/test_metrics.py +207 -0
- kaos_ml_core-0.1.0a1/tests/unit/test_pipeline.py +160 -0
- kaos_ml_core-0.1.0a1/tests/unit/test_predict.py +158 -0
- kaos_ml_core-0.1.0a1/tests/unit/test_rust_smoke.py +54 -0
- kaos_ml_core-0.1.0a1/tests/unit/test_split.py +86 -0
- kaos_ml_core-0.1.0a1/tests/unit/test_threshold.py +136 -0
- kaos_ml_core-0.1.0a1/tests/unit/test_tools.py +158 -0
- kaos_ml_core-0.1.0a1/tests/unit/test_train.py +121 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Default owner for everything in this repo
|
|
2
|
+
* @mjbommar
|
|
3
|
+
|
|
4
|
+
# Critical paths get explicit ownership for clarity
|
|
5
|
+
/.github/ @mjbommar
|
|
6
|
+
/pyproject.toml @mjbommar
|
|
7
|
+
/Cargo.toml @mjbommar
|
|
8
|
+
/Cargo.lock @mjbommar
|
|
9
|
+
/LICENSE @mjbommar
|
|
10
|
+
/NOTICE @mjbommar
|
|
11
|
+
/CHANGELOG.md @mjbommar
|
|
12
|
+
/SECURITY.md @mjbommar
|
|
13
|
+
/deny.toml @mjbommar
|
|
14
|
+
|
|
15
|
+
# Rust core / bindings — version-coupled with the Python wheel
|
|
16
|
+
/rust/ @mjbommar
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report a defect in kaos-ml-core
|
|
3
|
+
title: "[bug] "
|
|
4
|
+
labels: ["type:bug", "needs-triage"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for taking the time to file a bug report. Please fill out the sections below.
|
|
10
|
+
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: what-happened
|
|
13
|
+
attributes:
|
|
14
|
+
label: What happened?
|
|
15
|
+
description: A clear description of the bug. Include any error messages or stack traces.
|
|
16
|
+
placeholder: When I call X with Y, Z happens instead of W.
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
|
|
20
|
+
- type: textarea
|
|
21
|
+
id: reproduce
|
|
22
|
+
attributes:
|
|
23
|
+
label: How to reproduce
|
|
24
|
+
description: Minimal code or commands that reproduce the bug.
|
|
25
|
+
render: python
|
|
26
|
+
validations:
|
|
27
|
+
required: true
|
|
28
|
+
|
|
29
|
+
- type: input
|
|
30
|
+
id: version
|
|
31
|
+
attributes:
|
|
32
|
+
label: kaos-ml-core version
|
|
33
|
+
description: Output of `python -c "import kaos_ml_core; print(kaos_ml_core.__version__)"`
|
|
34
|
+
placeholder: e.g. 0.1.0a1
|
|
35
|
+
validations:
|
|
36
|
+
required: true
|
|
37
|
+
|
|
38
|
+
- type: input
|
|
39
|
+
id: python-version
|
|
40
|
+
attributes:
|
|
41
|
+
label: Python version
|
|
42
|
+
description: Output of `python --version`
|
|
43
|
+
placeholder: e.g. 3.13.1
|
|
44
|
+
validations:
|
|
45
|
+
required: true
|
|
46
|
+
|
|
47
|
+
- type: input
|
|
48
|
+
id: os
|
|
49
|
+
attributes:
|
|
50
|
+
label: Operating system + architecture
|
|
51
|
+
placeholder: e.g. Ubuntu 24.04 x86_64, macOS 14 arm64, Windows 11 x86_64
|
|
52
|
+
validations:
|
|
53
|
+
required: true
|
|
54
|
+
|
|
55
|
+
- type: textarea
|
|
56
|
+
id: extra
|
|
57
|
+
attributes:
|
|
58
|
+
label: Additional context
|
|
59
|
+
description: Anything else that might help. For Rust-side issues, include the wheel platform tag (e.g. `manylinux_2_28_x86_64`).
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Suggest a new capability or improvement for kaos-ml-core
|
|
3
|
+
title: "[feat] "
|
|
4
|
+
labels: ["type:feat", "needs-triage"]
|
|
5
|
+
body:
|
|
6
|
+
- type: textarea
|
|
7
|
+
id: problem
|
|
8
|
+
attributes:
|
|
9
|
+
label: What problem does this solve?
|
|
10
|
+
description: Describe the use case, not the implementation.
|
|
11
|
+
placeholder: I'm trying to do X and the current API forces me to Y.
|
|
12
|
+
validations:
|
|
13
|
+
required: true
|
|
14
|
+
|
|
15
|
+
- type: textarea
|
|
16
|
+
id: proposal
|
|
17
|
+
attributes:
|
|
18
|
+
label: Proposed solution
|
|
19
|
+
description: Optional. If you already have an API or implementation in mind, sketch it here.
|
|
20
|
+
render: python
|
|
21
|
+
|
|
22
|
+
- type: textarea
|
|
23
|
+
id: alternatives
|
|
24
|
+
attributes:
|
|
25
|
+
label: Alternatives considered
|
|
26
|
+
description: What workarounds did you try, and why aren't they enough?
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
<!-- One-paragraph description of what this PR does and why it's needed. -->
|
|
4
|
+
|
|
5
|
+
## Type of change
|
|
6
|
+
|
|
7
|
+
- [ ] Bug fix (non-breaking change which fixes an issue)
|
|
8
|
+
- [ ] New feature (non-breaking change which adds functionality)
|
|
9
|
+
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
|
10
|
+
- [ ] Documentation only
|
|
11
|
+
|
|
12
|
+
## Checklist
|
|
13
|
+
|
|
14
|
+
- [ ] Commits are signed off (`git commit -s`) — DCO required
|
|
15
|
+
- [ ] Tests added/updated for any behavior change
|
|
16
|
+
- [ ] **Rust** — `cargo fmt --check`, `cargo clippy --no-default-features --all-targets -- -D warnings`, `cargo test --no-default-features --lib`
|
|
17
|
+
- [ ] **Python** — `uv run ruff format --check python/kaos_ml_core tests`, `uv run ruff check python/kaos_ml_core tests`, `uv run ty check python/kaos_ml_core tests`, `uv run pytest -m "not live and not network and not slow" tests/`
|
|
18
|
+
- [ ] **Build** — `uv run maturin develop --release` succeeds
|
|
19
|
+
- [ ] `CHANGELOG.md` updated under `[Unreleased]` if user-visible
|
|
20
|
+
|
|
21
|
+
## Related issues
|
|
22
|
+
|
|
23
|
+
<!-- "Closes #123" or "Refs #123" -->
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
# ────────────── GitHub Actions ──────────────
|
|
4
|
+
- package-ecosystem: github-actions
|
|
5
|
+
directory: /
|
|
6
|
+
schedule:
|
|
7
|
+
interval: monthly
|
|
8
|
+
day: monday
|
|
9
|
+
time: "06:00"
|
|
10
|
+
timezone: Etc/UTC
|
|
11
|
+
groups:
|
|
12
|
+
actions:
|
|
13
|
+
patterns: ["*"]
|
|
14
|
+
labels: ["type:deps", "ci"]
|
|
15
|
+
commit-message:
|
|
16
|
+
prefix: "ci(deps)"
|
|
17
|
+
|
|
18
|
+
# ────────────── Python (uv-managed via pyproject.toml) ──────────────
|
|
19
|
+
- package-ecosystem: pip
|
|
20
|
+
directory: /
|
|
21
|
+
schedule:
|
|
22
|
+
interval: monthly
|
|
23
|
+
day: monday
|
|
24
|
+
time: "06:00"
|
|
25
|
+
timezone: Etc/UTC
|
|
26
|
+
groups:
|
|
27
|
+
python:
|
|
28
|
+
patterns: ["*"]
|
|
29
|
+
update-types: ["minor", "patch"]
|
|
30
|
+
python-major:
|
|
31
|
+
patterns: ["*"]
|
|
32
|
+
update-types: ["major"]
|
|
33
|
+
open-pull-requests-limit: 5
|
|
34
|
+
labels: ["type:deps"]
|
|
35
|
+
commit-message:
|
|
36
|
+
prefix: "deps"
|
|
37
|
+
|
|
38
|
+
# ────────────── Rust (cargo) ──────────────
|
|
39
|
+
- package-ecosystem: cargo
|
|
40
|
+
directory: /
|
|
41
|
+
schedule:
|
|
42
|
+
interval: monthly
|
|
43
|
+
day: monday
|
|
44
|
+
time: "06:00"
|
|
45
|
+
timezone: Etc/UTC
|
|
46
|
+
groups:
|
|
47
|
+
rust:
|
|
48
|
+
patterns: ["*"]
|
|
49
|
+
update-types: ["minor", "patch"]
|
|
50
|
+
rust-major:
|
|
51
|
+
patterns: ["*"]
|
|
52
|
+
update-types: ["major"]
|
|
53
|
+
open-pull-requests-limit: 5
|
|
54
|
+
labels: ["type:deps", "rust"]
|
|
55
|
+
commit-message:
|
|
56
|
+
prefix: "deps(rust)"
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [main]
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ci-${{ github.workflow }}-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
# ────────────── lint (Python + Rust) ──────────────
|
|
18
|
+
lint:
|
|
19
|
+
name: Lint
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
steps:
|
|
22
|
+
- name: Checkout
|
|
23
|
+
uses: actions/checkout@v6
|
|
24
|
+
|
|
25
|
+
- name: Set up Rust toolchain
|
|
26
|
+
uses: dtolnay/rust-toolchain@stable
|
|
27
|
+
with:
|
|
28
|
+
components: rustfmt, clippy
|
|
29
|
+
|
|
30
|
+
- name: Cargo fmt
|
|
31
|
+
run: cargo fmt --check
|
|
32
|
+
|
|
33
|
+
- name: Cargo clippy (no PyO3 features)
|
|
34
|
+
run: cargo clippy --no-default-features --all-targets -- -D warnings
|
|
35
|
+
|
|
36
|
+
- name: Set up uv
|
|
37
|
+
uses: astral-sh/setup-uv@v7
|
|
38
|
+
with:
|
|
39
|
+
enable-cache: true
|
|
40
|
+
|
|
41
|
+
- name: Install Python 3.13
|
|
42
|
+
run: uv python install 3.13
|
|
43
|
+
|
|
44
|
+
- name: Install dependencies (transformers + mcp extras for ty resolution)
|
|
45
|
+
# ty static-analyzes the pipeline.py / tools.py imports of
|
|
46
|
+
# kaos_nlp_transformers.models and kaos_mcp; install both extras
|
|
47
|
+
# so the symbols resolve. The runtime tests don't need this — the
|
|
48
|
+
# imports are gated by try/except — but the type checker is strict.
|
|
49
|
+
run: uv sync --group dev --extra transformers --extra mcp --python 3.13
|
|
50
|
+
|
|
51
|
+
- name: Ruff format check
|
|
52
|
+
run: uv run ruff format --check python/kaos_ml_core tests
|
|
53
|
+
|
|
54
|
+
- name: Ruff lint
|
|
55
|
+
run: uv run ruff check python/kaos_ml_core tests
|
|
56
|
+
|
|
57
|
+
- name: Type check (ty)
|
|
58
|
+
run: uv run ty check python/kaos_ml_core tests
|
|
59
|
+
|
|
60
|
+
# ────────────── pre-commit ──────────────
|
|
61
|
+
pre-commit:
|
|
62
|
+
name: Pre-commit hooks
|
|
63
|
+
runs-on: ubuntu-latest
|
|
64
|
+
steps:
|
|
65
|
+
- name: Checkout
|
|
66
|
+
uses: actions/checkout@v6
|
|
67
|
+
|
|
68
|
+
- name: Set up Rust toolchain
|
|
69
|
+
uses: dtolnay/rust-toolchain@stable
|
|
70
|
+
|
|
71
|
+
- name: Set up uv
|
|
72
|
+
uses: astral-sh/setup-uv@v7
|
|
73
|
+
with:
|
|
74
|
+
enable-cache: true
|
|
75
|
+
|
|
76
|
+
- name: Install Python 3.13
|
|
77
|
+
run: uv python install 3.13
|
|
78
|
+
|
|
79
|
+
- name: Install dependencies (transformers + mcp for ty resolution)
|
|
80
|
+
run: uv sync --group dev --extra transformers --extra mcp --python 3.13
|
|
81
|
+
|
|
82
|
+
- name: Run pre-commit
|
|
83
|
+
run: uvx pre-commit run --all-files --show-diff-on-failure
|
|
84
|
+
|
|
85
|
+
# ────────────── Rust unit tests (pure Rust core) ──────────────
|
|
86
|
+
rust-test:
|
|
87
|
+
name: Rust tests (no PyO3)
|
|
88
|
+
runs-on: ubuntu-latest
|
|
89
|
+
steps:
|
|
90
|
+
- name: Checkout
|
|
91
|
+
uses: actions/checkout@v6
|
|
92
|
+
|
|
93
|
+
- name: Set up Rust toolchain
|
|
94
|
+
uses: dtolnay/rust-toolchain@stable
|
|
95
|
+
|
|
96
|
+
- name: Cargo test (--no-default-features)
|
|
97
|
+
run: cargo test --no-default-features --lib
|
|
98
|
+
|
|
99
|
+
# ────────────── Python tests (Python × maturin develop) ──────────────
|
|
100
|
+
test:
|
|
101
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
102
|
+
runs-on: ubuntu-latest
|
|
103
|
+
strategy:
|
|
104
|
+
fail-fast: false
|
|
105
|
+
matrix:
|
|
106
|
+
include:
|
|
107
|
+
- python-version: "3.13"
|
|
108
|
+
experimental: false
|
|
109
|
+
- python-version: "3.14"
|
|
110
|
+
experimental: false
|
|
111
|
+
- python-version: "3.14t"
|
|
112
|
+
experimental: true
|
|
113
|
+
- python-version: "3.15"
|
|
114
|
+
experimental: true
|
|
115
|
+
continue-on-error: ${{ matrix.experimental }}
|
|
116
|
+
steps:
|
|
117
|
+
- name: Checkout
|
|
118
|
+
uses: actions/checkout@v6
|
|
119
|
+
|
|
120
|
+
- name: Set up Rust toolchain
|
|
121
|
+
uses: dtolnay/rust-toolchain@stable
|
|
122
|
+
|
|
123
|
+
- name: Set up uv
|
|
124
|
+
uses: astral-sh/setup-uv@v7
|
|
125
|
+
with:
|
|
126
|
+
enable-cache: true
|
|
127
|
+
|
|
128
|
+
- name: Install Python ${{ matrix.python-version }}
|
|
129
|
+
run: uv python install --preview ${{ matrix.python-version }}
|
|
130
|
+
|
|
131
|
+
- name: Install dependencies
|
|
132
|
+
run: uv sync --group dev --python ${{ matrix.python-version }}
|
|
133
|
+
|
|
134
|
+
- name: Build PyO3 extension (maturin develop --release)
|
|
135
|
+
run: uv run maturin develop --release
|
|
136
|
+
|
|
137
|
+
- name: Run tests with coverage
|
|
138
|
+
run: |
|
|
139
|
+
uv run pytest \
|
|
140
|
+
-m "not live and not network and not slow" \
|
|
141
|
+
--cov=kaos_ml_core \
|
|
142
|
+
--cov-branch \
|
|
143
|
+
--cov-report=term-missing \
|
|
144
|
+
--cov-report=xml:coverage.xml \
|
|
145
|
+
tests/
|
|
146
|
+
|
|
147
|
+
- name: Upload coverage report
|
|
148
|
+
if: always() && !matrix.experimental
|
|
149
|
+
uses: actions/upload-artifact@v7
|
|
150
|
+
with:
|
|
151
|
+
name: coverage-${{ matrix.python-version }}
|
|
152
|
+
path: coverage.xml
|
|
153
|
+
retention-days: 14
|
|
154
|
+
|
|
155
|
+
# ────────────── min-deps ──────────────
|
|
156
|
+
min-deps:
|
|
157
|
+
name: Test against minimum dependencies
|
|
158
|
+
runs-on: ubuntu-latest
|
|
159
|
+
steps:
|
|
160
|
+
- name: Checkout
|
|
161
|
+
uses: actions/checkout@v6
|
|
162
|
+
|
|
163
|
+
- name: Set up Rust toolchain
|
|
164
|
+
uses: dtolnay/rust-toolchain@stable
|
|
165
|
+
|
|
166
|
+
- name: Set up uv
|
|
167
|
+
uses: astral-sh/setup-uv@v7
|
|
168
|
+
|
|
169
|
+
- name: Install Python 3.13
|
|
170
|
+
run: uv python install 3.13
|
|
171
|
+
|
|
172
|
+
- name: Install with lowest-direct resolution
|
|
173
|
+
run: uv sync --group dev --resolution=lowest-direct --python 3.13
|
|
174
|
+
|
|
175
|
+
- name: Build PyO3 extension
|
|
176
|
+
run: uv run maturin develop --release
|
|
177
|
+
|
|
178
|
+
- name: Run tests
|
|
179
|
+
run: |
|
|
180
|
+
uv run pytest \
|
|
181
|
+
-m "not live and not network and not slow" \
|
|
182
|
+
--no-cov \
|
|
183
|
+
-q \
|
|
184
|
+
tests/
|
|
185
|
+
|
|
186
|
+
# ────────────── build + wheel smoke test ──────────────
|
|
187
|
+
build:
|
|
188
|
+
name: Build distribution + smoke test
|
|
189
|
+
runs-on: ubuntu-latest
|
|
190
|
+
needs: [lint, test, rust-test]
|
|
191
|
+
steps:
|
|
192
|
+
- name: Checkout
|
|
193
|
+
uses: actions/checkout@v6
|
|
194
|
+
|
|
195
|
+
- name: Set up Rust toolchain
|
|
196
|
+
uses: dtolnay/rust-toolchain@stable
|
|
197
|
+
|
|
198
|
+
- name: Set up uv
|
|
199
|
+
uses: astral-sh/setup-uv@v7
|
|
200
|
+
with:
|
|
201
|
+
enable-cache: true
|
|
202
|
+
|
|
203
|
+
- name: Install Python 3.13
|
|
204
|
+
run: uv python install 3.13
|
|
205
|
+
|
|
206
|
+
- name: Build wheel + sdist
|
|
207
|
+
run: uv build
|
|
208
|
+
|
|
209
|
+
- name: Verify metadata (twine check)
|
|
210
|
+
run: uvx --from twine twine check --strict dist/*
|
|
211
|
+
|
|
212
|
+
- name: Smoke-test the built wheel in a clean venv
|
|
213
|
+
run: |
|
|
214
|
+
uv venv --python 3.13 /tmp/smoke
|
|
215
|
+
# Install with [mcp] so register_ml_tools is reachable; the
|
|
216
|
+
# actual ML-pipeline smoke (embed + train + predict) lives in
|
|
217
|
+
# the integration tests, not in this fast-CI smoke.
|
|
218
|
+
uv pip install --python /tmp/smoke/bin/python "dist/kaos_ml_core-0.1.0a1-cp313-abi3-linux_x86_64.whl[mcp]"
|
|
219
|
+
/tmp/smoke/bin/python -c "
|
|
220
|
+
import kaos_ml_core
|
|
221
|
+
from kaos_ml_core import (
|
|
222
|
+
Corpus, KaosMLCoreSettings, Metrics, Pipeline, PipelineError,
|
|
223
|
+
SplitResult, ThresholdResult, aggregate_predictions, evaluate,
|
|
224
|
+
stratified_split, tune_threshold, wilson_score_interval,
|
|
225
|
+
)
|
|
226
|
+
assert kaos_ml_core.__version__, 'version missing from wheel'
|
|
227
|
+
assert len(kaos_ml_core.__all__) >= 22, f'unexpected public surface: {kaos_ml_core.__all__}'
|
|
228
|
+
|
|
229
|
+
# Hard-rule enforcement primitives are reachable.
|
|
230
|
+
lo, hi = wilson_score_interval(80, 100, confidence=0.95)
|
|
231
|
+
assert 0.7 < lo < 0.72 and 0.86 < hi < 0.87
|
|
232
|
+
|
|
233
|
+
# Four granularity levels supported.
|
|
234
|
+
from kaos_content.model.blocks import Heading, Paragraph
|
|
235
|
+
from kaos_content.model.document import ContentDocument
|
|
236
|
+
from kaos_content.model.inlines import Text
|
|
237
|
+
from kaos_content.model.metadata import DocumentMetadata, SourceRef
|
|
238
|
+
doc = ContentDocument(
|
|
239
|
+
metadata=DocumentMetadata(source=SourceRef(uri='smoke://1')),
|
|
240
|
+
body=(
|
|
241
|
+
Heading(depth=1, children=(Text(value='Indemnification'),)),
|
|
242
|
+
Paragraph(children=(Text(value='The Seller indemnifies Buyer.'),)),
|
|
243
|
+
Paragraph(children=(Text(value='Cap is 10 percent.'),)),
|
|
244
|
+
),
|
|
245
|
+
)
|
|
246
|
+
assert len(Corpus.from_documents([doc], level='paragraph')) == 2
|
|
247
|
+
assert len(Corpus.from_documents([doc], level='section')) == 1
|
|
248
|
+
assert len(Corpus.from_documents([doc], level='document')) == 1
|
|
249
|
+
|
|
250
|
+
# MCP tool surface registers 11 tools.
|
|
251
|
+
from kaos_core import KaosRuntime
|
|
252
|
+
from kaos_ml_core.tools import register_ml_tools
|
|
253
|
+
rt = KaosRuntime()
|
|
254
|
+
assert register_ml_tools(rt) == 11
|
|
255
|
+
|
|
256
|
+
# Settings + Rust extension reachable.
|
|
257
|
+
assert KaosMLCoreSettings().default_threshold == 0.5
|
|
258
|
+
from kaos_ml_core._rust import version as rust_version_fn
|
|
259
|
+
assert rust_version_fn() == kaos_ml_core.rust_version
|
|
260
|
+
print(f'kaos-ml-core {kaos_ml_core.__version__}: smoke OK ({len(kaos_ml_core.__all__)} symbols, 11 MCP tools)')
|
|
261
|
+
"
|
|
262
|
+
# Exercise the CLI entrypoint.
|
|
263
|
+
/tmp/smoke/bin/kaos-ml info --json
|
|
264
|
+
|
|
265
|
+
- name: Upload distribution artifacts
|
|
266
|
+
uses: actions/upload-artifact@v7
|
|
267
|
+
with:
|
|
268
|
+
name: dist-${{ github.sha }}
|
|
269
|
+
path: dist/
|
|
270
|
+
retention-days: 7
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
# Manual fallback so a failed publish (e.g. transient PyPI 5xx) can be
|
|
8
|
+
# retried without re-tagging.
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: release-${{ github.ref }}
|
|
16
|
+
cancel-in-progress: false
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
# ────────────── Pre-publish QA + sdist ──────────────
|
|
20
|
+
# One job that gates everything else: verifies version sync, runs the
|
|
21
|
+
# full QA gauntlet, builds + verifies the sdist (the format-agnostic
|
|
22
|
+
# source artifact). Wheel-matrix jobs depend on this; if the source
|
|
23
|
+
# tree is broken we never compile 8 wheels for nothing.
|
|
24
|
+
sdist:
|
|
25
|
+
name: Build sdist + pre-publish QA
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
outputs:
|
|
28
|
+
version: ${{ steps.version.outputs.version }}
|
|
29
|
+
steps:
|
|
30
|
+
- name: Checkout
|
|
31
|
+
uses: actions/checkout@v6
|
|
32
|
+
with:
|
|
33
|
+
fetch-depth: 0
|
|
34
|
+
|
|
35
|
+
- name: Set up Rust toolchain
|
|
36
|
+
uses: dtolnay/rust-toolchain@stable
|
|
37
|
+
with:
|
|
38
|
+
components: rustfmt, clippy
|
|
39
|
+
|
|
40
|
+
- name: Set up uv
|
|
41
|
+
uses: astral-sh/setup-uv@v7
|
|
42
|
+
with:
|
|
43
|
+
enable-cache: true
|
|
44
|
+
|
|
45
|
+
- name: Install Python 3.13
|
|
46
|
+
run: uv python install 3.13
|
|
47
|
+
|
|
48
|
+
- name: Install dependencies (transformers + mcp for ty resolution)
|
|
49
|
+
run: uv sync --group dev --extra transformers --extra mcp --python 3.13
|
|
50
|
+
|
|
51
|
+
- name: Verify Cargo.toml version matches tag
|
|
52
|
+
id: version
|
|
53
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
54
|
+
run: |
|
|
55
|
+
# Cargo SemVer "0.1.0-alpha.1" maps to PEP 440 "0.1.0a1".
|
|
56
|
+
CARGO_VERSION=$(awk -F\" '/^version = "/{print $2; exit}' Cargo.toml)
|
|
57
|
+
# Normalize Cargo SemVer "X.Y.Z-alpha.N" -> PEP 440 "X.Y.ZaN" etc.
|
|
58
|
+
PEP440_VERSION=$(echo "$CARGO_VERSION" \
|
|
59
|
+
| sed -E 's/-alpha\.([0-9]+)$/a\1/' \
|
|
60
|
+
| sed -E 's/-beta\.([0-9]+)$/b\1/' \
|
|
61
|
+
| sed -E 's/-rc\.([0-9]+)$/rc\1/')
|
|
62
|
+
TAG=${GITHUB_REF_NAME#v}
|
|
63
|
+
if [ "$PEP440_VERSION" != "$TAG" ]; then
|
|
64
|
+
echo "::error::Tag '$TAG' does not match Cargo.toml-derived PEP 440 version '$PEP440_VERSION' (Cargo SemVer '$CARGO_VERSION')"
|
|
65
|
+
exit 1
|
|
66
|
+
fi
|
|
67
|
+
echo "version=$PEP440_VERSION" >> "$GITHUB_OUTPUT"
|
|
68
|
+
echo "kaos-ml-core release: tag=$TAG, cargo=$CARGO_VERSION, pep440=$PEP440_VERSION"
|
|
69
|
+
|
|
70
|
+
- name: Pre-publish QA — Rust
|
|
71
|
+
run: |
|
|
72
|
+
cargo fmt --check
|
|
73
|
+
cargo clippy --no-default-features --all-targets -- -D warnings
|
|
74
|
+
cargo test --no-default-features --lib
|
|
75
|
+
|
|
76
|
+
- name: Pre-publish QA — Python (build extension first)
|
|
77
|
+
run: |
|
|
78
|
+
uv run maturin develop --release
|
|
79
|
+
uv run ruff format --check python/kaos_ml_core tests
|
|
80
|
+
uv run ruff check python/kaos_ml_core tests
|
|
81
|
+
uv run ty check python/kaos_ml_core tests
|
|
82
|
+
uv run pytest -m "not live and not network and not slow" --no-cov tests/
|
|
83
|
+
|
|
84
|
+
- name: Build sdist
|
|
85
|
+
run: uv run maturin sdist --out dist
|
|
86
|
+
|
|
87
|
+
- name: Verify sdist metadata
|
|
88
|
+
run: uvx --from twine twine check --strict dist/*.tar.gz
|
|
89
|
+
|
|
90
|
+
- name: Upload sdist
|
|
91
|
+
uses: actions/upload-artifact@v7
|
|
92
|
+
with:
|
|
93
|
+
name: sdist
|
|
94
|
+
path: dist/*.tar.gz
|
|
95
|
+
retention-days: 30
|
|
96
|
+
|
|
97
|
+
# ────────────── Wheel matrix ──────────────
|
|
98
|
+
# 8 wheels per release, per D017 (docs/oss/30-rust-packaging/wheel-matrix.md):
|
|
99
|
+
# - Linux x86_64 manylinux + musllinux
|
|
100
|
+
# - Linux aarch64 manylinux + musllinux
|
|
101
|
+
# - macOS arm64
|
|
102
|
+
# - Windows x86_64
|
|
103
|
+
# - Windows arm64
|
|
104
|
+
# macOS x86_64 deliberately skipped (Apple ended Intel sales in 2023).
|
|
105
|
+
wheels:
|
|
106
|
+
name: ${{ matrix.target }} ${{ matrix.linux-tag && '(' || '' }}${{ matrix.linux-tag }}${{ matrix.linux-tag && ')' || '' }}
|
|
107
|
+
needs: sdist
|
|
108
|
+
strategy:
|
|
109
|
+
fail-fast: false
|
|
110
|
+
matrix:
|
|
111
|
+
include:
|
|
112
|
+
- os: ubuntu-latest
|
|
113
|
+
target: x86_64-unknown-linux-gnu
|
|
114
|
+
linux-tag: manylinux_2_28
|
|
115
|
+
manylinux: "2_28"
|
|
116
|
+
- os: ubuntu-latest
|
|
117
|
+
target: x86_64-unknown-linux-musl
|
|
118
|
+
linux-tag: musllinux_1_2
|
|
119
|
+
manylinux: musllinux_1_2
|
|
120
|
+
- os: ubuntu-24.04-arm
|
|
121
|
+
target: aarch64-unknown-linux-gnu
|
|
122
|
+
linux-tag: manylinux_2_28
|
|
123
|
+
manylinux: "2_28"
|
|
124
|
+
- os: ubuntu-24.04-arm
|
|
125
|
+
target: aarch64-unknown-linux-musl
|
|
126
|
+
linux-tag: musllinux_1_2
|
|
127
|
+
manylinux: musllinux_1_2
|
|
128
|
+
- os: macos-14
|
|
129
|
+
target: aarch64-apple-darwin
|
|
130
|
+
linux-tag: ""
|
|
131
|
+
manylinux: ""
|
|
132
|
+
- os: windows-latest
|
|
133
|
+
target: x86_64-pc-windows-msvc
|
|
134
|
+
linux-tag: ""
|
|
135
|
+
manylinux: ""
|
|
136
|
+
- os: windows-11-arm
|
|
137
|
+
target: aarch64-pc-windows-msvc
|
|
138
|
+
linux-tag: ""
|
|
139
|
+
manylinux: ""
|
|
140
|
+
runs-on: ${{ matrix.os }}
|
|
141
|
+
steps:
|
|
142
|
+
- name: Checkout
|
|
143
|
+
uses: actions/checkout@v6
|
|
144
|
+
|
|
145
|
+
- name: Set up Python (host)
|
|
146
|
+
uses: actions/setup-python@v6
|
|
147
|
+
with:
|
|
148
|
+
python-version: "3.13"
|
|
149
|
+
|
|
150
|
+
- name: Build wheel via PyO3/maturin-action
|
|
151
|
+
uses: PyO3/maturin-action@v1
|
|
152
|
+
with:
|
|
153
|
+
target: ${{ matrix.target }}
|
|
154
|
+
# Empty for macOS/Windows; "2_28" or "musllinux_1_2" for Linux.
|
|
155
|
+
manylinux: ${{ matrix.manylinux }}
|
|
156
|
+
args: --release --strip --out dist
|
|
157
|
+
# Don't restore from cache — release builds must be reproducible
|
|
158
|
+
# from a clean state (per docs/oss/30-rust-packaging/wheel-matrix.md).
|
|
159
|
+
rust-toolchain: stable
|
|
160
|
+
sccache: "true"
|
|
161
|
+
|
|
162
|
+
- name: Upload wheel
|
|
163
|
+
uses: actions/upload-artifact@v7
|
|
164
|
+
with:
|
|
165
|
+
name: wheels-${{ matrix.target }}-${{ matrix.linux-tag || matrix.os }}
|
|
166
|
+
path: dist/*.whl
|
|
167
|
+
retention-days: 30
|
|
168
|
+
|
|
169
|
+
# ────────────── Publish to PyPI via OIDC ──────────────
|
|
170
|
+
publish-pypi:
|
|
171
|
+
name: Publish to PyPI
|
|
172
|
+
needs: [sdist, wheels]
|
|
173
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
174
|
+
runs-on: ubuntu-latest
|
|
175
|
+
environment:
|
|
176
|
+
name: pypi
|
|
177
|
+
url: https://pypi.org/p/kaos-ml-core
|
|
178
|
+
permissions:
|
|
179
|
+
id-token: write # OIDC for Trusted Publishing
|
|
180
|
+
steps:
|
|
181
|
+
- name: Download sdist
|
|
182
|
+
uses: actions/download-artifact@v8
|
|
183
|
+
with:
|
|
184
|
+
name: sdist
|
|
185
|
+
path: dist/
|
|
186
|
+
|
|
187
|
+
- name: Download all wheels
|
|
188
|
+
uses: actions/download-artifact@v8
|
|
189
|
+
with:
|
|
190
|
+
pattern: wheels-*
|
|
191
|
+
path: dist/
|
|
192
|
+
merge-multiple: true
|
|
193
|
+
|
|
194
|
+
- name: Show artifact set
|
|
195
|
+
run: ls -la dist/
|
|
196
|
+
|
|
197
|
+
- name: Publish to PyPI
|
|
198
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
199
|
+
with:
|
|
200
|
+
attestations: true
|
|
201
|
+
skip-existing: false
|
|
202
|
+
|
|
203
|
+
# ────────────── GitHub Release ──────────────
|
|
204
|
+
github-release:
|
|
205
|
+
name: Create GitHub Release
|
|
206
|
+
needs: [sdist, wheels]
|
|
207
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
208
|
+
runs-on: ubuntu-latest
|
|
209
|
+
permissions:
|
|
210
|
+
contents: write
|
|
211
|
+
steps:
|
|
212
|
+
- name: Checkout
|
|
213
|
+
uses: actions/checkout@v6
|
|
214
|
+
|
|
215
|
+
- name: Download sdist
|
|
216
|
+
uses: actions/download-artifact@v8
|
|
217
|
+
with:
|
|
218
|
+
name: sdist
|
|
219
|
+
path: dist/
|
|
220
|
+
|
|
221
|
+
- name: Download all wheels
|
|
222
|
+
uses: actions/download-artifact@v8
|
|
223
|
+
with:
|
|
224
|
+
pattern: wheels-*
|
|
225
|
+
path: dist/
|
|
226
|
+
merge-multiple: true
|
|
227
|
+
|
|
228
|
+
- name: Create GitHub Release
|
|
229
|
+
env:
|
|
230
|
+
GH_TOKEN: ${{ github.token }}
|
|
231
|
+
run: |
|
|
232
|
+
VERSION=${GITHUB_REF_NAME#v}
|
|
233
|
+
PRERELEASE_FLAG=""
|
|
234
|
+
if [[ "$VERSION" == *a* || "$VERSION" == *b* || "$VERSION" == *rc* ]]; then
|
|
235
|
+
PRERELEASE_FLAG="--prerelease"
|
|
236
|
+
fi
|
|
237
|
+
gh release create "$GITHUB_REF_NAME" \
|
|
238
|
+
--title "kaos-ml-core $VERSION" \
|
|
239
|
+
--notes-from-tag \
|
|
240
|
+
$PRERELEASE_FLAG \
|
|
241
|
+
dist/*
|