# Frameworks overview

The three integration tiers — native OTel, provider patches, and framework patches.

---

TokenJam is OTel-native, so any framework that emits OpenTelemetry works with no integration code. For everything else, a one-line patch does it. There are three tiers, listed from least to most opinionated.

1. **Native OTel.** The agent already speaks OpenTelemetry. Point its exporter at `tj serve`.
2. **Provider patches.** Intercept at the LLM API level. Framework-agnostic.
3. **Framework patches.** Instrument a higher-level framework's own tool and LLM abstractions.

## Native OTel

If a framework ships an OTel exporter, point it at `tj serve` and you are done. No SDK install, no code.

```bash
export OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:7391
```

| Framework | Notes |
|---|---|
| Claude Code | Built-in. `tj init --claude-code` |
| OpenAI Codex | Built-in. `tj init --codex` |
| OpenClaw | Built-in. `diagnostics-otel` plugin |
| LlamaIndex | `opentelemetry-instrumentation-llama-index` |
| OpenAI Agents SDK | Native OTel exporter |
| Google ADK | Native OTel exporter |
| Strands Agent SDK (AWS) | Native OTel exporter |
| Haystack | Native OTel exporter |
| Pydantic AI | Native OTel exporter |
| Semantic Kernel | Native OTel exporter |

**LlamaIndex** and the **OpenAI Agents SDK** have thin tj wrappers (`patch_llamaindex`, `patch_openai_agents`) over their native OTel support if you would rather import a patch than set an env var, but the zero-code path above is enough for both.

## Provider patches (Python)

Provider patches intercept the API client directly, so they work inside any orchestrator.

```python
from tokenjam.sdk.integrations.anthropic import patch_anthropic   # Messages.create + streaming
from tokenjam.sdk.integrations.openai    import patch_openai      # chat completions
from tokenjam.sdk.integrations.gemini    import patch_gemini      # GenerativeModel
from tokenjam.sdk.integrations.bedrock   import patch_bedrock     # boto3 invoke_model / invoke_agent
from tokenjam.sdk.integrations.litellm   import patch_litellm     # 100+ providers via LiteLLM
```

`patch_litellm()` covers every provider LiteLLM routes to, so if you use LiteLLM you do not need the individual patches. See [LiteLLM](/docs/litellm).

OpenAI-compatible providers (Groq, Together, Fireworks, xAI, Azure OpenAI) work through `patch_openai(base_url=...)`.

## Framework patches (Python)

Framework patches instrument a framework's own tool and LLM abstractions. Each is a one-line call at startup, and each has its own how-to page.

| Framework | Patch | How to instrument |
|---|---|---|
| LangChain / LangGraph | `patch_langchain` / `patch_langgraph` | [LangChain & LangGraph](/docs/langchain) |
| CrewAI | `patch_crewai` | [CrewAI](/docs/crewai) |
| AutoGen | `patch_autogen` | [AutoGen](/docs/autogen) |
| LiteLLM | `patch_litellm` | [LiteLLM](/docs/litellm) |

Spans nest naturally. A CrewAI task that calls a LangChain tool produces a parent-child tree, with the underlying API call as a leaf. Patches compose with the provider patches too, and inner spans are de-duplicated so nothing is counted twice.

## TypeScript

The TypeScript SDK ships the manual `SpanBuilder` interface today. Framework patches for LangChain JS, the OpenAI Agents SDK, the Vercel AI SDK, and Mastra are tracked in the [OSS issue tracker](https://github.com/Metabuilder-Labs/tokenjam/issues). See the [TypeScript SDK](/docs/typescript-sdk) page for `TjClient` and `SpanBuilder`.

## NemoClaw

NemoClaw is a sandbox runtime, not a framework you instrument. TokenJam connects to its Gateway WebSocket and turns sandbox events into spans and alerts. See [NemoClaw integration](/docs/nemoclaw).