cascade-ai 0.12.4 → 0.12.6

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.js CHANGED
@@ -40,50 +40,21 @@ import parser from 'socket.io-msgpack-parser';
40
40
  import jwt from 'jsonwebtoken';
41
41
 
42
42
  // Cascade AI — Multi-tier AI Orchestration System
43
- var __create = Object.create;
44
43
  var __defProp = Object.defineProperty;
45
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
46
44
  var __getOwnPropNames = Object.getOwnPropertyNames;
47
- var __getProtoOf = Object.getPrototypeOf;
48
- var __hasOwnProp = Object.prototype.hasOwnProperty;
49
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
50
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
51
- }) : x)(function(x) {
52
- if (typeof require !== "undefined") return require.apply(this, arguments);
53
- throw Error('Dynamic require of "' + x + '" is not supported');
54
- });
55
45
  var __esm = (fn, res) => function __init() {
56
46
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
57
47
  };
58
- var __commonJS = (cb, mod) => function __require2() {
59
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
60
- };
61
48
  var __export = (target, all) => {
62
49
  for (var name in all)
63
50
  __defProp(target, name, { get: all[name], enumerable: true });
64
51
  };
65
- var __copyProps = (to, from, except, desc) => {
66
- if (from && typeof from === "object" || typeof from === "function") {
67
- for (let key of __getOwnPropNames(from))
68
- if (!__hasOwnProp.call(to, key) && key !== except)
69
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
70
- }
71
- return to;
72
- };
73
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
74
- // If the importer is in node compatibility mode or this is not an ESM
75
- // file that has been converted to a CommonJS file using a Babel-
76
- // compatible transform (i.e. "__esModule" has not been set), then set
77
- // "default" to the CommonJS "module.exports" for node compatibility.
78
- __defProp(target, "default", { value: mod, enumerable: true }) ,
79
- mod
80
- ));
81
52
 
82
53
  // src/constants.ts
83
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;
84
55
  var init_constants = __esm({
85
56
  "src/constants.ts"() {
86
- CASCADE_VERSION = "0.9.6";
57
+ CASCADE_VERSION = "0.12.6";
87
58
  CASCADE_CONFIG_FILE = ".cascade/config.json";
88
59
  CASCADE_DB_FILE = ".cascade/memory.db";
89
60
  CASCADE_DASHBOARD_SECRET_FILE = ".cascade/dashboard-secret";
@@ -144,6 +115,30 @@ var init_constants = __esm({
144
115
  supportsStreaming: true,
145
116
  isLocal: false
146
117
  },
118
+ "claude-opus-4-8": {
119
+ id: "claude-opus-4-8",
120
+ name: "Claude Opus 4.8",
121
+ provider: "anthropic",
122
+ contextWindow: 2e5,
123
+ isVisionCapable: true,
124
+ inputCostPer1kTokens: 0.015,
125
+ outputCostPer1kTokens: 0.075,
126
+ maxOutputTokens: 32e3,
127
+ supportsStreaming: true,
128
+ isLocal: false
129
+ },
130
+ "claude-sonnet-4-6": {
131
+ id: "claude-sonnet-4-6",
132
+ name: "Claude Sonnet 4.6",
133
+ provider: "anthropic",
134
+ contextWindow: 2e5,
135
+ isVisionCapable: true,
136
+ inputCostPer1kTokens: 3e-3,
137
+ outputCostPer1kTokens: 0.015,
138
+ maxOutputTokens: 16e3,
139
+ supportsStreaming: true,
140
+ isLocal: false
141
+ },
147
142
  // OpenAI
148
143
  "gpt-4o": {
149
144
  id: "gpt-4o",
@@ -399,60 +394,26 @@ var init_constants = __esm({
399
394
  }
400
395
  });
401
396
 
402
- // node_modules/keytar/build/Release/keytar.node
403
- var keytar_default;
404
- var init_keytar = __esm({
405
- "node_modules/keytar/build/Release/keytar.node"() {
406
- keytar_default = "./keytar-VMICNFEJ.node";
407
- }
408
- });
409
-
410
- // node-file:/home/runner/work/Cascade-AI/Cascade-AI/node_modules/keytar/build/Release/keytar.node
411
- var require_keytar = __commonJS({
412
- "node-file:/home/runner/work/Cascade-AI/Cascade-AI/node_modules/keytar/build/Release/keytar.node"(exports, module) {
413
- init_keytar();
414
- try {
415
- module.exports = __require(keytar_default);
416
- } catch {
397
+ // src/utils/cost.ts
398
+ function resolveModelPricing(model) {
399
+ let input = model.inputCostPer1kTokens;
400
+ let output = model.outputCostPer1kTokens;
401
+ if (input === 0 && output === 0 && model.id && !model.isLocal) {
402
+ const known = Object.values(MODELS).find((m) => m.id === model.id && !m.isLocal);
403
+ if (known) {
404
+ input = known.inputCostPer1kTokens;
405
+ output = known.outputCostPer1kTokens;
417
406
  }
418
407
  }
419
- });
420
-
421
- // node_modules/keytar/lib/keytar.js
422
- var require_keytar2 = __commonJS({
423
- "node_modules/keytar/lib/keytar.js"(exports, module) {
424
- var keytar = require_keytar();
425
- function checkRequired(val, name) {
426
- if (!val || val.length <= 0) {
427
- throw new Error(name + " is required.");
428
- }
429
- }
430
- module.exports = {
431
- getPassword: function(service, account) {
432
- checkRequired(service, "Service");
433
- checkRequired(account, "Account");
434
- return keytar.getPassword(service, account);
435
- },
436
- setPassword: function(service, account, password) {
437
- checkRequired(service, "Service");
438
- checkRequired(account, "Account");
439
- checkRequired(password, "Password");
440
- return keytar.setPassword(service, account, password);
441
- },
442
- deletePassword: function(service, account) {
443
- checkRequired(service, "Service");
444
- checkRequired(account, "Account");
445
- return keytar.deletePassword(service, account);
446
- },
447
- findPassword: function(service) {
448
- checkRequired(service, "Service");
449
- return keytar.findPassword(service);
450
- },
451
- findCredentials: function(service) {
452
- checkRequired(service, "Service");
453
- return keytar.findCredentials(service);
454
- }
455
- };
408
+ return { input, output };
409
+ }
410
+ function calculateCost(inputTokens, outputTokens, model) {
411
+ const { input, output } = resolveModelPricing(model);
412
+ return inputTokens / 1e3 * input + outputTokens / 1e3 * output;
413
+ }
414
+ var init_cost = __esm({
415
+ "src/utils/cost.ts"() {
416
+ init_constants();
456
417
  }
457
418
  });
458
419
 
@@ -460,6 +421,7 @@ var require_keytar2 = __commonJS({
460
421
  var BaseProvider;
461
422
  var init_base = __esm({
462
423
  "src/providers/base.ts"() {
424
+ init_cost();
463
425
  BaseProvider = class {
464
426
  config;
465
427
  model;
@@ -474,7 +436,7 @@ var init_base = __esm({
474
436
  return this.model.isVisionCapable;
475
437
  }
476
438
  estimateCost(inputTokens, outputTokens) {
477
- return inputTokens / 1e3 * this.model.inputCostPer1kTokens + outputTokens / 1e3 * this.model.outputCostPer1kTokens;
439
+ return calculateCost(inputTokens, outputTokens, this.model);
478
440
  }
479
441
  makeUsage(inputTokens, outputTokens) {
480
442
  return {
@@ -1465,7 +1427,7 @@ var PBKDF2_ITERATIONS = 1e5;
1465
1427
  var KEYTAR_SERVICE = "cascade-ai";
1466
1428
  async function loadKeytar() {
1467
1429
  try {
1468
- const mod = await Promise.resolve().then(() => __toESM(require_keytar2(), 1));
1430
+ const mod = await import('keytar');
1469
1431
  const candidate = mod.default ?? mod;
1470
1432
  if (typeof candidate.getPassword !== "function") return null;
1471
1433
  return candidate;
@@ -3599,11 +3561,7 @@ var LocalRequestQueue = class {
3599
3561
 
3600
3562
  // src/core/router/index.ts
3601
3563
  init_constants();
3602
-
3603
- // src/utils/cost.ts
3604
- function calculateCost(inputTokens, outputTokens, model) {
3605
- return inputTokens / 1e3 * model.inputCostPer1kTokens + outputTokens / 1e3 * model.outputCostPer1kTokens;
3606
- }
3564
+ init_cost();
3607
3565
 
3608
3566
  // src/utils/retry.ts
3609
3567
  var CascadeCancelledError = class extends Error {
@@ -3721,6 +3679,7 @@ var ModelProfiler = class {
3721
3679
  };
3722
3680
 
3723
3681
  // src/core/router/savings.ts
3682
+ init_cost();
3724
3683
  var NO_SAVINGS = { savedUsd: 0, savedPct: 0, counterfactualUsd: 0 };
3725
3684
  function computeDelegationSavings(stats, t1Model) {
3726
3685
  if (!t1Model) return NO_SAVINGS;
@@ -5174,8 +5133,9 @@ var T3Worker = class extends BaseTier {
5174
5133
  const depOutputs = [];
5175
5134
  for (const depId of assignment.dependsOn) {
5176
5135
  try {
5177
- const dep = await this.peerBus.waitFor(depId);
5136
+ const dep = await this.peerBus.waitFor(depId, 6e4);
5178
5137
  if (dep.status === "FAILED" || dep.status === "ESCALATED") {
5138
+ this.peerBus.publish(this.id, assignment.subtaskId, `Blocked by failed dependency: ${depId}`, "FAILED");
5179
5139
  return this.buildResult(
5180
5140
  "ESCALATED",
5181
5141
  `Dependency ${depId} failed \u2014 cannot proceed`,
@@ -5187,6 +5147,7 @@ var T3Worker = class extends BaseTier {
5187
5147
  depOutputs.push(`[From ${dep.fromId} - ${dep.subtaskId}]:
5188
5148
  ${dep.output}`);
5189
5149
  } catch (err) {
5150
+ this.peerBus.publish(this.id, assignment.subtaskId, `Dependency timeout: ${depId}`, "FAILED");
5190
5151
  return this.buildResult(
5191
5152
  "ESCALATED",
5192
5153
  `Dependency timeout: ${depId}`,
@@ -6888,6 +6849,16 @@ function parseFirstJsonObject(input) {
6888
6849
  }
6889
6850
 
6890
6851
  // src/core/tiers/t1-administrator.ts
6852
+ function sharedKeywords(a = [], b = []) {
6853
+ const setB = new Set(b.map((k) => k.toLowerCase().trim()).filter(Boolean));
6854
+ return [...new Set(a.map((k) => k.toLowerCase().trim()).filter(Boolean))].filter((k) => setB.has(k));
6855
+ }
6856
+ function isStrongKeywordOverlap(a = [], b = []) {
6857
+ if (!a.length || !b.length) return false;
6858
+ const shared = sharedKeywords(a, b);
6859
+ const ratio = shared.length / Math.min(a.length, b.length);
6860
+ return shared.length >= 3 && ratio >= 0.6;
6861
+ }
6891
6862
  var T1_SYSTEM_PROMPT = `You are T1, the Administrator in the Cascade AI orchestration system.
6892
6863
 
6893
6864
  Your responsibilities:
@@ -7312,17 +7283,27 @@ Leave dependsOn empty for sections that can run immediately in parallel.`;
7312
7283
  siblingKeywords.set(payload.sectionId, [...new Set(existing)]);
7313
7284
  }
7314
7285
  }
7315
- const overlapSections = /* @__PURE__ */ new Set();
7316
- for (let i = 0; i < announcements.length; i++) {
7317
- for (let j = i + 1; j < announcements.length; j++) {
7318
- const a = announcements[i].payload;
7319
- const b = announcements[j].payload;
7320
- if (!a.keywords || !b.keywords || !a.sectionId || !b.sectionId) continue;
7321
- const shared = a.keywords.filter((k) => b.keywords.includes(k));
7322
- if (shared.length > 0) {
7323
- overlapSections.add(a.sectionId);
7324
- overlapSections.add(b.sectionId);
7325
- this.log(`T2 overlap detected between sections: ${a.sectionId} \u2194 ${b.sectionId} (shared: ${shared.join(", ")})`);
7286
+ const payloads = announcements.map((ann) => ann.payload).filter((p) => p?.type === "T2_PLAN_ANNOUNCEMENT" && !!p.sectionId);
7287
+ const softOverlap = /* @__PURE__ */ new Set();
7288
+ const orderOf = new Map(sections.map((s, i) => [s.sectionId, i]));
7289
+ for (let i = 0; i < payloads.length; i++) {
7290
+ for (let j = i + 1; j < payloads.length; j++) {
7291
+ const a = payloads[i];
7292
+ const b = payloads[j];
7293
+ const shared = sharedKeywords(a.keywords ?? [], b.keywords ?? []);
7294
+ if (shared.length === 0) continue;
7295
+ softOverlap.add(a.sectionId);
7296
+ softOverlap.add(b.sectionId);
7297
+ if (isStrongKeywordOverlap(a.keywords ?? [], b.keywords ?? [])) {
7298
+ const ai = orderOf.get(a.sectionId) ?? 0;
7299
+ const bi = orderOf.get(b.sectionId) ?? 0;
7300
+ const earlier = ai <= bi ? a.sectionId : b.sectionId;
7301
+ const later = ai <= bi ? b.sectionId : a.sectionId;
7302
+ const laterSection = sections.find((s) => s.sectionId === later);
7303
+ if (laterSection && earlier !== later && !(laterSection.dependsOn ?? []).includes(earlier)) {
7304
+ laterSection.dependsOn = [...laterSection.dependsOn || [], earlier];
7305
+ this.log(`Strong overlap ${earlier} \u2194 ${later} (shared: ${shared.slice(0, 5).join(", ")}) \u2014 serializing ${later} after ${earlier}`);
7306
+ }
7326
7307
  }
7327
7308
  }
7328
7309
  }
@@ -7334,20 +7315,10 @@ Leave dependsOn empty for sections that can run immediately in parallel.`;
7334
7315
  `You are T2 Manager for section: "${section.sectionTitle}".`,
7335
7316
  `Sibling sections being worked on in parallel: ${otherTitles.join(", ") || "none"}.`,
7336
7317
  myKeywords.length > 0 ? `Watch for overlap with: ${[...new Set(myKeywords)].slice(0, 10).join(", ")}.` : "",
7337
- overlapSections.has(section.sectionId) ? "NOTE: Potential overlap detected with a sibling section \u2014 be careful not to duplicate work." : ""
7318
+ softOverlap.has(section.sectionId) ? "NOTE: Potential overlap detected with a sibling section \u2014 be careful not to duplicate work." : ""
7338
7319
  ].filter(Boolean).join(" ");
7339
7320
  m.setHierarchyContext(context);
7340
7321
  });
7341
- if (overlapSections.size > 0) {
7342
- this.log("Overlap detected \u2014 adding sequential dependencies for conflicting sections to prevent race conditions");
7343
- const overlapArray = Array.from(overlapSections);
7344
- for (let i = 1; i < overlapArray.length; i++) {
7345
- const section = sections.find((s) => s.sectionId === overlapArray[i]);
7346
- if (section) {
7347
- section.dependsOn = [...section.dependsOn || [], overlapArray[i - 1]];
7348
- }
7349
- }
7350
- }
7351
7322
  const t2Results = [];
7352
7323
  try {
7353
7324
  t2Results.push(...await this.runT2sWithDependencies(sections, managers, this.taskId));
@@ -7542,6 +7513,9 @@ Reply with exactly one word: YES, NO, or UNSURE.
7542
7513
  }
7543
7514
  };
7544
7515
 
7516
+ // src/core/cascade.ts
7517
+ init_cost();
7518
+
7545
7519
  // src/tools/registry.ts
7546
7520
  init_constants();
7547
7521
 
@@ -14301,7 +14275,7 @@ async function doctorCommand() {
14301
14275
  });
14302
14276
  let keystoreBackend = "file (AES-256-GCM)";
14303
14277
  try {
14304
- await Promise.resolve().then(() => __toESM(require_keytar2(), 1));
14278
+ await import('keytar');
14305
14279
  keystoreBackend = "keytar (OS keychain)";
14306
14280
  } catch {
14307
14281
  }