@corenel/harness 0.13.0 → 0.14.0
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/dist/audit/recorder.d.ts +6 -1
- package/dist/audit/recorder.d.ts.map +1 -1
- package/dist/audit/recorder.js +9 -2
- package/dist/audit/recorder.js.map +1 -1
- package/dist/audit/runAudit.d.ts.map +1 -1
- package/dist/audit/runAudit.js +2 -0
- package/dist/audit/runAudit.js.map +1 -1
- package/dist/conversation.d.ts +33 -0
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +44 -1
- package/dist/conversation.js.map +1 -1
- package/dist/core/compactHistory.d.ts +27 -18
- package/dist/core/compactHistory.d.ts.map +1 -1
- package/dist/core/compactHistory.js +106 -40
- package/dist/core/compactHistory.js.map +1 -1
- package/dist/core/foldBlocks.d.ts +43 -0
- package/dist/core/foldBlocks.d.ts.map +1 -0
- package/dist/core/foldBlocks.js +114 -0
- package/dist/core/foldBlocks.js.map +1 -0
- package/dist/core/foldTypes.d.ts +25 -0
- package/dist/core/foldTypes.d.ts.map +1 -0
- package/dist/core/foldTypes.js +2 -0
- package/dist/core/foldTypes.js.map +1 -0
- package/dist/core/loop.d.ts +19 -5
- package/dist/core/loop.d.ts.map +1 -1
- package/dist/core/loop.js +140 -69
- package/dist/core/loop.js.map +1 -1
- package/dist/core/recovery.d.ts +1 -0
- package/dist/core/recovery.d.ts.map +1 -1
- package/dist/core/recovery.js +12 -0
- package/dist/core/recovery.js.map +1 -1
- package/dist/core/summarize.d.ts +9 -3
- package/dist/core/summarize.d.ts.map +1 -1
- package/dist/core/summarize.js +97 -42
- package/dist/core/summarize.js.map +1 -1
- package/dist/guardrail/permission-service.d.ts.map +1 -1
- package/dist/guardrail/permission-service.js +11 -2
- package/dist/guardrail/permission-service.js.map +1 -1
- package/dist/sessions/directivesStore.d.ts +9 -0
- package/dist/sessions/directivesStore.d.ts.map +1 -0
- package/dist/sessions/directivesStore.js +54 -0
- package/dist/sessions/directivesStore.js.map +1 -0
- package/dist/sessions/fileSessionStore.d.ts +2 -2
- package/dist/sessions/fileSessionStore.d.ts.map +1 -1
- package/dist/sessions/fileSessionStore.js +19 -8
- package/dist/sessions/fileSessionStore.js.map +1 -1
- package/dist/sessions/foldStorage.d.ts +15 -0
- package/dist/sessions/foldStorage.d.ts.map +1 -0
- package/dist/sessions/foldStorage.js +121 -0
- package/dist/sessions/foldStorage.js.map +1 -0
- package/dist/sessions/jsonl.d.ts +6 -0
- package/dist/sessions/jsonl.d.ts.map +1 -1
- package/dist/sessions/jsonl.js +15 -1
- package/dist/sessions/jsonl.js.map +1 -1
- package/dist/sidecar/server.d.ts.map +1 -1
- package/dist/sidecar/server.js +11 -1
- package/dist/sidecar/server.js.map +1 -1
- package/dist/tools/foldTools.d.ts +5 -0
- package/dist/tools/foldTools.d.ts.map +1 -0
- package/dist/tools/foldTools.js +123 -0
- package/dist/tools/foldTools.js.map +1 -0
- package/dist/tools/skillTool.d.ts.map +1 -1
- package/dist/tools/skillTool.js +7 -2
- package/dist/tools/skillTool.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compactHistory.js","sourceRoot":"","sources":["../../core/compactHistory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;6DAU6D;AAG7D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"compactHistory.js","sourceRoot":"","sources":["../../core/compactHistory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** The marker every checkpoint (rolling summary) message starts with, so a
|
|
2
|
+
* later pass can recognize one it already wrote instead of collapsing it again. */
|
|
3
|
+
export declare const CHECKPOINT_MARKER = "[checkpoint] ";
|
|
4
|
+
/** The marker every anchor message starts with. An anchor is context ABOUT the
|
|
5
|
+
* user message that follows it, not something the assistant said. */
|
|
6
|
+
export declare const ANCHOR_MARKER = "[anchor] ";
|
|
7
|
+
export declare const USER_TAIL_SHARE = 0.15;
|
|
8
|
+
export declare const DIRECTIVES_SHARE = 0.02;
|
|
9
|
+
export declare const SUMMARY_SHARE = 0.1;
|
|
10
|
+
export declare const SUMMARIZER_INPUT_SHARE = 0.7;
|
|
11
|
+
export declare const ANCHOR_CHARS = 120;
|
|
12
|
+
/** The window assumed when a host gave none -- matches resolveContextWindow's fallback. */
|
|
13
|
+
export declare const FALLBACK_CONTEXT_WINDOW = 32000;
|
|
14
|
+
export declare const DIRECTIVES_MARKER = "[directives] ";
|
|
15
|
+
export interface FoldSummary {
|
|
16
|
+
summary: string;
|
|
17
|
+
directives: string[];
|
|
18
|
+
}
|
|
19
|
+
export interface SummaryEntry {
|
|
20
|
+
at: string;
|
|
21
|
+
body: string;
|
|
22
|
+
}
|
|
23
|
+
export interface SummaryBlock {
|
|
24
|
+
folds: number;
|
|
25
|
+
entries: SummaryEntry[];
|
|
26
|
+
}
|
|
27
|
+
/** A share of a token window, in characters (4 per token, as estimateFill). */
|
|
28
|
+
export declare function shareChars(share: number, contextWindow: number): number;
|
|
29
|
+
export declare function normalizeDirective(s: string): string;
|
|
30
|
+
/** Previous then new, de-duplicated by normalized text (first wording wins),
|
|
31
|
+
* then the OLDEST dropped until the total fits `maxChars`. */
|
|
32
|
+
export declare function mergeDirectives(prev: string[], next: string[], maxChars: number): string[];
|
|
33
|
+
export declare function renderDirectivesBlock(directives: string[]): string;
|
|
34
|
+
export declare function parseDirectivesBlock(content: string): string[] | null;
|
|
35
|
+
export declare function renderSummaryBlock(block: SummaryBlock, opts: {
|
|
36
|
+
recall: boolean;
|
|
37
|
+
}): string;
|
|
38
|
+
export declare function parseSummaryBlock(content: string): SummaryBlock | null;
|
|
39
|
+
/** Drop the oldest entries until their RENDERED size fits; the newest always stays. */
|
|
40
|
+
export declare function trimEntries(entries: SummaryEntry[], maxChars: number): SummaryEntry[];
|
|
41
|
+
/** What a kept user message was replying to, without a model call. */
|
|
42
|
+
export declare function anchorText(answered: string | null): string | null;
|
|
43
|
+
//# sourceMappingURL=foldBlocks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foldBlocks.d.ts","sourceRoot":"","sources":["../../core/foldBlocks.ts"],"names":[],"mappings":"AAOA;mFACmF;AACnF,eAAO,MAAM,iBAAiB,kBAAkB,CAAC;AAEjD;qEACqE;AACrE,eAAO,MAAM,aAAa,cAAc,CAAC;AAEzC,eAAO,MAAM,eAAe,OAAO,CAAC;AACpC,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,eAAO,MAAM,aAAa,MAAM,CAAC;AACjC,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAC1C,eAAO,MAAM,YAAY,MAAM,CAAC;AAChC,2FAA2F;AAC3F,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAC9C,eAAO,MAAM,iBAAiB,kBAAkB,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AACD,MAAM,WAAW,YAAY;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAC1D,MAAM,WAAW,YAAY;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,YAAY,EAAE,CAAA;CAAE;AAExE,+EAA+E;AAC/E,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;8DAC8D;AAC9D,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAc1F;AAID,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,CAElE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAGrE;AAMD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAQzF;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAiBtE;AAOD,uFAAuF;AACvF,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,EAAE,CAKrF;AAED,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAGjE"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/* The blocks a fold leaves in the conversation, as pure text in and out.
|
|
2
|
+
*
|
|
3
|
+
* Both blocks are PARSED BACK FROM THE MESSAGE on the next fold, so a fold
|
|
4
|
+
* needs no store to remember what the last one kept: the conversation is its
|
|
5
|
+
* own record. The durable copies (CHECKPOINT.md, DIRECTIVES.md) are written by
|
|
6
|
+
* the host; these are only what the model carries. */
|
|
7
|
+
/** The marker every checkpoint (rolling summary) message starts with, so a
|
|
8
|
+
* later pass can recognize one it already wrote instead of collapsing it again. */
|
|
9
|
+
export const CHECKPOINT_MARKER = '[checkpoint] ';
|
|
10
|
+
/** The marker every anchor message starts with. An anchor is context ABOUT the
|
|
11
|
+
* user message that follows it, not something the assistant said. */
|
|
12
|
+
export const ANCHOR_MARKER = '[anchor] ';
|
|
13
|
+
export const USER_TAIL_SHARE = 0.15;
|
|
14
|
+
export const DIRECTIVES_SHARE = 0.02;
|
|
15
|
+
export const SUMMARY_SHARE = 0.1;
|
|
16
|
+
export const SUMMARIZER_INPUT_SHARE = 0.7;
|
|
17
|
+
export const ANCHOR_CHARS = 120;
|
|
18
|
+
/** The window assumed when a host gave none -- matches resolveContextWindow's fallback. */
|
|
19
|
+
export const FALLBACK_CONTEXT_WINDOW = 32000;
|
|
20
|
+
export const DIRECTIVES_MARKER = '[directives] ';
|
|
21
|
+
/** A share of a token window, in characters (4 per token, as estimateFill). */
|
|
22
|
+
export function shareChars(share, contextWindow) {
|
|
23
|
+
return Math.floor(share * contextWindow * 4);
|
|
24
|
+
}
|
|
25
|
+
export function normalizeDirective(s) {
|
|
26
|
+
return s.trim().replace(/\s+/g, ' ').toLowerCase();
|
|
27
|
+
}
|
|
28
|
+
/** Previous then new, de-duplicated by normalized text (first wording wins),
|
|
29
|
+
* then the OLDEST dropped until the total fits `maxChars`. */
|
|
30
|
+
export function mergeDirectives(prev, next, maxChars) {
|
|
31
|
+
const seen = new Set();
|
|
32
|
+
const out = [];
|
|
33
|
+
for (const d of [...prev, ...next]) {
|
|
34
|
+
const t = d.trim().replace(/\s+/g, ' ');
|
|
35
|
+
if (!t)
|
|
36
|
+
continue;
|
|
37
|
+
const k = normalizeDirective(t);
|
|
38
|
+
if (seen.has(k))
|
|
39
|
+
continue;
|
|
40
|
+
seen.add(k);
|
|
41
|
+
out.push(t);
|
|
42
|
+
}
|
|
43
|
+
let total = out.reduce((n, d) => n + d.length, 0);
|
|
44
|
+
while (out.length > 1 && total > maxChars)
|
|
45
|
+
total -= out.shift().length;
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
const DIRECTIVES_HEAD = 'Standing instructions and decisions from the user. They hold until the user changes them:';
|
|
49
|
+
export function renderDirectivesBlock(directives) {
|
|
50
|
+
return `${DIRECTIVES_MARKER}${DIRECTIVES_HEAD}\n${directives.map((d) => `- ${d}`).join('\n')}`;
|
|
51
|
+
}
|
|
52
|
+
export function parseDirectivesBlock(content) {
|
|
53
|
+
if (!content.startsWith(DIRECTIVES_MARKER))
|
|
54
|
+
return null;
|
|
55
|
+
return content.split('\n').filter((l) => l.startsWith('- ')).map((l) => l.slice(2).trim()).filter(Boolean);
|
|
56
|
+
}
|
|
57
|
+
const SUMMARY_HEAD = /^Conversation so far \(folded (\d+) times?\)\.$/;
|
|
58
|
+
const ENTRY_LINE = /^--- fold (.*) ---$/;
|
|
59
|
+
const NOTICE_PREFIX = 'Earlier conversation was folded ';
|
|
60
|
+
export function renderSummaryBlock(block, opts) {
|
|
61
|
+
const n = block.folds;
|
|
62
|
+
const parts = [`Conversation so far (folded ${n} ${n === 1 ? 'time' : 'times'}).`];
|
|
63
|
+
for (const e of block.entries)
|
|
64
|
+
parts.push(`--- fold ${e.at} ---`, e.body);
|
|
65
|
+
const notice = `${NOTICE_PREFIX}${n} ${n === 1 ? 'time' : 'times'}.`
|
|
66
|
+
+ (opts.recall ? ' Older summaries and the full transcript can be searched with recall_history.' : '');
|
|
67
|
+
parts.push('', notice);
|
|
68
|
+
return `${CHECKPOINT_MARKER}${parts.join('\n')}`;
|
|
69
|
+
}
|
|
70
|
+
export function parseSummaryBlock(content) {
|
|
71
|
+
if (!content.startsWith(CHECKPOINT_MARKER))
|
|
72
|
+
return null;
|
|
73
|
+
const lines = content.slice(CHECKPOINT_MARKER.length).split('\n');
|
|
74
|
+
const head = SUMMARY_HEAD.exec(lines[0] ?? '');
|
|
75
|
+
/* A checkpoint written before this format existed is one plain summary.
|
|
76
|
+
* Treat it as one entry from one fold rather than dropping it. */
|
|
77
|
+
if (!head)
|
|
78
|
+
return { folds: 1, entries: [{ at: '', body: lines.join('\n').trim() }] };
|
|
79
|
+
const entries = [];
|
|
80
|
+
let cur = null;
|
|
81
|
+
for (const line of lines.slice(1)) {
|
|
82
|
+
if (line.startsWith(NOTICE_PREFIX))
|
|
83
|
+
break;
|
|
84
|
+
const m = ENTRY_LINE.exec(line);
|
|
85
|
+
if (m) {
|
|
86
|
+
cur = { at: m[1], body: '' };
|
|
87
|
+
entries.push(cur);
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (cur)
|
|
91
|
+
cur.body = cur.body ? `${cur.body}\n${line}` : line;
|
|
92
|
+
}
|
|
93
|
+
for (const e of entries)
|
|
94
|
+
e.body = e.body.replace(/\n+$/, '');
|
|
95
|
+
return { folds: Number(head[1]), entries };
|
|
96
|
+
}
|
|
97
|
+
/** The size an entry adds to the rendered block: its fold line and its body, each with a newline. */
|
|
98
|
+
function entryChars(e) {
|
|
99
|
+
return `--- fold ${e.at} ---`.length + 1 + e.body.length + 1;
|
|
100
|
+
}
|
|
101
|
+
/** Drop the oldest entries until their RENDERED size fits; the newest always stays. */
|
|
102
|
+
export function trimEntries(entries, maxChars) {
|
|
103
|
+
const out = [...entries];
|
|
104
|
+
let total = out.reduce((n, e) => n + entryChars(e), 0);
|
|
105
|
+
while (out.length > 1 && total > maxChars)
|
|
106
|
+
total -= entryChars(out.shift());
|
|
107
|
+
return out;
|
|
108
|
+
}
|
|
109
|
+
/** What a kept user message was replying to, without a model call. */
|
|
110
|
+
export function anchorText(answered) {
|
|
111
|
+
const t = (answered ?? '').replace(/\s+/g, ' ').trim();
|
|
112
|
+
return t ? `re: ${t.slice(0, ANCHOR_CHARS)}` : null;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=foldBlocks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foldBlocks.js","sourceRoot":"","sources":["../../core/foldBlocks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ChatCompletionMessageParam } from 'openai/resources/chat/completions';
|
|
2
|
+
import type { FoldSummary } from './foldBlocks';
|
|
3
|
+
/** One fold as the host records it: what the summarizer kept, and the raw
|
|
4
|
+
* messages it was handed, so recall can still find what left the context. */
|
|
5
|
+
export interface FoldRecord extends FoldSummary {
|
|
6
|
+
collapsed: ChatCompletionMessageParam[];
|
|
7
|
+
}
|
|
8
|
+
export interface TranscriptReader {
|
|
9
|
+
/** This session's stored messages, either stored shape, including what
|
|
10
|
+
* folds removed. Throws when there is no readable history at all. */
|
|
11
|
+
messages(): Promise<unknown[]>;
|
|
12
|
+
/** CHECKPOINT.md text, or null when there is none. */
|
|
13
|
+
checkpoints(): Promise<string | null>;
|
|
14
|
+
}
|
|
15
|
+
export interface DirectivesFile {
|
|
16
|
+
/** Parsed DIRECTIVES.md, or null when absent/unreadable. */
|
|
17
|
+
read(): Promise<string[] | null>;
|
|
18
|
+
write(directives: string[]): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
export interface FoldStorage {
|
|
21
|
+
onFold?(record: FoldRecord): Promise<void>;
|
|
22
|
+
directives?: DirectivesFile;
|
|
23
|
+
transcript?: TranscriptReader;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=foldTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foldTypes.d.ts","sourceRoot":"","sources":["../../core/foldTypes.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AACpF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD;6EAC6E;AAC7E,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,SAAS,EAAE,0BAA0B,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,gBAAgB;IAC/B;yEACqE;IACrE,QAAQ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/B,sDAAsD;IACtD,WAAW,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;IACjC,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foldTypes.js","sourceRoot":"","sources":["../../core/foldTypes.ts"],"names":[],"mappings":""}
|
package/dist/core/loop.d.ts
CHANGED
|
@@ -5,7 +5,17 @@ import { type RecoveryConfig } from './recovery';
|
|
|
5
5
|
import type { Policy } from '@corenel/protocol';
|
|
6
6
|
import type { PermissionService } from '../guardrail/permission-service';
|
|
7
7
|
import { type CompressionConfig } from '../compression';
|
|
8
|
+
import { type FoldSummary } from './foldBlocks';
|
|
9
|
+
import type { FoldStorage } from './foldTypes';
|
|
8
10
|
import { type SkillEntry } from '../tools/skillTool';
|
|
11
|
+
/** What the run ends with when even a folded history will not fit the window. */
|
|
12
|
+
export declare const OVERFLOW_GIVE_UP = "The conversation no longer fits this model's context window even after folding. Start a new chat or switch to a larger-context model.";
|
|
13
|
+
/** The overflow ending when there was nothing a fold could remove (compaction
|
|
14
|
+
* not configured, or nothing collapsible). */
|
|
15
|
+
export declare const OVERFLOW_NO_FOLD = "The conversation no longer fits this model's context window and there is nothing left to fold. Start a new chat or switch to a larger-context model.";
|
|
16
|
+
/** The overflow ending when a fold was possible but did not complete (the
|
|
17
|
+
* summarizer threw, for one). The loop appends the fold error and the 400. */
|
|
18
|
+
export declare const OVERFLOW_FOLD_FAILED = "The conversation no longer fits this model's context window and folding it failed. Try again, or start a new chat.";
|
|
9
19
|
export interface RunAgentArgs {
|
|
10
20
|
client: OpenAI;
|
|
11
21
|
model: string;
|
|
@@ -54,13 +64,17 @@ export interface RunAgentArgs {
|
|
|
54
64
|
* then behaves exactly as it did before this existed, which is to say it
|
|
55
65
|
* runs until the provider rejects an oversized request with a fatal 400.
|
|
56
66
|
* `summarize` is a host concern because it costs a model call; the host also
|
|
57
|
-
* decides
|
|
58
|
-
* not an invisible blob). */
|
|
67
|
+
* decides, through `storage`, where a fold is persisted (files the user can
|
|
68
|
+
* edit, not an invisible blob). */
|
|
59
69
|
compaction?: {
|
|
60
|
-
summarize: (collapsed: ChatCompletionMessageParam[]) => Promise<
|
|
61
|
-
|
|
62
|
-
|
|
70
|
+
summarize: (collapsed: ChatCompletionMessageParam[]) => Promise<FoldSummary>;
|
|
71
|
+
/** Where folds are recorded and what backs recall_history/update_directives.
|
|
72
|
+
* Absent: the run still folds, it just records nothing. */
|
|
73
|
+
storage?: FoldStorage;
|
|
63
74
|
};
|
|
75
|
+
/** Fold before the first request regardless of fill: set when the chat's own
|
|
76
|
+
* model is gone and the fallback's window cannot hold the history. */
|
|
77
|
+
forceFoldFirstTurn?: boolean;
|
|
64
78
|
/** Intra-run self-healing budget (stream-retry + tool-steer). Omit for defaults. */
|
|
65
79
|
recovery?: Partial<RecoveryConfig>;
|
|
66
80
|
/** Optional output-token ceiling forwarded to the model on every turn (reasoning
|
package/dist/core/loop.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../core/loop.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,EAAE,0BAA0B,EAAsB,MAAM,mCAAmC,CAAC;AACxG,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAA4B,MAAM,mBAAmB,CAAC;AAE7G,OAAO,EACY,KAAK,cAAc,EAErC,MAAM,YAAY,CAAC;AAMpB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAA0D,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../core/loop.ts"],"names":[],"mappings":"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"}
|
package/dist/core/loop.js
CHANGED
|
@@ -6,7 +6,9 @@ import { checkFeature } from '../guards.js';
|
|
|
6
6
|
import { STANDARD_POLICY } from '../guardrail/builtins.js';
|
|
7
7
|
import { toolAddress } from '../tools/namespaces.js';
|
|
8
8
|
import { effectiveThreshold, formatOffloadRef, isOffloadPointer } from '../compression.js';
|
|
9
|
-
import {
|
|
9
|
+
import { FALLBACK_CONTEXT_WINDOW } from './foldBlocks.js';
|
|
10
|
+
import { afterCompaction, compactHistory, compactionDecision, estimateFill, isCompactionMarker } from './compactHistory.js';
|
|
11
|
+
import { makeRecallHistoryTool, makeUpdateDirectivesTool } from '../tools/foldTools.js';
|
|
10
12
|
import { contextNote, contextWindowLine, initialPressureGate, pressureDecision } from './contextPressure.js';
|
|
11
13
|
import { fillToolsMarker } from '../prompts/toolsMarker.js';
|
|
12
14
|
import { createToolLoader, serverIndex } from '../tools/toolSearch.js';
|
|
@@ -14,6 +16,14 @@ import { createSkillTool, skillIndex } from '../tools/skillTool.js';
|
|
|
14
16
|
import { crewToolGuidance } from '../tools/crewList.js';
|
|
15
17
|
import { createTurnVerifier } from './turnVerify.js';
|
|
16
18
|
import { existedBefore, reportFileChanges, FILE_CHANGE_TOOLS } from './fileChanges.js';
|
|
19
|
+
/** What the run ends with when even a folded history will not fit the window. */
|
|
20
|
+
export const OVERFLOW_GIVE_UP = "The conversation no longer fits this model's context window even after folding. Start a new chat or switch to a larger-context model.";
|
|
21
|
+
/** The overflow ending when there was nothing a fold could remove (compaction
|
|
22
|
+
* not configured, or nothing collapsible). */
|
|
23
|
+
export const OVERFLOW_NO_FOLD = "The conversation no longer fits this model's context window and there is nothing left to fold. Start a new chat or switch to a larger-context model.";
|
|
24
|
+
/** The overflow ending when a fold was possible but did not complete (the
|
|
25
|
+
* summarizer threw, for one). The loop appends the fold error and the 400. */
|
|
26
|
+
export const OVERFLOW_FOLD_FAILED = "The conversation no longer fits this model's context window and folding it failed. Try again, or start a new chat.";
|
|
17
27
|
/** The most tools one request may carry.
|
|
18
28
|
*
|
|
19
29
|
* OpenAI-compatible providers refuse the whole request above this -- "Invalid
|
|
@@ -105,7 +115,7 @@ export async function runAgent(args) {
|
|
|
105
115
|
let n = 0;
|
|
106
116
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
107
117
|
const m = messages[i];
|
|
108
|
-
// A
|
|
118
|
+
// A fold's own summary/directives blocks, and the system prompt unshifted
|
|
109
119
|
// below, are fresh objects too -- and neither is something this run said.
|
|
110
120
|
if (incoming.has(m) || m.role === 'system' || isCompactionMarker(m))
|
|
111
121
|
break;
|
|
@@ -122,7 +132,14 @@ export async function runAgent(args) {
|
|
|
122
132
|
? createToolLoader({ deferred, loaded: args.loadedTools, onChange: (names) => emit({ type: 'tools-loaded', names }) })
|
|
123
133
|
: null;
|
|
124
134
|
const skills = args.skills ?? [];
|
|
125
|
-
const
|
|
135
|
+
const storage = args.compaction?.storage;
|
|
136
|
+
const foldTools = [
|
|
137
|
+
...(storage?.transcript ? [makeRecallHistoryTool(storage.transcript)] : []),
|
|
138
|
+
...(storage?.directives ? [makeUpdateDirectivesTool(storage.directives)] : []),
|
|
139
|
+
];
|
|
140
|
+
/* Fold tools LAST: when MAX_PROVIDER_TOOLS caps this list, they must never be
|
|
141
|
+
* what pushes `use_skill` or `tool_search` off the end. */
|
|
142
|
+
const eager = [...tools, ...(skills.length ? [createSkillTool(skills)] : []), ...(loader ? [loader.searchTool] : []), ...foldTools];
|
|
126
143
|
const capped = (list) => (list.length > MAX_PROVIDER_TOOLS ? list.slice(0, MAX_PROVIDER_TOOLS) : list);
|
|
127
144
|
const activeTools = () => capped(loader ? [...eager, ...loader.loaded()] : eager);
|
|
128
145
|
let sent = activeTools();
|
|
@@ -197,6 +214,82 @@ export async function runAgent(args) {
|
|
|
197
214
|
const known = new Map([...eager, ...deferred].map((t) => [t.name, t]));
|
|
198
215
|
await compactIncomingOffloads(messages, known, compression, toolCtx.recall, emit);
|
|
199
216
|
}
|
|
217
|
+
const foldWindow = ctxWindow || FALLBACK_CONTEXT_WINDOW;
|
|
218
|
+
let forceFold = !!args.forceFoldFirstTurn;
|
|
219
|
+
/* One fold, used by three triggers: the fill gate, a forced fold (model
|
|
220
|
+
* switch), and the overflow retry. Rebuilds `messages` in place -- callers
|
|
221
|
+
* (and `res.messages`) hold this array. Returns what happened; on 'failed'
|
|
222
|
+
* the reason is left in `foldError` for the overflow message.
|
|
223
|
+
*
|
|
224
|
+
* A summarizer failure is the same shape as a persist failure: the window is
|
|
225
|
+
* full, the model call meant to compress it did not come back, and the honest
|
|
226
|
+
* response is to carry on UNFOLDED rather than end the run on the recovery
|
|
227
|
+
* path. The turn proceeds with the history it had, which is exactly what
|
|
228
|
+
* would have happened without compaction at all. */
|
|
229
|
+
let foldError = '';
|
|
230
|
+
const fold = async (offloadFill) => {
|
|
231
|
+
if (!args.compaction)
|
|
232
|
+
return 'nothing';
|
|
233
|
+
try {
|
|
234
|
+
let override = null;
|
|
235
|
+
try {
|
|
236
|
+
override = (await storage?.directives?.read()) ?? null;
|
|
237
|
+
}
|
|
238
|
+
catch (e) {
|
|
239
|
+
alog('directives read failed', e instanceof Error ? e.message : String(e));
|
|
240
|
+
}
|
|
241
|
+
const out = await compactHistory(messages, {
|
|
242
|
+
summarize: args.compaction.summarize,
|
|
243
|
+
contextWindow: foldWindow,
|
|
244
|
+
directivesOverride: override,
|
|
245
|
+
recallAvailable: !!storage?.transcript,
|
|
246
|
+
offloadOverBytes: compression && compression.mode !== 'off'
|
|
247
|
+
? effectiveThreshold(compression.mode, offloadFill)
|
|
248
|
+
: undefined,
|
|
249
|
+
offload: toolCtx.recall
|
|
250
|
+
// Recorded under 'user' rather than a tool name: the RecallStore is
|
|
251
|
+
// indifferent to who authored the bulk, but the transcript should not
|
|
252
|
+
// claim a tool produced what a person pasted.
|
|
253
|
+
? async (content) => formatOffloadRef(await toolCtx.recall.record('user', content))
|
|
254
|
+
: undefined,
|
|
255
|
+
});
|
|
256
|
+
/* Nothing to collapse: no fold happened, so nothing is recorded or emitted. */
|
|
257
|
+
if (!out)
|
|
258
|
+
return 'nothing';
|
|
259
|
+
messages.splice(0, messages.length, ...out.messages);
|
|
260
|
+
/* The 'deferred' strategy holds ABSOLUTE indices into `messages`, to
|
|
261
|
+
* rewrite those entries once the model has seen them in full. The splice
|
|
262
|
+
* above just invalidated every one of them, and the rewrite pass read
|
|
263
|
+
* `.role` off the resulting undefined -- a crash in the interactive
|
|
264
|
+
* CLI's shipping configuration ('deferred' + compaction). Nothing is
|
|
265
|
+
* lost by dropping them: the tool results they point at were collapsed
|
|
266
|
+
* into the summary and are not in `messages` any more. */
|
|
267
|
+
deferredOffloads.length = 0;
|
|
268
|
+
/* The fold has ALREADY happened by this point. Failing to RECORD it must
|
|
269
|
+
* not take the run with it -- the checkpoint store deliberately rejects
|
|
270
|
+
* rather than risk clobbering an existing CHECKPOINT.md, and a read-only
|
|
271
|
+
* workspace rejects too. Dying here would lose the whole conversation in
|
|
272
|
+
* order to save nothing. */
|
|
273
|
+
try {
|
|
274
|
+
await storage?.onFold?.({ summary: out.summary, directives: out.directives, collapsed: out.collapsed });
|
|
275
|
+
}
|
|
276
|
+
catch (e) {
|
|
277
|
+
alog('fold persist failed', e instanceof Error ? e.message : String(e));
|
|
278
|
+
}
|
|
279
|
+
emit({ type: 'checkpoint', collapsed: out.collapsedCount, checkpoint: out.summary });
|
|
280
|
+
compactGate = afterCompaction();
|
|
281
|
+
return 'folded';
|
|
282
|
+
}
|
|
283
|
+
catch (e) {
|
|
284
|
+
/* Re-arm so a later turn may try again rather than giving up for good.
|
|
285
|
+
* The floor is left as it was: it describes where the last SUCCESSFUL
|
|
286
|
+
* fold landed, and a failed attempt moved nothing. */
|
|
287
|
+
compactGate = { ...compactGate, armed: true };
|
|
288
|
+
foldError = e instanceof Error ? e.message : String(e);
|
|
289
|
+
alog('compaction failed', foldError);
|
|
290
|
+
return 'failed';
|
|
291
|
+
}
|
|
292
|
+
};
|
|
200
293
|
const usage = { promptTokens: 0, completionTokens: 0 };
|
|
201
294
|
/** Model calls made, and the largest single request among them. */
|
|
202
295
|
let calls = 0;
|
|
@@ -221,74 +314,26 @@ export async function runAgent(args) {
|
|
|
221
314
|
emit({ type: 'injected', content: typeof m.content === 'string' ? m.content : '' });
|
|
222
315
|
}
|
|
223
316
|
}
|
|
224
|
-
/* Rung-2
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
* the fatal 400. Fall back to reading the window off the messages. Only as
|
|
234
|
-
* a fallback: a real reading is always better than an estimate that cannot
|
|
235
|
-
* see the tool schemas. */
|
|
317
|
+
/* Rung-2 fold, BEFORE the request is built so the folded array is what goes
|
|
318
|
+
* on the wire. `fill` is last turn's prompt/window ratio; the gate refuses
|
|
319
|
+
* below the threshold and refuses again when there is nothing collapsible,
|
|
320
|
+
* because a fold that removes nothing still rewrites the cached prefix and
|
|
321
|
+
* re-bills everything after it. On turn 1 there is no usage reading yet, so
|
|
322
|
+
* `fill` is 0 and the gate could not fire before the first request -- which
|
|
323
|
+
* is how a resumed, already-oversized conversation took the fatal 400. Fall
|
|
324
|
+
* back to reading the window off the messages; only as a fallback: a real
|
|
325
|
+
* reading beats an estimate that cannot see the tool schemas. */
|
|
236
326
|
const gateFill = fill || estimateFill(messages, ctxWindow);
|
|
237
|
-
const
|
|
327
|
+
const prevGate = compactGate;
|
|
328
|
+
const gate = compactionDecision(gateFill, messages, compactGate, foldWindow);
|
|
238
329
|
compactGate = gate.next;
|
|
239
|
-
if (args.compaction && gate.compact) {
|
|
240
|
-
|
|
241
|
-
/*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
try {
|
|
247
|
-
const out = await compactHistory(messages, {
|
|
248
|
-
summarize: args.compaction.summarize,
|
|
249
|
-
anchor: args.compaction.anchor,
|
|
250
|
-
offloadOverBytes: compression && compression.mode !== 'off'
|
|
251
|
-
? effectiveThreshold(compression.mode, gateFill)
|
|
252
|
-
: undefined,
|
|
253
|
-
offload: toolCtx.recall
|
|
254
|
-
// Recorded under 'user' rather than a tool name: the RecallStore is
|
|
255
|
-
// indifferent to who authored the bulk, but the transcript should not
|
|
256
|
-
// claim a tool produced what a person pasted.
|
|
257
|
-
? async (content) => formatOffloadRef(await toolCtx.recall.record('user', content))
|
|
258
|
-
: undefined,
|
|
259
|
-
});
|
|
260
|
-
messages.splice(0, messages.length, ...out.messages);
|
|
261
|
-
/* The 'deferred' strategy holds ABSOLUTE indices into `messages`, to
|
|
262
|
-
* rewrite those entries once the model has seen them in full. The splice
|
|
263
|
-
* above just invalidated every one of them, and the rewrite pass read
|
|
264
|
-
* `.role` off the resulting undefined -- a crash in the interactive
|
|
265
|
-
* CLI's shipping configuration ('deferred' + compaction). Nothing is
|
|
266
|
-
* lost by dropping them: the tool results they point at were collapsed
|
|
267
|
-
* into the checkpoint and are not in `messages` any more. */
|
|
268
|
-
deferredOffloads.length = 0;
|
|
269
|
-
/* The compaction has ALREADY happened by this point. Failing to RECORD it
|
|
270
|
-
* must not take the run with it -- checkpointStore.append deliberately
|
|
271
|
-
* rejects rather than risk clobbering an existing CHECKPOINT.md, and a
|
|
272
|
-
* read-only workspace rejects too. Dying here would lose the whole
|
|
273
|
-
* conversation in order to save nothing. */
|
|
274
|
-
try {
|
|
275
|
-
await args.compaction.onCheckpoint?.(out.checkpoint);
|
|
276
|
-
}
|
|
277
|
-
catch (e) {
|
|
278
|
-
alog('checkpoint persist failed', e instanceof Error ? e.message : String(e));
|
|
279
|
-
}
|
|
280
|
-
emit({ type: 'checkpoint', collapsed: before - messages.length, checkpoint: out.checkpoint });
|
|
281
|
-
}
|
|
282
|
-
catch (e) {
|
|
283
|
-
/* Compaction failed (most likely the summarizer's own model call). The
|
|
284
|
-
* turn proceeds with the history it had -- exactly what would have
|
|
285
|
-
* happened had compaction never been configured. Re-arm so a later turn
|
|
286
|
-
* may try again rather than giving up on the run for good. */
|
|
287
|
-
/* The floor is left as it was: it describes where the last SUCCESSFUL
|
|
288
|
-
* compaction landed, and a failed attempt moved nothing. */
|
|
289
|
-
compactGate = { ...compactGate, armed: true };
|
|
290
|
-
alog('compaction failed', e instanceof Error ? e.message : String(e));
|
|
291
|
-
}
|
|
330
|
+
if (args.compaction && (gate.compact || forceFold)) {
|
|
331
|
+
forceFold = false;
|
|
332
|
+
/* The gate fired but there was nothing to fold (the only bulk is a
|
|
333
|
+
* pending tool call, held back): nothing was spent, so the latch is not
|
|
334
|
+
* either -- it fires again once there is something to collapse. */
|
|
335
|
+
if ((await fold(gateFill)) === 'nothing' && gate.compact)
|
|
336
|
+
compactGate = prevGate;
|
|
292
337
|
}
|
|
293
338
|
/* CONTEXT PRESSURE. After the compaction block, deliberately: if a
|
|
294
339
|
* compaction just ran, the window it drained is the one the agent should
|
|
@@ -357,6 +402,8 @@ export async function runAgent(args) {
|
|
|
357
402
|
turnAc = new AbortController();
|
|
358
403
|
if (signal.aborted)
|
|
359
404
|
turnAc.abort();
|
|
405
|
+
let overflowRetried = false;
|
|
406
|
+
let foldRetryOpen = false; // a 'retrying' fold-retry heal record awaits its outcome
|
|
360
407
|
for (let sAttempt = 0;;) {
|
|
361
408
|
try {
|
|
362
409
|
const result = await streamCompletion(client, {
|
|
@@ -369,6 +416,10 @@ export async function runAgent(args) {
|
|
|
369
416
|
}, turnAc.signal, (delta) => emit({ type: 'assistant-delta', delta }));
|
|
370
417
|
if (sAttempt > 0)
|
|
371
418
|
emit({ type: 'heal', record: { site: 'stream', kind: 'transient', strategy: 'retry-backoff', attempt: sAttempt, outcome: 'recovered', error: lastStreamErr } });
|
|
419
|
+
if (foldRetryOpen) {
|
|
420
|
+
foldRetryOpen = false;
|
|
421
|
+
emit({ type: 'heal', record: { site: 'stream', kind: 'overflow', strategy: 'fold-retry', attempt: 1, outcome: 'recovered', error: lastStreamErr } });
|
|
422
|
+
}
|
|
372
423
|
streamed = result;
|
|
373
424
|
break;
|
|
374
425
|
}
|
|
@@ -388,6 +439,26 @@ export async function runAgent(args) {
|
|
|
388
439
|
const msg = String(e?.message || e);
|
|
389
440
|
lastStreamErr = msg;
|
|
390
441
|
const kind = classifyStreamError(msg);
|
|
442
|
+
/* A context-length rejection is not transient: re-sending the same
|
|
443
|
+
* history fails the same way. Fold once and re-send (`fold` rewrote
|
|
444
|
+
* `messages` in place and streamCompletion reads it by reference); a
|
|
445
|
+
* second overflow means folding could not make it fit. */
|
|
446
|
+
if (kind === 'overflow') {
|
|
447
|
+
const outcome = overflowRetried ? null : await fold(1);
|
|
448
|
+
if (outcome === 'folded') {
|
|
449
|
+
overflowRetried = true;
|
|
450
|
+
foldRetryOpen = true;
|
|
451
|
+
emit({ type: 'heal', record: { site: 'stream', kind, strategy: 'fold-retry', attempt: sAttempt + 1, outcome: 'retrying', error: msg } });
|
|
452
|
+
continue;
|
|
453
|
+
}
|
|
454
|
+
emit({ type: 'heal', record: { site: 'stream', kind, strategy: 'give-up', attempt: sAttempt + 1, outcome: 'abandoned', error: msg } });
|
|
455
|
+
const ending = overflowRetried ? `${OVERFLOW_GIVE_UP} (${msg})`
|
|
456
|
+
: outcome === 'failed' ? `${OVERFLOW_FOLD_FAILED} (${foldError}; ${msg})`
|
|
457
|
+
: `${OVERFLOW_NO_FOLD} (${msg})`;
|
|
458
|
+
emit({ type: 'error', message: ending });
|
|
459
|
+
streamFail = 'error';
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
391
462
|
sAttempt++;
|
|
392
463
|
if (shouldRetryStream(kind, sAttempt, recovery)) {
|
|
393
464
|
emit({ type: 'heal', record: { site: 'stream', kind, strategy: 'retry-backoff', attempt: sAttempt, outcome: 'retrying', error: msg } });
|