navada-edge-cli 3.5.1 → 3.5.2
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 +90 -0
- package/package.json +1 -1
package/lib/agent.js
CHANGED
|
@@ -1072,7 +1072,97 @@ async function executeTool(name, input) {
|
|
|
1072
1072
|
}
|
|
1073
1073
|
}
|
|
1074
1074
|
|
|
1075
|
+
// ---------------------------------------------------------------------------
|
|
1076
|
+
// Local action interceptor — executes file/shell actions WITHOUT needing LLM tool use
|
|
1077
|
+
// This ensures free tier users can still create, read, edit, delete files
|
|
1078
|
+
// ---------------------------------------------------------------------------
|
|
1079
|
+
function tryLocalAction(userMessage) {
|
|
1080
|
+
const msg = userMessage.trim();
|
|
1081
|
+
const lower = msg.toLowerCase();
|
|
1082
|
+
const home = os.homedir();
|
|
1083
|
+
const desktop = path.join(home, 'Desktop');
|
|
1084
|
+
|
|
1085
|
+
// Resolve common path references
|
|
1086
|
+
function resolvePath(p) {
|
|
1087
|
+
return p
|
|
1088
|
+
.replace(/^~\//, home + '/')
|
|
1089
|
+
.replace(/^~\\/, home + '\\')
|
|
1090
|
+
.replace(/\bmy desktop\b/i, desktop)
|
|
1091
|
+
.replace(/\bthe desktop\b/i, desktop)
|
|
1092
|
+
.replace(/\bdesktop\b/i, desktop);
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
// ── Create folder/directory ──
|
|
1096
|
+
const mkdirMatch = lower.match(/(?:create|make|new)\s+(?:a\s+)?(?:new\s+)?(?:folder|directory|dir)\s+(?:called|named|on|at|in)?\s*[""']?(.+?)[""']?\s*(?:on|at|in)\s+(.+)/i)
|
|
1097
|
+
|| lower.match(/(?:create|make|new)\s+(?:a\s+)?(?:new\s+)?(?:folder|directory|dir)\s+(?:on|at|in)\s+(.+?)\s+(?:called|named)\s+[""']?(.+?)[""']?$/i)
|
|
1098
|
+
|| lower.match(/(?:create|make|new)\s+(?:a\s+)?(?:new\s+)?(?:folder|directory|dir)\s+(?:called|named)\s+[""']?(.+?)[""']?\s*(?:on|at|in)\s+(.+)/i)
|
|
1099
|
+
|| lower.match(/(?:create|make|new)\s+(?:a\s+)?(?:new\s+)?(?:folder|directory|dir)\s+(?:called|named)\s+[""']?(.+?)[""']?\s*$/i);
|
|
1100
|
+
|
|
1101
|
+
if (mkdirMatch) {
|
|
1102
|
+
let folderName, location;
|
|
1103
|
+
if (mkdirMatch.length === 3) {
|
|
1104
|
+
folderName = mkdirMatch[1].trim().replace(/[""']/g, '');
|
|
1105
|
+
location = mkdirMatch[2].trim().replace(/[""']/g, '');
|
|
1106
|
+
} else {
|
|
1107
|
+
folderName = mkdirMatch[1].trim().replace(/[""']/g, '');
|
|
1108
|
+
location = lower.includes('desktop') ? desktop : process.cwd();
|
|
1109
|
+
}
|
|
1110
|
+
const resolved = path.resolve(resolvePath(location), folderName);
|
|
1111
|
+
const result = localTools.shell.execute(process.platform === 'win32' ? `mkdir "${resolved}"` : `mkdir -p "${resolved}"`);
|
|
1112
|
+
if (result.includes('Error')) return null; // let LLM handle
|
|
1113
|
+
return `Created folder: ${resolved}`;
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
// ── Create file ──
|
|
1117
|
+
const touchMatch = lower.match(/(?:create|make|new|touch)\s+(?:a\s+)?(?:new\s+)?(?:file|empty file)\s+(?:called|named)\s+[""']?(.+?)[""']?\s*(?:on|at|in)\s+(.+)/i)
|
|
1118
|
+
|| lower.match(/(?:create|make|new|touch)\s+(?:a\s+)?(?:new\s+)?(?:file)\s+(?:called|named)\s+[""']?(.+?)[""']?\s*$/i);
|
|
1119
|
+
|
|
1120
|
+
if (touchMatch) {
|
|
1121
|
+
let fileName = touchMatch[1].trim().replace(/[""']/g, '');
|
|
1122
|
+
let location = touchMatch[2] ? touchMatch[2].trim().replace(/[""']/g, '') : process.cwd();
|
|
1123
|
+
const resolved = path.resolve(resolvePath(location), fileName);
|
|
1124
|
+
return localTools.writeFile.execute(resolved, '');
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
// ── Read file ──
|
|
1128
|
+
const readMatch = lower.match(/(?:read|show|display|cat|open)\s+(?:the\s+)?(?:file\s+)?[""']?(.+\.\w+)[""']?/i);
|
|
1129
|
+
if (readMatch) {
|
|
1130
|
+
const filePath = resolvePath(readMatch[1].trim().replace(/[""']/g, ''));
|
|
1131
|
+
return localTools.readFile.execute(filePath);
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
// ── Delete file/folder ──
|
|
1135
|
+
const deleteMatch = lower.match(/(?:delete|remove|rm)\s+(?:the\s+)?(?:file|folder|directory)?\s*[""']?(.+?)[""']?\s*$/i);
|
|
1136
|
+
if (deleteMatch && (lower.includes('file') || lower.includes('folder') || lower.includes('directory'))) {
|
|
1137
|
+
const filePath = path.resolve(resolvePath(deleteMatch[1].trim().replace(/[""']/g, '')));
|
|
1138
|
+
return localTools.deleteFile.execute(filePath);
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
// ── List files ──
|
|
1142
|
+
const lsMatch = lower.match(/(?:list|show|ls|dir)\s+(?:the\s+)?(?:files|contents|items)\s+(?:in|on|at|of)\s+(.+)/i);
|
|
1143
|
+
if (lsMatch) {
|
|
1144
|
+
const dir = resolvePath(lsMatch[1].trim().replace(/[""']/g, ''));
|
|
1145
|
+
return localTools.listFiles.execute(dir);
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
return null; // No match — let LLM handle
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1075
1151
|
async function grokChat(userMessage, conversationHistory = []) {
|
|
1152
|
+
// Try local action first — enables file ops on free tier
|
|
1153
|
+
const localResult = tryLocalAction(userMessage);
|
|
1154
|
+
if (localResult) {
|
|
1155
|
+
console.log(` ${localResult}`);
|
|
1156
|
+
// Send result to LLM for a natural confirmation
|
|
1157
|
+
const confirmMsg = `The user asked: "${userMessage}"\nI executed the action locally. Result: ${localResult}\nGive a brief, friendly confirmation and ask if they need anything else.`;
|
|
1158
|
+
try {
|
|
1159
|
+
const result = await callFreeTier([{ role: 'user', content: confirmMsg }], true);
|
|
1160
|
+
return result.content || localResult;
|
|
1161
|
+
} catch {
|
|
1162
|
+
return localResult;
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1076
1166
|
const messages = [
|
|
1077
1167
|
...conversationHistory.slice(-20).map(m => ({
|
|
1078
1168
|
role: m.role,
|
package/package.json
CHANGED