@mupt-ai/dari-gateway 0.2.0 → 0.2.1

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 (366) hide show
  1. package/dist/bun.d.ts +2 -0
  2. package/dist/bun.js +4 -0
  3. package/dist/context/eval_catalog.d.ts +3 -0
  4. package/dist/context/eval_catalog.js +7 -0
  5. package/dist/context/interaction_fingerprint.d.ts +27 -0
  6. package/dist/context/interaction_fingerprint.js +519 -0
  7. package/dist/context/interaction_fingerprint_format.d.ts +42 -0
  8. package/dist/context/interaction_fingerprint_format.js +113 -0
  9. package/dist/context/interaction_lease_depth.d.ts +2 -0
  10. package/dist/context/interaction_lease_depth.js +110 -0
  11. package/dist/context/lease_history.d.ts +7 -0
  12. package/dist/context/lease_history.js +158 -0
  13. package/dist/context/pricing.d.ts +4 -0
  14. package/dist/context/pricing.js +23 -0
  15. package/dist/context/provider_prompt_accounting.d.ts +14 -0
  16. package/dist/context/provider_prompt_accounting.js +187 -0
  17. package/dist/context/routing_context.d.ts +40 -0
  18. package/dist/context/routing_context.js +211 -0
  19. package/dist/http/auth.d.ts +2 -0
  20. package/dist/http/auth.js +35 -0
  21. package/dist/http/errors.d.ts +19 -0
  22. package/dist/http/errors.js +89 -0
  23. package/dist/http/handler.d.ts +12 -0
  24. package/dist/http/handler.js +81 -0
  25. package/dist/http/http2_server.d.ts +6 -0
  26. package/dist/http/http2_server.js +103 -0
  27. package/dist/http/serve.d.ts +20 -0
  28. package/dist/http/serve.js +78 -0
  29. package/dist/index.d.ts +6 -0
  30. package/dist/index.js +8 -0
  31. package/dist/ingress/anthropic_messages.d.ts +3 -0
  32. package/dist/ingress/anthropic_messages.js +122 -0
  33. package/dist/ingress/anthropic_models.d.ts +1 -0
  34. package/dist/ingress/anthropic_models.js +23 -0
  35. package/dist/ingress/chat_completions.d.ts +2 -0
  36. package/dist/ingress/chat_completions.js +37 -0
  37. package/dist/ingress/claude_code/request_context.d.ts +2 -0
  38. package/dist/ingress/claude_code/request_context.js +31 -0
  39. package/dist/ingress/codex.d.ts +3 -0
  40. package/dist/ingress/codex.js +65 -0
  41. package/dist/ingress/codex_models.d.ts +2 -0
  42. package/dist/ingress/codex_models.js +89 -0
  43. package/dist/ingress/json.d.ts +1 -0
  44. package/dist/ingress/json.js +95 -0
  45. package/dist/ingress/models.d.ts +1 -0
  46. package/dist/ingress/models.js +53 -0
  47. package/dist/interaction/capabilities.d.ts +3 -0
  48. package/dist/interaction/capabilities.js +24 -0
  49. package/dist/interaction/image.d.ts +4 -0
  50. package/dist/interaction/image.js +13 -0
  51. package/dist/interaction/portable_reasoning_state.d.ts +4 -0
  52. package/dist/interaction/portable_reasoning_state.js +18 -0
  53. package/dist/interaction/provider_continuation_state.d.ts +6 -0
  54. package/dist/interaction/provider_continuation_state.js +27 -0
  55. package/dist/interaction/tool_identity.d.ts +10 -0
  56. package/dist/interaction/tool_identity.js +41 -0
  57. package/dist/interaction/types.d.ts +203 -0
  58. package/dist/interaction/types.js +5 -0
  59. package/dist/models/context_limits.d.ts +2 -0
  60. package/dist/models/context_limits.js +7 -0
  61. package/dist/models/execution_provider.d.ts +8 -0
  62. package/dist/models/execution_provider.js +13 -0
  63. package/dist/models/gateways.d.ts +11 -0
  64. package/dist/models/gateways.js +45 -0
  65. package/dist/models/ids.d.ts +1 -0
  66. package/dist/models/ids.js +15 -0
  67. package/dist/models/provider_defaults.d.ts +4 -0
  68. package/dist/models/provider_defaults.js +41 -0
  69. package/dist/models/runtime_overrides.d.ts +4 -0
  70. package/dist/models/runtime_overrides.js +209 -0
  71. package/dist/observability/errors.d.ts +8 -0
  72. package/dist/observability/errors.js +11 -0
  73. package/dist/platform/platform.d.ts +152 -0
  74. package/dist/platform/platform.js +11 -0
  75. package/dist/platform/routing_contract.d.ts +2 -0
  76. package/dist/platform/routing_contract.js +5 -0
  77. package/dist/protocol/input/anthropic_messages.d.ts +2 -0
  78. package/dist/protocol/input/anthropic_messages.js +494 -0
  79. package/dist/protocol/input/chat_completions.d.ts +4 -0
  80. package/dist/protocol/input/chat_completions.js +212 -0
  81. package/dist/protocol/input/chat_completions_validation.d.ts +2 -0
  82. package/dist/protocol/input/chat_completions_validation.js +257 -0
  83. package/dist/protocol/input/openai_responses.d.ts +2 -0
  84. package/dist/protocol/input/openai_responses.js +666 -0
  85. package/dist/protocol/input/router_model.d.ts +7 -0
  86. package/dist/protocol/input/router_model.js +43 -0
  87. package/dist/protocol/output/anthropic_messages.d.ts +10 -0
  88. package/dist/protocol/output/anthropic_messages.js +15 -0
  89. package/dist/protocol/output/anthropic_messages_output.d.ts +10 -0
  90. package/dist/protocol/output/anthropic_messages_output.js +124 -0
  91. package/dist/protocol/output/anthropic_messages_stream.d.ts +16 -0
  92. package/dist/protocol/output/anthropic_messages_stream.js +267 -0
  93. package/dist/protocol/output/chat_completions.d.ts +29 -0
  94. package/dist/protocol/output/chat_completions.js +406 -0
  95. package/dist/protocol/output/chat_reasoning_detail.d.ts +2 -0
  96. package/dist/protocol/output/chat_reasoning_detail.js +13 -0
  97. package/dist/protocol/output/delivered_stream_snapshot.d.ts +10 -0
  98. package/dist/protocol/output/delivered_stream_snapshot.js +31 -0
  99. package/dist/protocol/output/openai_responses.d.ts +10 -0
  100. package/dist/protocol/output/openai_responses.js +14 -0
  101. package/dist/protocol/output/openai_responses_output.d.ts +14 -0
  102. package/dist/protocol/output/openai_responses_output.js +125 -0
  103. package/dist/protocol/output/openai_responses_stream.d.ts +18 -0
  104. package/dist/protocol/output/openai_responses_stream.js +546 -0
  105. package/dist/protocol/output/sse_stream.d.ts +31 -0
  106. package/dist/protocol/output/sse_stream.js +67 -0
  107. package/dist/providers/anthropic_safeguards.d.ts +11 -0
  108. package/dist/providers/anthropic_safeguards.js +81 -0
  109. package/dist/providers/aws_assume_role.d.ts +17 -0
  110. package/dist/providers/aws_assume_role.js +107 -0
  111. package/dist/providers/cancel_estimate.d.ts +43 -0
  112. package/dist/providers/cancel_estimate.js +89 -0
  113. package/dist/providers/execution.d.ts +72 -0
  114. package/dist/providers/execution.js +491 -0
  115. package/dist/providers/model_capabilities.d.ts +11 -0
  116. package/dist/providers/model_capabilities.js +29 -0
  117. package/dist/providers/pi.d.ts +65 -0
  118. package/dist/providers/pi.js +319 -0
  119. package/dist/providers/pi_context.d.ts +7 -0
  120. package/dist/providers/pi_context.js +405 -0
  121. package/dist/providers/pi_options.d.ts +11 -0
  122. package/dist/providers/pi_options.js +398 -0
  123. package/dist/providers/pi_output.d.ts +2 -0
  124. package/dist/providers/pi_output.js +453 -0
  125. package/dist/providers/provider_attempt_runner.d.ts +55 -0
  126. package/dist/providers/provider_attempt_runner.js +90 -0
  127. package/dist/providers/provider_call.d.ts +77 -0
  128. package/dist/providers/provider_call.js +292 -0
  129. package/dist/providers/provider_reported_cost.d.ts +10 -0
  130. package/dist/providers/provider_reported_cost.js +123 -0
  131. package/dist/providers/reasoning.d.ts +12 -0
  132. package/dist/providers/reasoning.js +30 -0
  133. package/dist/providers/response_capture.d.ts +23 -0
  134. package/dist/providers/response_capture.js +47 -0
  135. package/dist/providers/stream_finalization.d.ts +46 -0
  136. package/dist/providers/stream_finalization.js +165 -0
  137. package/dist/providers/subscription_limits.d.ts +31 -0
  138. package/dist/providers/subscription_limits.js +163 -0
  139. package/dist/providers/subscription_usage.d.ts +10 -0
  140. package/dist/providers/subscription_usage.js +79 -0
  141. package/dist/runtime/claude_code/auxiliary_routing.d.ts +3 -0
  142. package/dist/runtime/claude_code/auxiliary_routing.js +60 -0
  143. package/dist/runtime/customer_disconnect.d.ts +20 -0
  144. package/dist/runtime/customer_disconnect.js +49 -0
  145. package/dist/runtime/explicit_model.d.ts +4 -0
  146. package/dist/runtime/explicit_model.js +53 -0
  147. package/dist/runtime/harness_identity/conversation.d.ts +33 -0
  148. package/dist/runtime/harness_identity/conversation.js +39 -0
  149. package/dist/runtime/harness_identity/extract.d.ts +8 -0
  150. package/dist/runtime/harness_identity/extract.js +214 -0
  151. package/dist/runtime/harness_identity/index.d.ts +2 -0
  152. package/dist/runtime/harness_identity/index.js +2 -0
  153. package/dist/runtime/prepare_routed_completion.d.ts +33 -0
  154. package/dist/runtime/prepare_routed_completion.js +167 -0
  155. package/dist/runtime/provider_stream_lifecycle.d.ts +31 -0
  156. package/dist/runtime/provider_stream_lifecycle.js +88 -0
  157. package/dist/runtime/provider_stream_outcome.d.ts +23 -0
  158. package/dist/runtime/provider_stream_outcome.js +55 -0
  159. package/dist/runtime/request_tags.d.ts +7 -0
  160. package/dist/runtime/request_tags.js +33 -0
  161. package/dist/runtime/routed_completion.d.ts +17 -0
  162. package/dist/runtime/routed_completion.js +80 -0
  163. package/dist/runtime/routed_protocol.d.ts +30 -0
  164. package/dist/runtime/routed_protocol.js +1 -0
  165. package/dist/runtime/routed_runtime.d.ts +40 -0
  166. package/dist/runtime/routed_runtime.js +535 -0
  167. package/dist/runtime/routing_lease.d.ts +26 -0
  168. package/dist/runtime/routing_lease.js +210 -0
  169. package/dist/runtime/runtime_reporter.d.ts +71 -0
  170. package/dist/runtime/runtime_reporter.js +35 -0
  171. package/dist/self_host/config.d.ts +46 -0
  172. package/dist/self_host/config.js +105 -0
  173. package/dist/self_host/main.d.ts +16 -0
  174. package/dist/self_host/main.js +95 -0
  175. package/dist/self_host/platform.d.ts +13 -0
  176. package/dist/self_host/platform.js +50 -0
  177. package/dist/self_host/prefix_store.d.ts +46 -0
  178. package/dist/self_host/prefix_store.js +261 -0
  179. package/dist/self_host/resolve.d.ts +28 -0
  180. package/dist/self_host/resolve.js +171 -0
  181. package/dist/self_host/subscriptions/access.d.ts +10 -0
  182. package/dist/self_host/subscriptions/access.js +37 -0
  183. package/dist/self_host/subscriptions/http.d.ts +15 -0
  184. package/dist/self_host/subscriptions/http.js +187 -0
  185. package/dist/self_host/subscriptions/index.d.ts +24 -0
  186. package/dist/self_host/subscriptions/index.js +24 -0
  187. package/dist/self_host/subscriptions/oauth.d.ts +55 -0
  188. package/dist/self_host/subscriptions/oauth.js +281 -0
  189. package/dist/self_host/subscriptions/store.d.ts +78 -0
  190. package/dist/self_host/subscriptions/store.js +235 -0
  191. package/dist/strategies/auto_routing_selector.d.ts +12 -0
  192. package/dist/strategies/auto_routing_selector.js +61 -0
  193. package/dist/strategies/eval_relevance.d.ts +17 -0
  194. package/dist/strategies/eval_relevance.js +32 -0
  195. package/dist/strategies/fallback_decision.d.ts +8 -0
  196. package/dist/strategies/fallback_decision.js +17 -0
  197. package/dist/strategies/priority_selector.d.ts +7 -0
  198. package/dist/strategies/priority_selector.js +37 -0
  199. package/dist/strategies/route_decision.d.ts +22 -0
  200. package/dist/strategies/route_decision.js +65 -0
  201. package/dist/strategies/routing.d.ts +74 -0
  202. package/dist/strategies/routing.js +280 -0
  203. package/dist/strategies/selector_projection.d.ts +15 -0
  204. package/dist/strategies/selector_projection.js +161 -0
  205. package/dist/telemetry/background.d.ts +7 -0
  206. package/dist/telemetry/background.js +33 -0
  207. package/dist/telemetry/benchmark_replay.d.ts +37 -0
  208. package/dist/telemetry/benchmark_replay.js +108 -0
  209. package/dist/telemetry/billing_finalization.d.ts +64 -0
  210. package/dist/telemetry/billing_finalization.js +96 -0
  211. package/dist/telemetry/ingest_values.d.ts +4 -0
  212. package/dist/telemetry/ingest_values.js +12 -0
  213. package/dist/telemetry/model_cost.d.ts +3 -0
  214. package/dist/telemetry/model_cost.js +15 -0
  215. package/dist/telemetry/prefix_state.d.ts +47 -0
  216. package/dist/telemetry/prefix_state.js +116 -0
  217. package/dist/telemetry/report.d.ts +88 -0
  218. package/dist/telemetry/report.js +621 -0
  219. package/dist/telemetry/requests/interaction_observability.d.ts +45 -0
  220. package/dist/telemetry/requests/interaction_observability.js +180 -0
  221. package/dist/telemetry/requests/retained_interaction_request.d.ts +8 -0
  222. package/dist/telemetry/requests/retained_interaction_request.js +10 -0
  223. package/dist/telemetry/scrub.d.ts +2 -0
  224. package/dist/telemetry/scrub.js +31 -0
  225. package/dist/telemetry/skills/claude/catalog.d.ts +6 -0
  226. package/dist/telemetry/skills/claude/catalog.js +99 -0
  227. package/dist/telemetry/skills/claude/file_reads.d.ts +4 -0
  228. package/dist/telemetry/skills/claude/file_reads.js +110 -0
  229. package/dist/telemetry/skills/claude/observations.d.ts +3 -0
  230. package/dist/telemetry/skills/claude/observations.js +366 -0
  231. package/dist/telemetry/skills/codex/catalog.d.ts +11 -0
  232. package/dist/telemetry/skills/codex/catalog.js +138 -0
  233. package/dist/telemetry/skills/codex/exec_file_reads.d.ts +9 -0
  234. package/dist/telemetry/skills/codex/exec_file_reads.js +36 -0
  235. package/dist/telemetry/skills/codex/explicit.d.ts +3 -0
  236. package/dist/telemetry/skills/codex/explicit.js +90 -0
  237. package/dist/telemetry/skills/codex/file_reads.d.ts +4 -0
  238. package/dist/telemetry/skills/codex/file_reads.js +37 -0
  239. package/dist/telemetry/skills/codex/identity.d.ts +2 -0
  240. package/dist/telemetry/skills/codex/identity.js +20 -0
  241. package/dist/telemetry/skills/observations.d.ts +21 -0
  242. package/dist/telemetry/skills/observations.js +41 -0
  243. package/dist/telemetry/skills/paths.d.ts +11 -0
  244. package/dist/telemetry/skills/paths.js +61 -0
  245. package/dist/telemetry/skills/pi.d.ts +6 -0
  246. package/dist/telemetry/skills/pi.js +223 -0
  247. package/dist/telemetry/skills/shell_file_reads.d.ts +7 -0
  248. package/dist/telemetry/skills/shell_file_reads.js +226 -0
  249. package/dist/telemetry/skills/shell_words.d.ts +13 -0
  250. package/dist/telemetry/skills/shell_words.js +189 -0
  251. package/dist/telemetry/tools/input.d.ts +2 -0
  252. package/dist/telemetry/tools/input.js +14 -0
  253. package/dist/telemetry/tools/observations.d.ts +29 -0
  254. package/dist/telemetry/tools/observations.js +247 -0
  255. package/dist/telemetry/usage.d.ts +57 -0
  256. package/dist/telemetry/usage.js +136 -0
  257. package/dist/types.d.ts +94 -0
  258. package/dist/types.js +1 -0
  259. package/package.json +21 -6
  260. package/src/bun.ts +2 -2
  261. package/src/context/eval_catalog.ts +1 -1
  262. package/src/context/interaction_fingerprint.ts +9 -9
  263. package/src/context/interaction_fingerprint_format.ts +1 -1
  264. package/src/context/interaction_lease_depth.ts +1 -1
  265. package/src/context/pricing.ts +1 -1
  266. package/src/context/provider_prompt_accounting.ts +5 -5
  267. package/src/context/routing_context.ts +16 -16
  268. package/src/http/auth.ts +1 -1
  269. package/src/http/handler.ts +8 -8
  270. package/src/http/serve.ts +3 -3
  271. package/src/index.ts +6 -6
  272. package/src/ingress/anthropic_messages.ts +12 -12
  273. package/src/ingress/anthropic_models.ts +1 -1
  274. package/src/ingress/chat_completions.ts +9 -9
  275. package/src/ingress/claude_code/request_context.ts +2 -2
  276. package/src/ingress/codex.ts +10 -10
  277. package/src/ingress/codex_models.ts +4 -4
  278. package/src/ingress/json.ts +1 -1
  279. package/src/ingress/models.ts +9 -9
  280. package/src/interaction/capabilities.ts +1 -1
  281. package/src/interaction/portable_reasoning_state.ts +1 -1
  282. package/src/interaction/provider_continuation_state.ts +1 -1
  283. package/src/interaction/tool_identity.ts +2 -2
  284. package/src/models/context_limits.ts +1 -1
  285. package/src/models/execution_provider.ts +1 -1
  286. package/src/models/ids.ts +1 -1
  287. package/src/models/provider_defaults.ts +1 -1
  288. package/src/models/runtime_overrides.ts +1 -1
  289. package/src/observability/errors.ts +2 -2
  290. package/src/platform/platform.ts +4 -4
  291. package/src/protocol/input/anthropic_messages.ts +7 -7
  292. package/src/protocol/input/chat_completions.ts +5 -5
  293. package/src/protocol/input/chat_completions_validation.ts +4 -4
  294. package/src/protocol/input/openai_responses.ts +6 -6
  295. package/src/protocol/output/anthropic_messages.ts +3 -3
  296. package/src/protocol/output/anthropic_messages_output.ts +6 -4
  297. package/src/protocol/output/anthropic_messages_stream.ts +7 -7
  298. package/src/protocol/output/chat_completions.ts +13 -13
  299. package/src/protocol/output/chat_reasoning_detail.ts +1 -1
  300. package/src/protocol/output/openai_responses.ts +3 -3
  301. package/src/protocol/output/openai_responses_output.ts +4 -2
  302. package/src/protocol/output/openai_responses_stream.ts +6 -6
  303. package/src/protocol/output/sse_stream.ts +3 -3
  304. package/src/providers/anthropic_safeguards.ts +2 -2
  305. package/src/providers/aws_assume_role.ts +2 -2
  306. package/src/providers/cancel_estimate.ts +1 -1
  307. package/src/providers/execution.ts +17 -17
  308. package/src/providers/pi.ts +14 -14
  309. package/src/providers/pi_context.ts +6 -6
  310. package/src/providers/pi_options.ts +10 -10
  311. package/src/providers/pi_output.ts +5 -5
  312. package/src/providers/provider_attempt_runner.ts +1 -1
  313. package/src/providers/provider_call.ts +14 -14
  314. package/src/providers/provider_reported_cost.ts +3 -3
  315. package/src/providers/reasoning.ts +2 -2
  316. package/src/providers/stream_finalization.ts +9 -9
  317. package/src/providers/subscription_limits.ts +3 -3
  318. package/src/runtime/claude_code/auxiliary_routing.ts +5 -5
  319. package/src/runtime/customer_disconnect.ts +1 -1
  320. package/src/runtime/explicit_model.ts +4 -4
  321. package/src/runtime/harness_identity/conversation.ts +1 -1
  322. package/src/runtime/harness_identity/extract.ts +3 -3
  323. package/src/runtime/harness_identity/index.ts +2 -2
  324. package/src/runtime/prepare_routed_completion.ts +13 -13
  325. package/src/runtime/provider_stream_lifecycle.ts +1 -1
  326. package/src/runtime/provider_stream_outcome.ts +2 -2
  327. package/src/runtime/request_tags.ts +2 -2
  328. package/src/runtime/routed_completion.ts +11 -11
  329. package/src/runtime/routed_protocol.ts +2 -2
  330. package/src/runtime/routed_runtime.ts +20 -19
  331. package/src/runtime/routing_lease.ts +7 -7
  332. package/src/runtime/runtime_reporter.ts +3 -3
  333. package/src/self_host/main.ts +12 -12
  334. package/src/self_host/platform.ts +5 -5
  335. package/src/self_host/prefix_store.ts +2 -2
  336. package/src/self_host/resolve.ts +6 -6
  337. package/src/self_host/subscriptions/access.ts +2 -2
  338. package/src/self_host/subscriptions/http.ts +2 -2
  339. package/src/self_host/subscriptions/index.ts +4 -4
  340. package/src/self_host/subscriptions/store.ts +1 -1
  341. package/src/strategies/auto_routing_selector.ts +2 -2
  342. package/src/strategies/eval_relevance.ts +3 -3
  343. package/src/strategies/priority_selector.ts +1 -1
  344. package/src/strategies/route_decision.ts +7 -7
  345. package/src/strategies/routing.ts +10 -10
  346. package/src/strategies/selector_projection.ts +2 -2
  347. package/src/telemetry/billing_finalization.ts +3 -3
  348. package/src/telemetry/model_cost.ts +1 -1
  349. package/src/telemetry/prefix_state.ts +4 -4
  350. package/src/telemetry/report.ts +21 -21
  351. package/src/telemetry/requests/interaction_observability.ts +1 -1
  352. package/src/telemetry/requests/retained_interaction_request.ts +1 -1
  353. package/src/telemetry/skills/claude/catalog.ts +1 -1
  354. package/src/telemetry/skills/claude/file_reads.ts +6 -6
  355. package/src/telemetry/skills/claude/observations.ts +3 -3
  356. package/src/telemetry/skills/codex/catalog.ts +3 -3
  357. package/src/telemetry/skills/codex/exec_file_reads.ts +4 -4
  358. package/src/telemetry/skills/codex/explicit.ts +3 -3
  359. package/src/telemetry/skills/codex/file_reads.ts +5 -5
  360. package/src/telemetry/skills/observations.ts +7 -7
  361. package/src/telemetry/skills/pi.ts +3 -3
  362. package/src/telemetry/skills/shell_file_reads.ts +2 -2
  363. package/src/telemetry/skills/shell_words.ts +1 -1
  364. package/src/telemetry/tools/input.ts +1 -1
  365. package/src/telemetry/tools/observations.ts +9 -9
  366. package/src/telemetry/usage.ts +5 -5
package/dist/bun.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { installShutdownHandlers, startServer } from "./http/serve.js";
2
+ export { startSelfHostedGateway } from "./self_host/main.js";
package/dist/bun.js ADDED
@@ -0,0 +1,4 @@
1
+ // Bun-only entry points: the Bun.serve HTTP server and the self-hosted
2
+ // gateway, whose state lives in bun:sqlite.
3
+ export { installShutdownHandlers, startServer } from "./http/serve.js";
4
+ export { startSelfHostedGateway } from "./self_host/main.js";
@@ -0,0 +1,3 @@
1
+ import type { PublicEvalCatalogCard } from "../types.js";
2
+ import type { RouterEval } from "@mupt-ai/dari-router/policy-engine";
3
+ export declare function publicCatalogSelectorEvals(catalog: PublicEvalCatalogCard[] | null | undefined): RouterEval[];
@@ -0,0 +1,7 @@
1
+ // Convert public cards into hidden ratio-calibration inputs. Cards without a
2
+ // sync timestamp or scores carry no signal and are dropped.
3
+ export function publicCatalogSelectorEvals(catalog) {
4
+ if (!catalog)
5
+ return [];
6
+ return catalog.filter((card) => card.updated_at !== null && card.scores.length > 0);
7
+ }
@@ -0,0 +1,27 @@
1
+ import type { InteractionOutput, InteractionRequest, ProviderIdentity } from "../interaction/types.js";
2
+ export type InteractionPrefixContext = {
3
+ chainByModel: ReadonlyMap<string, string[]>;
4
+ itemIndexByHashByModel: ReadonlyMap<string, ReadonlyMap<string, number>>;
5
+ looseChain: string[];
6
+ fingerprints: {
7
+ tool_choice_fp: string;
8
+ response_format_fp: string;
9
+ };
10
+ };
11
+ /**
12
+ * Hash variants sent during router resolution. The portable chain covers
13
+ * providers that receive readable history only. Exact continuation-source
14
+ * variants cover a return to the originating model. Because provider APIs
15
+ * are unknown before resolution, Responses tool history also contributes a
16
+ * composite call/item-ID variant for OpenAI-compatible Responses targets.
17
+ */
18
+ export declare function interactionPrefixLookupHashes(routerId: string, request: InteractionRequest): string[];
19
+ export declare function interactionLooseChain(routerId: string, request: InteractionRequest): string[];
20
+ export declare function interactionConversationPrefix(request: InteractionRequest): string;
21
+ export declare function interactionPrefixContext(routerId: string, request: InteractionRequest, targets: ReadonlyMap<string, ProviderIdentity>): InteractionPrefixContext;
22
+ export declare function interactionPrefixChain(routerId: string, request: InteractionRequest, target: ProviderIdentity | null): string[];
23
+ export declare function extendInteractionChain(lastHash: string, output: InteractionOutput, target: ProviderIdentity, policy: {
24
+ includeItemIds: boolean;
25
+ sourceProtocol: InteractionRequest["sourceProtocol"];
26
+ }): string[];
27
+ export declare function extendInteractionLooseChain(lastHash: string, output: InteractionOutput, sourceProtocol: InteractionRequest["sourceProtocol"]): string[];
@@ -0,0 +1,519 @@
1
+ import { createHash } from "node:crypto";
2
+ import { stableStringify } from "@mupt-ai/dari-router/policy-engine";
3
+ import { anthropicMessagesToInteraction } from "../protocol/input/anthropic_messages.js";
4
+ import { internalChatCompletionsToInteraction } from "../protocol/input/chat_completions.js";
5
+ import { anthropicContent } from "../protocol/output/anthropic_messages_output.js";
6
+ import { assistantMessagePayload } from "../protocol/output/chat_completions.js";
7
+ import { compatibleProviderContinuation } from "../interaction/provider_continuation_state.js";
8
+ import { providerToolCallId, toolWireName } from "../interaction/tool_identity.js";
9
+ import { ROUTING_PREFIX_HASHES_MAX_COUNT } from "../platform/routing_contract.js";
10
+ import { appendFingerprintContentText, canonicalInteractionFingerprintStep, interactionFingerprintContent, interactionFingerprintHeadHash, interactionOptionsFingerprints, normalizedAssistantFingerprintContent, } from "./interaction_fingerprint_format.js";
11
+ const MAX_CONTINUATION_TARGETS = 16;
12
+ // The loose tier ignores reasoning and item ids, so provider identity and
13
+ // tool-call-id composition cannot influence it: one chain per request.
14
+ const LOOSE_POLICY = {
15
+ includeItemIds: false,
16
+ includePhase: false,
17
+ canonicalizeFunctionArguments: true,
18
+ loose: true,
19
+ };
20
+ // Salts the loose chain's seed so the two hash tiers can never collide in
21
+ // the shared prefix-entry lookup space.
22
+ const LOOSE_SEED_SALT = "fp-loose-1";
23
+ const CONVERSATION_PREFIX_VERSION = "conversation-prefix-v1";
24
+ /**
25
+ * Hash variants sent during router resolution. The portable chain covers
26
+ * providers that receive readable history only. Exact continuation-source
27
+ * variants cover a return to the originating model. Because provider APIs
28
+ * are unknown before resolution, Responses tool history also contributes a
29
+ * composite call/item-ID variant for OpenAI-compatible Responses targets.
30
+ */
31
+ export function interactionPrefixLookupHashes(routerId, request) {
32
+ const targets = [null];
33
+ const seen = new Set();
34
+ for (let index = request.items.length - 1; index >= 0 && seen.size < MAX_CONTINUATION_TARGETS; index -= 1) {
35
+ const item = request.items[index];
36
+ if (item.type !== "reasoning" || !item.continuation)
37
+ continue;
38
+ const key = identityKey(item.continuation.source);
39
+ if (seen.has(key))
40
+ continue;
41
+ seen.add(key);
42
+ targets.push(item.continuation.source);
43
+ }
44
+ const chains = targets.map((target) => interactionPrefixChain(routerId, request, target));
45
+ if (request.sourceProtocol === "openai_responses") {
46
+ chains.push(interactionPrefixChainFor(routerId, request, null, "openai-responses"));
47
+ }
48
+ chains.push(interactionLooseChain(routerId, request));
49
+ return deepestDistinctHashes(chains, ROUTING_PREFIX_HASHES_MAX_COUNT);
50
+ }
51
+ // The loose (client-durable) chain: what the conversation looks like once
52
+ // reasoning payloads, item ids, and provider-specific canonicalization are
53
+ // stripped. Distinct seed keeps its hashes disjoint from the strict tier.
54
+ export function interactionLooseChain(routerId, request) {
55
+ return fingerprintChain(sha256(`${interactionFingerprintHeadHash(routerId, request)}\u0000${LOOSE_SEED_SALT}`), looseFingerprintSteps(request.sourceProtocol, request.items));
56
+ }
57
+ // Stable logical-conversation discriminator. This deliberately excludes the
58
+ // cache head (instructions and tools) and hashes only the first normalized
59
+ // transcript step. Growing history and tool changes preserve identity, while
60
+ // unrelated work reusing the same harness session gets a new group.
61
+ export function interactionConversationPrefix(request) {
62
+ const firstStep = conversationFingerprintSteps(looseFingerprintSteps(request.sourceProtocol, request.items)).at(0);
63
+ return sha256(stableStringify({
64
+ version: CONVERSATION_PREFIX_VERSION,
65
+ firstStep: firstStep === undefined
66
+ ? null
67
+ : canonicalInteractionFingerprintStep(firstStep),
68
+ }));
69
+ }
70
+ export function interactionPrefixContext(routerId, request, targets) {
71
+ const chainByModel = new Map();
72
+ const itemIndexByHashByModel = new Map();
73
+ for (const [model, target] of targets) {
74
+ const steps = interactionPrefixStepsFor(routerId, request, target, target.api);
75
+ chainByModel.set(model, steps.map((step) => step.hash));
76
+ itemIndexByHashByModel.set(model, new Map(steps.map((step) => [step.hash, step.itemIndex])));
77
+ }
78
+ return {
79
+ chainByModel,
80
+ itemIndexByHashByModel,
81
+ looseChain: interactionLooseChain(routerId, request),
82
+ fingerprints: interactionOptionsFingerprints(request),
83
+ };
84
+ }
85
+ // Loose fingerprints share the strict grouping logic so step boundaries
86
+ // stay identical whether or not the client echoed reasoning; the policy just
87
+ // drops the volatile fields. Target-independent by construction.
88
+ function looseFingerprintSteps(sourceProtocol, items) {
89
+ return sourceProtocol === "openai_chat"
90
+ ? fingerprintChatInputSteps(items, null, null, LOOSE_POLICY)
91
+ : fingerprintSteps(items, null, null, LOOSE_POLICY);
92
+ }
93
+ export function interactionPrefixChain(routerId, request, target) {
94
+ return interactionPrefixStepsFor(routerId, request, target, target?.api ?? null)
95
+ .map((step) => step.hash);
96
+ }
97
+ function interactionPrefixChainFor(routerId, request, target, toolCallApi) {
98
+ return interactionPrefixStepsFor(routerId, request, target, toolCallApi)
99
+ .map((step) => step.hash);
100
+ }
101
+ function interactionPrefixStepsFor(routerId, request, target, toolCallApi) {
102
+ let hash = interactionFingerprintHeadHash(routerId, request);
103
+ const steps = [];
104
+ const responses = request.sourceProtocol === "openai_responses";
105
+ const fingerprintStepsForRequest = conversationFingerprintSteps(request.sourceProtocol === "openai_chat"
106
+ ? fingerprintChatInputSteps(request.items, target, toolCallApi)
107
+ : fingerprintSteps(request.items, target, toolCallApi, {
108
+ includeItemIds: true,
109
+ includePhase: responses,
110
+ canonicalizeFunctionArguments: responses,
111
+ }));
112
+ for (const step of fingerprintStepsForRequest) {
113
+ hash = extendFingerprintHash(hash, step);
114
+ steps.push({ hash, itemIndex: step.itemIndex });
115
+ }
116
+ return steps;
117
+ }
118
+ export function extendInteractionChain(lastHash, output, target, policy) {
119
+ let hash = lastHash;
120
+ const extension = [];
121
+ const steps = fingerprintClientEchoSteps(output, target, policy);
122
+ for (const step of steps) {
123
+ if (step.actor === "system" || step.actor === "developer")
124
+ continue;
125
+ hash = extendFingerprintHash(hash, step);
126
+ extension.push(hash);
127
+ }
128
+ return extension;
129
+ }
130
+ function fingerprintClientEchoSteps(output, target, policy) {
131
+ const items = clientEchoItems(output, policy.sourceProtocol);
132
+ if (policy.sourceProtocol === "openai_chat") {
133
+ return fingerprintChatInputSteps(items, target, target.api);
134
+ }
135
+ return fingerprintSteps(items, target, target.api, {
136
+ includeItemIds: policy.includeItemIds,
137
+ includePhase: policy.sourceProtocol === "openai_responses",
138
+ canonicalizeFunctionArguments: true,
139
+ });
140
+ }
141
+ // Prefix extensions must match the assistant output as the next client request
142
+ // will carry it, not necessarily the provider's canonical output items.
143
+ function clientEchoItems(output, sourceProtocol) {
144
+ if (sourceProtocol === "openai_chat") {
145
+ return internalChatCompletionsToInteraction({
146
+ model: "dari/routing",
147
+ messages: [assistantMessagePayload(output)],
148
+ }).items;
149
+ }
150
+ if (sourceProtocol === "anthropic_messages") {
151
+ return anthropicMessagesToInteraction({
152
+ model: "dari/routing",
153
+ max_tokens: 1,
154
+ messages: [{ role: "assistant", content: anthropicContent(output) }],
155
+ }).items;
156
+ }
157
+ return output.items;
158
+ }
159
+ // Loose-tier extension for the reply, mirroring interactionLooseChain's
160
+ // policy: what the next request's loose chain computes at this depth no
161
+ // matter which volatile fields the client's echo keeps.
162
+ export function extendInteractionLooseChain(lastHash, output, sourceProtocol) {
163
+ let hash = lastHash;
164
+ const extension = [];
165
+ const items = clientEchoItems(output, sourceProtocol);
166
+ for (const step of looseFingerprintSteps(sourceProtocol, items)) {
167
+ if (step.actor === "system" || step.actor === "developer")
168
+ continue;
169
+ hash = extendFingerprintHash(hash, step);
170
+ extension.push(hash);
171
+ }
172
+ return extension;
173
+ }
174
+ // Chat carries reasoning, assistant text, and tool calls in one assistant
175
+ // message. Its canonical interaction items intentionally separate those
176
+ // concerns, so prefix hashing must regroup one wire message before hashing.
177
+ function fingerprintChatInputSteps(items, target, toolCallApi, policy) {
178
+ const steps = [];
179
+ const toolCalls = new Map();
180
+ let pendingReasoning = [];
181
+ let pendingReasoningItemIndex = -1;
182
+ const flushReasoning = () => {
183
+ if (pendingReasoning.length === 0)
184
+ return;
185
+ steps.push({
186
+ actor: "assistant",
187
+ itemIndex: pendingReasoningItemIndex,
188
+ content: null,
189
+ calls: [],
190
+ resultCallId: null,
191
+ reasoning: pendingReasoning,
192
+ });
193
+ pendingReasoning = [];
194
+ pendingReasoningItemIndex = -1;
195
+ };
196
+ for (const [itemIndex, item] of items.entries()) {
197
+ if (item.type === "reasoning") {
198
+ if (policy?.loose)
199
+ continue;
200
+ pendingReasoning.push(reasoningFingerprint(item, target, false));
201
+ pendingReasoningItemIndex = itemIndex;
202
+ continue;
203
+ }
204
+ if (item.type === "message") {
205
+ if (item.role !== "assistant")
206
+ flushReasoning();
207
+ steps.push({
208
+ actor: item.role,
209
+ itemIndex,
210
+ content: item.role === "assistant"
211
+ ? normalizedAssistantFingerprintContent(item.content, item.contentShape)
212
+ : interactionFingerprintContent(item.content, item.contentShape),
213
+ calls: [],
214
+ resultCallId: null,
215
+ ...(item.role === "assistant" && pendingReasoning.length > 0
216
+ ? { reasoning: pendingReasoning }
217
+ : {}),
218
+ });
219
+ pendingReasoning = [];
220
+ pendingReasoningItemIndex = -1;
221
+ continue;
222
+ }
223
+ if (item.type === "reasoning_configuration") {
224
+ // Configuration updates change execution effort without becoming part
225
+ // of the conversational identity, just like request-level effort.
226
+ flushReasoning();
227
+ continue;
228
+ }
229
+ if (item.type === "tool_result") {
230
+ flushReasoning();
231
+ steps.push({
232
+ actor: "tool",
233
+ itemIndex,
234
+ content: interactionFingerprintContent(item.output, item.outputShape),
235
+ calls: [],
236
+ resultCallId: toolCalls.get(item.callId) ?? item.callId,
237
+ });
238
+ continue;
239
+ }
240
+ flushReasoning();
241
+ let assistant = steps.at(-1);
242
+ if (!assistant || assistant.actor !== "assistant") {
243
+ assistant = {
244
+ actor: "assistant",
245
+ content: null,
246
+ calls: [],
247
+ resultCallId: null,
248
+ itemIndex,
249
+ };
250
+ steps.push(assistant);
251
+ }
252
+ assistant.itemIndex = itemIndex;
253
+ if (item.type === "tool_call") {
254
+ const id = appendToolCall(assistant, item, toolCallApi, false, policy?.canonicalizeFunctionArguments ?? false);
255
+ toolCalls.set(item.callId, id);
256
+ }
257
+ else {
258
+ appendHostedToolCall(assistant, item);
259
+ }
260
+ }
261
+ flushReasoning();
262
+ return steps;
263
+ }
264
+ function fingerprintSteps(items, target, toolCallApi, policy) {
265
+ const steps = [];
266
+ const toolCalls = new Map();
267
+ for (const [itemIndex, item] of items.entries()) {
268
+ if (item.type === "reasoning") {
269
+ if (policy.loose)
270
+ continue;
271
+ const continuation = compatibleProviderContinuation(item.continuation, target);
272
+ const readable = continuationReadableText(item, continuation);
273
+ const itemFingerprint = reasoningFingerprint(item, target, policy.includeItemIds);
274
+ const previous = steps.at(-1);
275
+ if (previous?.actor === "assistant"
276
+ && (previous.calls.length > 0 || previous.reasoning?.length)) {
277
+ previous.itemIndex = itemIndex;
278
+ previous.content = appendFingerprintContentText(previous.content, readable);
279
+ previous.reasoning = [...(previous.reasoning ?? []), itemFingerprint];
280
+ continue;
281
+ }
282
+ steps.push({
283
+ actor: "assistant",
284
+ itemIndex,
285
+ content: readable || null,
286
+ calls: [],
287
+ resultCallId: null,
288
+ reasoning: [itemFingerprint],
289
+ });
290
+ continue;
291
+ }
292
+ if (item.type === "reasoning_configuration") {
293
+ continue;
294
+ }
295
+ if (item.type === "tool_result") {
296
+ steps.push({
297
+ actor: "tool",
298
+ itemIndex,
299
+ content: interactionFingerprintContent(item.output, item.outputShape),
300
+ calls: [],
301
+ resultCallId: toolCalls.get(item.callId) ?? item.callId,
302
+ });
303
+ continue;
304
+ }
305
+ if (item.type === "tool_call") {
306
+ let assistant = steps.at(-1);
307
+ if (!assistant || assistant.actor !== "assistant") {
308
+ assistant = {
309
+ actor: "assistant",
310
+ content: null,
311
+ calls: [],
312
+ resultCallId: null,
313
+ itemIndex,
314
+ };
315
+ steps.push(assistant);
316
+ }
317
+ assistant.itemIndex = itemIndex;
318
+ const id = appendToolCall(assistant, item, toolCallApi, policy.includeItemIds, policy.canonicalizeFunctionArguments);
319
+ toolCalls.set(item.callId, id);
320
+ continue;
321
+ }
322
+ if (item.type === "hosted_tool_call") {
323
+ let assistant = steps.at(-1);
324
+ if (!assistant || assistant.actor !== "assistant") {
325
+ assistant = {
326
+ actor: "assistant",
327
+ content: null,
328
+ calls: [],
329
+ resultCallId: null,
330
+ itemIndex,
331
+ };
332
+ steps.push(assistant);
333
+ }
334
+ assistant.itemIndex = itemIndex;
335
+ appendHostedToolCall(assistant, item);
336
+ continue;
337
+ }
338
+ steps.push({
339
+ actor: item.role,
340
+ itemIndex,
341
+ content: policy.loose && item.role === "assistant"
342
+ ? normalizedAssistantFingerprintContent(item.content, item.contentShape)
343
+ : interactionFingerprintContent(item.content, item.contentShape),
344
+ calls: [],
345
+ resultCallId: null,
346
+ ...(policy.includeItemIds && item.id ? { itemId: item.id } : {}),
347
+ ...(policy.includePhase && item.phase ? { phase: item.phase } : {}),
348
+ });
349
+ }
350
+ return steps;
351
+ }
352
+ function reasoningFingerprint(item, target, includeItemId) {
353
+ const continuation = compatibleProviderContinuation(item.continuation, target);
354
+ const readable = continuationReadableText(item, continuation);
355
+ return {
356
+ ...(includeItemId && item.id ? { itemId: item.id } : {}),
357
+ readableSha256: sha256(readable),
358
+ ...(continuation
359
+ ? { continuationStateSha256: sha256(stableStringify(continuation)) }
360
+ : {}),
361
+ };
362
+ }
363
+ function appendToolCall(assistant, item, toolCallApi, includeItemId, canonicalizeFunctionArguments) {
364
+ const id = providerToolCallId(item.callId, includeItemId ? item.id : undefined, toolCallApi);
365
+ assistant.calls = [
366
+ ...assistant.calls,
367
+ {
368
+ id,
369
+ kind: item.kind,
370
+ name: toolWireName(item.namespace, item.name),
371
+ input: toolArguments(item.kind, item.input, canonicalizeFunctionArguments),
372
+ },
373
+ ];
374
+ return id;
375
+ }
376
+ function appendHostedToolCall(assistant, item) {
377
+ const payload = {
378
+ ...item.payload,
379
+ type: item.providerType,
380
+ id: item.id,
381
+ };
382
+ if (item.status)
383
+ payload.status = item.status;
384
+ else
385
+ delete payload.status;
386
+ assistant.calls = [
387
+ ...assistant.calls,
388
+ {
389
+ id: item.id,
390
+ kind: "hosted",
391
+ name: item.tool,
392
+ input: payload,
393
+ },
394
+ ];
395
+ }
396
+ function continuationReadableText(item, continuation) {
397
+ if (continuation?.kind === "anthropic_thinking")
398
+ return normalizedReadable(continuation.thinking);
399
+ if (continuation?.kind === "anthropic_redacted_thinking")
400
+ return "";
401
+ return normalizedReadable([...item.summary, ...item.content].join("\n"));
402
+ }
403
+ // Streamed reasoning reaches clients as delta concatenations whose whitespace
404
+ // joins differ from the aggregated response body (part separators, trailing
405
+ // newlines), and the client echoes whichever form it saw. Whitespace therefore
406
+ // cannot participate in conversation identity.
407
+ function normalizedReadable(text) {
408
+ return text.replace(/\s+/g, " ").trim();
409
+ }
410
+ function fingerprintChain(seed, steps) {
411
+ let hash = seed;
412
+ return conversationFingerprintSteps(steps).map((step) => {
413
+ hash = extendFingerprintHash(hash, step);
414
+ return hash;
415
+ });
416
+ }
417
+ function conversationFingerprintSteps(steps) {
418
+ const positional = [];
419
+ let sawConversationStep = false;
420
+ for (const step of steps) {
421
+ if (step.actor !== "system" && step.actor !== "developer") {
422
+ sawConversationStep = true;
423
+ const previous = positional.at(-1);
424
+ if (step.actor === "user" && previous?.actor === "user") {
425
+ previous.content = appendPositionalFingerprintContent(previous.content, step.content);
426
+ previous.itemIndex = step.itemIndex;
427
+ }
428
+ else {
429
+ positional.push({ ...step });
430
+ }
431
+ continue;
432
+ }
433
+ if (!sawConversationStep)
434
+ continue;
435
+ const text = fingerprintReadableText(step.content);
436
+ if (!text)
437
+ continue;
438
+ const previous = positional.at(-1);
439
+ if (previous?.actor === "user" || previous?.actor === "tool") {
440
+ previous.content = appendPositionalFingerprintText(previous.content, text);
441
+ previous.itemIndex = step.itemIndex;
442
+ continue;
443
+ }
444
+ positional.push({
445
+ actor: "user",
446
+ content: [{ type: "text", text }],
447
+ calls: [],
448
+ resultCallId: null,
449
+ itemIndex: step.itemIndex,
450
+ });
451
+ }
452
+ return positional;
453
+ }
454
+ function fingerprintReadableText(content) {
455
+ if (typeof content === "string")
456
+ return content;
457
+ if (!Array.isArray(content))
458
+ return "";
459
+ return content.map((part) => part.type === "text" ? part.text : "(image omitted)").join("\n");
460
+ }
461
+ function appendPositionalFingerprintText(content, text) {
462
+ return appendPositionalFingerprintContent(content, [{ type: "text", text }]);
463
+ }
464
+ function appendPositionalFingerprintContent(content, appended) {
465
+ const contentParts = typeof content === "string"
466
+ ? [{ type: "text", text: content }]
467
+ : content ?? [];
468
+ const appendedParts = typeof appended === "string"
469
+ ? [{ type: "text", text: appended }]
470
+ : appended ?? [];
471
+ return [...contentParts, ...appendedParts];
472
+ }
473
+ function extendFingerprintHash(lastHash, step) {
474
+ return sha256(`${lastHash}\u0000${canonicalInteractionFingerprintStep(step)}`);
475
+ }
476
+ function toolArguments(kind, input, canonicalizeFunctionArguments) {
477
+ if (kind === "custom")
478
+ return JSON.stringify({ input: typeof input === "string" ? input : "" });
479
+ if (canonicalizeFunctionArguments && typeof input === "string") {
480
+ try {
481
+ const parsed = JSON.parse(input);
482
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed))
483
+ return parsed;
484
+ }
485
+ catch {
486
+ // Provider execution reports malformed function arguments separately;
487
+ // fingerprinting itself must remain best-effort.
488
+ }
489
+ }
490
+ return input;
491
+ }
492
+ function deepestDistinctHashes(chains, max) {
493
+ const result = [];
494
+ const seen = new Set();
495
+ for (let depth = 1; result.length < max; depth += 1) {
496
+ let found = false;
497
+ for (const chain of chains) {
498
+ const hash = chain.at(-depth);
499
+ if (!hash)
500
+ continue;
501
+ found = true;
502
+ if (!seen.has(hash)) {
503
+ seen.add(hash);
504
+ result.push(hash);
505
+ if (result.length === max)
506
+ break;
507
+ }
508
+ }
509
+ if (!found)
510
+ break;
511
+ }
512
+ return result;
513
+ }
514
+ function identityKey(identity) {
515
+ return `${identity.provider}\u0000${identity.api}\u0000${identity.model}`;
516
+ }
517
+ function sha256(text) {
518
+ return createHash("sha256").update(text, "utf8").digest("hex");
519
+ }
@@ -0,0 +1,42 @@
1
+ import type { InteractionContent, InteractionRequest } from "../interaction/types.js";
2
+ export type FingerprintContent = string | Array<{
3
+ type: "text";
4
+ text: string;
5
+ } | {
6
+ type: "image";
7
+ url: string;
8
+ detail?: "auto" | "low" | "high" | "original";
9
+ } | {
10
+ type: "tool_reference";
11
+ toolName: string;
12
+ }> | null;
13
+ export type FingerprintCall = {
14
+ id: string;
15
+ kind: "function" | "custom" | "hosted";
16
+ name: string;
17
+ input: unknown;
18
+ };
19
+ export type ReasoningFingerprint = {
20
+ itemId?: string;
21
+ readableSha256: string;
22
+ continuationStateSha256?: string;
23
+ };
24
+ export type InteractionFingerprintStep = {
25
+ actor: "system" | "developer" | "user" | "assistant" | "tool";
26
+ content: FingerprintContent;
27
+ calls: FingerprintCall[];
28
+ resultCallId: string | null;
29
+ itemIndex: number;
30
+ itemId?: string;
31
+ phase?: "commentary" | "final_answer";
32
+ reasoning?: ReasoningFingerprint[];
33
+ };
34
+ export declare function interactionFingerprintHeadHash(routerId: string, request: InteractionRequest): string;
35
+ export declare function interactionOptionsFingerprints(request: InteractionRequest): {
36
+ tool_choice_fp: string;
37
+ response_format_fp: string;
38
+ };
39
+ export declare function canonicalInteractionFingerprintStep(step: InteractionFingerprintStep): string;
40
+ export declare function interactionFingerprintContent(content: string | InteractionContent[] | null, shape: "string" | "parts" | "null" | "absent"): FingerprintContent;
41
+ export declare function normalizedAssistantFingerprintContent(content: string | InteractionContent[] | null, shape: "string" | "parts" | "null" | "absent"): FingerprintContent;
42
+ export declare function appendFingerprintContentText(content: FingerprintContent, text: string): FingerprintContent;