@aragon-agent/cli 0.6.14 → 0.6.15
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 +14 -0
- package/README.md +250 -233
- package/dist/agent/controller.d.ts +27 -1
- package/dist/agent/controller.js +182 -45
- package/dist/agent/plan-prompt.d.ts +1 -1
- package/dist/agent/plan-prompt.js +4 -3
- package/dist/agent/project-guidance-prompt.d.ts +4 -0
- package/dist/agent/project-guidance-prompt.js +104 -0
- package/dist/agent/reducer.d.ts +2 -0
- package/dist/agent/reducer.js +4 -0
- package/dist/agent/system-prompt.js +4 -0
- package/dist/commands/builtins.js +2 -2
- package/dist/compaction/child.d.ts +9 -1
- package/dist/compaction/child.js +39 -13
- package/dist/compaction/command.js +20 -10
- package/dist/compaction/compactor.d.ts +33 -204
- package/dist/compaction/compactor.js +311 -726
- package/dist/compaction/digest.d.ts +15 -51
- package/dist/compaction/digest.js +113 -148
- package/dist/compaction/limits.d.ts +19 -142
- package/dist/compaction/limits.js +20 -147
- package/dist/compaction/memory-identity.d.ts +16 -0
- package/dist/compaction/memory-identity.js +63 -0
- package/dist/compaction/memory-input.d.ts +25 -0
- package/dist/compaction/memory-input.js +106 -0
- package/dist/compaction/memory-render.d.ts +4 -0
- package/dist/compaction/memory-render.js +47 -0
- package/dist/compaction/memory-validation.d.ts +21 -0
- package/dist/compaction/memory-validation.js +268 -0
- package/dist/compaction/memory.d.ts +79 -0
- package/dist/compaction/memory.js +118 -0
- package/dist/compaction/meter.d.ts +14 -10
- package/dist/compaction/meter.js +53 -19
- package/dist/compaction/operation.d.ts +18 -0
- package/dist/compaction/operation.js +68 -0
- package/dist/compaction/pressure.d.ts +5 -20
- package/dist/compaction/pressure.js +13 -23
- package/dist/compaction/summarize-call.d.ts +3 -16
- package/dist/compaction/summarize-call.js +20 -20
- package/dist/compaction/summary-prompt.d.ts +29 -66
- package/dist/compaction/summary-prompt.js +132 -178
- package/dist/compaction/types.d.ts +21 -3
- package/dist/compaction/wiring.d.ts +10 -25
- package/dist/compaction/wiring.js +56 -66
- package/dist/config/schema.d.ts +1 -1
- package/dist/config/schema.js +1 -1
- package/dist/exec/events.d.ts +8 -0
- package/dist/exec/index.js +13 -6
- package/dist/exec/runner.d.ts +8 -0
- package/dist/exec/runner.js +26 -2
- package/dist/session/persist.d.ts +3 -0
- package/dist/session/persist.js +9 -0
- package/dist/session/store.js +2 -0
- package/dist/session/validate-session.js +34 -0
- package/dist/team/subagent.js +8 -0
- package/dist/ui/App.js +218 -116
- package/dist/ui/BottomStatusRow.d.ts +5 -10
- package/dist/ui/BottomStatusRow.js +7 -11
- package/dist/ui/Composer.d.ts +4 -2
- package/dist/ui/Composer.js +2 -2
- package/dist/ui/Header.d.ts +6 -2
- package/dist/ui/Header.js +7 -6
- package/dist/ui/PromptInput.d.ts +3 -1
- package/dist/ui/PromptInput.js +32 -41
- package/dist/ui/StatusBar.d.ts +6 -0
- package/dist/ui/StatusBar.js +8 -7
- package/dist/ui/Transcript.js +1 -1
- package/dist/ui/entries/CompactionCard.d.ts +3 -1
- package/dist/ui/entries/CompactionCard.js +7 -5
- package/dist/ui/frame-differ.js +27 -0
- package/dist/ui/frame-observer.js +18 -5
- package/dist/ui/interaction-copy.d.ts +73 -73
- package/dist/ui/interaction-copy.js +30 -38
- package/dist/ui/interaction-hints.d.ts +8 -1
- package/dist/ui/interaction-hints.js +56 -69
- package/dist/ui/layout/AppShell.d.ts +6 -2
- package/dist/ui/layout/AppShell.js +2 -2
- package/dist/ui/layout/OverlayFrame.d.ts +2 -0
- package/dist/ui/layout/OverlayFrame.js +23 -14
- package/dist/ui/layout/ScrollViewport.d.ts +3 -1
- package/dist/ui/layout/ScrollViewport.js +10 -2
- package/dist/ui/layout/budget.d.ts +25 -26
- package/dist/ui/layout/budget.js +29 -22
- package/dist/ui/layout/document-layout.d.ts +2 -2
- package/dist/ui/layout/document-layout.js +2 -3
- package/dist/ui/layout/queue-layout.js +4 -4
- package/dist/ui/layout/status-detail-layout.d.ts +9 -0
- package/dist/ui/layout/status-detail-layout.js +56 -0
- package/dist/ui/layout/status-layout.d.ts +19 -2
- package/dist/ui/layout/status-layout.js +95 -84
- package/dist/ui/layout/wrap-rows.d.ts +2 -0
- package/dist/ui/layout/wrap-rows.js +21 -7
- package/dist/ui/overlays/ConfirmDialog.d.ts +2 -1
- package/dist/ui/overlays/ConfirmDialog.js +22 -3
- package/dist/ui/overlays/HelpOverlay.js +9 -2
- package/dist/ui/overlays/ModelPicker.d.ts +5 -8
- package/dist/ui/overlays/ModelPicker.js +44 -10
- package/dist/ui/overlays/ModelProfileEditor.js +2 -0
- package/dist/ui/overlays/ModelProfilePicker.d.ts +1 -0
- package/dist/ui/overlays/ModelProfilePicker.js +4 -2
- package/dist/ui/overlays/PlanReviewOverlay.d.ts +2 -1
- package/dist/ui/overlays/PlanReviewOverlay.js +7 -4
- package/dist/ui/overlays/QuestionOverlay.d.ts +2 -1
- package/dist/ui/overlays/QuestionOverlay.js +45 -32
- package/dist/ui/overlays/QueueOverlay.js +2 -2
- package/dist/ui/overlays/SettingsScreen.d.ts +1 -0
- package/dist/ui/overlays/SettingsScreen.js +10 -3
- package/dist/ui/run-metrics.d.ts +23 -0
- package/dist/ui/run-metrics.js +27 -0
- package/dist/ui/status-feedback.d.ts +33 -0
- package/dist/ui/status-feedback.js +36 -0
- package/dist/ui/stdout-frame-writer.js +28 -0
- package/package.json +2 -2
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Local cancellation and deadline ownership, independent of transport cooperation. */
|
|
2
|
+
export declare class CompactionOperation {
|
|
3
|
+
readonly id: number;
|
|
4
|
+
private readonly parent;
|
|
5
|
+
readonly controller: AbortController;
|
|
6
|
+
readonly deadline: number;
|
|
7
|
+
private settled;
|
|
8
|
+
private reason;
|
|
9
|
+
private readonly onParentAbort;
|
|
10
|
+
constructor(id: number, parent: AbortSignal, timeoutMs: number);
|
|
11
|
+
get signal(): AbortSignal;
|
|
12
|
+
/** Abort is local; a late remote reply never restores ownership. */
|
|
13
|
+
abort(reason?: string): void;
|
|
14
|
+
/** One settlement per operation, including rejected or abandoned candidates. */
|
|
15
|
+
settle(): boolean;
|
|
16
|
+
/** Race every call locally and attach rejection handling even to late promises. */
|
|
17
|
+
run<T>(call: () => Promise<T>, timeoutMs: number): Promise<T>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/** Local cancellation and deadline ownership, independent of transport cooperation. */
|
|
2
|
+
export class CompactionOperation {
|
|
3
|
+
id;
|
|
4
|
+
parent;
|
|
5
|
+
controller = new AbortController();
|
|
6
|
+
deadline;
|
|
7
|
+
settled = false;
|
|
8
|
+
reason = 'aborted';
|
|
9
|
+
onParentAbort = () => this.abort();
|
|
10
|
+
constructor(id, parent, timeoutMs) {
|
|
11
|
+
this.id = id;
|
|
12
|
+
this.parent = parent;
|
|
13
|
+
this.deadline = Date.now() + timeoutMs;
|
|
14
|
+
parent.addEventListener('abort', this.onParentAbort, { once: true });
|
|
15
|
+
if (parent.aborted)
|
|
16
|
+
this.abort();
|
|
17
|
+
}
|
|
18
|
+
get signal() { return this.controller.signal; }
|
|
19
|
+
/** Abort is local; a late remote reply never restores ownership. */
|
|
20
|
+
abort(reason = 'aborted') {
|
|
21
|
+
if (this.signal.aborted)
|
|
22
|
+
return;
|
|
23
|
+
this.reason = reason;
|
|
24
|
+
this.controller.abort();
|
|
25
|
+
}
|
|
26
|
+
/** One settlement per operation, including rejected or abandoned candidates. */
|
|
27
|
+
settle() {
|
|
28
|
+
if (this.settled)
|
|
29
|
+
return false;
|
|
30
|
+
this.settled = true;
|
|
31
|
+
this.parent.removeEventListener('abort', this.onParentAbort);
|
|
32
|
+
this.abort();
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
/** Race every call locally and attach rejection handling even to late promises. */
|
|
36
|
+
async run(call, timeoutMs) {
|
|
37
|
+
if (this.signal.aborted || this.settled)
|
|
38
|
+
throw new Error(this.reason);
|
|
39
|
+
const remaining = Math.min(timeoutMs, this.deadline - Date.now());
|
|
40
|
+
if (remaining <= 0)
|
|
41
|
+
throw new Error('timeout');
|
|
42
|
+
let timer;
|
|
43
|
+
let onAbort = () => { };
|
|
44
|
+
const cancelled = new Promise((_, reject) => {
|
|
45
|
+
onAbort = () => reject(new Error(this.reason));
|
|
46
|
+
this.signal.addEventListener('abort', onAbort, { once: true });
|
|
47
|
+
if (this.signal.aborted)
|
|
48
|
+
onAbort();
|
|
49
|
+
timer = setTimeout(() => this.abort('timeout'), remaining);
|
|
50
|
+
});
|
|
51
|
+
try {
|
|
52
|
+
if (this.signal.aborted)
|
|
53
|
+
throw new Error(this.reason);
|
|
54
|
+
const remote = Promise.resolve().then(() => {
|
|
55
|
+
if (this.signal.aborted || this.settled)
|
|
56
|
+
throw new Error(this.reason);
|
|
57
|
+
if (Date.now() >= this.deadline)
|
|
58
|
+
throw new Error('timeout');
|
|
59
|
+
return call();
|
|
60
|
+
});
|
|
61
|
+
return await Promise.race([remote, cancelled]);
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
clearTimeout(timer);
|
|
65
|
+
this.signal.removeEventListener('abort', onAbort);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -119,24 +119,9 @@ export declare function isApproximate(p: Pressure): boolean;
|
|
|
119
119
|
* support thread about a wrong percentage.
|
|
120
120
|
*/
|
|
121
121
|
export declare function computePressure(input: PressureInput): Pressure;
|
|
122
|
-
|
|
123
|
-
|
|
122
|
+
/** Only actual occupancy authorizes automatic compaction. */
|
|
123
|
+
export declare function shouldCompactAt(p: Pressure, threshold: number): boolean;
|
|
124
|
+
/** Capacity helper retained for the standalone tail-budget API, never a trigger. */
|
|
125
|
+
export declare function requiredHeadroom(req: {
|
|
124
126
|
maxOutputTokens: number;
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* The tokens the NEXT request needs on top of the history.
|
|
128
|
-
*
|
|
129
|
-
* `THINKING_HEADROOM_TOKENS` (4096) and `CONTEXT_SAFETY_MARGIN_TOKENS` (1024) are
|
|
130
|
-
* existing core exports and are reused rather than re-spelled.
|
|
131
|
-
*/
|
|
132
|
-
export declare function requiredHeadroom(req: HeadroomRequirement): number;
|
|
133
|
-
/**
|
|
134
|
-
* The trigger, and the second term is not belt-and-braces (D-12).
|
|
135
|
-
*
|
|
136
|
-
* 90 % OF A 200 k WINDOW LEAVES 20 k, WHICH IS PLENTY. 90 % OF A 32 k WINDOW
|
|
137
|
-
* LEAVES 3.2 k, WHICH IS LESS THAN A SINGLE `max_tokens` OF 8192 - the request is
|
|
138
|
-
* already impossible. A pure ratio trigger is therefore correct for the models
|
|
139
|
-
* most users run and quietly wrong for the small ones, and "quietly wrong on the
|
|
140
|
-
* cheap models" is not a property this product ships.
|
|
141
|
-
*/
|
|
142
|
-
export declare function shouldCompactAt(p: Pressure, threshold: number, req: HeadroomRequirement): boolean;
|
|
127
|
+
}): number;
|
|
@@ -123,9 +123,8 @@ export function computePressure(input) {
|
|
|
123
123
|
source = 'usage';
|
|
124
124
|
}
|
|
125
125
|
else {
|
|
126
|
-
// Before the first
|
|
127
|
-
//
|
|
128
|
-
// is the belt for that case and it does not depend on the ratio being right.
|
|
126
|
+
// Before the first turn_end there is no calibration. Keep the estimate
|
|
127
|
+
// explicit: output reservations never authorize automatic compaction.
|
|
129
128
|
const raw = estimatePromptTokens(input.messages, input.systemPrompt);
|
|
130
129
|
occupied = raw + (input.estimateOffset ?? 0);
|
|
131
130
|
source = 'estimate';
|
|
@@ -147,26 +146,17 @@ export function computePressure(input) {
|
|
|
147
146
|
deltaTokens,
|
|
148
147
|
};
|
|
149
148
|
}
|
|
150
|
-
/**
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
149
|
+
/** Only actual occupancy authorizes automatic compaction. */
|
|
150
|
+
export function shouldCompactAt(p, threshold) {
|
|
151
|
+
if (!Number.isFinite(p.occupied) || p.occupied < 0)
|
|
152
|
+
return false;
|
|
153
|
+
if (!Number.isFinite(p.contextWindow) || p.contextWindow <= 0)
|
|
154
|
+
return false;
|
|
155
|
+
if (!Number.isFinite(threshold) || threshold < 0.5 || threshold > 0.95)
|
|
156
|
+
return false;
|
|
157
|
+
return p.occupied / p.contextWindow >= threshold;
|
|
158
|
+
}
|
|
159
|
+
/** Capacity helper retained for the standalone tail-budget API, never a trigger. */
|
|
156
160
|
export function requiredHeadroom(req) {
|
|
157
161
|
return req.maxOutputTokens + THINKING_HEADROOM_TOKENS + CONTEXT_SAFETY_MARGIN_TOKENS;
|
|
158
162
|
}
|
|
159
|
-
/**
|
|
160
|
-
* The trigger, and the second term is not belt-and-braces (D-12).
|
|
161
|
-
*
|
|
162
|
-
* 90 % OF A 200 k WINDOW LEAVES 20 k, WHICH IS PLENTY. 90 % OF A 32 k WINDOW
|
|
163
|
-
* LEAVES 3.2 k, WHICH IS LESS THAN A SINGLE `max_tokens` OF 8192 - the request is
|
|
164
|
-
* already impossible. A pure ratio trigger is therefore correct for the models
|
|
165
|
-
* most users run and quietly wrong for the small ones, and "quietly wrong on the
|
|
166
|
-
* cheap models" is not a property this product ships.
|
|
167
|
-
*/
|
|
168
|
-
export function shouldCompactAt(p, threshold, req) {
|
|
169
|
-
if (p.contextWindow <= 0)
|
|
170
|
-
return false;
|
|
171
|
-
return p.ratio >= threshold || p.headroom < requiredHeadroom(req);
|
|
172
|
-
}
|
|
@@ -1,19 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The bounded summarization call (context-auto-compaction §3.6.4).
|
|
3
|
-
*
|
|
4
|
-
* ASCII ONLY: `src/compaction/**` is inside the glyph scanner's scope.
|
|
5
|
-
*
|
|
6
|
-
* THIS MODULE DOES NOT OWN AN `AbortController`, AND THAT IS A PROHIBITION
|
|
7
|
-
* RATHER THAN AN OVERSIGHT - the identical rule `fast/review-call.ts` records at
|
|
8
|
-
* length, and for the identical reason: the retry layer returns SILENTLY on
|
|
9
|
-
* abort, so a cancellation and a timeout arrive as byte-identical bare `Error`s
|
|
10
|
-
* carrying no `errorType`. Once the controller is private to this module, the
|
|
11
|
-
* caller can no longer stamp WHICH of the two happened, and every cancelled
|
|
12
|
-
* summarization is misreported as a failure.
|
|
13
|
-
*
|
|
14
|
-
* So this module RECEIVES the signal and a timeout callback, and returns an
|
|
15
|
-
* outcome. It does not create, own, or classify the abort.
|
|
16
|
-
*/
|
|
1
|
+
/** Bounded summary transport; local cancellation also settles uncooperative providers. */
|
|
17
2
|
import type { AssistantMessage, LLMRequest, ModelRef, TokenUsage } from '@aragon-agent/core';
|
|
18
3
|
/** The assistant text of a completion, or `''` for an answer with no text block. */
|
|
19
4
|
export declare function assistantText(message: AssistantMessage | undefined): string;
|
|
@@ -34,6 +19,7 @@ export interface SummarizeRequestParams {
|
|
|
34
19
|
digest: string;
|
|
35
20
|
instructions?: string;
|
|
36
21
|
hasPriorSummary: boolean;
|
|
22
|
+
validationError?: string;
|
|
37
23
|
/** Created and owned by the compactor; forwarded into the provider from there. */
|
|
38
24
|
signal: AbortSignal;
|
|
39
25
|
now: number;
|
|
@@ -57,6 +43,7 @@ export interface SummarizeCallParams extends SummarizeRequestParams {
|
|
|
57
43
|
* THE CALLER ABORTS, NOT THIS MODULE. See the file header.
|
|
58
44
|
*/
|
|
59
45
|
onTimeout(): void;
|
|
46
|
+
onUsage?(usage: TokenUsage): void;
|
|
60
47
|
}
|
|
61
48
|
export type SummarizeOutcome = {
|
|
62
49
|
ok: true;
|
|
@@ -1,21 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The bounded summarization call (context-auto-compaction §3.6.4).
|
|
3
|
-
*
|
|
4
|
-
* ASCII ONLY: `src/compaction/**` is inside the glyph scanner's scope.
|
|
5
|
-
*
|
|
6
|
-
* THIS MODULE DOES NOT OWN AN `AbortController`, AND THAT IS A PROHIBITION
|
|
7
|
-
* RATHER THAN AN OVERSIGHT - the identical rule `fast/review-call.ts` records at
|
|
8
|
-
* length, and for the identical reason: the retry layer returns SILENTLY on
|
|
9
|
-
* abort, so a cancellation and a timeout arrive as byte-identical bare `Error`s
|
|
10
|
-
* carrying no `errorType`. Once the controller is private to this module, the
|
|
11
|
-
* caller can no longer stamp WHICH of the two happened, and every cancelled
|
|
12
|
-
* summarization is misreported as a failure.
|
|
13
|
-
*
|
|
14
|
-
* So this module RECEIVES the signal and a timeout callback, and returns an
|
|
15
|
-
* outcome. It does not create, own, or classify the abort.
|
|
16
|
-
*/
|
|
17
1
|
import { COMPACTION_LIMITS } from './limits.js';
|
|
18
2
|
import { buildSummarySystemPrompt, buildSummaryUserMessage } from './summary-prompt.js';
|
|
3
|
+
import { CompactionOperation } from './operation.js';
|
|
19
4
|
/** The assistant text of a completion, or `''` for an answer with no text block. */
|
|
20
5
|
export function assistantText(message) {
|
|
21
6
|
if (!message || !Array.isArray(message.content))
|
|
@@ -44,6 +29,10 @@ export function accumulateUsage(total, next) {
|
|
|
44
29
|
return {
|
|
45
30
|
inputTokens: total.inputTokens + next.inputTokens,
|
|
46
31
|
outputTokens: total.outputTokens + next.outputTokens,
|
|
32
|
+
...((total.cacheReadTokens !== undefined || next.cacheReadTokens !== undefined)
|
|
33
|
+
? { cacheReadTokens: (total.cacheReadTokens ?? 0) + (next.cacheReadTokens ?? 0) } : {}),
|
|
34
|
+
...((total.cacheWriteTokens !== undefined || next.cacheWriteTokens !== undefined)
|
|
35
|
+
? { cacheWriteTokens: (total.cacheWriteTokens ?? 0) + (next.cacheWriteTokens ?? 0) } : {}),
|
|
47
36
|
};
|
|
48
37
|
}
|
|
49
38
|
/**
|
|
@@ -59,7 +48,8 @@ export function buildSummarizeRequest(params) {
|
|
|
59
48
|
maxChars: COMPACTION_LIMITS.summaryMaxChars,
|
|
60
49
|
...(params.instructions ? { instructions: params.instructions } : {}),
|
|
61
50
|
hasPriorSummary: params.hasPriorSummary,
|
|
62
|
-
})
|
|
51
|
+
}) + (params.validationError
|
|
52
|
+
? `\nPrevious delta rejected: ${params.validationError.slice(0, 200)}. Correct that error.` : ''),
|
|
63
53
|
messages: [buildSummaryUserMessage(params.digest, params.now)],
|
|
64
54
|
maxTokens: COMPACTION_LIMITS.summaryOutputTokens,
|
|
65
55
|
// PAIRED WITH `temperature: 0` ON PURPOSE: the Anthropic adapter deletes
|
|
@@ -72,15 +62,25 @@ export function buildSummarizeRequest(params) {
|
|
|
72
62
|
}
|
|
73
63
|
/** Send one summarization and bound it in wall clock. */
|
|
74
64
|
export async function runSummarizeCall(params) {
|
|
75
|
-
const
|
|
65
|
+
const operation = new CompactionOperation(0, params.signal, COMPACTION_LIMITS.callTimeoutMs);
|
|
66
|
+
let charged = false;
|
|
76
67
|
try {
|
|
77
|
-
const message = await
|
|
68
|
+
const message = await operation.run(async () => {
|
|
69
|
+
const result = await params.complete(params.ref.providerId, buildSummarizeRequest({ ...params, signal: operation.signal }));
|
|
70
|
+
if (result.usage && !charged) {
|
|
71
|
+
charged = true;
|
|
72
|
+
params.onUsage?.(result.usage);
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
75
|
+
}, COMPACTION_LIMITS.callTimeoutMs);
|
|
78
76
|
return { ok: true, text: assistantText(message), usage: usageOf(message) };
|
|
79
77
|
}
|
|
80
78
|
catch (error) {
|
|
79
|
+
if (errorText(error) === 'timeout')
|
|
80
|
+
params.onTimeout();
|
|
81
81
|
return { ok: false, error };
|
|
82
82
|
}
|
|
83
83
|
finally {
|
|
84
|
-
|
|
84
|
+
operation.settle();
|
|
85
85
|
}
|
|
86
86
|
}
|
|
@@ -1,85 +1,48 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The summarizer's system prompt and the `<compacted_context>` splice
|
|
3
|
-
* (context-auto-compaction §3.6.4 / §3.6.5).
|
|
4
|
-
*
|
|
5
|
-
* ASCII ONLY: `src/compaction/**` is inside the glyph scanner's scope.
|
|
6
|
-
*
|
|
7
|
-
* PURE. Every input arrives as an argument, so the block a session produced can
|
|
8
|
-
* be reconstructed from a bug report with one call.
|
|
9
|
-
*/
|
|
1
|
+
/** Strict v2 framing and summarizer instructions. Text shape never grants authority. */
|
|
10
2
|
import type { Message, UserMessage } from '@aragon-agent/core';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
* THE HEADINGS ARE PART OF THE CONTRACT, because the next model to read them is
|
|
15
|
-
* an LLM: a summary with predictable sections can be scanned for "what is still
|
|
16
|
-
* open" without re-reading the whole thing.
|
|
17
|
-
*/
|
|
3
|
+
import { type CompactionMemory } from './memory.js';
|
|
4
|
+
import { type CompactionIdentity } from './memory-identity.js';
|
|
5
|
+
/** Build a strict delta-only prompt; throws on an oversized manual focus. */
|
|
18
6
|
export declare function buildSummarySystemPrompt(opts: {
|
|
19
7
|
maxChars: number;
|
|
20
|
-
/** Free text from `/compact <instructions>`, appended as `## Focus`. */
|
|
21
8
|
instructions?: string;
|
|
22
|
-
/** True when the digest opens with a `PRIOR SUMMARY` section. */
|
|
23
9
|
hasPriorSummary: boolean;
|
|
24
10
|
}): string;
|
|
25
|
-
/**
|
|
11
|
+
/** Wrap a digest for the summary request without changing its body. */
|
|
26
12
|
export declare function buildSummaryUserMessage(digest: string, now: number): UserMessage;
|
|
27
13
|
export type AnchorShape = 'tagged' | 'verbatim';
|
|
28
14
|
export interface AnchorInfo {
|
|
29
|
-
|
|
30
|
-
message: Message;
|
|
15
|
+
message: UserMessage;
|
|
31
16
|
shape: AnchorShape;
|
|
32
17
|
}
|
|
33
|
-
/**
|
|
34
|
-
* Recognize an anchor this feature produced on a previous pass.
|
|
35
|
-
*
|
|
36
|
-
* STRUCTURAL, NOT LENGTH-DEPENDENT (D-21 / P1-9). v1 of the design identified
|
|
37
|
-
* the anchor as "the first `user` message of the conversation" and chose between
|
|
38
|
-
* two shapes by length. Neither rule composes across repeated compactions,
|
|
39
|
-
* because after the first pass the first user message IS the compacted block:
|
|
40
|
-
* the merged shape promotes a SUMMARY to "the user's original task", and the
|
|
41
|
-
* standalone shape keeps the block as an anchor AND re-digests it. Neither
|
|
42
|
-
* failure raises anything, and both get worse every pass.
|
|
43
|
-
*/
|
|
44
|
-
export declare function isTaggedAnchor(message: Message): boolean;
|
|
45
|
-
/**
|
|
46
|
-
* Build (or carry through) the leading anchor.
|
|
47
|
-
*
|
|
48
|
-
* ALWAYS ITS OWN LEADING MESSAGE, AND ALWAYS STRUCTURALLY IDENTIFIABLE. A
|
|
49
|
-
* summarizer that is 90 % faithful is fine for the middle of a conversation and
|
|
50
|
-
* catastrophic for the sentence that says what the user wanted (D-6).
|
|
51
|
-
*/
|
|
18
|
+
/** Preserve the first original user Message, including all parts and timestamp. */
|
|
52
19
|
export declare function buildAnchor(messages: readonly Message[]): AnchorInfo | null;
|
|
53
|
-
/**
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
* stays free of any knowledge of the block format.
|
|
60
|
-
*/
|
|
61
|
-
export declare function countProtectedPrefix(messages: readonly Message[]): number;
|
|
62
|
-
/** Read `generation="N"` off a prior block, so the next one can say `N + 1`. */
|
|
63
|
-
export declare function readGeneration(messages: readonly Message[]): number;
|
|
20
|
+
/** Legacy syntax helper only; callers must independently establish provenance. */
|
|
21
|
+
export declare function isTaggedAnchor(message: Message): boolean;
|
|
22
|
+
/** Count only an adopted or restored verified prefix; tags alone protect nothing. */
|
|
23
|
+
export declare function countProtectedPrefix(messages: readonly Message[], identity?: CompactionIdentity): number;
|
|
24
|
+
/** Read the adopted generation; never continue a user-supplied block's authority. */
|
|
25
|
+
export declare function readGeneration(messages: readonly Message[], identity?: CompactionIdentity): number;
|
|
64
26
|
export interface BlockInput {
|
|
65
|
-
|
|
27
|
+
memory?: CompactionMemory;
|
|
28
|
+
/** Compatibility argument accepts only a complete validated v2 JSON body. */
|
|
29
|
+
summary?: string;
|
|
66
30
|
replaced: number;
|
|
67
31
|
turns: number;
|
|
68
32
|
anchor: AnchorShape;
|
|
69
33
|
generation: number;
|
|
70
|
-
|
|
71
|
-
|
|
34
|
+
truncated?: boolean;
|
|
35
|
+
timestamp?: number;
|
|
72
36
|
}
|
|
73
|
-
/**
|
|
74
|
-
export declare function truncationBody(replaced: number): string;
|
|
75
|
-
/**
|
|
76
|
-
* The spliced block.
|
|
77
|
-
*
|
|
78
|
-
* A `user` MESSAGE, NEVER A FABRICATED ASSISTANT ONE (D-5). An assistant message
|
|
79
|
-
* claiming the model said something it did not is a lie the model will then act
|
|
80
|
-
* on, and it corrupts every subsequent turn. The XML tag is the same disclosure
|
|
81
|
-
* device `<fast_review>` and `<skill>` already use in this codebase, and the
|
|
82
|
-
* instruction line is what stops the model reading the block as the user ASKING
|
|
83
|
-
* for a summary.
|
|
84
|
-
*/
|
|
37
|
+
/** Build a complete v2 block; rejects free text, truncation and mismatched metadata. */
|
|
85
38
|
export declare function buildCompactedBlock(input: BlockInput): UserMessage;
|
|
39
|
+
export interface ParsedCompactedBlock {
|
|
40
|
+
memory: CompactionMemory;
|
|
41
|
+
anchor: AnchorShape;
|
|
42
|
+
replaced: number;
|
|
43
|
+
turns: number;
|
|
44
|
+
}
|
|
45
|
+
/** Parse exact v2 syntax and schema. This does not authenticate a history prefix. */
|
|
46
|
+
export declare function parseCompactedBlock(message: Message): ParsedCompactedBlock;
|
|
47
|
+
/** Retained legacy display helper; v2 never uses it to delete history. */
|
|
48
|
+
export declare function truncationBody(replaced: number): string;
|