@calliopelabs/cli 0.4.6 → 0.6.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/README.md +258 -105
- package/dist/branching.d.ts +56 -0
- package/dist/branching.d.ts.map +1 -0
- package/dist/branching.js +211 -0
- package/dist/branching.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +235 -2
- package/dist/cli.js.map +1 -1
- package/dist/completion.d.ts +75 -0
- package/dist/completion.d.ts.map +1 -0
- package/dist/completion.js +234 -0
- package/dist/completion.js.map +1 -0
- package/dist/config.d.ts +36 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +90 -0
- package/dist/config.js.map +1 -1
- package/dist/diff.d.ts +73 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +317 -0
- package/dist/diff.js.map +1 -0
- package/dist/errors.d.ts +41 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +199 -0
- package/dist/errors.js.map +1 -0
- package/dist/file-watcher.d.ts +91 -0
- package/dist/file-watcher.d.ts.map +1 -0
- package/dist/file-watcher.js +269 -0
- package/dist/file-watcher.js.map +1 -0
- package/dist/files.d.ts +49 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +191 -0
- package/dist/files.js.map +1 -0
- package/dist/fuzzy-search.d.ts +75 -0
- package/dist/fuzzy-search.d.ts.map +1 -0
- package/dist/fuzzy-search.js +240 -0
- package/dist/fuzzy-search.js.map +1 -0
- package/dist/hooks.d.ts +79 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +271 -0
- package/dist/hooks.js.map +1 -0
- package/dist/keyboard.d.ts +57 -0
- package/dist/keyboard.d.ts.map +1 -0
- package/dist/keyboard.js +265 -0
- package/dist/keyboard.js.map +1 -0
- package/dist/markdown.d.ts +14 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/markdown.js +248 -0
- package/dist/markdown.js.map +1 -0
- package/dist/mcp.d.ts +90 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +290 -0
- package/dist/mcp.js.map +1 -0
- package/dist/memory.d.ts +104 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +394 -0
- package/dist/memory.js.map +1 -0
- package/dist/model-router.d.ts +67 -0
- package/dist/model-router.d.ts.map +1 -0
- package/dist/model-router.js +289 -0
- package/dist/model-router.js.map +1 -0
- package/dist/parallel-tools.d.ts +51 -0
- package/dist/parallel-tools.d.ts.map +1 -0
- package/dist/parallel-tools.js +278 -0
- package/dist/parallel-tools.js.map +1 -0
- package/dist/project-config.d.ts +84 -0
- package/dist/project-config.d.ts.map +1 -0
- package/dist/project-config.js +250 -0
- package/dist/project-config.js.map +1 -0
- package/dist/providers.d.ts +10 -2
- package/dist/providers.d.ts.map +1 -1
- package/dist/providers.js +240 -38
- package/dist/providers.js.map +1 -1
- package/dist/risk.d.ts +31 -0
- package/dist/risk.d.ts.map +1 -0
- package/dist/risk.js +367 -0
- package/dist/risk.js.map +1 -0
- package/dist/sandbox.d.ts +49 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/sandbox.js +347 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/skills.d.ts +71 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +383 -0
- package/dist/skills.js.map +1 -0
- package/dist/storage.d.ts +139 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +508 -0
- package/dist/storage.js.map +1 -0
- package/dist/streaming.d.ts +94 -0
- package/dist/streaming.d.ts.map +1 -0
- package/dist/streaming.js +305 -0
- package/dist/streaming.js.map +1 -0
- package/dist/summarization.d.ts +76 -0
- package/dist/summarization.d.ts.map +1 -0
- package/dist/summarization.js +242 -0
- package/dist/summarization.js.map +1 -0
- package/dist/themes.d.ts +110 -0
- package/dist/themes.d.ts.map +1 -0
- package/dist/themes.js +329 -0
- package/dist/themes.js.map +1 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +335 -1
- package/dist/tools.js.map +1 -1
- package/dist/types.d.ts +56 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +105 -0
- package/dist/types.js.map +1 -1
- package/dist/ui-cli.d.ts +9 -2
- package/dist/ui-cli.d.ts.map +1 -1
- package/dist/ui-cli.js +1315 -220
- package/dist/ui-cli.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calliope CLI - Improved Streaming
|
|
3
|
+
*
|
|
4
|
+
* Word-by-word streaming with smooth output.
|
|
5
|
+
*/
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// Token Buffer
|
|
8
|
+
// ============================================================================
|
|
9
|
+
export class TokenBuffer {
|
|
10
|
+
buffer = '';
|
|
11
|
+
emitted = '';
|
|
12
|
+
callback;
|
|
13
|
+
options;
|
|
14
|
+
emitTimer = null;
|
|
15
|
+
lastEmitTime = 0;
|
|
16
|
+
constructor(callback, options = {}) {
|
|
17
|
+
this.callback = callback;
|
|
18
|
+
this.options = {
|
|
19
|
+
wordsPerSecond: options.wordsPerSecond || 30,
|
|
20
|
+
chunkSize: options.chunkSize || 1,
|
|
21
|
+
smoothing: options.smoothing !== false,
|
|
22
|
+
preserveFormatting: options.preserveFormatting !== false,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Add tokens to buffer
|
|
27
|
+
*/
|
|
28
|
+
push(token) {
|
|
29
|
+
this.buffer += token;
|
|
30
|
+
this.scheduleEmit();
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Schedule emission of buffered content
|
|
34
|
+
*/
|
|
35
|
+
scheduleEmit() {
|
|
36
|
+
if (this.emitTimer)
|
|
37
|
+
return;
|
|
38
|
+
if (!this.options.smoothing) {
|
|
39
|
+
// Immediate emission
|
|
40
|
+
this.emit();
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
// Calculate delay for smooth word-by-word output
|
|
44
|
+
const msPerWord = 1000 / this.options.wordsPerSecond;
|
|
45
|
+
const now = Date.now();
|
|
46
|
+
const timeSinceLastEmit = now - this.lastEmitTime;
|
|
47
|
+
const delay = Math.max(0, msPerWord - timeSinceLastEmit);
|
|
48
|
+
this.emitTimer = setTimeout(() => {
|
|
49
|
+
this.emitTimer = null;
|
|
50
|
+
this.emit();
|
|
51
|
+
}, delay);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Emit buffered content
|
|
55
|
+
*/
|
|
56
|
+
emit() {
|
|
57
|
+
if (this.buffer.length === 0)
|
|
58
|
+
return;
|
|
59
|
+
// Find a good break point (word boundary)
|
|
60
|
+
let emitPoint = this.buffer.length;
|
|
61
|
+
if (this.options.preserveFormatting) {
|
|
62
|
+
// Don't break in the middle of markdown elements
|
|
63
|
+
const codeBlockStart = this.buffer.indexOf('```');
|
|
64
|
+
const inlineCodeStart = this.buffer.indexOf('`');
|
|
65
|
+
// If we're in a code block, emit everything up to the closing
|
|
66
|
+
if (codeBlockStart !== -1) {
|
|
67
|
+
const codeBlockEnd = this.buffer.indexOf('```', codeBlockStart + 3);
|
|
68
|
+
if (codeBlockEnd !== -1) {
|
|
69
|
+
emitPoint = codeBlockEnd + 3;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
// Still in code block, wait for more
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Handle inline code
|
|
77
|
+
if (inlineCodeStart !== -1 && inlineCodeStart < emitPoint) {
|
|
78
|
+
const inlineCodeEnd = this.buffer.indexOf('`', inlineCodeStart + 1);
|
|
79
|
+
if (inlineCodeEnd === -1) {
|
|
80
|
+
// Incomplete inline code, wait
|
|
81
|
+
emitPoint = inlineCodeStart;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// Find word boundary
|
|
86
|
+
if (emitPoint > this.options.chunkSize) {
|
|
87
|
+
const lastSpace = this.buffer.lastIndexOf(' ', emitPoint);
|
|
88
|
+
const lastNewline = this.buffer.lastIndexOf('\n', emitPoint);
|
|
89
|
+
const breakPoint = Math.max(lastSpace, lastNewline);
|
|
90
|
+
if (breakPoint > this.options.chunkSize) {
|
|
91
|
+
emitPoint = breakPoint + 1;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Emit content
|
|
95
|
+
const toEmit = this.buffer.slice(0, emitPoint);
|
|
96
|
+
this.buffer = this.buffer.slice(emitPoint);
|
|
97
|
+
this.emitted += toEmit;
|
|
98
|
+
this.lastEmitTime = Date.now();
|
|
99
|
+
this.callback(toEmit, false);
|
|
100
|
+
// Schedule next emission if there's more content
|
|
101
|
+
if (this.buffer.length > 0) {
|
|
102
|
+
this.scheduleEmit();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Flush all remaining content
|
|
107
|
+
*/
|
|
108
|
+
flush() {
|
|
109
|
+
if (this.emitTimer) {
|
|
110
|
+
clearTimeout(this.emitTimer);
|
|
111
|
+
this.emitTimer = null;
|
|
112
|
+
}
|
|
113
|
+
if (this.buffer.length > 0) {
|
|
114
|
+
const remaining = this.buffer;
|
|
115
|
+
this.buffer = '';
|
|
116
|
+
this.emitted += remaining;
|
|
117
|
+
this.callback(remaining, true);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
this.callback('', true);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get all emitted content
|
|
125
|
+
*/
|
|
126
|
+
getEmitted() {
|
|
127
|
+
return this.emitted + this.buffer;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Reset buffer
|
|
131
|
+
*/
|
|
132
|
+
reset() {
|
|
133
|
+
if (this.emitTimer) {
|
|
134
|
+
clearTimeout(this.emitTimer);
|
|
135
|
+
this.emitTimer = null;
|
|
136
|
+
}
|
|
137
|
+
this.buffer = '';
|
|
138
|
+
this.emitted = '';
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// ============================================================================
|
|
142
|
+
// Stream Transformers
|
|
143
|
+
// ============================================================================
|
|
144
|
+
/**
|
|
145
|
+
* Transform stream to add typing effect
|
|
146
|
+
*/
|
|
147
|
+
export function createTypingStream(callback, options = {}) {
|
|
148
|
+
return new TokenBuffer(callback, {
|
|
149
|
+
...options,
|
|
150
|
+
smoothing: true,
|
|
151
|
+
wordsPerSecond: options.wordsPerSecond || 40,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Transform stream to accumulate and emit by sentence
|
|
156
|
+
*/
|
|
157
|
+
export function createSentenceStream(callback) {
|
|
158
|
+
let buffer = '';
|
|
159
|
+
const sentenceEnders = /[.!?]\s+/;
|
|
160
|
+
return {
|
|
161
|
+
push(token) {
|
|
162
|
+
buffer += token;
|
|
163
|
+
// Check for sentence end
|
|
164
|
+
const match = buffer.match(sentenceEnders);
|
|
165
|
+
if (match) {
|
|
166
|
+
const endIndex = match.index + match[0].length;
|
|
167
|
+
const sentence = buffer.slice(0, endIndex);
|
|
168
|
+
buffer = buffer.slice(endIndex);
|
|
169
|
+
callback(sentence, false);
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
flush() {
|
|
173
|
+
if (buffer.length > 0) {
|
|
174
|
+
callback(buffer, true);
|
|
175
|
+
buffer = '';
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
callback('', true);
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Transform stream to group by paragraphs
|
|
185
|
+
*/
|
|
186
|
+
export function createParagraphStream(callback) {
|
|
187
|
+
let buffer = '';
|
|
188
|
+
return {
|
|
189
|
+
push(token) {
|
|
190
|
+
buffer += token;
|
|
191
|
+
// Check for paragraph break (double newline)
|
|
192
|
+
const paragraphBreak = buffer.indexOf('\n\n');
|
|
193
|
+
if (paragraphBreak !== -1) {
|
|
194
|
+
const paragraph = buffer.slice(0, paragraphBreak + 2);
|
|
195
|
+
buffer = buffer.slice(paragraphBreak + 2);
|
|
196
|
+
callback(paragraph, false);
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
flush() {
|
|
200
|
+
if (buffer.length > 0) {
|
|
201
|
+
callback(buffer, true);
|
|
202
|
+
buffer = '';
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
callback('', true);
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Track streaming statistics
|
|
212
|
+
*/
|
|
213
|
+
export function createStreamStats() {
|
|
214
|
+
let startTime = Date.now();
|
|
215
|
+
let tokenCount = 0;
|
|
216
|
+
let charCount = 0;
|
|
217
|
+
let wordCount = 0;
|
|
218
|
+
return {
|
|
219
|
+
track(token) {
|
|
220
|
+
if (tokenCount === 0) {
|
|
221
|
+
startTime = Date.now();
|
|
222
|
+
}
|
|
223
|
+
tokenCount++;
|
|
224
|
+
charCount += token.length;
|
|
225
|
+
wordCount += token.split(/\s+/).filter(Boolean).length;
|
|
226
|
+
},
|
|
227
|
+
getStats() {
|
|
228
|
+
const elapsed = (Date.now() - startTime) / 1000;
|
|
229
|
+
return {
|
|
230
|
+
startTime,
|
|
231
|
+
tokenCount,
|
|
232
|
+
charCount,
|
|
233
|
+
wordCount,
|
|
234
|
+
tokensPerSecond: elapsed > 0 ? tokenCount / elapsed : 0,
|
|
235
|
+
};
|
|
236
|
+
},
|
|
237
|
+
reset() {
|
|
238
|
+
startTime = Date.now();
|
|
239
|
+
tokenCount = 0;
|
|
240
|
+
charCount = 0;
|
|
241
|
+
wordCount = 0;
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
// ============================================================================
|
|
246
|
+
// Progress Indicators
|
|
247
|
+
// ============================================================================
|
|
248
|
+
/**
|
|
249
|
+
* Create a streaming progress indicator
|
|
250
|
+
*/
|
|
251
|
+
export function createProgressIndicator(updateCallback) {
|
|
252
|
+
const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
253
|
+
let frameIndex = 0;
|
|
254
|
+
let timer = null;
|
|
255
|
+
let message = '';
|
|
256
|
+
return {
|
|
257
|
+
start() {
|
|
258
|
+
if (timer)
|
|
259
|
+
return;
|
|
260
|
+
timer = setInterval(() => {
|
|
261
|
+
frameIndex = (frameIndex + 1) % frames.length;
|
|
262
|
+
updateCallback(`${frames[frameIndex]} ${message}`);
|
|
263
|
+
}, 80);
|
|
264
|
+
},
|
|
265
|
+
update(msg) {
|
|
266
|
+
if (msg !== undefined) {
|
|
267
|
+
message = msg;
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
stop() {
|
|
271
|
+
if (timer) {
|
|
272
|
+
clearInterval(timer);
|
|
273
|
+
timer = null;
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
// ============================================================================
|
|
279
|
+
// Cursor Animation
|
|
280
|
+
// ============================================================================
|
|
281
|
+
/**
|
|
282
|
+
* Create blinking cursor for streaming
|
|
283
|
+
*/
|
|
284
|
+
export function createCursorAnimation(updateCallback) {
|
|
285
|
+
let visible = true;
|
|
286
|
+
let timer = null;
|
|
287
|
+
return {
|
|
288
|
+
start() {
|
|
289
|
+
if (timer)
|
|
290
|
+
return;
|
|
291
|
+
timer = setInterval(() => {
|
|
292
|
+
visible = !visible;
|
|
293
|
+
updateCallback(visible ? '▌' : ' ');
|
|
294
|
+
}, 500);
|
|
295
|
+
},
|
|
296
|
+
stop() {
|
|
297
|
+
if (timer) {
|
|
298
|
+
clearInterval(timer);
|
|
299
|
+
timer = null;
|
|
300
|
+
}
|
|
301
|
+
updateCallback('');
|
|
302
|
+
},
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
//# sourceMappingURL=streaming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streaming.js","sourceRoot":"","sources":["../src/streaming.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calliope CLI - Context Summarization
|
|
3
|
+
*
|
|
4
|
+
* Summarize long conversations to fit within context limits.
|
|
5
|
+
*/
|
|
6
|
+
import type { Message as LLMMessage } from './types.js';
|
|
7
|
+
export interface SummarizationResult {
|
|
8
|
+
messages: LLMMessage[];
|
|
9
|
+
summarizedCount: number;
|
|
10
|
+
summary: string;
|
|
11
|
+
originalTokens: number;
|
|
12
|
+
reducedTokens: number;
|
|
13
|
+
}
|
|
14
|
+
export interface SummarizationOptions {
|
|
15
|
+
maxTokens: number;
|
|
16
|
+
preserveRecent: number;
|
|
17
|
+
preserveSystem: boolean;
|
|
18
|
+
summaryMaxTokens: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Estimate token count for a message
|
|
22
|
+
* Uses rough approximation: ~4 chars per token for English
|
|
23
|
+
*/
|
|
24
|
+
export declare function estimateTokens(content: string): number;
|
|
25
|
+
/**
|
|
26
|
+
* Estimate total tokens for messages
|
|
27
|
+
*/
|
|
28
|
+
export declare function estimateTotalTokens(messages: LLMMessage[]): number;
|
|
29
|
+
/**
|
|
30
|
+
* Extract key information from messages
|
|
31
|
+
*/
|
|
32
|
+
export declare function extractKeyInfo(messages: LLMMessage[]): {
|
|
33
|
+
topics: string[];
|
|
34
|
+
decisions: string[];
|
|
35
|
+
actions: string[];
|
|
36
|
+
codeChanges: string[];
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Create a summary of messages
|
|
40
|
+
*/
|
|
41
|
+
export declare function summarizeMessages(messages: LLMMessage[]): string;
|
|
42
|
+
/**
|
|
43
|
+
* Summarize conversation to fit within token limit
|
|
44
|
+
*/
|
|
45
|
+
export declare function summarizeConversation(messages: LLMMessage[], options?: Partial<SummarizationOptions>): SummarizationResult;
|
|
46
|
+
export declare class ConversationSummarizer {
|
|
47
|
+
private summaries;
|
|
48
|
+
private currentMessages;
|
|
49
|
+
private options;
|
|
50
|
+
constructor(options?: Partial<SummarizationOptions>);
|
|
51
|
+
/**
|
|
52
|
+
* Add a message
|
|
53
|
+
*/
|
|
54
|
+
addMessage(message: LLMMessage): void;
|
|
55
|
+
/**
|
|
56
|
+
* Add multiple messages
|
|
57
|
+
*/
|
|
58
|
+
addMessages(messages: LLMMessage[]): void;
|
|
59
|
+
/**
|
|
60
|
+
* Check if summarization is needed
|
|
61
|
+
*/
|
|
62
|
+
private checkAndSummarize;
|
|
63
|
+
/**
|
|
64
|
+
* Get current messages with summaries
|
|
65
|
+
*/
|
|
66
|
+
getMessages(): LLMMessage[];
|
|
67
|
+
/**
|
|
68
|
+
* Get summary count
|
|
69
|
+
*/
|
|
70
|
+
getSummaryCount(): number;
|
|
71
|
+
/**
|
|
72
|
+
* Clear all summaries and messages
|
|
73
|
+
*/
|
|
74
|
+
clear(): void;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=summarization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summarization.d.ts","sourceRoot":"","sources":["../src/summarization.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,YAAY,CAAC;AAMxD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAMD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,MAAM,CAgBlE;AAmBD;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG;IACtD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,CA8CA;AAMD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,MAAM,CAuBhE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,UAAU,EAAE,EACtB,OAAO,GAAE,OAAO,CAAC,oBAAoB,CAAM,GAC1C,mBAAmB,CAqDrB;AAMD,qBAAa,sBAAsB;IACjC,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,eAAe,CAAoB;IAC3C,OAAO,CAAC,OAAO,CAAuB;gBAE1B,OAAO,GAAE,OAAO,CAAC,oBAAoB,CAAM;IASvD;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAKrC;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI;IAKzC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAmBzB;;OAEG;IACH,WAAW,IAAI,UAAU,EAAE;IAe3B;;OAEG;IACH,eAAe,IAAI,MAAM;IAIzB;;OAEG;IACH,KAAK,IAAI,IAAI;CAId"}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calliope CLI - Context Summarization
|
|
3
|
+
*
|
|
4
|
+
* Summarize long conversations to fit within context limits.
|
|
5
|
+
*/
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// Token Estimation
|
|
8
|
+
// ============================================================================
|
|
9
|
+
/**
|
|
10
|
+
* Estimate token count for a message
|
|
11
|
+
* Uses rough approximation: ~4 chars per token for English
|
|
12
|
+
*/
|
|
13
|
+
export function estimateTokens(content) {
|
|
14
|
+
return Math.ceil(content.length / 4);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Estimate total tokens for messages
|
|
18
|
+
*/
|
|
19
|
+
export function estimateTotalTokens(messages) {
|
|
20
|
+
let total = 0;
|
|
21
|
+
for (const msg of messages) {
|
|
22
|
+
if (typeof msg.content === 'string') {
|
|
23
|
+
total += estimateTokens(msg.content);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
for (const block of msg.content) {
|
|
27
|
+
if (block.type === 'text') {
|
|
28
|
+
total += estimateTokens(block.text);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Add overhead for role, etc.
|
|
33
|
+
total += 10;
|
|
34
|
+
}
|
|
35
|
+
return total;
|
|
36
|
+
}
|
|
37
|
+
// ============================================================================
|
|
38
|
+
// Message Extraction
|
|
39
|
+
// ============================================================================
|
|
40
|
+
/**
|
|
41
|
+
* Get text content from a message
|
|
42
|
+
*/
|
|
43
|
+
function getMessageText(msg) {
|
|
44
|
+
if (typeof msg.content === 'string') {
|
|
45
|
+
return msg.content;
|
|
46
|
+
}
|
|
47
|
+
return msg.content
|
|
48
|
+
.filter(b => b.type === 'text')
|
|
49
|
+
.map(b => b.text)
|
|
50
|
+
.join('\n');
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Extract key information from messages
|
|
54
|
+
*/
|
|
55
|
+
export function extractKeyInfo(messages) {
|
|
56
|
+
const topics = [];
|
|
57
|
+
const decisions = [];
|
|
58
|
+
const actions = [];
|
|
59
|
+
const codeChanges = [];
|
|
60
|
+
for (const msg of messages) {
|
|
61
|
+
const text = getMessageText(msg);
|
|
62
|
+
// Extract topics (headers and emphasized text)
|
|
63
|
+
const topicMatches = text.match(/^#+\s+(.+)$/gm) || [];
|
|
64
|
+
topics.push(...topicMatches.map(m => m.replace(/^#+\s+/, '')));
|
|
65
|
+
// Extract decisions (patterns like "decided to", "chose to", etc.)
|
|
66
|
+
const decisionPatterns = [
|
|
67
|
+
/(?:decided|chose|selected|picked|went with)\s+(?:to\s+)?([^.]+)/gi,
|
|
68
|
+
/(?:will|going to)\s+([^.]+)/gi,
|
|
69
|
+
];
|
|
70
|
+
for (const pattern of decisionPatterns) {
|
|
71
|
+
let match;
|
|
72
|
+
while ((match = pattern.exec(text)) !== null) {
|
|
73
|
+
decisions.push(match[1].trim());
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Extract actions (tool uses)
|
|
77
|
+
if (msg.toolCalls) {
|
|
78
|
+
for (const tool of msg.toolCalls) {
|
|
79
|
+
const args = tool.arguments;
|
|
80
|
+
if (tool.name === 'shell') {
|
|
81
|
+
actions.push(`Ran: ${String(args.command || '').slice(0, 50)}`);
|
|
82
|
+
}
|
|
83
|
+
else if (tool.name === 'write_file') {
|
|
84
|
+
codeChanges.push(`Wrote: ${String(args.path || '')}`);
|
|
85
|
+
}
|
|
86
|
+
else if (tool.name === 'read_file') {
|
|
87
|
+
actions.push(`Read: ${String(args.path || '')}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
topics: [...new Set(topics)].slice(0, 10),
|
|
94
|
+
decisions: [...new Set(decisions)].slice(0, 10),
|
|
95
|
+
actions: [...new Set(actions)].slice(0, 10),
|
|
96
|
+
codeChanges: [...new Set(codeChanges)].slice(0, 10),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
// ============================================================================
|
|
100
|
+
// Summarization
|
|
101
|
+
// ============================================================================
|
|
102
|
+
/**
|
|
103
|
+
* Create a summary of messages
|
|
104
|
+
*/
|
|
105
|
+
export function summarizeMessages(messages) {
|
|
106
|
+
const info = extractKeyInfo(messages);
|
|
107
|
+
const parts = [];
|
|
108
|
+
parts.push(`[Summary of ${messages.length} messages]`);
|
|
109
|
+
if (info.topics.length > 0) {
|
|
110
|
+
parts.push(`\nTopics discussed: ${info.topics.join(', ')}`);
|
|
111
|
+
}
|
|
112
|
+
if (info.decisions.length > 0) {
|
|
113
|
+
parts.push(`\nKey decisions:\n- ${info.decisions.join('\n- ')}`);
|
|
114
|
+
}
|
|
115
|
+
if (info.codeChanges.length > 0) {
|
|
116
|
+
parts.push(`\nFiles modified:\n- ${info.codeChanges.join('\n- ')}`);
|
|
117
|
+
}
|
|
118
|
+
if (info.actions.length > 0) {
|
|
119
|
+
parts.push(`\nActions taken:\n- ${info.actions.slice(0, 5).join('\n- ')}`);
|
|
120
|
+
}
|
|
121
|
+
return parts.join('\n');
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Summarize conversation to fit within token limit
|
|
125
|
+
*/
|
|
126
|
+
export function summarizeConversation(messages, options = {}) {
|
|
127
|
+
const opts = {
|
|
128
|
+
maxTokens: options.maxTokens || 100000,
|
|
129
|
+
preserveRecent: options.preserveRecent || 10,
|
|
130
|
+
preserveSystem: options.preserveSystem !== false,
|
|
131
|
+
summaryMaxTokens: options.summaryMaxTokens || 2000,
|
|
132
|
+
};
|
|
133
|
+
const originalTokens = estimateTotalTokens(messages);
|
|
134
|
+
// If already under limit, return as-is
|
|
135
|
+
if (originalTokens <= opts.maxTokens) {
|
|
136
|
+
return {
|
|
137
|
+
messages,
|
|
138
|
+
summarizedCount: 0,
|
|
139
|
+
summary: '',
|
|
140
|
+
originalTokens,
|
|
141
|
+
reducedTokens: originalTokens,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
// Separate messages to keep
|
|
145
|
+
const systemMessages = opts.preserveSystem
|
|
146
|
+
? messages.filter(m => m.role === 'system')
|
|
147
|
+
: [];
|
|
148
|
+
const recentMessages = messages.slice(-opts.preserveRecent);
|
|
149
|
+
const toSummarize = messages.slice(systemMessages.length, -opts.preserveRecent);
|
|
150
|
+
// Create summary
|
|
151
|
+
const summary = summarizeMessages(toSummarize);
|
|
152
|
+
// Build new message list
|
|
153
|
+
const summarizedMessages = [
|
|
154
|
+
...systemMessages,
|
|
155
|
+
{
|
|
156
|
+
role: 'system',
|
|
157
|
+
content: `Previous conversation summary:\n${summary}`,
|
|
158
|
+
},
|
|
159
|
+
...recentMessages,
|
|
160
|
+
];
|
|
161
|
+
const reducedTokens = estimateTotalTokens(summarizedMessages);
|
|
162
|
+
return {
|
|
163
|
+
messages: summarizedMessages,
|
|
164
|
+
summarizedCount: toSummarize.length,
|
|
165
|
+
summary,
|
|
166
|
+
originalTokens,
|
|
167
|
+
reducedTokens,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
// ============================================================================
|
|
171
|
+
// Incremental Summarization
|
|
172
|
+
// ============================================================================
|
|
173
|
+
export class ConversationSummarizer {
|
|
174
|
+
summaries = [];
|
|
175
|
+
currentMessages = [];
|
|
176
|
+
options;
|
|
177
|
+
constructor(options = {}) {
|
|
178
|
+
this.options = {
|
|
179
|
+
maxTokens: options.maxTokens || 50000,
|
|
180
|
+
preserveRecent: options.preserveRecent || 10,
|
|
181
|
+
preserveSystem: options.preserveSystem !== false,
|
|
182
|
+
summaryMaxTokens: options.summaryMaxTokens || 1000,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Add a message
|
|
187
|
+
*/
|
|
188
|
+
addMessage(message) {
|
|
189
|
+
this.currentMessages.push(message);
|
|
190
|
+
this.checkAndSummarize();
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Add multiple messages
|
|
194
|
+
*/
|
|
195
|
+
addMessages(messages) {
|
|
196
|
+
this.currentMessages.push(...messages);
|
|
197
|
+
this.checkAndSummarize();
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Check if summarization is needed
|
|
201
|
+
*/
|
|
202
|
+
checkAndSummarize() {
|
|
203
|
+
const tokens = estimateTotalTokens(this.currentMessages);
|
|
204
|
+
if (tokens > this.options.maxTokens) {
|
|
205
|
+
// Summarize older messages
|
|
206
|
+
const toSummarize = this.currentMessages.slice(0, -this.options.preserveRecent);
|
|
207
|
+
const summary = summarizeMessages(toSummarize);
|
|
208
|
+
this.summaries.push(summary);
|
|
209
|
+
// Keep only recent messages
|
|
210
|
+
this.currentMessages = this.currentMessages.slice(-this.options.preserveRecent);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Get current messages with summaries
|
|
215
|
+
*/
|
|
216
|
+
getMessages() {
|
|
217
|
+
const messages = [];
|
|
218
|
+
// Add summaries as system message
|
|
219
|
+
if (this.summaries.length > 0) {
|
|
220
|
+
messages.push({
|
|
221
|
+
role: 'system',
|
|
222
|
+
content: `Previous conversation summaries:\n\n${this.summaries.join('\n\n---\n\n')}`,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
messages.push(...this.currentMessages);
|
|
226
|
+
return messages;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Get summary count
|
|
230
|
+
*/
|
|
231
|
+
getSummaryCount() {
|
|
232
|
+
return this.summaries.length;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Clear all summaries and messages
|
|
236
|
+
*/
|
|
237
|
+
clear() {
|
|
238
|
+
this.summaries = [];
|
|
239
|
+
this.currentMessages = [];
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
//# sourceMappingURL=summarization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summarization.js","sourceRoot":"","sources":["../src/summarization.ts"],"names":[],"mappings":"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"}
|