open-multi-agent-kit 0.90.4 → 0.90.6

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 (161) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/README.md +9 -9
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +1 -0
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/codexbar-cli.d.ts +39 -0
  7. package/dist/codexbar-cli.d.ts.map +1 -0
  8. package/dist/codexbar-cli.js +230 -0
  9. package/dist/codexbar-cli.js.map +1 -0
  10. package/dist/commands/doctor-provider.d.ts.map +1 -1
  11. package/dist/commands/doctor-provider.js +16 -3
  12. package/dist/commands/doctor-provider.js.map +1 -1
  13. package/dist/core/adaptorch-bridge.d.ts +14 -21
  14. package/dist/core/adaptorch-bridge.d.ts.map +1 -1
  15. package/dist/core/adaptorch-bridge.js +11 -18
  16. package/dist/core/adaptorch-bridge.js.map +1 -1
  17. package/dist/core/agent-session.d.ts +6 -39
  18. package/dist/core/agent-session.d.ts.map +1 -1
  19. package/dist/core/agent-session.js +37 -107
  20. package/dist/core/agent-session.js.map +1 -1
  21. package/dist/core/codexbar-adapter.d.ts +44 -0
  22. package/dist/core/codexbar-adapter.d.ts.map +1 -0
  23. package/dist/core/codexbar-adapter.js +211 -0
  24. package/dist/core/codexbar-adapter.js.map +1 -0
  25. package/dist/core/compaction/index.d.ts +2 -0
  26. package/dist/core/compaction/index.d.ts.map +1 -1
  27. package/dist/core/compaction/index.js +2 -0
  28. package/dist/core/compaction/index.js.map +1 -1
  29. package/dist/core/compaction/model-policy.d.ts +9 -0
  30. package/dist/core/compaction/model-policy.d.ts.map +1 -0
  31. package/dist/core/compaction/model-policy.js +37 -0
  32. package/dist/core/compaction/model-policy.js.map +1 -0
  33. package/dist/core/compaction/resume-policy.d.ts +6 -0
  34. package/dist/core/compaction/resume-policy.d.ts.map +1 -0
  35. package/dist/core/compaction/resume-policy.js +8 -0
  36. package/dist/core/compaction/resume-policy.js.map +1 -0
  37. package/dist/core/context-budget-v2-planner.d.ts.map +1 -1
  38. package/dist/core/context-budget-v2-planner.js +10 -2
  39. package/dist/core/context-budget-v2-planner.js.map +1 -1
  40. package/dist/core/context-budget-v2-types.d.ts +7 -1
  41. package/dist/core/context-budget-v2-types.d.ts.map +1 -1
  42. package/dist/core/context-budget-v2-types.js.map +1 -1
  43. package/dist/core/domain-loadouts.d.ts.map +1 -1
  44. package/dist/core/domain-loadouts.js +68 -1
  45. package/dist/core/domain-loadouts.js.map +1 -1
  46. package/dist/core/extensions/loader.d.ts.map +1 -1
  47. package/dist/core/extensions/loader.js +12 -0
  48. package/dist/core/extensions/loader.js.map +1 -1
  49. package/dist/core/extensions/runner.d.ts.map +1 -1
  50. package/dist/core/extensions/runner.js +3 -0
  51. package/dist/core/extensions/runner.js.map +1 -1
  52. package/dist/core/extensions/types.d.ts +15 -0
  53. package/dist/core/extensions/types.d.ts.map +1 -1
  54. package/dist/core/extensions/types.js.map +1 -1
  55. package/dist/core/grok-harness-dispatch.d.ts +22 -0
  56. package/dist/core/grok-harness-dispatch.d.ts.map +1 -0
  57. package/dist/core/grok-harness-dispatch.js +44 -0
  58. package/dist/core/grok-harness-dispatch.js.map +1 -0
  59. package/dist/core/grok-harness.d.ts +25 -0
  60. package/dist/core/grok-harness.d.ts.map +1 -0
  61. package/dist/core/grok-harness.js +61 -0
  62. package/dist/core/grok-harness.js.map +1 -0
  63. package/dist/core/grok-playbook.d.ts +7 -0
  64. package/dist/core/grok-playbook.d.ts.map +1 -0
  65. package/dist/core/grok-playbook.js +34 -0
  66. package/dist/core/grok-playbook.js.map +1 -0
  67. package/dist/core/reasoning-router-bias.d.ts +11 -23
  68. package/dist/core/reasoning-router-bias.d.ts.map +1 -1
  69. package/dist/core/reasoning-router-bias.js +9 -18
  70. package/dist/core/reasoning-router-bias.js.map +1 -1
  71. package/dist/core/reasoning-router-resolver.d.ts +44 -0
  72. package/dist/core/reasoning-router-resolver.d.ts.map +1 -0
  73. package/dist/core/reasoning-router-resolver.js +79 -0
  74. package/dist/core/reasoning-router-resolver.js.map +1 -0
  75. package/dist/core/reasoning-router-v4-weights.d.ts +28 -72
  76. package/dist/core/reasoning-router-v4-weights.d.ts.map +1 -1
  77. package/dist/core/reasoning-router-v4-weights.js +16 -60
  78. package/dist/core/reasoning-router-v4-weights.js.map +1 -1
  79. package/dist/core/reasoning-router-v4.d.ts +25 -70
  80. package/dist/core/reasoning-router-v4.d.ts.map +1 -1
  81. package/dist/core/reasoning-router-v4.js +46 -144
  82. package/dist/core/reasoning-router-v4.js.map +1 -1
  83. package/dist/core/router-feedback-collector.d.ts +13 -16
  84. package/dist/core/router-feedback-collector.d.ts.map +1 -1
  85. package/dist/core/router-feedback-collector.js +5 -8
  86. package/dist/core/router-feedback-collector.js.map +1 -1
  87. package/dist/core/sdk.d.ts.map +1 -1
  88. package/dist/core/sdk.js +31 -12
  89. package/dist/core/sdk.js.map +1 -1
  90. package/dist/core/slash-commands.d.ts.map +1 -1
  91. package/dist/core/slash-commands.js +1 -1
  92. package/dist/core/slash-commands.js.map +1 -1
  93. package/dist/main.d.ts.map +1 -1
  94. package/dist/main.js +4 -0
  95. package/dist/main.js.map +1 -1
  96. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  97. package/dist/modes/interactive/interactive-mode.js +16 -98
  98. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  99. package/dist/utils/tools-manager.d.ts +3 -2
  100. package/dist/utils/tools-manager.d.ts.map +1 -1
  101. package/dist/utils/tools-manager.js +42 -17
  102. package/dist/utils/tools-manager.js.map +1 -1
  103. package/docs/correctness-wall.md +117 -0
  104. package/docs/grok-harness.md +63 -0
  105. package/docs/loadout-domains/README.md +2 -1
  106. package/docs/loadout-domains/ai-agent-ops.md +8 -1
  107. package/docs/loadout-domains/grok-harness.md +74 -0
  108. package/docs/providers.md +4 -0
  109. package/docs/usage.md +11 -12
  110. package/examples/extensions/correctness-wall/LOADOUT.md +87 -0
  111. package/examples/extensions/correctness-wall/README.md +111 -0
  112. package/examples/extensions/correctness-wall/adjudication-fixture.ts +151 -0
  113. package/examples/extensions/correctness-wall/index.ts +470 -0
  114. package/examples/extensions/correctness-wall/repair-state.ts +77 -0
  115. package/examples/extensions/correctness-wall/wall-cache.ts +81 -0
  116. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  117. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  118. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  119. package/examples/extensions/gondolin/package-lock.json +2 -2
  120. package/examples/extensions/gondolin/package.json +1 -1
  121. package/examples/extensions/sandbox/package-lock.json +2 -2
  122. package/examples/extensions/sandbox/package.json +1 -1
  123. package/examples/extensions/subagent/agent-capability-router.test.ts +123 -0
  124. package/examples/extensions/subagent/agent-capability-router.ts +274 -0
  125. package/examples/extensions/subagent/agents/planner.md +3 -0
  126. package/examples/extensions/subagent/agents/reviewer.md +3 -0
  127. package/examples/extensions/subagent/agents/scout.md +3 -0
  128. package/examples/extensions/subagent/agents/worker.md +2 -0
  129. package/examples/extensions/subagent/agents.ts +14 -0
  130. package/examples/extensions/subagent/capabilities.ts +368 -0
  131. package/examples/extensions/subagent/domain-profiles.ts +1089 -0
  132. package/examples/extensions/subagent/index.ts +71 -3
  133. package/examples/extensions/with-deps/package-lock.json +2 -2
  134. package/examples/extensions/with-deps/package.json +1 -1
  135. package/examples/sdk/12-full-control.ts +1 -1
  136. package/npm-shrinkwrap.json +12 -12
  137. package/package.json +5 -5
  138. package/dist/core/compactor.d.ts +0 -42
  139. package/dist/core/compactor.d.ts.map +0 -1
  140. package/dist/core/compactor.js +0 -128
  141. package/dist/core/compactor.js.map +0 -1
  142. package/dist/core/reasoning-router-v2.d.ts +0 -94
  143. package/dist/core/reasoning-router-v2.d.ts.map +0 -1
  144. package/dist/core/reasoning-router-v2.js +0 -288
  145. package/dist/core/reasoning-router-v2.js.map +0 -1
  146. package/dist/core/reasoning-router-v3.d.ts +0 -15
  147. package/dist/core/reasoning-router-v3.d.ts.map +0 -1
  148. package/dist/core/reasoning-router-v3.js +0 -193
  149. package/dist/core/reasoning-router-v3.js.map +0 -1
  150. package/dist/core/reasoning-router-weights.d.ts +0 -155
  151. package/dist/core/reasoning-router-weights.d.ts.map +0 -1
  152. package/dist/core/reasoning-router-weights.js +0 -204
  153. package/dist/core/reasoning-router-weights.js.map +0 -1
  154. package/dist/core/reasoning-router.d.ts +0 -44
  155. package/dist/core/reasoning-router.d.ts.map +0 -1
  156. package/dist/core/reasoning-router.js +0 -138
  157. package/dist/core/reasoning-router.js.map +0 -1
  158. package/dist/core/token-optimizer.d.ts +0 -58
  159. package/dist/core/token-optimizer.d.ts.map +0 -1
  160. package/dist/core/token-optimizer.js +0 -179
  161. package/dist/core/token-optimizer.js.map +0 -1
@@ -0,0 +1,44 @@
1
+ export type CodexBarProvider = string;
2
+ export type CodexBarUsageWindowSummary = {
3
+ readonly usedPercent?: number;
4
+ readonly resetsAt?: string;
5
+ };
6
+ export type CodexBarStatusSummary = {
7
+ readonly indicator?: string;
8
+ readonly description?: string;
9
+ readonly url?: string;
10
+ };
11
+ export type CodexBarUsageSummary = {
12
+ readonly provider: CodexBarProvider;
13
+ readonly source?: string;
14
+ readonly primary?: CodexBarUsageWindowSummary;
15
+ readonly secondary?: CodexBarUsageWindowSummary;
16
+ readonly creditsRemaining?: number;
17
+ readonly updatedAt?: string;
18
+ readonly status?: CodexBarStatusSummary;
19
+ };
20
+ export type CodexBarCostSummary = {
21
+ readonly provider: CodexBarProvider;
22
+ readonly source?: string;
23
+ readonly sessionCostUSD?: number;
24
+ readonly last30DaysCostUSD?: number;
25
+ readonly totalCostUSD?: number;
26
+ readonly totalTokens?: number;
27
+ readonly updatedAt?: string;
28
+ };
29
+ export declare class CodexBarJsonError extends Error {
30
+ readonly name = "CodexBarJsonError";
31
+ readonly reason: string;
32
+ readonly inputLength: number;
33
+ constructor(reason: string, inputLength: number, options?: ErrorOptions);
34
+ }
35
+ export declare class CodexBarUnsafeOutputError extends Error {
36
+ readonly name = "CodexBarUnsafeOutputError";
37
+ readonly jsonPath: string;
38
+ constructor(jsonPath: string);
39
+ }
40
+ export declare function parseCodexBarUsageJson(stdout: string): CodexBarUsageSummary;
41
+ export declare function parseCodexBarCostJson(stdout: string): readonly CodexBarCostSummary[];
42
+ export declare function redactCodexBarJson(value: unknown): unknown;
43
+ export declare function hasSecretLikeValue(value: unknown): boolean;
44
+ //# sourceMappingURL=codexbar-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codexbar-adapter.d.ts","sourceRoot":"","sources":["../../src/core/codexbar-adapter.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEtC,MAAM,MAAM,0BAA0B,GAAG;IACxC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IAClC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,0BAA0B,CAAC;IAC9C,QAAQ,CAAC,SAAS,CAAC,EAAE,0BAA0B,CAAC;IAChD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,qBAAqB,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IACjC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,qBAAa,iBAAkB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,IAAI,uBAAuB;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B,YAAY,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,EAItE;CACD;AAED,qBAAa,yBAA0B,SAAQ,KAAK;IACnD,QAAQ,CAAC,IAAI,+BAA+B;IAC5C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,YAAY,QAAQ,EAAE,MAAM,EAG3B;CACD;AAkBD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,oBAAoB,CA6B3E;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,mBAAmB,EAAE,CAYpF;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE1D;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE1D","sourcesContent":["export type CodexBarProvider = string;\n\nexport type CodexBarUsageWindowSummary = {\n\treadonly usedPercent?: number;\n\treadonly resetsAt?: string;\n};\n\nexport type CodexBarStatusSummary = {\n\treadonly indicator?: string;\n\treadonly description?: string;\n\treadonly url?: string;\n};\n\nexport type CodexBarUsageSummary = {\n\treadonly provider: CodexBarProvider;\n\treadonly source?: string;\n\treadonly primary?: CodexBarUsageWindowSummary;\n\treadonly secondary?: CodexBarUsageWindowSummary;\n\treadonly creditsRemaining?: number;\n\treadonly updatedAt?: string;\n\treadonly status?: CodexBarStatusSummary;\n};\n\nexport type CodexBarCostSummary = {\n\treadonly provider: CodexBarProvider;\n\treadonly source?: string;\n\treadonly sessionCostUSD?: number;\n\treadonly last30DaysCostUSD?: number;\n\treadonly totalCostUSD?: number;\n\treadonly totalTokens?: number;\n\treadonly updatedAt?: string;\n};\n\nexport class CodexBarJsonError extends Error {\n\treadonly name = \"CodexBarJsonError\";\n\treadonly reason: string;\n\treadonly inputLength: number;\n\n\tconstructor(reason: string, inputLength: number, options?: ErrorOptions) {\n\t\tsuper(reason, options);\n\t\tthis.reason = reason;\n\t\tthis.inputLength = inputLength;\n\t}\n}\n\nexport class CodexBarUnsafeOutputError extends Error {\n\treadonly name = \"CodexBarUnsafeOutputError\";\n\treadonly jsonPath: string;\n\n\tconstructor(jsonPath: string) {\n\t\tsuper(`CodexBar output contains a credential-like value at ${jsonPath}`);\n\t\tthis.jsonPath = jsonPath;\n\t}\n}\n\nconst REDACTED_FIELD_NAMES = [\n\t\"accountEmail\",\n\t\"accountOrganization\",\n\t\"signedInEmail\",\n\t\"creditEvents\",\n\t\"dailyBreakdown\",\n] as const;\n\nconst SECRET_LIKE_VALUE_PATTERNS = [\n\tnew RegExp(`${\"Bear\"}${\"er\"}\\\\s+\\\\S+`, \"i\"),\n\tnew RegExp(`${\"Cook\"}${\"ie\"}:\\\\s*`, \"i\"),\n\tnew RegExp(`\\\\b${\"s\"}${\"k\"}-[A-Za-z0-9_-]*`, \"i\"),\n\tnew RegExp(`\\\\b${\"g\"}${\"hp\"}_[A-Za-z0-9_]+`, \"i\"),\n\tnew RegExp(`\\\\b${\"e\"}${\"y\"}${\"J\"}[A-Za-z0-9_-]{8,}(?:\\\\.[A-Za-z0-9_-]+){0,2}\\\\b`),\n] as const;\n\nexport function parseCodexBarUsageJson(stdout: string): CodexBarUsageSummary {\n\tconst parsed = parseJson(stdout);\n\tif (!isRecord(parsed)) {\n\t\tthrow new CodexBarJsonError(\"CodexBar usage JSON must be an object\", stdout.length);\n\t}\n\n\tconst usage = readRecord(parsed, \"usage\");\n\tconst credits = readRecord(parsed, \"credits\");\n\tconst statusRecord = readRecord(parsed, \"status\");\n\tconst primary = usage ? parseUsageWindow(usage.primary) : undefined;\n\tconst secondary = usage ? parseUsageWindow(usage.secondary) : undefined;\n\tconst status = parseStatus(statusRecord);\n\tconst source = readString(parsed, \"source\");\n\tconst creditsRemaining = credits ? readNumber(credits, \"remaining\") : undefined;\n\tconst updatedAt =\n\t\t(usage ? readString(usage, \"updatedAt\") : undefined) ??\n\t\treadString(parsed, \"updatedAt\") ??\n\t\t(credits ? readString(credits, \"updatedAt\") : undefined) ??\n\t\t(statusRecord ? readString(statusRecord, \"updatedAt\") : undefined);\n\n\treturn {\n\t\tprovider: readString(parsed, \"provider\") ?? \"unknown\",\n\t\t...(source === undefined ? {} : { source }),\n\t\t...(primary === undefined ? {} : { primary }),\n\t\t...(secondary === undefined ? {} : { secondary }),\n\t\t...(creditsRemaining === undefined ? {} : { creditsRemaining }),\n\t\t...(updatedAt === undefined ? {} : { updatedAt }),\n\t\t...(status === undefined ? {} : { status }),\n\t};\n}\n\nexport function parseCodexBarCostJson(stdout: string): readonly CodexBarCostSummary[] {\n\tconst parsed = parseJson(stdout);\n\tif (!isUnknownArray(parsed)) {\n\t\tthrow new CodexBarJsonError(\"CodexBar cost JSON must be an array\", stdout.length);\n\t}\n\n\treturn parsed.map((entry) => {\n\t\tif (!isRecord(entry)) {\n\t\t\tthrow new CodexBarJsonError(\"CodexBar cost entries must be objects\", stdout.length);\n\t\t}\n\t\treturn parseCostSummary(entry);\n\t});\n}\n\nexport function redactCodexBarJson(value: unknown): unknown {\n\treturn redactValue(value, undefined);\n}\n\nexport function hasSecretLikeValue(value: unknown): boolean {\n\treturn findUnsafeJsonPath(value, \"$\") !== undefined;\n}\n\nfunction parseJson(stdout: string): unknown {\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(stdout);\n\t} catch (error) {\n\t\tif (error instanceof SyntaxError) {\n\t\t\tthrow new CodexBarJsonError(\"CodexBar output is not valid JSON\", stdout.length, { cause: error });\n\t\t}\n\t\tthrow error;\n\t}\n\n\tconst unsafeJsonPath = findUnsafeJsonPath(parsed, \"$.\");\n\tif (unsafeJsonPath !== undefined) {\n\t\tthrow new CodexBarUnsafeOutputError(unsafeJsonPath);\n\t}\n\treturn parsed;\n}\n\nfunction parseUsageWindow(value: unknown): CodexBarUsageWindowSummary | undefined {\n\tif (!isRecord(value)) {\n\t\treturn undefined;\n\t}\n\n\tconst usedPercent = readNumber(value, \"usedPercent\");\n\tconst resetsAt = readString(value, \"resetsAt\");\n\tif (usedPercent === undefined && resetsAt === undefined) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\t...(usedPercent === undefined ? {} : { usedPercent }),\n\t\t...(resetsAt === undefined ? {} : { resetsAt }),\n\t};\n}\n\nfunction parseStatus(value: Record<string, unknown> | undefined): CodexBarStatusSummary | undefined {\n\tif (value === undefined) {\n\t\treturn undefined;\n\t}\n\n\tconst indicator = readString(value, \"indicator\");\n\tconst description = readString(value, \"description\");\n\tconst url = readString(value, \"url\");\n\tif (indicator === undefined && description === undefined && url === undefined) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\t...(indicator === undefined ? {} : { indicator }),\n\t\t...(description === undefined ? {} : { description }),\n\t\t...(url === undefined ? {} : { url }),\n\t};\n}\n\nfunction parseCostSummary(entry: Record<string, unknown>): CodexBarCostSummary {\n\tconst totals = readRecord(entry, \"totals\");\n\tconst source = readString(entry, \"source\");\n\tconst sessionCostUSD = readNumber(entry, \"sessionCostUSD\");\n\tconst last30DaysCostUSD = readNumber(entry, \"last30DaysCostUSD\");\n\tconst totalCostUSD = readNumber(entry, \"totalCostUSD\") ?? (totals ? readNumber(totals, \"totalCost\") : undefined);\n\tconst totalTokens = readNumber(entry, \"totalTokens\") ?? (totals ? readNumber(totals, \"totalTokens\") : undefined);\n\tconst updatedAt = readString(entry, \"updatedAt\");\n\n\treturn {\n\t\tprovider: readString(entry, \"provider\") ?? \"unknown\",\n\t\t...(source === undefined ? {} : { source }),\n\t\t...(sessionCostUSD === undefined ? {} : { sessionCostUSD }),\n\t\t...(last30DaysCostUSD === undefined ? {} : { last30DaysCostUSD }),\n\t\t...(totalCostUSD === undefined ? {} : { totalCostUSD }),\n\t\t...(totalTokens === undefined ? {} : { totalTokens }),\n\t\t...(updatedAt === undefined ? {} : { updatedAt }),\n\t};\n}\n\nfunction redactValue(value: unknown, parentKey: string | undefined): unknown {\n\tif (isUnknownArray(value)) {\n\t\treturn value.map((item) => redactValue(item, parentKey));\n\t}\n\tif (!isRecord(value)) {\n\t\treturn value;\n\t}\n\n\tconst redacted: Record<string, unknown> = {};\n\tfor (const [key, fieldValue] of Object.entries(value)) {\n\t\tif (shouldDropField(key, parentKey)) {\n\t\t\tcontinue;\n\t\t}\n\t\tredacted[key] = redactValue(fieldValue, key);\n\t}\n\treturn redacted;\n}\n\nfunction shouldDropField(key: string, parentKey: string | undefined): boolean {\n\tif (REDACTED_FIELD_NAMES.some((fieldName) => fieldName === key)) {\n\t\treturn true;\n\t}\n\treturn parentKey === \"projects\" && (key === \"path\" || key === \"name\");\n}\n\nfunction findUnsafeJsonPath(value: unknown, jsonPath: string): string | undefined {\n\tif (typeof value === \"string\") {\n\t\treturn isSecretLikeString(value) ? jsonPath : undefined;\n\t}\n\tif (isUnknownArray(value)) {\n\t\tfor (const [index, item] of value.entries()) {\n\t\t\tconst found = findUnsafeJsonPath(item, `${jsonPath}[${index}]`);\n\t\t\tif (found !== undefined) {\n\t\t\t\treturn found;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\tif (!isRecord(value)) {\n\t\treturn undefined;\n\t}\n\n\tfor (const [key, fieldValue] of Object.entries(value)) {\n\t\tconst separator = jsonPath.endsWith(\".\") ? \"\" : \".\";\n\t\tconst found = findUnsafeJsonPath(fieldValue, `${jsonPath}${separator}${key}`);\n\t\tif (found !== undefined) {\n\t\t\treturn found;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction isSecretLikeString(value: string): boolean {\n\treturn SECRET_LIKE_VALUE_PATTERNS.some((pattern) => pattern.test(value));\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isUnknownArray(value: unknown): value is readonly unknown[] {\n\treturn Array.isArray(value);\n}\n\nfunction readRecord(record: Record<string, unknown>, key: string): Record<string, unknown> | undefined {\n\tconst value = record[key];\n\treturn isRecord(value) ? value : undefined;\n}\n\nfunction readString(record: Record<string, unknown>, key: string): string | undefined {\n\tconst value = record[key];\n\treturn typeof value === \"string\" ? value : undefined;\n}\n\nfunction readNumber(record: Record<string, unknown>, key: string): number | undefined {\n\tconst value = record[key];\n\treturn typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n"]}
@@ -0,0 +1,211 @@
1
+ export class CodexBarJsonError extends Error {
2
+ name = "CodexBarJsonError";
3
+ reason;
4
+ inputLength;
5
+ constructor(reason, inputLength, options) {
6
+ super(reason, options);
7
+ this.reason = reason;
8
+ this.inputLength = inputLength;
9
+ }
10
+ }
11
+ export class CodexBarUnsafeOutputError extends Error {
12
+ name = "CodexBarUnsafeOutputError";
13
+ jsonPath;
14
+ constructor(jsonPath) {
15
+ super(`CodexBar output contains a credential-like value at ${jsonPath}`);
16
+ this.jsonPath = jsonPath;
17
+ }
18
+ }
19
+ const REDACTED_FIELD_NAMES = [
20
+ "accountEmail",
21
+ "accountOrganization",
22
+ "signedInEmail",
23
+ "creditEvents",
24
+ "dailyBreakdown",
25
+ ];
26
+ const SECRET_LIKE_VALUE_PATTERNS = [
27
+ new RegExp(`${"Bear"}${"er"}\\s+\\S+`, "i"),
28
+ new RegExp(`${"Cook"}${"ie"}:\\s*`, "i"),
29
+ new RegExp(`\\b${"s"}${"k"}-[A-Za-z0-9_-]*`, "i"),
30
+ new RegExp(`\\b${"g"}${"hp"}_[A-Za-z0-9_]+`, "i"),
31
+ new RegExp(`\\b${"e"}${"y"}${"J"}[A-Za-z0-9_-]{8,}(?:\\.[A-Za-z0-9_-]+){0,2}\\b`),
32
+ ];
33
+ export function parseCodexBarUsageJson(stdout) {
34
+ const parsed = parseJson(stdout);
35
+ if (!isRecord(parsed)) {
36
+ throw new CodexBarJsonError("CodexBar usage JSON must be an object", stdout.length);
37
+ }
38
+ const usage = readRecord(parsed, "usage");
39
+ const credits = readRecord(parsed, "credits");
40
+ const statusRecord = readRecord(parsed, "status");
41
+ const primary = usage ? parseUsageWindow(usage.primary) : undefined;
42
+ const secondary = usage ? parseUsageWindow(usage.secondary) : undefined;
43
+ const status = parseStatus(statusRecord);
44
+ const source = readString(parsed, "source");
45
+ const creditsRemaining = credits ? readNumber(credits, "remaining") : undefined;
46
+ const updatedAt = (usage ? readString(usage, "updatedAt") : undefined) ??
47
+ readString(parsed, "updatedAt") ??
48
+ (credits ? readString(credits, "updatedAt") : undefined) ??
49
+ (statusRecord ? readString(statusRecord, "updatedAt") : undefined);
50
+ return {
51
+ provider: readString(parsed, "provider") ?? "unknown",
52
+ ...(source === undefined ? {} : { source }),
53
+ ...(primary === undefined ? {} : { primary }),
54
+ ...(secondary === undefined ? {} : { secondary }),
55
+ ...(creditsRemaining === undefined ? {} : { creditsRemaining }),
56
+ ...(updatedAt === undefined ? {} : { updatedAt }),
57
+ ...(status === undefined ? {} : { status }),
58
+ };
59
+ }
60
+ export function parseCodexBarCostJson(stdout) {
61
+ const parsed = parseJson(stdout);
62
+ if (!isUnknownArray(parsed)) {
63
+ throw new CodexBarJsonError("CodexBar cost JSON must be an array", stdout.length);
64
+ }
65
+ return parsed.map((entry) => {
66
+ if (!isRecord(entry)) {
67
+ throw new CodexBarJsonError("CodexBar cost entries must be objects", stdout.length);
68
+ }
69
+ return parseCostSummary(entry);
70
+ });
71
+ }
72
+ export function redactCodexBarJson(value) {
73
+ return redactValue(value, undefined);
74
+ }
75
+ export function hasSecretLikeValue(value) {
76
+ return findUnsafeJsonPath(value, "$") !== undefined;
77
+ }
78
+ function parseJson(stdout) {
79
+ let parsed;
80
+ try {
81
+ parsed = JSON.parse(stdout);
82
+ }
83
+ catch (error) {
84
+ if (error instanceof SyntaxError) {
85
+ throw new CodexBarJsonError("CodexBar output is not valid JSON", stdout.length, { cause: error });
86
+ }
87
+ throw error;
88
+ }
89
+ const unsafeJsonPath = findUnsafeJsonPath(parsed, "$.");
90
+ if (unsafeJsonPath !== undefined) {
91
+ throw new CodexBarUnsafeOutputError(unsafeJsonPath);
92
+ }
93
+ return parsed;
94
+ }
95
+ function parseUsageWindow(value) {
96
+ if (!isRecord(value)) {
97
+ return undefined;
98
+ }
99
+ const usedPercent = readNumber(value, "usedPercent");
100
+ const resetsAt = readString(value, "resetsAt");
101
+ if (usedPercent === undefined && resetsAt === undefined) {
102
+ return undefined;
103
+ }
104
+ return {
105
+ ...(usedPercent === undefined ? {} : { usedPercent }),
106
+ ...(resetsAt === undefined ? {} : { resetsAt }),
107
+ };
108
+ }
109
+ function parseStatus(value) {
110
+ if (value === undefined) {
111
+ return undefined;
112
+ }
113
+ const indicator = readString(value, "indicator");
114
+ const description = readString(value, "description");
115
+ const url = readString(value, "url");
116
+ if (indicator === undefined && description === undefined && url === undefined) {
117
+ return undefined;
118
+ }
119
+ return {
120
+ ...(indicator === undefined ? {} : { indicator }),
121
+ ...(description === undefined ? {} : { description }),
122
+ ...(url === undefined ? {} : { url }),
123
+ };
124
+ }
125
+ function parseCostSummary(entry) {
126
+ const totals = readRecord(entry, "totals");
127
+ const source = readString(entry, "source");
128
+ const sessionCostUSD = readNumber(entry, "sessionCostUSD");
129
+ const last30DaysCostUSD = readNumber(entry, "last30DaysCostUSD");
130
+ const totalCostUSD = readNumber(entry, "totalCostUSD") ?? (totals ? readNumber(totals, "totalCost") : undefined);
131
+ const totalTokens = readNumber(entry, "totalTokens") ?? (totals ? readNumber(totals, "totalTokens") : undefined);
132
+ const updatedAt = readString(entry, "updatedAt");
133
+ return {
134
+ provider: readString(entry, "provider") ?? "unknown",
135
+ ...(source === undefined ? {} : { source }),
136
+ ...(sessionCostUSD === undefined ? {} : { sessionCostUSD }),
137
+ ...(last30DaysCostUSD === undefined ? {} : { last30DaysCostUSD }),
138
+ ...(totalCostUSD === undefined ? {} : { totalCostUSD }),
139
+ ...(totalTokens === undefined ? {} : { totalTokens }),
140
+ ...(updatedAt === undefined ? {} : { updatedAt }),
141
+ };
142
+ }
143
+ function redactValue(value, parentKey) {
144
+ if (isUnknownArray(value)) {
145
+ return value.map((item) => redactValue(item, parentKey));
146
+ }
147
+ if (!isRecord(value)) {
148
+ return value;
149
+ }
150
+ const redacted = {};
151
+ for (const [key, fieldValue] of Object.entries(value)) {
152
+ if (shouldDropField(key, parentKey)) {
153
+ continue;
154
+ }
155
+ redacted[key] = redactValue(fieldValue, key);
156
+ }
157
+ return redacted;
158
+ }
159
+ function shouldDropField(key, parentKey) {
160
+ if (REDACTED_FIELD_NAMES.some((fieldName) => fieldName === key)) {
161
+ return true;
162
+ }
163
+ return parentKey === "projects" && (key === "path" || key === "name");
164
+ }
165
+ function findUnsafeJsonPath(value, jsonPath) {
166
+ if (typeof value === "string") {
167
+ return isSecretLikeString(value) ? jsonPath : undefined;
168
+ }
169
+ if (isUnknownArray(value)) {
170
+ for (const [index, item] of value.entries()) {
171
+ const found = findUnsafeJsonPath(item, `${jsonPath}[${index}]`);
172
+ if (found !== undefined) {
173
+ return found;
174
+ }
175
+ }
176
+ return undefined;
177
+ }
178
+ if (!isRecord(value)) {
179
+ return undefined;
180
+ }
181
+ for (const [key, fieldValue] of Object.entries(value)) {
182
+ const separator = jsonPath.endsWith(".") ? "" : ".";
183
+ const found = findUnsafeJsonPath(fieldValue, `${jsonPath}${separator}${key}`);
184
+ if (found !== undefined) {
185
+ return found;
186
+ }
187
+ }
188
+ return undefined;
189
+ }
190
+ function isSecretLikeString(value) {
191
+ return SECRET_LIKE_VALUE_PATTERNS.some((pattern) => pattern.test(value));
192
+ }
193
+ function isRecord(value) {
194
+ return typeof value === "object" && value !== null && !Array.isArray(value);
195
+ }
196
+ function isUnknownArray(value) {
197
+ return Array.isArray(value);
198
+ }
199
+ function readRecord(record, key) {
200
+ const value = record[key];
201
+ return isRecord(value) ? value : undefined;
202
+ }
203
+ function readString(record, key) {
204
+ const value = record[key];
205
+ return typeof value === "string" ? value : undefined;
206
+ }
207
+ function readNumber(record, key) {
208
+ const value = record[key];
209
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
210
+ }
211
+ //# sourceMappingURL=codexbar-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codexbar-adapter.js","sourceRoot":"","sources":["../../src/core/codexbar-adapter.ts"],"names":[],"mappings":"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","sourcesContent":["export type CodexBarProvider = string;\n\nexport type CodexBarUsageWindowSummary = {\n\treadonly usedPercent?: number;\n\treadonly resetsAt?: string;\n};\n\nexport type CodexBarStatusSummary = {\n\treadonly indicator?: string;\n\treadonly description?: string;\n\treadonly url?: string;\n};\n\nexport type CodexBarUsageSummary = {\n\treadonly provider: CodexBarProvider;\n\treadonly source?: string;\n\treadonly primary?: CodexBarUsageWindowSummary;\n\treadonly secondary?: CodexBarUsageWindowSummary;\n\treadonly creditsRemaining?: number;\n\treadonly updatedAt?: string;\n\treadonly status?: CodexBarStatusSummary;\n};\n\nexport type CodexBarCostSummary = {\n\treadonly provider: CodexBarProvider;\n\treadonly source?: string;\n\treadonly sessionCostUSD?: number;\n\treadonly last30DaysCostUSD?: number;\n\treadonly totalCostUSD?: number;\n\treadonly totalTokens?: number;\n\treadonly updatedAt?: string;\n};\n\nexport class CodexBarJsonError extends Error {\n\treadonly name = \"CodexBarJsonError\";\n\treadonly reason: string;\n\treadonly inputLength: number;\n\n\tconstructor(reason: string, inputLength: number, options?: ErrorOptions) {\n\t\tsuper(reason, options);\n\t\tthis.reason = reason;\n\t\tthis.inputLength = inputLength;\n\t}\n}\n\nexport class CodexBarUnsafeOutputError extends Error {\n\treadonly name = \"CodexBarUnsafeOutputError\";\n\treadonly jsonPath: string;\n\n\tconstructor(jsonPath: string) {\n\t\tsuper(`CodexBar output contains a credential-like value at ${jsonPath}`);\n\t\tthis.jsonPath = jsonPath;\n\t}\n}\n\nconst REDACTED_FIELD_NAMES = [\n\t\"accountEmail\",\n\t\"accountOrganization\",\n\t\"signedInEmail\",\n\t\"creditEvents\",\n\t\"dailyBreakdown\",\n] as const;\n\nconst SECRET_LIKE_VALUE_PATTERNS = [\n\tnew RegExp(`${\"Bear\"}${\"er\"}\\\\s+\\\\S+`, \"i\"),\n\tnew RegExp(`${\"Cook\"}${\"ie\"}:\\\\s*`, \"i\"),\n\tnew RegExp(`\\\\b${\"s\"}${\"k\"}-[A-Za-z0-9_-]*`, \"i\"),\n\tnew RegExp(`\\\\b${\"g\"}${\"hp\"}_[A-Za-z0-9_]+`, \"i\"),\n\tnew RegExp(`\\\\b${\"e\"}${\"y\"}${\"J\"}[A-Za-z0-9_-]{8,}(?:\\\\.[A-Za-z0-9_-]+){0,2}\\\\b`),\n] as const;\n\nexport function parseCodexBarUsageJson(stdout: string): CodexBarUsageSummary {\n\tconst parsed = parseJson(stdout);\n\tif (!isRecord(parsed)) {\n\t\tthrow new CodexBarJsonError(\"CodexBar usage JSON must be an object\", stdout.length);\n\t}\n\n\tconst usage = readRecord(parsed, \"usage\");\n\tconst credits = readRecord(parsed, \"credits\");\n\tconst statusRecord = readRecord(parsed, \"status\");\n\tconst primary = usage ? parseUsageWindow(usage.primary) : undefined;\n\tconst secondary = usage ? parseUsageWindow(usage.secondary) : undefined;\n\tconst status = parseStatus(statusRecord);\n\tconst source = readString(parsed, \"source\");\n\tconst creditsRemaining = credits ? readNumber(credits, \"remaining\") : undefined;\n\tconst updatedAt =\n\t\t(usage ? readString(usage, \"updatedAt\") : undefined) ??\n\t\treadString(parsed, \"updatedAt\") ??\n\t\t(credits ? readString(credits, \"updatedAt\") : undefined) ??\n\t\t(statusRecord ? readString(statusRecord, \"updatedAt\") : undefined);\n\n\treturn {\n\t\tprovider: readString(parsed, \"provider\") ?? \"unknown\",\n\t\t...(source === undefined ? {} : { source }),\n\t\t...(primary === undefined ? {} : { primary }),\n\t\t...(secondary === undefined ? {} : { secondary }),\n\t\t...(creditsRemaining === undefined ? {} : { creditsRemaining }),\n\t\t...(updatedAt === undefined ? {} : { updatedAt }),\n\t\t...(status === undefined ? {} : { status }),\n\t};\n}\n\nexport function parseCodexBarCostJson(stdout: string): readonly CodexBarCostSummary[] {\n\tconst parsed = parseJson(stdout);\n\tif (!isUnknownArray(parsed)) {\n\t\tthrow new CodexBarJsonError(\"CodexBar cost JSON must be an array\", stdout.length);\n\t}\n\n\treturn parsed.map((entry) => {\n\t\tif (!isRecord(entry)) {\n\t\t\tthrow new CodexBarJsonError(\"CodexBar cost entries must be objects\", stdout.length);\n\t\t}\n\t\treturn parseCostSummary(entry);\n\t});\n}\n\nexport function redactCodexBarJson(value: unknown): unknown {\n\treturn redactValue(value, undefined);\n}\n\nexport function hasSecretLikeValue(value: unknown): boolean {\n\treturn findUnsafeJsonPath(value, \"$\") !== undefined;\n}\n\nfunction parseJson(stdout: string): unknown {\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(stdout);\n\t} catch (error) {\n\t\tif (error instanceof SyntaxError) {\n\t\t\tthrow new CodexBarJsonError(\"CodexBar output is not valid JSON\", stdout.length, { cause: error });\n\t\t}\n\t\tthrow error;\n\t}\n\n\tconst unsafeJsonPath = findUnsafeJsonPath(parsed, \"$.\");\n\tif (unsafeJsonPath !== undefined) {\n\t\tthrow new CodexBarUnsafeOutputError(unsafeJsonPath);\n\t}\n\treturn parsed;\n}\n\nfunction parseUsageWindow(value: unknown): CodexBarUsageWindowSummary | undefined {\n\tif (!isRecord(value)) {\n\t\treturn undefined;\n\t}\n\n\tconst usedPercent = readNumber(value, \"usedPercent\");\n\tconst resetsAt = readString(value, \"resetsAt\");\n\tif (usedPercent === undefined && resetsAt === undefined) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\t...(usedPercent === undefined ? {} : { usedPercent }),\n\t\t...(resetsAt === undefined ? {} : { resetsAt }),\n\t};\n}\n\nfunction parseStatus(value: Record<string, unknown> | undefined): CodexBarStatusSummary | undefined {\n\tif (value === undefined) {\n\t\treturn undefined;\n\t}\n\n\tconst indicator = readString(value, \"indicator\");\n\tconst description = readString(value, \"description\");\n\tconst url = readString(value, \"url\");\n\tif (indicator === undefined && description === undefined && url === undefined) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\t...(indicator === undefined ? {} : { indicator }),\n\t\t...(description === undefined ? {} : { description }),\n\t\t...(url === undefined ? {} : { url }),\n\t};\n}\n\nfunction parseCostSummary(entry: Record<string, unknown>): CodexBarCostSummary {\n\tconst totals = readRecord(entry, \"totals\");\n\tconst source = readString(entry, \"source\");\n\tconst sessionCostUSD = readNumber(entry, \"sessionCostUSD\");\n\tconst last30DaysCostUSD = readNumber(entry, \"last30DaysCostUSD\");\n\tconst totalCostUSD = readNumber(entry, \"totalCostUSD\") ?? (totals ? readNumber(totals, \"totalCost\") : undefined);\n\tconst totalTokens = readNumber(entry, \"totalTokens\") ?? (totals ? readNumber(totals, \"totalTokens\") : undefined);\n\tconst updatedAt = readString(entry, \"updatedAt\");\n\n\treturn {\n\t\tprovider: readString(entry, \"provider\") ?? \"unknown\",\n\t\t...(source === undefined ? {} : { source }),\n\t\t...(sessionCostUSD === undefined ? {} : { sessionCostUSD }),\n\t\t...(last30DaysCostUSD === undefined ? {} : { last30DaysCostUSD }),\n\t\t...(totalCostUSD === undefined ? {} : { totalCostUSD }),\n\t\t...(totalTokens === undefined ? {} : { totalTokens }),\n\t\t...(updatedAt === undefined ? {} : { updatedAt }),\n\t};\n}\n\nfunction redactValue(value: unknown, parentKey: string | undefined): unknown {\n\tif (isUnknownArray(value)) {\n\t\treturn value.map((item) => redactValue(item, parentKey));\n\t}\n\tif (!isRecord(value)) {\n\t\treturn value;\n\t}\n\n\tconst redacted: Record<string, unknown> = {};\n\tfor (const [key, fieldValue] of Object.entries(value)) {\n\t\tif (shouldDropField(key, parentKey)) {\n\t\t\tcontinue;\n\t\t}\n\t\tredacted[key] = redactValue(fieldValue, key);\n\t}\n\treturn redacted;\n}\n\nfunction shouldDropField(key: string, parentKey: string | undefined): boolean {\n\tif (REDACTED_FIELD_NAMES.some((fieldName) => fieldName === key)) {\n\t\treturn true;\n\t}\n\treturn parentKey === \"projects\" && (key === \"path\" || key === \"name\");\n}\n\nfunction findUnsafeJsonPath(value: unknown, jsonPath: string): string | undefined {\n\tif (typeof value === \"string\") {\n\t\treturn isSecretLikeString(value) ? jsonPath : undefined;\n\t}\n\tif (isUnknownArray(value)) {\n\t\tfor (const [index, item] of value.entries()) {\n\t\t\tconst found = findUnsafeJsonPath(item, `${jsonPath}[${index}]`);\n\t\t\tif (found !== undefined) {\n\t\t\t\treturn found;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\tif (!isRecord(value)) {\n\t\treturn undefined;\n\t}\n\n\tfor (const [key, fieldValue] of Object.entries(value)) {\n\t\tconst separator = jsonPath.endsWith(\".\") ? \"\" : \".\";\n\t\tconst found = findUnsafeJsonPath(fieldValue, `${jsonPath}${separator}${key}`);\n\t\tif (found !== undefined) {\n\t\t\treturn found;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction isSecretLikeString(value: string): boolean {\n\treturn SECRET_LIKE_VALUE_PATTERNS.some((pattern) => pattern.test(value));\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isUnknownArray(value: unknown): value is readonly unknown[] {\n\treturn Array.isArray(value);\n}\n\nfunction readRecord(record: Record<string, unknown>, key: string): Record<string, unknown> | undefined {\n\tconst value = record[key];\n\treturn isRecord(value) ? value : undefined;\n}\n\nfunction readString(record: Record<string, unknown>, key: string): string | undefined {\n\tconst value = record[key];\n\treturn typeof value === \"string\" ? value : undefined;\n}\n\nfunction readNumber(record: Record<string, unknown>, key: string): number | undefined {\n\tconst value = record[key];\n\treturn typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n"]}
@@ -3,5 +3,7 @@
3
3
  */
4
4
  export * from "./branch-summarization.ts";
5
5
  export * from "./compaction.ts";
6
+ export * from "./model-policy.ts";
7
+ export * from "./resume-policy.ts";
6
8
  export * from "./utils.ts";
7
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/compaction/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC","sourcesContent":["/**\n * Compaction and summarization utilities.\n */\n\nexport * from \"./branch-summarization.ts\";\nexport * from \"./compaction.ts\";\nexport * from \"./utils.ts\";\n"]}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/compaction/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC","sourcesContent":["/**\n * Compaction and summarization utilities.\n */\n\nexport * from \"./branch-summarization.ts\";\nexport * from \"./compaction.ts\";\nexport * from \"./model-policy.ts\";\nexport * from \"./resume-policy.ts\";\nexport * from \"./utils.ts\";\n"]}
@@ -3,5 +3,7 @@
3
3
  */
4
4
  export * from "./branch-summarization.js";
5
5
  export * from "./compaction.js";
6
+ export * from "./model-policy.js";
7
+ export * from "./resume-policy.js";
6
8
  export * from "./utils.js";
7
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/compaction/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC","sourcesContent":["/**\n * Compaction and summarization utilities.\n */\n\nexport * from \"./branch-summarization.ts\";\nexport * from \"./compaction.ts\";\nexport * from \"./utils.ts\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/compaction/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC","sourcesContent":["/**\n * Compaction and summarization utilities.\n */\n\nexport * from \"./branch-summarization.ts\";\nexport * from \"./compaction.ts\";\nexport * from \"./model-policy.ts\";\nexport * from \"./resume-policy.ts\";\nexport * from \"./utils.ts\";\n"]}
@@ -0,0 +1,9 @@
1
+ import type { Api, Model } from "omk-ai";
2
+ /** True when the model id is a Grok image/generation model (not suitable for compaction chat). */
3
+ export declare function isImagineOrGenerationModel(model: Model<any>): boolean;
4
+ /**
5
+ * Model used for compaction summarization. Imagine/generation models fall back to a chat model
6
+ * on the same provider (prefer grok-4.5, then grok-4.3, then any other non-imagine registry chat).
7
+ */
8
+ export declare function resolveCompactionModel(sessionModel: Model<any>, availableModels?: readonly Model<Api>[]): Model<any>;
9
+ //# sourceMappingURL=model-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-policy.d.ts","sourceRoot":"","sources":["../../../src/core/compaction/model-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAgBzC,kGAAkG;AAClG,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,CAErE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,eAAe,CAAC,EAAE,SAAS,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAgBpH","sourcesContent":["import type { Api, Model } from \"omk-ai\";\n\nconst IMAGINE_MODEL_ID_PREFIX = \"grok-imagine-\";\n/** Preferred chat fallbacks when session model is Imagine-only (first match wins). */\nconst COMPACTION_PREFERRED_CHAT_IDS = [\"grok-4.5\", \"grok-4.3\"] as const;\nconst COMPACTION_FALLBACK_MODEL_ID = COMPACTION_PREFERRED_CHAT_IDS[0];\n\nfunction isChatCompactionCandidate(model: Model<Api>): boolean {\n\treturn !model.id.startsWith(IMAGINE_MODEL_ID_PREFIX);\n}\n\nfunction preferredChatRank(modelId: string): number {\n\tconst index = COMPACTION_PREFERRED_CHAT_IDS.indexOf(modelId as (typeof COMPACTION_PREFERRED_CHAT_IDS)[number]);\n\treturn index === -1 ? COMPACTION_PREFERRED_CHAT_IDS.length : index;\n}\n\n/** True when the model id is a Grok image/generation model (not suitable for compaction chat). */\nexport function isImagineOrGenerationModel(model: Model<any>): boolean {\n\treturn model.id.startsWith(IMAGINE_MODEL_ID_PREFIX);\n}\n\n/**\n * Model used for compaction summarization. Imagine/generation models fall back to a chat model\n * on the same provider (prefer grok-4.5, then grok-4.3, then any other non-imagine registry chat).\n */\nexport function resolveCompactionModel(sessionModel: Model<any>, availableModels?: readonly Model<Api>[]): Model<any> {\n\tif (!isImagineOrGenerationModel(sessionModel)) {\n\t\treturn sessionModel;\n\t}\n\tif (availableModels) {\n\t\tconst sameProviderChat = availableModels\n\t\t\t.filter((m) => m.provider === sessionModel.provider && isChatCompactionCandidate(m))\n\t\t\t.sort((a, b) => preferredChatRank(a.id) - preferredChatRank(b.id));\n\t\tif (sameProviderChat[0]) {\n\t\t\treturn sameProviderChat[0];\n\t\t}\n\t}\n\treturn {\n\t\t...sessionModel,\n\t\tid: COMPACTION_FALLBACK_MODEL_ID,\n\t};\n}\n"]}
@@ -0,0 +1,37 @@
1
+ const IMAGINE_MODEL_ID_PREFIX = "grok-imagine-";
2
+ /** Preferred chat fallbacks when session model is Imagine-only (first match wins). */
3
+ const COMPACTION_PREFERRED_CHAT_IDS = ["grok-4.5", "grok-4.3"];
4
+ const COMPACTION_FALLBACK_MODEL_ID = COMPACTION_PREFERRED_CHAT_IDS[0];
5
+ function isChatCompactionCandidate(model) {
6
+ return !model.id.startsWith(IMAGINE_MODEL_ID_PREFIX);
7
+ }
8
+ function preferredChatRank(modelId) {
9
+ const index = COMPACTION_PREFERRED_CHAT_IDS.indexOf(modelId);
10
+ return index === -1 ? COMPACTION_PREFERRED_CHAT_IDS.length : index;
11
+ }
12
+ /** True when the model id is a Grok image/generation model (not suitable for compaction chat). */
13
+ export function isImagineOrGenerationModel(model) {
14
+ return model.id.startsWith(IMAGINE_MODEL_ID_PREFIX);
15
+ }
16
+ /**
17
+ * Model used for compaction summarization. Imagine/generation models fall back to a chat model
18
+ * on the same provider (prefer grok-4.5, then grok-4.3, then any other non-imagine registry chat).
19
+ */
20
+ export function resolveCompactionModel(sessionModel, availableModels) {
21
+ if (!isImagineOrGenerationModel(sessionModel)) {
22
+ return sessionModel;
23
+ }
24
+ if (availableModels) {
25
+ const sameProviderChat = availableModels
26
+ .filter((m) => m.provider === sessionModel.provider && isChatCompactionCandidate(m))
27
+ .sort((a, b) => preferredChatRank(a.id) - preferredChatRank(b.id));
28
+ if (sameProviderChat[0]) {
29
+ return sameProviderChat[0];
30
+ }
31
+ }
32
+ return {
33
+ ...sessionModel,
34
+ id: COMPACTION_FALLBACK_MODEL_ID,
35
+ };
36
+ }
37
+ //# sourceMappingURL=model-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-policy.js","sourceRoot":"","sources":["../../../src/core/compaction/model-policy.ts"],"names":[],"mappings":"AAEA,MAAM,uBAAuB,GAAG,eAAe,CAAC;AAChD,sFAAsF;AACtF,MAAM,6BAA6B,GAAG,CAAC,UAAU,EAAE,UAAU,CAAU,CAAC;AACxE,MAAM,4BAA4B,GAAG,6BAA6B,CAAC,CAAC,CAAC,CAAC;AAEtE,SAAS,yBAAyB,CAAC,KAAiB,EAAW;IAC9D,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAC;AAAA,CACrD;AAED,SAAS,iBAAiB,CAAC,OAAe,EAAU;IACnD,MAAM,KAAK,GAAG,6BAA6B,CAAC,OAAO,CAAC,OAAyD,CAAC,CAAC;IAC/G,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,6BAA6B,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;AAAA,CACnE;AAED,kGAAkG;AAClG,MAAM,UAAU,0BAA0B,CAAC,KAAiB,EAAW;IACtE,OAAO,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAC;AAAA,CACpD;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,YAAwB,EAAE,eAAuC,EAAc;IACrH,IAAI,CAAC,0BAA0B,CAAC,YAAY,CAAC,EAAE,CAAC;QAC/C,OAAO,YAAY,CAAC;IACrB,CAAC;IACD,IAAI,eAAe,EAAE,CAAC;QACrB,MAAM,gBAAgB,GAAG,eAAe;aACtC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,YAAY,CAAC,QAAQ,IAAI,yBAAyB,CAAC,CAAC,CAAC,CAAC;aACnF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACpE,IAAI,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;YACzB,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC;QAC5B,CAAC;IACF,CAAC;IACD,OAAO;QACN,GAAG,YAAY;QACf,EAAE,EAAE,4BAA4B;KAChC,CAAC;AAAA,CACF","sourcesContent":["import type { Api, Model } from \"omk-ai\";\n\nconst IMAGINE_MODEL_ID_PREFIX = \"grok-imagine-\";\n/** Preferred chat fallbacks when session model is Imagine-only (first match wins). */\nconst COMPACTION_PREFERRED_CHAT_IDS = [\"grok-4.5\", \"grok-4.3\"] as const;\nconst COMPACTION_FALLBACK_MODEL_ID = COMPACTION_PREFERRED_CHAT_IDS[0];\n\nfunction isChatCompactionCandidate(model: Model<Api>): boolean {\n\treturn !model.id.startsWith(IMAGINE_MODEL_ID_PREFIX);\n}\n\nfunction preferredChatRank(modelId: string): number {\n\tconst index = COMPACTION_PREFERRED_CHAT_IDS.indexOf(modelId as (typeof COMPACTION_PREFERRED_CHAT_IDS)[number]);\n\treturn index === -1 ? COMPACTION_PREFERRED_CHAT_IDS.length : index;\n}\n\n/** True when the model id is a Grok image/generation model (not suitable for compaction chat). */\nexport function isImagineOrGenerationModel(model: Model<any>): boolean {\n\treturn model.id.startsWith(IMAGINE_MODEL_ID_PREFIX);\n}\n\n/**\n * Model used for compaction summarization. Imagine/generation models fall back to a chat model\n * on the same provider (prefer grok-4.5, then grok-4.3, then any other non-imagine registry chat).\n */\nexport function resolveCompactionModel(sessionModel: Model<any>, availableModels?: readonly Model<Api>[]): Model<any> {\n\tif (!isImagineOrGenerationModel(sessionModel)) {\n\t\treturn sessionModel;\n\t}\n\tif (availableModels) {\n\t\tconst sameProviderChat = availableModels\n\t\t\t.filter((m) => m.provider === sessionModel.provider && isChatCompactionCandidate(m))\n\t\t\t.sort((a, b) => preferredChatRank(a.id) - preferredChatRank(b.id));\n\t\tif (sameProviderChat[0]) {\n\t\t\treturn sameProviderChat[0];\n\t\t}\n\t}\n\treturn {\n\t\t...sessionModel,\n\t\tid: COMPACTION_FALLBACK_MODEL_ID,\n\t};\n}\n"]}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * When threshold autocompaction finishes with agent-level queued messages (steer/follow-up/custom),
3
+ * the TUI must flush its compaction queue. It keys off compaction_end.willRetry.
4
+ */
5
+ export declare function compactionEmitWillRetry(willRetry: boolean, hasQueuedAgentMessages: boolean): boolean;
6
+ //# sourceMappingURL=resume-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resume-policy.d.ts","sourceRoot":"","sources":["../../../src/core/compaction/resume-policy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,OAAO,EAAE,sBAAsB,EAAE,OAAO,GAAG,OAAO,CAEpG","sourcesContent":["/**\n * When threshold autocompaction finishes with agent-level queued messages (steer/follow-up/custom),\n * the TUI must flush its compaction queue. It keys off compaction_end.willRetry.\n */\nexport function compactionEmitWillRetry(willRetry: boolean, hasQueuedAgentMessages: boolean): boolean {\n\treturn willRetry || hasQueuedAgentMessages;\n}\n"]}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * When threshold autocompaction finishes with agent-level queued messages (steer/follow-up/custom),
3
+ * the TUI must flush its compaction queue. It keys off compaction_end.willRetry.
4
+ */
5
+ export function compactionEmitWillRetry(willRetry, hasQueuedAgentMessages) {
6
+ return willRetry || hasQueuedAgentMessages;
7
+ }
8
+ //# sourceMappingURL=resume-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resume-policy.js","sourceRoot":"","sources":["../../../src/core/compaction/resume-policy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,SAAkB,EAAE,sBAA+B,EAAW;IACrG,OAAO,SAAS,IAAI,sBAAsB,CAAC;AAAA,CAC3C","sourcesContent":["/**\n * When threshold autocompaction finishes with agent-level queued messages (steer/follow-up/custom),\n * the TUI must flush its compaction queue. It keys off compaction_end.willRetry.\n */\nexport function compactionEmitWillRetry(willRetry: boolean, hasQueuedAgentMessages: boolean): boolean {\n\treturn willRetry || hasQueuedAgentMessages;\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":"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
+ {"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,EAK9B,MAAM,8BAA8B,CAAC;AAYtC,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\ttype TokenOptimizerRuntimeStatus,\n} from \"./context-budget-v2-types.ts\";\n\n// Inlined constant replacing the deleted legacy token-optimizer.ts module's\n// getTokenOptimizerRuntimeStatus(): a fixed, hardcoded compatibility status.\nconst TOKEN_OPTIMIZER_RUNTIME_STATUS: TokenOptimizerRuntimeStatus = {\n\toptimizerId: \"legacy-token-optimizer\",\n\tstatus: \"quarantined_compatibility\",\n\tactive: false,\n\tactiveContextBudgetOptimizer: \"context-budget-v2\",\n\tcompatibilityOnly: true,\n};\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: TOKEN_OPTIMIZER_RUNTIME_STATUS,\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"]}
@@ -5,7 +5,15 @@ import { compareOptionalForSelection } from "./context-budget-v2-scoring.js";
5
5
  import { applyPlannerRedundancyPenalties, buildTierAllocations, createPlannedItems, createTierUsage, emitCoverageDiagnostics, emitOmissionDiagnostics, selectHardItem, selectOptionalItem, } from "./context-budget-v2-selection.js";
6
6
  import { allocateTiers, computeTierDemand } from "./context-budget-v2-tiers.js";
7
7
  import { CONTEXT_BUDGET_POLICY_VERSION_V2, DEFAULT_TIER_POLICY_V2, } from "./context-budget-v2-types.js";
8
- import { getTokenOptimizerRuntimeStatus } from "./token-optimizer.js";
8
+ // Inlined constant replacing the deleted legacy token-optimizer.ts module's
9
+ // getTokenOptimizerRuntimeStatus(): a fixed, hardcoded compatibility status.
10
+ const TOKEN_OPTIMIZER_RUNTIME_STATUS = {
11
+ optimizerId: "legacy-token-optimizer",
12
+ status: "quarantined_compatibility",
13
+ active: false,
14
+ activeContextBudgetOptimizer: "context-budget-v2",
15
+ compatibilityOnly: true,
16
+ };
9
17
  export function planPromptContextBudgetV2(input) {
10
18
  const modelId = input.modelId ?? "unknown";
11
19
  const qualityPolicy = input.qualityPolicy ?? DEFAULT_HEADROOM_QUALITY_POLICY;
@@ -187,7 +195,7 @@ function buildObservability(input) {
187
195
  },
188
196
  planHash: input.planHash,
189
197
  cache: input.cacheTelemetry,
190
- tokenOptimizer: getTokenOptimizerRuntimeStatus(),
198
+ tokenOptimizer: TOKEN_OPTIMIZER_RUNTIME_STATUS,
191
199
  };
192
200
  }
193
201
  function countUniqueRetrievalFallbacks(retrievalFallbacks) {
@@ -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 {\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
+ {"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\ttype TokenOptimizerRuntimeStatus,\n} from \"./context-budget-v2-types.ts\";\n\n// Inlined constant replacing the deleted legacy token-optimizer.ts module's\n// getTokenOptimizerRuntimeStatus(): a fixed, hardcoded compatibility status.\nconst TOKEN_OPTIMIZER_RUNTIME_STATUS: TokenOptimizerRuntimeStatus = {\n\toptimizerId: \"legacy-token-optimizer\",\n\tstatus: \"quarantined_compatibility\",\n\tactive: false,\n\tactiveContextBudgetOptimizer: \"context-budget-v2\",\n\tcompatibilityOnly: true,\n};\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: TOKEN_OPTIMIZER_RUNTIME_STATUS,\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,7 +1,13 @@
1
1
  import type { ContextBudgetItemV2, ContextBudgetTierV2, ContextRepresentationCacheMetadataV2, ContextRepresentationCandidateV2, ContextRepresentationKindV2, ContextSourceRefV2, HeadroomQualityPolicyV2 } from "./context-budget-headroom.ts";
2
2
  import type { TokenCounterAdapter } from "./context-budget-token-counter.ts";
3
- import type { TokenOptimizerRuntimeStatus } from "./token-optimizer.ts";
4
3
  export declare const CONTEXT_BUDGET_POLICY_VERSION_V2 = "context-budget-v2";
4
+ export interface TokenOptimizerRuntimeStatus {
5
+ readonly optimizerId: "legacy-token-optimizer";
6
+ readonly status: "quarantined_compatibility";
7
+ readonly active: false;
8
+ readonly activeContextBudgetOptimizer: "context-budget-v2";
9
+ readonly compatibilityOnly: true;
10
+ }
5
11
  export interface TierBudgetPolicyV2 {
6
12
  readonly floorPct: number;
7
13
  readonly ceilingPct: number;