nothumanallowed 13.5.82 → 13.5.84

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": "13.5.82",
3
+ "version": "13.5.84",
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": {
@@ -266,7 +266,7 @@ export async function callNHA(apiKey, model, systemPrompt, userMessage, stream =
266
266
 
267
267
  const body = {
268
268
  model: model || '/opt/models/qwen3-32b',
269
- max_tokens: thinkingEnabled ? 8192 : 4096,
269
+ max_tokens: thinkingEnabled ? 16384 : 8192,
270
270
  messages: [
271
271
  { role: 'system', content: sanitizeForSentinel(systemPrompt) },
272
272
  { role: 'user', content: sanitizeForSentinel(userMessage) },
@@ -6527,7 +6527,8 @@ var wcState = {
6527
6527
  dir: null,
6528
6528
  logs: [],
6529
6529
  error: null
6530
- }
6530
+ },
6531
+ lastGenStats: null
6531
6532
  };
6532
6533
  var wcRightTab = 'files';
6533
6534
  var wcMainTab = 'new'; // 'new' | 'projects'
@@ -6661,7 +6662,13 @@ function renderWebCraft(el) {
6661
6662
  '<button onclick="wcToggleGrep()" title="Cerca nel codice" style="padding:9px 10px;background:'+(_wcGrepOpen?'var(--greendim)':'var(--bg3)')+';border:1px solid '+(_wcGrepOpen?'var(--green3)':'var(--border2)')+';border-radius:8px;color:'+(_wcGrepOpen?'var(--green)':'var(--dim)')+';font-size:11px;cursor:pointer">&#128269;</button>' +
6662
6663
  '<button onclick="wcManualSnapshot()" title="Salva snapshot" style="padding:9px 10px;background:var(--bg3);border:1px solid var(--border2);border-radius:8px;color:var(--dim);font-size:11px;cursor:pointer">&#128190;</button>' +
6663
6664
  '</div>' +
6664
- '<button onclick="wcStartSandbox()" id="wcSandboxBtn" style="width:100%;padding:10px;background:var(--bg3);border:1px solid var(--green3);border-radius:8px;color:var(--green);font-size:12px;font-weight:600;cursor:pointer">&#9654; '+t('wc_sandbox_start')+'</button>'
6665
+ '<button onclick="wcStartSandbox()" id="wcSandboxBtn" style="width:100%;padding:10px;background:var(--bg3);border:1px solid var(--green3);border-radius:8px;color:var(--green);font-size:12px;font-weight:600;cursor:pointer">&#9654; '+t('wc_sandbox_start')+'</button>' +
6666
+ (wcState.lastGenStats ? '<div style="padding:6px 8px;background:var(--bg3);border:1px solid var(--border);border-radius:6px;font-size:10px;color:var(--dim);font-family:var(--mono);display:flex;flex-wrap:wrap;gap:6px">' +
6667
+ '<span>&#9201; '+(wcState.lastGenStats.seconds >= 60 ? Math.floor(wcState.lastGenStats.seconds/60)+'m '+(wcState.lastGenStats.seconds%60)+'s' : wcState.lastGenStats.seconds+'s')+'</span>' +
6668
+ '<span>&#8679; '+wcState.lastGenStats.tokIn.toLocaleString()+' tok in</span>' +
6669
+ '<span>&#8681; '+wcState.lastGenStats.tokOut.toLocaleString()+' tok out</span>' +
6670
+ '<span>&#128196; '+wcState.lastGenStats.files+' file</span>' +
6671
+ '</div>' : '')
6665
6672
  : '') +
6666
6673
  '</div>' +
6667
6674
  '<div data-wc-files style="position:relative;flex:1;min-width:0;background:var(--bg2);border:1px solid var(--border);border-radius:10px;display:flex;flex-direction:column;height:100%;overflow:hidden">' +
@@ -7870,11 +7877,35 @@ async function wcGenerate() {
7870
7877
  var _nl = String.fromCharCode(10);
7871
7878
  var sysPreamble = 'You are an expert full-stack engineer generating production-quality code.' + _nl + _nl + 'SECURITY RULES (non-negotiable):' + _nl + SECURITY_RULES + _nl + _nl + 'Project: ' + projName + _nl + 'Description: ' + desc + _nl + 'Enabled blocks: ' + blocksEnabled + _nl + _nl + 'Generate ONLY the file content requested. No explanations, no markdown code fences, no comments like "here is the file". Output raw file content only.';
7872
7879
 
7880
+ var _wcGenStartTime = Date.now();
7881
+ var _wcTokIn = 0, _wcTokOut = 0;
7882
+ var _wcTimerInterval = null;
7883
+
7884
+ function wcGenElapsed() {
7885
+ var s = Math.floor((Date.now() - _wcGenStartTime) / 1000);
7886
+ var m = Math.floor(s / 60); s = s % 60;
7887
+ return (m > 0 ? m + 'm ' : '') + s + 's';
7888
+ }
7889
+
7890
+ function wcStartGenTimer() {
7891
+ if (_wcTimerInterval) clearInterval(_wcTimerInterval);
7892
+ _wcTimerInterval = setInterval(function() {
7893
+ if (!wcState.running) { clearInterval(_wcTimerInterval); _wcTimerInterval = null; return; }
7894
+ wcUpdateGenOverlay(_wcGenOverlayState.fi, _wcGenOverlayState.total, _wcGenOverlayState.name);
7895
+ }, 1000);
7896
+ }
7897
+
7898
+ var _wcGenOverlayState = { fi: 0, total: 0, name: '' };
7899
+
7873
7900
  function wcUpdateGenOverlay(fi2, total, name) {
7874
- if (_wcOverlayMinimized) return; // don't touch minimized pill
7901
+ _wcGenOverlayState = { fi: fi2, total: total, name: name };
7902
+ if (_wcOverlayMinimized) return;
7875
7903
  var ov = document.getElementById('wcGenOverlay');
7876
7904
  if (!ov) return;
7877
7905
  var pct = Math.round((fi2 / total) * 100);
7906
+ var tokLabel = (_wcTokIn + _wcTokOut) > 0
7907
+ ? '<div style="font-size:10px;color:var(--dim);margin-top:4px;font-family:var(--mono)">&#8679;' + _wcTokIn.toLocaleString() + ' &#8681;' + _wcTokOut.toLocaleString() + ' tok</div>'
7908
+ : '';
7878
7909
  ov.innerHTML =
7879
7910
  '<div style="font-size:38px;animation:wcRobotBob 1s ease-in-out infinite">&#129302;</div>' +
7880
7911
  '<div style="font-size:13px;font-weight:700;color:var(--green);margin-top:12px">Generazione in corso...</div>' +
@@ -7883,11 +7914,12 @@ async function wcGenerate() {
7883
7914
  '<div style="width:220px;height:4px;background:rgba(255,255,255,0.1);border-radius:2px;overflow:hidden;margin-top:12px">' +
7884
7915
  '<div style="height:100%;width:'+pct+'%;background:var(--green);border-radius:2px;transition:width .4s ease;animation:wcBarPulse 1.5s ease-in-out infinite"></div>' +
7885
7916
  '</div>' +
7886
- '<div style="font-size:10px;color:var(--dim);margin-top:6px">'+fi2+' / '+total+' file</div>' +
7917
+ '<div style="font-size:10px;color:var(--dim);margin-top:6px">'+fi2+' / '+total+' file &nbsp;&#183;&nbsp; '+wcGenElapsed()+'</div>' +
7918
+ tokLabel +
7887
7919
  '<div style="display:flex;gap:4px;margin-top:10px">'+[0,1,2,3,4].map(function(_,idx){ return '<div style="width:6px;height:6px;border-radius:50%;background:var(--green);animation:wcDot 1.1s ease-in-out infinite '+(idx*0.14)+'s"></div>'; }).join('')+'</div>';
7888
7920
  }
7889
7921
 
7890
- // Helper: generate one file, returns {ok, content} or {ok:false, err}
7922
+ // Helper: generate one file
7891
7923
  async function wcGenOneFile(fp, signal) {
7892
7924
  var _nl2 = String.fromCharCode(10);
7893
7925
  var content = await wcCallLLM(sysPreamble, fp.prompt + _nl2 + _nl2 + 'File to generate: ' + fp.name, signal, fp.lang);
@@ -7898,6 +7930,8 @@ async function wcGenerate() {
7898
7930
  return wcLines.join(_nl2).trim();
7899
7931
  }
7900
7932
 
7933
+ wcStartGenTimer();
7934
+
7901
7935
  for (var fi = 0; fi < filePlan.length; fi++) {
7902
7936
  var fp = filePlan[fi];
7903
7937
  wcUpdateGenOverlay(fi, filePlan.length, fp.name);
@@ -7998,9 +8032,14 @@ async function wcGenerate() {
7998
8032
  }
7999
8033
  }
8000
8034
 
8035
+ if (_wcTimerInterval) { clearInterval(_wcTimerInterval); _wcTimerInterval = null; }
8036
+ var _wcGenTotalTime = Math.floor((Date.now() - _wcGenStartTime) / 1000);
8037
+
8001
8038
  wcState.running = false;
8002
8039
  _wcGenAbortCtrl = null;
8003
8040
  _wcOverlayMinimized = false;
8041
+ // Store final stats for display after generation
8042
+ wcState.lastGenStats = { tokIn: _wcTokIn, tokOut: _wcTokOut, seconds: _wcGenTotalTime, files: wcState.generatedFiles.length };
8004
8043
 
8005
8044
  // Auto-save project to ~/.nha/webcraft/<projectName>/
8006
8045
  try {
@@ -8084,7 +8123,7 @@ async function wcCallLLMRaw(sys, user, signal) {
8084
8123
  var fetchOpts = {
8085
8124
  method: 'POST',
8086
8125
  headers: {'Content-Type':'application/json'},
8087
- body: JSON.stringify({system: sys, user: user, max_tokens: 4096})
8126
+ body: JSON.stringify({system: sys, user: user, max_tokens: 8192})
8088
8127
  };
8089
8128
  if (signal) fetchOpts.signal = signal;
8090
8129
  for (var attempt = 0; attempt < 3; attempt++) {
@@ -8092,6 +8131,15 @@ async function wcCallLLMRaw(sys, user, signal) {
8092
8131
  var r = await fetch(API + '/api/studio/webcraft', fetchOpts);
8093
8132
  if (r.ok) {
8094
8133
  var d = await r.json();
8134
+ // Accumulate token counts if the server returns usage data
8135
+ if (d && d.usage) {
8136
+ if (typeof _wcTokIn !== 'undefined') _wcTokIn += (d.usage.prompt_tokens || d.usage.input_tokens || 0);
8137
+ if (typeof _wcTokOut !== 'undefined') _wcTokOut += (d.usage.completion_tokens || d.usage.output_tokens || 0);
8138
+ } else if (d && d.text) {
8139
+ // Estimate from char count (4 chars ≈ 1 token)
8140
+ if (typeof _wcTokIn !== 'undefined') _wcTokIn += Math.round((sys.length + user.length) / 4);
8141
+ if (typeof _wcTokOut !== 'undefined') _wcTokOut += Math.round((d.text || '').length / 4);
8142
+ }
8095
8143
  return (d && (d.text || d.content || d.result)) || '';
8096
8144
  }
8097
8145
  if (r.status < 500 || attempt === 2) {