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/index.cjs CHANGED
@@ -74,100 +74,10 @@ var jwt__default = /*#__PURE__*/_interopDefault(jwt);
74
74
  var cron__default = /*#__PURE__*/_interopDefault(cron);
75
75
 
76
76
  // Cascade AI — Multi-tier AI Orchestration System
77
- var __create = Object.create;
78
- var __defProp = Object.defineProperty;
79
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
80
- var __getOwnPropNames = Object.getOwnPropertyNames;
81
- var __getProtoOf = Object.getPrototypeOf;
82
- var __hasOwnProp = Object.prototype.hasOwnProperty;
83
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
84
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
85
- }) : x)(function(x) {
86
- if (typeof require !== "undefined") return require.apply(this, arguments);
87
- throw Error('Dynamic require of "' + x + '" is not supported');
88
- });
89
- var __esm = (fn, res) => function __init() {
90
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
91
- };
92
- var __commonJS = (cb, mod) => function __require2() {
93
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
94
- };
95
- var __copyProps = (to, from, except, desc) => {
96
- if (from && typeof from === "object" || typeof from === "function") {
97
- for (let key of __getOwnPropNames(from))
98
- if (!__hasOwnProp.call(to, key) && key !== except)
99
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
100
- }
101
- return to;
102
- };
103
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
104
- // If the importer is in node compatibility mode or this is not an ESM
105
- // file that has been converted to a CommonJS file using a Babel-
106
- // compatible transform (i.e. "__esModule" has not been set), then set
107
- // "default" to the CommonJS "module.exports" for node compatibility.
108
- __defProp(target, "default", { value: mod, enumerable: true }) ,
109
- mod
110
- ));
111
-
112
- // node_modules/keytar/build/Release/keytar.node
113
- var keytar_default;
114
- var init_keytar = __esm({
115
- "node_modules/keytar/build/Release/keytar.node"() {
116
- keytar_default = "./keytar-VMICNFEJ.node";
117
- }
118
- });
119
77
 
120
- // node-file:/home/runner/work/Cascade-AI/Cascade-AI/node_modules/keytar/build/Release/keytar.node
121
- var require_keytar = __commonJS({
122
- "node-file:/home/runner/work/Cascade-AI/Cascade-AI/node_modules/keytar/build/Release/keytar.node"(exports, module) {
123
- init_keytar();
124
- try {
125
- module.exports = __require(keytar_default);
126
- } catch {
127
- }
128
- }
129
- });
130
-
131
- // node_modules/keytar/lib/keytar.js
132
- var require_keytar2 = __commonJS({
133
- "node_modules/keytar/lib/keytar.js"(exports, module) {
134
- var keytar = require_keytar();
135
- function checkRequired(val, name) {
136
- if (!val || val.length <= 0) {
137
- throw new Error(name + " is required.");
138
- }
139
- }
140
- module.exports = {
141
- getPassword: function(service, account) {
142
- checkRequired(service, "Service");
143
- checkRequired(account, "Account");
144
- return keytar.getPassword(service, account);
145
- },
146
- setPassword: function(service, account, password) {
147
- checkRequired(service, "Service");
148
- checkRequired(account, "Account");
149
- checkRequired(password, "Password");
150
- return keytar.setPassword(service, account, password);
151
- },
152
- deletePassword: function(service, account) {
153
- checkRequired(service, "Service");
154
- checkRequired(account, "Account");
155
- return keytar.deletePassword(service, account);
156
- },
157
- findPassword: function(service) {
158
- checkRequired(service, "Service");
159
- return keytar.findPassword(service);
160
- },
161
- findCredentials: function(service) {
162
- checkRequired(service, "Service");
163
- return keytar.findCredentials(service);
164
- }
165
- };
166
- }
167
- });
168
78
 
169
79
  // src/constants.ts
170
- var CASCADE_VERSION = "0.9.6";
80
+ var CASCADE_VERSION = "0.12.6";
171
81
  var CASCADE_CONFIG_DIR = ".cascade";
172
82
  var CASCADE_MD_FILE = "CASCADE.md";
173
83
  var CASCADE_IGNORE_FILE = ".cascadeignore";
@@ -236,6 +146,30 @@ var MODELS = {
236
146
  supportsStreaming: true,
237
147
  isLocal: false
238
148
  },
149
+ "claude-opus-4-8": {
150
+ id: "claude-opus-4-8",
151
+ name: "Claude Opus 4.8",
152
+ provider: "anthropic",
153
+ contextWindow: 2e5,
154
+ isVisionCapable: true,
155
+ inputCostPer1kTokens: 0.015,
156
+ outputCostPer1kTokens: 0.075,
157
+ maxOutputTokens: 32e3,
158
+ supportsStreaming: true,
159
+ isLocal: false
160
+ },
161
+ "claude-sonnet-4-6": {
162
+ id: "claude-sonnet-4-6",
163
+ name: "Claude Sonnet 4.6",
164
+ provider: "anthropic",
165
+ contextWindow: 2e5,
166
+ isVisionCapable: true,
167
+ inputCostPer1kTokens: 3e-3,
168
+ outputCostPer1kTokens: 0.015,
169
+ maxOutputTokens: 16e3,
170
+ supportsStreaming: true,
171
+ isLocal: false
172
+ },
239
173
  // OpenAI
240
174
  "gpt-4o": {
241
175
  id: "gpt-4o",
@@ -497,6 +431,24 @@ var PROVIDER_DISPLAY_NAMES = {
497
431
  ollama: "Ollama (Local)"
498
432
  };
499
433
 
434
+ // src/utils/cost.ts
435
+ function resolveModelPricing(model) {
436
+ let input = model.inputCostPer1kTokens;
437
+ let output = model.outputCostPer1kTokens;
438
+ if (input === 0 && output === 0 && model.id && !model.isLocal) {
439
+ const known = Object.values(MODELS).find((m) => m.id === model.id && !m.isLocal);
440
+ if (known) {
441
+ input = known.inputCostPer1kTokens;
442
+ output = known.outputCostPer1kTokens;
443
+ }
444
+ }
445
+ return { input, output };
446
+ }
447
+ function calculateCost(inputTokens, outputTokens, model) {
448
+ const { input, output } = resolveModelPricing(model);
449
+ return inputTokens / 1e3 * input + outputTokens / 1e3 * output;
450
+ }
451
+
500
452
  // src/providers/base.ts
501
453
  var BaseProvider = class {
502
454
  config;
@@ -512,7 +464,7 @@ var BaseProvider = class {
512
464
  return this.model.isVisionCapable;
513
465
  }
514
466
  estimateCost(inputTokens, outputTokens) {
515
- return inputTokens / 1e3 * this.model.inputCostPer1kTokens + outputTokens / 1e3 * this.model.outputCostPer1kTokens;
467
+ return calculateCost(inputTokens, outputTokens, this.model);
516
468
  }
517
469
  makeUsage(inputTokens, outputTokens) {
518
470
  return {
@@ -1801,11 +1753,6 @@ var LocalRequestQueue = class {
1801
1753
  }
1802
1754
  };
1803
1755
 
1804
- // src/utils/cost.ts
1805
- function calculateCost(inputTokens, outputTokens, model) {
1806
- return inputTokens / 1e3 * model.inputCostPer1kTokens + outputTokens / 1e3 * model.outputCostPer1kTokens;
1807
- }
1808
-
1809
1756
  // src/utils/retry.ts
1810
1757
  var CascadeCancelledError = class extends Error {
1811
1758
  constructor(reason) {
@@ -3384,8 +3331,9 @@ var T3Worker = class extends BaseTier {
3384
3331
  const depOutputs = [];
3385
3332
  for (const depId of assignment.dependsOn) {
3386
3333
  try {
3387
- const dep = await this.peerBus.waitFor(depId);
3334
+ const dep = await this.peerBus.waitFor(depId, 6e4);
3388
3335
  if (dep.status === "FAILED" || dep.status === "ESCALATED") {
3336
+ this.peerBus.publish(this.id, assignment.subtaskId, `Blocked by failed dependency: ${depId}`, "FAILED");
3389
3337
  return this.buildResult(
3390
3338
  "ESCALATED",
3391
3339
  `Dependency ${depId} failed \u2014 cannot proceed`,
@@ -3397,6 +3345,7 @@ var T3Worker = class extends BaseTier {
3397
3345
  depOutputs.push(`[From ${dep.fromId} - ${dep.subtaskId}]:
3398
3346
  ${dep.output}`);
3399
3347
  } catch (err) {
3348
+ this.peerBus.publish(this.id, assignment.subtaskId, `Dependency timeout: ${depId}`, "FAILED");
3400
3349
  return this.buildResult(
3401
3350
  "ESCALATED",
3402
3351
  `Dependency timeout: ${depId}`,
@@ -5095,6 +5044,16 @@ function parseFirstJsonObject(input) {
5095
5044
  }
5096
5045
 
5097
5046
  // src/core/tiers/t1-administrator.ts
5047
+ function sharedKeywords(a = [], b = []) {
5048
+ const setB = new Set(b.map((k) => k.toLowerCase().trim()).filter(Boolean));
5049
+ return [...new Set(a.map((k) => k.toLowerCase().trim()).filter(Boolean))].filter((k) => setB.has(k));
5050
+ }
5051
+ function isStrongKeywordOverlap(a = [], b = []) {
5052
+ if (!a.length || !b.length) return false;
5053
+ const shared = sharedKeywords(a, b);
5054
+ const ratio = shared.length / Math.min(a.length, b.length);
5055
+ return shared.length >= 3 && ratio >= 0.6;
5056
+ }
5098
5057
  var T1_SYSTEM_PROMPT = `You are T1, the Administrator in the Cascade AI orchestration system.
5099
5058
 
5100
5059
  Your responsibilities:
@@ -5519,17 +5478,27 @@ Leave dependsOn empty for sections that can run immediately in parallel.`;
5519
5478
  siblingKeywords.set(payload.sectionId, [...new Set(existing)]);
5520
5479
  }
5521
5480
  }
5522
- const overlapSections = /* @__PURE__ */ new Set();
5523
- for (let i = 0; i < announcements.length; i++) {
5524
- for (let j = i + 1; j < announcements.length; j++) {
5525
- const a = announcements[i].payload;
5526
- const b = announcements[j].payload;
5527
- if (!a.keywords || !b.keywords || !a.sectionId || !b.sectionId) continue;
5528
- const shared = a.keywords.filter((k) => b.keywords.includes(k));
5529
- if (shared.length > 0) {
5530
- overlapSections.add(a.sectionId);
5531
- overlapSections.add(b.sectionId);
5532
- this.log(`T2 overlap detected between sections: ${a.sectionId} \u2194 ${b.sectionId} (shared: ${shared.join(", ")})`);
5481
+ const payloads = announcements.map((ann) => ann.payload).filter((p) => p?.type === "T2_PLAN_ANNOUNCEMENT" && !!p.sectionId);
5482
+ const softOverlap = /* @__PURE__ */ new Set();
5483
+ const orderOf = new Map(sections.map((s, i) => [s.sectionId, i]));
5484
+ for (let i = 0; i < payloads.length; i++) {
5485
+ for (let j = i + 1; j < payloads.length; j++) {
5486
+ const a = payloads[i];
5487
+ const b = payloads[j];
5488
+ const shared = sharedKeywords(a.keywords ?? [], b.keywords ?? []);
5489
+ if (shared.length === 0) continue;
5490
+ softOverlap.add(a.sectionId);
5491
+ softOverlap.add(b.sectionId);
5492
+ if (isStrongKeywordOverlap(a.keywords ?? [], b.keywords ?? [])) {
5493
+ const ai = orderOf.get(a.sectionId) ?? 0;
5494
+ const bi = orderOf.get(b.sectionId) ?? 0;
5495
+ const earlier = ai <= bi ? a.sectionId : b.sectionId;
5496
+ const later = ai <= bi ? b.sectionId : a.sectionId;
5497
+ const laterSection = sections.find((s) => s.sectionId === later);
5498
+ if (laterSection && earlier !== later && !(laterSection.dependsOn ?? []).includes(earlier)) {
5499
+ laterSection.dependsOn = [...laterSection.dependsOn || [], earlier];
5500
+ this.log(`Strong overlap ${earlier} \u2194 ${later} (shared: ${shared.slice(0, 5).join(", ")}) \u2014 serializing ${later} after ${earlier}`);
5501
+ }
5533
5502
  }
5534
5503
  }
5535
5504
  }
@@ -5541,20 +5510,10 @@ Leave dependsOn empty for sections that can run immediately in parallel.`;
5541
5510
  `You are T2 Manager for section: "${section.sectionTitle}".`,
5542
5511
  `Sibling sections being worked on in parallel: ${otherTitles.join(", ") || "none"}.`,
5543
5512
  myKeywords.length > 0 ? `Watch for overlap with: ${[...new Set(myKeywords)].slice(0, 10).join(", ")}.` : "",
5544
- overlapSections.has(section.sectionId) ? "NOTE: Potential overlap detected with a sibling section \u2014 be careful not to duplicate work." : ""
5513
+ softOverlap.has(section.sectionId) ? "NOTE: Potential overlap detected with a sibling section \u2014 be careful not to duplicate work." : ""
5545
5514
  ].filter(Boolean).join(" ");
5546
5515
  m.setHierarchyContext(context);
5547
5516
  });
5548
- if (overlapSections.size > 0) {
5549
- this.log("Overlap detected \u2014 adding sequential dependencies for conflicting sections to prevent race conditions");
5550
- const overlapArray = Array.from(overlapSections);
5551
- for (let i = 1; i < overlapArray.length; i++) {
5552
- const section = sections.find((s) => s.sectionId === overlapArray[i]);
5553
- if (section) {
5554
- section.dependsOn = [...section.dependsOn || [], overlapArray[i - 1]];
5555
- }
5556
- }
5557
- }
5558
5517
  const t2Results = [];
5559
5518
  try {
5560
5519
  t2Results.push(...await this.runT2sWithDependencies(sections, managers, this.taskId));
@@ -9306,7 +9265,7 @@ var PBKDF2_ITERATIONS = 1e5;
9306
9265
  var KEYTAR_SERVICE = "cascade-ai";
9307
9266
  async function loadKeytar() {
9308
9267
  try {
9309
- const mod = await Promise.resolve().then(() => __toESM(require_keytar2(), 1));
9268
+ const mod = await import('keytar');
9310
9269
  const candidate = mod.default ?? mod;
9311
9270
  if (typeof candidate.getPassword !== "function") return null;
9312
9271
  return candidate;