-
Notifications
You must be signed in to change notification settings - Fork 5
Feat/compaction #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat/compaction #20
Conversation
…ummarization - Introduced a new architectural decision record (ADR-009) detailing the implementation of session history compaction in `adk-code`. - Addressed issues of token budget exhaustion, database bloat, performance degradation, and cost escalation due to unbounded session histories. - Proposed a sliding window compaction mechanism that maintains immutability of original events while providing selective context for LLM interactions. - Defined a comprehensive architecture including components for compaction configuration, metadata handling, event selection, LLM summarization, and session service integration. - Established a mathematical model for triggering compaction based on invocation counts and token thresholds. - Outlined implementation phases and testing strategies to ensure robust integration and performance.
…tion using Agent's current LLM model
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements session history compaction for the adk-code project to address unbounded token growth in long conversations. The implementation includes detailed ADR documentation and code changes across multiple layers.
Purpose: Enable 50+ turn agent workflows by automatically summarizing old conversation history, reducing token usage by 60-80% while preserving audit trails.
Key Changes:
- New compaction package with sliding window algorithm using invocation-based thresholds
- Wrapper pattern for session service to provide transparent event filtering
- Integration with REPL, orchestration layer, and configuration system
- New CLI flags and
/compactionREPL command for configuration management
Reviewed Changes
Copilot reviewed 24 out of 24 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
docs/adr/010-native-sdk-session-compaction.md |
ADR for upstream Google ADK Go SDK compaction (native EventActions approach) |
docs/adr/009-session-history-compaction.md |
ADR for adk-code-specific compaction using CustomMetadata workaround |
docs/adr/009-FEASIBILITY-REPORT.md |
Technical validation report confirming implementation feasibility |
docs/adr/0006-context-management.md |
Deleted - replaced by newer ADR-009 design |
adk-code/internal/session/compaction/types.go |
Core metadata types and helper functions for compaction events |
adk-code/internal/session/compaction/config.go |
Configuration structure with defaults matching ADR specs |
adk-code/internal/session/compaction/summarizer.go |
LLM-based summarization logic for event compaction |
adk-code/internal/session/compaction/selector.go |
Event selection algorithm for sliding window |
adk-code/internal/session/compaction/filtered_session.go |
Session wrapper implementing transparent event filtering |
adk-code/internal/session/compaction/service.go |
Service wrapper for compaction-aware session retrieval |
adk-code/internal/session/compaction/coordinator.go |
Orchestrates the compaction process |
adk-code/internal/session/compaction/compaction_test.go |
Unit tests for metadata storage and configuration |
adk-code/internal/session/manager.go |
Added WrapWithCompaction method for service wrapping |
adk-code/internal/repl/repl.go |
Integrated compaction trigger post-invocation with feedback display |
adk-code/internal/orchestration/session.go |
Modified initialization to create compaction coordinator |
adk-code/internal/orchestration/components.go |
Added compaction fields to SessionComponents |
adk-code/internal/orchestration/builder.go |
Updated builder to pass LLM to session initialization |
adk-code/internal/display/events/event.go |
Added compaction event detection and display |
adk-code/internal/config/config.go |
Added compaction configuration flags and fields |
adk-code/internal/cli/commands/repl_builders.go |
Updated help text with compaction documentation |
adk-code/internal/cli/commands/repl.go |
Added /compaction command handler |
adk-code/internal/cli/commands/interface.go |
Added CompactionCommand implementation |
adk-code/internal/cli/commands.go |
Updated command handler signature for appConfig |
adk-code/internal/app/app.go |
Passed config and session manager to REPL |
Comments suppressed due to low confidence (1)
docs/adr/0006-context-management.md:1
- This entire file is being deleted (ADR-0006), but the new implementation in ADR-009 and the code appears to be a different approach using CustomMetadata instead of the three-layer system described here. Consider if any valuable design insights from this ADR should be preserved in ADR-009, particularly around token tracking and output truncation.
| responseStream := ls.llm.GenerateContent(ctx, llmRequest, false) | ||
| for resp := range responseStream { | ||
| if resp == nil { | ||
| continue | ||
| } | ||
| if resp.Content != nil { | ||
| summaryContent = resp.Content | ||
| usageMetadata = resp.UsageMetadata | ||
| break | ||
| } | ||
| } |
Copilot
AI
Nov 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing error handling: the response stream is iterated but resp.Err is never checked. If the LLM API call fails, this will result in nil content without surfacing the actual error to the caller.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot open a new pull request to apply changes based on this feedback
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot open a new pull request to apply changes based on this feedback
| // Trigger compaction if enabled and conditions are met | ||
| if !hasError && r.config.SessionManager != nil && r.config.SessionManager.Coordinator != nil { | ||
| ctx := context.Background() | ||
|
|
||
| // Get the current session to pass to the coordinator | ||
| getResp, err := r.config.SessionManager.Manager.GetService().Get(ctx, &sessionpkg.GetRequest{ | ||
| AppName: "code_agent", | ||
| UserID: r.config.UserID, | ||
| SessionID: r.config.SessionName, | ||
| }) | ||
|
|
||
| if err == nil && getResp.Session != nil { | ||
| // Unwrap filtered session if necessary | ||
| sess := getResp.Session | ||
| if filtered, ok := sess.(*compaction.FilteredSession); ok { | ||
| sess = filtered.Underlying | ||
| } | ||
|
|
||
| // Create a spinner for compaction | ||
| compactionSpinner := display.NewSpinner(r.config.Renderer, "Compacting session history") | ||
| compactionSpinner.Start() | ||
|
|
||
| // Run compaction if thresholds are met | ||
| if compErr := r.config.SessionManager.Coordinator.RunCompaction(ctx, sess); compErr != nil { | ||
| // Log error but don't interrupt user experience | ||
| compactionSpinner.Stop() | ||
| fmt.Printf("%s Warning: Compaction failed: %v\n", r.config.Renderer.Yellow("⚠"), compErr) | ||
| } else { | ||
| // After compaction, check if an event was added and display feedback | ||
| // Get the session again to see the new compaction event | ||
| getResp2, err2 := r.config.SessionManager.Manager.GetService().Get(ctx, &sessionpkg.GetRequest{ | ||
| AppName: "code_agent", | ||
| UserID: r.config.UserID, | ||
| SessionID: r.config.SessionName, | ||
| }) | ||
|
|
||
| if err2 == nil && getResp2.Session != nil { | ||
| // Unwrap if needed | ||
| sess2 := getResp2.Session | ||
| if filtered, ok := sess2.(*compaction.FilteredSession); ok { | ||
| sess2 = filtered.Underlying | ||
| } | ||
|
|
||
| // Check if there's a recent compaction event | ||
| events := sess2.Events() | ||
| if events.Len() > 0 { | ||
| lastEvent := events.At(events.Len() - 1) | ||
| if lastEvent != nil && compaction.IsCompactionEvent(lastEvent) { | ||
| // Stop spinner with success | ||
| compactionSpinner.StopWithSuccess("Session history compacted") | ||
|
|
||
| // Display compaction notification | ||
| metadata, metaErr := compaction.GetCompactionMetadata(lastEvent) | ||
| if metaErr == nil { | ||
| fmt.Println() | ||
| fmt.Println(r.config.Renderer.Cyan("📦 Session History Compaction:")) | ||
| fmt.Printf(" %s Compacted %d events into 1 summary\n", r.config.Renderer.Dim("•"), metadata.EventCount) | ||
| fmt.Printf(" %s Token reduction: %d → %d tokens (%.1f%% compression)\n", | ||
| r.config.Renderer.Dim("•"), | ||
| metadata.OriginalTokens, | ||
| metadata.CompactedTokens, | ||
| metadata.CompressionRatio) | ||
| fmt.Printf(" %s Session context optimized for better performance\n", r.config.Renderer.Dim("•")) | ||
| fmt.Println() | ||
| } else { | ||
| compactionSpinner.Stop() | ||
| } | ||
| } else { | ||
| // No compaction event added (threshold not met) | ||
| compactionSpinner.Stop() | ||
| } | ||
| } else { | ||
| compactionSpinner.Stop() | ||
| } | ||
| } else { | ||
| compactionSpinner.Stop() | ||
| } | ||
| } | ||
| } | ||
| } |
Copilot
AI
Nov 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The compaction logic runs synchronously in the REPL main thread, which can cause a 1-5 second delay. According to ADR-009 line 801, this should be asynchronous to match Python ADK's behavior (asyncio.create_task()). The code should wrap this entire block in go func() { ... }() to avoid blocking the user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot open a new pull request to apply changes based on this feedback
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
@raphaelmansuy I've opened a new pull request, #21, to work on those changes. Once the pull request is ready, I'll request review from you. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
@raphaelmansuy I've opened a new pull request, #22, to work on those changes. Once the pull request is ready, I'll request review from you. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
@raphaelmansuy I've opened a new pull request, #23, to work on those changes. Once the pull request is ready, I'll request review from you. |
No description provided.