dsh-ssh-tui 0.7.1 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +76 -7
- package/README.md +50 -7
- package/lib/approval-cache.js +12 -9
- package/lib/approval-cache.js.map +1 -1
- package/lib/color-depth.js +10 -4
- package/lib/color-depth.js.map +1 -1
- package/lib/diag.js +41 -17
- package/lib/diag.js.map +1 -1
- package/lib/dialogs.js.map +1 -1
- package/lib/display-sock.js +68 -10
- package/lib/display-sock.js.map +1 -1
- package/lib/footer.js +35 -7
- package/lib/footer.js.map +1 -1
- package/lib/gateway-protocol.js +202 -0
- package/lib/gateway-protocol.js.map +1 -0
- package/lib/i18n/en.js +61 -41
- package/lib/i18n/en.js.map +1 -1
- package/lib/i18n/zh.js +61 -41
- package/lib/i18n/zh.js.map +1 -1
- package/lib/index.js +99 -23
- package/lib/index.js.map +1 -1
- package/lib/job-label.js +99 -17
- package/lib/job-label.js.map +1 -1
- package/lib/plan.js +269 -17
- package/lib/plan.js.map +1 -1
- package/lib/platform.js +88 -0
- package/lib/platform.js.map +1 -0
- package/lib/provider-catalog.js +3 -0
- package/lib/provider-catalog.js.map +1 -1
- package/lib/route-memory.js +8 -1
- package/lib/route-memory.js.map +1 -1
- package/lib/session-list.js +18 -1
- package/lib/session-list.js.map +1 -1
- package/lib/session-lock.js +75 -23
- package/lib/session-lock.js.map +1 -1
- package/lib/session-route.js +331 -0
- package/lib/session-route.js.map +1 -0
- package/lib/subagent-model.js +79 -1
- package/lib/subagent-model.js.map +1 -1
- package/lib/term-text.js +7 -4
- package/lib/term-text.js.map +1 -1
- package/lib/tool-present.js +46 -14
- package/lib/tool-present.js.map +1 -1
- package/lib/tui.js +1789 -275
- package/lib/tui.js.map +1 -1
- package/lib/types/color-depth.d.ts +3 -3
- package/lib/types/dialogs.d.ts +4 -0
- package/lib/types/display-sock.d.ts +52 -1
- package/lib/types/footer.d.ts +18 -4
- package/lib/types/gateway-protocol.d.ts +88 -0
- package/lib/types/job-label.d.ts +38 -7
- package/lib/types/plan.d.ts +94 -4
- package/lib/types/platform.d.ts +50 -0
- package/lib/types/route-memory.d.ts +17 -22
- package/lib/types/session-list.d.ts +5 -0
- package/lib/types/session-lock.d.ts +9 -0
- package/lib/types/session-route.d.ts +191 -0
- package/lib/types/subagent-model.d.ts +53 -0
- package/lib/types/term-text.d.ts +3 -2
- package/lib/types/tool-present.d.ts +2 -17
- package/lib/types/transcript-types.d.ts +44 -1
- package/lib/types/tui.d.ts +292 -2
- package/package.json +1 -1
package/lib/types/tui.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ import type { Context } from '@deepseek-ai/cordis';
|
|
|
20
20
|
import { type LlmCallConfig } from '@deepseek-ai/dsh-llm';
|
|
21
21
|
import { SessionId, type SessionEvent } from '@deepseek-ai/dsh-session';
|
|
22
22
|
import type { SubagentRunEndInfo, SubagentRunInfo } from '@deepseek-ai/dsh-subagent';
|
|
23
|
+
import { type SessionRoute } from './session-route.js';
|
|
23
24
|
import { type SubagentSelectionRef } from './subagent-model.js';
|
|
24
25
|
import { type AskUserQuestionAnswer, type AskUserQuestionRequest } from '@deepseek-ai/dsh-user-questions';
|
|
25
26
|
import type { ApprovalOutcome, ApprovalRequest } from '@deepseek-ai/dsh-user-approval';
|
|
@@ -28,10 +29,10 @@ import { paintedLinkHits } from './term-text.js';
|
|
|
28
29
|
export type { CollapsibleBlock, DisplayKind, DisconnectPolicyName, PlanTodoItem, Row, SubagentLogEntry, ToolDiffHunk, } from './transcript-types.js';
|
|
29
30
|
export { clipAnsiToWidth, cursorVisualPosition, displayWidth, foldInputView, hrefAtColumn, osc52Clipboard, osc8Enabled, paintedLinkHits, fmtElapsedCompact, padAnsiToWidth, padToWidth, renderMarkdownLines, repeatToWidth, shimmerText, truncateToWidth, visibleWidth, waitCardCopy, waitSummaryFromReasoning, wrapWaitDetails, } from './term-text.js';
|
|
30
31
|
export { captureHangupSignals, composePaintOutput, detectSshSession, formatLinkQualityChip, ignoreFurtherHangupSignals, isEscapePrefix, findCursorPositionReply, isHangupErrno, linkQualityOf, linkSignalPips, paintIntervalForRtt, paintLinkLabel, parseCursorPositionReply, pickerWindowStart, probeTerminalRttMs, releaseHangupSignals, resolvePaintIntervalMs, waitUntilIdleOrTimeout, writeBootSplash, type LinkQuality, type PaintLinkKind, } from './paint.js';
|
|
31
|
-
export { CONTEXT_IDLE_COMPACT_RATIO, CONTEXT_PRESSURE_DANGER_RATIO, CONTEXT_PRESSURE_WARN_RATIO, CONTEXT_RING_EMPTY, CONTEXT_RING_SEGMENTS, contextPressureAlertText, contextPressureRingColor, contextPressureUsedTokens, contextPressureView, describeProviderRoute, dropFooterQuotaPlanName, fitFooterStatsLine, fitFooterStatusLine, footerActivity, footerIdentityParts, footerStatsGroups, formatContextPressureChip, formatContextPressureRing, formatContextPressureStatusLine, formatDuration, formatFooterQuota, formatQuotaBar, formatQuotaUnknown, formatStatusReport, providerHasQuotaSurface, quotaWindowTag, shortModelName, shortQuotaPlanName, formatTokens, formatTokensPerSecond, parseContextPressure, promptPressureTokens, providerShortCode, providerUsesLocalOAuth, shouldIdleAutoCompact, subagentRouteLabel, type ContextPressureSample, type ContextPressureView, type FooterActivityKind, type FooterStatsInput, type FooterStatusInput, type StatusReportInput, } from './footer.js';
|
|
32
|
+
export { CONTEXT_IDLE_COMPACT_RATIO, CONTEXT_PRESSURE_DANGER_RATIO, CONTEXT_PRESSURE_WARN_RATIO, CONTEXT_RING_EMPTY, CONTEXT_RING_SEGMENTS, contextPressureAlertText, contextPressureRingColor, contextPressureUsedTokens, contextPressureView, describeProviderRoute, dropFooterQuotaPlanName, fitFooterStatsLine, fitFooterStatusLine, footerActivity, footerIdentityParts, footerStatsGroups, footerSubagentForeign, paintFooterSubagentChip, formatContextPressureChip, formatContextPressureRing, formatContextPressureStatusLine, formatDuration, formatFooterQuota, formatQuotaBar, formatQuotaUnknown, formatStatusReport, providerHasQuotaSurface, quotaWindowTag, shortModelName, shortQuotaPlanName, formatTokens, formatTokensPerSecond, parseContextPressure, promptPressureTokens, providerShortCode, providerUsesLocalOAuth, shouldIdleAutoCompact, subagentRouteLabel, type ContextPressureSample, type ContextPressureView, type FooterActivityKind, type FooterStatsInput, type FooterStatusInput, type StatusReportInput, } from './footer.js';
|
|
32
33
|
export { commandCodePeriodStart, commandCodeSourceFor, crossedQuotaThresholds, formatAccountBalance, formatFooterBalance, formatOpenCodeGoUsage, formatQuotaSnapshot, formatQuotaStatusLine, joinUrl, openCodeSourceFor, parseCommandCodeQuota, parseDeepSeekBalance, parseOpenAiCompatibleBalance, parseOpenCodeGoQuota, parseSuperGrokBilling, preferredQuotaWindow, quotaAlertText, quotaRefreshEverySteps, quotaRefreshEveryTurns, remainingPercentFromUsed, tightestQuotaWindow, type AccountBalanceLine, type AccountBalanceSnapshot, type CommandCodeSource, type OpenCodeFlavor, type OpenCodeSource, type QuotaPeriod, type QuotaSnapshot, type QuotaWindow, } from './quota.js';
|
|
33
34
|
export { commandAcceptsAttachments, forEachSessionEvent, isAssistantStreamEvent, isTokenDeltaChunk, listPersistenceHeaders, inspectPersistenceSession, sessionEventType, sessionEvents, settingsNamespace, streamChunkOf, streamFirstTokenTime, streamFrameAttemptId, streamFrameOwner, } from './dsh-compat.js';
|
|
34
|
-
export { applyTurnEndToPlan, askSummary, cardCategoryOf, compactionHeaderText, formatCompactCommandError, isPromptInjectionMessage, matchTranscriptRows, parseFindQuery, parsePlanTodos, planCloseNudgeText, planDockNote, planIsLive, planTitleFromMarkdown, planTurnLeftOpen, promptInjectionSources, promptInjectionTitle,
|
|
35
|
+
export { applyTurnEndToPlan, askSummary, cardCategoryOf, compactionHeaderText, formatCompactCommandError, isPromptInjectionMessage, matchTranscriptRows, parseFindQuery, parsePlanTodos, planCloseNudgeText, planDockNote, planIsLive, planTitleFromMarkdown, planTurnLeftOpen, promptInjectionSources, promptInjectionTitle, buildSubagentHeader, clipSubagentActivity, describeSubagentFailure, subagentChipSummary, subagentDisplayName, subagentInspectLines, subagentRowFromSpawnTool, foldSubagentUserLog, todoProgressLabel, todoSummary, type CardCategory, } from './plan.js';
|
|
35
36
|
export { buildToolHeader, canMergeToolCall, compactEditPath, compactToolBursts, compactToolGroups, countDiffAddDel, countDiffLines, countOutputLines, diffMetaDiffs, diffStatToken, friendlyJsonLines, parseExitStatus, presentToolCall, READ_TOOL_NAMES, renderToolDiff, toolBodyFitsWorkspace, toolBodyLines, toolStateColor, toolStateLabel, wrappedToolBodyLineCount, } from './tool-present.js';
|
|
36
37
|
/** Presentation configuration for the terminal channel. */
|
|
37
38
|
export interface TuiConfig {
|
|
@@ -51,6 +52,24 @@ export interface TuiConfig {
|
|
|
51
52
|
resume?: boolean;
|
|
52
53
|
/** One-line notice after entering a resumed session's working directory. */
|
|
53
54
|
cwdNotice?: string;
|
|
55
|
+
/**
|
|
56
|
+
* The route this resumed session ran on, when it has a record. Applied before
|
|
57
|
+
* the TUI mounts; this is only for saying so on screen.
|
|
58
|
+
*/
|
|
59
|
+
restoredRoute?: SessionRoute;
|
|
60
|
+
/**
|
|
61
|
+
* What the launcher decided about the resumed route: a supplier that is gone,
|
|
62
|
+
* or one that cannot be routed to at all. Pushed on screen at boot.
|
|
63
|
+
*/
|
|
64
|
+
launchNotices?: readonly {
|
|
65
|
+
kind: 'system' | 'error';
|
|
66
|
+
text: string;
|
|
67
|
+
}[];
|
|
68
|
+
/**
|
|
69
|
+
* Report a settled route to the launcher, which owns the per-session record.
|
|
70
|
+
* Absent in tests and in line mode: nothing here touches the disk.
|
|
71
|
+
*/
|
|
72
|
+
onRouteSettled?: (route: Omit<SessionRoute, 'updatedAt'>) => void;
|
|
54
73
|
/** Provider route selected at launch (defaults to deepseek-official). */
|
|
55
74
|
provider?: string;
|
|
56
75
|
/** Model selected at launch (defaults to the saved/fallback model). */
|
|
@@ -153,6 +172,19 @@ export declare class SshTui {
|
|
|
153
172
|
private catalogLoad;
|
|
154
173
|
/** Memoized id→window index over {@link catalogPresets}. */
|
|
155
174
|
private catalogWindows;
|
|
175
|
+
/** Wizard drafts whose models step is already asking the gateway, so a
|
|
176
|
+
* second Enter cannot start a duplicate listing. */
|
|
177
|
+
private readonly finishingModels;
|
|
178
|
+
/** `<base>\0<model>` → the family row last seen serving that model. */
|
|
179
|
+
/**
|
|
180
|
+
* `<base>\0<model>` → the family row last seen serving that model.
|
|
181
|
+
*
|
|
182
|
+
* Bounded: a gateway can publish hundreds of models and their rows are
|
|
183
|
+
* re-learned on every listing, so the oldest entries are dropped once the map
|
|
184
|
+
* passes FAMILY_OWNER_CACHE_MAX rather than growing for the life of the
|
|
185
|
+
* session. Losing an entry only costs one future "which row?" lookup.
|
|
186
|
+
*/
|
|
187
|
+
private readonly familyModelOwner;
|
|
156
188
|
private input;
|
|
157
189
|
private cursor;
|
|
158
190
|
private inputFolded;
|
|
@@ -194,10 +226,13 @@ export declare class SshTui {
|
|
|
194
226
|
private readonly selectionRef;
|
|
195
227
|
private readonly subagentSelection;
|
|
196
228
|
private readonly onSelectionChanged;
|
|
229
|
+
private readonly onRouteSettled;
|
|
197
230
|
private readonly disposers;
|
|
198
231
|
private userQuestionDisposer;
|
|
199
232
|
private presetId;
|
|
200
233
|
private presetName;
|
|
234
|
+
/** Last route reported to the launcher; a repaint must not report it again. */
|
|
235
|
+
private lastSessionRoute;
|
|
201
236
|
private readonly useAlternateScreen;
|
|
202
237
|
private agentGone;
|
|
203
238
|
private onboarding;
|
|
@@ -213,6 +248,8 @@ export declare class SshTui {
|
|
|
213
248
|
private readonly seenCommandDoneIds;
|
|
214
249
|
private activeSubagents;
|
|
215
250
|
private subagentSessions;
|
|
251
|
+
/** Parent `subagent` tool descriptions waiting for the matching child card. */
|
|
252
|
+
private pendingSubagentTasks;
|
|
216
253
|
private openToolCalls;
|
|
217
254
|
/** Survives result settlement so a card-less result can still be labelled. */
|
|
218
255
|
private toolCallNames;
|
|
@@ -389,6 +426,20 @@ export declare class SshTui {
|
|
|
389
426
|
* footer sat on `SSH ○○○○` for the whole load.
|
|
390
427
|
*/
|
|
391
428
|
replayHistory(): Promise<void>;
|
|
429
|
+
/**
|
|
430
|
+
* Close the chips replay could not settle.
|
|
431
|
+
*
|
|
432
|
+
* A spawn `tool/call` with no `tool/result` in the log means the wrapper was
|
|
433
|
+
* still in flight when the log was last written. Replay only runs in a Host
|
|
434
|
+
* that has just started, and the child lived in the Host running back then,
|
|
435
|
+
* so that child is gone and no `subagent/end` will ever arrive for it.
|
|
436
|
+
* Leaving the chip "running" made every resume of an interrupted turn show a
|
|
437
|
+
* child counting up forever while `/status` reported none.
|
|
438
|
+
*
|
|
439
|
+
* `stopReason: 'unknown'` is also what lets a late live end adopt this row
|
|
440
|
+
* instead of adding a twin beside it.
|
|
441
|
+
*/
|
|
442
|
+
private settleUnfinishedReplayChips;
|
|
392
443
|
/** Show the first-launch provider/API-key onboarding when nothing is configured. */
|
|
393
444
|
private maybeRunOnboarding;
|
|
394
445
|
/** Run the provider/API-key onboarding wizard. Resolves true when saved. */
|
|
@@ -513,6 +564,9 @@ export declare class SshTui {
|
|
|
513
564
|
private endWait;
|
|
514
565
|
private waitCardSource;
|
|
515
566
|
private findSubagentRow;
|
|
567
|
+
private subagentInspectId;
|
|
568
|
+
/** Courtesy name for a child session; never the raw session hash. */
|
|
569
|
+
private subagentNameFor;
|
|
516
570
|
private findLivePlanRow;
|
|
517
571
|
/** Older / finished plans stay in the scrolling transcript. */
|
|
518
572
|
private archiveStalePlans;
|
|
@@ -531,16 +585,51 @@ export declare class SshTui {
|
|
|
531
585
|
* including a monochrome terminal.
|
|
532
586
|
*/
|
|
533
587
|
private styleEmphasisedLine;
|
|
588
|
+
/**
|
|
589
|
+
* A body row whose parts carry different roles: the two columns of a
|
|
590
|
+
* side-by-side diff.
|
|
591
|
+
*
|
|
592
|
+
* No single kind fits such a row — the left column is a removal, the right an
|
|
593
|
+
* addition — so each part is painted with its own style, the gutter keeps the
|
|
594
|
+
* row's own (neutral) one, and a word emphasis rides inside whichever column
|
|
595
|
+
* it belongs to. The first column takes the leading indent and the last one
|
|
596
|
+
* runs to the end of the row, so both bars are flush.
|
|
597
|
+
*/
|
|
598
|
+
private styleColumnedLine;
|
|
534
599
|
private paintToolBodyLine;
|
|
535
600
|
private workspaceRowsFor;
|
|
536
601
|
private paintInspectOverlay;
|
|
602
|
+
/**
|
|
603
|
+
* Reverse-video (or a `»` in monochrome) on the overlay row that holds the
|
|
604
|
+
* current `/find` needle, matching what the transcript does for the same hit.
|
|
605
|
+
*/
|
|
606
|
+
private markSearchRow;
|
|
537
607
|
private openToolInspect;
|
|
608
|
+
private openSubagentInspect;
|
|
609
|
+
/**
|
|
610
|
+
* Line mode has no framed scroller, so an inspect body goes into the log.
|
|
611
|
+
*
|
|
612
|
+
* Opening the modal there printed nothing and then swallowed the next Enter:
|
|
613
|
+
* an invisible dialog. The log is the only detail surface line mode has, and
|
|
614
|
+
* writing it keeps the input free.
|
|
615
|
+
*/
|
|
616
|
+
private echoInspectToLog;
|
|
538
617
|
closeInspect(): void;
|
|
539
618
|
private paintCollapsibleHeader;
|
|
540
619
|
/** Move the expand/collapse focus among reasoning and tool rows. */
|
|
541
620
|
private moveCollapsibleFocus;
|
|
542
621
|
/** Toggle the focused block; without focus, toggle the most recent one. */
|
|
543
622
|
toggleCollapsible(): void;
|
|
623
|
+
/**
|
|
624
|
+
* Whether an inline tool body would be cut short.
|
|
625
|
+
*
|
|
626
|
+
* Two things stop a body short: it cannot fit the workspace, or the measured
|
|
627
|
+
* link is slow enough that the paint budget trims it. Both leave the reader
|
|
628
|
+
* looking at part of a diff under a header that counts all of it, and both
|
|
629
|
+
* are what the overlay is for — so both answers are the overlay, and the
|
|
630
|
+
* card's own `Enter 全览` hint stays true.
|
|
631
|
+
*/
|
|
632
|
+
private toolBodyTruncated;
|
|
544
633
|
toggleCard(target: CollapsibleBlock): void;
|
|
545
634
|
/** Expand all collapsible blocks, or collapse them again when all are open. */
|
|
546
635
|
toggleAllCollapsible(): void;
|
|
@@ -636,6 +725,28 @@ export declare class SshTui {
|
|
|
636
725
|
private mutedSeparator;
|
|
637
726
|
private mutedSgr;
|
|
638
727
|
private styleLine;
|
|
728
|
+
/**
|
|
729
|
+
* One emphasised piece of a body line — the words a diff changed.
|
|
730
|
+
*
|
|
731
|
+
* Inside a filled diff row the mark is a lighter shade of that same fill.
|
|
732
|
+
* Inverse video was there first, and it inverted the *fill*: a line replaced
|
|
733
|
+
* wholesale is emphasised from end to end, so it came out a bright block
|
|
734
|
+
* beside rows that kept the muted tone — visibly from another palette. On a
|
|
735
|
+
* terminal with no colour left to shift, the attribute is what survives, so
|
|
736
|
+
* the inverse video stays for that case.
|
|
737
|
+
*/
|
|
738
|
+
private styleEmphasisedPiece;
|
|
739
|
+
/**
|
|
740
|
+
* Paint a row the reader has selected.
|
|
741
|
+
*
|
|
742
|
+
* The obvious `7`…`27` wrap only reaches the part before the line's first
|
|
743
|
+
* reset, and every painted segment ends with one: a focused card kept its
|
|
744
|
+
* marker and status dot highlighted while the title, the state word and the
|
|
745
|
+
* summary stayed plain, so ↑/↓ gave no visible clue which card was picked —
|
|
746
|
+
* on exactly the rows that carry a segmented header. Re-opening the attribute
|
|
747
|
+
* after every reset covers the whole row, whatever colours sit on top of it.
|
|
748
|
+
*/
|
|
749
|
+
private selectLine;
|
|
639
750
|
/**
|
|
640
751
|
* Fold one live or durable stream chunk into the in-progress assistant
|
|
641
752
|
* row. 0.1.2 hosts append `assistant/chunk`; 0.1.5 emits the same chunk
|
|
@@ -653,6 +764,12 @@ export declare class SshTui {
|
|
|
653
764
|
* The parent request is left untouched (its own `/model` waterfall already
|
|
654
765
|
* owns the route); direct children created by tool-subagent inherit the
|
|
655
766
|
* parent provider unless `/submodel` stored an explicit subagent provider.
|
|
767
|
+
*
|
|
768
|
+
* Effort is not inherited from the parent. `next()` copies the live parent
|
|
769
|
+
* config, so a grok-4.6 `xhigh` parent would otherwise send `xhigh` with
|
|
770
|
+
* the light grok-4.5 child and fail with UNSUPPORTED_REASONING_EFFORT
|
|
771
|
+
* before the child writes a closing message. An explicit `/subeffort`
|
|
772
|
+
* still wins; otherwise the child's own adapter default is used.
|
|
656
773
|
*/
|
|
657
774
|
readonly handleAgentRequest: ({ agent }: {
|
|
658
775
|
agent: Agent;
|
|
@@ -669,6 +786,28 @@ export declare class SshTui {
|
|
|
669
786
|
/** Plan-mode / command / team events that plugins merge into SessionEventMap. */
|
|
670
787
|
private handleExtensionEvent;
|
|
671
788
|
private findCompactionRow;
|
|
789
|
+
/**
|
|
790
|
+
* Compaction cards that can still be in flight: not finished, and within the
|
|
791
|
+
* window a real compaction could take. A stale card is treated as not running
|
|
792
|
+
* so it cannot hold the footer, the spinner, or `/compact` hostage.
|
|
793
|
+
*/
|
|
794
|
+
private runningCompactions;
|
|
795
|
+
/** Whether a compaction is genuinely in flight right now. */
|
|
796
|
+
private compactionRunning;
|
|
797
|
+
/**
|
|
798
|
+
* Close compaction cards whose Host is gone.
|
|
799
|
+
*
|
|
800
|
+
* `compaction/start` is written before the work and `compaction/end` after it,
|
|
801
|
+
* so a Host that exits in between leaves an open start in the durable log.
|
|
802
|
+
* Replaying that log faithfully used to recreate a card stuck on "running"
|
|
803
|
+
* forever: the footer said 压缩中, the spinner kept animating, and every later
|
|
804
|
+
* `/compact` was refused as "already compacting". After a full replay nothing
|
|
805
|
+
* more can arrive for those starts, so they are settled here.
|
|
806
|
+
*
|
|
807
|
+
* `staleOnly` keeps the same sweep usable while the session is live, where a
|
|
808
|
+
* compaction that is merely slow must not be closed under it.
|
|
809
|
+
*/
|
|
810
|
+
private settleUnfinishedCompactions;
|
|
672
811
|
private handleCompactionEvent;
|
|
673
812
|
private readContextPressure;
|
|
674
813
|
private refreshContextPressure;
|
|
@@ -685,6 +824,8 @@ export declare class SshTui {
|
|
|
685
824
|
readonly handleSubagentSessionEvent: (sessionId: SessionId, event: SessionEvent) => void;
|
|
686
825
|
readonly handleSubagentStart: (info: SubagentRunInfo) => void;
|
|
687
826
|
readonly handleSubagentEnd: (info: SubagentRunEndInfo) => void;
|
|
827
|
+
/** Keep an open inspect overlay in sync with the live child log. */
|
|
828
|
+
private refreshOpenSubagentInspect;
|
|
688
829
|
private hasLiveDisplay;
|
|
689
830
|
private waitForLiveDisplay;
|
|
690
831
|
/**
|
|
@@ -726,6 +867,12 @@ export declare class SshTui {
|
|
|
726
867
|
/** Queue one dialog behind an already-open one instead of overwriting it. */
|
|
727
868
|
private openDialog;
|
|
728
869
|
private showNextDialog;
|
|
870
|
+
/**
|
|
871
|
+
* Line mode has no framed dialog. Write the prompt (and its keys) into the
|
|
872
|
+
* log once when it becomes active, so a `tee` or a screen reader can answer
|
|
873
|
+
* it. Options stay on the framed path; the log only needs the question.
|
|
874
|
+
*/
|
|
875
|
+
private echoLineModeDialog;
|
|
729
876
|
private removeQueuedDialog;
|
|
730
877
|
private settleQuestion;
|
|
731
878
|
private openConfirm;
|
|
@@ -737,6 +884,58 @@ export declare class SshTui {
|
|
|
737
884
|
private askQuestion;
|
|
738
885
|
/** The stored llm-pi-ai profile for one provider route, when settings provide one. */
|
|
739
886
|
private piAiProviderProfile;
|
|
887
|
+
/**
|
|
888
|
+
* Every settings-backed row one gateway family occupies, base first.
|
|
889
|
+
*
|
|
890
|
+
* `llm-pi-ai` puts the wire protocol on the provider entry, so a gateway
|
|
891
|
+
* whose catalogue spans protocols (Command Code, OpenCode Go) is stored as
|
|
892
|
+
* sibling rows. To the user they are one supplier: the TUI lists, picks and
|
|
893
|
+
* remembers them under the family's base id, and files each picked model on
|
|
894
|
+
* the row that actually serves it.
|
|
895
|
+
*
|
|
896
|
+
* The `-responses` / `-completions` / `-messages` suffix is only a naming
|
|
897
|
+
* convention, so a row is adopted into the family only when it corroborates:
|
|
898
|
+
* it must speak the protocol its suffix names, point at the same endpoint,
|
|
899
|
+
* and (when both name one) carry the same display name. A provider someone
|
|
900
|
+
* legitimately called `foo-messages` on another host therefore stays its own
|
|
901
|
+
* supplier instead of vanishing from `/provider` behind `foo`. A family of
|
|
902
|
+
* one — the ordinary case, and a sibling whose base row is missing — stays
|
|
903
|
+
* exactly as configured.
|
|
904
|
+
*/
|
|
905
|
+
private providerFamilyRows;
|
|
906
|
+
/**
|
|
907
|
+
* Whether `sibling` is genuinely the same gateway as `base`, on another
|
|
908
|
+
* protocol: its `api` matches its suffix, its endpoint matches the base row's,
|
|
909
|
+
* and the two labels agree when both are set.
|
|
910
|
+
*/
|
|
911
|
+
private isFamilyRow;
|
|
912
|
+
/** The id the TUI shows for a route: its family's base when it is spread. */
|
|
913
|
+
private displayProviderId;
|
|
914
|
+
/** The models one row configures, as ids with the labels settings carry. */
|
|
915
|
+
private configuredModelsOf;
|
|
916
|
+
/**
|
|
917
|
+
* The protocols the gateway publishes for one model, best-effort.
|
|
918
|
+
*
|
|
919
|
+
* Used when a model is being filed but no picker listed it yet (`/model <id>`
|
|
920
|
+
* on a new id, a `--model` override, a `/submodel` pin): the gateway's own
|
|
921
|
+
* answer is the only thing that can put it on a route that can send it.
|
|
922
|
+
* Any failure is "no opinion", never a blocked selection.
|
|
923
|
+
*/
|
|
924
|
+
private advertisedFor;
|
|
925
|
+
/**
|
|
926
|
+
* The row of a gateway family that serves `model`: the one learned from the
|
|
927
|
+
* last listing, else the one that already configures it, else the base —
|
|
928
|
+
* where a brand-new model lands and is re-filed from.
|
|
929
|
+
*/
|
|
930
|
+
/**
|
|
931
|
+
* Record which row a family's model belongs to, keeping the map bounded.
|
|
932
|
+
*
|
|
933
|
+
* Re-inserting keeps a key fresh, and the oldest half is dropped once the cap
|
|
934
|
+
* is crossed, so a gateway whose catalogue is re-listed on every `/model`
|
|
935
|
+
* does not accumulate a second copy of itself each time.
|
|
936
|
+
*/
|
|
937
|
+
private rememberFamilyOwner;
|
|
938
|
+
private familyOwnerRow;
|
|
740
939
|
/** Default listing endpoint for a built-in OpenCode route with no stored base URL. */
|
|
741
940
|
private openCodeListingBaseURL;
|
|
742
941
|
/**
|
|
@@ -744,8 +943,28 @@ export declare class SshTui {
|
|
|
744
943
|
* OpenAI-compatible listing endpoint. The provider route is deliberately not
|
|
745
944
|
* passed to discovery: pi-ai would answer a catalog route from its installed
|
|
746
945
|
* registry, while the TUI wants the endpoint's current list.
|
|
946
|
+
*
|
|
947
|
+
* A row speaks exactly one protocol (`api` on the provider entry), so with a
|
|
948
|
+
* gateway that publishes `supported_endpoints` the list is narrowed to the
|
|
949
|
+
* models that row can actually serve — otherwise `/model` on
|
|
950
|
+
* `command-code-messages` would offer, and then persist, a model that only
|
|
951
|
+
* answers `/responses`.
|
|
747
952
|
*/
|
|
748
953
|
private discoverEndpointModels;
|
|
954
|
+
/**
|
|
955
|
+
* One gateway's own model listing: every model the endpoint returns plus the
|
|
956
|
+
* route table it publishes. The caller narrows it to a protocol; a gateway
|
|
957
|
+
* spread over rows asks once and files the answer per row, so opening a
|
|
958
|
+
* picker costs one listing instead of one per sibling.
|
|
959
|
+
*/
|
|
960
|
+
private discoverGatewayListing;
|
|
961
|
+
/**
|
|
962
|
+
* The row of the same gateway that the gateway itself says serves `model`,
|
|
963
|
+
* when that is not the row the caller is on. `undefined` when the gateway has
|
|
964
|
+
* no opinion, when the current row already serves it, or when the model would
|
|
965
|
+
* need a row that does not exist yet.
|
|
966
|
+
*/
|
|
967
|
+
private rowServingModel;
|
|
749
968
|
/** Add one endpoint-listed model to the stored provider profile when needed. */
|
|
750
969
|
private ensureProviderModelConfigured;
|
|
751
970
|
/**
|
|
@@ -758,12 +977,34 @@ export declare class SshTui {
|
|
|
758
977
|
/** Built-in SuperGrok catalog used when the live adapter list is still warming up. */
|
|
759
978
|
private static readonly XAI_FALLBACK_MODELS;
|
|
760
979
|
private loadModelOptions;
|
|
980
|
+
/**
|
|
981
|
+
* The model list of a gateway spread over protocol rows.
|
|
982
|
+
*
|
|
983
|
+
* Every row is asked what it serves and the answers are merged under the
|
|
984
|
+
* family's base id, so the user picks from one list. Each model remembers the
|
|
985
|
+
* row that offered it, which is what routes the pick back to the protocol
|
|
986
|
+
* that can actually send it — the split stays invisible end to end.
|
|
987
|
+
*/
|
|
988
|
+
private loadFamilyModelOptions;
|
|
761
989
|
/** /model: models and effort for the current provider only. */
|
|
762
990
|
private runModelCommand;
|
|
763
991
|
/** /provider: pick a provider, then its model (remembered route pre-filled). */
|
|
764
992
|
private runProviderCommand;
|
|
765
993
|
/** Persist a provider/model/effort choice and keep the subagent on the same family. */
|
|
766
994
|
private rememberedRoute;
|
|
995
|
+
/** The route this session is running right now, record-shaped. */
|
|
996
|
+
private sessionRouteRecord;
|
|
997
|
+
/**
|
|
998
|
+
* Tell the launcher which route this session has settled on, so resuming it
|
|
999
|
+
* comes back on the same supplier — the subagent route included, which is what
|
|
1000
|
+
* makes a resumed cross-provider conversation reproducible.
|
|
1001
|
+
*
|
|
1002
|
+
* Reported when a route settles (`/model`, `/submodel`, `/setup`) and at the
|
|
1003
|
+
* start of every turn, which catches a preset or a settings edit moving the
|
|
1004
|
+
* route behind the TUI's back. The launcher owns the file; the TUI only says
|
|
1005
|
+
* what changed, and says nothing when nothing did.
|
|
1006
|
+
*/
|
|
1007
|
+
private noteSessionRoute;
|
|
767
1008
|
private rememberRoute;
|
|
768
1009
|
private applyModelSelection;
|
|
769
1010
|
/**
|
|
@@ -780,8 +1021,21 @@ export declare class SshTui {
|
|
|
780
1021
|
* When the parent provider changes (OAuth or API key), keep the subagent
|
|
781
1022
|
* on a same-family model. An explicit leftover DeepSeek flash id after
|
|
782
1023
|
* switching to xAI is treated as stale.
|
|
1024
|
+
*
|
|
1025
|
+
* A `/submodel` pin is the user's explicit route, so a parent switch asks
|
|
1026
|
+
* before moving the children: dropping the pin silently spends on a route
|
|
1027
|
+
* they pinned away from, and keeping it silently leaves the children on the
|
|
1028
|
+
* old provider.
|
|
783
1029
|
*/
|
|
784
1030
|
private syncSubagentToProvider;
|
|
1031
|
+
/**
|
|
1032
|
+
* Ask whether a `/submodel` pin survives a parent provider change.
|
|
1033
|
+
*
|
|
1034
|
+
* Returns true when the pin should be kept. Cancelling the dialog keeps it
|
|
1035
|
+
* too: the pin is the user's explicit choice, so only an explicit answer
|
|
1036
|
+
* moves the children onto the new parent route.
|
|
1037
|
+
*/
|
|
1038
|
+
private confirmKeepSubagentPin;
|
|
785
1039
|
private clearQuotaForProvider;
|
|
786
1040
|
/** Persist one subagent selection and publish it to the live request waterfall. */
|
|
787
1041
|
private saveSubagentSelection;
|
|
@@ -789,6 +1043,8 @@ export declare class SshTui {
|
|
|
789
1043
|
private subagentModelOptions;
|
|
790
1044
|
/** /submodel: pick (or set) the model subagent children use. */
|
|
791
1045
|
private runSubmodelCommand;
|
|
1046
|
+
/** Persist one subagent provider/model pair and say whether it follows or is pinned. */
|
|
1047
|
+
private commitSubagentRoute;
|
|
792
1048
|
/** /effort: pick or set the reasoning effort for the current model. */
|
|
793
1049
|
private runEffortCommand;
|
|
794
1050
|
/**
|
|
@@ -894,8 +1150,42 @@ export declare class SshTui {
|
|
|
894
1150
|
* @returns the windows discovered for this pick, by model id.
|
|
895
1151
|
*/
|
|
896
1152
|
private sizeOnboardingModels;
|
|
1153
|
+
/**
|
|
1154
|
+
* Leave the models step, after one best-effort trip to the gateway for what
|
|
1155
|
+
* the picks are still missing: the context window / output cap of every model
|
|
1156
|
+
* the listing has not described yet, and — for a gateway that spreads over
|
|
1157
|
+
* several protocols — the endpoints each picked model answers.
|
|
1158
|
+
*
|
|
1159
|
+
* `Ctrl+F` stays as it was, but it is no longer the only way to learn these:
|
|
1160
|
+
* a model typed by hand would otherwise be saved with no capacity at all, and
|
|
1161
|
+
* with no endpoint data the split had nothing to file it by.
|
|
1162
|
+
*/
|
|
1163
|
+
private finishModelsStep;
|
|
1164
|
+
/** Whether leaving the models step has anything left to ask the gateway for. */
|
|
1165
|
+
private onboardingWantsEndpoint;
|
|
1166
|
+
/** Fill the picks' capacities and endpoints from the gateway; never fatal. */
|
|
1167
|
+
private enrichOnboardingModels;
|
|
897
1168
|
private handleOnboardingChar;
|
|
898
1169
|
private advanceOnboarding;
|
|
1170
|
+
/**
|
|
1171
|
+
* Open the models picker: every model the listing offered — or the template's
|
|
1172
|
+
* pinned ones when nothing was listed — with the template's models checked.
|
|
1173
|
+
*
|
|
1174
|
+
* Enter used to accept the whole listing, which quietly wrote every model of
|
|
1175
|
+
* the gateway into settings and made the session's model whichever id came
|
|
1176
|
+
* first. The picker makes both the set and the session's model explicit; a
|
|
1177
|
+
* typed list still skips it.
|
|
1178
|
+
*/
|
|
1179
|
+
private openOnboardingModelPicker;
|
|
1180
|
+
/** The checked models of the wizard's picker, in listing order. */
|
|
1181
|
+
private checkedOnboardingModels;
|
|
1182
|
+
/** Move the highlight in either picker step. */
|
|
1183
|
+
private moveOnboardingModelCursor;
|
|
1184
|
+
/**
|
|
1185
|
+
* Esc in a picker step goes back one step instead of throwing the wizard
|
|
1186
|
+
* away — the listing is the expensive part and the user is still choosing.
|
|
1187
|
+
*/
|
|
1188
|
+
private stepBackOnboarding;
|
|
899
1189
|
/** Fetch the endpoint's model list into the onboarding wizard's models step. */
|
|
900
1190
|
private fetchOnboardingModels;
|
|
901
1191
|
private saveOnboarding;
|