nothumanallowed 13.5.90 → 13.5.92

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.90",
3
+ "version": "13.5.92",
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": {
@@ -3856,7 +3856,7 @@ ${completedHeadings ? `## SECTIONS ALREADY WRITTEN (headings only):\n${completed
3856
3856
  return;
3857
3857
  }
3858
3858
  try {
3859
- const result = await callLLM(config, body.system, body.user, { max_tokens: body.max_tokens || 4096 });
3859
+ const result = await callLLM(config, body.system, body.user, { max_tokens: body.max_tokens || 8192, temperature: 0.15 });
3860
3860
  sendJSON(res, 200, { text: result });
3861
3861
  } catch (e) {
3862
3862
  sendJSON(res, 500, { error: e.message });
@@ -7,14 +7,15 @@
7
7
 
8
8
  // ── Providers ──────────────────────────────────────────────────────────────
9
9
 
10
- export async function callAnthropic(apiKey, model, systemPrompt, userMessage, stream = false) {
10
+ export async function callAnthropic(apiKey, model, systemPrompt, userMessage, stream = false, opts = {}) {
11
11
  const body = {
12
12
  model: model || 'claude-sonnet-4-20250514',
13
- max_tokens: 8192,
13
+ max_tokens: opts.max_tokens || 8192,
14
14
  system: systemPrompt,
15
15
  messages: [{ role: 'user', content: userMessage }],
16
16
  stream,
17
17
  };
18
+ if (opts.temperature !== undefined) body.temperature = opts.temperature;
18
19
  const res = await fetch('https://api.anthropic.com/v1/messages', {
19
20
  method: 'POST',
20
21
  headers: {
@@ -33,16 +34,17 @@ export async function callAnthropic(apiKey, model, systemPrompt, userMessage, st
33
34
  return data.content?.[0]?.text || '';
34
35
  }
35
36
 
36
- export async function callOpenAI(apiKey, model, systemPrompt, userMessage, stream = false) {
37
+ export async function callOpenAI(apiKey, model, systemPrompt, userMessage, stream = false, opts = {}) {
37
38
  const body = {
38
39
  model: model || 'gpt-4o',
39
- max_tokens: 8192,
40
+ max_tokens: opts.max_tokens || 8192,
40
41
  messages: [
41
42
  { role: 'system', content: systemPrompt },
42
43
  { role: 'user', content: userMessage },
43
44
  ],
44
45
  stream,
45
46
  };
47
+ if (opts.temperature !== undefined) body.temperature = opts.temperature;
46
48
  const res = await fetch('https://api.openai.com/v1/chat/completions', {
47
49
  method: 'POST',
48
50
  headers: {
@@ -60,13 +62,15 @@ export async function callOpenAI(apiKey, model, systemPrompt, userMessage, strea
60
62
  return data.choices?.[0]?.message?.content || '';
61
63
  }
62
64
 
63
- export async function callGemini(apiKey, model, systemPrompt, userMessage, _stream = false) {
65
+ export async function callGemini(apiKey, model, systemPrompt, userMessage, _stream = false, opts = {}) {
64
66
  const m = model || 'gemini-2.5-pro-preview-05-06';
65
67
  const url = `https://generativelanguage.googleapis.com/v1beta/models/${m}:generateContent?key=${apiKey}`;
68
+ const generationConfig = { maxOutputTokens: opts.max_tokens || 8192 };
69
+ if (opts.temperature !== undefined) generationConfig.temperature = opts.temperature;
66
70
  const body = {
67
71
  system_instruction: { parts: [{ text: systemPrompt }] },
68
72
  contents: [{ parts: [{ text: userMessage }] }],
69
- generationConfig: { maxOutputTokens: 8192 },
73
+ generationConfig,
70
74
  };
71
75
  const res = await fetch(url, {
72
76
  method: 'POST',
@@ -81,16 +85,17 @@ export async function callGemini(apiKey, model, systemPrompt, userMessage, _stre
81
85
  return data.candidates?.[0]?.content?.parts?.[0]?.text || '';
82
86
  }
83
87
 
84
- export async function callDeepSeek(apiKey, model, systemPrompt, userMessage, stream = false) {
88
+ export async function callDeepSeek(apiKey, model, systemPrompt, userMessage, stream = false, opts = {}) {
85
89
  const body = {
86
90
  model: model || 'deepseek-chat',
87
- max_tokens: 8192,
91
+ max_tokens: opts.max_tokens || 8192,
88
92
  messages: [
89
93
  { role: 'system', content: systemPrompt },
90
94
  { role: 'user', content: userMessage },
91
95
  ],
92
96
  stream,
93
97
  };
98
+ if (opts.temperature !== undefined) body.temperature = opts.temperature;
94
99
  const res = await fetch('https://api.deepseek.com/v1/chat/completions', {
95
100
  method: 'POST',
96
101
  headers: {
@@ -108,16 +113,17 @@ export async function callDeepSeek(apiKey, model, systemPrompt, userMessage, str
108
113
  return data.choices?.[0]?.message?.content || '';
109
114
  }
110
115
 
111
- export async function callGrok(apiKey, model, systemPrompt, userMessage, stream = false) {
116
+ export async function callGrok(apiKey, model, systemPrompt, userMessage, stream = false, opts = {}) {
112
117
  const body = {
113
118
  model: model || 'grok-3-latest',
114
- max_tokens: 8192,
119
+ max_tokens: opts.max_tokens || 8192,
115
120
  messages: [
116
121
  { role: 'system', content: systemPrompt },
117
122
  { role: 'user', content: userMessage },
118
123
  ],
119
124
  stream,
120
125
  };
126
+ if (opts.temperature !== undefined) body.temperature = opts.temperature;
121
127
  const res = await fetch('https://api.x.ai/v1/chat/completions', {
122
128
  method: 'POST',
123
129
  headers: {
@@ -135,16 +141,17 @@ export async function callGrok(apiKey, model, systemPrompt, userMessage, stream
135
141
  return data.choices?.[0]?.message?.content || '';
136
142
  }
137
143
 
138
- export async function callMistral(apiKey, model, systemPrompt, userMessage, stream = false) {
144
+ export async function callMistral(apiKey, model, systemPrompt, userMessage, stream = false, opts = {}) {
139
145
  const body = {
140
146
  model: model || 'mistral-large-latest',
141
- max_tokens: 8192,
147
+ max_tokens: opts.max_tokens || 8192,
142
148
  messages: [
143
149
  { role: 'system', content: systemPrompt },
144
150
  { role: 'user', content: userMessage },
145
151
  ],
146
152
  stream,
147
153
  };
154
+ if (opts.temperature !== undefined) body.temperature = opts.temperature;
148
155
  const res = await fetch('https://api.mistral.ai/v1/chat/completions', {
149
156
  method: 'POST',
150
157
  headers: {
@@ -162,13 +169,14 @@ export async function callMistral(apiKey, model, systemPrompt, userMessage, stre
162
169
  return data.choices?.[0]?.message?.content || '';
163
170
  }
164
171
 
165
- export async function callCohere(apiKey, model, systemPrompt, userMessage, _stream = false) {
172
+ export async function callCohere(apiKey, model, systemPrompt, userMessage, _stream = false, opts = {}) {
166
173
  const body = {
167
174
  model: model || 'command-r-plus',
168
- max_tokens: 8192,
175
+ max_tokens: opts.max_tokens || 8192,
169
176
  preamble: systemPrompt,
170
177
  message: userMessage,
171
178
  };
179
+ if (opts.temperature !== undefined) body.temperature = opts.temperature;
172
180
  const res = await fetch('https://api.cohere.ai/v1/chat', {
173
181
  method: 'POST',
174
182
  headers: {
@@ -236,7 +244,7 @@ export async function streamSSE(res, format) {
236
244
  * NHA Free (Liara) — free LLM tier, no API key required.
237
245
  * Qwen3 32B on Hetzner RTX 6000 Pro 96GB. Supports thinking mode.
238
246
  */
239
- export async function callNHA(apiKey, model, systemPrompt, userMessage, stream = false) {
247
+ export async function callNHA(apiKey, model, systemPrompt, userMessage, stream = false, opts = {}) {
240
248
  // Read thinking preference from config
241
249
  let thinkingEnabled = false; // OFF by default for speed
242
250
  try {
@@ -266,7 +274,7 @@ export async function callNHA(apiKey, model, systemPrompt, userMessage, stream =
266
274
 
267
275
  const body = {
268
276
  model: model || '/opt/models/qwen3-32b',
269
- max_tokens: thinkingEnabled ? 16384 : 8192,
277
+ max_tokens: opts.max_tokens || (thinkingEnabled ? 16384 : 8192),
270
278
  messages: [
271
279
  { role: 'system', content: sanitizeForSentinel(systemPrompt) },
272
280
  { role: 'user', content: sanitizeForSentinel(userMessage) },
@@ -274,6 +282,7 @@ export async function callNHA(apiKey, model, systemPrompt, userMessage, stream =
274
282
  stream,
275
283
  chat_template_kwargs: { enable_thinking: thinkingEnabled },
276
284
  };
285
+ if (opts.temperature !== undefined) body.temperature = opts.temperature;
277
286
  // Route through NHA server proxy (SENTINEL protection) instead of direct to Hetzner
278
287
  const res = await fetch('https://nothumanallowed.com/api/v1/liara/chat', {
279
288
  method: 'POST',
@@ -338,7 +347,7 @@ export async function callLLM(config, systemPrompt, userMessage, opts = {}) {
338
347
  const callFn = getProviderCall(provider);
339
348
  if (!callFn) throw new Error(`Unknown provider: ${provider}`);
340
349
 
341
- return callFn(apiKey, model, systemPrompt, userMessage, false);
350
+ return callFn(apiKey, model, systemPrompt, userMessage, false, opts);
342
351
  }
343
352
 
344
353
  /**
@@ -6558,6 +6558,53 @@ var _wcLastFilePlan = []; // saved for manual repair trigger
6558
6558
  var _wcLastSysPreamble = '';
6559
6559
  var _wcTokIn = 0; // global token counters (accumulate across generation + repair)
6560
6560
  var _wcTokOut = 0;
6561
+ var _wcGenOverlayState = { fi: 0, total: 0, name: '' };
6562
+ var _wcGenStartTime = 0;
6563
+ var _wcTimerInterval = null;
6564
+
6565
+ function wcGenElapsed() {
6566
+ var s = Math.floor((Date.now() - _wcGenStartTime) / 1000);
6567
+ var m = Math.floor(s / 60); s = s % 60;
6568
+ return (m > 0 ? m + 'm ' : '') + s + 's';
6569
+ }
6570
+
6571
+ function wcStartGenTimer() {
6572
+ if (_wcTimerInterval) clearInterval(_wcTimerInterval);
6573
+ _wcTimerInterval = setInterval(function() {
6574
+ if (!wcState.running) { clearInterval(_wcTimerInterval); _wcTimerInterval = null; return; }
6575
+ if (_wcOverlayMinimized) {
6576
+ var pill = document.getElementById('wcPillLabel');
6577
+ if (pill) pill.textContent = _wcGenOverlayState.name || 'Generando...';
6578
+ var ov = document.getElementById('wcGenOverlay');
6579
+ if (ov) { var spans = ov.querySelectorAll('span'); if (spans[1]) spans[1].textContent = wcGenElapsed(); }
6580
+ } else {
6581
+ wcUpdateGenOverlay(_wcGenOverlayState.fi, _wcGenOverlayState.total, _wcGenOverlayState.name);
6582
+ }
6583
+ }, 1000);
6584
+ }
6585
+
6586
+ function wcUpdateGenOverlay(fi2, total, name) {
6587
+ _wcGenOverlayState = { fi: fi2, total: total, name: name };
6588
+ if (_wcOverlayMinimized) return;
6589
+ var ov = document.getElementById('wcGenOverlay');
6590
+ if (!ov) return;
6591
+ var pct = Math.round((fi2 / total) * 100);
6592
+ var tokLabel = (_wcTokIn + _wcTokOut) > 0
6593
+ ? '<div style="font-size:10px;color:var(--dim);margin-top:4px;font-family:var(--mono)">&#8679;' + _wcTokIn.toLocaleString() + ' &#8681;' + _wcTokOut.toLocaleString() + ' tok</div>'
6594
+ : '';
6595
+ ov.innerHTML =
6596
+ '<div style="font-size:38px;animation:wcRobotBob 1s ease-in-out infinite">&#129302;</div>' +
6597
+ '<div style="font-size:13px;font-weight:700;color:var(--green);margin-top:12px">' + (name.indexOf('Retry:') === 0 ? 'Retry in corso...' : name.indexOf('Fix:') === 0 ? 'Correzione in corso...' : 'Generazione in corso...') + '</div>' +
6598
+ '<div style="font-size:10px;color:var(--dim);margin-top:2px">Clicca per navigare i file</div>' +
6599
+ '<div style="font-size:11px;color:'+(name.indexOf('Retry:')===0?'#fb923c':name.indexOf('Fix:')===0?'#facc15':'var(--dim)')+';font-family:var(--mono);max-width:300px;text-align:center;word-break:break-all;margin-top:8px">'+wcEsc(name)+'</div>' +
6600
+ '<div style="width:220px;height:4px;background:rgba(255,255,255,0.1);border-radius:2px;overflow:hidden;margin-top:12px">' +
6601
+ '<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>' +
6602
+ '</div>' +
6603
+ '<div style="font-size:10px;color:var(--dim);margin-top:6px">'+fi2+' / '+total+' file &nbsp;&#183;&nbsp; '+wcGenElapsed()+'</div>' +
6604
+ tokLabel +
6605
+ '<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>';
6606
+ }
6607
+
6561
6608
  // Skills state
6562
6609
  var wcSkills = []; // [{name, content, type}] type: 'skill'|'memory'|'provider'
6563
6610
  var wcSkillModal = null; // null | {mode:'edit'|'new', idx:number|null, name, content, type, generating}
@@ -7937,65 +7984,46 @@ async function wcGenerate() {
7937
7984
  _wcLastFilePlan = filePlan;
7938
7985
  _wcLastSysPreamble = sysPreamble;
7939
7986
 
7940
- var _wcGenStartTime = Date.now();
7987
+ _wcGenStartTime = Date.now();
7941
7988
  _wcTokIn = 0; _wcTokOut = 0; // reset global counters for this generation run
7942
- var _wcTimerInterval = null;
7943
-
7944
- function wcGenElapsed() {
7945
- var s = Math.floor((Date.now() - _wcGenStartTime) / 1000);
7946
- var m = Math.floor(s / 60); s = s % 60;
7947
- return (m > 0 ? m + 'm ' : '') + s + 's';
7948
- }
7949
-
7950
- function wcStartGenTimer() {
7951
- if (_wcTimerInterval) clearInterval(_wcTimerInterval);
7952
- _wcTimerInterval = setInterval(function() {
7953
- if (!wcState.running) { clearInterval(_wcTimerInterval); _wcTimerInterval = null; return; }
7954
- if (_wcOverlayMinimized) {
7955
- // Update pill label + elapsed without full re-render
7956
- var pill = document.getElementById('wcPillLabel');
7957
- if (pill) pill.textContent = _wcGenOverlayState.name || 'Generando...';
7958
- var ov = document.getElementById('wcGenOverlay');
7959
- if (ov) { var spans = ov.querySelectorAll('span'); if (spans[1]) spans[1].textContent = wcGenElapsed(); }
7960
- } else {
7961
- wcUpdateGenOverlay(_wcGenOverlayState.fi, _wcGenOverlayState.total, _wcGenOverlayState.name);
7962
- }
7963
- }, 1000);
7964
- }
7965
7989
 
7966
- var _wcGenOverlayState = { fi: 0, total: 0, name: '' };
7990
+ // CSS files that need two-pass generation (too long for one call)
7991
+ var WC_CSS_SPLIT = {
7992
+ 'public/css/base.css': [
7993
+ 'PART 1 of 2. Generate the FIRST HALF of public/css/base.css. Include: (1) all CSS custom properties / design tokens (colors, spacing, font sizes, shadows, radii, transitions, z-index scale, dark/light mode via prefers-color-scheme data-theme), (2) CSS reset (*, box-sizing, margin, padding), (3) base typography (body, h1-h6, p, a, code, pre, blockquote), (4) utility classes (flex, grid helpers, spacing, text alignment, visibility, truncation). End the file at a natural boundary (closing brace). Do NOT generate components. Output raw CSS only.',
7994
+ 'PART 2 of 2. Continue (do NOT repeat) public/css/base.css from where part 1 ended. Generate: (5) layout helpers (.container, .grid, .col-*, .stack, .cluster, .sidebar-layout), (6) responsive breakpoint utilities (768px, 480px), (7) animation keyframes (@keyframes fadeIn, slideUp, pulse, spin), (8) scrollbar styling, (9) selection styles, (10) print styles. Output raw CSS only, starting directly from where part 1 ended — no repetition.'
7995
+ ],
7996
+ 'public/css/components.css': [
7997
+ 'PART 1 of 2. Generate the FIRST HALF of public/css/components.css using strict BEM. Include components: (1) .btn (--primary, --secondary, --danger, --ghost, --sm, --lg, disabled state, loading state with spinner), (2) .form (.form__group, .form__label, .form__input, .form__textarea, .form__select, .form__error, .form__hint, .form__input--invalid, focus states), (3) .card (.card__header, .card__body, .card__footer, .card--interactive hover/active), (4) .badge (--success, --error, --warning, --info, --neutral), (5) .alert (--success, --error, --warning, --info with icon space). Output raw CSS only.',
7998
+ 'PART 2 of 2. Continue (do NOT repeat) public/css/components.css from where part 1 ended. Include components: (6) .nav (.nav__brand, .nav__links, .nav__link, .nav__link--active, .nav__toggle mobile hamburger, .nav--sticky), (7) .modal (.modal__overlay, .modal__content, .modal__header, .modal__body, .modal__footer, open/close transition), (8) .spinner (sizes: sm/md/lg, colors), (9) .dropdown (.dropdown__menu, .dropdown__item, open state), (10) .avatar (.avatar--sm/md/lg, .avatar--initials), (11) .progress (.progress__bar, animated fill), (12) .table (.table__head, .table__row, .table__cell, striped, hover). Output raw CSS only, starting directly from where part 1 ended.'
7999
+ ]
8000
+ };
7967
8001
 
7968
- function wcUpdateGenOverlay(fi2, total, name) {
7969
- _wcGenOverlayState = { fi: fi2, total: total, name: name };
7970
- if (_wcOverlayMinimized) return;
7971
- var ov = document.getElementById('wcGenOverlay');
7972
- if (!ov) return;
7973
- var pct = Math.round((fi2 / total) * 100);
7974
- var tokLabel = (_wcTokIn + _wcTokOut) > 0
7975
- ? '<div style="font-size:10px;color:var(--dim);margin-top:4px;font-family:var(--mono)">&#8679;' + _wcTokIn.toLocaleString() + ' &#8681;' + _wcTokOut.toLocaleString() + ' tok</div>'
7976
- : '';
7977
- ov.innerHTML =
7978
- '<div style="font-size:38px;animation:wcRobotBob 1s ease-in-out infinite">&#129302;</div>' +
7979
- '<div style="font-size:13px;font-weight:700;color:var(--green);margin-top:12px">' + (name.indexOf('Retry:') === 0 ? 'Retry in corso...' : name.indexOf('Fix:') === 0 ? 'Correzione in corso...' : 'Generazione in corso...') + '</div>' +
7980
- '<div style="font-size:10px;color:var(--dim);margin-top:2px">Clicca per navigare i file</div>' +
7981
- '<div style="font-size:11px;color:'+(name.indexOf('Retry:')===0?'#fb923c':name.indexOf('Fix:')===0?'#facc15':'var(--dim)')+';font-family:var(--mono);max-width:300px;text-align:center;word-break:break-all;margin-top:8px">'+wcEsc(name)+'</div>' +
7982
- '<div style="width:220px;height:4px;background:rgba(255,255,255,0.1);border-radius:2px;overflow:hidden;margin-top:12px">' +
7983
- '<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>' +
7984
- '</div>' +
7985
- '<div style="font-size:10px;color:var(--dim);margin-top:6px">'+fi2+' / '+total+' file &nbsp;&#183;&nbsp; '+wcGenElapsed()+'</div>' +
7986
- tokLabel +
7987
- '<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>';
8002
+ // Helper: strip markdown fences from LLM output
8003
+ function wcStripFences(content) {
8004
+ var _nl2 = String.fromCharCode(10);
8005
+ var _fence = String.fromCharCode(96,96,96);
8006
+ var lines = content.split(_nl2);
8007
+ if (lines.length > 0 && lines[0].indexOf(_fence) === 0) lines.shift();
8008
+ if (lines.length > 0 && lines[lines.length-1].trim() === _fence) lines.pop();
8009
+ return lines.join(_nl2).trim();
7988
8010
  }
7989
8011
 
7990
- // Helper: generate one file
8012
+ // Helper: generate one file (with two-pass split for large CSS files)
7991
8013
  async function wcGenOneFile(fp, signal) {
7992
8014
  var _nl2 = String.fromCharCode(10);
8015
+ var splitPrompts = WC_CSS_SPLIT[fp.name];
8016
+ if (splitPrompts) {
8017
+ // Two-pass generation: call LLM twice and concatenate
8018
+ var part1 = await wcCallLLM(sysPreamble, splitPrompts[0] + _nl2 + _nl2 + 'File: ' + fp.name, signal, fp.lang);
8019
+ part1 = wcStripFences(part1);
8020
+ if (signal && signal.aborted) return part1;
8021
+ var part2 = await wcCallLLM(sysPreamble, splitPrompts[1] + _nl2 + _nl2 + 'File: ' + fp.name, signal, fp.lang);
8022
+ part2 = wcStripFences(part2);
8023
+ return part1 + _nl2 + _nl2 + part2;
8024
+ }
7993
8025
  var content = await wcCallLLM(sysPreamble, fp.prompt + _nl2 + _nl2 + 'File to generate: ' + fp.name, signal, fp.lang);
7994
- var _fence = String.fromCharCode(96,96,96);
7995
- var wcLines = content.split(_nl2);
7996
- if (wcLines.length > 0 && wcLines[0].indexOf(_fence) === 0) wcLines.shift();
7997
- if (wcLines.length > 0 && wcLines[wcLines.length-1].trim() === _fence) wcLines.pop();
7998
- return wcLines.join(_nl2).trim();
8026
+ return wcStripFences(content);
7999
8027
  }
8000
8028
 
8001
8029
  wcStartGenTimer();
@@ -8234,7 +8262,7 @@ async function wcCallLLMRaw(sys, user, signal) {
8234
8262
  var fetchOpts = {
8235
8263
  method: 'POST',
8236
8264
  headers: {'Content-Type':'application/json'},
8237
- body: JSON.stringify({system: sys, user: user, max_tokens: 8192})
8265
+ body: JSON.stringify({system: sys, user: user, max_tokens: 16384})
8238
8266
  };
8239
8267
  if (signal) fetchOpts.signal = signal;
8240
8268
  for (var attempt = 0; attempt < 3; attempt++) {