pi-smart-router 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. package/.pi/extensions/smart-router/command-formatters.ts +167 -0
  2. package/.pi/extensions/smart-router/commands.ts +242 -0
  3. package/.pi/extensions/smart-router/dataset-export.ts +142 -0
  4. package/.pi/extensions/smart-router/delegate-stream.ts +105 -0
  5. package/.pi/extensions/smart-router/delegation-runtime.ts +355 -0
  6. package/.pi/extensions/smart-router/extension-setup.ts +115 -0
  7. package/.pi/extensions/smart-router/fleet-bootstrap.ts +244 -0
  8. package/.pi/extensions/smart-router/index.ts +115 -0
  9. package/.pi/extensions/smart-router/package.json +3 -0
  10. package/.pi/extensions/smart-router/pi-model-scope.ts +55 -0
  11. package/.pi/extensions/smart-router/pricing-lifecycle.ts +43 -0
  12. package/.pi/extensions/smart-router/route-and-delegate.ts +562 -0
  13. package/.pi/extensions/smart-router/routing-context.ts +171 -0
  14. package/.pi/extensions/smart-router/routing-outcomes.ts +44 -0
  15. package/.pi/extensions/smart-router/session-lifecycle.ts +140 -0
  16. package/.pi/extensions/smart-router/stream-delegation.ts +75 -0
  17. package/.pi/extensions/smart-router/types.ts +90 -0
  18. package/.pi/extensions/smart-router/utils.ts +58 -0
  19. package/README.md +593 -0
  20. package/bin/pi-smart-router.mjs +79 -0
  21. package/config/.gitkeep +0 -0
  22. package/config/hydra-projection-weights.json.example +1169 -0
  23. package/config/models.yaml.example +58 -0
  24. package/config/p-success-weights.json.example +19 -0
  25. package/config/routing-calibration.json.example +1605 -0
  26. package/config/routing-centroids.json.example +1570 -0
  27. package/config/routing-clusters.yaml.example +41 -0
  28. package/data/contrib/example.json +25 -0
  29. package/dist/api/explain/router-explain.d.ts +47 -0
  30. package/dist/api/explain/router-explain.d.ts.map +1 -0
  31. package/dist/api/explain/router-explain.js +101 -0
  32. package/dist/api/explain/router-explain.js.map +1 -0
  33. package/dist/api/middleware/pi-router-middleware.d.ts +86 -0
  34. package/dist/api/middleware/pi-router-middleware.d.ts.map +1 -0
  35. package/dist/api/middleware/pi-router-middleware.js +83 -0
  36. package/dist/api/middleware/pi-router-middleware.js.map +1 -0
  37. package/dist/cli/smart-router-cli.d.ts +85 -0
  38. package/dist/cli/smart-router-cli.d.ts.map +1 -0
  39. package/dist/cli/smart-router-cli.js +293 -0
  40. package/dist/cli/smart-router-cli.js.map +1 -0
  41. package/dist/config/defaults.d.ts +7 -0
  42. package/dist/config/defaults.d.ts.map +1 -0
  43. package/dist/config/defaults.js +33 -0
  44. package/dist/config/defaults.js.map +1 -0
  45. package/dist/config/models-loader.d.ts +22 -0
  46. package/dist/config/models-loader.d.ts.map +1 -0
  47. package/dist/config/models-loader.js +51 -0
  48. package/dist/config/models-loader.js.map +1 -0
  49. package/dist/config/pi-model-mapper.d.ts +40 -0
  50. package/dist/config/pi-model-mapper.d.ts.map +1 -0
  51. package/dist/config/pi-model-mapper.js +216 -0
  52. package/dist/config/pi-model-mapper.js.map +1 -0
  53. package/dist/config/routing-clusters-loader.d.ts +35 -0
  54. package/dist/config/routing-clusters-loader.d.ts.map +1 -0
  55. package/dist/config/routing-clusters-loader.js +100 -0
  56. package/dist/config/routing-clusters-loader.js.map +1 -0
  57. package/dist/domain/delegation/delegation-context.d.ts +23 -0
  58. package/dist/domain/delegation/delegation-context.d.ts.map +1 -0
  59. package/dist/domain/delegation/delegation-context.js +73 -0
  60. package/dist/domain/delegation/delegation-context.js.map +1 -0
  61. package/dist/domain/delegation/execution-ledger.d.ts +19 -0
  62. package/dist/domain/delegation/execution-ledger.d.ts.map +1 -0
  63. package/dist/domain/delegation/execution-ledger.js +23 -0
  64. package/dist/domain/delegation/execution-ledger.js.map +1 -0
  65. package/dist/domain/delegation/output-headroom.d.ts +39 -0
  66. package/dist/domain/delegation/output-headroom.d.ts.map +1 -0
  67. package/dist/domain/delegation/output-headroom.js +78 -0
  68. package/dist/domain/delegation/output-headroom.js.map +1 -0
  69. package/dist/domain/matching/cluster-matcher.d.ts +69 -0
  70. package/dist/domain/matching/cluster-matcher.d.ts.map +1 -0
  71. package/dist/domain/matching/cluster-matcher.js +294 -0
  72. package/dist/domain/matching/cluster-matcher.js.map +1 -0
  73. package/dist/domain/matching/embedding-provider.d.ts +21 -0
  74. package/dist/domain/matching/embedding-provider.d.ts.map +1 -0
  75. package/dist/domain/matching/embedding-provider.js +42 -0
  76. package/dist/domain/matching/embedding-provider.js.map +1 -0
  77. package/dist/domain/matching/hydra-input.d.ts +18 -0
  78. package/dist/domain/matching/hydra-input.d.ts.map +1 -0
  79. package/dist/domain/matching/hydra-input.js +40 -0
  80. package/dist/domain/matching/hydra-input.js.map +1 -0
  81. package/dist/domain/matching/hydra-matcher.d.ts +103 -0
  82. package/dist/domain/matching/hydra-matcher.d.ts.map +1 -0
  83. package/dist/domain/matching/hydra-matcher.js +275 -0
  84. package/dist/domain/matching/hydra-matcher.js.map +1 -0
  85. package/dist/domain/pinning/cache-economics.d.ts +53 -0
  86. package/dist/domain/pinning/cache-economics.d.ts.map +1 -0
  87. package/dist/domain/pinning/cache-economics.js +72 -0
  88. package/dist/domain/pinning/cache-economics.js.map +1 -0
  89. package/dist/domain/pinning/loop-escalation.d.ts +41 -0
  90. package/dist/domain/pinning/loop-escalation.d.ts.map +1 -0
  91. package/dist/domain/pinning/loop-escalation.js +137 -0
  92. package/dist/domain/pinning/loop-escalation.js.map +1 -0
  93. package/dist/domain/pinning/session-pinner.d.ts +81 -0
  94. package/dist/domain/pinning/session-pinner.d.ts.map +1 -0
  95. package/dist/domain/pinning/session-pinner.js +237 -0
  96. package/dist/domain/pinning/session-pinner.js.map +1 -0
  97. package/dist/domain/pinning/sub-route-policy.d.ts +41 -0
  98. package/dist/domain/pinning/sub-route-policy.d.ts.map +1 -0
  99. package/dist/domain/pinning/sub-route-policy.js +72 -0
  100. package/dist/domain/pinning/sub-route-policy.js.map +1 -0
  101. package/dist/domain/pipeline/router-pipeline.d.ts +180 -0
  102. package/dist/domain/pipeline/router-pipeline.d.ts.map +1 -0
  103. package/dist/domain/pipeline/router-pipeline.js +807 -0
  104. package/dist/domain/pipeline/router-pipeline.js.map +1 -0
  105. package/dist/domain/pipeline/safe-default.d.ts +25 -0
  106. package/dist/domain/pipeline/safe-default.d.ts.map +1 -0
  107. package/dist/domain/pipeline/safe-default.js +41 -0
  108. package/dist/domain/pipeline/safe-default.js.map +1 -0
  109. package/dist/domain/refactor-guardrails.d.ts +48 -0
  110. package/dist/domain/refactor-guardrails.d.ts.map +1 -0
  111. package/dist/domain/refactor-guardrails.js +129 -0
  112. package/dist/domain/refactor-guardrails.js.map +1 -0
  113. package/dist/domain/routing/context-fit.d.ts +53 -0
  114. package/dist/domain/routing/context-fit.d.ts.map +1 -0
  115. package/dist/domain/routing/context-fit.js +142 -0
  116. package/dist/domain/routing/context-fit.js.map +1 -0
  117. package/dist/domain/routing/expected-cost.d.ts +63 -0
  118. package/dist/domain/routing/expected-cost.d.ts.map +1 -0
  119. package/dist/domain/routing/expected-cost.js +177 -0
  120. package/dist/domain/routing/expected-cost.js.map +1 -0
  121. package/dist/domain/routing/p-success-classifier.d.ts +130 -0
  122. package/dist/domain/routing/p-success-classifier.d.ts.map +1 -0
  123. package/dist/domain/routing/p-success-classifier.js +350 -0
  124. package/dist/domain/routing/p-success-classifier.js.map +1 -0
  125. package/dist/domain/routing/tier-features.d.ts +70 -0
  126. package/dist/domain/routing/tier-features.d.ts.map +1 -0
  127. package/dist/domain/routing/tier-features.js +174 -0
  128. package/dist/domain/routing/tier-features.js.map +1 -0
  129. package/dist/domain/routing/tool-history-guard.d.ts +32 -0
  130. package/dist/domain/routing/tool-history-guard.d.ts.map +1 -0
  131. package/dist/domain/routing/tool-history-guard.js +110 -0
  132. package/dist/domain/routing/tool-history-guard.js.map +1 -0
  133. package/dist/domain/scoring/multi-objective.d.ts +48 -0
  134. package/dist/domain/scoring/multi-objective.d.ts.map +1 -0
  135. package/dist/domain/scoring/multi-objective.js +116 -0
  136. package/dist/domain/scoring/multi-objective.js.map +1 -0
  137. package/dist/domain/triage/triage-engine.d.ts +43 -0
  138. package/dist/domain/triage/triage-engine.d.ts.map +1 -0
  139. package/dist/domain/triage/triage-engine.js +317 -0
  140. package/dist/domain/triage/triage-engine.js.map +1 -0
  141. package/dist/domain/triage/turn-envelope.d.ts +17 -0
  142. package/dist/domain/triage/turn-envelope.d.ts.map +1 -0
  143. package/dist/domain/triage/turn-envelope.js +81 -0
  144. package/dist/domain/triage/turn-envelope.js.map +1 -0
  145. package/dist/domain/types/entities.d.ts +303 -0
  146. package/dist/domain/types/entities.d.ts.map +1 -0
  147. package/dist/domain/types/entities.js +6 -0
  148. package/dist/domain/types/entities.js.map +1 -0
  149. package/dist/domain/types/index.d.ts +4 -0
  150. package/dist/domain/types/index.d.ts.map +1 -0
  151. package/dist/domain/types/index.js +2 -0
  152. package/dist/domain/types/index.js.map +1 -0
  153. package/dist/domain/types/schemas.d.ts +346 -0
  154. package/dist/domain/types/schemas.d.ts.map +1 -0
  155. package/dist/domain/types/schemas.js +241 -0
  156. package/dist/domain/types/schemas.js.map +1 -0
  157. package/dist/domain/types/store-port.d.ts +44 -0
  158. package/dist/domain/types/store-port.d.ts.map +1 -0
  159. package/dist/domain/types/store-port.js +6 -0
  160. package/dist/domain/types/store-port.js.map +1 -0
  161. package/dist/index.d.ts +39 -0
  162. package/dist/index.d.ts.map +1 -0
  163. package/dist/index.js +36 -0
  164. package/dist/index.js.map +1 -0
  165. package/dist/infra/gemini-provider.d.ts +28 -0
  166. package/dist/infra/gemini-provider.d.ts.map +1 -0
  167. package/dist/infra/gemini-provider.js +112 -0
  168. package/dist/infra/gemini-provider.js.map +1 -0
  169. package/dist/infra/telemetry.d.ts +51 -0
  170. package/dist/infra/telemetry.d.ts.map +1 -0
  171. package/dist/infra/telemetry.js +100 -0
  172. package/dist/infra/telemetry.js.map +1 -0
  173. package/dist/infrastructure/delegation/provider-error.d.ts +44 -0
  174. package/dist/infrastructure/delegation/provider-error.d.ts.map +1 -0
  175. package/dist/infrastructure/delegation/provider-error.js +179 -0
  176. package/dist/infrastructure/delegation/provider-error.js.map +1 -0
  177. package/dist/infrastructure/gateway/circuit-breaker.d.ts +68 -0
  178. package/dist/infrastructure/gateway/circuit-breaker.d.ts.map +1 -0
  179. package/dist/infrastructure/gateway/circuit-breaker.js +150 -0
  180. package/dist/infrastructure/gateway/circuit-breaker.js.map +1 -0
  181. package/dist/infrastructure/gateway/gateway-dispatch.d.ts +138 -0
  182. package/dist/infrastructure/gateway/gateway-dispatch.d.ts.map +1 -0
  183. package/dist/infrastructure/gateway/gateway-dispatch.js +308 -0
  184. package/dist/infrastructure/gateway/gateway-dispatch.js.map +1 -0
  185. package/dist/infrastructure/hardware/hardware-probe.d.ts +32 -0
  186. package/dist/infrastructure/hardware/hardware-probe.d.ts.map +1 -0
  187. package/dist/infrastructure/hardware/hardware-probe.js +199 -0
  188. package/dist/infrastructure/hardware/hardware-probe.js.map +1 -0
  189. package/dist/infrastructure/local/local-zero-tier.d.ts +47 -0
  190. package/dist/infrastructure/local/local-zero-tier.d.ts.map +1 -0
  191. package/dist/infrastructure/local/local-zero-tier.js +92 -0
  192. package/dist/infrastructure/local/local-zero-tier.js.map +1 -0
  193. package/dist/infrastructure/persistence/memory-store.d.ts +31 -0
  194. package/dist/infrastructure/persistence/memory-store.d.ts.map +1 -0
  195. package/dist/infrastructure/persistence/memory-store.js +87 -0
  196. package/dist/infrastructure/persistence/memory-store.js.map +1 -0
  197. package/dist/infrastructure/persistence/sqlite-store.d.ts +81 -0
  198. package/dist/infrastructure/persistence/sqlite-store.d.ts.map +1 -0
  199. package/dist/infrastructure/persistence/sqlite-store.js +658 -0
  200. package/dist/infrastructure/persistence/sqlite-store.js.map +1 -0
  201. package/dist/infrastructure/pricing/litellm-fetch.d.ts +46 -0
  202. package/dist/infrastructure/pricing/litellm-fetch.d.ts.map +1 -0
  203. package/dist/infrastructure/pricing/litellm-fetch.js +145 -0
  204. package/dist/infrastructure/pricing/litellm-fetch.js.map +1 -0
  205. package/dist/infrastructure/pricing/price-broker.d.ts +56 -0
  206. package/dist/infrastructure/pricing/price-broker.d.ts.map +1 -0
  207. package/dist/infrastructure/pricing/price-broker.js +133 -0
  208. package/dist/infrastructure/pricing/price-broker.js.map +1 -0
  209. package/dist/infrastructure/pricing/pricing-monitor.d.ts +27 -0
  210. package/dist/infrastructure/pricing/pricing-monitor.d.ts.map +1 -0
  211. package/dist/infrastructure/pricing/pricing-monitor.js +46 -0
  212. package/dist/infrastructure/pricing/pricing-monitor.js.map +1 -0
  213. package/dist/infrastructure/telemetry/dataset-limits.d.ts +13 -0
  214. package/dist/infrastructure/telemetry/dataset-limits.d.ts.map +1 -0
  215. package/dist/infrastructure/telemetry/dataset-limits.js +28 -0
  216. package/dist/infrastructure/telemetry/dataset-limits.js.map +1 -0
  217. package/dist/infrastructure/telemetry/dataset-recorder.d.ts +48 -0
  218. package/dist/infrastructure/telemetry/dataset-recorder.d.ts.map +1 -0
  219. package/dist/infrastructure/telemetry/dataset-recorder.js +154 -0
  220. package/dist/infrastructure/telemetry/dataset-recorder.js.map +1 -0
  221. package/dist/infrastructure/telemetry/outcome-limits.d.ts +12 -0
  222. package/dist/infrastructure/telemetry/outcome-limits.d.ts.map +1 -0
  223. package/dist/infrastructure/telemetry/outcome-limits.js +28 -0
  224. package/dist/infrastructure/telemetry/outcome-limits.js.map +1 -0
  225. package/dist/infrastructure/telemetry/outcome-recorder.d.ts +29 -0
  226. package/dist/infrastructure/telemetry/outcome-recorder.d.ts.map +1 -0
  227. package/dist/infrastructure/telemetry/outcome-recorder.js +49 -0
  228. package/dist/infrastructure/telemetry/outcome-recorder.js.map +1 -0
  229. package/dist/infrastructure/telemetry/routing-telemetry.d.ts +115 -0
  230. package/dist/infrastructure/telemetry/routing-telemetry.d.ts.map +1 -0
  231. package/dist/infrastructure/telemetry/routing-telemetry.js +529 -0
  232. package/dist/infrastructure/telemetry/routing-telemetry.js.map +1 -0
  233. package/dist/infrastructure/telemetry/telemetry-limits.d.ts +16 -0
  234. package/dist/infrastructure/telemetry/telemetry-limits.d.ts.map +1 -0
  235. package/dist/infrastructure/telemetry/telemetry-limits.js +35 -0
  236. package/dist/infrastructure/telemetry/telemetry-limits.js.map +1 -0
  237. package/package.json +110 -0
  238. package/skills/router-backlog-orchestrator/SKILL.md +183 -0
  239. package/skills/router-backlog-orchestrator/references/github-router-issue-template.md +78 -0
  240. package/skills/router-backlog-orchestrator/references/packet-from-issue.md +99 -0
  241. package/skills/router-backlog-orchestrator/references/prioritization-rubric.md +65 -0
  242. package/skills/router-backlog-orchestrator/scripts/collect-backlog.sh +44 -0
  243. package/specs/001-build-smart-router/contracts/telemetry-contrib.schema.json +151 -0
  244. package/src/api/explain/.gitkeep +0 -0
  245. package/src/api/explain/router-explain.ts +146 -0
  246. package/src/api/middleware/.gitkeep +0 -0
  247. package/src/api/middleware/pi-router-middleware.ts +169 -0
  248. package/src/cli/smart-router-cli.ts +436 -0
  249. package/src/config/.gitkeep +0 -0
  250. package/src/config/defaults.ts +35 -0
  251. package/src/config/models-loader.ts +68 -0
  252. package/src/config/pi-model-mapper.ts +285 -0
  253. package/src/config/routing-clusters-loader.ts +148 -0
  254. package/src/domain/delegation/delegation-context.ts +111 -0
  255. package/src/domain/delegation/execution-ledger.ts +34 -0
  256. package/src/domain/delegation/output-headroom.ts +131 -0
  257. package/src/domain/matching/.gitkeep +0 -0
  258. package/src/domain/matching/cluster-matcher.ts +474 -0
  259. package/src/domain/matching/embedding-provider.ts +79 -0
  260. package/src/domain/matching/hydra-input.ts +53 -0
  261. package/src/domain/matching/hydra-matcher.ts +454 -0
  262. package/src/domain/pinning/.gitkeep +0 -0
  263. package/src/domain/pinning/cache-economics.ts +128 -0
  264. package/src/domain/pinning/loop-escalation.ts +181 -0
  265. package/src/domain/pinning/session-pinner.ts +388 -0
  266. package/src/domain/pinning/sub-route-policy.ts +119 -0
  267. package/src/domain/pipeline/.gitkeep +0 -0
  268. package/src/domain/pipeline/router-pipeline.ts +1139 -0
  269. package/src/domain/pipeline/safe-default.ts +70 -0
  270. package/src/domain/refactor-guardrails.ts +202 -0
  271. package/src/domain/routing/context-fit.ts +221 -0
  272. package/src/domain/routing/expected-cost.ts +320 -0
  273. package/src/domain/routing/p-success-classifier.ts +511 -0
  274. package/src/domain/routing/tier-features.ts +290 -0
  275. package/src/domain/routing/tool-history-guard.ts +159 -0
  276. package/src/domain/scoring/.gitkeep +0 -0
  277. package/src/domain/scoring/multi-objective.ts +175 -0
  278. package/src/domain/triage/.gitkeep +0 -0
  279. package/src/domain/triage/triage-engine.ts +373 -0
  280. package/src/domain/triage/turn-envelope.ts +104 -0
  281. package/src/domain/types/.gitkeep +0 -0
  282. package/src/domain/types/entities.ts +384 -0
  283. package/src/domain/types/index.ts +41 -0
  284. package/src/domain/types/schemas.ts +289 -0
  285. package/src/domain/types/store-port.ts +59 -0
  286. package/src/index.ts +103 -0
  287. package/src/infra/gemini-provider.ts +142 -0
  288. package/src/infra/telemetry.ts +169 -0
  289. package/src/infrastructure/delegation/provider-error.ts +251 -0
  290. package/src/infrastructure/gateway/.gitkeep +0 -0
  291. package/src/infrastructure/gateway/circuit-breaker.ts +196 -0
  292. package/src/infrastructure/gateway/gateway-dispatch.ts +444 -0
  293. package/src/infrastructure/hardware/.gitkeep +0 -0
  294. package/src/infrastructure/hardware/hardware-probe.ts +276 -0
  295. package/src/infrastructure/local/.gitkeep +0 -0
  296. package/src/infrastructure/local/local-zero-tier.ts +151 -0
  297. package/src/infrastructure/persistence/.gitkeep +0 -0
  298. package/src/infrastructure/persistence/memory-store.ts +122 -0
  299. package/src/infrastructure/persistence/sqlite-store.ts +900 -0
  300. package/src/infrastructure/pricing/.gitkeep +0 -0
  301. package/src/infrastructure/pricing/litellm-fetch.ts +215 -0
  302. package/src/infrastructure/pricing/price-broker.ts +183 -0
  303. package/src/infrastructure/pricing/pricing-monitor.ts +65 -0
  304. package/src/infrastructure/telemetry/.gitkeep +0 -0
  305. package/src/infrastructure/telemetry/dataset-limits.ts +39 -0
  306. package/src/infrastructure/telemetry/dataset-recorder.ts +215 -0
  307. package/src/infrastructure/telemetry/outcome-limits.ts +42 -0
  308. package/src/infrastructure/telemetry/outcome-recorder.ts +118 -0
  309. package/src/infrastructure/telemetry/routing-telemetry.ts +824 -0
  310. package/src/infrastructure/telemetry/telemetry-limits.ts +50 -0
@@ -0,0 +1,529 @@
1
+ /**
2
+ * Routing telemetry emitter — T039.
3
+ *
4
+ * Maintains an append-only rolling window of routing decisions for
5
+ * observability and audit. Window bounds: 168 hours (7 days), max 1111 entries.
6
+ */
7
+ import { CONTEXT_FIT_EXCEEDED, CONTEXT_OVERFLOW_FRONTIER_FALLBACK, CONTEXT_OVERFLOW_NO_FIT, CONTEXT_OVERFLOW_SAME_PROVIDER_FALLBACK, modelFitsContext, resolveSafetyMargin, } from '../../domain/routing/context-fit.js';
8
+ import { CLUSTER_REASON_CODE_PREFIX } from '../../config/routing-clusters-loader.js';
9
+ import { resolveFrugalityCostPer1M } from '../pricing/price-broker.js';
10
+ import { TELEMETRY_MAX_ENTRIES, TELEMETRY_WINDOW_MS, evictExpiredTelemetryEntries, makeTelemetryRoom, } from './telemetry-limits.js';
11
+ export const CONTEXT_FIT_PASS = 'context_fit_pass';
12
+ export const CONTEXT_FIT_REJECTED_ALL = 'context_fit_rejected_all';
13
+ export const CONTEXT_OVERFLOW_PIN_BREAK = 'context_overflow_pin_break';
14
+ export const LOW_INTENSITY_STRUCTURAL = 'low_intensity_structural';
15
+ export const HIGH_INTENSITY_STRUCTURAL = 'high_intensity_structural';
16
+ export const P_SUCCESS_CHEAP = 'p_success_cheap';
17
+ export const P_SUCCESS_UNCERTAIN = 'p_success_uncertain';
18
+ const EXPECTED_COST_PREFIX = 'expected_cost_';
19
+ const EXPECTED_COST_DEFER_CODES = new Set([
20
+ 'expected_cost_price_delta_insufficient',
21
+ 'expected_cost_no_viable_tier',
22
+ ]);
23
+ const OVERFLOW_REASON_CODES = new Set([
24
+ CONTEXT_OVERFLOW_SAME_PROVIDER_FALLBACK,
25
+ CONTEXT_OVERFLOW_FRONTIER_FALLBACK,
26
+ CONTEXT_OVERFLOW_NO_FIT,
27
+ ]);
28
+ /**
29
+ * Estimate per-request routing cost in USD from resolved model pricing (SP-085).
30
+ * Uses estimated_input_tokens when present, otherwise prompt_text length as a token proxy.
31
+ */
32
+ export function estimateRoutingCost(model, request, catalog) {
33
+ const tokens = request.estimated_input_tokens ?? request.prompt_text.length;
34
+ const costPer1M = resolveFrugalityCostPer1M(model, catalog);
35
+ return (tokens / 1_000_000) * costPer1M;
36
+ }
37
+ export { DEFAULT_HISTORY_LIMIT, MAX_HISTORY_LIMIT, TELEMETRY_MAX_ENTRIES, TELEMETRY_WINDOW_HOURS, TELEMETRY_WINDOW_MS, } from './telemetry-limits.js';
38
+ function resolveEstimatedInputTokens(request) {
39
+ return request.estimated_input_tokens ?? request.prompt_text.length;
40
+ }
41
+ function extractContextFitRejected(decision) {
42
+ const candidates = decision.features?.candidates ?? decision.candidates ?? [];
43
+ return candidates.filter((candidate) => candidate.rejected_reason === CONTEXT_FIT_EXCEEDED);
44
+ }
45
+ function lookupMaxInputTokens(fleet, modelId) {
46
+ const profile = fleet?.find((model) => model.id === modelId);
47
+ return profile?.limits?.max_input_tokens ?? null;
48
+ }
49
+ function serializeContextFitRejected(rejected, fleet) {
50
+ if (rejected.length === 0) {
51
+ return null;
52
+ }
53
+ const entries = rejected.map((candidate) => ({
54
+ model_id: candidate.model_id,
55
+ max_input_tokens: lookupMaxInputTokens(fleet, candidate.model_id),
56
+ reason: candidate.rejected_reason ?? CONTEXT_FIT_EXCEEDED,
57
+ }));
58
+ return JSON.stringify(entries);
59
+ }
60
+ function countViableModels(fleet, estimatedInputTokens, safetyMargin) {
61
+ let count = 0;
62
+ for (const model of fleet) {
63
+ if (modelFitsContext(model, estimatedInputTokens, safetyMargin)) {
64
+ count += 1;
65
+ }
66
+ }
67
+ return count;
68
+ }
69
+ function resolveContextOverflowPinBreak(decision) {
70
+ if (decision.pin_reason === 'context_overflow') {
71
+ return true;
72
+ }
73
+ return OVERFLOW_REASON_CODES.has(decision.reason_code);
74
+ }
75
+ function resolveContextFitReasonCode(decision, rejectedCount, viableCount, gateRan) {
76
+ if (!gateRan) {
77
+ return null;
78
+ }
79
+ if (decision.pin_reason === 'context_overflow') {
80
+ return CONTEXT_OVERFLOW_PIN_BREAK;
81
+ }
82
+ if (OVERFLOW_REASON_CODES.has(decision.reason_code)) {
83
+ return decision.reason_code;
84
+ }
85
+ if (decision.reason_code === CONTEXT_OVERFLOW_PIN_BREAK) {
86
+ return CONTEXT_OVERFLOW_PIN_BREAK;
87
+ }
88
+ if (viableCount === 0 ||
89
+ decision.reason_code === CONTEXT_OVERFLOW_NO_FIT ||
90
+ (rejectedCount > 0 && decision.selected_model_id === 'unknown')) {
91
+ return CONTEXT_FIT_REJECTED_ALL;
92
+ }
93
+ if (rejectedCount > 0 || viableCount !== null) {
94
+ return CONTEXT_FIT_PASS;
95
+ }
96
+ return CONTEXT_FIT_PASS;
97
+ }
98
+ function gateSkipped(request) {
99
+ return request.force_model_id !== undefined;
100
+ }
101
+ function gateRan(request, decision) {
102
+ if (gateSkipped(request)) {
103
+ return false;
104
+ }
105
+ const rejected = extractContextFitRejected(decision);
106
+ if (rejected.length > 0) {
107
+ return true;
108
+ }
109
+ if (request.estimated_input_tokens !== undefined) {
110
+ return true;
111
+ }
112
+ if (OVERFLOW_REASON_CODES.has(decision.reason_code)) {
113
+ return true;
114
+ }
115
+ if (decision.pin_reason === 'context_overflow') {
116
+ return true;
117
+ }
118
+ return decision.features?.context_fit !== undefined;
119
+ }
120
+ /** Build privacy-safe context-fit observability from a routing decision (SP-110). */
121
+ export function buildContextFitObservability(input) {
122
+ const { request, decision, fleet, contextFitConfig } = input;
123
+ if (decision.features?.context_fit) {
124
+ return decision.features.context_fit;
125
+ }
126
+ if (gateSkipped(request)) {
127
+ return null;
128
+ }
129
+ const ran = gateRan(request, decision);
130
+ if (!ran) {
131
+ return null;
132
+ }
133
+ const rejected = extractContextFitRejected(decision);
134
+ const estimatedInputTokens = resolveEstimatedInputTokens(request);
135
+ const safetyMargin = resolveSafetyMargin(contextFitConfig);
136
+ const viableCount = fleet !== undefined ? countViableModels(fleet, estimatedInputTokens, safetyMargin) : null;
137
+ return {
138
+ estimated_input_tokens: estimatedInputTokens,
139
+ context_fit_viable_count: viableCount,
140
+ context_fit_rejected_json: serializeContextFitRejected(rejected, fleet),
141
+ context_overflow_pin_break: resolveContextOverflowPinBreak(decision),
142
+ selected_model_max_input_tokens: lookupMaxInputTokens(fleet, decision.selected_model_id),
143
+ context_fit_reason_code: resolveContextFitReasonCode(decision, rejected.length, viableCount, ran),
144
+ };
145
+ }
146
+ function parseClusterIdFromReasonCode(reasonCode) {
147
+ if (reasonCode === null || reasonCode === undefined || !reasonCode.startsWith(CLUSTER_REASON_CODE_PREFIX)) {
148
+ return null;
149
+ }
150
+ return reasonCode.slice(CLUSTER_REASON_CODE_PREFIX.length);
151
+ }
152
+ /** Normalize tier-selection reason codes for telemetry and explain (SP-113). */
153
+ export function resolveTierSelectionReasonCode(features) {
154
+ if (!features) {
155
+ return null;
156
+ }
157
+ const reasonCode = features.tier_hint_reason_code;
158
+ if (reasonCode === null || reasonCode === undefined) {
159
+ if (features.p_success_cheap !== null && features.tier_hint === null) {
160
+ return P_SUCCESS_UNCERTAIN;
161
+ }
162
+ return null;
163
+ }
164
+ if (reasonCode.startsWith(CLUSTER_REASON_CODE_PREFIX) ||
165
+ reasonCode === LOW_INTENSITY_STRUCTURAL ||
166
+ reasonCode === HIGH_INTENSITY_STRUCTURAL) {
167
+ return reasonCode;
168
+ }
169
+ if (reasonCode.startsWith(EXPECTED_COST_PREFIX)) {
170
+ if (EXPECTED_COST_DEFER_CODES.has(reasonCode) || features.tier_hint === null) {
171
+ return P_SUCCESS_UNCERTAIN;
172
+ }
173
+ if (features.tier_hint === 'economical-cloud' || features.tier_hint === 'zero-tier') {
174
+ return P_SUCCESS_CHEAP;
175
+ }
176
+ }
177
+ return reasonCode;
178
+ }
179
+ function extractRejectedTiers(candidates) {
180
+ if (!candidates || candidates.length === 0) {
181
+ return [];
182
+ }
183
+ const rejected = [];
184
+ for (const candidate of candidates) {
185
+ if (!candidate.model_id.startsWith('__expected_cost_')) {
186
+ continue;
187
+ }
188
+ const tier = candidate.model_id
189
+ .replace('__expected_cost_', '')
190
+ .replace(/__$/, '');
191
+ rejected.push({
192
+ tier,
193
+ expected_cost_usd: candidate.score,
194
+ adjusted_expected_cost_usd: candidate.shortfall,
195
+ reason: candidate.rejected_reason ?? '',
196
+ });
197
+ }
198
+ return rejected;
199
+ }
200
+ function buildTierFeatureSummary(features) {
201
+ return {
202
+ triage_verdict: features.triage?.verdict ?? null,
203
+ triage_reason_code: features.triage?.reason_code ?? null,
204
+ cyclomatic_score: features.triage?.cyclomatic_score ?? null,
205
+ requirement_reasoning: features.requirements?.reasoning ?? null,
206
+ requirement_code_gen: features.requirements?.code_gen ?? null,
207
+ requirement_tool_use: features.requirements?.tool_use ?? null,
208
+ };
209
+ }
210
+ function buildLowIntensityBreakdown(features) {
211
+ return {
212
+ score: features.low_intensity_score,
213
+ tier_hint: features.tier_hint,
214
+ tier_hint_reason_code: features.tier_hint_reason_code,
215
+ tier_selection_reason_code: resolveTierSelectionReasonCode(features),
216
+ p_success_cheap: features.p_success_cheap,
217
+ p_success_alpha: features.p_success_alpha,
218
+ rejected_tiers: extractRejectedTiers(features.candidates),
219
+ };
220
+ }
221
+ /** Infer why local_zero did not dispatch when another stage won (SP-113). */
222
+ export function buildLocalZeroSkipReasons(decision, features) {
223
+ if (decision.stage === 'local_zero') {
224
+ return [];
225
+ }
226
+ const reasons = [];
227
+ if (!features?.local_eligible_reason) {
228
+ reasons.push('not_locally_eligible');
229
+ }
230
+ const rejectedJson = features?.context_fit?.context_fit_rejected_json;
231
+ if (rejectedJson !== null && rejectedJson !== undefined && rejectedJson.includes('zero-tier')) {
232
+ reasons.push('context_fit_excluded_local');
233
+ }
234
+ if (features?.local_eligible_reason) {
235
+ if (decision.pin_reason !== null) {
236
+ reasons.push('session_pin_active');
237
+ }
238
+ else {
239
+ reasons.push('hardware_or_local_unavailable');
240
+ }
241
+ }
242
+ return reasons;
243
+ }
244
+ function resolveClusterScalars(features, clusterMatchTable) {
245
+ const selected = clusterMatchTable?.find((entry) => entry.selected) ??
246
+ clusterMatchTable?.[0] ??
247
+ null;
248
+ if (selected) {
249
+ return {
250
+ cluster_id: selected.cluster_id,
251
+ cluster_similarity: selected.similarity,
252
+ cluster_margin: selected.margin,
253
+ };
254
+ }
255
+ const clusterId = parseClusterIdFromReasonCode(features?.tier_hint_reason_code) ??
256
+ parseClusterIdFromReasonCode(features?.local_eligible_reason);
257
+ return {
258
+ cluster_id: clusterId,
259
+ cluster_similarity: null,
260
+ cluster_margin: null,
261
+ };
262
+ }
263
+ /** Build privacy-safe tier/cluster observability from routing decision features (SP-113). */
264
+ export function buildTierSelectionObservability(input) {
265
+ const { decision, clusterMatchTable = null } = input;
266
+ const features = decision.features;
267
+ if (!features) {
268
+ return null;
269
+ }
270
+ const tierGateRan = features.low_intensity_score !== null ||
271
+ features.tier_hint !== null ||
272
+ features.tier_hint_reason_code !== null ||
273
+ features.p_success_cheap !== null;
274
+ if (!tierGateRan) {
275
+ return null;
276
+ }
277
+ const clusterScalars = resolveClusterScalars(features, clusterMatchTable);
278
+ return {
279
+ ...clusterScalars,
280
+ low_intensity_score: features.low_intensity_score,
281
+ tier_hint: features.tier_hint,
282
+ p_success_cheap: features.p_success_cheap,
283
+ local_eligible_reason: features.local_eligible_reason,
284
+ tier_selection_reason_code: resolveTierSelectionReasonCode(features),
285
+ cluster_match_table: clusterMatchTable,
286
+ tier_feature_summary: buildTierFeatureSummary(features),
287
+ low_intensity_breakdown: buildLowIntensityBreakdown(features),
288
+ local_zero_skip_reasons: buildLocalZeroSkipReasons(decision, features),
289
+ };
290
+ }
291
+ function emptyFeatureSidecar() {
292
+ return {
293
+ triage: null,
294
+ requirements: null,
295
+ candidates: null,
296
+ tier_hint: null,
297
+ tier_hint_reason_code: null,
298
+ low_intensity_score: null,
299
+ p_success_cheap: null,
300
+ p_success_alpha: null,
301
+ local_eligible_reason: null,
302
+ };
303
+ }
304
+ /** Attach tier-selection observability to a routing decision features sidecar (SP-113). */
305
+ export function enrichRoutingDecisionWithTierSelection(decision, clusterMatchTable) {
306
+ const tierSelection = buildTierSelectionObservability({
307
+ decision,
308
+ clusterMatchTable: clusterMatchTable ?? null,
309
+ });
310
+ if (!tierSelection) {
311
+ return decision;
312
+ }
313
+ return {
314
+ ...decision,
315
+ features: {
316
+ ...(decision.features ?? emptyFeatureSidecar()),
317
+ tier_selection: tierSelection,
318
+ },
319
+ };
320
+ }
321
+ /** Attach context-fit and tier-selection observability for explain responses (SP-110, SP-113). */
322
+ export async function enrichRoutingDecisionForExplain(request, decision, options) {
323
+ const withContextFit = enrichRoutingDecisionWithContextFit(request, decision, options?.fleet, options?.contextFitConfig);
324
+ let clusterMatchTable = null;
325
+ if (options?.clusterMatcher) {
326
+ try {
327
+ clusterMatchTable = await options.clusterMatcher.matchTable(request);
328
+ }
329
+ catch {
330
+ clusterMatchTable = null;
331
+ }
332
+ }
333
+ return enrichRoutingDecisionWithTierSelection(withContextFit, clusterMatchTable);
334
+ }
335
+ /** Attach context-fit observability to a routing decision features sidecar (SP-110). */
336
+ export function enrichRoutingDecisionWithContextFit(request, decision, fleet, contextFitConfig) {
337
+ const contextFit = buildContextFitObservability({
338
+ request,
339
+ decision,
340
+ fleet,
341
+ ...(contextFitConfig !== undefined ? { contextFitConfig } : {}),
342
+ });
343
+ if (!contextFit) {
344
+ return decision;
345
+ }
346
+ return {
347
+ ...decision,
348
+ features: {
349
+ ...(decision.features ?? emptyFeatureSidecar()),
350
+ context_fit: contextFit,
351
+ },
352
+ };
353
+ }
354
+ /** JSON payload for SMART_ROUTER_LOG_ROUTING=1 stderr lines (SP-110). */
355
+ export function buildRoutingDecisionLogPayload(request, decision, delegate, fleet, contextFitConfig) {
356
+ const enriched = enrichRoutingDecisionWithTierSelection(enrichRoutingDecisionWithContextFit(request, decision, fleet, contextFitConfig));
357
+ const tierSelection = enriched.features?.tier_selection;
358
+ return {
359
+ request_id: enriched.request_id,
360
+ selected_model_id: enriched.selected_model_id,
361
+ tier: enriched.tier,
362
+ stage: enriched.stage,
363
+ reason_code: enriched.reason_code,
364
+ routing_latency_ms: enriched.routing_latency_ms,
365
+ features: enriched.features ?? null,
366
+ cluster_summary: tierSelection
367
+ ? {
368
+ cluster_id: tierSelection.cluster_id,
369
+ cluster_similarity: tierSelection.cluster_similarity,
370
+ cluster_margin: tierSelection.cluster_margin,
371
+ tier_hint: tierSelection.tier_hint,
372
+ tier_selection_reason_code: tierSelection.tier_selection_reason_code,
373
+ low_intensity_score: tierSelection.low_intensity_score,
374
+ p_success_cheap: tierSelection.p_success_cheap,
375
+ }
376
+ : null,
377
+ delegate,
378
+ };
379
+ }
380
+ function defaultContextFitTelemetry() {
381
+ return {
382
+ estimated_input_tokens: null,
383
+ context_fit_viable_count: null,
384
+ context_fit_rejected_json: null,
385
+ context_overflow_pin_break: false,
386
+ selected_model_max_input_tokens: null,
387
+ context_fit_reason_code: null,
388
+ };
389
+ }
390
+ /** Default context-fit telemetry scalars for tests and legacy store reads. */
391
+ export const DEFAULT_CONTEXT_FIT_TELEMETRY_FIELDS = defaultContextFitTelemetry();
392
+ function defaultTierSelectionTelemetry() {
393
+ return {
394
+ cluster_id: null,
395
+ cluster_similarity: null,
396
+ cluster_margin: null,
397
+ low_intensity_score: null,
398
+ tier_hint: null,
399
+ p_success_cheap: null,
400
+ local_eligible_reason: null,
401
+ tier_selection_reason_code: null,
402
+ };
403
+ }
404
+ /** Default tier-selection telemetry scalars for tests and legacy store reads. */
405
+ export const DEFAULT_TIER_SELECTION_TELEMETRY_FIELDS = defaultTierSelectionTelemetry();
406
+ function tierSelectionTelemetryFromDecision(decision) {
407
+ const observability = buildTierSelectionObservability({ decision });
408
+ if (!observability) {
409
+ return defaultTierSelectionTelemetry();
410
+ }
411
+ return {
412
+ cluster_id: observability.cluster_id,
413
+ cluster_similarity: observability.cluster_similarity,
414
+ cluster_margin: observability.cluster_margin,
415
+ low_intensity_score: observability.low_intensity_score,
416
+ tier_hint: observability.tier_hint,
417
+ p_success_cheap: observability.p_success_cheap,
418
+ local_eligible_reason: observability.local_eligible_reason,
419
+ tier_selection_reason_code: observability.tier_selection_reason_code,
420
+ };
421
+ }
422
+ /** Default context-fit dataset scalars for tests and legacy store reads. */
423
+ export const DEFAULT_CONTEXT_FIT_DATASET_FIELDS = {
424
+ estimated_input_tokens_gate: null,
425
+ context_fit_viable_count: null,
426
+ context_fit_rejected_json: null,
427
+ context_overflow_pin_break: false,
428
+ selected_model_max_input_tokens: null,
429
+ context_fit_reason_code: null,
430
+ };
431
+ /** Default tier-selection dataset scalars for tests and legacy store reads. */
432
+ export const DEFAULT_TIER_SELECTION_DATASET_FIELDS = {
433
+ cluster_id: null,
434
+ cluster_similarity: null,
435
+ cluster_margin: null,
436
+ low_intensity_score: null,
437
+ tier_hint: null,
438
+ p_success_cheap: null,
439
+ local_eligible_reason: null,
440
+ tier_selection_reason_code: null,
441
+ };
442
+ // ─── Emitter ─────────────────────────────────────────────────────────────────
443
+ export class RoutingTelemetryEmitter {
444
+ entries = [];
445
+ maxEntries;
446
+ windowMs;
447
+ clock;
448
+ onRecord;
449
+ fleet;
450
+ contextFitConfig;
451
+ constructor(options) {
452
+ this.maxEntries = options?.maxEntries ?? TELEMETRY_MAX_ENTRIES;
453
+ this.windowMs = options?.windowMs ?? TELEMETRY_WINDOW_MS;
454
+ this.clock = options?.clock ?? (() => new Date().toISOString());
455
+ this.onRecord = options?.onRecord;
456
+ this.fleet = options?.fleet;
457
+ this.contextFitConfig = options?.contextFitConfig;
458
+ }
459
+ /**
460
+ * Emit a telemetry record from a completed routing decision.
461
+ * Enforces the rolling window (time + count) before appending.
462
+ */
463
+ emit(request, decision) {
464
+ return this.appendRecord(request, decision);
465
+ }
466
+ /**
467
+ * Emit telemetry when a pipeline stage throws and routing degrades to safe default.
468
+ */
469
+ emitPipelineError(request, failedStage, fallback) {
470
+ const errorDecision = {
471
+ ...fallback,
472
+ stage: failedStage,
473
+ reason_code: 'pipeline_error',
474
+ };
475
+ return this.appendRecord(request, errorDecision);
476
+ }
477
+ appendRecord(request, decision) {
478
+ makeTelemetryRoom(this.entries, this.maxEntries);
479
+ const contextFit = buildContextFitObservability({
480
+ request,
481
+ decision,
482
+ ...(this.fleet !== undefined ? { fleet: this.fleet } : {}),
483
+ ...(this.contextFitConfig !== undefined
484
+ ? { contextFitConfig: this.contextFitConfig }
485
+ : {}),
486
+ });
487
+ const contextFitFields = contextFit ?? defaultContextFitTelemetry();
488
+ const tierSelectionFields = tierSelectionTelemetryFromDecision(decision);
489
+ const record = {
490
+ timestamp: this.clock(),
491
+ session_id: request.session_id,
492
+ request_id: decision.request_id,
493
+ turn_type: request.turn_type ?? 'unknown',
494
+ stage: decision.stage,
495
+ reason_code: decision.reason_code,
496
+ selected_model_id: decision.selected_model_id,
497
+ estimated_cost_usd: decision.estimated_cost_usd ?? 0,
498
+ routing_latency_ms: decision.routing_latency_ms,
499
+ pin_reason: decision.pin_reason,
500
+ estimated_input_tokens: contextFitFields.estimated_input_tokens,
501
+ context_fit_viable_count: contextFitFields.context_fit_viable_count,
502
+ context_fit_rejected_json: contextFitFields.context_fit_rejected_json,
503
+ context_overflow_pin_break: contextFitFields.context_overflow_pin_break,
504
+ selected_model_max_input_tokens: contextFitFields.selected_model_max_input_tokens,
505
+ context_fit_reason_code: contextFitFields.context_fit_reason_code,
506
+ cluster_id: tierSelectionFields.cluster_id,
507
+ cluster_similarity: tierSelectionFields.cluster_similarity,
508
+ cluster_margin: tierSelectionFields.cluster_margin,
509
+ low_intensity_score: tierSelectionFields.low_intensity_score,
510
+ tier_hint: tierSelectionFields.tier_hint,
511
+ p_success_cheap: tierSelectionFields.p_success_cheap,
512
+ local_eligible_reason: tierSelectionFields.local_eligible_reason,
513
+ tier_selection_reason_code: tierSelectionFields.tier_selection_reason_code,
514
+ };
515
+ this.entries.push(record);
516
+ this.onRecord?.(record);
517
+ return record;
518
+ }
519
+ /** Current number of retained entries. */
520
+ get size() {
521
+ return this.entries.length;
522
+ }
523
+ /** Snapshot of all retained entries (newest last). */
524
+ snapshot() {
525
+ evictExpiredTelemetryEntries(this.entries, this.windowMs);
526
+ return [...this.entries];
527
+ }
528
+ }
529
+ //# sourceMappingURL=routing-telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing-telemetry.js","sourceRoot":"","sources":["../../../src/infrastructure/telemetry/routing-telemetry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Shared retention bounds for routing telemetry (in-memory and SQLite).
3
+ */
4
+ import type { RoutingTelemetry } from '../../domain/types/index.js';
5
+ export declare const TELEMETRY_WINDOW_HOURS = 168;
6
+ export declare const TELEMETRY_WINDOW_MS: number;
7
+ export declare const TELEMETRY_MAX_ENTRIES = 1111;
8
+ export declare const DEFAULT_HISTORY_LIMIT = 10;
9
+ export declare const MAX_HISTORY_LIMIT = 100;
10
+ /** Remove entries older than the rolling window. */
11
+ export declare function evictExpiredTelemetryEntries(entries: RoutingTelemetry[], windowMs?: number): void;
12
+ /** Trim oldest entries until count is at most maxEntries. */
13
+ export declare function trimTelemetryEntriesToMax(entries: RoutingTelemetry[], maxEntries?: number): void;
14
+ /** Make room for one more entry before append. */
15
+ export declare function makeTelemetryRoom(entries: RoutingTelemetry[], maxEntries?: number): void;
16
+ //# sourceMappingURL=telemetry-limits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry-limits.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/telemetry/telemetry-limits.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAEpE,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAC1C,eAAO,MAAM,mBAAmB,QAA0C,CAAC;AAC3E,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAE1C,eAAO,MAAM,qBAAqB,KAAK,CAAC;AACxC,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAErC,oDAAoD;AACpD,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,gBAAgB,EAAE,EAC3B,QAAQ,GAAE,MAA4B,GACrC,IAAI,CAWN;AAED,6DAA6D;AAC7D,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,gBAAgB,EAAE,EAC3B,UAAU,GAAE,MAA8B,GACzC,IAAI,CAIN;AAED,kDAAkD;AAClD,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,gBAAgB,EAAE,EAC3B,UAAU,GAAE,MAA8B,GACzC,IAAI,CAKN"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Shared retention bounds for routing telemetry (in-memory and SQLite).
3
+ */
4
+ export const TELEMETRY_WINDOW_HOURS = 168;
5
+ export const TELEMETRY_WINDOW_MS = TELEMETRY_WINDOW_HOURS * 60 * 60 * 1000;
6
+ export const TELEMETRY_MAX_ENTRIES = 1111;
7
+ export const DEFAULT_HISTORY_LIMIT = 10;
8
+ export const MAX_HISTORY_LIMIT = 100;
9
+ /** Remove entries older than the rolling window. */
10
+ export function evictExpiredTelemetryEntries(entries, windowMs = TELEMETRY_WINDOW_MS) {
11
+ const cutoff = Date.now() - windowMs;
12
+ while (entries.length > 0) {
13
+ const oldest = entries[0];
14
+ if (new Date(oldest.timestamp).getTime() < cutoff) {
15
+ entries.shift();
16
+ }
17
+ else {
18
+ break;
19
+ }
20
+ }
21
+ }
22
+ /** Trim oldest entries until count is at most maxEntries. */
23
+ export function trimTelemetryEntriesToMax(entries, maxEntries = TELEMETRY_MAX_ENTRIES) {
24
+ while (entries.length > maxEntries) {
25
+ entries.shift();
26
+ }
27
+ }
28
+ /** Make room for one more entry before append. */
29
+ export function makeTelemetryRoom(entries, maxEntries = TELEMETRY_MAX_ENTRIES) {
30
+ evictExpiredTelemetryEntries(entries);
31
+ while (entries.length >= maxEntries) {
32
+ entries.shift();
33
+ }
34
+ }
35
+ //# sourceMappingURL=telemetry-limits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry-limits.js","sourceRoot":"","sources":["../../../src/infrastructure/telemetry/telemetry-limits.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAC1C,MAAM,CAAC,MAAM,mBAAmB,GAAG,sBAAsB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAC3E,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAE1C,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC;AACxC,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAErC,oDAAoD;AACpD,MAAM,UAAU,4BAA4B,CAC1C,OAA2B,EAC3B,WAAmB,mBAAmB;IAEtC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC;IAErC,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAE,CAAC;QAC3B,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,MAAM,EAAE,CAAC;YAClD,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,MAAM;QACR,CAAC;IACH,CAAC;AACH,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,yBAAyB,CACvC,OAA2B,EAC3B,aAAqB,qBAAqB;IAE1C,OAAO,OAAO,CAAC,MAAM,GAAG,UAAU,EAAE,CAAC;QACnC,OAAO,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;AACH,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,iBAAiB,CAC/B,OAA2B,EAC3B,aAAqB,qBAAqB;IAE1C,4BAA4B,CAAC,OAAO,CAAC,CAAC;IACtC,OAAO,OAAO,CAAC,MAAM,IAAI,UAAU,EAAE,CAAC;QACpC,OAAO,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;AACH,CAAC"}