LLM Provider Support
Which LLM client libraries mubit.learn auto-instruments, and what each integration captures.
mubit.learn.init() patches your existing LLM client classes in place — no wrapper code required. The table below lists the libraries that are auto-instrumented today.
| Provider | Python | Node.js |
|---|---|---|
| OpenAI | openai | openai |
| Anthropic | anthropic | @anthropic-ai/sdk |
| Google Gemini | google-generativeai | @google/generative-ai |
| LiteLLM | litellm | — |
| Vercel AI SDK | — | ai (via @mubit-ai/ai-sdk middleware) |
What gets patched is concrete: the constructor of the provider's client class. Subsequent calls to .messages.create(), .chat.completions.create(), etc. flow through MuBit before and after the network call.
What auto-instrumentation captures
For every wrapped call:
- Pre-call: relevant lessons retrieved from MuBit and injected into the system message (or as a synthetic system message if none exists).
- The call itself: sent to the provider unchanged.
- Post-call: the request, response, model name, latency, and token usage are recorded as a
tracein the active session.
On session end (or auto_reflect=True), reflect() runs and extracts new lessons from the session's traces.
Verifying instrumentation
import anthropic, mubit.learn
mubit.learn.init(api_key="mbt_...", agent_id="my-agent")
client = anthropic.Anthropic()
print(client._mubit_learn_wrapped) # TrueA wrapped client carries _mubit_learn_wrapped = True. If False, the patch didn't take — usually because mubit.learn.init() was called after the client was constructed. Patch first, instantiate second.
Turning instrumentation off
There is no per-call opt-out today. To stop capturing entirely, call mubit.learn.uninstrument() — it restores the original LLM client behavior so subsequent calls flow straight to the provider:
import mubit.learn
mubit.learn.uninstrument() # global — restores unpatched client behavior
resp = anthropic.Anthropic().messages.create(...) # not capturedIf you only need a few calls recorded (raw HTTP, an unsupported library, or a utility call you want logged on your terms), skip init()-style auto-instrumentation for those and capture them explicitly:
import mubit.learn
mubit.learn.capture(
messages=[{"role": "user", "content": "estimate cost"}],
response=resp_text,
model="claude-3-5-sonnet",
)A scoped per-call bypass context manager is not available yet. If you need system-utility calls (cost estimates, eval pipelines, retries) excluded from evidence without disabling instrumentation globally, open a feature request against mubit-sdk.
Provider-specific notes
OpenAI
- Both sync (
OpenAI) and async (AsyncOpenAI) clients are patched. - Streaming responses are captured incrementally; the full assembled output is recorded.
- Tool/function call traces include the tool name and arguments.
Anthropic
- Both sync (
Anthropic) and async (AsyncAnthropic) clients are patched. messages.createis wrapped; the deprecatedcompletions.createis not.- Tool-use blocks are captured as part of the response trace.
Google Gemini
- The
google-generativeaiclient is patched on first import afterinit(). - Multi-turn
ChatSessioninstances inherit instrumentation from their parent client.
LiteLLM (Python only)
- LiteLLM's unified
completion()andacompletion()calls are patched. - The provider-specific client behind LiteLLM is not double-wrapped.
Vercel AI SDK (Node only)
- Use
mubitMemoryMiddlewarefrom@mubit-ai/ai-sdkwithwrapLanguageModel()rather thanlearn.init(). The NodelearnAPI auto-instruments the lower-level provider SDKs but not the AI SDK abstraction. - Full example: see Framework integrations → Vercel AI SDK.
Adding a provider
Open an issue or a PR against mubit-sdk with the client class name and the call surface that should be wrapped (constructor + the methods that hit the network). Most providers take less than 50 lines of patch code; the existing per-provider patches (mubit/learn/_openai_learn.py, mubit/learn/_anthropic_learn.py) are the reference pattern to follow.