cascade-ai 0.12.7 → 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.js
CHANGED
|
@@ -54,7 +54,7 @@ var __export = (target, all) => {
|
|
|
54
54
|
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;
|
|
55
55
|
var init_constants = __esm({
|
|
56
56
|
"src/constants.ts"() {
|
|
57
|
-
CASCADE_VERSION = "0.12.
|
|
57
|
+
CASCADE_VERSION = "0.12.8";
|
|
58
58
|
CASCADE_CONFIG_FILE = ".cascade/config.json";
|
|
59
59
|
CASCADE_DB_FILE = ".cascade/memory.db";
|
|
60
60
|
CASCADE_DASHBOARD_SECRET_FILE = ".cascade/dashboard-secret";
|
|
@@ -3322,6 +3322,7 @@ var ModelSelector = class {
|
|
|
3322
3322
|
if (lower.includes("claude")) providerStr = "anthropic";
|
|
3323
3323
|
else if (lower.startsWith("gpt") || lower.startsWith("o1") || lower.startsWith("o3")) providerStr = "openai";
|
|
3324
3324
|
else if (lower.includes("gemini")) providerStr = "gemini";
|
|
3325
|
+
else if ((lower.endsWith(".gguf") || actualId.includes("/") || actualId.includes("\\")) && this.availableProviders.has("openai-compatible")) providerStr = "openai-compatible";
|
|
3325
3326
|
else if (this.availableProviders.has("ollama")) providerStr = "ollama";
|
|
3326
3327
|
else if (this.availableProviders.has("openai-compatible")) providerStr = "openai-compatible";
|
|
3327
3328
|
else if (this.availableProviders.size === 1) providerStr = Array.from(this.availableProviders)[0];
|
|
@@ -4004,6 +4005,11 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter {
|
|
|
4004
4005
|
if (availableProviders.has("ollama")) {
|
|
4005
4006
|
await this.discoverOllamaModels(ollamaCfg);
|
|
4006
4007
|
}
|
|
4008
|
+
if (availableProviders.has("openai-compatible")) {
|
|
4009
|
+
await Promise.all(
|
|
4010
|
+
config.providers.filter((p) => p.type === "openai-compatible").map((cfg) => this.discoverOpenAICompatibleModels(cfg))
|
|
4011
|
+
);
|
|
4012
|
+
}
|
|
4007
4013
|
for (const tier of ["T1", "T2", "T3"]) {
|
|
4008
4014
|
const override = tier === "T1" ? config.models.t1 : tier === "T2" ? config.models.t2 : config.models.t3;
|
|
4009
4015
|
if (!override || override === "auto") continue;
|
|
@@ -4435,6 +4441,14 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter {
|
|
|
4435
4441
|
getModelsForProvider(provider) {
|
|
4436
4442
|
return this.selector.getAvailableModelsForProvider(provider);
|
|
4437
4443
|
}
|
|
4444
|
+
/**
|
|
4445
|
+
* Every model available across the configured + reachable providers, after
|
|
4446
|
+
* discovery (Ollama tags, OpenAI-compatible/llama.cpp models, cloud catalog).
|
|
4447
|
+
* Used to populate the desktop model pickers with the user's real models.
|
|
4448
|
+
*/
|
|
4449
|
+
getAvailableModels() {
|
|
4450
|
+
return this.selector?.getAllAvailableModels() ?? [];
|
|
4451
|
+
}
|
|
4438
4452
|
// ── Private ──────────────────────────────────
|
|
4439
4453
|
async detectAvailableProviders(configs) {
|
|
4440
4454
|
const available = /* @__PURE__ */ new Set();
|
|
@@ -4465,6 +4479,28 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter {
|
|
|
4465
4479
|
} catch {
|
|
4466
4480
|
}
|
|
4467
4481
|
}
|
|
4482
|
+
async discoverOpenAICompatibleModels(cfg) {
|
|
4483
|
+
try {
|
|
4484
|
+
const seed = {
|
|
4485
|
+
id: "openai-compatible",
|
|
4486
|
+
name: "openai-compatible",
|
|
4487
|
+
provider: "openai-compatible",
|
|
4488
|
+
contextWindow: 32e3,
|
|
4489
|
+
isVisionCapable: false,
|
|
4490
|
+
inputCostPer1kTokens: 0,
|
|
4491
|
+
outputCostPer1kTokens: 0,
|
|
4492
|
+
maxOutputTokens: 4e3,
|
|
4493
|
+
supportsStreaming: true,
|
|
4494
|
+
isLocal: false
|
|
4495
|
+
};
|
|
4496
|
+
const provider = new OpenAICompatibleProvider(cfg, seed);
|
|
4497
|
+
const models = await provider.listModels();
|
|
4498
|
+
for (const m of models) {
|
|
4499
|
+
this.selector.addDynamicModel(m);
|
|
4500
|
+
}
|
|
4501
|
+
} catch {
|
|
4502
|
+
}
|
|
4503
|
+
}
|
|
4468
4504
|
ensureProvider(model, configs) {
|
|
4469
4505
|
const key = `${model.provider}:${model.id}`;
|
|
4470
4506
|
if (this.providers.has(key)) return;
|
|
@@ -4494,7 +4530,23 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter {
|
|
|
4494
4530
|
}
|
|
4495
4531
|
}
|
|
4496
4532
|
getAnyModelForProvider(type) {
|
|
4497
|
-
|
|
4533
|
+
const fromCatalog = Object.values(MODELS).find((m) => m.provider === type);
|
|
4534
|
+
if (fromCatalog) return fromCatalog;
|
|
4535
|
+
if (type === "openai-compatible" || type === "azure") {
|
|
4536
|
+
return {
|
|
4537
|
+
id: type,
|
|
4538
|
+
name: type,
|
|
4539
|
+
provider: type,
|
|
4540
|
+
contextWindow: 32e3,
|
|
4541
|
+
isVisionCapable: false,
|
|
4542
|
+
inputCostPer1kTokens: 0,
|
|
4543
|
+
outputCostPer1kTokens: 0,
|
|
4544
|
+
maxOutputTokens: 4e3,
|
|
4545
|
+
supportsStreaming: true,
|
|
4546
|
+
isLocal: false
|
|
4547
|
+
};
|
|
4548
|
+
}
|
|
4549
|
+
return void 0;
|
|
4498
4550
|
}
|
|
4499
4551
|
recordStats(tier, model, usage) {
|
|
4500
4552
|
this.stats.totalTokens += usage.totalTokens;
|
|
@@ -10363,7 +10415,11 @@ ${last.partialOutput}` : "");
|
|
|
10363
10415
|
looksLikeConversational(prompt) {
|
|
10364
10416
|
const LOW_COMPLEXITY = [
|
|
10365
10417
|
/^(?:hi|hello|hey|thanks|thank you|ok|okay|yes|no|sure|got it|sounds good)\b/i,
|
|
10366
|
-
/^(?:what is|what are|list|show me|tell me|who is|where is|when is|how do i)\b/i,
|
|
10418
|
+
/^(?: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,
|
|
10419
|
+
// Self-identity / capability questions ("who are you", "what can you do",
|
|
10420
|
+
// "who made you") are pure conversation — never a multi-agent build.
|
|
10421
|
+
/^(?:who|what)\b.*\byou\b/i,
|
|
10422
|
+
/^what can you\b/i,
|
|
10367
10423
|
/\b(?:simple|quick|brief|small|single|one-line|typo|rename)\b/i
|
|
10368
10424
|
];
|
|
10369
10425
|
const wordCount = prompt.trim().split(/\s+/).length;
|
|
@@ -10461,10 +10517,16 @@ ${prompt}` : prompt;
|
|
|
10461
10517
|
temperature: 0
|
|
10462
10518
|
});
|
|
10463
10519
|
const content = result.content.trim();
|
|
10464
|
-
const
|
|
10520
|
+
const match = content.toLowerCase().match(/\b(simple|moderate|complex)\b/);
|
|
10465
10521
|
const reason = content.replace(/^\S+\s*[—–-]*\s*/, "").trim();
|
|
10466
|
-
|
|
10467
|
-
|
|
10522
|
+
let verdict;
|
|
10523
|
+
if (match) {
|
|
10524
|
+
verdict = match[1] === "simple" ? "Simple" : match[1] === "moderate" ? "Moderate" : "Complex";
|
|
10525
|
+
this.recordDecision("complexity", `${verdict} \u2014 classifier: ${reason || "no reason given"}`);
|
|
10526
|
+
} else {
|
|
10527
|
+
verdict = prompt.trim().split(/\s+/).length <= 12 ? "Simple" : "Moderate";
|
|
10528
|
+
this.recordDecision("complexity", `${verdict} \u2014 classifier output unparseable; defaulted by length`);
|
|
10529
|
+
}
|
|
10468
10530
|
return verdict;
|
|
10469
10531
|
} catch {
|
|
10470
10532
|
const followUpPrompt = /^(proceed|continue|go ahead|do it|yes|yep|ok|okay|carry on)$/i.test(prompt.trim());
|
|
@@ -13873,7 +13935,8 @@ function SetupWizard({ workspacePath, onComplete }) {
|
|
|
13873
13935
|
) })
|
|
13874
13936
|
] });
|
|
13875
13937
|
}
|
|
13876
|
-
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`;
|
|
13938
|
+
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`;
|
|
13939
|
+
const keyOptional = isCompat && fieldStage === "apiKey";
|
|
13877
13940
|
const isMasked = fieldStage === "apiKey" && !isOllama;
|
|
13878
13941
|
return /* @__PURE__ */ jsxs(Frame, { theme, phase: "keys", children: [
|
|
13879
13942
|
doneEntries.length > 0 && /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginBottom: 1, children: doneEntries.map((e) => /* @__PURE__ */ jsxs(Box, { children: [
|
|
@@ -13891,8 +13954,8 @@ function SetupWizard({ workspacePath, onComplete }) {
|
|
|
13891
13954
|
{
|
|
13892
13955
|
theme,
|
|
13893
13956
|
label: prompt,
|
|
13894
|
-
tag: isOllama ? "optional \u2014 Enter for default" : "required",
|
|
13895
|
-
tagColor: isOllama ? theme.colors.muted : theme.colors.error,
|
|
13957
|
+
tag: isOllama ? "optional \u2014 Enter for default" : keyOptional ? "optional \u2014 Enter to skip" : "required",
|
|
13958
|
+
tagColor: isOllama || keyOptional ? theme.colors.muted : theme.colors.error,
|
|
13896
13959
|
active: true,
|
|
13897
13960
|
children: /* @__PURE__ */ jsx(
|
|
13898
13961
|
SafeTextInput,
|