Skip to Content

Query

A Query is a request to run work on an Ark resource. The CRD ships an input plus exactly one of target (a single agent / team / model / tool) or selector (picks a single target by label — first match wins, not a fan-out). For a task-oriented walkthrough see User Guide → Run queries / chat with agents and teams; this page is the field-by-field reference.

Spec

apiVersion: ark.mckinsey.com/v1alpha1 kind: Query metadata: name: example-query spec: # --- Required ---------------------------------------------------------- input: "What's the weather in {{.city}}?" # user message (string) # Exactly ONE of target or selector is required. target: type: agent # agent | team | model | tool name: weather-agent # OR pick a single target by label (first match wins; not a fan-out). # selector: # matchLabels: # role: reviewer # --- Common optional fields -------------------------------------------- type: user # only 'user' is accepted (default) parameters: # template values for {{.name}} in input - name: city value: Boston conversationId: chat-alice-001 # thread queries into one conversation memory: name: broker # Memory resource that stores history sessionId: user-session-123 # telemetry / tracking key (separate from conversationId) serviceAccount: my-sa # RBAC for execution timeout: 5m # default '5m' ttl: 720h # default from ArkConfig/default (720h fallback) cancel: false # set to true to cancel mid-flight overrides: # HTTP header overrides for downstream model/MCP calls - resourceType: model headers: - name: X-Trace-ID value: value: trace-xyz789

Fields

FieldTypeRequiredDescription
spec.inputstringyesThe user message. Supports Go template substitution via {{.name}} against spec.parameters.
spec.targetobjectconditionalSingle execution target. Either target or selector must be set — the validation webhook rejects queries with neither.
spec.target.typeenum (agent, team, model, tool)yes (when target set)Resource kind to dispatch to.
spec.target.namestringyes (when target set)Name of the target resource in the same namespace.
spec.selectorLabelSelectorconditionalPick a single target by label (alternative to target). Resolves to the first matching resource, checked in order Agent → Team → Model → Tool. Not a fan-out — it does not run against multiple matches. Empty match set fails with no matching resources found for selector.
spec.typeenum (user)noOnly user is accepted (default). The previous messages type is deprecated; the mutating webhook migrates it to user and stamps a migration-warning-input-type annotation.
spec.parameters[]listnoTemplate values substituted into input (and into any agent prompt that references queryParameterRef). Each entry has a name and either a value or valueFrom (configMapKeyRef, secretKeyRef).
spec.memory.namestringnoName of a Memory resource that stores conversation history keyed by conversationId. If unset, the completions executor falls back to a Memory named default in the same namespace; if that doesn’t exist either, it uses a no-op (in-process) store.
spec.sessionIdstringnoIdentifier for grouping queries in tracking / telemetry. Auto-derived from the Query UID if unset. Not the same as conversationIdsessionId is observability, conversationId is memory continuity.
spec.conversationIdstringnoConversation threading identifier. Sent to execution engines as the A2A contextId. With memory active, ties subsequent queries to the same history. Auto-generated by the memory backend if unset (a new conversation is created and the ID written back to status.conversationId).
spec.serviceAccountstringnoKubernetes ServiceAccount used for RBAC during execution.
spec.timeoutdurationnoExecution timeout (30s, 5m, 1h). Defaults to 5m. Applies to all targets in the query.
spec.ttldurationnoHow long the Query resource lingers after completion. Mutating webhook resolves the default from ArkConfig/default.spec.queryTTL (falls back to 720h).
spec.cancelboolnoWhen true, indicates intent to cancel a running query. The controller transitions the query to phase: canceled.
spec.overrides[]listnoHTTP header overrides applied when the query’s target calls its model or any MCP server. See Overrides.

Targets

A query dispatches to exactly one target — named directly via spec.target, or picked by label via spec.selector. Supported type values: agent, team, model, tool.

spec: input: "Summarise the news." target: type: team name: news-team

Pick by label (resolves to a single target — first match across Agent → Team → Model → Tool):

spec: input: "Should we ship this feature?" selector: matchLabels: role: reviewer

The webhook enforces that one of target / selector is set, and that the named resource exists when target is used.

Parameters

Parameters are substituted into spec.input (and into agent prompts that declare queryParameterRef) before dispatch. Sources:

spec: input: "Hit {{.endpoint}} with token {{.key}}, mode {{.mode}}." parameters: - name: mode value: "production" # direct value - name: endpoint valueFrom: configMapKeyRef: # from ConfigMap name: api-config key: url - name: key valueFrom: secretKeyRef: # from Secret name: api-credentials key: api-key

Template syntax is Go templates: {{.parameter_name}}. Names must match the parameters[].name field.

Wiring parameters into the agent

Agents can pull the same query parameters into their own prompt or system message using queryParameterRef:

apiVersion: ark.mckinsey.com/v1alpha1 kind: Agent metadata: name: dynamic-agent spec: prompt: | You are running in {{.mode}} mode against {{.environment}}. parameters: - name: mode valueFrom: queryParameterRef: name: operation_mode - name: environment valueFrom: queryParameterRef: name: target_env

The matching query supplies them:

apiVersion: ark.mckinsey.com/v1alpha1 kind: Query metadata: name: parameterised-q1 spec: input: "Run a health check." parameters: - name: operation_mode value: "production" - name: target_env value: "us-west-2" target: type: agent name: dynamic-agent

See Agents → Pass parameter values at query time for the dashboard walkthrough.

Conversations + memory

conversationId threads queries together; Memory stores the history. By default the completions executor uses the Memory named default in the query’s namespace when spec.memory is unset — most Ark installs ship one backed by the in-cluster broker. Two queries with the same conversationId share context as long as they hit the same memory store:

apiVersion: ark.mckinsey.com/v1alpha1 kind: Query metadata: name: chat-q1 spec: input: "Hi, my name is Alice." conversationId: chat-alice-001 memory: name: broker target: type: agent name: assistant --- apiVersion: ark.mckinsey.com/v1alpha1 kind: Query metadata: name: chat-q2 spec: input: "What's my name?" conversationId: chat-alice-001 # same conversation memory: name: broker target: type: agent name: assistant

sessionId is a separate identifier for telemetry — same telemetry session can contain many distinct conversations.

If you set conversationId without spec.memory, the executor still resolves the default Memory (so continuity works out of the box on a standard install). The conversationId also flows through to execution engines as the A2A contextId — named engines (Claude Agent SDK, LangChain, …) can use it for their own session model.

If you set memory without conversationId, the controller auto-generates a fresh conversationId on each query.

Timeout

spec.timeout caps execution. Default is 5m. Format follows Go’s time.ParseDuration (30s, 5m, 1h).

  • Completes within timeout → status.phase: done.
  • Exceeds timeout → status.phase: error with a timeout error message in status.response.content.

For A2A agents the timeout flows through as a Go context deadline. A2A servers can also enforce their own per-server timeouts via A2AServer.spec.timeout — see Building A2A Servers → Timeout configuration.

Cancel

To cancel a running query, patch spec.cancel: true:

kubectl patch query slow-q1 --type='merge' -p='{"spec":{"cancel": true}}'

The controller transitions the query to phase: canceled once the in-flight dispatch acknowledges. The dashboard chat panel does the same when you click Stop on an embedded chat.

Deletion and cleanup

When a Query is deleted, a controller finalizer removes the messages and operation events that query wrote to the broker, so deleting a Query does not leave orphaned history behind.

Messages go through the Memory contract:

  • Memory resolution mirrors execution: the controller uses spec.memory if set, otherwise a Memory named default in the query’s namespace. If neither exists, cleanup is skipped.
  • The controller resolves the backend address from the Memory resource (status.lastResolvedAddress, falling back to spec.address) and issues DELETE /queries/{queryId}/messages against it — see the Memory delete endpoint.

Operation events are not part of the Memory contract, so they use a separate path:

  • The controller discovers the broker endpoint from the ark-config-broker ConfigMap and issues DELETE /events/{queryId} directly against it. If no broker is configured for the namespace, cleanup is skipped.
  • Events are keyed by the Query’s UID, not its name (unlike messages), so {queryId} here is the UID.

Both cleanups run independently and either can fail without blocking the other. A backend that does not implement a delete endpoint returns 404/405, which the controller treats as “not supported” and skips. Scope: messages and events only — chunks and traces are not affected. Failure policy: if a backend is unreachable the finalizer retries every 15s; after a 5-minute grace period it gives up and removes itself, so a Query is never stuck in Deleting.

This is complementary to spec.ttl: TTL expires history on a timer, while deletion cleans it up immediately when the Query is removed.

Status

status: phase: done conditions: - type: Completed status: "True" reason: QuerySucceeded message: Query completed successfully conversationId: ctx-86e022b0-1f4f-49f5-bc4b-e0d6437a789b duration: 1.82s response: target: type: agent name: weather-agent content: "It's 72°F and sunny in New York" raw: '[{"content":"...","role":"assistant","name":"weather-agent"}]' phase: done a2a: contextId: ctx-86e022b0-1f4f-49f5-bc4b-e0d6437a789b taskId: task-xyz789 tokenUsage: promptTokens: 97 completionTokens: 20 totalTokens: 117

Status fields

FieldDescription
status.phaseOne of pending, provisioning, running, done, error, canceled.
status.conditions[]Standard Kubernetes conditions. The Completed condition flips to True on success or failure.
status.responseSingle response object (singular — there is no responses[] array). A selector resolves to one target, so there is always exactly one response.
status.response.contentThe final assistant message.
status.response.rawThe full conversation as a JSON-encoded array of messages — what the dashboard’s Debug tab renders.
status.response.phasePer-response phase (mirrors top-level phase).
status.response.targetThe target the response is for.
status.response.a2a.contextIdA2A context ID returned by the engine. When conversationId is set on the spec, the engine receives it as the contextId and echoes it back here.
status.response.a2a.taskIdSet when the target is an A2A agent and a task was created. References an A2ATask resource — see A2ATask.
status.conversationIdEffective conversation ID — either the one you supplied, or the auto-generated one when memory is set without a conversationId.
status.durationTotal wall-clock execution time.
status.tokenUsagepromptTokens, completionTokens, totalTokens from the underlying model call.

Phases

PhaseMeaning
pendingResource accepted by admission, controller hasn’t picked it up yet.
provisioningController is preparing the dispatch (parameter resolution, target lookup).
runningDispatched to the executor; waiting for the response.
doneExecution finished successfully.
errorExecution failed; details in status.response.content.
canceledspec.cancel: true was honoured.

kubectl get queries prints Type, Phase, Duration, Age. Pipe through -o jsonpath for the content/raw fields.

Webhook validation

Enforced by ark/internal/validation/query.go:

  • Exactly one of spec.target and spec.selector is required.
  • When spec.target is set, the named resource must exist in the namespace and target.type must be one of agent, team, model, tool.
  • Parameter resolution must succeed (referenced ConfigMaps and Secrets must exist).
  • spec.overrides[] must reference real resources for any valueFrom source.

Mutating webhook

Enforced by ark/internal/validation/defaults.go:

  • spec.type: messages is deprecated. The mutating webhook extracts the last user-message text, sets spec.type: user, replaces spec.input with that text, and stamps an ark.mckinsey.com/migration-warning-input-type annotation. Use conversationId for multi-turn instead.
  • spec.ttl is defaulted from ArkConfig/default.spec.queryTTL (or 720h if absent).
Last updated on