Skip to main content

everruns_core/
agent_identity.rs

1// Agent identity domain types
2//
3// Design Decision:
4// - AgentIdentity is a first-class virtual principal, separate from Agent behavior.
5// - It carries durable presentation + preference defaults and can be bound to Apps
6//   and Sessions without implying every interactive turn acts as the identity.
7
8use chrono::{DateTime, Utc};
9use serde::{Deserialize, Serialize};
10
11use crate::principal::PrincipalSummary;
12use crate::typed_id::AgentIdentityId;
13
14#[cfg(feature = "openapi")]
15use utoipa::ToSchema;
16
17/// Agent identity lifecycle status.
18#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
19#[cfg_attr(feature = "openapi", derive(ToSchema))]
20#[serde(rename_all = "lowercase")]
21pub enum AgentIdentityStatus {
22    Active,
23    Archived,
24    Deleted,
25}
26
27impl std::fmt::Display for AgentIdentityStatus {
28    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29        match self {
30            AgentIdentityStatus::Active => write!(f, "active"),
31            AgentIdentityStatus::Archived => write!(f, "archived"),
32            AgentIdentityStatus::Deleted => write!(f, "deleted"),
33        }
34    }
35}
36
37impl From<&str> for AgentIdentityStatus {
38    fn from(value: &str) -> Self {
39        match value {
40            "archived" => Self::Archived,
41            "deleted" => Self::Deleted,
42            _ => Self::Active,
43        }
44    }
45}
46
47/// AgentIdentity is a durable virtual principal.
48#[derive(Debug, Clone, Serialize, Deserialize)]
49#[cfg_attr(feature = "openapi", derive(ToSchema))]
50pub struct AgentIdentity {
51    /// External identifier (identity_<32-hex>). Shown as `id` in API.
52    #[serde(rename = "id")]
53    #[cfg_attr(feature = "openapi", schema(value_type = String, example = "identity_01933b5a000070008000000000000001"))]
54    pub id: AgentIdentityId,
55    /// Display name used when the identity acts autonomously.
56    pub name: String,
57    /// Optional description shown in management UI.
58    #[serde(skip_serializing_if = "Option::is_none")]
59    pub description: Option<String>,
60    /// Principal row representing this identity as a durable owner/executor.
61    #[serde(skip_serializing_if = "Option::is_none")]
62    pub principal: Option<PrincipalSummary>,
63    /// Effective human owner summary derived from the principal lineage.
64    #[serde(skip_serializing_if = "Option::is_none")]
65    pub effective_owner: Option<PrincipalSummary>,
66    /// Optional avatar URL for UI surfaces.
67    #[serde(skip_serializing_if = "Option::is_none")]
68    pub avatar_url: Option<String>,
69    /// Default locale for unattended runs.
70    #[serde(skip_serializing_if = "Option::is_none")]
71    pub locale: Option<String>,
72    /// Default timezone for unattended runs.
73    #[serde(skip_serializing_if = "Option::is_none")]
74    pub timezone: Option<String>,
75    /// Lifecycle status.
76    pub status: AgentIdentityStatus,
77    /// Creation timestamp.
78    pub created_at: DateTime<Utc>,
79    /// Last update timestamp.
80    pub updated_at: DateTime<Utc>,
81    /// Archive timestamp.
82    #[serde(skip_serializing_if = "Option::is_none")]
83    pub archived_at: Option<DateTime<Utc>>,
84    /// Delete timestamp.
85    #[serde(skip_serializing_if = "Option::is_none")]
86    pub deleted_at: Option<DateTime<Utc>>,
87}