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/
|
.vscode/
|
||||||
|
.fslckout
|
||||||
|
._*
|
||||||
.idea/
|
.idea/
|
||||||
node_modules/
|
node_modules/
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "andy",
|
"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!')
|
"narrate_behavior": true, // chat simple automatic actions ('Picking up item!')
|
||||||
"chat_bot_messages": true, // publicly chat messages to other bots
|
"chat_bot_messages": true, // publicly chat messages to other bots
|
||||||
"log_all_prompts": false, // log ALL prompts to file
|
"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
|
// 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 { containsCommand, commandExists, executeCommand, truncCommandMessage, isAction, blacklistCommands } from './commands/index.js';
|
||||||
import { ActionManager } from './action_manager.js';
|
import { ActionManager } from './action_manager.js';
|
||||||
import { NPCContoller } from './npc/controller.js';
|
import { NPCContoller } from './npc/controller.js';
|
||||||
|
import { PluginManager } from './plugin.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 convoManager from './conversation.js';
|
import convoManager from './conversation.js';
|
||||||
|
@ -39,6 +40,8 @@ export class Agent {
|
||||||
this.coder = new Coder(this);
|
this.coder = new Coder(this);
|
||||||
console.log('Initializing npc controller...');
|
console.log('Initializing npc controller...');
|
||||||
this.npc = new NPCContoller(this);
|
this.npc = new NPCContoller(this);
|
||||||
|
console.log('Initializing plugin manager...');
|
||||||
|
this.plugin = new PluginManager(this);
|
||||||
console.log('Initializing memory bank...');
|
console.log('Initializing memory bank...');
|
||||||
this.memory_bank = new MemoryBank();
|
this.memory_bank = new MemoryBank();
|
||||||
console.log('Initializing self prompter...');
|
console.log('Initializing self prompter...');
|
||||||
|
@ -457,6 +460,8 @@ export class Agent {
|
||||||
|
|
||||||
// Init NPC controller
|
// Init NPC controller
|
||||||
this.npc.init();
|
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
|
// This update loop ensures that each update() is called one at a time, even if it takes longer than the interval
|
||||||
const INTERVAL = 300;
|
const INTERVAL = 300;
|
||||||
|
|
|
@ -2,8 +2,7 @@ import * as skills from '../library/skills.js';
|
||||||
import settings from '../../../settings.js';
|
import settings from '../../../settings.js';
|
||||||
import convoManager from '../conversation.js';
|
import convoManager from '../conversation.js';
|
||||||
|
|
||||||
|
export function runAsAction (actionFn, resume = false, timeout = -1) {
|
||||||
function runAsAction (actionFn, resume = false, timeout = -1) {
|
|
||||||
let actionLabel = null; // Will be set on first use
|
let actionLabel = null; // Will be set on first use
|
||||||
|
|
||||||
const wrappedAction = async function (agent, ...args) {
|
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 commandRegex = /!(\w+)(?:\(((?:-?\d+(?:\.\d+)?|true|false|"[^"]*")(?:\s*,\s*(?:-?\d+(?:\.\d+)?|true|false|"[^"]*"))*)\))?/
|
||||||
const argRegex = /-?\d+(?:\.\d+)?|true|false|"[^"]*"/g;
|
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