@timetotest/cli 0.3.0 → 0.3.2
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 +12 -2
- package/dist/bin/ttt.js +0 -6
- package/dist/bin/ttt.js.map +1 -1
- package/dist/package.json +2 -1
- package/dist/src/commands/chat/ChatApp.js +102 -61
- package/dist/src/commands/chat/ChatApp.js.map +1 -1
- package/dist/src/commands/chat/OnboardingApp.js +49 -0
- package/dist/src/commands/chat/OnboardingApp.js.map +1 -0
- package/dist/src/commands/chat/components/Banner.js +1 -1
- package/dist/src/commands/chat/components/Banner.js.map +1 -1
- package/dist/src/commands/chat/components/ChatInput.js +16 -3
- package/dist/src/commands/chat/components/ChatInput.js.map +1 -1
- package/dist/src/commands/chat/components/TodoPanel.js +71 -0
- package/dist/src/commands/chat/components/TodoPanel.js.map +1 -0
- package/dist/src/commands/chat-ink.js +116 -292
- package/dist/src/commands/chat-ink.js.map +1 -1
- package/dist/src/lib/__tests__/code-mode-integration.test.js +45 -356
- package/dist/src/lib/__tests__/code-mode-integration.test.js.map +1 -1
- package/dist/src/lib/__tests__/tool-executor-mode-gating.test.js +46 -0
- package/dist/src/lib/__tests__/tool-executor-mode-gating.test.js.map +1 -0
- package/dist/src/lib/__tests__/ui-browser-integration.test.js +35 -0
- package/dist/src/lib/__tests__/ui-browser-integration.test.js.map +1 -0
- package/dist/src/lib/agent-orchestrator.js +16 -717
- package/dist/src/lib/agent-orchestrator.js.map +1 -1
- package/dist/src/lib/backend-loop-client.js +364 -0
- package/dist/src/lib/backend-loop-client.js.map +1 -0
- package/dist/src/lib/cli-tool-manifest.js +71 -0
- package/dist/src/lib/cli-tool-manifest.js.map +1 -0
- package/dist/src/lib/config.js +60 -9
- package/dist/src/lib/config.js.map +1 -1
- package/dist/src/lib/conversation/turns.js +58 -0
- package/dist/src/lib/conversation/turns.js.map +1 -0
- package/dist/src/lib/events.js +20 -4
- package/dist/src/lib/events.js.map +1 -1
- package/dist/src/lib/http.js +7 -2
- package/dist/src/lib/http.js.map +1 -1
- package/dist/src/lib/prompts/templates.js +18 -0
- package/dist/src/lib/prompts/templates.js.map +1 -1
- package/dist/src/lib/session-manager.js +74 -33
- package/dist/src/lib/session-manager.js.map +1 -1
- package/dist/src/lib/socket.js +15 -3
- package/dist/src/lib/socket.js.map +1 -1
- package/dist/src/lib/todo.js +7 -0
- package/dist/src/lib/todo.js.map +1 -0
- package/dist/src/lib/tool-executor.js +196 -51
- package/dist/src/lib/tool-executor.js.map +1 -1
- package/dist/src/lib/tui/events.js +10 -9
- package/dist/src/lib/tui/events.js.map +1 -1
- package/dist/src/lib/utils/json.js +15 -0
- package/dist/src/lib/utils/json.js.map +1 -0
- package/package.json +2 -1
- package/dist/src/commands/report.js +0 -25
- package/dist/src/commands/report.js.map +0 -1
- package/dist/src/commands/restart.js +0 -17
- package/dist/src/commands/restart.js.map +0 -1
- package/dist/src/commands/share.js +0 -18
- package/dist/src/commands/share.js.map +0 -1
- package/dist/src/lib/context-compactor.js +0 -310
- package/dist/src/lib/context-compactor.js.map +0 -1
- package/dist/src/lib/tool-registry.js +0 -971
- package/dist/src/lib/tool-registry.js.map +0 -1
- package/dist/src/lib/tool-result-pruner.js +0 -384
- package/dist/src/lib/tool-result-pruner.js.map +0 -1
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import fs from 'fs-extra';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import { createHttpClient } from '../lib/http.js';
|
|
5
|
-
export const report = new Command('report')
|
|
6
|
-
.description('Create and download a PDF report for a test')
|
|
7
|
-
.argument('<test-id>')
|
|
8
|
-
.option('--out <file>', 'Output PDF path', '')
|
|
9
|
-
.action(async (testId, opts) => {
|
|
10
|
-
try {
|
|
11
|
-
const http = createHttpClient();
|
|
12
|
-
const createResp = await http.post('/api/v1/reports/', { test_id: testId });
|
|
13
|
-
const reportId = createResp.data?.id || createResp.data?.report_id;
|
|
14
|
-
const pdfResp = await http.get(`/api/v1/reports/${reportId}/pdf`, { responseType: 'arraybuffer' });
|
|
15
|
-
const outPath = opts.out ? String(opts.out) : path.resolve(process.cwd(), `report-${testId}.pdf`);
|
|
16
|
-
await fs.ensureDir(path.dirname(outPath));
|
|
17
|
-
await fs.writeFile(outPath, pdfResp.data);
|
|
18
|
-
console.log('Saved:', outPath);
|
|
19
|
-
}
|
|
20
|
-
catch (err) {
|
|
21
|
-
console.error(err?.response?.data || err?.message || err);
|
|
22
|
-
process.exitCode = 1;
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
//# sourceMappingURL=report.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../../src/commands/report.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KACxC,WAAW,CAAC,6CAA6C,CAAC;KAC1D,QAAQ,CAAC,WAAW,CAAC;KACrB,MAAM,CAAC,cAAc,EAAE,iBAAiB,EAAE,EAAE,CAAC;KAC7C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;IAC7B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC;QAChC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAC5E,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,EAAE,EAAE,IAAI,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC;QACnE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,mBAAmB,QAAQ,MAAM,EAAE,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC,CAAC;QACnG,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,MAAM,MAAM,CAAC,CAAC;QAClG,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QAC1C,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,IAAI,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC,CAAC;QAC1D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import { createHttpClient } from '../lib/http.js';
|
|
3
|
-
export const restart = new Command('restart')
|
|
4
|
-
.description('Restart a test by ID')
|
|
5
|
-
.argument('<test-id>')
|
|
6
|
-
.action(async (testId) => {
|
|
7
|
-
try {
|
|
8
|
-
const http = createHttpClient();
|
|
9
|
-
const resp = await http.post(`/api/v1/tests/${encodeURIComponent(testId)}/restart`);
|
|
10
|
-
console.log(JSON.stringify(resp.data, null, 2));
|
|
11
|
-
}
|
|
12
|
-
catch (err) {
|
|
13
|
-
console.error(err?.response?.data || err?.message || err);
|
|
14
|
-
process.exitCode = 1;
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
//# sourceMappingURL=restart.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"restart.js","sourceRoot":"","sources":["../../../src/commands/restart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC;KAC1C,WAAW,CAAC,sBAAsB,CAAC;KACnC,QAAQ,CAAC,WAAW,CAAC;KACrB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;IACvB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,iBAAiB,kBAAkB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACpF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,IAAI,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC,CAAC;QAC1D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import { createHttpClient } from '../lib/http.js';
|
|
3
|
-
export const share = new Command('share')
|
|
4
|
-
.description('Enable public sharing for a test and print the public URL')
|
|
5
|
-
.argument('<test-id>')
|
|
6
|
-
.action(async (testId) => {
|
|
7
|
-
try {
|
|
8
|
-
const http = createHttpClient();
|
|
9
|
-
const resp = await http.post(`/api/v1/tests/${encodeURIComponent(testId)}/share`);
|
|
10
|
-
const url = resp.data?.url || resp.data?.public_url || JSON.stringify(resp.data);
|
|
11
|
-
console.log(url);
|
|
12
|
-
}
|
|
13
|
-
catch (err) {
|
|
14
|
-
console.error(err?.response?.data || err?.message || err);
|
|
15
|
-
process.exitCode = 1;
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
//# sourceMappingURL=share.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"share.js","sourceRoot":"","sources":["../../../src/commands/share.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,CAAC,MAAM,KAAK,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KACtC,WAAW,CAAC,2DAA2D,CAAC;KACxE,QAAQ,CAAC,WAAW,CAAC;KACrB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;IACvB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,iBAAiB,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAClF,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,UAAU,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjF,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,IAAI,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC,CAAC;QAC1D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -1,310 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Context Compactor - Industry-standard conversation history management
|
|
3
|
-
*
|
|
4
|
-
* Features:
|
|
5
|
-
* - Accurate token counting using tiktoken
|
|
6
|
-
* - Conversation turn preservation (keeps user-assistant pairs intact)
|
|
7
|
-
* - LLM-based summarization for old context
|
|
8
|
-
* - Importance scoring to preserve critical messages
|
|
9
|
-
* - Tool result preservation for recent tools
|
|
10
|
-
*/
|
|
11
|
-
import { encoding_for_model } from "tiktoken";
|
|
12
|
-
export class ContextCompactor {
|
|
13
|
-
config;
|
|
14
|
-
encoder = null;
|
|
15
|
-
constructor(config) {
|
|
16
|
-
this.config = {
|
|
17
|
-
maxTokens: config?.maxTokens ?? 200000,
|
|
18
|
-
targetTokens: config?.targetTokens ?? 150000,
|
|
19
|
-
preserveRecentTurns: config?.preserveRecentTurns ?? 10,
|
|
20
|
-
preserveRecentTools: config?.preserveRecentTools ?? 5,
|
|
21
|
-
enableSummarization: config?.enableSummarization ?? true,
|
|
22
|
-
model: config?.model ?? "gpt-4",
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Get or initialize tokenizer
|
|
27
|
-
*/
|
|
28
|
-
getEncoder() {
|
|
29
|
-
if (!this.encoder) {
|
|
30
|
-
try {
|
|
31
|
-
this.encoder = encoding_for_model(this.config.model);
|
|
32
|
-
}
|
|
33
|
-
catch {
|
|
34
|
-
// Fallback to cl100k_base (GPT-4/GPT-3.5-turbo)
|
|
35
|
-
this.encoder = encoding_for_model("gpt-4");
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return this.encoder;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Accurate token counting using tiktoken
|
|
42
|
-
*/
|
|
43
|
-
countTokens(messages) {
|
|
44
|
-
const encoder = this.getEncoder();
|
|
45
|
-
let totalTokens = 0;
|
|
46
|
-
for (const msg of messages) {
|
|
47
|
-
// Count role tokens
|
|
48
|
-
totalTokens += 4; // Every message has role overhead
|
|
49
|
-
// Count content tokens
|
|
50
|
-
if (typeof msg.content === "string") {
|
|
51
|
-
totalTokens += encoder.encode(msg.content).length;
|
|
52
|
-
}
|
|
53
|
-
else if (Array.isArray(msg.content)) {
|
|
54
|
-
totalTokens += encoder.encode(JSON.stringify(msg.content)).length;
|
|
55
|
-
}
|
|
56
|
-
// Count tool call tokens
|
|
57
|
-
if (msg.toolCalls) {
|
|
58
|
-
totalTokens += encoder.encode(JSON.stringify(msg.toolCalls)).length;
|
|
59
|
-
}
|
|
60
|
-
// Count metadata tokens
|
|
61
|
-
if (msg.metadata) {
|
|
62
|
-
totalTokens += encoder.encode(JSON.stringify(msg.metadata)).length;
|
|
63
|
-
}
|
|
64
|
-
// Count name/tool_call_id
|
|
65
|
-
if (msg.toolCall) {
|
|
66
|
-
totalTokens += encoder.encode(JSON.stringify(msg.toolCall)).length;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
// Add overhead for message formatting
|
|
70
|
-
totalTokens += 3; // Every reply is primed with assistant
|
|
71
|
-
return totalTokens;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Check if compaction is needed
|
|
75
|
-
*/
|
|
76
|
-
needsCompaction(messages) {
|
|
77
|
-
const tokens = this.countTokens(messages);
|
|
78
|
-
return tokens >= this.config.maxTokens;
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Group messages into conversation turns
|
|
82
|
-
* A turn = user message + assistant response + any tool calls
|
|
83
|
-
*/
|
|
84
|
-
groupIntoTurns(messages) {
|
|
85
|
-
const turns = [];
|
|
86
|
-
let i = 0;
|
|
87
|
-
while (i < messages.length) {
|
|
88
|
-
const msg = messages[i];
|
|
89
|
-
// Skip system messages (they're not part of turns)
|
|
90
|
-
if (msg.role === "system") {
|
|
91
|
-
i++;
|
|
92
|
-
continue;
|
|
93
|
-
}
|
|
94
|
-
// Start of a turn (user message)
|
|
95
|
-
if (msg.role === "user") {
|
|
96
|
-
const turn = {
|
|
97
|
-
userMessage: msg,
|
|
98
|
-
toolMessages: [],
|
|
99
|
-
startIndex: i,
|
|
100
|
-
endIndex: i,
|
|
101
|
-
tokens: 0,
|
|
102
|
-
importance: 0,
|
|
103
|
-
};
|
|
104
|
-
i++;
|
|
105
|
-
// Collect assistant response
|
|
106
|
-
if (i < messages.length && messages[i].role === "assistant") {
|
|
107
|
-
turn.assistantMessage = messages[i];
|
|
108
|
-
turn.endIndex = i;
|
|
109
|
-
i++;
|
|
110
|
-
}
|
|
111
|
-
// Collect tool messages
|
|
112
|
-
while (i < messages.length && messages[i].role === "tool") {
|
|
113
|
-
turn.toolMessages.push(messages[i]);
|
|
114
|
-
turn.endIndex = i;
|
|
115
|
-
i++;
|
|
116
|
-
}
|
|
117
|
-
// Calculate tokens for this turn
|
|
118
|
-
const turnMessages = messages.slice(turn.startIndex, turn.endIndex + 1);
|
|
119
|
-
turn.tokens = this.countTokens(turnMessages);
|
|
120
|
-
// Calculate importance score
|
|
121
|
-
turn.importance = this.calculateImportance(turn);
|
|
122
|
-
turns.push(turn);
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
// Orphaned message (shouldn't happen but handle gracefully)
|
|
126
|
-
i++;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return turns;
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Calculate importance score for a conversation turn
|
|
133
|
-
* Higher score = more important to preserve
|
|
134
|
-
*/
|
|
135
|
-
calculateImportance(turn) {
|
|
136
|
-
let score = 1.0; // Base score
|
|
137
|
-
// Boost if contains errors
|
|
138
|
-
const hasError = turn.assistantMessage?.content
|
|
139
|
-
?.toString()
|
|
140
|
-
.toLowerCase()
|
|
141
|
-
.includes("error") ||
|
|
142
|
-
turn.toolMessages.some((t) => t.content?.toString().toLowerCase().includes("error"));
|
|
143
|
-
if (hasError)
|
|
144
|
-
score += 2.0;
|
|
145
|
-
// Boost if user corrected the agent
|
|
146
|
-
const hasCorrection = turn.userMessage.content
|
|
147
|
-
?.toString()
|
|
148
|
-
.toLowerCase()
|
|
149
|
-
.match(/no|wrong|incorrect|actually|fix|correct/);
|
|
150
|
-
if (hasCorrection)
|
|
151
|
-
score += 1.5;
|
|
152
|
-
// Boost if contains important tool calls
|
|
153
|
-
const importantTools = ["run_command", "write_file", "delete_file"];
|
|
154
|
-
const hasImportantTool = turn.toolMessages.some((t) => importantTools.includes(t.toolCall?.name || ""));
|
|
155
|
-
if (hasImportantTool)
|
|
156
|
-
score += 1.0;
|
|
157
|
-
// Penalize very long tool results (likely verbose output)
|
|
158
|
-
const hasLongToolResult = turn.toolMessages.some((t) => (t.content?.toString().length || 0) > 5000);
|
|
159
|
-
if (hasLongToolResult)
|
|
160
|
-
score -= 0.5;
|
|
161
|
-
return Math.max(0, score);
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Main compaction method
|
|
165
|
-
*/
|
|
166
|
-
async compact(messages, httpClient) {
|
|
167
|
-
const tokensBeforeCompaction = this.countTokens(messages);
|
|
168
|
-
if (tokensBeforeCompaction < this.config.maxTokens) {
|
|
169
|
-
return {
|
|
170
|
-
compactedMessages: messages,
|
|
171
|
-
removedCount: 0,
|
|
172
|
-
tokensBeforeCompaction,
|
|
173
|
-
tokensAfterCompaction: tokensBeforeCompaction,
|
|
174
|
-
strategy: "none",
|
|
175
|
-
summaryGenerated: false,
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
// Separate system messages from conversation
|
|
179
|
-
const systemMessages = messages.filter((m) => m.role === "system");
|
|
180
|
-
const conversationMessages = messages.filter((m) => m.role !== "system");
|
|
181
|
-
// Group into turns
|
|
182
|
-
const turns = this.groupIntoTurns(conversationMessages);
|
|
183
|
-
// Keep recent turns
|
|
184
|
-
const recentTurns = turns.slice(-this.config.preserveRecentTurns);
|
|
185
|
-
const oldTurns = turns.slice(0, -this.config.preserveRecentTurns);
|
|
186
|
-
// Extract recent messages
|
|
187
|
-
const recentMessages = [];
|
|
188
|
-
for (const turn of recentTurns) {
|
|
189
|
-
recentMessages.push(...conversationMessages.slice(turn.startIndex, turn.endIndex + 1));
|
|
190
|
-
}
|
|
191
|
-
// Preserve recent tool results
|
|
192
|
-
const recentToolMessages = recentMessages.filter((m) => m.role === "tool");
|
|
193
|
-
const toolsToPreserve = recentToolMessages.slice(-this.config.preserveRecentTools);
|
|
194
|
-
let compactedMessages;
|
|
195
|
-
let summaryGenerated = false;
|
|
196
|
-
if (this.config.enableSummarization && oldTurns.length > 0 && httpClient) {
|
|
197
|
-
// Generate LLM summary of old context
|
|
198
|
-
const summary = await this.generateSummary(oldTurns, httpClient);
|
|
199
|
-
summaryGenerated = true;
|
|
200
|
-
compactedMessages = [
|
|
201
|
-
...systemMessages,
|
|
202
|
-
{
|
|
203
|
-
role: "system",
|
|
204
|
-
content: summary,
|
|
205
|
-
timestamp: Date.now(),
|
|
206
|
-
metadata: {
|
|
207
|
-
type: "conversation_summary",
|
|
208
|
-
turns_summarized: oldTurns.length,
|
|
209
|
-
tokens_before: this.countTokens(conversationMessages.slice(0, oldTurns[oldTurns.length - 1].endIndex + 1)),
|
|
210
|
-
},
|
|
211
|
-
},
|
|
212
|
-
...recentMessages,
|
|
213
|
-
];
|
|
214
|
-
}
|
|
215
|
-
else {
|
|
216
|
-
// Fallback: Keep high-importance turns from old context
|
|
217
|
-
const importantOldTurns = oldTurns
|
|
218
|
-
.sort((a, b) => b.importance - a.importance)
|
|
219
|
-
.slice(0, 3); // Keep top 3 important turns
|
|
220
|
-
const importantMessages = [];
|
|
221
|
-
for (const turn of importantOldTurns) {
|
|
222
|
-
importantMessages.push(...conversationMessages.slice(turn.startIndex, turn.endIndex + 1));
|
|
223
|
-
}
|
|
224
|
-
compactedMessages = [
|
|
225
|
-
...systemMessages,
|
|
226
|
-
{
|
|
227
|
-
role: "system",
|
|
228
|
-
content: `[Earlier conversation: ${oldTurns.length} turns compacted. Preserved ${importantOldTurns.length} important turns.]`,
|
|
229
|
-
timestamp: Date.now(),
|
|
230
|
-
metadata: {
|
|
231
|
-
type: "compaction_marker",
|
|
232
|
-
turns_removed: oldTurns.length - importantOldTurns.length,
|
|
233
|
-
},
|
|
234
|
-
},
|
|
235
|
-
...importantMessages,
|
|
236
|
-
...recentMessages,
|
|
237
|
-
];
|
|
238
|
-
}
|
|
239
|
-
const tokensAfterCompaction = this.countTokens(compactedMessages);
|
|
240
|
-
return {
|
|
241
|
-
compactedMessages,
|
|
242
|
-
removedCount: messages.length - compactedMessages.length,
|
|
243
|
-
tokensBeforeCompaction,
|
|
244
|
-
tokensAfterCompaction,
|
|
245
|
-
strategy: summaryGenerated ? "llm-summarization" : "importance-based",
|
|
246
|
-
summaryGenerated,
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* Generate LLM summary of old conversation turns
|
|
251
|
-
*/
|
|
252
|
-
async generateSummary(turns, httpClient) {
|
|
253
|
-
// Build a concise representation of the turns
|
|
254
|
-
const turnSummaries = turns.map((turn, idx) => {
|
|
255
|
-
const userContent = typeof turn.userMessage.content === "string"
|
|
256
|
-
? turn.userMessage.content
|
|
257
|
-
: JSON.stringify(turn.userMessage.content);
|
|
258
|
-
const assistantContent = turn.assistantMessage
|
|
259
|
-
? typeof turn.assistantMessage.content === "string"
|
|
260
|
-
? turn.assistantMessage.content
|
|
261
|
-
: JSON.stringify(turn.assistantMessage.content)
|
|
262
|
-
: "[No response]";
|
|
263
|
-
const toolsUsed = turn.toolMessages
|
|
264
|
-
.map((t) => t.toolCall?.name)
|
|
265
|
-
.filter(Boolean)
|
|
266
|
-
.join(", ");
|
|
267
|
-
return `Turn ${idx + 1}:\nUser: ${userContent.substring(0, 200)}${userContent.length > 200 ? "..." : ""}\nAssistant: ${assistantContent.substring(0, 200)}${assistantContent.length > 200 ? "..." : ""}${toolsUsed ? `\nTools: ${toolsUsed}` : ""}`;
|
|
268
|
-
});
|
|
269
|
-
const conversationText = turnSummaries.join("\n\n");
|
|
270
|
-
try {
|
|
271
|
-
// Call backend to generate summary
|
|
272
|
-
const response = await httpClient.post("/api/v1/ai/agent/summarize", {
|
|
273
|
-
conversation: conversationText,
|
|
274
|
-
max_tokens: 500,
|
|
275
|
-
});
|
|
276
|
-
return (response.data?.summary ||
|
|
277
|
-
`[Summary of ${turns.length} conversation turns]`);
|
|
278
|
-
}
|
|
279
|
-
catch (error) {
|
|
280
|
-
// Fallback to simple summary if API fails
|
|
281
|
-
const userMessages = turns.length;
|
|
282
|
-
const toolCalls = turns.reduce((sum, t) => sum + t.toolMessages.length, 0);
|
|
283
|
-
return `[Earlier conversation: ${userMessages} user messages, ${toolCalls} tool executions. Context preserved for continuity.]`;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
/**
|
|
287
|
-
* Get compaction statistics
|
|
288
|
-
*/
|
|
289
|
-
getStats(messages) {
|
|
290
|
-
const tokens = this.countTokens(messages);
|
|
291
|
-
const turns = this.groupIntoTurns(messages.filter((m) => m.role !== "system"));
|
|
292
|
-
return {
|
|
293
|
-
totalMessages: messages.length,
|
|
294
|
-
tokens,
|
|
295
|
-
needsCompaction: tokens >= this.config.maxTokens,
|
|
296
|
-
utilizationPercent: (tokens / this.config.maxTokens) * 100,
|
|
297
|
-
conversationTurns: turns.length,
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
|
-
/**
|
|
301
|
-
* Clean up tokenizer
|
|
302
|
-
*/
|
|
303
|
-
dispose() {
|
|
304
|
-
if (this.encoder) {
|
|
305
|
-
this.encoder.free();
|
|
306
|
-
this.encoder = null;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
//# sourceMappingURL=context-compactor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context-compactor.js","sourceRoot":"","sources":["../../../src/lib/context-compactor.ts"],"names":[],"mappings":"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"}
|