Skip to content

Agents overview

A quick tour of every agent shipped with the platform — what it does, the tools it exposes, and the role required to invoke the mutating ones.

For how agents are composed inside orrery-assistant, see ADR-003: Graph Workflow Inversion (which supersedes ADR-002). For how to build your own, see Adding a new agent.

At a glance

Agent Package Tools Guarded tools Primary use
orrery-assistant agents/orrery-assistant orchestrator delegates Top-level entry point — routes to specialists and runs triage / remediation workflows
kafka-health agents/kafka-health 24 9 Kafka cluster health, topic ops, consumer lag, Strimzi-aware
k8s-health agents/k8s-health 26 5 Kubernetes diagnostics, scaling, rollouts, operator-aware (Strimzi / ECK)
observability agents/observability 16 2 Prometheus queries, Loki logs, Alertmanager silences
elasticsearch agents/elasticsearch 24 0 ES cluster/index/shard diagnostics, search, ILM, snapshots, ECK-aware
docker-agent agents/docker-agent 17 6 Container inspection and lifecycle ops
ops-journal agents/ops-journal 10 0 Cross-session notes, preferences, and team bookmarks

Guarded tool counts

Counts reflect tools marked @confirm (operator+) or @destructive (admin-only). Unmarked tools are read-only and accessible to any viewer. See Testing RBAC across surfaces to exercise each tier.

Restricting where, not just what

Set ORRERY_PROTECTED_NAMESPACES (comma-separated globs, e.g. kube-system,kube-*,monitoring*) to stop non-admins mutating in infrastructure namespaces. An operator can then restart an application Deployment but not one in kube-system — same tool, very different blast radius. Reads are never scoped, so diagnosis still works everywhere. See RBAC.


orrery-assistant

The root orchestrator. The interactive root is orrery_chat_agent — a chat-mode ADK 2.0 LlmAgent that keeps conversation history and routes each query to the right specialist via AgentTool. A separate graph Workflow (orrery_triage_workflow) provides the deterministic, parallel, bounded-loop incident-response pipeline for batch / scheduled runs (make run-triage). Both reuse the same node agents; see ADR-003.

Run it:

make run-dev  # ADK Dev UI on :8000
make run-cli  # Terminal REPL
make run-cli PERSIST=1 # Persistent sessions + memory (in-memory, or PostgreSQL via DATABASE_URL)
make run-triage              # Deterministic triage Workflow, one batch run

Exposed capabilities: - orrery_chat_agent (interactive root) — conversational LLM that routes to kafka_health, k8s_health, observability, elasticsearch, docker, and ops_journal via AgentTool, plus incident_triage_agent for a single-turn full sweep and LoadMemoryTool (model-invoked load_memory) for cross-session recall - orrery_triage_workflow (batch root) — health_join barriers the 5 parallel subsystem checkers, then triage_summarizerjournal_writertriage_route - remediation_actor / remediation_verifier — closed-loop remediation subgraph that acts → verifies → retries up to 3 times via a verify_route state counter


kafka-health

Cluster monitoring via confluent-kafka's AdminClient. Clients are cached as module-level singletons to avoid per-call reconnect overhead.

Config: KAFKA_BOOTSTRAP_SERVERS=localhost:9092, KUBECONFIG_PATH (optional, for Strimzi tools)

Core tools — Kafka protocol:

Tool Role Description
get_kafka_cluster_health viewer Broker count, controller ID, reachability
list_kafka_topics viewer All topics, with internal filter
get_topic_metadata viewer Partitions, replicas, ISR
list_consumer_groups viewer Active consumer groups
describe_consumer_groups viewer Member details, state, coordinator
get_consumer_lag viewer Per-partition lag for a group
get_topic_config viewer Topic config, split into overridden vs cluster defaults (sensitive values masked)
create_kafka_topic operator (@confirm) Create with partitions + replication
update_kafka_partitions operator (@confirm) Increase partition count
tune_topic_config operator (@confirm) Set a topic setting that cannot delete data (message size, compression, min ISR)
alter_topic_config admin (@destructive) Set retention.* / cleanup.policy — a low retention discards data, so this is gated like a deletion
delete_kafka_topic admin (@destructive) Permanent topic deletion
reset_consumer_group_offsets admin (@destructive) Reset a group to earliest (reprocess) or latest (drop the backlog); group must be inactive
delete_consumer_group admin (@destructive) Delete an inactive group and its committed offsets

Strimzi tools — Kubernetes control plane (backed by orrery_core.default_registry.StrimziDetector):

Tool Role Description
list_strimzi_clusters viewer List Kafka CRs, enriched with healthy / phase / warnings
describe_strimzi_cluster viewer Full spec + raw status + interpreted status for a Kafka CR
list_strimzi_topics viewer List KafkaTopic CRs (Topic Operator view), optional strimzi.io/cluster label filter
list_kafka_users viewer List KafkaUser CRs with authentication / authorization type
get_kafka_connect_status viewer Describe a KafkaConnect cluster — REST URL, replicas, loaded plugins
list_kafka_connectors viewer List KafkaConnector CRs with task state + failed-task count
get_mirrormaker2_status viewer Describe a KafkaMirrorMaker2 — clusters, replication flows, per-connector state
get_kafka_rebalance_status viewer Cruise Control KafkaRebalance state + optimization result
approve_kafka_rebalance operator (@confirm) Annotate strimzi.io/rebalance: approve — only when state is ProposalReady
restart_kafka_connector operator (@confirm) Annotate strimzi.io/restart: true on a connector CR

Kafka protocol vs. Strimzi CRs

list_kafka_topics returns what the broker actually serves; list_strimzi_topics returns what the Topic Operator wants the broker to serve. Divergence between the two usually means the operator is reconciling or the TO has errored — check describe_custom_resource on the offending KafkaTopic in k8s-health.


k8s-health

Kubernetes control-plane tooling via the official Python client. Uses in-cluster config when available, falls back to ~/.kube/config.

Config: KUBECONFIG_PATH (optional)

Tool Role Description
get_cluster_info, get_nodes, list_namespaces viewer Cluster topology
list_pods, describe_pod, get_pod_logs viewer Pod diagnostics
list_deployments, get_deployment_status viewer Deployment state
get_events viewer Recent Events, optionally filtered by namespace
list_services, describe_service viewer Service spec plus ready vs not-ready Endpoints — the usual cause of "connection refused" when the pods look healthy
list_configmaps, get_configmap viewer ConfigMap keys and values (long values truncated)
top_nodes, top_pods viewer Live CPU/memory usage via the metrics API; degrades cleanly when metrics-server is absent
scale_deployment operator (@confirm) Change replica count
restart_deployment operator (@confirm) Rolling restart via annotation bump
rollback_deployment admin (@destructive) Revert to a previous revision

Operator-aware tools — backed by orrery_core.default_registry (Strimzi + ECK built in; pluggable for others):

Tool Role Description
detect_operators viewer Scan CRDs and report which known operators are installed
list_custom_resources viewer List any CR (GVR), enriched with healthy / phase / warnings when the group is known
describe_custom_resource viewer Full CR spec + raw status + interpreted status block
get_owner_chain viewer Walk ownerReferences from a Pod up to its root resource
describe_workload viewer Pod → operator-managed CR aware: returns the operator's health/phase summary instead of raw pod info
get_operator_events viewer Cluster events filtered to operator-watched kinds (e.g., only Kafka / Elasticsearch events)

Why this matters

For a failing kafka-broker-0 pod, describe_pod shows a CrashLoopBackOff; describe_workload walks to the owning Kafka CR and reports "Kafka 'demo' is unhealthy — NotReady: rolling update in progress". The operator's view is usually the one you want.


observability

A unified interface to Prometheus, Loki, and Alertmanager. HTTP sessions are pooled.

Config: PROMETHEUS_URL, LOKI_URL, ALERTMANAGER_URL (all default to their standard local dev ports)

Tool Role Description
query_prometheus, query_prometheus_range viewer Instant + range queries
get_prometheus_alerts, get_prometheus_targets viewer Alerting rules and scrape status
query_loki_logs, get_loki_labels, get_loki_label_values viewer LogQL queries and label discovery
get_active_alerts, get_alert_groups, get_silences viewer Alertmanager state
list_prometheus_metrics, get_prometheus_metadata viewer Discover metric names and their type/help/unit when the exact name isn't known
get_prometheus_rules viewer Configured alerting + recording rules with their state
query_loki_range viewer LogQL over a relative window ("the last N hours") without computing timestamps
create_silence operator (@confirm) Silence matcher + duration
delete_silence admin (@destructive) Remove an active silence by ID

elasticsearch

Elasticsearch cluster operations, split across two surfaces: REST tools that speak the Elasticsearch wire protocol against a live cluster, and ECK tools that introspect the Kubernetes control plane (*.k8s.elastic.co CRs) via the operator registry. HTTP sessions and the Kubernetes client are pooled.

Config: ELASTICSEARCH_URL (default http://localhost:9200), ELASTICSEARCH_API_KEY or ELASTICSEARCH_USERNAME + ELASTICSEARCH_PASSWORD, ELASTICSEARCH_VERIFY_CERTS, ELASTICSEARCH_CA_CERTS, ELASTICSEARCH_HTTP_TIMEOUT, KUBECONFIG_PATH (optional, for ECK tools)

REST tools — Elasticsearch wire protocol:

Tool Role Description
get_cluster_health viewer green/yellow/red status + shard counters
get_cluster_stats viewer Node roles, OS/JVM summary, indices totals
get_nodes_info viewer Per-node roles, version, host details
get_pending_tasks viewer Master-queue backlog — non-empty means the cluster is behind
get_cluster_settings viewer Persistent + transient cluster-level settings
list_indices viewer _cat/indices with optional wildcard filter
get_index_stats viewer Docs, storage, segment counts for an index
get_index_mappings viewer Field mapping document
get_index_settings viewer Index-level settings (refresh interval, replicas, etc.)
get_shard_allocation viewer _cat/shards — states, sizes, assigned nodes
explain_shard_allocation viewer _cluster/allocation/explain — why a shard is unassigned
search viewer Full _search with request body + size/from
count_documents viewer _count with optional query body
list_index_templates viewer Composable index templates
list_aliases viewer Alias → index mapping
list_ilm_policies viewer Configured ILM policies
explain_ilm_status viewer ILM state per index — the usual place "why is rollover stuck" is answered
list_snapshot_repositories viewer Registered snapshot repos
list_snapshots viewer Snapshots in a repo + state/duration

ECK tools — Kubernetes control plane (backed by orrery_core.default_registry.ECKDetector):

Tool Role Description
list_eck_clusters viewer List Elasticsearch CRs, enriched with healthy / phase / warnings
describe_eck_cluster viewer Full spec + nodeSets + raw status + interpreted status for an Elasticsearch CR
list_kibana_instances viewer List Kibana CRs with version, count, associated ES ref
describe_kibana viewer Full spec + raw status + interpreted status for a Kibana CR
get_eck_operator_events viewer Recent Kubernetes Events from the operator namespace (default elastic-system)

Wire protocol vs. ECK CRs

get_cluster_health reflects what the Elasticsearch data plane is actually doing; list_eck_clusters reflects what the operator is trying to do. If the REST health is green but the ECK CR is stuck in ApplyingChanges, the operator is mid-reconcile — check get_eck_operator_events for stalls.


docker-agent

Container inspection and lifecycle via the Docker CLI (subprocess). No Docker SDK dependency — works with whatever docker binary is on PATH.

Config: none — inherits the calling environment's Docker context.

Tool Role Description
list_containers, inspect_container viewer State + config (env vars redacted)
get_container_logs, get_container_stats viewer Runtime diagnostics
docker_compose_status viewer docker compose ps parsing
list_images viewer Local image inventory
list_networks, inspect_network viewer Driver, subnets, and which containers are attached
list_volumes, inspect_volume viewer Driver, mountpoint, labels
system_df viewer Disk usage by images / containers / volumes / build cache — what to prune, before pruning
start_container, restart_container operator (@confirm) Lifecycle control
stop_container operator (@confirm) Graceful stop with timeout
remove_image admin (@destructive) docker rmi with force flag
prune_images admin (@destructive) Remove unused images (dangling only unless all_unused)
prune_containers admin (@destructive) Remove all stopped containers

ops-journal

Demonstrates ADK's four state scopes (session / user / app / temp). Not infrastructure-touching — used for incident notes, team bookmarks, and preferences that persist across sessions.

Config: none.

Tool Role Description
log_operation, get_session_summary viewer Session-scoped event log
save_note, list_notes, search_notes, delete_note viewer User-scoped notes (persist across sessions when a memory_service is configured)
set_preference, get_preferences viewer User-scoped preferences
add_team_bookmark, list_team_bookmarks viewer App-scoped shared bookmarks

All tools are read/write on local session state — no external system is touched, so none are guarded. See Cross-session memory for how notes can outlive a single session.


Picking an agent

If you're writing a new workflow and need to decide which specialist(s) to call:

Question Agent
"Is the broker healthy? Who's consuming from topic X? What's the lag?" kafka-health
"What pods are running? Why is this deployment unhealthy?" k8s-health
"Is the Strimzi Kafka / ECK Elasticsearch cluster healthy? Why is broker-0 failing?" k8s-health (via describe_workload, describe_custom_resource)
"What are the active alerts? Show me logs matching {job=\"api\"}" observability
"Is the ES cluster green? Why is this shard unassigned? Is ILM stuck?" elasticsearch
"Is the ECK Elasticsearch / Kibana CR reconciled? What's the operator doing?" elasticsearch (via list_eck_clusters, get_eck_operator_events)
"What containers are up? Restart the web service." docker-agent
"Remember this incident / recall last week's postmortem." ops-journal + memory
"Run a full triage and file the report." orrery-assistantincident_triage_agent (interactive) or make run-triage (batch Workflow)
"The pod is still unhealthy — try to fix it." orrery-assistant → remediation subgraph (remediation_actor / verify_route)