Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 1 addition & 12 deletions .github/workflows/links.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ on:
- 'docs-site/layouts/**'
- 'docs-site/static/**'
- 'docs-site/hugo.yaml'
- 'docs-site/hugo.preview.yaml'
- 'docs-site/go.mod'
- 'docs-site/go.sum'
- '.github/workflows/links.yml'
Expand Down Expand Up @@ -111,17 +110,7 @@ jobs:
# docs-site's CSS pipeline shells out to tooling in its own
# devDependencies, so install them first so Hugo finds the binaries.
npm ci
# The preview overlay and -D are what put content/kagent/1.x/ in this
# build at all. That section is withheld from production by a draft
# cascade in 1.x/_index.md, so a plain `hugo --config hugo.yaml`
# renders ZERO 1.x pages and this job passes green having scanned
# none of them. The overlay also restores the 1.x entry in
# params.versions, without which every {{< version include-if="1.x" >}}
# renders empty. Both are temporary: at the 1.0 release the draft keys
# and hugo.preview.yaml go away, and this line reverts to
# `hugo --config hugo.yaml --gc --minify`. The Makefile and
# preview.yaml layer the overlay the same way.
hugo --config hugo.yaml,hugo.preview.yaml -D --gc --minify
hugo --config hugo.yaml --gc --minify

- name: Prepare workspace
run: mkdir -p artifacts
Expand Down
13 changes: 8 additions & 5 deletions .github/workflows/playwright-screenshots.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ on:
options: [mock, cluster, both]
push:
branches:
# The 1.x docs live on this branch until the 1.0 release; retarget to main
# when 1.x is published and the draft cascade is dropped.
- kagent-1-0-docs
# Retargeted from the kagent-1-0-docs feature branch on 2026-09-16, once that
# branch merged and main took ownership of the harness, the baselines, and the
# guides that embed them. Keep this on main: a feature branch gets deleted when
# it merges, and a push trigger that names a deleted branch simply stops firing,
# which is indistinguishable from a clean run.
- main
paths:
# Only the inputs that actually determine the pixels. Everything else in the
# repo can change without a capture being stale.
Expand Down Expand Up @@ -130,7 +133,7 @@ jobs:
Generated by the [**Refresh kagent UI screenshots** workflow](https://github.com/${{ github.repository_owner }}/website/actions/workflows/playwright-screenshots.yaml).
branch: playwright/screenshot-refresh-mock
delete-branch: true
base: kagent-1-0-docs
base: main
labels: |
documentation
automated pr
Expand Down Expand Up @@ -249,7 +252,7 @@ jobs:
Generated by the [**Refresh kagent UI screenshots** workflow](https://github.com/${{ github.repository_owner }}/website/actions/workflows/playwright-screenshots.yaml).
branch: playwright/screenshot-refresh-cluster
delete-branch: true
base: kagent-1-0-docs
base: main
labels: |
documentation
automated pr
2 changes: 1 addition & 1 deletion .github/workflows/preview.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
# OpenNext Worker (which bundles public/ as static assets). HUGO=hugo uses
# the Hugo installed above instead of the local hugo160 alias.
- name: Build (Hugo docs + inject into /docs + Worker)
run: make build HUGO=hugo HUGO_CONFIG=hugo.yaml,hugo.preview.yaml HUGO_FLAGS=-D
run: make build HUGO=hugo

# Derive a stable preview alias from the PR branch name. Cloudflare preview
# aliases must be a valid subdomain label (lowercase alphanumerics and
Expand Down
170 changes: 159 additions & 11 deletions .github/workflows/update-ref-docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ concurrency:
# --display-name kagent --out-dir docs-site/content/kagent/0.x/resources/cli \
# --url-prefix /docs/kagent/0.x/resources/cli --weight 1
#
# No --link-prefix there on purpose: 0.x is frozen and is not rebased into the
# enterprise hub, so its generated cross-links stay root-relative URLs.
#
# The section is named reference/ in 1.x, not resources/ as in 0.x, and the
# provider pages link to crd-ref-docs anchors (#modelconfigspec, #openaiconfig,
# ...), so keep that renderer and its anchor naming.
Expand Down Expand Up @@ -94,6 +97,11 @@ jobs:
KAGENT_CLI_DIR: docs-site/content/kagent/1.x/reference/cli
KMCP_CLI_DIR: docs-site/content/kmcp/reference/cli
KAGENT_CLI_URL_PREFIX: /docs/kagent/1.x/reference/cli
# Version-root-relative path behind the `link` shortcode in the
# generated kagent pages. kagent is versioned and its pages are
# rebased into the enterprise docs hub, so its cross-links must not
# hardcode the 1.x segment. kmcp is unversioned and passes none.
KAGENT_CLI_LINK_PREFIX: reference/cli
KMCP_CLI_URL_PREFIX: /docs/kmcp/reference/cli

steps:
Expand Down Expand Up @@ -140,11 +148,17 @@ jobs:
# is NOT a source: it is gitignored and generated from Chart-template.yaml
# by envsubst, so a checkout never carries a useful value.
#
# Deliberately not automated: kagent.md names the UPCOMING release while
# `git describe` on main yields a dev tag, so it stays editorial until 1.0
# ships; and jaeger / loki / tempo / otel-collector are pinned nowhere in
# kagent, so the only source is "latest upstream", which would assert
# chart versions no guide was tested against.
# Deliberately not automated: kagent.md names the release the docs
# DESCRIBE, while `git describe` on main yields a dev tag. That stayed
# editorial through 1.0 and should stay editorial now, for a second reason
# it did not have before -- the runtime image step below resolves its
# digests at the tag this conref names, so this one file is what decides
# which release the whole 1.x doc set pins to. Bumping it by hand is the
# release switch; everything else follows on the next run.
#
# Also not automated: jaeger / loki / tempo / otel-collector are pinned
# nowhere in kagent, so the only source is "latest upstream", which would
# assert chart versions no guide was tested against.
# ---------------------------------------------------------------------
- name: Read versions from kagent
run: |
Expand Down Expand Up @@ -182,10 +196,18 @@ jobs:
echo " $1 = $2"
}

# x.y.z with an OPTIONAL prerelease suffix. The suffix is not
# hypothetical: kagent 1.0 pins Agent Substrate at 0.2.0-beta4, and a
# bare-triple pattern rejected it and killed this step -- and with it
# the API reference regeneration downstream, which runs later in the
# same job. Component versions go through prerelease lines routinely;
# only the value's SHAPE is being guarded here, not its maturity.
SEMVER='^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$'

echo "Extracted from kagent ${KAGENT_COMMIT}:"
check SUBSTRATE_VERSION "$SUBSTRATE_VERSION" '^[0-9]+\.[0-9]+\.[0-9]+$'
check KMCP_VERSION "$KMCP_VERSION" '^[0-9]+\.[0-9]+\.[0-9]+$'
check KAGENT_TOOLS_VERSION "$KAGENT_TOOLS_VERSION" '^[0-9]+\.[0-9]+\.[0-9]+$'
check SUBSTRATE_VERSION "$SUBSTRATE_VERSION" "$SEMVER"
check KMCP_VERSION "$KMCP_VERSION" "$SEMVER"
check KAGENT_TOOLS_VERSION "$KAGENT_TOOLS_VERSION" "$SEMVER"
check MAX_KUBE "$MAX_KUBE" '^[0-9]+\.[0-9]+$'

{
Expand All @@ -195,6 +217,110 @@ jobs:
echo "MAX_KUBE=$MAX_KUBE"
} >> $GITHUB_ENV

# ---------------------------------------------------------------------
# Runtime image conrefs.
#
# versions/runtime-image.md and versions/runtime-image-claude.md hold a
# FULL digest-pinned reference (repository@sha256:...), not a version,
# because a Harness `workload.image` rejects a bare tag -- a revision has
# to be reproducible. Pages reuse the whole string, so the repository name
# is not hardcoded on any page either.
#
# A digest exists only once the image is pushed, so unlike every value
# above this one is read from the REGISTRY rather than from a file in the
# kagent tree. The tag to resolve comes from versions/kagent.md, not from
# `git describe` on main: that conref names the release the docs describe,
# so resolving against it is what keeps the image a reader pins consistent
# with the chart version the install page tells them to install. It also
# means these two follow automatically whenever kagent.md is bumped by
# hand, which is the reason that one stays editorial.
#
# Image names are NOT the ones the kagent tree suggests. The kagent
# runtime is golang-adk (values.yaml calls it `agentImage`); the claude
# runtime is claude-harness. The `claude-adk` and `codex-adk` strings in
# kagent are build stages, and nothing is published under those names.
#
# 0.x needs no equivalent: it predates Harness and pins no runtime image.
# ---------------------------------------------------------------------
- name: Resolve runtime image digests
run: |
set -euo pipefail

KAGENT_CONREF="$VERSIONS_DIR/kagent.md"
if [ ! -f "$KAGENT_CONREF" ]; then
echo "Error: expected conref $KAGENT_CONREF"
exit 1
fi

# The 1.x span of:
# {{< version include-if="0.x" >}}0.10.1{{< /version >}}{{< version include-if="1.x" >}}1.0.0-alpha1{{< /version >}}
IMAGE_TAG=$(sed -E 's|.*include-if="1\.x" >\}\}([^{]*)\{\{< /version >\}\}.*|\1|' "$KAGENT_CONREF")

if ! printf '%s' "$IMAGE_TAG" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$'; then
echo "Error: read the image tag as '$IMAGE_TAG' from $KAGENT_CONREF, which is not a version."
echo "The conref's shape likely changed. Fix the extraction here rather than editing the conref by hand."
exit 1
fi
echo "Resolving runtime images at tag $IMAGE_TAG (from versions/kagent.md)"

# Anonymous pull token; these packages are public. Deliberately not
# crane or `docker buildx imagetools`: neither is on this runner, and
# a HEAD against the registry needs no setup step.
ghcr_digest() {
local repo="$1" tag="$2" token
token=$(curl -fsS "https://ghcr.io/token?scope=repository:${repo}:pull&service=ghcr.io" \
| sed -n 's/.*"token":"\([^"]*\)".*/\1/p') || return 1
[ -n "$token" ] || return 1
# Index media types FIRST. These images are multi-arch and the value
# to pin is the index digest; an Accept header that omits the index
# types still succeeds but hands back ONE platform's digest, which
# would pin every reader to the runner's architecture.
curl -fsSI -H "Authorization: Bearer ${token}" \
-H "Accept: application/vnd.oci.image.index.v1+json,application/vnd.docker.distribution.manifest.list.v2+json,application/vnd.oci.image.manifest.v1+json,application/vnd.docker.distribution.manifest.v2+json" \
"https://ghcr.io/v2/${repo}/manifests/${tag}" \
| awk -F': ' 'tolower($1)=="docker-content-digest"{gsub(/\r/,"");print $2}'
}

# conref basename : GHCR repository
RUNTIME_IMAGES="runtime-image:kagent-dev/kagent/golang-adk
runtime-image-claude:kagent-dev/kagent/claude-harness"

UNRESOLVED=""
while IFS= read -r line; do
line=$(printf '%s' "$line" | tr -d '[:space:]')
[ -n "$line" ] || continue
name="${line%%:*}"
repo="${line#*:}"

digest=$(ghcr_digest "$repo" "$IMAGE_TAG" || true)

# An unresolved digest is NOT fatal. versions/kagent.md is editorial
# and may legitimately name a release whose images are not pushed
# yet. Writing an empty conref would blank a `workload.image` line
# on four pages, so the conref is left alone and the miss is
# surfaced in the PR body instead -- same shape as the kmcp
# cross-check above.
if ! printf '%s' "$digest" | grep -Eq '^sha256:[0-9a-f]{64}$'; then
echo "::warning::Could not resolve a digest for ${repo}:${IMAGE_TAG}. Leaving its conref unchanged."
UNRESOLVED="${UNRESOLVED}\`${repo}:${IMAGE_TAG}\` "
continue
fi

# runtime-image -> RUNTIME_IMAGE, runtime-image-claude -> RUNTIME_IMAGE_CLAUDE
var=$(printf '%s' "$name" | tr 'a-z-' 'A-Z_')
# ghcr.io/ is prepended here rather than carried in the table
# above, because the table's value doubles as the registry API path,
# which takes the repository WITHOUT the host.
echo " ${name}.md = ghcr.io/${repo}@${digest}"
echo "${var}=ghcr.io/${repo}@${digest}" >> $GITHUB_ENV
done <<< "$RUNTIME_IMAGES"

if [ -n "$UNRESOLVED" ]; then
echo "RUNTIME_IMAGE_NOTE=> [!WARNING] No digest resolved for ${UNRESOLVED}- those conrefs keep their previous value. Expected when versions/kagent.md names a release whose images are not published yet." >> $GITHUB_ENV
else
echo "RUNTIME_IMAGE_NOTE=" >> $GITHUB_ENV
fi

- name: Cross-check kmcp against its own latest release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down Expand Up @@ -262,6 +388,23 @@ jobs:
write_conref "$VERSIONS_DIR/max-kube.md" "$MAX_KUBE"
write_conref "$KUBE_VERSION_FILE" "$MAX_KUBE"

# Runtime image conrefs, written only when the digest resolved. An
# empty value would blank the `workload.image` line on four 1.x pages,
# so an unresolved lookup keeps the previous value rather than writing
# a broken one. The miss was already warned about upstream and is
# repeated in the PR body.
echo "Runtime image conrefs:"
if [ -n "${RUNTIME_IMAGE:-}" ]; then
write_conref "$VERSIONS_DIR/runtime-image.md" "$RUNTIME_IMAGE"
else
echo " runtime-image.md: SKIPPED, unresolved digest. Left at $(cat "$VERSIONS_DIR/runtime-image.md")"
fi
if [ -n "${RUNTIME_IMAGE_CLAUDE:-}" ]; then
write_conref "$VERSIONS_DIR/runtime-image-claude.md" "$RUNTIME_IMAGE_CLAUDE"
else
echo " runtime-image-claude.md: SKIPPED, unresolved digest. Left at $(cat "$VERSIONS_DIR/runtime-image-claude.md")"
fi

# agent-substrate.md is version-split and 0.x is FROZEN:
# {{< version include-if="0.x" >}}0.0.6{{< /version >}}{{< version include-if="1.x" >}}0.0.26{{< /version >}}
# Replace only the 1.x span. The 0.x value documents what kagent 0.9.x
Expand Down Expand Up @@ -681,6 +824,7 @@ jobs:
--display-name kagent \
--out-dir "$KAGENT_CLI_DIR" \
--url-prefix "$KAGENT_CLI_URL_PREFIX" \
--link-prefix "$KAGENT_CLI_LINK_PREFIX" \
--weight 30

- name: Generate kmcp CLI reference docs
Expand Down Expand Up @@ -713,14 +857,18 @@ jobs:

${{ env.CONREF_NOTE }}

Version conrefs in this run, each read from the same place kagent's own build reads it:
${{ env.RUNTIME_IMAGE_NOTE }}

Version conrefs in this run. Each is read from the same place kagent's own build reads it, except the two runtime images, which are resolved from the registry because a digest exists only once the image is pushed:

| Conref | Value | Source in kagent |
| ------ | ----- | ---------------- |
| Conref | Value | Source |
| ------ | ----- | ------ |
| `agent-substrate` (1.x span only) | `${{ env.SUBSTRATE_VERSION }}` | `go/go.mod` replace target |
| `kmcp` | `${{ env.KMCP_VERSION }}` | `go/go.mod` require |
| `kagent-tools` | `${{ env.KAGENT_TOOLS_VERSION }}` | `helm/kagent/Chart-template.yaml` |
| `max-kube` (both committed copies) | `${{ env.MAX_KUBE }}` | `Makefile` `KIND_IMAGE_VERSION` |
| `runtime-image` | `${{ env.RUNTIME_IMAGE }}` | GHCR, at the tag in `versions/kagent.md` |
| `runtime-image-claude` | `${{ env.RUNTIME_IMAGE_CLAUDE }}` | GHCR, at the tag in `versions/kagent.md` |

Unchanged conref values are normal: most runs touch only the generated reference pages.

Expand Down
9 changes: 3 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,9 @@ install: ## Install web + docs dependencies (npm) and Hugo modules

# ── Docs (Hugo) ────────────────────────────────────────────────────────────
.PHONY: build-docs
# HUGO_CONFIG and HUGO_FLAGS let a preview build layer hugo.preview.yaml and pass
# -D without changing the production defaults. See docs-site/hugo.preview.yaml.
# HUGO_CONFIG and HUGO_FLAGS let a caller layer an extra config file or pass
# extra flags without changing the production defaults.
HUGO_CONFIG ?= hugo.yaml
# serve-docs layers the preview overlay by default: without it, local authoring
# renders every {{< version include-if="1.x" >}} conref empty. See docs-site/hugo.preview.yaml.
HUGO_CONFIG_PREVIEW ?= hugo.yaml,hugo.preview.yaml
HUGO_FLAGS ?=

build-docs: ## Build the Hugo docs site -> docs-site/public
Expand All @@ -63,7 +60,7 @@ inject-docs: ## Copy built docs into public/docs (preserves tracked assets, e.g.
# 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_CONFIG_PREVIEW) -D --disableFastRender --renderToMemory
cd $(DOCS_DIR) && $(HUGO) server --config $(HUGO_CONFIG) --disableFastRender --renderToMemory

# ── Web (Next.js) ──────────────────────────────────────────────────────────
.PHONY: serve-web
Expand Down
1 change: 1 addition & 0 deletions docs-site/assets/kagent-docs/snippets/name-ui.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
kagent-ui
2 changes: 1 addition & 1 deletion docs-site/assets/kagent-docs/versions/agent-substrate.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{{< version include-if="0.x" >}}0.0.9{{< /version >}}{{< version include-if="1.x" >}}0.0.26{{< /version >}}
{{< version include-if="0.x" >}}0.0.9{{< /version >}}{{< version include-if="1.x" >}}0.2.0-beta4{{< /version >}}
2 changes: 1 addition & 1 deletion docs-site/assets/kagent-docs/versions/kagent.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{{< version include-if="0.x" >}}0.10.1{{< /version >}}{{< version include-if="1.x" >}}1.0.0-beta0{{< /version >}}
{{< version include-if="0.x" >}}0.10.1{{< /version >}}{{< version include-if="1.x" >}}1.0.0-alpha1{{< /version >}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ghcr.io/kagent-dev/kagent/claude-harness@sha256:23b59459d66ce3162892239b035ba924cd1d64a6e3826db277599e9a98b2f36a
1 change: 1 addition & 0 deletions docs-site/assets/kagent-docs/versions/runtime-image.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ghcr.io/kagent-dev/kagent/golang-adk@sha256:c8ab012e9774d50e20ffa8cd035ddebff69486a2843b3af281f5f6ebc67ab512
Loading
Loading