From 6004e3e661bb2930bbbf610f923ad2bbf78a13d7 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Fri, 21 Aug 2026 16:18:08 -0500
Subject: [PATCH 01/70] Split kagent docs into versioned 0.x/1.x tree for the
1.0 rewrite
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Move the existing flat kagent doc set to content/kagent/0.x/ (frozen) and
add content/kagent/1.x/ for the Agent Substrate/v1alpha3 rewrite, wired up
with docs-theme-extras' version switcher via sections.kagent.versions.
Scope the versions to the kagent section specifically (not site-wide)
since this Hugo build also serves kmcp, which stays unversioned. That also
required two local overrides of upstream partials (navbar.html,
version-banner.html): upstream assumes a single-product site where the
version sits directly after the baseURL, which breaks kagent's actual
/docs/kagent//... shape (an extra section segment) and doesn't
scope by section — both fixed here after empirically verifying with a real
Hugo build.
Also repoints the marketing site's hardcoded doc links and the nightly
update-ref-docs.yaml job at 0.x so they keep working, and fixes a stale
.docs-test.toml comment left over from the removed MDX pipeline.
Co-Authored-By: Claude Sonnet 5
Signed-off-by: Rachael Graham
---
.github/workflows/update-ref-docs.yaml | 15 +-
docs-site/.docs-test.toml | 21 +-
docs-site/content/kagent/0.x/_index.md | 37 ++
.../kagent/{ => 0.x}/concepts/_index.md | 0
.../{ => 0.x}/concepts/agent-harness.md | 0
.../kagent/{ => 0.x}/concepts/agent-memory.md | 0
.../{ => 0.x}/concepts/agent-substrate.md | 0
.../kagent/{ => 0.x}/concepts/agents.md | 0
.../kagent/{ => 0.x}/concepts/architecture.md | 0
.../kagent/{ => 0.x}/concepts/mcp-apps.md | 0
.../kagent/{ => 0.x}/concepts/tools.md | 0
.../kagent/{ => 0.x}/examples/_index.md | 0
.../kagent/{ => 0.x}/examples/a2a-agents.md | 0
.../kagent/{ => 0.x}/examples/a2a-byo.md | 0
.../{ => 0.x}/examples/agent-harness.md | 0
.../{ => 0.x}/examples/agent-substrate.md | 0
.../kagent/{ => 0.x}/examples/agentgateway.md | 0
.../kagent/{ => 0.x}/examples/agents-mcp.md | 0
.../kagent/{ => 0.x}/examples/crewai-byo.md | 0
.../kagent/{ => 0.x}/examples/discord-a2a.md | 0
.../{ => 0.x}/examples/documentation.md | 0
.../{ => 0.x}/examples/human-in-the-loop.md | 0
.../{ => 0.x}/examples/langchain-byo.md | 0
.../kagent/{ => 0.x}/examples/skills.md | 0
.../kagent/{ => 0.x}/examples/slack-a2a.md | 0
.../kagent/{ => 0.x}/examples/telegram-bot.md | 0
.../{ => 0.x}/getting-started/_index.md | 0
.../{ => 0.x}/getting-started/first-agent.md | 0
.../getting-started/first-mcp-tool.md | 0
.../getting-started/local-development.md | 0
.../{ => 0.x}/getting-started/quickstart.md | 0
.../getting-started/system-prompts.md | 0
.../kagent/{ => 0.x}/introduction/_index.md | 0
.../kagent/{ => 0.x}/introduction/features.md | 0
.../{ => 0.x}/introduction/installation.md | 0
.../{ => 0.x}/introduction/what-is-kagent.md | 0
.../content/kagent/0.x/not-in-version.md | 8 +
.../kagent/{ => 0.x}/observability/_index.md | 0
.../{ => 0.x}/observability/audit-prompts.md | 0
.../{ => 0.x}/observability/launch-ui.md | 0
.../kagent/{ => 0.x}/observability/tracing.md | 0
.../kagent/{ => 0.x}/operations/_index.md | 0
.../kagent/{ => 0.x}/operations/debug.md | 0
.../operations/operational-considerations.md | 0
.../kagent/{ => 0.x}/operations/uninstall.md | 0
.../kagent/{ => 0.x}/operations/upgrade.md | 0
.../kagent/{ => 0.x}/resources/_index.md | 0
.../kagent/{ => 0.x}/resources/api-ref.md | 0
.../kagent/{ => 0.x}/resources/cli/_index.md | 0
.../{ => 0.x}/resources/cli/kagent-add-mcp.md | 0
.../resources/cli/kagent-bug-report.md | 0
.../{ => 0.x}/resources/cli/kagent-build.md | 0
.../resources/cli/kagent-completion.md | 0
.../resources/cli/kagent-dashboard.md | 0
.../{ => 0.x}/resources/cli/kagent-deploy.md | 0
.../{ => 0.x}/resources/cli/kagent-get.md | 0
.../{ => 0.x}/resources/cli/kagent-help.md | 0
.../{ => 0.x}/resources/cli/kagent-init.md | 0
.../{ => 0.x}/resources/cli/kagent-install.md | 0
.../{ => 0.x}/resources/cli/kagent-invoke.md | 0
.../{ => 0.x}/resources/cli/kagent-mcp.md | 0
.../{ => 0.x}/resources/cli/kagent-run.md | 0
.../resources/cli/kagent-uninstall.md | 0
.../{ => 0.x}/resources/cli/kagent-version.md | 0
.../kagent/{ => 0.x}/resources/community.md | 0
.../content/kagent/{ => 0.x}/resources/faq.md | 0
.../kagent/{ => 0.x}/resources/helm.md | 0
.../{ => 0.x}/resources/release-notes.md | 0
.../{ => 0.x}/resources/tools-ecosystem.md | 0
.../kagent/{ => 0.x}/resources/versions.md | 0
.../{ => 0.x}/supported-providers/_index.md | 0
.../supported-providers/amazon-bedrock.md | 0
.../supported-providers/anthropic.md | 0
.../supported-providers/azure-ai-foundry.md | 0
.../supported-providers/azure-openai.md | 0
.../supported-providers/byo-agentgateway.md | 0
.../supported-providers/byo-openai.md | 0
.../{ => 0.x}/supported-providers/gemini.md | 0
.../supported-providers/google-vertexai.md | 0
.../{ => 0.x}/supported-providers/ollama.md | 0
.../{ => 0.x}/supported-providers/openai.md | 0
.../supported-providers/sap-ai-core.md | 0
.../{ => 0.x}/supported-providers/xai.md | 0
docs-site/content/kagent/1.x/_index.md | 13 +
.../content/kagent/1.x/not-in-version.md | 8 +
docs-site/content/kagent/_index.md | 31 +-
docs-site/hugo.yaml | 24 ++
docs-site/layouts/_partials/navbar.html | 318 ++++++++++++++++++
.../layouts/partials/version-banner.html | 49 +++
src/app/page.tsx | 4 +-
src/components/footer.tsx | 26 +-
src/components/key-components.tsx | 2 +-
92 files changed, 499 insertions(+), 57 deletions(-)
create mode 100644 docs-site/content/kagent/0.x/_index.md
rename docs-site/content/kagent/{ => 0.x}/concepts/_index.md (100%)
rename docs-site/content/kagent/{ => 0.x}/concepts/agent-harness.md (100%)
rename docs-site/content/kagent/{ => 0.x}/concepts/agent-memory.md (100%)
rename docs-site/content/kagent/{ => 0.x}/concepts/agent-substrate.md (100%)
rename docs-site/content/kagent/{ => 0.x}/concepts/agents.md (100%)
rename docs-site/content/kagent/{ => 0.x}/concepts/architecture.md (100%)
rename docs-site/content/kagent/{ => 0.x}/concepts/mcp-apps.md (100%)
rename docs-site/content/kagent/{ => 0.x}/concepts/tools.md (100%)
rename docs-site/content/kagent/{ => 0.x}/examples/_index.md (100%)
rename docs-site/content/kagent/{ => 0.x}/examples/a2a-agents.md (100%)
rename docs-site/content/kagent/{ => 0.x}/examples/a2a-byo.md (100%)
rename docs-site/content/kagent/{ => 0.x}/examples/agent-harness.md (100%)
rename docs-site/content/kagent/{ => 0.x}/examples/agent-substrate.md (100%)
rename docs-site/content/kagent/{ => 0.x}/examples/agentgateway.md (100%)
rename docs-site/content/kagent/{ => 0.x}/examples/agents-mcp.md (100%)
rename docs-site/content/kagent/{ => 0.x}/examples/crewai-byo.md (100%)
rename docs-site/content/kagent/{ => 0.x}/examples/discord-a2a.md (100%)
rename docs-site/content/kagent/{ => 0.x}/examples/documentation.md (100%)
rename docs-site/content/kagent/{ => 0.x}/examples/human-in-the-loop.md (100%)
rename docs-site/content/kagent/{ => 0.x}/examples/langchain-byo.md (100%)
rename docs-site/content/kagent/{ => 0.x}/examples/skills.md (100%)
rename docs-site/content/kagent/{ => 0.x}/examples/slack-a2a.md (100%)
rename docs-site/content/kagent/{ => 0.x}/examples/telegram-bot.md (100%)
rename docs-site/content/kagent/{ => 0.x}/getting-started/_index.md (100%)
rename docs-site/content/kagent/{ => 0.x}/getting-started/first-agent.md (100%)
rename docs-site/content/kagent/{ => 0.x}/getting-started/first-mcp-tool.md (100%)
rename docs-site/content/kagent/{ => 0.x}/getting-started/local-development.md (100%)
rename docs-site/content/kagent/{ => 0.x}/getting-started/quickstart.md (100%)
rename docs-site/content/kagent/{ => 0.x}/getting-started/system-prompts.md (100%)
rename docs-site/content/kagent/{ => 0.x}/introduction/_index.md (100%)
rename docs-site/content/kagent/{ => 0.x}/introduction/features.md (100%)
rename docs-site/content/kagent/{ => 0.x}/introduction/installation.md (100%)
rename docs-site/content/kagent/{ => 0.x}/introduction/what-is-kagent.md (100%)
create mode 100644 docs-site/content/kagent/0.x/not-in-version.md
rename docs-site/content/kagent/{ => 0.x}/observability/_index.md (100%)
rename docs-site/content/kagent/{ => 0.x}/observability/audit-prompts.md (100%)
rename docs-site/content/kagent/{ => 0.x}/observability/launch-ui.md (100%)
rename docs-site/content/kagent/{ => 0.x}/observability/tracing.md (100%)
rename docs-site/content/kagent/{ => 0.x}/operations/_index.md (100%)
rename docs-site/content/kagent/{ => 0.x}/operations/debug.md (100%)
rename docs-site/content/kagent/{ => 0.x}/operations/operational-considerations.md (100%)
rename docs-site/content/kagent/{ => 0.x}/operations/uninstall.md (100%)
rename docs-site/content/kagent/{ => 0.x}/operations/upgrade.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/_index.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/api-ref.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/cli/_index.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/cli/kagent-add-mcp.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/cli/kagent-bug-report.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/cli/kagent-build.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/cli/kagent-completion.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/cli/kagent-dashboard.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/cli/kagent-deploy.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/cli/kagent-get.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/cli/kagent-help.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/cli/kagent-init.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/cli/kagent-install.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/cli/kagent-invoke.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/cli/kagent-mcp.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/cli/kagent-run.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/cli/kagent-uninstall.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/cli/kagent-version.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/community.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/faq.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/helm.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/release-notes.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/tools-ecosystem.md (100%)
rename docs-site/content/kagent/{ => 0.x}/resources/versions.md (100%)
rename docs-site/content/kagent/{ => 0.x}/supported-providers/_index.md (100%)
rename docs-site/content/kagent/{ => 0.x}/supported-providers/amazon-bedrock.md (100%)
rename docs-site/content/kagent/{ => 0.x}/supported-providers/anthropic.md (100%)
rename docs-site/content/kagent/{ => 0.x}/supported-providers/azure-ai-foundry.md (100%)
rename docs-site/content/kagent/{ => 0.x}/supported-providers/azure-openai.md (100%)
rename docs-site/content/kagent/{ => 0.x}/supported-providers/byo-agentgateway.md (100%)
rename docs-site/content/kagent/{ => 0.x}/supported-providers/byo-openai.md (100%)
rename docs-site/content/kagent/{ => 0.x}/supported-providers/gemini.md (100%)
rename docs-site/content/kagent/{ => 0.x}/supported-providers/google-vertexai.md (100%)
rename docs-site/content/kagent/{ => 0.x}/supported-providers/ollama.md (100%)
rename docs-site/content/kagent/{ => 0.x}/supported-providers/openai.md (100%)
rename docs-site/content/kagent/{ => 0.x}/supported-providers/sap-ai-core.md (100%)
rename docs-site/content/kagent/{ => 0.x}/supported-providers/xai.md (100%)
create mode 100644 docs-site/content/kagent/1.x/_index.md
create mode 100644 docs-site/content/kagent/1.x/not-in-version.md
create mode 100644 docs-site/layouts/_partials/navbar.html
create mode 100644 docs-site/layouts/partials/version-banner.html
diff --git a/.github/workflows/update-ref-docs.yaml b/.github/workflows/update-ref-docs.yaml
index 5e4303fc..678b3b84 100644
--- a/.github/workflows/update-ref-docs.yaml
+++ b/.github/workflows/update-ref-docs.yaml
@@ -13,10 +13,17 @@ concurrency:
# The docs are a Hugo site under docs-site/ (served at /docs). This workflow
# generates the reference pages directly as Hugo markdown into docs-site/content:
-# - kagent CRD API ref -> docs-site/content/kagent/resources/api-ref.md
+# - kagent CRD API ref -> docs-site/content/kagent/0.x/resources/api-ref.md
# - kmcp CRD API ref -> docs-site/content/kmcp/reference/api-ref.md
-# - kagent Helm ref -> docs-site/content/kagent/resources/helm.md
+# - kagent Helm ref -> docs-site/content/kagent/0.x/resources/helm.md
# Each page uses plain Hugo YAML frontmatter (no MDX `export const metadata`).
+#
+# Targets the 0.x (current stable) tree only — v1alpha2, the API this job
+# generates against, is what 0.x actually ships. The 1.x rewrite tracks
+# v1alpha3 and gets its API/Helm reference hand-written for now (see the
+# kagent 1.0 docs scope: Phase 4, blocked on the v1alpha3 schema settling);
+# point a similar job at docs-site/content/kagent/1.x/resources/ once that's
+# ready to automate.
jobs:
generate-api-docs:
runs-on: ubuntu-latest
@@ -27,9 +34,9 @@ jobs:
# Target Hugo content paths (relative to the website checkout).
env:
- KAGENT_API_PAGE: docs-site/content/kagent/resources/api-ref.md
+ KAGENT_API_PAGE: docs-site/content/kagent/0.x/resources/api-ref.md
KMCP_API_PAGE: docs-site/content/kmcp/reference/api-ref.md
- HELM_PAGE: docs-site/content/kagent/resources/helm.md
+ HELM_PAGE: docs-site/content/kagent/0.x/resources/helm.md
steps:
- name: Checkout kagent repository
diff --git a/docs-site/.docs-test.toml b/docs-site/.docs-test.toml
index fdde7f01..84abaf8a 100644
--- a/docs-site/.docs-test.toml
+++ b/docs-site/.docs-test.toml
@@ -6,11 +6,10 @@
# against this file's directory (docs-site/). The harness does NOT build the
# site — `hugo --config hugo.yaml` runs first and writes to builtRoot.
#
-# NOTE: docs-site/content is GENERATED from the Next.js MDX source under
-# src/app/docs by `make gen-docs` (scripts/mdx-to-hugo.mjs --out docs-site/content).
-# These checks run against the generated Hugo output, which is the right place
-# to catch shortcode/rendering breaks — but a content fix must land in the MDX
-# source (or the converter), not in docs-site/content, or `gen-docs` overwrites it.
+# docs-site/content is hand-authored Markdown and is the source of truth (the
+# former MDX source under src/app/docs and its mdx-to-hugo.mjs converter were
+# removed once the one-time conversion landed — see "Remove the src/apps/docs
+# directory"). Edit pages directly under docs-site/content.
version = "1"
name = "kagent-oss"
@@ -35,10 +34,14 @@ scanRoots = [
"./content",
]
-# NOTE: kagent docs are a flat, unversioned set (///) with no
-# version segment. There is intentionally no [versioning] block — version-aware
-# specs detect the absence and skip gracefully (same mechanism agentregistry's
-# and ambientmesh's flat docs rely on).
+# kagent docs are versioned (0.x frozen, 1.x in-progress rewrite), nested
+# under /docs/kagent//... . kmcp, the other product built into this
+# same Hugo site, stays flat/unversioned — see the sections.kagent.versions
+# comment in hugo.yaml for why versions are scoped per-section rather than
+# site-wide.
+[versioning]
+versionFromPath = "^/docs/kagent/(?[^/]+)/"
+versions = ["0.x", "1.x"]
# All checks default to enabled. No [checks] overrides are needed: kagent runs
# the full default set. (The former `smoke`/`crossBrowser` toggles were removed
diff --git a/docs-site/content/kagent/0.x/_index.md b/docs-site/content/kagent/0.x/_index.md
new file mode 100644
index 00000000..489502ad
--- /dev/null
+++ b/docs-site/content/kagent/0.x/_index.md
@@ -0,0 +1,37 @@
+---
+title: kagent
+linkTitle: "kagent 0.x"
+description: Concepts, guides, and reference docs for running declarative AI agents on Kubernetes, from install through day-two operations.
+weight: 1
+author: kagent.dev
+---
+
+Your complete guide to the AI agent platform for Kubernetes
+
+## What is kagent?
+
+kagent is an innovative AI agent platform designed specifically for Kubernetes environments.
+It empowers developers and operations teams to create intelligent, autonomous agents that can
+monitor, manage, and automate complex Kubernetes workloads using the power of large language models (LLMs).
+
+kagent was created at [Solo.io](https://www.solo.io) in 2025 and is a [Cloud Native Computing Foundation](https://www.cncf.io) sandbox project.
+
+## Key Features
+
+- **AI-Powered Automation** - Create intelligent agents that understand natural language and can perform complex Kubernetes operations
+- **Multi-Provider Support** - Works with OpenAI, Anthropic, Google Vertex AI, Azure OpenAI, Ollama, and custom models
+- **Tool Integration** - Supports Model Context Protocol (MCP) tools, built-in Kubernetes tools, and custom HTTP tools
+- **Agent-to-Agent Communication** - Enable sophisticated workflows through A2A (Agent-to-Agent) interactions
+- **Comprehensive Observability** - Built-in tracing and monitoring to understand agent behavior and performance
+- **Cloud Native** - Designed from the ground up to run natively in Kubernetes environments
+
+## Why Choose kagent?
+
+Whether you're looking to automate routine operations, implement intelligent monitoring,
+or create sophisticated multi-agent workflows, kagent provides the tools and framework
+to bring AI to your Kubernetes infrastructure. Start with simple automation and scale
+to complex, intelligent systems that can reason about your cluster's state and make
+informed decisions.
+
+## Explore the Documentation
+
diff --git a/docs-site/content/kagent/concepts/_index.md b/docs-site/content/kagent/0.x/concepts/_index.md
similarity index 100%
rename from docs-site/content/kagent/concepts/_index.md
rename to docs-site/content/kagent/0.x/concepts/_index.md
diff --git a/docs-site/content/kagent/concepts/agent-harness.md b/docs-site/content/kagent/0.x/concepts/agent-harness.md
similarity index 100%
rename from docs-site/content/kagent/concepts/agent-harness.md
rename to docs-site/content/kagent/0.x/concepts/agent-harness.md
diff --git a/docs-site/content/kagent/concepts/agent-memory.md b/docs-site/content/kagent/0.x/concepts/agent-memory.md
similarity index 100%
rename from docs-site/content/kagent/concepts/agent-memory.md
rename to docs-site/content/kagent/0.x/concepts/agent-memory.md
diff --git a/docs-site/content/kagent/concepts/agent-substrate.md b/docs-site/content/kagent/0.x/concepts/agent-substrate.md
similarity index 100%
rename from docs-site/content/kagent/concepts/agent-substrate.md
rename to docs-site/content/kagent/0.x/concepts/agent-substrate.md
diff --git a/docs-site/content/kagent/concepts/agents.md b/docs-site/content/kagent/0.x/concepts/agents.md
similarity index 100%
rename from docs-site/content/kagent/concepts/agents.md
rename to docs-site/content/kagent/0.x/concepts/agents.md
diff --git a/docs-site/content/kagent/concepts/architecture.md b/docs-site/content/kagent/0.x/concepts/architecture.md
similarity index 100%
rename from docs-site/content/kagent/concepts/architecture.md
rename to docs-site/content/kagent/0.x/concepts/architecture.md
diff --git a/docs-site/content/kagent/concepts/mcp-apps.md b/docs-site/content/kagent/0.x/concepts/mcp-apps.md
similarity index 100%
rename from docs-site/content/kagent/concepts/mcp-apps.md
rename to docs-site/content/kagent/0.x/concepts/mcp-apps.md
diff --git a/docs-site/content/kagent/concepts/tools.md b/docs-site/content/kagent/0.x/concepts/tools.md
similarity index 100%
rename from docs-site/content/kagent/concepts/tools.md
rename to docs-site/content/kagent/0.x/concepts/tools.md
diff --git a/docs-site/content/kagent/examples/_index.md b/docs-site/content/kagent/0.x/examples/_index.md
similarity index 100%
rename from docs-site/content/kagent/examples/_index.md
rename to docs-site/content/kagent/0.x/examples/_index.md
diff --git a/docs-site/content/kagent/examples/a2a-agents.md b/docs-site/content/kagent/0.x/examples/a2a-agents.md
similarity index 100%
rename from docs-site/content/kagent/examples/a2a-agents.md
rename to docs-site/content/kagent/0.x/examples/a2a-agents.md
diff --git a/docs-site/content/kagent/examples/a2a-byo.md b/docs-site/content/kagent/0.x/examples/a2a-byo.md
similarity index 100%
rename from docs-site/content/kagent/examples/a2a-byo.md
rename to docs-site/content/kagent/0.x/examples/a2a-byo.md
diff --git a/docs-site/content/kagent/examples/agent-harness.md b/docs-site/content/kagent/0.x/examples/agent-harness.md
similarity index 100%
rename from docs-site/content/kagent/examples/agent-harness.md
rename to docs-site/content/kagent/0.x/examples/agent-harness.md
diff --git a/docs-site/content/kagent/examples/agent-substrate.md b/docs-site/content/kagent/0.x/examples/agent-substrate.md
similarity index 100%
rename from docs-site/content/kagent/examples/agent-substrate.md
rename to docs-site/content/kagent/0.x/examples/agent-substrate.md
diff --git a/docs-site/content/kagent/examples/agentgateway.md b/docs-site/content/kagent/0.x/examples/agentgateway.md
similarity index 100%
rename from docs-site/content/kagent/examples/agentgateway.md
rename to docs-site/content/kagent/0.x/examples/agentgateway.md
diff --git a/docs-site/content/kagent/examples/agents-mcp.md b/docs-site/content/kagent/0.x/examples/agents-mcp.md
similarity index 100%
rename from docs-site/content/kagent/examples/agents-mcp.md
rename to docs-site/content/kagent/0.x/examples/agents-mcp.md
diff --git a/docs-site/content/kagent/examples/crewai-byo.md b/docs-site/content/kagent/0.x/examples/crewai-byo.md
similarity index 100%
rename from docs-site/content/kagent/examples/crewai-byo.md
rename to docs-site/content/kagent/0.x/examples/crewai-byo.md
diff --git a/docs-site/content/kagent/examples/discord-a2a.md b/docs-site/content/kagent/0.x/examples/discord-a2a.md
similarity index 100%
rename from docs-site/content/kagent/examples/discord-a2a.md
rename to docs-site/content/kagent/0.x/examples/discord-a2a.md
diff --git a/docs-site/content/kagent/examples/documentation.md b/docs-site/content/kagent/0.x/examples/documentation.md
similarity index 100%
rename from docs-site/content/kagent/examples/documentation.md
rename to docs-site/content/kagent/0.x/examples/documentation.md
diff --git a/docs-site/content/kagent/examples/human-in-the-loop.md b/docs-site/content/kagent/0.x/examples/human-in-the-loop.md
similarity index 100%
rename from docs-site/content/kagent/examples/human-in-the-loop.md
rename to docs-site/content/kagent/0.x/examples/human-in-the-loop.md
diff --git a/docs-site/content/kagent/examples/langchain-byo.md b/docs-site/content/kagent/0.x/examples/langchain-byo.md
similarity index 100%
rename from docs-site/content/kagent/examples/langchain-byo.md
rename to docs-site/content/kagent/0.x/examples/langchain-byo.md
diff --git a/docs-site/content/kagent/examples/skills.md b/docs-site/content/kagent/0.x/examples/skills.md
similarity index 100%
rename from docs-site/content/kagent/examples/skills.md
rename to docs-site/content/kagent/0.x/examples/skills.md
diff --git a/docs-site/content/kagent/examples/slack-a2a.md b/docs-site/content/kagent/0.x/examples/slack-a2a.md
similarity index 100%
rename from docs-site/content/kagent/examples/slack-a2a.md
rename to docs-site/content/kagent/0.x/examples/slack-a2a.md
diff --git a/docs-site/content/kagent/examples/telegram-bot.md b/docs-site/content/kagent/0.x/examples/telegram-bot.md
similarity index 100%
rename from docs-site/content/kagent/examples/telegram-bot.md
rename to docs-site/content/kagent/0.x/examples/telegram-bot.md
diff --git a/docs-site/content/kagent/getting-started/_index.md b/docs-site/content/kagent/0.x/getting-started/_index.md
similarity index 100%
rename from docs-site/content/kagent/getting-started/_index.md
rename to docs-site/content/kagent/0.x/getting-started/_index.md
diff --git a/docs-site/content/kagent/getting-started/first-agent.md b/docs-site/content/kagent/0.x/getting-started/first-agent.md
similarity index 100%
rename from docs-site/content/kagent/getting-started/first-agent.md
rename to docs-site/content/kagent/0.x/getting-started/first-agent.md
diff --git a/docs-site/content/kagent/getting-started/first-mcp-tool.md b/docs-site/content/kagent/0.x/getting-started/first-mcp-tool.md
similarity index 100%
rename from docs-site/content/kagent/getting-started/first-mcp-tool.md
rename to docs-site/content/kagent/0.x/getting-started/first-mcp-tool.md
diff --git a/docs-site/content/kagent/getting-started/local-development.md b/docs-site/content/kagent/0.x/getting-started/local-development.md
similarity index 100%
rename from docs-site/content/kagent/getting-started/local-development.md
rename to docs-site/content/kagent/0.x/getting-started/local-development.md
diff --git a/docs-site/content/kagent/getting-started/quickstart.md b/docs-site/content/kagent/0.x/getting-started/quickstart.md
similarity index 100%
rename from docs-site/content/kagent/getting-started/quickstart.md
rename to docs-site/content/kagent/0.x/getting-started/quickstart.md
diff --git a/docs-site/content/kagent/getting-started/system-prompts.md b/docs-site/content/kagent/0.x/getting-started/system-prompts.md
similarity index 100%
rename from docs-site/content/kagent/getting-started/system-prompts.md
rename to docs-site/content/kagent/0.x/getting-started/system-prompts.md
diff --git a/docs-site/content/kagent/introduction/_index.md b/docs-site/content/kagent/0.x/introduction/_index.md
similarity index 100%
rename from docs-site/content/kagent/introduction/_index.md
rename to docs-site/content/kagent/0.x/introduction/_index.md
diff --git a/docs-site/content/kagent/introduction/features.md b/docs-site/content/kagent/0.x/introduction/features.md
similarity index 100%
rename from docs-site/content/kagent/introduction/features.md
rename to docs-site/content/kagent/0.x/introduction/features.md
diff --git a/docs-site/content/kagent/introduction/installation.md b/docs-site/content/kagent/0.x/introduction/installation.md
similarity index 100%
rename from docs-site/content/kagent/introduction/installation.md
rename to docs-site/content/kagent/0.x/introduction/installation.md
diff --git a/docs-site/content/kagent/introduction/what-is-kagent.md b/docs-site/content/kagent/0.x/introduction/what-is-kagent.md
similarity index 100%
rename from docs-site/content/kagent/introduction/what-is-kagent.md
rename to docs-site/content/kagent/0.x/introduction/what-is-kagent.md
diff --git a/docs-site/content/kagent/0.x/not-in-version.md b/docs-site/content/kagent/0.x/not-in-version.md
new file mode 100644
index 00000000..306e4dc5
--- /dev/null
+++ b/docs-site/content/kagent/0.x/not-in-version.md
@@ -0,0 +1,8 @@
+---
+title: Topic not available in this version
+description: This topic isn't available in this version of the documentation.
+build:
+ list: never
+---
+
+This topic doesn't exist in this version of the kagent docs. Use the version switcher above to go back to a version where it's available, or browse the [kagent docs]({{< relref "/kagent/0.x" >}}) landing page.
diff --git a/docs-site/content/kagent/observability/_index.md b/docs-site/content/kagent/0.x/observability/_index.md
similarity index 100%
rename from docs-site/content/kagent/observability/_index.md
rename to docs-site/content/kagent/0.x/observability/_index.md
diff --git a/docs-site/content/kagent/observability/audit-prompts.md b/docs-site/content/kagent/0.x/observability/audit-prompts.md
similarity index 100%
rename from docs-site/content/kagent/observability/audit-prompts.md
rename to docs-site/content/kagent/0.x/observability/audit-prompts.md
diff --git a/docs-site/content/kagent/observability/launch-ui.md b/docs-site/content/kagent/0.x/observability/launch-ui.md
similarity index 100%
rename from docs-site/content/kagent/observability/launch-ui.md
rename to docs-site/content/kagent/0.x/observability/launch-ui.md
diff --git a/docs-site/content/kagent/observability/tracing.md b/docs-site/content/kagent/0.x/observability/tracing.md
similarity index 100%
rename from docs-site/content/kagent/observability/tracing.md
rename to docs-site/content/kagent/0.x/observability/tracing.md
diff --git a/docs-site/content/kagent/operations/_index.md b/docs-site/content/kagent/0.x/operations/_index.md
similarity index 100%
rename from docs-site/content/kagent/operations/_index.md
rename to docs-site/content/kagent/0.x/operations/_index.md
diff --git a/docs-site/content/kagent/operations/debug.md b/docs-site/content/kagent/0.x/operations/debug.md
similarity index 100%
rename from docs-site/content/kagent/operations/debug.md
rename to docs-site/content/kagent/0.x/operations/debug.md
diff --git a/docs-site/content/kagent/operations/operational-considerations.md b/docs-site/content/kagent/0.x/operations/operational-considerations.md
similarity index 100%
rename from docs-site/content/kagent/operations/operational-considerations.md
rename to docs-site/content/kagent/0.x/operations/operational-considerations.md
diff --git a/docs-site/content/kagent/operations/uninstall.md b/docs-site/content/kagent/0.x/operations/uninstall.md
similarity index 100%
rename from docs-site/content/kagent/operations/uninstall.md
rename to docs-site/content/kagent/0.x/operations/uninstall.md
diff --git a/docs-site/content/kagent/operations/upgrade.md b/docs-site/content/kagent/0.x/operations/upgrade.md
similarity index 100%
rename from docs-site/content/kagent/operations/upgrade.md
rename to docs-site/content/kagent/0.x/operations/upgrade.md
diff --git a/docs-site/content/kagent/resources/_index.md b/docs-site/content/kagent/0.x/resources/_index.md
similarity index 100%
rename from docs-site/content/kagent/resources/_index.md
rename to docs-site/content/kagent/0.x/resources/_index.md
diff --git a/docs-site/content/kagent/resources/api-ref.md b/docs-site/content/kagent/0.x/resources/api-ref.md
similarity index 100%
rename from docs-site/content/kagent/resources/api-ref.md
rename to docs-site/content/kagent/0.x/resources/api-ref.md
diff --git a/docs-site/content/kagent/resources/cli/_index.md b/docs-site/content/kagent/0.x/resources/cli/_index.md
similarity index 100%
rename from docs-site/content/kagent/resources/cli/_index.md
rename to docs-site/content/kagent/0.x/resources/cli/_index.md
diff --git a/docs-site/content/kagent/resources/cli/kagent-add-mcp.md b/docs-site/content/kagent/0.x/resources/cli/kagent-add-mcp.md
similarity index 100%
rename from docs-site/content/kagent/resources/cli/kagent-add-mcp.md
rename to docs-site/content/kagent/0.x/resources/cli/kagent-add-mcp.md
diff --git a/docs-site/content/kagent/resources/cli/kagent-bug-report.md b/docs-site/content/kagent/0.x/resources/cli/kagent-bug-report.md
similarity index 100%
rename from docs-site/content/kagent/resources/cli/kagent-bug-report.md
rename to docs-site/content/kagent/0.x/resources/cli/kagent-bug-report.md
diff --git a/docs-site/content/kagent/resources/cli/kagent-build.md b/docs-site/content/kagent/0.x/resources/cli/kagent-build.md
similarity index 100%
rename from docs-site/content/kagent/resources/cli/kagent-build.md
rename to docs-site/content/kagent/0.x/resources/cli/kagent-build.md
diff --git a/docs-site/content/kagent/resources/cli/kagent-completion.md b/docs-site/content/kagent/0.x/resources/cli/kagent-completion.md
similarity index 100%
rename from docs-site/content/kagent/resources/cli/kagent-completion.md
rename to docs-site/content/kagent/0.x/resources/cli/kagent-completion.md
diff --git a/docs-site/content/kagent/resources/cli/kagent-dashboard.md b/docs-site/content/kagent/0.x/resources/cli/kagent-dashboard.md
similarity index 100%
rename from docs-site/content/kagent/resources/cli/kagent-dashboard.md
rename to docs-site/content/kagent/0.x/resources/cli/kagent-dashboard.md
diff --git a/docs-site/content/kagent/resources/cli/kagent-deploy.md b/docs-site/content/kagent/0.x/resources/cli/kagent-deploy.md
similarity index 100%
rename from docs-site/content/kagent/resources/cli/kagent-deploy.md
rename to docs-site/content/kagent/0.x/resources/cli/kagent-deploy.md
diff --git a/docs-site/content/kagent/resources/cli/kagent-get.md b/docs-site/content/kagent/0.x/resources/cli/kagent-get.md
similarity index 100%
rename from docs-site/content/kagent/resources/cli/kagent-get.md
rename to docs-site/content/kagent/0.x/resources/cli/kagent-get.md
diff --git a/docs-site/content/kagent/resources/cli/kagent-help.md b/docs-site/content/kagent/0.x/resources/cli/kagent-help.md
similarity index 100%
rename from docs-site/content/kagent/resources/cli/kagent-help.md
rename to docs-site/content/kagent/0.x/resources/cli/kagent-help.md
diff --git a/docs-site/content/kagent/resources/cli/kagent-init.md b/docs-site/content/kagent/0.x/resources/cli/kagent-init.md
similarity index 100%
rename from docs-site/content/kagent/resources/cli/kagent-init.md
rename to docs-site/content/kagent/0.x/resources/cli/kagent-init.md
diff --git a/docs-site/content/kagent/resources/cli/kagent-install.md b/docs-site/content/kagent/0.x/resources/cli/kagent-install.md
similarity index 100%
rename from docs-site/content/kagent/resources/cli/kagent-install.md
rename to docs-site/content/kagent/0.x/resources/cli/kagent-install.md
diff --git a/docs-site/content/kagent/resources/cli/kagent-invoke.md b/docs-site/content/kagent/0.x/resources/cli/kagent-invoke.md
similarity index 100%
rename from docs-site/content/kagent/resources/cli/kagent-invoke.md
rename to docs-site/content/kagent/0.x/resources/cli/kagent-invoke.md
diff --git a/docs-site/content/kagent/resources/cli/kagent-mcp.md b/docs-site/content/kagent/0.x/resources/cli/kagent-mcp.md
similarity index 100%
rename from docs-site/content/kagent/resources/cli/kagent-mcp.md
rename to docs-site/content/kagent/0.x/resources/cli/kagent-mcp.md
diff --git a/docs-site/content/kagent/resources/cli/kagent-run.md b/docs-site/content/kagent/0.x/resources/cli/kagent-run.md
similarity index 100%
rename from docs-site/content/kagent/resources/cli/kagent-run.md
rename to docs-site/content/kagent/0.x/resources/cli/kagent-run.md
diff --git a/docs-site/content/kagent/resources/cli/kagent-uninstall.md b/docs-site/content/kagent/0.x/resources/cli/kagent-uninstall.md
similarity index 100%
rename from docs-site/content/kagent/resources/cli/kagent-uninstall.md
rename to docs-site/content/kagent/0.x/resources/cli/kagent-uninstall.md
diff --git a/docs-site/content/kagent/resources/cli/kagent-version.md b/docs-site/content/kagent/0.x/resources/cli/kagent-version.md
similarity index 100%
rename from docs-site/content/kagent/resources/cli/kagent-version.md
rename to docs-site/content/kagent/0.x/resources/cli/kagent-version.md
diff --git a/docs-site/content/kagent/resources/community.md b/docs-site/content/kagent/0.x/resources/community.md
similarity index 100%
rename from docs-site/content/kagent/resources/community.md
rename to docs-site/content/kagent/0.x/resources/community.md
diff --git a/docs-site/content/kagent/resources/faq.md b/docs-site/content/kagent/0.x/resources/faq.md
similarity index 100%
rename from docs-site/content/kagent/resources/faq.md
rename to docs-site/content/kagent/0.x/resources/faq.md
diff --git a/docs-site/content/kagent/resources/helm.md b/docs-site/content/kagent/0.x/resources/helm.md
similarity index 100%
rename from docs-site/content/kagent/resources/helm.md
rename to docs-site/content/kagent/0.x/resources/helm.md
diff --git a/docs-site/content/kagent/resources/release-notes.md b/docs-site/content/kagent/0.x/resources/release-notes.md
similarity index 100%
rename from docs-site/content/kagent/resources/release-notes.md
rename to docs-site/content/kagent/0.x/resources/release-notes.md
diff --git a/docs-site/content/kagent/resources/tools-ecosystem.md b/docs-site/content/kagent/0.x/resources/tools-ecosystem.md
similarity index 100%
rename from docs-site/content/kagent/resources/tools-ecosystem.md
rename to docs-site/content/kagent/0.x/resources/tools-ecosystem.md
diff --git a/docs-site/content/kagent/resources/versions.md b/docs-site/content/kagent/0.x/resources/versions.md
similarity index 100%
rename from docs-site/content/kagent/resources/versions.md
rename to docs-site/content/kagent/0.x/resources/versions.md
diff --git a/docs-site/content/kagent/supported-providers/_index.md b/docs-site/content/kagent/0.x/supported-providers/_index.md
similarity index 100%
rename from docs-site/content/kagent/supported-providers/_index.md
rename to docs-site/content/kagent/0.x/supported-providers/_index.md
diff --git a/docs-site/content/kagent/supported-providers/amazon-bedrock.md b/docs-site/content/kagent/0.x/supported-providers/amazon-bedrock.md
similarity index 100%
rename from docs-site/content/kagent/supported-providers/amazon-bedrock.md
rename to docs-site/content/kagent/0.x/supported-providers/amazon-bedrock.md
diff --git a/docs-site/content/kagent/supported-providers/anthropic.md b/docs-site/content/kagent/0.x/supported-providers/anthropic.md
similarity index 100%
rename from docs-site/content/kagent/supported-providers/anthropic.md
rename to docs-site/content/kagent/0.x/supported-providers/anthropic.md
diff --git a/docs-site/content/kagent/supported-providers/azure-ai-foundry.md b/docs-site/content/kagent/0.x/supported-providers/azure-ai-foundry.md
similarity index 100%
rename from docs-site/content/kagent/supported-providers/azure-ai-foundry.md
rename to docs-site/content/kagent/0.x/supported-providers/azure-ai-foundry.md
diff --git a/docs-site/content/kagent/supported-providers/azure-openai.md b/docs-site/content/kagent/0.x/supported-providers/azure-openai.md
similarity index 100%
rename from docs-site/content/kagent/supported-providers/azure-openai.md
rename to docs-site/content/kagent/0.x/supported-providers/azure-openai.md
diff --git a/docs-site/content/kagent/supported-providers/byo-agentgateway.md b/docs-site/content/kagent/0.x/supported-providers/byo-agentgateway.md
similarity index 100%
rename from docs-site/content/kagent/supported-providers/byo-agentgateway.md
rename to docs-site/content/kagent/0.x/supported-providers/byo-agentgateway.md
diff --git a/docs-site/content/kagent/supported-providers/byo-openai.md b/docs-site/content/kagent/0.x/supported-providers/byo-openai.md
similarity index 100%
rename from docs-site/content/kagent/supported-providers/byo-openai.md
rename to docs-site/content/kagent/0.x/supported-providers/byo-openai.md
diff --git a/docs-site/content/kagent/supported-providers/gemini.md b/docs-site/content/kagent/0.x/supported-providers/gemini.md
similarity index 100%
rename from docs-site/content/kagent/supported-providers/gemini.md
rename to docs-site/content/kagent/0.x/supported-providers/gemini.md
diff --git a/docs-site/content/kagent/supported-providers/google-vertexai.md b/docs-site/content/kagent/0.x/supported-providers/google-vertexai.md
similarity index 100%
rename from docs-site/content/kagent/supported-providers/google-vertexai.md
rename to docs-site/content/kagent/0.x/supported-providers/google-vertexai.md
diff --git a/docs-site/content/kagent/supported-providers/ollama.md b/docs-site/content/kagent/0.x/supported-providers/ollama.md
similarity index 100%
rename from docs-site/content/kagent/supported-providers/ollama.md
rename to docs-site/content/kagent/0.x/supported-providers/ollama.md
diff --git a/docs-site/content/kagent/supported-providers/openai.md b/docs-site/content/kagent/0.x/supported-providers/openai.md
similarity index 100%
rename from docs-site/content/kagent/supported-providers/openai.md
rename to docs-site/content/kagent/0.x/supported-providers/openai.md
diff --git a/docs-site/content/kagent/supported-providers/sap-ai-core.md b/docs-site/content/kagent/0.x/supported-providers/sap-ai-core.md
similarity index 100%
rename from docs-site/content/kagent/supported-providers/sap-ai-core.md
rename to docs-site/content/kagent/0.x/supported-providers/sap-ai-core.md
diff --git a/docs-site/content/kagent/supported-providers/xai.md b/docs-site/content/kagent/0.x/supported-providers/xai.md
similarity index 100%
rename from docs-site/content/kagent/supported-providers/xai.md
rename to docs-site/content/kagent/0.x/supported-providers/xai.md
diff --git a/docs-site/content/kagent/1.x/_index.md b/docs-site/content/kagent/1.x/_index.md
new file mode 100644
index 00000000..f68c8997
--- /dev/null
+++ b/docs-site/content/kagent/1.x/_index.md
@@ -0,0 +1,13 @@
+---
+title: kagent 1.0
+linkTitle: "kagent 1.x (preview)"
+description: Preview documentation for the kagent 1.0 release, built on Agent Substrate.
+weight: 1
+author: kagent.dev
+---
+
+# kagent 1.0 (preview)
+
+kagent 1.0 moves the runtime from Kubernetes Deployments to [Agent Substrate](https://github.com/agent-substrate/substrate), introducing Harness, AgentTemplate, and AgentInstance as the new API surface.
+
+This section is under active development ahead of the 1.0 release. Pages here may be incomplete, and content may change without notice. See the [0.x docs]({{< relref "/kagent/0.x" >}}) for the current stable release.
diff --git a/docs-site/content/kagent/1.x/not-in-version.md b/docs-site/content/kagent/1.x/not-in-version.md
new file mode 100644
index 00000000..b4d3437f
--- /dev/null
+++ b/docs-site/content/kagent/1.x/not-in-version.md
@@ -0,0 +1,8 @@
+---
+title: Topic not available in this version
+description: This topic isn't available in this version of the documentation.
+build:
+ list: never
+---
+
+This topic doesn't exist in this version of the kagent docs yet. Use the version switcher above to go back to a version where it's available, or browse the [kagent 1.0 (preview)]({{< relref "/kagent/1.x" >}}) landing page.
diff --git a/docs-site/content/kagent/_index.md b/docs-site/content/kagent/_index.md
index 1a4f7505..bc8c3517 100644
--- a/docs-site/content/kagent/_index.md
+++ b/docs-site/content/kagent/_index.md
@@ -3,34 +3,9 @@ title: kagent
description: Concepts, guides, and reference docs for running declarative AI agents on Kubernetes, from install through day-two operations.
weight: 1
author: kagent.dev
+disableCards: true
---
-Your complete guide to the AI agent platform for Kubernetes
-
-## What is kagent?
-
-kagent is an innovative AI agent platform designed specifically for Kubernetes environments.
-It empowers developers and operations teams to create intelligent, autonomous agents that can
-monitor, manage, and automate complex Kubernetes workloads using the power of large language models (LLMs).
-
-kagent was created at [Solo.io](https://www.solo.io) in 2025 and is a [Cloud Native Computing Foundation](https://www.cncf.io) sandbox project.
-
-## Key Features
-
-- **AI-Powered Automation** - Create intelligent agents that understand natural language and can perform complex Kubernetes operations
-- **Multi-Provider Support** - Works with OpenAI, Anthropic, Google Vertex AI, Azure OpenAI, Ollama, and custom models
-- **Tool Integration** - Supports Model Context Protocol (MCP) tools, built-in Kubernetes tools, and custom HTTP tools
-- **Agent-to-Agent Communication** - Enable sophisticated workflows through A2A (Agent-to-Agent) interactions
-- **Comprehensive Observability** - Built-in tracing and monitoring to understand agent behavior and performance
-- **Cloud Native** - Designed from the ground up to run natively in Kubernetes environments
-
-## Why Choose kagent?
-
-Whether you're looking to automate routine operations, implement intelligent monitoring,
-or create sophisticated multi-agent workflows, kagent provides the tools and framework
-to bring AI to your Kubernetes infrastructure. Start with simple automation and scale
-to complex, intelligent systems that can reason about your cluster's state and make
-informed decisions.
-
-## Explore the Documentation
+# kagent docs
+{{< version-cards desc="Select a version of the kagent docs." >}}
diff --git a/docs-site/hugo.yaml b/docs-site/hugo.yaml
index fa93f101..7b2114e2 100644
--- a/docs-site/hugo.yaml
+++ b/docs-site/hugo.yaml
@@ -108,6 +108,30 @@ params:
# Auto-render the light/dark toggle in the navbar
displayToggle: true
+ # Per-section version lists, consumed by the local navbar.html override
+ # (layouts/_partials/navbar.html) and by docs-theme-extras' version-cards
+ # shortcode. Scoped under sections.kagent rather than the top-level
+ # `versions` key so kmcp — the other product built into this same Hugo
+ # site — never picks up kagent's version dropdown. See the navbar.html
+ # override's header comment for why that scoping is necessary here.
+ #
+ # 0.x is the frozen pre-1.0 doc set (moved verbatim from the former flat
+ # content/kagent/ tree); 1.x is the in-progress v1alpha3/Agent Substrate
+ # rewrite and carries an in-development banner until it's ready to become
+ # the default.
+ sections:
+ kagent:
+ versions:
+ - version: "0.x"
+ dropdown: "0.x (current)"
+ linkVersion: "0.x"
+ url: "/kagent/0.x"
+ - version: "1.x"
+ dropdown: "1.x (preview)"
+ linkVersion: "1.x"
+ url: "/kagent/1.x"
+ banner: "This is preview documentation for the upcoming kagent 1.0 release. It is incomplete and may change without notice."
+
# Top nav — mirrors kagent.dev. Docs is local; the marketing/blog sections stay
# on the Next.js site, so those link out to absolute kagent.dev URLs.
menu:
diff --git a/docs-site/layouts/_partials/navbar.html b/docs-site/layouts/_partials/navbar.html
new file mode 100644
index 00000000..bd13da2f
--- /dev/null
+++ b/docs-site/layouts/_partials/navbar.html
@@ -0,0 +1,318 @@
+{{- /* Custom navbar override: adds version dropdown from [[params.versions]] */ -}}
+{{- $navWidth := "hx:max-w-[90rem]" -}}
+{{- with .Site.Params.navbar.width -}}
+ {{ if eq . "normal" -}}
+ {{ $navWidth = "hx:max-w-screen-xl" -}}
+ {{ else if eq . "full" -}}
+ {{ $navWidth = "max-w-full" -}}
+ {{ end -}}
+{{- end -}}
+
+{{- $page := . -}}
+{{- $iconHeight := 24 -}}
+
+
+
+
+
+
diff --git a/docs-site/layouts/partials/version-banner.html b/docs-site/layouts/partials/version-banner.html
new file mode 100644
index 00000000..be3f790f
--- /dev/null
+++ b/docs-site/layouts/partials/version-banner.html
@@ -0,0 +1,49 @@
+{{- /* kagent override of docs-theme-extras' version-banner.html.
+
+ Why this exists: upstream matches against `.FirstSection.RelPermalink`
+ (always the top-level section, e.g. "/kagent/") checked as a substring
+ against `.linkVersion`, which can't see a version segment nested a
+ level deeper (content/kagent/0.x/…) — the substring check would never
+ fire. It also reads only the site-wide Site.Params.versions, which
+ kagent leaves unset (see the navbar.html override) since this build
+ also serves kmcp, an unrelated, unversioned product.
+
+ Fix: resolve versions the same way navbar.html's override and
+ version-cards.html do (Site.Params.sections..versions,
+ falling back to the site-wide list), and match by checking whether any
+ exact path segment of the current page's own RelPermalink equals
+ `.linkVersion` — correct regardless of nesting depth, folder prefix,
+ or language prefix, and still no-ops on kmcp pages since none of their
+ segments will ever equal "0.x"/"1.x".
+
+ Everything below the resolution step (the bannerID/i18n handling,
+ markdownify, markup) matches upstream. */ -}}
+{{- $currentSection := .Section -}}
+{{- $versions := slice -}}
+{{- if and $currentSection (isset .Site.Params.sections $currentSection) -}}
+ {{- with (index .Site.Params.sections $currentSection).versions -}}
+ {{- $versions = . -}}
+ {{- end -}}
+{{- end -}}
+{{- if eq (len $versions) 0 -}}
+ {{- with .Site.Params.versions -}}
+ {{- $versions = . -}}
+ {{- end -}}
+{{- end -}}
+
+{{- $segments := split (strings.Trim .RelPermalink "/") "/" -}}
+{{- $bannerText := "" -}}
+{{- range $versions -}}
+ {{- if and (not $bannerText) .banner (in $segments .linkVersion) -}}
+ {{- $bannerText = .banner -}}
+ {{- if .bannerID -}}
+ {{- $translated := i18n .bannerID . -}}
+ {{- if $translated -}}{{- $bannerText = $translated -}}{{- end -}}
+ {{- end -}}
+ {{- end -}}
+{{- end -}}
+{{- with $bannerText }}
+
+ {{ . | markdownify }}
+
+{{- end -}}
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 66289ba6..2c2aeacb 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -264,7 +264,7 @@ export default function RedesignPage() {
already trusts. Open source. Production grade. Built by the founders of Istio.
-
+
Get Started
@@ -680,7 +680,7 @@ export default function RedesignPage() {
Run your first agent on Kubernetes today.
One Helm chart. One CRD. One namespace. You'll be looking at agent traces before your coffee gets cold.
-
+
Get Started
diff --git a/src/components/footer.tsx b/src/components/footer.tsx
index d9c03ec9..1fe8874c 100644
--- a/src/components/footer.tsx
+++ b/src/components/footer.tsx
@@ -18,22 +18,22 @@ export default function Footer() {
Getting Started
-
+
Installing kagent
-
+
Quick Start
-
+
First Agent Guide
-
+
First MCP Tool
@@ -45,22 +45,22 @@ export default function Footer() {
Documentation
-
+
What is kagent
-
+
Architecture
-
+
Core Concepts
-
+
Configuring LLM Providers
@@ -82,22 +82,22 @@ export default function Footer() {
-
+
A2A Agents
-
+
Documentation Agent
-
+
Slack and A2A
-
+
Discord and A2A
@@ -129,7 +129,7 @@ export default function Footer() {
-
+
FAQ
diff --git a/src/components/key-components.tsx b/src/components/key-components.tsx
index 571454bc..5fddd49c 100644
--- a/src/components/key-components.tsx
+++ b/src/components/key-components.tsx
@@ -20,7 +20,7 @@ const keyComponents = [
{
title: "Framework",
icon: Code,
- link: "/docs/kagent/concepts",
+ link: "/docs/kagent/0.x/concepts",
description: "Simple CLI and UI interface to run agents, with full extensibility for custom solutions",
},
];
From 99e7077c66d7679b4474adf2ec713e5495ae5518 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Fri, 21 Aug 2026 16:25:56 -0500
Subject: [PATCH 02/70] Scope the docs sidebar to the current kagent doc
version
The sidebar override rooted its tree at the kagent product section via
.FirstSection, which was fine when kagent was flat. Now that 0.x and 1.x
are both direct children of that section, it showed both versions' full
trees at once regardless of which one the version switcher pointed at.
Resolve the current page's own version page and root the tree there
instead, falling back to hiding the sidebar on the bare version-picker
landing page where there's no single version to root at. kmcp, which has
no versions config, is unaffected. Verified against a real Hugo build.
Co-Authored-By: Claude Sonnet 5
Signed-off-by: Rachael Graham
---
docs-site/layouts/_partials/sidebar.html | 72 +++++++++++++++++++-----
1 file changed, 57 insertions(+), 15 deletions(-)
diff --git a/docs-site/layouts/_partials/sidebar.html b/docs-site/layouts/_partials/sidebar.html
index fd2a0d40..3c50bbdd 100644
--- a/docs-site/layouts/_partials/sidebar.html
+++ b/docs-site/layouts/_partials/sidebar.html
@@ -7,17 +7,29 @@
at the current section, so kagent's nav "drills down" as you navigate deeper
instead of showing the whole product tree.
- kagent docs are flat + unversioned but split across two products (kagent + kmcp,
- each a top-level content section). This override roots the tree at the product
- section via .FirstSection — the current page's top-level section ancestor — so
- every page in a product shows that product's full, expandable tree with the
- active branch auto-expanded. Using .FirstSection (rather than parsing the URL
- for a /docs/ prefix) keeps this correct regardless of the baseURL
+ kagent docs are split across two top-level content sections, kagent and
+ kmcp. This override roots the tree at the product section via .FirstSection
+ — the current page's top-level section ancestor — so every page in a
+ product shows that product's full, expandable tree with the active branch
+ auto-expanded. Using .FirstSection (rather than parsing the URL for a
+ /docs/ prefix) keeps this correct regardless of the baseURL
subpath the site is served under. It reuses the same CSS classes /
data-attributes as extras' sidebar (sidebar-link, sidebar-toggle,
sidebar-children, data-sidebar-item, sidebar-mobile-panel) so the toggle JS and
mobile drawer in docs-theme-extras keep working.
+ kagent (unlike kmcp) is also versioned (0.x, 1.x — see
+ sections.kagent.versions in hugo.yaml). .FirstSection alone would root the
+ tree at the "kagent" product page, whose direct children are now the 0.x
+ and 1.x version pages themselves — so BOTH versions' full trees would
+ render side by side, and the version switcher (navbar.html) would have no
+ effect on the sidebar at all. For a versioned product, this override
+ instead resolves the CURRENT page's version page (e.g. "/kagent/0.x") and
+ roots the tree there, so only that version's sections show. On the bare
+ product landing page (the version-picker itself, with no version segment
+ in its own URL) there's no single version to root at, so the sidebar is
+ suppressed there rather than showing every version.
+
Called by extras' docs/single.html + docs/list.html as:
{{ partial "sidebar.html" (dict "context" .) }}
*/ -}}
@@ -29,17 +41,47 @@
{{- else -}}
{{- $navRoot := $context.FirstSection -}}
+ {{- $suppress := false -}}
-
-
+ {{- end -}}
+ {{- if $versionPage -}}
+ {{- $navRoot = $versionPage -}}
+ {{- else -}}
+ {{- $suppress = true -}}
+ {{- end -}}
+ {{- end -}}
+ {{- end -}}
+
+ {{- if $suppress -}}
+
+ {{- else -}}
+
+
+ {{- end -}}
{{- end -}}
{{- /* Recursive tree renderer — mirrors extras' render-sidebar-tree markup. */ -}}
From 94eda0d4ff82515568a7e14e9800a6b803b91b79 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Fri, 21 Aug 2026 16:26:12 -0500
Subject: [PATCH 03/70] Convert internal kagent 0.x links to relref shortcodes
The 0.x content had 124 internal cross-links hardcoded as absolute
/docs/kagent/... paths, written before the version split. They all 404
now that the same content lives under /docs/kagent/0.x/...
Convert them to {{< relref >}} shortcodes pointing at /kagent/0.x/...
instead of just patching in the version segment as a literal string, so
they resolve against the actual content graph and Hugo's build fails
loudly (relref is strict) if a target ever moves again, rather than
silently 404ing.
Co-Authored-By: Claude Sonnet 5
Signed-off-by: Rachael Graham
---
.../content/kagent/0.x/concepts/_index.md | 2 +-
.../kagent/0.x/concepts/agent-harness.md | 6 +++---
.../kagent/0.x/concepts/agent-memory.md | 6 +++---
.../kagent/0.x/concepts/agent-substrate.md | 10 +++++-----
.../content/kagent/0.x/concepts/agents.md | 14 ++++++-------
.../kagent/0.x/concepts/architecture.md | 4 ++--
.../content/kagent/0.x/concepts/mcp-apps.md | 2 +-
.../content/kagent/0.x/concepts/tools.md | 4 ++--
.../content/kagent/0.x/examples/a2a-agents.md | 4 ++--
.../content/kagent/0.x/examples/a2a-byo.md | 6 +++---
.../kagent/0.x/examples/agent-harness.md | 10 +++++-----
.../kagent/0.x/examples/agent-substrate.md | 6 +++---
.../kagent/0.x/examples/agentgateway.md | 4 ++--
.../content/kagent/0.x/examples/crewai-byo.md | 6 +++---
.../kagent/0.x/examples/discord-a2a.md | 4 ++--
.../kagent/0.x/examples/langchain-byo.md | 4 ++--
.../content/kagent/0.x/examples/skills.md | 10 +++++-----
.../content/kagent/0.x/examples/slack-a2a.md | 2 +-
.../kagent/0.x/examples/telegram-bot.md | 2 +-
.../kagent/0.x/getting-started/first-agent.md | 4 ++--
.../0.x/getting-started/first-mcp-tool.md | 6 +++---
.../0.x/getting-started/local-development.md | 4 ++--
.../kagent/0.x/getting-started/quickstart.md | 6 +++---
.../content/kagent/0.x/introduction/_index.md | 2 +-
.../kagent/0.x/introduction/installation.md | 16 +++++++--------
.../kagent/0.x/introduction/what-is-kagent.md | 4 ++--
.../kagent/0.x/observability/audit-prompts.md | 2 +-
.../kagent/0.x/observability/launch-ui.md | 6 +++---
.../kagent/0.x/observability/tracing.md | 10 +++++-----
.../operations/operational-considerations.md | 2 +-
.../kagent/0.x/operations/uninstall.md | 2 +-
.../content/kagent/0.x/operations/upgrade.md | 10 +++++-----
.../content/kagent/0.x/resources/_index.md | 2 +-
docs-site/content/kagent/0.x/resources/faq.md | 2 +-
.../kagent/0.x/resources/release-notes.md | 20 +++++++++----------
.../0.x/supported-providers/amazon-bedrock.md | 2 +-
.../supported-providers/azure-ai-foundry.md | 2 +-
.../0.x/supported-providers/azure-openai.md | 2 +-
38 files changed, 105 insertions(+), 105 deletions(-)
diff --git a/docs-site/content/kagent/0.x/concepts/_index.md b/docs-site/content/kagent/0.x/concepts/_index.md
index 0f67b0a6..41b4b4f6 100644
--- a/docs-site/content/kagent/0.x/concepts/_index.md
+++ b/docs-site/content/kagent/0.x/concepts/_index.md
@@ -7,4 +7,4 @@ author: kagent.dev
Learn about the AI agent and kagent concepts.
-The [Agents](/docs/kagent/concepts/agents) page also covers [prompt templates](/docs/kagent/concepts/agents#prompt-templates), [Git-based skills](/docs/kagent/concepts/agents#git-based-skills), and [context management](/docs/kagent/concepts/agents#context-management). For related material, see [What is kagent](/docs/kagent/introduction/what-is-kagent), the [Tools Ecosystem](/docs/kagent/resources/tools-ecosystem) catalog, [Human-in-the-Loop](/docs/kagent/examples/human-in-the-loop) configuration, and the [examples](/docs/kagent/examples), which include both the Go and Python runtimes.
+The [Agents]({{< relref "/kagent/0.x/concepts/agents" >}}) page also covers [prompt templates]({{< relref "/kagent/0.x/concepts/agents#prompt-templates" >}}), [Git-based skills]({{< relref "/kagent/0.x/concepts/agents#git-based-skills" >}}), and [context management]({{< relref "/kagent/0.x/concepts/agents#context-management" >}}). For related material, see [What is kagent]({{< relref "/kagent/0.x/introduction/what-is-kagent" >}}), the [Tools Ecosystem]({{< relref "/kagent/0.x/resources/tools-ecosystem" >}}) catalog, [Human-in-the-Loop]({{< relref "/kagent/0.x/examples/human-in-the-loop" >}}) configuration, and the [examples]({{< relref "/kagent/0.x/examples" >}}), which include both the Go and Python runtimes.
diff --git a/docs-site/content/kagent/0.x/concepts/agent-harness.md b/docs-site/content/kagent/0.x/concepts/agent-harness.md
index ab4455fe..a5043d18 100644
--- a/docs-site/content/kagent/0.x/concepts/agent-harness.md
+++ b/docs-site/content/kagent/0.x/concepts/agent-harness.md
@@ -5,7 +5,7 @@ weight: 4
author: kagent.dev
---
-An `AgentHarness` is a Kubernetes custom resource that asks kagent to provision a long-running remote execution environment on [Agent Substrate](/docs/kagent/concepts/agent-substrate). It is useful when you want a managed sandbox that runs a coding agent (such as OpenClaw or Hermes) that you can chat with and connect to messaging channels, but you do not want kagent to package and run a full agent runtime inside the workload.
+An `AgentHarness` is a Kubernetes custom resource that asks kagent to provision a long-running remote execution environment on [Agent Substrate]({{< relref "/kagent/0.x/concepts/agent-substrate" >}}). It is useful when you want a managed sandbox that runs a coding agent (such as OpenClaw or Hermes) that you can chat with and connect to messaging channels, but you do not want kagent to package and run a full agent runtime inside the workload.
`AgentHarness` resources appear alongside agents in kagent APIs and status views, but they are not the same thing as `Agent` or `SandboxAgent`.
@@ -30,7 +30,7 @@ All backends use the same top-level `AgentHarness` shape: `backend`, `substrate`
## Runtime: Agent Substrate
-Every `AgentHarness` runs on [Agent Substrate](/docs/kagent/concepts/agent-substrate). The `spec.substrate` field is required and configures the Substrate provisioning stack:
+Every `AgentHarness` runs on [Agent Substrate]({{< relref "/kagent/0.x/concepts/agent-substrate" >}}). The `spec.substrate` field is required and configures the Substrate provisioning stack:
- `workerPoolRef` — references an existing `WorkerPool` in the harness namespace. When unset, the controller uses its configured default WorkerPool.
- `snapshotsConfig` — configures where actor memory snapshots are stored. Defaults to `gs://ate-snapshots//` when unset.
@@ -94,4 +94,4 @@ The API uses CEL validation to ensure Slack settings match the selected backend.
## Next steps
-For enabling Agent Substrate so the controller can provision harnesses, see [Enable AgentHarness support](/docs/kagent/introduction/installation#enable-agentharness-support). For complete YAML examples, including Slack token references and backend-specific Slack settings, see the [Agent Harness example](/docs/kagent/examples/agent-harness). For the generated schema, see the [API reference](/docs/kagent/resources/api-ref#agentharness).
+For enabling Agent Substrate so the controller can provision harnesses, see [Enable AgentHarness support]({{< relref "/kagent/0.x/introduction/installation#enable-agentharness-support" >}}). For complete YAML examples, including Slack token references and backend-specific Slack settings, see the [Agent Harness example]({{< relref "/kagent/0.x/examples/agent-harness" >}}). For the generated schema, see the [API reference]({{< relref "/kagent/0.x/resources/api-ref#agentharness" >}}).
diff --git a/docs-site/content/kagent/0.x/concepts/agent-memory.md b/docs-site/content/kagent/0.x/concepts/agent-memory.md
index 3e85e470..88db2e76 100644
--- a/docs-site/content/kagent/0.x/concepts/agent-memory.md
+++ b/docs-site/content/kagent/0.x/concepts/agent-memory.md
@@ -22,7 +22,7 @@ Agent memory provides the following capabilities.
### Install kagent with Postgres
-To use memory, you must install kagent with a Postgres database that has the `pgvector` extension installed and vector enabled. For more information, see the [Database configuration](/docs/kagent/operations/operational-considerations#database-configuration) section.
+To use memory, you must install kagent with a Postgres database that has the `pgvector` extension installed and vector enabled. For more information, see the [Database configuration]({{< relref "/kagent/0.x/operations/operational-considerations#database-configuration" >}}) section.
Example Helm configuration for your own external Postgres:
@@ -71,7 +71,7 @@ The embedding `ModelConfig` does not have to use the same provider as the agent'
To use [Amazon Bedrock Titan embedding models](https://docs.aws.amazon.com/bedrock/latest/userguide/titan-embedding-models.html), create a `ModelConfig` with `provider: Bedrock`.
-The Bedrock provider uses the standard AWS credential chain, so no API key secret is required. The agent's pod must have AWS credentials with the `bedrock:InvokeModel` permission for the chosen model. On Kubernetes, the recommended setup is [EKS IRSA on the agent ServiceAccount](/docs/kagent/supported-providers/amazon-bedrock#step-3-configure-the-agent-to-use-an-iam-role).
+The Bedrock provider uses the standard AWS credential chain, so no API key secret is required. The agent's pod must have AWS credentials with the `bedrock:InvokeModel` permission for the chosen model. On Kubernetes, the recommended setup is [EKS IRSA on the agent ServiceAccount]({{< relref "/kagent/0.x/supported-providers/amazon-bedrock#step-3-configure-the-agent-to-use-an-iam-role" >}}).
```yaml
apiVersion: kagent.dev/v1alpha2
@@ -184,5 +184,5 @@ DELETE /api/memories?agent_name=X&user_id=Y
- **No per-memory deletion.** You can delete all memories for an agent, but you cannot delete individual memory entries.
- **No cross-agent memory sharing.** Each agent has its own isolated memory store. You cannot share memories across agents.
-- **Not pluggable.** Memory is built on the Google ADK memory implementation and cannot be swapped for an alternative memory solution (such as Cognee). However, if an alternative memory solution exposes an [MCP server](/docs/kagent/concepts/tools#mcp-tools), you can add it as a tool and instruct the agent to use it instead of the built-in memory.
+- **Not pluggable.** Memory is built on the Google ADK memory implementation and cannot be swapped for an alternative memory solution (such as Cognee). However, if an alternative memory solution exposes an [MCP server]({{< relref "/kagent/0.x/concepts/tools#mcp-tools" >}}), you can add it as a tool and instruct the agent to use it instead of the built-in memory.
diff --git a/docs-site/content/kagent/0.x/concepts/agent-substrate.md b/docs-site/content/kagent/0.x/concepts/agent-substrate.md
index 85e7ff20..8ae021dd 100644
--- a/docs-site/content/kagent/0.x/concepts/agent-substrate.md
+++ b/docs-site/content/kagent/0.x/concepts/agent-substrate.md
@@ -9,8 +9,8 @@ Agent Substrate is a Kubernetes-native runtime for running AI agents and other s
kagent can run workloads on Agent Substrate in two ways:
-- **Declarative agents** — A declarative `Agent` describes its model, instructions, and tools (see [Agents](/docs/kagent/concepts/agents)). Its sandboxed variant, the [`SandboxAgent`](/docs/kagent/resources/api-ref) CRD, lets you run a (Go) declarative agent on Agent Substrate.
-- **AgentHarness** — The [`AgentHarness`](/docs/kagent/concepts/agent-harness) CRD provisions a long-running execution environment for a coding agent (OpenClaw or Hermes). It always runs on Agent Substrate: kagent generates a per-harness `ActorTemplate` and creates an `Actor` from it on demand, referencing a `WorkerPool` for capacity.
+- **Declarative agents** — A declarative `Agent` describes its model, instructions, and tools (see [Agents]({{< relref "/kagent/0.x/concepts/agents" >}})). Its sandboxed variant, the [`SandboxAgent`]({{< relref "/kagent/0.x/resources/api-ref" >}}) CRD, lets you run a (Go) declarative agent on Agent Substrate.
+- **AgentHarness** — The [`AgentHarness`]({{< relref "/kagent/0.x/concepts/agent-harness" >}}) CRD provisions a long-running execution environment for a coding agent (OpenClaw or Hermes). It always runs on Agent Substrate: kagent generates a per-harness `ActorTemplate` and creates an `Actor` from it on demand, referencing a `WorkerPool` for capacity.
## Why Agent Substrate
@@ -66,11 +66,11 @@ An `AgentHarness` always runs on Agent Substrate; `spec.substrate` is required.
- `snapshotsConfig` — configures where actor memory snapshots are stored. Defaults to `gs://ate-snapshots//` when unset.
- `workloadImage` — overrides the default OpenClaw or Hermes sandbox image used in the generated ActorTemplate.
-kagent talks to the harness over the [Agent Client Protocol (ACP)](https://agentclientprotocol.com/) so you can chat with it from the kagent UI. See the [Agent Harness concept page](/docs/kagent/concepts/agent-harness) for details.
+kagent talks to the harness over the [Agent Client Protocol (ACP)](https://agentclientprotocol.com/) so you can chat with it from the kagent UI. See the [Agent Harness concept page]({{< relref "/kagent/0.x/concepts/agent-harness" >}}) for details.
-See the [API reference](/docs/kagent/resources/api-ref) for the full `AgentHarnessSubstrateSpec` schema.
+See the [API reference]({{< relref "/kagent/0.x/resources/api-ref" >}}) for the full `AgentHarnessSubstrateSpec` schema.
## Learn more
-- [Run a declarative agent on Agent Substrate](/docs/kagent/examples/agent-substrate) — end-to-end walkthrough on a kind cluster.
+- [Run a declarative agent on Agent Substrate]({{< relref "/kagent/0.x/examples/agent-substrate" >}}) — end-to-end walkthrough on a kind cluster.
- For a deeper dive into the runtime internals, see the [Agent Substrate documentation](https://learn.agentsubstrate.dev/).
diff --git a/docs-site/content/kagent/0.x/concepts/agents.md b/docs-site/content/kagent/0.x/concepts/agents.md
index 9cd432b2..f366ea08 100644
--- a/docs-site/content/kagent/0.x/concepts/agents.md
+++ b/docs-site/content/kagent/0.x/concepts/agents.md
@@ -24,7 +24,7 @@ Your responses should be clear and concise; you should provide helpful informati
Instructions are an important part of the agent's behavior. They define the agent's role and capabilities and help the agent understand its environment and the tasks it can perform.
-Writing good instructions is an art and a science. It requires a good understanding of the task at hand, the tools available, and the user's needs. In order to make it easier to write good instructions, we've created a [system prompt tutorial](/docs/kagent/getting-started/system-prompts) that can help you get started.
+Writing good instructions is an art and a science. It requires a good understanding of the task at hand, the tools available, and the user's needs. In order to make it easier to write good instructions, we've created a [system prompt tutorial]({{< relref "/kagent/0.x/getting-started/system-prompts" >}}) that can help you get started.
### Prompt templates
@@ -98,7 +98,7 @@ kagent comes with a set of built-in tools that you can use to interact with your
kagent supports Human-in-the-Loop (HITL) to keep humans in control of agent actions. You can require user approval before an agent executes sensitive tools, and agents can ask users questions when they need clarification.
-For a hands-on tutorial that walks through setting up HITL with tool approval and the `ask_user` tool, see the [Human-in-the-Loop example](/docs/kagent/examples/human-in-the-loop).
+For a hands-on tutorial that walks through setting up HITL with tool approval and the `ask_user` tool, see the [Human-in-the-Loop example]({{< relref "/kagent/0.x/examples/human-in-the-loop" >}}).
### Tool approval
@@ -226,7 +226,7 @@ When creating skills for your agents, consider the following best practices. Age
4. **Align with tools**: Ensure your skills align with the tools available to the agent. If you have a skill that centers around writing docs in markdown, you might want to align it with the `write-markdown` tool (as opposed to a `generate-pdf` tool).
5. **Keep skills focused**: Each skill should have a clear, focused purpose. For example, a document-generating skill might be too broad, but a skill that focuses on creating a specific type of document, such as a `.docx` file or alternatively a genre like a getting started guide, might be more appropriate.
-To learn more about using skills in your agents, see the [Skills example guide](/docs/kagent/examples/skills).
+To learn more about using skills in your agents, see the [Skills example guide]({{< relref "/kagent/0.x/examples/skills" >}}).
## Runtime
@@ -263,7 +263,7 @@ For more benchmarks and details, see the [Go vs Python runtime blog post](https:
Your agents can save and retrieve relevant context across conversations using vector similarity search. When you enable memory on an agent, it receives three additional tools (`save_memory`, `load_memory`, `prefetch_memory`) and automatically extracts key information every 5th user message.
-For configuration details, supported storage backends, API endpoints, and limitations, see [Agent Memory](/docs/kagent/concepts/agent-memory).
+For configuration details, supported storage backends, API endpoints, and limitations, see [Agent Memory]({{< relref "/kagent/0.x/concepts/agent-memory" >}}).
## Context Management
@@ -292,9 +292,9 @@ Compaction removes older conversation events to free up space in the context win
## Sandboxed Agents
-You can run a declarative agent in an isolated sandbox by creating a `SandboxAgent` resource instead of a regular `Agent`. A `SandboxAgent` runs on [Agent Substrate](/docs/kagent/concepts/agent-substrate): the kagent controller runs it as a gVisor-sandboxed actor instead of a Deployment, snapshotting it to object storage when idle and rehydrating it on demand. The spec mirrors the `Agent` spec, with a few constraints: sandboxed agents always use the Go ADK runtime, and `spec.skills` and `BYO` agents are not supported. Configure substrate placement with the optional `spec.substrate` field (for example, `workerPoolRef`).
+You can run a declarative agent in an isolated sandbox by creating a `SandboxAgent` resource instead of a regular `Agent`. A `SandboxAgent` runs on [Agent Substrate]({{< relref "/kagent/0.x/concepts/agent-substrate" >}}): the kagent controller runs it as a gVisor-sandboxed actor instead of a Deployment, snapshotting it to object storage when idle and rehydrating it on demand. The spec mirrors the `Agent` spec, with a few constraints: sandboxed agents always use the Go ADK runtime, and `spec.skills` and `BYO` agents are not supported. Configure substrate placement with the optional `spec.substrate` field (for example, `workerPoolRef`).
-For setup steps, see the [Agent Substrate example](/docs/kagent/examples/agent-substrate).
+For setup steps, see the [Agent Substrate example]({{< relref "/kagent/0.x/examples/agent-substrate" >}}).
## Agents as Tools
@@ -330,4 +330,4 @@ Here's how you could reference an existing agent (`promql-agent`) as a tool:
A2A-enabled agents are automatically exposed as an MCP server on the kagent controller. The MCP endpoint is available at `/mcp` on the same port as the A2A endpoint (default 8083).
-For more information, see the [MCP tools](/docs/kagent/examples/agents-mcp) guide.
+For more information, see the [MCP tools]({{< relref "/kagent/0.x/examples/agents-mcp" >}}) guide.
diff --git a/docs-site/content/kagent/0.x/concepts/architecture.md b/docs-site/content/kagent/0.x/concepts/architecture.md
index e6dd9deb..0f38b86b 100644
--- a/docs-site/content/kagent/0.x/concepts/architecture.md
+++ b/docs-site/content/kagent/0.x/concepts/architecture.md
@@ -24,7 +24,7 @@ The kagent engine is the core component of kagent. It runs the agent's conversat
- **Python ADK** (default) — Built on top of the [Google ADK](https://google.github.io/adk-docs/) framework. Supports Google ADK-native features and integrations with CrewAI, LangGraph, and OpenAI frameworks.
- **Go ADK** — A native Go implementation that provides faster startup (~2 seconds vs ~15 seconds) and lower resource consumption.
-Select the runtime by setting the `runtime` field in the agent spec (e.g., `runtime: go`). Both runtimes support MCP tools, HITL, and agent memory. For more details, see [Agents](/docs/kagent/concepts/agents#runtime).
+Select the runtime by setting the `runtime` field in the agent spec (e.g., `runtime: go`). Both runtimes support MCP tools, HITL, and agent memory. For more details, see [Agents]({{< relref "/kagent/0.x/concepts/agents#runtime" >}}).
For more information on the Google ADK framework:
@@ -63,5 +63,5 @@ kagent dashboard provides a web interface for managing and working with AI agent
## Next Steps
-- Try [building your own agent](/docs/kagent/getting-started/first-agent)
+- Try [building your own agent]({{< relref "/kagent/0.x/getting-started/first-agent" >}})
- Join our [Community](https://discord.gg/Fu3k65f2k3)
diff --git a/docs-site/content/kagent/0.x/concepts/mcp-apps.md b/docs-site/content/kagent/0.x/concepts/mcp-apps.md
index f0cb1f61..d1bf1044 100644
--- a/docs-site/content/kagent/0.x/concepts/mcp-apps.md
+++ b/docs-site/content/kagent/0.x/concepts/mcp-apps.md
@@ -60,4 +60,4 @@ A complete example, including a demo agent, is available in the kagent repositor
- [MCP Apps extension](https://github.com/modelcontextprotocol/ext-apps)
- [Model Context Protocol](https://modelcontextprotocol.io/)
-- [Tools in kagent](/docs/kagent/concepts/tools)
+- [Tools in kagent]({{< relref "/kagent/0.x/concepts/tools" >}})
diff --git a/docs-site/content/kagent/0.x/concepts/tools.md b/docs-site/content/kagent/0.x/concepts/tools.md
index c2bfdb73..6573a194 100644
--- a/docs-site/content/kagent/0.x/concepts/tools.md
+++ b/docs-site/content/kagent/0.x/concepts/tools.md
@@ -11,7 +11,7 @@ kagent comes with a set of built-in tools that you can use to interact with your
## Built-in Tools
-You can check out the full list of [built-in tools](https://kagent.dev/tools), or see the [Tools Ecosystem](/docs/kagent/resources/tools-ecosystem) reference for a detailed catalog of tools organized by MCP server.
+You can check out the full list of [built-in tools](https://kagent.dev/tools), or see the [Tools Ecosystem]({{< relref "/kagent/0.x/resources/tools-ecosystem" >}}) reference for a detailed catalog of tools organized by MCP server.
The built-in tools are meant as a good starting point for any agents running in kubernetes, however we don't envision them covering all possible use-cases, so we support multiple tool extension points to allow you to bring in your own tools.
@@ -78,7 +78,7 @@ MCP stands for [Model Context Protocol](https://modelcontextprotocol.io/introduc
### MCP Apps
-Some MCP tools ship an interactive UI with their results. kagent detects these tools automatically and renders their widgets inline in the chat, and the dashboard lists them alongside a server's regular tools so you can test them directly. See [MCP Apps](/docs/kagent/concepts/mcp-apps) for details.
+Some MCP tools ship an interactive UI with their results. kagent detects these tools automatically and renders their widgets inline in the chat, and the dashboard lists them alongside a server's regular tools so you can test them directly. See [MCP Apps]({{< relref "/kagent/0.x/concepts/mcp-apps" >}}) for details.
## HTTP Tools
diff --git a/docs-site/content/kagent/0.x/examples/a2a-agents.md b/docs-site/content/kagent/0.x/examples/a2a-agents.md
index 08fb2670..272cd49f 100644
--- a/docs-site/content/kagent/0.x/examples/a2a-agents.md
+++ b/docs-site/content/kagent/0.x/examples/a2a-agents.md
@@ -12,7 +12,7 @@ Let's look at how this works in kagent!
## Prerequisites
-Install kagent by following the [quick start](/docs/kagent/getting-started/quickstart) guide.
+Install kagent by following the [quick start]({{< relref "/kagent/0.x/getting-started/quickstart" >}}) guide.
## Creating an AI agent that supports A2A
@@ -135,7 +135,7 @@ You can invoke the agent in several ways, including the kagent dashboard, kagent
### Dashboard
-Launch the dashboard with `kagent dashboard`, find your `k8s-a2a-agent`, and start chatting. For complete steps, see the [Your First Agent](/docs/kagent/getting-started/first-agent) guide.
+Launch the dashboard with `kagent dashboard`, find your `k8s-a2a-agent`, and start chatting. For complete steps, see the [Your First Agent]({{< relref "/kagent/0.x/getting-started/first-agent" >}}) guide.
### kagent CLI
diff --git a/docs-site/content/kagent/0.x/examples/a2a-byo.md b/docs-site/content/kagent/0.x/examples/a2a-byo.md
index 532a9892..2000a7f3 100644
--- a/docs-site/content/kagent/0.x/examples/a2a-byo.md
+++ b/docs-site/content/kagent/0.x/examples/a2a-byo.md
@@ -6,13 +6,13 @@ weight: 1
author: kagent.dev
---
-Bring your own custom agents. This example uses the [Agent Development Kit (ADK)](https://google.github.io/adk-docs/), but you can also try out the [LangGraph guide](/docs/kagent/examples/langchain-byo/). Such frameworks give you more control over the agent behavior and are well-suited for complex workflows and integration with external systems and APIs.
+Bring your own custom agents. This example uses the [Agent Development Kit (ADK)](https://google.github.io/adk-docs/), but you can also try out the [LangGraph guide]({{< relref "/kagent/0.x/examples/langchain-byo/" >}}). Such frameworks give you more control over the agent behavior and are well-suited for complex workflows and integration with external systems and APIs.
Unlike declarative agents that are defined by kagent resources with components such as system instructions, models, and tools written inline, these BYO agents give you full control over agent logic. If you have your own agent, no need to decompose its functions into separate kagent resources. kagent can invoke your agent directly through the A2A protocol.
## Prerequisites
-1. Install kagent by following the [quick start](/docs/kagent/getting-started/quickstart) guide.
+1. Install kagent by following the [quick start]({{< relref "/kagent/0.x/getting-started/quickstart" >}}) guide.
2. Use [Google ADK](https://github.com/google/adk-python) version 1.22.1 or later.
## Building a custom agent
@@ -162,7 +162,7 @@ You can invoke the agent in several ways, including the kagent dashboard, kagent
### Dashboard
-Launch the dashboard with `kagent dashboard`, find your `basic-agent`, and start chatting. For complete steps, see the [Your First Agent](/docs/kagent/getting-started/first-agent) guide.
+Launch the dashboard with `kagent dashboard`, find your `basic-agent`, and start chatting. For complete steps, see the [Your First Agent]({{< relref "/kagent/0.x/getting-started/first-agent" >}}) guide.

diff --git a/docs-site/content/kagent/0.x/examples/agent-harness.md b/docs-site/content/kagent/0.x/examples/agent-harness.md
index 7272b3fe..4be4b4f1 100644
--- a/docs-site/content/kagent/0.x/examples/agent-harness.md
+++ b/docs-site/content/kagent/0.x/examples/agent-harness.md
@@ -5,14 +5,14 @@ weight: 8
author: kagent.dev
---
-`AgentHarness` creates a long-running remote execution environment on [Agent Substrate](/docs/kagent/concepts/agent-substrate). Unlike an `Agent` or `SandboxAgent`, it does not package a kagent runtime into the workload. The backend provisions a sandbox that runs a coding agent (OpenClaw or Hermes), which you can chat with from the kagent UI and wire into messaging channels.
+`AgentHarness` creates a long-running remote execution environment on [Agent Substrate]({{< relref "/kagent/0.x/concepts/agent-substrate" >}}). Unlike an `Agent` or `SandboxAgent`, it does not package a kagent runtime into the workload. The backend provisions a sandbox that runs a coding agent (OpenClaw or Hermes), which you can chat with from the kagent UI and wire into messaging channels.
Use `AgentHarness` when you want kagent to manage the lifecycle of an OpenClaw or Hermes sandbox and surface it in the kagent API/UI alongside regular agents.
## Before you begin
-1. Install kagent v0.9.9 or later by following the [quick start](/docs/kagent/getting-started/quickstart) guide.
-2. Install Agent Substrate and enable the substrate integration in kagent. For Helm-based setup instructions, see [Enable AgentHarness support](/docs/kagent/introduction/installation#enable-agentharness-support) and the [Agent Substrate example](/docs/kagent/examples/agent-substrate).
+1. Install kagent v0.9.9 or later by following the [quick start]({{< relref "/kagent/0.x/getting-started/quickstart" >}}) guide.
+2. Install Agent Substrate and enable the substrate integration in kagent. For Helm-based setup instructions, see [Enable AgentHarness support]({{< relref "/kagent/0.x/introduction/installation#enable-agentharness-support" >}}) and the [Agent Substrate example]({{< relref "/kagent/0.x/examples/agent-substrate" >}}).
When the substrate integration is not enabled, the controller cannot provision AgentHarness resources.
@@ -204,7 +204,7 @@ Once the harness is `Ready`, it appears in the kagent UI alongside your other ag
2. Open [http://localhost:8001](http://localhost:8001), select your harness (for example `kagent/openclaw-shell`) from the Agents list, and send a message.
-The first chat connection creates a shared Substrate actor from the harness template; every chat is multiplexed as an ACP session inside that actor. You see streamed tool activity, and any tool-approval prompts the backend raises are surfaced through kagent's [human-in-the-loop](/docs/kagent/examples/human-in-the-loop) flow.
+The first chat connection creates a shared Substrate actor from the harness template; every chat is multiplexed as an ACP session inside that actor. You see streamed tool activity, and any tool-approval prompts the backend raises are surfaced through kagent's [human-in-the-loop]({{< relref "/kagent/0.x/examples/human-in-the-loop" >}}) flow.
## Troubleshooting
@@ -217,4 +217,4 @@ If the harness is not accepted or ready, check these common causes.
- A Slack channel has the wrong backend settings, such as `slack.hermes` on an OpenClaw harness or `slack.openclaw` on a Hermes harness.
- A Slack credential uses neither `value` nor `valueFrom`, or sets both.
-For the complete generated schema, see the [API reference](/docs/kagent/resources/api-ref#agentharness).
+For the complete generated schema, see the [API reference]({{< relref "/kagent/0.x/resources/api-ref#agentharness" >}}).
diff --git a/docs-site/content/kagent/0.x/examples/agent-substrate.md b/docs-site/content/kagent/0.x/examples/agent-substrate.md
index 312048d2..53af1c5f 100644
--- a/docs-site/content/kagent/0.x/examples/agent-substrate.md
+++ b/docs-site/content/kagent/0.x/examples/agent-substrate.md
@@ -13,7 +13,7 @@ By the end, you will have:
- kagent v0.9.7 or later installed with the substrate integration enabled. Earlier kagent releases do not include the controller wiring that lets a `SandboxAgent` target substrate.
- A `SandboxAgent` running on substrate, reachable from the kagent UI.
-For background on what substrate is and how it differs from a per-pod agent runtime, see the [Agent Substrate concept page](/docs/kagent/concepts/agent-substrate). This guide does not cover the `AgentHarness` path on substrate.
+For background on what substrate is and how it differs from a per-pod agent runtime, see the [Agent Substrate concept page]({{< relref "/kagent/0.x/concepts/agent-substrate" >}}). This guide does not cover the `AgentHarness` path on substrate.
## Before you begin
@@ -213,5 +213,5 @@ kind delete cluster --name kagent-substrate
## Next steps
-- [Agent Substrate concept page](/docs/kagent/concepts/agent-substrate) — runtime architecture and how snapshots, actors, and worker pools fit together.
-- [AgentHarness](/docs/kagent/examples/agent-harness) — provision long-running OpenClaw and Hermes coding-agent sandboxes on Agent Substrate and chat with them over ACP.
+- [Agent Substrate concept page]({{< relref "/kagent/0.x/concepts/agent-substrate" >}}) — runtime architecture and how snapshots, actors, and worker pools fit together.
+- [AgentHarness]({{< relref "/kagent/0.x/examples/agent-harness" >}}) — provision long-running OpenClaw and Hermes coding-agent sandboxes on Agent Substrate and chat with them over ACP.
diff --git a/docs-site/content/kagent/0.x/examples/agentgateway.md b/docs-site/content/kagent/0.x/examples/agentgateway.md
index 010a4554..196be566 100644
--- a/docs-site/content/kagent/0.x/examples/agentgateway.md
+++ b/docs-site/content/kagent/0.x/examples/agentgateway.md
@@ -10,7 +10,7 @@ As your kagent deployment grows, you might need governance over how your agents
## Prerequisites
-1. A running kagent installation. If you haven't installed kagent yet, follow the [quick start](/docs/kagent/getting-started/quickstart) guide first.
+1. A running kagent installation. If you haven't installed kagent yet, follow the [quick start]({{< relref "/kagent/0.x/getting-started/quickstart" >}}) guide first.
2. Follow the [agentgateway installation guide](https://agentgateway.dev/docs/kubernetes/latest/quickstart/install/) to install agentgateway in your cluster.
3. Set up an LLM provider with agentgateway. This guide uses [the Ollama setup](https://agentgateway.dev/docs/kubernetes/latest/llm/providers/ollama/) as an example.
@@ -86,7 +86,7 @@ With agentgateway installed, point kagent at the agentgateway proxy instead of d
{{< /tab >}}
{{< /tabs >}}
-4. [Open the kagent UI](/docs/kagent/observability/launch-ui).
+4. [Open the kagent UI]({{< relref "/kagent/0.x/observability/launch-ui" >}}).
5. Start a chat with an agent such as `k8s-agent` to confirm that requests flow through agentgateway.

diff --git a/docs-site/content/kagent/0.x/examples/crewai-byo.md b/docs-site/content/kagent/0.x/examples/crewai-byo.md
index 322ba174..a0f763b9 100644
--- a/docs-site/content/kagent/0.x/examples/crewai-byo.md
+++ b/docs-site/content/kagent/0.x/examples/crewai-byo.md
@@ -6,13 +6,13 @@ weight: 1
author: kagent.dev
---
-Bring your own custom agents. This example uses [CrewAI](https://www.crewai.com/), but you can also try out the [ADK guide](/docs/kagent/examples/a2a-byo/) or [LangGraph guide](/docs/kagent/examples/langchain-byo/). Such frameworks give you more control over the agent behavior and are well-suited for complex workflows and integration with external systems and APIs.
+Bring your own custom agents. This example uses [CrewAI](https://www.crewai.com/), but you can also try out the [ADK guide]({{< relref "/kagent/0.x/examples/a2a-byo/" >}}) or [LangGraph guide]({{< relref "/kagent/0.x/examples/langchain-byo/" >}}). Such frameworks give you more control over the agent behavior and are well-suited for complex workflows and integration with external systems and APIs.
Unlike declarative agents that are defined by kagent resources with components such as system instructions, models, and tools written inline, these BYO agents give you full control over agent logic. If you have your own agent, no need to decompose its functions into separate kagent resources. kagent can invoke your agent directly through the A2A protocol.
## Prerequisites
-Install kagent by following the [quick start](/docs/kagent/getting-started/quickstart) guide.
+Install kagent by following the [quick start]({{< relref "/kagent/0.x/getting-started/quickstart" >}}) guide.
## Building a custom agent
@@ -148,7 +148,7 @@ You can invoke the agent in several ways, including the kagent dashboard, kagent
### Dashboard
-Launch the dashboard with `kagent dashboard`, find your `research-crew`, and start chatting. For complete steps, see the [Your First Agent](/docs/kagent/getting-started/first-agent) guide.
+Launch the dashboard with `kagent dashboard`, find your `research-crew`, and start chatting. For complete steps, see the [Your First Agent]({{< relref "/kagent/0.x/getting-started/first-agent" >}}) guide.
### kagent CLI
diff --git a/docs-site/content/kagent/0.x/examples/discord-a2a.md b/docs-site/content/kagent/0.x/examples/discord-a2a.md
index 283c44ff..7ef4e775 100644
--- a/docs-site/content/kagent/0.x/examples/discord-a2a.md
+++ b/docs-site/content/kagent/0.x/examples/discord-a2a.md
@@ -8,7 +8,7 @@ author: kagent.dev
};
-kagent enables you to create AI agents that run inside your Kubernetes cluster. They can access a variety of [built-in tools](/docs/kagent/concepts/tools) and use other [external tools via MCP](/docs/kagent/examples/documentation).
+kagent enables you to create AI agents that run inside your Kubernetes cluster. They can access a variety of [built-in tools]({{< relref "/kagent/0.x/concepts/tools" >}}) and use other [external tools via MCP]({{< relref "/kagent/0.x/examples/documentation" >}}).
This guide shows how to connect a Discord bot to one of your agents using the A2A protocol, enabling natural conversations and command execution inside Discord.
@@ -129,7 +129,7 @@ When a message is received, it’s sent to the A2A endpoint (`KAGENT_A2A_URL`),
## Agent Setup
-If you haven’t deployed your agent yet, follow the instructions in [Deploying an Agent](/docs/kagent/examples/slack-a2a#deploying-an-agent). You can reuse the same agent across Slack and Discord integrations.
+If you haven’t deployed your agent yet, follow the instructions in [Deploying an Agent]({{< relref "/kagent/0.x/examples/slack-a2a#deploying-an-agent" >}}). You can reuse the same agent across Slack and Discord integrations.
Be sure to port-forward your agent if running locally:
diff --git a/docs-site/content/kagent/0.x/examples/langchain-byo.md b/docs-site/content/kagent/0.x/examples/langchain-byo.md
index 10d33c0e..b5a8ea39 100644
--- a/docs-site/content/kagent/0.x/examples/langchain-byo.md
+++ b/docs-site/content/kagent/0.x/examples/langchain-byo.md
@@ -10,7 +10,7 @@ You can bring your own LangGraph agent to kagent by configuring the kagentCheckp
## Prerequisites
-Install kagent by following the [quick start](/docs/kagent/getting-started/quickstart) guide.
+Install kagent by following the [quick start]({{< relref "/kagent/0.x/getting-started/quickstart" >}}) guide.
## Building a LangGraph agent
@@ -125,7 +125,7 @@ You can invoke the agent through the kagent dashboard or kagent CLI.
### Dashboard
-Launch the dashboard with `kagent dashboard`, find your `langgraph-agent`, and start chatting. For complete steps, see the [Your First Agent](/docs/kagent/getting-started/first-agent) guide.
+Launch the dashboard with `kagent dashboard`, find your `langgraph-agent`, and start chatting. For complete steps, see the [Your First Agent]({{< relref "/kagent/0.x/getting-started/first-agent" >}}) guide.

diff --git a/docs-site/content/kagent/0.x/examples/skills.md b/docs-site/content/kagent/0.x/examples/skills.md
index fd66647f..5fcab664 100644
--- a/docs-site/content/kagent/0.x/examples/skills.md
+++ b/docs-site/content/kagent/0.x/examples/skills.md
@@ -15,9 +15,9 @@ In this guide, you learn how to add container-based skills to your agents in kag
## Before you begin
-1. Install kagent by following the [quick start](/docs/kagent/getting-started/quickstart) guide.
+1. Install kagent by following the [quick start]({{< relref "/kagent/0.x/getting-started/quickstart" >}}) guide.
-2. Review the concepts of [agents and skills](/docs/kagent/concepts/agents) in kagent.
+2. Review the concepts of [agents and skills]({{< relref "/kagent/0.x/concepts/agents" >}}) in kagent.
## Container-based skills
@@ -372,6 +372,6 @@ When you're done, you can clean up the resources that you created.
## Next steps
-- Learn more about [agents](/docs/kagent/concepts/agents) and their components
-- Explore [tools](/docs/kagent/concepts/tools) available in kagent
-- Check out other [examples](/docs/kagent/examples) to see different agent configurations
+- Learn more about [agents]({{< relref "/kagent/0.x/concepts/agents" >}}) and their components
+- Explore [tools]({{< relref "/kagent/0.x/concepts/tools" >}}) available in kagent
+- Check out other [examples]({{< relref "/kagent/0.x/examples" >}}) to see different agent configurations
diff --git a/docs-site/content/kagent/0.x/examples/slack-a2a.md b/docs-site/content/kagent/0.x/examples/slack-a2a.md
index 01ed5c7e..22e63fc9 100644
--- a/docs-site/content/kagent/0.x/examples/slack-a2a.md
+++ b/docs-site/content/kagent/0.x/examples/slack-a2a.md
@@ -8,7 +8,7 @@ author: kagent.dev
};
-kagent enables you to create AI agents that run inside your Kubernetes cluster. They have access to a variety of [built-in tools](/docs/kagent/concepts/tools) like Kubernetes, Istio, Grafana, Prometheus, Argo and can be extended with any other tools [using MCP](/docs/kagent/examples/documentation).
+kagent enables you to create AI agents that run inside your Kubernetes cluster. They have access to a variety of [built-in tools]({{< relref "/kagent/0.x/concepts/tools" >}}) like Kubernetes, Istio, Grafana, Prometheus, Argo and can be extended with any other tools [using MCP]({{< relref "/kagent/0.x/examples/documentation" >}}).

diff --git a/docs-site/content/kagent/0.x/examples/telegram-bot.md b/docs-site/content/kagent/0.x/examples/telegram-bot.md
index dd3ecf81..bb3af6c3 100644
--- a/docs-site/content/kagent/0.x/examples/telegram-bot.md
+++ b/docs-site/content/kagent/0.x/examples/telegram-bot.md
@@ -98,7 +98,7 @@ spec:
EOF
```
-Notice `requireApproval` — anything destructive (deleting resources, applying manifests, Helm upgrades) goes through [Human-in-the-Loop](/docs/kagent/examples/human-in-the-loop) approval in the kagent UI first. Nobody's accidentally nuking prod from a Telegram chat.
+Notice `requireApproval` — anything destructive (deleting resources, applying manifests, Helm upgrades) goes through [Human-in-the-Loop]({{< relref "/kagent/0.x/examples/human-in-the-loop" >}}) approval in the kagent UI first. Nobody's accidentally nuking prod from a Telegram chat.
Verify it's working:
diff --git a/docs-site/content/kagent/0.x/getting-started/first-agent.md b/docs-site/content/kagent/0.x/getting-started/first-agent.md
index 8083bfba..3e2f4a10 100644
--- a/docs-site/content/kagent/0.x/getting-started/first-agent.md
+++ b/docs-site/content/kagent/0.x/getting-started/first-agent.md
@@ -10,7 +10,7 @@ In this guide, you'll learn how to create your first AI agent using the kagent d
## Prerequisites
-Before you begin make sure you have a Kubernetes cluster with kagent installed. If you haven't done this yet, check out the [installation guide](/docs/kagent/introduction/installation) or the [quickstart guide](/docs/kagent/getting-started/quickstart).
+Before you begin make sure you have a Kubernetes cluster with kagent installed. If you haven't done this yet, check out the [installation guide]({{< relref "/kagent/0.x/introduction/installation" >}}) or the [quickstart guide]({{< relref "/kagent/0.x/getting-started/quickstart" >}}).
We'll be working in the kagent dashboard, so use the kagent CLI to open the dashboard:
@@ -90,5 +90,5 @@ Now that you set up all the details for your agent, you're ready to finish creat
## Next Steps
-- Learn more about [Core Concepts](/docs/kagent/concepts)
+- Learn more about [Core Concepts]({{< relref "/kagent/0.x/concepts" >}})
- Join our [Community](https://discord.gg/Fu3k65f2k3)
diff --git a/docs-site/content/kagent/0.x/getting-started/first-mcp-tool.md b/docs-site/content/kagent/0.x/getting-started/first-mcp-tool.md
index 40e4c890..7781acd1 100644
--- a/docs-site/content/kagent/0.x/getting-started/first-mcp-tool.md
+++ b/docs-site/content/kagent/0.x/getting-started/first-mcp-tool.md
@@ -12,7 +12,7 @@ In this guide, you'll learn how to add an MCP tool to your first AI agent using
## Prerequisites
-1. Install kagent in a Kubernetes cluster. If you haven't done this yet, check out the [installation guide](/docs/kagent/introduction/installation) or the [quickstart guide](/docs/kagent/getting-started/quickstart).
+1. Install kagent in a Kubernetes cluster. If you haven't done this yet, check out the [installation guide]({{< relref "/kagent/0.x/introduction/installation" >}}) or the [quickstart guide]({{< relref "/kagent/0.x/getting-started/quickstart" >}}).
2. Make sure that you have the kagent custom resources in your cluster.
@@ -22,7 +22,7 @@ In this guide, you'll learn how to add an MCP tool to your first AI agent using
## Creating an agent
-To create an agent, follow the [Your First Agent guide](/docs/kagent/getting-started/first-agent).
+To create an agent, follow the [Your First Agent guide]({{< relref "/kagent/0.x/getting-started/first-agent" >}}).
Take a look at the Agent custom resource for your first agent, such as with the following command.
@@ -177,5 +177,5 @@ Now let's try our agent out with the fetch tool.
## Next Steps
-- Learn more about [Core Concepts](/docs/kagent/concepts)
+- Learn more about [Core Concepts]({{< relref "/kagent/0.x/concepts" >}})
- Join our [Community](https://discord.gg/Fu3k65f2k3)
diff --git a/docs-site/content/kagent/0.x/getting-started/local-development.md b/docs-site/content/kagent/0.x/getting-started/local-development.md
index 04a300f4..da2ec1b8 100644
--- a/docs-site/content/kagent/0.x/getting-started/local-development.md
+++ b/docs-site/content/kagent/0.x/getting-started/local-development.md
@@ -6,13 +6,13 @@ weight: 4
author: kagent.dev
---
-In this guide, you'll learn how to develop, build and run an AI agent locally using kagent CLI, without a Kubernetes cluster. This guide is meant for developers familiar with Python. You can also create declarative agents without writing a single line of code, by following the [Your First Agent](/docs/kagent/getting-started/first-agent) guide.
+In this guide, you'll learn how to develop, build and run an AI agent locally using kagent CLI, without a Kubernetes cluster. This guide is meant for developers familiar with Python. You can also create declarative agents without writing a single line of code, by following the [Your First Agent]({{< relref "/kagent/0.x/getting-started/first-agent" >}}) guide.
## Prerequisites
Before you begin make sure you have the following prerequisites installed:
-- [kagent CLI](/docs/kagent/introduction/installation)
+- [kagent CLI]({{< relref "/kagent/0.x/introduction/installation" >}})
- [Python](https://www.python.org/)
- [Docker](https://www.docker.com/) and [Docker compose](https://docs.docker.com/compose/)
diff --git a/docs-site/content/kagent/0.x/getting-started/quickstart.md b/docs-site/content/kagent/0.x/getting-started/quickstart.md
index de8cc6c0..cd91017f 100644
--- a/docs-site/content/kagent/0.x/getting-started/quickstart.md
+++ b/docs-site/content/kagent/0.x/getting-started/quickstart.md
@@ -141,12 +141,12 @@ Interact with kagent in your terminal.
## Next Steps
-- Create your [first agent](/docs/kagent/getting-started/first-agent)
-- Learn about [Core Concepts](/docs/kagent/concepts)
+- Create your [first agent]({{< relref "/kagent/0.x/getting-started/first-agent" >}})
+- Learn about [Core Concepts]({{< relref "/kagent/0.x/concepts" >}})
- Join our [Community](https://discord.gg/Fu3k65f2k3)
## Need Help?
- Visit our [GitHub repository](https://github.com/kagent-dev/kagent)
- Ask a question on [Discord](https://discord.gg/Fu3k65f2k3)
-- Check out the [FAQ](/docs/kagent/resources/faq)
\ No newline at end of file
+- Check out the [FAQ]({{< relref "/kagent/0.x/resources/faq" >}})
\ No newline at end of file
diff --git a/docs-site/content/kagent/0.x/introduction/_index.md b/docs-site/content/kagent/0.x/introduction/_index.md
index 15a86baf..1f86319e 100644
--- a/docs-site/content/kagent/0.x/introduction/_index.md
+++ b/docs-site/content/kagent/0.x/introduction/_index.md
@@ -5,4 +5,4 @@ weight: 1
author: kagent.dev
---
-Welcome to kagent! Start here to understand what kagent is and how to install it. To follow the roadmap or help improve kagent, see [Community and Contributing](/docs/kagent/resources/community).
+Welcome to kagent! Start here to understand what kagent is and how to install it. To follow the roadmap or help improve kagent, see [Community and Contributing]({{< relref "/kagent/0.x/resources/community" >}}).
diff --git a/docs-site/content/kagent/0.x/introduction/installation.md b/docs-site/content/kagent/0.x/introduction/installation.md
index 2e9b7609..7aa93038 100644
--- a/docs-site/content/kagent/0.x/introduction/installation.md
+++ b/docs-site/content/kagent/0.x/introduction/installation.md
@@ -5,13 +5,13 @@ weight: 1
author: kagent.dev
---
-This guide covers ways to install and configure kagent in your Kubernetes environment. For a quick setup, check out our [Quick Start Guide](/docs/kagent/getting-started/quickstart). For enterpise offerings, check out [Solo Enterprise for kagent](/docs/kagent/introduction/what-is-kagent/#enterprise-distributions).
+This guide covers ways to install and configure kagent in your Kubernetes environment. For a quick setup, check out our [Quick Start Guide]({{< relref "/kagent/0.x/getting-started/quickstart" >}}). For enterpise offerings, check out [Solo Enterprise for kagent]({{< relref "/kagent/0.x/introduction/what-is-kagent/#enterprise-distributions" >}}).
## Installation Methods
Install kagent by using the kagent CLI or Helm.
-> **Note**: As of [version 0.7](/docs/kagent/resources/release-notes#kmcp-installed-by-default), the kmcp subproject is included by default with kagent. To use an existing kmcp installation that you already set up separately, set `kmcp.enabled=false` in your `values.yaml` file or `--set` commands for both the `kagent` and `kagent-crds` charts.
+> **Note**: As of [version 0.7]({{< relref "/kagent/0.x/resources/release-notes#kmcp-installed-by-default" >}}), the kmcp subproject is included by default with kagent. To use an existing kmcp installation that you already set up separately, set `kmcp.enabled=false` in your `values.yaml` file or `--set` commands for both the `kagent` and `kagent-crds` charts.
### Using kagent CLI (Recommended)
@@ -66,7 +66,7 @@ Another way to install kagent is using Helm.
--create-namespace
```
-2. Optionally prepare a Helm values file or `--set` flags to use for your installation. For example, you might set up your default LLM provider, or configure resource requests and limits or disable the default agents. For options, refer to the [Helm reference docs](/docs/kagent/resources/helm).
+2. Optionally prepare a Helm values file or `--set` flags to use for your installation. For example, you might set up your default LLM provider, or configure resource requests and limits or disable the default agents. For options, refer to the [Helm reference docs]({{< relref "/kagent/0.x/resources/helm" >}}).
{{< tabs >}}
{{< tab name="OpenAI" >}}
@@ -185,7 +185,7 @@ Review the following advanced configuration options that you might want to set u
### Enable AgentHarness support
-`AgentHarness` resources run on [Agent Substrate](/docs/kagent/concepts/agent-substrate). To enable them, install Agent Substrate and turn on the substrate integration in kagent. When the integration is disabled, the controller cannot provision AgentHarness resources.
+`AgentHarness` resources run on [Agent Substrate]({{< relref "/kagent/0.x/concepts/agent-substrate" >}}). To enable them, install Agent Substrate and turn on the substrate integration in kagent. When the integration is disabled, the controller cannot provision AgentHarness resources.
1. Install Agent Substrate (CRDs, then the control plane and data plane).
@@ -228,11 +228,11 @@ Review the following advanced configuration options that you might want to set u
Pin the kagent chart to v0.9.9 or later — earlier versions do not include the `controller.substrate.*` and `substrateWorkerPool.*` values.
-For an end-to-end walkthrough on a kind cluster, see the [Agent Substrate example](/docs/kagent/examples/agent-substrate). For more information about creating harness resources, see [Agent Harness](/docs/kagent/examples/agent-harness).
+For an end-to-end walkthrough on a kind cluster, see the [Agent Substrate example]({{< relref "/kagent/0.x/examples/agent-substrate" >}}). For more information about creating harness resources, see [Agent Harness]({{< relref "/kagent/0.x/examples/agent-harness" >}}).
### Database configuration
-For production environments, set up kagent with an external PostgreSQL instance. For more information, see the [Database configuration guide](/docs/kagent/operations/operational-considerations/#database-configuration).
+For production environments, set up kagent with an external PostgreSQL instance. For more information, see the [Database configuration guide]({{< relref "/kagent/0.x/operations/operational-considerations/#database-configuration" >}}).
### Configure controller environment variables
@@ -303,9 +303,9 @@ This example loads all key-value pairs from the `controller-secrets` secret as e
## Uninstallation
-Refer to the [Uninstall](/docs/kagent/operations/uninstall) guide.
+Refer to the [Uninstall]({{< relref "/kagent/0.x/operations/uninstall" >}}) guide.
## Next Steps
-- [Create your first agent](/docs/kagent/getting-started/first-agent)
+- [Create your first agent]({{< relref "/kagent/0.x/getting-started/first-agent" >}})
- [Explore available agents](https://kagent.dev/agents)
diff --git a/docs-site/content/kagent/0.x/introduction/what-is-kagent.md b/docs-site/content/kagent/0.x/introduction/what-is-kagent.md
index c17818c7..c61b9728 100644
--- a/docs-site/content/kagent/0.x/introduction/what-is-kagent.md
+++ b/docs-site/content/kagent/0.x/introduction/what-is-kagent.md
@@ -62,7 +62,7 @@ Check out [Solo Enterprise for kagent](https://www.solo.io/products/kagent-enter
## Getting Started
-To start using kagent in your environment, check out the [Quick Start Guide](/docs/kagent/getting-started/quickstart) guide. For a deeper understanding of how kagent works, refer to the [kagent architecture](/docs/kagent/concepts/architecture).
+To start using kagent in your environment, check out the [Quick Start Guide]({{< relref "/kagent/0.x/getting-started/quickstart" >}}) guide. For a deeper understanding of how kagent works, refer to the [kagent architecture]({{< relref "/kagent/0.x/concepts/architecture" >}}).
Ready to contribute? Visit our [Github repository](https://github.com/kagent-dev) to learn how you can help expand the ecosystem of cloud-native AI agents.
@@ -71,5 +71,5 @@ Ready to contribute? Visit our [Github repository](https://github.com/kagent-dev
Join the kagent community:
- Explore our repositories on [GitHub](https://github.com/kagent-dev)
- Join the discussion in the #kagent channel on CNCF Slack
-- Check our [FAQ](/docs/kagent/resources/faq) for common questions
+- Check our [FAQ]({{< relref "/kagent/0.x/resources/faq" >}}) for common questions
- Follow our [Feature Roadmap](https://github.com/kagent-dev/kagent/blob/main/README.md#roadmap) for upcoming developments
diff --git a/docs-site/content/kagent/0.x/observability/audit-prompts.md b/docs-site/content/kagent/0.x/observability/audit-prompts.md
index c4301fc3..73cdd9a8 100644
--- a/docs-site/content/kagent/0.x/observability/audit-prompts.md
+++ b/docs-site/content/kagent/0.x/observability/audit-prompts.md
@@ -20,7 +20,7 @@ kagent supports logging input/output messages for the following LLM providers:
## Before you begin
-1. [Install kagent](/docs/kagent/introduction/installation) in your cluster.
+1. [Install kagent]({{< relref "/kagent/0.x/introduction/installation" >}}) in your cluster.
2. Add the OpenTelemetry Helm repository.
diff --git a/docs-site/content/kagent/0.x/observability/launch-ui.md b/docs-site/content/kagent/0.x/observability/launch-ui.md
index 66308306..edc687da 100644
--- a/docs-site/content/kagent/0.x/observability/launch-ui.md
+++ b/docs-site/content/kagent/0.x/observability/launch-ui.md
@@ -51,6 +51,6 @@ If you prefer to manually set up port-forwarding, or if you're on a platform whe
You can use the UI to view and manage your agents, tools, and models. For more information, see the following guides:
-- [Create your first agent](/docs/kagent/getting-started/first-agent)
-- [Add MCP tools to your agents](/docs/kagent/getting-started/first-mcp-tool)
-- [Configure LLM providers](/docs/kagent/supported-providers)
+- [Create your first agent]({{< relref "/kagent/0.x/getting-started/first-agent" >}})
+- [Add MCP tools to your agents]({{< relref "/kagent/0.x/getting-started/first-mcp-tool" >}})
+- [Configure LLM providers]({{< relref "/kagent/0.x/supported-providers" >}})
diff --git a/docs-site/content/kagent/0.x/observability/tracing.md b/docs-site/content/kagent/0.x/observability/tracing.md
index 3792cec5..00886605 100644
--- a/docs-site/content/kagent/0.x/observability/tracing.md
+++ b/docs-site/content/kagent/0.x/observability/tracing.md
@@ -9,7 +9,7 @@ Set up tracing for your kagent agents.
## Before you begin
-[Install kagent](/docs/kagent/introduction/installation).
+[Install kagent]({{< relref "/kagent/0.x/introduction/installation" >}}).
## Install Jaeger
@@ -82,7 +82,7 @@ Now that you installed kagent with Jaeger, learn how to trace requests to an age
### Generate tracing data
-To generate tracing data, you can chat with a pre-configured agent such as `k8s-agent`. For more information about agents, see the [Your First Agent](/docs/kagent/getting-started/first-agent) guide.
+To generate tracing data, you can chat with a pre-configured agent such as `k8s-agent`. For more information about agents, see the [Your First Agent]({{< relref "/kagent/0.x/getting-started/first-agent" >}}) guide.
1. Launch the kagent dashboard.
@@ -135,11 +135,11 @@ That's it! You've now traced your first agent.
## Next Steps
-- Learn about [Core Concepts](/docs/kagent/concepts)
-- Try out some [Example](/docs/kagent/examples) guides
+- Learn about [Core Concepts]({{< relref "/kagent/0.x/concepts" >}})
+- Try out some [Example]({{< relref "/kagent/0.x/examples" >}}) guides
## Need Help?
- Visit our [GitHub repository](https://github.com/kagent-dev/kagent)
- Ask a question on [Discord](https://discord.gg/Fu3k65f2k3)
-- Check out the [FAQ](/docs/kagent/resources/faq)
\ No newline at end of file
+- Check out the [FAQ]({{< relref "/kagent/0.x/resources/faq" >}})
\ No newline at end of file
diff --git a/docs-site/content/kagent/0.x/operations/operational-considerations.md b/docs-site/content/kagent/0.x/operations/operational-considerations.md
index 9e2cd8b5..d768ff64 100644
--- a/docs-site/content/kagent/0.x/operations/operational-considerations.md
+++ b/docs-site/content/kagent/0.x/operations/operational-considerations.md
@@ -89,7 +89,7 @@ urlFile > url > bundled connection string
The bundled PostgreSQL instance is deployed by default (`database.postgres.bundled.enabled: true`). The database name, username, and password are all hardcoded to `kagent`. Credentials are stored in a Kubernetes Secret.
-You can customize the storage size and image of the bundled instance when you [install](/docs/kagent/introduction/installation) or upgrade kagent.
+You can customize the storage size and image of the bundled instance when you [install]({{< relref "/kagent/0.x/introduction/installation" >}}) or upgrade kagent.
1. Add the bundled database settings to your Helm values file for kagent.
diff --git a/docs-site/content/kagent/0.x/operations/uninstall.md b/docs-site/content/kagent/0.x/operations/uninstall.md
index cca768ac..a66074fa 100644
--- a/docs-site/content/kagent/0.x/operations/uninstall.md
+++ b/docs-site/content/kagent/0.x/operations/uninstall.md
@@ -17,7 +17,7 @@ Remove kagent from your Kubernetes cluster using the kagent CLI or Helm.
## Uninstall with the kagent CLI
-Remove kagent by using the CLI. For more options, see the [`kagent uninstall` command reference](/docs/kagent/resources/cli/kagent-uninstall).
+Remove kagent by using the CLI. For more options, see the [`kagent uninstall` command reference]({{< relref "/kagent/0.x/resources/cli/kagent-uninstall" >}}).
```bash
kagent uninstall
diff --git a/docs-site/content/kagent/0.x/operations/upgrade.md b/docs-site/content/kagent/0.x/operations/upgrade.md
index 30159929..0c7099cb 100644
--- a/docs-site/content/kagent/0.x/operations/upgrade.md
+++ b/docs-site/content/kagent/0.x/operations/upgrade.md
@@ -15,12 +15,12 @@ Follow these steps to upgrade kagent to the latest version and keep your cluster
export NEW_VERSION=
```
-2. Read the [release notes](/docs/kagent/resources/release-notes) for the version you are upgrading to. Pay attention to any breaking changes or deprecations that might affect your configuration.
+2. Read the [release notes]({{< relref "/kagent/0.x/resources/release-notes" >}}) for the version you are upgrading to. Pay attention to any breaking changes or deprecations that might affect your configuration.
3. Back up your current configuration, including the following:
- Agent definitions
- Any custom settings
- - PostgreSQL database: You can take a snapshot now so that you have a restore point if the upgrade fails. For the database connection string, see [Database configuration](/docs/kagent/operations/operational-considerations#database-configuration).
+ - PostgreSQL database: You can take a snapshot now so that you have a restore point if the upgrade fails. For the database connection string, see [Database configuration]({{< relref "/kagent/0.x/operations/operational-considerations#database-configuration" >}}).
```bash
pg_dump "postgres://:@:5432/" \
@@ -28,7 +28,7 @@ Follow these steps to upgrade kagent to the latest version and keep your cluster
--file=kagent-pre-upgrade-snapshot.dump
```
-4. **v0.9.0 and later**: You must be running at least v0.8.0 before upgrading to v0.9.0. Check the [release notes](/docs/kagent/resources/release-notes#v09) for 0.9-specific upgrades related to database migrations and RBAC scope.
+4. **v0.9.0 and later**: You must be running at least v0.8.0 before upgrading to v0.9.0. Check the [release notes]({{< relref "/kagent/0.x/resources/release-notes#v09" >}}) for 0.9-specific upgrades related to database migrations and RBAC scope.
## Upgrade kagent
@@ -56,7 +56,7 @@ Follow these steps to upgrade kagent to the latest version and keep your cluster
3. Make any changes that you want by editing your `values.yaml` Helm values file or preparing `--set` flags for the upgrade commands.
- > **Note**: As of [version 0.7](/docs/kagent/resources/release-notes#kmcp-installed-by-default), the kmcp subproject is included by default with kagent. To use an existing kmcp installation that you already set up separately, set `kmcp.enabled=false` in your `values.yaml` file or `--set` commands for both the `kagent` and `kagent-crds` charts.
+ > **Note**: As of [version 0.7]({{< relref "/kagent/0.x/resources/release-notes#kmcp-installed-by-default" >}}), the kmcp subproject is included by default with kagent. To use an existing kmcp installation that you already set up separately, set `kmcp.enabled=false` in your `values.yaml` file or `--set` commands for both the `kagent` and `kagent-crds` charts.
4. Upgrade the kagent-crds chart.
@@ -171,7 +171,7 @@ For example, `v0.9.9` has migrations up to `000005_a2a_protocol_version.up.sql`
export ROLLBACK_MIGRATION_VERSION=
```
-5. Reset the core track. The `github://` source references the migration files directly from the release tag without a local checkout. For the database connection string, see [Database configuration](/docs/kagent/operations/operational-considerations#database-configuration).
+5. Reset the core track. The `github://` source references the migration files directly from the release tag without a local checkout. For the database connection string, see [Database configuration]({{< relref "/kagent/0.x/operations/operational-considerations#database-configuration" >}}).
```bash
migrate \
-source "github://kagent-dev/kagent/go/core/pkg/migrations/core#v$CURRENT_VERSION" \
diff --git a/docs-site/content/kagent/0.x/resources/_index.md b/docs-site/content/kagent/0.x/resources/_index.md
index a1fb1b51..659c77ad 100644
--- a/docs-site/content/kagent/0.x/resources/_index.md
+++ b/docs-site/content/kagent/0.x/resources/_index.md
@@ -5,4 +5,4 @@ weight: 7
author: kagent.dev
---
-Find helpful resources and FAQs for kagent. New to kagent? Start with the [Quick Start Guide](/docs/kagent/getting-started/quickstart).
+Find helpful resources and FAQs for kagent. New to kagent? Start with the [Quick Start Guide]({{< relref "/kagent/0.x/getting-started/quickstart" >}}).
diff --git a/docs-site/content/kagent/0.x/resources/faq.md b/docs-site/content/kagent/0.x/resources/faq.md
index 9d554b22..822fa07a 100644
--- a/docs-site/content/kagent/0.x/resources/faq.md
+++ b/docs-site/content/kagent/0.x/resources/faq.md
@@ -8,7 +8,7 @@ author: kagent.dev
## What's the best way to get started with kagent?
-The best way to get started with kagent is to follow the [quickstart guide](/docs/kagent/getting-started/quickstart). This will give you a basic understanding of how kagent works and how to use it.
+The best way to get started with kagent is to follow the [quickstart guide]({{< relref "/kagent/0.x/getting-started/quickstart" >}}). This will give you a basic understanding of how kagent works and how to use it.
## What differentiates kagent from other LLM frameworks?
diff --git a/docs-site/content/kagent/0.x/resources/release-notes.md b/docs-site/content/kagent/0.x/resources/release-notes.md
index 35c37174..fbe12d16 100644
--- a/docs-site/content/kagent/0.x/resources/release-notes.md
+++ b/docs-site/content/kagent/0.x/resources/release-notes.md
@@ -16,7 +16,7 @@ Review this summary of significant changes from kagent version 0.8 to v0.9.
**Before you upgrade:**
* You must be running at least v0.8.0 before upgrading to v0.9.0.
-* Back up your PostgreSQL database before upgrading. For details on your database configuration, see the [Database configuration guide](/docs/kagent/operations/operational-considerations/#database-configuration).
+* Back up your PostgreSQL database before upgrading. For details on your database configuration, see the [Database configuration guide]({{< relref "/kagent/0.x/operations/operational-considerations/#database-configuration" >}}).
* The `rbac.clusterScoped` Helm value is removed. RBAC scope is now derived from `rbac.namespaces`. If you set `rbac.clusterScoped` in your Helm values, update your configuration to use `rbac.namespaces` instead.
**What's included:**
@@ -159,7 +159,7 @@ You can now use two Human-in-the-Loop mechanisms that can pause agent execution
**Ask User** — A built-in `ask_user` tool is automatically added to every agent. Agents can pose questions to users with predefined choices (single-select, multi-select) or free-text input during execution.
-For more information, see the [Human-in-the-Loop example](/docs/kagent/examples/human-in-the-loop) and the [blog post](https://kagent.dev/blog/human-in-the-loop-kagent).
+For more information, see the [Human-in-the-Loop example]({{< relref "/kagent/0.x/examples/human-in-the-loop" >}}) and the [blog post](https://kagent.dev/blog/human-in-the-loop-kagent).
### Agent Memory
@@ -169,7 +169,7 @@ When you enable memory on an agent, it receives three additional tools: `save_me
You can configure memory in the Agent CR or through the UI when you create or edit an agent by selecting an embedding model and TTL.
-For more information, see [Agent Memory](/docs/kagent/concepts/agent-memory).
+For more information, see [Agent Memory]({{< relref "/kagent/0.x/concepts/agent-memory" >}}).
### Go ADK Runtime
@@ -186,7 +186,7 @@ spec:
The Go ADK includes built-in tools: `SkillsTool`, `BashTool`, `ReadFile`, `WriteFile`, and `EditFile`.
-For more information, see [Agents](/docs/kagent/concepts/agents#runtime) and the [blog post](https://kagent.dev/blog/go-vs-python-runtime).
+For more information, see [Agents]({{< relref "/kagent/0.x/concepts/agents#runtime" >}}) and the [blog post](https://kagent.dev/blog/go-vs-python-runtime).
### Agents as MCP Servers
@@ -201,7 +201,7 @@ You can load skills from two sources.
- **OCI images.** Container images containing skill files.
- **Git repositories.** Clone skills directly from Git repos, with support for private repos via HTTPS token or SSH key authentication.
-For more information, see [Agents](/docs/kagent/concepts/agents#git-based-skills).
+For more information, see [Agents]({{< relref "/kagent/0.x/concepts/agents#git-based-skills" >}}).
### Go Workspace Restructure
@@ -219,13 +219,13 @@ Agent system messages now support Go `text/template` syntax. You can store commo
The `kagent-builtin-prompts` ConfigMap ships with five reusable templates: `skills-usage`, `tool-usage-best-practices`, `safety-guardrails`, `kubernetes-context`, and `a2a-communication`.
-For more information, see [Agents](/docs/kagent/concepts/agents#prompt-templates).
+For more information, see [Agents]({{< relref "/kagent/0.x/concepts/agents#prompt-templates" >}}).
### Context Management
Long conversations can now be automatically compacted to stay within LLM context windows. You can configure the `context.compaction` field to enable periodic summarization of older events while preserving key information.
-For more information, see [Agents](/docs/kagent/concepts/agents#context-management).
+For more information, see [Agents]({{< relref "/kagent/0.x/concepts/agents#context-management" >}}).
### AWS Bedrock Support
@@ -252,7 +252,7 @@ SQLite support has been removed from kagent. PostgreSQL is now the only supporte
**Migration:**
-If you were using the default SQLite backend, no migration is needed. The bundled PostgreSQL is deployed automatically. You can optionally customize the bundled instance via `database.postgres.bundled.*` (storage size, image) as needed. See the [Database configuration guide](/docs/kagent/operations/operational-considerations/#database-configuration) for details.
+If you were using the default SQLite backend, no migration is needed. The bundled PostgreSQL is deployed automatically. You can optionally customize the bundled instance via `database.postgres.bundled.*` (storage size, image) as needed. See the [Database configuration guide]({{< relref "/kagent/0.x/operations/operational-considerations/#database-configuration" >}}) for details.
Note that for production deployments, use your own external PostgreSQL instance. If you already are, you can keep your `database.postgres.url` or `database.postgres.urlFile` settings as before. If your external PostgreSQL has the pgvector extension and you were using vector-based memory features, set `database.postgres.vectorEnabled: true` since the default has changed to `false`.
@@ -306,7 +306,7 @@ helm upgrade --install kagent oci://ghcr.io/kagent-dev/kagent/helm/kagent \
Develop and test agents locally on your machine without needing a Kubernetes cluster. As part of this feature, the `kagent` CLI includes new commands to scaffold, build, run, and deploy agents.
-For more information, see the [local development](/docs/kagent/getting-started/local-development) guide.
+For more information, see the [local development]({{< relref "/kagent/0.x/getting-started/local-development" >}}) guide.
### Discovery label
@@ -654,7 +654,7 @@ This change supports the new type for BYO agents.
A new agent type has been added to the Agents API so that you can bring your own (BYO) agent. The agent must be written in ADK, with other frameworks under development.
-BYO Agent example configuration. For more information, see the [BYO Agent](/docs/kagent/examples/a2a-byo) guide.
+BYO Agent example configuration. For more information, see the [BYO Agent]({{< relref "/kagent/0.x/examples/a2a-byo" >}}) guide.
```yaml
apiVersion: kagent.dev/v1alpha2
diff --git a/docs-site/content/kagent/0.x/supported-providers/amazon-bedrock.md b/docs-site/content/kagent/0.x/supported-providers/amazon-bedrock.md
index 72f329de..7d63fbc6 100644
--- a/docs-site/content/kagent/0.x/supported-providers/amazon-bedrock.md
+++ b/docs-site/content/kagent/0.x/supported-providers/amazon-bedrock.md
@@ -97,7 +97,7 @@ spec:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/kagent-bedrock
```
-If you want to use one shared ServiceAccount for multiple agents, you can also set `controller.agentDeployment.serviceAccountName` in the [Helm chart configuration](/docs/kagent/resources/helm).
+If you want to use one shared ServiceAccount for multiple agents, you can also set `controller.agentDeployment.serviceAccountName` in the [Helm chart configuration]({{< relref "/kagent/0.x/resources/helm" >}}).
## Option 2: OpenAI-compatible API
diff --git a/docs-site/content/kagent/0.x/supported-providers/azure-ai-foundry.md b/docs-site/content/kagent/0.x/supported-providers/azure-ai-foundry.md
index 2f8edd63..40782510 100644
--- a/docs-site/content/kagent/0.x/supported-providers/azure-ai-foundry.md
+++ b/docs-site/content/kagent/0.x/supported-providers/azure-ai-foundry.md
@@ -248,7 +248,7 @@ spec:
# No API key: use Azure Workload Identity.
```
-For the complete memory and embedding configuration and model requirements, see [Agent Memory](/docs/kagent/concepts/agent-memory).
+For the complete memory and embedding configuration and model requirements, see [Agent Memory]({{< relref "/kagent/0.x/concepts/agent-memory" >}}).
## Troubleshooting
diff --git a/docs-site/content/kagent/0.x/supported-providers/azure-openai.md b/docs-site/content/kagent/0.x/supported-providers/azure-openai.md
index ff10dc02..b9ec49e8 100644
--- a/docs-site/content/kagent/0.x/supported-providers/azure-openai.md
+++ b/docs-site/content/kagent/0.x/supported-providers/azure-openai.md
@@ -66,4 +66,4 @@ Omit `apiKeySecret` and `apiKeyPassthrough` to use Azure Workload Identity. For
Follow the [AKS Workload Identity deployment guide](https://learn.microsoft.com/azure/aks/workload-identity-deploy-cluster) and grant the managed identity the `Cognitive Services User` role.
-The kagent pod and ServiceAccount settings are provider-independent. Follow [Configure the agent for Azure Workload Identity](/docs/kagent/supported-providers/azure-ai-foundry#configure-the-agent-for-azure-workload-identity) and set the agent's `modelConfig` to `azure-openai`.
+The kagent pod and ServiceAccount settings are provider-independent. Follow [Configure the agent for Azure Workload Identity]({{< relref "/kagent/0.x/supported-providers/azure-ai-foundry#configure-the-agent-for-azure-workload-identity" >}}) and set the agent's `modelConfig` to `azure-openai`.
From 9ed386215d5646dcf75ddec5aeeaf3ce0429d2ab Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Fri, 21 Aug 2026 16:28:29 -0500
Subject: [PATCH 04/70] Use the link shortcode instead of relref for internal
kagent links
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
relref works but isn't the convention this theme actually uses for
same-product cross-links — docs-theme-extras ships a `link` shortcode
for exactly this. Swap the previous relref conversion over to it.
Upstream's link shortcode resolves relative to .Page.FirstSection, which
lands on the product root ("/docs/kagent/") and drops the version segment
— the same class of bug already fixed in navbar.html, sidebar.html, and
version-banner.html. Added a local override (layouts/_shortcodes/link.html)
that resolves relative to the current page's own version instead, and
verified against a real Hugo build (plain links, a fragment-bearing link,
and the not-in-version self-links all resolve correctly).
The one cross-version link (1.x's landing page pointing back at 0.x) stays
on relref, since `link` is inherently relative to the current page's own
version and can't express "the other version" — relref targeting an
absolute content path is the right tool for that one case.
Co-Authored-By: Claude Sonnet 5
Signed-off-by: Rachael Graham
---
.../content/kagent/0.x/concepts/_index.md | 2 +-
.../kagent/0.x/concepts/agent-harness.md | 6 +-
.../kagent/0.x/concepts/agent-memory.md | 6 +-
.../kagent/0.x/concepts/agent-substrate.md | 10 +--
.../content/kagent/0.x/concepts/agents.md | 14 ++--
.../kagent/0.x/concepts/architecture.md | 4 +-
.../content/kagent/0.x/concepts/mcp-apps.md | 2 +-
.../content/kagent/0.x/concepts/tools.md | 4 +-
.../content/kagent/0.x/examples/a2a-agents.md | 4 +-
.../content/kagent/0.x/examples/a2a-byo.md | 6 +-
.../kagent/0.x/examples/agent-harness.md | 10 +--
.../kagent/0.x/examples/agent-substrate.md | 6 +-
.../kagent/0.x/examples/agentgateway.md | 4 +-
.../content/kagent/0.x/examples/crewai-byo.md | 6 +-
.../kagent/0.x/examples/discord-a2a.md | 4 +-
.../kagent/0.x/examples/langchain-byo.md | 4 +-
.../content/kagent/0.x/examples/skills.md | 10 +--
.../content/kagent/0.x/examples/slack-a2a.md | 2 +-
.../kagent/0.x/examples/telegram-bot.md | 2 +-
.../kagent/0.x/getting-started/first-agent.md | 4 +-
.../0.x/getting-started/first-mcp-tool.md | 6 +-
.../0.x/getting-started/local-development.md | 4 +-
.../kagent/0.x/getting-started/quickstart.md | 6 +-
.../content/kagent/0.x/introduction/_index.md | 2 +-
.../kagent/0.x/introduction/installation.md | 16 ++---
.../kagent/0.x/introduction/what-is-kagent.md | 4 +-
.../content/kagent/0.x/not-in-version.md | 2 +-
.../kagent/0.x/observability/audit-prompts.md | 2 +-
.../kagent/0.x/observability/launch-ui.md | 6 +-
.../kagent/0.x/observability/tracing.md | 10 +--
.../operations/operational-considerations.md | 2 +-
.../kagent/0.x/operations/uninstall.md | 2 +-
.../content/kagent/0.x/operations/upgrade.md | 10 +--
.../content/kagent/0.x/resources/_index.md | 2 +-
docs-site/content/kagent/0.x/resources/faq.md | 2 +-
.../kagent/0.x/resources/release-notes.md | 20 +++---
.../0.x/supported-providers/amazon-bedrock.md | 2 +-
.../supported-providers/azure-ai-foundry.md | 2 +-
.../0.x/supported-providers/azure-openai.md | 2 +-
.../content/kagent/1.x/not-in-version.md | 2 +-
docs-site/layouts/_shortcodes/link.html | 72 +++++++++++++++++++
41 files changed, 179 insertions(+), 107 deletions(-)
create mode 100644 docs-site/layouts/_shortcodes/link.html
diff --git a/docs-site/content/kagent/0.x/concepts/_index.md b/docs-site/content/kagent/0.x/concepts/_index.md
index 41b4b4f6..d195c405 100644
--- a/docs-site/content/kagent/0.x/concepts/_index.md
+++ b/docs-site/content/kagent/0.x/concepts/_index.md
@@ -7,4 +7,4 @@ author: kagent.dev
Learn about the AI agent and kagent concepts.
-The [Agents]({{< relref "/kagent/0.x/concepts/agents" >}}) page also covers [prompt templates]({{< relref "/kagent/0.x/concepts/agents#prompt-templates" >}}), [Git-based skills]({{< relref "/kagent/0.x/concepts/agents#git-based-skills" >}}), and [context management]({{< relref "/kagent/0.x/concepts/agents#context-management" >}}). For related material, see [What is kagent]({{< relref "/kagent/0.x/introduction/what-is-kagent" >}}), the [Tools Ecosystem]({{< relref "/kagent/0.x/resources/tools-ecosystem" >}}) catalog, [Human-in-the-Loop]({{< relref "/kagent/0.x/examples/human-in-the-loop" >}}) configuration, and the [examples]({{< relref "/kagent/0.x/examples" >}}), which include both the Go and Python runtimes.
+The [Agents]({{< link path="concepts/agents" >}}) page also covers [prompt templates]({{< link path="concepts/agents#prompt-templates" >}}), [Git-based skills]({{< link path="concepts/agents#git-based-skills" >}}), and [context management]({{< link path="concepts/agents#context-management" >}}). For related material, see [What is kagent]({{< link path="introduction/what-is-kagent" >}}), the [Tools Ecosystem]({{< link path="resources/tools-ecosystem" >}}) catalog, [Human-in-the-Loop]({{< link path="examples/human-in-the-loop" >}}) configuration, and the [examples]({{< link path="examples" >}}), which include both the Go and Python runtimes.
diff --git a/docs-site/content/kagent/0.x/concepts/agent-harness.md b/docs-site/content/kagent/0.x/concepts/agent-harness.md
index a5043d18..bd07c01d 100644
--- a/docs-site/content/kagent/0.x/concepts/agent-harness.md
+++ b/docs-site/content/kagent/0.x/concepts/agent-harness.md
@@ -5,7 +5,7 @@ weight: 4
author: kagent.dev
---
-An `AgentHarness` is a Kubernetes custom resource that asks kagent to provision a long-running remote execution environment on [Agent Substrate]({{< relref "/kagent/0.x/concepts/agent-substrate" >}}). It is useful when you want a managed sandbox that runs a coding agent (such as OpenClaw or Hermes) that you can chat with and connect to messaging channels, but you do not want kagent to package and run a full agent runtime inside the workload.
+An `AgentHarness` is a Kubernetes custom resource that asks kagent to provision a long-running remote execution environment on [Agent Substrate]({{< link path="concepts/agent-substrate" >}}). It is useful when you want a managed sandbox that runs a coding agent (such as OpenClaw or Hermes) that you can chat with and connect to messaging channels, but you do not want kagent to package and run a full agent runtime inside the workload.
`AgentHarness` resources appear alongside agents in kagent APIs and status views, but they are not the same thing as `Agent` or `SandboxAgent`.
@@ -30,7 +30,7 @@ All backends use the same top-level `AgentHarness` shape: `backend`, `substrate`
## Runtime: Agent Substrate
-Every `AgentHarness` runs on [Agent Substrate]({{< relref "/kagent/0.x/concepts/agent-substrate" >}}). The `spec.substrate` field is required and configures the Substrate provisioning stack:
+Every `AgentHarness` runs on [Agent Substrate]({{< link path="concepts/agent-substrate" >}}). The `spec.substrate` field is required and configures the Substrate provisioning stack:
- `workerPoolRef` — references an existing `WorkerPool` in the harness namespace. When unset, the controller uses its configured default WorkerPool.
- `snapshotsConfig` — configures where actor memory snapshots are stored. Defaults to `gs://ate-snapshots//` when unset.
@@ -94,4 +94,4 @@ The API uses CEL validation to ensure Slack settings match the selected backend.
## Next steps
-For enabling Agent Substrate so the controller can provision harnesses, see [Enable AgentHarness support]({{< relref "/kagent/0.x/introduction/installation#enable-agentharness-support" >}}). For complete YAML examples, including Slack token references and backend-specific Slack settings, see the [Agent Harness example]({{< relref "/kagent/0.x/examples/agent-harness" >}}). For the generated schema, see the [API reference]({{< relref "/kagent/0.x/resources/api-ref#agentharness" >}}).
+For enabling Agent Substrate so the controller can provision harnesses, see [Enable AgentHarness support]({{< link path="introduction/installation#enable-agentharness-support" >}}). For complete YAML examples, including Slack token references and backend-specific Slack settings, see the [Agent Harness example]({{< link path="examples/agent-harness" >}}). For the generated schema, see the [API reference]({{< link path="resources/api-ref#agentharness" >}}).
diff --git a/docs-site/content/kagent/0.x/concepts/agent-memory.md b/docs-site/content/kagent/0.x/concepts/agent-memory.md
index 88db2e76..bace41e6 100644
--- a/docs-site/content/kagent/0.x/concepts/agent-memory.md
+++ b/docs-site/content/kagent/0.x/concepts/agent-memory.md
@@ -22,7 +22,7 @@ Agent memory provides the following capabilities.
### Install kagent with Postgres
-To use memory, you must install kagent with a Postgres database that has the `pgvector` extension installed and vector enabled. For more information, see the [Database configuration]({{< relref "/kagent/0.x/operations/operational-considerations#database-configuration" >}}) section.
+To use memory, you must install kagent with a Postgres database that has the `pgvector` extension installed and vector enabled. For more information, see the [Database configuration]({{< link path="operations/operational-considerations#database-configuration" >}}) section.
Example Helm configuration for your own external Postgres:
@@ -71,7 +71,7 @@ The embedding `ModelConfig` does not have to use the same provider as the agent'
To use [Amazon Bedrock Titan embedding models](https://docs.aws.amazon.com/bedrock/latest/userguide/titan-embedding-models.html), create a `ModelConfig` with `provider: Bedrock`.
-The Bedrock provider uses the standard AWS credential chain, so no API key secret is required. The agent's pod must have AWS credentials with the `bedrock:InvokeModel` permission for the chosen model. On Kubernetes, the recommended setup is [EKS IRSA on the agent ServiceAccount]({{< relref "/kagent/0.x/supported-providers/amazon-bedrock#step-3-configure-the-agent-to-use-an-iam-role" >}}).
+The Bedrock provider uses the standard AWS credential chain, so no API key secret is required. The agent's pod must have AWS credentials with the `bedrock:InvokeModel` permission for the chosen model. On Kubernetes, the recommended setup is [EKS IRSA on the agent ServiceAccount]({{< link path="supported-providers/amazon-bedrock#step-3-configure-the-agent-to-use-an-iam-role" >}}).
```yaml
apiVersion: kagent.dev/v1alpha2
@@ -184,5 +184,5 @@ DELETE /api/memories?agent_name=X&user_id=Y
- **No per-memory deletion.** You can delete all memories for an agent, but you cannot delete individual memory entries.
- **No cross-agent memory sharing.** Each agent has its own isolated memory store. You cannot share memories across agents.
-- **Not pluggable.** Memory is built on the Google ADK memory implementation and cannot be swapped for an alternative memory solution (such as Cognee). However, if an alternative memory solution exposes an [MCP server]({{< relref "/kagent/0.x/concepts/tools#mcp-tools" >}}), you can add it as a tool and instruct the agent to use it instead of the built-in memory.
+- **Not pluggable.** Memory is built on the Google ADK memory implementation and cannot be swapped for an alternative memory solution (such as Cognee). However, if an alternative memory solution exposes an [MCP server]({{< link path="concepts/tools#mcp-tools" >}}), you can add it as a tool and instruct the agent to use it instead of the built-in memory.
diff --git a/docs-site/content/kagent/0.x/concepts/agent-substrate.md b/docs-site/content/kagent/0.x/concepts/agent-substrate.md
index 8ae021dd..86c95802 100644
--- a/docs-site/content/kagent/0.x/concepts/agent-substrate.md
+++ b/docs-site/content/kagent/0.x/concepts/agent-substrate.md
@@ -9,8 +9,8 @@ Agent Substrate is a Kubernetes-native runtime for running AI agents and other s
kagent can run workloads on Agent Substrate in two ways:
-- **Declarative agents** — A declarative `Agent` describes its model, instructions, and tools (see [Agents]({{< relref "/kagent/0.x/concepts/agents" >}})). Its sandboxed variant, the [`SandboxAgent`]({{< relref "/kagent/0.x/resources/api-ref" >}}) CRD, lets you run a (Go) declarative agent on Agent Substrate.
-- **AgentHarness** — The [`AgentHarness`]({{< relref "/kagent/0.x/concepts/agent-harness" >}}) CRD provisions a long-running execution environment for a coding agent (OpenClaw or Hermes). It always runs on Agent Substrate: kagent generates a per-harness `ActorTemplate` and creates an `Actor` from it on demand, referencing a `WorkerPool` for capacity.
+- **Declarative agents** — A declarative `Agent` describes its model, instructions, and tools (see [Agents]({{< link path="concepts/agents" >}})). Its sandboxed variant, the [`SandboxAgent`]({{< link path="resources/api-ref" >}}) CRD, lets you run a (Go) declarative agent on Agent Substrate.
+- **AgentHarness** — The [`AgentHarness`]({{< link path="concepts/agent-harness" >}}) CRD provisions a long-running execution environment for a coding agent (OpenClaw or Hermes). It always runs on Agent Substrate: kagent generates a per-harness `ActorTemplate` and creates an `Actor` from it on demand, referencing a `WorkerPool` for capacity.
## Why Agent Substrate
@@ -66,11 +66,11 @@ An `AgentHarness` always runs on Agent Substrate; `spec.substrate` is required.
- `snapshotsConfig` — configures where actor memory snapshots are stored. Defaults to `gs://ate-snapshots//` when unset.
- `workloadImage` — overrides the default OpenClaw or Hermes sandbox image used in the generated ActorTemplate.
-kagent talks to the harness over the [Agent Client Protocol (ACP)](https://agentclientprotocol.com/) so you can chat with it from the kagent UI. See the [Agent Harness concept page]({{< relref "/kagent/0.x/concepts/agent-harness" >}}) for details.
+kagent talks to the harness over the [Agent Client Protocol (ACP)](https://agentclientprotocol.com/) so you can chat with it from the kagent UI. See the [Agent Harness concept page]({{< link path="concepts/agent-harness" >}}) for details.
-See the [API reference]({{< relref "/kagent/0.x/resources/api-ref" >}}) for the full `AgentHarnessSubstrateSpec` schema.
+See the [API reference]({{< link path="resources/api-ref" >}}) for the full `AgentHarnessSubstrateSpec` schema.
## Learn more
-- [Run a declarative agent on Agent Substrate]({{< relref "/kagent/0.x/examples/agent-substrate" >}}) — end-to-end walkthrough on a kind cluster.
+- [Run a declarative agent on Agent Substrate]({{< link path="examples/agent-substrate" >}}) — end-to-end walkthrough on a kind cluster.
- For a deeper dive into the runtime internals, see the [Agent Substrate documentation](https://learn.agentsubstrate.dev/).
diff --git a/docs-site/content/kagent/0.x/concepts/agents.md b/docs-site/content/kagent/0.x/concepts/agents.md
index f366ea08..474768cf 100644
--- a/docs-site/content/kagent/0.x/concepts/agents.md
+++ b/docs-site/content/kagent/0.x/concepts/agents.md
@@ -24,7 +24,7 @@ Your responses should be clear and concise; you should provide helpful informati
Instructions are an important part of the agent's behavior. They define the agent's role and capabilities and help the agent understand its environment and the tasks it can perform.
-Writing good instructions is an art and a science. It requires a good understanding of the task at hand, the tools available, and the user's needs. In order to make it easier to write good instructions, we've created a [system prompt tutorial]({{< relref "/kagent/0.x/getting-started/system-prompts" >}}) that can help you get started.
+Writing good instructions is an art and a science. It requires a good understanding of the task at hand, the tools available, and the user's needs. In order to make it easier to write good instructions, we've created a [system prompt tutorial]({{< link path="getting-started/system-prompts" >}}) that can help you get started.
### Prompt templates
@@ -98,7 +98,7 @@ kagent comes with a set of built-in tools that you can use to interact with your
kagent supports Human-in-the-Loop (HITL) to keep humans in control of agent actions. You can require user approval before an agent executes sensitive tools, and agents can ask users questions when they need clarification.
-For a hands-on tutorial that walks through setting up HITL with tool approval and the `ask_user` tool, see the [Human-in-the-Loop example]({{< relref "/kagent/0.x/examples/human-in-the-loop" >}}).
+For a hands-on tutorial that walks through setting up HITL with tool approval and the `ask_user` tool, see the [Human-in-the-Loop example]({{< link path="examples/human-in-the-loop" >}}).
### Tool approval
@@ -226,7 +226,7 @@ When creating skills for your agents, consider the following best practices. Age
4. **Align with tools**: Ensure your skills align with the tools available to the agent. If you have a skill that centers around writing docs in markdown, you might want to align it with the `write-markdown` tool (as opposed to a `generate-pdf` tool).
5. **Keep skills focused**: Each skill should have a clear, focused purpose. For example, a document-generating skill might be too broad, but a skill that focuses on creating a specific type of document, such as a `.docx` file or alternatively a genre like a getting started guide, might be more appropriate.
-To learn more about using skills in your agents, see the [Skills example guide]({{< relref "/kagent/0.x/examples/skills" >}}).
+To learn more about using skills in your agents, see the [Skills example guide]({{< link path="examples/skills" >}}).
## Runtime
@@ -263,7 +263,7 @@ For more benchmarks and details, see the [Go vs Python runtime blog post](https:
Your agents can save and retrieve relevant context across conversations using vector similarity search. When you enable memory on an agent, it receives three additional tools (`save_memory`, `load_memory`, `prefetch_memory`) and automatically extracts key information every 5th user message.
-For configuration details, supported storage backends, API endpoints, and limitations, see [Agent Memory]({{< relref "/kagent/0.x/concepts/agent-memory" >}}).
+For configuration details, supported storage backends, API endpoints, and limitations, see [Agent Memory]({{< link path="concepts/agent-memory" >}}).
## Context Management
@@ -292,9 +292,9 @@ Compaction removes older conversation events to free up space in the context win
## Sandboxed Agents
-You can run a declarative agent in an isolated sandbox by creating a `SandboxAgent` resource instead of a regular `Agent`. A `SandboxAgent` runs on [Agent Substrate]({{< relref "/kagent/0.x/concepts/agent-substrate" >}}): the kagent controller runs it as a gVisor-sandboxed actor instead of a Deployment, snapshotting it to object storage when idle and rehydrating it on demand. The spec mirrors the `Agent` spec, with a few constraints: sandboxed agents always use the Go ADK runtime, and `spec.skills` and `BYO` agents are not supported. Configure substrate placement with the optional `spec.substrate` field (for example, `workerPoolRef`).
+You can run a declarative agent in an isolated sandbox by creating a `SandboxAgent` resource instead of a regular `Agent`. A `SandboxAgent` runs on [Agent Substrate]({{< link path="concepts/agent-substrate" >}}): the kagent controller runs it as a gVisor-sandboxed actor instead of a Deployment, snapshotting it to object storage when idle and rehydrating it on demand. The spec mirrors the `Agent` spec, with a few constraints: sandboxed agents always use the Go ADK runtime, and `spec.skills` and `BYO` agents are not supported. Configure substrate placement with the optional `spec.substrate` field (for example, `workerPoolRef`).
-For setup steps, see the [Agent Substrate example]({{< relref "/kagent/0.x/examples/agent-substrate" >}}).
+For setup steps, see the [Agent Substrate example]({{< link path="examples/agent-substrate" >}}).
## Agents as Tools
@@ -330,4 +330,4 @@ Here's how you could reference an existing agent (`promql-agent`) as a tool:
A2A-enabled agents are automatically exposed as an MCP server on the kagent controller. The MCP endpoint is available at `/mcp` on the same port as the A2A endpoint (default 8083).
-For more information, see the [MCP tools]({{< relref "/kagent/0.x/examples/agents-mcp" >}}) guide.
+For more information, see the [MCP tools]({{< link path="examples/agents-mcp" >}}) guide.
diff --git a/docs-site/content/kagent/0.x/concepts/architecture.md b/docs-site/content/kagent/0.x/concepts/architecture.md
index 0f38b86b..7d40b4a5 100644
--- a/docs-site/content/kagent/0.x/concepts/architecture.md
+++ b/docs-site/content/kagent/0.x/concepts/architecture.md
@@ -24,7 +24,7 @@ The kagent engine is the core component of kagent. It runs the agent's conversat
- **Python ADK** (default) — Built on top of the [Google ADK](https://google.github.io/adk-docs/) framework. Supports Google ADK-native features and integrations with CrewAI, LangGraph, and OpenAI frameworks.
- **Go ADK** — A native Go implementation that provides faster startup (~2 seconds vs ~15 seconds) and lower resource consumption.
-Select the runtime by setting the `runtime` field in the agent spec (e.g., `runtime: go`). Both runtimes support MCP tools, HITL, and agent memory. For more details, see [Agents]({{< relref "/kagent/0.x/concepts/agents#runtime" >}}).
+Select the runtime by setting the `runtime` field in the agent spec (e.g., `runtime: go`). Both runtimes support MCP tools, HITL, and agent memory. For more details, see [Agents]({{< link path="concepts/agents#runtime" >}}).
For more information on the Google ADK framework:
@@ -63,5 +63,5 @@ kagent dashboard provides a web interface for managing and working with AI agent
## Next Steps
-- Try [building your own agent]({{< relref "/kagent/0.x/getting-started/first-agent" >}})
+- Try [building your own agent]({{< link path="getting-started/first-agent" >}})
- Join our [Community](https://discord.gg/Fu3k65f2k3)
diff --git a/docs-site/content/kagent/0.x/concepts/mcp-apps.md b/docs-site/content/kagent/0.x/concepts/mcp-apps.md
index d1bf1044..1668554e 100644
--- a/docs-site/content/kagent/0.x/concepts/mcp-apps.md
+++ b/docs-site/content/kagent/0.x/concepts/mcp-apps.md
@@ -60,4 +60,4 @@ A complete example, including a demo agent, is available in the kagent repositor
- [MCP Apps extension](https://github.com/modelcontextprotocol/ext-apps)
- [Model Context Protocol](https://modelcontextprotocol.io/)
-- [Tools in kagent]({{< relref "/kagent/0.x/concepts/tools" >}})
+- [Tools in kagent]({{< link path="concepts/tools" >}})
diff --git a/docs-site/content/kagent/0.x/concepts/tools.md b/docs-site/content/kagent/0.x/concepts/tools.md
index 6573a194..0ea813fe 100644
--- a/docs-site/content/kagent/0.x/concepts/tools.md
+++ b/docs-site/content/kagent/0.x/concepts/tools.md
@@ -11,7 +11,7 @@ kagent comes with a set of built-in tools that you can use to interact with your
## Built-in Tools
-You can check out the full list of [built-in tools](https://kagent.dev/tools), or see the [Tools Ecosystem]({{< relref "/kagent/0.x/resources/tools-ecosystem" >}}) reference for a detailed catalog of tools organized by MCP server.
+You can check out the full list of [built-in tools](https://kagent.dev/tools), or see the [Tools Ecosystem]({{< link path="resources/tools-ecosystem" >}}) reference for a detailed catalog of tools organized by MCP server.
The built-in tools are meant as a good starting point for any agents running in kubernetes, however we don't envision them covering all possible use-cases, so we support multiple tool extension points to allow you to bring in your own tools.
@@ -78,7 +78,7 @@ MCP stands for [Model Context Protocol](https://modelcontextprotocol.io/introduc
### MCP Apps
-Some MCP tools ship an interactive UI with their results. kagent detects these tools automatically and renders their widgets inline in the chat, and the dashboard lists them alongside a server's regular tools so you can test them directly. See [MCP Apps]({{< relref "/kagent/0.x/concepts/mcp-apps" >}}) for details.
+Some MCP tools ship an interactive UI with their results. kagent detects these tools automatically and renders their widgets inline in the chat, and the dashboard lists them alongside a server's regular tools so you can test them directly. See [MCP Apps]({{< link path="concepts/mcp-apps" >}}) for details.
## HTTP Tools
diff --git a/docs-site/content/kagent/0.x/examples/a2a-agents.md b/docs-site/content/kagent/0.x/examples/a2a-agents.md
index 272cd49f..b41fd043 100644
--- a/docs-site/content/kagent/0.x/examples/a2a-agents.md
+++ b/docs-site/content/kagent/0.x/examples/a2a-agents.md
@@ -12,7 +12,7 @@ Let's look at how this works in kagent!
## Prerequisites
-Install kagent by following the [quick start]({{< relref "/kagent/0.x/getting-started/quickstart" >}}) guide.
+Install kagent by following the [quick start]({{< link path="getting-started/quickstart" >}}) guide.
## Creating an AI agent that supports A2A
@@ -135,7 +135,7 @@ You can invoke the agent in several ways, including the kagent dashboard, kagent
### Dashboard
-Launch the dashboard with `kagent dashboard`, find your `k8s-a2a-agent`, and start chatting. For complete steps, see the [Your First Agent]({{< relref "/kagent/0.x/getting-started/first-agent" >}}) guide.
+Launch the dashboard with `kagent dashboard`, find your `k8s-a2a-agent`, and start chatting. For complete steps, see the [Your First Agent]({{< link path="getting-started/first-agent" >}}) guide.
### kagent CLI
diff --git a/docs-site/content/kagent/0.x/examples/a2a-byo.md b/docs-site/content/kagent/0.x/examples/a2a-byo.md
index 2000a7f3..0bfc740e 100644
--- a/docs-site/content/kagent/0.x/examples/a2a-byo.md
+++ b/docs-site/content/kagent/0.x/examples/a2a-byo.md
@@ -6,13 +6,13 @@ weight: 1
author: kagent.dev
---
-Bring your own custom agents. This example uses the [Agent Development Kit (ADK)](https://google.github.io/adk-docs/), but you can also try out the [LangGraph guide]({{< relref "/kagent/0.x/examples/langchain-byo/" >}}). Such frameworks give you more control over the agent behavior and are well-suited for complex workflows and integration with external systems and APIs.
+Bring your own custom agents. This example uses the [Agent Development Kit (ADK)](https://google.github.io/adk-docs/), but you can also try out the [LangGraph guide]({{< link path="examples/langchain-byo/" >}}). Such frameworks give you more control over the agent behavior and are well-suited for complex workflows and integration with external systems and APIs.
Unlike declarative agents that are defined by kagent resources with components such as system instructions, models, and tools written inline, these BYO agents give you full control over agent logic. If you have your own agent, no need to decompose its functions into separate kagent resources. kagent can invoke your agent directly through the A2A protocol.
## Prerequisites
-1. Install kagent by following the [quick start]({{< relref "/kagent/0.x/getting-started/quickstart" >}}) guide.
+1. Install kagent by following the [quick start]({{< link path="getting-started/quickstart" >}}) guide.
2. Use [Google ADK](https://github.com/google/adk-python) version 1.22.1 or later.
## Building a custom agent
@@ -162,7 +162,7 @@ You can invoke the agent in several ways, including the kagent dashboard, kagent
### Dashboard
-Launch the dashboard with `kagent dashboard`, find your `basic-agent`, and start chatting. For complete steps, see the [Your First Agent]({{< relref "/kagent/0.x/getting-started/first-agent" >}}) guide.
+Launch the dashboard with `kagent dashboard`, find your `basic-agent`, and start chatting. For complete steps, see the [Your First Agent]({{< link path="getting-started/first-agent" >}}) guide.

diff --git a/docs-site/content/kagent/0.x/examples/agent-harness.md b/docs-site/content/kagent/0.x/examples/agent-harness.md
index 4be4b4f1..98e27e10 100644
--- a/docs-site/content/kagent/0.x/examples/agent-harness.md
+++ b/docs-site/content/kagent/0.x/examples/agent-harness.md
@@ -5,14 +5,14 @@ weight: 8
author: kagent.dev
---
-`AgentHarness` creates a long-running remote execution environment on [Agent Substrate]({{< relref "/kagent/0.x/concepts/agent-substrate" >}}). Unlike an `Agent` or `SandboxAgent`, it does not package a kagent runtime into the workload. The backend provisions a sandbox that runs a coding agent (OpenClaw or Hermes), which you can chat with from the kagent UI and wire into messaging channels.
+`AgentHarness` creates a long-running remote execution environment on [Agent Substrate]({{< link path="concepts/agent-substrate" >}}). Unlike an `Agent` or `SandboxAgent`, it does not package a kagent runtime into the workload. The backend provisions a sandbox that runs a coding agent (OpenClaw or Hermes), which you can chat with from the kagent UI and wire into messaging channels.
Use `AgentHarness` when you want kagent to manage the lifecycle of an OpenClaw or Hermes sandbox and surface it in the kagent API/UI alongside regular agents.
## Before you begin
-1. Install kagent v0.9.9 or later by following the [quick start]({{< relref "/kagent/0.x/getting-started/quickstart" >}}) guide.
-2. Install Agent Substrate and enable the substrate integration in kagent. For Helm-based setup instructions, see [Enable AgentHarness support]({{< relref "/kagent/0.x/introduction/installation#enable-agentharness-support" >}}) and the [Agent Substrate example]({{< relref "/kagent/0.x/examples/agent-substrate" >}}).
+1. Install kagent v0.9.9 or later by following the [quick start]({{< link path="getting-started/quickstart" >}}) guide.
+2. Install Agent Substrate and enable the substrate integration in kagent. For Helm-based setup instructions, see [Enable AgentHarness support]({{< link path="introduction/installation#enable-agentharness-support" >}}) and the [Agent Substrate example]({{< link path="examples/agent-substrate" >}}).
When the substrate integration is not enabled, the controller cannot provision AgentHarness resources.
@@ -204,7 +204,7 @@ Once the harness is `Ready`, it appears in the kagent UI alongside your other ag
2. Open [http://localhost:8001](http://localhost:8001), select your harness (for example `kagent/openclaw-shell`) from the Agents list, and send a message.
-The first chat connection creates a shared Substrate actor from the harness template; every chat is multiplexed as an ACP session inside that actor. You see streamed tool activity, and any tool-approval prompts the backend raises are surfaced through kagent's [human-in-the-loop]({{< relref "/kagent/0.x/examples/human-in-the-loop" >}}) flow.
+The first chat connection creates a shared Substrate actor from the harness template; every chat is multiplexed as an ACP session inside that actor. You see streamed tool activity, and any tool-approval prompts the backend raises are surfaced through kagent's [human-in-the-loop]({{< link path="examples/human-in-the-loop" >}}) flow.
## Troubleshooting
@@ -217,4 +217,4 @@ If the harness is not accepted or ready, check these common causes.
- A Slack channel has the wrong backend settings, such as `slack.hermes` on an OpenClaw harness or `slack.openclaw` on a Hermes harness.
- A Slack credential uses neither `value` nor `valueFrom`, or sets both.
-For the complete generated schema, see the [API reference]({{< relref "/kagent/0.x/resources/api-ref#agentharness" >}}).
+For the complete generated schema, see the [API reference]({{< link path="resources/api-ref#agentharness" >}}).
diff --git a/docs-site/content/kagent/0.x/examples/agent-substrate.md b/docs-site/content/kagent/0.x/examples/agent-substrate.md
index 53af1c5f..ffd6acc4 100644
--- a/docs-site/content/kagent/0.x/examples/agent-substrate.md
+++ b/docs-site/content/kagent/0.x/examples/agent-substrate.md
@@ -13,7 +13,7 @@ By the end, you will have:
- kagent v0.9.7 or later installed with the substrate integration enabled. Earlier kagent releases do not include the controller wiring that lets a `SandboxAgent` target substrate.
- A `SandboxAgent` running on substrate, reachable from the kagent UI.
-For background on what substrate is and how it differs from a per-pod agent runtime, see the [Agent Substrate concept page]({{< relref "/kagent/0.x/concepts/agent-substrate" >}}). This guide does not cover the `AgentHarness` path on substrate.
+For background on what substrate is and how it differs from a per-pod agent runtime, see the [Agent Substrate concept page]({{< link path="concepts/agent-substrate" >}}). This guide does not cover the `AgentHarness` path on substrate.
## Before you begin
@@ -213,5 +213,5 @@ kind delete cluster --name kagent-substrate
## Next steps
-- [Agent Substrate concept page]({{< relref "/kagent/0.x/concepts/agent-substrate" >}}) — runtime architecture and how snapshots, actors, and worker pools fit together.
-- [AgentHarness]({{< relref "/kagent/0.x/examples/agent-harness" >}}) — provision long-running OpenClaw and Hermes coding-agent sandboxes on Agent Substrate and chat with them over ACP.
+- [Agent Substrate concept page]({{< link path="concepts/agent-substrate" >}}) — runtime architecture and how snapshots, actors, and worker pools fit together.
+- [AgentHarness]({{< link path="examples/agent-harness" >}}) — provision long-running OpenClaw and Hermes coding-agent sandboxes on Agent Substrate and chat with them over ACP.
diff --git a/docs-site/content/kagent/0.x/examples/agentgateway.md b/docs-site/content/kagent/0.x/examples/agentgateway.md
index 196be566..801d69f6 100644
--- a/docs-site/content/kagent/0.x/examples/agentgateway.md
+++ b/docs-site/content/kagent/0.x/examples/agentgateway.md
@@ -10,7 +10,7 @@ As your kagent deployment grows, you might need governance over how your agents
## Prerequisites
-1. A running kagent installation. If you haven't installed kagent yet, follow the [quick start]({{< relref "/kagent/0.x/getting-started/quickstart" >}}) guide first.
+1. A running kagent installation. If you haven't installed kagent yet, follow the [quick start]({{< link path="getting-started/quickstart" >}}) guide first.
2. Follow the [agentgateway installation guide](https://agentgateway.dev/docs/kubernetes/latest/quickstart/install/) to install agentgateway in your cluster.
3. Set up an LLM provider with agentgateway. This guide uses [the Ollama setup](https://agentgateway.dev/docs/kubernetes/latest/llm/providers/ollama/) as an example.
@@ -86,7 +86,7 @@ With agentgateway installed, point kagent at the agentgateway proxy instead of d
{{< /tab >}}
{{< /tabs >}}
-4. [Open the kagent UI]({{< relref "/kagent/0.x/observability/launch-ui" >}}).
+4. [Open the kagent UI]({{< link path="observability/launch-ui" >}}).
5. Start a chat with an agent such as `k8s-agent` to confirm that requests flow through agentgateway.

diff --git a/docs-site/content/kagent/0.x/examples/crewai-byo.md b/docs-site/content/kagent/0.x/examples/crewai-byo.md
index a0f763b9..5033e7d8 100644
--- a/docs-site/content/kagent/0.x/examples/crewai-byo.md
+++ b/docs-site/content/kagent/0.x/examples/crewai-byo.md
@@ -6,13 +6,13 @@ weight: 1
author: kagent.dev
---
-Bring your own custom agents. This example uses [CrewAI](https://www.crewai.com/), but you can also try out the [ADK guide]({{< relref "/kagent/0.x/examples/a2a-byo/" >}}) or [LangGraph guide]({{< relref "/kagent/0.x/examples/langchain-byo/" >}}). Such frameworks give you more control over the agent behavior and are well-suited for complex workflows and integration with external systems and APIs.
+Bring your own custom agents. This example uses [CrewAI](https://www.crewai.com/), but you can also try out the [ADK guide]({{< link path="examples/a2a-byo/" >}}) or [LangGraph guide]({{< link path="examples/langchain-byo/" >}}). Such frameworks give you more control over the agent behavior and are well-suited for complex workflows and integration with external systems and APIs.
Unlike declarative agents that are defined by kagent resources with components such as system instructions, models, and tools written inline, these BYO agents give you full control over agent logic. If you have your own agent, no need to decompose its functions into separate kagent resources. kagent can invoke your agent directly through the A2A protocol.
## Prerequisites
-Install kagent by following the [quick start]({{< relref "/kagent/0.x/getting-started/quickstart" >}}) guide.
+Install kagent by following the [quick start]({{< link path="getting-started/quickstart" >}}) guide.
## Building a custom agent
@@ -148,7 +148,7 @@ You can invoke the agent in several ways, including the kagent dashboard, kagent
### Dashboard
-Launch the dashboard with `kagent dashboard`, find your `research-crew`, and start chatting. For complete steps, see the [Your First Agent]({{< relref "/kagent/0.x/getting-started/first-agent" >}}) guide.
+Launch the dashboard with `kagent dashboard`, find your `research-crew`, and start chatting. For complete steps, see the [Your First Agent]({{< link path="getting-started/first-agent" >}}) guide.
### kagent CLI
diff --git a/docs-site/content/kagent/0.x/examples/discord-a2a.md b/docs-site/content/kagent/0.x/examples/discord-a2a.md
index 7ef4e775..5dc298f3 100644
--- a/docs-site/content/kagent/0.x/examples/discord-a2a.md
+++ b/docs-site/content/kagent/0.x/examples/discord-a2a.md
@@ -8,7 +8,7 @@ author: kagent.dev
};
-kagent enables you to create AI agents that run inside your Kubernetes cluster. They can access a variety of [built-in tools]({{< relref "/kagent/0.x/concepts/tools" >}}) and use other [external tools via MCP]({{< relref "/kagent/0.x/examples/documentation" >}}).
+kagent enables you to create AI agents that run inside your Kubernetes cluster. They can access a variety of [built-in tools]({{< link path="concepts/tools" >}}) and use other [external tools via MCP]({{< link path="examples/documentation" >}}).
This guide shows how to connect a Discord bot to one of your agents using the A2A protocol, enabling natural conversations and command execution inside Discord.
@@ -129,7 +129,7 @@ When a message is received, it’s sent to the A2A endpoint (`KAGENT_A2A_URL`),
## Agent Setup
-If you haven’t deployed your agent yet, follow the instructions in [Deploying an Agent]({{< relref "/kagent/0.x/examples/slack-a2a#deploying-an-agent" >}}). You can reuse the same agent across Slack and Discord integrations.
+If you haven’t deployed your agent yet, follow the instructions in [Deploying an Agent]({{< link path="examples/slack-a2a#deploying-an-agent" >}}). You can reuse the same agent across Slack and Discord integrations.
Be sure to port-forward your agent if running locally:
diff --git a/docs-site/content/kagent/0.x/examples/langchain-byo.md b/docs-site/content/kagent/0.x/examples/langchain-byo.md
index b5a8ea39..1a898790 100644
--- a/docs-site/content/kagent/0.x/examples/langchain-byo.md
+++ b/docs-site/content/kagent/0.x/examples/langchain-byo.md
@@ -10,7 +10,7 @@ You can bring your own LangGraph agent to kagent by configuring the kagentCheckp
## Prerequisites
-Install kagent by following the [quick start]({{< relref "/kagent/0.x/getting-started/quickstart" >}}) guide.
+Install kagent by following the [quick start]({{< link path="getting-started/quickstart" >}}) guide.
## Building a LangGraph agent
@@ -125,7 +125,7 @@ You can invoke the agent through the kagent dashboard or kagent CLI.
### Dashboard
-Launch the dashboard with `kagent dashboard`, find your `langgraph-agent`, and start chatting. For complete steps, see the [Your First Agent]({{< relref "/kagent/0.x/getting-started/first-agent" >}}) guide.
+Launch the dashboard with `kagent dashboard`, find your `langgraph-agent`, and start chatting. For complete steps, see the [Your First Agent]({{< link path="getting-started/first-agent" >}}) guide.

diff --git a/docs-site/content/kagent/0.x/examples/skills.md b/docs-site/content/kagent/0.x/examples/skills.md
index 5fcab664..897cf325 100644
--- a/docs-site/content/kagent/0.x/examples/skills.md
+++ b/docs-site/content/kagent/0.x/examples/skills.md
@@ -15,9 +15,9 @@ In this guide, you learn how to add container-based skills to your agents in kag
## Before you begin
-1. Install kagent by following the [quick start]({{< relref "/kagent/0.x/getting-started/quickstart" >}}) guide.
+1. Install kagent by following the [quick start]({{< link path="getting-started/quickstart" >}}) guide.
-2. Review the concepts of [agents and skills]({{< relref "/kagent/0.x/concepts/agents" >}}) in kagent.
+2. Review the concepts of [agents and skills]({{< link path="concepts/agents" >}}) in kagent.
## Container-based skills
@@ -372,6 +372,6 @@ When you're done, you can clean up the resources that you created.
## Next steps
-- Learn more about [agents]({{< relref "/kagent/0.x/concepts/agents" >}}) and their components
-- Explore [tools]({{< relref "/kagent/0.x/concepts/tools" >}}) available in kagent
-- Check out other [examples]({{< relref "/kagent/0.x/examples" >}}) to see different agent configurations
+- Learn more about [agents]({{< link path="concepts/agents" >}}) and their components
+- Explore [tools]({{< link path="concepts/tools" >}}) available in kagent
+- Check out other [examples]({{< link path="examples" >}}) to see different agent configurations
diff --git a/docs-site/content/kagent/0.x/examples/slack-a2a.md b/docs-site/content/kagent/0.x/examples/slack-a2a.md
index 22e63fc9..82b6f922 100644
--- a/docs-site/content/kagent/0.x/examples/slack-a2a.md
+++ b/docs-site/content/kagent/0.x/examples/slack-a2a.md
@@ -8,7 +8,7 @@ author: kagent.dev
};
-kagent enables you to create AI agents that run inside your Kubernetes cluster. They have access to a variety of [built-in tools]({{< relref "/kagent/0.x/concepts/tools" >}}) like Kubernetes, Istio, Grafana, Prometheus, Argo and can be extended with any other tools [using MCP]({{< relref "/kagent/0.x/examples/documentation" >}}).
+kagent enables you to create AI agents that run inside your Kubernetes cluster. They have access to a variety of [built-in tools]({{< link path="concepts/tools" >}}) like Kubernetes, Istio, Grafana, Prometheus, Argo and can be extended with any other tools [using MCP]({{< link path="examples/documentation" >}}).

diff --git a/docs-site/content/kagent/0.x/examples/telegram-bot.md b/docs-site/content/kagent/0.x/examples/telegram-bot.md
index bb3af6c3..c145d0f9 100644
--- a/docs-site/content/kagent/0.x/examples/telegram-bot.md
+++ b/docs-site/content/kagent/0.x/examples/telegram-bot.md
@@ -98,7 +98,7 @@ spec:
EOF
```
-Notice `requireApproval` — anything destructive (deleting resources, applying manifests, Helm upgrades) goes through [Human-in-the-Loop]({{< relref "/kagent/0.x/examples/human-in-the-loop" >}}) approval in the kagent UI first. Nobody's accidentally nuking prod from a Telegram chat.
+Notice `requireApproval` — anything destructive (deleting resources, applying manifests, Helm upgrades) goes through [Human-in-the-Loop]({{< link path="examples/human-in-the-loop" >}}) approval in the kagent UI first. Nobody's accidentally nuking prod from a Telegram chat.
Verify it's working:
diff --git a/docs-site/content/kagent/0.x/getting-started/first-agent.md b/docs-site/content/kagent/0.x/getting-started/first-agent.md
index 3e2f4a10..308cd9c4 100644
--- a/docs-site/content/kagent/0.x/getting-started/first-agent.md
+++ b/docs-site/content/kagent/0.x/getting-started/first-agent.md
@@ -10,7 +10,7 @@ In this guide, you'll learn how to create your first AI agent using the kagent d
## Prerequisites
-Before you begin make sure you have a Kubernetes cluster with kagent installed. If you haven't done this yet, check out the [installation guide]({{< relref "/kagent/0.x/introduction/installation" >}}) or the [quickstart guide]({{< relref "/kagent/0.x/getting-started/quickstart" >}}).
+Before you begin make sure you have a Kubernetes cluster with kagent installed. If you haven't done this yet, check out the [installation guide]({{< link path="introduction/installation" >}}) or the [quickstart guide]({{< link path="getting-started/quickstart" >}}).
We'll be working in the kagent dashboard, so use the kagent CLI to open the dashboard:
@@ -90,5 +90,5 @@ Now that you set up all the details for your agent, you're ready to finish creat
## Next Steps
-- Learn more about [Core Concepts]({{< relref "/kagent/0.x/concepts" >}})
+- Learn more about [Core Concepts]({{< link path="concepts" >}})
- Join our [Community](https://discord.gg/Fu3k65f2k3)
diff --git a/docs-site/content/kagent/0.x/getting-started/first-mcp-tool.md b/docs-site/content/kagent/0.x/getting-started/first-mcp-tool.md
index 7781acd1..1c6cd1eb 100644
--- a/docs-site/content/kagent/0.x/getting-started/first-mcp-tool.md
+++ b/docs-site/content/kagent/0.x/getting-started/first-mcp-tool.md
@@ -12,7 +12,7 @@ In this guide, you'll learn how to add an MCP tool to your first AI agent using
## Prerequisites
-1. Install kagent in a Kubernetes cluster. If you haven't done this yet, check out the [installation guide]({{< relref "/kagent/0.x/introduction/installation" >}}) or the [quickstart guide]({{< relref "/kagent/0.x/getting-started/quickstart" >}}).
+1. Install kagent in a Kubernetes cluster. If you haven't done this yet, check out the [installation guide]({{< link path="introduction/installation" >}}) or the [quickstart guide]({{< link path="getting-started/quickstart" >}}).
2. Make sure that you have the kagent custom resources in your cluster.
@@ -22,7 +22,7 @@ In this guide, you'll learn how to add an MCP tool to your first AI agent using
## Creating an agent
-To create an agent, follow the [Your First Agent guide]({{< relref "/kagent/0.x/getting-started/first-agent" >}}).
+To create an agent, follow the [Your First Agent guide]({{< link path="getting-started/first-agent" >}}).
Take a look at the Agent custom resource for your first agent, such as with the following command.
@@ -177,5 +177,5 @@ Now let's try our agent out with the fetch tool.
## Next Steps
-- Learn more about [Core Concepts]({{< relref "/kagent/0.x/concepts" >}})
+- Learn more about [Core Concepts]({{< link path="concepts" >}})
- Join our [Community](https://discord.gg/Fu3k65f2k3)
diff --git a/docs-site/content/kagent/0.x/getting-started/local-development.md b/docs-site/content/kagent/0.x/getting-started/local-development.md
index da2ec1b8..47c3e9cd 100644
--- a/docs-site/content/kagent/0.x/getting-started/local-development.md
+++ b/docs-site/content/kagent/0.x/getting-started/local-development.md
@@ -6,13 +6,13 @@ weight: 4
author: kagent.dev
---
-In this guide, you'll learn how to develop, build and run an AI agent locally using kagent CLI, without a Kubernetes cluster. This guide is meant for developers familiar with Python. You can also create declarative agents without writing a single line of code, by following the [Your First Agent]({{< relref "/kagent/0.x/getting-started/first-agent" >}}) guide.
+In this guide, you'll learn how to develop, build and run an AI agent locally using kagent CLI, without a Kubernetes cluster. This guide is meant for developers familiar with Python. You can also create declarative agents without writing a single line of code, by following the [Your First Agent]({{< link path="getting-started/first-agent" >}}) guide.
## Prerequisites
Before you begin make sure you have the following prerequisites installed:
-- [kagent CLI]({{< relref "/kagent/0.x/introduction/installation" >}})
+- [kagent CLI]({{< link path="introduction/installation" >}})
- [Python](https://www.python.org/)
- [Docker](https://www.docker.com/) and [Docker compose](https://docs.docker.com/compose/)
diff --git a/docs-site/content/kagent/0.x/getting-started/quickstart.md b/docs-site/content/kagent/0.x/getting-started/quickstart.md
index cd91017f..6f0c76ae 100644
--- a/docs-site/content/kagent/0.x/getting-started/quickstart.md
+++ b/docs-site/content/kagent/0.x/getting-started/quickstart.md
@@ -141,12 +141,12 @@ Interact with kagent in your terminal.
## Next Steps
-- Create your [first agent]({{< relref "/kagent/0.x/getting-started/first-agent" >}})
-- Learn about [Core Concepts]({{< relref "/kagent/0.x/concepts" >}})
+- Create your [first agent]({{< link path="getting-started/first-agent" >}})
+- Learn about [Core Concepts]({{< link path="concepts" >}})
- Join our [Community](https://discord.gg/Fu3k65f2k3)
## Need Help?
- Visit our [GitHub repository](https://github.com/kagent-dev/kagent)
- Ask a question on [Discord](https://discord.gg/Fu3k65f2k3)
-- Check out the [FAQ]({{< relref "/kagent/0.x/resources/faq" >}})
\ No newline at end of file
+- Check out the [FAQ]({{< link path="resources/faq" >}})
\ No newline at end of file
diff --git a/docs-site/content/kagent/0.x/introduction/_index.md b/docs-site/content/kagent/0.x/introduction/_index.md
index 1f86319e..119de4c9 100644
--- a/docs-site/content/kagent/0.x/introduction/_index.md
+++ b/docs-site/content/kagent/0.x/introduction/_index.md
@@ -5,4 +5,4 @@ weight: 1
author: kagent.dev
---
-Welcome to kagent! Start here to understand what kagent is and how to install it. To follow the roadmap or help improve kagent, see [Community and Contributing]({{< relref "/kagent/0.x/resources/community" >}}).
+Welcome to kagent! Start here to understand what kagent is and how to install it. To follow the roadmap or help improve kagent, see [Community and Contributing]({{< link path="resources/community" >}}).
diff --git a/docs-site/content/kagent/0.x/introduction/installation.md b/docs-site/content/kagent/0.x/introduction/installation.md
index 7aa93038..8eba5679 100644
--- a/docs-site/content/kagent/0.x/introduction/installation.md
+++ b/docs-site/content/kagent/0.x/introduction/installation.md
@@ -5,13 +5,13 @@ weight: 1
author: kagent.dev
---
-This guide covers ways to install and configure kagent in your Kubernetes environment. For a quick setup, check out our [Quick Start Guide]({{< relref "/kagent/0.x/getting-started/quickstart" >}}). For enterpise offerings, check out [Solo Enterprise for kagent]({{< relref "/kagent/0.x/introduction/what-is-kagent/#enterprise-distributions" >}}).
+This guide covers ways to install and configure kagent in your Kubernetes environment. For a quick setup, check out our [Quick Start Guide]({{< link path="getting-started/quickstart" >}}). For enterpise offerings, check out [Solo Enterprise for kagent]({{< link path="introduction/what-is-kagent/#enterprise-distributions" >}}).
## Installation Methods
Install kagent by using the kagent CLI or Helm.
-> **Note**: As of [version 0.7]({{< relref "/kagent/0.x/resources/release-notes#kmcp-installed-by-default" >}}), the kmcp subproject is included by default with kagent. To use an existing kmcp installation that you already set up separately, set `kmcp.enabled=false` in your `values.yaml` file or `--set` commands for both the `kagent` and `kagent-crds` charts.
+> **Note**: As of [version 0.7]({{< link path="resources/release-notes#kmcp-installed-by-default" >}}), the kmcp subproject is included by default with kagent. To use an existing kmcp installation that you already set up separately, set `kmcp.enabled=false` in your `values.yaml` file or `--set` commands for both the `kagent` and `kagent-crds` charts.
### Using kagent CLI (Recommended)
@@ -66,7 +66,7 @@ Another way to install kagent is using Helm.
--create-namespace
```
-2. Optionally prepare a Helm values file or `--set` flags to use for your installation. For example, you might set up your default LLM provider, or configure resource requests and limits or disable the default agents. For options, refer to the [Helm reference docs]({{< relref "/kagent/0.x/resources/helm" >}}).
+2. Optionally prepare a Helm values file or `--set` flags to use for your installation. For example, you might set up your default LLM provider, or configure resource requests and limits or disable the default agents. For options, refer to the [Helm reference docs]({{< link path="resources/helm" >}}).
{{< tabs >}}
{{< tab name="OpenAI" >}}
@@ -185,7 +185,7 @@ Review the following advanced configuration options that you might want to set u
### Enable AgentHarness support
-`AgentHarness` resources run on [Agent Substrate]({{< relref "/kagent/0.x/concepts/agent-substrate" >}}). To enable them, install Agent Substrate and turn on the substrate integration in kagent. When the integration is disabled, the controller cannot provision AgentHarness resources.
+`AgentHarness` resources run on [Agent Substrate]({{< link path="concepts/agent-substrate" >}}). To enable them, install Agent Substrate and turn on the substrate integration in kagent. When the integration is disabled, the controller cannot provision AgentHarness resources.
1. Install Agent Substrate (CRDs, then the control plane and data plane).
@@ -228,11 +228,11 @@ Review the following advanced configuration options that you might want to set u
Pin the kagent chart to v0.9.9 or later — earlier versions do not include the `controller.substrate.*` and `substrateWorkerPool.*` values.
-For an end-to-end walkthrough on a kind cluster, see the [Agent Substrate example]({{< relref "/kagent/0.x/examples/agent-substrate" >}}). For more information about creating harness resources, see [Agent Harness]({{< relref "/kagent/0.x/examples/agent-harness" >}}).
+For an end-to-end walkthrough on a kind cluster, see the [Agent Substrate example]({{< link path="examples/agent-substrate" >}}). For more information about creating harness resources, see [Agent Harness]({{< link path="examples/agent-harness" >}}).
### Database configuration
-For production environments, set up kagent with an external PostgreSQL instance. For more information, see the [Database configuration guide]({{< relref "/kagent/0.x/operations/operational-considerations/#database-configuration" >}}).
+For production environments, set up kagent with an external PostgreSQL instance. For more information, see the [Database configuration guide]({{< link path="operations/operational-considerations/#database-configuration" >}}).
### Configure controller environment variables
@@ -303,9 +303,9 @@ This example loads all key-value pairs from the `controller-secrets` secret as e
## Uninstallation
-Refer to the [Uninstall]({{< relref "/kagent/0.x/operations/uninstall" >}}) guide.
+Refer to the [Uninstall]({{< link path="operations/uninstall" >}}) guide.
## Next Steps
-- [Create your first agent]({{< relref "/kagent/0.x/getting-started/first-agent" >}})
+- [Create your first agent]({{< link path="getting-started/first-agent" >}})
- [Explore available agents](https://kagent.dev/agents)
diff --git a/docs-site/content/kagent/0.x/introduction/what-is-kagent.md b/docs-site/content/kagent/0.x/introduction/what-is-kagent.md
index c61b9728..72dc0706 100644
--- a/docs-site/content/kagent/0.x/introduction/what-is-kagent.md
+++ b/docs-site/content/kagent/0.x/introduction/what-is-kagent.md
@@ -62,7 +62,7 @@ Check out [Solo Enterprise for kagent](https://www.solo.io/products/kagent-enter
## Getting Started
-To start using kagent in your environment, check out the [Quick Start Guide]({{< relref "/kagent/0.x/getting-started/quickstart" >}}) guide. For a deeper understanding of how kagent works, refer to the [kagent architecture]({{< relref "/kagent/0.x/concepts/architecture" >}}).
+To start using kagent in your environment, check out the [Quick Start Guide]({{< link path="getting-started/quickstart" >}}) guide. For a deeper understanding of how kagent works, refer to the [kagent architecture]({{< link path="concepts/architecture" >}}).
Ready to contribute? Visit our [Github repository](https://github.com/kagent-dev) to learn how you can help expand the ecosystem of cloud-native AI agents.
@@ -71,5 +71,5 @@ Ready to contribute? Visit our [Github repository](https://github.com/kagent-dev
Join the kagent community:
- Explore our repositories on [GitHub](https://github.com/kagent-dev)
- Join the discussion in the #kagent channel on CNCF Slack
-- Check our [FAQ]({{< relref "/kagent/0.x/resources/faq" >}}) for common questions
+- Check our [FAQ]({{< link path="resources/faq" >}}) for common questions
- Follow our [Feature Roadmap](https://github.com/kagent-dev/kagent/blob/main/README.md#roadmap) for upcoming developments
diff --git a/docs-site/content/kagent/0.x/not-in-version.md b/docs-site/content/kagent/0.x/not-in-version.md
index 306e4dc5..30a0b1be 100644
--- a/docs-site/content/kagent/0.x/not-in-version.md
+++ b/docs-site/content/kagent/0.x/not-in-version.md
@@ -5,4 +5,4 @@ build:
list: never
---
-This topic doesn't exist in this version of the kagent docs. Use the version switcher above to go back to a version where it's available, or browse the [kagent docs]({{< relref "/kagent/0.x" >}}) landing page.
+This topic doesn't exist in this version of the kagent docs. Use the version switcher above to go back to a version where it's available, or browse the [kagent docs]({{< link path="" >}}) landing page.
diff --git a/docs-site/content/kagent/0.x/observability/audit-prompts.md b/docs-site/content/kagent/0.x/observability/audit-prompts.md
index 73cdd9a8..d04b306d 100644
--- a/docs-site/content/kagent/0.x/observability/audit-prompts.md
+++ b/docs-site/content/kagent/0.x/observability/audit-prompts.md
@@ -20,7 +20,7 @@ kagent supports logging input/output messages for the following LLM providers:
## Before you begin
-1. [Install kagent]({{< relref "/kagent/0.x/introduction/installation" >}}) in your cluster.
+1. [Install kagent]({{< link path="introduction/installation" >}}) in your cluster.
2. Add the OpenTelemetry Helm repository.
diff --git a/docs-site/content/kagent/0.x/observability/launch-ui.md b/docs-site/content/kagent/0.x/observability/launch-ui.md
index edc687da..50905474 100644
--- a/docs-site/content/kagent/0.x/observability/launch-ui.md
+++ b/docs-site/content/kagent/0.x/observability/launch-ui.md
@@ -51,6 +51,6 @@ If you prefer to manually set up port-forwarding, or if you're on a platform whe
You can use the UI to view and manage your agents, tools, and models. For more information, see the following guides:
-- [Create your first agent]({{< relref "/kagent/0.x/getting-started/first-agent" >}})
-- [Add MCP tools to your agents]({{< relref "/kagent/0.x/getting-started/first-mcp-tool" >}})
-- [Configure LLM providers]({{< relref "/kagent/0.x/supported-providers" >}})
+- [Create your first agent]({{< link path="getting-started/first-agent" >}})
+- [Add MCP tools to your agents]({{< link path="getting-started/first-mcp-tool" >}})
+- [Configure LLM providers]({{< link path="supported-providers" >}})
diff --git a/docs-site/content/kagent/0.x/observability/tracing.md b/docs-site/content/kagent/0.x/observability/tracing.md
index 00886605..30b176f7 100644
--- a/docs-site/content/kagent/0.x/observability/tracing.md
+++ b/docs-site/content/kagent/0.x/observability/tracing.md
@@ -9,7 +9,7 @@ Set up tracing for your kagent agents.
## Before you begin
-[Install kagent]({{< relref "/kagent/0.x/introduction/installation" >}}).
+[Install kagent]({{< link path="introduction/installation" >}}).
## Install Jaeger
@@ -82,7 +82,7 @@ Now that you installed kagent with Jaeger, learn how to trace requests to an age
### Generate tracing data
-To generate tracing data, you can chat with a pre-configured agent such as `k8s-agent`. For more information about agents, see the [Your First Agent]({{< relref "/kagent/0.x/getting-started/first-agent" >}}) guide.
+To generate tracing data, you can chat with a pre-configured agent such as `k8s-agent`. For more information about agents, see the [Your First Agent]({{< link path="getting-started/first-agent" >}}) guide.
1. Launch the kagent dashboard.
@@ -135,11 +135,11 @@ That's it! You've now traced your first agent.
## Next Steps
-- Learn about [Core Concepts]({{< relref "/kagent/0.x/concepts" >}})
-- Try out some [Example]({{< relref "/kagent/0.x/examples" >}}) guides
+- Learn about [Core Concepts]({{< link path="concepts" >}})
+- Try out some [Example]({{< link path="examples" >}}) guides
## Need Help?
- Visit our [GitHub repository](https://github.com/kagent-dev/kagent)
- Ask a question on [Discord](https://discord.gg/Fu3k65f2k3)
-- Check out the [FAQ]({{< relref "/kagent/0.x/resources/faq" >}})
\ No newline at end of file
+- Check out the [FAQ]({{< link path="resources/faq" >}})
\ No newline at end of file
diff --git a/docs-site/content/kagent/0.x/operations/operational-considerations.md b/docs-site/content/kagent/0.x/operations/operational-considerations.md
index d768ff64..ee83341a 100644
--- a/docs-site/content/kagent/0.x/operations/operational-considerations.md
+++ b/docs-site/content/kagent/0.x/operations/operational-considerations.md
@@ -89,7 +89,7 @@ urlFile > url > bundled connection string
The bundled PostgreSQL instance is deployed by default (`database.postgres.bundled.enabled: true`). The database name, username, and password are all hardcoded to `kagent`. Credentials are stored in a Kubernetes Secret.
-You can customize the storage size and image of the bundled instance when you [install]({{< relref "/kagent/0.x/introduction/installation" >}}) or upgrade kagent.
+You can customize the storage size and image of the bundled instance when you [install]({{< link path="introduction/installation" >}}) or upgrade kagent.
1. Add the bundled database settings to your Helm values file for kagent.
diff --git a/docs-site/content/kagent/0.x/operations/uninstall.md b/docs-site/content/kagent/0.x/operations/uninstall.md
index a66074fa..ecf6fb83 100644
--- a/docs-site/content/kagent/0.x/operations/uninstall.md
+++ b/docs-site/content/kagent/0.x/operations/uninstall.md
@@ -17,7 +17,7 @@ Remove kagent from your Kubernetes cluster using the kagent CLI or Helm.
## Uninstall with the kagent CLI
-Remove kagent by using the CLI. For more options, see the [`kagent uninstall` command reference]({{< relref "/kagent/0.x/resources/cli/kagent-uninstall" >}}).
+Remove kagent by using the CLI. For more options, see the [`kagent uninstall` command reference]({{< link path="resources/cli/kagent-uninstall" >}}).
```bash
kagent uninstall
diff --git a/docs-site/content/kagent/0.x/operations/upgrade.md b/docs-site/content/kagent/0.x/operations/upgrade.md
index 0c7099cb..52fbc59d 100644
--- a/docs-site/content/kagent/0.x/operations/upgrade.md
+++ b/docs-site/content/kagent/0.x/operations/upgrade.md
@@ -15,12 +15,12 @@ Follow these steps to upgrade kagent to the latest version and keep your cluster
export NEW_VERSION=
```
-2. Read the [release notes]({{< relref "/kagent/0.x/resources/release-notes" >}}) for the version you are upgrading to. Pay attention to any breaking changes or deprecations that might affect your configuration.
+2. Read the [release notes]({{< link path="resources/release-notes" >}}) for the version you are upgrading to. Pay attention to any breaking changes or deprecations that might affect your configuration.
3. Back up your current configuration, including the following:
- Agent definitions
- Any custom settings
- - PostgreSQL database: You can take a snapshot now so that you have a restore point if the upgrade fails. For the database connection string, see [Database configuration]({{< relref "/kagent/0.x/operations/operational-considerations#database-configuration" >}}).
+ - PostgreSQL database: You can take a snapshot now so that you have a restore point if the upgrade fails. For the database connection string, see [Database configuration]({{< link path="operations/operational-considerations#database-configuration" >}}).
```bash
pg_dump "postgres://:@:5432/" \
@@ -28,7 +28,7 @@ Follow these steps to upgrade kagent to the latest version and keep your cluster
--file=kagent-pre-upgrade-snapshot.dump
```
-4. **v0.9.0 and later**: You must be running at least v0.8.0 before upgrading to v0.9.0. Check the [release notes]({{< relref "/kagent/0.x/resources/release-notes#v09" >}}) for 0.9-specific upgrades related to database migrations and RBAC scope.
+4. **v0.9.0 and later**: You must be running at least v0.8.0 before upgrading to v0.9.0. Check the [release notes]({{< link path="resources/release-notes#v09" >}}) for 0.9-specific upgrades related to database migrations and RBAC scope.
## Upgrade kagent
@@ -56,7 +56,7 @@ Follow these steps to upgrade kagent to the latest version and keep your cluster
3. Make any changes that you want by editing your `values.yaml` Helm values file or preparing `--set` flags for the upgrade commands.
- > **Note**: As of [version 0.7]({{< relref "/kagent/0.x/resources/release-notes#kmcp-installed-by-default" >}}), the kmcp subproject is included by default with kagent. To use an existing kmcp installation that you already set up separately, set `kmcp.enabled=false` in your `values.yaml` file or `--set` commands for both the `kagent` and `kagent-crds` charts.
+ > **Note**: As of [version 0.7]({{< link path="resources/release-notes#kmcp-installed-by-default" >}}), the kmcp subproject is included by default with kagent. To use an existing kmcp installation that you already set up separately, set `kmcp.enabled=false` in your `values.yaml` file or `--set` commands for both the `kagent` and `kagent-crds` charts.
4. Upgrade the kagent-crds chart.
@@ -171,7 +171,7 @@ For example, `v0.9.9` has migrations up to `000005_a2a_protocol_version.up.sql`
export ROLLBACK_MIGRATION_VERSION=
```
-5. Reset the core track. The `github://` source references the migration files directly from the release tag without a local checkout. For the database connection string, see [Database configuration]({{< relref "/kagent/0.x/operations/operational-considerations#database-configuration" >}}).
+5. Reset the core track. The `github://` source references the migration files directly from the release tag without a local checkout. For the database connection string, see [Database configuration]({{< link path="operations/operational-considerations#database-configuration" >}}).
```bash
migrate \
-source "github://kagent-dev/kagent/go/core/pkg/migrations/core#v$CURRENT_VERSION" \
diff --git a/docs-site/content/kagent/0.x/resources/_index.md b/docs-site/content/kagent/0.x/resources/_index.md
index 659c77ad..789e3b5c 100644
--- a/docs-site/content/kagent/0.x/resources/_index.md
+++ b/docs-site/content/kagent/0.x/resources/_index.md
@@ -5,4 +5,4 @@ weight: 7
author: kagent.dev
---
-Find helpful resources and FAQs for kagent. New to kagent? Start with the [Quick Start Guide]({{< relref "/kagent/0.x/getting-started/quickstart" >}}).
+Find helpful resources and FAQs for kagent. New to kagent? Start with the [Quick Start Guide]({{< link path="getting-started/quickstart" >}}).
diff --git a/docs-site/content/kagent/0.x/resources/faq.md b/docs-site/content/kagent/0.x/resources/faq.md
index 822fa07a..948151f8 100644
--- a/docs-site/content/kagent/0.x/resources/faq.md
+++ b/docs-site/content/kagent/0.x/resources/faq.md
@@ -8,7 +8,7 @@ author: kagent.dev
## What's the best way to get started with kagent?
-The best way to get started with kagent is to follow the [quickstart guide]({{< relref "/kagent/0.x/getting-started/quickstart" >}}). This will give you a basic understanding of how kagent works and how to use it.
+The best way to get started with kagent is to follow the [quickstart guide]({{< link path="getting-started/quickstart" >}}). This will give you a basic understanding of how kagent works and how to use it.
## What differentiates kagent from other LLM frameworks?
diff --git a/docs-site/content/kagent/0.x/resources/release-notes.md b/docs-site/content/kagent/0.x/resources/release-notes.md
index fbe12d16..3344497f 100644
--- a/docs-site/content/kagent/0.x/resources/release-notes.md
+++ b/docs-site/content/kagent/0.x/resources/release-notes.md
@@ -16,7 +16,7 @@ Review this summary of significant changes from kagent version 0.8 to v0.9.
**Before you upgrade:**
* You must be running at least v0.8.0 before upgrading to v0.9.0.
-* Back up your PostgreSQL database before upgrading. For details on your database configuration, see the [Database configuration guide]({{< relref "/kagent/0.x/operations/operational-considerations/#database-configuration" >}}).
+* Back up your PostgreSQL database before upgrading. For details on your database configuration, see the [Database configuration guide]({{< link path="operations/operational-considerations/#database-configuration" >}}).
* The `rbac.clusterScoped` Helm value is removed. RBAC scope is now derived from `rbac.namespaces`. If you set `rbac.clusterScoped` in your Helm values, update your configuration to use `rbac.namespaces` instead.
**What's included:**
@@ -159,7 +159,7 @@ You can now use two Human-in-the-Loop mechanisms that can pause agent execution
**Ask User** — A built-in `ask_user` tool is automatically added to every agent. Agents can pose questions to users with predefined choices (single-select, multi-select) or free-text input during execution.
-For more information, see the [Human-in-the-Loop example]({{< relref "/kagent/0.x/examples/human-in-the-loop" >}}) and the [blog post](https://kagent.dev/blog/human-in-the-loop-kagent).
+For more information, see the [Human-in-the-Loop example]({{< link path="examples/human-in-the-loop" >}}) and the [blog post](https://kagent.dev/blog/human-in-the-loop-kagent).
### Agent Memory
@@ -169,7 +169,7 @@ When you enable memory on an agent, it receives three additional tools: `save_me
You can configure memory in the Agent CR or through the UI when you create or edit an agent by selecting an embedding model and TTL.
-For more information, see [Agent Memory]({{< relref "/kagent/0.x/concepts/agent-memory" >}}).
+For more information, see [Agent Memory]({{< link path="concepts/agent-memory" >}}).
### Go ADK Runtime
@@ -186,7 +186,7 @@ spec:
The Go ADK includes built-in tools: `SkillsTool`, `BashTool`, `ReadFile`, `WriteFile`, and `EditFile`.
-For more information, see [Agents]({{< relref "/kagent/0.x/concepts/agents#runtime" >}}) and the [blog post](https://kagent.dev/blog/go-vs-python-runtime).
+For more information, see [Agents]({{< link path="concepts/agents#runtime" >}}) and the [blog post](https://kagent.dev/blog/go-vs-python-runtime).
### Agents as MCP Servers
@@ -201,7 +201,7 @@ You can load skills from two sources.
- **OCI images.** Container images containing skill files.
- **Git repositories.** Clone skills directly from Git repos, with support for private repos via HTTPS token or SSH key authentication.
-For more information, see [Agents]({{< relref "/kagent/0.x/concepts/agents#git-based-skills" >}}).
+For more information, see [Agents]({{< link path="concepts/agents#git-based-skills" >}}).
### Go Workspace Restructure
@@ -219,13 +219,13 @@ Agent system messages now support Go `text/template` syntax. You can store commo
The `kagent-builtin-prompts` ConfigMap ships with five reusable templates: `skills-usage`, `tool-usage-best-practices`, `safety-guardrails`, `kubernetes-context`, and `a2a-communication`.
-For more information, see [Agents]({{< relref "/kagent/0.x/concepts/agents#prompt-templates" >}}).
+For more information, see [Agents]({{< link path="concepts/agents#prompt-templates" >}}).
### Context Management
Long conversations can now be automatically compacted to stay within LLM context windows. You can configure the `context.compaction` field to enable periodic summarization of older events while preserving key information.
-For more information, see [Agents]({{< relref "/kagent/0.x/concepts/agents#context-management" >}}).
+For more information, see [Agents]({{< link path="concepts/agents#context-management" >}}).
### AWS Bedrock Support
@@ -252,7 +252,7 @@ SQLite support has been removed from kagent. PostgreSQL is now the only supporte
**Migration:**
-If you were using the default SQLite backend, no migration is needed. The bundled PostgreSQL is deployed automatically. You can optionally customize the bundled instance via `database.postgres.bundled.*` (storage size, image) as needed. See the [Database configuration guide]({{< relref "/kagent/0.x/operations/operational-considerations/#database-configuration" >}}) for details.
+If you were using the default SQLite backend, no migration is needed. The bundled PostgreSQL is deployed automatically. You can optionally customize the bundled instance via `database.postgres.bundled.*` (storage size, image) as needed. See the [Database configuration guide]({{< link path="operations/operational-considerations/#database-configuration" >}}) for details.
Note that for production deployments, use your own external PostgreSQL instance. If you already are, you can keep your `database.postgres.url` or `database.postgres.urlFile` settings as before. If your external PostgreSQL has the pgvector extension and you were using vector-based memory features, set `database.postgres.vectorEnabled: true` since the default has changed to `false`.
@@ -306,7 +306,7 @@ helm upgrade --install kagent oci://ghcr.io/kagent-dev/kagent/helm/kagent \
Develop and test agents locally on your machine without needing a Kubernetes cluster. As part of this feature, the `kagent` CLI includes new commands to scaffold, build, run, and deploy agents.
-For more information, see the [local development]({{< relref "/kagent/0.x/getting-started/local-development" >}}) guide.
+For more information, see the [local development]({{< link path="getting-started/local-development" >}}) guide.
### Discovery label
@@ -654,7 +654,7 @@ This change supports the new type for BYO agents.
A new agent type has been added to the Agents API so that you can bring your own (BYO) agent. The agent must be written in ADK, with other frameworks under development.
-BYO Agent example configuration. For more information, see the [BYO Agent]({{< relref "/kagent/0.x/examples/a2a-byo" >}}) guide.
+BYO Agent example configuration. For more information, see the [BYO Agent]({{< link path="examples/a2a-byo" >}}) guide.
```yaml
apiVersion: kagent.dev/v1alpha2
diff --git a/docs-site/content/kagent/0.x/supported-providers/amazon-bedrock.md b/docs-site/content/kagent/0.x/supported-providers/amazon-bedrock.md
index 7d63fbc6..7d6c60b4 100644
--- a/docs-site/content/kagent/0.x/supported-providers/amazon-bedrock.md
+++ b/docs-site/content/kagent/0.x/supported-providers/amazon-bedrock.md
@@ -97,7 +97,7 @@ spec:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/kagent-bedrock
```
-If you want to use one shared ServiceAccount for multiple agents, you can also set `controller.agentDeployment.serviceAccountName` in the [Helm chart configuration]({{< relref "/kagent/0.x/resources/helm" >}}).
+If you want to use one shared ServiceAccount for multiple agents, you can also set `controller.agentDeployment.serviceAccountName` in the [Helm chart configuration]({{< link path="resources/helm" >}}).
## Option 2: OpenAI-compatible API
diff --git a/docs-site/content/kagent/0.x/supported-providers/azure-ai-foundry.md b/docs-site/content/kagent/0.x/supported-providers/azure-ai-foundry.md
index 40782510..b5c90041 100644
--- a/docs-site/content/kagent/0.x/supported-providers/azure-ai-foundry.md
+++ b/docs-site/content/kagent/0.x/supported-providers/azure-ai-foundry.md
@@ -248,7 +248,7 @@ spec:
# No API key: use Azure Workload Identity.
```
-For the complete memory and embedding configuration and model requirements, see [Agent Memory]({{< relref "/kagent/0.x/concepts/agent-memory" >}}).
+For the complete memory and embedding configuration and model requirements, see [Agent Memory]({{< link path="concepts/agent-memory" >}}).
## Troubleshooting
diff --git a/docs-site/content/kagent/0.x/supported-providers/azure-openai.md b/docs-site/content/kagent/0.x/supported-providers/azure-openai.md
index b9ec49e8..dfc02b0e 100644
--- a/docs-site/content/kagent/0.x/supported-providers/azure-openai.md
+++ b/docs-site/content/kagent/0.x/supported-providers/azure-openai.md
@@ -66,4 +66,4 @@ Omit `apiKeySecret` and `apiKeyPassthrough` to use Azure Workload Identity. For
Follow the [AKS Workload Identity deployment guide](https://learn.microsoft.com/azure/aks/workload-identity-deploy-cluster) and grant the managed identity the `Cognitive Services User` role.
-The kagent pod and ServiceAccount settings are provider-independent. Follow [Configure the agent for Azure Workload Identity]({{< relref "/kagent/0.x/supported-providers/azure-ai-foundry#configure-the-agent-for-azure-workload-identity" >}}) and set the agent's `modelConfig` to `azure-openai`.
+The kagent pod and ServiceAccount settings are provider-independent. Follow [Configure the agent for Azure Workload Identity]({{< link path="supported-providers/azure-ai-foundry#configure-the-agent-for-azure-workload-identity" >}}) and set the agent's `modelConfig` to `azure-openai`.
diff --git a/docs-site/content/kagent/1.x/not-in-version.md b/docs-site/content/kagent/1.x/not-in-version.md
index b4d3437f..2380ad55 100644
--- a/docs-site/content/kagent/1.x/not-in-version.md
+++ b/docs-site/content/kagent/1.x/not-in-version.md
@@ -5,4 +5,4 @@ build:
list: never
---
-This topic doesn't exist in this version of the kagent docs yet. Use the version switcher above to go back to a version where it's available, or browse the [kagent 1.0 (preview)]({{< relref "/kagent/1.x" >}}) landing page.
+This topic doesn't exist in this version of the kagent docs yet. Use the version switcher above to go back to a version where it's available, or browse the [kagent 1.0 (preview)]({{< link path="" >}}) landing page.
diff --git a/docs-site/layouts/_shortcodes/link.html b/docs-site/layouts/_shortcodes/link.html
new file mode 100644
index 00000000..5131d9c4
--- /dev/null
+++ b/docs-site/layouts/_shortcodes/link.html
@@ -0,0 +1,72 @@
+{{- /* kagent override of docs-theme-extras' link shortcode.
+
+ Why this exists: upstream resolves relative to
+ .Page.FirstSection.RelPermalink — the product's top-level section
+ (e.g. "/docs/kagent/"). kagent is now versioned (0.x, 1.x — see
+ sections.kagent.versions in hugo.yaml), so content lives one level
+ deeper than that; a plain FirstSection-relative path would drop the
+ version segment entirely, the same class of bug already fixed in
+ this repo's navbar.html, sidebar.html, and version-banner.html
+ overrides.
+
+ Fix: when the current page's section has a versions list, resolve
+ relative to the CURRENT VERSION's own page (e.g. "/kagent/0.x") —
+ found by locating $sectionKey within this page's own URL segments and
+ taking the page one level deeper — instead of the top-level section.
+ Unversioned sections (kmcp) fall through to upstream's behavior
+ unchanged.
+
+ Everything else (translation-export mode, slash cleanup) is
+ byte-for-byte identical to upstream. */ -}}
+{{- $path := .Get "path" -}}
+{{- if eq hugo.Environment "translation" -}}
+ {{- $reg := .Page.Store.Get "transReg" | default slice -}}
+ {{- $ph := printf "XTRANSPH%dX" (len $reg) -}}
+ {{- $reg = $reg | append (dict "ph" $ph "text" (printf "{{< link path=\"%s\" >}}" $path)) -}}
+ {{- .Page.Store.Set "transReg" $reg -}}
+ {{- $ph -}}
+{{- else -}}
+{{- $page := .Page -}}
+{{- $root := $page.FirstSection -}}
+{{- $sectionKey := $page.Section -}}
+{{- if and $sectionKey (isset $page.Site.Params.sections $sectionKey) -}}
+ {{- with (index $page.Site.Params.sections $sectionKey).versions -}}
+ {{- $segments := split (strings.Trim $page.RelPermalink "/") "/" -}}
+ {{- $sectionIdx := -1 -}}
+ {{- range $i, $seg := $segments -}}
+ {{- if and (eq $sectionIdx -1) (eq $seg $sectionKey) -}}
+ {{- $sectionIdx = $i -}}
+ {{- end -}}
+ {{- end -}}
+ {{- if ge $sectionIdx 0 -}}
+ {{- $versionIdx := add $sectionIdx 1 -}}
+ {{- if lt $versionIdx (len $segments) -}}
+ {{- $versionPage := site.GetPage (printf "/%s/%s" $sectionKey (index $segments $versionIdx)) -}}
+ {{- if $versionPage -}}
+ {{- $root = $versionPage -}}
+ {{- end -}}
+ {{- end -}}
+ {{- end -}}
+ {{- end -}}
+{{- end -}}
+
+{{- $finalURL := printf "/%s/%s" $root.RelPermalink $path -}}
+
+{{- /* Append a slash if the link is not a fragment */ -}}
+{{- if not (strings.Contains $finalURL "#") -}}
+ {{- $finalURL = printf "%s/" $finalURL -}}
+{{- end -}}
+
+{{- /* Replace all double slashes with single slashes as a safety measure */ -}}
+{{- /* Preserve the protocol separator (://) by temporarily replacing it */ -}}
+{{- $finalURL = replace $finalURL "://" "__PROTOCOL_SEPARATOR__" -}}
+{{- /* Loop until no more double slashes exist (max 10 iterations for safety) */ -}}
+{{- range $i := (seq 10) -}}
+ {{- if (strings.Contains $finalURL "//") -}}
+ {{- $finalURL = replace $finalURL "//" "/" -}}
+ {{- end -}}
+{{- end -}}
+{{- /* Restore the protocol separator */ -}}
+{{- $finalURL = replace $finalURL "__PROTOCOL_SEPARATOR__" "://" -}}
+{{- $finalURL -}}
+{{- end -}}
From cc5db939a7cc0ecea495886222fb7f9d06b76a1c Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Fri, 21 Aug 2026 17:33:25 -0500
Subject: [PATCH 05/70] Write Phase 1 kagent 1.0 docs: About and Get started
sections
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Adds the five Phase 1 pages from the docs scope: What is kagent, Core
concepts, Architecture, Architecture: Agent Substrate, and Your first
agent, plus the About and Get started section landing pages.
Grounded against the actual kagent-private v1alpha3 code and the
substrate repo rather than the design vault alone, which caught several
places where the vault (and the original docs scope) had drifted from
what's actually implemented — Hermes/OpenClaw living in a separate
AgentHarness CRD rather than as Harness runtime variants, the v1alpha3
CRD version not covering the gRPC control plane (that's v1alpha1), and
Harness/AgentTemplate attachment being a one-way label selector rather
than a bilateral handshake. "Your first agent" uses kubectl + grpcurl
directly, verified end-to-end against real e2e test code and the actual
a2a-go proto, since the kagent CLI doesn't support this flow yet.
Reviewed against solo.io's shared docs writing conventions (voice,
sentence-case titles/headings, full-sentence descriptions, no
contractions) and a Vale pass borrowing the docs repo's real Solo style
rules.
Co-Authored-By: Claude Sonnet 5
Signed-off-by: Rachael Graham
---
docs-site/content/kagent/1.x/_index.md | 2 +-
docs-site/content/kagent/1.x/about/_index.md | 8 ++
.../kagent/1.x/about/agent-substrate.md | 47 +++++++
.../content/kagent/1.x/about/architecture.md | 63 +++++++++
.../content/kagent/1.x/about/core-concepts.md | 96 +++++++++++++
.../kagent/1.x/about/what-is-kagent.md | 77 ++++++++++
.../content/kagent/1.x/get-started/_index.md | 8 ++
.../1.x/get-started/your-first-agent.md | 133 ++++++++++++++++++
docs-site/content/kagent/_index.md | 2 +-
9 files changed, 434 insertions(+), 2 deletions(-)
create mode 100644 docs-site/content/kagent/1.x/about/_index.md
create mode 100644 docs-site/content/kagent/1.x/about/agent-substrate.md
create mode 100644 docs-site/content/kagent/1.x/about/architecture.md
create mode 100644 docs-site/content/kagent/1.x/about/core-concepts.md
create mode 100644 docs-site/content/kagent/1.x/about/what-is-kagent.md
create mode 100644 docs-site/content/kagent/1.x/get-started/_index.md
create mode 100644 docs-site/content/kagent/1.x/get-started/your-first-agent.md
diff --git a/docs-site/content/kagent/1.x/_index.md b/docs-site/content/kagent/1.x/_index.md
index f68c8997..abd552db 100644
--- a/docs-site/content/kagent/1.x/_index.md
+++ b/docs-site/content/kagent/1.x/_index.md
@@ -1,7 +1,7 @@
---
title: kagent 1.0
linkTitle: "kagent 1.x (preview)"
-description: Preview documentation for the kagent 1.0 release, built on Agent Substrate.
+description: Preview the kagent 1.0 documentation, built on Agent Substrate.
weight: 1
author: kagent.dev
---
diff --git a/docs-site/content/kagent/1.x/about/_index.md b/docs-site/content/kagent/1.x/about/_index.md
new file mode 100644
index 00000000..e2b34a46
--- /dev/null
+++ b/docs-site/content/kagent/1.x/about/_index.md
@@ -0,0 +1,8 @@
+---
+title: About
+description: Learn the core concepts and architecture behind kagent 1.0.
+weight: 2
+author: kagent.dev
+---
+
+Learn what changed in kagent 1.0 and the vocabulary the rest of these docs build on.
diff --git a/docs-site/content/kagent/1.x/about/agent-substrate.md b/docs-site/content/kagent/1.x/about/agent-substrate.md
new file mode 100644
index 00000000..768cc52c
--- /dev/null
+++ b/docs-site/content/kagent/1.x/about/agent-substrate.md
@@ -0,0 +1,47 @@
+---
+title: "Architecture: Agent Substrate"
+description: See how Agent Substrate runs, suspends, and resumes the Actors behind every AgentInstance.
+weight: 4
+author: kagent.dev
+---
+
+[Architecture]({{< link path="about/architecture" >}}) covers where an Actor fits between an AgentInstance and a running conversation. This page covers how Agent Substrate itself runs that Actor: on what compute, inside what sandbox, and how it suspends and resumes without staying resident the whole time.
+
+## Workers and WorkerPools
+
+A **WorkerPool** is a Kubernetes custom resource that an operator provisions before any Harness can create AgentInstances. It defines a pool of pre-started sandbox pods, called **Workers**, along with the sandbox technology those Workers use.
+
+A Worker is not something an operator creates directly. Substrate manages Workers itself, keeping enough of them ready in each WorkerPool so that an Actor can start or resume on one immediately, without waiting on the Kubernetes scheduler to place a new Pod.
+
+## Sandboxing
+
+Because an Actor often runs a model-directed agent that calls tools and executes commands, Substrate runs each Actor in an isolated sandbox rather than a plain container. A WorkerPool's `sandboxClass` field selects the sandbox technology for its Workers: [gVisor](https://gvisor.dev) or a micro-VM technology such as [Kata Containers](https://katacontainers.io). Both technologies isolate an Actor from its Worker's host kernel, and both support the suspend and resume operations that the rest of this page covers.
+
+## ActorTemplate
+
+An **ActorTemplate** is the compiled, immutable definition that a new Actor is created from. [Architecture]({{< link path="about/architecture" >}}) covers how the kagent controller compiles a Harness and AgentTemplate pair into one. Substrate rejects any change to an ActorTemplate's spec after creation, so the kagent controller creates a new ActorTemplate for every compiled revision rather than editing an existing one, and reclaims old ones once no AgentInstance references them.
+
+## Suspend, snapshot, and resume
+
+Substrate's density model rests on one fact about agent workloads: an Actor spends most of its time idle, waiting on a person or a large language model (LLM) to respond, not actively computing. Substrate exploits that by suspending idle Actors and reclaiming their Worker, then resuming them on demand when traffic arrives. Suspending and resuming this way lets a WorkerPool run far more Actors than it has Workers for at any one moment.
+
+The diagram below follows an Actor through one suspend-and-resume cycle. Read it left to right: a WorkerPool hosts Workers, a Worker hosts a running Actor, suspending that Actor produces a snapshot, and a tag on that snapshot lets a later Actor resume from it on whichever Worker is free.
+
+```mermaid
+flowchart LR
+ pool["WorkerPool"] --> worker1["Worker"]
+ pool --> worker2["Worker"]
+ worker1 -->|hosts| actor["Actor (running)"]
+ actor -->|suspend| snapshot["ActorSnapshot (immutable)"]
+ snapshot -->|tag| tag["ActorSnapshotTag (stable handle)"]
+ tag -->|resume| worker2
+```
+
+Suspending an Actor writes its full state to an immutable **ActorSnapshot** and frees the Worker it was running on. An **ActorSnapshotTag** gives that snapshot a stable, human-meaningful name, so callers do not need to track Substrate's internal snapshot identity. A tag's target can be updated to point at a newer snapshot without changing the tag's own name, and a snapshot cannot be deleted while any tag still points to it. Resuming reads the tagged snapshot and restores it onto whichever Worker in the pool is free, not necessarily the Worker the Actor originally ran on.
+
+Substrate's own target for this cycle is 100ms at the 95th percentile, measured from the moment traffic arrives for a suspended Actor to the moment that Actor can receive it.
+
+## Next steps
+
+- [Your first agent]({{< link path="get-started/your-first-agent" >}}): apply a Harness and AgentTemplate, and watch the Actor they produce suspend and resume.
+- [Substrate operations]({{< link path="operations/substrate-operations" >}}): size a WorkerPool and choose a sandbox class for your cluster.
diff --git a/docs-site/content/kagent/1.x/about/architecture.md b/docs-site/content/kagent/1.x/about/architecture.md
new file mode 100644
index 00000000..0228ab2f
--- /dev/null
+++ b/docs-site/content/kagent/1.x/about/architecture.md
@@ -0,0 +1,63 @@
+---
+title: Architecture
+description: See how a Harness and AgentTemplate become a running conversation, across kagent's two authorization planes.
+weight: 3
+author: kagent.dev
+---
+
+[Core concepts]({{< link path="about/core-concepts" >}}) defines Harness, AgentTemplate, AgentInstance, and Actor on their own. This page connects them into one system: how applying a Harness and AgentTemplate leads to a running conversation, and which parts of that path Kubernetes governs versus which parts kagent governs itself.
+
+kagent 1.0 splits authorization across two planes, not one:
+
+- The **Kubernetes plane** governs the Harness and AgentTemplate custom resources. Kubernetes Role-Based Access Control (RBAC) decides who can create, read, or edit them, exactly as it would for any other Custom Resource Definition (CRD).
+- The **kagent plane** governs AgentInstances: creating one, suspending or resuming it, sharing it, deleting it, and holding a conversation with it. kagent's own gRPC authentication and authorization decide who can do these things, independent of Kubernetes RBAC.
+
+Someone with RBAC access to apply a Harness and AgentTemplate does not automatically get access to create or talk to AgentInstances that use them, and the reverse is also true. The diagram below shows where the boundary between the two planes falls, and the walkthrough after it follows a request across that boundary from start to finish.
+
+```mermaid
+flowchart TB
+ subgraph k8s["Kubernetes plane (RBAC)"]
+ operator["Operator kubectl apply"]
+ harness["Harness"]
+ template["AgentTemplate"]
+ controller["kagent controller"]
+ actortemplate["ActorTemplate (Substrate)"]
+ operator --> harness
+ operator --> template
+ harness --> controller
+ template --> controller
+ controller -->|compiles the pair into| actortemplate
+ end
+
+ subgraph kagentplane["kagent plane (gRPC auth)"]
+ caller["Caller"]
+ instance["AgentInstance"]
+ gateway["A2A gateway"]
+ actor["Actor (Substrate)"]
+ caller -->|CreateAgentInstance| instance
+ instance -->|created from| actortemplate
+ instance -->|runs on| actor
+ caller -->|A2A conversation| gateway
+ gateway -->|routes to| actor
+ end
+
+ classDef crd stroke:#a78bfa,fill:transparent
+ class harness,template crd
+```
+
+Follow the Kubernetes plane first. An operator applies a Harness and an AgentTemplate, governed by Kubernetes RBAC. The kagent controller watches for a valid pair, one whose `allowedAgentTemplates` selector matches, and compiles it into an ActorTemplate on Substrate.
+
+The kagent plane starts once that ActorTemplate exists. A caller, who may or may not be the same person as the operator, calls `CreateAgentInstance` through kagent's gRPC API. This call is governed by kagent's own authentication and authorization, not by Kubernetes RBAC. kagent creates the AgentInstance from the latest compiled ActorTemplate, and that AgentInstance runs on an Actor.
+
+From there, the caller holds a conversation with the AgentInstance over the A2A (Agent-to-Agent) protocol. The A2A gateway routes each request to the Actor running behind the target AgentInstance, so the caller only ever needs to know an AgentInstance's identity, never which Actor or Worker is behind it.
+
+## Why two planes
+
+Kubernetes RBAC is designed to authorize configuration changes: who can create a Deployment, edit a ConfigMap, or in this case, apply a Harness or AgentTemplate. It is not designed to authorize a running conversation, share access to it with another user, or scope who can suspend it. kagent's gRPC plane exists to authorize exactly those actions, at the granularity of a single AgentInstance rather than a namespace or a resource kind.
+
+This split also keeps the two lifecycles independent. Editing a Harness or AgentTemplate does not affect AgentInstances already running against the ActorTemplate they were created from. It only affects new AgentInstances, created after the edit is compiled.
+
+## Next steps
+
+- [Architecture: Agent Substrate]({{< link path="about/agent-substrate" >}}): what an Actor actually runs on, and how it suspends and resumes.
+- [Your first agent]({{< link path="get-started/your-first-agent" >}}): apply a Harness and AgentTemplate, and create the AgentInstance they produce.
diff --git a/docs-site/content/kagent/1.x/about/core-concepts.md b/docs-site/content/kagent/1.x/about/core-concepts.md
new file mode 100644
index 00000000..c9f77d58
--- /dev/null
+++ b/docs-site/content/kagent/1.x/about/core-concepts.md
@@ -0,0 +1,96 @@
+---
+title: Core concepts
+description: Learn the Harness, AgentTemplate, AgentInstance, and Actor model that kagent 1.0 is built on.
+weight: 2
+author: kagent.dev
+---
+
+kagent 1.0 replaces the Deployment-based `Agent` custom resource with a new model built around **Harness**, **AgentTemplate**, and **AgentInstance**, running on [Agent Substrate]({{< link path="about/agent-substrate" >}}) instead of plain Kubernetes Deployments. This page defines the vocabulary the rest of these docs use. If your existing kagent installation is on 0.x, see the [0.x docs]({{< relref "/kagent/0.x" >}}). This page and everything under it describes the 1.0 model only.
+
+The new model separates what an agent can do from how it is allowed to run:
+
+- A **Harness** defines how an agent is allowed to run. It picks a runtime and the infrastructure policy around it.
+- An **AgentTemplate** defines what an agent can do: its model, prompt, and tools.
+- An **AgentInstance** is a running conversation, created by pairing the two.
+- An **Actor** is the sandboxed process, provided by Substrate, that an AgentInstance runs on.
+
+The diagram below shows how a Harness and an AgentTemplate become a running conversation. Follow the arrows from left to right: the kagent controller compiles the Harness and AgentTemplate pair into an ActorTemplate, and each AgentInstance is created from that ActorTemplate and runs on an Actor.
+
+```mermaid
+flowchart LR
+ harness["Harness (CRD)"]
+ template["AgentTemplate (CRD)"]
+ controller["kagent controller"]
+ actortemplate["ActorTemplate (compiled, immutable)"]
+ instance["AgentInstance (gRPC + database)"]
+ actor["Actor (Substrate)"]
+
+ harness --> controller
+ template --> controller
+ controller -->|compiles the pair into| actortemplate
+ instance -->|created from| actortemplate
+ instance -->|runs on| actor
+
+ classDef crd stroke:#a78bfa,fill:transparent
+ class harness,template crd
+```
+
+The Harness and AgentTemplate are the only two resources an operator applies directly. The kagent controller watches for a valid pair and compiles it into an ActorTemplate. From there, each AgentInstance created from that ActorTemplate gets its own Actor to run on. The rest of this page defines each of these terms in more detail.
+
+## Harness
+
+A **Harness** is a Kubernetes custom resource that defines how an agent is allowed to run. It specifies:
+
+- **Runtime**: the engine that executes the agent. This is either kagent's own Go or Python runtime, or a bring-your-own coding agent such as Claude Code or Codex.
+- **Workload**: the container image and environment the runtime runs in.
+- **Substrate policy**: the [WorkerPool]({{< link path="about/agent-substrate#workers-and-workerpools" >}}) that the Harness's Actors are scheduled onto, and where their snapshots are stored.
+- **Allowed AgentTemplates**: a selector that names which AgentTemplates are permitted to run on this Harness.
+
+That last point is a one-way match, not a mutual handshake. An AgentTemplate has no field naming a Harness. Instead, a Harness's `allowedAgentTemplates` selector matches on labels, and any AgentTemplate in the same namespace carrying a matching label becomes eligible to run on it. Whoever controls a Harness's selector decides which AgentTemplates it accepts.
+
+A Harness owns no running compute by itself. Applying one registers a runtime and policy that an AgentTemplate can pair with.
+
+## AgentTemplate
+
+An **AgentTemplate** is a Kubernetes custom resource that defines what an agent does. It specifies:
+
+- **Model configuration**: the large language model (LLM) provider and model the agent uses. This is the only field an AgentTemplate strictly requires.
+- **System prompt**: a literal prompt, or a Go-templated one that can `include` shared ConfigMaps.
+- **Tools**: a list of tool bindings the agent can call. Each binding is either a Model Context Protocol (MCP) server, or another AgentTemplate used as an agent tool (see [Agent tools](#agent-tools-shared-vs-dedicated) below).
+- **Skills** and **plugins**: reusable capability packages, sourced from an Open Container Initiative (OCI) registry, Git, or S3.
+
+An AgentTemplate does nothing on its own. It becomes runnable once it is paired with a Harness whose `allowedAgentTemplates` selector accepts it.
+
+## AgentInstance
+
+An **AgentInstance** is a running, conversational pairing of a Harness and an AgentTemplate. Unlike Harness and AgentTemplate, an AgentInstance is not a Kubernetes custom resource. It does not live in etcd. kagent's own gRPC API creates it, and kagent's PostgreSQL database tracks it.
+
+This split is deliberate, not an implementation detail to work around:
+
+- Applying a Harness or AgentTemplate is a **Kubernetes-native operation**, governed by Kubernetes RBAC, exactly like any other CRD.
+- Creating, suspending, resuming, sharing, or deleting an AgentInstance, and holding a conversation with it, are **kagent-native operations**, governed by kagent's own gRPC authentication and authorization, independent of who can `kubectl apply` a Harness or AgentTemplate.
+
+Under the hood, the kagent controller watches for valid Harness and AgentTemplate pairs and compiles each one into an immutable `ActorTemplate`, a Substrate resource keyed by a digest of the compiled revision. Creating an AgentInstance resolves to the latest successfully compiled ActorTemplate for that pair and creates an Actor from it. If you edit the Harness or AgentTemplate, existing AgentInstances keep running against the ActorTemplate they were created from. New AgentInstances pick up the new revision.
+
+Once created, an AgentInstance talks to callers over the A2A (Agent-to-Agent) protocol, through kagent's A2A gateway. The gateway resolves each request to the right AgentInstance and forwards it to the Actor running behind it.
+
+## Actor
+
+An **Actor** is the sandboxed unit of compute, provided by [Agent Substrate]({{< link path="about/agent-substrate" >}}), that runs an AgentInstance's conversation loop. Every AgentInstance is backed by an Actor.
+
+Actors are why AgentInstances can suspend and resume cheaply instead of staying resident: an idle Actor can be snapshotted and torn down, then resumed from that snapshot on demand. [Architecture: Agent Substrate]({{< link path="about/agent-substrate" >}}) covers the full mechanics (Workers, WorkerPools, ActorTemplates, and snapshotting). For this page, an Actor is simply the sandbox that an AgentInstance's conversation runs inside.
+
+## Agent tools: Shared vs. Dedicated
+
+An AgentTemplate's tools are not limited to MCP servers. A tool binding can also point at another AgentTemplate, letting one agent call another agent as a tool. Each agent-tool binding picks an isolation mode:
+
+- **Shared** (the default): the child agent runs inside the same Actor as its parent. This is cheaper, and the child shares its parent's fate. If the parent's Actor is suspended or crashes, so does the child.
+- **Dedicated**: the child agent gets its own Actor, isolated from its parent. This is more expensive, but a crash or a long-running task in the child cannot take down the parent, and the child can be scaled, suspended, or resumed independently.
+
+A Shared agent tool can itself have Dedicated agent tools underneath it, but a Shared agent tool cannot contain another Shared one. Sharing a single Actor only ever goes one level deep. Restricting Shared nesting this way keeps the isolation model easy to reason about: at any point in an agent's tool tree, you can tell exactly which Actor a given call executes in just by walking up to the nearest Dedicated boundary, or the root.
+
+## Next steps
+
+- [Architecture]({{< link path="about/architecture" >}}): how these pieces fit together end to end, from `kubectl apply` to a live conversation.
+- [Architecture: Agent Substrate]({{< link path="about/agent-substrate" >}}): Workers, WorkerPools, ActorTemplates, and how Actors suspend and resume.
+- [Your first agent]({{< link path="get-started/your-first-agent" >}}): apply a Harness and AgentTemplate, and talk to the AgentInstance they create.
diff --git a/docs-site/content/kagent/1.x/about/what-is-kagent.md b/docs-site/content/kagent/1.x/about/what-is-kagent.md
new file mode 100644
index 00000000..4956b9b3
--- /dev/null
+++ b/docs-site/content/kagent/1.x/about/what-is-kagent.md
@@ -0,0 +1,77 @@
+---
+title: Introducing kagent
+linkTitle: What is kagent
+description: Understand what kagent is and its core purpose.
+weight: 1
+author: kagent.dev
+---
+
+kagent is an open-source, Kubernetes-native platform for running AI agents. It defines an agent's runtime and behavior as ordinary Kubernetes custom resources, governed by the same role-based access control (RBAC), GitOps, and observability you already use for your other workloads, and runs each agent's conversation inside [Agent Substrate]({{< link path="about/agent-substrate" >}}), a sandboxed, suspend-and-resume compute layer built for bursty, mostly idle agent workloads. kagent works with coding-agent runtimes such as Claude Code and Codex, agent frameworks such as Google's Agent Development Kit (ADK), LangGraph, and CrewAI, and every major large language model (LLM) provider.
+
+kagent was created at [Solo.io](https://www.solo.io) in 2025 and is a [Cloud Native Computing Foundation](https://www.cncf.io) sandbox project.
+
+## What is kagent?
+
+Unlike a traditional chatbot, kagent uses advanced reasoning and iterative planning to autonomously handle multi-step problems in cloud-native environments. It turns AI insight into concrete action, helping teams tackle common operational challenges such as:
+
+- Diagnosing connectivity issues across multiple service hops
+- Troubleshooting application performance degradation
+- Automating alert generation from Prometheus metrics
+- Debugging Gateway and HTTPRoute configurations
+- Managing progressive rollouts with Argo Rollouts
+
+## Core model
+
+kagent 1.0 separates an agent's capabilities from its runtime, then runs the two together as a conversation:
+
+- A **Harness** and an **AgentTemplate** are the Kubernetes custom resources you author. Together they say how an agent is allowed to run and what it can do.
+- An **AgentInstance** is the running conversation those two resources produce, backed by an **Actor** on Agent Substrate.
+
+[Core concepts]({{< link path="about/core-concepts" >}}) defines each of these in detail, and [Architecture]({{< link path="about/architecture" >}}) walks through how they connect end to end.
+
+## Why kagent?
+
+kagent addresses the growing complexity of cloud-native operations by:
+
+- Automating routine troubleshooting and operational tasks
+- Reducing the need for specialist intervention in common scenarios
+- Enabling teams to formalize and share their operational expertise
+- Providing a platform for building and sharing custom AI agents
+
+## Platform features
+
+Everything works with a single `helm install`. No add-ons, no extra databases, no waiting for enterprise.
+
+{{< feature-cards >}}
+{{< feature-card title="Agent lifecycle via CRDs" desc="Define, version, and roll out Harnesses and AgentTemplates with kubectl and GitOps, the same workflow as every other workload." >}}
+{{< feature-card title="Sandboxed by default" desc="Every AgentInstance runs on a Substrate Actor, sandboxed with gVisor or a micro-VM. Run untrusted, model-directed code safely." >}}
+{{< feature-card title="Suspend and resume" desc="Idle AgentInstances suspend and free their compute, then resume on demand. Run far more agents than you have capacity for at any one moment." >}}
+{{< feature-card title="Bring your own runtime" desc="Run kagent's native Go or Python engine, or bring Claude Code or Codex as the runtime behind a Harness." >}}
+{{< feature-card title="Agent tools" desc="Compose agents from other agents. Choose Shared isolation for cheap nesting, or Dedicated isolation to give a nested agent its own Actor." >}}
+{{< feature-card title="Long-term memory" desc="Persistent, vector-backed memory across sessions. Agents remember context, not just the last prompt." >}}
+{{< feature-card title="Human-in-the-loop" desc="Tool approval gates and agent-initiated questions keep a person in control of consequential actions." >}}
+{{< feature-card title="Agent-to-Agent (A2A)" desc="AgentInstances talk to callers, and to each other, over the A2A protocol." >}}
+{{< feature-card title="Skills and plugins" desc="Load skills and capability packages from an Open Container Initiative (OCI) registry, Git, or S3 at startup." >}}
+{{< feature-card title="Prompt templates" desc="Reusable prompt fragments stored as ConfigMaps. Keep system prompts consistent across agents." >}}
+{{< feature-card title="Full observability" desc="OpenTelemetry tracing, Prometheus metrics, and structured logs. See every prompt, every tool call, every token." >}}
+{{< feature-card title="Postgres storage" desc="AgentInstances are tracked in production-grade, Postgres-backed storage with reviewable migrations." >}}
+{{< /feature-cards >}}
+
+## Enterprise distributions
+
+Check out [Solo Enterprise for kagent](https://www.solo.io/products/kagent-enterprise), a comprehensive agent management interface for creating, validating, debugging, deploying, and monitoring AI agents across federated Kubernetes clusters. Solo Enterprise for kagent adds enterprise-grade capabilities on top of the kagent open source project, including advanced management features, observability tools, and multicluster federation support.
+
+## Getting started
+
+To start using kagent, see [Your first agent]({{< link path="get-started/your-first-agent" >}}). For a deeper understanding of how kagent works, see [Architecture]({{< link path="about/architecture" >}}).
+
+Ready to contribute? Visit the [GitHub repository](https://github.com/kagent-dev) to learn how you can help expand the ecosystem of cloud-native AI agents.
+
+## Community
+
+Join the kagent community:
+
+- Explore the repositories on [GitHub](https://github.com/kagent-dev)
+- Join the discussion in the #kagent channel on CNCF Slack
+- Check the [FAQ]({{< link path="reference/faq" >}}) for common questions
+- Follow the [feature roadmap](https://github.com/kagent-dev/kagent/blob/main/README.md#roadmap) for upcoming developments
diff --git a/docs-site/content/kagent/1.x/get-started/_index.md b/docs-site/content/kagent/1.x/get-started/_index.md
new file mode 100644
index 00000000..6b754904
--- /dev/null
+++ b/docs-site/content/kagent/1.x/get-started/_index.md
@@ -0,0 +1,8 @@
+---
+title: Get started
+description: Install kagent and create your first agent.
+weight: 1
+author: kagent.dev
+---
+
+Install kagent, then create and talk to your first agent.
diff --git a/docs-site/content/kagent/1.x/get-started/your-first-agent.md b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
new file mode 100644
index 00000000..6ec94ddf
--- /dev/null
+++ b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
@@ -0,0 +1,133 @@
+---
+title: Your first agent
+description: Apply a Harness and AgentTemplate, then create and talk to the AgentInstance they produce.
+weight: 1
+author: kagent.dev
+---
+
+This guide walks through the full path from applying a Harness and an AgentTemplate to holding a conversation with the AgentInstance they produce. [Core concepts]({{< link path="about/core-concepts" >}}) defines each of these terms, and [Architecture]({{< link path="about/architecture" >}}) covers how they fit together.
+
+## Before you begin creating your first agent
+
+- Install kagent with a WorkerPool provisioned. See [Installation]({{< link path="setup/installation" >}}).
+- Install [grpcurl](https://github.com/fullstorydev/grpcurl).
+- Enable gRPC reflection on the controller, so grpcurl can discover its methods without a local copy of kagent's proto files. Add `--set controller.grpc.reflection=true` to your Helm install or upgrade command.
+- Port-forward the controller's gRPC port to your local machine:
+
+ ```shell
+ kubectl port-forward -n kagent svc/kagent-controller 8084:8084
+ ```
+
+The kagent CLI does not yet have commands for Harness, AgentTemplate, or AgentInstance. Until it does, this guide uses `kubectl` and `grpcurl` directly.
+
+## Apply a Harness and an AgentTemplate
+
+1. Apply a `ModelConfig` that names your model provider:
+
+ ```yaml
+ apiVersion: kagent.dev/v1alpha3
+ kind: ModelConfig
+ metadata:
+ name: default-model-config
+ namespace: kagent
+ spec:
+ provider: "OpenAI"
+ model: "gpt-4.1-mini"
+ apiKeySecret: kagent-openai
+ apiKeySecretKey: OPENAI_API_KEY
+ ```
+
+ If you installed kagent with the Helm chart's default model provider settings, this `ModelConfig` already exists. Skip this step in that case.
+
+2. Apply a `Harness` that uses kagent's native runtime:
+
+ ```yaml
+ apiVersion: kagent.dev/v1alpha3
+ kind: Harness
+ metadata:
+ name: my-first-harness
+ namespace: kagent
+ spec:
+ kagent: {}
+ workload:
+ image: @sha256: # pin this to your kagent release's runtime image
+ substrate:
+ workerPoolRef:
+ name: kagent-default
+ snapshotPolicy:
+ location: gs:///kagent/
+ allowedAgentTemplates:
+ selector:
+ matchLabels:
+ kagent.dev/harness: my-first-harness
+ ```
+
+3. Apply an `AgentTemplate` labeled to match that selector:
+
+ ```yaml
+ apiVersion: kagent.dev/v1alpha3
+ kind: AgentTemplate
+ metadata:
+ name: my-first-agent
+ namespace: kagent
+ labels:
+ kagent.dev/harness: my-first-harness
+ spec:
+ description: My first kagent agent
+ modelConfig:
+ name: default-model-config
+ systemPrompt: You are a concise, helpful assistant.
+ ```
+
+ An `AgentTemplate` has no field naming a Harness. The `kagent.dev/harness` label is only a convention this guide uses to match the selector above. Choose any label key and value, as long as the Harness selector and the AgentTemplate's labels agree.
+
+4. Confirm the pair is ready:
+
+ ```shell
+ kubectl get agenttemplate my-first-agent -n kagent -o jsonpath='{.status.harnesses}'
+ ```
+
+ A ready pair reports a `Ready` condition for `my-first-harness`. If the status is empty, wait a few seconds for the kagent controller to reconcile, then check again.
+
+## Create the AgentInstance
+
+Once the pair is ready, create an AgentInstance from it:
+
+```shell
+grpcurl -plaintext \
+ -d '{"namespace":"kagent","harness":"my-first-harness","agentTemplate":"my-first-agent","requestId":"'"$(uuidgen)"'"}' \
+ localhost:8084 kagent.api.v1alpha1.AgentInstanceService/CreateAgentInstance
+```
+
+The response includes an `id` field. Save it. The next step needs it to address the AgentInstance you just created.
+
+## Talk to your agent
+
+Send a message to the AgentInstance over the A2A (Agent-to-Agent) protocol, using the `id` from the previous step:
+
+```shell
+grpcurl -plaintext \
+ -H "x-kagent-agent-instance-namespace: kagent" \
+ -H "x-kagent-agent-instance-id: " \
+ -d '{"message":{"messageId":"'"$(uuidgen)"'","role":"ROLE_USER","parts":[{"text":"What is 2+2?"}]}}' \
+ localhost:8084 lf.a2a.v1.A2AService/SendMessage
+```
+
+The response carries the agent's reply in the same `parts` shape as the request.
+
+A future kagent CLI release will wrap the create-and-converse steps above into a single command.
+
+## Clean up your first agent
+
+```shell
+kubectl delete agenttemplate my-first-agent -n kagent
+kubectl delete harness my-first-harness -n kagent
+```
+
+Deleting the Harness and AgentTemplate does not delete the AgentInstance you created from them. Delete it directly through the same `AgentInstanceService` you used to create it.
+
+## Next steps
+
+- [Architecture: Agent Substrate]({{< link path="about/agent-substrate" >}}): what happens to your AgentInstance's Actor when it sits idle.
+- [Agent harness]({{< link path="agents/agent-harness" >}}): the full set of Harness runtime options, including Claude Code and Codex.
+- [Skills]({{< link path="skills-mcp/skills" >}}): give your agent capabilities beyond its system prompt.
diff --git a/docs-site/content/kagent/_index.md b/docs-site/content/kagent/_index.md
index bc8c3517..485b2cd8 100644
--- a/docs-site/content/kagent/_index.md
+++ b/docs-site/content/kagent/_index.md
@@ -1,6 +1,6 @@
---
title: kagent
-description: Concepts, guides, and reference docs for running declarative AI agents on Kubernetes, from install through day-two operations.
+description: Explore concepts, guides, and reference docs for running declarative AI agents on Kubernetes, from install through day-two operations.
weight: 1
author: kagent.dev
disableCards: true
From de7f422757142af12409b39e0abd4569524bb8e6 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Mon, 24 Aug 2026 13:31:35 -0500
Subject: [PATCH 06/70] Phase 1, review 1
Signed-off-by: Rachael Graham
---
docs-site/content/kagent/1.x/_index.md | 6 +-
docs-site/content/kagent/1.x/about/_index.md | 2 +-
.../kagent/1.x/about/agent-substrate.md | 8 +-
.../content/kagent/1.x/about/architecture.md | 8 +-
.../content/kagent/1.x/about/core-concepts.md | 10 +-
.../kagent/1.x/about/what-is-kagent.md | 2 +-
.../content/kagent/1.x/get-started/_index.md | 6 +-
.../1.x/get-started/your-first-agent.md | 163 +++++++++++-------
8 files changed, 125 insertions(+), 80 deletions(-)
diff --git a/docs-site/content/kagent/1.x/_index.md b/docs-site/content/kagent/1.x/_index.md
index abd552db..d7e05c80 100644
--- a/docs-site/content/kagent/1.x/_index.md
+++ b/docs-site/content/kagent/1.x/_index.md
@@ -1,13 +1,11 @@
---
-title: kagent 1.0
+title: kagent 1.0 (preview)
linkTitle: "kagent 1.x (preview)"
description: Preview the kagent 1.0 documentation, built on Agent Substrate.
-weight: 1
+weight: 10
author: kagent.dev
---
-# kagent 1.0 (preview)
-
kagent 1.0 moves the runtime from Kubernetes Deployments to [Agent Substrate](https://github.com/agent-substrate/substrate), introducing Harness, AgentTemplate, and AgentInstance as the new API surface.
This section is under active development ahead of the 1.0 release. Pages here may be incomplete, and content may change without notice. See the [0.x docs]({{< relref "/kagent/0.x" >}}) for the current stable release.
diff --git a/docs-site/content/kagent/1.x/about/_index.md b/docs-site/content/kagent/1.x/about/_index.md
index e2b34a46..e2c087a0 100644
--- a/docs-site/content/kagent/1.x/about/_index.md
+++ b/docs-site/content/kagent/1.x/about/_index.md
@@ -1,7 +1,7 @@
---
title: About
description: Learn the core concepts and architecture behind kagent 1.0.
-weight: 2
+weight: 20
author: kagent.dev
---
diff --git a/docs-site/content/kagent/1.x/about/agent-substrate.md b/docs-site/content/kagent/1.x/about/agent-substrate.md
index 768cc52c..9b459ce0 100644
--- a/docs-site/content/kagent/1.x/about/agent-substrate.md
+++ b/docs-site/content/kagent/1.x/about/agent-substrate.md
@@ -1,7 +1,7 @@
---
title: "Architecture: Agent Substrate"
description: See how Agent Substrate runs, suspends, and resumes the Actors behind every AgentInstance.
-weight: 4
+weight: 40
author: kagent.dev
---
@@ -43,5 +43,7 @@ Substrate's own target for this cycle is 100ms at the 95th percentile, measured
## Next steps
-- [Your first agent]({{< link path="get-started/your-first-agent" >}}): apply a Harness and AgentTemplate, and watch the Actor they produce suspend and resume.
-- [Substrate operations]({{< link path="operations/substrate-operations" >}}): size a WorkerPool and choose a sandbox class for your cluster.
+{{< cards >}}
+ {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Apply a Harness and AgentTemplate, and talk to the AgentInstance they produce." >}}
+ {{< card link=`{{< link path="operations/substrate-operations" >}}` title="Substrate operations" subtitle="Size a WorkerPool and choose a sandbox class for your cluster." >}}
+{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/about/architecture.md b/docs-site/content/kagent/1.x/about/architecture.md
index 0228ab2f..dc59fd5d 100644
--- a/docs-site/content/kagent/1.x/about/architecture.md
+++ b/docs-site/content/kagent/1.x/about/architecture.md
@@ -1,7 +1,7 @@
---
title: Architecture
description: See how a Harness and AgentTemplate become a running conversation, across kagent's two authorization planes.
-weight: 3
+weight: 30
author: kagent.dev
---
@@ -59,5 +59,7 @@ This split also keeps the two lifecycles independent. Editing a Harness or Agent
## Next steps
-- [Architecture: Agent Substrate]({{< link path="about/agent-substrate" >}}): what an Actor actually runs on, and how it suspends and resumes.
-- [Your first agent]({{< link path="get-started/your-first-agent" >}}): apply a Harness and AgentTemplate, and create the AgentInstance they produce.
+{{< cards >}}
+ {{< card link=`{{< link path="about/agent-substrate" >}}` title="Architecture: Agent Substrate" subtitle="See what an Actor actually runs on, and how it suspends and resumes." >}}
+ {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Apply a Harness and AgentTemplate, and talk to the AgentInstance they produce." >}}
+{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/about/core-concepts.md b/docs-site/content/kagent/1.x/about/core-concepts.md
index c9f77d58..e8a7bc25 100644
--- a/docs-site/content/kagent/1.x/about/core-concepts.md
+++ b/docs-site/content/kagent/1.x/about/core-concepts.md
@@ -1,7 +1,7 @@
---
title: Core concepts
description: Learn the Harness, AgentTemplate, AgentInstance, and Actor model that kagent 1.0 is built on.
-weight: 2
+weight: 20
author: kagent.dev
---
@@ -91,6 +91,8 @@ A Shared agent tool can itself have Dedicated agent tools underneath it, but a S
## Next steps
-- [Architecture]({{< link path="about/architecture" >}}): how these pieces fit together end to end, from `kubectl apply` to a live conversation.
-- [Architecture: Agent Substrate]({{< link path="about/agent-substrate" >}}): Workers, WorkerPools, ActorTemplates, and how Actors suspend and resume.
-- [Your first agent]({{< link path="get-started/your-first-agent" >}}): apply a Harness and AgentTemplate, and talk to the AgentInstance they create.
+{{< cards >}}
+ {{< card link=`{{< link path="about/architecture" >}}` title="Architecture" subtitle="See how these pieces fit together end to end, from `kubectl apply` to a live conversation." >}}
+ {{< card link=`{{< link path="about/agent-substrate" >}}` title="Architecture: Agent Substrate" subtitle="Learn about Workers, WorkerPools, ActorTemplates, and how Actors suspend and resume." >}}
+ {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Apply a Harness and AgentTemplate, and talk to the AgentInstance they produce." >}}
+{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/about/what-is-kagent.md b/docs-site/content/kagent/1.x/about/what-is-kagent.md
index 4956b9b3..40904e17 100644
--- a/docs-site/content/kagent/1.x/about/what-is-kagent.md
+++ b/docs-site/content/kagent/1.x/about/what-is-kagent.md
@@ -2,7 +2,7 @@
title: Introducing kagent
linkTitle: What is kagent
description: Understand what kagent is and its core purpose.
-weight: 1
+weight: 10
author: kagent.dev
---
diff --git a/docs-site/content/kagent/1.x/get-started/_index.md b/docs-site/content/kagent/1.x/get-started/_index.md
index 6b754904..91326661 100644
--- a/docs-site/content/kagent/1.x/get-started/_index.md
+++ b/docs-site/content/kagent/1.x/get-started/_index.md
@@ -1,8 +1,6 @@
---
title: Get started
description: Install kagent and create your first agent.
-weight: 1
+weight: 10
author: kagent.dev
----
-
-Install kagent, then create and talk to your first agent.
+---
\ No newline at end of file
diff --git a/docs-site/content/kagent/1.x/get-started/your-first-agent.md b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
index 6ec94ddf..340530eb 100644
--- a/docs-site/content/kagent/1.x/get-started/your-first-agent.md
+++ b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
@@ -1,46 +1,27 @@
---
title: Your first agent
-description: Apply a Harness and AgentTemplate, then create and talk to the AgentInstance they produce.
-weight: 1
+description: Create and communicate with your first agent by using the kagent project.
+weight: 10
author: kagent.dev
---
-This guide walks through the full path from applying a Harness and an AgentTemplate to holding a conversation with the AgentInstance they produce. [Core concepts]({{< link path="about/core-concepts" >}}) defines each of these terms, and [Architecture]({{< link path="about/architecture" >}}) covers how they fit together.
+This guide walks you through creating an agent, from applying a Harness and an AgentTemplate to holding a conversation with the AgentInstance that they produce. For definitions of each of these components, review the [core concepts]({{< link path="about/core-concepts" >}}). For an overview of how each component fits together in kagent, review the [architecture]({{< link path="about/architecture" >}}).
-## Before you begin creating your first agent
+## Before you begin
-- Install kagent with a WorkerPool provisioned. See [Installation]({{< link path="setup/installation" >}}).
-- Install [grpcurl](https://github.com/fullstorydev/grpcurl).
-- Enable gRPC reflection on the controller, so grpcurl can discover its methods without a local copy of kagent's proto files. Add `--set controller.grpc.reflection=true` to your Helm install or upgrade command.
-- Port-forward the controller's gRPC port to your local machine:
-
- ```shell
- kubectl port-forward -n kagent svc/kagent-controller 8084:8084
- ```
-
-The kagent CLI does not yet have commands for Harness, AgentTemplate, or AgentInstance. Until it does, this guide uses `kubectl` and `grpcurl` directly.
-
-## Apply a Harness and an AgentTemplate
-
-1. Apply a `ModelConfig` that names your model provider:
-
- ```yaml
- apiVersion: kagent.dev/v1alpha3
- kind: ModelConfig
- metadata:
- name: default-model-config
- namespace: kagent
- spec:
- provider: "OpenAI"
- model: "gpt-4.1-mini"
- apiKeySecret: kagent-openai
- apiKeySecretKey: OPENAI_API_KEY
+1. [Install kagent with a WorkerPool provisioned]({{< link path="setup/installation" >}}). Be sure to add `--set controller.grpc.reflection=true` to the Helm install command so that grpcurl can discover the controller's gRPC methods without a local copy of kagent's proto files.
+2. Install [grpcurl](https://github.com/fullstorydev/grpcurl).
+3. Port-forward the controller's gRPC port to your local machine.
+ ```shell
+ kubectl port-forward -n kagent svc/kagent-controller 8084:8084
```
- If you installed kagent with the Helm chart's default model provider settings, this `ModelConfig` already exists. Skip this step in that case.
+> [!NOTE]
+> This guide uses `kubectl` and `grpcurl` directly, as the kagent CLI does not yet have commands for Harness, AgentTemplate, or AgentInstance.
-2. Apply a `Harness` that uses kagent's native runtime:
+## Create a Harness and an AgentTemplate
+1. Apply a `Harness` that uses kagent's native runtime.
```yaml
apiVersion: kagent.dev/v1alpha3
kind: Harness
@@ -50,20 +31,24 @@ The kagent CLI does not yet have commands for Harness, AgentTemplate, or AgentIn
spec:
kagent: {}
workload:
- image: @sha256: # pin this to your kagent release's runtime image
+ # Your kagent release's runtime image
+ image: @sha256:
substrate:
workerPoolRef:
name: kagent-default
snapshotPolicy:
+ # The object storage location your cluster's Substrate installation uses for Actor snapshots
location: gs:///kagent/
allowedAgentTemplates:
selector:
matchLabels:
+ # Selector to match the AgentTemplate label
kagent.dev/harness: my-first-harness
```
+ > [!NOTE]
+ > An `AgentTemplate` has no field naming this Harness. The `kagent.dev/harness: my-first-harness` selector is a convention that this guide uses to match the `kagent.dev/harness` label in the next step. However, you can choose any label key and value, as long as the Harness selector and the AgentTemplate's labels match.
-3. Apply an `AgentTemplate` labeled to match that selector:
-
+2. Apply an `AgentTemplate` that is labeled to match the Harness's `allowedAgentTemplates` selector. The `ModelConfig` field references the `default-model-config` that was automatically created for the model provider API key that you provided during kagent installation.
```yaml
apiVersion: kagent.dev/v1alpha3
kind: AgentTemplate
@@ -71,63 +56,121 @@ The kagent CLI does not yet have commands for Harness, AgentTemplate, or AgentIn
name: my-first-agent
namespace: kagent
labels:
+ # Label matching the Harness selector
kagent.dev/harness: my-first-harness
spec:
description: My first kagent agent
modelConfig:
+ # Default config created by the kagent install guide
name: default-model-config
systemPrompt: You are a concise, helpful assistant.
```
- An `AgentTemplate` has no field naming a Harness. The `kagent.dev/harness` label is only a convention this guide uses to match the selector above. Choose any label key and value, as long as the Harness selector and the AgentTemplate's labels agree.
-
-4. Confirm the pair is ready:
-
+3. Confirm that the pair is ready.
```shell
- kubectl get agenttemplate my-first-agent -n kagent -o jsonpath='{.status.harnesses}'
+ kubectl get agenttemplate my-first-agent -n kagent -o jsonpath='{.status.harnesses}' | jq .
```
A ready pair reports a `Ready` condition for `my-first-harness`. If the status is empty, wait a few seconds for the kagent controller to reconcile, then check again.
+ ```json
+ [
+ {
+ "harness": "my-first-harness",
+ "desiredRevision": "sha256:5f2b3c1a9e8d",
+ "latestSuccessfulRevision": "sha256:5f2b3c1a9e8d",
+ "conditions": [
+ {
+ "type": "Ready",
+ "status": "True",
+ "reason": "Ready",
+ "message": "ActorTemplate is ready",
+ "lastTransitionTime": "2026-08-24T15:02:10Z"
+ }
+ ]
+ }
+ ]
+ ```
## Create the AgentInstance
-Once the pair is ready, create an AgentInstance from it:
+1. Create an AgentInstance from the Harness and AgentTemplate pair.
+ ```shell
+ RESPONSE=$(grpcurl -plaintext \
+ -d '{"namespace":"kagent","harness":"my-first-harness","agentTemplate":"my-first-agent","requestId":"'"$(uuidgen)"'"}' \
+ localhost:8084 kagent.api.v1alpha1.AgentInstanceService/CreateAgentInstance)
+ echo "$RESPONSE"
+ ```
-```shell
-grpcurl -plaintext \
- -d '{"namespace":"kagent","harness":"my-first-harness","agentTemplate":"my-first-agent","requestId":"'"$(uuidgen)"'"}' \
- localhost:8084 kagent.api.v1alpha1.AgentInstanceService/CreateAgentInstance
-```
+ A successful response includes the new AgentInstance and its `id`.
+ ```json
+ {
+ "agentInstance": {
+ "id": "8f14e45f-ceea-4a37-b0f1-2b5c4d3a9c6e",
+ "namespace": "kagent",
+ "harness": {
+ "namespace": "kagent",
+ "name": "my-first-harness"
+ },
+ "agentTemplate": {
+ "namespace": "kagent",
+ "name": "my-first-agent"
+ },
+ "state": "AGENT_INSTANCE_STATE_READY"
+ }
+ }
+ ```
-The response includes an `id` field. Save it. The next step needs it to address the AgentInstance you just created.
+2. Save the AgentInstance's `id` to an environment variable. The next step needs it to address the AgentInstance you created.
+ ```shell
+ export INSTANCE_ID=$(echo "$RESPONSE" | jq -r '.agentInstance.id')
+ ```
## Talk to your agent
-Send a message to the AgentInstance over the A2A (Agent-to-Agent) protocol, using the `id` from the previous step:
+Send a message to the AgentInstance over the A2A (Agent-to-Agent) protocol.
```shell
grpcurl -plaintext \
-H "x-kagent-agent-instance-namespace: kagent" \
- -H "x-kagent-agent-instance-id: " \
+ -H "x-kagent-agent-instance-id: $INSTANCE_ID" \
-d '{"message":{"messageId":"'"$(uuidgen)"'","role":"ROLE_USER","parts":[{"text":"What is 2+2?"}]}}' \
localhost:8084 lf.a2a.v1.A2AService/SendMessage
```
The response carries the agent's reply in the same `parts` shape as the request.
+```json
+{
+ "message": {
+ "messageId": "b2b1e2b4-5c3a-4f8e-9d1a-7e6f5c4b3a2d",
+ "role": "ROLE_AGENT",
+ "parts": [
+ {
+ "text": "4"
+ }
+ ]
+ }
+}
+```
-A future kagent CLI release will wrap the create-and-converse steps above into a single command.
-
-## Clean up your first agent
+## Clean up
-```shell
-kubectl delete agenttemplate my-first-agent -n kagent
-kubectl delete harness my-first-harness -n kagent
-```
+1. Delete the Harness and AgentTemplate.
+ ```shell
+ kubectl delete agenttemplate my-first-agent -n kagent
+ kubectl delete harness my-first-harness -n kagent
+ ```
-Deleting the Harness and AgentTemplate does not delete the AgentInstance you created from them. Delete it directly through the same `AgentInstanceService` you used to create it.
+2. Delete the AgentInstance directly through the same `AgentInstanceService` you used to create it, as deleting the Harness and AgentTemplate does not delete the AgentInstance you created from them.
+ ```shell
+ grpcurl -plaintext \
+ -d '{"namespace":"kagent","agentInstanceId":"'"$INSTANCE_ID"'"}' \
+ localhost:8084 kagent.api.v1alpha1.AgentInstanceService/DeleteAgentInstance
+ ```
## Next steps
-- [Architecture: Agent Substrate]({{< link path="about/agent-substrate" >}}): what happens to your AgentInstance's Actor when it sits idle.
-- [Agent harness]({{< link path="agents/agent-harness" >}}): the full set of Harness runtime options, including Claude Code and Codex.
-- [Skills]({{< link path="skills-mcp/skills" >}}): give your agent capabilities beyond its system prompt.
+{{< cards >}}
+ {{< card link=`{{< link path="about/agent-substrate" >}}` title="Architecture: Agent Substrate" subtitle="Understand what happens to your AgentInstance's Actor when it sits idle." >}}
+ {{< card link=`{{< link path="agents/agent-harness" >}}` title="Agent harness" subtitle="Choose from the full set of Harness runtime options, including Claude Code and Codex." >}}
+ {{< card link=`{{< link path="skills-mcp/skills" >}}` title="Skills" subtitle="Give your agent capabilities beyond its system prompt." >}}
+{{< /cards >}}
From 835c9b4220c47de993558e9700f012a20307eb42 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Mon, 24 Aug 2026 15:12:26 -0500
Subject: [PATCH 07/70] Phase 1, review 2
Signed-off-by: Rachael Graham
---
.../kagent/1.x/about/agent-substrate.md | 2 +-
.../content/kagent/1.x/about/architecture.md | 2 +-
.../content/kagent/1.x/about/core-concepts.md | 10 +++---
.../kagent/1.x/about/what-is-kagent.md | 33 +++++++++----------
.../1.x/get-started/your-first-agent.md | 4 +--
.../content/kagent/1.x/not-in-version.md | 2 +-
6 files changed, 26 insertions(+), 27 deletions(-)
diff --git a/docs-site/content/kagent/1.x/about/agent-substrate.md b/docs-site/content/kagent/1.x/about/agent-substrate.md
index 9b459ce0..fc508f34 100644
--- a/docs-site/content/kagent/1.x/about/agent-substrate.md
+++ b/docs-site/content/kagent/1.x/about/agent-substrate.md
@@ -25,7 +25,7 @@ An **ActorTemplate** is the compiled, immutable definition that a new Actor is c
Substrate's density model rests on one fact about agent workloads: an Actor spends most of its time idle, waiting on a person or a large language model (LLM) to respond, not actively computing. Substrate exploits that by suspending idle Actors and reclaiming their Worker, then resuming them on demand when traffic arrives. Suspending and resuming this way lets a WorkerPool run far more Actors than it has Workers for at any one moment.
-The diagram below follows an Actor through one suspend-and-resume cycle. Read it left to right: a WorkerPool hosts Workers, a Worker hosts a running Actor, suspending that Actor produces a snapshot, and a tag on that snapshot lets a later Actor resume from it on whichever Worker is free.
+The following diagram traces an Actor through one suspend-and-resume cycle. Read it left to right: a WorkerPool hosts Workers, a Worker hosts a running Actor, suspending that Actor produces a snapshot, and a tag on that snapshot lets a later Actor resume from it on whichever Worker is free.
```mermaid
flowchart LR
diff --git a/docs-site/content/kagent/1.x/about/architecture.md b/docs-site/content/kagent/1.x/about/architecture.md
index dc59fd5d..aaa2872a 100644
--- a/docs-site/content/kagent/1.x/about/architecture.md
+++ b/docs-site/content/kagent/1.x/about/architecture.md
@@ -12,7 +12,7 @@ kagent 1.0 splits authorization across two planes, not one:
- The **Kubernetes plane** governs the Harness and AgentTemplate custom resources. Kubernetes Role-Based Access Control (RBAC) decides who can create, read, or edit them, exactly as it would for any other Custom Resource Definition (CRD).
- The **kagent plane** governs AgentInstances: creating one, suspending or resuming it, sharing it, deleting it, and holding a conversation with it. kagent's own gRPC authentication and authorization decide who can do these things, independent of Kubernetes RBAC.
-Someone with RBAC access to apply a Harness and AgentTemplate does not automatically get access to create or talk to AgentInstances that use them, and the reverse is also true. The diagram below shows where the boundary between the two planes falls, and the walkthrough after it follows a request across that boundary from start to finish.
+Someone with RBAC access to apply a Harness and AgentTemplate does not automatically get access to create or talk to AgentInstances that use them, and the reverse is also true. The following diagram shows where the boundary between the two planes falls, and the walkthrough after it follows a request across that boundary from start to finish.
```mermaid
flowchart TB
diff --git a/docs-site/content/kagent/1.x/about/core-concepts.md b/docs-site/content/kagent/1.x/about/core-concepts.md
index e8a7bc25..f00a81e6 100644
--- a/docs-site/content/kagent/1.x/about/core-concepts.md
+++ b/docs-site/content/kagent/1.x/about/core-concepts.md
@@ -5,7 +5,7 @@ weight: 20
author: kagent.dev
---
-kagent 1.0 replaces the Deployment-based `Agent` custom resource with a new model built around **Harness**, **AgentTemplate**, and **AgentInstance**, running on [Agent Substrate]({{< link path="about/agent-substrate" >}}) instead of plain Kubernetes Deployments. This page defines the vocabulary the rest of these docs use. If your existing kagent installation is on 0.x, see the [0.x docs]({{< relref "/kagent/0.x" >}}). This page and everything under it describes the 1.0 model only.
+kagent 1.0 replaces the Deployment-based `Agent` custom resource with a new model built around **Harness**, **AgentTemplate**, and **AgentInstance**, running on [Agent Substrate]({{< link path="about/agent-substrate" >}}) instead of the plain Kubernetes Deployments that the 0.x model uses. This page defines the vocabulary that the rest of the 1.0 model docs use.
The new model separates what an agent can do from how it is allowed to run:
@@ -14,7 +14,7 @@ The new model separates what an agent can do from how it is allowed to run:
- An **AgentInstance** is a running conversation, created by pairing the two.
- An **Actor** is the sandboxed process, provided by Substrate, that an AgentInstance runs on.
-The diagram below shows how a Harness and an AgentTemplate become a running conversation. Follow the arrows from left to right: the kagent controller compiles the Harness and AgentTemplate pair into an ActorTemplate, and each AgentInstance is created from that ActorTemplate and runs on an Actor.
+The following diagram shows how a Harness and an AgentTemplate become a running conversation. Follow the arrows from left to right: the kagent controller compiles the Harness and AgentTemplate pair into an ActorTemplate, and each AgentInstance is created from that ActorTemplate and runs on an Actor.
```mermaid
flowchart LR
@@ -35,7 +35,7 @@ flowchart LR
class harness,template crd
```
-The Harness and AgentTemplate are the only two resources an operator applies directly. The kagent controller watches for a valid pair and compiles it into an ActorTemplate. From there, each AgentInstance created from that ActorTemplate gets its own Actor to run on. The rest of this page defines each of these terms in more detail.
+The Harness and AgentTemplate are the only two resources that an operator applies directly. The kagent controller watches for a valid pair and compiles it into an ActorTemplate. From there, each AgentInstance created from that ActorTemplate gets its own Actor to run on. The rest of this page defines each of these terms in more detail.
## Harness
@@ -56,7 +56,7 @@ An **AgentTemplate** is a Kubernetes custom resource that defines what an agent
- **Model configuration**: the large language model (LLM) provider and model the agent uses. This is the only field an AgentTemplate strictly requires.
- **System prompt**: a literal prompt, or a Go-templated one that can `include` shared ConfigMaps.
-- **Tools**: a list of tool bindings the agent can call. Each binding is either a Model Context Protocol (MCP) server, or another AgentTemplate used as an agent tool (see [Agent tools](#agent-tools-shared-vs-dedicated) below).
+- **Tools**: a list of tool bindings the agent can call. Each binding is either a Model Context Protocol (MCP) server, or another AgentTemplate used as an agent tool (see [Agent tools](#agent-tools-shared-vs-dedicated)).
- **Skills** and **plugins**: reusable capability packages, sourced from an Open Container Initiative (OCI) registry, Git, or S3.
An AgentTemplate does nothing on its own. It becomes runnable once it is paired with a Harness whose `allowedAgentTemplates` selector accepts it.
@@ -70,7 +70,7 @@ This split is deliberate, not an implementation detail to work around:
- Applying a Harness or AgentTemplate is a **Kubernetes-native operation**, governed by Kubernetes RBAC, exactly like any other CRD.
- Creating, suspending, resuming, sharing, or deleting an AgentInstance, and holding a conversation with it, are **kagent-native operations**, governed by kagent's own gRPC authentication and authorization, independent of who can `kubectl apply` a Harness or AgentTemplate.
-Under the hood, the kagent controller watches for valid Harness and AgentTemplate pairs and compiles each one into an immutable `ActorTemplate`, a Substrate resource keyed by a digest of the compiled revision. Creating an AgentInstance resolves to the latest successfully compiled ActorTemplate for that pair and creates an Actor from it. If you edit the Harness or AgentTemplate, existing AgentInstances keep running against the ActorTemplate they were created from. New AgentInstances pick up the new revision.
+Under the hood, the kagent controller watches for valid Harness and AgentTemplate pairs and compiles each one into an immutable `ActorTemplate`, a Substrate resource keyed by a digest of the compiled revision. Creating an AgentInstance resolves to the latest successfully compiled ActorTemplate for that pair and creates an Actor from it. If you edit the Harness or AgentTemplate, existing AgentInstances keep running against the ActorTemplate that they were created from. New AgentInstances pick up the new revision.
Once created, an AgentInstance talks to callers over the A2A (Agent-to-Agent) protocol, through kagent's A2A gateway. The gateway resolves each request to the right AgentInstance and forwards it to the Actor running behind it.
diff --git a/docs-site/content/kagent/1.x/about/what-is-kagent.md b/docs-site/content/kagent/1.x/about/what-is-kagent.md
index 40904e17..42362f61 100644
--- a/docs-site/content/kagent/1.x/about/what-is-kagent.md
+++ b/docs-site/content/kagent/1.x/about/what-is-kagent.md
@@ -1,16 +1,15 @@
---
-title: Introducing kagent
-linkTitle: What is kagent
-description: Understand what kagent is and its core purpose.
+title: What is kagent?
+description: Understand what the kagent platform is and its core purpose.
weight: 10
author: kagent.dev
---
-kagent is an open-source, Kubernetes-native platform for running AI agents. It defines an agent's runtime and behavior as ordinary Kubernetes custom resources, governed by the same role-based access control (RBAC), GitOps, and observability you already use for your other workloads, and runs each agent's conversation inside [Agent Substrate]({{< link path="about/agent-substrate" >}}), a sandboxed, suspend-and-resume compute layer built for bursty, mostly idle agent workloads. kagent works with coding-agent runtimes such as Claude Code and Codex, agent frameworks such as Google's Agent Development Kit (ADK), LangGraph, and CrewAI, and every major large language model (LLM) provider.
+kagent is an open-source, Kubernetes-native platform for running AI agents. It defines an agent's runtime and behavior as ordinary Kubernetes custom resources, governed by the same role-based access control (RBAC), GitOps, and observability that you already use for your other workloads, and runs each agent's conversation inside [Agent Substrate]({{< link path="about/agent-substrate" >}}), a sandboxed, suspend-and-resume compute layer built for bursty, mostly idle agent workloads. kagent works with coding-agent runtimes such as Claude Code and Codex, agent frameworks such as Google's Agent Development Kit (ADK), LangGraph, and CrewAI, and every major large language model (LLM) provider.
kagent was created at [Solo.io](https://www.solo.io) in 2025 and is a [Cloud Native Computing Foundation](https://www.cncf.io) sandbox project.
-## What is kagent?
+## How kagent works
Unlike a traditional chatbot, kagent uses advanced reasoning and iterative planning to autonomously handle multi-step problems in cloud-native environments. It turns AI insight into concrete action, helping teams tackle common operational challenges such as:
@@ -25,18 +24,18 @@ Unlike a traditional chatbot, kagent uses advanced reasoning and iterative plann
kagent 1.0 separates an agent's capabilities from its runtime, then runs the two together as a conversation:
- A **Harness** and an **AgentTemplate** are the Kubernetes custom resources you author. Together they say how an agent is allowed to run and what it can do.
-- An **AgentInstance** is the running conversation those two resources produce, backed by an **Actor** on Agent Substrate.
+- An **AgentInstance** is the running conversation that those two resources produce, backed by an **Actor** on Agent Substrate.
-[Core concepts]({{< link path="about/core-concepts" >}}) defines each of these in detail, and [Architecture]({{< link path="about/architecture" >}}) walks through how they connect end to end.
+[Core concepts]({{< link path="about/core-concepts" >}}) define each of these in detail, and the [architecture]({{< link path="about/architecture" >}}) walks through how they connect end to end.
-## Why kagent?
+## Benefits
kagent addresses the growing complexity of cloud-native operations by:
-- Automating routine troubleshooting and operational tasks
-- Reducing the need for specialist intervention in common scenarios
-- Enabling teams to formalize and share their operational expertise
-- Providing a platform for building and sharing custom AI agents
+- Automating routine troubleshooting and operational tasks.
+- Reducing the need for specialist intervention in common scenarios.
+- Enabling teams to formalize and share their operational expertise.
+- Providing a platform for building and sharing custom AI agents.
## Platform features
@@ -69,9 +68,9 @@ Ready to contribute? Visit the [GitHub repository](https://github.com/kagent-dev
## Community
-Join the kagent community:
+Join the kagent community!
-- Explore the repositories on [GitHub](https://github.com/kagent-dev)
-- Join the discussion in the #kagent channel on CNCF Slack
-- Check the [FAQ]({{< link path="reference/faq" >}}) for common questions
-- Follow the [feature roadmap](https://github.com/kagent-dev/kagent/blob/main/README.md#roadmap) for upcoming developments
+- Explore the repositories on [GitHub](https://github.com/kagent-dev).
+- Join the discussion in the #kagent channel on CNCF Slack.
+- Check the [FAQ]({{< link path="reference/faq" >}}) for common questions.
+- Follow the [feature roadmap](https://github.com/kagent-dev/kagent/blob/main/README.md#roadmap) for upcoming developments.
diff --git a/docs-site/content/kagent/1.x/get-started/your-first-agent.md b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
index 340530eb..584ca0bf 100644
--- a/docs-site/content/kagent/1.x/get-started/your-first-agent.md
+++ b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
@@ -120,7 +120,7 @@ This guide walks you through creating an agent, from applying a Harness and an A
}
```
-2. Save the AgentInstance's `id` to an environment variable. The next step needs it to address the AgentInstance you created.
+2. Save the AgentInstance's `id` to an environment variable. The next step needs it to address the AgentInstance that you created.
```shell
export INSTANCE_ID=$(echo "$RESPONSE" | jq -r '.agentInstance.id')
```
@@ -160,7 +160,7 @@ The response carries the agent's reply in the same `parts` shape as the request.
kubectl delete harness my-first-harness -n kagent
```
-2. Delete the AgentInstance directly through the same `AgentInstanceService` you used to create it, as deleting the Harness and AgentTemplate does not delete the AgentInstance you created from them.
+2. Delete the AgentInstance directly through the same `AgentInstanceService` that you used to create it, as deleting the Harness and AgentTemplate does not delete the AgentInstance that you created from them.
```shell
grpcurl -plaintext \
-d '{"namespace":"kagent","agentInstanceId":"'"$INSTANCE_ID"'"}' \
diff --git a/docs-site/content/kagent/1.x/not-in-version.md b/docs-site/content/kagent/1.x/not-in-version.md
index 2380ad55..7f96bd52 100644
--- a/docs-site/content/kagent/1.x/not-in-version.md
+++ b/docs-site/content/kagent/1.x/not-in-version.md
@@ -5,4 +5,4 @@ build:
list: never
---
-This topic doesn't exist in this version of the kagent docs yet. Use the version switcher above to go back to a version where it's available, or browse the [kagent 1.0 (preview)]({{< link path="" >}}) landing page.
+This topic doesn't exist in this version of the kagent docs yet. Use the version switcher to go back to a version where it's available, or browse the [kagent 1.0 (preview)]({{< link path="" >}}) landing page.
From b98a32ad54c545a3e1f40f59e7b8dea264d2a93a Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Tue, 25 Aug 2026 15:32:02 -0500
Subject: [PATCH 08/70] Phase 1, review 3
Signed-off-by: Rachael Graham
---
.../content/kagent/1.x/about/core-concepts.md | 65 ++++++++++++-------
.../1.x/get-started/your-first-agent.md | 6 +-
2 files changed, 43 insertions(+), 28 deletions(-)
diff --git a/docs-site/content/kagent/1.x/about/core-concepts.md b/docs-site/content/kagent/1.x/about/core-concepts.md
index f00a81e6..6f314293 100644
--- a/docs-site/content/kagent/1.x/about/core-concepts.md
+++ b/docs-site/content/kagent/1.x/about/core-concepts.md
@@ -9,12 +9,12 @@ kagent 1.0 replaces the Deployment-based `Agent` custom resource with a new mode
The new model separates what an agent can do from how it is allowed to run:
-- A **Harness** defines how an agent is allowed to run. It picks a runtime and the infrastructure policy around it.
-- An **AgentTemplate** defines what an agent can do: its model, prompt, and tools.
-- An **AgentInstance** is a running conversation, created by pairing the two.
-- An **Actor** is the sandboxed process, provided by Substrate, that an AgentInstance runs on.
+- A [**Harness**](#harness) defines how an agent is allowed to run. It picks a runtime and the infrastructure policy around it.
+- An [**AgentTemplate**](#agenttemplate) defines what an agent can do: its model, prompt, and tools.
+- An [**AgentInstance**](#agentinstance) is a running conversation, created by pairing the two.
+- An [**Actor**](#actor) is the sandboxed process, provided by Substrate, that an AgentInstance runs on.
-The following diagram shows how a Harness and an AgentTemplate become a running conversation. Follow the arrows from left to right: the kagent controller compiles the Harness and AgentTemplate pair into an ActorTemplate, and each AgentInstance is created from that ActorTemplate and runs on an Actor.
+The following diagram shows how a Harness and an AgentTemplate become a running conversation. The kagent controller compiles the Harness and AgentTemplate pair into an ActorTemplate, and each AgentInstance is created from that ActorTemplate and runs on an Actor.
```mermaid
flowchart LR
@@ -28,71 +28,86 @@ flowchart LR
harness --> controller
template --> controller
controller -->|compiles the pair into| actortemplate
- instance -->|created from| actortemplate
+ actortemplate -->|instantiated as| instance
instance -->|runs on| actor
classDef crd stroke:#a78bfa,fill:transparent
class harness,template crd
```
-The Harness and AgentTemplate are the only two resources that an operator applies directly. The kagent controller watches for a valid pair and compiles it into an ActorTemplate. From there, each AgentInstance created from that ActorTemplate gets its own Actor to run on. The rest of this page defines each of these terms in more detail.
+The Harness and AgentTemplate are the only two resources that an operator applies directly. The kagent controller watches for a valid pair and compiles it into an ActorTemplate. From there, each AgentInstance created from that ActorTemplate gets its own Actor to run on.
## Harness
-A **Harness** is a Kubernetes custom resource that defines how an agent is allowed to run. It specifies:
+A **Harness** is a Kubernetes custom resource that defines _how an agent is allowed to run_. It specifies:
-- **Runtime**: the engine that executes the agent. This is either kagent's own Go or Python runtime, or a bring-your-own coding agent such as Claude Code or Codex.
-- **Workload**: the container image and environment the runtime runs in.
-- **Substrate policy**: the [WorkerPool]({{< link path="about/agent-substrate#workers-and-workerpools" >}}) that the Harness's Actors are scheduled onto, and where their snapshots are stored.
-- **Allowed AgentTemplates**: a selector that names which AgentTemplates are permitted to run on this Harness.
+- **Runtime**: The engine that executes the agent. This is either kagent's own Go or Python runtime, or a bring-your-own coding agent such as Claude Code or Codex.
+- **Workload**: The container image and environment the runtime runs in.
+- **Substrate policy**: The [WorkerPool]({{< link path="about/agent-substrate#workers-and-workerpools" >}}) that the Harness's Actors are scheduled onto, and where their snapshots are stored.
+- **Allowed AgentTemplates**: A selector that names which AgentTemplates are permitted to run on this Harness.
That last point is a one-way match, not a mutual handshake. An AgentTemplate has no field naming a Harness. Instead, a Harness's `allowedAgentTemplates` selector matches on labels, and any AgentTemplate in the same namespace carrying a matching label becomes eligible to run on it. Whoever controls a Harness's selector decides which AgentTemplates it accepts.
A Harness owns no running compute by itself. Applying one registers a runtime and policy that an AgentTemplate can pair with.
+For the complete Harness schema, see the [API reference]({{< link path="reference/api-ref#harness" >}}).
+
+> [!IMPORTANT]
+> This `Harness` is unrelated to 0.x's `AgentHarness` resource, which provisions OpenClaw or Hermes coding-agent sandboxes. `Harness` is a different resource that covers how any agent is allowed to run, not a renamed or expanded version of `AgentHarness`.
+
## AgentTemplate
-An **AgentTemplate** is a Kubernetes custom resource that defines what an agent does. It specifies:
+An **AgentTemplate** is a Kubernetes custom resource that defines _what an agent does_. It specifies:
-- **Model configuration**: the large language model (LLM) provider and model the agent uses. This is the only field an AgentTemplate strictly requires.
-- **System prompt**: a literal prompt, or a Go-templated one that can `include` shared ConfigMaps.
-- **Tools**: a list of tool bindings the agent can call. Each binding is either a Model Context Protocol (MCP) server, or another AgentTemplate used as an agent tool (see [Agent tools](#agent-tools-shared-vs-dedicated)).
-- **Skills** and **plugins**: reusable capability packages, sourced from an Open Container Initiative (OCI) registry, Git, or S3.
+- **Model configuration**: The large language model (LLM) provider and model the agent uses. This is the only field an AgentTemplate strictly requires.
+- **System prompt**: A literal prompt, or a Go-templated one that can `include` shared ConfigMaps.
+- **Tools**: A list of tool bindings the agent can call. Each binding is either a Model Context Protocol (MCP) server, or another AgentTemplate used as an agent tool (see [Agent tools](#agent-tools-shared-vs-dedicated)).
+- **Skills** and **plugins**: Reusable capability packages, sourced from an Open Container Initiative (OCI) registry, Git, or S3.
An AgentTemplate does nothing on its own. It becomes runnable once it is paired with a Harness whose `allowedAgentTemplates` selector accepts it.
+For the complete AgentTemplate schema, see the [API reference]({{< link path="reference/api-ref#agenttemplate" >}}).
+
## AgentInstance
-An **AgentInstance** is a running, conversational pairing of a Harness and an AgentTemplate. Unlike Harness and AgentTemplate, an AgentInstance is not a Kubernetes custom resource. It does not live in etcd. kagent's own gRPC API creates it, and kagent's PostgreSQL database tracks it.
+An **AgentInstance** is a _running, conversational pairing_ of a Harness and an AgentTemplate. Unlike Harness and AgentTemplate, an AgentInstance is not a Kubernetes custom resource, and does not live in etcd. kagent's own gRPC API creates it, and kagent's PostgreSQL database tracks it.
This split is deliberate, not an implementation detail to work around:
- Applying a Harness or AgentTemplate is a **Kubernetes-native operation**, governed by Kubernetes RBAC, exactly like any other CRD.
- Creating, suspending, resuming, sharing, or deleting an AgentInstance, and holding a conversation with it, are **kagent-native operations**, governed by kagent's own gRPC authentication and authorization, independent of who can `kubectl apply` a Harness or AgentTemplate.
-Under the hood, the kagent controller watches for valid Harness and AgentTemplate pairs and compiles each one into an immutable `ActorTemplate`, a Substrate resource keyed by a digest of the compiled revision. Creating an AgentInstance resolves to the latest successfully compiled ActorTemplate for that pair and creates an Actor from it. If you edit the Harness or AgentTemplate, existing AgentInstances keep running against the ActorTemplate that they were created from. New AgentInstances pick up the new revision.
+Under the hood, the kagent controller watches for valid Harness and AgentTemplate pairs and compiles each pair into an `ActorTemplate`, a Substrate resource that holds everything Substrate needs to start an Actor.
+
+Each compile produces one **revision**, identified by a digest: a SHA-256 hash of the compiled configuration. Because that digest is derived from the configuration itself, editing a Harness or AgentTemplate compiles to a different digest, and therefore becomes a separate ActorTemplate. kagent never rewrites an existing one.
+
+That immutability is what keeps running conversations stable. When you create an AgentInstance, kagent looks up the newest revision that compiled successfully for that Harness and AgentTemplate pair, and then creates an Actor from that revision. Editing the Harness or AgentTemplate afterward does not disturb that AgentInstance, which keeps running on the revision that it was created from. Only AgentInstances created after the edit use the new revision.
Once created, an AgentInstance talks to callers over the A2A (Agent-to-Agent) protocol, through kagent's A2A gateway. The gateway resolves each request to the right AgentInstance and forwards it to the Actor running behind it.
+For the AgentInstance gRPC service definition, see the [API reference]({{< link path="reference/api-ref" >}}).
+
## Actor
-An **Actor** is the sandboxed unit of compute, provided by [Agent Substrate]({{< link path="about/agent-substrate" >}}), that runs an AgentInstance's conversation loop. Every AgentInstance is backed by an Actor.
+An **Actor** is the sandboxed unit of compute, provided by [Agent Substrate]({{< link path="about/agent-substrate" >}}), that _runs an AgentInstance's conversation loop_. Every AgentInstance is backed by an Actor.
-Actors are why AgentInstances can suspend and resume cheaply instead of staying resident: an idle Actor can be snapshotted and torn down, then resumed from that snapshot on demand. [Architecture: Agent Substrate]({{< link path="about/agent-substrate" >}}) covers the full mechanics (Workers, WorkerPools, ActorTemplates, and snapshotting). For this page, an Actor is simply the sandbox that an AgentInstance's conversation runs inside.
+Actors are the reason why AgentInstances can suspend and resume cheaply instead of staying resident. An idle Actor can be snapshotted and torn down, then resumed from that snapshot on demand. To understand the full mechanics (Workers, WorkerPools, ActorTemplates, and snapshotting), see [Architecture: Agent Substrate]({{< link path="about/agent-substrate" >}}).
## Agent tools: Shared vs. Dedicated
An AgentTemplate's tools are not limited to MCP servers. A tool binding can also point at another AgentTemplate, letting one agent call another agent as a tool. Each agent-tool binding picks an isolation mode:
-- **Shared** (the default): the child agent runs inside the same Actor as its parent. This is cheaper, and the child shares its parent's fate. If the parent's Actor is suspended or crashes, so does the child.
-- **Dedicated**: the child agent gets its own Actor, isolated from its parent. This is more expensive, but a crash or a long-running task in the child cannot take down the parent, and the child can be scaled, suspended, or resumed independently.
+- **Shared** (default): The child agent runs inside the same Actor as its parent. This option is cheaper, but the child shares its parent's fate: if the parent's Actor is suspended or crashes, so does the child.
+- **Dedicated**: The child agent gets its own Actor, isolated from its parent. This option is more expensive, but a crash or a long-running task in the child cannot take down the parent, and the child can be scaled, suspended, or resumed independently.
+
+Shared nesting never goes more than one level deep. A Shared agent tool can have Dedicated agent tools beneath it, but it cannot contain another Shared one.
-A Shared agent tool can itself have Dedicated agent tools underneath it, but a Shared agent tool cannot contain another Shared one. Sharing a single Actor only ever goes one level deep. Restricting Shared nesting this way keeps the isolation model easy to reason about: at any point in an agent's tool tree, you can tell exactly which Actor a given call executes in just by walking up to the nearest Dedicated boundary, or the root.
+This limit keeps the model predictable. A Dedicated binding gives the child its own Actor. A Shared binding puts the child in its parent's Actor, and because Shared bindings cannot chain, that parent always has an Actor of its own. Working out where any agent runs is therefore never more than a single step.
## Next steps
{{< cards >}}
{{< card link=`{{< link path="about/architecture" >}}` title="Architecture" subtitle="See how these pieces fit together end to end, from `kubectl apply` to a live conversation." >}}
- {{< card link=`{{< link path="about/agent-substrate" >}}` title="Architecture: Agent Substrate" subtitle="Learn about Workers, WorkerPools, ActorTemplates, and how Actors suspend and resume." >}}
+ {{< card link=`{{< link path="about/agent-substrate" >}}` title="Architecture: Agent Substrate" subtitle="Learn about Workers, WorkerPools, and ActorTemplates, and how Actors suspend and resume." >}}
{{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Apply a Harness and AgentTemplate, and talk to the AgentInstance they produce." >}}
{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/get-started/your-first-agent.md b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
index 584ca0bf..10fd20f4 100644
--- a/docs-site/content/kagent/1.x/get-started/your-first-agent.md
+++ b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
@@ -5,7 +5,7 @@ weight: 10
author: kagent.dev
---
-This guide walks you through creating an agent, from applying a Harness and an AgentTemplate to holding a conversation with the AgentInstance that they produce. For definitions of each of these components, review the [core concepts]({{< link path="about/core-concepts" >}}). For an overview of how each component fits together in kagent, review the [architecture]({{< link path="about/architecture" >}}).
+This guide walks you through creating an agent, from applying a Harness and an AgentTemplate to holding a conversation with the AgentInstance that they produce. For definitions of each of these components, review the [core concepts]({{< link path="about/core-concepts" >}}). For an overview of how each component fits together in kagent, review the [architecture]({{< link path="about/architecture" >}}). For the complete schema of every field that this guide sets, see the [API reference]({{< link path="reference/api-ref" >}}).
## Before you begin
@@ -76,8 +76,8 @@ This guide walks you through creating an agent, from applying a Harness and an A
[
{
"harness": "my-first-harness",
- "desiredRevision": "sha256:5f2b3c1a9e8d",
- "latestSuccessfulRevision": "sha256:5f2b3c1a9e8d",
+ "desiredRevision": "5f2b3c1a9e8d4b7a6c3e2f1d0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b",
+ "latestSuccessfulRevision": "5f2b3c1a9e8d4b7a6c3e2f1d0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b",
"conditions": [
{
"type": "Ready",
From cb9032323d0d51fb075e957052c92f0e7d1cc31a Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Tue, 25 Aug 2026 15:44:13 -0500
Subject: [PATCH 09/70] Render the docs preview server to memory
Hugo's server renders to disk and serves from docs-site/public, the same
directory build-docs writes and clean removes. Emptying it mid-session
strands the running server: later saves re-render only the touched pages,
so pages return but stylesheets do not, and the preview degrades with
each edit. --renderToMemory removes the shared directory.
Co-Authored-By: Claude Opus 5 (1M context)
Signed-off-by: Rachael Graham
---
Makefile | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index 7ed431cf..e0f08aa9 100644
--- a/Makefile
+++ b/Makefile
@@ -47,8 +47,15 @@ inject-docs: ## Copy built docs into public/docs (preserves tracked assets, e.g.
$(DOCS_OUT)/ $(WEB_DOCS)/
.PHONY: serve-docs
+# --renderToMemory keeps the preview out of $(DOCS_OUT) entirely. Hugo's server
+# otherwise renders to disk and serves from there, so it shares one directory
+# with `build-docs`/`clean`. Anything that empties that directory mid-session --
+# a `make clean` or `make build` in a second terminal -- strands the running
+# server: each later save re-renders only the pages it touched, so pages come
+# back but the stylesheets never do, and the preview degrades edit by edit
+# instead of failing outright. Rendering to memory removes the shared directory.
serve-docs: ## Preview the docs alone at http://localhost:1313/docs/
- cd $(DOCS_DIR) && $(HUGO) server --config hugo.yaml -D --disableFastRender
+ cd $(DOCS_DIR) && $(HUGO) server --config hugo.yaml -D --disableFastRender --renderToMemory
# ── Web (Next.js) ──────────────────────────────────────────────────────────
.PHONY: serve-web
From 2d6b28394cc22db0149e8493c659fc1f5b82451d Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Tue, 25 Aug 2026 16:56:25 -0500
Subject: [PATCH 10/70] Phase 1, review 4
Signed-off-by: Rachael Graham
---
.../kagent/1.x/about/agent-substrate.md | 33 ++++++++++-----
.../content/kagent/1.x/about/architecture.md | 41 ++++++++++++-------
.../1.x/get-started/your-first-agent.md | 6 ++-
3 files changed, 52 insertions(+), 28 deletions(-)
diff --git a/docs-site/content/kagent/1.x/about/agent-substrate.md b/docs-site/content/kagent/1.x/about/agent-substrate.md
index fc508f34..d77054a2 100644
--- a/docs-site/content/kagent/1.x/about/agent-substrate.md
+++ b/docs-site/content/kagent/1.x/about/agent-substrate.md
@@ -5,27 +5,36 @@ weight: 40
author: kagent.dev
---
-[Architecture]({{< link path="about/architecture" >}}) covers where an Actor fits between an AgentInstance and a running conversation. This page covers how Agent Substrate itself runs that Actor: on what compute, inside what sandbox, and how it suspends and resumes without staying resident the whole time.
+[Architecture]({{< link path="about/architecture" >}}) established that every AgentInstance runs on an Actor. This page explains what an Actor is built from and what it runs on: the ActorTemplate it is created from, the compute that hosts it, the sandbox that isolates it, and the snapshot cycle that lets it suspend when idle and resume on demand.
-## Workers and WorkerPools
+## ActorTemplate
-A **WorkerPool** is a Kubernetes custom resource that an operator provisions before any Harness can create AgentInstances. It defines a pool of pre-started sandbox pods, called **Workers**, along with the sandbox technology those Workers use.
+Every Actor is created from an **ActorTemplate**, the compiled definition that the kagent controller produces from a Harness and AgentTemplate pair.
-A Worker is not something an operator creates directly. Substrate manages Workers itself, keeping enough of them ready in each WorkerPool so that an Actor can start or resume on one immediately, without waiting on the Kubernetes scheduler to place a new Pod.
+What Substrate adds is enforcement. Substrate rejects any change to an ActorTemplate's spec after it is created, so immutability is a property of the resource itself rather than a convention that the controller follows. That immutability requires the controller to create a new ActorTemplate for every compiled revision instead of editing an existing one, and allows the controller to safely reclaim an old ActorTemplate once no AgentInstance references it.
-## Sandboxing
+## Workers and WorkerPools
-Because an Actor often runs a model-directed agent that calls tools and executes commands, Substrate runs each Actor in an isolated sandbox rather than a plain container. A WorkerPool's `sandboxClass` field selects the sandbox technology for its Workers: [gVisor](https://gvisor.dev) or a micro-VM technology such as [Kata Containers](https://katacontainers.io). Both technologies isolate an Actor from its Worker's host kernel, and both support the suspend and resume operations that the rest of this page covers.
+An Actor needs somewhere to run. Each Actor runs on a **Worker**: a pre-started, sandboxed pod that hosts at most one Actor at a time. Instead of starting a new pod each time an AgentInstance needs an Actor, Substrate schedules that Actor onto a Worker that is already running and waiting.
-## ActorTemplate
+Workers come from a **WorkerPool**, a Kubernetes custom resource that an operator provisions before any Harness can create AgentInstances. A WorkerPool declares how many Workers to keep running and which sandbox technology those Workers use.
-An **ActorTemplate** is the compiled, immutable definition that a new Actor is created from. [Architecture]({{< link path="about/architecture" >}}) covers how the kagent controller compiles a Harness and AgentTemplate pair into one. Substrate rejects any change to an ActorTemplate's spec after creation, so the kagent controller creates a new ActorTemplate for every compiled revision rather than editing an existing one, and reclaims old ones once no AgentInstance references them.
+An operator never creates a Worker directly. Substrate manages them, keeping enough ready in each WorkerPool so that an Actor can start or resume on one immediately, without waiting on the Kubernetes scheduler to place a new Pod.
+
+## Sandboxing
+
+Because an Actor often runs a model-directed agent that calls tools and executes commands, Substrate runs each Actor in an isolated sandbox rather than a plain container. A WorkerPool's `sandboxClass` field selects the sandbox technology for its Workers: [gVisor](https://gvisor.dev) or a micro-VM technology such as [Kata Containers](https://katacontainers.io). Both technologies isolate an Actor from its Worker's host kernel, and both support suspend and resume operations.
## Suspend, snapshot, and resume
-Substrate's density model rests on one fact about agent workloads: an Actor spends most of its time idle, waiting on a person or a large language model (LLM) to respond, not actively computing. Substrate exploits that by suspending idle Actors and reclaiming their Worker, then resuming them on demand when traffic arrives. Suspending and resuming this way lets a WorkerPool run far more Actors than it has Workers for at any one moment.
+Substrate's density model rests on one fact about agent workloads: an Actor spends most of its time idle, waiting on a person or a large language model (LLM) to respond, not actively computing. Substrate exploits that by suspending idle Actors and reclaiming their Worker, then resuming them on demand when traffic arrives. Suspending and resuming allows a WorkerPool to run far more Actors than it has Workers for at any given moment.
-The following diagram traces an Actor through one suspend-and-resume cycle. Read it left to right: a WorkerPool hosts Workers, a Worker hosts a running Actor, suspending that Actor produces a snapshot, and a tag on that snapshot lets a later Actor resume from it on whichever Worker is free.
+The following diagram traces an Actor through one suspend-and-resume cycle.
+1. A WorkerPool hosts Workers.
+2. A Worker hosts a running Actor.
+3. Suspending that Actor produces a snapshot.
+4. That snapshot is tagged.
+5. A later Actor uses the tag to resume from the snapshot on whichever Worker is free.
```mermaid
flowchart LR
@@ -37,7 +46,9 @@ flowchart LR
tag -->|resume| worker2
```
-Suspending an Actor writes its full state to an immutable **ActorSnapshot** and frees the Worker it was running on. An **ActorSnapshotTag** gives that snapshot a stable, human-meaningful name, so callers do not need to track Substrate's internal snapshot identity. A tag's target can be updated to point at a newer snapshot without changing the tag's own name, and a snapshot cannot be deleted while any tag still points to it. Resuming reads the tagged snapshot and restores it onto whichever Worker in the pool is free, not necessarily the Worker the Actor originally ran on.
+Suspending an Actor writes its full state to an immutable **ActorSnapshot** and frees the Worker that it was running on. Resuming reads that snapshot back and restores the Actor onto whichever Worker in the pool is free, which is not necessarily the Worker that it originally ran on. Because the snapshot captures the Actor's full state, the conversation continues from where it left off.
+
+An **ActorSnapshotTag** gives a snapshot a stable, human-meaningful name, so callers do not need to track Substrate's internal snapshot identity. A tag can be repointed at a newer snapshot without its own name changing, and Substrate does not delete a snapshot while any tag still points to it.
Substrate's own target for this cycle is 100ms at the 95th percentile, measured from the moment traffic arrives for a suspended Actor to the moment that Actor can receive it.
diff --git a/docs-site/content/kagent/1.x/about/architecture.md b/docs-site/content/kagent/1.x/about/architecture.md
index aaa2872a..68e6e15f 100644
--- a/docs-site/content/kagent/1.x/about/architecture.md
+++ b/docs-site/content/kagent/1.x/about/architecture.md
@@ -5,23 +5,27 @@ weight: 30
author: kagent.dev
---
-[Core concepts]({{< link path="about/core-concepts" >}}) defines Harness, AgentTemplate, AgentInstance, and Actor on their own. This page connects them into one system: how applying a Harness and AgentTemplate leads to a running conversation, and which parts of that path Kubernetes governs versus which parts kagent governs itself.
+The previous page defined the [core concepts]({{< link path="about/core-concepts" >}}) of Harness, AgentTemplate, AgentInstance, and Actor. This page connects them into one system: how applying a Harness and AgentTemplate leads to a running conversation, and which parts of that path Kubernetes governs versus which parts kagent governs itself.
-kagent 1.0 splits authorization across two planes, not one:
+## Two authorization planes
-- The **Kubernetes plane** governs the Harness and AgentTemplate custom resources. Kubernetes Role-Based Access Control (RBAC) decides who can create, read, or edit them, exactly as it would for any other Custom Resource Definition (CRD).
-- The **kagent plane** governs AgentInstances: creating one, suspending or resuming it, sharing it, deleting it, and holding a conversation with it. kagent's own gRPC authentication and authorization decide who can do these things, independent of Kubernetes RBAC.
+kagent 1.0 splits authorization across two planes:
-Someone with RBAC access to apply a Harness and AgentTemplate does not automatically get access to create or talk to AgentInstances that use them, and the reverse is also true. The following diagram shows where the boundary between the two planes falls, and the walkthrough after it follows a request across that boundary from start to finish.
+- The **Kubernetes plane** governs the Harness and AgentTemplate custom resources. Kubernetes Role-Based Access Control (RBAC) decides who can create, read, or edit the resources, exactly as it would for any other Custom Resource Definition (CRD).
+- The **kagent plane** governs any interactions involving AgentInstances, such as creating, suspending, resuming, sharing, deleting, and holding a conversation with an AgentInstance. kagent's own gRPC authentication and authorization decide who can complete these interactions, independent of Kubernetes RBAC.
+
+Someone with Kubernetes RBAC access to apply a Harness and AgentTemplate does not automatically have access to create or talk to AgentInstances that use them, and the reverse is also true. The following diagram shows where the boundary between the two planes falls.
+
```mermaid
flowchart TB
+
subgraph k8s["Kubernetes plane (RBAC)"]
operator["Operator kubectl apply"]
harness["Harness"]
template["AgentTemplate"]
controller["kagent controller"]
- actortemplate["ActorTemplate (Substrate)"]
+ actortemplate["ActorTemplate (Substrate)"]
operator --> harness
operator --> template
harness --> controller
@@ -31,31 +35,38 @@ flowchart TB
subgraph kagentplane["kagent plane (gRPC auth)"]
caller["Caller"]
- instance["AgentInstance"]
gateway["A2A gateway"]
- actor["Actor (Substrate)"]
- caller -->|CreateAgentInstance| instance
- instance -->|created from| actortemplate
- instance -->|runs on| actor
+ instance["AgentInstance"]
+ actor["Actor (Substrate)"]
caller -->|A2A conversation| gateway
+ caller -->|CreateAgentInstance| instance
gateway -->|routes to| actor
+ instance -->|runs on| actor
end
+ %% Declared outside both subgraphs on purpose: a node belongs to whichever
+ %% subgraph first references it, so putting this edge inside the kagent plane
+ %% would pull ActorTemplate out of the Kubernetes plane.
+ actortemplate -->|instantiated as| instance
+ %% Invisible link: forces the kagent plane to sit fully below the Kubernetes
+ %% plane. Without it, the layout engine staggers the two planes diagonally.
+ %% actortemplate ~~~ caller
+
classDef crd stroke:#a78bfa,fill:transparent
class harness,template crd
```
-Follow the Kubernetes plane first. An operator applies a Harness and an AgentTemplate, governed by Kubernetes RBAC. The kagent controller watches for a valid pair, one whose `allowedAgentTemplates` selector matches, and compiles it into an ActorTemplate on Substrate.
+Follow the **Kubernetes plane** first. An operator applies a Harness and an AgentTemplate, governed by Kubernetes RBAC. The kagent controller watches for a valid pair with a matching `allowedAgentTemplates` selector, and compiles it into an ActorTemplate on Substrate.
-The kagent plane starts once that ActorTemplate exists. A caller, who may or may not be the same person as the operator, calls `CreateAgentInstance` through kagent's gRPC API. This call is governed by kagent's own authentication and authorization, not by Kubernetes RBAC. kagent creates the AgentInstance from the latest compiled ActorTemplate, and that AgentInstance runs on an Actor.
+The **kagent plane** starts once that ActorTemplate exists. A caller, who may or may not be the same person as the operator, calls `CreateAgentInstance` through kagent's gRPC API. This call is governed by kagent's own authentication and authorization, not by Kubernetes RBAC. kagent creates the AgentInstance from the newest ActorTemplate that compiled successfully, and that AgentInstance runs on an Actor.
-From there, the caller holds a conversation with the AgentInstance over the A2A (Agent-to-Agent) protocol. The A2A gateway routes each request to the Actor running behind the target AgentInstance, so the caller only ever needs to know an AgentInstance's identity, never which Actor or Worker is behind it.
+From there, the caller holds a conversation with the AgentInstance over the A2A (Agent-to-Agent) protocol. The A2A gateway routes each request to the Actor running behind the target AgentInstance. This means that the caller only ever needs to know an AgentInstance's identity, never which Actor or Worker is behind it.
## Why two planes
Kubernetes RBAC is designed to authorize configuration changes: who can create a Deployment, edit a ConfigMap, or in this case, apply a Harness or AgentTemplate. It is not designed to authorize a running conversation, share access to it with another user, or scope who can suspend it. kagent's gRPC plane exists to authorize exactly those actions, at the granularity of a single AgentInstance rather than a namespace or a resource kind.
-This split also keeps the two lifecycles independent. Editing a Harness or AgentTemplate does not affect AgentInstances already running against the ActorTemplate they were created from. It only affects new AgentInstances, created after the edit is compiled.
+This split also keeps the two lifecycles independent. Editing a Harness or AgentTemplate does not affect AgentInstances already running against the ActorTemplate that they were created from. It only affects new AgentInstances, created after the edit is compiled.
## Next steps
diff --git a/docs-site/content/kagent/1.x/get-started/your-first-agent.md b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
index 10fd20f4..f48db4db 100644
--- a/docs-site/content/kagent/1.x/get-started/your-first-agent.md
+++ b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
@@ -21,7 +21,7 @@ This guide walks you through creating an agent, from applying a Harness and an A
## Create a Harness and an AgentTemplate
-1. Apply a `Harness` that uses kagent's native runtime.
+1. Apply a `Harness` that uses kagent's native runtime. Its `substrate` section names the [WorkerPool]({{< link path="about/agent-substrate#workers-and-workerpools" >}}) that this Harness's Actors run on, and the object storage location for their [snapshots]({{< link path="about/agent-substrate#suspend-snapshot-and-resume" >}}).
```yaml
apiVersion: kagent.dev/v1alpha3
kind: Harness
@@ -48,7 +48,7 @@ This guide walks you through creating an agent, from applying a Harness and an A
> [!NOTE]
> An `AgentTemplate` has no field naming this Harness. The `kagent.dev/harness: my-first-harness` selector is a convention that this guide uses to match the `kagent.dev/harness` label in the next step. However, you can choose any label key and value, as long as the Harness selector and the AgentTemplate's labels match.
-2. Apply an `AgentTemplate` that is labeled to match the Harness's `allowedAgentTemplates` selector. The `ModelConfig` field references the `default-model-config` that was automatically created for the model provider API key that you provided during kagent installation.
+2. Apply an `AgentTemplate` that is labeled to match the Harness's `allowedAgentTemplates` selector. The `modelConfig` field references the `default-model-config` ModelConfig that was automatically created for the model provider API key that you provided during kagent installation.
```yaml
apiVersion: kagent.dev/v1alpha3
kind: AgentTemplate
@@ -91,6 +91,8 @@ This guide walks you through creating an agent, from applying a Harness and an A
]
```
+ The `latestSuccessfulRevision` value is the compiled revision that kagent creates your AgentInstance from in the next section.
+
## Create the AgentInstance
1. Create an AgentInstance from the Harness and AgentTemplate pair.
From d745f9bf5f2d557b92fab632057a0b0e4c3a8de4 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Tue, 25 Aug 2026 16:58:36 -0500
Subject: [PATCH 11/70] Phase 1, review 5: restore dropped relative pronoun
Keep "that" in the restrictive relative clause on the Agent Substrate
intro so all four items in the list read in parallel.
Co-Authored-By: Claude Opus 5 (1M context)
Signed-off-by: Rachael Graham
---
docs-site/content/kagent/1.x/about/agent-substrate.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs-site/content/kagent/1.x/about/agent-substrate.md b/docs-site/content/kagent/1.x/about/agent-substrate.md
index d77054a2..b7f167cf 100644
--- a/docs-site/content/kagent/1.x/about/agent-substrate.md
+++ b/docs-site/content/kagent/1.x/about/agent-substrate.md
@@ -5,7 +5,7 @@ weight: 40
author: kagent.dev
---
-[Architecture]({{< link path="about/architecture" >}}) established that every AgentInstance runs on an Actor. This page explains what an Actor is built from and what it runs on: the ActorTemplate it is created from, the compute that hosts it, the sandbox that isolates it, and the snapshot cycle that lets it suspend when idle and resume on demand.
+[Architecture]({{< link path="about/architecture" >}}) established that every AgentInstance runs on an Actor. This page explains what an Actor is built from and what it runs on: the ActorTemplate that it is created from, the compute that hosts it, the sandbox that isolates it, and the snapshot cycle that lets it suspend when idle and resume on demand.
## ActorTemplate
From 03ca8d2ad35f32112f4d8e628ce3848122807f18 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Tue, 25 Aug 2026 17:41:55 -0500
Subject: [PATCH 12/70] Write Phase 2 Installation page for kagent 1.0
Adds the Setup section and its Installation page, covering the three
install phases: Agent Substrate, the identity bootstrap, and kagent.
The install path was verified end to end on a local kind cluster
(Kubernetes 1.35, Substrate 0.0.20) by reproducing the kagent CI e2e
job. All 7 e2e tests passed. Notably, the identity bootstrap is
mandatory and no Helm chart performs it: without it every ate-system
pod stays in ContainerCreating on FailedMount for the podidentity and
servicedns volumes. The 0.x page sidestepped this with
controller.substrate.ateApiInsecure, which no longer exists.
Also notes that the kagent CLI cannot produce a working 1.0 install,
since kagent install has no Agent Substrate awareness.
Co-Authored-By: Claude Opus 5 (1M context)
Signed-off-by: Rachael Graham
---
.../assets/versions/agent-substrate-1x.md | 1 +
docs-site/content/kagent/1.x/setup/_index.md | 6 +
.../content/kagent/1.x/setup/installation.md | 249 ++++++++++++++++++
3 files changed, 256 insertions(+)
create mode 100644 docs-site/assets/versions/agent-substrate-1x.md
create mode 100644 docs-site/content/kagent/1.x/setup/_index.md
create mode 100644 docs-site/content/kagent/1.x/setup/installation.md
diff --git a/docs-site/assets/versions/agent-substrate-1x.md b/docs-site/assets/versions/agent-substrate-1x.md
new file mode 100644
index 00000000..eb1591a7
--- /dev/null
+++ b/docs-site/assets/versions/agent-substrate-1x.md
@@ -0,0 +1 @@
+0.0.20
\ No newline at end of file
diff --git a/docs-site/content/kagent/1.x/setup/_index.md b/docs-site/content/kagent/1.x/setup/_index.md
new file mode 100644
index 00000000..3a0e64be
--- /dev/null
+++ b/docs-site/content/kagent/1.x/setup/_index.md
@@ -0,0 +1,6 @@
+---
+title: Setup
+description: Install kagent and configure the model providers that your agents use.
+weight: 30
+author: kagent.dev
+---
\ No newline at end of file
diff --git a/docs-site/content/kagent/1.x/setup/installation.md b/docs-site/content/kagent/1.x/setup/installation.md
new file mode 100644
index 00000000..f7f24ccf
--- /dev/null
+++ b/docs-site/content/kagent/1.x/setup/installation.md
@@ -0,0 +1,249 @@
+---
+title: Install kagent
+description: Install kagent 1.0 and Agent Substrate on a Kubernetes cluster.
+weight: 10
+author: kagent.dev
+---
+
+kagent 1.0 runs every agent on [Agent Substrate]({{< link path="about/agent-substrate" >}}), so an installation sets up two systems in the same cluster. Agent Substrate provides the sandboxed compute that agents run on, and kagent provides the Harness, AgentTemplate, and AgentInstance API that you author against.
+
+## About installing kagent
+
+Installation has three phases, and the order matters.
+
+- **Install Agent Substrate**: Deploys the Agent Substrate control plane and data plane into the `ate-system` namespace.
+- **Bootstrap Agent Substrate identity**: Creates the certificate authority (CA) pools, the JSON Web Token (JWT) authority pool, and the authentication configuration that Agent Substrate components use to prove identity to each other and to kagent.
+- **Install kagent**: Deploys the kagent controller with the Agent Substrate integration enabled, and provisions the WorkerPool that agents run on.
+
+> [!IMPORTANT]
+> The bootstrap phase is required, and no Helm chart performs it for you. Until you complete it, every pod in the `ate-system` namespace stays in `ContainerCreating` and reports `FailedMount` events for the `podidentity` and `servicedns` volumes. Agent Substrate authenticates its components with mutual Transport Layer Security (mTLS), and the identity material that mTLS depends on is created by the `kubectl-ate` plugin, not by Helm.
+
+> [!NOTE]
+> Install kagent 1.0 with Helm. The `kagent install` command does not provision Agent Substrate and cannot produce a working 1.0 installation.
+
+## Before you begin
+
+You need the following tools and cluster capabilities.
+
+- **Kubernetes 1.35 or later**: Agent Substrate requires the `ClusterTrustBundle`, `ClusterTrustBundleProjection`, and `PodCertificateRequest` feature gates, along with the `certificates.k8s.io/v1beta1` API. Kubernetes 1.35 enables all of them by default. On an earlier version, enable them explicitly on the API server.
+- **Helm 3 and `kubectl`**: Both must be on your `PATH`.
+- **`jq` and `openssl`**: The bootstrap phase uses both to extract a root certificate from a generated CA pool.
+- **A model provider API key**: The examples on this page use OpenAI. For other providers, see [Configure model providers]({{< link path="setup/configure-model-providers" >}}).
+
+### Prepare a cluster
+
+Confirm that your cluster exposes the certificate APIs that Agent Substrate depends on.
+
+{{< tabs >}}
+{{% tab name="Existing cluster" %}}
+Check that both resources are present.
+```bash
+kubectl api-resources --api-group=certificates.k8s.io
+```
+
+Example output, truncated to the two resources that matter.
+```console
+NAME APIVERSION NAMESPACED KIND
+clustertrustbundles certificates.k8s.io/v1beta1 false ClusterTrustBundle
+podcertificaterequests certificates.k8s.io/v1beta1 true PodCertificateRequest
+```
+
+If either resource is missing, enable the feature gates on your API server before you continue.
+{{% /tab %}}
+{{% tab name="Local kind cluster" %}}
+Create a kind cluster on a node image that includes the certificate APIs.
+```bash
+kind create cluster --name kagent --image kindest/node:v1.35.0
+```
+
+An earlier node image does not expose `certificates.k8s.io/v1beta1`, and Agent Substrate cannot start on it.
+{{% /tab %}}
+{{< /tabs >}}
+
+### Install the kubectl-ate plugin
+
+Agent Substrate ships `kubectl-ate` as a standalone binary that is published with each Agent Substrate release. Download the build that matches your operating system and architecture, then put it on your `PATH` so that `kubectl` finds it as a plugin.
+```bash
+curl -fsSL -o kubectl-ate \
+ "https://github.com/kagent-dev/substrate/releases/download/v{{< reuse "versions/agent-substrate-1x.md" >}}/kubectl-ate-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m | sed 's/x86_64/amd64/; s/aarch64/arm64/')"
+chmod +x kubectl-ate
+sudo mv kubectl-ate /usr/local/bin/
+```
+
+Confirm that `kubectl` picks the plugin up.
+```bash
+kubectl ate --help
+```
+
+## Install Agent Substrate
+
+1. Install the Agent Substrate custom resource definitions (CRDs).
+ ```bash
+ helm upgrade --install substrate-crds \
+ oci://ghcr.io/kagent-dev/substrate/helm/substrate-crds \
+ --version {{< reuse "versions/agent-substrate-1x.md" >}} \
+ --namespace ate-system --create-namespace
+ ```
+2. Install the Agent Substrate control plane and data plane. Do not add `--wait` to this command, because the pods cannot become ready until you bootstrap identity in the next section.
+ ```bash
+ helm upgrade --install substrate \
+ oci://ghcr.io/kagent-dev/substrate/helm/substrate \
+ --version {{< reuse "versions/agent-substrate-1x.md" >}} \
+ --namespace ate-system
+ ```
+
+## Bootstrap Agent Substrate identity
+
+Agent Substrate signs pod identities and service certificates from CA pools that you generate, and it authenticates callers against a JWT authority pool. The `kubectl-ate admin` commands create that material as Kubernetes secrets, and a ConfigMap tells the Agent Substrate API server which token issuer to trust.
+
+1. Create the CA pools that sign service DNS and pod identity certificates.
+ ```bash
+ kubectl ate admin make-ca-pool --ca-id=1 \
+ --name=service-dns-ca-pool \
+ --secret-namespace=podcertificate-controller-system
+ kubectl ate admin make-ca-pool --ca-id=1 \
+ --name=pod-identity-ca-pool \
+ --secret-namespace=podcertificate-controller-system
+ ```
+2. Create the actor identity pools that Agent Substrate uses to issue and verify actor credentials.
+ ```bash
+ kubectl ate admin make-jwt-pool --key-id=1 \
+ --name=actor-id-jwt-pool \
+ --secret-namespace=ate-system
+ kubectl ate admin make-ca-pool --ca-id=1 \
+ --name=actor-id-ca-pool \
+ --secret-namespace=ate-system
+ ```
+3. Extract the actor identity root certificate and store it in the secret that the Agent Substrate API server reads.
+ ```bash
+ actor_id_ca_root="$(kubectl get secret actor-id-ca-pool -n ate-system \
+ -o jsonpath='{.data.pool}' | base64 --decode \
+ | jq -r '.CAs[0].RootCertificateDER' | base64 --decode \
+ | openssl x509 -inform der -outform pem)"
+
+ kubectl create secret generic actor-id-ca-certs -n ate-system \
+ --from-literal=ca.crt="${actor_id_ca_root}"
+ ```
+4. Create the authentication configuration. The `kubernetes` provider accepts Kubernetes ServiceAccount tokens that are issued for the Agent Substrate API server audience.
+ ```bash
+ kubectl create configmap ate-api-authentication -n ate-system \
+ --from-literal=authentication.yaml='actorIdentityJWTProvider: kubernetes
+ jwtProviders:
+ - name: kubernetes
+ issuer: https://kubernetes.default.svc
+ audiences: [api.ate-system.svc]
+ certificateAuthorityFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
+ discoveryTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
+ '
+ ```
+5. Roll Agent Substrate out again so that its pods mount the identity material, and wait for them to become ready.
+ ```bash
+ helm upgrade substrate \
+ oci://ghcr.io/kagent-dev/substrate/helm/substrate \
+ --version {{< reuse "versions/agent-substrate-1x.md" >}} \
+ --namespace ate-system --reuse-values --wait --timeout 10m
+ ```
+6. Verify that Agent Substrate is running.
+ ```bash
+ kubectl get pods -n ate-system
+ ```
+ Example output.
+ ```console
+ NAME READY STATUS RESTARTS AGE
+ ate-api-server-59fccdf6dc-f77h6 1/1 Running 3 9m
+ ate-api-server-59fccdf6dc-q49hv 1/1 Running 3 9m
+ ate-controller-6c788456f8-zh2rm 1/1 Running 0 9m
+ atelet-wxm5s 1/1 Running 0 9m
+ atenet-egress-66f5699886-6rgg9 2/2 Running 0 9m
+ atenet-router-645bd98bdd-dlrv2 2/2 Running 0 9m
+ dns-6bf4fff5bb-zqsnm 2/2 Running 0 9m
+ postgres-0 1/1 Running 0 9m
+ rustfs-56cdbc9dcb-2ntck 1/1 Running 0 9m
+ rustfs-bucket-init-4pxgt 0/1 Completed 0 9m
+ ```
+
+## Install kagent
+
+The kagent chart connects the controller to Agent Substrate and creates a WorkerPool for agents to run on. A WorkerPool is platform capacity that you provision once, and every Harness references it. No Harness can run until a WorkerPool exists.
+
+1. Install the kagent CRDs.
+ ```bash
+ helm upgrade --install kagent-crds \
+ oci://ghcr.io/kagent-dev/kagent/helm/kagent-crds \
+ --version \
+ --namespace kagent --create-namespace --wait
+ ```
+2. Set your model provider API key.
+ ```bash
+ export OPENAI_API_KEY="your-api-key-here"
+ ```
+3. Install kagent with the Agent Substrate integration enabled. Set `substrateWorkerPool.ateomImage` explicitly, because the chart has no default for it and the install fails without it whenever `substrateWorkerPool.create` is `true`.
+ ```bash
+ helm upgrade --install kagent \
+ oci://ghcr.io/kagent-dev/kagent/helm/kagent \
+ --version \
+ --namespace kagent --create-namespace --timeout 10m \
+ --set providers.default=openAI \
+ --set providers.openAI.apiKey="${OPENAI_API_KEY}" \
+ --set controller.substrate.enabled=true \
+ --set controller.substrate.ateApiEndpoint=dns:///api.ate-system.svc:443 \
+ --set controller.substrate.atenetRouterURL=http://atenet-router.ate-system.svc:80 \
+ --set controller.substrate.defaultWorkerPool.name=kagent-default \
+ --set substrateWorkerPool.create=true \
+ --set substrateWorkerPool.replicas=1 \
+ --set-string substrateWorkerPool.ateomImage=ghcr.io/kagent-dev/substrate/ateom-gvisor:v{{< reuse "versions/agent-substrate-1x.md" >}}
+ ```
+4. Wait for the controller to roll out.
+ ```bash
+ kubectl rollout status deployment/kagent-controller -n kagent --timeout=300s
+ ```
+
+> [!NOTE]
+> The kagent controller can restart a few times during a first install while it waits for its bundled PostgreSQL database to accept connections. The controller logs `dial tcp ...:5432: connect: connection refused` and then recovers on its own. A restart loop that reports an `ate-api` dial failure instead points at an incomplete identity bootstrap.
+
+## Verify the installation
+
+1. Confirm that the kagent pods are running.
+ ```bash
+ kubectl get pods -n kagent
+ ```
+ Example output.
+ ```console
+ NAME READY STATUS RESTARTS AGE
+ kagent-controller-659b58768b-2k6h4 1/1 Running 3 2m
+ kagent-default-864fdc4c94-xbsl9 1/1 Running 0 2m
+ kagent-postgresql-65cc684b78-9qbh2 1/1 Running 0 2m
+ ```
+2. Confirm that the WorkerPool reports a ready replica. Agents cannot start until the pool is ready.
+ ```bash
+ kubectl get workerpools -n kagent
+ ```
+ Example output.
+ ```console
+ NAMESPACE NAME DESIRED REPLICAS READY AGE
+ kagent kagent-default 1 1 1 2m
+ ```
+3. Note how you reach the kagent gRPC API, which serves the AgentInstance lifecycle and conversation calls. [Your first agent]({{< link path="get-started/your-first-agent" >}}) assumes the port-forward.
+ {{< tabs >}}
+ {{% tab name="Cloud Provider LoadBalancer" %}}
+ Read the external address of the controller service. The gRPC API listens on port `8084`.
+ ```bash
+ kubectl get svc -n kagent kagent-controller \
+ -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}"
+ ```
+ {{% /tab %}}
+ {{% tab name="Port-forward for local testing" %}}
+ Forward the gRPC port and leave the command running. The API is then available at `localhost:8084`.
+ ```bash
+ kubectl port-forward -n kagent svc/kagent-controller 8084:8084
+ ```
+ On a local kind cluster, use the port-forward. kind assigns a LoadBalancer address that is routable from inside the cluster, but not from your workstation.
+ {{% /tab %}}
+ {{< /tabs >}}
+
+## Next steps
+
+{{< cards >}}
+ {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Apply a Harness and AgentTemplate, and talk to the AgentInstance they produce." >}}
+ {{< card link=`{{< link path="setup/configure-model-providers" >}}` title="Configure model providers" subtitle="Point kagent at OpenAI, Anthropic, Gemini, or a provider of your own." >}}
+{{< /cards >}}
From d74f87f820c0cfdcee9802462d699d212bb37a3d Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Tue, 25 Aug 2026 17:48:53 -0500
Subject: [PATCH 13/70] rm newlines
Signed-off-by: Rachael Graham
---
docs-site/assets/versions/agent-substrate.md | 2 +-
docs-site/assets/versions/jaeger.md | 2 +-
docs-site/assets/versions/kagent.md | 2 +-
docs-site/assets/versions/kmcp.md | 2 +-
docs-site/assets/versions/loki.md | 2 +-
docs-site/assets/versions/max-kube.md | 2 +-
docs-site/assets/versions/tempo.md | 2 +-
7 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/docs-site/assets/versions/agent-substrate.md b/docs-site/assets/versions/agent-substrate.md
index 1750564f..99d85ecd 100644
--- a/docs-site/assets/versions/agent-substrate.md
+++ b/docs-site/assets/versions/agent-substrate.md
@@ -1 +1 @@
-0.0.6
+0.0.6
\ No newline at end of file
diff --git a/docs-site/assets/versions/jaeger.md b/docs-site/assets/versions/jaeger.md
index c966188e..34014745 100644
--- a/docs-site/assets/versions/jaeger.md
+++ b/docs-site/assets/versions/jaeger.md
@@ -1 +1 @@
-4.4.7
+4.4.7
\ No newline at end of file
diff --git a/docs-site/assets/versions/kagent.md b/docs-site/assets/versions/kagent.md
index 7e310bae..6f060dcb 100644
--- a/docs-site/assets/versions/kagent.md
+++ b/docs-site/assets/versions/kagent.md
@@ -1 +1 @@
-0.9.9
+0.9.9
\ No newline at end of file
diff --git a/docs-site/assets/versions/kmcp.md b/docs-site/assets/versions/kmcp.md
index 0d91a54c..9325c3cc 100644
--- a/docs-site/assets/versions/kmcp.md
+++ b/docs-site/assets/versions/kmcp.md
@@ -1 +1 @@
-0.3.0
+0.3.0
\ No newline at end of file
diff --git a/docs-site/assets/versions/loki.md b/docs-site/assets/versions/loki.md
index 2496b04b..57f7599b 100644
--- a/docs-site/assets/versions/loki.md
+++ b/docs-site/assets/versions/loki.md
@@ -1 +1 @@
-6.24.0
+6.24.0
\ No newline at end of file
diff --git a/docs-site/assets/versions/max-kube.md b/docs-site/assets/versions/max-kube.md
index f7613c2d..f71ef947 100644
--- a/docs-site/assets/versions/max-kube.md
+++ b/docs-site/assets/versions/max-kube.md
@@ -1 +1 @@
-1.35
+1.35
\ No newline at end of file
diff --git a/docs-site/assets/versions/tempo.md b/docs-site/assets/versions/tempo.md
index 15b989e3..71bd5d9e 100644
--- a/docs-site/assets/versions/tempo.md
+++ b/docs-site/assets/versions/tempo.md
@@ -1 +1 @@
-1.16.0
+1.16.0
\ No newline at end of file
From c6eb2a49c9196eff3d50520aa1945887a38a24ae Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Tue, 25 Aug 2026 17:51:22 -0500
Subject: [PATCH 14/70] Write Phase 2 Suspend and resume page, and fix two
Phase 1 errors
Adds the Substrate runtime section and its suspend-and-resume page,
covering the Actor lifecycle operations, snapshot scopes, golden and
per-Actor snapshots, kagent's per-turn suspension, on-demand resume,
and checkpoint retention.
Titled "Suspend and resume" rather than the scope doc's "Sessions and
passivation". Neither "passivation" nor a conversation-level "session"
appears anywhere in Substrate or kagent: Substrate's lifecycle
vocabulary is Suspend, Pause, and Resume.
Fixes two errors in about/agent-substrate.md:
- An ActorSnapshotTag cannot be repointed at a newer snapshot. Both
snapshot.atespace and snapshot.name are enforced immutable on
update, and only the visibility scope can change.
- Spells out the ordinal in "95th percentile" per Solo.Ordinal. That
error had gone undetected because Vale's BlockIgnores skips page
content following a code fence, which on that page is the mermaid
diagram.
Co-Authored-By: Claude Opus 5 (1M context)
Signed-off-by: Rachael Graham
---
.../kagent/1.x/about/agent-substrate.md | 4 +-
.../kagent/1.x/substrate-runtime/_index.md | 6 ++
.../substrate-runtime/suspend-and-resume.md | 75 +++++++++++++++++++
3 files changed, 83 insertions(+), 2 deletions(-)
create mode 100644 docs-site/content/kagent/1.x/substrate-runtime/_index.md
create mode 100644 docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
diff --git a/docs-site/content/kagent/1.x/about/agent-substrate.md b/docs-site/content/kagent/1.x/about/agent-substrate.md
index b7f167cf..44ead771 100644
--- a/docs-site/content/kagent/1.x/about/agent-substrate.md
+++ b/docs-site/content/kagent/1.x/about/agent-substrate.md
@@ -48,9 +48,9 @@ flowchart LR
Suspending an Actor writes its full state to an immutable **ActorSnapshot** and frees the Worker that it was running on. Resuming reads that snapshot back and restores the Actor onto whichever Worker in the pool is free, which is not necessarily the Worker that it originally ran on. Because the snapshot captures the Actor's full state, the conversation continues from where it left off.
-An **ActorSnapshotTag** gives a snapshot a stable, human-meaningful name, so callers do not need to track Substrate's internal snapshot identity. A tag can be repointed at a newer snapshot without its own name changing, and Substrate does not delete a snapshot while any tag still points to it.
+An **ActorSnapshotTag** gives a snapshot a stable, human-meaningful name, so callers do not need to track Substrate's internal snapshot identity. A tag names one snapshot permanently, and only its visibility scope can change afterward. A tag also acts as a retention pin, so Substrate does not delete a snapshot while a tag still names it.
-Substrate's own target for this cycle is 100ms at the 95th percentile, measured from the moment traffic arrives for a suspended Actor to the moment that Actor can receive it.
+Substrate's own target for this cycle is 100 milliseconds at the ninety-fifth percentile, measured from the moment traffic arrives for a suspended Actor to the moment that Actor can receive it.
## Next steps
diff --git a/docs-site/content/kagent/1.x/substrate-runtime/_index.md b/docs-site/content/kagent/1.x/substrate-runtime/_index.md
new file mode 100644
index 00000000..7fc8789f
--- /dev/null
+++ b/docs-site/content/kagent/1.x/substrate-runtime/_index.md
@@ -0,0 +1,6 @@
+---
+title: Substrate runtime
+description: Learn how Agent Substrate isolates, suspends, and resumes the Actors that run your agents.
+weight: 60
+author: kagent.dev
+---
\ No newline at end of file
diff --git a/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md b/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
new file mode 100644
index 00000000..fe4f3d62
--- /dev/null
+++ b/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
@@ -0,0 +1,75 @@
+---
+title: Suspend and resume
+description: Learn how Agent Substrate suspends idle Actors to snapshots and resumes them on demand.
+weight: 20
+author: kagent.dev
+---
+
+An agent spends most of its life waiting. It waits on a person to reply, and it waits on a large language model (LLM) to answer. [Agent Substrate]({{< link path="about/agent-substrate" >}}) treats that idle time as reclaimable: it suspends an idle Actor into a snapshot, frees the Worker that the Actor was running on, and restores the Actor when traffic arrives for it. This page explains what a snapshot captures, when kagent suspends an Actor, and what happens when a suspended Actor is addressed again.
+
+## Actor lifecycle operations
+
+Agent Substrate provides three lifecycle operations, and each one moves an Actor between states that you can observe on the Actor record.
+
+- **Suspend**: Writes the Actor's state to a durable snapshot in snapshot storage, then frees its Worker. A running Actor is checkpointed on its Worker. A paused Actor's node-local snapshot is uploaded instead.
+- **Pause**: Takes a short-term checkpoint whose files stay on the node. Pausing pins the Actor to that node, because the following resume is prioritized onto the node that holds the snapshot files.
+- **Resume**: Restores a suspended or paused Actor onto a Worker, from its latest snapshot. The common path restores from a snapshot rather than cold-booting the workload.
+
+An Actor reports its position in that cycle through its state, which is one of `RESUMING`, `RUNNING`, `SUSPENDING`, `SUSPENDED`, `PAUSING`, `PAUSED`, `CRASHED`, or `DELETING`. Only a suspended Actor can be deleted.
+
+> [!NOTE]
+> Resume restores an Actor onto whichever Worker in the pool is free, which is not necessarily the Worker that the Actor ran on before. Suspend and resume are what let a WorkerPool carry far more Actors than it has Workers at any one moment.
+
+## What a snapshot captures
+
+An ActorTemplate's snapshot configuration decides how much of an Actor a given snapshot holds. Two scopes exist.
+
+- **`Full`**: Captures process memory, the root filesystem changes layered on top of the container image, and any attached durable volumes. A `Full` snapshot holds everything that is needed to resume the Actor hot, with its in-memory state intact.
+- **`Data`**: Captures only the contents of attached durable volumes. Process memory and the rest of the root filesystem are discarded, which makes the snapshot much cheaper to write and store.
+
+Scopes describe only what a snapshot captures, and they are configured per trigger. The `onPause` setting selects what a pause captures on the node, and `onCommit` selects what a suspend uploads to snapshot storage. What `onCommit` captures must be a subset of what `onPause` captures.
+
+A **DurableDir volume** is the per-Actor application data surface. Its contents are preserved by the `Data` scope, so they survive a suspend and resume cycle independently of process memory. How many such volumes an ActorTemplate can declare depends on its sandbox class. A `microvm` template can declare several, because they are subdirectories of a single shared filesystem. A `gvisor` template is limited to one, until gVisor accepts more than a single durable mount.
+
+When an Actor resumes from a `Data`-scope snapshot, the ActorTemplate's `onResume.fromData` setting decides where the rest of the guest state comes from. The default is `ColdBoot`, which starts the containers fresh from the container image with the durable volume contents restored over them.
+
+## Golden and per-Actor snapshots
+
+Two kinds of snapshot serve different purposes, and both appear in a normal installation.
+
+- **Golden snapshot**: Captured once, when an ActorTemplate is created, from a temporary golden boot of the workload. Every Actor of that template is first restored from this one shared snapshot, so a new Actor starts from an already-booted image rather than a cold start. An AgentTemplate is not ready until its golden snapshot exists, which is why the kagent controller reports `waiting for the ActorTemplate golden snapshot` while Agent Substrate captures it.
+- **Last snapshot**: The most recent per-Actor snapshot, written on every suspend and used to restore that specific Actor on its next resume. Because it carries the Actor's own accumulated state, the conversation continues from where it stopped.
+
+Snapshots are persisted to object storage, either Google Cloud Storage or Amazon Simple Storage Service (S3), so that Actor state is durable and portable across the cluster. A Harness names the location for its Actors' snapshots in its `substrate.snapshotPolicy` section.
+
+## Suspension between turns
+
+kagent does not wait for an Actor to go idle for a long stretch before suspending it. It suspends the Actor at every turn boundary, as soon as the conversation reaches a point where nothing is running.
+
+A turn reaches such a boundary when its task enters a terminal state, or when the task stops to wait on a person, which is the `INPUT_REQUIRED` and `AUTH_REQUIRED` case. At that point kagent suspends the Actor durably and records the exact snapshot that the suspend produced.
+
+The AgentInstance's own state does not change while this happens. It stays `READY` throughout, because suspension is a property of the runtime underneath it rather than of the conversation. A caller that lists AgentInstances sees a ready agent whether or not an Actor is currently running for it.
+
+> [!NOTE]
+> Creating an AgentInstance does not start an Actor running. The Actor is created suspended, and the first message addressed to the AgentInstance is what resumes it.
+
+## Resuming on demand
+
+Every Actor is reachable at a uniform address, `..actors.resources.substrate.ate.dev`, resolved by Agent Substrate's own Domain Name System (DNS) server. Traffic sent to that name is routed to the right Worker, and an Actor that is currently suspended is resumed automatically to receive it. Nothing in the calling path needs to know whether the Actor was running beforehand.
+
+Resume speed is what makes suspending at every turn boundary practical rather than costly. Agent Substrate's own target for this cycle is 100 milliseconds at the ninety-fifth percentile, measured from the moment traffic arrives for a suspended Actor to the moment that Actor can receive it.
+
+## Checkpoints
+
+A snapshot that Agent Substrate writes on suspend is transient. Agent Substrate is free to collect it once a newer snapshot supersedes it. A **checkpoint** makes one of those snapshots durable by pinning it.
+
+Creating a checkpoint attaches an ActorSnapshotTag to the snapshot that the AgentInstance most recently suspended to. The tag names that one snapshot permanently, and it acts as a retention pin, so Agent Substrate does not collect a snapshot while a tag still names it. Deleting the checkpoint removes the tag and releases the pin.
+
+Because a checkpoint captures a turn boundary, an AgentInstance must be at one to be checkpointed. An AgentInstance with a turn still in progress has no quiescent boundary to capture, and the request fails until the turn finishes.
+
+## Next steps
+
+{{< cards >}}
+ {{< card link=`{{< link path="substrate-runtime/sandboxing" >}}` title="Sandboxing" subtitle="See how a sandbox isolates each Actor's process, filesystem, and network." >}}
+ {{< card link=`{{< link path="about/agent-substrate" >}}` title="Architecture: Agent Substrate" subtitle="Review how Workers, Actors, and ActorTemplates fit together." >}}
+{{< /cards >}}
From 3591d73fde6e1d0048d990ba080082e202d24217 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Tue, 25 Aug 2026 17:53:31 -0500
Subject: [PATCH 15/70] Write Phase 2 Sandboxing page
Covers sandbox classes (gvisor and microvm), the SandboxConfig
resource, what the sandbox separates across process, filesystem, and
network, and the routing path that reaches a sandboxed Actor.
Describes the default network posture from what Substrate actually
creates, verified on a live cluster: the per-WorkerPool NetworkPolicy
restricts ingress to the Substrate router and sets no egress rule at
all. The page says so plainly rather than implying the sandbox blocks
outbound traffic by default, since Substrate's own threat model states
it has little to no security hardening yet and its granular
authorization policies are still planned.
Co-Authored-By: Claude Opus 5 (1M context)
Signed-off-by: Rachael Graham
---
.../1.x/substrate-runtime/sandboxing.md | 59 +++++++++++++++++++
1 file changed, 59 insertions(+)
create mode 100644 docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
diff --git a/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md b/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
new file mode 100644
index 00000000..7ff9fbfb
--- /dev/null
+++ b/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
@@ -0,0 +1,59 @@
+---
+title: Sandboxing
+description: Learn how Agent Substrate isolates each Actor in its own sandbox, and what that sandbox separates.
+weight: 10
+author: kagent.dev
+---
+
+An agent is a program that decides at run time what to do next. It runs the commands that a model asks for, and it calls the tools that it was given. [Agent Substrate]({{< link path="about/agent-substrate" >}}) therefore does not run an Actor as an ordinary container process. It runs each Actor inside its own sandbox, on a Worker that hosts one Actor at a time. This page explains what selects a sandbox, what the sandbox separates, and how traffic reaches an Actor through it.
+
+## Sandbox classes
+
+A **sandbox class** is the sandbox runtime family that a Worker uses. Agent Substrate supports two.
+
+- **`gvisor`**: The default. [gVisor](https://gvisor.dev) runs a user-space kernel that intercepts the sandboxed program's system calls, so the workload does not call the host kernel directly.
+- **`microvm`**: Runs the workload inside a lightweight virtual machine, which places a hypervisor boundary between the workload and the host.
+
+A WorkerPool selects its class through the `sandboxClass` field, which defaults to `gvisor`. The choice is not only a runtime preference. It also determines the shape of the Worker pods that Agent Substrate creates for that pool, including the virtualization device mounts and node placement that a micro-VM needs, and it determines which sandbox configurations the pool can draw on.
+
+> [!NOTE]
+> kagent generates ActorTemplates that use the `gvisor` class. Keep a WorkerPool that backs kagent Harnesses on `gvisor`.
+
+## Sandbox configuration
+
+A **SandboxConfig** is a cluster-scoped resource that holds the material needed to start one sandbox runtime family. It carries the runtime assets that the node agent fetches, keyed by processor architecture, along with the pause image that holds the sandbox's namespaces as its root container. One SandboxConfig can be marked as the cluster default for its class, and a WorkerPool that names no configuration explicitly resolves to that default.
+
+Holding these assets in a cluster resource is what lets one configuration pin a runtime version for many ActorTemplates at once, rather than each template carrying its own copy. A default installation creates a single `gvisor-default` configuration.
+
+## What the sandbox separates
+
+The sandbox draws a boundary in three places.
+
+- **Process and kernel**: The Actor's processes run against the sandbox runtime rather than the Worker node's kernel. A system call that the workload makes is handled by gVisor's user-space kernel, or by the guest kernel inside a micro-VM, instead of reaching the host directly.
+- **Filesystem**: The Actor sees the filesystem assembled from its container image, plus whatever durable volume its ActorTemplate declares. Writes to the root filesystem are a layer on top of the image, captured in a `Full` snapshot and discarded by a `Data` one. See [Suspend and resume]({{< link path="substrate-runtime/suspend-and-resume" >}}) for what each scope keeps.
+- **Network**: The Actor does not share the Worker pod's network position. The node agent gives the active Actor a private, point-to-point virtual network inside the Worker pod, so reaching the Actor means going through Agent Substrate's own network path rather than connecting to the Worker directly.
+
+## How traffic reaches a sandboxed Actor
+
+Every Actor is addressed by name, at `..actors.resources.substrate.ate.dev`. Reaching it involves several hops, and each one is what keeps a sandboxed Actor addressable without exposing the Worker that it happens to be running on.
+
+1. Agent Substrate runs its own Domain Name System (DNS) service that answers queries for that address pattern with the address of the router, rather than any individual Worker.
+2. The router reads the Actor name and atespace from the request, asks the Agent Substrate API to resume that Actor and report which Worker it is now assigned to, then selects that Worker as the destination.
+3. The router connects to a listener on the Worker over mutual Transport Layer Security (mTLS). The listener validates that the caller is the router, and forwards traffic only to the Actor currently assigned to that Worker.
+
+Because the router resolves the Worker assignment on every request, an Actor keeps a stable address across suspends, resumes, and moves between Workers.
+
+Traffic in the other direction leaves through a separate egress gateway rather than going straight out from the Worker. Routing Actor egress through one gateway is what gives Agent Substrate a single place to apply outbound controls.
+
+## Default network posture
+
+Agent Substrate creates a Kubernetes NetworkPolicy for each WorkerPool, selecting that pool's Worker pods. The policy restricts **ingress** to the Agent Substrate router alone. No other pod in the cluster can open a connection to a Worker, so an Actor is not reachable by anything that bypasses the routing path.
+
+That policy governs inbound traffic only. It does not constrain what an Actor may reach outbound, so outbound access is whatever the surrounding cluster and its infrastructure already allow. Treat network egress as something to configure deliberately for your environment rather than as something the WorkerPool policy settles.
+
+## Next steps
+
+{{< cards >}}
+ {{< card link=`{{< link path="substrate-runtime/suspend-and-resume" >}}` title="Suspend and resume" subtitle="See what a snapshot captures and how an idle Actor comes back." >}}
+ {{< card link=`{{< link path="about/agent-substrate" >}}` title="Architecture: Agent Substrate" subtitle="Review how Workers, Actors, and ActorTemplates fit together." >}}
+{{< /cards >}}
From 7835dd8e81405c388d82bbab9c125975d6945b2a Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Tue, 25 Aug 2026 17:55:24 -0500
Subject: [PATCH 16/70] Write Phase 2 Skills page
Adds the Skills and MCP section and its Skills page: what a skill is,
how SKILL.md front matter becomes a tool the model can call, and the
two ways an AgentTemplate attaches skills.
Documents the allowlist behavior the scope doc called for, verified
against the API and the materializer: a plugin package enables only
the skills named in plugins[].skills, and an empty list enables
nothing. Also covers the pinning rules that every artifact source
enforces, and the name uniqueness checks that run across standalone
and plugin skills together.
Co-Authored-By: Claude Opus 5 (1M context)
Signed-off-by: Rachael Graham
---
.../kagent/1.x/skills-and-mcp/_index.md | 8 ++
.../kagent/1.x/skills-and-mcp/skills.md | 86 +++++++++++++++++++
2 files changed, 94 insertions(+)
create mode 100644 docs-site/content/kagent/1.x/skills-and-mcp/_index.md
create mode 100644 docs-site/content/kagent/1.x/skills-and-mcp/skills.md
diff --git a/docs-site/content/kagent/1.x/skills-and-mcp/_index.md b/docs-site/content/kagent/1.x/skills-and-mcp/_index.md
new file mode 100644
index 00000000..04ac9723
--- /dev/null
+++ b/docs-site/content/kagent/1.x/skills-and-mcp/_index.md
@@ -0,0 +1,8 @@
+---
+title: Skills and MCP
+description: Give an agent capabilities through skills and Model Context Protocol tools.
+weight: 50
+author: kagent.dev
+---
+
+Extend what an agent can do, with skills that package instructions and supporting files, and with tools served over the Model Context Protocol.
diff --git a/docs-site/content/kagent/1.x/skills-and-mcp/skills.md b/docs-site/content/kagent/1.x/skills-and-mcp/skills.md
new file mode 100644
index 00000000..0e72792e
--- /dev/null
+++ b/docs-site/content/kagent/1.x/skills-and-mcp/skills.md
@@ -0,0 +1,86 @@
+---
+title: Skills
+description: Package instructions and supporting files as skills, and attach them to an AgentTemplate.
+weight: 20
+author: kagent.dev
+---
+
+A **skill** packages a piece of know-how that an agent can pick up: a set of instructions, together with whatever scripts or reference files those instructions depend on. An AgentTemplate attaches skills by naming where each one comes from, and kagent fetches them and places them where the agent runtime can find them.
+
+## What a skill is
+
+A skill is a directory whose root holds a `SKILL.md` file. That file carries front matter naming the skill and describing what it is for, followed by the instructions themselves.
+
+The description is what makes a skill usable. When an agent starts, the runtime reads the front matter of every skill that is attached to it and offers those skills to the model as tools that it can call. The model chooses a skill from its description, in the same way that it chooses any other tool, so a description that states plainly when to use the skill matters more than the length of the instructions behind it.
+
+## Attach skills to an AgentTemplate
+
+An AgentTemplate attaches skills two ways, and it can use both at once. Use `spec.skills` for a skill that is published on its own, and `spec.plugins` for a bundle that carries several skills together.
+
+```yaml
+apiVersion: kagent.dev/v1alpha3
+kind: AgentTemplate
+metadata:
+ name: incident-responder
+ namespace: kagent
+spec:
+ modelConfig:
+ name: default-model-config
+ systemPrompt: You help engineers work through production incidents.
+ skills:
+ - name: incident-triage
+ source:
+ oci: registry.example.com/skills/incident-triage@sha256:
+ plugins:
+ - source:
+ git:
+ url: https://github.com/example/agent-plugins
+ commit:
+ path: bundles/observability
+ skills:
+ - log-search
+ - runbook-lookup
+```
+
+| Field | Description |
+| ----- | ----------- |
+| `skills[].name` | The name that the skill is mounted under, and the name that the model sees. |
+| `skills[].source` | Where to fetch this one skill from. The source root must hold a `SKILL.md` file. |
+| `plugins[].source` | Where to fetch the plugin package from. The source root must hold a `plugin.json` manifest. |
+| `plugins[].skills` | The names of the skills inside that package to enable. Omit or leave empty to enable none. |
+| `source.path` | Selects a directory inside the artifact, when the content is not at its root. The path must be relative, and it cannot climb out of the artifact with `..` segments. |
+
+A plugin package follows the Agent Plugins 1.0.0 format. Its `plugin.json` names the package, and its skills live in a `skills` directory, one subdirectory per skill. A package may also declare Model Context Protocol (MCP) servers, which kagent adds to the agent's tools alongside the skills that you enabled.
+
+## Every source is immutable
+
+A skill changes what an agent does, so kagent only accepts artifact references that cannot shift underneath a running agent. Each source names exactly one of three kinds of artifact, and each one has to be pinned.
+
+- **`oci`**: An image reference pinned to a digest, in the form `@sha256:`. A tag alone is rejected, because a tag can be moved to different content later.
+- **`git`**: A repository URL together with a full commit identifier. An abbreviated commit, a branch, or a tag is rejected.
+- **`bucket.s3`**: An endpoint, bucket, and key, together with the `versionId` of that exact object version. A region is included where the service requires one for request signing.
+
+Pinning has a practical consequence worth planning for. Publishing a new version of a skill means updating the AgentTemplate to name the new digest, commit, or object version, which compiles a new revision. Agents that are already running keep the skill content that they started with.
+
+## The plugin allowlist
+
+A plugin package can carry many skills, and attaching the package does not enable any of them. Only the names listed in `plugins[].skills` are enabled.
+
+> [!IMPORTANT]
+> An empty skills list enables nothing. Adding a plugin package and omitting its `skills` list gives the agent no skills from that package, which is the safe default rather than an error. Listing skills explicitly also means that a package gaining new skills in a later version does not silently grant them to your agent.
+
+## Naming rules
+
+Skill names are checked before anything is fetched, and two rules apply across every skill on an AgentTemplate.
+
+- A name must be a single path component. A name containing a slash, or a name of `.` or `..`, is rejected.
+- Names must be unique across the whole AgentTemplate. Because standalone skills and plugin skills are mounted into the same place, a standalone skill cannot reuse the name of an enabled plugin skill, and two plugin packages cannot both contribute the same name.
+
+Plugin package names must also be unique. Two entries in `plugins` whose manifests declare the same name are rejected.
+
+## Next steps
+
+{{< cards >}}
+ {{< card link=`{{< link path="skills-and-mcp/about-tools" >}}` title="About tools" subtitle="See how MCP tools and agent tools attach to an AgentTemplate." >}}
+ {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Apply a Harness and AgentTemplate, and talk to the AgentInstance they produce." >}}
+{{< /cards >}}
From b09915905277d568bab6fa4b707ae10d008e74ea Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Tue, 25 Aug 2026 18:07:12 -0500
Subject: [PATCH 17/70] Redraw the suspend-and-resume diagram to show both
snapshot paths
The old diagram routed resume through the tag, which conflated two
different mechanisms. ResumeActor restores an existing Actor from its
latest snapshot with no tag involved, while a tag is used at
CreateActor via source_snapshot_tag to seed a new Actor.
The diagram now forks at ActorSnapshot: resume restores the same Actor
onto any free Worker, and a tag pins the snapshot and can seed a new
Actor. The walkthrough states outright that resuming an existing Actor
never goes through a tag.
Also drops the pool-to-second-Worker edge, which rendered as a long
line sweeping across the whole diagram to a node labeled identically
to the first Worker, and moves the walkthrough after the diagram to
match core-concepts.md and architecture.md.
Verified by rendering the mermaid block extracted from this file:
784x132px, clean left-to-right spine, no crossing edges.
Co-Authored-By: Claude Opus 5 (1M context)
Signed-off-by: Rachael Graham
---
.../kagent/1.x/about/agent-substrate.md | 22 +++++++++----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/docs-site/content/kagent/1.x/about/agent-substrate.md b/docs-site/content/kagent/1.x/about/agent-substrate.md
index 44ead771..1852c4ce 100644
--- a/docs-site/content/kagent/1.x/about/agent-substrate.md
+++ b/docs-site/content/kagent/1.x/about/agent-substrate.md
@@ -29,26 +29,26 @@ Because an Actor often runs a model-directed agent that calls tools and executes
Substrate's density model rests on one fact about agent workloads: an Actor spends most of its time idle, waiting on a person or a large language model (LLM) to respond, not actively computing. Substrate exploits that by suspending idle Actors and reclaiming their Worker, then resuming them on demand when traffic arrives. Suspending and resuming allows a WorkerPool to run far more Actors than it has Workers for at any given moment.
-The following diagram traces an Actor through one suspend-and-resume cycle.
-1. A WorkerPool hosts Workers.
-2. A Worker hosts a running Actor.
-3. Suspending that Actor produces a snapshot.
-4. That snapshot is tagged.
-5. A later Actor uses the tag to resume from the snapshot on whichever Worker is free.
+The following diagram traces an Actor through one suspend-and-resume cycle, and shows the second path that opens up once the resulting snapshot is tagged.
```mermaid
flowchart LR
pool["WorkerPool"] --> worker1["Worker"]
- pool --> worker2["Worker"]
worker1 -->|hosts| actor["Actor (running)"]
actor -->|suspend| snapshot["ActorSnapshot (immutable)"]
- snapshot -->|tag| tag["ActorSnapshotTag (stable handle)"]
- tag -->|resume| worker2
+ snapshot -->|resume| worker2["Any free Worker in the pool"]
+ snapshot -->|pinned by| tag["ActorSnapshotTag (retention pin)"]
+ tag -->|seeds| newactor["New Actor"]
```
-Suspending an Actor writes its full state to an immutable **ActorSnapshot** and frees the Worker that it was running on. Resuming reads that snapshot back and restores the Actor onto whichever Worker in the pool is free, which is not necessarily the Worker that it originally ran on. Because the snapshot captures the Actor's full state, the conversation continues from where it left off.
+A **WorkerPool** keeps **Workers** running and ready, and one Worker hosts the **Actor** while its conversation is active. Suspending that Actor writes its full state to an immutable **ActorSnapshot** and frees the Worker that it was running on.
-An **ActorSnapshotTag** gives a snapshot a stable, human-meaningful name, so callers do not need to track Substrate's internal snapshot identity. A tag names one snapshot permanently, and only its visibility scope can change afterward. A tag also acts as a retention pin, so Substrate does not delete a snapshot while a tag still names it.
+The diagram forks at that snapshot, because a snapshot serves two purposes.
+
+- **Resume** restores the same Actor onto **any free Worker in the pool**, which is not necessarily the Worker that it ran on before. Because the snapshot captures the Actor's full state, the conversation continues from where it left off. Every idle agent takes this path.
+- An **ActorSnapshotTag** pins that snapshot, and a **New Actor** can be seeded from the tag at the moment that it is created. Resuming an existing Actor never goes through a tag.
+
+A tag gives a snapshot a stable, human-meaningful name, so callers do not need to track Substrate's internal snapshot identity. A tag names one snapshot permanently, and only its visibility scope can change afterward. A tag also acts as a retention pin, so Substrate does not delete a snapshot while a tag still names it.
Substrate's own target for this cycle is 100 milliseconds at the ninety-fifth percentile, measured from the moment traffic arrives for a suspended Actor to the moment that Actor can receive it.
From a52e5b841d147ed85fe042b205a0ad6c8f079035 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Tue, 25 Aug 2026 18:07:45 -0500
Subject: [PATCH 18/70] Update _index.md
Signed-off-by: Rachael Graham
---
docs-site/content/kagent/1.x/skills-and-mcp/_index.md | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/docs-site/content/kagent/1.x/skills-and-mcp/_index.md b/docs-site/content/kagent/1.x/skills-and-mcp/_index.md
index 04ac9723..da14a380 100644
--- a/docs-site/content/kagent/1.x/skills-and-mcp/_index.md
+++ b/docs-site/content/kagent/1.x/skills-and-mcp/_index.md
@@ -3,6 +3,4 @@ title: Skills and MCP
description: Give an agent capabilities through skills and Model Context Protocol tools.
weight: 50
author: kagent.dev
----
-
-Extend what an agent can do, with skills that package instructions and supporting files, and with tools served over the Model Context Protocol.
+---
\ No newline at end of file
From a3d95d493ea81e832bce3037ccf55d51f4fabc78 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Tue, 25 Aug 2026 18:26:30 -0500
Subject: [PATCH 19/70] Rename the two About architecture pages as a parallel
pair
"Architecture" and "Architecture: Agent Substrate" become "kagent
architecture" and "Agent Substrate architecture".
The colon prefix implied that the Agent Substrate page was a deeper
cut of the Architecture page. It is not: it describes a different
system that kagent runs on top of, so the two are sibling subjects
rather than parent and child. Naming each page after its own subject
makes the symmetry honest, and separates the conceptual page from the
Substrate runtime section that now covers sandboxing and suspend and
resume in depth.
Updates all 11 occurrences, including the six places where the old
title was quoted as card link text. Two prose links were rephrased so
the lowercase project name is not sentence-initial. Lowercase "kagent"
at the start of a title follows the section landing page, which is
titled "kagent 1.0 (preview)".
Co-Authored-By: Claude Opus 5 (1M context)
Signed-off-by: Rachael Graham
---
docs-site/content/kagent/1.x/about/agent-substrate.md | 4 ++--
docs-site/content/kagent/1.x/about/architecture.md | 4 ++--
docs-site/content/kagent/1.x/about/core-concepts.md | 6 +++---
docs-site/content/kagent/1.x/about/what-is-kagent.md | 2 +-
.../content/kagent/1.x/get-started/your-first-agent.md | 2 +-
.../content/kagent/1.x/substrate-runtime/sandboxing.md | 2 +-
.../kagent/1.x/substrate-runtime/suspend-and-resume.md | 2 +-
7 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/docs-site/content/kagent/1.x/about/agent-substrate.md b/docs-site/content/kagent/1.x/about/agent-substrate.md
index 1852c4ce..8a374708 100644
--- a/docs-site/content/kagent/1.x/about/agent-substrate.md
+++ b/docs-site/content/kagent/1.x/about/agent-substrate.md
@@ -1,11 +1,11 @@
---
-title: "Architecture: Agent Substrate"
+title: Agent Substrate architecture
description: See how Agent Substrate runs, suspends, and resumes the Actors behind every AgentInstance.
weight: 40
author: kagent.dev
---
-[Architecture]({{< link path="about/architecture" >}}) established that every AgentInstance runs on an Actor. This page explains what an Actor is built from and what it runs on: the ActorTemplate that it is created from, the compute that hosts it, the sandbox that isolates it, and the snapshot cycle that lets it suspend when idle and resume on demand.
+The [kagent architecture]({{< link path="about/architecture" >}}) page established that every AgentInstance runs on an Actor. This page explains what an Actor is built from and what it runs on: the ActorTemplate that it is created from, the compute that hosts it, the sandbox that isolates it, and the snapshot cycle that lets it suspend when idle and resume on demand.
## ActorTemplate
diff --git a/docs-site/content/kagent/1.x/about/architecture.md b/docs-site/content/kagent/1.x/about/architecture.md
index 68e6e15f..cd34d668 100644
--- a/docs-site/content/kagent/1.x/about/architecture.md
+++ b/docs-site/content/kagent/1.x/about/architecture.md
@@ -1,5 +1,5 @@
---
-title: Architecture
+title: kagent architecture
description: See how a Harness and AgentTemplate become a running conversation, across kagent's two authorization planes.
weight: 30
author: kagent.dev
@@ -71,6 +71,6 @@ This split also keeps the two lifecycles independent. Editing a Harness or Agent
## Next steps
{{< cards >}}
- {{< card link=`{{< link path="about/agent-substrate" >}}` title="Architecture: Agent Substrate" subtitle="See what an Actor actually runs on, and how it suspends and resumes." >}}
+ {{< card link=`{{< link path="about/agent-substrate" >}}` title="Agent Substrate architecture" subtitle="See what an Actor actually runs on, and how it suspends and resumes." >}}
{{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Apply a Harness and AgentTemplate, and talk to the AgentInstance they produce." >}}
{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/about/core-concepts.md b/docs-site/content/kagent/1.x/about/core-concepts.md
index 6f314293..663c726b 100644
--- a/docs-site/content/kagent/1.x/about/core-concepts.md
+++ b/docs-site/content/kagent/1.x/about/core-concepts.md
@@ -91,7 +91,7 @@ For the AgentInstance gRPC service definition, see the [API reference]({{< link
An **Actor** is the sandboxed unit of compute, provided by [Agent Substrate]({{< link path="about/agent-substrate" >}}), that _runs an AgentInstance's conversation loop_. Every AgentInstance is backed by an Actor.
-Actors are the reason why AgentInstances can suspend and resume cheaply instead of staying resident. An idle Actor can be snapshotted and torn down, then resumed from that snapshot on demand. To understand the full mechanics (Workers, WorkerPools, ActorTemplates, and snapshotting), see [Architecture: Agent Substrate]({{< link path="about/agent-substrate" >}}).
+Actors are the reason why AgentInstances can suspend and resume cheaply instead of staying resident. An idle Actor can be snapshotted and torn down, then resumed from that snapshot on demand. To understand the full mechanics (Workers, WorkerPools, ActorTemplates, and snapshotting), see [Agent Substrate architecture]({{< link path="about/agent-substrate" >}}).
## Agent tools: Shared vs. Dedicated
@@ -107,7 +107,7 @@ This limit keeps the model predictable. A Dedicated binding gives the child its
## Next steps
{{< cards >}}
- {{< card link=`{{< link path="about/architecture" >}}` title="Architecture" subtitle="See how these pieces fit together end to end, from `kubectl apply` to a live conversation." >}}
- {{< card link=`{{< link path="about/agent-substrate" >}}` title="Architecture: Agent Substrate" subtitle="Learn about Workers, WorkerPools, and ActorTemplates, and how Actors suspend and resume." >}}
+ {{< card link=`{{< link path="about/architecture" >}}` title="kagent architecture" subtitle="See how these pieces fit together end to end, from `kubectl apply` to a live conversation." >}}
+ {{< card link=`{{< link path="about/agent-substrate" >}}` title="Agent Substrate architecture" subtitle="Learn about Workers, WorkerPools, and ActorTemplates, and how Actors suspend and resume." >}}
{{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Apply a Harness and AgentTemplate, and talk to the AgentInstance they produce." >}}
{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/about/what-is-kagent.md b/docs-site/content/kagent/1.x/about/what-is-kagent.md
index 42362f61..0c6ef586 100644
--- a/docs-site/content/kagent/1.x/about/what-is-kagent.md
+++ b/docs-site/content/kagent/1.x/about/what-is-kagent.md
@@ -62,7 +62,7 @@ Check out [Solo Enterprise for kagent](https://www.solo.io/products/kagent-enter
## Getting started
-To start using kagent, see [Your first agent]({{< link path="get-started/your-first-agent" >}}). For a deeper understanding of how kagent works, see [Architecture]({{< link path="about/architecture" >}}).
+To start using kagent, see [Your first agent]({{< link path="get-started/your-first-agent" >}}). For a deeper understanding of how the pieces fit together, see [kagent architecture]({{< link path="about/architecture" >}}).
Ready to contribute? Visit the [GitHub repository](https://github.com/kagent-dev) to learn how you can help expand the ecosystem of cloud-native AI agents.
diff --git a/docs-site/content/kagent/1.x/get-started/your-first-agent.md b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
index f48db4db..ff1731ad 100644
--- a/docs-site/content/kagent/1.x/get-started/your-first-agent.md
+++ b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
@@ -172,7 +172,7 @@ The response carries the agent's reply in the same `parts` shape as the request.
## Next steps
{{< cards >}}
- {{< card link=`{{< link path="about/agent-substrate" >}}` title="Architecture: Agent Substrate" subtitle="Understand what happens to your AgentInstance's Actor when it sits idle." >}}
+ {{< card link=`{{< link path="about/agent-substrate" >}}` title="Agent Substrate architecture" subtitle="Understand what happens to your AgentInstance's Actor when it sits idle." >}}
{{< card link=`{{< link path="agents/agent-harness" >}}` title="Agent harness" subtitle="Choose from the full set of Harness runtime options, including Claude Code and Codex." >}}
{{< card link=`{{< link path="skills-mcp/skills" >}}` title="Skills" subtitle="Give your agent capabilities beyond its system prompt." >}}
{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md b/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
index 7ff9fbfb..fce33678 100644
--- a/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
+++ b/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
@@ -55,5 +55,5 @@ That policy governs inbound traffic only. It does not constrain what an Actor ma
{{< cards >}}
{{< card link=`{{< link path="substrate-runtime/suspend-and-resume" >}}` title="Suspend and resume" subtitle="See what a snapshot captures and how an idle Actor comes back." >}}
- {{< card link=`{{< link path="about/agent-substrate" >}}` title="Architecture: Agent Substrate" subtitle="Review how Workers, Actors, and ActorTemplates fit together." >}}
+ {{< card link=`{{< link path="about/agent-substrate" >}}` title="Agent Substrate architecture" subtitle="Review how Workers, Actors, and ActorTemplates fit together." >}}
{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md b/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
index fe4f3d62..4cf12290 100644
--- a/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
+++ b/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
@@ -71,5 +71,5 @@ Because a checkpoint captures a turn boundary, an AgentInstance must be at one t
{{< cards >}}
{{< card link=`{{< link path="substrate-runtime/sandboxing" >}}` title="Sandboxing" subtitle="See how a sandbox isolates each Actor's process, filesystem, and network." >}}
- {{< card link=`{{< link path="about/agent-substrate" >}}` title="Architecture: Agent Substrate" subtitle="Review how Workers, Actors, and ActorTemplates fit together." >}}
+ {{< card link=`{{< link path="about/agent-substrate" >}}` title="Agent Substrate architecture" subtitle="Review how Workers, Actors, and ActorTemplates fit together." >}}
{{< /cards >}}
From c487eda4c98026e44bac1d5958d0a8b2d2a49dc6 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Tue, 25 Aug 2026 18:28:10 -0500
Subject: [PATCH 20/70] Illustrate ActorSnapshotTag with a concrete example
The tag paragraph explained the mechanism but gave the reader nothing
to picture. Adds a short worked example: checkpointing an agent
partway through an incident investigation tags the snapshot it most
recently suspended to, which holds that snapshot in place while newer
ones accumulate, and links forward to the checkpoint section on the
Suspend and resume page.
Co-Authored-By: Claude Opus 5 (1M context)
Signed-off-by: Rachael Graham
---
docs-site/content/kagent/1.x/about/agent-substrate.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/docs-site/content/kagent/1.x/about/agent-substrate.md b/docs-site/content/kagent/1.x/about/agent-substrate.md
index 8a374708..798aa2ed 100644
--- a/docs-site/content/kagent/1.x/about/agent-substrate.md
+++ b/docs-site/content/kagent/1.x/about/agent-substrate.md
@@ -50,6 +50,8 @@ The diagram forks at that snapshot, because a snapshot serves two purposes.
A tag gives a snapshot a stable, human-meaningful name, so callers do not need to track Substrate's internal snapshot identity. A tag names one snapshot permanently, and only its visibility scope can change afterward. A tag also acts as a retention pin, so Substrate does not delete a snapshot while a tag still names it.
+For example, an agent partway through a long incident investigation reaches a state worth keeping. Creating a [checkpoint]({{< link path="substrate-runtime/suspend-and-resume#checkpoints" >}}) tags the snapshot that the agent most recently suspended to, which holds that one snapshot in place while the agent carries on and writes newer ones. Without the tag, Substrate collects that snapshot once a newer one supersedes it.
+
Substrate's own target for this cycle is 100 milliseconds at the ninety-fifth percentile, measured from the moment traffic arrives for a suspended Actor to the moment that Actor can receive it.
## Next steps
From 7762b08d56815a23d402586ca597afafc5cfee9e Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Wed, 26 Aug 2026 11:00:15 -0500
Subject: [PATCH 21/70] Phase 2, review 1
Signed-off-by: Rachael Graham
---
.../content/kagent/1.x/setup/installation.md | 137 ++++++++++--------
1 file changed, 77 insertions(+), 60 deletions(-)
diff --git a/docs-site/content/kagent/1.x/setup/installation.md b/docs-site/content/kagent/1.x/setup/installation.md
index f7f24ccf..f487d548 100644
--- a/docs-site/content/kagent/1.x/setup/installation.md
+++ b/docs-site/content/kagent/1.x/setup/installation.md
@@ -9,74 +9,77 @@ kagent 1.0 runs every agent on [Agent Substrate]({{< link path="about/agent-subs
## About installing kagent
-Installation has three phases, and the order matters.
+Installation has three phases that you must complete in this order.
-- **Install Agent Substrate**: Deploys the Agent Substrate control plane and data plane into the `ate-system` namespace.
-- **Bootstrap Agent Substrate identity**: Creates the certificate authority (CA) pools, the JSON Web Token (JWT) authority pool, and the authentication configuration that Agent Substrate components use to prove identity to each other and to kagent.
-- **Install kagent**: Deploys the kagent controller with the Agent Substrate integration enabled, and provisions the WorkerPool that agents run on.
+1. **Install Agent Substrate**: Deploys the Agent Substrate control plane and data plane into the `ate-system` namespace.
+2. **Bootstrap Agent Substrate identity**: Creates the certificate authority (CA) pools, the JSON Web Token (JWT) authority pool, and the authentication configuration that Agent Substrate components use to prove identity to each other and to kagent.
+3. **Install kagent**: Deploys the kagent controller with the Agent Substrate integration enabled, and provisions the WorkerPool that agents run on.
> [!IMPORTANT]
-> The bootstrap phase is required, and no Helm chart performs it for you. Until you complete it, every pod in the `ate-system` namespace stays in `ContainerCreating` and reports `FailedMount` events for the `podidentity` and `servicedns` volumes. Agent Substrate authenticates its components with mutual Transport Layer Security (mTLS), and the identity material that mTLS depends on is created by the `kubectl-ate` plugin, not by Helm.
-
-> [!NOTE]
-> Install kagent 1.0 with Helm. The `kagent install` command does not provision Agent Substrate and cannot produce a working 1.0 installation.
+> The bootstrap phase is required, and no Helm chart performs it for you. Agent Substrate authenticates its components with mutual Transport Layer Security (mTLS), and the identity material that mTLS depends on is created by the `kubectl-ate` plugin, not by Helm.
## Before you begin
-You need the following tools and cluster capabilities.
-
-- **Kubernetes 1.35 or later**: Agent Substrate requires the `ClusterTrustBundle`, `ClusterTrustBundleProjection`, and `PodCertificateRequest` feature gates, along with the `certificates.k8s.io/v1beta1` API. Kubernetes 1.35 enables all of them by default. On an earlier version, enable them explicitly on the API server.
-- **Helm 3 and `kubectl`**: Both must be on your `PATH`.
-- **`jq` and `openssl`**: The bootstrap phase uses both to extract a root certificate from a generated CA pool.
-- **A model provider API key**: The examples on this page use OpenAI. For other providers, see [Configure model providers]({{< link path="setup/configure-model-providers" >}}).
-
-### Prepare a cluster
-
-Confirm that your cluster exposes the certificate APIs that Agent Substrate depends on.
-
-{{< tabs >}}
-{{% tab name="Existing cluster" %}}
-Check that both resources are present.
-```bash
-kubectl api-resources --api-group=certificates.k8s.io
-```
-
-Example output, truncated to the two resources that matter.
-```console
-NAME APIVERSION NAMESPACED KIND
-clustertrustbundles certificates.k8s.io/v1beta1 false ClusterTrustBundle
-podcertificaterequests certificates.k8s.io/v1beta1 true PodCertificateRequest
-```
-
-If either resource is missing, enable the feature gates on your API server before you continue.
-{{% /tab %}}
-{{% tab name="Local kind cluster" %}}
-Create a kind cluster on a node image that includes the certificate APIs.
-```bash
-kind create cluster --name kagent --image kindest/node:v1.35.0
-```
-
-An earlier node image does not expose `certificates.k8s.io/v1beta1`, and Agent Substrate cannot start on it.
-{{% /tab %}}
-{{< /tabs >}}
-
-### Install the kubectl-ate plugin
-
-Agent Substrate ships `kubectl-ate` as a standalone binary that is published with each Agent Substrate release. Download the build that matches your operating system and architecture, then put it on your `PATH` so that `kubectl` finds it as a plugin.
-```bash
-curl -fsSL -o kubectl-ate \
- "https://github.com/kagent-dev/substrate/releases/download/v{{< reuse "versions/agent-substrate-1x.md" >}}/kubectl-ate-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m | sed 's/x86_64/amd64/; s/aarch64/arm64/')"
-chmod +x kubectl-ate
-sudo mv kubectl-ate /usr/local/bin/
-```
-
-Confirm that `kubectl` picks the plugin up.
-```bash
-kubectl ate --help
-```
+1. Install the following CLI tools.
+ * [`helm`](https://helm.sh/docs/intro/install/), the Kubernetes package manager. Use Helm 3.
+ * [`kubectl`](https://kubernetes.io/docs/tasks/tools/#kubectl), the Kubernetes command line tool.
+ * [`jq`](https://jqlang.org/download/), to read the root certificate out of the generated CA pool.
+ * [`openssl`](https://www.openssl.org), to convert that certificate to PEM format.
+ * [`kubectl-ate`](https://github.com/kagent-dev/substrate/releases), the Agent Substrate command line tool, published as a `kubectl` plugin with each Agent Substrate release. No Helm chart creates the identity material that Agent Substrate needs, so the bootstrap phase depends on this plugin.
+ ```bash
+ curl -fsSL -o kubectl-ate \
+ "https://github.com/kagent-dev/substrate/releases/download/v{{< reuse "versions/agent-substrate-1x.md" >}}/kubectl-ate-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m | sed 's/x86_64/amd64/; s/aarch64/arm64/')"
+ chmod +x kubectl-ate
+ sudo mv kubectl-ate /usr/local/bin/
+ kubectl ate --help
+ ```
+
+2. Prepare a Kubernetes cluster at **version 1.37 or later**. Agent Substrate depends on the `ClusterTrustBundle`, `ClusterTrustBundleProjection`, and `PodCertificateRequest` feature gates, along with the `certificates.k8s.io/v1beta1` API. Kubernetes promotes all three feature gates to generally available, and enables them by default, in version 1.37. In 1.36 and earlier, none are enabled by default, and must be manually enabled.
+
+ {{< tabs >}}
+ {{% tab name="Local kind cluster" %}}
+ For local testing and development, create a kind cluster at version 1.37.
+
+ {{% /tab %}}
+ {{% tab name="Existing upgraded 1.37 cluster" %}}
+
+ {{% /tab %}}
+ {{% tab name="Use an existing 1.36 or earlier cluster" %}}
+ To use an existing cluster that continues to run on 1.36, first confirm that your cluster exposes both certificate resources.
+ ```bash
+ kubectl api-resources --api-group=certificates.k8s.io
+ ```
+
+ Example output:
+ ```console
+ NAME APIVERSION NAMESPACED KIND
+ ...
+ clustertrustbundles certificates.k8s.io/v1beta1 false ClusterTrustBundle
+ podcertificaterequests certificates.k8s.io/v1beta1 true PodCertificateRequest
+ ```
+
+ If either resource is missing, enable the gates on each control plane component, then restart that component.
+
+ > [!WARNING]
+ > Changing these settings requires control over your control plane configuration. Before you plan an installation on a managed Kubernetes service, confirm that the provider lets you set API server flags and kubelet configuration.
+ > If you cannot change the component configuration, use the **Local kind cluster** tab instead.
+
+ * **kube-apiserver**: Add `--feature-gates=ClusterTrustBundle=true` and `--runtime-config=certificates.k8s.io/v1beta1=true`.
+ * **kube-controller-manager**: Add `--feature-gates=ClusterTrustBundle=true`.
+ * **kubelet, on every node**: Add all three gates to the kubelet configuration file.
+ ```yaml
+ featureGates:
+ ClusterTrustBundle: true
+ ClusterTrustBundleProjection: true
+ PodCertificateRequest: true
+ ```
+ {{% /tab %}}
+ {{< /tabs >}}
## Install Agent Substrate
+Deploy the Agent Substrate control plane and data plane into the `ate-system` namespace.
+
1. Install the Agent Substrate custom resource definitions (CRDs).
```bash
helm upgrade --install substrate-crds \
@@ -84,6 +87,7 @@ kubectl ate --help
--version {{< reuse "versions/agent-substrate-1x.md" >}} \
--namespace ate-system --create-namespace
```
+
2. Install the Agent Substrate control plane and data plane. Do not add `--wait` to this command, because the pods cannot become ready until you bootstrap identity in the next section.
```bash
helm upgrade --install substrate \
@@ -105,6 +109,7 @@ Agent Substrate signs pod identities and service certificates from CA pools that
--name=pod-identity-ca-pool \
--secret-namespace=podcertificate-controller-system
```
+
2. Create the actor identity pools that Agent Substrate uses to issue and verify actor credentials.
```bash
kubectl ate admin make-jwt-pool --key-id=1 \
@@ -114,6 +119,7 @@ Agent Substrate signs pod identities and service certificates from CA pools that
--name=actor-id-ca-pool \
--secret-namespace=ate-system
```
+
3. Extract the actor identity root certificate and store it in the secret that the Agent Substrate API server reads.
```bash
actor_id_ca_root="$(kubectl get secret actor-id-ca-pool -n ate-system \
@@ -124,6 +130,7 @@ Agent Substrate signs pod identities and service certificates from CA pools that
kubectl create secret generic actor-id-ca-certs -n ate-system \
--from-literal=ca.crt="${actor_id_ca_root}"
```
+
4. Create the authentication configuration. The `kubernetes` provider accepts Kubernetes ServiceAccount tokens that are issued for the Agent Substrate API server audience.
```bash
kubectl create configmap ate-api-authentication -n ate-system \
@@ -136,6 +143,7 @@ Agent Substrate signs pod identities and service certificates from CA pools that
discoveryTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
'
```
+
5. Roll Agent Substrate out again so that its pods mount the identity material, and wait for them to become ready.
```bash
helm upgrade substrate \
@@ -143,6 +151,7 @@ Agent Substrate signs pod identities and service certificates from CA pools that
--version {{< reuse "versions/agent-substrate-1x.md" >}} \
--namespace ate-system --reuse-values --wait --timeout 10m
```
+
6. Verify that Agent Substrate is running.
```bash
kubectl get pods -n ate-system
@@ -166,6 +175,9 @@ Agent Substrate signs pod identities and service certificates from CA pools that
The kagent chart connects the controller to Agent Substrate and creates a WorkerPool for agents to run on. A WorkerPool is platform capacity that you provision once, and every Harness references it. No Harness can run until a WorkerPool exists.
+> [!IMPORTANT]
+> Install kagent 1.0 with Helm. The `kagent install` command does not yet provision Agent Substrate and cannot produce a working 1.0 installation.
+
1. Install the kagent CRDs.
```bash
helm upgrade --install kagent-crds \
@@ -173,10 +185,12 @@ The kagent chart connects the controller to Agent Substrate and creates a Worker
--version \
--namespace kagent --create-namespace --wait
```
-2. Set your model provider API key.
+
+2. Set your model provider API key. The examples in this guide use OpenAI. For other providers, see [Configure model providers]({{< link path="setup/configure-model-providers" >}}).
```bash
export OPENAI_API_KEY="your-api-key-here"
```
+
3. Install kagent with the Agent Substrate integration enabled. Set `substrateWorkerPool.ateomImage` explicitly, because the chart has no default for it and the install fails without it whenever `substrateWorkerPool.create` is `true`.
```bash
helm upgrade --install kagent \
@@ -193,6 +207,7 @@ The kagent chart connects the controller to Agent Substrate and creates a Worker
--set substrateWorkerPool.replicas=1 \
--set-string substrateWorkerPool.ateomImage=ghcr.io/kagent-dev/substrate/ateom-gvisor:v{{< reuse "versions/agent-substrate-1x.md" >}}
```
+
4. Wait for the controller to roll out.
```bash
kubectl rollout status deployment/kagent-controller -n kagent --timeout=300s
@@ -214,6 +229,7 @@ The kagent chart connects the controller to Agent Substrate and creates a Worker
kagent-default-864fdc4c94-xbsl9 1/1 Running 0 2m
kagent-postgresql-65cc684b78-9qbh2 1/1 Running 0 2m
```
+
2. Confirm that the WorkerPool reports a ready replica. Agents cannot start until the pool is ready.
```bash
kubectl get workerpools -n kagent
@@ -223,6 +239,7 @@ The kagent chart connects the controller to Agent Substrate and creates a Worker
NAMESPACE NAME DESIRED REPLICAS READY AGE
kagent kagent-default 1 1 1 2m
```
+
3. Note how you reach the kagent gRPC API, which serves the AgentInstance lifecycle and conversation calls. [Your first agent]({{< link path="get-started/your-first-agent" >}}) assumes the port-forward.
{{< tabs >}}
{{% tab name="Cloud Provider LoadBalancer" %}}
From 03e2a25d4bb0c43bc3a86fffc101c0a79e868a0b Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Wed, 26 Aug 2026 12:22:51 -0500
Subject: [PATCH 22/70] Phase 2, review 2
Signed-off-by: Rachael Graham
---
.../content/kagent/1.x/setup/installation.md | 149 ++++++++++--------
1 file changed, 82 insertions(+), 67 deletions(-)
diff --git a/docs-site/content/kagent/1.x/setup/installation.md b/docs-site/content/kagent/1.x/setup/installation.md
index f487d548..13428da3 100644
--- a/docs-site/content/kagent/1.x/setup/installation.md
+++ b/docs-site/content/kagent/1.x/setup/installation.md
@@ -5,18 +5,7 @@ weight: 10
author: kagent.dev
---
-kagent 1.0 runs every agent on [Agent Substrate]({{< link path="about/agent-substrate" >}}), so an installation sets up two systems in the same cluster. Agent Substrate provides the sandboxed compute that agents run on, and kagent provides the Harness, AgentTemplate, and AgentInstance API that you author against.
-
-## About installing kagent
-
-Installation has three phases that you must complete in this order.
-
-1. **Install Agent Substrate**: Deploys the Agent Substrate control plane and data plane into the `ate-system` namespace.
-2. **Bootstrap Agent Substrate identity**: Creates the certificate authority (CA) pools, the JSON Web Token (JWT) authority pool, and the authentication configuration that Agent Substrate components use to prove identity to each other and to kagent.
-3. **Install kagent**: Deploys the kagent controller with the Agent Substrate integration enabled, and provisions the WorkerPool that agents run on.
-
-> [!IMPORTANT]
-> The bootstrap phase is required, and no Helm chart performs it for you. Agent Substrate authenticates its components with mutual Transport Layer Security (mTLS), and the identity material that mTLS depends on is created by the `kubectl-ate` plugin, not by Helm.
+kagent 1.0 runs every agent on [Agent Substrate]({{< link path="about/agent-substrate" >}}), so an installation sets up two systems in the same cluster. Agent Substrate provides the sandboxed compute that agents run on, and kagent provides the Harness, AgentTemplate, and AgentInstance API that you author against. Install Agent Substrate first, because the kagent controller connects to it at startup.
## Before you begin
@@ -25,43 +14,67 @@ Installation has three phases that you must complete in this order.
* [`kubectl`](https://kubernetes.io/docs/tasks/tools/#kubectl), the Kubernetes command line tool.
* [`jq`](https://jqlang.org/download/), to read the root certificate out of the generated CA pool.
* [`openssl`](https://www.openssl.org), to convert that certificate to PEM format.
- * [`kubectl-ate`](https://github.com/kagent-dev/substrate/releases), the Agent Substrate command line tool, published as a `kubectl` plugin with each Agent Substrate release. No Helm chart creates the identity material that Agent Substrate needs, so the bootstrap phase depends on this plugin.
+ * [`kubectl-ate`](https://github.com/kagent-dev/substrate/releases), the Agent Substrate command line tool, published as a `kubectl` plugin with each Agent Substrate release.
```bash
curl -fsSL -o kubectl-ate \
- "https://github.com/kagent-dev/substrate/releases/download/v{{< reuse "versions/agent-substrate-1x.md" >}}/kubectl-ate-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m | sed 's/x86_64/amd64/; s/aarch64/arm64/')"
+ "https://github.com/kagent-dev/substrate/releases/download/v{{< reuse "kagent-docs/versions/agent-substrate-1x.md" >}}/kubectl-ate-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m | sed 's/x86_64/amd64/; s/aarch64/arm64/')"
chmod +x kubectl-ate
sudo mv kubectl-ate /usr/local/bin/
kubectl ate --help
```
-2. Prepare a Kubernetes cluster at **version 1.37 or later**. Agent Substrate depends on the `ClusterTrustBundle`, `ClusterTrustBundleProjection`, and `PodCertificateRequest` feature gates, along with the `certificates.k8s.io/v1beta1` API. Kubernetes promotes all three feature gates to generally available, and enables them by default, in version 1.37. In 1.36 and earlier, none are enabled by default, and must be manually enabled.
+2. Set your model provider API key. The examples in this guide use OpenAI. For other providers, see [Configure model providers]({{< link path="setup/configure-model-providers" >}}).
+ ```bash
+ export OPENAI_API_KEY="your-api-key-here"
+ ```
+
+3. Prepare a Kubernetes cluster at **1.37 or later** and enable it with the following requirements for Agent Substrate.
{{< tabs >}}
{{% tab name="Local kind cluster" %}}
- For local testing and development, create a kind cluster at version 1.37.
-
- {{% /tab %}}
- {{% tab name="Existing upgraded 1.37 cluster" %}}
-
- {{% /tab %}}
- {{% tab name="Use an existing 1.36 or earlier cluster" %}}
- To use an existing cluster that continues to run on 1.36, first confirm that your cluster exposes both certificate resources.
+ For local testing and development, create a [kind](https://kind.sigs.k8s.io/docs/user/quick-start/#installation) cluster at Kubernetes 1.37 or later. Enable the `certificates.k8s.io/v1beta1` API, which Agent Substrate depends on.
```bash
- kubectl api-resources --api-group=certificates.k8s.io
+ kind create cluster --image kindest/node:v1.37.0 --config=- < [!NOTE]
+ > If the command list already has a `--runtime-config` flag, edit that line instead of adding a second one. A duplicate flag is silently ignored, and the API is not served.
+
+ 2. Confirm that the beta group is served. Be sure to check the served API versions, not the resource list.
+ ```bash
+ kubectl api-versions | grep certificates.k8s.io
+ ```
+
+ Example output:
+ ```console
+ certificates.k8s.io/v1
+ certificates.k8s.io/v1beta1
+ ```
+ {{% /tab %}}
- If either resource is missing, enable the gates on each control plane component, then restart that component.
+ {{% tab name="1.36 or earlier cluster" %}}
+ Agent Substrate depends on the `ClusterTrustBundle`, `ClusterTrustBundleProjection`, and `PodCertificateRequest` feature gates, along with the `certificates.k8s.io/v1beta1` API. In 1.36 and earlier, none of these are enabled by default, and must be manually enabled.
> [!WARNING]
- > Changing these settings requires control over your control plane configuration. Before you plan an installation on a managed Kubernetes service, confirm that the provider lets you set API server flags and kubelet configuration.
+ > Changing these settings requires control over your control plane configuration. When planning a kagent installation on a managed Kubernetes service, confirm that the provider lets you set API server flags and kubelet configuration.
> If you cannot change the component configuration, use the **Local kind cluster** tab instead.
* **kube-apiserver**: Add `--feature-gates=ClusterTrustBundle=true` and `--runtime-config=certificates.k8s.io/v1beta1=true`.
@@ -78,29 +91,28 @@ Installation has three phases that you must complete in this order.
## Install Agent Substrate
-Deploy the Agent Substrate control plane and data plane into the `ate-system` namespace.
+Deploy the Agent Substrate control plane and data plane into the `ate-system` namespace, then create the identity material that its components authenticate with. Agent Substrate signs pod identities and service certificates from certificate authority (CA) pools that you generate, and it authenticates callers against a JSON Web Token (JWT) authority pool.
+
+> [!IMPORTANT]
+> Creating the identity material is required, and no Helm chart performs it for you. Agent Substrate authenticates its components with mutual Transport Layer Security (mTLS), and the identity material that mTLS depends on is created by the `kubectl-ate` plugin, not by Helm.
1. Install the Agent Substrate custom resource definitions (CRDs).
```bash
helm upgrade --install substrate-crds \
oci://ghcr.io/kagent-dev/substrate/helm/substrate-crds \
- --version {{< reuse "versions/agent-substrate-1x.md" >}} \
+ --version {{< reuse "kagent-docs/versions/agent-substrate-1x.md" >}} \
--namespace ate-system --create-namespace
```
-2. Install the Agent Substrate control plane and data plane. Do not add `--wait` to this command, because the pods cannot become ready until you bootstrap identity in the next section.
+2. Install the Agent Substrate control plane and data plane. Do not add `--wait` to this command, because the pods cannot become ready until you create the identity material in the following steps.
```bash
helm upgrade --install substrate \
oci://ghcr.io/kagent-dev/substrate/helm/substrate \
- --version {{< reuse "versions/agent-substrate-1x.md" >}} \
+ --version {{< reuse "kagent-docs/versions/agent-substrate-1x.md" >}} \
--namespace ate-system
```
-## Bootstrap Agent Substrate identity
-
-Agent Substrate signs pod identities and service certificates from CA pools that you generate, and it authenticates callers against a JWT authority pool. The `kubectl-ate admin` commands create that material as Kubernetes secrets, and a ConfigMap tells the Agent Substrate API server which token issuer to trust.
-
-1. Create the CA pools that sign service DNS and pod identity certificates.
+3. Create the CA pools that sign service DNS and pod identity certificates.
```bash
kubectl ate admin make-ca-pool --ca-id=1 \
--name=service-dns-ca-pool \
@@ -110,7 +122,7 @@ Agent Substrate signs pod identities and service certificates from CA pools that
--secret-namespace=podcertificate-controller-system
```
-2. Create the actor identity pools that Agent Substrate uses to issue and verify actor credentials.
+4. Create the actor identity pools that Agent Substrate uses to issue and verify actor credentials.
```bash
kubectl ate admin make-jwt-pool --key-id=1 \
--name=actor-id-jwt-pool \
@@ -120,7 +132,7 @@ Agent Substrate signs pod identities and service certificates from CA pools that
--secret-namespace=ate-system
```
-3. Extract the actor identity root certificate and store it in the secret that the Agent Substrate API server reads.
+5. Extract the actor identity root certificate and store it in the secret that the Agent Substrate API server reads.
```bash
actor_id_ca_root="$(kubectl get secret actor-id-ca-pool -n ate-system \
-o jsonpath='{.data.pool}' | base64 --decode \
@@ -131,7 +143,7 @@ Agent Substrate signs pod identities and service certificates from CA pools that
--from-literal=ca.crt="${actor_id_ca_root}"
```
-4. Create the authentication configuration. The `kubernetes` provider accepts Kubernetes ServiceAccount tokens that are issued for the Agent Substrate API server audience.
+6. Create the authentication configuration. The `kubernetes` provider accepts Kubernetes ServiceAccount tokens that are issued for the Agent Substrate API server audience.
```bash
kubectl create configmap ate-api-authentication -n ate-system \
--from-literal=authentication.yaml='actorIdentityJWTProvider: kubernetes
@@ -144,19 +156,19 @@ Agent Substrate signs pod identities and service certificates from CA pools that
'
```
-5. Roll Agent Substrate out again so that its pods mount the identity material, and wait for them to become ready.
+7. Roll Agent Substrate out again so that its pods mount the identity material, and wait for them to become ready.
```bash
helm upgrade substrate \
oci://ghcr.io/kagent-dev/substrate/helm/substrate \
- --version {{< reuse "versions/agent-substrate-1x.md" >}} \
+ --version {{< reuse "kagent-docs/versions/agent-substrate-1x.md" >}} \
--namespace ate-system --reuse-values --wait --timeout 10m
```
-6. Verify that Agent Substrate is running.
+8. Verify that Agent Substrate is running.
```bash
kubectl get pods -n ate-system
```
- Example output.
+ Example output:
```console
NAME READY STATUS RESTARTS AGE
ate-api-server-59fccdf6dc-f77h6 1/1 Running 3 9m
@@ -186,29 +198,32 @@ The kagent chart connects the controller to Agent Substrate and creates a Worker
--namespace kagent --create-namespace --wait
```
-2. Set your model provider API key. The examples in this guide use OpenAI. For other providers, see [Configure model providers]({{< link path="setup/configure-model-providers" >}}).
- ```bash
- export OPENAI_API_KEY="your-api-key-here"
- ```
-
-3. Install kagent with the Agent Substrate integration enabled. Set `substrateWorkerPool.ateomImage` explicitly, because the chart has no default for it and the install fails without it whenever `substrateWorkerPool.create` is `true`.
+2. Install kagent with the Agent Substrate integration enabled. Set `substrateWorkerPool.ateomImage` explicitly, because the chart has no default for it and the install fails without it whenever `substrateWorkerPool.create` is `true`.
```bash
helm upgrade --install kagent \
oci://ghcr.io/kagent-dev/kagent/helm/kagent \
--version \
--namespace kagent --create-namespace --timeout 10m \
- --set providers.default=openAI \
- --set providers.openAI.apiKey="${OPENAI_API_KEY}" \
- --set controller.substrate.enabled=true \
- --set controller.substrate.ateApiEndpoint=dns:///api.ate-system.svc:443 \
- --set controller.substrate.atenetRouterURL=http://atenet-router.ate-system.svc:80 \
- --set controller.substrate.defaultWorkerPool.name=kagent-default \
- --set substrateWorkerPool.create=true \
- --set substrateWorkerPool.replicas=1 \
- --set-string substrateWorkerPool.ateomImage=ghcr.io/kagent-dev/substrate/ateom-gvisor:v{{< reuse "versions/agent-substrate-1x.md" >}}
+ -f - <}}"
+ EOF
```
-4. Wait for the controller to roll out.
+3. Wait for the controller to roll out.
```bash
kubectl rollout status deployment/kagent-controller -n kagent --timeout=300s
```
@@ -222,7 +237,7 @@ The kagent chart connects the controller to Agent Substrate and creates a Worker
```bash
kubectl get pods -n kagent
```
- Example output.
+ Example output:
```console
NAME READY STATUS RESTARTS AGE
kagent-controller-659b58768b-2k6h4 1/1 Running 3 2m
@@ -234,7 +249,7 @@ The kagent chart connects the controller to Agent Substrate and creates a Worker
```bash
kubectl get workerpools -n kagent
```
- Example output.
+ Example output:
```console
NAMESPACE NAME DESIRED REPLICAS READY AGE
kagent kagent-default 1 1 1 2m
From 92dc29e937edaf33d1d0cdec2e65abbc63f01ce3 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Wed, 26 Aug 2026 12:41:49 -0500
Subject: [PATCH 23/70] Move version conrefs
Signed-off-by: Rachael Graham
---
.../snippets}/review-table.md | 0
.../kagent-docs/versions/agent-substrate.md | 1 +
.../{ => kagent-docs}/versions/jaeger.md | 0
.../assets/kagent-docs/versions/kagent.md | 1 +
.../assets/{ => kagent-docs}/versions/loki.md | 0
.../{ => kagent-docs}/versions/max-kube.md | 0
.../{ => kagent-docs}/versions/tempo.md | 0
.../assets/versions/agent-substrate-1x.md | 1 -
docs-site/assets/versions/agent-substrate.md | 1 -
docs-site/assets/versions/kagent.md | 1 -
.../kagent/0.x/examples/agent-substrate.md | 16 ++++-----
.../kagent/0.x/getting-started/quickstart.md | 2 +-
.../kagent/0.x/introduction/installation.md | 2 +-
.../kagent/0.x/observability/audit-prompts.md | 4 +--
.../kagent/0.x/observability/tracing.md | 2 +-
.../content/kagent/0.x/resources/versions.md | 4 +--
.../supported-providers/byo-agentgateway.md | 4 +--
.../content/kagent/1.x/setup/installation.md | 35 +++++++++----------
18 files changed, 36 insertions(+), 38 deletions(-)
rename docs-site/assets/{conrefs/snippets/field-desc => kagent-docs/snippets}/review-table.md (100%)
create mode 100644 docs-site/assets/kagent-docs/versions/agent-substrate.md
rename docs-site/assets/{ => kagent-docs}/versions/jaeger.md (100%)
create mode 100644 docs-site/assets/kagent-docs/versions/kagent.md
rename docs-site/assets/{ => kagent-docs}/versions/loki.md (100%)
rename docs-site/assets/{ => kagent-docs}/versions/max-kube.md (100%)
rename docs-site/assets/{ => kagent-docs}/versions/tempo.md (100%)
delete mode 100644 docs-site/assets/versions/agent-substrate-1x.md
delete mode 100644 docs-site/assets/versions/agent-substrate.md
delete mode 100644 docs-site/assets/versions/kagent.md
diff --git a/docs-site/assets/conrefs/snippets/field-desc/review-table.md b/docs-site/assets/kagent-docs/snippets/review-table.md
similarity index 100%
rename from docs-site/assets/conrefs/snippets/field-desc/review-table.md
rename to docs-site/assets/kagent-docs/snippets/review-table.md
diff --git a/docs-site/assets/kagent-docs/versions/agent-substrate.md b/docs-site/assets/kagent-docs/versions/agent-substrate.md
new file mode 100644
index 00000000..8ade5faa
--- /dev/null
+++ b/docs-site/assets/kagent-docs/versions/agent-substrate.md
@@ -0,0 +1 @@
+{{< version include-if="0.x" >}}0.0.6{{< /version >}}{{< version include-if="1.x" >}}0.0.20{{< /version >}}
\ No newline at end of file
diff --git a/docs-site/assets/versions/jaeger.md b/docs-site/assets/kagent-docs/versions/jaeger.md
similarity index 100%
rename from docs-site/assets/versions/jaeger.md
rename to docs-site/assets/kagent-docs/versions/jaeger.md
diff --git a/docs-site/assets/kagent-docs/versions/kagent.md b/docs-site/assets/kagent-docs/versions/kagent.md
new file mode 100644
index 00000000..68d3c797
--- /dev/null
+++ b/docs-site/assets/kagent-docs/versions/kagent.md
@@ -0,0 +1 @@
+{{< version include-if="0.x" >}}0.9.9{{< /version >}}{{< version include-if="1.x" >}}1.0.0-beta0{{< /version >}}
\ No newline at end of file
diff --git a/docs-site/assets/versions/loki.md b/docs-site/assets/kagent-docs/versions/loki.md
similarity index 100%
rename from docs-site/assets/versions/loki.md
rename to docs-site/assets/kagent-docs/versions/loki.md
diff --git a/docs-site/assets/versions/max-kube.md b/docs-site/assets/kagent-docs/versions/max-kube.md
similarity index 100%
rename from docs-site/assets/versions/max-kube.md
rename to docs-site/assets/kagent-docs/versions/max-kube.md
diff --git a/docs-site/assets/versions/tempo.md b/docs-site/assets/kagent-docs/versions/tempo.md
similarity index 100%
rename from docs-site/assets/versions/tempo.md
rename to docs-site/assets/kagent-docs/versions/tempo.md
diff --git a/docs-site/assets/versions/agent-substrate-1x.md b/docs-site/assets/versions/agent-substrate-1x.md
deleted file mode 100644
index eb1591a7..00000000
--- a/docs-site/assets/versions/agent-substrate-1x.md
+++ /dev/null
@@ -1 +0,0 @@
-0.0.20
\ No newline at end of file
diff --git a/docs-site/assets/versions/agent-substrate.md b/docs-site/assets/versions/agent-substrate.md
deleted file mode 100644
index 99d85ecd..00000000
--- a/docs-site/assets/versions/agent-substrate.md
+++ /dev/null
@@ -1 +0,0 @@
-0.0.6
\ No newline at end of file
diff --git a/docs-site/assets/versions/kagent.md b/docs-site/assets/versions/kagent.md
deleted file mode 100644
index 6f060dcb..00000000
--- a/docs-site/assets/versions/kagent.md
+++ /dev/null
@@ -1 +0,0 @@
-0.9.9
\ No newline at end of file
diff --git a/docs-site/content/kagent/0.x/examples/agent-substrate.md b/docs-site/content/kagent/0.x/examples/agent-substrate.md
index ffd6acc4..5cba795a 100644
--- a/docs-site/content/kagent/0.x/examples/agent-substrate.md
+++ b/docs-site/content/kagent/0.x/examples/agent-substrate.md
@@ -9,7 +9,7 @@ In this guide, you install Agent Substrate and kagent on a local kind cluster, t
By the end, you will have:
-- Agent Substrate v{{< reuse "versions/agent-substrate.md" >}} running in the `ate-system` namespace.
+- Agent Substrate v{{< reuse "kagent-docs/versions/agent-substrate.md" >}} running in the `ate-system` namespace.
- kagent v0.9.7 or later installed with the substrate integration enabled. Earlier kagent releases do not include the controller wiring that lets a `SandboxAgent` target substrate.
- A `SandboxAgent` running on substrate, reachable from the kagent UI.
@@ -33,7 +33,7 @@ export OPENAI_API_KEY="sk-..."
kind create cluster --name kagent-substrate
```
-The substrate v{{< reuse "versions/agent-substrate.md" >}} chart defaults to JWT auth backed by Kubernetes ServiceAccount tokens, so a vanilla kind cluster works — no feature gates or custom kind config are required.
+The substrate v{{< reuse "kagent-docs/versions/agent-substrate.md" >}} chart defaults to JWT auth backed by Kubernetes ServiceAccount tokens, so a vanilla kind cluster works — no feature gates or custom kind config are required.
## Step 2: Install Agent Substrate
@@ -42,12 +42,12 @@ Install the CRDs first, then the substrate control plane and data plane.
```bash
helm upgrade --install substrate-crds \
oci://ghcr.io/kagent-dev/substrate/helm/substrate-crds \
- --version {{< reuse "versions/agent-substrate.md" >}} \
+ --version {{< reuse "kagent-docs/versions/agent-substrate.md" >}} \
--namespace ate-system --create-namespace --wait
helm upgrade --install substrate \
oci://ghcr.io/kagent-dev/substrate/helm/substrate \
- --version {{< reuse "versions/agent-substrate.md" >}} \
+ --version {{< reuse "kagent-docs/versions/agent-substrate.md" >}} \
--namespace ate-system --wait --timeout 10m
```
@@ -78,12 +78,12 @@ Install the CRDs, then kagent with the substrate flags.
```bash
helm upgrade --install kagent-crds \
oci://ghcr.io/kagent-dev/kagent/helm/kagent-crds \
- --version {{< reuse "versions/kagent.md" >}} \
+ --version {{< reuse "kagent-docs/versions/kagent.md" >}} \
--namespace kagent --create-namespace --wait
helm upgrade --install kagent \
oci://ghcr.io/kagent-dev/kagent/helm/kagent \
- --version {{< reuse "versions/kagent.md" >}} \
+ --version {{< reuse "kagent-docs/versions/kagent.md" >}} \
--namespace kagent --timeout 10m --wait \
--set providers.openAI.apiKey="${OPENAI_API_KEY}" \
--set providers.default=openAI \
@@ -92,7 +92,7 @@ helm upgrade --install kagent \
--set controller.substrate.ateApiInsecure=true \
--set substrateWorkerPool.create=true \
--set substrateWorkerPool.replicas=1 \
- --set substrateWorkerPool.ateomImage=ghcr.io/kagent-dev/substrate/ateom-gvisor:v{{< reuse "versions/agent-substrate.md" >}}
+ --set substrateWorkerPool.ateomImage=ghcr.io/kagent-dev/substrate/ateom-gvisor:v{{< reuse "kagent-docs/versions/agent-substrate.md" >}}
```
The `controller.substrate.*` and `substrateWorkerPool.*` flags turn on the substrate integration. The rest is a standard kagent install.
@@ -127,7 +127,7 @@ kubectl scale workerpool kagent-default -n kagent --replicas=3
# 2) Stick it into the helm release — survives upgrades.
helm upgrade kagent oci://ghcr.io/kagent-dev/kagent/helm/kagent \
- --version {{< reuse "versions/kagent.md" >}} --namespace kagent --reuse-values \
+ --version {{< reuse "kagent-docs/versions/kagent.md" >}} --namespace kagent --reuse-values \
--set substrateWorkerPool.replicas=3
# 3) Fresh install — change the value on the Step 3 install command above.
diff --git a/docs-site/content/kagent/0.x/getting-started/quickstart.md b/docs-site/content/kagent/0.x/getting-started/quickstart.md
index 6f0c76ae..9e548226 100644
--- a/docs-site/content/kagent/0.x/getting-started/quickstart.md
+++ b/docs-site/content/kagent/0.x/getting-started/quickstart.md
@@ -25,7 +25,7 @@ To run the AI agents you'll also need an [OpenAI](https://openai.com) API key. Y
export OPENAI_API_KEY="your-api-key-here"
```
-2. Download the kagent CLI. By default, the latest version {{< reuse "versions/kagent.md" >}} of kagent is installed.
+2. Download the kagent CLI. By default, the latest version {{< reuse "kagent-docs/versions/kagent.md" >}} of kagent is installed.
```bash
brew install kagent
diff --git a/docs-site/content/kagent/0.x/introduction/installation.md b/docs-site/content/kagent/0.x/introduction/installation.md
index 8eba5679..ca6e3350 100644
--- a/docs-site/content/kagent/0.x/introduction/installation.md
+++ b/docs-site/content/kagent/0.x/introduction/installation.md
@@ -21,7 +21,7 @@ Install kagent by using the kagent CLI or Helm.
export OPENAI_API_KEY="your-api-key-here"
```
-2. Download the kagent CLI. By default, the latest version {{< reuse "versions/kagent.md" >}} of kagent is installed.
+2. Download the kagent CLI. By default, the latest version {{< reuse "kagent-docs/versions/kagent.md" >}} of kagent is installed.
```bash
brew install kagent
diff --git a/docs-site/content/kagent/0.x/observability/audit-prompts.md b/docs-site/content/kagent/0.x/observability/audit-prompts.md
index d04b306d..9f48205b 100644
--- a/docs-site/content/kagent/0.x/observability/audit-prompts.md
+++ b/docs-site/content/kagent/0.x/observability/audit-prompts.md
@@ -34,7 +34,7 @@ kagent supports logging input/output messages for the following LLM providers:
```yaml
helm upgrade --install loki loki \
--repo https://grafana.github.io/helm-charts \
- --version {{< reuse "versions/loki.md" >}} \
+ --version {{< reuse "kagent-docs/versions/loki.md" >}} \
--namespace telemetry \
--create-namespace \
--values - <}} \
+ --version {{< reuse "kagent-docs/versions/tempo.md" >}} \
--namespace telemetry \
--create-namespace \
--values - <}}
+ --version {{< reuse "kagent-docs/versions/jaeger.md" >}}
```
## Upgrade kagent
diff --git a/docs-site/content/kagent/0.x/resources/versions.md b/docs-site/content/kagent/0.x/resources/versions.md
index f40549bc..9624c729 100644
--- a/docs-site/content/kagent/0.x/resources/versions.md
+++ b/docs-site/content/kagent/0.x/resources/versions.md
@@ -6,7 +6,7 @@ weight: 4
author: kagent.dev
---
-kagent's CI tests against Kubernetes {{< reuse "versions/max-kube.md" >}} today.
+kagent's CI tests against Kubernetes {{< reuse "kagent-docs/versions/max-kube.md" >}} today.
Only the latest kagent release is supported. The tested Kubernetes version above applies to that release. Older kagent releases are not maintained or supported, regardless of which Kubernetes version they were originally tested against.
@@ -15,5 +15,5 @@ The tested version is sourced from `KIND_IMAGE_VERSION` in the [kagent Makefile]
Kubernetes versions other than the one listed above are not tested in CI and are not guaranteed to work, though kagent's Kubernetes client libraries generally follow the [client-go version skew policy](https://github.com/kubernetes/client-go#compatibility-matrix).
diff --git a/docs-site/content/kagent/0.x/supported-providers/byo-agentgateway.md b/docs-site/content/kagent/0.x/supported-providers/byo-agentgateway.md
index 4c0095cc..86c331b2 100644
--- a/docs-site/content/kagent/0.x/supported-providers/byo-agentgateway.md
+++ b/docs-site/content/kagent/0.x/supported-providers/byo-agentgateway.md
@@ -84,7 +84,7 @@ You can route model requests through an [agentgateway](https://agentgateway.dev/
EOF
```
- {{< reuse "conrefs/snippets/field-desc/review-table.md" >}} For more information, see the [API docs](https://kagent.dev/docs/kagent/resources/api-ref#modelconfigspec).
+ {{< reuse "kagent-docs/snippets/review-table.md" >}} For more information, see the [API docs](https://kagent.dev/docs/kagent/resources/api-ref#modelconfigspec).
| Setting | Description |
| --- | --- |
@@ -120,7 +120,7 @@ You can route model requests through an [agentgateway](https://agentgateway.dev/
EOF
```
- {{< reuse "conrefs/snippets/field-desc/review-table.md" >}} For more information, see the [API docs](https://kagent.dev/docs/kagent/resources/api-ref#modelconfigspec).
+ {{< reuse "kagent-docs/snippets/review-table.md" >}} For more information, see the [API docs](https://kagent.dev/docs/kagent/resources/api-ref#modelconfigspec).
| Setting | Description |
| --- | --- |
diff --git a/docs-site/content/kagent/1.x/setup/installation.md b/docs-site/content/kagent/1.x/setup/installation.md
index 13428da3..45ffd699 100644
--- a/docs-site/content/kagent/1.x/setup/installation.md
+++ b/docs-site/content/kagent/1.x/setup/installation.md
@@ -17,7 +17,7 @@ kagent 1.0 runs every agent on [Agent Substrate]({{< link path="about/agent-subs
* [`kubectl-ate`](https://github.com/kagent-dev/substrate/releases), the Agent Substrate command line tool, published as a `kubectl` plugin with each Agent Substrate release.
```bash
curl -fsSL -o kubectl-ate \
- "https://github.com/kagent-dev/substrate/releases/download/v{{< reuse "kagent-docs/versions/agent-substrate-1x.md" >}}/kubectl-ate-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m | sed 's/x86_64/amd64/; s/aarch64/arm64/')"
+ "https://github.com/kagent-dev/substrate/releases/download/v{{< reuse "kagent-docs/versions/agent-substrate.md" >}}/kubectl-ate-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m | sed 's/x86_64/amd64/; s/aarch64/arm64/')"
chmod +x kubectl-ate
sudo mv kubectl-ate /usr/local/bin/
kubectl ate --help
@@ -100,7 +100,7 @@ Deploy the Agent Substrate control plane and data plane into the `ate-system` na
```bash
helm upgrade --install substrate-crds \
oci://ghcr.io/kagent-dev/substrate/helm/substrate-crds \
- --version {{< reuse "kagent-docs/versions/agent-substrate-1x.md" >}} \
+ --version {{< reuse "kagent-docs/versions/agent-substrate.md" >}} \
--namespace ate-system --create-namespace
```
@@ -108,7 +108,7 @@ Deploy the Agent Substrate control plane and data plane into the `ate-system` na
```bash
helm upgrade --install substrate \
oci://ghcr.io/kagent-dev/substrate/helm/substrate \
- --version {{< reuse "kagent-docs/versions/agent-substrate-1x.md" >}} \
+ --version {{< reuse "kagent-docs/versions/agent-substrate.md" >}} \
--namespace ate-system
```
@@ -160,7 +160,7 @@ Deploy the Agent Substrate control plane and data plane into the `ate-system` na
```bash
helm upgrade substrate \
oci://ghcr.io/kagent-dev/substrate/helm/substrate \
- --version {{< reuse "kagent-docs/versions/agent-substrate-1x.md" >}} \
+ --version {{< reuse "kagent-docs/versions/agent-substrate.md" >}} \
--namespace ate-system --reuse-values --wait --timeout 10m
```
@@ -194,15 +194,15 @@ The kagent chart connects the controller to Agent Substrate and creates a Worker
```bash
helm upgrade --install kagent-crds \
oci://ghcr.io/kagent-dev/kagent/helm/kagent-crds \
- --version \
+ --version {{< reuse "kagent-docs/versions/kagent.md" >}} \
--namespace kagent --create-namespace --wait
```
-2. Install kagent with the Agent Substrate integration enabled. Set `substrateWorkerPool.ateomImage` explicitly, because the chart has no default for it and the install fails without it whenever `substrateWorkerPool.create` is `true`.
+2. Install kagent with the Agent Substrate integration enabled.
```bash
helm upgrade --install kagent \
oci://ghcr.io/kagent-dev/kagent/helm/kagent \
- --version \
+ --version {{< reuse "kagent-docs/versions/kagent.md" >}} \
--namespace kagent --create-namespace --timeout 10m \
-f - <}}"
+ ateomImage: "ghcr.io/kagent-dev/substrate/ateom-gvisor:v{{< reuse "kagent-docs/versions/agent-substrate.md" >}}"
EOF
```
@@ -229,7 +229,7 @@ The kagent chart connects the controller to Agent Substrate and creates a Worker
```
> [!NOTE]
-> The kagent controller can restart a few times during a first install while it waits for its bundled PostgreSQL database to accept connections. The controller logs `dial tcp ...:5432: connect: connection refused` and then recovers on its own. A restart loop that reports an `ate-api` dial failure instead points at an incomplete identity bootstrap.
+> The kagent controller can restart a few times during a first install while it waits for its bundled PostgreSQL database to accept connections. The controller logs `dial tcp ...:5432: connect: connection refused` and then recovers on its own. A restart loop that reports an `ate-api` dial failure instead indicates an incomplete identity bootstrap.
## Verify the installation
@@ -245,7 +245,7 @@ The kagent chart connects the controller to Agent Substrate and creates a Worker
kagent-postgresql-65cc684b78-9qbh2 1/1 Running 0 2m
```
-2. Confirm that the WorkerPool reports a ready replica. Agents cannot start until the pool is ready.
+2. Confirm that the WorkerPool reports a ready replica.
```bash
kubectl get workerpools -n kagent
```
@@ -255,8 +255,14 @@ The kagent chart connects the controller to Agent Substrate and creates a Worker
kagent kagent-default 1 1 1 2m
```
-3. Note how you reach the kagent gRPC API, which serves the AgentInstance lifecycle and conversation calls. [Your first agent]({{< link path="get-started/your-first-agent" >}}) assumes the port-forward.
+3. Get the address to reach the kagent gRPC API, which serves the AgentInstance lifecycle and conversation calls. The guide to [create your first agent]({{< link path="get-started/your-first-agent" >}}) assumes port-forwarding.
{{< tabs >}}
+ {{% tab name="Port-forward for local testing" %}}
+ Forward the gRPC port and leave the command running. The API is then available at `localhost:8084`.
+ ```bash
+ kubectl port-forward -n kagent svc/kagent-controller 8084:8084
+ ```
+ {{% /tab %}}
{{% tab name="Cloud Provider LoadBalancer" %}}
Read the external address of the controller service. The gRPC API listens on port `8084`.
```bash
@@ -264,13 +270,6 @@ The kagent chart connects the controller to Agent Substrate and creates a Worker
-o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}"
```
{{% /tab %}}
- {{% tab name="Port-forward for local testing" %}}
- Forward the gRPC port and leave the command running. The API is then available at `localhost:8084`.
- ```bash
- kubectl port-forward -n kagent svc/kagent-controller 8084:8084
- ```
- On a local kind cluster, use the port-forward. kind assigns a LoadBalancer address that is routable from inside the cluster, but not from your workstation.
- {{% /tab %}}
{{< /tabs >}}
## Next steps
From a030a3ceb9694beecb723edabf6ce3ced5486f39 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Wed, 26 Aug 2026 21:47:25 -0500
Subject: [PATCH 24/70] Phase 2, review 3
Signed-off-by: Rachael Graham
---
.../1.x/get-started/your-first-agent.md | 4 +--
.../content/kagent/1.x/setup/installation.md | 4 +++
.../kagent/1.x/skills-and-mcp/skills.md | 25 ++++++++++---------
.../1.x/substrate-runtime/sandboxing.md | 6 ++---
.../substrate-runtime/suspend-and-resume.md | 2 +-
5 files changed, 23 insertions(+), 18 deletions(-)
diff --git a/docs-site/content/kagent/1.x/get-started/your-first-agent.md b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
index ff1731ad..bbb36135 100644
--- a/docs-site/content/kagent/1.x/get-started/your-first-agent.md
+++ b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
@@ -9,7 +9,7 @@ This guide walks you through creating an agent, from applying a Harness and an A
## Before you begin
-1. [Install kagent with a WorkerPool provisioned]({{< link path="setup/installation" >}}). Be sure to add `--set controller.grpc.reflection=true` to the Helm install command so that grpcurl can discover the controller's gRPC methods without a local copy of kagent's proto files.
+1. [Install kagent with a WorkerPool provisioned]({{< link path="setup/installation" >}}).
2. Install [grpcurl](https://github.com/fullstorydev/grpcurl).
3. Port-forward the controller's gRPC port to your local machine.
```shell
@@ -174,5 +174,5 @@ The response carries the agent's reply in the same `parts` shape as the request.
{{< cards >}}
{{< card link=`{{< link path="about/agent-substrate" >}}` title="Agent Substrate architecture" subtitle="Understand what happens to your AgentInstance's Actor when it sits idle." >}}
{{< card link=`{{< link path="agents/agent-harness" >}}` title="Agent harness" subtitle="Choose from the full set of Harness runtime options, including Claude Code and Codex." >}}
- {{< card link=`{{< link path="skills-mcp/skills" >}}` title="Skills" subtitle="Give your agent capabilities beyond its system prompt." >}}
+ {{< card link=`{{< link path="skills-and-mcp/skills" >}}` title="Skills" subtitle="Give your agent capabilities beyond its system prompt." >}}
{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/setup/installation.md b/docs-site/content/kagent/1.x/setup/installation.md
index 45ffd699..cb46d323 100644
--- a/docs-site/content/kagent/1.x/setup/installation.md
+++ b/docs-site/content/kagent/1.x/setup/installation.md
@@ -210,6 +210,8 @@ The kagent chart connects the controller to Agent Substrate and creates a Worker
openAI:
apiKey: ${OPENAI_API_KEY}
controller:
+ grpc:
+ reflection: true
substrate:
enabled: true
ateApiEndpoint: dns:///api.ate-system.svc:443
@@ -222,6 +224,8 @@ The kagent chart connects the controller to Agent Substrate and creates a Worker
ateomImage: "ghcr.io/kagent-dev/substrate/ateom-gvisor:v{{< reuse "kagent-docs/versions/agent-substrate.md" >}}"
EOF
```
+ > [!NOTE]
+ > `controller.grpc.reflection` lets a gRPC client discover the controller's methods without a local copy of kagent's proto files, which is how [Your first agent]({{< link path="get-started/your-first-agent" >}}) calls the API. Leave it on while you explore the API, and turn it off for a production installation.
3. Wait for the controller to roll out.
```bash
diff --git a/docs-site/content/kagent/1.x/skills-and-mcp/skills.md b/docs-site/content/kagent/1.x/skills-and-mcp/skills.md
index 0e72792e..60adc8d1 100644
--- a/docs-site/content/kagent/1.x/skills-and-mcp/skills.md
+++ b/docs-site/content/kagent/1.x/skills-and-mcp/skills.md
@@ -11,11 +11,13 @@ A **skill** packages a piece of know-how that an agent can pick up: a set of ins
A skill is a directory whose root holds a `SKILL.md` file. That file carries front matter naming the skill and describing what it is for, followed by the instructions themselves.
-The description is what makes a skill usable. When an agent starts, the runtime reads the front matter of every skill that is attached to it and offers those skills to the model as tools that it can call. The model chooses a skill from its description, in the same way that it chooses any other tool, so a description that states plainly when to use the skill matters more than the length of the instructions behind it.
+The description is what makes a skill usable. When an agent starts, the runtime reads the front matter of every skill that is attached to it, and offers those skills to the model as tools that it can call. The model chooses a skill from its description, in the same way that it chooses any other tool. This means that a description that states plainly when to use the skill matters more than the length of the instructions behind it.
+
+A skill can be published on its own, or bundled with other skills in a **plugin package**. A plugin package follows the Agent Plugins 1.0.0 format. Its `plugin.json` manifest names the package, and its skills live in a `skills` directory, one subdirectory per skill. A package may also declare Model Context Protocol (MCP) servers, which kagent adds to the agent's tools alongside the skills that you enable from that package.
## Attach skills to an AgentTemplate
-An AgentTemplate attaches skills two ways, and it can use both at once. Use `spec.skills` for a skill that is published on its own, and `spec.plugins` for a bundle that carries several skills together.
+An AgentTemplate attaches skills in two ways, and it can use both at once. Use `spec.skills` for a standalone skill, and `spec.plugins` for a plugin package.
```yaml
apiVersion: kagent.dev/v1alpha3
@@ -50,7 +52,12 @@ spec:
| `plugins[].skills` | The names of the skills inside that package to enable. Omit or leave empty to enable none. |
| `source.path` | Selects a directory inside the artifact, when the content is not at its root. The path must be relative, and it cannot climb out of the artifact with `..` segments. |
-A plugin package follows the Agent Plugins 1.0.0 format. Its `plugin.json` names the package, and its skills live in a `skills` directory, one subdirectory per skill. A package may also declare Model Context Protocol (MCP) servers, which kagent adds to the agent's tools alongside the skills that you enabled.
+### The plugin allowlist
+
+Attaching a plugin package does not enable any of the skills that it carries. Only the names listed in `plugins[].skills` are enabled.
+
+> [!IMPORTANT]
+> An empty skills list enables nothing. Adding a plugin package and omitting its `skills` list gives the agent no skills from that package, which is the safe default rather than an error. Listing skills explicitly also means that a package gaining new skills in a later version does not silently grant them to your agent.
## Every source is immutable
@@ -60,14 +67,7 @@ A skill changes what an agent does, so kagent only accepts artifact references t
- **`git`**: A repository URL together with a full commit identifier. An abbreviated commit, a branch, or a tag is rejected.
- **`bucket.s3`**: An endpoint, bucket, and key, together with the `versionId` of that exact object version. A region is included where the service requires one for request signing.
-Pinning has a practical consequence worth planning for. Publishing a new version of a skill means updating the AgentTemplate to name the new digest, commit, or object version, which compiles a new revision. Agents that are already running keep the skill content that they started with.
-
-## The plugin allowlist
-
-A plugin package can carry many skills, and attaching the package does not enable any of them. Only the names listed in `plugins[].skills` are enabled.
-
-> [!IMPORTANT]
-> An empty skills list enables nothing. Adding a plugin package and omitting its `skills` list gives the agent no skills from that package, which is the safe default rather than an error. Listing skills explicitly also means that a package gaining new skills in a later version does not silently grant them to your agent.
+Pinning has a practical consequence worth planning for. Publishing a new version of a skill means updating the AgentTemplate to name the new digest, commit, or object version, which compiles a new revision. Agents that are already running keep using the skill content that they started with.
## Naming rules
@@ -76,11 +76,12 @@ Skill names are checked before anything is fetched, and two rules apply across e
- A name must be a single path component. A name containing a slash, or a name of `.` or `..`, is rejected.
- Names must be unique across the whole AgentTemplate. Because standalone skills and plugin skills are mounted into the same place, a standalone skill cannot reuse the name of an enabled plugin skill, and two plugin packages cannot both contribute the same name.
-Plugin package names must also be unique. Two entries in `plugins` whose manifests declare the same name are rejected.
+Plugin package names must also be unique. Two entries in `plugins` whose manifests declare the same name are rejected. Unlike skill names, kagent checks this as each package is fetched, because the name comes from the package's `plugin.json` manifest rather than from your AgentTemplate.
## Next steps
{{< cards >}}
+ {{< card link=`{{< link path="examples/skills" >}}` title="Add skills to agents" subtitle="Walk through attaching a skill from an OCI artifact, end to end." >}}
{{< card link=`{{< link path="skills-and-mcp/about-tools" >}}` title="About tools" subtitle="See how MCP tools and agent tools attach to an AgentTemplate." >}}
{{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Apply a Harness and AgentTemplate, and talk to the AgentInstance they produce." >}}
{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md b/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
index fce33678..c75a7b02 100644
--- a/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
+++ b/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
@@ -5,16 +5,16 @@ weight: 10
author: kagent.dev
---
-An agent is a program that decides at run time what to do next. It runs the commands that a model asks for, and it calls the tools that it was given. [Agent Substrate]({{< link path="about/agent-substrate" >}}) therefore does not run an Actor as an ordinary container process. It runs each Actor inside its own sandbox, on a Worker that hosts one Actor at a time. This page explains what selects a sandbox, what the sandbox separates, and how traffic reaches an Actor through it.
+An agent is a program that decides at run time what to do next. It runs the commands that a model asks for, and it calls the tools that it was given. [Agent Substrate]({{< link path="about/agent-substrate" >}}) runs each agent inside an **Actor**, its own unit of compute, and it does not run that Actor as an ordinary container process. Each Actor runs inside its own sandbox, on a Worker that hosts one Actor at a time. This page explains what selects a sandbox, what the sandbox separates, and how traffic reaches an Actor through it.
## Sandbox classes
A **sandbox class** is the sandbox runtime family that a Worker uses. Agent Substrate supports two.
-- **`gvisor`**: The default. [gVisor](https://gvisor.dev) runs a user-space kernel that intercepts the sandboxed program's system calls, so the workload does not call the host kernel directly.
+- **`gvisor`** (default): Runs the workload against a [gVisor](https://gvisor.dev) user-space kernel, which keeps the workload's system calls from reaching the host kernel.
- **`microvm`**: Runs the workload inside a lightweight virtual machine, which places a hypervisor boundary between the workload and the host.
-A WorkerPool selects its class through the `sandboxClass` field, which defaults to `gvisor`. The choice is not only a runtime preference. It also determines the shape of the Worker pods that Agent Substrate creates for that pool, including the virtualization device mounts and node placement that a micro-VM needs, and it determines which sandbox configurations the pool can draw on.
+A WorkerPool selects its class through the `sandboxClass` field, which defaults to `gvisor`. The choice is not only a runtime preference. It also shapes the Worker pods that Agent Substrate creates for that pool, including the virtualization device mounts and node placement that a micro-VM needs.
> [!NOTE]
> kagent generates ActorTemplates that use the `gvisor` class. Keep a WorkerPool that backs kagent Harnesses on `gvisor`.
diff --git a/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md b/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
index 4cf12290..2252bb5b 100644
--- a/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
+++ b/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
@@ -5,7 +5,7 @@ weight: 20
author: kagent.dev
---
-An agent spends most of its life waiting. It waits on a person to reply, and it waits on a large language model (LLM) to answer. [Agent Substrate]({{< link path="about/agent-substrate" >}}) treats that idle time as reclaimable: it suspends an idle Actor into a snapshot, frees the Worker that the Actor was running on, and restores the Actor when traffic arrives for it. This page explains what a snapshot captures, when kagent suspends an Actor, and what happens when a suspended Actor is addressed again.
+An agent spends most of its life waiting. It waits on a person to reply, and it waits on a large language model (LLM) to answer. [Agent Substrate]({{< link path="about/agent-substrate" >}}) runs each agent inside an **Actor**, the unit that it suspends and resumes, and it treats that idle time as reclaimable: it suspends an idle Actor into a snapshot, frees the Worker that the Actor was running on, and restores the Actor when traffic arrives for it. This page explains what a snapshot captures, when kagent suspends an Actor, and what happens when a suspended Actor is addressed again.
## Actor lifecycle operations
From 650fd0b5d4189d074ab0205caa3afc962401d04f Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Thu, 27 Aug 2026 15:24:00 -0500
Subject: [PATCH 25/70] update mermaid styling
Signed-off-by: Rachael Graham
---
docs-site/assets/css/custom.css | 17 ++++++
.../kagent/1.x/about/agent-substrate.md | 8 ++-
.../content/kagent/1.x/about/architecture.md | 2 +-
.../content/kagent/1.x/about/core-concepts.md | 2 +-
.../kagent/1.x/skills-and-mcp/skills.md | 2 +-
.../1.x/substrate-runtime/sandboxing.md | 51 ++++++++++++++++--
.../layouts/partials/custom/head-end.html | 54 +++++++++++++++++++
7 files changed, 129 insertions(+), 7 deletions(-)
diff --git a/docs-site/assets/css/custom.css b/docs-site/assets/css/custom.css
index 2680967b..2f66da83 100644
--- a/docs-site/assets/css/custom.css
+++ b/docs-site/assets/css/custom.css
@@ -434,3 +434,20 @@ h6 {
:where(.dark, .dark *) .hextra-nav-container img[src*="kagent-logo-light"] { display: none; }
:where(.dark, .dark *) .hextra-nav-container img[src*="kagent-logo-dark"] { display: block; }
}
+
+/* ── Mermaid diagram alignment ────────────────────────────────────────────
+ Hextra renders every diagram into a full-width
that
+ carries the code-block background, while Mermaid sizes its own SVG to the
+ diagram's natural width. A narrow diagram therefore sits against the left
+ edge of a wide, mostly empty panel. Center it instead.
+
+ Note: the panel itself cannot be shrunk to fit from CSS. Mermaid sets
+ width="100%" on the SVG and records the real size only in an inline
+ max-width, so width:fit-content has no definite width to measure and
+ collapses every diagram to the 300px SVG default. Shrinking the panel would
+ require Mermaid's useMaxWidth:false, which means overriding the theme's
+ scripts/mermaid.html partial. */
+pre.mermaid {
+ display: flex;
+ justify-content: center;
+}
diff --git a/docs-site/content/kagent/1.x/about/agent-substrate.md b/docs-site/content/kagent/1.x/about/agent-substrate.md
index 798aa2ed..e21f94af 100644
--- a/docs-site/content/kagent/1.x/about/agent-substrate.md
+++ b/docs-site/content/kagent/1.x/about/agent-substrate.md
@@ -5,7 +5,7 @@ weight: 40
author: kagent.dev
---
-The [kagent architecture]({{< link path="about/architecture" >}}) page established that every AgentInstance runs on an Actor. This page explains what an Actor is built from and what it runs on: the ActorTemplate that it is created from, the compute that hosts it, the sandbox that isolates it, and the snapshot cycle that lets it suspend when idle and resume on demand.
+The [kagent architecture]({{< link path="about/architecture" >}}) page established that every AgentInstance runs on an Actor. This page explains what an Actor is built from and what it runs on: the ActorTemplate that it is created from, the compute that hosts it, the atespace that identifies it, the sandbox that isolates it, and the snapshot cycle that lets it suspend when idle and resume on demand.
## ActorTemplate
@@ -21,6 +21,12 @@ Workers come from a **WorkerPool**, a Kubernetes custom resource that an operato
An operator never creates a Worker directly. Substrate manages them, keeping enough ready in each WorkerPool so that an Actor can start or resume on one immediately, without waiting on the Kubernetes scheduler to place a new Pod.
+## Atespaces
+
+An **atespace** is the isolation boundary that an Actor belongs to, and the first half of its identity. Agent Substrate addresses an Actor by its atespace and its name together, so the same Actor name can exist in two atespaces without colliding. Despite the resemblance, an atespace is a global-scoped Agent Substrate resource rather than a Kubernetes namespace.
+
+kagent names each atespace after the Kubernetes namespace of the AgentInstance whose Actor it holds, and creates that atespace on demand the first time an AgentInstance in the namespace needs an Actor. The Actor's own name comes from the AgentInstance's identifier. An AgentInstance in the `kagent` namespace therefore runs on an Actor that Agent Substrate addresses within the `kagent` atespace. Both halves of that identity appear in the address that traffic uses to reach the Actor, which [Sandboxing]({{< link path="substrate-runtime/sandboxing#how-traffic-reaches-a-sandboxed-actor" >}}) covers.
+
## Sandboxing
Because an Actor often runs a model-directed agent that calls tools and executes commands, Substrate runs each Actor in an isolated sandbox rather than a plain container. A WorkerPool's `sandboxClass` field selects the sandbox technology for its Workers: [gVisor](https://gvisor.dev) or a micro-VM technology such as [Kata Containers](https://katacontainers.io). Both technologies isolate an Actor from its Worker's host kernel, and both support suspend and resume operations.
diff --git a/docs-site/content/kagent/1.x/about/architecture.md b/docs-site/content/kagent/1.x/about/architecture.md
index cd34d668..c2f5021e 100644
--- a/docs-site/content/kagent/1.x/about/architecture.md
+++ b/docs-site/content/kagent/1.x/about/architecture.md
@@ -52,7 +52,7 @@ flowchart TB
%% plane. Without it, the layout engine staggers the two planes diagonally.
%% actortemplate ~~~ caller
- classDef crd stroke:#a78bfa,fill:transparent
+ classDef crd stroke:#a78bfa,stroke-width:2px
class harness,template crd
```
diff --git a/docs-site/content/kagent/1.x/about/core-concepts.md b/docs-site/content/kagent/1.x/about/core-concepts.md
index 663c726b..cadad85d 100644
--- a/docs-site/content/kagent/1.x/about/core-concepts.md
+++ b/docs-site/content/kagent/1.x/about/core-concepts.md
@@ -31,7 +31,7 @@ flowchart LR
actortemplate -->|instantiated as| instance
instance -->|runs on| actor
- classDef crd stroke:#a78bfa,fill:transparent
+ classDef crd stroke:#a78bfa,stroke-width:2px
class harness,template crd
```
diff --git a/docs-site/content/kagent/1.x/skills-and-mcp/skills.md b/docs-site/content/kagent/1.x/skills-and-mcp/skills.md
index 60adc8d1..f5b0f9b9 100644
--- a/docs-site/content/kagent/1.x/skills-and-mcp/skills.md
+++ b/docs-site/content/kagent/1.x/skills-and-mcp/skills.md
@@ -52,7 +52,7 @@ spec:
| `plugins[].skills` | The names of the skills inside that package to enable. Omit or leave empty to enable none. |
| `source.path` | Selects a directory inside the artifact, when the content is not at its root. The path must be relative, and it cannot climb out of the artifact with `..` segments. |
-### The plugin allowlist
+### Plugin allowlist
Attaching a plugin package does not enable any of the skills that it carries. Only the names listed in `plugins[].skills` are enabled.
diff --git a/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md b/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
index c75a7b02..6d4da3c8 100644
--- a/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
+++ b/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
@@ -5,7 +5,22 @@ weight: 10
author: kagent.dev
---
-An agent is a program that decides at run time what to do next. It runs the commands that a model asks for, and it calls the tools that it was given. [Agent Substrate]({{< link path="about/agent-substrate" >}}) runs each agent inside an **Actor**, its own unit of compute, and it does not run that Actor as an ordinary container process. Each Actor runs inside its own sandbox, on a Worker that hosts one Actor at a time. This page explains what selects a sandbox, what the sandbox separates, and how traffic reaches an Actor through it.
+An agent is a program that decides at run time what to do next. It runs the commands that a model asks for, and it calls the tools it can access. [Agent Substrate]({{< link path="about/agent-substrate" >}}) runs each agent inside an **Actor**, its own unit of compute, and it does not run that Actor as an ordinary container process. Each Actor runs inside its own **sandbox**, on a Worker that hosts one Actor at a time. This page explains what selects a sandbox, what the sandbox separates, and how traffic reaches an Actor through it.
+
+```mermaid
+flowchart LR
+ subgraph worker["Worker pod"]
+ subgraph sandbox["Sandbox: gvisor or microvm"]
+ subgraph actor["Actor"]
+ agent["Agent"]
+ end
+ end
+ end
+ classDef boundary fill:#a78bfa26,stroke:#a78bfa,stroke-width:2px
+ classDef inner fill:#80808033,stroke:#9ca3af,stroke-width:1px
+ class sandbox boundary
+ class agent inner
+```
## Sandbox classes
@@ -23,14 +38,44 @@ A WorkerPool selects its class through the `sandboxClass` field, which defaults
A **SandboxConfig** is a cluster-scoped resource that holds the material needed to start one sandbox runtime family. It carries the runtime assets that the node agent fetches, keyed by processor architecture, along with the pause image that holds the sandbox's namespaces as its root container. One SandboxConfig can be marked as the cluster default for its class, and a WorkerPool that names no configuration explicitly resolves to that default.
-Holding these assets in a cluster resource is what lets one configuration pin a runtime version for many ActorTemplates at once, rather than each template carrying its own copy. A default installation creates a single `gvisor-default` configuration.
+Defining these assets in a cluster resource is what lets one configuration pin a runtime version for many ActorTemplates at once, rather than each template carrying its own copy.
+
+A default installation creates a single `gvisor-default` configuration, which looks like the following:
+
+```yaml
+apiVersion: ate.dev/v1alpha1
+kind: SandboxConfig
+metadata:
+ name: gvisor-default
+spec:
+ sandboxClass: gvisor
+ default: true
+ pauseImage: registry.k8s.io/pause:3.10.2@sha256:
+ assets:
+ amd64:
+ gvisor:
+ url: gs://gvisor/releases/release/20260803/x86_64/gvisor.tar.bz2
+ sha256:
+ arm64:
+ gvisor:
+ url: gs://gvisor/releases/release/20260803/aarch64/gvisor.tar.bz2
+ sha256:
+```
+
+| Field | Description |
+| ----- | ----------- |
+| `sandboxClass` | The sandbox runtime family that this configuration applies to, `gvisor` or `microvm`. A WorkerPool only draws on configurations whose class matches its own. |
+| `default` | Marks this configuration as the cluster default for its class. Expect at most one default per class. |
+| `pauseImage` | The image for the root sandbox container, which holds the sandbox's namespaces and runs no workload code. It must be pinned to a digest, because the snapshot manifest records it, and changing the image invalidates the snapshots that were taken with it. |
+| `assets` | The files that the node agent fetches, keyed first by processor architecture and then by asset name. A `gvisor` class expects one `gvisor` asset, the release archive that the node agent extracts. A `microvm` class expects several, such as `cloud-hypervisor`, `kata-kernel`, and `kata-image`. |
+| `assets...sha256` | The lowercase hex digest of the file. The node agent verifies each download against it, and caches the result under a path that includes the digest, so changing the digest fetches the new asset instead of reusing the cached one. To read the configuration that your own cluster installed, including the pinned digests, run `kubectl get sandboxconfig gvisor-default -o yaml`.|
## What the sandbox separates
The sandbox draws a boundary in three places.
- **Process and kernel**: The Actor's processes run against the sandbox runtime rather than the Worker node's kernel. A system call that the workload makes is handled by gVisor's user-space kernel, or by the guest kernel inside a micro-VM, instead of reaching the host directly.
-- **Filesystem**: The Actor sees the filesystem assembled from its container image, plus whatever durable volume its ActorTemplate declares. Writes to the root filesystem are a layer on top of the image, captured in a `Full` snapshot and discarded by a `Data` one. See [Suspend and resume]({{< link path="substrate-runtime/suspend-and-resume" >}}) for what each scope keeps.
+- **Filesystem**: The Actor sees the filesystem assembled from its container image, plus whatever durable volume its ActorTemplate declares. Writes to the root filesystem are a layer on top of the image, captured in a `Full` snapshot and discarded by a `Data` one. For what each scope keeps, see [Suspend and resume]({{< link path="substrate-runtime/suspend-and-resume" >}}).
- **Network**: The Actor does not share the Worker pod's network position. The node agent gives the active Actor a private, point-to-point virtual network inside the Worker pod, so reaching the Actor means going through Agent Substrate's own network path rather than connecting to the Worker directly.
## How traffic reaches a sandboxed Actor
diff --git a/docs-site/layouts/partials/custom/head-end.html b/docs-site/layouts/partials/custom/head-end.html
index 603d7cc0..23e750a2 100644
--- a/docs-site/layouts/partials/custom/head-end.html
+++ b/docs-site/layouts/partials/custom/head-end.html
@@ -23,3 +23,57 @@
+
+{{- /* Mermaid light-theme colors.
+
+ Mermaid's stock "default" (light) theme fills clusters pale yellow (#ffffde)
+ and nodes lavender (#ECECFF), which is not the house palette. Its "dark" theme
+ is already correct: a gray cluster with the node reading as the page behind it.
+
+ This cannot be fixed from CSS or from a classDef:
+ - Mermaid emits classDef rules as `#mermaid- .cls>*{...!important}`.
+ That is ID-scoped, so no class-based rule in custom.css can outrank it.
+ - `fill:var(--x)` inside a classDef is a parse error — the parentheses break
+ Mermaid's classDef grammar — so the color cannot be a CSS variable.
+ - `fill:transparent` is not "the page" inside nested subgraphs: SVG
+ composites, so a transparent node shows the stacked cluster tints behind
+ it rather than the panel color.
+
+ So the light values are supplied as themeVariables, the same mechanism
+ Mermaid's dark theme uses. docs-theme-extras owns the Mermaid partial and
+ re-runs mermaid.initialize() on every theme switch, so this wraps initialize
+ rather than calling it, and stays correct across toggles without forking that
+ partial. Kept in this file (not a new _partials/custom/head-end.html) because
+ Hugo prefers _partials/ over partials/, so a second file would shadow this one
+ and drop the themeExtras bootstrap above. */ -}}
+
From e3f8c4d8ccdec9f98c8326106640ef8c0e456da5 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Thu, 27 Aug 2026 16:09:03 -0500
Subject: [PATCH 26/70] glossary
Signed-off-by: Rachael Graham
---
docs-site/assets/css/custom.css | 30 ++++++++++++
.../kagent/1.x/about/agent-substrate.md | 5 +-
.../content/kagent/1.x/about/architecture.md | 10 ++--
.../content/kagent/1.x/about/core-concepts.md | 5 +-
.../kagent/1.x/skills-and-mcp/skills.md | 4 +-
.../1.x/substrate-runtime/sandboxing.md | 13 ++---
.../substrate-runtime/suspend-and-resume.md | 16 +++----
docs-site/data/glossary.yaml | 47 +++++++++++++++++++
8 files changed, 105 insertions(+), 25 deletions(-)
create mode 100644 docs-site/data/glossary.yaml
diff --git a/docs-site/assets/css/custom.css b/docs-site/assets/css/custom.css
index 2f66da83..a1826742 100644
--- a/docs-site/assets/css/custom.css
+++ b/docs-site/assets/css/custom.css
@@ -451,3 +451,33 @@ pre.mermaid {
display: flex;
justify-content: center;
}
+
+/* ── Glossary term indicator ──────────────────────────────────────────────
+ docs-theme-extras marks a {{< gloss >}} term with `border-bottom: 1px
+ dotted #666` and defines no dark-mode variant. Two problems: that color
+ lands near 3:1 on this site's dark page, and a 1px dotted rule is only
+ about half coverage, so it reads as a hairline whatever its contrast.
+
+ Swap the border for a text-decoration underline, which allows a real
+ thickness and an offset that lifts the dots off the baseline, and raise
+ the color per theme. Hover and focus use the OSS brand color in place of
+ the theme's hardcoded #007acc.
+
+ The `html` prefix is load-bearing: glossary.css is a separate that
+ loads AFTER custom.css in both the production and dev pipelines, so a bare
+ `.glossary-term` would lose the cascade at equal specificity. */
+html .glossary-term {
+ border-bottom: none;
+ text-decoration: underline;
+ text-decoration-style: dotted;
+ text-decoration-thickness: 2px;
+ text-underline-offset: 4px;
+ text-decoration-color: #4b5563;
+}
+html.dark .glossary-term {
+ text-decoration-color: #9ca3af;
+}
+html .glossary-term:hover,
+html .glossary-term:focus {
+ text-decoration-color: var(--theme-primary, #0060cf);
+}
diff --git a/docs-site/content/kagent/1.x/about/agent-substrate.md b/docs-site/content/kagent/1.x/about/agent-substrate.md
index e21f94af..74a9bbe3 100644
--- a/docs-site/content/kagent/1.x/about/agent-substrate.md
+++ b/docs-site/content/kagent/1.x/about/agent-substrate.md
@@ -5,11 +5,11 @@ weight: 40
author: kagent.dev
---
-The [kagent architecture]({{< link path="about/architecture" >}}) page established that every AgentInstance runs on an Actor. This page explains what an Actor is built from and what it runs on: the ActorTemplate that it is created from, the compute that hosts it, the atespace that identifies it, the sandbox that isolates it, and the snapshot cycle that lets it suspend when idle and resume on demand.
+The [kagent architecture]({{< link path="about/architecture" >}}) page established that every {{< gloss "AgentInstance" >}}AgentInstance{{< /gloss >}} runs on an Actor. This page explains what an Actor is built from and what it runs on: the ActorTemplate that it is created from, the compute that hosts it, the atespace that identifies it, the sandbox that isolates it, and the snapshot cycle that lets it suspend when idle and resume on demand.
## ActorTemplate
-Every Actor is created from an **ActorTemplate**, the compiled definition that the kagent controller produces from a Harness and AgentTemplate pair.
+Every Actor is created from an **ActorTemplate**, the compiled definition that the kagent controller produces from a {{< gloss "Harness" >}}Harness{{< /gloss >}} and {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}} pair.
What Substrate adds is enforcement. Substrate rejects any change to an ActorTemplate's spec after it is created, so immutability is a property of the resource itself rather than a convention that the controller follows. That immutability requires the controller to create a new ActorTemplate for every compiled revision instead of editing an existing one, and allows the controller to safely reclaim an old ActorTemplate once no AgentInstance references it.
@@ -36,6 +36,7 @@ Because an Actor often runs a model-directed agent that calls tools and executes
Substrate's density model rests on one fact about agent workloads: an Actor spends most of its time idle, waiting on a person or a large language model (LLM) to respond, not actively computing. Substrate exploits that by suspending idle Actors and reclaiming their Worker, then resuming them on demand when traffic arrives. Suspending and resuming allows a WorkerPool to run far more Actors than it has Workers for at any given moment.
The following diagram traces an Actor through one suspend-and-resume cycle, and shows the second path that opens up once the resulting snapshot is tagged.
+
```mermaid
flowchart LR
diff --git a/docs-site/content/kagent/1.x/about/architecture.md b/docs-site/content/kagent/1.x/about/architecture.md
index c2f5021e..508614ba 100644
--- a/docs-site/content/kagent/1.x/about/architecture.md
+++ b/docs-site/content/kagent/1.x/about/architecture.md
@@ -11,8 +11,8 @@ The previous page defined the [core concepts]({{< link path="about/core-concepts
kagent 1.0 splits authorization across two planes:
-- The **Kubernetes plane** governs the Harness and AgentTemplate custom resources. Kubernetes Role-Based Access Control (RBAC) decides who can create, read, or edit the resources, exactly as it would for any other Custom Resource Definition (CRD).
-- The **kagent plane** governs any interactions involving AgentInstances, such as creating, suspending, resuming, sharing, deleting, and holding a conversation with an AgentInstance. kagent's own gRPC authentication and authorization decide who can complete these interactions, independent of Kubernetes RBAC.
+- The **Kubernetes plane** governs the {{< gloss "Harness" >}}Harness{{< /gloss >}} and {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}} custom resources. Kubernetes Role-Based Access Control (RBAC) decides who can create, read, or edit the resources, exactly as it would for any other Custom Resource Definition (CRD).
+- The **kagent plane** governs any interactions involving {{< gloss "AgentInstance" >}}AgentInstances{{< /gloss >}}, such as creating, suspending, resuming, sharing, deleting, and holding a conversation with an AgentInstance. kagent's own gRPC authentication and authorization decide who can complete these interactions, independent of Kubernetes RBAC.
Someone with Kubernetes RBAC access to apply a Harness and AgentTemplate does not automatically have access to create or talk to AgentInstances that use them, and the reverse is also true. The following diagram shows where the boundary between the two planes falls.
@@ -56,11 +56,11 @@ flowchart TB
class harness,template crd
```
-Follow the **Kubernetes plane** first. An operator applies a Harness and an AgentTemplate, governed by Kubernetes RBAC. The kagent controller watches for a valid pair with a matching `allowedAgentTemplates` selector, and compiles it into an ActorTemplate on Substrate.
+Follow the **Kubernetes plane** first. An operator applies a Harness and an AgentTemplate, governed by Kubernetes RBAC. The kagent controller watches for a valid pair with a matching `allowedAgentTemplates` selector, and compiles it into an {{< gloss "ActorTemplate" >}}ActorTemplate{{< /gloss >}} on Substrate.
-The **kagent plane** starts once that ActorTemplate exists. A caller, who may or may not be the same person as the operator, calls `CreateAgentInstance` through kagent's gRPC API. This call is governed by kagent's own authentication and authorization, not by Kubernetes RBAC. kagent creates the AgentInstance from the newest ActorTemplate that compiled successfully, and that AgentInstance runs on an Actor.
+The **kagent plane** starts once that ActorTemplate exists. A caller, who may or may not be the same person as the operator, calls `CreateAgentInstance` through kagent's gRPC API. This call is governed by kagent's own authentication and authorization, not by Kubernetes RBAC. kagent creates the AgentInstance from the newest ActorTemplate that compiled successfully, and that AgentInstance runs on an {{< gloss "Actor" >}}Actor{{< /gloss >}}.
-From there, the caller holds a conversation with the AgentInstance over the A2A (Agent-to-Agent) protocol. The A2A gateway routes each request to the Actor running behind the target AgentInstance. This means that the caller only ever needs to know an AgentInstance's identity, never which Actor or Worker is behind it.
+From there, the caller holds a conversation with the AgentInstance over the A2A (Agent-to-Agent) protocol. The A2A gateway routes each request to the Actor running behind the target AgentInstance. This means that the caller only ever needs to know an AgentInstance's identity, never which Actor or {{< gloss "Worker" >}}Worker{{< /gloss >}} is behind it.
## Why two planes
diff --git a/docs-site/content/kagent/1.x/about/core-concepts.md b/docs-site/content/kagent/1.x/about/core-concepts.md
index cadad85d..d0e064cf 100644
--- a/docs-site/content/kagent/1.x/about/core-concepts.md
+++ b/docs-site/content/kagent/1.x/about/core-concepts.md
@@ -14,7 +14,8 @@ The new model separates what an agent can do from how it is allowed to run:
- An [**AgentInstance**](#agentinstance) is a running conversation, created by pairing the two.
- An [**Actor**](#actor) is the sandboxed process, provided by Substrate, that an AgentInstance runs on.
-The following diagram shows how a Harness and an AgentTemplate become a running conversation. The kagent controller compiles the Harness and AgentTemplate pair into an ActorTemplate, and each AgentInstance is created from that ActorTemplate and runs on an Actor.
+The following diagram shows how a Harness and an AgentTemplate become a running conversation. The kagent controller compiles the Harness and AgentTemplate pair into an {{< gloss "ActorTemplate" >}}ActorTemplate{{< /gloss >}}, and each AgentInstance is created from that ActorTemplate and runs on an Actor.
+
```mermaid
flowchart LR
@@ -91,7 +92,7 @@ For the AgentInstance gRPC service definition, see the [API reference]({{< link
An **Actor** is the sandboxed unit of compute, provided by [Agent Substrate]({{< link path="about/agent-substrate" >}}), that _runs an AgentInstance's conversation loop_. Every AgentInstance is backed by an Actor.
-Actors are the reason why AgentInstances can suspend and resume cheaply instead of staying resident. An idle Actor can be snapshotted and torn down, then resumed from that snapshot on demand. To understand the full mechanics (Workers, WorkerPools, ActorTemplates, and snapshotting), see [Agent Substrate architecture]({{< link path="about/agent-substrate" >}}).
+Actors are the reason why AgentInstances can suspend and resume cheaply instead of staying resident. An idle Actor can be snapshotted and torn down, then resumed from that snapshot on demand. To understand the full mechanics ({{< gloss "Worker" >}}Workers{{< /gloss >}}, {{< gloss "WorkerPool" >}}WorkerPools{{< /gloss >}}, ActorTemplates, and snapshotting), see [Agent Substrate architecture]({{< link path="about/agent-substrate" >}}).
## Agent tools: Shared vs. Dedicated
diff --git a/docs-site/content/kagent/1.x/skills-and-mcp/skills.md b/docs-site/content/kagent/1.x/skills-and-mcp/skills.md
index f5b0f9b9..1131e0f4 100644
--- a/docs-site/content/kagent/1.x/skills-and-mcp/skills.md
+++ b/docs-site/content/kagent/1.x/skills-and-mcp/skills.md
@@ -5,9 +5,9 @@ weight: 20
author: kagent.dev
---
-A **skill** packages a piece of know-how that an agent can pick up: a set of instructions, together with whatever scripts or reference files those instructions depend on. An AgentTemplate attaches skills by naming where each one comes from, and kagent fetches them and places them where the agent runtime can find them.
+A **skill** packages a piece of know-how that an agent can pick up: a set of instructions, together with whatever scripts or reference files those instructions depend on. An {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}} attaches skills by naming where each one comes from, and kagent fetches them and places them where the agent runtime can find them.
-## What a skill is
+## About
A skill is a directory whose root holds a `SKILL.md` file. That file carries front matter naming the skill and describing what it is for, followed by the instructions themselves.
diff --git a/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md b/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
index 6d4da3c8..307ea864 100644
--- a/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
+++ b/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
@@ -5,7 +5,8 @@ weight: 10
author: kagent.dev
---
-An agent is a program that decides at run time what to do next. It runs the commands that a model asks for, and it calls the tools it can access. [Agent Substrate]({{< link path="about/agent-substrate" >}}) runs each agent inside an **Actor**, its own unit of compute, and it does not run that Actor as an ordinary container process. Each Actor runs inside its own **sandbox**, on a Worker that hosts one Actor at a time. This page explains what selects a sandbox, what the sandbox separates, and how traffic reaches an Actor through it.
+An agent is a program that decides at run time what to do next. It runs the commands that a model asks for, and it calls the tools it can access. [Agent Substrate]({{< link path="about/agent-substrate" >}}) runs each agent inside an **Actor**, its own unit of compute, and it does not run that Actor as an ordinary container process. Each Actor runs inside its own **sandbox**, on a {{< gloss "Worker" >}}Worker{{< /gloss >}} that hosts one Actor at a time. This page explains what selects a sandbox, what the sandbox separates, and how traffic reaches an Actor through it.
+
```mermaid
flowchart LR
@@ -24,15 +25,15 @@ flowchart LR
## Sandbox classes
-A **sandbox class** is the sandbox runtime family that a Worker uses. Agent Substrate supports two.
+A **sandbox class** is the sandbox runtime family that a Worker uses. {{< gloss "Agent Substrate" >}}Agent Substrate{{< /gloss >}} supports two.
- **`gvisor`** (default): Runs the workload against a [gVisor](https://gvisor.dev) user-space kernel, which keeps the workload's system calls from reaching the host kernel.
- **`microvm`**: Runs the workload inside a lightweight virtual machine, which places a hypervisor boundary between the workload and the host.
-A WorkerPool selects its class through the `sandboxClass` field, which defaults to `gvisor`. The choice is not only a runtime preference. It also shapes the Worker pods that Agent Substrate creates for that pool, including the virtualization device mounts and node placement that a micro-VM needs.
+A {{< gloss "WorkerPool" >}}WorkerPool{{< /gloss >}} selects its class through the `sandboxClass` field, which defaults to `gvisor`. The choice is not only a runtime preference. It also shapes the Worker pods that Agent Substrate creates for that pool, including the virtualization device mounts and node placement that a micro-VM needs.
> [!NOTE]
-> kagent generates ActorTemplates that use the `gvisor` class. Keep a WorkerPool that backs kagent Harnesses on `gvisor`.
+> kagent generates {{< gloss "ActorTemplate" >}}ActorTemplates{{< /gloss >}} that use the `gvisor` class. Keep a WorkerPool that backs kagent Harnesses on `gvisor`.
## Sandbox configuration
@@ -80,7 +81,7 @@ The sandbox draws a boundary in three places.
## How traffic reaches a sandboxed Actor
-Every Actor is addressed by name, at `..actors.resources.substrate.ate.dev`. Reaching it involves several hops, and each one is what keeps a sandboxed Actor addressable without exposing the Worker that it happens to be running on.
+Every Actor is addressed by its {{< gloss "Atespace" >}}atespace{{< /gloss >}} and name, at `..actors.resources.substrate.ate.dev`. Reaching it involves several hops, and each one is what keeps a sandboxed Actor addressable without exposing the Worker that it happens to be running on.
1. Agent Substrate runs its own Domain Name System (DNS) service that answers queries for that address pattern with the address of the router, rather than any individual Worker.
2. The router reads the Actor name and atespace from the request, asks the Agent Substrate API to resume that Actor and report which Worker it is now assigned to, then selects that Worker as the destination.
@@ -88,7 +89,7 @@ Every Actor is addressed by name, at `..actors.resources.s
Because the router resolves the Worker assignment on every request, an Actor keeps a stable address across suspends, resumes, and moves between Workers.
-Traffic in the other direction leaves through a separate egress gateway rather than going straight out from the Worker. Routing Actor egress through one gateway is what gives Agent Substrate a single place to apply outbound controls.
+Traffic in the other direction leaves through a separate egress gateway rather than going straight out from the Worker. Routing Actor egress through one gateway provides a single place to apply outbound controls.
## Default network posture
diff --git a/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md b/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
index 2252bb5b..7b59dc34 100644
--- a/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
+++ b/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
@@ -5,11 +5,11 @@ weight: 20
author: kagent.dev
---
-An agent spends most of its life waiting. It waits on a person to reply, and it waits on a large language model (LLM) to answer. [Agent Substrate]({{< link path="about/agent-substrate" >}}) runs each agent inside an **Actor**, the unit that it suspends and resumes, and it treats that idle time as reclaimable: it suspends an idle Actor into a snapshot, frees the Worker that the Actor was running on, and restores the Actor when traffic arrives for it. This page explains what a snapshot captures, when kagent suspends an Actor, and what happens when a suspended Actor is addressed again.
+An agent spends most of its life waiting. It waits on a person to reply, and it waits on a large language model (LLM) to answer. [Agent Substrate]({{< link path="about/agent-substrate" >}}) runs each agent inside an **Actor**, the unit that it suspends and resumes, and it treats that idle time as reclaimable: it suspends an idle Actor into a snapshot, frees the {{< gloss "Worker" >}}Worker{{< /gloss >}} that the Actor was running on, and restores the Actor when traffic arrives for it. This page explains what a snapshot captures, when kagent suspends an Actor, and what happens when a suspended Actor is addressed again.
## Actor lifecycle operations
-Agent Substrate provides three lifecycle operations, and each one moves an Actor between states that you can observe on the Actor record.
+{{< gloss "Agent Substrate" >}}Agent Substrate{{< /gloss >}} provides three lifecycle operations, and each one moves an Actor between states that you can observe on the Actor record.
- **Suspend**: Writes the Actor's state to a durable snapshot in snapshot storage, then frees its Worker. A running Actor is checkpointed on its Worker. A paused Actor's node-local snapshot is uploaded instead.
- **Pause**: Takes a short-term checkpoint whose files stay on the node. Pausing pins the Actor to that node, because the following resume is prioritized onto the node that holds the snapshot files.
@@ -18,11 +18,11 @@ Agent Substrate provides three lifecycle operations, and each one moves an Actor
An Actor reports its position in that cycle through its state, which is one of `RESUMING`, `RUNNING`, `SUSPENDING`, `SUSPENDED`, `PAUSING`, `PAUSED`, `CRASHED`, or `DELETING`. Only a suspended Actor can be deleted.
> [!NOTE]
-> Resume restores an Actor onto whichever Worker in the pool is free, which is not necessarily the Worker that the Actor ran on before. Suspend and resume are what let a WorkerPool carry far more Actors than it has Workers at any one moment.
+> Resume restores an Actor onto whichever Worker in the pool is free, which is not necessarily the Worker that the Actor ran on before. Suspend and resume are what let a {{< gloss "WorkerPool" >}}WorkerPool{{< /gloss >}} carry far more Actors than it has Workers at any one moment.
## What a snapshot captures
-An ActorTemplate's snapshot configuration decides how much of an Actor a given snapshot holds. Two scopes exist.
+An {{< gloss "ActorTemplate" >}}ActorTemplate{{< /gloss >}}'s snapshot configuration decides how much of an Actor a given snapshot holds. Two scopes exist.
- **`Full`**: Captures process memory, the root filesystem changes layered on top of the container image, and any attached durable volumes. A `Full` snapshot holds everything that is needed to resume the Actor hot, with its in-memory state intact.
- **`Data`**: Captures only the contents of attached durable volumes. Process memory and the rest of the root filesystem are discarded, which makes the snapshot much cheaper to write and store.
@@ -37,10 +37,10 @@ When an Actor resumes from a `Data`-scope snapshot, the ActorTemplate's `onResum
Two kinds of snapshot serve different purposes, and both appear in a normal installation.
-- **Golden snapshot**: Captured once, when an ActorTemplate is created, from a temporary golden boot of the workload. Every Actor of that template is first restored from this one shared snapshot, so a new Actor starts from an already-booted image rather than a cold start. An AgentTemplate is not ready until its golden snapshot exists, which is why the kagent controller reports `waiting for the ActorTemplate golden snapshot` while Agent Substrate captures it.
+- **Golden snapshot**: Captured once, when an ActorTemplate is created, from a temporary golden boot of the workload. Every Actor of that template is first restored from this one shared snapshot, so a new Actor starts from an already-booted image rather than a cold start. An {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}} is not ready until its golden snapshot exists, which is why the kagent controller reports `waiting for the ActorTemplate golden snapshot` while Agent Substrate captures it.
- **Last snapshot**: The most recent per-Actor snapshot, written on every suspend and used to restore that specific Actor on its next resume. Because it carries the Actor's own accumulated state, the conversation continues from where it stopped.
-Snapshots are persisted to object storage, either Google Cloud Storage or Amazon Simple Storage Service (S3), so that Actor state is durable and portable across the cluster. A Harness names the location for its Actors' snapshots in its `substrate.snapshotPolicy` section.
+Snapshots are persisted to object storage, either Google Cloud Storage or Amazon Simple Storage Service (S3), so that Actor state is durable and portable across the cluster. A {{< gloss "Harness" >}}Harness{{< /gloss >}} names the location for its Actors' snapshots in its `substrate.snapshotPolicy` section.
## Suspension between turns
@@ -48,14 +48,14 @@ kagent does not wait for an Actor to go idle for a long stretch before suspendin
A turn reaches such a boundary when its task enters a terminal state, or when the task stops to wait on a person, which is the `INPUT_REQUIRED` and `AUTH_REQUIRED` case. At that point kagent suspends the Actor durably and records the exact snapshot that the suspend produced.
-The AgentInstance's own state does not change while this happens. It stays `READY` throughout, because suspension is a property of the runtime underneath it rather than of the conversation. A caller that lists AgentInstances sees a ready agent whether or not an Actor is currently running for it.
+The {{< gloss "AgentInstance" >}}AgentInstance{{< /gloss >}}'s own state does not change while this happens. It stays `READY` throughout, because suspension is a property of the runtime underneath it rather than of the conversation. A caller that lists AgentInstances sees a ready agent whether or not an Actor is currently running for it.
> [!NOTE]
> Creating an AgentInstance does not start an Actor running. The Actor is created suspended, and the first message addressed to the AgentInstance is what resumes it.
## Resuming on demand
-Every Actor is reachable at a uniform address, `..actors.resources.substrate.ate.dev`, resolved by Agent Substrate's own Domain Name System (DNS) server. Traffic sent to that name is routed to the right Worker, and an Actor that is currently suspended is resumed automatically to receive it. Nothing in the calling path needs to know whether the Actor was running beforehand.
+Every Actor is reachable at a uniform address built from its {{< gloss "Atespace" >}}atespace{{< /gloss >}} and name, `..actors.resources.substrate.ate.dev`, resolved by Agent Substrate's own Domain Name System (DNS) server. Traffic sent to that name is routed to the right Worker, and an Actor that is currently suspended is resumed automatically to receive it. Nothing in the calling path needs to know whether the Actor was running beforehand.
Resume speed is what makes suspending at every turn boundary practical rather than costly. Agent Substrate's own target for this cycle is 100 milliseconds at the ninety-fifth percentile, measured from the moment traffic arrives for a suspended Actor to the moment that Actor can receive it.
diff --git a/docs-site/data/glossary.yaml b/docs-site/data/glossary.yaml
new file mode 100644
index 00000000..a506afb1
--- /dev/null
+++ b/docs-site/data/glossary.yaml
@@ -0,0 +1,47 @@
+# Glossary terms for the {{< gloss >}} shortcode, which docs-theme-extras
+# provides along with the tooltip behavior (glossary.js) and styling
+# (glossary.css). Both load automatically through themeExtras/head-end.html.
+#
+# Usage is a PAIRED shortcode; the unclosed form is a build error:
+# {{< gloss "Atespace" >}}atespace{{< /gloss >}}
+# The key is the tooltip heading, so it is capitalized. The inner text is what
+# appears in the sentence, so it carries the prose's own casing and plurality.
+#
+# Gloss the FIRST instance of a term on a page only. Repeating it on every
+# occurrence adds underlines without adding information.
+#
+# A key that is missing here renders as plain text with no tooltip and no
+# warning, so check spelling against this file when a tooltip does not appear.
+#
+# Entries carry `short` only, matching agentgateway's glossary. The shortcode
+# also supports an optional `link` ("Learn more"), but it hardcodes
+# target="_blank", which suits an external reference rather than a link to
+# another page in this docset.
+
+Actor:
+ short: "The sandboxed unit of compute, provided by Agent Substrate, that runs an AgentInstance's conversation loop. Every AgentInstance is backed by one."
+
+Atespace:
+ short: "The isolation boundary that an Actor belongs to, and the first half of its identity. Global-scoped in Agent Substrate, not a Kubernetes namespace."
+
+Agent Substrate:
+ short: "The runtime that kagent runs agents on. It multiplexes many sandboxed Actors onto a smaller pool of pre-started Workers, suspending idle ones to snapshots."
+
+ActorTemplate:
+ short: "The compiled, immutable definition that the kagent controller produces from a Harness and AgentTemplate pair. Every Actor is created from one."
+
+AgentInstance:
+ short: "A running, conversational pairing of a Harness and an AgentTemplate. Unlike the two, it is not a Kubernetes resource: kagent's gRPC API creates it and its database tracks it."
+
+AgentTemplate:
+ short: "A Kubernetes custom resource defining what an agent does: its model, system prompt, tools, skills, and plugins. It runs only once a Harness accepts it."
+
+Harness:
+ short: "A Kubernetes custom resource defining how an agent is allowed to run: its runtime, workload image, WorkerPool and snapshot storage, and which AgentTemplates it accepts."
+
+Worker:
+ short: "A pre-started, sandboxed pod that hosts at most one Actor at a time. Actors are multiplexed across a pool of Workers over time."
+
+WorkerPool:
+ short: "A Kubernetes custom resource declaring how many Workers to keep running and which sandbox class they use. An operator must provision one before any Harness can create AgentInstances."
+
From b7619a41d017ac517330ac7d099349585676a29d Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Thu, 27 Aug 2026 16:42:47 -0500
Subject: [PATCH 27/70] Phase 2, review 4
Signed-off-by: Rachael Graham
---
.../snippets/snapshot-cycle-diagram.md | 9 +++++++
.../kagent/1.x/about/agent-substrate.md | 10 +------
.../substrate-runtime/suspend-and-resume.md | 26 ++++++++++++++++---
3 files changed, 32 insertions(+), 13 deletions(-)
create mode 100644 docs-site/assets/kagent-docs/snippets/snapshot-cycle-diagram.md
diff --git a/docs-site/assets/kagent-docs/snippets/snapshot-cycle-diagram.md b/docs-site/assets/kagent-docs/snippets/snapshot-cycle-diagram.md
new file mode 100644
index 00000000..b52db498
--- /dev/null
+++ b/docs-site/assets/kagent-docs/snippets/snapshot-cycle-diagram.md
@@ -0,0 +1,9 @@
+```mermaid
+flowchart LR
+ pool["WorkerPool"] --> worker1["Worker"]
+ worker1 -->|hosts| actor["Actor (running)"]
+ actor -->|suspend| snapshot["ActorSnapshot (immutable)"]
+ snapshot -->|resume| worker2["Any free Worker in the pool"]
+ snapshot -->|pinned by| tag["ActorSnapshotTag (retention pin)"]
+ tag -->|seeds| newactor["New Actor"]
+```
diff --git a/docs-site/content/kagent/1.x/about/agent-substrate.md b/docs-site/content/kagent/1.x/about/agent-substrate.md
index 74a9bbe3..d9c0f31c 100644
--- a/docs-site/content/kagent/1.x/about/agent-substrate.md
+++ b/docs-site/content/kagent/1.x/about/agent-substrate.md
@@ -38,15 +38,7 @@ Substrate's density model rests on one fact about agent workloads: an Actor spen
The following diagram traces an Actor through one suspend-and-resume cycle, and shows the second path that opens up once the resulting snapshot is tagged.
-```mermaid
-flowchart LR
- pool["WorkerPool"] --> worker1["Worker"]
- worker1 -->|hosts| actor["Actor (running)"]
- actor -->|suspend| snapshot["ActorSnapshot (immutable)"]
- snapshot -->|resume| worker2["Any free Worker in the pool"]
- snapshot -->|pinned by| tag["ActorSnapshotTag (retention pin)"]
- tag -->|seeds| newactor["New Actor"]
-```
+{{< reuse "kagent-docs/snippets/snapshot-cycle-diagram.md" >}}
A **WorkerPool** keeps **Workers** running and ready, and one Worker hosts the **Actor** while its conversation is active. Suspending that Actor writes its full state to an immutable **ActorSnapshot** and frees the Worker that it was running on.
diff --git a/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md b/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
index 7b59dc34..ed0c3455 100644
--- a/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
+++ b/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
@@ -15,6 +15,11 @@ An agent spends most of its life waiting. It waits on a person to reply, and it
- **Pause**: Takes a short-term checkpoint whose files stay on the node. Pausing pins the Actor to that node, because the following resume is prioritized onto the node that holds the snapshot files.
- **Resume**: Restores a suspended or paused Actor onto a Worker, from its latest snapshot. The common path restores from a snapshot rather than cold-booting the workload.
+The following diagram traces an Actor through those operations, and shows the further path that opens once a snapshot is [pinned by a tag](#checkpoints).
+
+
+{{< reuse "kagent-docs/snippets/snapshot-cycle-diagram.md" >}}
+
An Actor reports its position in that cycle through its state, which is one of `RESUMING`, `RUNNING`, `SUSPENDING`, `SUSPENDED`, `PAUSING`, `PAUSED`, `CRASHED`, or `DELETING`. Only a suspended Actor can be deleted.
> [!NOTE]
@@ -29,10 +34,13 @@ An {{< gloss "ActorTemplate" >}}ActorTemplate{{< /gloss >}}'s snapshot configura
Scopes describe only what a snapshot captures, and they are configured per trigger. The `onPause` setting selects what a pause captures on the node, and `onCommit` selects what a suspend uploads to snapshot storage. What `onCommit` captures must be a subset of what `onPause` captures.
-A **DurableDir volume** is the per-Actor application data surface. Its contents are preserved by the `Data` scope, so they survive a suspend and resume cycle independently of process memory. How many such volumes an ActorTemplate can declare depends on its sandbox class. A `microvm` template can declare several, because they are subdirectories of a single shared filesystem. A `gvisor` template is limited to one, until gVisor accepts more than a single durable mount.
+A **DurableDir volume** is the per-Actor application data surface. Its contents are preserved by the `Data` scope, so they survive a suspend and resume cycle independently of process memory. How many volumes an ActorTemplate can declare depends on its sandbox class. A `microvm` template can declare several, because they are subdirectories of a single shared filesystem. A `gvisor` template is limited to one, until gVisor accepts more than a single durable mount.
When an Actor resumes from a `Data`-scope snapshot, the ActorTemplate's `onResume.fromData` setting decides where the rest of the guest state comes from. The default is `ColdBoot`, which starts the containers fresh from the container image with the durable volume contents restored over them.
+> [!NOTE]
+> These scopes describe what Agent Substrate supports, not choices that you make. kagent compiles every ActorTemplate with the same snapshot configuration: `Full` on pause, `Data` on commit, `ColdBoot` on resume, and a single DurableDir volume named `data`. The only snapshot setting that you author is the storage location, on the Harness.
+
## Golden and per-Actor snapshots
Two kinds of snapshot serve different purposes, and both appear in a normal installation.
@@ -42,6 +50,16 @@ Two kinds of snapshot serve different purposes, and both appear in a normal inst
Snapshots are persisted to object storage, either Google Cloud Storage or Amazon Simple Storage Service (S3), so that Actor state is durable and portable across the cluster. A {{< gloss "Harness" >}}Harness{{< /gloss >}} names the location for its Actors' snapshots in its `substrate.snapshotPolicy` section.
+```yaml
+spec:
+ substrate:
+ workerPoolRef:
+ name: kagent-default
+ snapshotPolicy:
+ # The object storage location your cluster's Substrate installation uses
+ location: gs:///kagent/
+```
+
## Suspension between turns
kagent does not wait for an Actor to go idle for a long stretch before suspending it. It suspends the Actor at every turn boundary, as soon as the conversation reaches a point where nothing is running.
@@ -51,7 +69,7 @@ A turn reaches such a boundary when its task enters a terminal state, or when th
The {{< gloss "AgentInstance" >}}AgentInstance{{< /gloss >}}'s own state does not change while this happens. It stays `READY` throughout, because suspension is a property of the runtime underneath it rather than of the conversation. A caller that lists AgentInstances sees a ready agent whether or not an Actor is currently running for it.
> [!NOTE]
-> Creating an AgentInstance does not start an Actor running. The Actor is created suspended, and the first message addressed to the AgentInstance is what resumes it.
+> Creating an AgentInstance does not start an Actor running. The Actor is created as suspended, and the first message addressed to the AgentInstance resumes it.
## Resuming on demand
@@ -63,9 +81,9 @@ Resume speed is what makes suspending at every turn boundary practical rather th
A snapshot that Agent Substrate writes on suspend is transient. Agent Substrate is free to collect it once a newer snapshot supersedes it. A **checkpoint** makes one of those snapshots durable by pinning it.
-Creating a checkpoint attaches an ActorSnapshotTag to the snapshot that the AgentInstance most recently suspended to. The tag names that one snapshot permanently, and it acts as a retention pin, so Agent Substrate does not collect a snapshot while a tag still names it. Deleting the checkpoint removes the tag and releases the pin.
+Creating a checkpoint attaches an ActorSnapshotTag to the snapshot that the AgentInstance most recently suspended to. The tag names that one snapshot permanently and acts as a retention pin, such that Agent Substrate does not collect a snapshot while a tag still names it. Deleting the checkpoint removes the tag and releases the pin.
-Because a checkpoint captures a turn boundary, an AgentInstance must be at one to be checkpointed. An AgentInstance with a turn still in progress has no quiescent boundary to capture, and the request fails until the turn finishes.
+An AgentInstance must be a turn boundary to be checkpointed, because the turn boundary is captured. An AgentInstance with a turn still in progress has no quiescent boundary to capture, and the request fails until the turn finishes.
## Next steps
From 6e7d3b702798862babb0126ed33b7294e2848ec0 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Fri, 28 Aug 2026 11:57:22 -0500
Subject: [PATCH 28/70] Phase 2, review 5
Signed-off-by: Rachael Graham
---
.../kagent-docs/snippets/artifact-sources.md | 9 +++
.../kagent/1.x/about/agent-substrate.md | 7 ---
.../content/kagent/1.x/about/architecture.md | 7 ---
.../content/kagent/1.x/about/core-concepts.md | 8 ---
.../content/kagent/1.x/setup/installation.md | 13 +++--
.../kagent/1.x/skills-and-mcp/plugins.md | 57 +++++++++++++++++++
.../kagent/1.x/skills-and-mcp/skills.md | 20 +------
.../1.x/substrate-runtime/sandboxing.md | 7 ---
.../substrate-runtime/suspend-and-resume.md | 7 ---
9 files changed, 75 insertions(+), 60 deletions(-)
create mode 100644 docs-site/assets/kagent-docs/snippets/artifact-sources.md
create mode 100644 docs-site/content/kagent/1.x/skills-and-mcp/plugins.md
diff --git a/docs-site/assets/kagent-docs/snippets/artifact-sources.md b/docs-site/assets/kagent-docs/snippets/artifact-sources.md
new file mode 100644
index 00000000..4f4643ab
--- /dev/null
+++ b/docs-site/assets/kagent-docs/snippets/artifact-sources.md
@@ -0,0 +1,9 @@
+## Every source is immutable
+
+A skill or a plugin package changes what an agent does, so kagent only accepts artifact references that cannot shift underneath a running agent. Each source names exactly one of three kinds of artifact, and every kind must be pinned in its own way.
+
+- **`oci`**: An image reference pinned to a digest, in the form `@sha256:`. A tag alone is rejected, because a tag can be moved to different content later.
+- **`git`**: A repository URL together with a full commit identifier. An abbreviated commit, a branch, or a tag is rejected.
+- **`bucket.s3`**: An endpoint, bucket, and key, together with the `versionId` of that exact object version. A region is included where the service requires one for request signing.
+
+Pinning has a practical consequence worth planning for. Publishing a new version means updating the AgentTemplate to name the new digest, commit, or object version, which compiles a new revision. Agents that are already running keep the content that they started with.
diff --git a/docs-site/content/kagent/1.x/about/agent-substrate.md b/docs-site/content/kagent/1.x/about/agent-substrate.md
index d9c0f31c..4844c0a2 100644
--- a/docs-site/content/kagent/1.x/about/agent-substrate.md
+++ b/docs-site/content/kagent/1.x/about/agent-substrate.md
@@ -52,10 +52,3 @@ A tag gives a snapshot a stable, human-meaningful name, so callers do not need t
For example, an agent partway through a long incident investigation reaches a state worth keeping. Creating a [checkpoint]({{< link path="substrate-runtime/suspend-and-resume#checkpoints" >}}) tags the snapshot that the agent most recently suspended to, which holds that one snapshot in place while the agent carries on and writes newer ones. Without the tag, Substrate collects that snapshot once a newer one supersedes it.
Substrate's own target for this cycle is 100 milliseconds at the ninety-fifth percentile, measured from the moment traffic arrives for a suspended Actor to the moment that Actor can receive it.
-
-## Next steps
-
-{{< cards >}}
- {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Apply a Harness and AgentTemplate, and talk to the AgentInstance they produce." >}}
- {{< card link=`{{< link path="operations/substrate-operations" >}}` title="Substrate operations" subtitle="Size a WorkerPool and choose a sandbox class for your cluster." >}}
-{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/about/architecture.md b/docs-site/content/kagent/1.x/about/architecture.md
index 508614ba..59230b3a 100644
--- a/docs-site/content/kagent/1.x/about/architecture.md
+++ b/docs-site/content/kagent/1.x/about/architecture.md
@@ -67,10 +67,3 @@ From there, the caller holds a conversation with the AgentInstance over the A2A
Kubernetes RBAC is designed to authorize configuration changes: who can create a Deployment, edit a ConfigMap, or in this case, apply a Harness or AgentTemplate. It is not designed to authorize a running conversation, share access to it with another user, or scope who can suspend it. kagent's gRPC plane exists to authorize exactly those actions, at the granularity of a single AgentInstance rather than a namespace or a resource kind.
This split also keeps the two lifecycles independent. Editing a Harness or AgentTemplate does not affect AgentInstances already running against the ActorTemplate that they were created from. It only affects new AgentInstances, created after the edit is compiled.
-
-## Next steps
-
-{{< cards >}}
- {{< card link=`{{< link path="about/agent-substrate" >}}` title="Agent Substrate architecture" subtitle="See what an Actor actually runs on, and how it suspends and resumes." >}}
- {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Apply a Harness and AgentTemplate, and talk to the AgentInstance they produce." >}}
-{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/about/core-concepts.md b/docs-site/content/kagent/1.x/about/core-concepts.md
index d0e064cf..f3d5770c 100644
--- a/docs-site/content/kagent/1.x/about/core-concepts.md
+++ b/docs-site/content/kagent/1.x/about/core-concepts.md
@@ -104,11 +104,3 @@ An AgentTemplate's tools are not limited to MCP servers. A tool binding can also
Shared nesting never goes more than one level deep. A Shared agent tool can have Dedicated agent tools beneath it, but it cannot contain another Shared one.
This limit keeps the model predictable. A Dedicated binding gives the child its own Actor. A Shared binding puts the child in its parent's Actor, and because Shared bindings cannot chain, that parent always has an Actor of its own. Working out where any agent runs is therefore never more than a single step.
-
-## Next steps
-
-{{< cards >}}
- {{< card link=`{{< link path="about/architecture" >}}` title="kagent architecture" subtitle="See how these pieces fit together end to end, from `kubectl apply` to a live conversation." >}}
- {{< card link=`{{< link path="about/agent-substrate" >}}` title="Agent Substrate architecture" subtitle="Learn about Workers, WorkerPools, and ActorTemplates, and how Actors suspend and resume." >}}
- {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Apply a Harness and AgentTemplate, and talk to the AgentInstance they produce." >}}
-{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/setup/installation.md b/docs-site/content/kagent/1.x/setup/installation.md
index cb46d323..54fe2ee5 100644
--- a/docs-site/content/kagent/1.x/setup/installation.md
+++ b/docs-site/content/kagent/1.x/setup/installation.md
@@ -243,10 +243,11 @@ The kagent chart connects the controller to Agent Substrate and creates a Worker
```
Example output:
```console
- NAME READY STATUS RESTARTS AGE
- kagent-controller-659b58768b-2k6h4 1/1 Running 3 2m
- kagent-default-864fdc4c94-xbsl9 1/1 Running 0 2m
- kagent-postgresql-65cc684b78-9qbh2 1/1 Running 0 2m
+ NAME READY STATUS RESTARTS AGE
+ kagent-controller-659b58768b-2k6h4 1/1 Running 3 2m
+ kagent-default-864fdc4c94-xbsl9 1/1 Running 0 2m
+ kagent-kmcp-controller-manager-6676b45958-knkzd 1/1 Running 0 2m
+ kagent-postgresql-65cc684b78-9qbh2 1/1 Running 0 2m
```
2. Confirm that the WorkerPool reports a ready replica.
@@ -255,8 +256,8 @@ The kagent chart connects the controller to Agent Substrate and creates a Worker
```
Example output:
```console
- NAMESPACE NAME DESIRED REPLICAS READY AGE
- kagent kagent-default 1 1 1 2m
+ NAME DESIRED REPLICAS READY AGE
+ kagent-default 1 1 1 2m
```
3. Get the address to reach the kagent gRPC API, which serves the AgentInstance lifecycle and conversation calls. The guide to [create your first agent]({{< link path="get-started/your-first-agent" >}}) assumes port-forwarding.
diff --git a/docs-site/content/kagent/1.x/skills-and-mcp/plugins.md b/docs-site/content/kagent/1.x/skills-and-mcp/plugins.md
new file mode 100644
index 00000000..523ac2aa
--- /dev/null
+++ b/docs-site/content/kagent/1.x/skills-and-mcp/plugins.md
@@ -0,0 +1,57 @@
+---
+title: Plugins
+description: Understand what a plugin package holds, and what kagent does with one when an agent starts.
+weight: 30
+author: kagent.dev
+---
+
+A **plugin package** is a bundle that an AgentTemplate attaches with `spec.plugins`. The package carries skills and can also declare Model Context Protocol (MCP) servers. Packages follow the [Agent Plugins](https://agent-plugins.org) 1.0.0 format, which kagent consumes rather than defines.This page covers what a package holds and how kagent handles it. To understand how to attach a plugin package with an AgentTemplate, see [Skills]({{< link path="skills-and-mcp/skills" >}}).
+
+## What a package holds
+
+A package root can hold up to three things.
+
+* `plugin.json` (required): The manifest that names the package.
+* `skills/`: One subdirectory per skill, each holding a `SKILL.md` file at its root.
+* `mcp.json`: Declares MCP servers that kagent adds to the agent's tools.
+
+kagent reads `name` from the manifest and ignores the rest, so a package that carries `version`, `description`, `author`, `homepage`, `repository`, `license`, `keywords`, or `extensions` is accepted, but none of those fields change what the agent gets. The manifest's `$schema` must be exactly `https://agent-plugins.org/schemas/1.0.0/plugin.schema.json`.
+
+> [!NOTE]
+> kagent compares that `$schema` value literally. It does not fetch the schema or validate the document against it, so a manifest that names the right schema and holds the wrong shape is rejected by the decoder rather than by schema validation.
+
+## MCP servers
+
+A package that includes `mcp.json` contributes MCP servers to every agent that enables it. The file declares an `mcpServers` object, keyed by server name, and its `$schema` must be exactly `https://agent-plugins.org/schemas/1.0.0/mcp.schema.json`.
+
+Each server names a transport in its `type` field, and the transport determines which other fields are allowed.
+
+| Transport | Fields | Description |
+| --------- | ------ | ----------- |
+| `stdio` | `command`, `args`, `env`, `cwd` | Runs a process inside the agent's sandbox. Specifying `url` or `headers` is rejected. |
+| `streamable-http` | `url`, `headers` | Calls a remote server. Specifying `command`, `args`, `env`, or `cwd` is rejected. |
+| `sse` | `url`, `headers` | As `streamable-http`, over Server-Sent Events. |
+
+kagent enforces several rules on these servers, and each one exists to keep a package from reaching outside itself.
+
+- A `stdio` command must be either a bare name resolved on the sandbox's path, or a package-relative path beginning with `./`. A command holding a path separator any other way or containing whitespace is rejected.
+- A `cwd` must be package-relative or written with the `${PLUGIN_ROOT}` or `${PLUGIN_DATA}` [variables](#referring-to-package-files), and it is rejected if it resolves outside the package.
+- A remote `url` must be `http` or `https`, and must not carry user information or fragments. Any host other than a loopback address must use HTTPS.
+- Unrecognized fields are rejected rather than ignored.
+
+An invalid server is skipped with a log entry, and the rest of the file still loads. An `mcp.json` that is invalid or that names an unexpected schema is ignored in full.
+
+### Referring to package files
+
+A `stdio` server often needs to run something that the package ships, or to write somewhere durable. Two variables are expanded in `args`, `env` values, and `cwd`.
+
+* `${PLUGIN_ROOT}`: The directory the package was unpacked into. Read-only in practice, and shared by every Actor of the template.
+* `${PLUGIN_DATA}`: A per-package data directory that kagent creates. Use it for anything the server writes.
+
+kagent also sets both as environment variables on every `stdio` server, so a server can read them without the package declaring them. A package cannot override either one: an `env` block that sets `PLUGIN_ROOT` or `PLUGIN_DATA` is rejected.
+
+## Package limits
+
+kagent measures a package after fetching it and before mounting anything. A package is rejected if it holds more than 10,000 filesystem entries or more than 100 MB of regular files. A `.git` directory is skipped and counts toward neither.
+
+{{< reuse "kagent-docs/snippets/artifact-sources.md" >}}
diff --git a/docs-site/content/kagent/1.x/skills-and-mcp/skills.md b/docs-site/content/kagent/1.x/skills-and-mcp/skills.md
index 1131e0f4..7bee3a54 100644
--- a/docs-site/content/kagent/1.x/skills-and-mcp/skills.md
+++ b/docs-site/content/kagent/1.x/skills-and-mcp/skills.md
@@ -13,7 +13,7 @@ A skill is a directory whose root holds a `SKILL.md` file. That file carries fro
The description is what makes a skill usable. When an agent starts, the runtime reads the front matter of every skill that is attached to it, and offers those skills to the model as tools that it can call. The model chooses a skill from its description, in the same way that it chooses any other tool. This means that a description that states plainly when to use the skill matters more than the length of the instructions behind it.
-A skill can be published on its own, or bundled with other skills in a **plugin package**. A plugin package follows the Agent Plugins 1.0.0 format. Its `plugin.json` manifest names the package, and its skills live in a `skills` directory, one subdirectory per skill. A package may also declare Model Context Protocol (MCP) servers, which kagent adds to the agent's tools alongside the skills that you enable from that package.
+A skill can be published on its own, or bundled with other skills in a [plugin package]({{< link path="skills-and-mcp/plugins" >}}), which can also declare Model Context Protocol (MCP) servers that kagent adds to the agent's tools.
## Attach skills to an AgentTemplate
@@ -59,15 +59,7 @@ Attaching a plugin package does not enable any of the skills that it carries. On
> [!IMPORTANT]
> An empty skills list enables nothing. Adding a plugin package and omitting its `skills` list gives the agent no skills from that package, which is the safe default rather than an error. Listing skills explicitly also means that a package gaining new skills in a later version does not silently grant them to your agent.
-## Every source is immutable
-
-A skill changes what an agent does, so kagent only accepts artifact references that cannot shift underneath a running agent. Each source names exactly one of three kinds of artifact, and each one has to be pinned.
-
-- **`oci`**: An image reference pinned to a digest, in the form `@sha256:`. A tag alone is rejected, because a tag can be moved to different content later.
-- **`git`**: A repository URL together with a full commit identifier. An abbreviated commit, a branch, or a tag is rejected.
-- **`bucket.s3`**: An endpoint, bucket, and key, together with the `versionId` of that exact object version. A region is included where the service requires one for request signing.
-
-Pinning has a practical consequence worth planning for. Publishing a new version of a skill means updating the AgentTemplate to name the new digest, commit, or object version, which compiles a new revision. Agents that are already running keep using the skill content that they started with.
+{{< reuse "kagent-docs/snippets/artifact-sources.md" >}}
## Naming rules
@@ -77,11 +69,3 @@ Skill names are checked before anything is fetched, and two rules apply across e
- Names must be unique across the whole AgentTemplate. Because standalone skills and plugin skills are mounted into the same place, a standalone skill cannot reuse the name of an enabled plugin skill, and two plugin packages cannot both contribute the same name.
Plugin package names must also be unique. Two entries in `plugins` whose manifests declare the same name are rejected. Unlike skill names, kagent checks this as each package is fetched, because the name comes from the package's `plugin.json` manifest rather than from your AgentTemplate.
-
-## Next steps
-
-{{< cards >}}
- {{< card link=`{{< link path="examples/skills" >}}` title="Add skills to agents" subtitle="Walk through attaching a skill from an OCI artifact, end to end." >}}
- {{< card link=`{{< link path="skills-and-mcp/about-tools" >}}` title="About tools" subtitle="See how MCP tools and agent tools attach to an AgentTemplate." >}}
- {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Apply a Harness and AgentTemplate, and talk to the AgentInstance they produce." >}}
-{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md b/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
index 307ea864..7a607d50 100644
--- a/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
+++ b/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
@@ -96,10 +96,3 @@ Traffic in the other direction leaves through a separate egress gateway rather t
Agent Substrate creates a Kubernetes NetworkPolicy for each WorkerPool, selecting that pool's Worker pods. The policy restricts **ingress** to the Agent Substrate router alone. No other pod in the cluster can open a connection to a Worker, so an Actor is not reachable by anything that bypasses the routing path.
That policy governs inbound traffic only. It does not constrain what an Actor may reach outbound, so outbound access is whatever the surrounding cluster and its infrastructure already allow. Treat network egress as something to configure deliberately for your environment rather than as something the WorkerPool policy settles.
-
-## Next steps
-
-{{< cards >}}
- {{< card link=`{{< link path="substrate-runtime/suspend-and-resume" >}}` title="Suspend and resume" subtitle="See what a snapshot captures and how an idle Actor comes back." >}}
- {{< card link=`{{< link path="about/agent-substrate" >}}` title="Agent Substrate architecture" subtitle="Review how Workers, Actors, and ActorTemplates fit together." >}}
-{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md b/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
index ed0c3455..2a7054b1 100644
--- a/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
+++ b/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
@@ -84,10 +84,3 @@ A snapshot that Agent Substrate writes on suspend is transient. Agent Substrate
Creating a checkpoint attaches an ActorSnapshotTag to the snapshot that the AgentInstance most recently suspended to. The tag names that one snapshot permanently and acts as a retention pin, such that Agent Substrate does not collect a snapshot while a tag still names it. Deleting the checkpoint removes the tag and releases the pin.
An AgentInstance must be a turn boundary to be checkpointed, because the turn boundary is captured. An AgentInstance with a turn still in progress has no quiescent boundary to capture, and the request fails until the turn finishes.
-
-## Next steps
-
-{{< cards >}}
- {{< card link=`{{< link path="substrate-runtime/sandboxing" >}}` title="Sandboxing" subtitle="See how a sandbox isolates each Actor's process, filesystem, and network." >}}
- {{< card link=`{{< link path="about/agent-substrate" >}}` title="Agent Substrate architecture" subtitle="Review how Workers, Actors, and ActorTemplates fit together." >}}
-{{< /cards >}}
From 19a4fd244ae55eff1ab79e3435ad7db36ed9f8ea Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Fri, 28 Aug 2026 12:38:38 -0500
Subject: [PATCH 29/70] Phase 2, review 6
Signed-off-by: Rachael Graham
---
.../1.x/get-started/your-first-agent.md | 41 ++++++++--
.../kagent/1.x/skills-and-mcp/about-tools.md | 75 +++++++++++++++++++
.../kagent/1.x/skills-and-mcp/plugins.md | 14 ++--
.../kagent/1.x/skills-and-mcp/skills.md | 8 +-
.../1.x/substrate-runtime/sandboxing.md | 2 +-
5 files changed, 120 insertions(+), 20 deletions(-)
create mode 100644 docs-site/content/kagent/1.x/skills-and-mcp/about-tools.md
diff --git a/docs-site/content/kagent/1.x/get-started/your-first-agent.md b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
index bbb36135..5eb909b8 100644
--- a/docs-site/content/kagent/1.x/get-started/your-first-agent.md
+++ b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
@@ -71,22 +71,47 @@ This guide walks you through creating an agent, from applying a Harness and an A
kubectl get agenttemplate my-first-agent -n kagent -o jsonpath='{.status.harnesses}' | jq .
```
- A ready pair reports a `Ready` condition for `my-first-harness`. If the status is empty, wait a few seconds for the kagent controller to reconcile, then check again.
+ A ready pair reports four conditions for `my-first-harness`, ending in `Ready`. If the status is empty, wait a few seconds for the kagent controller to reconcile, then check again.
```json
[
{
- "harness": "my-first-harness",
- "desiredRevision": "5f2b3c1a9e8d4b7a6c3e2f1d0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b",
- "latestSuccessfulRevision": "5f2b3c1a9e8d4b7a6c3e2f1d0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b",
"conditions": [
{
- "type": "Ready",
+ "lastTransitionTime": "2026-08-24T15:02:10Z",
+ "message": "Harness admission selector matches the AgentTemplate",
+ "observedGeneration": 1,
+ "reason": "Accepted",
+ "status": "True",
+ "type": "Accepted"
+ },
+ {
+ "lastTransitionTime": "2026-08-24T15:02:10Z",
+ "message": "All runtime references resolved",
+ "observedGeneration": 1,
+ "reason": "Resolved",
+ "status": "True",
+ "type": "ResolvedRefs"
+ },
+ {
+ "lastTransitionTime": "2026-08-24T15:02:10Z",
+ "message": "Resolved configuration is compatible with the Harness",
+ "observedGeneration": 1,
+ "reason": "Compatible",
"status": "True",
+ "type": "Compatible"
+ },
+ {
+ "lastTransitionTime": "2026-08-24T15:02:10Z",
+ "message": "ActorTemplate golden snapshot is ready",
+ "observedGeneration": 1,
"reason": "Ready",
- "message": "ActorTemplate is ready",
- "lastTransitionTime": "2026-08-24T15:02:10Z"
+ "status": "True",
+ "type": "Ready"
}
- ]
+ ],
+ "desiredRevision": "5f2b3c1a9e8d4b7a6c3e2f1d0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b",
+ "harness": "my-first-harness",
+ "latestSuccessfulRevision": "5f2b3c1a9e8d4b7a6c3e2f1d0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b"
}
]
```
diff --git a/docs-site/content/kagent/1.x/skills-and-mcp/about-tools.md b/docs-site/content/kagent/1.x/skills-and-mcp/about-tools.md
new file mode 100644
index 00000000..9441fee6
--- /dev/null
+++ b/docs-site/content/kagent/1.x/skills-and-mcp/about-tools.md
@@ -0,0 +1,75 @@
+---
+title: About tools
+description: Give an agent tools by binding Model Context Protocol servers or other agents to an AgentTemplate.
+weight: 10
+author: kagent.dev
+---
+
+An {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}}'s `spec.tools` list defines what an agent can do beyond its system prompt. Each entry is a **tool binding**, and every binding selects exactly one source: a Model Context Protocol (MCP) server, or another AgentTemplate used as a tool. A binding that names both, or neither, is rejected.
+
+- `mcp`: Binds tools from an MCP server.
+- `agent`: Binds another AgentTemplate, so that the agent can hand work to it.
+
+Both kinds resolve within the AgentTemplate's own namespace, so a binding cannot reach a server or a template in another namespace.
+
+## MCP tools
+
+An `mcp` binding names a server and the tools to take from it. Naming the tools is required. A binding takes between 1 and 50 named tools, never the server's whole catalog.
+
+```yaml
+tools:
+ - mcp:
+ server:
+ kind: RemoteMCPServer
+ name: my-mcp-server
+ tools:
+ - search_docs
+ - fetch_page
+```
+
+| Field | Description |
+| ----- | ----------- |
+| `mcp.server.kind` | The kind of server resource. `RemoteMCPServer` is the only accepted value. |
+| `mcp.server.name` | The server's name, in the AgentTemplate's namespace. |
+| `mcp.tools` | The names of the tools to bind, between 1 and 50. Duplicates in the list are collapsed. |
+
+## Agents as tools
+
+An `agent` binding points at another AgentTemplate, which lets one agent route work to another. The model reads the `description` when it decides whether to route work here, so a description that states plainly what the bound agent is for matters more than the detail of its configuration.
+
+```yaml
+tools:
+ - agent:
+ name: log-searcher
+ description: Search application logs for a time range and a query string.
+ templateRef:
+ name: log-search-agent
+ isolation: Shared
+```
+
+| Field | Description |
+| ----- | ----------- |
+| `agent.name` | The name that the model sees for this binding. |
+| `agent.description` | The text that tells the parent agent when to route work here. |
+| `agent.templateRef.name` | The AgentTemplate to bind, in the same namespace. |
+| `agent.isolation` | The [isolation mode](#shared-and-dedicated-isolation) for the bound agent. Currently, `Shared` is the only supported value. |
+
+### Shared and Dedicated isolation
+
+The isolation setting determines whether a bound agent runs inside its parent's runtime boundary, or runs within a boundary of its own.
+
+- **`Shared`**: The bound agent runs inside the parent's {{< gloss "Actor" >}}Actor{{< /gloss >}}. Nesting costs no extra compute, and the two agents share one sandbox.
+- **`Dedicated`**: The bound agent would run in its own Actor, with its own sandbox and its own suspend and resume cycle.
+
+> [!WARNING]
+> `Dedicated` is not currently implemented. The AgentTemplate schema accepts the value, but compiling a binding that uses it fails with `Dedicated AgentTemplate tools are not supported yet`, and the pair does not become ready. Use `Shared`, which is the default.
+
+### What a Shared tree allows
+
+A `Shared` binding nests one agent inside another's runtime, so kagent constrains the shape of the resulting tree. The compiler enforces each of the following rules, and a violation surfaces as a failed revision rather than a failure at run time.
+
+- **One level of nesting.** A bound agent cannot itself bind another agent. A second consecutive binding is rejected as exceeding the kagent runtime boundary.
+- **No cycles.** An AgentTemplate cannot reach itself through a chain of bindings.
+- **No reuse within one tree.** The same AgentTemplate cannot appear twice in the same tree.
+- **Unique binding names.** Two bindings on one AgentTemplate cannot share a `name`.
+- **The bound template must be admitted too.** A nested AgentTemplate has to match the same {{< gloss "Harness" >}}Harness{{< /gloss >}}'s `allowedAgentTemplates` selector. Binding a template that the Harness does not admit is rejected.
diff --git a/docs-site/content/kagent/1.x/skills-and-mcp/plugins.md b/docs-site/content/kagent/1.x/skills-and-mcp/plugins.md
index 523ac2aa..4f34fb79 100644
--- a/docs-site/content/kagent/1.x/skills-and-mcp/plugins.md
+++ b/docs-site/content/kagent/1.x/skills-and-mcp/plugins.md
@@ -11,9 +11,9 @@ A **plugin package** is a bundle that an AgentTemplate attaches with `spec.plugi
A package root can hold up to three things.
-* `plugin.json` (required): The manifest that names the package.
-* `skills/`: One subdirectory per skill, each holding a `SKILL.md` file at its root.
-* `mcp.json`: Declares MCP servers that kagent adds to the agent's tools.
+- `plugin.json` (required): The manifest that names the package.
+- `skills/`: One subdirectory per skill, each holding a `SKILL.md` file at its root.
+- `mcp.json`: Declares MCP servers that kagent adds to the agent's tools.
kagent reads `name` from the manifest and ignores the rest, so a package that carries `version`, `description`, `author`, `homepage`, `repository`, `license`, `keywords`, or `extensions` is accepted, but none of those fields change what the agent gets. The manifest's `$schema` must be exactly `https://agent-plugins.org/schemas/1.0.0/plugin.schema.json`.
@@ -22,7 +22,7 @@ kagent reads `name` from the manifest and ignores the rest, so a package that ca
## MCP servers
-A package that includes `mcp.json` contributes MCP servers to every agent that enables it. The file declares an `mcpServers` object, keyed by server name, and its `$schema` must be exactly `https://agent-plugins.org/schemas/1.0.0/mcp.schema.json`.
+A package that includes `mcp.json` contributes MCP servers to every agent that enables it, alongside any bound directly on the AgentTemplate (see [About tools]({{< link path="skills-and-mcp/about-tools" >}})). The file declares an `mcpServers` object, keyed by server name, and its `$schema` must be exactly `https://agent-plugins.org/schemas/1.0.0/mcp.schema.json`.
Each server names a transport in its `type` field, and the transport determines which other fields are allowed.
@@ -30,7 +30,7 @@ Each server names a transport in its `type` field, and the transport determines
| --------- | ------ | ----------- |
| `stdio` | `command`, `args`, `env`, `cwd` | Runs a process inside the agent's sandbox. Specifying `url` or `headers` is rejected. |
| `streamable-http` | `url`, `headers` | Calls a remote server. Specifying `command`, `args`, `env`, or `cwd` is rejected. |
-| `sse` | `url`, `headers` | As `streamable-http`, over Server-Sent Events. |
+| `sse` | `url`, `headers` | Calls a remote server over Server-Sent Events. Accepts the same fields as `streamable-http`. |
kagent enforces several rules on these servers, and each one exists to keep a package from reaching outside itself.
@@ -45,8 +45,8 @@ An invalid server is skipped with a log entry, and the rest of the file still lo
A `stdio` server often needs to run something that the package ships, or to write somewhere durable. Two variables are expanded in `args`, `env` values, and `cwd`.
-* `${PLUGIN_ROOT}`: The directory the package was unpacked into. Read-only in practice, and shared by every Actor of the template.
-* `${PLUGIN_DATA}`: A per-package data directory that kagent creates. Use it for anything the server writes.
+- `${PLUGIN_ROOT}`: The directory the package was unpacked into. Read-only in practice, and shared by every Actor of the template.
+- `${PLUGIN_DATA}`: A per-package data directory that kagent creates. Use it for anything the server writes.
kagent also sets both as environment variables on every `stdio` server, so a server can read them without the package declaring them. A package cannot override either one: an `env` block that sets `PLUGIN_ROOT` or `PLUGIN_DATA` is rejected.
diff --git a/docs-site/content/kagent/1.x/skills-and-mcp/skills.md b/docs-site/content/kagent/1.x/skills-and-mcp/skills.md
index 7bee3a54..6cfd1ba2 100644
--- a/docs-site/content/kagent/1.x/skills-and-mcp/skills.md
+++ b/docs-site/content/kagent/1.x/skills-and-mcp/skills.md
@@ -13,7 +13,7 @@ A skill is a directory whose root holds a `SKILL.md` file. That file carries fro
The description is what makes a skill usable. When an agent starts, the runtime reads the front matter of every skill that is attached to it, and offers those skills to the model as tools that it can call. The model chooses a skill from its description, in the same way that it chooses any other tool. This means that a description that states plainly when to use the skill matters more than the length of the instructions behind it.
-A skill can be published on its own, or bundled with other skills in a [plugin package]({{< link path="skills-and-mcp/plugins" >}}), which can also declare Model Context Protocol (MCP) servers that kagent adds to the agent's tools.
+A skill can be published on its own, or bundled with other skills in a [plugin package]({{< link path="skills-and-mcp/plugins" >}}), which can also declare Model Context Protocol (MCP) servers that kagent adds to the agent's [tools]({{< link path="skills-and-mcp/about-tools" >}}).
## Attach skills to an AgentTemplate
@@ -47,10 +47,10 @@ spec:
| Field | Description |
| ----- | ----------- |
| `skills[].name` | The name that the skill is mounted under, and the name that the model sees. |
-| `skills[].source` | Where to fetch this one skill from. The source root must hold a `SKILL.md` file. |
-| `plugins[].source` | Where to fetch the plugin package from. The source root must hold a `plugin.json` manifest. |
+| `skills[].source` | The location to fetch this one skill from. The source root must hold a `SKILL.md` file. |
+| `plugins[].source` | The location to fetch the plugin package from. The source root must hold a `plugin.json` manifest. |
| `plugins[].skills` | The names of the skills inside that package to enable. Omit or leave empty to enable none. |
-| `source.path` | Selects a directory inside the artifact, when the content is not at its root. The path must be relative, and it cannot climb out of the artifact with `..` segments. |
+| `source.path` | The directory to select inside the artifact, when the content is not at its root. The path must be relative, and it cannot climb out of the artifact with `..` segments. |
### Plugin allowlist
diff --git a/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md b/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
index 7a607d50..d919773b 100644
--- a/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
+++ b/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
@@ -66,7 +66,7 @@ spec:
| Field | Description |
| ----- | ----------- |
| `sandboxClass` | The sandbox runtime family that this configuration applies to, `gvisor` or `microvm`. A WorkerPool only draws on configurations whose class matches its own. |
-| `default` | Marks this configuration as the cluster default for its class. Expect at most one default per class. |
+| `default` | Whether this configuration is the cluster default for its class. Expect at most one default per class. |
| `pauseImage` | The image for the root sandbox container, which holds the sandbox's namespaces and runs no workload code. It must be pinned to a digest, because the snapshot manifest records it, and changing the image invalidates the snapshots that were taken with it. |
| `assets` | The files that the node agent fetches, keyed first by processor architecture and then by asset name. A `gvisor` class expects one `gvisor` asset, the release archive that the node agent extracts. A `microvm` class expects several, such as `cloud-hypervisor`, `kata-kernel`, and `kata-image`. |
| `assets...sha256` | The lowercase hex digest of the file. The node agent verifies each download against it, and caches the result under a path that includes the digest, so changing the digest fetches the new asset instead of reusing the cached one. To read the configuration that your own cluster installed, including the pinned digests, run `kubectl get sandboxconfig gvisor-default -o yaml`.|
From 5a463c840d0c2c21510e88b20987b83ccc2508c8 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Fri, 28 Aug 2026 13:12:29 -0500
Subject: [PATCH 30/70] Create identity.md
Signed-off-by: Rachael Graham
---
.../kagent/1.x/substrate-runtime/identity.md | 53 +++++++++++++++++++
1 file changed, 53 insertions(+)
create mode 100644 docs-site/content/kagent/1.x/substrate-runtime/identity.md
diff --git a/docs-site/content/kagent/1.x/substrate-runtime/identity.md b/docs-site/content/kagent/1.x/substrate-runtime/identity.md
new file mode 100644
index 00000000..23574cee
--- /dev/null
+++ b/docs-site/content/kagent/1.x/substrate-runtime/identity.md
@@ -0,0 +1,53 @@
+---
+title: Identity
+description: Understand how kagent authenticates callers, scopes an AgentInstance to its creator, and how Agent Substrate identifies its own components.
+weight: 30
+author: kagent.dev
+---
+
+A kagent installation authenticates three different kinds of caller, and each one is handled by a different system. This page describes what each layer establishes, and what it does not.
+
+- An operator applying a {{< gloss "Harness" >}}Harness{{< /gloss >}} is authenticated by [Kubernetes](#the-kubernetes-plane).
+- A caller creating or talking to an {{< gloss "AgentInstance" >}}AgentInstance{{< /gloss >}} is authenticated by [kagent's own gRPC API](#the-kagent-plane).
+- The components inside [Agent Substrate](#the-agent-substrate-plane) authenticate each other.
+
+## The Kubernetes plane
+
+Harness and AgentTemplate are Kubernetes custom resources, so Kubernetes role-based access control (RBAC) governs who can create, read, edit, or delete them. Nothing in kagent replaces or supplements that: a cluster's existing roles and bindings decide who authors an agent's runtime and behavior.
+
+A Harness's `allowedAgentTemplates` selector adds a second, narrower control on top of RBAC. Whoever holds edit access on a Harness decides which AgentTemplates that Harness admits. In this way, RBAC governs who can write the resources, and the selector governs which pairs can run. For more information on the one-way match, see the [Harness core concept]({{< link path="about/core-concepts/#harness" >}}).
+
+## The kagent plane
+
+An AgentInstance is not a Kubernetes resource. kagent's gRPC API creates the AgentInstance and kagent's database tracks it, so Kubernetes RBAC does not reach it. kagent authenticates these calls itself.
+
+Every call on the AgentInstance API requires an authenticated principal. A call that arrives without one is rejected as unauthenticated before any other check runs.
+
+### Creator ownership
+
+kagent records a **creator** on every AgentInstance, taken from the authenticated principal that created it. That creator is then part of the database query for every read, so a caller who asks for an AgentInstance that another principal created receives a not-found response rather than a permission error.
+
+Listing behaves the same way. A list returns the caller's own AgentInstances by default. A caller that sets the request's all-creators flag asks to widen that to every creator in the namespace, and kagent authorizes that request separately from an ordinary list.
+
+> [!IMPORTANT]
+> Creator ownership is the boundary that the open source build enforces. kagent calls an authorizer before every AgentInstance operation. However, the authorizer that this build installs permits every check, so a widened list is available to any authenticated caller. Treat authentication and creator scoping as the guarantees that this build makes.
+
+### Shares
+
+A share lets an AgentInstance's owner give another account access to that one conversation. Creating a share produces a token, and a caller presenting that token reaches the shared AgentInstance without becoming its creator.
+
+A share carries one of two permissions.
+
+- **`READ_ONLY`**: The holder can read the conversation. kagent refuses any call that is not a read before the request reaches the service.
+- **`READ_WRITE`**: The holder can also send messages to the AgentInstance.
+
+A share widens what the holder can reach to what the owner can see, and the underlying record is read as the owner rather than as the visitor. Revoking the share withdraws that access.
+
+## The Agent Substrate plane
+
+{{< gloss "Agent Substrate" >}}Agent Substrate{{< /gloss >}} authenticates its own components rather than authenticating end users. Its API server accepts Kubernetes ServiceAccount tokens issued for its audience, and the components that carry traffic to an Actor authenticate each other with mutual Transport Layer Security (mTLS). The [kagent installation guide]({{< link path="setup/installation" >}}) covers creating the certificate authority pools and the JSON Web Token (JWT) authority pool that these identities are issued from, which is a required step that no Helm chart performs.
+
+Each Actor also carries an identity of its own, addressed as its {{< gloss "Atespace" >}}atespace{{< /gloss >}} and name together. [Sandboxing]({{< link path="substrate-runtime/sandboxing" >}}) covers how the router uses that identity to reach the right Worker over mTLS.
+
+> [!IMPORTANT]
+> Agent Substrate authenticates callers but does not authorize them. Any provider that you configure as an authenticated caller can reach every remote procedure call, including destructive ones, so configure only providers whose users require full access to Agent Substrate.
From cba2dd27003e40b7075f9d2cdea11d095363af78 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Mon, 31 Aug 2026 11:40:01 -0500
Subject: [PATCH 31/70] weekend update
Signed-off-by: Rachael Graham
---
.../kagent/1.x/about/agent-substrate.md | 2 +
.../kagent/1.x/about/what-is-kagent.md | 8 +-
.../content/kagent/1.x/examples/_index.md | 6 +
.../kagent/1.x/examples/agent-substrate.md | 171 ++++++++++++++++
.../1.x/get-started/your-first-agent.md | 190 ++++++++----------
.../content/kagent/1.x/setup/installation.md | 2 +-
.../substrate-runtime/suspend-and-resume.md | 6 +-
docs-site/data/glossary.yaml | 3 +
8 files changed, 270 insertions(+), 118 deletions(-)
create mode 100644 docs-site/content/kagent/1.x/examples/_index.md
create mode 100644 docs-site/content/kagent/1.x/examples/agent-substrate.md
diff --git a/docs-site/content/kagent/1.x/about/agent-substrate.md b/docs-site/content/kagent/1.x/about/agent-substrate.md
index 4844c0a2..29ed404c 100644
--- a/docs-site/content/kagent/1.x/about/agent-substrate.md
+++ b/docs-site/content/kagent/1.x/about/agent-substrate.md
@@ -31,6 +31,8 @@ kagent names each atespace after the Kubernetes namespace of the AgentInstance w
Because an Actor often runs a model-directed agent that calls tools and executes commands, Substrate runs each Actor in an isolated sandbox rather than a plain container. A WorkerPool's `sandboxClass` field selects the sandbox technology for its Workers: [gVisor](https://gvisor.dev) or a micro-VM technology such as [Kata Containers](https://katacontainers.io). Both technologies isolate an Actor from its Worker's host kernel, and both support suspend and resume operations.
+kagent compiles every ActorTemplate to the `gvisor` class, so a kagent agent runs in a gVisor sandbox today and the micro-VM class is a Substrate capability that kagent does not yet select. Keep a WorkerPool that backs kagent Harnesses on `gvisor`. For what each class isolates, see [Sandboxing]({{< link path="substrate-runtime/sandboxing" >}}).
+
## Suspend, snapshot, and resume
Substrate's density model rests on one fact about agent workloads: an Actor spends most of its time idle, waiting on a person or a large language model (LLM) to respond, not actively computing. Substrate exploits that by suspending idle Actors and reclaiming their Worker, then resuming them on demand when traffic arrives. Suspending and resuming allows a WorkerPool to run far more Actors than it has Workers for at any given moment.
diff --git a/docs-site/content/kagent/1.x/about/what-is-kagent.md b/docs-site/content/kagent/1.x/about/what-is-kagent.md
index 0c6ef586..e7f78815 100644
--- a/docs-site/content/kagent/1.x/about/what-is-kagent.md
+++ b/docs-site/content/kagent/1.x/about/what-is-kagent.md
@@ -43,16 +43,16 @@ Everything works with a single `helm install`. No add-ons, no extra databases, n
{{< feature-cards >}}
{{< feature-card title="Agent lifecycle via CRDs" desc="Define, version, and roll out Harnesses and AgentTemplates with kubectl and GitOps, the same workflow as every other workload." >}}
-{{< feature-card title="Sandboxed by default" desc="Every AgentInstance runs on a Substrate Actor, sandboxed with gVisor or a micro-VM. Run untrusted, model-directed code safely." >}}
+{{< feature-card title="Sandboxed by default" desc="Every AgentInstance runs on a Substrate Actor, isolated from the host kernel by a gVisor sandbox. Run untrusted, model-directed code safely." >}}
{{< feature-card title="Suspend and resume" desc="Idle AgentInstances suspend and free their compute, then resume on demand. Run far more agents than you have capacity for at any one moment." >}}
-{{< feature-card title="Bring your own runtime" desc="Run kagent's native Go or Python engine, or bring Claude Code or Codex as the runtime behind a Harness." >}}
-{{< feature-card title="Agent tools" desc="Compose agents from other agents. Choose Shared isolation for cheap nesting, or Dedicated isolation to give a nested agent its own Actor." >}}
+{{< feature-card title="Bring your own runtime" desc="Run kagent's native Go or Python engine behind a Harness. Codex is planned as an additional runtime." >}}
+{{< feature-card title="Agent tools" desc="Compose agents from other agents. A Shared binding nests an agent inside its parent's Actor, one level deep." >}}
{{< feature-card title="Long-term memory" desc="Persistent, vector-backed memory across sessions. Agents remember context, not just the last prompt." >}}
{{< feature-card title="Human-in-the-loop" desc="Tool approval gates and agent-initiated questions keep a person in control of consequential actions." >}}
{{< feature-card title="Agent-to-Agent (A2A)" desc="AgentInstances talk to callers, and to each other, over the A2A protocol." >}}
{{< feature-card title="Skills and plugins" desc="Load skills and capability packages from an Open Container Initiative (OCI) registry, Git, or S3 at startup." >}}
{{< feature-card title="Prompt templates" desc="Reusable prompt fragments stored as ConfigMaps. Keep system prompts consistent across agents." >}}
-{{< feature-card title="Full observability" desc="OpenTelemetry tracing, Prometheus metrics, and structured logs. See every prompt, every tool call, every token." >}}
+{{< feature-card title="Full observability" desc="OpenTelemetry tracing, Prometheus metrics, and structured logs, with control plane traces carrying the Actor that they belong to." >}}
{{< feature-card title="Postgres storage" desc="AgentInstances are tracked in production-grade, Postgres-backed storage with reviewable migrations." >}}
{{< /feature-cards >}}
diff --git a/docs-site/content/kagent/1.x/examples/_index.md b/docs-site/content/kagent/1.x/examples/_index.md
new file mode 100644
index 00000000..65bb6f3c
--- /dev/null
+++ b/docs-site/content/kagent/1.x/examples/_index.md
@@ -0,0 +1,6 @@
+---
+title: Examples
+description: Work through end-to-end examples that put kagent's runtime, tools, and Agent Substrate features together.
+weight: 80
+author: kagent.dev
+---
diff --git a/docs-site/content/kagent/1.x/examples/agent-substrate.md b/docs-site/content/kagent/1.x/examples/agent-substrate.md
new file mode 100644
index 00000000..a8b47ce3
--- /dev/null
+++ b/docs-site/content/kagent/1.x/examples/agent-substrate.md
@@ -0,0 +1,171 @@
+---
+title: Agent Substrate
+description: Watch an agent's Actor suspend between turns, pin the conversation with a checkpoint, and fork it into two independent branches.
+weight: 10
+author: kagent.dev
+---
+
+[Agent Substrate]({{< link path="about/agent-substrate" >}}) runs every agent as an Actor: a sandboxed unit of compute that holds a {{< gloss "Worker" >}}Worker{{< /gloss >}} only while a turn is in progress, and whose state you can pin and branch. This example follows one agent through all three behaviors.
+
+## Before you begin
+
+1. Complete [Your first agent]({{< link path="get-started/your-first-agent" >}}). The steps on this page continues from the Harness, AgentTemplate, and AgentInstance that the agent guide creates, and assumes that you have sent the agent at least one message.
+
+2. If you have not already, save the AgentInstance's ID to an environment variable. To find the ID, run `kagent get agent-instance` to list your AgentInstances and copy the value from the `ID` column.
+ ```bash
+ export INSTANCE_ID=
+ ```
+
+3. Install [grpcurl](https://github.com/fullstorydev/grpcurl), and confirm that your kagent installation sets `controller.grpc.reflection`. Checkpoints and forks have no kagent CLI commands yet, so this example calls `CheckpointService` directly.
+
+4. Port-forward the controller's gRPC port to your local machine.
+ ```bash
+ kubectl port-forward -n kagent svc/kagent-controller 8084:8084
+ ```
+
+## Watch the Actor suspend between turns
+
+1. List the Actors in your namespace's {{< gloss "Atespace" >}}atespace{{< /gloss >}}. kagent names an AgentInstance's Actor `ai-`.
+ ```bash
+ kubectl ate get actors --atespace kagent
+ ```
+
+ Between turns, the Actor reports `ACTOR_STATE_SUSPENDED` and holds no Worker, so the `ATEOM POD` column reads ``. Example output:
+ ```console
+ ATESPACE NAME TEMPLATE STATE ATEOM POD ATEOM IP VERSION AGE
+ kagent ai-0198c3d7-4f2a-7b61-9c3e-5d8f7a2b4e10 kagent/my-first-agent-my-first-harness-5f2b3c1a9e8d ACTOR_STATE_SUSPENDED 4 6m
+ ```
+
+ That Actor is also the isolation boundary. Every Actor runs in its own gVisor sandbox rather than sharing one with its neighbors, which is what makes it safe to let a model run tools and execute commands. For what the sandbox blocks, see [Sandboxing]({{< link path="substrate-runtime/sandboxing" >}}).
+
+2. Send the agent another message. Nothing in the command acknowledges that the Actor was suspended, because resuming is automatic.
+ ```bash
+ kagent invoke --agent-instance $INSTANCE_ID --task "Summarize this conversation so far."
+ ```
+
+3. List the Actors again while the turn is running, and the same Actor reports `ACTOR_STATE_RUNNING` against a real Worker pod. Once the turn finishes it returns to `ACTOR_STATE_SUSPENDED`.
+ ```bash
+ kubectl ate get actors --atespace kagent
+ ```
+
+The AgentInstance stays `READY` throughout all of this. Suspension is a property of the Actor underneath the conversation, not of the conversation, which is why a suspended agent is still listed and still readable. For the full cycle, see [Suspend and resume]({{< link path="substrate-runtime/suspend-and-resume" >}}).
+
+## Pin the conversation with a checkpoint
+
+Each suspend writes a snapshot, and Agent Substrate is free to collect that snapshot once a newer one supersedes it. A {{< gloss "Checkpoint" >}}checkpoint{{< /gloss >}} pins one so that you can come back to it.
+
+1. Create a checkpoint. The `requestId` field is a required idempotency key of 1 to 128 characters, so reusing it returns the same checkpoint rather than creating a second one.
+ ```bash
+ grpcurl -plaintext \
+ -d '{"namespace":"kagent","agentInstanceId":"'"$INSTANCE_ID"'","requestId":"'"$(uuidgen)"'"}' \
+ localhost:8084 kagent.api.v1alpha1.CheckpointService/CreateCheckpoint
+ ```
+
+ The checkpoint records the snapshot it pinned and how far the transcript had advanced. Example output:
+ ```json
+ {
+ "checkpoint": {
+ "id": "0198c3e2-8a41-7d05-b6c2-1f4e9a7b3c58",
+ "namespace": "kagent",
+ "agentInstanceId": "0198c3d7-4f2a-7b61-9c3e-5d8f7a2b4e10",
+ "headTaskId": "0198c3d9-b7e3-7a24-8f10-6c2d5e8a1b47",
+ "historySequence": "4",
+ "state": "CHECKPOINT_STATE_READY",
+ "createdAt": "2026-08-31T15:12:44Z"
+ }
+ }
+ ```
+
+2. Save the checkpoint's `id`, to fork from it in the next section.
+ ```bash
+ export CHECKPOINT_ID=
+ ```
+
+3. List the checkpoints on the AgentInstance at any time. Omit `limit` for the default page of 50, up to a maximum of 100.
+ ```bash
+ grpcurl -plaintext \
+ -d '{"namespace":"kagent","agentInstanceId":"'"$INSTANCE_ID"'","page":{"limit":50}}' \
+ localhost:8084 kagent.api.v1alpha1.CheckpointService/ListCheckpoints
+ ```
+
+Underneath, the checkpoint attaches an ActorSnapshotTag named `checkpoint-` to the snapshot, and Agent Substrate does not collect a snapshot while a tag names it. You can see the tag with `kubectl ate get actor-snapshot-tag`.
+
+> [!NOTE]
+> A checkpoint captures a turn boundary, so two conditions have to hold and a request that fails either one reports `AgentInstance has no quiescent turn boundary`. The AgentInstance must be `READY` with no lifecycle operation in flight, and at least one turn must have reached a quiescent state. Send the request again once the turn finishes.
+
+## Fork the conversation into a second agent
+
+Forking creates a second AgentInstance that starts from the pinned snapshot, with the transcript up to the checkpoint's position already in place. The original is untouched, so the two conversations diverge from that point.
+
+1. Fork the checkpoint.
+ ```bash
+ grpcurl -plaintext \
+ -d '{"namespace":"kagent","checkpointId":"'"$CHECKPOINT_ID"'","requestId":"'"$(uuidgen)"'"}' \
+ localhost:8084 kagent.api.v1alpha1.CheckpointService/ForkAgentInstance
+ ```
+
+ The response carries a new AgentInstance with its own ID. Example output:
+ ```json
+ {
+ "agentInstance": {
+ "id": "0198c3e5-1d62-7f38-a904-8b3c7e2f5d16",
+ "namespace": "kagent",
+ "harness": {
+ "namespace": "kagent",
+ "name": "my-first-harness"
+ },
+ "agentTemplate": {
+ "namespace": "kagent",
+ "name": "my-first-agent"
+ },
+ "state": "AGENT_INSTANCE_STATE_READY"
+ }
+ }
+ ```
+
+2. Save the fork's ID, then send it down a different path than the original.
+ ```bash
+ export FORK_ID=
+ kagent invoke --agent-instance $FORK_ID --task "What did I ask you first?"
+ ```
+
+ The fork answers from the transcript it inherited, which is what distinguishes a fork from a new AgentInstance that happens to use the same AgentTemplate.
+
+3. List your AgentInstances, and both branches appear, each with its own Actor.
+ ```bash
+ kagent get agent-instance
+ ```
+
+A fork runs the compiled revision that its checkpoint was taken on, not whatever revision the AgentTemplate resolves to now. Editing the AgentTemplate after checkpointing does not change what a fork of that checkpoint runs, which is what makes a fork a faithful continuation rather than a fresh start with an old transcript.
+
+> [!NOTE]
+> A checkpoint can only be forked when its snapshot captured durable data alone. kagent compiles every ActorTemplate to take a `Data`-scope snapshot on commit, so a checkpoint taken on a suspended AgentInstance is forkable. A checkpoint whose snapshot also captured process state is rejected with `Checkpoint includes process state and cannot be forked`, because process memory belongs to the one Actor that produced it.
+
+## Clean up
+
+1. Delete the checkpoint. Deleting removes the ActorSnapshotTag and releases the pin, and Agent Substrate can collect the snapshot once no tag names it.
+ ```bash
+ grpcurl -plaintext \
+ -d '{"namespace":"kagent","checkpointId":"'"$CHECKPOINT_ID"'"}' \
+ localhost:8084 kagent.api.v1alpha1.CheckpointService/DeleteCheckpoint
+ ```
+
+2. Delete both AgentInstances.
+ ```bash
+ kagent delete agent-instance $FORK_ID
+ kagent delete agent-instance $INSTANCE_ID
+ ```
+
+3. Delete the AgentTemplate and the Harness.
+ ```bash
+ kubectl delete agenttemplate my-first-agent -n kagent
+ kubectl delete harness my-first-harness -n kagent
+ ```
+
+## Next steps
+
+{{< cards >}}
+ {{< card link=`{{< link path="substrate-runtime/suspend-and-resume" >}}` title="Suspend and resume" subtitle="Understand the snapshot cycle that checkpoints pin." >}}
+ {{< card link=`{{< link path="substrate-runtime/sandboxing" >}}` title="Sandboxing" subtitle="See what the sandbox around each Actor isolates." >}}
+ {{< card link=`{{< link path="substrate-runtime/identity" >}}` title="Identity" subtitle="See who owns an AgentInstance and the checkpoints taken on it." >}}
+{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/get-started/your-first-agent.md b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
index 5eb909b8..7b21fc0f 100644
--- a/docs-site/content/kagent/1.x/get-started/your-first-agent.md
+++ b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
@@ -5,19 +5,20 @@ weight: 10
author: kagent.dev
---
-This guide walks you through creating an agent, from applying a Harness and an AgentTemplate to holding a conversation with the AgentInstance that they produce. For definitions of each of these components, review the [core concepts]({{< link path="about/core-concepts" >}}). For an overview of how each component fits together in kagent, review the [architecture]({{< link path="about/architecture" >}}). For the complete schema of every field that this guide sets, see the [API reference]({{< link path="reference/api-ref" >}}).
+This guide walks you through creating an agent, from applying a Harness and an AgentTemplate to holding a conversation with the AgentInstance that they produce. You apply the Harness and the AgentTemplate as Kubernetes resources, and you create and talk to the AgentInstance with the kagent CLI. For definitions of each of these components, review the [core concepts]({{< link path="about/core-concepts" >}}). For an overview of how each component fits together in kagent, review the [architecture]({{< link path="about/architecture" >}}). For the complete schema of every field that this guide sets, see the [API reference]({{< link path="reference/api-ref" >}}).
## Before you begin
1. [Install kagent with a WorkerPool provisioned]({{< link path="setup/installation" >}}).
-2. Install [grpcurl](https://github.com/fullstorydev/grpcurl).
-3. Port-forward the controller's gRPC port to your local machine.
- ```shell
- kubectl port-forward -n kagent svc/kagent-controller 8084:8084
+2. Download the kagent CLI.
+ ```bash
+ curl https://raw.githubusercontent.com/kagent-dev/kagent/refs/heads/main/scripts/get-kagent | bash
```
+3. Install [`jq`](https://jqlang.org/download/), to read the AgentInstance ID out of the CLI's JSON output.
+
> [!NOTE]
-> This guide uses `kubectl` and `grpcurl` directly, as the kagent CLI does not yet have commands for Harness, AgentTemplate, or AgentInstance.
+> The CLI reaches the kagent controller at `localhost:8083` and `localhost:8084`. When nothing serves those ports, the CLI runs `kubectl port-forward` against the `kagent-controller` service for you, and closes the forward when the command exits. Keep `kubectl` on your path, and keep your kubeconfig pointed at the cluster that runs kagent.
## Create a Harness and an AgentTemplate
@@ -66,132 +67,99 @@ This guide walks you through creating an agent, from applying a Harness and an A
systemPrompt: You are a concise, helpful assistant.
```
-3. Confirm that the pair is ready.
- ```shell
- kubectl get agenttemplate my-first-agent -n kagent -o jsonpath='{.status.harnesses}' | jq .
+3. Confirm that the pair is ready. The `HARNESS` column lists each Harness that admitted this AgentTemplate, and `READY` reports whether kagent compiled a runtime revision for that pairing.
+ ```bash
+ kagent get agent-template my-first-agent
+ ```
+
+ Example output:
+ ```console
+ +----------------+------------------+-------+----------------------+
+ | NAME | HARNESS | READY | CREATED |
+ +----------------+------------------+-------+----------------------+
+ | my-first-agent | my-first-harness | TRUE | 2026-08-31T15:01:44Z |
+ +----------------+------------------+-------+----------------------+
```
- A ready pair reports four conditions for `my-first-harness`, ending in `Ready`. If the status is empty, wait a few seconds for the kagent controller to reconcile, then check again.
- ```json
- [
- {
- "conditions": [
- {
- "lastTransitionTime": "2026-08-24T15:02:10Z",
- "message": "Harness admission selector matches the AgentTemplate",
- "observedGeneration": 1,
- "reason": "Accepted",
- "status": "True",
- "type": "Accepted"
- },
- {
- "lastTransitionTime": "2026-08-24T15:02:10Z",
- "message": "All runtime references resolved",
- "observedGeneration": 1,
- "reason": "Resolved",
- "status": "True",
- "type": "ResolvedRefs"
- },
- {
- "lastTransitionTime": "2026-08-24T15:02:10Z",
- "message": "Resolved configuration is compatible with the Harness",
- "observedGeneration": 1,
- "reason": "Compatible",
- "status": "True",
- "type": "Compatible"
- },
- {
- "lastTransitionTime": "2026-08-24T15:02:10Z",
- "message": "ActorTemplate golden snapshot is ready",
- "observedGeneration": 1,
- "reason": "Ready",
- "status": "True",
- "type": "Ready"
- }
- ],
- "desiredRevision": "5f2b3c1a9e8d4b7a6c3e2f1d0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b",
- "harness": "my-first-harness",
- "latestSuccessfulRevision": "5f2b3c1a9e8d4b7a6c3e2f1d0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b"
- }
- ]
+ An empty `HARNESS` column with a `READY` value of `UNKNOWN` means that the kagent controller has not yet reconciled the pair. Wait a few seconds, then check again. If `READY` stays `FALSE`, inspect the individual conditions to find which stage failed.
+ ```bash
+ kagent get agent-template my-first-agent -o json
```
- The `latestSuccessfulRevision` value is the compiled revision that kagent creates your AgentInstance from in the next section.
+ Each entry in `status.harnesses` reports four conditions, ending in `Ready`. The `Accepted` condition covers the label selector match, `ResolvedRefs` covers the ModelConfig and tool references, `Compatible` covers whether the resolved configuration suits the Harness runtime, and `Ready` covers the compiled revision itself.
## Create the AgentInstance
+An AgentInstance is one running conversation. Creating it starts an Actor on the WorkerPool from the revision that kagent compiled for the Harness and AgentTemplate pair.
+
1. Create an AgentInstance from the Harness and AgentTemplate pair.
- ```shell
- RESPONSE=$(grpcurl -plaintext \
- -d '{"namespace":"kagent","harness":"my-first-harness","agentTemplate":"my-first-agent","requestId":"'"$(uuidgen)"'"}' \
- localhost:8084 kagent.api.v1alpha1.AgentInstanceService/CreateAgentInstance)
- echo "$RESPONSE"
+ ```bash
+ kagent create agent-instance --harness my-first-harness --agent-template my-first-agent
```
- A successful response includes the new AgentInstance and its `id`.
- ```json
- {
- "agentInstance": {
- "id": "8f14e45f-ceea-4a37-b0f1-2b5c4d3a9c6e",
- "namespace": "kagent",
- "harness": {
- "namespace": "kagent",
- "name": "my-first-harness"
- },
- "agentTemplate": {
- "namespace": "kagent",
- "name": "my-first-agent"
- },
- "state": "AGENT_INSTANCE_STATE_READY"
- }
- }
+ The command returns output only after the AgentInstance reaches the `READY` state. Example output:
+ ```console
+ +--------------------------------------+----------------+------------------+-------+----------------------+
+ | ID | AGENT TEMPLATE | HARNESS | STATE | CREATED |
+ +--------------------------------------+----------------+------------------+-------+----------------------+
+ | 0198c3d7-4f2a-7b61-9c3e-5d8f7a2b4e10 | my-first-agent | my-first-harness | READY | 2026-08-31T15:02:10Z |
+ +--------------------------------------+----------------+------------------+-------+----------------------+
```
-2. Save the AgentInstance's `id` to an environment variable. The next step needs it to address the AgentInstance that you created.
- ```shell
- export INSTANCE_ID=$(echo "$RESPONSE" | jq -r '.agentInstance.id')
+ An error reporting that the AgentTemplate and Harness have no ready prepared revision means that the pair is not `READY` yet. Return to step 3 of the previous section to check the conditions.
+
+2. Save the AgentInstance's ID to an environment variable.
+ ```bash
+ export INSTANCE_ID=$(kagent get agent-instance -o json \
+ | jq -r '[.agentInstances[] | select(.agentTemplate.name == "my-first-agent")] | sort_by(.createdAt) | last | .id')
+ echo $INSTANCE_ID
```
## Talk to your agent
-Send a message to the AgentInstance over the A2A (Agent-to-Agent) protocol.
-
-```shell
-grpcurl -plaintext \
- -H "x-kagent-agent-instance-namespace: kagent" \
- -H "x-kagent-agent-instance-id: $INSTANCE_ID" \
- -d '{"message":{"messageId":"'"$(uuidgen)"'","role":"ROLE_USER","parts":[{"text":"What is 2+2?"}]}}' \
- localhost:8084 lf.a2a.v1.A2AService/SendMessage
-```
-
-The response carries the agent's reply in the same `parts` shape as the request.
-```json
-{
- "message": {
- "messageId": "b2b1e2b4-5c3a-4f8e-9d1a-7e6f5c4b3a2d",
- "role": "ROLE_AGENT",
- "parts": [
- {
- "text": "4"
- }
- ]
- }
-}
-```
+1. Send a message to the AgentInstance. The CLI holds the conversation over the A2A (Agent-to-Agent) protocol.
+ ```bash
+ kagent invoke --agent-instance $INSTANCE_ID --task "What is 2+2?"
+ ```
+
+ The agent's reply prints as text.
+ ```console
+ 4
+ ```
+
+2. Send a follow-up message to the same AgentInstance. An AgentInstance holds the transcript of its conversation, so the agent answers with the earlier turns in context.
+ ```bash
+ kagent invoke --agent-instance $INSTANCE_ID --task "What did I just ask you?"
+ ```
+
+ ```console
+ You asked what 2+2 is.
+ ```
+
+> [!NOTE]
+> An AgentInstance gives its Worker back at the end of every turn. The AgentInstance itself stays `READY`, because suspension applies to the Actor running underneath it rather than to the conversation, and the next `kagent invoke` resumes that Actor automatically. To understand what happens to the Actor in between, see [Suspend and resume]({{< link path="substrate-runtime/suspend-and-resume" >}}).
+
+The `invoke` command takes a few more options that are useful beyond a first conversation.
+
+| Option | Description |
+| ------ | ----------- |
+| `--file` | Read the task from a file, or from standard input with `-`, instead of passing it inline with `--task`. |
+| `--stream` | Print the reply as the agent produces it, rather than waiting for the complete answer. |
+
+> [!TIP]
+> Run `kagent` with no arguments to open an interactive workspace in your terminal, where you can browse your AgentInstances and chat with them without passing an ID to each command.
## Clean up
-1. Delete the Harness and AgentTemplate.
- ```shell
- kubectl delete agenttemplate my-first-agent -n kagent
- kubectl delete harness my-first-harness -n kagent
+1. Delete the AgentInstance. Deleting the Harness and the AgentTemplate does not delete the AgentInstances that you created from them, so delete the AgentInstance first.
+ ```bash
+ kagent delete agent-instance $INSTANCE_ID
```
-2. Delete the AgentInstance directly through the same `AgentInstanceService` that you used to create it, as deleting the Harness and AgentTemplate does not delete the AgentInstance that you created from them.
- ```shell
- grpcurl -plaintext \
- -d '{"namespace":"kagent","agentInstanceId":"'"$INSTANCE_ID"'"}' \
- localhost:8084 kagent.api.v1alpha1.AgentInstanceService/DeleteAgentInstance
+2. Delete the AgentTemplate and the Harness.
+ ```bash
+ kubectl delete agenttemplate my-first-agent -n kagent
+ kubectl delete harness my-first-harness -n kagent
```
## Next steps
diff --git a/docs-site/content/kagent/1.x/setup/installation.md b/docs-site/content/kagent/1.x/setup/installation.md
index 54fe2ee5..b7a438ff 100644
--- a/docs-site/content/kagent/1.x/setup/installation.md
+++ b/docs-site/content/kagent/1.x/setup/installation.md
@@ -225,7 +225,7 @@ The kagent chart connects the controller to Agent Substrate and creates a Worker
EOF
```
> [!NOTE]
- > `controller.grpc.reflection` lets a gRPC client discover the controller's methods without a local copy of kagent's proto files, which is how [Your first agent]({{< link path="get-started/your-first-agent" >}}) calls the API. Leave it on while you explore the API, and turn it off for a production installation.
+ > `controller.grpc.reflection` lets a gRPC client discover the controller's methods without a local copy of kagent's proto files. The kagent CLI does not need it, because the CLI ships with generated clients for every kagent API. Leave reflection on to explore the API with a general-purpose client such as [grpcurl](https://github.com/fullstorydev/grpcurl), and turn it off for a production installation.
3. Wait for the controller to roll out.
```bash
diff --git a/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md b/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
index 2a7054b1..da935da6 100644
--- a/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
+++ b/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
@@ -11,8 +11,8 @@ An agent spends most of its life waiting. It waits on a person to reply, and it
{{< gloss "Agent Substrate" >}}Agent Substrate{{< /gloss >}} provides three lifecycle operations, and each one moves an Actor between states that you can observe on the Actor record.
-- **Suspend**: Writes the Actor's state to a durable snapshot in snapshot storage, then frees its Worker. A running Actor is checkpointed on its Worker. A paused Actor's node-local snapshot is uploaded instead.
-- **Pause**: Takes a short-term checkpoint whose files stay on the node. Pausing pins the Actor to that node, because the following resume is prioritized onto the node that holds the snapshot files.
+- **Suspend**: Writes the Actor's state to a durable snapshot in snapshot storage, then frees its Worker. A running Actor is snapshotted on its Worker. A paused Actor's node-local snapshot is uploaded instead.
+- **Pause**: Takes a short-term snapshot whose files stay on the node. Pausing pins the Actor to that node, because the following resume is prioritized onto the node that holds the snapshot files.
- **Resume**: Restores a suspended or paused Actor onto a Worker, from its latest snapshot. The common path restores from a snapshot rather than cold-booting the workload.
The following diagram traces an Actor through those operations, and shows the further path that opens once a snapshot is [pinned by a tag](#checkpoints).
@@ -84,3 +84,5 @@ A snapshot that Agent Substrate writes on suspend is transient. Agent Substrate
Creating a checkpoint attaches an ActorSnapshotTag to the snapshot that the AgentInstance most recently suspended to. The tag names that one snapshot permanently and acts as a retention pin, such that Agent Substrate does not collect a snapshot while a tag still names it. Deleting the checkpoint removes the tag and releases the pin.
An AgentInstance must be a turn boundary to be checkpointed, because the turn boundary is captured. An AgentInstance with a turn still in progress has no quiescent boundary to capture, and the request fails until the turn finishes.
+
+A checkpoint also records where the conversation had reached, which lets you start a second AgentInstance from that point. To create a checkpoint and fork an AgentInstance from it, work through the [Agent Substrate example]({{< link path="examples/agent-substrate" >}}).
diff --git a/docs-site/data/glossary.yaml b/docs-site/data/glossary.yaml
index a506afb1..d95ee706 100644
--- a/docs-site/data/glossary.yaml
+++ b/docs-site/data/glossary.yaml
@@ -33,6 +33,9 @@ ActorTemplate:
AgentInstance:
short: "A running, conversational pairing of a Harness and an AgentTemplate. Unlike the two, it is not a Kubernetes resource: kagent's gRPC API creates it and its database tracks it."
+Checkpoint:
+ short: "A durable pin on the snapshot that an AgentInstance most recently suspended to, and a record of how far its transcript had advanced. Not a copy of the state: it tags a snapshot so that Agent Substrate does not collect it, and a second AgentInstance can be forked from it."
+
AgentTemplate:
short: "A Kubernetes custom resource defining what an agent does: its model, system prompt, tools, skills, and plugins. It runs only once a Harness accepts it."
From 6f4e407680e913eeefc059931b1e620cf8935426 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Mon, 31 Aug 2026 12:33:28 -0500
Subject: [PATCH 32/70] clarify codex & claude code
Signed-off-by: Rachael Graham
---
docs-site/content/kagent/1.x/about/core-concepts.md | 5 ++++-
docs-site/content/kagent/1.x/about/what-is-kagent.md | 4 ++--
docs-site/content/kagent/1.x/get-started/your-first-agent.md | 3 ++-
3 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/docs-site/content/kagent/1.x/about/core-concepts.md b/docs-site/content/kagent/1.x/about/core-concepts.md
index f3d5770c..cbf990cb 100644
--- a/docs-site/content/kagent/1.x/about/core-concepts.md
+++ b/docs-site/content/kagent/1.x/about/core-concepts.md
@@ -42,13 +42,16 @@ The Harness and AgentTemplate are the only two resources that an operator applie
A **Harness** is a Kubernetes custom resource that defines _how an agent is allowed to run_. It specifies:
-- **Runtime**: The engine that executes the agent. This is either kagent's own Go or Python runtime, or a bring-your-own coding agent such as Claude Code or Codex.
+- **Runtime**: The engine that executes the agent. A Harness selects exactly one of `kagent`, `codex`, or `claude`. kagent compiles only the `kagent` runtime, which runs kagent's own Go and Python engines.
- **Workload**: The container image and environment the runtime runs in.
- **Substrate policy**: The [WorkerPool]({{< link path="about/agent-substrate#workers-and-workerpools" >}}) that the Harness's Actors are scheduled onto, and where their snapshots are stored.
- **Allowed AgentTemplates**: A selector that names which AgentTemplates are permitted to run on this Harness.
That last point is a one-way match, not a mutual handshake. An AgentTemplate has no field naming a Harness. Instead, a Harness's `allowedAgentTemplates` selector matches on labels, and any AgentTemplate in the same namespace carrying a matching label becomes eligible to run on it. Whoever controls a Harness's selector decides which AgentTemplates it accepts.
+> [!NOTE]
+> The `codex` and `claude` runtimes are part of the Harness API, so the Kubernetes API server accepts a Harness that selects either one. However, kagent currently has no compiler for them, so the pair then reports the `Compatible` condition as `False`, with the reason `UnsupportedConfiguration` and the message `Harness runtime is not supported by any compiler`.
+
A Harness owns no running compute by itself. Applying one registers a runtime and policy that an AgentTemplate can pair with.
For the complete Harness schema, see the [API reference]({{< link path="reference/api-ref#harness" >}}).
diff --git a/docs-site/content/kagent/1.x/about/what-is-kagent.md b/docs-site/content/kagent/1.x/about/what-is-kagent.md
index e7f78815..302f5259 100644
--- a/docs-site/content/kagent/1.x/about/what-is-kagent.md
+++ b/docs-site/content/kagent/1.x/about/what-is-kagent.md
@@ -5,7 +5,7 @@ weight: 10
author: kagent.dev
---
-kagent is an open-source, Kubernetes-native platform for running AI agents. It defines an agent's runtime and behavior as ordinary Kubernetes custom resources, governed by the same role-based access control (RBAC), GitOps, and observability that you already use for your other workloads, and runs each agent's conversation inside [Agent Substrate]({{< link path="about/agent-substrate" >}}), a sandboxed, suspend-and-resume compute layer built for bursty, mostly idle agent workloads. kagent works with coding-agent runtimes such as Claude Code and Codex, agent frameworks such as Google's Agent Development Kit (ADK), LangGraph, and CrewAI, and every major large language model (LLM) provider.
+kagent is an open-source, Kubernetes-native platform for running AI agents. It defines an agent's runtime and behavior as ordinary Kubernetes custom resources, governed by the same role-based access control (RBAC), GitOps, and observability that you already use for your other workloads, and runs each agent's conversation inside [Agent Substrate]({{< link path="about/agent-substrate" >}}), a sandboxed, suspend-and-resume compute layer built for bursty, mostly idle agent workloads. kagent works with agent frameworks such as Google's Agent Development Kit (ADK), LangGraph, and CrewAI, and with every major large language model (LLM) provider. Agents run on kagent's own Go and Python engines.
kagent was created at [Solo.io](https://www.solo.io) in 2025 and is a [Cloud Native Computing Foundation](https://www.cncf.io) sandbox project.
@@ -45,7 +45,7 @@ Everything works with a single `helm install`. No add-ons, no extra databases, n
{{< feature-card title="Agent lifecycle via CRDs" desc="Define, version, and roll out Harnesses and AgentTemplates with kubectl and GitOps, the same workflow as every other workload." >}}
{{< feature-card title="Sandboxed by default" desc="Every AgentInstance runs on a Substrate Actor, isolated from the host kernel by a gVisor sandbox. Run untrusted, model-directed code safely." >}}
{{< feature-card title="Suspend and resume" desc="Idle AgentInstances suspend and free their compute, then resume on demand. Run far more agents than you have capacity for at any one moment." >}}
-{{< feature-card title="Bring your own runtime" desc="Run kagent's native Go or Python engine behind a Harness. Codex is planned as an additional runtime." >}}
+{{< feature-card title="Pluggable agent runtimes" desc="A Harness selects the engine behind an agent. kagent runs its own Go and Python engines, and the Harness API defines Codex and Claude runtime selectors." >}}
{{< feature-card title="Agent tools" desc="Compose agents from other agents. A Shared binding nests an agent inside its parent's Actor, one level deep." >}}
{{< feature-card title="Long-term memory" desc="Persistent, vector-backed memory across sessions. Agents remember context, not just the last prompt." >}}
{{< feature-card title="Human-in-the-loop" desc="Tool approval gates and agent-initiated questions keep a person in control of consequential actions." >}}
diff --git a/docs-site/content/kagent/1.x/get-started/your-first-agent.md b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
index 7b21fc0f..9eb4e4eb 100644
--- a/docs-site/content/kagent/1.x/get-started/your-first-agent.md
+++ b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
@@ -165,7 +165,8 @@ The `invoke` command takes a few more options that are useful beyond a first con
## Next steps
{{< cards >}}
+ {{< card link=`{{< link path="get-started/your-first-mcp-tool" >}}` title="Your first MCP tool" subtitle="Bind a Model Context Protocol tool so that your agent can act on live cluster data." >}}
{{< card link=`{{< link path="about/agent-substrate" >}}` title="Agent Substrate architecture" subtitle="Understand what happens to your AgentInstance's Actor when it sits idle." >}}
- {{< card link=`{{< link path="agents/agent-harness" >}}` title="Agent harness" subtitle="Choose from the full set of Harness runtime options, including Claude Code and Codex." >}}
+ {{< card link=`{{< link path="agents/agent-harness" >}}` title="Agent harness" subtitle="Choose from the full set of Harness runtime options." >}}
{{< card link=`{{< link path="skills-and-mcp/skills" >}}` title="Skills" subtitle="Give your agent capabilities beyond its system prompt." >}}
{{< /cards >}}
From e9519d417631806d308cc4945217f03db6b320bb Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Mon, 31 Aug 2026 13:33:38 -0500
Subject: [PATCH 33/70] Phase 3 - agent substrate example
Signed-off-by: Rachael Graham
---
.../kagent/1.x/examples/agent-substrate.md | 93 +++++++++++++------
1 file changed, 66 insertions(+), 27 deletions(-)
diff --git a/docs-site/content/kagent/1.x/examples/agent-substrate.md b/docs-site/content/kagent/1.x/examples/agent-substrate.md
index a8b47ce3..a9360582 100644
--- a/docs-site/content/kagent/1.x/examples/agent-substrate.md
+++ b/docs-site/content/kagent/1.x/examples/agent-substrate.md
@@ -7,9 +7,11 @@ author: kagent.dev
[Agent Substrate]({{< link path="about/agent-substrate" >}}) runs every agent as an Actor: a sandboxed unit of compute that holds a {{< gloss "Worker" >}}Worker{{< /gloss >}} only while a turn is in progress, and whose state you can pin and branch. This example follows one agent through all three behaviors.
+The Actor that these steps follow is also the isolation boundary. Every Actor runs in its own gVisor sandbox rather than sharing one with its neighbors, which is why a model can safely run tools and execute commands. For what the sandbox blocks, see [Sandboxing]({{< link path="substrate-runtime/sandboxing" >}}).
+
## Before you begin
-1. Complete [Your first agent]({{< link path="get-started/your-first-agent" >}}). The steps on this page continues from the Harness, AgentTemplate, and AgentInstance that the agent guide creates, and assumes that you have sent the agent at least one message.
+1. Complete [Your first agent]({{< link path="get-started/your-first-agent" >}}). The steps on this page continue from the Harness, AgentTemplate, and AgentInstance that the agent guide creates, and assumes that you have sent the agent at least one message.
2. If you have not already, save the AgentInstance's ID to an environment variable. To find the ID, run `kagent get agent-instance` to list your AgentInstances and copy the value from the `ID` column.
```bash
@@ -25,43 +27,77 @@ author: kagent.dev
## Watch the Actor suspend between turns
-1. List the Actors in your namespace's {{< gloss "Atespace" >}}atespace{{< /gloss >}}. kagent names an AgentInstance's Actor `ai-`.
+1. List the Actors in your namespace's {{< gloss "Atespace" >}}atespace{{< /gloss >}}. An AgentInstance's Actor name is formatted `ai-`.
```bash
kubectl ate get actors --atespace kagent
```
- Between turns, the Actor reports `ACTOR_STATE_SUSPENDED` and holds no Worker, so the `ATEOM POD` column reads ``. Example output:
+ Between turns, the Actor reports `ACTOR_STATE_SUSPENDED` and holds no Worker, so the `ATEOM POD` column reads `` and the `ATEOM IP` column is blank. The `VERSION` column is the Actor record's revision counter, which increases each time the record is updated. Example output:
```console
- ATESPACE NAME TEMPLATE STATE ATEOM POD ATEOM IP VERSION AGE
- kagent ai-0198c3d7-4f2a-7b61-9c3e-5d8f7a2b4e10 kagent/my-first-agent-my-first-harness-5f2b3c1a9e8d ACTOR_STATE_SUSPENDED 4 6m
+ ATESPACE NAME TEMPLATE STATE ATEOM POD ATEOM IP VERSION AGE
+ kagent ai-0198c3d7-4f2a-7b61-9c3e-5d8f7a2b4e10 kagent/my-first-agent-my-first-harness-5f2b3c1a9e8d ACTOR_STATE_SUSPENDED 4 11m
```
- That Actor is also the isolation boundary. Every Actor runs in its own gVisor sandbox rather than sharing one with its neighbors, which is what makes it safe to let a model run tools and execute commands. For what the sandbox blocks, see [Sandboxing]({{< link path="substrate-runtime/sandboxing" >}}).
-
2. Send the agent another message. Nothing in the command acknowledges that the Actor was suspended, because resuming is automatic.
```bash
kagent invoke --agent-instance $INSTANCE_ID --task "Summarize this conversation so far."
```
-3. List the Actors again while the turn is running, and the same Actor reports `ACTOR_STATE_RUNNING` against a real Worker pod. Once the turn finishes it returns to `ACTOR_STATE_SUSPENDED`.
+3. From a second terminal, list the Actors again while the turn is still running.
+ ```bash
+ kubectl ate get actors --atespace kagent
+ ```
+
+ The same Actor now reports `ACTOR_STATE_RUNNING`, names the Worker pod that it resumed onto, and carries a higher `VERSION`. Example output:
+ ```console
+ ATESPACE NAME TEMPLATE STATE ATEOM POD ATEOM IP VERSION AGE
+ kagent ai-0198c3d7-4f2a-7b61-9c3e-5d8f7a2b4e10 kagent/my-first-agent-my-first-harness-5f2b3c1a9e8d ACTOR_STATE_RUNNING kagent/kagent-default-7c9f8b6d54-x2n4p 10.244.1.37 6 12m
+ ```
+
+ If the listing already reads `ACTOR_STATE_SUSPENDED`, the turn finished before the command ran. Repeat steps 2 and 3 to catch the Actor mid-turn. A turn is short, and the two transitions on either side of one, `ACTOR_STATE_RESUMING` and `ACTOR_STATE_SUSPENDING`, pass quickly enough that a single listing rarely catches them.
+
+4. After the turn finishes, list the Actors again.
```bash
kubectl ate get actors --atespace kagent
```
-The AgentInstance stays `READY` throughout all of this. Suspension is a property of the Actor underneath the conversation, not of the conversation, which is why a suspended agent is still listed and still readable. For the full cycle, see [Suspend and resume]({{< link path="substrate-runtime/suspend-and-resume" >}}).
+ The Actor is back to `ACTOR_STATE_SUSPENDED` and holds no Worker again, at a higher `VERSION` than the listing in step 1. The `NAME` and `AGE` columns confirm that this is the same Actor throughout, rather than a new one per turn. Example output:
+ ```console
+ ATESPACE NAME TEMPLATE STATE ATEOM POD ATEOM IP VERSION AGE
+ kagent ai-0198c3d7-4f2a-7b61-9c3e-5d8f7a2b4e10 kagent/my-first-agent-my-first-harness-5f2b3c1a9e8d ACTOR_STATE_SUSPENDED 8 13m
+ ```
+
+5. Check the AgentInstance while its Actor is suspended.
+ ```bash
+ kagent get agent-instance
+ ```
+
+ The AgentInstance reports `READY`, even though the Actor that runs it holds no Worker. Example output:
+ ```console
+ +--------------------------------------+----------------+------------------+-------+----------------------+
+ | ID | AGENT TEMPLATE | HARNESS | STATE | CREATED |
+ +--------------------------------------+----------------+------------------+-------+----------------------+
+ | 0198c3d7-4f2a-7b61-9c3e-5d8f7a2b4e10 | my-first-agent | my-first-harness | READY | 2026-08-31T15:02:10Z |
+ +--------------------------------------+----------------+------------------+-------+----------------------+
+ ```
+
+The AgentInstance stays `READY` throughout all steps. A suspended agent remains listed and readable because suspension is a property of the Actor underneath the conversation, not of the conversation itself. For the full cycle, see [Suspend and resume]({{< link path="substrate-runtime/suspend-and-resume" >}}).
+
+> [!NOTE]
+> Two objects report state on this page, and each interface names its states differently. `kubectl ate get actors` reports the Actor's state in full, such as `ACTOR_STATE_SUSPENDED`, because the command prints the Agent Substrate enum name. The kagent CLI trims the prefix from the AgentInstance's state and prints `READY`, and the same value reaches you as `AGENT_INSTANCE_STATE_READY` in a `grpcurl` response. Checkpoints have no CLI command yet, so the next section calls the API directly and reads the checkpoint's state in full, as `CHECKPOINT_STATE_READY`.
## Pin the conversation with a checkpoint
-Each suspend writes a snapshot, and Agent Substrate is free to collect that snapshot once a newer one supersedes it. A {{< gloss "Checkpoint" >}}checkpoint{{< /gloss >}} pins one so that you can come back to it.
+Each suspend writes a snapshot, and Agent Substrate is free to collect that snapshot once a newer one supersedes it. A {{< gloss "Checkpoint" >}}checkpoint{{< /gloss >}} pins a snapshot so that you can come back to it.
-1. Create a checkpoint. The `requestId` field is a required idempotency key of 1 to 128 characters, so reusing it returns the same checkpoint rather than creating a second one.
+1. Create a checkpoint. The checkpoint records the snapshot it pinned and how far the transcript had advanced. The `requestId` field is a required idempotency key of 1 to 128 characters, so reusing it returns the same checkpoint rather than creating a second one.
```bash
grpcurl -plaintext \
-d '{"namespace":"kagent","agentInstanceId":"'"$INSTANCE_ID"'","requestId":"'"$(uuidgen)"'"}' \
localhost:8084 kagent.api.v1alpha1.CheckpointService/CreateCheckpoint
```
- The checkpoint records the snapshot it pinned and how far the transcript had advanced. Example output:
+ Example output:
```json
{
"checkpoint": {
@@ -76,7 +112,10 @@ Each suspend writes a snapshot, and Agent Substrate is free to collect that snap
}
```
-2. Save the checkpoint's `id`, to fork from it in the next section.
+ > [!NOTE]
+ > A checkpoint captures a turn boundary, so two conditions must hold: the AgentInstance must be `READY` with no lifecycle operation in flight, and at least one turn must have reached a quiescent state. A request that fails either one reports `AgentInstance has no quiescent turn boundary`. Send the request again once the turn finishes.
+
+2. Save the checkpoint's `id` to fork from it in the next section.
```bash
export CHECKPOINT_ID=
```
@@ -88,10 +127,7 @@ Each suspend writes a snapshot, and Agent Substrate is free to collect that snap
localhost:8084 kagent.api.v1alpha1.CheckpointService/ListCheckpoints
```
-Underneath, the checkpoint attaches an ActorSnapshotTag named `checkpoint-` to the snapshot, and Agent Substrate does not collect a snapshot while a tag names it. You can see the tag with `kubectl ate get actor-snapshot-tag`.
-
-> [!NOTE]
-> A checkpoint captures a turn boundary, so two conditions have to hold and a request that fails either one reports `AgentInstance has no quiescent turn boundary`. The AgentInstance must be `READY` with no lifecycle operation in flight, and at least one turn must have reached a quiescent state. Send the request again once the turn finishes.
+Underneath, the checkpoint attaches an ActorSnapshotTag named `checkpoint-` to the snapshot, and Agent Substrate does not collect a snapshot while a tag names it. You can see the tag by running `kubectl ate get actor-snapshot-tag`.
## Fork the conversation into a second agent
@@ -131,11 +167,21 @@ Forking creates a second AgentInstance that starts from the pinned snapshot, wit
The fork answers from the transcript it inherited, which is what distinguishes a fork from a new AgentInstance that happens to use the same AgentTemplate.
-3. List your AgentInstances, and both branches appear, each with its own Actor.
+3. List your AgentInstances to verify that both branches appear as separate conversations.
```bash
kagent get agent-instance
```
+ The two rows share an AgentTemplate and a Harness, and differ in their IDs and creation times. Each one has its own Actor, named `ai-`. Example output:
+ ```console
+ +--------------------------------------+----------------+------------------+-------+----------------------+
+ | ID | AGENT TEMPLATE | HARNESS | STATE | CREATED |
+ +--------------------------------------+----------------+------------------+-------+----------------------+
+ | 0198c3d7-4f2a-7b61-9c3e-5d8f7a2b4e10 | my-first-agent | my-first-harness | READY | 2026-08-31T15:02:10Z |
+ | 0198c3e5-1d62-7f38-a904-8b3c7e2f5d16 | my-first-agent | my-first-harness | READY | 2026-08-31T15:14:02Z |
+ +--------------------------------------+----------------+------------------+-------+----------------------+
+ ```
+
A fork runs the compiled revision that its checkpoint was taken on, not whatever revision the AgentTemplate resolves to now. Editing the AgentTemplate after checkpointing does not change what a fork of that checkpoint runs, which is what makes a fork a faithful continuation rather than a fresh start with an old transcript.
> [!NOTE]
@@ -143,23 +189,16 @@ A fork runs the compiled revision that its checkpoint was taken on, not whatever
## Clean up
-1. Delete the checkpoint. Deleting removes the ActorSnapshotTag and releases the pin, and Agent Substrate can collect the snapshot once no tag names it.
+1. Delete the checkpoint. Deleting removes the ActorSnapshotTag and releases the pin, and Agent Substrate can collect the snapshot whenever no tag names it.
```bash
grpcurl -plaintext \
-d '{"namespace":"kagent","checkpointId":"'"$CHECKPOINT_ID"'"}' \
localhost:8084 kagent.api.v1alpha1.CheckpointService/DeleteCheckpoint
```
-2. Delete both AgentInstances.
+2. Delete the fork. A fork is an AgentInstance in its own right, so deleting the checkpoint that it started from does not remove it.
```bash
kagent delete agent-instance $FORK_ID
- kagent delete agent-instance $INSTANCE_ID
- ```
-
-3. Delete the AgentTemplate and the Harness.
- ```bash
- kubectl delete agenttemplate my-first-agent -n kagent
- kubectl delete harness my-first-harness -n kagent
```
## Next steps
From ada03932f5ee0ad2f1d576a7470fb944b92624e5 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Mon, 31 Aug 2026 15:08:19 -0500
Subject: [PATCH 34/70] Phase 3 - your first MCP tool
Signed-off-by: Rachael Graham
---
.../1.x/get-started/your-first-agent.md | 11 +-
.../1.x/get-started/your-first-mcp-tool.md | 191 ++++++++++++++++++
2 files changed, 200 insertions(+), 2 deletions(-)
create mode 100644 docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md
diff --git a/docs-site/content/kagent/1.x/get-started/your-first-agent.md b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
index 9eb4e4eb..6d22f3b8 100644
--- a/docs-site/content/kagent/1.x/get-started/your-first-agent.md
+++ b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
@@ -151,9 +151,16 @@ The `invoke` command takes a few more options that are useful beyond a first con
## Clean up
-1. Delete the AgentInstance. Deleting the Harness and the AgentTemplate does not delete the AgentInstances that you created from them, so delete the AgentInstance first.
+> [!IMPORTANT]
+> Other guides build on the Harness, AgentTemplate, and AgentInstance that you created here, including [Your first MCP tool]({{< link path="get-started/your-first-mcp-tool" >}}) and [Agent Substrate]({{< link path="examples/agent-substrate" >}}). Leave the resources in place unless you are finished with the kagent guides.
+
+To remove the resources, follow these steps.
+
+1. Delete every AgentInstance that was created from the AgentTemplate. Later guides create their own instances from the same pair, so delete them all rather than only the one that you saved. Deleting the Harness and the AgentTemplate does not delete the AgentInstances that you created from them, so delete the instances first.
```bash
- kagent delete agent-instance $INSTANCE_ID
+ kagent get agent-instance -o json \
+ | jq -r '.agentInstances[] | select(.agentTemplate.name == "my-first-agent") | .id' \
+ | xargs -n1 kagent delete agent-instance
```
2. Delete the AgentTemplate and the Harness.
diff --git a/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md b/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md
new file mode 100644
index 00000000..f8f582b5
--- /dev/null
+++ b/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md
@@ -0,0 +1,191 @@
+---
+title: Your first MCP tool
+description: Give an agent a Model Context Protocol tool by binding an MCP server to its AgentTemplate.
+weight: 20
+author: kagent.dev
+---
+
+A system prompt tells an agent how to behave. Tools tell it what it can do. This guide binds a Model Context Protocol (MCP) tool to the agent that you built in [Your first agent]({{< link path="get-started/your-first-agent" >}}), so that the agent can read live data out of your cluster instead of answering from the model alone. For the full tool binding schema, including binding one agent as another agent's tool, see [About tools]({{< link path="skills-and-mcp/about-tools" >}}).
+
+## Before you begin
+
+1. Complete [Your first agent]({{< link path="get-started/your-first-agent" >}}). This guide edits the `my-first-agent` AgentTemplate that the agent guide creates, so keep that AgentTemplate and the `my-first-harness` Harness in place.
+
+2. Confirm that you have the kagent CLI and [`jq`](https://jqlang.org/download/) installed.
+
+## Bind the tool to your AgentTemplate
+
+kagent ships an MCP server of its own, and installs a `RemoteMCPServer` that points at it, so the built-in server is the shortest path to a working tool. An {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}} takes tools through an `mcp` binding, which names one server and the tools to take from it. Naming the tools is required, because a binding never takes a server's whole catalog.
+
+The names must come from the server's own documentation rather than from the cluster, because kagent does not populate a server's discovered tools. This guide binds `k8s_get_resources` and `k8s_get_pod_logs`. For the full catalog that the built-in server serves, see the [tools ecosystem reference]({{< link path="reference/tools-ecosystem" >}}).
+
+1. List the RemoteMCPServers in the `kagent` namespace.
+ ```bash
+ kubectl get remotemcpserver -n kagent
+ ```
+
+ Example output: The `ACCEPTED` column is empty because kagent does not yet write status back to a RemoteMCPServer. An empty column is expected, and does not mean that the server is unhealthy.
+ ```console
+ NAME PROTOCOL URL ACCEPTED AGE
+ kagent-tool-server STREAMABLE_HTTP http://kagent-tools.kagent:8084/mcp 14m
+ ```
+
+ > [!NOTE]
+ > The built-in server is installed only when the `kagent-tools.enabled` Helm value is `true`, which is the default. If the command returns no resources, either re-install with that value enabled, or use your own server as described in [Bind your own MCP server](#bind-your-own-mcp-server).
+
+2. Re-apply the `my-first-agent` AgentTemplate with a `spec.tools` list and a system prompt that tells the model what the tools are for.
+ ```yaml
+ kubectl apply -f - < [!WARNING]
+ > kagent resolves the server, but it does not check the tool names against the tools that the server actually serves. A misspelled tool name compiles into a ready revision, and the only symptom is an agent that never calls the tool that you expected. Check the spelling against the server's catalog when a bound tool appears to be missing.
+
+## Create an AgentInstance that has the tool
+
+An {{< gloss "AgentInstance" >}}AgentInstance{{< /gloss >}} runs the revision that it was created from, and keeps running that revision for its whole life. The instance from the agent guide still runs the revision without tools, so create a second instance to pick up the binding.
+
+1. Create a second AgentInstance from the same Harness and AgentTemplate pair. The command is the one that you ran in the agent guide, but the pair has a newer revision now, so this instance picks up the tools.
+ ```bash
+ kagent create agent-instance --harness my-first-harness --agent-template my-first-agent
+ ```
+
+ Example output:
+ ```console
+ +--------------------------------------+----------------+------------------+-------+----------------------+
+ | ID | AGENT TEMPLATE | HARNESS | STATE | CREATED |
+ +--------------------------------------+----------------+------------------+-------+----------------------+
+ | 0198c4e2-8b3f-7d45-a1c6-9e2f4b8d6a03 | my-first-agent | my-first-harness | READY | 2026-08-31T16:20:38Z |
+ +--------------------------------------+----------------+------------------+-------+----------------------+
+ ```
+
+2. Save the new AgentInstance's ID to an environment variable.
+ ```bash
+ export TOOL_INSTANCE_ID=$(kagent get agent-instance -o json \
+ | jq -r '[.agentInstances[] | select(.agentTemplate.name == "my-first-agent")] | sort_by(.createdAt) | last | .id')
+ echo $TOOL_INSTANCE_ID
+ ```
+
+3. Ask the agent something that it can answer only by calling a tool.
+ ```bash
+ kagent invoke --agent-instance $TOOL_INSTANCE_ID --task "Which pods are running in the kagent namespace?"
+ ```
+
+ The agent calls `k8s_get_resources` and answers from the result rather than from the model's own knowledge.
+
+4. Ask a follow-up question that uses the second tool. The AgentInstance holds the transcript of the conversation, so the agent can act on the pods that it just listed.
+ ```bash
+ kagent invoke --agent-instance $TOOL_INSTANCE_ID --task "Show me the last few log lines from the kagent controller pod."
+ ```
+
+## Bind your own MCP server
+
+A `RemoteMCPServer` points at any MCP server that the cluster can reach, whether it runs in the cluster or outside it. Create one, then bind it in the same way that you bound the built-in server.
+
+1. Apply a `RemoteMCPServer` for your own server.
+ ```yaml
+ kubectl apply -f - < [!IMPORTANT]
+> Leave the Harness, AgentTemplate, and AgentInstances in place. Other guides build on them, and [Your first agent]({{< link path="get-started/your-first-agent#clean-up-the-get-started-resources" >}}) covers removing them when you are finished with the kagent guides. Leave `kagent-tool-server` in place as well, because the kagent installation owns it.
+
+If you created a RemoteMCPServer of your own in [Bind your own MCP server](#bind-your-own-mcp-server), delete it.
+
+```bash
+kubectl delete remotemcpserver my-mcp-server -n kagent
+```
+
+## Next steps
+
+{{< cards >}}
+ {{< card link=`{{< link path="skills-and-mcp/about-tools" >}}` title="About tools" subtitle="Read the full tool binding schema, including binding one agent as another agent's tool." >}}
+ {{< card link=`{{< link path="skills-and-mcp/skills" >}}` title="Skills" subtitle="Give your agent capabilities that no MCP server provides." >}}
+ {{< card link=`{{< link path="examples/agent-substrate" >}}` title="Agent Substrate" subtitle="Watch your agent's Actor suspend between turns, then checkpoint and fork the conversation." >}}
+{{< /cards >}}
From 8da3384af76741560e44c1f5684d82c7f1360575 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Mon, 31 Aug 2026 16:32:26 -0500
Subject: [PATCH 35/70] glossary updates
Signed-off-by: Rachael Graham
---
.../kagent/1.x/about/agent-substrate.md | 6 +--
.../content/kagent/1.x/about/architecture.md | 2 +-
.../content/kagent/1.x/about/core-concepts.md | 8 ++--
.../kagent/1.x/examples/agent-substrate.md | 10 ++---
.../1.x/get-started/your-first-agent.md | 8 ++--
.../1.x/get-started/your-first-mcp-tool.md | 8 ++--
.../kagent/1.x/skills-and-mcp/about-tools.md | 4 +-
.../kagent/1.x/skills-and-mcp/plugins.md | 2 +-
.../kagent/1.x/skills-and-mcp/skills.md | 6 +--
.../1.x/substrate-runtime/sandboxing.md | 4 +-
.../substrate-runtime/suspend-and-resume.md | 4 +-
docs-site/data/glossary.yaml | 39 +++++++++++++++++++
12 files changed, 70 insertions(+), 31 deletions(-)
diff --git a/docs-site/content/kagent/1.x/about/agent-substrate.md b/docs-site/content/kagent/1.x/about/agent-substrate.md
index 29ed404c..1d6512d6 100644
--- a/docs-site/content/kagent/1.x/about/agent-substrate.md
+++ b/docs-site/content/kagent/1.x/about/agent-substrate.md
@@ -5,13 +5,13 @@ weight: 40
author: kagent.dev
---
-The [kagent architecture]({{< link path="about/architecture" >}}) page established that every {{< gloss "AgentInstance" >}}AgentInstance{{< /gloss >}} runs on an Actor. This page explains what an Actor is built from and what it runs on: the ActorTemplate that it is created from, the compute that hosts it, the atespace that identifies it, the sandbox that isolates it, and the snapshot cycle that lets it suspend when idle and resume on demand.
+The [kagent architecture]({{< link path="about/architecture" >}}) page established that every {{< gloss "AgentInstance" >}}AgentInstance{{< /gloss >}} runs on an Actor. This page explains what an Actor is built from and what it runs on: the ActorTemplate that it is created from, the compute that hosts it, the atespace that identifies it, the sandbox that isolates it, and the {{< gloss "Snapshot" >}}snapshot{{< /gloss >}} cycle that lets it suspend when idle and resume on demand.
## ActorTemplate
Every Actor is created from an **ActorTemplate**, the compiled definition that the kagent controller produces from a {{< gloss "Harness" >}}Harness{{< /gloss >}} and {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}} pair.
-What Substrate adds is enforcement. Substrate rejects any change to an ActorTemplate's spec after it is created, so immutability is a property of the resource itself rather than a convention that the controller follows. That immutability requires the controller to create a new ActorTemplate for every compiled revision instead of editing an existing one, and allows the controller to safely reclaim an old ActorTemplate once no AgentInstance references it.
+What Substrate adds is enforcement. Substrate rejects any change to an ActorTemplate's spec after it is created, so immutability is a property of the resource itself rather than a convention that the controller follows. That immutability requires the controller to create a new ActorTemplate for every compiled {{< gloss "Revision" >}}revision{{< /gloss >}} instead of editing an existing one, and allows the controller to safely reclaim an old ActorTemplate once no AgentInstance references it.
## Workers and WorkerPools
@@ -31,7 +31,7 @@ kagent names each atespace after the Kubernetes namespace of the AgentInstance w
Because an Actor often runs a model-directed agent that calls tools and executes commands, Substrate runs each Actor in an isolated sandbox rather than a plain container. A WorkerPool's `sandboxClass` field selects the sandbox technology for its Workers: [gVisor](https://gvisor.dev) or a micro-VM technology such as [Kata Containers](https://katacontainers.io). Both technologies isolate an Actor from its Worker's host kernel, and both support suspend and resume operations.
-kagent compiles every ActorTemplate to the `gvisor` class, so a kagent agent runs in a gVisor sandbox today and the micro-VM class is a Substrate capability that kagent does not yet select. Keep a WorkerPool that backs kagent Harnesses on `gvisor`. For what each class isolates, see [Sandboxing]({{< link path="substrate-runtime/sandboxing" >}}).
+kagent compiles every ActorTemplate to the `gvisor` class, so a kagent agent runs in a {{< gloss "gVisor" >}}gVisor{{< /gloss >}} sandbox today and the micro-VM class is a Substrate capability that kagent does not yet select. Keep a WorkerPool that backs kagent Harnesses on `gvisor`. For what each class isolates, see [Sandboxing]({{< link path="substrate-runtime/sandboxing" >}}).
## Suspend, snapshot, and resume
diff --git a/docs-site/content/kagent/1.x/about/architecture.md b/docs-site/content/kagent/1.x/about/architecture.md
index 59230b3a..343cfa07 100644
--- a/docs-site/content/kagent/1.x/about/architecture.md
+++ b/docs-site/content/kagent/1.x/about/architecture.md
@@ -60,7 +60,7 @@ Follow the **Kubernetes plane** first. An operator applies a Harness and an Agen
The **kagent plane** starts once that ActorTemplate exists. A caller, who may or may not be the same person as the operator, calls `CreateAgentInstance` through kagent's gRPC API. This call is governed by kagent's own authentication and authorization, not by Kubernetes RBAC. kagent creates the AgentInstance from the newest ActorTemplate that compiled successfully, and that AgentInstance runs on an {{< gloss "Actor" >}}Actor{{< /gloss >}}.
-From there, the caller holds a conversation with the AgentInstance over the A2A (Agent-to-Agent) protocol. The A2A gateway routes each request to the Actor running behind the target AgentInstance. This means that the caller only ever needs to know an AgentInstance's identity, never which Actor or {{< gloss "Worker" >}}Worker{{< /gloss >}} is behind it.
+From there, the caller holds a conversation with the AgentInstance over the {{< gloss "A2A" >}}A2A{{< /gloss >}} (Agent-to-Agent) protocol. The A2A gateway routes each request to the Actor running behind the target AgentInstance. This means that the caller only ever needs to know an AgentInstance's identity, never which Actor or {{< gloss "Worker" >}}Worker{{< /gloss >}} is behind it.
## Why two planes
diff --git a/docs-site/content/kagent/1.x/about/core-concepts.md b/docs-site/content/kagent/1.x/about/core-concepts.md
index cbf990cb..00564874 100644
--- a/docs-site/content/kagent/1.x/about/core-concepts.md
+++ b/docs-site/content/kagent/1.x/about/core-concepts.md
@@ -44,7 +44,7 @@ A **Harness** is a Kubernetes custom resource that defines _how an agent is allo
- **Runtime**: The engine that executes the agent. A Harness selects exactly one of `kagent`, `codex`, or `claude`. kagent compiles only the `kagent` runtime, which runs kagent's own Go and Python engines.
- **Workload**: The container image and environment the runtime runs in.
-- **Substrate policy**: The [WorkerPool]({{< link path="about/agent-substrate#workers-and-workerpools" >}}) that the Harness's Actors are scheduled onto, and where their snapshots are stored.
+- **Substrate policy**: The [WorkerPool]({{< link path="about/agent-substrate#workers-and-workerpools" >}}) that the Harness's Actors are scheduled onto, and where their {{< gloss "Snapshot" >}}snapshots{{< /gloss >}} are stored.
- **Allowed AgentTemplates**: A selector that names which AgentTemplates are permitted to run on this Harness.
That last point is a one-way match, not a mutual handshake. An AgentTemplate has no field naming a Harness. Instead, a Harness's `allowedAgentTemplates` selector matches on labels, and any AgentTemplate in the same namespace carrying a matching label becomes eligible to run on it. Whoever controls a Harness's selector decides which AgentTemplates it accepts.
@@ -65,7 +65,7 @@ An **AgentTemplate** is a Kubernetes custom resource that defines _what an agent
- **Model configuration**: The large language model (LLM) provider and model the agent uses. This is the only field an AgentTemplate strictly requires.
- **System prompt**: A literal prompt, or a Go-templated one that can `include` shared ConfigMaps.
-- **Tools**: A list of tool bindings the agent can call. Each binding is either a Model Context Protocol (MCP) server, or another AgentTemplate used as an agent tool (see [Agent tools](#agent-tools-shared-vs-dedicated)).
+- **Tools**: A list of {{< gloss "Tool binding" >}}tool bindings{{< /gloss >}} that the agent can call. Each binding is either a {{< gloss "Model Context Protocol" >}}Model Context Protocol{{< /gloss >}} (MCP) server, or another AgentTemplate used as an agent tool (see [Agent tools](#agent-tools-shared-vs-dedicated)).
- **Skills** and **plugins**: Reusable capability packages, sourced from an Open Container Initiative (OCI) registry, Git, or S3.
An AgentTemplate does nothing on its own. It becomes runnable once it is paired with a Harness whose `allowedAgentTemplates` selector accepts it.
@@ -83,11 +83,11 @@ This split is deliberate, not an implementation detail to work around:
Under the hood, the kagent controller watches for valid Harness and AgentTemplate pairs and compiles each pair into an `ActorTemplate`, a Substrate resource that holds everything Substrate needs to start an Actor.
-Each compile produces one **revision**, identified by a digest: a SHA-256 hash of the compiled configuration. Because that digest is derived from the configuration itself, editing a Harness or AgentTemplate compiles to a different digest, and therefore becomes a separate ActorTemplate. kagent never rewrites an existing one.
+Each compile produces one **{{< gloss "Revision" >}}revision{{< /gloss >}}**, identified by a digest: a SHA-256 hash of the compiled configuration. Because that digest is derived from the configuration itself, editing a Harness or AgentTemplate compiles to a different digest, and therefore becomes a separate ActorTemplate. kagent never rewrites an existing one.
That immutability is what keeps running conversations stable. When you create an AgentInstance, kagent looks up the newest revision that compiled successfully for that Harness and AgentTemplate pair, and then creates an Actor from that revision. Editing the Harness or AgentTemplate afterward does not disturb that AgentInstance, which keeps running on the revision that it was created from. Only AgentInstances created after the edit use the new revision.
-Once created, an AgentInstance talks to callers over the A2A (Agent-to-Agent) protocol, through kagent's A2A gateway. The gateway resolves each request to the right AgentInstance and forwards it to the Actor running behind it.
+Once created, an AgentInstance talks to callers over the {{< gloss "A2A" >}}A2A{{< /gloss >}} (Agent-to-Agent) protocol, through kagent's A2A gateway. The gateway resolves each request to the right AgentInstance and forwards it to the Actor running behind it.
For the AgentInstance gRPC service definition, see the [API reference]({{< link path="reference/api-ref" >}}).
diff --git a/docs-site/content/kagent/1.x/examples/agent-substrate.md b/docs-site/content/kagent/1.x/examples/agent-substrate.md
index a9360582..e07ed813 100644
--- a/docs-site/content/kagent/1.x/examples/agent-substrate.md
+++ b/docs-site/content/kagent/1.x/examples/agent-substrate.md
@@ -7,7 +7,7 @@ author: kagent.dev
[Agent Substrate]({{< link path="about/agent-substrate" >}}) runs every agent as an Actor: a sandboxed unit of compute that holds a {{< gloss "Worker" >}}Worker{{< /gloss >}} only while a turn is in progress, and whose state you can pin and branch. This example follows one agent through all three behaviors.
-The Actor that these steps follow is also the isolation boundary. Every Actor runs in its own gVisor sandbox rather than sharing one with its neighbors, which is why a model can safely run tools and execute commands. For what the sandbox blocks, see [Sandboxing]({{< link path="substrate-runtime/sandboxing" >}}).
+The Actor that these steps follow is also the isolation boundary. Every Actor runs in its own {{< gloss "gVisor" >}}gVisor{{< /gloss >}} sandbox rather than sharing one with its neighbors, which is why a model can safely run tools and execute commands. For what the sandbox blocks, see [Sandboxing]({{< link path="substrate-runtime/sandboxing" >}}).
## Before you begin
@@ -18,7 +18,7 @@ The Actor that these steps follow is also the isolation boundary. Every Actor ru
export INSTANCE_ID=
```
-3. Install [grpcurl](https://github.com/fullstorydev/grpcurl), and confirm that your kagent installation sets `controller.grpc.reflection`. Checkpoints and forks have no kagent CLI commands yet, so this example calls `CheckpointService` directly.
+3. Install [grpcurl](https://github.com/fullstorydev/grpcurl), and confirm that your kagent installation sets `controller.grpc.reflection`. Checkpoints and {{< gloss "Fork" >}}forks{{< /gloss >}} have no kagent CLI commands yet, so this example calls `CheckpointService` directly.
4. Port-forward the controller's gRPC port to your local machine.
```bash
@@ -88,9 +88,9 @@ The AgentInstance stays `READY` throughout all steps. A suspended agent remains
## Pin the conversation with a checkpoint
-Each suspend writes a snapshot, and Agent Substrate is free to collect that snapshot once a newer one supersedes it. A {{< gloss "Checkpoint" >}}checkpoint{{< /gloss >}} pins a snapshot so that you can come back to it.
+Each suspend writes a {{< gloss "Snapshot" >}}snapshot{{< /gloss >}}, and Agent Substrate is free to collect that snapshot once a newer one supersedes it. A {{< gloss "Checkpoint" >}}checkpoint{{< /gloss >}} pins a snapshot so that you can come back to it.
-1. Create a checkpoint. The checkpoint records the snapshot it pinned and how far the transcript had advanced. The `requestId` field is a required idempotency key of 1 to 128 characters, so reusing it returns the same checkpoint rather than creating a second one.
+1. Create a checkpoint. The checkpoint records the snapshot that it pinned and how far the {{< gloss "Transcript" >}}transcript{{< /gloss >}} had advanced. The `requestId` field is a required idempotency key of 1 to 128 characters, so reusing it returns the same checkpoint rather than creating a second one.
```bash
grpcurl -plaintext \
-d '{"namespace":"kagent","agentInstanceId":"'"$INSTANCE_ID"'","requestId":"'"$(uuidgen)"'"}' \
@@ -182,7 +182,7 @@ Forking creates a second AgentInstance that starts from the pinned snapshot, wit
+--------------------------------------+----------------+------------------+-------+----------------------+
```
-A fork runs the compiled revision that its checkpoint was taken on, not whatever revision the AgentTemplate resolves to now. Editing the AgentTemplate after checkpointing does not change what a fork of that checkpoint runs, which is what makes a fork a faithful continuation rather than a fresh start with an old transcript.
+A fork runs the compiled {{< gloss "Revision" >}}revision{{< /gloss >}} that its checkpoint was taken on, not whatever revision the AgentTemplate resolves to now. Editing the AgentTemplate after checkpointing does not change what a fork of that checkpoint runs, which is what makes a fork a faithful continuation rather than a fresh start with an old transcript.
> [!NOTE]
> A checkpoint can only be forked when its snapshot captured durable data alone. kagent compiles every ActorTemplate to take a `Data`-scope snapshot on commit, so a checkpoint taken on a suspended AgentInstance is forkable. A checkpoint whose snapshot also captured process state is rejected with `Checkpoint includes process state and cannot be forked`, because process memory belongs to the one Actor that produced it.
diff --git a/docs-site/content/kagent/1.x/get-started/your-first-agent.md b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
index 6d22f3b8..ba21f692 100644
--- a/docs-site/content/kagent/1.x/get-started/your-first-agent.md
+++ b/docs-site/content/kagent/1.x/get-started/your-first-agent.md
@@ -49,7 +49,7 @@ This guide walks you through creating an agent, from applying a Harness and an A
> [!NOTE]
> An `AgentTemplate` has no field naming this Harness. The `kagent.dev/harness: my-first-harness` selector is a convention that this guide uses to match the `kagent.dev/harness` label in the next step. However, you can choose any label key and value, as long as the Harness selector and the AgentTemplate's labels match.
-2. Apply an `AgentTemplate` that is labeled to match the Harness's `allowedAgentTemplates` selector. The `modelConfig` field references the `default-model-config` ModelConfig that was automatically created for the model provider API key that you provided during kagent installation.
+2. Apply an `AgentTemplate` that is labeled to match the Harness's `allowedAgentTemplates` selector. The `modelConfig` field references the `default-model-config` {{< gloss "ModelConfig" >}}ModelConfig{{< /gloss >}} that was automatically created for the model provider API key that you provided during kagent installation.
```yaml
apiVersion: kagent.dev/v1alpha3
kind: AgentTemplate
@@ -67,7 +67,7 @@ This guide walks you through creating an agent, from applying a Harness and an A
systemPrompt: You are a concise, helpful assistant.
```
-3. Confirm that the pair is ready. The `HARNESS` column lists each Harness that admitted this AgentTemplate, and `READY` reports whether kagent compiled a runtime revision for that pairing.
+3. Confirm that the pair is ready. The `HARNESS` column lists each Harness that admitted this AgentTemplate, and `READY` reports whether kagent compiled a runtime {{< gloss "Revision" >}}revision{{< /gloss >}} for that pairing.
```bash
kagent get agent-template my-first-agent
```
@@ -117,7 +117,7 @@ An AgentInstance is one running conversation. Creating it starts an Actor on the
## Talk to your agent
-1. Send a message to the AgentInstance. The CLI holds the conversation over the A2A (Agent-to-Agent) protocol.
+1. Send a message to the AgentInstance. The CLI holds the conversation over the {{< gloss "A2A" >}}A2A{{< /gloss >}} (Agent-to-Agent) protocol.
```bash
kagent invoke --agent-instance $INSTANCE_ID --task "What is 2+2?"
```
@@ -127,7 +127,7 @@ An AgentInstance is one running conversation. Creating it starts an Actor on the
4
```
-2. Send a follow-up message to the same AgentInstance. An AgentInstance holds the transcript of its conversation, so the agent answers with the earlier turns in context.
+2. Send a follow-up message to the same AgentInstance. An AgentInstance holds the {{< gloss "Transcript" >}}transcript{{< /gloss >}} of its conversation, so the agent answers with the earlier turns in context.
```bash
kagent invoke --agent-instance $INSTANCE_ID --task "What did I just ask you?"
```
diff --git a/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md b/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md
index f8f582b5..4fca8229 100644
--- a/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md
+++ b/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md
@@ -5,7 +5,7 @@ weight: 20
author: kagent.dev
---
-A system prompt tells an agent how to behave. Tools tell it what it can do. This guide binds a Model Context Protocol (MCP) tool to the agent that you built in [Your first agent]({{< link path="get-started/your-first-agent" >}}), so that the agent can read live data out of your cluster instead of answering from the model alone. For the full tool binding schema, including binding one agent as another agent's tool, see [About tools]({{< link path="skills-and-mcp/about-tools" >}}).
+A system prompt tells an agent how to behave. Tools tell it what it can do. This guide binds a {{< gloss "Model Context Protocol" >}}Model Context Protocol{{< /gloss >}} (MCP) tool to the agent that you built in [Your first agent]({{< link path="get-started/your-first-agent" >}}), so that the agent can read live data out of your cluster instead of answering from the model alone. For the full {{< gloss "Tool binding" >}}tool binding{{< /gloss >}} schema, including binding one agent as another agent's tool, see [About tools]({{< link path="skills-and-mcp/about-tools" >}}).
## Before you begin
@@ -19,7 +19,7 @@ kagent ships an MCP server of its own, and installs a `RemoteMCPServer` that poi
The names must come from the server's own documentation rather than from the cluster, because kagent does not populate a server's discovered tools. This guide binds `k8s_get_resources` and `k8s_get_pod_logs`. For the full catalog that the built-in server serves, see the [tools ecosystem reference]({{< link path="reference/tools-ecosystem" >}}).
-1. List the RemoteMCPServers in the `kagent` namespace.
+1. List the {{< gloss "RemoteMCPServer" >}}RemoteMCPServers{{< /gloss >}} in the `kagent` namespace.
```bash
kubectl get remotemcpserver -n kagent
```
@@ -68,7 +68,7 @@ The names must come from the server's own documentation rather than from the clu
| `mcp.server.name` | The server's name. A binding resolves in the AgentTemplate's own namespace, so it cannot reach a server in another namespace. |
| `mcp.tools` | The names of the tools to bind, between 1 and 50. An AgentTemplate takes at most 50 bindings in total. |
-3. Confirm that kagent compiled a new revision for the edited AgentTemplate. Every edit produces a new desired revision, and the pair is current when the latest successful revision matches it.
+3. Confirm that kagent compiled a new {{< gloss "Revision" >}}revision{{< /gloss >}} for the edited AgentTemplate. Every edit produces a new desired revision, and the pair is current when the latest successful revision matches it.
```bash
kubectl get agenttemplate my-first-agent -n kagent \
-o jsonpath='{range .status.harnesses[*]}{.harness}{"\t"}{.desiredRevision}{"\t"}{.latestSuccessfulRevision}{"\n"}{end}'
@@ -116,7 +116,7 @@ An {{< gloss "AgentInstance" >}}AgentInstance{{< /gloss >}} runs the revision th
The agent calls `k8s_get_resources` and answers from the result rather than from the model's own knowledge.
-4. Ask a follow-up question that uses the second tool. The AgentInstance holds the transcript of the conversation, so the agent can act on the pods that it just listed.
+4. Ask a follow-up question that uses the second tool. The AgentInstance holds the {{< gloss "Transcript" >}}transcript{{< /gloss >}} of the conversation, so the agent can act on the pods that it just listed.
```bash
kagent invoke --agent-instance $TOOL_INSTANCE_ID --task "Show me the last few log lines from the kagent controller pod."
```
diff --git a/docs-site/content/kagent/1.x/skills-and-mcp/about-tools.md b/docs-site/content/kagent/1.x/skills-and-mcp/about-tools.md
index 9441fee6..fcf803db 100644
--- a/docs-site/content/kagent/1.x/skills-and-mcp/about-tools.md
+++ b/docs-site/content/kagent/1.x/skills-and-mcp/about-tools.md
@@ -5,7 +5,7 @@ weight: 10
author: kagent.dev
---
-An {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}}'s `spec.tools` list defines what an agent can do beyond its system prompt. Each entry is a **tool binding**, and every binding selects exactly one source: a Model Context Protocol (MCP) server, or another AgentTemplate used as a tool. A binding that names both, or neither, is rejected.
+An {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}}'s `spec.tools` list defines what an agent can do beyond its system prompt. Each entry is a **{{< gloss "Tool binding" >}}tool binding{{< /gloss >}}**, and every binding selects exactly one source: a {{< gloss "Model Context Protocol" >}}Model Context Protocol{{< /gloss >}} (MCP) server, or another AgentTemplate used as a tool. A binding that names both, or neither, is rejected.
- `mcp`: Binds tools from an MCP server.
- `agent`: Binds another AgentTemplate, so that the agent can hand work to it.
@@ -66,7 +66,7 @@ The isolation setting determines whether a bound agent runs inside its parent's
### What a Shared tree allows
-A `Shared` binding nests one agent inside another's runtime, so kagent constrains the shape of the resulting tree. The compiler enforces each of the following rules, and a violation surfaces as a failed revision rather than a failure at run time.
+A `Shared` binding nests one agent inside another's runtime, so kagent constrains the shape of the resulting tree. The compiler enforces each of the following rules, and a violation surfaces as a failed {{< gloss "Revision" >}}revision{{< /gloss >}} rather than a failure at run time.
- **One level of nesting.** A bound agent cannot itself bind another agent. A second consecutive binding is rejected as exceeding the kagent runtime boundary.
- **No cycles.** An AgentTemplate cannot reach itself through a chain of bindings.
diff --git a/docs-site/content/kagent/1.x/skills-and-mcp/plugins.md b/docs-site/content/kagent/1.x/skills-and-mcp/plugins.md
index 4f34fb79..41ed0f4d 100644
--- a/docs-site/content/kagent/1.x/skills-and-mcp/plugins.md
+++ b/docs-site/content/kagent/1.x/skills-and-mcp/plugins.md
@@ -5,7 +5,7 @@ weight: 30
author: kagent.dev
---
-A **plugin package** is a bundle that an AgentTemplate attaches with `spec.plugins`. The package carries skills and can also declare Model Context Protocol (MCP) servers. Packages follow the [Agent Plugins](https://agent-plugins.org) 1.0.0 format, which kagent consumes rather than defines.This page covers what a package holds and how kagent handles it. To understand how to attach a plugin package with an AgentTemplate, see [Skills]({{< link path="skills-and-mcp/skills" >}}).
+A **{{< gloss "Plugin package" >}}plugin package{{< /gloss >}}** is a bundle that an AgentTemplate attaches with `spec.plugins`. The package carries {{< gloss "Skill" >}}skills{{< /gloss >}} and can also declare {{< gloss "Model Context Protocol" >}}Model Context Protocol{{< /gloss >}} (MCP) servers. Packages follow the [Agent Plugins](https://agent-plugins.org) 1.0.0 format, which kagent consumes rather than defines. This page covers what a package holds and how kagent handles it. To understand how to attach a plugin package with an AgentTemplate, see [Skills]({{< link path="skills-and-mcp/skills" >}}).
## What a package holds
diff --git a/docs-site/content/kagent/1.x/skills-and-mcp/skills.md b/docs-site/content/kagent/1.x/skills-and-mcp/skills.md
index 6cfd1ba2..5408c813 100644
--- a/docs-site/content/kagent/1.x/skills-and-mcp/skills.md
+++ b/docs-site/content/kagent/1.x/skills-and-mcp/skills.md
@@ -5,7 +5,7 @@ weight: 20
author: kagent.dev
---
-A **skill** packages a piece of know-how that an agent can pick up: a set of instructions, together with whatever scripts or reference files those instructions depend on. An {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}} attaches skills by naming where each one comes from, and kagent fetches them and places them where the agent runtime can find them.
+A **{{< gloss "Skill" >}}skill{{< /gloss >}}** packages a piece of know-how that an agent can pick up: a set of instructions, together with whatever scripts or reference files those instructions depend on. An {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}} attaches skills by naming where each one comes from, and kagent fetches them and places them where the agent runtime can find them.
## About
@@ -13,11 +13,11 @@ A skill is a directory whose root holds a `SKILL.md` file. That file carries fro
The description is what makes a skill usable. When an agent starts, the runtime reads the front matter of every skill that is attached to it, and offers those skills to the model as tools that it can call. The model chooses a skill from its description, in the same way that it chooses any other tool. This means that a description that states plainly when to use the skill matters more than the length of the instructions behind it.
-A skill can be published on its own, or bundled with other skills in a [plugin package]({{< link path="skills-and-mcp/plugins" >}}), which can also declare Model Context Protocol (MCP) servers that kagent adds to the agent's [tools]({{< link path="skills-and-mcp/about-tools" >}}).
+A skill can be published on its own, or bundled with other skills in a [plugin package]({{< link path="skills-and-mcp/plugins" >}}), which can also declare {{< gloss "Model Context Protocol" >}}Model Context Protocol{{< /gloss >}} (MCP) servers that kagent adds to the agent's [tools]({{< link path="skills-and-mcp/about-tools" >}}).
## Attach skills to an AgentTemplate
-An AgentTemplate attaches skills in two ways, and it can use both at once. Use `spec.skills` for a standalone skill, and `spec.plugins` for a plugin package.
+An AgentTemplate attaches skills in two ways, and it can use both at once. Use `spec.skills` for a standalone skill, and `spec.plugins` for a {{< gloss "Plugin package" >}}plugin package{{< /gloss >}}.
```yaml
apiVersion: kagent.dev/v1alpha3
diff --git a/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md b/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
index d919773b..f1b7773a 100644
--- a/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
+++ b/docs-site/content/kagent/1.x/substrate-runtime/sandboxing.md
@@ -75,8 +75,8 @@ spec:
The sandbox draws a boundary in three places.
-- **Process and kernel**: The Actor's processes run against the sandbox runtime rather than the Worker node's kernel. A system call that the workload makes is handled by gVisor's user-space kernel, or by the guest kernel inside a micro-VM, instead of reaching the host directly.
-- **Filesystem**: The Actor sees the filesystem assembled from its container image, plus whatever durable volume its ActorTemplate declares. Writes to the root filesystem are a layer on top of the image, captured in a `Full` snapshot and discarded by a `Data` one. For what each scope keeps, see [Suspend and resume]({{< link path="substrate-runtime/suspend-and-resume" >}}).
+- **Process and kernel**: The Actor's processes run against the sandbox runtime rather than the Worker node's kernel. A system call that the workload makes is handled by {{< gloss "gVisor" >}}gVisor{{< /gloss >}}'s user-space kernel, or by the guest kernel inside a micro-VM, instead of reaching the host directly.
+- **Filesystem**: The Actor sees the filesystem assembled from its container image, plus whatever durable volume its ActorTemplate declares. Writes to the root filesystem are a layer on top of the image, captured in a `Full` {{< gloss "Snapshot" >}}snapshot{{< /gloss >}} and discarded by a `Data` one. For what each scope keeps, see [Suspend and resume]({{< link path="substrate-runtime/suspend-and-resume" >}}).
- **Network**: The Actor does not share the Worker pod's network position. The node agent gives the active Actor a private, point-to-point virtual network inside the Worker pod, so reaching the Actor means going through Agent Substrate's own network path rather than connecting to the Worker directly.
## How traffic reaches a sandboxed Actor
diff --git a/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md b/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
index da935da6..56130369 100644
--- a/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
+++ b/docs-site/content/kagent/1.x/substrate-runtime/suspend-and-resume.md
@@ -5,7 +5,7 @@ weight: 20
author: kagent.dev
---
-An agent spends most of its life waiting. It waits on a person to reply, and it waits on a large language model (LLM) to answer. [Agent Substrate]({{< link path="about/agent-substrate" >}}) runs each agent inside an **Actor**, the unit that it suspends and resumes, and it treats that idle time as reclaimable: it suspends an idle Actor into a snapshot, frees the {{< gloss "Worker" >}}Worker{{< /gloss >}} that the Actor was running on, and restores the Actor when traffic arrives for it. This page explains what a snapshot captures, when kagent suspends an Actor, and what happens when a suspended Actor is addressed again.
+An agent spends most of its life waiting. It waits on a person to reply, and it waits on a large language model (LLM) to answer. [Agent Substrate]({{< link path="about/agent-substrate" >}}) runs each agent inside an **Actor**, the unit that it suspends and resumes, and it treats that idle time as reclaimable: it suspends an idle Actor into a {{< gloss "Snapshot" >}}snapshot{{< /gloss >}}, frees the {{< gloss "Worker" >}}Worker{{< /gloss >}} that the Actor was running on, and restores the Actor when traffic arrives for it. This page explains what a snapshot captures, when kagent suspends an Actor, and what happens when a suspended Actor is addressed again.
## Actor lifecycle operations
@@ -34,7 +34,7 @@ An {{< gloss "ActorTemplate" >}}ActorTemplate{{< /gloss >}}'s snapshot configura
Scopes describe only what a snapshot captures, and they are configured per trigger. The `onPause` setting selects what a pause captures on the node, and `onCommit` selects what a suspend uploads to snapshot storage. What `onCommit` captures must be a subset of what `onPause` captures.
-A **DurableDir volume** is the per-Actor application data surface. Its contents are preserved by the `Data` scope, so they survive a suspend and resume cycle independently of process memory. How many volumes an ActorTemplate can declare depends on its sandbox class. A `microvm` template can declare several, because they are subdirectories of a single shared filesystem. A `gvisor` template is limited to one, until gVisor accepts more than a single durable mount.
+A **DurableDir volume** is the per-Actor application data surface. Its contents are preserved by the `Data` scope, so they survive a suspend and resume cycle independently of process memory. How many volumes an ActorTemplate can declare depends on its sandbox class. A `microvm` template can declare several, because they are subdirectories of a single shared filesystem. A `gvisor` template is limited to one, until {{< gloss "gVisor" >}}gVisor{{< /gloss >}} accepts more than a single durable mount.
When an Actor resumes from a `Data`-scope snapshot, the ActorTemplate's `onResume.fromData` setting decides where the rest of the guest state comes from. The default is `ColdBoot`, which starts the containers fresh from the container image with the durable volume contents restored over them.
diff --git a/docs-site/data/glossary.yaml b/docs-site/data/glossary.yaml
index d95ee706..b790ae18 100644
--- a/docs-site/data/glossary.yaml
+++ b/docs-site/data/glossary.yaml
@@ -48,3 +48,42 @@ Worker:
WorkerPool:
short: "A Kubernetes custom resource declaring how many Workers to keep running and which sandbox class they use. An operator must provision one before any Harness can create AgentInstances."
+
+# Added when the glossary widened from Substrate and Harness-model vocabulary to
+# any important concept. Same rules apply: gloss the first instance on a page only.
+
+ModelConfig:
+ short: "A Kubernetes custom resource naming one model at one provider, along with the credentials to reach it. An AgentTemplate references one by name, and every agent compiled from that template calls the model that it names."
+
+RemoteMCPServer:
+ short: "A Kubernetes custom resource pointing at a Model Context Protocol server that the cluster can reach. It is the only server kind that an AgentTemplate tool binding accepts."
+
+Revision:
+ short: "The compiled, immutable output of one Harness and AgentTemplate pairing, identified by a content digest. An AgentInstance runs the revision it was created from for its whole life, so editing either resource affects only instances created afterward."
+
+Snapshot:
+ short: "The stored state that an Actor suspends to, held in object storage. Resuming restores the Actor from its most recent snapshot, which is what makes suspending idle agents cheap."
+
+Fork:
+ short: "A second AgentInstance created from a checkpoint, starting with the transcript and state that the checkpoint pinned. A fork inherits the checkpoint's revision, so later edits to the AgentTemplate do not change what it runs."
+
+Transcript:
+ short: "The record of an AgentInstance's conversation, held server-side and append-only. It survives the Actor suspending between turns, and a resumed runtime cannot shrink it."
+
+Skill:
+ short: "A packaged piece of know-how that an agent can pick up: a directory holding a SKILL.md file of instructions, plus any scripts or reference files those instructions use. An AgentTemplate attaches skills by naming where each one comes from."
+
+Plugin package:
+ short: "A bundle that an AgentTemplate attaches with spec.plugins, carrying skills and optionally declaring Model Context Protocol servers. Packages follow the Agent Plugins format, which kagent consumes rather than defines."
+
+Tool binding:
+ short: "One entry in an AgentTemplate's spec.tools list. Each binding selects exactly one source: tools from a Model Context Protocol server, or another AgentTemplate used as a tool."
+
+Model Context Protocol:
+ short: "An open protocol for exposing tools and resources to a model. kagent reaches an MCP server through a RemoteMCPServer resource, and an AgentTemplate binds individual tools from it."
+
+A2A:
+ short: "The Agent-to-Agent protocol, which callers and other agents use to talk to an AgentInstance. The conversation's context identifier is the AgentInstance ID, so a second message on the same ID continues the same conversation."
+
+gVisor:
+ short: "A user-space kernel that isolates a workload from the host kernel by intercepting its system calls. kagent compiles every ActorTemplate to the gvisor sandbox class."
From c31bb9671f5b7ef3cd0001403ab44ad79500682e Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Wed, 2 Sep 2026 11:07:30 -0500
Subject: [PATCH 36/70] Phase 3 - Model providers
Signed-off-by: Rachael Graham
---
.../1.x/setup/model-providers/_index.md | 6 +
.../model-providers/about-model-providers.md | 47 ++++++
.../setup/model-providers/amazon-bedrock.md | 123 +++++++++++++++
.../1.x/setup/model-providers/anthropic.md | 74 +++++++++
.../setup/model-providers/azure-ai-foundry.md | 119 ++++++++++++++
.../1.x/setup/model-providers/azure-openai.md | 92 +++++++++++
.../setup/model-providers/byo-agentgateway.md | 149 ++++++++++++++++++
.../1.x/setup/model-providers/byo-openai.md | 132 ++++++++++++++++
.../1.x/setup/model-providers/gemini.md | 74 +++++++++
.../setup/model-providers/google-vertexai.md | 34 ++++
.../1.x/setup/model-providers/ollama.md | 127 +++++++++++++++
.../1.x/setup/model-providers/openai.md | 85 ++++++++++
.../1.x/setup/model-providers/sap-ai-core.md | 73 +++++++++
.../kagent/1.x/setup/model-providers/xai.md | 65 ++++++++
14 files changed, 1200 insertions(+)
create mode 100644 docs-site/content/kagent/1.x/setup/model-providers/_index.md
create mode 100644 docs-site/content/kagent/1.x/setup/model-providers/about-model-providers.md
create mode 100644 docs-site/content/kagent/1.x/setup/model-providers/amazon-bedrock.md
create mode 100644 docs-site/content/kagent/1.x/setup/model-providers/anthropic.md
create mode 100644 docs-site/content/kagent/1.x/setup/model-providers/azure-ai-foundry.md
create mode 100644 docs-site/content/kagent/1.x/setup/model-providers/azure-openai.md
create mode 100644 docs-site/content/kagent/1.x/setup/model-providers/byo-agentgateway.md
create mode 100644 docs-site/content/kagent/1.x/setup/model-providers/byo-openai.md
create mode 100644 docs-site/content/kagent/1.x/setup/model-providers/gemini.md
create mode 100644 docs-site/content/kagent/1.x/setup/model-providers/google-vertexai.md
create mode 100644 docs-site/content/kagent/1.x/setup/model-providers/ollama.md
create mode 100644 docs-site/content/kagent/1.x/setup/model-providers/openai.md
create mode 100644 docs-site/content/kagent/1.x/setup/model-providers/sap-ai-core.md
create mode 100644 docs-site/content/kagent/1.x/setup/model-providers/xai.md
diff --git a/docs-site/content/kagent/1.x/setup/model-providers/_index.md b/docs-site/content/kagent/1.x/setup/model-providers/_index.md
new file mode 100644
index 00000000..ac0685e1
--- /dev/null
+++ b/docs-site/content/kagent/1.x/setup/model-providers/_index.md
@@ -0,0 +1,6 @@
+---
+title: Configure model providers
+description: Connect kagent to a LLM provider by creating a ModelConfig resource.
+weight: 20
+author: kagent.dev
+---
diff --git a/docs-site/content/kagent/1.x/setup/model-providers/about-model-providers.md b/docs-site/content/kagent/1.x/setup/model-providers/about-model-providers.md
new file mode 100644
index 00000000..be54a2f2
--- /dev/null
+++ b/docs-site/content/kagent/1.x/setup/model-providers/about-model-providers.md
@@ -0,0 +1,47 @@
+---
+title: About model providers
+description: Understand how a ModelConfig connects kagent to a LLM provider, and which configurations a Harness can run.
+weight: 10
+author: kagent.dev
+---
+
+A `ModelConfig` is a Kubernetes custom resource that names one model at one provider, along with the credentials to reach it. An {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}} references a {{< gloss "ModelConfig" >}}ModelConfig{{< /gloss >}} by name in its `spec.modelConfig.name` field, and every agent compiled from that template calls the model that the ModelConfig names.
+
+The kagent installation creates a `default-model-config` ModelConfig from the provider API key that you supply at install time, so a first agent needs no extra setup. Create additional ModelConfigs when you want to use a different provider, a different model, or a different set of credentials.
+
+## How a ModelConfig reaches an agent
+
+Every ModelConfig shares the same three parts, regardless of the provider that it names.
+
+| Field | Description |
+| ----- | ----------- |
+| `provider` | The provider to use. Accepted values are `OpenAI`, `Anthropic`, `AzureOpenAI`, `Ollama`, `Gemini`, `GeminiVertexAI`, `AnthropicVertexAI`, `Bedrock`, `SAPAICore`, and `Foundry`. Defaults to `OpenAI`. |
+| `model` | The model name, as the provider spells it. |
+| Provider block | A block named after the provider, such as `openAI` or `bedrock`, holding the settings that only that provider takes. An empty block is valid when the provider needs no extra settings. |
+
+Credentials come from a Kubernetes Secret in the same namespace as the ModelConfig. The `apiKeySecret` field names the Secret, and `apiKeySecretKey` names the key within that Secret. To forward the bearer token from the incoming request to the provider instead, set `apiKeyPassthrough: true`. A ModelConfig cannot set both `apiKeyPassthrough` and `apiKeySecret`. For every ModelConfig field, including its type, default, and validation rules, see the [API reference]({{< link path="reference/api-ref#modelconfigspec" >}}).
+
+**Credential files**
+
+kagent passes model credentials to an agent as environment variables. A ModelConfig that instead requires a credential **file** mounted into the agent does not compile. The AgentTemplate reports the `Compatible` condition as `False`, with the reason `UnsupportedConfiguration` and the message `ModelConfig requires volume mounts unsupported by Substrate ActorTemplate`. kagent compiles no revision from that AgentTemplate, so no agent runs from it, and any AgentInstance that already exists keeps running the last revision that compiled. Three configurations encounter this today.
+- **The Vertex AI providers.** `GeminiVertexAI` and `AnthropicVertexAI` mount the Google credentials file that `apiKeySecret` names. Leaving `apiKeySecret` unset compiles, but a Substrate Actor does not inherit cloud workload identity, so the agent still has no credentials to send. Both providers are unavailable in practice. For the alternatives, see [Google Vertex AI]({{< link path="setup/model-providers/google-vertexai" >}}).
+- **A private certificate authority (CA), on any provider.** Setting `tls.caCertSecretRef` mounts the CA bundle as a file. Every provider accepts the `tls` block, so this affects all of them, not only the Vertex AI providers. You cannot reach a provider endpoint that presents a certificate from a private CA, unless you set `tls.disableVerify: true`, which skips certificate verification entirely and belongs only in a test environment.
+- **OpenAI token exchange.** The `openAI.tokenExchange` block acquires a bearer token by reading a mounted service account file, so a ModelConfig that sets it never compiles. An OpenAI-compatible endpoint has to accept a static API key instead. See [OpenAI]({{< link path="setup/model-providers/openai" >}}).
+
+## Use a ModelConfig
+
+Reference the ModelConfig by name in an AgentTemplate. The ModelConfig must be in the same namespace as the AgentTemplate.
+
+```yaml
+apiVersion: kagent.dev/v1alpha3
+kind: AgentTemplate
+metadata:
+ name: my-agent
+ namespace: kagent
+spec:
+ modelConfig:
+ name: default-model-config
+ systemPrompt: You are a concise, helpful assistant.
+```
+
+Editing a ModelConfig produces a new compiled {{< gloss "Revision" >}}revision{{< /gloss >}} for every AgentTemplate that references it. An {{< gloss "AgentInstance" >}}AgentInstance{{< /gloss >}} keeps running the revision that it was created from, so create a new AgentInstance to pick up a changed model.
diff --git a/docs-site/content/kagent/1.x/setup/model-providers/amazon-bedrock.md b/docs-site/content/kagent/1.x/setup/model-providers/amazon-bedrock.md
new file mode 100644
index 00000000..dc3b4f34
--- /dev/null
+++ b/docs-site/content/kagent/1.x/setup/model-providers/amazon-bedrock.md
@@ -0,0 +1,123 @@
+---
+title: Amazon Bedrock
+description: Configure kagent to use models served through AWS Bedrock, with either the native Bedrock provider or its OpenAI-compatible API.
+weight: 20
+author: kagent.dev
+---
+
+Amazon Bedrock serves models from several families behind one AWS API. kagent reaches it two ways: the native `Bedrock` provider, which is the fuller integration, and Bedrock's OpenAI-compatible endpoint through the `OpenAI` provider.
+
+Prefer the native provider. Use the OpenAI-compatible path when you need the OpenAI request format, or an inference profile that only that endpoint exposes.
+
+> [!IMPORTANT]
+> Both paths authenticate with credentials from a Kubernetes Secret. Attaching an AWS IAM role to the agent, such as with [EKS IAM Roles for Service Accounts](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html), is not currently supported: an agent runs as a Substrate Actor rather than as a pod that kagent controls, so there is no per-agent ServiceAccount to attach a role to.
+
+## Before you begin
+
+1. Create an IAM user or role with permissions for Bedrock. At minimum you need `bedrock:InvokeModel` for the models that you use. For more information, see the [AWS Bedrock model access docs](https://docs.aws.amazon.com/bedrock/latest/userguide/model-access.html).
+
+2. Choose an AWS region and a Bedrock model, and confirm that your account has access to that model in that region. For the available models, see the [AWS Bedrock supported models docs](https://docs.aws.amazon.com/bedrock/latest/userguide/models-supported.html).
+
+## Native Bedrock provider
+
+1. Create a Kubernetes Secret that stores your AWS access keys. Create it in the same namespace as the AgentTemplates that use it, such as `kagent`.
+ ```bash
+ kubectl create secret generic bedrock-credentials -n kagent \
+ --from-literal AWS_ACCESS_KEY_ID= \
+ --from-literal AWS_SECRET_ACCESS_KEY=
+ ```
+
+2. Create a `ModelConfig` that uses the `Bedrock` provider.
+ ```yaml
+ kubectl apply -f - <}}).
+
+| Field | Description |
+| ----- | ----------- |
+| `region` | The AWS region that serves the model. Required. |
+| `additionalModelRequestFields` | Extra request fields to pass through to the model, as arbitrary JSON. Use this field for parameters that only one model family accepts. |
+| `promptCaching` | Whether to cache prompt prefixes across requests. Defaults to `false`. |
+| `cacheTTL` | How long a cached prefix lives, either `5m` or `1h`. Defaults to `5m`. |
+| `guardrail` | An AWS Bedrock guardrail to apply, given as an `identifier` and a `version`, with an optional `trace` of `disabled`, `enabled`, or `enabled_full`. |
+| `readTimeout` | How long to wait on a response, in seconds. |
+| `connectTimeout` | How long to wait on a connection, in seconds. |
+
+## OpenAI-compatible endpoint
+
+Bedrock also serves an [OpenAI-compatible chat completions API](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-chat-completions.html), which the `OpenAI` provider can call.
+
+1. Follow the [AWS Bedrock API keys guide](https://docs.aws.amazon.com/bedrock/latest/userguide/getting-started-api-keys.html) to create an API key, and save it as an environment variable.
+ ```bash
+ export AWS_API_KEY=
+ ```
+
+2. Create a Kubernetes Secret that stores the API key.
+ ```bash
+ kubectl create secret generic kagent-bedrock -n kagent --from-literal AWS_API_KEY=$AWS_API_KEY
+ ```
+
+3. Create a `ModelConfig` that uses the `OpenAI` provider and points at the Bedrock endpoint for your region.
+ ```yaml
+ kubectl apply -f - <.amazonaws.com/openai/v1`. |
+
+## Use the ModelConfig
+
+Reference the ModelConfig by name from an AgentTemplate in the same namespace.
+
+```yaml
+spec:
+ modelConfig:
+ name: bedrock-model-config
+```
+
+## Next steps
+
+{{< cards >}}
+ {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Create an agent that uses this model, and hold a conversation with it." >}}
+ {{< card link=`{{< link path="setup/model-providers/about-model-providers" >}}` title="About model providers" subtitle="Understand how a ModelConfig reaches a running agent." >}}
+{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/setup/model-providers/anthropic.md b/docs-site/content/kagent/1.x/setup/model-providers/anthropic.md
new file mode 100644
index 00000000..2ec6dd7a
--- /dev/null
+++ b/docs-site/content/kagent/1.x/setup/model-providers/anthropic.md
@@ -0,0 +1,74 @@
+---
+title: Anthropic
+description: Configure kagent to use Anthropic Claude models by creating a ModelConfig for the Anthropic provider.
+weight: 20
+author: kagent.dev
+---
+
+The `Anthropic` provider calls the Anthropic API directly. To reach Claude models through Google Cloud instead, see [Google Vertex AI]({{< link path="setup/model-providers/google-vertexai" >}}).
+
+## Create the ModelConfig
+
+1. Save your [Anthropic API key](https://console.anthropic.com/settings/keys) as an environment variable.
+ ```bash
+ export ANTHROPIC_API_KEY=
+ ```
+
+2. Create a Kubernetes Secret that stores the API key. Create it in the same namespace as the AgentTemplates that use it, such as `kagent`.
+ ```bash
+ kubectl create secret generic kagent-anthropic -n kagent --from-literal ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY
+ ```
+
+3. Create a `ModelConfig` that references the Secret.
+ ```yaml
+ kubectl apply -f - <}}).
+
+| Field | Description |
+| ----- | ----------- |
+| `baseUrl` | An alternative API endpoint, for a proxy or a compatible service. |
+| `maxTokens` | A cap on the tokens generated in one response. |
+| `temperature` | How much randomness the model applies when it picks the next token. |
+| `topP` | The nucleus sampling cutoff. |
+| `topK` | How many candidate tokens to sample from. |
+
+## Use the ModelConfig
+
+Reference the ModelConfig by name from an AgentTemplate in the same namespace.
+
+```yaml
+spec:
+ modelConfig:
+ name: anthropic-model-config
+```
+
+## Next steps
+
+{{< cards >}}
+ {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Create an agent that uses this model, and hold a conversation with it." >}}
+ {{< card link=`{{< link path="setup/model-providers/about-model-providers" >}}` title="About model providers" subtitle="Understand how a ModelConfig reaches a running agent." >}}
+{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/setup/model-providers/azure-ai-foundry.md b/docs-site/content/kagent/1.x/setup/model-providers/azure-ai-foundry.md
new file mode 100644
index 00000000..db9bf617
--- /dev/null
+++ b/docs-site/content/kagent/1.x/setup/model-providers/azure-ai-foundry.md
@@ -0,0 +1,119 @@
+---
+title: Azure AI Foundry
+description: Configure kagent to use models served through an Azure AI Foundry deployment.
+weight: 20
+author: kagent.dev
+---
+
+The `Foundry` provider calls a model deployment in an Azure AI Foundry resource. The chat model has to be reachable through Foundry's OpenAI-compatible chat completions API.
+
+## Create the ModelConfig
+
+1. Save your Azure AI Foundry API key as an environment variable.
+ ```bash
+ export FOUNDRY_API_KEY=
+ ```
+
+2. Create a Kubernetes Secret that stores the API key. Create it in the same namespace as the AgentTemplates that use it, such as `kagent`.
+ ```bash
+ kubectl create secret generic foundry-api-key -n kagent --from-literal api-key=$FOUNDRY_API_KEY
+ ```
+
+3. Create a `ModelConfig` for your Foundry deployment.
+ ```yaml
+ kubectl apply -f - <.cognitiveservices.azure.com/
+ deployment: gpt-4-1-nano
+ apiVersion: "2024-10-21"
+ EOF
+ ```
+
+ | Field | Description |
+ | ----- | ----------- |
+ | `apiKeySecret` | The name of the Kubernetes Secret that stores the API key, in the same namespace as this ModelConfig. |
+ | `apiKeySecretKey` | The key within that Secret that holds the API key. |
+ | `model` | The model that the deployment serves. |
+ | `provider` | The provider to use, `Foundry`. |
+ | `foundry.endpoint` | The endpoint of your Foundry account. |
+ | `foundry.deployment` | The name of the deployment within the account. This field is required. |
+ | `foundry.apiVersion` | The Foundry API version to call. Defaults to `2024-10-21`. |
+
+## Azure AI Foundry provider settings
+
+The `foundry` block takes the following settings. For every field, including its type, default, and validation rules, see the [API reference]({{< link path="reference/api-ref#foundryconfig" >}}).
+
+| Field | Description |
+| ----- | ----------- |
+| `deployment` | The deployment name within the Foundry account. Required. |
+| `endpoint` | The endpoint of the Foundry account. |
+| `endpointFrom` | Read the endpoint from a key in a ConfigMap instead of setting it inline. Use this field when the endpoint differs per environment and is published by a platform team. |
+| `apiVersion` | The Foundry API version. Defaults to `2024-10-21`. |
+
+### Read the endpoint from a ConfigMap
+
+Set `endpointFrom` in place of `endpoint` to take the endpoint from a ConfigMap in the same namespace.
+
+```yaml
+spec:
+ provider: Foundry
+ model: gpt-4.1-nano
+ apiKeySecret: foundry-api-key
+ apiKeySecretKey: api-key
+ foundry:
+ endpointFrom:
+ name: foundry-endpoint
+ key: endpoint
+ deployment: gpt-4-1-nano
+```
+
+When the named ConfigMap or key does not exist, the {{< gloss "ModelConfig" >}}ModelConfig{{< /gloss >}} reports `Accepted` as `False`. Inspect it to find which reference failed.
+
+```bash
+kubectl describe modelconfig foundry-model-config -n kagent
+```
+
+## Authentication
+
+| Configuration | Credential |
+| ------------- | ---------- |
+| `apiKeySecret` is set | The API key from the referenced Secret. |
+| `apiKeyPassthrough: true` | The bearer token from the caller's request, forwarded to Foundry as the API key. Mutually exclusive with `apiKeySecret`. |
+
+> [!WARNING]
+> **Azure Workload Identity is not currently supported.** In earlier versions of kagent, omitting the credential fields fell back to Azure Workload Identity, which depended on an annotated ServiceAccount on the agent's pod. An agent now runs as a Substrate Actor rather than as a pod that kagent controls, so there is no per-agent ServiceAccount to federate an Azure identity onto. Supply an API key instead.
+
+## Use the ModelConfig
+
+Reference the ModelConfig by name from an AgentTemplate in the same namespace.
+
+```yaml
+spec:
+ modelConfig:
+ name: foundry-model-config
+```
+
+## Troubleshooting
+
+| Symptom | Cause |
+| ------- | ----- |
+| The ModelConfig reports `Accepted` as `False` | A referenced Secret or `endpointFrom` ConfigMap does not exist, or does not hold the named key. Run `kubectl describe modelconfig` to see which one. |
+| Foundry returns `401 Unauthorized` or `403 Forbidden` | The API key does not have access to the resource. |
+| The AgentTemplate reports `Compatible` as `False` | The resolved configuration cannot run on the Harness. Read the condition message for the specific reason. |
+
+## Next steps
+
+{{< cards >}}
+ {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Create an agent that uses this model, and hold a conversation with it." >}}
+ {{< card link=`{{< link path="setup/model-providers/azure-openai" >}}` title="Azure OpenAI" subtitle="Reach OpenAI models hosted directly on Azure OpenAI." >}}
+{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/setup/model-providers/azure-openai.md b/docs-site/content/kagent/1.x/setup/model-providers/azure-openai.md
new file mode 100644
index 00000000..676de7d9
--- /dev/null
+++ b/docs-site/content/kagent/1.x/setup/model-providers/azure-openai.md
@@ -0,0 +1,92 @@
+---
+title: Azure OpenAI
+description: Configure kagent to use OpenAI models hosted on Azure by creating a ModelConfig for the AzureOpenAI provider.
+weight: 20
+author: kagent.dev
+---
+
+The `AzureOpenAI` provider calls an Azure OpenAI deployment. It differs from the [OpenAI]({{< link path="setup/model-providers/openai" >}}) provider in that it addresses a named deployment in your own Azure resource rather than a model on OpenAI's API.
+
+## Create the ModelConfig
+
+1. Save your Azure OpenAI API key as an environment variable.
+ ```bash
+ export AZURE_OPENAI_API_KEY=
+ ```
+
+2. Create a Kubernetes Secret that stores the API key. Create it in the same namespace as the AgentTemplates that use it, such as `kagent`.
+ ```bash
+ kubectl create secret generic azure-openai-api-key -n kagent --from-literal api-key=$AZURE_OPENAI_API_KEY
+ ```
+
+3. Create a `ModelConfig` for your Azure OpenAI deployment.
+ ```yaml
+ kubectl apply -f - <.openai.azure.com/
+ apiVersion: "2025-03-01-preview"
+ azureDeployment: gpt-4o-mini
+ EOF
+ ```
+
+ | Field | Description |
+ | ----- | ----------- |
+ | `apiKeySecret` | The name of the Kubernetes Secret that stores the API key, in the same namespace as this ModelConfig. |
+ | `apiKeySecretKey` | The key within that Secret that holds the API key. |
+ | `model` | The model that the deployment serves. |
+ | `provider` | The provider to use, `AzureOpenAI`. |
+ | `azureOpenAI.azureEndpoint` | The endpoint of your Azure OpenAI resource. This field is required. |
+ | `azureOpenAI.apiVersion` | The Azure OpenAI API version to call. This field is required. |
+ | `azureOpenAI.azureDeployment` | The name of the deployment within the resource. |
+
+## Azure OpenAI provider settings
+
+The `azureOpenAI` block takes the following settings. For every field, including its type, default, and validation rules, see the [API reference]({{< link path="reference/api-ref#azureopenaiconfig" >}}).
+
+| Field | Description |
+| ----- | ----------- |
+| `azureEndpoint` | The endpoint of the Azure OpenAI resource. Required. |
+| `apiVersion` | The Azure OpenAI API version. Required. |
+| `azureDeployment` | The deployment name within the resource. |
+| `azureAdToken` | A Microsoft Entra ID token to send instead of an API key. |
+| `temperature` | How much randomness the model applies when it picks the next token. |
+| `topP` | The nucleus sampling cutoff. |
+| `maxTokens` | A cap on the tokens generated in one response. |
+
+## Authentication
+
+| Configuration | Credential |
+| ------------- | ---------- |
+| `apiKeySecret` is set | The API key from the referenced Secret. |
+| `azureOpenAI.azureAdToken` is set | The Microsoft Entra ID token given in the field. |
+| `apiKeyPassthrough: true` | The bearer token from the caller's request, forwarded to Azure OpenAI as the API key. This is not Microsoft Entra ID authentication, and it is mutually exclusive with `apiKeySecret`. |
+
+> [!WARNING]
+> **Azure Workload Identity is not currently supported.** In earlier versions of kagent, omitting the credential fields fell back to Azure Workload Identity, which depended on an annotated ServiceAccount on the agent's pod. An agent now runs as a Substrate Actor rather than as a pod that kagent controls, so there is no per-agent ServiceAccount to federate an Azure identity onto. Supply a credential with one of the configurations in the preceding table.
+
+## Use the ModelConfig
+
+Reference the ModelConfig by name from an AgentTemplate in the same namespace.
+
+```yaml
+spec:
+ modelConfig:
+ name: azure-openai-model-config
+```
+
+## Next steps
+
+{{< cards >}}
+ {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Create an agent that uses this model, and hold a conversation with it." >}}
+ {{< card link=`{{< link path="setup/model-providers/azure-ai-foundry" >}}` title="Azure AI Foundry" subtitle="Reach models served through an Azure AI Foundry deployment." >}}
+{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/setup/model-providers/byo-agentgateway.md b/docs-site/content/kagent/1.x/setup/model-providers/byo-agentgateway.md
new file mode 100644
index 00000000..f3ed013f
--- /dev/null
+++ b/docs-site/content/kagent/1.x/setup/model-providers/byo-agentgateway.md
@@ -0,0 +1,149 @@
+---
+title: agentgateway
+description: Route kagent model requests through an agentgateway deployment for traffic management, observability, and security.
+weight: 20
+author: kagent.dev
+---
+
+[agentgateway](https://agentgateway.dev/docs/) is an AI-native proxy that adds traffic management, observability, and security to large language model calls. It serves an OpenAI-compatible API, so a {{< gloss "ModelConfig" >}}ModelConfig{{< /gloss >}} for agentgateway sets `provider: OpenAI` and points `openAI.baseUrl` at the Gateway service.
+
+## Set up agentgateway model routing
+
+> [!NOTE]
+> The `AgentgatewayModel` feature is experimental and disabled by default. Enable it when you install agentgateway by passing `--set agentgatewayModels.enabled=true` to the control plane Helm chart.
+
+1. Install agentgateway in your cluster, adding `--set agentgatewayModels.enabled=true` to the Helm command for the control plane. For more information, see the [agentgateway documentation](https://agentgateway.dev/docs/kubernetes/latest/setup/).
+
+2. Create a `Gateway` resource for model routing.
+ ```yaml
+ kubectl apply -f - <}}
+{{% tab name="No authentication" %}}
+When your agentgateway deployment enforces no API key authentication, the ModelConfig needs no Secret.
+
+```yaml
+kubectl apply -f - <
+ kubectl create secret generic kagent-agentgateway-key -n kagent \
+ --from-literal AGENTGATEWAY_API_KEY=$AGENTGATEWAY_API_KEY
+ ```
+
+2. Create the `ModelConfig`.
+ ```yaml
+ kubectl apply -f - <}}
+
+For every `openAI` field, including its type, default, and validation rules, see the [API reference]({{< link path="reference/api-ref#openaiconfig" >}}).
+
+## Use the ModelConfig
+
+Reference the ModelConfig by name from an AgentTemplate in the same namespace.
+
+```yaml
+spec:
+ modelConfig:
+ name: agentgateway-model-config
+```
+
+## Next steps
+
+{{< cards >}}
+ {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Create an agent that uses this model, and hold a conversation with it." >}}
+ {{< card link=`{{< link path="setup/model-providers/byo-openai" >}}` title="BYO OpenAI-compatible endpoint" subtitle="Point the OpenAI provider at any other compatible service." >}}
+{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/setup/model-providers/byo-openai.md b/docs-site/content/kagent/1.x/setup/model-providers/byo-openai.md
new file mode 100644
index 00000000..580c336a
--- /dev/null
+++ b/docs-site/content/kagent/1.x/setup/model-providers/byo-openai.md
@@ -0,0 +1,132 @@
+---
+title: BYO OpenAI-compatible endpoint
+description: Configure kagent to use any provider that serves the OpenAI API, including a self-hosted gateway in front of your own models.
+weight: 40
+author: kagent.dev
+---
+
+Many providers serve the [OpenAI API](https://platform.openai.com/docs/api-reference/introduction) rather than an API of their own. To use one, set `provider: OpenAI` and point `openAI.baseUrl` at the provider's endpoint. This is the same mechanism behind the [xAI]({{< link path="setup/model-providers/xai" >}}) and [Amazon Bedrock]({{< link path="setup/model-providers/amazon-bedrock" >}}) OpenAI-compatible paths.
+
+## Create the ModelConfig
+
+The following example uses [Cohere](https://cohere.com/), which serves an OpenAI-compatible endpoint.
+
+1. Save the API key from your provider as an environment variable.
+ ```bash
+ export PROVIDER_API_KEY=
+ ```
+
+2. Create a Kubernetes Secret that stores the API key. Create it in the same namespace as the AgentTemplates that use it, such as `kagent`.
+ ```bash
+ kubectl create secret generic kagent-my-provider -n kagent --from-literal PROVIDER_API_KEY=$PROVIDER_API_KEY
+ ```
+
+3. Create a `ModelConfig` that points at your provider's endpoint.
+ ```yaml
+ kubectl apply -f - <}}). Not every compatible provider honors every setting, so check your provider's documentation before setting one. For every `openAI` field, including its type, default, and validation rules, see the [API reference]({{< link path="reference/api-ref#openaiconfig" >}}).
+
+## Self-hosted vLLM behind a gateway
+
+A common self-hosted pattern puts an OpenAI-compatible gateway such as [Bifrost](https://github.com/maximhq/bifrost) or [LiteLLM](https://docs.litellm.ai/) in front of a [vLLM](https://docs.vllm.ai/) server, so that requests travel from kagent to the gateway to vLLM. Configure the gateway as an OpenAI-compatible provider in the same way, with two extra things to get right.
+
+### Enable tool calling in vLLM
+
+kagent sends a `tools` array with `tool_choice: "auto"` on every request. kagent's runtime registers a built-in `ask_user` tool on every agent, so that array is sent even when you bind no tools yourself. Launch vLLM with automatic tool choice enabled, or every agent turn fails.
+
+```bash
+vllm serve Qwen/Qwen2.5-7B-Instruct \
+ --enable-auto-tool-choice \
+ --tool-call-parser hermes
+```
+
+The correct `--tool-call-parser` depends on your model family. Qwen2.5 uses `hermes` and Llama 3.1 uses `llama3_json`. Parser names change across vLLM releases, so check the [vLLM tool calling docs](https://docs.vllm.ai/en/latest/features/tool_calling.html) for the current name for your model.
+
+### Use the gateway's model identifier
+
+Set `model` to the identifier that your gateway routes on, which is often provider-prefixed and can differ from the bare model name that vLLM serves internally. Point `openAI.baseUrl` at the gateway. LiteLLM defaults to port `4000`, and Bifrost to `8080`.
+
+```yaml
+spec:
+ apiKeySecret: kagent-my-provider
+ apiKeySecretKey: PROVIDER_API_KEY
+ model: vllm/Qwen/Qwen2.5-7B-Instruct
+ provider: OpenAI
+ openAI:
+ baseUrl: http://litellm.kagent.svc.cluster.local:4000/v1
+```
+
+### Troubleshooting a 400 from the provider
+
+When every agent message fails with a generic `provider API error (status 400)`, the most common cause is a vLLM server started without `--enable-auto-tool-choice` and a matching `--tool-call-parser`. Because kagent always sends `tool_choice: "auto"`, vLLM rejects the request until automatic tool choice is enabled. Restart vLLM with both flags and try again.
+
+## TLS
+
+A provider on your own network may present a certificate that the agent does not already trust. The `tls` block adjusts how the agent verifies it.
+
+| Field | Description |
+| ----- | ----------- |
+| `disableVerify` | Turns off certificate verification entirely. Defaults to `false`. |
+| `disableSystemCAs` | Trusts only the named CA bundle rather than the system trust store. Defaults to `false`. |
+| `caCertSecretRef` | The name of a Secret holding a PEM certificate authority bundle. |
+| `caCertSecretKey` | The key within that Secret that holds the bundle. |
+
+> [!WARNING]
+> **Pinning a certificate authority is not currently supported.** Setting `tls.caCertSecretRef` and `tls.caCertSecretKey` makes kagent mount the bundle as a file, and an agent running on {{< gloss "Agent Substrate" >}}Agent Substrate{{< /gloss >}} cannot mount files. The AgentTemplate reports the `Compatible` condition as `False` with the message `ModelConfig requires volume mounts unsupported by Substrate ActorTemplate`. Use a certificate that chains to a public authority, or terminate TLS at a gateway that the agent can trust.
+
+Turning verification off does not mount anything, so it does compile.
+
+```yaml
+spec:
+ apiKeySecret: kagent-my-provider
+ apiKeySecretKey: PROVIDER_API_KEY
+ model: command-a-03-2025
+ provider: OpenAI
+ openAI:
+ baseUrl: https://llm.internal.example.com/v1
+ tls:
+ disableVerify: true
+```
+
+> [!WARNING]
+> Disabling verification removes the guarantee that the agent is talking to the server that it thinks it is. Use it for local testing, never in production.
+
+## Use the ModelConfig
+
+Reference the ModelConfig by name from an AgentTemplate in the same namespace.
+
+```yaml
+spec:
+ modelConfig:
+ name: my-provider-model-config
+```
+
+## Next steps
+
+{{< cards >}}
+ {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Create an agent that uses this model, and hold a conversation with it." >}}
+ {{< card link=`{{< link path="setup/model-providers/byo-agentgateway" >}}` title="agentgateway" subtitle="Route model traffic through an agentgateway deployment." >}}
+{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/setup/model-providers/gemini.md b/docs-site/content/kagent/1.x/setup/model-providers/gemini.md
new file mode 100644
index 00000000..ab539f3b
--- /dev/null
+++ b/docs-site/content/kagent/1.x/setup/model-providers/gemini.md
@@ -0,0 +1,74 @@
+---
+title: Gemini
+description: Configure kagent to use Google Gemini models through the Google AI Studio API.
+weight: 20
+author: kagent.dev
+---
+
+The `Gemini` provider reaches Google's Gemini models through the Google AI Studio API, authenticating with a single API key. To reach Gemini through Google Cloud instead, see [Google Vertex AI]({{< link path="setup/model-providers/google-vertexai" >}}).
+
+## Before you begin
+
+Make sure that your Google Cloud account has a project with the Gemini API enabled.
+
+## Create the ModelConfig
+
+1. Get an API key from [Google AI Studio](https://ai.google.dev/), and save it as an environment variable.
+ ```bash
+ export GOOGLE_API_KEY=
+ ```
+
+2. Create a Kubernetes Secret that stores the API key. Create it in the same namespace as the AgentTemplates that use it, such as `kagent`.
+ ```bash
+ kubectl create secret generic kagent-gemini -n kagent --from-literal GOOGLE_API_KEY=$GOOGLE_API_KEY
+ ```
+
+3. Create a `ModelConfig` that references the Secret.
+ ```yaml
+ kubectl apply -f - <}}).
+
+| Field | Description |
+| ----- | ----------- |
+| `maxOutputTokens` | A cap on the tokens generated in one response. |
+
+## Use the ModelConfig
+
+Reference the ModelConfig by name from an AgentTemplate in the same namespace.
+
+```yaml
+spec:
+ modelConfig:
+ name: gemini-model-config
+```
+
+## Next steps
+
+{{< cards >}}
+ {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Create an agent that uses this model, and hold a conversation with it." >}}
+ {{< card link=`{{< link path="setup/model-providers/about-model-providers" >}}` title="About model providers" subtitle="Understand how a ModelConfig reaches a running agent." >}}
+{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/setup/model-providers/google-vertexai.md b/docs-site/content/kagent/1.x/setup/model-providers/google-vertexai.md
new file mode 100644
index 00000000..04154b3a
--- /dev/null
+++ b/docs-site/content/kagent/1.x/setup/model-providers/google-vertexai.md
@@ -0,0 +1,34 @@
+---
+title: Google Vertex AI
+description: Understand why the Google Vertex AI providers do not currently run on a kagent Harness.
+weight: 20
+author: kagent.dev
+---
+
+The `GeminiVertexAI` and `AnthropicVertexAI` providers reach Gemini and Claude models through Google Cloud Vertex AI. Both providers exist in the {{< gloss "ModelConfig" >}}ModelConfig{{< /gloss >}} schema, but neither currently runs on a kagent {{< gloss "Harness" >}}Harness{{< /gloss >}}.
+
+> [!WARNING]
+> **Vertex AI is not currently supported.** Vertex AI authenticates with a Google Application Default Credentials file rather than with an API key. When `apiKeySecret` is set, kagent mounts that credentials file into the agent, and mounting a file is not something an agent running on {{< gloss "Agent Substrate" >}}Agent Substrate{{< /gloss >}} can do. The AgentTemplate reports the `Compatible` condition as `False` with the message `ModelConfig requires volume mounts unsupported by Substrate ActorTemplate`, and no runtime {{< gloss "Revision" >}}revision{{< /gloss >}} is compiled.
+
+## Why the configuration fails
+
+kagent passes model credentials to an agent as environment variables. Every provider whose credential is a string, such as an API key, works on a Harness. Vertex AI is different: the Google credentials are a JSON file, so kagent sets `GOOGLE_APPLICATION_CREDENTIALS` to a path and mounts the Secret at that path. An agent runs as a Substrate Actor rather than as a pod that kagent controls, so there is nowhere to mount it.
+
+Omitting `apiKeySecret` avoids the mount, because kagent then expects Google credentials to be already present in the agent's environment. An Actor's sandbox does not inherit cloud workload identity from the node, so that path does not authenticate either.
+
+For the full explanation of which configurations a Harness can run, see [About model providers]({{< link path="setup/model-providers/about-model-providers" >}}).
+
+## What to use instead
+
+| Goal | Alternative |
+| ---- | ----------- |
+| Gemini models | Use the [Gemini]({{< link path="setup/model-providers/gemini" >}}) provider, which reaches the same model family through the Google AI Studio API with an API key. |
+| Claude models | Use the [Anthropic]({{< link path="setup/model-providers/anthropic" >}}) provider, or reach Claude through [Amazon Bedrock]({{< link path="setup/model-providers/amazon-bedrock" >}}). |
+| Vertex AI specifically | Route Vertex AI through a gateway that presents an OpenAI-compatible API and authenticates to Google itself, then point an [OpenAI-compatible endpoint]({{< link path="setup/model-providers/byo-openai" >}}) ModelConfig at the gateway. |
+
+## Next steps
+
+{{< cards >}}
+ {{< card link=`{{< link path="setup/model-providers/gemini" >}}` title="Gemini" subtitle="Reach Gemini models with an API key instead." >}}
+ {{< card link=`{{< link path="setup/model-providers/about-model-providers" >}}` title="About model providers" subtitle="Understand which provider configurations a Harness can run." >}}
+{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/setup/model-providers/ollama.md b/docs-site/content/kagent/1.x/setup/model-providers/ollama.md
new file mode 100644
index 00000000..a8a33d11
--- /dev/null
+++ b/docs-site/content/kagent/1.x/setup/model-providers/ollama.md
@@ -0,0 +1,127 @@
+---
+title: Ollama
+description: Configure kagent to use models that you run yourself with Ollama, in the cluster or on your own machine.
+weight: 20
+author: kagent.dev
+---
+
+[Ollama](https://ollama.com) runs large language models on hardware that you control. The `Ollama` provider points kagent at an Ollama server rather than at a hosted API, so it needs a host address instead of an API key.
+
+> [!IMPORTANT]
+> kagent agents call tools, so choose a model that supports function calling. A model without tool support connects successfully and then fails to use any tool that you bind to it.
+
+## Run Ollama in the cluster
+
+Skip this section if you already have an Ollama server that your cluster can reach.
+
+1. Create a namespace for Ollama.
+ ```bash
+ kubectl create namespace ollama
+ ```
+
+2. Create the Ollama Deployment and Service.
+ ```yaml
+ kubectl apply -f - <}}).
+
+| Field | Description |
+| ----- | ----------- |
+| `host` | The address of the Ollama server. |
+| `options` | Ollama runtime options, as a map of string keys to string values. Use this field for the parameters that Ollama accepts per request, such as `num_ctx`. |
+
+## Use the ModelConfig
+
+Reference the ModelConfig by name from an AgentTemplate in the same namespace.
+
+```yaml
+spec:
+ modelConfig:
+ name: llama3-model-config
+```
+
+> [!NOTE]
+> An agent runs inside a sandboxed Actor with controlled egress, so the Ollama server has to be reachable from the cluster network. An Ollama server on your laptop is not reachable from an agent, even when `kubectl port-forward` makes it reachable from your terminal.
+
+## Next steps
+
+{{< cards >}}
+ {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Create an agent that uses this model, and hold a conversation with it." >}}
+ {{< card link=`{{< link path="setup/model-providers/about-model-providers" >}}` title="About model providers" subtitle="Understand how a ModelConfig reaches a running agent." >}}
+{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/setup/model-providers/openai.md b/docs-site/content/kagent/1.x/setup/model-providers/openai.md
new file mode 100644
index 00000000..e2b0ba2a
--- /dev/null
+++ b/docs-site/content/kagent/1.x/setup/model-providers/openai.md
@@ -0,0 +1,85 @@
+---
+title: OpenAI
+description: Configure kagent to use OpenAI models by creating a ModelConfig for the OpenAI provider.
+weight: 10
+author: kagent.dev
+---
+
+The `OpenAI` provider calls the OpenAI API directly. It also backs every OpenAI-compatible endpoint, so several other providers in this section set `provider: OpenAI` and point `openAI.baseUrl` somewhere else.
+
+## Create the ModelConfig
+
+1. Save your [OpenAI API key](https://platform.openai.com/api-keys) as an environment variable.
+ ```bash
+ export OPENAI_API_KEY=
+ ```
+
+2. Create a Kubernetes Secret that stores the API key. Create it in the same namespace as the AgentTemplates that use it, such as `kagent`.
+ ```bash
+ kubectl create secret generic kagent-openai -n kagent --from-literal OPENAI_API_KEY=$OPENAI_API_KEY
+ ```
+
+3. Create a `ModelConfig` that references the Secret.
+ ```yaml
+ kubectl apply -f - <}}).
+
+| Field | Description |
+| ----- | ----------- |
+| `baseUrl` | An alternative API endpoint. Set this to point the OpenAI provider at an OpenAI-compatible service rather than at OpenAI. |
+| `organization` | The OpenAI organization to bill requests to. |
+| `apiFormat` | Which OpenAI HTTP API to call, either `chatCompletions` or `responses`. Defaults to `chatCompletions`. Use `responses` for gateways and models that require the Responses API. |
+| `maxTokens` | A cap on the tokens generated in one response, sent as the deprecated `max_tokens` parameter. Reasoning models reject it. Mutually exclusive with `maxCompletionTokens`. |
+| `maxCompletionTokens` | A cap on visible output plus reasoning tokens, sent as `max_completion_tokens`. Reasoning models require this field in place of `maxTokens`. Mutually exclusive with `maxTokens`. |
+| `reasoningEffort` | How many reasoning tokens the model generates before it answers. Accepted values are `none`, `minimal`, `low`, `medium`, `high`, and `xhigh`. Support varies by model, and some models require `none` to use tools through the Chat Completions API. |
+| `temperature` | How much randomness the model applies when it picks the next token. |
+| `topP` | The nucleus sampling cutoff. |
+| `frequencyPenalty` | How strongly to discourage repeating tokens that already appeared. |
+| `presencePenalty` | How strongly to discourage reusing topics that already appeared. |
+| `seed` | A fixed seed, for more repeatable output. |
+| `n` | How many completions to request. |
+| `timeout` | How long to wait on a request to the provider. |
+
+> [!WARNING]
+> The `openAI` block also accepts `tokenExchange`, which acquires a bearer token from a mounted service account file. That configuration mounts a credential file into the agent, so it does not compile on a Harness. See [About model providers]({{< link path="setup/model-providers/about-model-providers" >}}) for the full list of configurations that this affects.
+
+## Use the ModelConfig
+
+Reference the ModelConfig by name from an AgentTemplate in the same namespace.
+
+```yaml
+spec:
+ modelConfig:
+ name: openai-model-config
+```
+
+## Next steps
+
+{{< cards >}}
+ {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Create an agent that uses this model, and hold a conversation with it." >}}
+ {{< card link=`{{< link path="setup/model-providers/byo-openai" >}}` title="BYO OpenAI-compatible endpoint" subtitle="Point the OpenAI provider at a different service." >}}
+{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/setup/model-providers/sap-ai-core.md b/docs-site/content/kagent/1.x/setup/model-providers/sap-ai-core.md
new file mode 100644
index 00000000..d9e6c2e0
--- /dev/null
+++ b/docs-site/content/kagent/1.x/setup/model-providers/sap-ai-core.md
@@ -0,0 +1,73 @@
+---
+title: SAP AI Core
+description: Configure kagent to use models served through the SAP AI Core Orchestration Service.
+weight: 20
+author: kagent.dev
+---
+
+kagent reaches SAP AI Core through its [Orchestration Service](https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/orchestration), a single endpoint that serves models from several families, including Anthropic, OpenAI, Gemini, Amazon, Meta, and Mistral. Authentication uses OAuth2 client credentials from your SAP AI Core service key.
+
+## Create the ModelConfig
+
+1. Save the OAuth2 client credentials from your SAP AI Core service key as environment variables.
+ ```bash
+ export SAP_AI_CORE_CLIENT_ID=
+ export SAP_AI_CORE_CLIENT_SECRET=
+ ```
+
+2. Create a Kubernetes Secret that stores both credentials. The Secret has to contain the keys `client_id` and `client_secret` under exactly those names.
+ ```bash
+ kubectl create secret generic kagent-sapaicore -n kagent \
+ --from-literal client_id=$SAP_AI_CORE_CLIENT_ID \
+ --from-literal client_secret=$SAP_AI_CORE_CLIENT_SECRET
+ ```
+
+ > [!NOTE]
+ > SAP AI Core is the one provider that does not use `apiKeySecretKey`. kagent reads `client_id` and `client_secret` directly from the Secret that `apiKeySecret` names, so setting `apiKeySecretKey` has no effect.
+
+3. Create a `ModelConfig` that references the Secret. The endpoint, resource group, and OAuth2 token endpoint all come from your SAP AI Core service key.
+ ```yaml
+ kubectl apply -f - <.authentication.eu10.hana.ondemand.com
+ resourceGroup: default
+ EOF
+ ```
+
+ | Field | Description |
+ | ----- | ----------- |
+ | `apiKeySecret` | The name of the Kubernetes Secret that holds `client_id` and `client_secret`. |
+ | `model` | The model to use, in the Orchestration Service naming convention, such as `anthropic--claude-4.5-sonnet`, `gpt-5-mini`, or `gemini-3-pro-preview`. For the full list, see the [SAP AI Core models docs](https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/models-and-scenarios-in-generative-ai-hub). |
+ | `provider` | The provider to use, `SAPAICore`. |
+ | `sapAICore.baseUrl` | The base URL for the SAP AI Core API. This field is required. |
+ | `sapAICore.authUrl` | The OAuth2 token endpoint. |
+ | `sapAICore.resourceGroup` | The resource group within SAP AI Core. Defaults to `default`. |
+
+ For every `sapAICore` field, including its type, default, and validation rules, see the [API reference]({{< link path="reference/api-ref#sapaicoreconfig" >}}).
+
+## Use the ModelConfig
+
+Reference the ModelConfig by name from an AgentTemplate in the same namespace.
+
+```yaml
+spec:
+ modelConfig:
+ name: sapaicore-model-config
+```
+
+## Next steps
+
+{{< cards >}}
+ {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Create an agent that uses this model, and hold a conversation with it." >}}
+ {{< card link=`{{< link path="setup/model-providers/about-model-providers" >}}` title="About model providers" subtitle="Understand how a ModelConfig reaches a running agent." >}}
+{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/setup/model-providers/xai.md b/docs-site/content/kagent/1.x/setup/model-providers/xai.md
new file mode 100644
index 00000000..4e60bebd
--- /dev/null
+++ b/docs-site/content/kagent/1.x/setup/model-providers/xai.md
@@ -0,0 +1,65 @@
+---
+title: xAI
+description: Configure kagent to use xAI Grok models through xAI's OpenAI-compatible API.
+weight: 20
+author: kagent.dev
+---
+
+xAI's Grok models are served through an OpenAI-compatible API, so a {{< gloss "ModelConfig" >}}ModelConfig{{< /gloss >}} for xAI sets `provider: OpenAI` and points `openAI.baseUrl` at xAI. There is no separate xAI provider value.
+
+## Create the ModelConfig
+
+1. Save your [xAI API key](https://console.x.ai/) as an environment variable.
+ ```bash
+ export XAI_API_KEY=
+ ```
+
+2. Create a Kubernetes Secret that stores the API key. Create it in the same namespace as the AgentTemplates that use it, such as `kagent`.
+ ```bash
+ kubectl create secret generic kagent-xai -n kagent --from-literal XAI_API_KEY=$XAI_API_KEY
+ ```
+
+3. Create a `ModelConfig` that references the Secret and sets the xAI base URL.
+ ```yaml
+ kubectl apply -f - <}}). For every `openAI` field, including its type, default, and validation rules, see the [API reference]({{< link path="reference/api-ref#openaiconfig" >}}).
+
+## Use the ModelConfig
+
+Reference the ModelConfig by name from an AgentTemplate in the same namespace.
+
+```yaml
+spec:
+ modelConfig:
+ name: grok-model-config
+```
+
+## Next steps
+
+{{< cards >}}
+ {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Create an agent that uses this model, and hold a conversation with it." >}}
+ {{< card link=`{{< link path="setup/model-providers/byo-openai" >}}` title="BYO OpenAI-compatible endpoint" subtitle="Point the OpenAI provider at any other compatible service." >}}
+{{< /cards >}}
From 4a84a88132bc86657b6dc41f8aeb0ca13f13d075 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Wed, 2 Sep 2026 11:52:50 -0500
Subject: [PATCH 37/70] code updates
Signed-off-by: Rachael Graham
---
.../kagent-docs/versions/agent-substrate.md | 2 +-
.../content/kagent/1.x/about/architecture.md | 23 +++++++++++--------
.../kagent/1.x/about/what-is-kagent.md | 4 ++--
.../1.x/get-started/your-first-mcp-tool.md | 12 +++++++---
.../content/kagent/1.x/setup/installation.md | 2 +-
5 files changed, 27 insertions(+), 16 deletions(-)
diff --git a/docs-site/assets/kagent-docs/versions/agent-substrate.md b/docs-site/assets/kagent-docs/versions/agent-substrate.md
index 8ade5faa..a9de7678 100644
--- a/docs-site/assets/kagent-docs/versions/agent-substrate.md
+++ b/docs-site/assets/kagent-docs/versions/agent-substrate.md
@@ -1 +1 @@
-{{< version include-if="0.x" >}}0.0.6{{< /version >}}{{< version include-if="1.x" >}}0.0.20{{< /version >}}
\ No newline at end of file
+{{< version include-if="0.x" >}}0.0.6{{< /version >}}{{< version include-if="1.x" >}}0.0.22{{< /version >}}
\ No newline at end of file
diff --git a/docs-site/content/kagent/1.x/about/architecture.md b/docs-site/content/kagent/1.x/about/architecture.md
index 343cfa07..03bf8b18 100644
--- a/docs-site/content/kagent/1.x/about/architecture.md
+++ b/docs-site/content/kagent/1.x/about/architecture.md
@@ -25,14 +25,19 @@ flowchart TB
harness["Harness"]
template["AgentTemplate"]
controller["kagent controller"]
- actortemplate["ActorTemplate (Substrate)"]
operator --> harness
operator --> template
harness --> controller
template --> controller
- controller -->|compiles the pair into| actortemplate
end
+ %% Declared outside both subgraphs on purpose. An ActorTemplate is a Substrate
+ %% resource reached over gRPC, not a Kubernetes object, so it belongs to
+ %% neither plane. A node joins whichever subgraph first references it, so both
+ %% of its edges have to live out here too.
+ actortemplate["ActorTemplate (Substrate)"]
+ controller -->|compiles the pair into| actortemplate
+
subgraph kagentplane["kagent plane (gRPC auth)"]
caller["Caller"]
gateway["A2A gateway"]
@@ -44,19 +49,19 @@ flowchart TB
instance -->|runs on| actor
end
- %% Declared outside both subgraphs on purpose: a node belongs to whichever
- %% subgraph first references it, so putting this edge inside the kagent plane
- %% would pull ActorTemplate out of the Kubernetes plane.
actortemplate -->|instantiated as| instance
- %% Invisible link: forces the kagent plane to sit fully below the Kubernetes
- %% plane. Without it, the layout engine staggers the two planes diagonally.
- %% actortemplate ~~~ caller
+ %% Invisible link: forces the kagent plane to sit fully below the ActorTemplate,
+ %% and the ActorTemplate below the Kubernetes plane. Without it the layout engine
+ %% staggers the two planes diagonally, which both wastes width and scrambles the
+ %% reading order. Anchor it to actortemplate, not controller: anchoring higher
+ %% loses the stacking. Verified by rendering.
+ actortemplate ~~~ caller
classDef crd stroke:#a78bfa,stroke-width:2px
class harness,template crd
```
-Follow the **Kubernetes plane** first. An operator applies a Harness and an AgentTemplate, governed by Kubernetes RBAC. The kagent controller watches for a valid pair with a matching `allowedAgentTemplates` selector, and compiles it into an {{< gloss "ActorTemplate" >}}ActorTemplate{{< /gloss >}} on Substrate.
+Follow the **Kubernetes plane** first. An operator applies a Harness and an AgentTemplate, governed by Kubernetes RBAC. The kagent controller watches for a valid pair with a matching `allowedAgentTemplates` selector, and compiles it into an {{< gloss "ActorTemplate" >}}ActorTemplate{{< /gloss >}} on Substrate. The ActorTemplate sits outside both planes in the diagram because that is where it sits in reality: it is a Substrate resource that the controller creates over gRPC, not a Kubernetes object, so no Kubernetes role grants access to it.
The **kagent plane** starts once that ActorTemplate exists. A caller, who may or may not be the same person as the operator, calls `CreateAgentInstance` through kagent's gRPC API. This call is governed by kagent's own authentication and authorization, not by Kubernetes RBAC. kagent creates the AgentInstance from the newest ActorTemplate that compiled successfully, and that AgentInstance runs on an {{< gloss "Actor" >}}Actor{{< /gloss >}}.
diff --git a/docs-site/content/kagent/1.x/about/what-is-kagent.md b/docs-site/content/kagent/1.x/about/what-is-kagent.md
index 302f5259..bbd31e6e 100644
--- a/docs-site/content/kagent/1.x/about/what-is-kagent.md
+++ b/docs-site/content/kagent/1.x/about/what-is-kagent.md
@@ -5,7 +5,7 @@ weight: 10
author: kagent.dev
---
-kagent is an open-source, Kubernetes-native platform for running AI agents. It defines an agent's runtime and behavior as ordinary Kubernetes custom resources, governed by the same role-based access control (RBAC), GitOps, and observability that you already use for your other workloads, and runs each agent's conversation inside [Agent Substrate]({{< link path="about/agent-substrate" >}}), a sandboxed, suspend-and-resume compute layer built for bursty, mostly idle agent workloads. kagent works with agent frameworks such as Google's Agent Development Kit (ADK), LangGraph, and CrewAI, and with every major large language model (LLM) provider. Agents run on kagent's own Go and Python engines.
+kagent is an open-source, Kubernetes-native platform for running AI agents. It defines an agent's runtime and behavior as ordinary Kubernetes custom resources, governed by the same role-based access control (RBAC), GitOps, and observability that you already use for your other workloads, and runs each agent's conversation inside [Agent Substrate]({{< link path="about/agent-substrate" >}}), a sandboxed, suspend-and-resume compute layer built for bursty, mostly idle agent workloads. kagent works with agent frameworks such as Google's Agent Development Kit (ADK), LangGraph, and CrewAI, and with every major large language model (LLM) provider. Agents run on kagent's own Go and Python engines, on the Codex or Claude coding agents, or on an image of your own.
kagent was created at [Solo.io](https://www.solo.io) in 2025 and is a [Cloud Native Computing Foundation](https://www.cncf.io) sandbox project.
@@ -45,7 +45,7 @@ Everything works with a single `helm install`. No add-ons, no extra databases, n
{{< feature-card title="Agent lifecycle via CRDs" desc="Define, version, and roll out Harnesses and AgentTemplates with kubectl and GitOps, the same workflow as every other workload." >}}
{{< feature-card title="Sandboxed by default" desc="Every AgentInstance runs on a Substrate Actor, isolated from the host kernel by a gVisor sandbox. Run untrusted, model-directed code safely." >}}
{{< feature-card title="Suspend and resume" desc="Idle AgentInstances suspend and free their compute, then resume on demand. Run far more agents than you have capacity for at any one moment." >}}
-{{< feature-card title="Pluggable agent runtimes" desc="A Harness selects the engine behind an agent. kagent runs its own Go and Python engines, and the Harness API defines Codex and Claude runtime selectors." >}}
+{{< feature-card title="Pluggable agent runtimes" desc="A Harness selects the engine behind an agent: kagent's own Go and Python engines, the Codex or Claude coding agents, or any image of your own that speaks kagent's A2A contract." >}}
{{< feature-card title="Agent tools" desc="Compose agents from other agents. A Shared binding nests an agent inside its parent's Actor, one level deep." >}}
{{< feature-card title="Long-term memory" desc="Persistent, vector-backed memory across sessions. Agents remember context, not just the last prompt." >}}
{{< feature-card title="Human-in-the-loop" desc="Tool approval gates and agent-initiated questions keep a person in control of consequential actions." >}}
diff --git a/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md b/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md
index 4fca8229..f7a6e932 100644
--- a/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md
+++ b/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md
@@ -17,17 +17,23 @@ A system prompt tells an agent how to behave. Tools tell it what it can do. This
kagent ships an MCP server of its own, and installs a `RemoteMCPServer` that points at it, so the built-in server is the shortest path to a working tool. An {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}} takes tools through an `mcp` binding, which names one server and the tools to take from it. Naming the tools is required, because a binding never takes a server's whole catalog.
-The names must come from the server's own documentation rather than from the cluster, because kagent does not populate a server's discovered tools. This guide binds `k8s_get_resources` and `k8s_get_pod_logs`. For the full catalog that the built-in server serves, see the [tools ecosystem reference]({{< link path="reference/tools-ecosystem" >}}).
+kagent records what it discovered on the server's status, so the tool names come from the cluster. This guide binds `k8s_get_resources` and `k8s_get_pod_logs`. For the full catalog that the built-in server serves, see the [tools ecosystem reference]({{< link path="reference/tools-ecosystem" >}}).
1. List the {{< gloss "RemoteMCPServer" >}}RemoteMCPServers{{< /gloss >}} in the `kagent` namespace.
```bash
kubectl get remotemcpserver -n kagent
```
- Example output: The `ACCEPTED` column is empty because kagent does not yet write status back to a RemoteMCPServer. An empty column is expected, and does not mean that the server is unhealthy.
+ Example output: The `ACCEPTED` column reports whether kagent reached the server and read its catalog. No tool can be bound from a server that is not `True`.
```console
NAME PROTOCOL URL ACCEPTED AGE
- kagent-tool-server STREAMABLE_HTTP http://kagent-tools.kagent:8084/mcp 14m
+ kagent-tool-server STREAMABLE_HTTP http://kagent-tools.kagent:8084/mcp True 14m
+ ```
+
+ To see the tools that the server offers, read the discovered set from its status.
+ ```bash
+ kubectl get remotemcpserver kagent-tool-server -n kagent \
+ -o jsonpath='{range .status.discoveredTools[*]}{.name}{"\t"}{.description}{"\n"}{end}'
```
> [!NOTE]
diff --git a/docs-site/content/kagent/1.x/setup/installation.md b/docs-site/content/kagent/1.x/setup/installation.md
index b7a438ff..b5af88fe 100644
--- a/docs-site/content/kagent/1.x/setup/installation.md
+++ b/docs-site/content/kagent/1.x/setup/installation.md
@@ -221,7 +221,7 @@ The kagent chart connects the controller to Agent Substrate and creates a Worker
substrateWorkerPool:
create: true
replicas: 1
- ateomImage: "ghcr.io/kagent-dev/substrate/ateom-gvisor:v{{< reuse "kagent-docs/versions/agent-substrate.md" >}}"
+ workerImage: "ghcr.io/kagent-dev/substrate/ateom-gvisor:v{{< reuse "kagent-docs/versions/agent-substrate.md" >}}"
EOF
```
> [!NOTE]
From ec3d55fd9cdc8cde0a2cf19db130067d01c9dda8 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Wed, 2 Sep 2026 14:41:08 -0500
Subject: [PATCH 38/70] Phase 3 - Agent harness
Signed-off-by: Rachael Graham
---
.../content/kagent/1.x/about/core-concepts.md | 6 +-
docs-site/content/kagent/1.x/agents/_index.md | 6 +
.../kagent/1.x/agents/agent-harness.md | 159 ++++++++++++++++++
.../model-providers/about-model-providers.md | 16 +-
.../setup/model-providers/amazon-bedrock.md | 3 +
.../1.x/setup/model-providers/anthropic.md | 5 +-
.../setup/model-providers/google-vertexai.md | 80 +++++++--
.../1.x/setup/model-providers/openai.md | 7 +-
8 files changed, 261 insertions(+), 21 deletions(-)
create mode 100644 docs-site/content/kagent/1.x/agents/_index.md
create mode 100644 docs-site/content/kagent/1.x/agents/agent-harness.md
diff --git a/docs-site/content/kagent/1.x/about/core-concepts.md b/docs-site/content/kagent/1.x/about/core-concepts.md
index 00564874..b1886db4 100644
--- a/docs-site/content/kagent/1.x/about/core-concepts.md
+++ b/docs-site/content/kagent/1.x/about/core-concepts.md
@@ -42,7 +42,7 @@ The Harness and AgentTemplate are the only two resources that an operator applie
A **Harness** is a Kubernetes custom resource that defines _how an agent is allowed to run_. It specifies:
-- **Runtime**: The engine that executes the agent. A Harness selects exactly one of `kagent`, `codex`, or `claude`. kagent compiles only the `kagent` runtime, which runs kagent's own Go and Python engines.
+- **Runtime**: The engine that executes the agent. A Harness selects exactly one of `kagent`, `codex`, `claude`, or `byo`, and kagent compiles all four. `kagent` runs kagent's own Go and Python engines, `codex` and `claude` run those coding agents, and `byo` runs any image that implements kagent's A2A contract.
- **Workload**: The container image and environment the runtime runs in.
- **Substrate policy**: The [WorkerPool]({{< link path="about/agent-substrate#workers-and-workerpools" >}}) that the Harness's Actors are scheduled onto, and where their {{< gloss "Snapshot" >}}snapshots{{< /gloss >}} are stored.
- **Allowed AgentTemplates**: A selector that names which AgentTemplates are permitted to run on this Harness.
@@ -50,7 +50,9 @@ A **Harness** is a Kubernetes custom resource that defines _how an agent is allo
That last point is a one-way match, not a mutual handshake. An AgentTemplate has no field naming a Harness. Instead, a Harness's `allowedAgentTemplates` selector matches on labels, and any AgentTemplate in the same namespace carrying a matching label becomes eligible to run on it. Whoever controls a Harness's selector decides which AgentTemplates it accepts.
> [!NOTE]
-> The `codex` and `claude` runtimes are part of the Harness API, so the Kubernetes API server accepts a Harness that selects either one. However, kagent currently has no compiler for them, so the pair then reports the `Compatible` condition as `False`, with the reason `UnsupportedConfiguration` and the message `Harness runtime is not supported by any compiler`.
+> Each runtime accepts a different subset of configuration. The `codex` and `claude` runtimes support fewer model providers than `kagent` does, and neither accepts a ModelConfig that sets `defaultHeaders`, `tls`, or `apiKeyPassthrough`. A Harness and AgentTemplate pair that asks for something its runtime cannot do reports the `Compatible` condition as `False`, with the reason `UnsupportedConfiguration` and a message naming the specific setting.
+
+A `byo` Harness has one extra requirement: it must set `spec.workload.command`, because kagent has no default entrypoint for an image that it does not build.
A Harness owns no running compute by itself. Applying one registers a runtime and policy that an AgentTemplate can pair with.
diff --git a/docs-site/content/kagent/1.x/agents/_index.md b/docs-site/content/kagent/1.x/agents/_index.md
new file mode 100644
index 00000000..e07add1a
--- /dev/null
+++ b/docs-site/content/kagent/1.x/agents/_index.md
@@ -0,0 +1,6 @@
+---
+title: Agents
+description: Configure how an agent runs and what it knows, from the runtime behind it to its prompt and memory.
+weight: 40
+author: kagent.dev
+---
diff --git a/docs-site/content/kagent/1.x/agents/agent-harness.md b/docs-site/content/kagent/1.x/agents/agent-harness.md
new file mode 100644
index 00000000..4f3f335e
--- /dev/null
+++ b/docs-site/content/kagent/1.x/agents/agent-harness.md
@@ -0,0 +1,159 @@
+---
+title: Agent harness
+description: Configure a Harness, the resource that defines which runtime executes an agent and what infrastructure it runs on.
+weight: 10
+author: kagent.dev
+---
+
+This page is the configuration reference for the `Harness` resource: every field it takes, the four runtimes it can select, and what each runtime supports. For what a Harness *is* and why it is separate from an AgentTemplate, see [Core concepts]({{< link path="about/core-concepts#harness" >}}).
+
+## Configure a Harness
+
+A complete Harness. Only `workload`, `substrate`, and one runtime block are required.
+
+```yaml
+kubectl apply -f - <@sha256:
+ env:
+ - name: LOG_LEVEL
+ value: info
+ - name: MY_API_KEY
+ credentialRef:
+ name: my-secret
+ key: api-key
+ substrate:
+ workerPoolRef:
+ name: kagent-default
+ snapshotPolicy:
+ location: gs:///kagent/
+ allowedAgentTemplates:
+ selector:
+ matchLabels:
+ kagent.dev/harness: my-harness
+EOF
+```
+
+| Field | Required | Description |
+| ----- | -------- | ----------- |
+| One of `kagent`, `codex`, `claude`, `byo` | Yes | The runtime that executes the agent. Naming none, or more than one, is rejected. See [Choose a runtime](#choose-a-runtime). |
+| `workload.image` | Yes | The runtime image, pinned by `sha256` digest. A tag alone is rejected, because a revision has to be reproducible. |
+| `workload.command` | For `byo` | Overrides the image entrypoint, up to 32 entries. Required for the `byo` runtime, optional otherwise. |
+| `workload.args` | No | Overrides the image arguments, up to 64 entries. |
+| `env` | No | Environment variables for the runtime, up to 100. Each entry sets either a literal `value` or a `credentialRef` naming a key in a same-namespace Secret, never both. |
+| `substrate.workerPoolRef.name` | Yes | The {{< gloss "WorkerPool" >}}WorkerPool{{< /gloss >}} that this Harness's Actors are scheduled onto. An operator has to provision one before any agent can run. |
+| `substrate.snapshotPolicy.location` | Yes | The object storage location for Actor {{< gloss "Snapshot" >}}snapshots{{< /gloss >}}. |
+| `allowedAgentTemplates.selector` | No | A label selector naming which AgentTemplates this Harness admits. Omitting it admits none, which makes the Harness unusable. |
+
+Admission is a one-way match. An {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}} has no field naming a Harness, so whoever controls a Harness's selector decides what it accepts.
+
+For every field, including its type, default, and validation rules, see the [API reference]({{< link path="reference/api-ref#harness" >}}).
+
+## Choose a runtime
+
+| Runtime | What it runs | Use it when |
+| ------- | ------------ | ----------- |
+| `kagent` | kagent's own Go and Python engines. | You want the full feature set: every model provider, agent-as-tool composition, skills, plugins, and long-term memory. |
+| `codex` | The Codex coding agent. | You want Codex to do the work, and your model is OpenAI or an OpenAI-compatible Bedrock deployment. |
+| `claude` | The Claude coding agent. | You want Claude to do the work, with Anthropic, Bedrock, or Anthropic on Vertex AI as the model. |
+| `byo` | Any container image of your own that implements kagent's A2A contract. | You have an agent framework kagent does not adapt, and you would rather bring the image than the integration. See [Bring your own agent]({{< link path="agents/bring-your-own-agent" >}}). |
+
+The `kagent` and `byo` runtimes compile through the same path, so they accept the same model providers and the same AgentTemplate features. The `codex` and `claude` runtimes are purpose-built adapters, and each accepts a narrower slice.
+
+### Runtime-specific settings
+
+`spec.kagent` is the only runtime block that takes settings of its own. The rest are empty.
+
+```yaml
+spec:
+ kagent:
+ memory:
+ modelConfigRef:
+ name: embedding-model-config
+ ttlDays: 30
+```
+
+| Field | Description |
+| ----- | ----------- |
+| `memory.modelConfigRef.name` | The ModelConfig supplying the embedding model, in the Harness's namespace. Required when `memory` is set. |
+| `memory.ttlDays` | How many days a stored memory entry stays valid. Minimum 1. Omit it to keep entries indefinitely. |
+
+Setting `memory` gives every agent on this Harness memory that persists across conversations. For how agents store and retrieve it, see [Agent memory]({{< link path="agents/agent-memory" >}}).
+
+## Model provider support
+
+The runtime that a Harness selects decides which ModelConfig its AgentTemplates can use.
+
+| Provider | `kagent` | `byo` | `codex` | `claude` |
+| -------- | :------: | :---: | :-----: | :------: |
+| `OpenAI` | Yes | Yes | Yes | No |
+| `Anthropic` | Yes | Yes | No | Yes |
+| `Bedrock` | Yes | Yes | Yes | Yes |
+| `AnthropicVertexAI` | No | No | No | Yes |
+| `GeminiVertexAI` | No | No | No | No |
+| `AzureOpenAI` | Yes | Yes | No | No |
+| `Gemini` | Yes | Yes | No | No |
+| `Ollama` | Yes | Yes | No | No |
+| `SAPAICore` | Yes | Yes | No | No |
+| `Foundry` | Yes | Yes | No | No |
+
+Some combinations that the table marks `Yes` still carry restrictions.
+
+| Combination | Restriction |
+| ----------- | ----------- |
+| `codex` with `OpenAI` | Requires `openAI.apiFormat: responses`, and accepts no other `openAI` settings beyond `baseUrl`. |
+| `codex` with `Bedrock` | Accepts only OpenAI `gpt-*` model IDs, and no `bedrock` settings beyond `region`. |
+| `claude` with `Anthropic` | Accepts no `anthropic` settings beyond `baseUrl`. |
+| `claude` with `Bedrock` | Accepts no `bedrock` settings beyond `region`. |
+| `claude` with `AnthropicVertexAI` | Accepts only `projectID` and `location`. The Secret has to hold a `service_account` key whose `project_id` matches and whose `token_uri` is `https://oauth2.googleapis.com`. |
+
+> [!IMPORTANT]
+> Neither `codex` nor `claude` accepts a ModelConfig that sets `defaultHeaders`, `tls`, or `apiKeyPassthrough`. Separately, the `kagent` and `byo` runtimes cannot use a ModelConfig whose credential is a file rather than a string, which is what rules out both Vertex AI providers there. For that limitation, see [About model providers]({{< link path="setup/model-providers/about-model-providers" >}}).
+
+## Tool and skill support
+
+The coding-agent runtimes also constrain what an AgentTemplate can ask for.
+
+| Constraint | Applies to |
+| ---------- | ---------- |
+| A `Shared` agent-tool binding cannot itself carry tools, skills, plugins, or nested agents, and has to use the same provider and credentials as the agent that binds it. | `codex`, `claude` |
+| An MCP server is bound whole. Claude does not support partial tool selection, so the agent sees every tool the server offers rather than only the ones a binding names. The compiler warns rather than failing. | `claude` |
+| A `RemoteMCPServer` has to use the `STREAMABLE_HTTP` protocol. `SSE` is rejected. | `codex` |
+
+The `kagent` and `byo` runtimes take the full set. See [About tools]({{< link path="skills-and-mcp/about-tools" >}}).
+
+## Check that a Harness is ready
+
+```bash
+kubectl get harness -n kagent
+```
+
+Example output:
+```console
+NAME READY AGE
+my-first-harness True 4m
+```
+
+A Harness that is not `Ready` has a dependency that does not resolve, most often a WorkerPool that does not exist yet. Read its conditions for the specific reason.
+
+```bash
+kubectl describe harness my-first-harness -n kagent
+```
+
+`Ready` covers the Harness's own dependencies, not whether any given agent will run on it. Whether an AgentTemplate compiles against this Harness is reported on the AgentTemplate, under `status.harnesses`. A pair that asks for something the runtime cannot do reports the `Compatible` condition as `False`, with the reason `UnsupportedConfiguration` and a message naming the specific setting.
+
+## Next steps
+
+{{< cards >}}
+ {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Apply a Harness and an AgentTemplate, then talk to the AgentInstance they produce." >}}
+ {{< card link=`{{< link path="agents/agent-memory" >}}` title="Agent memory" subtitle="Give agents on this Harness memory that outlasts a single conversation." >}}
+ {{< card link=`{{< link path="setup/model-providers/about-model-providers" >}}` title="About model providers" subtitle="Understand how a ModelConfig reaches a running agent." >}}
+{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/setup/model-providers/about-model-providers.md b/docs-site/content/kagent/1.x/setup/model-providers/about-model-providers.md
index be54a2f2..23652a3a 100644
--- a/docs-site/content/kagent/1.x/setup/model-providers/about-model-providers.md
+++ b/docs-site/content/kagent/1.x/setup/model-providers/about-model-providers.md
@@ -24,9 +24,21 @@ Credentials come from a Kubernetes Secret in the same namespace as the ModelConf
**Credential files**
kagent passes model credentials to an agent as environment variables. A ModelConfig that instead requires a credential **file** mounted into the agent does not compile. The AgentTemplate reports the `Compatible` condition as `False`, with the reason `UnsupportedConfiguration` and the message `ModelConfig requires volume mounts unsupported by Substrate ActorTemplate`. kagent compiles no revision from that AgentTemplate, so no agent runs from it, and any AgentInstance that already exists keeps running the last revision that compiled. Three configurations encounter this today.
-- **The Vertex AI providers.** `GeminiVertexAI` and `AnthropicVertexAI` mount the Google credentials file that `apiKeySecret` names. Leaving `apiKeySecret` unset compiles, but a Substrate Actor does not inherit cloud workload identity, so the agent still has no credentials to send. Both providers are unavailable in practice. For the alternatives, see [Google Vertex AI]({{< link path="setup/model-providers/google-vertexai" >}}).
+- **The Vertex AI providers, on the `kagent` and `byo` runtimes.** `GeminiVertexAI` and `AnthropicVertexAI` mount the Google credentials file that `apiKeySecret` names. Leaving `apiKeySecret` unset compiles, but a Substrate Actor does not inherit cloud workload identity, so the agent still has no credentials to send. The `claude` runtime is the exception: it passes the same credentials as an environment variable, so `AnthropicVertexAI` works there. For more information, see [Google Vertex AI]({{< link path="setup/model-providers/google-vertexai" >}}).
- **A private certificate authority (CA), on any provider.** Setting `tls.caCertSecretRef` mounts the CA bundle as a file. Every provider accepts the `tls` block, so this affects all of them, not only the Vertex AI providers. You cannot reach a provider endpoint that presents a certificate from a private CA, unless you set `tls.disableVerify: true`, which skips certificate verification entirely and belongs only in a test environment.
-- **OpenAI token exchange.** The `openAI.tokenExchange` block acquires a bearer token by reading a mounted service account file, so a ModelConfig that sets it never compiles. An OpenAI-compatible endpoint has to accept a static API key instead. See [OpenAI]({{< link path="setup/model-providers/openai" >}}).
+- **OpenAI token exchange.** The `openAI.tokenExchange` block acquires a bearer token by reading a mounted service account file, so a ModelConfig that sets it never compiles. An OpenAI-compatible endpoint has to accept a static API key instead. For more information, see [OpenAI]({{< link path="setup/model-providers/openai" >}}).
+
+## The Harness runtime decides which providers are available
+
+A ModelConfig is only half of the decision. The runtime that a {{< gloss "Harness" >}}Harness{{< /gloss >}} selects also constrains which providers an agent can use, because each runtime integrates a different set.
+
+- The **`kagent`** runtime supports every provider, and the **`byo`** runtime supports the same set, because both compile through the same path.
+- The **`codex`** runtime supports only `OpenAI` and `Bedrock`.
+- The **`claude`** runtime supports only `Anthropic`, `Bedrock`, and `AnthropicVertexAI`.
+
+Neither `codex` nor `claude` accepts a ModelConfig that sets `defaultHeaders`, `tls`, or `apiKeyPassthrough`, and each narrows the provider settings it takes. A pair that asks for a provider its runtime does not integrate fails to compile, and the AgentTemplate reports the `Compatible` condition as `False` with the reason `UnsupportedConfiguration`.
+
+For the full matrix, including the per-combination restrictions, see [Agent harness]({{< link path="agents/agent-harness#model-provider-support" >}}).
## Use a ModelConfig
diff --git a/docs-site/content/kagent/1.x/setup/model-providers/amazon-bedrock.md b/docs-site/content/kagent/1.x/setup/model-providers/amazon-bedrock.md
index dc3b4f34..ade87850 100644
--- a/docs-site/content/kagent/1.x/setup/model-providers/amazon-bedrock.md
+++ b/docs-site/content/kagent/1.x/setup/model-providers/amazon-bedrock.md
@@ -9,6 +9,9 @@ Amazon Bedrock serves models from several families behind one AWS API. kagent re
Prefer the native provider. Use the OpenAI-compatible path when you need the OpenAI request format, or an inference profile that only that endpoint exposes.
+> [!NOTE]
+> Bedrock is the only provider that every runtime supports. A `codex` Harness accepts only OpenAI `gpt-*` model IDs, and both `codex` and `claude` accept no `bedrock` settings beyond `region`. For more information, see [Agent harness]({{< link path="agents/agent-harness#model-provider-support" >}}).
+
> [!IMPORTANT]
> Both paths authenticate with credentials from a Kubernetes Secret. Attaching an AWS IAM role to the agent, such as with [EKS IAM Roles for Service Accounts](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html), is not currently supported: an agent runs as a Substrate Actor rather than as a pod that kagent controls, so there is no per-agent ServiceAccount to attach a role to.
diff --git a/docs-site/content/kagent/1.x/setup/model-providers/anthropic.md b/docs-site/content/kagent/1.x/setup/model-providers/anthropic.md
index 2ec6dd7a..3958d33c 100644
--- a/docs-site/content/kagent/1.x/setup/model-providers/anthropic.md
+++ b/docs-site/content/kagent/1.x/setup/model-providers/anthropic.md
@@ -5,7 +5,10 @@ weight: 20
author: kagent.dev
---
-The `Anthropic` provider calls the Anthropic API directly. To reach Claude models through Google Cloud instead, see [Google Vertex AI]({{< link path="setup/model-providers/google-vertexai" >}}).
+The `Anthropic` provider calls the Anthropic API directly.
+
+> [!NOTE]
+> This provider works on the `kagent`, `byo`, and `claude` runtimes, but not on `codex`. A `claude` Harness accepts no `anthropic` settings beyond `baseUrl`. For more information, see [Agent harness]({{< link path="agents/agent-harness#model-provider-support" >}}). To reach Claude models through Google Cloud instead, see [Google Vertex AI]({{< link path="setup/model-providers/google-vertexai" >}}).
## Create the ModelConfig
diff --git a/docs-site/content/kagent/1.x/setup/model-providers/google-vertexai.md b/docs-site/content/kagent/1.x/setup/model-providers/google-vertexai.md
index 04154b3a..aeac47b6 100644
--- a/docs-site/content/kagent/1.x/setup/model-providers/google-vertexai.md
+++ b/docs-site/content/kagent/1.x/setup/model-providers/google-vertexai.md
@@ -1,30 +1,82 @@
---
title: Google Vertex AI
-description: Understand why the Google Vertex AI providers do not currently run on a kagent Harness.
+description: Configure kagent to use Claude models through Google Cloud Vertex AI on a Claude harness.
weight: 20
author: kagent.dev
---
-The `GeminiVertexAI` and `AnthropicVertexAI` providers reach Gemini and Claude models through Google Cloud Vertex AI. Both providers exist in the {{< gloss "ModelConfig" >}}ModelConfig{{< /gloss >}} schema, but neither currently runs on a kagent {{< gloss "Harness" >}}Harness{{< /gloss >}}.
+Google Cloud Vertex AI serves both Gemini and Claude models, and the {{< gloss "ModelConfig" >}}ModelConfig{{< /gloss >}} schema has a provider for each: `GeminiVertexAI` and `AnthropicVertexAI`. Which of them works depends on the runtime that your {{< gloss "Harness" >}}Harness{{< /gloss >}} selects.
-> [!WARNING]
-> **Vertex AI is not currently supported.** Vertex AI authenticates with a Google Application Default Credentials file rather than with an API key. When `apiKeySecret` is set, kagent mounts that credentials file into the agent, and mounting a file is not something an agent running on {{< gloss "Agent Substrate" >}}Agent Substrate{{< /gloss >}} can do. The AgentTemplate reports the `Compatible` condition as `False` with the message `ModelConfig requires volume mounts unsupported by Substrate ActorTemplate`, and no runtime {{< gloss "Revision" >}}revision{{< /gloss >}} is compiled.
+| Provider | Harness runtime | Supported |
+| -------- | --------------- | --------- |
+| `AnthropicVertexAI` | `claude` | Yes |
+| `AnthropicVertexAI` | `kagent` or `byo` | No |
+| `GeminiVertexAI` | any | No |
-## Why the configuration fails
+For the full provider matrix across all four runtimes, see [Agent harness]({{< link path="agents/agent-harness#model-provider-support" >}}).
-kagent passes model credentials to an agent as environment variables. Every provider whose credential is a string, such as an API key, works on a Harness. Vertex AI is different: the Google credentials are a JSON file, so kagent sets `GOOGLE_APPLICATION_CREDENTIALS` to a path and mounts the Secret at that path. An agent runs as a Substrate Actor rather than as a pod that kagent controls, so there is nowhere to mount it.
+The difference is how each runtime receives the Google credentials. Vertex AI authenticates with a service account key, which is a JSON document rather than a single string. The `claude` runtime takes that document as an environment variable. The `kagent` runtime instead writes it to a file and mounts it, and an agent running on {{< gloss "Agent Substrate" >}}Agent Substrate{{< /gloss >}} cannot mount files.
-Omitting `apiKeySecret` avoids the mount, because kagent then expects Google credentials to be already present in the agent's environment. An Actor's sandbox does not inherit cloud workload identity from the node, so that path does not authenticate either.
+## Claude models on a Claude harness
-For the full explanation of which configurations a Harness can run, see [About model providers]({{< link path="setup/model-providers/about-model-providers" >}}).
+1. Create a [Google service account key](https://cloud.google.com/iam/docs/keys-create-delete) with access to Vertex AI, and store the JSON in a Kubernetes Secret. Create it in the same namespace as the AgentTemplates that use it, such as `kagent`.
+ ```bash
+ kubectl create secret generic kagent-vertex -n kagent \
+ --from-file=credentials.json=.json
+ ```
-## What to use instead
+2. Create a `ModelConfig` that uses the `AnthropicVertexAI` provider.
+ ```yaml
+ kubectl apply -f - <}}) provider, which reaches the same model family through the Google AI Studio API with an API key. |
-| Claude models | Use the [Anthropic]({{< link path="setup/model-providers/anthropic" >}}) provider, or reach Claude through [Amazon Bedrock]({{< link path="setup/model-providers/amazon-bedrock" >}}). |
-| Vertex AI specifically | Route Vertex AI through a gateway that presents an OpenAI-compatible API and authenticates to Google itself, then point an [OpenAI-compatible endpoint]({{< link path="setup/model-providers/byo-openai" >}}) ModelConfig at the gateway. |
+ | Field | Description |
+ | ----- | ----------- |
+ | `apiKeySecret` | The name of the Kubernetes Secret that holds the service account key. |
+ | `apiKeySecretKey` | The key within that Secret that holds the JSON document. |
+ | `model` | The Vertex AI model ID, such as `claude-sonnet-4@20250514`. |
+ | `provider` | The provider to use, `AnthropicVertexAI`. |
+ | `anthropicVertexAI.projectID` | Your Google Cloud project ID. This field is required, and has to match the `project_id` inside the service account key. |
+ | `anthropicVertexAI.location` | The Vertex AI region, such as `us-east5`. This field is required. |
+
+ The `claude` runtime accepts no other settings in the `anthropicVertexAI` block yet, and rejects a ModelConfig that sets `defaultHeaders`, `tls`, or `apiKeyPassthrough`. For every field, including its type, default, and validation rules, see the [API reference]({{< link path="reference/api-ref#anthropicvertexaiconfig" >}}).
+
+3. Pair the ModelConfig with a Harness that selects the `claude` runtime.
+ ```yaml
+ spec:
+ claude: {}
+ workload:
+ image: @sha256:
+ ```
+
+### What kagent checks before it compiles
+
+kagent validates the service account key at compile time rather than failing at run time, so a malformed credential surfaces on the AgentTemplate's `Compatible` condition.
+
+- The Secret key has to hold valid JSON.
+- The document has to be a `service_account` key. Other credential types are not accepted yet.
+- Its `project_id` has to match `anthropicVertexAI.projectID`.
+- Its `token_uri` has to be `https://oauth2.googleapis.com`.
+
+## Gemini models on Vertex AI
+
+The `GeminiVertexAI` provider does not compile on any runtime. On a `kagent` Harness it fails with `ModelConfig requires volume mounts unsupported by Substrate ActorTemplate`, and the `claude` runtime does not accept the provider at all.
+
+To reach Gemini models, use the [Gemini]({{< link path="setup/model-providers/gemini" >}}) provider, which serves the same model family through the Google AI Studio API and authenticates with an ordinary API key.
## Next steps
diff --git a/docs-site/content/kagent/1.x/setup/model-providers/openai.md b/docs-site/content/kagent/1.x/setup/model-providers/openai.md
index e2b0ba2a..93c725c4 100644
--- a/docs-site/content/kagent/1.x/setup/model-providers/openai.md
+++ b/docs-site/content/kagent/1.x/setup/model-providers/openai.md
@@ -5,7 +5,10 @@ weight: 10
author: kagent.dev
---
-The `OpenAI` provider calls the OpenAI API directly. It also backs every OpenAI-compatible endpoint, so several other providers in this section set `provider: OpenAI` and point `openAI.baseUrl` somewhere else.
+The `OpenAI` provider calls the OpenAI API directly.
+
+> [!NOTE]
+> This provider works on the `kagent`, `byo`, and `codex` runtimes, but not on `claude`. A `codex` Harness additionally requires `openAI.apiFormat: responses` and accepts no other `openAI` settings beyond `baseUrl`. For more information, see [Agent harness]({{< link path="agents/agent-harness#model-provider-support" >}}). It also backs every OpenAI-compatible endpoint, so several other providers in this section set `provider: OpenAI` and point `openAI.baseUrl` somewhere else.
## Create the ModelConfig
@@ -65,7 +68,7 @@ The `openAI` block takes the following optional settings. For every field, inclu
| `timeout` | How long to wait on a request to the provider. |
> [!WARNING]
-> The `openAI` block also accepts `tokenExchange`, which acquires a bearer token from a mounted service account file. That configuration mounts a credential file into the agent, so it does not compile on a Harness. See [About model providers]({{< link path="setup/model-providers/about-model-providers" >}}) for the full list of configurations that this affects.
+> The `openAI` block also accepts `tokenExchange`, which acquires a bearer token from a mounted service account file. That configuration mounts a credential file into the agent, so it does not compile on a Harness. For the full list of configurations that this affects, see [About model providers]({{< link path="setup/model-providers/about-model-providers" >}}).
## Use the ModelConfig
From e19a2f23b4e923d7033ab3a25a5082e61709216f Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Wed, 2 Sep 2026 15:31:59 -0500
Subject: [PATCH 39/70] Phase 3 - agent pages
Signed-off-by: Rachael Graham
---
docs-site/content/kagent/1.x/_index.md | 2 +-
.../kagent/1.x/agents/agent-harness.md | 71 +++---
.../content/kagent/1.x/agents/agent-memory.md | 215 ++++++++++++++++++
.../kagent/1.x/agents/system-prompts.md | 142 ++++++++++++
.../setup/model-providers/azure-ai-foundry.md | 22 ++
5 files changed, 411 insertions(+), 41 deletions(-)
create mode 100644 docs-site/content/kagent/1.x/agents/agent-memory.md
create mode 100644 docs-site/content/kagent/1.x/agents/system-prompts.md
diff --git a/docs-site/content/kagent/1.x/_index.md b/docs-site/content/kagent/1.x/_index.md
index d7e05c80..1f780c8f 100644
--- a/docs-site/content/kagent/1.x/_index.md
+++ b/docs-site/content/kagent/1.x/_index.md
@@ -8,4 +8,4 @@ author: kagent.dev
kagent 1.0 moves the runtime from Kubernetes Deployments to [Agent Substrate](https://github.com/agent-substrate/substrate), introducing Harness, AgentTemplate, and AgentInstance as the new API surface.
-This section is under active development ahead of the 1.0 release. Pages here may be incomplete, and content may change without notice. See the [0.x docs]({{< relref "/kagent/0.x" >}}) for the current stable release.
+This section is under active development ahead of the 1.0 release. Pages here may be incomplete, and content may change without notice. For the current stable release, see the [0.x docs]({{< relref "/kagent/0.x" >}}).
diff --git a/docs-site/content/kagent/1.x/agents/agent-harness.md b/docs-site/content/kagent/1.x/agents/agent-harness.md
index 4f3f335e..1b9e4c5e 100644
--- a/docs-site/content/kagent/1.x/agents/agent-harness.md
+++ b/docs-site/content/kagent/1.x/agents/agent-harness.md
@@ -5,11 +5,11 @@ weight: 10
author: kagent.dev
---
-This page is the configuration reference for the `Harness` resource: every field it takes, the four runtimes it can select, and what each runtime supports. For what a Harness *is* and why it is separate from an AgentTemplate, see [Core concepts]({{< link path="about/core-concepts#harness" >}}).
+Review configuration guidelines and reference for the `Harness` resource: every field it takes, the four runtimes it can select, and what each runtime supports. To understand a Harness and why it is separate from an AgentTemplate, see the [core concepts]({{< link path="about/core-concepts#harness" >}}).
## Configure a Harness
-A complete Harness. Only `workload`, `substrate`, and one runtime block are required.
+The following configuration is for a complete Harness resource. Only `workload`, `substrate`, and one runtime block are required.
```yaml
kubectl apply -f - <}} For more information, see the [API reference]({{< link path="reference/api-ref#agentharness" >}}).
+
| Field | Required | Description |
| ----- | -------- | ----------- |
-| One of `kagent`, `codex`, `claude`, `byo` | Yes | The runtime that executes the agent. Naming none, or more than one, is rejected. See [Choose a runtime](#choose-a-runtime). |
+| One of `kagent`, `codex`, `claude`, `byo` | Yes | The runtime that executes the agent. Naming none, or more than one, is rejected. For the available runtimes, see [Choose a runtime](#choose-a-runtime). |
| `workload.image` | Yes | The runtime image, pinned by `sha256` digest. A tag alone is rejected, because a revision has to be reproducible. |
| `workload.command` | For `byo` | Overrides the image entrypoint, up to 32 entries. Required for the `byo` runtime, optional otherwise. |
| `workload.args` | No | Overrides the image arguments, up to 64 entries. |
| `env` | No | Environment variables for the runtime, up to 100. Each entry sets either a literal `value` or a `credentialRef` naming a key in a same-namespace Secret, never both. |
| `substrate.workerPoolRef.name` | Yes | The {{< gloss "WorkerPool" >}}WorkerPool{{< /gloss >}} that this Harness's Actors are scheduled onto. An operator has to provision one before any agent can run. |
| `substrate.snapshotPolicy.location` | Yes | The object storage location for Actor {{< gloss "Snapshot" >}}snapshots{{< /gloss >}}. |
-| `allowedAgentTemplates.selector` | No | A label selector naming which AgentTemplates this Harness admits. Omitting it admits none, which makes the Harness unusable. |
-
-Admission is a one-way match. An {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}} has no field naming a Harness, so whoever controls a Harness's selector decides what it accepts.
-
-For every field, including its type, default, and validation rules, see the [API reference]({{< link path="reference/api-ref#harness" >}}).
+| `allowedAgentTemplates.selector` | No | A label selector naming which AgentTemplates this Harness admits. Omitting it admits none, which makes the Harness unusable. Admission is a one-way match. An {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}} has no field naming a Harness, so whoever controls a Harness's selector decides what it accepts. |
## Choose a runtime
-| Runtime | What it runs | Use it when |
+A Harness names exactly one of the following four runtimes, and that choice decides what executes an agent and how much of kagent's feature set the agent can use.
+
+| Runtime | What it runs | When to use it |
| ------- | ------------ | ----------- |
-| `kagent` | kagent's own Go and Python engines. | You want the full feature set: every model provider, agent-as-tool composition, skills, plugins, and long-term memory. |
-| `codex` | The Codex coding agent. | You want Codex to do the work, and your model is OpenAI or an OpenAI-compatible Bedrock deployment. |
-| `claude` | The Claude coding agent. | You want Claude to do the work, with Anthropic, Bedrock, or Anthropic on Vertex AI as the model. |
-| `byo` | Any container image of your own that implements kagent's A2A contract. | You have an agent framework kagent does not adapt, and you would rather bring the image than the integration. See [Bring your own agent]({{< link path="agents/bring-your-own-agent" >}}). |
+| `kagent` | kagent's own Go and Python engines | You want the full feature set: every model provider, agent-as-tool composition, skills, plugins, and long-term memory. |
+| `codex` | The Codex coding agent | You want Codex to do the work, and your model is OpenAI or an OpenAI-compatible Bedrock deployment. |
+| `claude` | The Claude coding agent | You want Claude to do the work, with Anthropic, Bedrock, or Anthropic on Vertex AI as the model. |
+| `byo` | Any container image of your own that implements kagent's A2A contract | You have an agent framework kagent does not adapt, and you would rather bring the image than the integration. For more information, see [Bring your own agent]({{< link path="agents/bring-your-own-agent" >}}). |
The `kagent` and `byo` runtimes compile through the same path, so they accept the same model providers and the same AgentTemplate features. The `codex` and `claude` runtimes are purpose-built adapters, and each accepts a narrower slice.
@@ -84,7 +84,7 @@ spec:
| Field | Description |
| ----- | ----------- |
| `memory.modelConfigRef.name` | The ModelConfig supplying the embedding model, in the Harness's namespace. Required when `memory` is set. |
-| `memory.ttlDays` | How many days a stored memory entry stays valid. Minimum 1. Omit it to keep entries indefinitely. |
+| `memory.ttlDays` | How many days a stored memory entry stays valid. Minimum 1. When omitted, the server applies a default of 15 days. |
Setting `memory` gives every agent on this Harness memory that persists across conversations. For how agents store and retrieve it, see [Agent memory]({{< link path="agents/agent-memory" >}}).
@@ -94,18 +94,18 @@ The runtime that a Harness selects decides which ModelConfig its AgentTemplates
| Provider | `kagent` | `byo` | `codex` | `claude` |
| -------- | :------: | :---: | :-----: | :------: |
-| `OpenAI` | Yes | Yes | Yes | No |
-| `Anthropic` | Yes | Yes | No | Yes |
-| `Bedrock` | Yes | Yes | Yes | Yes |
-| `AnthropicVertexAI` | No | No | No | Yes |
-| `GeminiVertexAI` | No | No | No | No |
-| `AzureOpenAI` | Yes | Yes | No | No |
-| `Gemini` | Yes | Yes | No | No |
-| `Ollama` | Yes | Yes | No | No |
-| `SAPAICore` | Yes | Yes | No | No |
-| `Foundry` | Yes | Yes | No | No |
-
-Some combinations that the table marks `Yes` still carry restrictions.
+| `OpenAI` | ✅ | ✅ | ✅ | ❌ |
+| `Anthropic` | ✅ | ✅ | ❌ | ✅ |
+| `Bedrock` | ✅ | ✅ | ✅ | ✅ |
+| `AnthropicVertexAI` | ❌ | ❌ | ❌ | ✅ |
+| `GeminiVertexAI` | ❌ | ❌ | ❌ | ❌ |
+| `AzureOpenAI` | ✅ | ✅ | ❌ | ❌ |
+| `Gemini` | ✅ | ✅ | ❌ | ❌ |
+| `Ollama` | ✅ | ✅ | ❌ | ❌ |
+| `SAPAICore` | ✅ | ✅ | ❌ | ❌ |
+| `Foundry` | ✅ | ✅ | ❌ | ❌ |
+
+Some supported combinations still carry restrictions.
| Combination | Restriction |
| ----------- | ----------- |
@@ -116,7 +116,7 @@ Some combinations that the table marks `Yes` still carry restrictions.
| `claude` with `AnthropicVertexAI` | Accepts only `projectID` and `location`. The Secret has to hold a `service_account` key whose `project_id` matches and whose `token_uri` is `https://oauth2.googleapis.com`. |
> [!IMPORTANT]
-> Neither `codex` nor `claude` accepts a ModelConfig that sets `defaultHeaders`, `tls`, or `apiKeyPassthrough`. Separately, the `kagent` and `byo` runtimes cannot use a ModelConfig whose credential is a file rather than a string, which is what rules out both Vertex AI providers there. For that limitation, see [About model providers]({{< link path="setup/model-providers/about-model-providers" >}}).
+> Neither `codex` nor `claude` accepts a ModelConfig that sets `defaultHeaders`, `tls`, or `apiKeyPassthrough`. Separately, the `kagent` and `byo` runtimes cannot use a ModelConfig whose credential is a file rather than a string, which is what rules out both Vertex AI providers there. For more information about that limitation, see [About model providers]({{< link path="setup/model-providers/about-model-providers" >}}).
## Tool and skill support
@@ -128,27 +128,18 @@ The coding-agent runtimes also constrain what an AgentTemplate can ask for.
| An MCP server is bound whole. Claude does not support partial tool selection, so the agent sees every tool the server offers rather than only the ones a binding names. The compiler warns rather than failing. | `claude` |
| A `RemoteMCPServer` has to use the `STREAMABLE_HTTP` protocol. `SSE` is rejected. | `codex` |
-The `kagent` and `byo` runtimes take the full set. See [About tools]({{< link path="skills-and-mcp/about-tools" >}}).
+The `kagent` and `byo` runtimes take the full set. For more information about what an AgentTemplate can bind, see [About tools]({{< link path="skills-and-mcp/about-tools" >}}).
## Check that a Harness is ready
+The `READY` column reports whether a Harness's dependencies resolved.
```bash
kubectl get harness -n kagent
```
-Example output:
-```console
-NAME READY AGE
-my-first-harness True 4m
-```
-
-A Harness that is not `Ready` has a dependency that does not resolve, most often a WorkerPool that does not exist yet. Read its conditions for the specific reason.
-
-```bash
-kubectl describe harness my-first-harness -n kagent
-```
+A Harness that is not `Ready` most often names a WorkerPool that does not exist yet. For the specific reason, read its conditions with `kubectl describe harness -n kagent`.
-`Ready` covers the Harness's own dependencies, not whether any given agent will run on it. Whether an AgentTemplate compiles against this Harness is reported on the AgentTemplate, under `status.harnesses`. A pair that asks for something the runtime cannot do reports the `Compatible` condition as `False`, with the reason `UnsupportedConfiguration` and a message naming the specific setting.
+`Ready` covers the Harness's own dependencies, not whether a given agent runs on it. Whether an AgentTemplate compiles against this Harness is reported on the AgentTemplate, under `status.harnesses`. For that check and the conditions it reports, see [Your first agent]({{< link path="get-started/your-first-agent" >}}).
## Next steps
diff --git a/docs-site/content/kagent/1.x/agents/agent-memory.md b/docs-site/content/kagent/1.x/agents/agent-memory.md
new file mode 100644
index 00000000..b662fa30
--- /dev/null
+++ b/docs-site/content/kagent/1.x/agents/agent-memory.md
@@ -0,0 +1,215 @@
+---
+title: Agent memory
+description: Give agents long-term memory that persists across conversations, backed by vector similarity search.
+weight: 40
+author: kagent.dev
+---
+
+An {{< gloss "AgentInstance" >}}AgentInstance{{< /gloss >}} remembers its own conversation, because it holds the {{< gloss "Transcript" >}}transcript{{< /gloss >}}. Long-term memory is different: it carries what an agent learned in one conversation into later ones. kagent stores those memories as vectors and retrieves them by similarity to whatever the user just said. Each agent on a {{< gloss "Harness" >}}Harness{{< /gloss >}} keeps its own memories, scoped to the user who created them.
+
+Memory is configured on the Harness rather than on an AgentTemplate, so it applies to every agent that the Harness runs.
+
+## How an agent uses memory
+
+Enabling memory adds three tools to every agent on the Harness, and appends a short instruction to its system prompt telling it that the tools exist.
+
+| Tool | What it does |
+| ---- | ------------ |
+| `save_memory` | Stores a specific fact, preference, or finding for later. |
+| `load_memory` | Searches stored memories by query when the agent needs context it does not have. |
+| `prefetch_memory` | Retrieves memories relevant to the current message before the agent answers. |
+
+Retrieval works by similarity rather than by keyword. kagent encodes the query as a vector, compares it against stored memories by cosine similarity, and puts the closest matches into the agent's context. A search returns at most five memories, and only those that score above 0.3. The agent also saves memories from a finished session on its own, so a user does not have to ask it to remember anything.
+
+Memories are scoped to the agent and to the user who created them, and carry the time that kagent wrote them. One agent cannot read another agent's memories, even on the same Harness.
+
+## Before you begin
+
+> [!IMPORTANT]
+> Memory requires an **external** PostgreSQL database with the [pgvector](https://github.com/pgvector/pgvector) extension installed. kagent's bundled database uses the stock `postgres` image, which does not ship pgvector, so it cannot store memories. Point kagent at your own database first.
+
+1. Store the connection string for your database in a Kubernetes Secret, in the same namespace as the kagent controller. The key that you choose becomes the file name that kagent reads, so `db-url` produces the path `/var/secrets/db-url`.
+ ```bash
+ kubectl create secret generic my-postgres-url-secret -n kagent \
+ --from-literal=db-url='postgres://:@:5432/?sslmode=require'
+ ```
+
+2. Save the following values, which point kagent at your database, mount the Secret into the controller, and run the migration that creates the pgvector extension.
+ ```yaml
+ cat > kagent-memory-values.yaml <}} \
+ --namespace kagent --timeout 10m --reuse-values \
+ -f kagent-memory-values.yaml
+ ```
+
+4. Wait for the controller to roll out with the new configuration.
+ ```bash
+ kubectl rollout status deployment/kagent-controller -n kagent --timeout=300s
+ ```
+
+## Choose an embedding model
+
+Any provider that the `kagent` runtime supports can serve the embedding model, so the choice typically depends on whichever provider already holds your credentials. The embedding ModelConfig is resolved in the same way that a chat ModelConfig is, which means that the same [provider limitations]({{< link path="setup/model-providers/about-model-providers" >}}) apply to it.
+
+kagent stores every memory as a **768-dimensional** vector. Models that produce wider vectors are truncated and re-normalized to that width, so no dimension setting is needed and models of different widths can coexist.
+
+An Amazon Bedrock embedding model, for example, looks like the following:
+
+```yaml
+spec:
+ provider: Bedrock
+ model: amazon.titan-embed-text-v2:0
+ bedrock:
+ region: us-east-1
+```
+
+## Enable memory
+
+Add memory to a Harness that already exists. The examples in these steps use `my-first-harness` in the `kagent` namespace, which you create in [Your first agent]({{< link path="get-started/your-first-agent" >}}).
+
+1. Create a `ModelConfig` for the embedding model in the same namespace as your Harness. The model is an embedding model rather than a chat model.
+ ```yaml
+ kubectl apply -f - <}} To review other available Harness fields, see [Agent harness]({{< link path="agents/agent-harness" >}}).
+ | Field | Description |
+ | ----- | ----------- |
+ | `memory.modelConfigRef.name` | The ModelConfig supplying the embedding model, in the Harness's namespace. Required when `memory` is set. |
+ | `memory.ttlDays` | How many days a stored memory stays valid. Minimum 1. When omitted, the server applies a default of 15 days. |
+
+3. Create a new {{< gloss "AgentInstance" >}}AgentInstance{{< /gloss >}} from the Harness and an AgentTemplate that it admits. Editing the Harness compiles a new {{< gloss "Revision" >}}revision{{< /gloss >}}, and an existing AgentInstance keeps running the revision it was created from, so an agent that was already running does not gain memory until you recreate it.
+ ```bash
+ kagent create agent-instance --harness my-first-harness --agent-template my-first-agent
+ ```
+
+ The command returns output only after the AgentInstance reaches the `READY` state. Example output:
+ ```console
+ +--------------------------------------+----------------+------------------+-------+----------------------+
+ | ID | AGENT TEMPLATE | HARNESS | STATE | CREATED |
+ +--------------------------------------+----------------+------------------+-------+----------------------+
+ | 0198c3d7-4f2a-7b61-9c3e-5d8f7a2b4e10 | my-first-agent | my-first-harness | READY | 2026-08-31T15:02:10Z |
+ +--------------------------------------+----------------+------------------+-------+----------------------+
+ ```
+
+> [!NOTE]
+> Only the `kagent` runtime supports memory. `spec.kagent` is the one runtime block that takes settings, so a Harness selecting `codex`, `claude`, or `byo` has nowhere to configure it.
+
+## Verify that memory works
+
+Memory is working when a fact from one conversation reaches a later one. An AgentInstance holds the transcript of its own conversation, so the check needs a second AgentInstance that never saw the first.
+
+1. Save the ID of the AgentInstance that you created. The command selects the most recently created AgentInstance for the AgentTemplate.
+ ```bash
+ export INSTANCE_ID=$(kagent get agent-instance -o json \
+ | jq -r '[.agentInstances[] | select(.agentTemplate.name == "my-first-agent")] | sort_by(.createdAt) | last | .id')
+ ```
+
+2. Tell the agent a fact that is worth remembering.
+ ```bash
+ kagent invoke --agent-instance $INSTANCE_ID \
+ --task "Remember that I deploy to the staging cluster on Fridays."
+ ```
+
+3. Create a second AgentInstance from the same Harness and AgentTemplate pair. The new AgentInstance starts with an empty transcript.
+ ```bash
+ kagent create agent-instance --harness my-first-harness --agent-template my-first-agent
+ ```
+
+4. Save the ID of the new AgentInstance.
+ ```bash
+ export INSTANCE_ID=$(kagent get agent-instance -o json \
+ | jq -r '[.agentInstances[] | select(.agentTemplate.name == "my-first-agent")] | sort_by(.createdAt) | last | .id')
+ ```
+
+5. Ask the new AgentInstance about the fact. An answer that includes the fact can only have come from memory, because this AgentInstance never saw the earlier conversation.
+ ```bash
+ kagent invoke --agent-instance $INSTANCE_ID --task "When do I deploy to staging?"
+ ```
+
+ Example output:
+ ```console
+ You deploy to the staging cluster on Fridays.
+ ```
+
+### What kagent stored
+
+Each memory is one row in the `memory` table of the database that you connected. Query the table to read what an agent saved.
+
+```sql
+SELECT agent_name, user_id, content, created_at, expires_at
+FROM memory ORDER BY created_at DESC LIMIT 10;
+```
+
+| Column | What it holds |
+| ------ | ------------- |
+| `content` | The text that the agent saved, which is what retrieval returns to a later conversation. |
+| `agent_name` | The agent that owns the memory, written as `__NS__` with every hyphen replaced by an underscore. |
+| `user_id` | The user that the memory belongs to. |
+| `embedding` | The 768-dimensional vector that similarity search compares a query against. |
+| `created_at` and `expires_at` | When kagent wrote the memory, and `ttlDays` after that. |
+| `access_count` | How many times retrieval has returned this memory. |
+
+A memory that the agent saves at the end of a session is summarized first, so one conversation usually produces several short rows rather than one long one.
+
+## Memory lifetime
+
+A memory expires `ttlDays` after it is written, defaulting to 15 days. Expiry is per memory rather than per session, so an old preference ages out while a recent one survives.
+
+Changing `ttlDays` on the Harness applies to memories written by AgentInstances created after the change, because the value is compiled into the revision.
+
+## Next steps
+
+{{< cards >}}
+ {{< card link=`{{< link path="agents/agent-harness" >}}` title="Agent harness" subtitle="Configure the rest of the Harness that memory is enabled on." >}}
+ {{< card link=`{{< link path="setup/model-providers/about-model-providers" >}}` title="About model providers" subtitle="Understand how a ModelConfig reaches a running agent." >}}
+{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/agents/system-prompts.md b/docs-site/content/kagent/1.x/agents/system-prompts.md
new file mode 100644
index 00000000..bf54bf5f
--- /dev/null
+++ b/docs-site/content/kagent/1.x/agents/system-prompts.md
@@ -0,0 +1,142 @@
+---
+title: System prompts
+description: Set an agent's system prompt inline or from a ConfigMap, and template it with values that kagent resolves at compile time.
+weight: 30
+author: kagent.dev
+---
+
+An {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}}'s system prompt defines the agent's role and how it should behave. kagent resolves the prompt when it compiles a {{< gloss "Revision" >}}revision{{< /gloss >}}, so the text an agent runs with is fixed for the life of an {{< gloss "AgentInstance" >}}AgentInstance{{< /gloss >}}: editing the prompt affects instances created after the edit compiles, not ones already running.
+
+## Write an effective prompt
+
+A prompt that works tends to carry four things, in roughly this order.
+
+- **Role.** What the agent is, in a sentence. `You are a Kubernetes assistant.`
+- **Scope.** What it should and should not take on, which matters more as you give it more tools.
+- **Instructions.** How to behave in the cases you care about: when to ask for clarification, what to do when a tool fails, when to refuse.
+- **Response format.** What a good answer looks like. Ask for Markdown, or for a summary before detail, if that is what you want.
+
+Two things are worth stating explicitly, because models otherwise guess: what the agent should do when it does not know an answer, and whether it should act or ask first when an action is consequential. For approval gates that the runtime enforces rather than the prompt, see [Human in the loop]({{< link path="agents/human-in-the-loop" >}}).
+
+## Set the prompt inline
+
+```yaml
+spec:
+ systemPrompt: |-
+ You are a Kubernetes assistant. You help users understand what is running in their cluster.
+
+ # Instructions
+ - Ask for clarification before running a tool when a request is ambiguous.
+ - Answer from tool output rather than from memory of how clusters usually look.
+ - Say so plainly when a question cannot be answered with the tools you have.
+```
+
+## Store the prompt in a ConfigMap
+
+Use `systemPromptFrom` to keep the prompt outside the AgentTemplate, which lets several AgentTemplates share one prompt, or lets a prompt change without editing the agent.
+
+1. Create a ConfigMap holding the prompt.
+ ```yaml
+ kubectl apply -f - < [!NOTE]
+> A prompt can come only from a ConfigMap. Earlier versions of kagent also accepted a Secret, through a `systemMessageFrom.type` field that v1alpha3 does not have. A system prompt is not a credential, so keep secrets out of it and pass them to the runtime as [Harness environment variables]({{< link path="agents/agent-harness" >}}) instead.
+
+## Template the prompt
+
+Set `spec.promptTemplate` to run the prompt through [Go templates](https://pkg.go.dev/text/template) before it reaches the model. Templating applies to whichever prompt you set, inline or from a ConfigMap.
+
+```yaml
+spec:
+ description: Answers questions about a Kubernetes cluster.
+ systemPrompt: |-
+ You are {{ .AgentTemplateName }}. {{ .Description }}
+
+ You have these tools available: {{ .ToolNames }}
+
+ {{ include "shared-prompts/response-format" }}
+ promptTemplate:
+ dataSources:
+ - name: shared-prompts
+```
+
+### Values available to a template
+
+| Value | Description |
+| ----- | ----------- |
+| `.AgentTemplateName` | The AgentTemplate's `metadata.name`. |
+| `.AgentTemplateNamespace` | The AgentTemplate's `metadata.namespace`. |
+| `.Description` | The AgentTemplate's `spec.description`. |
+| `.ToolNames` | The tool names selected from every MCP server the AgentTemplate binds. Agents bound as tools are not included. |
+
+`.ToolNames` is worth using rather than listing tools by hand, because it cannot drift from the bindings that the AgentTemplate actually declares.
+
+> [!NOTE]
+> A prompt template can reach only these values and the ConfigMaps that `dataSources` names. Templates cannot read arbitrary Kubernetes objects.
+
+### Include text from a ConfigMap
+
+The `include` function pulls in one key from a ConfigMap that `dataSources` lists. Its argument is `"/"`, where the source is the ConfigMap's name.
+
+```yaml
+spec:
+ promptTemplate:
+ dataSources:
+ - name: shared-prompts
+ - name: house-style
+ alias: style
+```
+
+| Field | Description |
+| ----- | ----------- |
+| `dataSources[].name` | A ConfigMap in the AgentTemplate's namespace. Up to 20 entries. |
+| `dataSources[].alias` | An alternative identifier to use in `include` paths. The ConfigMap is still looked up by `name`. |
+
+An alias only changes what you type. With the preceding configuration, `include "house-style/tone"` fails and `include "style/tone"` succeeds.
+
+Every key in every listed ConfigMap becomes available, so two sources that share a key name collide. kagent rejects that at compile time rather than picking one.
+
+## Troubleshooting
+
+Prompt problems surface on the AgentTemplate's `ResolvedRefs` condition, because they are reference failures rather than runtime errors. No revision compiles, so no new AgentInstance can start.
+
+| Message | Cause |
+| ------- | ----- |
+| `resolve systemPromptFrom: ConfigMap "x" not found` | The ConfigMap does not exist in the AgentTemplate's namespace. |
+| `resolve systemPromptFrom: ConfigMap "x" does not contain key "y"` | The ConfigMap exists but has no such key. |
+| `resolve prompt source "x": ConfigMap not found` | A `dataSources` entry names a ConfigMap that does not exist. |
+| `duplicate prompt template identifier "x/y"` | Two data sources expose the same `source/key` path. Give one of them an `alias`. |
+| `prompt template "x/y" not found, available: [...]` | An `include` path does not match any available key. The error lists every path that is available. |
+| `parse system message template: ...` | The template is not valid Go template syntax. |
+
+## Next steps
+
+{{< cards >}}
+ {{< card link=`{{< link path="skills-and-mcp/about-tools" >}}` title="About tools" subtitle="Bind the tools that a prompt can refer to." >}}
+ {{< card link=`{{< link path="agents/agent-memory" >}}` title="Agent memory" subtitle="Let an agent carry what it learned into later conversations." >}}
+{{< /cards >}}
diff --git a/docs-site/content/kagent/1.x/setup/model-providers/azure-ai-foundry.md b/docs-site/content/kagent/1.x/setup/model-providers/azure-ai-foundry.md
index db9bf617..fb10e251 100644
--- a/docs-site/content/kagent/1.x/setup/model-providers/azure-ai-foundry.md
+++ b/docs-site/content/kagent/1.x/setup/model-providers/azure-ai-foundry.md
@@ -103,6 +103,28 @@ spec:
name: foundry-model-config
```
+## Memory embeddings
+
+A Foundry deployment can also serve the embedding model behind [long-term memory]({{< link path="agents/agent-memory" >}}). Point a second ModelConfig at your embedding deployment, then name it from the Harness's `spec.kagent.memory.modelConfigRef`.
+
+```yaml
+kubectl apply -f - <.cognitiveservices.azure.com/
+ deployment: text-embedding-3-small
+EOF
+```
+
## Troubleshooting
| Symptom | Cause |
From ff48368e97ebb4fd38614aaa5eb17ea7390ed71f Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Wed, 2 Sep 2026 23:17:52 -0500
Subject: [PATCH 40/70] Phase 3 - sys prompts & agent memory
Signed-off-by: Rachael Graham
---
.../content/kagent/1.x/agents/agent-memory.md | 76 ++++++++++++++-----
.../kagent/1.x/agents/system-prompts.md | 73 ++++++++++++------
.../1.x/get-started/your-first-mcp-tool.md | 4 +-
.../kagent/1.x/skills-and-mcp/about-tools.md | 4 +-
4 files changed, 113 insertions(+), 44 deletions(-)
diff --git a/docs-site/content/kagent/1.x/agents/agent-memory.md b/docs-site/content/kagent/1.x/agents/agent-memory.md
index b662fa30..b3ac4f01 100644
--- a/docs-site/content/kagent/1.x/agents/agent-memory.md
+++ b/docs-site/content/kagent/1.x/agents/agent-memory.md
@@ -59,7 +59,7 @@ Memories are scoped to the agent and to the user who created them, and carry the
EOF
```
-3. Upgrade your kagent installation with the file. The `--reuse-values` flag keeps every value that you installed kagent with, such as the Agent Substrate settings, and adds only the values in this file.
+3. Upgrade your kagent installation with the values file. The `--reuse-values` flag keeps every value that you installed kagent with, such as the Agent Substrate settings, and adds only the values in this file.
```bash
helm upgrade kagent \
oci://ghcr.io/kagent-dev/kagent/helm/kagent \
@@ -142,7 +142,7 @@ Add memory to a Harness that already exists. The examples in these steps use `my
```
> [!NOTE]
-> Only the `kagent` runtime supports memory. `spec.kagent` is the one runtime block that takes settings, so a Harness selecting `codex`, `claude`, or `byo` has nowhere to configure it.
+> Only the `kagent` runtime supports memory. The `spec.kagent` runtime block is the only runtimes that has settings, so a Harness that selects `codex`, `claude`, or `byo` has settings to configure memory.
## Verify that memory works
@@ -183,30 +183,72 @@ Memory is working when a fact from one conversation reaches a later one. An Agen
### What kagent stored
-Each memory is one row in the `memory` table of the database that you connected. Query the table to read what an agent saved.
+Each memory is one row in the `memory` table, which the vector migration created in your database. A memory that the agent saves at the end of a session is summarized first, so one conversation typically produces several short rows rather than one long one.
-```sql
-SELECT agent_name, user_id, content, created_at, expires_at
-FROM memory ORDER BY created_at DESC LIMIT 10;
-```
+1. Connect to the database with the connection string that you stored in the Secret. Any PostgreSQL client works.
+ ```bash
+ psql 'postgres://:@:5432/?sslmode=require'
+ ```
+
+2. Read what an agent saved.
+ ```sql
+ SELECT agent_name, user_id, content, created_at, expires_at
+ FROM memory ORDER BY created_at DESC LIMIT 10;
+ ```
+
+ Review the following table to understand the `memory` table output.
+ | Column | What it holds |
+ | ------ | ------------- |
+ | `content` | The text that the agent saved, which is what retrieval returns to a later conversation. |
+ | `agent_name` | The agent that owns the memory, written as `__NS__` with every hyphen replaced by an underscore. |
+ | `user_id` | The user that the memory belongs to. |
+ | `embedding` | The 768-dimensional vector that similarity search compares a query against. |
+ | `created_at` and `expires_at` | When kagent wrote the memory, and `ttlDays` after that. |
+ | `access_count` | How many times retrieval has returned this memory. |
+
+## Manage memories
+
+The SQL query only reads the table. To list or clear memories, call the `MemoryService` that the kagent controller serves over gRPC.
+
+No CLI command wraps the service yet, so these examples call it with [grpcurl](https://github.com/fullstorydev/grpcurl), and both calls take the `agent_name` exactly as the memory table stores it.
+
+1. Port-forward the controller's gRPC port, and confirm that your kagent installation sets `controller.grpc.reflection=true`.
+ ```bash
+ kubectl port-forward -n kagent svc/kagent-controller 8084:8084
+ ```
+
+2. List the memories that an agent stores for one user.
+ ```bash
+ grpcurl -plaintext -d '{
+ "agent_name": "kagent__NS__my_first_agent",
+ "user_id": "admin@kagent.dev"
+ }' localhost:8084 kagent.api.v1alpha1.MemoryService/List
+ ```
-| Column | What it holds |
-| ------ | ------------- |
-| `content` | The text that the agent saved, which is what retrieval returns to a later conversation. |
-| `agent_name` | The agent that owns the memory, written as `__NS__` with every hyphen replaced by an underscore. |
-| `user_id` | The user that the memory belongs to. |
-| `embedding` | The 768-dimensional vector that similarity search compares a query against. |
-| `created_at` and `expires_at` | When kagent wrote the memory, and `ttlDays` after that. |
-| `access_count` | How many times retrieval has returned this memory. |
+ Each entry returns the `id`, `content`, `access_count`, `created_at`, and `expires_at` fields. Results are ranked by how often retrieval has returned them, so the most-used memories appear first.
-A memory that the agent saves at the end of a session is summarized first, so one conversation usually produces several short rows rather than one long one.
+3. Delete the memories for an agent and user.
+ ```bash
+ grpcurl -plaintext -d '{
+ "agent_name": "kagent__NS__my_first_agent",
+ "user_id": "admin@kagent.dev"
+ }' localhost:8084 kagent.api.v1alpha1.MemoryService/Delete
+ ```
+
+The memory service also exposes `Search`, `AddSession`, and `AddSessionBatch`. Each method takes a 768-dimensional vector rather than text, because kagent does not embed on the caller's behalf. Call them from a program that already has an embedding model, rather than by hand.
## Memory lifetime
-A memory expires `ttlDays` after it is written, defaulting to 15 days. Expiry is per memory rather than per session, so an old preference ages out while a recent one survives.
+A memory expires `ttlDays` after it is written, which defaults to 15 days. Expiry is per memory rather than per session, so an old preference ages out while a recent one survives.
Changing `ttlDays` on the Harness applies to memories written by AgentInstances created after the change, because the value is compiled into the revision.
+## Known limitations
+
+- **Memories are deleted for an agent and user together.** `Delete` clears everything for that pair, and no call removes a single memory.
+- **Memories are not shared between agents.** Each agent has its own store, so one agent cannot read what another learned, even on the same Harness and for the same user.
+- **The memory implementation is not pluggable.** kagent builds on the Google Agent Development Kit (ADK) memory implementation, and it cannot be swapped for another memory system. To use an alternative, run it as a Model Context Protocol (MCP) server, [bind it as a tool]({{< link path="skills-and-mcp/about-tools" >}}), and instruct the agent to use that instead of the built-in tools.
+
## Next steps
{{< cards >}}
diff --git a/docs-site/content/kagent/1.x/agents/system-prompts.md b/docs-site/content/kagent/1.x/agents/system-prompts.md
index bf54bf5f..edb75112 100644
--- a/docs-site/content/kagent/1.x/agents/system-prompts.md
+++ b/docs-site/content/kagent/1.x/agents/system-prompts.md
@@ -5,21 +5,23 @@ weight: 30
author: kagent.dev
---
-An {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}}'s system prompt defines the agent's role and how it should behave. kagent resolves the prompt when it compiles a {{< gloss "Revision" >}}revision{{< /gloss >}}, so the text an agent runs with is fixed for the life of an {{< gloss "AgentInstance" >}}AgentInstance{{< /gloss >}}: editing the prompt affects instances created after the edit compiles, not ones already running.
+An {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}}'s system prompt defines the agent's role and how it should behave. kagent resolves the prompt when it compiles a {{< gloss "Revision" >}}revision{{< /gloss >}}, so the text that an agent runs with is fixed for the life of an {{< gloss "AgentInstance" >}}AgentInstance{{< /gloss >}}. Editing the prompt affects instances created after the edit compiles, but not ones that are already running.
## Write an effective prompt
A prompt that works tends to carry four things, in roughly this order.
-- **Role.** What the agent is, in a sentence. `You are a Kubernetes assistant.`
-- **Scope.** What it should and should not take on, which matters more as you give it more tools.
-- **Instructions.** How to behave in the cases you care about: when to ask for clarification, what to do when a tool fails, when to refuse.
-- **Response format.** What a good answer looks like. Ask for Markdown, or for a summary before detail, if that is what you want.
+- **Role.** What the agent is, in a sentence, such as `You are a Kubernetes assistant.`
+- **Scope.** What the agent should and should not take on, which matters more as you give it more tools.
+- **Instructions.** How the agent should behave in the cases that you care about: when to ask for clarification, what to do when a tool fails, and when to refuse.
+- **Response format.** What a good answer looks like. For example, ask for Markdown, or for a summary before detail.
Two things are worth stating explicitly, because models otherwise guess: what the agent should do when it does not know an answer, and whether it should act or ask first when an action is consequential. For approval gates that the runtime enforces rather than the prompt, see [Human in the loop]({{< link path="agents/human-in-the-loop" >}}).
## Set the prompt inline
+Set `spec.systemPrompt` to keep the prompt in the AgentTemplate itself, so that the prompt and the rest of the agent's configuration change together. Inline suits a prompt that only one AgentTemplate uses.
+
```yaml
spec:
systemPrompt: |-
@@ -31,6 +33,8 @@ spec:
- Say so plainly when a question cannot be answered with the tools you have.
```
+Write the value as a YAML block scalar, such as the `|-` in the example, so that the blank lines, headings, and lists that structure the prompt reach the model as written. A folded scalar collapses them into a single paragraph.
+
## Store the prompt in a ConfigMap
Use `systemPromptFrom` to keep the prompt outside the AgentTemplate, which lets several AgentTemplates share one prompt, or lets a prompt change without editing the agent.
@@ -62,14 +66,14 @@ Use `systemPromptFrom` to keep the prompt outside the AgentTemplate, which lets
| `systemPromptFrom.name` | The ConfigMap holding the prompt, in the AgentTemplate's namespace. |
| `systemPromptFrom.key` | The key within that ConfigMap. |
-`systemPrompt` and `systemPromptFrom` are mutually exclusive, and an AgentTemplate that sets both is rejected.
+`systemPrompt` and `systemPromptFrom` are mutually exclusive, and an AgentTemplate that sets both is rejected. If you omit both fields, the revision compiles with no system prompt at all, and the agent runs on its harness's default behavior.
> [!NOTE]
> A prompt can come only from a ConfigMap. Earlier versions of kagent also accepted a Secret, through a `systemMessageFrom.type` field that v1alpha3 does not have. A system prompt is not a credential, so keep secrets out of it and pass them to the runtime as [Harness environment variables]({{< link path="agents/agent-harness" >}}) instead.
## Template the prompt
-Set `spec.promptTemplate` to run the prompt through [Go templates](https://pkg.go.dev/text/template) before it reaches the model. Templating applies to whichever prompt you set, inline or from a ConfigMap.
+Set `spec.promptTemplate` to run the prompt through [Go templates](https://pkg.go.dev/text/template) before it reaches the model. Templating applies to both inline prompts or prompts set in a ConfigMap.
```yaml
spec:
@@ -85,26 +89,30 @@ spec:
- name: shared-prompts
```
-### Values available to a template
+The following values are available to a template.
| Value | Description |
| ----- | ----------- |
| `.AgentTemplateName` | The AgentTemplate's `metadata.name`. |
| `.AgentTemplateNamespace` | The AgentTemplate's `metadata.namespace`. |
| `.Description` | The AgentTemplate's `spec.description`. |
-| `.ToolNames` | The tool names selected from every MCP server the AgentTemplate binds. Agents bound as tools are not included. |
+| `.ToolNames` | The tool names selected from every MCP server the AgentTemplate binds. Agents bound as tools are not included. Prefer this value over listing tools by hand, because it cannot drift from the bindings that the AgentTemplate declares. |
-`.ToolNames` is worth using rather than listing tools by hand, because it cannot drift from the bindings that the AgentTemplate actually declares.
+Additionally, the `include` function pulls in one key from a ConfigMap that `dataSources` lists. The argument is formatted `"/"`, where the source is the ConfigMap's name. Every key in every listed ConfigMap becomes available, so two sources that share a key name collide. kagent rejects that at compile time rather than picking one.
-> [!NOTE]
-> A prompt template can reach only these values and the ConfigMaps that `dataSources` names. Templates cannot read arbitrary Kubernetes objects.
-
-### Include text from a ConfigMap
+| Field | Description |
+| ----- | ----------- |
+| `dataSources[].name` | A ConfigMap in the AgentTemplate's namespace, up to 20 entries. |
+| `dataSources[].alias` | An alternative identifier to use in `include` paths. The ConfigMap is still looked up by `name`. |
-The `include` function pulls in one key from a ConfigMap that `dataSources` lists. Its argument is `"/"`, where the source is the ConfigMap's name.
+An alias only changes what you type. In this example configuration, `include "house-style/tone"` fails and `include "style/tone"` succeeds.
```yaml
spec:
+ systemPrompt: |-
+ {{ include "shared-prompts/response-format" }}
+
+ {{ include "style/tone" }}
promptTemplate:
dataSources:
- name: shared-prompts
@@ -112,18 +120,37 @@ spec:
alias: style
```
-| Field | Description |
-| ----- | ----------- |
-| `dataSources[].name` | A ConfigMap in the AgentTemplate's namespace. Up to 20 entries. |
-| `dataSources[].alias` | An alternative identifier to use in `include` paths. The ConfigMap is still looked up by `name`. |
+> [!NOTE]
+> A prompt template can reach only the supported values and the ConfigMaps that `dataSources` names. Templates cannot read arbitrary Kubernetes objects.
-An alias only changes what you type. With the preceding configuration, `include "house-style/tone"` fails and `include "style/tone"` succeeds.
+## Troubleshooting
-Every key in every listed ConfigMap becomes available, so two sources that share a key name collide. kagent rejects that at compile time rather than picking one.
+Prompt problems surface on the `ResolvedRefs` condition, because they are reference failures rather than runtime errors. No revision compiles, so no new AgentInstance can start.
-## Troubleshooting
+An AgentTemplate reports one set of conditions for each Harness that admits it, under `status.harnesses`. To check the condition for your Harness, run the following command.
+
+```bash
+kubectl get agenttemplate my-first-agent -n kagent -o json \
+ | jq '.status.harnesses[] | {harness, conditions: [.conditions[] | select(.type == "ResolvedRefs")]}'
+```
-Prompt problems surface on the AgentTemplate's `ResolvedRefs` condition, because they are reference failures rather than runtime errors. No revision compiles, so no new AgentInstance can start.
+In the output, a failure sets the reason to `ReferenceResolutionFailed` and the resolve error is listed in the message. Example output:
+
+```json
+{
+ "harness": "my-first-harness",
+ "conditions": [
+ {
+ "type": "ResolvedRefs",
+ "status": "False",
+ "observedGeneration": 2,
+ "lastTransitionTime": "2026-08-31T15:02:10Z",
+ "reason": "ReferenceResolutionFailed",
+ "message": "resolve systemPromptFrom: ConfigMap \"shared-prompts\" does not contain key \"kubernetes-assistant\""
+ }
+ ]
+}
+```
| Message | Cause |
| ------- | ----- |
diff --git a/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md b/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md
index f7a6e932..b3651a2b 100644
--- a/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md
+++ b/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md
@@ -15,7 +15,7 @@ A system prompt tells an agent how to behave. Tools tell it what it can do. This
## Bind the tool to your AgentTemplate
-kagent ships an MCP server of its own, and installs a `RemoteMCPServer` that points at it, so the built-in server is the shortest path to a working tool. An {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}} takes tools through an `mcp` binding, which names one server and the tools to take from it. Naming the tools is required, because a binding never takes a server's whole catalog.
+kagent ships an MCP server of its own, and installs a `RemoteMCPServer` that points at it, so the built-in server is the shortest path to a working tool. An {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}} takes tools through an `mcp` binding, which names one server and, optionally, the tools to take from it. This guide names the tools specifically, so that the agent gets only the two tools it needs rather than the server's whole catalog.
kagent records what it discovered on the server's status, so the tool names come from the cluster. This guide binds `k8s_get_resources` and `k8s_get_pod_logs`. For the full catalog that the built-in server serves, see the [tools ecosystem reference]({{< link path="reference/tools-ecosystem" >}}).
@@ -72,7 +72,7 @@ kagent records what it discovered on the server's status, so the tool names come
| ----- | ----------- |
| `mcp.server.kind` | The kind of server resource. `RemoteMCPServer` is the only accepted value. |
| `mcp.server.name` | The server's name. A binding resolves in the AgentTemplate's own namespace, so it cannot reach a server in another namespace. |
- | `mcp.tools` | The names of the tools to bind, between 1 and 50. An AgentTemplate takes at most 50 bindings in total. |
+ | `mcp.tools` | Optional. The names of the tools to bind, up to 50. An omitted or empty list exposes every tool on the server. An AgentTemplate takes at most 50 bindings in total. |
3. Confirm that kagent compiled a new {{< gloss "Revision" >}}revision{{< /gloss >}} for the edited AgentTemplate. Every edit produces a new desired revision, and the pair is current when the latest successful revision matches it.
```bash
diff --git a/docs-site/content/kagent/1.x/skills-and-mcp/about-tools.md b/docs-site/content/kagent/1.x/skills-and-mcp/about-tools.md
index fcf803db..f0eeaecc 100644
--- a/docs-site/content/kagent/1.x/skills-and-mcp/about-tools.md
+++ b/docs-site/content/kagent/1.x/skills-and-mcp/about-tools.md
@@ -14,7 +14,7 @@ Both kinds resolve within the AgentTemplate's own namespace, so a binding cannot
## MCP tools
-An `mcp` binding names a server and the tools to take from it. Naming the tools is required. A binding takes between 1 and 50 named tools, never the server's whole catalog.
+An `mcp` binding names a server, and optionally the tools to take from it. Listing tools narrows the binding to those tools. Omitting the list, or leaving it empty, exposes every tool that the server offers.
```yaml
tools:
@@ -31,7 +31,7 @@ tools:
| ----- | ----------- |
| `mcp.server.kind` | The kind of server resource. `RemoteMCPServer` is the only accepted value. |
| `mcp.server.name` | The server's name, in the AgentTemplate's namespace. |
-| `mcp.tools` | The names of the tools to bind, between 1 and 50. Duplicates in the list are collapsed. |
+| `mcp.tools` | Optional. The names of the tools to bind, up to 50. Duplicates are collapsed. An omitted or empty list exposes every tool on the server. |
## Agents as tools
From 7b7971d0a3da0265570e2af5e12158dff0fe0b78 Mon Sep 17 00:00:00 2001
From: Rachael Graham
Date: Thu, 3 Sep 2026 10:32:33 -0500
Subject: [PATCH 41/70] Phase 3 - HITL
Signed-off-by: Rachael Graham
---
.../kagent/1.x/agents/human-in-the-loop.md | 155 ++++++++++++++++++
1 file changed, 155 insertions(+)
create mode 100644 docs-site/content/kagent/1.x/agents/human-in-the-loop.md
diff --git a/docs-site/content/kagent/1.x/agents/human-in-the-loop.md b/docs-site/content/kagent/1.x/agents/human-in-the-loop.md
new file mode 100644
index 00000000..f122a503
--- /dev/null
+++ b/docs-site/content/kagent/1.x/agents/human-in-the-loop.md
@@ -0,0 +1,155 @@
+---
+title: Human in the loop
+description: Understand how an agent pauses to ask a question or to get a tool call approved, and what a client does to answer it.
+weight: 50
+author: kagent.dev
+---
+
+An agent that only answers questions can run unattended. An agent that takes action often should not. The human in the loop (HITL) mechanism lets an agent stop mid-turn, return a question or a pending tool call to a person, and continue once that person answers.
+
+> [!IMPORTANT]
+> HITL is negotiated by the **client**, per call, rather than configured on an {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}}. There is no field to switch it on. A client that does not ask for the extension still gets the pause: the agent stops, and the task waits. What it loses is the ability to answer, because the request reaches it as bare text with no correlation `id`. This differs from kagent 0.x, where a `requireApproval` list on the `Agent` resource decided which tools paused.
+
+## How a pause works
+
+The following diagram traces one turn in which the agent stops for a person.
+
+```mermaid
+flowchart TB
+ caller["Client sends a message requesting the HITL extension"]
+ working["Agent works on the turn"]
+ decision{"Does the agent need a person?"}
+ pause["Task state becomes INPUT_REQUIRED"]
+ request["Status message carries a tool_approval_request or ask_user_request"]
+ answer["Client sends a response message on the same task"]
+ done["Agent finishes the turn"]
+
+ caller --> working
+ working --> decision
+ decision -->|no| done
+ decision -->|yes| pause
+ pause --> request
+ request --> answer
+ answer --> working
+```
+
+The client opens the turn by sending a message that requests the HITL extension. The agent works until it either finishes, in which case the turn ends, or needs a person. When it needs a person, the task moves to `INPUT_REQUIRED` and its status message carries either a `tool_approval_request` or an `ask_user_request`. The client answers by sending a response message on the same task, and the agent resumes the turn where it left off.
+
+## Pause kinds
+
+An agent pauses either to get permission before it acts or to ask a question. Each case raises its own request.
+
+| Request | Raised when | The client answers with |
+| ------- | ----------- | ----------------------- |
+| `tool_approval_request` | The agent wants to call a tool that asked for confirmation before it runs. | `tool_approval_response` |
+| `ask_user_request` | The agent calls the built-in `ask_user` tool because it needs information only a person has. | `ask_user_response` |
+
+Both use the same pause and resume mechanism, so a client that handles one can handle the other with a different payload.
+
+The runtime's tool-confirmation mechanism decides which tool calls raise an approval, rather than kagent configuration. kagent does not keep a list of tools that need approval.
+
+## Negotiate the extension
+
+HITL is an [A2A](https://a2a-protocol.org) message extension, identified by a versioned URI. A client requests it by setting that URI as the `A2A-Extensions` header on the call that sends a message.
+
+```http
+A2A-Extensions: https://kagent.dev/extensions/hitl/v1
+```
+
+kagent activates the extension only for calls that request it, and echoes the activated URI back. A client that never requests the extension sees ordinary turns until the agent needs a person. The turn then pauses like any other, and that client has no way to answer the request.
+
+A call from outside the cluster addresses the agent with two more headers, because the gateway routes on metadata rather than on a path. Port-forward the controller's gRPC port first, as in [Install kagent]({{< link path="setup/installation" >}}).
+
+```bash
+grpcurl -plaintext \
+ -H 'A2A-Extensions: https://kagent.dev/extensions/hitl/v1' \
+ -H 'x-kagent-agent-instance-namespace: kagent' \
+ -H 'x-kagent-agent-instance-id: ' \
+ -d '{
+ "message": {
+ "message_id": "msg-1",
+ "role": "ROLE_USER",
+ "parts": [{"text": "Delete the obsolete pod in the production namespace."}]
+ }
+ }' localhost:8084 lf.a2a.v1.A2AService/SendStreamingMessage
+```
+
+When the agent pauses, the payload arrives in the status message's `metadata`, keyed by the extension URI. The URI is also listed in the message's `extensions` array. Each payload carries a `type` field that specifies its shape.
+
+| Type | Direction |
+| ---- | --------- |
+| `tool_approval_request` | Agent to client |
+| `ask_user_request` | Agent to client |
+| `tool_approval_response` | Client to agent |
+| `ask_user_response` | Client to agent |
+
+> [!WARNING]
+> In case of failure, both halves of this negotiation fail silently, and neither failure reports anything.
+- **A send that omits the header produces a pause that cannot be answered.** The turn still stops, but its status message carries the question as prose, with no `metadata` and no correlation `id`, so there is nothing to render and no `id` to answer with. Re-reading that task with the header does not recover it, because the payload was never attached. Send the header on every call: it is harmless on a read, and unrecoverable if missed on a send. An attached payload is stored with the task, so a later read returns it whether or not that read requests the extension.
+- **A response that omits the `extensions` array is delivered as ordinary text.** kagent ignores the `metadata` payload unless the message itself lists the extension URI in `extensions`. The task resumes and the agent replies, so the call looks like it worked, but the structured decision never reached the agent.
+
+### Approving or rejecting a tool
+
+A `tool_approval_request` lists the pending calls, each with an `id`, the tool `name`, and the `args` the agent chose. The response decides every listed call.
+
+```json
+{
+ "type": "tool_approval_response",
+ "approvals": [
+ { "id": "", "approved": true },
+ { "id": "", "approved": false, "rejection_reason": "Deleting that namespace is out of scope." }
+ ]
+}
+```
+
+A response must decide every call in the request. A rejection reason is optional but worth sending, because the agent receives it and can adapt rather than simply failing.
+
+### Answering a question
+
+An `ask_user_request` carries an `id` and a list of `questions`. The response echoes the same `id` and answers them in order.
+
+```json
+{
+ "type": "ask_user_response",
+ "id": "