mindcraft 0.1.4-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/FAQ.md +38 -0
- package/LICENSE +21 -0
- package/README.md +255 -0
- package/andy.json +6 -0
- package/bin/mindcraft.js +80 -0
- package/keys.example.json +19 -0
- package/main.js +80 -0
- package/package.json +78 -0
- package/patches/minecraft-data+3.97.0.patch +13 -0
- package/patches/mineflayer+4.33.0.patch +54 -0
- package/patches/mineflayer-pathfinder+2.4.5.patch +265 -0
- package/patches/mineflayer-pvp+1.3.2.patch +13 -0
- package/patches/prismarine-viewer+1.33.0.patch +13 -0
- package/patches/protodef+1.19.0.patch +15 -0
- package/profiles/andy-4-reasoning.json +14 -0
- package/profiles/andy-4.json +7 -0
- package/profiles/azure.json +19 -0
- package/profiles/claude.json +7 -0
- package/profiles/claude_thinker.json +15 -0
- package/profiles/deepseek.json +7 -0
- package/profiles/defaults/_default.json +256 -0
- package/profiles/defaults/assistant.json +14 -0
- package/profiles/defaults/creative.json +14 -0
- package/profiles/defaults/god_mode.json +14 -0
- package/profiles/defaults/survival.json +14 -0
- package/profiles/freeguy.json +7 -0
- package/profiles/gemini.json +9 -0
- package/profiles/gpt.json +12 -0
- package/profiles/grok.json +7 -0
- package/profiles/llama.json +10 -0
- package/profiles/mercury.json +9 -0
- package/profiles/mistral.json +5 -0
- package/profiles/qwen.json +17 -0
- package/profiles/tasks/construction_profile.json +42 -0
- package/profiles/tasks/cooking_profile.json +11 -0
- package/profiles/tasks/crafting_profile.json +71 -0
- package/profiles/vllm.json +10 -0
- package/settings.js +64 -0
- package/src/agent/action_manager.js +177 -0
- package/src/agent/agent.js +561 -0
- package/src/agent/coder.js +229 -0
- package/src/agent/commands/actions.js +504 -0
- package/src/agent/commands/index.js +259 -0
- package/src/agent/commands/queries.js +347 -0
- package/src/agent/connection_handler.js +96 -0
- package/src/agent/conversation.js +353 -0
- package/src/agent/history.js +122 -0
- package/src/agent/library/full_state.js +89 -0
- package/src/agent/library/index.js +23 -0
- package/src/agent/library/lockdown.js +32 -0
- package/src/agent/library/skill_library.js +93 -0
- package/src/agent/library/skills.js +2093 -0
- package/src/agent/library/world.js +431 -0
- package/src/agent/memory_bank.js +25 -0
- package/src/agent/mindserver_proxy.js +136 -0
- package/src/agent/modes.js +446 -0
- package/src/agent/npc/build_goal.js +80 -0
- package/src/agent/npc/construction/dirt_shelter.json +38 -0
- package/src/agent/npc/construction/large_house.json +230 -0
- package/src/agent/npc/construction/small_stone_house.json +42 -0
- package/src/agent/npc/construction/small_wood_house.json +42 -0
- package/src/agent/npc/controller.js +261 -0
- package/src/agent/npc/data.js +50 -0
- package/src/agent/npc/item_goal.js +355 -0
- package/src/agent/npc/utils.js +126 -0
- package/src/agent/self_prompter.js +146 -0
- package/src/agent/settings.js +7 -0
- package/src/agent/speak.js +150 -0
- package/src/agent/tasks/construction_tasks.js +1104 -0
- package/src/agent/tasks/cooking_tasks.js +358 -0
- package/src/agent/tasks/tasks.js +594 -0
- package/src/agent/templates/execTemplate.js +6 -0
- package/src/agent/templates/lintTemplate.js +10 -0
- package/src/agent/vision/browser_viewer.js +8 -0
- package/src/agent/vision/camera.js +78 -0
- package/src/agent/vision/vision_interpreter.js +82 -0
- package/src/mindcraft/index.js +28 -0
- package/src/mindcraft/mcserver.js +154 -0
- package/src/mindcraft/mindcraft.js +111 -0
- package/src/mindcraft/mindserver.js +328 -0
- package/src/mindcraft/public/index.html +1253 -0
- package/src/mindcraft/public/settings_spec.json +145 -0
- package/src/mindcraft/userconfig.js +72 -0
- package/src/mindcraft-py/example.py +27 -0
- package/src/mindcraft-py/init-mindcraft.js +24 -0
- package/src/mindcraft-py/mindcraft.py +99 -0
- package/src/models/_model_map.js +89 -0
- package/src/models/azure.js +32 -0
- package/src/models/cerebras.js +61 -0
- package/src/models/claude.js +87 -0
- package/src/models/deepseek.js +59 -0
- package/src/models/gemini.js +176 -0
- package/src/models/glhf.js +71 -0
- package/src/models/gpt.js +147 -0
- package/src/models/grok.js +82 -0
- package/src/models/groq.js +95 -0
- package/src/models/huggingface.js +86 -0
- package/src/models/hyperbolic.js +114 -0
- package/src/models/lmstudio.js +74 -0
- package/src/models/mercury.js +95 -0
- package/src/models/mistral.js +94 -0
- package/src/models/novita.js +71 -0
- package/src/models/ollama.js +115 -0
- package/src/models/openrouter.js +77 -0
- package/src/models/prompter.js +366 -0
- package/src/models/qwen.js +80 -0
- package/src/models/replicate.js +60 -0
- package/src/models/vllm.js +81 -0
- package/src/process/agent_process.js +84 -0
- package/src/process/init_agent.js +54 -0
- package/src/utils/examples.js +83 -0
- package/src/utils/keys.js +34 -0
- package/src/utils/math.js +13 -0
- package/src/utils/mcdata.js +572 -0
- package/src/utils/text.js +78 -0
- package/src/utils/translator.js +30 -0
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
import { Server } from 'socket.io';
|
|
2
|
+
import express from 'express';
|
|
3
|
+
import http from 'http';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import * as mindcraft from './mindcraft.js';
|
|
7
|
+
import * as userconfig from './userconfig.js';
|
|
8
|
+
import { readFileSync } from 'fs';
|
|
9
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
|
|
11
|
+
// Mindserver is:
|
|
12
|
+
// - central hub for communication between all agent processes
|
|
13
|
+
// - api to control from other languages and remote users
|
|
14
|
+
// - host for webapp
|
|
15
|
+
|
|
16
|
+
let io;
|
|
17
|
+
let server;
|
|
18
|
+
const agent_connections = {};
|
|
19
|
+
const agent_listeners = [];
|
|
20
|
+
|
|
21
|
+
const settings_spec = JSON.parse(readFileSync(path.join(__dirname, 'public/settings_spec.json'), 'utf8'));
|
|
22
|
+
|
|
23
|
+
// Allows the CLI / library callers to override defaults (e.g. data_dir) for
|
|
24
|
+
// agents created later via the web UI's create-agent socket event.
|
|
25
|
+
export function overrideSpecDefaults(overrides) {
|
|
26
|
+
for (const [key, value] of Object.entries(overrides)) {
|
|
27
|
+
if (settings_spec[key]) settings_spec[key].default = value;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
class AgentConnection {
|
|
32
|
+
constructor(settings, viewer_port) {
|
|
33
|
+
this.socket = null;
|
|
34
|
+
this.settings = settings;
|
|
35
|
+
this.in_game = false;
|
|
36
|
+
this.full_state = null;
|
|
37
|
+
this.viewer_port = viewer_port;
|
|
38
|
+
}
|
|
39
|
+
setSettings(settings) {
|
|
40
|
+
this.settings = settings;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function registerAgent(settings, viewer_port) {
|
|
45
|
+
let agentConnection = new AgentConnection(settings, viewer_port);
|
|
46
|
+
agent_connections[settings.profile.name] = agentConnection;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function logoutAgent(agentName) {
|
|
50
|
+
if (agent_connections[agentName]) {
|
|
51
|
+
agent_connections[agentName].in_game = false;
|
|
52
|
+
agentsStatusUpdate();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Initialize the server
|
|
57
|
+
export function createMindServer(host_public = false, port = 8080) {
|
|
58
|
+
const app = express();
|
|
59
|
+
server = http.createServer(app);
|
|
60
|
+
io = new Server(server);
|
|
61
|
+
|
|
62
|
+
// Serve static files
|
|
63
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
64
|
+
app.use(express.static(path.join(__dirname, 'public')));
|
|
65
|
+
|
|
66
|
+
// Socket.io connection handling
|
|
67
|
+
io.on('connection', (socket) => {
|
|
68
|
+
let curAgentName = null;
|
|
69
|
+
console.log('Client connected');
|
|
70
|
+
|
|
71
|
+
agentsStatusUpdate(socket);
|
|
72
|
+
|
|
73
|
+
socket.on('create-agent', async (settings, callback) => {
|
|
74
|
+
console.log('API create agent...');
|
|
75
|
+
for (let key in settings_spec) {
|
|
76
|
+
if (!(key in settings)) {
|
|
77
|
+
if (settings_spec[key].required) {
|
|
78
|
+
callback({ success: false, error: `Setting ${key} is required` });
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
settings[key] = settings_spec[key].default;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
for (let key in settings) {
|
|
87
|
+
if (!(key in settings_spec)) {
|
|
88
|
+
delete settings[key];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (settings.profile?.name) {
|
|
92
|
+
if (settings.profile.name in agent_connections) {
|
|
93
|
+
callback({ success: false, error: 'Agent already exists' });
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
let returned = await mindcraft.createAgent(settings);
|
|
97
|
+
callback({ success: returned.success, error: returned.error });
|
|
98
|
+
let name = settings.profile.name;
|
|
99
|
+
if (!returned.success && agent_connections[name]) {
|
|
100
|
+
mindcraft.destroyAgent(name);
|
|
101
|
+
delete agent_connections[name];
|
|
102
|
+
}
|
|
103
|
+
agentsStatusUpdate();
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
console.error('Agent name is required in profile');
|
|
107
|
+
callback({ success: false, error: 'Agent name is required in profile' });
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
socket.on('get-settings', (agentName, callback) => {
|
|
112
|
+
if (agent_connections[agentName]) {
|
|
113
|
+
callback({ settings: agent_connections[agentName].settings });
|
|
114
|
+
} else {
|
|
115
|
+
callback({ error: `Agent '${agentName}' not found.` });
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
socket.on('connect-agent-process', (agentName) => {
|
|
120
|
+
if (agent_connections[agentName]) {
|
|
121
|
+
agent_connections[agentName].socket = socket;
|
|
122
|
+
agentsStatusUpdate();
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
socket.on('login-agent', (agentName) => {
|
|
127
|
+
if (agent_connections[agentName]) {
|
|
128
|
+
agent_connections[agentName].socket = socket;
|
|
129
|
+
agent_connections[agentName].in_game = true;
|
|
130
|
+
curAgentName = agentName;
|
|
131
|
+
agentsStatusUpdate();
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
console.warn(`Unregistered agent ${agentName} tried to login`);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
socket.on('disconnect', () => {
|
|
139
|
+
if (agent_connections[curAgentName]) {
|
|
140
|
+
console.log(`Agent ${curAgentName} disconnected`);
|
|
141
|
+
agent_connections[curAgentName].in_game = false;
|
|
142
|
+
agent_connections[curAgentName].socket = null;
|
|
143
|
+
agentsStatusUpdate();
|
|
144
|
+
}
|
|
145
|
+
if (agent_listeners.includes(socket)) {
|
|
146
|
+
removeListener(socket);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
socket.on('chat-message', (agentName, json) => {
|
|
151
|
+
if (!agent_connections[agentName]) {
|
|
152
|
+
console.warn(`Agent ${agentName} tried to send a message but is not logged in`);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
console.log(`${curAgentName} sending message to ${agentName}: ${json.message}`);
|
|
156
|
+
agent_connections[agentName].socket.emit('chat-message', curAgentName, json);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
socket.on('set-agent-settings', (agentName, settings) => {
|
|
160
|
+
const agent = agent_connections[agentName];
|
|
161
|
+
if (agent) {
|
|
162
|
+
agent.setSettings(settings);
|
|
163
|
+
agent.socket.emit('restart-agent');
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
socket.on('restart-agent', (agentName) => {
|
|
168
|
+
console.log(`Restarting agent: ${agentName}`);
|
|
169
|
+
agent_connections[agentName].socket.emit('restart-agent');
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
socket.on('stop-agent', (agentName) => {
|
|
173
|
+
mindcraft.stopAgent(agentName);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
socket.on('start-agent', (agentName) => {
|
|
177
|
+
mindcraft.startAgent(agentName);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
socket.on('destroy-agent', (agentName) => {
|
|
181
|
+
if (agent_connections[agentName]) {
|
|
182
|
+
mindcraft.destroyAgent(agentName);
|
|
183
|
+
delete agent_connections[agentName];
|
|
184
|
+
}
|
|
185
|
+
agentsStatusUpdate();
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
socket.on('stop-all-agents', () => {
|
|
189
|
+
console.log('Killing all agents');
|
|
190
|
+
for (let agentName in agent_connections) {
|
|
191
|
+
mindcraft.stopAgent(agentName);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
socket.on('shutdown', () => {
|
|
196
|
+
console.log('Shutting down');
|
|
197
|
+
for (let agentName in agent_connections) {
|
|
198
|
+
mindcraft.stopAgent(agentName);
|
|
199
|
+
}
|
|
200
|
+
// wait 2 seconds
|
|
201
|
+
setTimeout(() => {
|
|
202
|
+
console.log('Exiting MindServer');
|
|
203
|
+
process.exit(0);
|
|
204
|
+
}, 2000);
|
|
205
|
+
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
socket.on('send-message', (agentName, data) => {
|
|
209
|
+
if (!agent_connections[agentName]) {
|
|
210
|
+
console.warn(`Agent ${agentName} not in game, cannot send message via MindServer.`);
|
|
211
|
+
return
|
|
212
|
+
}
|
|
213
|
+
try {
|
|
214
|
+
agent_connections[agentName].socket.emit('send-message', data)
|
|
215
|
+
} catch (error) {
|
|
216
|
+
console.error('Error: ', error);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
socket.on('bot-output', (agentName, message) => {
|
|
221
|
+
io.emit('bot-output', agentName, message);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
socket.on('listen-to-agents', () => {
|
|
225
|
+
addListener(socket);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
// ---- setup wizard / persistence ----
|
|
229
|
+
|
|
230
|
+
socket.on('get-config', (callback) => {
|
|
231
|
+
callback({
|
|
232
|
+
config: userconfig.getConfig(),
|
|
233
|
+
hasKeys: userconfig.hasKeys(),
|
|
234
|
+
profiles: userconfig.listProfiles(),
|
|
235
|
+
settingsSpec: settings_spec,
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
socket.on('save-keys', (keys, callback) => {
|
|
240
|
+
try { userconfig.saveKeys(keys); callback({ success: true }); }
|
|
241
|
+
catch (e) { callback({ success: false, error: e.message }); }
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
socket.on('save-config', (config, callback) => {
|
|
245
|
+
try {
|
|
246
|
+
userconfig.saveConfig(config);
|
|
247
|
+
if (config.server) overrideSpecDefaults(config.server);
|
|
248
|
+
callback({ success: true });
|
|
249
|
+
} catch (e) { callback({ success: false, error: e.message }); }
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
socket.on('save-profile', (profile, callback) => {
|
|
253
|
+
try { userconfig.saveProfile(profile); callback({ success: true }); }
|
|
254
|
+
catch (e) { callback({ success: false, error: e.message }); }
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
socket.on('list-profiles', (callback) => {
|
|
258
|
+
callback({ profiles: userconfig.listProfiles() });
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
if (host_public) {
|
|
263
|
+
console.log('Public hosting not supported yet. Using localhost.');
|
|
264
|
+
}
|
|
265
|
+
const host = 'localhost';
|
|
266
|
+
server.listen(port, host, () => {
|
|
267
|
+
console.log(`MindServer running on port ${port} on host ${host}`);
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
return server;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function agentsStatusUpdate(socket) {
|
|
274
|
+
if (!socket) {
|
|
275
|
+
socket = io;
|
|
276
|
+
}
|
|
277
|
+
let agents = [];
|
|
278
|
+
for (let agentName in agent_connections) {
|
|
279
|
+
const conn = agent_connections[agentName];
|
|
280
|
+
agents.push({
|
|
281
|
+
name: agentName,
|
|
282
|
+
in_game: conn.in_game,
|
|
283
|
+
viewerPort: conn.viewer_port,
|
|
284
|
+
socket_connected: !!conn.socket
|
|
285
|
+
});
|
|
286
|
+
};
|
|
287
|
+
socket.emit('agents-status', agents);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
let listenerInterval = null;
|
|
292
|
+
function addListener(listener_socket) {
|
|
293
|
+
agent_listeners.push(listener_socket);
|
|
294
|
+
if (agent_listeners.length === 1) {
|
|
295
|
+
listenerInterval = setInterval(async () => {
|
|
296
|
+
const states = {};
|
|
297
|
+
for (let agentName in agent_connections) {
|
|
298
|
+
let agent = agent_connections[agentName];
|
|
299
|
+
if (agent.in_game) {
|
|
300
|
+
try {
|
|
301
|
+
const state = await new Promise((resolve) => {
|
|
302
|
+
agent.socket.emit('get-full-state', (s) => resolve(s));
|
|
303
|
+
});
|
|
304
|
+
states[agentName] = state;
|
|
305
|
+
} catch (e) {
|
|
306
|
+
states[agentName] = { error: String(e) };
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
for (let listener of agent_listeners) {
|
|
311
|
+
listener.emit('state-update', states);
|
|
312
|
+
}
|
|
313
|
+
}, 1000);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function removeListener(listener_socket) {
|
|
318
|
+
agent_listeners.splice(agent_listeners.indexOf(listener_socket), 1);
|
|
319
|
+
if (agent_listeners.length === 0) {
|
|
320
|
+
clearInterval(listenerInterval);
|
|
321
|
+
listenerInterval = null;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Optional: export these if you need access to them from other files
|
|
326
|
+
export const getIO = () => io;
|
|
327
|
+
export const getServer = () => server;
|
|
328
|
+
export const numStateListeners = () => agent_listeners.length;
|