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.
Files changed (116) hide show
  1. package/FAQ.md +38 -0
  2. package/LICENSE +21 -0
  3. package/README.md +255 -0
  4. package/andy.json +6 -0
  5. package/bin/mindcraft.js +80 -0
  6. package/keys.example.json +19 -0
  7. package/main.js +80 -0
  8. package/package.json +78 -0
  9. package/patches/minecraft-data+3.97.0.patch +13 -0
  10. package/patches/mineflayer+4.33.0.patch +54 -0
  11. package/patches/mineflayer-pathfinder+2.4.5.patch +265 -0
  12. package/patches/mineflayer-pvp+1.3.2.patch +13 -0
  13. package/patches/prismarine-viewer+1.33.0.patch +13 -0
  14. package/patches/protodef+1.19.0.patch +15 -0
  15. package/profiles/andy-4-reasoning.json +14 -0
  16. package/profiles/andy-4.json +7 -0
  17. package/profiles/azure.json +19 -0
  18. package/profiles/claude.json +7 -0
  19. package/profiles/claude_thinker.json +15 -0
  20. package/profiles/deepseek.json +7 -0
  21. package/profiles/defaults/_default.json +256 -0
  22. package/profiles/defaults/assistant.json +14 -0
  23. package/profiles/defaults/creative.json +14 -0
  24. package/profiles/defaults/god_mode.json +14 -0
  25. package/profiles/defaults/survival.json +14 -0
  26. package/profiles/freeguy.json +7 -0
  27. package/profiles/gemini.json +9 -0
  28. package/profiles/gpt.json +12 -0
  29. package/profiles/grok.json +7 -0
  30. package/profiles/llama.json +10 -0
  31. package/profiles/mercury.json +9 -0
  32. package/profiles/mistral.json +5 -0
  33. package/profiles/qwen.json +17 -0
  34. package/profiles/tasks/construction_profile.json +42 -0
  35. package/profiles/tasks/cooking_profile.json +11 -0
  36. package/profiles/tasks/crafting_profile.json +71 -0
  37. package/profiles/vllm.json +10 -0
  38. package/settings.js +64 -0
  39. package/src/agent/action_manager.js +177 -0
  40. package/src/agent/agent.js +561 -0
  41. package/src/agent/coder.js +229 -0
  42. package/src/agent/commands/actions.js +504 -0
  43. package/src/agent/commands/index.js +259 -0
  44. package/src/agent/commands/queries.js +347 -0
  45. package/src/agent/connection_handler.js +96 -0
  46. package/src/agent/conversation.js +353 -0
  47. package/src/agent/history.js +122 -0
  48. package/src/agent/library/full_state.js +89 -0
  49. package/src/agent/library/index.js +23 -0
  50. package/src/agent/library/lockdown.js +32 -0
  51. package/src/agent/library/skill_library.js +93 -0
  52. package/src/agent/library/skills.js +2093 -0
  53. package/src/agent/library/world.js +431 -0
  54. package/src/agent/memory_bank.js +25 -0
  55. package/src/agent/mindserver_proxy.js +136 -0
  56. package/src/agent/modes.js +446 -0
  57. package/src/agent/npc/build_goal.js +80 -0
  58. package/src/agent/npc/construction/dirt_shelter.json +38 -0
  59. package/src/agent/npc/construction/large_house.json +230 -0
  60. package/src/agent/npc/construction/small_stone_house.json +42 -0
  61. package/src/agent/npc/construction/small_wood_house.json +42 -0
  62. package/src/agent/npc/controller.js +261 -0
  63. package/src/agent/npc/data.js +50 -0
  64. package/src/agent/npc/item_goal.js +355 -0
  65. package/src/agent/npc/utils.js +126 -0
  66. package/src/agent/self_prompter.js +146 -0
  67. package/src/agent/settings.js +7 -0
  68. package/src/agent/speak.js +150 -0
  69. package/src/agent/tasks/construction_tasks.js +1104 -0
  70. package/src/agent/tasks/cooking_tasks.js +358 -0
  71. package/src/agent/tasks/tasks.js +594 -0
  72. package/src/agent/templates/execTemplate.js +6 -0
  73. package/src/agent/templates/lintTemplate.js +10 -0
  74. package/src/agent/vision/browser_viewer.js +8 -0
  75. package/src/agent/vision/camera.js +78 -0
  76. package/src/agent/vision/vision_interpreter.js +82 -0
  77. package/src/mindcraft/index.js +28 -0
  78. package/src/mindcraft/mcserver.js +154 -0
  79. package/src/mindcraft/mindcraft.js +111 -0
  80. package/src/mindcraft/mindserver.js +328 -0
  81. package/src/mindcraft/public/index.html +1253 -0
  82. package/src/mindcraft/public/settings_spec.json +145 -0
  83. package/src/mindcraft/userconfig.js +72 -0
  84. package/src/mindcraft-py/example.py +27 -0
  85. package/src/mindcraft-py/init-mindcraft.js +24 -0
  86. package/src/mindcraft-py/mindcraft.py +99 -0
  87. package/src/models/_model_map.js +89 -0
  88. package/src/models/azure.js +32 -0
  89. package/src/models/cerebras.js +61 -0
  90. package/src/models/claude.js +87 -0
  91. package/src/models/deepseek.js +59 -0
  92. package/src/models/gemini.js +176 -0
  93. package/src/models/glhf.js +71 -0
  94. package/src/models/gpt.js +147 -0
  95. package/src/models/grok.js +82 -0
  96. package/src/models/groq.js +95 -0
  97. package/src/models/huggingface.js +86 -0
  98. package/src/models/hyperbolic.js +114 -0
  99. package/src/models/lmstudio.js +74 -0
  100. package/src/models/mercury.js +95 -0
  101. package/src/models/mistral.js +94 -0
  102. package/src/models/novita.js +71 -0
  103. package/src/models/ollama.js +115 -0
  104. package/src/models/openrouter.js +77 -0
  105. package/src/models/prompter.js +366 -0
  106. package/src/models/qwen.js +80 -0
  107. package/src/models/replicate.js +60 -0
  108. package/src/models/vllm.js +81 -0
  109. package/src/process/agent_process.js +84 -0
  110. package/src/process/init_agent.js +54 -0
  111. package/src/utils/examples.js +83 -0
  112. package/src/utils/keys.js +34 -0
  113. package/src/utils/math.js +13 -0
  114. package/src/utils/mcdata.js +572 -0
  115. package/src/utils/text.js +78 -0
  116. package/src/utils/translator.js +30 -0
@@ -0,0 +1,84 @@
1
+ import { spawn } from 'child_process';
2
+ import { fileURLToPath } from 'url';
3
+ import { logoutAgent } from '../mindcraft/mindserver.js';
4
+
5
+ const init_agent_path = fileURLToPath(new URL('./init_agent.js', import.meta.url));
6
+
7
+ export class AgentProcess {
8
+ constructor(name, port) {
9
+ this.name = name;
10
+ this.port = port;
11
+ }
12
+
13
+ start(load_memory=false, init_message=null, count_id=0) {
14
+ this.count_id = count_id;
15
+ this.running = true;
16
+
17
+ let args = [init_agent_path, this.name];
18
+ args.push('-n', this.name);
19
+ args.push('-c', count_id);
20
+ if (load_memory)
21
+ args.push('-l', load_memory);
22
+ if (init_message)
23
+ args.push('-m', init_message);
24
+ args.push('-p', this.port);
25
+
26
+ const agentProcess = spawn(process.execPath, args, {
27
+ stdio: 'inherit',
28
+ stderr: 'inherit',
29
+ });
30
+
31
+ let last_restart = Date.now();
32
+ agentProcess.on('exit', (code, signal) => {
33
+ console.log(`Agent process exited with code ${code} and signal ${signal}`);
34
+ this.running = false;
35
+ logoutAgent(this.name);
36
+
37
+ if (code > 1) {
38
+ console.log(`Ending task`);
39
+ process.exit(code);
40
+ }
41
+
42
+ if (code !== 0 && signal !== 'SIGINT') {
43
+ // agent must run for at least 10 seconds before restarting
44
+ if (Date.now() - last_restart < 10000) {
45
+ console.error(`Agent process exited too quickly and will not be restarted.`);
46
+ return;
47
+ }
48
+ console.log('Restarting agent...');
49
+ this.start(true, 'Agent process restarted.', count_id, this.port);
50
+ last_restart = Date.now();
51
+ }
52
+ });
53
+
54
+ agentProcess.on('error', (err) => {
55
+ console.error('Agent process error:', err);
56
+ });
57
+
58
+ this.process = agentProcess;
59
+ }
60
+
61
+ stop() {
62
+ if (!this.running) return;
63
+ this.process.kill('SIGINT');
64
+ }
65
+
66
+ forceRestart() {
67
+ if (this.running && this.process && !this.process.killed) {
68
+ console.log(`Agent process for ${this.name} is still running. Attempting to force restart.`);
69
+
70
+ const restartTimeout = setTimeout(() => {
71
+ console.warn(`Agent ${this.name} did not stop in time. It might be stuck.`);
72
+ }, 5000); // 5 seconds to exit
73
+
74
+ this.process.once('exit', () => {
75
+ clearTimeout(restartTimeout);
76
+ console.log(`Stopped hanging agent ${this.name}. Now restarting.`);
77
+ this.start(true, 'Agent process restarted.', this.count_id);
78
+ });
79
+ this.stop(); // sends SIGINT
80
+ } else {
81
+ this.start(true, 'Agent process restarted.', this.count_id);
82
+ }
83
+ }
84
+ }
@@ -0,0 +1,54 @@
1
+ import { Agent } from '../agent/agent.js';
2
+ import { serverProxy } from '../agent/mindserver_proxy.js';
3
+ import yargs from 'yargs';
4
+
5
+ const args = process.argv.slice(2);
6
+ if (args.length < 1) {
7
+ console.log('Usage: node init_agent.js -n <agent_name> -p <port> -l <load_memory> -m <init_message> -c <count_id>');
8
+ process.exit(1);
9
+ }
10
+
11
+ const argv = yargs(args)
12
+ .option('name', {
13
+ alias: 'n',
14
+ type: 'string',
15
+ description: 'name of agent'
16
+ })
17
+ .option('load_memory', {
18
+ alias: 'l',
19
+ type: 'boolean',
20
+ description: 'load agent memory from file on startup'
21
+ })
22
+ .option('init_message', {
23
+ alias: 'm',
24
+ type: 'string',
25
+ description: 'automatically prompt the agent on startup'
26
+ })
27
+ .option('count_id', {
28
+ alias: 'c',
29
+ type: 'number',
30
+ default: 0,
31
+ description: 'identifying count for multi-agent scenarios',
32
+ })
33
+ .option('port', {
34
+ alias: 'p',
35
+ type: 'number',
36
+ description: 'port of mindserver'
37
+ })
38
+ .argv;
39
+
40
+ (async () => {
41
+ try {
42
+ console.log('Connecting to MindServer');
43
+ await serverProxy.connect(argv.name, argv.port);
44
+ console.log('Starting agent');
45
+ const agent = new Agent();
46
+ serverProxy.setAgent(agent);
47
+ await agent.start(argv.load_memory, argv.init_message, argv.count_id);
48
+ } catch (error) {
49
+ console.error('Failed to start agent process:');
50
+ console.error(error.message);
51
+ console.error(error.stack);
52
+ process.exit(1);
53
+ }
54
+ })();
@@ -0,0 +1,83 @@
1
+ import { cosineSimilarity } from './math.js';
2
+ import { stringifyTurns, wordOverlapScore } from './text.js';
3
+
4
+ export class Examples {
5
+ constructor(model, select_num=2) {
6
+ this.examples = [];
7
+ this.model = model;
8
+ this.select_num = select_num;
9
+ this.embeddings = {};
10
+ }
11
+
12
+ turnsToText(turns) {
13
+ let messages = '';
14
+ for (let turn of turns) {
15
+ if (turn.role !== 'assistant')
16
+ messages += turn.content.substring(turn.content.indexOf(':')+1).trim() + '\n';
17
+ }
18
+ return messages.trim();
19
+ }
20
+
21
+ async load(examples) {
22
+ this.examples = examples;
23
+ if (!this.model) return; // Early return if no embedding model
24
+
25
+ if (this.select_num === 0)
26
+ return;
27
+
28
+ try {
29
+ // Create array of promises first
30
+ const embeddingPromises = examples.map(example => {
31
+ const turn_text = this.turnsToText(example);
32
+ return this.model.embed(turn_text)
33
+ .then(embedding => {
34
+ this.embeddings[turn_text] = embedding;
35
+ });
36
+ });
37
+
38
+ // Wait for all embeddings to complete
39
+ await Promise.all(embeddingPromises);
40
+ } catch (err) {
41
+ console.warn('Error with embedding model, using word-overlap instead.');
42
+ this.model = null;
43
+ }
44
+ }
45
+
46
+ async getRelevant(turns) {
47
+ if (this.select_num === 0)
48
+ return [];
49
+
50
+ let turn_text = this.turnsToText(turns);
51
+ if (this.model !== null) {
52
+ let embedding = await this.model.embed(turn_text);
53
+ this.examples.sort((a, b) =>
54
+ cosineSimilarity(embedding, this.embeddings[this.turnsToText(b)]) -
55
+ cosineSimilarity(embedding, this.embeddings[this.turnsToText(a)])
56
+ );
57
+ }
58
+ else {
59
+ this.examples.sort((a, b) =>
60
+ wordOverlapScore(turn_text, this.turnsToText(b)) -
61
+ wordOverlapScore(turn_text, this.turnsToText(a))
62
+ );
63
+ }
64
+ let selected = this.examples.slice(0, this.select_num);
65
+ return JSON.parse(JSON.stringify(selected)); // deep copy
66
+ }
67
+
68
+ async createExampleMessage(turns) {
69
+ let selected_examples = await this.getRelevant(turns);
70
+
71
+ console.log('selected examples:');
72
+ for (let example of selected_examples) {
73
+ console.log('Example:', example[0].content)
74
+ }
75
+
76
+ let msg = 'Examples of how to respond:\n';
77
+ for (let i=0; i<selected_examples.length; i++) {
78
+ let example = selected_examples[i];
79
+ msg += `Example ${i+1}:\n${stringifyTurns(example)}\n\n`;
80
+ }
81
+ return msg;
82
+ }
83
+ }
@@ -0,0 +1,34 @@
1
+ import { readFileSync } from 'fs';
2
+ import path from 'path';
3
+ import { homedir } from 'os';
4
+
5
+ // Lookup order: ./keys.json (repo-local), then $XDG_CONFIG_HOME/mindcraft/keys.json
6
+ // (written by the web UI's setup wizard), then environment variables.
7
+ function tryRead(p) {
8
+ try { return JSON.parse(readFileSync(p, 'utf8')); }
9
+ catch { return null; }
10
+ }
11
+
12
+ const configHome = process.env.XDG_CONFIG_HOME || path.join(homedir(), '.config');
13
+ const local = tryRead(path.join(process.cwd(), 'keys.json'));
14
+ const user = tryRead(path.join(configHome, 'mindcraft', 'keys.json'));
15
+ const keys = { ...(user || {}), ...(local || {}) };
16
+
17
+ if (!local && !user) {
18
+ console.warn('keys.json not found. Defaulting to environment variables.'); // still works with local models
19
+ }
20
+
21
+ export function getKey(name) {
22
+ let key = keys[name];
23
+ if (!key) {
24
+ key = process.env[name];
25
+ }
26
+ if (!key) {
27
+ throw new Error(`API key "${name}" not found in keys.json or environment variables!`);
28
+ }
29
+ return key;
30
+ }
31
+
32
+ export function hasKey(name) {
33
+ return keys[name] || process.env[name];
34
+ }
@@ -0,0 +1,13 @@
1
+ export function cosineSimilarity(a, b) {
2
+ let dotProduct = 0;
3
+ let magnitudeA = 0;
4
+ let magnitudeB = 0;
5
+ for (let i = 0; i < a.length; i++) {
6
+ dotProduct += a[i] * b[i]; // calculate dot product
7
+ magnitudeA += Math.pow(a[i], 2); // calculate magnitude of a
8
+ magnitudeB += Math.pow(b[i], 2); // calculate magnitude of b
9
+ }
10
+ magnitudeA = Math.sqrt(magnitudeA);
11
+ magnitudeB = Math.sqrt(magnitudeB);
12
+ return dotProduct / (magnitudeA * magnitudeB); // calculate cosine similarity
13
+ }