use serde::{Deserialize, Serialize};
use systemprompt_identifiers::{AgentName, ClientId};
use super::claims::TokenInteraction;
pub const UNNAMED_AGENT: &str = "agent";
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum RequestActor {
Human,
Agent { name: AgentName, attended: bool },
}
impl RequestActor {
#[must_use]
pub const fn is_agent(&self) -> bool {
matches!(self, Self::Agent { .. })
}
#[must_use]
pub const fn is_unattended_agent(&self) -> bool {
matches!(
self,
Self::Agent {
attended: false,
..
}
)
}
}
#[must_use]
pub fn bearer_actor(
purpose: Option<&str>,
client_id: Option<&ClientId>,
interaction: Option<TokenInteraction>,
) -> RequestActor {
let attended = interaction == Some(TokenInteraction::Interactive) && purpose.is_none();
RequestActor::Agent {
name: agent_name(purpose, client_id),
attended,
}
}
#[must_use]
pub fn agent_name(purpose: Option<&str>, client_id: Option<&ClientId>) -> AgentName {
purpose
.or_else(|| client_id.map(ClientId::as_str))
.and_then(|name| AgentName::try_new(name).ok())
.unwrap_or_else(|| AgentName::new(UNNAMED_AGENT))
}