Disclosure: this issue was drafted by an AI agent (Claude) while testing kagent 1.x on Agent
Substrate, and reviewed by a human before filing.
Severity: High · default byo setup (kagent's own Go ADK image) · workaround: override the Harness command (below)
What happens
As a user I run an agent on a byo Harness with kagent's Go ADK image. I tell it my project name in
turn 1. The AgentInstance suspends after the turn, as every instance does. In turn 2 the agent has
forgotten everything (3 of 3 attempts):
turn 1: "My project is named zebra42. Reply with OK." -> [COMPLETED] OK.
actor state between turns: ACTOR_STATE_SUSPENDED
turn 2: "What is my project named? Reply with just the name." -> [INPUT_REQUIRED] What is the name of your project?
The same two turns on a kagent Harness with the same image and model answer zebra42, and so do a
checkpoint fork and a later turn of the original. On byo, every conversation, checkpoint and fork
loses its history after one turn.
Reproduce
kagent v1.0.0-alpha2 on Agent Substrate, with an OpenAI ModelConfig default-model-config:
apiVersion: kagent.dev/v1alpha3
kind: Harness
metadata: {name: byo-harness, namespace: kagent}
spec:
byo: {}
workload:
image: ghcr.io/kagent-dev/kagent/golang-adk@sha256:0ef67974d39518b18de074bd9762fb4aea9764fc8836eeb45d7868b358eecb30
command: [/app]
env:
- {name: PORT, value: "80"}
substrate:
workerPoolRef: {name: kagent-default}
snapshotPolicy: {location: "s3://ate-snapshots/kagent/"}
allowedAgentTemplates:
selector: {matchLabels: {kagent.dev/harness: byo-harness}}
---
apiVersion: kagent.dev/v1alpha3
kind: AgentTemplate
metadata: {name: byo-agent, namespace: kagent, labels: {kagent.dev/harness: byo-harness}}
spec:
description: An agent served by a byo runtime
modelConfig: {name: default-model-config}
systemPrompt: You are a concise assistant.
Create an AgentInstance of byo-agent and send the two turns above over
lf.a2a.v1.A2AService/SendMessage.
Expected vs actual
- Expected: turn 2 answers
zebra42, as on the kagent runtime.
- Actual: turn 2 has no history; the agent asks for the name.
Ask
Set session_db_url in the byo compiler as the kagent compiler does, or document that a byo runtime
must keep its state under /data and give it that location. Related: #2884 asks for the BYO contract
to be documented.
Root cause: the byo compiler never sets session_db_url, so the Go ADK keeps sessions in memory, and a snapshot keeps only /data
- Every actor gets
/data as its durable directory (go/core/internal/substrate/actor_template.go:
durableDataMount = "/data", a DurableDir volume), and a snapshot keeps only that directory
(checkpoint tags report SNAPSHOT_CONTENT_SCOPE_DATA). go/harness/README.md: "DurableDir
contains private state that must survive Actor replacement and snapshot restore".
- The kagent compiler points its runtime there:
compiled.Config.SessionDBURL = "sqlite+aiosqlite:////data/sessions.db"
(go/core/internal/translator/kagent/compiler.go).
- The byo compiler (
go/core/internal/translator/byo/compiler.go) builds the same ADK-shaped config
with adkconfig.Build, but never sets SessionDBURL.
- Without it the Go ADK uses an in-memory session store (
go/adk/cmd/main.go: "no session DB
configured, using in-memory session"), which a restore does not bring back.
go/adk/pkg/session/local.go expects a BYO image to receive the URL: it accepts the Python
dialect "so a BYO image built with this SDK works regardless of which dialect it was handed".
Workaround, which also confirms the fix
A byo Harness whose command adds the field before it starts the runtime keeps the conversation
through the suspend, a checkpoint fork, and a later turn of the original:
command:
- bash
- -c
- |
export KAGENT_CONFIG_JSON="{\"session_db_url\":\"sqlite:////data/sessions.db\",${KAGENT_CONFIG_JSON#\{}"
exec /app
Scope
- Reproduced on kind with kagent
v1.0.0-alpha2 and Agent Substrate 0.2.0-beta5, 3 of 3
attempts. Source-confirmed on main at c61fad8b (2026-09-23).
- Unaffected: the kagent runtime (its sessions are in
/data/sessions.db). Single-turn byo agents
work, and so do tools and tool approval.
Severity: High · default byo setup (kagent's own Go ADK image) · workaround: override the Harness command (below)
What happens
As a user I run an agent on a
byoHarness with kagent's Go ADK image. I tell it my project name inturn 1. The AgentInstance suspends after the turn, as every instance does. In turn 2 the agent has
forgotten everything (3 of 3 attempts):
The same two turns on a
kagentHarness with the same image and model answerzebra42, and so do acheckpoint fork and a later turn of the original. On byo, every conversation, checkpoint and fork
loses its history after one turn.
Reproduce
kagent
v1.0.0-alpha2on Agent Substrate, with an OpenAI ModelConfigdefault-model-config:Create an AgentInstance of
byo-agentand send the two turns above overlf.a2a.v1.A2AService/SendMessage.Expected vs actual
zebra42, as on the kagent runtime.Ask
Set
session_db_urlin the byo compiler as the kagent compiler does, or document that a byo runtimemust keep its state under
/dataand give it that location. Related: #2884 asks for the BYO contractto be documented.
Root cause: the byo compiler never sets session_db_url, so the Go ADK keeps sessions in memory, and a snapshot keeps only /data
/dataas its durable directory (go/core/internal/substrate/actor_template.go:durableDataMount = "/data", aDurableDirvolume), and a snapshot keeps only that directory(checkpoint tags report
SNAPSHOT_CONTENT_SCOPE_DATA).go/harness/README.md: "DurableDircontains private state that must survive Actor replacement and snapshot restore".
compiled.Config.SessionDBURL = "sqlite+aiosqlite:////data/sessions.db"(
go/core/internal/translator/kagent/compiler.go).go/core/internal/translator/byo/compiler.go) builds the same ADK-shaped configwith
adkconfig.Build, but never setsSessionDBURL.go/adk/cmd/main.go: "no session DBconfigured, using in-memory session"), which a restore does not bring back.
go/adk/pkg/session/local.goexpects a BYO image to receive the URL: it accepts the Pythondialect "so a BYO image built with this SDK works regardless of which dialect it was handed".
Workaround, which also confirms the fix
A byo Harness whose command adds the field before it starts the runtime keeps the conversation
through the suspend, a checkpoint fork, and a later turn of the original:
Scope
v1.0.0-alpha2and Agent Substrate0.2.0-beta5, 3 of 3attempts. Source-confirmed on
mainatc61fad8b(2026-09-23)./data/sessions.db). Single-turn byo agentswork, and so do tools and tool approval.