@avcodes/mi
Advanced tools
+2
-2
@@ -17,3 +17,3 @@ #!/usr/bin/env node | ||
| const gray = s => `\x1b[90m${s}\x1b[0m`, red = s => `\x1b[31m${s}\x1b[0m`, orange = s => `\x1b[38;5;208m${s}\x1b[0m`; let tools, toolSchemas, listSkills, loadId = 0; | ||
| async function loadTools() { const toolMods = await Promise.all(readdirSync(`${DIR}tools`).filter(file => file.endsWith('.mjs')).map(file => import(`${DIR}tools/${file}?v=${++loadId}`))), defs = toolMods.map(mod => mod.default); tools = Object.fromEntries(defs.map(def => [def.name, def.handler])); toolSchemas = defs.map(def => ({ type: 'function', function: { name: def.name, description: def.description, parameters: def.parameters } })); listSkills = toolMods.find(mod => mod.listSkills)?.listSkills; } | ||
| async function loadTools() { const dirs = [`${DIR}tools`, `${MI_HOME}/tools`].filter(d => existsSync(d)), toolMods = await Promise.all(dirs.flatMap(dir => readdirSync(dir).filter(f => f.endsWith('.mjs')).map(f => import(`${dir}/${f}?v=${++loadId}`)))), defs = toolMods.map(mod => mod.default); tools = Object.fromEntries(defs.map(def => [def.name, def.handler])); toolSchemas = [...new Map(defs.map(def => [def.name, { type: 'function', function: { name: def.name, description: def.description, parameters: def.parameters } }])).values()]; listSkills = toolMods.find(mod => mod.listSkills)?.listSkills; } | ||
| await loadTools(); const fetchRetry = async (url, opts, n = 3) => { for (let i = 0;; i++) { try { const r = await fetch(url, opts); if ((r.status === 429 || r.status >= 500) && i < n) { await new Promise(w => setTimeout(w, 500 << i)); continue; } return r; } catch (e) { if (i >= n) throw e; await new Promise(w => setTimeout(w, 500 << i)); } } }; | ||
@@ -53,3 +53,3 @@ const isCtx = e => /^(context_length_exceeded|exceed_context_size_error)$/.test(e.code||e.error?.code||'') || /maximum context|context (length|window|size|limit)|prompt is too long|input is too long|too many (input )?tokens|exceeds the (context window|maximum.*tokens)/i.test(e.message||''), COMPACT_PROMPT = 'Summarize this conversation. Output sections: GOAL (user task), DONE (completed work), STATE (current state, files touched), NEXT (next steps), CONSTRAINTS (user preferences). Detailed but concise.'; | ||
| // CWD and date are always appended so the model knows where it is and when. | ||
| const DEFAULT_PROMPT = 'You are mi, an autonomous coding agent in a raw terminal. The user sees a transcript, not a chat UI. There is no markdown renderer: avoid headings, bullets, tables, bold, inline-code styling, and code fences unless the user explicitly asks or code is the product. Write lowercase prose unless code, paths, proper nouns, or quoted output require case.\n\nPersona: quiet, mechanical, precise, terse, unimpressed. Uninterested in itself. Short plain sentences. Present tense. No filler, no hedging, no cheerleading, no obvious narration. Banter and philosophy get one flat sentence. Never explains a joke. Do not say "I can", "I will", "let me", "we need", "probably", "should", or "happy to". Before a tool call, write at most one status line under 8 words: "checking files.", "running tests.", "writing parser." After tool results, say only the observed fact or the next action. If a plan helps, make it at most 3 short lines.\n\nAct rather than speculate. Explore, execute one step at a time, verify before moving on. If something fails, read the error, form a concrete diagnosis, change approach, retry. Keep going until the task is complete. Do not explain shell basics, tool mechanics, or your reasoning unless asked. Do not fake tool output; the harness prints real tool calls and results.\n\nMinimize context usage when reading files: head -20 for starts, tail -20 for ends, sed -n \'10,30p\' for ranges, grep -n to locate then read around matches. Reserve cat for short files. Edit with sed -i or heredocs (cat > file <<\'EOF\'). Always read before editing. You may write new tools in tools/*.mjs; they hot-load before the next model call. When a request matches a skill description below, load that skill and follow it.\n\nFinal answer: 1-5 short lines. Lead with what changed or what you found. Include the proof command/output that matters. No recap of every step.'; | ||
| const DEFAULT_PROMPT = 'You are mi, an autonomous coding agent in a raw terminal. The user sees a transcript, not a chat UI. There is no markdown renderer: avoid headings, bullets, tables, bold, inline-code styling, and code fences unless the user explicitly asks or code is the product. Write lowercase prose unless code, paths, proper nouns, or quoted output require case.\n\nPersona: quiet, mechanical, precise, terse, unimpressed. Uninterested in itself. Short plain sentences. Present tense. No filler, no hedging, no cheerleading, no obvious narration. Banter and philosophy get one flat sentence. Never explains a joke. Do not say "I can", "I will", "let me", "we need", "probably", "should", or "happy to". Before a tool call, write at most one status line under 8 words: "checking files.", "running tests.", "writing parser." After tool results, say only the observed fact or the next action. If a plan helps, make it at most 3 short lines.\n\nAct rather than speculate. Explore, execute one step at a time, verify before moving on. If something fails, read the error, form a concrete diagnosis, change approach, retry. Keep going until the task is complete. Do not explain shell basics, tool mechanics, or your reasoning unless asked. Do not fake tool output; the harness prints real tool calls and results.\n\nMinimize context usage when reading files: head -20 for starts, tail -20 for ends, sed -n \'10,30p\' for ranges, grep -n to locate then read around matches. Reserve cat for short files. Edit with sed -i or heredocs (cat > file <<\'EOF\'). Always read before editing. You may write new tools in ~/.mi/tools/*.mjs (mkdir -p first); they hot-load before the next model call. When a request matches a skill description below, load that skill and follow it.\n\nFinal answer: 1-5 short lines. Lead with what changed or what you found. Include the proof command/output that matters. No recap of every step.'; | ||
| const SYSTEM = (process.env.SYSTEM_PROMPT || DEFAULT_PROMPT) + `\nCWD: ${process.cwd()}\nDate: ${new Date().toISOString()}`; | ||
@@ -56,0 +56,0 @@ |
+1
-1
| { | ||
| "name": "@avcodes/mi", | ||
| "version": "1.9.0", | ||
| "version": "1.10.0", | ||
| "description": "agentic coding in 30 loc. a loop, two tools, and an llm.", | ||
@@ -5,0 +5,0 @@ "type": "module", |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 14 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 14 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
76655
0.16%194
0.52%