For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.
Upgrade from 0.x
Move an existing kagent 0.10.x installation to 1.0 by standing up a new installation and recreating your resources on it.
kagent 1.0 has no in-place upgrade path from the 0.10.x line. Moving to 1.0 means installing kagent fresh against a new database, and recreating your resources on it. When your installation runs 1.0, you can perform regular in-place upgrades for later minor releases. To review upgrade paths and versions, see Version support. For a summary of what 1.0 changes before you plan the move, see Release notes.
In-place upgrade blockers
Three independent changes each rule out helm upgrade, so working around any one of them does not help.
| Change | Consequence |
|---|---|
| The database schema is a clean baseline | 1.0 replaces golang-migrate with goose and starts from a single baseline migration. An existing 0.10.x database has no bridge to it, and 1.0 refuses to run against one. |
| The custom resources moved to a new API group | 1.0 serves its resources under api.kagent.dev, where 0.10.x serves them under kagent.dev. The groups share no conversion, so nothing stored under the old group is visible through the new CRDs. |
| The resource model is replaced | 0.10.x’s Agent is gone. What it described is now split between an AgentTemplate and a HarnessHarnessA Kubernetes custom resource defining how an agent is allowed to run: which harness executes the agent, its workload image, and its WorkerPool and snapshot storage. An Agent pairs it with the AgentTemplate that it runs.Learn more, paired by a new AgentAgentA Kubernetes custom resource that pairs one AgentTemplate with one Harness. Each side takes either an inline spec or a reference to an existing resource, and the controller compiles the pair into a revision.Learn more resource in the api.kagent.dev group, and a conversation is a SessionSessionA running conversation with one Agent. Unlike the resources it is built from, a Session is not a Kubernetes resource: kagent's gRPC API creates it and its PostgreSQL database tracks it.Learn more created against that Agent. The two Agent kinds share a name and nothing else. For the model itself, see Core concepts. |
The two releases also cannot run side by side on one cluster. The group rename separates the custom resources, but both charts name their cluster-scoped ClusterRoles after the release, such as kagent-getter-role. When both releases use the default kagent release name, the 1.0 install collides with the ClusterRoles that 0.10.x owns. A second cluster keeps the old installation intact while you work.
Warning
Downgrading from 1.0 back to 0.10.x is unsupported. Treat the cutover as one-way, and keep the 0.10.x installation running until you have verified the new one.
Before you begin
Read the kagent releases for the breaking changes in the version that you are moving to, and Version support for what 1.0 does and does not promise.
Decide where you will install 1.0. A second cluster is the safer choice, because it leaves your 0.10.x installation untouched. Installing on the same cluster means uninstalling 0.10.x first, and that step is not reversible.
Provision an empty PostgreSQL database for 1.0. It must be a new database rather than a new schema in the old one, and pointing 1.0 at a 0.10.x database fails at startup with a clear error.
source core uses an unsupported migration table. Use a new PostgreSQL databaseBack up your 0.10.x database. The backup is a restore point for the old installation rather than an input to the new one, because no procedure loads it into 1.0.
pg_dump "postgres://<user>:<password>@<host>:5432/<dbname>" \ --format=custom \ --file=kagent-0.10-backup.dump
Export your 0.10.x resources
Your Kubernetes resources do carry forward, so export them before anything replaces the CRDs. Conversation history does not carry forward.
Export every kagent resource in your namespace.
kubectl get agents,agentharnesses,sandboxagents,memories,toolservers,remotemcpservers,modelconfigs,modelproviderconfigs \ -n kagent -o yaml > kagent-0.10-resources.yamlNote which Secrets your ModelConfigs reference. Secrets are ordinary Kubernetes resources that kagent does not own, so recreate them on the new cluster by whatever means you created them originally.
kubectl get modelconfigs -n kagent \ -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.apiKeySecret}{"\n"}{end}'
Install kagent 1.0
Install 1.0 against the empty database that you provisioned. kagent and Agent Substrate both store their state in that database, each with an owner login that applies migrations and a read/write login that serves runtime queries. kagent install normally creates a development database for both. The --skip-database-setup flag skips that database. The releases then read the connection Secrets that you create in this section.
Before you start, complete the Before you begin steps of the installation guide. Those steps prepare the kagent CLI, your provider API key, and a cluster at Kubernetes 1.37 or later.
Create the namespaces that hold the connection Secrets.
kagent installuses the namespaces when they already exist.kubectl create namespace kagent kubectl create namespace ate-systemPrepare the database for kagent. Follow steps 1 to 3 of Use an external PostgreSQL instance, which create the
kagent_ownerandkagent_readwriteroles and themy-postgres-ownerandmy-postgres-readwriteSecrets.Prepare the same database for Agent Substrate. Agent Substrate ships its own setup script, which creates the
substrate_ownerandsubstrate_readwriteroles and thesubstrateschema. Run it in the same way as the kagent script.curl -sSLo substrate-setup.sql https://raw.githubusercontent.com/kagent-dev/substrate/refs/tags/v0.5.0-alpha2/pkg/postgressetup/setup.sql export SUBSTRATE_OWNER_PASSWORD=<substrate-owner-password> SUBSTRATE_READWRITE_PASSWORD=<substrate-readwrite-password> psql "$ADMIN_CONNECTION_STRING" --no-psqlrc --set=ON_ERROR_STOP=1 --single-transaction \ --set=substrate_schema=substrate \ --set=substrate_owner_role=substrate_owner \ --set=substrate_owner_user=substrate_owner_user \ --set=substrate_readwrite_role=substrate_readwrite \ --set=substrate_readwrite_user=substrate_readwrite_user \ --command='\getenv substrate_owner_password SUBSTRATE_OWNER_PASSWORD' \ --command='\getenv substrate_readwrite_password SUBSTRATE_READWRITE_PASSWORD' \ --file=substrate-setup.sqlCreate the Agent Substrate connection Secrets. The Agent Substrate chart reads these names and keys by default, so its release needs no extra values.
kubectl create secret generic substrate-postgres-owner \ --namespace ate-system \ --from-literal=ownerConnectionString="postgresql://substrate_owner_user:<substrate-owner-password>@<host>:5432/<dbname>?sslmode=verify-full" kubectl create secret generic substrate-postgres-readwrite \ --namespace ate-system \ --from-literal=readWriteConnectionString="postgresql://substrate_readwrite_user:<substrate-readwrite-password>@<host>:5432/<dbname>?sslmode=verify-full"Save the kagent Helm values that configure kagent to use your Secrets and roles.
cat > kagent-values.yaml <<EOF database: postgres: ownerConnectionStringSecretRef: name: my-postgres-owner readWriteConnectionStringSecretRef: name: my-postgres-readwrite config: server: grpcReflection: true database: owner: role: kagent_owner readWrite: role: kagent_readwrite vectorEnabled: true EOFValue Why database.postgres.ownerConnectionStringSecretRef.nameanddatabase.postgres.readWriteConnectionStringSecretRef.nameRead the two connection strings from the Secrets that you created. The keys default to ownerConnectionStringandreadWriteConnectionString.config.database.owner.roleandconfig.database.readWrite.roleThe roles that the kagent setup script created. If you passed other role names to the script, set those names instead. config.database.vectorEnabledApplies the pgvector migrations, which long-term memory depends on. If your database does not have the pgvector extension installed, omit the value. config.server.grpcReflectionLets the guides that use grpcurldiscover the controller API, as in the installation guide.The controller applies migrations at startup. To apply them from a pipeline instead, set
config.database.skipMigrations=trueand runkagent db migrate upwith the owner login yourself. The controller then verifies the schema and fails if it is not already current.Save a CLI configuration file that references those values.
cat > kagent-config.yaml <<EOF install: kagent: valuesFiles: [kagent-values.yaml] EOFInstall kagent without the development database.
kagent --config kagent-config.yaml install --namespace kagent --skip-database-setupVerify the schema before continuing. The
kagent dbcommands connect as the owner login and assume the owner role.kagent db migrate status \ --db-url "postgresql://kagent_owner_user:<owner-password>@<host>:5432/<dbname>?sslmode=verify-full" \ --db-role kagent_ownerExample output:
1 migration(s) applied (at v1), 0 pending
Recreate your resources
The export splits into three groups: resources that need only an apiVersion change, agents that need rewriting, and resources with no 1.0 equivalent. Work through them in that order, because an AgentTemplate refers to the ModelConfigs and RemoteMCPServers that the first group creates.
Resources that carry forward
ModelConfig, ModelProviderConfig, and RemoteMCPServer keep every field that v1alpha2 sets. v1alpha3 adds fields that 0.10.x did not serve, so an exported resource applies unchanged apart from its apiVersion.
Recreate the Secrets that your ModelConfigs name before you apply them, or the ModelConfigs resolve to nothing.
Change the
apiVersionand apply the resources unchanged.sed 's|^apiVersion: kagent.dev/v1alpha2$|apiVersion: api.kagent.dev/v1alpha3|' \ kagent-0.10-resources.yaml > kagent-1.0-resources.yaml
Agents become an AgentTemplate, a Harness, and an Agent
A 0.10.x Agent described both what the agent does and how it runs. In 1.0 these concepts are separated into two resources: an AgentTemplate holds the agent’s behavior, and a Harness holds the runtime and infrastructure. A third resource, 1.0’s own Agent, pairs one of each. One Harness serves many Agents, so expect fewer Harnesses than you had 0.10.x Agents.
0.10.x Agent field | Equivalent field in 1.0 |
|---|---|
spec.description | AgentTemplate.spec.description |
spec.declarative.systemMessage | AgentTemplate.spec.systemPrompt |
spec.declarative.systemMessageFrom | AgentTemplate.spec.systemPromptFrom |
spec.declarative.promptTemplate | AgentTemplate.spec.promptTemplate, unchanged |
spec.declarative.modelConfig | AgentTemplate.spec.modelConfig, now an object with a name rather than a bare string |
spec.declarative.tools | AgentTemplate.spec.tools, reshaped. See the following note. |
spec.declarative.memory | Harness.spec.kagent.memory, so memory is now a property of the runtime rather than of one agent |
spec.declarative.runtime | Harness.spec.workload.image, through the runtime that the Harness selects |
spec.declarative.deployment | Harness.spec.workload and Harness.spec.substrate. Agents no longer run as Deployments. |
spec.type, spec.byo | The byo runtime on a Harness. For more information, see Bring your own agent. |
spec.declarative.a2aConfig | Nothing. A2A is always on, and callers address an Agent at /agents/{namespace}/{name}. |
spec.iconUrl, spec.documentationUrl, spec.version, spec.provider | Nothing. kagent builds the agent card from the AgentTemplate’s name and description. |
spec.declarative.stream, executeCodeBlocks, shareTools, context | Nothing. v1alpha3 has no equivalent field. |
Note
Tool bindings changed shape. A 0.10.x tool set type: McpServer or type: Agent alongside a matching block. A 1.0 ToolBinding carries an mcp or subAgent block and no discriminator, so the block you set is the binding’s kind. For what each binding does, see About tools.
Write one Harness for each distinct runtime and infrastructure combination that your agents need. Then write one Agent for each 0.10.x Agent, naming the AgentTemplate and the Harness that it pairs. Neither reusable resource names the other, so the Agent makes a template runnable. For the full field reference, see Agent harness, and for a worked example, see Your first agent.
Resources with no 1.0 equivalent
Four resource kinds are removed rather than replaced, so plan for each one before you cut over.
| Removed resource | What to do |
|---|---|
AgentHarness | No equivalent. It provisioned OpenClaw and Hermes coding-agent sandboxes with Slack and Telegram channels. 1.0’s Harness shares part of the name and nothing else. |
Memory | Configure memory on the Harness with spec.kagent.memory instead. For more information, see Agent memory. |
SandboxAgent | No equivalent, and none is needed. Every 1.0 agent runs in a gVisor sandbox by default. |
ToolServer | Use RemoteMCPServer, which 0.10.x already served alongside it. |
Verify the new installation
Confirm that the resources resolved before you retire anything. Harness and AgentTemplate resources do not report their own statuses, so check for issues in the Agent that references them both.
Check that each Agent is ready.
kagent agent listRead the conditions on any Agent that is not ready.
ResolvedRefsreports a missing reference, and a Harness that names a WorkerPool that does not exist is the most common cause.kubectl describe agent <agent-name> -n kagentCreate a Session against a migrated Agent and send it a message. A reply confirms the whole path, from the revision to the model credentials.
kagent agent session create --agent <agent-name>
Retire the 0.10.x installation
Once the new installation answers correctly, remove the old one. Follow the 0.x procedure rather than the one in these docs: a 0.10.x installation has no Agent Substrate, no ate.dev resources, and no identity material to clean up. For those steps, see Uninstall kagent in the 0.x documentation.
Keep the database backup after the uninstall for your own records. It is the only remaining copy of the 0.10.x conversation history, and nothing in 1.0 can read it.