@wrongstack/tui 0.41.0 → 0.54.1
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/index.d.ts +51 -26
- package/dist/index.js +396 -18
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -54,6 +54,7 @@ function StatusBar({
|
|
|
54
54
|
git,
|
|
55
55
|
subagentCount = 0,
|
|
56
56
|
context,
|
|
57
|
+
brain,
|
|
57
58
|
projectName,
|
|
58
59
|
processCount,
|
|
59
60
|
hiddenItems,
|
|
@@ -79,7 +80,8 @@ function StatusBar({
|
|
|
79
80
|
const { label: stateLabel, color: stateColor } = stateChip(state, fleet?.running ?? 0);
|
|
80
81
|
const hasSecondLine = yolo || autonomy && autonomy !== "off" || elapsedMs !== void 0 || git !== null && git !== void 0 || projectName !== void 0 && projectName.length > 0 || goalSummary !== null && goalSummary !== void 0;
|
|
81
82
|
const fleetHasActivity = fleet && (fleet.running > 0 || fleet.idle > 0 || fleet.pending > 0 || fleet.completed > 0) || subagentCount > 0;
|
|
82
|
-
const
|
|
83
|
+
const hasBrainActivity = !!brain && brain.state !== "idle";
|
|
84
|
+
const hasThirdLine = todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) || fleetHasActivity || hasBrainActivity;
|
|
83
85
|
return /* @__PURE__ */ jsxs(
|
|
84
86
|
Box,
|
|
85
87
|
{
|
|
@@ -316,6 +318,10 @@ function StatusBar({
|
|
|
316
318
|
" agent",
|
|
317
319
|
subagentCount === 1 ? "" : "s"
|
|
318
320
|
] })
|
|
321
|
+
] }) : null,
|
|
322
|
+
hasBrainActivity && brain ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
323
|
+
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) || fleetHasActivity ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
324
|
+
/* @__PURE__ */ jsx(BrainChip, { brain })
|
|
319
325
|
] }) : null
|
|
320
326
|
] }) : null,
|
|
321
327
|
fleetAgents && fleetAgents.length > 0 ? /* @__PURE__ */ jsx(Box, { flexDirection: "row", gap: 2, children: fleetAgents.map((a, i) => (
|
|
@@ -348,6 +354,18 @@ function StatusBar({
|
|
|
348
354
|
}
|
|
349
355
|
);
|
|
350
356
|
}
|
|
357
|
+
function BrainChip({ brain }) {
|
|
358
|
+
const color = brain.state === "denied" ? "red" : brain.state === "ask_human" ? "yellow" : brain.state === "deciding" ? "magenta" : "cyan";
|
|
359
|
+
const label = brain.state === "deciding" ? "deciding" : brain.state === "ask_human" ? "human" : brain.state;
|
|
360
|
+
const scope = brain.source ? ` ${brain.source}` : "";
|
|
361
|
+
const summary = brain.summary ? ` \xB7 ${brain.summary.slice(0, 40)}` : "";
|
|
362
|
+
return /* @__PURE__ */ jsxs(Text, { color, children: [
|
|
363
|
+
"\u{1F9E0} ",
|
|
364
|
+
label,
|
|
365
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: scope }),
|
|
366
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: summary })
|
|
367
|
+
] });
|
|
368
|
+
}
|
|
351
369
|
function EternalStageChip({
|
|
352
370
|
stage
|
|
353
371
|
}) {
|
|
@@ -376,6 +394,25 @@ function EternalStageChip({
|
|
|
376
394
|
]
|
|
377
395
|
}
|
|
378
396
|
);
|
|
397
|
+
case "decompose":
|
|
398
|
+
return /* @__PURE__ */ jsx(Text, { color: "cyan", children: "\u2B07 decompose" });
|
|
399
|
+
case "fanout":
|
|
400
|
+
return /* @__PURE__ */ jsxs(Text, { color: "magenta", children: [
|
|
401
|
+
"\u21C4 fanout: ",
|
|
402
|
+
stage.slots
|
|
403
|
+
] });
|
|
404
|
+
case "await":
|
|
405
|
+
return /* @__PURE__ */ jsxs(Text, { color: "magenta", children: [
|
|
406
|
+
"\u23F3 await: ",
|
|
407
|
+
stage.taskIds.length
|
|
408
|
+
] });
|
|
409
|
+
case "aggregate":
|
|
410
|
+
return /* @__PURE__ */ jsxs(Text, { color: stage.goalComplete ? "green" : "magenta", children: [
|
|
411
|
+
"\u21A9 aggregate: ",
|
|
412
|
+
stage.successCount,
|
|
413
|
+
"/",
|
|
414
|
+
stage.total
|
|
415
|
+
] });
|
|
379
416
|
case "sleep":
|
|
380
417
|
return /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
381
418
|
"\u{1F4A4} sleep ",
|
|
@@ -734,6 +771,9 @@ function fmtTokens2(n) {
|
|
|
734
771
|
if (n < 1e6) return `${(n / 1e3).toFixed(1)}k`;
|
|
735
772
|
return `${(n / 1e6).toFixed(1)}M`;
|
|
736
773
|
}
|
|
774
|
+
function fmtExactTokens(n) {
|
|
775
|
+
return `${Math.round(n).toLocaleString("en-US")} tok`;
|
|
776
|
+
}
|
|
737
777
|
function snippet(s2, max = 72) {
|
|
738
778
|
const oneLine2 = s2.replace(/\s+/g, " ").trim();
|
|
739
779
|
if (oneLine2.length <= max) return oneLine2;
|
|
@@ -831,6 +871,10 @@ function AgentsMonitor({
|
|
|
831
871
|
/* @__PURE__ */ jsx(Text, { color: s2.color, bold: true, children: s2.icon }),
|
|
832
872
|
/* @__PURE__ */ jsx(Text, { bold: true, children: e.name }),
|
|
833
873
|
fmtModelLabel(e.provider, e.model) ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: fmtModelLabel(e.provider, e.model) }) : null,
|
|
874
|
+
e.ctxMaxTokens && e.ctxMaxTokens > 0 ? /* @__PURE__ */ jsxs(Text, { color: "blue", children: [
|
|
875
|
+
"ctx max ",
|
|
876
|
+
fmtExactTokens(e.ctxMaxTokens)
|
|
877
|
+
] }) : null,
|
|
834
878
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7" }),
|
|
835
879
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: elapsed }),
|
|
836
880
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7" }),
|
|
@@ -952,6 +996,92 @@ function AutonomyPicker({
|
|
|
952
996
|
hint ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: hint }) : null
|
|
953
997
|
] });
|
|
954
998
|
}
|
|
999
|
+
function riskColor(risk) {
|
|
1000
|
+
switch (risk) {
|
|
1001
|
+
case "low":
|
|
1002
|
+
return "green";
|
|
1003
|
+
case "medium":
|
|
1004
|
+
return "cyan";
|
|
1005
|
+
case "high":
|
|
1006
|
+
return "yellow";
|
|
1007
|
+
case "critical":
|
|
1008
|
+
return "red";
|
|
1009
|
+
default:
|
|
1010
|
+
return "white";
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
function optionKey(index) {
|
|
1014
|
+
return String.fromCharCode("A".charCodeAt(0) + index);
|
|
1015
|
+
}
|
|
1016
|
+
function contextLines(context) {
|
|
1017
|
+
if (!context?.trim()) return [];
|
|
1018
|
+
return context.trim().split("\n").slice(0, 5);
|
|
1019
|
+
}
|
|
1020
|
+
function BrainDecisionPrompt({
|
|
1021
|
+
requestId,
|
|
1022
|
+
source,
|
|
1023
|
+
risk,
|
|
1024
|
+
question,
|
|
1025
|
+
context,
|
|
1026
|
+
options = [],
|
|
1027
|
+
onAnswer
|
|
1028
|
+
}) {
|
|
1029
|
+
const color = riskColor(risk);
|
|
1030
|
+
const ctx = contextLines(context);
|
|
1031
|
+
useInput((input, key) => {
|
|
1032
|
+
if (!onAnswer) return;
|
|
1033
|
+
if (key.escape || input.toLowerCase() === "d") {
|
|
1034
|
+
onAnswer({ id: requestId, deny: true, text: "Denied by human from TUI." });
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1037
|
+
const ch = input.toLowerCase();
|
|
1038
|
+
const index = ch >= "a" && ch <= "z" ? ch.charCodeAt(0) - "a".charCodeAt(0) : Number(ch) - 1;
|
|
1039
|
+
const option = Number.isInteger(index) && index >= 0 ? options[index] : void 0;
|
|
1040
|
+
if (option) onAnswer({ id: requestId, optionId: option.id, text: option.label });
|
|
1041
|
+
});
|
|
1042
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "magenta", paddingX: 1, children: [
|
|
1043
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "row", children: /* @__PURE__ */ jsx(Text, { bold: true, color: "magenta", children: "\u{1F9E0} BRAIN REQUIRES HUMAN DECISION" }) }),
|
|
1044
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
1045
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Source:" }),
|
|
1046
|
+
/* @__PURE__ */ jsx(Text, { children: source }),
|
|
1047
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Risk:" }),
|
|
1048
|
+
/* @__PURE__ */ jsx(Text, { color, children: risk })
|
|
1049
|
+
] }),
|
|
1050
|
+
/* @__PURE__ */ jsx(Text, { color: "white", children: question }),
|
|
1051
|
+
ctx.length > 0 ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
1052
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Context:" }),
|
|
1053
|
+
ctx.map((line, index) => (
|
|
1054
|
+
// biome-ignore lint/suspicious/noArrayIndexKey: context lines are static for this prompt render
|
|
1055
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: line }, index)
|
|
1056
|
+
))
|
|
1057
|
+
] }) : null,
|
|
1058
|
+
options.length > 0 ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
1059
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Options:" }),
|
|
1060
|
+
options.slice(0, 6).map((option, index) => {
|
|
1061
|
+
const key = optionKey(index);
|
|
1062
|
+
const optionColor = riskColor(String(option.risk ?? risk));
|
|
1063
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
1064
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
1065
|
+
/* @__PURE__ */ jsxs(Text, { bold: true, color: "yellow", children: [
|
|
1066
|
+
"[",
|
|
1067
|
+
key,
|
|
1068
|
+
"]"
|
|
1069
|
+
] }),
|
|
1070
|
+
" ",
|
|
1071
|
+
/* @__PURE__ */ jsx(Text, { color: optionColor, children: option.label }),
|
|
1072
|
+
option.recommended ? /* @__PURE__ */ jsx(Text, { color: "green", children: " recommended" }) : null
|
|
1073
|
+
] }),
|
|
1074
|
+
option.consequence ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1075
|
+
" ",
|
|
1076
|
+
option.consequence
|
|
1077
|
+
] }) : null
|
|
1078
|
+
] }, option.id);
|
|
1079
|
+
})
|
|
1080
|
+
] }) : null,
|
|
1081
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" }),
|
|
1082
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press A/B/C or 1/2/3 to answer; Esc or D denies with the safe default." })
|
|
1083
|
+
] });
|
|
1084
|
+
}
|
|
955
1085
|
function CheckpointTimeline({
|
|
956
1086
|
checkpoints,
|
|
957
1087
|
selected,
|
|
@@ -2318,6 +2448,30 @@ function DiffBlock({ rows, hidden }) {
|
|
|
2318
2448
|
hidden > 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, italic: true, children: `${blank} \u2026 ${hidden} more line${hidden === 1 ? "" : "s"}` }) : null
|
|
2319
2449
|
] });
|
|
2320
2450
|
}
|
|
2451
|
+
function brainStatusStyle(status) {
|
|
2452
|
+
switch (status) {
|
|
2453
|
+
case "thinking":
|
|
2454
|
+
return { icon: "\u2026", color: "magenta" };
|
|
2455
|
+
case "answered":
|
|
2456
|
+
return { icon: "\u2696", color: "cyan" };
|
|
2457
|
+
case "ask_human":
|
|
2458
|
+
return { icon: "?", color: "yellow" };
|
|
2459
|
+
case "denied":
|
|
2460
|
+
return { icon: "\xD7", color: "red" };
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
function brainRiskColor(risk) {
|
|
2464
|
+
switch (risk) {
|
|
2465
|
+
case "low":
|
|
2466
|
+
return "green";
|
|
2467
|
+
case "medium":
|
|
2468
|
+
return "cyan";
|
|
2469
|
+
case "high":
|
|
2470
|
+
return "yellow";
|
|
2471
|
+
case "critical":
|
|
2472
|
+
return "red";
|
|
2473
|
+
}
|
|
2474
|
+
}
|
|
2321
2475
|
var Entry = React4.memo(function Entry2({
|
|
2322
2476
|
entry,
|
|
2323
2477
|
termWidth
|
|
@@ -2450,6 +2604,38 @@ var Entry = React4.memo(function Entry2({
|
|
|
2450
2604
|
);
|
|
2451
2605
|
case "turn-summary":
|
|
2452
2606
|
return /* @__PURE__ */ jsx(Text, { dimColor: true, children: entry.text });
|
|
2607
|
+
case "brain": {
|
|
2608
|
+
const statusStyle = brainStatusStyle(entry.status);
|
|
2609
|
+
const riskColor2 = brainRiskColor(entry.risk);
|
|
2610
|
+
return /* @__PURE__ */ jsxs(
|
|
2611
|
+
Box,
|
|
2612
|
+
{
|
|
2613
|
+
flexDirection: "column",
|
|
2614
|
+
marginY: 1,
|
|
2615
|
+
borderStyle: "single",
|
|
2616
|
+
borderTop: false,
|
|
2617
|
+
borderRight: false,
|
|
2618
|
+
borderBottom: false,
|
|
2619
|
+
borderColor: "magenta",
|
|
2620
|
+
paddingLeft: 1,
|
|
2621
|
+
children: [
|
|
2622
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
2623
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "magenta", children: "BRAIN" }),
|
|
2624
|
+
/* @__PURE__ */ jsx(Text, { color: statusStyle.color, children: statusStyle.icon }),
|
|
2625
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: entry.source }),
|
|
2626
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7" }),
|
|
2627
|
+
/* @__PURE__ */ jsx(Text, { color: riskColor2, children: entry.risk })
|
|
2628
|
+
] }),
|
|
2629
|
+
/* @__PURE__ */ jsx(Text, { color: "white", children: entry.question }),
|
|
2630
|
+
entry.decision ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
2631
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Decision: " }),
|
|
2632
|
+
/* @__PURE__ */ jsx(Text, { color: statusStyle.color, children: entry.decision })
|
|
2633
|
+
] }) : null,
|
|
2634
|
+
entry.rationale ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: entry.rationale }) : null
|
|
2635
|
+
]
|
|
2636
|
+
}
|
|
2637
|
+
);
|
|
2638
|
+
}
|
|
2453
2639
|
case "confirm":
|
|
2454
2640
|
return /* @__PURE__ */ jsxs(
|
|
2455
2641
|
Box,
|
|
@@ -3583,12 +3769,28 @@ var LiveActivityStrip = React4.memo(function LiveActivityStrip2({
|
|
|
3583
3769
|
] }) }) : null
|
|
3584
3770
|
] });
|
|
3585
3771
|
});
|
|
3772
|
+
var MAX_VISIBLE = 10;
|
|
3773
|
+
function getVisibleWindow(selected, total) {
|
|
3774
|
+
const half = Math.floor(MAX_VISIBLE / 2);
|
|
3775
|
+
let start = selected - half;
|
|
3776
|
+
let end = start + MAX_VISIBLE;
|
|
3777
|
+
if (start < 0) {
|
|
3778
|
+
start = 0;
|
|
3779
|
+
end = Math.min(total, MAX_VISIBLE);
|
|
3780
|
+
}
|
|
3781
|
+
if (end > total) {
|
|
3782
|
+
end = total;
|
|
3783
|
+
start = Math.max(0, end - MAX_VISIBLE);
|
|
3784
|
+
}
|
|
3785
|
+
return { start, end };
|
|
3786
|
+
}
|
|
3586
3787
|
function ModelPicker({
|
|
3587
3788
|
step,
|
|
3588
3789
|
providerOptions,
|
|
3589
|
-
|
|
3790
|
+
filteredOptions,
|
|
3590
3791
|
selected,
|
|
3591
3792
|
pickedProviderId,
|
|
3793
|
+
searchQuery,
|
|
3592
3794
|
hint
|
|
3593
3795
|
}) {
|
|
3594
3796
|
if (step === "provider") {
|
|
@@ -3613,17 +3815,47 @@ function ModelPicker({
|
|
|
3613
3815
|
hint ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: hint }) : null
|
|
3614
3816
|
] });
|
|
3615
3817
|
}
|
|
3818
|
+
const total = filteredOptions.length;
|
|
3819
|
+
const { start, end } = getVisibleWindow(selected, total);
|
|
3820
|
+
const visibleItems = filteredOptions.slice(start, end);
|
|
3821
|
+
const searchHint = searchQuery ? ` | filter:"${searchQuery}" \u2192 ${total} match${total === 1 ? "" : "es"}` : total > MAX_VISIBLE ? ` (${total} models \u2014 type to filter)` : "";
|
|
3616
3822
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: 1, children: [
|
|
3617
3823
|
/* @__PURE__ */ jsxs(Text, { color: "cyan", bold: true, children: [
|
|
3618
|
-
"\u2501\u2501 Switch model \u2014 Step 2/2: Pick model
|
|
3824
|
+
"\u2501\u2501 Switch model \u2014 Step 2/2: Pick model ",
|
|
3825
|
+
"(",
|
|
3619
3826
|
pickedProviderId,
|
|
3620
|
-
|
|
3827
|
+
searchHint,
|
|
3828
|
+
")",
|
|
3829
|
+
" \u2501\u2501"
|
|
3830
|
+
] }),
|
|
3831
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 navigate \xB7 Enter select \xB7 Esc back \xB7 Ctrl+C exit \xB7 type to filter" }),
|
|
3832
|
+
total === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: searchQuery ? `(no models match "${searchQuery}")` : "(no models known for this provider)" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3833
|
+
start > 0 && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
3834
|
+
"\u25B2 ",
|
|
3835
|
+
start,
|
|
3836
|
+
" above"
|
|
3837
|
+
] }),
|
|
3838
|
+
visibleItems.map((id, vi) => {
|
|
3839
|
+
const absoluteIndex = start + vi;
|
|
3840
|
+
return /* @__PURE__ */ jsxs(
|
|
3841
|
+
Text,
|
|
3842
|
+
{
|
|
3843
|
+
color: absoluteIndex === selected ? "cyan" : void 0,
|
|
3844
|
+
inverse: absoluteIndex === selected,
|
|
3845
|
+
children: [
|
|
3846
|
+
absoluteIndex === selected ? "\u203A " : " ",
|
|
3847
|
+
id
|
|
3848
|
+
]
|
|
3849
|
+
},
|
|
3850
|
+
id
|
|
3851
|
+
);
|
|
3852
|
+
}),
|
|
3853
|
+
end < total && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
3854
|
+
"\u25BC ",
|
|
3855
|
+
total - end,
|
|
3856
|
+
" below"
|
|
3857
|
+
] })
|
|
3621
3858
|
] }),
|
|
3622
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 navigate \xB7 Enter select \xB7 Esc back \xB7 Ctrl+C exit" }),
|
|
3623
|
-
modelOptions.length === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "(no models known for this provider)" }) : modelOptions.map((id, i) => /* @__PURE__ */ jsxs(Text, { color: i === selected ? "cyan" : void 0, inverse: i === selected, children: [
|
|
3624
|
-
i === selected ? "\u203A " : " ",
|
|
3625
|
-
id
|
|
3626
|
-
] }, id)),
|
|
3627
3859
|
hint ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: hint }) : null
|
|
3628
3860
|
] });
|
|
3629
3861
|
}
|
|
@@ -4574,6 +4806,21 @@ function reducer(state, action) {
|
|
|
4574
4806
|
return { ...state, interrupts: 0 };
|
|
4575
4807
|
case "hint":
|
|
4576
4808
|
return { ...state, hint: action.text };
|
|
4809
|
+
case "brainStatus":
|
|
4810
|
+
return {
|
|
4811
|
+
...state,
|
|
4812
|
+
brain: {
|
|
4813
|
+
state: action.state,
|
|
4814
|
+
source: action.source,
|
|
4815
|
+
risk: action.risk,
|
|
4816
|
+
summary: action.summary,
|
|
4817
|
+
updatedAt: Date.now()
|
|
4818
|
+
}
|
|
4819
|
+
};
|
|
4820
|
+
case "brainPromptSet":
|
|
4821
|
+
return { ...state, brainPrompt: action.prompt };
|
|
4822
|
+
case "brainPromptClear":
|
|
4823
|
+
return { ...state, brainPrompt: null };
|
|
4577
4824
|
case "pickerOpen":
|
|
4578
4825
|
return {
|
|
4579
4826
|
...state,
|
|
@@ -4710,8 +4957,10 @@ function reducer(state, action) {
|
|
|
4710
4957
|
step: "provider",
|
|
4711
4958
|
providerOptions: action.providers,
|
|
4712
4959
|
modelOptions: [],
|
|
4960
|
+
filteredOptions: [],
|
|
4713
4961
|
selected: 0,
|
|
4714
|
-
hint: void 0
|
|
4962
|
+
hint: void 0,
|
|
4963
|
+
searchQuery: ""
|
|
4715
4964
|
}
|
|
4716
4965
|
};
|
|
4717
4966
|
case "modelPickerClose":
|
|
@@ -4722,12 +4971,15 @@ function reducer(state, action) {
|
|
|
4722
4971
|
step: "provider",
|
|
4723
4972
|
providerOptions: [],
|
|
4724
4973
|
modelOptions: [],
|
|
4725
|
-
|
|
4974
|
+
filteredOptions: [],
|
|
4975
|
+
selected: 0,
|
|
4976
|
+
searchQuery: ""
|
|
4726
4977
|
}
|
|
4727
4978
|
};
|
|
4728
4979
|
case "modelPickerMove": {
|
|
4729
4980
|
if (!state.modelPicker.open) return state;
|
|
4730
|
-
const
|
|
4981
|
+
const list = state.modelPicker.step === "provider" ? state.modelPicker.providerOptions : state.modelPicker.filteredOptions;
|
|
4982
|
+
const len = list.length;
|
|
4731
4983
|
if (len === 0) return state;
|
|
4732
4984
|
const next = (state.modelPicker.selected + action.delta + len) % len;
|
|
4733
4985
|
return {
|
|
@@ -4742,9 +4994,11 @@ function reducer(state, action) {
|
|
|
4742
4994
|
...state.modelPicker,
|
|
4743
4995
|
step: "model",
|
|
4744
4996
|
modelOptions: action.models,
|
|
4997
|
+
filteredOptions: action.models,
|
|
4745
4998
|
selected: 0,
|
|
4746
4999
|
pickedProviderId: action.providerId,
|
|
4747
|
-
hint: void 0
|
|
5000
|
+
hint: void 0,
|
|
5001
|
+
searchQuery: ""
|
|
4748
5002
|
}
|
|
4749
5003
|
};
|
|
4750
5004
|
case "modelPickerBack":
|
|
@@ -4754,11 +5008,29 @@ function reducer(state, action) {
|
|
|
4754
5008
|
...state.modelPicker,
|
|
4755
5009
|
step: "provider",
|
|
4756
5010
|
modelOptions: [],
|
|
5011
|
+
filteredOptions: [],
|
|
4757
5012
|
selected: 0,
|
|
4758
5013
|
pickedProviderId: void 0,
|
|
5014
|
+
hint: void 0,
|
|
5015
|
+
searchQuery: ""
|
|
5016
|
+
}
|
|
5017
|
+
};
|
|
5018
|
+
case "modelPickerSearch": {
|
|
5019
|
+
if (!state.modelPicker.open || state.modelPicker.step !== "model") return state;
|
|
5020
|
+
const q = action.query.toLowerCase();
|
|
5021
|
+
const filtered = q ? state.modelPicker.modelOptions.filter((id) => id.toLowerCase().includes(q)) : state.modelPicker.modelOptions;
|
|
5022
|
+
const selected = filtered.length > 0 ? Math.min(state.modelPicker.selected, filtered.length - 1) : 0;
|
|
5023
|
+
return {
|
|
5024
|
+
...state,
|
|
5025
|
+
modelPicker: {
|
|
5026
|
+
...state.modelPicker,
|
|
5027
|
+
filteredOptions: filtered,
|
|
5028
|
+
selected,
|
|
5029
|
+
searchQuery: action.query,
|
|
4759
5030
|
hint: void 0
|
|
4760
5031
|
}
|
|
4761
5032
|
};
|
|
5033
|
+
}
|
|
4762
5034
|
case "modelPickerHint":
|
|
4763
5035
|
return {
|
|
4764
5036
|
...state,
|
|
@@ -5534,6 +5806,7 @@ function App({
|
|
|
5534
5806
|
const { exit } = useApp();
|
|
5535
5807
|
const [liveModel, setLiveModel] = useState(model);
|
|
5536
5808
|
const [liveProvider, setLiveProvider] = useState(provider ?? "agent");
|
|
5809
|
+
const [activeMaxContext, setActiveMaxContext] = useState(effectiveMaxContext);
|
|
5537
5810
|
const [yoloLive, setYoloLive] = useState(yolo);
|
|
5538
5811
|
const [autonomyLive, setAutonomyLive] = useState(getAutonomy?.() ?? "off");
|
|
5539
5812
|
const [hiddenItems, setHiddenItems] = useState(statuslineHiddenItems);
|
|
@@ -5602,6 +5875,8 @@ function App({
|
|
|
5602
5875
|
steeringPending: false,
|
|
5603
5876
|
steerSnapshot: null,
|
|
5604
5877
|
hint: "",
|
|
5878
|
+
brain: { state: "idle" },
|
|
5879
|
+
brainPrompt: null,
|
|
5605
5880
|
nextId: 1,
|
|
5606
5881
|
picker: { open: false, query: "", matches: [], selected: 0 },
|
|
5607
5882
|
slashPicker: { open: false, query: "", matches: [], selected: 0 },
|
|
@@ -5615,7 +5890,9 @@ function App({
|
|
|
5615
5890
|
step: "provider",
|
|
5616
5891
|
providerOptions: [],
|
|
5617
5892
|
modelOptions: [],
|
|
5618
|
-
|
|
5893
|
+
filteredOptions: [],
|
|
5894
|
+
selected: 0,
|
|
5895
|
+
searchQuery: ""
|
|
5619
5896
|
},
|
|
5620
5897
|
autonomyPicker: { open: false, options: [], selected: 0 },
|
|
5621
5898
|
settingsPicker: { open: false, field: 0, mode: "off", delayMs: 0 },
|
|
@@ -5943,7 +6220,7 @@ function App({
|
|
|
5943
6220
|
clearInterval(t);
|
|
5944
6221
|
};
|
|
5945
6222
|
}, [agent.ctx.cwd]);
|
|
5946
|
-
const maxContext =
|
|
6223
|
+
const maxContext = activeMaxContext ?? agent.ctx.provider.capabilities.maxContext;
|
|
5947
6224
|
const currentContextTokens = (tokenCounter?.currentRequestTokens()?.input ?? 0) + (tokenCounter?.currentRequestTokens()?.cacheRead ?? 0);
|
|
5948
6225
|
const contextWindow = useMemo(() => {
|
|
5949
6226
|
void state.contextChipVersion;
|
|
@@ -5989,10 +6266,10 @@ function App({
|
|
|
5989
6266
|
currentTool: state.leader.currentTool,
|
|
5990
6267
|
ctxPct: state.leader.ctxPct,
|
|
5991
6268
|
ctxTokens: state.leader.ctxTokens,
|
|
5992
|
-
ctxMaxTokens: state.leader.ctxMaxTokens
|
|
6269
|
+
ctxMaxTokens: state.leader.ctxMaxTokens ?? effectiveMaxContext
|
|
5993
6270
|
};
|
|
5994
6271
|
return { leader: leaderEntry, ...state.fleet };
|
|
5995
|
-
}, [state.fleet, state.leader, state.status, provider, model]);
|
|
6272
|
+
}, [state.fleet, state.leader, state.status, provider, model, effectiveMaxContext]);
|
|
5996
6273
|
const STREAM_COLORS = ["cyan", "magenta", "yellow", "green", "blue"];
|
|
5997
6274
|
const labelsRef = useRef(/* @__PURE__ */ new Map());
|
|
5998
6275
|
const labelFor = (id, name) => {
|
|
@@ -6769,6 +7046,7 @@ function App({
|
|
|
6769
7046
|
});
|
|
6770
7047
|
});
|
|
6771
7048
|
const offLeaderCtxPct = events.on("ctx.pct", (e) => {
|
|
7049
|
+
setActiveMaxContext(e.maxContext);
|
|
6772
7050
|
dispatch({
|
|
6773
7051
|
type: "leaderCtxPct",
|
|
6774
7052
|
load: e.load,
|
|
@@ -6776,6 +7054,9 @@ function App({
|
|
|
6776
7054
|
maxContext: e.maxContext
|
|
6777
7055
|
});
|
|
6778
7056
|
});
|
|
7057
|
+
const offLeaderMaxContext = events.on("ctx.max_context", (e) => {
|
|
7058
|
+
if (e.maxContext > 0) setActiveMaxContext(e.maxContext);
|
|
7059
|
+
});
|
|
6779
7060
|
const offTool = events.on("subagent.tool_executed", (e) => {
|
|
6780
7061
|
dispatch({
|
|
6781
7062
|
type: "fleetTool",
|
|
@@ -6796,6 +7077,7 @@ function App({
|
|
|
6796
7077
|
offIterationSummary();
|
|
6797
7078
|
offCtxPct();
|
|
6798
7079
|
offLeaderCtxPct();
|
|
7080
|
+
offLeaderMaxContext();
|
|
6799
7081
|
offTool();
|
|
6800
7082
|
};
|
|
6801
7083
|
}, [events, director]);
|
|
@@ -6823,6 +7105,71 @@ function App({
|
|
|
6823
7105
|
offRewound();
|
|
6824
7106
|
};
|
|
6825
7107
|
}, [events, onClearHistory]);
|
|
7108
|
+
useEffect(() => {
|
|
7109
|
+
const requestSummary = (request) => `${request.source}: ${request.question}`.slice(0, 80);
|
|
7110
|
+
const addBrainEntry = (status, payload) => {
|
|
7111
|
+
const p = payload;
|
|
7112
|
+
const decision = p.decision.optionId ?? p.decision.text ?? p.decision.reason ?? p.decision.prompt ?? p.decision.type;
|
|
7113
|
+
dispatch({
|
|
7114
|
+
type: "brainStatus",
|
|
7115
|
+
state: status,
|
|
7116
|
+
source: p.request.source,
|
|
7117
|
+
risk: p.request.risk,
|
|
7118
|
+
summary: decision
|
|
7119
|
+
});
|
|
7120
|
+
if (status === "ask_human") {
|
|
7121
|
+
dispatch({
|
|
7122
|
+
type: "brainPromptSet",
|
|
7123
|
+
prompt: {
|
|
7124
|
+
requestId: p.request.id,
|
|
7125
|
+
source: p.request.source,
|
|
7126
|
+
risk: p.request.risk,
|
|
7127
|
+
question: p.request.question,
|
|
7128
|
+
context: p.request.context,
|
|
7129
|
+
options: p.request.options
|
|
7130
|
+
}
|
|
7131
|
+
});
|
|
7132
|
+
} else {
|
|
7133
|
+
dispatch({ type: "brainPromptClear" });
|
|
7134
|
+
}
|
|
7135
|
+
dispatch({
|
|
7136
|
+
type: "addEntry",
|
|
7137
|
+
entry: {
|
|
7138
|
+
kind: "brain",
|
|
7139
|
+
status,
|
|
7140
|
+
source: p.request.source,
|
|
7141
|
+
risk: p.request.risk,
|
|
7142
|
+
question: p.request.question,
|
|
7143
|
+
decision,
|
|
7144
|
+
rationale: p.decision.rationale
|
|
7145
|
+
}
|
|
7146
|
+
});
|
|
7147
|
+
};
|
|
7148
|
+
const offRequested = events.on("brain.decision_requested", ({ request }) => {
|
|
7149
|
+
dispatch({
|
|
7150
|
+
type: "brainStatus",
|
|
7151
|
+
state: "deciding",
|
|
7152
|
+
source: request.source,
|
|
7153
|
+
risk: request.risk,
|
|
7154
|
+
summary: requestSummary(request)
|
|
7155
|
+
});
|
|
7156
|
+
});
|
|
7157
|
+
const offAnswered = events.on("brain.decision_answered", (payload) => {
|
|
7158
|
+
addBrainEntry("answered", payload);
|
|
7159
|
+
});
|
|
7160
|
+
const offAskHuman = events.on("brain.decision_ask_human", (payload) => {
|
|
7161
|
+
addBrainEntry("ask_human", payload);
|
|
7162
|
+
});
|
|
7163
|
+
const offDenied = events.on("brain.decision_denied", (payload) => {
|
|
7164
|
+
addBrainEntry("denied", payload);
|
|
7165
|
+
});
|
|
7166
|
+
return () => {
|
|
7167
|
+
offRequested();
|
|
7168
|
+
offAnswered();
|
|
7169
|
+
offAskHuman();
|
|
7170
|
+
offDenied();
|
|
7171
|
+
};
|
|
7172
|
+
}, [events]);
|
|
6826
7173
|
useEffect(() => {
|
|
6827
7174
|
if (!subscribeAutoPhase) return;
|
|
6828
7175
|
const handler = (event, payload) => {
|
|
@@ -7590,6 +7937,19 @@ function App({
|
|
|
7590
7937
|
dispatch({ type: "modelPickerMove", delta: 1 });
|
|
7591
7938
|
return;
|
|
7592
7939
|
}
|
|
7940
|
+
if (state.modelPicker.step === "model" && input && !key.return && !key.backspace) {
|
|
7941
|
+
dispatch({ type: "modelPickerSearch", query: state.modelPicker.searchQuery + input });
|
|
7942
|
+
return;
|
|
7943
|
+
}
|
|
7944
|
+
if (state.modelPicker.step === "model" && key.backspace) {
|
|
7945
|
+
const q = state.modelPicker.searchQuery;
|
|
7946
|
+
if (q.length > 0) {
|
|
7947
|
+
dispatch({ type: "modelPickerSearch", query: q.slice(0, -1) });
|
|
7948
|
+
} else {
|
|
7949
|
+
dispatch({ type: "modelPickerBack" });
|
|
7950
|
+
}
|
|
7951
|
+
return;
|
|
7952
|
+
}
|
|
7593
7953
|
if (isEnter) {
|
|
7594
7954
|
inputGateRef.current = true;
|
|
7595
7955
|
try {
|
|
@@ -7604,7 +7964,7 @@ function App({
|
|
|
7604
7964
|
return;
|
|
7605
7965
|
}
|
|
7606
7966
|
const providerId = state.modelPicker.pickedProviderId;
|
|
7607
|
-
const modelId = state.modelPicker.
|
|
7967
|
+
const modelId = state.modelPicker.filteredOptions[state.modelPicker.selected];
|
|
7608
7968
|
if (!providerId || !modelId) return;
|
|
7609
7969
|
const err = switchProviderAndModel?.(providerId, modelId);
|
|
7610
7970
|
if (err) {
|
|
@@ -7613,6 +7973,7 @@ function App({
|
|
|
7613
7973
|
}
|
|
7614
7974
|
setLiveProvider(providerId);
|
|
7615
7975
|
setLiveModel(modelId);
|
|
7976
|
+
setActiveMaxContext(agent.ctx.provider.capabilities.maxContext);
|
|
7616
7977
|
dispatch({
|
|
7617
7978
|
type: "addEntry",
|
|
7618
7979
|
entry: { kind: "info", text: `Switched to ${providerId} / ${modelId}.` }
|
|
@@ -8213,6 +8574,10 @@ function App({
|
|
|
8213
8574
|
if (ctxModel && ctxModel !== liveModel) setLiveModel(ctxModel);
|
|
8214
8575
|
const ctxProviderId = agent.ctx.provider?.id;
|
|
8215
8576
|
if (ctxProviderId && ctxProviderId !== liveProvider) setLiveProvider(ctxProviderId);
|
|
8577
|
+
const ctxMaxContext = agent.ctx.provider.capabilities.maxContext;
|
|
8578
|
+
if (ctxMaxContext > 0 && ctxMaxContext !== activeMaxContext) {
|
|
8579
|
+
setActiveMaxContext(ctxMaxContext);
|
|
8580
|
+
}
|
|
8216
8581
|
if (getYolo) {
|
|
8217
8582
|
const currentYolo = getYolo();
|
|
8218
8583
|
if (currentYolo !== yoloLive) setYoloLive(currentYolo);
|
|
@@ -8405,8 +8770,10 @@ User message:
|
|
|
8405
8770
|
step: state.modelPicker.step,
|
|
8406
8771
|
providerOptions: state.modelPicker.providerOptions,
|
|
8407
8772
|
modelOptions: state.modelPicker.modelOptions,
|
|
8773
|
+
filteredOptions: state.modelPicker.filteredOptions,
|
|
8408
8774
|
selected: state.modelPicker.selected,
|
|
8409
8775
|
pickedProviderId: state.modelPicker.pickedProviderId,
|
|
8776
|
+
searchQuery: state.modelPicker.searchQuery,
|
|
8410
8777
|
hint: state.modelPicker.hint
|
|
8411
8778
|
}
|
|
8412
8779
|
) : null,
|
|
@@ -8437,6 +8804,16 @@ User message:
|
|
|
8437
8804
|
onClose: () => dispatch({ type: "rewindOverlayClose" })
|
|
8438
8805
|
}
|
|
8439
8806
|
) : null,
|
|
8807
|
+
state.brainPrompt ? /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginY: 1, flexShrink: 0, children: /* @__PURE__ */ jsx(
|
|
8808
|
+
BrainDecisionPrompt,
|
|
8809
|
+
{
|
|
8810
|
+
...state.brainPrompt,
|
|
8811
|
+
onAnswer: (answer) => {
|
|
8812
|
+
events.emit("brain.human_answered", { ...answer, at: Date.now() });
|
|
8813
|
+
dispatch({ type: "brainPromptClear" });
|
|
8814
|
+
}
|
|
8815
|
+
}
|
|
8816
|
+
) }) : null,
|
|
8440
8817
|
state.confirmQueue.length > 0 && (() => {
|
|
8441
8818
|
const head = state.confirmQueue[0];
|
|
8442
8819
|
let resolved = false;
|
|
@@ -8474,6 +8851,7 @@ User message:
|
|
|
8474
8851
|
fleet: fleetCounts,
|
|
8475
8852
|
git: gitInfo,
|
|
8476
8853
|
context: contextWindow,
|
|
8854
|
+
brain: state.brain,
|
|
8477
8855
|
projectName,
|
|
8478
8856
|
subagentCount: Object.keys(state.fleet).length,
|
|
8479
8857
|
processCount: getProcessRegistry().activeCount,
|