@wrongstack/tui 0.255.0 → 0.256.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 +28 -9
- package/dist/index.js +149 -35
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
package/dist/index.d.ts
CHANGED
|
@@ -153,6 +153,8 @@ type Settings = {
|
|
|
153
153
|
featureMemory: boolean;
|
|
154
154
|
featureSkills: boolean;
|
|
155
155
|
featureModelsRegistry: boolean;
|
|
156
|
+
/** Token-saving mode: omits non-essential tools and trims system prompt. */
|
|
157
|
+
featureTokenSaving: boolean;
|
|
156
158
|
contextAutoCompact: boolean;
|
|
157
159
|
contextStrategy: 'hybrid' | 'intelligent' | 'selective';
|
|
158
160
|
logLevel: 'error' | 'warn' | 'info' | 'debug' | 'trace';
|
|
@@ -269,6 +271,10 @@ interface RunTuiOptions {
|
|
|
269
271
|
confirmExit?: boolean | undefined;
|
|
270
272
|
/** Active agent mode label shown in the status bar (e.g. "teach", "brief"). */
|
|
271
273
|
modeLabel?: string | undefined;
|
|
274
|
+
/** Token-saving mode indicator — shown in the TUI status bar. */
|
|
275
|
+
tokenSavingMode?: boolean | undefined;
|
|
276
|
+
/** Number of registered tools — shown on the status bar line 2. */
|
|
277
|
+
toolCount?: number | undefined;
|
|
272
278
|
/** Live getter for the agent mode label so the status bar updates after /mode. */
|
|
273
279
|
getModeLabel?: (() => string) | undefined;
|
|
274
280
|
/**
|
|
@@ -322,6 +328,13 @@ interface RunTuiOptions {
|
|
|
322
328
|
enabled: boolean;
|
|
323
329
|
setEnabled: (enabled: boolean) => void;
|
|
324
330
|
} | undefined;
|
|
331
|
+
/**
|
|
332
|
+
* Controller for the `/interrupt` slash command. The App installs the real
|
|
333
|
+
* `abortLeader` on mount so the command can abort the in-flight leader run.
|
|
334
|
+
*/
|
|
335
|
+
interruptController?: {
|
|
336
|
+
abortLeader: () => boolean;
|
|
337
|
+
} | undefined;
|
|
325
338
|
/**
|
|
326
339
|
* Controller for the `/enhance on|off` prompt-refinement toggle. The App
|
|
327
340
|
* installs a dispatch-backed `setEnabled` here on mount so the slash command
|
|
@@ -338,8 +351,8 @@ interface RunTuiOptions {
|
|
|
338
351
|
* visible bar without a round-trip. The initial value is loaded from
|
|
339
352
|
* the config file before App mounts.
|
|
340
353
|
*/
|
|
341
|
-
statuslineHiddenItems: Array<'todos' | 'plan' | 'tasks' | 'fleet' | 'git' | 'elapsed' | 'context' | 'cost'>;
|
|
342
|
-
setStatuslineHiddenItems: (items: Array<'todos' | 'plan' | 'tasks' | 'fleet' | 'git' | 'elapsed' | 'context' | 'cost'>) => void;
|
|
354
|
+
statuslineHiddenItems: Array<'todos' | 'plan' | 'tasks' | 'fleet' | 'git' | 'elapsed' | 'context' | 'cost' | 'working_dir'>;
|
|
355
|
+
setStatuslineHiddenItems: (items: Array<'todos' | 'plan' | 'tasks' | 'fleet' | 'git' | 'elapsed' | 'context' | 'cost' | 'working_dir'>) => void;
|
|
343
356
|
/**
|
|
344
357
|
* Controller for the agents monitor overlay. App installs a dispatch-backed
|
|
345
358
|
* setter on mount so the `/agents on|off` slash command can toggle the
|
|
@@ -541,16 +554,22 @@ declare function replaySessionEvents(events: SessionEvent[], startId: number): H
|
|
|
541
554
|
* Unified next-steps suggestion parser.
|
|
542
555
|
*
|
|
543
556
|
* Three code paths feed into the suggestion store:
|
|
544
|
-
* 1. TUI rendering — entry.tsx parses "💡 Next steps" from assistant output
|
|
545
|
-
* 2. REPL store — repl.ts parses "💡 Next steps" from final agent output
|
|
557
|
+
* 1. TUI rendering — entry.tsx parses "💡 Next steps" or "<next_steps>" from assistant output
|
|
558
|
+
* 2. REPL store — repl.ts parses "💡 Next steps" or "<next_steps>" from final agent output
|
|
546
559
|
* 3. /suggest output — suggest.ts parses LLM-generated numbered lists
|
|
547
560
|
*
|
|
548
561
|
* Heading mode (`requireHeading = true`):
|
|
549
|
-
* strict=true — only 💡 emoji heading (TUI rendering)
|
|
550
|
-
* strict=false — 💡, ##, plain "Next steps" headings (REPL store)
|
|
562
|
+
* strict=true — only 💡 emoji heading or <next_steps> tag (TUI rendering)
|
|
563
|
+
* strict=false — 💡, ##, plain "Next steps", or <next_steps> headings (REPL store)
|
|
551
564
|
*
|
|
552
565
|
* Raw mode (`requireHeading = false`):
|
|
553
566
|
* Parses numbered/bullet items from anywhere in text (subagent /suggest output).
|
|
567
|
+
*
|
|
568
|
+
* Supported formats:
|
|
569
|
+
* 💡 Next steps (old emoji format)
|
|
570
|
+
* ## Next steps (markdown heading)
|
|
571
|
+
* Next steps (plain text)
|
|
572
|
+
* <next_steps> (new XML tag format - preferred)
|
|
554
573
|
*/
|
|
555
574
|
interface ParsedNextStep {
|
|
556
575
|
index: number;
|
|
@@ -562,16 +581,16 @@ interface ParseNextStepsResult {
|
|
|
562
581
|
/** Flat string array — what gets stored in the suggestion store. */
|
|
563
582
|
texts: string[];
|
|
564
583
|
/**
|
|
565
|
-
* Content with the entire "💡 Next steps" block removed.
|
|
584
|
+
* Content with the entire "💡 Next steps" or "<next_steps>" block removed.
|
|
566
585
|
* Used by entry.tsx to strip suggestions from the rendered message body.
|
|
567
586
|
*/
|
|
568
587
|
stripped: string;
|
|
569
588
|
}
|
|
570
589
|
/**
|
|
571
|
-
* Parse "💡 Next steps" blocks from assistant output (or raw numbered lines).
|
|
590
|
+
* Parse "<next_steps>" or "💡 Next steps" blocks from assistant output (or raw numbered lines).
|
|
572
591
|
*
|
|
573
592
|
* @param content — raw assistant message text or subagent output
|
|
574
|
-
* @param strict — when true,
|
|
593
|
+
* @param strict — when true, accepts 💡 emoji heading OR <next_steps> XML tag (TUI rendering).
|
|
575
594
|
* when false, also accepts ## / plain "Next steps" headings (REPL store).
|
|
576
595
|
* @param requireHeading — when true, a heading must precede the item list.
|
|
577
596
|
* when false, numbered/bullet items are parsed from anywhere in text
|
package/dist/index.js
CHANGED
|
@@ -163,7 +163,9 @@ function StatusBar({
|
|
|
163
163
|
nextStepsAutoSubmitCountdown,
|
|
164
164
|
autoProceedCountdown,
|
|
165
165
|
sessionCount,
|
|
166
|
-
mailbox
|
|
166
|
+
mailbox,
|
|
167
|
+
tokenSavingMode,
|
|
168
|
+
toolCount
|
|
167
169
|
}) {
|
|
168
170
|
const { stdout } = useStdout();
|
|
169
171
|
const [termWidth, setTermWidth] = useState(stdout?.columns ?? 90);
|
|
@@ -202,7 +204,7 @@ function StatusBar({
|
|
|
202
204
|
const statePrefix = state === "idle" || state === "aborting" ? "\u25CF" : spinner;
|
|
203
205
|
const thinking = state === "running" || state === "streaming";
|
|
204
206
|
const hasAutoProceed = autoProceedCountdown != null && autoProceedCountdown > 0;
|
|
205
|
-
const hasSecondLine = yolo || autonomy && autonomy !== "off" || startedAt != null || git !== null && git !== void 0 || projectName !== void 0 && projectName.length > 0 || workingDir !== void 0 && workingDir.length > 0 || goalSummary !== null && goalSummary !== void 0 || !!modeLabel || hasAutoProceed;
|
|
207
|
+
const hasSecondLine = yolo || autonomy && autonomy !== "off" || startedAt != null || git !== null && git !== void 0 || projectName !== void 0 && projectName.length > 0 || workingDir !== void 0 && workingDir.length > 0 || goalSummary !== null && goalSummary !== void 0 || !!modeLabel || hasAutoProceed || tokenSavingMode || typeof toolCount === "number" && toolCount > 0;
|
|
206
208
|
const fleetHasActivity = fleet && (fleet.running > 0 || fleet.idle > 0 || fleet.pending > 0 || fleet.completed > 0) || subagentCount > 0;
|
|
207
209
|
const hasBrainActivity = !!brain && brain.state !== "idle";
|
|
208
210
|
const hasDebugStream = !!debugStreamStats;
|
|
@@ -423,6 +425,19 @@ function StatusBar({
|
|
|
423
425
|
" session",
|
|
424
426
|
sessionCount === 1 ? "" : "s"
|
|
425
427
|
] })
|
|
428
|
+
] }) : null,
|
|
429
|
+
toolCount != null ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
430
|
+
yolo || startedAt != null || projectName || workingDir || git || sessionCount ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
431
|
+
/* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
|
|
432
|
+
"\u{1F527} ",
|
|
433
|
+
toolCount,
|
|
434
|
+
" tool",
|
|
435
|
+
toolCount === 1 ? "" : "s"
|
|
436
|
+
] })
|
|
437
|
+
] }) : null,
|
|
438
|
+
tokenSavingMode ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
439
|
+
yolo || startedAt != null || projectName || workingDir || git || sessionCount || toolCount ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
440
|
+
/* @__PURE__ */ jsx(Text, { color: "yellow", bold: true, children: "\u{1F4BE} save" })
|
|
426
441
|
] }) : null
|
|
427
442
|
] }) : /* @__PURE__ */ jsx(Box, { height: 1, children: /* @__PURE__ */ jsx(Text, { children: " " }) }),
|
|
428
443
|
hasThirdLine ? /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 2, children: [
|
|
@@ -2846,7 +2861,7 @@ function MarkdownView({
|
|
|
2846
2861
|
const tableEnd = detectTable(lines, i);
|
|
2847
2862
|
if (tableEnd > i) {
|
|
2848
2863
|
rows.push(
|
|
2849
|
-
/* @__PURE__ */ jsx(Text, { children: renderTable(lines.slice(i, tableEnd), tableBudget) }, `t${key++}`)
|
|
2864
|
+
/* @__PURE__ */ jsx(Box, { width: tableBudget, backgroundColor: "transparent", children: /* @__PURE__ */ jsx(Text, { children: renderTable(lines.slice(i, tableEnd), tableBudget) }) }, `t${key++}`)
|
|
2850
2865
|
);
|
|
2851
2866
|
i = tableEnd;
|
|
2852
2867
|
continue;
|
|
@@ -2866,10 +2881,14 @@ function MarkdownView({
|
|
|
2866
2881
|
rows.push(
|
|
2867
2882
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
|
|
2868
2883
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " " }),
|
|
2869
|
-
/[\u2500-\u257F]/.test(qContent) ?
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2884
|
+
/[\u2500-\u257F]/.test(qContent) ? (
|
|
2885
|
+
// Box-drawing characters inside blockquotes also need transparent
|
|
2886
|
+
// background to avoid inheriting the message panel background.
|
|
2887
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "row", backgroundColor: "transparent", children: [...qContent].slice(0, (contentWidth ?? termWidth) - 2).map((ch, ci) => (
|
|
2888
|
+
/* biome-ignore lint/suspicious/noArrayIndexKey: characters are not reorderable */
|
|
2889
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: ch }, ci)
|
|
2890
|
+
)) })
|
|
2891
|
+
) : /* @__PURE__ */ jsx(InlineLine, { tokens: parseInline(qContent), dim: true })
|
|
2873
2892
|
] }, `q${key++}`)
|
|
2874
2893
|
);
|
|
2875
2894
|
continue;
|
|
@@ -2898,7 +2917,7 @@ function MarkdownView({
|
|
|
2898
2917
|
const maxW = contentWidth ?? termWidth;
|
|
2899
2918
|
const chars = [...line].slice(0, maxW);
|
|
2900
2919
|
rows.push(
|
|
2901
|
-
/* @__PURE__ */ jsx(Box, { flexDirection: "row", children: chars.map((ch, ci) => (
|
|
2920
|
+
/* @__PURE__ */ jsx(Box, { width: maxW, backgroundColor: "transparent", flexDirection: "row", children: chars.map((ch, ci) => (
|
|
2902
2921
|
/* biome-ignore lint/suspicious/noArrayIndexKey: characters are not reorderable */
|
|
2903
2922
|
/* @__PURE__ */ jsx(Text, { children: ch }, ci)
|
|
2904
2923
|
)) }, `bx${key++}`)
|
|
@@ -3800,11 +3819,12 @@ function Banner({
|
|
|
3800
3819
|
}
|
|
3801
3820
|
|
|
3802
3821
|
// src/components/suggestions.ts
|
|
3803
|
-
var STRICT_HEADING_RE =
|
|
3822
|
+
var STRICT_HEADING_RE = /(?:💡\s*Next steps?|<next_steps>)\s*\n+/i;
|
|
3804
3823
|
var PERMISSIVE_HEADING_PATTERNS = [
|
|
3805
3824
|
{ re: /💡\s*Next steps?\s*\n+/i, label: "emoji" },
|
|
3806
3825
|
{ re: /##?\s*Next steps?\s*\n+/i, label: "markdown" },
|
|
3807
|
-
{ re: /\n{1,2}Next steps?\s*\n+/i, label: "plain" }
|
|
3826
|
+
{ re: /\n{1,2}Next steps?\s*\n+/i, label: "plain" },
|
|
3827
|
+
{ re: /<next_steps>\s*\n+/i, label: "xml-tag" }
|
|
3808
3828
|
];
|
|
3809
3829
|
var ITEM_RE = /^(?:(\d+)[.)]\s*|[-*•]\s*)(.+)$/;
|
|
3810
3830
|
var MAX_STEPS = 6;
|
|
@@ -3888,6 +3908,10 @@ function findBlockEnd(afterHeading, stepCount) {
|
|
|
3888
3908
|
let found = 0;
|
|
3889
3909
|
for (const rawLine of lines) {
|
|
3890
3910
|
const line = rawLine.trim();
|
|
3911
|
+
if (line === "</next_steps>") {
|
|
3912
|
+
consumed += rawLine.length + 1;
|
|
3913
|
+
break;
|
|
3914
|
+
}
|
|
3891
3915
|
if (!line) {
|
|
3892
3916
|
consumed += rawLine.length + 1;
|
|
3893
3917
|
continue;
|
|
@@ -3952,6 +3976,7 @@ var Entry = React5.memo(function Entry2({
|
|
|
3952
3976
|
borderRight: false,
|
|
3953
3977
|
borderBottom: false,
|
|
3954
3978
|
borderColor: theme.user,
|
|
3979
|
+
backgroundColor: "#1e1e2e",
|
|
3955
3980
|
paddingLeft: 1,
|
|
3956
3981
|
children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
3957
3982
|
/* @__PURE__ */ jsx(Text, { bold: true, color: theme.user, children: "USER " }),
|
|
@@ -3981,8 +4006,9 @@ var Entry = React5.memo(function Entry2({
|
|
|
3981
4006
|
borderStyle: "single",
|
|
3982
4007
|
borderTop: false,
|
|
3983
4008
|
borderRight: false,
|
|
3984
|
-
borderBottom:
|
|
4009
|
+
borderBottom: false,
|
|
3985
4010
|
borderColor: theme.assistant,
|
|
4011
|
+
backgroundColor: "#1e1e2e",
|
|
3986
4012
|
paddingLeft: 1,
|
|
3987
4013
|
children: [
|
|
3988
4014
|
/* @__PURE__ */ jsx(Box, { flexDirection: "row", children: /* @__PURE__ */ jsx(Text, { bold: true, color: theme.assistant, children: "ASSISTANT" }) }),
|
|
@@ -5543,7 +5569,7 @@ var MODE_DESC = {
|
|
|
5543
5569
|
suggest: "Shows next-step suggestions after each turn",
|
|
5544
5570
|
auto: "Self-driving \u2014 agent continues automatically"
|
|
5545
5571
|
};
|
|
5546
|
-
var SETTINGS_FIELD_COUNT =
|
|
5572
|
+
var SETTINGS_FIELD_COUNT = 26;
|
|
5547
5573
|
var CONFIG_SCOPES = ["global", "project"];
|
|
5548
5574
|
function SettingsPicker({
|
|
5549
5575
|
field,
|
|
@@ -5560,6 +5586,7 @@ function SettingsPicker({
|
|
|
5560
5586
|
featureMemory,
|
|
5561
5587
|
featureSkills,
|
|
5562
5588
|
featureModelsRegistry,
|
|
5589
|
+
featureTokenSaving,
|
|
5563
5590
|
contextAutoCompact,
|
|
5564
5591
|
contextStrategy,
|
|
5565
5592
|
logLevel,
|
|
@@ -5643,6 +5670,11 @@ function SettingsPicker({
|
|
|
5643
5670
|
value: boolVal(featureModelsRegistry),
|
|
5644
5671
|
detail: "Fetch models.dev catalog at startup"
|
|
5645
5672
|
},
|
|
5673
|
+
{
|
|
5674
|
+
label: "Token-saving mode",
|
|
5675
|
+
value: boolVal(featureTokenSaving),
|
|
5676
|
+
detail: "Omit non-essential tools and trim system prompt to save tokens"
|
|
5677
|
+
},
|
|
5646
5678
|
// ── Context ──
|
|
5647
5679
|
{ section: "Context" },
|
|
5648
5680
|
{
|
|
@@ -6743,6 +6775,36 @@ function handleCollabDone(event, dispatch, stateRef) {
|
|
|
6743
6775
|
verdict: payload.report.overallVerdict ?? "needs_revision"
|
|
6744
6776
|
});
|
|
6745
6777
|
}
|
|
6778
|
+
function useStatuslineState(opts) {
|
|
6779
|
+
const [liveModel, setLiveModel] = useState(opts.model);
|
|
6780
|
+
const [liveProvider, setLiveProvider] = useState(opts.provider ?? "agent");
|
|
6781
|
+
const [activeMaxContext, setActiveMaxContext] = useState(opts.effectiveMaxContext);
|
|
6782
|
+
const [yoloLive, setYoloLive] = useState(opts.yolo);
|
|
6783
|
+
const [autonomyLive, setAutonomyLive] = useState(opts.getAutonomy?.() ?? "off");
|
|
6784
|
+
const [liveModeLabel, setLiveModeLabel] = useState(opts.modeLabel ?? "");
|
|
6785
|
+
const [hiddenItems, setHiddenItems] = useState(
|
|
6786
|
+
Array.isArray(opts.statuslineHiddenItems) ? [...opts.statuslineHiddenItems] : [...opts.statuslineHiddenItems]
|
|
6787
|
+
);
|
|
6788
|
+
const [sessionCount, setSessionCount] = useState(0);
|
|
6789
|
+
return {
|
|
6790
|
+
liveModel,
|
|
6791
|
+
setLiveModel,
|
|
6792
|
+
liveProvider,
|
|
6793
|
+
setLiveProvider,
|
|
6794
|
+
activeMaxContext,
|
|
6795
|
+
setActiveMaxContext,
|
|
6796
|
+
yoloLive,
|
|
6797
|
+
setYoloLive,
|
|
6798
|
+
autonomyLive,
|
|
6799
|
+
setAutonomyLive,
|
|
6800
|
+
liveModeLabel,
|
|
6801
|
+
setLiveModeLabel,
|
|
6802
|
+
hiddenItems,
|
|
6803
|
+
setHiddenItems,
|
|
6804
|
+
sessionCount,
|
|
6805
|
+
setSessionCount
|
|
6806
|
+
};
|
|
6807
|
+
}
|
|
6746
6808
|
function useTuiControllers({
|
|
6747
6809
|
dispatch,
|
|
6748
6810
|
streamFleet,
|
|
@@ -7809,6 +7871,7 @@ function reducer(state, action) {
|
|
|
7809
7871
|
featureMemory: action.featureMemory,
|
|
7810
7872
|
featureSkills: action.featureSkills,
|
|
7811
7873
|
featureModelsRegistry: action.featureModelsRegistry,
|
|
7874
|
+
featureTokenSaving: action.featureTokenSaving,
|
|
7812
7875
|
contextAutoCompact: action.contextAutoCompact,
|
|
7813
7876
|
contextStrategy: action.contextStrategy,
|
|
7814
7877
|
logLevel: action.logLevel,
|
|
@@ -7866,53 +7929,54 @@ function reducer(state, action) {
|
|
|
7866
7929
|
if (f === 10) return { ...state, settingsPicker: { ...sp, featureMemory: !sp.featureMemory, hint: void 0 } };
|
|
7867
7930
|
if (f === 11) return { ...state, settingsPicker: { ...sp, featureSkills: !sp.featureSkills, hint: void 0 } };
|
|
7868
7931
|
if (f === 12) return { ...state, settingsPicker: { ...sp, featureModelsRegistry: !sp.featureModelsRegistry, hint: void 0 } };
|
|
7869
|
-
if (f === 13) return { ...state, settingsPicker: { ...sp,
|
|
7870
|
-
if (f === 14) {
|
|
7932
|
+
if (f === 13) return { ...state, settingsPicker: { ...sp, featureTokenSaving: !sp.featureTokenSaving, hint: void 0 } };
|
|
7933
|
+
if (f === 14) return { ...state, settingsPicker: { ...sp, contextAutoCompact: !sp.contextAutoCompact, hint: void 0 } };
|
|
7934
|
+
if (f === 15) {
|
|
7871
7935
|
const i = COMPACTOR_STRATEGIES.indexOf(sp.contextStrategy);
|
|
7872
7936
|
const base = i < 0 ? 0 : i;
|
|
7873
7937
|
const next = (base + action.delta + COMPACTOR_STRATEGIES.length) % COMPACTOR_STRATEGIES.length;
|
|
7874
7938
|
return { ...state, settingsPicker: { ...sp, contextStrategy: expectDefined$1(COMPACTOR_STRATEGIES[next]), hint: void 0 } };
|
|
7875
7939
|
}
|
|
7876
|
-
if (f ===
|
|
7940
|
+
if (f === 16) {
|
|
7877
7941
|
const i = LOG_LEVELS.indexOf(sp.logLevel);
|
|
7878
7942
|
const base = i < 0 ? 0 : i;
|
|
7879
7943
|
const next = (base + action.delta + LOG_LEVELS.length) % LOG_LEVELS.length;
|
|
7880
7944
|
return { ...state, settingsPicker: { ...sp, logLevel: expectDefined$1(LOG_LEVELS[next]), hint: void 0 } };
|
|
7881
7945
|
}
|
|
7882
|
-
if (f ===
|
|
7946
|
+
if (f === 17) {
|
|
7883
7947
|
const i = AUDIT_LEVELS.indexOf(sp.auditLevel);
|
|
7884
7948
|
const base = i < 0 ? 0 : i;
|
|
7885
7949
|
const next = (base + action.delta + AUDIT_LEVELS.length) % AUDIT_LEVELS.length;
|
|
7886
7950
|
return { ...state, settingsPicker: { ...sp, auditLevel: expectDefined$1(AUDIT_LEVELS[next]), hint: void 0 } };
|
|
7887
7951
|
}
|
|
7888
|
-
if (f ===
|
|
7889
|
-
if (f ===
|
|
7952
|
+
if (f === 18) return { ...state, settingsPicker: { ...sp, indexOnStart: !sp.indexOnStart, hint: void 0 } };
|
|
7953
|
+
if (f === 19) {
|
|
7890
7954
|
const j = MAX_ITERATIONS_PRESETS.indexOf(sp.maxIterations);
|
|
7891
7955
|
const base = j < 0 ? 0 : j;
|
|
7892
7956
|
const next = (base + action.delta + MAX_ITERATIONS_PRESETS.length) % MAX_ITERATIONS_PRESETS.length;
|
|
7893
7957
|
return { ...state, settingsPicker: { ...sp, maxIterations: expectDefined$1(MAX_ITERATIONS_PRESETS[next]), hint: void 0 } };
|
|
7894
7958
|
}
|
|
7895
|
-
if (f ===
|
|
7959
|
+
if (f === 20) {
|
|
7896
7960
|
const aj = AUTO_PROCEED_MAX_PRESETS.indexOf(sp.autoProceedMaxIterations);
|
|
7897
7961
|
const abase = aj < 0 ? 0 : aj;
|
|
7898
7962
|
const anext = (abase + action.delta + AUTO_PROCEED_MAX_PRESETS.length) % AUTO_PROCEED_MAX_PRESETS.length;
|
|
7899
7963
|
return { ...state, settingsPicker: { ...sp, autoProceedMaxIterations: expectDefined$1(AUTO_PROCEED_MAX_PRESETS[anext]), hint: void 0 } };
|
|
7900
7964
|
}
|
|
7901
|
-
if (f ===
|
|
7965
|
+
if (f === 21) {
|
|
7902
7966
|
const ej = ENHANCE_DELAY_PRESETS.indexOf(sp.enhanceDelayMs);
|
|
7903
7967
|
const ebase = ej < 0 ? 0 : ej;
|
|
7904
7968
|
const enext = (ebase + action.delta + ENHANCE_DELAY_PRESETS.length) % ENHANCE_DELAY_PRESETS.length;
|
|
7905
7969
|
return { ...state, settingsPicker: { ...sp, enhanceDelayMs: expectDefined$1(ENHANCE_DELAY_PRESETS[enext]), hint: void 0 } };
|
|
7906
7970
|
}
|
|
7907
|
-
if (f ===
|
|
7908
|
-
if (f ===
|
|
7971
|
+
if (f === 22) return { ...state, settingsPicker: { ...sp, enhanceEnabled: !sp.enhanceEnabled, hint: void 0 } };
|
|
7972
|
+
if (f === 23) {
|
|
7909
7973
|
const i = ENHANCE_LANGUAGES.indexOf(sp.enhanceLanguage);
|
|
7910
7974
|
const base = i < 0 ? 0 : i;
|
|
7911
7975
|
const next = (base + action.delta + ENHANCE_LANGUAGES.length) % ENHANCE_LANGUAGES.length;
|
|
7912
7976
|
return { ...state, settingsPicker: { ...sp, enhanceLanguage: expectDefined$1(ENHANCE_LANGUAGES[next]), hint: void 0 } };
|
|
7913
7977
|
}
|
|
7914
|
-
if (f ===
|
|
7915
|
-
if (f ===
|
|
7978
|
+
if (f === 24) return { ...state, settingsPicker: { ...sp, debugStream: !sp.debugStream, hint: void 0 } };
|
|
7979
|
+
if (f === 25) {
|
|
7916
7980
|
const i = CONFIG_SCOPES.indexOf(sp.configScope);
|
|
7917
7981
|
const base = i < 0 ? 0 : i;
|
|
7918
7982
|
const next = (base + action.delta + CONFIG_SCOPES.length) % CONFIG_SCOPES.length;
|
|
@@ -8751,6 +8815,8 @@ function App({
|
|
|
8751
8815
|
provider,
|
|
8752
8816
|
family,
|
|
8753
8817
|
keyTail,
|
|
8818
|
+
tokenSavingMode,
|
|
8819
|
+
toolCount,
|
|
8754
8820
|
getPickableProviders,
|
|
8755
8821
|
switchProviderAndModel,
|
|
8756
8822
|
getSettings,
|
|
@@ -8768,6 +8834,7 @@ function App({
|
|
|
8768
8834
|
listSessions,
|
|
8769
8835
|
onResumeSession,
|
|
8770
8836
|
fleetStreamController,
|
|
8837
|
+
interruptController,
|
|
8771
8838
|
statuslineHiddenItems,
|
|
8772
8839
|
setStatuslineHiddenItems,
|
|
8773
8840
|
agentsMonitorController,
|
|
@@ -8788,14 +8855,32 @@ function App({
|
|
|
8788
8855
|
}) {
|
|
8789
8856
|
const { exit } = useApp();
|
|
8790
8857
|
const { stdout } = useStdout();
|
|
8791
|
-
const
|
|
8792
|
-
|
|
8793
|
-
|
|
8794
|
-
|
|
8795
|
-
|
|
8796
|
-
|
|
8797
|
-
|
|
8798
|
-
|
|
8858
|
+
const {
|
|
8859
|
+
liveModel,
|
|
8860
|
+
setLiveModel,
|
|
8861
|
+
liveProvider,
|
|
8862
|
+
setLiveProvider,
|
|
8863
|
+
activeMaxContext,
|
|
8864
|
+
setActiveMaxContext,
|
|
8865
|
+
yoloLive,
|
|
8866
|
+
setYoloLive,
|
|
8867
|
+
autonomyLive,
|
|
8868
|
+
setAutonomyLive,
|
|
8869
|
+
liveModeLabel,
|
|
8870
|
+
setLiveModeLabel,
|
|
8871
|
+
hiddenItems,
|
|
8872
|
+
setHiddenItems,
|
|
8873
|
+
sessionCount,
|
|
8874
|
+
setSessionCount
|
|
8875
|
+
} = useStatuslineState({
|
|
8876
|
+
model,
|
|
8877
|
+
provider,
|
|
8878
|
+
effectiveMaxContext,
|
|
8879
|
+
yolo,
|
|
8880
|
+
getAutonomy,
|
|
8881
|
+
modeLabel,
|
|
8882
|
+
statuslineHiddenItems
|
|
8883
|
+
});
|
|
8799
8884
|
const prevBranchRef = useRef(null);
|
|
8800
8885
|
const [indexState, setIndexState] = useState(() => getIndexState());
|
|
8801
8886
|
useEffect(() => {
|
|
@@ -8803,7 +8888,7 @@ function App({
|
|
|
8803
8888
|
return onIndexStateChange((next) => setIndexState(next));
|
|
8804
8889
|
}, []);
|
|
8805
8890
|
useEffect(() => {
|
|
8806
|
-
setHiddenItems(statuslineHiddenItems);
|
|
8891
|
+
setHiddenItems([...statuslineHiddenItems]);
|
|
8807
8892
|
}, [statuslineHiddenItems]);
|
|
8808
8893
|
useEffect(() => {
|
|
8809
8894
|
setStatuslineHiddenItems(hiddenItems);
|
|
@@ -8899,7 +8984,7 @@ function App({
|
|
|
8899
8984
|
},
|
|
8900
8985
|
autonomyPicker: { open: false, options: [], selected: 0 },
|
|
8901
8986
|
resumePicker: { open: false, sessions: [], selected: 0, busy: false, hint: void 0, error: void 0 },
|
|
8902
|
-
settingsPicker: { open: false, field: 0, mode: "off", delayMs: 0, titleAnimation: true, yolo: false, streamFleet: true, chime: false, confirmExit: true, nextPrediction: false, featureMcp: true, featurePlugins: true, featureMemory: true, featureSkills: true, featureModelsRegistry: true, contextAutoCompact: true, contextStrategy: "hybrid", logLevel: "info", auditLevel: "standard", indexOnStart: true, maxIterations: 500, autoProceedMaxIterations: 50, enhanceDelayMs: 6e4, enhanceEnabled: true, enhanceLanguage: "original", debugStream: false, configScope: "global" },
|
|
8987
|
+
settingsPicker: { open: false, field: 0, mode: "off", delayMs: 0, titleAnimation: true, yolo: false, streamFleet: true, chime: false, confirmExit: true, nextPrediction: false, featureMcp: true, featurePlugins: true, featureMemory: true, featureSkills: true, featureModelsRegistry: true, featureTokenSaving: false, contextAutoCompact: true, contextStrategy: "hybrid", logLevel: "info", auditLevel: "standard", indexOnStart: true, maxIterations: 500, autoProceedMaxIterations: 50, enhanceDelayMs: 6e4, enhanceEnabled: true, enhanceLanguage: "original", debugStream: false, configScope: "global" },
|
|
8903
8988
|
projectPicker: { open: false, allItems: [], items: [], selected: 0, filter: "", hint: void 0 },
|
|
8904
8989
|
confirmQueue: [],
|
|
8905
8990
|
enhance: null,
|
|
@@ -9531,6 +9616,7 @@ function App({
|
|
|
9531
9616
|
featureMemory: sp.featureMemory,
|
|
9532
9617
|
featureSkills: sp.featureSkills,
|
|
9533
9618
|
featureModelsRegistry: sp.featureModelsRegistry,
|
|
9619
|
+
featureTokenSaving: sp.featureTokenSaving,
|
|
9534
9620
|
contextAutoCompact: sp.contextAutoCompact,
|
|
9535
9621
|
contextStrategy: sp.contextStrategy,
|
|
9536
9622
|
logLevel: sp.logLevel,
|
|
@@ -9908,6 +9994,7 @@ function App({
|
|
|
9908
9994
|
featureMemory: s2.featureMemory ?? true,
|
|
9909
9995
|
featureSkills: s2.featureSkills ?? true,
|
|
9910
9996
|
featureModelsRegistry: s2.featureModelsRegistry ?? true,
|
|
9997
|
+
featureTokenSaving: s2.featureTokenSaving ?? false,
|
|
9911
9998
|
contextAutoCompact: s2.contextAutoCompact ?? true,
|
|
9912
9999
|
contextStrategy: s2.contextStrategy ?? "hybrid",
|
|
9913
10000
|
logLevel: s2.logLevel ?? "info",
|
|
@@ -10025,6 +10112,7 @@ function App({
|
|
|
10025
10112
|
featureMemory: sp.featureMemory,
|
|
10026
10113
|
featureSkills: sp.featureSkills,
|
|
10027
10114
|
featureModelsRegistry: sp.featureModelsRegistry,
|
|
10115
|
+
featureTokenSaving: sp.featureTokenSaving,
|
|
10028
10116
|
contextAutoCompact: sp.contextAutoCompact,
|
|
10029
10117
|
contextStrategy: sp.contextStrategy,
|
|
10030
10118
|
logLevel: sp.logLevel,
|
|
@@ -10234,6 +10322,15 @@ function App({
|
|
|
10234
10322
|
entry: { kind: "error", text: e.description }
|
|
10235
10323
|
});
|
|
10236
10324
|
});
|
|
10325
|
+
const offFallback = events.on("provider.fallback", (e) => {
|
|
10326
|
+
dispatch({
|
|
10327
|
+
type: "addEntry",
|
|
10328
|
+
entry: {
|
|
10329
|
+
kind: "warn",
|
|
10330
|
+
text: `\u21BB rate-limited (${e.status}) \u2014 switched to ${e.to.providerId}/${e.to.model}`
|
|
10331
|
+
}
|
|
10332
|
+
});
|
|
10333
|
+
});
|
|
10237
10334
|
const offProvResp = events.on("provider.response", () => {
|
|
10238
10335
|
const text = streamingTextRef.current;
|
|
10239
10336
|
streamingTextRef.current = "";
|
|
@@ -10307,6 +10404,7 @@ function App({
|
|
|
10307
10404
|
offTool();
|
|
10308
10405
|
offRetry();
|
|
10309
10406
|
offProvErr();
|
|
10407
|
+
offFallback();
|
|
10310
10408
|
offProvResp();
|
|
10311
10409
|
offConfirmNeeded();
|
|
10312
10410
|
offTrustPersisted();
|
|
@@ -10368,6 +10466,15 @@ function App({
|
|
|
10368
10466
|
enhanceController,
|
|
10369
10467
|
agentsMonitorController
|
|
10370
10468
|
});
|
|
10469
|
+
useEffect(() => {
|
|
10470
|
+
if (!interruptController) return;
|
|
10471
|
+
interruptController.abortLeader = () => {
|
|
10472
|
+
if (stateRef.current.status === "idle") return false;
|
|
10473
|
+
activeCtrlRef.current?.abort("user interrupt (/interrupt)");
|
|
10474
|
+
dispatch({ type: "status", status: "aborting" });
|
|
10475
|
+
return true;
|
|
10476
|
+
};
|
|
10477
|
+
}, [interruptController, dispatch, stateRef]);
|
|
10371
10478
|
const lastEscAtRef = useRef(0);
|
|
10372
10479
|
const ESC_DOUBLE_PRESS_MS = 1e3;
|
|
10373
10480
|
useDirectorFleetBridge({
|
|
@@ -11223,6 +11330,7 @@ function App({
|
|
|
11223
11330
|
featureMemory: cfg.featureMemory ?? true,
|
|
11224
11331
|
featureSkills: cfg.featureSkills ?? true,
|
|
11225
11332
|
featureModelsRegistry: cfg.featureModelsRegistry ?? true,
|
|
11333
|
+
featureTokenSaving: cfg.featureTokenSaving ?? false,
|
|
11226
11334
|
contextAutoCompact: cfg.contextAutoCompact ?? true,
|
|
11227
11335
|
contextStrategy: cfg.contextStrategy ?? "hybrid",
|
|
11228
11336
|
logLevel: cfg.logLevel ?? "info",
|
|
@@ -12142,6 +12250,7 @@ User message:
|
|
|
12142
12250
|
featureMemory: state.settingsPicker.featureMemory,
|
|
12143
12251
|
featureSkills: state.settingsPicker.featureSkills,
|
|
12144
12252
|
featureModelsRegistry: state.settingsPicker.featureModelsRegistry,
|
|
12253
|
+
featureTokenSaving: state.settingsPicker.featureTokenSaving,
|
|
12145
12254
|
contextAutoCompact: state.settingsPicker.contextAutoCompact,
|
|
12146
12255
|
contextStrategy: state.settingsPicker.contextStrategy,
|
|
12147
12256
|
logLevel: state.settingsPicker.logLevel,
|
|
@@ -12322,7 +12431,9 @@ User message:
|
|
|
12322
12431
|
nextStepsAutoSubmitCountdown,
|
|
12323
12432
|
autoProceedCountdown: state.countdown?.remainingSeconds ?? null,
|
|
12324
12433
|
sessionCount,
|
|
12325
|
-
mailbox: mailboxStatus
|
|
12434
|
+
mailbox: mailboxStatus,
|
|
12435
|
+
tokenSavingMode: getSettings ? getSettings().featureTokenSaving : tokenSavingMode,
|
|
12436
|
+
toolCount
|
|
12326
12437
|
}
|
|
12327
12438
|
) }),
|
|
12328
12439
|
/* @__PURE__ */ jsx(
|
|
@@ -12731,6 +12842,7 @@ async function runTui(opts) {
|
|
|
12731
12842
|
fleetRoster: opts.fleetRoster,
|
|
12732
12843
|
onClearHistory: opts.onClearHistory ? (dispatch) => opts.onClearHistory?.(dispatch) : void 0,
|
|
12733
12844
|
fleetStreamController: opts.fleetStreamController,
|
|
12845
|
+
interruptController: opts.interruptController,
|
|
12734
12846
|
enhanceController: opts.enhanceController,
|
|
12735
12847
|
enhanceEnabled: opts.enhanceController?.enabled ?? true,
|
|
12736
12848
|
statuslineHiddenItems: opts.statuslineHiddenItems,
|
|
@@ -12750,6 +12862,8 @@ async function runTui(opts) {
|
|
|
12750
12862
|
confirmExit: opts.confirmExit,
|
|
12751
12863
|
mouse: mouseEnabled,
|
|
12752
12864
|
modeLabel: opts.modeLabel,
|
|
12865
|
+
tokenSavingMode: opts.tokenSavingMode,
|
|
12866
|
+
toolCount: opts.toolCount,
|
|
12753
12867
|
getModeLabel: opts.getModeLabel,
|
|
12754
12868
|
registerDebugStreamCallback: opts.registerDebugStreamCallback,
|
|
12755
12869
|
restoreDebugStreamCallback: opts.restoreDebugStreamCallback,
|