Skip to main content

agent_evaluate_v2_contract/
admin.rs

1//! Administration surface.
2//!
3//! The console needs a cross-tenant view that the tenant API deliberately
4//! cannot give: platform drafts, every run, and the judge catalogue. Counts
5//! and pages are bounded so an operations screen can never scan the world.
6
7use std::collections::BTreeMap;
8
9use serde::{Deserialize, Serialize};
10
11use crate::binding::{BindingTarget, EvalBinding};
12use crate::catalog::{Capability, OwnerKind, SnapshotLifecycle, SnapshotRef, SnapshotSummary};
13use crate::run::{EvaluationSubject, OperationState};
14
15/// Aggregate counts for the landing screen. Keyed by the enum's wire name so
16/// a new state shows up without a schema change on the console side.
17#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
18#[serde(rename_all = "camelCase")]
19pub struct AdminOverview {
20    pub snapshots_by_lifecycle: BTreeMap<String, u64>,
21    pub snapshots_by_owner: BTreeMap<String, u64>,
22    pub ephemeral_snapshots: u64,
23    pub runs_by_state: BTreeMap<String, u64>,
24    pub case_runs_by_state: BTreeMap<String, u64>,
25    pub analysis_tasks_by_state: BTreeMap<String, u64>,
26    pub bindings: u64,
27    pub judge_models: u64,
28    pub gate_approved_judge_models: u64,
29}
30
31#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
32#[serde(rename_all = "camelCase", deny_unknown_fields)]
33pub struct ListAdminSnapshotsRequest {
34    #[serde(default, skip_serializing_if = "Option::is_none")]
35    pub owner: Option<OwnerKind>,
36    #[serde(default, skip_serializing_if = "Option::is_none")]
37    pub lifecycle: Option<SnapshotLifecycle>,
38    #[serde(default, skip_serializing_if = "Option::is_none")]
39    pub capability: Option<Capability>,
40    /// Restricts tenant-owned rows; platform rows ignore it.
41    #[serde(default, skip_serializing_if = "Option::is_none")]
42    pub tenant_id: Option<String>,
43    #[serde(default, skip_serializing_if = "Option::is_none")]
44    pub cursor: Option<String>,
45    #[serde(default, skip_serializing_if = "Option::is_none")]
46    pub limit: Option<usize>,
47}
48
49/// Same shape as the tenant listing plus the scope a platform operator needs
50/// in order to tell two tenants' snapshots apart.
51#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
52#[serde(rename_all = "camelCase")]
53pub struct AdminSnapshotSummary {
54    #[serde(flatten)]
55    pub summary: SnapshotSummary,
56    pub tenant_id: String,
57    pub project_id: String,
58}
59
60#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
61#[serde(rename_all = "camelCase")]
62pub struct AdminSnapshotPage {
63    pub items: Vec<AdminSnapshotSummary>,
64    #[serde(default, skip_serializing_if = "Option::is_none")]
65    pub next_cursor: Option<String>,
66}
67
68#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
69#[serde(rename_all = "camelCase", deny_unknown_fields)]
70pub struct ListAdminRunsRequest {
71    #[serde(default, skip_serializing_if = "Option::is_none")]
72    pub state: Option<OperationState>,
73    #[serde(default, skip_serializing_if = "Option::is_none")]
74    pub tenant_id: Option<String>,
75    #[serde(default, skip_serializing_if = "Option::is_none")]
76    pub cursor: Option<String>,
77    #[serde(default, skip_serializing_if = "Option::is_none")]
78    pub limit: Option<usize>,
79}
80
81#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
82#[serde(rename_all = "camelCase")]
83pub struct AdminRunSummary {
84    pub run_id: String,
85    pub operation_id: String,
86    pub tenant_id: String,
87    pub project_id: String,
88    pub target: BindingTarget,
89    #[serde(default, skip_serializing_if = "Option::is_none")]
90    pub subject: Option<EvaluationSubject>,
91    pub subject_version: String,
92    pub snapshots: Vec<SnapshotRef>,
93    pub state: OperationState,
94    pub phase: String,
95    pub completed_cases: usize,
96    pub total_cases: usize,
97    #[serde(default, skip_serializing_if = "Option::is_none")]
98    pub report_id: Option<String>,
99    pub created_at_ms: i64,
100    pub updated_at_ms: i64,
101}
102
103#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
104#[serde(rename_all = "camelCase")]
105pub struct AdminRunPage {
106    pub items: Vec<AdminRunSummary>,
107    #[serde(default, skip_serializing_if = "Option::is_none")]
108    pub next_cursor: Option<String>,
109}
110
111#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
112#[serde(rename_all = "camelCase", deny_unknown_fields)]
113pub struct ListAdminBindingsRequest {
114    #[serde(default, skip_serializing_if = "Option::is_none")]
115    pub tenant_id: Option<String>,
116    #[serde(default, skip_serializing_if = "Option::is_none")]
117    pub cursor: Option<String>,
118    #[serde(default, skip_serializing_if = "Option::is_none")]
119    pub limit: Option<usize>,
120}
121
122#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
123#[serde(rename_all = "camelCase")]
124pub struct AdminBindingPage {
125    pub items: Vec<EvalBinding>,
126    #[serde(default, skip_serializing_if = "Option::is_none")]
127    pub next_cursor: Option<String>,
128}
129
130/// Selects what an export bundle carries. An empty selection exports every
131/// published platform snapshot, which is the usual "seed a new deployment"
132/// case.
133#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
134#[serde(rename_all = "camelCase", deny_unknown_fields)]
135pub struct ExportBundleRequest {
136    #[serde(default)]
137    pub snapshots: Vec<SnapshotRef>,
138}