cascade-ai 0.12.6 → 0.12.8
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 +72 -9
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +72 -9
- package/dist/cli.js.map +1 -1
- package/dist/desktop-core.cjs +299101 -0
- package/dist/index.cjs +68 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +68 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -77,7 +77,7 @@ var cron__default = /*#__PURE__*/_interopDefault(cron);
|
|
|
77
77
|
|
|
78
78
|
|
|
79
79
|
// src/constants.ts
|
|
80
|
-
var CASCADE_VERSION = "0.12.
|
|
80
|
+
var CASCADE_VERSION = "0.12.8";
|
|
81
81
|
var CASCADE_CONFIG_DIR = ".cascade";
|
|
82
82
|
var CASCADE_MD_FILE = "CASCADE.md";
|
|
83
83
|
var CASCADE_IGNORE_FILE = ".cascadeignore";
|
|
@@ -1516,6 +1516,7 @@ var ModelSelector = class {
|
|
|
1516
1516
|
if (lower.includes("claude")) providerStr = "anthropic";
|
|
1517
1517
|
else if (lower.startsWith("gpt") || lower.startsWith("o1") || lower.startsWith("o3")) providerStr = "openai";
|
|
1518
1518
|
else if (lower.includes("gemini")) providerStr = "gemini";
|
|
1519
|
+
else if ((lower.endsWith(".gguf") || actualId.includes("/") || actualId.includes("\\")) && this.availableProviders.has("openai-compatible")) providerStr = "openai-compatible";
|
|
1519
1520
|
else if (this.availableProviders.has("ollama")) providerStr = "ollama";
|
|
1520
1521
|
else if (this.availableProviders.has("openai-compatible")) providerStr = "openai-compatible";
|
|
1521
1522
|
else if (this.availableProviders.size === 1) providerStr = Array.from(this.availableProviders)[0];
|
|
@@ -2203,6 +2204,11 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
|
|
|
2203
2204
|
if (availableProviders.has("ollama")) {
|
|
2204
2205
|
await this.discoverOllamaModels(ollamaCfg);
|
|
2205
2206
|
}
|
|
2207
|
+
if (availableProviders.has("openai-compatible")) {
|
|
2208
|
+
await Promise.all(
|
|
2209
|
+
config.providers.filter((p) => p.type === "openai-compatible").map((cfg) => this.discoverOpenAICompatibleModels(cfg))
|
|
2210
|
+
);
|
|
2211
|
+
}
|
|
2206
2212
|
for (const tier of ["T1", "T2", "T3"]) {
|
|
2207
2213
|
const override = tier === "T1" ? config.models.t1 : tier === "T2" ? config.models.t2 : config.models.t3;
|
|
2208
2214
|
if (!override || override === "auto") continue;
|
|
@@ -2634,6 +2640,14 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
|
|
|
2634
2640
|
getModelsForProvider(provider) {
|
|
2635
2641
|
return this.selector.getAvailableModelsForProvider(provider);
|
|
2636
2642
|
}
|
|
2643
|
+
/**
|
|
2644
|
+
* Every model available across the configured + reachable providers, after
|
|
2645
|
+
* discovery (Ollama tags, OpenAI-compatible/llama.cpp models, cloud catalog).
|
|
2646
|
+
* Used to populate the desktop model pickers with the user's real models.
|
|
2647
|
+
*/
|
|
2648
|
+
getAvailableModels() {
|
|
2649
|
+
return this.selector?.getAllAvailableModels() ?? [];
|
|
2650
|
+
}
|
|
2637
2651
|
// ── Private ──────────────────────────────────
|
|
2638
2652
|
async detectAvailableProviders(configs) {
|
|
2639
2653
|
const available = /* @__PURE__ */ new Set();
|
|
@@ -2664,6 +2678,28 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
|
|
|
2664
2678
|
} catch {
|
|
2665
2679
|
}
|
|
2666
2680
|
}
|
|
2681
|
+
async discoverOpenAICompatibleModels(cfg) {
|
|
2682
|
+
try {
|
|
2683
|
+
const seed = {
|
|
2684
|
+
id: "openai-compatible",
|
|
2685
|
+
name: "openai-compatible",
|
|
2686
|
+
provider: "openai-compatible",
|
|
2687
|
+
contextWindow: 32e3,
|
|
2688
|
+
isVisionCapable: false,
|
|
2689
|
+
inputCostPer1kTokens: 0,
|
|
2690
|
+
outputCostPer1kTokens: 0,
|
|
2691
|
+
maxOutputTokens: 4e3,
|
|
2692
|
+
supportsStreaming: true,
|
|
2693
|
+
isLocal: false
|
|
2694
|
+
};
|
|
2695
|
+
const provider = new OpenAICompatibleProvider(cfg, seed);
|
|
2696
|
+
const models = await provider.listModels();
|
|
2697
|
+
for (const m of models) {
|
|
2698
|
+
this.selector.addDynamicModel(m);
|
|
2699
|
+
}
|
|
2700
|
+
} catch {
|
|
2701
|
+
}
|
|
2702
|
+
}
|
|
2667
2703
|
ensureProvider(model, configs) {
|
|
2668
2704
|
const key = `${model.provider}:${model.id}`;
|
|
2669
2705
|
if (this.providers.has(key)) return;
|
|
@@ -2693,7 +2729,23 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
|
|
|
2693
2729
|
}
|
|
2694
2730
|
}
|
|
2695
2731
|
getAnyModelForProvider(type) {
|
|
2696
|
-
|
|
2732
|
+
const fromCatalog = Object.values(MODELS).find((m) => m.provider === type);
|
|
2733
|
+
if (fromCatalog) return fromCatalog;
|
|
2734
|
+
if (type === "openai-compatible" || type === "azure") {
|
|
2735
|
+
return {
|
|
2736
|
+
id: type,
|
|
2737
|
+
name: type,
|
|
2738
|
+
provider: type,
|
|
2739
|
+
contextWindow: 32e3,
|
|
2740
|
+
isVisionCapable: false,
|
|
2741
|
+
inputCostPer1kTokens: 0,
|
|
2742
|
+
outputCostPer1kTokens: 0,
|
|
2743
|
+
maxOutputTokens: 4e3,
|
|
2744
|
+
supportsStreaming: true,
|
|
2745
|
+
isLocal: false
|
|
2746
|
+
};
|
|
2747
|
+
}
|
|
2748
|
+
return void 0;
|
|
2697
2749
|
}
|
|
2698
2750
|
recordStats(tier, model, usage) {
|
|
2699
2751
|
this.stats.totalTokens += usage.totalTokens;
|
|
@@ -8834,7 +8886,11 @@ ${last.partialOutput}` : "");
|
|
|
8834
8886
|
looksLikeConversational(prompt) {
|
|
8835
8887
|
const LOW_COMPLEXITY = [
|
|
8836
8888
|
/^(?:hi|hello|hey|thanks|thank you|ok|okay|yes|no|sure|got it|sounds good)\b/i,
|
|
8837
|
-
/^(?:what is|what are|list|show me|tell me|who is|where is|when is|how do i)\b/i,
|
|
8889
|
+
/^(?:what is|what are|what'?s|list|show me|tell me|who is|who are|who'?re|where is|when is|how do i)\b/i,
|
|
8890
|
+
// Self-identity / capability questions ("who are you", "what can you do",
|
|
8891
|
+
// "who made you") are pure conversation — never a multi-agent build.
|
|
8892
|
+
/^(?:who|what)\b.*\byou\b/i,
|
|
8893
|
+
/^what can you\b/i,
|
|
8838
8894
|
/\b(?:simple|quick|brief|small|single|one-line|typo|rename)\b/i
|
|
8839
8895
|
];
|
|
8840
8896
|
const wordCount = prompt.trim().split(/\s+/).length;
|
|
@@ -8932,10 +8988,16 @@ ${prompt}` : prompt;
|
|
|
8932
8988
|
temperature: 0
|
|
8933
8989
|
});
|
|
8934
8990
|
const content = result.content.trim();
|
|
8935
|
-
const
|
|
8991
|
+
const match = content.toLowerCase().match(/\b(simple|moderate|complex)\b/);
|
|
8936
8992
|
const reason = content.replace(/^\S+\s*[—–-]*\s*/, "").trim();
|
|
8937
|
-
|
|
8938
|
-
|
|
8993
|
+
let verdict;
|
|
8994
|
+
if (match) {
|
|
8995
|
+
verdict = match[1] === "simple" ? "Simple" : match[1] === "moderate" ? "Moderate" : "Complex";
|
|
8996
|
+
this.recordDecision("complexity", `${verdict} \u2014 classifier: ${reason || "no reason given"}`);
|
|
8997
|
+
} else {
|
|
8998
|
+
verdict = prompt.trim().split(/\s+/).length <= 12 ? "Simple" : "Moderate";
|
|
8999
|
+
this.recordDecision("complexity", `${verdict} \u2014 classifier output unparseable; defaulted by length`);
|
|
9000
|
+
}
|
|
8939
9001
|
return verdict;
|
|
8940
9002
|
} catch {
|
|
8941
9003
|
const followUpPrompt = /^(proceed|continue|go ahead|do it|yes|yep|ok|okay|carry on)$/i.test(prompt.trim());
|