@caupulican/pi-adaptative 0.85.3 → 0.85.8

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 (411) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/dist/bun/cli.d.ts +1 -1
  3. package/dist/bun/cli.d.ts.map +1 -1
  4. package/dist/bun/cli.js +1 -0
  5. package/dist/bun/cli.js.map +1 -1
  6. package/dist/core/agent-session-runtime.d.ts +1 -1
  7. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  8. package/dist/core/agent-session-runtime.js +1 -1
  9. package/dist/core/agent-session-runtime.js.map +1 -1
  10. package/dist/core/agent-session-services.d.ts.map +1 -1
  11. package/dist/core/agent-session-services.js +2 -0
  12. package/dist/core/agent-session-services.js.map +1 -1
  13. package/dist/core/agent-session.d.ts +12 -8
  14. package/dist/core/agent-session.d.ts.map +1 -1
  15. package/dist/core/agent-session.js +82 -88
  16. package/dist/core/agent-session.js.map +1 -1
  17. package/dist/core/auth-guidance.d.ts.map +1 -1
  18. package/dist/core/auth-guidance.js +3 -0
  19. package/dist/core/auth-guidance.js.map +1 -1
  20. package/dist/core/auth-storage.d.ts +2 -2
  21. package/dist/core/auth-storage.d.ts.map +1 -1
  22. package/dist/core/auth-storage.js +2 -2
  23. package/dist/core/auth-storage.js.map +1 -1
  24. package/dist/core/autonomy/lane-tool-surface.d.ts +2 -0
  25. package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
  26. package/dist/core/autonomy/lane-tool-surface.js +4 -3
  27. package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
  28. package/dist/core/background-lane-controller.d.ts +4 -0
  29. package/dist/core/background-lane-controller.d.ts.map +1 -1
  30. package/dist/core/background-lane-controller.js +2 -0
  31. package/dist/core/background-lane-controller.js.map +1 -1
  32. package/dist/core/background-tool-task-controller.d.ts +12 -7
  33. package/dist/core/background-tool-task-controller.d.ts.map +1 -1
  34. package/dist/core/background-tool-task-controller.js +55 -19
  35. package/dist/core/background-tool-task-controller.js.map +1 -1
  36. package/dist/core/bash-executor.js +2 -2
  37. package/dist/core/bash-executor.js.map +1 -1
  38. package/dist/core/bedrock-scope.d.ts +26 -0
  39. package/dist/core/bedrock-scope.d.ts.map +1 -0
  40. package/dist/core/bedrock-scope.js +178 -0
  41. package/dist/core/bedrock-scope.js.map +1 -0
  42. package/dist/core/billing-failover-controller.d.ts +2 -2
  43. package/dist/core/billing-failover-controller.d.ts.map +1 -1
  44. package/dist/core/billing-failover-controller.js +1 -1
  45. package/dist/core/billing-failover-controller.js.map +1 -1
  46. package/dist/core/compaction-controller.d.ts +8 -2
  47. package/dist/core/compaction-controller.d.ts.map +1 -1
  48. package/dist/core/compaction-controller.js +73 -3
  49. package/dist/core/compaction-controller.js.map +1 -1
  50. package/dist/core/compaction-support.d.ts +2 -2
  51. package/dist/core/compaction-support.d.ts.map +1 -1
  52. package/dist/core/compaction-support.js +9 -1
  53. package/dist/core/compaction-support.js.map +1 -1
  54. package/dist/core/context/artifact-retrieval.d.ts +1 -1
  55. package/dist/core/context/artifact-retrieval.d.ts.map +1 -1
  56. package/dist/core/context/artifact-retrieval.js +1 -1
  57. package/dist/core/context/artifact-retrieval.js.map +1 -1
  58. package/dist/core/context/context-artifacts.d.ts +6 -6
  59. package/dist/core/context/context-artifacts.d.ts.map +1 -1
  60. package/dist/core/context/context-artifacts.js +151 -63
  61. package/dist/core/context/context-artifacts.js.map +1 -1
  62. package/dist/core/context/context-composition.js +1 -1
  63. package/dist/core/context/context-composition.js.map +1 -1
  64. package/dist/core/context/context-store-retention.d.ts.map +1 -1
  65. package/dist/core/context/context-store-retention.js +5 -2
  66. package/dist/core/context/context-store-retention.js.map +1 -1
  67. package/dist/core/context/file-store-memory-provider.js +1 -1
  68. package/dist/core/context/file-store-memory-provider.js.map +1 -1
  69. package/dist/core/context/tool-output-packer.d.ts +1 -1
  70. package/dist/core/context/tool-output-packer.d.ts.map +1 -1
  71. package/dist/core/context/tool-output-packer.js +1 -1
  72. package/dist/core/context/tool-output-packer.js.map +1 -1
  73. package/dist/core/context-gc.d.ts.map +1 -1
  74. package/dist/core/context-gc.js +7 -5
  75. package/dist/core/context-gc.js.map +1 -1
  76. package/dist/core/context-pipeline.d.ts +2 -2
  77. package/dist/core/context-pipeline.d.ts.map +1 -1
  78. package/dist/core/context-pipeline.js +8 -4
  79. package/dist/core/context-pipeline.js.map +1 -1
  80. package/dist/core/cost/cost-summary.d.ts +1 -1
  81. package/dist/core/cost/cost-summary.d.ts.map +1 -1
  82. package/dist/core/cost/cost-summary.js +1 -1
  83. package/dist/core/cost/cost-summary.js.map +1 -1
  84. package/dist/core/cost/daily-usage.d.ts +1 -1
  85. package/dist/core/cost/daily-usage.d.ts.map +1 -1
  86. package/dist/core/cost/daily-usage.js +2 -2
  87. package/dist/core/cost/daily-usage.js.map +1 -1
  88. package/dist/core/cost/session-usage.d.ts +1 -1
  89. package/dist/core/cost/session-usage.d.ts.map +1 -1
  90. package/dist/core/cost/session-usage.js +1 -1
  91. package/dist/core/cost/session-usage.js.map +1 -1
  92. package/dist/core/delegation/worker-actions.js +1 -1
  93. package/dist/core/delegation/worker-actions.js.map +1 -1
  94. package/dist/core/delegation/worker-attempt-executor.d.ts +1 -1
  95. package/dist/core/delegation/worker-attempt-executor.d.ts.map +1 -1
  96. package/dist/core/delegation/worker-attempt-executor.js +3 -2
  97. package/dist/core/delegation/worker-attempt-executor.js.map +1 -1
  98. package/dist/core/delegation/worker-conversation-store.d.ts +2 -1
  99. package/dist/core/delegation/worker-conversation-store.d.ts.map +1 -1
  100. package/dist/core/delegation/worker-conversation-store.js +3 -2
  101. package/dist/core/delegation/worker-conversation-store.js.map +1 -1
  102. package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
  103. package/dist/core/delegation/worker-delegation-controller.js +6 -0
  104. package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
  105. package/dist/core/extensions/builtin.d.ts +2 -2
  106. package/dist/core/extensions/builtin.d.ts.map +1 -1
  107. package/dist/core/extensions/builtin.js +2 -2
  108. package/dist/core/extensions/builtin.js.map +1 -1
  109. package/dist/core/extensions/bundled-virtual-modules.d.ts +2 -0
  110. package/dist/core/extensions/bundled-virtual-modules.d.ts.map +1 -0
  111. package/dist/core/extensions/bundled-virtual-modules.js +129 -0
  112. package/dist/core/extensions/bundled-virtual-modules.js.map +1 -0
  113. package/dist/core/extensions/factory-runtime.d.ts +22 -0
  114. package/dist/core/extensions/factory-runtime.d.ts.map +1 -0
  115. package/dist/core/extensions/factory-runtime.js +334 -0
  116. package/dist/core/extensions/factory-runtime.js.map +1 -0
  117. package/dist/core/extensions/index.d.ts +1 -1
  118. package/dist/core/extensions/index.d.ts.map +1 -1
  119. package/dist/core/extensions/index.js +1 -1
  120. package/dist/core/extensions/index.js.map +1 -1
  121. package/dist/core/extensions/lifecycle.d.ts +13 -0
  122. package/dist/core/extensions/lifecycle.d.ts.map +1 -0
  123. package/dist/core/extensions/lifecycle.js +52 -0
  124. package/dist/core/extensions/lifecycle.js.map +1 -0
  125. package/dist/core/extensions/loader.d.ts +3 -24
  126. package/dist/core/extensions/loader.d.ts.map +1 -1
  127. package/dist/core/extensions/loader.js +21 -528
  128. package/dist/core/extensions/loader.js.map +1 -1
  129. package/dist/core/extensions/virtual-modules.d.ts +51 -0
  130. package/dist/core/extensions/virtual-modules.d.ts.map +1 -0
  131. package/dist/core/extensions/virtual-modules.js +59 -0
  132. package/dist/core/extensions/virtual-modules.js.map +1 -0
  133. package/dist/core/foreground-recovery-controller.d.ts +26 -2
  134. package/dist/core/foreground-recovery-controller.d.ts.map +1 -1
  135. package/dist/core/foreground-recovery-controller.js +112 -3
  136. package/dist/core/foreground-recovery-controller.js.map +1 -1
  137. package/dist/core/foreground-terminal-handoff-controller.d.ts +27 -0
  138. package/dist/core/foreground-terminal-handoff-controller.d.ts.map +1 -0
  139. package/dist/core/foreground-terminal-handoff-controller.js +56 -0
  140. package/dist/core/foreground-terminal-handoff-controller.js.map +1 -0
  141. package/dist/core/goal-loop-controller.d.ts.map +1 -1
  142. package/dist/core/goal-loop-controller.js +5 -0
  143. package/dist/core/goal-loop-controller.js.map +1 -1
  144. package/dist/core/goals/compact-goal-context.d.ts +1 -1
  145. package/dist/core/goals/compact-goal-context.d.ts.map +1 -1
  146. package/dist/core/goals/compact-goal-context.js +1 -1
  147. package/dist/core/goals/compact-goal-context.js.map +1 -1
  148. package/dist/core/goals/goal-auto-continue-controller.d.ts +3 -0
  149. package/dist/core/goals/goal-auto-continue-controller.d.ts.map +1 -1
  150. package/dist/core/goals/goal-auto-continue-controller.js +28 -7
  151. package/dist/core/goals/goal-auto-continue-controller.js.map +1 -1
  152. package/dist/core/goals/goal-session-controller.d.ts +1 -1
  153. package/dist/core/goals/goal-session-controller.d.ts.map +1 -1
  154. package/dist/core/goals/goal-session-controller.js +1 -1
  155. package/dist/core/goals/goal-session-controller.js.map +1 -1
  156. package/dist/core/http-dispatcher.d.ts +1 -1
  157. package/dist/core/http-dispatcher.d.ts.map +1 -1
  158. package/dist/core/http-dispatcher.js +1 -1
  159. package/dist/core/http-dispatcher.js.map +1 -1
  160. package/dist/core/human-input-controller.d.ts +9 -0
  161. package/dist/core/human-input-controller.d.ts.map +1 -1
  162. package/dist/core/human-input-controller.js +60 -5
  163. package/dist/core/human-input-controller.js.map +1 -1
  164. package/dist/core/human-input.d.ts +12 -0
  165. package/dist/core/human-input.d.ts.map +1 -1
  166. package/dist/core/human-input.js +59 -12
  167. package/dist/core/human-input.js.map +1 -1
  168. package/dist/core/index.d.ts +3 -2
  169. package/dist/core/index.d.ts.map +1 -1
  170. package/dist/core/index.js +2 -1
  171. package/dist/core/index.js.map +1 -1
  172. package/dist/core/local-runtime-controller.d.ts.map +1 -1
  173. package/dist/core/local-runtime-controller.js +15 -9
  174. package/dist/core/local-runtime-controller.js.map +1 -1
  175. package/dist/core/memory/providers/file-store.d.ts +1 -0
  176. package/dist/core/memory/providers/file-store.d.ts.map +1 -1
  177. package/dist/core/memory/providers/file-store.js +253 -126
  178. package/dist/core/memory/providers/file-store.js.map +1 -1
  179. package/dist/core/memory/providers/user-memory-archive.js +1 -1
  180. package/dist/core/memory/providers/user-memory-archive.js.map +1 -1
  181. package/dist/core/model-capability.d.ts +15 -1
  182. package/dist/core/model-capability.d.ts.map +1 -1
  183. package/dist/core/model-capability.js +24 -1
  184. package/dist/core/model-capability.js.map +1 -1
  185. package/dist/core/model-registry.d.ts +7 -1
  186. package/dist/core/model-registry.d.ts.map +1 -1
  187. package/dist/core/model-registry.js +22 -1
  188. package/dist/core/model-registry.js.map +1 -1
  189. package/dist/core/model-resolver.d.ts +1 -1
  190. package/dist/core/model-resolver.d.ts.map +1 -1
  191. package/dist/core/model-resolver.js +1 -1
  192. package/dist/core/model-resolver.js.map +1 -1
  193. package/dist/core/model-router-controller.d.ts +6 -6
  194. package/dist/core/model-router-controller.d.ts.map +1 -1
  195. package/dist/core/model-router-controller.js +6 -6
  196. package/dist/core/model-router-controller.js.map +1 -1
  197. package/dist/core/model-selection-controller.js +1 -1
  198. package/dist/core/model-selection-controller.js.map +1 -1
  199. package/dist/core/model-tool-protocol.d.ts +1 -1
  200. package/dist/core/model-tool-protocol.d.ts.map +1 -1
  201. package/dist/core/model-tool-protocol.js +1 -1
  202. package/dist/core/model-tool-protocol.js.map +1 -1
  203. package/dist/core/models/context-sizing.d.ts +1 -0
  204. package/dist/core/models/context-sizing.d.ts.map +1 -1
  205. package/dist/core/models/context-sizing.js +4 -1
  206. package/dist/core/models/context-sizing.js.map +1 -1
  207. package/dist/core/models/default-model-suggestions.d.ts.map +1 -1
  208. package/dist/core/models/default-model-suggestions.js +20 -10
  209. package/dist/core/models/default-model-suggestions.js.map +1 -1
  210. package/dist/core/models/llamacpp-runtime.d.ts +39 -11
  211. package/dist/core/models/llamacpp-runtime.d.ts.map +1 -1
  212. package/dist/core/models/llamacpp-runtime.js +87 -31
  213. package/dist/core/models/llamacpp-runtime.js.map +1 -1
  214. package/dist/core/models/local-execution-planner.d.ts +24 -0
  215. package/dist/core/models/local-execution-planner.d.ts.map +1 -0
  216. package/dist/core/models/local-execution-planner.js +119 -0
  217. package/dist/core/models/local-execution-planner.js.map +1 -0
  218. package/dist/core/models/local-inference-profile.d.ts +34 -0
  219. package/dist/core/models/local-inference-profile.d.ts.map +1 -0
  220. package/dist/core/models/local-inference-profile.js +74 -0
  221. package/dist/core/models/local-inference-profile.js.map +1 -0
  222. package/dist/core/models/local-runtime.d.ts +23 -4
  223. package/dist/core/models/local-runtime.d.ts.map +1 -1
  224. package/dist/core/models/local-runtime.js +12 -9
  225. package/dist/core/models/local-runtime.js.map +1 -1
  226. package/dist/core/models/managed-ollama-model.d.ts +26 -0
  227. package/dist/core/models/managed-ollama-model.d.ts.map +1 -0
  228. package/dist/core/models/managed-ollama-model.js +59 -0
  229. package/dist/core/models/managed-ollama-model.js.map +1 -0
  230. package/dist/core/models/model-ref.js +11 -11
  231. package/dist/core/models/model-ref.js.map +1 -1
  232. package/dist/core/models/prism-llamacpp-lifecycle.d.ts +10 -20
  233. package/dist/core/models/prism-llamacpp-lifecycle.d.ts.map +1 -1
  234. package/dist/core/models/prism-llamacpp-lifecycle.js +11 -31
  235. package/dist/core/models/prism-llamacpp-lifecycle.js.map +1 -1
  236. package/dist/core/models/prism-llamacpp-server-probe.d.ts +10 -0
  237. package/dist/core/models/prism-llamacpp-server-probe.d.ts.map +1 -0
  238. package/dist/core/models/prism-llamacpp-server-probe.js +36 -0
  239. package/dist/core/models/prism-llamacpp-server-probe.js.map +1 -0
  240. package/dist/core/models/runtime-arbiter.d.ts +3 -0
  241. package/dist/core/models/runtime-arbiter.d.ts.map +1 -1
  242. package/dist/core/models/runtime-arbiter.js +2 -1
  243. package/dist/core/models/runtime-arbiter.js.map +1 -1
  244. package/dist/core/orchestration/model-binding.d.ts +1 -1
  245. package/dist/core/orchestration/model-binding.d.ts.map +1 -1
  246. package/dist/core/orchestration/model-binding.js +1 -1
  247. package/dist/core/orchestration/model-binding.js.map +1 -1
  248. package/dist/core/orchestration/task-profile-writer.js +1 -1
  249. package/dist/core/orchestration/task-profile-writer.js.map +1 -1
  250. package/dist/core/process-matrix/runtime.d.ts +15 -1
  251. package/dist/core/process-matrix/runtime.d.ts.map +1 -1
  252. package/dist/core/process-matrix/runtime.js +55 -34
  253. package/dist/core/process-matrix/runtime.js.map +1 -1
  254. package/dist/core/reflection-controller.d.ts +4 -3
  255. package/dist/core/reflection-controller.d.ts.map +1 -1
  256. package/dist/core/reflection-controller.js +2 -2
  257. package/dist/core/reflection-controller.js.map +1 -1
  258. package/dist/core/research/model-fitness-controller.js +1 -1
  259. package/dist/core/research/model-fitness-controller.js.map +1 -1
  260. package/dist/core/research/research-lane-controller.d.ts +2 -2
  261. package/dist/core/research/research-lane-controller.d.ts.map +1 -1
  262. package/dist/core/research/research-lane-controller.js +15 -6
  263. package/dist/core/research/research-lane-controller.js.map +1 -1
  264. package/dist/core/resource-loader.d.ts +10 -19
  265. package/dist/core/resource-loader.d.ts.map +1 -1
  266. package/dist/core/resource-loader.js +8 -70
  267. package/dist/core/resource-loader.js.map +1 -1
  268. package/dist/core/runtime-builder.d.ts +5 -1
  269. package/dist/core/runtime-builder.d.ts.map +1 -1
  270. package/dist/core/runtime-builder.js +50 -7
  271. package/dist/core/runtime-builder.js.map +1 -1
  272. package/dist/core/scout-controller.d.ts +4 -3
  273. package/dist/core/scout-controller.d.ts.map +1 -1
  274. package/dist/core/scout-controller.js +2 -1
  275. package/dist/core/scout-controller.js.map +1 -1
  276. package/dist/core/sdk.d.ts +2 -2
  277. package/dist/core/sdk.d.ts.map +1 -1
  278. package/dist/core/sdk.js +13 -11
  279. package/dist/core/sdk.js.map +1 -1
  280. package/dist/core/security/context-threat-scanner.d.ts +14 -0
  281. package/dist/core/security/context-threat-scanner.d.ts.map +1 -0
  282. package/dist/core/security/context-threat-scanner.js +71 -0
  283. package/dist/core/security/context-threat-scanner.js.map +1 -0
  284. package/dist/core/session-supervision-runtime.d.ts +4 -1
  285. package/dist/core/session-supervision-runtime.d.ts.map +1 -1
  286. package/dist/core/session-supervision-runtime.js +49 -11
  287. package/dist/core/session-supervision-runtime.js.map +1 -1
  288. package/dist/core/settings-manager.d.ts +13 -0
  289. package/dist/core/settings-manager.d.ts.map +1 -1
  290. package/dist/core/settings-manager.js +60 -1
  291. package/dist/core/settings-manager.js.map +1 -1
  292. package/dist/core/system-prompt-builder.d.ts +5 -2
  293. package/dist/core/system-prompt-builder.d.ts.map +1 -1
  294. package/dist/core/system-prompt-builder.js +22 -10
  295. package/dist/core/system-prompt-builder.js.map +1 -1
  296. package/dist/core/system-prompt.d.ts +3 -0
  297. package/dist/core/system-prompt.d.ts.map +1 -1
  298. package/dist/core/system-prompt.js +181 -55
  299. package/dist/core/system-prompt.js.map +1 -1
  300. package/dist/core/tool-protocol-controller.d.ts.map +1 -1
  301. package/dist/core/tool-protocol-controller.js +5 -3
  302. package/dist/core/tool-protocol-controller.js.map +1 -1
  303. package/dist/core/tool-recovery-logger.js +1 -1
  304. package/dist/core/tool-recovery-logger.js.map +1 -1
  305. package/dist/core/tools/artifact-retrieve.js +1 -1
  306. package/dist/core/tools/artifact-retrieve.js.map +1 -1
  307. package/dist/core/tools/bash.d.ts +2 -2
  308. package/dist/core/tools/bash.d.ts.map +1 -1
  309. package/dist/core/tools/bash.js +16 -4
  310. package/dist/core/tools/bash.js.map +1 -1
  311. package/dist/core/tools/edit-diff.d.ts +2 -0
  312. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  313. package/dist/core/tools/edit-diff.js +9 -1
  314. package/dist/core/tools/edit-diff.js.map +1 -1
  315. package/dist/core/tools/edit.d.ts +5 -8
  316. package/dist/core/tools/edit.d.ts.map +1 -1
  317. package/dist/core/tools/edit.js +88 -55
  318. package/dist/core/tools/edit.js.map +1 -1
  319. package/dist/core/tools/extensionify-runtime.d.ts +44 -0
  320. package/dist/core/tools/extensionify-runtime.d.ts.map +1 -0
  321. package/dist/core/tools/extensionify-runtime.js +115 -0
  322. package/dist/core/tools/extensionify-runtime.js.map +1 -0
  323. package/dist/core/tools/extensionify.d.ts +9 -30
  324. package/dist/core/tools/extensionify.d.ts.map +1 -1
  325. package/dist/core/tools/extensionify.js +10 -140
  326. package/dist/core/tools/extensionify.js.map +1 -1
  327. package/dist/core/tools/file-mutation-intent.d.ts +42 -15
  328. package/dist/core/tools/file-mutation-intent.d.ts.map +1 -1
  329. package/dist/core/tools/file-mutation-intent.js +271 -77
  330. package/dist/core/tools/file-mutation-intent.js.map +1 -1
  331. package/dist/core/tools/find.d.ts +1 -1
  332. package/dist/core/tools/find.d.ts.map +1 -1
  333. package/dist/core/tools/find.js +1 -1
  334. package/dist/core/tools/find.js.map +1 -1
  335. package/dist/core/tools/index.d.ts +3 -5
  336. package/dist/core/tools/index.d.ts.map +1 -1
  337. package/dist/core/tools/index.js +8 -44
  338. package/dist/core/tools/index.js.map +1 -1
  339. package/dist/core/tools/ls.d.ts +1 -1
  340. package/dist/core/tools/ls.d.ts.map +1 -1
  341. package/dist/core/tools/ls.js +1 -1
  342. package/dist/core/tools/ls.js.map +1 -1
  343. package/dist/core/tools/output-accumulator.d.ts +1 -1
  344. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  345. package/dist/core/tools/output-accumulator.js +1 -1
  346. package/dist/core/tools/output-accumulator.js.map +1 -1
  347. package/dist/core/tools/render-utils.js +1 -1
  348. package/dist/core/tools/render-utils.js.map +1 -1
  349. package/dist/core/tools/search-command-guard.d.ts +8 -0
  350. package/dist/core/tools/search-command-guard.d.ts.map +1 -1
  351. package/dist/core/tools/search-command-guard.js +54 -0
  352. package/dist/core/tools/search-command-guard.js.map +1 -1
  353. package/dist/core/tools/shell-contract-router.d.ts.map +1 -1
  354. package/dist/core/tools/shell-contract-router.js +9 -4
  355. package/dist/core/tools/shell-contract-router.js.map +1 -1
  356. package/dist/core/tools/shell-session.d.ts.map +1 -1
  357. package/dist/core/tools/shell-session.js +6 -4
  358. package/dist/core/tools/shell-session.js.map +1 -1
  359. package/dist/core/tools/tool-definition-factory.d.ts +32 -0
  360. package/dist/core/tools/tool-definition-factory.d.ts.map +1 -0
  361. package/dist/core/tools/tool-definition-factory.js +55 -0
  362. package/dist/core/tools/tool-definition-factory.js.map +1 -0
  363. package/dist/core/tools/write.d.ts +5 -10
  364. package/dist/core/tools/write.d.ts.map +1 -1
  365. package/dist/core/tools/write.js +92 -73
  366. package/dist/core/tools/write.js.map +1 -1
  367. package/dist/core/util/atomic-file.d.ts.map +1 -1
  368. package/dist/core/util/atomic-file.js +79 -32
  369. package/dist/core/util/atomic-file.js.map +1 -1
  370. package/dist/index.d.ts +3 -2
  371. package/dist/index.d.ts.map +1 -1
  372. package/dist/index.js +3 -2
  373. package/dist/index.js.map +1 -1
  374. package/dist/main.d.ts +2 -0
  375. package/dist/main.d.ts.map +1 -1
  376. package/dist/main.js +24 -18
  377. package/dist/main.js.map +1 -1
  378. package/dist/modes/interactive/auth-dialogs-controller.d.ts +6 -0
  379. package/dist/modes/interactive/auth-dialogs-controller.d.ts.map +1 -1
  380. package/dist/modes/interactive/auth-dialogs-controller.js +59 -12
  381. package/dist/modes/interactive/auth-dialogs-controller.js.map +1 -1
  382. package/dist/modes/interactive/auto-learn-controller.js +1 -1
  383. package/dist/modes/interactive/auto-learn-controller.js.map +1 -1
  384. package/dist/modes/interactive/components/tool-execution.js +1 -1
  385. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  386. package/dist/modes/interactive/interactive-event-controller.js +1 -1
  387. package/dist/modes/interactive/interactive-event-controller.js.map +1 -1
  388. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  389. package/dist/modes/interactive/interactive-mode.js +1 -1
  390. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  391. package/dist/modes/interactive/local-model-commands.d.ts +1 -1
  392. package/dist/modes/interactive/local-model-commands.d.ts.map +1 -1
  393. package/dist/modes/interactive/local-model-commands.js +51 -8
  394. package/dist/modes/interactive/local-model-commands.js.map +1 -1
  395. package/dist/utils/child-process.js +1 -1
  396. package/dist/utils/child-process.js.map +1 -1
  397. package/docs/providers.md +34 -10
  398. package/docs/tool-boundary-performance-roadmap-2026-08-02.md +21 -18
  399. package/examples/extensions/built-in-tool-renderer.ts +1 -1
  400. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  401. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  402. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  403. package/examples/extensions/minimal-mode.ts +1 -1
  404. package/examples/extensions/prompt-customizer.ts +2 -2
  405. package/examples/extensions/sandbox/package-lock.json +2 -2
  406. package/examples/extensions/sandbox/package.json +1 -1
  407. package/examples/extensions/ssh.ts +17 -0
  408. package/examples/extensions/with-deps/package-lock.json +2 -2
  409. package/examples/extensions/with-deps/package.json +1 -1
  410. package/npm-shrinkwrap.json +240 -260
  411. package/package.json +9 -7
@@ -1 +1 @@
1
- {"version":3,"file":"user-memory-archive.js","sourceRoot":"","sources":["../../../../src/core/memory/providers/user-memory-archive.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { type Dirent, promises as fs } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { okfMemoryDir } from \"../../agent-paths.ts\";\nimport { formatOkfMemoryDocument, parseOkfMemoryDocument } from \"../../context/okf-memory.ts\";\nimport { hasInvisibleUnicode, scanContextFileThreats } from \"../../resource-loader.ts\";\n\nconst ARCHIVE_DIR_NAME = \"user-preferences\";\nconst ARCHIVE_INDEX_NAME = \"index.okf.md\";\nconst SHARD_NAME_RE = /^user-preferences-([a-f0-9]{16})\\.okf\\.md$/;\nconst MAX_SHARD_BODY_CHARS = 64_000;\n\nexport const USER_ARCHIVE_POINTER =\n\t\"# User profile\\n\\nArchived preferences: [User preference archive](okf-memory/user-preferences/index.okf.md).\\n\";\n\nexport type UserMemoryAction =\n\t| { action: \"add\"; content: string }\n\t| { action: \"replace\"; oldContent: string; content: string }\n\t| { action: \"remove\"; oldContent: string };\n\nexport interface UserMemoryMutationResult {\n\tuserContent: string;\n\tarchiveChanged: boolean;\n}\n\ninterface UserPreferenceShard {\n\tpath: string;\n\tname: string;\n\tbody: string;\n\ttitle: string;\n\ttimestamp?: string;\n}\n\nfunction appendLine(existing: string, content: string): string {\n\treturn existing.endsWith(\"\\n\") || existing === \"\" ? `${existing}${content}\\n` : `${existing}\\n${content}\\n`;\n}\n\nfunction activeUserContent(content: string): { active: string; managed: boolean } {\n\tif (!content.startsWith(USER_ARCHIVE_POINTER)) return { active: content, managed: false };\n\treturn { active: content.slice(USER_ARCHIVE_POINTER.length), managed: true };\n}\n\nfunction safeDescription(body: string): string {\n\tconst line = body\n\t\t.split(\"\\n\")\n\t\t.map((candidate) => candidate.trim())\n\t\t.find((candidate) => candidate.length > 0 && !candidate.startsWith(\"#\"));\n\tconst normalized = (line ?? \"Archived user preferences\")\n\t\t.replace(/^[-*+]\\s+/, \"\")\n\t\t.replace(/[<>[\\]()]/g, \" \")\n\t\t.replace(/\\s+/g, \" \")\n\t\t.trim();\n\treturn normalized.slice(0, 220) || \"Archived user preferences\";\n}\n\nfunction splitArchiveBody(body: string): string[] {\n\tconst chunks: string[] = [];\n\tlet remaining = body;\n\twhile (remaining.length > MAX_SHARD_BODY_CHARS) {\n\t\tconst newline = remaining.lastIndexOf(\"\\n\", MAX_SHARD_BODY_CHARS);\n\t\tconst end = newline >= Math.floor(MAX_SHARD_BODY_CHARS / 2) ? newline : MAX_SHARD_BODY_CHARS;\n\t\tchunks.push(remaining.slice(0, end));\n\t\tremaining = remaining.slice(end + (remaining[end] === \"\\n\" ? 1 : 0));\n\t}\n\tif (remaining.length > 0) chunks.push(remaining);\n\treturn chunks;\n}\n\nasync function atomicWrite(path: string, content: string): Promise<void> {\n\tconst temporaryPath = `${path}.tmp-${process.pid}`;\n\tawait fs.writeFile(temporaryPath, content, \"utf8\");\n\tawait fs.rename(temporaryPath, path);\n}\n\n/**\n * Owns USER.md overflow migration and archived preference mutation. USER.md stays the bounded hot\n * index; canonical overflow content lives in valid OKF documents discovered by the existing memory\n * provider. The caller owns the USER.md lock, so every multi-file operation is serialized through\n * the same mandatory write path.\n */\nexport class UserMemoryArchive {\n\tprivate readonly archiveDir: string;\n\tprivate readonly indexPath: string;\n\n\tconstructor(agentDir: string) {\n\t\tthis.archiveDir = join(okfMemoryDir(agentDir), ARCHIVE_DIR_NAME);\n\t\tthis.indexPath = join(this.archiveDir, ARCHIVE_INDEX_NAME);\n\t}\n\n\tasync apply(\n\t\tcurrentUser: string,\n\t\taction: UserMemoryAction,\n\t\tbudget: number,\n\t\tsupersedeNearDuplicate: (existing: string, content: string) => string | null,\n\t): Promise<UserMemoryMutationResult> {\n\t\t// Validate the generated storage boundary before any shard discovery. Otherwise a symlinked\n\t\t// archive directory could redirect a replace/remove before the later index rebuild rejected it.\n\t\tawait this.ensureArchiveDir();\n\t\tconst split = activeUserContent(currentUser);\n\t\tlet active = split.active;\n\t\tlet archiveChanged = false;\n\n\t\tif (action.action === \"add\") {\n\t\t\tconst supersededActive = supersedeNearDuplicate(active, action.content);\n\t\t\tif (supersededActive !== null) {\n\t\t\t\tactive = supersededActive;\n\t\t\t} else if (await this.supersedeArchivedFact(action.content, supersedeNearDuplicate)) {\n\t\t\t\tarchiveChanged = true;\n\t\t\t} else {\n\t\t\t\tactive = appendLine(active, action.content);\n\t\t\t}\n\t\t} else {\n\t\t\tconst replacement = action.action === \"replace\" ? action.content : \"\";\n\t\t\tif (active.includes(action.oldContent)) {\n\t\t\t\tactive = active.replace(action.oldContent, replacement);\n\t\t\t} else if (await this.replaceArchivedFact(action.oldContent, replacement)) {\n\t\t\t\tarchiveChanged = true;\n\t\t\t} else {\n\t\t\t\tthrow new Error(`The content to ${action.action} ('oldContent') was not found in the file or its archive.`);\n\t\t\t}\n\t\t}\n\n\t\tif (archiveChanged) {\n\t\t\tawait this.rebuildIndex();\n\t\t\treturn { userContent: currentUser, archiveChanged: true };\n\t\t}\n\n\t\tconst hasArchive = split.managed || (await this.hasArchivedShards());\n\t\tconst candidate = `${hasArchive ? USER_ARCHIVE_POINTER : \"\"}${active}`;\n\t\tif (candidate.length <= budget) {\n\t\t\tif (hasArchive) await this.rebuildIndex();\n\t\t\treturn { userContent: candidate, archiveChanged: false };\n\t\t}\n\n\t\tconst body = active.trim();\n\t\tif (!body) throw new Error(\"USER.md index exceeds its character budget without archivable content.\");\n\t\tthis.validateArchiveContent(body);\n\t\tawait this.archiveBody(body);\n\t\tawait this.rebuildIndex();\n\t\treturn { userContent: USER_ARCHIVE_POINTER, archiveChanged: true };\n\t}\n\n\tprivate validateArchiveContent(body: string): void {\n\t\tif (hasInvisibleUnicode(body) || scanContextFileThreats(body, \"strict\").length > 0) {\n\t\t\tthrow new Error(\"USER.md contains unsafe content and cannot be migrated into durable memory shards.\");\n\t\t}\n\t}\n\n\tprivate async ensureArchiveDir(): Promise<void> {\n\t\tawait fs.mkdir(this.archiveDir, { recursive: true });\n\t\tconst stat = await fs.lstat(this.archiveDir);\n\t\tif (!stat.isDirectory() || stat.isSymbolicLink()) {\n\t\t\tthrow new Error(\"User memory archive path must be a real directory, not a symlink.\");\n\t\t}\n\t}\n\n\tprivate async shardFiles(): Promise<UserPreferenceShard[]> {\n\t\tlet entries: Dirent[];\n\t\ttry {\n\t\t\tentries = await fs.readdir(this.archiveDir, { withFileTypes: true, encoding: \"utf8\" });\n\t\t} catch {\n\t\t\treturn [];\n\t\t}\n\t\tconst shards: UserPreferenceShard[] = [];\n\t\tfor (const entry of entries) {\n\t\t\tif (!entry.isFile() || !SHARD_NAME_RE.test(entry.name)) continue;\n\t\t\tconst path = join(this.archiveDir, entry.name);\n\t\t\tlet content: string;\n\t\t\ttry {\n\t\t\t\tcontent = await fs.readFile(path, \"utf8\");\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst parsed = parseOkfMemoryDocument(content, { uri: `okf:${ARCHIVE_DIR_NAME}/${entry.name}` });\n\t\t\tif (parsed.diagnostics.length > 0 || parsed.item?.kind !== \"user_preference\") continue;\n\t\t\tshards.push({\n\t\t\t\tpath,\n\t\t\t\tname: entry.name,\n\t\t\t\tbody: parsed.body,\n\t\t\t\ttitle: parsed.item.title ?? `User preference shard ${entry.name.slice(17, 33)}`,\n\t\t\t\ttimestamp: parsed.item.timestamp,\n\t\t\t});\n\t\t}\n\t\treturn shards.sort((left, right) => left.name.localeCompare(right.name));\n\t}\n\n\tprivate async hasArchivedShards(): Promise<boolean> {\n\t\treturn (await this.shardFiles()).length > 0;\n\t}\n\n\tprivate async archiveBody(body: string): Promise<void> {\n\t\tawait this.ensureArchiveDir();\n\t\tconst migrationDigest = createHash(\"sha256\").update(body).digest(\"hex\");\n\t\tconst chunks = splitArchiveBody(body);\n\t\tfor (let index = 0; index < chunks.length; index++) {\n\t\t\tconst chunk = chunks[index];\n\t\t\tif (chunk === undefined) continue;\n\t\t\tconst identity = `${migrationDigest}\\0${index}`;\n\t\t\tawait this.writeNewShard(chunk, identity);\n\t\t}\n\t}\n\n\tprivate async writeNewShard(body: string, identity: string): Promise<void> {\n\t\tconst hash = createHash(\"sha256\").update(identity).digest(\"hex\").slice(0, 16);\n\t\tconst name = `user-preferences-${hash}.okf.md`;\n\t\tconst path = join(this.archiveDir, name);\n\t\ttry {\n\t\t\tconst existing = await fs.readFile(path, \"utf8\");\n\t\t\tconst parsed = parseOkfMemoryDocument(existing);\n\t\t\tif (parsed.diagnostics.length === 0 && parsed.body.trim() === body) return;\n\t\t\tthrow new Error(`User memory shard hash collision at ${name}.`);\n\t\t} catch (error) {\n\t\t\tif ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n\t\t}\n\n\t\tconst timestamp = new Date().toISOString();\n\t\tawait atomicWrite(\n\t\t\tpath,\n\t\t\tformatOkfMemoryDocument({\n\t\t\t\ttype: \"User Preference\",\n\t\t\t\ttitle: `User preference shard ${hash}`,\n\t\t\t\tdescription: safeDescription(body),\n\t\t\t\tscope: \"user\",\n\t\t\t\tbody,\n\t\t\t\ttags: [\"user-preferences\", \"archived\"],\n\t\t\t\ttimestamp,\n\t\t\t}),\n\t\t);\n\t}\n\n\tprivate async writeShard(shard: UserPreferenceShard, body: string): Promise<void> {\n\t\tif (!body.trim()) {\n\t\t\tawait fs.unlink(shard.path);\n\t\t\treturn;\n\t\t}\n\t\tthis.validateArchiveContent(body);\n\t\tconst chunks = splitArchiveBody(body);\n\t\tconst first = chunks[0];\n\t\tif (first === undefined) return;\n\t\tawait atomicWrite(\n\t\t\tshard.path,\n\t\t\tformatOkfMemoryDocument({\n\t\t\t\ttype: \"User Preference\",\n\t\t\t\ttitle: shard.title,\n\t\t\t\tdescription: safeDescription(first),\n\t\t\t\tscope: \"user\",\n\t\t\t\tbody: first,\n\t\t\t\ttags: [\"user-preferences\", \"archived\"],\n\t\t\t\ttimestamp: shard.timestamp,\n\t\t\t}),\n\t\t);\n\t\tconst mutationDigest = createHash(\"sha256\").update(`${shard.name}\\0${body}`).digest(\"hex\");\n\t\tfor (let index = 1; index < chunks.length; index++) {\n\t\t\tconst chunk = chunks[index];\n\t\t\tif (chunk !== undefined) await this.writeNewShard(chunk, `${mutationDigest}\\0${index}`);\n\t\t}\n\t}\n\n\tprivate async supersedeArchivedFact(\n\t\tcontent: string,\n\t\tsupersedeNearDuplicate: (existing: string, content: string) => string | null,\n\t): Promise<boolean> {\n\t\tfor (const shard of await this.shardFiles()) {\n\t\t\tconst superseded = supersedeNearDuplicate(shard.body, content);\n\t\t\tif (superseded === null) continue;\n\t\t\tawait this.writeShard(shard, superseded);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate async replaceArchivedFact(oldContent: string, replacement: string): Promise<boolean> {\n\t\tfor (const shard of await this.shardFiles()) {\n\t\t\tif (!shard.body.includes(oldContent)) continue;\n\t\t\tawait this.writeShard(shard, shard.body.replace(oldContent, replacement));\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate async rebuildIndex(): Promise<void> {\n\t\tawait this.ensureArchiveDir();\n\t\tconst shards = await this.shardFiles();\n\t\tconst body =\n\t\t\tshards.length === 0\n\t\t\t\t? \"No archived user preference shards.\"\n\t\t\t\t: shards.map((shard) => `- [${shard.name}](./${shard.name}): ${safeDescription(shard.body)}`).join(\"\\n\");\n\t\tawait atomicWrite(\n\t\t\tthis.indexPath,\n\t\t\tformatOkfMemoryDocument({\n\t\t\t\ttype: \"User Preference\",\n\t\t\t\ttitle: \"User preference archive index\",\n\t\t\t\tdescription: \"Index of archived durable user preference shards.\",\n\t\t\t\tscope: \"user\",\n\t\t\t\tbody,\n\t\t\t\ttags: [\"user-preferences\", \"index\"],\n\t\t\t}),\n\t\t);\n\t}\n}\n"]}
1
+ {"version":3,"file":"user-memory-archive.js","sourceRoot":"","sources":["../../../../src/core/memory/providers/user-memory-archive.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { type Dirent, promises as fs } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { okfMemoryDir } from \"../../agent-paths.ts\";\nimport { formatOkfMemoryDocument, parseOkfMemoryDocument } from \"../../context/okf-memory.ts\";\nimport { hasInvisibleUnicode, scanContextFileThreats } from \"../../security/context-threat-scanner.ts\";\n\nconst ARCHIVE_DIR_NAME = \"user-preferences\";\nconst ARCHIVE_INDEX_NAME = \"index.okf.md\";\nconst SHARD_NAME_RE = /^user-preferences-([a-f0-9]{16})\\.okf\\.md$/;\nconst MAX_SHARD_BODY_CHARS = 64_000;\n\nexport const USER_ARCHIVE_POINTER =\n\t\"# User profile\\n\\nArchived preferences: [User preference archive](okf-memory/user-preferences/index.okf.md).\\n\";\n\nexport type UserMemoryAction =\n\t| { action: \"add\"; content: string }\n\t| { action: \"replace\"; oldContent: string; content: string }\n\t| { action: \"remove\"; oldContent: string };\n\nexport interface UserMemoryMutationResult {\n\tuserContent: string;\n\tarchiveChanged: boolean;\n}\n\ninterface UserPreferenceShard {\n\tpath: string;\n\tname: string;\n\tbody: string;\n\ttitle: string;\n\ttimestamp?: string;\n}\n\nfunction appendLine(existing: string, content: string): string {\n\treturn existing.endsWith(\"\\n\") || existing === \"\" ? `${existing}${content}\\n` : `${existing}\\n${content}\\n`;\n}\n\nfunction activeUserContent(content: string): { active: string; managed: boolean } {\n\tif (!content.startsWith(USER_ARCHIVE_POINTER)) return { active: content, managed: false };\n\treturn { active: content.slice(USER_ARCHIVE_POINTER.length), managed: true };\n}\n\nfunction safeDescription(body: string): string {\n\tconst line = body\n\t\t.split(\"\\n\")\n\t\t.map((candidate) => candidate.trim())\n\t\t.find((candidate) => candidate.length > 0 && !candidate.startsWith(\"#\"));\n\tconst normalized = (line ?? \"Archived user preferences\")\n\t\t.replace(/^[-*+]\\s+/, \"\")\n\t\t.replace(/[<>[\\]()]/g, \" \")\n\t\t.replace(/\\s+/g, \" \")\n\t\t.trim();\n\treturn normalized.slice(0, 220) || \"Archived user preferences\";\n}\n\nfunction splitArchiveBody(body: string): string[] {\n\tconst chunks: string[] = [];\n\tlet remaining = body;\n\twhile (remaining.length > MAX_SHARD_BODY_CHARS) {\n\t\tconst newline = remaining.lastIndexOf(\"\\n\", MAX_SHARD_BODY_CHARS);\n\t\tconst end = newline >= Math.floor(MAX_SHARD_BODY_CHARS / 2) ? newline : MAX_SHARD_BODY_CHARS;\n\t\tchunks.push(remaining.slice(0, end));\n\t\tremaining = remaining.slice(end + (remaining[end] === \"\\n\" ? 1 : 0));\n\t}\n\tif (remaining.length > 0) chunks.push(remaining);\n\treturn chunks;\n}\n\nasync function atomicWrite(path: string, content: string): Promise<void> {\n\tconst temporaryPath = `${path}.tmp-${process.pid}`;\n\tawait fs.writeFile(temporaryPath, content, \"utf8\");\n\tawait fs.rename(temporaryPath, path);\n}\n\n/**\n * Owns USER.md overflow migration and archived preference mutation. USER.md stays the bounded hot\n * index; canonical overflow content lives in valid OKF documents discovered by the existing memory\n * provider. The caller owns the USER.md lock, so every multi-file operation is serialized through\n * the same mandatory write path.\n */\nexport class UserMemoryArchive {\n\tprivate readonly archiveDir: string;\n\tprivate readonly indexPath: string;\n\n\tconstructor(agentDir: string) {\n\t\tthis.archiveDir = join(okfMemoryDir(agentDir), ARCHIVE_DIR_NAME);\n\t\tthis.indexPath = join(this.archiveDir, ARCHIVE_INDEX_NAME);\n\t}\n\n\tasync apply(\n\t\tcurrentUser: string,\n\t\taction: UserMemoryAction,\n\t\tbudget: number,\n\t\tsupersedeNearDuplicate: (existing: string, content: string) => string | null,\n\t): Promise<UserMemoryMutationResult> {\n\t\t// Validate the generated storage boundary before any shard discovery. Otherwise a symlinked\n\t\t// archive directory could redirect a replace/remove before the later index rebuild rejected it.\n\t\tawait this.ensureArchiveDir();\n\t\tconst split = activeUserContent(currentUser);\n\t\tlet active = split.active;\n\t\tlet archiveChanged = false;\n\n\t\tif (action.action === \"add\") {\n\t\t\tconst supersededActive = supersedeNearDuplicate(active, action.content);\n\t\t\tif (supersededActive !== null) {\n\t\t\t\tactive = supersededActive;\n\t\t\t} else if (await this.supersedeArchivedFact(action.content, supersedeNearDuplicate)) {\n\t\t\t\tarchiveChanged = true;\n\t\t\t} else {\n\t\t\t\tactive = appendLine(active, action.content);\n\t\t\t}\n\t\t} else {\n\t\t\tconst replacement = action.action === \"replace\" ? action.content : \"\";\n\t\t\tif (active.includes(action.oldContent)) {\n\t\t\t\tactive = active.replace(action.oldContent, replacement);\n\t\t\t} else if (await this.replaceArchivedFact(action.oldContent, replacement)) {\n\t\t\t\tarchiveChanged = true;\n\t\t\t} else {\n\t\t\t\tthrow new Error(`The content to ${action.action} ('oldContent') was not found in the file or its archive.`);\n\t\t\t}\n\t\t}\n\n\t\tif (archiveChanged) {\n\t\t\tawait this.rebuildIndex();\n\t\t\treturn { userContent: currentUser, archiveChanged: true };\n\t\t}\n\n\t\tconst hasArchive = split.managed || (await this.hasArchivedShards());\n\t\tconst candidate = `${hasArchive ? USER_ARCHIVE_POINTER : \"\"}${active}`;\n\t\tif (candidate.length <= budget) {\n\t\t\tif (hasArchive) await this.rebuildIndex();\n\t\t\treturn { userContent: candidate, archiveChanged: false };\n\t\t}\n\n\t\tconst body = active.trim();\n\t\tif (!body) throw new Error(\"USER.md index exceeds its character budget without archivable content.\");\n\t\tthis.validateArchiveContent(body);\n\t\tawait this.archiveBody(body);\n\t\tawait this.rebuildIndex();\n\t\treturn { userContent: USER_ARCHIVE_POINTER, archiveChanged: true };\n\t}\n\n\tprivate validateArchiveContent(body: string): void {\n\t\tif (hasInvisibleUnicode(body) || scanContextFileThreats(body, \"strict\").length > 0) {\n\t\t\tthrow new Error(\"USER.md contains unsafe content and cannot be migrated into durable memory shards.\");\n\t\t}\n\t}\n\n\tprivate async ensureArchiveDir(): Promise<void> {\n\t\tawait fs.mkdir(this.archiveDir, { recursive: true });\n\t\tconst stat = await fs.lstat(this.archiveDir);\n\t\tif (!stat.isDirectory() || stat.isSymbolicLink()) {\n\t\t\tthrow new Error(\"User memory archive path must be a real directory, not a symlink.\");\n\t\t}\n\t}\n\n\tprivate async shardFiles(): Promise<UserPreferenceShard[]> {\n\t\tlet entries: Dirent[];\n\t\ttry {\n\t\t\tentries = await fs.readdir(this.archiveDir, { withFileTypes: true, encoding: \"utf8\" });\n\t\t} catch {\n\t\t\treturn [];\n\t\t}\n\t\tconst shards: UserPreferenceShard[] = [];\n\t\tfor (const entry of entries) {\n\t\t\tif (!entry.isFile() || !SHARD_NAME_RE.test(entry.name)) continue;\n\t\t\tconst path = join(this.archiveDir, entry.name);\n\t\t\tlet content: string;\n\t\t\ttry {\n\t\t\t\tcontent = await fs.readFile(path, \"utf8\");\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst parsed = parseOkfMemoryDocument(content, { uri: `okf:${ARCHIVE_DIR_NAME}/${entry.name}` });\n\t\t\tif (parsed.diagnostics.length > 0 || parsed.item?.kind !== \"user_preference\") continue;\n\t\t\tshards.push({\n\t\t\t\tpath,\n\t\t\t\tname: entry.name,\n\t\t\t\tbody: parsed.body,\n\t\t\t\ttitle: parsed.item.title ?? `User preference shard ${entry.name.slice(17, 33)}`,\n\t\t\t\ttimestamp: parsed.item.timestamp,\n\t\t\t});\n\t\t}\n\t\treturn shards.sort((left, right) => left.name.localeCompare(right.name));\n\t}\n\n\tprivate async hasArchivedShards(): Promise<boolean> {\n\t\treturn (await this.shardFiles()).length > 0;\n\t}\n\n\tprivate async archiveBody(body: string): Promise<void> {\n\t\tawait this.ensureArchiveDir();\n\t\tconst migrationDigest = createHash(\"sha256\").update(body).digest(\"hex\");\n\t\tconst chunks = splitArchiveBody(body);\n\t\tfor (let index = 0; index < chunks.length; index++) {\n\t\t\tconst chunk = chunks[index];\n\t\t\tif (chunk === undefined) continue;\n\t\t\tconst identity = `${migrationDigest}\\0${index}`;\n\t\t\tawait this.writeNewShard(chunk, identity);\n\t\t}\n\t}\n\n\tprivate async writeNewShard(body: string, identity: string): Promise<void> {\n\t\tconst hash = createHash(\"sha256\").update(identity).digest(\"hex\").slice(0, 16);\n\t\tconst name = `user-preferences-${hash}.okf.md`;\n\t\tconst path = join(this.archiveDir, name);\n\t\ttry {\n\t\t\tconst existing = await fs.readFile(path, \"utf8\");\n\t\t\tconst parsed = parseOkfMemoryDocument(existing);\n\t\t\tif (parsed.diagnostics.length === 0 && parsed.body.trim() === body) return;\n\t\t\tthrow new Error(`User memory shard hash collision at ${name}.`);\n\t\t} catch (error) {\n\t\t\tif ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n\t\t}\n\n\t\tconst timestamp = new Date().toISOString();\n\t\tawait atomicWrite(\n\t\t\tpath,\n\t\t\tformatOkfMemoryDocument({\n\t\t\t\ttype: \"User Preference\",\n\t\t\t\ttitle: `User preference shard ${hash}`,\n\t\t\t\tdescription: safeDescription(body),\n\t\t\t\tscope: \"user\",\n\t\t\t\tbody,\n\t\t\t\ttags: [\"user-preferences\", \"archived\"],\n\t\t\t\ttimestamp,\n\t\t\t}),\n\t\t);\n\t}\n\n\tprivate async writeShard(shard: UserPreferenceShard, body: string): Promise<void> {\n\t\tif (!body.trim()) {\n\t\t\tawait fs.unlink(shard.path);\n\t\t\treturn;\n\t\t}\n\t\tthis.validateArchiveContent(body);\n\t\tconst chunks = splitArchiveBody(body);\n\t\tconst first = chunks[0];\n\t\tif (first === undefined) return;\n\t\tawait atomicWrite(\n\t\t\tshard.path,\n\t\t\tformatOkfMemoryDocument({\n\t\t\t\ttype: \"User Preference\",\n\t\t\t\ttitle: shard.title,\n\t\t\t\tdescription: safeDescription(first),\n\t\t\t\tscope: \"user\",\n\t\t\t\tbody: first,\n\t\t\t\ttags: [\"user-preferences\", \"archived\"],\n\t\t\t\ttimestamp: shard.timestamp,\n\t\t\t}),\n\t\t);\n\t\tconst mutationDigest = createHash(\"sha256\").update(`${shard.name}\\0${body}`).digest(\"hex\");\n\t\tfor (let index = 1; index < chunks.length; index++) {\n\t\t\tconst chunk = chunks[index];\n\t\t\tif (chunk !== undefined) await this.writeNewShard(chunk, `${mutationDigest}\\0${index}`);\n\t\t}\n\t}\n\n\tprivate async supersedeArchivedFact(\n\t\tcontent: string,\n\t\tsupersedeNearDuplicate: (existing: string, content: string) => string | null,\n\t): Promise<boolean> {\n\t\tfor (const shard of await this.shardFiles()) {\n\t\t\tconst superseded = supersedeNearDuplicate(shard.body, content);\n\t\t\tif (superseded === null) continue;\n\t\t\tawait this.writeShard(shard, superseded);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate async replaceArchivedFact(oldContent: string, replacement: string): Promise<boolean> {\n\t\tfor (const shard of await this.shardFiles()) {\n\t\t\tif (!shard.body.includes(oldContent)) continue;\n\t\t\tawait this.writeShard(shard, shard.body.replace(oldContent, replacement));\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate async rebuildIndex(): Promise<void> {\n\t\tawait this.ensureArchiveDir();\n\t\tconst shards = await this.shardFiles();\n\t\tconst body =\n\t\t\tshards.length === 0\n\t\t\t\t? \"No archived user preference shards.\"\n\t\t\t\t: shards.map((shard) => `- [${shard.name}](./${shard.name}): ${safeDescription(shard.body)}`).join(\"\\n\");\n\t\tawait atomicWrite(\n\t\t\tthis.indexPath,\n\t\t\tformatOkfMemoryDocument({\n\t\t\t\ttype: \"User Preference\",\n\t\t\t\ttitle: \"User preference archive index\",\n\t\t\t\tdescription: \"Index of archived durable user preference shards.\",\n\t\t\t\tscope: \"user\",\n\t\t\t\tbody,\n\t\t\t\ttags: [\"user-preferences\", \"index\"],\n\t\t\t}),\n\t\t);\n\t}\n}\n"]}
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * Model capability auto-detection: derive what the harness may load onto a model FROM the model's
3
3
  * own metadata (`Model.contextWindow`), so small open models (4k/8k/16k windows, sub-1B params)
4
- * can still hold a usable chat instead of drowning in tool schemas and background-lane prompts.
4
+ * can still hold a usable chat instead of drowning in the stable prompt, tool schemas, and
5
+ * background-lane prompts. The same class is the single input to prompt shaping and tool/lane gates.
5
6
  *
6
7
  * Derivation is metadata-first; defaults apply only when the metadata is missing (unknown/zero
7
8
  * window keeps today's full behavior rather than guessing). Detection can be disabled or forced
@@ -13,6 +14,8 @@ export interface ModelCapabilityProfile {
13
14
  class: ModelCapabilityClass;
14
15
  contextWindow?: number;
15
16
  reasonCode: string;
17
+ /** Hard aggregate character envelope for the stable system prompt; undefined = intentionally unbounded. */
18
+ systemPromptMaxChars: number | undefined;
16
19
  /** Allow-list; undefined = no allow-list restriction. */
17
20
  allowedToolNames?: readonly string[];
18
21
  /** Block-list applied after the allow-list; undefined = nothing blocked. */
@@ -28,10 +31,21 @@ export declare const MODEL_CAPABILITY_FULL_MIN_CONTEXT = 32768;
28
31
  export declare const MODEL_CAPABILITY_LEAN_MIN_CONTEXT = 16384;
29
32
  /** Windows at or above this get the minimal coding set; below is chat-only. */
30
33
  export declare const MODEL_CAPABILITY_MINIMAL_MIN_CONTEXT = 8192;
34
+ /**
35
+ * Aggregate stable-prompt envelopes. These are deliberately owned beside the classification
36
+ * thresholds so every harness expansion must fit the same profile that owns tools and lanes.
37
+ * Full/off profiles are intentionally unbounded; constrained profiles fail visibly on overflow.
38
+ */
39
+ export declare const MODEL_CAPABILITY_SYSTEM_PROMPT_MAX_CHARS: Readonly<Record<ModelCapabilityClass, number | undefined>>;
31
40
  export declare const MODEL_CAPABILITY_LEAN_BLOCKED_TOOLS: readonly string[];
32
41
  export declare const MODEL_CAPABILITY_MINIMAL_ALLOWED_TOOLS: readonly string[];
33
42
  export declare const MODEL_CAPABILITY_CHAT_ALLOWED_TOOLS: readonly string[];
34
43
  export declare const DEFAULT_LANE_MAX_OUTPUT_TOKENS = 2048;
44
+ /**
45
+ * Mandatory provider-neutral gate for a final system prompt. This intentionally rejects rather
46
+ * than truncates: arbitrary truncation can silently remove security, repair, or project rules.
47
+ */
48
+ export declare function enforceModelCapabilitySystemPromptBudget(systemPrompt: string, profile: Pick<ModelCapabilityProfile, "class" | "systemPromptMaxChars">): string;
35
49
  export declare function deriveModelCapabilityProfile(args: {
36
50
  contextWindow?: number;
37
51
  mode?: ModelCapabilityMode;
@@ -1 +1 @@
1
- {"version":3,"file":"model-capability.d.ts","sourceRoot":"","sources":["../../src/core/model-capability.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;AAExE,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,KAAK,GAAG,oBAAoB,CAAC;AAExE,MAAM,WAAW,sBAAsB;IACtC,KAAK,EAAE,oBAAoB,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,0FAA0F;IAC1F,sBAAsB,EAAE,OAAO,CAAC;IAChC,4EAA4E;IAC5E,mBAAmB,EAAE,MAAM,CAAC;CAC5B;AAED,8DAA8D;AAC9D,eAAO,MAAM,iCAAiC,QAAS,CAAC;AACxD,oFAAoF;AACpF,eAAO,MAAM,iCAAiC,QAAS,CAAC;AACxD,+EAA+E;AAC/E,eAAO,MAAM,oCAAoC,OAAQ,CAAC;AAE1D,eAAO,MAAM,mCAAmC,EAAE,SAAS,MAAM,EAYhE,CAAC;AACF,eAAO,MAAM,sCAAsC,EAAE,SAAS,MAAM,EAUnE,CAAC;AACF,eAAO,MAAM,mCAAmC,EAAE,SAAS,MAAM,EAAO,CAAC;AAEzE,eAAO,MAAM,8BAA8B,OAAO,CAAC;AA0CnD,wBAAgB,4BAA4B,CAAC,IAAI,EAAE;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,mBAAmB,CAAC;CAC3B,GAAG,sBAAsB,CA2BzB;AAED,6FAA6F;AAC7F,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,EAAE,sBAAsB,GAAG,MAAM,EAAE,CAWpH;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,uBAAuB,GAChC,6BAA6B,GAC7B,wBAAwB,GACxB,2BAA2B,GAC3B,sBAAsB,CAAC;AAE1B,MAAM,WAAW,iBAAiB;IACjC,MAAM,EAAE,uBAAuB,CAAC;IAChC,eAAe,EAAE,oBAAoB,CAAC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE;IAC/C,eAAe,EAAE,oBAAoB,CAAC;IACtC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,kBAAkB,EAAE,OAAO,CAAC;CAC5B,GAAG,iBAAiB,GAAG,SAAS,CAOhC;AAED,6EAA6E;AAC7E,eAAO,MAAM,0BAA0B,uCAAuC,CAAC;AAE/E,0GAA0G;AAC1G,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,iBAAiB,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAI5F"}
1
+ {"version":3,"file":"model-capability.d.ts","sourceRoot":"","sources":["../../src/core/model-capability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;AAExE,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,KAAK,GAAG,oBAAoB,CAAC;AAExE,MAAM,WAAW,sBAAsB;IACtC,KAAK,EAAE,oBAAoB,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,2GAA2G;IAC3G,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,yDAAyD;IACzD,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,0FAA0F;IAC1F,sBAAsB,EAAE,OAAO,CAAC;IAChC,4EAA4E;IAC5E,mBAAmB,EAAE,MAAM,CAAC;CAC5B;AAED,8DAA8D;AAC9D,eAAO,MAAM,iCAAiC,QAAS,CAAC;AACxD,oFAAoF;AACpF,eAAO,MAAM,iCAAiC,QAAS,CAAC;AACxD,+EAA+E;AAC/E,eAAO,MAAM,oCAAoC,OAAQ,CAAC;AAE1D;;;;GAIG;AACH,eAAO,MAAM,wCAAwC,EAAE,QAAQ,CAAC,MAAM,CAAC,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC,CAK/G,CAAC;AAEF,eAAO,MAAM,mCAAmC,EAAE,SAAS,MAAM,EAYhE,CAAC;AACF,eAAO,MAAM,sCAAsC,EAAE,SAAS,MAAM,EAUnE,CAAC;AACF,eAAO,MAAM,mCAAmC,EAAE,SAAS,MAAM,EAAO,CAAC;AAEzE,eAAO,MAAM,8BAA8B,OAAO,CAAC;AA2CnD;;;GAGG;AACH,wBAAgB,wCAAwC,CACvD,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,IAAI,CAAC,sBAAsB,EAAE,OAAO,GAAG,sBAAsB,CAAC,GACrE,MAAM,CAMR;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,mBAAmB,CAAC;CAC3B,GAAG,sBAAsB,CA2BzB;AAED,6FAA6F;AAC7F,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,EAAE,sBAAsB,GAAG,MAAM,EAAE,CAWpH;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,uBAAuB,GAChC,6BAA6B,GAC7B,wBAAwB,GACxB,2BAA2B,GAC3B,sBAAsB,CAAC;AAE1B,MAAM,WAAW,iBAAiB;IACjC,MAAM,EAAE,uBAAuB,CAAC;IAChC,eAAe,EAAE,oBAAoB,CAAC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE;IAC/C,eAAe,EAAE,oBAAoB,CAAC;IACtC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,kBAAkB,EAAE,OAAO,CAAC;CAC5B,GAAG,iBAAiB,GAAG,SAAS,CAOhC;AAED,6EAA6E;AAC7E,eAAO,MAAM,0BAA0B,uCAAuC,CAAC;AAE/E,0GAA0G;AAC1G,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,iBAAiB,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAI5F"}
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * Model capability auto-detection: derive what the harness may load onto a model FROM the model's
3
3
  * own metadata (`Model.contextWindow`), so small open models (4k/8k/16k windows, sub-1B params)
4
- * can still hold a usable chat instead of drowning in tool schemas and background-lane prompts.
4
+ * can still hold a usable chat instead of drowning in the stable prompt, tool schemas, and
5
+ * background-lane prompts. The same class is the single input to prompt shaping and tool/lane gates.
5
6
  *
6
7
  * Derivation is metadata-first; defaults apply only when the metadata is missing (unknown/zero
7
8
  * window keeps today's full behavior rather than guessing). Detection can be disabled or forced
@@ -13,6 +14,17 @@ export const MODEL_CAPABILITY_FULL_MIN_CONTEXT = 32_768;
13
14
  export const MODEL_CAPABILITY_LEAN_MIN_CONTEXT = 16_384;
14
15
  /** Windows at or above this get the minimal coding set; below is chat-only. */
15
16
  export const MODEL_CAPABILITY_MINIMAL_MIN_CONTEXT = 8_192;
17
+ /**
18
+ * Aggregate stable-prompt envelopes. These are deliberately owned beside the classification
19
+ * thresholds so every harness expansion must fit the same profile that owns tools and lanes.
20
+ * Full/off profiles are intentionally unbounded; constrained profiles fail visibly on overflow.
21
+ */
22
+ export const MODEL_CAPABILITY_SYSTEM_PROMPT_MAX_CHARS = {
23
+ full: undefined,
24
+ lean: 8_192,
25
+ minimal: 4_096,
26
+ chat: 2_048,
27
+ };
16
28
  export const MODEL_CAPABILITY_LEAN_BLOCKED_TOOLS = [
17
29
  "delegate",
18
30
  "profile_writer",
@@ -51,6 +63,7 @@ function profileForClass(capabilityClass, reasonCode, contextWindow) {
51
63
  const base = {
52
64
  class: capabilityClass,
53
65
  reasonCode,
66
+ systemPromptMaxChars: MODEL_CAPABILITY_SYSTEM_PROMPT_MAX_CHARS[capabilityClass],
54
67
  backgroundLanesEnabled: true,
55
68
  laneMaxOutputTokens: laneOutputTokensForWindow(contextWindow),
56
69
  ...(contextWindow !== undefined && contextWindow > 0 ? { contextWindow } : {}),
@@ -74,6 +87,16 @@ function profileForClass(capabilityClass, reasonCode, contextWindow) {
74
87
  };
75
88
  }
76
89
  }
90
+ /**
91
+ * Mandatory provider-neutral gate for a final system prompt. This intentionally rejects rather
92
+ * than truncates: arbitrary truncation can silently remove security, repair, or project rules.
93
+ */
94
+ export function enforceModelCapabilitySystemPromptBudget(systemPrompt, profile) {
95
+ const maxChars = profile.systemPromptMaxChars;
96
+ if (maxChars === undefined || systemPrompt.length <= maxChars)
97
+ return systemPrompt;
98
+ throw new Error(`${profile.class} system prompt exceeds its ${maxChars}-character capability budget (${systemPrompt.length} characters). Reduce custom, extension, or harness prompt guidance, or select a more capable profile.`);
99
+ }
77
100
  export function deriveModelCapabilityProfile(args) {
78
101
  const mode = args.mode ?? "auto";
79
102
  const contextWindow = args.contextWindow !== undefined && Number.isFinite(args.contextWindow) && args.contextWindow > 0
@@ -1 +1 @@
1
- {"version":3,"file":"model-capability.js","sourceRoot":"","sources":["../../src/core/model-capability.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Model capability auto-detection: derive what the harness may load onto a model FROM the model's\n * own metadata (`Model.contextWindow`), so small open models (4k/8k/16k windows, sub-1B params)\n * can still hold a usable chat instead of drowning in tool schemas and background-lane prompts.\n *\n * Derivation is metadata-first; defaults apply only when the metadata is missing (unknown/zero\n * window keeps today's full behavior rather than guessing). Detection can be disabled or forced\n * per class via the `modelCapability.mode` setting.\n */\n\nexport type ModelCapabilityClass = \"full\" | \"lean\" | \"minimal\" | \"chat\";\n\nexport type ModelCapabilityMode = \"auto\" | \"off\" | ModelCapabilityClass;\n\nexport interface ModelCapabilityProfile {\n\tclass: ModelCapabilityClass;\n\tcontextWindow?: number;\n\treasonCode: string;\n\t/** Allow-list; undefined = no allow-list restriction. */\n\tallowedToolNames?: readonly string[];\n\t/** Block-list applied after the allow-list; undefined = nothing blocked. */\n\tblockedToolNames?: readonly string[];\n\t/** Whether idle background lanes (goal auto-continue, research) may run on this model. */\n\tbackgroundLanesEnabled: boolean;\n\t/** Output-token cap for lane isolated completions, scaled to the window. */\n\tlaneMaxOutputTokens: number;\n}\n\n/** Windows at or above this keep the full harness surface. */\nexport const MODEL_CAPABILITY_FULL_MIN_CONTEXT = 32_768;\n/** Windows at or above this keep core tools but shed background-autonomy extras. */\nexport const MODEL_CAPABILITY_LEAN_MIN_CONTEXT = 16_384;\n/** Windows at or above this get the minimal coding set; below is chat-only. */\nexport const MODEL_CAPABILITY_MINIMAL_MIN_CONTEXT = 8_192;\n\nexport const MODEL_CAPABILITY_LEAN_BLOCKED_TOOLS: readonly string[] = [\n\t\"delegate\",\n\t\"profile_writer\",\n\t\"context_audit\",\n\t\"goal\",\n\t\"worktree_sync\",\n\t\"improvement_loop\",\n\t\"extensionify\",\n\t\"skillify\",\n\t\"model_fitness\",\n\t\"context_scout\",\n\t\"tmux_agent_manager\",\n];\nexport const MODEL_CAPABILITY_MINIMAL_ALLOWED_TOOLS: readonly string[] = [\n\t\"read\",\n\t\"bash\",\n\t\"python\",\n\t\"powershell\",\n\t\"edit\",\n\t\"write\",\n\t\"ask_question\",\n\t// The executor tool: minimal-class models ARE the daily-ops executors, and its schema is tiny.\n\t\"run_toolkit_script\",\n];\nexport const MODEL_CAPABILITY_CHAT_ALLOWED_TOOLS: readonly string[] = [];\n\nexport const DEFAULT_LANE_MAX_OUTPUT_TOKENS = 2048;\nconst MIN_LANE_MAX_OUTPUT_TOKENS = 256;\n\nfunction laneOutputTokensForWindow(contextWindow: number | undefined): number {\n\tif (contextWindow === undefined || contextWindow <= 0) return DEFAULT_LANE_MAX_OUTPUT_TOKENS;\n\t// A lane completion may use at most an eighth of the window for output, floored so tiny\n\t// windows still produce something parseable.\n\treturn Math.min(DEFAULT_LANE_MAX_OUTPUT_TOKENS, Math.max(MIN_LANE_MAX_OUTPUT_TOKENS, Math.floor(contextWindow / 8)));\n}\n\nfunction profileForClass(\n\tcapabilityClass: ModelCapabilityClass,\n\treasonCode: string,\n\tcontextWindow: number | undefined,\n): ModelCapabilityProfile {\n\tconst base = {\n\t\tclass: capabilityClass,\n\t\treasonCode,\n\t\tbackgroundLanesEnabled: true,\n\t\tlaneMaxOutputTokens: laneOutputTokensForWindow(contextWindow),\n\t\t...(contextWindow !== undefined && contextWindow > 0 ? { contextWindow } : {}),\n\t};\n\tswitch (capabilityClass) {\n\t\tcase \"full\":\n\t\t\treturn base;\n\t\tcase \"lean\":\n\t\t\treturn { ...base, blockedToolNames: MODEL_CAPABILITY_LEAN_BLOCKED_TOOLS };\n\t\tcase \"minimal\":\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\tallowedToolNames: MODEL_CAPABILITY_MINIMAL_ALLOWED_TOOLS,\n\t\t\t\tbackgroundLanesEnabled: false,\n\t\t\t};\n\t\tcase \"chat\":\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\tallowedToolNames: MODEL_CAPABILITY_CHAT_ALLOWED_TOOLS,\n\t\t\t\tbackgroundLanesEnabled: false,\n\t\t\t};\n\t}\n}\n\nexport function deriveModelCapabilityProfile(args: {\n\tcontextWindow?: number;\n\tmode?: ModelCapabilityMode;\n}): ModelCapabilityProfile {\n\tconst mode = args.mode ?? \"auto\";\n\tconst contextWindow =\n\t\targs.contextWindow !== undefined && Number.isFinite(args.contextWindow) && args.contextWindow > 0\n\t\t\t? args.contextWindow\n\t\t\t: undefined;\n\tif (mode === \"off\") {\n\t\treturn profileForClass(\"full\", \"detection_disabled\", contextWindow);\n\t}\n\tif (mode !== \"auto\") {\n\t\treturn profileForClass(mode, \"forced_by_setting\", contextWindow);\n\t}\n\n\tif (contextWindow === undefined) {\n\t\t// Metadata missing: defaults, never guesses.\n\t\treturn profileForClass(\"full\", \"unknown_context_window_defaults\", undefined);\n\t}\n\tif (contextWindow >= MODEL_CAPABILITY_FULL_MIN_CONTEXT) {\n\t\treturn profileForClass(\"full\", \"large_context_window\", contextWindow);\n\t}\n\tif (contextWindow >= MODEL_CAPABILITY_LEAN_MIN_CONTEXT) {\n\t\treturn profileForClass(\"lean\", \"lean_context_window\", contextWindow);\n\t}\n\tif (contextWindow >= MODEL_CAPABILITY_MINIMAL_MIN_CONTEXT) {\n\t\treturn profileForClass(\"minimal\", \"minimal_context_window\", contextWindow);\n\t}\n\treturn profileForClass(\"chat\", \"chat_only_context_window\", contextWindow);\n}\n\n/** Apply the profile's allow/block lists to a requested tool-name list, preserving order. */\nexport function filterToolNamesForCapability(toolNames: readonly string[], profile: ModelCapabilityProfile): string[] {\n\tlet filtered = [...toolNames];\n\tif (profile.allowedToolNames !== undefined) {\n\t\tconst allowed = new Set(profile.allowedToolNames);\n\t\tfiltered = filtered.filter((name) => allowed.has(name));\n\t}\n\tif (profile.blockedToolNames !== undefined) {\n\t\tconst blocked = new Set(profile.blockedToolNames);\n\t\tfiltered = filtered.filter((name) => !blocked.has(name));\n\t}\n\treturn filtered;\n}\n\n/**\n * Lane-worker eligibility: a session bound to a worktree-sync lane (`--worktree-lane` /\n * `PI_WORKTREE_LANE`, see worktree-sync/runtime.ts) is expected to drive the FULL multi-step\n * lane-gate/recovery surface -- sync, conflict recovery, land -- unattended. A sub-full capability\n * class or a model with no working native tool-call path cannot reliably drive that surface. This\n * rides the SAME capability system every other adaptation in this file rides (class + context\n * window + the `/toolprobe` verdict) -- no parallel mechanism, no new env var, no new registry field.\n */\nexport type LaneWorkerRefusalReason =\n\t| \"capability_class_below_full\"\n\t| \"context_window_unknown\"\n\t| \"tool_calling_unadvertised\"\n\t| \"tool_calling_demoted\";\n\nexport interface LaneWorkerRefusal {\n\treason: LaneWorkerRefusalReason;\n\tcapabilityClass: ModelCapabilityClass;\n\tcontextWindow?: number;\n}\n\n/**\n * Decide whether the model described by `args` may drive a worktree-sync lane worker. First\n * failure wins, in order: capability class below full; an unknown/undeclared context window (the\n * classifier's own registry-derived SSOT -- see `deriveModelCapabilityProfile`; a full class can\n * still carry an undefined window via the `unknown_context_window_defaults` fallback); no\n * ADVERTISED native tool-call path (`Model.textToolCallProtocol` unset/false -- set true means\n * phone-only); or a GRADED `/toolprobe` demotion to \"text-protocol\"/\"none\". An UNPROBED model (no\n * verdict on record yet) is eligible on its advertised support alone -- unprobed is never treated\n * as demoted. `undefined` means eligible.\n */\nexport function evaluateLaneWorkerRefusal(args: {\n\tcapabilityClass: ModelCapabilityClass;\n\tcontextWindow: number | undefined;\n\ttoolCallingAdvertised: boolean;\n\ttoolCallingDemoted: boolean;\n}): LaneWorkerRefusal | undefined {\n\tconst { capabilityClass, contextWindow, toolCallingAdvertised, toolCallingDemoted } = args;\n\tif (capabilityClass !== \"full\") return { reason: \"capability_class_below_full\", capabilityClass, contextWindow };\n\tif (contextWindow === undefined) return { reason: \"context_window_unknown\", capabilityClass, contextWindow };\n\tif (!toolCallingAdvertised) return { reason: \"tool_calling_unadvertised\", capabilityClass, contextWindow };\n\tif (toolCallingDemoted) return { reason: \"tool_calling_demoted\", capabilityClass, contextWindow };\n\treturn undefined;\n}\n\n/** Stable, greppable prefix for {@link formatLaneWorkerRefusal}'s output. */\nexport const LANE_WORKER_REFUSAL_PREFIX = \"worktree-sync lane-worker refusal:\";\n\n/** Format a refusal into one deterministic, greppable line naming the lane, class, window, and reason. */\nexport function formatLaneWorkerRefusal(refusal: LaneWorkerRefusal, laneKey?: string): string {\n\tconst laneSuffix = laneKey !== undefined ? ` lane=${laneKey}` : \"\";\n\tconst windowText = refusal.contextWindow !== undefined ? String(refusal.contextWindow) : \"unknown\";\n\treturn `${LANE_WORKER_REFUSAL_PREFIX}${laneSuffix} class=${refusal.capabilityClass} contextWindow=${windowText} reason=${refusal.reason}`;\n}\n"]}
1
+ {"version":3,"file":"model-capability.js","sourceRoot":"","sources":["../../src/core/model-capability.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Model capability auto-detection: derive what the harness may load onto a model FROM the model's\n * own metadata (`Model.contextWindow`), so small open models (4k/8k/16k windows, sub-1B params)\n * can still hold a usable chat instead of drowning in the stable prompt, tool schemas, and\n * background-lane prompts. The same class is the single input to prompt shaping and tool/lane gates.\n *\n * Derivation is metadata-first; defaults apply only when the metadata is missing (unknown/zero\n * window keeps today's full behavior rather than guessing). Detection can be disabled or forced\n * per class via the `modelCapability.mode` setting.\n */\n\nexport type ModelCapabilityClass = \"full\" | \"lean\" | \"minimal\" | \"chat\";\n\nexport type ModelCapabilityMode = \"auto\" | \"off\" | ModelCapabilityClass;\n\nexport interface ModelCapabilityProfile {\n\tclass: ModelCapabilityClass;\n\tcontextWindow?: number;\n\treasonCode: string;\n\t/** Hard aggregate character envelope for the stable system prompt; undefined = intentionally unbounded. */\n\tsystemPromptMaxChars: number | undefined;\n\t/** Allow-list; undefined = no allow-list restriction. */\n\tallowedToolNames?: readonly string[];\n\t/** Block-list applied after the allow-list; undefined = nothing blocked. */\n\tblockedToolNames?: readonly string[];\n\t/** Whether idle background lanes (goal auto-continue, research) may run on this model. */\n\tbackgroundLanesEnabled: boolean;\n\t/** Output-token cap for lane isolated completions, scaled to the window. */\n\tlaneMaxOutputTokens: number;\n}\n\n/** Windows at or above this keep the full harness surface. */\nexport const MODEL_CAPABILITY_FULL_MIN_CONTEXT = 32_768;\n/** Windows at or above this keep core tools but shed background-autonomy extras. */\nexport const MODEL_CAPABILITY_LEAN_MIN_CONTEXT = 16_384;\n/** Windows at or above this get the minimal coding set; below is chat-only. */\nexport const MODEL_CAPABILITY_MINIMAL_MIN_CONTEXT = 8_192;\n\n/**\n * Aggregate stable-prompt envelopes. These are deliberately owned beside the classification\n * thresholds so every harness expansion must fit the same profile that owns tools and lanes.\n * Full/off profiles are intentionally unbounded; constrained profiles fail visibly on overflow.\n */\nexport const MODEL_CAPABILITY_SYSTEM_PROMPT_MAX_CHARS: Readonly<Record<ModelCapabilityClass, number | undefined>> = {\n\tfull: undefined,\n\tlean: 8_192,\n\tminimal: 4_096,\n\tchat: 2_048,\n};\n\nexport const MODEL_CAPABILITY_LEAN_BLOCKED_TOOLS: readonly string[] = [\n\t\"delegate\",\n\t\"profile_writer\",\n\t\"context_audit\",\n\t\"goal\",\n\t\"worktree_sync\",\n\t\"improvement_loop\",\n\t\"extensionify\",\n\t\"skillify\",\n\t\"model_fitness\",\n\t\"context_scout\",\n\t\"tmux_agent_manager\",\n];\nexport const MODEL_CAPABILITY_MINIMAL_ALLOWED_TOOLS: readonly string[] = [\n\t\"read\",\n\t\"bash\",\n\t\"python\",\n\t\"powershell\",\n\t\"edit\",\n\t\"write\",\n\t\"ask_question\",\n\t// The executor tool: minimal-class models ARE the daily-ops executors, and its schema is tiny.\n\t\"run_toolkit_script\",\n];\nexport const MODEL_CAPABILITY_CHAT_ALLOWED_TOOLS: readonly string[] = [];\n\nexport const DEFAULT_LANE_MAX_OUTPUT_TOKENS = 2048;\nconst MIN_LANE_MAX_OUTPUT_TOKENS = 256;\n\nfunction laneOutputTokensForWindow(contextWindow: number | undefined): number {\n\tif (contextWindow === undefined || contextWindow <= 0) return DEFAULT_LANE_MAX_OUTPUT_TOKENS;\n\t// A lane completion may use at most an eighth of the window for output, floored so tiny\n\t// windows still produce something parseable.\n\treturn Math.min(DEFAULT_LANE_MAX_OUTPUT_TOKENS, Math.max(MIN_LANE_MAX_OUTPUT_TOKENS, Math.floor(contextWindow / 8)));\n}\n\nfunction profileForClass(\n\tcapabilityClass: ModelCapabilityClass,\n\treasonCode: string,\n\tcontextWindow: number | undefined,\n): ModelCapabilityProfile {\n\tconst base = {\n\t\tclass: capabilityClass,\n\t\treasonCode,\n\t\tsystemPromptMaxChars: MODEL_CAPABILITY_SYSTEM_PROMPT_MAX_CHARS[capabilityClass],\n\t\tbackgroundLanesEnabled: true,\n\t\tlaneMaxOutputTokens: laneOutputTokensForWindow(contextWindow),\n\t\t...(contextWindow !== undefined && contextWindow > 0 ? { contextWindow } : {}),\n\t};\n\tswitch (capabilityClass) {\n\t\tcase \"full\":\n\t\t\treturn base;\n\t\tcase \"lean\":\n\t\t\treturn { ...base, blockedToolNames: MODEL_CAPABILITY_LEAN_BLOCKED_TOOLS };\n\t\tcase \"minimal\":\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\tallowedToolNames: MODEL_CAPABILITY_MINIMAL_ALLOWED_TOOLS,\n\t\t\t\tbackgroundLanesEnabled: false,\n\t\t\t};\n\t\tcase \"chat\":\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\tallowedToolNames: MODEL_CAPABILITY_CHAT_ALLOWED_TOOLS,\n\t\t\t\tbackgroundLanesEnabled: false,\n\t\t\t};\n\t}\n}\n\n/**\n * Mandatory provider-neutral gate for a final system prompt. This intentionally rejects rather\n * than truncates: arbitrary truncation can silently remove security, repair, or project rules.\n */\nexport function enforceModelCapabilitySystemPromptBudget(\n\tsystemPrompt: string,\n\tprofile: Pick<ModelCapabilityProfile, \"class\" | \"systemPromptMaxChars\">,\n): string {\n\tconst maxChars = profile.systemPromptMaxChars;\n\tif (maxChars === undefined || systemPrompt.length <= maxChars) return systemPrompt;\n\tthrow new Error(\n\t\t`${profile.class} system prompt exceeds its ${maxChars}-character capability budget (${systemPrompt.length} characters). Reduce custom, extension, or harness prompt guidance, or select a more capable profile.`,\n\t);\n}\n\nexport function deriveModelCapabilityProfile(args: {\n\tcontextWindow?: number;\n\tmode?: ModelCapabilityMode;\n}): ModelCapabilityProfile {\n\tconst mode = args.mode ?? \"auto\";\n\tconst contextWindow =\n\t\targs.contextWindow !== undefined && Number.isFinite(args.contextWindow) && args.contextWindow > 0\n\t\t\t? args.contextWindow\n\t\t\t: undefined;\n\tif (mode === \"off\") {\n\t\treturn profileForClass(\"full\", \"detection_disabled\", contextWindow);\n\t}\n\tif (mode !== \"auto\") {\n\t\treturn profileForClass(mode, \"forced_by_setting\", contextWindow);\n\t}\n\n\tif (contextWindow === undefined) {\n\t\t// Metadata missing: defaults, never guesses.\n\t\treturn profileForClass(\"full\", \"unknown_context_window_defaults\", undefined);\n\t}\n\tif (contextWindow >= MODEL_CAPABILITY_FULL_MIN_CONTEXT) {\n\t\treturn profileForClass(\"full\", \"large_context_window\", contextWindow);\n\t}\n\tif (contextWindow >= MODEL_CAPABILITY_LEAN_MIN_CONTEXT) {\n\t\treturn profileForClass(\"lean\", \"lean_context_window\", contextWindow);\n\t}\n\tif (contextWindow >= MODEL_CAPABILITY_MINIMAL_MIN_CONTEXT) {\n\t\treturn profileForClass(\"minimal\", \"minimal_context_window\", contextWindow);\n\t}\n\treturn profileForClass(\"chat\", \"chat_only_context_window\", contextWindow);\n}\n\n/** Apply the profile's allow/block lists to a requested tool-name list, preserving order. */\nexport function filterToolNamesForCapability(toolNames: readonly string[], profile: ModelCapabilityProfile): string[] {\n\tlet filtered = [...toolNames];\n\tif (profile.allowedToolNames !== undefined) {\n\t\tconst allowed = new Set(profile.allowedToolNames);\n\t\tfiltered = filtered.filter((name) => allowed.has(name));\n\t}\n\tif (profile.blockedToolNames !== undefined) {\n\t\tconst blocked = new Set(profile.blockedToolNames);\n\t\tfiltered = filtered.filter((name) => !blocked.has(name));\n\t}\n\treturn filtered;\n}\n\n/**\n * Lane-worker eligibility: a session bound to a worktree-sync lane (`--worktree-lane` /\n * `PI_WORKTREE_LANE`, see worktree-sync/runtime.ts) is expected to drive the FULL multi-step\n * lane-gate/recovery surface -- sync, conflict recovery, land -- unattended. A sub-full capability\n * class or a model with no working native tool-call path cannot reliably drive that surface. This\n * rides the SAME capability system every other adaptation in this file rides (class + context\n * window + the `/toolprobe` verdict) -- no parallel mechanism, no new env var, no new registry field.\n */\nexport type LaneWorkerRefusalReason =\n\t| \"capability_class_below_full\"\n\t| \"context_window_unknown\"\n\t| \"tool_calling_unadvertised\"\n\t| \"tool_calling_demoted\";\n\nexport interface LaneWorkerRefusal {\n\treason: LaneWorkerRefusalReason;\n\tcapabilityClass: ModelCapabilityClass;\n\tcontextWindow?: number;\n}\n\n/**\n * Decide whether the model described by `args` may drive a worktree-sync lane worker. First\n * failure wins, in order: capability class below full; an unknown/undeclared context window (the\n * classifier's own registry-derived SSOT -- see `deriveModelCapabilityProfile`; a full class can\n * still carry an undefined window via the `unknown_context_window_defaults` fallback); no\n * ADVERTISED native tool-call path (`Model.textToolCallProtocol` unset/false -- set true means\n * phone-only); or a GRADED `/toolprobe` demotion to \"text-protocol\"/\"none\". An UNPROBED model (no\n * verdict on record yet) is eligible on its advertised support alone -- unprobed is never treated\n * as demoted. `undefined` means eligible.\n */\nexport function evaluateLaneWorkerRefusal(args: {\n\tcapabilityClass: ModelCapabilityClass;\n\tcontextWindow: number | undefined;\n\ttoolCallingAdvertised: boolean;\n\ttoolCallingDemoted: boolean;\n}): LaneWorkerRefusal | undefined {\n\tconst { capabilityClass, contextWindow, toolCallingAdvertised, toolCallingDemoted } = args;\n\tif (capabilityClass !== \"full\") return { reason: \"capability_class_below_full\", capabilityClass, contextWindow };\n\tif (contextWindow === undefined) return { reason: \"context_window_unknown\", capabilityClass, contextWindow };\n\tif (!toolCallingAdvertised) return { reason: \"tool_calling_unadvertised\", capabilityClass, contextWindow };\n\tif (toolCallingDemoted) return { reason: \"tool_calling_demoted\", capabilityClass, contextWindow };\n\treturn undefined;\n}\n\n/** Stable, greppable prefix for {@link formatLaneWorkerRefusal}'s output. */\nexport const LANE_WORKER_REFUSAL_PREFIX = \"worktree-sync lane-worker refusal:\";\n\n/** Format a refusal into one deterministic, greppable line naming the lane, class, window, and reason. */\nexport function formatLaneWorkerRefusal(refusal: LaneWorkerRefusal, laneKey?: string): string {\n\tconst laneSuffix = laneKey !== undefined ? ` lane=${laneKey}` : \"\";\n\tconst windowText = refusal.contextWindow !== undefined ? String(refusal.contextWindow) : \"unknown\";\n\treturn `${LANE_WORKER_REFUSAL_PREFIX}${laneSuffix} class=${refusal.capabilityClass} contextWindow=${windowText} reason=${refusal.reason}`;\n}\n"]}
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * Model registry - manages built-in and custom models, provides API key resolution.
3
3
  */
4
- import { type Api, type AssistantMessageEventStream, type Context, type Model, type OAuthProviderInterface, type SimpleStreamOptions } from "@caupulican/pi-ai";
4
+ import { type OAuthProviderInterface } from "@caupulican/pi-ai/oauth";
5
+ import type { Api, AssistantMessageEventStream, Context, Model, SimpleStreamOptions } from "@caupulican/pi-ai/types";
5
6
  import { type Static, Type } from "typebox";
6
7
  import type { AuthStatus, AuthStorage } from "./auth-storage.ts";
7
8
  import { clearConfigValueCache } from "./resolve-config-value.ts";
@@ -120,6 +121,7 @@ export declare class ModelRegistry {
120
121
  private providerRequestConfigs;
121
122
  private modelRequestHeaders;
122
123
  private registeredProviders;
124
+ private providerModelScopes;
123
125
  private loadError;
124
126
  readonly authStorage: AuthStorage;
125
127
  private modelsJsonPath;
@@ -152,6 +154,9 @@ export declare class ModelRegistry {
152
154
  * This is a fast check that doesn't refresh OAuth tokens.
153
155
  */
154
156
  getAvailable(): Model<Api>[];
157
+ /** Restrict one provider to an exact, externally verified set of model IDs. */
158
+ setProviderModelScope(provider: string, modelIds: Iterable<string> | undefined): void;
159
+ getProviderModelScope(provider: string): string[] | undefined;
155
160
  /**
156
161
  * Find a model by provider and ID.
157
162
  */
@@ -265,6 +270,7 @@ export interface ModelRegistryReloadSnapshot {
265
270
  providerRequestConfigs: Map<string, ProviderRequestConfig>;
266
271
  modelRequestHeaders: Map<string, Record<string, string>>;
267
272
  registeredProviders: Map<string, ProviderConfigInput>;
273
+ providerModelScopes: Map<string, Set<string>>;
268
274
  loadError: string | undefined;
269
275
  }
270
276
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"model-registry.d.ts","sourceRoot":"","sources":["../../src/core/model-registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model-registry.d.ts","sourceRoot":"","sources":["../../src/core/model-registry.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,11 @@
1
1
  /**
2
2
  * Model registry - manages built-in and custom models, provides API key resolution.
3
3
  */
4
- import { getEnvAuthHeaders, getModels, getProviders, registerApiProvider, resetApiProviders, } from "@caupulican/pi-ai";
4
+ import { registerApiProvider } from "@caupulican/pi-ai/api-registry";
5
+ import { getEnvAuthHeaders } from "@caupulican/pi-ai/env-api-keys";
6
+ import { getModels, getProviders } from "@caupulican/pi-ai/models";
5
7
  import { registerOAuthProvider, resetOAuthProviders } from "@caupulican/pi-ai/oauth";
8
+ import { resetApiProviders } from "@caupulican/pi-ai/register-builtins";
6
9
  import { formatValidationPath } from "@caupulican/pi-ai/validation-path";
7
10
  import { existsSync, readFileSync } from "fs";
8
11
  import { join } from "path";
@@ -293,6 +296,7 @@ export class ModelRegistry {
293
296
  this.providerRequestConfigs = new Map();
294
297
  this.modelRequestHeaders = new Map();
295
298
  this.registeredProviders = new Map();
299
+ this.providerModelScopes = new Map();
296
300
  this.loadError = undefined;
297
301
  this.authStorage = authStorage;
298
302
  this.modelsJsonPath = modelsJsonPath ? normalizePath(modelsJsonPath) : undefined;
@@ -532,6 +536,18 @@ export class ModelRegistry {
532
536
  getAvailable() {
533
537
  return this.models.filter((m) => this.hasConfiguredAuth(m));
534
538
  }
539
+ /** Restrict one provider to an exact, externally verified set of model IDs. */
540
+ setProviderModelScope(provider, modelIds) {
541
+ if (modelIds === undefined) {
542
+ this.providerModelScopes.delete(provider);
543
+ return;
544
+ }
545
+ this.providerModelScopes.set(provider, new Set([...modelIds].map((id) => id.trim()).filter((id) => id.length > 0)));
546
+ }
547
+ getProviderModelScope(provider) {
548
+ const scope = this.providerModelScopes.get(provider);
549
+ return scope ? [...scope] : undefined;
550
+ }
535
551
  /**
536
552
  * Find a model by provider and ID.
537
553
  */
@@ -542,6 +558,9 @@ export class ModelRegistry {
542
558
  * Get API key for a model.
543
559
  */
544
560
  hasConfiguredAuth(model) {
561
+ const scope = this.providerModelScopes.get(model.provider);
562
+ if (scope && !scope.has(model.id))
563
+ return false;
545
564
  if (model.provider === "llama-cpp") {
546
565
  return true;
547
566
  }
@@ -694,6 +713,7 @@ export class ModelRegistry {
694
713
  providerRequestConfigs: new Map(Array.from(this.providerRequestConfigs, ([name, config]) => [name, { ...config }])),
695
714
  modelRequestHeaders: new Map(Array.from(this.modelRequestHeaders, ([key, headers]) => [key, { ...headers }])),
696
715
  registeredProviders: new Map(Array.from(this.registeredProviders, ([name, config]) => [name, cloneProviderConfigInput(config)])),
716
+ providerModelScopes: new Map(Array.from(this.providerModelScopes, ([name, modelIds]) => [name, new Set(modelIds)])),
697
717
  loadError: this.loadError,
698
718
  };
699
719
  }
@@ -703,6 +723,7 @@ export class ModelRegistry {
703
723
  this.providerRequestConfigs = new Map(Array.from(snapshot.providerRequestConfigs, ([name, config]) => [name, { ...config }]));
704
724
  this.modelRequestHeaders = new Map(Array.from(snapshot.modelRequestHeaders, ([key, headers]) => [key, { ...headers }]));
705
725
  this.registeredProviders = new Map(Array.from(snapshot.registeredProviders, ([name, config]) => [name, cloneProviderConfigInput(config)]));
726
+ this.providerModelScopes = new Map(Array.from(snapshot.providerModelScopes, ([name, modelIds]) => [name, new Set(modelIds)]));
706
727
  this.loadError = snapshot.loadError;
707
728
  resetApiProviders();
708
729
  resetOAuthProviders();