mirror of
https://github.com/kolbytn/mindcraft.git
synced 2025-06-08 02:05:54 +02:00
Merge cc7e20637a
into f2f06fcf3f
This commit is contained in:
commit
c44ff42177
9 changed files with 114 additions and 3 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,4 +1,6 @@
|
|||
.vscode/
|
||||
.fslckout
|
||||
._*
|
||||
.idea/
|
||||
node_modules/
|
||||
package-lock.json
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "andy",
|
||||
|
||||
"model": "gpt-4o-mini"
|
||||
"model": "qwen-max"
|
||||
|
||||
}
|
|
@ -45,6 +45,7 @@ const settings = {
|
|||
"narrate_behavior": true, // chat simple automatic actions ('Picking up item!')
|
||||
"chat_bot_messages": true, // publicly chat messages to other bots
|
||||
"log_all_prompts": false, // log ALL prompts to file
|
||||
// "plugins" : ["Dance"], // plugin will be loaded if and only if it's name appears here
|
||||
}
|
||||
|
||||
// these environment variables override certain settings
|
||||
|
|
BIN
src/agent/._action_manager.js
Normal file
BIN
src/agent/._action_manager.js
Normal file
Binary file not shown.
|
@ -7,6 +7,7 @@ import { initBot } from '../utils/mcdata.js';
|
|||
import { containsCommand, commandExists, executeCommand, truncCommandMessage, isAction, blacklistCommands } from './commands/index.js';
|
||||
import { ActionManager } from './action_manager.js';
|
||||
import { NPCContoller } from './npc/controller.js';
|
||||
import { PluginManager } from './plugin.js';
|
||||
import { MemoryBank } from './memory_bank.js';
|
||||
import { SelfPrompter } from './self_prompter.js';
|
||||
import convoManager from './conversation.js';
|
||||
|
@ -39,6 +40,8 @@ export class Agent {
|
|||
this.coder = new Coder(this);
|
||||
console.log('Initializing npc controller...');
|
||||
this.npc = new NPCContoller(this);
|
||||
console.log('Initializing plugin manager...');
|
||||
this.plugin = new PluginManager(this);
|
||||
console.log('Initializing memory bank...');
|
||||
this.memory_bank = new MemoryBank();
|
||||
console.log('Initializing self prompter...');
|
||||
|
@ -457,6 +460,8 @@ export class Agent {
|
|||
|
||||
// Init NPC controller
|
||||
this.npc.init();
|
||||
// Init plugins manager
|
||||
this.plugin.init();
|
||||
|
||||
// This update loop ensures that each update() is called one at a time, even if it takes longer than the interval
|
||||
const INTERVAL = 300;
|
||||
|
|
|
@ -2,8 +2,7 @@ import * as skills from '../library/skills.js';
|
|||
import settings from '../../../settings.js';
|
||||
import convoManager from '../conversation.js';
|
||||
|
||||
|
||||
function runAsAction (actionFn, resume = false, timeout = -1) {
|
||||
export function runAsAction (actionFn, resume = false, timeout = -1) {
|
||||
let actionLabel = null; // Will be set on first use
|
||||
|
||||
const wrappedAction = async function (agent, ...args) {
|
||||
|
|
|
@ -26,6 +26,18 @@ export function blacklistCommands(commands) {
|
|||
}
|
||||
}
|
||||
|
||||
export function addPluginActions(plugin, actions) {
|
||||
for (let action of actions) {
|
||||
if (commandMap[action.name]) {
|
||||
console.log(`Command already exists. Can't add ${action.name} from plugin ${plugin}.`)
|
||||
} else {
|
||||
commandMap[action.name] = action;
|
||||
commandList.push(action);
|
||||
actionsList.push(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const commandRegex = /!(\w+)(?:\(((?:-?\d+(?:\.\d+)?|true|false|"[^"]*")(?:\s*,\s*(?:-?\d+(?:\.\d+)?|true|false|"[^"]*"))*)\))?/
|
||||
const argRegex = /-?\d+(?:\.\d+)?|true|false|"[^"]*"/g;
|
||||
|
||||
|
|
59
src/agent/plugin.js
Normal file
59
src/agent/plugin.js
Normal file
|
@ -0,0 +1,59 @@
|
|||
|
||||
import { readdirSync, readFileSync } from 'fs';
|
||||
import { join, relative, isAbsolute } from 'path';
|
||||
import { pathToFileURL } from 'url';
|
||||
import settings from '../../settings.js';
|
||||
import { addPluginActions } from './commands/index.js';
|
||||
|
||||
export class PluginManager {
|
||||
constructor(agent) {
|
||||
this.agent = agent;
|
||||
this.plugins = {};
|
||||
}
|
||||
|
||||
init() {
|
||||
this.importPlugins()
|
||||
.then((plugins) => {
|
||||
this.plugins = plugins;
|
||||
for (let plugin in this.plugins) {
|
||||
addPluginActions(plugin, this.plugins[plugin].getPluginActions());
|
||||
}
|
||||
console.log("Load plugins:", Object.keys(this.plugins).join(", "));
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error importing plugins:", error);
|
||||
});
|
||||
}
|
||||
|
||||
async importPlugin(dir, name) {
|
||||
let path = join(dir, name, "main.js");
|
||||
let instance = null;
|
||||
try {
|
||||
const plugin = await import(pathToFileURL(path).href);
|
||||
if (plugin.PluginInstance) {
|
||||
instance = new plugin.PluginInstance(this.agent);
|
||||
instance.init();
|
||||
} else {
|
||||
console.error(`Can't find PluginInstance in ${path}.`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error import plugin ${path}:`, error);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
async importPlugins(dir = "src/plugins") {
|
||||
let plugins = {};
|
||||
try {
|
||||
for (let file of readdirSync(dir, { withFileTypes: true })) {
|
||||
if (settings.plugins && settings.plugins.includes(file.name) && file.isDirectory && !file.name.startsWith('.')) {
|
||||
let instance = await this.importPlugin(dir, file.name);
|
||||
plugins[file.name] = instance;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error importing plugins in ${dir}:`, error);
|
||||
}
|
||||
return plugins;
|
||||
}
|
||||
}
|
33
src/plugins/Dance/main.js
Normal file
33
src/plugins/Dance/main.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
import { Vec3 } from 'vec3';
|
||||
import { readdirSync, readFileSync } from 'fs';
|
||||
import * as skills from '../../agent/library/skills.js';
|
||||
import * as world from '../../agent/library/world.js';
|
||||
import { runAsAction } from '../../agent/commands/actions.js';
|
||||
import * as mc from '../../utils/mcdata.js';
|
||||
|
||||
export class PluginInstance {
|
||||
constructor(agent) {
|
||||
this.agent = agent;
|
||||
}
|
||||
|
||||
init() {
|
||||
}
|
||||
|
||||
getPluginActions() {
|
||||
return [
|
||||
{
|
||||
name: '!dancePoping',
|
||||
description: 'Dance poping.',
|
||||
params: {
|
||||
'duration': {type: 'int', description: 'The time duration (in millions seconds, i.e. 1000 for 1 second) of dancing.'},
|
||||
},
|
||||
perform: runAsAction(async (agent, duration) => {
|
||||
this.agent.bot.chat("I am dancing~");
|
||||
this.agent.bot.setControlState("jump", true);
|
||||
await new Promise((resolve) => setTimeout(resolve, duration));
|
||||
this.agent.bot.setControlState("jump", false);
|
||||
})
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue