Discovery Flow
The Discovery Flow uses straightforward HTTP-based lookup that can handle millions of agents efficiently, instead of complex multi-step discovery protocols.
Design
Key Concepts:
- No complex handshakes - direct capability lookup
- No peer-to-peer discovery - centralized registry for efficiency
- No elaborate filtering - simple capability matching
- Immediate connection - no discovery negotiation
Discovery Methods
Primary: HTTP Registry Lookup
Step 1: Query registry for capability
GET /agents?capability=text-translation HTTP/1.1
Host: wwww.openhive.sh
# Response:
{
"agents": [
{
"agent_id": "hive:agentid:translator123",
"type": "capability_response",
"data": {
"capabilities": [
{
"id": "text-translation",
"input": { "text": "string", "target_lang": "string" },
"output": { "translated_text": "string" }
}
],
"endpoint": "https://translator123.example.com/api",
"last_seen": "2025-07-18T14:30:00Z"
},
"sig": "ed25519_signature_here"
},
{
"agent_id": "hive:agentid:translator456",
"type": "capability_response",
"data": {
"capabilities": [
{
"id": "text-translation",
"input": { "text": "string", "target_lang": "string" },
"output": { "translated_text": "string" }
}
],
"endpoint": "https://translator456.example.com/api",
"last_seen": "2025-07-18T14:29:45Z",
},
"sig": "ed25519_signature_here"
}
]
}Step 2: Pick an agent and send task directly
// Simple agent selection (pick first available)
async function findAndUseAgent(capability, taskData) {
// 1. Discover agents
const response = await fetch(
`https://www.openhive.sh/agents?capability=${capability}`
);
const { agents } = await response.json();
if (agents.length === 0) {
throw new Error(`No agents found for capability: ${capability}`);
}
// 2. Pick first agent (or implement your selection logic)
const selectedAgent = agents[0];
// 3. Send task immediately
const taskRequest = {
from: CLIENT_ID,
to: selectedAgent.agent_id,
type: "task_request",
data: {
task_id: generateTaskId(),
capability: capability,
...taskData,
},
};
const signedRequest = {
...taskRequest,
sig: signMessage(taskRequest),
};
// 4. Send to agent
const taskResponse = await fetch(`${selectedAgent.endpoint}/tasks`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(signedRequest),
});
return await taskResponse.json();
}Fallback: Direct Agent Query
If you know an agent's endpoint, query it directly:
// Direct capability query
async function queryAgentCapabilities(agentEndpoint) {
const response = await fetch(`${agentEndpoint}/capabilities`);
return await response.json();
}
// Check if agent has specific capability
async function agentHasCapability(agentEndpoint, capabilityId) {
const capabilities = await queryAgentCapabilities(agentEndpoint);
return capabilities.capabilities.some((cap) => cap.id === capabilityId);
}Optional: Local Network Discovery (Tier 2+)
For local networks, use mDNS service discovery:
// mDNS discovery (Node.js example)
const mdns = require("mdns");
// Advertise your agent
const ad = mdns.createAdvertisement(mdns.tcp("hive"), 3000, {
txtRecord: {
agent_id: AGENT_ID,
capabilities: "text-processing,image-resize",
},
});
ad.start();
// Discover other agents
const browser = mdns.createBrowser(mdns.tcp("hive"));
browser.on("serviceUp", (service) => {
console.log("Found agent:", service.txtRecord.agent_id);
console.log("Capabilities:", service.txtRecord.capabilities);
console.log("Endpoint:", `http://${service.addresses[0]}:${service.port}`);
});
browser.start();Agent Selection Strategies
Simple Selection
// Pick first available agent
function selectAgent(agents) {
return agents[0];
}Smart Selection
// Select based on multiple factors
function selectBestAgent(agents, criteria) {
return agents
.filter((agent) => agent.last_seen > Date.now() - 300000) // Active in last 5 minutes
.sort((a, b) => {
// Prefer agents with fewer capabilities (more specialized)
if (a.capabilities.length !== b.capabilities.length) {
return a.capabilities.length - b.capabilities.length;
}
// Prefer more recently seen agents
return new Date(b.last_seen) - new Date(a.last_seen);
})[0];
}Registry Implementation
Simple registry for development:
// Simple in-memory registry
const agents = new Map();
// Register agent
app.post("/agents", (req, res) => {
const { agent_id, endpoint, capabilities } = req.body;
agents.set(agent_id, {
agent_id,
endpoint,
capabilities: capabilities.map((cap) => cap.id),
last_seen: new Date().toISOString(),
full_capabilities: capabilities,
});
res.json({ status: "registered" });
});
// Discover agents
app.get("/agents", (req, res) => {
const capability = req.query.capability;
const matchingAgents = Array.from(agents.values())
.filter((agent) => {
if (!capability) return true;
return agent.capabilities.includes(capability);
})
.map((agent) => ({
agent_id: agent.agent_id,
endpoint: agent.endpoint,
capabilities: agent.capabilities,
last_seen: agent.last_seen,
}));
res.json({ agents: matchingAgents });
});
// Heartbeat to keep agents active
app.post("/agents/:agentId/heartbeat", (req, res) => {
const agent = agents.get(req.params.agentId);
if (agent) {
agent.last_seen = new Date().toISOString();
res.json({ status: "updated" });
} else {
res.status(404).json({ error: "agent_not_found" });
}
});Scale Optimization: The simplified discovery flow can handle millions of agents efficiently by eliminating complex negotiation and using straightforward HTTP queries.
Registry Dependency: Relies on registry availability. Implement fallback mechanisms (cached agents, direct connections) for production systems.
Performance: Cache discovery results and implement agent heartbeats to maintain accurate availability information.
