Skip to main content

Install

Supported: llama-index-core 0.14.23 to 0.15. 0.14.23 is the release where the workflow stream started carrying the typed agent events this adapter reads. Below it, model names and agent structure both go missing.

Instrument

LlamaIndex’s agent API is async. Every scope works under async with as well as with and produces identical events. instrument() attaches an event handler and a span handler to LlamaIndex’s global dispatcher. Together they make the agent loop visible, not just its model calls.
Without one extra argument on your LLM, every token count in your trace is null. See Token counts below.

Token counts

FunctionAgent calls astream_chat, and llama-index-llms-openai does not send stream_options={"include_usage": True} when it streams. The provider therefore never sends the usage chunk, and there is nothing for any instrumentation to read. This is upstream LlamaIndex behavior. Opt in on your LLM:
Measured on the same run and model: Non-streaming calls (llm.chat, llm.achat) report usage with no configuration. Only the streaming path, which is the default agent path, needs this.

What gets recorded

agent_id is the FunctionAgent.name when you set one, and the workflow class name otherwise. Under an AgentWorkflow, each agent that takes a turn gets its own nested span under the workflow, so a handoff reads as two agents rather than one. Retrieval output is summarized rather than dumped. A retriever returns documents, and storing them in the payload would put your corpus in the events store once per query. The count, score range, and truncated snippets are kept instead.

Example

The agent loop appears in the trace as hook pairs: init_run, setup_agent, run_agent_step, parse_agent_output, call_tool, and aggregate_tool_results. They are the framework’s own loop, so they are hooks rather than agents, which keeps agent_id meaningful.

Name your spans

agent_id is the FunctionAgent.name when you set one, and the workflow class name otherwise.
In an AgentWorkflow, that name is also what each handoff is recorded under:
So agent_id tells you which agent did the work and parent_id tells you which workflow it belonged to. An agent handed control back later opens a second turn rather than reopening its first. Wrap the run to override it, or to group several agents under one parent:
Keep agent_id low cardinality. It is the primary facet on every dashboard surface, so use a role or workflow name, never a UUID or per-run string.

Control the session

This adapter takes no session_id option. The session comes from the enclosing scope, and otherwise a generated uuid4().hex per workflow run:

Options

Human in the loop

Captured when the wait happens inside a tool:
ctx.wait_for_event in a plain workflow step is not captured. The runtime catches the drop before it reaches the dispatcher, so the step exits and re-runs later with no signal to key a pause on. The FunctionAgent pattern, which LlamaIndex documents, waits inside a tool and is captured in full.

Common problems

Add additional_kwargs={"stream_options": {"include_usage": True}} to your LLM. See Token counts.
LlamaIndex has no standard usage field. The adapter tries several known shapes, and an integration that names its counters something new will not match any of them.The raw dict always ships, so check usage in the payload to see what your provider called them.A populated usage alongside empty token columns is deliberate — it beats a confident wrong number.
That is the FunctionAgent loop, one set per iteration. Filter by hook name on the dashboard. These step timings are usually the reason to use this adapter rather than a model-only one.
Check in this order: instrument() ran before the run; there is an async with failproofai_sdk.session(): around the await; llama-index-core is 0.14.23 or newer; FAILPROOFAI_SDK_STRICT=1 set, so a degraded hook raises instead of being swallowed.

Next

How it works

Pairs, ids, session lifecycle, and delivery.

Read a trace

Follow causality through the session you just captured.

Other frameworks

LangGraph, CrewAI, Pydantic AI, and custom agents.