evalrun 0.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agents/__init__.py +6 -0
- agents/auditor/__init__.py +13 -0
- agents/auditor/budget_auditor.py +91 -0
- agents/auditor/parser.py +139 -0
- agents/auditor/prompts.py +64 -0
- agents/auditor/schema.py +67 -0
- agents/base.py +20 -0
- agents/reflection/__init__.py +3 -0
- agents/reflection/agent.py +77 -0
- agents/reflection/prompts.py +18 -0
- agents/research/__init__.py +4 -0
- agents/research/agent.py +45 -0
- agents/research/planner.py +52 -0
- agents/research/prompts.py +14 -0
- agents/support/__init__.py +5 -0
- agents/support/triage_agent.py +45 -0
- agents/travel/__init__.py +11 -0
- agents/travel/agent.py +377 -0
- agents/travel/prompts.py +30 -0
- agents/travel/session.py +110 -0
- cli/__init__.py +6 -0
- cli/demo.py +47 -0
- cli/formatter.py +93 -0
- cli/html_reporter.py +647 -0
- cli/main.py +423 -0
- cli/progress.py +38 -0
- cli/resolver.py +99 -0
- evalrun-0.4.0.dist-info/METADATA +268 -0
- evalrun-0.4.0.dist-info/RECORD +100 -0
- evalrun-0.4.0.dist-info/WHEEL +5 -0
- evalrun-0.4.0.dist-info/entry_points.txt +2 -0
- evalrun-0.4.0.dist-info/licenses/LICENSE +0 -0
- evalrun-0.4.0.dist-info/top_level.txt +4 -0
- framework/__init__.py +70 -0
- framework/core/__init__.py +17 -0
- framework/core/adapters.py +118 -0
- framework/core/contracts.py +88 -0
- framework/core/suite.py +44 -0
- framework/evaluation/__init__.py +22 -0
- framework/evaluation/base.py +29 -0
- framework/evaluation/dimensions.py +7 -0
- framework/evaluation/engine.py +110 -0
- framework/evaluation/evaluators/__init__.py +7 -0
- framework/evaluation/evaluators/adaptability.py +27 -0
- framework/evaluation/evaluators/base_llm.py +104 -0
- framework/evaluation/evaluators/constraint.py +27 -0
- framework/evaluation/evaluators/information_accuracy.py +41 -0
- framework/evaluation/evaluators/personalization.py +27 -0
- framework/evaluation/evaluators/planning.py +27 -0
- framework/evaluation/evaluators/support.py +81 -0
- framework/evaluation/prompts/__init__.py +11 -0
- framework/evaluation/prompts/adaptability.py +57 -0
- framework/evaluation/prompts/base.py +52 -0
- framework/evaluation/prompts/constraint.py +41 -0
- framework/evaluation/prompts/information_accuracy.py +79 -0
- framework/evaluation/prompts/personalization.py +57 -0
- framework/evaluation/prompts/planning.py +61 -0
- framework/evaluation/runner.py +363 -0
- framework/evaluation/testing.py +25 -0
- framework/exceptions.py +49 -0
- framework/llms/__init__.py +8 -0
- framework/llms/base.py +37 -0
- framework/llms/factory.py +38 -0
- framework/llms/gemini.py +85 -0
- framework/llms/mock.py +25 -0
- framework/llms/openai.py +94 -0
- framework/llms/openai_compatible.py +139 -0
- framework/mcp/__init__.py +20 -0
- framework/mcp/client.py +62 -0
- framework/mcp/constraints.py +125 -0
- framework/mcp/revision_summary.py +122 -0
- framework/mcp/server.py +49 -0
- framework/memory/__init__.py +3 -0
- framework/memory/base.py +17 -0
- framework/models.py +83 -0
- framework/parser.py +45 -0
- framework/parsers/__init__.py +12 -0
- framework/parsers/frontmatter.py +28 -0
- framework/parsers/mapper.py +66 -0
- framework/parsers/markdown.py +122 -0
- framework/parsers/transformers.py +112 -0
- framework/profiles/__init__.py +28 -0
- framework/profiles/registry.py +104 -0
- framework/profiles/support.py +27 -0
- framework/profiles/travel.py +78 -0
- framework/regression/__init__.py +17 -0
- framework/regression/comparator.py +273 -0
- framework/regression/loader.py +145 -0
- framework/sdk.py +151 -0
- framework/utils.py +41 -0
- framework/verification/__init__.py +13 -0
- framework/verification/base.py +32 -0
- framework/verification/extractor.py +105 -0
- framework/verification/local.py +122 -0
- framework/verification/models.py +112 -0
- framework/verification/pipeline.py +36 -0
- framework/verification/prompts.py +24 -0
- framework/verification/utils.py +54 -0
- ui/__init__.py +1 -0
- ui/server.py +255 -0
cli/formatter.py
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""Terminal report formatter and credential redaction utilities for evalrun CLI."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, List, Optional
|
|
4
|
+
from framework.models import EvaluationResult
|
|
5
|
+
|
|
6
|
+
SECRET_KEYS = {"api_key", "apikey", "authorization", "password", "secret", "bearer", "token"}
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def redact_credentials(data: Any) -> Any:
|
|
10
|
+
"""Recursively redacts sensitive credentials from dictionaries or lists for manifest persistence."""
|
|
11
|
+
if isinstance(data, dict):
|
|
12
|
+
redacted = {}
|
|
13
|
+
for key, val in data.items():
|
|
14
|
+
if key.lower() in SECRET_KEYS:
|
|
15
|
+
redacted[key] = "[REDACTED]"
|
|
16
|
+
else:
|
|
17
|
+
redacted[key] = redact_credentials(val)
|
|
18
|
+
return redacted
|
|
19
|
+
elif isinstance(data, list):
|
|
20
|
+
return [redact_credentials(item) for item in data]
|
|
21
|
+
return data
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def format_terminal_summary(
|
|
25
|
+
results: List[EvaluationResult],
|
|
26
|
+
manifest: Dict[str, Any],
|
|
27
|
+
regression_report: Optional[Dict[str, Any]] = None,
|
|
28
|
+
) -> str:
|
|
29
|
+
"""Renders a clean ASCII summary table for terminal display."""
|
|
30
|
+
lines = []
|
|
31
|
+
lines.append("=" * 85)
|
|
32
|
+
lines.append(" EVALRUN BENCHMARK SUMMARY")
|
|
33
|
+
lines.append("=" * 85)
|
|
34
|
+
lines.append(f" Run ID: {manifest.get('run_id', 'N/A')}")
|
|
35
|
+
lines.append(f" Target Model: {manifest.get('target_model', {}).get('model_name', 'N/A')} ({manifest.get('target_model', {}).get('base_url', 'N/A')})")
|
|
36
|
+
lines.append(f" Judge Model: {manifest.get('judge_model', {}).get('model_name', 'N/A')}")
|
|
37
|
+
if manifest.get("baseline_path"):
|
|
38
|
+
lines.append(f" Baseline: {manifest.get('baseline_path')}")
|
|
39
|
+
lines.append(f" Total Runs: {len(results)}")
|
|
40
|
+
lines.append("-" * 85)
|
|
41
|
+
|
|
42
|
+
if regression_report:
|
|
43
|
+
lines.append(f"{'Scenario Name':<28} | {'Score':<7} | {'Delta':<8} | {'Evaluator':<10} | {'Auditor':<8} | {'Status':<10}")
|
|
44
|
+
else:
|
|
45
|
+
lines.append(f"{'Scenario Name':<32} | {'Score':<8} | {'Evaluator':<10} | {'Auditor Gate':<12}")
|
|
46
|
+
lines.append("-" * 85)
|
|
47
|
+
|
|
48
|
+
all_passed = True
|
|
49
|
+
reg_scenarios_by_id = {}
|
|
50
|
+
if regression_report:
|
|
51
|
+
if regression_report.get("release_blocked"):
|
|
52
|
+
all_passed = False
|
|
53
|
+
for s in regression_report.get("scenarios", []):
|
|
54
|
+
reg_scenarios_by_id[s["scenario_id"]] = s
|
|
55
|
+
|
|
56
|
+
for res in results:
|
|
57
|
+
eval_status = "PASS" if res.passed else "FAIL"
|
|
58
|
+
if not res.passed:
|
|
59
|
+
all_passed = False
|
|
60
|
+
|
|
61
|
+
audit_status = "N/A"
|
|
62
|
+
if hasattr(res, "agent_metadata") and isinstance(res.agent_metadata, dict):
|
|
63
|
+
gate = res.agent_metadata.get("audit_gate_decision")
|
|
64
|
+
if gate:
|
|
65
|
+
audit_status = "PASS" if gate == "PASS" else "BLOCK"
|
|
66
|
+
if gate != "PASS":
|
|
67
|
+
all_passed = False
|
|
68
|
+
|
|
69
|
+
if regression_report:
|
|
70
|
+
reg_info = reg_scenarios_by_id.get(res.benchmark_id, {})
|
|
71
|
+
delta_val = reg_info.get("overall_delta")
|
|
72
|
+
delta_str = f"{delta_val:+.2f}" if delta_val is not None else "N/A"
|
|
73
|
+
status_str = reg_info.get("status", "OK")
|
|
74
|
+
lines.append(
|
|
75
|
+
f"{res.benchmark_name[:28]:<28} | {res.overall_score:6.2f} | {delta_str:<8} | {eval_status:<10} | {audit_status:<8} | {status_str:<10}"
|
|
76
|
+
)
|
|
77
|
+
else:
|
|
78
|
+
lines.append(f"{res.benchmark_name[:32]:<32} | {res.overall_score:6.2f} | {eval_status:<10} | {audit_status:<12}")
|
|
79
|
+
|
|
80
|
+
lines.append("=" * 85)
|
|
81
|
+
if regression_report and regression_report.get("regression_detected"):
|
|
82
|
+
final_verdict = "RELEASE BLOCKED: REGRESSION OR GATE FAILURE (Exit Code: 1)"
|
|
83
|
+
elif not all_passed:
|
|
84
|
+
final_verdict = "EVALUATION OR GATE FAILURE (Exit Code: 1)"
|
|
85
|
+
else:
|
|
86
|
+
final_verdict = "ALL SCENARIOS PASSED (Exit Code: 0)"
|
|
87
|
+
|
|
88
|
+
lines.append(f" Final Verdict: {final_verdict}")
|
|
89
|
+
lines.append("=" * 85)
|
|
90
|
+
lines.append(f" Artifacts saved to: {manifest.get('output_dir', './eval_results')}")
|
|
91
|
+
lines.append("")
|
|
92
|
+
|
|
93
|
+
return "\n".join(lines)
|