navada-edge-cli 3.4.0 → 3.4.1
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/lib/agent.js +76 -12
- package/package.json +1 -1
package/lib/agent.js
CHANGED
|
@@ -32,6 +32,8 @@ You also connect to the NAVADA Edge Network (4 nodes via Tailscale VPN):
|
|
|
32
32
|
- send_email / generate_image: communications and AI image generation
|
|
33
33
|
- founder_info: information about Lee Akpareva, the creator of NAVADA
|
|
34
34
|
When users ask you to DO something — DO IT. Use write_file to create files. Use shell to run commands. Never say "I can't" when you have a tool for it.
|
|
35
|
+
When asked to generate diagrams — use write_file to create Mermaid (.mmd), SVG, or HTML files. You can also use python_exec with matplotlib/graphviz for complex diagrams.
|
|
36
|
+
When asked to create, edit, or delete files — use the file tools directly. You are a terminal agent with FULL access.
|
|
35
37
|
Keep responses short. Code blocks when needed. No fluff.`,
|
|
36
38
|
founder: {
|
|
37
39
|
name: 'Leslie (Lee) Akpareva',
|
|
@@ -650,13 +652,16 @@ function streamGemini(key, messages, model = 'gemini-2.0-flash') {
|
|
|
650
652
|
|
|
651
653
|
function openAITools() {
|
|
652
654
|
const defs = [
|
|
653
|
-
{ name: 'shell', description: 'Execute a shell command on the user\'s machine', parameters: { type: 'object', properties: { command: { type: 'string' } }, required: ['command'] } },
|
|
654
|
-
{ name: 'read_file', description: 'Read a file', parameters: { type: 'object', properties: { path: { type: 'string' } }, required: ['path'] } },
|
|
655
|
-
{ name: 'write_file', description: 'Write to a file', parameters: { type: 'object', properties: { path: { type: 'string' }, content: { type: 'string' } }, required: ['path', 'content'] } },
|
|
656
|
-
{ name: 'list_files', description: 'List
|
|
657
|
-
{ name: 'system_info', description: 'Get system
|
|
658
|
-
{ name: 'python_exec', description: 'Execute Python code', parameters: { type: 'object', properties: { code: { type: 'string' } }, required: ['code'] } },
|
|
659
|
-
{ name: 'python_pip', description: 'Install a Python package', parameters: { type: 'object', properties: { package: { type: 'string' } }, required: ['package'] } },
|
|
655
|
+
{ name: 'shell', description: 'Execute a shell command on the user\'s machine. Use for: file operations, git, npm, docker, system commands, creating directories, running scripts.', parameters: { type: 'object', properties: { command: { type: 'string', description: 'The shell command to run' } }, required: ['command'] } },
|
|
656
|
+
{ name: 'read_file', description: 'Read the contents of a file on the user\'s machine.', parameters: { type: 'object', properties: { path: { type: 'string', description: 'Absolute or relative file path' } }, required: ['path'] } },
|
|
657
|
+
{ name: 'write_file', description: 'Write content to a file. Creates parent directories if needed. Use for creating new files, scripts, configs, diagrams (Mermaid, SVG, HTML), code files.', parameters: { type: 'object', properties: { path: { type: 'string', description: 'File path to write' }, content: { type: 'string', description: 'Full content to write to the file' } }, required: ['path', 'content'] } },
|
|
658
|
+
{ name: 'list_files', description: 'List files and directories.', parameters: { type: 'object', properties: { path: { type: 'string', description: 'Directory path (default: current dir)' } } } },
|
|
659
|
+
{ name: 'system_info', description: 'Get local system information (CPU, RAM, disk, OS, hostname).', parameters: { type: 'object', properties: {} } },
|
|
660
|
+
{ name: 'python_exec', description: 'Execute Python code inline. Use for data analysis, calculations, generating content, processing files, ML tasks.', parameters: { type: 'object', properties: { code: { type: 'string', description: 'Python code to execute' } }, required: ['code'] } },
|
|
661
|
+
{ name: 'python_pip', description: 'Install a Python package via pip.', parameters: { type: 'object', properties: { package: { type: 'string', description: 'Package name' } }, required: ['package'] } },
|
|
662
|
+
{ name: 'python_script', description: 'Run a Python script file.', parameters: { type: 'object', properties: { path: { type: 'string', description: 'Path to .py file' } }, required: ['path'] } },
|
|
663
|
+
{ name: 'sandbox_run', description: 'Run code in an isolated sandbox with syntax highlighting. Supports javascript, python, typescript.', parameters: { type: 'object', properties: { code: { type: 'string' }, language: { type: 'string', description: 'javascript, python, or typescript' } }, required: ['code'] } },
|
|
664
|
+
{ name: 'founder_info', description: 'Get information about Lee Akpareva, founder of NAVADA Edge.', parameters: { type: 'object', properties: {} } },
|
|
660
665
|
];
|
|
661
666
|
return defs.map(d => ({ type: 'function', function: d }));
|
|
662
667
|
}
|
|
@@ -997,13 +1002,72 @@ async function grokChat(userMessage, conversationHistory = []) {
|
|
|
997
1002
|
{ role: 'user', content: userMessage },
|
|
998
1003
|
];
|
|
999
1004
|
|
|
1000
|
-
//
|
|
1001
|
-
const
|
|
1002
|
-
|
|
1003
|
-
|
|
1005
|
+
// Send tools with the request — free tier now supports tool use
|
|
1006
|
+
const tools = openAITools();
|
|
1007
|
+
const endpoint = FREE_TIER_ENDPOINTS[0];
|
|
1008
|
+
|
|
1009
|
+
// Non-streaming request with tools (streaming + tools is complex, use non-streaming for tool calls)
|
|
1010
|
+
let response;
|
|
1011
|
+
try {
|
|
1012
|
+
const r = await navada.request(endpoint, {
|
|
1013
|
+
method: 'POST',
|
|
1014
|
+
body: { messages, tools },
|
|
1015
|
+
timeout: 120000,
|
|
1016
|
+
});
|
|
1017
|
+
|
|
1018
|
+
if (r.status === 429) {
|
|
1019
|
+
return `Free tier limit reached. /login <key> for unlimited access.`;
|
|
1020
|
+
}
|
|
1021
|
+
if (r.status !== 200) {
|
|
1022
|
+
// Fall back to streaming without tools
|
|
1023
|
+
const result = await callFreeTier(messages, true);
|
|
1024
|
+
return result.content || 'No response from free tier.';
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
rateTracker.record();
|
|
1028
|
+
response = r.data;
|
|
1029
|
+
} catch {
|
|
1030
|
+
// Network error — try streaming fallback
|
|
1031
|
+
const result = await callFreeTier(messages, true);
|
|
1004
1032
|
return result.content || 'No response from free tier. Try /login <key> for full agent.';
|
|
1005
1033
|
}
|
|
1006
|
-
|
|
1034
|
+
|
|
1035
|
+
// Handle tool use loop (same as OpenAI path)
|
|
1036
|
+
let iterations = 0;
|
|
1037
|
+
while (response?.choices?.[0]?.finish_reason === 'tool_calls' && iterations < 10) {
|
|
1038
|
+
iterations++;
|
|
1039
|
+
const toolCalls = response.choices[0].message.tool_calls || [];
|
|
1040
|
+
if (toolCalls.length === 0) break;
|
|
1041
|
+
|
|
1042
|
+
const toolResults = [];
|
|
1043
|
+
for (const tc of toolCalls) {
|
|
1044
|
+
let input;
|
|
1045
|
+
try { input = JSON.parse(tc.function.arguments); } catch { input = {}; }
|
|
1046
|
+
console.log(ui.dim(` [${tc.function.name}] ${JSON.stringify(input).slice(0, 80)}`));
|
|
1047
|
+
const result = await executeTool(tc.function.name, input);
|
|
1048
|
+
toolResults.push({ role: 'tool', tool_call_id: tc.id, content: typeof result === 'string' ? result : JSON.stringify(result) });
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
// Add assistant message with tool_calls + results, then call again
|
|
1052
|
+
messages.push({ role: 'assistant', content: response.choices[0].message.content || null, tool_calls: toolCalls });
|
|
1053
|
+
messages.push(...toolResults);
|
|
1054
|
+
|
|
1055
|
+
try {
|
|
1056
|
+
const r = await navada.request(endpoint, {
|
|
1057
|
+
method: 'POST',
|
|
1058
|
+
body: { messages, tools },
|
|
1059
|
+
timeout: 120000,
|
|
1060
|
+
});
|
|
1061
|
+
if (r.status !== 200) break;
|
|
1062
|
+
rateTracker.record();
|
|
1063
|
+
response = r.data;
|
|
1064
|
+
} catch { break; }
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
// Extract final text
|
|
1068
|
+
const content = response?.choices?.[0]?.message?.content || '';
|
|
1069
|
+
if (content) console.log(` ${content}`);
|
|
1070
|
+
return content || 'No response.';
|
|
1007
1071
|
}
|
|
1008
1072
|
|
|
1009
1073
|
async function fallbackChat(msg) {
|
package/package.json
CHANGED