cascade-ai 0.43.0 → 0.46.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/dist/cli.js CHANGED
@@ -63,7 +63,7 @@ var __export = (target, all) => {
63
63
  var CASCADE_VERSION, CASCADE_CONFIG_FILE, CASCADE_DB_FILE, CASCADE_DASHBOARD_SECRET_FILE, GLOBAL_CONFIG_DIR, GLOBAL_DB_FILE, GLOBAL_KEYSTORE_FILE, GLOBAL_CREDENTIALS_FILE, GLOBAL_RUNTIME_DB_FILE, DEFAULT_DASHBOARD_PORT, DEFAULT_CONTEXT_LIMIT, DEFAULT_AUTO_SUMMARIZE_AT, MODELS, T1_MODEL_PRIORITY, T2_MODEL_PRIORITY, T3_MODEL_PRIORITY, VISION_MODEL_PRIORITY, COMPLEXITY_T2_COUNT, THEME_NAMES, DEFAULT_THEME, OLLAMA_BASE_URL, LM_STUDIO_BASE_URL, AZURE_BASE_URL_TEMPLATE, TOOL_NAMES, DEFAULT_APPROVAL_REQUIRED;
64
64
  var init_constants = __esm({
65
65
  "src/constants.ts"() {
66
- CASCADE_VERSION = "0.43.0";
66
+ CASCADE_VERSION = "0.46.0";
67
67
  CASCADE_CONFIG_FILE = ".cascade/config.json";
68
68
  CASCADE_DB_FILE = ".cascade/memory.db";
69
69
  CASCADE_DASHBOARD_SECRET_FILE = ".cascade/dashboard-secret";
@@ -3901,12 +3901,21 @@ var ModelSelector = class {
3901
3901
  * Absent for a provider ⇒ no validation ran ⇒ behave exactly as before.
3902
3902
  */
3903
3903
  validatedIds = /* @__PURE__ */ new Map();
3904
+ /**
3905
+ * Normalized ids that were added via discovery/registration but aren't in the
3906
+ * bundled catalog — i.e. genuinely new models the provider reported (a Gemini
3907
+ * flash released after the catalog was last hand-updated, an Ollama tag, etc.).
3908
+ * getCandidatesForTier lets these compete in AUTO ranking so a newer,
3909
+ * better-value model isn't invisible until someone edits constants.ts.
3910
+ */
3911
+ discovered = /* @__PURE__ */ new Set();
3904
3912
  constructor(availableProviders) {
3905
3913
  this.availableProviders = availableProviders;
3906
3914
  this.availableModels = new Map(Object.entries(MODELS));
3907
3915
  }
3908
3916
  addDynamicModel(model) {
3909
3917
  this.availableModels.set(model.id, model);
3918
+ if (!(model.id in MODELS)) this.discovered.add(normalizeModelId(model.id));
3910
3919
  }
3911
3920
  /** Record the ids a provider's API actually serves (discovery). Empty ⇒ ignored. */
3912
3921
  setValidatedModels(provider, ids) {
@@ -4014,6 +4023,19 @@ var ModelSelector = class {
4014
4023
  candidates2.push(model);
4015
4024
  }
4016
4025
  }
4026
+ if (this.discovered.size) {
4027
+ const tierProviders = /* @__PURE__ */ new Set();
4028
+ for (const key of priority) {
4029
+ const m = MODELS[key];
4030
+ if (m) tierProviders.add(m.provider);
4031
+ }
4032
+ const have = new Set(candidates2.map((c) => c.id));
4033
+ for (const model of this.availableModels.values()) {
4034
+ if (have.has(model.id)) continue;
4035
+ if (!this.discovered.has(normalizeModelId(model.id))) continue;
4036
+ if (tierProviders.has(model.provider) && this.isUsable(model)) candidates2.push(model);
4037
+ }
4038
+ }
4017
4039
  const localOnly = this.availableProviders.size > 0 && Array.from(this.availableProviders).every((p) => p === "ollama");
4018
4040
  if (localOnly) {
4019
4041
  for (const model of this.availableModels.values()) {
@@ -4725,6 +4747,14 @@ var FAMILY_MATCHERS = [
4725
4747
  [/gemini-?1\.5-pro/i, "gemini-1.5-pro"],
4726
4748
  [/gemini-?2\.0-flash-lite/i, "gemini-flash-lite"],
4727
4749
  [/gemini-?2\.0-flash/i, "gemini-2.0-flash"],
4750
+ // Generic Gemini fallbacks — a model released after this table was written
4751
+ // (e.g. a Gemini 3.x flash discovered live from the provider) still gets a
4752
+ // sensible score by its class instead of a neutral 0.5, so it can compete in
4753
+ // AUTO ranking. Ordered after the specific rows above; most-specific first.
4754
+ [/gemini.*flash.?lite/i, "gemini-flash-lite"],
4755
+ [/gemini.*pro/i, "gemini-2.5-pro"],
4756
+ [/gemini.*flash/i, "gemini-2.5-flash"],
4757
+ [/gemini/i, "gemini-2.5-flash"],
4728
4758
  [/codellama|code-llama|starcoder|stable-code/i, "codellama"],
4729
4759
  [/deepseek/i, "deepseek"],
4730
4760
  [/qwen/i, "qwen"],
@@ -4816,6 +4846,13 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter {
4816
4846
  costByFeature: {}
4817
4847
  };
4818
4848
  tierModels = /* @__PURE__ */ new Map();
4849
+ /**
4850
+ * Tiers the user pinned to a specific model in config (`models.tX` !== 'auto').
4851
+ * An explicit pin always wins over Cascade Auto — selectModelForSubtask never
4852
+ * re-selects a pinned tier per subtask. (tierModels is also filled with
4853
+ * auto-picked defaults, so it alone can't distinguish "pinned" from "default".)
4854
+ */
4855
+ explicitTierModels = /* @__PURE__ */ new Set();
4819
4856
  config;
4820
4857
  sessionCostUsd = 0;
4821
4858
  // Per-run accounting for the hard per-task cap. Reset by beginRun() at the
@@ -4893,6 +4930,7 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter {
4893
4930
  );
4894
4931
  }
4895
4932
  this.tierModels.set(tier, model);
4933
+ this.explicitTierModels.add(tier);
4896
4934
  this.ensureProvider(model, config.providers);
4897
4935
  }
4898
4936
  const azureRanked = [...azureDeployments].sort((a, b) => inferModelCapability(b.id) - inferModelCapability(a.id));
@@ -5333,6 +5371,7 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter {
5333
5371
  * Pure heuristic — no extra LLM call.
5334
5372
  */
5335
5373
  async selectModelForSubtask(tier, text, opts) {
5374
+ if (this.explicitTierModels.has(tier)) return this.tierModels.get(tier) ?? null;
5336
5375
  if (!this.config?.cascadeAuto || !this.taskAnalyzer || !text.trim()) return null;
5337
5376
  try {
5338
5377
  return await this.taskAnalyzer.selectModel(text, tier, this.selector, opts);
@@ -14781,20 +14820,20 @@ function defineTheme(name, colors) {
14781
14820
  return { name, colors };
14782
14821
  }
14783
14822
  var midnightTheme = defineTheme("midnight", {
14784
- primary: "#8B7CF9",
14785
- secondary: "#B7AEFF",
14786
- accent: "#42D3E7",
14787
- success: "#3DDC97",
14788
- warning: "#F7B84B",
14789
- error: "#FF6685",
14790
- info: "#67A8FF",
14791
- muted: "#7C819B",
14792
- background: "#080A12",
14793
- foreground: "#EDF0FA",
14794
- border: "#292D42",
14795
- t1Color: "#F7B84B",
14796
- t2Color: "#A98BFF",
14797
- t3Color: "#42D3E7"
14823
+ primary: "#4C8DFF",
14824
+ secondary: "#38B0DE",
14825
+ accent: "#2DD4BF",
14826
+ success: "#3DD68C",
14827
+ warning: "#F5B54B",
14828
+ error: "#F76D6D",
14829
+ info: "#4C8DFF",
14830
+ muted: "#8A93A8",
14831
+ background: "#0A0E1A",
14832
+ foreground: "#E8ECF6",
14833
+ border: "#202A3E",
14834
+ t1Color: "#4C8DFF",
14835
+ t2Color: "#38B0DE",
14836
+ t3Color: "#2DD4BF"
14798
14837
  });
14799
14838
  var auroraTheme = defineTheme("aurora", {
14800
14839
  primary: "#6F8CFF",
@@ -20788,9 +20827,9 @@ async function modelsCommand(options = {}) {
20788
20827
  });
20789
20828
  const liveData = router.getLiveData();
20790
20829
  const tiers = [
20791
- { tier: "T1", label: "T1 Administrator", color: chalk7.hex("#7C6AF7") },
20792
- { tier: "T2", label: "T2 Manager", color: chalk7.hex("#5AB4E8") },
20793
- { tier: "T3", label: "T3 Worker", color: chalk7.hex("#5AE8A4") }
20830
+ { tier: "T1", label: "T1 Administrator", color: chalk7.hex("#4C8DFF") },
20831
+ { tier: "T2", label: "T2 Manager", color: chalk7.hex("#38B0DE") },
20832
+ { tier: "T3", label: "T3 Worker", color: chalk7.hex("#2DD4BF") }
20794
20833
  ];
20795
20834
  let anyMissing = false;
20796
20835
  for (const { tier, label, color } of tiers) {
@@ -21391,10 +21430,9 @@ async function runHeadless(prompt, options) {
21391
21430
  function printBanner() {
21392
21431
  if (process.stdout.columns < 60) return;
21393
21432
  console.log();
21394
- console.log(chalk7.hex("#7C6AF7").bold(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
21395
- console.log(chalk7.hex("#7C6AF7").bold(" \u2551") + chalk7.white.bold(" \u25C8 CASCADE AI") + chalk7.gray(" v" + CASCADE_VERSION + " ") + chalk7.hex("#7C6AF7").bold("\u2551"));
21396
- console.log(chalk7.hex("#7C6AF7").bold(" \u2551") + chalk7.gray(" Multi-Tier Orchestration ") + chalk7.hex("#7C6AF7").bold("\u2551"));
21397
- console.log(chalk7.hex("#7C6AF7").bold(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
21433
+ console.log(" " + chalk7.hex("#4C8DFF").bold("\u2588\u2588\u2588\u2588\u2588\u2588\u2588"));
21434
+ console.log(" " + chalk7.hex("#38B0DE").bold(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588") + " " + chalk7.white.bold("CASCADE") + chalk7.gray(" v" + CASCADE_VERSION));
21435
+ console.log(" " + chalk7.hex("#2DD4BF").bold(" \u2588\u2588\u2588\u2588\u2588\u2588") + " " + chalk7.hex("#8A93A8")("multi-tier orchestration"));
21398
21436
  console.log();
21399
21437
  }
21400
21438
  program.parse(process.argv);