Instrumented apps
If the app is instrumented with Tracevell (it callsLaminar.initialize()), there’s nothing to convert.
During a run, the Tracevell plugin sets LMNR_TRAJECTORY_PATH=/logs/agent/trajectory.json in the agent’s environment. When this variable is set, the SDK writes the app’s spans to that file instead of sending them to Tracevell. The plugin then attaches them to the trial’s trace: every LLM call with its tokens and cost, and tool calls as TOOL spans.
- The app needs no Tracevell API key and no network access to Tracevell.
- It works with the Python SDK (
lmnr0.8.4 and later) and the TypeScript SDK (@lmnr-ai/lmnr0.8.54 and later).
Apps without instrumentation
If the app isn’t instrumented, you can rebuild the trajectory from its own history. Most products already store the conversation somewhere, for the UI, for audit, or as agent memory: message tables, run and step tables, LangGraph checkpointers, or JSONL transcripts. After the driver finishes, including when it ends asfailed or timeout (a partial trajectory is often the most useful one), run an exporter that reads this case’s history and writes /logs/agent/trajectory.json in Harbor’s ATIF format:
/logs/agent/trajectory.json
step_id, a source (user, agent, or system), a message, and a timestamp. Tool calls and their results belong to the agent step that made them. Stored history usually lacks token counts and costs, so leave metrics out instead of estimating it, and use notes to say where the trajectory came from.
Next steps
Drive and grade a trial
Write the driver and the verifier, and choose where the verifier runs.
Read a failing trial
Open a low-scoring datapoint and read the app’s run as a transcript.
Track failures with Signals
Detect a failure in production traces, then turn the flagged traces into cases.
Troubleshooting
Fixes for stale images, missing env vars, and empty traces.