Route by capability
Send a capability to the right agent, and change which agent serves it without touching the applications that call it.
Before you begin#
You need at least one healthy agent that declares the capability you want to route. Check what is available:
kubectl get agents -A
An agent must be Ready and registered or managed in the Registry to be routable. Degraded agents are deliberately skipped, and so is an agent whose Registry record is still pending: only registered and managed records route. An applied agent is pending in the Registry and does not route until it is approved (the approval service, issue #727, is not built yet) or, on a profile that sets registry.operatorWritesAreApprovals=true, until an operator write is taken as the approval. That setting records no person’s decision, and with Registry write authentication off, the default, any caller that can reach the write API can make a record routable. local-light, local-durable, demo-observability and demo-registration set it when their file is passed (not for an older release upgraded with --reuse-values: see Install with Helm); the chart default, enterprise-baseline, enterprise-postgres and secure-production do not. On PostgreSQL storage, turning it on later affects agents created afterwards, not one that is already pending; on memory storage the restart that turning it on causes loses the Registry’s records, and the Operator’s next republish creates each agent again as registered (read from the chart and the Registry code; not run on a cluster).
Declare the capability on the agent#
spec:
capabilities:
- name: refund-processing
description: Evaluates and drafts customer refunds.
Create the route#
apiVersion: agentfleet.io/v1alpha1
kind: AgentRoute
metadata:
name: refund-processing-route
namespace: agentfleet-demo
spec:
routeType: capability
capabilities:
- refund-processing
priority: 100
enabled: true
kubectl apply -f refund-route.yaml
Verify#
Ask for the capability and read which agent answered and why:
curl -s http://127.0.0.1:8080/v1/run \
-H 'Content-Type: application/json' \
-d '{"tenant":"retail","capability":"refund-processing","input":{"message":"test"}}' \
| grep -o '"route":{[^}]*}'
"route":{"mode":"capability",
"reason":"Matched healthy agent by capability."}
route.reason is the scheduler explaining itself. When routing surprises you, this field tells
you whether the decision came from priority, health, or a fallback.
Shifting traffic between agents#
Give the replacement a higher priority and both stay eligible, with the new one preferred:
spec:
priority: 120
To drain the old one entirely without deleting anything, disable its route:
spec:
enabled: false
A higher-priority agent that is Degraded still loses to a healthy lower-priority one.
Priority orders candidates; it does not create eligibility.
When no agent matches#
A 409 with no_matching_agent means no healthy and registered or managed agent declared the
capability. An agent whose Registry record is pending is not routed to. Check whether the agent exists but is degraded before assuming the route is wrong:
kubectl get agents -A
kubectl describe agent refund-agent -n agentfleet-demo