cascade-ai 0.12.5 → 0.12.7

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 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.5";
104
+ CASCADE_VERSION = "0.12.7";
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";
@@ -162,6 +162,30 @@ var init_constants = __esm({
162
162
  supportsStreaming: true,
163
163
  isLocal: false
164
164
  },
165
+ "claude-opus-4-8": {
166
+ id: "claude-opus-4-8",
167
+ name: "Claude Opus 4.8",
168
+ provider: "anthropic",
169
+ contextWindow: 2e5,
170
+ isVisionCapable: true,
171
+ inputCostPer1kTokens: 0.015,
172
+ outputCostPer1kTokens: 0.075,
173
+ maxOutputTokens: 32e3,
174
+ supportsStreaming: true,
175
+ isLocal: false
176
+ },
177
+ "claude-sonnet-4-6": {
178
+ id: "claude-sonnet-4-6",
179
+ name: "Claude Sonnet 4.6",
180
+ provider: "anthropic",
181
+ contextWindow: 2e5,
182
+ isVisionCapable: true,
183
+ inputCostPer1kTokens: 3e-3,
184
+ outputCostPer1kTokens: 0.015,
185
+ maxOutputTokens: 16e3,
186
+ supportsStreaming: true,
187
+ isLocal: false
188
+ },
165
189
  // OpenAI
166
190
  "gpt-4o": {
167
191
  id: "gpt-4o",
@@ -417,10 +441,34 @@ var init_constants = __esm({
417
441
  }
418
442
  });
419
443
 
444
+ // src/utils/cost.ts
445
+ function resolveModelPricing(model) {
446
+ let input = model.inputCostPer1kTokens;
447
+ let output = model.outputCostPer1kTokens;
448
+ if (input === 0 && output === 0 && model.id && !model.isLocal) {
449
+ const known = Object.values(MODELS).find((m) => m.id === model.id && !m.isLocal);
450
+ if (known) {
451
+ input = known.inputCostPer1kTokens;
452
+ output = known.outputCostPer1kTokens;
453
+ }
454
+ }
455
+ return { input, output };
456
+ }
457
+ function calculateCost(inputTokens, outputTokens, model) {
458
+ const { input, output } = resolveModelPricing(model);
459
+ return inputTokens / 1e3 * input + outputTokens / 1e3 * output;
460
+ }
461
+ var init_cost = __esm({
462
+ "src/utils/cost.ts"() {
463
+ init_constants();
464
+ }
465
+ });
466
+
420
467
  // src/providers/base.ts
421
468
  var BaseProvider;
422
469
  var init_base = __esm({
423
470
  "src/providers/base.ts"() {
471
+ init_cost();
424
472
  BaseProvider = class {
425
473
  config;
426
474
  model;
@@ -435,7 +483,7 @@ var init_base = __esm({
435
483
  return this.model.isVisionCapable;
436
484
  }
437
485
  estimateCost(inputTokens, outputTokens) {
438
- return inputTokens / 1e3 * this.model.inputCostPer1kTokens + outputTokens / 1e3 * this.model.outputCostPer1kTokens;
486
+ return calculateCost(inputTokens, outputTokens, this.model);
439
487
  }
440
488
  makeUsage(inputTokens, outputTokens) {
441
489
  return {
@@ -3560,11 +3608,7 @@ var LocalRequestQueue = class {
3560
3608
 
3561
3609
  // src/core/router/index.ts
3562
3610
  init_constants();
3563
-
3564
- // src/utils/cost.ts
3565
- function calculateCost(inputTokens, outputTokens, model) {
3566
- return inputTokens / 1e3 * model.inputCostPer1kTokens + outputTokens / 1e3 * model.outputCostPer1kTokens;
3567
- }
3611
+ init_cost();
3568
3612
 
3569
3613
  // src/utils/retry.ts
3570
3614
  var CascadeCancelledError = class extends Error {
@@ -3682,6 +3726,7 @@ var ModelProfiler = class {
3682
3726
  };
3683
3727
 
3684
3728
  // src/core/router/savings.ts
3729
+ init_cost();
3685
3730
  var NO_SAVINGS = { savedUsd: 0, savedPct: 0, counterfactualUsd: 0 };
3686
3731
  function computeDelegationSavings(stats, t1Model) {
3687
3732
  if (!t1Model) return NO_SAVINGS;
@@ -5135,8 +5180,9 @@ var T3Worker = class extends BaseTier {
5135
5180
  const depOutputs = [];
5136
5181
  for (const depId of assignment.dependsOn) {
5137
5182
  try {
5138
- const dep = await this.peerBus.waitFor(depId);
5183
+ const dep = await this.peerBus.waitFor(depId, 6e4);
5139
5184
  if (dep.status === "FAILED" || dep.status === "ESCALATED") {
5185
+ this.peerBus.publish(this.id, assignment.subtaskId, `Blocked by failed dependency: ${depId}`, "FAILED");
5140
5186
  return this.buildResult(
5141
5187
  "ESCALATED",
5142
5188
  `Dependency ${depId} failed \u2014 cannot proceed`,
@@ -5148,6 +5194,7 @@ var T3Worker = class extends BaseTier {
5148
5194
  depOutputs.push(`[From ${dep.fromId} - ${dep.subtaskId}]:
5149
5195
  ${dep.output}`);
5150
5196
  } catch (err) {
5197
+ this.peerBus.publish(this.id, assignment.subtaskId, `Dependency timeout: ${depId}`, "FAILED");
5151
5198
  return this.buildResult(
5152
5199
  "ESCALATED",
5153
5200
  `Dependency timeout: ${depId}`,
@@ -6849,6 +6896,16 @@ function parseFirstJsonObject(input) {
6849
6896
  }
6850
6897
 
6851
6898
  // src/core/tiers/t1-administrator.ts
6899
+ function sharedKeywords(a = [], b = []) {
6900
+ const setB = new Set(b.map((k) => k.toLowerCase().trim()).filter(Boolean));
6901
+ return [...new Set(a.map((k) => k.toLowerCase().trim()).filter(Boolean))].filter((k) => setB.has(k));
6902
+ }
6903
+ function isStrongKeywordOverlap(a = [], b = []) {
6904
+ if (!a.length || !b.length) return false;
6905
+ const shared = sharedKeywords(a, b);
6906
+ const ratio = shared.length / Math.min(a.length, b.length);
6907
+ return shared.length >= 3 && ratio >= 0.6;
6908
+ }
6852
6909
  var T1_SYSTEM_PROMPT = `You are T1, the Administrator in the Cascade AI orchestration system.
6853
6910
 
6854
6911
  Your responsibilities:
@@ -7273,17 +7330,27 @@ Leave dependsOn empty for sections that can run immediately in parallel.`;
7273
7330
  siblingKeywords.set(payload.sectionId, [...new Set(existing)]);
7274
7331
  }
7275
7332
  }
7276
- const overlapSections = /* @__PURE__ */ new Set();
7277
- for (let i = 0; i < announcements.length; i++) {
7278
- for (let j = i + 1; j < announcements.length; j++) {
7279
- const a = announcements[i].payload;
7280
- const b = announcements[j].payload;
7281
- if (!a.keywords || !b.keywords || !a.sectionId || !b.sectionId) continue;
7282
- const shared = a.keywords.filter((k) => b.keywords.includes(k));
7283
- if (shared.length > 0) {
7284
- overlapSections.add(a.sectionId);
7285
- overlapSections.add(b.sectionId);
7286
- this.log(`T2 overlap detected between sections: ${a.sectionId} \u2194 ${b.sectionId} (shared: ${shared.join(", ")})`);
7333
+ const payloads = announcements.map((ann) => ann.payload).filter((p) => p?.type === "T2_PLAN_ANNOUNCEMENT" && !!p.sectionId);
7334
+ const softOverlap = /* @__PURE__ */ new Set();
7335
+ const orderOf = new Map(sections.map((s, i) => [s.sectionId, i]));
7336
+ for (let i = 0; i < payloads.length; i++) {
7337
+ for (let j = i + 1; j < payloads.length; j++) {
7338
+ const a = payloads[i];
7339
+ const b = payloads[j];
7340
+ const shared = sharedKeywords(a.keywords ?? [], b.keywords ?? []);
7341
+ if (shared.length === 0) continue;
7342
+ softOverlap.add(a.sectionId);
7343
+ softOverlap.add(b.sectionId);
7344
+ if (isStrongKeywordOverlap(a.keywords ?? [], b.keywords ?? [])) {
7345
+ const ai = orderOf.get(a.sectionId) ?? 0;
7346
+ const bi = orderOf.get(b.sectionId) ?? 0;
7347
+ const earlier = ai <= bi ? a.sectionId : b.sectionId;
7348
+ const later = ai <= bi ? b.sectionId : a.sectionId;
7349
+ const laterSection = sections.find((s) => s.sectionId === later);
7350
+ if (laterSection && earlier !== later && !(laterSection.dependsOn ?? []).includes(earlier)) {
7351
+ laterSection.dependsOn = [...laterSection.dependsOn || [], earlier];
7352
+ this.log(`Strong overlap ${earlier} \u2194 ${later} (shared: ${shared.slice(0, 5).join(", ")}) \u2014 serializing ${later} after ${earlier}`);
7353
+ }
7287
7354
  }
7288
7355
  }
7289
7356
  }
@@ -7295,20 +7362,10 @@ Leave dependsOn empty for sections that can run immediately in parallel.`;
7295
7362
  `You are T2 Manager for section: "${section.sectionTitle}".`,
7296
7363
  `Sibling sections being worked on in parallel: ${otherTitles.join(", ") || "none"}.`,
7297
7364
  myKeywords.length > 0 ? `Watch for overlap with: ${[...new Set(myKeywords)].slice(0, 10).join(", ")}.` : "",
7298
- overlapSections.has(section.sectionId) ? "NOTE: Potential overlap detected with a sibling section \u2014 be careful not to duplicate work." : ""
7365
+ softOverlap.has(section.sectionId) ? "NOTE: Potential overlap detected with a sibling section \u2014 be careful not to duplicate work." : ""
7299
7366
  ].filter(Boolean).join(" ");
7300
7367
  m.setHierarchyContext(context);
7301
7368
  });
7302
- if (overlapSections.size > 0) {
7303
- this.log("Overlap detected \u2014 adding sequential dependencies for conflicting sections to prevent race conditions");
7304
- const overlapArray = Array.from(overlapSections);
7305
- for (let i = 1; i < overlapArray.length; i++) {
7306
- const section = sections.find((s) => s.sectionId === overlapArray[i]);
7307
- if (section) {
7308
- section.dependsOn = [...section.dependsOn || [], overlapArray[i - 1]];
7309
- }
7310
- }
7311
- }
7312
7369
  const t2Results = [];
7313
7370
  try {
7314
7371
  t2Results.push(...await this.runT2sWithDependencies(sections, managers, this.taskId));
@@ -7503,6 +7560,9 @@ Reply with exactly one word: YES, NO, or UNSURE.
7503
7560
  }
7504
7561
  };
7505
7562
 
7563
+ // src/core/cascade.ts
7564
+ init_cost();
7565
+
7506
7566
  // src/tools/registry.ts
7507
7567
  init_constants();
7508
7568