refactor(litellm-rust): 3-crate layer structure (core / ai-gateway / python-bridge) + AGENTS.md + enforcement test - #31143
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Greptile SummaryThis PR restructures
Confidence Score: 4/5Safe to merge — no logic changes, all moves are mechanical renames with updated import paths confirmed by the passing test suite. The refactor is purely mechanical with no runtime behavior changes. Two minor follow-ups remain: stale
|
| Filename | Overview |
|---|---|
| litellm-rust/Cargo.toml | Workspace manifest updated: crates/providers to crates/ai-gateway, all references consistent with the rename. |
| litellm-rust/crates/core/tests/workspace_crate_allowlist.rs | New enforcement test using a hand-rolled TOML parser; works correctly for the current fixed file layout but would silently mismatch if a members key appears in a non-[workspace] section before the real one. |
| litellm-rust/crates/ai-gateway/src/ocr.rs | Renamed from providers; import paths updated to litellm_core::providers::mistral — logic unchanged. |
| litellm-rust/crates/ai-gateway/src/realtime.rs | Renamed from providers; import path for OPENAI_REALTIME_CONFIG updated; doc comment and ignored-test command updated to match new crate name. |
| litellm-rust/crates/python-bridge/CLAUDE.md | Unchanged file with a stale reference to the deleted litellm_providers crate name that was not updated alongside this rename. |
| litellm-rust/.cargo/config.toml | New macOS-only config.toml adding the standard pyo3 -undefined dynamic_lookup linker flag for both x86_64 and arm64; no effect on Linux/CI. |
| litellm-rust/crates/providers/CLAUDE.md | Deleted along with the providers crate; the detailed test requirements and implementation rules it contained are not all carried over to the new AGENTS.md files. |
Reviews (1): Last reviewed commit: "docs(litellm-rust): add litellm-python-b..." | Re-trigger Greptile
| // Match `members = [` possibly with entries on the same line. | ||
| if let Some(rest) = trimmed.strip_prefix("members") { | ||
| let rest = rest.trim_start(); | ||
| if let Some(rest) = rest.strip_prefix('=') { | ||
| in_members = true; | ||
| collect_quoted(rest, &mut members); | ||
| if rest.contains(']') { | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| continue; |
There was a problem hiding this comment.
Hand-rolled parser lacks section-scope tracking
parse_workspace_members matches the first line starting with members in the entire file, regardless of which TOML section it is in. If a new section (e.g., [workspace.metadata], [lints.workspace], or a tool section) ever gains a members = [...] key that appears before [workspace], the test would silently validate the wrong list and fail to catch a real workspace-membership change. Adding a check that resets in_members when a new [section] header is encountered would make the parser section-aware.
|
Superseded — staging has since added the |
Relevant issues
Restructures
litellm-rustso the crate boundaries match what they actually are — layers, not routes — before more providers/routes land. This is the shape every mature Rust gateway uses (TensorZero, ruff, uv): a pure core, an I/O host, and the binding.Pre-Submission checklist
cargo test --workspace→ 27 passed, 1 ignored (the ignored one is the pre-existing live-OpenAI realtime test)cargo clippy --workspace --all-targets -- -D warnings,cargo fmt --all --check,cargo build --workspaceall greenType
🧹 Refactoring
Changes
Collapses
{core, providers, python-bridge}into three layer crates:litellm-coreproviders/)litellm-ai-gatewayrun_ocr,realtime)litellm-python-bridgeDependency line (acyclic):
litellm-core ← litellm-ai-gateway ← litellm-python-bridgeWhat moved:
mistral,openai)providers/→core/src/providers/(they're pure)ocr.rsrun_ocr,realtime.rs)providers/→ newai-gateway/cratepython-bridgenow importslitellm_ai_gateway::ocr::run_ocrproviderscrate deletedWhy: the pure/I-O split is now compiler-enforced —
coredoesn't listreqwest/tokio, so it can't do network I/O. Faster incremental builds (change one layer, rebuild one layer) and the layering can't rot into a cycle.Guardrails added:
litellm-rust/AGENTS.md+ per-crateAGENTS.mddocumenting the rule: a crate is a layer; routes/providers are modules; add a crate only on a real trigger (separate artifact / proc-macro / shared foundation / publishable).crates/core/tests/workspace_crate_allowlist.rs— fails CI if the crate set ever drifts from the 3 allowlisted crates, so humans and agents get told the rule.Note: added
litellm-rust/.cargo/config.tomlwith the standard pyo3-undefined dynamic_lookupflag (apple-darwin only) socargo build --workspacelinks the cdylib locally without maturin. macOS-only, no effect on Linux/CI or crate logic.