sam-coder-cli 1.0.44 ā 1.0.45
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/bin/agi-cli.js +115 -12
- package/package.json +2 -1
- package/bin/agi-cli.js.new +0 -328
package/bin/agi-cli.js
CHANGED
|
@@ -15,8 +15,42 @@ let OPENROUTER_API_KEY;
|
|
|
15
15
|
let MODEL = 'deepseek/deepseek-chat-v3-0324:free';
|
|
16
16
|
let API_BASE_URL = 'https://openrouter.ai/api/v1';
|
|
17
17
|
|
|
18
|
+
// Tool/Function definitions for the AI
|
|
19
|
+
// Knowledge management functions
|
|
20
|
+
const KNOWLEDGE_FILE = path.join(os.homedir(), '.sam-coder-knowledge.json');
|
|
21
|
+
|
|
22
|
+
async function loadKnowledge() {
|
|
23
|
+
try {
|
|
24
|
+
const data = await fs.readFile(KNOWLEDGE_FILE, 'utf8');
|
|
25
|
+
return JSON.parse(data);
|
|
26
|
+
} catch (error) {
|
|
27
|
+
// If file doesn't exist, return empty knowledge
|
|
28
|
+
return {};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function saveKnowledge(knowledge) {
|
|
33
|
+
await fs.writeFile(KNOWLEDGE_FILE, JSON.stringify(knowledge, null, 2), 'utf8');
|
|
34
|
+
}
|
|
35
|
+
|
|
18
36
|
// Tool/Function definitions for the AI
|
|
19
37
|
const tools = [
|
|
38
|
+
{
|
|
39
|
+
type: 'function',
|
|
40
|
+
function: {
|
|
41
|
+
name: 'addKnowledge',
|
|
42
|
+
description: 'Add or update knowledge in the knowledge base',
|
|
43
|
+
parameters: {
|
|
44
|
+
type: 'object',
|
|
45
|
+
properties: {
|
|
46
|
+
key: { type: 'string', description: 'Key/identifier for the knowledge' },
|
|
47
|
+
value: { type: 'string', description: 'The knowledge content' },
|
|
48
|
+
description: { type: 'string', description: 'Description of what this knowledge is about' }
|
|
49
|
+
},
|
|
50
|
+
required: ['key', 'value', 'description']
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
20
54
|
{
|
|
21
55
|
type: 'function',
|
|
22
56
|
function: {
|
|
@@ -190,12 +224,19 @@ const tools = [
|
|
|
190
224
|
// System prompt for the AI Assistant when using tool calling
|
|
191
225
|
const TOOL_CALLING_PROMPT = `You are a helpful AI assistant with agency capabilities. You can perform actions on the user's system using the provided tools.
|
|
192
226
|
|
|
227
|
+
KNOWLEDGE MANAGEMENT:
|
|
228
|
+
- You can store and retrieve knowledge using the 'addKnowledge' tool.
|
|
229
|
+
- Use this to remember user preferences, project details, or any other important information.
|
|
230
|
+
- The knowledge will persist across sessions.
|
|
231
|
+
- Example: If the user mentions they prefer Python for all projects, store this preference.
|
|
232
|
+
|
|
193
233
|
TOOLS AVAILABLE:
|
|
194
|
-
1.
|
|
195
|
-
2.
|
|
196
|
-
3.
|
|
197
|
-
4.
|
|
198
|
-
5.
|
|
234
|
+
1. addKnowledge - Add or update knowledge in the knowledge base
|
|
235
|
+
2. readFile - Read the contents of a file
|
|
236
|
+
3. writeFile - Write content to a file
|
|
237
|
+
4. editFile - Edit specific parts of a file
|
|
238
|
+
5. runCommand - Execute a shell command
|
|
239
|
+
6. searchFiles - Search for files using a glob pattern
|
|
199
240
|
|
|
200
241
|
ENVIRONMENT:
|
|
201
242
|
- OS: ${process.platform}
|
|
@@ -355,6 +396,28 @@ const agentUtils = {
|
|
|
355
396
|
}
|
|
356
397
|
};
|
|
357
398
|
|
|
399
|
+
const toolHandlers = {
|
|
400
|
+
addKnowledge: async ({ key, value, description }) => {
|
|
401
|
+
try {
|
|
402
|
+
const knowledge = await loadKnowledge();
|
|
403
|
+
knowledge[key] = {
|
|
404
|
+
value,
|
|
405
|
+
description,
|
|
406
|
+
timestamp: new Date().toISOString()
|
|
407
|
+
};
|
|
408
|
+
await saveKnowledge(knowledge);
|
|
409
|
+
return { success: true, message: `Knowledge '${key}' added successfully` };
|
|
410
|
+
} catch (error) {
|
|
411
|
+
return { success: false, error: error.message };
|
|
412
|
+
}
|
|
413
|
+
},
|
|
414
|
+
readFile,
|
|
415
|
+
writeFile,
|
|
416
|
+
editFile,
|
|
417
|
+
runCommand,
|
|
418
|
+
searchFiles
|
|
419
|
+
};
|
|
420
|
+
|
|
358
421
|
// Extract JSON from markdown code blocks
|
|
359
422
|
function extractJsonFromMarkdown(text) {
|
|
360
423
|
// Try to find a markdown code block with JSON content
|
|
@@ -428,7 +491,29 @@ async function callOpenRouter(messages, currentModel, useJson = false) {
|
|
|
428
491
|
// Process a query with tool calling
|
|
429
492
|
async function processQueryWithTools(query, conversation = [], currentModel) {
|
|
430
493
|
const userMessage = { role: 'user', content: query };
|
|
431
|
-
|
|
494
|
+
let messages = [...conversation, userMessage];
|
|
495
|
+
|
|
496
|
+
// Add system message with knowledge if this is the first message
|
|
497
|
+
if (conversation.length === 0) {
|
|
498
|
+
// Load knowledge and include it in the system prompt
|
|
499
|
+
const knowledge = await loadKnowledge();
|
|
500
|
+
let systemPrompt = TOOL_CALLING_PROMPT;
|
|
501
|
+
|
|
502
|
+
// Add knowledge to the system prompt if any exists
|
|
503
|
+
const knowledgeEntries = Object.entries(knowledge);
|
|
504
|
+
if (knowledgeEntries.length > 0) {
|
|
505
|
+
systemPrompt += '\n\nCURRENT KNOWLEDGE BASE:\n';
|
|
506
|
+
systemPrompt += knowledgeEntries.map(([key, { value, description }]) =>
|
|
507
|
+
`- ${key}: ${value} (${description})`
|
|
508
|
+
).join('\n');
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// Add system message at the beginning
|
|
512
|
+
messages = [
|
|
513
|
+
{ role: 'system', content: systemPrompt },
|
|
514
|
+
...messages
|
|
515
|
+
];
|
|
516
|
+
}
|
|
432
517
|
|
|
433
518
|
ui.startThinking();
|
|
434
519
|
|
|
@@ -471,12 +556,20 @@ async function processQueryWithTools(query, conversation = [], currentModel) {
|
|
|
471
556
|
async function handleToolCalls(toolCalls, messages) {
|
|
472
557
|
const results = [];
|
|
473
558
|
|
|
559
|
+
// Load knowledge at the start of processing tool calls
|
|
560
|
+
const knowledge = await loadKnowledge();
|
|
561
|
+
|
|
474
562
|
for (const toolCall of toolCalls) {
|
|
475
563
|
const functionName = toolCall.function.name;
|
|
476
564
|
let args;
|
|
477
565
|
|
|
478
566
|
try {
|
|
479
567
|
args = JSON.parse(toolCall.function.arguments);
|
|
568
|
+
|
|
569
|
+
// If we have knowledge that might be relevant, include it in the context
|
|
570
|
+
if (knowledge.defaultLanguage && !args.language) {
|
|
571
|
+
args.language = knowledge.defaultLanguage.value;
|
|
572
|
+
}
|
|
480
573
|
} catch (error) {
|
|
481
574
|
console.error('ā Failed to parse tool arguments:', error);
|
|
482
575
|
results.push({
|
|
@@ -647,18 +740,28 @@ async function chat(rl, useToolCalling, initialModel) {
|
|
|
647
740
|
if (input.toLowerCase() === '/setup') {
|
|
648
741
|
await runSetup(rl, true);
|
|
649
742
|
console.log('\nSetup complete. Please restart the application to apply changes.');
|
|
650
|
-
rl.
|
|
743
|
+
rl.prompt();
|
|
651
744
|
return;
|
|
652
745
|
}
|
|
653
|
-
|
|
654
|
-
if (input.toLowerCase() === '
|
|
655
|
-
|
|
746
|
+
|
|
747
|
+
if (input.toLowerCase() === '/eraseknowledge') {
|
|
748
|
+
try {
|
|
749
|
+
await fs.unlink(KNOWLEDGE_FILE);
|
|
750
|
+
console.log('ā
All knowledge has been erased.');
|
|
751
|
+
} catch (error) {
|
|
752
|
+
if (error.code === 'ENOENT') {
|
|
753
|
+
console.log('ā¹ļø No knowledge to erase.');
|
|
754
|
+
} else {
|
|
755
|
+
console.error('ā Failed to erase knowledge:', error.message);
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
rl.prompt();
|
|
656
759
|
return;
|
|
657
760
|
}
|
|
658
761
|
|
|
659
762
|
const result = useToolCalling
|
|
660
|
-
? await processQueryWithTools(
|
|
661
|
-
: await processQuery(
|
|
763
|
+
? await processQueryWithTools(query, conversation, currentModel)
|
|
764
|
+
: await processQuery(query, conversation, currentModel);
|
|
662
765
|
ui.stopThinking();
|
|
663
766
|
ui.showResponse(result.response);
|
|
664
767
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sam-coder-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.45",
|
|
4
4
|
"description": "SAM-CODER: An animated command-line AI assistant with agency capabilities.",
|
|
5
5
|
"main": "bin/agi-cli.js",
|
|
6
6
|
"bin": {
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"ws": "^8.18.3"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
+
"@types/vscode": "^1.102.0",
|
|
27
28
|
"eslint": "^7.27.0"
|
|
28
29
|
},
|
|
29
30
|
"engines": {
|
package/bin/agi-cli.js.new
DELETED
|
@@ -1,328 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const readline = require('readline');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
const fs = require('fs').promises;
|
|
6
|
-
const { exec } = require('child_process');
|
|
7
|
-
const util = require('util');
|
|
8
|
-
const execAsync = util.promisify(exec);
|
|
9
|
-
|
|
10
|
-
// Configuration
|
|
11
|
-
const MODEL = 'deepseek/deepseek-chat-v3-0324:free';
|
|
12
|
-
const API_BASE_URL = 'https://openrouter.ai/api/v1';
|
|
13
|
-
|
|
14
|
-
// System prompt matching the VS Code extension
|
|
15
|
-
const SYSTEM_PROMPT = `You are a VS Code AI Assistant with agency capabilities. You can perform actions on the user's workspace.
|
|
16
|
-
|
|
17
|
-
ENVIRONMENT CONTEXT:
|
|
18
|
-
- OS: ${process.platform}
|
|
19
|
-
- Working Directory: ${process.cwd()}
|
|
20
|
-
|
|
21
|
-
When you need to perform actions, respond with JSON in the following format:
|
|
22
|
-
\`\`\`json
|
|
23
|
-
{
|
|
24
|
-
"thoughts": "Your reasoning about what needs to be done",
|
|
25
|
-
"actions": [
|
|
26
|
-
{
|
|
27
|
-
"type": "read|write|search|command|analyze|execute|stop",
|
|
28
|
-
"data": { ... action specific data ... }
|
|
29
|
-
}
|
|
30
|
-
]
|
|
31
|
-
}
|
|
32
|
-
\`\`\`
|
|
33
|
-
|
|
34
|
-
Action types and their data:
|
|
35
|
-
- read: { "path": "relative/or/absolute/path" }
|
|
36
|
-
- write: { "path": "relative/or/absolute/path", "content": "file content" }
|
|
37
|
-
- search: { "type": "files", "pattern": "glob pattern" } or { "type": "text", "text": "search text" }
|
|
38
|
-
- command: { "command": "command string to execute in terminal" }
|
|
39
|
-
- execute: { "language": "js|python|bash|...", "code": "code to execute" }
|
|
40
|
-
- analyze: { "code": "code to analyze", "question": "what you want to analyze" }
|
|
41
|
-
- browse: { "query": "search query", "numResults": 5 } (free web search using DuckDuckGo, optional numResults)
|
|
42
|
-
- edit: {
|
|
43
|
-
"path": "relative/or/absolute/path",
|
|
44
|
-
"edits": {
|
|
45
|
-
"operations": [
|
|
46
|
-
{ "type": "replace", "startLine": 10, "endLine": 15, "newText": "new code here" },
|
|
47
|
-
{ "type": "replace", "pattern": "oldFunction\\(\\)", "replacement": "newFunction()", "flags": "g" },
|
|
48
|
-
{ "type": "insert", "line": 20, "text": "new line of code here" },
|
|
49
|
-
{ "type": "insert", "position": "start", "text": "// Header comment" },
|
|
50
|
-
{ "type": "insert", "position": "end", "text": "// Footer comment" },
|
|
51
|
-
{ "type": "delete", "startLine": 25, "endLine": 30 }
|
|
52
|
-
]
|
|
53
|
-
}
|
|
54
|
-
} (edit specific parts of an existing file)
|
|
55
|
-
- stop: {} (use this to indicate you're done with the task and no more actions are needed)
|
|
56
|
-
|
|
57
|
-
By default, you will continue to take actions in a loop until you decide to stop with the 'stop' action type.
|
|
58
|
-
Always wrap your JSON in markdown code blocks with the json language specifier.
|
|
59
|
-
When executing code or commands that might be potentially harmful, explain what the code does before executing it.`;
|
|
60
|
-
|
|
61
|
-
// Agent utilities
|
|
62
|
-
const agentUtils = {
|
|
63
|
-
async readFile(filePath) {
|
|
64
|
-
try {
|
|
65
|
-
const content = await fs.readFile(filePath, 'utf-8');
|
|
66
|
-
return content;
|
|
67
|
-
} catch (error) {
|
|
68
|
-
throw new Error(`Failed to read file ${filePath}: ${error.message}`);
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
|
|
72
|
-
async writeFile(filePath, content) {
|
|
73
|
-
try {
|
|
74
|
-
await fs.writeFile(filePath, content, 'utf-8');
|
|
75
|
-
return `Successfully wrote to ${filePath}`;
|
|
76
|
-
} catch (error) {
|
|
77
|
-
throw new Error(`Failed to write to file ${filePath}: ${error.message}`);
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
|
|
81
|
-
async runCommand(command) {
|
|
82
|
-
try {
|
|
83
|
-
const { stdout, stderr } = await execAsync(command, { cwd: process.cwd() });
|
|
84
|
-
if (stderr) {
|
|
85
|
-
console.error('Command stderr:', stderr);
|
|
86
|
-
}
|
|
87
|
-
return stdout || 'Command executed successfully (no output)';
|
|
88
|
-
} catch (error) {
|
|
89
|
-
throw new Error(`Command failed: ${error.message}`);
|
|
90
|
-
}
|
|
91
|
-
},
|
|
92
|
-
|
|
93
|
-
async searchFiles(pattern) {
|
|
94
|
-
try {
|
|
95
|
-
const { stdout } = await execAsync(`find . -name "${pattern}"`, { cwd: process.cwd() });
|
|
96
|
-
return stdout || 'No files found';
|
|
97
|
-
} catch (error) {
|
|
98
|
-
throw new Error(`Search failed: ${error.message}`);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
// Extract JSON from markdown code blocks
|
|
104
|
-
function extractJsonFromMarkdown(text) {
|
|
105
|
-
// Try to find a markdown code block with JSON content
|
|
106
|
-
const codeBlockRegex = /```json\s*([\s\S]*?)\s*```/;
|
|
107
|
-
const match = text.match(codeBlockRegex);
|
|
108
|
-
|
|
109
|
-
if (match) {
|
|
110
|
-
try {
|
|
111
|
-
return JSON.parse(match[1]);
|
|
112
|
-
} catch (error) {
|
|
113
|
-
console.error('Error parsing JSON from markdown:', error);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// If no code block, try to parse the entire text as JSON
|
|
118
|
-
try {
|
|
119
|
-
return JSON.parse(text);
|
|
120
|
-
} catch (error) {
|
|
121
|
-
console.error('Error parsing JSON:', error);
|
|
122
|
-
return null;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Call OpenRouter API
|
|
127
|
-
async function callOpenRouter(messages) {
|
|
128
|
-
const apiKey = process.env.OPENROUTER_API_KEY;
|
|
129
|
-
|
|
130
|
-
if (!apiKey) {
|
|
131
|
-
throw new Error('OPENROUTER_API_KEY environment variable is not set');
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
try {
|
|
135
|
-
const response = await fetch(API_BASE_URL + '/chat/completions', {
|
|
136
|
-
method: 'POST',
|
|
137
|
-
headers: {
|
|
138
|
-
'Content-Type': 'application/json',
|
|
139
|
-
'Authorization': `Bearer ${apiKey}`,
|
|
140
|
-
'HTTP-Referer': 'https://github.com/yourusername/agi-cli'
|
|
141
|
-
},
|
|
142
|
-
body: JSON.stringify({
|
|
143
|
-
model: MODEL,
|
|
144
|
-
messages: messages
|
|
145
|
-
})
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
if (!response.ok) {
|
|
149
|
-
const error = await response.json();
|
|
150
|
-
throw new Error(`API error: ${error.error?.message || response.statusText}`);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return await response.json();
|
|
154
|
-
} catch (error) {
|
|
155
|
-
console.error('API call failed:', error);
|
|
156
|
-
throw new Error(`Failed to call OpenRouter API: ${error.message}`);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Process a query with action handling
|
|
161
|
-
async function processQuery(query, conversation = []) {
|
|
162
|
-
try {
|
|
163
|
-
// Add user message to conversation
|
|
164
|
-
const userMessage = { role: 'user', content: query };
|
|
165
|
-
const messages = [...conversation, userMessage];
|
|
166
|
-
|
|
167
|
-
// Add system message if this is the first message
|
|
168
|
-
if (conversation.length === 0) {
|
|
169
|
-
messages.unshift({
|
|
170
|
-
role: 'system',
|
|
171
|
-
content: SYSTEM_PROMPT
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
let shouldContinue = true;
|
|
176
|
-
let iteration = 0;
|
|
177
|
-
const maxIterations = 10; // Prevent infinite loops
|
|
178
|
-
let finalResponse = '';
|
|
179
|
-
|
|
180
|
-
while (shouldContinue && iteration < maxIterations) {
|
|
181
|
-
iteration++;
|
|
182
|
-
console.log('š¤ Thinking...');
|
|
183
|
-
|
|
184
|
-
const response = await callOpenRouter(messages);
|
|
185
|
-
const assistantMessage = response.choices[0].message;
|
|
186
|
-
|
|
187
|
-
// Add assistant's message to the conversation
|
|
188
|
-
messages.push(assistantMessage);
|
|
189
|
-
|
|
190
|
-
// Check if the response contains actions
|
|
191
|
-
const actionData = extractJsonFromMarkdown(assistantMessage.content);
|
|
192
|
-
|
|
193
|
-
if (actionData && actionData.actions && Array.isArray(actionData.actions)) {
|
|
194
|
-
console.log(`š§ Processing ${actionData.actions.length} actions...`);
|
|
195
|
-
if (actionData.thoughts) {
|
|
196
|
-
console.log(`š ${actionData.thoughts}`);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
const actionResults = [];
|
|
200
|
-
|
|
201
|
-
for (const action of actionData.actions) {
|
|
202
|
-
console.log(`š ļø Executing action: ${action.type}`);
|
|
203
|
-
|
|
204
|
-
// Handle stop action
|
|
205
|
-
if (action.type === 'stop') {
|
|
206
|
-
console.log('š Stop action received, ending action processing');
|
|
207
|
-
shouldContinue = false;
|
|
208
|
-
finalResponse = 'Task completed successfully.';
|
|
209
|
-
break;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
try {
|
|
213
|
-
let result;
|
|
214
|
-
|
|
215
|
-
switch (action.type) {
|
|
216
|
-
case 'read':
|
|
217
|
-
result = await agentUtils.readFile(action.data.path);
|
|
218
|
-
break;
|
|
219
|
-
|
|
220
|
-
case 'write':
|
|
221
|
-
result = await agentUtils.writeFile(action.data.path, action.data.content);
|
|
222
|
-
break;
|
|
223
|
-
|
|
224
|
-
case 'command':
|
|
225
|
-
result = await agentUtils.runCommand(action.data.command);
|
|
226
|
-
break;
|
|
227
|
-
|
|
228
|
-
case 'search':
|
|
229
|
-
if (action.data.type === 'files') {
|
|
230
|
-
result = await agentUtils.searchFiles(action.data.pattern);
|
|
231
|
-
} else {
|
|
232
|
-
result = 'Text search not yet implemented';
|
|
233
|
-
}
|
|
234
|
-
break;
|
|
235
|
-
|
|
236
|
-
default:
|
|
237
|
-
result = `Action type '${action.type}' is not supported yet.`;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
actionResults.push({
|
|
241
|
-
type: action.type,
|
|
242
|
-
success: true,
|
|
243
|
-
result: result
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
console.log(`ā
Action ${action.type} completed successfully`);
|
|
247
|
-
|
|
248
|
-
} catch (error) {
|
|
249
|
-
console.error(`ā Action ${action.type} failed:`, error);
|
|
250
|
-
actionResults.push({
|
|
251
|
-
type: action.type,
|
|
252
|
-
success: false,
|
|
253
|
-
error: error.message
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// Add action results to the conversation
|
|
259
|
-
messages.push({
|
|
260
|
-
role: 'system',
|
|
261
|
-
content: `Action results:\n\`\`\`json\n${JSON.stringify(actionResults, null, 2)}\n\`\`\`\n` +
|
|
262
|
-
`Based on these results, determine what to do next. You can:\n` +
|
|
263
|
-
`1. Continue with more actions by returning a new JSON with "actions" array\n` +
|
|
264
|
-
`2. Stop the iteration by including an action with "type": "stop" if the task is completed\n` +
|
|
265
|
-
`3. Provide a final response to the user with your findings`
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
} else {
|
|
269
|
-
// No actions, this is a regular response
|
|
270
|
-
shouldContinue = false;
|
|
271
|
-
finalResponse = assistantMessage.content;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
// If we hit max iterations, add a note
|
|
276
|
-
if (iteration >= maxIterations) {
|
|
277
|
-
finalResponse += '\n\nā ļø Reached maximum number of iterations. Stopping execution.';
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
return {
|
|
281
|
-
response: finalResponse,
|
|
282
|
-
conversation: messages
|
|
283
|
-
};
|
|
284
|
-
|
|
285
|
-
} catch (error) {
|
|
286
|
-
console.error('Error processing query:', error);
|
|
287
|
-
return {
|
|
288
|
-
response: `Error: ${error.message}`,
|
|
289
|
-
conversation
|
|
290
|
-
};
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
// Main chat loop
|
|
295
|
-
async function chat() {
|
|
296
|
-
const conversation = [];
|
|
297
|
-
console.log('Welcome to AGI-CLI. Type your message, or "exit" to quit.');
|
|
298
|
-
|
|
299
|
-
const rl = readline.createInterface({
|
|
300
|
-
input: process.stdin,
|
|
301
|
-
output: process.stdout,
|
|
302
|
-
prompt: '> '
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
rl.prompt();
|
|
306
|
-
|
|
307
|
-
rl.on('line', async (input) => {
|
|
308
|
-
if (input.toLowerCase() === 'exit') {
|
|
309
|
-
rl.close();
|
|
310
|
-
return;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
const result = await processQuery(input, conversation);
|
|
314
|
-
console.log(result.response);
|
|
315
|
-
|
|
316
|
-
// Update conversation with the full context
|
|
317
|
-
conversation.length = 0; // Clear the array
|
|
318
|
-
result.conversation.forEach(msg => conversation.push(msg));
|
|
319
|
-
|
|
320
|
-
rl.prompt();
|
|
321
|
-
}).on('close', () => {
|
|
322
|
-
console.log('Goodbye!');
|
|
323
|
-
process.exit(0);
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
// Start the chat
|
|
328
|
-
chat().catch(console.error);
|