cascade-ai 0.47.0 → 0.48.1
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/README.md +3 -3
- package/dist/cli.cjs +96 -13
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +96 -13
- package/dist/cli.js.map +1 -1
- package/dist/desktop-core.cjs +86 -13
- package/dist/index.cjs +86 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +86 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
[](https://www.npmjs.com/package/cascade-ai)
|
|
7
7
|
[](LICENSE)
|
|
8
|
-
[](#installation)
|
|
9
9
|
[](#ai-providers)
|
|
10
10
|
[](CONTRIBUTING.md)
|
|
11
11
|
|
|
@@ -227,7 +227,7 @@ User prompt
|
|
|
227
227
|
npm install -g cascade-ai
|
|
228
228
|
```
|
|
229
229
|
|
|
230
|
-
> Requires **Node.js ≥
|
|
230
|
+
> Requires **Node.js ≥ 22**.
|
|
231
231
|
|
|
232
232
|
---
|
|
233
233
|
|
|
@@ -797,7 +797,7 @@ web/
|
|
|
797
797
|
|
|
798
798
|
| Tool | Required Version |
|
|
799
799
|
|------|-----------------|
|
|
800
|
-
| Node.js | ≥
|
|
800
|
+
| Node.js | ≥ 22.x |
|
|
801
801
|
| npm | ≥ 10.x |
|
|
802
802
|
|
|
803
803
|
### Setup
|
package/dist/cli.cjs
CHANGED
|
@@ -116,7 +116,7 @@ var __export = (target, all) => {
|
|
|
116
116
|
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;
|
|
117
117
|
var init_constants = __esm({
|
|
118
118
|
"src/constants.ts"() {
|
|
119
|
-
CASCADE_VERSION = "0.
|
|
119
|
+
CASCADE_VERSION = "0.48.1";
|
|
120
120
|
CASCADE_CONFIG_FILE = ".cascade/config.json";
|
|
121
121
|
CASCADE_DB_FILE = ".cascade/memory.db";
|
|
122
122
|
CASCADE_DASHBOARD_SECRET_FILE = ".cascade/dashboard-secret";
|
|
@@ -595,6 +595,60 @@ var init_base = __esm({
|
|
|
595
595
|
}
|
|
596
596
|
});
|
|
597
597
|
|
|
598
|
+
// src/providers/model-filter.ts
|
|
599
|
+
function isChatModel(id, methods) {
|
|
600
|
+
if (methods && methods.length > 0) {
|
|
601
|
+
const canGenerate = methods.some((m) => /generatecontent|generatemessage|chat|completion/i.test(m));
|
|
602
|
+
if (!canGenerate) return false;
|
|
603
|
+
}
|
|
604
|
+
return !NON_CHAT.test(id);
|
|
605
|
+
}
|
|
606
|
+
var NON_CHAT_PATTERNS, NON_CHAT;
|
|
607
|
+
var init_model_filter = __esm({
|
|
608
|
+
"src/providers/model-filter.ts"() {
|
|
609
|
+
NON_CHAT_PATTERNS = [
|
|
610
|
+
"embed",
|
|
611
|
+
// text-embedding-3, nomic-embed, mxbai-embed, snowflake-arctic-embed
|
|
612
|
+
"(?:^|[-_/])tts(?:[-_/]|$)",
|
|
613
|
+
"text-to-speech",
|
|
614
|
+
"speech",
|
|
615
|
+
// text-to-speech
|
|
616
|
+
"whisper",
|
|
617
|
+
"transcrib",
|
|
618
|
+
"(?:^|[-_/])stt(?:[-_/]|$)",
|
|
619
|
+
// speech-to-text
|
|
620
|
+
"dall[-]?e",
|
|
621
|
+
"imagen",
|
|
622
|
+
"image-generation",
|
|
623
|
+
"gpt-image",
|
|
624
|
+
"(?:^|[-_/])image(?:[-_/]|$)",
|
|
625
|
+
"stable-diffusion",
|
|
626
|
+
"sdxl",
|
|
627
|
+
"flux",
|
|
628
|
+
// image gen
|
|
629
|
+
"moderation",
|
|
630
|
+
"(?:^|[-_/])guard(?:[-_/]|$)",
|
|
631
|
+
// moderation / safety
|
|
632
|
+
"rerank",
|
|
633
|
+
"(?:^|[-_/])audio(?:[-_/]|$)",
|
|
634
|
+
"native-audio",
|
|
635
|
+
"realtime",
|
|
636
|
+
// audio / realtime
|
|
637
|
+
"veo",
|
|
638
|
+
"sora",
|
|
639
|
+
"(?:^|[-_/])video(?:[-_/]|$)",
|
|
640
|
+
// video
|
|
641
|
+
"(?:^|[-_/])aqa(?:[-_/]|$)",
|
|
642
|
+
// attributed QA
|
|
643
|
+
"(?:^|[-_/])live(?:[-_/]|$)",
|
|
644
|
+
// live-audio variants
|
|
645
|
+
"(?:^|[-_/])(?:davinci|babbage)(?:[-_/]|$)"
|
|
646
|
+
// legacy completion-only base models
|
|
647
|
+
];
|
|
648
|
+
NON_CHAT = new RegExp(NON_CHAT_PATTERNS.join("|"), "i");
|
|
649
|
+
}
|
|
650
|
+
});
|
|
651
|
+
|
|
598
652
|
// src/providers/anthropic.ts
|
|
599
653
|
var anthropic_exports = {};
|
|
600
654
|
__export(anthropic_exports, {
|
|
@@ -611,6 +665,7 @@ var init_anthropic = __esm({
|
|
|
611
665
|
"src/providers/anthropic.ts"() {
|
|
612
666
|
init_constants();
|
|
613
667
|
init_base();
|
|
668
|
+
init_model_filter();
|
|
614
669
|
AnthropicProvider = class extends BaseProvider {
|
|
615
670
|
client;
|
|
616
671
|
constructor(config, model) {
|
|
@@ -717,7 +772,7 @@ var init_anthropic = __esm({
|
|
|
717
772
|
if (!Array.isArray(data?.data)) {
|
|
718
773
|
return Object.values(MODELS).filter((m) => m.provider === "anthropic");
|
|
719
774
|
}
|
|
720
|
-
return data.data.map((m) => {
|
|
775
|
+
return data.data.filter((m) => isChatModel(m.id)).map((m) => {
|
|
721
776
|
const known = Object.values(MODELS).find((km) => km.id === m.id && km.provider === "anthropic");
|
|
722
777
|
if (known) return known;
|
|
723
778
|
return {
|
|
@@ -826,6 +881,7 @@ var init_openai = __esm({
|
|
|
826
881
|
"src/providers/openai.ts"() {
|
|
827
882
|
init_constants();
|
|
828
883
|
init_base();
|
|
884
|
+
init_model_filter();
|
|
829
885
|
OpenAIProvider = class extends BaseProvider {
|
|
830
886
|
client;
|
|
831
887
|
/** Once we learn (from the model id or an API error) that this deployment
|
|
@@ -947,7 +1003,7 @@ var init_openai = __esm({
|
|
|
947
1003
|
async listModels() {
|
|
948
1004
|
try {
|
|
949
1005
|
const response = await this.client.models.list();
|
|
950
|
-
return response.data.map((m) => {
|
|
1006
|
+
return response.data.filter((m) => isChatModel(m.id)).map((m) => {
|
|
951
1007
|
const known = Object.values(MODELS).find((km) => km.id === m.id && km.provider === "openai");
|
|
952
1008
|
if (known) return known;
|
|
953
1009
|
return {
|
|
@@ -1155,6 +1211,7 @@ var init_gemini = __esm({
|
|
|
1155
1211
|
"src/providers/gemini.ts"() {
|
|
1156
1212
|
init_constants();
|
|
1157
1213
|
init_base();
|
|
1214
|
+
init_model_filter();
|
|
1158
1215
|
GeminiProvider = class extends BaseProvider {
|
|
1159
1216
|
client;
|
|
1160
1217
|
constructor(config, model) {
|
|
@@ -1248,7 +1305,7 @@ var init_gemini = __esm({
|
|
|
1248
1305
|
if (!Array.isArray(data?.models)) {
|
|
1249
1306
|
return Object.values(MODELS).filter((m) => m.provider === "gemini");
|
|
1250
1307
|
}
|
|
1251
|
-
return data.models.map((m) => {
|
|
1308
|
+
return data.models.filter((m) => isChatModel(m.name.replace("models/", ""), m.supportedGenerationMethods)).map((m) => {
|
|
1252
1309
|
const id = m.name.replace("models/", "");
|
|
1253
1310
|
const known = Object.values(MODELS).find(
|
|
1254
1311
|
(km) => km.id === id && km.provider === "gemini"
|
|
@@ -1471,6 +1528,7 @@ var init_ollama = __esm({
|
|
|
1471
1528
|
init_constants();
|
|
1472
1529
|
init_net();
|
|
1473
1530
|
init_base();
|
|
1531
|
+
init_model_filter();
|
|
1474
1532
|
TOOL_CAPABLE_FAMILIES = [
|
|
1475
1533
|
"llama3.1",
|
|
1476
1534
|
"llama3.2",
|
|
@@ -1623,10 +1681,10 @@ var init_ollama = __esm({
|
|
|
1623
1681
|
const response = await fetch(`${this.baseUrl}/api/tags`);
|
|
1624
1682
|
if (!response.ok) return [];
|
|
1625
1683
|
const data = await response.json();
|
|
1626
|
-
const supportedKeywords = ["llama3", "llama2", "gemma", "mistral", "mixtral", "qwen", "phi3", "codellama", "deepseek", "llava", "starcoder", "stable-code"
|
|
1684
|
+
const supportedKeywords = ["llama3", "llama2", "gemma", "mistral", "mixtral", "qwen", "phi3", "codellama", "deepseek", "llava", "starcoder", "stable-code"];
|
|
1627
1685
|
const entries = data.models.filter((m) => {
|
|
1628
1686
|
const name = m.name.toLowerCase();
|
|
1629
|
-
return supportedKeywords.some((k) => name.includes(k));
|
|
1687
|
+
return supportedKeywords.some((k) => name.includes(k)) && isChatModel(name);
|
|
1630
1688
|
});
|
|
1631
1689
|
const shows = await Promise.all(entries.map((m) => this.showModel(m.name)));
|
|
1632
1690
|
return entries.map((m, i) => {
|
|
@@ -1726,6 +1784,7 @@ var OpenAICompatibleProvider;
|
|
|
1726
1784
|
var init_openai_compatible = __esm({
|
|
1727
1785
|
"src/providers/openai-compatible.ts"() {
|
|
1728
1786
|
init_openai();
|
|
1787
|
+
init_model_filter();
|
|
1729
1788
|
init_net();
|
|
1730
1789
|
OpenAICompatibleProvider = class extends OpenAIProvider {
|
|
1731
1790
|
constructor(config, model) {
|
|
@@ -1759,7 +1818,8 @@ var init_openai_compatible = __esm({
|
|
|
1759
1818
|
return typeof m === "string" ? m : void 0;
|
|
1760
1819
|
}).filter((x) => typeof x === "string" && x.length > 0);
|
|
1761
1820
|
if (ids.length === 0) return [this.model];
|
|
1762
|
-
|
|
1821
|
+
const chatIds = ids.filter((id) => isChatModel(id));
|
|
1822
|
+
return (chatIds.length ? chatIds : ids).map((id) => ({
|
|
1763
1823
|
id,
|
|
1764
1824
|
name: id,
|
|
1765
1825
|
provider: "openai-compatible",
|
|
@@ -14609,12 +14669,19 @@ var CloudClient = class _CloudClient {
|
|
|
14609
14669
|
);
|
|
14610
14670
|
await openUrl(authorizeUrl);
|
|
14611
14671
|
const code = await listener.waitForCode;
|
|
14612
|
-
|
|
14613
|
-
|
|
14614
|
-
|
|
14615
|
-
|
|
14616
|
-
|
|
14617
|
-
|
|
14672
|
+
let res;
|
|
14673
|
+
try {
|
|
14674
|
+
res = await fetch(this.url("/api/native/token"), {
|
|
14675
|
+
method: "POST",
|
|
14676
|
+
headers: { "Content-Type": "application/json" },
|
|
14677
|
+
body: JSON.stringify({ code, code_verifier: verifier })
|
|
14678
|
+
});
|
|
14679
|
+
} catch (err) {
|
|
14680
|
+
throw new Error(
|
|
14681
|
+
`Signed in, but could not reach Cascade at ${this.serverUrl} to finish. Check your connection and that the server URL is correct. (${err instanceof Error ? err.message : String(err)})`
|
|
14682
|
+
);
|
|
14683
|
+
}
|
|
14684
|
+
if (!res.ok) throw new Error(await loginFailureMessage(res, this.serverUrl));
|
|
14618
14685
|
const tokens = await res.json();
|
|
14619
14686
|
return await this.finishLogin(tokens);
|
|
14620
14687
|
} finally {
|
|
@@ -14788,6 +14855,22 @@ function sleep(ms, signal) {
|
|
|
14788
14855
|
}, { once: true });
|
|
14789
14856
|
});
|
|
14790
14857
|
}
|
|
14858
|
+
async function loginFailureMessage(res, serverUrl) {
|
|
14859
|
+
const body = await res.text().catch(() => "");
|
|
14860
|
+
let apiError = "";
|
|
14861
|
+
try {
|
|
14862
|
+
apiError = String(JSON.parse(body).error ?? "");
|
|
14863
|
+
} catch {
|
|
14864
|
+
}
|
|
14865
|
+
if (apiError === "invalid_grant") {
|
|
14866
|
+
return "Sign-in expired before it completed \u2014 the code is single-use and short-lived, and restarting the server during sign-in also invalidates it. Please try again.";
|
|
14867
|
+
}
|
|
14868
|
+
if (apiError) return `Sign-in failed: ${apiError} (HTTP ${res.status}).`;
|
|
14869
|
+
if (res.status === 404 || /<html/i.test(body)) {
|
|
14870
|
+
return `Signed in, but ${serverUrl} did not answer the Cascade API (HTTP ${res.status}). If this host was recently pointed at a new server, DNS may still be propagating.`;
|
|
14871
|
+
}
|
|
14872
|
+
return `Sign-in could not be completed (HTTP ${res.status}). Please try again.`;
|
|
14873
|
+
}
|
|
14791
14874
|
function base64url(buf) {
|
|
14792
14875
|
return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
14793
14876
|
}
|