Skip to main content
A tool call is one tool execution inside a run. In Lemma custom instrumentation, tool calls are child spans created around each tool invocation.

Required

Create a child span for each tool call and include the tool name:
import { trace } from "@opentelemetry/api";

const tracer = trace.getTracer("my-agent");

async function callWeatherTool(city: string) {
  return tracer.startActiveSpan("tool.call", async (toolSpan) => {
    toolSpan.setAttribute("tool.name", "get_weather");
    toolSpan.setAttribute("tool.args", JSON.stringify({ city }));

    const result = await getWeather(city);
    toolSpan.setAttribute("tool.result", JSON.stringify(result));
    toolSpan.end();
    return result;
  });
}

Optional tool-call data

Recommended attributes:
  • tool.name
  • tool.args
  • tool.result
  • tool.status
  • tool.duration_ms (if you compute it separately)
For large payloads, store only summary fields (for example, item counts or IDs) and avoid full sensitive bodies.

Mark a tool call as failed

await tracer.startActiveSpan("tool.call", async (toolSpan) => {
  toolSpan.setAttribute("tool.name", "get_weather");
  try {
    return await getWeather("London");
  } catch (error) {
    toolSpan.recordException(error as Error);
    toolSpan.setAttribute("tool.status", "error");
    throw error;
  } finally {
    toolSpan.end();
  }
});

Dashboard outcome

Tool-call spans appear under the active run and show:
  • which tool was used
  • what arguments were passed
  • what result was returned
  • whether the tool failed
This makes bad arguments, retries, and unnecessary calls easy to spot.

Next Steps