@aragon-agent/cli 0.6.4 → 0.6.8
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/CHANGELOG.md +37 -0
- package/README.md +163 -37
- package/dist/agent/controller.d.ts +49 -8
- package/dist/agent/controller.js +160 -48
- package/dist/agent/headless.d.ts +2 -1
- package/dist/agent/prompt-options.d.ts +15 -0
- package/dist/agent/prompt-options.js +1 -0
- package/dist/agent/reducer.d.ts +33 -19
- package/dist/agent/reducer.js +62 -71
- package/dist/agent/usage.d.ts +34 -0
- package/dist/agent/usage.js +43 -0
- package/dist/cli.js +131 -54
- package/dist/commands/builtins.js +12 -1
- package/dist/commands/registry.d.ts +2 -3
- package/dist/compaction/compactor.d.ts +60 -24
- package/dist/compaction/compactor.js +89 -61
- package/dist/compaction/context-command.d.ts +33 -0
- package/dist/compaction/context-command.js +166 -0
- package/dist/compaction/meter.d.ts +251 -0
- package/dist/compaction/meter.js +428 -0
- package/dist/compaction/pressure.d.ts +6 -0
- package/dist/compaction/pressure.js +4 -0
- package/dist/compaction/types.d.ts +41 -0
- package/dist/compaction/wiring.d.ts +47 -0
- package/dist/compaction/wiring.js +88 -27
- package/dist/config/cli-commands.js +5 -0
- package/dist/config/env.js +15 -1
- package/dist/config/load.d.ts +17 -0
- package/dist/config/load.js +45 -1
- package/dist/config/schema.d.ts +44 -0
- package/dist/config/schema.js +36 -0
- package/dist/config/store.js +27 -1
- package/dist/exec/events.d.ts +138 -1
- package/dist/exec/events.js +42 -0
- package/dist/exec/index.js +43 -6
- package/dist/exec/progress-reporter.d.ts +23 -0
- package/dist/exec/progress-reporter.js +88 -0
- package/dist/exec/runner.d.ts +34 -0
- package/dist/exec/runner.js +137 -25
- package/dist/fast/reviewer.d.ts +19 -1
- package/dist/fast/reviewer.js +22 -0
- package/dist/fast/types.d.ts +15 -0
- package/dist/fast/wiring.d.ts +10 -1
- package/dist/fast/wiring.js +18 -1
- package/dist/input/interrupt-gesture.d.ts +18 -0
- package/dist/input/interrupt-gesture.js +19 -0
- package/dist/input/pointer-router.d.ts +11 -0
- package/dist/input/pointer-router.js +14 -0
- package/dist/todo/limits.d.ts +4 -17
- package/dist/todo/limits.js +4 -17
- package/dist/todo/panel-rows.d.ts +8 -6
- package/dist/todo/panel-rows.js +19 -6
- package/dist/todo/store.d.ts +8 -13
- package/dist/todo/store.js +13 -14
- package/dist/todo/types.d.ts +2 -1
- package/dist/ui/App.d.ts +2 -0
- package/dist/ui/App.js +233 -183
- package/dist/ui/AutocompletePopup.d.ts +3 -1
- package/dist/ui/AutocompletePopup.js +9 -11
- package/dist/ui/BottomStatusRow.d.ts +1 -1
- package/dist/ui/Composer.d.ts +13 -5
- package/dist/ui/Composer.js +7 -11
- package/dist/ui/PromptCaret.d.ts +11 -0
- package/dist/ui/PromptCaret.js +31 -0
- package/dist/ui/PromptInput.d.ts +12 -6
- package/dist/ui/PromptInput.js +50 -16
- package/dist/ui/StatusBar.d.ts +22 -15
- package/dist/ui/StatusBar.js +61 -16
- package/dist/ui/TeamPanel.d.ts +3 -1
- package/dist/ui/TeamPanel.js +13 -9
- package/dist/ui/TodoPanel.d.ts +5 -5
- package/dist/ui/TodoPanel.js +56 -24
- package/dist/ui/Transcript.js +1 -0
- package/dist/ui/UpdateLine.d.ts +1 -1
- package/dist/ui/capabilities.js +5 -5
- package/dist/ui/composer-rows.js +50 -9
- package/dist/ui/exit-snapshot.d.ts +9 -0
- package/dist/ui/frame-differ.js +2 -19
- package/dist/ui/frame-observer.d.ts +17 -0
- package/dist/ui/frame-observer.js +81 -0
- package/dist/ui/frame-parser.d.ts +7 -0
- package/dist/ui/frame-parser.js +18 -0
- package/dist/ui/layout/AppShell.d.ts +7 -52
- package/dist/ui/layout/AppShell.js +2 -2
- package/dist/ui/layout/ScrollIndicator.d.ts +4 -3
- package/dist/ui/layout/ScrollIndicator.js +4 -4
- package/dist/ui/layout/ScrollViewport.d.ts +13 -66
- package/dist/ui/layout/ScrollViewport.js +183 -185
- package/dist/ui/layout/autocomplete.d.ts +18 -0
- package/dist/ui/layout/autocomplete.js +26 -0
- package/dist/ui/layout/budget.d.ts +3 -51
- package/dist/ui/layout/budget.js +4 -53
- package/dist/ui/layout/document-layout.d.ts +13 -0
- package/dist/ui/layout/document-layout.js +11 -0
- package/dist/ui/layout/follow-state.d.ts +1 -0
- package/dist/ui/layout/follow-state.js +1 -3
- package/dist/ui/layout/rail.d.ts +4 -53
- package/dist/ui/layout/rail.js +10 -62
- package/dist/ui/layout/scroll-indicator.d.ts +1 -1
- package/dist/ui/layout/scroll-indicator.js +3 -2
- package/dist/ui/layout/scrollbar-geometry.d.ts +17 -0
- package/dist/ui/layout/scrollbar-geometry.js +13 -0
- package/dist/ui/layout/team-panel.d.ts +18 -0
- package/dist/ui/layout/team-panel.js +22 -0
- package/dist/ui/layout/todo-layout.d.ts +25 -0
- package/dist/ui/layout/todo-layout.js +28 -0
- package/dist/ui/layout/viewport-geometry.d.ts +1 -0
- package/dist/ui/layout/viewport-geometry.js +1 -0
- package/dist/ui/layout/virtual-window.d.ts +1 -0
- package/dist/ui/layout/virtual-window.js +1 -1
- package/dist/ui/overlays/HelpOverlay.js +5 -2
- package/dist/ui/screen.d.ts +1 -1
- package/dist/ui/screen.js +4 -6
- package/dist/ui/scrollbar-controller.d.ts +30 -0
- package/dist/ui/scrollbar-controller.js +124 -0
- package/dist/ui/transcript-text.js +6 -2
- package/dist/ui/use-wheel-routing.d.ts +2 -0
- package/dist/ui/use-wheel-routing.js +6 -0
- package/package.json +2 -2
|
@@ -57,6 +57,12 @@ export interface PressureInput {
|
|
|
57
57
|
contextWindow: number;
|
|
58
58
|
/** False when the window is `buildRuntimeModel`'s 128k placeholder. */
|
|
59
59
|
windowKnown: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Whether `contextWindow` came from the user's `contextWindow` override
|
|
62
|
+
* (context-usage-gauge-accuracy I-6). Defaults to `false`, so every existing
|
|
63
|
+
* construction site is unchanged and the arithmetic below is untouched.
|
|
64
|
+
*/
|
|
65
|
+
windowOverridden?: boolean;
|
|
60
66
|
/** Carried from the last `turn_end`; applied to every ESTIMATED figure. */
|
|
61
67
|
estimateOffset?: number;
|
|
62
68
|
/**
|
|
@@ -138,6 +138,10 @@ export function computePressure(input) {
|
|
|
138
138
|
headroom: Math.max(0, window - occupied),
|
|
139
139
|
source,
|
|
140
140
|
windowKnown: input.windowKnown,
|
|
141
|
+
// PURE PASS-THROUGH. This function's arithmetic is unchanged by
|
|
142
|
+
// context-usage-gauge-accuracy; the flag only travels with the number so
|
|
143
|
+
// `/context` can name the denominator's source (I-6).
|
|
144
|
+
windowOverridden: input.windowOverridden ?? false,
|
|
141
145
|
...(input.estimateOffset !== undefined ? { estimateOffset: input.estimateOffset } : {}),
|
|
142
146
|
deltaTokens,
|
|
143
147
|
};
|
|
@@ -60,6 +60,18 @@ export interface Pressure {
|
|
|
60
60
|
source: PressureSource;
|
|
61
61
|
/** False when the window came from `buildRuntimeModel`'s 128k placeholder. */
|
|
62
62
|
windowKnown: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Whether the denominator came from the user's `contextWindow` override
|
|
65
|
+
* (context-usage-gauge-accuracy I-6).
|
|
66
|
+
*
|
|
67
|
+
* SEPARATE FROM `windowKnown` RATHER THAN FOLDED INTO IT. An override makes
|
|
68
|
+
* the window KNOWN - the user asserted it, so the `~` has no business staying
|
|
69
|
+
* on the percentage - but `/context` still has to be able to say WHO supplied
|
|
70
|
+
* the number. Collapsing the two into one boolean makes "found in the model
|
|
71
|
+
* table" and "typed by hand" indistinguishable in the report, and the second
|
|
72
|
+
* one being wrong is exactly the case that most needs to be visible.
|
|
73
|
+
*/
|
|
74
|
+
windowOverridden: boolean;
|
|
63
75
|
/**
|
|
64
76
|
* `occupiedTokens(lastUsage) - estimateOf(the history that produced it)`,
|
|
65
77
|
* clamped to `>= 0`, or `undefined` before the first `turn_end`.
|
|
@@ -89,6 +101,35 @@ export interface Pressure {
|
|
|
89
101
|
*/
|
|
90
102
|
deltaTokens: number;
|
|
91
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* The ONE occupancy projection the status bar and `/context` read
|
|
106
|
+
* (context-usage-gauge-accuracy §4.1).
|
|
107
|
+
*
|
|
108
|
+
* DELIBERATELY CARRIES NO TIMESTAMP. Its only consumer is the reducer's identity
|
|
109
|
+
* short-circuit (§5.2), and a field that changes on every tick would make that
|
|
110
|
+
* short-circuit never hold - turning a permanently visible row into a 2.5 Hz
|
|
111
|
+
* re-render source and pushing the render governor up its ladder for nothing.
|
|
112
|
+
*
|
|
113
|
+
* `Pressure` is the compaction subsystem's shape and carries a headroom and a
|
|
114
|
+
* ratio the UI does not want; this is the projection of it that crosses into
|
|
115
|
+
* view state, and `toContextUsage` in `meter.ts` is the ONLY converter.
|
|
116
|
+
*/
|
|
117
|
+
export interface ContextUsageSnapshot {
|
|
118
|
+
/** Occupied tokens (measured, plus an estimate of anything appended since). */
|
|
119
|
+
occupied: number;
|
|
120
|
+
/** The denominator actually used. */
|
|
121
|
+
window: number;
|
|
122
|
+
/** `occupied / window` as a percentage, clamped to [0, 100] and rounded. */
|
|
123
|
+
pct: number;
|
|
124
|
+
/** Where the BASE came from. */
|
|
125
|
+
source: PressureSource;
|
|
126
|
+
/** How much of `occupied` is an estimate of appended messages; `> 0` means approximate. */
|
|
127
|
+
deltaTokens: number;
|
|
128
|
+
/** Whether the denominator is trustworthy (in the model table, or overridden). */
|
|
129
|
+
windowKnown: boolean;
|
|
130
|
+
/** Whether the denominator came from the user's `contextWindow` (I-6). */
|
|
131
|
+
windowOverridden: boolean;
|
|
132
|
+
}
|
|
92
133
|
/** One compaction, in whatever state it reached. Rendered by `CompactionCard`. */
|
|
93
134
|
export interface CompactionRecord {
|
|
94
135
|
/** 1-based within the session, so the card can name itself. */
|
|
@@ -39,6 +39,7 @@ import { type AgentEvent, type ContextManager, type Message, type ModelInfo, typ
|
|
|
39
39
|
import type { CliConfig } from '../config/schema.js';
|
|
40
40
|
import type { NoticeLevel } from '../agent/reducer.js';
|
|
41
41
|
import { type ChildContextManagerFactory } from './child.js';
|
|
42
|
+
import { ContextMeter } from './meter.js';
|
|
42
43
|
import type { CompactionEventListener, CompactionSnapshot } from './types.js';
|
|
43
44
|
export interface CompactionWiringDeps {
|
|
44
45
|
/** Read LIVE on every call - the controller replaces the object on mutation. */
|
|
@@ -54,6 +55,17 @@ export interface CompactionWiringDeps {
|
|
|
54
55
|
getMessages: () => readonly Message[];
|
|
55
56
|
getSystemPrompt: () => string;
|
|
56
57
|
notify: (level: NoticeLevel, text: string) => void;
|
|
58
|
+
/**
|
|
59
|
+
* The controller's `ContextMeter`, forwarded to the compactor
|
|
60
|
+
* (context-usage-gauge-accuracy W1).
|
|
61
|
+
*
|
|
62
|
+
* OPTIONAL SO EVERY EXISTING CONSTRUCTION SITE COMPILES (R-1); production
|
|
63
|
+
* always injects, and `AgentController` owns the instance because it builds
|
|
64
|
+
* one UNCONDITIONALLY while this class only exists when `compaction.enabled`
|
|
65
|
+
* is true. That asymmetry is the whole point: occupancy has to be measurable
|
|
66
|
+
* in a session that turned compaction off.
|
|
67
|
+
*/
|
|
68
|
+
meter?: ContextMeter;
|
|
57
69
|
/**
|
|
58
70
|
* How the summarizer's own registry is built. Defaults to `initProviders`.
|
|
59
71
|
*
|
|
@@ -80,6 +92,8 @@ export declare class CompactionWiring {
|
|
|
80
92
|
private readonly log;
|
|
81
93
|
private readonly listeners;
|
|
82
94
|
private readonly compactor;
|
|
95
|
+
/** The occupancy meter, injected or private (R-1). Forwarded to the compactor. */
|
|
96
|
+
private readonly meter;
|
|
83
97
|
/** The compactor's OWN transport (D-10). Lazy - see `getRegistry()`. */
|
|
84
98
|
private registry;
|
|
85
99
|
private unsubscribe;
|
|
@@ -152,6 +166,20 @@ export declare class CompactionWiring {
|
|
|
152
166
|
* `/clear`, `/resume`, and any future host-side rewrite. A recorded prefix
|
|
153
167
|
* length indexes an array that no longer exists, so the delta must be
|
|
154
168
|
* abandoned rather than applied to a different history.
|
|
169
|
+
*
|
|
170
|
+
* THE **DEEP** RESET (I-8). `/resume` can change the model in the same breath,
|
|
171
|
+
* so `estimateOffset` - a calibration for one toolset on one model - goes too.
|
|
172
|
+
* The SHALLOW reset is `settlePending`'s splice branch, and the two are not
|
|
173
|
+
* interchangeable: swapping them produces silent errors in OPPOSITE
|
|
174
|
+
* directions (a splice that drops the offset reads too low and climbs back; a
|
|
175
|
+
* resume that keeps it reads too high and never self-corrects).
|
|
176
|
+
*
|
|
177
|
+
* DUPLICATED BY `AgentController` ON PURPOSE. The controller calls
|
|
178
|
+
* `contextMeter.onHistoryReplaced()` directly at the same two sites, because
|
|
179
|
+
* this class does not exist at all when `compaction.enabled` is false - and
|
|
180
|
+
* that unconditional call is the only thing that keeps `/resume` re-measuring
|
|
181
|
+
* for such a session. A deep reset is idempotent, so both firing costs
|
|
182
|
+
* nothing; deleting the controller's copy "to de-duplicate" reintroduces P0-2.
|
|
155
183
|
*/
|
|
156
184
|
onHistoryReplaced(): void;
|
|
157
185
|
/**
|
|
@@ -201,6 +229,17 @@ export declare class CompactionWiring {
|
|
|
201
229
|
ok: false;
|
|
202
230
|
reason: string;
|
|
203
231
|
}>;
|
|
232
|
+
/**
|
|
233
|
+
* The status a reader gets right now.
|
|
234
|
+
*
|
|
235
|
+
* IT READS `meter.current()`, WHICH RE-MEASURES WHEN DIRTY - and that is the
|
|
236
|
+
* fix for P0-1 (§3.3). This method is called one statement after
|
|
237
|
+
* `settlePending` marks the meter spliced, so the `snapshot` event emitted
|
|
238
|
+
* immediately after `compaction_end` carries the POST-compaction occupancy.
|
|
239
|
+
* The old body preferred `compactor.lastMeasured()`, i.e. the measurement that
|
|
240
|
+
* TRIGGERED this compaction, so the gauge fell and was bounced straight back
|
|
241
|
+
* to the pre-compaction figure inside the same synchronous emit loop.
|
|
242
|
+
*/
|
|
204
243
|
snapshot(): CompactionSnapshot;
|
|
205
244
|
/**
|
|
206
245
|
* `snapshot()` with the pressure argument substituted for the re-measurement.
|
|
@@ -214,6 +253,14 @@ export declare class CompactionWiring {
|
|
|
214
253
|
/** The summarizer that would be used right now, for `/compact status`. */
|
|
215
254
|
summarizerRef(): ModelRef | null;
|
|
216
255
|
subscribe(listener: CompactionEventListener): () => void;
|
|
256
|
+
/**
|
|
257
|
+
* The main model, for the FALLBACK meter's deps only (R-1).
|
|
258
|
+
*
|
|
259
|
+
* Production injects a meter built by `AgentController`, which resolves the
|
|
260
|
+
* same ref from the same live config; this exists so a test that constructs a
|
|
261
|
+
* bare wiring still gets a working denominator.
|
|
262
|
+
*/
|
|
263
|
+
private mainRef;
|
|
217
264
|
/**
|
|
218
265
|
* The transport one summarization call goes through - separate from the lead's,
|
|
219
266
|
* and fail-fast (D-10).
|
|
@@ -40,6 +40,7 @@ import { getLogger } from '../logging/logger.js';
|
|
|
40
40
|
import { mintRunId, writeArchive } from './archive.js';
|
|
41
41
|
import { createChildContextManager } from './child.js';
|
|
42
42
|
import { Compactor } from './compactor.js';
|
|
43
|
+
import { ContextMeter } from './meter.js';
|
|
43
44
|
/**
|
|
44
45
|
* One retry, not ten and not zero - the `fast/wiring.ts` argument unchanged
|
|
45
46
|
* (D-10).
|
|
@@ -68,6 +69,7 @@ export function offCompactionSnapshot() {
|
|
|
68
69
|
headroom: 0,
|
|
69
70
|
source: 'estimate',
|
|
70
71
|
windowKnown: false,
|
|
72
|
+
windowOverridden: false,
|
|
71
73
|
deltaTokens: 0,
|
|
72
74
|
},
|
|
73
75
|
};
|
|
@@ -77,6 +79,8 @@ export class CompactionWiring {
|
|
|
77
79
|
log = getLogger().child('compaction');
|
|
78
80
|
listeners = new Set();
|
|
79
81
|
compactor;
|
|
82
|
+
/** The occupancy meter, injected or private (R-1). Forwarded to the compactor. */
|
|
83
|
+
meter;
|
|
80
84
|
/** The compactor's OWN transport (D-10). Lazy - see `getRegistry()`. */
|
|
81
85
|
registry = null;
|
|
82
86
|
unsubscribe = null;
|
|
@@ -125,6 +129,15 @@ export class CompactionWiring {
|
|
|
125
129
|
constructor(deps) {
|
|
126
130
|
this.deps = deps;
|
|
127
131
|
this.enabled = deps.getConfig().compaction.enabled;
|
|
132
|
+
this.meter =
|
|
133
|
+
deps.meter ??
|
|
134
|
+
new ContextMeter({
|
|
135
|
+
getMessages: deps.getMessages,
|
|
136
|
+
getSystemPrompt: deps.getSystemPrompt,
|
|
137
|
+
getModelInfo: () => deps.getModelInfoFor(this.mainRef()),
|
|
138
|
+
isWindowKnown: () => deps.isPricedModel(this.mainRef()),
|
|
139
|
+
getWindowOverride: () => deps.getConfig().contextWindow,
|
|
140
|
+
});
|
|
128
141
|
this.compactor = new Compactor({
|
|
129
142
|
getConfig: deps.getConfig,
|
|
130
143
|
hasKey: deps.hasKey,
|
|
@@ -139,6 +152,9 @@ export class CompactionWiring {
|
|
|
139
152
|
complete: (providerId, request) => this.getRegistry().complete(providerId, request),
|
|
140
153
|
emit: (event) => this.onCompactorEvent(event),
|
|
141
154
|
notify: deps.notify,
|
|
155
|
+
// ONE METER PER PROCESS. The compactor must not build its own fallback
|
|
156
|
+
// here, or the trigger would read a different number from the gauge.
|
|
157
|
+
meter: this.meter,
|
|
142
158
|
// ONE NUMBER ON SCREEN AND IN THE TRIGGER (R-11 / DH-15). The checkpoint
|
|
143
159
|
// has already measured; publishing THAT pressure rather than re-measuring
|
|
144
160
|
// is what keeps the two from disagreeing by one turn's tool results.
|
|
@@ -205,9 +221,23 @@ export class CompactionWiring {
|
|
|
205
221
|
* `/clear`, `/resume`, and any future host-side rewrite. A recorded prefix
|
|
206
222
|
* length indexes an array that no longer exists, so the delta must be
|
|
207
223
|
* abandoned rather than applied to a different history.
|
|
224
|
+
*
|
|
225
|
+
* THE **DEEP** RESET (I-8). `/resume` can change the model in the same breath,
|
|
226
|
+
* so `estimateOffset` - a calibration for one toolset on one model - goes too.
|
|
227
|
+
* The SHALLOW reset is `settlePending`'s splice branch, and the two are not
|
|
228
|
+
* interchangeable: swapping them produces silent errors in OPPOSITE
|
|
229
|
+
* directions (a splice that drops the offset reads too low and climbs back; a
|
|
230
|
+
* resume that keeps it reads too high and never self-corrects).
|
|
231
|
+
*
|
|
232
|
+
* DUPLICATED BY `AgentController` ON PURPOSE. The controller calls
|
|
233
|
+
* `contextMeter.onHistoryReplaced()` directly at the same two sites, because
|
|
234
|
+
* this class does not exist at all when `compaction.enabled` is false - and
|
|
235
|
+
* that unconditional call is the only thing that keeps `/resume` re-measuring
|
|
236
|
+
* for such a session. A deep reset is idempotent, so both firing costs
|
|
237
|
+
* nothing; deleting the controller's copy "to de-duplicate" reintroduces P0-2.
|
|
208
238
|
*/
|
|
209
239
|
onHistoryReplaced() {
|
|
210
|
-
this.
|
|
240
|
+
this.meter.onHistoryReplaced();
|
|
211
241
|
}
|
|
212
242
|
/**
|
|
213
243
|
* The per-child manager factory, or `null` when children get none
|
|
@@ -314,13 +344,19 @@ export class CompactionWiring {
|
|
|
314
344
|
// -----------------------------------------------------------------------
|
|
315
345
|
// Status and events
|
|
316
346
|
// -----------------------------------------------------------------------
|
|
347
|
+
/**
|
|
348
|
+
* The status a reader gets right now.
|
|
349
|
+
*
|
|
350
|
+
* IT READS `meter.current()`, WHICH RE-MEASURES WHEN DIRTY - and that is the
|
|
351
|
+
* fix for P0-1 (§3.3). This method is called one statement after
|
|
352
|
+
* `settlePending` marks the meter spliced, so the `snapshot` event emitted
|
|
353
|
+
* immediately after `compaction_end` carries the POST-compaction occupancy.
|
|
354
|
+
* The old body preferred `compactor.lastMeasured()`, i.e. the measurement that
|
|
355
|
+
* TRIGGERED this compaction, so the gauge fell and was bounced straight back
|
|
356
|
+
* to the pre-compaction figure inside the same synchronous emit loop.
|
|
357
|
+
*/
|
|
317
358
|
snapshot() {
|
|
318
|
-
|
|
319
|
-
this.compactor.measure({
|
|
320
|
-
messages: this.deps.getMessages(),
|
|
321
|
-
systemPrompt: this.deps.getSystemPrompt(),
|
|
322
|
-
});
|
|
323
|
-
return this.snapshotWith(pressure);
|
|
359
|
+
return this.snapshotWith(this.meter.current());
|
|
324
360
|
}
|
|
325
361
|
/**
|
|
326
362
|
* `snapshot()` with the pressure argument substituted for the re-measurement.
|
|
@@ -362,6 +398,17 @@ export class CompactionWiring {
|
|
|
362
398
|
// -----------------------------------------------------------------------
|
|
363
399
|
// Internals
|
|
364
400
|
// -----------------------------------------------------------------------
|
|
401
|
+
/**
|
|
402
|
+
* The main model, for the FALLBACK meter's deps only (R-1).
|
|
403
|
+
*
|
|
404
|
+
* Production injects a meter built by `AgentController`, which resolves the
|
|
405
|
+
* same ref from the same live config; this exists so a test that constructs a
|
|
406
|
+
* bare wiring still gets a working denominator.
|
|
407
|
+
*/
|
|
408
|
+
mainRef() {
|
|
409
|
+
const config = this.deps.getConfig();
|
|
410
|
+
return { providerId: config.provider, modelId: config.model };
|
|
411
|
+
}
|
|
365
412
|
/**
|
|
366
413
|
* The transport one summarization call goes through - separate from the lead's,
|
|
367
414
|
* and fail-fast (D-10).
|
|
@@ -408,19 +455,16 @@ export class CompactionWiring {
|
|
|
408
455
|
return;
|
|
409
456
|
}
|
|
410
457
|
if (event.type === 'turn_end') {
|
|
411
|
-
//
|
|
412
|
-
//
|
|
413
|
-
//
|
|
414
|
-
//
|
|
415
|
-
|
|
416
|
-
//
|
|
417
|
-
//
|
|
418
|
-
//
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
messages: this.deps.getMessages(),
|
|
422
|
-
systemPrompt: this.deps.getSystemPrompt(),
|
|
423
|
-
});
|
|
458
|
+
// THE MEASUREMENT IS THE METER'S (context-usage-gauge-accuracy §3.3.4). It
|
|
459
|
+
// subscribes to `turn_end` on the same stream and recomputes the offset,
|
|
460
|
+
// the prefix length and the pressure there; the two calls that used to
|
|
461
|
+
// live here - `compactor.onTurnEnd(...)` and `compactor.measure(...)` -
|
|
462
|
+
// were both forwarders to it and doing the same work twice.
|
|
463
|
+
//
|
|
464
|
+
// THE SNAPSHOT EMIT STAYS. The other fields on it - `inFlight`, the
|
|
465
|
+
// session counts, the summarizer - are this class's own and still need
|
|
466
|
+
// refreshing on a turn boundary, and `snapshot()` picks up the meter's
|
|
467
|
+
// freshly published pressure for free.
|
|
424
468
|
this.emit({ type: 'snapshot', snapshot: this.snapshot() });
|
|
425
469
|
return;
|
|
426
470
|
}
|
|
@@ -462,9 +506,13 @@ export class CompactionWiring {
|
|
|
462
506
|
// A SILENT DECLINE (quiet-noop §3.6). No card - but the gauge and the chip
|
|
463
507
|
// are still refreshed: `inFlight` has just gone false and `/compact status`
|
|
464
508
|
// reads this same snapshot, which is where the `declined` count surfaces.
|
|
465
|
-
//
|
|
466
|
-
//
|
|
467
|
-
//
|
|
509
|
+
//
|
|
510
|
+
// `snapshot()` NOW GOES THROUGH `meter.current()`, so this path DOES pay a
|
|
511
|
+
// re-measurement when the history has moved since the last one (RV-11 -
|
|
512
|
+
// the previous sentence here claimed the opposite and was left stale by
|
|
513
|
+
// context-usage-gauge-accuracy). The cost is bounded the same way it always
|
|
514
|
+
// was: guard 4 caps declines per session at `stuckLimit`, and a re-measure
|
|
515
|
+
// on the measured branch walks one turn's worth of appended messages.
|
|
468
516
|
this.emit({ type: 'snapshot', snapshot: this.snapshot() });
|
|
469
517
|
return;
|
|
470
518
|
}
|
|
@@ -478,10 +526,23 @@ export class CompactionWiring {
|
|
|
478
526
|
};
|
|
479
527
|
if (verdict.applied) {
|
|
480
528
|
this.compactor.recordApplied(settled.tokensBefore, settled.tokensAfter);
|
|
481
|
-
// SITE 1 OF THE FOUR INVALIDATION SITES (hardening §3.2.3)
|
|
482
|
-
//
|
|
483
|
-
//
|
|
484
|
-
this
|
|
529
|
+
// SITE 1 OF THE FOUR INVALIDATION SITES (hardening §3.2.3), and THE LOAD-
|
|
530
|
+
// BEARING LINE OF THE P0-1 FIX (context-usage-gauge-accuracy I-9).
|
|
531
|
+
//
|
|
532
|
+
// ITS POSITION IS THE WHOLE ARGUMENT: it runs in this class's own
|
|
533
|
+
// synchronous code, BEFORE both `emit` calls below, so the `snapshot()`
|
|
534
|
+
// two statements down is guaranteed to see a dirty meter and re-measure -
|
|
535
|
+
// no matter which of the two agent-stream listeners the emitter reached
|
|
536
|
+
// first. Deleting it and relying on the meter's own `compaction_end`
|
|
537
|
+
// subscription instead moves correctness onto subscription ORDER, which is
|
|
538
|
+
// true in every unit test and false in production import order.
|
|
539
|
+
//
|
|
540
|
+
// THE **SHALLOW** RESET (I-8). A splice changes the history and nothing
|
|
541
|
+
// else, so `estimateOffset` - a calibration for this toolset on this model
|
|
542
|
+
// - is still valid and is the only thing keeping the post-compaction
|
|
543
|
+
// estimate honest (I-5). `onHistoryReplaced()` is the other depth and is
|
|
544
|
+
// NOT interchangeable with this one.
|
|
545
|
+
this.meter.onHistorySpliced();
|
|
485
546
|
const path = this.archive(settled, dropped);
|
|
486
547
|
if (path)
|
|
487
548
|
settled.archivePath = path;
|
|
@@ -405,6 +405,11 @@ function maskConfig(config) {
|
|
|
405
405
|
function displayOverride(key, value) {
|
|
406
406
|
if (key === 'maxTokens' && value === null)
|
|
407
407
|
return 'auto';
|
|
408
|
+
// The SECOND tri-state key, and it needs this for the same reason (§4.5):
|
|
409
|
+
// `contextWindow: null` is AUTO ("use the model table"), not "unset", and a
|
|
410
|
+
// bare `null` sends the user looking for a bug that is not there.
|
|
411
|
+
if (key === 'contextWindow' && value === null)
|
|
412
|
+
return 'auto';
|
|
408
413
|
return undefined;
|
|
409
414
|
}
|
|
410
415
|
/** Resolve a flat or one-level-dotted key against the persisted config. */
|
package/dist/config/env.js
CHANGED
|
@@ -37,7 +37,7 @@ import process from 'node:process';
|
|
|
37
37
|
import dotenv from 'dotenv';
|
|
38
38
|
import { registerSecretsFrom } from '../logging/secret-registry.js';
|
|
39
39
|
import { clampLogLevel } from '../logging/levels.js';
|
|
40
|
-
import { clampMaxTokens, clampTheme, clampThinkingLevel, isAutoToken, parseThresholdInput, } from './schema.js';
|
|
40
|
+
import { clampContextWindow, clampMaxTokens, clampTheme, clampThinkingLevel, isAutoToken, parseThresholdInput, } from './schema.js';
|
|
41
41
|
/**
|
|
42
42
|
* Load a project `.env` from the given directory into `process.env` (existing
|
|
43
43
|
* process env wins — dotenv never overrides already-set variables).
|
|
@@ -113,6 +113,20 @@ export function readEnvConfig() {
|
|
|
113
113
|
partial.maxTokens = clamped;
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
|
+
// `auto` / `0` mean AUTO (`null`); a number is clamped. Anything else is LEFT
|
|
117
|
+
// ABSENT rather than written as `null`, the rule `ARAGON_MAX_TOKENS` states one
|
|
118
|
+
// block up: a typo must not silently discard the number in the config file.
|
|
119
|
+
const contextWindow = process.env.ARAGON_CONTEXT_WINDOW?.trim();
|
|
120
|
+
if (contextWindow !== undefined && contextWindow.length > 0) {
|
|
121
|
+
if (isAutoToken(contextWindow)) {
|
|
122
|
+
partial.contextWindow = null;
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
const clamped = clampContextWindow(contextWindow, null);
|
|
126
|
+
if (clamped !== null)
|
|
127
|
+
partial.contextWindow = clamped;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
116
130
|
if (process.env.ARAGON_THEME) {
|
|
117
131
|
partial.theme = clampTheme(process.env.ARAGON_THEME.trim(), 'auto');
|
|
118
132
|
}
|
package/dist/config/load.d.ts
CHANGED
|
@@ -185,6 +185,23 @@ export interface CliFlags {
|
|
|
185
185
|
* to keep in step with `toFlags`.
|
|
186
186
|
*/
|
|
187
187
|
fastReview?: string;
|
|
188
|
+
/**
|
|
189
|
+
* `--fast-delegate` ⇒ true, `--no-fast-delegate` ⇒ false, absent ⇒ undefined
|
|
190
|
+
* (web-use-tier-cooperation-and-control-closure §4.1.5).
|
|
191
|
+
*
|
|
192
|
+
* DECLARED AS A PAIR — MANDATORY, for the reason `--team`, `--todo-panel`,
|
|
193
|
+
* `--render-governor`, `--retry` and `--fast` each record in turn, and here
|
|
194
|
+
* with the SAME polarity as `--update`: `fast.delegate` is PERSISTED and
|
|
195
|
+
* defaults to `true`, so a lone `--no-fast-delegate` would make commander
|
|
196
|
+
* default `opts.fastDelegate` to `true` and silently overwrite a stored
|
|
197
|
+
* `false` on every run that passed no flag at all.
|
|
198
|
+
*
|
|
199
|
+
* It exists because it is the ONLY `fast.*` sub-switch with no channel a
|
|
200
|
+
* wrapper can reach: `--fast-review <n|off>` already covers `review` and
|
|
201
|
+
* `reviewEveryTurns`, and `enabled` / `model` / `provider` have both a flag
|
|
202
|
+
* and an environment variable.
|
|
203
|
+
*/
|
|
204
|
+
fastDelegate?: boolean;
|
|
188
205
|
/**
|
|
189
206
|
* `--update` ⇒ true, `--no-update` ⇒ false, absent ⇒ undefined
|
|
190
207
|
* (cli-auto-update §4.2).
|
package/dist/config/load.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* legitimately long single tool run can never be watchdog-killed.
|
|
7
7
|
*/
|
|
8
8
|
import process from 'node:process';
|
|
9
|
-
import { DEFAULT_CONFIG, IDLE_TIMEOUT_MARGIN_MS, clampAskRounds, clampDensity, clampHumanTimeout, clampCompactionConfig, clampLogConfig, clampFastConfig, clampRetryConfig, clampSkillsConfig, clampTeamConfig, clampTodoConfig, clampBashConfig, clampUpdateConfig, clampTheme, clampThinkingLevel, clampMaxTokens, clampMaxRenderInterval, clampScrollResumeMs, clampTranscriptRetain, clampTranscriptWindow, coercePositiveInt, isAutoToken, isSkillsToolPolicyMode, parseThresholdInput, } from './schema.js';
|
|
9
|
+
import { DEFAULT_CONFIG, IDLE_TIMEOUT_MARGIN_MS, clampAskRounds, clampDensity, clampHumanTimeout, clampCompactionConfig, clampLogConfig, clampFastConfig, clampRetryConfig, clampSkillsConfig, clampTeamConfig, clampTodoConfig, clampBashConfig, clampUpdateConfig, clampTheme, clampThinkingLevel, clampContextWindow, clampMaxTokens, clampMaxRenderInterval, clampScrollResumeMs, clampTranscriptRetain, clampTranscriptWindow, coercePositiveInt, isAutoToken, isSkillsToolPolicyMode, parseThresholdInput, } from './schema.js';
|
|
10
10
|
import { loadDotenv, readEnvConfig, readEnvDisabledSkills } from './env.js';
|
|
11
11
|
import { readConfigFile } from './store.js';
|
|
12
12
|
import { getConfigPath } from './app-paths.js';
|
|
@@ -250,6 +250,12 @@ function resolveFastConfig(flags, env, file) {
|
|
|
250
250
|
...(flags.fastProvider !== undefined && flags.fastProvider !== ''
|
|
251
251
|
? { provider: flags.fastProvider }
|
|
252
252
|
: {}),
|
|
253
|
+
// `!== undefined`, for the reason stated on `flags.fast` above: commander
|
|
254
|
+
// materialises a lone `--no-fast-delegate` as `opts.fastDelegate = true`
|
|
255
|
+
// when the flag is absent, and `delegate` defaults to TRUE — so a truthiness
|
|
256
|
+
// check would force it on for every run that passed no flag at all,
|
|
257
|
+
// overwriting a stored `false` with nothing to show for it.
|
|
258
|
+
...(flags.fastDelegate !== undefined ? { delegate: flags.fastDelegate } : {}),
|
|
253
259
|
...reviewPatch,
|
|
254
260
|
});
|
|
255
261
|
}
|
|
@@ -410,6 +416,42 @@ function resolveMaxTokens(flags, env, file) {
|
|
|
410
416
|
}
|
|
411
417
|
return DEFAULT_CONFIG.maxTokens ?? undefined;
|
|
412
418
|
}
|
|
419
|
+
/**
|
|
420
|
+
* Resolve the context-window override: env > file > default, where an EXPLICIT
|
|
421
|
+
* `null` at either layer means AUTO (context-usage-gauge-accuracy §3.6).
|
|
422
|
+
*
|
|
423
|
+
* IT CANNOT USE `pick()` FOR THE REASON `resolveMaxTokens` GIVES: `pick` skips
|
|
424
|
+
* `null`, and `null` is exactly the value being looked for. NO CLI FLAG feeds
|
|
425
|
+
* this - it is a per-installation correction for a model table entry, not a
|
|
426
|
+
* per-invocation choice, so `config set` and the environment variable are the
|
|
427
|
+
* two surfaces the design names.
|
|
428
|
+
*/
|
|
429
|
+
function resolveContextWindow(env, file) {
|
|
430
|
+
const layers = [
|
|
431
|
+
{
|
|
432
|
+
name: 'ARAGON_CONTEXT_WINDOW',
|
|
433
|
+
value: hasOwn(env, 'contextWindow') ? env.contextWindow : undefined,
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
name: 'config.json contextWindow',
|
|
437
|
+
value: hasOwn(file, 'contextWindow') ? file.contextWindow : undefined,
|
|
438
|
+
},
|
|
439
|
+
];
|
|
440
|
+
for (const layer of layers) {
|
|
441
|
+
if (layer.value === undefined)
|
|
442
|
+
continue; // this layer said nothing
|
|
443
|
+
if (layer.value === null || isAutoToken(layer.value))
|
|
444
|
+
return null; // AUTO
|
|
445
|
+
const n = clampContextWindow(layer.value, null);
|
|
446
|
+
if (n !== null)
|
|
447
|
+
return n;
|
|
448
|
+
getLogger().warn('config', 'context_window_unusable', {
|
|
449
|
+
source: layer.name,
|
|
450
|
+
value: String(layer.value),
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
return DEFAULT_CONFIG.contextWindow;
|
|
454
|
+
}
|
|
413
455
|
/**
|
|
414
456
|
* Resolve the effective config by merging all layers, then derive the runtime
|
|
415
457
|
* (non-persisted) fields and enforce the timeout invariant.
|
|
@@ -445,6 +487,7 @@ export function loadConfig(flags = {}) {
|
|
|
445
487
|
const liveToolOutput = pick(flags.liveToolOutput, env.partial.liveToolOutput, file.liveToolOutput) ??
|
|
446
488
|
DEFAULT_CONFIG.liveToolOutput;
|
|
447
489
|
const maxTokens = resolveMaxTokens(flags, env.partial, file);
|
|
490
|
+
const contextWindow = resolveContextWindow(env.partial, file);
|
|
448
491
|
// `clampTheme` is also where the v0.3.0 `dark` name is migrated to `cool`,
|
|
449
492
|
// so reading a legacy config file needs no extra step here (§4.5 / R-4).
|
|
450
493
|
const theme = clampTheme(pick(flags.theme, env.partial.theme, file.theme), DEFAULT_CONFIG.theme);
|
|
@@ -534,6 +577,7 @@ export function loadConfig(flags = {}) {
|
|
|
534
577
|
showThinking,
|
|
535
578
|
liveToolOutput,
|
|
536
579
|
maxTokens,
|
|
580
|
+
contextWindow,
|
|
537
581
|
theme,
|
|
538
582
|
reducedMotion,
|
|
539
583
|
fullscreen: resolveFullscreen(flags, env.partial, file),
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -78,6 +78,27 @@ export declare const DEFAULT_TRANSCRIPT_WINDOW = 1000;
|
|
|
78
78
|
export declare const MIN_TRANSCRIPT_WINDOW = 50;
|
|
79
79
|
export declare const MAX_TRANSCRIPT_WINDOW = 20000;
|
|
80
80
|
export declare function clampTranscriptWindow(v: unknown, fallback: number): number;
|
|
81
|
+
/**
|
|
82
|
+
* Bounds for a hand-supplied context window.
|
|
83
|
+
*
|
|
84
|
+
* The floor is roughly the smallest window any current model ships with; the
|
|
85
|
+
* ceiling is well above the largest, and both exist to keep a typo (a missing
|
|
86
|
+
* or an extra zero) from producing a gauge that is permanently red or
|
|
87
|
+
* permanently flat.
|
|
88
|
+
*/
|
|
89
|
+
export declare const MIN_CONTEXT_WINDOW = 8000;
|
|
90
|
+
export declare const MAX_CONTEXT_WINDOW = 5000000;
|
|
91
|
+
/**
|
|
92
|
+
* THE single gate for every `contextWindow` read AND write.
|
|
93
|
+
*
|
|
94
|
+
* TRI-STATE, AND `null` MUST PASS STRAIGHT THROUGH (RV-12). `null` means AUTO -
|
|
95
|
+
* take the model table's number, or the 128k placeholder. Clamping it into
|
|
96
|
+
* `[8000, ...]` yields 8000, which removes "auto" from the config permanently
|
|
97
|
+
* and presents to the user as an 8k denominator with a permanently red bar and
|
|
98
|
+
* no visible source. `maxTokens` above is the existing tri-state precedent and
|
|
99
|
+
* this deliberately copies its shape rather than inventing a second convention.
|
|
100
|
+
*/
|
|
101
|
+
export declare function clampContextWindow(v: unknown, fallback: number | null): number | null;
|
|
81
102
|
/**
|
|
82
103
|
* Entries kept in `ViewState` at all (tui-render-performance L1 / R5).
|
|
83
104
|
*
|
|
@@ -692,6 +713,18 @@ export interface PersistedConfig {
|
|
|
692
713
|
* `null`), which left the user no way to express "let the model decide".
|
|
693
714
|
*/
|
|
694
715
|
maxTokens: number | null;
|
|
716
|
+
/**
|
|
717
|
+
* The context window to measure occupancy against, or `null` for AUTO
|
|
718
|
+
* (context-usage-gauge-accuracy §3.6).
|
|
719
|
+
*
|
|
720
|
+
* `null` MEANS AUTO - the model table's window, or `buildRuntimeModel`'s 128k
|
|
721
|
+
* placeholder for a model the table has never seen. It exists because that
|
|
722
|
+
* placeholder is a FABRICATED denominator: on a custom `baseUrl` or an
|
|
723
|
+
* unlisted model id the gauge is a percentage of a number nobody supplied, and
|
|
724
|
+
* before this key there was no way to correct it. Setting it also removes the
|
|
725
|
+
* `?` marker from the absolute pair (I-6).
|
|
726
|
+
*/
|
|
727
|
+
contextWindow: number | null;
|
|
695
728
|
theme: ThemeName;
|
|
696
729
|
/** Replace spinners with a static glyph for calmer, low-motion output. */
|
|
697
730
|
reducedMotion: boolean;
|
|
@@ -835,6 +868,17 @@ export interface CliConfig {
|
|
|
835
868
|
liveToolOutput: boolean;
|
|
836
869
|
/** The resolved cap, or `undefined` for AUTO (per-model ceiling, ≤ 64000). */
|
|
837
870
|
maxTokens?: number;
|
|
871
|
+
/**
|
|
872
|
+
* The user's context-window override, or `null` for AUTO.
|
|
873
|
+
*
|
|
874
|
+
* IT MUST EXIST HERE AND NOT ONLY IN `PersistedConfig`, for the reason
|
|
875
|
+
* `showThinking` / `liveToolOutput` / `diffRender` each record above: the
|
|
876
|
+
* runtime reads `config.*`, where `config` is a `CliConfig`, so a key added to
|
|
877
|
+
* the persisted shape alone would round-trip through `config set`, appear in
|
|
878
|
+
* `config list` - and never reach `ContextMeter`. `ARAGON_CONTEXT_WINDOW`
|
|
879
|
+
* would parse and be discarded, with nothing failing.
|
|
880
|
+
*/
|
|
881
|
+
contextWindow: number | null;
|
|
838
882
|
theme: ThemeName;
|
|
839
883
|
reducedMotion: boolean;
|
|
840
884
|
/**
|
package/dist/config/schema.js
CHANGED
|
@@ -115,6 +115,39 @@ export function clampTranscriptWindow(v, fallback) {
|
|
|
115
115
|
const n = coercePositiveInt(v, fallback);
|
|
116
116
|
return Math.min(MAX_TRANSCRIPT_WINDOW, Math.max(MIN_TRANSCRIPT_WINDOW, n));
|
|
117
117
|
}
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
// Context window override (context-usage-gauge-accuracy §3.6 / W5)
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
/**
|
|
122
|
+
* Bounds for a hand-supplied context window.
|
|
123
|
+
*
|
|
124
|
+
* The floor is roughly the smallest window any current model ships with; the
|
|
125
|
+
* ceiling is well above the largest, and both exist to keep a typo (a missing
|
|
126
|
+
* or an extra zero) from producing a gauge that is permanently red or
|
|
127
|
+
* permanently flat.
|
|
128
|
+
*/
|
|
129
|
+
export const MIN_CONTEXT_WINDOW = 8_000;
|
|
130
|
+
export const MAX_CONTEXT_WINDOW = 5_000_000;
|
|
131
|
+
/**
|
|
132
|
+
* THE single gate for every `contextWindow` read AND write.
|
|
133
|
+
*
|
|
134
|
+
* TRI-STATE, AND `null` MUST PASS STRAIGHT THROUGH (RV-12). `null` means AUTO -
|
|
135
|
+
* take the model table's number, or the 128k placeholder. Clamping it into
|
|
136
|
+
* `[8000, ...]` yields 8000, which removes "auto" from the config permanently
|
|
137
|
+
* and presents to the user as an 8k denominator with a permanently red bar and
|
|
138
|
+
* no visible source. `maxTokens` above is the existing tri-state precedent and
|
|
139
|
+
* this deliberately copies its shape rather than inventing a second convention.
|
|
140
|
+
*/
|
|
141
|
+
export function clampContextWindow(v, fallback) {
|
|
142
|
+
if (v === null)
|
|
143
|
+
return null;
|
|
144
|
+
if (v === undefined || v === '')
|
|
145
|
+
return fallback;
|
|
146
|
+
const n = typeof v === 'number' ? v : Number.parseInt(String(v), 10);
|
|
147
|
+
if (!Number.isFinite(n) || n <= 0)
|
|
148
|
+
return fallback;
|
|
149
|
+
return Math.min(MAX_CONTEXT_WINDOW, Math.max(MIN_CONTEXT_WINDOW, Math.floor(n)));
|
|
150
|
+
}
|
|
118
151
|
/**
|
|
119
152
|
* Entries kept in `ViewState` at all (tui-render-performance L1 / R5).
|
|
120
153
|
*
|
|
@@ -841,6 +874,9 @@ export const DEFAULT_CONFIG = {
|
|
|
841
874
|
// The engine owns this number; spelling it here again is how the CLI and the
|
|
842
875
|
// provider adapters end up disagreeing about what "the default" is.
|
|
843
876
|
maxTokens: DEFAULT_MAX_OUTPUT_TOKENS,
|
|
877
|
+
// AUTO. The model table is right for every listed model, and a default number
|
|
878
|
+
// here would be the same fabricated denominator this key exists to correct.
|
|
879
|
+
contextWindow: null,
|
|
844
880
|
theme: 'auto',
|
|
845
881
|
reducedMotion: false,
|
|
846
882
|
fullscreen: true,
|