rlm-cli 0.2.19 → 0.2.21

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/cli.js CHANGED
@@ -77,7 +77,7 @@ function parseArgs() {
77
77
  }
78
78
  }
79
79
  if (!modelId) {
80
- modelId = process.env.RLM_MODEL || "claude-sonnet-4-5-20250929";
80
+ modelId = process.env.RLM_MODEL || "claude-sonnet-4-6";
81
81
  }
82
82
  if (positional.length === 0) {
83
83
  console.error("Error: query argument is required");
package/dist/config.js CHANGED
@@ -56,12 +56,13 @@ export function loadConfig() {
56
56
  try {
57
57
  const raw = fs.readFileSync(configPath, "utf-8");
58
58
  const parsed = parseYaml(raw);
59
+ const clamp = (v, min, max, def) => typeof v === "number" && isFinite(v) ? Math.max(min, Math.min(max, Math.round(v))) : def;
59
60
  return {
60
- max_iterations: typeof parsed.max_iterations === "number" ? parsed.max_iterations : DEFAULTS.max_iterations,
61
- max_depth: typeof parsed.max_depth === "number" ? parsed.max_depth : DEFAULTS.max_depth,
62
- max_sub_queries: typeof parsed.max_sub_queries === "number" ? parsed.max_sub_queries : DEFAULTS.max_sub_queries,
63
- truncate_len: typeof parsed.truncate_len === "number" ? parsed.truncate_len : DEFAULTS.truncate_len,
64
- metadata_preview_lines: typeof parsed.metadata_preview_lines === "number" ? parsed.metadata_preview_lines : DEFAULTS.metadata_preview_lines,
61
+ max_iterations: clamp(parsed.max_iterations, 1, 100, DEFAULTS.max_iterations),
62
+ max_depth: clamp(parsed.max_depth, 1, 10, DEFAULTS.max_depth),
63
+ max_sub_queries: clamp(parsed.max_sub_queries, 1, 500, DEFAULTS.max_sub_queries),
64
+ truncate_len: clamp(parsed.truncate_len, 500, 50000, DEFAULTS.truncate_len),
65
+ metadata_preview_lines: clamp(parsed.metadata_preview_lines, 5, 100, DEFAULTS.metadata_preview_lines),
65
66
  };
66
67
  }
67
68
  catch {
package/dist/env.js CHANGED
@@ -22,7 +22,11 @@ function loadEnvFile(filePath) {
22
22
  if (eqIndex === -1)
23
23
  continue;
24
24
  const key = trimmed.slice(0, eqIndex).trim();
25
- const value = trimmed.slice(eqIndex + 1).trim();
25
+ let value = trimmed.slice(eqIndex + 1).trim();
26
+ // Strip matching surrounding quotes ("..." or '...')
27
+ if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
28
+ value = value.slice(1, -1);
29
+ }
26
30
  if (key && !process.env[key]) {
27
31
  process.env[key] = value;
28
32
  }
@@ -1127,11 +1127,32 @@ async function interactive() {
1127
1127
  }
1128
1128
  setupRl.close();
1129
1129
  }
1130
- // Resolve model
1130
+ // Resolve model — ensure the resolved provider actually has an API key
1131
1131
  const initialResolved = resolveModelWithProvider(currentModelId);
1132
1132
  if (initialResolved) {
1133
- currentModel = initialResolved.model;
1134
- currentProviderName = initialResolved.provider;
1133
+ const resolvedKey = providerEnvKey(initialResolved.provider);
1134
+ if (process.env[resolvedKey]) {
1135
+ // Provider has a key — use it
1136
+ currentModel = initialResolved.model;
1137
+ currentProviderName = initialResolved.provider;
1138
+ }
1139
+ }
1140
+ // If default model's provider has no key, fall back to a provider that does
1141
+ if (!currentModel) {
1142
+ const activeProvider = detectProvider();
1143
+ if (activeProvider !== "unknown") {
1144
+ const fallbackModel = getDefaultModelForProvider(activeProvider);
1145
+ if (fallbackModel) {
1146
+ const fallbackResolved = resolveModelWithProvider(fallbackModel);
1147
+ if (fallbackResolved) {
1148
+ currentModelId = fallbackModel;
1149
+ currentModel = fallbackResolved.model;
1150
+ currentProviderName = fallbackResolved.provider;
1151
+ const label = findSetupProvider(activeProvider)?.name || activeProvider;
1152
+ console.log(` ${c.dim}Using ${label} (${currentModelId})${c.reset}`);
1153
+ }
1154
+ }
1155
+ }
1135
1156
  }
1136
1157
  if (!currentModel) {
1137
1158
  console.log(`\n ${c.red}Model "${currentModelId}" not found.${c.reset}`);
@@ -1399,11 +1420,16 @@ async function interactive() {
1399
1420
  if (!contextText) {
1400
1421
  const { filePath, query: extractedQuery } = extractFilePath(query);
1401
1422
  if (filePath) {
1402
- contextText = fs.readFileSync(filePath, "utf-8");
1403
- contextSource = path.basename(filePath);
1404
- const lines = contextText.split("\n").length;
1405
- console.log(` ${c.green}✓${c.reset} Loaded ${c.bold}${contextText.length.toLocaleString()}${c.reset} chars (${lines} lines) from ${c.underline}${filePath}${c.reset}`);
1406
- query = extractedQuery || query;
1423
+ try {
1424
+ contextText = fs.readFileSync(filePath, "utf-8");
1425
+ contextSource = path.basename(filePath);
1426
+ const lines = contextText.split("\n").length;
1427
+ console.log(` ${c.green}✓${c.reset} Loaded ${c.bold}${contextText.length.toLocaleString()}${c.reset} chars (${lines} lines) from ${c.underline}${filePath}${c.reset}`);
1428
+ query = extractedQuery || query;
1429
+ }
1430
+ catch (err) {
1431
+ console.log(` ${c.red}Could not read file: ${err.message}${c.reset}`);
1432
+ }
1407
1433
  }
1408
1434
  }
1409
1435
  // Run query
package/dist/viewer.js CHANGED
@@ -639,7 +639,14 @@ async function main() {
639
639
  console.error(`${c.red}File not found: ${filePath}${c.reset}`);
640
640
  process.exit(1);
641
641
  }
642
- const traj = JSON.parse(fs.readFileSync(filePath, "utf-8"));
642
+ let traj;
643
+ try {
644
+ traj = JSON.parse(fs.readFileSync(filePath, "utf-8"));
645
+ }
646
+ catch (err) {
647
+ console.error(`${c.red}Could not parse trajectory file: ${err.message}${c.reset}`);
648
+ process.exit(1);
649
+ }
643
650
  if (!traj.iterations || traj.iterations.length === 0) {
644
651
  console.error(`${c.red}Trajectory has no iterations (empty run).${c.reset}`);
645
652
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rlm-cli",
3
- "version": "0.2.19",
3
+ "version": "0.2.21",
4
4
  "description": "Standalone CLI for Recursive Language Models (RLMs) — implements Algorithm 1 from arXiv:2512.24601",
5
5
  "type": "module",
6
6
  "bin": {