Skip to main content

ai_agent/types/
ids.rs

1// Source: ~/claudecode/openclaudecode/src/types/ids.ts
2
3//! Branded types for session and agent IDs.
4//! These prevent accidentally mixing up session IDs and agent IDs at compile time.
5
6use serde::{Deserialize, Serialize};
7
8/// A session ID uniquely identifies a Claude Code session.
9/// Returned by getSessionId().
10#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
11pub struct SessionId(String);
12
13/// An agent ID uniquely identifies a subagent within a session.
14/// Returned by createAgentId().
15/// When present, indicates the context is a subagent (not the main session).
16#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
17pub struct AgentId(String);
18
19/// Cast a raw string to SessionId.
20/// Use sparingly - prefer getSessionId() when possible.
21pub fn as_session_id(id: &str) -> SessionId {
22    SessionId(id.to_string())
23}
24
25/// Cast a raw string to AgentId.
26/// Use sparingly - prefer createAgentId() when possible.
27pub fn as_agent_id(id: &str) -> AgentId {
28    AgentId(id.to_string())
29}
30
31const AGENT_ID_PATTERN: &str = r"^a(?:.+-)?[0-9a-f]{16}$";
32
33/// Validate and brand a string as AgentId.
34/// Matches the format produced by createAgentId(): `a` + optional `<label>-` + 16 hex chars.
35/// Returns None if the string doesn't match (e.g. teammate names, team-addressing).
36pub fn to_agent_id(s: &str) -> Option<AgentId> {
37    let re = regex::Regex::new(AGENT_ID_PATTERN).ok()?;
38    if re.is_match(s) {
39        Some(AgentId(s.to_string()))
40    } else {
41        None
42    }
43}
44
45impl SessionId {
46    pub fn inner(&self) -> &str {
47        &self.0
48    }
49
50    pub fn as_str(&self) -> &str {
51        &self.0
52    }
53}
54
55impl AgentId {
56    pub fn inner(&self) -> &str {
57        &self.0
58    }
59
60    pub fn as_str(&self) -> &str {
61        &self.0
62    }
63}
64
65impl std::fmt::Display for SessionId {
66    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67        write!(f, "{}", self.0)
68    }
69}
70
71impl std::fmt::Display for AgentId {
72    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73        write!(f, "{}", self.0)
74    }
75}
76
77impl From<&str> for SessionId {
78    fn from(s: &str) -> Self {
79        as_session_id(s)
80    }
81}
82
83impl From<&str> for AgentId {
84    fn from(s: &str) -> Self {
85        as_agent_id(s)
86    }
87}