@caupulican/pi-adaptative 0.81.39 → 0.81.40

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 (667) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +2 -0
  3. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts +2 -0
  4. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts.map +1 -1
  5. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js +2 -0
  6. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js.map +1 -1
  7. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.ts +3 -0
  8. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts +9 -0
  9. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts.map +1 -1
  10. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js +290 -107
  11. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js.map +1 -1
  12. package/dist/bundled-resources/extensions/tmux-agent-manager/index.ts +357 -122
  13. package/dist/bundled-resources/skills/tool-call-repair/references/repair-catalogue.md +2 -2
  14. package/dist/cli/args.d.ts +2 -0
  15. package/dist/cli/args.d.ts.map +1 -1
  16. package/dist/cli/args.js +9 -0
  17. package/dist/cli/args.js.map +1 -1
  18. package/dist/core/agent-directory-layout.d.ts +15 -0
  19. package/dist/core/agent-directory-layout.d.ts.map +1 -0
  20. package/dist/core/agent-directory-layout.js +72 -0
  21. package/dist/core/agent-directory-layout.js.map +1 -0
  22. package/dist/core/agent-paths.d.ts +19 -2
  23. package/dist/core/agent-paths.d.ts.map +1 -1
  24. package/dist/core/agent-paths.js +67 -4
  25. package/dist/core/agent-paths.js.map +1 -1
  26. package/dist/core/agent-session-runtime.d.ts +52 -8
  27. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  28. package/dist/core/agent-session-runtime.js +397 -79
  29. package/dist/core/agent-session-runtime.js.map +1 -1
  30. package/dist/core/agent-session-services.d.ts +1 -0
  31. package/dist/core/agent-session-services.d.ts.map +1 -1
  32. package/dist/core/agent-session-services.js +1 -0
  33. package/dist/core/agent-session-services.js.map +1 -1
  34. package/dist/core/agent-session.d.ts +71 -136
  35. package/dist/core/agent-session.d.ts.map +1 -1
  36. package/dist/core/agent-session.js +477 -1318
  37. package/dist/core/agent-session.js.map +1 -1
  38. package/dist/core/autonomy/approval-gate.d.ts +3 -2
  39. package/dist/core/autonomy/approval-gate.d.ts.map +1 -1
  40. package/dist/core/autonomy/approval-gate.js +6 -28
  41. package/dist/core/autonomy/approval-gate.js.map +1 -1
  42. package/dist/core/autonomy/bounded-completion.d.ts +1 -1
  43. package/dist/core/autonomy/bounded-completion.d.ts.map +1 -1
  44. package/dist/core/autonomy/bounded-completion.js +1 -1
  45. package/dist/core/autonomy/bounded-completion.js.map +1 -1
  46. package/dist/core/autonomy/contracts.d.ts +20 -12
  47. package/dist/core/autonomy/contracts.d.ts.map +1 -1
  48. package/dist/core/autonomy/contracts.js.map +1 -1
  49. package/dist/core/autonomy/foreground-envelope.d.ts +8 -2
  50. package/dist/core/autonomy/foreground-envelope.d.ts.map +1 -1
  51. package/dist/core/autonomy/foreground-envelope.js +8 -25
  52. package/dist/core/autonomy/foreground-envelope.js.map +1 -1
  53. package/dist/core/autonomy/gates.d.ts.map +1 -1
  54. package/dist/core/autonomy/gates.js +8 -10
  55. package/dist/core/autonomy/gates.js.map +1 -1
  56. package/dist/core/autonomy/lane-private-paths.d.ts +2 -0
  57. package/dist/core/autonomy/lane-private-paths.d.ts.map +1 -0
  58. package/dist/core/autonomy/lane-private-paths.js +16 -0
  59. package/dist/core/autonomy/lane-private-paths.js.map +1 -0
  60. package/dist/core/autonomy/lane-tool-surface.d.ts +10 -0
  61. package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
  62. package/dist/core/autonomy/lane-tool-surface.js +46 -8
  63. package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
  64. package/dist/core/autonomy/lane-tracker.d.ts +14 -0
  65. package/dist/core/autonomy/lane-tracker.d.ts.map +1 -1
  66. package/dist/core/autonomy/lane-tracker.js +38 -0
  67. package/dist/core/autonomy/lane-tracker.js.map +1 -1
  68. package/dist/core/autonomy/risk-assessment.d.ts +1 -2
  69. package/dist/core/autonomy/risk-assessment.d.ts.map +1 -1
  70. package/dist/core/autonomy/risk-assessment.js +1 -123
  71. package/dist/core/autonomy/risk-assessment.js.map +1 -1
  72. package/dist/core/autonomy/session-lane-record.d.ts +4 -4
  73. package/dist/core/autonomy/session-lane-record.d.ts.map +1 -1
  74. package/dist/core/autonomy/session-lane-record.js +16 -29
  75. package/dist/core/autonomy/session-lane-record.js.map +1 -1
  76. package/dist/core/autonomy/telemetry-events.d.ts +1 -1
  77. package/dist/core/autonomy/telemetry-events.d.ts.map +1 -1
  78. package/dist/core/autonomy/telemetry-events.js +1 -1
  79. package/dist/core/autonomy/telemetry-events.js.map +1 -1
  80. package/dist/core/autonomy-telemetry.d.ts +7 -7
  81. package/dist/core/autonomy-telemetry.d.ts.map +1 -1
  82. package/dist/core/autonomy-telemetry.js +9 -9
  83. package/dist/core/autonomy-telemetry.js.map +1 -1
  84. package/dist/core/background-lane-controller.d.ts +54 -236
  85. package/dist/core/background-lane-controller.d.ts.map +1 -1
  86. package/dist/core/background-lane-controller.js +140 -1273
  87. package/dist/core/background-lane-controller.js.map +1 -1
  88. package/dist/core/capability-contract.d.ts +4 -0
  89. package/dist/core/capability-contract.d.ts.map +1 -0
  90. package/dist/core/capability-contract.js +28 -0
  91. package/dist/core/capability-contract.js.map +1 -0
  92. package/dist/core/compaction-controller.d.ts +90 -0
  93. package/dist/core/compaction-controller.d.ts.map +1 -0
  94. package/dist/core/compaction-controller.js +452 -0
  95. package/dist/core/compaction-controller.js.map +1 -0
  96. package/dist/core/compaction-support.d.ts +12 -11
  97. package/dist/core/compaction-support.d.ts.map +1 -1
  98. package/dist/core/compaction-support.js.map +1 -1
  99. package/dist/core/context/context-artifacts.d.ts +6 -2
  100. package/dist/core/context/context-artifacts.d.ts.map +1 -1
  101. package/dist/core/context/context-artifacts.js +34 -2
  102. package/dist/core/context/context-artifacts.js.map +1 -1
  103. package/dist/core/context/context-store-retention.d.ts +8 -2
  104. package/dist/core/context/context-store-retention.d.ts.map +1 -1
  105. package/dist/core/context/context-store-retention.js +158 -35
  106. package/dist/core/context/context-store-retention.js.map +1 -1
  107. package/dist/core/context/okf-memory.d.ts.map +1 -1
  108. package/dist/core/context/okf-memory.js +9 -11
  109. package/dist/core/context/okf-memory.js.map +1 -1
  110. package/dist/core/context/sqlite-runtime-index.d.ts.map +1 -1
  111. package/dist/core/context/sqlite-runtime-index.js +6 -8
  112. package/dist/core/context/sqlite-runtime-index.js.map +1 -1
  113. package/dist/core/context-gc.d.ts +3 -0
  114. package/dist/core/context-gc.d.ts.map +1 -1
  115. package/dist/core/context-gc.js +10 -5
  116. package/dist/core/context-gc.js.map +1 -1
  117. package/dist/core/context-pipeline.d.ts.map +1 -1
  118. package/dist/core/context-pipeline.js +9 -4
  119. package/dist/core/context-pipeline.js.map +1 -1
  120. package/dist/core/default-tool-surface.d.ts.map +1 -1
  121. package/dist/core/default-tool-surface.js +1 -0
  122. package/dist/core/default-tool-surface.js.map +1 -1
  123. package/dist/core/delegation/managed-lane-controller.d.ts +34 -0
  124. package/dist/core/delegation/managed-lane-controller.d.ts.map +1 -0
  125. package/dist/core/delegation/managed-lane-controller.js +217 -0
  126. package/dist/core/delegation/managed-lane-controller.js.map +1 -0
  127. package/dist/core/delegation/session-worker-claim.d.ts +44 -0
  128. package/dist/core/delegation/session-worker-claim.d.ts.map +1 -0
  129. package/dist/core/delegation/session-worker-claim.js +98 -0
  130. package/dist/core/delegation/session-worker-claim.js.map +1 -0
  131. package/dist/core/delegation/worker-actions.d.ts +7 -5
  132. package/dist/core/delegation/worker-actions.d.ts.map +1 -1
  133. package/dist/core/delegation/worker-actions.js +20 -4
  134. package/dist/core/delegation/worker-actions.js.map +1 -1
  135. package/dist/core/delegation/{worker-result.d.ts → worker-claim.d.ts} +13 -13
  136. package/dist/core/delegation/worker-claim.d.ts.map +1 -0
  137. package/dist/core/delegation/{worker-result.js → worker-claim.js} +61 -51
  138. package/dist/core/delegation/worker-claim.js.map +1 -0
  139. package/dist/core/delegation/worker-delegation-controller.d.ts +110 -0
  140. package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -0
  141. package/dist/core/delegation/worker-delegation-controller.js +861 -0
  142. package/dist/core/delegation/worker-delegation-controller.js.map +1 -0
  143. package/dist/core/delegation/worker-delegation-request.d.ts +11 -0
  144. package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -0
  145. package/dist/core/delegation/worker-delegation-request.js +2 -0
  146. package/dist/core/delegation/worker-delegation-request.js.map +1 -0
  147. package/dist/core/delegation/worker-dispatch-scheduler.d.ts +40 -0
  148. package/dist/core/delegation/worker-dispatch-scheduler.d.ts.map +1 -0
  149. package/dist/core/delegation/worker-dispatch-scheduler.js +93 -0
  150. package/dist/core/delegation/worker-dispatch-scheduler.js.map +1 -0
  151. package/dist/core/delegation/worker-execution-policy.d.ts +62 -0
  152. package/dist/core/delegation/worker-execution-policy.d.ts.map +1 -0
  153. package/dist/core/delegation/worker-execution-policy.js +160 -0
  154. package/dist/core/delegation/worker-execution-policy.js.map +1 -0
  155. package/dist/core/delegation/worker-lane-projection.d.ts +14 -0
  156. package/dist/core/delegation/worker-lane-projection.d.ts.map +1 -0
  157. package/dist/core/delegation/worker-lane-projection.js +100 -0
  158. package/dist/core/delegation/worker-lane-projection.js.map +1 -0
  159. package/dist/core/delegation/worker-lifecycle.d.ts +97 -0
  160. package/dist/core/delegation/worker-lifecycle.d.ts.map +1 -0
  161. package/dist/core/delegation/worker-lifecycle.js +339 -0
  162. package/dist/core/delegation/worker-lifecycle.js.map +1 -0
  163. package/dist/core/delegation/worker-notification-coordinator.d.ts +36 -0
  164. package/dist/core/delegation/worker-notification-coordinator.d.ts.map +1 -0
  165. package/dist/core/delegation/worker-notification-coordinator.js +90 -0
  166. package/dist/core/delegation/worker-notification-coordinator.js.map +1 -0
  167. package/dist/core/delegation/worker-profile-resolver.d.ts +55 -0
  168. package/dist/core/delegation/worker-profile-resolver.d.ts.map +1 -0
  169. package/dist/core/delegation/worker-profile-resolver.js +113 -0
  170. package/dist/core/delegation/worker-profile-resolver.js.map +1 -0
  171. package/dist/core/delegation/worker-runner.d.ts +25 -14
  172. package/dist/core/delegation/worker-runner.d.ts.map +1 -1
  173. package/dist/core/delegation/worker-runner.js +122 -53
  174. package/dist/core/delegation/worker-runner.js.map +1 -1
  175. package/dist/core/delegation/worker-task-label.d.ts +3 -0
  176. package/dist/core/delegation/worker-task-label.d.ts.map +1 -0
  177. package/dist/core/delegation/worker-task-label.js +11 -0
  178. package/dist/core/delegation/worker-task-label.js.map +1 -0
  179. package/dist/core/doctor.d.ts +8 -0
  180. package/dist/core/doctor.d.ts.map +1 -1
  181. package/dist/core/doctor.js +32 -1
  182. package/dist/core/doctor.js.map +1 -1
  183. package/dist/core/extensions/index.d.ts +1 -1
  184. package/dist/core/extensions/index.d.ts.map +1 -1
  185. package/dist/core/extensions/index.js.map +1 -1
  186. package/dist/core/extensions/loader.d.ts +5 -1
  187. package/dist/core/extensions/loader.d.ts.map +1 -1
  188. package/dist/core/extensions/loader.js +50 -15
  189. package/dist/core/extensions/loader.js.map +1 -1
  190. package/dist/core/extensions/runner.d.ts.map +1 -1
  191. package/dist/core/extensions/runner.js +6 -0
  192. package/dist/core/extensions/runner.js.map +1 -1
  193. package/dist/core/extensions/storage.d.ts +8 -0
  194. package/dist/core/extensions/storage.d.ts.map +1 -0
  195. package/dist/core/extensions/storage.js +28 -0
  196. package/dist/core/extensions/storage.js.map +1 -0
  197. package/dist/core/extensions/types.d.ts +70 -21
  198. package/dist/core/extensions/types.d.ts.map +1 -1
  199. package/dist/core/extensions/types.js.map +1 -1
  200. package/dist/core/failure-corpus.d.ts +1 -15
  201. package/dist/core/failure-corpus.d.ts.map +1 -1
  202. package/dist/core/failure-corpus.js +9 -37
  203. package/dist/core/failure-corpus.js.map +1 -1
  204. package/dist/core/foreground-recovery-controller.d.ts +52 -0
  205. package/dist/core/foreground-recovery-controller.d.ts.map +1 -0
  206. package/dist/core/foreground-recovery-controller.js +111 -0
  207. package/dist/core/foreground-recovery-controller.js.map +1 -0
  208. package/dist/core/gateways/channel-provider.d.ts +3 -0
  209. package/dist/core/gateways/channel-provider.d.ts.map +1 -1
  210. package/dist/core/gateways/channel-provider.js +31 -6
  211. package/dist/core/gateways/channel-provider.js.map +1 -1
  212. package/dist/core/goals/goal-acceptance.d.ts +11 -0
  213. package/dist/core/goals/goal-acceptance.d.ts.map +1 -0
  214. package/dist/core/goals/goal-acceptance.js +25 -0
  215. package/dist/core/goals/goal-acceptance.js.map +1 -0
  216. package/dist/core/goals/goal-auto-continue-controller.d.ts +27 -0
  217. package/dist/core/goals/goal-auto-continue-controller.d.ts.map +1 -0
  218. package/dist/core/goals/goal-auto-continue-controller.js +93 -0
  219. package/dist/core/goals/goal-auto-continue-controller.js.map +1 -0
  220. package/dist/core/goals/goal-continuation-controller.d.ts +1 -1
  221. package/dist/core/goals/goal-continuation-controller.d.ts.map +1 -1
  222. package/dist/core/goals/goal-continuation-controller.js +10 -0
  223. package/dist/core/goals/goal-continuation-controller.js.map +1 -1
  224. package/dist/core/goals/goal-continuation-prompt.d.ts +1 -1
  225. package/dist/core/goals/goal-continuation-prompt.d.ts.map +1 -1
  226. package/dist/core/goals/goal-continuation-prompt.js +6 -6
  227. package/dist/core/goals/goal-continuation-prompt.js.map +1 -1
  228. package/dist/core/goals/goal-lifecycle.d.ts +20 -0
  229. package/dist/core/goals/goal-lifecycle.d.ts.map +1 -0
  230. package/dist/core/goals/goal-lifecycle.js +17 -0
  231. package/dist/core/goals/goal-lifecycle.js.map +1 -0
  232. package/dist/core/goals/goal-runtime-snapshot.d.ts +11 -9
  233. package/dist/core/goals/goal-runtime-snapshot.d.ts.map +1 -1
  234. package/dist/core/goals/goal-runtime-snapshot.js +10 -8
  235. package/dist/core/goals/goal-runtime-snapshot.js.map +1 -1
  236. package/dist/core/goals/goal-state.d.ts +1 -0
  237. package/dist/core/goals/goal-state.d.ts.map +1 -1
  238. package/dist/core/goals/goal-state.js +7 -10
  239. package/dist/core/goals/goal-state.js.map +1 -1
  240. package/dist/core/goals/goal-tool-core.d.ts +8 -6
  241. package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
  242. package/dist/core/goals/goal-tool-core.js +11 -41
  243. package/dist/core/goals/goal-tool-core.js.map +1 -1
  244. package/dist/core/goals/session-goal-state.d.ts +2 -4
  245. package/dist/core/goals/session-goal-state.d.ts.map +1 -1
  246. package/dist/core/goals/session-goal-state.js +10 -33
  247. package/dist/core/goals/session-goal-state.js.map +1 -1
  248. package/dist/core/human-input.d.ts +100 -0
  249. package/dist/core/human-input.d.ts.map +1 -0
  250. package/dist/core/human-input.js +362 -0
  251. package/dist/core/human-input.js.map +1 -0
  252. package/dist/core/index.d.ts +9 -1
  253. package/dist/core/index.d.ts.map +1 -1
  254. package/dist/core/index.js +9 -1
  255. package/dist/core/index.js.map +1 -1
  256. package/dist/core/{telemetry.d.ts → install-telemetry.d.ts} +1 -1
  257. package/dist/core/install-telemetry.d.ts.map +1 -0
  258. package/dist/core/{telemetry.js → install-telemetry.js} +1 -1
  259. package/dist/core/install-telemetry.js.map +1 -0
  260. package/dist/core/keybindings.d.ts +17 -1
  261. package/dist/core/keybindings.d.ts.map +1 -1
  262. package/dist/core/keybindings.js +24 -6
  263. package/dist/core/keybindings.js.map +1 -1
  264. package/dist/core/learning/learning-audit.d.ts +2 -4
  265. package/dist/core/learning/learning-audit.d.ts.map +1 -1
  266. package/dist/core/learning/learning-audit.js +9 -29
  267. package/dist/core/learning/learning-audit.js.map +1 -1
  268. package/dist/core/learning/learning-gate.d.ts.map +1 -1
  269. package/dist/core/learning/learning-gate.js +1 -6
  270. package/dist/core/learning/learning-gate.js.map +1 -1
  271. package/dist/core/learning/session-learning-decision.d.ts +2 -4
  272. package/dist/core/learning/session-learning-decision.d.ts.map +1 -1
  273. package/dist/core/learning/session-learning-decision.js +9 -29
  274. package/dist/core/learning/session-learning-decision.js.map +1 -1
  275. package/dist/core/memory-controller.d.ts.map +1 -1
  276. package/dist/core/memory-controller.js +4 -4
  277. package/dist/core/memory-controller.js.map +1 -1
  278. package/dist/core/model-capability.d.ts.map +1 -1
  279. package/dist/core/model-capability.js +1 -0
  280. package/dist/core/model-capability.js.map +1 -1
  281. package/dist/core/model-resolver.d.ts +1 -1
  282. package/dist/core/model-resolver.d.ts.map +1 -1
  283. package/dist/core/model-resolver.js +6 -9
  284. package/dist/core/model-resolver.js.map +1 -1
  285. package/dist/core/model-router/intent-classifier.d.ts +1 -4
  286. package/dist/core/model-router/intent-classifier.d.ts.map +1 -1
  287. package/dist/core/model-router/intent-classifier.js +1 -156
  288. package/dist/core/model-router/intent-classifier.js.map +1 -1
  289. package/dist/core/model-router-controller.d.ts.map +1 -1
  290. package/dist/core/model-router-controller.js +2 -2
  291. package/dist/core/model-router-controller.js.map +1 -1
  292. package/dist/core/model-selection-controller.d.ts +4 -4
  293. package/dist/core/model-selection-controller.d.ts.map +1 -1
  294. package/dist/core/model-selection-controller.js.map +1 -1
  295. package/dist/core/model-tool-protocol.d.ts +23 -0
  296. package/dist/core/model-tool-protocol.d.ts.map +1 -0
  297. package/dist/core/model-tool-protocol.js +43 -0
  298. package/dist/core/model-tool-protocol.js.map +1 -0
  299. package/dist/core/models/adaptation-store.d.ts +4 -6
  300. package/dist/core/models/adaptation-store.d.ts.map +1 -1
  301. package/dist/core/models/adaptation-store.js +95 -83
  302. package/dist/core/models/adaptation-store.js.map +1 -1
  303. package/dist/core/models/fitness-store.d.ts +2 -12
  304. package/dist/core/models/fitness-store.d.ts.map +1 -1
  305. package/dist/core/models/fitness-store.js +84 -57
  306. package/dist/core/models/fitness-store.js.map +1 -1
  307. package/dist/core/models/host-state-store.d.ts +34 -0
  308. package/dist/core/models/host-state-store.d.ts.map +1 -0
  309. package/dist/core/models/host-state-store.js +86 -0
  310. package/dist/core/models/host-state-store.js.map +1 -0
  311. package/dist/core/orchestration/agent-resume.d.ts +24 -0
  312. package/dist/core/orchestration/agent-resume.d.ts.map +1 -0
  313. package/dist/core/orchestration/agent-resume.js +90 -0
  314. package/dist/core/orchestration/agent-resume.js.map +1 -0
  315. package/dist/core/orchestration/capability-gateway.d.ts +61 -0
  316. package/dist/core/orchestration/capability-gateway.d.ts.map +1 -0
  317. package/dist/core/orchestration/capability-gateway.js +152 -0
  318. package/dist/core/orchestration/capability-gateway.js.map +1 -0
  319. package/dist/core/orchestration/contracts.d.ts +343 -0
  320. package/dist/core/orchestration/contracts.d.ts.map +1 -0
  321. package/dist/core/orchestration/contracts.js +135 -0
  322. package/dist/core/orchestration/contracts.js.map +1 -0
  323. package/dist/core/orchestration/delegation-ledger.d.ts +56 -0
  324. package/dist/core/orchestration/delegation-ledger.d.ts.map +1 -0
  325. package/dist/core/orchestration/delegation-ledger.js +197 -0
  326. package/dist/core/orchestration/delegation-ledger.js.map +1 -0
  327. package/dist/core/orchestration/event-store.d.ts +83 -0
  328. package/dist/core/orchestration/event-store.d.ts.map +1 -0
  329. package/dist/core/orchestration/event-store.js +560 -0
  330. package/dist/core/orchestration/event-store.js.map +1 -0
  331. package/dist/core/orchestration/lane-tool-manifests.d.ts +9 -0
  332. package/dist/core/orchestration/lane-tool-manifests.d.ts.map +1 -0
  333. package/dist/core/orchestration/lane-tool-manifests.js +37 -0
  334. package/dist/core/orchestration/lane-tool-manifests.js.map +1 -0
  335. package/dist/core/orchestration/model-binding.d.ts +15 -0
  336. package/dist/core/orchestration/model-binding.d.ts.map +1 -0
  337. package/dist/core/orchestration/model-binding.js +29 -0
  338. package/dist/core/orchestration/model-binding.js.map +1 -0
  339. package/dist/core/orchestration/policy-compiler.d.ts +49 -0
  340. package/dist/core/orchestration/policy-compiler.d.ts.map +1 -0
  341. package/dist/core/orchestration/policy-compiler.js +191 -0
  342. package/dist/core/orchestration/policy-compiler.js.map +1 -0
  343. package/dist/core/orchestration/policy-gate.d.ts +18 -0
  344. package/dist/core/orchestration/policy-gate.d.ts.map +1 -0
  345. package/dist/core/orchestration/policy-gate.js +24 -0
  346. package/dist/core/orchestration/policy-gate.js.map +1 -0
  347. package/dist/core/orchestration/profile-registry.d.ts +51 -0
  348. package/dist/core/orchestration/profile-registry.d.ts.map +1 -0
  349. package/dist/core/orchestration/profile-registry.js +393 -0
  350. package/dist/core/orchestration/profile-registry.js.map +1 -0
  351. package/dist/core/orchestration/profile-store.d.ts +31 -0
  352. package/dist/core/orchestration/profile-store.d.ts.map +1 -0
  353. package/dist/core/orchestration/profile-store.js +136 -0
  354. package/dist/core/orchestration/profile-store.js.map +1 -0
  355. package/dist/core/orchestration/risk-budget.d.ts +9 -0
  356. package/dist/core/orchestration/risk-budget.d.ts.map +1 -0
  357. package/dist/core/orchestration/risk-budget.js +48 -0
  358. package/dist/core/orchestration/risk-budget.js.map +1 -0
  359. package/dist/core/orchestration/task-runtime.d.ts +168 -0
  360. package/dist/core/orchestration/task-runtime.d.ts.map +1 -0
  361. package/dist/core/orchestration/task-runtime.js +1600 -0
  362. package/dist/core/orchestration/task-runtime.js.map +1 -0
  363. package/dist/core/orchestration/work-state-projection.d.ts +32 -0
  364. package/dist/core/orchestration/work-state-projection.d.ts.map +1 -0
  365. package/dist/core/orchestration/work-state-projection.js +116 -0
  366. package/dist/core/orchestration/work-state-projection.js.map +1 -0
  367. package/dist/core/orchestration/worker-execution-contract.d.ts +21 -0
  368. package/dist/core/orchestration/worker-execution-contract.d.ts.map +1 -0
  369. package/dist/core/orchestration/worker-execution-contract.js +179 -0
  370. package/dist/core/orchestration/worker-execution-contract.js.map +1 -0
  371. package/dist/core/orchestration/worker-result-adapter.d.ts +21 -0
  372. package/dist/core/orchestration/worker-result-adapter.d.ts.map +1 -0
  373. package/dist/core/orchestration/worker-result-adapter.js +109 -0
  374. package/dist/core/orchestration/worker-result-adapter.js.map +1 -0
  375. package/dist/core/process-identity.d.ts +11 -0
  376. package/dist/core/process-identity.d.ts.map +1 -0
  377. package/dist/core/process-identity.js +26 -0
  378. package/dist/core/process-identity.js.map +1 -0
  379. package/dist/core/process-matrix/codes.d.ts +14 -3
  380. package/dist/core/process-matrix/codes.d.ts.map +1 -1
  381. package/dist/core/process-matrix/codes.js.map +1 -1
  382. package/dist/core/process-matrix/resume-launcher.d.ts +26 -0
  383. package/dist/core/process-matrix/resume-launcher.d.ts.map +1 -0
  384. package/dist/core/process-matrix/resume-launcher.js +62 -0
  385. package/dist/core/process-matrix/resume-launcher.js.map +1 -0
  386. package/dist/core/process-matrix/runtime.d.ts +37 -22
  387. package/dist/core/process-matrix/runtime.d.ts.map +1 -1
  388. package/dist/core/process-matrix/runtime.js +399 -76
  389. package/dist/core/process-matrix/runtime.js.map +1 -1
  390. package/dist/core/process-matrix/store.d.ts +5 -2
  391. package/dist/core/process-matrix/store.d.ts.map +1 -1
  392. package/dist/core/process-matrix/store.js +123 -14
  393. package/dist/core/process-matrix/store.js.map +1 -1
  394. package/dist/core/process-matrix/supervisor.d.ts +10 -7
  395. package/dist/core/process-matrix/supervisor.d.ts.map +1 -1
  396. package/dist/core/process-matrix/supervisor.js +45 -14
  397. package/dist/core/process-matrix/supervisor.js.map +1 -1
  398. package/dist/core/profile-registry.d.ts.map +1 -1
  399. package/dist/core/profile-registry.js +6 -8
  400. package/dist/core/profile-registry.js.map +1 -1
  401. package/dist/core/reflection-controller.d.ts +4 -4
  402. package/dist/core/reflection-controller.d.ts.map +1 -1
  403. package/dist/core/reflection-controller.js +2 -1
  404. package/dist/core/reflection-controller.js.map +1 -1
  405. package/dist/core/reload-blockers.d.ts.map +1 -1
  406. package/dist/core/reload-blockers.js +6 -8
  407. package/dist/core/reload-blockers.js.map +1 -1
  408. package/dist/core/research/evidence-bundle.d.ts.map +1 -1
  409. package/dist/core/research/evidence-bundle.js +1 -6
  410. package/dist/core/research/evidence-bundle.js.map +1 -1
  411. package/dist/core/research/lane-model-resolver.d.ts +33 -0
  412. package/dist/core/research/lane-model-resolver.d.ts.map +1 -0
  413. package/dist/core/research/lane-model-resolver.js +65 -0
  414. package/dist/core/research/lane-model-resolver.js.map +1 -0
  415. package/dist/core/research/model-fitness-controller.d.ts +38 -0
  416. package/dist/core/research/model-fitness-controller.d.ts.map +1 -0
  417. package/dist/core/research/model-fitness-controller.js +106 -0
  418. package/dist/core/research/model-fitness-controller.js.map +1 -0
  419. package/dist/core/research/model-fitness.d.ts +1 -1
  420. package/dist/core/research/model-fitness.d.ts.map +1 -1
  421. package/dist/core/research/model-fitness.js +4 -4
  422. package/dist/core/research/model-fitness.js.map +1 -1
  423. package/dist/core/research/research-gate.d.ts.map +1 -1
  424. package/dist/core/research/research-gate.js +7 -7
  425. package/dist/core/research/research-gate.js.map +1 -1
  426. package/dist/core/research/research-lane-controller.d.ts +62 -0
  427. package/dist/core/research/research-lane-controller.d.ts.map +1 -0
  428. package/dist/core/research/research-lane-controller.js +292 -0
  429. package/dist/core/research/research-lane-controller.js.map +1 -0
  430. package/dist/core/research/session-evidence-bundle.d.ts +2 -4
  431. package/dist/core/research/session-evidence-bundle.d.ts.map +1 -1
  432. package/dist/core/research/session-evidence-bundle.js +10 -46
  433. package/dist/core/research/session-evidence-bundle.js.map +1 -1
  434. package/dist/core/resource-loader.d.ts.map +1 -1
  435. package/dist/core/resource-loader.js +7 -2
  436. package/dist/core/resource-loader.js.map +1 -1
  437. package/dist/core/risk-classifier.d.ts +6 -0
  438. package/dist/core/risk-classifier.d.ts.map +1 -0
  439. package/dist/core/risk-classifier.js +225 -0
  440. package/dist/core/risk-classifier.js.map +1 -0
  441. package/dist/core/runtime-builder.d.ts +26 -20
  442. package/dist/core/runtime-builder.d.ts.map +1 -1
  443. package/dist/core/runtime-builder.js +237 -178
  444. package/dist/core/runtime-builder.js.map +1 -1
  445. package/dist/core/sdk.d.ts +6 -3
  446. package/dist/core/sdk.d.ts.map +1 -1
  447. package/dist/core/sdk.js +61 -24
  448. package/dist/core/sdk.js.map +1 -1
  449. package/dist/core/session-analytics.d.ts.map +1 -1
  450. package/dist/core/session-analytics.js +28 -1
  451. package/dist/core/session-analytics.js.map +1 -1
  452. package/dist/core/session-image-store.d.ts +33 -0
  453. package/dist/core/session-image-store.d.ts.map +1 -0
  454. package/dist/core/session-image-store.js +283 -0
  455. package/dist/core/session-image-store.js.map +1 -0
  456. package/dist/core/session-role.d.ts +6 -4
  457. package/dist/core/session-role.d.ts.map +1 -1
  458. package/dist/core/session-role.js +10 -4
  459. package/dist/core/session-role.js.map +1 -1
  460. package/dist/core/session-snapshot.d.ts +34 -0
  461. package/dist/core/session-snapshot.d.ts.map +1 -0
  462. package/dist/core/session-snapshot.js +68 -0
  463. package/dist/core/session-snapshot.js.map +1 -0
  464. package/dist/core/session-supervision-runtime.d.ts +31 -0
  465. package/dist/core/session-supervision-runtime.d.ts.map +1 -0
  466. package/dist/core/session-supervision-runtime.js +97 -0
  467. package/dist/core/session-supervision-runtime.js.map +1 -0
  468. package/dist/core/settings-manager.d.ts +9 -4
  469. package/dist/core/settings-manager.d.ts.map +1 -1
  470. package/dist/core/settings-manager.js +80 -28
  471. package/dist/core/settings-manager.js.map +1 -1
  472. package/dist/core/tasks/session-task-state.d.ts +2 -4
  473. package/dist/core/tasks/session-task-state.d.ts.map +1 -1
  474. package/dist/core/tasks/session-task-state.js +10 -28
  475. package/dist/core/tasks/session-task-state.js.map +1 -1
  476. package/dist/core/tasks/task-projection.d.ts +20 -0
  477. package/dist/core/tasks/task-projection.d.ts.map +1 -0
  478. package/dist/core/tasks/task-projection.js +47 -0
  479. package/dist/core/tasks/task-projection.js.map +1 -0
  480. package/dist/core/tasks/task-state.d.ts +4 -0
  481. package/dist/core/tasks/task-state.d.ts.map +1 -1
  482. package/dist/core/tasks/task-state.js +28 -11
  483. package/dist/core/tasks/task-state.js.map +1 -1
  484. package/dist/core/tool-capability-policy.d.ts +13 -0
  485. package/dist/core/tool-capability-policy.d.ts.map +1 -0
  486. package/dist/core/tool-capability-policy.js +85 -0
  487. package/dist/core/tool-capability-policy.js.map +1 -0
  488. package/dist/core/tool-protocol-controller.d.ts +91 -0
  489. package/dist/core/tool-protocol-controller.d.ts.map +1 -0
  490. package/dist/core/tool-protocol-controller.js +512 -0
  491. package/dist/core/tool-protocol-controller.js.map +1 -0
  492. package/dist/core/tool-recovery-log-records.d.ts +2 -3
  493. package/dist/core/tool-recovery-log-records.d.ts.map +1 -1
  494. package/dist/core/tool-recovery-log-records.js +9 -35
  495. package/dist/core/tool-recovery-log-records.js.map +1 -1
  496. package/dist/core/tool-selection/tool-performance-store.d.ts +3 -7
  497. package/dist/core/tool-selection/tool-performance-store.d.ts.map +1 -1
  498. package/dist/core/tool-selection/tool-performance-store.js +97 -138
  499. package/dist/core/tool-selection/tool-performance-store.js.map +1 -1
  500. package/dist/core/tools/ask-question.d.ts +124 -0
  501. package/dist/core/tools/ask-question.d.ts.map +1 -0
  502. package/dist/core/tools/ask-question.js +693 -0
  503. package/dist/core/tools/ask-question.js.map +1 -0
  504. package/dist/core/tools/delegate-status.d.ts +31 -3
  505. package/dist/core/tools/delegate-status.d.ts.map +1 -1
  506. package/dist/core/tools/delegate-status.js +149 -29
  507. package/dist/core/tools/delegate-status.js.map +1 -1
  508. package/dist/core/tools/delegate.d.ts +15 -13
  509. package/dist/core/tools/delegate.d.ts.map +1 -1
  510. package/dist/core/tools/delegate.js +108 -23
  511. package/dist/core/tools/delegate.js.map +1 -1
  512. package/dist/core/tools/extensionify.d.ts.map +1 -1
  513. package/dist/core/tools/extensionify.js +1 -0
  514. package/dist/core/tools/extensionify.js.map +1 -1
  515. package/dist/core/tools/goal.d.ts +5 -5
  516. package/dist/core/tools/goal.d.ts.map +1 -1
  517. package/dist/core/tools/goal.js +10 -10
  518. package/dist/core/tools/goal.js.map +1 -1
  519. package/dist/core/tools/model-fitness.d.ts.map +1 -1
  520. package/dist/core/tools/model-fitness.js +2 -2
  521. package/dist/core/tools/model-fitness.js.map +1 -1
  522. package/dist/core/tools/orchestration-panel.d.ts +43 -0
  523. package/dist/core/tools/orchestration-panel.d.ts.map +1 -0
  524. package/dist/core/tools/orchestration-panel.js +168 -0
  525. package/dist/core/tools/orchestration-panel.js.map +1 -0
  526. package/dist/core/tools/run-process.d.ts +26 -0
  527. package/dist/core/tools/run-process.d.ts.map +1 -0
  528. package/dist/core/tools/run-process.js +138 -0
  529. package/dist/core/tools/run-process.js.map +1 -0
  530. package/dist/core/tools/task-steps.d.ts +2 -0
  531. package/dist/core/tools/task-steps.d.ts.map +1 -1
  532. package/dist/core/tools/task-steps.js +102 -0
  533. package/dist/core/tools/task-steps.js.map +1 -1
  534. package/dist/core/tools/tmux-dispatch.d.ts +3 -5
  535. package/dist/core/tools/tmux-dispatch.d.ts.map +1 -1
  536. package/dist/core/tools/tmux-dispatch.js +4 -4
  537. package/dist/core/tools/tmux-dispatch.js.map +1 -1
  538. package/dist/core/tools/windows-shell-engine.d.ts.map +1 -1
  539. package/dist/core/tools/windows-shell-engine.js +4 -6
  540. package/dist/core/tools/windows-shell-engine.js.map +1 -1
  541. package/dist/core/util/bounded-jsonl.d.ts +10 -0
  542. package/dist/core/util/bounded-jsonl.d.ts.map +1 -0
  543. package/dist/core/util/bounded-jsonl.js +75 -0
  544. package/dist/core/util/bounded-jsonl.js.map +1 -0
  545. package/dist/core/util/value-guards.d.ts +5 -0
  546. package/dist/core/util/value-guards.d.ts.map +1 -0
  547. package/dist/core/util/value-guards.js +12 -0
  548. package/dist/core/util/value-guards.js.map +1 -0
  549. package/dist/core/worktree-sync/store.d.ts +3 -3
  550. package/dist/core/worktree-sync/store.d.ts.map +1 -1
  551. package/dist/core/worktree-sync/store.js +10 -5
  552. package/dist/core/worktree-sync/store.js.map +1 -1
  553. package/dist/index.d.ts +13 -3
  554. package/dist/index.d.ts.map +1 -1
  555. package/dist/index.js +12 -2
  556. package/dist/index.js.map +1 -1
  557. package/dist/main.d.ts.map +1 -1
  558. package/dist/main.js +128 -44
  559. package/dist/main.js.map +1 -1
  560. package/dist/migrations.d.ts +4 -6
  561. package/dist/migrations.d.ts.map +1 -1
  562. package/dist/migrations.js +186 -28
  563. package/dist/migrations.js.map +1 -1
  564. package/dist/modes/interactive/clipboard-input.d.ts +7 -1
  565. package/dist/modes/interactive/clipboard-input.d.ts.map +1 -1
  566. package/dist/modes/interactive/clipboard-input.js +44 -6
  567. package/dist/modes/interactive/clipboard-input.js.map +1 -1
  568. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  569. package/dist/modes/interactive/components/settings-selector.js +2 -2
  570. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  571. package/dist/modes/interactive/config-backup.d.ts.map +1 -1
  572. package/dist/modes/interactive/config-backup.js +5 -4
  573. package/dist/modes/interactive/config-backup.js.map +1 -1
  574. package/dist/modes/interactive/extension-ui-host.d.ts +14 -0
  575. package/dist/modes/interactive/extension-ui-host.d.ts.map +1 -1
  576. package/dist/modes/interactive/extension-ui-host.js +76 -15
  577. package/dist/modes/interactive/extension-ui-host.js.map +1 -1
  578. package/dist/modes/interactive/interactive-mode.d.ts +3 -0
  579. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  580. package/dist/modes/interactive/interactive-mode.js +63 -1
  581. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  582. package/dist/modes/interactive/key-handlers.d.ts.map +1 -1
  583. package/dist/modes/interactive/key-handlers.js +1 -1
  584. package/dist/modes/interactive/key-handlers.js.map +1 -1
  585. package/dist/modes/interactive/profile-menu-controller.d.ts.map +1 -1
  586. package/dist/modes/interactive/profile-menu-controller.js +7 -7
  587. package/dist/modes/interactive/profile-menu-controller.js.map +1 -1
  588. package/dist/modes/interactive/report-commands.d.ts.map +1 -1
  589. package/dist/modes/interactive/report-commands.js +21 -0
  590. package/dist/modes/interactive/report-commands.js.map +1 -1
  591. package/dist/modes/interactive/session-flow-commands.d.ts +17 -2
  592. package/dist/modes/interactive/session-flow-commands.d.ts.map +1 -1
  593. package/dist/modes/interactive/session-flow-commands.js +50 -17
  594. package/dist/modes/interactive/session-flow-commands.js.map +1 -1
  595. package/dist/modes/interactive/session-io-commands.d.ts.map +1 -1
  596. package/dist/modes/interactive/session-io-commands.js +16 -6
  597. package/dist/modes/interactive/session-io-commands.js.map +1 -1
  598. package/dist/modes/interactive/session-replacement-errors.d.ts +7 -0
  599. package/dist/modes/interactive/session-replacement-errors.d.ts.map +1 -0
  600. package/dist/modes/interactive/session-replacement-errors.js +15 -0
  601. package/dist/modes/interactive/session-replacement-errors.js.map +1 -0
  602. package/dist/modes/interactive/startup-checks.d.ts.map +1 -1
  603. package/dist/modes/interactive/startup-checks.js +1 -1
  604. package/dist/modes/interactive/startup-checks.js.map +1 -1
  605. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  606. package/dist/modes/rpc/rpc-mode.js +82 -23
  607. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  608. package/dist/modes/rpc/rpc-types.d.ts +15 -0
  609. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  610. package/dist/modes/rpc/rpc-types.js +138 -1
  611. package/dist/modes/rpc/rpc-types.js.map +1 -1
  612. package/dist/utils/clipboard-image.d.ts.map +1 -1
  613. package/dist/utils/clipboard-image.js +2 -13
  614. package/dist/utils/clipboard-image.js.map +1 -1
  615. package/dist/utils/clipboard-native.d.ts +1 -0
  616. package/dist/utils/clipboard-native.d.ts.map +1 -1
  617. package/dist/utils/clipboard-native.js.map +1 -1
  618. package/dist/utils/clipboard.d.ts +1 -0
  619. package/dist/utils/clipboard.d.ts.map +1 -1
  620. package/dist/utils/clipboard.js +52 -1
  621. package/dist/utils/clipboard.js.map +1 -1
  622. package/dist/utils/platform.d.ts +3 -0
  623. package/dist/utils/platform.d.ts.map +1 -0
  624. package/dist/utils/platform.js +8 -0
  625. package/dist/utils/platform.js.map +1 -0
  626. package/dist/utils/work-directory.d.ts +11 -0
  627. package/dist/utils/work-directory.d.ts.map +1 -1
  628. package/dist/utils/work-directory.js +30 -9
  629. package/dist/utils/work-directory.js.map +1 -1
  630. package/docs/UI_POLISH_ORCHESTRATION.md +44 -0
  631. package/docs/UI_QUALITY_ORCHESTRATION.md +30 -0
  632. package/docs/docs.json +4 -0
  633. package/docs/extensions.md +62 -2
  634. package/docs/harness-architecture.md +156 -0
  635. package/docs/keybindings.md +11 -1
  636. package/docs/process-matrix.md +59 -26
  637. package/docs/rpc.md +45 -2
  638. package/docs/sessions.md +15 -0
  639. package/docs/settings.md +125 -11
  640. package/docs/task-steps.md +8 -0
  641. package/docs/telemetry.md +19 -0
  642. package/docs/tmux-agent-manager.md +10 -3
  643. package/docs/ui-reference/README.md +9 -0
  644. package/docs/ui-reference/orchestration-after.txt +7 -0
  645. package/docs/ui-reference/orchestration-before.txt +7 -0
  646. package/docs/ui-reference/orchestration-reference.txt +6 -0
  647. package/docs/usage.md +14 -2
  648. package/docs/work-directory.md +19 -8
  649. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  650. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  651. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  652. package/examples/extensions/question.ts +34 -245
  653. package/examples/extensions/questionnaire.ts +41 -407
  654. package/examples/extensions/sandbox/package-lock.json +2 -2
  655. package/examples/extensions/sandbox/package.json +1 -1
  656. package/examples/extensions/with-deps/package-lock.json +2 -2
  657. package/examples/extensions/with-deps/package.json +1 -1
  658. package/npm-shrinkwrap.json +12 -12
  659. package/package.json +4 -4
  660. package/dist/core/delegation/session-worker-result.d.ts +0 -46
  661. package/dist/core/delegation/session-worker-result.d.ts.map +0 -1
  662. package/dist/core/delegation/session-worker-result.js +0 -113
  663. package/dist/core/delegation/session-worker-result.js.map +0 -1
  664. package/dist/core/delegation/worker-result.d.ts.map +0 -1
  665. package/dist/core/delegation/worker-result.js.map +0 -1
  666. package/dist/core/telemetry.d.ts.map +0 -1
  667. package/dist/core/telemetry.js.map +0 -1
@@ -1,8 +1,7 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
- import { dirname } from "node:path";
3
1
  import { stateFile } from "../agent-paths.js";
4
- import { currentHostFingerprint } from "../models/fitness-store.js";
2
+ import { HostStateStore, isHostFingerprint } from "../models/host-state-store.js";
5
3
  import { isWorkerSession } from "../session-role.js";
4
+ import { isRecordObject } from "../util/value-guards.js";
6
5
  const STORE_VERSION = 1;
7
6
  const MAX_STATS_PER_HOST = 500;
8
7
  const MAX_OBSERVATIONS_PER_HOST = 1_000;
@@ -14,9 +13,6 @@ function statKey(key) {
14
13
  function intentAgreementKey(modelRef, intentClass) {
15
14
  return `${modelRef}\0${intentClass}`;
16
15
  }
17
- function isRecord(value) {
18
- return typeof value === "object" && value !== null && !Array.isArray(value);
19
- }
20
16
  function isIntentClass(value) {
21
17
  return (value === "read" ||
22
18
  value === "search" ||
@@ -27,7 +23,7 @@ function isIntentClass(value) {
27
23
  value === "other");
28
24
  }
29
25
  function isStats(value) {
30
- return (isRecord(value) &&
26
+ return (isRecordObject(value) &&
31
27
  typeof value.modelRef === "string" &&
32
28
  isIntentClass(value.intentClass) &&
33
29
  typeof value.tool === "string" &&
@@ -40,7 +36,7 @@ function isStats(value) {
40
36
  typeof value.lastUsedAt === "string");
41
37
  }
42
38
  function isObservation(value) {
43
- return (isRecord(value) &&
39
+ return (isRecordObject(value) &&
44
40
  typeof value.at === "string" &&
45
41
  typeof value.modelRef === "string" &&
46
42
  isIntentClass(value.intentClass) &&
@@ -53,7 +49,7 @@ function isObservation(value) {
53
49
  typeof value.entropy === "number" &&
54
50
  typeof value.margin === "number" &&
55
51
  Array.isArray(value.ranked) &&
56
- value.ranked.every((entry) => isRecord(entry) &&
52
+ value.ranked.every((entry) => isRecordObject(entry) &&
57
53
  typeof entry.tool === "string" &&
58
54
  typeof entry.utility === "number" &&
59
55
  typeof entry.probability === "number") &&
@@ -62,7 +58,7 @@ function isObservation(value) {
62
58
  (value.outputTokenEstimate === undefined || typeof value.outputTokenEstimate === "number"));
63
59
  }
64
60
  function isIntentAgreement(value) {
65
- return (isRecord(value) &&
61
+ return (isRecordObject(value) &&
66
62
  typeof value.modelRef === "string" &&
67
63
  isIntentClass(value.intentClass) &&
68
64
  typeof value.sampleCount === "number" &&
@@ -108,36 +104,24 @@ function updateDeviation(previousValue, previousDeviation, next) {
108
104
  const deviation = previousValue === undefined ? 0 : Math.abs(next - previousValue);
109
105
  return updateEwma(previousDeviation, deviation);
110
106
  }
111
- function parseHost(value) {
112
- if (!isRecord(value) || !isRecord(value.host) || !isRecord(value.stats) || !Array.isArray(value.observations))
107
+ function parseHost(value, hostId) {
108
+ if (!isRecordObject(value) ||
109
+ !isHostFingerprint(value.host) ||
110
+ value.host.id !== hostId ||
111
+ !isRecordObject(value.stats) ||
112
+ !Array.isArray(value.observations))
113
113
  return undefined;
114
114
  const host = value.host;
115
- if (typeof host.id !== "string" ||
116
- typeof host.cpu !== "string" ||
117
- typeof host.cores !== "number" ||
118
- typeof host.totalMemGb !== "number")
119
- return undefined;
120
115
  // intentAgreement is a purely additive field (older store files predate it) — tolerate absence
121
116
  // rather than bumping STORE_VERSION, same as any other backward-compatible default-empty field.
122
- const intentAgreementRaw = isRecord(value.intentAgreement) ? value.intentAgreement : {};
117
+ const intentAgreementRaw = isRecordObject(value.intentAgreement) ? value.intentAgreement : {};
123
118
  return {
124
- host: { id: host.id, cpu: host.cpu, cores: host.cores, totalMemGb: host.totalMemGb },
119
+ host,
125
120
  stats: Object.fromEntries(Object.entries(value.stats).filter((entry) => isStats(entry[1]))),
126
121
  observations: value.observations.filter(isObservation),
127
122
  intentAgreement: Object.fromEntries(Object.entries(intentAgreementRaw).filter((entry) => isIntentAgreement(entry[1]))),
128
123
  };
129
124
  }
130
- function parseFile(value) {
131
- if (!isRecord(value) || value.version !== STORE_VERSION || !isRecord(value.hosts)) {
132
- return { version: STORE_VERSION, hosts: {} };
133
- }
134
- return {
135
- version: STORE_VERSION,
136
- hosts: Object.fromEntries(Object.entries(value.hosts)
137
- .map(([hostId, host]) => [hostId, parseHost(host)])
138
- .filter((entry) => entry[1] !== undefined)),
139
- };
140
- }
141
125
  function trimStats(stats) {
142
126
  const entries = Object.entries(stats);
143
127
  if (entries.length <= MAX_STATS_PER_HOST)
@@ -155,53 +139,30 @@ function trimIntentAgreement(records) {
155
139
  .slice(0, MAX_INTENT_AGREEMENT_PER_HOST));
156
140
  }
157
141
  export class ToolPerformanceStore {
158
- filePath;
159
- fingerprint;
160
- readOnly;
142
+ storage;
161
143
  constructor(filePath, options = {}) {
162
- this.filePath = filePath;
163
- this.fingerprint = options.fingerprint ?? currentHostFingerprint;
164
- this.readOnly = options.readOnly ?? isWorkerSession();
144
+ this.storage = new HostStateStore({
145
+ filePath,
146
+ version: STORE_VERSION,
147
+ fingerprint: options.fingerprint,
148
+ readOnly: options.readOnly ?? isWorkerSession(),
149
+ parseHost,
150
+ });
165
151
  }
166
152
  static forAgentDir(agentDir, options = {}) {
167
153
  return new ToolPerformanceStore(stateFile(agentDir, "tool-performance.json"), options);
168
154
  }
169
- load() {
170
- try {
171
- if (!existsSync(this.filePath))
172
- return { version: STORE_VERSION, hosts: {} };
173
- return parseFile(JSON.parse(readFileSync(this.filePath, "utf8")));
174
- }
175
- catch {
176
- return { version: STORE_VERSION, hosts: {} };
177
- }
178
- }
179
- save(file) {
180
- // Zero-footprint (worker session): never create the state dir, lock, or file -- the caller
181
- // still gets its normally-computed return value from the in-memory `file`.
182
- if (this.readOnly)
183
- return;
184
- mkdirSync(dirname(this.filePath), { recursive: true });
185
- writeFileSync(this.filePath, `${JSON.stringify(file, null, "\t")}\n`, "utf8");
186
- }
187
- hostData(file) {
188
- const fingerprint = this.fingerprint();
189
- const existing = file.hosts[fingerprint.id];
190
- if (existing)
191
- return existing;
192
- const created = { host: fingerprint, stats: {}, observations: [], intentAgreement: {} };
193
- file.hosts[fingerprint.id] = created;
194
- return created;
155
+ createHostData(host) {
156
+ return { host, stats: {}, observations: [], intentAgreement: {} };
195
157
  }
196
158
  get(key) {
197
- const file = this.load();
198
- const host = file.hosts[this.fingerprint().id];
159
+ const host = this.storage.getHost();
199
160
  const stats = host?.stats[statKey(key)];
200
161
  return stats ? { ...stats } : emptyStats(key, new Date(0).toISOString());
201
162
  }
202
163
  /** Every per-tool track record recorded for a (model,intent) bucket — the promotion.ts input. */
203
164
  getStatsForIntent(modelRef, intentClass) {
204
- const host = this.load().hosts[this.fingerprint().id];
165
+ const host = this.storage.getHost();
205
166
  if (!host)
206
167
  return [];
207
168
  return Object.values(host.stats)
@@ -210,94 +171,92 @@ export class ToolPerformanceStore {
210
171
  }
211
172
  /** Durable observe-mode agreement for one (model,intent) bucket (see {@link ToolSelectionIntentAgreement}). */
212
173
  getIntentAgreement(modelRef, intentClass) {
213
- const host = this.load().hosts[this.fingerprint().id];
174
+ const host = this.storage.getHost();
214
175
  const record = host?.intentAgreement[intentAgreementKey(modelRef, intentClass)];
215
176
  return record ? { ...record } : emptyIntentAgreement(modelRef, intentClass, new Date(0).toISOString());
216
177
  }
217
178
  /** All recorded (model,intent) agreement buckets, optionally scoped to one model — report input. */
218
179
  getAllIntentAgreements(modelRef) {
219
- const host = this.load().hosts[this.fingerprint().id];
180
+ const host = this.storage.getHost();
220
181
  return Object.values(host?.intentAgreement ?? {})
221
182
  .filter((record) => modelRef === undefined || record.modelRef === modelRef)
222
183
  .map((record) => ({ ...record }));
223
184
  }
224
185
  recordValidation(key, outcome, at = new Date().toISOString()) {
225
- const file = this.load();
226
- const host = this.hostData(file);
227
- const storageKey = statKey(key);
228
- const current = host.stats[storageKey] ?? emptyStats(key, at);
229
- const next = {
230
- ...current,
231
- repairCount: current.repairCount + (outcome === "repaired" ? 1 : 0),
232
- bounceCount: current.bounceCount + (outcome === "bounced" ? 1 : 0),
233
- lastUsedAt: at,
234
- };
235
- host.stats[storageKey] = next;
236
- host.stats = trimStats(host.stats);
237
- this.save(file);
238
- return { ...next };
186
+ return this.storage.mutateCurrentHost((host) => this.createHostData(host), (host) => {
187
+ const storageKey = statKey(key);
188
+ const current = host.stats[storageKey] ?? emptyStats(key, at);
189
+ const next = {
190
+ ...current,
191
+ repairCount: current.repairCount + (outcome === "repaired" ? 1 : 0),
192
+ bounceCount: current.bounceCount + (outcome === "bounced" ? 1 : 0),
193
+ lastUsedAt: at,
194
+ };
195
+ host.stats[storageKey] = next;
196
+ host.stats = trimStats(host.stats);
197
+ return { result: { ...next }, changed: true };
198
+ });
239
199
  }
240
200
  recordExecution(observation) {
241
201
  const at = observation.at ?? new Date().toISOString();
242
- const file = this.load();
243
- const host = this.hostData(file);
244
- const storageKey = statKey(observation.key);
245
- const current = host.stats[storageKey] ?? emptyStats(observation.key, at);
246
- const latencyMs = finiteNonNegative(observation.latencyMs);
247
- const inputTokenEstimate = finiteNonNegative(observation.inputTokenEstimate);
248
- const outputTokenEstimate = finiteNonNegative(observation.outputTokenEstimate);
249
- const next = {
250
- ...current,
251
- alpha: current.alpha + (observation.success ? 1 : 0),
252
- beta: current.beta + (observation.success ? 0 : 1),
253
- sampleCount: current.sampleCount + 1,
254
- latencyEwmaMs: updateEwma(current.latencyEwmaMs, latencyMs),
255
- latencyDeviationEwmaMs: updateDeviation(current.latencyEwmaMs, current.latencyDeviationEwmaMs, latencyMs),
256
- inputTokenEstimateEwma: updateEwma(current.inputTokenEstimateEwma, inputTokenEstimate),
257
- outputTokenEstimateEwma: updateEwma(current.outputTokenEstimateEwma, outputTokenEstimate),
258
- failureCount: current.failureCount + (observation.success ? 0 : 1),
259
- lastUsedAt: at,
260
- };
261
- host.stats[storageKey] = next;
262
- host.stats = trimStats(host.stats);
263
- host.observations.push({
264
- ...observation.selection,
265
- at,
266
- modelRef: observation.key.modelRef,
267
- intentClass: observation.key.intentClass,
268
- actualTool: observation.key.tool,
269
- succeeded: observation.success,
270
- ranked: observation.selection.ranked.slice(0, 6),
271
- shortlist: observation.selection.shortlist.slice(0, 3),
272
- latencyMs,
273
- inputTokenEstimate,
274
- outputTokenEstimate,
202
+ return this.storage.mutateCurrentHost((host) => this.createHostData(host), (host) => {
203
+ const storageKey = statKey(observation.key);
204
+ const current = host.stats[storageKey] ?? emptyStats(observation.key, at);
205
+ const latencyMs = finiteNonNegative(observation.latencyMs);
206
+ const inputTokenEstimate = finiteNonNegative(observation.inputTokenEstimate);
207
+ const outputTokenEstimate = finiteNonNegative(observation.outputTokenEstimate);
208
+ const next = {
209
+ ...current,
210
+ alpha: current.alpha + (observation.success ? 1 : 0),
211
+ beta: current.beta + (observation.success ? 0 : 1),
212
+ sampleCount: current.sampleCount + 1,
213
+ latencyEwmaMs: updateEwma(current.latencyEwmaMs, latencyMs),
214
+ latencyDeviationEwmaMs: updateDeviation(current.latencyEwmaMs, current.latencyDeviationEwmaMs, latencyMs),
215
+ inputTokenEstimateEwma: updateEwma(current.inputTokenEstimateEwma, inputTokenEstimate),
216
+ outputTokenEstimateEwma: updateEwma(current.outputTokenEstimateEwma, outputTokenEstimate),
217
+ failureCount: current.failureCount + (observation.success ? 0 : 1),
218
+ lastUsedAt: at,
219
+ };
220
+ host.stats[storageKey] = next;
221
+ host.stats = trimStats(host.stats);
222
+ host.observations.push({
223
+ ...observation.selection,
224
+ at,
225
+ modelRef: observation.key.modelRef,
226
+ intentClass: observation.key.intentClass,
227
+ actualTool: observation.key.tool,
228
+ succeeded: observation.success,
229
+ ranked: observation.selection.ranked.slice(0, 6),
230
+ shortlist: observation.selection.shortlist.slice(0, 3),
231
+ latencyMs,
232
+ inputTokenEstimate,
233
+ outputTokenEstimate,
234
+ });
235
+ if (host.observations.length > MAX_OBSERVATIONS_PER_HOST) {
236
+ host.observations = host.observations.slice(-MAX_OBSERVATIONS_PER_HOST);
237
+ }
238
+ // Observe-mode agreement: did the RAW ranking's top pick (before any actual-tool-only
239
+ // eligibility gating) match what the model actually called? Recorded durably per
240
+ // (model,intent), separate from the capped `observations` log above, so it survives trimming.
241
+ const predictedBest = observation.selection.ranked[0]?.tool;
242
+ const agreed = predictedBest !== undefined && predictedBest === observation.key.tool;
243
+ const agreementKey = intentAgreementKey(observation.key.modelRef, observation.key.intentClass);
244
+ const currentAgreement = host.intentAgreement[agreementKey] ??
245
+ emptyIntentAgreement(observation.key.modelRef, observation.key.intentClass, at);
246
+ host.intentAgreement[agreementKey] = {
247
+ ...currentAgreement,
248
+ sampleCount: currentAgreement.sampleCount + 1,
249
+ agreementCount: currentAgreement.agreementCount + (agreed ? 1 : 0),
250
+ hintActiveSampleCount: currentAgreement.hintActiveSampleCount + (observation.hintActiveAtCallTime ? 1 : 0),
251
+ hintActiveAgreementCount: currentAgreement.hintActiveAgreementCount + (observation.hintActiveAtCallTime && agreed ? 1 : 0),
252
+ lastUpdatedAt: at,
253
+ };
254
+ host.intentAgreement = trimIntentAgreement(host.intentAgreement);
255
+ return { result: { ...next }, changed: true };
275
256
  });
276
- if (host.observations.length > MAX_OBSERVATIONS_PER_HOST) {
277
- host.observations = host.observations.slice(-MAX_OBSERVATIONS_PER_HOST);
278
- }
279
- // Observe-mode agreement: did the RAW ranking's top pick (before any actual-tool-only
280
- // eligibility gating) match what the model actually called? Recorded durably per
281
- // (model,intent), separate from the capped `observations` log above, so it survives trimming.
282
- const predictedBest = observation.selection.ranked[0]?.tool;
283
- const agreed = predictedBest !== undefined && predictedBest === observation.key.tool;
284
- const agreementKey = intentAgreementKey(observation.key.modelRef, observation.key.intentClass);
285
- const currentAgreement = host.intentAgreement[agreementKey] ??
286
- emptyIntentAgreement(observation.key.modelRef, observation.key.intentClass, at);
287
- host.intentAgreement[agreementKey] = {
288
- ...currentAgreement,
289
- sampleCount: currentAgreement.sampleCount + 1,
290
- agreementCount: currentAgreement.agreementCount + (agreed ? 1 : 0),
291
- hintActiveSampleCount: currentAgreement.hintActiveSampleCount + (observation.hintActiveAtCallTime ? 1 : 0),
292
- hintActiveAgreementCount: currentAgreement.hintActiveAgreementCount + (observation.hintActiveAtCallTime && agreed ? 1 : 0),
293
- lastUpdatedAt: at,
294
- };
295
- host.intentAgreement = trimIntentAgreement(host.intentAgreement);
296
- this.save(file);
297
- return { ...next };
298
257
  }
299
258
  getMetrics(modelRef) {
300
- const host = this.load().hosts[this.fingerprint().id];
259
+ const host = this.storage.getHost();
301
260
  const observations = (host?.observations ?? []).filter((observation) => modelRef === undefined || observation.modelRef === modelRef);
302
261
  const firstTools = observations.filter((observation) => observation.firstTool);
303
262
  const recommended = observations.filter((observation) => observation.disposition === "recommend");
@@ -320,7 +279,7 @@ export class ToolPerformanceStore {
320
279
  };
321
280
  }
322
281
  getObservations(modelRef) {
323
- const host = this.load().hosts[this.fingerprint().id];
282
+ const host = this.storage.getHost();
324
283
  return (host?.observations ?? [])
325
284
  .filter((observation) => modelRef === undefined || observation.modelRef === modelRef)
326
285
  .map((observation) => ({
@@ -1 +1 @@
1
- {"version":3,"file":"tool-performance-store.js","sourceRoot":"","sources":["../../../src/core/tool-selection/tool-performance-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { stateFile } from \"../agent-paths.ts\";\nimport { currentHostFingerprint, type HostFingerprint } from \"../models/fitness-store.ts\";\nimport { isWorkerSession } from \"../session-role.ts\";\n\nconst STORE_VERSION = 1;\nconst MAX_STATS_PER_HOST = 500;\nconst MAX_OBSERVATIONS_PER_HOST = 1_000;\nconst MAX_INTENT_AGREEMENT_PER_HOST = 500;\nconst EWMA_ALPHA = 0.25;\n\nexport type ToolSelectionIntentClass = \"read\" | \"search\" | \"execute\" | \"write\" | \"retrieve\" | \"explain\" | \"other\";\n\nexport interface ToolPerformanceKey {\n\tmodelRef: string;\n\tintentClass: ToolSelectionIntentClass;\n\ttool: string;\n}\n\nexport interface ToolPerformanceStats extends ToolPerformanceKey {\n\talpha: number;\n\tbeta: number;\n\tsampleCount: number;\n\tlatencyEwmaMs?: number;\n\tlatencyDeviationEwmaMs?: number;\n\tinputTokenEstimateEwma?: number;\n\toutputTokenEstimateEwma?: number;\n\trepairCount: number;\n\tbounceCount: number;\n\tfailureCount: number;\n\tlastUsedAt: string;\n}\n\nexport interface ToolSelectionObservation {\n\tat: string;\n\tmodelRef: string;\n\tintentClass: ToolSelectionIntentClass;\n\tactualTool: string;\n\tfirstTool: boolean;\n\tsucceeded: boolean;\n\tdisposition: \"recommend\" | \"shortlist\" | \"abstain\";\n\trecommendation?: string;\n\tshortlist: string[];\n\tentropy: number;\n\tmargin: number;\n\t/** Redacted ranking: names and numeric scores only, never prompts, arguments, paths, or output. */\n\tranked: Array<{ tool: string; utility: number; probability: number }>;\n\tlatencyMs?: number;\n\tinputTokenEstimate?: number;\n\toutputTokenEstimate?: number;\n}\n\nexport interface ToolSelectionMetrics {\n\tfirstToolAttempts: number;\n\tfirstToolSuccesses: number;\n\twrongToolOrFailureCount: number;\n\trecommendationCount: number;\n\trecommendationMatchedCount: number;\n\tshortlistCount: number;\n\tabstentionCount: number;\n\taverageLatencyMs?: number;\n\taverageInputTokenEstimate?: number;\n\taverageOutputTokenEstimate?: number;\n}\n\n/**\n * Durable, per-(model,intent) aggregate of the observe-mode loop: does the raw expected-utility\n * ranking's top pick (`ToolSelectionObservation.ranked[0]`) match what the model actually called\n * (`ToolSelectionObservation.actualTool`)? Tracked separately from the capped, rolling\n * `observations` log so evidence for a given (model,intent) pair survives that log's trimming.\n * `hintActive*` fields are the SAME agreement measure, but restricted to calls made while an\n * evidence-gated promotion hint (see promotion.ts) was active for this bucket — the hint's own\n * efficacy trace: it never gates activation directly (that is always\n * recomputed live from `ToolPerformanceStats`), but it is the durable evidence a report can show\n * for \"is the hint still earning its keep\".\n */\nexport interface ToolSelectionIntentAgreement {\n\tmodelRef: string;\n\tintentClass: ToolSelectionIntentClass;\n\tsampleCount: number;\n\tagreementCount: number;\n\thintActiveSampleCount: number;\n\thintActiveAgreementCount: number;\n\tlastUpdatedAt: string;\n}\n\ninterface HostToolPerformanceData {\n\thost: HostFingerprint;\n\tstats: Record<string, ToolPerformanceStats>;\n\tobservations: ToolSelectionObservation[];\n\tintentAgreement: Record<string, ToolSelectionIntentAgreement>;\n}\n\ninterface ToolPerformanceStoreFile {\n\tversion: 1;\n\thosts: Record<string, HostToolPerformanceData>;\n}\n\nexport interface ToolExecutionObservation {\n\tkey: ToolPerformanceKey;\n\tsuccess: boolean;\n\tlatencyMs: number;\n\tinputTokenEstimate?: number;\n\toutputTokenEstimate?: number;\n\tselection: Omit<ToolSelectionObservation, \"at\" | \"modelRef\" | \"intentClass\" | \"actualTool\" | \"succeeded\">;\n\tat?: string;\n\t/**\n\t * Whether an evidence-gated promotion hint (promotion.ts) was already active for this\n\t * (model,intent) bucket BEFORE this call was recorded — captured by the controller at\n\t * `begin()` time, so it reflects evidence up to but not including this observation. Used only\n\t * to bucket the durable agreement stats (`ToolSelectionIntentAgreement.hintActive*`); never\n\t * changes what gets recorded, only how it is split for the efficacy report.\n\t */\n\thintActiveAtCallTime?: boolean;\n}\n\nfunction statKey(key: ToolPerformanceKey): string {\n\treturn `${key.modelRef}\\0${key.intentClass}\\0${key.tool}`;\n}\n\nfunction intentAgreementKey(modelRef: string, intentClass: ToolSelectionIntentClass): string {\n\treturn `${modelRef}\\0${intentClass}`;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isIntentClass(value: unknown): value is ToolSelectionIntentClass {\n\treturn (\n\t\tvalue === \"read\" ||\n\t\tvalue === \"search\" ||\n\t\tvalue === \"execute\" ||\n\t\tvalue === \"write\" ||\n\t\tvalue === \"retrieve\" ||\n\t\tvalue === \"explain\" ||\n\t\tvalue === \"other\"\n\t);\n}\n\nfunction isStats(value: unknown): value is ToolPerformanceStats {\n\treturn (\n\t\tisRecord(value) &&\n\t\ttypeof value.modelRef === \"string\" &&\n\t\tisIntentClass(value.intentClass) &&\n\t\ttypeof value.tool === \"string\" &&\n\t\ttypeof value.alpha === \"number\" &&\n\t\ttypeof value.beta === \"number\" &&\n\t\ttypeof value.sampleCount === \"number\" &&\n\t\ttypeof value.repairCount === \"number\" &&\n\t\ttypeof value.bounceCount === \"number\" &&\n\t\ttypeof value.failureCount === \"number\" &&\n\t\ttypeof value.lastUsedAt === \"string\"\n\t);\n}\n\nfunction isObservation(value: unknown): value is ToolSelectionObservation {\n\treturn (\n\t\tisRecord(value) &&\n\t\ttypeof value.at === \"string\" &&\n\t\ttypeof value.modelRef === \"string\" &&\n\t\tisIntentClass(value.intentClass) &&\n\t\ttypeof value.actualTool === \"string\" &&\n\t\ttypeof value.firstTool === \"boolean\" &&\n\t\ttypeof value.succeeded === \"boolean\" &&\n\t\t(value.disposition === \"recommend\" || value.disposition === \"shortlist\" || value.disposition === \"abstain\") &&\n\t\tArray.isArray(value.shortlist) &&\n\t\tvalue.shortlist.every((tool) => typeof tool === \"string\") &&\n\t\ttypeof value.entropy === \"number\" &&\n\t\ttypeof value.margin === \"number\" &&\n\t\tArray.isArray(value.ranked) &&\n\t\tvalue.ranked.every(\n\t\t\t(entry) =>\n\t\t\t\tisRecord(entry) &&\n\t\t\t\ttypeof entry.tool === \"string\" &&\n\t\t\t\ttypeof entry.utility === \"number\" &&\n\t\t\t\ttypeof entry.probability === \"number\",\n\t\t) &&\n\t\t(value.latencyMs === undefined || typeof value.latencyMs === \"number\") &&\n\t\t(value.inputTokenEstimate === undefined || typeof value.inputTokenEstimate === \"number\") &&\n\t\t(value.outputTokenEstimate === undefined || typeof value.outputTokenEstimate === \"number\")\n\t);\n}\n\nfunction isIntentAgreement(value: unknown): value is ToolSelectionIntentAgreement {\n\treturn (\n\t\tisRecord(value) &&\n\t\ttypeof value.modelRef === \"string\" &&\n\t\tisIntentClass(value.intentClass) &&\n\t\ttypeof value.sampleCount === \"number\" &&\n\t\ttypeof value.agreementCount === \"number\" &&\n\t\ttypeof value.hintActiveSampleCount === \"number\" &&\n\t\ttypeof value.hintActiveAgreementCount === \"number\" &&\n\t\ttypeof value.lastUpdatedAt === \"string\"\n\t);\n}\n\nfunction emptyStats(key: ToolPerformanceKey, at: string): ToolPerformanceStats {\n\treturn {\n\t\t...key,\n\t\talpha: 1,\n\t\tbeta: 1,\n\t\tsampleCount: 0,\n\t\trepairCount: 0,\n\t\tbounceCount: 0,\n\t\tfailureCount: 0,\n\t\tlastUsedAt: at,\n\t};\n}\n\nfunction emptyIntentAgreement(\n\tmodelRef: string,\n\tintentClass: ToolSelectionIntentClass,\n\tat: string,\n): ToolSelectionIntentAgreement {\n\treturn {\n\t\tmodelRef,\n\t\tintentClass,\n\t\tsampleCount: 0,\n\t\tagreementCount: 0,\n\t\thintActiveSampleCount: 0,\n\t\thintActiveAgreementCount: 0,\n\t\tlastUpdatedAt: at,\n\t};\n}\n\nfunction finiteNonNegative(value: number | undefined): number | undefined {\n\treturn typeof value === \"number\" && Number.isFinite(value) && value >= 0 ? value : undefined;\n}\n\nfunction updateEwma(previous: number | undefined, next: number | undefined): number | undefined {\n\tif (next === undefined) return previous;\n\treturn previous === undefined ? next : previous + EWMA_ALPHA * (next - previous);\n}\n\nfunction updateDeviation(\n\tpreviousValue: number | undefined,\n\tpreviousDeviation: number | undefined,\n\tnext: number | undefined,\n): number | undefined {\n\tif (next === undefined) return previousDeviation;\n\tconst deviation = previousValue === undefined ? 0 : Math.abs(next - previousValue);\n\treturn updateEwma(previousDeviation, deviation);\n}\n\nfunction parseHost(value: unknown): HostToolPerformanceData | undefined {\n\tif (!isRecord(value) || !isRecord(value.host) || !isRecord(value.stats) || !Array.isArray(value.observations))\n\t\treturn undefined;\n\tconst host = value.host;\n\tif (\n\t\ttypeof host.id !== \"string\" ||\n\t\ttypeof host.cpu !== \"string\" ||\n\t\ttypeof host.cores !== \"number\" ||\n\t\ttypeof host.totalMemGb !== \"number\"\n\t)\n\t\treturn undefined;\n\t// intentAgreement is a purely additive field (older store files predate it) — tolerate absence\n\t// rather than bumping STORE_VERSION, same as any other backward-compatible default-empty field.\n\tconst intentAgreementRaw = isRecord(value.intentAgreement) ? value.intentAgreement : {};\n\treturn {\n\t\thost: { id: host.id, cpu: host.cpu, cores: host.cores, totalMemGb: host.totalMemGb },\n\t\tstats: Object.fromEntries(\n\t\t\tObject.entries(value.stats).filter((entry): entry is [string, ToolPerformanceStats] => isStats(entry[1])),\n\t\t),\n\t\tobservations: value.observations.filter(isObservation),\n\t\tintentAgreement: Object.fromEntries(\n\t\t\tObject.entries(intentAgreementRaw).filter((entry): entry is [string, ToolSelectionIntentAgreement] =>\n\t\t\t\tisIntentAgreement(entry[1]),\n\t\t\t),\n\t\t),\n\t};\n}\n\nfunction parseFile(value: unknown): ToolPerformanceStoreFile {\n\tif (!isRecord(value) || value.version !== STORE_VERSION || !isRecord(value.hosts)) {\n\t\treturn { version: STORE_VERSION, hosts: {} };\n\t}\n\treturn {\n\t\tversion: STORE_VERSION,\n\t\thosts: Object.fromEntries(\n\t\t\tObject.entries(value.hosts)\n\t\t\t\t.map(([hostId, host]) => [hostId, parseHost(host)] as const)\n\t\t\t\t.filter((entry): entry is readonly [string, HostToolPerformanceData] => entry[1] !== undefined),\n\t\t),\n\t};\n}\n\nfunction trimStats(stats: Record<string, ToolPerformanceStats>): Record<string, ToolPerformanceStats> {\n\tconst entries = Object.entries(stats);\n\tif (entries.length <= MAX_STATS_PER_HOST) return stats;\n\treturn Object.fromEntries(\n\t\tentries\n\t\t\t.sort(([, left], [, right]) => Date.parse(right.lastUsedAt) - Date.parse(left.lastUsedAt))\n\t\t\t.slice(0, MAX_STATS_PER_HOST),\n\t);\n}\n\nfunction trimIntentAgreement(\n\trecords: Record<string, ToolSelectionIntentAgreement>,\n): Record<string, ToolSelectionIntentAgreement> {\n\tconst entries = Object.entries(records);\n\tif (entries.length <= MAX_INTENT_AGREEMENT_PER_HOST) return records;\n\treturn Object.fromEntries(\n\t\tentries\n\t\t\t.sort(([, left], [, right]) => Date.parse(right.lastUpdatedAt) - Date.parse(left.lastUpdatedAt))\n\t\t\t.slice(0, MAX_INTENT_AGREEMENT_PER_HOST),\n\t);\n}\n\nexport class ToolPerformanceStore {\n\tprivate readonly filePath: string;\n\tprivate readonly fingerprint: () => HostFingerprint;\n\tprivate readonly readOnly: boolean;\n\n\tconstructor(filePath: string, options: { fingerprint?: () => HostFingerprint; readOnly?: boolean } = {}) {\n\t\tthis.filePath = filePath;\n\t\tthis.fingerprint = options.fingerprint ?? currentHostFingerprint;\n\t\tthis.readOnly = options.readOnly ?? isWorkerSession();\n\t}\n\n\tstatic forAgentDir(\n\t\tagentDir: string,\n\t\toptions: { fingerprint?: () => HostFingerprint; readOnly?: boolean } = {},\n\t): ToolPerformanceStore {\n\t\treturn new ToolPerformanceStore(stateFile(agentDir, \"tool-performance.json\"), options);\n\t}\n\n\tprivate load(): ToolPerformanceStoreFile {\n\t\ttry {\n\t\t\tif (!existsSync(this.filePath)) return { version: STORE_VERSION, hosts: {} };\n\t\t\treturn parseFile(JSON.parse(readFileSync(this.filePath, \"utf8\")));\n\t\t} catch {\n\t\t\treturn { version: STORE_VERSION, hosts: {} };\n\t\t}\n\t}\n\n\tprivate save(file: ToolPerformanceStoreFile): void {\n\t\t// Zero-footprint (worker session): never create the state dir, lock, or file -- the caller\n\t\t// still gets its normally-computed return value from the in-memory `file`.\n\t\tif (this.readOnly) return;\n\t\tmkdirSync(dirname(this.filePath), { recursive: true });\n\t\twriteFileSync(this.filePath, `${JSON.stringify(file, null, \"\\t\")}\\n`, \"utf8\");\n\t}\n\n\tprivate hostData(file: ToolPerformanceStoreFile): HostToolPerformanceData {\n\t\tconst fingerprint = this.fingerprint();\n\t\tconst existing = file.hosts[fingerprint.id];\n\t\tif (existing) return existing;\n\t\tconst created: HostToolPerformanceData = { host: fingerprint, stats: {}, observations: [], intentAgreement: {} };\n\t\tfile.hosts[fingerprint.id] = created;\n\t\treturn created;\n\t}\n\n\tget(key: ToolPerformanceKey): ToolPerformanceStats {\n\t\tconst file = this.load();\n\t\tconst host = file.hosts[this.fingerprint().id];\n\t\tconst stats = host?.stats[statKey(key)];\n\t\treturn stats ? { ...stats } : emptyStats(key, new Date(0).toISOString());\n\t}\n\n\t/** Every per-tool track record recorded for a (model,intent) bucket — the promotion.ts input. */\n\tgetStatsForIntent(modelRef: string, intentClass: ToolSelectionIntentClass): ToolPerformanceStats[] {\n\t\tconst host = this.load().hosts[this.fingerprint().id];\n\t\tif (!host) return [];\n\t\treturn Object.values(host.stats)\n\t\t\t.filter((stats) => stats.modelRef === modelRef && stats.intentClass === intentClass)\n\t\t\t.map((stats) => ({ ...stats }));\n\t}\n\n\t/** Durable observe-mode agreement for one (model,intent) bucket (see {@link ToolSelectionIntentAgreement}). */\n\tgetIntentAgreement(modelRef: string, intentClass: ToolSelectionIntentClass): ToolSelectionIntentAgreement {\n\t\tconst host = this.load().hosts[this.fingerprint().id];\n\t\tconst record = host?.intentAgreement[intentAgreementKey(modelRef, intentClass)];\n\t\treturn record ? { ...record } : emptyIntentAgreement(modelRef, intentClass, new Date(0).toISOString());\n\t}\n\n\t/** All recorded (model,intent) agreement buckets, optionally scoped to one model — report input. */\n\tgetAllIntentAgreements(modelRef?: string): ToolSelectionIntentAgreement[] {\n\t\tconst host = this.load().hosts[this.fingerprint().id];\n\t\treturn Object.values(host?.intentAgreement ?? {})\n\t\t\t.filter((record) => modelRef === undefined || record.modelRef === modelRef)\n\t\t\t.map((record) => ({ ...record }));\n\t}\n\n\trecordValidation(\n\t\tkey: ToolPerformanceKey,\n\t\toutcome: \"repaired\" | \"bounced\",\n\t\tat = new Date().toISOString(),\n\t): ToolPerformanceStats {\n\t\tconst file = this.load();\n\t\tconst host = this.hostData(file);\n\t\tconst storageKey = statKey(key);\n\t\tconst current = host.stats[storageKey] ?? emptyStats(key, at);\n\t\tconst next: ToolPerformanceStats = {\n\t\t\t...current,\n\t\t\trepairCount: current.repairCount + (outcome === \"repaired\" ? 1 : 0),\n\t\t\tbounceCount: current.bounceCount + (outcome === \"bounced\" ? 1 : 0),\n\t\t\tlastUsedAt: at,\n\t\t};\n\t\thost.stats[storageKey] = next;\n\t\thost.stats = trimStats(host.stats);\n\t\tthis.save(file);\n\t\treturn { ...next };\n\t}\n\n\trecordExecution(observation: ToolExecutionObservation): ToolPerformanceStats {\n\t\tconst at = observation.at ?? new Date().toISOString();\n\t\tconst file = this.load();\n\t\tconst host = this.hostData(file);\n\t\tconst storageKey = statKey(observation.key);\n\t\tconst current = host.stats[storageKey] ?? emptyStats(observation.key, at);\n\t\tconst latencyMs = finiteNonNegative(observation.latencyMs);\n\t\tconst inputTokenEstimate = finiteNonNegative(observation.inputTokenEstimate);\n\t\tconst outputTokenEstimate = finiteNonNegative(observation.outputTokenEstimate);\n\t\tconst next: ToolPerformanceStats = {\n\t\t\t...current,\n\t\t\talpha: current.alpha + (observation.success ? 1 : 0),\n\t\t\tbeta: current.beta + (observation.success ? 0 : 1),\n\t\t\tsampleCount: current.sampleCount + 1,\n\t\t\tlatencyEwmaMs: updateEwma(current.latencyEwmaMs, latencyMs),\n\t\t\tlatencyDeviationEwmaMs: updateDeviation(current.latencyEwmaMs, current.latencyDeviationEwmaMs, latencyMs),\n\t\t\tinputTokenEstimateEwma: updateEwma(current.inputTokenEstimateEwma, inputTokenEstimate),\n\t\t\toutputTokenEstimateEwma: updateEwma(current.outputTokenEstimateEwma, outputTokenEstimate),\n\t\t\tfailureCount: current.failureCount + (observation.success ? 0 : 1),\n\t\t\tlastUsedAt: at,\n\t\t};\n\t\thost.stats[storageKey] = next;\n\t\thost.stats = trimStats(host.stats);\n\t\thost.observations.push({\n\t\t\t...observation.selection,\n\t\t\tat,\n\t\t\tmodelRef: observation.key.modelRef,\n\t\t\tintentClass: observation.key.intentClass,\n\t\t\tactualTool: observation.key.tool,\n\t\t\tsucceeded: observation.success,\n\t\t\tranked: observation.selection.ranked.slice(0, 6),\n\t\t\tshortlist: observation.selection.shortlist.slice(0, 3),\n\t\t\tlatencyMs,\n\t\t\tinputTokenEstimate,\n\t\t\toutputTokenEstimate,\n\t\t});\n\t\tif (host.observations.length > MAX_OBSERVATIONS_PER_HOST) {\n\t\t\thost.observations = host.observations.slice(-MAX_OBSERVATIONS_PER_HOST);\n\t\t}\n\n\t\t// Observe-mode agreement: did the RAW ranking's top pick (before any actual-tool-only\n\t\t// eligibility gating) match what the model actually called? Recorded durably per\n\t\t// (model,intent), separate from the capped `observations` log above, so it survives trimming.\n\t\tconst predictedBest = observation.selection.ranked[0]?.tool;\n\t\tconst agreed = predictedBest !== undefined && predictedBest === observation.key.tool;\n\t\tconst agreementKey = intentAgreementKey(observation.key.modelRef, observation.key.intentClass);\n\t\tconst currentAgreement =\n\t\t\thost.intentAgreement[agreementKey] ??\n\t\t\temptyIntentAgreement(observation.key.modelRef, observation.key.intentClass, at);\n\t\thost.intentAgreement[agreementKey] = {\n\t\t\t...currentAgreement,\n\t\t\tsampleCount: currentAgreement.sampleCount + 1,\n\t\t\tagreementCount: currentAgreement.agreementCount + (agreed ? 1 : 0),\n\t\t\thintActiveSampleCount: currentAgreement.hintActiveSampleCount + (observation.hintActiveAtCallTime ? 1 : 0),\n\t\t\thintActiveAgreementCount:\n\t\t\t\tcurrentAgreement.hintActiveAgreementCount + (observation.hintActiveAtCallTime && agreed ? 1 : 0),\n\t\t\tlastUpdatedAt: at,\n\t\t};\n\t\thost.intentAgreement = trimIntentAgreement(host.intentAgreement);\n\n\t\tthis.save(file);\n\t\treturn { ...next };\n\t}\n\n\tgetMetrics(modelRef?: string): ToolSelectionMetrics {\n\t\tconst host = this.load().hosts[this.fingerprint().id];\n\t\tconst observations = (host?.observations ?? []).filter(\n\t\t\t(observation) => modelRef === undefined || observation.modelRef === modelRef,\n\t\t);\n\t\tconst firstTools = observations.filter((observation) => observation.firstTool);\n\t\tconst recommended = observations.filter((observation) => observation.disposition === \"recommend\");\n\t\tconst average = (values: Array<number | undefined>): number | undefined => {\n\t\t\tconst present = values.filter((value): value is number => value !== undefined);\n\t\t\treturn present.length > 0 ? present.reduce((sum, value) => sum + value, 0) / present.length : undefined;\n\t\t};\n\t\treturn {\n\t\t\tfirstToolAttempts: firstTools.length,\n\t\t\tfirstToolSuccesses: firstTools.filter((observation) => observation.succeeded).length,\n\t\t\twrongToolOrFailureCount: observations.filter(\n\t\t\t\t(observation) =>\n\t\t\t\t\t!observation.succeeded ||\n\t\t\t\t\t(observation.disposition === \"recommend\" && observation.recommendation !== observation.actualTool),\n\t\t\t).length,\n\t\t\trecommendationCount: recommended.length,\n\t\t\trecommendationMatchedCount: recommended.filter(\n\t\t\t\t(observation) => observation.recommendation === observation.actualTool,\n\t\t\t).length,\n\t\t\tshortlistCount: observations.filter((observation) => observation.disposition === \"shortlist\").length,\n\t\t\tabstentionCount: observations.filter((observation) => observation.disposition === \"abstain\").length,\n\t\t\taverageLatencyMs: average(observations.map((observation) => observation.latencyMs)),\n\t\t\taverageInputTokenEstimate: average(observations.map((observation) => observation.inputTokenEstimate)),\n\t\t\taverageOutputTokenEstimate: average(observations.map((observation) => observation.outputTokenEstimate)),\n\t\t};\n\t}\n\n\tgetObservations(modelRef?: string): ToolSelectionObservation[] {\n\t\tconst host = this.load().hosts[this.fingerprint().id];\n\t\treturn (host?.observations ?? [])\n\t\t\t.filter((observation) => modelRef === undefined || observation.modelRef === modelRef)\n\t\t\t.map((observation) => ({\n\t\t\t\t...observation,\n\t\t\t\tshortlist: [...observation.shortlist],\n\t\t\t\tranked: observation.ranked.map((candidate) => ({ ...candidate })),\n\t\t\t}));\n\t}\n}\n"]}
1
+ {"version":3,"file":"tool-performance-store.js","sourceRoot":"","sources":["../../../src/core/tool-selection/tool-performance-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { stateFile } from \"../agent-paths.ts\";\nimport { type HostFingerprint, HostStateStore, isHostFingerprint } from \"../models/host-state-store.ts\";\nimport { isWorkerSession } from \"../session-role.ts\";\nimport { isRecordObject } from \"../util/value-guards.ts\";\n\nconst STORE_VERSION = 1;\nconst MAX_STATS_PER_HOST = 500;\nconst MAX_OBSERVATIONS_PER_HOST = 1_000;\nconst MAX_INTENT_AGREEMENT_PER_HOST = 500;\nconst EWMA_ALPHA = 0.25;\n\nexport type ToolSelectionIntentClass = \"read\" | \"search\" | \"execute\" | \"write\" | \"retrieve\" | \"explain\" | \"other\";\n\nexport interface ToolPerformanceKey {\n\tmodelRef: string;\n\tintentClass: ToolSelectionIntentClass;\n\ttool: string;\n}\n\nexport interface ToolPerformanceStats extends ToolPerformanceKey {\n\talpha: number;\n\tbeta: number;\n\tsampleCount: number;\n\tlatencyEwmaMs?: number;\n\tlatencyDeviationEwmaMs?: number;\n\tinputTokenEstimateEwma?: number;\n\toutputTokenEstimateEwma?: number;\n\trepairCount: number;\n\tbounceCount: number;\n\tfailureCount: number;\n\tlastUsedAt: string;\n}\n\nexport interface ToolSelectionObservation {\n\tat: string;\n\tmodelRef: string;\n\tintentClass: ToolSelectionIntentClass;\n\tactualTool: string;\n\tfirstTool: boolean;\n\tsucceeded: boolean;\n\tdisposition: \"recommend\" | \"shortlist\" | \"abstain\";\n\trecommendation?: string;\n\tshortlist: string[];\n\tentropy: number;\n\tmargin: number;\n\t/** Redacted ranking: names and numeric scores only, never prompts, arguments, paths, or output. */\n\tranked: Array<{ tool: string; utility: number; probability: number }>;\n\tlatencyMs?: number;\n\tinputTokenEstimate?: number;\n\toutputTokenEstimate?: number;\n}\n\nexport interface ToolSelectionMetrics {\n\tfirstToolAttempts: number;\n\tfirstToolSuccesses: number;\n\twrongToolOrFailureCount: number;\n\trecommendationCount: number;\n\trecommendationMatchedCount: number;\n\tshortlistCount: number;\n\tabstentionCount: number;\n\taverageLatencyMs?: number;\n\taverageInputTokenEstimate?: number;\n\taverageOutputTokenEstimate?: number;\n}\n\n/**\n * Durable, per-(model,intent) aggregate of the observe-mode loop: does the raw expected-utility\n * ranking's top pick (`ToolSelectionObservation.ranked[0]`) match what the model actually called\n * (`ToolSelectionObservation.actualTool`)? Tracked separately from the capped, rolling\n * `observations` log so evidence for a given (model,intent) pair survives that log's trimming.\n * `hintActive*` fields are the SAME agreement measure, but restricted to calls made while an\n * evidence-gated promotion hint (see promotion.ts) was active for this bucket — the hint's own\n * efficacy trace: it never gates activation directly (that is always\n * recomputed live from `ToolPerformanceStats`), but it is the durable evidence a report can show\n * for \"is the hint still earning its keep\".\n */\nexport interface ToolSelectionIntentAgreement {\n\tmodelRef: string;\n\tintentClass: ToolSelectionIntentClass;\n\tsampleCount: number;\n\tagreementCount: number;\n\thintActiveSampleCount: number;\n\thintActiveAgreementCount: number;\n\tlastUpdatedAt: string;\n}\n\ninterface HostToolPerformanceData {\n\thost: HostFingerprint;\n\tstats: Record<string, ToolPerformanceStats>;\n\tobservations: ToolSelectionObservation[];\n\tintentAgreement: Record<string, ToolSelectionIntentAgreement>;\n}\n\nexport interface ToolExecutionObservation {\n\tkey: ToolPerformanceKey;\n\tsuccess: boolean;\n\tlatencyMs: number;\n\tinputTokenEstimate?: number;\n\toutputTokenEstimate?: number;\n\tselection: Omit<ToolSelectionObservation, \"at\" | \"modelRef\" | \"intentClass\" | \"actualTool\" | \"succeeded\">;\n\tat?: string;\n\t/**\n\t * Whether an evidence-gated promotion hint (promotion.ts) was already active for this\n\t * (model,intent) bucket BEFORE this call was recorded — captured by the controller at\n\t * `begin()` time, so it reflects evidence up to but not including this observation. Used only\n\t * to bucket the durable agreement stats (`ToolSelectionIntentAgreement.hintActive*`); never\n\t * changes what gets recorded, only how it is split for the efficacy report.\n\t */\n\thintActiveAtCallTime?: boolean;\n}\n\nfunction statKey(key: ToolPerformanceKey): string {\n\treturn `${key.modelRef}\\0${key.intentClass}\\0${key.tool}`;\n}\n\nfunction intentAgreementKey(modelRef: string, intentClass: ToolSelectionIntentClass): string {\n\treturn `${modelRef}\\0${intentClass}`;\n}\n\nfunction isIntentClass(value: unknown): value is ToolSelectionIntentClass {\n\treturn (\n\t\tvalue === \"read\" ||\n\t\tvalue === \"search\" ||\n\t\tvalue === \"execute\" ||\n\t\tvalue === \"write\" ||\n\t\tvalue === \"retrieve\" ||\n\t\tvalue === \"explain\" ||\n\t\tvalue === \"other\"\n\t);\n}\n\nfunction isStats(value: unknown): value is ToolPerformanceStats {\n\treturn (\n\t\tisRecordObject(value) &&\n\t\ttypeof value.modelRef === \"string\" &&\n\t\tisIntentClass(value.intentClass) &&\n\t\ttypeof value.tool === \"string\" &&\n\t\ttypeof value.alpha === \"number\" &&\n\t\ttypeof value.beta === \"number\" &&\n\t\ttypeof value.sampleCount === \"number\" &&\n\t\ttypeof value.repairCount === \"number\" &&\n\t\ttypeof value.bounceCount === \"number\" &&\n\t\ttypeof value.failureCount === \"number\" &&\n\t\ttypeof value.lastUsedAt === \"string\"\n\t);\n}\n\nfunction isObservation(value: unknown): value is ToolSelectionObservation {\n\treturn (\n\t\tisRecordObject(value) &&\n\t\ttypeof value.at === \"string\" &&\n\t\ttypeof value.modelRef === \"string\" &&\n\t\tisIntentClass(value.intentClass) &&\n\t\ttypeof value.actualTool === \"string\" &&\n\t\ttypeof value.firstTool === \"boolean\" &&\n\t\ttypeof value.succeeded === \"boolean\" &&\n\t\t(value.disposition === \"recommend\" || value.disposition === \"shortlist\" || value.disposition === \"abstain\") &&\n\t\tArray.isArray(value.shortlist) &&\n\t\tvalue.shortlist.every((tool) => typeof tool === \"string\") &&\n\t\ttypeof value.entropy === \"number\" &&\n\t\ttypeof value.margin === \"number\" &&\n\t\tArray.isArray(value.ranked) &&\n\t\tvalue.ranked.every(\n\t\t\t(entry) =>\n\t\t\t\tisRecordObject(entry) &&\n\t\t\t\ttypeof entry.tool === \"string\" &&\n\t\t\t\ttypeof entry.utility === \"number\" &&\n\t\t\t\ttypeof entry.probability === \"number\",\n\t\t) &&\n\t\t(value.latencyMs === undefined || typeof value.latencyMs === \"number\") &&\n\t\t(value.inputTokenEstimate === undefined || typeof value.inputTokenEstimate === \"number\") &&\n\t\t(value.outputTokenEstimate === undefined || typeof value.outputTokenEstimate === \"number\")\n\t);\n}\n\nfunction isIntentAgreement(value: unknown): value is ToolSelectionIntentAgreement {\n\treturn (\n\t\tisRecordObject(value) &&\n\t\ttypeof value.modelRef === \"string\" &&\n\t\tisIntentClass(value.intentClass) &&\n\t\ttypeof value.sampleCount === \"number\" &&\n\t\ttypeof value.agreementCount === \"number\" &&\n\t\ttypeof value.hintActiveSampleCount === \"number\" &&\n\t\ttypeof value.hintActiveAgreementCount === \"number\" &&\n\t\ttypeof value.lastUpdatedAt === \"string\"\n\t);\n}\n\nfunction emptyStats(key: ToolPerformanceKey, at: string): ToolPerformanceStats {\n\treturn {\n\t\t...key,\n\t\talpha: 1,\n\t\tbeta: 1,\n\t\tsampleCount: 0,\n\t\trepairCount: 0,\n\t\tbounceCount: 0,\n\t\tfailureCount: 0,\n\t\tlastUsedAt: at,\n\t};\n}\n\nfunction emptyIntentAgreement(\n\tmodelRef: string,\n\tintentClass: ToolSelectionIntentClass,\n\tat: string,\n): ToolSelectionIntentAgreement {\n\treturn {\n\t\tmodelRef,\n\t\tintentClass,\n\t\tsampleCount: 0,\n\t\tagreementCount: 0,\n\t\thintActiveSampleCount: 0,\n\t\thintActiveAgreementCount: 0,\n\t\tlastUpdatedAt: at,\n\t};\n}\n\nfunction finiteNonNegative(value: number | undefined): number | undefined {\n\treturn typeof value === \"number\" && Number.isFinite(value) && value >= 0 ? value : undefined;\n}\n\nfunction updateEwma(previous: number | undefined, next: number | undefined): number | undefined {\n\tif (next === undefined) return previous;\n\treturn previous === undefined ? next : previous + EWMA_ALPHA * (next - previous);\n}\n\nfunction updateDeviation(\n\tpreviousValue: number | undefined,\n\tpreviousDeviation: number | undefined,\n\tnext: number | undefined,\n): number | undefined {\n\tif (next === undefined) return previousDeviation;\n\tconst deviation = previousValue === undefined ? 0 : Math.abs(next - previousValue);\n\treturn updateEwma(previousDeviation, deviation);\n}\n\nfunction parseHost(value: unknown, hostId: string): HostToolPerformanceData | undefined {\n\tif (\n\t\t!isRecordObject(value) ||\n\t\t!isHostFingerprint(value.host) ||\n\t\tvalue.host.id !== hostId ||\n\t\t!isRecordObject(value.stats) ||\n\t\t!Array.isArray(value.observations)\n\t)\n\t\treturn undefined;\n\tconst host = value.host;\n\t// intentAgreement is a purely additive field (older store files predate it) — tolerate absence\n\t// rather than bumping STORE_VERSION, same as any other backward-compatible default-empty field.\n\tconst intentAgreementRaw = isRecordObject(value.intentAgreement) ? value.intentAgreement : {};\n\treturn {\n\t\thost,\n\t\tstats: Object.fromEntries(\n\t\t\tObject.entries(value.stats).filter((entry): entry is [string, ToolPerformanceStats] => isStats(entry[1])),\n\t\t),\n\t\tobservations: value.observations.filter(isObservation),\n\t\tintentAgreement: Object.fromEntries(\n\t\t\tObject.entries(intentAgreementRaw).filter((entry): entry is [string, ToolSelectionIntentAgreement] =>\n\t\t\t\tisIntentAgreement(entry[1]),\n\t\t\t),\n\t\t),\n\t};\n}\n\nfunction trimStats(stats: Record<string, ToolPerformanceStats>): Record<string, ToolPerformanceStats> {\n\tconst entries = Object.entries(stats);\n\tif (entries.length <= MAX_STATS_PER_HOST) return stats;\n\treturn Object.fromEntries(\n\t\tentries\n\t\t\t.sort(([, left], [, right]) => Date.parse(right.lastUsedAt) - Date.parse(left.lastUsedAt))\n\t\t\t.slice(0, MAX_STATS_PER_HOST),\n\t);\n}\n\nfunction trimIntentAgreement(\n\trecords: Record<string, ToolSelectionIntentAgreement>,\n): Record<string, ToolSelectionIntentAgreement> {\n\tconst entries = Object.entries(records);\n\tif (entries.length <= MAX_INTENT_AGREEMENT_PER_HOST) return records;\n\treturn Object.fromEntries(\n\t\tentries\n\t\t\t.sort(([, left], [, right]) => Date.parse(right.lastUpdatedAt) - Date.parse(left.lastUpdatedAt))\n\t\t\t.slice(0, MAX_INTENT_AGREEMENT_PER_HOST),\n\t);\n}\n\nexport class ToolPerformanceStore {\n\tprivate readonly storage: HostStateStore<HostToolPerformanceData>;\n\n\tconstructor(filePath: string, options: { fingerprint?: () => HostFingerprint; readOnly?: boolean } = {}) {\n\t\tthis.storage = new HostStateStore({\n\t\t\tfilePath,\n\t\t\tversion: STORE_VERSION,\n\t\t\tfingerprint: options.fingerprint,\n\t\t\treadOnly: options.readOnly ?? isWorkerSession(),\n\t\t\tparseHost,\n\t\t});\n\t}\n\n\tstatic forAgentDir(\n\t\tagentDir: string,\n\t\toptions: { fingerprint?: () => HostFingerprint; readOnly?: boolean } = {},\n\t): ToolPerformanceStore {\n\t\treturn new ToolPerformanceStore(stateFile(agentDir, \"tool-performance.json\"), options);\n\t}\n\n\tprivate createHostData(host: HostFingerprint): HostToolPerformanceData {\n\t\treturn { host, stats: {}, observations: [], intentAgreement: {} };\n\t}\n\n\tget(key: ToolPerformanceKey): ToolPerformanceStats {\n\t\tconst host = this.storage.getHost();\n\t\tconst stats = host?.stats[statKey(key)];\n\t\treturn stats ? { ...stats } : emptyStats(key, new Date(0).toISOString());\n\t}\n\n\t/** Every per-tool track record recorded for a (model,intent) bucket — the promotion.ts input. */\n\tgetStatsForIntent(modelRef: string, intentClass: ToolSelectionIntentClass): ToolPerformanceStats[] {\n\t\tconst host = this.storage.getHost();\n\t\tif (!host) return [];\n\t\treturn Object.values(host.stats)\n\t\t\t.filter((stats) => stats.modelRef === modelRef && stats.intentClass === intentClass)\n\t\t\t.map((stats) => ({ ...stats }));\n\t}\n\n\t/** Durable observe-mode agreement for one (model,intent) bucket (see {@link ToolSelectionIntentAgreement}). */\n\tgetIntentAgreement(modelRef: string, intentClass: ToolSelectionIntentClass): ToolSelectionIntentAgreement {\n\t\tconst host = this.storage.getHost();\n\t\tconst record = host?.intentAgreement[intentAgreementKey(modelRef, intentClass)];\n\t\treturn record ? { ...record } : emptyIntentAgreement(modelRef, intentClass, new Date(0).toISOString());\n\t}\n\n\t/** All recorded (model,intent) agreement buckets, optionally scoped to one model — report input. */\n\tgetAllIntentAgreements(modelRef?: string): ToolSelectionIntentAgreement[] {\n\t\tconst host = this.storage.getHost();\n\t\treturn Object.values(host?.intentAgreement ?? {})\n\t\t\t.filter((record) => modelRef === undefined || record.modelRef === modelRef)\n\t\t\t.map((record) => ({ ...record }));\n\t}\n\n\trecordValidation(\n\t\tkey: ToolPerformanceKey,\n\t\toutcome: \"repaired\" | \"bounced\",\n\t\tat = new Date().toISOString(),\n\t): ToolPerformanceStats {\n\t\treturn this.storage.mutateCurrentHost(\n\t\t\t(host) => this.createHostData(host),\n\t\t\t(host) => {\n\t\t\t\tconst storageKey = statKey(key);\n\t\t\t\tconst current = host.stats[storageKey] ?? emptyStats(key, at);\n\t\t\t\tconst next: ToolPerformanceStats = {\n\t\t\t\t\t...current,\n\t\t\t\t\trepairCount: current.repairCount + (outcome === \"repaired\" ? 1 : 0),\n\t\t\t\t\tbounceCount: current.bounceCount + (outcome === \"bounced\" ? 1 : 0),\n\t\t\t\t\tlastUsedAt: at,\n\t\t\t\t};\n\t\t\t\thost.stats[storageKey] = next;\n\t\t\t\thost.stats = trimStats(host.stats);\n\t\t\t\treturn { result: { ...next }, changed: true };\n\t\t\t},\n\t\t);\n\t}\n\n\trecordExecution(observation: ToolExecutionObservation): ToolPerformanceStats {\n\t\tconst at = observation.at ?? new Date().toISOString();\n\t\treturn this.storage.mutateCurrentHost(\n\t\t\t(host) => this.createHostData(host),\n\t\t\t(host) => {\n\t\t\t\tconst storageKey = statKey(observation.key);\n\t\t\t\tconst current = host.stats[storageKey] ?? emptyStats(observation.key, at);\n\t\t\t\tconst latencyMs = finiteNonNegative(observation.latencyMs);\n\t\t\t\tconst inputTokenEstimate = finiteNonNegative(observation.inputTokenEstimate);\n\t\t\t\tconst outputTokenEstimate = finiteNonNegative(observation.outputTokenEstimate);\n\t\t\t\tconst next: ToolPerformanceStats = {\n\t\t\t\t\t...current,\n\t\t\t\t\talpha: current.alpha + (observation.success ? 1 : 0),\n\t\t\t\t\tbeta: current.beta + (observation.success ? 0 : 1),\n\t\t\t\t\tsampleCount: current.sampleCount + 1,\n\t\t\t\t\tlatencyEwmaMs: updateEwma(current.latencyEwmaMs, latencyMs),\n\t\t\t\t\tlatencyDeviationEwmaMs: updateDeviation(\n\t\t\t\t\t\tcurrent.latencyEwmaMs,\n\t\t\t\t\t\tcurrent.latencyDeviationEwmaMs,\n\t\t\t\t\t\tlatencyMs,\n\t\t\t\t\t),\n\t\t\t\t\tinputTokenEstimateEwma: updateEwma(current.inputTokenEstimateEwma, inputTokenEstimate),\n\t\t\t\t\toutputTokenEstimateEwma: updateEwma(current.outputTokenEstimateEwma, outputTokenEstimate),\n\t\t\t\t\tfailureCount: current.failureCount + (observation.success ? 0 : 1),\n\t\t\t\t\tlastUsedAt: at,\n\t\t\t\t};\n\t\t\t\thost.stats[storageKey] = next;\n\t\t\t\thost.stats = trimStats(host.stats);\n\t\t\t\thost.observations.push({\n\t\t\t\t\t...observation.selection,\n\t\t\t\t\tat,\n\t\t\t\t\tmodelRef: observation.key.modelRef,\n\t\t\t\t\tintentClass: observation.key.intentClass,\n\t\t\t\t\tactualTool: observation.key.tool,\n\t\t\t\t\tsucceeded: observation.success,\n\t\t\t\t\tranked: observation.selection.ranked.slice(0, 6),\n\t\t\t\t\tshortlist: observation.selection.shortlist.slice(0, 3),\n\t\t\t\t\tlatencyMs,\n\t\t\t\t\tinputTokenEstimate,\n\t\t\t\t\toutputTokenEstimate,\n\t\t\t\t});\n\t\t\t\tif (host.observations.length > MAX_OBSERVATIONS_PER_HOST) {\n\t\t\t\t\thost.observations = host.observations.slice(-MAX_OBSERVATIONS_PER_HOST);\n\t\t\t\t}\n\n\t\t\t\t// Observe-mode agreement: did the RAW ranking's top pick (before any actual-tool-only\n\t\t\t\t// eligibility gating) match what the model actually called? Recorded durably per\n\t\t\t\t// (model,intent), separate from the capped `observations` log above, so it survives trimming.\n\t\t\t\tconst predictedBest = observation.selection.ranked[0]?.tool;\n\t\t\t\tconst agreed = predictedBest !== undefined && predictedBest === observation.key.tool;\n\t\t\t\tconst agreementKey = intentAgreementKey(observation.key.modelRef, observation.key.intentClass);\n\t\t\t\tconst currentAgreement =\n\t\t\t\t\thost.intentAgreement[agreementKey] ??\n\t\t\t\t\temptyIntentAgreement(observation.key.modelRef, observation.key.intentClass, at);\n\t\t\t\thost.intentAgreement[agreementKey] = {\n\t\t\t\t\t...currentAgreement,\n\t\t\t\t\tsampleCount: currentAgreement.sampleCount + 1,\n\t\t\t\t\tagreementCount: currentAgreement.agreementCount + (agreed ? 1 : 0),\n\t\t\t\t\thintActiveSampleCount:\n\t\t\t\t\t\tcurrentAgreement.hintActiveSampleCount + (observation.hintActiveAtCallTime ? 1 : 0),\n\t\t\t\t\thintActiveAgreementCount:\n\t\t\t\t\t\tcurrentAgreement.hintActiveAgreementCount + (observation.hintActiveAtCallTime && agreed ? 1 : 0),\n\t\t\t\t\tlastUpdatedAt: at,\n\t\t\t\t};\n\t\t\t\thost.intentAgreement = trimIntentAgreement(host.intentAgreement);\n\n\t\t\t\treturn { result: { ...next }, changed: true };\n\t\t\t},\n\t\t);\n\t}\n\n\tgetMetrics(modelRef?: string): ToolSelectionMetrics {\n\t\tconst host = this.storage.getHost();\n\t\tconst observations = (host?.observations ?? []).filter(\n\t\t\t(observation) => modelRef === undefined || observation.modelRef === modelRef,\n\t\t);\n\t\tconst firstTools = observations.filter((observation) => observation.firstTool);\n\t\tconst recommended = observations.filter((observation) => observation.disposition === \"recommend\");\n\t\tconst average = (values: Array<number | undefined>): number | undefined => {\n\t\t\tconst present = values.filter((value): value is number => value !== undefined);\n\t\t\treturn present.length > 0 ? present.reduce((sum, value) => sum + value, 0) / present.length : undefined;\n\t\t};\n\t\treturn {\n\t\t\tfirstToolAttempts: firstTools.length,\n\t\t\tfirstToolSuccesses: firstTools.filter((observation) => observation.succeeded).length,\n\t\t\twrongToolOrFailureCount: observations.filter(\n\t\t\t\t(observation) =>\n\t\t\t\t\t!observation.succeeded ||\n\t\t\t\t\t(observation.disposition === \"recommend\" && observation.recommendation !== observation.actualTool),\n\t\t\t).length,\n\t\t\trecommendationCount: recommended.length,\n\t\t\trecommendationMatchedCount: recommended.filter(\n\t\t\t\t(observation) => observation.recommendation === observation.actualTool,\n\t\t\t).length,\n\t\t\tshortlistCount: observations.filter((observation) => observation.disposition === \"shortlist\").length,\n\t\t\tabstentionCount: observations.filter((observation) => observation.disposition === \"abstain\").length,\n\t\t\taverageLatencyMs: average(observations.map((observation) => observation.latencyMs)),\n\t\t\taverageInputTokenEstimate: average(observations.map((observation) => observation.inputTokenEstimate)),\n\t\t\taverageOutputTokenEstimate: average(observations.map((observation) => observation.outputTokenEstimate)),\n\t\t};\n\t}\n\n\tgetObservations(modelRef?: string): ToolSelectionObservation[] {\n\t\tconst host = this.storage.getHost();\n\t\treturn (host?.observations ?? [])\n\t\t\t.filter((observation) => modelRef === undefined || observation.modelRef === modelRef)\n\t\t\t.map((observation) => ({\n\t\t\t\t...observation,\n\t\t\t\tshortlist: [...observation.shortlist],\n\t\t\t\tranked: observation.ranked.map((candidate) => ({ ...candidate })),\n\t\t\t}));\n\t}\n}\n"]}
@@ -0,0 +1,124 @@
1
+ import type { SessionManager } from "@caupulican/pi-agent-core/node";
2
+ import { type Component } from "@caupulican/pi-tui";
3
+ import { type Static, Type } from "typebox";
4
+ import type { ClipboardInputHost } from "../../modes/interactive/clipboard-input.ts";
5
+ import type { Theme } from "../../modes/interactive/theme/theme.ts";
6
+ import type { ArtifactStore } from "../context/context-artifacts.ts";
7
+ import { type HumanInputAnswer, type HumanInputAnswerImage, type HumanInputPresentationResult, type HumanInputQuestion, type HumanInputStopReason } from "../human-input.ts";
8
+ import type { KeybindingsManager } from "../keybindings.ts";
9
+ import type { SessionImageStore } from "../session-image-store.ts";
10
+ declare const askQuestionSchema: Type.TObject<{
11
+ questions: Type.TArray<Type.TObject<{
12
+ id: Type.TString;
13
+ header: Type.TString;
14
+ question: Type.TString;
15
+ options: Type.TArray<Type.TObject<{
16
+ label: Type.TString;
17
+ description: Type.TString;
18
+ }>>;
19
+ multiSelect: Type.TOptional<Type.TBoolean>;
20
+ }>>;
21
+ }>;
22
+ export type AskQuestionToolInput = Static<typeof askQuestionSchema>;
23
+ export type AskQuestion = HumanInputQuestion;
24
+ export type AskQuestionAnswer = HumanInputAnswer;
25
+ export type AskQuestionAnswerImage = HumanInputAnswerImage;
26
+ export type AskQuestionStopReason = HumanInputStopReason;
27
+ export interface AskQuestionToolDetails {
28
+ questions: readonly AskQuestion[];
29
+ answers: readonly AskQuestionAnswer[];
30
+ cancelled: boolean;
31
+ reason?: AskQuestionStopReason;
32
+ error?: string;
33
+ }
34
+ export interface AskQuestionToolOptions {
35
+ name?: string;
36
+ label?: string;
37
+ /** Production session sink. When present, requests and answers are checkpointed before continuation. */
38
+ sessionManager?: Pick<SessionManager, "appendCustomEntry">;
39
+ artifactStore?: ArtifactStore;
40
+ getImageStore?: () => Pick<SessionImageStore, "retainContent"> | undefined;
41
+ }
42
+ export interface AskQuestionClipboardOptions {
43
+ autoResizeImages: boolean;
44
+ blockImages: boolean;
45
+ blockImagesReason?: string;
46
+ imageStore?: Pick<SessionImageStore, "write">;
47
+ }
48
+ export type PasteClipboardImage = (host: ClipboardInputHost) => Promise<void>;
49
+ export interface AskQuestionAnswerEditor extends Component {
50
+ focused: boolean;
51
+ onSubmit?: (text: string) => void;
52
+ handleInput(data: string): void;
53
+ getText(): string;
54
+ setText(text: string): void;
55
+ insertTextAtCursor(text: string): void;
56
+ }
57
+ export type CreateAskQuestionAnswerEditor = () => AskQuestionAnswerEditor;
58
+ type AskQuestionDialogResult = HumanInputPresentationResult;
59
+ /** Native focused question interaction shared by every provider-facing ask_question call. */
60
+ export declare class AskQuestionDialog implements Component {
61
+ private readonly questions;
62
+ private readonly theme;
63
+ private readonly keybindings;
64
+ private readonly requestRender;
65
+ private readonly finish;
66
+ private readonly clipboard;
67
+ private readonly pasteClipboardImage;
68
+ private readonly createAnswerEditor;
69
+ private readonly selections;
70
+ private readonly cursors;
71
+ private pendingClipboardImages;
72
+ private clipboardImageCounter;
73
+ private currentIndex;
74
+ private input;
75
+ private inputError;
76
+ private inputStatus;
77
+ private pasteInFlight;
78
+ private submitAfterPaste;
79
+ private cachedWidth;
80
+ private cachedLines;
81
+ private settled;
82
+ constructor(options: {
83
+ questions: readonly AskQuestion[];
84
+ theme: Theme;
85
+ keybindings: KeybindingsManager;
86
+ requestRender: () => void;
87
+ finish: (result: AskQuestionDialogResult) => void;
88
+ clipboard?: AskQuestionClipboardOptions;
89
+ pasteClipboardImage?: PasteClipboardImage;
90
+ createAnswerEditor?: CreateAskQuestionAnswerEditor;
91
+ });
92
+ private refresh;
93
+ private result;
94
+ private complete;
95
+ cancel(reason: Extract<AskQuestionStopReason, "user_cancelled" | "interrupted">): void;
96
+ private move;
97
+ private advanceAfterSingleSelection;
98
+ private beginCustomAnswer;
99
+ private pasteIntoCustomAnswer;
100
+ private selectCurrent;
101
+ private submitReview;
102
+ handleInput(data: string): void;
103
+ private addWrapped;
104
+ private renderProgress;
105
+ private renderQuestion;
106
+ private renderReview;
107
+ private renderHelp;
108
+ render(width: number): string[];
109
+ invalidate(): void;
110
+ }
111
+ export declare function createAskQuestionToolDefinition(options?: AskQuestionToolOptions): import("../extensions/types.ts").ToolDefinition<Type.TObject<{
112
+ questions: Type.TArray<Type.TObject<{
113
+ id: Type.TString;
114
+ header: Type.TString;
115
+ question: Type.TString;
116
+ options: Type.TArray<Type.TObject<{
117
+ label: Type.TString;
118
+ description: Type.TString;
119
+ }>>;
120
+ multiSelect: Type.TOptional<Type.TBoolean>;
121
+ }>>;
122
+ }>, AskQuestionToolDetails, any> & import("../extensions/types.ts").ToolDefinition<any, any, any>;
123
+ export {};
124
+ //# sourceMappingURL=ask-question.d.ts.map