gencode-ai 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +11 -0
- package/CLAUDE.md +70 -0
- package/LICENSE +21 -0
- package/README.md +117 -0
- package/dist/agent/agent.d.ts +84 -0
- package/dist/agent/agent.d.ts.map +1 -0
- package/dist/agent/agent.js +233 -0
- package/dist/agent/agent.js.map +1 -0
- package/dist/agent/index.d.ts +6 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +6 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/types.d.ts +47 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +5 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/cli/components/App.d.ts +14 -0
- package/dist/cli/components/App.d.ts.map +1 -0
- package/dist/cli/components/App.js +395 -0
- package/dist/cli/components/App.js.map +1 -0
- package/dist/cli/components/CommandSuggestions.d.ts +13 -0
- package/dist/cli/components/CommandSuggestions.d.ts.map +1 -0
- package/dist/cli/components/CommandSuggestions.js +32 -0
- package/dist/cli/components/CommandSuggestions.js.map +1 -0
- package/dist/cli/components/Header.d.ts +9 -0
- package/dist/cli/components/Header.d.ts.map +1 -0
- package/dist/cli/components/Header.js +13 -0
- package/dist/cli/components/Header.js.map +1 -0
- package/dist/cli/components/Input.d.ts +13 -0
- package/dist/cli/components/Input.d.ts.map +1 -0
- package/dist/cli/components/Input.js +27 -0
- package/dist/cli/components/Input.js.map +1 -0
- package/dist/cli/components/Logo.d.ts +2 -0
- package/dist/cli/components/Logo.d.ts.map +1 -0
- package/dist/cli/components/Logo.js +8 -0
- package/dist/cli/components/Logo.js.map +1 -0
- package/dist/cli/components/Messages.d.ts +37 -0
- package/dist/cli/components/Messages.d.ts.map +1 -0
- package/dist/cli/components/Messages.js +106 -0
- package/dist/cli/components/Messages.js.map +1 -0
- package/dist/cli/components/ModelSelector.d.ts +13 -0
- package/dist/cli/components/ModelSelector.d.ts.map +1 -0
- package/dist/cli/components/ModelSelector.js +72 -0
- package/dist/cli/components/ModelSelector.js.map +1 -0
- package/dist/cli/components/Spinner.d.ts +12 -0
- package/dist/cli/components/Spinner.d.ts.map +1 -0
- package/dist/cli/components/Spinner.js +45 -0
- package/dist/cli/components/Spinner.js.map +1 -0
- package/dist/cli/components/index.d.ts +12 -0
- package/dist/cli/components/index.d.ts.map +1 -0
- package/dist/cli/components/index.js +12 -0
- package/dist/cli/components/index.js.map +1 -0
- package/dist/cli/components/theme.d.ts +31 -0
- package/dist/cli/components/theme.d.ts.map +1 -0
- package/dist/cli/components/theme.js +36 -0
- package/dist/cli/components/theme.js.map +1 -0
- package/dist/cli/index-legacy.d.ts +7 -0
- package/dist/cli/index-legacy.d.ts.map +1 -0
- package/dist/cli/index-legacy.js +431 -0
- package/dist/cli/index-legacy.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +116 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/ink-cli.d.ts +7 -0
- package/dist/cli/ink-cli.d.ts.map +1 -0
- package/dist/cli/ink-cli.js +105 -0
- package/dist/cli/ink-cli.js.map +1 -0
- package/dist/cli/session-picker.d.ts +16 -0
- package/dist/cli/session-picker.d.ts.map +1 -0
- package/dist/cli/session-picker.js +280 -0
- package/dist/cli/session-picker.js.map +1 -0
- package/dist/cli/ui.d.ts +61 -0
- package/dist/cli/ui.d.ts.map +1 -0
- package/dist/cli/ui.js +364 -0
- package/dist/cli/ui.js.map +1 -0
- package/dist/config/index.d.ts +7 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +6 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/manager.d.ts +31 -0
- package/dist/config/manager.d.ts.map +1 -0
- package/dist/config/manager.js +65 -0
- package/dist/config/manager.js.map +1 -0
- package/dist/config/types.d.ts +22 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +6 -0
- package/dist/config/types.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/memory/index.d.ts +10 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +9 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/init.d.ts +20 -0
- package/dist/memory/init.d.ts.map +1 -0
- package/dist/memory/init.js +332 -0
- package/dist/memory/init.js.map +1 -0
- package/dist/memory/manager.d.ts +85 -0
- package/dist/memory/manager.d.ts.map +1 -0
- package/dist/memory/manager.js +234 -0
- package/dist/memory/manager.js.map +1 -0
- package/dist/memory/types.d.ts +74 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js +6 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/permissions/index.d.ts +7 -0
- package/dist/permissions/index.d.ts.map +1 -0
- package/dist/permissions/index.js +6 -0
- package/dist/permissions/index.js.map +1 -0
- package/dist/permissions/manager.d.ts +32 -0
- package/dist/permissions/manager.d.ts.map +1 -0
- package/dist/permissions/manager.js +79 -0
- package/dist/permissions/manager.js.map +1 -0
- package/dist/permissions/types.d.ts +14 -0
- package/dist/permissions/types.d.ts.map +1 -0
- package/dist/permissions/types.js +17 -0
- package/dist/permissions/types.js.map +1 -0
- package/dist/providers/anthropic.d.ts +20 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +185 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/gemini.d.ts +21 -0
- package/dist/providers/gemini.d.ts.map +1 -0
- package/dist/providers/gemini.js +241 -0
- package/dist/providers/gemini.js.map +1 -0
- package/dist/providers/index.d.ts +34 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +72 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/openai.d.ts +19 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +221 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/providers/types.d.ts +125 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +6 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/session/index.d.ts +6 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +6 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/manager.d.ts +101 -0
- package/dist/session/manager.d.ts.map +1 -0
- package/dist/session/manager.js +295 -0
- package/dist/session/manager.js.map +1 -0
- package/dist/session/types.d.ts +39 -0
- package/dist/session/types.d.ts.map +1 -0
- package/dist/session/types.js +10 -0
- package/dist/session/types.js.map +1 -0
- package/dist/tools/builtin/bash.d.ts +7 -0
- package/dist/tools/builtin/bash.d.ts.map +1 -0
- package/dist/tools/builtin/bash.js +80 -0
- package/dist/tools/builtin/bash.js.map +1 -0
- package/dist/tools/builtin/edit.d.ts +7 -0
- package/dist/tools/builtin/edit.d.ts.map +1 -0
- package/dist/tools/builtin/edit.js +32 -0
- package/dist/tools/builtin/edit.js.map +1 -0
- package/dist/tools/builtin/glob.d.ts +7 -0
- package/dist/tools/builtin/glob.d.ts.map +1 -0
- package/dist/tools/builtin/glob.js +36 -0
- package/dist/tools/builtin/glob.js.map +1 -0
- package/dist/tools/builtin/grep.d.ts +7 -0
- package/dist/tools/builtin/grep.d.ts.map +1 -0
- package/dist/tools/builtin/grep.js +59 -0
- package/dist/tools/builtin/grep.js.map +1 -0
- package/dist/tools/builtin/read.d.ts +7 -0
- package/dist/tools/builtin/read.d.ts.map +1 -0
- package/dist/tools/builtin/read.js +29 -0
- package/dist/tools/builtin/read.js.map +1 -0
- package/dist/tools/builtin/write.d.ts +7 -0
- package/dist/tools/builtin/write.d.ts.map +1 -0
- package/dist/tools/builtin/write.js +24 -0
- package/dist/tools/builtin/write.js.map +1 -0
- package/dist/tools/index.d.ts +38 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +32 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/registry.d.ts +22 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +71 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/types.d.ts +62 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +126 -0
- package/dist/tools/types.js.map +1 -0
- package/docs/README.md +16 -0
- package/docs/proposals/0001-web-fetch-tool.md +293 -0
- package/docs/proposals/0002-web-search-tool.md +306 -0
- package/docs/proposals/0003-task-subagents.md +333 -0
- package/docs/proposals/0004-plan-mode.md +338 -0
- package/docs/proposals/0005-todo-system.md +299 -0
- package/docs/proposals/0006-memory-system.md +539 -0
- package/docs/proposals/0007-context-management.md +429 -0
- package/docs/proposals/0008-checkpointing.md +327 -0
- package/docs/proposals/0009-hooks-system.md +343 -0
- package/docs/proposals/0010-mcp-integration.md +382 -0
- package/docs/proposals/0011-custom-commands.md +374 -0
- package/docs/proposals/0012-ask-user-question.md +317 -0
- package/docs/proposals/0013-multi-edit-tool.md +345 -0
- package/docs/proposals/0014-lsp-tool.md +478 -0
- package/docs/proposals/0015-ls-tool.md +407 -0
- package/docs/proposals/0016-kill-shell-tool.md +455 -0
- package/docs/proposals/0017-background-tasks.md +489 -0
- package/docs/proposals/0018-parallel-tool-execution.md +415 -0
- package/docs/proposals/0019-session-enhancements.md +462 -0
- package/docs/proposals/0020-session-summarization.md +447 -0
- package/docs/proposals/0021-skills-system.md +409 -0
- package/docs/proposals/0022-plugin-system.md +467 -0
- package/docs/proposals/0023-permission-enhancements.md +470 -0
- package/docs/proposals/0024-keyboard-shortcuts.md +443 -0
- package/docs/proposals/0025-cost-tracking.md +447 -0
- package/docs/proposals/0026-git-integration.md +475 -0
- package/docs/proposals/0027-enhanced-read-tool.md +514 -0
- package/docs/proposals/0028-enhanced-bash-tool.md +511 -0
- package/docs/proposals/0029-notebook-edit-tool.md +413 -0
- package/docs/proposals/0030-plugin-marketplace.md +360 -0
- package/docs/proposals/0031-command-suggestions.md +295 -0
- package/docs/proposals/0032-ide-integrations.md +328 -0
- package/docs/proposals/0033-enterprise-deployment.md +221 -0
- package/docs/proposals/0034-sandboxing.md +273 -0
- package/docs/proposals/0035-auto-updater.md +311 -0
- package/docs/proposals/0036-enhanced-glob-tool.md +267 -0
- package/docs/proposals/0037-enhanced-grep-tool.md +360 -0
- package/docs/proposals/0038-interactive-cli-ui.md +373 -0
- package/docs/proposals/0039-streaming-enhancements.md +359 -0
- package/docs/proposals/0040-multi-provider-enhancements.md +369 -0
- package/docs/proposals/README.md +84 -0
- package/docs/proposals/TEMPLATE.md +57 -0
- package/docs/proposals/research/claude-code-research.md +307 -0
- package/examples/agent-demo.ts +115 -0
- package/examples/basic.ts +166 -0
- package/package.json +50 -0
- package/src/agent/agent.ts +276 -0
- package/src/agent/index.ts +6 -0
- package/src/agent/types.ts +62 -0
- package/src/cli/components/App.tsx +565 -0
- package/src/cli/components/CommandSuggestions.tsx +58 -0
- package/src/cli/components/Header.tsx +36 -0
- package/src/cli/components/Input.tsx +60 -0
- package/src/cli/components/Logo.tsx +16 -0
- package/src/cli/components/Messages.tsx +210 -0
- package/src/cli/components/ModelSelector.tsx +135 -0
- package/src/cli/components/Spinner.tsx +72 -0
- package/src/cli/components/index.ts +21 -0
- package/src/cli/components/theme.ts +36 -0
- package/src/cli/index.tsx +136 -0
- package/src/config/index.ts +7 -0
- package/src/config/manager.ts +77 -0
- package/src/config/types.ts +25 -0
- package/src/index.ts +86 -0
- package/src/permissions/index.ts +7 -0
- package/src/permissions/manager.ts +97 -0
- package/src/permissions/types.ts +29 -0
- package/src/providers/anthropic.ts +224 -0
- package/src/providers/gemini.ts +295 -0
- package/src/providers/index.ts +97 -0
- package/src/providers/openai.ts +261 -0
- package/src/providers/types.ts +181 -0
- package/src/session/index.ts +6 -0
- package/src/session/manager.ts +354 -0
- package/src/session/types.ts +49 -0
- package/src/tools/builtin/bash.ts +92 -0
- package/src/tools/builtin/edit.ts +37 -0
- package/src/tools/builtin/glob.ts +42 -0
- package/src/tools/builtin/grep.ts +67 -0
- package/src/tools/builtin/read.ts +34 -0
- package/src/tools/builtin/write.ts +27 -0
- package/src/tools/index.ts +36 -0
- package/src/tools/registry.ts +83 -0
- package/src/tools/types.ts +172 -0
- package/tsconfig.json +21 -0
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
# Proposal: Session Summarization
|
|
2
|
+
|
|
3
|
+
- **Proposal ID**: 0020
|
|
4
|
+
- **Author**: mycode team
|
|
5
|
+
- **Status**: Draft
|
|
6
|
+
- **Created**: 2025-01-15
|
|
7
|
+
- **Updated**: 2025-01-15
|
|
8
|
+
|
|
9
|
+
## Summary
|
|
10
|
+
|
|
11
|
+
Implement automatic session summarization to compress long conversations while preserving essential context. This enables unlimited conversation length through intelligent context management without hitting token limits.
|
|
12
|
+
|
|
13
|
+
## Motivation
|
|
14
|
+
|
|
15
|
+
LLM context windows are limited, causing issues with long conversations:
|
|
16
|
+
|
|
17
|
+
1. **Token limits**: Conversations get truncated or fail
|
|
18
|
+
2. **Cost increase**: Long contexts cost more per request
|
|
19
|
+
3. **Latency**: Large contexts slow response time
|
|
20
|
+
4. **Lost context**: Important early context gets dropped
|
|
21
|
+
5. **No continuity**: Can't resume long projects effectively
|
|
22
|
+
|
|
23
|
+
Automatic summarization maintains conversation quality indefinitely.
|
|
24
|
+
|
|
25
|
+
## Claude Code Reference
|
|
26
|
+
|
|
27
|
+
Claude Code mentions automatic summarization:
|
|
28
|
+
|
|
29
|
+
### From System Prompt
|
|
30
|
+
```
|
|
31
|
+
The conversation has unlimited context through automatic summarization.
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Expected Behavior
|
|
35
|
+
- Long conversations are automatically summarized
|
|
36
|
+
- Critical context (file changes, decisions) preserved
|
|
37
|
+
- Summaries replace older message blocks
|
|
38
|
+
- Agent maintains awareness of full conversation history
|
|
39
|
+
- Seamless experience for user
|
|
40
|
+
|
|
41
|
+
## Detailed Design
|
|
42
|
+
|
|
43
|
+
### API Design
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
// src/session/summarization/types.ts
|
|
47
|
+
interface SummarizationConfig {
|
|
48
|
+
enabled: boolean;
|
|
49
|
+
trigger_threshold: number; // Messages before summarizing
|
|
50
|
+
target_compression: number; // Target compression ratio (e.g., 0.3)
|
|
51
|
+
preserve_recent: number; // Keep N recent messages intact
|
|
52
|
+
preserve_system: boolean; // Always keep system prompts
|
|
53
|
+
model?: string; // Model for summarization
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
interface ConversationSummary {
|
|
57
|
+
id: string;
|
|
58
|
+
covering_messages: [number, number]; // Range of summarized messages
|
|
59
|
+
content: string;
|
|
60
|
+
key_decisions: string[];
|
|
61
|
+
files_modified: string[];
|
|
62
|
+
tools_used: ToolUsageSummary[];
|
|
63
|
+
generated_at: string;
|
|
64
|
+
token_count: number;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
interface ToolUsageSummary {
|
|
68
|
+
tool: string;
|
|
69
|
+
count: number;
|
|
70
|
+
notable_uses: string[];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
interface SummarizedSession {
|
|
74
|
+
metadata: SessionMetadata;
|
|
75
|
+
summaries: ConversationSummary[];
|
|
76
|
+
recent_messages: Message[];
|
|
77
|
+
full_message_count: number;
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Summarization Engine
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
// src/session/summarization/engine.ts
|
|
85
|
+
class SummarizationEngine {
|
|
86
|
+
private provider: LLMProvider;
|
|
87
|
+
private config: SummarizationConfig;
|
|
88
|
+
|
|
89
|
+
constructor(provider: LLMProvider, config?: Partial<SummarizationConfig>) {
|
|
90
|
+
this.provider = provider;
|
|
91
|
+
this.config = {
|
|
92
|
+
enabled: true,
|
|
93
|
+
trigger_threshold: 50,
|
|
94
|
+
target_compression: 0.3,
|
|
95
|
+
preserve_recent: 10,
|
|
96
|
+
preserve_system: true,
|
|
97
|
+
...config
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async shouldSummarize(session: Session): Promise<boolean> {
|
|
102
|
+
if (!this.config.enabled) return false;
|
|
103
|
+
return session.messages.length > this.config.trigger_threshold;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async summarize(
|
|
107
|
+
messages: Message[],
|
|
108
|
+
range: [number, number]
|
|
109
|
+
): Promise<ConversationSummary> {
|
|
110
|
+
const toSummarize = messages.slice(range[0], range[1] + 1);
|
|
111
|
+
|
|
112
|
+
// Extract structured information
|
|
113
|
+
const filesModified = this.extractFilesModified(toSummarize);
|
|
114
|
+
const toolsUsed = this.extractToolUsage(toSummarize);
|
|
115
|
+
const keyDecisions = await this.extractKeyDecisions(toSummarize);
|
|
116
|
+
|
|
117
|
+
// Generate narrative summary
|
|
118
|
+
const summaryContent = await this.generateSummary(toSummarize);
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
id: generateId(),
|
|
122
|
+
covering_messages: range,
|
|
123
|
+
content: summaryContent,
|
|
124
|
+
key_decisions: keyDecisions,
|
|
125
|
+
files_modified: filesModified,
|
|
126
|
+
tools_used: toolsUsed,
|
|
127
|
+
generated_at: new Date().toISOString(),
|
|
128
|
+
token_count: countTokens(summaryContent)
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
private async generateSummary(messages: Message[]): Promise<string> {
|
|
133
|
+
const prompt = `Summarize this conversation segment concisely.
|
|
134
|
+
Focus on:
|
|
135
|
+
1. What the user was trying to accomplish
|
|
136
|
+
2. What actions were taken (files changed, commands run)
|
|
137
|
+
3. Any important decisions or discoveries
|
|
138
|
+
4. Current state at the end of this segment
|
|
139
|
+
|
|
140
|
+
Keep the summary focused and technical. Use bullet points.
|
|
141
|
+
|
|
142
|
+
Conversation:
|
|
143
|
+
${this.formatMessages(messages)}
|
|
144
|
+
|
|
145
|
+
Summary:`;
|
|
146
|
+
|
|
147
|
+
const response = await this.provider.complete({
|
|
148
|
+
messages: [{ role: 'user', content: prompt }],
|
|
149
|
+
max_tokens: 1000
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
return response.content[0].text;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
private extractFilesModified(messages: Message[]): string[] {
|
|
156
|
+
const files = new Set<string>();
|
|
157
|
+
|
|
158
|
+
for (const msg of messages) {
|
|
159
|
+
if (typeof msg.content !== 'string') {
|
|
160
|
+
for (const block of msg.content) {
|
|
161
|
+
if (block.type === 'tool_use') {
|
|
162
|
+
if (['Write', 'Edit'].includes(block.name)) {
|
|
163
|
+
files.add(block.input.file_path);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return Array.from(files);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
private extractToolUsage(messages: Message[]): ToolUsageSummary[] {
|
|
174
|
+
const toolStats = new Map<string, { count: number; uses: string[] }>();
|
|
175
|
+
|
|
176
|
+
for (const msg of messages) {
|
|
177
|
+
if (typeof msg.content !== 'string') {
|
|
178
|
+
for (const block of msg.content) {
|
|
179
|
+
if (block.type === 'tool_use') {
|
|
180
|
+
const stats = toolStats.get(block.name) || { count: 0, uses: [] };
|
|
181
|
+
stats.count++;
|
|
182
|
+
if (stats.uses.length < 3) {
|
|
183
|
+
stats.uses.push(summarizeToolUse(block));
|
|
184
|
+
}
|
|
185
|
+
toolStats.set(block.name, stats);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return Array.from(toolStats.entries()).map(([tool, stats]) => ({
|
|
192
|
+
tool,
|
|
193
|
+
count: stats.count,
|
|
194
|
+
notable_uses: stats.uses
|
|
195
|
+
}));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
private async extractKeyDecisions(messages: Message[]): Promise<string[]> {
|
|
199
|
+
// Look for decision patterns in conversation
|
|
200
|
+
const decisions: string[] = [];
|
|
201
|
+
|
|
202
|
+
for (const msg of messages) {
|
|
203
|
+
const content = typeof msg.content === 'string' ? msg.content : '';
|
|
204
|
+
|
|
205
|
+
// Look for decision indicators
|
|
206
|
+
if (content.includes('decided to') ||
|
|
207
|
+
content.includes('chose to') ||
|
|
208
|
+
content.includes('will use') ||
|
|
209
|
+
content.includes('going with')) {
|
|
210
|
+
decisions.push(this.extractDecisionContext(content));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return decisions.slice(0, 5); // Keep top 5
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Session Manager Integration
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
// Updated src/session/manager.ts
|
|
223
|
+
class SessionManager {
|
|
224
|
+
private summarizer: SummarizationEngine;
|
|
225
|
+
|
|
226
|
+
async addMessage(message: Message): Promise<void> {
|
|
227
|
+
this.currentSession.messages.push(message);
|
|
228
|
+
|
|
229
|
+
// Check if summarization needed
|
|
230
|
+
if (await this.summarizer.shouldSummarize(this.currentSession)) {
|
|
231
|
+
await this.performSummarization();
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
await this.save();
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
private async performSummarization(): Promise<void> {
|
|
238
|
+
const session = this.currentSession;
|
|
239
|
+
const preserve = this.summarizer.config.preserve_recent;
|
|
240
|
+
|
|
241
|
+
// Determine range to summarize (keep recent messages)
|
|
242
|
+
const summarizeEnd = session.messages.length - preserve - 1;
|
|
243
|
+
const summarizeStart = this.getLastSummaryEnd() + 1;
|
|
244
|
+
|
|
245
|
+
if (summarizeEnd <= summarizeStart) return;
|
|
246
|
+
|
|
247
|
+
// Generate summary
|
|
248
|
+
const summary = await this.summarizer.summarize(
|
|
249
|
+
session.messages,
|
|
250
|
+
[summarizeStart, summarizeEnd]
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
// Store summary and compress messages
|
|
254
|
+
session.summaries = session.summaries || [];
|
|
255
|
+
session.summaries.push(summary);
|
|
256
|
+
|
|
257
|
+
// Replace summarized messages with placeholder
|
|
258
|
+
const preserved = session.messages.slice(0, summarizeStart);
|
|
259
|
+
const recent = session.messages.slice(summarizeEnd + 1);
|
|
260
|
+
|
|
261
|
+
session.messages = [
|
|
262
|
+
...preserved,
|
|
263
|
+
{
|
|
264
|
+
role: 'system',
|
|
265
|
+
content: `[Previous conversation summarized - ${summary.covering_messages[1] - summary.covering_messages[0] + 1} messages]\n\n${summary.content}`
|
|
266
|
+
},
|
|
267
|
+
...recent
|
|
268
|
+
];
|
|
269
|
+
|
|
270
|
+
session.full_message_count = session.full_message_count || session.messages.length;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
getContextForLLM(): Message[] {
|
|
274
|
+
const session = this.currentSession;
|
|
275
|
+
|
|
276
|
+
// Build context with summaries
|
|
277
|
+
const context: Message[] = [];
|
|
278
|
+
|
|
279
|
+
// Add system prompt if exists
|
|
280
|
+
const systemMsg = session.messages.find(m => m.role === 'system');
|
|
281
|
+
if (systemMsg) context.push(systemMsg);
|
|
282
|
+
|
|
283
|
+
// Add summary context
|
|
284
|
+
if (session.summaries?.length) {
|
|
285
|
+
context.push({
|
|
286
|
+
role: 'system',
|
|
287
|
+
content: this.formatSummariesForContext(session.summaries)
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Add recent messages (skip system prompts already added)
|
|
292
|
+
const recentMessages = session.messages.filter(m =>
|
|
293
|
+
m.role !== 'system' || !m.content.includes('[Previous conversation')
|
|
294
|
+
);
|
|
295
|
+
context.push(...recentMessages);
|
|
296
|
+
|
|
297
|
+
return context;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
private formatSummariesForContext(summaries: ConversationSummary[]): string {
|
|
301
|
+
let context = 'Previous conversation context:\n\n';
|
|
302
|
+
|
|
303
|
+
for (const summary of summaries) {
|
|
304
|
+
context += `--- Earlier in conversation ---\n`;
|
|
305
|
+
context += summary.content + '\n';
|
|
306
|
+
if (summary.files_modified.length) {
|
|
307
|
+
context += `Files modified: ${summary.files_modified.join(', ')}\n`;
|
|
308
|
+
}
|
|
309
|
+
context += '\n';
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return context;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### File Changes
|
|
318
|
+
|
|
319
|
+
| File | Action | Description |
|
|
320
|
+
|------|--------|-------------|
|
|
321
|
+
| `src/session/summarization/types.ts` | Create | Type definitions |
|
|
322
|
+
| `src/session/summarization/engine.ts` | Create | Summarization logic |
|
|
323
|
+
| `src/session/summarization/index.ts` | Create | Module exports |
|
|
324
|
+
| `src/session/manager.ts` | Modify | Integrate summarization |
|
|
325
|
+
| `src/agent/agent.ts` | Modify | Use summarized context |
|
|
326
|
+
|
|
327
|
+
## User Experience
|
|
328
|
+
|
|
329
|
+
### Automatic Summarization (Invisible)
|
|
330
|
+
```
|
|
331
|
+
[After 50+ messages, automatically triggers...]
|
|
332
|
+
|
|
333
|
+
Agent: I notice this conversation is getting long. I've created a summary
|
|
334
|
+
of our earlier discussion to maintain context efficiently.
|
|
335
|
+
|
|
336
|
+
Summary created:
|
|
337
|
+
- Discussed authentication implementation
|
|
338
|
+
- Modified 5 files (auth.ts, login.tsx, ...)
|
|
339
|
+
- Decided to use JWT tokens with refresh mechanism
|
|
340
|
+
- Ran tests successfully
|
|
341
|
+
|
|
342
|
+
Recent conversation preserved. You can continue normally.
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Manual Summarization
|
|
346
|
+
```
|
|
347
|
+
User: /summarize
|
|
348
|
+
|
|
349
|
+
Summarizing conversation history...
|
|
350
|
+
|
|
351
|
+
┌─ Session Summary ─────────────────────────────────┐
|
|
352
|
+
│ Messages: 78 → 23 (70% reduction) │
|
|
353
|
+
│ Tokens saved: ~15,000 │
|
|
354
|
+
│ │
|
|
355
|
+
│ Key Topics: │
|
|
356
|
+
│ • Authentication system design │
|
|
357
|
+
│ • Database schema updates │
|
|
358
|
+
│ • Test coverage improvements │
|
|
359
|
+
│ │
|
|
360
|
+
│ Files Modified: 12 │
|
|
361
|
+
│ Commands Run: 34 │
|
|
362
|
+
│ Key Decisions: 5 │
|
|
363
|
+
└───────────────────────────────────────────────────┘
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### Viewing Full History
|
|
367
|
+
```
|
|
368
|
+
User: /history --full
|
|
369
|
+
|
|
370
|
+
Session history (78 messages total):
|
|
371
|
+
|
|
372
|
+
[Summary 1] Messages 1-30:
|
|
373
|
+
Initial project setup and architecture discussion...
|
|
374
|
+
|
|
375
|
+
[Summary 2] Messages 31-55:
|
|
376
|
+
Authentication implementation and testing...
|
|
377
|
+
|
|
378
|
+
[Recent] Messages 56-78:
|
|
379
|
+
Message 56: User asked about caching...
|
|
380
|
+
Message 57: Agent suggested Redis implementation...
|
|
381
|
+
...
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
## Alternatives Considered
|
|
385
|
+
|
|
386
|
+
### Alternative 1: Simple Truncation
|
|
387
|
+
Just drop old messages.
|
|
388
|
+
|
|
389
|
+
**Pros**: Simple, predictable
|
|
390
|
+
**Cons**: Loses important context
|
|
391
|
+
**Decision**: Rejected - Context loss is unacceptable
|
|
392
|
+
|
|
393
|
+
### Alternative 2: User-Triggered Only
|
|
394
|
+
Only summarize when user requests.
|
|
395
|
+
|
|
396
|
+
**Pros**: User control
|
|
397
|
+
**Cons**: May hit limits unexpectedly
|
|
398
|
+
**Decision**: Rejected - Automatic is better UX
|
|
399
|
+
|
|
400
|
+
### Alternative 3: External Summarization Service
|
|
401
|
+
Use dedicated summarization API.
|
|
402
|
+
|
|
403
|
+
**Pros**: Optimized summaries
|
|
404
|
+
**Cons**: Additional dependency, cost
|
|
405
|
+
**Decision**: Deferred - Use same LLM for now
|
|
406
|
+
|
|
407
|
+
## Security Considerations
|
|
408
|
+
|
|
409
|
+
1. **Data Minimization**: Summaries should not include secrets
|
|
410
|
+
2. **Summary Storage**: Secure storage of summarized content
|
|
411
|
+
3. **Original Deletion**: Option to delete original messages after summary
|
|
412
|
+
4. **Audit Trail**: Keep record of what was summarized
|
|
413
|
+
5. **User Control**: Allow disabling summarization
|
|
414
|
+
|
|
415
|
+
## Testing Strategy
|
|
416
|
+
|
|
417
|
+
1. **Unit Tests**:
|
|
418
|
+
- Summary generation
|
|
419
|
+
- Context reconstruction
|
|
420
|
+
- Token counting
|
|
421
|
+
- Decision extraction
|
|
422
|
+
|
|
423
|
+
2. **Integration Tests**:
|
|
424
|
+
- Long conversation handling
|
|
425
|
+
- Summary quality validation
|
|
426
|
+
- Context continuity
|
|
427
|
+
|
|
428
|
+
3. **Quality Tests**:
|
|
429
|
+
- Agent understands summarized context
|
|
430
|
+
- No important info lost
|
|
431
|
+
- Coherent conversation flow
|
|
432
|
+
|
|
433
|
+
## Migration Path
|
|
434
|
+
|
|
435
|
+
1. **Phase 1**: Basic summarization engine
|
|
436
|
+
2. **Phase 2**: Automatic triggering
|
|
437
|
+
3. **Phase 3**: Structured extraction (files, decisions)
|
|
438
|
+
4. **Phase 4**: User controls and visibility
|
|
439
|
+
5. **Phase 5**: Quality improvements
|
|
440
|
+
|
|
441
|
+
Existing sessions remain unchanged until summarized.
|
|
442
|
+
|
|
443
|
+
## References
|
|
444
|
+
|
|
445
|
+
- [Claude Context Windows](https://docs.anthropic.com/claude/docs/context-windows)
|
|
446
|
+
- [Retrieval Augmented Generation](https://arxiv.org/abs/2005.11401)
|
|
447
|
+
- [Conversation Summarization Research](https://arxiv.org/abs/2106.00829)
|