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.cjs +60 -22
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +60 -22
- package/dist/cli.js.map +1 -1
- package/dist/desktop-core.cjs +40 -1
- package/dist/index.cjs +40 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +40 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -831,6 +831,14 @@ declare class ModelSelector {
|
|
|
831
831
|
* Absent for a provider ⇒ no validation ran ⇒ behave exactly as before.
|
|
832
832
|
*/
|
|
833
833
|
private validatedIds;
|
|
834
|
+
/**
|
|
835
|
+
* Normalized ids that were added via discovery/registration but aren't in the
|
|
836
|
+
* bundled catalog — i.e. genuinely new models the provider reported (a Gemini
|
|
837
|
+
* flash released after the catalog was last hand-updated, an Ollama tag, etc.).
|
|
838
|
+
* getCandidatesForTier lets these compete in AUTO ranking so a newer,
|
|
839
|
+
* better-value model isn't invisible until someone edits constants.ts.
|
|
840
|
+
*/
|
|
841
|
+
private discovered;
|
|
834
842
|
constructor(availableProviders: Set<ProviderType>);
|
|
835
843
|
addDynamicModel(model: ModelInfo): void;
|
|
836
844
|
/** Record the ids a provider's API actually serves (discovery). Empty ⇒ ignored. */
|
|
@@ -1344,6 +1352,13 @@ declare class CascadeRouter extends EventEmitter {
|
|
|
1344
1352
|
private providers;
|
|
1345
1353
|
private stats;
|
|
1346
1354
|
private tierModels;
|
|
1355
|
+
/**
|
|
1356
|
+
* Tiers the user pinned to a specific model in config (`models.tX` !== 'auto').
|
|
1357
|
+
* An explicit pin always wins over Cascade Auto — selectModelForSubtask never
|
|
1358
|
+
* re-selects a pinned tier per subtask. (tierModels is also filled with
|
|
1359
|
+
* auto-picked defaults, so it alone can't distinguish "pinned" from "default".)
|
|
1360
|
+
*/
|
|
1361
|
+
private explicitTierModels;
|
|
1347
1362
|
private config;
|
|
1348
1363
|
private sessionCostUsd;
|
|
1349
1364
|
private runTokens;
|
package/dist/index.d.ts
CHANGED
|
@@ -831,6 +831,14 @@ declare class ModelSelector {
|
|
|
831
831
|
* Absent for a provider ⇒ no validation ran ⇒ behave exactly as before.
|
|
832
832
|
*/
|
|
833
833
|
private validatedIds;
|
|
834
|
+
/**
|
|
835
|
+
* Normalized ids that were added via discovery/registration but aren't in the
|
|
836
|
+
* bundled catalog — i.e. genuinely new models the provider reported (a Gemini
|
|
837
|
+
* flash released after the catalog was last hand-updated, an Ollama tag, etc.).
|
|
838
|
+
* getCandidatesForTier lets these compete in AUTO ranking so a newer,
|
|
839
|
+
* better-value model isn't invisible until someone edits constants.ts.
|
|
840
|
+
*/
|
|
841
|
+
private discovered;
|
|
834
842
|
constructor(availableProviders: Set<ProviderType>);
|
|
835
843
|
addDynamicModel(model: ModelInfo): void;
|
|
836
844
|
/** Record the ids a provider's API actually serves (discovery). Empty ⇒ ignored. */
|
|
@@ -1344,6 +1352,13 @@ declare class CascadeRouter extends EventEmitter {
|
|
|
1344
1352
|
private providers;
|
|
1345
1353
|
private stats;
|
|
1346
1354
|
private tierModels;
|
|
1355
|
+
/**
|
|
1356
|
+
* Tiers the user pinned to a specific model in config (`models.tX` !== 'auto').
|
|
1357
|
+
* An explicit pin always wins over Cascade Auto — selectModelForSubtask never
|
|
1358
|
+
* re-selects a pinned tier per subtask. (tierModels is also filled with
|
|
1359
|
+
* auto-picked defaults, so it alone can't distinguish "pinned" from "default".)
|
|
1360
|
+
*/
|
|
1361
|
+
private explicitTierModels;
|
|
1347
1362
|
private config;
|
|
1348
1363
|
private sessionCostUsd;
|
|
1349
1364
|
private runTokens;
|
package/dist/index.js
CHANGED
|
@@ -193,7 +193,7 @@ var init_audit_logger = __esm({
|
|
|
193
193
|
});
|
|
194
194
|
|
|
195
195
|
// src/constants.ts
|
|
196
|
-
var CASCADE_VERSION = "0.
|
|
196
|
+
var CASCADE_VERSION = "0.46.0";
|
|
197
197
|
var CASCADE_CONFIG_DIR = ".cascade";
|
|
198
198
|
var CASCADE_MD_FILE = "CASCADE.md";
|
|
199
199
|
var CASCADE_IGNORE_FILE = ".cascadeignore";
|
|
@@ -1797,12 +1797,21 @@ var ModelSelector = class {
|
|
|
1797
1797
|
* Absent for a provider ⇒ no validation ran ⇒ behave exactly as before.
|
|
1798
1798
|
*/
|
|
1799
1799
|
validatedIds = /* @__PURE__ */ new Map();
|
|
1800
|
+
/**
|
|
1801
|
+
* Normalized ids that were added via discovery/registration but aren't in the
|
|
1802
|
+
* bundled catalog — i.e. genuinely new models the provider reported (a Gemini
|
|
1803
|
+
* flash released after the catalog was last hand-updated, an Ollama tag, etc.).
|
|
1804
|
+
* getCandidatesForTier lets these compete in AUTO ranking so a newer,
|
|
1805
|
+
* better-value model isn't invisible until someone edits constants.ts.
|
|
1806
|
+
*/
|
|
1807
|
+
discovered = /* @__PURE__ */ new Set();
|
|
1800
1808
|
constructor(availableProviders) {
|
|
1801
1809
|
this.availableProviders = availableProviders;
|
|
1802
1810
|
this.availableModels = new Map(Object.entries(MODELS));
|
|
1803
1811
|
}
|
|
1804
1812
|
addDynamicModel(model) {
|
|
1805
1813
|
this.availableModels.set(model.id, model);
|
|
1814
|
+
if (!(model.id in MODELS)) this.discovered.add(normalizeModelId(model.id));
|
|
1806
1815
|
}
|
|
1807
1816
|
/** Record the ids a provider's API actually serves (discovery). Empty ⇒ ignored. */
|
|
1808
1817
|
setValidatedModels(provider, ids) {
|
|
@@ -1910,6 +1919,19 @@ var ModelSelector = class {
|
|
|
1910
1919
|
candidates.push(model);
|
|
1911
1920
|
}
|
|
1912
1921
|
}
|
|
1922
|
+
if (this.discovered.size) {
|
|
1923
|
+
const tierProviders = /* @__PURE__ */ new Set();
|
|
1924
|
+
for (const key of priority) {
|
|
1925
|
+
const m = MODELS[key];
|
|
1926
|
+
if (m) tierProviders.add(m.provider);
|
|
1927
|
+
}
|
|
1928
|
+
const have = new Set(candidates.map((c) => c.id));
|
|
1929
|
+
for (const model of this.availableModels.values()) {
|
|
1930
|
+
if (have.has(model.id)) continue;
|
|
1931
|
+
if (!this.discovered.has(normalizeModelId(model.id))) continue;
|
|
1932
|
+
if (tierProviders.has(model.provider) && this.isUsable(model)) candidates.push(model);
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1913
1935
|
const localOnly = this.availableProviders.size > 0 && Array.from(this.availableProviders).every((p) => p === "ollama");
|
|
1914
1936
|
if (localOnly) {
|
|
1915
1937
|
for (const model of this.availableModels.values()) {
|
|
@@ -2626,6 +2648,14 @@ var FAMILY_MATCHERS = [
|
|
|
2626
2648
|
[/gemini-?1\.5-pro/i, "gemini-1.5-pro"],
|
|
2627
2649
|
[/gemini-?2\.0-flash-lite/i, "gemini-flash-lite"],
|
|
2628
2650
|
[/gemini-?2\.0-flash/i, "gemini-2.0-flash"],
|
|
2651
|
+
// Generic Gemini fallbacks — a model released after this table was written
|
|
2652
|
+
// (e.g. a Gemini 3.x flash discovered live from the provider) still gets a
|
|
2653
|
+
// sensible score by its class instead of a neutral 0.5, so it can compete in
|
|
2654
|
+
// AUTO ranking. Ordered after the specific rows above; most-specific first.
|
|
2655
|
+
[/gemini.*flash.?lite/i, "gemini-flash-lite"],
|
|
2656
|
+
[/gemini.*pro/i, "gemini-2.5-pro"],
|
|
2657
|
+
[/gemini.*flash/i, "gemini-2.5-flash"],
|
|
2658
|
+
[/gemini/i, "gemini-2.5-flash"],
|
|
2629
2659
|
[/codellama|code-llama|starcoder|stable-code/i, "codellama"],
|
|
2630
2660
|
[/deepseek/i, "deepseek"],
|
|
2631
2661
|
[/qwen/i, "qwen"],
|
|
@@ -2717,6 +2747,13 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter {
|
|
|
2717
2747
|
costByFeature: {}
|
|
2718
2748
|
};
|
|
2719
2749
|
tierModels = /* @__PURE__ */ new Map();
|
|
2750
|
+
/**
|
|
2751
|
+
* Tiers the user pinned to a specific model in config (`models.tX` !== 'auto').
|
|
2752
|
+
* An explicit pin always wins over Cascade Auto — selectModelForSubtask never
|
|
2753
|
+
* re-selects a pinned tier per subtask. (tierModels is also filled with
|
|
2754
|
+
* auto-picked defaults, so it alone can't distinguish "pinned" from "default".)
|
|
2755
|
+
*/
|
|
2756
|
+
explicitTierModels = /* @__PURE__ */ new Set();
|
|
2720
2757
|
config;
|
|
2721
2758
|
sessionCostUsd = 0;
|
|
2722
2759
|
// Per-run accounting for the hard per-task cap. Reset by beginRun() at the
|
|
@@ -2794,6 +2831,7 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter {
|
|
|
2794
2831
|
);
|
|
2795
2832
|
}
|
|
2796
2833
|
this.tierModels.set(tier, model);
|
|
2834
|
+
this.explicitTierModels.add(tier);
|
|
2797
2835
|
this.ensureProvider(model, config.providers);
|
|
2798
2836
|
}
|
|
2799
2837
|
const azureRanked = [...azureDeployments].sort((a, b) => inferModelCapability(b.id) - inferModelCapability(a.id));
|
|
@@ -3234,6 +3272,7 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter {
|
|
|
3234
3272
|
* Pure heuristic — no extra LLM call.
|
|
3235
3273
|
*/
|
|
3236
3274
|
async selectModelForSubtask(tier, text, opts) {
|
|
3275
|
+
if (this.explicitTierModels.has(tier)) return this.tierModels.get(tier) ?? null;
|
|
3237
3276
|
if (!this.config?.cascadeAuto || !this.taskAnalyzer || !text.trim()) return null;
|
|
3238
3277
|
try {
|
|
3239
3278
|
return await this.taskAnalyzer.selectModel(text, tier, this.selector, opts);
|