Skip to content

alpha5-7: Rebaseline on new api group, CRDs, and more - #551

Merged
Rachael-Graham merged 22 commits into
mainfrom
rlg-alpha5-rebaseline
Oct 2, 2026
Merged

Rachael-Graham merged 22 commits into
mainfrom
rlg-alpha5-rebaseline

Conversation

@Rachael-Graham

@Rachael-Graham Rachael-Graham commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Re-baselines the 1.x doc set from kagent 1.0.0-alpha2 to 1.0.0-alpha7, with Agent Substrate 0.3.0-alpha3. Closes #549, which was written against alpha5 — alpha6's kagent#3007 reverted two things that issue states as fact, so the work follows alpha7.

Product changes the docs now reflect

  • API group kagent.dev/v1alpha3 → api.kagent.dev/v1alpha3, on every example.
  • Agent is a real CRD pairing an AgentTemplate with a Harness, and AgentInstance is now Session. Core concepts, the getting-started flow, and the glossary follow.
  • Agent-runtime environment variables validated against generated docs/env.md; removed ones are gone.
  • New page for standalone sandboxes. Controller auth modes added to identity.
  • Regenerated CLI reference, API reference, and Helm values.

Verified on a cluster

Installed alpha7 on kind and ran get-started/your-first-agent end to end. UI screenshots re-captured against that install; the dashboard capture was unchanged and is left alone.

Two defects surfaced on the way and are fixed here: the install guide was setting controller.substrate.defaultWorkerPool, which kagent#2967 removed, and the screenshot harness's mock-mode variable was renamed upstream, which had been silently aiming it at a live backend.

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>
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>
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>
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>
Signed-off-by: Rachael Graham <rachael.graham@solo.io>
@github-actions

github-actions Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Docs preview

Link Points at
Branch preview The newest push to this branch. Updates in place.
Commit preview ce60723 only. Frozen.

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>
---

{{< reuse "kagent-docs/snippets/name-product.md" >}} 1.0 runs every agent on [Agent Substrate]({{< link path="about/architecture/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.
{{< reuse "kagent-docs/snippets/name-product.md" >}} 1.0 runs every agent on [Agent Substrate]({{< link path="about/architecture/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 Agent API that you author against. Install Agent Substrate first, because the kagent controller connects to it at startup.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it agent or session?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agent is correct here — Harness, AgentTemplate, and Agent are the three CRDs you author with kubectl. A Session is not authored: kagent's gRPC API creates one for each running conversation.

## Subagents 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.
A `subAgent` 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. A description that states plainly what the bound agent is for therefore matters more than the detail of its configuration.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A `subAgent` 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. A description that states plainly what the bound agent is for therefore matters more than the detail of its configuration.
A `subAgent` binding points at another AgentTemplate, which allows an agent to route traffic to another agent. The model reads the `description` when it decides whether to route work here. A description that states plainly what the bound agent is for therefore matters more than the detail of its configuration.


> [!WARNING]
> The open source build neither authenticates nor authorizes this path: the authenticator it installs admits every request, and the authorizer it installs permits every check. Any caller that reaches the gRPC endpoint can author an agent's runtime and behavior, whatever their Kubernetes permissions are. Do not expose port `8083` outside the cluster. For the identity that the open source build gives an anonymous caller, see [The kagent plane](#the-kagent-plane).
> By default, kagent neither authenticates nor authorizes this path: the `insecure` authenticator admits every request, and the authorizer it installs permits every check. Any caller that reaches the gRPC endpoint can author an agent's runtime and behavior, whatever their Kubernetes permissions are. Do not expose port `8083` outside the cluster. For the identity that this mode gives an anonymous caller, and for the mode that changes it, see [The kagent plane](#the-kagent-plane).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
> By default, kagent neither authenticates nor authorizes this path: the `insecure` authenticator admits every request, and the authorizer it installs permits every check. Any caller that reaches the gRPC endpoint can author an agent's runtime and behavior, whatever their Kubernetes permissions are. Do not expose port `8083` outside the cluster. For the identity that this mode gives an anonymous caller, and for the mode that changes it, see [The kagent plane](#the-kagent-plane).
> By default, kagent neither authenticates nor authorizes this path. The `insecure` authenticator admits every request, and the authorizer it installs permits every check. Any caller that reaches the gRPC endpoint can author an agent's runtime and behavior, whatever their Kubernetes permissions are. Do not expose port `8083` outside the cluster. For the identity that this mode gives an anonymous caller, and for the mode that changes it, see [The kagent plane](#the-kagent-plane).

> By default, kagent neither authenticates nor authorizes this path: the `insecure` authenticator admits every request, and the authorizer it installs permits every check. Any caller that reaches the gRPC endpoint can author an agent's runtime and behavior, whatever their Kubernetes permissions are. Do not expose port `8083` outside the cluster. For the identity that this mode gives an anonymous caller, and for the mode that changes it, see [The kagent plane](#the-kagent-plane).

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" >}}).
An Agent is where RBAC decides which template runs on which Harness, because neither reusable resource names the other. Whoever can write Agents in a namespace decides every pairing in it, whatever their access to the Harnesses and AgentTemplates that those Agents name. For the pairing itself, see the [Agent core concept]({{< link path="about/core-concepts#agent" >}}).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the first two sentences are confusing to me. are we just saying that the user's permissions on these resources decide what the agent will be able to do?


### Controller authentication modes

The `controller.auth.mode` Helm value selects which authenticator the controller installs. The chart defaults to `insecure`, and enabling the bundled oauth2-proxy does not change it. Browser sign-in and controller authentication are separate boundaries. A deployment that wants both sets this value as well.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A deployment that wants both sets this value as well.

not sure what this means

---

{{< reuse "kagent-docs/snippets/name-product.md" >}} 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. For a summary of what changed in 1.0, see the [Release notes]({{< link path="reference/release-notes/1.0#100" >}}). No newline at end of file
{{< reuse "kagent-docs/snippets/name-product.md" >}} 1.0 moves the runtime from Kubernetes Deployments to [Agent Substrate](https://github.com/agent-substrate/substrate), introducing Harness, AgentTemplate, and Agent as the new API surface, with a Session for each running conversation. For a summary of what changed in 1.0, see the [Release notes]({{< link path="reference/release-notes/1.0#100" >}}). No newline at end of file

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just making sure that both Agent and Session are correct here as we seem to replace AgentInstance with Sessions throughout

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.

Substrate adds enforcement. It 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.
Substrate adds enforcement. It 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 Session references it.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also here not sure if this should maybe be an Agent instead?

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.
kagent names each atespace after the Kubernetes namespace of the Agent whose Actor it holds, and creates that atespace on demand the first time a Session in the namespace needs an Actor. The Actor's own name is `session-` followed by the Session's identifier. A Session on an Agent 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.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
kagent names each atespace after the Kubernetes namespace of the Agent whose Actor it holds, and creates that atespace on demand the first time a Session in the namespace needs an Actor. The Actor's own name is `session-` followed by the Session's identifier. A Session on an Agent 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.
Kagent names each atespace after the Kubernetes namespace of the Agent whose Actor it holds, and creates that atespace on demand the first time a Session in the namespace needs an Actor. The Actor's own name is `session-` followed by the Session's identifier. A Session on an Agent 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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had looked into this a while back, and we arent meant to capitalize at the beginning of a sentence. The website itself has it lowercase on the home screen https://kagent.dev/


- 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 with `kubectl`, 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.
- The **kagent plane** governs any interactions involving {{< gloss "Session" >}}Sessions{{< /gloss >}}, such as creating, suspending, resuming, sharing, deleting, and holding a conversation with a Session. kagent's own gRPC authentication and authorization decide who can complete these interactions, independent of Kubernetes RBAC.

@Nadine2016 Nadine2016 Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- The **kagent plane** governs any interactions involving {{< gloss "Session" >}}Sessions{{< /gloss >}}, such as creating, suspending, resuming, sharing, deleting, and holding a conversation with a Session. kagent's own gRPC authentication and authorization decide who can complete these interactions, independent of Kubernetes RBAC.
- The **kagent control plane** governs any interactions involving {{< gloss "Session" >}}Sessions{{< /gloss >}}, such as creating, suspending, resuming, sharing, deleting, and holding a conversation with a Session. Kagent's own gRPC authentication and authorization decide who can complete these interactions, independent of Kubernetes RBAC.

- The **kagent plane** governs any interactions involving {{< gloss "Session" >}}Sessions{{< /gloss >}}, such as creating, suspending, resuming, sharing, deleting, and holding a conversation with a Session. 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. The planes are not mirror images, though. kagent's gRPC API also writes Harness and AgentTemplate resources, so a caller on the kagent plane reaches both. For more information on that second path, see [Identity]({{< link path="substrate-runtime/identity#the-kubernetes-plane" >}}).
Someone with Kubernetes RBAC access to apply an Agent and the resources it names does not automatically have access to create or talk to Sessions on it. The planes are not mirror images, though. kagent's gRPC API also writes those Kubernetes resources, so a caller on the kagent plane reaches both. For more information on that second path, see [Identity]({{< link path="substrate-runtime/identity#the-kubernetes-plane" >}}).

@Nadine2016 Nadine2016 Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Someone with Kubernetes RBAC access to apply an Agent and the resources it names does not automatically have access to create or talk to Sessions on it. The planes are not mirror images, though. kagent's gRPC API also writes those Kubernetes resources, so a caller on the kagent plane reaches both. For more information on that second path, see [Identity]({{< link path="substrate-runtime/identity#the-kubernetes-plane" >}}).
Someone with Kubernetes RBAC access who can apply an Agent and the resources it names, does not automatically have access to create or talk to Sessions on it. The planes are not mirror images, though. Kagent's gRPC API also writes those Kubernetes resources, so a caller on the kagent plane reaches both. For more information on that second path, see [Identity]({{< link path="substrate-runtime/identity#the-kubernetes-plane" >}}).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure what this means: The planes are not mirror images, though.

Follow the **Kubernetes plane** first. An operator applies a Harness, an AgentTemplate, and an Agent that pairs them with `kubectl`, governed by Kubernetes RBAC. The diagram shows this path because RBAC governs it, and kagent's gRPC API reaches the same resources instead. The kagent controller watches each Agent, resolves the template and harness that it names, and compiles the result 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, rather than a Kubernetes object. 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 >}}.
The **kagent plane** starts once that ActorTemplate exists. A caller, who may or may not be the same person as the operator, calls `CreateSession` through kagent's gRPC API. This call is governed by kagent's own authentication and authorization, not by Kubernetes RBAC. kagent creates the Session from the Agent's latest successful revision. That Session runs on an {{< gloss "Actor" >}}Actor{{< /gloss >}}.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The **kagent plane** starts once that ActorTemplate exists. A caller, who may or may not be the same person as the operator, calls `CreateSession` through kagent's gRPC API. This call is governed by kagent's own authentication and authorization, not by Kubernetes RBAC. kagent creates the Session from the Agent's latest successful revision. That Session runs on an {{< gloss "Actor" >}}Actor{{< /gloss >}}.
The **kagent plane** starts once that ActorTemplate exists. A caller, who might be the same person as the operator, calls `CreateSession` through kagent's gRPC API. This call is governed by kagent's own authentication and authorization, not by Kubernetes RBAC. Kagent creates the Session from the Agent's latest successful revision. That Session runs on an {{< gloss "Actor" >}}Actor{{< /gloss >}}.

## kagent 1.0

{{< reuse "kagent-docs/snippets/name-product.md" >}} 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/architecture/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. If you already have a 0.x installation, see [Upgrade from 0.x]({{< link path="operations/upgrade-from-0x#recreate-your-resources" >}}), which maps each 0.x resource onto its 1.0 replacement.
{{< reuse "kagent-docs/snippets/name-product.md" >}} 1.0 replaces the Deployment-based `Agent` custom resource with a new model built around **Harness**, **AgentTemplate**, **Agent**, and **Session**, running on [Agent Substrate]({{< link path="about/architecture/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. If you already have a 0.x installation, see [Upgrade from 0.x]({{< link path="operations/upgrade-from-0x#recreate-your-resources" >}}), which maps each 0.x resource onto its 1.0 replacement.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the first sentence says we replace agent with agent

| `spec.harnessRef` | An existing Harness in the Agent's namespace, by name |
| `spec.harness` | A complete Harness spec, written inline |

The two sides are independent, so an Agent can reference both, inline both, or mix the two. An inline spec is a complete value rather than an override of a referenced one, and kagent creates no Kubernetes object to back it. Every reference, including one nested inside an inline spec, resolves in the Agent's own namespace.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The two sides are independent, so an Agent can reference both, inline both, or mix the two. An inline spec is a complete value rather than an override of a referenced one, and kagent creates no Kubernetes object to back it. Every reference, including one nested inside an inline spec, resolves in the Agent's own namespace.
The AgentTemplate and Harness pairing can be configured independently, so an Agent can reference both, inline both, or mix the two. Every reference, including one that is nested inside an inline spec, resolves in the Agent's own namespace.


The two sides are independent, so an Agent can reference both, inline both, or mix the two. An inline spec is a complete value rather than an override of a referenced one, and kagent creates no Kubernetes object to back it. Every reference, including one nested inside an inline spec, resolves in the Agent's own namespace.

This Agent references both sides:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This Agent references both sides:
The following Agent resource references both sides:

## Session

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.
A **Session** is a _running conversation with one Agent_. Unlike the three resources it is built from, a Session 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.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A **Session** is a _running conversation with one Agent_. Unlike the three resources it is built from, a Session 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.
A **Session** is a _running conversation with one Agent_. Unlike the three resources it is built from, a Session 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.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we say there are three resources it is built from, but those are not mentioned. maybe we can just remove that part of the sentence

- Creating, suspending, resuming, sharing, or deleting a Session, 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` an Agent.

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 **{{< gloss "Revision" >}}revision{{< /gloss >}}**, identified by a digest, which is a SHA-256 hash of the compiled configuration. Because that digest is derived from the configuration itself, editing an Agent or either resource it references compiles to a different digest, and therefore becomes a separate ActorTemplate. kagent never rewrites an existing one.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Each compile produces one **{{< gloss "Revision" >}}revision{{< /gloss >}}**, identified by a digest, which is a SHA-256 hash of the compiled configuration. Because that digest is derived from the configuration itself, editing an Agent or either resource it references 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, which is a SHA-256 hash of the compiled configuration. Because that digest is derived from the configuration itself, editing an Agent or either resource it references compiles to a different digest, and therefore becomes a separate ActorTemplate. Kagent never rewrites an existing one.

After it is created, a Session talks to callers over the {{< gloss "A2A" >}}A2A{{< /gloss >}} (Agent-to-Agent) protocol, through kagent's A2A gateway. Callers address the Agent rather than the Session. The HTTP endpoint is `/agents/{namespace}/{name}` and gRPC carries the same `namespace/name` in the standard A2A `tenant` field. The Session's ID is the A2A `contextId`, so a message that carries no context identifier starts a new conversation, and a message that repeats one continues that conversation.

For the AgentInstance gRPC service definition, see the [API reference]({{< link path="reference/api-ref" >}}).
A Session that records no task activity for seven days is deleted by an expiration worker. The `controller.sessionIdleTTL` Helm value sets that window. `0` turns the worker off. For what the deletion retains, see [Expire idle conversations]({{< link path="operations/operational-considerations#expire-idle-conversations" >}}).

@Nadine2016 Nadine2016 Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A Session that records no task activity for seven days is deleted by an expiration worker. The `controller.sessionIdleTTL` Helm value sets that window. `0` turns the worker off. For what the deletion retains, see [Expire idle conversations]({{< link path="operations/operational-considerations#expire-idle-conversations" >}}).
A Session that records no task activity for seven days is deleted by an expiration worker. The `controller.sessionIdleTTL` Helm value sets that window. A value of `0` turns the expiration worker off. For more information about what the deletion retains, see [Expire idle conversations]({{< link path="operations/operational-considerations#expire-idle-conversations" >}}).

| `workload.command` | For `byo` | Overrides the image entrypoint, up to 32 entries. Required for the `byo` runtime, optional otherwise. Every runtime honors an explicit value, the `kagent` runtime included, whatever language its image is written in. |
| `workload.args` | No | Overrides the image arguments, up to 64 entries. An override that you omit stays unset rather than taking a default. |
| `env` | No | Environment variables for the runtime, up to 100. Each entry sets a literal `value`. A `credentialRef` is accepted by the API and then rejected at compile time on every runtime, so put credentials on a ModelConfig or a RemoteMCPServer instead. For more information, see [About model providers]({{< link path="setup/model-providers/about-model-providers#credentials-that-do-not-compile" >}}). |
| `env` | No | Environment variables for the runtime, up to 100. Each entry sets a literal `value`, which is required and may be an empty string. The schema defines no secret-backed source, so the API server rejects a `credentialRef` entry as an unknown field. Put credentials on a ModelConfig or a RemoteMCPServer instead. For more information, see [About model providers]({{< link path="setup/model-providers/about-model-providers#credentials-that-do-not-compile" >}}). |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| `env` | No | Environment variables for the runtime, up to 100. Each entry sets a literal `value`, which is required and may be an empty string. The schema defines no secret-backed source, so the API server rejects a `credentialRef` entry as an unknown field. Put credentials on a ModelConfig or a RemoteMCPServer instead. For more information, see [About model providers]({{< link path="setup/model-providers/about-model-providers#credentials-that-do-not-compile" >}}). |
| `env` | No | Environment variables for the runtime, up to 100. Each entry sets a literal `value`, which is required and can be an empty string. The schema defines no secret-backed source, so the API server rejects a `credentialRef` entry as an unknown field. Put credentials on a ModelConfig or a RemoteMCPServer instead. For more information, see [About model providers]({{< link path="setup/model-providers/about-model-providers#credentials-that-do-not-compile" >}}). |

| `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. |

A command or argument override belongs to the revision that kagent prepares, so changing one prepares a new revision rather than altering a running agent. An AgentInstance pinned to an earlier revision keeps the command it was prepared with until it moves to the new one.
A Harness names no AgentTemplate. An {{< gloss "Agent" >}}Agent{{< /gloss >}} pairs the two through either `spec.harnessRef` or an inline `spec.harness`, so whoever writes the Agent decides which template runs on which Harness. For that pairing, see [Core concepts]({{< link path="about/core-concepts#agent" >}}).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A Harness names no AgentTemplate. An {{< gloss "Agent" >}}Agent{{< /gloss >}} pairs the two through either `spec.harnessRef` or an inline `spec.harness`, so whoever writes the Agent decides which template runs on which Harness. For that pairing, see [Core concepts]({{< link path="about/core-concepts#agent" >}}).
A Harness names no AgentTemplate. An {{< gloss "Agent" >}}Agent{{< /gloss >}} pairs the two through either `spec.harnessRef` or an inline `spec.harness`, so whoever writes the Agent decides which template runs on which Harness. For more information about the pairing process, see [Core concepts]({{< link path="about/core-concepts#agent" >}}).

| `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.
3. Create a new Session against an {{< gloss "Agent" >}}Agent{{< /gloss >}} that uses this Harness. Editing the Harness compiles a new {{< gloss "Revision" >}}revision{{< /gloss >}}, and an existing Session keeps running the revision it was created from. An agent that was already running does not gain memory until you start a new conversation.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
3. Create a new Session against an {{< gloss "Agent" >}}Agent{{< /gloss >}} that uses this Harness. Editing the Harness compiles a new {{< gloss "Revision" >}}revision{{< /gloss >}}, and an existing Session keeps running the revision it was created from. An agent that was already running does not gain memory until you start a new conversation.
3. Create a new Session against an {{< gloss "Agent" >}}Agent{{< /gloss >}} that uses this Harness. Editing the Harness compiles a new {{< gloss "Revision" >}}revision{{< /gloss >}}, and an existing Session keeps running the revision it was created from. An agent that was already running does not gain memory until you start a new Session.

Signed-off-by: Rachael Graham <rachael.graham@solo.io>
Set `spec.outputSchema` to keep the schema in the AgentTemplate, so that the schema and the rest of the agent's configuration change together.

1. Apply an AgentTemplate with a schema. The `kagent.dev/harness` label matches the `allowedAgentTemplates` selector of `my-first-harness`.
1. Apply an AgentTemplate with a schema, and an Agent that pairs it with `my-first-harness`.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1. Apply an AgentTemplate with a schema, and an Agent that pairs it with `my-first-harness`.
1. Apply an AgentTemplate with a schema, and an Agent that pairs it with the `my-first-harness` Harness.


An HTTP request that also sets a tenant must set one that matches its URL. There is no deployment-wide agent card, because the gateway serves many agents.

A caller addresses the Agent rather than one conversation. The message's `contextId` selects the conversation: omitting both a `contextId` and a task ID starts a new {{< gloss "Session" >}}Session{{< /gloss >}}, and repeating a `contextId` continues that Session.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A caller addresses the Agent rather than one conversation. The message's `contextId` selects the conversation: omitting both a `contextId` and a task ID starts a new {{< gloss "Session" >}}Session{{< /gloss >}}, and repeating a `contextId` continues that Session.
A caller addresses the Agent rather than one conversation. The message's `contextId` selects the conversation. Omitting both a `contextId` and a task ID starts a new {{< gloss "Session" >}}Session{{< /gloss >}}, and repeating a `contextId` continues that Session.

## Invoke the agent

At this point, the BYO agent behaves in the same way as any other. The {{< gloss "AgentInstance" >}}AgentInstance{{< /gloss >}} is the conversation, the CLI reaches it through the controller's A2A service, and nothing in these commands names the runtime.
At this point, the BYO agent behaves in the same way as any other. The {{< gloss "Session" >}}Session{{< /gloss >}} is the conversation, the CLI reaches it through the controller's A2A service, and nothing in these commands names the runtime.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
At this point, the BYO agent behaves in the same way as any other. The {{< gloss "Session" >}}Session{{< /gloss >}} is the conversation, the CLI reaches it through the controller's A2A service, and nothing in these commands names the runtime.
At this point, the BYO agent behaves in the same way as any other. The {{< gloss "Session" >}}Session{{< /gloss >}} is the conversation, the CLI reaches it through the controller's A2A service.

That string is hardcoded, so the reply itself proves nothing. Its path proves the contract: kagent compiled a revision, Agent Substrate started a sandboxed {{< gloss "Actor" >}}Actor{{< /gloss >}} from your image, the controller's A2A gateway routed the message to it, and your executor answered.

4. Send another message to the same AgentInstance. The reply does not change, but the message reaches the same Actor. Agent Substrate suspended that Actor after the first turn and resumed it for this one. For that cycle, see [Suspend and resume]({{< link path="substrate-runtime/suspend-and-resume#suspension-between-turns" >}}).
4. Send another message to the same Session. The reply does not change, but the message reaches the same Actor. Agent Substrate suspended that Actor after the first turn and resumed it for this one. For that cycle, see [Suspend and resume]({{< link path="substrate-runtime/suspend-and-resume#suspension-between-turns" >}}).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
4. Send another message to the same Session. The reply does not change, but the message reaches the same Actor. Agent Substrate suspended that Actor after the first turn and resumed it for this one. For that cycle, see [Suspend and resume]({{< link path="substrate-runtime/suspend-and-resume#suspension-between-turns" >}}).
4. Send another message to the same Session. The reply does not change, but the message reaches the same Actor. Agent Substrate suspended that Actor after the first turn and resumed it for this message. For more information about the Actor lifecycle, see [Suspend and resume]({{< link path="substrate-runtime/suspend-and-resume#suspension-between-turns" >}}).


> [!IMPORTANT]
> **A `Shared` binding hands over the conversation rather than returning an answer.** kagent compiles the binding into a sub-agent of the parent and runs the whole tree in one Actor, so the parent's model can transfer the turn to it. Once that happens, the bound agent answers, and it keeps answering the turns that follow in the same conversation. The parent does not receive the bound agent's output and cannot summarize it or combine it with a second agent's. Plan a tree around routing a conversation to the right specialist, rather than around a coordinator that collects results.
> **A subagent binding hands over the conversation rather than returning an answer.** kagent compiles the binding into a subagent of the parent and runs the whole tree in one Actor, so the parent's model can transfer the turn to it. Once that happens, the bound agent answers, and it keeps answering the turns that follow in the same conversation. The parent does not receive the bound agent's output and cannot summarize it or combine it with a second agent's. Plan a tree around routing a conversation to the right specialist, rather than around a coordinator that collects results.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
> **A subagent binding hands over the conversation rather than returning an answer.** kagent compiles the binding into a subagent of the parent and runs the whole tree in one Actor, so the parent's model can transfer the turn to it. Once that happens, the bound agent answers, and it keeps answering the turns that follow in the same conversation. The parent does not receive the bound agent's output and cannot summarize it or combine it with a second agent's. Plan a tree around routing a conversation to the right specialist, rather than around a coordinator that collects results.
> **A subagent binding hands over the conversation rather than returning an answer.** Kagent compiles the binding into a subagent of the parent and runs the whole tree in one Actor, so the parent's model can transfer the turn to it. Once that happens, the bound agent answers, and it keeps answering the turns that follow in the same conversation. The parent does not receive the bound agent's output and cannot summarize it or combine it with a second agent's. Plan a tree around routing a conversation to the right specialist, rather than around a coordinator that collects results.

## MCP tool reference

The server exposes five tools. Two cover discovery and conversation, and three expose the {{< gloss "Checkpoint" >}}checkpoint{{< /gloss >}} operations, so a client can pin and branch an agent's state as well as talk to it. Every tool takes a `namespace` because an AgentInstance is scoped to one. No tool deletes an object, so removing an AgentInstance or a checkpoint means leaving MCP for the command line.
The server exposes five Session tools. Two cover discovery and conversation. Three expose the {{< gloss "Checkpoint" >}}checkpoint{{< /gloss >}} operations, so a client can pin and branch an agent's state as well as talk to it. No tool takes a namespace. A Session is addressed by its own UUID. No tool deletes an object either, so removing a Session or a checkpoint means leaving MCP for the command line. The server also exposes a set of [standalone sandbox]({{< link path="substrate-runtime/standalone-sandboxes" >}}) tools, which this example does not cover.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does means leaving MCP for the command line mean?

---

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 {{< reuse "kagent-docs/snippets/name-product.md" >}}, review the [architecture]({{< link path="about/architecture/kagent" >}}). 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 Agent that pairs them. You apply the Harness, the AgentTemplate, and the Agent as Kubernetes resources. You create and talk to a Session 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 {{< reuse "kagent-docs/snippets/name-product.md" >}}, review the [architecture]({{< link path="about/architecture/kagent" >}}). For the complete schema of every field that this guide sets, see the [API reference]({{< link path="reference/api-ref" >}}).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This guide walks you through creating an agent, from applying a Harness and an AgentTemplate to holding a conversation with the Agent that pairs them. You apply the Harness, the AgentTemplate, and the Agent as Kubernetes resources. You create and talk to a Session 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 {{< reuse "kagent-docs/snippets/name-product.md" >}}, review the [architecture]({{< link path="about/architecture/kagent" >}}). 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 Agent that pairs them. You apply the Harness, the AgentTemplate, and the Agent as Kubernetes resources. Then, you create and talk to a Session 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 {{< reuse "kagent-docs/snippets/name-product.md" >}}, review the [architecture]({{< link path="about/architecture/kagent" >}}). For the complete schema of every field that this guide sets, see the [API reference]({{< link path="reference/api-ref" >}}).

```

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.
3. Apply an `Agent` that names both. Nothing pairs a Harness and an AgentTemplate implicitly, so this resource is what makes the two runnable together.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
3. Apply an `Agent` that names both. Nothing pairs a Harness and an AgentTemplate implicitly, so this resource is what makes the two runnable together.
3. Apply an `Agent` that pairs a Harness and an AgentTemplate.

{{< reuse-image-light src="img/kagent-ui-agents.png" alt="The Agents page, listing agents, templates, and harnesses" caption="Figure: The Agents page" >}}
{{< reuse-image-dark srcDark="img/kagent-ui-agents-dark.png" alt="The Agents page, listing agents, templates, and harnesses" caption="Figure: The Agents page" >}}

The **Agents** tab authors the `Agent` custom resource directly. Create one to pair a template with a harness, edit one to change either side, and delete one to retire the pairing. Deleting an Agent leaves its Sessions in place, along with the AgentTemplate and Harness that it named. For the same work from the command line, see [Create your first agent]({{< link path="get-started/your-first-agent" >}}).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The **Agents** tab authors the `Agent` custom resource directly. Create one to pair a template with a harness, edit one to change either side, and delete one to retire the pairing. Deleting an Agent leaves its Sessions in place, along with the AgentTemplate and Harness that it named. For the same work from the command line, see [Create your first agent]({{< link path="get-started/your-first-agent" >}}).
The **Agents** tab authors the `Agent` custom resource directly. Create one to pair a template with a harness, edit one to change either side, and delete one to retire the pairing. Deleting an Agent leaves its Sessions in place, along with the AgentTemplate and Harness that it named. For CLI steps, see [Create your first agent]({{< link path="get-started/your-first-agent" >}}).

1. [Install kagent]({{< link path="setup/installation" >}}), including the `kubectl-ate` plugin that the installation guide describes.
2. [Create your first agent]({{< link path="get-started/your-first-agent" >}}), and send it at least one message, so that the `my-first-agent` AgentTemplate and the `my-first-harness` Harness have an Actor with logs to read. That guide also installs the kagent CLI.
3. Install [`jq`](https://jqlang.org/download/), to read the AgentInstance ID and filter the JSON log records.
2. [Create your first agent]({{< link path="get-started/your-first-agent" >}}), then send it at least one message. That gives the `my-first-agent` Agent an Actor with logs to read. That guide also installs the kagent CLI.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
2. [Create your first agent]({{< link path="get-started/your-first-agent" >}}), then send it at least one message. That gives the `my-first-agent` Agent an Actor with logs to read. That guide also installs the kagent CLI.
2. [Create your first agent]({{< link path="get-started/your-first-agent" >}}) and send it at least one message. This setup gives the `my-first-agent` Agent an Actor with logs to read. The guide also installs the kagent CLI.


## Expire idle conversations

A conversation that nobody returns to still holds a row in your database and a pinned runtime revision. kagent deletes idle {{< gloss "Session" >}}Sessions{{< /gloss >}} on a timer so that neither accumulates without a bound.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A conversation that nobody returns to still holds a row in your database and a pinned runtime revision. kagent deletes idle {{< gloss "Session" >}}Sessions{{< /gloss >}} on a timer so that neither accumulates without a bound.
A conversation that nobody returns to still holds a row in your database and a pinned runtime revision. The kagent controller deletes idle {{< gloss "Session" >}}Sessions{{< /gloss >}} on a timer so that neither accumulates without a bound.


| Value | Default | Description |
| ----- | ------- | ----------- |
| `controller.sessionIdleTTL` | `168h` | How long a Session may sit idle before the worker deletes it, as a Go duration. `0` turns the worker off, retries included. A negative value is rejected. |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| `controller.sessionIdleTTL` | `168h` | How long a Session may sit idle before the worker deletes it, as a Go duration. `0` turns the worker off, retries included. A negative value is rejected. |
| `controller.sessionIdleTTL` | `168h` | How long a Session can be idle before the worker deletes it, as a Go duration. `0` turns the worker off, retries included. A negative value is rejected. |

| ----- | ------- | ----------- |
| `controller.sessionIdleTTL` | `168h` | How long a Session may sit idle before the worker deletes it, as a Go duration. `0` turns the worker off, retries included. A negative value is rejected. |

Seven days is the default. There is no per-agent override and no maximum, so this one value governs every conversation in the installation.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seven days is the default >>> for what?

| The resource model is replaced | 0.10.x's `Agent` is gone. What it described is now split between an AgentTemplate and a {{< gloss "Harness" >}}Harness{{< /gloss >}}, paired by a new {{< gloss "Agent" >}}Agent{{< /gloss >}} resource in the `api.kagent.dev` group, and a conversation is a {{< gloss "Session" >}}Session{{< /gloss >}} created against that Agent. The two `Agent` kinds share a name and nothing else. For the model itself, see [Core concepts]({{< link path="about/core-concepts" >}}). |

The two releases also cannot run side by side on one cluster. `modelconfigs.kagent.dev`, `modelproviderconfigs.kagent.dev`, and `remotemcpservers.kagent.dev` exist in both, and a CRD is cluster-scoped, so installing 1.0's CRDs replaces 0.10.x's. A second cluster keeps the old installation intact while you work.
The two releases also cannot run side by side on one cluster. The group rename separates most of the custom resources. Both releases bundle kmcp, though, so both install `mcpservers.kagent.dev` at different versions. A CRD is cluster-scoped, so installing 1.0's CRDs replaces that one. A second cluster keeps the old installation intact while you work.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at different versions.. > that could be interpreted as not being in sync

Signed-off-by: Rachael Graham <rachael.graham@solo.io>
@Rachael-Graham
Rachael-Graham merged commit efc9048 into main Oct 2, 2026
4 checks passed
@Rachael-Graham
Rachael-Graham deleted the rlg-alpha5-rebaseline branch October 2, 2026 16:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tracking: re-baseline the 1.x docs for kagent 1.0.0-alpha5

2 participants