2024-12-10 04:42:17 -05:00
import 'dotenv/config' ;
import Groq from 'groq-sdk' ;
import unirest from 'unirest' ;
import readline from 'readline' ;
const DISCORD _LINUX _API _URL = 'https://api.ssh.surf' ;
const DISCORD _LINUX _API _KEY = process . env [ 'DISCORD_LINUX_API_KEY' ] ;
const GROQ _API _KEY = process . env [ 'GROQ_API_KEY' ] ;
const MAX _ITERATIONS = 5 ;
// Initialize the Groq client
const groqClient = new Groq ( {
apiKey : GROQ _API _KEY ,
} ) ;
2024-12-10 04:53:24 -05:00
// Logging helpers
2024-12-10 04:42:17 -05:00
function logHeader ( message ) {
console . log ( '\n' + '═' . repeat ( 80 ) ) ;
console . log ( '═ ' + message ) ;
console . log ( '═' . repeat ( 80 ) + '\n' ) ;
}
function logSubHeader ( message ) {
console . log ( '\n' + '-' . repeat ( 60 ) ) ;
console . log ( '> ' + message ) ;
console . log ( '-' . repeat ( 60 ) + '\n' ) ;
}
function logInfo ( message ) {
console . log ( ` INFO: ${ message } ` ) ;
}
function logCommandStart ( cmd ) {
console . log ( ` \n [EXECUTING COMMAND] \n $ ${ cmd } \n ` ) ;
}
function logCommandResult ( stdout , stderr ) {
if ( stdout && stdout . trim ( ) . length > 0 ) {
console . log ( "[STDOUT]:\n" + indentMultiline ( stdout ) ) ;
} else {
console . log ( "[STDOUT]: (empty)\n" ) ;
}
if ( stderr && stderr . trim ( ) . length > 0 ) {
console . log ( "[STDERR]:\n" + indentMultiline ( stderr ) ) ;
} else {
console . log ( "[STDERR]: (empty)\n" ) ;
}
}
function indentMultiline ( text ) {
return text . split ( '\n' ) . map ( line => ' ' + line ) . join ( '\n' ) ;
}
2024-12-10 04:53:24 -05:00
// Execute a command in the container
2024-12-10 04:42:17 -05:00
async function execCommandInContainer ( cmd , pwd = '/home' ) {
const response = await unirest
. post ( ` ${ DISCORD _LINUX _API _URL } /exec ` )
. headers ( {
'Accept' : 'application/json' ,
'Content-Type' : 'application/json' ,
'x-ssh-auth' : DISCORD _LINUX _API _KEY
} )
. send ( { cmd , pwd } ) ;
return response . body ;
}
2024-12-10 04:53:24 -05:00
// Ask AI for instructions
2024-12-10 04:42:17 -05:00
async function askAIForInstructions ( context , goal ) {
2024-12-10 04:53:24 -05:00
const systemPrompt = ` You are a highly skilled Linux system administration assistant with direct command-line access to a Debian/Ubuntu-based Linux container.
Your mission is to achieve the following goal : "${goal}"
Follow these rules :
1. Return only shell commands needed to achieve this exact goal , line - by - line , no explanations .
2. The commands must be directly related to accomplishing the goal . Do not run unrelated commands .
3. If previous attempts failed , adjust the commands based on the context and errors .
4. Consider common steps if needed ( e . g . , update packages before installing ) .
5. Always ensure non - interactive operation ( use - y for apt , etc . ) .
6. No markdown formatting . Just commands , one per line . No extra text .
7. Only include necessary commands . Avoid irrelevant repository additions or unrelated installations .
8. Do not forget the exact goal . All commands must focus on achieving the requested goal . ` ;
const userPrompt = ` CONTEXT: \n ${ context } \n \n Please provide the exact shell commands to achieve the goal: " ${ goal } " ` ;
2024-12-10 04:42:17 -05:00
const params = {
messages : [
{ role : 'system' , content : systemPrompt } ,
{ role : 'user' , content : userPrompt }
] ,
model : 'llama3-8b-8192' ,
} ;
const chatCompletion = await groqClient . chat . completions . create ( params ) ;
const aiResponse = chatCompletion . choices [ 0 ] . message . content . trim ( ) ;
return aiResponse ;
}
2024-12-10 04:53:24 -05:00
// Chat with the AI in interactive mode
2024-12-10 04:42:17 -05:00
async function chatWithAI ( context , userMessage ) {
2024-12-10 04:53:24 -05:00
const systemPrompt = ` You are a helpful Linux system administration assistant with direct command-line access to a Debian/Ubuntu-based Linux container.
You can answer questions , suggest commands , or help with Linux tasks related to the current context . Stay on topic . ` ;
2024-12-10 04:42:17 -05:00
const userPrompt = ` Context: \n ${ context } \n \n User says: ${ userMessage } ` ;
const params = {
messages : [
{ role : 'system' , content : systemPrompt } ,
{ role : 'user' , content : userPrompt }
] ,
model : 'llama3-8b-8192' ,
} ;
const chatCompletion = await groqClient . chat . completions . create ( params ) ;
const aiResponse = chatCompletion . choices [ 0 ] . message . content . trim ( ) ;
return aiResponse ;
}
function parseCommandsFromAIResponse ( aiResponse ) {
const lines = aiResponse . split ( '\n' ) . map ( l => l . trim ( ) ) . filter ( l => l . length > 0 ) ;
return lines ;
}
2024-12-10 04:53:24 -05:00
// Automate the given goal using up to MAX_ITERATIONS
2024-12-10 04:42:17 -05:00
async function automateGoal ( context , goal ) {
2024-12-10 04:53:24 -05:00
context += ` \n \n [NEW AUTOMATION ATTEMPT FOR GOAL: " ${ goal } "] \n ` ;
2024-12-10 04:42:17 -05:00
logHeader ( ` ATTEMPTING TO AUTOMATE GOAL: ${ goal } ` ) ;
let iteration = 0 ;
let success = false ;
2024-12-10 04:53:24 -05:00
2024-12-10 04:42:17 -05:00
while ( iteration < MAX _ITERATIONS && ! success ) {
iteration ++ ;
logHeader ( ` ITERATION ${ iteration } OF ${ MAX _ITERATIONS } ` ) ;
logSubHeader ( 'Asking AI for instructions' ) ;
const instructions = await askAIForInstructions ( context , goal ) ;
console . log ( "AI PROVIDED COMMANDS:\n" + indentMultiline ( instructions ) ) ;
const commands = parseCommandsFromAIResponse ( instructions ) ;
let allCommandsSucceeded = true ;
let attemptLog = ` Attempt # ${ iteration } : \n AI instructions: \n ${ instructions } \n \n Command results: \n ` ;
for ( const cmd of commands ) {
logCommandStart ( cmd ) ;
const result = await execCommandInContainer ( cmd ) ;
const stdout = result . stdout || '' ;
const stderr = result . stderr || '' ;
logCommandResult ( stdout , stderr ) ;
attemptLog += ` \n > ${ cmd } \n stdout: \n ${ stdout } \n stderr: \n ${ stderr } \n ` ;
if ( stderr && stderr . trim ( ) . length > 0 ) {
logInfo ( ` Command failed with error. Will request refined instructions next iteration. ` ) ;
allCommandsSucceeded = false ;
break ;
} else {
logInfo ( ` Command executed successfully. ` ) ;
}
}
context += ` \n \n ${ attemptLog } ` ;
2024-12-10 04:53:24 -05:00
// If no commands failed, assume success for now.
2024-12-10 04:42:17 -05:00
if ( allCommandsSucceeded ) {
success = true ;
}
}
if ( success ) {
logHeader ( "SUCCESS! The goal appears to have been achieved." ) ;
} else {
logHeader ( "FAILURE TO ACHIEVE GOAL WITHIN MAX ITERATIONS" ) ;
logInfo ( "Below is the final accumulated context/logs:\n" + context ) ;
}
return { context , success } ;
}
2024-12-10 04:53:24 -05:00
// Start interactive chat loop
2024-12-10 04:42:17 -05:00
async function startChatLoop ( context ) {
const rl = readline . createInterface ( {
input : process . stdin ,
output : process . stdout
} ) ;
logHeader ( "Entering Interactive Chat Mode" ) ;
2024-12-10 04:53:24 -05:00
console . log ( "You can ask the AI about the container or request tasks." ) ;
2024-12-10 04:42:17 -05:00
console . log ( "Type 'exit' to quit." ) ;
2024-12-10 04:53:24 -05:00
console . log ( "If the AI suggests commands, run them with 'run <line_number>'." ) ;
console . log ( 'To automate a new goal, type: automate "Your new goal"' ) ;
console . log ( ) ;
2024-12-10 04:42:17 -05:00
let lastAIResponse = "" ;
async function promptUser ( ) {
rl . question ( "> " , async ( input ) => {
if ( input . trim ( ) . toLowerCase ( ) === 'exit' ) {
rl . close ( ) ;
return ;
}
2024-12-10 04:53:24 -05:00
// Run a command from AI suggestion:
2024-12-10 04:42:17 -05:00
if ( input . startsWith ( 'run ' ) ) {
const lineNum = parseInt ( input . replace ( 'run ' , '' ) . trim ( ) , 10 ) ;
const commands = parseCommandsFromAIResponse ( lastAIResponse ) ;
if ( ! isNaN ( lineNum ) && lineNum > 0 && lineNum <= commands . length ) {
const cmd = commands [ lineNum - 1 ] ;
logInfo ( ` Running command from AI suggestion: ${ cmd } ` ) ;
const result = await execCommandInContainer ( cmd ) ;
const stdout = result . stdout || '' ;
const stderr = result . stderr || '' ;
logCommandResult ( stdout , stderr ) ;
context += ` \n User ran command: ${ cmd } \n stdout: \n ${ stdout } \n stderr: \n ${ stderr } ` ;
} else {
console . log ( "Invalid line number for running command." ) ;
}
return promptUser ( ) ;
}
2024-12-10 04:53:24 -05:00
// Automate a new goal:
2024-12-10 04:42:17 -05:00
if ( input . trim ( ) . toLowerCase ( ) . startsWith ( 'automate ' ) ) {
const goalMatch = input . match ( /^automate\s+["'](.+)["']$/i ) ;
if ( goalMatch && goalMatch [ 1 ] ) {
const newGoal = goalMatch [ 1 ] ;
const result = await automateGoal ( context , newGoal ) ;
context = result . context ;
return promptUser ( ) ;
} else {
console . log ( "To automate a new goal, use: automate \"Your new goal\"" ) ;
return promptUser ( ) ;
}
}
2024-12-10 04:53:24 -05:00
// Otherwise, treat as a normal chat message
2024-12-10 04:42:17 -05:00
lastAIResponse = await chatWithAI ( context , input ) ;
console . log ( "AI:" , lastAIResponse ) ;
promptUser ( ) ;
} ) ;
}
promptUser ( ) ;
}
async function main ( ) {
const args = process . argv . slice ( 2 ) ;
const initialGoal = args . join ( ' ' ) . trim ( ) ;
if ( ! initialGoal ) {
console . error ( "Usage: node script.js \"Your goal here\"" ) ;
process . exit ( 1 ) ;
}
2024-12-10 04:53:24 -05:00
let context = "Initial attempt. We have a Debian/Ubuntu container.\n" ;
context += "Initial Goal: " + initialGoal ;
2024-12-10 04:42:17 -05:00
const result = await automateGoal ( context , initialGoal ) ;
context = result . context ;
await startChatLoop ( context ) ;
}
main ( ) . catch ( err => {
console . error ( "An error occurred:" , err ) ;
} ) ;