cascade-ai 0.2.11 → 0.3.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 +179 -70
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +179 -70
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +98 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +98 -34
- package/dist/index.js.map +1 -1
- package/package.json +8 -5
- 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.3.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";
|
|
@@ -569,17 +569,38 @@ var init_anthropic = __esm({
|
|
|
569
569
|
messages,
|
|
570
570
|
tools: tools?.length ? tools : void 0
|
|
571
571
|
});
|
|
572
|
+
let isThinking = false;
|
|
572
573
|
for await (const event of stream) {
|
|
573
|
-
if (event.type === "content_block_delta"
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
574
|
+
if (event.type === "content_block_delta") {
|
|
575
|
+
if (event.delta.type === "thinking_delta") {
|
|
576
|
+
if (!isThinking) {
|
|
577
|
+
isThinking = true;
|
|
578
|
+
fullContent += "<think>\n";
|
|
579
|
+
onChunk({ text: "<think>\n", finishReason: null });
|
|
580
|
+
}
|
|
581
|
+
const text = event.delta.thinking;
|
|
582
|
+
fullContent += text;
|
|
583
|
+
onChunk({ text, finishReason: null });
|
|
584
|
+
} else if (event.delta.type === "text_delta") {
|
|
585
|
+
if (isThinking) {
|
|
586
|
+
isThinking = false;
|
|
587
|
+
fullContent += "\n</think>\n\n";
|
|
588
|
+
onChunk({ text: "\n</think>\n\n", finishReason: null });
|
|
589
|
+
}
|
|
590
|
+
const text = event.delta.text;
|
|
591
|
+
fullContent += text;
|
|
592
|
+
onChunk({ text, finishReason: null });
|
|
593
|
+
}
|
|
577
594
|
} else if (event.type === "message_delta" && event.usage) {
|
|
578
595
|
outputTokens = event.usage.output_tokens;
|
|
579
596
|
} else if (event.type === "message_start" && event.message.usage) {
|
|
580
597
|
inputTokens = event.message.usage.input_tokens;
|
|
581
598
|
}
|
|
582
599
|
}
|
|
600
|
+
if (isThinking) {
|
|
601
|
+
fullContent += "\n</think>\n\n";
|
|
602
|
+
onChunk({ text: "\n</think>\n\n", finishReason: null });
|
|
603
|
+
}
|
|
583
604
|
const finalMessage = await stream.finalMessage();
|
|
584
605
|
const toolCalls = finalMessage.content.filter((b) => b.type === "tool_use").map((b) => ({
|
|
585
606
|
id: b.id,
|
|
@@ -763,9 +784,25 @@ var init_openai = __esm({
|
|
|
763
784
|
}
|
|
764
785
|
}
|
|
765
786
|
const toolCallsMap = {};
|
|
787
|
+
let isThinking = false;
|
|
766
788
|
for await (const chunk of stream) {
|
|
767
789
|
const delta = chunk.choices[0]?.delta;
|
|
790
|
+
const reasoningContent = delta?.reasoning_content;
|
|
791
|
+
if (reasoningContent) {
|
|
792
|
+
if (!isThinking) {
|
|
793
|
+
isThinking = true;
|
|
794
|
+
fullContent += "<think>\n";
|
|
795
|
+
onChunk({ text: "<think>\n", finishReason: null });
|
|
796
|
+
}
|
|
797
|
+
fullContent += reasoningContent;
|
|
798
|
+
onChunk({ text: reasoningContent, finishReason: null });
|
|
799
|
+
}
|
|
768
800
|
if (delta?.content) {
|
|
801
|
+
if (isThinking) {
|
|
802
|
+
isThinking = false;
|
|
803
|
+
fullContent += "\n</think>\n\n";
|
|
804
|
+
onChunk({ text: "\n</think>\n\n", finishReason: null });
|
|
805
|
+
}
|
|
769
806
|
fullContent += delta.content;
|
|
770
807
|
onChunk({ text: delta.content, finishReason: null });
|
|
771
808
|
}
|
|
@@ -788,6 +825,10 @@ var init_openai = __esm({
|
|
|
788
825
|
outputTokens = chunk.usage.completion_tokens;
|
|
789
826
|
}
|
|
790
827
|
}
|
|
828
|
+
if (isThinking) {
|
|
829
|
+
fullContent += "\n</think>\n\n";
|
|
830
|
+
onChunk({ text: "\n</think>\n\n", finishReason: null });
|
|
831
|
+
}
|
|
791
832
|
const toolCalls = Object.values(toolCallsMap).map((tc) => {
|
|
792
833
|
let input = {};
|
|
793
834
|
try {
|
|
@@ -1881,8 +1922,8 @@ Original error: ${err.message}`
|
|
|
1881
1922
|
upsertRuntimeNode(node) {
|
|
1882
1923
|
this.enqueueWrite(() => {
|
|
1883
1924
|
this.db.prepare(`
|
|
1884
|
-
INSERT INTO runtime_nodes (tier_id, session_id, parent_id, role, label, status, current_action, progress_pct, updated_at, workspace_path, is_global)
|
|
1885
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1925
|
+
INSERT INTO runtime_nodes (tier_id, session_id, parent_id, role, label, status, current_action, progress_pct, updated_at, workspace_path, is_global, output)
|
|
1926
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1886
1927
|
ON CONFLICT(tier_id) DO UPDATE SET
|
|
1887
1928
|
session_id = excluded.session_id,
|
|
1888
1929
|
parent_id = excluded.parent_id,
|
|
@@ -1893,7 +1934,8 @@ Original error: ${err.message}`
|
|
|
1893
1934
|
progress_pct = excluded.progress_pct,
|
|
1894
1935
|
updated_at = excluded.updated_at,
|
|
1895
1936
|
workspace_path = excluded.workspace_path,
|
|
1896
|
-
is_global = excluded.is_global
|
|
1937
|
+
is_global = excluded.is_global,
|
|
1938
|
+
output = excluded.output
|
|
1897
1939
|
`).run(
|
|
1898
1940
|
node.tierId,
|
|
1899
1941
|
node.sessionId,
|
|
@@ -1905,7 +1947,8 @@ Original error: ${err.message}`
|
|
|
1905
1947
|
node.progressPct ?? null,
|
|
1906
1948
|
node.updatedAt,
|
|
1907
1949
|
node.workspacePath ?? null,
|
|
1908
|
-
node.isGlobal ? 1 : 0
|
|
1950
|
+
node.isGlobal ? 1 : 0,
|
|
1951
|
+
node.output ?? null
|
|
1909
1952
|
);
|
|
1910
1953
|
});
|
|
1911
1954
|
}
|
|
@@ -1926,14 +1969,15 @@ Original error: ${err.message}`
|
|
|
1926
1969
|
progressPct: row.progress_pct ?? void 0,
|
|
1927
1970
|
updatedAt: row.updated_at,
|
|
1928
1971
|
workspacePath: row.workspace_path ?? void 0,
|
|
1929
|
-
isGlobal: row.is_global === 1
|
|
1972
|
+
isGlobal: row.is_global === 1,
|
|
1973
|
+
output: row.output ?? void 0
|
|
1930
1974
|
}));
|
|
1931
1975
|
}
|
|
1932
1976
|
addRuntimeNodeLog(log) {
|
|
1933
1977
|
this.enqueueWrite(() => {
|
|
1934
1978
|
this.db.prepare(`
|
|
1935
|
-
INSERT INTO runtime_node_logs (id, session_id, tier_id, role, label, status, current_action, progress_pct, timestamp, workspace_path, is_global)
|
|
1936
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1979
|
+
INSERT INTO runtime_node_logs (id, session_id, tier_id, role, label, status, current_action, progress_pct, timestamp, workspace_path, is_global, output)
|
|
1980
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1937
1981
|
`).run(
|
|
1938
1982
|
log.id,
|
|
1939
1983
|
log.sessionId,
|
|
@@ -1945,7 +1989,8 @@ Original error: ${err.message}`
|
|
|
1945
1989
|
log.progressPct ?? null,
|
|
1946
1990
|
log.timestamp,
|
|
1947
1991
|
log.workspacePath ?? null,
|
|
1948
|
-
log.isGlobal ? 1 : 0
|
|
1992
|
+
log.isGlobal ? 1 : 0,
|
|
1993
|
+
log.output ?? null
|
|
1949
1994
|
);
|
|
1950
1995
|
this.db.prepare(`
|
|
1951
1996
|
DELETE FROM runtime_node_logs
|
|
@@ -1988,7 +2033,8 @@ Original error: ${err.message}`
|
|
|
1988
2033
|
progressPct: row.progress_pct ?? void 0,
|
|
1989
2034
|
timestamp: row.timestamp,
|
|
1990
2035
|
workspacePath: row.workspace_path ?? void 0,
|
|
1991
|
-
isGlobal: row.is_global === 1
|
|
2036
|
+
isGlobal: row.is_global === 1,
|
|
2037
|
+
output: row.output ?? void 0
|
|
1992
2038
|
}));
|
|
1993
2039
|
}
|
|
1994
2040
|
// ── Messages ──────────────────────────────────
|
|
@@ -2315,7 +2361,8 @@ Original error: ${err.message}`
|
|
|
2315
2361
|
progress_pct INTEGER,
|
|
2316
2362
|
updated_at TEXT NOT NULL,
|
|
2317
2363
|
workspace_path TEXT,
|
|
2318
|
-
is_global INTEGER NOT NULL DEFAULT 0
|
|
2364
|
+
is_global INTEGER NOT NULL DEFAULT 0,
|
|
2365
|
+
output TEXT
|
|
2319
2366
|
);
|
|
2320
2367
|
|
|
2321
2368
|
CREATE INDEX IF NOT EXISTS idx_runtime_nodes_session ON runtime_nodes(session_id);
|
|
@@ -2332,7 +2379,8 @@ Original error: ${err.message}`
|
|
|
2332
2379
|
progress_pct INTEGER,
|
|
2333
2380
|
timestamp TEXT NOT NULL,
|
|
2334
2381
|
workspace_path TEXT,
|
|
2335
|
-
is_global INTEGER NOT NULL DEFAULT 0
|
|
2382
|
+
is_global INTEGER NOT NULL DEFAULT 0,
|
|
2383
|
+
output TEXT
|
|
2336
2384
|
);
|
|
2337
2385
|
|
|
2338
2386
|
CREATE TABLE IF NOT EXISTS model_cache (
|
|
@@ -2361,6 +2409,14 @@ Original error: ${err.message}`
|
|
|
2361
2409
|
|
|
2362
2410
|
CREATE INDEX IF NOT EXISTS idx_file_snapshots_session ON file_snapshots(session_id);
|
|
2363
2411
|
`);
|
|
2412
|
+
try {
|
|
2413
|
+
this.db.exec("ALTER TABLE runtime_nodes ADD COLUMN output TEXT");
|
|
2414
|
+
} catch {
|
|
2415
|
+
}
|
|
2416
|
+
try {
|
|
2417
|
+
this.db.exec("ALTER TABLE runtime_node_logs ADD COLUMN output TEXT");
|
|
2418
|
+
} catch {
|
|
2419
|
+
}
|
|
2364
2420
|
}
|
|
2365
2421
|
// ── Deserializers ─────────────────────────────
|
|
2366
2422
|
deserializeSession(row, messages) {
|
|
@@ -2623,6 +2679,7 @@ var ConfigManager = class {
|
|
|
2623
2679
|
}
|
|
2624
2680
|
}
|
|
2625
2681
|
async injectEnvKeys() {
|
|
2682
|
+
const isFirstRun = this.config.providers.length === 0;
|
|
2626
2683
|
const envProviders = [
|
|
2627
2684
|
{ env: "ANTHROPIC_API_KEY", type: "anthropic" },
|
|
2628
2685
|
{ env: "OPENAI_API_KEY", type: "openai" },
|
|
@@ -2633,10 +2690,13 @@ var ConfigManager = class {
|
|
|
2633
2690
|
const key = process.env[env];
|
|
2634
2691
|
if (!key) continue;
|
|
2635
2692
|
const existing = this.config.providers.find((p) => p.type === type);
|
|
2636
|
-
if (!existing)
|
|
2637
|
-
|
|
2693
|
+
if (!existing && isFirstRun) {
|
|
2694
|
+
this.config.providers.push({ type, apiKey: key });
|
|
2695
|
+
} else if (existing && !existing.apiKey) {
|
|
2696
|
+
existing.apiKey = key;
|
|
2697
|
+
}
|
|
2638
2698
|
}
|
|
2639
|
-
if (!this.config.providers.find((p) => p.type === "ollama")) {
|
|
2699
|
+
if (isFirstRun && !this.config.providers.find((p) => p.type === "ollama")) {
|
|
2640
2700
|
this.config.providers.push({ type: "ollama" });
|
|
2641
2701
|
}
|
|
2642
2702
|
}
|
|
@@ -3585,7 +3645,7 @@ var BaseTier = class extends EventEmitter__default.default {
|
|
|
3585
3645
|
getStatus() {
|
|
3586
3646
|
return this.status;
|
|
3587
3647
|
}
|
|
3588
|
-
setStatus(status) {
|
|
3648
|
+
setStatus(status, output) {
|
|
3589
3649
|
this.status = status;
|
|
3590
3650
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
3591
3651
|
const event = {
|
|
@@ -3594,7 +3654,8 @@ var BaseTier = class extends EventEmitter__default.default {
|
|
|
3594
3654
|
parentId: this.parentId,
|
|
3595
3655
|
label: this.label,
|
|
3596
3656
|
status,
|
|
3597
|
-
timestamp
|
|
3657
|
+
timestamp,
|
|
3658
|
+
output
|
|
3598
3659
|
};
|
|
3599
3660
|
this.emit("status", event);
|
|
3600
3661
|
this.emit("tier:status", event);
|
|
@@ -3620,7 +3681,8 @@ var BaseTier = class extends EventEmitter__default.default {
|
|
|
3620
3681
|
status: this.status,
|
|
3621
3682
|
currentAction: update.currentAction,
|
|
3622
3683
|
progressPct: update.progressPct,
|
|
3623
|
-
timestamp
|
|
3684
|
+
timestamp,
|
|
3685
|
+
output: update.output
|
|
3624
3686
|
});
|
|
3625
3687
|
}
|
|
3626
3688
|
buildMessage(type, to, payload) {
|
|
@@ -4001,16 +4063,17 @@ Now execute your subtask using this context where relevant.`
|
|
|
4001
4063
|
return this.buildResult("ESCALATED", output, { checksRun, passed, failed }, issues, correctionAttempts);
|
|
4002
4064
|
}
|
|
4003
4065
|
}
|
|
4004
|
-
this.setStatus("COMPLETED");
|
|
4005
|
-
this.sendStatusUpdate({ progressPct: 100, currentAction: "Subtask complete", status: "IN_PROGRESS" });
|
|
4066
|
+
this.setStatus("COMPLETED", output);
|
|
4067
|
+
this.sendStatusUpdate({ progressPct: 100, currentAction: "Subtask complete", status: "IN_PROGRESS", output });
|
|
4006
4068
|
this.peerBus?.publish(this.id, assignment.subtaskId, output, "COMPLETED");
|
|
4007
4069
|
return this.buildResult("COMPLETED", output, { checksRun, passed, failed }, issues, correctionAttempts);
|
|
4008
4070
|
} catch (err) {
|
|
4009
4071
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
4010
4072
|
issues.push(`Execution error: ${errMsg}`);
|
|
4011
|
-
|
|
4012
|
-
this.
|
|
4013
|
-
|
|
4073
|
+
const finalOutput = output || errMsg;
|
|
4074
|
+
this.setStatus("FAILED", finalOutput);
|
|
4075
|
+
this.peerBus?.publish(this.id, assignment.subtaskId, finalOutput, "FAILED");
|
|
4076
|
+
return this.buildResult("ESCALATED", finalOutput, { checksRun, passed, failed }, issues, correctionAttempts);
|
|
4014
4077
|
}
|
|
4015
4078
|
}
|
|
4016
4079
|
sendToPeer(toId, content) {
|
|
@@ -4693,8 +4756,9 @@ var T2Manager = class extends BaseTier {
|
|
|
4693
4756
|
const summary = await this.aggregateResults(assignment, t3Results);
|
|
4694
4757
|
const issues = t3Results.filter((r) => r.status !== "COMPLETED").flatMap((r) => r.issues);
|
|
4695
4758
|
const overallStatus = this.determineStatus(t3Results);
|
|
4696
|
-
|
|
4697
|
-
this.
|
|
4759
|
+
const isOk = overallStatus === "COMPLETED" || overallStatus === "PARTIAL";
|
|
4760
|
+
this.setStatus(isOk ? "COMPLETED" : "FAILED", summary);
|
|
4761
|
+
this.sendStatusUpdate({ progressPct: 100, currentAction: "Section complete", status: "IN_PROGRESS", output: summary });
|
|
4698
4762
|
const result = {
|
|
4699
4763
|
sectionId: assignment.sectionId,
|
|
4700
4764
|
sectionTitle: assignment.sectionTitle,
|
|
@@ -4707,7 +4771,7 @@ var T2Manager = class extends BaseTier {
|
|
|
4707
4771
|
return result;
|
|
4708
4772
|
} catch (err) {
|
|
4709
4773
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
4710
|
-
this.setStatus("FAILED");
|
|
4774
|
+
this.setStatus("FAILED", errMsg);
|
|
4711
4775
|
const failedResult = {
|
|
4712
4776
|
sectionId: assignment.sectionId,
|
|
4713
4777
|
sectionTitle: assignment.sectionTitle,
|
|
@@ -5272,8 +5336,8 @@ Create a CORRECTION PLAN that contains only the new sections needed to fix the i
|
|
|
5272
5336
|
status: "IN_PROGRESS"
|
|
5273
5337
|
});
|
|
5274
5338
|
const output = await this.compileFinalOutput(userPrompt, plan, allT2Results);
|
|
5275
|
-
this.setStatus("COMPLETED");
|
|
5276
|
-
this.sendStatusUpdate({ progressPct: 100, currentAction: "Task complete", status: "IN_PROGRESS" });
|
|
5339
|
+
this.setStatus("COMPLETED", output);
|
|
5340
|
+
this.sendStatusUpdate({ progressPct: 100, currentAction: "Task complete", status: "IN_PROGRESS", output });
|
|
5277
5341
|
return { output, t2Results: allT2Results, taskId: this.taskId, complexity: plan.complexity };
|
|
5278
5342
|
}
|
|
5279
5343
|
getEscalations() {
|
|
@@ -8102,11 +8166,6 @@ var SlashCommandRegistry = class {
|
|
|
8102
8166
|
description: "Show active models per tier",
|
|
8103
8167
|
handler: (_args, ctx) => ({ output: ctx.onModelInfo(), handled: true })
|
|
8104
8168
|
});
|
|
8105
|
-
this.register({
|
|
8106
|
-
command: "/models",
|
|
8107
|
-
description: "Browse available models by provider",
|
|
8108
|
-
handler: (_args, ctx) => ({ output: ctx.onModelsInfo(), handled: true })
|
|
8109
|
-
});
|
|
8110
8169
|
this.register({
|
|
8111
8170
|
command: "/providers",
|
|
8112
8171
|
description: "Show configured providers",
|
|
@@ -8235,35 +8294,69 @@ function AgentTree({ root, theme }) {
|
|
|
8235
8294
|
}
|
|
8236
8295
|
function T2Row({ node, theme, isLast }) {
|
|
8237
8296
|
const connector = isLast ? "\u2514\u2500 " : "\u251C\u2500 ";
|
|
8238
|
-
const
|
|
8239
|
-
const
|
|
8240
|
-
const workerSuffix = t3Total > 0 ? ` T3\xD7${t3Total}` : "";
|
|
8297
|
+
const t3Nodes = (node.children ?? []).filter((c) => c.role === "T3");
|
|
8298
|
+
const t3ActiveCount = t3Nodes.filter((c) => c.status === "ACTIVE").length;
|
|
8241
8299
|
const label = stripRolePrefix(node.label, node.role);
|
|
8242
8300
|
const action = node.currentAction ? ` ${node.currentAction.slice(0, 38)}` : "";
|
|
8301
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { flexDirection: "column", children: [
|
|
8302
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { children: [
|
|
8303
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { color: theme.colors.muted, children: [
|
|
8304
|
+
" ",
|
|
8305
|
+
connector
|
|
8306
|
+
] }),
|
|
8307
|
+
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.t2Color, bold: true, children: "[T2]" }),
|
|
8308
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { color: theme.colors.foreground, children: [
|
|
8309
|
+
" ",
|
|
8310
|
+
label
|
|
8311
|
+
] }),
|
|
8312
|
+
node.status === "ACTIVE" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8313
|
+
action ? /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.muted, children: action }) : null,
|
|
8314
|
+
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { children: " " }),
|
|
8315
|
+
/* @__PURE__ */ jsxRuntime.jsx(Spinner__default.default, { type: "dots" }),
|
|
8316
|
+
t3ActiveCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { color: theme.colors.muted, children: [
|
|
8317
|
+
" (",
|
|
8318
|
+
t3ActiveCount,
|
|
8319
|
+
" running)"
|
|
8320
|
+
] }) : null
|
|
8321
|
+
] }),
|
|
8322
|
+
node.status === "COMPLETED" && /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.success, children: " \u2714" }),
|
|
8323
|
+
node.status === "FAILED" && /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.error, children: " \u2718" }),
|
|
8324
|
+
node.status === "ESCALATED" && /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.warning, children: " \u25B2" })
|
|
8325
|
+
] }),
|
|
8326
|
+
t3Nodes.map((t3, idx) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
8327
|
+
T3Row,
|
|
8328
|
+
{
|
|
8329
|
+
node: t3,
|
|
8330
|
+
theme,
|
|
8331
|
+
isLast: idx === t3Nodes.length - 1,
|
|
8332
|
+
parentIsLast: isLast
|
|
8333
|
+
},
|
|
8334
|
+
t3.id
|
|
8335
|
+
))
|
|
8336
|
+
] });
|
|
8337
|
+
}
|
|
8338
|
+
function T3Row({ node, theme, isLast, parentIsLast }) {
|
|
8339
|
+
const indent = parentIsLast ? " " : " \u2502 ";
|
|
8340
|
+
const connector = isLast ? "\u2514\u2500 " : "\u251C\u2500 ";
|
|
8341
|
+
const label = stripRolePrefix(node.label, node.role);
|
|
8342
|
+
const action = node.currentAction ? ` ${node.currentAction.slice(0, 42)}` : "";
|
|
8243
8343
|
return /* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { children: [
|
|
8244
8344
|
/* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { color: theme.colors.muted, children: [
|
|
8245
|
-
|
|
8345
|
+
indent,
|
|
8246
8346
|
connector
|
|
8247
8347
|
] }),
|
|
8248
|
-
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.
|
|
8249
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { color: theme.colors.
|
|
8348
|
+
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.t3Color, children: "[T3]" }),
|
|
8349
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { color: theme.colors.muted, children: [
|
|
8250
8350
|
" ",
|
|
8251
8351
|
label
|
|
8252
8352
|
] }),
|
|
8253
|
-
workerSuffix ? /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.muted, children: workerSuffix }) : null,
|
|
8254
8353
|
node.status === "ACTIVE" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8255
8354
|
action ? /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.muted, children: action }) : null,
|
|
8256
8355
|
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { children: " " }),
|
|
8257
|
-
/* @__PURE__ */ jsxRuntime.jsx(Spinner__default.default, { type: "dots" })
|
|
8258
|
-
t3Active > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { color: theme.colors.muted, children: [
|
|
8259
|
-
" (",
|
|
8260
|
-
t3Active,
|
|
8261
|
-
" running)"
|
|
8262
|
-
] }) : null
|
|
8356
|
+
/* @__PURE__ */ jsxRuntime.jsx(Spinner__default.default, { type: "dots" })
|
|
8263
8357
|
] }),
|
|
8264
8358
|
node.status === "COMPLETED" && /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.success, children: " \u2714" }),
|
|
8265
|
-
node.status === "FAILED" && /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.error, children: " \u2718" })
|
|
8266
|
-
node.status === "ESCALATED" && /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.warning, children: " \u25B2" })
|
|
8359
|
+
node.status === "FAILED" && /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.error, children: " \u2718" })
|
|
8267
8360
|
] });
|
|
8268
8361
|
}
|
|
8269
8362
|
function hasActiveOrFailed(node) {
|
|
@@ -8875,7 +8968,7 @@ function Repl({ config, workspacePath, themeName, initialPrompt, identityName })
|
|
|
8875
8968
|
treeNodesRef.current.set(event.tierId, node);
|
|
8876
8969
|
const store = storeRef.current;
|
|
8877
8970
|
if (store) {
|
|
8878
|
-
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 };
|
|
8971
|
+
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 };
|
|
8879
8972
|
store.upsertRuntimeNode(runtimeNode);
|
|
8880
8973
|
globalStoreRef.current?.upsertRuntimeNode({ ...runtimeNode, isGlobal: true });
|
|
8881
8974
|
}
|
|
@@ -8886,7 +8979,6 @@ function Repl({ config, workspacePath, themeName, initialPrompt, identityName })
|
|
|
8886
8979
|
React5.useEffect(() => {
|
|
8887
8980
|
const originalWarn = console.warn;
|
|
8888
8981
|
const originalLog = console.log;
|
|
8889
|
-
process.stdout.write("\x1Bc");
|
|
8890
8982
|
console.warn = (...args) => {
|
|
8891
8983
|
const msg = args.join(" ");
|
|
8892
8984
|
if (msg.includes("non-text parts") || msg.includes("functionCall")) return;
|
|
@@ -9403,8 +9495,8 @@ Use /identity <name|id> to switch.`;
|
|
|
9403
9495
|
const statusHeight = agentTreeHeight + timelineHeight;
|
|
9404
9496
|
const costHeight = state.showCost ? 6 : 0;
|
|
9405
9497
|
const approvalHeight = state.approvalRequest ? 12 : 0;
|
|
9406
|
-
|
|
9407
|
-
const slashHeight =
|
|
9498
|
+
Math.min(SLASH_PAGE_SIZE, slashEntries.length);
|
|
9499
|
+
const slashHeight = isTypingCommand ? SLASH_PAGE_SIZE + 2 : 0;
|
|
9408
9500
|
const chromeHeight = statusHeight + costHeight + approvalHeight + slashHeight + 7;
|
|
9409
9501
|
const availableHeight = Math.max(4, height - chromeHeight);
|
|
9410
9502
|
const allLines = formatToLines(
|
|
@@ -9816,8 +9908,21 @@ function wizardReducer(state, action) {
|
|
|
9816
9908
|
addingAnotherCompat: false
|
|
9817
9909
|
};
|
|
9818
9910
|
}
|
|
9911
|
+
case "ADD_OLLAMA": {
|
|
9912
|
+
const newEntry = {
|
|
9913
|
+
id: crypto.randomUUID(),
|
|
9914
|
+
type: "ollama",
|
|
9915
|
+
label: `Ollama endpoint ${state.entries.filter((e) => e.type === "ollama").length + 1}`
|
|
9916
|
+
};
|
|
9917
|
+
return {
|
|
9918
|
+
...state,
|
|
9919
|
+
entries: [...state.entries, newEntry],
|
|
9920
|
+
currentEntryIdx: state.entries.length,
|
|
9921
|
+
addingAnotherOllama: false
|
|
9922
|
+
};
|
|
9923
|
+
}
|
|
9819
9924
|
case "SKIP_MORE":
|
|
9820
|
-
return { ...state, addingAnotherAzure: false, addingAnotherCompat: false, step: "FETCH_MODELS", currentEntryIdx: 0 };
|
|
9925
|
+
return { ...state, addingAnotherAzure: false, addingAnotherCompat: false, addingAnotherOllama: false, step: "FETCH_MODELS", currentEntryIdx: 0 };
|
|
9821
9926
|
case "GO_FETCH":
|
|
9822
9927
|
return { ...state, step: "FETCH_MODELS", fetchLog: [], fetchedModels: [] };
|
|
9823
9928
|
case "SET_FETCH_LOG":
|
|
@@ -9850,6 +9955,7 @@ function SetupWizard({ workspacePath, onComplete }) {
|
|
|
9850
9955
|
currentEntryIdx: 0,
|
|
9851
9956
|
addingAnotherAzure: false,
|
|
9852
9957
|
addingAnotherCompat: false,
|
|
9958
|
+
addingAnotherOllama: false,
|
|
9853
9959
|
fetchedModels: [],
|
|
9854
9960
|
fetchLog: [],
|
|
9855
9961
|
tierT1: "auto",
|
|
@@ -9949,13 +10055,16 @@ function SetupWizard({ workspacePath, onComplete }) {
|
|
|
9949
10055
|
}, [state.step, state.entries, state.tierT1, state.tierT2, state.tierT3, workspacePath, onComplete, exit]);
|
|
9950
10056
|
ink.useInput((_input, key) => {
|
|
9951
10057
|
if (state.step === "PROVIDER_SELECT") {
|
|
9952
|
-
if (key.upArrow) setProviderCursor((p) =>
|
|
9953
|
-
if (key.downArrow) setProviderCursor((p) =>
|
|
10058
|
+
if (key.upArrow) setProviderCursor((p) => p <= 0 ? providerOrder.length - 1 : p - 1);
|
|
10059
|
+
if (key.downArrow) setProviderCursor((p) => p >= providerOrder.length - 1 ? 0 : p + 1);
|
|
9954
10060
|
if (_input === " ") dispatch({ type: "TOGGLE_PROVIDER", provider: providerOrder[providerCursor] });
|
|
9955
10061
|
if (_input === "a") dispatch({ type: "TOGGLE_ALL" });
|
|
9956
10062
|
if (_input === "i") dispatch({ type: "INVERT_SELECTION" });
|
|
9957
10063
|
if (key.return) {
|
|
9958
|
-
if (state.selectedTypes.size === 0)
|
|
10064
|
+
if (state.selectedTypes.size === 0) {
|
|
10065
|
+
dispatch({ type: "SET_ERROR", error: "Please select at least one provider using <space> before pressing <enter>." });
|
|
10066
|
+
return;
|
|
10067
|
+
}
|
|
9959
10068
|
dispatch({ type: "CONFIRM_PROVIDERS" });
|
|
9960
10069
|
const firstType = [...state.selectedTypes][0];
|
|
9961
10070
|
setFieldStage(firstType === "azure" ? "deploymentName" : firstType === "openai-compatible" ? "label" : firstType === "ollama" ? "baseUrl" : "apiKey");
|
|
@@ -10012,11 +10121,7 @@ function SetupWizard({ workspacePath, onComplete }) {
|
|
|
10012
10121
|
} else if (currentEntry.type === "ollama") {
|
|
10013
10122
|
dispatch({ type: "SET_ENTRY_FIELD", field: "baseUrl", value: val || "http://localhost:11434" });
|
|
10014
10123
|
setFieldBuffer("");
|
|
10015
|
-
|
|
10016
|
-
if (nextEntry) {
|
|
10017
|
-
setFieldStage(nextEntry.type === "azure" ? "deploymentName" : nextEntry.type === "openai-compatible" ? "label" : nextEntry.type === "ollama" ? "baseUrl" : "apiKey");
|
|
10018
|
-
}
|
|
10019
|
-
dispatch({ type: "NEXT_ENTRY" });
|
|
10124
|
+
setFieldStage("askMore");
|
|
10020
10125
|
} else {
|
|
10021
10126
|
dispatch({ type: "SET_ENTRY_FIELD", field: "apiKey", value: val });
|
|
10022
10127
|
setFieldBuffer("");
|
|
@@ -10057,7 +10162,7 @@ function SetupWizard({ workspacePath, onComplete }) {
|
|
|
10057
10162
|
return /* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
|
|
10058
10163
|
/* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { marginBottom: 1, children: [
|
|
10059
10164
|
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: "magenta", bold: true, children: "? " }),
|
|
10060
|
-
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { bold: true, children: isAzure ? "Add another Azure deployment? (y/n)" : "Add another custom endpoint? (y/n)" })
|
|
10165
|
+
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { bold: true, children: isAzure ? "Add another Azure deployment? (y/n)" : isOllama ? "Add another Ollama endpoint? (y/n)" : "Add another custom endpoint? (y/n)" })
|
|
10061
10166
|
] }),
|
|
10062
10167
|
/* @__PURE__ */ jsxRuntime.jsx(ink.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10063
10168
|
SelectInput__default.default,
|
|
@@ -10071,8 +10176,9 @@ function SetupWizard({ workspacePath, onComplete }) {
|
|
|
10071
10176
|
onSelect: (item) => {
|
|
10072
10177
|
if (item.value === "yes") {
|
|
10073
10178
|
if (isAzure) dispatch({ type: "ADD_AZURE" });
|
|
10179
|
+
else if (isOllama) dispatch({ type: "ADD_OLLAMA" });
|
|
10074
10180
|
else dispatch({ type: "ADD_COMPAT" });
|
|
10075
|
-
setFieldStage(isAzure ? "deploymentName" : "label");
|
|
10181
|
+
setFieldStage(isAzure ? "deploymentName" : isOllama ? "baseUrl" : "label");
|
|
10076
10182
|
setFieldBuffer("");
|
|
10077
10183
|
} else {
|
|
10078
10184
|
const nextEntry = state.entries[state.currentEntryIdx + 1];
|
|
@@ -10088,7 +10194,7 @@ function SetupWizard({ workspacePath, onComplete }) {
|
|
|
10088
10194
|
] });
|
|
10089
10195
|
}
|
|
10090
10196
|
const prompt = isAzure && fieldStage === "deploymentName" ? `Azure deployment name (${currentEntry.label})` : isAzure && fieldStage === "baseUrl" ? `Azure endpoint URL` : isCompat && fieldStage === "label" ? `Name for this endpoint (e.g. Groq)` : isCompat && fieldStage === "baseUrl" ? `Base URL (e.g. https://api.groq.com/openai/v1)` : isOllama ? `Ollama URL (Enter for http://localhost:11434)` : `${currentEntry.label} API Key`;
|
|
10091
|
-
const isMasked = fieldStage === "apiKey";
|
|
10197
|
+
const isMasked = fieldStage === "apiKey" && !isOllama;
|
|
10092
10198
|
return /* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
|
|
10093
10199
|
/* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { marginBottom: 1, children: [
|
|
10094
10200
|
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: "magenta", bold: true, children: "? " }),
|
|
@@ -10982,8 +11088,8 @@ var DashboardServer = class {
|
|
|
10982
11088
|
void (async () => {
|
|
10983
11089
|
const cascade = new Cascade(this.config, this.workspacePath, this.store);
|
|
10984
11090
|
cascade.on("stream:token", (e) => {
|
|
10985
|
-
this.socket.broadcast("stream:token", { sessionId,
|
|
10986
|
-
this.socket.broadcastToRoom(`session:${sessionId}`, "stream:token", { sessionId,
|
|
11091
|
+
this.socket.broadcast("stream:token", { sessionId, tierId: e.tierId, text: e.text });
|
|
11092
|
+
this.socket.broadcastToRoom(`session:${sessionId}`, "stream:token", { sessionId, tierId: e.tierId, text: e.text });
|
|
10987
11093
|
});
|
|
10988
11094
|
cascade.on("tier:status", (e) => {
|
|
10989
11095
|
this.socket.broadcast("tier:status", { sessionId, ...e });
|
|
@@ -11419,6 +11525,9 @@ async function startRepl(options) {
|
|
|
11419
11525
|
await cm.load();
|
|
11420
11526
|
config = cm.getConfig();
|
|
11421
11527
|
}
|
|
11528
|
+
if (process.stdout.isTTY) {
|
|
11529
|
+
process.stdout.write("\x1B[2J\x1B[H");
|
|
11530
|
+
}
|
|
11422
11531
|
const { waitUntilExit } = ink.render(
|
|
11423
11532
|
React5__default.default.createElement(Repl, {
|
|
11424
11533
|
config,
|