first commit

This commit is contained in:
Raven Scott 2024-12-10 04:10:46 -05:00
commit 90482142d2
5 changed files with 381 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.env
node_modules
package-lock.json

204
README.md Normal file
View File

@ -0,0 +1,204 @@
# Remote Container Manager
## Table of Contents
- [Overview](#overview)
- [Features](#features)
- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [Configuration](#configuration)
- [Usage](#usage)
- [Logging](#logging)
- [Troubleshooting](#troubleshooting)
- [Contributing](#contributing)
- [License](#license)
## Overview
**Remote Container Manager** is a Node.js script designed to automate the management of remote Debian/Ubuntu-based Linux containers. Leveraging AI-driven command generation and robust API integrations, this tool simplifies tasks such as package installation and service management by executing precise shell commands on remote containers.
## Features
- **AI-Powered Command Generation:** Utilizes AI to generate shell commands based on your specified goals and context.
- **Verbose Logging:** Detailed and formatted logs make it easy to track the script's actions and outputs.
- **API Integration:** Connects seamlessly with Groq and Discord Linux APIs to execute commands remotely.
- **Iterative Execution:** Attempts to achieve the desired state through multiple iterations, refining commands based on previous outcomes.
- **Environment Configuration:** Easily manage API keys and other settings via environment variables.
## Prerequisites
Before you begin, ensure you have met the following requirements:
- **Node.js:** Version 14.0 or higher. [Download Node.js](https://nodejs.org/)
- **Git:** For cloning the repository. [Download Git](https://git-scm.com/)
- **API Access:**
- **Groq API Key**
- **Discord Linux API Key**
## Installation
1. **Clone the Repository**
```bash
git clone https://github.com/yourusername/remote-container-manager.git
cd remote-container-manager
```
2. **Install Dependencies**
Ensure you have [Node.js](https://nodejs.org/) installed. Then, install the required packages:
```bash
npm install
```
## Configuration
1. **Create Environment Variables**
The script relies on environment variables for API keys and configurations. An example file named `default.env` is provided. Follow these steps to set up your environment variables:
- **Copy the Example `.env` File**
```bash
cp default.env .env
```
- **Edit the `.env` File**
Open the `.env` file in your preferred text editor and replace the placeholder values with your actual API keys.
```env
# .env
DISCORD_LINUX_API_URL=https://api.ssh.surf
DISCORD_LINUX_API_KEY=your_discord_linux_api_key
GROQ_API_KEY=your_groq_api_key
```
- **Environment Variables Explained**
| Variable | Description |
| ---------------------- | -------------------------------------------------- |
| `DISCORD_LINUX_API_URL`| The base URL for the Discord Linux API. |
| `DISCORD_LINUX_API_KEY`| Your API key for authenticating with Discord Linux. |
| `GROQ_API_KEY` | Your Groq API key for AI-driven command generation.|
## Usage
To run the script, use the following command:
```bash
node index.js
```
**Example Goal:**
```javascript
const goal = 'install apache2 (apache2) on the container and run it with service';
```
**Script Flow:**
1. **Initialization:** Sets up the Groq client and logs the starting process.
2. **AI Instruction Request:** Sends the current context and goal to the AI to receive shell commands.
3. **Command Execution:** Executes each command on the remote container, logging the output.
4. **Iteration:** Repeats the process up to a maximum number of iterations (`MAX_ITERATIONS`) until the goal is achieved or attempts are exhausted.
## Logging
The script features comprehensive and formatted logging to ensure transparency and ease of monitoring.
### Log Components
- **Headers:** Clearly marked sections indicating the start of processes and iterations.
- **Subheaders:** Indicate specific actions like requesting AI instructions.
- **Info Messages:** Provide status updates on command execution success or failure.
- **Command Execution Logs:** Detailed output of each executed command, including `stdout` and `stderr`.
**Example Log Output:**
```
════════════════════════════════════════════════════════════════════════════════════════
═ STARTING PROCESS TO ACHIEVE GOAL: install apache2 (apache2) on the container and run it with service
════════════════════════════════════════════════════════════════════════════════════════
════════════════════════════════════════════════════════════════════════════════════════
═ ITERATION 1 OF 5
════════════════════════════════════════════════════════════════════════════════════════
------------------------------------------------------------
> Asking AI for instructions
------------------------------------------------------------
AI PROVIDED COMMANDS:
sudo apt-get update
sudo apt-get install -y apache2
sudo service apache2 start
[EXECUTING COMMAND]
$ sudo apt-get update
[STDOUT]:
Get:1 http://archive.ubuntu.com/ubuntu focal InRelease [265 kB]
...
[STDERR]: (empty)
INFO: Command executed successfully.
...
SUCCESS! The goal appears to have been achieved.
```
## Troubleshooting
If you encounter issues while running the script, consider the following steps:
1. **Check Environment Variables:**
- Ensure all required environment variables are set correctly in the `.env` file.
- Verify that API keys are valid and have the necessary permissions.
2. **API Connectivity:**
- Confirm that the `DISCORD_LINUX_API_URL` is correct and reachable.
- Check your internet connection and any firewall settings that might block API requests.
3. **Dependencies:**
- Make sure all dependencies are installed by running `npm install`.
- Verify that you're using a compatible Node.js version (14.0 or higher).
4. **Script Errors:**
- Review the console logs for specific error messages.
- Ensure that the remote container is accessible and configured correctly.
5. **AI Command Accuracy:**
- If the AI provides incorrect or ineffective commands, consider refining the `systemPrompt` or providing more context.
## Contributing
Contributions are welcome! Follow these steps to contribute:
1. **Fork the Repository**
2. **Create a Feature Branch**
```bash
git checkout -b feature/YourFeature
```
3. **Commit Your Changes**
```bash
git commit -m "Add your feature"
```
4. **Push to the Branch**
```bash
git push origin feature/YourFeature
```
5. **Open a Pull Request**
Please ensure your contributions adhere to the project's coding standards and include appropriate documentation.

165
agent.mjs Normal file
View File

@ -0,0 +1,165 @@
import 'dotenv/config';
import Groq from 'groq-sdk';
import unirest from 'unirest';
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,
});
// A small helper for nice verbose logging:
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');
}
// Helper to execute a command in the container:
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;
}
// This function queries the AI for instructions. It returns a series of commands to try.
async function askAIForInstructions(context, goal) {
const systemPrompt = `You are a world-class Linux system administration assistant, given the ability to access and run commands on a remote Debian/Ubuntu-based Linux container. Your mission is to help achieve the following goal: ${goal}.
Rules:
1. Return only shell commands needed, line-by-line, no explanation.
2. If previous attempts failed, refine your approach and fix the issues based on the provided errors and output.
3. If you need to run multiple commands, separate them by new lines.
4. Consider common steps: updating package lists, installing packages, verifying installation.
5. The container might be minimal, so consider installing or fixing repositories if needed.
6. Always ensure commands are non-interactive.
7. Do not use markdown formatting at all ever.
8. All commands are non-interactive
9. If installing packages, always use -y to allow for non-interactive commands
`;
const userPrompt = `CONTEXT:\n${context}\n\nPlease provide the exact shell commands to achieve the goal above.`;
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;
}
async function main() {
const goal = 'install apache2 (apache2) on the container and run it with service';
let context = "Initial attempt. No commands have been run yet.\n" +
"We are working with a Debian/Ubuntu container.\n" +
"Goal: " + goal;
logHeader(`STARTING PROCESS TO ACHIEVE GOAL: ${goal}`);
let iteration = 0;
let success = false;
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}:\nAI instructions:\n${instructions}\n\nCommand 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}\nstdout:\n${stdout}\nstderr:\n${stderr}\n`;
if (stderr && stderr.trim().length > 0) {
logInfo(`Command failed with error detected in STDERR. Will request refined instructions next iteration.`);
allCommandsSucceeded = false;
break;
} else {
logInfo(`Command executed successfully.`);
}
}
context += `\n\n${attemptLog}`;
if (allCommandsSucceeded) {
logInfo("All commands executed successfully.");
success = true;
} else {
logInfo("At least one command failed. The AI will refine approach in next iteration.");
}
}
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);
}
}
main().catch(err => {
console.error("An error occurred:", err);
});

2
default.env Normal file
View File

@ -0,0 +1,2 @@
DISCORD_LINUX_API_KEY=
GROQ_API_KEY=

7
package.json Normal file
View File

@ -0,0 +1,7 @@
{
"dependencies": {
"dotenv": "^16.4.7",
"groq-sdk": "^0.9.0",
"unirest": "^0.6.0"
}
}