nothumanallowed 13.5.59 → 13.5.60
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/commands/ui.mjs +29 -1
- package/src/constants.mjs +1 -1
- package/src/services/web-ui.mjs +15 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "13.5.
|
|
3
|
+
"version": "13.5.60",
|
|
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/commands/ui.mjs
CHANGED
|
@@ -4632,12 +4632,40 @@ REGOLE CRITICHE:
|
|
|
4632
4632
|
}
|
|
4633
4633
|
|
|
4634
4634
|
// Parse and execute tool calls from response
|
|
4635
|
+
// Sanitize JSON from LLM: replace literal newlines inside JSON strings with \n
|
|
4636
|
+
// Models often write multiline strings without escaping, which breaks JSON.parse
|
|
4637
|
+
const sanitizeToolJson = (raw) => {
|
|
4638
|
+
// Replace literal CR/LF inside JSON string values with escaped versions
|
|
4639
|
+
// Strategy: walk char by char, track if we're inside a JSON string
|
|
4640
|
+
let out = '';
|
|
4641
|
+
let inStr = false;
|
|
4642
|
+
let escaped = false;
|
|
4643
|
+
for (let ci = 0; ci < raw.length; ci++) {
|
|
4644
|
+
const ch = raw[ci];
|
|
4645
|
+
if (escaped) { out += ch; escaped = false; continue; }
|
|
4646
|
+
if (ch === '\\') { out += ch; escaped = true; continue; }
|
|
4647
|
+
if (ch === '"') { inStr = !inStr; out += ch; continue; }
|
|
4648
|
+
if (inStr && (ch === '\n' || ch === '\r')) {
|
|
4649
|
+
out += ch === '\n' ? '\\n' : '\\r';
|
|
4650
|
+
continue;
|
|
4651
|
+
}
|
|
4652
|
+
out += ch;
|
|
4653
|
+
}
|
|
4654
|
+
return out;
|
|
4655
|
+
};
|
|
4656
|
+
|
|
4635
4657
|
const toolRegex = /<tool>([\s\S]*?)<\/tool>/g;
|
|
4636
4658
|
let toolMatch;
|
|
4637
4659
|
const toolResults = [];
|
|
4638
4660
|
while ((toolMatch = toolRegex.exec(fullResponse)) !== null) {
|
|
4639
4661
|
let toolCall;
|
|
4640
|
-
try {
|
|
4662
|
+
try {
|
|
4663
|
+
const raw = toolMatch[1].trim();
|
|
4664
|
+
toolCall = JSON.parse(sanitizeToolJson(raw));
|
|
4665
|
+
} catch(e) {
|
|
4666
|
+
sendEv({ type: 'tool', op: 'parse_error', path: '?', result: 'JSON malformato: ' + e.message.slice(0, 80) });
|
|
4667
|
+
continue;
|
|
4668
|
+
}
|
|
4641
4669
|
|
|
4642
4670
|
if (toolCall.op === 'read') {
|
|
4643
4671
|
const fp = path.join(sandboxDir, toolCall.path.replace(/^\/+/, ''));
|
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.60';
|
|
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/web-ui.mjs
CHANGED
|
@@ -6984,16 +6984,23 @@ function wcChatPanelHtml() {
|
|
|
6984
6984
|
}
|
|
6985
6985
|
} else {
|
|
6986
6986
|
var toolBadges = (msg.tools || []).map(function(tool){
|
|
6987
|
-
var
|
|
6988
|
-
var
|
|
6989
|
-
|
|
6987
|
+
var isOk = tool.result === 'ok';
|
|
6988
|
+
var isParseErr = tool.op === 'parse_error';
|
|
6989
|
+
var icon = isParseErr ? '❓' : (tool.op === 'edit' ? '✎' : (tool.op === 'write' ? '➕' : '👁'));
|
|
6990
|
+
var color = isOk ? 'var(--green)' : 'var(--red)';
|
|
6991
|
+
var label = isParseErr ? ('JSON err: ' + wcEsc(tool.result)) : wcEsc(tool.path);
|
|
6992
|
+
var title = isOk ? tool.op + ': ' + tool.path : (tool.result || '');
|
|
6993
|
+
return '<span title="'+wcEsc(title)+'" style="display:inline-flex;align-items:center;gap:3px;background:var(--bg3);border:1px solid '+(isOk?'var(--green3)':'var(--red)')+';border-radius:4px;padding:2px 6px;font-size:9px;font-family:var(--mono);color:'+color+'">' +
|
|
6994
|
+
icon + ' ' + label + '</span>';
|
|
6990
6995
|
}).join(' ');
|
|
6991
|
-
|
|
6992
|
-
|
|
6993
|
-
|
|
6996
|
+
var agentText = wcEsc(msg.text.replace(new RegExp('<tool>[\\s\\S]*?<\\/tool>', 'g'), '').trim());
|
|
6997
|
+
messagesHtml += '<div style="margin:6px 12px;border:1px solid rgba(255,255,255,0.12);border-radius:10px;background:var(--bg3);overflow:hidden">' +
|
|
6998
|
+
'<div style="display:flex;align-items:center;gap:6px;padding:6px 10px;border-bottom:1px solid rgba(255,255,255,0.06);background:rgba(255,255,255,0.03)">' +
|
|
6999
|
+
'<span style="font-size:13px">🤖</span>' +
|
|
7000
|
+
'<span style="font-size:10px;font-weight:700;color:var(--green)">WebCraft Agent</span>' +
|
|
6994
7001
|
'</div>' +
|
|
6995
|
-
'<div style="font-size:11px;color:var(--text);line-height:1.6;white-space:pre-wrap
|
|
6996
|
-
(toolBadges ? '<div style="display:flex;flex-wrap:wrap;gap:4px;
|
|
7002
|
+
'<div style="padding:8px 10px;font-size:11px;color:var(--text);line-height:1.6;white-space:pre-wrap">'+agentText+'</div>' +
|
|
7003
|
+
(toolBadges ? '<div style="display:flex;flex-wrap:wrap;gap:4px;padding:6px 10px;border-top:1px solid rgba(255,255,255,0.06)">'+toolBadges+'</div>' : '') +
|
|
6997
7004
|
'</div>';
|
|
6998
7005
|
}
|
|
6999
7006
|
}
|