Skip to main content

Auto-instrumentation matrix

The Eden SDKs patch the most popular LLM SDKs at import time (Python) or wrap client instances (TypeScript), so "trace my agent" is a one-liner. The matrix below lists every framework the SDKs know how to wrap and what gets recorded.

Three-tier model

TierWhenMechanism
1 — NativeFramework listed beloweden.instrument() / wrap*
2 — UniversalCustom agent, raw HTTP, OTel-only frameworksHTTP capture, OTel bridge, logging forwarder
3 — ManualFull control@trace_agent / traceAgent

See Connect any agent for the full decision tree.

By SDK

Python (eden-sdk)

FrameworkMechanismRecorded
openaiMonkey-patch sync/async chat.completions.createmodel, prompt, response, tokens, latency; streaming TTFT/ITL/TPOT
anthropicMonkey-patch sync/async messages.createmodel, messages, response, tokens, cache read/write tokens
langchainGlobal BaseCallbackHandler via langchain_core.callbackschain/agent/tool spans across the execution tree
llama_indexBaseSpanHandler on Settings.callback_managerspan name, query/response, duration
crewaiDefault step_callback + task_callback on Crewstep thought/tool/result, task name/outcome
autogenGlobal reply hook on ConversableAgentspeaker, recipient, message contents
pydantic_aiPatch Agent.run / run_syncagent name, input/output, duration, source_format: pydantic-ai
bedrockboto3 bedrock-runtime API call wrapmodel, request/response, tokens, latency
geminigoogle.generativeai generate_content wrapmodel, prompt, response, tokens, latency
mastraNo-op (use TypeScript SDK)

Tier 2 — Python universal fallback

MechanismPatchesRecorded
HTTP capturehttpx for OpenAI/Anthropic/Ollama URL patternsmodel, request/response bodies (truncated), latency
OTel bridgeeden_sdk.otel.configure_exporter()spans forwarded with framework attribution
Logging forwardereden_sdk.logging_forwarder.install_logging()event_type: log events

TypeScript (@eden-ai/sdk)

The TypeScript SDK wraps client instances (Proxy-based), not global module exports. Call wrap* on the object you already use in production.

FrameworkWrapperRecorded
openaiwrapOpenAI(client)model, prompt, response, tokens; streaming metrics + chunk replay
anthropicwrapAnthropic(client)model, messages, response, tokens, cache tokens
ai (Vercel AI)wrapVercelAI(aiModule) — pass import * as ai from "ai"model, prompt/response from generateText / streamText
langchainwrapLangChain(chatModelInstance)invoke/call/stream/batch on any chat model
mastrawrapMastra(mastraInstance)agent/workflow name, step outcomes, source_format: mastra

Tier 2 — TypeScript universal fallback

MechanismPatchesRecorded
HTTP capturefetch / undici for known LLM URLsmodel, bodies (truncated), latency
OTel bridgeconfigureOtelExporter() from @eden-ai/sdkspans with framework attribution
Logging forwarderSDK logging shimevent_type: log events

What gets recorded, per call

Every instrumented call emits a single framework ingestion event with these standard fields:

FieldSourceAlways?
event_type"framework"yes
source_format"openai" | "anthropic" | "vercel-ai" | "langchain" | "pydantic-ai" | "mastra" | "http-capture" | "custom"yes
modelFrom requestyes
promptLast user message (truncated at 8 KiB)yes
responseAssistant message (truncated at 8 KiB)yes
input_tokensusage.prompt_tokensif available
output_tokensusage.completion_tokensif available
cost_usdComputed from model_pricing tableif model known
duration_msWrapped start→finishyes
outcome"success" | "error" | "timeout"yes
errorTruncated error message if outcome != "success"conditional
trace_idFrom active span, or generatedyes
parent_span_idFrom active spanif nested
attributesAnything you set via set_attribute()optional

The portal renders this as the timeline view; trace_id ties sibling calls into one agent graph.

Custom frameworks

If your framework isn't on the list, you have two options:

1. Manual ingestion

Send a custom event with whatever fields matter to you:

from eden_sdk import EventBuilder, Outcome

await eden.trace(
EventBuilder.agent_call("my_tool_call")
.with_attribute("tool", "search")
.with_attribute("query", q)
.with_outcome(Outcome.Success)
)
import { traceAgent } from "@eden-ai/sdk";

class MyTool {
@traceAgent({ name: "search" })
async search(q: string) { /* ... */ }
}

2. Wire-format ingestion

Send the raw event directly:

curl -X POST "https://api.edenobservability.com/orgs/org_abc/ingest/custom" \
-H "Authorization: Bearer sk_eden_..." \
-H "Content-Type: application/json" \
-d '{
"events": [{
"name": "my_custom_event",
"outcome": "success",
"duration_ms": 137,
"attributes": { "anything": "you want" }
}]
}'

See the Ingestion reference for the full schema.

Disabling instrumentation

# Python — reverses monkey-patches
eden.uninstrument() # undo everything
eden.uninstrument("openai") # undo just one framework
eden.uninstrument("http_capture") # undo httpx capture
// TypeScript — create a fresh unwrapped client (no global uninstrument)
const raw = new OpenAI();
// do not pass through wrapOpenAI()

// Or disable telemetry entirely:
configure({ disabled: true });

For tests, combine configure({ disabled: true }) or EDEN_DISABLED=1 (Python) with unwrapped clients so no events ship.