@itookit/dsht 0.3.8 → 0.5.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/README.i18n.yaml +2 -2
- package/README.md +30 -11
- package/README.zh.md +30 -11
- package/dist/cli/dsht.js +203 -18
- package/dist/cli/startup.d.ts +40 -0
- package/dist/cli/startup.js +295 -0
- package/dist/cli/trace-summary.d.ts +78 -0
- package/dist/cli/trace-summary.js +241 -0
- package/dist/cli/verifier.d.ts +60 -0
- package/dist/cli/verifier.js +242 -0
- package/dist/contracts.d.ts +344 -0
- package/dist/contracts.js +1 -0
- package/dist/controller/commands.d.ts +47 -0
- package/dist/controller/commands.js +322 -0
- package/dist/controller/connection.d.ts +11 -29
- package/dist/controller/connection.js +26 -60
- package/dist/controller/controller.d.ts +616 -166
- package/dist/controller/controller.js +1395 -146
- package/dist/controller/index.d.ts +8 -1
- package/dist/controller/index.js +5 -0
- package/dist/controller/loop-contract.d.ts +136 -0
- package/dist/controller/loop-contract.js +308 -0
- package/dist/controller/loop-prompts-schema.d.ts +56 -0
- package/dist/controller/loop-prompts-schema.js +144 -0
- package/dist/controller/loop-prompts.d.ts +55 -0
- package/dist/controller/loop-prompts.generated.d.ts +104 -0
- package/dist/controller/loop-prompts.generated.js +185 -0
- package/dist/controller/loop-prompts.js +104 -0
- package/dist/controller/loop-protocols.d.ts +39 -0
- package/dist/controller/loop-protocols.js +115 -0
- package/dist/controller/loop.d.ts +275 -0
- package/dist/controller/loop.js +378 -0
- package/dist/controller/prompts.d.ts +54 -0
- package/dist/controller/prompts.js +162 -0
- package/dist/controller/trace-log.d.ts +45 -0
- package/dist/controller/trace-log.js +144 -0
- package/dist/controller/verifier.d.ts +126 -0
- package/dist/controller/verifier.js +75 -0
- package/dist/cost/index.d.ts +1 -1
- package/dist/cost/index.js +1 -1
- package/dist/cost/ledger.d.ts +0 -1
- package/dist/cost/ledger.js +0 -1
- package/dist/json.d.ts +18 -0
- package/dist/json.js +19 -0
- package/dist/references.d.ts +25 -0
- package/dist/references.js +26 -0
- package/dist/session/connection-view.d.ts +2 -11
- package/dist/session/controller.d.ts +73 -72
- package/dist/session/controller.js +185 -209
- package/dist/session/history.d.ts +6 -18
- package/dist/session/history.js +1 -24
- package/dist/session/index.d.ts +9 -4
- package/dist/session/index.js +7 -3
- package/dist/session/info.d.ts +25 -52
- package/dist/session/info.js +39 -25
- package/dist/session/markdown.js +1 -1
- package/dist/session/math.js +1 -1
- package/dist/session/mutation-gate.d.ts +51 -0
- package/dist/session/mutation-gate.js +73 -0
- package/dist/session/navigation.d.ts +2 -89
- package/dist/session/navigation.js +2 -129
- package/dist/session/peek.d.ts +38 -0
- package/dist/session/peek.js +103 -0
- package/dist/session/references.d.ts +2 -20
- package/dist/session/references.js +1 -26
- package/dist/session/runtime.d.ts +26 -0
- package/dist/session/runtime.js +28 -0
- package/dist/session/telemetry.d.ts +12 -13
- package/dist/session/telemetry.js +27 -58
- package/dist/session/transcript.d.ts +0 -6
- package/dist/session/transcript.js +2 -15
- package/dist/session/types.d.ts +25 -0
- package/dist/session/types.js +0 -1
- package/dist/session-title.d.ts +9 -0
- package/dist/session-title.js +21 -0
- package/dist/shell/controller.d.ts +31 -1
- package/dist/shell/controller.js +34 -2
- package/dist/shell/index.d.ts +3 -3
- package/dist/shell/index.js +2 -2
- package/dist/shell/runner.d.ts +10 -0
- package/dist/shell/runner.js +48 -9
- package/dist/slash/index.d.ts +10 -0
- package/dist/slash/index.js +7 -0
- package/dist/slash/parse.d.ts +166 -0
- package/dist/slash/parse.js +259 -0
- package/dist/slash/pipeline.d.ts +140 -0
- package/dist/slash/pipeline.js +115 -0
- package/dist/slash/registry.d.ts +88 -0
- package/dist/slash/registry.js +177 -0
- package/dist/state.d.ts +14 -4
- package/dist/state.js +3 -2
- package/dist/text.d.ts +28 -0
- package/dist/text.js +55 -0
- package/dist/transport/events.d.ts +104 -0
- package/dist/transport/events.js +149 -0
- package/dist/transport/wire.d.ts +9 -17
- package/dist/transport/wire.js +2 -27
- package/dist/ui/app.js +856 -441
- package/dist/ui/chat/header.js +1 -1
- package/dist/ui/chat/history-view.d.ts +1 -1
- package/dist/ui/chat/loop-status.d.ts +11 -0
- package/dist/ui/chat/loop-status.js +28 -0
- package/dist/ui/chat/navigation-model.d.ts +86 -0
- package/dist/ui/chat/navigation-model.js +107 -0
- package/dist/ui/chat/shell-view.d.ts +15 -2
- package/dist/ui/chat/shell-view.js +37 -3
- package/dist/ui/chat/status.d.ts +47 -3
- package/dist/ui/chat/status.js +65 -50
- package/dist/ui/chat/viewport.d.ts +1 -1
- package/dist/ui/dialogs/cost.d.ts +21 -4
- package/dist/ui/dialogs/cost.js +7 -12
- package/dist/ui/dialogs/index.d.ts +22 -5
- package/dist/ui/dialogs/index.js +19 -3
- package/dist/ui/dialogs/loop.d.ts +43 -0
- package/dist/ui/dialogs/loop.js +224 -0
- package/dist/ui/dialogs/peek.d.ts +25 -0
- package/dist/ui/dialogs/peek.js +35 -0
- package/dist/ui/dialogs/picker.d.ts +2 -0
- package/dist/ui/dialogs/picker.js +4 -2
- package/dist/ui/input/mouse.d.ts +12 -2
- package/dist/ui/input/mouse.js +20 -7
- package/dist/ui/input/references.d.ts +1 -1
- package/dist/ui/status/model.d.ts +7 -0
- package/dist/ui/status/model.js +5 -0
- package/dist/ui/theme/index.d.ts +1 -1
- package/package.json +6 -4
- package/dist/ui/commands/parse.d.ts +0 -104
- package/dist/ui/commands/parse.js +0 -135
- package/dist/ui/commands/registry.d.ts +0 -33
- package/dist/ui/commands/registry.js +0 -73
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
/** Application facade: composes the connection, session, catalog and cost domains. */
|
|
2
1
|
import { Client } from '../transport/client.ts';
|
|
3
|
-
import { type
|
|
2
|
+
import { type ObjectValue } from '../transport/wire.ts';
|
|
3
|
+
import type { HostEvent } from '../transport/events.ts';
|
|
4
4
|
import { type HistoryLimits } from '../session/memory.ts';
|
|
5
|
+
import { type SessionRender } from '../session/history.ts';
|
|
5
6
|
import { SessionController } from '../session/controller.ts';
|
|
6
7
|
import { CatalogController } from '../catalog/controller.ts';
|
|
7
8
|
import type { Telemetry } from '../session/telemetry.ts';
|
|
@@ -10,24 +11,201 @@ import type { CostLedger } from '../cost/ledger.ts';
|
|
|
10
11
|
import { CostController } from '../cost/controller.ts';
|
|
11
12
|
import { ConnectionController, type ConnectionListener } from './connection.ts';
|
|
12
13
|
import { MemoryLog } from './memory-log.ts';
|
|
14
|
+
import { TraceLog } from './trace-log.ts';
|
|
15
|
+
import { PromptStore } from './prompts.ts';
|
|
16
|
+
import { type LoopLimits, type LoopProtocol } from './loop.ts';
|
|
17
|
+
import { type VerifierPort } from './verifier.ts';
|
|
18
|
+
import type { ClientActivity, ForegroundKind, ForegroundSnapshot, LoopProgress, LoopRecord, OutputSource, PeekSnapshot } from '../contracts.ts';
|
|
19
|
+
import { SessionPeek } from '../session/peek.ts';
|
|
13
20
|
import { type ControllerStore, type State } from '../state.ts';
|
|
14
21
|
import { ShellController } from '../shell/index.ts';
|
|
15
|
-
import type { HistorySearch, RemovalTarget } from '../session/types.ts';
|
|
16
|
-
import type {
|
|
22
|
+
import type { HistorySearch, AnswerValue, RemovalTarget } from '../session/types.ts';
|
|
23
|
+
import type { SavedPrompt } from '../contracts.ts';
|
|
24
|
+
import type { FileReference } from '../session/references.ts';
|
|
25
|
+
import type { InteractionState, OptionState } from '../session/info.ts';
|
|
17
26
|
import type { Reasoning } from '../session/history.ts';
|
|
27
|
+
/** Mutating operations the UI drives; each runs in the client's single foreground slot. */
|
|
28
|
+
export interface Actions {
|
|
29
|
+
/** Claim the single foreground slot for work the front end orchestrates itself (paging, loading).
|
|
30
|
+
*
|
|
31
|
+
* The controller owns the slot, the abort controller and the identity; the front end only supplies
|
|
32
|
+
* the work and renders `queries.foreground`. Returns undefined when the client is busy with another
|
|
33
|
+
* operation or when this one was cancelled.
|
|
34
|
+
*/
|
|
35
|
+
foreground<T>(kind: ForegroundKind, label: string, work: (signal: AbortSignal) => Promise<T>, wait?: boolean): Promise<T | undefined>;
|
|
36
|
+
/** Cancel the operation that owns the slot; false when none is running. */
|
|
37
|
+
cancelForeground(): boolean;
|
|
38
|
+
/** Open one output source read-only, at full screen; unknown ids are ignored. */
|
|
39
|
+
openPeek(id: string): void;
|
|
40
|
+
/** Close the read-only view and release whatever it was following. */
|
|
41
|
+
closePeek(): void;
|
|
42
|
+
switchWorkspace(workspaceId?: string): Promise<boolean>;
|
|
43
|
+
switchSession(query?: string): Promise<boolean>;
|
|
44
|
+
selectSession(sessionId: string): Promise<boolean>;
|
|
45
|
+
createWorkspace(path: string): Promise<boolean>;
|
|
46
|
+
createSession(): Promise<boolean>;
|
|
47
|
+
/** Create a named session without selecting it; used by a forked verifier. */
|
|
48
|
+
createVerifierSession(title: string): Promise<string | undefined>;
|
|
49
|
+
/** Stop a verifier session's turn on the host without selecting it. */
|
|
50
|
+
cancelVerifierSession(sessionId: string): Promise<boolean>;
|
|
51
|
+
showPicker(screen: 'workspaces' | 'sessions'): Promise<boolean>;
|
|
52
|
+
removeTarget(target: RemovalTarget): Promise<boolean>;
|
|
53
|
+
removalTarget(kind: 'workspace' | 'session', query: string): Promise<RemovalTarget | undefined>;
|
|
54
|
+
waitForHistory(signal: AbortSignal): Promise<boolean>;
|
|
55
|
+
searchSessions(query: string, workspaceOnly: boolean, signal: AbortSignal): Promise<{
|
|
56
|
+
items: ObjectValue[];
|
|
57
|
+
hasMore: boolean;
|
|
58
|
+
} | undefined>;
|
|
59
|
+
searchHistory(query: string, signal: AbortSignal): Promise<HistorySearch | undefined>;
|
|
60
|
+
prompt(text: string): Promise<boolean>;
|
|
61
|
+
/** Clear this client's HANDOFF.md, then ask the agent to write a fresh handoff there. */
|
|
62
|
+
handoff(): Promise<boolean>;
|
|
63
|
+
/** Start any client-driven scored loop and send its first step. */
|
|
64
|
+
startLoop(protocol: LoopProtocol, limits: LoopLimits): Promise<boolean>;
|
|
65
|
+
/** Stop a running loop; the terminal progress stays visible for the reader. */
|
|
66
|
+
stopLoop(): void;
|
|
67
|
+
/** Drop a finished run's progress line; a run that is still active is left alone. */
|
|
68
|
+
clearLoopResult(): void;
|
|
69
|
+
/** Answer a paused run: re-judge the current artifact with what the operator supplied. */
|
|
70
|
+
answerLoop(text: string): Promise<boolean>;
|
|
71
|
+
cancelTurn(): Promise<boolean>;
|
|
72
|
+
answer(value: AnswerValue): Promise<boolean>;
|
|
73
|
+
/** Answer the current sub-question of the pending set, advancing the waterfall or sending it. */
|
|
74
|
+
answerQuestion(input?: {
|
|
75
|
+
selected?: readonly string[];
|
|
76
|
+
custom?: string;
|
|
77
|
+
}): Promise<boolean>;
|
|
78
|
+
approve(allowed: boolean): Promise<boolean>;
|
|
79
|
+
dismissQuestion(): Promise<boolean>;
|
|
80
|
+
/** Repeated keys share one cancellation; it reports exit eligibility itself. */
|
|
81
|
+
interrupt(force?: boolean): Promise<boolean>;
|
|
82
|
+
older(signal?: AbortSignal, transcript?: Transcript): Promise<boolean>;
|
|
83
|
+
historyThrough(target: number | 'first', signal: AbortSignal): Promise<boolean>;
|
|
84
|
+
removeQueued(itemId: string): Promise<boolean>;
|
|
85
|
+
/** Local shortcut prompts: no connection and no busy envelope, since they never reach the host. */
|
|
86
|
+
savePrompt(text: string): Promise<boolean>;
|
|
87
|
+
updatePrompt(id: string, text: string): Promise<boolean>;
|
|
88
|
+
deletePrompt(id: string): Promise<boolean>;
|
|
89
|
+
command(line: string, signal: AbortSignal): Promise<string | undefined>;
|
|
90
|
+
exportLog(path: string | undefined, signal: AbortSignal): Promise<string | undefined>;
|
|
91
|
+
exportHtml(path: string | undefined, signal: AbortSignal): Promise<string | undefined>;
|
|
92
|
+
selectModel(provider: string, model: string, reasoningEffort?: string): Promise<boolean>;
|
|
93
|
+
modelCatalog(): Promise<ObjectValue | undefined>;
|
|
94
|
+
refreshCosts(signal?: AbortSignal): Promise<boolean>;
|
|
95
|
+
/** Local, immediate setters: no request, so they keep the synchronous contract. */
|
|
96
|
+
loadPresetNames(): void;
|
|
97
|
+
/** Drop the internal last failure, once the fact has been reported elsewhere. */
|
|
98
|
+
clearFailure(): void;
|
|
99
|
+
enterPath(): void;
|
|
100
|
+
pickWorkspace(workspaceId?: string): void;
|
|
101
|
+
/** Leave a picker and return to the selected conversation; false when none is selected. */
|
|
102
|
+
showChat(): boolean;
|
|
103
|
+
setViewWindow(window?: Transcript): void;
|
|
104
|
+
pinHistory(pinned: boolean): void;
|
|
105
|
+
setAnswers(answers: Record<string, AnswerValue['answers']>): void;
|
|
106
|
+
setOption(option?: OptionState): void;
|
|
107
|
+
setApproval(approval?: InteractionState['approval']): void;
|
|
108
|
+
recordRecall(value: string): void;
|
|
109
|
+
resetRecall(): void;
|
|
110
|
+
refillRecall(): boolean;
|
|
111
|
+
heapSnapshot(tag?: string): string;
|
|
112
|
+
}
|
|
113
|
+
/** Read-only operations the UI drives; none of them changes observable state. */
|
|
114
|
+
export interface Queries {
|
|
115
|
+
readonly running: boolean;
|
|
116
|
+
/** Turns the selected session has finished since this client connected. */
|
|
117
|
+
readonly turnsCompleted: number;
|
|
118
|
+
/** Whether a forked verifier is available to score rounds. */
|
|
119
|
+
readonly forkedVerification: boolean;
|
|
120
|
+
/** Whether this client's own reply block may decide an attempt: no verifier, or the fallback is on. */
|
|
121
|
+
readonly selfScoring: boolean;
|
|
122
|
+
/** Whether this connection generation finished its startup work and is safe to drive. */
|
|
123
|
+
readonly connectionSettled: boolean;
|
|
124
|
+
readonly sessionName: string | undefined;
|
|
125
|
+
readonly sessionMode: string | undefined;
|
|
126
|
+
readonly workingSince: number | undefined;
|
|
127
|
+
readonly visibleSessions: ObjectValue[];
|
|
128
|
+
readonly record: Transcript;
|
|
129
|
+
readonly window: Transcript | undefined;
|
|
130
|
+
readonly interaction: InteractionState;
|
|
131
|
+
readonly telemetry: Telemetry;
|
|
132
|
+
readonly recallAtOldest: boolean;
|
|
133
|
+
readonly recallLength: number;
|
|
134
|
+
readonly recallHasOlder: boolean;
|
|
135
|
+
/** Shortcut prompts the operator saved, oldest first. */
|
|
136
|
+
readonly prompts: readonly SavedPrompt[];
|
|
137
|
+
/** Live progress of the selected session's design review, when one has run. */
|
|
138
|
+
readonly loop: LoopProgress | undefined;
|
|
139
|
+
/** What the client is working on now, already merged across the host turn and any running loop. */
|
|
140
|
+
readonly activity: ClientActivity | undefined;
|
|
141
|
+
/** The one operation that owns the client, when one does; the view renders its label and clock. */
|
|
142
|
+
readonly foreground: ForegroundSnapshot | undefined;
|
|
143
|
+
/** Every readable output source this client knows: verifier sessions, `!` runs, host children. */
|
|
144
|
+
readonly sources: readonly OutputSource[];
|
|
145
|
+
/** The read-only view's content, when one is open; undefined while it is closed. */
|
|
146
|
+
readonly peek: PeekSnapshot | undefined;
|
|
147
|
+
/** Every `loop.yaml` record, so the picker can offer names and their defaults without a lookup. */
|
|
148
|
+
readonly loopRecords: readonly LoopRecord[];
|
|
149
|
+
/** Why the saved prompts could not be read, when the file was malformed. */
|
|
150
|
+
readonly promptsError: string | undefined;
|
|
151
|
+
pendingCounts(): ReadonlyMap<string, number>;
|
|
152
|
+
recall(direction: -1 | 1, current: string): string;
|
|
153
|
+
references(query: string, signal: AbortSignal): Promise<FileReference[]>;
|
|
154
|
+
historyAt(target: number, signal: AbortSignal): Promise<Transcript>;
|
|
155
|
+
/** Plain rows and offsets for one laid-out record. */
|
|
156
|
+
render(input: {
|
|
157
|
+
transcript: Transcript;
|
|
158
|
+
width: number;
|
|
159
|
+
folds: ReadonlySet<number>;
|
|
160
|
+
liveReasoning: Reasoning;
|
|
161
|
+
}): SessionRender;
|
|
162
|
+
}
|
|
163
|
+
/** Everything one `Controller` needs, named so a new capability never shifts an argument position.
|
|
164
|
+
*
|
|
165
|
+
* `base` is the only required field: a local or offline client still has an address to show, while
|
|
166
|
+
* every other capability — authentication, billing, budgets, local shell, shortcut prompts — is
|
|
167
|
+
* opted into by supplying its own field.
|
|
168
|
+
*/
|
|
169
|
+
export interface ControllerOptions {
|
|
170
|
+
/** Host base URL. */
|
|
171
|
+
base: string;
|
|
172
|
+
/** Token for the first authentication; absent when a saved cookie already authenticates. */
|
|
173
|
+
token?: string;
|
|
174
|
+
/** Session to open once connected, instead of starting on the picker. */
|
|
175
|
+
initialSession?: string;
|
|
176
|
+
/** Builds one connection client; defaults to a plain `Client` for `base`. */
|
|
177
|
+
makeClient?: () => Client;
|
|
178
|
+
/** Authenticates one connection client; defaults to the supplied token. */
|
|
179
|
+
authenticate?: (client: Client) => Promise<void>;
|
|
180
|
+
/** Billing ledger; absent disables every cost feature. */
|
|
181
|
+
costs?: CostLedger;
|
|
182
|
+
/** History retention budgets. */
|
|
183
|
+
historyLimits?: HistoryLimits;
|
|
184
|
+
/** Runtime memory log path; absent disables the log. */
|
|
185
|
+
memoryLogPath?: string;
|
|
186
|
+
/** Connection, screen and selection trace path; absent disables the log. */
|
|
187
|
+
tracePath?: string;
|
|
188
|
+
/** Directory this client runs in, offered as a workspace the host has not registered. */
|
|
189
|
+
localDirectory?: string;
|
|
190
|
+
/** Whether `!` may run local commands; the CLI disables it with `--no-shell`. */
|
|
191
|
+
shellEnabled?: boolean;
|
|
192
|
+
/** File holding the operator's shortcut prompts; absent keeps them in memory for this run. */
|
|
193
|
+
promptsPath?: string;
|
|
194
|
+
/** Independent verifier for scored rounds; absent keeps verification inside the reviewed session. */
|
|
195
|
+
verifier?: VerifierPort;
|
|
196
|
+
/** Allow a reply block to decide when the verifier is unavailable; the progress line says so. */
|
|
197
|
+
allowSelfFallback?: boolean;
|
|
198
|
+
/** Client-side root for verdict files; defaults to the workspace this client runs in. */
|
|
199
|
+
verdictRoot?: string;
|
|
200
|
+
/** Whole-run budget in milliseconds; when it expires the run stops as `deadline`. */
|
|
201
|
+
deadlineMs?: number;
|
|
202
|
+
}
|
|
18
203
|
/** Application facade over the domain controllers; the UI owns only this object.
|
|
19
204
|
*
|
|
20
205
|
* State lives here, connection generations live in `connection`, the selected session and its
|
|
21
206
|
* history live in `session`, model metadata lives in `catalog`, and billing lives in `cost`.
|
|
22
207
|
*/
|
|
23
208
|
export declare class Controller implements ControllerStore, ConnectionListener {
|
|
24
|
-
readonly base: string;
|
|
25
|
-
private readonly initialSession?;
|
|
26
|
-
readonly costs?: CostLedger | undefined;
|
|
27
|
-
readonly historyLimits: HistoryLimits;
|
|
28
|
-
readonly memoryLogPath?: string | undefined;
|
|
29
|
-
/** Directory this client runs in, offered as a workspace when the host has not registered it. */
|
|
30
|
-
readonly localDirectory: string;
|
|
31
209
|
state: State;
|
|
32
210
|
/** Physical connection, retry loop and projection store. */
|
|
33
211
|
readonly connection: ConnectionController;
|
|
@@ -39,23 +217,105 @@ export declare class Controller implements ControllerStore, ConnectionListener {
|
|
|
39
217
|
readonly cost: CostController | undefined;
|
|
40
218
|
/** Bounded runtime memory samples; present only when a log path was supplied. */
|
|
41
219
|
readonly memoryLog: MemoryLog | undefined;
|
|
220
|
+
/** Bounded connection, screen and selection trace; present only when a path was supplied. */
|
|
221
|
+
readonly trace: TraceLog | undefined;
|
|
222
|
+
/** Shortcut prompts the operator saved; in memory for this run when no path was supplied. */
|
|
223
|
+
readonly promptStore: PromptStore;
|
|
224
|
+
/** Running agent loop, if any; the loop lives here, not in the UI. */
|
|
225
|
+
private loop?;
|
|
226
|
+
/** Prompt the loop still has to send, when it could not be sent immediately. */
|
|
227
|
+
private loopPrompt?;
|
|
228
|
+
/** Finished turns of the selected session, so a waiter never has to sample a cached flag. */
|
|
229
|
+
private completedTurns;
|
|
230
|
+
/** Sessions the host reported busy, so a lone idle frame cannot claim a finished turn. */
|
|
231
|
+
private readonly busySessions;
|
|
232
|
+
/** When the in-flight attempt's turn ended, while its result block is still awaited. */
|
|
233
|
+
private loopEndedAt?;
|
|
234
|
+
/** Timer that settles an attempt whose reply never commits its result block. */
|
|
235
|
+
private loopSettleTimer?;
|
|
236
|
+
/** Whether an attempt is currently being judged by an independent verifier. */
|
|
237
|
+
private loopVerifying;
|
|
238
|
+
/** A verdict is being consumed right now.
|
|
239
|
+
*
|
|
240
|
+
* Consuming one reads the artifact, so it is asynchronous; without this gate a replayed idle edge
|
|
241
|
+
* could start a second verification of an attempt whose verdict is already being applied.
|
|
242
|
+
*/
|
|
243
|
+
private loopSettling;
|
|
244
|
+
/** Cancels that verification when the loop is stopped or replaced. */
|
|
245
|
+
private loopVerifyAbort?;
|
|
246
|
+
/** Verdict of the previous attempt on the current step, for the retry and the next verifier. */
|
|
247
|
+
private loopPrevious?;
|
|
248
|
+
/** Identity of the run in flight, so its verdicts are isolated from every other run's. */
|
|
249
|
+
private loopRunId?;
|
|
250
|
+
/** Whether the run in flight already wrote its `loop end`; one end per begin (I9). */
|
|
251
|
+
private loopEndTraced;
|
|
252
|
+
/** Sequence of the verification task in flight, so a retry never reuses the old task's identity. */
|
|
253
|
+
private loopVerifySeq;
|
|
254
|
+
/** Identity of the verification task whose result may still decide the attempt in flight. */
|
|
255
|
+
private loopVerifyIdentity?;
|
|
256
|
+
/** Timer that stops the whole run when its budget expires. */
|
|
257
|
+
private loopDeadlineTimer?;
|
|
258
|
+
/** Whole-run budget, when the operator set one. */
|
|
259
|
+
private readonly deadlineMs?;
|
|
260
|
+
/** Consecutive verifier outages in this attempt, so a broken verifier is retried then reported. */
|
|
261
|
+
private loopVerifierMisses;
|
|
262
|
+
/** What the operator answered when a verifier abstained; consumed by the next judgment. */
|
|
263
|
+
private loopAnswer?;
|
|
264
|
+
/** Whether a reply block may stand in for a missing verdict; off unless asked for. */
|
|
265
|
+
private readonly allowSelfFallback;
|
|
266
|
+
/** Client-side directory verdict files are written under. */
|
|
267
|
+
private readonly verdictRoot;
|
|
42
268
|
/** Local `!` commands, run on this machine and shown inline in the transcript. */
|
|
43
269
|
readonly shell: ShellController;
|
|
270
|
+
/** Mutating surface the UI drives. */
|
|
271
|
+
readonly actions: Actions;
|
|
272
|
+
/** Read-only surface the UI drives. */
|
|
273
|
+
readonly queries: Queries;
|
|
274
|
+
/** Host base URL this client talks to. */
|
|
275
|
+
readonly base: string;
|
|
276
|
+
/** Billing ledger supplied at construction, when any. */
|
|
277
|
+
readonly costs: CostLedger | undefined;
|
|
278
|
+
/** History retention budgets in force. */
|
|
279
|
+
readonly historyLimits: HistoryLimits;
|
|
280
|
+
/** Runtime memory log path, when one was configured. */
|
|
281
|
+
readonly memoryLogPath: string | undefined;
|
|
282
|
+
/** Directory this client runs in. */
|
|
283
|
+
readonly localDirectory: string;
|
|
284
|
+
/** Independent verifier for scored rounds, when one was supplied. */
|
|
285
|
+
private readonly verifier;
|
|
286
|
+
/** Session opened at startup, when one was named. */
|
|
287
|
+
private readonly initialSession;
|
|
44
288
|
private readonly observers;
|
|
45
289
|
private selector;
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
|
|
290
|
+
private connectionSettled;
|
|
291
|
+
/** Counter behind `commandId`, so every executed line has one identifier in begin and end. */
|
|
292
|
+
private commandSeq;
|
|
293
|
+
/** The operation that owns the client right now, when one does; the single foreground slot. */
|
|
294
|
+
private foreground?;
|
|
295
|
+
/** Callers waiting for the slot, oldest first; woken one at a time so nobody barges in. */
|
|
296
|
+
private readonly foregroundWaiters;
|
|
297
|
+
/** True while a waiter has been promised the slot but has not taken it yet. */
|
|
298
|
+
private foregroundGranted;
|
|
299
|
+
/** Set when the client stops, so a waiter never starts work on a closed connection. */
|
|
300
|
+
private foregroundClosed;
|
|
301
|
+
private foregroundSeq;
|
|
302
|
+
/** Which operation the current async continuation belongs to, so a nested call never re-claims. */
|
|
303
|
+
private readonly foregroundOwner;
|
|
304
|
+
/** Read-only follower for the full-screen view; it borrows the connection and never selects. */
|
|
305
|
+
readonly peek: SessionPeek;
|
|
306
|
+
/** Sources this client created, keyed by session id; the host cannot record that lineage itself. */
|
|
307
|
+
private readonly createdSources;
|
|
308
|
+
/** The source the read-only view is showing, when one is open. */
|
|
309
|
+
private peekId;
|
|
310
|
+
constructor(options: ControllerOptions);
|
|
51
311
|
/** React-compatible state subscription. */
|
|
52
312
|
subscribe: (listener: () => void) => (() => void);
|
|
53
313
|
/** Snapshot identity changes only when the controller publishes. */
|
|
54
314
|
snapshot: () => State;
|
|
55
315
|
/** Current projection store; replaced at each connection generation. */
|
|
56
|
-
get telemetry()
|
|
316
|
+
private get telemetry();
|
|
57
317
|
/** Record of the selected session; the one strong owner lives in `State.session`. */
|
|
58
|
-
get record()
|
|
318
|
+
private get record();
|
|
59
319
|
/** @returns The current selector generation. */
|
|
60
320
|
selection(): number;
|
|
61
321
|
/** Advance the selector generation when the selected workspace or session changes. */
|
|
@@ -63,7 +323,46 @@ export declare class Controller implements ControllerStore, ConnectionListener {
|
|
|
63
323
|
/** Publish a state patch, re-deriving the visible pending interactions.
|
|
64
324
|
* @param patch - Fields to replace on the current state.
|
|
65
325
|
*/
|
|
326
|
+
/** Whether an operation owns the client's foreground slot right now.
|
|
327
|
+
* @returns True while an operation is running.
|
|
328
|
+
*/
|
|
329
|
+
busy(): boolean;
|
|
66
330
|
update(patch: Partial<State>): void;
|
|
331
|
+
/** Record one diagnostic event; a no-op when no trace path was configured. */
|
|
332
|
+
private traceEvent;
|
|
333
|
+
/** Record one diagnostic event from outside the controller, such as a UI-only decision.
|
|
334
|
+
*
|
|
335
|
+
* The composition root knows things this class cannot see — which record the operator highlighted,
|
|
336
|
+
* that a form was refused a name — and a start that never reaches `startLoop` is otherwise invisible
|
|
337
|
+
* in every log. Same no-op contract as the internal call.
|
|
338
|
+
* @param event - Event name, e.g. `loop-ui`.
|
|
339
|
+
* @param detail - Identifiers only; never prompt or session text.
|
|
340
|
+
*/
|
|
341
|
+
traceNote(event: string, detail?: ObjectValue): void;
|
|
342
|
+
/** Mint the identifier one executed line carries through its `begin` and `end` events.
|
|
343
|
+
*
|
|
344
|
+
* Short and process-local on purpose: it exists to pair two lines of one file, not to identify a
|
|
345
|
+
* line across runs, so a monotonic counter beats a random id a reader would have to match by eye.
|
|
346
|
+
* @returns The next command id, such as `C17`.
|
|
347
|
+
*/
|
|
348
|
+
nextCommandId(): string;
|
|
349
|
+
/** Record the state fields that decide which screen the reader is looking at.
|
|
350
|
+
*
|
|
351
|
+
* Every non-user transition is written here as well as at its cause, so a screen that moved
|
|
352
|
+
* without an expected reason is still visible in the trace rather than silently skipped.
|
|
353
|
+
* @param previous - State before the patch.
|
|
354
|
+
* @param next - State after the patch.
|
|
355
|
+
*/
|
|
356
|
+
private traceTransition;
|
|
357
|
+
/** Bind every mutating entry point to its private implementation.
|
|
358
|
+
*
|
|
359
|
+
* Each one names the kind and label of the operation it performs, because that is now the single
|
|
360
|
+
* answer to "what owns the client right now" (§6.2): the front end renders it and cancels it, and
|
|
361
|
+
* nothing else has to know which layer started the work.
|
|
362
|
+
*/
|
|
363
|
+
private buildActions;
|
|
364
|
+
/** Bind every read-only entry point; getters stay live because the values move between renders. */
|
|
365
|
+
private buildQueries;
|
|
67
366
|
/** Start one retry loop, with a fresh snapshot generation after every disconnect. */
|
|
68
367
|
start(): void;
|
|
69
368
|
/** Cancel retries and HTTP, close the socket, and release session and catalog work. */
|
|
@@ -72,11 +371,52 @@ export declare class Controller implements ControllerStore, ConnectionListener {
|
|
|
72
371
|
* An idle session stays untouched, and an in-flight cancellation is awaited rather than repeated.
|
|
73
372
|
*/
|
|
74
373
|
shutdown(): Promise<void>;
|
|
75
|
-
/** Run
|
|
374
|
+
/** Run one mutating operation inside the client's single foreground slot.
|
|
375
|
+
*
|
|
376
|
+
* Private on purpose: the application owns the slot, so a caller never hands the controller a
|
|
377
|
+
* closure to orchestrate. Every entry of `actions` uses it, and `actions.foreground` is the one
|
|
378
|
+
* door left open for work the front end orchestrates itself.
|
|
379
|
+
* @param kind - What the operation is, for the label and the trace.
|
|
380
|
+
* @param label - Human label shown while it runs.
|
|
76
381
|
* @param operation - Operation to run while the client is busy.
|
|
77
|
-
* @returns Whether the operation
|
|
382
|
+
* @returns Whether the operation ran to completion.
|
|
78
383
|
*/
|
|
79
|
-
|
|
384
|
+
private runAction;
|
|
385
|
+
/** Same slot, for an operation that produces a value the caller needs. */
|
|
386
|
+
private runActionValue;
|
|
387
|
+
/** Whether the current async continuation is already inside the foreground operation.
|
|
388
|
+
*
|
|
389
|
+
* An action invoked *by* a running operation (a paging loop calling `older`, a command's policy
|
|
390
|
+
* calling an action) belongs to that operation: refusing it for being busy would deadlock the very
|
|
391
|
+
* work that owns the slot. An async-local owner answers that exactly, where a plain flag could not
|
|
392
|
+
* tell a nested call from a second, unrelated one.
|
|
393
|
+
* @returns True when this call runs inside the operation that owns the slot.
|
|
394
|
+
*/
|
|
395
|
+
private ownsForeground;
|
|
396
|
+
/** Run one operation in the foreground slot, claiming it when the caller does not already own it.
|
|
397
|
+
*
|
|
398
|
+
* The slot serializes what the operator is doing — one thing at a time — which is a different
|
|
399
|
+
* question from the session write order (§6.3): a read takes this slot too. The controller owns the
|
|
400
|
+
* slot, the abort controller and the identity, so the front end only renders `queries.foreground`
|
|
401
|
+
* and cancels it in one call.
|
|
402
|
+
* @param kind - What the operation is.
|
|
403
|
+
* @param label - Human label shown while it runs.
|
|
404
|
+
* @param work - The work, handed the signal that `cancelForeground` aborts.
|
|
405
|
+
* @returns What the work returned, or undefined when the slot was taken or the work was cancelled.
|
|
406
|
+
*/
|
|
407
|
+
private claimForeground;
|
|
408
|
+
/** Cancel the operation that owns the foreground slot; false when none is running.
|
|
409
|
+
* @returns Whether an operation was there to cancel.
|
|
410
|
+
*/
|
|
411
|
+
private cancelForeground;
|
|
412
|
+
/** Run one local operation that needs no connection, reporting failure the way `runAction` does.
|
|
413
|
+
*
|
|
414
|
+
* Shortcut prompts are the operator's own file, so they must keep working while the host is
|
|
415
|
+
* disconnected; only the failure line is shared with the remote operations.
|
|
416
|
+
* @param operation - Operation to run against local storage.
|
|
417
|
+
* @returns Whether it ran to completion.
|
|
418
|
+
*/
|
|
419
|
+
private runLocalAction;
|
|
80
420
|
/** Read the counters one memory sample records; content never leaves as text.
|
|
81
421
|
*
|
|
82
422
|
* The retained transcript and the ledger are small in practice, so a sample also reads the two
|
|
@@ -98,292 +438,402 @@ export declare class Controller implements ControllerStore, ConnectionListener {
|
|
|
98
438
|
begin(): void;
|
|
99
439
|
/** The event stream is ready and the control baseline is applied. */
|
|
100
440
|
ready(): Promise<void>;
|
|
101
|
-
/** The generation ended; invalidate session work and stop the scan.
|
|
441
|
+
/** The generation ended; invalidate session work and stop the scan.
|
|
442
|
+
*
|
|
443
|
+
* A running loop is deliberately left alone: the host keeps running the review, and the client
|
|
444
|
+
* re-selects the same session after reconnecting, so only a switch to another session ends it.
|
|
445
|
+
*/
|
|
102
446
|
ended(): Promise<void>;
|
|
103
|
-
/**
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
cancelled(eventId: string): void;
|
|
112
|
-
/** Apply one host running-state notification.
|
|
113
|
-
* @param sessionId - Session whose state changed.
|
|
114
|
-
* @param running - Whether the host still runs that session.
|
|
115
|
-
*/
|
|
116
|
-
status(sessionId: string, running: boolean): void;
|
|
117
|
-
/** Surface a host-reported session error.
|
|
118
|
-
* @param sessionId - Session the host reported on.
|
|
119
|
-
* @param error - Error payload as delivered by the host.
|
|
120
|
-
*/
|
|
121
|
-
error(sessionId: unknown, error: unknown): void;
|
|
122
|
-
/** Reload the model catalog after a host settings, credential or adapter change. */
|
|
123
|
-
invalidated(): void;
|
|
124
|
-
/** Refresh billing after a turn finished. */
|
|
125
|
-
idle(): void;
|
|
447
|
+
/** Route one normalized host event to the domain that owns it.
|
|
448
|
+
*
|
|
449
|
+
* This is the composition point: the connection knows only that an event arrived, so a feature
|
|
450
|
+
* never has to hold another feature. `false` means the host's waterfall is still unsettled.
|
|
451
|
+
* @param event - Normalized host event.
|
|
452
|
+
* @returns Whether a retained waterfall was consumed.
|
|
453
|
+
*/
|
|
454
|
+
event(event: HostEvent): boolean;
|
|
126
455
|
/** @returns Host running state of the selected session. */
|
|
127
|
-
get running()
|
|
456
|
+
private get running();
|
|
128
457
|
/** @returns Current session title, falling back to the list title and then the ID. */
|
|
129
|
-
get sessionName()
|
|
458
|
+
private get sessionName();
|
|
130
459
|
/** @returns Current agent-preset label. */
|
|
131
|
-
get sessionMode()
|
|
460
|
+
private get sessionMode();
|
|
132
461
|
/** @returns Epoch start of the active turn, when known. */
|
|
133
|
-
get workingSince()
|
|
462
|
+
private get workingSince();
|
|
463
|
+
/** What the client is doing right now, merged across the host turn and any running loop.
|
|
464
|
+
*
|
|
465
|
+
* This is the controller's answer, not a view's guess: a turn speaks for the session while it runs,
|
|
466
|
+
* otherwise a live loop speaks for itself with its own sub-state and clock, and neither means idle.
|
|
467
|
+
* @returns The activity, or undefined when nothing is in flight.
|
|
468
|
+
*/
|
|
469
|
+
private get activity();
|
|
134
470
|
/** @returns Sessions accounted to the selected workspace, minus archived identities. */
|
|
135
|
-
get visibleSessions()
|
|
471
|
+
private get visibleSessions();
|
|
472
|
+
/** Every readable output source, newest activity first.
|
|
473
|
+
*
|
|
474
|
+
* Three origins feed one list, because a reader asking "what is that session" does not care which
|
|
475
|
+
* layer knows about it: sessions this client created (the host cannot record that link), local `!`
|
|
476
|
+
* runs it already holds, and host-created subagent children, whose only lineage is their list row.
|
|
477
|
+
* A client-created source wins over the list row for the same session, since it says more.
|
|
478
|
+
* @returns Sources to offer, running ones first.
|
|
479
|
+
*/
|
|
480
|
+
private outputSources;
|
|
481
|
+
/** Register a session this client created for a verifier, so the list can explain it. */
|
|
482
|
+
private createVerifierSession;
|
|
483
|
+
/** Mark a source this client created as finished, keeping it readable. */
|
|
484
|
+
private endSource;
|
|
485
|
+
/** Open one source read-only at full screen; a session source starts following it. */
|
|
486
|
+
private openPeek;
|
|
487
|
+
/** Close the read-only view and release whatever it followed. */
|
|
488
|
+
private closePeek;
|
|
489
|
+
/** Release the view without publishing; the caller is already inside an update. */
|
|
490
|
+
private dropPeek;
|
|
491
|
+
/** What the read-only view renders, or undefined while it is closed. */
|
|
492
|
+
private peekSnapshot;
|
|
136
493
|
/** @returns Unanswered interactions by session, for the state each list row reports. */
|
|
137
|
-
pendingCounts
|
|
494
|
+
private pendingCounts;
|
|
138
495
|
/** Load the optional preset roster once per connection. */
|
|
139
|
-
loadPresetNames
|
|
496
|
+
private loadPresetNames;
|
|
140
497
|
/** @returns Host model routes and adapter-owned reasoning choices. */
|
|
141
|
-
modelCatalog
|
|
498
|
+
private modelCatalog;
|
|
142
499
|
/** Select the next request's model.
|
|
143
500
|
* @param provider - Host provider route ID.
|
|
144
501
|
* @param model - Exact model ID.
|
|
145
502
|
* @param reasoningEffort - Optional adapter-owned effort ID.
|
|
146
503
|
*/
|
|
147
|
-
selectModel
|
|
504
|
+
private selectModel;
|
|
148
505
|
/** Stop the selected turn, or allow exit only while idle.
|
|
149
506
|
* @param force - Send an explicit cancellation even when the cached running flag is idle.
|
|
150
507
|
* @returns True when the caller may exit.
|
|
151
508
|
*/
|
|
152
|
-
interrupt
|
|
509
|
+
private interrupt;
|
|
153
510
|
/** One-line estimate of the selected session's cost, or `?` while the ledger has no entry for it. */
|
|
154
|
-
get sessionCostText(): string;
|
|
155
511
|
/** Keep history stable while the user reads, searches, or expands it.
|
|
156
512
|
* @param pinned - Whether the main transcript is being read away from its tail.
|
|
157
513
|
*/
|
|
158
|
-
pinHistory
|
|
514
|
+
private pinHistory;
|
|
515
|
+
/** @returns The detached history window the reader opened, if any. */
|
|
516
|
+
private get window();
|
|
517
|
+
/** Show a detached history window, releasing the one it replaces.
|
|
518
|
+
* @param window - Record to display, or undefined to return to the live transcript.
|
|
519
|
+
*/
|
|
520
|
+
private setViewWindow;
|
|
159
521
|
/** Recall one step through the selected session's prompt index; never touches the network.
|
|
160
522
|
* @param direction - Negative for older input, positive for newer input.
|
|
161
523
|
* @param current - Composer content before recall began, restored at the newest position.
|
|
162
524
|
* @returns The recalled prompt, or the unsent draft.
|
|
163
525
|
*/
|
|
164
|
-
recall
|
|
526
|
+
private recall;
|
|
165
527
|
/** Remember a locally submitted command, which never becomes a durable session record.
|
|
166
528
|
* @param value - Submitted command text.
|
|
167
529
|
*/
|
|
168
|
-
recordRecall
|
|
530
|
+
private recordRecall;
|
|
169
531
|
/** Leave recall navigation because the composer was edited or replaced. */
|
|
170
|
-
resetRecall
|
|
532
|
+
private resetRecall;
|
|
171
533
|
/** Whether recall is parked on the oldest prompt the session retains. */
|
|
172
|
-
get recallAtOldest()
|
|
534
|
+
private get recallAtOldest();
|
|
173
535
|
/** How many prompts the selected session retains for recall. */
|
|
174
|
-
get recallLength()
|
|
536
|
+
private get recallLength();
|
|
175
537
|
/** Whether an older prompt is reachable, in the loaded window or on the host. */
|
|
176
|
-
get recallHasOlder()
|
|
538
|
+
private get recallHasOlder();
|
|
177
539
|
/** Recover older prompts from the loaded window before spending a page request.
|
|
178
540
|
* @returns Whether any older prompt was recovered.
|
|
179
541
|
*/
|
|
180
|
-
refillRecall
|
|
181
|
-
/** Composer draft, caret and parked draft of the selected session. */
|
|
182
|
-
get composer(): ComposerState;
|
|
183
|
-
/** Replace the composer text and caret.
|
|
184
|
-
* @param draft - New text.
|
|
185
|
-
* @param cursor - Caret column; defaults to the end of the text.
|
|
186
|
-
*/
|
|
187
|
-
setComposer(draft: string, cursor?: number): void;
|
|
188
|
-
/** Move the caret without changing the text.
|
|
189
|
-
* @param cursor - Caret column.
|
|
190
|
-
*/
|
|
191
|
-
setComposerCursor(cursor: number): void;
|
|
192
|
-
/** Move a non-empty draft aside while a dialog owns the keyboard. */
|
|
193
|
-
parkComposer(): void;
|
|
194
|
-
/** Give a parked draft back once no dialog needs the keyboard. */
|
|
195
|
-
restoreComposer(): void;
|
|
196
|
-
/** How the selected session's record is being read right now. */
|
|
197
|
-
get view(): ViewState;
|
|
198
|
-
/** Show a detached history window, releasing the one it replaces.
|
|
199
|
-
* @param window - Record to display, or undefined to return to the live transcript.
|
|
200
|
-
*/
|
|
201
|
-
setViewWindow(window?: Transcript): void;
|
|
202
|
-
/** Move the reader's position inside the displayed record.
|
|
203
|
-
* @param scroll - Rows scrolled back from the live end.
|
|
204
|
-
*/
|
|
205
|
-
setScroll(scroll: number): void;
|
|
206
|
-
/** Replace the set of expanded reasoning blocks.
|
|
207
|
-
* @param folds - Sequences to expand beyond the default fold.
|
|
208
|
-
*/
|
|
209
|
-
setFolds(folds: ReadonlySet<number>): void;
|
|
210
|
-
/** Set the fold mode of the live attempt's completed reasoning.
|
|
211
|
-
* @param reasoning - `row` to fold, `full` to keep the streamed text.
|
|
212
|
-
*/
|
|
213
|
-
setLiveReasoning(reasoning: Reasoning): void;
|
|
542
|
+
private refillRecall;
|
|
214
543
|
/** Local answer state for the selected session's pending waterfalls. */
|
|
215
|
-
get interaction()
|
|
544
|
+
private get interaction();
|
|
216
545
|
/** Replace the partly collected answers, keyed by waterfall event id.
|
|
217
546
|
* @param answers - Answers collected so far, by event id.
|
|
218
547
|
*/
|
|
219
|
-
setAnswers
|
|
548
|
+
private setAnswers;
|
|
549
|
+
/** Clear the internal last failure; a no-op when there is none. */
|
|
550
|
+
private clearFailure;
|
|
220
551
|
/** Replace the pending question's option keyboard state.
|
|
221
552
|
* @param option - Highlighted option, toggled labels and free-text mode; undefined clears it.
|
|
222
553
|
*/
|
|
223
|
-
setOption
|
|
554
|
+
private setOption;
|
|
224
555
|
/** Replace the pending approval's selected row.
|
|
225
556
|
* @param approval - Selected approval row; undefined clears the highlight.
|
|
226
557
|
*/
|
|
227
|
-
setApproval
|
|
228
|
-
/** Composer-adjacent `@` reference menu state. */
|
|
229
|
-
get reference(): ReferenceState;
|
|
230
|
-
/** Highlight one row of the open reference menu.
|
|
231
|
-
* @param index - Row index into the current matches.
|
|
232
|
-
*/
|
|
233
|
-
setReferenceIndex(index: number): void;
|
|
234
|
-
/** Remember the draft that dismissed the reference menu.
|
|
235
|
-
* @param draft - Composer text at dismissal, or undefined to allow the menu again.
|
|
236
|
-
*/
|
|
237
|
-
setReferenceDismissed(draft?: string): void;
|
|
238
|
-
/** Panels the selected session has open. */
|
|
239
|
-
get panels(): PanelState;
|
|
240
|
-
/** Show or hide the reasoning panel.
|
|
241
|
-
* @param open - Whether `/think` is open.
|
|
242
|
-
*/
|
|
243
|
-
openThoughts(open: boolean): void;
|
|
244
|
-
/** Show or hide the pending-input panel.
|
|
245
|
-
* @param open - Whether `/queue` is open.
|
|
246
|
-
*/
|
|
247
|
-
openQueue(open: boolean): void;
|
|
248
|
-
/** Show the model dialog at one step, or close it.
|
|
249
|
-
* @param model - Catalog plus the provider or model being inspected; undefined closes the dialog.
|
|
250
|
-
*/
|
|
251
|
-
setModelPanel(model?: ModelState): void;
|
|
252
|
-
/** Show the history or content-search dialog, or close it.
|
|
253
|
-
* @param history - Query, content-search mode and matches; undefined closes the dialog.
|
|
254
|
-
*/
|
|
255
|
-
setHistoryPanel(history?: PanelState['history']): void;
|
|
256
|
-
/** Show the host session-search results, or close them.
|
|
257
|
-
* @param search - Query, results and truncation flag; undefined closes the dialog.
|
|
258
|
-
*/
|
|
259
|
-
setSearchPanel(search?: PanelState['search']): void;
|
|
558
|
+
private setApproval;
|
|
260
559
|
/** Refresh all HTTP-visible sessions without changing the selected conversation.
|
|
261
560
|
* @param signal - Optional cancellation for an explicit /cost refresh.
|
|
262
561
|
*/
|
|
263
|
-
refreshCosts
|
|
562
|
+
private refreshCosts;
|
|
264
563
|
/** Refresh both lists from the host, then show the requested picker.
|
|
265
564
|
* @param screen - Picker to display after the refresh.
|
|
266
565
|
*/
|
|
267
|
-
showPicker
|
|
566
|
+
private showPicker;
|
|
268
567
|
/** Resolve a removal command to one reviewable object.
|
|
269
568
|
* @param kind - Workspace registration removal or session archival.
|
|
270
569
|
* @param query - Exact name, ID, or unambiguous ID prefix.
|
|
271
570
|
* @returns The fixed identity and display details for confirmation.
|
|
272
571
|
*/
|
|
273
|
-
removalTarget
|
|
572
|
+
private removalTarget;
|
|
274
573
|
/** Apply a confirmed removal or verified empty-session archival.
|
|
275
574
|
* @param target - Exact workspace or session identity reviewed by the user.
|
|
276
575
|
*/
|
|
277
|
-
removeTarget
|
|
576
|
+
private removeTarget;
|
|
278
577
|
/** Pick a workspace, or use all sessions when the identity is omitted.
|
|
279
578
|
* @param workspaceId - Workspace to select, if any.
|
|
280
579
|
*/
|
|
281
|
-
pickWorkspace
|
|
580
|
+
private pickWorkspace;
|
|
581
|
+
/** Leave a picker and return to the selected conversation, without reloading it.
|
|
582
|
+
* @returns Whether there was a selected conversation to return to.
|
|
583
|
+
*/
|
|
584
|
+
private showChat;
|
|
282
585
|
/** Open a workspace picker, or resolve a workspace target.
|
|
283
586
|
* @param query - Workspace target, if any.
|
|
284
587
|
*/
|
|
285
|
-
switchWorkspace
|
|
588
|
+
private switchWorkspace;
|
|
286
589
|
/** Guide session selection, list all sessions with `all`, or resolve a target.
|
|
287
590
|
* @param query - Session target, `all`, or nothing for the guided picker.
|
|
288
591
|
*/
|
|
289
|
-
switchSession
|
|
592
|
+
private switchSession;
|
|
290
593
|
/** Prompt for a host path without starting a local agent. */
|
|
291
|
-
enterPath
|
|
594
|
+
private enterPath;
|
|
292
595
|
/** Register a host directory and move to its session picker.
|
|
293
596
|
* @param path - Absolute directory path on the host.
|
|
294
597
|
*/
|
|
295
|
-
createWorkspace
|
|
598
|
+
private createWorkspace;
|
|
296
599
|
/** Create a session in the selected workspace. */
|
|
297
|
-
createSession
|
|
600
|
+
private createSession;
|
|
298
601
|
/** Replace the selected transcript and follow the session.
|
|
299
602
|
* @param sessionId - Session to follow.
|
|
300
603
|
*/
|
|
301
|
-
selectSession
|
|
604
|
+
private selectSession;
|
|
302
605
|
/** Wait for the selected follow snapshot.
|
|
303
606
|
* @param signal - Cancels waiting without closing the session.
|
|
304
607
|
*/
|
|
305
|
-
waitForHistory
|
|
608
|
+
private waitForHistory;
|
|
306
609
|
/** Search host session results.
|
|
307
610
|
* @param query - Literal message text.
|
|
308
611
|
* @param workspaceOnly - Restrict hits to the selected workspace.
|
|
309
612
|
* @param signal - Cancels the HTTP search.
|
|
310
613
|
* @returns Session snippets and the global truncation flag.
|
|
311
614
|
*/
|
|
312
|
-
searchSessions
|
|
313
|
-
items: ObjectValue[];
|
|
314
|
-
hasMore: boolean;
|
|
315
|
-
}>;
|
|
615
|
+
private searchSessions;
|
|
316
616
|
/** Search host paths for the composer's `@` completion.
|
|
317
617
|
* @param query - Path text after @.
|
|
318
618
|
* @param signal - Cancels an obsolete lookup.
|
|
319
619
|
* @returns Validated candidates in host order.
|
|
320
620
|
*/
|
|
321
|
-
|
|
621
|
+
private references;
|
|
322
622
|
/** Execute a human command directly, outside the model prompt queue.
|
|
323
623
|
* @param line - Complete slash command, including arguments.
|
|
324
624
|
* @param signal - Cancels the request while the host performs compaction.
|
|
325
625
|
* @returns The host's successful command result text.
|
|
326
626
|
*/
|
|
327
|
-
command
|
|
627
|
+
private command;
|
|
328
628
|
/** Remove one host-owned pending input.
|
|
329
629
|
* @param itemId - Queue occurrence identity from session/control.
|
|
330
630
|
*/
|
|
331
|
-
removeQueued
|
|
631
|
+
private removeQueued;
|
|
332
632
|
/** Export the selected host log to a new local ZIP file.
|
|
333
633
|
* @param path - Optional local destination; existing files are never overwritten.
|
|
334
634
|
* @param signal - Cancels the download and removes an incomplete file.
|
|
335
635
|
* @returns Absolute saved filename.
|
|
336
636
|
*/
|
|
337
|
-
exportLog
|
|
637
|
+
private exportLog;
|
|
338
638
|
/** Save loaded Markdown, diagrams and math as offline HTML.
|
|
339
639
|
* @param path - Optional filename; existing files are not replaced.
|
|
340
640
|
* @param signal - Cancels the write.
|
|
341
641
|
* @returns Absolute saved filename.
|
|
342
642
|
*/
|
|
343
|
-
exportHtml
|
|
643
|
+
private exportHtml;
|
|
344
644
|
/** Write a V8 heap snapshot into this client's working directory; the write pauses the client.
|
|
345
645
|
* @param tag - Sampling-point label naming the file, such as `after-stress`.
|
|
346
646
|
* @returns Absolute path of the written snapshot.
|
|
347
647
|
*/
|
|
348
|
-
heapSnapshot
|
|
648
|
+
private heapSnapshot;
|
|
349
649
|
/** Admit text once as steering while running, or a new turn while idle.
|
|
650
|
+
*
|
|
651
|
+
* Text the operator typed ends an automated review: the loop must not race a human for the turn,
|
|
652
|
+
* and the reply it would parse is no longer the reply to its own prompt.
|
|
350
653
|
* @param text - Composed prompt text.
|
|
351
654
|
*/
|
|
352
|
-
prompt
|
|
655
|
+
private prompt;
|
|
656
|
+
/** Clear this client's stale handoff file, then ask the agent to write a new one.
|
|
657
|
+
*
|
|
658
|
+
* The deletion happens first and on this machine, so a handoff that never gets written cannot be
|
|
659
|
+
* mistaken for the previous one. The request itself is an ordinary turn: it steers a running
|
|
660
|
+
* agent and starts an idle one, exactly like submitted text.
|
|
661
|
+
*/
|
|
662
|
+
private handoff;
|
|
663
|
+
/** Start a scored loop and send its opening step.
|
|
664
|
+
* @param protocol - Prompt text and step count the loop follows.
|
|
665
|
+
* @param limits - Resolved `--from/--to/--score/--tries`.
|
|
666
|
+
*/
|
|
667
|
+
private startLoop;
|
|
668
|
+
/** End a run whose next prompt could not be sent, keeping the reason visible.
|
|
669
|
+
*
|
|
670
|
+
* A rejected send is not a verdict and not an operator cancellation, so the phase is `needs-human`
|
|
671
|
+
* and `terminalReason` says why — this is what keeps `phase=cancelled` meaning "a person stopped it".
|
|
672
|
+
* @param loop - Run that could not send.
|
|
673
|
+
* @param error - What the host or the session layer rejected with.
|
|
674
|
+
*/
|
|
675
|
+
private rejectLoopSend;
|
|
676
|
+
/** Record the end of one run once, with the phase it stopped in and why.
|
|
677
|
+
*
|
|
678
|
+
* I9 needs every `begin` to be paired inside the trace window; this is the only writer of `loop end`.
|
|
679
|
+
* @param loop - Run whose terminal phase was just published.
|
|
680
|
+
*/
|
|
681
|
+
private traceLoopEnd;
|
|
682
|
+
/** Whether a step begins with verification rather than with a work prompt.
|
|
683
|
+
*
|
|
684
|
+
* Needs all three: the record asks for it, the record has a verifier prompt, and this client was
|
|
685
|
+
* given a verifier. Otherwise there is nobody to verify first, and the step asks for work.
|
|
686
|
+
* @param loop - Loop about to start a step.
|
|
687
|
+
* @returns True when the step starts by verifying.
|
|
688
|
+
*/
|
|
689
|
+
private startsByVerifying;
|
|
690
|
+
/** Verify the step in flight without a work turn before it.
|
|
691
|
+
*
|
|
692
|
+
* The activity is set inside `verifyRound`, so the first verification, a work-turn verdict and a
|
|
693
|
+
* retry all publish the same state without this caller having to remember it.
|
|
694
|
+
* @param loop - Loop whose step and attempt are already set.
|
|
695
|
+
*/
|
|
696
|
+
private verifyStep;
|
|
697
|
+
/** Check the round's own section before spending a verifier on it, then verify or ask for work.
|
|
698
|
+
*
|
|
699
|
+
* Verify-first exists so a round that already passes costs no work turn. When the section is not in
|
|
700
|
+
* the artifact at all the round *cannot* pass, and this client can read that itself — the same check
|
|
701
|
+
* it applies to a verdict before accepting one. Sending a verifier to discover "the file is missing"
|
|
702
|
+
* costs a session and, because a failed attempt consumes one, also the round's first attempt: a run
|
|
703
|
+
* over a document with no review yet would start working at attempt 2/10. An artifact this client
|
|
704
|
+
* cannot read stays a boundary: the verification runs and its verdict decides, as before.
|
|
705
|
+
* @param loop - Loop whose step and attempt are already set.
|
|
706
|
+
*/
|
|
707
|
+
private verifySection;
|
|
708
|
+
/** Whether the directory this client runs in is readable here at all.
|
|
709
|
+
*
|
|
710
|
+
* `readText` answers undefined for a missing file and for a file inside a directory this machine does
|
|
711
|
+
* not have, and the two mean opposite things: the first is a producer that wrote nothing, the second
|
|
712
|
+
* is a workspace whose verdict cannot be checked from here.
|
|
713
|
+
* @returns True when the directory can be listed.
|
|
714
|
+
*/
|
|
715
|
+
private workspaceVisible;
|
|
716
|
+
/** Arm the whole-run budget, when the operator set one. */
|
|
717
|
+
private armLoopDeadline;
|
|
718
|
+
/** Answer a paused run, so the current artifact is judged again with what the operator supplied.
|
|
719
|
+
*
|
|
720
|
+
* The answer is not a work order: it only adds a condition to the judgment, so nothing is sent to the
|
|
721
|
+
* agent and no attempt is consumed. The verification that follows is a new task with a new identity,
|
|
722
|
+
* which is what keeps a late verdict from the paused one from deciding the attempt.
|
|
723
|
+
* @param text - What the operator added; never written to the trace.
|
|
724
|
+
*/
|
|
725
|
+
private answerLoop;
|
|
726
|
+
/** Stop a running review; the terminal progress stays visible for the reader.
|
|
727
|
+
* @param reason - Why it stopped; the default is an operator action.
|
|
728
|
+
*/
|
|
729
|
+
private stopLoop;
|
|
730
|
+
/** Drop a finished run's progress line, keeping an active one.
|
|
731
|
+
*
|
|
732
|
+
* D3 keeps a terminal result on screen because it is what the reader most needs to see — but it is a
|
|
733
|
+
* result, not a status: the next line the operator runs means they have read it. An active run is
|
|
734
|
+
* left alone, so `/loop answer` and `/loop stop` keep the target they were typed for.
|
|
735
|
+
*/
|
|
736
|
+
private clearLoopResult;
|
|
737
|
+
/** Drop the loop entirely, without publishing a cancelled phase.
|
|
738
|
+
* @param reason - Why it was dropped, recorded when it never reached a terminal phase itself.
|
|
739
|
+
*/
|
|
740
|
+
private forgetLoop;
|
|
741
|
+
/** Note that an attempt's turn ended; its block may still be arriving.
|
|
742
|
+
* @param sessionId - Session the host reported idle.
|
|
743
|
+
*/
|
|
744
|
+
private settleLoop;
|
|
745
|
+
/** Consume the attempt once its result block is committed, or the grace period expires.
|
|
746
|
+
*
|
|
747
|
+
* The final assistant message can land a moment after the idle event, so an empty parse is not yet
|
|
748
|
+
* a failed attempt: the next publish retries, and one timer covers a transcript that never grows.
|
|
749
|
+
*/
|
|
750
|
+
private trySettleLoop;
|
|
751
|
+
/** Score one finished round out of band, in a process of its own.
|
|
752
|
+
*
|
|
753
|
+
* The child writes its verdict to a file, so a slow or failed verifier delays the attempt instead
|
|
754
|
+
* of corrupting it: with no verdict the reply block decides, and with neither the attempt fails.
|
|
755
|
+
* @param loop - The run whose attempt just finished.
|
|
756
|
+
*/
|
|
757
|
+
private verifyRound;
|
|
758
|
+
/** Apply a protocol's own artifact requirement, then settle the attempt.
|
|
759
|
+
*
|
|
760
|
+
* The score is the verifier's judgement; whether the round's conclusion actually reached the
|
|
761
|
+
* artifact is a fact this client checks itself. A hard condition may not be overridden by a score:
|
|
762
|
+
* a round whose section is missing fails even at 10/10, and the missing line is fed back to the
|
|
763
|
+
* next attempt like any other finding. An artifact this client cannot read cannot be checked, so
|
|
764
|
+
* the verdict stands rather than being failed on a boundary.
|
|
765
|
+
* @param loop - The run whose attempt just finished.
|
|
766
|
+
* @param result - Verdict to consume.
|
|
767
|
+
* @param note - Note to show instead, when the check accepted the verdict unchanged.
|
|
768
|
+
*/
|
|
769
|
+
private settleChecked;
|
|
770
|
+
/** Apply one attempt's verdict, and continue the run when it has a next step.
|
|
771
|
+
* @param loop - The run being settled.
|
|
772
|
+
* @param result - Verdict to consume, or undefined when the attempt produced none.
|
|
773
|
+
*/
|
|
774
|
+
private settleWith;
|
|
775
|
+
/** Stop an in-flight verification, if any; its result can no longer decide anything. */
|
|
776
|
+
private abortVerification;
|
|
777
|
+
/** Stop the run because the whole-run budget expired; a budget stop, not a verdict.
|
|
778
|
+
*
|
|
779
|
+
* Any verification in flight is cancelled (bounded, as everywhere else) and its late result can
|
|
780
|
+
* no longer decide anything, because the loop is no longer active.
|
|
781
|
+
*/
|
|
782
|
+
private expireLoopDeadline;
|
|
783
|
+
/** Drop the run deadline, if one is armed. */
|
|
784
|
+
private clearLoopDeadline;
|
|
785
|
+
/** Drop a pending settle timer, if any. */
|
|
786
|
+
private forgetSettleTimer;
|
|
787
|
+
/** Send the prompt the loop is holding, once the client can actually send it. */
|
|
788
|
+
private flushLoop;
|
|
353
789
|
/** Cancel the active turn; pending queue items remain host-owned. */
|
|
354
|
-
cancelTurn
|
|
790
|
+
private cancelTurn;
|
|
355
791
|
/** Add a page before the retained window.
|
|
356
792
|
* @param signal - Cancels local paging without interrupting the remote agent.
|
|
357
793
|
* @param transcript - Transcript to extend; defaults to the live one.
|
|
358
794
|
*/
|
|
359
|
-
older
|
|
795
|
+
private older;
|
|
360
796
|
/** Search the loaded history page by page.
|
|
361
797
|
* @param query - Literal, case-insensitive text including folded reasoning.
|
|
362
798
|
* @param signal - Cancels HTTP and processing without cancelling the agent.
|
|
363
799
|
* @returns Newest-first bounded summaries and an explicit truncation flag.
|
|
364
800
|
*/
|
|
365
|
-
searchHistory
|
|
801
|
+
private searchHistory;
|
|
366
802
|
/** Load a separate small window ending at a search target.
|
|
367
803
|
* @param target - Durable message sequence to display.
|
|
368
804
|
* @param signal - Cancels the target-page request.
|
|
369
805
|
* @returns A caller-owned historical window that must be disposed when closed.
|
|
370
806
|
*/
|
|
371
|
-
historyAt
|
|
807
|
+
private historyAt;
|
|
808
|
+
/** Plain rows and offsets for one laid-out record; the projection stays in the session domain. */
|
|
809
|
+
private render;
|
|
372
810
|
/** Load the prefix required for an explicit history jump.
|
|
373
811
|
* @param target - Visible record sequence, or first for the oldest available history.
|
|
374
812
|
* @param signal - Cancels local paging without interrupting the remote agent.
|
|
375
813
|
*/
|
|
376
|
-
historyThrough
|
|
814
|
+
private historyThrough;
|
|
377
815
|
/** Answer the oldest selected-session interaction, after explicit user action.
|
|
378
|
-
* @param value - Structured answer
|
|
816
|
+
* @param value - Structured answer collected by the UI.
|
|
379
817
|
*/
|
|
380
|
-
answer
|
|
818
|
+
private answer;
|
|
819
|
+
/** Answer the current sub-question of the pending set, advancing the waterfall or sending it.
|
|
820
|
+
*
|
|
821
|
+
* The waterfall is interaction state of the session — which sub-question is current follows from the
|
|
822
|
+
* answers collected so far, and the ticked labels live in the option state — so it belongs here
|
|
823
|
+
* rather than in a front end. Both entry points then complete a question the same way: a line the
|
|
824
|
+
* operator typed as an answer, and the option keys.
|
|
825
|
+
* @param input - Labels chosen for this sub-question, or free text the operator typed.
|
|
826
|
+
* @returns True once the answer was recorded or sent; a host refusal throws, leaving the collected
|
|
827
|
+
* answers in place so the same submission can be retried.
|
|
828
|
+
*/
|
|
829
|
+
private answerQuestion;
|
|
381
830
|
/** Approve or reject the pending approval request.
|
|
382
831
|
* @param allowed - Whether the request is approved once.
|
|
383
832
|
*/
|
|
384
|
-
approve
|
|
833
|
+
private approve;
|
|
385
834
|
/** Dismiss the whole pending question set without answering it, as the Web close button does. */
|
|
386
|
-
dismissQuestion
|
|
835
|
+
private dismissQuestion;
|
|
387
836
|
}
|
|
388
|
-
export type { HistorySearch, RemovalTarget } from '../session/types.ts';
|
|
837
|
+
export type { HistorySearch, RemovalTarget, AnswerValue, PendingInteraction } from '../session/types.ts';
|
|
838
|
+
export type { SavedPrompt } from '../contracts.ts';
|
|
389
839
|
export type { State } from '../state.ts';
|