Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 19 additions & 0 deletions litellm-rust/ADDING_A_PROVIDER.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,23 @@ Three layers, same for every route (see `ocr` and `realtime` as references):
2. **Provider config (pure)** — `crates/providers/src/<provider>/<route>/transformation.rs`: implement that trait as a `const <PROVIDER>_<ROUTE>_CONFIG`, mirroring the Python provider tree. Add parity unit tests.
3. **HTTP / transport (the host)** — `crates/providers/src/<route>.rs` (e.g. `ocr.rs`, `realtime.rs`): the callable fn (`run_ocr`, `realtime`). It resolves the key, builds the auth header, builds URL + transforms via the config, then does the network call. This is the only layer allowed to do I/O.

## Coding standards

Before writing new logic, look for an existing base to extend. When a change is
“the same behavior for one more provider/endpoint/integration”, the codebase
almost always already has a shared abstraction for it (for example, provider
`BaseConfig` transformation classes in `litellm/llms/base_llm/`, shared
helpers in `litellm_core_utils/`, typed request/response models, or factory
functions). Find it first with a search, then add the new variant by inheriting
from or composing that base, overriding only what genuinely differs (model
name, parameter mapping, or auth).

Never copy an existing implementation and edit it in place, and never hand-roll
a parallel version of logic a base already provides. If you catch yourself
writing a second copy of a pattern that exists twice already, stop and extract a
base instead: put the shared shape in one place and make both call sites thin
variants of it. The test for a good abstraction is that adding the next provider
is a few declarative lines, not a new file of duplicated flow. Only diverge from
the base when behavior is genuinely different, and say so explicitly in the PR.
Comment on lines +9 to +26

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Identical block duplicated across both files

The "Coding standards" section added here is character-for-character identical to the "Provider Coding Standards" block added to CLAUDE.md. If this guidance ever needs to change, both files must be updated in sync, and they will inevitably drift. Consider either keeping the canonical text in one file and having the other reference it (e.g., "See CLAUDE.md for provider coding standards"), or consolidating the two files so there is a single source of truth.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!


**Calling:** the host invokes the route fn — the Python bridge calls `run_ocr`; the `ai-gateway` server calls `realtime`. Register new modules in `lib.rs` / `mod.rs`, then run `cargo fmt && cargo clippy --workspace -- -D warnings && cargo test --workspace`.
19 changes: 19 additions & 0 deletions litellm-rust/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,25 @@

This file defines the rules for Rust work in LiteLLM.

## Provider Coding Standards

Before writing new logic, look for an existing base to extend. When a change is
“the same behavior for one more provider/endpoint/integration”, the codebase
almost always already has a shared abstraction for it (for example, provider
`BaseConfig` transformation classes in `litellm/llms/base_llm/`, shared
helpers in `litellm_core_utils/`, typed request/response models, or factory
functions). Find it first with a search, then add the new variant by inheriting
from or composing that base, overriding only what genuinely differs (model
name, parameter mapping, or auth).

Never copy an existing implementation and edit it in place, and never hand-roll
a parallel version of logic a base already provides. If you catch yourself
writing a second copy of a pattern that exists twice already, stop and extract a
base instead: put the shared shape in one place and make both call sites thin
variants of it. The test for a good abstraction is that adding the next provider
is a few declarative lines, not a new file of duplicated flow. Only diverge from
the base when behavior is genuinely different, and say so explicitly in the PR.
Comment on lines +5 to +22

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Python paths referenced in Rust-specific documentation

The guidance references litellm/llms/base_llm/ and litellm_core_utils/ — Python filesystem paths — inside CLAUDE.md, which is declared as the guide for Rust work. A Rust contributor searching for BaseConfig in those paths will find Python classes that cannot be inherited or composed from Rust. It would be clearer to either state these paths as conceptual models to mirror (not reuse directly), or point to the corresponding Rust equivalents (e.g., the traits in crates/core/src/<route>/transformation.rs).


## Crates (exactly three — see AGENTS.md)

`litellm-core` describes work; `litellm-ai-gateway` executes it; `litellm-python-bridge`
Expand Down
Loading