Repository navigation
Add offline and online guardrails and scored evals - #10
Merged
Merged
Conversation
The same guardrail definition checks recorded traces and live message or tool-call streams. Evals register with a decorator and run from pytest, and both results appear in the HTML report. Co-authored-by: Dor Ingber <Doringber@users.noreply.github.com>
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.
Summary
Guardrails and evals follow the same pytest style as the existing assertions and scorers. One guardrail definition runs offline against a recorded trace and online against a live stream. Evals are named scores with a pass threshold. Both show up in the HTML report.
Guardrails
Guardrailis a small base class.@guardrailturns a function into one. Hooks areon_message,on_tool_call, andon_trace.check_guardrails(result, ...),result.assert_guardrails(...), or theagent_guardrails.checkfixture.GuardrailMonitor.handle/on_message/on_tool_callas events arrive. Trace rules run infinish().fail_fast=TrueraisesGuardrailViolationError. Theagent_guardrails.monitorfixture records the outcome, including when the stream aborts.NoProfanityGuardrail(profanity or any disallowed language) andRequiredFinalToolGuardrail, plusmust_open_pull_request()for "this flow must open a PR at the end".Evals
Evalplus@eval_caseregisters a scorer. Pass meansscore >= threshold.run_evals,result.assert_evals, or theagent_evalfixture.@pytest.mark.agent_eval("name")selects registered evals.RequiredTermsEvalandRequiredToolsEval.Report
Scenario cards gain Guardrails and Evals sections, using the same details/table layout as assertions. The sections are omitted when a scenario has neither.
Tests
pytest -m "not agent_e2e and not agent_write_action"— 310 passed, coverage 88.88% (threshold 85%). Each built-in guardrail and eval has a known-good trace that passes and a known-bad trace that fails, in both offline and online modes for guardrails.python examples/guardrails_and_evals.pyruns the three README examples.Also: scenario reports now keep
expected_mcp_servers(the writer already passed it), and the HTML tool-flow pytester fixture lives in the test module so it still overridesagent_clienton pytest 9.