use agent_uri::{AgentUri, CapabilityPath, TrustRoot};
use libp2p::kad::RecordKey;
use sha2::{Digest, Sha256};
const IDENTITY_DOMAIN: &[u8] = b"agent-uri/dht/identity/v1\x00";
const DESCRIPTOR_DOMAIN: &[u8] = b"agent-uri/dht/shard-descriptor/v1\x00";
const PAGE_DOMAIN: &[u8] = b"agent-uri/dht/shard-page/v1\x00";
const PLACEMENT_DOMAIN: &[u8] = b"agent-uri/dht/shard-placement/v1\x00";
pub const MAX_SHARD_LEVEL: u8 = 16;
#[must_use]
pub fn identity_key(agent_uri: &AgentUri) -> RecordKey {
let mut hasher = Sha256::new();
hasher.update(IDENTITY_DOMAIN);
hasher.update(agent_uri.canonical().as_bytes());
RecordKey::new(&hasher.finalize().as_slice())
}
#[must_use]
pub fn descriptor_key(trust_root: &TrustRoot, path: &str) -> RecordKey {
let mut hasher = Sha256::new();
hasher.update(DESCRIPTOR_DOMAIN);
hasher.update(trust_root.as_str().as_bytes());
hasher.update(b"/");
hasher.update(path.as_bytes());
RecordKey::new(&hasher.finalize().as_slice())
}
#[must_use]
pub fn page_key(trust_root: &TrustRoot, path: &str, page: u32) -> RecordKey {
let mut hasher = Sha256::new();
hasher.update(PAGE_DOMAIN);
hasher.update(trust_root.as_str().as_bytes());
hasher.update(b"/");
hasher.update(path.as_bytes());
hasher.update(b"#");
hasher.update(page.to_be_bytes());
RecordKey::new(&hasher.finalize().as_slice())
}
#[must_use]
pub fn page_for(agent_uri: &AgentUri, level: u8) -> u32 {
let level = level.min(MAX_SHARD_LEVEL);
if level == 0 {
return 0;
}
let mut hasher = Sha256::new();
hasher.update(PLACEMENT_DOMAIN);
hasher.update(agent_uri.agent_id().to_string().as_bytes());
let digest = hasher.finalize();
let mut head = [0u8; 4];
head.copy_from_slice(&digest[..4]);
u32::from_be_bytes(head) & (page_count(level) - 1)
}
#[must_use]
pub fn page_count(level: u8) -> u32 {
1u32 << level.min(MAX_SHARD_LEVEL)
}
#[must_use]
pub fn path_and_ancestors(path: &CapabilityPath) -> Vec<String> {
let segments = path.segments();
(1..=segments.len())
.map(|depth| {
segments[..depth]
.iter()
.map(agent_uri::PathSegment::as_str)
.collect::<Vec<_>>()
.join("/")
})
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
fn uri(agent: &str) -> AgentUri {
AgentUri::parse(&format!("agent://anthropic.com/assistant/chat/{agent}")).unwrap()
}
fn trust_root() -> TrustRoot {
TrustRoot::parse("anthropic.com").unwrap()
}
fn hex(key: &RecordKey) -> String {
use std::fmt::Write as _;
key.as_ref().iter().fold(String::new(), |mut out, byte| {
let _ = write!(out, "{byte:02x}");
out
})
}
#[test]
fn derivation_matches_the_specs_test_vectors() {
let root = trust_root();
let agent = uri("llm_01h455vb4pex5vsknk084sn02q");
assert_eq!(
hex(&identity_key(&agent)),
"90a4a81f9c9170054bb24aa43c96d6f228a4af6eb494af2deb9b01fe342f84e0"
);
assert_eq!(
hex(&descriptor_key(&root, "assistant/chat")),
"d40a062c6be6ecfdec023bb8b2de9c33ce438b1e1f9a3a1f5810dd692daa6d48"
);
assert_eq!(
hex(&page_key(&root, "assistant/chat", 0)),
"5f5cb6dbffabc05bcb29216212b86c4b1372881218406df99aeaebd944a81494"
);
assert_eq!(
hex(&page_key(&root, "assistant/chat", 1)),
"53e0301a0584471036c44b3a6fcc5c67d7c0308498a062f83dc1f7e51a29e5ea"
);
for (level, page) in [(0u8, 0u32), (1, 1), (2, 1), (3, 1), (4, 9)] {
assert_eq!(page_for(&agent, level), page, "level {level}");
}
}
#[test]
fn identity_key_is_deterministic() {
assert_eq!(
identity_key(&uri("llm_01h455vb4pex5vsknk084sn02q")),
identity_key(&uri("llm_01h455vb4pex5vsknk084sn02q"))
);
}
#[test]
fn identity_key_ignores_query_and_fragment() {
let plain =
AgentUri::parse("agent://anthropic.com/assistant/chat/llm_01h455vb4pex5vsknk084sn02q")
.unwrap();
let decorated = AgentUri::parse(
"agent://anthropic.com/assistant/chat/llm_01h455vb4pex5vsknk084sn02q?version=2#sum",
)
.unwrap();
assert_eq!(identity_key(&plain), identity_key(&decorated));
}
#[test]
fn different_agents_get_different_identity_keys() {
assert_ne!(
identity_key(&uri("llm_01h455vb4pex5vsknk084sn02q")),
identity_key(&uri("llm_01h455vb4pex5vsknk084sn02r"))
);
}
#[test]
fn the_three_key_kinds_never_collide() {
let root = trust_root();
let identity = identity_key(&uri("llm_01h455vb4pex5vsknk084sn02q"));
let descriptor = descriptor_key(&root, "assistant/chat");
let page = page_key(&root, "assistant/chat", 0);
assert_ne!(identity, descriptor);
assert_ne!(identity, page);
assert_ne!(descriptor, page);
}
#[test]
fn pages_of_one_path_are_distinct() {
let root = trust_root();
let a = page_key(&root, "assistant", 0);
let b = page_key(&root, "assistant", 1);
assert_ne!(a, b);
}
#[test]
fn trust_roots_do_not_share_pages() {
let a = page_key(&trust_root(), "assistant", 0);
let b = page_key(&TrustRoot::parse("openai.com").unwrap(), "assistant", 0);
assert_ne!(a, b);
}
#[test]
fn level_zero_puts_everyone_on_one_page() {
assert_eq!(page_for(&uri("llm_01h455vb4pex5vsknk084sn02q"), 0), 0);
assert_eq!(page_count(0), 1);
}
#[test]
fn placement_is_stable_across_a_level_increase() {
for n in 0..64u32 {
let agent = uri(&format!("llm_01h455vb4pex5vsknk084s{n:04}"));
let low = page_for(&agent, 3);
let high = page_for(&agent, 4);
assert!(
high == low || high == low + page_count(3),
"agent moved from page {low} to {high}, which a level-3 reader never visits"
);
}
}
#[test]
fn placement_spreads_across_pages() {
let pages: std::collections::HashSet<u32> = (0..256u32)
.map(|n| page_for(&uri(&format!("llm_01h455vb4pex5vsknk084s{n:04}")), 4))
.collect();
assert!(pages.len() > 8, "only {} of 16 pages used", pages.len());
}
#[test]
fn level_is_capped() {
assert_eq!(page_count(u8::MAX), 1 << MAX_SHARD_LEVEL);
let agent = uri("llm_01h455vb4pex5vsknk084sn02q");
assert!(page_for(&agent, u8::MAX) < page_count(MAX_SHARD_LEVEL));
}
#[test]
fn ancestors_run_shallowest_first() {
let path = CapabilityPath::parse("workflow/approval/finance").unwrap();
assert_eq!(
path_and_ancestors(&path),
vec![
"workflow".to_string(),
"workflow/approval".to_string(),
"workflow/approval/finance".to_string(),
]
);
}
#[test]
fn a_single_segment_path_is_its_own_only_ancestor() {
let path = CapabilityPath::parse("workflow").unwrap();
assert_eq!(path_and_ancestors(&path), vec!["workflow".to_string()]);
}
#[test]
fn ancestor_paths_agree_with_the_specs_key_derivation() {
let path = CapabilityPath::parse("assistant/chat/streaming").unwrap();
let root = trust_root();
for (depth, ancestor) in path_and_ancestors(&path).iter().enumerate() {
let spec_key = agent_uri_dht::DhtKey::derive_at_depth(&root, &path, depth + 1).unwrap();
let mut hasher = Sha256::new();
hasher.update(root.as_str().as_bytes());
hasher.update(b"/");
hasher.update(ancestor.as_bytes());
assert_eq!(spec_key.as_bytes()[..], hasher.finalize()[..]);
}
}
}