nothumanallowed 11.3.0 → 11.5.0

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": "11.3.0",
3
+ "version": "11.5.0",
4
4
  "description": "NotHumanAllowed — 38 AI agents, 53 tools. Email, calendar, browser automation, screen capture, canvas, cron/heartbeat, GitHub, Notion, Slack, voice chat, 28 languages. Zero-dependency CLI.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/config.mjs CHANGED
@@ -283,6 +283,9 @@ export function setConfigValue(key, value) {
283
283
  'my-role': 'profile.role',
284
284
  'role': 'profile.role',
285
285
  'profile-notes': 'profile.notes',
286
+ 'thinking': 'thinking',
287
+ 'extended-thinking': 'thinking',
288
+ 'language': 'language',
286
289
  };
287
290
 
288
291
  const resolved = aliases[key] || key;
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 = '11.3.0';
8
+ export const VERSION = '11.5.0';
9
9
  export const BASE_URL = 'https://nothumanallowed.com/cli';
10
10
  export const API_BASE = 'https://nothumanallowed.com/api/v1';
11
11
 
@@ -234,18 +234,33 @@ export async function streamSSE(res, format) {
234
234
 
235
235
  /**
236
236
  * NHA Free (Liara) — free LLM tier, no API key required.
237
- * Connects to the NHA-hosted Qwen3 + LoRA on Hetzner GPU.
238
- * OpenAI-compatible format. Slower than paid providers (5-15 seconds).
237
+ * Qwen3 32B on Hetzner RTX 6000 Pro 96GB. Supports thinking mode.
239
238
  */
240
239
  export async function callNHA(apiKey, model, systemPrompt, userMessage, stream = false) {
240
+ // Read thinking preference from config
241
+ let thinkingEnabled = false; // OFF by default for speed
242
+ try {
243
+ const fs = await import('fs');
244
+ const path = await import('path');
245
+ const os = await import('os');
246
+ const cfgFile = path.default.join(os.default.homedir(), '.nha', 'config.json');
247
+ if (fs.default.existsSync(cfgFile)) {
248
+ const cfg = JSON.parse(fs.default.readFileSync(cfgFile, 'utf-8'));
249
+ if (cfg.thinking === true || cfg.thinking === 'on' || cfg.thinking === 'true') {
250
+ thinkingEnabled = true;
251
+ }
252
+ }
253
+ } catch {}
254
+
241
255
  const body = {
242
- model: model || 'nha-v1',
243
- max_tokens: 4096,
256
+ model: model || '/opt/models/qwen3-32b',
257
+ max_tokens: thinkingEnabled ? 8192 : 4096,
244
258
  messages: [
245
259
  { role: 'system', content: systemPrompt },
246
260
  { role: 'user', content: userMessage },
247
261
  ],
248
262
  stream,
263
+ chat_template_kwargs: { enable_thinking: thinkingEnabled },
249
264
  };
250
265
  const res = await fetch('https://liara.nothumanallowed.com/v1/chat/completions', {
251
266
  method: 'POST',
@@ -258,9 +273,12 @@ export async function callNHA(apiKey, model, systemPrompt, userMessage, stream =
258
273
  const err = await res.text();
259
274
  throw new Error(`NHA Free ${res.status}: ${err}`);
260
275
  }
261
- if (stream) return streamSSE(res, 'openai'); // OpenAI-compatible SSE format
276
+ if (stream) return streamSSE(res, 'openai');
262
277
  const data = await res.json();
263
- return data.choices?.[0]?.message?.content || '';
278
+ let content = data.choices?.[0]?.message?.content || '';
279
+ // Strip thinking tags if present
280
+ content = content.replace(/<think>[\s\S]*?<\/think>/g, '').trim();
281
+ return content;
264
282
  }
265
283
 
266
284
  const PROVIDERS = {
@@ -414,6 +432,22 @@ export async function callLLMStream(config, systemPrompt, userMessage, onToken,
414
432
  const callFn = getProviderCall(provider);
415
433
  if (!callFn) throw new Error(`Unknown provider: ${provider}`);
416
434
 
435
+ // NHA Free: add thinking config to streaming request
436
+ if (provider === 'nha') {
437
+ try {
438
+ const fs2 = await import('fs');
439
+ const path2 = await import('path');
440
+ const os2 = await import('os');
441
+ const cfgFile2 = path2.default.join(os2.default.homedir(), '.nha', 'config.json');
442
+ if (fs2.default.existsSync(cfgFile2)) {
443
+ const cfg2 = JSON.parse(fs2.default.readFileSync(cfgFile2, 'utf-8'));
444
+ const thinkOn = cfg2.thinking === true || cfg2.thinking === 'on' || cfg2.thinking === 'true';
445
+ // Will be added to body below via buildRequestBody override
446
+ opts._thinkingEnabled = thinkOn;
447
+ }
448
+ } catch {}
449
+ }
450
+
417
451
  // Gemini and Cohere don't support streaming — fall back to non-streaming
418
452
  if (provider === 'gemini' || provider === 'cohere') {
419
453
  const text = await callFn(apiKey, model, systemPrompt, userMessage, false);
@@ -452,13 +486,13 @@ function buildRequestBody(provider, model, systemPrompt, userMessage, stream) {
452
486
  }
453
487
  // OpenAI-compatible format (OpenAI, DeepSeek, Grok, Mistral)
454
488
  const modelDefaults = {
455
- nha: 'nha-v1',
489
+ nha: '/opt/models/qwen3-32b',
456
490
  openai: 'gpt-4o',
457
491
  deepseek: 'deepseek-chat',
458
492
  grok: 'grok-3-latest',
459
493
  mistral: 'mistral-large-latest',
460
494
  };
461
- return {
495
+ const req = {
462
496
  model: model || modelDefaults[provider] || 'gpt-4o',
463
497
  max_tokens: provider === 'nha' ? 4096 : 8192,
464
498
  messages: [
@@ -467,6 +501,11 @@ function buildRequestBody(provider, model, systemPrompt, userMessage, stream) {
467
501
  ],
468
502
  stream,
469
503
  };
504
+ // NHA: add thinking control
505
+ if (provider === 'nha') {
506
+ req.chat_template_kwargs = { enable_thinking: false };
507
+ }
508
+ return req;
470
509
  }
471
510
 
472
511
  /** Get provider API URL */
@@ -1984,6 +1984,7 @@ function renderSettings(el) {
1984
1984
  ['provider', 'Provider', 'nha (free) / anthropic / openai / gemini / deepseek / grok / mistral'],
1985
1985
  ['key', 'API Key', 'Not needed for NHA Free', true],
1986
1986
  ['model', 'Model', 'Leave empty for default'],
1987
+ ['thinking', 'Extended Thinking', 'on / off — Qwen3 reasoning mode (NHA Free only)'],
1987
1988
  ]) +
1988
1989
  settingsSection('responder', 'Message Responder', 'Auto-reply to Telegram and Discord messages.', [
1989
1990
  ['telegram-bot-token', 'Telegram Bot Token', 'Get from @BotFather', true],