cascade-ai 0.2.12 → 0.4.0
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 +146 -58
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +147 -59
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +76 -37
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -2
- package/dist/index.d.ts +6 -2
- package/dist/index.js +77 -38
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/web/dist/assets/{index-BdaS_Mbj.js → index-BvxaBI9b.js} +34 -34
- package/web/dist/index.html +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -130,7 +130,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
130
130
|
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;
|
|
131
131
|
var init_constants = __esm({
|
|
132
132
|
"src/constants.ts"() {
|
|
133
|
-
CASCADE_VERSION = "0.
|
|
133
|
+
CASCADE_VERSION = "0.4.0";
|
|
134
134
|
CASCADE_CONFIG_FILE = ".cascade/config.json";
|
|
135
135
|
CASCADE_DB_FILE = ".cascade/memory.db";
|
|
136
136
|
CASCADE_DASHBOARD_SECRET_FILE = ".cascade/dashboard-secret";
|
|
@@ -949,19 +949,21 @@ var init_azure = __esm({
|
|
|
949
949
|
init_openai();
|
|
950
950
|
AzureOpenAIProvider = class extends OpenAIProvider {
|
|
951
951
|
constructor(config, model) {
|
|
952
|
-
const
|
|
952
|
+
const rawUrl = config.baseUrl ?? AZURE_BASE_URL_TEMPLATE.replace("{resource}", "YOUR_RESOURCE");
|
|
953
|
+
const endpoint = rawUrl.replace(/\/+$/, "");
|
|
953
954
|
super(
|
|
954
955
|
{
|
|
955
956
|
...config,
|
|
956
|
-
baseUrl:
|
|
957
|
+
baseUrl: endpoint
|
|
958
|
+
// Kept for superclass compatibility if it reads it
|
|
957
959
|
},
|
|
958
960
|
model
|
|
959
961
|
);
|
|
960
|
-
this.client = new
|
|
962
|
+
this.client = new OpenAI.AzureOpenAI({
|
|
961
963
|
apiKey: config.apiKey,
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
964
|
+
endpoint,
|
|
965
|
+
deployment: config.deploymentName ?? model.id,
|
|
966
|
+
apiVersion: config.apiVersion ?? "2024-08-01-preview"
|
|
965
967
|
});
|
|
966
968
|
}
|
|
967
969
|
async listModels() {
|
|
@@ -1922,8 +1924,8 @@ Original error: ${err.message}`
|
|
|
1922
1924
|
upsertRuntimeNode(node) {
|
|
1923
1925
|
this.enqueueWrite(() => {
|
|
1924
1926
|
this.db.prepare(`
|
|
1925
|
-
INSERT INTO runtime_nodes (tier_id, session_id, parent_id, role, label, status, current_action, progress_pct, updated_at, workspace_path, is_global)
|
|
1926
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1927
|
+
INSERT INTO runtime_nodes (tier_id, session_id, parent_id, role, label, status, current_action, progress_pct, updated_at, workspace_path, is_global, output)
|
|
1928
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1927
1929
|
ON CONFLICT(tier_id) DO UPDATE SET
|
|
1928
1930
|
session_id = excluded.session_id,
|
|
1929
1931
|
parent_id = excluded.parent_id,
|
|
@@ -1934,7 +1936,8 @@ Original error: ${err.message}`
|
|
|
1934
1936
|
progress_pct = excluded.progress_pct,
|
|
1935
1937
|
updated_at = excluded.updated_at,
|
|
1936
1938
|
workspace_path = excluded.workspace_path,
|
|
1937
|
-
is_global = excluded.is_global
|
|
1939
|
+
is_global = excluded.is_global,
|
|
1940
|
+
output = excluded.output
|
|
1938
1941
|
`).run(
|
|
1939
1942
|
node.tierId,
|
|
1940
1943
|
node.sessionId,
|
|
@@ -1946,7 +1949,8 @@ Original error: ${err.message}`
|
|
|
1946
1949
|
node.progressPct ?? null,
|
|
1947
1950
|
node.updatedAt,
|
|
1948
1951
|
node.workspacePath ?? null,
|
|
1949
|
-
node.isGlobal ? 1 : 0
|
|
1952
|
+
node.isGlobal ? 1 : 0,
|
|
1953
|
+
node.output ?? null
|
|
1950
1954
|
);
|
|
1951
1955
|
});
|
|
1952
1956
|
}
|
|
@@ -1967,14 +1971,15 @@ Original error: ${err.message}`
|
|
|
1967
1971
|
progressPct: row.progress_pct ?? void 0,
|
|
1968
1972
|
updatedAt: row.updated_at,
|
|
1969
1973
|
workspacePath: row.workspace_path ?? void 0,
|
|
1970
|
-
isGlobal: row.is_global === 1
|
|
1974
|
+
isGlobal: row.is_global === 1,
|
|
1975
|
+
output: row.output ?? void 0
|
|
1971
1976
|
}));
|
|
1972
1977
|
}
|
|
1973
1978
|
addRuntimeNodeLog(log) {
|
|
1974
1979
|
this.enqueueWrite(() => {
|
|
1975
1980
|
this.db.prepare(`
|
|
1976
|
-
INSERT INTO runtime_node_logs (id, session_id, tier_id, role, label, status, current_action, progress_pct, timestamp, workspace_path, is_global)
|
|
1977
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1981
|
+
INSERT INTO runtime_node_logs (id, session_id, tier_id, role, label, status, current_action, progress_pct, timestamp, workspace_path, is_global, output)
|
|
1982
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1978
1983
|
`).run(
|
|
1979
1984
|
log.id,
|
|
1980
1985
|
log.sessionId,
|
|
@@ -1986,7 +1991,8 @@ Original error: ${err.message}`
|
|
|
1986
1991
|
log.progressPct ?? null,
|
|
1987
1992
|
log.timestamp,
|
|
1988
1993
|
log.workspacePath ?? null,
|
|
1989
|
-
log.isGlobal ? 1 : 0
|
|
1994
|
+
log.isGlobal ? 1 : 0,
|
|
1995
|
+
log.output ?? null
|
|
1990
1996
|
);
|
|
1991
1997
|
this.db.prepare(`
|
|
1992
1998
|
DELETE FROM runtime_node_logs
|
|
@@ -2029,7 +2035,8 @@ Original error: ${err.message}`
|
|
|
2029
2035
|
progressPct: row.progress_pct ?? void 0,
|
|
2030
2036
|
timestamp: row.timestamp,
|
|
2031
2037
|
workspacePath: row.workspace_path ?? void 0,
|
|
2032
|
-
isGlobal: row.is_global === 1
|
|
2038
|
+
isGlobal: row.is_global === 1,
|
|
2039
|
+
output: row.output ?? void 0
|
|
2033
2040
|
}));
|
|
2034
2041
|
}
|
|
2035
2042
|
// ── Messages ──────────────────────────────────
|
|
@@ -2356,7 +2363,8 @@ Original error: ${err.message}`
|
|
|
2356
2363
|
progress_pct INTEGER,
|
|
2357
2364
|
updated_at TEXT NOT NULL,
|
|
2358
2365
|
workspace_path TEXT,
|
|
2359
|
-
is_global INTEGER NOT NULL DEFAULT 0
|
|
2366
|
+
is_global INTEGER NOT NULL DEFAULT 0,
|
|
2367
|
+
output TEXT
|
|
2360
2368
|
);
|
|
2361
2369
|
|
|
2362
2370
|
CREATE INDEX IF NOT EXISTS idx_runtime_nodes_session ON runtime_nodes(session_id);
|
|
@@ -2373,7 +2381,8 @@ Original error: ${err.message}`
|
|
|
2373
2381
|
progress_pct INTEGER,
|
|
2374
2382
|
timestamp TEXT NOT NULL,
|
|
2375
2383
|
workspace_path TEXT,
|
|
2376
|
-
is_global INTEGER NOT NULL DEFAULT 0
|
|
2384
|
+
is_global INTEGER NOT NULL DEFAULT 0,
|
|
2385
|
+
output TEXT
|
|
2377
2386
|
);
|
|
2378
2387
|
|
|
2379
2388
|
CREATE TABLE IF NOT EXISTS model_cache (
|
|
@@ -2402,6 +2411,14 @@ Original error: ${err.message}`
|
|
|
2402
2411
|
|
|
2403
2412
|
CREATE INDEX IF NOT EXISTS idx_file_snapshots_session ON file_snapshots(session_id);
|
|
2404
2413
|
`);
|
|
2414
|
+
try {
|
|
2415
|
+
this.db.exec("ALTER TABLE runtime_nodes ADD COLUMN output TEXT");
|
|
2416
|
+
} catch {
|
|
2417
|
+
}
|
|
2418
|
+
try {
|
|
2419
|
+
this.db.exec("ALTER TABLE runtime_node_logs ADD COLUMN output TEXT");
|
|
2420
|
+
} catch {
|
|
2421
|
+
}
|
|
2405
2422
|
}
|
|
2406
2423
|
// ── Deserializers ─────────────────────────────
|
|
2407
2424
|
deserializeSession(row, messages) {
|
|
@@ -3280,7 +3297,7 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
|
|
|
3280
3297
|
if (!model) {
|
|
3281
3298
|
throw new Error(`Configured model "${override}" for ${tier} could not be loaded. Check provider availability and exact model name.`);
|
|
3282
3299
|
}
|
|
3283
|
-
if (model.id !== override) {
|
|
3300
|
+
if (model.id !== override && `${model.provider}:${model.id}` !== override) {
|
|
3284
3301
|
throw new Error(`Configured model "${override}" for ${tier} resolved to "${model.id}". Use the exact provider model ID or prefix the provider (e.g. gemini:${override}).`);
|
|
3285
3302
|
}
|
|
3286
3303
|
this.tierModels.set(tier, model);
|
|
@@ -3630,7 +3647,7 @@ var BaseTier = class extends EventEmitter__default.default {
|
|
|
3630
3647
|
getStatus() {
|
|
3631
3648
|
return this.status;
|
|
3632
3649
|
}
|
|
3633
|
-
setStatus(status) {
|
|
3650
|
+
setStatus(status, output) {
|
|
3634
3651
|
this.status = status;
|
|
3635
3652
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
3636
3653
|
const event = {
|
|
@@ -3639,7 +3656,8 @@ var BaseTier = class extends EventEmitter__default.default {
|
|
|
3639
3656
|
parentId: this.parentId,
|
|
3640
3657
|
label: this.label,
|
|
3641
3658
|
status,
|
|
3642
|
-
timestamp
|
|
3659
|
+
timestamp,
|
|
3660
|
+
output
|
|
3643
3661
|
};
|
|
3644
3662
|
this.emit("status", event);
|
|
3645
3663
|
this.emit("tier:status", event);
|
|
@@ -3665,7 +3683,8 @@ var BaseTier = class extends EventEmitter__default.default {
|
|
|
3665
3683
|
status: this.status,
|
|
3666
3684
|
currentAction: update.currentAction,
|
|
3667
3685
|
progressPct: update.progressPct,
|
|
3668
|
-
timestamp
|
|
3686
|
+
timestamp,
|
|
3687
|
+
output: update.output
|
|
3669
3688
|
});
|
|
3670
3689
|
}
|
|
3671
3690
|
buildMessage(type, to, payload) {
|
|
@@ -4046,16 +4065,17 @@ Now execute your subtask using this context where relevant.`
|
|
|
4046
4065
|
return this.buildResult("ESCALATED", output, { checksRun, passed, failed }, issues, correctionAttempts);
|
|
4047
4066
|
}
|
|
4048
4067
|
}
|
|
4049
|
-
this.setStatus("COMPLETED");
|
|
4050
|
-
this.sendStatusUpdate({ progressPct: 100, currentAction: "Subtask complete", status: "IN_PROGRESS" });
|
|
4068
|
+
this.setStatus("COMPLETED", output);
|
|
4069
|
+
this.sendStatusUpdate({ progressPct: 100, currentAction: "Subtask complete", status: "IN_PROGRESS", output });
|
|
4051
4070
|
this.peerBus?.publish(this.id, assignment.subtaskId, output, "COMPLETED");
|
|
4052
4071
|
return this.buildResult("COMPLETED", output, { checksRun, passed, failed }, issues, correctionAttempts);
|
|
4053
4072
|
} catch (err) {
|
|
4054
4073
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
4055
4074
|
issues.push(`Execution error: ${errMsg}`);
|
|
4056
|
-
|
|
4057
|
-
this.
|
|
4058
|
-
|
|
4075
|
+
const finalOutput = output || errMsg;
|
|
4076
|
+
this.setStatus("FAILED", finalOutput);
|
|
4077
|
+
this.peerBus?.publish(this.id, assignment.subtaskId, finalOutput, "FAILED");
|
|
4078
|
+
return this.buildResult("ESCALATED", finalOutput, { checksRun, passed, failed }, issues, correctionAttempts);
|
|
4059
4079
|
}
|
|
4060
4080
|
}
|
|
4061
4081
|
sendToPeer(toId, content) {
|
|
@@ -4109,6 +4129,10 @@ HIERARCHY CONTEXT: ${this.hierarchyContext}` : ""),
|
|
|
4109
4129
|
await this.context.addMessage({ role: "assistant", content: result.content, toolCalls: result.toolCalls });
|
|
4110
4130
|
if (!result.toolCalls?.length) {
|
|
4111
4131
|
if (requiresArtifact) {
|
|
4132
|
+
const artifactCheck = await this.verifyArtifacts(this.assignment);
|
|
4133
|
+
if (artifactCheck.ok) {
|
|
4134
|
+
return { output: result.content, toolCalls: allToolCalls };
|
|
4135
|
+
}
|
|
4112
4136
|
stalledArtifactIterations += 1;
|
|
4113
4137
|
if (stalledArtifactIterations >= 2) {
|
|
4114
4138
|
if (stalledArtifactIterations === 2) {
|
|
@@ -4118,15 +4142,22 @@ HIERARCHY CONTEXT: ${this.hierarchyContext}` : ""),
|
|
|
4118
4142
|
}
|
|
4119
4143
|
await this.context.addMessage({
|
|
4120
4144
|
role: "user",
|
|
4121
|
-
content:
|
|
4145
|
+
content: `You have not yet created and verified the required artifact. Issues: ${artifactCheck.issues.join("; ")}. Use tools to create the file in the workspace, verify it exists, and inspect the result before concluding.`
|
|
4122
4146
|
});
|
|
4123
4147
|
continue;
|
|
4124
4148
|
}
|
|
4125
4149
|
return { output: result.content, toolCalls: allToolCalls };
|
|
4126
4150
|
}
|
|
4127
4151
|
stalledArtifactIterations = 0;
|
|
4128
|
-
if (result.finishReason === "stop"
|
|
4129
|
-
|
|
4152
|
+
if (result.finishReason === "stop") {
|
|
4153
|
+
if (requiresArtifact) {
|
|
4154
|
+
const artifactCheck = await this.verifyArtifacts(this.assignment);
|
|
4155
|
+
if (artifactCheck.ok) {
|
|
4156
|
+
return { output: result.content, toolCalls: allToolCalls };
|
|
4157
|
+
}
|
|
4158
|
+
} else {
|
|
4159
|
+
return { output: result.content, toolCalls: allToolCalls };
|
|
4160
|
+
}
|
|
4130
4161
|
}
|
|
4131
4162
|
for (const tc of result.toolCalls) {
|
|
4132
4163
|
allToolCalls.push(tc);
|
|
@@ -4738,8 +4769,9 @@ var T2Manager = class extends BaseTier {
|
|
|
4738
4769
|
const summary = await this.aggregateResults(assignment, t3Results);
|
|
4739
4770
|
const issues = t3Results.filter((r) => r.status !== "COMPLETED").flatMap((r) => r.issues);
|
|
4740
4771
|
const overallStatus = this.determineStatus(t3Results);
|
|
4741
|
-
|
|
4742
|
-
this.
|
|
4772
|
+
const isOk = overallStatus === "COMPLETED" || overallStatus === "PARTIAL";
|
|
4773
|
+
this.setStatus(isOk ? "COMPLETED" : "FAILED", summary);
|
|
4774
|
+
this.sendStatusUpdate({ progressPct: 100, currentAction: "Section complete", status: "IN_PROGRESS", output: summary });
|
|
4743
4775
|
const result = {
|
|
4744
4776
|
sectionId: assignment.sectionId,
|
|
4745
4777
|
sectionTitle: assignment.sectionTitle,
|
|
@@ -4752,7 +4784,7 @@ var T2Manager = class extends BaseTier {
|
|
|
4752
4784
|
return result;
|
|
4753
4785
|
} catch (err) {
|
|
4754
4786
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
4755
|
-
this.setStatus("FAILED");
|
|
4787
|
+
this.setStatus("FAILED", errMsg);
|
|
4756
4788
|
const failedResult = {
|
|
4757
4789
|
sectionId: assignment.sectionId,
|
|
4758
4790
|
sectionTitle: assignment.sectionTitle,
|
|
@@ -5317,8 +5349,8 @@ Create a CORRECTION PLAN that contains only the new sections needed to fix the i
|
|
|
5317
5349
|
status: "IN_PROGRESS"
|
|
5318
5350
|
});
|
|
5319
5351
|
const output = await this.compileFinalOutput(userPrompt, plan, allT2Results);
|
|
5320
|
-
this.setStatus("COMPLETED");
|
|
5321
|
-
this.sendStatusUpdate({ progressPct: 100, currentAction: "Task complete", status: "IN_PROGRESS" });
|
|
5352
|
+
this.setStatus("COMPLETED", output);
|
|
5353
|
+
this.sendStatusUpdate({ progressPct: 100, currentAction: "Task complete", status: "IN_PROGRESS", output });
|
|
5322
5354
|
return { output, t2Results: allT2Results, taskId: this.taskId, complexity: plan.complexity };
|
|
5323
5355
|
}
|
|
5324
5356
|
getEscalations() {
|
|
@@ -7596,10 +7628,17 @@ var Cascade = class extends EventEmitter__default.default {
|
|
|
7596
7628
|
throw err;
|
|
7597
7629
|
}
|
|
7598
7630
|
}
|
|
7631
|
+
isCasualGreeting(prompt) {
|
|
7632
|
+
const casual = /^(hi|hello|hey|greetings|thanks|thank you|thx|bye|goodbye|cya)$/i.test(prompt.trim().replace(/[!?.]+$/, ""));
|
|
7633
|
+
return casual;
|
|
7634
|
+
}
|
|
7599
7635
|
looksLikeSimpleArtifactTask(prompt) {
|
|
7600
7636
|
return /create .*\.(txt|md|json|csv)\b/i.test(prompt) && !/(research|compare|thorough|pdf|report|analy[sz]e|architecture|multi-agent)/i.test(prompt);
|
|
7601
7637
|
}
|
|
7602
7638
|
async determineComplexity(prompt, workspacePath, conversationHistory = []) {
|
|
7639
|
+
if (this.isCasualGreeting(prompt)) {
|
|
7640
|
+
return "Simple";
|
|
7641
|
+
}
|
|
7603
7642
|
if (this.looksLikeSimpleArtifactTask(prompt)) {
|
|
7604
7643
|
return "Simple";
|
|
7605
7644
|
}
|
|
@@ -8275,35 +8314,69 @@ function AgentTree({ root, theme }) {
|
|
|
8275
8314
|
}
|
|
8276
8315
|
function T2Row({ node, theme, isLast }) {
|
|
8277
8316
|
const connector = isLast ? "\u2514\u2500 " : "\u251C\u2500 ";
|
|
8278
|
-
const
|
|
8279
|
-
const
|
|
8280
|
-
const workerSuffix = t3Total > 0 ? ` T3\xD7${t3Total}` : "";
|
|
8317
|
+
const t3Nodes = (node.children ?? []).filter((c) => c.role === "T3");
|
|
8318
|
+
const t3ActiveCount = t3Nodes.filter((c) => c.status === "ACTIVE").length;
|
|
8281
8319
|
const label = stripRolePrefix(node.label, node.role);
|
|
8282
8320
|
const action = node.currentAction ? ` ${node.currentAction.slice(0, 38)}` : "";
|
|
8321
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { flexDirection: "column", children: [
|
|
8322
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { children: [
|
|
8323
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { color: theme.colors.muted, children: [
|
|
8324
|
+
" ",
|
|
8325
|
+
connector
|
|
8326
|
+
] }),
|
|
8327
|
+
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.t2Color, bold: true, children: "[T2]" }),
|
|
8328
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { color: theme.colors.foreground, children: [
|
|
8329
|
+
" ",
|
|
8330
|
+
label
|
|
8331
|
+
] }),
|
|
8332
|
+
node.status === "ACTIVE" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8333
|
+
action ? /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.muted, children: action }) : null,
|
|
8334
|
+
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { children: " " }),
|
|
8335
|
+
/* @__PURE__ */ jsxRuntime.jsx(Spinner__default.default, { type: "dots" }),
|
|
8336
|
+
t3ActiveCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { color: theme.colors.muted, children: [
|
|
8337
|
+
" (",
|
|
8338
|
+
t3ActiveCount,
|
|
8339
|
+
" running)"
|
|
8340
|
+
] }) : null
|
|
8341
|
+
] }),
|
|
8342
|
+
node.status === "COMPLETED" && /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.success, children: " \u2714" }),
|
|
8343
|
+
node.status === "FAILED" && /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.error, children: " \u2718" }),
|
|
8344
|
+
node.status === "ESCALATED" && /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.warning, children: " \u25B2" })
|
|
8345
|
+
] }),
|
|
8346
|
+
t3Nodes.map((t3, idx) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
8347
|
+
T3Row,
|
|
8348
|
+
{
|
|
8349
|
+
node: t3,
|
|
8350
|
+
theme,
|
|
8351
|
+
isLast: idx === t3Nodes.length - 1,
|
|
8352
|
+
parentIsLast: isLast
|
|
8353
|
+
},
|
|
8354
|
+
t3.id
|
|
8355
|
+
))
|
|
8356
|
+
] });
|
|
8357
|
+
}
|
|
8358
|
+
function T3Row({ node, theme, isLast, parentIsLast }) {
|
|
8359
|
+
const indent = parentIsLast ? " " : " \u2502 ";
|
|
8360
|
+
const connector = isLast ? "\u2514\u2500 " : "\u251C\u2500 ";
|
|
8361
|
+
const label = stripRolePrefix(node.label, node.role);
|
|
8362
|
+
const action = node.currentAction ? ` ${node.currentAction.slice(0, 42)}` : "";
|
|
8283
8363
|
return /* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { children: [
|
|
8284
8364
|
/* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { color: theme.colors.muted, children: [
|
|
8285
|
-
|
|
8365
|
+
indent,
|
|
8286
8366
|
connector
|
|
8287
8367
|
] }),
|
|
8288
|
-
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.
|
|
8289
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { color: theme.colors.
|
|
8368
|
+
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.t3Color, children: "[T3]" }),
|
|
8369
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { color: theme.colors.muted, children: [
|
|
8290
8370
|
" ",
|
|
8291
8371
|
label
|
|
8292
8372
|
] }),
|
|
8293
|
-
workerSuffix ? /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.muted, children: workerSuffix }) : null,
|
|
8294
8373
|
node.status === "ACTIVE" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8295
8374
|
action ? /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.muted, children: action }) : null,
|
|
8296
8375
|
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { children: " " }),
|
|
8297
|
-
/* @__PURE__ */ jsxRuntime.jsx(Spinner__default.default, { type: "dots" })
|
|
8298
|
-
t3Active > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { color: theme.colors.muted, children: [
|
|
8299
|
-
" (",
|
|
8300
|
-
t3Active,
|
|
8301
|
-
" running)"
|
|
8302
|
-
] }) : null
|
|
8376
|
+
/* @__PURE__ */ jsxRuntime.jsx(Spinner__default.default, { type: "dots" })
|
|
8303
8377
|
] }),
|
|
8304
8378
|
node.status === "COMPLETED" && /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.success, children: " \u2714" }),
|
|
8305
|
-
node.status === "FAILED" && /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.error, children: " \u2718" })
|
|
8306
|
-
node.status === "ESCALATED" && /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.warning, children: " \u25B2" })
|
|
8379
|
+
node.status === "FAILED" && /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.error, children: " \u2718" })
|
|
8307
8380
|
] });
|
|
8308
8381
|
}
|
|
8309
8382
|
function hasActiveOrFailed(node) {
|
|
@@ -8872,7 +8945,7 @@ function Repl({ config, workspacePath, themeName, initialPrompt, identityName })
|
|
|
8872
8945
|
if (sel.kind === "auto") {
|
|
8873
8946
|
delete config.models[tierKey];
|
|
8874
8947
|
} else {
|
|
8875
|
-
config.models[tierKey] = sel.modelId
|
|
8948
|
+
config.models[tierKey] = `${sel.provider}:${sel.modelId}`;
|
|
8876
8949
|
}
|
|
8877
8950
|
try {
|
|
8878
8951
|
const router = cascadeRef.current?.getRouter();
|
|
@@ -8915,7 +8988,7 @@ function Repl({ config, workspacePath, themeName, initialPrompt, identityName })
|
|
|
8915
8988
|
treeNodesRef.current.set(event.tierId, node);
|
|
8916
8989
|
const store = storeRef.current;
|
|
8917
8990
|
if (store) {
|
|
8918
|
-
const runtimeNode = { tierId: node.id, sessionId: sessionIdRef.current, parentId: node.parentId, role: node.role, label: node.label, status: node.status, currentAction: node.currentAction, progressPct: node.progressPct, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), workspacePath, isGlobal: false };
|
|
8991
|
+
const runtimeNode = { tierId: node.id, sessionId: sessionIdRef.current, parentId: node.parentId, role: node.role, label: node.label, status: node.status, currentAction: node.currentAction, progressPct: node.progressPct, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), workspacePath, isGlobal: false, output: event.output };
|
|
8919
8992
|
store.upsertRuntimeNode(runtimeNode);
|
|
8920
8993
|
globalStoreRef.current?.upsertRuntimeNode({ ...runtimeNode, isGlobal: true });
|
|
8921
8994
|
}
|
|
@@ -8926,7 +8999,6 @@ function Repl({ config, workspacePath, themeName, initialPrompt, identityName })
|
|
|
8926
8999
|
React5.useEffect(() => {
|
|
8927
9000
|
const originalWarn = console.warn;
|
|
8928
9001
|
const originalLog = console.log;
|
|
8929
|
-
process.stdout.write("\x1Bc");
|
|
8930
9002
|
console.warn = (...args) => {
|
|
8931
9003
|
const msg = args.join(" ");
|
|
8932
9004
|
if (msg.includes("non-text parts") || msg.includes("functionCall")) return;
|
|
@@ -9431,9 +9503,15 @@ Use /identity <name|id> to switch.`;
|
|
|
9431
9503
|
let agentTreeHeight = 0;
|
|
9432
9504
|
if (state.agentTree && hasActiveOrFailed2(state.agentTree)) {
|
|
9433
9505
|
agentTreeHeight = 1;
|
|
9434
|
-
const
|
|
9435
|
-
agentTreeHeight +=
|
|
9436
|
-
|
|
9506
|
+
const visibleT2s = state.agentTree.children?.slice(0, 6) ?? [];
|
|
9507
|
+
agentTreeHeight += visibleT2s.length;
|
|
9508
|
+
for (const t2 of visibleT2s) {
|
|
9509
|
+
const t3Count = (t2.children ?? []).filter((c) => c.role === "T3").length;
|
|
9510
|
+
agentTreeHeight += t3Count;
|
|
9511
|
+
}
|
|
9512
|
+
if ((state.agentTree.children?.length ?? 0) > 6) {
|
|
9513
|
+
agentTreeHeight += 1;
|
|
9514
|
+
}
|
|
9437
9515
|
}
|
|
9438
9516
|
let timelineHeight = 0;
|
|
9439
9517
|
if (state.showDetails && treeNodesRef.current.size > 0) {
|
|
@@ -9622,6 +9700,13 @@ async function validateConfiguredModels(config) {
|
|
|
9622
9700
|
return problems.length ? `Model warnings: ${problems.join(", ")}` : null;
|
|
9623
9701
|
}
|
|
9624
9702
|
function inferProviderFromModelId(id, providers) {
|
|
9703
|
+
if (id.includes(":")) {
|
|
9704
|
+
const prefix = id.split(":")[0].toLowerCase();
|
|
9705
|
+
const validProviders = ["anthropic", "openai", "gemini", "azure", "openai-compatible", "ollama"];
|
|
9706
|
+
if (validProviders.includes(prefix)) {
|
|
9707
|
+
return prefix;
|
|
9708
|
+
}
|
|
9709
|
+
}
|
|
9625
9710
|
const lower = id.toLowerCase();
|
|
9626
9711
|
if (lower.includes("gpt")) return "openai";
|
|
9627
9712
|
if (lower.includes("claude")) return "anthropic";
|
|
@@ -11036,8 +11121,8 @@ var DashboardServer = class {
|
|
|
11036
11121
|
void (async () => {
|
|
11037
11122
|
const cascade = new Cascade(this.config, this.workspacePath, this.store);
|
|
11038
11123
|
cascade.on("stream:token", (e) => {
|
|
11039
|
-
this.socket.broadcast("stream:token", { sessionId,
|
|
11040
|
-
this.socket.broadcastToRoom(`session:${sessionId}`, "stream:token", { sessionId,
|
|
11124
|
+
this.socket.broadcast("stream:token", { sessionId, tierId: e.tierId, text: e.text });
|
|
11125
|
+
this.socket.broadcastToRoom(`session:${sessionId}`, "stream:token", { sessionId, tierId: e.tierId, text: e.text });
|
|
11041
11126
|
});
|
|
11042
11127
|
cascade.on("tier:status", (e) => {
|
|
11043
11128
|
this.socket.broadcast("tier:status", { sessionId, ...e });
|
|
@@ -11473,6 +11558,9 @@ async function startRepl(options) {
|
|
|
11473
11558
|
await cm.load();
|
|
11474
11559
|
config = cm.getConfig();
|
|
11475
11560
|
}
|
|
11561
|
+
if (process.stdout.isTTY) {
|
|
11562
|
+
process.stdout.write("\x1B[2J\x1B[H");
|
|
11563
|
+
}
|
|
11476
11564
|
const { waitUntilExit } = ink.render(
|
|
11477
11565
|
React5__default.default.createElement(Repl, {
|
|
11478
11566
|
config,
|