alpha5-7: Rebaseline on new api group, CRDs, and more - #551
Conversation
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>
Docs preview
Both are uploaded Worker versions and serve no production traffic. |
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. |
There was a problem hiding this comment.
is it agent or session?
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
| 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). |
There was a problem hiding this comment.
| > 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" >}}). |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
| 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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
| - 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" >}}). |
There was a problem hiding this comment.
| 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" >}}). |
There was a problem hiding this comment.
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 >}}. |
There was a problem hiding this comment.
| 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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
| 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: |
There was a problem hiding this comment.
| 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. |
There was a problem hiding this comment.
| 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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
| 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" >}}). |
There was a problem hiding this comment.
| 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" >}}). | |
There was a problem hiding this comment.
| | `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" >}}). |
There was a problem hiding this comment.
| 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. |
There was a problem hiding this comment.
| 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`. |
There was a problem hiding this comment.
| 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. |
There was a problem hiding this comment.
| 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. |
There was a problem hiding this comment.
| 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" >}}). |
There was a problem hiding this comment.
| 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. |
There was a problem hiding this comment.
| > **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. |
There was a problem hiding this comment.
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" >}}). |
There was a problem hiding this comment.
| 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. |
There was a problem hiding this comment.
| 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" >}}). |
There was a problem hiding this comment.
| 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. |
There was a problem hiding this comment.
| 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. |
There was a problem hiding this comment.
| 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. | |
There was a problem hiding this comment.
| | `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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
at different versions.. > that could be interpreted as not being in sync
Signed-off-by: Rachael Graham <rachael.graham@solo.io>
Re-baselines the 1.x doc set from kagent
1.0.0-alpha2to1.0.0-alpha7, with Agent Substrate0.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
kagent.dev/v1alpha3→api.kagent.dev/v1alpha3, on every example.Agentis a real CRD pairing an AgentTemplate with a Harness, andAgentInstanceis nowSession. Core concepts, the getting-started flow, and the glossary follow.docs/env.md; removed ones are gone.Verified on a cluster
Installed alpha7 on kind and ran
get-started/your-first-agentend 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.