agent_evaluate_v2_contract/
binding.rs1use serde::{Deserialize, Serialize};
4
5use crate::catalog::SnapshotRef;
6use crate::report::GatePolicy;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
9#[serde(rename_all = "snake_case")]
10pub enum TargetKind {
11 Agent,
12 Runtime,
13}
14
15impl TargetKind {
16 pub const fn as_str(self) -> &'static str {
17 match self {
18 Self::Agent => "agent",
19 Self::Runtime => "runtime",
20 }
21 }
22}
23
24#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
25#[serde(rename_all = "camelCase", deny_unknown_fields)]
26pub struct BindingTarget {
27 pub kind: TargetKind,
28 pub id: String,
29}
30
31impl BindingTarget {
32 pub fn agent(id: impl Into<String>) -> Self {
33 Self {
34 kind: TargetKind::Agent,
35 id: id.into(),
36 }
37 }
38
39 pub fn runtime(id: impl Into<String>) -> Self {
40 Self {
41 kind: TargetKind::Runtime,
42 id: id.into(),
43 }
44 }
45}
46
47#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
48#[serde(rename_all = "camelCase", deny_unknown_fields)]
49pub struct BoundSnapshot {
50 #[serde(rename = "ref")]
51 pub reference: SnapshotRef,
52 #[serde(default = "default_required")]
54 pub required: bool,
55}
56
57fn default_required() -> bool {
58 true
59}
60
61#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
62#[serde(rename_all = "snake_case")]
63pub enum BindingTrigger {
64 Manual,
65 OnDeploy,
66 Scheduled,
67}
68
69#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
73#[serde(rename_all = "camelCase", deny_unknown_fields)]
74pub struct EvalBinding {
75 pub tenant_id: String,
76 pub project_id: String,
77 pub target: BindingTarget,
78 pub snapshots: Vec<BoundSnapshot>,
79 #[serde(default, skip_serializing_if = "Option::is_none")]
80 pub gate_policy: Option<GatePolicy>,
81 #[serde(default)]
82 pub triggers: Vec<BindingTrigger>,
83 pub version: i64,
85 pub created_at_ms: i64,
86 pub updated_at_ms: i64,
87}
88
89#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
90#[serde(rename_all = "camelCase", deny_unknown_fields)]
91pub struct PutBindingRequest {
92 pub target: BindingTarget,
93 pub snapshots: Vec<BoundSnapshot>,
94 #[serde(default, skip_serializing_if = "Option::is_none")]
95 pub gate_policy: Option<GatePolicy>,
96 #[serde(default)]
97 pub triggers: Vec<BindingTrigger>,
98 #[serde(default, skip_serializing_if = "Option::is_none")]
100 pub if_version: Option<i64>,
101}
102
103#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
104#[serde(rename_all = "camelCase", deny_unknown_fields)]
105pub struct GetBindingRequest {
106 pub target: BindingTarget,
107}
108
109#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
110#[serde(rename_all = "camelCase", deny_unknown_fields)]
111pub struct ListBindingsRequest {
112 #[serde(default, skip_serializing_if = "Option::is_none")]
113 pub kind: Option<TargetKind>,
114 #[serde(default, skip_serializing_if = "Option::is_none")]
115 pub cursor: Option<String>,
116 #[serde(default, skip_serializing_if = "Option::is_none")]
117 pub limit: Option<usize>,
118}
119
120#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
121#[serde(rename_all = "camelCase")]
122pub struct BindingPage {
123 pub items: Vec<EvalBinding>,
124 #[serde(default, skip_serializing_if = "Option::is_none")]
125 pub next_cursor: Option<String>,
126}