knitbrain 0.1.1 → 0.2.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/README.md +66 -23
- package/dist/engine/agents.d.ts +4 -0
- package/dist/engine/agents.js +3 -2
- package/dist/engine/agents.js.map +1 -1
- package/dist/engine/feedback.js +1 -1
- package/dist/engine/feedback.js.map +1 -1
- package/dist/engine/meter.d.ts +2 -0
- package/dist/engine/meter.js +5 -0
- package/dist/engine/meter.js.map +1 -1
- package/dist/evals.d.ts +53 -0
- package/dist/evals.js +189 -0
- package/dist/evals.js.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -1
- package/dist/learn.d.ts +39 -0
- package/dist/learn.js +289 -0
- package/dist/learn.js.map +1 -0
- package/dist/lib.d.ts +37 -0
- package/dist/lib.js +17 -0
- package/dist/lib.js.map +1 -0
- package/dist/mcp/instructions.d.ts +7 -0
- package/dist/mcp/instructions.js +29 -0
- package/dist/mcp/instructions.js.map +1 -0
- package/dist/mcp/tools.js +50 -12
- package/dist/mcp/tools.js.map +1 -1
- package/dist/optimizer/ast.d.ts +11 -0
- package/dist/optimizer/ast.js +99 -29
- package/dist/optimizer/ast.js.map +1 -1
- package/dist/optimizer/code.js +1 -1
- package/dist/optimizer/code.js.map +1 -1
- package/dist/optimizer/router.d.ts +3 -1
- package/dist/optimizer/router.js +32 -7
- package/dist/optimizer/router.js.map +1 -1
- package/dist/optimizer/structured.d.ts +43 -0
- package/dist/optimizer/structured.js +196 -0
- package/dist/optimizer/structured.js.map +1 -0
- package/dist/optimizer/text.js +38 -7
- package/dist/optimizer/text.js.map +1 -1
- package/dist/optimizer/types.d.ts +4 -2
- package/dist/platforms.d.ts +11 -1
- package/dist/platforms.js +34 -1
- package/dist/platforms.js.map +1 -1
- package/dist/proxy/cache-aligner.d.ts +25 -4
- package/dist/proxy/cache-aligner.js +45 -4
- package/dist/proxy/cache-aligner.js.map +1 -1
- package/dist/proxy/optimize-request.d.ts +10 -0
- package/dist/proxy/optimize-request.js +96 -6
- package/dist/proxy/optimize-request.js.map +1 -1
- package/dist/proxy/server.js +2 -2
- package/dist/proxy/server.js.map +1 -1
- package/dist/server.js +5 -1
- package/dist/server.js.map +1 -1
- package/dist/setup.d.ts +1 -1
- package/dist/setup.js +30 -1
- package/dist/setup.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +11 -2
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured-output handlers — search results, build/test logs, unified
|
|
3
|
+
* diffs. These shapes dominated the misrouted residue of the code bucket
|
|
4
|
+
* (markdown reports, grep dumps, test runs tripping the loose isCode
|
|
5
|
+
* heuristic), so their detectors run BEFORE isCode in the router.
|
|
6
|
+
*
|
|
7
|
+
* Shared invariant: failure/error lines are NEVER elided — a compressed log
|
|
8
|
+
* that loses the FATAL line is worse than no compression at all.
|
|
9
|
+
*/
|
|
10
|
+
/** Lines that must survive any elision (failures live mid-output). */
|
|
11
|
+
export const IMPORTANT_LINE = /\b(FAIL(ED|URE)?|FATAL|ERROR|Error:|error(\s+TS\d+|\[E\d+\])?:|✗|✘|✖|npm ERR!|Exception|Traceback|AssertionError|fatal:|panic:|Segmentation fault|undefined reference)\b|^\s*(✗|✘|✖)/m;
|
|
12
|
+
/** Result-summary lines (test/build totals) — the other thing an agent always
|
|
13
|
+
* needs from a run. Rescued alongside errors by every elision path. */
|
|
14
|
+
export const RESULT_LINE = /^\s*(Tests?|Test (Suites?|Files)|Suites?|Duration|Time:|Ran \d+|\d+ (passing|failing|pending|tests? (passed|failed)))\b/m;
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Search results (grep -n / ripgrep / eslint style: path:line[:col]: content)
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
const SEARCH_LINE = /^(\S[^:\n]*):(\d+)(?::\d+)?[:-]/;
|
|
19
|
+
const MIN_SEARCH_LINES = 10;
|
|
20
|
+
/** Matches kept per file before the rest collapse to a count. */
|
|
21
|
+
const KEEP_PER_FILE = 2;
|
|
22
|
+
/** ≥50% of non-empty lines look like `path:line:` matches (and enough of them). */
|
|
23
|
+
export function isSearchResults(text) {
|
|
24
|
+
const lines = text.split("\n").filter((l) => l.trim().length > 0);
|
|
25
|
+
if (lines.length < MIN_SEARCH_LINES)
|
|
26
|
+
return false;
|
|
27
|
+
let hits = 0;
|
|
28
|
+
for (const l of lines)
|
|
29
|
+
if (SEARCH_LINE.test(l))
|
|
30
|
+
hits += 1;
|
|
31
|
+
return hits >= lines.length * 0.5 && hits >= MIN_SEARCH_LINES;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Collapse search output by file: keep the first matches per file (the
|
|
35
|
+
* locations), count the rest. Agents almost always act on file+line, not on
|
|
36
|
+
* the repeated match text — and the full set is one retrieve away.
|
|
37
|
+
*/
|
|
38
|
+
export function compressSearchResults(original, ccr) {
|
|
39
|
+
const lines = original.split("\n");
|
|
40
|
+
const out = [];
|
|
41
|
+
let currentFile = "";
|
|
42
|
+
let keptInFile = 0;
|
|
43
|
+
let droppedInFile = 0;
|
|
44
|
+
let files = 0;
|
|
45
|
+
let matches = 0;
|
|
46
|
+
const flushDrops = () => {
|
|
47
|
+
if (droppedInFile > 0)
|
|
48
|
+
out.push(` ⟪… +${droppedInFile} more matches in this file⟫`);
|
|
49
|
+
droppedInFile = 0;
|
|
50
|
+
};
|
|
51
|
+
for (const line of lines) {
|
|
52
|
+
const m = SEARCH_LINE.exec(line);
|
|
53
|
+
if (m === null) {
|
|
54
|
+
flushDrops();
|
|
55
|
+
currentFile = "";
|
|
56
|
+
if (line.trim().length > 0)
|
|
57
|
+
out.push(line);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
matches += 1;
|
|
61
|
+
if (m[1] !== currentFile) {
|
|
62
|
+
flushDrops();
|
|
63
|
+
currentFile = m[1];
|
|
64
|
+
keptInFile = 0;
|
|
65
|
+
files += 1;
|
|
66
|
+
}
|
|
67
|
+
if (keptInFile < KEEP_PER_FILE || IMPORTANT_LINE.test(line)) {
|
|
68
|
+
out.push(line);
|
|
69
|
+
keptInFile += 1;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
droppedInFile += 1;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
flushDrops();
|
|
76
|
+
const handle = ccr.put(original);
|
|
77
|
+
out.push(`⟪${matches} matches across ${files} files · exact original: ⟨ccr:${handle}⟩⟫`);
|
|
78
|
+
return { skeleton: out.join("\n"), handle, contentType: "search" };
|
|
79
|
+
}
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
// Build / test logs
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
const LOG_SIGNATURE = /^\[?\d{4}-\d{2}-\d{2}[T ]|^\d{2}:\d{2}:\d{2}|\b(INFO|DEBUG|WARN(ING)?|ERROR|TRACE)\b|^\s*(PASS|FAIL|ok|not ok)\b|^\s*[✓✔✗✘✖·❯]|\b(PASSED|FAILED|SKIPPED)\b|^={5,}|^-{5,}|^⎯{5,}|^\s*> Task |^npm (warn|notice|http|error)|^\s*at .+\(?.+:\d+:\d+\)?$|^\s*\d+\||^\s*(Test Files|Tests|Duration|Start at)\s|^\s*RUN\s+v\d|^>\s\S+@\d/;
|
|
84
|
+
const MIN_LOG_LINES = 20;
|
|
85
|
+
/** ≥30% of lines carry a log/test signature (timestamps, levels, test
|
|
86
|
+
* markers, vitest/jest code frames `123|`, stack frames, run summaries). */
|
|
87
|
+
export function isLogOutput(text) {
|
|
88
|
+
const lines = text.split("\n");
|
|
89
|
+
if (lines.length < MIN_LOG_LINES)
|
|
90
|
+
return false;
|
|
91
|
+
let hits = 0;
|
|
92
|
+
for (const l of lines)
|
|
93
|
+
if (LOG_SIGNATURE.test(l))
|
|
94
|
+
hits += 1;
|
|
95
|
+
return hits >= lines.length * 0.3;
|
|
96
|
+
}
|
|
97
|
+
const LOG_HEAD = 5;
|
|
98
|
+
const LOG_TAIL = 10;
|
|
99
|
+
/** Runs of routine lines shorter than this stay inline. */
|
|
100
|
+
const MIN_RUN = 4;
|
|
101
|
+
/**
|
|
102
|
+
* Log skeleton: keep the head (what ran), the tail (summaries land at the
|
|
103
|
+
* end), and EVERY error/failure line; collapse runs of routine lines to
|
|
104
|
+
* counted markers. The router still race-checks this against the generic
|
|
105
|
+
* text handler and keeps whichever is smaller.
|
|
106
|
+
*/
|
|
107
|
+
export function compressLog(original, ccr) {
|
|
108
|
+
const lines = original.split("\n");
|
|
109
|
+
const keep = new Array(lines.length).fill(false);
|
|
110
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
111
|
+
if (i < LOG_HEAD || i >= lines.length - LOG_TAIL)
|
|
112
|
+
keep[i] = true;
|
|
113
|
+
else if (IMPORTANT_LINE.test(lines[i]) || RESULT_LINE.test(lines[i]))
|
|
114
|
+
keep[i] = true;
|
|
115
|
+
}
|
|
116
|
+
const out = [];
|
|
117
|
+
let run = [];
|
|
118
|
+
const flushRun = () => {
|
|
119
|
+
if (run.length === 0)
|
|
120
|
+
return;
|
|
121
|
+
// Tiny gaps stay inline — the elision marker would cost more than it saves.
|
|
122
|
+
if (run.length < MIN_RUN)
|
|
123
|
+
out.push(...run);
|
|
124
|
+
else
|
|
125
|
+
out.push(`⟪… ${run.length} routine lines⟫`);
|
|
126
|
+
run = [];
|
|
127
|
+
};
|
|
128
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
129
|
+
if (keep[i]) {
|
|
130
|
+
flushRun();
|
|
131
|
+
out.push(lines[i]);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
run.push(lines[i]);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
flushRun();
|
|
138
|
+
const handle = ccr.put(original);
|
|
139
|
+
out.push(`⟪exact original: ⟨ccr:${handle}⟩⟫`);
|
|
140
|
+
return { skeleton: out.join("\n"), handle, contentType: "log" };
|
|
141
|
+
}
|
|
142
|
+
// ---------------------------------------------------------------------------
|
|
143
|
+
// Unified diffs
|
|
144
|
+
// ---------------------------------------------------------------------------
|
|
145
|
+
const DIFF_FILE_HEADER = /^(diff --git |index [0-9a-f]+\.\.|--- |\+\+\+ )/;
|
|
146
|
+
const HUNK_HEADER = /^@@ -\d+(,\d+)? \+\d+(,\d+)? @@/;
|
|
147
|
+
/** Unified diff: a `diff --git` header, or ---/+++ pair plus a hunk header. */
|
|
148
|
+
export function isDiff(text) {
|
|
149
|
+
const head = text.slice(0, 4000);
|
|
150
|
+
if (/^diff --git /m.test(head))
|
|
151
|
+
return true;
|
|
152
|
+
return /^--- /m.test(head) && /^\+\+\+ /m.test(head) && HUNK_HEADER.test(text.split("\n").find((l) => l.startsWith("@@")) ?? "");
|
|
153
|
+
}
|
|
154
|
+
/** Hunk bodies longer than this elide to a ±count marker. */
|
|
155
|
+
const MAX_INLINE_HUNK = 14;
|
|
156
|
+
/**
|
|
157
|
+
* Diff skeleton: keep file headers and hunk headers (the WHERE), keep error
|
|
158
|
+
* lines, elide long hunk bodies to `⟪… +a/-b/~c lines⟫` (the churn size).
|
|
159
|
+
* Reviewers and agents mostly need which files/regions changed and how much;
|
|
160
|
+
* the full patch is one retrieve away.
|
|
161
|
+
*/
|
|
162
|
+
export function compressDiff(original, ccr) {
|
|
163
|
+
const lines = original.split("\n");
|
|
164
|
+
const out = [];
|
|
165
|
+
let body = [];
|
|
166
|
+
const flushBody = () => {
|
|
167
|
+
if (body.length === 0)
|
|
168
|
+
return;
|
|
169
|
+
if (body.length <= MAX_INLINE_HUNK) {
|
|
170
|
+
out.push(...body);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
const adds = body.filter((l) => l.startsWith("+")).length;
|
|
174
|
+
const dels = body.filter((l) => l.startsWith("-")).length;
|
|
175
|
+
const ctx = body.length - adds - dels;
|
|
176
|
+
const rescued = body.filter((l) => IMPORTANT_LINE.test(l));
|
|
177
|
+
out.push(`⟪… hunk elided: +${adds}/-${dels} lines, ${ctx} context⟫`);
|
|
178
|
+
out.push(...rescued);
|
|
179
|
+
}
|
|
180
|
+
body = [];
|
|
181
|
+
};
|
|
182
|
+
for (const line of lines) {
|
|
183
|
+
if (DIFF_FILE_HEADER.test(line) || HUNK_HEADER.test(line)) {
|
|
184
|
+
flushBody();
|
|
185
|
+
out.push(line);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
body.push(line);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
flushBody();
|
|
192
|
+
const handle = ccr.put(original);
|
|
193
|
+
out.push(`⟪exact diff: ⟨ccr:${handle}⟩⟫`);
|
|
194
|
+
return { skeleton: out.join("\n"), handle, contentType: "diff" };
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=structured.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structured.js","sourceRoot":"","sources":["../../src/optimizer/structured.ts"],"names":[],"mappings":"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"}
|
package/dist/optimizer/text.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { IMPORTANT_LINE, RESULT_LINE } from "./structured.js";
|
|
1
2
|
/** Below this many lines, line-dedup isn't worth attempting. */
|
|
2
3
|
const MIN_LINES_FOR_DEDUP = 20;
|
|
3
4
|
/**
|
|
@@ -24,8 +25,11 @@ export function compressText(original, ccr) {
|
|
|
24
25
|
const counts = new Map();
|
|
25
26
|
const firstSeen = new Map();
|
|
26
27
|
const order = [];
|
|
28
|
+
let uniq = 0;
|
|
27
29
|
for (const line of lines) {
|
|
28
|
-
|
|
30
|
+
// Error lines never collapse into a ×N template: assertion failures
|
|
31
|
+
// differ exactly in the bits the normalizer erases (the values).
|
|
32
|
+
const key = IMPORTANT_LINE.test(line) ? `!imp${(uniq += 1)}` : normalize(line);
|
|
29
33
|
const seen = counts.get(key);
|
|
30
34
|
if (seen === undefined) {
|
|
31
35
|
counts.set(key, 1);
|
|
@@ -75,14 +79,41 @@ const TAIL_SENTENCES = 1;
|
|
|
75
79
|
* Returns null when there aren't enough sentences to anchor.
|
|
76
80
|
*/
|
|
77
81
|
export function compressShortProse(original, ccr) {
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
// Find sentence boundaries by OFFSET so head/tail keep the original bytes
|
|
83
|
+
// verbatim (joining split sentences with " " used to break mid-line after
|
|
84
|
+
// colons, splitting error lines across the elision boundary).
|
|
85
|
+
const re = new RegExp(SENTENCE_SPLIT.source, "g");
|
|
86
|
+
const bounds = [];
|
|
87
|
+
for (let m = re.exec(original); m !== null; m = re.exec(original)) {
|
|
88
|
+
bounds.push({ end: m.index, next: m.index + m[0].length });
|
|
89
|
+
}
|
|
90
|
+
if (bounds.length + 1 < MIN_SENTENCES)
|
|
80
91
|
return null;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
92
|
+
// Snap both boundaries to LINE breaks: a sentence boundary can land
|
|
93
|
+
// mid-line (": 1"), and splitting a line across the elision turns one
|
|
94
|
+
// error line into two fragments. Lines are the unit of fidelity.
|
|
95
|
+
const tailBound = bounds[bounds.length - TAIL_SENTENCES];
|
|
96
|
+
let headEnd = original.indexOf("\n", bounds[HEAD_SENTENCES - 1].end);
|
|
97
|
+
if (headEnd === -1)
|
|
98
|
+
headEnd = bounds[HEAD_SENTENCES - 1].end;
|
|
99
|
+
let tailStart = original.lastIndexOf("\n", tailBound.next) + 1;
|
|
100
|
+
if (tailStart <= headEnd) {
|
|
101
|
+
// Single-line prose (no newline between the anchors): line snapping is
|
|
102
|
+
// moot — cut at the sentence boundaries directly.
|
|
103
|
+
headEnd = bounds[HEAD_SENTENCES - 1].end;
|
|
104
|
+
tailStart = tailBound.next;
|
|
105
|
+
}
|
|
106
|
+
const head = original.slice(0, headEnd);
|
|
107
|
+
const tail = original.slice(tailStart);
|
|
108
|
+
const middle = original.slice(headEnd, tailStart);
|
|
109
|
+
// Error/failure and result-summary LINES are never elided — same invariant
|
|
110
|
+
// as every other handler (a skeleton that loses the error is worse than no
|
|
111
|
+
// skeleton). Whole lines, so the exact original text survives.
|
|
112
|
+
const rescued = middle.split("\n").filter((l) => IMPORTANT_LINE.test(l) || RESULT_LINE.test(l));
|
|
113
|
+
const elided = bounds.length + 1 - HEAD_SENTENCES - TAIL_SENTENCES;
|
|
84
114
|
const handle = ccr.put(original);
|
|
85
|
-
const
|
|
115
|
+
const rescueBlock = rescued.length > 0 ? `\n${rescued.join("\n")}` : "";
|
|
116
|
+
const skeleton = `${head}\n⟪… ${elided} sentences elided · exact original: ⟨ccr:${handle}⟩ …⟫${rescueBlock}\n${tail}`;
|
|
86
117
|
return { skeleton, handle, contentType: "prose" };
|
|
87
118
|
}
|
|
88
119
|
//# sourceMappingURL=text.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/optimizer/text.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/optimizer/text.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9D,gEAAgE;AAChE,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAE/B;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,GAAa;IAC1D,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEnC,uEAAuE;IACvE,qEAAqE;IACrE,kEAAkE;IAClE,MAAM,SAAS,GAAG,CAAC,CAAS,EAAU,EAAE,CACtC,CAAC;SACE,OAAO,CAAC,iCAAiC,EAAE,MAAM,CAAC;SAClD,OAAO,CAAC,qBAAqB,EAAE,OAAO,CAAC;SACvC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAE5B,IAAI,IAAY,CAAC;IACjB,IAAI,KAAK,CAAC,MAAM,IAAI,mBAAmB,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;QACzC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC5C,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,oEAAoE;YACpE,iEAAiE;YACjE,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC/E,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC7B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;gBACnB,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;gBACzB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;QACD,8EAA8E;QAC9E,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC;YACxC,IAAI,GAAG,KAAK;iBACT,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;gBACX,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;gBAC3B,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;gBACjC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;YAC7E,CAAC,CAAC;iBACD,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,IAAI,IAAI,MAAM,KAAK,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,0CAA0C,CAAC;QAC/F,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,IAAI,GAAG,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC9E,MAAM,QAAQ,GACZ,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,UAAU,UAAU,MAAM,GAAG,CAAC;IACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;AACnD,CAAC;AAED,mFAAmF;AACnF,MAAM,cAAc,GAAG,kCAAkC,CAAC;AAC1D;;8EAE8E;AAC9E,MAAM,aAAa,GAAG,CAAC,CAAC;AACxB,MAAM,cAAc,GAAG,CAAC,CAAC;AACzB,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB,EAAE,GAAa;IAChE,0EAA0E;IAC1E,0EAA0E;IAC1E,8DAA8D;IAC9D,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAClD,MAAM,MAAM,GAAyC,EAAE,CAAC;IACxD,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClE,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,aAAa;QAAE,OAAO,IAAI,CAAC;IAEnD,oEAAoE;IACpE,sEAAsE;IACtE,iEAAiE;IACjE,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,cAAc,CAAE,CAAC;IAC1D,IAAI,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,cAAc,GAAG,CAAC,CAAE,CAAC,GAAG,CAAC,CAAC;IACtE,IAAI,OAAO,KAAK,CAAC,CAAC;QAAE,OAAO,GAAG,MAAM,CAAC,cAAc,GAAG,CAAC,CAAE,CAAC,GAAG,CAAC;IAC9D,IAAI,SAAS,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/D,IAAI,SAAS,IAAI,OAAO,EAAE,CAAC;QACzB,uEAAuE;QACvE,kDAAkD;QAClD,OAAO,GAAG,MAAM,CAAC,cAAc,GAAG,CAAC,CAAE,CAAC,GAAG,CAAC;QAC1C,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC;IAC7B,CAAC;IACD,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAClD,2EAA2E;IAC3E,2EAA2E;IAC3E,+DAA+D;IAC/D,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAChG,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,cAAc,GAAG,cAAc,CAAC;IACnE,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjC,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxE,MAAM,QAAQ,GAAG,GAAG,IAAI,QAAQ,MAAM,4CAA4C,MAAM,OAAO,WAAW,KAAK,IAAI,EAAE,CAAC;IACtH,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;AACpD,CAAC"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/** Content categories the router can detect and the handlers produce.
|
|
2
2
|
* "prose" is produced (not detected): short prose that took the sentence
|
|
3
|
-
* anchor — its own TOIN kind so over-retrieval backs it off independently.
|
|
4
|
-
|
|
3
|
+
* anchor — its own TOIN kind so over-retrieval backs it off independently.
|
|
4
|
+
* "search" / "log" / "diff" are structured shapes with dedicated handlers
|
|
5
|
+
* (detected before the looser code heuristic). */
|
|
6
|
+
export type ContentType = "json" | "code" | "text" | "prose" | "search" | "log" | "diff";
|
|
5
7
|
/** Output of compressing one payload: the skeleton view + its CCR handle. */
|
|
6
8
|
export interface CompressResult {
|
|
7
9
|
/** The compressed, still-readable skeleton (carries the ⟨ccr:…⟩ handle). */
|
package/dist/platforms.d.ts
CHANGED
|
@@ -34,8 +34,18 @@ export declare const KNITBRAIN_HOOKS: {
|
|
|
34
34
|
export declare function claudeArtifacts(cfg: SetupConfig): Artifact[];
|
|
35
35
|
/** Cursor: .cursor/mcp.json + an always-on rules file. */
|
|
36
36
|
export declare function cursorArtifacts(): Artifact[];
|
|
37
|
-
/**
|
|
37
|
+
/** Copilot CLI: MCP config is global (~/.copilot) — print a snippet. The
|
|
38
|
+
* project-side .github/instructions file is shared with VS Code Copilot. */
|
|
39
|
+
export declare function copilotSnippet(): string;
|
|
40
|
+
/** VS Code (GitHub Copilot agent mode): .vscode/mcp.json (uses "servers"
|
|
41
|
+
* key) + .github/instructions — the native Copilot instruction surface. */
|
|
38
42
|
export declare function vscodeArtifacts(): Artifact[];
|
|
43
|
+
/** Windsurf: project rules are native; MCP config is global (snippet). */
|
|
44
|
+
export declare function windsurfArtifacts(): Artifact[];
|
|
45
|
+
/** Windsurf's MCP config lives in ~/.codeium/windsurf — never clobber it. */
|
|
46
|
+
export declare function windsurfSnippet(): string;
|
|
47
|
+
/** Zed: MCP servers live in global settings — print a snippet. */
|
|
48
|
+
export declare function zedSnippet(): string;
|
|
39
49
|
/** Codex CLI: global config — print a snippet rather than touching ~/.codex. */
|
|
40
50
|
export declare function codexSnippet(cfg: SetupConfig): string;
|
|
41
51
|
/**
|
package/dist/platforms.js
CHANGED
|
@@ -68,7 +68,16 @@ export function cursorArtifacts() {
|
|
|
68
68
|
},
|
|
69
69
|
];
|
|
70
70
|
}
|
|
71
|
-
/**
|
|
71
|
+
/** Copilot CLI: MCP config is global (~/.copilot) — print a snippet. The
|
|
72
|
+
* project-side .github/instructions file is shared with VS Code Copilot. */
|
|
73
|
+
export function copilotSnippet() {
|
|
74
|
+
return [
|
|
75
|
+
"# Add to ~/.copilot/mcp-config.json :",
|
|
76
|
+
'{ "mcpServers": { "knitbrain": { "type": "local", "command": "knitbrain", "tools": ["*"] } } }',
|
|
77
|
+
].join("\n");
|
|
78
|
+
}
|
|
79
|
+
/** VS Code (GitHub Copilot agent mode): .vscode/mcp.json (uses "servers"
|
|
80
|
+
* key) + .github/instructions — the native Copilot instruction surface. */
|
|
72
81
|
export function vscodeArtifacts() {
|
|
73
82
|
return [
|
|
74
83
|
{ path: ".vscode/mcp.json", content: "", mode: "json-merge-mcp" },
|
|
@@ -79,6 +88,30 @@ export function vscodeArtifacts() {
|
|
|
79
88
|
},
|
|
80
89
|
];
|
|
81
90
|
}
|
|
91
|
+
/** Windsurf: project rules are native; MCP config is global (snippet). */
|
|
92
|
+
export function windsurfArtifacts() {
|
|
93
|
+
return [
|
|
94
|
+
{
|
|
95
|
+
path: ".windsurf/rules/knitbrain.md",
|
|
96
|
+
mode: "write",
|
|
97
|
+
content: `---\ntrigger: always_on\n---\n\n${NOTATION_GUIDE}\n\n${TERSE_MODE}\n`,
|
|
98
|
+
},
|
|
99
|
+
];
|
|
100
|
+
}
|
|
101
|
+
/** Windsurf's MCP config lives in ~/.codeium/windsurf — never clobber it. */
|
|
102
|
+
export function windsurfSnippet() {
|
|
103
|
+
return [
|
|
104
|
+
"# Add to ~/.codeium/windsurf/mcp_config.json :",
|
|
105
|
+
'{ "mcpServers": { "knitbrain": { "command": "knitbrain" } } }',
|
|
106
|
+
].join("\n");
|
|
107
|
+
}
|
|
108
|
+
/** Zed: MCP servers live in global settings — print a snippet. */
|
|
109
|
+
export function zedSnippet() {
|
|
110
|
+
return [
|
|
111
|
+
"# Add to Zed settings.json (cmd-,) :",
|
|
112
|
+
'"context_servers": { "knitbrain": { "command": { "path": "knitbrain" } } }',
|
|
113
|
+
].join("\n");
|
|
114
|
+
}
|
|
82
115
|
/** Codex CLI: global config — print a snippet rather than touching ~/.codex. */
|
|
83
116
|
export function codexSnippet(cfg) {
|
|
84
117
|
return [
|
package/dist/platforms.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platforms.js","sourceRoot":"","sources":["../src/platforms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAkB1C,uEAAuE;AACvE,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,UAAU,EAAE;QACV;YACE,OAAO,EAAE,MAAM;YACf,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,2BAA2B,EAAE,CAAC;SACnE;KACF;IACD,UAAU,EAAE;QACV;YACE,OAAO,EAAE,EAAE;YACX,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,2BAA2B,EAAE,CAAC;SACnE;KACF;CACO,CAAC;AAEX,MAAM,cAAc,GAAG;;mZAE4X,CAAC;AAEpZ;;;;GAIG;AACH,MAAM,UAAU,GAAG;;;;;;;;;;;kEAW+C,CAAC;AAEnE,sDAAsD;AACtD,MAAM,UAAU,eAAe,CAAC,GAAgB;IAC9C,OAAO;QACL,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;QAC1D,EAAE,IAAI,EAAE,uBAAuB,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE;QACxE;YACE,IAAI,EAAE,2BAA2B;YACjC,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,iSAAiS;SAC3S;QACD;YACE,IAAI,EAAE,6BAA6B;YACnC,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,4WAA4W;SACtX;QACD;YACE,IAAI,EAAE,4BAA4B;YAClC,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,mBAAmB,cAAc,OAAO,UAAU,gGAAgG,GAAG,CAAC,QAAQ,CAAC,oBAAoB,CAAC,OAAO;SACrM;KACF,CAAC;AACJ,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,eAAe;IAC7B,OAAO;QACL,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;QACjE;YACE,IAAI,EAAE,6BAA6B;YACnC,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,uFAAuF,cAAc,OAAO,UAAU,IAAI;SACpI;KACF,CAAC;AACJ,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"platforms.js","sourceRoot":"","sources":["../src/platforms.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CacheAligner —
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* CacheAligner — make the request's stable prefix actually stable, so the
|
|
3
|
+
* provider's KV-cache hits across turns.
|
|
4
|
+
*
|
|
5
|
+
* Three meaning-preserving levers:
|
|
6
|
+
* 1. whitespace normalization (collapse trailing whitespace + blank runs);
|
|
7
|
+
* 2. dynamic-content extraction — lines like "Today's date is 2026-06-11"
|
|
8
|
+
* change every session and sit near the TOP of system prompts, breaking
|
|
9
|
+
* byte-identity for everything after them. They move to a marked section
|
|
10
|
+
* at the END of the prompt (content kept verbatim, position changes);
|
|
11
|
+
* 3. Anthropic cache_control breakpoints — inserted only when the client
|
|
12
|
+
* didn't set its own (never fight the host's caching strategy).
|
|
13
|
+
*
|
|
14
|
+
* Compression upstream is deterministic (same text → same skeleton), so
|
|
15
|
+
* optimized history prefixes stay byte-stable turn over turn.
|
|
6
16
|
*/
|
|
7
17
|
export declare function normalizePrefix(prefix: string): string;
|
|
8
18
|
/** Stable content hash of the normalized prefix — for cache-hit metrics. */
|
|
9
19
|
export declare function prefixHash(prefix: string): string;
|
|
20
|
+
export interface AlignResult {
|
|
21
|
+
text: string;
|
|
22
|
+
/** Number of volatile lines moved to the tail section. */
|
|
23
|
+
moved: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Move volatile lines out of the prefix to a marked tail section. Content is
|
|
27
|
+
* preserved verbatim — only position changes — and the result is idempotent
|
|
28
|
+
* (already-aligned prompts pass through unchanged).
|
|
29
|
+
*/
|
|
30
|
+
export declare function alignDynamicContent(text: string): AlignResult;
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import { sha256 } from "../ccr/store.js";
|
|
2
2
|
/**
|
|
3
|
-
* CacheAligner —
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* CacheAligner — make the request's stable prefix actually stable, so the
|
|
4
|
+
* provider's KV-cache hits across turns.
|
|
5
|
+
*
|
|
6
|
+
* Three meaning-preserving levers:
|
|
7
|
+
* 1. whitespace normalization (collapse trailing whitespace + blank runs);
|
|
8
|
+
* 2. dynamic-content extraction — lines like "Today's date is 2026-06-11"
|
|
9
|
+
* change every session and sit near the TOP of system prompts, breaking
|
|
10
|
+
* byte-identity for everything after them. They move to a marked section
|
|
11
|
+
* at the END of the prompt (content kept verbatim, position changes);
|
|
12
|
+
* 3. Anthropic cache_control breakpoints — inserted only when the client
|
|
13
|
+
* didn't set its own (never fight the host's caching strategy).
|
|
14
|
+
*
|
|
15
|
+
* Compression upstream is deterministic (same text → same skeleton), so
|
|
16
|
+
* optimized history prefixes stay byte-stable turn over turn.
|
|
7
17
|
*/
|
|
8
18
|
export function normalizePrefix(prefix) {
|
|
9
19
|
return prefix.replace(/[ \t]+\n/g, "\n").replace(/\n{3,}/g, "\n\n");
|
|
@@ -12,4 +22,35 @@ export function normalizePrefix(prefix) {
|
|
|
12
22
|
export function prefixHash(prefix) {
|
|
13
23
|
return sha256(normalizePrefix(prefix));
|
|
14
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Strong volatile-line signals only: explicit "today/current date/time"
|
|
27
|
+
* phrasing, or a line that is mostly a timestamp/UUID. A date appearing
|
|
28
|
+
* inside instructions ("use ISO dates like 2024-01-01") stays put unless the
|
|
29
|
+
* phrasing marks it as session state.
|
|
30
|
+
*/
|
|
31
|
+
const DYNAMIC_LINE = /\b(today'?s? (date )?is|the current (date|time|month) is|current (date|time):|as of (today|now)[,:]|session id[:=]|generated at[:=]?)\b/i;
|
|
32
|
+
const MOSTLY_TIMESTAMP = /^\s*[\d:T Z.+-]{8,40}\s*$|^\s*[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\s*$/i;
|
|
33
|
+
const MARKER = "[session context — moved here so the prompt prefix stays cache-stable]";
|
|
34
|
+
/**
|
|
35
|
+
* Move volatile lines out of the prefix to a marked tail section. Content is
|
|
36
|
+
* preserved verbatim — only position changes — and the result is idempotent
|
|
37
|
+
* (already-aligned prompts pass through unchanged).
|
|
38
|
+
*/
|
|
39
|
+
export function alignDynamicContent(text) {
|
|
40
|
+
if (text.includes(MARKER))
|
|
41
|
+
return { text, moved: 0 }; // already aligned (idempotent)
|
|
42
|
+
const lines = text.split("\n");
|
|
43
|
+
const stable = [];
|
|
44
|
+
const movedLines = [];
|
|
45
|
+
for (const line of lines) {
|
|
46
|
+
if (DYNAMIC_LINE.test(line) || MOSTLY_TIMESTAMP.test(line))
|
|
47
|
+
movedLines.push(line);
|
|
48
|
+
else
|
|
49
|
+
stable.push(line);
|
|
50
|
+
}
|
|
51
|
+
if (movedLines.length === 0)
|
|
52
|
+
return { text: normalizePrefix(text), moved: 0 };
|
|
53
|
+
const aligned = `${normalizePrefix(stable.join("\n")).replace(/\n+$/, "")}\n\n${MARKER}\n${movedLines.join("\n")}`;
|
|
54
|
+
return { text: aligned, moved: movedLines.length };
|
|
55
|
+
}
|
|
15
56
|
//# sourceMappingURL=cache-aligner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache-aligner.js","sourceRoot":"","sources":["../../src/proxy/cache-aligner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC
|
|
1
|
+
{"version":3,"file":"cache-aligner.js","sourceRoot":"","sources":["../../src/proxy/cache-aligner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,OAAO,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AACtE,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,OAAO,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;AACzC,CAAC;AAED;;;;;GAKG;AACH,MAAM,YAAY,GAChB,0IAA0I,CAAC;AAC7I,MAAM,gBAAgB,GACpB,iGAAiG,CAAC;AAQpG,MAAM,MAAM,GAAG,wEAAwE,CAAC;AAExF;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,+BAA+B;IAErF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;;YAC7E,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IACD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,eAAe,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAE9E,MAAM,OAAO,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,MAAM,KAAK,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IACnH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC;AACrD,CAAC"}
|
|
@@ -27,6 +27,10 @@ export interface OptimizeOptions {
|
|
|
27
27
|
minBlockChars?: number;
|
|
28
28
|
/** Whether short-prose sentence anchoring may apply (TOIN-gated by callers). */
|
|
29
29
|
allowProse?: boolean;
|
|
30
|
+
/** Wire protocol — enables provider-specific cache strategy (cache_control). */
|
|
31
|
+
provider?: "anthropic" | "openai";
|
|
32
|
+
/** CacheAligner master switch (default on). */
|
|
33
|
+
cacheAlign?: boolean;
|
|
30
34
|
}
|
|
31
35
|
export interface ProxyStats {
|
|
32
36
|
originalTokens: number;
|
|
@@ -38,6 +42,12 @@ export interface ProxyStats {
|
|
|
38
42
|
handles: string[];
|
|
39
43
|
/** Content kind per compressed handle — lets callers feed TOIN (onCompress). */
|
|
40
44
|
kinds: Record<string, ContentType>;
|
|
45
|
+
/** Volatile lines CacheAligner moved out of the system prefix. */
|
|
46
|
+
dynamicMoved: number;
|
|
47
|
+
/** Anthropic cache_control breakpoints we inserted (0 if client had its own). */
|
|
48
|
+
cacheBreakpoints: number;
|
|
49
|
+
/** Hash of the aligned system prefix — equal across turns ⇒ cache-hittable. */
|
|
50
|
+
prefixHash: string;
|
|
41
51
|
}
|
|
42
52
|
/**
|
|
43
53
|
* Optimize an LLM request: protect the recent turns + the current intent +
|