systemprompt_identifiers/
agent.rs1crate::define_id!(AgentId, generate, schema);
11crate::define_id!(ExternalAgentId, non_empty);
12
13use crate::error::IdValidationError;
14
15crate::define_id!(AgentName, checked, validate_agent_name);
16
17const MAX_AGENT_NAME_BYTES: usize = 64;
18
19fn validate_agent_name(name: &str) -> Result<(), IdValidationError> {
20 if name.trim().is_empty() {
21 return Err(IdValidationError::empty("AgentName"));
22 }
23 if name.len() > MAX_AGENT_NAME_BYTES {
24 return Err(IdValidationError::invalid(
25 "AgentName",
26 format!("longer than {MAX_AGENT_NAME_BYTES} bytes"),
27 ));
28 }
29 if !name.chars().all(allowed_agent_name_char) {
30 return Err(IdValidationError::invalid(
31 "AgentName",
32 "only ASCII letters, digits and '-', '_', '.', ':', '/' are allowed",
33 ));
34 }
35 if name.eq_ignore_ascii_case("unknown") || name.eq_ignore_ascii_case("unset") {
36 return Err(IdValidationError::invalid(
37 "AgentName",
38 format!("'{name}' is a reserved sentinel, not an agent name"),
39 ));
40 }
41 Ok(())
42}
43
44const fn allowed_agent_name_char(c: char) -> bool {
45 c.is_ascii_alphanumeric() || matches!(c, '-' | '_' | '.' | ':' | '/')
46}
47
48impl AgentName {
49 pub fn system() -> Self {
50 Self("system".to_owned())
51 }
52
53 pub fn bridge() -> Self {
54 Self("bridge".to_owned())
55 }
56}