cascade-ai 0.2.0 → 0.2.2
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 +10 -3
- package/bin/cascade.js +3 -3
- package/completions/cascade.bash +23 -23
- package/completions/cascade.fish +20 -20
- package/completions/cascade.zsh +32 -32
- package/dist/cli.cjs +317 -106
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +317 -106
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +47 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +47 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/web/dist/assets/{index-qNI_hqt1.js → index-BdaS_Mbj.js} +69 -69
- package/web/dist/index.html +13 -13
package/dist/index.d.cts
CHANGED
|
@@ -540,6 +540,13 @@ declare class ModelSelector {
|
|
|
540
540
|
private getPriorityList;
|
|
541
541
|
isProviderAvailable(provider: ProviderType): boolean;
|
|
542
542
|
markProviderUnavailable(provider: ProviderType): void;
|
|
543
|
+
/**
|
|
544
|
+
* Re-add a provider to the available set after it has recovered (e.g. after
|
|
545
|
+
* a failover timeout expires or a successful call confirms recovery). Only
|
|
546
|
+
* re-enables providers that were originally configured — callers should
|
|
547
|
+
* guard against enabling providers that were never configured.
|
|
548
|
+
*/
|
|
549
|
+
markProviderAvailable(provider: ProviderType): void;
|
|
543
550
|
private resolveDynamicModel;
|
|
544
551
|
}
|
|
545
552
|
|
|
@@ -1527,7 +1534,7 @@ declare class Telemetry {
|
|
|
1527
1534
|
shutdown(): Promise<void>;
|
|
1528
1535
|
}
|
|
1529
1536
|
|
|
1530
|
-
declare const CASCADE_VERSION = "0.
|
|
1537
|
+
declare const CASCADE_VERSION = "0.2.2";
|
|
1531
1538
|
declare const CASCADE_CONFIG_DIR = ".cascade";
|
|
1532
1539
|
declare const CASCADE_MD_FILE = "CASCADE.md";
|
|
1533
1540
|
declare const CASCADE_IGNORE_FILE = ".cascadeignore";
|
package/dist/index.d.ts
CHANGED
|
@@ -540,6 +540,13 @@ declare class ModelSelector {
|
|
|
540
540
|
private getPriorityList;
|
|
541
541
|
isProviderAvailable(provider: ProviderType): boolean;
|
|
542
542
|
markProviderUnavailable(provider: ProviderType): void;
|
|
543
|
+
/**
|
|
544
|
+
* Re-add a provider to the available set after it has recovered (e.g. after
|
|
545
|
+
* a failover timeout expires or a successful call confirms recovery). Only
|
|
546
|
+
* re-enables providers that were originally configured — callers should
|
|
547
|
+
* guard against enabling providers that were never configured.
|
|
548
|
+
*/
|
|
549
|
+
markProviderAvailable(provider: ProviderType): void;
|
|
543
550
|
private resolveDynamicModel;
|
|
544
551
|
}
|
|
545
552
|
|
|
@@ -1527,7 +1534,7 @@ declare class Telemetry {
|
|
|
1527
1534
|
shutdown(): Promise<void>;
|
|
1528
1535
|
}
|
|
1529
1536
|
|
|
1530
|
-
declare const CASCADE_VERSION = "0.
|
|
1537
|
+
declare const CASCADE_VERSION = "0.2.2";
|
|
1531
1538
|
declare const CASCADE_CONFIG_DIR = ".cascade";
|
|
1532
1539
|
declare const CASCADE_MD_FILE = "CASCADE.md";
|
|
1533
1540
|
declare const CASCADE_IGNORE_FILE = ".cascadeignore";
|
package/dist/index.js
CHANGED
|
@@ -123,7 +123,7 @@ var require_keytar2 = __commonJS({
|
|
|
123
123
|
});
|
|
124
124
|
|
|
125
125
|
// src/constants.ts
|
|
126
|
-
var CASCADE_VERSION = "0.
|
|
126
|
+
var CASCADE_VERSION = "0.2.2";
|
|
127
127
|
var CASCADE_CONFIG_DIR = ".cascade";
|
|
128
128
|
var CASCADE_MD_FILE = "CASCADE.md";
|
|
129
129
|
var CASCADE_IGNORE_FILE = ".cascadeignore";
|
|
@@ -1243,6 +1243,15 @@ var ModelSelector = class {
|
|
|
1243
1243
|
markProviderUnavailable(provider) {
|
|
1244
1244
|
this.availableProviders.delete(provider);
|
|
1245
1245
|
}
|
|
1246
|
+
/**
|
|
1247
|
+
* Re-add a provider to the available set after it has recovered (e.g. after
|
|
1248
|
+
* a failover timeout expires or a successful call confirms recovery). Only
|
|
1249
|
+
* re-enables providers that were originally configured — callers should
|
|
1250
|
+
* guard against enabling providers that were never configured.
|
|
1251
|
+
*/
|
|
1252
|
+
markProviderAvailable(provider) {
|
|
1253
|
+
this.availableProviders.add(provider);
|
|
1254
|
+
}
|
|
1246
1255
|
resolveDynamicModel(overrideModelId) {
|
|
1247
1256
|
let providerStr = null;
|
|
1248
1257
|
let actualId = overrideModelId;
|
|
@@ -1312,10 +1321,23 @@ var FailoverManager = class {
|
|
|
1312
1321
|
if (!failure) return true;
|
|
1313
1322
|
if (Date.now() - failure.failedAt >= failure.retryAfterMs) {
|
|
1314
1323
|
this.failures.delete(provider);
|
|
1324
|
+
this.selector.markProviderAvailable(provider);
|
|
1315
1325
|
return true;
|
|
1316
1326
|
}
|
|
1317
1327
|
return false;
|
|
1318
1328
|
}
|
|
1329
|
+
/**
|
|
1330
|
+
* Call after a successful generation to immediately re-enable a provider
|
|
1331
|
+
* that had previously been marked unavailable. This allows fast recovery
|
|
1332
|
+
* when a transient rate-limit clears before the backoff window expires,
|
|
1333
|
+
* preventing unnecessary routing to more expensive fallback models.
|
|
1334
|
+
*/
|
|
1335
|
+
recordSuccess(provider) {
|
|
1336
|
+
if (this.failures.has(provider)) {
|
|
1337
|
+
this.failures.delete(provider);
|
|
1338
|
+
this.selector.markProviderAvailable(provider);
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1319
1341
|
getFallbackModel(currentModel, tier) {
|
|
1320
1342
|
return this.selector.getNextFallback(currentModel.id, tier);
|
|
1321
1343
|
}
|
|
@@ -1332,6 +1354,7 @@ var FailoverManager = class {
|
|
|
1332
1354
|
}
|
|
1333
1355
|
clearFailure(provider) {
|
|
1334
1356
|
this.failures.delete(provider);
|
|
1357
|
+
this.selector.markProviderAvailable(provider);
|
|
1335
1358
|
}
|
|
1336
1359
|
};
|
|
1337
1360
|
|
|
@@ -1544,6 +1567,7 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter {
|
|
|
1544
1567
|
throw new Error(`Provider ${model.provider}:${model.id} returned an invalid generation result.`);
|
|
1545
1568
|
}
|
|
1546
1569
|
this.recordStats(tier, model, result.usage);
|
|
1570
|
+
this.failover.recordSuccess(model.provider);
|
|
1547
1571
|
return result;
|
|
1548
1572
|
} catch (err) {
|
|
1549
1573
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
@@ -2242,14 +2266,13 @@ Now execute your subtask using this context where relevant.`
|
|
|
2242
2266
|
await this.peerBus.barrier(this.id, barrierName, total);
|
|
2243
2267
|
}
|
|
2244
2268
|
receivePeerSync(fromId, content) {
|
|
2245
|
-
|
|
2246
|
-
if (existing) {
|
|
2247
|
-
existing.content = content;
|
|
2248
|
-
existing.timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
2249
|
-
} else {
|
|
2250
|
-
this.peerSyncBuffer.push({ fromId, content, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
2251
|
-
}
|
|
2269
|
+
this.peerSyncBuffer.push({ fromId, content, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
2252
2270
|
this.emit("peer-sync-received", { fromId, content });
|
|
2271
|
+
this.context.addMessage({
|
|
2272
|
+
role: "user",
|
|
2273
|
+
content: `[SYSTEM_NOTIFICATION]: You received a new peer message from ${fromId}. Use the "peer_message" tool with action="receive" to read it.`
|
|
2274
|
+
}).catch(() => {
|
|
2275
|
+
});
|
|
2253
2276
|
}
|
|
2254
2277
|
// ── Private ──────────────────────────────────
|
|
2255
2278
|
async runAgentLoop(systemPrompt, tools) {
|
|
@@ -2380,7 +2403,11 @@ HIERARCHY CONTEXT: ${this.hierarchyContext}` : ""),
|
|
|
2380
2403
|
sendPeerSync: (to, syncType, content) => {
|
|
2381
2404
|
this.peerBus?.send(this.id, to, syncType, this.assignment?.subtaskId ?? "", content);
|
|
2382
2405
|
},
|
|
2383
|
-
getPeerMessages: () =>
|
|
2406
|
+
getPeerMessages: () => {
|
|
2407
|
+
const msgs = [...this.peerSyncBuffer];
|
|
2408
|
+
this.peerSyncBuffer = [];
|
|
2409
|
+
return msgs;
|
|
2410
|
+
}
|
|
2384
2411
|
});
|
|
2385
2412
|
if (this.audit) {
|
|
2386
2413
|
this.audit.toolCall(this.id, tc.name, tc.input);
|
|
@@ -2922,13 +2949,17 @@ var T2Manager = class extends BaseTier {
|
|
|
2922
2949
|
}
|
|
2923
2950
|
// ── Private ──────────────────────────────────
|
|
2924
2951
|
async decomposeSection(assignment) {
|
|
2952
|
+
const peerPlans = this.peerSyncBuffer.filter((p) => p.content?.type === "T2_PLAN_ANNOUNCEMENT").map((p) => `[Peer ${p.fromId} Plan]: ${p.content.sectionTitle} - ${p.content.subtaskTitles?.join(", ")}`).join("\n");
|
|
2925
2953
|
const prompt = `Decompose this section into 2-5 concrete subtasks for T3 workers.
|
|
2926
2954
|
|
|
2927
2955
|
Section: ${assignment.sectionTitle}
|
|
2928
2956
|
Description: ${assignment.description}
|
|
2929
2957
|
Expected output: ${assignment.expectedOutput}
|
|
2930
2958
|
Constraints: ${assignment.constraints.join("; ")}
|
|
2931
|
-
|
|
2959
|
+
${peerPlans ? `
|
|
2960
|
+
Context from sibling T2 plans (use this to align execution and avoid overlaps):
|
|
2961
|
+
${peerPlans}
|
|
2962
|
+
` : ""}
|
|
2932
2963
|
Return a JSON array of subtask objects, each with:
|
|
2933
2964
|
- subtaskId: string (unique)
|
|
2934
2965
|
- subtaskTitle: string
|
|
@@ -3142,9 +3173,14 @@ HIERARCHY CONTEXT: ${this.hierarchyContext}` : ""),
|
|
|
3142
3173
|
const completed = results.filter((r) => r.status === "COMPLETED");
|
|
3143
3174
|
if (!completed.length) return `Section ${assignment.sectionTitle} failed \u2014 no T3 workers completed.`;
|
|
3144
3175
|
const outputs = completed.map((r, i) => `[T3-${i + 1}]: ${r.output}`).join("\n\n");
|
|
3176
|
+
const peerOutputs = this.peerSyncBuffer.filter((p) => p.content?.type === "T2_SECTION_OUTPUT").map((p) => `[Peer ${p.fromId} Output]: ${p.content.output}`).join("\n\n");
|
|
3145
3177
|
const prompt = `Summarize these T3 worker outputs for section "${assignment.sectionTitle}" in 2-3 sentences:
|
|
3146
3178
|
|
|
3147
|
-
${outputs}
|
|
3179
|
+
${outputs}
|
|
3180
|
+
${peerOutputs ? `
|
|
3181
|
+
|
|
3182
|
+
Context from sibling T2 completed sections (use this to ensure your summary aligns with the overall state):
|
|
3183
|
+
${peerOutputs}` : ""}`;
|
|
3148
3184
|
const messages = [{ role: "user", content: prompt }];
|
|
3149
3185
|
try {
|
|
3150
3186
|
const result = await this.router.generate("T2", {
|