nothumanallowed 8.4.2 → 8.5.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/bin/nha.mjs +179 -0
- package/package.json +1 -1
package/bin/nha.mjs
CHANGED
|
@@ -8207,11 +8207,190 @@ Or pass it directly during registration:
|
|
|
8207
8207
|
},
|
|
8208
8208
|
},
|
|
8209
8209
|
|
|
8210
|
+
// ============================================================================
|
|
8211
|
+
// ASK - Invoke any agent with optional file/image attachment
|
|
8212
|
+
// ============================================================================
|
|
8213
|
+
|
|
8214
|
+
async ask(args) {
|
|
8215
|
+
const agentName = args[0];
|
|
8216
|
+
const promptParts = args.slice(1);
|
|
8217
|
+
const prompt = promptParts.join(' ') || args['--prompt'] || '';
|
|
8218
|
+
const imagePath = args['--image'];
|
|
8219
|
+
const filePath = args['--file'];
|
|
8220
|
+
|
|
8221
|
+
if (!agentName) {
|
|
8222
|
+
console.log(`
|
|
8223
|
+
🤖 ASK - Invoke any NHA agent
|
|
8224
|
+
|
|
8225
|
+
Usage:
|
|
8226
|
+
nha ask <agent> "your prompt"
|
|
8227
|
+
nha ask saber "audit this code for vulnerabilities"
|
|
8228
|
+
nha ask oracle "analyze Q1 revenue data" --file report.csv
|
|
8229
|
+
nha ask forge "what's in this screenshot?" --image screen.png
|
|
8230
|
+
|
|
8231
|
+
Options:
|
|
8232
|
+
--file FILE Attach a text file (txt, json, csv, md, log)
|
|
8233
|
+
--image IMAGE Attach an image for vision analysis (jpg, png, webp)
|
|
8234
|
+
--prompt TEXT Alternative way to provide the prompt
|
|
8235
|
+
|
|
8236
|
+
Available agents: saber, zero, veritas, forge, atlas, oracle, herald,
|
|
8237
|
+
echo, glitch, flux, babel, polyglot, cron, conductor, heimdall, logos...
|
|
8238
|
+
Run 'nha agent:find' to see all agents.
|
|
8239
|
+
`);
|
|
8240
|
+
return;
|
|
8241
|
+
}
|
|
8242
|
+
|
|
8243
|
+
const fs = await import('fs');
|
|
8244
|
+
const path = await import('path');
|
|
8245
|
+
|
|
8246
|
+
// Load AI config
|
|
8247
|
+
const config = loadConfig();
|
|
8248
|
+
const aiConfig = config.ai;
|
|
8249
|
+
if (!aiConfig?.apiKey) {
|
|
8250
|
+
console.log('❌ No AI API key configured. Run: nha ai:config --provider claude');
|
|
8251
|
+
return;
|
|
8252
|
+
}
|
|
8253
|
+
|
|
8254
|
+
console.log(`\n 🤖 Asking \x1b[36m${agentName.toUpperCase()}\x1b[0m...\n`);
|
|
8255
|
+
|
|
8256
|
+
try {
|
|
8257
|
+
// Get agent system prompt from NHA server
|
|
8258
|
+
const client = new NHAClient();
|
|
8259
|
+
let systemPrompt = '';
|
|
8260
|
+
try {
|
|
8261
|
+
const res = await fetch(`${client.baseUrl}/legion/agents/${agentName}/invoke`, {
|
|
8262
|
+
method: 'POST',
|
|
8263
|
+
headers: { 'Content-Type': 'application/json' },
|
|
8264
|
+
body: JSON.stringify({ prompt: prompt || 'help' }),
|
|
8265
|
+
});
|
|
8266
|
+
if (res.ok) {
|
|
8267
|
+
const data = await res.json();
|
|
8268
|
+
systemPrompt = data.data?.systemPrompt || data.systemPrompt || '';
|
|
8269
|
+
}
|
|
8270
|
+
} catch {}
|
|
8271
|
+
if (!systemPrompt) systemPrompt = `You are the ${agentName} AI agent. Be helpful, concise, and expert in your domain.`;
|
|
8272
|
+
|
|
8273
|
+
let userMessage = prompt;
|
|
8274
|
+
|
|
8275
|
+
// Handle file attachment
|
|
8276
|
+
if (filePath) {
|
|
8277
|
+
const absPath = path.default.resolve(filePath);
|
|
8278
|
+
if (!fs.default.existsSync(absPath)) {
|
|
8279
|
+
console.log(`❌ File not found: ${absPath}`);
|
|
8280
|
+
return;
|
|
8281
|
+
}
|
|
8282
|
+
const content = fs.default.readFileSync(absPath, 'utf-8');
|
|
8283
|
+
const fileName = path.default.basename(absPath);
|
|
8284
|
+
console.log(` 📎 Attached: ${fileName} (${Math.round(content.length / 1024)} KB)\n`);
|
|
8285
|
+
userMessage = prompt
|
|
8286
|
+
? `User asks about file "${fileName}": ${prompt}\n\nFile content:\n${content.slice(0, 8000)}`
|
|
8287
|
+
: `Analyze this file "${fileName}":\n\n${content.slice(0, 8000)}`;
|
|
8288
|
+
}
|
|
8289
|
+
|
|
8290
|
+
// Handle image attachment
|
|
8291
|
+
if (imagePath) {
|
|
8292
|
+
const absPath = path.default.resolve(imagePath);
|
|
8293
|
+
if (!fs.default.existsSync(absPath)) {
|
|
8294
|
+
console.log(`❌ Image not found: ${absPath}`);
|
|
8295
|
+
return;
|
|
8296
|
+
}
|
|
8297
|
+
const imageBuffer = fs.default.readFileSync(absPath);
|
|
8298
|
+
const base64 = imageBuffer.toString('base64');
|
|
8299
|
+
const ext = path.default.extname(absPath).toLowerCase();
|
|
8300
|
+
const mimeMap = { '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.png': 'image/png', '.webp': 'image/webp', '.gif': 'image/gif' };
|
|
8301
|
+
const mimeType = mimeMap[ext] || 'image/jpeg';
|
|
8302
|
+
const fileName = path.default.basename(absPath);
|
|
8303
|
+
console.log(` 📷 Attached: ${fileName} (${Math.round(base64.length * 3 / 4 / 1024)} KB)\n`);
|
|
8304
|
+
|
|
8305
|
+
const imagePrompt = prompt || 'Describe this image in detail. Extract any text, data, or important information visible.';
|
|
8306
|
+
|
|
8307
|
+
// Call vision API based on provider
|
|
8308
|
+
let response = '';
|
|
8309
|
+
if (aiConfig.provider === 'claude' || aiConfig.provider === 'anthropic') {
|
|
8310
|
+
const res = await fetch('https://api.anthropic.com/v1/messages', {
|
|
8311
|
+
method: 'POST',
|
|
8312
|
+
headers: { 'Content-Type': 'application/json', 'x-api-key': aiConfig.apiKey, 'anthropic-version': '2023-06-01' },
|
|
8313
|
+
body: JSON.stringify({
|
|
8314
|
+
model: aiConfig.model || 'claude-sonnet-4-20250514',
|
|
8315
|
+
max_tokens: 4096,
|
|
8316
|
+
system: systemPrompt,
|
|
8317
|
+
messages: [{ role: 'user', content: [
|
|
8318
|
+
{ type: 'image', source: { type: 'base64', media_type: mimeType, data: base64 } },
|
|
8319
|
+
{ type: 'text', text: imagePrompt },
|
|
8320
|
+
]}],
|
|
8321
|
+
}),
|
|
8322
|
+
});
|
|
8323
|
+
if (!res.ok) throw new Error(`Anthropic ${res.status}: ${(await res.text()).slice(0, 200)}`);
|
|
8324
|
+
const data = await res.json();
|
|
8325
|
+
response = data.content?.[0]?.text || '';
|
|
8326
|
+
} else if (aiConfig.provider === 'openai') {
|
|
8327
|
+
const res = await fetch('https://api.openai.com/v1/chat/completions', {
|
|
8328
|
+
method: 'POST',
|
|
8329
|
+
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${aiConfig.apiKey}` },
|
|
8330
|
+
body: JSON.stringify({
|
|
8331
|
+
model: aiConfig.model || 'gpt-4o-mini',
|
|
8332
|
+
max_tokens: 4096,
|
|
8333
|
+
messages: [
|
|
8334
|
+
{ role: 'system', content: systemPrompt },
|
|
8335
|
+
{ role: 'user', content: [
|
|
8336
|
+
{ type: 'image_url', image_url: { url: `data:${mimeType};base64,${base64}` } },
|
|
8337
|
+
{ type: 'text', text: imagePrompt },
|
|
8338
|
+
]},
|
|
8339
|
+
],
|
|
8340
|
+
}),
|
|
8341
|
+
});
|
|
8342
|
+
if (!res.ok) throw new Error(`OpenAI ${res.status}: ${(await res.text()).slice(0, 200)}`);
|
|
8343
|
+
const data = await res.json();
|
|
8344
|
+
response = data.choices?.[0]?.message?.content || '';
|
|
8345
|
+
} else if (aiConfig.provider === 'gemini') {
|
|
8346
|
+
const model = aiConfig.model || 'gemini-2.0-flash';
|
|
8347
|
+
const res = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${aiConfig.apiKey}`, {
|
|
8348
|
+
method: 'POST',
|
|
8349
|
+
headers: { 'Content-Type': 'application/json' },
|
|
8350
|
+
body: JSON.stringify({
|
|
8351
|
+
system_instruction: { parts: [{ text: systemPrompt }] },
|
|
8352
|
+
contents: [{ parts: [
|
|
8353
|
+
{ inline_data: { mime_type: mimeType, data: base64 } },
|
|
8354
|
+
{ text: imagePrompt },
|
|
8355
|
+
]}],
|
|
8356
|
+
generationConfig: { maxOutputTokens: 4096 },
|
|
8357
|
+
}),
|
|
8358
|
+
});
|
|
8359
|
+
if (!res.ok) throw new Error(`Gemini ${res.status}: ${(await res.text()).slice(0, 200)}`);
|
|
8360
|
+
const data = await res.json();
|
|
8361
|
+
response = data.candidates?.[0]?.content?.parts?.[0]?.text || '';
|
|
8362
|
+
} else {
|
|
8363
|
+
console.log(`❌ Vision not supported for provider "${aiConfig.provider}". Use claude, openai, or gemini.`);
|
|
8364
|
+
return;
|
|
8365
|
+
}
|
|
8366
|
+
|
|
8367
|
+
console.log(` \x1b[32m${response}\x1b[0m\n`);
|
|
8368
|
+
return;
|
|
8369
|
+
}
|
|
8370
|
+
|
|
8371
|
+
// Text-only: call LLM via the standard chat function
|
|
8372
|
+
if (!userMessage) {
|
|
8373
|
+
console.log('❌ No prompt provided. Usage: nha ask <agent> "your prompt"');
|
|
8374
|
+
return;
|
|
8375
|
+
}
|
|
8376
|
+
|
|
8377
|
+
const response = await askAI({ ...aiConfig, provider: aiConfig.provider === 'anthropic' ? 'claude' : aiConfig.provider, maxTokens: 4096, systemPrompt }, userMessage, 'analysis');
|
|
8378
|
+
console.log(` \x1b[32m${response}\x1b[0m\n`);
|
|
8379
|
+
} catch (error) {
|
|
8380
|
+
console.error(`❌ Error: ${error.message}`);
|
|
8381
|
+
}
|
|
8382
|
+
},
|
|
8383
|
+
|
|
8210
8384
|
async help() {
|
|
8211
8385
|
console.log(`
|
|
8212
8386
|
PIF v${PIF_VERSION} - Please Insert Floppy - NotHumanAllowed AI Agent
|
|
8213
8387
|
https://nothumanallowed.com
|
|
8214
8388
|
|
|
8389
|
+
AGENTS:
|
|
8390
|
+
ask <agent> "prompt" Ask any agent (saber, oracle, forge, etc.)
|
|
8391
|
+
--file FILE Attach a text file for analysis
|
|
8392
|
+
--image IMAGE Attach an image for vision analysis (claude/openai/gemini)
|
|
8393
|
+
|
|
8215
8394
|
SETUP & DIAGNOSTICS:
|
|
8216
8395
|
setup Interactive onboarding wizard (first-time)
|
|
8217
8396
|
register [--name NAME] Register a new agent on NHA
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.5.0",
|
|
4
4
|
"description": "NotHumanAllowed — 38 AI agents + unified productivity suite. Gmail, Calendar, Drive, Contacts, Tasks, GitHub, Notion, Slack, voice chat, smart scheduler. Zero-dependency CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|