@codebolt/agent 2.2.2 → 2.2.3

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.
Files changed (141) hide show
  1. package/dist/builderpattern/agent.js +2 -2
  2. package/dist/builderpattern/followupquestionbuilder.js +1 -1
  3. package/dist/builderpattern/llmoutputhandler.js +7 -7
  4. package/dist/builderpattern/usermessage.d.ts +6 -1
  5. package/dist/composablepattern/document.js +2 -35
  6. package/dist/local-tools/fileTools.d.ts +26 -0
  7. package/dist/local-tools/fileTools.js +162 -0
  8. package/dist/processor/types/interfaces.d.ts +44 -21
  9. package/dist/processor-pieces/additionalModifiers/argumentProcessorModifier.d.ts +13 -0
  10. package/dist/processor-pieces/additionalModifiers/argumentProcessorModifier.js +68 -0
  11. package/dist/processor-pieces/additionalModifiers/atFileProcessorModifier.d.ts +15 -0
  12. package/dist/processor-pieces/additionalModifiers/atFileProcessorModifier.js +212 -0
  13. package/dist/processor-pieces/additionalModifiers/chatCompressionModifier.d.ts +19 -0
  14. package/dist/processor-pieces/additionalModifiers/chatCompressionModifier.js +110 -0
  15. package/dist/processor-pieces/additionalModifiers/chatRecordingModifier.d.ts +23 -0
  16. package/dist/processor-pieces/additionalModifiers/chatRecordingModifier.js +173 -0
  17. package/dist/processor-pieces/additionalModifiers/coreSystemPromptModifier.d.ts +14 -0
  18. package/dist/processor-pieces/additionalModifiers/coreSystemPromptModifier.js +93 -0
  19. package/dist/processor-pieces/additionalModifiers/directoryContextModifier.d.ts +30 -0
  20. package/dist/processor-pieces/additionalModifiers/directoryContextModifier.js +330 -0
  21. package/dist/processor-pieces/additionalModifiers/environmentContextModifier.d.ts +26 -0
  22. package/dist/processor-pieces/additionalModifiers/environmentContextModifier.js +269 -0
  23. package/dist/processor-pieces/additionalModifiers/fallbackHandlerModifier.d.ts +38 -0
  24. package/dist/processor-pieces/additionalModifiers/fallbackHandlerModifier.js +217 -0
  25. package/dist/processor-pieces/additionalModifiers/ideContextModifier.d.ts +34 -0
  26. package/dist/processor-pieces/additionalModifiers/ideContextModifier.js +147 -0
  27. package/dist/processor-pieces/additionalModifiers/index.d.ts +12 -0
  28. package/dist/processor-pieces/additionalModifiers/index.js +28 -0
  29. package/dist/processor-pieces/additionalModifiers/loopDetectionModifier.d.ts +29 -0
  30. package/dist/processor-pieces/additionalModifiers/loopDetectionModifier.js +155 -0
  31. package/dist/processor-pieces/additionalModifiers/memoryImportModifier.d.ts +15 -0
  32. package/dist/processor-pieces/additionalModifiers/memoryImportModifier.js +129 -0
  33. package/dist/processor-pieces/additionalModifiers/shellProcessorModifier.d.ts +25 -0
  34. package/dist/processor-pieces/additionalModifiers/shellProcessorModifier.js +169 -0
  35. package/dist/processor-pieces/additionalModifiers/toolInjectionModifier.d.ts +20 -0
  36. package/dist/processor-pieces/additionalModifiers/toolInjectionModifier.js +152 -0
  37. package/dist/processor-pieces/messageModifiers/addCurrentDirectoryRootFilesModifier.d.ts +7 -0
  38. package/dist/processor-pieces/messageModifiers/addCurrentDirectoryRootFilesModifier.js +93 -0
  39. package/dist/processor-pieces/messageModifiers/addToolsListMessageModifier.d.ts +14 -5
  40. package/dist/processor-pieces/messageModifiers/addToolsListMessageModifier.js +41 -40
  41. package/dist/processor-pieces/messageModifiers/advancedSystemInstructionMessageModifier.d.ts +9 -0
  42. package/dist/processor-pieces/messageModifiers/advancedSystemInstructionMessageModifier.js +77 -0
  43. package/dist/processor-pieces/messageModifiers/atFileProcessorModifier.js +5 -5
  44. package/dist/processor-pieces/messageModifiers/baseContextMessageModifier.d.ts +5 -13
  45. package/dist/processor-pieces/messageModifiers/baseContextMessageModifier.js +50 -58
  46. package/dist/processor-pieces/messageModifiers/baseSystemInstructionMessageModifier.d.ts +6 -8
  47. package/dist/processor-pieces/messageModifiers/baseSystemInstructionMessageModifier.js +66 -22
  48. package/dist/processor-pieces/messageModifiers/chatCompressionModifier.d.ts +19 -0
  49. package/dist/processor-pieces/messageModifiers/chatCompressionModifier.js +110 -0
  50. package/dist/processor-pieces/messageModifiers/chatHistoryMessageModifier.example.d.ts +20 -0
  51. package/dist/processor-pieces/messageModifiers/chatHistoryMessageModifier.example.js +124 -0
  52. package/dist/processor-pieces/messageModifiers/environmentContext.d.ts +41 -0
  53. package/dist/processor-pieces/messageModifiers/environmentContext.js +355 -0
  54. package/dist/processor-pieces/messageModifiers/handleUrlMessageModifier.d.ts +3 -2
  55. package/dist/processor-pieces/messageModifiers/handleUrlMessageModifier.js +1 -2
  56. package/dist/processor-pieces/messageModifiers/imageAttachmentMessageModifier.d.ts +3 -2
  57. package/dist/processor-pieces/messageModifiers/imageAttachmentMessageModifier.js +1 -2
  58. package/dist/processor-pieces/messageModifiers/mentionedFilesModifier.d.ts +23 -0
  59. package/dist/processor-pieces/messageModifiers/mentionedFilesModifier.js +207 -0
  60. package/dist/processor-pieces/messageModifiers/simpleMessageModifier.d.ts +7 -0
  61. package/dist/processor-pieces/messageModifiers/simpleMessageModifier.js +26 -0
  62. package/dist/processor-pieces/messageModifiers/workingDirectoryMessageModifier.d.ts +18 -2
  63. package/dist/processor-pieces/messageModifiers/workingDirectoryMessageModifier.js +291 -93
  64. package/dist/processor-pieces/postInference/llmOutputValidityProcessor.d.ts +1 -0
  65. package/dist/processor-pieces/postInference/llmOutputValidityProcessor.js +2 -0
  66. package/dist/processor-pieces/postInferenceProcessors/checkForNoToolCall.d.ts +7 -0
  67. package/dist/processor-pieces/postInferenceProcessors/checkForNoToolCall.js +24 -0
  68. package/dist/processor-pieces/postToolCall/advancedLoopDetectionProcessor.d.ts +41 -0
  69. package/dist/processor-pieces/postToolCall/advancedLoopDetectionProcessor.js +197 -0
  70. package/dist/processor-pieces/postToolCall/chatCompressionProcessor.d.ts +26 -0
  71. package/dist/processor-pieces/postToolCall/chatCompressionProcessor.js +90 -0
  72. package/dist/processor-pieces/postToolCall/chatRecordingProcessor.d.ts +81 -0
  73. package/dist/processor-pieces/postToolCall/chatRecordingProcessor.js +329 -0
  74. package/dist/processor-pieces/postToolCall/contextManagementProcessor.d.ts +40 -0
  75. package/dist/processor-pieces/postToolCall/contextManagementProcessor.js +272 -0
  76. package/dist/processor-pieces/postToolCall/conversationCompactorProcessor.d.ts +49 -0
  77. package/dist/processor-pieces/postToolCall/conversationCompactorProcessor.js +291 -0
  78. package/dist/processor-pieces/postToolCall/conversationContinuityProcessor.d.ts +49 -0
  79. package/dist/processor-pieces/postToolCall/conversationContinuityProcessor.js +293 -0
  80. package/dist/processor-pieces/postToolCall/followUpConversationProcessor.d.ts +47 -0
  81. package/dist/processor-pieces/postToolCall/followUpConversationProcessor.js +249 -0
  82. package/dist/processor-pieces/postToolCall/loopDetectionProcessor.d.ts +30 -0
  83. package/dist/processor-pieces/postToolCall/loopDetectionProcessor.js +137 -0
  84. package/dist/processor-pieces/postToolCall/responseValidationProcessor.d.ts +30 -0
  85. package/dist/processor-pieces/postToolCall/responseValidationProcessor.js +228 -0
  86. package/dist/processor-pieces/postToolCall/telemetryProcessor.d.ts +99 -0
  87. package/dist/processor-pieces/postToolCall/telemetryProcessor.js +278 -0
  88. package/dist/processor-pieces/postToolCall/tokenManagementProcessor.d.ts +37 -0
  89. package/dist/processor-pieces/postToolCall/tokenManagementProcessor.js +178 -0
  90. package/dist/processor-pieces/postToolCall/toolExecutionProcessor.d.ts +43 -0
  91. package/dist/processor-pieces/postToolCall/toolExecutionProcessor.js +207 -0
  92. package/dist/processor-pieces/preInference/conversationCompactorProcessor.d.ts +52 -0
  93. package/dist/processor-pieces/preInference/conversationCompactorProcessor.js +264 -0
  94. package/dist/processor-pieces/preInference/conversationContinuityProcessor.d.ts +49 -0
  95. package/dist/processor-pieces/preInference/conversationContinuityProcessor.js +293 -0
  96. package/dist/processor-pieces/preInferenceProcessors/conversationCompaction.d.ts +7 -0
  97. package/dist/processor-pieces/preInferenceProcessors/conversationCompaction.js +31 -0
  98. package/dist/processor-pieces/preToolCall/index.d.ts +9 -0
  99. package/dist/processor-pieces/preToolCall/index.js +18 -0
  100. package/dist/processor-pieces/preToolCall/localToolInterceptorProcessor.d.ts +58 -0
  101. package/dist/processor-pieces/preToolCall/localToolInterceptorProcessor.js +444 -0
  102. package/dist/processor-pieces/preToolCall/toolParameterModifierProcessor.d.ts +44 -0
  103. package/dist/processor-pieces/preToolCall/toolParameterModifierProcessor.js +367 -0
  104. package/dist/processor-pieces/preToolCall/toolValidationProcessor.d.ts +58 -0
  105. package/dist/processor-pieces/preToolCall/toolValidationProcessor.js +391 -0
  106. package/dist/unified/agent/agent.js +2 -2
  107. package/dist/unified/agent/tool.d.ts +99 -0
  108. package/dist/unified/agent/tool.js +440 -0
  109. package/dist/unified/base/initialPromptGenerator.js +5 -5
  110. package/dist/unified/base/responseExecutor.js +6 -6
  111. package/dist/unified/examples/agentExample.d.ts +46 -0
  112. package/dist/unified/examples/agentExample.js +464 -0
  113. package/dist/unified/examples/documentationPatternExample.d.ts +10 -0
  114. package/dist/unified/examples/documentationPatternExample.js +385 -0
  115. package/dist/unified/examples/followUpProcessorsExample.d.ts +45 -0
  116. package/dist/unified/examples/followUpProcessorsExample.js +311 -0
  117. package/dist/unified/examples/orchestratorExample.d.ts +16 -0
  118. package/dist/unified/examples/orchestratorExample.js +415 -0
  119. package/dist/unified/examples/preToolCallProcessorsExample.d.ts +36 -0
  120. package/dist/unified/examples/preToolCallProcessorsExample.js +458 -0
  121. package/dist/unified/examples/workflowExample.d.ts +12 -0
  122. package/dist/unified/examples/workflowExample.js +497 -0
  123. package/dist/unified/orchestrator/orchestrator.d.ts +260 -0
  124. package/dist/unified/orchestrator/orchestrator.js +519 -0
  125. package/package.json +15 -15
  126. package/dist/agent.d.ts +0 -86
  127. package/dist/agent.js +0 -324
  128. package/dist/followupquestionbuilder.d.ts +0 -75
  129. package/dist/followupquestionbuilder.js +0 -197
  130. package/dist/index.d.ts +0 -14
  131. package/dist/index.js +0 -23
  132. package/dist/llmoutputhandler.d.ts +0 -102
  133. package/dist/llmoutputhandler.js +0 -452
  134. package/dist/promptbuilder.d.ts +0 -382
  135. package/dist/promptbuilder.js +0 -805
  136. package/dist/systemprompt.d.ts +0 -20
  137. package/dist/systemprompt.js +0 -48
  138. package/dist/taskInstruction.d.ts +0 -37
  139. package/dist/taskInstruction.js +0 -57
  140. package/dist/usermessage.d.ts +0 -70
  141. package/dist/usermessage.js +0 -123
@@ -0,0 +1,207 @@
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.ToolExecutionProcessor = void 0;
7
+ const processor_1 = require("../../processor");
8
+ const codeboltjs_1 = __importDefault(require("@codebolt/codeboltjs"));
9
+ class ToolExecutionProcessor extends processor_1.BaseProcessor {
10
+ constructor(options = {}) {
11
+ super(options);
12
+ this.executedTools = new Map();
13
+ this.enableToolConfirmation = options.enableToolConfirmation !== false;
14
+ this.maxRetries = options.maxRetries || 3;
15
+ this.retryDelay = options.retryDelay || 1000;
16
+ this.enableLogging = options.enableLogging !== false;
17
+ }
18
+ async processInput(input) {
19
+ try {
20
+ const { message, context } = input;
21
+ // Check if message contains tool calls
22
+ const toolCalls = this.extractToolCalls(message);
23
+ if (toolCalls.length === 0) {
24
+ return [this.createEvent('NoToolCalls', {
25
+ reason: 'No tool calls found in message'
26
+ })];
27
+ }
28
+ const events = [
29
+ this.createEvent('ToolCallsDetected', {
30
+ count: toolCalls.length,
31
+ tools: toolCalls.map(tc => tc.function.name)
32
+ })
33
+ ];
34
+ // Process each tool call
35
+ for (const toolCall of toolCalls) {
36
+ const executionInfo = await this.processToolCall(toolCall, context);
37
+ if (executionInfo.needsConfirmation) {
38
+ events.push(this.createEvent('ToolConfirmationRequired', executionInfo));
39
+ }
40
+ else {
41
+ const result = await this.executeTool(executionInfo);
42
+ events.push(this.createEvent('ToolExecuted', result));
43
+ }
44
+ }
45
+ // Add summary event
46
+ events.push(this.createEvent('ToolExecutionSummary', {
47
+ totalTools: toolCalls.length,
48
+ executedTools: Array.from(this.executedTools.values()),
49
+ successRate: this.calculateSuccessRate()
50
+ }));
51
+ return events;
52
+ }
53
+ catch (error) {
54
+ console.error('Error in ToolExecutionProcessor:', error);
55
+ return [this.createEvent('ToolExecutionError', {
56
+ error: error instanceof Error ? error.message : String(error)
57
+ })];
58
+ }
59
+ }
60
+ extractToolCalls(message) {
61
+ const toolCalls = [];
62
+ message.messages.forEach((msg) => {
63
+ if (msg.tool_calls && Array.isArray(msg.tool_calls)) {
64
+ toolCalls.push(...msg.tool_calls);
65
+ }
66
+ });
67
+ return toolCalls;
68
+ }
69
+ async processToolCall(toolCall, context) {
70
+ const [toolbox, toolName] = toolCall.function.name.split('--');
71
+ if (!toolbox || !toolName) {
72
+ throw new Error(`Invalid tool name format: ${toolCall.function.name}`);
73
+ }
74
+ // Parse tool arguments
75
+ let parameters = {};
76
+ try {
77
+ parameters = typeof toolCall.function.arguments === 'string'
78
+ ? JSON.parse(toolCall.function.arguments)
79
+ : toolCall.function.arguments;
80
+ }
81
+ catch (error) {
82
+ console.warn(`Failed to parse tool arguments for ${toolCall.function.name}:`, error);
83
+ }
84
+ // Check if tool needs confirmation
85
+ const needsConfirmation = this.shouldConfirmTool(toolCall, parameters);
86
+ return {
87
+ toolCall,
88
+ toolName,
89
+ toolbox,
90
+ parameters,
91
+ needsConfirmation
92
+ };
93
+ }
94
+ shouldConfirmTool(toolCall, parameters) {
95
+ // Check for dangerous operations
96
+ const dangerousOperations = [
97
+ 'delete', 'remove', 'drop', 'destroy', 'format', 'wipe',
98
+ 'shutdown', 'restart', 'kill', 'terminate'
99
+ ];
100
+ const toolName = toolCall.function.name.toLowerCase();
101
+ const hasDangerousOperation = dangerousOperations.some(op => toolName.includes(op));
102
+ // Check for file system operations with important paths
103
+ if (parameters.filePath || parameters.path) {
104
+ const path = (parameters.filePath || parameters.path || '').toLowerCase();
105
+ const importantPaths = ['/', 'c:', 'system', 'windows', 'etc', 'usr'];
106
+ const hasImportantPath = importantPaths.some(ip => path.includes(ip));
107
+ if (hasImportantPath) {
108
+ return true;
109
+ }
110
+ }
111
+ // Check for network operations
112
+ if (parameters.url || parameters.host || parameters.port) {
113
+ return true;
114
+ }
115
+ return hasDangerousOperation;
116
+ }
117
+ async executeTool(executionInfo) {
118
+ const startTime = Date.now();
119
+ const { toolCall, toolbox, toolName, parameters } = executionInfo;
120
+ try {
121
+ // Execute tool using CodeBolt's MCP
122
+ const { data } = await codeboltjs_1.default.mcp.executeTool(toolbox, toolName, parameters);
123
+ // Data comes as [failure: boolean, content: string] from CodeBolt MCP
124
+ let resultData;
125
+ let success = true;
126
+ if (Array.isArray(data) && data.length >= 2) {
127
+ const [failure, content] = data;
128
+ if (failure) {
129
+ success = false;
130
+ resultData = content; // Content is error message on failure
131
+ }
132
+ else {
133
+ resultData = content; // Content is result on success
134
+ }
135
+ }
136
+ else {
137
+ // Fallback for unexpected data format
138
+ console.warn(`[Tool] Unexpected data format from ${toolCall.function.name}:`, data);
139
+ resultData = data;
140
+ }
141
+ const executionResult = {
142
+ toolCallId: toolCall.id,
143
+ result: resultData,
144
+ success: success,
145
+ executionTime: Date.now() - startTime,
146
+ error: success ? undefined : String(resultData)
147
+ };
148
+ // Store result
149
+ this.executedTools.set(toolCall.id, executionResult);
150
+ // Log execution if enabled
151
+ if (this.enableLogging) {
152
+ console.log(`[Tool] Successfully executed ${toolbox}--${toolName} in ${executionResult.executionTime}ms`);
153
+ }
154
+ return executionResult;
155
+ }
156
+ catch (error) {
157
+ const executionResult = {
158
+ toolCallId: toolCall.id,
159
+ result: null,
160
+ error: error instanceof Error ? error.message : String(error),
161
+ success: false,
162
+ executionTime: Date.now() - startTime
163
+ };
164
+ // Store result
165
+ this.executedTools.set(toolCall.id, executionResult);
166
+ // Log error if enabled
167
+ if (this.enableLogging) {
168
+ console.error(`[Tool] Failed to execute ${toolbox}--${toolName}:`, error);
169
+ }
170
+ return executionResult;
171
+ }
172
+ }
173
+ calculateSuccessRate() {
174
+ if (this.executedTools.size === 0)
175
+ return 0;
176
+ const successfulTools = Array.from(this.executedTools.values())
177
+ .filter(result => result.success).length;
178
+ return (successfulTools / this.executedTools.size) * 100;
179
+ }
180
+ // Public methods for external control
181
+ async confirmToolExecution(toolCallId, confirmed) {
182
+ // This method can be used to track confirmation status in the future
183
+ // For now, we'll just log the confirmation
184
+ if (this.enableLogging) {
185
+ console.log(`[ToolExecutor] Tool ${toolCallId} confirmation: ${confirmed}`);
186
+ }
187
+ }
188
+ getToolExecutionHistory() {
189
+ return Array.from(this.executedTools.values());
190
+ }
191
+ clearToolHistory() {
192
+ this.executedTools.clear();
193
+ }
194
+ setMaxRetries(maxRetries) {
195
+ this.maxRetries = Math.max(1, maxRetries);
196
+ }
197
+ setRetryDelay(delay) {
198
+ this.retryDelay = Math.max(100, delay);
199
+ }
200
+ enableLoggingForSession() {
201
+ this.enableLogging = true;
202
+ }
203
+ disableLoggingForSession() {
204
+ this.enableLogging = false;
205
+ }
206
+ }
207
+ exports.ToolExecutionProcessor = ToolExecutionProcessor;
@@ -0,0 +1,52 @@
1
+ import { BaseProcessor, ProcessorInput, ProcessorOutput } from '../types/processorTypes';
2
+ export interface ConversationCompactorInfo {
3
+ originalMessageCount: number;
4
+ compactedMessageCount: number;
5
+ compressionRatio: number;
6
+ compactionMethod: 'summarization' | 'truncation' | 'smart_removal';
7
+ preservedMessages: number;
8
+ removedMessages: number;
9
+ }
10
+ export interface ConversationCompactorProcessorOptions {
11
+ maxConversationLength?: number;
12
+ compactionThreshold?: number;
13
+ preserveRecentMessages?: number;
14
+ preserveSystemMessages?: boolean;
15
+ preserveToolMessages?: boolean;
16
+ enableSummarization?: boolean;
17
+ enableSmartRemoval?: boolean;
18
+ compressionRatio?: number;
19
+ }
20
+ /**
21
+ * Processor that compacts long conversations to keep them within manageable limits
22
+ * while preserving important context and recent interactions.
23
+ */
24
+ export declare class ConversationCompactorProcessor extends BaseProcessor {
25
+ private readonly maxConversationLength;
26
+ private readonly compactionThreshold;
27
+ private readonly preserveRecentMessages;
28
+ private readonly preserveSystemMessages;
29
+ private readonly preserveToolMessages;
30
+ private readonly enableSummarization;
31
+ private readonly enableSmartRemoval;
32
+ private readonly compressionRatio;
33
+ constructor(options?: ConversationCompactorProcessorOptions);
34
+ processInput(input: ProcessorInput): Promise<ProcessorOutput[]>;
35
+ private shouldCompactConversation;
36
+ private compactConversation;
37
+ private compactWithSummarization;
38
+ private compactWithSmartRemoval;
39
+ private compactWithTruncation;
40
+ private calculateMessageImportance;
41
+ getMaxConversationLength(): number;
42
+ getCompactionThreshold(): number;
43
+ isCompactionNeeded(messageCount: number): boolean;
44
+ getCompressionRatio(): number;
45
+ getProcessorStats(): {
46
+ maxLength: number;
47
+ threshold: number;
48
+ preserveRecent: number;
49
+ compressionRatio: number;
50
+ enabledFeatures: string[];
51
+ };
52
+ }
@@ -0,0 +1,264 @@
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.ConversationCompactorProcessor = void 0;
7
+ const processorTypes_1 = require("../types/processorTypes");
8
+ const codeboltjs_1 = __importDefault(require("@codebolt/codeboltjs"));
9
+ const { chatSummary } = codeboltjs_1.default;
10
+ /**
11
+ * Processor that compacts long conversations to keep them within manageable limits
12
+ * while preserving important context and recent interactions.
13
+ */
14
+ class ConversationCompactorProcessor extends processorTypes_1.BaseProcessor {
15
+ constructor(options = {}) {
16
+ super(options);
17
+ this.maxConversationLength = options.maxConversationLength || 50;
18
+ this.compactionThreshold = options.compactionThreshold || 0.8; // Compact when 80% of max length
19
+ this.preserveRecentMessages = options.preserveRecentMessages || 10;
20
+ this.preserveSystemMessages = options.preserveSystemMessages !== false;
21
+ this.preserveToolMessages = options.preserveToolMessages !== false;
22
+ this.enableSummarization = options.enableSummarization !== false;
23
+ this.enableSmartRemoval = options.enableSmartRemoval !== false;
24
+ this.compressionRatio = options.compressionRatio || 0.6; // Target 60% of original size
25
+ }
26
+ async processInput(input) {
27
+ try {
28
+ const { message, context } = input;
29
+ const messages = message.messages;
30
+ // Check if compaction is needed
31
+ const needsCompaction = this.shouldCompactConversation(messages);
32
+ if (!needsCompaction) {
33
+ return [this.createEvent('ConversationCompactionSkipped', {
34
+ reason: 'Conversation length within limits',
35
+ messageCount: messages.length,
36
+ maxLength: this.maxConversationLength
37
+ })];
38
+ }
39
+ // Perform compaction
40
+ const compactionResult = await this.compactConversation(messages, context);
41
+ // Update the message with compacted conversation
42
+ const compactedMessage = {
43
+ messages: compactionResult.compactedMessages,
44
+ metadata: {
45
+ ...message.metadata,
46
+ compactionInfo: compactionResult.info
47
+ }
48
+ };
49
+ return [
50
+ this.createEvent('ConversationCompacted', compactionResult.info),
51
+ this.createEvent('MessageModified', {
52
+ originalMessageCount: messages.length,
53
+ newMessageCount: compactionResult.compactedMessages.length,
54
+ compactedMessage
55
+ })
56
+ ];
57
+ }
58
+ catch (error) {
59
+ console.error('Error in ConversationCompactorProcessor:', error);
60
+ return [this.createEvent('ConversationCompactionError', {
61
+ error: error instanceof Error ? error.message : String(error)
62
+ })];
63
+ }
64
+ }
65
+ shouldCompactConversation(messages) {
66
+ const threshold = Math.floor(this.maxConversationLength * this.compactionThreshold);
67
+ return messages.length >= threshold;
68
+ }
69
+ async compactConversation(messages, context) {
70
+ const originalCount = messages.length;
71
+ let compactedMessages;
72
+ let compactionMethod;
73
+ // Determine the best compaction method
74
+ if (this.enableSummarization && originalCount > this.preserveRecentMessages * 2) {
75
+ compactionMethod = 'summarization';
76
+ compactedMessages = await this.compactWithSummarization(messages);
77
+ }
78
+ else if (this.enableSmartRemoval) {
79
+ compactionMethod = 'smart_removal';
80
+ compactedMessages = this.compactWithSmartRemoval(messages);
81
+ }
82
+ else {
83
+ compactionMethod = 'truncation';
84
+ compactedMessages = this.compactWithTruncation(messages);
85
+ }
86
+ const compactedCount = compactedMessages.length;
87
+ const info = {
88
+ originalMessageCount: originalCount,
89
+ compactedMessageCount: compactedCount,
90
+ compressionRatio: compactedCount / originalCount,
91
+ compactionMethod,
92
+ preservedMessages: compactedCount,
93
+ removedMessages: originalCount - compactedCount
94
+ };
95
+ return { compactedMessages, info };
96
+ }
97
+ async compactWithSummarization(messages) {
98
+ // Separate messages into categories
99
+ const systemMessages = messages.filter(m => m.role === 'system');
100
+ const recentMessages = messages.slice(-this.preserveRecentMessages);
101
+ const middleMessages = messages.slice(systemMessages.length, messages.length - this.preserveRecentMessages);
102
+ if (middleMessages.length === 0) {
103
+ return messages;
104
+ }
105
+ try {
106
+ // Create conversation text for summarization
107
+ const conversationText = middleMessages
108
+ .map(m => `${m.role}: ${typeof m.content === 'string' ? m.content : JSON.stringify(m.content)}`)
109
+ .join('\n');
110
+ // Use codeboltjs chat summary
111
+ const summary = await chatSummary.summarizeConversation(conversationText, {
112
+ maxLength: Math.floor(middleMessages.length * this.compressionRatio),
113
+ preserveImportantDetails: true
114
+ });
115
+ // Create summary message
116
+ const summaryMessage = {
117
+ role: 'system',
118
+ content: `[Conversation Summary]: ${summary}`
119
+ };
120
+ // Combine preserved messages with summary
121
+ return [
122
+ ...systemMessages,
123
+ summaryMessage,
124
+ ...recentMessages
125
+ ];
126
+ }
127
+ catch (error) {
128
+ console.warn('Summarization failed, falling back to smart removal:', error);
129
+ return this.compactWithSmartRemoval(messages);
130
+ }
131
+ }
132
+ compactWithSmartRemoval(messages) {
133
+ // Always preserve system messages
134
+ const systemMessages = messages.filter(m => m.role === 'system');
135
+ const nonSystemMessages = messages.filter(m => m.role !== 'system');
136
+ // Always preserve recent messages
137
+ const recentMessages = nonSystemMessages.slice(-this.preserveRecentMessages);
138
+ const olderMessages = nonSystemMessages.slice(0, -this.preserveRecentMessages);
139
+ if (olderMessages.length === 0) {
140
+ return messages;
141
+ }
142
+ // Calculate target count for older messages
143
+ const targetTotal = Math.floor(this.maxConversationLength * this.compressionRatio);
144
+ const preservedCount = systemMessages.length + recentMessages.length;
145
+ const targetOlderCount = Math.max(0, targetTotal - preservedCount);
146
+ if (targetOlderCount >= olderMessages.length) {
147
+ return messages;
148
+ }
149
+ // Score messages by importance
150
+ const scoredMessages = olderMessages.map((message, index) => ({
151
+ message,
152
+ score: this.calculateMessageImportance(message, index, olderMessages.length)
153
+ }));
154
+ // Sort by score (descending) and take top messages
155
+ scoredMessages.sort((a, b) => b.score - a.score);
156
+ const selectedOlderMessages = scoredMessages
157
+ .slice(0, targetOlderCount)
158
+ .map(item => item.message);
159
+ // Maintain chronological order
160
+ const selectedIndices = new Set(selectedOlderMessages.map(msg => olderMessages.indexOf(msg)));
161
+ const chronologicalOlderMessages = olderMessages.filter((_, index) => selectedIndices.has(index));
162
+ return [
163
+ ...systemMessages,
164
+ ...chronologicalOlderMessages,
165
+ ...recentMessages
166
+ ];
167
+ }
168
+ compactWithTruncation(messages) {
169
+ const targetCount = Math.floor(this.maxConversationLength * this.compressionRatio);
170
+ if (messages.length <= targetCount) {
171
+ return messages;
172
+ }
173
+ // Preserve system messages and recent messages
174
+ const systemMessages = messages.filter(m => m.role === 'system');
175
+ const nonSystemMessages = messages.filter(m => m.role !== 'system');
176
+ const recentCount = Math.min(this.preserveRecentMessages, nonSystemMessages.length);
177
+ const recentMessages = nonSystemMessages.slice(-recentCount);
178
+ const availableForOlder = targetCount - systemMessages.length - recentMessages.length;
179
+ if (availableForOlder <= 0) {
180
+ return [...systemMessages, ...recentMessages];
181
+ }
182
+ const olderMessages = nonSystemMessages.slice(0, -recentCount);
183
+ const selectedOlderMessages = olderMessages.slice(-availableForOlder);
184
+ return [
185
+ ...systemMessages,
186
+ ...selectedOlderMessages,
187
+ ...recentMessages
188
+ ];
189
+ }
190
+ calculateMessageImportance(message, index, totalCount) {
191
+ let score = 0;
192
+ // Base score for message type
193
+ switch (message.role) {
194
+ case 'system':
195
+ score += 100; // Highest priority
196
+ break;
197
+ case 'assistant':
198
+ score += 50;
199
+ break;
200
+ case 'user':
201
+ score += 40;
202
+ break;
203
+ case 'tool':
204
+ score += this.preserveToolMessages ? 60 : 20;
205
+ break;
206
+ }
207
+ // Boost score for messages with tool calls
208
+ if (message.tool_calls && message.tool_calls.length > 0) {
209
+ score += 30;
210
+ }
211
+ // Boost score for longer messages (more content)
212
+ const contentLength = typeof message.content === 'string'
213
+ ? message.content.length
214
+ : JSON.stringify(message.content).length;
215
+ score += Math.min(contentLength / 100, 20); // Max 20 points for length
216
+ // Recency bonus (more recent = higher score)
217
+ const recencyBonus = (index / totalCount) * 10;
218
+ score += recencyBonus;
219
+ // Boost for messages that contain important keywords
220
+ const importantKeywords = [
221
+ 'error', 'exception', 'failed', 'success', 'completed',
222
+ 'important', 'critical', 'warning', 'note'
223
+ ];
224
+ const contentStr = typeof message.content === 'string'
225
+ ? message.content.toLowerCase()
226
+ : JSON.stringify(message.content).toLowerCase();
227
+ const keywordMatches = importantKeywords.filter(keyword => contentStr.includes(keyword)).length;
228
+ score += keywordMatches * 5;
229
+ return score;
230
+ }
231
+ // Public methods for configuration
232
+ getMaxConversationLength() {
233
+ return this.maxConversationLength;
234
+ }
235
+ getCompactionThreshold() {
236
+ return this.compactionThreshold;
237
+ }
238
+ isCompactionNeeded(messageCount) {
239
+ return messageCount >= Math.floor(this.maxConversationLength * this.compactionThreshold);
240
+ }
241
+ getCompressionRatio() {
242
+ return this.compressionRatio;
243
+ }
244
+ // Statistics and monitoring
245
+ getProcessorStats() {
246
+ const enabledFeatures = [];
247
+ if (this.enableSummarization)
248
+ enabledFeatures.push('summarization');
249
+ if (this.enableSmartRemoval)
250
+ enabledFeatures.push('smart_removal');
251
+ if (this.preserveSystemMessages)
252
+ enabledFeatures.push('preserve_system');
253
+ if (this.preserveToolMessages)
254
+ enabledFeatures.push('preserve_tools');
255
+ return {
256
+ maxLength: this.maxConversationLength,
257
+ threshold: this.compactionThreshold,
258
+ preserveRecent: this.preserveRecentMessages,
259
+ compressionRatio: this.compressionRatio,
260
+ enabledFeatures
261
+ };
262
+ }
263
+ }
264
+ exports.ConversationCompactorProcessor = ConversationCompactorProcessor;
@@ -0,0 +1,49 @@
1
+ import { BaseProcessor, ProcessorInput, ProcessorOutput } from '../types/processorTypes';
2
+ export interface ConversationContinuityInfo {
3
+ contextLinksAdded: number;
4
+ referenceResolutionsAdded: number;
5
+ continuityEnhanced: boolean;
6
+ missingContextDetected: boolean;
7
+ conversationGapsFound: number;
8
+ }
9
+ export interface ConversationContinuityProcessorOptions {
10
+ enableContextLinking?: boolean;
11
+ enableReferenceResolution?: boolean;
12
+ enableGapDetection?: boolean;
13
+ maxContextLinks?: number;
14
+ contextLookbackWindow?: number;
15
+ enableProactiveContext?: boolean;
16
+ }
17
+ /**
18
+ * Processor that maintains conversation continuity by linking related messages,
19
+ * resolving references, and detecting context gaps in follow-up conversations.
20
+ */
21
+ export declare class ConversationContinuityProcessor extends BaseProcessor {
22
+ private readonly enableContextLinking;
23
+ private readonly enableReferenceResolution;
24
+ private readonly enableGapDetection;
25
+ private readonly maxContextLinks;
26
+ private readonly contextLookbackWindow;
27
+ private readonly enableProactiveContext;
28
+ constructor(options?: ConversationContinuityProcessorOptions);
29
+ processInput(input: ProcessorInput): Promise<ProcessorOutput[]>;
30
+ private enhanceConversationContinuity;
31
+ private addContextLinks;
32
+ private findReferencingMessages;
33
+ private generateContextLinkMessage;
34
+ private resolveReferences;
35
+ private resolveMessageReferences;
36
+ private detectAndFillGaps;
37
+ private detectConversationGaps;
38
+ private generateGapFillerMessage;
39
+ private addProactiveContext;
40
+ private calculateContinuityInfo;
41
+ setContextLookbackWindow(window: number): void;
42
+ setMaxContextLinks(max: number): void;
43
+ enableContextLinkingForSession(): void;
44
+ disableContextLinkingForSession(): void;
45
+ enableReferenceResolutionForSession(): void;
46
+ disableReferenceResolutionForSession(): void;
47
+ enableGapDetectionForSession(): void;
48
+ disableGapDetectionForSession(): void;
49
+ }