Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
8e96810
Ignore local agent and mise configuration files
tempusfrangit Jan 17, 2026
867c735
Add Rust tooling tasks to mise configuration
tempusfrangit Jan 17, 2026
3138595
Add Cargo workspace for Rust crates
tempusfrangit Jan 17, 2026
d5b6914
Add coglet dependencies to Cargo.toml
tempusfrangit Jan 17, 2026
726e145
Add health and version foundation types
tempusfrangit Jan 17, 2026
e089c4e
Add IPC bridge protocol and codec
tempusfrangit Jan 17, 2026
38528be
Add Unix socket transport for slot IPC
tempusfrangit Jan 17, 2026
cc8f076
Add Prediction state tracking and PredictionOutput
tempusfrangit Jan 17, 2026
701cce8
Add predictor traits and prediction lifecycle types
tempusfrangit Jan 17, 2026
803a136
Add permit pool with typestate for slot management
tempusfrangit Jan 17, 2026
4747fcc
Add PredictionSlot combining Prediction and Permit
tempusfrangit Jan 17, 2026
e09e5ce
Add webhook sender with throttling and retry
tempusfrangit Jan 17, 2026
dad0093
Add PredictionSupervisor for lifecycle management
tempusfrangit Jan 17, 2026
4cef6bd
Add Orchestrator for worker subprocess lifecycle
tempusfrangit Jan 17, 2026
82c590f
Add PredictionService for transport-agnostic prediction lifecycle
tempusfrangit Jan 17, 2026
3b7ec2b
Add HTTP transport layer with axum server and routes
tempusfrangit Jan 17, 2026
ca11120
Add worker subprocess types for PyO3 bindings
tempusfrangit Jan 17, 2026
3477207
Add coglet-python crate with PyO3 bindings
tempusfrangit Jan 17, 2026
8c86cfa
Add Python input/output processing infrastructure
tempusfrangit Jan 17, 2026
1eb34b6
Add full predictor and worker bridge implementation
tempusfrangit Jan 17, 2026
91d014a
Add type stubs and Python tests
tempusfrangit Jan 17, 2026
154a213
Add setup log hook and audit helper exports to coglet module
tempusfrangit Jan 17, 2026
694df39
Upgrade PyO3 from 0.24 to 0.27
tempusfrangit Jan 17, 2026
3947382
Install log writers and audit hook in worker startup
tempusfrangit Jan 17, 2026
7549ad2
Add SetupError type for typed setup failures
tempusfrangit Jan 18, 2026
1e74764
Add architecture documentation for coglet crates
tempusfrangit Jan 18, 2026
a5d67ce
Remove dead predict_fn code path from service
tempusfrangit Jan 18, 2026
9f96453
Extract Orchestrator trait for testable service layer
tempusfrangit Jan 18, 2026
306ef96
Add comprehensive tests using MockOrchestrator
tempusfrangit Jan 18, 2026
b3f1fa2
Remove panics from permit/slot.rs state transitions
tempusfrangit Jan 18, 2026
a870b58
Remove panics from orchestrator.rs
tempusfrangit Jan 18, 2026
0a12c21
Remove panics from service.rs prediction locks
tempusfrangit Jan 18, 2026
3872cf4
Remove panics from coglet-python setup and mutex locks
tempusfrangit Jan 18, 2026
9cefa64
Remove panics from webhook, routes, and server modules
tempusfrangit Jan 18, 2026
01c84f0
Replace remaining panics with PyErr in coglet-python
tempusfrangit Jan 18, 2026
e602efe
Add Rust CI workflow and stub generation
tempusfrangit Jan 18, 2026
7947b4c
Apply cargo fmt formatting
tempusfrangit Jan 18, 2026
c875f73
Fix Rust CI: add cargo-binstall, uv sync for Python
tempusfrangit Jan 18, 2026
98b4a86
Fix CI: resolve checkout and virtualenv issues
tempusfrangit Jan 19, 2026
c52e58d
Replace boolean flags with Rust enums (#2643)
markphelps Jan 20, 2026
9f7b7e1
Add Rust coglet integration to CI tests (#2644)
markphelps Jan 21, 2026
adcec69
cog-dataclass: fix Rust server predictor configuration
tempusfrangit Jan 21, 2026
11a1243
Enable Rust coglet server in integration tests
tempusfrangit Jan 21, 2026
f4a0252
Clarify SDK detection: PYDANTIC_V2 exists in both v1 and v2
tempusfrangit Jan 21, 2026
7e4912e
Exclude Rust coglet wheel from Go binary embedding
tempusfrangit Jan 21, 2026
af5c684
Fix type checking errors in cog http.py for Rust coglet integration
tempusfrangit Jan 21, 2026
d16f30b
Remove embedded Python coglet wheel to avoid package name conflicts
tempusfrangit Jan 21, 2026
9f06cca
Remove coglet wheel test references
tempusfrangit Jan 21, 2026
d4a158f
Fix Path handling for data URLs in cog-dataclass
tempusfrangit Jan 21, 2026
b5cf6bb
cog-dataclass: allow non-BasePredictor classes and add tests
tempusfrangit Jan 22, 2026
534e7a0
coglet: detect non-pydantic runtime via cog-dataclass inspector
tempusfrangit Jan 22, 2026
f0bd8fa
cog-dataclass: accept local paths in Path.validate
tempusfrangit Jan 22, 2026
7d501a6
coglet: fix spurious error log during normal shutdown
tempusfrangit Jan 22, 2026
25e737a
coglet: use manylinux2014 for Python 3.8+ compatibility
tempusfrangit Jan 22, 2026
351f9f7
Linting fixes
tempusfrangit Jan 22, 2026
4dabe06
Use rustls with native OS certificate stores
tempusfrangit Jan 22, 2026
e7fb7e9
Allow CDLA-Permissive-2.0 license in cargo-deny
tempusfrangit Jan 22, 2026
e069184
Fix coglet-python test task to install dependencies
tempusfrangit Jan 22, 2026
67b9125
CI: Add coglet-python tests and ensure rust+binstall before mise
tempusfrangit Jan 22, 2026
7737c94
Fix coglet-python tests with dynamic port discovery and cog.yaml
tempusfrangit Jan 22, 2026
8fbff10
Require Python 3.10+ for coglet (matching cog-dataclass)
tempusfrangit Jan 22, 2026
48b2b7a
Skip integration tests with Python <3.10 or monobase for coglet (Rust)
tempusfrangit Jan 22, 2026
794f7fc
CI: Use zig cross-compilation for Linux coglet wheel build
tempusfrangit Jan 22, 2026
d3e753a
fixup! CI: Add coglet-python tests and ensure rust+binstall before mise
tempusfrangit Jan 22, 2026
2c4f894
Fix Secret serialization and skip pydantic2_output for cog-dataclass
tempusfrangit Jan 22, 2026
b297598
Fix OpenAPI schema generation for training mode in coglet
tempusfrangit Jan 22, 2026
e3f7457
Fix validation error messages to match pydantic format
tempusfrangit Jan 22, 2026
af3eb36
Fix subprocess output corrupting control channel in coglet
tempusfrangit Jan 23, 2026
d996386
Fix validation error format to show simple field messages
tempusfrangit Jan 23, 2026
e3d6061
Fix TrainingOutput serialization for Pydantic v2 models
tempusfrangit Jan 23, 2026
69ee226
Fix validation error formatting in coglet to show simple messages
tempusfrangit Jan 23, 2026
968afdf
Fix capture thread feedback loop and update to bounded channels
tempusfrangit Jan 23, 2026
fe46af4
Update cog-dataclass test to expect new validation error format
tempusfrangit Jan 23, 2026
f0c4d6b
Fix blocking panic and add dropped log tracking
tempusfrangit Jan 23, 2026
8e4477c
Ship worker tracing logs over IPC with preserved targets
tempusfrangit Jan 23, 2026
bd4814d
Prevent feedback loop in codec logging
tempusfrangit Jan 23, 2026
23696a1
Accumulate coglet server setup logs via tracing layer
tempusfrangit Jan 23, 2026
b558a50
Ensure 'Server ready' log is accumulated before stopping
tempusfrangit Jan 23, 2026
49ea646
Stabilize coglet bindings runtime detection
tempusfrangit Jan 23, 2026
d7699c2
Normalize coglet output serialization
tempusfrangit Jan 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 104 additions & 13 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ jobs:
- uses: actions/checkout@v6
with:
fetch-depth: 0 # needed for setuptools_scm version determination
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install cargo-binstall
uses: cargo-bins/cargo-binstall@v1.12.3
- uses: jdx/mise-action@v2
# Build main cog package (wheel + sdist)
- name: Build cog package
Expand All @@ -34,16 +38,6 @@ jobs:
with:
name: CogPackage
path: dist/cog-*
# Build coglet wheel with embedded Go binary
- name: Build coglet-server binary
run: script/build-coglet-server
- name: Build coglet wheel
run: uv build --wheel --out-dir=dist ./coglet
- name: Upload coglet wheel
uses: actions/upload-artifact@v6
with:
name: CogletWheel
path: dist/coglet-*.whl
# Build cog-dataclass wheel
- name: Build cog-dataclass wheel
run: uv build --wheel --out-dir=dist ./cog-dataclass
Expand All @@ -52,6 +46,21 @@ jobs:
with:
name: CogDataclassWheel
path: dist/cog_dataclass-*.whl
# Build Rust coglet wheel
- uses: Swatinem/rust-cache@v2
with:
workspaces: crates -> target
- name: Check Rust formatting
run: cargo fmt --manifest-path crates/Cargo.toml --all -- --check
- name: Run clippy
run: cargo clippy --manifest-path crates/Cargo.toml --workspace -- -D warnings
- name: Build Rust coglet wheel (ABI3)
run: mise run build:coglet:wheel:linux
- name: Upload Rust coglet wheel
uses: actions/upload-artifact@v6
with:
name: CogletRustWheel
path: dist/coglet-*-cp310-abi3-*.whl

lint:
name: Lint
Expand All @@ -66,6 +75,10 @@ jobs:
merge-multiple: true
- name: Extract source distribution
run: tar xf dist/*.tar.gz --strip-components=1
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install cargo-binstall
uses: cargo-bins/cargo-binstall@v1.12.3
- uses: jdx/mise-action@v2
- name: Lint
run: make lint
Expand All @@ -76,6 +89,7 @@ jobs:
- test-go
- test-python
- test-python-dataclasses
- test-coglet-python
- test-integration
runs-on: ubuntu-latest
timeout-minutes: 30
Expand All @@ -102,6 +116,10 @@ jobs:
with:
path: dist
merge-multiple: true
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install cargo-binstall
uses: cargo-bins/cargo-binstall@v1.12.3
- uses: jdx/mise-action@v2
- name: Build
run: make cog
Expand All @@ -128,6 +146,10 @@ jobs:
merge-multiple: true
- name: Extract source distribution
run: tar xf dist/*.tar.gz --strip-components=1
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install cargo-binstall
uses: cargo-bins/cargo-binstall@v1.12.3
- uses: jdx/mise-action@v2
- name: Compute tox env name
run: echo TOX_PYTHON=py$(echo "${{ matrix.python-version }}" | tr -d .) >>$GITHUB_ENV
Expand Down Expand Up @@ -156,6 +178,10 @@ jobs:
with:
path: dist
merge-multiple: true
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install cargo-binstall
uses: cargo-bins/cargo-binstall@v1.12.3
- uses: jdx/mise-action@v2
- name: Create virtual environment and install cog-dataclass wheel with dev dependencies
run: |
Expand All @@ -164,16 +190,52 @@ jobs:
- name: Test
run: uv run pytest cog-dataclass/python/tests -v

test-coglet-python:
name: "Test Coglet Python bindings (${{ matrix.runtime }})"
needs: build-python
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
runtime: [dataclass, cog]
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Download built wheels
uses: actions/download-artifact@v7
with:
path: dist
merge-multiple: true
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- uses: astral-sh/setup-uv@v5
- name: Create virtual environment
run: uv venv
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install cargo-binstall
uses: cargo-bins/cargo-binstall@v1.12.3
- uses: jdx/mise-action@v2
- uses: Swatinem/rust-cache@v2
with:
workspaces: crates -> target
- name: Test coglet Python bindings
run: mise test:coglet-python:${{ matrix.runtime }}

# Go-based integration tests using testscript framework
test-integration:
name: "Test integration (${{ matrix.runtime }})"
needs: build-python
needs:
- build-python
runs-on: ubuntu-latest-16-cores
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
runtime: [cog, coglet-alpha, cog-dataclass]
runtime: [cog, cog-dataclass, coglet-alpha, cog-rust, cog-dataclass-rust]
steps:
- uses: actions/checkout@v6
with:
Expand All @@ -199,9 +261,34 @@ jobs:
integration-tests/go.sum
- name: Build cog binary
run: make cog
- name: Set wheels for runtime
run: |
# Set COG_WHEEL and COGLET_RUST_WHEEL based on runtime matrix value
case "${{ matrix.runtime }}" in
cog)
echo "COG_WHEEL=cog" >> $GITHUB_ENV
;;
cog-dataclass)
echo "COG_WHEEL=cog-dataclass" >> $GITHUB_ENV
;;
coglet-alpha)
echo "COG_WHEEL=coglet-alpha" >> $GITHUB_ENV
;;
cog-rust)
RUST_WHEEL=$(ls dist/coglet-*-cp310-abi3-*.whl | head -1)
echo "Found Rust coglet wheel: $RUST_WHEEL"
echo "COG_WHEEL=cog" >> $GITHUB_ENV
echo "COGLET_RUST_WHEEL=${PWD}/${RUST_WHEEL}" >> $GITHUB_ENV
;;
cog-dataclass-rust)
RUST_WHEEL=$(ls dist/coglet-*-cp310-abi3-*.whl | head -1)
echo "Found Rust coglet wheel: $RUST_WHEEL"
echo "COG_WHEEL=cog-dataclass" >> $GITHUB_ENV
echo "COGLET_RUST_WHEEL=${PWD}/${RUST_WHEEL}" >> $GITHUB_ENV
;;
esac
- name: Run integration tests
env:
COG_WHEEL: ${{ matrix.runtime }}
COG_BINARY: ./cog
TEST_PARALLEL: 4
BUILDKIT_PROGRESS: 'quiet'
Expand All @@ -227,6 +314,10 @@ jobs:
with:
path: dist
merge-multiple: true
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install cargo-binstall
uses: cargo-bins/cargo-binstall@v1.12.3
- uses: jdx/mise-action@v2
- uses: goreleaser/goreleaser-action@v6
with:
Expand Down
129 changes: 129 additions & 0 deletions .github/workflows/rust.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
name: Rust

on:
merge_group:
push:
branches: [main]
paths:
- "crates/**"
- "Cargo.toml"
- "Cargo.lock"
- ".github/workflows/rust.yaml"
pull_request:
paths:
- "crates/**"
- "Cargo.toml"
- "Cargo.lock"
- ".github/workflows/rust.yaml"
workflow_dispatch:

env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1

permissions: {}

jobs:
# Pure Rust checks (no Python needed)
rust:
name: Rust checks
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4

# Order matters: Rust -> cargo-binstall -> mise (so mise uses binstall for cargo tools)
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy

- name: Install cargo-binstall
uses: cargo-bins/cargo-binstall@v1.12.3

- uses: Swatinem/rust-cache@v2
with:
workspaces: crates -> target

- uses: jdx/mise-action@v2

- name: Check formatting
run: mise run fmt:rust:check

- name: Clippy
run: mise run clippy

- name: Run tests
run: mise run test:rust

# coglet-python checks (requires Python + maturin build)
# Builds once with ABI3 (works across Python 3.8+)
coglet-python:
name: coglet-python
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4

# Order matters: Rust -> cargo-binstall -> mise (so mise uses binstall for cargo tools)
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable

- name: Install cargo-binstall
uses: cargo-bins/cargo-binstall@v1.12.3

- uses: Swatinem/rust-cache@v2
with:
workspaces: crates -> target

- uses: jdx/mise-action@v2

# Setup Python with uv
- name: Setup Python with uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
python-version: "3.12"

- name: Create virtualenv
run: uv venv .venv

- name: Build coglet wheel (ABI3)
env:
VIRTUAL_ENV: ${{ github.workspace }}/.venv
run: |
export PATH="${VIRTUAL_ENV}/bin:${PATH}"
mise run build:coglet

- name: Check stubs are up to date
env:
VIRTUAL_ENV: ${{ github.workspace }}/.venv
run: |
export PATH="${VIRTUAL_ENV}/bin:${PATH}"
mise run stubs:check

- name: Type-check stubs
env:
VIRTUAL_ENV: ${{ github.workspace }}/.venv
run: |
export PATH="${VIRTUAL_ENV}/bin:${PATH}"
mise run stubs:typecheck

# Summary job for branch protection
rust-ci:
name: Rust CI
needs: [rust, coglet-python]
runs-on: ubuntu-latest
if: always()
steps:
- name: Check job results
run: |
if [[ "${{ needs.rust.result }}" != "success" ]]; then
echo "Rust checks failed"
exit 1
fi
if [[ "${{ needs.coglet-python.result }}" != "success" ]]; then
echo "coglet-python checks failed"
exit 1
fi
echo "All Rust CI checks passed!"
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,11 @@ coglet/python/cog/bin/

# Local planning files
docs/plans/**

# Local agent files
AGENTS.local.md
CLAUDE.local.md

# Local mise files
mise.local.toml
mise.local.lock
11 changes: 8 additions & 3 deletions cog-dataclass/python/cog/_adt.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,10 @@ def normalize(self, value: Any) -> Any:
# URL string or data URI - validate to file-like object
return File.validate(value)
elif self is PrimitiveType.PATH:
# Convert strings to Path objects
# Convert strings/URLs to Path or URLPath objects
if isinstance(value, Path):
return value
return Path(value)
return Path.validate(value)
elif self is PrimitiveType.SECRET:
# Convert strings to Secret objects
if isinstance(value, Secret):
Expand Down Expand Up @@ -175,7 +175,12 @@ def json_encode(self, value: Any) -> Any:
"""Encode a value for JSON serialization."""
if self is PrimitiveType.FLOAT:
return float(value)
elif self in {PrimitiveType.PATH, PrimitiveType.FILE, PrimitiveType.SECRET}:
elif self in {PrimitiveType.PATH, PrimitiveType.FILE}:
return value
elif self is PrimitiveType.SECRET:
# Secret objects need to be unwrapped for JSON serialization
if isinstance(value, Secret):
return value.get_secret_value()
return value
elif self is PrimitiveType.ANY:
return value
Expand Down
Loading