objects/object/
state_attribution.rs1use serde::{Deserialize, Serialize};
5
6#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
8pub struct Principal {
9 pub name: String,
11 pub email: String,
13}
14
15impl Principal {
16 pub fn new(name: impl Into<String>, email: impl Into<String>) -> Self {
18 Self {
19 name: name.into(),
20 email: email.into(),
21 }
22 }
23
24 pub fn from_env() -> Option<Self> {
26 let name = std::env::var("HEDDLE_PRINCIPAL_NAME").ok()?;
27 let email = std::env::var("HEDDLE_PRINCIPAL_EMAIL").ok()?;
28 Some(Self { name, email })
29 }
30}
31
32impl std::fmt::Display for Principal {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 write!(f, "{} <{}>", self.name, self.email)
35 }
36}
37
38#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
40pub struct Agent {
41 pub provider: String,
43 pub model: String,
45 pub session_id: Option<String>,
47 pub segment_id: Option<String>,
49 pub policy_id: Option<String>,
51}
52
53impl Agent {
54 pub fn new(provider: impl Into<String>, model: impl Into<String>) -> Self {
56 Self {
57 provider: provider.into(),
58 model: model.into(),
59 session_id: None,
60 segment_id: None,
61 policy_id: None,
62 }
63 }
64
65 pub fn with_session(
67 mut self,
68 session_id: impl Into<String>,
69 segment_id: impl Into<String>,
70 ) -> Self {
71 self.session_id = Some(session_id.into());
72 self.segment_id = Some(segment_id.into());
73 self
74 }
75
76 pub fn with_policy(mut self, policy_id: impl Into<String>) -> Self {
78 self.policy_id = Some(policy_id.into());
79 self
80 }
81
82 pub fn from_env() -> Option<Self> {
84 let provider = std::env::var("HEDDLE_AGENT_PROVIDER").ok()?;
85 let model = std::env::var("HEDDLE_AGENT_MODEL").ok()?;
86 let session_id = std::env::var("HEDDLE_SESSION_ID").ok();
87 let segment_id = std::env::var("HEDDLE_SESSION_SEGMENT").ok();
88 let policy_id = std::env::var("HEDDLE_AGENT_POLICY").ok();
89 Some(Self {
90 provider,
91 model,
92 session_id,
93 segment_id,
94 policy_id,
95 })
96 }
97}
98
99impl std::fmt::Display for Agent {
100 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101 write!(f, "{}/{}", self.provider, self.model)
102 }
103}
104
105#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
107pub struct Attribution {
108 pub principal: Principal,
110 pub agent: Option<Agent>,
112}
113
114impl Attribution {
115 pub fn human(principal: Principal) -> Self {
117 Self {
118 principal,
119 agent: None,
120 }
121 }
122
123 pub fn with_agent(principal: Principal, agent: Agent) -> Self {
125 Self {
126 principal,
127 agent: Some(agent),
128 }
129 }
130}
131
132impl std::fmt::Display for Attribution {
133 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
134 if let Some(agent) = &self.agent {
135 write!(f, "{} (via {})", self.principal, agent)
136 } else {
137 write!(f, "{}", self.principal)
138 }
139 }
140}