ctx.discover()
Discover capabilities of agents registered with the control plane
The ctx.discover() method queries the Agentfield control plane to find available agents and their capabilities, enabling dynamic agent orchestration.
Basic Usage
agent.reasoner('find_agents', async (ctx) => {
const result = await ctx.discover();
return {
totalAgents: result.json?.totalAgents,
capabilities: result.json?.capabilities
};
});Discovery Options
Prop
Type
Response Format
JSON Format (Default)
const result = await ctx.discover({ format: 'json' });
interface DiscoveryResponse {
discoveredAt: string;
totalAgents: number;
totalReasoners: number;
totalSkills: number;
pagination: {
limit: number;
offset: number;
hasMore: boolean;
};
capabilities: AgentCapability[];
}
interface AgentCapability {
agentId: string;
baseUrl: string;
version: string;
healthStatus: string;
deploymentType?: string;
lastHeartbeat?: string;
reasoners: ReasonerCapability[];
skills: SkillCapability[];
}Compact Format
const result = await ctx.discover({ format: 'compact' });
// result.compact contains a condensed representationXML Format
const result = await ctx.discover({ format: 'xml' });
// result.xml contains XML stringExamples
Filter by Tags
agent.reasoner('find_analyzers', async (ctx) => {
const result = await ctx.discover({
tags: ['analysis', 'nlp'],
includeDescriptions: true
});
return result.json?.capabilities.map(agent => ({
id: agent.agentId,
reasoners: agent.reasoners.map(r => ({
name: r.name,
description: r.description
}))
}));
});Find Specific Capability
agent.reasoner('find_sentiment_analyzer', async (ctx) => {
const result = await ctx.discover({
reasoner: 'analyze_sentiment',
healthStatus: 'healthy'
});
if (result.json?.capabilities.length === 0) {
throw new Error('No sentiment analyzer available');
}
// Use the first available agent
const agent = result.json.capabilities[0];
return await ctx.call(`${agent.agentId}.analyze_sentiment`, ctx.input);
});Dynamic Routing
agent.reasoner('smart_route', async (ctx) => {
const { taskType, data } = ctx.input;
// Find agents that can handle this task type
const result = await ctx.discover({
tags: [taskType],
healthStatus: 'healthy',
includeInputSchema: true
});
const available = result.json?.capabilities || [];
if (available.length === 0) {
throw new Error(`No agents available for task: ${taskType}`);
}
// Pick best agent (e.g., by version, load, etc.)
const target = available[0];
const reasoner = target.reasoners[0];
return await ctx.call(`${target.agentId}.${reasoner.name}`, data);
});Agent-Level Discovery
// Outside of a reasoner context
const result = await agent.discover({
tags: ['database'],
limit: 10
});
console.log(`Found ${result.json?.totalAgents} database agents`);With Pagination
agent.reasoner('list_all_agents', async (ctx) => {
const allAgents = [];
let offset = 0;
const limit = 50;
while (true) {
const result = await ctx.discover({ limit, offset });
const capabilities = result.json?.capabilities || [];
allAgents.push(...capabilities);
if (!result.json?.pagination.hasMore) break;
offset += limit;
}
return { totalAgents: allAgents.length, agents: allAgents };
});Use Cases
Service Mesh Pattern
agent.reasoner('orchestrate', async (ctx) => {
// Discover available services
const services = await ctx.discover({
tags: ['microservice'],
healthStatus: 'healthy'
});
// Build service map
const serviceMap = new Map();
for (const svc of services.json?.capabilities || []) {
for (const reasoner of svc.reasoners) {
serviceMap.set(reasoner.name, svc.agentId);
}
}
// Route to appropriate service
const { operation, data } = ctx.input;
const targetAgent = serviceMap.get(operation);
if (!targetAgent) {
throw new Error(`Unknown operation: ${operation}`);
}
return await ctx.call(`${targetAgent}.${operation}`, data);
});Health-Aware Load Balancing
agent.reasoner('load_balance', async (ctx) => {
const { operation, data } = ctx.input;
// Find all healthy instances
const result = await ctx.discover({
reasoner: operation,
healthStatus: 'healthy'
});
const instances = result.json?.capabilities || [];
if (instances.length === 0) {
throw new Error(`No healthy instances for: ${operation}`);
}
// Random selection (simple load balancing)
const target = instances[Math.floor(Math.random() * instances.length)];
return await ctx.call(`${target.agentId}.${operation}`, data);
});Related
- ctx.call() - Execute discovered capabilities
- Agent Class - Agent registration
- REST API Discovery - HTTP discovery endpoint