@sema-agent/core
Version:
Stateless, task-oriented AI agent core
72 lines (71 loc) • 2.69 kB
JavaScript
import { createHash } from "node:crypto";
export const PEER_REF_MIN = 6;
export const PEER_REF_MAX = 12;
export const PEER_REF_RE = /^[0-9a-f]{6,12}$/;
function refHash(e) {
return createHash("sha256").update(`${e.kind}:${e.id}`).digest("hex");
}
function commonPrefixLen(a, b) {
let n = 0;
while (n < a.length && n < b.length && a[n] === b[n])
n++;
return n;
}
export function mintPeerRef(entries, self) {
const hashes = entries.map(refHash);
const universe = [...new Set([...hashes, ...(self !== undefined ? [refHash(self)] : [])])].sort();
const lengths = new Map();
for (let i = 0; i < universe.length; i++) {
const h = universe[i];
const shared = Math.max(i > 0 ? commonPrefixLen(h, universe[i - 1]) : 0, i + 1 < universe.length ? commonPrefixLen(h, universe[i + 1]) : 0);
lengths.set(h, Math.min(h.length, Math.max(PEER_REF_MIN, shared + 1)));
}
return entries.map((e, i) => {
const h = hashes[i];
return { ...e, ref: h.slice(0, Math.min(lengths.get(h), PEER_REF_MAX)) };
});
}
export function formatPeerNameRef(name, ref) {
return `${name} [${ref}]`;
}
export function parsePeerNameRef(text) {
const m = /^(.*\S)\s*\[([0-9a-f]{6,12})\]$/.exec(text.trim());
return m === null ? undefined : { name: m[1], ref: m[2] };
}
export function normalizePeerName(name) {
return name
.normalize("NFKC")
.replace(/[\p{Cc}\p{Cf}]/gu, "")
.trim()
.toLowerCase()
.replace(/\s+/g, "-");
}
export const PEER_ADDRESS_PREFIXES = Object.freeze(["session.", "principal."]);
export const PRINCIPAL_INBOX_HANDLE = "principal.inbox";
const SOCKET_PATH_RE = /^\/\S*\.sock/;
const NAMED_PIPE_RE = /^[\\/]{2}[.?][\\/]pipe[\\/]/i;
function isSocketPathSpelling(text) {
return SOCKET_PATH_RE.test(text) || NAMED_PIPE_RE.test(text);
}
export const RESERVED_AGENT_NAMES = Object.freeze(["main", "team-lead", "user", "system"]);
const AGENT_ID_SHAPE_RE = /^a(?:[\w-]{1,63}-)?[0-9a-f]{16}$/;
export function reservedPeerNameReason(name) {
const key = normalizePeerName(name);
if (key === "")
return "empty";
if (key === "*")
return "wildcard";
if (key.includes("@"))
return "at_sign";
if (PEER_ADDRESS_PREFIXES.some((p) => key.startsWith(p)))
return "address_prefix";
if (/^(?:uds|bridge|did):/.test(key))
return "transport_scheme";
if (isSocketPathSpelling(name) || isSocketPathSpelling(key))
return "socket_path";
if (RESERVED_AGENT_NAMES.includes(key))
return "reserved_name";
if (AGENT_ID_SHAPE_RE.test(key))
return "agent_id_shape";
return undefined;
}