Repository navigation
docs: update kagent 1.x docs for v1.0.0-rc1 - #652
Conversation
Signed-off-by: Rachael Graham <rachael.graham@solo.io>
Signed-off-by: Rachael Graham <rachael.graham@solo.io>
Docs preview
Both are uploaded Worker versions and serve no production traffic. |
Signed-off-by: Rachael Graham <rachael.graham@solo.io>
Signed-off-by: Rachael Graham <rachael.graham@solo.io>
Signed-off-by: Rachael Graham <rachael.graham@solo.io>
Signed-off-by: Rachael Graham <rachael.graham@solo.io>
Rachael-Graham
left a comment
There was a problem hiding this comment.
Inline notes on changes a reviewer might pause on.
| --out-dir "$KMCP_CLI_DIR" \ | ||
| --url-prefix "$KMCP_CLI_URL_PREFIX" | ||
|
|
||
| - name: Generate environment variable reference |
There was a problem hiding this comment.
Removed because kagent#3434 deleted docs/env.md at v1.0.0-rc1 and declared env vars internal wiring, not a supported interface. This step exits 1 when that file is missing, so the env-vars page and generate-env-docs.py are retired with it.
|
|
||
| A2A: | ||
| short: "The Agent-to-Agent protocol, which callers and other agents use to talk to an Agent. The conversation's context identifier is the Session ID, so a second message on the same ID continues the same conversation." | ||
| short: "The Agent2Agent protocol, which callers and other agents use to talk to an Agent. The conversation's context identifier is the Session ID, so a second message on the same ID continues the same conversation." |
There was a problem hiding this comment.
Agent2Agent is the protocol's own name; this sweep replaced both agent-to-agent spellings. This glossary is shared with 0.x, so the 0.x A2A tooltip changes too.
| } | ||
| ``` | ||
|
|
||
| The response contains the Agent's namespace, name, UID, labels, and annotations, and the ID of the Session and the revision that the Actor runs. The labels and annotations are the Agent's current values, returned unchanged. They include `kubectl.kubernetes.io/last-applied-configuration` when you applied the Agent with `kubectl apply`, so the service can read the Agent's full manifest. Do not put values in an Agent's labels or annotations that the receiving service must not see. The Session ID does not give the service access to the Session. |
There was a problem hiding this comment.
The lookup (kagent#3362) was live-tested, and its response really does include last-applied-configuration, which is why the page warns about labels and annotations. A token without the kagent-agent-info audience returned Invalid Agent identity credential.
| ## 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. | ||
| {{< 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). `kagent install` creates the certificate authority pools and the JWT authority pool that these identities are issued from. No Helm chart creates these pools. For an installation that you manage with Helm, see [Export the installation to Helm]({{< link path="operations/export-to-helm" >}}). |
There was a problem hiding this comment.
Factual fix: the old text said the installation guide covers creating these pools, but it no longer does. kagent install creates them now.
| ``` | ||
|
|
||
| 6. Let the Agent's namespace read Secrets in the shared namespace. Agent Substrate's credential provider controls which Secret namespaces each namespace's Agents can read, separately from `allowedNamespaces`. kagent does not widen this grant automatically. | ||
| 1. Read the current namespace policies. The `credentialProvider.namespacePolicies` list that you set replaces the existing list, so you must include the entries that your installation already has. |
There was a problem hiding this comment.
Without this grant, the Agent goes Ready but every model call returns 403; verified live. The list replaces the existing value, so a reader who skips this read step drops the default kagent entry.
| ``` | ||
|
|
||
| > [!IMPORTANT] | ||
| > `allowedNamespaces` gates compilation, not running agents. When you narrow the policy or remove a namespace label, the Agent reports `Ready=False`, but kagent keeps its last successful revision. New Sessions still start from that revision and use the shared ModelConfig's credential. To cut off a namespace completely, also remove its entry from `credentialProvider.namespacePolicies`. |
There was a problem hiding this comment.
Security-relevant and verified live: after removing the namespace label, the Agent showed Ready=False, but a new Session still started on the last good revision. Only removing the Substrate grant actually cuts the namespace off.
| - The server's `allowedNamespaces` field admits the AgentTemplate's namespace. Until the server admits the namespace, the controller cannot resolve the binding, and the Agent that runs that template does not become ready. | ||
| - The controller watches both namespaces. | ||
|
|
||
| The server sends no Secret-backed header, so an Agent in another namespace does not need an Agent Substrate Secret grant to reach it. For a RemoteMCPServer that does send one, see [Share an MCP server across namespaces]({{< link path="skills-and-mcp/about-tools#share-an-mcp-server-across-namespaces" >}}). |
There was a problem hiding this comment.
Live-tested at rc1: an Agent in another namespace called kagent-tool-server with no Agent Substrate grant to the kagent namespace, because the server sends no Secret-backed header. The Agent's namespace still needs its own namespacePolicies entry for its model Secret.
| gvisor: | ||
| url: gs://gvisor/releases/release/20260803/aarch64/gvisor.tar.bz2 | ||
| sha256: <sha256> | ||
| defaultVersion: v6 |
There was a problem hiding this comment.
Substrate 1.0.0-rc.1 reshaped SandboxConfig: defaultVersion plus versions[], and pauseImage is gone. The WorkerPool now resolves the config, not the ActorTemplate. This example matches the live gvisor-default with the digests elided.
| loglevel: debug | ||
| config: | ||
| logging: | ||
| level: debug |
There was a problem hiding this comment.
Factual fix: controller.loglevel does not exist in the rc1 chart. The controller's level is config.logging.level.
Signed-off-by: Rachael Graham <rachael.graham@solo.io>
There was a problem hiding this comment.
New guide to explain swapping from a demo cli install to a helm-managed install
There was a problem hiding this comment.
moved some existing namespace-scoping content out of the install page here, plus added some new rc1 functionality
kristin-kronstain-brown
left a comment
There was a problem hiding this comment.
Thank you, Rachael. This is a big, careful release update, and the inline notes made it much easier to review. The anchor preservation, the conventions pass, and the live-tested security notes are especially good.
I checked the claims against the kagent and Agent Substrate source at v1.0.0-rc1. I did not run the procedures on a cluster. Labels on each comment: Blocking is wrong content, Should fix is before merge, and Nit is optional.
Order of merges (blocking). The version conrefs on this branch still pin kagent 1.0.0-alpha17, Agent Substrate 0.6.0-alpha3, and the Substrate chart 0.4.0-alpha1, but the pages describe rc1. The rc1 reference-docs run has not happened yet, and it fails until the env-docs step is removed. Could the update-ref-docs.yaml change and the generate-env-docs.py deletion move to their own PR? Then we merge that, run the reference-docs update at v1.0.0-rc1, and merge this PR.
Not inline, because the lines are outside the diff:
reference/env-vars.mdis deleted without a redirect, so the published URL returns 404 after merge. Analiases:entry onreference/helm(or a similar page) would fix it.- The comment at
update-ref-docs.yaml:263still says "The CLI and env doc generators import PyYAML". - The PR description still calls this a draft for alpha18.
Overlapping automated drafts: #659, #661, #662, and #665 to #668 cover changes that this PR also makes. #664 (image pull secrets for the worker pool ServiceAccount) and #669 (the API breaks made before rc1) cover topics that I could not find here. Are those in scope for this PR?
| NAME AGE READY | ||
| my-agent 30s True | ||
| my-agent 30s True |
There was a problem hiding this comment.
Blocking (accuracy). At v1.0.0-rc1, the Agent CRD prints Ready before Age (helm/kagent-crds/templates/api.kagent.dev_agents.yaml). Each kubectl get command also prints its own header. This output came over from the old installation page, so the error is older than this PR.
| NAME AGE READY | |
| my-agent 30s True | |
| my-agent 30s True | |
| NAME READY AGE | |
| my-agent True 30s | |
| NAME READY AGE | |
| my-agent True 30s |
| my-agent 30s True | ||
| ``` | ||
|
|
||
| 4. Confirm that the Agent in the unwatched namespace stays unmanaged. The controller does not have a watch entry for that namespace. The Agent's `READY` value therefore stays `UNKNOWN`, and its conditions stay empty. |
There was a problem hiding this comment.
Blocking (accuracy). The Ready column is .status.conditions[?(@.type=='Ready')].status. An Agent with no conditions shows an empty cell, not UNKNOWN.
| 4. Confirm that the Agent in the unwatched namespace stays unmanaged. The controller does not have a watch entry for that namespace. The Agent's `READY` value therefore stays `UNKNOWN`, and its conditions stay empty. | |
| 4. Confirm that the Agent in the unwatched namespace stays unmanaged. The controller does not have a watch entry for that namespace. The Agent's `READY` value therefore stays empty, and its conditions stay empty. |
| NAME AGE READY | ||
| my-agent 30s UNKNOWN | ||
| null |
There was a problem hiding this comment.
Blocking (accuracy). The READY cell is empty, and -o jsonpath='{.status.conditions}' on a missing field prints nothing, not null.
| NAME AGE READY | |
| my-agent 30s UNKNOWN | |
| null | |
| NAME READY AGE | |
| my-agent 30s |
| * Kubernetes RBAC governs who can create Agents, Harnesses, AgentTemplates, and EgressPolicies in the namespace. | ||
| * The Agent Substrate credential policy limits which namespaces' Secrets the namespace's agents can read. | ||
| * An Agent or SandboxTemplate can select only the EgressPolicies in its own namespace. For more information, see [Access control]({{< link path="agents/egress-policies#access-control" >}}). | ||
| * A ModelConfig or RemoteMCPServer admits references only from the namespaces in its `allowedNamespaces` field. |
There was a problem hiding this comment.
Blocking (accuracy). allowedNamespaces is not a list of namespaces. It is {from: All|Same|Selector, selector}, and defaults to Same (go/api/v1alpha3/common_types.go). As written, readers will try to write a list.
| * A ModelConfig or RemoteMCPServer admits references only from the namespaces in its `allowedNamespaces` field. | |
| * A ModelConfig or RemoteMCPServer admits references only from the namespaces that its `allowedNamespaces` field selects. |
| * Agent Substrate has one credential policy. The policy lets agents in `kagent` read Secrets in `kagent` only. Each namespace that you prepare gets a policy of its own. | ||
| * The `default-model-config` ModelConfig and the `kagent-tool-server` RemoteMCPServer admit references from the `kagent` namespace only. To use them from another namespace, see [Share configuration across namespaces](#share-configuration-across-namespaces). | ||
|
|
||
| When you install the charts directly with Helm, the installation sets up the following defaults: |
There was a problem hiding this comment.
Should fix. Which install does this half of the section describe? I cannot find a page that documents installing the charts directly with Helm. identity.md also says that no Helm chart creates the identity pools, so a Helm-only install does not get far. An export applied with install.sh carries the CLI-generated values, so its defaults match the kagent install list instead. Should this half go, or should it say how a Helm-only install gets its pools?
If it stays, the list also leaves out default-model-config. The chart creates that ModelConfig by default, with providers.default: openAI in values.yaml.
|
|
||
| ```bash | ||
| kubectl port-forward -n kagent deployment/kagent-controller 8083:8083 & | ||
| TOKEN=$(kubectl create token scheduler -n ci-bots --audience kagent-invocation) |
There was a problem hiding this comment.
Nit. This command assumes a scheduler ServiceAccount in a ci-bots namespace. A one-line kubectl create namespace ci-bots && kubectl create serviceaccount scheduler -n ci-bots before it would make the example runnable. The port-forward on line 63 also keeps running in the background after the example ends.
| An agent can stop mid-task to ask a question or to request approval for a tool call. The task then reports `TASK_STATE_INPUT_REQUIRED` and waits until a caller answers it. By default, every agent on the `kagent` harness can raise the question kind, because the runtime gives each one a built-in `ask_user` tool. A system prompt that tells an agent to ask before it answers is therefore enough to see a pause. | ||
|
|
||
| Answering a pause needs the human-in-the-loop extension, which a caller requests per call. The extension is a versioned URI, and a request names it in two places: the `A2A-Extensions` header, and the message's own `extensions` list. | ||
| Answering a pause needs the human-in-the-loop extension, which a caller requests per call. The extension is a versioned URI. A request must include the URI in both the `A2A-Extensions` header and the message's own `extensions` list. |
There was a problem hiding this comment.
Should fix (contradiction with human-in-the-loop.md). Activation reads only the A2A-Extensions header (go/adk/pkg/a2a/hitl.go:43). Only a response message must list the URI in message.extensions (go/api/a2a/hitl.go:115-116, 146). human-in-the-loop.md says that the header is enough. Suggest: "A request activates the extension through the A2A-Extensions header. A response that answers a pause must also list the URI in the message's own extensions list."
| ### 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. | ||
| kagent sends a `tools` array with `tool_choice: "auto"` on every request. By default, kagent's runtime registers a built-in `ask_user` tool on every agent, so kagent sends that array even when you do not bind any tools yourself. To prevent every agent turn from failing, launch vLLM with automatic tool choice enabled. |
There was a problem hiding this comment.
Should fix. "By default" suggests that disableAskUser: true stops the tools array from being sent, but it does not. The runtime always registers read_file, write_file, edit_file, list_files, grep_file, and bash (upstream docs/architecture/process-configuration.md, lines 226-233). Suggest: "kagent's runtime always registers built-in tools, such as the file tools, on every agent, so kagent sends that array even when you do not bind any tools yourself."
| ``` | ||
|
|
||
| 3. Apply the converted resources. | ||
| 3. Delete the ModelConfig fields that `v1alpha3` removed from the converted file. The conversion command does not delete them, and the apply fails while they remain. If the file includes the `kagent-grafana-mcp` RemoteMCPServer, delete it too, because 1.0 does not deploy the Grafana Model Context Protocol (MCP) server behind it. |
There was a problem hiding this comment.
Should fix. This step tells the reader to delete "the ModelConfig fields that v1alpha3 removed" without naming them. Could you list the fields, or add a yq del(...) to the conversion command in step 2, so that the reader does not have to find them by failing an apply?
| ``` | ||
|
|
||
| The Agent's status reports two revision fields that answer a different question. `desiredRevision` is the {{< gloss "Revision" >}}revision{{< /gloss >}} that the current spec should produce, and `latestSuccessfulRevision` is the newest revision that finished preparing. A missing `latestSuccessfulRevision` means that the Agent was never ready, and two differing values mean that the newest edit is not yet prepared. | ||
| A failed golden snapshot is not final. When Agent Substrate fails to build the golden snapshot, kagent deletes the failed ActorTemplate and rebuilds it after 15 seconds, 1 minute, and 4 minutes, and then every 10 minutes indefinitely. While a rebuild waits, `Ready` is `False` with the reason `ActorTemplateRetrying` and a message such as `golden build failed (GoldenActorCrashed), retry 1 at <time>`. The message omits Agent Substrate's full error, because that error can quote your configuration. Read the full error in the controller log. When a configuration fault causes the failure, kagent retries until you edit the Agent or the SandboxTemplate. |
There was a problem hiding this comment.
Nit. These are base delays. Each one gets up to 20% jitter (maxJitterFraction: 0.2 in go/core/internal/controller/golden_retry.go:30-33). "About 15 seconds, 1 minute, and 4 minutes" would match better.
Signed-off-by: Rachael Graham <rachael.graham@solo.io>
Signed-off-by: Rachael Graham <rachael.graham@solo.io>
kagent#3434 deleted docs/env.md at v1.0.0-rc1 and declared environment variables internal wiring rather than a supported interface. The "Generate environment variable reference" step exits 1 when that file is missing, so every rc1 reference-docs run fails until it is removed. Remove the step, the WITH_ENV_DOCS and KAGENT_ENV_PAGE plumbing, the ENV_DOCS_NOTE in the generated PR body, and scripts/generate-env-docs.py. The helm.md write step now carries over an existing aliases: block from the page it overwrites. The 1.x env-vars page is deleted in the alpha18 docs PR (#652) with an alias on reference/helm.md, and without this the next regeneration would drop that alias and 404 the old URL. Signed-off-by: Rachael Graham <rachael.graham@solo.io> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Updates the 1.x docs for kagent v1.0.0-rc1. Each claim is checked against the rc1 source, and the behavioral ones are live-tested on a kind 1.37 cluster.
New rc1 features. This PR documents cross-namespace ModelConfig and MCP server references, Actor JWTs, service account callers and the agent identity lookup, push delivery settings, and the golden-build retry.
Pages that rc1 made wrong. These pages now cover:
ListSubstrateActors,ListSubstrateWorkers, andGetSubstrateSummarymethods that replaceGetSubstrateStatus.ateworker-*image rename.config.logging.level.New pages. "Run agents in multiple namespaces" takes the namespace sections from the installation page and adds the rc1 behavior. "Export a CLI installation to Helm" covers moving an installation to Helm.
Retired. The env-vars page is deleted (kagent#3434) and redirects to the Helm reference. The workflow change is in #674.
Worth a close look: the per-namespace
credentialProvider.namespacePoliciesrequirement on multiple-namespaces.md. Without it an Agent goes Ready, but every model call returns 403. A selector-based share on a restricted installation also needs a Namespace ClusterRole.Also: "Agent2Agent (A2A)" spelling throughout.
Merge #674, run the reference-docs workflow at
v1.0.0-rc1, then merge this PR.🤖 Generated with Claude Code