open-multi-agent-kit 0.90.0 → 0.90.4

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.
Files changed (307) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/README.md +22 -31
  3. package/dist/cli/args.d.ts +0 -2
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +1 -7
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/config.d.ts +3 -6
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/config.js +27 -19
  10. package/dist/config.js.map +1 -1
  11. package/dist/core/adaptorch-bridge.d.ts +257 -0
  12. package/dist/core/adaptorch-bridge.d.ts.map +1 -0
  13. package/dist/core/adaptorch-bridge.js +473 -0
  14. package/dist/core/adaptorch-bridge.js.map +1 -0
  15. package/dist/core/agent-session.d.ts +132 -0
  16. package/dist/core/agent-session.d.ts.map +1 -1
  17. package/dist/core/agent-session.js +327 -5
  18. package/dist/core/agent-session.js.map +1 -1
  19. package/dist/core/bang-skill-invocation.d.ts +26 -0
  20. package/dist/core/bang-skill-invocation.d.ts.map +1 -0
  21. package/dist/core/bang-skill-invocation.js +208 -0
  22. package/dist/core/bang-skill-invocation.js.map +1 -0
  23. package/dist/core/compaction/utils.d.ts.map +1 -1
  24. package/dist/core/compaction/utils.js +15 -2
  25. package/dist/core/compaction/utils.js.map +1 -1
  26. package/dist/core/compactor.d.ts.map +1 -1
  27. package/dist/core/compactor.js +0 -3
  28. package/dist/core/compactor.js.map +1 -1
  29. package/dist/core/context-budget-governor-v2.d.ts +2 -1
  30. package/dist/core/context-budget-governor-v2.d.ts.map +1 -1
  31. package/dist/core/context-budget-governor-v2.js +1 -0
  32. package/dist/core/context-budget-governor-v2.js.map +1 -1
  33. package/dist/core/context-budget-headroom-types.d.ts +8 -0
  34. package/dist/core/context-budget-headroom-types.d.ts.map +1 -1
  35. package/dist/core/context-budget-headroom-types.js.map +1 -1
  36. package/dist/core/context-budget-headroom.d.ts +1 -1
  37. package/dist/core/context-budget-headroom.d.ts.map +1 -1
  38. package/dist/core/context-budget-headroom.js +17 -4
  39. package/dist/core/context-budget-headroom.js.map +1 -1
  40. package/dist/core/context-budget-system-prompt.d.ts +2 -1
  41. package/dist/core/context-budget-system-prompt.d.ts.map +1 -1
  42. package/dist/core/context-budget-system-prompt.js +6 -1
  43. package/dist/core/context-budget-system-prompt.js.map +1 -1
  44. package/dist/core/context-budget-v2-cache-hash.d.ts +3 -0
  45. package/dist/core/context-budget-v2-cache-hash.d.ts.map +1 -0
  46. package/dist/core/context-budget-v2-cache-hash.js +16 -0
  47. package/dist/core/context-budget-v2-cache-hash.js.map +1 -0
  48. package/dist/core/context-budget-v2-cache-keys.d.ts +58 -0
  49. package/dist/core/context-budget-v2-cache-keys.d.ts.map +1 -0
  50. package/dist/core/context-budget-v2-cache-keys.js +128 -0
  51. package/dist/core/context-budget-v2-cache-keys.js.map +1 -0
  52. package/dist/core/context-budget-v2-cache-provider.d.ts +23 -0
  53. package/dist/core/context-budget-v2-cache-provider.d.ts.map +1 -0
  54. package/dist/core/context-budget-v2-cache-provider.js +29 -0
  55. package/dist/core/context-budget-v2-cache-provider.js.map +1 -0
  56. package/dist/core/context-budget-v2-cache-telemetry.d.ts +36 -0
  57. package/dist/core/context-budget-v2-cache-telemetry.d.ts.map +1 -0
  58. package/dist/core/context-budget-v2-cache-telemetry.js +64 -0
  59. package/dist/core/context-budget-v2-cache-telemetry.js.map +1 -0
  60. package/dist/core/context-budget-v2-cache-validation.d.ts +36 -0
  61. package/dist/core/context-budget-v2-cache-validation.d.ts.map +1 -0
  62. package/dist/core/context-budget-v2-cache-validation.js +98 -0
  63. package/dist/core/context-budget-v2-cache-validation.js.map +1 -0
  64. package/dist/core/context-budget-v2-cache.d.ts +36 -0
  65. package/dist/core/context-budget-v2-cache.d.ts.map +1 -0
  66. package/dist/core/context-budget-v2-cache.js +50 -0
  67. package/dist/core/context-budget-v2-cache.js.map +1 -0
  68. package/dist/core/context-budget-v2-plan-cache-keys.d.ts +16 -0
  69. package/dist/core/context-budget-v2-plan-cache-keys.d.ts.map +1 -0
  70. package/dist/core/context-budget-v2-plan-cache-keys.js +49 -0
  71. package/dist/core/context-budget-v2-plan-cache-keys.js.map +1 -0
  72. package/dist/core/context-budget-v2-planner.d.ts.map +1 -1
  73. package/dist/core/context-budget-v2-planner.js +55 -2
  74. package/dist/core/context-budget-v2-planner.js.map +1 -1
  75. package/dist/core/context-budget-v2-representation-cache.d.ts +27 -0
  76. package/dist/core/context-budget-v2-representation-cache.d.ts.map +1 -0
  77. package/dist/core/context-budget-v2-representation-cache.js +173 -0
  78. package/dist/core/context-budget-v2-representation-cache.js.map +1 -0
  79. package/dist/core/context-budget-v2-selection.d.ts +2 -0
  80. package/dist/core/context-budget-v2-selection.d.ts.map +1 -1
  81. package/dist/core/context-budget-v2-selection.js +12 -2
  82. package/dist/core/context-budget-v2-selection.js.map +1 -1
  83. package/dist/core/context-budget-v2-types.d.ts +107 -1
  84. package/dist/core/context-budget-v2-types.d.ts.map +1 -1
  85. package/dist/core/context-budget-v2-types.js.map +1 -1
  86. package/dist/core/domain-loadouts.d.ts.map +1 -1
  87. package/dist/core/domain-loadouts.js +1 -1
  88. package/dist/core/domain-loadouts.js.map +1 -1
  89. package/dist/core/headroom.d.ts.map +1 -1
  90. package/dist/core/headroom.js +0 -4
  91. package/dist/core/headroom.js.map +1 -1
  92. package/dist/core/hook-inventory.d.ts.map +1 -1
  93. package/dist/core/hook-inventory.js +6 -0
  94. package/dist/core/hook-inventory.js.map +1 -1
  95. package/dist/core/mcp-computer-use-presets.d.ts +64 -0
  96. package/dist/core/mcp-computer-use-presets.d.ts.map +1 -0
  97. package/dist/core/mcp-computer-use-presets.js +158 -0
  98. package/dist/core/mcp-computer-use-presets.js.map +1 -0
  99. package/dist/core/mcp-public-presets.d.ts +578 -0
  100. package/dist/core/mcp-public-presets.d.ts.map +1 -0
  101. package/dist/core/mcp-public-presets.js +647 -0
  102. package/dist/core/mcp-public-presets.js.map +1 -0
  103. package/dist/core/model-registry.d.ts.map +1 -1
  104. package/dist/core/model-registry.js +1 -0
  105. package/dist/core/model-registry.js.map +1 -1
  106. package/dist/core/pi-package-intake-candidates.d.ts +14 -1
  107. package/dist/core/pi-package-intake-candidates.d.ts.map +1 -1
  108. package/dist/core/pi-package-intake-candidates.js +182 -0
  109. package/dist/core/pi-package-intake-candidates.js.map +1 -1
  110. package/dist/core/pi-package-intake.d.ts +8 -1
  111. package/dist/core/pi-package-intake.d.ts.map +1 -1
  112. package/dist/core/pi-package-intake.js +14 -4
  113. package/dist/core/pi-package-intake.js.map +1 -1
  114. package/dist/core/reasoning-router-bias.d.ts +119 -0
  115. package/dist/core/reasoning-router-bias.d.ts.map +1 -0
  116. package/dist/core/reasoning-router-bias.js +287 -0
  117. package/dist/core/reasoning-router-bias.js.map +1 -0
  118. package/dist/core/reasoning-router-v2.d.ts +94 -0
  119. package/dist/core/reasoning-router-v2.d.ts.map +1 -0
  120. package/dist/core/reasoning-router-v2.js +288 -0
  121. package/dist/core/reasoning-router-v2.js.map +1 -0
  122. package/dist/core/reasoning-router-v3.d.ts +15 -0
  123. package/dist/core/reasoning-router-v3.d.ts.map +1 -0
  124. package/dist/core/reasoning-router-v3.js +193 -0
  125. package/dist/core/reasoning-router-v3.js.map +1 -0
  126. package/dist/core/reasoning-router-v4-weights.d.ts +124 -0
  127. package/dist/core/reasoning-router-v4-weights.d.ts.map +1 -0
  128. package/dist/core/reasoning-router-v4-weights.js +112 -0
  129. package/dist/core/reasoning-router-v4-weights.js.map +1 -0
  130. package/dist/core/reasoning-router-v4.d.ts +163 -0
  131. package/dist/core/reasoning-router-v4.d.ts.map +1 -0
  132. package/dist/core/reasoning-router-v4.js +683 -0
  133. package/dist/core/reasoning-router-v4.js.map +1 -0
  134. package/dist/core/reasoning-router-weights.d.ts +155 -0
  135. package/dist/core/reasoning-router-weights.d.ts.map +1 -0
  136. package/dist/core/reasoning-router-weights.js +204 -0
  137. package/dist/core/reasoning-router-weights.js.map +1 -0
  138. package/dist/core/reasoning-router.d.ts +44 -0
  139. package/dist/core/reasoning-router.d.ts.map +1 -0
  140. package/dist/core/reasoning-router.js +138 -0
  141. package/dist/core/reasoning-router.js.map +1 -0
  142. package/dist/core/reverse-skill.d.ts +2 -0
  143. package/dist/core/reverse-skill.d.ts.map +1 -0
  144. package/dist/core/reverse-skill.js +7 -0
  145. package/dist/core/reverse-skill.js.map +1 -0
  146. package/dist/core/router-feedback-collector.d.ts +101 -0
  147. package/dist/core/router-feedback-collector.d.ts.map +1 -0
  148. package/dist/core/router-feedback-collector.js +239 -0
  149. package/dist/core/router-feedback-collector.js.map +1 -0
  150. package/dist/core/settings-manager.d.ts +31 -3
  151. package/dist/core/settings-manager.d.ts.map +1 -1
  152. package/dist/core/settings-manager.js +16 -0
  153. package/dist/core/settings-manager.js.map +1 -1
  154. package/dist/core/slash-commands.d.ts.map +1 -1
  155. package/dist/core/slash-commands.js +4 -1
  156. package/dist/core/slash-commands.js.map +1 -1
  157. package/dist/core/system-prompt.d.ts +2 -0
  158. package/dist/core/system-prompt.d.ts.map +1 -1
  159. package/dist/core/system-prompt.js +58 -5
  160. package/dist/core/system-prompt.js.map +1 -1
  161. package/dist/index.d.ts +1 -0
  162. package/dist/index.d.ts.map +1 -1
  163. package/dist/index.js +1 -0
  164. package/dist/index.js.map +1 -1
  165. package/dist/migrations.d.ts +19 -0
  166. package/dist/migrations.d.ts.map +1 -1
  167. package/dist/migrations.js +39 -15
  168. package/dist/migrations.js.map +1 -1
  169. package/dist/modes/interactive/components/control-panel-box.d.ts +3 -3
  170. package/dist/modes/interactive/components/control-panel-box.d.ts.map +1 -1
  171. package/dist/modes/interactive/components/control-panel-box.js +10 -10
  172. package/dist/modes/interactive/components/control-panel-box.js.map +1 -1
  173. package/dist/modes/interactive/components/control-panel-gradient-motion.d.ts.map +1 -1
  174. package/dist/modes/interactive/components/control-panel-gradient-motion.js +2 -1
  175. package/dist/modes/interactive/components/control-panel-gradient-motion.js.map +1 -1
  176. package/dist/modes/interactive/components/control-panel-layout.d.ts +15 -1
  177. package/dist/modes/interactive/components/control-panel-layout.d.ts.map +1 -1
  178. package/dist/modes/interactive/components/control-panel-layout.js +212 -68
  179. package/dist/modes/interactive/components/control-panel-layout.js.map +1 -1
  180. package/dist/modes/interactive/components/control-panel-runtime-status.d.ts +15 -0
  181. package/dist/modes/interactive/components/control-panel-runtime-status.d.ts.map +1 -1
  182. package/dist/modes/interactive/components/control-panel-runtime-status.js +105 -5
  183. package/dist/modes/interactive/components/control-panel-runtime-status.js.map +1 -1
  184. package/dist/modes/interactive/components/control-panel-sparkles.d.ts +27 -0
  185. package/dist/modes/interactive/components/control-panel-sparkles.d.ts.map +1 -0
  186. package/dist/modes/interactive/components/control-panel-sparkles.js +42 -0
  187. package/dist/modes/interactive/components/control-panel-sparkles.js.map +1 -0
  188. package/dist/modes/interactive/components/control-panel.d.ts +8 -0
  189. package/dist/modes/interactive/components/control-panel.d.ts.map +1 -1
  190. package/dist/modes/interactive/components/control-panel.js +40 -8
  191. package/dist/modes/interactive/components/control-panel.js.map +1 -1
  192. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  193. package/dist/modes/interactive/components/settings-selector.js +2 -1
  194. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  195. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  196. package/dist/modes/interactive/components/thinking-selector.js +2 -1
  197. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  198. package/dist/modes/interactive/interactive-mode.d.ts +6 -0
  199. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  200. package/dist/modes/interactive/interactive-mode.js +206 -32
  201. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  202. package/dist/modes/interactive/theme/theme.d.ts +1 -1
  203. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  204. package/dist/modes/interactive/theme/theme.js +2 -0
  205. package/dist/modes/interactive/theme/theme.js.map +1 -1
  206. package/docs/loadout-domains/README.md +8 -6
  207. package/docs/loadout-domains/ai-agent-ops.md +3 -2
  208. package/docs/loadout-domains/backend-api.md +3 -2
  209. package/docs/loadout-domains/data-science.md +3 -2
  210. package/docs/loadout-domains/devops-infra.md +2 -1
  211. package/docs/loadout-domains/docs-writing.md +7 -2
  212. package/docs/loadout-domains/frontend-ui.md +42 -11
  213. package/docs/loadout-domains/korean-document.md +83 -0
  214. package/docs/loadout-domains/mobile.md +1 -1
  215. package/docs/loadout-domains/qa-testing.md +4 -2
  216. package/docs/loadout-domains/security-audit.md +2 -1
  217. package/docs/loadout-domains/visual-qa.md +94 -0
  218. package/docs/skills.md +11 -4
  219. package/docs/usage.md +39 -4
  220. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  221. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  222. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  223. package/examples/extensions/gondolin/package-lock.json +2 -2
  224. package/examples/extensions/gondolin/package.json +1 -1
  225. package/examples/extensions/preset.ts +2 -2
  226. package/examples/extensions/sandbox/package-lock.json +2 -2
  227. package/examples/extensions/sandbox/package.json +1 -1
  228. package/examples/extensions/with-deps/package-lock.json +2 -2
  229. package/examples/extensions/with-deps/package.json +1 -1
  230. package/npm-shrinkwrap.json +27 -34
  231. package/package.json +5 -5
  232. package/dist/agents/jailbreak/index.d.ts +0 -7
  233. package/dist/agents/jailbreak/index.d.ts.map +0 -1
  234. package/dist/agents/jailbreak/index.js +0 -7
  235. package/dist/agents/jailbreak/index.js.map +0 -1
  236. package/dist/agents/jailbreak/subagent-f.d.ts +0 -44
  237. package/dist/agents/jailbreak/subagent-f.d.ts.map +0 -1
  238. package/dist/agents/jailbreak/subagent-f.js +0 -60
  239. package/dist/agents/jailbreak/subagent-f.js.map +0 -1
  240. package/dist/cli/jailbreak-args.d.ts +0 -26
  241. package/dist/cli/jailbreak-args.d.ts.map +0 -1
  242. package/dist/cli/jailbreak-args.js +0 -86
  243. package/dist/cli/jailbreak-args.js.map +0 -1
  244. package/dist/commands/jailbreak.d.ts +0 -49
  245. package/dist/commands/jailbreak.d.ts.map +0 -1
  246. package/dist/commands/jailbreak.js +0 -201
  247. package/dist/commands/jailbreak.js.map +0 -1
  248. package/dist/encoding/index.d.ts +0 -6
  249. package/dist/encoding/index.d.ts.map +0 -1
  250. package/dist/encoding/index.js +0 -6
  251. package/dist/encoding/index.js.map +0 -1
  252. package/dist/encoding/l4-encoder.d.ts +0 -96
  253. package/dist/encoding/l4-encoder.d.ts.map +0 -1
  254. package/dist/encoding/l4-encoder.js +0 -474
  255. package/dist/encoding/l4-encoder.js.map +0 -1
  256. package/dist/fuzzing/index.d.ts +0 -6
  257. package/dist/fuzzing/index.d.ts.map +0 -1
  258. package/dist/fuzzing/index.js +0 -6
  259. package/dist/fuzzing/index.js.map +0 -1
  260. package/dist/fuzzing/mutation-engine.d.ts +0 -93
  261. package/dist/fuzzing/mutation-engine.d.ts.map +0 -1
  262. package/dist/fuzzing/mutation-engine.js +0 -244
  263. package/dist/fuzzing/mutation-engine.js.map +0 -1
  264. package/dist/jailbreak-extension.d.ts +0 -48
  265. package/dist/jailbreak-extension.d.ts.map +0 -1
  266. package/dist/jailbreak-extension.js +0 -47
  267. package/dist/jailbreak-extension.js.map +0 -1
  268. package/dist/modules/index.d.ts +0 -8
  269. package/dist/modules/index.d.ts.map +0 -1
  270. package/dist/modules/index.js +0 -7
  271. package/dist/modules/index.js.map +0 -1
  272. package/dist/modules/lrl-bypass.d.ts +0 -40
  273. package/dist/modules/lrl-bypass.d.ts.map +0 -1
  274. package/dist/modules/lrl-bypass.js +0 -84
  275. package/dist/modules/lrl-bypass.js.map +0 -1
  276. package/dist/modules/lrl-deps.d.ts +0 -38
  277. package/dist/modules/lrl-deps.d.ts.map +0 -1
  278. package/dist/modules/lrl-deps.js +0 -128
  279. package/dist/modules/lrl-deps.js.map +0 -1
  280. package/dist/multiturn/easl-chain.d.ts +0 -113
  281. package/dist/multiturn/easl-chain.d.ts.map +0 -1
  282. package/dist/multiturn/easl-chain.js +0 -351
  283. package/dist/multiturn/easl-chain.js.map +0 -1
  284. package/dist/multiturn/index.d.ts +0 -6
  285. package/dist/multiturn/index.d.ts.map +0 -1
  286. package/dist/multiturn/index.js +0 -6
  287. package/dist/multiturn/index.js.map +0 -1
  288. package/dist/routing/fallback-router.d.ts +0 -123
  289. package/dist/routing/fallback-router.d.ts.map +0 -1
  290. package/dist/routing/fallback-router.js +0 -355
  291. package/dist/routing/fallback-router.js.map +0 -1
  292. package/dist/routing/index.d.ts +0 -6
  293. package/dist/routing/index.d.ts.map +0 -1
  294. package/dist/routing/index.js +0 -6
  295. package/dist/routing/index.js.map +0 -1
  296. package/dist/types/jailbreak.d.ts +0 -246
  297. package/dist/types/jailbreak.d.ts.map +0 -1
  298. package/dist/types/jailbreak.js +0 -8
  299. package/dist/types/jailbreak.js.map +0 -1
  300. package/dist/utils/jailbreak/common.d.ts +0 -63
  301. package/dist/utils/jailbreak/common.d.ts.map +0 -1
  302. package/dist/utils/jailbreak/common.js +0 -130
  303. package/dist/utils/jailbreak/common.js.map +0 -1
  304. package/dist/utils/jailbreak/index.d.ts +0 -7
  305. package/dist/utils/jailbreak/index.d.ts.map +0 -1
  306. package/dist/utils/jailbreak/index.js +0 -7
  307. package/dist/utils/jailbreak/index.js.map +0 -1
@@ -0,0 +1,50 @@
1
+ import { createMutableContextBudgetCacheTelemetryV2, withCacheTelemetry, } from "./context-budget-v2-cache-telemetry.js";
2
+ import { sourceHashesByContextBudgetItemIdV2, validateContextBudgetPlanCacheEntryV2, } from "./context-budget-v2-cache-validation.js";
3
+ export { buildContextBudgetExactRepresentationCacheKeyV2, buildContextBudgetMaterializedRepresentationCacheKeyV2, buildContextBudgetMaterializedRepresentationCandidateKeyV2, buildContextBudgetRepresentationCacheKeyV2, computeContextBudgetOutputTextHashV2, computeContextBudgetQueryIntentHashV2, computeContextBudgetRepresentationFingerprintV2, computeContextBudgetTargetTokenBucketV2, createContextBudgetCacheKeyBaseV2, DEFAULT_MATERIALIZED_COMPRESSOR_POLICY_HASH_V2, DEFAULT_MATERIALIZED_QUALITY_POLICY_HASH_V2, } from "./context-budget-v2-cache-keys.js";
4
+ export { createMemoryContextBudgetCacheProviderV2 } from "./context-budget-v2-cache-provider.js";
5
+ export { finalizeContextBudgetCacheTelemetryV2, withCacheTelemetry, } from "./context-budget-v2-cache-telemetry.js";
6
+ export { buildContextBudgetPlanCacheKeyV2 } from "./context-budget-v2-plan-cache-keys.js";
7
+ export { applyRepresentationCacheV2, isMaterializableRepresentationV2, writeRepresentationCacheV2, } from "./context-budget-v2-representation-cache.js";
8
+ const DEFAULT_CACHE_TTL_MS = 5 * 60 * 1000;
9
+ export function createContextBudgetSelectionCacheV2(input) {
10
+ return {
11
+ provider: input.provider,
12
+ keyBase: input.keyBase,
13
+ nowEpochMs: input.nowEpochMs ?? Date.now(),
14
+ ttlMs: input.ttlMs ?? DEFAULT_CACHE_TTL_MS,
15
+ telemetry: createMutableContextBudgetCacheTelemetryV2(input.planCacheKey),
16
+ };
17
+ }
18
+ export function readValidPlanCacheV2(input) {
19
+ const read = input.cache.provider?.readPlan(input.key);
20
+ if (!read)
21
+ return undefined;
22
+ const rejection = validateContextBudgetPlanCacheEntryV2({
23
+ availableTokens: input.availableTokens,
24
+ cache: input.cache,
25
+ entry: read.entry,
26
+ planned: input.planned,
27
+ });
28
+ if (rejection) {
29
+ input.cache.telemetry.planCache.rejectedReason = rejection;
30
+ return undefined;
31
+ }
32
+ input.cache.telemetry.planCache.hit = true;
33
+ input.cache.telemetry.planCache.layer = read.layer;
34
+ return withCacheTelemetry(read.entry.plan, input.cache.telemetry);
35
+ }
36
+ export function writePlanCacheV2(input) {
37
+ if (!input.cache.provider || input.plan.emergency)
38
+ return;
39
+ if (input.plan.selectedRepresentations.some((representation) => representation.cache?.hit === true))
40
+ return;
41
+ input.cache.provider.writePlan({
42
+ key: input.key,
43
+ entry: {
44
+ createdAtEpochMs: input.cache.nowEpochMs,
45
+ plan: input.plan,
46
+ sourceHashes: sourceHashesByContextBudgetItemIdV2(input.planned),
47
+ },
48
+ });
49
+ }
50
+ //# sourceMappingURL=context-budget-v2-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-budget-v2-cache.js","sourceRoot":"","sources":["../../src/core/context-budget-v2-cache.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContextBudgetCacheKeyBaseV2 } from \"./context-budget-v2-cache-keys.ts\";\nimport {\n\tcreateMutableContextBudgetCacheTelemetryV2,\n\ttype MutableTokenCacheTelemetryV2,\n\twithCacheTelemetry,\n} from \"./context-budget-v2-cache-telemetry.ts\";\nimport {\n\tsourceHashesByContextBudgetItemIdV2,\n\tvalidateContextBudgetPlanCacheEntryV2,\n} from \"./context-budget-v2-cache-validation.ts\";\nimport type { PlannedItemV2 } from \"./context-budget-v2-scoring.ts\";\nimport type { ContextBudgetCacheProviderV2, PromptContextBudgetPlanV2 } from \"./context-budget-v2-types.ts\";\n\nexport {\n\tbuildContextBudgetExactRepresentationCacheKeyV2,\n\tbuildContextBudgetMaterializedRepresentationCacheKeyV2,\n\tbuildContextBudgetMaterializedRepresentationCandidateKeyV2,\n\tbuildContextBudgetRepresentationCacheKeyV2,\n\ttype ContextBudgetCacheKeyBaseV2,\n\tcomputeContextBudgetOutputTextHashV2,\n\tcomputeContextBudgetQueryIntentHashV2,\n\tcomputeContextBudgetRepresentationFingerprintV2,\n\tcomputeContextBudgetTargetTokenBucketV2,\n\tcreateContextBudgetCacheKeyBaseV2,\n\tDEFAULT_MATERIALIZED_COMPRESSOR_POLICY_HASH_V2,\n\tDEFAULT_MATERIALIZED_QUALITY_POLICY_HASH_V2,\n} from \"./context-budget-v2-cache-keys.ts\";\nexport { createMemoryContextBudgetCacheProviderV2 } from \"./context-budget-v2-cache-provider.ts\";\nexport {\n\tfinalizeContextBudgetCacheTelemetryV2,\n\ttype MutableTokenCacheTelemetryV2,\n\twithCacheTelemetry,\n} from \"./context-budget-v2-cache-telemetry.ts\";\nexport { buildContextBudgetPlanCacheKeyV2 } from \"./context-budget-v2-plan-cache-keys.ts\";\nexport {\n\tapplyRepresentationCacheV2,\n\tisMaterializableRepresentationV2,\n\twriteRepresentationCacheV2,\n} from \"./context-budget-v2-representation-cache.ts\";\n\nconst DEFAULT_CACHE_TTL_MS = 5 * 60 * 1000;\n\nexport interface ContextBudgetSelectionCacheV2 {\n\treadonly provider?: ContextBudgetCacheProviderV2;\n\treadonly keyBase: ContextBudgetCacheKeyBaseV2;\n\treadonly nowEpochMs: number;\n\treadonly ttlMs: number;\n\treadonly telemetry: MutableTokenCacheTelemetryV2;\n}\n\nexport function createContextBudgetSelectionCacheV2(input: {\n\treadonly provider?: ContextBudgetCacheProviderV2;\n\treadonly keyBase: ContextBudgetCacheKeyBaseV2;\n\treadonly planCacheKey: string;\n\treadonly nowEpochMs?: number;\n\treadonly ttlMs?: number;\n}): ContextBudgetSelectionCacheV2 {\n\treturn {\n\t\tprovider: input.provider,\n\t\tkeyBase: input.keyBase,\n\t\tnowEpochMs: input.nowEpochMs ?? Date.now(),\n\t\tttlMs: input.ttlMs ?? DEFAULT_CACHE_TTL_MS,\n\t\ttelemetry: createMutableContextBudgetCacheTelemetryV2(input.planCacheKey),\n\t};\n}\n\nexport function readValidPlanCacheV2(input: {\n\treadonly cache: ContextBudgetSelectionCacheV2;\n\treadonly key: string;\n\treadonly planned: readonly PlannedItemV2[];\n\treadonly availableTokens: number;\n}): PromptContextBudgetPlanV2 | undefined {\n\tconst read = input.cache.provider?.readPlan(input.key);\n\tif (!read) return undefined;\n\tconst rejection = validateContextBudgetPlanCacheEntryV2({\n\t\tavailableTokens: input.availableTokens,\n\t\tcache: input.cache,\n\t\tentry: read.entry,\n\t\tplanned: input.planned,\n\t});\n\tif (rejection) {\n\t\tinput.cache.telemetry.planCache.rejectedReason = rejection;\n\t\treturn undefined;\n\t}\n\tinput.cache.telemetry.planCache.hit = true;\n\tinput.cache.telemetry.planCache.layer = read.layer;\n\treturn withCacheTelemetry(read.entry.plan, input.cache.telemetry);\n}\n\nexport function writePlanCacheV2(input: {\n\treadonly cache: ContextBudgetSelectionCacheV2;\n\treadonly key: string;\n\treadonly plan: PromptContextBudgetPlanV2;\n\treadonly planned: readonly PlannedItemV2[];\n}): void {\n\tif (!input.cache.provider || input.plan.emergency) return;\n\tif (input.plan.selectedRepresentations.some((representation) => representation.cache?.hit === true)) return;\n\tinput.cache.provider.writePlan({\n\t\tkey: input.key,\n\t\tentry: {\n\t\t\tcreatedAtEpochMs: input.cache.nowEpochMs,\n\t\t\tplan: input.plan,\n\t\t\tsourceHashes: sourceHashesByContextBudgetItemIdV2(input.planned),\n\t\t},\n\t});\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import type { HeadroomQualityPolicyV2 } from "./context-budget-headroom.ts";
2
+ import { type ContextBudgetCacheKeyBaseV2 } from "./context-budget-v2-cache-keys.ts";
3
+ import type { PlannedItemV2 } from "./context-budget-v2-scoring.ts";
4
+ import type { TierBudgetPolicyV2 } from "./context-budget-v2-types.ts";
5
+ export declare function buildContextBudgetPlanCacheKeyV2(input: {
6
+ readonly keyBase: ContextBudgetCacheKeyBaseV2;
7
+ readonly promptHash?: string;
8
+ readonly maxTokens: number;
9
+ readonly responseReserveTokens: number;
10
+ readonly safetyMarginTokens: number;
11
+ readonly availableTokens: number;
12
+ readonly planned: readonly PlannedItemV2[];
13
+ readonly tierPolicy: Readonly<Record<string, TierBudgetPolicyV2>>;
14
+ readonly qualityPolicy: HeadroomQualityPolicyV2;
15
+ }): string;
16
+ //# sourceMappingURL=context-budget-v2-plan-cache-keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-budget-v2-plan-cache-keys.d.ts","sourceRoot":"","sources":["../../src/core/context-budget-v2-plan-cache-keys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAE5E,OAAO,EACN,KAAK,2BAA2B,EAGhC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,wBAAgB,gCAAgC,CAAC,KAAK,EAAE;IACvD,QAAQ,CAAC,OAAO,EAAE,2BAA2B,CAAC;IAC9C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,CAAC;IAC3C,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAClE,QAAQ,CAAC,aAAa,EAAE,uBAAuB,CAAC;CAChD,GAAG,MAAM,CA6CT","sourcesContent":["import type { HeadroomQualityPolicyV2 } from \"./context-budget-headroom.ts\";\nimport { sha256Canonical } from \"./context-budget-v2-cache-hash.ts\";\nimport {\n\ttype ContextBudgetCacheKeyBaseV2,\n\tcomputeContextBudgetRepresentationFingerprintV2,\n\tfingerprintSourceRef,\n} from \"./context-budget-v2-cache-keys.ts\";\nimport type { PlannedItemV2 } from \"./context-budget-v2-scoring.ts\";\nimport type { TierBudgetPolicyV2 } from \"./context-budget-v2-types.ts\";\n\nexport function buildContextBudgetPlanCacheKeyV2(input: {\n\treadonly keyBase: ContextBudgetCacheKeyBaseV2;\n\treadonly promptHash?: string;\n\treadonly maxTokens: number;\n\treadonly responseReserveTokens: number;\n\treadonly safetyMarginTokens: number;\n\treadonly availableTokens: number;\n\treadonly planned: readonly PlannedItemV2[];\n\treadonly tierPolicy: Readonly<Record<string, TierBudgetPolicyV2>>;\n\treadonly qualityPolicy: HeadroomQualityPolicyV2;\n}): string {\n\treturn `context-plan:${sha256Canonical({\n\t\tavailableTokens: input.availableTokens,\n\t\tbudgetBucket: input.keyBase.budgetBucket,\n\t\titems: input.planned\n\t\t\t.map((planned) => ({\n\t\t\t\tageTurns: planned.item.ageTurns ?? null,\n\t\t\t\tbaseScore: planned.baseScore,\n\t\t\t\teffectiveScore: planned.effectiveScore,\n\t\t\t\tevidenceKind: planned.item.evidenceKind ?? null,\n\t\t\t\tevidenceValue: planned.item.evidenceValue ?? null,\n\t\t\t\tid: planned.item.id,\n\t\t\t\tpinReason: planned.item.pinReason ?? null,\n\t\t\t\tpriority: planned.item.priority,\n\t\t\t\trecency: planned.item.recency ?? null,\n\t\t\t\tredundancyKey: planned.item.redundancyKey ?? null,\n\t\t\t\tredundancyPenalty: planned.redundancyPenalty,\n\t\t\t\trelevance: planned.item.relevance ?? null,\n\t\t\t\trepresentations: (planned.item.representations ?? [])\n\t\t\t\t\t.map((candidate) => ({\n\t\t\t\t\t\tfingerprint: computeContextBudgetRepresentationFingerprintV2(candidate),\n\t\t\t\t\t\tkind: candidate.kind,\n\t\t\t\t\t}))\n\t\t\t\t\t.sort((a, b) => a.kind.localeCompare(b.kind) || a.fingerprint.localeCompare(b.fingerprint)),\n\t\t\t\trequired: planned.item.required === true,\n\t\t\t\tsourceRef: fingerprintSourceRef(planned.item.sourceRef),\n\t\t\t\tsourceHash: planned.contentHash,\n\t\t\t\ttier: planned.item.tier,\n\t\t\t\ttokenEstimate: planned.item.tokenEstimate ?? null,\n\t\t\t}))\n\t\t\t.sort((a, b) => a.id.localeCompare(b.id)),\n\t\tmaxTokens: input.maxTokens,\n\t\tmodelId: input.keyBase.modelId,\n\t\tnamespace: input.keyBase.namespace,\n\t\tpolicyVersion: input.keyBase.policyVersion,\n\t\tpromptHash: input.promptHash ?? null,\n\t\tqueryIntentHash: input.keyBase.queryIntentHash,\n\t\tredactionPolicyHash: input.keyBase.redactionPolicyHash,\n\t\tresponseReserveTokens: input.responseReserveTokens,\n\t\tsafetyMarginTokens: input.safetyMarginTokens,\n\t\tsafetyProfileHash: input.keyBase.safetyProfileHash,\n\t\ttierPolicy: input.tierPolicy,\n\t\tqualityPolicy: input.qualityPolicy,\n\t\ttokenizerId: input.keyBase.tokenizerId,\n\t})}`;\n}\n"]}
@@ -0,0 +1,49 @@
1
+ import { sha256Canonical } from "./context-budget-v2-cache-hash.js";
2
+ import { computeContextBudgetRepresentationFingerprintV2, fingerprintSourceRef, } from "./context-budget-v2-cache-keys.js";
3
+ export function buildContextBudgetPlanCacheKeyV2(input) {
4
+ return `context-plan:${sha256Canonical({
5
+ availableTokens: input.availableTokens,
6
+ budgetBucket: input.keyBase.budgetBucket,
7
+ items: input.planned
8
+ .map((planned) => ({
9
+ ageTurns: planned.item.ageTurns ?? null,
10
+ baseScore: planned.baseScore,
11
+ effectiveScore: planned.effectiveScore,
12
+ evidenceKind: planned.item.evidenceKind ?? null,
13
+ evidenceValue: planned.item.evidenceValue ?? null,
14
+ id: planned.item.id,
15
+ pinReason: planned.item.pinReason ?? null,
16
+ priority: planned.item.priority,
17
+ recency: planned.item.recency ?? null,
18
+ redundancyKey: planned.item.redundancyKey ?? null,
19
+ redundancyPenalty: planned.redundancyPenalty,
20
+ relevance: planned.item.relevance ?? null,
21
+ representations: (planned.item.representations ?? [])
22
+ .map((candidate) => ({
23
+ fingerprint: computeContextBudgetRepresentationFingerprintV2(candidate),
24
+ kind: candidate.kind,
25
+ }))
26
+ .sort((a, b) => a.kind.localeCompare(b.kind) || a.fingerprint.localeCompare(b.fingerprint)),
27
+ required: planned.item.required === true,
28
+ sourceRef: fingerprintSourceRef(planned.item.sourceRef),
29
+ sourceHash: planned.contentHash,
30
+ tier: planned.item.tier,
31
+ tokenEstimate: planned.item.tokenEstimate ?? null,
32
+ }))
33
+ .sort((a, b) => a.id.localeCompare(b.id)),
34
+ maxTokens: input.maxTokens,
35
+ modelId: input.keyBase.modelId,
36
+ namespace: input.keyBase.namespace,
37
+ policyVersion: input.keyBase.policyVersion,
38
+ promptHash: input.promptHash ?? null,
39
+ queryIntentHash: input.keyBase.queryIntentHash,
40
+ redactionPolicyHash: input.keyBase.redactionPolicyHash,
41
+ responseReserveTokens: input.responseReserveTokens,
42
+ safetyMarginTokens: input.safetyMarginTokens,
43
+ safetyProfileHash: input.keyBase.safetyProfileHash,
44
+ tierPolicy: input.tierPolicy,
45
+ qualityPolicy: input.qualityPolicy,
46
+ tokenizerId: input.keyBase.tokenizerId,
47
+ })}`;
48
+ }
49
+ //# sourceMappingURL=context-budget-v2-plan-cache-keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-budget-v2-plan-cache-keys.js","sourceRoot":"","sources":["../../src/core/context-budget-v2-plan-cache-keys.ts"],"names":[],"mappings":"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","sourcesContent":["import type { HeadroomQualityPolicyV2 } from \"./context-budget-headroom.ts\";\nimport { sha256Canonical } from \"./context-budget-v2-cache-hash.ts\";\nimport {\n\ttype ContextBudgetCacheKeyBaseV2,\n\tcomputeContextBudgetRepresentationFingerprintV2,\n\tfingerprintSourceRef,\n} from \"./context-budget-v2-cache-keys.ts\";\nimport type { PlannedItemV2 } from \"./context-budget-v2-scoring.ts\";\nimport type { TierBudgetPolicyV2 } from \"./context-budget-v2-types.ts\";\n\nexport function buildContextBudgetPlanCacheKeyV2(input: {\n\treadonly keyBase: ContextBudgetCacheKeyBaseV2;\n\treadonly promptHash?: string;\n\treadonly maxTokens: number;\n\treadonly responseReserveTokens: number;\n\treadonly safetyMarginTokens: number;\n\treadonly availableTokens: number;\n\treadonly planned: readonly PlannedItemV2[];\n\treadonly tierPolicy: Readonly<Record<string, TierBudgetPolicyV2>>;\n\treadonly qualityPolicy: HeadroomQualityPolicyV2;\n}): string {\n\treturn `context-plan:${sha256Canonical({\n\t\tavailableTokens: input.availableTokens,\n\t\tbudgetBucket: input.keyBase.budgetBucket,\n\t\titems: input.planned\n\t\t\t.map((planned) => ({\n\t\t\t\tageTurns: planned.item.ageTurns ?? null,\n\t\t\t\tbaseScore: planned.baseScore,\n\t\t\t\teffectiveScore: planned.effectiveScore,\n\t\t\t\tevidenceKind: planned.item.evidenceKind ?? null,\n\t\t\t\tevidenceValue: planned.item.evidenceValue ?? null,\n\t\t\t\tid: planned.item.id,\n\t\t\t\tpinReason: planned.item.pinReason ?? null,\n\t\t\t\tpriority: planned.item.priority,\n\t\t\t\trecency: planned.item.recency ?? null,\n\t\t\t\tredundancyKey: planned.item.redundancyKey ?? null,\n\t\t\t\tredundancyPenalty: planned.redundancyPenalty,\n\t\t\t\trelevance: planned.item.relevance ?? null,\n\t\t\t\trepresentations: (planned.item.representations ?? [])\n\t\t\t\t\t.map((candidate) => ({\n\t\t\t\t\t\tfingerprint: computeContextBudgetRepresentationFingerprintV2(candidate),\n\t\t\t\t\t\tkind: candidate.kind,\n\t\t\t\t\t}))\n\t\t\t\t\t.sort((a, b) => a.kind.localeCompare(b.kind) || a.fingerprint.localeCompare(b.fingerprint)),\n\t\t\t\trequired: planned.item.required === true,\n\t\t\t\tsourceRef: fingerprintSourceRef(planned.item.sourceRef),\n\t\t\t\tsourceHash: planned.contentHash,\n\t\t\t\ttier: planned.item.tier,\n\t\t\t\ttokenEstimate: planned.item.tokenEstimate ?? null,\n\t\t\t}))\n\t\t\t.sort((a, b) => a.id.localeCompare(b.id)),\n\t\tmaxTokens: input.maxTokens,\n\t\tmodelId: input.keyBase.modelId,\n\t\tnamespace: input.keyBase.namespace,\n\t\tpolicyVersion: input.keyBase.policyVersion,\n\t\tpromptHash: input.promptHash ?? null,\n\t\tqueryIntentHash: input.keyBase.queryIntentHash,\n\t\tredactionPolicyHash: input.keyBase.redactionPolicyHash,\n\t\tresponseReserveTokens: input.responseReserveTokens,\n\t\tsafetyMarginTokens: input.safetyMarginTokens,\n\t\tsafetyProfileHash: input.keyBase.safetyProfileHash,\n\t\ttierPolicy: input.tierPolicy,\n\t\tqualityPolicy: input.qualityPolicy,\n\t\ttokenizerId: input.keyBase.tokenizerId,\n\t})}`;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"context-budget-v2-planner.d.ts","sourceRoot":"","sources":["../../src/core/context-budget-v2-planner.ts"],"names":[],"mappings":"AAmBA,OAAO,EAGN,KAAK,0BAA0B,EAE/B,KAAK,yBAAyB,EAI9B,MAAM,8BAA8B,CAAC;AAGtC,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,0BAA0B,GAAG,yBAAyB,CAoHtG","sourcesContent":["import {\n\ttype ContextBudgetItemV2,\n\ttype ContextBudgetTierV2,\n\ttype ContextSourceRefV2,\n\tDEFAULT_HEADROOM_QUALITY_POLICY,\n} from \"./context-budget-headroom.ts\";\nimport { computePlanHash } from \"./context-budget-v2-plan-hash.ts\";\nimport { compareOptionalForSelection } from \"./context-budget-v2-scoring.ts\";\nimport {\n\tapplyPlannerRedundancyPenalties,\n\tbuildTierAllocations,\n\tcreatePlannedItems,\n\tcreateTierUsage,\n\temitCoverageDiagnostics,\n\temitOmissionDiagnostics,\n\tselectHardItem,\n\tselectOptionalItem,\n} from \"./context-budget-v2-selection.ts\";\nimport { allocateTiers, computeTierDemand } from \"./context-budget-v2-tiers.ts\";\nimport {\n\tCONTEXT_BUDGET_POLICY_VERSION_V2,\n\tDEFAULT_TIER_POLICY_V2,\n\ttype PromptContextBudgetInputV2,\n\ttype PromptContextBudgetObservabilityV2,\n\ttype PromptContextBudgetPlanV2,\n\ttype QualityDiagnosticV2,\n\ttype SelectedRepresentationV2,\n\ttype TierBudgetPolicyV2,\n} from \"./context-budget-v2-types.ts\";\nimport { getTokenOptimizerRuntimeStatus } from \"./token-optimizer.ts\";\n\nexport function planPromptContextBudgetV2(input: PromptContextBudgetInputV2): PromptContextBudgetPlanV2 {\n\tconst modelId = input.modelId ?? \"unknown\";\n\tconst qualityPolicy = input.qualityPolicy ?? DEFAULT_HEADROOM_QUALITY_POLICY;\n\tconst policyVersion = input.policyVersion ?? CONTEXT_BUDGET_POLICY_VERSION_V2;\n\tconst diagnostics: QualityDiagnosticV2[] = [];\n\n\tconst maxTokens = normalizeBudgetTokens(\"maxTokens\", input.maxTokens, diagnostics);\n\tconst responseReserve = normalizeBudgetTokens(\n\t\t\"responseReserveTokens\",\n\t\tinput.responseReserveTokens ?? 0,\n\t\tdiagnostics,\n\t);\n\tconst safetyMargin = normalizeBudgetTokens(\n\t\t\"safetyMarginTokens\",\n\t\tinput.safetyMarginTokens ?? Math.ceil(maxTokens * 0.05),\n\t\tdiagnostics,\n\t);\n\tconst available = Math.max(0, maxTokens - responseReserve - safetyMargin);\n\n\tconst tierPolicy: Readonly<Record<ContextBudgetTierV2, TierBudgetPolicyV2>> = {\n\t\t...DEFAULT_TIER_POLICY_V2,\n\t\t...(input.tierPolicy ?? {}),\n\t};\n\tconst basePlanned = createPlannedItems(input.items, input.tokenCounter, modelId);\n\tapplyPlannerRedundancyPenalties(basePlanned);\n\n\tconst demand = computeTierDemand(basePlanned);\n\tconst allocation = allocateTiers(available, tierPolicy, demand);\n\tconst selection = new Map<string, SelectedRepresentationV2>();\n\tconst tierUsed = createTierUsage();\n\tconst omitted: ContextBudgetItemV2[] = [];\n\tconst retrievalFallbacks: ContextSourceRefV2[] = [];\n\tlet usedTokens = 0;\n\n\tfor (const planned of basePlanned) {\n\t\tif (!planned.isHard) continue;\n\t\tusedTokens += selectHardItem(planned, selection, tierUsed);\n\t}\n\tif (usedTokens > available) {\n\t\tdiagnostics.push({\n\t\t\treason: \"hard_pin_over_capacity\",\n\t\t\tdetail: `hard-pinned context uses ${usedTokens} tokens against ${available} available tokens`,\n\t\t});\n\t}\n\n\tconst optionalPlanned = basePlanned.filter((planned) => !planned.isHard).sort(compareOptionalForSelection);\n\tfor (const planned of optionalPlanned) {\n\t\tusedTokens = selectOptionalItem(planned, {\n\t\t\tallocation,\n\t\t\tavailable,\n\t\t\tdiagnostics,\n\t\t\tomitted,\n\t\t\tqualityPolicy,\n\t\t\tretrievalFallbacks,\n\t\t\tselection,\n\t\t\ttierUsed,\n\t\t\tusedTokens,\n\t\t});\n\t}\n\n\tconst omittedHighPriority = omitted.some((item) => item.priority === \"high\" || item.required === true);\n\temitOmissionDiagnostics(omitted, diagnostics, retrievalFallbacks);\n\temitCoverageDiagnostics(input.query, selection, diagnostics);\n\n\tconst tierAllocations = buildTierAllocations(allocation, demand, tierUsed);\n\tconst rawTokens = basePlanned.reduce((sum, planned) => sum + planned.fullTokens, 0);\n\tconst omittedTokens = omitted.reduce(\n\t\t(sum, item) => sum + (basePlanned.find((planned) => planned.item.id === item.id)?.fullTokens ?? 0),\n\t\t0,\n\t);\n\tconst omittedItemIds = omitted.map((item) => item.id);\n\tconst planHash = computePlanHash({\n\t\tpolicyVersion,\n\t\tpromptHash: input.promptHash,\n\t\tplanned: basePlanned,\n\t\tselection,\n\t\tallocations: tierAllocations,\n\t\tomittedItemIds,\n\t});\n\tconst observability = buildObservability({\n\t\tavailable,\n\t\tdiagnostics,\n\t\tomittedItemIds,\n\t\tomittedTokens,\n\t\tplanHash,\n\t\trawTokens,\n\t\tretrievalFallbacks,\n\t\tselection,\n\t\tusedTokens,\n\t});\n\n\treturn {\n\t\tpolicyVersion,\n\t\tpromptHash: input.promptHash,\n\t\tplanHash,\n\t\tmaxTokens,\n\t\tresponseReserveTokens: responseReserve,\n\t\tsafetyMarginTokens: safetyMargin,\n\t\tavailableTokens: available,\n\t\tusedTokens,\n\t\tomittedTokens,\n\t\trawTokens,\n\t\ttokenSavingsRatio: rawTokens > 0 ? Math.max(0, 1 - usedTokens / rawTokens) : 0,\n\t\temergency: usedTokens > available || diagnostics.some((diagnostic) => diagnostic.reason === \"invalid_budget\"),\n\t\tomittedHighPriority,\n\t\ttierAllocations,\n\t\tselectedRepresentations: [...selection.values()].sort((a, b) => a.itemId.localeCompare(b.itemId)),\n\t\tincludedItemIds: basePlanned\n\t\t\t.map((planned) => planned.item.id)\n\t\t\t.filter((id) => selection.has(id))\n\t\t\t.sort(),\n\t\tomittedItemIds,\n\t\tdiagnostics,\n\t\tretrievalFallbacks,\n\t\tobservability,\n\t};\n}\n\nfunction normalizeBudgetTokens(field: string, value: number, diagnostics: QualityDiagnosticV2[]): number {\n\tif (!Number.isFinite(value) || value < 0) {\n\t\tdiagnostics.push({\n\t\t\treason: \"invalid_budget\",\n\t\t\tdetail: `${field} must be a non-negative finite number, got ${value}`,\n\t\t});\n\t\treturn 0;\n\t}\n\treturn Math.floor(value);\n}\n\nfunction buildObservability(input: {\n\treadonly available: number;\n\treadonly diagnostics: readonly QualityDiagnosticV2[];\n\treadonly omittedItemIds: readonly string[];\n\treadonly omittedTokens: number;\n\treadonly planHash: string;\n\treadonly rawTokens: number;\n\treadonly retrievalFallbacks: readonly ContextSourceRefV2[];\n\treadonly selection: ReadonlyMap<string, SelectedRepresentationV2>;\n\treadonly usedTokens: number;\n}): PromptContextBudgetObservabilityV2 {\n\tconst selected = [...input.selection.values()];\n\treturn {\n\t\tcounts: {\n\t\t\tselected: selected.length,\n\t\t\tomitted: input.omittedItemIds.length,\n\t\t\tpointer: selected.filter((representation) => representation.kind === \"pointer\").length,\n\t\t\tcompressed: selected.filter((representation) => representation.kind === \"headroom-compressed\").length,\n\t\t\tfull: selected.filter((representation) => representation.kind === \"full\").length,\n\t\t\tretrievalFallback: countUniqueRetrievalFallbacks(input.retrievalFallbacks),\n\t\t},\n\t\tdiagnosticReasons: [...new Set(input.diagnostics.map((diagnostic) => diagnostic.reason))].sort(),\n\t\ttokens: {\n\t\t\tavailable: input.available,\n\t\t\tused: input.usedTokens,\n\t\t\traw: input.rawTokens,\n\t\t\tomitted: input.omittedTokens,\n\t\t\ttokenSavings: Math.max(0, input.rawTokens - input.usedTokens),\n\t\t},\n\t\tplanHash: input.planHash,\n\t\ttokenOptimizer: getTokenOptimizerRuntimeStatus(),\n\t};\n}\n\nfunction countUniqueRetrievalFallbacks(retrievalFallbacks: readonly ContextSourceRefV2[]): number {\n\treturn new Set(\n\t\tretrievalFallbacks.map((ref) =>\n\t\t\t[ref.uri, ref.contentHash, ref.symbol ?? \"\", ref.range?.startLine ?? \"\", ref.range?.endLine ?? \"\"].join(\"\\0\"),\n\t\t),\n\t).size;\n}\n"]}
1
+ {"version":3,"file":"context-budget-v2-planner.d.ts","sourceRoot":"","sources":["../../src/core/context-budget-v2-planner.ts"],"names":[],"mappings":"AA2BA,OAAO,EAGN,KAAK,0BAA0B,EAE/B,KAAK,yBAAyB,EAI9B,MAAM,8BAA8B,CAAC;AAGtC,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,0BAA0B,GAAG,yBAAyB,CAuKtG","sourcesContent":["import {\n\ttype ContextBudgetItemV2,\n\ttype ContextBudgetTierV2,\n\ttype ContextSourceRefV2,\n\tDEFAULT_HEADROOM_QUALITY_POLICY,\n} from \"./context-budget-headroom.ts\";\nimport {\n\tbuildContextBudgetPlanCacheKeyV2,\n\tcreateContextBudgetCacheKeyBaseV2,\n\tcreateContextBudgetSelectionCacheV2,\n\tfinalizeContextBudgetCacheTelemetryV2,\n\treadValidPlanCacheV2,\n\twritePlanCacheV2,\n} from \"./context-budget-v2-cache.ts\";\nimport { computePlanHash } from \"./context-budget-v2-plan-hash.ts\";\nimport { compareOptionalForSelection } from \"./context-budget-v2-scoring.ts\";\nimport {\n\tapplyPlannerRedundancyPenalties,\n\tbuildTierAllocations,\n\tcreatePlannedItems,\n\tcreateTierUsage,\n\temitCoverageDiagnostics,\n\temitOmissionDiagnostics,\n\tselectHardItem,\n\tselectOptionalItem,\n} from \"./context-budget-v2-selection.ts\";\nimport { allocateTiers, computeTierDemand } from \"./context-budget-v2-tiers.ts\";\nimport {\n\tCONTEXT_BUDGET_POLICY_VERSION_V2,\n\tDEFAULT_TIER_POLICY_V2,\n\ttype PromptContextBudgetInputV2,\n\ttype PromptContextBudgetObservabilityV2,\n\ttype PromptContextBudgetPlanV2,\n\ttype QualityDiagnosticV2,\n\ttype SelectedRepresentationV2,\n\ttype TierBudgetPolicyV2,\n} from \"./context-budget-v2-types.ts\";\nimport { getTokenOptimizerRuntimeStatus } from \"./token-optimizer.ts\";\n\nexport function planPromptContextBudgetV2(input: PromptContextBudgetInputV2): PromptContextBudgetPlanV2 {\n\tconst modelId = input.modelId ?? \"unknown\";\n\tconst qualityPolicy = input.qualityPolicy ?? DEFAULT_HEADROOM_QUALITY_POLICY;\n\tconst policyVersion = input.policyVersion ?? CONTEXT_BUDGET_POLICY_VERSION_V2;\n\tconst diagnostics: QualityDiagnosticV2[] = [];\n\n\tconst maxTokens = normalizeBudgetTokens(\"maxTokens\", input.maxTokens, diagnostics);\n\tconst responseReserve = normalizeBudgetTokens(\n\t\t\"responseReserveTokens\",\n\t\tinput.responseReserveTokens ?? 0,\n\t\tdiagnostics,\n\t);\n\tconst safetyMargin = normalizeBudgetTokens(\n\t\t\"safetyMarginTokens\",\n\t\tinput.safetyMarginTokens ?? Math.ceil(maxTokens * 0.05),\n\t\tdiagnostics,\n\t);\n\tconst available = Math.max(0, maxTokens - responseReserve - safetyMargin);\n\n\tconst tierPolicy: Readonly<Record<ContextBudgetTierV2, TierBudgetPolicyV2>> = {\n\t\t...DEFAULT_TIER_POLICY_V2,\n\t\t...(input.tierPolicy ?? {}),\n\t};\n\tconst basePlanned = createPlannedItems(input.items, input.tokenCounter, modelId);\n\tapplyPlannerRedundancyPenalties(basePlanned);\n\tconst rawTokens = basePlanned.reduce((sum, planned) => sum + planned.fullTokens, 0);\n\n\tconst demand = computeTierDemand(basePlanned);\n\tconst allocation = allocateTiers(available, tierPolicy, demand);\n\tconst cacheKeyBase = createContextBudgetCacheKeyBaseV2({\n\t\tbudgetBucket: input.cacheBudgetBucket ?? String(available),\n\t\tmodelId,\n\t\tnamespace: input.cacheNamespace,\n\t\tpolicyVersion,\n\t\tquery: input.query,\n\t\tqueryIntentHash: input.queryIntentHash,\n\t\tredactionPolicyHash: input.redactionPolicyHash,\n\t\tsafetyProfileHash: input.safetyProfileHash,\n\t\ttokenizerId: input.tokenizerId,\n\t});\n\tconst planCacheKey = buildContextBudgetPlanCacheKeyV2({\n\t\tavailableTokens: available,\n\t\tkeyBase: cacheKeyBase,\n\t\tmaxTokens,\n\t\tplanned: basePlanned,\n\t\tpromptHash: input.promptHash,\n\t\tqualityPolicy,\n\t\tresponseReserveTokens: responseReserve,\n\t\tsafetyMarginTokens: safetyMargin,\n\t\ttierPolicy,\n\t});\n\tconst cache = createContextBudgetSelectionCacheV2({\n\t\tkeyBase: cacheKeyBase,\n\t\tnowEpochMs: input.cacheNowEpochMs,\n\t\tplanCacheKey,\n\t\tprovider: input.cacheProvider,\n\t\tttlMs: input.cacheTtlMs,\n\t});\n\tconst cachedPlan = readValidPlanCacheV2({\n\t\tavailableTokens: available,\n\t\tcache,\n\t\tkey: planCacheKey,\n\t\tplanned: basePlanned,\n\t});\n\tif (cachedPlan) {\n\t\treturn cachedPlan;\n\t}\n\tconst selection = new Map<string, SelectedRepresentationV2>();\n\tconst tierUsed = createTierUsage();\n\tconst omitted: ContextBudgetItemV2[] = [];\n\tconst retrievalFallbacks: ContextSourceRefV2[] = [];\n\tlet usedTokens = 0;\n\n\tfor (const planned of basePlanned) {\n\t\tif (!planned.isHard) continue;\n\t\tusedTokens += selectHardItem(planned, selection, tierUsed);\n\t}\n\tif (usedTokens > available) {\n\t\tdiagnostics.push({\n\t\t\treason: \"hard_pin_over_capacity\",\n\t\t\tdetail: `hard-pinned context uses ${usedTokens} tokens against ${available} available tokens`,\n\t\t});\n\t}\n\n\tconst optionalPlanned = basePlanned.filter((planned) => !planned.isHard).sort(compareOptionalForSelection);\n\tfor (const planned of optionalPlanned) {\n\t\tusedTokens = selectOptionalItem(planned, {\n\t\t\tallocation,\n\t\t\tavailable,\n\t\t\tcache,\n\t\t\tdiagnostics,\n\t\t\tomitted,\n\t\t\tqualityPolicy,\n\t\t\tretrievalFallbacks,\n\t\t\tselection,\n\t\t\ttierUsed,\n\t\t\tusedTokens,\n\t\t});\n\t}\n\n\tconst omittedHighPriority = omitted.some((item) => item.priority === \"high\" || item.required === true);\n\temitOmissionDiagnostics(omitted, diagnostics, retrievalFallbacks);\n\temitCoverageDiagnostics(input.query, selection, diagnostics);\n\n\tconst tierAllocations = buildTierAllocations(allocation, demand, tierUsed);\n\tconst omittedTokens = omitted.reduce(\n\t\t(sum, item) => sum + (basePlanned.find((planned) => planned.item.id === item.id)?.fullTokens ?? 0),\n\t\t0,\n\t);\n\tconst omittedItemIds = omitted.map((item) => item.id);\n\tconst planHash = computePlanHash({\n\t\tpolicyVersion,\n\t\tpromptHash: input.promptHash,\n\t\tplanned: basePlanned,\n\t\tselection,\n\t\tallocations: tierAllocations,\n\t\tomittedItemIds,\n\t});\n\tconst observability = buildObservability({\n\t\tavailable,\n\t\tdiagnostics,\n\t\tomittedItemIds,\n\t\tomittedTokens,\n\t\tplanHash,\n\t\trawTokens,\n\t\tretrievalFallbacks,\n\t\tselection,\n\t\tusedTokens,\n\t\tcacheTelemetry: finalizeContextBudgetCacheTelemetryV2(cache.telemetry, {\n\t\t\tomittedTokens,\n\t\t\trawTokens,\n\t\t\tusedTokens,\n\t\t}),\n\t});\n\n\tconst plan: PromptContextBudgetPlanV2 = {\n\t\tpolicyVersion,\n\t\tpromptHash: input.promptHash,\n\t\tplanHash,\n\t\tmaxTokens,\n\t\tresponseReserveTokens: responseReserve,\n\t\tsafetyMarginTokens: safetyMargin,\n\t\tavailableTokens: available,\n\t\tusedTokens,\n\t\tomittedTokens,\n\t\trawTokens,\n\t\ttokenSavingsRatio: rawTokens > 0 ? Math.max(0, 1 - usedTokens / rawTokens) : 0,\n\t\temergency: usedTokens > available || diagnostics.some((diagnostic) => diagnostic.reason === \"invalid_budget\"),\n\t\tomittedHighPriority,\n\t\ttierAllocations,\n\t\tselectedRepresentations: [...selection.values()].sort((a, b) => a.itemId.localeCompare(b.itemId)),\n\t\tincludedItemIds: basePlanned\n\t\t\t.map((planned) => planned.item.id)\n\t\t\t.filter((id) => selection.has(id))\n\t\t\t.sort(),\n\t\tomittedItemIds,\n\t\tdiagnostics,\n\t\tretrievalFallbacks,\n\t\tobservability,\n\t};\n\twritePlanCacheV2({\n\t\tcache,\n\t\tkey: planCacheKey,\n\t\tplan,\n\t\tplanned: basePlanned,\n\t});\n\treturn plan;\n}\n\nfunction normalizeBudgetTokens(field: string, value: number, diagnostics: QualityDiagnosticV2[]): number {\n\tif (!Number.isFinite(value) || value < 0) {\n\t\tdiagnostics.push({\n\t\t\treason: \"invalid_budget\",\n\t\t\tdetail: `${field} must be a non-negative finite number, got ${value}`,\n\t\t});\n\t\treturn 0;\n\t}\n\treturn Math.floor(value);\n}\n\nfunction buildObservability(input: {\n\treadonly available: number;\n\treadonly diagnostics: readonly QualityDiagnosticV2[];\n\treadonly omittedItemIds: readonly string[];\n\treadonly omittedTokens: number;\n\treadonly planHash: string;\n\treadonly rawTokens: number;\n\treadonly retrievalFallbacks: readonly ContextSourceRefV2[];\n\treadonly selection: ReadonlyMap<string, SelectedRepresentationV2>;\n\treadonly usedTokens: number;\n\treadonly cacheTelemetry: PromptContextBudgetObservabilityV2[\"cache\"];\n}): PromptContextBudgetObservabilityV2 {\n\tconst selected = [...input.selection.values()];\n\treturn {\n\t\tcounts: {\n\t\t\tselected: selected.length,\n\t\t\tomitted: input.omittedItemIds.length,\n\t\t\tpointer: selected.filter((representation) => representation.kind === \"pointer\").length,\n\t\t\tcompressed: selected.filter((representation) => representation.kind === \"headroom-compressed\").length,\n\t\t\tfull: selected.filter((representation) => representation.kind === \"full\").length,\n\t\t\tretrievalFallback: countUniqueRetrievalFallbacks(input.retrievalFallbacks),\n\t\t},\n\t\tdiagnosticReasons: [...new Set(input.diagnostics.map((diagnostic) => diagnostic.reason))].sort(),\n\t\ttokens: {\n\t\t\tavailable: input.available,\n\t\t\tused: input.usedTokens,\n\t\t\traw: input.rawTokens,\n\t\t\tomitted: input.omittedTokens,\n\t\t\ttokenSavings: Math.max(0, input.rawTokens - input.usedTokens),\n\t\t},\n\t\tplanHash: input.planHash,\n\t\tcache: input.cacheTelemetry,\n\t\ttokenOptimizer: getTokenOptimizerRuntimeStatus(),\n\t};\n}\n\nfunction countUniqueRetrievalFallbacks(retrievalFallbacks: readonly ContextSourceRefV2[]): number {\n\treturn new Set(\n\t\tretrievalFallbacks.map((ref) =>\n\t\t\t[ref.uri, ref.contentHash, ref.symbol ?? \"\", ref.range?.startLine ?? \"\", ref.range?.endLine ?? \"\"].join(\"\\0\"),\n\t\t),\n\t).size;\n}\n"]}
@@ -1,4 +1,5 @@
1
1
  import { DEFAULT_HEADROOM_QUALITY_POLICY, } from "./context-budget-headroom.js";
2
+ import { buildContextBudgetPlanCacheKeyV2, createContextBudgetCacheKeyBaseV2, createContextBudgetSelectionCacheV2, finalizeContextBudgetCacheTelemetryV2, readValidPlanCacheV2, writePlanCacheV2, } from "./context-budget-v2-cache.js";
2
3
  import { computePlanHash } from "./context-budget-v2-plan-hash.js";
3
4
  import { compareOptionalForSelection } from "./context-budget-v2-scoring.js";
4
5
  import { applyPlannerRedundancyPenalties, buildTierAllocations, createPlannedItems, createTierUsage, emitCoverageDiagnostics, emitOmissionDiagnostics, selectHardItem, selectOptionalItem, } from "./context-budget-v2-selection.js";
@@ -20,8 +21,47 @@ export function planPromptContextBudgetV2(input) {
20
21
  };
21
22
  const basePlanned = createPlannedItems(input.items, input.tokenCounter, modelId);
22
23
  applyPlannerRedundancyPenalties(basePlanned);
24
+ const rawTokens = basePlanned.reduce((sum, planned) => sum + planned.fullTokens, 0);
23
25
  const demand = computeTierDemand(basePlanned);
24
26
  const allocation = allocateTiers(available, tierPolicy, demand);
27
+ const cacheKeyBase = createContextBudgetCacheKeyBaseV2({
28
+ budgetBucket: input.cacheBudgetBucket ?? String(available),
29
+ modelId,
30
+ namespace: input.cacheNamespace,
31
+ policyVersion,
32
+ query: input.query,
33
+ queryIntentHash: input.queryIntentHash,
34
+ redactionPolicyHash: input.redactionPolicyHash,
35
+ safetyProfileHash: input.safetyProfileHash,
36
+ tokenizerId: input.tokenizerId,
37
+ });
38
+ const planCacheKey = buildContextBudgetPlanCacheKeyV2({
39
+ availableTokens: available,
40
+ keyBase: cacheKeyBase,
41
+ maxTokens,
42
+ planned: basePlanned,
43
+ promptHash: input.promptHash,
44
+ qualityPolicy,
45
+ responseReserveTokens: responseReserve,
46
+ safetyMarginTokens: safetyMargin,
47
+ tierPolicy,
48
+ });
49
+ const cache = createContextBudgetSelectionCacheV2({
50
+ keyBase: cacheKeyBase,
51
+ nowEpochMs: input.cacheNowEpochMs,
52
+ planCacheKey,
53
+ provider: input.cacheProvider,
54
+ ttlMs: input.cacheTtlMs,
55
+ });
56
+ const cachedPlan = readValidPlanCacheV2({
57
+ availableTokens: available,
58
+ cache,
59
+ key: planCacheKey,
60
+ planned: basePlanned,
61
+ });
62
+ if (cachedPlan) {
63
+ return cachedPlan;
64
+ }
25
65
  const selection = new Map();
26
66
  const tierUsed = createTierUsage();
27
67
  const omitted = [];
@@ -43,6 +83,7 @@ export function planPromptContextBudgetV2(input) {
43
83
  usedTokens = selectOptionalItem(planned, {
44
84
  allocation,
45
85
  available,
86
+ cache,
46
87
  diagnostics,
47
88
  omitted,
48
89
  qualityPolicy,
@@ -56,7 +97,6 @@ export function planPromptContextBudgetV2(input) {
56
97
  emitOmissionDiagnostics(omitted, diagnostics, retrievalFallbacks);
57
98
  emitCoverageDiagnostics(input.query, selection, diagnostics);
58
99
  const tierAllocations = buildTierAllocations(allocation, demand, tierUsed);
59
- const rawTokens = basePlanned.reduce((sum, planned) => sum + planned.fullTokens, 0);
60
100
  const omittedTokens = omitted.reduce((sum, item) => sum + (basePlanned.find((planned) => planned.item.id === item.id)?.fullTokens ?? 0), 0);
61
101
  const omittedItemIds = omitted.map((item) => item.id);
62
102
  const planHash = computePlanHash({
@@ -77,8 +117,13 @@ export function planPromptContextBudgetV2(input) {
77
117
  retrievalFallbacks,
78
118
  selection,
79
119
  usedTokens,
120
+ cacheTelemetry: finalizeContextBudgetCacheTelemetryV2(cache.telemetry, {
121
+ omittedTokens,
122
+ rawTokens,
123
+ usedTokens,
124
+ }),
80
125
  });
81
- return {
126
+ const plan = {
82
127
  policyVersion,
83
128
  promptHash: input.promptHash,
84
129
  planHash,
@@ -103,6 +148,13 @@ export function planPromptContextBudgetV2(input) {
103
148
  retrievalFallbacks,
104
149
  observability,
105
150
  };
151
+ writePlanCacheV2({
152
+ cache,
153
+ key: planCacheKey,
154
+ plan,
155
+ planned: basePlanned,
156
+ });
157
+ return plan;
106
158
  }
107
159
  function normalizeBudgetTokens(field, value, diagnostics) {
108
160
  if (!Number.isFinite(value) || value < 0) {
@@ -134,6 +186,7 @@ function buildObservability(input) {
134
186
  tokenSavings: Math.max(0, input.rawTokens - input.usedTokens),
135
187
  },
136
188
  planHash: input.planHash,
189
+ cache: input.cacheTelemetry,
137
190
  tokenOptimizer: getTokenOptimizerRuntimeStatus(),
138
191
  };
139
192
  }
@@ -1 +1 @@
1
- {"version":3,"file":"context-budget-v2-planner.js","sourceRoot":"","sources":["../../src/core/context-budget-v2-planner.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype ContextBudgetItemV2,\n\ttype ContextBudgetTierV2,\n\ttype ContextSourceRefV2,\n\tDEFAULT_HEADROOM_QUALITY_POLICY,\n} from \"./context-budget-headroom.ts\";\nimport { computePlanHash } from \"./context-budget-v2-plan-hash.ts\";\nimport { compareOptionalForSelection } from \"./context-budget-v2-scoring.ts\";\nimport {\n\tapplyPlannerRedundancyPenalties,\n\tbuildTierAllocations,\n\tcreatePlannedItems,\n\tcreateTierUsage,\n\temitCoverageDiagnostics,\n\temitOmissionDiagnostics,\n\tselectHardItem,\n\tselectOptionalItem,\n} from \"./context-budget-v2-selection.ts\";\nimport { allocateTiers, computeTierDemand } from \"./context-budget-v2-tiers.ts\";\nimport {\n\tCONTEXT_BUDGET_POLICY_VERSION_V2,\n\tDEFAULT_TIER_POLICY_V2,\n\ttype PromptContextBudgetInputV2,\n\ttype PromptContextBudgetObservabilityV2,\n\ttype PromptContextBudgetPlanV2,\n\ttype QualityDiagnosticV2,\n\ttype SelectedRepresentationV2,\n\ttype TierBudgetPolicyV2,\n} from \"./context-budget-v2-types.ts\";\nimport { getTokenOptimizerRuntimeStatus } from \"./token-optimizer.ts\";\n\nexport function planPromptContextBudgetV2(input: PromptContextBudgetInputV2): PromptContextBudgetPlanV2 {\n\tconst modelId = input.modelId ?? \"unknown\";\n\tconst qualityPolicy = input.qualityPolicy ?? DEFAULT_HEADROOM_QUALITY_POLICY;\n\tconst policyVersion = input.policyVersion ?? CONTEXT_BUDGET_POLICY_VERSION_V2;\n\tconst diagnostics: QualityDiagnosticV2[] = [];\n\n\tconst maxTokens = normalizeBudgetTokens(\"maxTokens\", input.maxTokens, diagnostics);\n\tconst responseReserve = normalizeBudgetTokens(\n\t\t\"responseReserveTokens\",\n\t\tinput.responseReserveTokens ?? 0,\n\t\tdiagnostics,\n\t);\n\tconst safetyMargin = normalizeBudgetTokens(\n\t\t\"safetyMarginTokens\",\n\t\tinput.safetyMarginTokens ?? Math.ceil(maxTokens * 0.05),\n\t\tdiagnostics,\n\t);\n\tconst available = Math.max(0, maxTokens - responseReserve - safetyMargin);\n\n\tconst tierPolicy: Readonly<Record<ContextBudgetTierV2, TierBudgetPolicyV2>> = {\n\t\t...DEFAULT_TIER_POLICY_V2,\n\t\t...(input.tierPolicy ?? {}),\n\t};\n\tconst basePlanned = createPlannedItems(input.items, input.tokenCounter, modelId);\n\tapplyPlannerRedundancyPenalties(basePlanned);\n\n\tconst demand = computeTierDemand(basePlanned);\n\tconst allocation = allocateTiers(available, tierPolicy, demand);\n\tconst selection = new Map<string, SelectedRepresentationV2>();\n\tconst tierUsed = createTierUsage();\n\tconst omitted: ContextBudgetItemV2[] = [];\n\tconst retrievalFallbacks: ContextSourceRefV2[] = [];\n\tlet usedTokens = 0;\n\n\tfor (const planned of basePlanned) {\n\t\tif (!planned.isHard) continue;\n\t\tusedTokens += selectHardItem(planned, selection, tierUsed);\n\t}\n\tif (usedTokens > available) {\n\t\tdiagnostics.push({\n\t\t\treason: \"hard_pin_over_capacity\",\n\t\t\tdetail: `hard-pinned context uses ${usedTokens} tokens against ${available} available tokens`,\n\t\t});\n\t}\n\n\tconst optionalPlanned = basePlanned.filter((planned) => !planned.isHard).sort(compareOptionalForSelection);\n\tfor (const planned of optionalPlanned) {\n\t\tusedTokens = selectOptionalItem(planned, {\n\t\t\tallocation,\n\t\t\tavailable,\n\t\t\tdiagnostics,\n\t\t\tomitted,\n\t\t\tqualityPolicy,\n\t\t\tretrievalFallbacks,\n\t\t\tselection,\n\t\t\ttierUsed,\n\t\t\tusedTokens,\n\t\t});\n\t}\n\n\tconst omittedHighPriority = omitted.some((item) => item.priority === \"high\" || item.required === true);\n\temitOmissionDiagnostics(omitted, diagnostics, retrievalFallbacks);\n\temitCoverageDiagnostics(input.query, selection, diagnostics);\n\n\tconst tierAllocations = buildTierAllocations(allocation, demand, tierUsed);\n\tconst rawTokens = basePlanned.reduce((sum, planned) => sum + planned.fullTokens, 0);\n\tconst omittedTokens = omitted.reduce(\n\t\t(sum, item) => sum + (basePlanned.find((planned) => planned.item.id === item.id)?.fullTokens ?? 0),\n\t\t0,\n\t);\n\tconst omittedItemIds = omitted.map((item) => item.id);\n\tconst planHash = computePlanHash({\n\t\tpolicyVersion,\n\t\tpromptHash: input.promptHash,\n\t\tplanned: basePlanned,\n\t\tselection,\n\t\tallocations: tierAllocations,\n\t\tomittedItemIds,\n\t});\n\tconst observability = buildObservability({\n\t\tavailable,\n\t\tdiagnostics,\n\t\tomittedItemIds,\n\t\tomittedTokens,\n\t\tplanHash,\n\t\trawTokens,\n\t\tretrievalFallbacks,\n\t\tselection,\n\t\tusedTokens,\n\t});\n\n\treturn {\n\t\tpolicyVersion,\n\t\tpromptHash: input.promptHash,\n\t\tplanHash,\n\t\tmaxTokens,\n\t\tresponseReserveTokens: responseReserve,\n\t\tsafetyMarginTokens: safetyMargin,\n\t\tavailableTokens: available,\n\t\tusedTokens,\n\t\tomittedTokens,\n\t\trawTokens,\n\t\ttokenSavingsRatio: rawTokens > 0 ? Math.max(0, 1 - usedTokens / rawTokens) : 0,\n\t\temergency: usedTokens > available || diagnostics.some((diagnostic) => diagnostic.reason === \"invalid_budget\"),\n\t\tomittedHighPriority,\n\t\ttierAllocations,\n\t\tselectedRepresentations: [...selection.values()].sort((a, b) => a.itemId.localeCompare(b.itemId)),\n\t\tincludedItemIds: basePlanned\n\t\t\t.map((planned) => planned.item.id)\n\t\t\t.filter((id) => selection.has(id))\n\t\t\t.sort(),\n\t\tomittedItemIds,\n\t\tdiagnostics,\n\t\tretrievalFallbacks,\n\t\tobservability,\n\t};\n}\n\nfunction normalizeBudgetTokens(field: string, value: number, diagnostics: QualityDiagnosticV2[]): number {\n\tif (!Number.isFinite(value) || value < 0) {\n\t\tdiagnostics.push({\n\t\t\treason: \"invalid_budget\",\n\t\t\tdetail: `${field} must be a non-negative finite number, got ${value}`,\n\t\t});\n\t\treturn 0;\n\t}\n\treturn Math.floor(value);\n}\n\nfunction buildObservability(input: {\n\treadonly available: number;\n\treadonly diagnostics: readonly QualityDiagnosticV2[];\n\treadonly omittedItemIds: readonly string[];\n\treadonly omittedTokens: number;\n\treadonly planHash: string;\n\treadonly rawTokens: number;\n\treadonly retrievalFallbacks: readonly ContextSourceRefV2[];\n\treadonly selection: ReadonlyMap<string, SelectedRepresentationV2>;\n\treadonly usedTokens: number;\n}): PromptContextBudgetObservabilityV2 {\n\tconst selected = [...input.selection.values()];\n\treturn {\n\t\tcounts: {\n\t\t\tselected: selected.length,\n\t\t\tomitted: input.omittedItemIds.length,\n\t\t\tpointer: selected.filter((representation) => representation.kind === \"pointer\").length,\n\t\t\tcompressed: selected.filter((representation) => representation.kind === \"headroom-compressed\").length,\n\t\t\tfull: selected.filter((representation) => representation.kind === \"full\").length,\n\t\t\tretrievalFallback: countUniqueRetrievalFallbacks(input.retrievalFallbacks),\n\t\t},\n\t\tdiagnosticReasons: [...new Set(input.diagnostics.map((diagnostic) => diagnostic.reason))].sort(),\n\t\ttokens: {\n\t\t\tavailable: input.available,\n\t\t\tused: input.usedTokens,\n\t\t\traw: input.rawTokens,\n\t\t\tomitted: input.omittedTokens,\n\t\t\ttokenSavings: Math.max(0, input.rawTokens - input.usedTokens),\n\t\t},\n\t\tplanHash: input.planHash,\n\t\ttokenOptimizer: getTokenOptimizerRuntimeStatus(),\n\t};\n}\n\nfunction countUniqueRetrievalFallbacks(retrievalFallbacks: readonly ContextSourceRefV2[]): number {\n\treturn new Set(\n\t\tretrievalFallbacks.map((ref) =>\n\t\t\t[ref.uri, ref.contentHash, ref.symbol ?? \"\", ref.range?.startLine ?? \"\", ref.range?.endLine ?? \"\"].join(\"\\0\"),\n\t\t),\n\t).size;\n}\n"]}
1
+ {"version":3,"file":"context-budget-v2-planner.js","sourceRoot":"","sources":["../../src/core/context-budget-v2-planner.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype ContextBudgetItemV2,\n\ttype ContextBudgetTierV2,\n\ttype ContextSourceRefV2,\n\tDEFAULT_HEADROOM_QUALITY_POLICY,\n} from \"./context-budget-headroom.ts\";\nimport {\n\tbuildContextBudgetPlanCacheKeyV2,\n\tcreateContextBudgetCacheKeyBaseV2,\n\tcreateContextBudgetSelectionCacheV2,\n\tfinalizeContextBudgetCacheTelemetryV2,\n\treadValidPlanCacheV2,\n\twritePlanCacheV2,\n} from \"./context-budget-v2-cache.ts\";\nimport { computePlanHash } from \"./context-budget-v2-plan-hash.ts\";\nimport { compareOptionalForSelection } from \"./context-budget-v2-scoring.ts\";\nimport {\n\tapplyPlannerRedundancyPenalties,\n\tbuildTierAllocations,\n\tcreatePlannedItems,\n\tcreateTierUsage,\n\temitCoverageDiagnostics,\n\temitOmissionDiagnostics,\n\tselectHardItem,\n\tselectOptionalItem,\n} from \"./context-budget-v2-selection.ts\";\nimport { allocateTiers, computeTierDemand } from \"./context-budget-v2-tiers.ts\";\nimport {\n\tCONTEXT_BUDGET_POLICY_VERSION_V2,\n\tDEFAULT_TIER_POLICY_V2,\n\ttype PromptContextBudgetInputV2,\n\ttype PromptContextBudgetObservabilityV2,\n\ttype PromptContextBudgetPlanV2,\n\ttype QualityDiagnosticV2,\n\ttype SelectedRepresentationV2,\n\ttype TierBudgetPolicyV2,\n} from \"./context-budget-v2-types.ts\";\nimport { getTokenOptimizerRuntimeStatus } from \"./token-optimizer.ts\";\n\nexport function planPromptContextBudgetV2(input: PromptContextBudgetInputV2): PromptContextBudgetPlanV2 {\n\tconst modelId = input.modelId ?? \"unknown\";\n\tconst qualityPolicy = input.qualityPolicy ?? DEFAULT_HEADROOM_QUALITY_POLICY;\n\tconst policyVersion = input.policyVersion ?? CONTEXT_BUDGET_POLICY_VERSION_V2;\n\tconst diagnostics: QualityDiagnosticV2[] = [];\n\n\tconst maxTokens = normalizeBudgetTokens(\"maxTokens\", input.maxTokens, diagnostics);\n\tconst responseReserve = normalizeBudgetTokens(\n\t\t\"responseReserveTokens\",\n\t\tinput.responseReserveTokens ?? 0,\n\t\tdiagnostics,\n\t);\n\tconst safetyMargin = normalizeBudgetTokens(\n\t\t\"safetyMarginTokens\",\n\t\tinput.safetyMarginTokens ?? Math.ceil(maxTokens * 0.05),\n\t\tdiagnostics,\n\t);\n\tconst available = Math.max(0, maxTokens - responseReserve - safetyMargin);\n\n\tconst tierPolicy: Readonly<Record<ContextBudgetTierV2, TierBudgetPolicyV2>> = {\n\t\t...DEFAULT_TIER_POLICY_V2,\n\t\t...(input.tierPolicy ?? {}),\n\t};\n\tconst basePlanned = createPlannedItems(input.items, input.tokenCounter, modelId);\n\tapplyPlannerRedundancyPenalties(basePlanned);\n\tconst rawTokens = basePlanned.reduce((sum, planned) => sum + planned.fullTokens, 0);\n\n\tconst demand = computeTierDemand(basePlanned);\n\tconst allocation = allocateTiers(available, tierPolicy, demand);\n\tconst cacheKeyBase = createContextBudgetCacheKeyBaseV2({\n\t\tbudgetBucket: input.cacheBudgetBucket ?? String(available),\n\t\tmodelId,\n\t\tnamespace: input.cacheNamespace,\n\t\tpolicyVersion,\n\t\tquery: input.query,\n\t\tqueryIntentHash: input.queryIntentHash,\n\t\tredactionPolicyHash: input.redactionPolicyHash,\n\t\tsafetyProfileHash: input.safetyProfileHash,\n\t\ttokenizerId: input.tokenizerId,\n\t});\n\tconst planCacheKey = buildContextBudgetPlanCacheKeyV2({\n\t\tavailableTokens: available,\n\t\tkeyBase: cacheKeyBase,\n\t\tmaxTokens,\n\t\tplanned: basePlanned,\n\t\tpromptHash: input.promptHash,\n\t\tqualityPolicy,\n\t\tresponseReserveTokens: responseReserve,\n\t\tsafetyMarginTokens: safetyMargin,\n\t\ttierPolicy,\n\t});\n\tconst cache = createContextBudgetSelectionCacheV2({\n\t\tkeyBase: cacheKeyBase,\n\t\tnowEpochMs: input.cacheNowEpochMs,\n\t\tplanCacheKey,\n\t\tprovider: input.cacheProvider,\n\t\tttlMs: input.cacheTtlMs,\n\t});\n\tconst cachedPlan = readValidPlanCacheV2({\n\t\tavailableTokens: available,\n\t\tcache,\n\t\tkey: planCacheKey,\n\t\tplanned: basePlanned,\n\t});\n\tif (cachedPlan) {\n\t\treturn cachedPlan;\n\t}\n\tconst selection = new Map<string, SelectedRepresentationV2>();\n\tconst tierUsed = createTierUsage();\n\tconst omitted: ContextBudgetItemV2[] = [];\n\tconst retrievalFallbacks: ContextSourceRefV2[] = [];\n\tlet usedTokens = 0;\n\n\tfor (const planned of basePlanned) {\n\t\tif (!planned.isHard) continue;\n\t\tusedTokens += selectHardItem(planned, selection, tierUsed);\n\t}\n\tif (usedTokens > available) {\n\t\tdiagnostics.push({\n\t\t\treason: \"hard_pin_over_capacity\",\n\t\t\tdetail: `hard-pinned context uses ${usedTokens} tokens against ${available} available tokens`,\n\t\t});\n\t}\n\n\tconst optionalPlanned = basePlanned.filter((planned) => !planned.isHard).sort(compareOptionalForSelection);\n\tfor (const planned of optionalPlanned) {\n\t\tusedTokens = selectOptionalItem(planned, {\n\t\t\tallocation,\n\t\t\tavailable,\n\t\t\tcache,\n\t\t\tdiagnostics,\n\t\t\tomitted,\n\t\t\tqualityPolicy,\n\t\t\tretrievalFallbacks,\n\t\t\tselection,\n\t\t\ttierUsed,\n\t\t\tusedTokens,\n\t\t});\n\t}\n\n\tconst omittedHighPriority = omitted.some((item) => item.priority === \"high\" || item.required === true);\n\temitOmissionDiagnostics(omitted, diagnostics, retrievalFallbacks);\n\temitCoverageDiagnostics(input.query, selection, diagnostics);\n\n\tconst tierAllocations = buildTierAllocations(allocation, demand, tierUsed);\n\tconst omittedTokens = omitted.reduce(\n\t\t(sum, item) => sum + (basePlanned.find((planned) => planned.item.id === item.id)?.fullTokens ?? 0),\n\t\t0,\n\t);\n\tconst omittedItemIds = omitted.map((item) => item.id);\n\tconst planHash = computePlanHash({\n\t\tpolicyVersion,\n\t\tpromptHash: input.promptHash,\n\t\tplanned: basePlanned,\n\t\tselection,\n\t\tallocations: tierAllocations,\n\t\tomittedItemIds,\n\t});\n\tconst observability = buildObservability({\n\t\tavailable,\n\t\tdiagnostics,\n\t\tomittedItemIds,\n\t\tomittedTokens,\n\t\tplanHash,\n\t\trawTokens,\n\t\tretrievalFallbacks,\n\t\tselection,\n\t\tusedTokens,\n\t\tcacheTelemetry: finalizeContextBudgetCacheTelemetryV2(cache.telemetry, {\n\t\t\tomittedTokens,\n\t\t\trawTokens,\n\t\t\tusedTokens,\n\t\t}),\n\t});\n\n\tconst plan: PromptContextBudgetPlanV2 = {\n\t\tpolicyVersion,\n\t\tpromptHash: input.promptHash,\n\t\tplanHash,\n\t\tmaxTokens,\n\t\tresponseReserveTokens: responseReserve,\n\t\tsafetyMarginTokens: safetyMargin,\n\t\tavailableTokens: available,\n\t\tusedTokens,\n\t\tomittedTokens,\n\t\trawTokens,\n\t\ttokenSavingsRatio: rawTokens > 0 ? Math.max(0, 1 - usedTokens / rawTokens) : 0,\n\t\temergency: usedTokens > available || diagnostics.some((diagnostic) => diagnostic.reason === \"invalid_budget\"),\n\t\tomittedHighPriority,\n\t\ttierAllocations,\n\t\tselectedRepresentations: [...selection.values()].sort((a, b) => a.itemId.localeCompare(b.itemId)),\n\t\tincludedItemIds: basePlanned\n\t\t\t.map((planned) => planned.item.id)\n\t\t\t.filter((id) => selection.has(id))\n\t\t\t.sort(),\n\t\tomittedItemIds,\n\t\tdiagnostics,\n\t\tretrievalFallbacks,\n\t\tobservability,\n\t};\n\twritePlanCacheV2({\n\t\tcache,\n\t\tkey: planCacheKey,\n\t\tplan,\n\t\tplanned: basePlanned,\n\t});\n\treturn plan;\n}\n\nfunction normalizeBudgetTokens(field: string, value: number, diagnostics: QualityDiagnosticV2[]): number {\n\tif (!Number.isFinite(value) || value < 0) {\n\t\tdiagnostics.push({\n\t\t\treason: \"invalid_budget\",\n\t\t\tdetail: `${field} must be a non-negative finite number, got ${value}`,\n\t\t});\n\t\treturn 0;\n\t}\n\treturn Math.floor(value);\n}\n\nfunction buildObservability(input: {\n\treadonly available: number;\n\treadonly diagnostics: readonly QualityDiagnosticV2[];\n\treadonly omittedItemIds: readonly string[];\n\treadonly omittedTokens: number;\n\treadonly planHash: string;\n\treadonly rawTokens: number;\n\treadonly retrievalFallbacks: readonly ContextSourceRefV2[];\n\treadonly selection: ReadonlyMap<string, SelectedRepresentationV2>;\n\treadonly usedTokens: number;\n\treadonly cacheTelemetry: PromptContextBudgetObservabilityV2[\"cache\"];\n}): PromptContextBudgetObservabilityV2 {\n\tconst selected = [...input.selection.values()];\n\treturn {\n\t\tcounts: {\n\t\t\tselected: selected.length,\n\t\t\tomitted: input.omittedItemIds.length,\n\t\t\tpointer: selected.filter((representation) => representation.kind === \"pointer\").length,\n\t\t\tcompressed: selected.filter((representation) => representation.kind === \"headroom-compressed\").length,\n\t\t\tfull: selected.filter((representation) => representation.kind === \"full\").length,\n\t\t\tretrievalFallback: countUniqueRetrievalFallbacks(input.retrievalFallbacks),\n\t\t},\n\t\tdiagnosticReasons: [...new Set(input.diagnostics.map((diagnostic) => diagnostic.reason))].sort(),\n\t\ttokens: {\n\t\t\tavailable: input.available,\n\t\t\tused: input.usedTokens,\n\t\t\traw: input.rawTokens,\n\t\t\tomitted: input.omittedTokens,\n\t\t\ttokenSavings: Math.max(0, input.rawTokens - input.usedTokens),\n\t\t},\n\t\tplanHash: input.planHash,\n\t\tcache: input.cacheTelemetry,\n\t\ttokenOptimizer: getTokenOptimizerRuntimeStatus(),\n\t};\n}\n\nfunction countUniqueRetrievalFallbacks(retrievalFallbacks: readonly ContextSourceRefV2[]): number {\n\treturn new Set(\n\t\tretrievalFallbacks.map((ref) =>\n\t\t\t[ref.uri, ref.contentHash, ref.symbol ?? \"\", ref.range?.startLine ?? \"\", ref.range?.endLine ?? \"\"].join(\"\\0\"),\n\t\t),\n\t).size;\n}\n"]}
@@ -0,0 +1,27 @@
1
+ import type { ContextRepresentationCandidateV2 } from "./context-budget-headroom.ts";
2
+ import { type ContextBudgetCacheKeyBaseV2 } from "./context-budget-v2-cache-keys.ts";
3
+ import type { MutableTokenCacheTelemetryV2 } from "./context-budget-v2-cache-telemetry.ts";
4
+ import type { PlannedItemV2 } from "./context-budget-v2-scoring.ts";
5
+ import type { ContextBudgetCacheProviderV2 } from "./context-budget-v2-types.ts";
6
+ interface ContextBudgetRepresentationCacheRuntimeV2 {
7
+ readonly provider?: ContextBudgetCacheProviderV2;
8
+ readonly keyBase: ContextBudgetCacheKeyBaseV2;
9
+ readonly nowEpochMs: number;
10
+ readonly ttlMs: number;
11
+ readonly telemetry: MutableTokenCacheTelemetryV2;
12
+ }
13
+ export declare function applyRepresentationCacheV2(input: {
14
+ readonly planned: PlannedItemV2;
15
+ readonly candidates: readonly ContextRepresentationCandidateV2[];
16
+ readonly cache: ContextBudgetRepresentationCacheRuntimeV2;
17
+ readonly materializedEnabled?: boolean;
18
+ }): readonly ContextRepresentationCandidateV2[];
19
+ export declare function writeRepresentationCacheV2(input: {
20
+ readonly planned: PlannedItemV2;
21
+ readonly selected: ContextRepresentationCandidateV2;
22
+ readonly cache: ContextBudgetRepresentationCacheRuntimeV2;
23
+ readonly materializedEnabled?: boolean;
24
+ }): void;
25
+ export declare function isMaterializableRepresentationV2(candidate: ContextRepresentationCandidateV2): boolean;
26
+ export {};
27
+ //# sourceMappingURL=context-budget-v2-representation-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-budget-v2-representation-cache.d.ts","sourceRoot":"","sources":["../../src/core/context-budget-v2-representation-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAGN,KAAK,2BAA2B,EAIhC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,wCAAwC,CAAC;AAM3F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAC;AAEjF,UAAU,yCAAyC;IAClD,QAAQ,CAAC,QAAQ,CAAC,EAAE,4BAA4B,CAAC;IACjD,QAAQ,CAAC,OAAO,EAAE,2BAA2B,CAAC;IAC9C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,4BAA4B,CAAC;CACjD;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IACjD,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,SAAS,gCAAgC,EAAE,CAAC;IACjE,QAAQ,CAAC,KAAK,EAAE,yCAAyC,CAAC;IAC1D,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;CACvC,GAAG,SAAS,gCAAgC,EAAE,CAgE9C;AA6CD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IACjD,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,gCAAgC,CAAC;IACpD,QAAQ,CAAC,KAAK,EAAE,yCAAyC,CAAC;IAC1D,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;CACvC,GAAG,IAAI,CAiEP;AAED,wBAAgB,gCAAgC,CAAC,SAAS,EAAE,gCAAgC,GAAG,OAAO,CAErG","sourcesContent":["import type { ContextRepresentationCandidateV2 } from \"./context-budget-headroom.ts\";\nimport {\n\tbuildContextBudgetMaterializedRepresentationCandidateKeyV2,\n\tbuildContextBudgetRepresentationCandidateKeyV2,\n\ttype ContextBudgetCacheKeyBaseV2,\n\tcomputeContextBudgetOutputTextHashV2,\n\tcomputeContextBudgetRepresentationFingerprintV2,\n\tcomputeContextBudgetTargetTokenBucketV2,\n} from \"./context-budget-v2-cache-keys.ts\";\nimport type { MutableTokenCacheTelemetryV2 } from \"./context-budget-v2-cache-telemetry.ts\";\nimport { recordContextBudgetRepresentationCacheHitV2 } from \"./context-budget-v2-cache-telemetry.ts\";\nimport {\n\tvalidateContextBudgetMaterializedRepresentationCacheEntryV2,\n\tvalidateContextBudgetRepresentationCacheEntryV2,\n} from \"./context-budget-v2-cache-validation.ts\";\nimport type { PlannedItemV2 } from \"./context-budget-v2-scoring.ts\";\nimport type { ContextBudgetCacheProviderV2 } from \"./context-budget-v2-types.ts\";\n\ninterface ContextBudgetRepresentationCacheRuntimeV2 {\n\treadonly provider?: ContextBudgetCacheProviderV2;\n\treadonly keyBase: ContextBudgetCacheKeyBaseV2;\n\treadonly nowEpochMs: number;\n\treadonly ttlMs: number;\n\treadonly telemetry: MutableTokenCacheTelemetryV2;\n}\n\nexport function applyRepresentationCacheV2(input: {\n\treadonly planned: PlannedItemV2;\n\treadonly candidates: readonly ContextRepresentationCandidateV2[];\n\treadonly cache: ContextBudgetRepresentationCacheRuntimeV2;\n\treadonly materializedEnabled?: boolean;\n}): readonly ContextRepresentationCandidateV2[] {\n\tconst provider = input.cache.provider;\n\tif (!provider) return input.candidates;\n\tconst sourceHash = input.planned.contentHash;\n\tconst resolved: ContextRepresentationCandidateV2[] = [];\n\tfor (const candidate of input.candidates) {\n\t\tif (candidate.kind === \"omit\") {\n\t\t\tresolved.push(candidate);\n\t\t\tcontinue;\n\t\t}\n\t\tconst exactKey = buildContextBudgetRepresentationCandidateKeyV2(input.cache.keyBase, candidate, sourceHash);\n\t\tconst negative = provider.readNegativeRepresentation(exactKey);\n\t\tif (negative) {\n\t\t\tinput.cache.telemetry.representationCache.negativeHits += 1;\n\t\t\tcontinue;\n\t\t}\n\t\tconst cached = provider.readRepresentation(exactKey);\n\t\tif (!cached) {\n\t\t\tconst materialized = readMaterializedRepresentationCacheV2({\n\t\t\t\tcache: input.cache,\n\t\t\t\tcandidate,\n\t\t\t\tmaterializedEnabled: input.materializedEnabled === true,\n\t\t\t\tprovider,\n\t\t\t\tsourceHash,\n\t\t\t});\n\t\t\tif (materialized) {\n\t\t\t\tresolved.push(materialized);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tinput.cache.telemetry.representationCache.misses += 1;\n\t\t\tresolved.push({ ...candidate, cache: { hit: false, key: exactKey, keyKind: \"exact\" } });\n\t\t\tcontinue;\n\t\t}\n\t\tconst rejection = validateContextBudgetRepresentationCacheEntryV2({\n\t\t\tcache: input.cache,\n\t\t\tcached,\n\t\t\tcandidate,\n\t\t\tsourceHash,\n\t\t});\n\t\tif (rejection) {\n\t\t\trecordRepresentationReject(input.cache.telemetry, rejection);\n\t\t\tresolved.push({\n\t\t\t\t...candidate,\n\t\t\t\tcache: { hit: false, key: exactKey, keyKind: \"exact\", rejectedReason: rejection },\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\trecordContextBudgetRepresentationCacheHitV2(\n\t\t\tinput.cache.telemetry,\n\t\t\tcached.entry.kind,\n\t\t\tcached.entry.keyKind ?? \"exact\",\n\t\t);\n\t\tresolved.push({\n\t\t\t...candidate,\n\t\t\tcache: { hit: true, key: exactKey, keyKind: cached.entry.keyKind ?? \"exact\", layer: cached.layer },\n\t\t\tcompressorId: cached.entry.compressorId,\n\t\t\testimatedTokens: cached.entry.estimatedTokens,\n\t\t\tfidelity: cached.entry.fidelity,\n\t\t\tsourceRef: cached.entry.sourceRef ?? candidate.sourceRef,\n\t\t\tsummaryHash: cached.entry.summaryHash,\n\t\t\ttext: cached.entry.text,\n\t\t});\n\t}\n\treturn resolved;\n}\n\nfunction readMaterializedRepresentationCacheV2(input: {\n\treadonly cache: ContextBudgetRepresentationCacheRuntimeV2;\n\treadonly candidate: ContextRepresentationCandidateV2;\n\treadonly materializedEnabled: boolean;\n\treadonly provider: ContextBudgetCacheProviderV2;\n\treadonly sourceHash: string;\n}): ContextRepresentationCandidateV2 | undefined {\n\tif (!input.materializedEnabled || !isMaterializableRepresentationV2(input.candidate)) return undefined;\n\tconst key = buildContextBudgetMaterializedRepresentationCandidateKeyV2(\n\t\tinput.cache.keyBase,\n\t\tinput.candidate,\n\t\tinput.sourceHash,\n\t);\n\tconst negative = input.provider.readNegativeRepresentation(key);\n\tif (negative) {\n\t\tinput.cache.telemetry.representationCache.negativeHits += 1;\n\t\treturn undefined;\n\t}\n\tconst cached = input.provider.readRepresentation(key);\n\tif (!cached) return undefined;\n\tconst rejection = validateContextBudgetMaterializedRepresentationCacheEntryV2({\n\t\tcache: input.cache,\n\t\tcached,\n\t\tcandidate: input.candidate,\n\t\tsourceHash: input.sourceHash,\n\t});\n\tif (rejection) {\n\t\trecordRepresentationReject(input.cache.telemetry, rejection);\n\t\treturn { ...input.candidate, cache: { hit: false, key, keyKind: \"materialized\", rejectedReason: rejection } };\n\t}\n\trecordContextBudgetRepresentationCacheHitV2(input.cache.telemetry, cached.entry.kind, \"materialized\");\n\treturn {\n\t\t...input.candidate,\n\t\tcache: { hit: true, key, keyKind: \"materialized\", layer: cached.layer },\n\t\tcompressorId: cached.entry.compressorId,\n\t\testimatedTokens: cached.entry.estimatedTokens,\n\t\tfidelity: cached.entry.fidelity,\n\t\tsourceRef: cached.entry.sourceRef ?? input.candidate.sourceRef,\n\t\tsummaryHash: cached.entry.summaryHash,\n\t\ttext: cached.entry.text,\n\t};\n}\n\nexport function writeRepresentationCacheV2(input: {\n\treadonly planned: PlannedItemV2;\n\treadonly selected: ContextRepresentationCandidateV2;\n\treadonly cache: ContextBudgetRepresentationCacheRuntimeV2;\n\treadonly materializedEnabled?: boolean;\n}): void {\n\tif (!input.cache.provider || input.selected.kind === \"omit\" || input.selected.cache?.hit === true) return;\n\tconst sourceHash = input.planned.contentHash;\n\tconst exactKey =\n\t\tinput.selected.cache?.keyKind === \"exact\" && input.selected.cache.key !== undefined\n\t\t\t? input.selected.cache.key\n\t\t\t: buildContextBudgetRepresentationCandidateKeyV2(input.cache.keyBase, input.selected, sourceHash);\n\tinput.cache.provider.writeRepresentation({\n\t\tkey: exactKey,\n\t\tentry: {\n\t\t\tcompressorId: input.selected.compressorId,\n\t\t\tcreatedAtEpochMs: input.cache.nowEpochMs,\n\t\t\testimatedTokens: input.selected.estimatedTokens,\n\t\t\tfidelity: input.selected.fidelity,\n\t\t\tkeyKind: \"exact\",\n\t\t\tkind: input.selected.kind,\n\t\t\tmodelId: input.cache.keyBase.modelId,\n\t\t\tpolicyVersion: input.cache.keyBase.policyVersion,\n\t\t\trepresentationFingerprint: computeContextBudgetRepresentationFingerprintV2(input.selected),\n\t\t\tsourceHash,\n\t\t\tsourceRef: input.selected.sourceRef,\n\t\t\tsummaryHash: input.selected.summaryHash,\n\t\t\ttext: input.selected.text,\n\t\t\ttokenizerId: input.cache.keyBase.tokenizerId,\n\t\t},\n\t});\n\tinput.cache.telemetry.representationCache.writes += 1;\n\tif (input.materializedEnabled === true && isMaterializableRepresentationV2(input.selected)) {\n\t\tinput.cache.provider.writeRepresentation({\n\t\t\tkey: buildContextBudgetMaterializedRepresentationCandidateKeyV2(\n\t\t\t\tinput.cache.keyBase,\n\t\t\t\tinput.selected,\n\t\t\t\tsourceHash,\n\t\t\t),\n\t\t\tentry: {\n\t\t\t\tcompressorId: input.selected.compressorId,\n\t\t\t\tcompressorPolicyHash: input.cache.keyBase.compressorPolicyHash,\n\t\t\t\tcreatedAtEpochMs: input.cache.nowEpochMs,\n\t\t\t\testimatedTokens: input.selected.estimatedTokens,\n\t\t\t\tfidelity: input.selected.fidelity,\n\t\t\t\tkeyKind: \"materialized\",\n\t\t\t\tkind: input.selected.kind,\n\t\t\t\tmodelId: input.cache.keyBase.modelId,\n\t\t\t\toutputTextHash: computeContextBudgetOutputTextHashV2(input.selected.text),\n\t\t\t\tpolicyVersion: input.cache.keyBase.policyVersion,\n\t\t\t\tqualityPolicyHash: input.cache.keyBase.qualityPolicyHash,\n\t\t\t\tqueryIntentCluster: input.cache.keyBase.queryIntentCluster,\n\t\t\t\trepresentationFingerprint: computeContextBudgetRepresentationFingerprintV2(input.selected),\n\t\t\t\tsourceHash,\n\t\t\t\tsourceRef: input.selected.sourceRef,\n\t\t\t\tsummaryHash: input.selected.summaryHash,\n\t\t\t\ttargetTokenBucket: computeContextBudgetTargetTokenBucketV2(input.selected.estimatedTokens),\n\t\t\t\ttext: input.selected.text,\n\t\t\t\ttokenizerId: input.cache.keyBase.tokenizerId,\n\t\t\t\tverification: {\n\t\t\t\t\tpoisonScore: 0,\n\t\t\t\t\tqueryCoverage: 1,\n\t\t\t\t\tsecretLeakScore: 0,\n\t\t\t\t\tsourceCoverage: 1,\n\t\t\t\t\tvalidatorVersion: \"context-budget-v2-heuristic\",\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\t\tinput.cache.telemetry.representationCache.writes += 1;\n\t}\n}\n\nexport function isMaterializableRepresentationV2(candidate: ContextRepresentationCandidateV2): boolean {\n\treturn candidate.kind === \"summary\" || candidate.kind === \"headroom-compressed\";\n}\n\nfunction recordRepresentationReject(telemetry: MutableTokenCacheTelemetryV2, rejection: string): void {\n\tif (rejection === \"stale\") {\n\t\ttelemetry.representationCache.staleRejects += 1;\n\t} else {\n\t\ttelemetry.representationCache.poisonRejects += 1;\n\t}\n}\n"]}
@@ -0,0 +1,173 @@
1
+ import { buildContextBudgetMaterializedRepresentationCandidateKeyV2, buildContextBudgetRepresentationCandidateKeyV2, computeContextBudgetOutputTextHashV2, computeContextBudgetRepresentationFingerprintV2, computeContextBudgetTargetTokenBucketV2, } from "./context-budget-v2-cache-keys.js";
2
+ import { recordContextBudgetRepresentationCacheHitV2 } from "./context-budget-v2-cache-telemetry.js";
3
+ import { validateContextBudgetMaterializedRepresentationCacheEntryV2, validateContextBudgetRepresentationCacheEntryV2, } from "./context-budget-v2-cache-validation.js";
4
+ export function applyRepresentationCacheV2(input) {
5
+ const provider = input.cache.provider;
6
+ if (!provider)
7
+ return input.candidates;
8
+ const sourceHash = input.planned.contentHash;
9
+ const resolved = [];
10
+ for (const candidate of input.candidates) {
11
+ if (candidate.kind === "omit") {
12
+ resolved.push(candidate);
13
+ continue;
14
+ }
15
+ const exactKey = buildContextBudgetRepresentationCandidateKeyV2(input.cache.keyBase, candidate, sourceHash);
16
+ const negative = provider.readNegativeRepresentation(exactKey);
17
+ if (negative) {
18
+ input.cache.telemetry.representationCache.negativeHits += 1;
19
+ continue;
20
+ }
21
+ const cached = provider.readRepresentation(exactKey);
22
+ if (!cached) {
23
+ const materialized = readMaterializedRepresentationCacheV2({
24
+ cache: input.cache,
25
+ candidate,
26
+ materializedEnabled: input.materializedEnabled === true,
27
+ provider,
28
+ sourceHash,
29
+ });
30
+ if (materialized) {
31
+ resolved.push(materialized);
32
+ continue;
33
+ }
34
+ input.cache.telemetry.representationCache.misses += 1;
35
+ resolved.push({ ...candidate, cache: { hit: false, key: exactKey, keyKind: "exact" } });
36
+ continue;
37
+ }
38
+ const rejection = validateContextBudgetRepresentationCacheEntryV2({
39
+ cache: input.cache,
40
+ cached,
41
+ candidate,
42
+ sourceHash,
43
+ });
44
+ if (rejection) {
45
+ recordRepresentationReject(input.cache.telemetry, rejection);
46
+ resolved.push({
47
+ ...candidate,
48
+ cache: { hit: false, key: exactKey, keyKind: "exact", rejectedReason: rejection },
49
+ });
50
+ continue;
51
+ }
52
+ recordContextBudgetRepresentationCacheHitV2(input.cache.telemetry, cached.entry.kind, cached.entry.keyKind ?? "exact");
53
+ resolved.push({
54
+ ...candidate,
55
+ cache: { hit: true, key: exactKey, keyKind: cached.entry.keyKind ?? "exact", layer: cached.layer },
56
+ compressorId: cached.entry.compressorId,
57
+ estimatedTokens: cached.entry.estimatedTokens,
58
+ fidelity: cached.entry.fidelity,
59
+ sourceRef: cached.entry.sourceRef ?? candidate.sourceRef,
60
+ summaryHash: cached.entry.summaryHash,
61
+ text: cached.entry.text,
62
+ });
63
+ }
64
+ return resolved;
65
+ }
66
+ function readMaterializedRepresentationCacheV2(input) {
67
+ if (!input.materializedEnabled || !isMaterializableRepresentationV2(input.candidate))
68
+ return undefined;
69
+ const key = buildContextBudgetMaterializedRepresentationCandidateKeyV2(input.cache.keyBase, input.candidate, input.sourceHash);
70
+ const negative = input.provider.readNegativeRepresentation(key);
71
+ if (negative) {
72
+ input.cache.telemetry.representationCache.negativeHits += 1;
73
+ return undefined;
74
+ }
75
+ const cached = input.provider.readRepresentation(key);
76
+ if (!cached)
77
+ return undefined;
78
+ const rejection = validateContextBudgetMaterializedRepresentationCacheEntryV2({
79
+ cache: input.cache,
80
+ cached,
81
+ candidate: input.candidate,
82
+ sourceHash: input.sourceHash,
83
+ });
84
+ if (rejection) {
85
+ recordRepresentationReject(input.cache.telemetry, rejection);
86
+ return { ...input.candidate, cache: { hit: false, key, keyKind: "materialized", rejectedReason: rejection } };
87
+ }
88
+ recordContextBudgetRepresentationCacheHitV2(input.cache.telemetry, cached.entry.kind, "materialized");
89
+ return {
90
+ ...input.candidate,
91
+ cache: { hit: true, key, keyKind: "materialized", layer: cached.layer },
92
+ compressorId: cached.entry.compressorId,
93
+ estimatedTokens: cached.entry.estimatedTokens,
94
+ fidelity: cached.entry.fidelity,
95
+ sourceRef: cached.entry.sourceRef ?? input.candidate.sourceRef,
96
+ summaryHash: cached.entry.summaryHash,
97
+ text: cached.entry.text,
98
+ };
99
+ }
100
+ export function writeRepresentationCacheV2(input) {
101
+ if (!input.cache.provider || input.selected.kind === "omit" || input.selected.cache?.hit === true)
102
+ return;
103
+ const sourceHash = input.planned.contentHash;
104
+ const exactKey = input.selected.cache?.keyKind === "exact" && input.selected.cache.key !== undefined
105
+ ? input.selected.cache.key
106
+ : buildContextBudgetRepresentationCandidateKeyV2(input.cache.keyBase, input.selected, sourceHash);
107
+ input.cache.provider.writeRepresentation({
108
+ key: exactKey,
109
+ entry: {
110
+ compressorId: input.selected.compressorId,
111
+ createdAtEpochMs: input.cache.nowEpochMs,
112
+ estimatedTokens: input.selected.estimatedTokens,
113
+ fidelity: input.selected.fidelity,
114
+ keyKind: "exact",
115
+ kind: input.selected.kind,
116
+ modelId: input.cache.keyBase.modelId,
117
+ policyVersion: input.cache.keyBase.policyVersion,
118
+ representationFingerprint: computeContextBudgetRepresentationFingerprintV2(input.selected),
119
+ sourceHash,
120
+ sourceRef: input.selected.sourceRef,
121
+ summaryHash: input.selected.summaryHash,
122
+ text: input.selected.text,
123
+ tokenizerId: input.cache.keyBase.tokenizerId,
124
+ },
125
+ });
126
+ input.cache.telemetry.representationCache.writes += 1;
127
+ if (input.materializedEnabled === true && isMaterializableRepresentationV2(input.selected)) {
128
+ input.cache.provider.writeRepresentation({
129
+ key: buildContextBudgetMaterializedRepresentationCandidateKeyV2(input.cache.keyBase, input.selected, sourceHash),
130
+ entry: {
131
+ compressorId: input.selected.compressorId,
132
+ compressorPolicyHash: input.cache.keyBase.compressorPolicyHash,
133
+ createdAtEpochMs: input.cache.nowEpochMs,
134
+ estimatedTokens: input.selected.estimatedTokens,
135
+ fidelity: input.selected.fidelity,
136
+ keyKind: "materialized",
137
+ kind: input.selected.kind,
138
+ modelId: input.cache.keyBase.modelId,
139
+ outputTextHash: computeContextBudgetOutputTextHashV2(input.selected.text),
140
+ policyVersion: input.cache.keyBase.policyVersion,
141
+ qualityPolicyHash: input.cache.keyBase.qualityPolicyHash,
142
+ queryIntentCluster: input.cache.keyBase.queryIntentCluster,
143
+ representationFingerprint: computeContextBudgetRepresentationFingerprintV2(input.selected),
144
+ sourceHash,
145
+ sourceRef: input.selected.sourceRef,
146
+ summaryHash: input.selected.summaryHash,
147
+ targetTokenBucket: computeContextBudgetTargetTokenBucketV2(input.selected.estimatedTokens),
148
+ text: input.selected.text,
149
+ tokenizerId: input.cache.keyBase.tokenizerId,
150
+ verification: {
151
+ poisonScore: 0,
152
+ queryCoverage: 1,
153
+ secretLeakScore: 0,
154
+ sourceCoverage: 1,
155
+ validatorVersion: "context-budget-v2-heuristic",
156
+ },
157
+ },
158
+ });
159
+ input.cache.telemetry.representationCache.writes += 1;
160
+ }
161
+ }
162
+ export function isMaterializableRepresentationV2(candidate) {
163
+ return candidate.kind === "summary" || candidate.kind === "headroom-compressed";
164
+ }
165
+ function recordRepresentationReject(telemetry, rejection) {
166
+ if (rejection === "stale") {
167
+ telemetry.representationCache.staleRejects += 1;
168
+ }
169
+ else {
170
+ telemetry.representationCache.poisonRejects += 1;
171
+ }
172
+ }
173
+ //# sourceMappingURL=context-budget-v2-representation-cache.js.map