@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,212 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.AtFileProcessorModifier = void 0;
37
+ const base_1 = require("../base");
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ class AtFileProcessorModifier extends base_1.BaseMessageModifier {
41
+ constructor(options = {}) {
42
+ super();
43
+ this.options = {
44
+ maxFileSize: options.maxFileSize || 1024 * 1024, // 1MB default
45
+ allowedExtensions: options.allowedExtensions || ['.ts', '.js', '.json', '.md', '.txt', '.yml', '.yaml', '.xml', '.html', '.css', '.py', '.java', '.cpp', '.c', '.h'],
46
+ basePath: options.basePath || process.cwd()
47
+ };
48
+ }
49
+ async modify(originalRequest, createdMessage) {
50
+ try {
51
+ const mentionedFiles = originalRequest.mentionedFiles || [];
52
+ const mentionedFolders = originalRequest.mentionedFolders || [];
53
+ if (mentionedFiles.length === 0 && mentionedFolders.length === 0) {
54
+ return createdMessage;
55
+ }
56
+ const contextParts = [];
57
+ // Process mentioned files
58
+ if (mentionedFiles.length > 0) {
59
+ const fileContents = await Promise.all(mentionedFiles.map(async (filePath) => {
60
+ try {
61
+ const content = await this.readFileContent(filePath);
62
+ return `--- Content from ${filePath} ---\n${content}\n--- End of ${filePath} ---`;
63
+ }
64
+ catch (error) {
65
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
66
+ return `[Error loading ${filePath}: ${errorMessage}]`;
67
+ }
68
+ }));
69
+ contextParts.push(`File Contents:\n${fileContents.join('\n\n')}`);
70
+ }
71
+ // Process mentioned folders
72
+ if (mentionedFolders.length > 0) {
73
+ const folderContents = await Promise.all(mentionedFolders.map(async (folderPath) => {
74
+ try {
75
+ const structure = await this.getFolderStructure(folderPath);
76
+ return `--- Structure of ${folderPath} ---\n${structure}\n--- End of ${folderPath} ---`;
77
+ }
78
+ catch (error) {
79
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
80
+ return `[Error reading folder ${folderPath}: ${errorMessage}]`;
81
+ }
82
+ }));
83
+ contextParts.push(`Folder Structures:\n${folderContents.join('\n\n')}`);
84
+ }
85
+ // Find the last user message and append context to it
86
+ const messages = [...createdMessage.message.messages];
87
+ let lastUserMessageIndex = -1;
88
+ for (let i = messages.length - 1; i >= 0; i--) {
89
+ if (messages[i].role === 'user') {
90
+ lastUserMessageIndex = i;
91
+ break;
92
+ }
93
+ }
94
+ if (lastUserMessageIndex !== -1) {
95
+ const lastUserMessage = messages[lastUserMessageIndex];
96
+ const currentContent = Array.isArray(lastUserMessage.content)
97
+ ? lastUserMessage.content
98
+ : [{ type: 'text', text: lastUserMessage.content }];
99
+ // Add context as additional content parts
100
+ const contextContent = {
101
+ type: 'text',
102
+ text: contextParts.join('\n\n')
103
+ };
104
+ messages[lastUserMessageIndex] = {
105
+ ...lastUserMessage,
106
+ content: [...currentContent, contextContent]
107
+ };
108
+ }
109
+ return Promise.resolve({
110
+ message: {
111
+ ...createdMessage.message,
112
+ messages
113
+ },
114
+ metadata: {
115
+ ...createdMessage.metadata,
116
+ atFileProcessed: true,
117
+ processedFiles: mentionedFiles,
118
+ processedFolders: mentionedFolders
119
+ }
120
+ });
121
+ }
122
+ catch (error) {
123
+ console.error('Error in AtFileProcessorModifier:', error);
124
+ return createdMessage;
125
+ }
126
+ }
127
+ async readFileContent(filePath) {
128
+ // Resolve path relative to base path
129
+ const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(this.options.basePath, filePath);
130
+ // Security check: ensure the file is within allowed directory
131
+ const relativePath = path.relative(this.options.basePath, resolvedPath);
132
+ if (relativePath.startsWith('..')) {
133
+ throw new Error(`Access denied: ${filePath} is outside the allowed directory`);
134
+ }
135
+ // Check if file exists
136
+ try {
137
+ await fs.promises.access(resolvedPath, fs.constants.R_OK);
138
+ }
139
+ catch (error) {
140
+ throw new Error(`File not found or not readable: ${filePath}`);
141
+ }
142
+ // Check file size
143
+ const stats = await fs.promises.stat(resolvedPath);
144
+ if (stats.size > this.options.maxFileSize) {
145
+ throw new Error(`File too large: ${filePath} (${stats.size} bytes, max ${this.options.maxFileSize} bytes)`);
146
+ }
147
+ // Check file extension if allowedExtensions is specified
148
+ if (this.options.allowedExtensions.length > 0) {
149
+ const ext = path.extname(resolvedPath).toLowerCase();
150
+ if (!this.options.allowedExtensions.includes(ext)) {
151
+ throw new Error(`File type not allowed: ${ext}`);
152
+ }
153
+ }
154
+ // Read and return file content
155
+ const content = await fs.promises.readFile(resolvedPath, 'utf-8');
156
+ return content;
157
+ }
158
+ async getFolderStructure(folderPath) {
159
+ // Resolve path relative to base path
160
+ const resolvedPath = path.isAbsolute(folderPath) ? folderPath : path.resolve(this.options.basePath, folderPath);
161
+ // Security check: ensure the folder is within allowed directory
162
+ const relativePath = path.relative(this.options.basePath, resolvedPath);
163
+ if (relativePath.startsWith('..')) {
164
+ throw new Error(`Access denied: ${folderPath} is outside the allowed directory`);
165
+ }
166
+ // Check if folder exists and is readable
167
+ try {
168
+ await fs.promises.access(resolvedPath, fs.constants.R_OK);
169
+ const stats = await fs.promises.stat(resolvedPath);
170
+ if (!stats.isDirectory()) {
171
+ throw new Error(`${folderPath} is not a directory`);
172
+ }
173
+ }
174
+ catch (error) {
175
+ throw new Error(`Folder not found or not readable: ${folderPath}`);
176
+ }
177
+ // Read directory structure
178
+ try {
179
+ const entries = await fs.promises.readdir(resolvedPath, { withFileTypes: true });
180
+ const lines = [];
181
+ // Sort entries: directories first, then files
182
+ const sortedEntries = entries.sort((a, b) => {
183
+ if (a.isDirectory() && !b.isDirectory())
184
+ return -1;
185
+ if (!a.isDirectory() && b.isDirectory())
186
+ return 1;
187
+ return a.name.localeCompare(b.name);
188
+ });
189
+ for (const entry of sortedEntries.slice(0, 50)) { // Limit to 50 entries
190
+ if (entry.name.startsWith('.'))
191
+ continue; // Skip hidden files
192
+ if (entry.isDirectory()) {
193
+ lines.push(`${folderPath}/${entry.name}/`);
194
+ }
195
+ else {
196
+ const filePath = path.join(resolvedPath, entry.name);
197
+ const stats = await fs.promises.stat(filePath);
198
+ const size = stats.size < 1024 ? `${stats.size}B` : `${Math.round(stats.size / 1024)}KB`;
199
+ lines.push(`${folderPath}/${entry.name} (${size})`);
200
+ }
201
+ }
202
+ if (entries.length > 50) {
203
+ lines.push(`... and ${entries.length - 50} more items`);
204
+ }
205
+ return lines.join('\n');
206
+ }
207
+ catch (error) {
208
+ throw new Error(`Error reading folder structure: ${error instanceof Error ? error.message : 'unknown error'}`);
209
+ }
210
+ }
211
+ }
212
+ exports.AtFileProcessorModifier = AtFileProcessorModifier;
@@ -0,0 +1,19 @@
1
+ import { ProcessedMessage } from "@codebolt/types/agent";
2
+ import { BaseMessageModifier } from "../base";
3
+ import { FlatUserMessage } from "@codebolt/types/sdk";
4
+ export interface ChatCompressionOptions {
5
+ tokenThreshold?: number;
6
+ compressionRatio?: number;
7
+ preserveRecentMessages?: number;
8
+ enableCompression?: boolean;
9
+ }
10
+ export declare class ChatCompressionModifier extends BaseMessageModifier {
11
+ private readonly options;
12
+ private hasFailedCompressionAttempt;
13
+ constructor(options?: ChatCompressionOptions);
14
+ modify(originalRequest: FlatUserMessage, createdMessage: ProcessedMessage): Promise<ProcessedMessage>;
15
+ private shouldCompressChat;
16
+ private compressMessages;
17
+ private createConversationSummary;
18
+ resetCompressionState(): void;
19
+ }
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ChatCompressionModifier = void 0;
4
+ const base_1 = require("../base");
5
+ class ChatCompressionModifier extends base_1.BaseMessageModifier {
6
+ constructor(options = {}) {
7
+ super();
8
+ this.hasFailedCompressionAttempt = false;
9
+ this.options = {
10
+ tokenThreshold: options.tokenThreshold || 8000, // Approximate token threshold
11
+ compressionRatio: options.compressionRatio || 0.5, // Compress to 50% of original
12
+ preserveRecentMessages: options.preserveRecentMessages || 5,
13
+ enableCompression: options.enableCompression !== false
14
+ };
15
+ }
16
+ async modify(originalRequest, createdMessage) {
17
+ try {
18
+ if (!this.options.enableCompression || this.hasFailedCompressionAttempt) {
19
+ return createdMessage;
20
+ }
21
+ const messages = createdMessage.message.messages;
22
+ // Skip compression if we don't have enough messages
23
+ if (messages.length <= this.options.preserveRecentMessages) {
24
+ return createdMessage;
25
+ }
26
+ const shouldCompress = await this.shouldCompressChat(messages);
27
+ if (!shouldCompress) {
28
+ return createdMessage;
29
+ }
30
+ const compressedMessages = await this.compressMessages(messages);
31
+ return Promise.resolve({
32
+ message: {
33
+ ...createdMessage.message,
34
+ messages: compressedMessages
35
+ },
36
+ metadata: {
37
+ ...createdMessage.metadata,
38
+ chatCompressed: true,
39
+ originalMessageCount: messages.length,
40
+ compressedMessageCount: compressedMessages.length
41
+ }
42
+ });
43
+ }
44
+ catch (error) {
45
+ console.error('Error in ChatCompressionModifier:', error);
46
+ this.hasFailedCompressionAttempt = true;
47
+ return createdMessage;
48
+ }
49
+ }
50
+ async shouldCompressChat(messages) {
51
+ // Estimate token count (rough approximation: 4 characters per token)
52
+ const totalCharacters = messages.reduce((sum, msg) => {
53
+ return sum + (typeof msg.content === 'string' ? msg.content.length : JSON.stringify(msg.content).length);
54
+ }, 0);
55
+ const estimatedTokens = totalCharacters / 4;
56
+ return estimatedTokens > this.options.tokenThreshold;
57
+ }
58
+ async compressMessages(messages) {
59
+ const preserveCount = this.options.preserveRecentMessages;
60
+ const recentMessages = messages.slice(-preserveCount);
61
+ const messagesToCompress = messages.slice(0, -preserveCount);
62
+ if (messagesToCompress.length === 0) {
63
+ return messages;
64
+ }
65
+ // Create a summary of the messages to compress
66
+ const conversationSummary = this.createConversationSummary(messagesToCompress);
67
+ const compressionMessage = {
68
+ role: 'system',
69
+ content: `[Conversation Summary - Previous ${messagesToCompress.length} messages compressed]
70
+
71
+ ${conversationSummary}
72
+
73
+ [End of Summary - Continuing with recent conversation...]`
74
+ };
75
+ return [compressionMessage, ...recentMessages];
76
+ }
77
+ createConversationSummary(messages) {
78
+ const summaryParts = [];
79
+ let currentTopic = '';
80
+ let userQuestions = [];
81
+ let assistantResponses = [];
82
+ for (const message of messages) {
83
+ const content = typeof message.content === 'string' ? message.content : JSON.stringify(message.content);
84
+ if (message.role === 'user') {
85
+ // Extract key questions or requests
86
+ if (content.length > 20) { // Only include substantial messages
87
+ userQuestions.push(content.substring(0, 100) + (content.length > 100 ? '...' : ''));
88
+ }
89
+ }
90
+ else if (message.role === 'assistant') {
91
+ // Extract key responses or actions
92
+ if (content.length > 20) {
93
+ assistantResponses.push(content.substring(0, 100) + (content.length > 100 ? '...' : ''));
94
+ }
95
+ }
96
+ }
97
+ if (userQuestions.length > 0) {
98
+ summaryParts.push(`Key user requests: ${userQuestions.slice(0, 3).join('; ')}`);
99
+ }
100
+ if (assistantResponses.length > 0) {
101
+ summaryParts.push(`Key assistant actions: ${assistantResponses.slice(0, 3).join('; ')}`);
102
+ }
103
+ summaryParts.push(`Total messages compressed: ${messages.length}`);
104
+ return summaryParts.join('\n');
105
+ }
106
+ resetCompressionState() {
107
+ this.hasFailedCompressionAttempt = false;
108
+ }
109
+ }
110
+ exports.ChatCompressionModifier = ChatCompressionModifier;
@@ -0,0 +1,23 @@
1
+ import { ProcessedMessage } from "@codebolt/types/agent";
2
+ import { BaseMessageModifier } from "../base";
3
+ import { FlatUserMessage } from "@codebolt/types/sdk";
4
+ export interface ChatRecordingOptions {
5
+ enableRecording?: boolean;
6
+ recordingPath?: string;
7
+ maxRecordingSize?: number;
8
+ includeMetadata?: boolean;
9
+ recordingFormat?: 'json' | 'markdown';
10
+ }
11
+ export declare class ChatRecordingModifier extends BaseMessageModifier {
12
+ private readonly options;
13
+ private recordingFile?;
14
+ constructor(options?: ChatRecordingOptions);
15
+ modify(originalRequest: FlatUserMessage, createdMessage: ProcessedMessage): Promise<ProcessedMessage>;
16
+ private initializeRecording;
17
+ private recordMessages;
18
+ private writeRecord;
19
+ startRecording(customPath?: string): void;
20
+ stopRecording(): void;
21
+ getRecordingFile(): string | undefined;
22
+ isRecording(): boolean;
23
+ }
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ChatRecordingModifier = void 0;
37
+ const base_1 = require("../base");
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ class ChatRecordingModifier extends base_1.BaseMessageModifier {
41
+ constructor(options = {}) {
42
+ super();
43
+ this.options = {
44
+ enableRecording: options.enableRecording || false,
45
+ recordingPath: options.recordingPath || path.join(process.cwd(), '.chat-recordings'),
46
+ maxRecordingSize: options.maxRecordingSize || 10 * 1024 * 1024, // 10MB
47
+ includeMetadata: options.includeMetadata !== false,
48
+ recordingFormat: options.recordingFormat || 'json'
49
+ };
50
+ if (this.options.enableRecording) {
51
+ this.initializeRecording();
52
+ }
53
+ }
54
+ async modify(originalRequest, createdMessage) {
55
+ try {
56
+ if (!this.options.enableRecording || !this.recordingFile) {
57
+ return createdMessage;
58
+ }
59
+ // Record the conversation
60
+ await this.recordMessages(createdMessage, originalRequest);
61
+ return Promise.resolve({
62
+ ...createdMessage,
63
+ metadata: {
64
+ ...createdMessage.metadata,
65
+ chatRecorded: true,
66
+ recordingFile: this.recordingFile
67
+ }
68
+ });
69
+ }
70
+ catch (error) {
71
+ console.error('Error in ChatRecordingModifier:', error);
72
+ return createdMessage;
73
+ }
74
+ }
75
+ initializeRecording() {
76
+ try {
77
+ // Ensure recording directory exists
78
+ if (!fs.existsSync(this.options.recordingPath)) {
79
+ fs.mkdirSync(this.options.recordingPath, { recursive: true });
80
+ }
81
+ // Create recording file with timestamp
82
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
83
+ const extension = this.options.recordingFormat === 'markdown' ? 'md' : 'jsonl';
84
+ this.recordingFile = path.join(this.options.recordingPath, `chat-${timestamp}.${extension}`);
85
+ // Initialize file with header
86
+ if (this.options.recordingFormat === 'markdown') {
87
+ fs.writeFileSync(this.recordingFile, `# Chat Recording\n\nStarted: ${new Date().toISOString()}\n\n---\n\n`);
88
+ }
89
+ }
90
+ catch (error) {
91
+ console.error('Failed to initialize chat recording:', error);
92
+ this.recordingFile = undefined;
93
+ }
94
+ }
95
+ async recordMessages(createdMessage, originalRequest) {
96
+ var _a, _b;
97
+ if (!this.recordingFile)
98
+ return;
99
+ try {
100
+ // Check file size before writing
101
+ if (fs.existsSync(this.recordingFile)) {
102
+ const stats = fs.statSync(this.recordingFile);
103
+ if (stats.size > this.options.maxRecordingSize) {
104
+ console.warn(`Chat recording file ${this.recordingFile} exceeds maximum size. Stopping recording.`);
105
+ return;
106
+ }
107
+ }
108
+ const timestamp = new Date().toISOString();
109
+ // Record each message
110
+ for (const message of createdMessage.message.messages) {
111
+ const record = {
112
+ timestamp,
113
+ messageId: (_a = createdMessage.metadata) === null || _a === void 0 ? void 0 : _a.messageId,
114
+ threadId: (_b = createdMessage.metadata) === null || _b === void 0 ? void 0 : _b.threadId,
115
+ role: message.role,
116
+ content: typeof message.content === 'string' ? message.content : JSON.stringify(message.content)
117
+ };
118
+ if (this.options.includeMetadata) {
119
+ record.metadata = {
120
+ originalRequest: {
121
+ userMessage: originalRequest.userMessage,
122
+ messageId: originalRequest.messageId,
123
+ threadId: originalRequest.threadId
124
+ },
125
+ processedMetadata: createdMessage.metadata
126
+ };
127
+ }
128
+ await this.writeRecord(record);
129
+ }
130
+ }
131
+ catch (error) {
132
+ console.error('Error recording chat messages:', error);
133
+ }
134
+ }
135
+ async writeRecord(record) {
136
+ if (!this.recordingFile)
137
+ return;
138
+ try {
139
+ if (this.options.recordingFormat === 'markdown') {
140
+ const content = `## ${record.role.toUpperCase()} - ${record.timestamp}\n\n${record.content}\n\n---\n\n`;
141
+ fs.appendFileSync(this.recordingFile, content);
142
+ }
143
+ else {
144
+ const jsonLine = JSON.stringify(record) + '\n';
145
+ fs.appendFileSync(this.recordingFile, jsonLine);
146
+ }
147
+ }
148
+ catch (error) {
149
+ console.error('Error writing chat record:', error);
150
+ }
151
+ }
152
+ startRecording(customPath) {
153
+ this.options.enableRecording = true;
154
+ if (customPath) {
155
+ this.options.recordingPath = customPath;
156
+ }
157
+ this.initializeRecording();
158
+ }
159
+ stopRecording() {
160
+ this.options.enableRecording = false;
161
+ if (this.recordingFile && this.options.recordingFormat === 'markdown') {
162
+ fs.appendFileSync(this.recordingFile, `\n---\n\nRecording ended: ${new Date().toISOString()}\n`);
163
+ }
164
+ this.recordingFile = undefined;
165
+ }
166
+ getRecordingFile() {
167
+ return this.recordingFile;
168
+ }
169
+ isRecording() {
170
+ return (this.options.enableRecording || false) && !!this.recordingFile;
171
+ }
172
+ }
173
+ exports.ChatRecordingModifier = ChatRecordingModifier;
@@ -0,0 +1,14 @@
1
+ import { ProcessedMessage } from "@codebolt/types/agent";
2
+ import { BaseMessageModifier } from "../base";
3
+ import { FlatUserMessage } from "@codebolt/types/sdk";
4
+ export interface CoreSystemPromptOptions {
5
+ customSystemPrompt?: string;
6
+ userMemory?: string;
7
+ }
8
+ export declare class CoreSystemPromptModifier extends BaseMessageModifier {
9
+ private readonly options;
10
+ constructor(options?: CoreSystemPromptOptions);
11
+ modify(originalRequest: FlatUserMessage, createdMessage: ProcessedMessage): Promise<ProcessedMessage>;
12
+ private getCoreSystemPrompt;
13
+ private getDefaultSystemPrompt;
14
+ }
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CoreSystemPromptModifier = void 0;
4
+ const base_1 = require("../base");
5
+ class CoreSystemPromptModifier extends base_1.BaseMessageModifier {
6
+ constructor(options = {}) {
7
+ super();
8
+ this.options = options;
9
+ }
10
+ modify(originalRequest, createdMessage) {
11
+ var _a;
12
+ // Get user memory from metadata or options
13
+ const userMemory = ((_a = createdMessage.metadata) === null || _a === void 0 ? void 0 : _a.userMemory) || this.options.userMemory;
14
+ const systemPrompt = this.options.customSystemPrompt || this.getCoreSystemPrompt(userMemory);
15
+ const systemMessage = {
16
+ role: 'system',
17
+ content: systemPrompt
18
+ };
19
+ // Find existing system message or add new one
20
+ const messages = [...createdMessage.message.messages];
21
+ const systemMessageIndex = messages.findIndex(msg => msg.role === 'system');
22
+ if (systemMessageIndex !== -1) {
23
+ // Replace existing system message
24
+ messages[systemMessageIndex] = systemMessage;
25
+ }
26
+ else {
27
+ // Add new system message at the beginning
28
+ messages.unshift(systemMessage);
29
+ }
30
+ return Promise.resolve({
31
+ message: {
32
+ ...createdMessage.message,
33
+ messages
34
+ },
35
+ metadata: {
36
+ ...createdMessage.metadata,
37
+ coreSystemPromptAdded: true,
38
+ systemPromptSource: this.options.customSystemPrompt ? 'custom' : 'default',
39
+ hasUserMemory: !!userMemory
40
+ }
41
+ });
42
+ }
43
+ getCoreSystemPrompt(userMemory) {
44
+ const basePrompt = this.getDefaultSystemPrompt();
45
+ // Add user memory with separator if provided (exactly like gemini-cli)
46
+ const memorySuffix = userMemory && userMemory.trim().length > 0
47
+ ? `\n\n---\n\n${userMemory.trim()}`
48
+ : '';
49
+ return `${basePrompt}${memorySuffix}`;
50
+ }
51
+ getDefaultSystemPrompt() {
52
+ return `
53
+ You are an interactive AI agent specializing in software engineering tasks. Your primary goal is to help users safely and efficiently, adhering strictly to the following instructions and utilizing your available tools.
54
+
55
+ # Core Mandates
56
+
57
+ - **Conventions:** Rigorously adhere to existing project conventions when reading or modifying code. Analyze surrounding code, tests, and configuration first.
58
+ - **Libraries/Frameworks:** NEVER assume a library/framework is available or appropriate. Verify its established usage within the project before employing it.
59
+ - **Style & Structure:** Mimic the style (formatting, naming), structure, framework choices, typing, and architectural patterns of existing code in the project.
60
+ - **Idiomatic Changes:** When editing, understand the local context (imports, functions/classes) to ensure your changes integrate naturally and idiomatically.
61
+ - **Comments:** Add code comments sparingly. Focus on *why* something is done, especially for complex logic, rather than *what* is done.
62
+ - **Proactiveness:** Fulfill the user's request thoroughly, including reasonable, directly implied follow-up actions.
63
+ - **Confirm Ambiguity/Expansion:** Do not take significant actions beyond the clear scope of the request without confirming with the user.
64
+ - **Explaining Changes:** After completing a code modification or file operation *do not* provide summaries unless asked.
65
+
66
+ # Primary Workflows
67
+
68
+ ## Software Engineering Tasks
69
+ When requested to perform tasks like fixing bugs, adding features, refactoring, or explaining code, follow this sequence:
70
+ 1. **Understand:** Think about the user's request and the relevant codebase context. Use search tools extensively to understand file structures, existing code patterns, and conventions.
71
+ 2. **Plan:** Build a coherent and grounded plan for how you intend to resolve the user's task. Share a concise yet clear plan with the user if it would help.
72
+ 3. **Implement:** Use the available tools to act on the plan, strictly adhering to the project's established conventions.
73
+ 4. **Verify:** If applicable and feasible, verify the changes using the project's testing procedures and build/lint commands.
74
+
75
+ # Operational Guidelines
76
+
77
+ ## Tone and Style
78
+ - **Concise & Direct:** Adopt a professional, direct, and concise tone.
79
+ - **Minimal Output:** Aim for fewer than 3 lines of text output per response whenever practical.
80
+ - **Clarity over Brevity:** While conciseness is key, prioritize clarity for essential explanations.
81
+ - **No Chitchat:** Avoid conversational filler. Get straight to the action or answer.
82
+ - **Formatting:** Use GitHub-flavored Markdown.
83
+
84
+ ## Security and Safety Rules
85
+ - **Security First:** Always apply security best practices. Never introduce code that exposes, logs, or commits secrets, API keys, or other sensitive information.
86
+ - **File Operations:** Always use absolute paths when referring to files with tools.
87
+
88
+ # Final Reminder
89
+ Your core function is efficient and safe assistance. Balance extreme conciseness with the crucial need for clarity, especially regarding safety and potential system modifications. Always prioritize user control and project conventions.
90
+ `.trim();
91
+ }
92
+ }
93
+ exports.CoreSystemPromptModifier = CoreSystemPromptModifier;
@@ -0,0 +1,30 @@
1
+ import { ProcessedMessage } from "@codebolt/types/agent";
2
+ import { BaseMessageModifier } from "../base";
3
+ import { FlatUserMessage } from "@codebolt/types/sdk";
4
+ export interface DirectoryContextOptions {
5
+ workspaceDirectories?: string[];
6
+ }
7
+ export declare class DirectoryContextModifier extends BaseMessageModifier {
8
+ private readonly options;
9
+ constructor(options?: DirectoryContextOptions);
10
+ modify(originalRequest: FlatUserMessage, createdMessage: ProcessedMessage): Promise<ProcessedMessage>;
11
+ /**
12
+ * Generates a string representation of a directory's structure,
13
+ * limiting the number of items displayed. Ignored folders are shown
14
+ * followed by '...' instead of their contents.
15
+ *
16
+ * @param directory The absolute or relative path to the directory.
17
+ * @param options Optional configuration settings.
18
+ * @returns A promise resolving to the formatted folder structure string.
19
+ */
20
+ private getFolderStructure;
21
+ private readFullStructure;
22
+ /**
23
+ * Reads the directory structure using BFS, respecting maxItems.
24
+ * @param node The current node in the reduced structure.
25
+ * @param indent The current indentation string.
26
+ * @param isLast Sibling indicator.
27
+ * @param builder Array to build the string lines.
28
+ */
29
+ private formatStructure;
30
+ }