nothumanallowed 13.5.124 → 13.5.126
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/package.json +1 -1
- package/src/commands/ui.mjs +22 -1
- package/src/constants.mjs +1 -1
- package/src/services/email-db.mjs +15 -3
- package/src/services/tool-executor.mjs +11 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "13.5.
|
|
3
|
+
"version": "13.5.126",
|
|
4
4
|
"description": "NotHumanAllowed — 38 AI agents, 80 tools, Studio (visual agentic workflows). Email, calendar, browser automation, screen capture, canvas, cron/heartbeat, Alexandria E2E messaging, GitHub, Notion, Slack, voice chat, free AI (Liara), 28 languages. Zero-dependency CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/commands/ui.mjs
CHANGED
|
@@ -259,6 +259,22 @@ export async function cmdUI(args) {
|
|
|
259
259
|
`Never output raw JSON to the user.`;
|
|
260
260
|
const chatSystemPrompt = await buildSystemPrompt('NHA UI', UI_PERSONA, config);
|
|
261
261
|
|
|
262
|
+
// Returns a live IMAP accounts block to append to any system prompt
|
|
263
|
+
async function getImapAccountsContext() {
|
|
264
|
+
try {
|
|
265
|
+
const { listAccounts } = await import('../services/email-db.mjs');
|
|
266
|
+
const accs = listAccounts();
|
|
267
|
+
if (!accs.length) return '';
|
|
268
|
+
let ctx = '\n\n--- IMAP EMAIL ACCOUNTS (custom, already configured) ---\n';
|
|
269
|
+
ctx += 'Use these accountIds directly in imap_* tools — do NOT call imap_accounts() first.\n';
|
|
270
|
+
for (const a of accs) {
|
|
271
|
+
ctx += `accountId: "${a.id}" | email: ${a.email_address} | name: "${a.display_name}" | status: ${a.sync_status}\n`;
|
|
272
|
+
}
|
|
273
|
+
ctx += 'When the user mentions their company name, email domain, or display name, map it to the correct accountId above.';
|
|
274
|
+
return ctx;
|
|
275
|
+
} catch { return ''; }
|
|
276
|
+
}
|
|
277
|
+
|
|
262
278
|
// ── Route Handlers ──────────────────────────────────────────────────────
|
|
263
279
|
|
|
264
280
|
async function handleRequest(req, res) {
|
|
@@ -1817,13 +1833,17 @@ export async function cmdUI(args) {
|
|
|
1817
1833
|
parts.push(`[User] ${body.message}`);
|
|
1818
1834
|
let userMessage = parts.join('\n\n');
|
|
1819
1835
|
|
|
1820
|
-
// Inject episodic memory
|
|
1836
|
+
// Inject episodic memory + live IMAP accounts into the system prompt
|
|
1821
1837
|
const basePrompt = effectiveSystemPrompt || chatSystemPrompt;
|
|
1822
1838
|
let enrichedSystemPrompt = basePrompt;
|
|
1823
1839
|
try {
|
|
1824
1840
|
const memCtx = buildMemoryContext('chat', body.message);
|
|
1825
1841
|
if (memCtx) enrichedSystemPrompt = basePrompt + memCtx;
|
|
1826
1842
|
} catch { /* memory unavailable */ }
|
|
1843
|
+
try {
|
|
1844
|
+
const imapCtx = await getImapAccountsContext();
|
|
1845
|
+
if (imapCtx) enrichedSystemPrompt += imapCtx;
|
|
1846
|
+
} catch { /* imap context unavailable */ }
|
|
1827
1847
|
|
|
1828
1848
|
// Handle image attachment — vision API
|
|
1829
1849
|
if (body.imageBase64 && body.imageMimeType) {
|
|
@@ -2277,6 +2297,7 @@ export async function cmdUI(args) {
|
|
|
2277
2297
|
const basePrompt = effectiveSystemPrompt || chatSystemPrompt;
|
|
2278
2298
|
let enrichedPrompt = basePrompt;
|
|
2279
2299
|
try { const m = buildMemoryContext('chat', effectiveMsg); if (m) enrichedPrompt = basePrompt + m; } catch {}
|
|
2300
|
+
try { const ic = await getImapAccountsContext(); if (ic) enrichedPrompt += ic; } catch {}
|
|
2280
2301
|
|
|
2281
2302
|
// Build message with rolling context window:
|
|
2282
2303
|
// - Recent messages (last 6): full content up to 2000 chars
|
package/src/constants.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'url';
|
|
|
5
5
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
6
|
const __dirname = path.dirname(__filename);
|
|
7
7
|
|
|
8
|
-
export const VERSION = '13.5.
|
|
8
|
+
export const VERSION = '13.5.126';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
* Nothing is ever written back to the IMAP server.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import Database from 'better-sqlite3';
|
|
10
9
|
import { createHash, randomUUID } from 'crypto';
|
|
11
10
|
import { mkdirSync } from 'fs';
|
|
12
11
|
import { join } from 'path';
|
|
@@ -17,13 +16,26 @@ const DB_PATH = join(NHA_DIR, 'email.db');
|
|
|
17
16
|
|
|
18
17
|
let _db = null;
|
|
19
18
|
|
|
19
|
+
// Lazy-load better-sqlite3 so NHA works on platforms where it can't be compiled (Android/Termux)
|
|
20
|
+
let _Database = null;
|
|
21
|
+
try {
|
|
22
|
+
const mod = await import('better-sqlite3');
|
|
23
|
+
_Database = mod.default || mod;
|
|
24
|
+
} catch {
|
|
25
|
+
// better-sqlite3 not available (e.g. Android/Termux without build tools)
|
|
26
|
+
// IMAP email features will be disabled; all other NHA features work normally
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const SQLITE_AVAILABLE = !!_Database;
|
|
30
|
+
|
|
20
31
|
export function getDb() {
|
|
32
|
+
if (!_Database) throw new Error('Email features are not available on this platform. better-sqlite3 requires native compilation (not supported on Android/Termux). All other NHA features work normally.');
|
|
21
33
|
if (_db && _db.open) return _db;
|
|
22
34
|
mkdirSync(NHA_DIR, { recursive: true });
|
|
23
|
-
_db = new
|
|
35
|
+
_db = new _Database(DB_PATH);
|
|
24
36
|
_db.pragma('journal_mode = WAL');
|
|
25
37
|
_db.pragma('foreign_keys = ON');
|
|
26
|
-
_db.pragma('cache_size = -8000');
|
|
38
|
+
_db.pragma('cache_size = -8000');
|
|
27
39
|
initSchema(_db);
|
|
28
40
|
return _db;
|
|
29
41
|
}
|
|
@@ -961,9 +961,17 @@ export async function executeTool(action, params, config) {
|
|
|
961
961
|
const { listMessages: imapListMessages } = await import('./email-db.mjs');
|
|
962
962
|
const result = imapListMessages(params.accountId, params.labelId || null, params.limit || 20, 0, params.search || null);
|
|
963
963
|
if (!result.messages.length) return 'No messages found.';
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
964
|
+
const rows = result.messages.map((m, i) => {
|
|
965
|
+
const date = (m.internal_date || '').slice(0, 10);
|
|
966
|
+
const time = (m.internal_date || '').slice(11, 16);
|
|
967
|
+
const from = m.from_name ? `${m.from_name} <${m.from_address}>` : m.from_address;
|
|
968
|
+
const status = m.is_read ? '✓' : '● UNREAD';
|
|
969
|
+
const star = m.is_starred ? ' ★' : '';
|
|
970
|
+
const attach = m.has_attachments ? ' 📎' : '';
|
|
971
|
+
const preview = (m.body_preview || '').slice(0, 150);
|
|
972
|
+
return `${i + 1}. ${status}${star}${attach}\n ID: ${m.id}\n From: ${from}\n Subject: ${m.subject || '(no subject)'}\n Date: ${date} ${time}\n Preview: ${preview}`;
|
|
973
|
+
});
|
|
974
|
+
return `Found ${result.total} messages (showing ${result.messages.length}):\n\n` + rows.join('\n\n---\n\n');
|
|
967
975
|
}
|
|
968
976
|
|
|
969
977
|
case 'imap_read': {
|