Operations
Agent CRD
An Agent is a saved agentic-search configuration as a resource. It binds an
inference model, a turn budget, and a set of indices
to a name, so a caller searches with
POST /v2/agents/{name}/query and sends only a query string.
Everything that decides what a call costs and what it can read lives on the
resource, not in the request.
An agent adds no retrieval primitive. Its only tool is the
federated query; it sits one level above the
Auto router, using a model to reformulate the
query, fan out for recall, and score the candidates for relevance. What it returns
is the same row shape as every other search endpoint — a better-ranked result set,
not a generated answer.
Like the other CRDs here, an Agent has two authoring surfaces that round-trip
through one schema: kubectl get agent -o yaml and
client.agent("support-search").apply() are two spellings of the same object.
apiVersion: hevlayer.com/v1alpha1
kind: Agent
metadata:
name: support-search
namespace: layer
spec:
model:
provider: openrouter
name: anthropic/claude-haiku-4-5
fallback: anthropic/claude-sonnet-4-6 # optional; used on primary timeout/error
apiKeySecretRef:
name: openrouter
key: credential
budget:
deadlineMs: 60000
onDeadline: bestEffort
indices: [docs, tickets]
retrieval:
fanout: 8
recallDepth: 50
rankBy: auto
relevanceWeight: 0.6
output:
provenance: false
trace: false
status:
phase: Ready
conditions:
- type: SecretResolved
status: "True"
- type: ModelReachable
status: "True"
- type: IndicesResolved
status: "True"
Model
| Field | Purpose |
|---|---|
provider | Inference backend. openrouter. |
name | Model id passed to the provider, e.g. anthropic/claude-haiku-4-5. |
fallback | Optional model used when the primary times out or errors. |
apiKeySecretRef | Secret holding the provider credential (name, key). The token is never inline on the resource — the same rule the ApiKey and VectorStore CRDs follow. |
Budget
| Field | Purpose |
|---|---|
deadlineMs | Wall-clock deadline for the whole request. |
onDeadline | bestEffort (default) returns the best ranking the agent has when the deadline hits; error fails the request instead. |
Indices
indices is the set of namespaces the agent searches, passed to the
federated query as its namespaces. The operator
checks that the list is present and every entry is a non-empty string, surfaced
as the IndicesResolved condition; it does not currently confirm each entry
names a namespace that exists. The agent reads each listed namespace under the
caller’s credential, so a caller only reaches the namespaces its own key grants.
Retrieval
All retrieval behavior is expressed against the federated query — nothing new reaches the upstream.
| Field | Default | Purpose |
|---|---|---|
fanout | 8 | Query reformulations the agent issues, run in parallel via layer’s scatter/gather and merged for recall. Higher fan-out trades latency for recall. |
recallDepth | 50 | Candidates gathered for ranking before top_k, at least top_k. Bounds how much the model reads. |
rankBy | auto | Default route per leg: auto, hybridText, or semantic. A semantic leg needs a query vector, which the caller supplies on the request (vector) — layer never embeds query text; see Agentic search. Without a supplied vector, semantic legs fall back to the lexical route. |
relevanceWeight | 0.6 | Weight of the relevance score against the recall score in the final ranking. |
Output
| Field | Purpose |
|---|---|
provenance | When true, each row carries a $agent field with its retrievalScore and relevanceScore, and the response gains a top-level agent echo. |
trace | When true, the agent echo also carries the full reasoning trace. |
Default off, the response is byte-for-byte the federated query shape: a client cannot tell a reasoning loop produced it.
See Agentic search for the request and response contract.
Auth
Auth follows the same model as the other API endpoints; multi-namespace queries
follow federated query auth behavior. Who
may invoke an agent is an agent.<name> entitlement on the
ApiKey.
Status
status carries health and validation only; latency, turn counts, and spend go to
metrics and history, never into etcd.
| Condition | Meaning |
|---|---|
SecretResolved | model.apiKeySecretRef exists and is readable. |
ModelReachable | the provider answered with the bound credential. |
IndicesResolved | spec.indices is non-empty and every entry is a non-empty string. (It does not yet verify each entry is a known namespace.) |
| Phase | Meaning |
|---|---|
Ready | Resolvable and callable. |
Degraded | Reachable but a condition is failing — calls may fall back or error. |
Invalid | A required field or reference does not resolve; calls are refused. |
kubectl get agent print columns: MODEL, INDICES, PHASE.
Edits are picked up shortly after they apply: the gateway resolves agents — spec,
provider credential, and per-index schema — into memory and refreshes on a periodic
tick, so a kubectl apply lands within the refresh interval rather than instantly.
Naming
Agent names are cluster-unique at the gateway because callers address agents by name only. If two namespaces define the same Agent name, the gateway sorts by agent name and namespace, keeps the lexicographically later namespace, and logs a warning naming both namespaces. Keep Agent names unique across the cluster.
Observability
Deadline-hit rate, provider latency, and token usage per agent export as
hevlayer_* metrics. Token counts come back on the inference response, so they
cost no extra call; dollar cost is derived from them downstream rather than fetched
in the request path. The reasoning trace is written to the
search-history record alongside the query it belongs
to, so agentic and plain searches share one history surface for evaluation.