agenteval-toolkit 0.1.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.
Files changed (67) hide show
  1. agenteval/__init__.py +5 -0
  2. agenteval/_starter/certification/policy.yaml +15 -0
  3. agenteval/_starter/certification/systems/northwind-cs-staging.yaml +16 -0
  4. agenteval/_starter/certification/systems/northwind-cs.yaml +17 -0
  5. agenteval/_starter/examples/agents/demo-good.yaml +41 -0
  6. agenteval/_starter/examples/agents/demo-weak.yaml +34 -0
  7. agenteval/_starter/examples/agents/openai-compatible.example.yaml +15 -0
  8. agenteval/_starter/examples/agents/webhook.example.yaml +21 -0
  9. agenteval/_starter/examples/attestations-certification.yaml +16 -0
  10. agenteval/_starter/examples/attestations.yaml +19 -0
  11. agenteval/_starter/examples/snapshots/sample-cluster.json +323 -0
  12. agenteval/_starter/exams/customer-service/cs-ecommerce-v1.yaml +222 -0
  13. agenteval/_starter/rules/industry-pci-dss/i18n/zh.yaml +27 -0
  14. agenteval/_starter/rules/industry-pci-dss/pack.yaml +9 -0
  15. agenteval/_starter/rules/industry-pci-dss/rules.yaml +83 -0
  16. agenteval/_starter/rules/us-ca/i18n/zh.yaml +21 -0
  17. agenteval/_starter/rules/us-ca/pack.yaml +9 -0
  18. agenteval/_starter/rules/us-ca/rules.yaml +72 -0
  19. agenteval/_starter/rules/us-federal/governance.yaml +216 -0
  20. agenteval/_starter/rules/us-federal/i18n/zh.yaml +107 -0
  21. agenteval/_starter/rules/us-federal/pack.yaml +8 -0
  22. agenteval/_starter/rules/us-federal/security.yaml +164 -0
  23. agenteval/certification/__init__.py +16 -0
  24. agenteval/certification/assess.py +137 -0
  25. agenteval/certification/issuer.py +165 -0
  26. agenteval/certification/models.py +113 -0
  27. agenteval/certification/render.py +100 -0
  28. agenteval/certification/signing.py +86 -0
  29. agenteval/cli.py +533 -0
  30. agenteval/collectors/__init__.py +30 -0
  31. agenteval/collectors/kubernetes.py +70 -0
  32. agenteval/collectors/normalize.py +247 -0
  33. agenteval/config.py +49 -0
  34. agenteval/engine/__init__.py +12 -0
  35. agenteval/engine/conditions.py +109 -0
  36. agenteval/engine/evaluator.py +133 -0
  37. agenteval/engine/loader.py +131 -0
  38. agenteval/evaluation/__init__.py +17 -0
  39. agenteval/evaluation/adapters.py +276 -0
  40. agenteval/evaluation/assertions.py +73 -0
  41. agenteval/evaluation/judges.py +214 -0
  42. agenteval/evaluation/messages.py +56 -0
  43. agenteval/evaluation/models.py +174 -0
  44. agenteval/evaluation/papers.py +103 -0
  45. agenteval/evaluation/report.py +80 -0
  46. agenteval/evaluation/runner.py +154 -0
  47. agenteval/i18n.py +118 -0
  48. agenteval/models.py +136 -0
  49. agenteval/reports/__init__.py +86 -0
  50. agenteval/reports/templates/certificate.html.j2 +178 -0
  51. agenteval/reports/templates/eval_report.html.j2 +191 -0
  52. agenteval/reports/templates/report.html.j2 +75 -0
  53. agenteval/schema.py +66 -0
  54. agenteval/schemas/attestations.schema.json +76 -0
  55. agenteval/schemas/exam.schema.json +85 -0
  56. agenteval/schemas/pack.schema.json +48 -0
  57. agenteval/schemas/policy.schema.json +67 -0
  58. agenteval/schemas/rule.schema.json +298 -0
  59. agenteval/schemas/system.schema.json +76 -0
  60. agenteval/schemas/translations.schema.json +32 -0
  61. agenteval_toolkit-0.1.0.dist-info/METADATA +307 -0
  62. agenteval_toolkit-0.1.0.dist-info/RECORD +67 -0
  63. agenteval_toolkit-0.1.0.dist-info/WHEEL +5 -0
  64. agenteval_toolkit-0.1.0.dist-info/entry_points.txt +2 -0
  65. agenteval_toolkit-0.1.0.dist-info/licenses/LICENSE +202 -0
  66. agenteval_toolkit-0.1.0.dist-info/licenses/NOTICE +19 -0
  67. agenteval_toolkit-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,75 @@
1
+ <!doctype html>
2
+ <html lang="{{ t.html_lang }}">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>{{ t.title }} {{ r.scan_id }}</title>
7
+ <style>
8
+ :root { --bg:#fff; --fg:#1b1d22; --muted:#5d6370; --line:#e3e5ea; --card:#f7f8fa;
9
+ --fail:#c0352b; --pass:#2f7d4f; --manual:#9a6a00; --na:#6b7280; }
10
+ @media (prefers-color-scheme: dark) {
11
+ :root { --bg:#14161a; --fg:#e8eaee; --muted:#9aa1ad; --line:#2b2f37; --card:#1c1f25;
12
+ --fail:#ff7a6e; --pass:#6fd39b; --manual:#f0c060; --na:#9aa1ad; }
13
+ }
14
+ body { margin:0; background:var(--bg); color:var(--fg); font:14px/1.5 system-ui, -apple-system, "PingFang SC", sans-serif; }
15
+ main { max-width:1100px; margin:0 auto; padding:24px 16px 48px; }
16
+ h1 { font-size:22px; margin:0 0 4px; }
17
+ .meta { color:var(--muted); font-size:13px; }
18
+ .tiles { display:grid; grid-template-columns:repeat(auto-fit,minmax(140px,1fr)); gap:12px; margin:20px 0; }
19
+ .tile { background:var(--card); border:1px solid var(--line); border-radius:8px; padding:12px; }
20
+ .tile b { display:block; font-size:24px; }
21
+ .disclaimer { border-left:3px solid var(--manual); padding:8px 12px; background:var(--card); font-size:13px; }
22
+ table { width:100%; border-collapse:collapse; margin-top:16px; }
23
+ th, td { text-align:left; padding:8px; border-bottom:1px solid var(--line); vertical-align:top; }
24
+ th { font-size:12px; color:var(--muted); font-weight:600; }
25
+ .st { font-weight:600; white-space:nowrap; }
26
+ .st-fail { color:var(--fail); } .st-pass { color:var(--pass); }
27
+ .st-manual { color:var(--manual); } .st-not_applicable, .st-error { color:var(--na); }
28
+ details summary { cursor:pointer; color:var(--muted); }
29
+ pre { white-space:pre-wrap; word-break:break-all; font-size:12px; margin:4px 0 0; }
30
+ .wrap { overflow-x:auto; }
31
+ </style>
32
+ </head>
33
+ <body>
34
+ <main>
35
+ <h1>{{ t.title }}</h1>
36
+ <div class="meta">{{ t.scan_id }} {{ r.scan_id }} · {{ t.source }} {{ r.source }} · {{ t.rules_version }} {{ r.rules_version }} · {{ r.started_at.strftime('%Y-%m-%d %H:%M UTC') }}</div>
37
+
38
+ <div class="tiles">
39
+ <div class="tile"><b>{{ r.summary.score }}%</b>{{ t.score }}</div>
40
+ <div class="tile"><b>{{ r.asset_count }}</b>{{ t.assets }}</div>
41
+ <div class="tile"><b>{{ r.summary.by_status.get('fail', 0) }}</b>{{ t.failed }}</div>
42
+ <div class="tile"><b>{{ r.summary.by_status.get('manual', 0) }}</b>{{ t.manual }}</div>
43
+ <div class="tile"><b>{{ r.summary.by_status.get('pass', 0) }}</b>{{ t.passed }}</div>
44
+ </div>
45
+
46
+ <p class="disclaimer">{{ r.disclaimer }}</p>
47
+
48
+ <div class="wrap">
49
+ <table>
50
+ <thead><tr><th>{{ t.col_status }}</th><th>{{ t.col_severity }}</th><th>{{ t.col_rule }}</th><th>{{ t.col_asset }}</th><th>{{ t.col_detail }}</th></tr></thead>
51
+ <tbody>
52
+ {% for f in r.findings %}
53
+ <tr>
54
+ <td class="st st-{{ f.status.value }}">{{ t['status_' ~ f.status.value] }}</td>
55
+ <td>{{ t['sev_' ~ f.severity.value] }}</td>
56
+ <td><b>{{ f.rule_id }}</b><br>{{ f.rule_title }}</td>
57
+ <td>{{ f.asset_id }}</td>
58
+ <td>
59
+ {{ f.message }}
60
+ {% if f.status.value in ('fail', 'manual') %}
61
+ <details><summary>{{ t.remediation }}</summary>
62
+ <p>{{ f.remediation }}</p>
63
+ <ul>{% for s in f.sources %}<li>{{ s.framework }} — {{ s.reference }}{% if not s.verified %}{{ t.unverified }}{% endif %}</li>{% endfor %}</ul>
64
+ </details>
65
+ {% endif %}
66
+ {% if f.evidence %}<details><summary>{{ t.evidence }}</summary><pre>{{ f.evidence | tojson_pretty }}</pre></details>{% endif %}
67
+ </td>
68
+ </tr>
69
+ {% endfor %}
70
+ </tbody>
71
+ </table>
72
+ </div>
73
+ </main>
74
+ </body>
75
+ </html>
agenteval/schema.py ADDED
@@ -0,0 +1,66 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Copyright 2026 The AgentEval Authors
3
+ """JSON Schema validation for AgentEval's YAML inputs.
4
+
5
+ Schemas live in ``agenteval/schemas/*.schema.json`` (Draft 2020-12) and are
6
+ exported for editors with ``agenteval schemas --out schemas/``.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import json
12
+ from datetime import date, datetime
13
+ from functools import lru_cache
14
+ from importlib import resources
15
+ from typing import Any
16
+
17
+ from jsonschema import Draft202012Validator
18
+
19
+ SCHEMA_NAMES = ("rule", "pack", "translations", "attestations", "exam", "system", "policy")
20
+
21
+
22
+ @lru_cache(maxsize=None)
23
+ def schema(name: str) -> dict:
24
+ text = resources.files("agenteval").joinpath(f"schemas/{name}.schema.json").read_text(encoding="utf-8")
25
+ return json.loads(text)
26
+
27
+
28
+ @lru_cache(maxsize=None)
29
+ def validator(name: str) -> Draft202012Validator:
30
+ """``rule`` validates one rule; ``rule-file`` validates a whole rules file."""
31
+ if name == "rule":
32
+ s = schema("rule")
33
+ return Draft202012Validator({"$schema": s["$schema"], "$defs": s["$defs"], "$ref": "#/$defs/rule"})
34
+ return Draft202012Validator(schema("rule" if name == "rule-file" else name))
35
+
36
+
37
+ def _plain(v: Any) -> Any:
38
+ """YAML turns unquoted dates into date objects; validate them as ISO strings."""
39
+ if isinstance(v, (date, datetime)):
40
+ return v.isoformat()
41
+ if isinstance(v, dict):
42
+ return {k: _plain(x) for k, x in v.items()}
43
+ if isinstance(v, list):
44
+ return [_plain(x) for x in v]
45
+ return v
46
+
47
+
48
+ def errors(name: str, data: Any, where: str = "") -> list[str]:
49
+ """Return human-readable validation errors (empty list when valid)."""
50
+ out = []
51
+ for e in sorted(validator(name).iter_errors(_plain(data)), key=lambda e: list(e.path)):
52
+ path = "/".join(str(p) for p in e.path) or "<root>"
53
+ out.append(f"{where} {path}: {e.message}".strip())
54
+ return out
55
+
56
+
57
+ class SchemaError(ValueError):
58
+ def __init__(self, errs: list[str]):
59
+ self.errors = errs
60
+ super().__init__("Schema validation failed:\n " + "\n ".join(errs))
61
+
62
+
63
+ def check(name: str, data: Any, where: str = "") -> None:
64
+ errs = errors(name, data, where)
65
+ if errs:
66
+ raise SchemaError(errs)
@@ -0,0 +1,76 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://agenteval.dev/schemas/v1/attestations.schema.json",
4
+ "title": "AgentEval attestations file",
5
+ "oneOf": [
6
+ {
7
+ "type": "object",
8
+ "additionalProperties": false,
9
+ "required": [
10
+ "attestations"
11
+ ],
12
+ "properties": {
13
+ "attestations": {
14
+ "type": "array",
15
+ "items": {
16
+ "$ref": "#/$defs/attestation"
17
+ }
18
+ }
19
+ }
20
+ },
21
+ {
22
+ "type": "array",
23
+ "items": {
24
+ "$ref": "#/$defs/attestation"
25
+ }
26
+ }
27
+ ],
28
+ "$defs": {
29
+ "attestation": {
30
+ "type": "object",
31
+ "additionalProperties": false,
32
+ "required": [
33
+ "rule_id",
34
+ "attested_by",
35
+ "attested_at",
36
+ "evidence"
37
+ ],
38
+ "properties": {
39
+ "rule_id": {
40
+ "type": "string",
41
+ "pattern": "^[A-Z]{2,6}(-[A-Z0-9]{2,8})+$"
42
+ },
43
+ "asset_id": {
44
+ "type": "string",
45
+ "minLength": 1,
46
+ "default": "*",
47
+ "description": "Asset ID, or \"*\" for every asset the rule applies to."
48
+ },
49
+ "attested_by": {
50
+ "type": "string",
51
+ "minLength": 1
52
+ },
53
+ "attested_at": {
54
+ "type": "string",
55
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}([T ].*)?$",
56
+ "description": "ISO date (YYYY-MM-DD). Used for max_age_days checks."
57
+ },
58
+ "evidence": {
59
+ "type": "object",
60
+ "additionalProperties": {
61
+ "type": [
62
+ "string",
63
+ "number",
64
+ "boolean",
65
+ "null"
66
+ ]
67
+ },
68
+ "description": "Keys must match the rule's attestation.evidence_required. Prefer links or ticket IDs over pasted content."
69
+ },
70
+ "notes": {
71
+ "type": "string"
72
+ }
73
+ }
74
+ }
75
+ }
76
+ }
@@ -0,0 +1,85 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://agenteval.dev/schemas/v1/exam.schema.json",
4
+ "title": "agenteval exam paper",
5
+ "type": "object",
6
+ "required": ["id", "title", "domain", "version", "dimensions", "cases"],
7
+ "additionalProperties": false,
8
+ "properties": {
9
+ "id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9-]{2,63}$"},
10
+ "title": {"type": "string", "minLength": 3},
11
+ "domain": {"type": "string"},
12
+ "version": {"type": "string"},
13
+ "language": {"type": "string"},
14
+ "description": {"type": "string"},
15
+ "passing_score": {"type": "number", "minimum": 0, "maximum": 100},
16
+ "case_passing_score": {"type": "number", "minimum": 0, "maximum": 100},
17
+ "context": {"type": "string"},
18
+ "tools": {"type": "array", "items": {"type": "object", "required": ["name"]}},
19
+ "dimensions": {
20
+ "type": "array", "minItems": 1,
21
+ "items": {
22
+ "type": "object", "required": ["id", "name", "weight"], "additionalProperties": false,
23
+ "properties": {
24
+ "id": {"type": "string", "pattern": "^[a-z_]+$"},
25
+ "name": {"type": "string"},
26
+ "weight": {"type": "number", "exclusiveMinimum": 0},
27
+ "description": {"type": "string"}
28
+ }
29
+ }
30
+ },
31
+ "cases": {
32
+ "type": "array", "minItems": 1,
33
+ "items": {
34
+ "type": "object", "required": ["id", "title", "category", "turns"], "additionalProperties": false,
35
+ "properties": {
36
+ "id": {"type": "string", "pattern": "^[A-Z]{2,6}-[0-9]{3}$"},
37
+ "title": {"type": "string"},
38
+ "category": {"type": "string"},
39
+ "difficulty": {"enum": ["easy", "medium", "hard"]},
40
+ "weight": {"type": "number", "exclusiveMinimum": 0},
41
+ "tags": {"type": "array", "items": {"type": "string"}},
42
+ "tool_mocks": {"type": "object"},
43
+ "turns": {
44
+ "type": "array", "minItems": 1,
45
+ "items": {
46
+ "type": "object", "required": ["user"], "additionalProperties": false,
47
+ "properties": {
48
+ "user": {"type": "string", "minLength": 1},
49
+ "expect": {"type": "array", "items": {"$ref": "#/$defs/assertion"}}
50
+ }
51
+ }
52
+ },
53
+ "rubric": {
54
+ "type": "array",
55
+ "items": {
56
+ "type": "object", "required": ["id", "dimension", "criterion"], "additionalProperties": false,
57
+ "properties": {
58
+ "id": {"type": "string"},
59
+ "dimension": {"type": "string"},
60
+ "criterion": {"type": "string", "minLength": 5},
61
+ "weight": {"type": "number", "exclusiveMinimum": 0},
62
+ "signals": {"type": "array", "items": {"type": "string"}}
63
+ }
64
+ }
65
+ }
66
+ }
67
+ }
68
+ }
69
+ },
70
+ "$defs": {
71
+ "assertion": {
72
+ "type": "object", "required": ["type", "dimension"], "additionalProperties": false,
73
+ "properties": {
74
+ "type": {"enum": ["contains", "contains_any", "contains_all", "not_contains", "regex", "not_regex",
75
+ "tool_called", "tool_not_called", "max_latency_ms", "min_chars", "max_chars"]},
76
+ "value": {},
77
+ "dimension": {"type": "string"},
78
+ "weight": {"type": "number", "exclusiveMinimum": 0},
79
+ "critical": {"type": "boolean"},
80
+ "args_contains": {"type": "object"},
81
+ "description": {"type": "string"}
82
+ }
83
+ }
84
+ }
85
+ }
@@ -0,0 +1,48 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://agenteval.dev/schemas/v1/pack.schema.json",
4
+ "title": "AgentEval rule pack metadata (pack.yaml)",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "id",
9
+ "name",
10
+ "tier",
11
+ "jurisdiction"
12
+ ],
13
+ "properties": {
14
+ "id": {
15
+ "type": "string",
16
+ "pattern": "^[a-z0-9][a-z0-9-]{1,62}$",
17
+ "description": "Stable pack ID referenced by systems' rule_packs."
18
+ },
19
+ "name": {
20
+ "type": "string",
21
+ "minLength": 1,
22
+ "description": "Display name (English, the source language)."
23
+ },
24
+ "name_zh": {
25
+ "type": "string",
26
+ "description": "Optional Simplified Chinese display name."
27
+ },
28
+ "tier": {
29
+ "enum": [
30
+ "national",
31
+ "regional",
32
+ "industry"
33
+ ],
34
+ "description": "Where the obligations come from."
35
+ },
36
+ "jurisdiction": {
37
+ "type": "string",
38
+ "minLength": 1,
39
+ "description": "e.g. US, US-CA, or an industry code such as PCI-DSS."
40
+ },
41
+ "description": {
42
+ "type": "string"
43
+ },
44
+ "description_zh": {
45
+ "type": "string"
46
+ }
47
+ }
48
+ }
@@ -0,0 +1,67 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://agenteval.dev/schemas/v1/policy.schema.json",
4
+ "title": "AgentEval certification policy (certification/policy.yaml)",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "properties": {
8
+ "min_security_score": {
9
+ "type": "number",
10
+ "minimum": 0,
11
+ "maximum": 100,
12
+ "description": "Security score must be strictly greater than this."
13
+ },
14
+ "min_quality_score": {
15
+ "type": "number",
16
+ "minimum": 0,
17
+ "maximum": 100,
18
+ "description": "Evaluation score must be strictly greater than this."
19
+ },
20
+ "block_on_severities": {
21
+ "type": "array",
22
+ "uniqueItems": true,
23
+ "items": {
24
+ "enum": [
25
+ "critical",
26
+ "high",
27
+ "medium",
28
+ "low",
29
+ "info"
30
+ ]
31
+ }
32
+ },
33
+ "require_no_pending_attestations": {
34
+ "type": "boolean"
35
+ },
36
+ "require_zero_critical_eval_failures": {
37
+ "type": "boolean"
38
+ },
39
+ "require_no_eval_errors": {
40
+ "type": "boolean"
41
+ },
42
+ "require_llm_judge": {
43
+ "type": "boolean"
44
+ },
45
+ "allow_demo_certificates": {
46
+ "type": "boolean"
47
+ },
48
+ "max_evidence_age_days": {
49
+ "type": "integer",
50
+ "minimum": 1
51
+ },
52
+ "validity_months": {
53
+ "type": "integer",
54
+ "minimum": 1,
55
+ "maximum": 36
56
+ },
57
+ "auto_revoke": {
58
+ "type": "boolean"
59
+ },
60
+ "issuer_name": {
61
+ "type": "string"
62
+ },
63
+ "issuer_name_zh": {
64
+ "type": "string"
65
+ }
66
+ }
67
+ }