@bestdefense/bd-agent 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +25 -5
- package/dist/cli.js.map +1 -1
- package/dist/commands/chat.d.ts.map +1 -1
- package/dist/commands/chat.js +463 -66
- package/dist/commands/chat.js.map +1 -1
- package/dist/services/bedrock-client.d.ts +1 -0
- package/dist/services/bedrock-client.d.ts.map +1 -1
- package/dist/services/bedrock-client.js +82 -12
- package/dist/services/bedrock-client.js.map +1 -1
- package/dist/services/conversation-manager.d.ts +9 -0
- package/dist/services/conversation-manager.d.ts.map +1 -1
- package/dist/services/conversation-manager.js +13 -0
- package/dist/services/conversation-manager.js.map +1 -1
- package/dist/services/history-manager.d.ts +18 -0
- package/dist/services/history-manager.d.ts.map +1 -0
- package/dist/services/history-manager.js +140 -0
- package/dist/services/history-manager.js.map +1 -0
- package/dist/services/memory-manager.d.ts +47 -0
- package/dist/services/memory-manager.d.ts.map +1 -0
- package/dist/services/memory-manager.js +157 -0
- package/dist/services/memory-manager.js.map +1 -0
- package/dist/services/slash-commands.d.ts +21 -0
- package/dist/services/slash-commands.d.ts.map +1 -0
- package/dist/services/slash-commands.js +142 -0
- package/dist/services/slash-commands.js.map +1 -0
- package/dist/services/tool-executor.d.ts.map +1 -1
- package/dist/services/tool-executor.js +16 -2
- package/dist/services/tool-executor.js.map +1 -1
- package/dist/tools/advanced-edit.d.ts +94 -0
- package/dist/tools/advanced-edit.d.ts.map +1 -0
- package/dist/tools/advanced-edit.js +265 -0
- package/dist/tools/advanced-edit.js.map +1 -0
- package/dist/tools/file-system.d.ts +5 -0
- package/dist/tools/file-system.d.ts.map +1 -1
- package/dist/tools/file-system.js +8 -1
- package/dist/tools/file-system.js.map +1 -1
- package/dist/tools/search-tools.d.ts +110 -0
- package/dist/tools/search-tools.d.ts.map +1 -0
- package/dist/tools/search-tools.js +321 -0
- package/dist/tools/search-tools.js.map +1 -0
- package/dist/types/conversation.d.ts +6 -0
- package/dist/types/conversation.d.ts.map +1 -0
- package/dist/types/conversation.js +3 -0
- package/dist/types/conversation.js.map +1 -0
- package/dist/utils/claude-md.d.ts +24 -0
- package/dist/utils/claude-md.d.ts.map +1 -0
- package/dist/utils/claude-md.js +222 -0
- package/dist/utils/claude-md.js.map +1 -0
- package/dist/utils/error-handler.d.ts +20 -0
- package/dist/utils/error-handler.d.ts.map +1 -0
- package/dist/utils/error-handler.js +130 -0
- package/dist/utils/error-handler.js.map +1 -0
- package/dist/utils/markdown-renderer.d.ts +15 -0
- package/dist/utils/markdown-renderer.d.ts.map +1 -0
- package/dist/utils/markdown-renderer.js +143 -0
- package/dist/utils/markdown-renderer.js.map +1 -0
- package/dist/utils/multi-line-input.d.ts +3 -0
- package/dist/utils/multi-line-input.d.ts.map +1 -0
- package/dist/utils/multi-line-input.js +68 -0
- package/dist/utils/multi-line-input.js.map +1 -0
- package/dist/utils/prompts.d.ts +1 -0
- package/dist/utils/prompts.d.ts.map +1 -1
- package/dist/utils/prompts.js +17 -1
- package/dist/utils/prompts.js.map +1 -1
- package/dist/utils/readline-with-history.d.ts +13 -0
- package/dist/utils/readline-with-history.d.ts.map +1 -0
- package/dist/utils/readline-with-history.js +196 -0
- package/dist/utils/readline-with-history.js.map +1 -0
- package/package.json +9 -4
package/dist/cli.js
CHANGED
|
@@ -9,6 +9,7 @@ const chalk_1 = __importDefault(require("chalk"));
|
|
|
9
9
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
10
10
|
const config_1 = require("./utils/config");
|
|
11
11
|
const chat_1 = require("./commands/chat");
|
|
12
|
+
const claude_md_1 = require("./utils/claude-md");
|
|
12
13
|
const package_json_1 = require("../package.json");
|
|
13
14
|
const program = new commander_1.Command();
|
|
14
15
|
program
|
|
@@ -20,16 +21,35 @@ program
|
|
|
20
21
|
.description('Start an interactive chat session')
|
|
21
22
|
.option('-m, --model <model>', 'Bedrock model ID to use')
|
|
22
23
|
.action(async (options) => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
try {
|
|
25
|
+
if (!(0, config_1.validateConfig)()) {
|
|
26
|
+
console.log(chalk_1.default.yellow('AWS credentials not configured. Running setup...'));
|
|
27
|
+
await runSetup();
|
|
28
|
+
}
|
|
29
|
+
await (0, chat_1.startChat)(options);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
console.error(chalk_1.default.red(`\nUnexpected error: ${error.message}`));
|
|
33
|
+
console.error(chalk_1.default.gray(error.stack));
|
|
34
|
+
process.exit(1);
|
|
26
35
|
}
|
|
27
|
-
await (0, chat_1.startChat)(options);
|
|
28
36
|
});
|
|
29
37
|
program
|
|
30
38
|
.command('setup')
|
|
31
39
|
.description('Configure AWS credentials and settings')
|
|
32
40
|
.action(runSetup);
|
|
41
|
+
program
|
|
42
|
+
.command('init')
|
|
43
|
+
.description('Create a CLAUDE.md template for project-specific instructions')
|
|
44
|
+
.action(() => {
|
|
45
|
+
try {
|
|
46
|
+
claude_md_1.ClaudeMdManager.createTemplate(process.cwd());
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
console.error(chalk_1.default.red(`Error: ${error.message}`));
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
33
53
|
async function runSetup() {
|
|
34
54
|
console.log(chalk_1.default.blue('BD Agent Setup'));
|
|
35
55
|
console.log(chalk_1.default.gray('Configure your AWS credentials for Bedrock access\n'));
|
|
@@ -71,7 +91,7 @@ async function runSetup() {
|
|
|
71
91
|
{ name: 'Claude Opus 4 (requires setup)', value: 'opus-setup' },
|
|
72
92
|
{ name: 'Custom Model/Profile (enter manually)', value: 'custom' }
|
|
73
93
|
],
|
|
74
|
-
default: 'anthropic.claude-
|
|
94
|
+
default: 'us.anthropic.claude-opus-4-20250514-v1:0'
|
|
75
95
|
},
|
|
76
96
|
{
|
|
77
97
|
type: 'input',
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;AAEA,yCAAoC;AACpC,kDAA0B;AAC1B,wDAAgC;AAChC,2CAA4D;AAC5D,0CAA4C;AAC5C,kDAA0C;AAE1C,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,0DAA0D,CAAC;KACvE,OAAO,CAAC,sBAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,mCAAmC,CAAC;KAChD,MAAM,CAAC,qBAAqB,EAAE,yBAAyB,CAAC;KACxD,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,IAAI,CAAC,IAAA,uBAAc,GAAE,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/commands/chat.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/commands/chat.ts"],"names":[],"mappings":"AAeA,wBAAsB,SAAS,CAAC,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,iBA2gB1D"}
|
package/dist/commands/chat.js
CHANGED
|
@@ -5,97 +5,494 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.startChat = startChat;
|
|
7
7
|
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
-
const inquirer_1 = __importDefault(require("inquirer"));
|
|
9
|
-
const ora_1 = __importDefault(require("ora"));
|
|
10
|
-
const marked_1 = require("marked");
|
|
11
8
|
const bedrock_client_1 = require("../services/bedrock-client");
|
|
12
9
|
const conversation_manager_1 = require("../services/conversation-manager");
|
|
13
10
|
const tool_executor_1 = require("../services/tool-executor");
|
|
11
|
+
const memory_manager_1 = require("../services/memory-manager");
|
|
12
|
+
const slash_commands_1 = require("../services/slash-commands");
|
|
13
|
+
const history_manager_1 = require("../services/history-manager");
|
|
14
|
+
const readline_with_history_1 = require("../utils/readline-with-history");
|
|
14
15
|
const prompts_1 = require("../utils/prompts");
|
|
15
|
-
const
|
|
16
|
-
|
|
16
|
+
const markdown_renderer_1 = require("../utils/markdown-renderer");
|
|
17
|
+
const error_handler_1 = require("../utils/error-handler");
|
|
17
18
|
async function startChat(options) {
|
|
19
|
+
// Initialize CLAUDE.md support
|
|
20
|
+
(0, prompts_1.initializeClaudeMd)(process.cwd());
|
|
18
21
|
const client = new bedrock_client_1.BedrockClient();
|
|
19
22
|
const conversation = new conversation_manager_1.ConversationManager();
|
|
20
23
|
const toolExecutor = new tool_executor_1.ToolExecutor();
|
|
24
|
+
const memoryManager = new memory_manager_1.MemoryManager(client);
|
|
25
|
+
const slashCommands = new slash_commands_1.SlashCommandManager();
|
|
26
|
+
const historyManager = new history_manager_1.HistoryManager();
|
|
27
|
+
// Connect memory manager to conversation
|
|
28
|
+
conversation.setMemoryManager(memoryManager);
|
|
21
29
|
console.log(chalk_1.default.blue('BD Agent - AI Coding Assistant'));
|
|
22
|
-
console.log(chalk_1.default.gray('Type "exit" or "quit" to end the session
|
|
30
|
+
console.log(chalk_1.default.gray('Type "exit" or "quit" to end the session'));
|
|
31
|
+
console.log(chalk_1.default.gray('Type "/help" for available commands'));
|
|
32
|
+
console.log(chalk_1.default.gray('Use ↑/↓ arrow keys to navigate command history\n'));
|
|
33
|
+
// Create readline interface with history support
|
|
34
|
+
const readlineWithHistory = new readline_with_history_1.ReadlineWithHistory(historyManager);
|
|
35
|
+
// Handle stdin close event (happens when piping input)
|
|
36
|
+
process.stdin.on('end', () => {
|
|
37
|
+
console.log(chalk_1.default.gray('\nInput stream ended.'));
|
|
38
|
+
readlineWithHistory.close();
|
|
39
|
+
});
|
|
40
|
+
// Keep the process alive
|
|
41
|
+
process.stdin.resume();
|
|
23
42
|
while (true) {
|
|
24
|
-
const { message } = await inquirer_1.default.prompt([
|
|
25
|
-
{
|
|
26
|
-
type: 'input',
|
|
27
|
-
name: 'message',
|
|
28
|
-
message: chalk_1.default.green('You:'),
|
|
29
|
-
validate: (input) => input.trim().length > 0 || 'Please enter a message'
|
|
30
|
-
}
|
|
31
|
-
]);
|
|
32
|
-
if (['exit', 'quit'].includes(message.toLowerCase())) {
|
|
33
|
-
console.log(chalk_1.default.yellow('\nGoodbye!'));
|
|
34
|
-
break;
|
|
35
|
-
}
|
|
36
|
-
conversation.addMessage('user', message);
|
|
37
|
-
const spinner = (0, ora_1.default)('Thinking...').start();
|
|
38
43
|
try {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
// Get input with history support
|
|
45
|
+
let message;
|
|
46
|
+
if (process.stdin.isTTY) {
|
|
47
|
+
// Use custom readline with history for TTY
|
|
48
|
+
message = await readlineWithHistory.question(chalk_1.default.green('You: '));
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
// Fallback for non-TTY environments
|
|
52
|
+
message = await readlineWithHistory.questionSimple(chalk_1.default.green('You: '));
|
|
53
|
+
}
|
|
54
|
+
if (['exit', 'quit'].includes(message.toLowerCase().trim())) {
|
|
55
|
+
console.log(chalk_1.default.yellow('\nGoodbye!'));
|
|
56
|
+
readlineWithHistory.close();
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
// Memory management commands
|
|
60
|
+
if (message.trim() === '/memory') {
|
|
61
|
+
const stats = conversation.getMemoryStats();
|
|
62
|
+
if (stats) {
|
|
63
|
+
console.log(chalk_1.default.cyan('\nMemory Statistics:'));
|
|
64
|
+
console.log(chalk_1.default.gray(`Total messages: ${stats.totalMessages}`));
|
|
65
|
+
console.log(chalk_1.default.gray(`Summaries created: ${stats.summaryCount}`));
|
|
66
|
+
console.log(chalk_1.default.gray(`Max messages: ${stats.config.maxMessages}`));
|
|
67
|
+
console.log(chalk_1.default.gray(`Summary threshold: ${stats.config.summaryThreshold}`));
|
|
48
68
|
}
|
|
49
|
-
else
|
|
50
|
-
|
|
69
|
+
else {
|
|
70
|
+
console.log(chalk_1.default.yellow('Memory management not available'));
|
|
51
71
|
}
|
|
72
|
+
console.log('');
|
|
73
|
+
continue;
|
|
52
74
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
console.log((
|
|
57
|
-
|
|
75
|
+
if (message.trim() === '/clear') {
|
|
76
|
+
conversation.clear();
|
|
77
|
+
memoryManager.clear();
|
|
78
|
+
console.log(chalk_1.default.green('Conversation cleared!\n'));
|
|
79
|
+
continue;
|
|
58
80
|
}
|
|
59
|
-
if (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
81
|
+
if (message.trim() === '/help') {
|
|
82
|
+
console.log(chalk_1.default.cyan('\nAvailable commands:'));
|
|
83
|
+
console.log(chalk_1.default.gray(' /memory - Show memory statistics'));
|
|
84
|
+
console.log(chalk_1.default.gray(' /history - Show command history'));
|
|
85
|
+
console.log(chalk_1.default.gray(' /clear - Clear conversation history'));
|
|
86
|
+
console.log(chalk_1.default.gray(' /commands - List available slash commands'));
|
|
87
|
+
console.log(chalk_1.default.gray(' /help - Show this help message'));
|
|
88
|
+
console.log(chalk_1.default.gray(' exit - Exit the chat session'));
|
|
89
|
+
console.log(chalk_1.default.gray('\nNavigation:'));
|
|
90
|
+
console.log(chalk_1.default.gray(' ↑/↓ - Navigate through command history'));
|
|
91
|
+
console.log(chalk_1.default.gray(' Ctrl+A - Move to beginning of line'));
|
|
92
|
+
console.log(chalk_1.default.gray(' Ctrl+E - Move to end of line'));
|
|
93
|
+
console.log(chalk_1.default.gray('\nSlash commands:'));
|
|
94
|
+
const commands = slashCommands.getAllCommands();
|
|
95
|
+
for (const cmd of commands.slice(0, 5)) {
|
|
96
|
+
console.log(chalk_1.default.gray(` /${cmd.name} - ${cmd.description}`));
|
|
97
|
+
}
|
|
98
|
+
if (commands.length > 5) {
|
|
99
|
+
console.log(chalk_1.default.gray(` ... and ${commands.length - 5} more (use /commands to see all)`));
|
|
100
|
+
}
|
|
101
|
+
console.log('');
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (message.trim() === '/history') {
|
|
105
|
+
const history = historyManager.getHistory(20); // Show last 20 commands
|
|
106
|
+
if (history.length === 0) {
|
|
107
|
+
console.log(chalk_1.default.yellow('No command history available yet.'));
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
console.log(chalk_1.default.cyan('\nCommand History (most recent first):'));
|
|
111
|
+
history.reverse().forEach((cmd, index) => {
|
|
112
|
+
console.log(chalk_1.default.gray(` ${index + 1}. ${cmd}`));
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
console.log('');
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (message.trim() === '/commands') {
|
|
119
|
+
console.log(chalk_1.default.cyan('\nAvailable slash commands:'));
|
|
120
|
+
const commands = slashCommands.getAllCommands();
|
|
121
|
+
for (const cmd of commands) {
|
|
122
|
+
console.log(chalk_1.default.yellow(` /${cmd.name}`) + chalk_1.default.gray(` - ${cmd.description}`));
|
|
123
|
+
if (cmd.arguments && cmd.arguments.length > 0) {
|
|
124
|
+
console.log(chalk_1.default.gray(` Arguments: ${cmd.arguments.join(', ')}`));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
console.log(chalk_1.default.gray(`\nCustom commands directory: ${slashCommands.getCommandsDirectory()}`));
|
|
128
|
+
console.log('');
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (!message.trim()) {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
// Check if it's a slash command
|
|
135
|
+
let processedMessage = message;
|
|
136
|
+
if (message.trim().startsWith('/')) {
|
|
137
|
+
const parts = message.trim().split(' ');
|
|
138
|
+
const commandName = parts[0].substring(1); // Remove the '/'
|
|
139
|
+
const args = parts.slice(1);
|
|
140
|
+
const expandedPrompt = slashCommands.executeCommand(commandName, args);
|
|
141
|
+
if (expandedPrompt) {
|
|
142
|
+
processedMessage = expandedPrompt;
|
|
143
|
+
console.log(chalk_1.default.gray(`Executing /${commandName}...\n`));
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
console.log(chalk_1.default.red(`Unknown command: /${commandName}`));
|
|
147
|
+
console.log(chalk_1.default.gray('Use /help to see available commands\n'));
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
conversation.addMessage('user', processedMessage);
|
|
152
|
+
console.log(chalk_1.default.gray('Analyzing your request...'));
|
|
153
|
+
let timeoutCleared = false;
|
|
154
|
+
let isResponseReceived = false;
|
|
155
|
+
// Add timeout for initial response
|
|
156
|
+
const initialTimeout = setTimeout(() => {
|
|
157
|
+
if (!timeoutCleared && !isResponseReceived) {
|
|
158
|
+
console.log(chalk_1.default.red('\n✗ Response timeout - the AI is taking longer than expected'));
|
|
159
|
+
console.log(chalk_1.default.yellow('Please try again or check your AWS Bedrock connection.'));
|
|
160
|
+
}
|
|
161
|
+
}, 30000); // 30 second timeout for initial response
|
|
162
|
+
try {
|
|
163
|
+
const messages = await conversation.getOptimizedMessages();
|
|
164
|
+
const tools = toolExecutor.getAvailableTools();
|
|
165
|
+
const systemPrompt = (0, prompts_1.getSystemPrompt)();
|
|
166
|
+
let assistantMessage = '';
|
|
167
|
+
let pendingToolCalls = [];
|
|
168
|
+
let isFirstChunk = true;
|
|
169
|
+
const markdownRenderer = new markdown_renderer_1.StreamingMarkdownRenderer();
|
|
170
|
+
const stream = client.streamMessage(messages, tools, systemPrompt);
|
|
171
|
+
for await (const chunk of stream) {
|
|
172
|
+
if (typeof chunk === 'string') {
|
|
173
|
+
if (isFirstChunk) {
|
|
174
|
+
timeoutCleared = true;
|
|
175
|
+
isResponseReceived = true;
|
|
176
|
+
clearTimeout(initialTimeout); // Clear the timeout when we get first response
|
|
177
|
+
console.log(chalk_1.default.blue('\nAssistant:'));
|
|
178
|
+
isFirstChunk = false;
|
|
69
179
|
}
|
|
180
|
+
// Process chunk through streaming markdown renderer
|
|
181
|
+
const formatted = markdownRenderer.addChunk(chunk);
|
|
182
|
+
process.stdout.write(formatted);
|
|
183
|
+
assistantMessage += chunk;
|
|
70
184
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
185
|
+
else if (chunk && 'toolUseId' in chunk) {
|
|
186
|
+
if (!isFirstChunk) {
|
|
187
|
+
// Flush any remaining markdown content
|
|
188
|
+
const remaining = markdownRenderer.flush();
|
|
189
|
+
if (remaining)
|
|
190
|
+
process.stdout.write(remaining);
|
|
191
|
+
console.log(); // New line after text output
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
timeoutCleared = true;
|
|
195
|
+
isResponseReceived = true;
|
|
196
|
+
clearTimeout(initialTimeout); // Clear the timeout when we get first response
|
|
197
|
+
}
|
|
198
|
+
pendingToolCalls.push(chunk);
|
|
75
199
|
}
|
|
76
200
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if (
|
|
83
|
-
|
|
201
|
+
if (assistantMessage || pendingToolCalls.length > 0) {
|
|
202
|
+
// Flush any remaining content
|
|
203
|
+
const remaining = markdownRenderer.flush();
|
|
204
|
+
if (remaining)
|
|
205
|
+
process.stdout.write(remaining);
|
|
206
|
+
if (assistantMessage)
|
|
207
|
+
console.log(); // Ensure we end with a newline
|
|
208
|
+
// Add assistant message with both text and tool use blocks
|
|
209
|
+
const contentBlocks = [];
|
|
210
|
+
if (assistantMessage) {
|
|
211
|
+
contentBlocks.push({ text: assistantMessage });
|
|
212
|
+
}
|
|
213
|
+
for (const toolCall of pendingToolCalls) {
|
|
214
|
+
contentBlocks.push({ toolUse: toolCall });
|
|
215
|
+
}
|
|
216
|
+
if (contentBlocks.length > 0) {
|
|
217
|
+
conversation.addMessage('assistant', contentBlocks);
|
|
84
218
|
}
|
|
85
219
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
220
|
+
// Tool execution loop - keep executing tools until no more are requested
|
|
221
|
+
let toolRounds = 0;
|
|
222
|
+
const MAX_TOOL_ROUNDS = 100; // Allow extended tool usage for mission completion
|
|
223
|
+
let consecutiveToolOnlyRounds = 0;
|
|
224
|
+
while (pendingToolCalls.length > 0 && toolRounds < MAX_TOOL_ROUNDS) {
|
|
225
|
+
toolRounds++;
|
|
226
|
+
const currentToolCalls = [...pendingToolCalls];
|
|
227
|
+
pendingToolCalls = []; // Clear for next round
|
|
228
|
+
for (const toolCall of currentToolCalls) {
|
|
229
|
+
// Create more descriptive spinner text based on tool
|
|
230
|
+
let spinnerText = `Executing ${toolCall.name}...`;
|
|
231
|
+
switch (toolCall.name) {
|
|
232
|
+
case 'read_file':
|
|
233
|
+
spinnerText = `Reading file: ${toolCall.input?.path || toolCall.input?.file_path || 'unknown'}`;
|
|
234
|
+
break;
|
|
235
|
+
case 'read':
|
|
236
|
+
spinnerText = `Reading file: ${toolCall.input?.file_path || toolCall.input?.path || 'unknown'}`;
|
|
237
|
+
break;
|
|
238
|
+
case 'write_file':
|
|
239
|
+
case 'write':
|
|
240
|
+
spinnerText = `Writing to file: ${toolCall.input.file_path || 'unknown'}`;
|
|
241
|
+
break;
|
|
242
|
+
case 'edit_file':
|
|
243
|
+
case 'edit':
|
|
244
|
+
case 'multi_edit':
|
|
245
|
+
spinnerText = `Editing file: ${toolCall.input.file_path || 'unknown'}`;
|
|
246
|
+
break;
|
|
247
|
+
case 'list_directory':
|
|
248
|
+
spinnerText = `Listing directory: ${toolCall.input.path || '.'}`;
|
|
249
|
+
break;
|
|
250
|
+
case 'run_command':
|
|
251
|
+
case 'bash':
|
|
252
|
+
spinnerText = `Running command: ${toolCall.input.command?.substring(0, 50) || 'unknown'}${toolCall.input.command?.length > 50 ? '...' : ''}`;
|
|
253
|
+
break;
|
|
254
|
+
case 'grep':
|
|
255
|
+
spinnerText = `Searching for pattern: "${toolCall.input.pattern?.substring(0, 30) || 'unknown'}"${toolCall.input.pattern?.length > 30 ? '...' : ''}`;
|
|
256
|
+
break;
|
|
257
|
+
case 'glob':
|
|
258
|
+
spinnerText = `Finding files matching: ${toolCall.input.pattern || 'unknown'}`;
|
|
259
|
+
break;
|
|
260
|
+
case 'git_status':
|
|
261
|
+
spinnerText = 'Checking git status...';
|
|
262
|
+
break;
|
|
263
|
+
case 'git_diff':
|
|
264
|
+
spinnerText = 'Getting git diff...';
|
|
265
|
+
break;
|
|
266
|
+
case 'git_add':
|
|
267
|
+
spinnerText = `Staging files: ${toolCall.input.files?.join(', ') || 'unknown'}`;
|
|
268
|
+
break;
|
|
269
|
+
case 'git_commit':
|
|
270
|
+
spinnerText = 'Creating git commit...';
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
console.log(chalk_1.default.yellow(`⚡ ${spinnerText}`));
|
|
274
|
+
try {
|
|
275
|
+
// Check if tool exists
|
|
276
|
+
if (!toolExecutor.hasTool(toolCall.name)) {
|
|
277
|
+
throw new Error(`Unknown tool: ${toolCall.name}. Did you mean 'read_file'?`);
|
|
278
|
+
}
|
|
279
|
+
const result = await toolExecutor.executeTool(toolCall.name, toolCall.input);
|
|
280
|
+
// Create success message based on tool and result
|
|
281
|
+
let successMessage = `${toolCall.name} completed`;
|
|
282
|
+
switch (toolCall.name) {
|
|
283
|
+
case 'read_file':
|
|
284
|
+
if (result.success && result.content) {
|
|
285
|
+
const lines = result.content.split('\n').length;
|
|
286
|
+
successMessage = `Read ${lines} lines from ${toolCall.input?.path || 'file'}`;
|
|
287
|
+
}
|
|
288
|
+
break;
|
|
289
|
+
case 'read':
|
|
290
|
+
if (result.success && result.content) {
|
|
291
|
+
const lines = result.content.split('\n').length;
|
|
292
|
+
successMessage = `Read ${lines} lines from ${toolCall.input?.file_path || 'file'}`;
|
|
293
|
+
}
|
|
294
|
+
break;
|
|
295
|
+
case 'write_file':
|
|
296
|
+
case 'write':
|
|
297
|
+
if (result.success) {
|
|
298
|
+
successMessage = `Successfully wrote to ${toolCall.input.file_path}`;
|
|
299
|
+
}
|
|
300
|
+
break;
|
|
301
|
+
case 'edit_file':
|
|
302
|
+
case 'edit':
|
|
303
|
+
if (result.success) {
|
|
304
|
+
successMessage = `Successfully edited ${toolCall.input.file_path}`;
|
|
305
|
+
}
|
|
306
|
+
break;
|
|
307
|
+
case 'multi_edit':
|
|
308
|
+
if (result.success && toolCall.input.edits) {
|
|
309
|
+
successMessage = `Applied ${toolCall.input.edits.length} edits to ${toolCall.input.file_path}`;
|
|
310
|
+
}
|
|
311
|
+
break;
|
|
312
|
+
case 'grep':
|
|
313
|
+
if (result.success && result.matches) {
|
|
314
|
+
successMessage = `Found ${result.matches.length} matches`;
|
|
315
|
+
}
|
|
316
|
+
else if (result.success && result.count !== undefined) {
|
|
317
|
+
successMessage = `Found ${result.count} total matches`;
|
|
318
|
+
}
|
|
319
|
+
break;
|
|
320
|
+
case 'glob':
|
|
321
|
+
if (result.success && result.files) {
|
|
322
|
+
successMessage = `Found ${result.files.length} files matching pattern`;
|
|
323
|
+
}
|
|
324
|
+
break;
|
|
325
|
+
case 'run_command':
|
|
326
|
+
case 'bash':
|
|
327
|
+
if (result.success) {
|
|
328
|
+
successMessage = `Command executed successfully`;
|
|
329
|
+
}
|
|
330
|
+
break;
|
|
331
|
+
}
|
|
332
|
+
console.log(chalk_1.default.green(`✓ ${successMessage}`));
|
|
333
|
+
conversation.addToolResult(toolCall.toolUseId, result);
|
|
334
|
+
if (result) {
|
|
335
|
+
console.log(chalk_1.default.gray(`\nTool Result (${toolCall.name}):`));
|
|
336
|
+
// Special handling for edit tools to show diffs
|
|
337
|
+
if ((toolCall.name === 'edit_file' || toolCall.name === 'edit' || toolCall.name === 'multi_edit')
|
|
338
|
+
&& result.success && result.diff) {
|
|
339
|
+
console.log((0, markdown_renderer_1.renderDiff)(result.diff.old, result.diff.new));
|
|
340
|
+
if (result.preview) {
|
|
341
|
+
console.log(chalk_1.default.gray('\nPreview:'));
|
|
342
|
+
console.log(result.preview);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
else if (result.error) {
|
|
346
|
+
// Show errors in a more readable format
|
|
347
|
+
console.log(chalk_1.default.red(result.error));
|
|
348
|
+
}
|
|
349
|
+
else if ((toolCall.name === 'grep' || toolCall.name === 'glob') && result.success) {
|
|
350
|
+
// Special formatting for search results
|
|
351
|
+
if (result.matches) {
|
|
352
|
+
console.log(chalk_1.default.cyan(`Found ${result.matches.length} matches:`));
|
|
353
|
+
result.matches.forEach((match) => {
|
|
354
|
+
console.log(` ${chalk_1.default.yellow(match.file)}:${chalk_1.default.green(match.line)} ${match.match}`);
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
else if (result.files) {
|
|
358
|
+
console.log(chalk_1.default.cyan(`Found ${result.files.length} files:`));
|
|
359
|
+
result.files.forEach((file) => {
|
|
360
|
+
console.log(` ${chalk_1.default.yellow(file)}`);
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
else if (result.count !== undefined) {
|
|
364
|
+
console.log(chalk_1.default.cyan(`Total matches: ${result.count}`));
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
// Regular JSON output for other tools
|
|
369
|
+
console.log(chalk_1.default.gray(JSON.stringify(result, null, 2)));
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
catch (error) {
|
|
374
|
+
console.log(chalk_1.default.red(`✗ ${toolCall.name} failed`));
|
|
375
|
+
const toolError = new error_handler_1.ToolExecutionError(error.message || String(error), toolCall.name, error);
|
|
376
|
+
console.error((0, error_handler_1.formatError)(toolError));
|
|
377
|
+
conversation.addToolResult(toolCall.toolUseId, `Error: ${error.message || error}`);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
// Only show spinner if we're expecting a follow-up
|
|
381
|
+
console.log(''); // Add spacing
|
|
382
|
+
console.log(chalk_1.default.cyan('⏳ Waiting for AI response...'));
|
|
383
|
+
let streamTimeout;
|
|
384
|
+
try {
|
|
385
|
+
const followUpMessages = await conversation.getOptimizedMessages();
|
|
386
|
+
// Add timeout for streaming - give more time for follow-up responses
|
|
387
|
+
streamTimeout = setTimeout(() => {
|
|
388
|
+
if (!followUpMessage && pendingToolCalls.length === 0) {
|
|
389
|
+
console.log(chalk_1.default.gray('(AI completed tool execution without additional commentary)'));
|
|
390
|
+
}
|
|
391
|
+
}, 10000); // 10 second timeout for follow-up
|
|
392
|
+
const followUpStream = client.streamMessage(followUpMessages, tools, systemPrompt);
|
|
393
|
+
let followUpMessage = '';
|
|
394
|
+
let isFirstFollowUpChunk = true;
|
|
395
|
+
const followUpRenderer = new markdown_renderer_1.StreamingMarkdownRenderer();
|
|
396
|
+
for await (const chunk of followUpStream) {
|
|
397
|
+
if (typeof chunk === 'string') {
|
|
398
|
+
if (isFirstFollowUpChunk) {
|
|
399
|
+
console.log(chalk_1.default.blue('\nAssistant:'));
|
|
400
|
+
isFirstFollowUpChunk = false;
|
|
401
|
+
}
|
|
402
|
+
const formatted = followUpRenderer.addChunk(chunk);
|
|
403
|
+
process.stdout.write(formatted);
|
|
404
|
+
followUpMessage += chunk;
|
|
405
|
+
}
|
|
406
|
+
else if (chunk && 'toolUseId' in chunk) {
|
|
407
|
+
// Handle additional tool calls in follow-up
|
|
408
|
+
if (isFirstFollowUpChunk) {
|
|
409
|
+
isFirstFollowUpChunk = false;
|
|
410
|
+
}
|
|
411
|
+
// Collect the new tool call for the next iteration
|
|
412
|
+
console.log(chalk_1.default.yellow(`\n[AI requests tool: ${chunk.name}]`));
|
|
413
|
+
pendingToolCalls.push(chunk);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
// Clear timeout since we completed successfully
|
|
417
|
+
clearTimeout(streamTimeout);
|
|
418
|
+
// Ensure spinner is stopped even if no chunks received
|
|
419
|
+
if (isFirstFollowUpChunk) {
|
|
420
|
+
}
|
|
421
|
+
if (followUpMessage || pendingToolCalls.length > 0) {
|
|
422
|
+
const remaining = followUpRenderer.flush();
|
|
423
|
+
if (remaining)
|
|
424
|
+
process.stdout.write(remaining);
|
|
425
|
+
if (followUpMessage)
|
|
426
|
+
console.log(); // Ensure we end with a newline
|
|
427
|
+
// Track if this was a tool-only response
|
|
428
|
+
if (!followUpMessage && pendingToolCalls.length > 0) {
|
|
429
|
+
consecutiveToolOnlyRounds++;
|
|
430
|
+
}
|
|
431
|
+
else {
|
|
432
|
+
consecutiveToolOnlyRounds = 0;
|
|
433
|
+
}
|
|
434
|
+
// Add assistant message with both text and any new tool calls
|
|
435
|
+
const followUpContentBlocks = [];
|
|
436
|
+
if (followUpMessage) {
|
|
437
|
+
followUpContentBlocks.push({ text: followUpMessage });
|
|
438
|
+
}
|
|
439
|
+
for (const toolCall of pendingToolCalls) {
|
|
440
|
+
followUpContentBlocks.push({ toolUse: toolCall });
|
|
441
|
+
}
|
|
442
|
+
if (followUpContentBlocks.length > 0) {
|
|
443
|
+
conversation.addMessage('assistant', followUpContentBlocks);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
catch (followUpError) {
|
|
448
|
+
clearTimeout(streamTimeout);
|
|
449
|
+
console.log(chalk_1.default.red('✗ Failed to process tool results'));
|
|
450
|
+
console.error(chalk_1.default.red(`Error: ${followUpError.message}`));
|
|
451
|
+
// If it's a specific error about the model not responding, handle gracefully
|
|
452
|
+
if (followUpError.message?.includes('timeout') || followUpError.message?.includes('stream')) {
|
|
453
|
+
console.log(chalk_1.default.yellow('\nThe AI completed the tool execution but didn\'t provide additional commentary.'));
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
// Check if we should continue the loop
|
|
457
|
+
if (pendingToolCalls.length === 0) {
|
|
458
|
+
// No more tools to execute, we're done
|
|
459
|
+
break;
|
|
460
|
+
}
|
|
461
|
+
// Stop if too many consecutive tool-only responses
|
|
462
|
+
if (consecutiveToolOnlyRounds >= 100) {
|
|
463
|
+
console.log(chalk_1.default.yellow('\nThe AI is requesting many tools without providing explanations. Stopping here.'));
|
|
464
|
+
console.log(chalk_1.default.gray('You can ask a follow-up question to get more details.'));
|
|
465
|
+
break;
|
|
466
|
+
}
|
|
467
|
+
if (toolRounds >= MAX_TOOL_ROUNDS) {
|
|
468
|
+
console.log(chalk_1.default.yellow('\nReached maximum tool execution rounds.'));
|
|
469
|
+
break;
|
|
470
|
+
}
|
|
471
|
+
// Otherwise, continue with the next round of tool execution
|
|
472
|
+
} // End of while loop for tool execution
|
|
473
|
+
}
|
|
474
|
+
catch (error) {
|
|
475
|
+
timeoutCleared = true;
|
|
476
|
+
clearTimeout(initialTimeout); // Clear timeout on error
|
|
477
|
+
console.error((0, error_handler_1.formatError)(error));
|
|
478
|
+
// If it's a retryable error, suggest retrying
|
|
479
|
+
if (error.retryable) {
|
|
480
|
+
console.log(chalk_1.default.yellow('\nWould you like to try again? The error might be temporary.'));
|
|
91
481
|
}
|
|
482
|
+
// Don't break the main loop - continue to accept new prompts
|
|
483
|
+
// This matches Claude's behavior of continuing after errors
|
|
92
484
|
}
|
|
485
|
+
console.log('');
|
|
93
486
|
}
|
|
94
|
-
catch (
|
|
95
|
-
|
|
96
|
-
console.error(chalk_1.default.
|
|
487
|
+
catch (outerError) {
|
|
488
|
+
console.error(chalk_1.default.red(`\nFatal error in chat loop: ${outerError.message}`));
|
|
489
|
+
console.error(chalk_1.default.gray(outerError.stack));
|
|
490
|
+
readlineWithHistory.close();
|
|
491
|
+
break;
|
|
97
492
|
}
|
|
98
|
-
console.log('');
|
|
99
493
|
}
|
|
494
|
+
// This should never be reached unless exit/quit is typed
|
|
495
|
+
console.log(chalk_1.default.gray('Chat session ended.'));
|
|
496
|
+
process.stdin.pause();
|
|
100
497
|
}
|
|
101
498
|
//# sourceMappingURL=chat.js.map
|