@sema-agent/core
Version:
Stateless, task-oriented AI agent core
47 lines (46 loc) • 1.89 kB
JavaScript
const NAME_SEP = "__";
function makeProtocolNamespace(id, prefix) {
const parse = (name) => {
if (!name.startsWith(prefix))
return undefined;
const rest = name.slice(prefix.length);
const sep = rest.indexOf(NAME_SEP);
if (sep <= 0)
return undefined;
const tool = rest.slice(sep + NAME_SEP.length);
if (tool.length === 0)
return undefined;
return { peer: rest.slice(0, sep), tool };
};
const makeName = (peer, tool) => {
if (peer.length === 0 || tool.length === 0) {
throw new Error(`protocol table (${id}): peer and tool must both be non-empty (got peer=${JSON.stringify(peer)}, tool=${JSON.stringify(tool)})`);
}
if (peer.includes(NAME_SEP)) {
throw new Error(`protocol table (${id}): peer must not contain the ${NAME_SEP} separator (got ${JSON.stringify(peer)}) — the composed name would parse back as a DIFFERENT peer`);
}
return `${prefix}${peer}${NAME_SEP}${tool}`;
};
return {
id,
prefix,
makeName,
parse,
displayGroupKey: (name) => {
const p = parse(name);
return p === undefined ? name : `${prefix}${p.peer}${NAME_SEP}*`;
},
};
}
const MCP_PREFIX_NAME = `mcp${NAME_SEP}`;
const A2A_PREFIX_NAME = `a2a${NAME_SEP}`;
export const MCP_NAMESPACE = makeProtocolNamespace("mcp", MCP_PREFIX_NAME);
export const A2A_NAMESPACE = makeProtocolNamespace("a2a", A2A_PREFIX_NAME);
export const PROTOCOL_TABLE = [MCP_NAMESPACE, A2A_NAMESPACE];
export const NAMESPACED_NAME_SHAPES = PROTOCOL_TABLE.map((ns) => `${ns.prefix}<peer>__<tool>`).join(", ");
export function carriesNamespaceSeparator(name) {
return name.includes(NAME_SEP);
}
export function protocolOf(name) {
return PROTOCOL_TABLE.find((ns) => name.startsWith(ns.prefix));
}