nothumanallowed 16.0.58 → 16.0.59

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": "16.0.58",
3
+ "version": "16.0.59",
4
4
  "description": "Local AI assistant: 80 tools (Gmail, Calendar, Drive, GitHub, Slack, browser, code, files), 38 agents, visual workflows (Studio, AWF, WebCraft). Install with `npm i -g nothumanallowed`, run with `nha ui`. Free tier built-in (Liara), no API key required. Your data stays on your PC — OAuth tokens local, no cloud. Open-source MIT.",
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 = '16.0.58';
8
+ export const VERSION = '16.0.59';
9
9
  export const BASE_URL = 'https://nothumanallowed.com/cli';
10
10
  export const API_BASE = 'https://nothumanallowed.com/api/v1';
11
11
 
@@ -2672,7 +2672,69 @@ class TelegramResponder {
2672
2672
  }
2673
2673
  }
2674
2674
  } catch (e) { this.log(`[direct] pagination failed: ${e.message}`); }
2675
- // Fall through if no cached list
2675
+
2676
+ // NO CACHE FALLBACK (Giovanni's recurring bug): if user asks "mostra i
2677
+ // prossimi" but no calendar list was cached in this session, the LLM
2678
+ // hallucinates plausible-but-fake events. Instead, run calendar_upcoming
2679
+ // for the next 7 days directly here. Deterministic, zero LLM call.
2680
+ try {
2681
+ const { listEvents } = await import('./google-calendar.mjs');
2682
+ const now = new Date();
2683
+ const weekAhead = new Date(now.getTime() + 7 * 86400000);
2684
+ const evs = await listEvents(config, 'primary', now, weekAhead);
2685
+ if (Array.isArray(evs) && evs.length > 0) {
2686
+ const items = evs.map(e => ({
2687
+ eventId: e.id,
2688
+ id: e.id,
2689
+ summary: e.summary || '(senza titolo)',
2690
+ time: (e.start || '').slice(11, 16),
2691
+ date: (e.start || '').slice(0, 10),
2692
+ start: e.start,
2693
+ }));
2694
+ // Persist into list-cache so subsequent "mostra i prossimi" paginates
2695
+ try {
2696
+ const { rememberList } = await import('./list-cache.mjs');
2697
+ rememberList(chatId || '__last_list__', 'calendar', items);
2698
+ } catch {}
2699
+ const pageSize = 8;
2700
+ const firstSlice = items.slice(0, pageSize);
2701
+ const lines = [`šŸ“… Prossimi eventi (7 giorni, ${items.length} totali):`];
2702
+ const byDay = new Map();
2703
+ for (const e of firstSlice) {
2704
+ const day = e.date || 'misc';
2705
+ if (!byDay.has(day)) byDay.set(day, []);
2706
+ byDay.get(day).push(e);
2707
+ }
2708
+ for (const [day, evs] of [...byDay.entries()].sort()) {
2709
+ const d = day !== 'misc' ? new Date(day + 'T12:00:00').toLocaleDateString('it-IT', { weekday: 'short', day: 'numeric', month: 'short' }) : '';
2710
+ if (d) lines.push(`\n${d}:`);
2711
+ for (const e of evs) lines.push(` ${e.time || '—'} — ${e.summary}`);
2712
+ }
2713
+ if (items.length > pageSize) {
2714
+ lines.push(`\n... ${items.length - pageSize} eventi rimanenti. Scrivi "mostra i prossimi" per continuare.`);
2715
+ } else {
2716
+ lines.push(`\nāœ“ Fine elenco.`);
2717
+ }
2718
+ // Track shownCount so next "mostra i prossimi" works
2719
+ try {
2720
+ const cacheFile = path.join(os.homedir(), '.nha', 'list-cache.json');
2721
+ const cacheNow = fs.existsSync(cacheFile) ? JSON.parse(fs.readFileSync(cacheFile, 'utf-8')) : {};
2722
+ const key = chatId || '__last_list__';
2723
+ if (!cacheNow[key]) cacheNow[key] = {};
2724
+ cacheNow[key].lastList_calendar_shownCount = pageSize;
2725
+ fs.writeFileSync(cacheFile, JSON.stringify(cacheNow, null, 2));
2726
+ } catch {}
2727
+ this.log(`[direct] PAGINATION fallback: fetched ${items.length} events from calendar_upcoming(7d)`);
2728
+ return { action: 'calendar_page', success: true, message: lines.join('\n') };
2729
+ }
2730
+ // No events in next 7 days — say so explicitly, do NOT fall to LLM
2731
+ return { action: 'calendar_page', success: true, message: 'šŸ“… Nessun evento programmato nei prossimi 7 giorni. Scrivi "appuntamenti di [data/mese]" per cercare in un altro periodo.' };
2732
+ } catch (e) {
2733
+ this.log(`[direct] pagination fallback failed: ${e.message}`);
2734
+ // CRITICAL: do NOT fall through to LLM — return error instead of
2735
+ // letting HERALD hallucinate fake events (Giovanni's bug).
2736
+ return { action: 'calendar_page', success: false, message: `Non riesco a leggere il calendario in questo momento (${e.message.slice(0, 100)}). Verifica la connessione Google in Settings.` };
2737
+ }
2676
2738
  }
2677
2739
 
2678
2740
  // ─── ANAPHORIC delete + CONFIRMATION yes ────────────────────────────────