nexrall-code 0.5.99 → 0.5.101
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/dist/index.js +92 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9875,6 +9875,7 @@ var require_client = __commonJS({
|
|
|
9875
9875
|
exports2.revokeRefreshToken = revokeRefreshToken2;
|
|
9876
9876
|
exports2.describeAttachment = describeAttachment2;
|
|
9877
9877
|
exports2.getBalance = getBalance3;
|
|
9878
|
+
exports2.getCodeModels = getCodeModels;
|
|
9878
9879
|
exports2.getUsageDaily = getUsageDaily;
|
|
9879
9880
|
exports2.exchangeVscodeCode = exchangeVscodeCode;
|
|
9880
9881
|
exports2.login = login2;
|
|
@@ -10648,6 +10649,27 @@ var require_client = __commonJS({
|
|
|
10648
10649
|
const data = await response.json();
|
|
10649
10650
|
return typeof data.balance === "number" ? data.balance : 0;
|
|
10650
10651
|
}
|
|
10652
|
+
async function getCodeModels() {
|
|
10653
|
+
const fetchOnce = () => (0, node_fetch_1.default)(`${exports2.API_BASE}/api/code/models`, { method: "GET", headers: authHeaders() });
|
|
10654
|
+
let response = await fetchOnce();
|
|
10655
|
+
if (response.status === 401 || response.status === 403) {
|
|
10656
|
+
const body = await response.text().catch(() => "");
|
|
10657
|
+
if (isExpiredTokenResponse(response.status, body) && await refreshAccessToken()) {
|
|
10658
|
+
response = await fetchOnce();
|
|
10659
|
+
} else {
|
|
10660
|
+
throw new Error(`API error ${response.status}: ${body}`);
|
|
10661
|
+
}
|
|
10662
|
+
}
|
|
10663
|
+
if (!response.ok) {
|
|
10664
|
+
const errText = await response.text();
|
|
10665
|
+
throw new Error(`API error ${response.status}: ${errText}`);
|
|
10666
|
+
}
|
|
10667
|
+
const data = await response.json();
|
|
10668
|
+
return {
|
|
10669
|
+
models: Array.isArray(data.models) ? data.models : [],
|
|
10670
|
+
defaultModel: typeof data.defaultModel === "string" ? data.defaultModel : "claude-sonnet-5"
|
|
10671
|
+
};
|
|
10672
|
+
}
|
|
10651
10673
|
async function getUsageDaily(days = 30) {
|
|
10652
10674
|
const fetchOnce = () => (0, node_fetch_1.default)(`${exports2.API_BASE}/api/user/usage-daily?days=${days}`, { method: "GET", headers: authHeaders() });
|
|
10653
10675
|
let response = await fetchOnce();
|
|
@@ -153192,6 +153214,59 @@ function normaliseModelId(model) {
|
|
|
153192
153214
|
return "claude-sonnet-5";
|
|
153193
153215
|
return LEGACY_MODEL_ALIASES[raw.toLowerCase()] ?? raw;
|
|
153194
153216
|
}
|
|
153217
|
+
var MODEL_EFFORT_STYLE = {
|
|
153218
|
+
"gpt-5.4": "openai_gated",
|
|
153219
|
+
"gpt-5.4-mini": "openai_gated",
|
|
153220
|
+
"gpt-4.1": "none",
|
|
153221
|
+
"gpt-4o-mini": "none",
|
|
153222
|
+
"deepseek-v4-pro": "deepseek",
|
|
153223
|
+
"deepseek-v4-flash": "deepseek",
|
|
153224
|
+
"qwen3.7-max": "qwen",
|
|
153225
|
+
"glm-5.3": "glm"
|
|
153226
|
+
// Everything else (all claude-* ids) falls through to 'anthropic' below.
|
|
153227
|
+
};
|
|
153228
|
+
var EFFORT_STYLE_CONFIG = {
|
|
153229
|
+
// Anthropic's real output_config.effort enum is low|medium|high|xhigh|max
|
|
153230
|
+
// (docs.claude.com extended output). 'extra'/'ultra' are legacy UI labels
|
|
153231
|
+
// this codebase invented, translated server-side by routes/code.js's
|
|
153232
|
+
// EFFORT_MAP (extra->xhigh, ultra->max) — kept as the wire values here
|
|
153233
|
+
// (rather than switching to 'xhigh'/'max' directly) only for backward
|
|
153234
|
+
// compatibility with saved sessions/scripts already passing them.
|
|
153235
|
+
anthropic: { levels: ["low", "medium", "high", "extra", "ultra"], names: ["Low", "Medium", "High", "Extra High", "Max"] },
|
|
153236
|
+
// DeepSeek V4 has THREE real buckets — live-verified against
|
|
153237
|
+
// api.deepseek.com 2026-08-30 (see streamFactory.test.js's DEEPSEEK case):
|
|
153238
|
+
// low->low, medium/high/xhigh->high, max->max.
|
|
153239
|
+
deepseek: { levels: ["low", "high", "max"], names: ["Low", "Standard", "Max"] },
|
|
153240
|
+
// Qwen3.7-Max's knob is a boolean (enable_thinking), not a graded scale.
|
|
153241
|
+
qwen: { levels: ["low", "high"], names: ["Thinking Off", "Thinking On"] },
|
|
153242
|
+
// GLM-5.3 cannot disable reasoning at all (a hard 400 if you try) and has
|
|
153243
|
+
// 3 real buckets (low/high/max) via a FLAT top-level `reasoning_effort`
|
|
153244
|
+
// string — live-verified against api.z.ai 2026-08-30 (see
|
|
153245
|
+
// streamFactory.test.js's GLM_THINKING_LEVEL case).
|
|
153246
|
+
glm: { levels: ["low", "high", "max"], names: ["Low", "High", "Max"] },
|
|
153247
|
+
// Effectively a no-op today whenever the turn has tools (almost always true
|
|
153248
|
+
// for nexrall-code) — see backend modelRegistry.js's OPENAI_GATED doc
|
|
153249
|
+
// comment. Still forwards a real value for the rare tool-less turn.
|
|
153250
|
+
openai_gated: { levels: ["low", "medium", "high"], names: ["Low", "Medium", "High"] },
|
|
153251
|
+
// No reasoning-effort concept on this model at all (gpt-4.1, gpt-4o-mini).
|
|
153252
|
+
none: { levels: ["medium"], names: ["N/A"] }
|
|
153253
|
+
};
|
|
153254
|
+
function effortStyleFor(modelId) {
|
|
153255
|
+
return MODEL_EFFORT_STYLE[normaliseModelId(modelId)] ?? "anthropic";
|
|
153256
|
+
}
|
|
153257
|
+
function effortConfigFor(modelId) {
|
|
153258
|
+
return EFFORT_STYLE_CONFIG[effortStyleFor(modelId)];
|
|
153259
|
+
}
|
|
153260
|
+
function clampEffortForModel(effort, modelId) {
|
|
153261
|
+
const config = effortConfigFor(modelId);
|
|
153262
|
+
if (config.levels.includes(effort))
|
|
153263
|
+
return effort;
|
|
153264
|
+
return defaultEffortForModel(modelId);
|
|
153265
|
+
}
|
|
153266
|
+
function defaultEffortForModel(modelId) {
|
|
153267
|
+
const levels = effortConfigFor(modelId).levels;
|
|
153268
|
+
return levels[Math.min(1, levels.length - 1)];
|
|
153269
|
+
}
|
|
153195
153270
|
function resolveModelLabel(alias) {
|
|
153196
153271
|
const id = normaliseModelId(alias);
|
|
153197
153272
|
return MODEL_LABELS[id] ?? id;
|
|
@@ -153733,7 +153808,7 @@ function printHelp() {
|
|
|
153733
153808
|
["/help", "Show this help"],
|
|
153734
153809
|
["/model [name]", "Switch model (e.g. claude-opus-5, gpt-5.4)"],
|
|
153735
153810
|
["/mode [ask|edit|plan|auto]", "Set agent mode"],
|
|
153736
|
-
["/effort [
|
|
153811
|
+
["/effort [level]", "Set thinking effort level (options depend on the current model \u2014 run /effort with no argument to see them)"],
|
|
153737
153812
|
["/yolo", "Auto-approve all permissions"],
|
|
153738
153813
|
["/balance", "Show wallet balance"],
|
|
153739
153814
|
["/add <filepath>", "Add a file to conversation context"],
|
|
@@ -153854,8 +153929,7 @@ Set ${TRUST_ENV_VAR}=1 to confirm non-interactively, or run \`nex\` interactivel
|
|
|
153854
153929
|
let sessionId = crypto4.randomBytes(8).toString("hex");
|
|
153855
153930
|
let sessionTitle = "";
|
|
153856
153931
|
let agentMode = "auto";
|
|
153857
|
-
|
|
153858
|
-
let effortLevel = options.effort && VALID_EFFORT_LEVELS.includes(options.effort) ? options.effort : "medium";
|
|
153932
|
+
let effortLevel = options.effort ? clampEffortForModel(options.effort, modelAlias) : defaultEffortForModel(modelAlias);
|
|
153859
153933
|
const permRules = initPermissions(workDir);
|
|
153860
153934
|
const ruleCount = permRules.allow.length + permRules.ask.length + permRules.deny.length;
|
|
153861
153935
|
if (ruleCount && !headless)
|
|
@@ -154334,7 +154408,13 @@ ${dirList}`;
|
|
|
154334
154408
|
console.log(source_default.dim(` Options: ${SELECTABLE_MODELS.map(modelWithCostHint).join(" \xB7 ")}`));
|
|
154335
154409
|
} else if (SELECTABLE_MODELS.includes(normaliseModelId(requested))) {
|
|
154336
154410
|
modelAlias = normaliseModelId(requested);
|
|
154411
|
+
const clamped = clampEffortForModel(effortLevel, modelAlias);
|
|
154412
|
+
const effortChanged = clamped !== effortLevel;
|
|
154413
|
+
effortLevel = clamped;
|
|
154337
154414
|
console.log(source_default.green(` Model \u2192 ${source_default.bold(resolveModelLabel(modelAlias))}`));
|
|
154415
|
+
if (effortChanged) {
|
|
154416
|
+
console.log(source_default.dim(` Effort reset \u2192 ${effortLevel} (previous level not available on this model)`));
|
|
154417
|
+
}
|
|
154338
154418
|
} else {
|
|
154339
154419
|
console.log(source_default.red(` Unknown: ${requested}. Options: ${SELECTABLE_MODELS.join(", ")}`));
|
|
154340
154420
|
}
|
|
@@ -154361,13 +154441,15 @@ ${dirList}`;
|
|
|
154361
154441
|
}
|
|
154362
154442
|
case "/effort": {
|
|
154363
154443
|
const effortArg = arg.toLowerCase();
|
|
154444
|
+
const config = effortConfigFor(modelAlias);
|
|
154445
|
+
const optionsLine = config.levels.map((v, i2) => `${v} (${config.names[i2]})`).join(" \xB7 ");
|
|
154364
154446
|
if (!effortArg) {
|
|
154365
|
-
console.log(source_default.dim(` Current: ${source_default.cyan(effortLevel)} Options:
|
|
154366
|
-
} else if (
|
|
154447
|
+
console.log(source_default.dim(` Current: ${source_default.cyan(effortLevel)} Options: ${optionsLine}`));
|
|
154448
|
+
} else if (config.levels.includes(effortArg)) {
|
|
154367
154449
|
effortLevel = effortArg;
|
|
154368
154450
|
console.log(source_default.green(` Effort \u2192 ${source_default.bold(effortArg)}`));
|
|
154369
154451
|
} else {
|
|
154370
|
-
console.log(source_default.red(` Unknown: ${effortArg}`));
|
|
154452
|
+
console.log(source_default.red(` Unknown: ${effortArg}. Options: ${optionsLine}`));
|
|
154371
154453
|
}
|
|
154372
154454
|
rl.prompt();
|
|
154373
154455
|
return;
|
|
@@ -155129,7 +155211,7 @@ program2.command("sessions").description("List or delete saved chat sessions").o
|
|
|
155129
155211
|
console.log(source_default.dim(" nex sessions --delete <id> to remove one"));
|
|
155130
155212
|
console.log();
|
|
155131
155213
|
});
|
|
155132
|
-
program2.option("-p, --pro", "Use Claude Opus 5 (most capable)").option("-t, --turbo", "Use Claude Sonnet 5 (fast, default)").option("-u, --ultra", "Use Claude Fable 5 (most powerful)").option("-y, --yolo", "Auto-approve all tool calls (no permission prompts)").option("-d, --dir <path>", "Set working directory (default: current directory)").option("-m, --model <name>", "Explicit model, e.g. claude-opus-5 | gpt-5.4 | gpt-4.1").option("-r, --resume [id]", "Resume last session, or a specific session id").option("-e, --effort <level>", "Thinking effort: low
|
|
155214
|
+
program2.option("-p, --pro", "Use Claude Opus 5 (most capable)").option("-t, --turbo", "Use Claude Sonnet 5 (fast, default)").option("-u, --ultra", "Use Claude Fable 5 (most powerful)").option("-y, --yolo", "Auto-approve all tool calls (no permission prompts)").option("-d, --dir <path>", "Set working directory (default: current directory)").option("-m, --model <name>", "Explicit model, e.g. claude-opus-5 | gpt-5.4 | gpt-4.1").option("-r, --resume [id]", "Resume last session, or a specific session id").option("-e, --effort <level>", "Thinking effort \u2014 real levels depend on the model (e.g. DeepSeek: low|high|max, Qwen: low|high); run `nex --model <id>` then `/effort` with no argument to see a model's scale").option("--no-banner", "Skip the ASCII banner (useful in scripts/pipes)").option("--output-format <fmt>", "One-shot output format: text | json | stream-json (implies auto-approve)").option("--audit [path]", "Log every tool call (and refusal) to a JSONL trail (default: .nexrall/audit/<session>.jsonl)").argument("[prompt...]", "One-shot prompt \u2014 if omitted, starts interactive mode").action(async (promptParts, options) => {
|
|
155133
155215
|
if (!(0, import_code_core7.isAuthenticated)()) {
|
|
155134
155216
|
console.error("Not logged in. Run: nex auth");
|
|
155135
155217
|
process.exit(1);
|
|
@@ -155164,8 +155246,9 @@ program2.option("-p, --pro", "Use Claude Opus 5 (most capable)").option("-t, --t
|
|
|
155164
155246
|
let effort;
|
|
155165
155247
|
if (options.effort) {
|
|
155166
155248
|
const lvl = String(options.effort).toLowerCase();
|
|
155167
|
-
|
|
155168
|
-
|
|
155249
|
+
const config = effortConfigFor(normaliseModelId(model));
|
|
155250
|
+
if (!config.levels.includes(lvl)) {
|
|
155251
|
+
console.error(`Invalid --effort "${options.effort}" for model "${model}". Use: ${config.levels.join(" | ")}`);
|
|
155169
155252
|
process.exit(1);
|
|
155170
155253
|
}
|
|
155171
155254
|
effort = lvl;
|