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 +90 -30
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +90 -30
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +79 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +79 -30
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -35,7 +35,7 @@ import cron from 'node-cron';
|
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
// src/constants.ts
|
|
38
|
-
var CASCADE_VERSION = "0.12.
|
|
38
|
+
var CASCADE_VERSION = "0.12.7";
|
|
39
39
|
var CASCADE_CONFIG_DIR = ".cascade";
|
|
40
40
|
var CASCADE_MD_FILE = "CASCADE.md";
|
|
41
41
|
var CASCADE_IGNORE_FILE = ".cascadeignore";
|
|
@@ -104,6 +104,30 @@ var MODELS = {
|
|
|
104
104
|
supportsStreaming: true,
|
|
105
105
|
isLocal: false
|
|
106
106
|
},
|
|
107
|
+
"claude-opus-4-8": {
|
|
108
|
+
id: "claude-opus-4-8",
|
|
109
|
+
name: "Claude Opus 4.8",
|
|
110
|
+
provider: "anthropic",
|
|
111
|
+
contextWindow: 2e5,
|
|
112
|
+
isVisionCapable: true,
|
|
113
|
+
inputCostPer1kTokens: 0.015,
|
|
114
|
+
outputCostPer1kTokens: 0.075,
|
|
115
|
+
maxOutputTokens: 32e3,
|
|
116
|
+
supportsStreaming: true,
|
|
117
|
+
isLocal: false
|
|
118
|
+
},
|
|
119
|
+
"claude-sonnet-4-6": {
|
|
120
|
+
id: "claude-sonnet-4-6",
|
|
121
|
+
name: "Claude Sonnet 4.6",
|
|
122
|
+
provider: "anthropic",
|
|
123
|
+
contextWindow: 2e5,
|
|
124
|
+
isVisionCapable: true,
|
|
125
|
+
inputCostPer1kTokens: 3e-3,
|
|
126
|
+
outputCostPer1kTokens: 0.015,
|
|
127
|
+
maxOutputTokens: 16e3,
|
|
128
|
+
supportsStreaming: true,
|
|
129
|
+
isLocal: false
|
|
130
|
+
},
|
|
107
131
|
// OpenAI
|
|
108
132
|
"gpt-4o": {
|
|
109
133
|
id: "gpt-4o",
|
|
@@ -365,6 +389,24 @@ var PROVIDER_DISPLAY_NAMES = {
|
|
|
365
389
|
ollama: "Ollama (Local)"
|
|
366
390
|
};
|
|
367
391
|
|
|
392
|
+
// src/utils/cost.ts
|
|
393
|
+
function resolveModelPricing(model) {
|
|
394
|
+
let input = model.inputCostPer1kTokens;
|
|
395
|
+
let output = model.outputCostPer1kTokens;
|
|
396
|
+
if (input === 0 && output === 0 && model.id && !model.isLocal) {
|
|
397
|
+
const known = Object.values(MODELS).find((m) => m.id === model.id && !m.isLocal);
|
|
398
|
+
if (known) {
|
|
399
|
+
input = known.inputCostPer1kTokens;
|
|
400
|
+
output = known.outputCostPer1kTokens;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
return { input, output };
|
|
404
|
+
}
|
|
405
|
+
function calculateCost(inputTokens, outputTokens, model) {
|
|
406
|
+
const { input, output } = resolveModelPricing(model);
|
|
407
|
+
return inputTokens / 1e3 * input + outputTokens / 1e3 * output;
|
|
408
|
+
}
|
|
409
|
+
|
|
368
410
|
// src/providers/base.ts
|
|
369
411
|
var BaseProvider = class {
|
|
370
412
|
config;
|
|
@@ -380,7 +422,7 @@ var BaseProvider = class {
|
|
|
380
422
|
return this.model.isVisionCapable;
|
|
381
423
|
}
|
|
382
424
|
estimateCost(inputTokens, outputTokens) {
|
|
383
|
-
return inputTokens
|
|
425
|
+
return calculateCost(inputTokens, outputTokens, this.model);
|
|
384
426
|
}
|
|
385
427
|
makeUsage(inputTokens, outputTokens) {
|
|
386
428
|
return {
|
|
@@ -1669,11 +1711,6 @@ var LocalRequestQueue = class {
|
|
|
1669
1711
|
}
|
|
1670
1712
|
};
|
|
1671
1713
|
|
|
1672
|
-
// src/utils/cost.ts
|
|
1673
|
-
function calculateCost(inputTokens, outputTokens, model) {
|
|
1674
|
-
return inputTokens / 1e3 * model.inputCostPer1kTokens + outputTokens / 1e3 * model.outputCostPer1kTokens;
|
|
1675
|
-
}
|
|
1676
|
-
|
|
1677
1714
|
// src/utils/retry.ts
|
|
1678
1715
|
var CascadeCancelledError = class extends Error {
|
|
1679
1716
|
constructor(reason) {
|
|
@@ -3252,8 +3289,9 @@ var T3Worker = class extends BaseTier {
|
|
|
3252
3289
|
const depOutputs = [];
|
|
3253
3290
|
for (const depId of assignment.dependsOn) {
|
|
3254
3291
|
try {
|
|
3255
|
-
const dep = await this.peerBus.waitFor(depId);
|
|
3292
|
+
const dep = await this.peerBus.waitFor(depId, 6e4);
|
|
3256
3293
|
if (dep.status === "FAILED" || dep.status === "ESCALATED") {
|
|
3294
|
+
this.peerBus.publish(this.id, assignment.subtaskId, `Blocked by failed dependency: ${depId}`, "FAILED");
|
|
3257
3295
|
return this.buildResult(
|
|
3258
3296
|
"ESCALATED",
|
|
3259
3297
|
`Dependency ${depId} failed \u2014 cannot proceed`,
|
|
@@ -3265,6 +3303,7 @@ var T3Worker = class extends BaseTier {
|
|
|
3265
3303
|
depOutputs.push(`[From ${dep.fromId} - ${dep.subtaskId}]:
|
|
3266
3304
|
${dep.output}`);
|
|
3267
3305
|
} catch (err) {
|
|
3306
|
+
this.peerBus.publish(this.id, assignment.subtaskId, `Dependency timeout: ${depId}`, "FAILED");
|
|
3268
3307
|
return this.buildResult(
|
|
3269
3308
|
"ESCALATED",
|
|
3270
3309
|
`Dependency timeout: ${depId}`,
|
|
@@ -4963,6 +5002,16 @@ function parseFirstJsonObject(input) {
|
|
|
4963
5002
|
}
|
|
4964
5003
|
|
|
4965
5004
|
// src/core/tiers/t1-administrator.ts
|
|
5005
|
+
function sharedKeywords(a = [], b = []) {
|
|
5006
|
+
const setB = new Set(b.map((k) => k.toLowerCase().trim()).filter(Boolean));
|
|
5007
|
+
return [...new Set(a.map((k) => k.toLowerCase().trim()).filter(Boolean))].filter((k) => setB.has(k));
|
|
5008
|
+
}
|
|
5009
|
+
function isStrongKeywordOverlap(a = [], b = []) {
|
|
5010
|
+
if (!a.length || !b.length) return false;
|
|
5011
|
+
const shared = sharedKeywords(a, b);
|
|
5012
|
+
const ratio = shared.length / Math.min(a.length, b.length);
|
|
5013
|
+
return shared.length >= 3 && ratio >= 0.6;
|
|
5014
|
+
}
|
|
4966
5015
|
var T1_SYSTEM_PROMPT = `You are T1, the Administrator in the Cascade AI orchestration system.
|
|
4967
5016
|
|
|
4968
5017
|
Your responsibilities:
|
|
@@ -5387,17 +5436,27 @@ Leave dependsOn empty for sections that can run immediately in parallel.`;
|
|
|
5387
5436
|
siblingKeywords.set(payload.sectionId, [...new Set(existing)]);
|
|
5388
5437
|
}
|
|
5389
5438
|
}
|
|
5390
|
-
const
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
const
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5439
|
+
const payloads = announcements.map((ann) => ann.payload).filter((p) => p?.type === "T2_PLAN_ANNOUNCEMENT" && !!p.sectionId);
|
|
5440
|
+
const softOverlap = /* @__PURE__ */ new Set();
|
|
5441
|
+
const orderOf = new Map(sections.map((s, i) => [s.sectionId, i]));
|
|
5442
|
+
for (let i = 0; i < payloads.length; i++) {
|
|
5443
|
+
for (let j = i + 1; j < payloads.length; j++) {
|
|
5444
|
+
const a = payloads[i];
|
|
5445
|
+
const b = payloads[j];
|
|
5446
|
+
const shared = sharedKeywords(a.keywords ?? [], b.keywords ?? []);
|
|
5447
|
+
if (shared.length === 0) continue;
|
|
5448
|
+
softOverlap.add(a.sectionId);
|
|
5449
|
+
softOverlap.add(b.sectionId);
|
|
5450
|
+
if (isStrongKeywordOverlap(a.keywords ?? [], b.keywords ?? [])) {
|
|
5451
|
+
const ai = orderOf.get(a.sectionId) ?? 0;
|
|
5452
|
+
const bi = orderOf.get(b.sectionId) ?? 0;
|
|
5453
|
+
const earlier = ai <= bi ? a.sectionId : b.sectionId;
|
|
5454
|
+
const later = ai <= bi ? b.sectionId : a.sectionId;
|
|
5455
|
+
const laterSection = sections.find((s) => s.sectionId === later);
|
|
5456
|
+
if (laterSection && earlier !== later && !(laterSection.dependsOn ?? []).includes(earlier)) {
|
|
5457
|
+
laterSection.dependsOn = [...laterSection.dependsOn || [], earlier];
|
|
5458
|
+
this.log(`Strong overlap ${earlier} \u2194 ${later} (shared: ${shared.slice(0, 5).join(", ")}) \u2014 serializing ${later} after ${earlier}`);
|
|
5459
|
+
}
|
|
5401
5460
|
}
|
|
5402
5461
|
}
|
|
5403
5462
|
}
|
|
@@ -5409,20 +5468,10 @@ Leave dependsOn empty for sections that can run immediately in parallel.`;
|
|
|
5409
5468
|
`You are T2 Manager for section: "${section.sectionTitle}".`,
|
|
5410
5469
|
`Sibling sections being worked on in parallel: ${otherTitles.join(", ") || "none"}.`,
|
|
5411
5470
|
myKeywords.length > 0 ? `Watch for overlap with: ${[...new Set(myKeywords)].slice(0, 10).join(", ")}.` : "",
|
|
5412
|
-
|
|
5471
|
+
softOverlap.has(section.sectionId) ? "NOTE: Potential overlap detected with a sibling section \u2014 be careful not to duplicate work." : ""
|
|
5413
5472
|
].filter(Boolean).join(" ");
|
|
5414
5473
|
m.setHierarchyContext(context);
|
|
5415
5474
|
});
|
|
5416
|
-
if (overlapSections.size > 0) {
|
|
5417
|
-
this.log("Overlap detected \u2014 adding sequential dependencies for conflicting sections to prevent race conditions");
|
|
5418
|
-
const overlapArray = Array.from(overlapSections);
|
|
5419
|
-
for (let i = 1; i < overlapArray.length; i++) {
|
|
5420
|
-
const section = sections.find((s) => s.sectionId === overlapArray[i]);
|
|
5421
|
-
if (section) {
|
|
5422
|
-
section.dependsOn = [...section.dependsOn || [], overlapArray[i - 1]];
|
|
5423
|
-
}
|
|
5424
|
-
}
|
|
5425
|
-
}
|
|
5426
5475
|
const t2Results = [];
|
|
5427
5476
|
try {
|
|
5428
5477
|
t2Results.push(...await this.runT2sWithDependencies(sections, managers, this.taskId));
|