Skip to main content

agent_evaluate_v2_contract/
lib.rs

1//! HTTP contract for the Agent Evaluate domain application.
2//!
3//! Evaluate owns exactly one immutable registration unit — the **Snapshot** —
4//! which carries its cases, each case's evaluators and the execution spec.
5//! Everything else it stores is a reference (trace, sandbox, model) or a
6//! judgement (metric, verdict, report).
7//!
8//! # Layering
9//!
10//! ```text
11//! agent-evaluate-contract   paths + DTOs        (this crate)
12//! agent-evaluate-domain     pure domain logic
13//! agent-evaluate-adapter-*  SQL / Infra SDK
14//! agent-evaluate-server     router + auth + bin
15//! ```
16
17pub mod admin;
18pub mod analysis;
19pub mod binding;
20pub mod catalog;
21pub mod driver;
22pub mod evaluator;
23pub mod execution;
24pub mod report;
25pub mod run;
26
27pub use admin::*;
28pub use analysis::*;
29pub use binding::*;
30pub use catalog::*;
31pub use driver::*;
32pub use evaluator::*;
33pub use execution::*;
34pub use report::*;
35pub use run::*;
36
37use serde::{Deserialize, Serialize};
38
39pub const SERVICE_NAME: &str = "agent-evaluate";
40pub const DEFAULT_PORT: u16 = 5150;
41pub const AUDIENCE: &str = "agent-evaluate";
42
43/// Identifier length cap shared by every product identifier. Matches the
44/// indexable prefix of a `VARCHAR(191)` column under `utf8mb4`.
45pub const MAX_RESOURCE_ID_CHARS: usize = 191;
46
47// ── Limits ────────────────────────────────────────────────────────────
48// Every bound is enforced by the domain layer, never by the storage engine
49// discovering it the hard way.
50
51pub const MAX_CASES_PER_SNAPSHOT: usize = 2_000;
52pub const MAX_EVALUATORS_PER_CASE: usize = 16;
53pub const MAX_TURNS_PER_CASE: usize = 64;
54pub const MAX_FIXTURES_PER_CASE: usize = 64;
55pub const MAX_FIXTURE_BYTES: usize = 256 * 1024;
56pub const MAX_INCLUDES_PER_SNAPSHOT: usize = 32;
57pub const MAX_SNAPSHOTS_PER_BINDING: usize = 32;
58pub const MAX_JUDGES_PER_EVALUATOR: usize = 5;
59pub const MAX_PAGE_SIZE: usize = 200;
60pub const DEFAULT_PAGE_SIZE: usize = 50;
61
62/// Ephemeral snapshot policy (design §15.1). Temporary assets must never
63/// enter a long-lived dependency graph, so they are also barred from
64/// bindings and includes.
65pub const DEFAULT_EPHEMERAL_TTL_MS: i64 = 24 * 60 * 60 * 1_000;
66pub const MAX_EPHEMERAL_TTL_MS: i64 = 7 * 24 * 60 * 60 * 1_000;
67pub const MAX_EPHEMERAL_SNAPSHOTS_PER_PROJECT: usize = 50;
68pub const MAX_EPHEMERAL_CASES_PER_PROJECT: usize = 5_000;
69
70// ── Paths ─────────────────────────────────────────────────────────────
71
72pub const HEALTH_PATH: &str = "/health";
73pub const READY_PATH: &str = "/readyz";
74
75pub const SNAPSHOTS_PATH: &str = "/internal/v1/evaluate/snapshots";
76pub const SNAPSHOTS_LIST_PATH: &str = "/internal/v1/evaluate/snapshots/list";
77pub const SNAPSHOTS_GET_PATH: &str = "/internal/v1/evaluate/snapshots/get";
78
79pub const BINDINGS_PATH: &str = "/internal/v1/evaluate/bindings";
80pub const BINDINGS_LIST_PATH: &str = "/internal/v1/evaluate/bindings/list";
81pub const BINDINGS_GET_PATH: &str = "/internal/v1/evaluate/bindings/get";
82pub const BINDINGS_DELETE_PATH: &str = "/internal/v1/evaluate/bindings/delete";
83
84pub const RUNS_PATH: &str = "/internal/v1/evaluate/runs";
85pub const OPERATIONS_PATH: &str = "/internal/v1/evaluate/operations";
86pub const RUN_CASES_PATH: &str = "/internal/v1/evaluate/runs/cases";
87pub const CANCEL_RUN_PATH: &str = "/internal/v1/evaluate/runs/cancel";
88
89pub const DRIVER_CLAIM_PATH: &str = "/internal/v1/evaluate/driver/cases/claim";
90pub const DRIVER_RENEW_PATH: &str = "/internal/v1/evaluate/driver/cases/renew";
91pub const DRIVER_SUBMIT_PATH: &str = "/internal/v1/evaluate/driver/cases/submit";
92
93pub const ANALYSIS_CLAIM_PATH: &str = "/internal/v1/evaluate/analysis/tasks/claim";
94pub const ANALYSIS_SUBMIT_PATH: &str = "/internal/v1/evaluate/analysis/tasks/submit";
95pub const ANALYSIS_RERUN_PATH: &str = "/internal/v1/evaluate/analysis/rerun";
96
97pub const REPORT_GET_PATH: &str = "/internal/v1/evaluate/reports/get";
98pub const REPORT_COMPARE_PATH: &str = "/internal/v1/evaluate/reports/compare";
99
100pub const METRIC_HEALTH_PATH: &str = "/internal/v1/evaluate/metrics/health";
101pub const METRIC_CANDIDATES_PATH: &str = "/internal/v1/evaluate/metrics/candidates";
102
103pub const REVIEWS_PATH: &str = "/internal/v1/evaluate/reviews";
104pub const REVIEWS_CLAIM_PATH: &str = "/internal/v1/evaluate/reviews/claim";
105pub const REVIEWS_COMPLETE_PATH: &str = "/internal/v1/evaluate/reviews/complete";
106
107pub const ADMIN_SNAPSHOTS_PATH: &str = "/internal/v1/evaluate/admin/snapshots";
108pub const ADMIN_SNAPSHOTS_LIST_PATH: &str = "/internal/v1/evaluate/admin/snapshots/list";
109pub const ADMIN_SNAPSHOTS_GET_PATH: &str = "/internal/v1/evaluate/admin/snapshots/get";
110pub const ADMIN_SNAPSHOTS_PUBLISH_PATH: &str = "/internal/v1/evaluate/admin/snapshots/publish";
111pub const ADMIN_SNAPSHOTS_DEPRECATE_PATH: &str = "/internal/v1/evaluate/admin/snapshots/deprecate";
112pub const ADMIN_SNAPSHOTS_EXPORT_PATH: &str = "/internal/v1/evaluate/admin/snapshots/export";
113pub const ADMIN_SNAPSHOTS_IMPORT_PATH: &str = "/internal/v1/evaluate/admin/snapshots/import";
114pub const ADMIN_JUDGE_ALLOWLIST_PATH: &str = "/internal/v1/evaluate/admin/judge-allowlist";
115pub const ADMIN_OVERVIEW_PATH: &str = "/internal/v1/evaluate/admin/overview";
116pub const ADMIN_RUNS_PATH: &str = "/internal/v1/evaluate/admin/runs";
117pub const ADMIN_BINDINGS_PATH: &str = "/internal/v1/evaluate/admin/bindings";
118
119/// Tenant/project scope derived from a verified identity. Callers never get
120/// to assert their own scope in a request body.
121#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
122#[serde(rename_all = "camelCase", deny_unknown_fields)]
123pub struct EvalScope {
124    pub tenant_id: String,
125    pub project_id: String,
126}
127
128impl EvalScope {
129    pub fn new(tenant_id: impl Into<String>, project_id: impl Into<String>) -> Self {
130        Self {
131            tenant_id: tenant_id.into(),
132            project_id: project_id.into(),
133        }
134    }
135}
136
137/// Error body shared by every non-2xx response.
138#[derive(Debug, Clone, Serialize, Deserialize)]
139pub struct ApiError {
140    pub status: u16,
141    pub code: String,
142    pub message: String,
143}