nothumanallowed 15.1.56 → 15.1.58

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nothumanallowed",
3
- "version": "15.1.56",
3
+ "version": "15.1.58",
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/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.56';
8
+ export const VERSION = '15.1.58';
9
9
  export const BASE_URL = 'https://nothumanallowed.com/cli';
10
10
  export const API_BASE = 'https://nothumanallowed.com/api/v1';
11
11
 
@@ -1380,11 +1380,73 @@ class TelegramResponder {
1380
1380
 
1381
1381
  const isDelete = /\b(elimin|cancell|rimuov|cancel\b|delete\b|remove\b)\w*/.test(lower);
1382
1382
  const isList = /\b(lista|elenco|mostra|mostrami|fammi vedere|fai vedere|tutti|dammi|dimmi|cosa\s+ho|che\s+impegni|impegni|appuntamenti|eventi|meeting|agenda|calendario)\b/.test(lower);
1383
+ // Verify intent — user is challenging or asking us to re-check a previous
1384
+ // calendar claim. Triggered by complaint phrases ("non vedo più", "sei
1385
+ // sicuro?", "hai sbagliato", "inaffidabile", "in realtà") combined with
1386
+ // a date or title reference. We answer FACTUALLY by re-querying the
1387
+ // calendar — never by apologizing in the abstract.
1388
+ const isVerify = /\b(non\s+(vedo|c'è|esiste)|c'è\s+(ancora|sempre)|è\s+ancora|stai\s+sbagliand|hai\s+sbagliat|in\s+realt[àa]|sei\s+sicur|davvero|inaffidabil|controlla|verifica|conferma\b|guarda)\b/.test(lower);
1383
1389
 
1384
1390
  const { executeTool } = await import('./tool-executor.mjs');
1385
1391
 
1392
+ // ─── VERIFY intent ─────────────────────────────────────────────────────
1393
+ // User is challenging a prior action ("non c'è più", "sei sicuro?",
1394
+ // "hai sbagliato", "inaffidabile", "in realtà l'hai cancellato"). The
1395
+ // only honest reply is a factual re-check, NOT a vague apology. We
1396
+ // re-query the calendar and report exactly what's there.
1397
+ if (isVerify) {
1398
+ const extracted = this._extractCalendarProposal(userMessage);
1399
+ if (extracted.date || extracted.title) {
1400
+ let events = [];
1401
+ try {
1402
+ if (extracted.date) {
1403
+ const result = await executeTool('calendar_date', { date: extracted.date }, config);
1404
+ events = this._parseEventsFromToolOutput(result);
1405
+ } else if (extracted.title) {
1406
+ const result = await executeTool('calendar_find', { query: extracted.title, daysAhead: 60 }, config);
1407
+ events = this._parseEventsFromToolOutput(result);
1408
+ }
1409
+ } catch (e) {
1410
+ return { action: 'calendar_verify', success: false, message: `Errore durante la verifica: ${e.message}` };
1411
+ }
1412
+
1413
+ const dateStr = extracted.date ? this._formatDateIT(extracted.date) : null;
1414
+ // Filter by title match if both date and title are present, to be precise.
1415
+ let matching = events;
1416
+ if (extracted.title && events.length > 0) {
1417
+ const norm = (s) => String(s || '').toLowerCase()
1418
+ .normalize('NFD').replace(/[̀-ͯ]/g, '')
1419
+ .replace(/[^a-z0-9\s]/g, ' ')
1420
+ .split(/\s+/).filter(t => t.length > 2);
1421
+ const titleTokens = norm(extracted.title);
1422
+ matching = events.filter(c => {
1423
+ const summaryTokens = new Set(norm(c.summary));
1424
+ const score = titleTokens.filter(t => summaryTokens.has(t)).length;
1425
+ return score >= Math.max(1, Math.ceil(titleTokens.length * 0.5));
1426
+ });
1427
+ }
1428
+
1429
+ if (matching.length === 0) {
1430
+ // Event genuinely absent — confirm fact, no apology.
1431
+ const subject = extracted.title ? `"${extracted.title}"` : 'l\'appuntamento';
1432
+ const when = dateStr ? ` del ${dateStr}` : '';
1433
+ return {
1434
+ action: 'calendar_verify', success: true,
1435
+ message: `Confermato: ${subject}${when} NON è presente nel calendario. Risulta cancellato.`,
1436
+ };
1437
+ }
1438
+ // Event(s) still present.
1439
+ const list = matching.slice(0, 5).map((c, i) => `${i + 1}. ${c.time || '—'} ${c.summary}`).join('\n');
1440
+ return {
1441
+ action: 'calendar_verify', success: true,
1442
+ message: `Ho riverificato il calendario${dateStr ? ` per ${dateStr}` : ''}:\n\n${list}\n\nQuesti appuntamenti risultano ancora presenti.`,
1443
+ };
1444
+ }
1445
+ // No date/title to verify — fall through to LIST/DELETE detection.
1446
+ }
1447
+
1386
1448
  // ─── LIST intents ──────────────────────────────────────────────────────
1387
- if (isList && !isDelete) {
1449
+ if (isList && !isDelete && !isVerify) {
1388
1450
  // "appuntamenti di oggi"
1389
1451
  if (/\b(oggi|today)\b/.test(lower)) {
1390
1452
  try {