nothumanallowed 13.2.13 → 13.2.15
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 +40 -24
- package/src/constants.mjs +1 -1
- package/src/services/web-ui.mjs +48 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "13.2.
|
|
3
|
+
"version": "13.2.15",
|
|
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
|
@@ -2745,10 +2745,8 @@ Respond with ONLY valid JSON, no markdown:
|
|
|
2745
2745
|
|
|
2746
2746
|
// ── Build system prompt with real tool data ───────────────────
|
|
2747
2747
|
const isCanvasAgent = agent === 'CanvasAgent';
|
|
2748
|
-
//
|
|
2749
|
-
const
|
|
2750
|
-
const isToolOutputAgent = ['CalendarAgent','EmailAgent','GitHubAgent','NotionAgent','SlackAgent'].includes(agent);
|
|
2751
|
-
const isPureAnalysis = isSynthesisAgent || isToolOutputAgent;
|
|
2748
|
+
// Tool-data agents: fetch real live data and use buildSystemPrompt (tool calls allowed)
|
|
2749
|
+
const isLiveDataAgent = ['CalendarAgent','EmailAgent','GitHubAgent','NotionAgent','SlackAgent','DriveAgent','BrowserAgent','WebSearchAgent','ResearchAgent'].includes(agent);
|
|
2752
2750
|
|
|
2753
2751
|
const canvasSystemPrompt = `You are an HTML report generator. Output a single complete HTML document. No preamble, no explanation.
|
|
2754
2752
|
RULES:
|
|
@@ -2763,33 +2761,38 @@ RULES:
|
|
|
2763
2761
|
if (isCanvasAgent) {
|
|
2764
2762
|
sysPrompt = canvasSystemPrompt;
|
|
2765
2763
|
userMsg = `Generate a beautiful HTML dashboard report for this content. Start immediately with <!DOCTYPE html>:\n\n${context.slice(0, 8000)}`;
|
|
2766
|
-
} else if (
|
|
2767
|
-
//
|
|
2768
|
-
const today = new Date().toISOString().split('T')[0];
|
|
2769
|
-
const language = config?.language || 'Italian';
|
|
2770
|
-
sysPrompt = `You are ${agent}, a specialist AI agent inside NHA Studio. Today is ${today}. Respond in ${language}.
|
|
2771
|
-
Task: ${stepPrompt}
|
|
2772
|
-
${toolData ? `\n## LIVE DATA:\n${toolData.slice(0, 4000)}\n` : ''}
|
|
2773
|
-
${context ? `\n## CONTEXT FROM PREVIOUS STEPS:\n${context.slice(0, 5000)}\n` : ''}
|
|
2774
|
-
Write your full response in plain prose. Do NOT output JSON, tool calls, or code blocks unless explicitly asked. Use the context and data above — do not ask for more information.`;
|
|
2775
|
-
userMsg = toolData
|
|
2776
|
-
? `Use the live data and context above to complete: ${stepPrompt}`
|
|
2777
|
-
: context
|
|
2778
|
-
? `Based on the context above, complete: ${stepPrompt}`
|
|
2779
|
-
: stepPrompt;
|
|
2780
|
-
} else {
|
|
2764
|
+
} else if (isLiveDataAgent) {
|
|
2765
|
+
// These agents fetched real data — use buildSystemPrompt so they can call tools too
|
|
2781
2766
|
const agentInstruction = `You are ${agent}, a specialist AI agent inside NHA Studio.\nYour task: ${stepPrompt}\n` +
|
|
2782
2767
|
(toolData ? `\n## DATA FROM TOOLS:\n${toolData.slice(0, 4000)}\n` : '') +
|
|
2783
2768
|
(context ? `\n## OUTPUT FROM PREVIOUS AGENTS:\n${context.slice(0, 3000)}\n` : '') +
|
|
2784
|
-
|
|
2785
|
-
? '\nWrite your analysis in plain text. Do NOT output JSON, tool calls, or code blocks. Use the context above.'
|
|
2786
|
-
: '\nOutput your result directly. No preamble.');
|
|
2769
|
+
'\nWrite your analysis in plain text. Do NOT output JSON, tool calls, or code blocks. Summarize the data clearly.';
|
|
2787
2770
|
sysPrompt = buildSystemPrompt(agent, agentInstruction, config);
|
|
2788
2771
|
userMsg = toolData
|
|
2789
|
-
? `
|
|
2772
|
+
? `Summarize the data above for: ${stepPrompt}`
|
|
2790
2773
|
: context
|
|
2791
2774
|
? `Based on the previous output, complete: ${stepPrompt}`
|
|
2792
2775
|
: stepPrompt;
|
|
2776
|
+
} else {
|
|
2777
|
+
// All other agents (WriterAgent, DataAnalystAgent, specialist agents, etc.)
|
|
2778
|
+
// Use a focused prompt with NO TOOL_DEFINITIONS to prevent JSON/tool-call output
|
|
2779
|
+
const today = new Date().toISOString().split('T')[0];
|
|
2780
|
+
const language = config?.language || 'Italian';
|
|
2781
|
+
sysPrompt = `You are ${agent}, a specialist AI agent inside NHA Studio. Today is ${today}. Respond in ${language}.
|
|
2782
|
+
|
|
2783
|
+
CRITICAL RULES:
|
|
2784
|
+
- Do NOT output JSON, tool calls, function calls, or code blocks
|
|
2785
|
+
- Do NOT ask for more information — use only the data provided below
|
|
2786
|
+
- Write in plain prose, structured with headers and bullet points where appropriate
|
|
2787
|
+
- Be thorough and specific — this is for an executive briefing
|
|
2788
|
+
|
|
2789
|
+
${toolData ? `## LIVE DATA:\n${toolData.slice(0, 4000)}\n` : ''}
|
|
2790
|
+
${context ? `## CONTEXT FROM PREVIOUS AGENTS:\n${context.slice(0, 5000)}\n` : ''}`;
|
|
2791
|
+
userMsg = toolData
|
|
2792
|
+
? `Use the live data and context above to complete this task: ${stepPrompt}`
|
|
2793
|
+
: context
|
|
2794
|
+
? `Using the context from previous steps, complete this task: ${stepPrompt}`
|
|
2795
|
+
: stepPrompt;
|
|
2793
2796
|
}
|
|
2794
2797
|
|
|
2795
2798
|
// ── Stream LLM response ───────────────────────────────────────
|
|
@@ -2798,7 +2801,14 @@ Write your full response in plain prose. Do NOT output JSON, tool calls, or code
|
|
|
2798
2801
|
try {
|
|
2799
2802
|
await withTimeout(
|
|
2800
2803
|
callLLMStream(config, sysPrompt, userMsg,
|
|
2801
|
-
(token) => {
|
|
2804
|
+
(token) => {
|
|
2805
|
+
fullOutput += token;
|
|
2806
|
+
if (!isCanvasAgent) {
|
|
2807
|
+
// Strip JSON tool calls from synthesis agent output before sending to client
|
|
2808
|
+
const stripped = token.replace(/\{[\s\S]*?"action"[\s\S]*?\}/g, '').trim();
|
|
2809
|
+
if (stripped) sendToken(stripped);
|
|
2810
|
+
}
|
|
2811
|
+
},
|
|
2802
2812
|
),
|
|
2803
2813
|
isCanvasAgent ? 60000 : 35000
|
|
2804
2814
|
);
|
|
@@ -2806,6 +2816,12 @@ Write your full response in plain prose. Do NOT output JSON, tool calls, or code
|
|
|
2806
2816
|
if (!isCanvasAgent) sendToken(`[Error: ${e.message}]`);
|
|
2807
2817
|
}
|
|
2808
2818
|
|
|
2819
|
+
// Fallback: if LLM returned empty and we have tool data, send that directly
|
|
2820
|
+
if (!isCanvasAgent && !fullOutput.trim() && toolData) {
|
|
2821
|
+
fullOutput = toolData;
|
|
2822
|
+
sendToken(toolData.slice(0, 2000));
|
|
2823
|
+
}
|
|
2824
|
+
|
|
2809
2825
|
if (isCanvasAgent) {
|
|
2810
2826
|
let html = fullOutput.trim();
|
|
2811
2827
|
// Strip thinking tags if not already filtered
|
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.2.
|
|
8
|
+
export const VERSION = '13.2.15';
|
|
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
|
@@ -2715,6 +2715,24 @@ var studioState = {
|
|
|
2715
2715
|
planned: false
|
|
2716
2716
|
};
|
|
2717
2717
|
|
|
2718
|
+
function studioReset() {
|
|
2719
|
+
if (studioState.running) return;
|
|
2720
|
+
studioState.task = '';
|
|
2721
|
+
studioState.nodes = [];
|
|
2722
|
+
studioState.log = [];
|
|
2723
|
+
studioState.result = '';
|
|
2724
|
+
studioState.running = false;
|
|
2725
|
+
studioState.planned = false;
|
|
2726
|
+
studioTokens = {in:0, out:0};
|
|
2727
|
+
var ta = document.getElementById('studioTaskInput');
|
|
2728
|
+
if (ta) ta.value = '';
|
|
2729
|
+
var tb = document.getElementById('studioTokenBar');
|
|
2730
|
+
if (tb) tb.textContent = '';
|
|
2731
|
+
renderStudioNodes();
|
|
2732
|
+
renderStudioLog();
|
|
2733
|
+
renderStudioResult();
|
|
2734
|
+
}
|
|
2735
|
+
|
|
2718
2736
|
var STUDIO_EXAMPLES = [
|
|
2719
2737
|
'Analyze my unread emails and create a priority action plan',
|
|
2720
2738
|
'Search the web for AI news today and summarize it in a canvas report',
|
|
@@ -2748,18 +2766,25 @@ function renderStudioNodes() {
|
|
|
2748
2766
|
else if (n.status === 'done') cls += ' studio-node--done';
|
|
2749
2767
|
else if (n.status === 'error') cls += ' studio-node--error';
|
|
2750
2768
|
var statusLabel = {waiting:'◯ wait', running:'▶ running', done:'✓ done', error:'✕ error'}[n.status] || '';
|
|
2751
|
-
|
|
2769
|
+
// Only animate nodes that haven't been rendered yet (first appearance)
|
|
2770
|
+
var style = n._rendered ? '' : 'animation-delay:' + (i * 110) + 'ms';
|
|
2771
|
+
html += '<div class="' + cls + '" style="' + style + '">';
|
|
2752
2772
|
html += '<div class="studio-node__circle">' + n.icon + '</div>';
|
|
2753
2773
|
html += '<div class="studio-node__label">' + esc(n.label) + '</div>';
|
|
2754
2774
|
html += '<div class="studio-node__status studio-node__status--' + n.status + '">' + statusLabel + '</div>';
|
|
2775
|
+
if (n.status === 'running') {
|
|
2776
|
+
html += '<div class="studio-node__progress"><span></span><span></span><span></span></div>';
|
|
2777
|
+
}
|
|
2755
2778
|
html += '</div>';
|
|
2756
2779
|
if (i < studioState.nodes.length - 1) {
|
|
2757
2780
|
var next = studioState.nodes[i + 1];
|
|
2758
2781
|
var arrowCls = 'studio-arrow';
|
|
2759
2782
|
if (n.status === 'done' && next.status === 'running') arrowCls += ' studio-arrow--active';
|
|
2760
2783
|
else if (n.status === 'done') arrowCls += ' studio-arrow--done';
|
|
2761
|
-
|
|
2784
|
+
var arrowStyle = n._rendered ? '' : 'opacity:0;animation:stNodeIn .3s ease ' + (i * 110 + 55) + 'ms forwards';
|
|
2785
|
+
html += '<div class="' + arrowCls + '" style="' + arrowStyle + '">→</div>';
|
|
2762
2786
|
}
|
|
2787
|
+
n._rendered = true;
|
|
2763
2788
|
});
|
|
2764
2789
|
html += '</div>';
|
|
2765
2790
|
el.innerHTML = html;
|
|
@@ -2914,7 +2939,8 @@ function renderStudioSessionsBar() {
|
|
|
2914
2939
|
if (!sessions.length) { el.style.display = 'none'; return; }
|
|
2915
2940
|
el.style.display = 'block';
|
|
2916
2941
|
el.innerHTML = '<div style="font-size:10px;color:var(--dim);margin-bottom:8px;text-transform:uppercase;letter-spacing:1px">Recent sessions</div>' +
|
|
2917
|
-
|
|
2942
|
+
'<div style="max-height:220px;overflow-y:auto;padding-right:4px">' +
|
|
2943
|
+
sessions.map(function(s,i) {
|
|
2918
2944
|
return '<div class="studio-session-item">' +
|
|
2919
2945
|
'<div style="display:flex;align-items:center;justify-content:space-between;gap:8px">' +
|
|
2920
2946
|
'<span class="studio-session-task">' + esc(s.task.slice(0,60)) + (s.task.length>60?'...':'') + '</span>' +
|
|
@@ -2926,7 +2952,7 @@ function renderStudioSessionsBar() {
|
|
|
2926
2952
|
'<button onclick="deleteStudioSession('+i+')" style="font-size:10px;padding:3px 8px;background:none;border:none;color:var(--dim);cursor:pointer">×</button>' +
|
|
2927
2953
|
'</div>' +
|
|
2928
2954
|
'</div>';
|
|
2929
|
-
}).join('');
|
|
2955
|
+
}).join('') + '</div>';
|
|
2930
2956
|
}
|
|
2931
2957
|
|
|
2932
2958
|
function restoreStudioSession(idx) {
|
|
@@ -3031,6 +3057,8 @@ function runStudioStep(idx, node, task, context, stepDef) {
|
|
|
3031
3057
|
var ct2 = document.getElementById('canvasTitle');
|
|
3032
3058
|
if (ct2) ct2.textContent = 'Studio Report';
|
|
3033
3059
|
}
|
|
3060
|
+
var scb = document.getElementById('studioCanvasBtn');
|
|
3061
|
+
if (scb) scb.style.display = '';
|
|
3034
3062
|
}
|
|
3035
3063
|
if (ev.usage) { studioAddTokens(ev.usage.input||0, ev.usage.output||0); }
|
|
3036
3064
|
if (ev.done) { resolve({output: output || '(no output)', canvas: canvasHtml}); return; }
|
|
@@ -3148,7 +3176,10 @@ function renderStudio(el) {
|
|
|
3148
3176
|
'</div>' +
|
|
3149
3177
|
'<div class="studio-input-row">' +
|
|
3150
3178
|
'<textarea id="studioTaskInput" placeholder="Describe what you want to accomplish... (Ctrl+Enter to run)" onkeydown="if(event.key===\\x27Enter\\x27&&(event.ctrlKey||event.metaKey)){runStudio();event.preventDefault()}">' + esc(studioState.task) + '</textarea>' +
|
|
3151
|
-
'<
|
|
3179
|
+
'<div style="display:flex;gap:6px">' +
|
|
3180
|
+
'<button id="studioRunBtn" class="studio-run-btn" onclick="runStudio()" style="flex:1" ' + (studioState.running ? 'disabled' : '') + '>▶ Run</button>' +
|
|
3181
|
+
'<button onclick="studioReset()" title="New workflow" style="padding:8px 12px;background:none;border:1px solid var(--border);border-radius:8px;color:var(--dim);cursor:pointer;font-size:16px;line-height:1" ' + (studioState.running ? 'disabled' : '') + '>↻</button>' +
|
|
3182
|
+
'</div>' +
|
|
3152
3183
|
'</div>' +
|
|
3153
3184
|
'</div>' +
|
|
3154
3185
|
|
|
@@ -3166,7 +3197,10 @@ function renderStudio(el) {
|
|
|
3166
3197
|
'</div>' +
|
|
3167
3198
|
'</div>' +
|
|
3168
3199
|
|
|
3169
|
-
'<div
|
|
3200
|
+
'<div style="display:flex;align-items:center;gap:8px;margin:8px 0">' +
|
|
3201
|
+
'<div id="studioTokenBar" style="font-size:10px;color:var(--dim);font-family:var(--mono);flex:1"></div>' +
|
|
3202
|
+
'<button id="studioCanvasBtn" onclick="var p=document.getElementById(\\x27canvasPanel\\x27);if(p)p.classList.add(\\x27open\\x27)" style="display:none;font-size:10px;padding:3px 9px;background:none;border:1px solid var(--green3);border-radius:5px;color:var(--green);cursor:pointer;font-family:var(--mono)">■ Open Canvas</button>' +
|
|
3203
|
+
'</div>' +
|
|
3170
3204
|
'<div class="studio-canvas" id="studioNodes"></div>' +
|
|
3171
3205
|
'<div class="studio-log" id="studioLog" style="display:none"></div>' +
|
|
3172
3206
|
'<div id="studioResult"></div>' +
|
|
@@ -3678,9 +3712,15 @@ input:focus,textarea:focus{border-color:var(--green3)}
|
|
|
3678
3712
|
.studio-canvas__empty{display:flex;align-items:center;justify-content:center;height:180px;color:var(--dim);font-size:11px;flex-direction:column;gap:8px}
|
|
3679
3713
|
.studio-canvas__empty-icon{font-size:32px;opacity:.3}
|
|
3680
3714
|
.studio-nodes{display:flex;align-items:center;gap:0;padding:28px 24px;overflow-x:auto;min-height:130px;background:var(--bg2);border-radius:10px;border:1px solid var(--border);margin-bottom:16px}
|
|
3681
|
-
.studio-node{position:relative;display:flex;flex-direction:column;align-items:center;gap:7px;min-width:106px;max-width:126px}
|
|
3715
|
+
.studio-node{position:relative;display:flex;flex-direction:column;align-items:center;gap:7px;min-width:106px;max-width:126px;opacity:0;animation:stNodeIn .35s ease forwards}
|
|
3716
|
+
@keyframes stNodeIn{from{opacity:0;transform:translateY(10px) scale(.92)}to{opacity:1;transform:translateY(0) scale(1)}}
|
|
3682
3717
|
.studio-node__circle{width:56px;height:56px;border-radius:14px;border:1.5px solid var(--border2);background:var(--bg3);display:flex;align-items:center;justify-content:center;font-size:22px;transition:all .35s;flex-shrink:0}
|
|
3683
|
-
.studio-
|
|
3718
|
+
.studio-node__progress{display:flex;gap:4px;align-items:center;margin-top:2px}
|
|
3719
|
+
.studio-node__progress span{width:5px;height:5px;border-radius:50%;background:var(--green3);animation:stDot 1.1s ease-in-out infinite}
|
|
3720
|
+
.studio-node__progress span:nth-child(2){animation-delay:.18s}
|
|
3721
|
+
.studio-node__progress span:nth-child(3){animation-delay:.36s}
|
|
3722
|
+
@keyframes stDot{0%,80%,100%{opacity:.2;transform:scale(.7)}40%{opacity:1;transform:scale(1)}}
|
|
3723
|
+
.studio-node--active .studio-node__circle{border-color:var(--green3);box-shadow:0 0 0 6px rgba(99,102,241,.18),0 0 20px rgba(99,102,241,.25);background:var(--greendim);animation:stRing 1.6s ease-out infinite}
|
|
3684
3724
|
.studio-node--done .studio-node__circle{border-color:#22c55e;background:rgba(34,197,94,.08);box-shadow:0 0 0 3px rgba(34,197,94,.12)}
|
|
3685
3725
|
.studio-node--error .studio-node__circle{border-color:var(--red);background:rgba(239,68,68,.07)}
|
|
3686
3726
|
.studio-node__label{font-size:10px;color:var(--dim);text-align:center;line-height:1.3;max-width:110px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500}
|