Repository navigation
feat(evaluations): return tool errors to the model and mark eval spans for viewers - #203
Merged
ccschmitz-launchdarkly merged 1 commit intoNov 5, 2026
Conversation
…s for viewers A throwing tool in an offline eval row now answers the model with "Error: <type>: <message>" instead of failing the row; the trajectory recorder still records the error. Row roots set gen_ai.operation.name=invoke_workflow, and criterion results carry launchdarkly.evaluation.score.min/max (0-1). Ports launchdarkly/python-ai-sdk#271.
ccschmitz-launchdarkly
marked this pull request as ready for review
November 4, 2026 17:43
donei003
approved these changes
Nov 4, 2026
ccschmitz-launchdarkly
deleted the
ccschmitz/eval-tool-errors-row-envelope
branch
November 5, 2026 01:21
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
This brings launchdarkly/python-ai-sdk#271 to TypeScript. Two problems came up running offline evals against staging. A tool that threw failed the whole row, so an eval couldn't test how an agent recovers from a broken tool. The Trace panel also couldn't show a failed row as a failed run, or show a score against its range.
Summary
evaluations-tools.tsreturnToolErrors: wraps the row's tools outside the trajectory recorder. A throwing tool (sync, async, or one that returns a promise) returns"Error: <type>: <message>"to the model and the row continues. Sync tools stay sync. The recorder still logs the call as an error, so judges andexecute_toolspans see it. Native tools pass through.EvalToolconstructor docs: the implementation gets one object of the model's arguments. What it returns goes back as the tool result, and a throw becomes the error result.recordEvaluationOnSpantakes an optionalscoreRange. Offline criteria pass[0, 1], which addslaunchdarkly.evaluation.score.min/.maxtogen_ai.evaluation.resultand to the span. Online judges are unchanged.startRowSpansetsgen_ai.operation.name=invoke_workflow.Testing
evaluations-tool-errors.test.ts: sync and async throws, the recorder still records the error, working and native tools are unchanged, and a non-Errorthrow. Span tests now assertinvoke_workflowon the row root and the range on result events. The existing failed-tool test asserts the handler receives the error result.packages/client: 2,194 tests pass. Typecheck,biome check, build andyarn api:checkare clean.Notes
invoke_workflowroot as an extra LLM call.Note
Overview
Offline eval rows no longer abort when an inline tool throws.
returnToolErrorswraps each row’s tool map (outside the trajectory recorder) so sync throws, async rejections, and promise failures become"Error: <type>: <message>"tool results for the handler/model while the recorder still logstool_erroronexecute_toolspans. Handler and model failures still fail the row.Trace UX improvements: the dataset row root now sets
gen_ai.operation.name=invoke_workflow, and offline criterion results addlaunchdarkly.evaluation.score.min/.max(0–1) ongen_ai.evaluation.resultevents and mirrored span attributes via an optionalscoreRangeonrecordEvaluationOnSpan. Online judges are unchanged.EvalTooldocs now describe the single-args-object calling convention and throw-to-error-result behavior. New unit tests coverreturnToolErrors/toolErrorResult; span tests assert the envelope operation name, score range (including when content capture is off), and that handlers receive the error string on failed tools.Reviewed by Cursor Bugbot for commit fb750ca. Bugbot is set up for automated code reviews on this repo. Configure here.