deepseek-cli-mode 1.3.0 → 1.4.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/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.4.0 — reasoning effort levels in the model picker
4
+
5
+ - `/model` now asks for the reasoning effort after you pick a model, listing the adapter's real levels
6
+ (`low`, `medium`, `high`, `max`) plus `default`, with the current value preselected.
7
+ - `/reasoning` lists the same adapter-provided levels (falling back to `low`/`medium`/`high`/`max` when the
8
+ adapter exposes no metadata).
9
+ - The footer and banner show the active model **and** effort, e.g. `deepseek-flash · high`.
10
+ - Direct arguments still work: `/reasoning low`, `/model deepseek-v4-pro`.
11
+
3
12
  ## 1.3.0 — pickers, Shift+Tab permission cycling, permanent mode footer
4
13
 
5
14
  - `/model`, `/reasoning`, `/permissions`, and `/resume` now open an interactive picker (`↑`/`↓`, `Enter`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepseek-cli-mode",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Terminal (CLI) mode for DeepSeek Harness — an interactive, Claude Code-style coding agent for your shell.",
5
5
  "type": "module",
6
6
  "main": "index.js",
package/runner/runner.js CHANGED
@@ -547,7 +547,7 @@ Interactive commands:
547
547
  /new start a fresh session
548
548
  /sessions list recent sessions in this directory
549
549
  /resume <id> switch to another session
550
- /model [id] pick a model, or pass an id directly
550
+ /model [id] pick a model and its reasoning effort (low/medium/high/max)
551
551
  /reasoning [off|high|max] pick a reasoning effort
552
552
  /permissions [p] pick a permission mode (native: /permission; Shift+Tab cycles)
553
553
  /skills list the skills discovered in this workspace
@@ -1051,7 +1051,18 @@ async function run(ctx, options, exit) {
1051
1051
  return options[index]?.value ?? null;
1052
1052
  }
1053
1053
 
1054
- async function applyModelSelection(modelId) {
1054
+ /** Adapter-owned reasoning levels for the selected model, when exposed. */
1055
+ async function reasoningInfo() {
1056
+ try {
1057
+ if (llm === undefined) return null;
1058
+ const resolved = await llm.resolveModel(selectionRef.current.provider, selectionRef.current.model);
1059
+ return resolved.reasoning ?? null;
1060
+ } catch {
1061
+ return null;
1062
+ }
1063
+ }
1064
+
1065
+ async function applyModelSelection(modelId, pickEffort = true) {
1055
1066
  const next = { ...selectionRef.current, model: modelId };
1056
1067
  try {
1057
1068
  await defaultModel.saveSelection(next);
@@ -1059,7 +1070,23 @@ async function run(ctx, options, exit) {
1059
1070
  out(paint(ansi.green, ` ✓ model set: ${sanitize(next.provider)}/${sanitize(next.model)} (next message)\n`));
1060
1071
  } catch (error) {
1061
1072
  out(paint(ansi.red, ` ✘ ${sanitize(describeError(error))}\n`));
1073
+ return;
1062
1074
  }
1075
+ if (!pickEffort) return;
1076
+ const info = await reasoningInfo();
1077
+ const effortOptions =
1078
+ info !== null && info.efforts.length > 0
1079
+ ? info.efforts.map((effort) => ({ label: effort.name, description: effort.id, value: effort.id }))
1080
+ : ["low", "medium", "high", "max"].map((effort) => ({ label: effort, description: `effort: ${effort}`, value: effort }));
1081
+ const options = [...effortOptions, { label: "default", description: "provider default", value: "default" }];
1082
+ const defaultEffort = info !== null && info.defaultEffort !== undefined ? info.defaultEffort : "default";
1083
+ // Offer the effort choice for the newly selected model, keeping the current
1084
+ // value when it is still valid.
1085
+ const currentEffort = selectionRef.current.reasoningEffort ?? "default";
1086
+ const preferred = options.some((option) => option.value === currentEffort) ? currentEffort : defaultEffort;
1087
+ const initial = Math.max(0, options.findIndex((option) => option.value === preferred));
1088
+ const chosen = await selectOption(`Reasoning effort for ${modelId}`, options, initial);
1089
+ if (chosen !== null) await applyReasoningSelection(chosen);
1063
1090
  }
1064
1091
 
1065
1092
  async function applyReasoningSelection(effort) {
@@ -1392,17 +1419,22 @@ async function run(ctx, options, exit) {
1392
1419
  await applyReasoningSelection(argument);
1393
1420
  continue;
1394
1421
  }
1395
- const efforts = ["off", "high", "max", "default"];
1422
+ const info = await reasoningInfo();
1423
+ const efforts =
1424
+ info !== null && info.efforts.length > 0
1425
+ ? info.efforts.map((effort) => ({
1426
+ label: effort.name,
1427
+ description: effort.description ?? effort.id,
1428
+ value: effort.id,
1429
+ }))
1430
+ : ["low", "medium", "high", "max"].map((effort) => ({
1431
+ label: effort,
1432
+ description: `effort: ${effort}`,
1433
+ value: effort,
1434
+ }));
1435
+ efforts.push({ label: "default", description: "provider default", value: "default" });
1396
1436
  const current = selectionRef.current.reasoningEffort ?? "default";
1397
- const chosen = await selectOption(
1398
- "Select reasoning effort",
1399
- efforts.map((effort) => ({
1400
- label: effort,
1401
- description: effort === "default" ? "provider default" : `effort: ${effort}`,
1402
- value: effort,
1403
- })),
1404
- Math.max(0, efforts.indexOf(current))
1405
- );
1437
+ const chosen = await selectOption("Select reasoning effort", efforts, Math.max(0, efforts.findIndex((option) => option.value === current)));
1406
1438
  if (chosen !== null) await applyReasoningSelection(chosen);
1407
1439
  continue;
1408
1440
  }