Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions packages/agent/src/discovery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,31 @@ export class DiscoveryClient {
}));
}

/**
* OT-RFC-55 §5.1 — the READ side of the "context-oracle" phonebook: which peers
* advertise that they serve the (public) context graph `contextGraphId`. Reads
* the `skill:contextGraphsServed` triples published by {@link buildAgentProfile}
* into the agents registry CG. Only public, subscribed, non-system CGs are ever
* advertised there (the publish side filters), so this never leaks private CGs.
*
* Strictly local (over this node's synced copy of the agents CG), so coverage is
* bounded by agents-CG gossip freshness — same caveat as {@link findAgents}.
*/
async findNodesServingCG(contextGraphId: string): Promise<string[]> {
const sparql = `
SELECT DISTINCT ?peerId WHERE {
?agent <${DKG}peerId> ?peerId ;
<${SKILL}hostingProfile> ?hosting .
?hosting <${SKILL}contextGraphsServed> "${escapeSparqlLiteral(contextGraphId)}" .
}
`;
const result = await this.engine.query(sparql, { contextGraphId: AGENT_REGISTRY_CONTEXT_GRAPH });
const peers = result.bindings
.map((row) => stripQuotes(row['peerId']))
.filter((p): p is string => typeof p === 'string' && p.length > 0);
return Array.from(new Set(peers));
}

async findSkillOfferings(options: SkillSearchOptions = {}): Promise<DiscoveredOffering[]> {
const filters: string[] = [];

Expand Down
Loading
Loading