nothumanallowed 13.5.193 → 13.5.195
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/constants.mjs +1 -1
- package/src/services/message-responder.mjs +44 -27
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "13.5.
|
|
3
|
+
"version": "13.5.195",
|
|
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.
|
|
8
|
+
export const VERSION = '13.5.195';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { callAgent, callLLM } from './llm.mjs';
|
|
12
|
-
import { buildSystemPrompt, parseActions, executeTool, TOOL_DEFINITIONS } from './tool-executor.mjs';
|
|
12
|
+
import { buildSystemPrompt, parseActions, executeTool, TOOL_DEFINITIONS, LIARA_TOOL_DEFINITIONS } from './tool-executor.mjs';
|
|
13
13
|
import https from 'https';
|
|
14
14
|
import http from 'http';
|
|
15
15
|
import { URL } from 'url';
|
|
@@ -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';
|
|
@@ -187,22 +187,26 @@ async function callAgentWithTools(config, agentName, userMessage, languageOverri
|
|
|
187
187
|
// Priority: explicit override (from message text detection) → config setting → system locale
|
|
188
188
|
const language = languageOverride || config?.profile?.language || config?.language || LANG_MAP[locale.split('-')[0]] || 'English';
|
|
189
189
|
|
|
190
|
-
|
|
190
|
+
// Use compact Liara prompt when provider is 'nha' (same logic as buildSystemPrompt)
|
|
191
|
+
const isLiara = config?.llm?.provider === 'nha';
|
|
192
|
+
const baseDefinitions = isLiara ? LIARA_TOOL_DEFINITIONS : TOOL_DEFINITIONS;
|
|
193
|
+
const systemPrompt = baseDefinitions
|
|
191
194
|
.replace('{{TODAY}}', today)
|
|
192
195
|
.replace('{{TIMEZONE}}', tz)
|
|
193
|
-
.replace(/\{\{LANGUAGE\}\}/g, language)
|
|
196
|
+
.replace(/\{\{LANGUAGE\}\}/g, language) +
|
|
197
|
+
// For Telegram: user confirmation already happened in the chat — execute destructive actions directly
|
|
198
|
+
'\n\nIMPORTANT: This is a Telegram bot context. The user has already confirmed destructive actions (delete, send, etc.) via chat messages. Execute them immediately without asking again — do NOT describe what you are about to do, just do it and confirm when done.';
|
|
194
199
|
|
|
195
200
|
// Multi-turn: serialize history as [User]/[Assistant] string (same pattern as chat.mjs)
|
|
196
|
-
|
|
201
|
+
// preHistory: optional [{role, content}] from previous conversation turn (for sticky confirmations)
|
|
202
|
+
const history = preHistory ? [...preHistory] : [];
|
|
197
203
|
let finalText = '';
|
|
204
|
+
let lastToolResults = null; // saved for context return
|
|
198
205
|
|
|
199
|
-
for (let round = 0; round <
|
|
206
|
+
for (let round = 0; round < 4; round++) {
|
|
200
207
|
// Build serialized message
|
|
201
208
|
const parts = history.map(h => (h.role === 'user' ? '[User]' : '[Assistant]') + ' ' + h.content);
|
|
202
209
|
parts.push('[User] ' + userMessage);
|
|
203
|
-
if (round > 0) {
|
|
204
|
-
// Replace last user with tool results continuation
|
|
205
|
-
}
|
|
206
210
|
const serialized = parts.join('\n\n');
|
|
207
211
|
|
|
208
212
|
const response = await callLLM(config, systemPrompt, serialized);
|
|
@@ -226,13 +230,14 @@ async function callAgentWithTools(config, agentName, userMessage, languageOverri
|
|
|
226
230
|
toolResults.push(`[${action}] Error: ${err.message}`);
|
|
227
231
|
}
|
|
228
232
|
}
|
|
233
|
+
lastToolResults = toolResults;
|
|
229
234
|
|
|
230
235
|
// Feed results back: append assistant response + tool results as next user turn
|
|
231
236
|
history.push({ role: 'assistant', content: response });
|
|
232
237
|
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
238
|
}
|
|
234
239
|
|
|
235
|
-
return finalText || 'Done.';
|
|
240
|
+
return { text: finalText || 'Done.', history, lastToolResults };
|
|
236
241
|
}
|
|
237
242
|
|
|
238
243
|
// ── Telegram Bot (Long Polling via native fetch) ─────────────────────────────
|
|
@@ -587,17 +592,24 @@ class TelegramResponder {
|
|
|
587
592
|
|
|
588
593
|
let agent;
|
|
589
594
|
let enrichedMessage = cleanText;
|
|
595
|
+
let preHistory = null;
|
|
590
596
|
if (useStickyAgent) {
|
|
591
597
|
agent = lastCtx.agent;
|
|
592
|
-
//
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
598
|
+
// Re-inject the full conversation history from last turn so the agent
|
|
599
|
+
// has the eventId/context already and can proceed directly (e.g. calendar_delete)
|
|
600
|
+
if (lastCtx.history && lastCtx.history.length > 0) {
|
|
601
|
+
preHistory = lastCtx.history;
|
|
602
|
+
} else {
|
|
603
|
+
// Fallback: text-only context injection
|
|
604
|
+
const nl = '\n';
|
|
605
|
+
enrichedMessage =
|
|
606
|
+
'[Conversazione precedente]' + nl +
|
|
607
|
+
'Utente: ' + lastCtx.userMsg + nl +
|
|
608
|
+
'Tu (' + agent.toUpperCase() + '): ' + lastCtx.agentReply.slice(0, 600) + nl + nl +
|
|
609
|
+
'[Nuovo messaggio utente — è una conferma/risposta al turno precedente]' + nl +
|
|
610
|
+
cleanText;
|
|
611
|
+
}
|
|
612
|
+
this.log(`[Telegram] ${fromUser}: sticky agent ${agent.toUpperCase()} (ambiguous, last ctx ${Math.round(stickyAge/1000)}s ago, preHistory=${preHistory ? preHistory.length : 0} turns)`);
|
|
601
613
|
} else {
|
|
602
614
|
agent = routeMessage(cleanText, this.autoRoute);
|
|
603
615
|
this.log(`[Telegram] ${fromUser} (chat ${chatId}): routed to ${agent.toUpperCase()}${isVoice ? ' [voice]' : ''}`);
|
|
@@ -620,25 +632,30 @@ class TelegramResponder {
|
|
|
620
632
|
// Tool-capable agents use the full tool execution loop
|
|
621
633
|
// Pure reasoning/analysis agents use the simple callAgent (no tools)
|
|
622
634
|
const TOOL_AGENTS = new Set(['herald', 'hermes', 'edi', 'jarvis', 'flux', 'echo', 'mercury', 'pipe', 'navi', 'link', 'prometheus', 'tempest']);
|
|
623
|
-
let
|
|
635
|
+
let responseText;
|
|
636
|
+
let responseHistory = null;
|
|
624
637
|
if (TOOL_AGENTS.has(agent)) {
|
|
625
|
-
|
|
638
|
+
const result = await callAgentWithTools(this.config, agent, enrichedMessage, detectedLang, preHistory);
|
|
639
|
+
responseText = result.text;
|
|
640
|
+
responseHistory = result.history;
|
|
626
641
|
} else {
|
|
627
642
|
// For non-tool agents: inject language instruction into the message
|
|
628
643
|
const langInstruction = detectedLang ? `[Respond in ${detectedLang}] ` : '';
|
|
629
|
-
|
|
644
|
+
responseText = await callAgent(this.config, agent, langInstruction + enrichedMessage);
|
|
630
645
|
}
|
|
631
646
|
|
|
632
647
|
// Truncate if too long for Telegram (4096 char limit)
|
|
633
|
-
const truncated =
|
|
634
|
-
?
|
|
635
|
-
:
|
|
648
|
+
const truncated = responseText.length > 4000
|
|
649
|
+
? responseText.slice(0, 3950) + '\n\n... [truncated]'
|
|
650
|
+
: responseText;
|
|
636
651
|
|
|
637
652
|
// Save context for sticky agent continuity (next short message reuses this agent)
|
|
653
|
+
// Save full history so next confirmation turn has the eventId already resolved
|
|
638
654
|
this._lastContextByChatId[chatId] = {
|
|
639
655
|
agent,
|
|
640
656
|
userMsg: cleanText,
|
|
641
|
-
agentReply:
|
|
657
|
+
agentReply: responseText,
|
|
658
|
+
history: responseHistory,
|
|
642
659
|
ts: Date.now(),
|
|
643
660
|
};
|
|
644
661
|
this._lastAgentByChatId[chatId] = agent;
|
|
@@ -649,7 +666,7 @@ class TelegramResponder {
|
|
|
649
666
|
text: `[${agent.toUpperCase()}]\n\n${truncated}`,
|
|
650
667
|
});
|
|
651
668
|
|
|
652
|
-
this.log(`[Telegram] Responded to ${fromUser} via ${agent.toUpperCase()} (${
|
|
669
|
+
this.log(`[Telegram] Responded to ${fromUser} via ${agent.toUpperCase()} (${responseText.length} chars)`);
|
|
653
670
|
} catch (err) {
|
|
654
671
|
this.log(`[Telegram] Agent call failed: ${err.message}`);
|
|
655
672
|
// Send error message to user
|