Previous wiremock conversion fixed the listener-lifecycle race but left the underlying problem unsolved: `ensure_env()` mutates the process-global ANTHROPIC_ENDPOINT, and parallel `cargo test` threads race on that write. Manifested as 502 / "error sending request for url …" on the first concurrent test pair under both macOS and Linux. Annotate every #[tokio::test] in openai_loop_wiring.rs + openai_compat.rs with `#[serial_test::serial]` — these are the only tests that touch ANTHROPIC_ENDPOINT via shared_mock_anthropic. serial_test enforces process-wide ordering so the env mutation + HTTP request pair is atomic per test. All other tests stay parallel. Stress: 5 parallel `cargo test` runs all green.
70 lines
2.2 KiB
TOML
70 lines
2.2 KiB
TOML
[package]
|
|
name = "kei-cortex"
|
|
version = "0.1.0"
|
|
edition.workspace = true
|
|
rust-version.workspace = true
|
|
description = "Local HTTP daemon exposing cortex state for UI consumption"
|
|
authors.workspace = true
|
|
license.workspace = true
|
|
|
|
[[bin]]
|
|
name = "kei-cortex"
|
|
path = "src/main.rs"
|
|
|
|
[lib]
|
|
name = "kei_cortex"
|
|
path = "src/lib.rs"
|
|
|
|
[dependencies]
|
|
axum = { version = "0.7", features = ["multipart", "ws"] }
|
|
tokio = { workspace = true }
|
|
tokio-util = { version = "0.7", features = ["rt"] }
|
|
tower = { workspace = true }
|
|
tower-http = { version = "0.5", features = ["cors", "trace"] }
|
|
serde = { workspace = true }
|
|
serde_json = { workspace = true }
|
|
clap = { workspace = true }
|
|
thiserror = { workspace = true }
|
|
rusqlite = { workspace = true }
|
|
anyhow = { workspace = true }
|
|
rand = "0.8"
|
|
reqwest = { workspace = true }
|
|
tokio-stream = { workspace = true }
|
|
futures = { workspace = true }
|
|
uuid = { version = "1", features = ["v4"] }
|
|
async-stream = "0.3"
|
|
toml = { workspace = true }
|
|
bytes = { workspace = true }
|
|
tempfile = { workspace = true }
|
|
dashmap = { workspace = true }
|
|
walkdir = { workspace = true }
|
|
which = "6"
|
|
once_cell = "1"
|
|
regex = { workspace = true }
|
|
portable-pty = { workspace = true }
|
|
# Wave 44a — tool-sandbox hardening
|
|
shell-words = { workspace = true }
|
|
url = { workspace = true }
|
|
lru = { workspace = true }
|
|
# Wave 44b — symlink-safe writes
|
|
nix = { workspace = true }
|
|
# Wave 44d — calendar usage boundaries
|
|
chrono = { workspace = true }
|
|
kei-pet = { path = "../kei-pet" }
|
|
kei-router = { path = "../kei-router" }
|
|
kei-shared = { path = "../kei-shared" }
|
|
kei-ledger = { path = "../kei-ledger" }
|
|
# Wave 55 Stage 2 — universal model registry. `default_model()` in
|
|
# `anthropic.rs` consults this for the `kei-cortex-default` role before
|
|
# falling back to the literal pin.
|
|
kei-model = { path = "../kei-model" }
|
|
# Phase 2 — per-turn token telemetry. Every chat handler fires a
|
|
# fire-and-forget `Store::record_event` after Done so sleep-report has
|
|
# real data. Open lazily on AppState init; tracker IO failures must
|
|
# never break the chat call.
|
|
kei-token-tracker = { path = "../kei-token-tracker" }
|
|
|
|
[dev-dependencies]
|
|
reqwest = { workspace = true, features = ["blocking"] }
|
|
wiremock = { workspace = true }
|
|
serial_test = "3"
|