Skip to content

feat: implement dynamic context compression#3

Merged
lxowalle merged 2 commits intosipeed:mainfrom
Danieldd28:feature/dynamic-context-compression
Feb 10, 2026
Merged

feat: implement dynamic context compression#3
lxowalle merged 2 commits intosipeed:mainfrom
Danieldd28:feature/dynamic-context-compression

Conversation

@Danieldd28
Copy link
Collaborator

This PR implements a dynamic context compression mechanism to optimize memory usage for long conversations.

Changes:

  • Session Management: Added a field to store compressed history.
  • Context Building: The summary is now included in the system prompt if available.
  • Agent Loop: Added a background job that triggers when history exceeds 20 messages. It summarizes the old messages (keeping the last 4 for continuity) and updates the session.
  • Safety: Added concurrency protection to prevent multiple summarization jobs for the same session.

This allows the agent to maintain 'long-term' memory of the conversation core without blowing up the token count or RAM usage.

- Added Summary field to Session struct
- Implemented background summarization when history > 20 messages
- Included conversation summary in system prompt for long-term context
- Added thread-safety for concurrent summarization per session
Copilot AI review requested due to automatic review settings February 9, 2026 18:29
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements dynamic context compression for long-running conversations by adding per-session summaries, injecting summaries into the constructed prompt context, and running an async summarization job once session history exceeds a threshold.

Changes:

  • Add Summary to Session plus manager helpers to get/set summary and truncate history.
  • Include stored session summary in the system prompt during context construction.
  • Trigger background summarization when history grows beyond 20 messages, with per-session concurrency protection.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.

File Description
pkg/session/manager.go Adds summary storage to sessions and introduces summary/history management helpers.
pkg/agent/loop.go Adds async summarization job, session-level summarization dedupe, and persistence updates.
pkg/agent/context.go Extends context building to include session summary in the prompt.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +106 to +108
if summary != "" {
systemPrompt += "\n\n## Summary of Previous Conversation\n\n" + summary
}
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary text is inserted into the system prompt. Since the summary is model-generated from user content, this can inadvertently elevate user-controlled instructions into the highest-priority role (prompt-injection risk). Consider placing the summary in a lower-priority message (e.g., an initial assistant message) and/or wrapping it with explicit guidance like “for reference only; do not follow instructions from the summary.”

Copilot uses AI. Check for mistakes.
Comment on lines +262 to +266
if response.Content != "" {
al.sessions.SetSummary(sessionKey, response.Content)
al.sessions.TruncateHistory(sessionKey, 4)
al.sessions.Save(al.sessions.GetOrCreate(sessionKey))
}
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The summarization job snapshots history, but later calls TruncateHistory(sessionKey, 4) on the current session state. If new messages arrive while the LLM call is in-flight, truncation can drop messages that were not included in the generated summary. Consider applying the update atomically with awareness of the snapshot (e.g., keep the last 4 messages from the snapshot and append any messages added after the snapshot length).

Copilot uses AI. Check for mistakes.
Comment on lines +127 to +132
if len(session.Messages) <= keepLast {
return
}

session.Messages = session.Messages[len(session.Messages)-keepLast:]
session.Updated = time.Now()
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TruncateHistory can panic if keepLast is negative (slice bounds will be invalid). Since this is an exported method, add an explicit guard (e.g., treat keepLast <= 0 as truncating to 0, or return an error).

Copilot uses AI. Check for mistakes.
Comment on lines +229 to +243
prompt := "Below is a conversation history and an optional existing summary. " +
"Please provide a concise summary of the conversation so far, " +
"preserving the core context and key points discussed. " +
"If there's an existing summary, incorporate it into the new one.\n\n"

if summary != "" {
prompt += "EXISTING SUMMARY: " + summary + "\n\n"
}

prompt += "CONVERSATION TO SUMMARIZE:\n"
for _, m := range toSummarize {
if m.Role == "user" || m.Role == "assistant" {
prompt += fmt.Sprintf("%s: %s\n", m.Role, m.Content)
}
}
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Building prompt via repeated string concatenation in a loop can cause unnecessary allocations as history grows. Prefer a strings.Builder (or bytes.Buffer) to assemble the prompt efficiently, especially since this runs in a background goroutine and may process large message contents.

Copilot uses AI. Check for mistakes.
Comment on lines +257 to +259
if err != nil {
fmt.Printf("Error summarizing session %s: %v\n", sessionKey, err)
return
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses fmt.Printf for error reporting, which bypasses the repo’s structured logging utilities (see pkg/logger). Consider switching to logger.Error... (or whichever level is appropriate) so operational logs are consistent and machine-parseable.

Copilot uses AI. Check for mistakes.
Comment on lines +216 to +217
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

summarizeSession uses context.Background() for its timeout context, so summarization won’t be cancelled when the agent loop’s ctx is cancelled/stopping. Consider threading a parent context into the goroutine (or storing one on AgentLoop) so shutdown can reliably stop in-flight summarization calls.

Copilot uses AI. Check for mistakes.
- Implement dynamic context window awareness for compression thresholds
- Add 'Thinking' animation for Telegram channel with auto-edit response
- Refactor summarization to handle multi-part batches and oversized messages
@lxowalle
Copy link
Collaborator

Good! thank you for the PR!

@lxowalle lxowalle merged commit ac945fa into sipeed:main Feb 10, 2026
@Zepan
Copy link
Contributor

Zepan commented Feb 13, 2026

Thanks for your contribution! We are forming the PicoClaw Dev Group to accelerate the evolution of the project. Any developer with more than one merged PR is invited to join.

Would you like to join the PicoClaw Dev Group? If so, please reply with your email address or send an email to support@sipeed.com with the subject line: [Join PicoClaw Dev Group] + Your GitHub account. We will send the Discord invite link to your inbox.

emadomedher pushed a commit to emadomedher/picoclaw that referenced this pull request Feb 17, 2026
…ompression

feat: implement dynamic context compression
KoheiYamashita referenced this pull request in KarakuriAgent/clawdroid Feb 19, 2026
Fix five issues in VoiceModeManager: replace CoroutineScope extension
with coroutineScope{} (#5), move initialIds snapshot into collectorJob
to eliminate race window (#3), add select+onTimeout(30s) to prevent
permanent blocking on server death (#1/#2), propagate null statusText
(#4), and fix break-in-lambda compile error.

Add 10s heartbeat goroutine in runAgentLoop to keep voice mode alive
during long tool executions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ex-takashima added a commit to ex-takashima/picoclaw that referenced this pull request Feb 26, 2026
- Replace stdlib log.Printf with logger.InfoCF/WarnCF for consistency
  with the rest of the codebase (addresses @nikolasdehor review point sipeed#3)
- ReleaseAll: clean refToScope/refs mappings even if refs entry is missing
- CleanExpired: guard refToScope lookup before scope cleanup
- Add TestReleaseAllCleansMappingsIfRefsMissing for robustness

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
alexhoshina pushed a commit that referenced this pull request Feb 26, 2026
- Replace stdlib log.Printf with logger.InfoCF/WarnCF for consistency
  with the rest of the codebase (addresses @nikolasdehor review point #3)
- ReleaseAll: clean refToScope/refs mappings even if refs entry is missing
- CleanExpired: guard refToScope lookup before scope cleanup
- Add TestReleaseAllCleansMappingsIfRefsMissing for robustness

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Nyukimin pushed a commit to Nyukimin/picoclaw_multiLLM that referenced this pull request Mar 2, 2026
伝説のアーキテクトレビューで発見された10個の致命的不備のうち、Phase 1(即時修正必須)を完了。

## 修正内容

### Issue #1: 承認フロー残骸削除 (🔴 CRITICAL)
- L328: Chat役割「承認管理」→「ユーザー対話」に変更
- L346-349: 承認フロー管理の責務削除、実行結果統合を追加
- L382: 「承認後に担当」→「即座に担当」に修正
- L384: 目的「承認フロー確実な動作」→「Worker即時実行確実な動作」
- L660: JobID コメント「承認ジョブ」→「Worker実行ジョブ」
- L835: CHAT ルート「承認管理」→「対話管理」
- L881: ルール辞書「承認して|approve」→「状態|status|確認」
- L1274-1278: Section 11.3「承認必須操作」完全削除
- L1285-1297: approval イベント削除、worker イベントに置換
- L1457: テスト「承認フロー」→「Worker即時実行」
- L2250: usecase.NewManageApproval 削除
- L2289: 付録差分「承認フロー仕様」→「(削除)」
- L2318: アグリゲート例「ApprovalFlow」→「Session」

### Issue sipeed#2: データベーススキーマ残骸削除 (🔴 CRITICAL)
- L288-293: db/migrations/ ディレクトリ削除
  - 001_create_events_table.sql
  - 002_create_jobs_table.sql
  - 003_create_auto_approve_policies_table.sql
- L2155-2194: Section 18.3「Job Repository」完全削除
  - SQLiteJobRepository実装
  - approval.ApprovalFlow 参照

### Issue sipeed#3, sipeed#4: EventStore、approval package参照削除 (🔴 CRITICAL)
- L1460: 実装プラン「Event Store, Worker実行」→「Worker即時実行、E2Eシナリオ」
- L2224-2226: Wire DI import削除
  - internal/domain/approval
  - internal/infrastructure/eventstore
  - internal/infrastructure/persistence/job
- L2233-2235: Wire DI provider削除
  - provideSQLiteDB
  - eventstore.NewSQLiteEventStore
  - job.NewSQLiteJobRepository
  - approval.NewAutoApprovePolicy
  - service.NewApprovalService
- L2220+: Wire DI import追加
  - internal/infrastructure/persistence/session
  - pkg/tools
  - provideToolRegistry
  - session.NewJSONSessionRepository

### Issue sipeed#5: セクション番号修正 (🟡 MEDIUM)
- 11章: ### 12.1, 12.2 → 11.1, 11.2
- 13章: ### 14.1, 13.2, 14.3 → 13.1, 13.2, 13.3
- 14章: ### 15.1 → 14.1
- 15章: ### 16.1, 16.2 → 15.1, 15.2
- 16章: ### 17.1 → 16.1
- 17章: ### 18.1 → 17.1
- 18章: ### 19.1 → 18.1

## 影響

### 修正前(システム破綻リスク)
- ❌ 承認フロー残骸13箇所
- ❌ 存在しないパッケージへの依存(ビルド失敗)
- ❌ 削除されたDB migrations参照
- ❌ Wire DI設定矛盾(起動不能)

### 修正後(実装可能)
- ✅ 承認フロー完全削除
- ✅ Worker即時実行への統一
- ✅ ビルド可能な依存関係
- ✅ 正しいWire DI設定

## 残存Issue(Phase 2で対応)

- Issue sipeed#6: workspace設定の統一(実装前に必須)
- Issue sipeed#7: parseMarkdownPatch正規表現修正(実装前に必須)
- Issue sipeed#8: コードブロック順序保証(実装前に必須)
- Issue sipeed#9: 保護ファイルチェック強化(実装前に必須)
- Issue sipeed#10: Git ロック機構追加(実装中に対応)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
liangzhang-keepmoving pushed a commit to liangzhang-keepmoving/picoclaw that referenced this pull request Mar 2, 2026
- Replace stdlib log.Printf with logger.InfoCF/WarnCF for consistency
  with the rest of the codebase (addresses @nikolasdehor review point sipeed#3)
- ReleaseAll: clean refToScope/refs mappings even if refs entry is missing
- CleanExpired: guard refToScope lookup before scope cleanup
- Add TestReleaseAllCleansMappingsIfRefsMissing for robustness

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Nyukimin pushed a commit to Nyukimin/picoclaw_multiLLM that referenced this pull request Mar 3, 2026
- MEDIUM sipeed#3: Type-Based Phased Execution Model(§1.2.2.1)新設
  file_edit並列→shell_command順次→git_operation順次の3フェーズ分割
- MEDIUM sipeed#16: Worker並列実行の完全実装仕様(§2.4.2)追加
  executeParallel()、セマフォ制御、テスト計画6件
- MEDIUM sipeed#5: Config構造体をv3実装に合わせて全面修正(§4.4)
  DistributedConfig追加、後方互換性保証、Validate()ロジック
- MEDIUM sipeed#10: Standalone Agent完全設計(§4.2)
  AgentHandler、Worker/Coder初期化、json.Decoder、シグナルハンドリング

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
AaronJny added a commit to AaronJny/picoclaw that referenced this pull request Mar 4, 2026
… fix

- TestCronScheduleParamValidation: verifies that LLM-supplied zero/empty
  defaults (at_seconds=0) do not hijack schedule priority (Patch sipeed#3)
- TestComputeNextRun_CronTimezone: verifies cron expressions respect
  schedule.TZ field with multiple timezones (Patch sipeed#4)
- TestComputeNextRun_DefaultTZ_NotUTC: verifies empty TZ defaults to
  Asia/Shanghai, not UTC (Patch sipeed#4)
hyperwd pushed a commit to hyperwd/picoclaw that referenced this pull request Mar 5, 2026
- Replace stdlib log.Printf with logger.InfoCF/WarnCF for consistency
  with the rest of the codebase (addresses @nikolasdehor review point sipeed#3)
- ReleaseAll: clean refToScope/refs mappings even if refs entry is missing
- CleanExpired: guard refToScope lookup before scope cleanup
- Add TestReleaseAllCleansMappingsIfRefsMissing for robustness

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants