@aragon-agent/cli 0.5.8 → 0.5.10
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 +1157 -747
- package/README.md +1552 -1163
- package/dist/agent/coalesce.d.ts +13 -0
- package/dist/agent/coalesce.js +50 -11
- package/dist/agent/controller.d.ts +141 -2
- package/dist/agent/controller.js +396 -4
- package/dist/agent/headless.d.ts +8 -0
- package/dist/agent/headless.js +40 -0
- package/dist/agent/reducer.d.ts +245 -3
- package/dist/agent/reducer.js +490 -17
- package/dist/agent/retry-view.d.ts +68 -0
- package/dist/agent/retry-view.js +95 -0
- package/dist/agent/system-prompt.d.ts +11 -0
- package/dist/agent/system-prompt.js +2 -0
- package/dist/boot/guard.d.ts +135 -0
- package/dist/boot/guard.js +218 -0
- package/dist/boot/rollback.d.ts +86 -0
- package/dist/boot/rollback.js +185 -0
- package/dist/cli.js +368 -3
- package/dist/commands/builtins.d.ts +1 -1
- package/dist/commands/builtins.js +426 -2
- package/dist/commands/registry.d.ts +17 -0
- package/dist/config/app-paths.d.ts +31 -0
- package/dist/config/app-paths.js +37 -0
- package/dist/config/cli-commands.d.ts +79 -2
- package/dist/config/cli-commands.js +185 -3
- package/dist/config/env.d.ts +15 -3
- package/dist/config/env.js +143 -3
- package/dist/config/load.d.ts +66 -0
- package/dist/config/load.js +107 -1
- package/dist/config/schema.d.ts +268 -2
- package/dist/config/schema.js +288 -1
- package/dist/config/store.js +32 -1
- package/dist/fast/critique.d.ts +43 -0
- package/dist/fast/critique.js +62 -0
- package/dist/fast/digest.d.ts +42 -0
- package/dist/fast/digest.js +85 -0
- package/dist/fast/frames.d.ts +99 -0
- package/dist/fast/frames.js +180 -0
- package/dist/fast/limits.d.ts +98 -0
- package/dist/fast/limits.js +98 -0
- package/dist/fast/prompt.d.ts +72 -0
- package/dist/fast/prompt.js +94 -0
- package/dist/fast/resolve.d.ts +43 -0
- package/dist/fast/resolve.js +105 -0
- package/dist/fast/review-call.d.ts +99 -0
- package/dist/fast/review-call.js +130 -0
- package/dist/fast/reviewer.d.ts +248 -0
- package/dist/fast/reviewer.js +664 -0
- package/dist/fast/types.d.ts +128 -0
- package/dist/fast/types.js +14 -0
- package/dist/fast/wiring.d.ts +170 -0
- package/dist/fast/wiring.js +316 -0
- package/dist/launcher.d.ts +14 -0
- package/dist/launcher.js +43 -0
- package/dist/logging/install.d.ts +15 -1
- package/dist/logging/install.js +37 -4
- package/dist/logging/logger.d.ts +1 -1
- package/dist/session/persist.js +57 -1
- package/dist/team/normalize.d.ts +26 -1
- package/dist/team/normalize.js +23 -3
- package/dist/team/prompt.d.ts +11 -0
- package/dist/team/prompt.js +10 -0
- package/dist/team/report.d.ts +18 -0
- package/dist/team/report.js +27 -1
- package/dist/team/runtime.d.ts +13 -2
- package/dist/team/runtime.js +33 -6
- package/dist/team/subagent.d.ts +19 -1
- package/dist/team/subagent.js +72 -10
- package/dist/team/task-tool.d.ts +26 -0
- package/dist/team/task-tool.js +48 -4
- package/dist/team/types.d.ts +80 -1
- package/dist/tools/bash-tool.js +19 -3
- package/dist/tools/diff.d.ts +25 -5
- package/dist/tools/diff.js +72 -41
- package/dist/tools/file-change-store.d.ts +34 -0
- package/dist/tools/file-change-store.js +57 -0
- package/dist/tools/fs-tools.d.ts +26 -0
- package/dist/tools/fs-tools.js +62 -5
- package/dist/tools/index.d.ts +31 -0
- package/dist/tools/index.js +7 -1
- package/dist/tools/patch.d.ts +115 -0
- package/dist/tools/patch.js +453 -0
- package/dist/tools/terminal-output.d.ts +107 -0
- package/dist/tools/terminal-output.js +198 -0
- package/dist/tools/tool-output-store.d.ts +68 -0
- package/dist/tools/tool-output-store.js +102 -0
- package/dist/ui/ActivityLine.d.ts +48 -0
- package/dist/ui/ActivityLine.js +22 -0
- package/dist/ui/App.d.ts +11 -4
- package/dist/ui/App.js +359 -37
- package/dist/ui/BottomStatusRow.d.ts +65 -0
- package/dist/ui/BottomStatusRow.js +17 -0
- package/dist/ui/Composer.d.ts +1 -6
- package/dist/ui/Composer.js +2 -2
- package/dist/ui/PromptInput.d.ts +1 -15
- package/dist/ui/PromptInput.js +1 -38
- package/dist/ui/StatusBar.d.ts +37 -0
- package/dist/ui/StatusBar.js +5 -3
- package/dist/ui/TeamPanel.d.ts +5 -4
- package/dist/ui/TeamPanel.js +1 -1
- package/dist/ui/TodoPanel.d.ts +5 -4
- package/dist/ui/Transcript.d.ts +26 -3
- package/dist/ui/Transcript.js +76 -10
- package/dist/ui/UpdateLine.d.ts +44 -0
- package/dist/ui/UpdateLine.js +129 -0
- package/dist/ui/activity-phrases.d.ts +33 -0
- package/dist/ui/activity-phrases.js +50 -0
- package/dist/ui/entries/AssistantEntry.d.ts +20 -0
- package/dist/ui/entries/AssistantEntry.js +3 -2
- package/dist/ui/entries/DiffView.d.ts +67 -0
- package/dist/ui/entries/DiffView.js +103 -0
- package/dist/ui/entries/FastCard.d.ts +53 -0
- package/dist/ui/entries/FastCard.js +87 -0
- package/dist/ui/entries/RetryCard.d.ts +56 -0
- package/dist/ui/entries/RetryCard.js +60 -0
- package/dist/ui/entries/TeamCard.js +6 -1
- package/dist/ui/entries/ToolCard.d.ts +38 -1
- package/dist/ui/entries/ToolCard.js +68 -5
- package/dist/ui/glyphs.d.ts +9 -0
- package/dist/ui/glyphs.js +2 -0
- package/dist/ui/layout/AppShell.d.ts +13 -22
- package/dist/ui/layout/AppShell.js +3 -38
- package/dist/ui/layout/virtual-window.d.ts +1 -1
- package/dist/ui/layout/virtual-window.js +109 -5
- package/dist/ui/overlays/HelpOverlay.js +16 -2
- package/dist/ui/overlays/SettingsScreen.d.ts +82 -1
- package/dist/ui/overlays/SettingsScreen.js +147 -1
- package/dist/ui/transcript-text.js +27 -0
- package/dist/ui/use-wheel-routing.d.ts +16 -32
- package/dist/ui/use-wheel-routing.js +21 -38
- package/dist/update/classify-failure.d.ts +32 -0
- package/dist/update/classify-failure.js +60 -0
- package/dist/update/install-lock.d.ts +55 -0
- package/dist/update/install-lock.js +184 -0
- package/dist/update/install-source.d.ts +97 -0
- package/dist/update/install-source.js +218 -0
- package/dist/update/installer.d.ts +108 -0
- package/dist/update/installer.js +242 -0
- package/dist/update/limits.d.ts +111 -0
- package/dist/update/limits.js +111 -0
- package/dist/update/npm-view.d.ts +62 -0
- package/dist/update/npm-view.js +133 -0
- package/dist/update/registry.d.ts +52 -0
- package/dist/update/registry.js +161 -0
- package/dist/update/semver.d.ts +89 -0
- package/dist/update/semver.js +295 -0
- package/dist/update/service.d.ts +193 -0
- package/dist/update/service.js +636 -0
- package/dist/update/state.d.ts +103 -0
- package/dist/update/state.js +142 -0
- package/dist/update/types.d.ts +169 -0
- package/dist/update/types.js +68 -0
- package/package.json +3 -3
- package/dist/ui/layout/regions.d.ts +0 -55
- package/dist/ui/layout/regions.js +0 -52
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, clampLogConfig, clampSkillsConfig, clampTeamConfig, clampTodoConfig, clampTheme, clampThinkingLevel, clampMaxTokens, clampMaxRenderInterval, clampTranscriptRetain, clampTranscriptWindow, coercePositiveInt, isAutoToken, isSkillsToolPolicyMode, } from './schema.js';
|
|
9
|
+
import { DEFAULT_CONFIG, IDLE_TIMEOUT_MARGIN_MS, clampAskRounds, clampDensity, clampHumanTimeout, clampLogConfig, clampFastConfig, clampRetryConfig, clampSkillsConfig, clampTeamConfig, clampTodoConfig, clampUpdateConfig, clampTheme, clampThinkingLevel, clampMaxTokens, clampMaxRenderInterval, clampTranscriptRetain, clampTranscriptWindow, coercePositiveInt, isAutoToken, isSkillsToolPolicyMode, } 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';
|
|
@@ -121,6 +121,93 @@ function resolveTodoConfig(flags, env, file) {
|
|
|
121
121
|
...(flags.todoFollow !== undefined ? { followThrough: flags.todoFollow } : {}),
|
|
122
122
|
});
|
|
123
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Merge the `retry` section across all four layers (defaults › file › env ›
|
|
126
|
+
* flags), llm-api-retry-backoff §6.2.
|
|
127
|
+
*
|
|
128
|
+
* `!== undefined` ON BOTH FLAGS, and that is the whole point — the rule
|
|
129
|
+
* `resolveTeamConfig` and `resolveTodoConfig` each state once. Commander
|
|
130
|
+
* materialises a lone `--no-retry` as `opts.retry = true` when the flag is
|
|
131
|
+
* ABSENT, so a truthiness check cannot tell `--no-retry` from "not passed"; and
|
|
132
|
+
* `flags.retryMax` may legitimately be `0`, which a truthiness check would drop
|
|
133
|
+
* on the floor and replace with the default 10 (R-16).
|
|
134
|
+
*/
|
|
135
|
+
function resolveRetryConfig(flags, env, file) {
|
|
136
|
+
return clampRetryConfig({
|
|
137
|
+
...DEFAULT_CONFIG.retry,
|
|
138
|
+
...(file.retry ?? {}),
|
|
139
|
+
...(env.retry ?? {}),
|
|
140
|
+
...(flags.retry !== undefined ? { enabled: flags.retry } : {}),
|
|
141
|
+
...(flags.retryMax !== undefined && flags.retryMax !== ''
|
|
142
|
+
? { maxRetries: flags.retryMax }
|
|
143
|
+
: {}),
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Merge the `fast` section across all four layers (defaults › file › env ›
|
|
148
|
+
* flags), fast-model-tier §3.7.
|
|
149
|
+
*
|
|
150
|
+
* `!== undefined` ON `flags.fast`, which is the rule `resolveTeamConfig`,
|
|
151
|
+
* `resolveTodoConfig` and `resolveRetryConfig` each state once (C-9): commander
|
|
152
|
+
* materialises a lone `--no-fast` as `opts.fast = true` when the flag is absent,
|
|
153
|
+
* so a truthiness check cannot tell `--no-fast` from "not passed" — and here the
|
|
154
|
+
* damage would run the other way from usual, silently turning a default-OFF
|
|
155
|
+
* feature ON for every run that passed no flag at all.
|
|
156
|
+
*
|
|
157
|
+
* `--fast-review` maps onto TWO keys, so it is parsed rather than spread: `off`
|
|
158
|
+
* is `review: false`, a number is `reviewEveryTurns`, and anything else is
|
|
159
|
+
* ignored (the clamp discipline every other key in this file follows).
|
|
160
|
+
*/
|
|
161
|
+
function resolveFastConfig(flags, env, file) {
|
|
162
|
+
const reviewFlag = flags.fastReview?.trim().toLowerCase();
|
|
163
|
+
const reviewPatch = {};
|
|
164
|
+
if (reviewFlag !== undefined && reviewFlag.length > 0) {
|
|
165
|
+
if (reviewFlag === 'off') {
|
|
166
|
+
reviewPatch.review = false;
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
const n = Number.parseInt(reviewFlag, 10);
|
|
170
|
+
if (Number.isFinite(n) && n > 0)
|
|
171
|
+
reviewPatch.reviewEveryTurns = n;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return clampFastConfig({
|
|
175
|
+
...DEFAULT_CONFIG.fast,
|
|
176
|
+
...(file.fast ?? {}),
|
|
177
|
+
...(env.fast ?? {}),
|
|
178
|
+
...(flags.fast !== undefined ? { enabled: flags.fast } : {}),
|
|
179
|
+
...(flags.fastModel !== undefined && flags.fastModel !== ''
|
|
180
|
+
? { model: flags.fastModel }
|
|
181
|
+
: {}),
|
|
182
|
+
...(flags.fastProvider !== undefined && flags.fastProvider !== ''
|
|
183
|
+
? { provider: flags.fastProvider }
|
|
184
|
+
: {}),
|
|
185
|
+
...reviewPatch,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Merge the `update` section across all four layers (defaults › file › env ›
|
|
190
|
+
* flags), cli-auto-update §4.2.
|
|
191
|
+
*
|
|
192
|
+
* `!== undefined` ON `flags.update`, which is the rule `resolveTeamConfig`,
|
|
193
|
+
* `resolveTodoConfig`, `resolveRetryConfig` and `resolveFastConfig` each state
|
|
194
|
+
* once (C-11): commander materialises a lone `--no-update` as
|
|
195
|
+
* `opts.update = true` when the flag is absent, so a truthiness check cannot
|
|
196
|
+
* tell `--no-update` from "not passed" — and here that would silently re-enable
|
|
197
|
+
* a subsystem the user turned off, which is the one direction this feature must
|
|
198
|
+
* never fail in.
|
|
199
|
+
*
|
|
200
|
+
* The flag maps onto `mode` rather than carrying its own key, so there is
|
|
201
|
+
* exactly one place that says whether the updater runs.
|
|
202
|
+
*/
|
|
203
|
+
function resolveUpdateConfig(flags, env, file) {
|
|
204
|
+
return clampUpdateConfig({
|
|
205
|
+
...DEFAULT_CONFIG.update,
|
|
206
|
+
...(file.update ?? {}),
|
|
207
|
+
...(env.update ?? {}),
|
|
208
|
+
...(flags.update !== undefined ? { mode: flags.update ? 'auto' : 'off' } : {}),
|
|
209
|
+
});
|
|
210
|
+
}
|
|
124
211
|
/**
|
|
125
212
|
* Resolve the adaptive render governor: flag › env › file › default `true`
|
|
126
213
|
* (tui-render-performance L4).
|
|
@@ -223,6 +310,16 @@ export function loadConfig(flags = {}) {
|
|
|
223
310
|
const model = pick(flags.model, env.partial.model, file.model) ?? DEFAULT_CONFIG.model;
|
|
224
311
|
const baseUrl = pick(flags.baseUrl, env.partial.baseUrl ?? undefined, file.baseUrl ?? undefined);
|
|
225
312
|
const thinkingLevel = clampThinkingLevel(pick(flags.thinking, env.partial.thinkingLevel, file.thinkingLevel), DEFAULT_CONFIG.thinkingLevel);
|
|
313
|
+
// BESIDE ITS SIBLING, and through the same three layers (§4.1 / P1-2). This is
|
|
314
|
+
// the ONLY place flags, environment and file are joined, so a key resolved
|
|
315
|
+
// anywhere else reaches the UI from at most one of them.
|
|
316
|
+
const showThinking = pick(flags.showThinking, env.partial.showThinking, file.showThinking) ??
|
|
317
|
+
DEFAULT_CONFIG.showThinking;
|
|
318
|
+
// THE SAME THREE LAYERS, in the same one place (§4.1). Round 1's P1-2 and the
|
|
319
|
+
// fast tier's round-2 IF both record the identical failure: a key resolved
|
|
320
|
+
// anywhere else reaches the UI from at most one of flags, environment and file.
|
|
321
|
+
const liveToolOutput = pick(flags.liveToolOutput, env.partial.liveToolOutput, file.liveToolOutput) ??
|
|
322
|
+
DEFAULT_CONFIG.liveToolOutput;
|
|
226
323
|
const maxTokens = resolveMaxTokens(flags, env.partial, file);
|
|
227
324
|
// `clampTheme` is also where the v0.3.0 `dark` name is migrated to `cool`,
|
|
228
325
|
// so reading a legacy config file needs no extra step here (§4.5 / R-4).
|
|
@@ -310,6 +407,8 @@ export function loadConfig(flags = {}) {
|
|
|
310
407
|
model,
|
|
311
408
|
baseUrl,
|
|
312
409
|
thinkingLevel,
|
|
410
|
+
showThinking,
|
|
411
|
+
liveToolOutput,
|
|
313
412
|
maxTokens,
|
|
314
413
|
theme,
|
|
315
414
|
reducedMotion,
|
|
@@ -350,6 +449,9 @@ export function loadConfig(flags = {}) {
|
|
|
350
449
|
log: resolveLogConfig(flags, env.partial, file),
|
|
351
450
|
team: resolveTeamConfig(flags, env.partial, file),
|
|
352
451
|
todo: resolveTodoConfig(flags, env.partial, file),
|
|
452
|
+
retry: resolveRetryConfig(flags, env.partial, file),
|
|
453
|
+
fast: resolveFastConfig(flags, env.partial, file),
|
|
454
|
+
update: resolveUpdateConfig(flags, env.partial, file),
|
|
353
455
|
cwd,
|
|
354
456
|
color,
|
|
355
457
|
colorLevel,
|
|
@@ -386,6 +488,10 @@ function recordResolvedConfig(config) {
|
|
|
386
488
|
idleTimeoutMs: config.idleTimeoutMs,
|
|
387
489
|
historyEnabled: config.historyEnabled,
|
|
388
490
|
logLevel: config.log.level,
|
|
491
|
+
// Four layers feed this one too, and none of them would otherwise leave a
|
|
492
|
+
// trace — so "why did my failing call sit there for three minutes" (or
|
|
493
|
+
// "why did it not retry at all") has an answer after the fact.
|
|
494
|
+
retry: config.retry.enabled ? config.retry.maxRetries : 'off',
|
|
389
495
|
hasApiKey: Boolean(config.apiKeys[config.provider]),
|
|
390
496
|
configPath: getConfigPath(),
|
|
391
497
|
});
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* See spec §3.5 (resolution pipeline), §6.1 (config file), and §3.8 (timeout
|
|
6
6
|
* invariant).
|
|
7
7
|
*/
|
|
8
|
-
import { type ThinkingLevel } from '@aragon-agent/core';
|
|
8
|
+
import { type RetryPolicy, type ThinkingLevel } from '@aragon-agent/core';
|
|
9
9
|
import { type LogLevelName } from '../logging/levels.js';
|
|
10
10
|
import type { FollowThroughMode } from '../todo/types.js';
|
|
11
11
|
/**
|
|
@@ -299,12 +299,209 @@ export declare const DEFAULT_TODO_CONFIG: TodoConfig;
|
|
|
299
299
|
* setting won't stick".
|
|
300
300
|
*/
|
|
301
301
|
export declare function clampTodoConfig(raw: unknown): TodoConfig;
|
|
302
|
+
export interface RetryConfig {
|
|
303
|
+
/**
|
|
304
|
+
* The user's switch. KEPT SEPARATE FROM `maxRetries: 0` on purpose: `enabled`
|
|
305
|
+
* survives round-tripping through the settings screen, while `maxRetries: 0` is
|
|
306
|
+
* what `toRetryPolicy` produces from it. Folding them would make
|
|
307
|
+
* `/retry off; /retry on` forget the user's chosen count.
|
|
308
|
+
*/
|
|
309
|
+
enabled: boolean;
|
|
310
|
+
/** Retries AFTER the initial attempt. `0` is the kill switch, not a typo. */
|
|
311
|
+
maxRetries: number;
|
|
312
|
+
initialDelayMs: number;
|
|
313
|
+
maxDelayMs: number;
|
|
314
|
+
/** Growth factor. THE ONLY FLOAT KEY in this section. */
|
|
315
|
+
multiplier: number;
|
|
316
|
+
jitter: boolean;
|
|
317
|
+
respectRetryAfter: boolean;
|
|
318
|
+
/** Wall-clock budget from the first failure of one request. */
|
|
319
|
+
maxElapsedMs: number;
|
|
320
|
+
/** Allow a restart after content has already streamed to the transcript. */
|
|
321
|
+
onPartialStream: boolean;
|
|
322
|
+
}
|
|
323
|
+
export declare const DEFAULT_RETRY_CONFIG: RetryConfig;
|
|
324
|
+
/**
|
|
325
|
+
* `hardMaxRetries` re-exported rather than re-spelled, for the reason
|
|
326
|
+
* `HARD_MAX_SUBAGENTS` records: the ceiling is enforced in TWO places — here on
|
|
327
|
+
* the config value, and again by `normalizePolicy` inside the engine — and two
|
|
328
|
+
* copies of the same 20 is exactly how a hand-edited `config.json` ends up able
|
|
329
|
+
* to raise a ceiling the mechanism fixed.
|
|
330
|
+
*/
|
|
331
|
+
export declare const HARD_MAX_RETRIES: 20;
|
|
332
|
+
/**
|
|
333
|
+
* THE single gate for every retry-config read AND write, mirroring
|
|
334
|
+
* `clampSkillsConfig` / `clampLogConfig` / `clampTeamConfig` / `clampTodoConfig`
|
|
335
|
+
* for the reason those record: hardening only the read path leaves a bad value on
|
|
336
|
+
* disk that reverts to the default on every launch, which presents to the user as
|
|
337
|
+
* "my setting won't stick".
|
|
338
|
+
*
|
|
339
|
+
* Three invariants live inside the gate:
|
|
340
|
+
*
|
|
341
|
+
* - `maxDelayMs = max(maxDelayMs, initialDelayMs)` — a ceiling under the floor
|
|
342
|
+
* makes the ladder a flat line and the countdown a lie.
|
|
343
|
+
* - `multiplier` goes through `clampNumber`, not `clampInt`: `2.5` is a
|
|
344
|
+
* legitimate factor and `coercePositiveInt` would floor it to 2.
|
|
345
|
+
* - `maxRetries` goes through `clampIntAllowingZero`. THIS IS THE ONE THAT SHIPS
|
|
346
|
+
* BROKEN WITHOUT IT (R-16): `clampInt` returns the fallback for `n <= 0`, so
|
|
347
|
+
* `clampRetryConfig({ maxRetries: 0 })` would yield 10 — the maximum instead
|
|
348
|
+
* of the minimum, silently, for the key that gates the whole feature.
|
|
349
|
+
*
|
|
350
|
+
* `maxElapsedMs` intentionally keeps plain `clampInt`: its floor is 10 000, so it
|
|
351
|
+
* has no `0` to express.
|
|
352
|
+
*/
|
|
353
|
+
export declare function clampRetryConfig(raw: unknown): RetryConfig;
|
|
354
|
+
/**
|
|
355
|
+
* `RetryConfig` (user intent) -> `RetryPolicy` (engine policy), or `null` for
|
|
356
|
+
* "the user said no".
|
|
357
|
+
*
|
|
358
|
+
* `null` rather than a policy with `maxRetries: 0` because `ProviderRegistry`
|
|
359
|
+
* short-circuits on a null policy and returns the adapter's iterator DIRECTLY —
|
|
360
|
+
* an opted-out session is then allocation-identical to a pre-feature build.
|
|
361
|
+
*
|
|
362
|
+
* TOTAL, AND IT ACCEPTS A MISSING SECTION. `loadConfig` always supplies one, but
|
|
363
|
+
* a `CliConfig` built by hand — every controller test in this package does exactly
|
|
364
|
+
* that, and so would an embedder — legitimately omits it, and a `TypeError` from a
|
|
365
|
+
* pure translation function is the wrong way to find out. Routing through
|
|
366
|
+
* `clampRetryConfig` also means an out-of-range hand-built value can never reach
|
|
367
|
+
* the engine, which is the same "one gate, both directions" rule every other
|
|
368
|
+
* section in this file follows.
|
|
369
|
+
*/
|
|
370
|
+
export declare function toRetryPolicy(cfg: RetryConfig | undefined): RetryPolicy | null;
|
|
371
|
+
export interface FastConfig {
|
|
372
|
+
/**
|
|
373
|
+
* Resolve the tier at all. Defaults to FALSE (R-d).
|
|
374
|
+
*
|
|
375
|
+
* OFF IS BYTE-IDENTICAL (I-2): with this false the system prompt, `task`'s
|
|
376
|
+
* schema, the tool array, the transcript, the status bar and the request
|
|
377
|
+
* payloads are exactly what a pre-feature build produces.
|
|
378
|
+
*/
|
|
379
|
+
enabled: boolean;
|
|
380
|
+
/** `''` INHERITS the main provider — what makes `fast.model` alone a complete
|
|
381
|
+
* configuration for the common "same vendor, cheaper model" case. */
|
|
382
|
+
provider: string;
|
|
383
|
+
/** The fast model id. Empty means NOT CONFIGURED, never "same as main": that
|
|
384
|
+
* distinction is what keeps R-e (opt in to fast == main) from being
|
|
385
|
+
* indistinguishable from a typo (D-4). */
|
|
386
|
+
model: string;
|
|
387
|
+
/** `''` inherits only when the provider matches — a base URL belongs to one
|
|
388
|
+
* API, so a fast tier on a different vendor must not borrow it. */
|
|
389
|
+
baseUrl: string;
|
|
390
|
+
/** Applied to fast-tier children and to the review call. Defaults to `'off'`:
|
|
391
|
+
* a "fast" model asked to think for 32 768 tokens is not fast (D-13). */
|
|
392
|
+
thinkingLevel: ThinkingLevel;
|
|
393
|
+
/** Allow `model: "fast"` on `task`. */
|
|
394
|
+
delegate: boolean;
|
|
395
|
+
/** Run the periodic asynchronous review. */
|
|
396
|
+
review: boolean;
|
|
397
|
+
/** Completed turns between reviews. */
|
|
398
|
+
reviewEveryTurns: number;
|
|
399
|
+
/** Turn frames included in one digest. */
|
|
400
|
+
reviewContextTurns: number;
|
|
401
|
+
/** Ceiling on an injected critique, in characters. */
|
|
402
|
+
reviewMaxChars: number;
|
|
403
|
+
/**
|
|
404
|
+
* Reviews STARTED per session, across all runs (fast-model-tier-hardening
|
|
405
|
+
* §4.1 / W1).
|
|
406
|
+
*
|
|
407
|
+
* The one bound on spend the user never asked for. `reviewEveryTurns`
|
|
408
|
+
* controls the PACE; this controls the TOTAL — and the two are different
|
|
409
|
+
* questions, because a session is not one run. `reviewsThisRun` is reset by
|
|
410
|
+
* every user message, so thirty messages buys thirty runs' worth of reviews
|
|
411
|
+
* with nothing counting across them.
|
|
412
|
+
*
|
|
413
|
+
* DENOMINATED IN REVIEWS, NOT CURRENCY (D-H1). The fast tier is by
|
|
414
|
+
* construction the likeliest place in the product to name a model the static
|
|
415
|
+
* cost table has never seen, and `buildRuntimeModel` prices exactly those at
|
|
416
|
+
* zero (C-11) — so a dollar budget would silently never trigger for the
|
|
417
|
+
* configuration that most needs it. A count is exact for every model, and
|
|
418
|
+
* because per-review cost is already bounded on both sides (a 4 000-char
|
|
419
|
+
* digest in, 512 tokens out), `count x bound` is an honest ceiling.
|
|
420
|
+
*/
|
|
421
|
+
reviewMaxPerSession: number;
|
|
422
|
+
}
|
|
423
|
+
export declare const DEFAULT_FAST_CONFIG: FastConfig;
|
|
424
|
+
/**
|
|
425
|
+
* THE single gate for every fast-config read AND write, mirroring
|
|
426
|
+
* `clampSkillsConfig` / `clampLogConfig` / `clampTeamConfig` / `clampTodoConfig`
|
|
427
|
+
* for the reason those four record: hardening only the read path leaves a bad
|
|
428
|
+
* value on disk that reverts to the default on every launch, which presents to
|
|
429
|
+
* the user as "my setting won't stick".
|
|
430
|
+
*
|
|
431
|
+
* `provider` is CLAMPED TO `''` rather than rejected when it names something
|
|
432
|
+
* with no adapter. `''` means "inherit the main provider", which is the safe
|
|
433
|
+
* reading of a typo — and `resolveFastTier` reports `no_adapter` for the case a
|
|
434
|
+
* user really did configure a dead vendor as the MAIN one.
|
|
435
|
+
*/
|
|
436
|
+
export declare function clampFastConfig(raw: unknown): FastConfig;
|
|
437
|
+
/** `auto` installs; `notify` only reports; `off` disables the subsystem. */
|
|
438
|
+
export declare const UPDATE_MODES: readonly ["auto", "notify", "off"];
|
|
439
|
+
export type UpdateMode = (typeof UPDATE_MODES)[number];
|
|
440
|
+
export declare function isUpdateMode(v: unknown): v is UpdateMode;
|
|
441
|
+
export interface UpdateConfig {
|
|
442
|
+
/**
|
|
443
|
+
* Whether the updater installs, merely reports, or does nothing at all.
|
|
444
|
+
*
|
|
445
|
+
* DEFAULTS TO `'auto'`, and that is a PRODUCT decision rather than a technical
|
|
446
|
+
* one: this CLI's users are overwhelmingly on a stale version they did not
|
|
447
|
+
* choose. The trade it makes — a wider supply-chain window in exchange for
|
|
448
|
+
* users who are actually on the current release — is stated plainly in the
|
|
449
|
+
* README (R-1), and `'off'` plus `ARAGON_UPDATE=0` are the documented kill
|
|
450
|
+
* switches.
|
|
451
|
+
*/
|
|
452
|
+
mode: UpdateMode;
|
|
453
|
+
/** Minimum wall-clock between registry checks, MACHINE-WIDE (§3.7). */
|
|
454
|
+
checkIntervalMs: number;
|
|
455
|
+
/** `''` = derive: `ARAGON_UPDATE_REGISTRY` › `npm_config_registry` › npmjs. */
|
|
456
|
+
registry: string;
|
|
457
|
+
/** The dist-tag to track. */
|
|
458
|
+
distTag: string;
|
|
459
|
+
}
|
|
460
|
+
export declare const DEFAULT_UPDATE_CONFIG: UpdateConfig;
|
|
461
|
+
/**
|
|
462
|
+
* THE single gate for every update-config read AND write, mirroring
|
|
463
|
+
* `clampSkillsConfig` / `clampLogConfig` / `clampTeamConfig` / `clampTodoConfig`
|
|
464
|
+
* / `clampRetryConfig` / `clampFastConfig` for the reason all six record:
|
|
465
|
+
* hardening only the read path leaves a bad value on disk that reverts to the
|
|
466
|
+
* default on every launch, which presents to the user as "my setting won't
|
|
467
|
+
* stick".
|
|
468
|
+
*
|
|
469
|
+
* `registry` is CLAMPED TO `''` rather than rejected when it is not an
|
|
470
|
+
* `http(s):` URL. `''` means "derive it" (§3.3), which is the safe reading of a
|
|
471
|
+
* typo — the alternative is a background timer that throws on a value the user
|
|
472
|
+
* cannot see it reading.
|
|
473
|
+
*/
|
|
474
|
+
export declare function clampUpdateConfig(raw: unknown): UpdateConfig;
|
|
302
475
|
export interface PersistedConfig {
|
|
303
476
|
version: number;
|
|
304
477
|
provider: string;
|
|
305
478
|
model: string;
|
|
306
479
|
baseUrl: string | null;
|
|
307
480
|
thinkingLevel: ThinkingLevel;
|
|
481
|
+
/**
|
|
482
|
+
* Whether the terminal DRAWS the reasoning that came back
|
|
483
|
+
* (agent-activity-presentation §4.1).
|
|
484
|
+
*
|
|
485
|
+
* ADJACENT TO `thinkingLevel` AND DELIBERATELY NAMED DIFFERENTLY: that key is
|
|
486
|
+
* the effort the provider is asked to SPEND, this one is whether the transcript
|
|
487
|
+
* shows it. They are one word apart in the config file and must never be
|
|
488
|
+
* confused, which is why the flag is `--show-thinking` rather than the shorter
|
|
489
|
+
* `--thinking` the existing key already resembles.
|
|
490
|
+
*/
|
|
491
|
+
showThinking: boolean;
|
|
492
|
+
/**
|
|
493
|
+
* Whether a RUNNING tool card draws a bounded tail of its live output
|
|
494
|
+
* (agent-activity-presentation-live §4.1).
|
|
495
|
+
*
|
|
496
|
+
* DEFAULT `true`, unlike `showThinking` next door (D-28). That key hides
|
|
497
|
+
* information by default because reasoning is noise most of the time; this one
|
|
498
|
+
* ADDS the information the requirement asks for, and its cost is bounded by
|
|
499
|
+
* construction -- eight rows per call, sixteen calls, whatever the command
|
|
500
|
+
* emits. It exists as a KILL SWITCH, not as an opt-in: "a build's output
|
|
501
|
+
* redraws the transcript" is exactly the kind of change a user on a slow SSH
|
|
502
|
+
* link may want off.
|
|
503
|
+
*/
|
|
504
|
+
liveToolOutput: boolean;
|
|
308
505
|
/**
|
|
309
506
|
* Output token cap.
|
|
310
507
|
*
|
|
@@ -353,7 +550,8 @@ export interface PersistedConfig {
|
|
|
353
550
|
hints: boolean;
|
|
354
551
|
/**
|
|
355
552
|
* Enable SGR mouse reporting in full-screen mode so the wheel scrolls the
|
|
356
|
-
*
|
|
553
|
+
* transcript, whatever row the pointer is on (wheel-scrolls-transcript-only
|
|
554
|
+
* §4.1).
|
|
357
555
|
*
|
|
358
556
|
* A PLAIN BOOLEAN, not a `fullscreen`-style tri-state: there are no
|
|
359
557
|
* heuristics for an explicit `true` to override (D-10).
|
|
@@ -373,6 +571,12 @@ export interface PersistedConfig {
|
|
|
373
571
|
team: TeamConfig;
|
|
374
572
|
/** Todo planning. The FIFTH nested object; scalars only (see TodoConfig). */
|
|
375
573
|
todo: TodoConfig;
|
|
574
|
+
/** API retry. The SIXTH nested object; scalars only (see RetryConfig). */
|
|
575
|
+
retry: RetryConfig;
|
|
576
|
+
/** Fast model tier. The SEVENTH nested object; scalars only (see FastConfig). */
|
|
577
|
+
fast: FastConfig;
|
|
578
|
+
/** Auto-update. The EIGHTH nested object; scalars only (see UpdateConfig). */
|
|
579
|
+
update: UpdateConfig;
|
|
376
580
|
}
|
|
377
581
|
export declare const DEFAULT_CONFIG: PersistedConfig;
|
|
378
582
|
/**
|
|
@@ -404,6 +608,28 @@ export interface CliConfig {
|
|
|
404
608
|
model: string;
|
|
405
609
|
baseUrl?: string;
|
|
406
610
|
thinkingLevel: ThinkingLevel;
|
|
611
|
+
/**
|
|
612
|
+
* Seeds `ViewState.thinkingVisible` on the first frame (§4.1 / P1-2).
|
|
613
|
+
*
|
|
614
|
+
* IT MUST EXIST HERE AND NOT ONLY IN `PersistedConfig`. `App` reads `cfg.*`,
|
|
615
|
+
* where `cfg` is a `CliConfig`; a key added to the persisted shape alone would
|
|
616
|
+
* round-trip through `config set`, appear in `config list` — and never reach
|
|
617
|
+
* `initialViewState`. `--show-thinking` and `ARAGON_SHOW_THINKING` would parse
|
|
618
|
+
* and be discarded. Nothing would fail; the setting would simply do nothing.
|
|
619
|
+
*/
|
|
620
|
+
showThinking: boolean;
|
|
621
|
+
/**
|
|
622
|
+
* Whether `AgentController` allocates the live-output store and binds
|
|
623
|
+
* `recordOutput` (agent-activity-presentation-live §4.1).
|
|
624
|
+
*
|
|
625
|
+
* IT MUST EXIST HERE AND NOT ONLY IN `PersistedConfig`, for the reason its
|
|
626
|
+
* neighbour records one comment up: the controller reads `config.*`, where
|
|
627
|
+
* `config` is a `CliConfig`, so a key added to the persisted shape alone would
|
|
628
|
+
* round-trip through `config set`, appear in `config list` -- and never reach
|
|
629
|
+
* the constructor. `--live-tool-output` and `ARAGON_LIVE_TOOL_OUTPUT` would
|
|
630
|
+
* parse and be discarded, with nothing failing.
|
|
631
|
+
*/
|
|
632
|
+
liveToolOutput: boolean;
|
|
407
633
|
/** The resolved cap, or `undefined` for AUTO (per-model ceiling, ≤ 64000). */
|
|
408
634
|
maxTokens?: number;
|
|
409
635
|
theme: ThemeName;
|
|
@@ -499,6 +725,46 @@ export interface CliConfig {
|
|
|
499
725
|
* must call `setTodoConfig` as well as persisting (P1-2).
|
|
500
726
|
*/
|
|
501
727
|
todo: TodoConfig;
|
|
728
|
+
/**
|
|
729
|
+
* Resolved API-retry settings (llm-api-retry-backoff §6.2).
|
|
730
|
+
*
|
|
731
|
+
* Unlike `team.enabled` / `todo.enabled` this decides NOTHING at construction
|
|
732
|
+
* time: the policy lives on the `ProviderRegistry` and `setRetryConfig()`
|
|
733
|
+
* replaces it live, so `/retry off` takes effect in the running session. That is
|
|
734
|
+
* why the controller has no `retryRegistered` twin of the two flags above.
|
|
735
|
+
*/
|
|
736
|
+
retry: RetryConfig;
|
|
737
|
+
/**
|
|
738
|
+
* Resolved fast-tier settings (fast-model-tier §4.2).
|
|
739
|
+
*
|
|
740
|
+
* `enabled` here decides `fastRegistered` — whether `task`'s schema carries a
|
|
741
|
+
* `model` property at all — which happens once at construction and can never
|
|
742
|
+
* be undone (C-2). The live on/off switch `/fast` flips is a separate flag on
|
|
743
|
+
* `FastWiring`.
|
|
744
|
+
*
|
|
745
|
+
* THE OTHER NINE KEYS ARE READ LIVE, and that is not the same statement.
|
|
746
|
+
* `provider` / `model` / `baseUrl` feed `resolveFastTier`, which is re-run on
|
|
747
|
+
* every config mutation (§3.2 rule 8 / RV-3) because `''` INHERITS from
|
|
748
|
+
* `config.provider` / `config.baseUrl` and those are rewritten by `/model`,
|
|
749
|
+
* `/provider`, `/reload` and the settings screen.
|
|
750
|
+
*/
|
|
751
|
+
fast: FastConfig;
|
|
752
|
+
/**
|
|
753
|
+
* Resolved auto-update settings (cli-auto-update §4.1).
|
|
754
|
+
*
|
|
755
|
+
* `mode` here decides whether `runInteractive` CONSTRUCTS the service at all
|
|
756
|
+
* (§3.8), which is what makes `'off'` byte-identical to a pre-feature build:
|
|
757
|
+
* no timer, no file read, no socket. The other three keys are read by the
|
|
758
|
+
* service on every check, so a `/update off` mid-session stops the next one.
|
|
759
|
+
*
|
|
760
|
+
* IT MUST EXIST HERE AND NOT ONLY IN `PersistedConfig`, for the reason
|
|
761
|
+
* `showThinking` and `liveToolOutput` each record above: the gate reads
|
|
762
|
+
* `cfg.update`, where `cfg` is a `CliConfig`, so a key added to the persisted
|
|
763
|
+
* shape alone would round-trip through `config set`, appear in `config list` —
|
|
764
|
+
* and never reach the gate. `--no-update` and `ARAGON_UPDATE=0` would parse
|
|
765
|
+
* and be discarded, with no compile error and no runtime error.
|
|
766
|
+
*/
|
|
767
|
+
update: UpdateConfig;
|
|
502
768
|
/**
|
|
503
769
|
* Lifetime submit count driving the composer hint fade (`HINT_FADE_AFTER`).
|
|
504
770
|
*
|