nothumanallowed 13.5.91 → 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.91",
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
  /**
@@ -7987,15 +7987,43 @@ async function wcGenerate() {
7987
7987
  _wcGenStartTime = Date.now();
7988
7988
  _wcTokIn = 0; _wcTokOut = 0; // reset global counters for this generation run
7989
7989
 
7990
- // Helper: generate one file
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
+ };
8001
+
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();
8010
+ }
8011
+
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++) {