Skip to content

Go declarative runtime silently ignores spec.declarative.context.compaction while being the CRD default #2728

Closed

Description

@davidkarlsen

Summary

As of 0.10.0 the Agent CRD defaults spec.declarative.runtime to go, so any agent that omits the field runs on the Go ADK. The Go runtime does not implement spec.declarative.context.compaction — for long-running tool-using agents that field is what bounds session history growth. An operator upgrading to 0.10.0 without an explicit runtime therefore loses compaction, and the only signal is a status condition that no UI or printer column surfaces.

Evidence (all at tag v0.10.0, commit ae008d1e)

  1. go is the CRD default — kagent.dev_agents.yaml:13236 default: go (same at kagent.dev_sandboxagents.yaml:10893). Note go/api/v1alpha2/agent_types.go:325-336 (EffectiveDeclarativeRuntime) still documents and implements a Python fallback, which is unreachable for objects created through the API.

  2. Compaction is unimplemented on Go — go/core/internal/controller/reconciler/reconciler.go:946-948:

    // Context compression: Not yet implemented in Go runtime
    if decl.Context != nil && decl.Context.Compaction != nil {
        unsupported = append(unsupported, "context compression/compaction (not implemented in Go runtime)")
    }

    grep -rn Compaction go/adk returns zero functional hits, while the controller compiles the config regardless (translator/agent/compiler.go:265-302) — the field is delivered to the runtime and dropped.

  3. The gap is soft-failed — reconciler.go:341-350 sets UnsupportedFeatures=True; the agent still reconciles Accepted and serves traffic, just without compaction. Good that a signal exists; it is invisible in the UI and in kubectl get agents.

Scope

  1. Implement context.compaction in the Go runtime. The upstream primitives are not in place yet — in google/adk-go, #298 "ADR-010: Native SDK Session History Compaction" (design) and #1001 "Add EventCompaction support to EventActions and compaction filtering in contents_processor.go" (implementation) are both open as of 2026-09-07; see also discussion #589. Either consume that work when it lands, or implement session-history compaction kagent-side for the Go runtime.

  2. Publish an authoritative runtime parity matrix in the docs, generated from or cross-checked against validateRuntimeFeatures, and replace "most features supported" in the CRD description with a link to it.

  3. Make degradation harder to miss — surface UnsupportedFeatures on the agent card / UI and in kubectl get agents printer columns, and consider an opt-in strict mode that fails reconciliation rather than ignoring the field. Given go is now the default, this is the difference between a visible upgrade note and a silent regression.

  4. Close the smaller deltas or drop the fields — file upload is Go-only ("Python ADK agents do not yet support file attachments"), and executeCodeBlocks is inert on both runtimes pending google/adk-python#3921 while still being an accepted API field.

Acceptance criteria

  • An agent with runtime: go and context.compaction set demonstrably compacts session history (test or trace evidence), and UnsupportedFeatures is not raised for it.
  • Docs carry a parity matrix that matches validateRuntimeFeatures.
  • Until item 1 ships, the compaction-on-Go gap is stated in the docs where runtime is described, not only in the reconciler.

Activity

  1. go-faustino commented on Sep 9, 2026

    @go-faustino
    Contributor

    The upstream dependency this depends on has landed, which I think changes the shape of item 1 considerably.

    google/adk-go shipped native compaction in v2.3.0 (2026-08-31). There is now a session/compaction package providing SlidingWindowEventCompactor, TokenThresholdEventCompactor and NewLLMSummarizer, along with session.EventCompaction, the internal/compactioninternal machinery, runner integration, and an examples/compactionrecall worked example. I checked the tags directly: session/compaction is present at v2.3.0 and absent at both v2.1.0 and v2.2.0.

    So the "upstream primitives are not in place yet" note in the issue body, accurate when written, is now out of date — google/adk-go#298 and #1001 were resolved by that release even though the issues appear to still be open.

    kagent v0.10.1 pins google.golang.org/adk/v2 v2.1.0, one release behind the one that carries this.

    Why this matters for the two earlier attempts

    Both prior PRs were auto-closed by stalebot rather than rejected:

    • #1971 — the author explicitly concluded the right order was to land EventCompaction in google/adk-go first, and that afterwards "implementing proper marker-based compaction in kagent would be pretty straightforward". That precondition is now met.
    • #2025 — a full port of the adk-python algorithm into adk/pkg/compaction, +1008/-18 with tests, closed with no human review comments.

    Given v2.3.0, the #2025 approach is largely obsolete: there is no longer a reason to carry a port of the algorithm inside kagent when the SDK implements it.

    Suggested shape

    The compactor knobs map closely onto the existing CRD surface, so most of the translation layer already exists and is already delivered to the runtime:

    spec.declarative.context.compaction adk-go v2.3.0
    compactionInterval + overlapSize SlidingWindowEventCompactor
    tokenThreshold TokenThresholdEventCompactor
    summarizer.modelConfig + summarizer.promptTemplate NewLLMSummarizer

    AgentContextConfig is already compiled by translator/agent/compiler.go and delivered in config.json; the Go runtime simply never reads it. So the work looks like: bump the adk-go dependency, construct the compactor and summarizer from cfg.ContextConfig at agent/runner setup, and drop the unsupported branch in reconciler.go.

    The dependency bump across two minor versions of the core ADK is probably the bulk of the risk rather than the wiring itself — I have not assessed that changelog.

    Happy to help with the implementation or testing if it would be useful — please say if someone is already on it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions