@codebolt/agent 2.2.2 → 2.2.5
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/dist/builderpattern/agent.js +2 -2
- package/dist/builderpattern/followupquestionbuilder.js +1 -1
- package/dist/builderpattern/llmoutputhandler.js +7 -7
- package/dist/builderpattern/usermessage.d.ts +6 -1
- package/dist/composablepattern/document.js +2 -35
- package/dist/local-tools/fileTools.d.ts +26 -0
- package/dist/local-tools/fileTools.js +162 -0
- package/dist/processor/types/interfaces.d.ts +44 -21
- package/dist/processor-pieces/additionalModifiers/argumentProcessorModifier.d.ts +13 -0
- package/dist/processor-pieces/additionalModifiers/argumentProcessorModifier.js +68 -0
- package/dist/processor-pieces/additionalModifiers/atFileProcessorModifier.d.ts +15 -0
- package/dist/processor-pieces/additionalModifiers/atFileProcessorModifier.js +212 -0
- package/dist/processor-pieces/additionalModifiers/chatCompressionModifier.d.ts +19 -0
- package/dist/processor-pieces/additionalModifiers/chatCompressionModifier.js +110 -0
- package/dist/processor-pieces/additionalModifiers/chatRecordingModifier.d.ts +23 -0
- package/dist/processor-pieces/additionalModifiers/chatRecordingModifier.js +173 -0
- package/dist/processor-pieces/additionalModifiers/coreSystemPromptModifier.d.ts +14 -0
- package/dist/processor-pieces/additionalModifiers/coreSystemPromptModifier.js +93 -0
- package/dist/processor-pieces/additionalModifiers/directoryContextModifier.d.ts +30 -0
- package/dist/processor-pieces/additionalModifiers/directoryContextModifier.js +330 -0
- package/dist/processor-pieces/additionalModifiers/environmentContextModifier.d.ts +26 -0
- package/dist/processor-pieces/additionalModifiers/environmentContextModifier.js +269 -0
- package/dist/processor-pieces/additionalModifiers/fallbackHandlerModifier.d.ts +38 -0
- package/dist/processor-pieces/additionalModifiers/fallbackHandlerModifier.js +217 -0
- package/dist/processor-pieces/additionalModifiers/ideContextModifier.d.ts +34 -0
- package/dist/processor-pieces/additionalModifiers/ideContextModifier.js +147 -0
- package/dist/processor-pieces/additionalModifiers/index.d.ts +12 -0
- package/dist/processor-pieces/additionalModifiers/index.js +28 -0
- package/dist/processor-pieces/additionalModifiers/loopDetectionModifier.d.ts +29 -0
- package/dist/processor-pieces/additionalModifiers/loopDetectionModifier.js +155 -0
- package/dist/processor-pieces/additionalModifiers/memoryImportModifier.d.ts +15 -0
- package/dist/processor-pieces/additionalModifiers/memoryImportModifier.js +129 -0
- package/dist/processor-pieces/additionalModifiers/shellProcessorModifier.d.ts +25 -0
- package/dist/processor-pieces/additionalModifiers/shellProcessorModifier.js +169 -0
- package/dist/processor-pieces/additionalModifiers/toolInjectionModifier.d.ts +20 -0
- package/dist/processor-pieces/additionalModifiers/toolInjectionModifier.js +152 -0
- package/dist/processor-pieces/messageModifiers/addCurrentDirectoryRootFilesModifier.d.ts +7 -0
- package/dist/processor-pieces/messageModifiers/addCurrentDirectoryRootFilesModifier.js +93 -0
- package/dist/processor-pieces/messageModifiers/addToolsListMessageModifier.d.ts +14 -5
- package/dist/processor-pieces/messageModifiers/addToolsListMessageModifier.js +41 -40
- package/dist/processor-pieces/messageModifiers/advancedSystemInstructionMessageModifier.d.ts +9 -0
- package/dist/processor-pieces/messageModifiers/advancedSystemInstructionMessageModifier.js +77 -0
- package/dist/processor-pieces/messageModifiers/atFileProcessorModifier.js +5 -5
- package/dist/processor-pieces/messageModifiers/baseContextMessageModifier.d.ts +5 -13
- package/dist/processor-pieces/messageModifiers/baseContextMessageModifier.js +50 -58
- package/dist/processor-pieces/messageModifiers/baseSystemInstructionMessageModifier.d.ts +6 -8
- package/dist/processor-pieces/messageModifiers/baseSystemInstructionMessageModifier.js +66 -22
- package/dist/processor-pieces/messageModifiers/chatCompressionModifier.d.ts +19 -0
- package/dist/processor-pieces/messageModifiers/chatCompressionModifier.js +110 -0
- package/dist/processor-pieces/messageModifiers/chatHistoryMessageModifier.example.d.ts +20 -0
- package/dist/processor-pieces/messageModifiers/chatHistoryMessageModifier.example.js +124 -0
- package/dist/processor-pieces/messageModifiers/environmentContext.d.ts +41 -0
- package/dist/processor-pieces/messageModifiers/environmentContext.js +355 -0
- package/dist/processor-pieces/messageModifiers/handleUrlMessageModifier.d.ts +3 -2
- package/dist/processor-pieces/messageModifiers/handleUrlMessageModifier.js +1 -2
- package/dist/processor-pieces/messageModifiers/imageAttachmentMessageModifier.d.ts +3 -2
- package/dist/processor-pieces/messageModifiers/imageAttachmentMessageModifier.js +1 -2
- package/dist/processor-pieces/messageModifiers/mentionedFilesModifier.d.ts +23 -0
- package/dist/processor-pieces/messageModifiers/mentionedFilesModifier.js +207 -0
- package/dist/processor-pieces/messageModifiers/simpleMessageModifier.d.ts +7 -0
- package/dist/processor-pieces/messageModifiers/simpleMessageModifier.js +26 -0
- package/dist/processor-pieces/messageModifiers/workingDirectoryMessageModifier.d.ts +18 -2
- package/dist/processor-pieces/messageModifiers/workingDirectoryMessageModifier.js +291 -93
- package/dist/processor-pieces/postInference/llmOutputValidityProcessor.d.ts +1 -0
- package/dist/processor-pieces/postInference/llmOutputValidityProcessor.js +2 -0
- package/dist/processor-pieces/postInferenceProcessors/checkForNoToolCall.d.ts +7 -0
- package/dist/processor-pieces/postInferenceProcessors/checkForNoToolCall.js +24 -0
- package/dist/processor-pieces/postToolCall/advancedLoopDetectionProcessor.d.ts +41 -0
- package/dist/processor-pieces/postToolCall/advancedLoopDetectionProcessor.js +197 -0
- package/dist/processor-pieces/postToolCall/chatCompressionProcessor.d.ts +26 -0
- package/dist/processor-pieces/postToolCall/chatCompressionProcessor.js +90 -0
- package/dist/processor-pieces/postToolCall/chatRecordingProcessor.d.ts +81 -0
- package/dist/processor-pieces/postToolCall/chatRecordingProcessor.js +329 -0
- package/dist/processor-pieces/postToolCall/contextManagementProcessor.d.ts +40 -0
- package/dist/processor-pieces/postToolCall/contextManagementProcessor.js +272 -0
- package/dist/processor-pieces/postToolCall/conversationCompactorProcessor.d.ts +49 -0
- package/dist/processor-pieces/postToolCall/conversationCompactorProcessor.js +291 -0
- package/dist/processor-pieces/postToolCall/conversationContinuityProcessor.d.ts +49 -0
- package/dist/processor-pieces/postToolCall/conversationContinuityProcessor.js +293 -0
- package/dist/processor-pieces/postToolCall/followUpConversationProcessor.d.ts +47 -0
- package/dist/processor-pieces/postToolCall/followUpConversationProcessor.js +249 -0
- package/dist/processor-pieces/postToolCall/loopDetectionProcessor.d.ts +30 -0
- package/dist/processor-pieces/postToolCall/loopDetectionProcessor.js +137 -0
- package/dist/processor-pieces/postToolCall/responseValidationProcessor.d.ts +30 -0
- package/dist/processor-pieces/postToolCall/responseValidationProcessor.js +228 -0
- package/dist/processor-pieces/postToolCall/telemetryProcessor.d.ts +99 -0
- package/dist/processor-pieces/postToolCall/telemetryProcessor.js +278 -0
- package/dist/processor-pieces/postToolCall/tokenManagementProcessor.d.ts +37 -0
- package/dist/processor-pieces/postToolCall/tokenManagementProcessor.js +178 -0
- package/dist/processor-pieces/postToolCall/toolExecutionProcessor.d.ts +43 -0
- package/dist/processor-pieces/postToolCall/toolExecutionProcessor.js +207 -0
- package/dist/processor-pieces/preInference/conversationCompactorProcessor.d.ts +52 -0
- package/dist/processor-pieces/preInference/conversationCompactorProcessor.js +264 -0
- package/dist/processor-pieces/preInference/conversationContinuityProcessor.d.ts +49 -0
- package/dist/processor-pieces/preInference/conversationContinuityProcessor.js +293 -0
- package/dist/processor-pieces/preInferenceProcessors/conversationCompaction.d.ts +7 -0
- package/dist/processor-pieces/preInferenceProcessors/conversationCompaction.js +31 -0
- package/dist/processor-pieces/preToolCall/index.d.ts +9 -0
- package/dist/processor-pieces/preToolCall/index.js +18 -0
- package/dist/processor-pieces/preToolCall/localToolInterceptorProcessor.d.ts +58 -0
- package/dist/processor-pieces/preToolCall/localToolInterceptorProcessor.js +444 -0
- package/dist/processor-pieces/preToolCall/toolParameterModifierProcessor.d.ts +44 -0
- package/dist/processor-pieces/preToolCall/toolParameterModifierProcessor.js +367 -0
- package/dist/processor-pieces/preToolCall/toolValidationProcessor.d.ts +58 -0
- package/dist/processor-pieces/preToolCall/toolValidationProcessor.js +391 -0
- package/dist/unified/agent/agent.js +2 -2
- package/dist/unified/agent/tool.d.ts +99 -0
- package/dist/unified/agent/tool.js +440 -0
- package/dist/unified/base/initialPromptGenerator.js +5 -5
- package/dist/unified/base/responseExecutor.js +6 -6
- package/dist/unified/examples/agentExample.d.ts +46 -0
- package/dist/unified/examples/agentExample.js +464 -0
- package/dist/unified/examples/documentationPatternExample.d.ts +10 -0
- package/dist/unified/examples/documentationPatternExample.js +385 -0
- package/dist/unified/examples/followUpProcessorsExample.d.ts +45 -0
- package/dist/unified/examples/followUpProcessorsExample.js +311 -0
- package/dist/unified/examples/orchestratorExample.d.ts +16 -0
- package/dist/unified/examples/orchestratorExample.js +415 -0
- package/dist/unified/examples/preToolCallProcessorsExample.d.ts +36 -0
- package/dist/unified/examples/preToolCallProcessorsExample.js +458 -0
- package/dist/unified/examples/workflowExample.d.ts +12 -0
- package/dist/unified/examples/workflowExample.js +497 -0
- package/dist/unified/orchestrator/orchestrator.d.ts +260 -0
- package/dist/unified/orchestrator/orchestrator.js +519 -0
- package/package.json +5 -5
- package/dist/agent.d.ts +0 -86
- package/dist/agent.js +0 -324
- package/dist/followupquestionbuilder.d.ts +0 -75
- package/dist/followupquestionbuilder.js +0 -197
- package/dist/index.d.ts +0 -14
- package/dist/index.js +0 -23
- package/dist/llmoutputhandler.d.ts +0 -102
- package/dist/llmoutputhandler.js +0 -452
- package/dist/promptbuilder.d.ts +0 -382
- package/dist/promptbuilder.js +0 -805
- package/dist/systemprompt.d.ts +0 -20
- package/dist/systemprompt.js +0 -48
- package/dist/taskInstruction.d.ts +0 -37
- package/dist/taskInstruction.js +0 -57
- package/dist/usermessage.d.ts +0 -70
- package/dist/usermessage.js +0 -123
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AdvancedLoopDetectionProcessor = void 0;
|
|
4
|
+
const processor_1 = require("../../processor");
|
|
5
|
+
const crypto_1 = require("crypto");
|
|
6
|
+
class AdvancedLoopDetectionProcessor extends processor_1.BaseProcessor {
|
|
7
|
+
constructor(options = {}) {
|
|
8
|
+
super();
|
|
9
|
+
// Tool call tracking
|
|
10
|
+
this.lastToolCallKey = null;
|
|
11
|
+
this.toolCallRepetitionCount = 0;
|
|
12
|
+
// Content streaming tracking
|
|
13
|
+
this.streamContentHistory = '';
|
|
14
|
+
this.contentStats = new Map();
|
|
15
|
+
this.lastContentIndex = 0;
|
|
16
|
+
this.loopDetected = false;
|
|
17
|
+
this.inCodeBlock = false;
|
|
18
|
+
// Turn tracking
|
|
19
|
+
this.turnsInCurrentPrompt = 0;
|
|
20
|
+
this.lastCheckTurn = 0;
|
|
21
|
+
this.toolCallThreshold = options.toolCallThreshold || 5;
|
|
22
|
+
this.contentLoopThreshold = options.contentLoopThreshold || 10;
|
|
23
|
+
this.contentChunkSize = options.contentChunkSize || 50;
|
|
24
|
+
this.maxHistoryLength = options.maxHistoryLength || 1000;
|
|
25
|
+
this.enableLLMDetection = options.enableLLMDetection || false;
|
|
26
|
+
this.llmCheckAfterTurns = options.llmCheckAfterTurns || 30;
|
|
27
|
+
this.defaultLLMCheckInterval = options.defaultLLMCheckInterval || 3;
|
|
28
|
+
this.llmCheckInterval = this.defaultLLMCheckInterval;
|
|
29
|
+
}
|
|
30
|
+
async processInput(input) {
|
|
31
|
+
const { message, context } = input;
|
|
32
|
+
// Increment turn counter
|
|
33
|
+
this.turnsInCurrentPrompt++;
|
|
34
|
+
// Check for tool call loops in the last message
|
|
35
|
+
const lastMessage = message.messages[message.messages.length - 1];
|
|
36
|
+
if (lastMessage.tool_calls && lastMessage.tool_calls.length > 0) {
|
|
37
|
+
for (const toolCall of lastMessage.tool_calls) {
|
|
38
|
+
const isLoop = this.checkToolCallLoop({
|
|
39
|
+
name: toolCall.function.name,
|
|
40
|
+
args: typeof toolCall.function.arguments === 'string'
|
|
41
|
+
? JSON.parse(toolCall.function.arguments)
|
|
42
|
+
: toolCall.function.arguments
|
|
43
|
+
});
|
|
44
|
+
if (isLoop) {
|
|
45
|
+
this.loopDetected = true;
|
|
46
|
+
return [this.createEvent('LoopDetected', {
|
|
47
|
+
type: 'tool_call_loop',
|
|
48
|
+
toolCall: toolCall.function.name,
|
|
49
|
+
repetitionCount: this.toolCallRepetitionCount,
|
|
50
|
+
threshold: this.toolCallThreshold
|
|
51
|
+
})];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Check for content loops
|
|
56
|
+
if (lastMessage.content && typeof lastMessage.content === 'string') {
|
|
57
|
+
const isContentLoop = this.checkContentLoop(lastMessage.content);
|
|
58
|
+
if (isContentLoop) {
|
|
59
|
+
this.loopDetected = true;
|
|
60
|
+
return [this.createEvent('LoopDetected', {
|
|
61
|
+
type: 'content_loop',
|
|
62
|
+
contentLength: this.streamContentHistory.length,
|
|
63
|
+
threshold: this.contentLoopThreshold
|
|
64
|
+
})];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// LLM-based loop detection (if enabled)
|
|
68
|
+
if (this.enableLLMDetection &&
|
|
69
|
+
this.turnsInCurrentPrompt >= this.llmCheckAfterTurns &&
|
|
70
|
+
this.turnsInCurrentPrompt - this.lastCheckTurn >= this.llmCheckInterval) {
|
|
71
|
+
this.lastCheckTurn = this.turnsInCurrentPrompt;
|
|
72
|
+
// For now, just log that LLM check would happen
|
|
73
|
+
// In a real implementation, this would call an LLM to analyze the conversation
|
|
74
|
+
console.log('[AdvancedLoopDetection] LLM-based loop check would be performed here');
|
|
75
|
+
}
|
|
76
|
+
return [this.createEvent('LoopCheckCompleted', {
|
|
77
|
+
loopDetected: this.loopDetected,
|
|
78
|
+
turnsInPrompt: this.turnsInCurrentPrompt,
|
|
79
|
+
toolCallCount: this.toolCallRepetitionCount
|
|
80
|
+
})];
|
|
81
|
+
}
|
|
82
|
+
getToolCallKey(toolCall) {
|
|
83
|
+
const argsString = JSON.stringify(toolCall.args);
|
|
84
|
+
const keyString = `${toolCall.name}:${argsString}`;
|
|
85
|
+
return (0, crypto_1.createHash)('sha256').update(keyString).digest('hex');
|
|
86
|
+
}
|
|
87
|
+
checkToolCallLoop(toolCall) {
|
|
88
|
+
const key = this.getToolCallKey(toolCall);
|
|
89
|
+
if (this.lastToolCallKey === key) {
|
|
90
|
+
this.toolCallRepetitionCount++;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
this.lastToolCallKey = key;
|
|
94
|
+
this.toolCallRepetitionCount = 1;
|
|
95
|
+
}
|
|
96
|
+
return this.toolCallRepetitionCount >= this.toolCallThreshold;
|
|
97
|
+
}
|
|
98
|
+
checkContentLoop(content) {
|
|
99
|
+
var _a;
|
|
100
|
+
// Different content elements can often contain repetitive syntax that is not indicative of a loop.
|
|
101
|
+
// To avoid false positives, we detect when we encounter different content types and
|
|
102
|
+
// reset tracking to avoid analyzing content that spans across different element boundaries.
|
|
103
|
+
const numFences = ((_a = content.match(/```/g)) !== null && _a !== void 0 ? _a : []).length;
|
|
104
|
+
const hasTable = /(^|\n)\s*(\|.*\||[|+-]{3,})/.test(content);
|
|
105
|
+
const hasListItem = /(^|\n)\s*[*-+]\s/.test(content) || /(^|\n)\s*\d+\.\s/.test(content);
|
|
106
|
+
const hasHeading = /(^|\n)#+\s/.test(content);
|
|
107
|
+
const hasBlockquote = /(^|\n)>\s/.test(content);
|
|
108
|
+
if (numFences || hasTable || hasListItem || hasHeading || hasBlockquote) {
|
|
109
|
+
// Reset tracking when different content elements are detected
|
|
110
|
+
this.resetContentTracking();
|
|
111
|
+
}
|
|
112
|
+
const wasInCodeBlock = this.inCodeBlock;
|
|
113
|
+
this.inCodeBlock = numFences % 2 === 0 ? this.inCodeBlock : !this.inCodeBlock;
|
|
114
|
+
if (wasInCodeBlock || this.inCodeBlock) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
this.streamContentHistory += content;
|
|
118
|
+
this.truncateAndUpdate();
|
|
119
|
+
return this.analyzeContentChunksForLoop();
|
|
120
|
+
}
|
|
121
|
+
truncateAndUpdate() {
|
|
122
|
+
if (this.streamContentHistory.length <= this.maxHistoryLength) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const truncationAmount = this.streamContentHistory.length - this.maxHistoryLength;
|
|
126
|
+
this.streamContentHistory = this.streamContentHistory.slice(truncationAmount);
|
|
127
|
+
this.lastContentIndex = Math.max(0, this.lastContentIndex - truncationAmount);
|
|
128
|
+
// Update all stored chunk indices to account for the truncation
|
|
129
|
+
for (const [hash, oldIndices] of this.contentStats.entries()) {
|
|
130
|
+
const adjustedIndices = oldIndices
|
|
131
|
+
.map((index) => index - truncationAmount)
|
|
132
|
+
.filter((index) => index >= 0);
|
|
133
|
+
if (adjustedIndices.length > 0) {
|
|
134
|
+
this.contentStats.set(hash, adjustedIndices);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
this.contentStats.delete(hash);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
analyzeContentChunksForLoop() {
|
|
142
|
+
while (this.hasMoreChunksToProcess()) {
|
|
143
|
+
const currentChunk = this.streamContentHistory.substring(this.lastContentIndex, this.lastContentIndex + this.contentChunkSize);
|
|
144
|
+
const chunkHash = (0, crypto_1.createHash)('sha256').update(currentChunk).digest('hex');
|
|
145
|
+
if (this.isLoopDetectedForChunk(currentChunk, chunkHash)) {
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
this.lastContentIndex++;
|
|
149
|
+
}
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
hasMoreChunksToProcess() {
|
|
153
|
+
return this.lastContentIndex + this.contentChunkSize <= this.streamContentHistory.length;
|
|
154
|
+
}
|
|
155
|
+
isLoopDetectedForChunk(chunk, hash) {
|
|
156
|
+
const existingIndices = this.contentStats.get(hash);
|
|
157
|
+
if (!existingIndices) {
|
|
158
|
+
this.contentStats.set(hash, [this.lastContentIndex]);
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
if (!this.isActualContentMatch(chunk, existingIndices[0])) {
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
existingIndices.push(this.lastContentIndex);
|
|
165
|
+
if (existingIndices.length < this.contentLoopThreshold) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
// Analyze the most recent occurrences to see if they're clustered closely together
|
|
169
|
+
const recentIndices = existingIndices.slice(-this.contentLoopThreshold);
|
|
170
|
+
const totalDistance = recentIndices[recentIndices.length - 1] - recentIndices[0];
|
|
171
|
+
const averageDistance = totalDistance / (this.contentLoopThreshold - 1);
|
|
172
|
+
const maxAllowedDistance = this.contentChunkSize * 1.5;
|
|
173
|
+
return averageDistance <= maxAllowedDistance;
|
|
174
|
+
}
|
|
175
|
+
isActualContentMatch(currentChunk, originalIndex) {
|
|
176
|
+
const originalChunk = this.streamContentHistory.substring(originalIndex, originalIndex + this.contentChunkSize);
|
|
177
|
+
return originalChunk === currentChunk;
|
|
178
|
+
}
|
|
179
|
+
resetContentTracking(resetHistory = true) {
|
|
180
|
+
if (resetHistory) {
|
|
181
|
+
this.streamContentHistory = '';
|
|
182
|
+
}
|
|
183
|
+
this.contentStats.clear();
|
|
184
|
+
this.lastContentIndex = 0;
|
|
185
|
+
}
|
|
186
|
+
reset() {
|
|
187
|
+
this.lastToolCallKey = null;
|
|
188
|
+
this.toolCallRepetitionCount = 0;
|
|
189
|
+
this.resetContentTracking();
|
|
190
|
+
this.turnsInCurrentPrompt = 0;
|
|
191
|
+
this.llmCheckInterval = this.defaultLLMCheckInterval;
|
|
192
|
+
this.lastCheckTurn = 0;
|
|
193
|
+
this.loopDetected = false;
|
|
194
|
+
this.inCodeBlock = false;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
exports.AdvancedLoopDetectionProcessor = AdvancedLoopDetectionProcessor;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { BaseProcessor, ProcessorInput, ProcessorOutput } from '../../processor';
|
|
2
|
+
export interface ChatCompressionInfo {
|
|
3
|
+
originalTokenCount: number;
|
|
4
|
+
newTokenCount: number;
|
|
5
|
+
compressionRatio: number;
|
|
6
|
+
threshold: number;
|
|
7
|
+
}
|
|
8
|
+
export interface ChatCompressionProcessorOptions {
|
|
9
|
+
compressionThreshold?: number;
|
|
10
|
+
compressionPreserveThreshold?: number;
|
|
11
|
+
tokenLimit?: number;
|
|
12
|
+
enableCompression?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare class ChatCompressionProcessor extends BaseProcessor {
|
|
15
|
+
private readonly compressionThreshold;
|
|
16
|
+
private readonly compressionPreserveThreshold;
|
|
17
|
+
private readonly tokenLimit;
|
|
18
|
+
private readonly enableCompression;
|
|
19
|
+
constructor(options?: ChatCompressionProcessorOptions);
|
|
20
|
+
processInput(input: ProcessorInput): Promise<ProcessorOutput[]>;
|
|
21
|
+
private estimateTokenCount;
|
|
22
|
+
setCompressionThreshold(threshold: number): void;
|
|
23
|
+
setTokenLimit(limit: number): void;
|
|
24
|
+
enableCompressionForSession(): void;
|
|
25
|
+
disableCompressionForSession(): void;
|
|
26
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ChatCompressionProcessor = void 0;
|
|
7
|
+
const processor_1 = require("../../processor");
|
|
8
|
+
const codeboltjs_1 = __importDefault(require("@codebolt/codeboltjs"));
|
|
9
|
+
class ChatCompressionProcessor extends processor_1.BaseProcessor {
|
|
10
|
+
constructor(options = {}) {
|
|
11
|
+
super(options);
|
|
12
|
+
this.compressionThreshold = options.compressionThreshold || 0.7;
|
|
13
|
+
this.compressionPreserveThreshold = options.compressionPreserveThreshold || 0.3;
|
|
14
|
+
this.tokenLimit = options.tokenLimit || 128000;
|
|
15
|
+
this.enableCompression = options.enableCompression !== false;
|
|
16
|
+
}
|
|
17
|
+
async processInput(input) {
|
|
18
|
+
try {
|
|
19
|
+
const { message, context } = input;
|
|
20
|
+
if (!this.enableCompression) {
|
|
21
|
+
return [this.createEvent('ChatCompressionDisabled', {
|
|
22
|
+
reason: 'Compression is disabled for this session'
|
|
23
|
+
})];
|
|
24
|
+
}
|
|
25
|
+
// Get chat history from CodeBolt
|
|
26
|
+
const chatHistory = await codeboltjs_1.default.chat.getChatHistory();
|
|
27
|
+
if (chatHistory.length === 0) {
|
|
28
|
+
return [this.createEvent('NoChatHistory', {
|
|
29
|
+
reason: 'No chat history available for compression'
|
|
30
|
+
})];
|
|
31
|
+
}
|
|
32
|
+
// Estimate token count (simple heuristic: 4 chars per token)
|
|
33
|
+
const estimatedTokens = this.estimateTokenCount(chatHistory);
|
|
34
|
+
const threshold = this.compressionThreshold * this.tokenLimit;
|
|
35
|
+
console.log(`[Compression] Estimated tokens: ${estimatedTokens}, threshold: ${threshold}`);
|
|
36
|
+
if (estimatedTokens < threshold) {
|
|
37
|
+
return [this.createEvent('ChatCompressionSkipped', {
|
|
38
|
+
estimatedTokens,
|
|
39
|
+
threshold,
|
|
40
|
+
reason: 'Below compression threshold'
|
|
41
|
+
})];
|
|
42
|
+
}
|
|
43
|
+
// Perform compression using CodeBolt's chatSummary
|
|
44
|
+
const compressionResult = await codeboltjs_1.default.chatSummary.summarizeAll();
|
|
45
|
+
if (compressionResult.success && compressionResult.data) {
|
|
46
|
+
const newTokenCount = this.estimateTokenCount(compressionResult.data);
|
|
47
|
+
const compressionInfo = {
|
|
48
|
+
originalTokenCount: estimatedTokens,
|
|
49
|
+
newTokenCount,
|
|
50
|
+
compressionRatio: newTokenCount / estimatedTokens,
|
|
51
|
+
threshold: this.compressionThreshold
|
|
52
|
+
};
|
|
53
|
+
// Send notification about compression
|
|
54
|
+
await codeboltjs_1.default.chat.sendNotificationEvent(`Chat compressed: ${estimatedTokens} → ${newTokenCount} tokens`, 'debug');
|
|
55
|
+
return [this.createEvent('ChatCompressed', compressionInfo)];
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
return [this.createEvent('ChatCompressionFailed', {
|
|
59
|
+
error: compressionResult.message || 'Unknown compression error',
|
|
60
|
+
originalTokenCount: estimatedTokens
|
|
61
|
+
})];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
console.error('Error in ChatCompressionProcessor:', error);
|
|
66
|
+
return [this.createEvent('ChatCompressionError', {
|
|
67
|
+
error: error instanceof Error ? error.message : String(error)
|
|
68
|
+
})];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
estimateTokenCount(data) {
|
|
72
|
+
// Simple heuristic: 4 characters per token
|
|
73
|
+
const totalContent = JSON.stringify(data);
|
|
74
|
+
return Math.ceil(totalContent.length / 4);
|
|
75
|
+
}
|
|
76
|
+
// Public methods for external control
|
|
77
|
+
setCompressionThreshold(threshold) {
|
|
78
|
+
this.compressionThreshold = Math.max(0.1, Math.min(0.9, threshold));
|
|
79
|
+
}
|
|
80
|
+
setTokenLimit(limit) {
|
|
81
|
+
this.tokenLimit = Math.max(1000, limit);
|
|
82
|
+
}
|
|
83
|
+
enableCompressionForSession() {
|
|
84
|
+
this.enableCompression = true;
|
|
85
|
+
}
|
|
86
|
+
disableCompressionForSession() {
|
|
87
|
+
this.enableCompression = false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
exports.ChatCompressionProcessor = ChatCompressionProcessor;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { BaseProcessor, ProcessorInput, ProcessorOutput } from '../../processor';
|
|
2
|
+
export interface ChatRecordingProcessorOptions {
|
|
3
|
+
enableTokenTracking?: boolean;
|
|
4
|
+
exportFormat?: 'json' | 'txt' | 'csv';
|
|
5
|
+
outputDirectory?: string;
|
|
6
|
+
maxFileSize?: number;
|
|
7
|
+
enableCompression?: boolean;
|
|
8
|
+
includeMetadata?: boolean;
|
|
9
|
+
autoExport?: boolean;
|
|
10
|
+
exportInterval?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface TokensSummary {
|
|
13
|
+
input: number;
|
|
14
|
+
output: number;
|
|
15
|
+
cached: number;
|
|
16
|
+
thoughts?: number;
|
|
17
|
+
tool?: number;
|
|
18
|
+
total: number;
|
|
19
|
+
}
|
|
20
|
+
export interface MessageRecord {
|
|
21
|
+
id: string;
|
|
22
|
+
timestamp: string;
|
|
23
|
+
role: string;
|
|
24
|
+
content: string;
|
|
25
|
+
metadata?: Record<string, any>;
|
|
26
|
+
tokens?: TokensSummary;
|
|
27
|
+
toolCalls?: ToolCallRecord[];
|
|
28
|
+
}
|
|
29
|
+
export interface ToolCallRecord {
|
|
30
|
+
id: string;
|
|
31
|
+
name: string;
|
|
32
|
+
args: Record<string, unknown>;
|
|
33
|
+
result?: any;
|
|
34
|
+
status: 'pending' | 'success' | 'error' | 'cancelled';
|
|
35
|
+
timestamp: string;
|
|
36
|
+
executionTime?: number;
|
|
37
|
+
}
|
|
38
|
+
export interface ConversationSession {
|
|
39
|
+
sessionId: string;
|
|
40
|
+
startTime: string;
|
|
41
|
+
endTime?: string;
|
|
42
|
+
messages: MessageRecord[];
|
|
43
|
+
totalTokens: TokensSummary;
|
|
44
|
+
toolCallCount: number;
|
|
45
|
+
metadata: Record<string, any>;
|
|
46
|
+
}
|
|
47
|
+
export declare class ChatRecordingProcessor extends BaseProcessor {
|
|
48
|
+
private readonly enableTokenTracking;
|
|
49
|
+
private readonly exportFormat;
|
|
50
|
+
private readonly outputDirectory;
|
|
51
|
+
private readonly maxFileSize;
|
|
52
|
+
private readonly enableCompression;
|
|
53
|
+
private readonly includeMetadata;
|
|
54
|
+
private readonly autoExport;
|
|
55
|
+
private readonly exportInterval;
|
|
56
|
+
private currentSession;
|
|
57
|
+
private messageCount;
|
|
58
|
+
private sessions;
|
|
59
|
+
constructor(options?: ChatRecordingProcessorOptions);
|
|
60
|
+
processInput(input: ProcessorInput): Promise<ProcessorOutput[]>;
|
|
61
|
+
private initializeSession;
|
|
62
|
+
private createMessageRecord;
|
|
63
|
+
private extractContent;
|
|
64
|
+
private extractToolCalls;
|
|
65
|
+
private estimateTokens;
|
|
66
|
+
private updateSessionTotals;
|
|
67
|
+
private generateSessionId;
|
|
68
|
+
private generateMessageId;
|
|
69
|
+
private generateToolCallId;
|
|
70
|
+
exportSession(session: ConversationSession): Promise<string>;
|
|
71
|
+
private ensureDirectoryExists;
|
|
72
|
+
private formatAsText;
|
|
73
|
+
private formatAsCSV;
|
|
74
|
+
finalizeSession(): Promise<string | null>;
|
|
75
|
+
getCurrentSession(): ConversationSession | null;
|
|
76
|
+
getSessionStats(): {
|
|
77
|
+
currentSessionMessages: number;
|
|
78
|
+
totalSessions: number;
|
|
79
|
+
totalMessages: number;
|
|
80
|
+
};
|
|
81
|
+
}
|