nothumanallowed 16.0.59 → 16.0.61
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/constants.mjs +1 -1
- package/src/services/llm.mjs +30 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "16.0.
|
|
3
|
+
"version": "16.0.61",
|
|
4
4
|
"description": "Local AI assistant: 80 tools (Gmail, Calendar, Drive, GitHub, Slack, browser, code, files), 38 agents, visual workflows (Studio, AWF, WebCraft). Install with `npm i -g nothumanallowed`, run with `nha ui`. Free tier built-in (Liara), no API key required. Your data stays on your PC — OAuth tokens local, no cloud. Open-source MIT.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
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 = '16.0.
|
|
8
|
+
export const VERSION = '16.0.61';
|
|
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/llm.mjs
CHANGED
|
@@ -605,7 +605,11 @@ export function _autoPrefixOpenRouterModel(model) {
|
|
|
605
605
|
* Model names: "anthropic/claude-sonnet-4.5", "openai/gpt-4o", "google/gemini-2.5-pro"...
|
|
606
606
|
*/
|
|
607
607
|
export async function callOpenRouter(apiKey, model, systemPrompt, userMessage, stream = false, opts = {}) {
|
|
608
|
+
const originalModel = model;
|
|
608
609
|
model = _autoPrefixOpenRouterModel(model);
|
|
610
|
+
if (process.env.NHA_LOG_OPENROUTER === '1') {
|
|
611
|
+
console.error(`[openrouter] model resolved: "${originalModel}" → "${model}"`);
|
|
612
|
+
}
|
|
609
613
|
const body = {
|
|
610
614
|
model: model || 'anthropic/claude-sonnet-4.5',
|
|
611
615
|
max_tokens: opts.max_tokens || 8192,
|
|
@@ -630,16 +634,23 @@ export async function callOpenRouter(apiKey, model, systemPrompt, userMessage, s
|
|
|
630
634
|
});
|
|
631
635
|
if (!res.ok) {
|
|
632
636
|
const err = await res.text();
|
|
633
|
-
// OpenRouter
|
|
634
|
-
//
|
|
635
|
-
//
|
|
637
|
+
// OpenRouter passes through provider-side errors verbatim. The most confusing
|
|
638
|
+
// case is "platform.openai.com" 401 — this means: OpenRouter forwarded the
|
|
639
|
+
// request to OpenAI in BYOK mode (Bring Your Own Key) and OpenAI rejected
|
|
640
|
+
// the key. We DO NOT silently swap the user's model — they chose it on purpose.
|
|
636
641
|
let hint = '';
|
|
637
642
|
if (res.status === 401) {
|
|
638
|
-
|
|
643
|
+
if (/platform\.openai\.com/i.test(err)) {
|
|
644
|
+
hint = `\n → BYOK mode rejected: model "${model}" is being routed via OpenAI in BYOK (Bring Your Own Key) mode, and the OpenAI key configured on your OpenRouter account is invalid or missing.\n Fix (keep using ${model}):\n 1. Go to openrouter.ai/settings/integrations\n 2. Either DISABLE the OpenAI integration (so OpenRouter uses its own credit), OR add a valid OpenAI key there.\n Note: NHA will NOT silently switch to a different model — your config stays as you set it.`;
|
|
645
|
+
} else {
|
|
646
|
+
hint = '\n → 401 from OpenRouter: your sk-or-v1-... key is invalid/expired. Regenerate at openrouter.ai/keys and run `nha config set key <new-key>`.';
|
|
647
|
+
}
|
|
639
648
|
} else if (res.status === 404) {
|
|
640
|
-
hint =
|
|
649
|
+
hint = `\n → 404 from OpenRouter: model "${model}" does not exist. See openrouter.ai/models for valid IDs (need vendor prefix like "openai/", "anthropic/", "google/").`;
|
|
641
650
|
} else if (res.status === 402) {
|
|
642
|
-
hint = '\n → 402 from OpenRouter
|
|
651
|
+
hint = '\n → 402 from OpenRouter: insufficient credits. Top up at openrouter.ai/credits.';
|
|
652
|
+
} else if (res.status === 429) {
|
|
653
|
+
hint = '\n → 429 from OpenRouter: rate limited. Wait a few seconds or upgrade your tier at openrouter.ai/settings.';
|
|
643
654
|
}
|
|
644
655
|
throw new Error(`OpenRouter ${res.status}: ${err}${hint}`);
|
|
645
656
|
}
|
|
@@ -1077,7 +1088,19 @@ async function _callOpenAIWithTools(apiKey, model, systemPrompt, messages, tools
|
|
|
1077
1088
|
headers,
|
|
1078
1089
|
body: JSON.stringify(body),
|
|
1079
1090
|
});
|
|
1080
|
-
if (!res.ok) {
|
|
1091
|
+
if (!res.ok) {
|
|
1092
|
+
const err = await res.text();
|
|
1093
|
+
const isOR = !!opts.baseUrl;
|
|
1094
|
+
let hint = '';
|
|
1095
|
+
if (isOR && res.status === 401 && /platform\.openai\.com/i.test(err)) {
|
|
1096
|
+
hint = `\n → BYOK mode rejected for model "${body.model}". OpenRouter forwarded the request to OpenAI in BYOK (Bring Your Own Key) mode, and the OpenAI key on your OpenRouter account is invalid/missing.\n Fix: openrouter.ai/settings/integrations → either DISABLE the OpenAI integration (so OpenRouter uses its own credit), OR add a valid OpenAI key there. NHA will keep your chosen model.`;
|
|
1097
|
+
} else if (isOR && res.status === 404) {
|
|
1098
|
+
hint = `\n → 404 from OpenRouter: model "${body.model}" not found. Must be in vendor/model format (e.g. "openai/gpt-4o", "anthropic/claude-sonnet-4.5").`;
|
|
1099
|
+
} else if (isOR && res.status === 402) {
|
|
1100
|
+
hint = '\n → 402 from OpenRouter: insufficient credits. Top up at openrouter.ai/credits.';
|
|
1101
|
+
}
|
|
1102
|
+
throw new Error(`${isOR ? 'OpenRouter' : 'OpenAI'} ${res.status}: ${err}${hint}`);
|
|
1103
|
+
}
|
|
1081
1104
|
|
|
1082
1105
|
const reader = res.body.getReader();
|
|
1083
1106
|
const dec = new TextDecoder();
|