added prismarine viewer, simple viewing html file, port counter

This commit is contained in:
MaxRobinsonTheGreat 2024-10-10 17:37:02 -05:00
parent 2e849b8f28
commit 05fcc9967c
8 changed files with 97 additions and 8 deletions

View file

@ -24,9 +24,9 @@ function main() {
console.log(profiles); console.log(profiles);
const { load_memory, init_message } = settings; const { load_memory, init_message } = settings;
for (const profile of profiles) { for (let i=0; i<profiles.length; i++) {
const agent = new AgentProcess(); const agent = new AgentProcess();
agent.start(profile, load_memory, init_message); agent.start(profiles[i], load_memory, init_message, i);
} }
} }

View file

@ -4,6 +4,7 @@
"@anthropic-ai/sdk": "^0.17.1", "@anthropic-ai/sdk": "^0.17.1",
"@google/generative-ai": "^0.2.1", "@google/generative-ai": "^0.2.1",
"google-translate-api-x": "^10.7.1", "google-translate-api-x": "^10.7.1",
"groq-sdk": "^0.5.0",
"minecraft-data": "^3.46.2", "minecraft-data": "^3.46.2",
"mineflayer": "^4.20.0", "mineflayer": "^4.20.0",
"mineflayer-armor-manager": "^2.0.1", "mineflayer-armor-manager": "^2.0.1",
@ -14,10 +15,10 @@
"openai": "^4.4.0", "openai": "^4.4.0",
"patch-package": "^8.0.0", "patch-package": "^8.0.0",
"prismarine-item": "^1.14.0", "prismarine-item": "^1.14.0",
"prismarine-viewer": "^1.28.0",
"replicate": "^0.29.4", "replicate": "^0.29.4",
"vec3": "^0.1.10", "vec3": "^0.1.10",
"yargs": "^17.7.2", "yargs": "^17.7.2"
"groq-sdk": "^0.5.0"
}, },
"scripts": { "scripts": {
"postinstall": "patch-package", "postinstall": "patch-package",

View file

@ -15,6 +15,7 @@ export default
"init_message": "Say hello world and your name", // sends to all on spawn "init_message": "Say hello world and your name", // sends to all on spawn
"language": "en", // translate to/from this language. Supports these language names: https://cloud.google.com/translate/docs/languages "language": "en", // translate to/from this language. Supports these language names: https://cloud.google.com/translate/docs/languages
"show_bot_views": true, // show bot's view in browser at localhost:3000, 3001...
"allow_insecure_coding": false, // allows newAction command and model can write/run code on your computer. enable at own risk "allow_insecure_coding": false, // allows newAction command and model can write/run code on your computer. enable at own risk
"code_timeout_mins": 10, // minutes code is allowed to run. -1 for no timeout "code_timeout_mins": 10, // minutes code is allowed to run. -1 for no timeout

View file

@ -7,11 +7,12 @@ import { containsCommand, commandExists, executeCommand, truncCommandMessage, is
import { NPCContoller } from './npc/controller.js'; import { NPCContoller } from './npc/controller.js';
import { MemoryBank } from './memory_bank.js'; import { MemoryBank } from './memory_bank.js';
import { SelfPrompter } from './self_prompter.js'; import { SelfPrompter } from './self_prompter.js';
import settings from '../../settings.js';
import { handleTranslation, handleEnglishTranslation } from '../utils/translator.js'; import { handleTranslation, handleEnglishTranslation } from '../utils/translator.js';
import { addViewer } from './viewer.js';
import settings from '../../settings.js';
export class Agent { export class Agent {
async start(profile_fp, load_mem=false, init_message=null) { async start(profile_fp, load_mem=false, init_message=null, count_id=0) {
this.prompter = new Prompter(this, profile_fp); this.prompter = new Prompter(this, profile_fp);
this.name = this.prompter.getName(); this.name = this.prompter.getName();
this.history = new History(this); this.history = new History(this);
@ -33,6 +34,8 @@ export class Agent {
} }
this.bot.once('spawn', async () => { this.bot.once('spawn', async () => {
addViewer(this.bot, count_id);
// wait for a bit so stats are not undefined // wait for a bit so stats are not undefined
await new Promise((resolve) => setTimeout(resolve, 1000)); await new Promise((resolve) => setTimeout(resolve, 1000));

8
src/agent/viewer.js Normal file
View file

@ -0,0 +1,8 @@
import settings from '../../settings.js';
import prismarineViewer from 'prismarine-viewer';
const mineflayerViewer = prismarineViewer.mineflayer;
export function addViewer(bot, count_id) {
if (settings.show_bot_views)
mineflayerViewer(bot, { port: 3000+count_id, firstPerson: true, });
}

View file

@ -1,9 +1,10 @@
import { spawn } from 'child_process'; import { spawn } from 'child_process';
export class AgentProcess { export class AgentProcess {
start(profile, load_memory=false, init_message=null) { start(profile, load_memory=false, init_message=null, count_id=0) {
let args = ['src/process/init-agent.js', this.name]; let args = ['src/process/init-agent.js', this.name];
args.push('-p', profile); args.push('-p', profile);
args.push('-c', count_id);
if (load_memory) if (load_memory)
args.push('-l', load_memory); args.push('-l', load_memory);
if (init_message) if (init_message)

View file

@ -22,6 +22,12 @@ const argv = yargs(args)
alias: 'm', alias: 'm',
type: 'string', type: 'string',
description: 'automatically prompt the agent on startup' description: 'automatically prompt the agent on startup'
})
.option('count_id', {
alias: 'c',
type: 'number',
default: 0,
description: 'identifying count for multi-agent scenarios',
}).argv }).argv
new Agent().start(argv.profile, argv.load_memory, argv.init_message); new Agent().start(argv.profile, argv.load_memory, argv.init_message, argv.count_id);

69
viewer.html Normal file
View file

@ -0,0 +1,69 @@
<html>
<head>
<title>Viewer</title>
<style>
body {
margin: 0;
padding: 0;
}
#container {
display: flex;
flex-wrap: wrap;
width: 100%;
height: 100vh;
}
.iframe-wrapper {
border: none;
}
</style>
</head>
<body>
<div id="container">
<iframe data-port="3000" src="http://localhost:3000" class="iframe-wrapper"></iframe>
<iframe data-port="3001" src="http://localhost:3001" class="iframe-wrapper"></iframe>
<iframe data-port="3002" src="http://localhost:3002" class="iframe-wrapper"></iframe>
<iframe data-port="3003" src="http://localhost:3003" class="iframe-wrapper"></iframe>
</div>
<script>
function updateLayout() {
var width = window.innerWidth;
var height = window.innerHeight;
var iframes = document.querySelectorAll('.iframe-wrapper');
if (width > height) {
iframes.forEach(function(iframe) {
iframe.style.width = '50%';
iframe.style.height = '50%';
});
} else {
iframes.forEach(function(iframe) {
iframe.style.width = '100%';
iframe.style.height = '25%';
});
}
}
window.addEventListener('resize', updateLayout);
window.addEventListener('load', updateLayout);
var iframes = document.querySelectorAll('.iframe-wrapper');
iframes.forEach(function(iframe) {
var port = iframe.getAttribute('data-port');
var loaded = false;
function checkServer() {
fetch('http://localhost:' + port, { method: 'HEAD' })
.then(function(response) {
if (response.ok && !loaded) {
iframe.src = 'http://localhost:' + port;
}
})
.catch(function(error) {});
}
iframe.onload = function() {
loaded = true;
};
iframe.onerror = function() {
loaded = false;
};
setInterval(checkServer, 3000);
});
</script>
</body>
</html>