Skip to main content
Adapters read the response object returned by an LLM provider SDK and extract a normalized dict of telemetry fields. You pass that dict directly to agentvista.record() or attach it inside an agentvista.run() block — no manual token counting required. Every adapter returns a subset of these fields:
FieldTypeDescription
modelstrModel identifier as returned by the API (e.g. "claude-sonnet-4-6-20260205")
input_tokensintInput (prompt) token count
output_tokensintOutput (completion) token count
total_tokensintSum of input and output tokens
cost_usdfloatEstimated cost in USD, calculated from known model pricing
Fields present in the response are included; fields that cannot be determined are omitted from the dict.

Anthropic

Install with pip install agentvista[anthropic]. AnthropicAdapter works with both sync responses (client.messages.create(...)) and streaming responses (stream.get_final_message()).
import anthropic
import agentvista
from agentvista.adapters.anthropic import AnthropicAdapter

agentvista.init(api_key="av_xxxxx")
adapter = AnthropicAdapter()

client = anthropic.Anthropic()
response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Qualify this lead..."}],
)

telemetry = adapter.extract(response)
# telemetry = {
#   "model": "claude-sonnet-4-6-20260205",
#   "input_tokens": 312,
#   "output_tokens": 87,
#   "total_tokens": 399,
#   "cost_usd": 0.002145,
# }

agentvista.record(agent="lead-qualifier", success=True, **telemetry)
The Anthropic adapter includes cache token counts (cache_creation_input_tokens and cache_read_input_tokens) in the input_tokens total and uses them for accurate cost calculation when prompt caching is active.

OpenAI

Install with pip install agentvista[openai]. OpenAIAdapter handles both the Chat Completions API (client.chat.completions.create) and the Responses API (client.responses.create). It auto-detects which response shape is present.
from openai import OpenAI
import agentvista
from agentvista.adapters.openai import OpenAIAdapter

agentvista.init(api_key="av_xxxxx")
adapter = OpenAIAdapter()
client = OpenAI()

response = client.chat.completions.create(
    model="gpt-4.1",
    messages=[{"role": "user", "content": "Qualify this lead..."}],
)

telemetry = adapter.extract(response)
# telemetry = {
#   "model": "gpt-4.1",
#   "input_tokens": 284,
#   "output_tokens": 93,
#   "total_tokens": 377,
#   "cost_usd": 0.001508,
# }

agentvista.record(agent="lead-qualifier", success=True, **telemetry)
For responses with prompt caching, the adapter reads cached_tokens from the usage details object and uses it to compute an accurate cost estimate.

LangChain

Install langchain-core in addition to agentvista. No extra install extra is required. AgentVistaCallbackHandler is a drop-in LangChain callback handler. Add it to any chain or agent via the callbacks argument and spans are produced automatically — no manual span() calls needed.
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
import agentvista
from agentvista.adapters.langchain import AgentVistaCallbackHandler

agentvista.init(api_key="av_xxxxx")
handler = AgentVistaCallbackHandler(agent_name="lead-qualifier")

llm = ChatOpenAI(model="gpt-4.1")
prompt = ChatPromptTemplate.from_template("Qualify this lead: {lead}")
chain = prompt | llm

# All LLM and chain events are captured automatically
result = chain.invoke({"lead": "Acme Corp, 200 employees"}, config={"callbacks": [handler]})

Span mapping

The handler maps LangChain events to AgentVista span types:
LangChain eventAgentVista span type
on_chain_start / on_chain_endagent
on_llm_start / on_llm_endllm
on_tool_start / on_tool_endtool

Combining with agentvista.run()

When you add the handler inside an existing run() context, its spans become children of that root trace. This lets you attach an outcome signal:
with agentvista.run("lead-qualifier") as r:
    result = chain.invoke(
        {"lead": "Acme Corp"},
        config={"callbacks": [handler]},
    )
    qualified = result.content.strip().lower() == "yes"
    r.set_outcome(success=qualified, outcome="qualified" if qualified else "rejected")
When used without an enclosing run(), the handler auto-creates a trace that is flushed when the outermost chain completes.
If langchain_core is not installed, AgentVistaCallbackHandler is still importable but behaves as a silent no-op. This means you can add the handler to shared code without making langchain_core a hard dependency for all consumers.