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/cli.cjs
CHANGED
|
@@ -101,7 +101,7 @@ var __export = (target, all) => {
|
|
|
101
101
|
var CASCADE_VERSION, CASCADE_CONFIG_FILE, CASCADE_DB_FILE, CASCADE_DASHBOARD_SECRET_FILE, GLOBAL_CONFIG_DIR, GLOBAL_DB_FILE, GLOBAL_KEYSTORE_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;
|
|
102
102
|
var init_constants = __esm({
|
|
103
103
|
"src/constants.ts"() {
|
|
104
|
-
CASCADE_VERSION = "0.12.
|
|
104
|
+
CASCADE_VERSION = "0.12.8";
|
|
105
105
|
CASCADE_CONFIG_FILE = ".cascade/config.json";
|
|
106
106
|
CASCADE_DB_FILE = ".cascade/memory.db";
|
|
107
107
|
CASCADE_DASHBOARD_SECRET_FILE = ".cascade/dashboard-secret";
|
|
@@ -3369,6 +3369,7 @@ var ModelSelector = class {
|
|
|
3369
3369
|
if (lower.includes("claude")) providerStr = "anthropic";
|
|
3370
3370
|
else if (lower.startsWith("gpt") || lower.startsWith("o1") || lower.startsWith("o3")) providerStr = "openai";
|
|
3371
3371
|
else if (lower.includes("gemini")) providerStr = "gemini";
|
|
3372
|
+
else if ((lower.endsWith(".gguf") || actualId.includes("/") || actualId.includes("\\")) && this.availableProviders.has("openai-compatible")) providerStr = "openai-compatible";
|
|
3372
3373
|
else if (this.availableProviders.has("ollama")) providerStr = "ollama";
|
|
3373
3374
|
else if (this.availableProviders.has("openai-compatible")) providerStr = "openai-compatible";
|
|
3374
3375
|
else if (this.availableProviders.size === 1) providerStr = Array.from(this.availableProviders)[0];
|
|
@@ -4051,6 +4052,11 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
|
|
|
4051
4052
|
if (availableProviders.has("ollama")) {
|
|
4052
4053
|
await this.discoverOllamaModels(ollamaCfg);
|
|
4053
4054
|
}
|
|
4055
|
+
if (availableProviders.has("openai-compatible")) {
|
|
4056
|
+
await Promise.all(
|
|
4057
|
+
config.providers.filter((p) => p.type === "openai-compatible").map((cfg) => this.discoverOpenAICompatibleModels(cfg))
|
|
4058
|
+
);
|
|
4059
|
+
}
|
|
4054
4060
|
for (const tier of ["T1", "T2", "T3"]) {
|
|
4055
4061
|
const override = tier === "T1" ? config.models.t1 : tier === "T2" ? config.models.t2 : config.models.t3;
|
|
4056
4062
|
if (!override || override === "auto") continue;
|
|
@@ -4482,6 +4488,14 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
|
|
|
4482
4488
|
getModelsForProvider(provider) {
|
|
4483
4489
|
return this.selector.getAvailableModelsForProvider(provider);
|
|
4484
4490
|
}
|
|
4491
|
+
/**
|
|
4492
|
+
* Every model available across the configured + reachable providers, after
|
|
4493
|
+
* discovery (Ollama tags, OpenAI-compatible/llama.cpp models, cloud catalog).
|
|
4494
|
+
* Used to populate the desktop model pickers with the user's real models.
|
|
4495
|
+
*/
|
|
4496
|
+
getAvailableModels() {
|
|
4497
|
+
return this.selector?.getAllAvailableModels() ?? [];
|
|
4498
|
+
}
|
|
4485
4499
|
// ── Private ──────────────────────────────────
|
|
4486
4500
|
async detectAvailableProviders(configs) {
|
|
4487
4501
|
const available = /* @__PURE__ */ new Set();
|
|
@@ -4512,6 +4526,28 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
|
|
|
4512
4526
|
} catch {
|
|
4513
4527
|
}
|
|
4514
4528
|
}
|
|
4529
|
+
async discoverOpenAICompatibleModels(cfg) {
|
|
4530
|
+
try {
|
|
4531
|
+
const seed = {
|
|
4532
|
+
id: "openai-compatible",
|
|
4533
|
+
name: "openai-compatible",
|
|
4534
|
+
provider: "openai-compatible",
|
|
4535
|
+
contextWindow: 32e3,
|
|
4536
|
+
isVisionCapable: false,
|
|
4537
|
+
inputCostPer1kTokens: 0,
|
|
4538
|
+
outputCostPer1kTokens: 0,
|
|
4539
|
+
maxOutputTokens: 4e3,
|
|
4540
|
+
supportsStreaming: true,
|
|
4541
|
+
isLocal: false
|
|
4542
|
+
};
|
|
4543
|
+
const provider = new OpenAICompatibleProvider(cfg, seed);
|
|
4544
|
+
const models = await provider.listModels();
|
|
4545
|
+
for (const m of models) {
|
|
4546
|
+
this.selector.addDynamicModel(m);
|
|
4547
|
+
}
|
|
4548
|
+
} catch {
|
|
4549
|
+
}
|
|
4550
|
+
}
|
|
4515
4551
|
ensureProvider(model, configs) {
|
|
4516
4552
|
const key = `${model.provider}:${model.id}`;
|
|
4517
4553
|
if (this.providers.has(key)) return;
|
|
@@ -4541,7 +4577,23 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
|
|
|
4541
4577
|
}
|
|
4542
4578
|
}
|
|
4543
4579
|
getAnyModelForProvider(type) {
|
|
4544
|
-
|
|
4580
|
+
const fromCatalog = Object.values(MODELS).find((m) => m.provider === type);
|
|
4581
|
+
if (fromCatalog) return fromCatalog;
|
|
4582
|
+
if (type === "openai-compatible" || type === "azure") {
|
|
4583
|
+
return {
|
|
4584
|
+
id: type,
|
|
4585
|
+
name: type,
|
|
4586
|
+
provider: type,
|
|
4587
|
+
contextWindow: 32e3,
|
|
4588
|
+
isVisionCapable: false,
|
|
4589
|
+
inputCostPer1kTokens: 0,
|
|
4590
|
+
outputCostPer1kTokens: 0,
|
|
4591
|
+
maxOutputTokens: 4e3,
|
|
4592
|
+
supportsStreaming: true,
|
|
4593
|
+
isLocal: false
|
|
4594
|
+
};
|
|
4595
|
+
}
|
|
4596
|
+
return void 0;
|
|
4545
4597
|
}
|
|
4546
4598
|
recordStats(tier, model, usage) {
|
|
4547
4599
|
this.stats.totalTokens += usage.totalTokens;
|
|
@@ -10410,7 +10462,11 @@ ${last.partialOutput}` : "");
|
|
|
10410
10462
|
looksLikeConversational(prompt) {
|
|
10411
10463
|
const LOW_COMPLEXITY = [
|
|
10412
10464
|
/^(?:hi|hello|hey|thanks|thank you|ok|okay|yes|no|sure|got it|sounds good)\b/i,
|
|
10413
|
-
/^(?:what is|what are|list|show me|tell me|who is|where is|when is|how do i)\b/i,
|
|
10465
|
+
/^(?: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,
|
|
10466
|
+
// Self-identity / capability questions ("who are you", "what can you do",
|
|
10467
|
+
// "who made you") are pure conversation — never a multi-agent build.
|
|
10468
|
+
/^(?:who|what)\b.*\byou\b/i,
|
|
10469
|
+
/^what can you\b/i,
|
|
10414
10470
|
/\b(?:simple|quick|brief|small|single|one-line|typo|rename)\b/i
|
|
10415
10471
|
];
|
|
10416
10472
|
const wordCount = prompt.trim().split(/\s+/).length;
|
|
@@ -10508,10 +10564,16 @@ ${prompt}` : prompt;
|
|
|
10508
10564
|
temperature: 0
|
|
10509
10565
|
});
|
|
10510
10566
|
const content = result.content.trim();
|
|
10511
|
-
const
|
|
10567
|
+
const match = content.toLowerCase().match(/\b(simple|moderate|complex)\b/);
|
|
10512
10568
|
const reason = content.replace(/^\S+\s*[—–-]*\s*/, "").trim();
|
|
10513
|
-
|
|
10514
|
-
|
|
10569
|
+
let verdict;
|
|
10570
|
+
if (match) {
|
|
10571
|
+
verdict = match[1] === "simple" ? "Simple" : match[1] === "moderate" ? "Moderate" : "Complex";
|
|
10572
|
+
this.recordDecision("complexity", `${verdict} \u2014 classifier: ${reason || "no reason given"}`);
|
|
10573
|
+
} else {
|
|
10574
|
+
verdict = prompt.trim().split(/\s+/).length <= 12 ? "Simple" : "Moderate";
|
|
10575
|
+
this.recordDecision("complexity", `${verdict} \u2014 classifier output unparseable; defaulted by length`);
|
|
10576
|
+
}
|
|
10515
10577
|
return verdict;
|
|
10516
10578
|
} catch {
|
|
10517
10579
|
const followUpPrompt = /^(proceed|continue|go ahead|do it|yes|yep|ok|okay|carry on)$/i.test(prompt.trim());
|
|
@@ -13920,7 +13982,8 @@ function SetupWizard({ workspacePath, onComplete }) {
|
|
|
13920
13982
|
) })
|
|
13921
13983
|
] });
|
|
13922
13984
|
}
|
|
13923
|
-
const prompt = isAzure && fieldStage === "deploymentName" ? `Azure deployment name (${currentEntry.label})` : isAzure && fieldStage === "baseUrl" ? `Azure endpoint URL` : isAzure && fieldStage === "apiKey" ? `${currentEntry.label} API Key` : isAzure && fieldStage === "apiVersion" ? `Azure API version (e.g. 2024-08-01-preview)` : isCompat && fieldStage === "label" ? `Name for this endpoint (e.g. Groq)` : isCompat && fieldStage === "baseUrl" ? `Base URL (e.g. https://api.groq.com/openai/v1)` : isOllama ? `Ollama URL` : `${currentEntry.label} API Key`;
|
|
13985
|
+
const prompt = isAzure && fieldStage === "deploymentName" ? `Azure deployment name (${currentEntry.label})` : isAzure && fieldStage === "baseUrl" ? `Azure endpoint URL` : isAzure && fieldStage === "apiKey" ? `${currentEntry.label} API Key` : isAzure && fieldStage === "apiVersion" ? `Azure API version (e.g. 2024-08-01-preview)` : isCompat && fieldStage === "label" ? `Name for this endpoint (e.g. Groq)` : isCompat && fieldStage === "baseUrl" ? `Base URL (e.g. https://api.groq.com/openai/v1)` : isCompat && fieldStage === "apiKey" ? `${currentEntry.label} API Key (optional)` : isOllama ? `Ollama URL` : `${currentEntry.label} API Key`;
|
|
13986
|
+
const keyOptional = isCompat && fieldStage === "apiKey";
|
|
13924
13987
|
const isMasked = fieldStage === "apiKey" && !isOllama;
|
|
13925
13988
|
return /* @__PURE__ */ jsxRuntime.jsxs(Frame, { theme, phase: "keys", children: [
|
|
13926
13989
|
doneEntries.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ink.Box, { flexDirection: "column", marginBottom: 1, children: doneEntries.map((e) => /* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { children: [
|
|
@@ -13938,8 +14001,8 @@ function SetupWizard({ workspacePath, onComplete }) {
|
|
|
13938
14001
|
{
|
|
13939
14002
|
theme,
|
|
13940
14003
|
label: prompt,
|
|
13941
|
-
tag: isOllama ? "optional \u2014 Enter for default" : "required",
|
|
13942
|
-
tagColor: isOllama ? theme.colors.muted : theme.colors.error,
|
|
14004
|
+
tag: isOllama ? "optional \u2014 Enter for default" : keyOptional ? "optional \u2014 Enter to skip" : "required",
|
|
14005
|
+
tagColor: isOllama || keyOptional ? theme.colors.muted : theme.colors.error,
|
|
13943
14006
|
active: true,
|
|
13944
14007
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
13945
14008
|
SafeTextInput,
|