acp-kernel 0.0.79 → 0.0.80-pr.334.200

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/absorb.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { type LatestProtected } from "./protected.js";
1
2
  import type { AbsorbConfig, Config, CompressionState, CoreMessage } from "./types.js";
2
3
  /**
3
4
  * Instant tool-result absorption ("absorb") — the middle layer between
@@ -17,7 +18,7 @@ export declare function buildAbsorbPrompt(ref: string, tokens: number, toolName?
17
18
  export declare function buildAbsorbSystemPrompt(toolName?: string): string;
18
19
  /** True when a tool-result message is in scope for absorption prompting:
19
20
  * a tool-result of a non-ACP, non-excluded, non-protected tool. */
20
- export declare function isAbsorbCandidate(msg: CoreMessage, config: Config): boolean;
21
+ export declare function isAbsorbCandidate(msg: CoreMessage, config: Config, latest?: LatestProtected): boolean;
21
22
  /** Drop tool-call + tool-result pairs recorded in state.absorbed. Both halves
22
23
  * go together so the provider-visible conversation stays structurally valid;
23
24
  * prune's orphan stripping cleans up any straddling leftovers. */
@@ -1 +1 @@
1
- {"version":3,"file":"absorb.d.ts","sourceRoot":"","sources":["../src/absorb.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,YAAY,EAEZ,MAAM,EACN,gBAAgB,EAChB,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;GASG;AAEH,eAAO,MAAM,oBAAoB,iBAAiB,CAAC;AAEnD,eAAO,MAAM,qBAAqB,EAAE,YAMnC,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAEhE;AAQD,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,MAAyB,GAClC,MAAM,CAQR;AAED,8DAA8D;AAC9D,wBAAgB,uBAAuB,CACrC,QAAQ,GAAE,MAAyB,GAClC,MAAM,CAIR;AAWD;oEACoE;AACpE,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAS3E;AAED;;mEAEmE;AACnE,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,gBAAgB,GACtB,WAAW,EAAE,CASf;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;sEAGsE;AACtE,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,gBAAgB,EACvB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GACpC,yBAAyB,CAmC3B;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;4DAE4D;AAC5D,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,OAAO,EACd,MAAM,CAAC,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GACjC,YAAY,GAAG,IAAI,CA+BrB;AAaD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACxC;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,gBAAgB,CAAC;IACxB,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;0DAE0D;AAC1D,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,aAAa,CAsG7D"}
1
+ {"version":3,"file":"absorb.d.ts","sourceRoot":"","sources":["../src/absorb.ts"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EACV,YAAY,EAEZ,MAAM,EACN,gBAAgB,EAChB,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;GASG;AAEH,eAAO,MAAM,oBAAoB,iBAAiB,CAAC;AAEnD,eAAO,MAAM,qBAAqB,EAAE,YAMnC,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAEhE;AAQD,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,MAAyB,GAClC,MAAM,CAQR;AAED,8DAA8D;AAC9D,wBAAgB,uBAAuB,CACrC,QAAQ,GAAE,MAAyB,GAClC,MAAM,CAIR;AAWD;oEACoE;AACpE,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,eAAe,GACvB,OAAO,CAUT;AAED;;mEAEmE;AACnE,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,gBAAgB,GACtB,WAAW,EAAE,CASf;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;sEAGsE;AACtE,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,gBAAgB,EACvB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GACpC,yBAAyB,CAoC3B;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;4DAE4D;AAC5D,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,OAAO,EACd,MAAM,CAAC,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GACjC,YAAY,GAAG,IAAI,CA+BrB;AAaD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACxC;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,gBAAgB,CAAC;IACxB,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;0DAE0D;AAC1D,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,aAAa,CA4G7D"}
@@ -13,6 +13,8 @@ function createInitialState() {
13
13
  },
14
14
  stats: { tokensCompressed: 0, compressionCount: 0, absorbedTokens: 0 },
15
15
  absorbed: [],
16
+ rules: [],
17
+ nextRuleId: 1,
16
18
  nextBlockId: 1,
17
19
  nextRunId: 1
18
20
  };
@@ -68,4 +70,4 @@ export {
68
70
  highestActiveTier,
69
71
  advanceSurvival
70
72
  };
71
- //# sourceMappingURL=chunk-UX4LINT7.js.map
73
+ //# sourceMappingURL=chunk-5TQA7ZQM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/state.ts"],"sourcesContent":["import type { CompressionBlock, CompressionState } from \"./types.js\";\n\nexport function createInitialState(): CompressionState {\n return {\n blocks: [],\n messageRefs: { byRaw: {}, byRef: {} },\n tokenSnapshot: {},\n nudge: {\n lastPerMessageNudgeTokens: 0,\n lastNudgeShownTokens: 0,\n baselineTokens: 0,\n anchors: {},\n lastShownByTier: {},\n },\n stats: { tokensCompressed: 0, compressionCount: 0, absorbedTokens: 0 },\n absorbed: [],\n rules: [],\n nextRuleId: 1,\n nextBlockId: 1,\n nextRunId: 1,\n };\n}\n\nexport function allocateBlockId(state: CompressionState): string {\n const id = state.nextBlockId;\n state.nextBlockId = Math.max(1, id) + 1;\n return `b${id}`;\n}\n\nexport function allocateRunId(state: CompressionState): string {\n const id = state.nextRunId;\n state.nextRunId = Math.max(1, id) + 1;\n return `r${id}`;\n}\n\nexport function blockById(\n state: CompressionState,\n blockId: string,\n): CompressionBlock | undefined {\n return state.blocks.find((block) => block.blockId === blockId);\n}\n\nexport function activeBlocks(state: CompressionState): CompressionBlock[] {\n return state.blocks.filter((block) => block.active);\n}\n\nexport function coveredMessageIds(state: CompressionState): Set<string> {\n const covered = new Set<string>();\n for (const block of state.blocks) {\n if (!block.active) continue;\n for (const id of block.effectiveMessageIds) covered.add(id);\n }\n return covered;\n}\n\nexport function highestActiveTier(state: CompressionState): 0 | 1 | 2 | 3 {\n let highest: 0 | 1 | 2 | 3 = 0;\n for (const block of state.blocks) {\n if (block.active && block.tier > highest) highest = block.tier;\n }\n return highest;\n}\n\nexport function advanceSurvival(\n state: CompressionState,\n promotionThreshold: number,\n): void {\n for (const block of state.blocks) {\n if (!block.active) continue;\n block.survivedCount += 1;\n if (block.survivedCount >= promotionThreshold) {\n block.generation = \"old\";\n }\n }\n}\n"],"mappings":";AAEO,SAAS,qBAAuC;AACrD,SAAO;AAAA,IACL,QAAQ,CAAC;AAAA,IACT,aAAa,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,EAAE;AAAA,IACpC,eAAe,CAAC;AAAA,IAChB,OAAO;AAAA,MACL,2BAA2B;AAAA,MAC3B,sBAAsB;AAAA,MACtB,gBAAgB;AAAA,MAChB,SAAS,CAAC;AAAA,MACV,iBAAiB,CAAC;AAAA,IACpB;AAAA,IACA,OAAO,EAAE,kBAAkB,GAAG,kBAAkB,GAAG,gBAAgB,EAAE;AAAA,IACrE,UAAU,CAAC;AAAA,IACX,OAAO,CAAC;AAAA,IACR,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,WAAW;AAAA,EACb;AACF;AAEO,SAAS,gBAAgB,OAAiC;AAC/D,QAAM,KAAK,MAAM;AACjB,QAAM,cAAc,KAAK,IAAI,GAAG,EAAE,IAAI;AACtC,SAAO,IAAI,EAAE;AACf;AAEO,SAAS,cAAc,OAAiC;AAC7D,QAAM,KAAK,MAAM;AACjB,QAAM,YAAY,KAAK,IAAI,GAAG,EAAE,IAAI;AACpC,SAAO,IAAI,EAAE;AACf;AAEO,SAAS,UACd,OACA,SAC8B;AAC9B,SAAO,MAAM,OAAO,KAAK,CAAC,UAAU,MAAM,YAAY,OAAO;AAC/D;AAEO,SAAS,aAAa,OAA6C;AACxE,SAAO,MAAM,OAAO,OAAO,CAAC,UAAU,MAAM,MAAM;AACpD;AAEO,SAAS,kBAAkB,OAAsC;AACtE,QAAM,UAAU,oBAAI,IAAY;AAChC,aAAW,SAAS,MAAM,QAAQ;AAChC,QAAI,CAAC,MAAM,OAAQ;AACnB,eAAW,MAAM,MAAM,oBAAqB,SAAQ,IAAI,EAAE;AAAA,EAC5D;AACA,SAAO;AACT;AAEO,SAAS,kBAAkB,OAAwC;AACxE,MAAI,UAAyB;AAC7B,aAAW,SAAS,MAAM,QAAQ;AAChC,QAAI,MAAM,UAAU,MAAM,OAAO,QAAS,WAAU,MAAM;AAAA,EAC5D;AACA,SAAO;AACT;AAEO,SAAS,gBACd,OACA,oBACM;AACN,aAAW,SAAS,MAAM,QAAQ;AAChC,QAAI,CAAC,MAAM,OAAQ;AACnB,UAAM,iBAAiB;AACvB,QAAI,MAAM,iBAAiB,oBAAoB;AAC7C,YAAM,aAAa;AAAA,IACrB;AAAA,EACF;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"compress.d.ts","sourceRoot":"","sources":["../src/compress.ts"],"names":[],"mappings":"AAIA,OAAO,EAAkC,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAgBhF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAUvD,OAAO,EAGL,KAAK,YAAY,EAGlB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EACV,sBAAsB,EACtB,gBAAgB,EAChB,gBAAgB,EAEhB,MAAM,EAEN,WAAW,EAGX,iBAAiB,EAEjB,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,KAAK;IACpB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACxC;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAAC;IACxD,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,sBAAsB,CAAC;IACvE,YAAY,IAAI,YAAY,EAAE,CAAC;IAC/B,UAAU,CACR,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,gBAAgB,GACtB,gBAAgB,GAAG,SAAS,CAAC;IAChC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,gBAAgB,EAAE,CAAC;IACnE,MAAM,CACJ,KAAK,EAAE,gBAAgB,EACvB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,YAAY,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,EAAE,CAAC;IACJ,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACnC;AA2DD,wBAAgB,UAAU,CAAC,KAAK,GAAE,KAAU,GAAG,eAAe,CA+U7D;AA0jCD,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
1
+ {"version":3,"file":"compress.d.ts","sourceRoot":"","sources":["../src/compress.ts"],"names":[],"mappings":"AAIA,OAAO,EAAkC,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAgBhF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAcvD,OAAO,EAGL,KAAK,YAAY,EAGlB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EACV,sBAAsB,EACtB,gBAAgB,EAChB,gBAAgB,EAEhB,MAAM,EAEN,WAAW,EAGX,iBAAiB,EAEjB,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,KAAK;IACpB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACxC;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAAC;IACxD,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,sBAAsB,CAAC;IACvE,YAAY,IAAI,YAAY,EAAE,CAAC;IAC/B,UAAU,CACR,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,gBAAgB,GACtB,gBAAgB,GAAG,SAAS,CAAC;IAChC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,gBAAgB,EAAE,CAAC;IACnE,MAAM,CACJ,KAAK,EAAE,gBAAgB,EACvB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,YAAY,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,EAAE,CAAC;IACJ,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACnC;AA2DD,wBAAgB,UAAU,CAAC,KAAK,GAAE,KAAU,GAAG,eAAe,CA+U7D;AAwkCD,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,wBAAgB,aAAa,CAC3B,iBAAiB,EAAE,MAAM,EACzB,SAAS,GAAE,OAAO,CAAC,MAAM,CAAM,GAC9B,MAAM,CA+CR;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CA8DvD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,wBAAgB,aAAa,CAC3B,iBAAiB,EAAE,MAAM,EACzB,SAAS,GAAE,OAAO,CAAC,MAAM,CAAM,GAC9B,MAAM,CAgDR;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CA6EvD"}
package/dist/index.d.ts CHANGED
@@ -35,6 +35,8 @@ export type { HideConsumedResult } from "./hide-consumed.js";
35
35
  export { ABSORB_TOOL_NAME, ABSORB_TOOL, ABSORB_TOOL_OPENAI, } from "./compress-tools.js";
36
36
  export { ABSORB_PROMPT_MARKER, DEFAULT_ABSORB_CONFIG, resolveAbsorbConfig, buildAbsorbPrompt, buildAbsorbSystemPrompt, isAbsorbCandidate, hideAbsorbedMessages, appendAbsorbPrompts, parseAbsorbInput, applyAbsorb, } from "./absorb.js";
37
37
  export type { AbsorbInput, AbsorbOutcome, ParsedAbsorb, AppendAbsorbPromptsResult, } from "./absorb.js";
38
+ export { RULE_TOOL_NAME, DEFAULT_RULE_LIMITS, RULES_USAGE_PROMPT, listRules, allocateRuleId, resolveRuleLimits, addRule, removeRule, clearRules, formatRulesForPrompt, formatRulesList, } from "./rules.js";
39
+ export type { RuleLimits, AddRuleResult, RemoveRuleResult, ClearRulesResult, } from "./rules.js";
38
40
  export { rebuildCompressionState } from "./rebuild.js";
39
41
  export type { RebuildResult, RebuildPorts } from "./rebuild.js";
40
42
  export { parseCompressArgs } from "./parse-compress-input.js";
@@ -47,7 +49,7 @@ export { searchBlocks, searchBlocksAsync, blockDocs, messageDocs, } from "./sear
47
49
  export { clearDocFeatures, docCacheInfo, docFeatures, setDocCacheCap, } from "./search.js";
48
50
  export type { SearchResult, SearchOptions, SearchAlgorithm, AsyncSearchAlgorithm, AnySearchAlgorithm, SearchDoc, SearchDocKind, ScoredBlock, MessageRole, RoleWeights, MessageInput, } from "./search.js";
49
51
  export { DEFAULT_ALGORITHM, DEFAULT_ROLE_WEIGHTS, registerSearchAlgorithm, getSearchAlgorithm, listSearchAlgorithms, } from "./search.js";
50
- export { isMessageProtected, matchToolPattern } from "./protected.js";
52
+ export { collectLatestProtected, isMessageLatestProtected, isMessageProtected, matchToolPattern, type LatestProtected, } from "./protected.js";
51
53
  export { runPipeline, makeIO, type PipelineNode, type PipelineContext, type NodeIO, type NodeEffects, } from "./pipeline.js";
52
54
  export * from "./filter/index.js";
53
55
  export { VIABLE_RANGE_MIN_TOKENS, viableRanges } from "./viable.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -26,7 +26,7 @@ import {
26
26
  coveredMessageIds,
27
27
  createInitialState,
28
28
  highestActiveTier
29
- } from "./chunk-UX4LINT7.js";
29
+ } from "./chunk-5TQA7ZQM.js";
30
30
 
31
31
  // src/refs.ts
32
32
  var REF_WIDTH = 5;
@@ -298,6 +298,8 @@ function syncBlocks(messages, state) {
298
298
  nudge: { ...state.nudge, anchors: { ...state.nudge.anchors } },
299
299
  stats: { ...state.stats },
300
300
  absorbed: (state.absorbed ?? []).map((record) => ({ ...record })),
301
+ rules: (state.rules ?? []).map((rule) => ({ ...rule })),
302
+ nextRuleId: state.nextRuleId,
301
303
  terminalStreak: state.terminalStreak,
302
304
  nextBlockId: state.nextBlockId,
303
305
  nextRunId: state.nextRunId
@@ -363,6 +365,7 @@ function defaultConfig(modelContextLimit, overrides = {}) {
363
365
  minSummaryLength: 50
364
366
  },
365
367
  protectedTools: [],
368
+ protectedLatestTools: [],
366
369
  preserveRecentMessages: 5,
367
370
  preserveRecentTokens: 5e3,
368
371
  modelContextLimit,
@@ -428,6 +431,14 @@ function validateConfig(config) {
428
431
  errors.push("absorb.contextThresholdPct must be in [0, 1]");
429
432
  }
430
433
  }
434
+ if (config.rules) {
435
+ if (config.rules.maxRules !== void 0 && (!Number.isFinite(config.rules.maxRules) || config.rules.maxRules < 1)) {
436
+ errors.push("rules.maxRules must be >= 1");
437
+ }
438
+ if (config.rules.maxRuleChars !== void 0 && (!Number.isFinite(config.rules.maxRuleChars) || config.rules.maxRuleChars < 1)) {
439
+ errors.push("rules.maxRuleChars must be >= 1");
440
+ }
441
+ }
431
442
  return errors;
432
443
  }
433
444
 
@@ -1466,7 +1477,7 @@ var ABSORB_TOOL_GOOGLE = {
1466
1477
  };
1467
1478
 
1468
1479
  // src/protected.ts
1469
- var ALWAYS_PROTECTED_TOOLS = ["compress"];
1480
+ var ALWAYS_PROTECTED_TOOLS = ["compress", "acp_rule"];
1470
1481
  var NEVER_PRESERVE_RECENT_TOOLS = [
1471
1482
  "decompress",
1472
1483
  "search_context",
@@ -1515,6 +1526,31 @@ function isMessageProtectedWithPairing(msg, config, protectedCallIds) {
1515
1526
  }
1516
1527
  return false;
1517
1528
  }
1529
+ function collectLatestProtected(messages, config) {
1530
+ const callIds = /* @__PURE__ */ new Set();
1531
+ const msgIds = /* @__PURE__ */ new Set();
1532
+ const patterns = config.protectedLatestTools ?? [];
1533
+ if (patterns.length === 0) return { callIds, msgIds };
1534
+ for (const pattern of patterns) {
1535
+ let last;
1536
+ for (const m of messages) {
1537
+ if (m.contentType === "tool-call" && m.toolName && matchToolPattern(m.toolName, pattern)) {
1538
+ last = m;
1539
+ }
1540
+ }
1541
+ if (!last) continue;
1542
+ if (last.toolCallId) callIds.add(last.toolCallId);
1543
+ else msgIds.add(last.id);
1544
+ }
1545
+ return { callIds, msgIds };
1546
+ }
1547
+ function isMessageLatestProtected(msg, latest) {
1548
+ if (msg.contentType === "tool-call" && latest.msgIds.has(msg.id)) return true;
1549
+ if ((msg.contentType === "tool-call" || msg.contentType === "tool-result") && msg.toolCallId && latest.callIds.has(msg.toolCallId)) {
1550
+ return true;
1551
+ }
1552
+ return false;
1553
+ }
1518
1554
 
1519
1555
  // src/absorb.ts
1520
1556
  var ABSORB_PROMPT_MARKER = "[ACP absorb]";
@@ -1546,11 +1582,12 @@ function isAcpOrConfiguredTool(toolName, cfg) {
1546
1582
  if (toolName === cfg.toolName) return true;
1547
1583
  return ACP_TOOL_NAMES.has(toolName);
1548
1584
  }
1549
- function isAbsorbCandidate(msg, config) {
1585
+ function isAbsorbCandidate(msg, config, latest) {
1550
1586
  if (msg.contentType !== "tool-result" || !msg.toolCallId) return false;
1551
1587
  const cfg = resolveAbsorbConfig(config);
1552
1588
  if (isAcpOrConfiguredTool(msg.toolName, cfg)) return false;
1553
1589
  if (isMessageProtected(msg, config)) return false;
1590
+ if (latest && isMessageLatestProtected(msg, latest)) return false;
1554
1591
  for (const pattern of cfg.excludeTools) {
1555
1592
  if (msg.toolName && matchToolPattern(msg.toolName, pattern)) return false;
1556
1593
  }
@@ -1578,8 +1615,9 @@ function appendAbsorbPrompts(messages, state, config, tokenCount, countTokens) {
1578
1615
  if (record.resultMessageId) absorbedIds.add(record.resultMessageId);
1579
1616
  }
1580
1617
  let promptedCount = 0;
1618
+ const latest = collectLatestProtected(messages, config);
1581
1619
  const out = messages.map((msg) => {
1582
- if (!isAbsorbCandidate(msg, config)) return msg;
1620
+ if (!isAbsorbCandidate(msg, config, latest)) return msg;
1583
1621
  if (absorbedIds.has(msg.id)) return msg;
1584
1622
  const text = msg.text ?? "";
1585
1623
  if (text.includes(ABSORB_PROMPT_MARKER)) return msg;
@@ -1685,7 +1723,10 @@ function applyAbsorb(input) {
1685
1723
  resultText: `absorb failed: ${target.toolName} is an ACP-managed tool result \u2014 it is not absorbable.`
1686
1724
  };
1687
1725
  }
1688
- if (isMessageProtected(target, input.config)) {
1726
+ if (isMessageProtected(target, input.config) || isMessageLatestProtected(
1727
+ target,
1728
+ collectLatestProtected(input.messages, input.config)
1729
+ )) {
1689
1730
  return {
1690
1731
  state: input.state,
1691
1732
  ok: false,
@@ -2196,6 +2237,8 @@ function buildCompressibleRanges(messages, state, config, protectedZoneRefs, cou
2196
2237
  let compressibleMsgs = [];
2197
2238
  const protectedMsgs = [];
2198
2239
  const protectedCallIds = collectProtectedToolCallIds(messages, config);
2240
+ const latest = collectLatestProtected(messages, config);
2241
+ for (const id of latest.callIds) protectedCallIds.add(id);
2199
2242
  let skipSinceCompressible = false;
2200
2243
  let skipSinceProtected = false;
2201
2244
  let msgIndex = -1;
@@ -2208,7 +2251,7 @@ function buildCompressibleRanges(messages, state, config, protectedZoneRefs, cou
2208
2251
  skipSinceProtected = true;
2209
2252
  continue;
2210
2253
  }
2211
- if (isMessageProtectedWithPairing(msg, config, protectedCallIds)) {
2254
+ if (isMessageProtectedWithPairing(msg, config, protectedCallIds) || isMessageLatestProtected(msg, latest)) {
2212
2255
  protectedMsgs.push({
2213
2256
  ref,
2214
2257
  gapBefore: skipSinceProtected,
@@ -2669,8 +2712,9 @@ function createCore(ports = {}) {
2669
2712
  var assignRefsNode = {
2670
2713
  name: "assign-refs",
2671
2714
  run(io, ctx) {
2672
- const hasProtection = ctx.config.protectedTools.length > 0 || !!ctx.config.isToolProtected;
2673
- const protectedFn = hasProtection ? (m) => isMessageProtected(m, ctx.config) : void 0;
2715
+ const hasProtection = ctx.config.protectedTools.length > 0 || !!ctx.config.isToolProtected || (ctx.config.protectedLatestTools?.length ?? 0) > 0;
2716
+ const latest = hasProtection ? collectLatestProtected(io.messages, ctx.config) : void 0;
2717
+ const protectedFn = hasProtection ? (m) => isMessageProtected(m, ctx.config) || (latest ? isMessageLatestProtected(m, latest) : false) : void 0;
2674
2718
  const refResult = assignRefs(io.messages, {
2675
2719
  existing: io.state.messageRefs,
2676
2720
  nextIndex: highestUsedIndex(io.state.messageRefs) + 1,
@@ -3066,6 +3110,8 @@ function validateCompressionRange(input, directMessageIds, consumedBlockCount) {
3066
3110
  function filterProtectedToolMessages(directMessageIds, messages, config) {
3067
3111
  const protectedCallIds = /* @__PURE__ */ new Set();
3068
3112
  const removedIds = /* @__PURE__ */ new Set();
3113
+ const latest = collectLatestProtected(messages, config);
3114
+ for (const id of latest.callIds) protectedCallIds.add(id);
3069
3115
  for (const msg of messages) {
3070
3116
  if (isMessageProtected(msg, config) && msg.toolCallId) {
3071
3117
  protectedCallIds.add(msg.toolCallId);
@@ -3074,7 +3120,7 @@ function filterProtectedToolMessages(directMessageIds, messages, config) {
3074
3120
  for (const id of directMessageIds) {
3075
3121
  const msg = messages.find((m) => m.id === id);
3076
3122
  if (!msg) continue;
3077
- if (isMessageProtected(msg, config)) {
3123
+ if (isMessageProtected(msg, config) || isMessageLatestProtected(msg, latest)) {
3078
3124
  removedIds.add(id);
3079
3125
  if (msg.toolCallId) protectedCallIds.add(msg.toolCallId);
3080
3126
  }
@@ -3332,6 +3378,8 @@ function cloneState(state) {
3332
3378
  nudge: { ...state.nudge, anchors: { ...state.nudge.anchors } },
3333
3379
  stats: { ...state.stats },
3334
3380
  absorbed: (state.absorbed ?? []).map((record) => ({ ...record })),
3381
+ rules: (state.rules ?? []).map((rule) => ({ ...rule })),
3382
+ nextRuleId: state.nextRuleId,
3335
3383
  terminalStreak: state.terminalStreak,
3336
3384
  nextBlockId: state.nextBlockId,
3337
3385
  nextRunId: state.nextRunId
@@ -4532,6 +4580,105 @@ function matchSession(sessions, selector, labelOf) {
4532
4580
  return sessions.filter((s) => s.id.startsWith(selector) || (labelOf(s) ?? "").startsWith(selector));
4533
4581
  }
4534
4582
 
4583
+ // src/rules.ts
4584
+ var RULE_TOOL_NAME = "acp_rule";
4585
+ var DEFAULT_RULE_LIMITS = Object.freeze({
4586
+ maxRules: 50,
4587
+ maxRuleChars: 300
4588
+ });
4589
+ var RULES_USAGE_PROMPT = [
4590
+ "Use the acp_rule tool to record short, principle-level reminders that must survive context compression:",
4591
+ "- behavioral corrections the user has had to repeat more than once,",
4592
+ "- project invariants the user explicitly asked you to remember,",
4593
+ "- pitfalls you ran into once and must not run into again.",
4594
+ "Rules are re-injected into the system prompt every turn. Omit the text argument to list recorded rules."
4595
+ ].join("\n");
4596
+ function listRules(state) {
4597
+ return state.rules ?? [];
4598
+ }
4599
+ function resolveRuleLimits(config) {
4600
+ return {
4601
+ maxRules: config?.rules?.maxRules ?? DEFAULT_RULE_LIMITS.maxRules,
4602
+ maxRuleChars: config?.rules?.maxRuleChars ?? DEFAULT_RULE_LIMITS.maxRuleChars
4603
+ };
4604
+ }
4605
+ var RULE_ID_RE = /^rule(\d+)$/;
4606
+ function highestRuleNumber(state) {
4607
+ let highest = 0;
4608
+ for (const rule of state.rules ?? []) {
4609
+ const match = RULE_ID_RE.exec(rule.id);
4610
+ if (match) highest = Math.max(highest, Number(match[1]));
4611
+ }
4612
+ return highest;
4613
+ }
4614
+ function allocateRuleId(state) {
4615
+ return `rule${Math.max(state.nextRuleId ?? 1, highestRuleNumber(state) + 1)}`;
4616
+ }
4617
+ function addRule(state, text, limits = {}) {
4618
+ const maxRules = limits.maxRules ?? DEFAULT_RULE_LIMITS.maxRules;
4619
+ const maxRuleChars = limits.maxRuleChars ?? DEFAULT_RULE_LIMITS.maxRuleChars;
4620
+ const trimmed = (text ?? "").trim();
4621
+ if (!trimmed) {
4622
+ return {
4623
+ ok: false,
4624
+ error: "rule text is empty \u2014 provide the reminder to record."
4625
+ };
4626
+ }
4627
+ if (trimmed.length > maxRuleChars) {
4628
+ return {
4629
+ ok: false,
4630
+ error: `${trimmed.length} chars exceeds the ${maxRuleChars}-char limit \u2014 keep rules short and principle-level.`
4631
+ };
4632
+ }
4633
+ const rules = listRules(state);
4634
+ const duplicate = rules.find((rule2) => rule2.text === trimmed);
4635
+ if (duplicate) {
4636
+ return {
4637
+ ok: false,
4638
+ error: `identical rule already exists (${duplicate.id}) \u2014 no change.`
4639
+ };
4640
+ }
4641
+ if (rules.length >= maxRules) {
4642
+ return {
4643
+ ok: false,
4644
+ error: `rule limit reached (${maxRules}) \u2014 remove or clear outdated rules first.`
4645
+ };
4646
+ }
4647
+ const next = Math.max(state.nextRuleId ?? 1, highestRuleNumber(state) + 1);
4648
+ const rule = { id: `rule${next}`, text: trimmed };
4649
+ state.rules = [...rules, rule];
4650
+ state.nextRuleId = next + 1;
4651
+ return { ok: true, rule };
4652
+ }
4653
+ function removeRule(state, id) {
4654
+ const rules = listRules(state);
4655
+ const target = rules.find((rule) => rule.id === id.trim());
4656
+ if (!target) {
4657
+ return {
4658
+ ok: false,
4659
+ error: `no rule with id "${id.trim()}" \u2014 list current rules first (omit the text argument).`
4660
+ };
4661
+ }
4662
+ state.rules = rules.filter((rule) => rule.id !== target.id);
4663
+ return { ok: true, rule: target };
4664
+ }
4665
+ function clearRules(state) {
4666
+ const count = listRules(state).length;
4667
+ state.rules = [];
4668
+ return { ok: true, count };
4669
+ }
4670
+ function formatRulesForPrompt(state) {
4671
+ const rules = listRules(state);
4672
+ if (rules.length === 0) return "";
4673
+ return [
4674
+ "# Persistent rules (recorded via acp_rule \u2014 kept across compression)",
4675
+ ...rules.map((rule) => `- [${rule.id}] ${rule.text}`)
4676
+ ].join("\n");
4677
+ }
4678
+ function formatRulesList(rules) {
4679
+ return rules.map((rule, i) => `${i + 1}. [${rule.id}] ${rule.text}`).join("\n");
4680
+ }
4681
+
4535
4682
  // src/parse-compress-input.ts
4536
4683
  function parseCompressArgs(input, opts) {
4537
4684
  const callId = opts?.callId;
@@ -5473,8 +5620,11 @@ export {
5473
5620
  DEFAULT_ABSORB_CONFIG,
5474
5621
  DEFAULT_ALGORITHM,
5475
5622
  DEFAULT_ROLE_WEIGHTS,
5623
+ DEFAULT_RULE_LIMITS,
5476
5624
  HOW_TO_COMPRESS_RULES,
5477
5625
  LEAN_HOW_TO_COMPRESS,
5626
+ RULES_USAGE_PROMPT,
5627
+ RULE_TOOL_NAME,
5478
5628
  SEARCH_CONTEXT_TOOL,
5479
5629
  SEARCH_CONTEXT_TOOL_GOOGLE,
5480
5630
  SEARCH_CONTEXT_TOOL_NAME,
@@ -5486,8 +5636,10 @@ export {
5486
5636
  VIABLE_RANGE_MIN_TOKENS,
5487
5637
  activeBlockSpans,
5488
5638
  activeBlocks,
5639
+ addRule,
5489
5640
  advanceSurvival,
5490
5641
  allocateBlockId,
5642
+ allocateRuleId,
5491
5643
  allocateRunId,
5492
5644
  appendAbsorbPrompts,
5493
5645
  applyAbsorb,
@@ -5510,8 +5662,10 @@ export {
5510
5662
  builtinSource,
5511
5663
  clearDocFeatures,
5512
5664
  clearMessageFilters,
5665
+ clearRules,
5513
5666
  cloneWithDescriptions,
5514
5667
  collectBlockContent,
5668
+ collectLatestProtected,
5515
5669
  computeFoldEconomics,
5516
5670
  countMessageTokens,
5517
5671
  coveredMessageIds,
@@ -5537,6 +5691,8 @@ export {
5537
5691
  formatCacheReport,
5538
5692
  formatCreatedBlocks,
5539
5693
  formatRanges,
5694
+ formatRulesForPrompt,
5695
+ formatRulesList,
5540
5696
  getMessageFilter,
5541
5697
  getSearchAlgorithm,
5542
5698
  hideAbsorbedMessages,
@@ -5545,12 +5701,14 @@ export {
5545
5701
  highestUsedIndex,
5546
5702
  indexToRef,
5547
5703
  isAbsorbCandidate,
5704
+ isMessageLatestProtected,
5548
5705
  isMessageProtected,
5549
5706
  isRenderedSummaryMessage,
5550
5707
  isSummaryMessageId,
5551
5708
  isValidPackName,
5552
5709
  leanPack,
5553
5710
  listMessageFilters,
5711
+ listRules,
5554
5712
  listSearchAlgorithms,
5555
5713
  makeIO,
5556
5714
  matchSession,
@@ -5568,6 +5726,7 @@ export {
5568
5726
  refToIndex,
5569
5727
  registerMessageFilter,
5570
5728
  registerSearchAlgorithm,
5729
+ removeRule,
5571
5730
  renderHandoff,
5572
5731
  renderMessage2 as renderMessage,
5573
5732
  renderNudgeText,
@@ -5577,6 +5736,7 @@ export {
5577
5736
  resolveBlockSpan,
5578
5737
  resolveBoundaries,
5579
5738
  resolvePrompts,
5739
+ resolveRuleLimits,
5580
5740
  resolveTransformChannel,
5581
5741
  runPipeline,
5582
5742
  sanitizePackSurface,