Skip to content

Commit c4349de

Browse files
Merge PR paoloanzn#7: feat: Implement context compression services (contextCollapse + snipCompact)
2 parents 08b57ce + aee5978 commit c4349de

24 files changed

Lines changed: 2803 additions & 89 deletions
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Issue #1: Implement contextCollapse Service (High Priority) ✅ COMPLETED
2+
3+
## Status
4+
**COMPLETED** - Full implementation created and build passing
5+
6+
## Files Created
7+
8+
| File | Description |
9+
|------|-------------|
10+
| `src/services/contextCollapse/types.ts` | Type definitions (CollapseState, CommitEntry, SnapshotEntry) |
11+
| `src/services/contextCollapse/state.ts` | State management (getState, addCommit, subscribe) |
12+
| `src/services/contextCollapse/operations.ts` | Core operations (projectView, findCollapsibleSpans, commitSpan) |
13+
| `src/services/contextCollapse/persist.ts` | Persistence (restoreFromEntries, createSnapshot) |
14+
| `src/services/contextCollapse/index.ts` | Main API (applyCollapsesIfNeeded, recoverFromOverflow, etc.) |
15+
16+
## API Implemented
17+
18+
### Core Functions
19+
-`applyCollapsesIfNeeded(messages, toolUseContext, querySource)` - Apply context collapses
20+
-`isContextCollapseEnabled()` - Check if feature is enabled
21+
-`isWithheldPromptTooLong(message, isPromptTooLongMessage, querySource)` - Check prompt length
22+
-`recoverFromOverflow(messages, querySource)` - Recover from token overflow
23+
-`resetContextCollapse()` - Reset collapse state
24+
25+
### Additional Functions
26+
-`projectView(messages)` - Project commits onto message list
27+
-`getSummaries()` - Get summary map
28+
-`registerSummary(uuid, summary)` - Register summary
29+
-`restoreFromEntries(commits, snapshot)` - Restore from persisted state
30+
-`getStats()` - Get collapse statistics
31+
-`subscribe(callback)` - Subscribe to state changes
32+
33+
## Architecture
34+
35+
```
36+
contextCollapse/
37+
├── types.ts # TypeScript interfaces
38+
├── state.ts # Module state + subscriptions
39+
├── operations.ts # Message transformation logic
40+
├── persist.ts # Save/restore state
41+
└── index.ts # Public API
42+
```
43+
44+
## How It Works
45+
46+
1. **Span Detection**: `findCollapsibleSpans()` finds message ranges to collapse
47+
2. **Commit Creation**: `commitSpan()` creates a commit with summary
48+
3. **View Projection**: `projectView()` replaces messages with summaries
49+
4. **Overflow Recovery**: `recoverFromOverflow()` forces collapse on 413 errors
50+
5. **Persistence**: `restoreFromEntries()` restores state from logs
51+
52+
## Build Status
53+
```
54+
✅ 4701 modules bundled
55+
✅ 23.92 MB output
56+
✅ CLI runs successfully
57+
```
58+
59+
## Notes
60+
61+
- Implementation is simplified compared to internal Anthropic version
62+
- Summary generation uses heuristics instead of LLM
63+
- All feature flags (CONTEXT_COLLAPSE) are enabled for public builds
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
# contextCollapse 服务实现详细分析
2+
3+
## 概述
4+
5+
contextCollapse 是一个**智能上下文压缩系统**,它通过以下方式管理长对话:
6+
1. **分段压缩** - 将旧消息分组并生成摘要
7+
2. **提交日志** - 持久化压缩记录(marble-origami-commit)
8+
3. **快照管理** - 保存待处理和进行中的压缩状态
9+
4. **溢出恢复** - 当达到 token 限制时自动恢复
10+
11+
## 核心概念
12+
13+
### 1. Commit(提交)
14+
```typescript
15+
ContextCollapseCommitEntry = {
16+
type: 'marble-origami-commit'
17+
sessionId: UUID
18+
collapseId: string // 16位数字ID
19+
summaryUuid: string // 摘要消息的UUID
20+
summaryContent: string // <collapsed id="...">text</collapsed>
21+
summary: string // 纯文本摘要
22+
}
23+
```
24+
25+
### 2. Snapshot(快照)
26+
```typescript
27+
ContextCollapseSnapshotEntry = {
28+
type: 'marble-origami-snapshot'
29+
sessionId: UUID
30+
staged: Array<{
31+
startUuid: string
32+
endUuid: string
33+
summary: string
34+
risk: number // 风险评分
35+
stagedAt: number // 时间戳
36+
}>
37+
// 触发器状态
38+
}
39+
```
40+
41+
### 3. 状态流转
42+
```
43+
消息列表 → 检测阈值 → 分段(stage) → 生成摘要 → 提交(commit) → 持久化
44+
↑ ↓
45+
└────────── 溢出时恢复 ────────────────┘
46+
```
47+
48+
## 需要实现的文件结构
49+
50+
```
51+
src/services/contextCollapse/
52+
├── index.ts # 主模块,导出核心API
53+
├── types.ts # 类型定义(可合并到index.ts)
54+
├── operations.ts # projectView等操作
55+
├── persist.ts # 持久化/恢复
56+
└── state.ts # 状态管理(可选)
57+
```
58+
59+
## 详细实现方案
60+
61+
### 1. index.ts - 主模块
62+
63+
```typescript
64+
// 核心状态
65+
interface CollapseState {
66+
enabled: boolean
67+
commits: ContextCollapseCommitEntry[]
68+
snapshot: ContextCollapseSnapshotEntry | null
69+
staged: StagedSpan[]
70+
nextCollapseId: number
71+
}
72+
73+
const state: CollapseState = {
74+
enabled: true,
75+
commits: [],
76+
snapshot: null,
77+
staged: [],
78+
nextCollapseId: 1,
79+
}
80+
81+
// 导出函数
82+
export function isContextCollapseEnabled(): boolean
83+
export async function applyCollapsesIfNeeded(
84+
messages: Message[],
85+
toolUseContext: ToolUseContext,
86+
querySource: QuerySource
87+
): Promise<{ messages: Message[] }>
88+
89+
export function isWithheldPromptTooLong(
90+
message: Message,
91+
isPromptTooLongMessage: (m: Message) => boolean,
92+
querySource: QuerySource
93+
): boolean
94+
95+
export function recoverFromOverflow(
96+
messages: Message[],
97+
querySource: QuerySource
98+
): { messages: Message[]; committed: number }
99+
100+
export function resetContextCollapse(): void
101+
102+
// TokenWarning 需要的统计
103+
export function getStats(): CollapseStats
104+
export function subscribe(callback: () => void): () => void
105+
```
106+
107+
### 2. operations.ts - 视图操作
108+
109+
```typescript
110+
/**
111+
* 将提交日志投影到消息列表
112+
* 用摘要替换已折叠的消息段
113+
*/
114+
export function projectView(messages: Message[]): Message[] {
115+
const commits = getCommits()
116+
// 对于每个 commit,找到对应的原始消息范围
117+
// 用 summaryContent 替换该范围内的消息
118+
// 返回新的消息列表
119+
}
120+
121+
/**
122+
* 注册摘要到持久化存储
123+
*/
124+
export function registerSummary(
125+
summaryUuid: string,
126+
summary: string
127+
): void
128+
129+
/**
130+
* 获取所有摘要
131+
*/
132+
export function getSummaries(): Map<string, string>
133+
```
134+
135+
### 3. persist.ts - 持久化
136+
137+
```typescript
138+
/**
139+
* 从日志条目恢复状态
140+
*/
141+
export function restoreFromEntries(
142+
commits: ContextCollapseCommitEntry[],
143+
snapshot: ContextCollapseSnapshotEntry | null
144+
): void {
145+
// 恢复 commits 到 state.commits
146+
// 恢复 snapshot 到 state.snapshot
147+
// 重新计算 nextCollapseId
148+
}
149+
150+
/**
151+
* 保存当前状态到持久化存储
152+
*/
153+
export function persistState(): void
154+
```
155+
156+
## 实现步骤
157+
158+
### 第一步:基础框架(可运行)
159+
160+
1. 创建 `index.ts` 框架,所有函数返回 safe defaults
161+
2. 导出必要的类型
162+
3. 确保构建通过
163+
164+
### 第二步:核心逻辑
165+
166+
1. 实现 `projectView` - 这是最核心的功能
167+
2. 实现提交日志管理
168+
3. 实现快照管理
169+
170+
### 第三步:高级功能
171+
172+
1. 实现 `applyCollapsesIfNeeded`
173+
2. 实现溢出恢复
174+
3. 实现统计和订阅
175+
176+
### 第四步:集成测试
177+
178+
1. 测试与 query.ts 的集成
179+
2. 测试与 TokenWarning 的集成
180+
3. 测试持久化/恢复
181+
182+
## 最小可行实现(MVP
183+
184+
最简单的实现可以先让函数返回空值或原值,确保系统能运行:
185+
186+
```typescript
187+
// index.ts MVP
188+
export const isContextCollapseEnabled = () => false
189+
export const applyCollapsesIfNeeded = async (messages) => ({ messages })
190+
export const isWithheldPromptTooLong = () => false
191+
export const recoverFromOverflow = (messages) => ({ messages, committed: 0 })
192+
export const resetContextCollapse = () => {}
193+
export const getStats = () => ({ collapsedSpans: 0, stagedSpans: 0, health: {} })
194+
export const subscribe = () => () => {}
195+
196+
// operations.ts MVP
197+
export const projectView = (messages) => messages
198+
```
199+
200+
然后逐步添加真实逻辑。
201+
202+
## 依赖关系
203+
204+
```
205+
query.ts
206+
├── applyCollapsesIfNeeded
207+
├── isContextCollapseEnabled
208+
├── recoverFromOverflow
209+
└── isWithheldPromptTooLong
210+
211+
TokenWarning.tsx
212+
├── isContextCollapseEnabled
213+
├── getStats
214+
└── subscribe
215+
216+
REPL.tsx
217+
└── resetContextCollapse
218+
219+
commands/context/
220+
└── operations.projectView
221+
222+
ResumeConversation.tsx
223+
└── persist.restoreFromEntries
224+
```
225+
226+
## 关键决策点
227+
228+
1. **何时触发折叠?** - 基于 token 阈值还是消息数量?
229+
2. **如何生成摘要?** - 使用 LLM 还是简单截断?
230+
3. **持久化策略?** - 文件存储还是内存存储?
231+
4. **并发处理?** - 是否允许多个折叠同时进行?
232+
233+
## 建议的实现顺序
234+
235+
1. ✅ 基础 stub(已完成)
236+
2. 🔄 projectView 最小实现
237+
3. 🔄 提交日志管理
238+
4. ⏳ 摘要生成逻辑
239+
5. ⏳ 完整 applyCollapsesIfNeeded
240+
6. ⏳ 溢出恢复
241+
7. ⏳ 持久化/恢复
242+
243+
## 相关文件参考
244+
245+
- `src/services/compact/` - 类似的压缩逻辑可参考
246+
- `src/services/compact/autoCompact.ts` - 自动压缩参考
247+
- `src/services/compact/microCompact.ts` - 微压缩参考
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Issue #2: Complete cachedMicrocompact Implementation (Medium Priority)
2+
3+
## Overview
4+
The `cachedMicrocompact` feature provides advanced context compression using cache editing. Currently has a basic stub implementation.
5+
6+
## Current State
7+
**File**: `src/services/compact/cachedMicrocompact.ts`
8+
9+
Has interface definitions but minimal logic. Used by `microCompact.ts` for advanced compression.
10+
11+
## Required Improvements
12+
13+
### Core Functions (Already stubbed, need full logic)
14+
- [ ] `registerToolResult(state, toolUseId)` - Register tool results for tracking
15+
- [ ] `registerToolMessage(state, toolIds)` - Register tool message groups
16+
- [ ] `getToolResultsToDelete(state)` - Determine which tool results to delete
17+
- [ ] `createCacheEditsBlock(state, toolIds)` - Create cache edit blocks
18+
- [ ] `markToolsSentToAPI(state)` - Mark tools as sent
19+
- [ ] `resetCachedMCState(state)` - Reset state
20+
21+
### Configuration
22+
- [ ] `isCachedMicrocompactEnabled()` - Should return `true` for public builds
23+
- [ ] `isModelSupportedForCacheEditing(model)` - Check model compatibility
24+
- [ ] `getCachedMCConfig()` - Return proper configuration
25+
26+
## Integration Points
27+
- Used by `src/services/compact/microCompact.ts`
28+
- Referenced in `src/query.ts` for `CACHED_MICROCOMPACT` feature
29+
- Gated by `feature('CACHED_MICROCOMPACT')`
30+
31+
## Impact
32+
- **Medium**: Optimizes API calls by using cache editing
33+
- Reduces token usage in long conversations
34+
- Falls back to time-based microcompact if disabled
35+
36+
## Acceptance Criteria
37+
- [ ] All functions implemented with proper state management
38+
- [ ] Integration with microCompact.ts verified
39+
- [ ] Token savings tracking working
40+
- [ ] Proper cleanup on conversation reset

0 commit comments

Comments
 (0)