nothumanallowed 15.1.32 → 15.1.33
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.
|
|
3
|
+
"version": "15.1.33",
|
|
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.
|
|
8
|
+
export const VERSION = '15.1.33';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
|
@@ -822,17 +822,50 @@ class TelegramResponder {
|
|
|
822
822
|
const shortConfirm = /^(s[ìi]\.?|ok\.?|okay\.?|yes\.?|yep\.?|sure\.?|certo\.?|procedi\.?|fallo\.?|vai\.?|go\.?|do it\.?|conferma\.?|certo che s[ìi]\.?|fallo pure\.?)$/i.test(cleanText.trim());
|
|
823
823
|
|
|
824
824
|
if (proposedAction && shortConfirm) {
|
|
825
|
+
// Extract the SPECIFIC action the assistant proposed (create/delete/
|
|
826
|
+
// update/move/send/...), so we can inject an explicit tool name in
|
|
827
|
+
// the instruction. Without this, Liara may pick a random tool —
|
|
828
|
+
// e.g. user confirms a CREATE proposal and the model fires DELETE
|
|
829
|
+
// with a hallucinated eventId.
|
|
830
|
+
const r = lowerReply;
|
|
831
|
+
let actionHint = '';
|
|
832
|
+
let toolHint = '';
|
|
833
|
+
if (/fissat[oa]|inserir[oe]|cre(a|er)[oa]|aggiunger[oeò]|prenota|registr[oa]|mett[oa] (?:in calendario|nel calendario)/.test(r)) {
|
|
834
|
+
actionHint = 'CREARE un nuovo appuntamento';
|
|
835
|
+
toolHint = 'calendar_create con i parametri ESATTI (summary, start, end) che hai descritto nel turno precedente';
|
|
836
|
+
} else if (/cancell|eliminar[eo]|rimuover/.test(r)) {
|
|
837
|
+
actionHint = 'CANCELLARE un appuntamento esistente';
|
|
838
|
+
toolHint = 'PRIMA calendar_find/calendar_date per ottenere l\'eventId REALE, POI calendar_delete con quell\'eventId. Mai inventare ID';
|
|
839
|
+
} else if (/spostar|riprogrammar|cambiar[eo] (?:l\')?orario|cambiar[eo] (?:la )?data/.test(r)) {
|
|
840
|
+
actionHint = 'SPOSTARE un appuntamento';
|
|
841
|
+
toolHint = 'PRIMA calendar_find per ottenere eventId, POI calendar_move(eventId, newStart, newEnd)';
|
|
842
|
+
} else if (/modificar|correggere|rinominar|cambiar[eo] (?:il )?titolo/.test(r)) {
|
|
843
|
+
actionHint = 'MODIFICARE un appuntamento';
|
|
844
|
+
toolHint = 'PRIMA calendar_find per eventId, POI calendar_update(eventId, ...) con SOLO i campi da cambiare';
|
|
845
|
+
} else if (/inviar|spedir|mandar (?:l\'|la )?email|send (?:the )?email/.test(r)) {
|
|
846
|
+
actionHint = 'INVIARE un\'email';
|
|
847
|
+
toolHint = 'gmail_send (o gmail_reply se è una risposta) con destinatario, oggetto e corpo già concordati';
|
|
848
|
+
} else if (/aggiunger[eo] (?:un )?task|creare (?:un )?task|inserir[eo] (?:il )?task/.test(r)) {
|
|
849
|
+
actionHint = 'CREARE un task';
|
|
850
|
+
toolHint = 'task_add con la descrizione concordata';
|
|
851
|
+
} else {
|
|
852
|
+
actionHint = 'l\'azione che hai proposto';
|
|
853
|
+
toolHint = 'il tool corrispondente all\'azione (calendar_create se hai detto "fisso"; calendar_delete se "cancello"; gmail_send se "invio"; ecc.). NON inventare eventId — usa SOLO ID reali ricevuti da tool precedenti';
|
|
854
|
+
}
|
|
855
|
+
|
|
825
856
|
enrichedMessage =
|
|
826
|
-
`[CONFERMA UTENTE — Esegui SUBITO l'azione che hai proposto
|
|
827
|
-
`Tuo turno precedente:\n"${(lastCtx.agentReply || '').slice(0, 800)}"\n\n` +
|
|
857
|
+
`[CONFERMA UTENTE — Esegui SUBITO l'azione che hai proposto]\n\n` +
|
|
858
|
+
`Tuo turno precedente (proposta):\n"${(lastCtx.agentReply || '').slice(0, 800)}"\n\n` +
|
|
828
859
|
`Risposta utente: "${cleanText.trim()}"\n\n` +
|
|
860
|
+
`AZIONE DA ESEGUIRE: ${actionHint}\n` +
|
|
861
|
+
`TOOL DA USARE: ${toolHint}\n\n` +
|
|
829
862
|
`ISTRUZIONI OBBLIGATORIE:\n` +
|
|
830
|
-
`1.
|
|
831
|
-
`2.
|
|
832
|
-
`3. Se
|
|
833
|
-
`4.
|
|
834
|
-
`5. NON
|
|
835
|
-
this.log(`[Telegram] ${fromUser}: pending-action force
|
|
863
|
+
`1. Emetti SUBITO il blocco JSON \`\`\`json {"action":"...","params":{...}} \`\`\` per ESATTAMENTE l'azione qui sopra.\n` +
|
|
864
|
+
`2. Usa i parametri (data, ora, titolo, destinatario, eccetera) che HAI GIÀ menzionato nel tuo turno precedente. NON chiedere di nuovo.\n` +
|
|
865
|
+
`3. Se l'azione è CREATE/SEND/ADD: emetti SOLO quel tool. NIENTE find/delete/update preliminare — quei tool servono per modificare cose esistenti, non per creare di nuove.\n` +
|
|
866
|
+
`4. Se l'azione è DELETE/UPDATE/MOVE: emetti PRIMA calendar_find o calendar_date per trovare l'eventId REALE (lungo, alfanumerico Google). MAI usare placeholder come "A1B2C3D4E5F6G7H8I9J0", "abc123", "ABC123".\n` +
|
|
867
|
+
`5. NON chiedere "cosa vuoi". NON dire "Procedo." senza eseguire. SOLO il blocco JSON e una breve conferma in italiano dopo l'esecuzione.`;
|
|
868
|
+
this.log(`[Telegram] ${fromUser}: pending-action force → ${actionHint}`);
|
|
836
869
|
}
|
|
837
870
|
|
|
838
871
|
this.log(`[Telegram] ${fromUser}: continuation → ${agent.toUpperCase()} (ctx ${Math.round(stickyAge/1000)}s ago, history=${preHistory ? preHistory.length : 0})`);
|
|
@@ -1091,6 +1091,41 @@ export async function buildSystemPrompt(persona, personaDescription, config, ini
|
|
|
1091
1091
|
* @param {object} config — NHA config
|
|
1092
1092
|
* @returns {Promise<string>} result description
|
|
1093
1093
|
*/
|
|
1094
|
+
|
|
1095
|
+
/**
|
|
1096
|
+
* Detect IDs that the model has clearly invented vs real Google Calendar
|
|
1097
|
+
* eventIds. Real ones are LONG (≥10), LOWERCASE, alphanumeric (a-v + 0-9,
|
|
1098
|
+
* sometimes with `_` or `-`). Placeholders are typically short, uppercase,
|
|
1099
|
+
* dictionary words, or alternate-letter+digit pseudo-random patterns like
|
|
1100
|
+
* "A1B2C3D4E5F6G7H8I9J0".
|
|
1101
|
+
*/
|
|
1102
|
+
function isPlaceholderEventId(id) {
|
|
1103
|
+
if (!id || typeof id !== 'string') return true;
|
|
1104
|
+
const s = id.trim();
|
|
1105
|
+
// 1. Explicit literal blocklist (covers everything we've seen so far)
|
|
1106
|
+
const LITERAL = new Set([
|
|
1107
|
+
'abc123', 'def456', 'xyz789', 'event_123', 'event_123456789',
|
|
1108
|
+
'123', '456', 'foo', 'bar', 'baz', 'example', 'placeholder',
|
|
1109
|
+
'eventid', 'event_id', 'id', 'null', 'undefined', 'some-google-id',
|
|
1110
|
+
'event-id', 'id-from-tool', 'event_abc', 'event_xyz',
|
|
1111
|
+
]);
|
|
1112
|
+
if (LITERAL.has(s.toLowerCase())) return true;
|
|
1113
|
+
// 2. Too short — Google eventIds are always ≥ 16 chars in practice
|
|
1114
|
+
if (s.length < 10) return true;
|
|
1115
|
+
// 3. Contains spaces — never valid
|
|
1116
|
+
if (/\s/.test(s)) return true;
|
|
1117
|
+
// 4. Pseudo-random alternating letter+digit pattern like "A1B2C3D4..."
|
|
1118
|
+
// Real Google eventIds NEVER look like this — they have natural
|
|
1119
|
+
// base32-ish randomness, not human-readable patterns.
|
|
1120
|
+
if (/^[A-Z](?:\d[A-Z]){3,}/i.test(s)) return true;
|
|
1121
|
+
// 5. Almost-all-uppercase: Google eventIds are lowercase. UPPERCASE
|
|
1122
|
+
// is a model invention signature.
|
|
1123
|
+
const upper = (s.match(/[A-Z]/g) || []).length;
|
|
1124
|
+
const lower = (s.match(/[a-z]/g) || []).length;
|
|
1125
|
+
if (upper >= 3 && upper > lower) return true;
|
|
1126
|
+
return false;
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1094
1129
|
export async function executeTool(action, params, config) {
|
|
1095
1130
|
switch (action) {
|
|
1096
1131
|
// ── Gmail ──────────────────────────────────────────────────────────────
|
|
@@ -1634,14 +1669,10 @@ export async function executeTool(action, params, config) {
|
|
|
1634
1669
|
let eventId = String(params.eventId || '').trim();
|
|
1635
1670
|
if (!eventId) return 'eventId required. Call calendar_find or calendar_date first to get the REAL eventId.';
|
|
1636
1671
|
|
|
1637
|
-
// Reject obvious placeholder IDs (model copied from prompt examples
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
'eventid', 'event_id', 'id', 'null', 'undefined',
|
|
1642
|
-
]);
|
|
1643
|
-
if (PLACEHOLDERS.has(eventId.toLowerCase())) {
|
|
1644
|
-
return `"${eventId}" is a placeholder, not a real eventId. Call calendar_find or calendar_date FIRST to get real eventIds.`;
|
|
1672
|
+
// Reject obvious placeholder IDs (model copied from prompt examples or
|
|
1673
|
+
// emitted obvious patterns like "A1B2C3D4E5F6G7H8I9J0").
|
|
1674
|
+
if (isPlaceholderEventId(eventId)) {
|
|
1675
|
+
return `"${eventId}" looks invented (placeholder pattern). Call calendar_find or calendar_date FIRST to get real eventIds.`;
|
|
1645
1676
|
}
|
|
1646
1677
|
|
|
1647
1678
|
// Smart eventId resolution: if it looks like a name instead of a Google Calendar ID, search for it
|
|
@@ -1695,16 +1726,11 @@ export async function executeTool(action, params, config) {
|
|
|
1695
1726
|
let delEventId = String(params.eventId).trim();
|
|
1696
1727
|
|
|
1697
1728
|
// Reject placeholder IDs the model may have copied verbatim from prompt
|
|
1698
|
-
// examples or hallucinated wholesale.
|
|
1699
|
-
//
|
|
1700
|
-
//
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
'123', '456', 'foo', 'bar', 'baz', 'example', 'placeholder',
|
|
1704
|
-
'eventid', 'event_id', 'id', 'null', 'undefined',
|
|
1705
|
-
]);
|
|
1706
|
-
if (PLACEHOLDER_IDS.has(delEventId.toLowerCase())) {
|
|
1707
|
-
return `"${delEventId}" is a placeholder, not a real eventId. Call calendar_date(YYYY-MM-DD) or calendar_find(query) FIRST to get the real eventIds, then call calendar_delete with one of those values.`;
|
|
1729
|
+
// examples or hallucinated wholesale. Real Google Calendar eventIds
|
|
1730
|
+
// are long LOWERCASE alphanumeric strings — never UPPERCASE patterns
|
|
1731
|
+
// like "A1B2C3D4E5F6G7H8I9J0" (visibly invented).
|
|
1732
|
+
if (isPlaceholderEventId(delEventId)) {
|
|
1733
|
+
return `"${delEventId}" looks invented (placeholder pattern). Real Google Calendar eventIds are long lowercase alphanumeric strings (a-v + 0-9, often with - and _). Call calendar_date(YYYY-MM-DD) or calendar_find(query) FIRST to get the real eventIds, then call calendar_delete with one of those.`;
|
|
1708
1734
|
}
|
|
1709
1735
|
|
|
1710
1736
|
// Branch A — looks like a free-text search query (spaces, caps, very short).
|