1
Wrap the run
RunAsync starts a trace, runs your agent, then ships the trace to Veval.2
Track each step
Your agent calls
ctx.TrackStepAsync for each LLM call or sub-operation.3
Open the dashboard
The trace appears in your dashboard with full step detail.
RunAsync
Wraps a complete agent invocation. Sends a trace on success or error.Synchronous Python agents
If your Python agent is plain synchronous code, userun and track_step. They take ordinary functions and need no event loop. run sends the trace on the calling thread, so in async code, such as an async def web handler, use run_async instead. C# and Node agents use the async API.
Python
get_trace, replay and run_scenario mirror their _async counterparts. Call them from synchronous code; inside a running event loop, await the _async versions instead. The async methods also accept a plain function as the agent.
Delivery failures
Tracing never breaks your app. If Veval can’t store a trace (wrong API key, quota used up, network down), the SDK logs a warning and your agent’s result comes back as usual. The warning names the HTTP status and, when the API gives one, the reason:
Posting a scenario run or a snapshot comparison to the dashboard fails the same way: a warning, and no exception unless strict mode is on.
This only covers sending results. Calls that return something you asked for throw when they fail, whether or not strict mode is on. That includes
SaveSnapshotAsync, GetSnapshotAsync, JudgeAsync and GetTraceAsync. It also includes RunScenarioAsync when it loads a scenario’s items or a saved trace to replay.
Loading a trace or a scenario’s items throws VevalRequestException (C#) or VevalRequestError (Python, Node). Like the send error, it carries the HTTP status, or null when there was no response. GetTraceAsync returns null only when the trace doesn’t exist. A scenario whose items can’t be loaded throws instead of running zero items and passing.
Throw in tests and CI
In a test suite, a run that never reached the dashboard should fail the build. Turn on strict mode and a failed send throwsVevalSendException (C#) or VevalSendError (Python, Node). The exception carries the HTTP status (StatusCode in C#, status in Python and Node). The status is null when the request got no response, and on the single error a scenario throws for lost item traces (see below).
CompareSnapshotAsync throws if it can’t post the comparison, so you don’t get the diff back. The comparison itself ran; only reporting it failed.
In a scenario, a trace that can’t be stored doesn’t stop the remaining items. Every item runs, then the scenario run is posted. If posting the run fails, strict mode throws that failure. Otherwise, if any item traces were lost, it throws once for all of them: Veval: 3 trace(s) from scenario 'my-scenario' could not be stored. That error has no status; the warnings logged for each item have the details.
VevalExecutionContext
The context object passed into your agent. Do not instantiate directly — Veval creates it for you.TrackStepAsync
Records a single step within a trace.StepHandle metadata keys
handle.SetMeta(key, value) accepts these well-known keys, plus any custom string:
Nested steps
Steps can be nested by passing theStepHandle to a child TrackStepAsync call.
Nested steps appear as a tree in the dashboard, letting you see exactly where time and cost are spent.
Trace-level metadata
Attach arbitrary key/value pairs to the whole trace (not a step):What’s next
Test with replay
Run your agent against recorded traces with no live LLM calls.
Run a scenario
Run your agent against multiple inputs and assert on every result.