litellm/litellm-rust/AGENTS.md
devin-ai-integration[bot] 268e8bb735
refactor(rust): share anthropic types, request helpers, and streaming contracts across crates (#43426)
* refactor(rust): standardize Azure Messages module path

* docs(rust): define shared types crate boundaries

* refactor(rust): share request helpers and type Anthropic blocks

* docs(rust): format shared type invariants as bullets

* test(rust): parameterize repeated cases with rstest

* refactor(rust): move Responses transform result into llms

* fix(anthropic): validate chat and batch responses

* docs(rust): clarify API format ownership boundaries

* docs: clarify Rust error message construction

* refactor(auth): keep shared Rust errors provider-neutral

* refactor(rust): separate format contracts from provider policy

* fix(rust): type Anthropic chat response text collection

* fix(rust): pass audio secret sources through hosts

* fix(rust): unblock batch lint and OCR error assertions

* test(rust): assert response failures at the adapter boundary

* refactor(rust): declare error messages with typed context

* wip

* fix(rust): adapt Bedrock error details

* style(rust): cargo fmt bedrock audio transcription

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(rust): adapt tests and dead code to typed error details

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(rust): keep converse error contracts and read env secrets without litellm

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* ci(rust): raise the native wheel size gate to 45 MB

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(rust): tolerate missing usage in converse responses on the transcription route

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Yujong Lee <yujong@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-27 14:53:12 -07:00

2.9 KiB

Rust workspace rules

Test placement

  • Never create a tests.rs (or test.rs) file under src/, and never #[path = "tests.rs"] mod tests;
  • A test that reaches private items lives inline, in a #[cfg(test)] mod tests { ... } at the bottom of the file that owns those items
  • A test that only uses the crate's public API lives in crates/<crate>/tests/<subject>.rs, next to src/
  • Split a mixed test file along that line instead of widening visibility to move it
  • A test for another crate's item belongs in that crate, not in a downstream one
  • Never set autotests = false or hand-list [[test]] targets; every file directly under tests/ is discovered by cargo, and a shared helper goes in tests/<name>/mod.rs or tests/<subject>/support.rs so it is not picked up as a test crate of its own

Test fixtures and cases

Use #[rstest] for new and updated tests and #[fixture] for reusable setup, injected through typed test arguments. Express input variations as named #[case::name(...)] cases instead of loops or duplicated tests so each failure identifies its case. Keep behavior assertions in the test body and fixtures focused on setup. Use the workspace rstest dependency

Error definitions

  • A crate's errors live in src/error.rs, defined with thiserror, and re-exported from lib.rs
  • Put message templates in the variant's #[error(...)] declaration. Callers pass only the small typed arguments needed to fill them, never Error::Variant(format!(...)) or a preformatted message. Keep the smallest set of neutral variants that callers need to distinguish; different wording or providers do not justify new variants
  • Default to one top-level Error enum per crate, with one variant per failure mode and a #[error(...)] message on each. A failure mode is something a caller handles differently (phase, status code, retry, a message Python parity pins exactly); failures no caller tells apart share one variant and differ only in its message
  • Keep shared error enums minimal and provider-neutral. Provider names, credential types, configuration fields, and setup guidance belong in caller-supplied data, not dedicated variants or hardcoded shared messages. Reuse a variant for the same failure mode across providers, such as MissingApiBase { provider: "Azure", guidance: "..." }. An exact parity message does not justify a provider-specific variant when caller-supplied context can preserve it
  • Wrap a lower-level error as a variant with #[from] or #[source] instead of flattening it to a string
  • Exception: split into separate types when different functions fail in disjoint ways, especially when different callers see them. A shared enum would force every caller to match variants its function can never return
  • Name a split type after what went wrong (a unit struct is fine for a single failure mode), not after the function that returns it