nothumanallowed 15.1.58 → 15.1.60
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/cli.mjs +4 -0
- package/src/constants.mjs +1 -1
- package/src/services/message-responder.mjs +55 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "15.1.
|
|
3
|
+
"version": "15.1.60",
|
|
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/cli.mjs
CHANGED
|
@@ -63,6 +63,10 @@ export async function main(argv) {
|
|
|
63
63
|
info(`Run "nha update" (recommended — auto-installs npm + agents)`);
|
|
64
64
|
info(`Or copy-paste this ENTIRE line (note: --prefer-online, not --pref-online):`);
|
|
65
65
|
info(` npm cache clean --force && npm install -g nothumanallowed@${result.latest} --prefer-online && hash -r && nha version`);
|
|
66
|
+
info(`⚠ If you ran the install WITHOUT "hash -r" at the end and now get`);
|
|
67
|
+
info(` "bash: ...node/vX.Y.Z/bin/nha: No such file", run: hash -r`);
|
|
68
|
+
info(` (or just close and reopen the terminal). It's a bash path cache issue,`);
|
|
69
|
+
info(` not an install failure — your nha package is already updated.`);
|
|
66
70
|
}
|
|
67
71
|
}).catch(() => {});
|
|
68
72
|
}
|
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 = '15.1.
|
|
8
|
+
export const VERSION = '15.1.60';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
|
@@ -952,6 +952,7 @@ class TelegramResponder {
|
|
|
952
952
|
// the LLM entirely: parse the proposal, resolve the eventId via
|
|
953
953
|
// calendar_date / calendar_find, then call calendar_delete /
|
|
954
954
|
// calendar_move directly. The user gets a guaranteed real result.
|
|
955
|
+
this._lastDirectAuditChatId = chatId;
|
|
955
956
|
const directResult = await this._tryDirectAction(lastCtx.agentReply || '', this.config);
|
|
956
957
|
if (directResult) {
|
|
957
958
|
this.log(`[Telegram] ${fromUser}: direct-action ${directResult.action} → ${directResult.success ? 'OK' : 'FAIL'}`);
|
|
@@ -1043,6 +1044,7 @@ class TelegramResponder {
|
|
|
1043
1044
|
// touching the API, OR invent the event list when asked for "all
|
|
1044
1045
|
// appointments of May". By running the calendar tool server-side, the
|
|
1045
1046
|
// user always sees REAL data — never fabricated.
|
|
1047
|
+
this._lastDirectAuditChatId = chatId;
|
|
1046
1048
|
const directFresh = await this._tryDirectFreshCalendarAction(cleanText, this.config);
|
|
1047
1049
|
if (directFresh) {
|
|
1048
1050
|
this.log(`[Telegram] ${fromUser}: direct-fresh ${directFresh.action} → ${directFresh.success ? 'OK' : 'FAIL'}`);
|
|
@@ -1103,6 +1105,13 @@ class TelegramResponder {
|
|
|
1103
1105
|
let responseText;
|
|
1104
1106
|
let responseHistory = null;
|
|
1105
1107
|
|
|
1108
|
+
// Inject cross-agent action audit log into the enriched message so any
|
|
1109
|
+
// agent invoked for this chat is aware of what other agents already did
|
|
1110
|
+
// (calendar deletes, email sends, task creations, etc.). Without this,
|
|
1111
|
+
// HERALD would forget a deletion executed via direct-action 2 turns ago.
|
|
1112
|
+
const auditNote = this._renderAuditForPrompt(chatId);
|
|
1113
|
+
if (auditNote) enrichedMessage = auditNote + enrichedMessage;
|
|
1114
|
+
|
|
1106
1115
|
if (TOOL_AGENTS.has(agent)) {
|
|
1107
1116
|
const result = await callAgentWithTools(this.config, agent, enrichedMessage, detectedLang, preHistory);
|
|
1108
1117
|
responseText = result.text;
|
|
@@ -1271,6 +1280,13 @@ class TelegramResponder {
|
|
|
1271
1280
|
const message = ok
|
|
1272
1281
|
? `Fatto. Ho cancellato "${summary}"${dateStr ? ` del ${this._formatDateIT(dateStr)}` : ''}${match.time ? ` alle ${match.time}` : ''}.`
|
|
1273
1282
|
: `Non sono riuscito a cancellare l'evento: ${delResult}`;
|
|
1283
|
+
if (this._lastDirectAuditChatId) {
|
|
1284
|
+
this._recordAudit(this._lastDirectAuditChatId, {
|
|
1285
|
+
tool: 'calendar_delete',
|
|
1286
|
+
success: ok,
|
|
1287
|
+
summary: `${summary}${dateStr ? ` del ${this._formatDateIT(dateStr)}` : ''}${match.time ? ` alle ${match.time}` : ''} (eventId ${match.eventId.slice(0, 16)}…)`,
|
|
1288
|
+
});
|
|
1289
|
+
}
|
|
1274
1290
|
return { action: 'calendar_delete', success: ok, message };
|
|
1275
1291
|
} catch (err) {
|
|
1276
1292
|
return { action: 'calendar_delete', success: false, message: `Errore nella cancellazione: ${err.message}` };
|
|
@@ -1354,6 +1370,36 @@ class TelegramResponder {
|
|
|
1354
1370
|
return events;
|
|
1355
1371
|
}
|
|
1356
1372
|
|
|
1373
|
+
// ── Action audit log (cross-agent memory of REAL executions) ─────────────
|
|
1374
|
+
// Every direct-action OR LLM-mediated tool call that mutates external state
|
|
1375
|
+
// (calendar, email, tasks, contacts, files, github, slack…) is appended
|
|
1376
|
+
// here. The log is per chatId, persisted to disk, capped at 50 entries.
|
|
1377
|
+
//
|
|
1378
|
+
// When ANY agent is invoked for this chat, the recent audit entries are
|
|
1379
|
+
// prepended to the user message as "AZIONI RECENTI ESEGUITE". Result: a
|
|
1380
|
+
// user who deleted a calendar event via HERALD and then asks JARVIS about
|
|
1381
|
+
// it ten minutes later — JARVIS sees the deletion in the audit log and
|
|
1382
|
+
// can answer factually. No more "have I done that?" amnesia.
|
|
1383
|
+
_recordAudit(chatId, entry) {
|
|
1384
|
+
const ctx = this._lastContextByChatId[chatId] || (this._lastContextByChatId[chatId] = {});
|
|
1385
|
+
if (!Array.isArray(ctx.auditLog)) ctx.auditLog = [];
|
|
1386
|
+
ctx.auditLog.push({ ts: Date.now(), ...entry });
|
|
1387
|
+
if (ctx.auditLog.length > 50) ctx.auditLog = ctx.auditLog.slice(-50);
|
|
1388
|
+
this._persistContext();
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
_renderAuditForPrompt(chatId, maxEntries = 10) {
|
|
1392
|
+
const ctx = this._lastContextByChatId[chatId];
|
|
1393
|
+
if (!ctx || !Array.isArray(ctx.auditLog) || ctx.auditLog.length === 0) return '';
|
|
1394
|
+
const recent = ctx.auditLog.slice(-maxEntries);
|
|
1395
|
+
const lines = recent.map(e => {
|
|
1396
|
+
const time = new Date(e.ts).toLocaleString('it-IT', { day: '2-digit', month: 'short', hour: '2-digit', minute: '2-digit' });
|
|
1397
|
+
const status = e.success === false ? '✗ FALLITA' : '✓ OK';
|
|
1398
|
+
return `- ${time} · ${e.tool} · ${status} · ${e.summary || ''}`;
|
|
1399
|
+
});
|
|
1400
|
+
return `\n\n[AZIONI RECENTI ESEGUITE IN QUESTA CONVERSAZIONE — fonte di verità sui fatti già accaduti]\n${lines.join('\n')}\n[FINE AZIONI RECENTI]\n`;
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1357
1403
|
_formatDateIT(isoDate) {
|
|
1358
1404
|
const m = String(isoDate || '').match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
1359
1405
|
if (!m) return isoDate;
|
|
@@ -1564,6 +1610,15 @@ class TelegramResponder {
|
|
|
1564
1610
|
const message = ok
|
|
1565
1611
|
? `Fatto. Ho cancellato "${summary}"${dateStr ? ` del ${this._formatDateIT(dateStr)}` : ''}${match.time ? ` alle ${match.time}` : ''}.`
|
|
1566
1612
|
: `Non sono riuscito a cancellare l'evento: ${delResult}`;
|
|
1613
|
+
// Audit log — every agent in this chat will see this entry on their
|
|
1614
|
+
// next invocation, so no one forgets the deletion happened.
|
|
1615
|
+
if (this._lastDirectAuditChatId) {
|
|
1616
|
+
this._recordAudit(this._lastDirectAuditChatId, {
|
|
1617
|
+
tool: 'calendar_delete',
|
|
1618
|
+
success: ok,
|
|
1619
|
+
summary: `${summary}${dateStr ? ` del ${this._formatDateIT(dateStr)}` : ''}${match.time ? ` alle ${match.time}` : ''} (eventId ${match.eventId.slice(0, 16)}…)`,
|
|
1620
|
+
});
|
|
1621
|
+
}
|
|
1567
1622
|
return { action: 'calendar_delete', success: ok, message };
|
|
1568
1623
|
} catch (e) {
|
|
1569
1624
|
return { action: 'calendar_delete', success: false, message: `Errore nella cancellazione: ${e.message}` };
|