Coordination
Service Discovery
Find agents, reasoners, and skills at runtime through the control plane discovery API.
Find every agent, reasoner, and skill in your fleet -- at runtime, not at deploy time.
Hard-coded service addresses break the moment you scale past a handful of agents. AgentField's discovery API lets any agent query the control plane for live capabilities, filtered by tags, health status, or name patterns. Build orchestrators that discover what is available, introspect input schemas, and dynamically decide which agents to call -- all without a single hardcoded address.
@app.reasoner(tags=["orchestrator"])
async def dynamic_router(question: str) -> dict:
# 1. Discover active agents with input schemas — zero hardcoded addresses
caps = app.discover(
tags=["public"],
health_status="active",
include_input_schema=True,
format="json",
)
print(f"{caps.json.total_agents} agents online, {len(caps.json.capabilities)} capabilities")
# 2. Feed discovered capabilities + schemas into an LLM — it picks the best agent
result = await app.ai(
system=(
"You are a routing agent. Pick the best tool for the user's question.\n"
"Available capabilities:\n" + caps.raw
),
user=question,
tools="discover", # built-in: turns discovered capabilities into callable tools
)
# 3. The LLM chose an agent and called it — no static routing table needed
return result
# New agents register at startup → the router discovers them automatically.
# No config changes, no redeployment, no service mesh.agent.reasoner('dynamicRouter', async (ctx) => {
// 1. Discover active agents with input schemas — zero hardcoded addresses
const caps = await agent.discover({
tags: ['public'],
healthStatus: 'active',
includeInputSchema: true,
format: 'json',
});
console.log(`${caps.json?.totalAgents} agents online`);
// 2. Feed discovered capabilities + schemas into an LLM — it picks the best agent
const result = await ctx.ai(ctx.input.question, {
system: `You are a routing agent. Pick the best tool.\nAvailable:\n${caps.raw}`,
});
// 3. The LLM chose an agent and called it — no static routing table needed
return result;
});
// New agents register at startup → the router discovers them automatically.a.RegisterReasoner("dynamic_router", func(ctx context.Context, input map[string]any) (any, error) {
// 1. Discover active agents with input schemas — zero hardcoded addresses
caps, err := a.Discover(ctx,
agent.WithTags([]string{"public"}),
agent.WithHealthStatus("active"),
agent.WithDiscoveryInputSchema(true),
agent.WithFormat("json"),
)
if err != nil {
return nil, err
}
fmt.Printf("%d agents online, %d capabilities\n",
caps.JSON.TotalAgents, len(caps.JSON.Capabilities))
// 2. Use compact format in LLM context for dynamic tool selection
// 3. Route to the best agent based on discovered capabilities
return map[string]any{
"available_agents": caps.JSON.TotalAgents,
"capabilities": caps.JSON.Capabilities,
}, nil
})
// New agents register at startup → the router discovers them automatically.What just happened
- The agent queried the live control plane registry instead of relying on hardcoded targets
- Discovery results included enough metadata to drive dynamic routing decisions
- New active agents could appear in routing immediately after registration
Example discovery summary:
{
"discovered_at": "2026-03-23T12:00:00Z",
"total_agents": 2,
"total_reasoners": 2,
"total_skills": 0,
"pagination": { "limit": 100, "offset": 0, "has_more": false },
"capabilities": [
{
"agent_id": "weather-agent",
"base_url": "http://weather-agent:9000",
"version": "1.0.0",
"health_status": "active",
"deployment_type": "sidecar",
"last_heartbeat": "2026-03-23T12:00:00Z",
"reasoners": [
{ "id": "forecast", "tags": ["public", "weather"], "invocation_target": "weather-agent:forecast" }
],
"skills": []
},
{
"agent_id": "translator",
"base_url": "http://translator:9000",
"version": "1.0.0",
"health_status": "active",
"deployment_type": "sidecar",
"last_heartbeat": "2026-03-23T12:00:00Z",
"reasoners": [
{ "id": "translate", "tags": ["public", "translation"], "invocation_target": "translator:translate" }
],
"skills": []
}
]
}