nothumanallowed 13.5.193 → 13.5.194

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": "13.5.193",
3
+ "version": "13.5.194",
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 = '13.5.193';
8
+ export const VERSION = '13.5.194';
9
9
  export const BASE_URL = 'https://nothumanallowed.com/cli';
10
10
  export const API_BASE = 'https://nothumanallowed.com/api/v1';
11
11
 
@@ -179,7 +179,7 @@ function detectLanguage(text) {
179
179
  * Like chat.mjs but headless — no confirmation prompts, all tools auto-executed.
180
180
  * Returns a human-readable summary of what was done.
181
181
  */
182
- async function callAgentWithTools(config, agentName, userMessage, languageOverride) {
182
+ async function callAgentWithTools(config, agentName, userMessage, languageOverride, preHistory) {
183
183
  const today = new Date().toISOString().split('T')[0];
184
184
  const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
185
185
  const locale = Intl.DateTimeFormat().resolvedOptions().locale || 'en';
@@ -193,16 +193,15 @@ async function callAgentWithTools(config, agentName, userMessage, languageOverri
193
193
  .replace(/\{\{LANGUAGE\}\}/g, language);
194
194
 
195
195
  // Multi-turn: serialize history as [User]/[Assistant] string (same pattern as chat.mjs)
196
- const history = []; // [{role, content}]
196
+ // preHistory: optional [{role, content}] from previous conversation turn (for sticky confirmations)
197
+ const history = preHistory ? [...preHistory] : [];
197
198
  let finalText = '';
199
+ let lastToolResults = null; // saved for context return
198
200
 
199
- for (let round = 0; round < 3; round++) {
201
+ for (let round = 0; round < 4; round++) {
200
202
  // Build serialized message
201
203
  const parts = history.map(h => (h.role === 'user' ? '[User]' : '[Assistant]') + ' ' + h.content);
202
204
  parts.push('[User] ' + userMessage);
203
- if (round > 0) {
204
- // Replace last user with tool results continuation
205
- }
206
205
  const serialized = parts.join('\n\n');
207
206
 
208
207
  const response = await callLLM(config, systemPrompt, serialized);
@@ -226,13 +225,14 @@ async function callAgentWithTools(config, agentName, userMessage, languageOverri
226
225
  toolResults.push(`[${action}] Error: ${err.message}`);
227
226
  }
228
227
  }
228
+ lastToolResults = toolResults;
229
229
 
230
230
  // Feed results back: append assistant response + tool results as next user turn
231
231
  history.push({ role: 'assistant', content: response });
232
232
  userMessage = 'Tool results:\n' + toolResults.join('\n') + '\n\nNow give the user a concise confirmation in ' + language + '. Do NOT use HERALD format — respond conversationally.';
233
233
  }
234
234
 
235
- return finalText || 'Done.';
235
+ return { text: finalText || 'Done.', history, lastToolResults };
236
236
  }
237
237
 
238
238
  // ── Telegram Bot (Long Polling via native fetch) ─────────────────────────────
@@ -587,17 +587,24 @@ class TelegramResponder {
587
587
 
588
588
  let agent;
589
589
  let enrichedMessage = cleanText;
590
+ let preHistory = null;
590
591
  if (useStickyAgent) {
591
592
  agent = lastCtx.agent;
592
- // Inject previous turn context so agent understands what "Sì" refers to
593
- const nl = '\n';
594
- enrichedMessage =
595
- '[Conversazione precedente]' + nl +
596
- 'Utente: ' + lastCtx.userMsg + nl +
597
- 'Tu (' + agent.toUpperCase() + '): ' + lastCtx.agentReply.slice(0, 400) + nl + nl +
598
- '[Nuovo messaggio utente]' + nl +
599
- cleanText;
600
- this.log(`[Telegram] ${fromUser}: sticky agent ${agent.toUpperCase()} (ambiguous message, last ctx ${Math.round(stickyAge/1000)}s ago)`);
593
+ // Re-inject the full conversation history from last turn so the agent
594
+ // has the eventId/context already and can proceed directly (e.g. calendar_delete)
595
+ if (lastCtx.history && lastCtx.history.length > 0) {
596
+ preHistory = lastCtx.history;
597
+ } else {
598
+ // Fallback: text-only context injection
599
+ const nl = '\n';
600
+ enrichedMessage =
601
+ '[Conversazione precedente]' + nl +
602
+ 'Utente: ' + lastCtx.userMsg + nl +
603
+ 'Tu (' + agent.toUpperCase() + '): ' + lastCtx.agentReply.slice(0, 600) + nl + nl +
604
+ '[Nuovo messaggio utente — è una conferma/risposta al turno precedente]' + nl +
605
+ cleanText;
606
+ }
607
+ this.log(`[Telegram] ${fromUser}: sticky agent ${agent.toUpperCase()} (ambiguous, last ctx ${Math.round(stickyAge/1000)}s ago, preHistory=${preHistory ? preHistory.length : 0} turns)`);
601
608
  } else {
602
609
  agent = routeMessage(cleanText, this.autoRoute);
603
610
  this.log(`[Telegram] ${fromUser} (chat ${chatId}): routed to ${agent.toUpperCase()}${isVoice ? ' [voice]' : ''}`);
@@ -620,25 +627,30 @@ class TelegramResponder {
620
627
  // Tool-capable agents use the full tool execution loop
621
628
  // Pure reasoning/analysis agents use the simple callAgent (no tools)
622
629
  const TOOL_AGENTS = new Set(['herald', 'hermes', 'edi', 'jarvis', 'flux', 'echo', 'mercury', 'pipe', 'navi', 'link', 'prometheus', 'tempest']);
623
- let response;
630
+ let responseText;
631
+ let responseHistory = null;
624
632
  if (TOOL_AGENTS.has(agent)) {
625
- response = await callAgentWithTools(this.config, agent, enrichedMessage, detectedLang);
633
+ const result = await callAgentWithTools(this.config, agent, enrichedMessage, detectedLang, preHistory);
634
+ responseText = result.text;
635
+ responseHistory = result.history;
626
636
  } else {
627
637
  // For non-tool agents: inject language instruction into the message
628
638
  const langInstruction = detectedLang ? `[Respond in ${detectedLang}] ` : '';
629
- response = await callAgent(this.config, agent, langInstruction + enrichedMessage);
639
+ responseText = await callAgent(this.config, agent, langInstruction + enrichedMessage);
630
640
  }
631
641
 
632
642
  // Truncate if too long for Telegram (4096 char limit)
633
- const truncated = response.length > 4000
634
- ? response.slice(0, 3950) + '\n\n... [truncated]'
635
- : response;
643
+ const truncated = responseText.length > 4000
644
+ ? responseText.slice(0, 3950) + '\n\n... [truncated]'
645
+ : responseText;
636
646
 
637
647
  // Save context for sticky agent continuity (next short message reuses this agent)
648
+ // Save full history so next confirmation turn has the eventId already resolved
638
649
  this._lastContextByChatId[chatId] = {
639
650
  agent,
640
651
  userMsg: cleanText,
641
- agentReply: response,
652
+ agentReply: responseText,
653
+ history: responseHistory,
642
654
  ts: Date.now(),
643
655
  };
644
656
  this._lastAgentByChatId[chatId] = agent;
@@ -649,7 +661,7 @@ class TelegramResponder {
649
661
  text: `[${agent.toUpperCase()}]\n\n${truncated}`,
650
662
  });
651
663
 
652
- this.log(`[Telegram] Responded to ${fromUser} via ${agent.toUpperCase()} (${response.length} chars)`);
664
+ this.log(`[Telegram] Responded to ${fromUser} via ${agent.toUpperCase()} (${responseText.length} chars)`);
653
665
  } catch (err) {
654
666
  this.log(`[Telegram] Agent call failed: ${err.message}`);
655
667
  // Send error message to user