sam-coder-cli 1.0.43 → 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.
@@ -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);
@@ -1,175 +0,0 @@
1
- const { MultiplayerClient } = require('./multiplayer-client');
2
- const chalk = require('chalk');
3
- const readline = require('readline');
4
- const { v4: uuidv4 } = require('uuid');
5
-
6
- class AICollaboration {
7
- constructor(options = {}) {
8
- this.client = new MultiplayerClient({
9
- name: options.name || `Agent-${uuidv4().substr(0, 4)}`,
10
- role: options.role || 'DEVELOPER',
11
- model: options.model || 'default',
12
- rl: options.rl
13
- });
14
-
15
- this.rl = options.rl || readline.createInterface({
16
- input: process.stdin,
17
- output: process.stdout
18
- });
19
-
20
- this.setupEventHandlers();
21
- }
22
-
23
- setupEventHandlers() {
24
- this.client.on('connected', () => {
25
- console.log(chalk.green('āœ… Connected to multiplayer server'));
26
- });
27
-
28
- this.client.on('disconnected', () => {
29
- console.log(chalk.yellow('Disconnected from multiplayer server'));
30
- });
31
-
32
- this.client.on('error', (error) => {
33
- console.error(chalk.red('Error:'), error.message);
34
- });
35
-
36
- this.client.on('session_joined', (data) => {
37
- console.log(chalk.green(`\nšŸŽ‰ Joined session ${data.sessionId} as ${this.client.name}`));
38
- console.log(chalk.blue(`Role: ${this.client.role}`));
39
- console.log(chalk.blue(`Host: ${data.isHost ? 'Yes' : 'No'}`));
40
-
41
- if (data.isHost) {
42
- console.log('\nAs the host, you can now enter a project prompt (e.g., "create a calculator"):');
43
- this.promptForProject();
44
- } else {
45
- console.log('\nWaiting for host to start a project...');
46
- }
47
- });
48
-
49
- this.client.on('task_assigned', (task) => {
50
- console.log(chalk.yellow(`\nšŸ“‹ Task assigned: ${task.description}`));
51
- console.log('Working on task...');
52
-
53
- // Simulate working on the task
54
- setTimeout(() => {
55
- const result = this.workOnTask(task);
56
- console.log(chalk.green('āœ… Task completed!'));
57
- console.log('Result:', result);
58
-
59
- this.client.completeTask(task.id, result);
60
- }, 2000);
61
- });
62
-
63
- this.client.on('task_completed', (data) => {
64
- if (this.client.isHost) {
65
- console.log(chalk.green(`\nšŸŽÆ Task ${data.taskId} completed by all agents!`));
66
- console.log('Results:', JSON.stringify(data.results, null, 2));
67
- }
68
- });
69
-
70
- this.client.on('chat_message', (message) => {
71
- if (message.clientId !== this.client.clientId) {
72
- console.log(`\nšŸ’¬ ${message.clientName || 'Unknown'}: ${message.text}`);
73
- }
74
- });
75
- }
76
-
77
- async start(sessionId = null) {
78
- try {
79
- await this.client.connect();
80
-
81
- if (sessionId) {
82
- console.log(`Joining session ${sessionId}...`);
83
- await this.client.joinSession(sessionId);
84
- } else {
85
- console.log('Creating new session...');
86
- const newSessionId = await this.client.createSession();
87
- console.log(`Created new session: ${newSessionId}`);
88
- console.log('Share this ID with others to collaborate!');
89
- }
90
- } catch (error) {
91
- console.error(chalk.red('Failed to start AI collaboration:'), error.message);
92
- process.exit(1);
93
- }
94
- }
95
-
96
- promptForProject() {
97
- this.rl.question('\nšŸ”¹ Enter project prompt: ', async (prompt) => {
98
- if (!prompt.trim()) {
99
- console.log(chalk.yellow('Please enter a valid prompt'));
100
- return this.promptForProject();
101
- }
102
-
103
- console.log(chalk.blue(`\nšŸ¤– AI Team is working on: ${prompt}`));
104
-
105
- // Divide tasks based on the prompt
106
- const tasks = this.divideTasks(prompt);
107
-
108
- // Assign tasks to agents
109
- for (const task of tasks) {
110
- this.client.assignTask(task);
111
- }
112
- });
113
- }
114
-
115
- divideTasks(prompt) {
116
- // Simple task division based on project type
117
- const tasks = [];
118
-
119
- if (prompt.toLowerCase().includes('calculator')) {
120
- tasks.push(
121
- { id: 'task-1', type: 'ui', description: 'Design calculator UI', assignee: 'DEVELOPER' },
122
- { id: 'task-2', type: 'logic', description: 'Implement basic arithmetic operations', assignee: 'DEVELOPER' },
123
- { id: 'task-3', type: 'features', description: 'Add advanced functions (sqrt, power, etc.)', assignee: 'DEVELOPER' },
124
- { id: 'task-4', type: 'testing', description: 'Test calculator functionality', assignee: 'REVIEWER' }
125
- );
126
- } else if (prompt.toLowerCase().includes('todo')) {
127
- tasks.push(
128
- { id: 'task-1', type: 'ui', description: 'Design todo list UI', assignee: 'DEVELOPER' },
129
- { id: 'task-2', type: 'data', description: 'Implement todo item storage', assignee: 'DEVELOPER' },
130
- { id: 'task-3', type: 'features', description: 'Add CRUD operations', assignee: 'DEVELOPER' },
131
- { id: 'task-4', type: 'features', description: 'Add filtering and sorting', assignee: 'DEVELOPER' },
132
- { id: 'task-5', type: 'testing', description: 'Test todo functionality', assignee: 'REVIEWER' }
133
- );
134
- } else {
135
- // Default task division for unknown project types
136
- tasks.push(
137
- { id: 'task-1', type: 'planning', description: 'Plan project structure', assignee: 'LEAD' },
138
- { id: 'task-2', type: 'research', description: 'Research required technologies', assignee: 'RESEARCHER' },
139
- { id: 'task-3', type: 'development', description: 'Implement core features', assignee: 'DEVELOPER' },
140
- { id: 'task-4', type: 'testing', description: 'Test the implementation', assignee: 'REVIEWER' }
141
- );
142
- }
143
-
144
- return tasks;
145
- }
146
-
147
- workOnTask(task) {
148
- // Simulate work based on task type
149
- switch (task.type) {
150
- case 'ui':
151
- return 'UI implementation completed with responsive design';
152
- case 'logic':
153
- return 'Core logic implemented and tested';
154
- case 'features':
155
- return 'Additional features implemented successfully';
156
- case 'testing':
157
- return 'All tests passed successfully';
158
- case 'planning':
159
- return 'Project plan created with milestones';
160
- case 'research':
161
- return 'Research completed with technology recommendations';
162
- default:
163
- return 'Task completed successfully';
164
- }
165
- }
166
-
167
- sendChatMessage(message) {
168
- if (message && typeof message === 'string') {
169
- this.client.sendChatMessage(message);
170
- }
171
- }
172
- }
173
-
174
- // Export the AICollaboration class
175
- module.exports = AICollaboration;