LiteLLM and gateways

LiteLLM's SDK is recorded because it dispatches through the real provider clients. Proxies and gateways work too, with one attribution caveat.

Gateways sit below the SDK rather than beside it. There are two shapes and they behave differently.

LiteLLM as a library

litellm.completion() dispatches OpenAI-family models through the real openai client, so the calls are recorded. Verified in the SDK's test suite against real LiteLLM.

import litellm
import capsera

capsera.init(api_key=os.environ["CAPSERA_API_KEY"])


@capsera.agent("router", team="platform")
def ask(prompt: str) -> str:
    response = litellm.completion(
        model="openai/gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}],
    )
    return response.choices[0].message.content

LiteLLM is on the frame-skip list, so caller_file points at your function rather than litellm/llms/openai/openai.py. This needed handling specifically, because LiteLLM's dispatch module lives at site-packages/litellm/llms/openai/openai.py, which does not match the site-packages/openai skip fragment.

LiteLLM supports many providers through its own HTTP handlers rather than a vendor SDK. Where it does, there is no patched client in the path and the call is not recorded. OpenAI-family models are the verified path. For anything else, use record().

LiteLLM Proxy and other OpenAI-compatible gateways

A gateway running as a separate service is simpler. Point the openai client at it:

client = openai.OpenAI(
    base_url="https://gateway.internal.example.com/v1",
    api_key=os.environ["GATEWAY_KEY"],
)

Coverage is full, because this is the OpenAI client.

Two things affect what is recorded.

Provider labelling. The SDK identifies providers by base URL, and a private gateway host is not in its map, so the label falls back to the model's catalogued provider. A call through your gateway using gpt-4o-mini records openai, which is correct about the model and says nothing about the gateway. Report the host and it will be added to the map.

Model aliases. Gateways often expose their own names, such as prod-fast or cheap-tier, that resolve to a real model upstream. An alias cannot be priced.

The SDK prefers the model reported in the response over the one requested. If your gateway rewrites the response's model field to the upstream model, cost is correct automatically. If it echoes the alias, you will see a fallback-estimate warning:

capsera: no pricing found for model 'prod-fast' — using fallback estimate

Configuring the gateway to report the resolved model is the single change that makes gateway cost accurate.

Why not integrate at the gateway instead

A gateway sees requests from one API key. It cannot know that a call came from your planner node rather than your summarizer, because nothing in the HTTP request carries that. The information exists only in the calling process's stack, which is why the SDK runs in-process.

The two compose. The gateway handles failover, key management, and caching. Capsera handles attribution and enforcement.