@loxia-labs/loxia-autopilot-one 1.0.1 → 1.0.4
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 +44 -54
- package/bin/cli.js +1 -115
- package/bin/loxia-terminal-v2.js +3 -0
- package/bin/loxia-terminal.js +3 -0
- package/bin/start-with-terminal.js +3 -0
- package/package.json +15 -15
- package/scripts/install-scanners.js +1 -235
- package/src/analyzers/CSSAnalyzer.js +1 -297
- package/src/analyzers/ConfigValidator.js +1 -690
- package/src/analyzers/ESLintAnalyzer.js +1 -320
- package/src/analyzers/JavaScriptAnalyzer.js +1 -261
- package/src/analyzers/PrettierFormatter.js +1 -247
- package/src/analyzers/PythonAnalyzer.js +1 -266
- package/src/analyzers/SecurityAnalyzer.js +1 -729
- package/src/analyzers/TypeScriptAnalyzer.js +1 -247
- package/src/analyzers/codeCloneDetector/analyzer.js +1 -344
- package/src/analyzers/codeCloneDetector/detector.js +1 -203
- package/src/analyzers/codeCloneDetector/index.js +1 -160
- package/src/analyzers/codeCloneDetector/parser.js +1 -199
- package/src/analyzers/codeCloneDetector/reporter.js +1 -148
- package/src/analyzers/codeCloneDetector/scanner.js +1 -59
- package/src/core/agentPool.js +1 -1474
- package/src/core/agentScheduler.js +1 -2147
- package/src/core/contextManager.js +1 -709
- package/src/core/messageProcessor.js +1 -732
- package/src/core/orchestrator.js +1 -548
- package/src/core/stateManager.js +1 -877
- package/src/index.js +1 -631
- package/src/interfaces/cli.js +1 -549
- package/src/interfaces/terminal/__tests__/smoke/advancedFeatures.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/agentControl.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/agents.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/components.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/connection.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/enhancements.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/imports.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/messages.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/tools.test.js +1 -0
- package/src/interfaces/terminal/api/apiClient.js +1 -0
- package/src/interfaces/terminal/api/messageRouter.js +1 -0
- package/src/interfaces/terminal/api/session.js +1 -0
- package/src/interfaces/terminal/api/websocket.js +1 -0
- package/src/interfaces/terminal/components/AgentCreator.js +1 -0
- package/src/interfaces/terminal/components/AgentEditor.js +1 -0
- package/src/interfaces/terminal/components/AgentSwitcher.js +1 -0
- package/src/interfaces/terminal/components/ErrorBoundary.js +1 -0
- package/src/interfaces/terminal/components/ErrorPanel.js +1 -0
- package/src/interfaces/terminal/components/Header.js +1 -0
- package/src/interfaces/terminal/components/HelpPanel.js +1 -0
- package/src/interfaces/terminal/components/InputBox.js +1 -0
- package/src/interfaces/terminal/components/Layout.js +1 -0
- package/src/interfaces/terminal/components/LoadingSpinner.js +1 -0
- package/src/interfaces/terminal/components/MessageList.js +1 -0
- package/src/interfaces/terminal/components/MultilineTextInput.js +1 -0
- package/src/interfaces/terminal/components/SearchPanel.js +1 -0
- package/src/interfaces/terminal/components/SettingsPanel.js +1 -0
- package/src/interfaces/terminal/components/StatusBar.js +1 -0
- package/src/interfaces/terminal/components/TextInput.js +1 -0
- package/src/interfaces/terminal/config/agentEditorConstants.js +1 -0
- package/src/interfaces/terminal/config/constants.js +1 -0
- package/src/interfaces/terminal/index.js +1 -0
- package/src/interfaces/terminal/state/useAgentControl.js +1 -0
- package/src/interfaces/terminal/state/useAgents.js +1 -0
- package/src/interfaces/terminal/state/useConnection.js +1 -0
- package/src/interfaces/terminal/state/useMessages.js +1 -0
- package/src/interfaces/terminal/state/useTools.js +1 -0
- package/src/interfaces/terminal/utils/debugLogger.js +1 -0
- package/src/interfaces/terminal/utils/settingsStorage.js +1 -0
- package/src/interfaces/terminal/utils/theme.js +1 -0
- package/src/interfaces/webServer.js +1 -2162
- package/src/modules/fileExplorer/controller.js +1 -280
- package/src/modules/fileExplorer/index.js +1 -37
- package/src/modules/fileExplorer/middleware.js +1 -92
- package/src/modules/fileExplorer/routes.js +1 -125
- package/src/modules/fileExplorer/types.js +1 -44
- package/src/services/aiService.js +1 -1232
- package/src/services/apiKeyManager.js +1 -164
- package/src/services/benchmarkService.js +1 -366
- package/src/services/budgetService.js +1 -539
- package/src/services/contextInjectionService.js +1 -247
- package/src/services/conversationCompactionService.js +1 -637
- package/src/services/errorHandler.js +1 -810
- package/src/services/fileAttachmentService.js +1 -544
- package/src/services/modelRouterService.js +1 -366
- package/src/services/modelsService.js +1 -322
- package/src/services/qualityInspector.js +1 -796
- package/src/services/tokenCountingService.js +1 -536
- package/src/tools/agentCommunicationTool.js +1 -1344
- package/src/tools/agentDelayTool.js +1 -485
- package/src/tools/asyncToolManager.js +1 -604
- package/src/tools/baseTool.js +1 -800
- package/src/tools/browserTool.js +1 -920
- package/src/tools/cloneDetectionTool.js +1 -621
- package/src/tools/dependencyResolverTool.js +1 -1215
- package/src/tools/fileContentReplaceTool.js +1 -875
- package/src/tools/fileSystemTool.js +1 -1107
- package/src/tools/fileTreeTool.js +1 -853
- package/src/tools/imageTool.js +1 -901
- package/src/tools/importAnalyzerTool.js +1 -1060
- package/src/tools/jobDoneTool.js +1 -248
- package/src/tools/seekTool.js +1 -956
- package/src/tools/staticAnalysisTool.js +1 -1778
- package/src/tools/taskManagerTool.js +1 -2873
- package/src/tools/terminalTool.js +1 -2304
- package/src/tools/webTool.js +1 -1430
- package/src/types/agent.js +1 -519
- package/src/types/contextReference.js +1 -972
- package/src/types/conversation.js +1 -730
- package/src/types/toolCommand.js +1 -747
- package/src/utilities/attachmentValidator.js +1 -292
- package/src/utilities/configManager.js +1 -582
- package/src/utilities/constants.js +1 -722
- package/src/utilities/directoryAccessManager.js +1 -535
- package/src/utilities/fileProcessor.js +1 -307
- package/src/utilities/logger.js +1 -436
- package/src/utilities/tagParser.js +1 -1246
- package/src/utilities/toolConstants.js +1 -317
- package/web-ui/build/index.html +2 -2
- package/web-ui/build/static/{index-Dy2bYbOa.css → index-CClD1090.css} +1 -1
- package/web-ui/build/static/{index-CjkkcnFA.js → index-lCBai6dX.js} +66 -67
|
@@ -1,637 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ConversationCompactionService - Intelligent conversation compactization
|
|
3
|
-
*
|
|
4
|
-
* Purpose:
|
|
5
|
-
* - Compress long conversations while preserving critical information
|
|
6
|
-
* - Support multiple compaction strategies
|
|
7
|
-
* - Maintain conversation continuity and context
|
|
8
|
-
* - Enable agents to perform long-running tasks
|
|
9
|
-
*
|
|
10
|
-
* Strategies:
|
|
11
|
-
* 1. Summarization - AI-based intelligent summary (sandwich approach)
|
|
12
|
-
* 2. Truncation - Fast extraction for model switching
|
|
13
|
-
* 3. Aggressive - More aggressive summarization for retry scenarios
|
|
14
|
-
*
|
|
15
|
-
* Key Features:
|
|
16
|
-
* - Token-aware segment identification
|
|
17
|
-
* - Preservation guidelines (high/medium/low priority)
|
|
18
|
-
* - Quality validation
|
|
19
|
-
* - Model switching support
|
|
20
|
-
* - Comprehensive metadata tracking
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
import {
|
|
24
|
-
COMPACTION_CONFIG,
|
|
25
|
-
COMPACTION_STRATEGIES,
|
|
26
|
-
TOKEN_COUNTING_MODES,
|
|
27
|
-
} from '../utilities/constants.js';
|
|
28
|
-
|
|
29
|
-
class ConversationCompactionService {
|
|
30
|
-
constructor(tokenCountingService, aiService, logger) {
|
|
31
|
-
this.tokenCountingService = tokenCountingService;
|
|
32
|
-
this.aiService = aiService;
|
|
33
|
-
this.logger = logger;
|
|
34
|
-
|
|
35
|
-
// Summary generation prompt template
|
|
36
|
-
this.summaryPromptTemplate = this._createSummaryPromptTemplate();
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Main compaction entry point - determines strategy and executes
|
|
41
|
-
* @param {Array} messages - Original messages array
|
|
42
|
-
* @param {string} currentModel - Current model being used
|
|
43
|
-
* @param {string} targetModel - Target model (may differ if switching)
|
|
44
|
-
* @param {Object} options - Compaction options
|
|
45
|
-
* @returns {Promise<Object>} Compaction result with messages and metadata
|
|
46
|
-
*/
|
|
47
|
-
async compactConversation(messages, currentModel, targetModel, options = {}) {
|
|
48
|
-
const startTime = Date.now();
|
|
49
|
-
|
|
50
|
-
try {
|
|
51
|
-
// Validate inputs
|
|
52
|
-
if (!Array.isArray(messages) || messages.length === 0) {
|
|
53
|
-
throw new Error('Messages array is required and cannot be empty');
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (messages.length < COMPACTION_CONFIG.MIN_MESSAGES_FOR_COMPACTION) {
|
|
57
|
-
this.logger.warn('Too few messages for compaction', {
|
|
58
|
-
messageCount: messages.length,
|
|
59
|
-
minimum: COMPACTION_CONFIG.MIN_MESSAGES_FOR_COMPACTION
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
return {
|
|
63
|
-
compactedMessages: messages,
|
|
64
|
-
strategy: 'none',
|
|
65
|
-
originalTokenCount: 0,
|
|
66
|
-
compactedTokenCount: 0,
|
|
67
|
-
reductionPercent: 0,
|
|
68
|
-
skipped: true,
|
|
69
|
-
reason: 'Too few messages'
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Determine strategy
|
|
74
|
-
const isModelSwitch = currentModel !== targetModel;
|
|
75
|
-
const isRetry = options.isRetry || false;
|
|
76
|
-
|
|
77
|
-
let strategy;
|
|
78
|
-
if (isModelSwitch) {
|
|
79
|
-
strategy = COMPACTION_STRATEGIES.TRUNCATION;
|
|
80
|
-
} else if (isRetry) {
|
|
81
|
-
strategy = COMPACTION_STRATEGIES.AGGRESSIVE;
|
|
82
|
-
} else {
|
|
83
|
-
strategy = options.strategy || COMPACTION_STRATEGIES.SUMMARIZATION;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
this.logger.info('Starting conversation compaction', {
|
|
87
|
-
messageCount: messages.length,
|
|
88
|
-
currentModel,
|
|
89
|
-
targetModel,
|
|
90
|
-
strategy,
|
|
91
|
-
isModelSwitch,
|
|
92
|
-
isRetry
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
// Execute strategy
|
|
96
|
-
let result;
|
|
97
|
-
switch (strategy) {
|
|
98
|
-
case COMPACTION_STRATEGIES.SUMMARIZATION:
|
|
99
|
-
result = await this._compactWithSummarization(messages, currentModel, options);
|
|
100
|
-
break;
|
|
101
|
-
|
|
102
|
-
case COMPACTION_STRATEGIES.TRUNCATION:
|
|
103
|
-
result = await this._compactWithTruncation(messages, targetModel, options);
|
|
104
|
-
break;
|
|
105
|
-
|
|
106
|
-
case COMPACTION_STRATEGIES.AGGRESSIVE:
|
|
107
|
-
result = await this._compactWithAggressiveSummarization(messages, currentModel, options);
|
|
108
|
-
break;
|
|
109
|
-
|
|
110
|
-
default:
|
|
111
|
-
throw new Error(`Unknown compaction strategy: ${strategy}`);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Add execution metadata
|
|
115
|
-
const executionTime = Date.now() - startTime;
|
|
116
|
-
result.executionTime = executionTime;
|
|
117
|
-
result.timestamp = new Date().toISOString();
|
|
118
|
-
|
|
119
|
-
this.logger.info('Compaction completed successfully', {
|
|
120
|
-
strategy: result.strategy,
|
|
121
|
-
originalMessages: messages.length,
|
|
122
|
-
compactedMessages: result.compactedMessages.length,
|
|
123
|
-
originalTokens: result.originalTokenCount,
|
|
124
|
-
compactedTokens: result.compactedTokenCount,
|
|
125
|
-
reductionPercent: result.reductionPercent.toFixed(2),
|
|
126
|
-
executionTime: `${executionTime}ms`
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
return result;
|
|
130
|
-
|
|
131
|
-
} catch (error) {
|
|
132
|
-
const executionTime = Date.now() - startTime;
|
|
133
|
-
|
|
134
|
-
this.logger.error('Compaction failed', {
|
|
135
|
-
error: error.message,
|
|
136
|
-
messageCount: messages.length,
|
|
137
|
-
currentModel,
|
|
138
|
-
targetModel,
|
|
139
|
-
executionTime: `${executionTime}ms`
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
throw error;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Strategy 1: Intelligent summarization with sandwich approach
|
|
148
|
-
* Preserves beginning (15%) + AI summary of middle + end (35%)
|
|
149
|
-
* @private
|
|
150
|
-
*/
|
|
151
|
-
async _compactWithSummarization(messages, model, options) {
|
|
152
|
-
const strategy = COMPACTION_STRATEGIES.SUMMARIZATION;
|
|
153
|
-
|
|
154
|
-
// Count tokens in original conversation
|
|
155
|
-
const originalTokenCount = await this.tokenCountingService.estimateConversationTokens(
|
|
156
|
-
messages,
|
|
157
|
-
model,
|
|
158
|
-
TOKEN_COUNTING_MODES.ACCURATE
|
|
159
|
-
);
|
|
160
|
-
|
|
161
|
-
// Identify segments using token-based boundaries
|
|
162
|
-
const segments = await this._identifySegments(
|
|
163
|
-
messages,
|
|
164
|
-
model,
|
|
165
|
-
COMPACTION_CONFIG.BEGINNING_SEGMENT_PERCENTAGE,
|
|
166
|
-
COMPACTION_CONFIG.END_SEGMENT_PERCENTAGE
|
|
167
|
-
);
|
|
168
|
-
|
|
169
|
-
this.logger.debug('Segments identified for summarization', {
|
|
170
|
-
beginningMessages: segments.beginning.length,
|
|
171
|
-
middleMessages: segments.middle.length,
|
|
172
|
-
endMessages: segments.end.length,
|
|
173
|
-
middleStartIndex: segments.middleStartIndex,
|
|
174
|
-
middleEndIndex: segments.middleEndIndex,
|
|
175
|
-
totalMessages: messages.length
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
// Generate summary of middle segment
|
|
179
|
-
const summary = await this._generateSummary(
|
|
180
|
-
segments.middle,
|
|
181
|
-
model,
|
|
182
|
-
{
|
|
183
|
-
...options,
|
|
184
|
-
middleStartIndex: segments.middleStartIndex,
|
|
185
|
-
middleEndIndex: segments.middleEndIndex
|
|
186
|
-
}
|
|
187
|
-
);
|
|
188
|
-
|
|
189
|
-
// Construct compacted conversation
|
|
190
|
-
const compactedMessages = [
|
|
191
|
-
...segments.beginning,
|
|
192
|
-
summary,
|
|
193
|
-
...segments.end
|
|
194
|
-
];
|
|
195
|
-
|
|
196
|
-
// Count tokens in compacted conversation
|
|
197
|
-
const compactedTokenCount = await this.tokenCountingService.estimateConversationTokens(
|
|
198
|
-
compactedMessages,
|
|
199
|
-
model,
|
|
200
|
-
TOKEN_COUNTING_MODES.ACCURATE
|
|
201
|
-
);
|
|
202
|
-
|
|
203
|
-
// Calculate reduction
|
|
204
|
-
const reductionPercent = ((originalTokenCount - compactedTokenCount) / originalTokenCount) * 100;
|
|
205
|
-
|
|
206
|
-
return {
|
|
207
|
-
compactedMessages,
|
|
208
|
-
strategy,
|
|
209
|
-
originalTokenCount,
|
|
210
|
-
compactedTokenCount,
|
|
211
|
-
reductionPercent,
|
|
212
|
-
segments: {
|
|
213
|
-
beginningCount: segments.beginning.length,
|
|
214
|
-
middleCount: segments.middle.length,
|
|
215
|
-
endCount: segments.end.length,
|
|
216
|
-
summaryInserted: true
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Strategy 2: Fast truncation for model switching
|
|
223
|
-
* Preserves beginning (30%) + separator + end (50%)
|
|
224
|
-
* No AI call required - fast extraction
|
|
225
|
-
* @private
|
|
226
|
-
*/
|
|
227
|
-
async _compactWithTruncation(messages, targetModel, options) {
|
|
228
|
-
const strategy = COMPACTION_STRATEGIES.TRUNCATION;
|
|
229
|
-
|
|
230
|
-
// Get target context window
|
|
231
|
-
const targetContextWindow = this.tokenCountingService.getModelContextWindow(targetModel);
|
|
232
|
-
const targetTokenCount = Math.floor(targetContextWindow * 0.8); // Use 80% of context
|
|
233
|
-
|
|
234
|
-
// Count tokens in original conversation
|
|
235
|
-
const originalTokenCount = await this.tokenCountingService.estimateConversationTokens(
|
|
236
|
-
messages,
|
|
237
|
-
targetModel,
|
|
238
|
-
TOKEN_COUNTING_MODES.ACCURATE
|
|
239
|
-
);
|
|
240
|
-
|
|
241
|
-
// Identify segments using token-based boundaries (30% + 50%)
|
|
242
|
-
const segments = await this._identifySegments(
|
|
243
|
-
messages,
|
|
244
|
-
targetModel,
|
|
245
|
-
COMPACTION_CONFIG.TRUNCATION_BEGINNING_PERCENTAGE,
|
|
246
|
-
COMPACTION_CONFIG.TRUNCATION_END_PERCENTAGE
|
|
247
|
-
);
|
|
248
|
-
|
|
249
|
-
this.logger.debug('Segments identified for truncation', {
|
|
250
|
-
beginningMessages: segments.beginning.length,
|
|
251
|
-
middleMessages: segments.middle.length,
|
|
252
|
-
endMessages: segments.end.length,
|
|
253
|
-
targetTokenCount,
|
|
254
|
-
originalTokenCount
|
|
255
|
-
});
|
|
256
|
-
|
|
257
|
-
// Create separator message
|
|
258
|
-
const separatorMessage = {
|
|
259
|
-
role: 'system',
|
|
260
|
-
content: COMPACTION_CONFIG.COMPACTION_SEPARATOR_MESSAGE,
|
|
261
|
-
type: 'separator',
|
|
262
|
-
timestamp: new Date().toISOString(),
|
|
263
|
-
metadata: {
|
|
264
|
-
truncatedMessages: segments.middle.length,
|
|
265
|
-
reason: 'Model switch - middle section removed to fit target context window'
|
|
266
|
-
}
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
// Construct compacted conversation
|
|
270
|
-
const compactedMessages = [
|
|
271
|
-
...segments.beginning,
|
|
272
|
-
separatorMessage,
|
|
273
|
-
...segments.end
|
|
274
|
-
];
|
|
275
|
-
|
|
276
|
-
// Count tokens in compacted conversation
|
|
277
|
-
const compactedTokenCount = await this.tokenCountingService.estimateConversationTokens(
|
|
278
|
-
compactedMessages,
|
|
279
|
-
targetModel,
|
|
280
|
-
TOKEN_COUNTING_MODES.ACCURATE
|
|
281
|
-
);
|
|
282
|
-
|
|
283
|
-
// Calculate reduction
|
|
284
|
-
const reductionPercent = ((originalTokenCount - compactedTokenCount) / originalTokenCount) * 100;
|
|
285
|
-
|
|
286
|
-
return {
|
|
287
|
-
compactedMessages,
|
|
288
|
-
strategy,
|
|
289
|
-
originalTokenCount,
|
|
290
|
-
compactedTokenCount,
|
|
291
|
-
reductionPercent,
|
|
292
|
-
segments: {
|
|
293
|
-
beginningCount: segments.beginning.length,
|
|
294
|
-
middleCount: segments.middle.length,
|
|
295
|
-
endCount: segments.end.length,
|
|
296
|
-
summaryInserted: false
|
|
297
|
-
}
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Strategy 3: Aggressive summarization for retry scenarios
|
|
303
|
-
* More aggressive compression: 10% beginning + summary + 30% end
|
|
304
|
-
* @private
|
|
305
|
-
*/
|
|
306
|
-
async _compactWithAggressiveSummarization(messages, model, options) {
|
|
307
|
-
const strategy = COMPACTION_STRATEGIES.AGGRESSIVE;
|
|
308
|
-
|
|
309
|
-
// Count tokens in original conversation
|
|
310
|
-
const originalTokenCount = await this.tokenCountingService.estimateConversationTokens(
|
|
311
|
-
messages,
|
|
312
|
-
model,
|
|
313
|
-
TOKEN_COUNTING_MODES.ACCURATE
|
|
314
|
-
);
|
|
315
|
-
|
|
316
|
-
// Identify segments with aggressive percentages
|
|
317
|
-
const segments = await this._identifySegments(
|
|
318
|
-
messages,
|
|
319
|
-
model,
|
|
320
|
-
COMPACTION_CONFIG.AGGRESSIVE_BEGINNING_PERCENTAGE,
|
|
321
|
-
COMPACTION_CONFIG.AGGRESSIVE_END_PERCENTAGE
|
|
322
|
-
);
|
|
323
|
-
|
|
324
|
-
this.logger.debug('Segments identified for aggressive compaction', {
|
|
325
|
-
beginningMessages: segments.beginning.length,
|
|
326
|
-
middleMessages: segments.middle.length,
|
|
327
|
-
endMessages: segments.end.length,
|
|
328
|
-
middleStartIndex: segments.middleStartIndex,
|
|
329
|
-
middleEndIndex: segments.middleEndIndex
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
// Generate summary with more aggressive compression instruction
|
|
333
|
-
const summary = await this._generateSummary(segments.middle, model, {
|
|
334
|
-
...options,
|
|
335
|
-
aggressive: true,
|
|
336
|
-
middleStartIndex: segments.middleStartIndex,
|
|
337
|
-
middleEndIndex: segments.middleEndIndex
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
// Construct compacted conversation
|
|
341
|
-
const compactedMessages = [
|
|
342
|
-
...segments.beginning,
|
|
343
|
-
summary,
|
|
344
|
-
...segments.end
|
|
345
|
-
];
|
|
346
|
-
|
|
347
|
-
// Count tokens in compacted conversation
|
|
348
|
-
const compactedTokenCount = await this.tokenCountingService.estimateConversationTokens(
|
|
349
|
-
compactedMessages,
|
|
350
|
-
model,
|
|
351
|
-
TOKEN_COUNTING_MODES.ACCURATE
|
|
352
|
-
);
|
|
353
|
-
|
|
354
|
-
// Calculate reduction
|
|
355
|
-
const reductionPercent = ((originalTokenCount - compactedTokenCount) / originalTokenCount) * 100;
|
|
356
|
-
|
|
357
|
-
return {
|
|
358
|
-
compactedMessages,
|
|
359
|
-
strategy,
|
|
360
|
-
originalTokenCount,
|
|
361
|
-
compactedTokenCount,
|
|
362
|
-
reductionPercent,
|
|
363
|
-
segments: {
|
|
364
|
-
beginningCount: segments.beginning.length,
|
|
365
|
-
middleCount: segments.middle.length,
|
|
366
|
-
endCount: segments.end.length,
|
|
367
|
-
summaryInserted: true
|
|
368
|
-
}
|
|
369
|
-
};
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* Identify conversation segments based on token counts
|
|
374
|
-
* @private
|
|
375
|
-
*/
|
|
376
|
-
async _identifySegments(messages, model, beginningPercent, endPercent) {
|
|
377
|
-
// Calculate total tokens
|
|
378
|
-
const totalTokens = await this.tokenCountingService.estimateConversationTokens(
|
|
379
|
-
messages,
|
|
380
|
-
model,
|
|
381
|
-
TOKEN_COUNTING_MODES.ACCURATE
|
|
382
|
-
);
|
|
383
|
-
|
|
384
|
-
// Calculate target tokens for each segment
|
|
385
|
-
const beginningTargetTokens = Math.floor(totalTokens * beginningPercent);
|
|
386
|
-
const endTargetTokens = Math.floor(totalTokens * endPercent);
|
|
387
|
-
|
|
388
|
-
// Identify beginning segment (from start)
|
|
389
|
-
let beginningTokens = 0;
|
|
390
|
-
let beginningEndIndex = 0;
|
|
391
|
-
|
|
392
|
-
for (let i = 0; i < messages.length; i++) {
|
|
393
|
-
const messageTokens = await this.tokenCountingService.countTokens(
|
|
394
|
-
messages[i].content,
|
|
395
|
-
model,
|
|
396
|
-
TOKEN_COUNTING_MODES.CACHED
|
|
397
|
-
);
|
|
398
|
-
|
|
399
|
-
if (beginningTokens + messageTokens > beginningTargetTokens && i >= 2) {
|
|
400
|
-
// Ensure at least 2 messages in beginning (as per design doc)
|
|
401
|
-
break;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
beginningTokens += messageTokens;
|
|
405
|
-
beginningEndIndex = i + 1;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
// Identify end segment (from end, working backwards)
|
|
409
|
-
let endTokens = 0;
|
|
410
|
-
let endStartIndex = messages.length;
|
|
411
|
-
|
|
412
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
413
|
-
const messageTokens = await this.tokenCountingService.countTokens(
|
|
414
|
-
messages[i].content,
|
|
415
|
-
model,
|
|
416
|
-
TOKEN_COUNTING_MODES.CACHED
|
|
417
|
-
);
|
|
418
|
-
|
|
419
|
-
if (endTokens + messageTokens > endTargetTokens) {
|
|
420
|
-
break;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
endTokens += messageTokens;
|
|
424
|
-
endStartIndex = i;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
// Ensure no overlap
|
|
428
|
-
if (endStartIndex < beginningEndIndex) {
|
|
429
|
-
endStartIndex = beginningEndIndex;
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
// Extract segments
|
|
433
|
-
const beginning = messages.slice(0, beginningEndIndex);
|
|
434
|
-
const middle = messages.slice(beginningEndIndex, endStartIndex);
|
|
435
|
-
const end = messages.slice(endStartIndex);
|
|
436
|
-
|
|
437
|
-
return {
|
|
438
|
-
beginning,
|
|
439
|
-
middle,
|
|
440
|
-
end,
|
|
441
|
-
middleStartIndex: beginningEndIndex,
|
|
442
|
-
middleEndIndex: endStartIndex - 1 // Inclusive end index
|
|
443
|
-
};
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
/**
|
|
447
|
-
* Generate AI summary of middle segment using GPT-4o-mini
|
|
448
|
-
* @private
|
|
449
|
-
*/
|
|
450
|
-
async _generateSummary(middleMessages, model, options = {}) {
|
|
451
|
-
if (middleMessages.length === 0) {
|
|
452
|
-
return {
|
|
453
|
-
role: 'system',
|
|
454
|
-
content: `${COMPACTION_CONFIG.COMPACTION_SUMMARY_PREFIX} No messages to summarize.`,
|
|
455
|
-
type: 'summary',
|
|
456
|
-
timestamp: new Date().toISOString()
|
|
457
|
-
};
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
// Format middle messages for summarization
|
|
461
|
-
const middleContent = middleMessages
|
|
462
|
-
.map(msg => `${msg.role}: ${msg.content}`)
|
|
463
|
-
.join('\n\n');
|
|
464
|
-
|
|
465
|
-
// Build summary prompt
|
|
466
|
-
const summaryPrompt = this.summaryPromptTemplate
|
|
467
|
-
.replace('{middle_segment}', middleContent)
|
|
468
|
-
.replace('{aggressive_instruction}', options.aggressive
|
|
469
|
-
? '\n\nIMPORTANT: Be VERY aggressive in compression. Prioritize only the most critical information. Aim for maximum brevity while maintaining essential context.'
|
|
470
|
-
: '');
|
|
471
|
-
|
|
472
|
-
// Try primary model and fallbacks
|
|
473
|
-
const modelsToTry = [
|
|
474
|
-
COMPACTION_CONFIG.COMPACTION_MODEL,
|
|
475
|
-
...COMPACTION_CONFIG.COMPACTION_MODEL_FALLBACKS
|
|
476
|
-
];
|
|
477
|
-
|
|
478
|
-
let lastError = null;
|
|
479
|
-
|
|
480
|
-
for (const compactionModel of modelsToTry) {
|
|
481
|
-
try {
|
|
482
|
-
this.logger.debug('Generating summary', {
|
|
483
|
-
compactionModel,
|
|
484
|
-
middleMessageCount: middleMessages.length,
|
|
485
|
-
middleContentLength: middleContent.length,
|
|
486
|
-
aggressive: options.aggressive
|
|
487
|
-
});
|
|
488
|
-
|
|
489
|
-
// Call AI service
|
|
490
|
-
const response = await this.aiService.sendMessage(
|
|
491
|
-
compactionModel,
|
|
492
|
-
summaryPrompt,
|
|
493
|
-
{
|
|
494
|
-
systemPrompt: 'You are a conversation summarization expert. Your goal is to compress conversations while preserving critical information for continued interaction.',
|
|
495
|
-
maxTokens: COMPACTION_CONFIG.MAX_SUMMARY_TOKENS,
|
|
496
|
-
temperature: 0.3, // Lower temperature for consistency
|
|
497
|
-
sessionId: options.sessionId,
|
|
498
|
-
platformProvided: true // Use Loxia API key
|
|
499
|
-
}
|
|
500
|
-
);
|
|
501
|
-
|
|
502
|
-
const summaryContent = response.content.trim();
|
|
503
|
-
|
|
504
|
-
// Build index range string
|
|
505
|
-
const indexRange = (options.middleStartIndex !== undefined && options.middleEndIndex !== undefined)
|
|
506
|
-
? `original messages ${options.middleStartIndex}-${options.middleEndIndex}`
|
|
507
|
-
: `${middleMessages.length} messages`;
|
|
508
|
-
|
|
509
|
-
this.logger.info('Summary generated successfully', {
|
|
510
|
-
compactionModel,
|
|
511
|
-
originalLength: middleContent.length,
|
|
512
|
-
summaryLength: summaryContent.length,
|
|
513
|
-
compressionRatio: (summaryContent.length / middleContent.length * 100).toFixed(2) + '%',
|
|
514
|
-
indexRange
|
|
515
|
-
});
|
|
516
|
-
|
|
517
|
-
// Return formatted summary message
|
|
518
|
-
return {
|
|
519
|
-
role: 'system',
|
|
520
|
-
content: `${COMPACTION_CONFIG.COMPACTION_SUMMARY_PREFIX} - ${indexRange}]\n\n${summaryContent}\n\n${COMPACTION_CONFIG.COMPACTION_SUMMARY_SUFFIX}`,
|
|
521
|
-
type: 'summary',
|
|
522
|
-
timestamp: new Date().toISOString(),
|
|
523
|
-
metadata: {
|
|
524
|
-
originalMessageCount: middleMessages.length,
|
|
525
|
-
originalStartIndex: options.middleStartIndex,
|
|
526
|
-
originalEndIndex: options.middleEndIndex,
|
|
527
|
-
compactionModel: compactionModel,
|
|
528
|
-
aggressive: options.aggressive || false
|
|
529
|
-
}
|
|
530
|
-
};
|
|
531
|
-
|
|
532
|
-
} catch (error) {
|
|
533
|
-
lastError = error;
|
|
534
|
-
this.logger.warn('Summary generation failed with model, trying next fallback', {
|
|
535
|
-
compactionModel,
|
|
536
|
-
error: error.message,
|
|
537
|
-
middleMessageCount: middleMessages.length
|
|
538
|
-
});
|
|
539
|
-
// Continue to next model
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
// All models failed, use fallback summary
|
|
544
|
-
this.logger.error('All summary generation attempts failed', {
|
|
545
|
-
modelsAttempted: modelsToTry.length,
|
|
546
|
-
lastError: lastError?.message,
|
|
547
|
-
middleMessageCount: middleMessages.length
|
|
548
|
-
});
|
|
549
|
-
|
|
550
|
-
// Fallback to simple truncated summary
|
|
551
|
-
const fallbackSummary = this._createFallbackSummary(middleMessages);
|
|
552
|
-
|
|
553
|
-
// Build index range string for fallback
|
|
554
|
-
const indexRange = (options.middleStartIndex !== undefined && options.middleEndIndex !== undefined)
|
|
555
|
-
? `original messages ${options.middleStartIndex}-${options.middleEndIndex}`
|
|
556
|
-
: `${middleMessages.length} messages`;
|
|
557
|
-
|
|
558
|
-
return {
|
|
559
|
-
role: 'system',
|
|
560
|
-
content: `${COMPACTION_CONFIG.COMPACTION_SUMMARY_PREFIX} - ${indexRange}]\n\n${fallbackSummary}\n\n${COMPACTION_CONFIG.COMPACTION_SUMMARY_SUFFIX}`,
|
|
561
|
-
type: 'summary',
|
|
562
|
-
timestamp: new Date().toISOString(),
|
|
563
|
-
metadata: {
|
|
564
|
-
originalMessageCount: middleMessages.length,
|
|
565
|
-
originalStartIndex: options.middleStartIndex,
|
|
566
|
-
originalEndIndex: options.middleEndIndex,
|
|
567
|
-
fallback: true,
|
|
568
|
-
error: lastError?.message,
|
|
569
|
-
modelsAttempted: modelsToTry
|
|
570
|
-
}
|
|
571
|
-
};
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
/**
|
|
575
|
-
* Create fallback summary when AI generation fails
|
|
576
|
-
* @private
|
|
577
|
-
*/
|
|
578
|
-
_createFallbackSummary(messages) {
|
|
579
|
-
const messageCount = messages.length;
|
|
580
|
-
const roles = messages.map(m => m.role);
|
|
581
|
-
const userCount = roles.filter(r => r === 'user').length;
|
|
582
|
-
const assistantCount = roles.filter(r => r === 'assistant').length;
|
|
583
|
-
|
|
584
|
-
return `[${messageCount} messages summarized - ${userCount} user messages, ${assistantCount} assistant responses. ` +
|
|
585
|
-
`Summary generation unavailable - middle section compressed for context management.]`;
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
/**
|
|
589
|
-
* Create summary prompt template with preservation guidelines
|
|
590
|
-
* @private
|
|
591
|
-
*/
|
|
592
|
-
_createSummaryPromptTemplate() {
|
|
593
|
-
return `You are compacting a conversation to preserve critical information while reducing token count.
|
|
594
|
-
|
|
595
|
-
CONTEXT: This is part of a longer conversation that needs compactization for continued processing.
|
|
596
|
-
|
|
597
|
-
PRESERVATION GUIDELINES:
|
|
598
|
-
|
|
599
|
-
HIGH PRIORITY (Always Preserve):
|
|
600
|
-
- Future reference value: Information likely to be referenced again
|
|
601
|
-
- Decisions and reasoning: WHY things were decided, not just what
|
|
602
|
-
- API signatures and interfaces: Function definitions, method calls
|
|
603
|
-
- Active dependencies: Information that ongoing work relies on
|
|
604
|
-
- Error patterns and solutions: What failed and how it was fixed
|
|
605
|
-
- Key facts and data: Specific numbers, names, configurations
|
|
606
|
-
|
|
607
|
-
MEDIUM PRIORITY (Compress Intelligently):
|
|
608
|
-
- Code blocks: Keep function signatures + brief description, compress implementation details
|
|
609
|
-
- Working solutions: Essence and outcome, not every implementation step
|
|
610
|
-
- Failed attempts: Brief mention of what didn't work and why, skip detailed troubleshooting
|
|
611
|
-
- Repetitive content: Consolidate similar examples or explanations
|
|
612
|
-
|
|
613
|
-
LOW PRIORITY (Heavily Compress/Remove):
|
|
614
|
-
- Completed calculations: Keep results, skip intermediate steps
|
|
615
|
-
- Verbose explanations: Summarize well-known concepts
|
|
616
|
-
- Debug output: Skip terminal logs and error messages that served their purpose
|
|
617
|
-
- Trial-and-error sequences: Skip multiple failed attempts with no lasting value
|
|
618
|
-
- Acknowledgments and pleasantries: Skip "thank you", "sure", "okay" type exchanges
|
|
619
|
-
|
|
620
|
-
CONVERSATION SEGMENT TO SUMMARIZE:
|
|
621
|
-
{middle_segment}
|
|
622
|
-
|
|
623
|
-
TASK: Create a concise summary that preserves logical flow and critical information. Focus on:
|
|
624
|
-
1. Key decisions and their reasoning
|
|
625
|
-
2. Important facts, data, and configurations
|
|
626
|
-
3. Active context needed for continuation
|
|
627
|
-
4. Problem-solving outcomes (skip the debugging process)
|
|
628
|
-
5. Dependencies and interfaces that code/work relies on
|
|
629
|
-
|
|
630
|
-
Someone reading this should understand the conversation progression and have all information needed for effective continuation.
|
|
631
|
-
{aggressive_instruction}
|
|
632
|
-
|
|
633
|
-
OUTPUT: Provide ONLY the summary text without preamble, explanation, or meta-commentary.`;
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
export default ConversationCompactionService;
|
|
1
|
+
const a0_0x371d2d=a0_0x2938;(function(_0x1d6b3a,_0x303a05){const _0x47953c=a0_0x2938,_0x488ef7=_0x1d6b3a();while(!![]){try{const _0x1c22bf=-parseInt(_0x47953c(0x74))/0x1*(parseInt(_0x47953c(0x8f))/0x2)+-parseInt(_0x47953c(0x8e))/0x3+parseInt(_0x47953c(0x96))/0x4*(-parseInt(_0x47953c(0xbd))/0x5)+-parseInt(_0x47953c(0xa0))/0x6+-parseInt(_0x47953c(0x76))/0x7+parseInt(_0x47953c(0x86))/0x8*(parseInt(_0x47953c(0x7e))/0x9)+parseInt(_0x47953c(0x8b))/0xa;if(_0x1c22bf===_0x303a05)break;else _0x488ef7['push'](_0x488ef7['shift']());}catch(_0x5098fb){_0x488ef7['push'](_0x488ef7['shift']());}}}(a0_0x3302,0xc68c4));import{COMPACTION_CONFIG,COMPACTION_STRATEGIES,TOKEN_COUNTING_MODES}from'../utilities/constants.js';class ConversationCompactionService{constructor(_0x2f7bf5,_0x7126ff,_0x4c9224){const _0x5325c6=a0_0x2938;this['tokenCountingService']=_0x2f7bf5,this[_0x5325c6(0x8d)]=_0x7126ff,this[_0x5325c6(0x94)]=_0x4c9224,this[_0x5325c6(0x75)]=this['_createSummaryPromptTemplate']();}async['compactConversation'](_0xe2c78,_0x5b0f2f,_0x3da8b9,_0x340450={}){const _0x1c5777=a0_0x2938,_0x316f43=Date['now']();try{if(!Array['isArray'](_0xe2c78)||_0xe2c78[_0x1c5777(0x91)]===0x0)throw new Error(_0x1c5777(0x81));if(_0xe2c78['length']<COMPACTION_CONFIG['MIN_MESSAGES_FOR_COMPACTION'])return this['logger'][_0x1c5777(0xa7)]('Too\x20few\x20messages\x20for\x20compaction',{'messageCount':_0xe2c78['length'],'minimum':COMPACTION_CONFIG['MIN_MESSAGES_FOR_COMPACTION']}),{'compactedMessages':_0xe2c78,'strategy':'none','originalTokenCount':0x0,'compactedTokenCount':0x0,'reductionPercent':0x0,'skipped':!![],'reason':'Too\x20few\x20messages'};const _0x499e49=_0x5b0f2f!==_0x3da8b9,_0xd7b683=_0x340450[_0x1c5777(0x87)]||![];let _0x5dcf6d;if(_0x499e49)_0x5dcf6d=COMPACTION_STRATEGIES[_0x1c5777(0xa6)];else _0xd7b683?_0x5dcf6d=COMPACTION_STRATEGIES['AGGRESSIVE']:_0x5dcf6d=_0x340450['strategy']||COMPACTION_STRATEGIES['SUMMARIZATION'];this[_0x1c5777(0x94)][_0x1c5777(0x98)](_0x1c5777(0x95),{'messageCount':_0xe2c78['length'],'currentModel':_0x5b0f2f,'targetModel':_0x3da8b9,'strategy':_0x5dcf6d,'isModelSwitch':_0x499e49,'isRetry':_0xd7b683});let _0x12c158;switch(_0x5dcf6d){case COMPACTION_STRATEGIES[_0x1c5777(0x82)]:_0x12c158=await this['_compactWithSummarization'](_0xe2c78,_0x5b0f2f,_0x340450);break;case COMPACTION_STRATEGIES[_0x1c5777(0xa6)]:_0x12c158=await this[_0x1c5777(0x89)](_0xe2c78,_0x3da8b9,_0x340450);break;case COMPACTION_STRATEGIES['AGGRESSIVE']:_0x12c158=await this[_0x1c5777(0x93)](_0xe2c78,_0x5b0f2f,_0x340450);break;default:throw new Error(_0x1c5777(0xb4)+_0x5dcf6d);}const _0x4e4248=Date['now']()-_0x316f43;return _0x12c158['executionTime']=_0x4e4248,_0x12c158['timestamp']=new Date()[_0x1c5777(0xa2)](),this['logger'][_0x1c5777(0x98)]('Compaction\x20completed\x20successfully',{'strategy':_0x12c158['strategy'],'originalMessages':_0xe2c78['length'],'compactedMessages':_0x12c158[_0x1c5777(0x9d)][_0x1c5777(0x91)],'originalTokens':_0x12c158['originalTokenCount'],'compactedTokens':_0x12c158[_0x1c5777(0xa8)],'reductionPercent':_0x12c158['reductionPercent']['toFixed'](0x2),'executionTime':_0x4e4248+'ms'}),_0x12c158;}catch(_0x27ba60){const _0x2973a1=Date[_0x1c5777(0xa3)]()-_0x316f43;this['logger'][_0x1c5777(0x9f)]('Compaction\x20failed',{'error':_0x27ba60[_0x1c5777(0xa4)],'messageCount':_0xe2c78['length'],'currentModel':_0x5b0f2f,'targetModel':_0x3da8b9,'executionTime':_0x2973a1+'ms'});throw _0x27ba60;}}async['_compactWithSummarization'](_0x538d35,_0xce3c01,_0x598072){const _0x529615=a0_0x2938,_0x190859=COMPACTION_STRATEGIES['SUMMARIZATION'],_0x53cd88=await this[_0x529615(0xad)][_0x529615(0x79)](_0x538d35,_0xce3c01,TOKEN_COUNTING_MODES[_0x529615(0x84)]),_0x1bf936=await this[_0x529615(0xb1)](_0x538d35,_0xce3c01,COMPACTION_CONFIG['BEGINNING_SEGMENT_PERCENTAGE'],COMPACTION_CONFIG[_0x529615(0x99)]);this[_0x529615(0x94)]['debug'](_0x529615(0x7d),{'beginningMessages':_0x1bf936['beginning'][_0x529615(0x91)],'middleMessages':_0x1bf936['middle']['length'],'endMessages':_0x1bf936['end'][_0x529615(0x91)],'middleStartIndex':_0x1bf936['middleStartIndex'],'middleEndIndex':_0x1bf936[_0x529615(0x8a)],'totalMessages':_0x538d35[_0x529615(0x91)]});const _0x1bd187=await this['_generateSummary'](_0x1bf936[_0x529615(0xac)],_0xce3c01,{..._0x598072,'middleStartIndex':_0x1bf936[_0x529615(0x9a)],'middleEndIndex':_0x1bf936[_0x529615(0x8a)]}),_0x2f7299=[..._0x1bf936[_0x529615(0xab)],_0x1bd187,..._0x1bf936['end']],_0x2620f4=await this['tokenCountingService'][_0x529615(0x79)](_0x2f7299,_0xce3c01,TOKEN_COUNTING_MODES['ACCURATE']),_0x53b1c2=(_0x53cd88-_0x2620f4)/_0x53cd88*0x64;return{'compactedMessages':_0x2f7299,'strategy':_0x190859,'originalTokenCount':_0x53cd88,'compactedTokenCount':_0x2620f4,'reductionPercent':_0x53b1c2,'segments':{'beginningCount':_0x1bf936[_0x529615(0xab)][_0x529615(0x91)],'middleCount':_0x1bf936[_0x529615(0xac)]['length'],'endCount':_0x1bf936['end']['length'],'summaryInserted':!![]}};}async[a0_0x371d2d(0x89)](_0x48b2f2,_0x388bbb,_0x4e8966){const _0x6053eb=a0_0x371d2d,_0x431e42=COMPACTION_STRATEGIES['TRUNCATION'],_0x351751=this['tokenCountingService']['getModelContextWindow'](_0x388bbb),_0x5dd284=Math[_0x6053eb(0xaa)](_0x351751*0.8),_0x3c436b=await this[_0x6053eb(0xad)][_0x6053eb(0x79)](_0x48b2f2,_0x388bbb,TOKEN_COUNTING_MODES['ACCURATE']),_0x29bd21=await this[_0x6053eb(0xb1)](_0x48b2f2,_0x388bbb,COMPACTION_CONFIG[_0x6053eb(0x90)],COMPACTION_CONFIG['TRUNCATION_END_PERCENTAGE']);this[_0x6053eb(0x94)][_0x6053eb(0xba)]('Segments\x20identified\x20for\x20truncation',{'beginningMessages':_0x29bd21[_0x6053eb(0xab)][_0x6053eb(0x91)],'middleMessages':_0x29bd21['middle'][_0x6053eb(0x91)],'endMessages':_0x29bd21['end']['length'],'targetTokenCount':_0x5dd284,'originalTokenCount':_0x3c436b});const _0x4dc6b7={'role':'system','content':COMPACTION_CONFIG['COMPACTION_SEPARATOR_MESSAGE'],'type':_0x6053eb(0xb5),'timestamp':new Date()['toISOString'](),'metadata':{'truncatedMessages':_0x29bd21[_0x6053eb(0xac)]['length'],'reason':'Model\x20switch\x20-\x20middle\x20section\x20removed\x20to\x20fit\x20target\x20context\x20window'}},_0x56a65a=[..._0x29bd21[_0x6053eb(0xab)],_0x4dc6b7,..._0x29bd21['end']],_0x2ef4c7=await this[_0x6053eb(0xad)][_0x6053eb(0x79)](_0x56a65a,_0x388bbb,TOKEN_COUNTING_MODES['ACCURATE']),_0x30159f=(_0x3c436b-_0x2ef4c7)/_0x3c436b*0x64;return{'compactedMessages':_0x56a65a,'strategy':_0x431e42,'originalTokenCount':_0x3c436b,'compactedTokenCount':_0x2ef4c7,'reductionPercent':_0x30159f,'segments':{'beginningCount':_0x29bd21['beginning']['length'],'middleCount':_0x29bd21[_0x6053eb(0xac)]['length'],'endCount':_0x29bd21['end']['length'],'summaryInserted':![]}};}async['_compactWithAggressiveSummarization'](_0xc7fcf2,_0x5c38a3,_0x19972a){const _0x42960a=a0_0x371d2d,_0x11001d=COMPACTION_STRATEGIES['AGGRESSIVE'],_0x4b9d7f=await this['tokenCountingService']['estimateConversationTokens'](_0xc7fcf2,_0x5c38a3,TOKEN_COUNTING_MODES['ACCURATE']),_0x19a5b9=await this[_0x42960a(0xb1)](_0xc7fcf2,_0x5c38a3,COMPACTION_CONFIG[_0x42960a(0x88)],COMPACTION_CONFIG['AGGRESSIVE_END_PERCENTAGE']);this[_0x42960a(0x94)][_0x42960a(0xba)](_0x42960a(0xb0),{'beginningMessages':_0x19a5b9['beginning'][_0x42960a(0x91)],'middleMessages':_0x19a5b9[_0x42960a(0xac)][_0x42960a(0x91)],'endMessages':_0x19a5b9['end'][_0x42960a(0x91)],'middleStartIndex':_0x19a5b9['middleStartIndex'],'middleEndIndex':_0x19a5b9['middleEndIndex']});const _0x27b442=await this['_generateSummary'](_0x19a5b9['middle'],_0x5c38a3,{..._0x19972a,'aggressive':!![],'middleStartIndex':_0x19a5b9['middleStartIndex'],'middleEndIndex':_0x19a5b9[_0x42960a(0x8a)]}),_0x216054=[..._0x19a5b9[_0x42960a(0xab)],_0x27b442,..._0x19a5b9[_0x42960a(0x80)]],_0x45c2b5=await this[_0x42960a(0xad)]['estimateConversationTokens'](_0x216054,_0x5c38a3,TOKEN_COUNTING_MODES['ACCURATE']),_0x244af9=(_0x4b9d7f-_0x45c2b5)/_0x4b9d7f*0x64;return{'compactedMessages':_0x216054,'strategy':_0x11001d,'originalTokenCount':_0x4b9d7f,'compactedTokenCount':_0x45c2b5,'reductionPercent':_0x244af9,'segments':{'beginningCount':_0x19a5b9[_0x42960a(0xab)]['length'],'middleCount':_0x19a5b9['middle'][_0x42960a(0x91)],'endCount':_0x19a5b9['end'][_0x42960a(0x91)],'summaryInserted':!![]}};}async[a0_0x371d2d(0xb1)](_0x691cb3,_0x3ff1e8,_0x3bbb09,_0x48ebb9){const _0xd53e8b=a0_0x371d2d,_0x5b32ef=await this['tokenCountingService'][_0xd53e8b(0x79)](_0x691cb3,_0x3ff1e8,TOKEN_COUNTING_MODES['ACCURATE']),_0xd42894=Math[_0xd53e8b(0xaa)](_0x5b32ef*_0x3bbb09),_0x5329fa=Math[_0xd53e8b(0xaa)](_0x5b32ef*_0x48ebb9);let _0x32616e=0x0,_0x42dcf2=0x0;for(let _0x17a227=0x0;_0x17a227<_0x691cb3[_0xd53e8b(0x91)];_0x17a227++){const _0x1733ff=await this['tokenCountingService'][_0xd53e8b(0x78)](_0x691cb3[_0x17a227][_0xd53e8b(0x77)],_0x3ff1e8,TOKEN_COUNTING_MODES[_0xd53e8b(0xaf)]);if(_0x32616e+_0x1733ff>_0xd42894&&_0x17a227>=0x2)break;_0x32616e+=_0x1733ff,_0x42dcf2=_0x17a227+0x1;}let _0x47d342=0x0,_0x19fbf6=_0x691cb3[_0xd53e8b(0x91)];for(let _0x1b84c8=_0x691cb3[_0xd53e8b(0x91)]-0x1;_0x1b84c8>=0x0;_0x1b84c8--){const _0x22cc40=await this[_0xd53e8b(0xad)][_0xd53e8b(0x78)](_0x691cb3[_0x1b84c8][_0xd53e8b(0x77)],_0x3ff1e8,TOKEN_COUNTING_MODES[_0xd53e8b(0xaf)]);if(_0x47d342+_0x22cc40>_0x5329fa)break;_0x47d342+=_0x22cc40,_0x19fbf6=_0x1b84c8;}_0x19fbf6<_0x42dcf2&&(_0x19fbf6=_0x42dcf2);const _0x2b9cca=_0x691cb3['slice'](0x0,_0x42dcf2),_0xaf9d5d=_0x691cb3[_0xd53e8b(0x97)](_0x42dcf2,_0x19fbf6),_0xac2585=_0x691cb3['slice'](_0x19fbf6);return{'beginning':_0x2b9cca,'middle':_0xaf9d5d,'end':_0xac2585,'middleStartIndex':_0x42dcf2,'middleEndIndex':_0x19fbf6-0x1};}async[a0_0x371d2d(0x9b)](_0x458f6c,_0xeaae8b,_0xde0d54={}){const _0x1630ca=a0_0x371d2d;if(_0x458f6c['length']===0x0)return{'role':'system','content':COMPACTION_CONFIG[_0x1630ca(0x8c)]+_0x1630ca(0xb9),'type':_0x1630ca(0xb6),'timestamp':new Date()[_0x1630ca(0xa2)]()};const _0x1e8611=_0x458f6c['map'](_0x40a1ba=>_0x40a1ba[_0x1630ca(0xb3)]+':\x20'+_0x40a1ba[_0x1630ca(0x77)])[_0x1630ca(0x9c)]('\x0a\x0a'),_0x364cad=this[_0x1630ca(0x75)]['replace']('{middle_segment}',_0x1e8611)[_0x1630ca(0x7b)]('{aggressive_instruction}',_0xde0d54['aggressive']?'\x0a\x0aIMPORTANT:\x20Be\x20VERY\x20aggressive\x20in\x20compression.\x20Prioritize\x20only\x20the\x20most\x20critical\x20information.\x20Aim\x20for\x20maximum\x20brevity\x20while\x20maintaining\x20essential\x20context.':''),_0x3f3cd5=[COMPACTION_CONFIG[_0x1630ca(0xa9)],...COMPACTION_CONFIG['COMPACTION_MODEL_FALLBACKS']];let _0x2cbfca=null;for(const _0x3806a3 of _0x3f3cd5){try{this[_0x1630ca(0x94)][_0x1630ca(0xba)]('Generating\x20summary',{'compactionModel':_0x3806a3,'middleMessageCount':_0x458f6c['length'],'middleContentLength':_0x1e8611[_0x1630ca(0x91)],'aggressive':_0xde0d54[_0x1630ca(0x73)]});const _0x446789=await this['aiService'][_0x1630ca(0xa5)](_0x3806a3,_0x364cad,{'systemPrompt':_0x1630ca(0x7f),'maxTokens':COMPACTION_CONFIG[_0x1630ca(0xb2)],'temperature':0.3,'sessionId':_0xde0d54['sessionId'],'platformProvided':!![]}),_0x461d7e=_0x446789[_0x1630ca(0x77)]['trim'](),_0x313463=_0xde0d54['middleStartIndex']!==undefined&&_0xde0d54[_0x1630ca(0x8a)]!==undefined?'original\x20messages\x20'+_0xde0d54['middleStartIndex']+'-'+_0xde0d54[_0x1630ca(0x8a)]:_0x458f6c[_0x1630ca(0x91)]+_0x1630ca(0xb7);return this['logger']['info']('Summary\x20generated\x20successfully',{'compactionModel':_0x3806a3,'originalLength':_0x1e8611['length'],'summaryLength':_0x461d7e['length'],'compressionRatio':(_0x461d7e[_0x1630ca(0x91)]/_0x1e8611[_0x1630ca(0x91)]*0x64)[_0x1630ca(0x92)](0x2)+'%','indexRange':_0x313463}),{'role':'system','content':COMPACTION_CONFIG['COMPACTION_SUMMARY_PREFIX']+_0x1630ca(0xa1)+_0x313463+_0x1630ca(0xae)+_0x461d7e+'\x0a\x0a'+COMPACTION_CONFIG['COMPACTION_SUMMARY_SUFFIX'],'type':_0x1630ca(0xb6),'timestamp':new Date()['toISOString'](),'metadata':{'originalMessageCount':_0x458f6c['length'],'originalStartIndex':_0xde0d54['middleStartIndex'],'originalEndIndex':_0xde0d54['middleEndIndex'],'compactionModel':_0x3806a3,'aggressive':_0xde0d54[_0x1630ca(0x73)]||![]}};}catch(_0x34088f){_0x2cbfca=_0x34088f,this['logger'][_0x1630ca(0xa7)](_0x1630ca(0xb8),{'compactionModel':_0x3806a3,'error':_0x34088f[_0x1630ca(0xa4)],'middleMessageCount':_0x458f6c[_0x1630ca(0x91)]});}}this[_0x1630ca(0x94)][_0x1630ca(0x9f)]('All\x20summary\x20generation\x20attempts\x20failed',{'modelsAttempted':_0x3f3cd5['length'],'lastError':_0x2cbfca?.[_0x1630ca(0xa4)],'middleMessageCount':_0x458f6c[_0x1630ca(0x91)]});const _0x200e0a=this[_0x1630ca(0xbc)](_0x458f6c),_0x3fa424=_0xde0d54[_0x1630ca(0x9a)]!==undefined&&_0xde0d54['middleEndIndex']!==undefined?_0x1630ca(0x83)+_0xde0d54[_0x1630ca(0x9a)]+'-'+_0xde0d54['middleEndIndex']:_0x458f6c[_0x1630ca(0x91)]+'\x20messages';return{'role':'system','content':COMPACTION_CONFIG[_0x1630ca(0x8c)]+_0x1630ca(0xa1)+_0x3fa424+_0x1630ca(0xae)+_0x200e0a+'\x0a\x0a'+COMPACTION_CONFIG[_0x1630ca(0xbb)],'type':'summary','timestamp':new Date()['toISOString'](),'metadata':{'originalMessageCount':_0x458f6c['length'],'originalStartIndex':_0xde0d54['middleStartIndex'],'originalEndIndex':_0xde0d54['middleEndIndex'],'fallback':!![],'error':_0x2cbfca?.['message'],'modelsAttempted':_0x3f3cd5}};}['_createFallbackSummary'](_0x204410){const _0x3ba736=a0_0x371d2d,_0x47da49=_0x204410['length'],_0x394b3c=_0x204410['map'](_0x5341e4=>_0x5341e4['role']),_0x57ac67=_0x394b3c[_0x3ba736(0x85)](_0x1e42f9=>_0x1e42f9===_0x3ba736(0x9e))[_0x3ba736(0x91)],_0x4721b4=_0x394b3c['filter'](_0x1090d4=>_0x1090d4==='assistant')[_0x3ba736(0x91)];return'['+_0x47da49+_0x3ba736(0x7a)+_0x57ac67+'\x20user\x20messages,\x20'+_0x4721b4+'\x20assistant\x20responses.\x20'+'Summary\x20generation\x20unavailable\x20-\x20middle\x20section\x20compressed\x20for\x20context\x20management.]';}['_createSummaryPromptTemplate'](){const _0x6bde3e=a0_0x371d2d;return _0x6bde3e(0x7c);}}function a0_0x3302(){const _0x19936f=['mZiZndu1ohLkv05Zva','ic0G','Dg9ju09tDhjPBMC','BM93','BwvZC2fNzq','C2vUze1LC3nHz2u','vfjvtKnbveLptG','D2fYBG','y29TCgfJDgvKvg9Rzw5dB3vUDa','q09nuefdveLptL9nt0rfta','zMXVB3i','yMvNAw5UAw5N','BwLKzgXL','Dg9Rzw5dB3vUDgLUz1nLCNzPy2u','xqOk','q0fdseve','u2vNBwvUDhmGAwrLBNrPzMLLzcbMB3iGywDNCMvZC2L2zsbJB21Wywn0Aw9U','x2LKzw50Awz5u2vNBwvUDhm','tufyx1nvtu1buLLFve9lru5t','CM9Szq','vw5RBM93BIbJB21Wywn0Aw9Uihn0CMf0zwD5oIa','C2vWyxjHDg9Y','C3vTBwfYEq','ig1LC3nHz2vZ','u3vTBwfYEsbNzw5LCMf0Aw9UigzHAwXLzcb3AxrOig1VzgvSlcb0CNLPBMCGBMv4DcbMywXSyMfJAW','ie5Vig1LC3nHz2vZihrVihn1Bw1HCML6zs4','zgvIDwC','q09nuefdveLptL9tvu1nqvjzx1nvrKzjwa','x2nYzwf0zuzHBgXIywnRu3vTBwfYEq','ndqWnxHKCKjUra','ywDNCMvZC2L2zq','mZDJAhHgq08','C3vTBwfYEvbYB21WDfrLBxbSyxrL','nZeYmZm0ENLlBwru','y29UDgvUDa','y291BNruB2TLBNm','zxn0Aw1HDgvdB252zxjZyxrPB25uB2TLBNm','ig1LC3nHz2vZihn1Bw1HCML6zwqGlsa','CMvWBgfJzq','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','ota1ngPtyKLQBW','ww91igfYzsbHignVBNzLCNnHDgLVBIbZDw1TyxjPEMf0Aw9Uigv4CgvYDc4Gww91CIbNB2fSigLZihrVignVBxbYzxnZignVBNzLCNnHDgLVBNmGD2HPBguGChjLC2vYDMLUzYbJCML0AwnHBcbPBMzVCM1HDgLVBIbMB3iGy29UDgLUDwvKigLUDgvYywn0Aw9UlG','zw5K','twvZC2fNzxmGyxjYyxKGAxmGCMvXDwLYzwqGyw5KignHBM5VDcbIzsbLBxb0Eq','u1vntufssvPbveLptG','B3jPz2LUywWGBwvZC2fNzxmG','qundvvjbveu','zMLSDgvY','otm1mNHcwuTuAa','AxnszxrYEq','quDhuKvtu0Lwrv9cruDjtK5jtKDFuevsq0vovefhrq','x2nVBxbHy3rxAxrOvhj1BMnHDgLVBG','BwLKzgXLrw5Ksw5KzxG','mZq0mda3ndbYC3fSuKe','q09nuefdveLptL9tvu1nqvjzx1bsruzjwa','ywLtzxj2AwnL','mZa1mZK4nuHSv1bRza','odC4ndj1u3nqtKO','vfjvtKnbveLptL9cruDjtK5jtKDFuevsq0vovefhrq','BgvUz3rO','Dg9gAxHLza','x2nVBxbHy3rxAxrOqwDNCMvZC2L2zvn1Bw1HCML6yxrPB24','Bg9Nz2vY','u3rHCNrPBMCGy29UDMvYC2f0Aw9UignVBxbHy3rPB24','mJm1nNzVv0L2Ba','C2XPy2u','Aw5MBW','ru5ex1nfr01ftLrFuevsq0vovefhrq','BwLKzgXLu3rHCNrjBMrLEa','x2DLBMvYyxrLu3vTBwfYEq','AM9PBG','y29TCgfJDgvKtwvZC2fNzxm','DxnLCG','zxjYB3i'];a0_0x3302=function(){return _0x19936f;};return a0_0x3302();}function a0_0x2938(_0x3d12e0,_0x3a9e93){_0x3d12e0=_0x3d12e0-0x73;const _0x330299=a0_0x3302();let _0x2938ad=_0x330299[_0x3d12e0];if(a0_0x2938['CytnJE']===undefined){var _0x5e8406=function(_0x20ac03){const _0x1b6071='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x2f7bf5='',_0x7126ff='';for(let _0x4c9224=0x0,_0xe2c78,_0x5b0f2f,_0x3da8b9=0x0;_0x5b0f2f=_0x20ac03['charAt'](_0x3da8b9++);~_0x5b0f2f&&(_0xe2c78=_0x4c9224%0x4?_0xe2c78*0x40+_0x5b0f2f:_0x5b0f2f,_0x4c9224++%0x4)?_0x2f7bf5+=String['fromCharCode'](0xff&_0xe2c78>>(-0x2*_0x4c9224&0x6)):0x0){_0x5b0f2f=_0x1b6071['indexOf'](_0x5b0f2f);}for(let _0x340450=0x0,_0x316f43=_0x2f7bf5['length'];_0x340450<_0x316f43;_0x340450++){_0x7126ff+='%'+('00'+_0x2f7bf5['charCodeAt'](_0x340450)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x7126ff);};a0_0x2938['QuYTAk']=_0x5e8406,a0_0x2938['jBWvtO']={},a0_0x2938['CytnJE']=!![];}const _0x390c95=_0x330299[0x0],_0x327cdb=_0x3d12e0+_0x390c95,_0x57db10=a0_0x2938['jBWvtO'][_0x327cdb];return!_0x57db10?(_0x2938ad=a0_0x2938['QuYTAk'](_0x2938ad),a0_0x2938['jBWvtO'][_0x327cdb]=_0x2938ad):_0x2938ad=_0x57db10,_0x2938ad;}export default ConversationCompactionService;
|