conproxy 0.2.1

Cache proxy server for heterogeneous RAG/vector search backends with cascade, scope, and MCP
Documentation
[workspace]
members = [".", "sdk/rust", "sdk/python"]
resolver = "2"

[package]
name = "conproxy"
version = "0.2.1"
edition = "2021"
description = "Cache proxy server for heterogeneous RAG/vector search backends with cascade, scope, and MCP"
repository = "https://github.com/jmcgrath207/conproxy"
homepage = "https://github.com/jmcgrath207/conproxy"
keywords = ["cache", "proxy", "rag", "vector-search", "mcp"]
categories = ["web-programming::http-server", "caching"]
license = "MIT"
readme = "README.md"
default-run = "conproxy"

[lib]
name = "conproxy"
path = "src/lib.rs"

[[bin]]
name = "conproxy"
path = "src/bin/conproxy/main.rs"

[[bin]]
name = "test_runner"
path = "src/bin/test_runner.rs"

[[bin]]
name = "generate_embeddings"
path = "src/bin/generate_embeddings.rs"

[[bin]]
name = "perf_summarize"
path = "src/bin/perf_summarize.rs"

[[bin]]
name = "hitrate_bench"
path = "src/bin/hitrate_bench.rs"

[[bin]]
name = "console_snap"
path = "src/bin/console_snap.rs"
required-features = ["tokio-console-snap"]

[[bin]]
name = "corpus_seed"
path = "src/bin/corpus_seed.rs"
required-features = ["embed", "pgvector"]

[[bin]]
name = "corpus_gen"
path = "src/bin/corpus_gen.rs"

[features]
default = []

# MCP server support
mcp = ["rmcp", "schemars"]

# Embedding provider trait + API providers (no ONNX deps)
embed-api = []

# Embedding support (ONNX + API providers, for VectorOnly upstreams)
embed = ["embed-api", "ort", "tokenizers", "ndarray"]

# Disk persistence (redb backend)
persistence = ["redb"]

# pgvector adapter
pgvector = ["tokio-postgres"]

# Linux sandbox
linux-sandbox = ["caps", "nix"]

# E2E proxy tests (requires running proxy instance)
e2e = []

# Load testing
load-test = ["dep:rlt", "dep:rand", "dep:rand_distr", "dep:hdrhistogram"]

# Integration tests against real backends (requires Docker)
integration-tests = ["dep:testcontainers"]

# DHAT heap profiling
dhat-heap = ["dhat"]

# tokio-console (async runtime diagnosis; dev only)
# Requires RUSTFLAGS="--cfg tokio_unstable" at build time (set by make profile-tokio-console).
# Default console server: 127.0.0.1:6669 (override via TOKIO_CONSOLE_BIND).
# Inspect with the `tokio-console` CLI client, NOT a browser.
tokio-console = ["console-subscriber", "tracing-subscriber/registry", "tokio/tracing"]
# Tokio taskdump (`Handle::dump()`) — requires RUSTFLAGS="--cfg tokio_unstable"
# at build time. Exposes `GET /debug/tokio/dump` for stuck-task diagnosis.
tokio-taskdump = ["tokio/taskdump"]

# console_snap binary: headless client that connects to the console port.
# Built separately from the proxy so the main binary doesn't pay the
# transport dep cost.
tokio-console-snap = ["dep:console-api", "dep:futures", "dep:prost-types"]


# Release binary (standard production SKU).
# Bundles MCP, durable cache, remote embedders (OpenAI/Cohere/HF) and pgvector.
# Out of release (opt-in only):
#   - `embed`        — ONNX / `ort`; dynamic-link pain for precompiled binaries
#   - `linux-sandbox`— Linux-only hardening
# See docs/feature-flags.md.
release = ["mcp", "persistence", "embed-api", "pgvector"]

# Test infrastructure (all features)
test = ["release", "load-test", "dhat-heap"]

[dependencies]
# Core (always compiled)
anyhow = { version = "1", default-features = false }
thiserror = { version = "2", default-features = false }
serde = { version = "1", default-features = false, features = ["derive"] }
serde_json = { version = "1", default-features = false, features = ["std"] }
toml = { version = "1", default-features = false, features = ["parse", "display", "serde"] }
clap = { version = "4", default-features = false, features = ["std", "derive", "help", "usage", "error-context"] }
dirs = { version = "6", default-features = false }
walkdir = { version = "2", default-features = false }

# Proxy core (always compiled in conproxy)
axum = { version = "0.8", default-features = false, features = ["json", "tokio", "http1", "http2"] }
blake3 = { version = "1", default-features = false, features = ["std"] }
bytes = { version = "1", default-features = false }
percent-encoding = { version = "2", default-features = false, features = ["alloc"] }
tokio = { version = "1", features = ["macros", "sync", "time", "rt-multi-thread", "io-util", "net", "signal", "fs"] }
reqwest = { version = "0.13", default-features = false, features = ["json", "rustls", "blocking", "stream"] }
tokio-util = { version = "0.7", default-features = false }
tokio-stream = { version = "0.1", default-features = false }
async-stream = { version = "0.3", default-features = false }
async-trait = { version = "0.1", default-features = false }
dashmap = { version = "6", default-features = false }
papaya = { version = "0.2" }
parking_lot = { version = "0.12", default-features = false }
arc-swap = { version = "1", default-features = false }
tracing = { version = "0.1", default-features = false, features = ["std", "attributes"] }
tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "env-filter"] }

# Embedded static assets (web UI)
rust-embed = { version = "8", default-features = false, features = ["mime-guess"] }

# OS page cache prefetch
libc = { version = "0.2", default-features = false }
glob-match = { version = "0.2", default-features = false }

# gRPC (tonic + protobuf)
tonic = { version = "0.14", default-features = false, features = ["transport", "router", "codegen", "gzip", "zstd"] }
tonic-prost = { version = "0.14" }
prost = { version = "0.14", default-features = false, features = ["derive", "std"] }

# OS-level socket tuning
socket2 = { version = "0.6", default-features = false, features = ["all"] }

# Optional: Embedding (for VectorOnly upstreams)
ort = { version = "2.0.0-rc.12", default-features = false, features = ["std", "download-binaries", "tls-rustls"], optional = true }
tokenizers = { version = "0.23", default-features = false, features = ["fancy-regex"], optional = true }
ndarray = { version = "0.17", default-features = false, optional = true }

# Optional: MCP
rmcp = { version = "2.2", default-features = false, features = ["base64", "macros", "server", "transport-io"], optional = true }
schemars = { version = "1", default-features = false, features = ["derive"], optional = true }

# Optional: Disk persistence (redb)
redb = { version = "4", default-features = false, optional = true }

# Optional: pgvector adapter
tokio-postgres = { version = "0.7", default-features = false, features = ["runtime"], optional = true }

# Optional: Linux sandbox
caps = { version = "0.5", default-features = false, optional = true }
nix = { version = "0.31", default-features = false, features = ["user", "process"], optional = true }

# Optional: Load testing
rlt = { version = "0.5", optional = true, default-features = false }
rand = { version = "0.10", optional = true }
rand_distr = { version = "0.6", optional = true }
hdrhistogram = { version = "7.6", optional = true }

# Optional: Integration test containers
testcontainers = { version = "0.27", optional = true, default-features = false }

# Optional: DHAT heap profiling
dhat = { version = "0.3", optional = true }

# Optional: tokio-console (dev/diagnosis only)
console-subscriber = { version = "0.5", optional = true }
# console_snap bin: tonic client that talks to the console port.
# `transport` enables the tonic-generated client (InstrumentClient::connect).
console-api = { version = "0.9", features = ["transport"], optional = true }
prost-types = { version = "0.14", default-features = false, features = ["std"], optional = true }
# Stream helpers for console_snap (StreamExt on the watch_updates stream).
futures = { version = "0.3", default-features = false, features = ["std"], optional = true }
fake = "3"
serde_yaml = "0.9"

[build-dependencies]
tonic-build = { version = "0.14", default-features = false, features = ["transport"] }
tonic-prost-build = { version = "0.14" }

[dev-dependencies]
conproxy-sdk = { path = "sdk/rust" }
tempfile = "3"
assert_cmd = "2"
predicates = "3"
serial_test = "3"
criterion = { version = "0.8", default-features = false, features = ["html_reports"] }
sha2 = "0.11"
tower = { version = "0.5", default-features = false, features = ["util"] }
http-body-util = "0.1"
ureq = { version = "3", features = ["json"] }
proptest = "1"

[[test]]
name = "e2e_eval"
path = "tests/e2e_eval/main.rs"
required-features = ["e2e"]

[[test]]
name = "e2e_proxy"
path = "tests/e2e_proxy/main.rs"
required-features = ["e2e"]

[[test]]
name = "e2e_uat"
path = "tests/e2e_uat/main.rs"
required-features = ["e2e"]

[[test]]
name = "e2e_sdk_python"
required-features = ["e2e"]


[[test]]
name = "e2e_load"
harness = false
required-features = ["load-test", "e2e"]

[[test]]
name = "integration_qdrant"
path = "tests/integration_qdrant.rs"
required-features = ["integration-tests"]

[[test]]
name = "integration_engine"
path = "tests/integration_engine.rs"
required-features = ["integration-tests"]

[[test]]
name = "integration_elasticsearch"
path = "tests/integration_elasticsearch.rs"
required-features = ["integration-tests"]

[[test]]
name = "integration_opensearch"
path = "tests/integration_opensearch.rs"
required-features = ["integration-tests"]

[[test]]
name = "integration_singleflight"
path = "tests/integration_singleflight.rs"
required-features = ["integration-tests"]

[[test]]
name = "integration_pgvector"
path = "tests/integration_pgvector.rs"
required-features = ["integration-tests", "pgvector"]

[[test]]
name = "integration_meilisearch"
path = "tests/integration_meilisearch.rs"
required-features = ["integration-tests"]

[[test]]
name = "integration_context_config"
path = "tests/integration_context_config.rs"
required-features = ["integration-tests"]

[[test]]
name = "integration_cascade"
path = "tests/integration_cascade.rs"
required-features = ["integration-tests"]

[[test]]
name = "integration_circuit"
path = "tests/integration_circuit.rs"
required-features = ["integration-tests"]

[[test]]
name = "integration_metrics"
path = "tests/integration_metrics.rs"
required-features = ["integration-tests"]

[[test]]
name = "integration_milvus"
path = "tests/integration_milvus.rs"
required-features = ["integration-tests"]

[[test]]
name = "integration_pinecone"
path = "tests/integration_pinecone.rs"
required-features = ["integration-tests"]

[[test]]
name = "integration_peer"
path = "tests/integration_peer.rs"
required-features = ["integration-tests"]

[[test]]
name = "integration_batch"
path = "tests/integration_batch.rs"
required-features = ["integration-tests"]

[[bench]]
name = "core_ops"
harness = false

[[bench]]
name = "cascade_scope"
harness = false

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tarpaulin_include)', 'cfg(feature, values("dhat-heap"))', 'cfg(tokio_unstable)'] }

[lints.clippy]
suspicious = "warn"
style = "warn"
complexity = "warn"
perf = "warn"
unwrap_used = "warn"
expect_used = "warn"
panic = "warn"
indexing_slicing = "warn"
arithmetic_side_effects = "warn"

[profile.dev]
debug = "line-tables-only"
split-debuginfo = "unpacked"

[profile.dev.package."*"]
opt-level = 1

[profile.dev.build-override]
opt-level = 1

[profile.release]
lto = "fat"
codegen-units = 1
strip = "symbols"
panic = "abort"

[profile.profiling]
inherits = "release"
debug = 2
strip = false
lto = false