nothumanallowed 14.1.26 → 14.1.28
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": "14.1.
|
|
3
|
+
"version": "14.1.28",
|
|
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 = '14.1.
|
|
8
|
+
export const VERSION = '14.1.28';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
package/src/services/llm.mjs
CHANGED
|
@@ -5,6 +5,63 @@
|
|
|
5
5
|
* Supports: Anthropic, OpenAI, Gemini, DeepSeek, Grok, Mistral, Cohere.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
// ── Qwen3 BPE artifact repair ─────────────────────────────────────────────
|
|
9
|
+
//
|
|
10
|
+
// Qwen3-32B running on vLLM produces text where Italian/English function words
|
|
11
|
+
// (articles, prepositions, conjunctions) are fused to adjacent content words
|
|
12
|
+
// due to BPE tokenizer subword merging. Examples:
|
|
13
|
+
// "lacorrelazione" → "la correlazione"
|
|
14
|
+
// "ilprezzodell'oro" → "il prezzo dell'oro"
|
|
15
|
+
// "deidati" → "dei dati"
|
|
16
|
+
// "nonesiste" → "non esiste"
|
|
17
|
+
//
|
|
18
|
+
// Strategy: insert a space before any known function word that immediately
|
|
19
|
+
// follows a lowercase letter (i.e. is fused mid-word). We run multiple
|
|
20
|
+
// passes because chains like "dellacorrelazione" need two separations.
|
|
21
|
+
// Table rows (lines starting with |) are intentionally skipped to avoid
|
|
22
|
+
// corrupting cell separators.
|
|
23
|
+
|
|
24
|
+
const IT_FUNCTION_WORDS = [
|
|
25
|
+
// Definite articles
|
|
26
|
+
'il','lo','la','i','gli','le',
|
|
27
|
+
// Indefinite articles
|
|
28
|
+
'un','uno','una',
|
|
29
|
+
// Prepositions + contractions
|
|
30
|
+
'di','del','dello','della','dei','degli','delle',
|
|
31
|
+
'a','al','allo','alla','ai','agli','alle',
|
|
32
|
+
'da','dal','dallo','dalla','dai','dagli','dalle',
|
|
33
|
+
'in','nel','nello','nella','nei','negli','nelle',
|
|
34
|
+
'su','sul','sullo','sulla','sui','sugli','sulle',
|
|
35
|
+
'con','col','per','tra','fra',
|
|
36
|
+
// Common conjunctions / adverbs that fuse
|
|
37
|
+
'che','non','ma','se','anche','come','dove','quando',
|
|
38
|
+
'perché','mentre','quindi','però','sia','né',
|
|
39
|
+
'questo','questa','questi','queste','quello','quella',
|
|
40
|
+
'e','o','è',
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
// Build a single regex that matches any of these words preceded by a lowercase letter
|
|
44
|
+
const BPE_SPLIT_RE = new RegExp(
|
|
45
|
+
'([a-zàèéìòù])(' + IT_FUNCTION_WORDS.map((w) => w.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|') + ')(?=[A-Za-zàèéìòù])',
|
|
46
|
+
'g',
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
function fixQwen3BPE(text) {
|
|
50
|
+
// Process line by line — skip table rows and code blocks
|
|
51
|
+
let inCode = false;
|
|
52
|
+
return text.split('\n').map((line) => {
|
|
53
|
+
if (line.trimStart().startsWith('```')) { inCode = !inCode; return line; }
|
|
54
|
+
if (inCode) return line;
|
|
55
|
+
if (line.trimStart().startsWith('|')) return line; // table row — untouched
|
|
56
|
+
// Three passes to handle chains
|
|
57
|
+
let out = line;
|
|
58
|
+
out = out.replace(BPE_SPLIT_RE, '$1 $2');
|
|
59
|
+
out = out.replace(BPE_SPLIT_RE, '$1 $2');
|
|
60
|
+
out = out.replace(BPE_SPLIT_RE, '$1 $2');
|
|
61
|
+
return out;
|
|
62
|
+
}).join('\n');
|
|
63
|
+
}
|
|
64
|
+
|
|
8
65
|
// ── Providers ──────────────────────────────────────────────────────────────
|
|
9
66
|
|
|
10
67
|
export async function callAnthropic(apiKey, model, systemPrompt, userMessage, stream = false, opts = {}) {
|
|
@@ -574,6 +631,13 @@ export async function callLLMStream(config, systemPrompt, userMessage, onToken,
|
|
|
574
631
|
let fullNhaText = nhaJson.choices?.[0]?.message?.content || '';
|
|
575
632
|
// Strip <think>...</think> blocks
|
|
576
633
|
fullNhaText = fullNhaText.replace(/<think>[\s\S]*?<\/think>/g, '').trim();
|
|
634
|
+
// Fix Qwen3 BPE tokenizer artifacts: words joined without spaces.
|
|
635
|
+
// Qwen3 streaming via vLLM occasionally produces subword tokens that arrive
|
|
636
|
+
// concatenated — e.g. "lacorrelazione" instead of "la correlazione",
|
|
637
|
+
// "ilprezzodell'oro" instead of "il prezzo dell'oro".
|
|
638
|
+
// We fix this by inserting spaces before Italian/English articles and
|
|
639
|
+
// prepositions that appear fused at word boundaries.
|
|
640
|
+
fullNhaText = fixQwen3BPE(fullNhaText);
|
|
577
641
|
if (onToken) onToken(fullNhaText);
|
|
578
642
|
return fullNhaText;
|
|
579
643
|
}
|