open-multi-agent-kit 0.90.7 → 0.90.9

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 (331) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +17 -10
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +5 -1
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/commands/doctor-provider-cli.d.ts +33 -0
  7. package/dist/commands/doctor-provider-cli.d.ts.map +1 -0
  8. package/dist/commands/doctor-provider-cli.js +215 -0
  9. package/dist/commands/doctor-provider-cli.js.map +1 -0
  10. package/dist/commands/doctor-provider-transport.d.ts +35 -0
  11. package/dist/commands/doctor-provider-transport.d.ts.map +1 -0
  12. package/dist/commands/doctor-provider-transport.js +185 -0
  13. package/dist/commands/doctor-provider-transport.js.map +1 -0
  14. package/dist/commands/doctor-provider.d.ts +121 -7
  15. package/dist/commands/doctor-provider.d.ts.map +1 -1
  16. package/dist/commands/doctor-provider.js +1295 -102
  17. package/dist/commands/doctor-provider.js.map +1 -1
  18. package/dist/commands/session-doctor-cli.d.ts +43 -0
  19. package/dist/commands/session-doctor-cli.d.ts.map +1 -0
  20. package/dist/commands/session-doctor-cli.js +494 -0
  21. package/dist/commands/session-doctor-cli.js.map +1 -0
  22. package/dist/commands/verify-ci.d.ts +21 -0
  23. package/dist/commands/verify-ci.d.ts.map +1 -0
  24. package/dist/commands/verify-ci.js +66 -0
  25. package/dist/commands/verify-ci.js.map +1 -0
  26. package/dist/core/agent-session-services.d.ts +3 -0
  27. package/dist/core/agent-session-services.d.ts.map +1 -1
  28. package/dist/core/agent-session-services.js +3 -0
  29. package/dist/core/agent-session-services.js.map +1 -1
  30. package/dist/core/agent-session.d.ts +116 -2
  31. package/dist/core/agent-session.d.ts.map +1 -1
  32. package/dist/core/agent-session.js +1015 -71
  33. package/dist/core/agent-session.js.map +1 -1
  34. package/dist/core/agent-tool-settings.d.ts +35 -0
  35. package/dist/core/agent-tool-settings.d.ts.map +1 -0
  36. package/dist/core/agent-tool-settings.js +155 -0
  37. package/dist/core/agent-tool-settings.js.map +1 -0
  38. package/dist/core/atomic-session-file.d.ts +14 -0
  39. package/dist/core/atomic-session-file.d.ts.map +1 -0
  40. package/dist/core/atomic-session-file.js +104 -0
  41. package/dist/core/atomic-session-file.js.map +1 -0
  42. package/dist/core/compaction/compaction.d.ts +6 -0
  43. package/dist/core/compaction/compaction.d.ts.map +1 -1
  44. package/dist/core/compaction/compaction.js +12 -1
  45. package/dist/core/compaction/compaction.js.map +1 -1
  46. package/dist/core/compaction/hysteresis.d.ts +27 -0
  47. package/dist/core/compaction/hysteresis.d.ts.map +1 -0
  48. package/dist/core/compaction/hysteresis.js +84 -0
  49. package/dist/core/compaction/hysteresis.js.map +1 -0
  50. package/dist/core/compaction/index.d.ts +2 -0
  51. package/dist/core/compaction/index.d.ts.map +1 -1
  52. package/dist/core/compaction/index.js +2 -0
  53. package/dist/core/compaction/index.js.map +1 -1
  54. package/dist/core/compaction/transaction.d.ts +172 -0
  55. package/dist/core/compaction/transaction.d.ts.map +1 -0
  56. package/dist/core/compaction/transaction.js +824 -0
  57. package/dist/core/compaction/transaction.js.map +1 -0
  58. package/dist/core/context-budget-governor-v2.d.ts +2 -1
  59. package/dist/core/context-budget-governor-v2.d.ts.map +1 -1
  60. package/dist/core/context-budget-governor-v2.js +2 -1
  61. package/dist/core/context-budget-governor-v2.js.map +1 -1
  62. package/dist/core/context-budget-headroom.d.ts.map +1 -1
  63. package/dist/core/context-budget-headroom.js +5 -1
  64. package/dist/core/context-budget-headroom.js.map +1 -1
  65. package/dist/core/context-budget-reserved-tokens.d.ts +110 -0
  66. package/dist/core/context-budget-reserved-tokens.d.ts.map +1 -0
  67. package/dist/core/context-budget-reserved-tokens.js +188 -0
  68. package/dist/core/context-budget-reserved-tokens.js.map +1 -0
  69. package/dist/core/context-budget-v2-cache-invalidation.d.ts +133 -0
  70. package/dist/core/context-budget-v2-cache-invalidation.d.ts.map +1 -0
  71. package/dist/core/context-budget-v2-cache-invalidation.js +452 -0
  72. package/dist/core/context-budget-v2-cache-invalidation.js.map +1 -0
  73. package/dist/core/context-budget-v2-cache-keys.d.ts +3 -0
  74. package/dist/core/context-budget-v2-cache-keys.d.ts.map +1 -1
  75. package/dist/core/context-budget-v2-cache-keys.js +6 -0
  76. package/dist/core/context-budget-v2-cache-keys.js.map +1 -1
  77. package/dist/core/context-budget-v2-cache-provider.d.ts +8 -2
  78. package/dist/core/context-budget-v2-cache-provider.d.ts.map +1 -1
  79. package/dist/core/context-budget-v2-cache-provider.js +28 -5
  80. package/dist/core/context-budget-v2-cache-provider.js.map +1 -1
  81. package/dist/core/context-budget-v2-plan-cache-keys.d.ts.map +1 -1
  82. package/dist/core/context-budget-v2-plan-cache-keys.js +1 -0
  83. package/dist/core/context-budget-v2-plan-cache-keys.js.map +1 -1
  84. package/dist/core/context-budget-v2-planner.d.ts.map +1 -1
  85. package/dist/core/context-budget-v2-planner.js +1 -0
  86. package/dist/core/context-budget-v2-planner.js.map +1 -1
  87. package/dist/core/context-budget-v2-selection.d.ts.map +1 -1
  88. package/dist/core/context-budget-v2-selection.js +9 -0
  89. package/dist/core/context-budget-v2-selection.js.map +1 -1
  90. package/dist/core/context-budget-v2-types.d.ts +4 -0
  91. package/dist/core/context-budget-v2-types.d.ts.map +1 -1
  92. package/dist/core/context-budget-v2-types.js.map +1 -1
  93. package/dist/core/durable-file-directory.d.ts +4 -0
  94. package/dist/core/durable-file-directory.d.ts.map +1 -0
  95. package/dist/core/durable-file-directory.js +76 -0
  96. package/dist/core/durable-file-directory.js.map +1 -0
  97. package/dist/core/durable-file-identity.d.ts +26 -0
  98. package/dist/core/durable-file-identity.d.ts.map +1 -0
  99. package/dist/core/durable-file-identity.js +118 -0
  100. package/dist/core/durable-file-identity.js.map +1 -0
  101. package/dist/core/durable-file-io.d.ts +29 -0
  102. package/dist/core/durable-file-io.d.ts.map +1 -0
  103. package/dist/core/durable-file-io.js +179 -0
  104. package/dist/core/durable-file-io.js.map +1 -0
  105. package/dist/core/durable-file-lock-cleanup.d.ts +12 -0
  106. package/dist/core/durable-file-lock-cleanup.d.ts.map +1 -0
  107. package/dist/core/durable-file-lock-cleanup.js +39 -0
  108. package/dist/core/durable-file-lock-cleanup.js.map +1 -0
  109. package/dist/core/durable-file-lock-owner.d.ts +18 -0
  110. package/dist/core/durable-file-lock-owner.d.ts.map +1 -0
  111. package/dist/core/durable-file-lock-owner.js +78 -0
  112. package/dist/core/durable-file-lock-owner.js.map +1 -0
  113. package/dist/core/durable-file-lock-storage.d.ts +35 -0
  114. package/dist/core/durable-file-lock-storage.d.ts.map +1 -0
  115. package/dist/core/durable-file-lock-storage.js +263 -0
  116. package/dist/core/durable-file-lock-storage.js.map +1 -0
  117. package/dist/core/durable-file-mode.d.ts +8 -0
  118. package/dist/core/durable-file-mode.d.ts.map +1 -0
  119. package/dist/core/durable-file-mode.js +41 -0
  120. package/dist/core/durable-file-mode.js.map +1 -0
  121. package/dist/core/extensions/loader.d.ts +12 -0
  122. package/dist/core/extensions/loader.d.ts.map +1 -1
  123. package/dist/core/extensions/loader.js +50 -37
  124. package/dist/core/extensions/loader.js.map +1 -1
  125. package/dist/core/extensions/types.d.ts +2 -0
  126. package/dist/core/extensions/types.d.ts.map +1 -1
  127. package/dist/core/extensions/types.js.map +1 -1
  128. package/dist/core/index.d.ts +6 -2
  129. package/dist/core/index.d.ts.map +1 -1
  130. package/dist/core/index.js +5 -0
  131. package/dist/core/index.js.map +1 -1
  132. package/dist/core/loop-gates.d.ts.map +1 -1
  133. package/dist/core/loop-gates.js +25 -1
  134. package/dist/core/loop-gates.js.map +1 -1
  135. package/dist/core/model-resolver.d.ts.map +1 -1
  136. package/dist/core/model-resolver.js +1 -1
  137. package/dist/core/model-resolver.js.map +1 -1
  138. package/dist/core/pi-package-intake.d.ts +1 -0
  139. package/dist/core/pi-package-intake.d.ts.map +1 -1
  140. package/dist/core/pi-package-intake.js +7 -0
  141. package/dist/core/pi-package-intake.js.map +1 -1
  142. package/dist/core/redaction.d.ts +8 -0
  143. package/dist/core/redaction.d.ts.map +1 -0
  144. package/dist/core/redaction.js +31 -0
  145. package/dist/core/redaction.js.map +1 -0
  146. package/dist/core/resource-loader.d.ts.map +1 -1
  147. package/dist/core/resource-loader.js +36 -0
  148. package/dist/core/resource-loader.js.map +1 -1
  149. package/dist/core/run-journal-store.d.ts +53 -0
  150. package/dist/core/run-journal-store.d.ts.map +1 -0
  151. package/dist/core/run-journal-store.js +278 -0
  152. package/dist/core/run-journal-store.js.map +1 -0
  153. package/dist/core/run-journal.d.ts +172 -0
  154. package/dist/core/run-journal.d.ts.map +1 -0
  155. package/dist/core/run-journal.js +1053 -0
  156. package/dist/core/run-journal.js.map +1 -0
  157. package/dist/core/sdk.d.ts +7 -0
  158. package/dist/core/sdk.d.ts.map +1 -1
  159. package/dist/core/sdk.js +94 -3
  160. package/dist/core/sdk.js.map +1 -1
  161. package/dist/core/session-doctor-plan.d.ts +128 -0
  162. package/dist/core/session-doctor-plan.d.ts.map +1 -0
  163. package/dist/core/session-doctor-plan.js +833 -0
  164. package/dist/core/session-doctor-plan.js.map +1 -0
  165. package/dist/core/session-file-compaction.d.ts +6 -0
  166. package/dist/core/session-file-compaction.d.ts.map +1 -0
  167. package/dist/core/session-file-compaction.js +169 -0
  168. package/dist/core/session-file-compaction.js.map +1 -0
  169. package/dist/core/session-file-head.d.ts +10 -0
  170. package/dist/core/session-file-head.d.ts.map +1 -0
  171. package/dist/core/session-file-head.js +78 -0
  172. package/dist/core/session-file-head.js.map +1 -0
  173. package/dist/core/session-file-persistence.d.ts +30 -0
  174. package/dist/core/session-file-persistence.d.ts.map +1 -0
  175. package/dist/core/session-file-persistence.js +106 -0
  176. package/dist/core/session-file-persistence.js.map +1 -0
  177. package/dist/core/session-integrity.d.ts +43 -0
  178. package/dist/core/session-integrity.d.ts.map +1 -0
  179. package/dist/core/session-integrity.js +420 -0
  180. package/dist/core/session-integrity.js.map +1 -0
  181. package/dist/core/session-manager.d.ts +24 -4
  182. package/dist/core/session-manager.d.ts.map +1 -1
  183. package/dist/core/session-manager.js +242 -125
  184. package/dist/core/session-manager.js.map +1 -1
  185. package/dist/core/session-owner-lease.d.ts +22 -0
  186. package/dist/core/session-owner-lease.d.ts.map +1 -0
  187. package/dist/core/session-owner-lease.js +176 -0
  188. package/dist/core/session-owner-lease.js.map +1 -0
  189. package/dist/core/session-path-policy.d.ts +132 -0
  190. package/dist/core/session-path-policy.d.ts.map +1 -0
  191. package/dist/core/session-path-policy.js +780 -0
  192. package/dist/core/session-path-policy.js.map +1 -0
  193. package/dist/core/session-repair-plan.d.ts +49 -0
  194. package/dist/core/session-repair-plan.d.ts.map +1 -0
  195. package/dist/core/session-repair-plan.js +202 -0
  196. package/dist/core/session-repair-plan.js.map +1 -0
  197. package/dist/core/session-termination.d.ts +100 -0
  198. package/dist/core/session-termination.d.ts.map +1 -0
  199. package/dist/core/session-termination.js +403 -0
  200. package/dist/core/session-termination.js.map +1 -0
  201. package/dist/core/settings-manager.d.ts +32 -0
  202. package/dist/core/settings-manager.d.ts.map +1 -1
  203. package/dist/core/settings-manager.js +52 -5
  204. package/dist/core/settings-manager.js.map +1 -1
  205. package/dist/core/system-prompt.d.ts.map +1 -1
  206. package/dist/core/system-prompt.js +1 -1
  207. package/dist/core/system-prompt.js.map +1 -1
  208. package/dist/core/verified-bash-adapter.d.ts +36 -0
  209. package/dist/core/verified-bash-adapter.d.ts.map +1 -0
  210. package/dist/core/verified-bash-adapter.js +90 -0
  211. package/dist/core/verified-bash-adapter.js.map +1 -0
  212. package/dist/guardrails/command-redaction.d.ts +32 -0
  213. package/dist/guardrails/command-redaction.d.ts.map +1 -0
  214. package/dist/guardrails/command-redaction.js +776 -0
  215. package/dist/guardrails/command-redaction.js.map +1 -0
  216. package/dist/guardrails/evidence-attestation.d.ts +31 -0
  217. package/dist/guardrails/evidence-attestation.d.ts.map +1 -0
  218. package/dist/guardrails/evidence-attestation.js +178 -0
  219. package/dist/guardrails/evidence-attestation.js.map +1 -0
  220. package/dist/guardrails/evidence-receipt-store.d.ts +33 -0
  221. package/dist/guardrails/evidence-receipt-store.d.ts.map +1 -0
  222. package/dist/guardrails/evidence-receipt-store.js +446 -0
  223. package/dist/guardrails/evidence-receipt-store.js.map +1 -0
  224. package/dist/guardrails/evidence-receipt.d.ts +58 -0
  225. package/dist/guardrails/evidence-receipt.d.ts.map +1 -0
  226. package/dist/guardrails/evidence-receipt.js +389 -0
  227. package/dist/guardrails/evidence-receipt.js.map +1 -0
  228. package/dist/guardrails/evidence-system.d.ts +40 -9
  229. package/dist/guardrails/evidence-system.d.ts.map +1 -1
  230. package/dist/guardrails/evidence-system.js +379 -83
  231. package/dist/guardrails/evidence-system.js.map +1 -1
  232. package/dist/guardrails/replay-ledger-io.d.ts +6 -0
  233. package/dist/guardrails/replay-ledger-io.d.ts.map +1 -0
  234. package/dist/guardrails/replay-ledger-io.js +42 -0
  235. package/dist/guardrails/replay-ledger-io.js.map +1 -0
  236. package/dist/guardrails/replay-ledger-lock-owner.d.ts +32 -0
  237. package/dist/guardrails/replay-ledger-lock-owner.d.ts.map +1 -0
  238. package/dist/guardrails/replay-ledger-lock-owner.js +138 -0
  239. package/dist/guardrails/replay-ledger-lock-owner.js.map +1 -0
  240. package/dist/guardrails/replay-ledger-lock.d.ts +24 -0
  241. package/dist/guardrails/replay-ledger-lock.d.ts.map +1 -0
  242. package/dist/guardrails/replay-ledger-lock.js +135 -0
  243. package/dist/guardrails/replay-ledger-lock.js.map +1 -0
  244. package/dist/guardrails/replay-ledger-mutation-gate.d.ts +24 -0
  245. package/dist/guardrails/replay-ledger-mutation-gate.d.ts.map +1 -0
  246. package/dist/guardrails/replay-ledger-mutation-gate.js +205 -0
  247. package/dist/guardrails/replay-ledger-mutation-gate.js.map +1 -0
  248. package/dist/guardrails/replay-ledger-quarantine.d.ts +2 -0
  249. package/dist/guardrails/replay-ledger-quarantine.d.ts.map +1 -0
  250. package/dist/guardrails/replay-ledger-quarantine.js +19 -0
  251. package/dist/guardrails/replay-ledger-quarantine.js.map +1 -0
  252. package/dist/guardrails/replay-ledger-store.d.ts +32 -0
  253. package/dist/guardrails/replay-ledger-store.d.ts.map +1 -0
  254. package/dist/guardrails/replay-ledger-store.js +211 -0
  255. package/dist/guardrails/replay-ledger-store.js.map +1 -0
  256. package/dist/guardrails/shell-command-name-glob.d.ts +3 -0
  257. package/dist/guardrails/shell-command-name-glob.d.ts.map +1 -0
  258. package/dist/guardrails/shell-command-name-glob.js +233 -0
  259. package/dist/guardrails/shell-command-name-glob.js.map +1 -0
  260. package/dist/guardrails/shell-command-option.d.ts +7 -0
  261. package/dist/guardrails/shell-command-option.d.ts.map +1 -0
  262. package/dist/guardrails/shell-command-option.js +24 -0
  263. package/dist/guardrails/shell-command-option.js.map +1 -0
  264. package/dist/guardrails/shell-command-tokenizer.d.ts +29 -0
  265. package/dist/guardrails/shell-command-tokenizer.d.ts.map +1 -0
  266. package/dist/guardrails/shell-command-tokenizer.js +145 -0
  267. package/dist/guardrails/shell-command-tokenizer.js.map +1 -0
  268. package/dist/guardrails/shell-command-wrapper.d.ts +18 -0
  269. package/dist/guardrails/shell-command-wrapper.d.ts.map +1 -0
  270. package/dist/guardrails/shell-command-wrapper.js +42 -0
  271. package/dist/guardrails/shell-command-wrapper.js.map +1 -0
  272. package/dist/guardrails/verified-executor.d.ts +65 -0
  273. package/dist/guardrails/verified-executor.d.ts.map +1 -0
  274. package/dist/guardrails/verified-executor.js +171 -0
  275. package/dist/guardrails/verified-executor.js.map +1 -0
  276. package/dist/guardrails/workspace-fingerprint.d.ts +23 -0
  277. package/dist/guardrails/workspace-fingerprint.d.ts.map +1 -0
  278. package/dist/guardrails/workspace-fingerprint.js +634 -0
  279. package/dist/guardrails/workspace-fingerprint.js.map +1 -0
  280. package/dist/index.d.ts +15 -3
  281. package/dist/index.d.ts.map +1 -1
  282. package/dist/index.js +13 -1
  283. package/dist/index.js.map +1 -1
  284. package/dist/main.d.ts.map +1 -1
  285. package/dist/main.js +12 -0
  286. package/dist/main.js.map +1 -1
  287. package/dist/modes/interactive/components/control-panel-layout.d.ts.map +1 -1
  288. package/dist/modes/interactive/components/control-panel-layout.js +1 -1
  289. package/dist/modes/interactive/components/control-panel-layout.js.map +1 -1
  290. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  291. package/dist/modes/interactive/components/footer.js +1 -1
  292. package/dist/modes/interactive/components/footer.js.map +1 -1
  293. package/dist/modes/interactive/interactive-mode.d.ts +3 -0
  294. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  295. package/dist/modes/interactive/interactive-mode.js +59 -9
  296. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  297. package/dist/modes/print-mode.d.ts.map +1 -1
  298. package/dist/modes/print-mode.js +43 -2
  299. package/dist/modes/print-mode.js.map +1 -1
  300. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  301. package/dist/modes/rpc/rpc-mode.js +23 -5
  302. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  303. package/dist/modes/rpc/rpc-types.d.ts +3 -0
  304. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  305. package/dist/modes/rpc/rpc-types.js.map +1 -1
  306. package/dist/types/evidence.d.ts +215 -1
  307. package/dist/types/evidence.d.ts.map +1 -1
  308. package/dist/types/evidence.js.map +1 -1
  309. package/dist/verify-ci.d.ts +3 -0
  310. package/dist/verify-ci.d.ts.map +1 -0
  311. package/dist/verify-ci.js +30 -0
  312. package/dist/verify-ci.js.map +1 -0
  313. package/docs/compaction.md +44 -4
  314. package/docs/extensions.md +2 -0
  315. package/docs/providers.md +6 -0
  316. package/docs/sdk.md +238 -1
  317. package/docs/settings.md +67 -4
  318. package/docs/usage.md +38 -0
  319. package/examples/extensions/correctness-wall/README.md +6 -6
  320. package/examples/extensions/correctness-wall/index.ts +37 -11
  321. package/examples/extensions/custom-provider-anthropic/package-lock.json +5 -5
  322. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  323. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  324. package/examples/extensions/gondolin/package-lock.json +2 -2
  325. package/examples/extensions/gondolin/package.json +1 -1
  326. package/examples/extensions/sandbox/package-lock.json +2 -2
  327. package/examples/extensions/sandbox/package.json +1 -1
  328. package/examples/extensions/with-deps/package-lock.json +4 -4
  329. package/examples/extensions/with-deps/package.json +1 -1
  330. package/npm-shrinkwrap.json +12 -12
  331. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"loop-gates.js","sourceRoot":"","sources":["../../src/core/loop-gates.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tLoopDefinition,\n\tLoopRunOutcome,\n\tLoopState,\n\tLoopValidationDiagnostic,\n\tLoopWorkItem,\n} from \"./loop-types.ts\";\n\nexport type LoopGateAction = \"allow\" | \"block\" | \"human-gate\" | \"escalate\";\n\nexport type LoopVerifierStatus = \"pass\" | \"fail\" | \"blocked\";\n\nexport interface LoopVerifierEvidence {\n\treadonly independent: boolean;\n\treadonly status?: LoopVerifierStatus;\n\treadonly evidenceRefs?: readonly string[];\n\treadonly verifierId?: string;\n\treadonly implementerId?: string;\n}\n\nexport interface LoopHumanGateEvidence {\n\treadonly approved: boolean;\n\treadonly approvalRef?: string;\n}\n\nexport interface LoopWorktreeEvidence {\n\treadonly isolated: boolean;\n\treadonly worktreeId?: string;\n\treadonly branch?: string;\n\treadonly cleanCheckout?: boolean;\n}\n\nexport interface LoopDurableStateEvidence {\n\treadonly stateRevision?: string;\n\treadonly runLogRef?: string;\n\treadonly budgetReservationId?: string;\n}\n\nexport interface LoopGateEvidence {\n\treadonly writeScope?: readonly string[];\n\treadonly changedFiles?: readonly string[];\n\treadonly evidenceRefs?: readonly string[];\n\treadonly verifier?: LoopVerifierEvidence;\n\treadonly humanGate?: LoopHumanGateEvidence;\n\treadonly worktree?: LoopWorktreeEvidence;\n\treadonly durableState?: LoopDurableStateEvidence;\n}\n\nexport interface LoopSafetyGateResult {\n\treadonly passed: boolean;\n\treadonly action: LoopGateAction;\n\treadonly outcome?: LoopRunOutcome;\n\treadonly diagnostics: readonly LoopValidationDiagnostic[];\n}\n\nexport interface LoopWriteScopeValidationResult {\n\treadonly passed: boolean;\n\treadonly diagnostics: readonly LoopValidationDiagnostic[];\n}\n\nconst TOKEN_STOP_WORDS = new Set([\n\t\"a\",\n\t\"an\",\n\t\"and\",\n\t\"are\",\n\t\"as\",\n\t\"for\",\n\t\"in\",\n\t\"inside\",\n\t\"is\",\n\t\"of\",\n\t\"on\",\n\t\"or\",\n\t\"the\",\n\t\"to\",\n\t\"with\",\n]);\n\nexport function evaluateLoopSafetyGates(\n\tdefinition: LoopDefinition,\n\tstate: LoopState,\n\titem: LoopWorkItem,\n\tevidence: LoopGateEvidence,\n): LoopSafetyGateResult {\n\tconst diagnostics: LoopValidationDiagnostic[] = [];\n\n\tif (state.killSwitch) {\n\t\tdiagnostics.push({ code: \"loop-kill-switch\", message: \"Loop kill switch is active.\" });\n\t}\n\tif (state.status === \"paused\" || state.status === \"retired\") {\n\t\tdiagnostics.push({ code: \"loop-not-active\", message: `Loop status ${state.status} cannot take action.` });\n\t}\n\n\tif (item.attemptCount >= definition.budget.maxAttemptsPerItem) {\n\t\tdiagnostics.push({\n\t\t\tcode: \"max-attempts-exceeded\",\n\t\t\tmessage: `Item ${item.id} reached maxAttemptsPerItem=${definition.budget.maxAttemptsPerItem}.`,\n\t\t});\n\t}\n\n\tif (!evidence.writeScope) {\n\t\tdiagnostics.push({ code: \"write-scope-missing\", message: \"Exact writeScope evidence is required.\" });\n\t} else {\n\t\tdiagnostics.push(...validateLoopWriteScope(definition, evidence.writeScope).diagnostics);\n\t\tdiagnostics.push(...validateRequestedWriteScopeDoesNotOverlapDenied(definition, evidence.writeScope));\n\t}\n\n\tif (evidence.writeScope && evidence.changedFiles) {\n\t\tdiagnostics.push(...validateChangedFilesWithinRequestedScope(evidence.writeScope, evidence.changedFiles));\n\t}\n\n\tif (requiresWorktreeIsolation(definition)) {\n\t\tdiagnostics.push(...validateWorktreeEvidence(definition, evidence.worktree));\n\t}\n\n\tif (definition.durableState?.requireReplayableEvidence === true) {\n\t\tdiagnostics.push(...validateDurableStateEvidence(evidence.durableState));\n\t}\n\n\tif (requiresHumanApproval(definition, item)) {\n\t\tconst approvalRef = evidence.humanGate?.approvalRef?.trim();\n\t\tconst approvalRefSatisfied = definition.humanGates?.approvalRefsRequired === false || Boolean(approvalRef);\n\t\tif (evidence.humanGate?.approved !== true || !approvalRefSatisfied) {\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: \"human-gate-required\",\n\t\t\t\tmessage: \"High-risk work item requires human approval evidence.\",\n\t\t\t});\n\t\t}\n\t}\n\n\tif (!hasEvidenceRefs(evidence.evidenceRefs)) {\n\t\tdiagnostics.push({ code: \"evidence-refs-missing\", message: \"Completion evidenceRefs are required.\" });\n\t}\n\n\tif (requiresIndependentVerifier(definition)) {\n\t\tdiagnostics.push(...validateIndependentVerifier(evidence.verifier));\n\t}\n\n\treturn safetyGateResult(diagnostics);\n}\n\nexport function calculateLoopDriftScore(definition: LoopDefinition, item: LoopWorkItem): number {\n\tconst itemTokens = tokenize([item.title, item.sourceRef, item.actingOn].join(\" \"));\n\tconst objectiveTokens = tokenize(definition.objective);\n\tconst objectiveOverlap = overlapRatio(itemTokens, objectiveTokens);\n\tconst nonGoalOverlap = Math.max(\n\t\t0,\n\t\t...definition.nonGoals.map((nonGoal) => overlapRatio(itemTokens, tokenize(nonGoal))),\n\t);\n\tconst scopeMatched = matchesWatchedScope(definition, item);\n\n\tlet score = 0.45;\n\tscore -= objectiveOverlap * 0.25;\n\tscore += objectiveOverlap === 0 ? 0.2 : 0;\n\tscore += scopeMatched ? -0.2 : 0.2;\n\tscore += nonGoalOverlap * 0.7;\n\n\treturn clamp01(score);\n}\n\nexport function validateLoopWriteScope(\n\tdefinition: LoopDefinition,\n\tpaths: readonly string[],\n): LoopWriteScopeValidationResult {\n\tconst diagnostics: LoopValidationDiagnostic[] = [];\n\n\tif (paths.length === 0 && (definition.level === \"L2\" || definition.level === \"L3\")) {\n\t\tdiagnostics.push({\n\t\t\tcode: \"write-scope-empty\",\n\t\t\tmessage: `${definition.level} loops require explicit write paths.`,\n\t\t});\n\t}\n\n\tif (definition.safety.maxWriteScopeCount !== undefined && paths.length > definition.safety.maxWriteScopeCount) {\n\t\tdiagnostics.push({\n\t\t\tcode: \"write-scope-count-exceeded\",\n\t\t\tmessage: `Write scope count ${paths.length} exceeds maxWriteScopeCount=${definition.safety.maxWriteScopeCount}.`,\n\t\t});\n\t}\n\n\tfor (const path of paths) {\n\t\tconst normalizedPath = normalizePath(path);\n\t\tif (!normalizedPath) {\n\t\t\tdiagnostics.push({ code: \"write-scope-empty-path\", message: \"Write scope contains an empty path.\" });\n\t\t\tcontinue;\n\t\t}\n\t\tif (!matchesAnyScope(normalizedPath, definition.safety.allowedWriteScopes)) {\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: \"write-scope-outside-allowed\",\n\t\t\t\tmessage: `Path ${normalizedPath} is outside allowedWriteScopes.`,\n\t\t\t\tpath: normalizedPath,\n\t\t\t});\n\t\t}\n\t\tif (matchesAnyScope(normalizedPath, definition.safety.deniedWriteScopes ?? [])) {\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: \"write-scope-denied\",\n\t\t\t\tmessage: `Path ${normalizedPath} is inside deniedWriteScopes.`,\n\t\t\t\tpath: normalizedPath,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn { passed: diagnostics.length === 0, diagnostics };\n}\n\nfunction safetyGateResult(diagnostics: readonly LoopValidationDiagnostic[]): LoopSafetyGateResult {\n\tif (diagnostics.length === 0) {\n\t\treturn { passed: true, action: \"allow\", diagnostics: [] };\n\t}\n\n\tif (hasDiagnostic(diagnostics, \"loop-kill-switch\")) {\n\t\treturn { passed: false, action: \"block\", outcome: \"killed\", diagnostics };\n\t}\n\tif (hasDiagnostic(diagnostics, \"max-attempts-exceeded\")) {\n\t\treturn { passed: false, action: \"escalate\", outcome: \"escalated\", diagnostics };\n\t}\n\tif (hasDiagnostic(diagnostics, \"human-gate-required\")) {\n\t\treturn { passed: false, action: \"human-gate\", outcome: \"escalated\", diagnostics };\n\t}\n\treturn { passed: false, action: \"block\", outcome: \"verifier-failed\", diagnostics };\n}\n\nfunction hasDiagnostic(diagnostics: readonly LoopValidationDiagnostic[], code: string): boolean {\n\treturn diagnostics.some((diagnostic) => diagnostic.code === code);\n}\n\nfunction requiresIndependentVerifier(definition: LoopDefinition): boolean {\n\treturn definition.level === \"L2\" || definition.level === \"L3\" || definition.safety.requireIndependentVerifier;\n}\n\nfunction validateIndependentVerifier(verifier: LoopVerifierEvidence | undefined): LoopValidationDiagnostic[] {\n\tif (!verifier) {\n\t\treturn [{ code: \"independent-verifier-required\", message: \"L2/L3 actions require an independent verifier.\" }];\n\t}\n\n\tconst diagnostics: LoopValidationDiagnostic[] = [];\n\tconst sameActor = Boolean(\n\t\tverifier.verifierId && verifier.implementerId && verifier.verifierId.trim() === verifier.implementerId.trim(),\n\t);\n\tif (!verifier.independent || sameActor) {\n\t\tdiagnostics.push({ code: \"independent-verifier-required\", message: \"Verifier must be independent.\" });\n\t}\n\tif (verifier.status && verifier.status !== \"pass\") {\n\t\tdiagnostics.push({ code: \"verifier-failed\", message: `Verifier status is ${verifier.status}.` });\n\t}\n\tif (!hasEvidenceRefs(verifier.evidenceRefs)) {\n\t\tdiagnostics.push({ code: \"verifier-evidence-missing\", message: \"Verifier evidenceRefs are required.\" });\n\t}\n\treturn diagnostics;\n}\n\nfunction requiresWorktreeIsolation(definition: LoopDefinition): boolean {\n\treturn definition.worktree?.mode === \"per-run\" || definition.worktree?.mode === \"per-item\";\n}\n\nfunction validateWorktreeEvidence(\n\tdefinition: LoopDefinition,\n\tworktree: LoopWorktreeEvidence | undefined,\n): LoopValidationDiagnostic[] {\n\tif (!worktree) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tcode: \"worktree-isolation-required\",\n\t\t\t\tmessage: \"Isolated loop actions require worktree evidence.\",\n\t\t\t},\n\t\t];\n\t}\n\n\tconst diagnostics: LoopValidationDiagnostic[] = [];\n\tif (worktree.isolated !== true) {\n\t\tdiagnostics.push({\n\t\t\tcode: \"worktree-isolation-required\",\n\t\t\tmessage: \"Loop worktree evidence must confirm isolation.\",\n\t\t});\n\t}\n\tif (!worktree.worktreeId?.trim()) {\n\t\tdiagnostics.push({\n\t\t\tcode: \"worktree-id-required\",\n\t\t\tmessage: \"Loop worktree evidence must include a worktreeId.\",\n\t\t});\n\t}\n\tif (definition.worktree?.requireCleanCheckout === true && worktree.cleanCheckout !== true) {\n\t\tdiagnostics.push({\n\t\t\tcode: \"worktree-clean-checkout-required\",\n\t\t\tmessage: \"Loop worktree must start from a clean checkout.\",\n\t\t});\n\t}\n\tconst branchPrefix = definition.worktree?.branchPrefix;\n\tif (\n\t\tbranchPrefix &&\n\t\tworktree.branch &&\n\t\t!pathHasScopePrefix(normalizePath(worktree.branch), normalizePath(branchPrefix))\n\t) {\n\t\tdiagnostics.push({\n\t\t\tcode: \"worktree-branch-prefix-mismatch\",\n\t\t\tmessage: `Loop worktree branch must use prefix ${branchPrefix}.`,\n\t\t\tpath: worktree.branch,\n\t\t});\n\t}\n\treturn diagnostics;\n}\n\nfunction validateDurableStateEvidence(durableState: LoopDurableStateEvidence | undefined): LoopValidationDiagnostic[] {\n\tconst diagnostics: LoopValidationDiagnostic[] = [];\n\tif (!durableState?.stateRevision?.trim()) {\n\t\tdiagnostics.push({\n\t\t\tcode: \"state-revision-missing\",\n\t\t\tmessage: \"Replayable loop actions require a stateRevision.\",\n\t\t});\n\t}\n\tif (!durableState?.runLogRef?.trim()) {\n\t\tdiagnostics.push({\n\t\t\tcode: \"run-log-ref-missing\",\n\t\t\tmessage: \"Replayable loop actions require a runLogRef.\",\n\t\t});\n\t}\n\tif (!durableState?.budgetReservationId?.trim()) {\n\t\tdiagnostics.push({\n\t\t\tcode: \"budget-reservation-missing\",\n\t\t\tmessage: \"Replayable loop actions require a budgetReservationId.\",\n\t\t});\n\t}\n\treturn diagnostics;\n}\n\nfunction requiresHumanApproval(definition: LoopDefinition, item: LoopWorkItem): boolean {\n\tconst gatedRisks = definition.humanGates?.requiredForRisks;\n\tif (gatedRisks !== undefined) {\n\t\treturn gatedRisks.includes(item.risk);\n\t}\n\treturn definition.safety.requireHumanGateForHighRisk && item.risk === \"high\";\n}\n\nfunction validateRequestedWriteScopeDoesNotOverlapDenied(\n\tdefinition: LoopDefinition,\n\trequestedScopes: readonly string[],\n): LoopValidationDiagnostic[] {\n\tconst deniedScopes = definition.safety.deniedWriteScopes ?? [];\n\tconst diagnostics: LoopValidationDiagnostic[] = [];\n\tfor (const requestedScope of requestedScopes) {\n\t\tconst normalizedRequested = normalizePath(requestedScope);\n\t\tif (!normalizedRequested) {\n\t\t\tcontinue;\n\t\t}\n\t\tfor (const deniedScope of deniedScopes) {\n\t\t\tconst normalizedDenied = normalizePath(deniedScope);\n\t\t\tif (normalizedDenied && scopesOverlap(normalizedRequested, normalizedDenied)) {\n\t\t\t\tdiagnostics.push({\n\t\t\t\t\tcode: \"write-scope-denied-overlap\",\n\t\t\t\t\tmessage: `Requested writeScope ${normalizedRequested} overlaps deniedWriteScope ${normalizedDenied}.`,\n\t\t\t\t\tpath: normalizedRequested,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\treturn diagnostics;\n}\n\nfunction validateChangedFilesWithinRequestedScope(\n\twriteScope: readonly string[],\n\tchangedFiles: readonly string[],\n): LoopValidationDiagnostic[] {\n\tconst diagnostics: LoopValidationDiagnostic[] = [];\n\tfor (const changedFile of changedFiles) {\n\t\tconst normalizedFile = normalizePath(changedFile);\n\t\tif (!normalizedFile) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (!matchesAnyScope(normalizedFile, writeScope)) {\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: \"changed-file-outside-write-scope\",\n\t\t\t\tmessage: `Changed file ${normalizedFile} is outside the requested writeScope.`,\n\t\t\t\tpath: normalizedFile,\n\t\t\t});\n\t\t}\n\t}\n\treturn diagnostics;\n}\n\nfunction hasEvidenceRefs(refs: readonly string[] | undefined): boolean {\n\treturn Boolean(refs?.some((ref) => ref.trim().length > 0));\n}\n\nfunction matchesWatchedScope(definition: LoopDefinition, item: LoopWorkItem): boolean {\n\tconst haystack = normalizePath([item.actingOn, item.sourceRef, item.title].join(\" \"));\n\tconst watchedPaths = definition.watchedScope.paths ?? [];\n\tif (watchedPaths.some((scope) => pathHasScopePrefix(normalizePath(item.actingOn), normalizePath(scope)))) {\n\t\treturn true;\n\t}\n\tconst watchedTickets = definition.watchedScope.tickets ?? [];\n\tif (watchedTickets.some((ticket) => haystack.includes(normalizePath(ticket)))) {\n\t\treturn true;\n\t}\n\tconst watchedBranches = definition.watchedScope.branches ?? [];\n\tif (watchedBranches.some((branch) => haystack.includes(normalizePath(branch)))) {\n\t\treturn true;\n\t}\n\treturn definition.watchedScope.repos.some((repo) => haystack.includes(normalizePath(repo)));\n}\n\nfunction tokenize(text: string): Set<string> {\n\tconst matches = text.toLowerCase().match(/[a-z0-9][a-z0-9_-]*/g) ?? [];\n\treturn new Set(matches.filter((token) => token.length > 1 && !TOKEN_STOP_WORDS.has(token)));\n}\n\nfunction overlapRatio(source: Set<string>, target: Set<string>): number {\n\tif (target.size === 0) {\n\t\treturn 0;\n\t}\n\tlet overlap = 0;\n\tfor (const token of target) {\n\t\tif (source.has(token)) {\n\t\t\toverlap++;\n\t\t}\n\t}\n\treturn overlap / target.size;\n}\n\nfunction clamp01(value: number): number {\n\tif (value < 0) {\n\t\treturn 0;\n\t}\n\tif (value > 1) {\n\t\treturn 1;\n\t}\n\treturn value;\n}\n\nfunction matchesAnyScope(path: string, scopes: readonly string[]): boolean {\n\treturn scopes.some((scope) => scopeMatchesPath(path, scope));\n}\n\nfunction scopesOverlap(first: string, second: string): boolean {\n\treturn scopeMatchesPath(first, second) || scopeMatchesPath(second, first);\n}\n\nfunction scopeMatchesPath(path: string, scope: string): boolean {\n\tconst normalizedPath = normalizePath(path);\n\tconst normalizedScope = normalizePath(scope);\n\tif (!normalizedPath || !normalizedScope) {\n\t\treturn false;\n\t}\n\tif (normalizedScope.includes(\"*\")) {\n\t\treturn globToRegExp(normalizedScope).test(normalizedPath);\n\t}\n\treturn pathHasScopePrefix(normalizedPath, normalizedScope);\n}\n\nfunction pathHasScopePrefix(path: string, scope: string): boolean {\n\treturn path === scope || path.startsWith(`${scope}/`);\n}\n\nfunction normalizePath(path: string): string {\n\treturn path.trim().replace(/\\\\/g, \"/\").replace(/\\/+/g, \"/\").replace(/^\\.\\//, \"\").replace(/\\/$/, \"\");\n}\n\nfunction globToRegExp(glob: string): RegExp {\n\tlet pattern = \"^\";\n\tfor (let index = 0; index < glob.length; index++) {\n\t\tconst char = glob[index];\n\t\tconst nextChar = glob[index + 1];\n\t\tif (char === \"*\" && nextChar === \"*\") {\n\t\t\tpattern += \".*\";\n\t\t\tindex++;\n\t\t} else if (char === \"*\") {\n\t\t\tpattern += \"[^/]*\";\n\t\t} else {\n\t\t\tpattern += escapeRegExp(char);\n\t\t}\n\t}\n\treturn new RegExp(`${pattern}$`);\n}\n\nfunction escapeRegExp(char: string): string {\n\treturn char.replace(/[|\\\\{}()[\\]^$+?.]/g, \"\\\\$&\");\n}\n"]}
1
+ {"version":3,"file":"loop-gates.js","sourceRoot":"","sources":["../../src/core/loop-gates.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tLoopDefinition,\n\tLoopRunOutcome,\n\tLoopState,\n\tLoopValidationDiagnostic,\n\tLoopWorkItem,\n} from \"./loop-types.ts\";\n\nexport type LoopGateAction = \"allow\" | \"block\" | \"human-gate\" | \"escalate\";\n\nexport type LoopVerifierStatus = \"pass\" | \"fail\" | \"blocked\";\n\nexport interface LoopVerifierEvidence {\n\treadonly independent: boolean;\n\treadonly status?: LoopVerifierStatus;\n\treadonly evidenceRefs?: readonly string[];\n\treadonly verifierId?: string;\n\treadonly implementerId?: string;\n}\n\nexport interface LoopHumanGateEvidence {\n\treadonly approved: boolean;\n\treadonly approvalRef?: string;\n}\n\nexport interface LoopWorktreeEvidence {\n\treadonly isolated: boolean;\n\treadonly worktreeId?: string;\n\treadonly branch?: string;\n\treadonly cleanCheckout?: boolean;\n}\n\nexport interface LoopDurableStateEvidence {\n\treadonly stateRevision?: string;\n\treadonly runLogRef?: string;\n\treadonly budgetReservationId?: string;\n}\n\nexport interface LoopGateEvidence {\n\treadonly writeScope?: readonly string[];\n\treadonly changedFiles?: readonly string[];\n\treadonly evidenceRefs?: readonly string[];\n\treadonly verifier?: LoopVerifierEvidence;\n\treadonly humanGate?: LoopHumanGateEvidence;\n\treadonly worktree?: LoopWorktreeEvidence;\n\treadonly durableState?: LoopDurableStateEvidence;\n}\n\nexport interface LoopSafetyGateResult {\n\treadonly passed: boolean;\n\treadonly action: LoopGateAction;\n\treadonly outcome?: LoopRunOutcome;\n\treadonly diagnostics: readonly LoopValidationDiagnostic[];\n}\n\nexport interface LoopWriteScopeValidationResult {\n\treadonly passed: boolean;\n\treadonly diagnostics: readonly LoopValidationDiagnostic[];\n}\n\nconst TOKEN_STOP_WORDS = new Set([\n\t\"a\",\n\t\"an\",\n\t\"and\",\n\t\"are\",\n\t\"as\",\n\t\"for\",\n\t\"in\",\n\t\"inside\",\n\t\"is\",\n\t\"of\",\n\t\"on\",\n\t\"or\",\n\t\"the\",\n\t\"to\",\n\t\"with\",\n]);\n\nexport function evaluateLoopSafetyGates(\n\tdefinition: LoopDefinition,\n\tstate: LoopState,\n\titem: LoopWorkItem,\n\tevidence: LoopGateEvidence,\n): LoopSafetyGateResult {\n\tconst diagnostics: LoopValidationDiagnostic[] = [];\n\n\tif (state.killSwitch) {\n\t\tdiagnostics.push({ code: \"loop-kill-switch\", message: \"Loop kill switch is active.\" });\n\t}\n\tif (state.status === \"paused\" || state.status === \"retired\") {\n\t\tdiagnostics.push({ code: \"loop-not-active\", message: `Loop status ${state.status} cannot take action.` });\n\t}\n\n\tif (item.attemptCount >= definition.budget.maxAttemptsPerItem) {\n\t\tdiagnostics.push({\n\t\t\tcode: \"max-attempts-exceeded\",\n\t\t\tmessage: `Item ${item.id} reached maxAttemptsPerItem=${definition.budget.maxAttemptsPerItem}.`,\n\t\t});\n\t}\n\n\tif (!evidence.writeScope) {\n\t\tdiagnostics.push({ code: \"write-scope-missing\", message: \"Exact writeScope evidence is required.\" });\n\t} else {\n\t\tdiagnostics.push(...validateLoopWriteScope(definition, evidence.writeScope).diagnostics);\n\t\tdiagnostics.push(...validateRequestedWriteScopeDoesNotOverlapDenied(definition, evidence.writeScope));\n\t}\n\n\tif (evidence.writeScope && evidence.changedFiles) {\n\t\tdiagnostics.push(...validateChangedFilesWithinRequestedScope(evidence.writeScope, evidence.changedFiles));\n\t}\n\n\tif (requiresWorktreeIsolation(definition)) {\n\t\tdiagnostics.push(...validateWorktreeEvidence(definition, evidence.worktree));\n\t}\n\n\tif (definition.durableState?.requireReplayableEvidence === true) {\n\t\tdiagnostics.push(...validateDurableStateEvidence(evidence.durableState));\n\t}\n\n\tif (requiresHumanApproval(definition, item)) {\n\t\tconst approvalRef = evidence.humanGate?.approvalRef?.trim();\n\t\tconst approvalRefSatisfied = definition.humanGates?.approvalRefsRequired === false || Boolean(approvalRef);\n\t\tif (evidence.humanGate?.approved !== true || !approvalRefSatisfied) {\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: \"human-gate-required\",\n\t\t\t\tmessage: \"High-risk work item requires human approval evidence.\",\n\t\t\t});\n\t\t}\n\t}\n\n\tif (!hasEvidenceRefs(evidence.evidenceRefs)) {\n\t\tdiagnostics.push({ code: \"evidence-refs-missing\", message: \"Completion evidenceRefs are required.\" });\n\t}\n\n\tif (requiresIndependentVerifier(definition)) {\n\t\tdiagnostics.push(...validateIndependentVerifier(evidence.verifier));\n\t}\n\n\treturn safetyGateResult(diagnostics);\n}\n\nexport function calculateLoopDriftScore(definition: LoopDefinition, item: LoopWorkItem): number {\n\tconst itemTokens = tokenize([item.title, item.sourceRef, item.actingOn].join(\" \"));\n\tconst objectiveTokens = tokenize(definition.objective);\n\tconst objectiveOverlap = overlapRatio(itemTokens, objectiveTokens);\n\tconst nonGoalOverlap = Math.max(\n\t\t0,\n\t\t...definition.nonGoals.map((nonGoal) => overlapRatio(itemTokens, tokenize(nonGoal))),\n\t);\n\tconst scopeMatched = matchesWatchedScope(definition, item);\n\n\tlet score = 0.45;\n\tscore -= objectiveOverlap * 0.25;\n\tscore += objectiveOverlap === 0 ? 0.2 : 0;\n\tscore += scopeMatched ? -0.2 : 0.2;\n\tscore += nonGoalOverlap * 0.7;\n\n\treturn clamp01(score);\n}\n\nexport function validateLoopWriteScope(\n\tdefinition: LoopDefinition,\n\tpaths: readonly string[],\n): LoopWriteScopeValidationResult {\n\tconst diagnostics: LoopValidationDiagnostic[] = [];\n\n\tif (paths.length === 0 && (definition.level === \"L2\" || definition.level === \"L3\")) {\n\t\tdiagnostics.push({\n\t\t\tcode: \"write-scope-empty\",\n\t\t\tmessage: `${definition.level} loops require explicit write paths.`,\n\t\t});\n\t}\n\n\tif (definition.safety.maxWriteScopeCount !== undefined && paths.length > definition.safety.maxWriteScopeCount) {\n\t\tdiagnostics.push({\n\t\t\tcode: \"write-scope-count-exceeded\",\n\t\t\tmessage: `Write scope count ${paths.length} exceeds maxWriteScopeCount=${definition.safety.maxWriteScopeCount}.`,\n\t\t});\n\t}\n\n\tfor (const path of paths) {\n\t\tconst normalizedPath = normalizePath(path);\n\t\tif (!normalizedPath) {\n\t\t\tdiagnostics.push({ code: \"write-scope-empty-path\", message: \"Write scope contains an empty path.\" });\n\t\t\tcontinue;\n\t\t}\n\t\tif (!matchesAnyScope(normalizedPath, definition.safety.allowedWriteScopes)) {\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: \"write-scope-outside-allowed\",\n\t\t\t\tmessage: `Path ${normalizedPath} is outside allowedWriteScopes.`,\n\t\t\t\tpath: normalizedPath,\n\t\t\t});\n\t\t}\n\t\tif (matchesAnyScope(normalizedPath, definition.safety.deniedWriteScopes ?? [])) {\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: \"write-scope-denied\",\n\t\t\t\tmessage: `Path ${normalizedPath} is inside deniedWriteScopes.`,\n\t\t\t\tpath: normalizedPath,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn { passed: diagnostics.length === 0, diagnostics };\n}\n\nfunction safetyGateResult(diagnostics: readonly LoopValidationDiagnostic[]): LoopSafetyGateResult {\n\tif (diagnostics.length === 0) {\n\t\treturn { passed: true, action: \"allow\", diagnostics: [] };\n\t}\n\n\tif (hasDiagnostic(diagnostics, \"loop-kill-switch\")) {\n\t\treturn { passed: false, action: \"block\", outcome: \"killed\", diagnostics };\n\t}\n\tif (hasDiagnostic(diagnostics, \"max-attempts-exceeded\")) {\n\t\treturn { passed: false, action: \"escalate\", outcome: \"escalated\", diagnostics };\n\t}\n\tif (hasDiagnostic(diagnostics, \"human-gate-required\")) {\n\t\treturn { passed: false, action: \"human-gate\", outcome: \"escalated\", diagnostics };\n\t}\n\treturn { passed: false, action: \"block\", outcome: \"verifier-failed\", diagnostics };\n}\n\nfunction hasDiagnostic(diagnostics: readonly LoopValidationDiagnostic[], code: string): boolean {\n\treturn diagnostics.some((diagnostic) => diagnostic.code === code);\n}\n\nfunction requiresIndependentVerifier(definition: LoopDefinition): boolean {\n\treturn definition.level === \"L2\" || definition.level === \"L3\" || definition.safety.requireIndependentVerifier;\n}\n\nfunction validateIndependentVerifier(verifier: LoopVerifierEvidence | undefined): LoopValidationDiagnostic[] {\n\tif (!verifier) {\n\t\treturn [{ code: \"independent-verifier-required\", message: \"L2/L3 actions require an independent verifier.\" }];\n\t}\n\n\tconst diagnostics: LoopValidationDiagnostic[] = [];\n\tconst sameActor = Boolean(\n\t\tverifier.verifierId && verifier.implementerId && verifier.verifierId.trim() === verifier.implementerId.trim(),\n\t);\n\tif (!verifier.independent || sameActor) {\n\t\tdiagnostics.push({ code: \"independent-verifier-required\", message: \"Verifier must be independent.\" });\n\t}\n\tif (verifier.status && verifier.status !== \"pass\") {\n\t\tdiagnostics.push({ code: \"verifier-failed\", message: `Verifier status is ${verifier.status}.` });\n\t}\n\tif (!hasEvidenceRefs(verifier.evidenceRefs)) {\n\t\tdiagnostics.push({ code: \"verifier-evidence-missing\", message: \"Verifier evidenceRefs are required.\" });\n\t}\n\treturn diagnostics;\n}\n\nfunction requiresWorktreeIsolation(definition: LoopDefinition): boolean {\n\treturn definition.worktree?.mode === \"per-run\" || definition.worktree?.mode === \"per-item\";\n}\n\nfunction validateWorktreeEvidence(\n\tdefinition: LoopDefinition,\n\tworktree: LoopWorktreeEvidence | undefined,\n): LoopValidationDiagnostic[] {\n\tif (!worktree) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tcode: \"worktree-isolation-required\",\n\t\t\t\tmessage: \"Isolated loop actions require worktree evidence.\",\n\t\t\t},\n\t\t];\n\t}\n\n\tconst diagnostics: LoopValidationDiagnostic[] = [];\n\tif (worktree.isolated !== true) {\n\t\tdiagnostics.push({\n\t\t\tcode: \"worktree-isolation-required\",\n\t\t\tmessage: \"Loop worktree evidence must confirm isolation.\",\n\t\t});\n\t}\n\tif (!worktree.worktreeId?.trim()) {\n\t\tdiagnostics.push({\n\t\t\tcode: \"worktree-id-required\",\n\t\t\tmessage: \"Loop worktree evidence must include a worktreeId.\",\n\t\t});\n\t}\n\tif (definition.worktree?.requireCleanCheckout === true && worktree.cleanCheckout !== true) {\n\t\tdiagnostics.push({\n\t\t\tcode: \"worktree-clean-checkout-required\",\n\t\t\tmessage: \"Loop worktree must start from a clean checkout.\",\n\t\t});\n\t}\n\tconst branchPrefix = definition.worktree?.branchPrefix;\n\tif (\n\t\tbranchPrefix &&\n\t\tworktree.branch &&\n\t\t!pathHasScopePrefix(normalizePath(worktree.branch), normalizePath(branchPrefix))\n\t) {\n\t\tdiagnostics.push({\n\t\t\tcode: \"worktree-branch-prefix-mismatch\",\n\t\t\tmessage: `Loop worktree branch must use prefix ${branchPrefix}.`,\n\t\t\tpath: worktree.branch,\n\t\t});\n\t}\n\treturn diagnostics;\n}\n\nfunction validateDurableStateEvidence(durableState: LoopDurableStateEvidence | undefined): LoopValidationDiagnostic[] {\n\tconst diagnostics: LoopValidationDiagnostic[] = [];\n\tif (!durableState?.stateRevision?.trim()) {\n\t\tdiagnostics.push({\n\t\t\tcode: \"state-revision-missing\",\n\t\t\tmessage: \"Replayable loop actions require a stateRevision.\",\n\t\t});\n\t}\n\tif (!durableState?.runLogRef?.trim()) {\n\t\tdiagnostics.push({\n\t\t\tcode: \"run-log-ref-missing\",\n\t\t\tmessage: \"Replayable loop actions require a runLogRef.\",\n\t\t});\n\t}\n\tif (!durableState?.budgetReservationId?.trim()) {\n\t\tdiagnostics.push({\n\t\t\tcode: \"budget-reservation-missing\",\n\t\t\tmessage: \"Replayable loop actions require a budgetReservationId.\",\n\t\t});\n\t}\n\treturn diagnostics;\n}\n\nfunction requiresHumanApproval(definition: LoopDefinition, item: LoopWorkItem): boolean {\n\tconst gatedRisks = definition.humanGates?.requiredForRisks;\n\tif (gatedRisks !== undefined) {\n\t\treturn gatedRisks.includes(item.risk);\n\t}\n\treturn definition.safety.requireHumanGateForHighRisk && item.risk === \"high\";\n}\n\nfunction validateRequestedWriteScopeDoesNotOverlapDenied(\n\tdefinition: LoopDefinition,\n\trequestedScopes: readonly string[],\n): LoopValidationDiagnostic[] {\n\tconst deniedScopes = definition.safety.deniedWriteScopes ?? [];\n\tconst diagnostics: LoopValidationDiagnostic[] = [];\n\tfor (const requestedScope of requestedScopes) {\n\t\tconst normalizedRequested = normalizePath(requestedScope);\n\t\tif (!normalizedRequested) {\n\t\t\tcontinue;\n\t\t}\n\t\tfor (const deniedScope of deniedScopes) {\n\t\t\tconst normalizedDenied = normalizePath(deniedScope);\n\t\t\tif (normalizedDenied && scopesOverlap(normalizedRequested, normalizedDenied)) {\n\t\t\t\tdiagnostics.push({\n\t\t\t\t\tcode: \"write-scope-denied-overlap\",\n\t\t\t\t\tmessage: `Requested writeScope ${normalizedRequested} overlaps deniedWriteScope ${normalizedDenied}.`,\n\t\t\t\t\tpath: normalizedRequested,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\treturn diagnostics;\n}\n\nfunction validateChangedFilesWithinRequestedScope(\n\twriteScope: readonly string[],\n\tchangedFiles: readonly string[],\n): LoopValidationDiagnostic[] {\n\tconst diagnostics: LoopValidationDiagnostic[] = [];\n\tfor (const changedFile of changedFiles) {\n\t\tconst normalizedFile = normalizePath(changedFile);\n\t\tif (!normalizedFile) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (!matchesAnyScope(normalizedFile, writeScope)) {\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: \"changed-file-outside-write-scope\",\n\t\t\t\tmessage: `Changed file ${normalizedFile} is outside the requested writeScope.`,\n\t\t\t\tpath: normalizedFile,\n\t\t\t});\n\t\t}\n\t}\n\treturn diagnostics;\n}\n\nfunction hasEvidenceRefs(refs: readonly string[] | undefined): boolean {\n\treturn Boolean(refs?.some((ref) => ref.trim().length > 0));\n}\n\nfunction matchesWatchedScope(definition: LoopDefinition, item: LoopWorkItem): boolean {\n\tconst haystack = normalizePath([item.actingOn, item.sourceRef, item.title].join(\" \"));\n\tconst watchedPaths = definition.watchedScope.paths ?? [];\n\tif (watchedPaths.some((scope) => pathHasScopePrefix(normalizePath(item.actingOn), normalizePath(scope)))) {\n\t\treturn true;\n\t}\n\tconst watchedTickets = definition.watchedScope.tickets ?? [];\n\tif (watchedTickets.some((ticket) => haystack.includes(normalizePath(ticket)))) {\n\t\treturn true;\n\t}\n\tconst watchedBranches = definition.watchedScope.branches ?? [];\n\tif (watchedBranches.some((branch) => haystack.includes(normalizePath(branch)))) {\n\t\treturn true;\n\t}\n\treturn definition.watchedScope.repos.some((repo) => haystack.includes(normalizePath(repo)));\n}\n\nfunction tokenize(text: string): Set<string> {\n\tconst matches = text.toLowerCase().match(/[a-z0-9][a-z0-9_-]*/g) ?? [];\n\treturn new Set(matches.filter((token) => token.length > 1 && !TOKEN_STOP_WORDS.has(token)));\n}\n\nfunction overlapRatio(source: Set<string>, target: Set<string>): number {\n\tif (target.size === 0) {\n\t\treturn 0;\n\t}\n\tlet overlap = 0;\n\tfor (const token of target) {\n\t\tif (source.has(token)) {\n\t\t\toverlap++;\n\t\t}\n\t}\n\treturn overlap / target.size;\n}\n\nfunction clamp01(value: number): number {\n\tif (value < 0) {\n\t\treturn 0;\n\t}\n\tif (value > 1) {\n\t\treturn 1;\n\t}\n\treturn value;\n}\n\nfunction matchesAnyScope(path: string, scopes: readonly string[]): boolean {\n\treturn scopes.some((scope) => scopeMatchesPath(path, scope));\n}\n\nfunction scopesOverlap(first: string, second: string): boolean {\n\treturn scopeMatchesPath(first, second) || scopeMatchesPath(second, first);\n}\n\nfunction scopeMatchesPath(path: string, scope: string): boolean {\n\tconst normalizedPath = normalizePath(path);\n\tconst normalizedScope = normalizePath(scope);\n\tif (!normalizedPath || !normalizedScope) {\n\t\treturn false;\n\t}\n\tif (normalizedScope.includes(\"*\")) {\n\t\treturn globToRegExp(normalizedScope).test(normalizedPath);\n\t}\n\treturn pathHasScopePrefix(normalizedPath, normalizedScope);\n}\n\nfunction pathHasScopePrefix(path: string, scope: string): boolean {\n\treturn path === scope || path.startsWith(`${scope}/`);\n}\n\nfunction normalizePath(path: string): string {\n\tconst cleaned = path.trim().replace(/\\\\/g, \"/\").replace(/\\/+/g, \"/\").replace(/^\\.\\//, \"\").replace(/\\/$/, \"\");\n\tif (!/(^|\\/)\\.\\.?(\\/|$)/.test(cleaned)) {\n\t\treturn cleaned;\n\t}\n\t// Collapse \".\" and \"..\" so \"src/../package.json\" cannot pass a \"src\" scope prefix check.\n\tconst isAbsolute = cleaned.startsWith(\"/\");\n\tconst collapsed: string[] = [];\n\tlet escapes = 0;\n\tfor (const segment of cleaned.split(\"/\")) {\n\t\tif (segment.length === 0 || segment === \".\") continue;\n\t\tif (segment === \"..\") {\n\t\t\tif (collapsed.length > 0) {\n\t\t\t\tcollapsed.pop();\n\t\t\t} else if (!isAbsolute) {\n\t\t\t\t// Keep root-escaping \"..\" so escaped paths never match any scope prefix.\n\t\t\t\tescapes++;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tcollapsed.push(segment);\n\t}\n\tconst joined = (isAbsolute ? \"/\" : \"../\".repeat(escapes)) + collapsed.join(\"/\");\n\treturn joined === \"/\" ? joined : joined.replace(/\\/$/, \"\");\n}\n\nfunction globToRegExp(glob: string): RegExp {\n\tlet pattern = \"^\";\n\tfor (let index = 0; index < glob.length; index++) {\n\t\tconst char = glob[index];\n\t\tconst nextChar = glob[index + 1];\n\t\tif (char === \"*\" && nextChar === \"*\") {\n\t\t\tpattern += \".*\";\n\t\t\tindex++;\n\t\t} else if (char === \"*\") {\n\t\t\tpattern += \"[^/]*\";\n\t\t} else {\n\t\t\tpattern += escapeRegExp(char);\n\t\t}\n\t}\n\treturn new RegExp(`${pattern}$`);\n}\n\nfunction escapeRegExp(char: string): string {\n\treturn char.replace(/[|\\\\{}()[\\]^$+?.]/g, \"\\\\$&\");\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"model-resolver.d.ts","sourceRoot":"","sources":["../../src/core/model-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Model resolution, scoping, and initial selection\n */\n\nimport chalk from \"chalk\";\nimport { minimatch } from \"minimatch\";\nimport type { ThinkingLevel } from \"omk-agent-core\";\nimport { type Api, type KnownProvider, type Model, modelsAreEqual } from \"omk-ai\";\nimport { isValidThinkingLevel } from \"../cli/args.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport type { ModelRegistry } from \"./model-registry.ts\";\n\n/** Default model IDs for each known provider */\nexport const defaultModelPerProvider: Record<KnownProvider, string> = {\n\t\"amazon-bedrock\": \"us.anthropic.claude-opus-4-6-v1\",\n\t\"ant-ling\": \"Ring-2.6-1T\",\n\tanthropic: \"claude-opus-4-8\",\n\topenai: \"gpt-5.4\",\n\t\"azure-openai-responses\": \"gpt-5.4\",\n\t\"openai-codex\": \"gpt-5.5\",\n\tnvidia: \"nvidia/nemotron-3-super-120b-a12b\",\n\tdeepseek: \"deepseek-v4-pro\",\n\tgoogle: \"gemini-3.1-pro-preview\",\n\t\"google-vertex\": \"gemini-3.1-pro-preview\",\n\t\"github-copilot\": \"gpt-5.4\",\n\topenrouter: \"moonshotai/kimi-k2.6\",\n\t\"vercel-ai-gateway\": \"zai/glm-5.1\",\n\txai: \"grok-4.20-0309-reasoning\",\n\tgroq: \"openai/gpt-oss-120b\",\n\tcerebras: \"zai-glm-4.7\",\n\tzai: \"glm-5.1\",\n\t\"zai-coding-cn\": \"glm-5.1\",\n\tmistral: \"devstral-medium-latest\",\n\tminimax: \"MiniMax-M2.7\",\n\t\"minimax-cn\": \"MiniMax-M2.7\",\n\tmoonshotai: \"kimi-k2.6\",\n\t\"moonshotai-cn\": \"kimi-k2.6\",\n\thuggingface: \"moonshotai/Kimi-K2.6\",\n\tfireworks: \"accounts/fireworks/models/kimi-k2p6\",\n\ttogether: \"moonshotai/Kimi-K2.6\",\n\topencode: \"kimi-k2.6\",\n\t\"opencode-go\": \"kimi-k2.6\",\n\t\"kimi-coding\": \"kimi-for-coding\",\n\t\"cloudflare-workers-ai\": \"@cf/moonshotai/kimi-k2.6\",\n\t\"cloudflare-ai-gateway\": \"workers-ai/@cf/moonshotai/kimi-k2.6\",\n\txiaomi: \"mimo-v2.5-pro\",\n\t\"xiaomi-token-plan-cn\": \"mimo-v2.5-pro\",\n\t\"xiaomi-token-plan-ams\": \"mimo-v2.5-pro\",\n\t\"xiaomi-token-plan-sgp\": \"mimo-v2.5-pro\",\n\tzyloo: \"claude-opus-4-7\",\n};\n\nexport interface ScopedModel {\n\tmodel: Model<Api>;\n\t/** Thinking level if explicitly specified in pattern (e.g., \"model:high\"), undefined otherwise */\n\tthinkingLevel?: ThinkingLevel;\n}\n\n/**\n * Helper to check if a model ID looks like an alias (no date suffix)\n * Dates are typically in format: -20241022 or -20250929\n */\nfunction isAlias(id: string): boolean {\n\t// Check if ID ends with -latest\n\tif (id.endsWith(\"-latest\")) return true;\n\n\t// Check if ID ends with a date pattern (-YYYYMMDD)\n\tconst datePattern = /-\\d{8}$/;\n\treturn !datePattern.test(id);\n}\n\n/**\n * Find an exact model reference match.\n * Supports either a bare model id or a canonical provider/modelId reference.\n * When matching by bare id, ambiguous matches across providers are rejected.\n */\nexport function findExactModelReferenceMatch(\n\tmodelReference: string,\n\tavailableModels: Model<Api>[],\n): Model<Api> | undefined {\n\tconst trimmedReference = modelReference.trim();\n\tif (!trimmedReference) {\n\t\treturn undefined;\n\t}\n\n\tconst normalizedReference = trimmedReference.toLowerCase();\n\n\tconst canonicalMatches = availableModels.filter(\n\t\t(model) => `${model.provider}/${model.id}`.toLowerCase() === normalizedReference,\n\t);\n\tif (canonicalMatches.length === 1) {\n\t\treturn canonicalMatches[0];\n\t}\n\tif (canonicalMatches.length > 1) {\n\t\treturn undefined;\n\t}\n\n\tconst slashIndex = trimmedReference.indexOf(\"/\");\n\tif (slashIndex !== -1) {\n\t\tconst provider = trimmedReference.substring(0, slashIndex).trim();\n\t\tconst modelId = trimmedReference.substring(slashIndex + 1).trim();\n\t\tif (provider && modelId) {\n\t\t\tconst providerMatches = availableModels.filter(\n\t\t\t\t(model) =>\n\t\t\t\t\tmodel.provider.toLowerCase() === provider.toLowerCase() &&\n\t\t\t\t\tmodel.id.toLowerCase() === modelId.toLowerCase(),\n\t\t\t);\n\t\t\tif (providerMatches.length === 1) {\n\t\t\t\treturn providerMatches[0];\n\t\t\t}\n\t\t\tif (providerMatches.length > 1) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst idMatches = availableModels.filter((model) => model.id.toLowerCase() === normalizedReference);\n\treturn idMatches.length === 1 ? idMatches[0] : undefined;\n}\n\n/**\n * Try to match a pattern to a model from the available models list.\n * Returns the matched model or undefined if no match found.\n */\nfunction tryMatchModel(modelPattern: string, availableModels: Model<Api>[]): Model<Api> | undefined {\n\tconst exactMatch = findExactModelReferenceMatch(modelPattern, availableModels);\n\tif (exactMatch) {\n\t\treturn exactMatch;\n\t}\n\n\t// No exact match - fall back to partial matching\n\tconst matches = availableModels.filter(\n\t\t(m) =>\n\t\t\tm.id.toLowerCase().includes(modelPattern.toLowerCase()) ||\n\t\t\tm.name?.toLowerCase().includes(modelPattern.toLowerCase()),\n\t);\n\n\tif (matches.length === 0) {\n\t\treturn undefined;\n\t}\n\n\t// Separate into aliases and dated versions\n\tconst aliases = matches.filter((m) => isAlias(m.id));\n\tconst datedVersions = matches.filter((m) => !isAlias(m.id));\n\n\tif (aliases.length > 0) {\n\t\t// Prefer alias - if multiple aliases, pick the one that sorts highest\n\t\taliases.sort((a, b) => b.id.localeCompare(a.id));\n\t\treturn aliases[0];\n\t} else {\n\t\t// No alias found, pick latest dated version\n\t\tdatedVersions.sort((a, b) => b.id.localeCompare(a.id));\n\t\treturn datedVersions[0];\n\t}\n}\n\nexport interface ParsedModelResult {\n\tmodel: Model<Api> | undefined;\n\t/** Thinking level if explicitly specified in pattern, undefined otherwise */\n\tthinkingLevel?: ThinkingLevel;\n\twarning: string | undefined;\n}\n\nfunction buildFallbackModel(provider: string, modelId: string, availableModels: Model<Api>[]): Model<Api> | undefined {\n\tconst providerModels = availableModels.filter((m) => m.provider === provider);\n\tif (providerModels.length === 0) return undefined;\n\n\tconst defaultId = defaultModelPerProvider[provider as KnownProvider];\n\tconst baseModel = defaultId\n\t\t? (providerModels.find((m) => m.id === defaultId) ?? providerModels[0])\n\t\t: providerModels[0];\n\n\treturn {\n\t\t...baseModel,\n\t\tid: modelId,\n\t\tname: modelId,\n\t};\n}\n\n/**\n * Parse a pattern to extract model and thinking level.\n * Handles models with colons in their IDs (e.g., OpenRouter's :exacto suffix).\n *\n * Algorithm:\n * 1. Try to match full pattern as a model\n * 2. If found, return it with \"off\" thinking level\n * 3. If not found and has colons, split on last colon:\n * - If suffix is valid thinking level, use it and recurse on prefix\n * - If suffix is invalid, warn and recurse on prefix with \"off\"\n *\n * @internal Exported for testing\n */\nexport function parseModelPattern(\n\tpattern: string,\n\tavailableModels: Model<Api>[],\n\toptions?: { allowInvalidThinkingLevelFallback?: boolean },\n): ParsedModelResult {\n\t// Try exact match first\n\tconst exactMatch = tryMatchModel(pattern, availableModels);\n\tif (exactMatch) {\n\t\treturn { model: exactMatch, thinkingLevel: undefined, warning: undefined };\n\t}\n\n\t// No match - try splitting on last colon if present\n\tconst lastColonIndex = pattern.lastIndexOf(\":\");\n\tif (lastColonIndex === -1) {\n\t\t// No colons, pattern simply doesn't match any model\n\t\treturn { model: undefined, thinkingLevel: undefined, warning: undefined };\n\t}\n\n\tconst prefix = pattern.substring(0, lastColonIndex);\n\tconst suffix = pattern.substring(lastColonIndex + 1);\n\n\tif (isValidThinkingLevel(suffix)) {\n\t\t// Valid thinking level - recurse on prefix and use this level\n\t\tconst result = parseModelPattern(prefix, availableModels, options);\n\t\tif (result.model) {\n\t\t\t// Only use this thinking level if no warning from inner recursion\n\t\t\treturn {\n\t\t\t\tmodel: result.model,\n\t\t\t\tthinkingLevel: result.warning ? undefined : suffix,\n\t\t\t\twarning: result.warning,\n\t\t\t};\n\t\t}\n\t\treturn result;\n\t} else {\n\t\t// Invalid suffix\n\t\tconst allowFallback = options?.allowInvalidThinkingLevelFallback ?? true;\n\t\tif (!allowFallback) {\n\t\t\t// In strict mode (CLI --model parsing), treat it as part of the model id and fail.\n\t\t\t// This avoids accidentally resolving to a different model.\n\t\t\treturn { model: undefined, thinkingLevel: undefined, warning: undefined };\n\t\t}\n\n\t\t// Scope mode: recurse on prefix and warn\n\t\tconst result = parseModelPattern(prefix, availableModels, options);\n\t\tif (result.model) {\n\t\t\treturn {\n\t\t\t\tmodel: result.model,\n\t\t\t\tthinkingLevel: undefined,\n\t\t\t\twarning: `Invalid thinking level \"${suffix}\" in pattern \"${pattern}\". Using default instead.`,\n\t\t\t};\n\t\t}\n\t\treturn result;\n\t}\n}\n\n/**\n * Resolve model patterns to actual Model objects with optional thinking levels\n * Format: \"pattern:level\" where :level is optional\n * For each pattern, finds all matching models and picks the best version:\n * 1. Prefer alias (e.g., claude-sonnet-4-5) over dated versions (claude-sonnet-4-5-20250929)\n * 2. If no alias, pick the latest dated version\n *\n * Supports models with colons in their IDs (e.g., OpenRouter's model:exacto).\n * The algorithm tries to match the full pattern first, then progressively\n * strips colon-suffixes to find a match.\n */\nexport async function resolveModelScope(patterns: string[], modelRegistry: ModelRegistry): Promise<ScopedModel[]> {\n\tconst availableModels = await modelRegistry.getAvailable();\n\tconst scopedModels: ScopedModel[] = [];\n\n\tfor (const pattern of patterns) {\n\t\t// Check if pattern contains glob characters\n\t\tif (pattern.includes(\"*\") || pattern.includes(\"?\") || pattern.includes(\"[\")) {\n\t\t\t// Extract optional thinking level suffix (e.g., \"provider/*:high\")\n\t\t\tconst colonIdx = pattern.lastIndexOf(\":\");\n\t\t\tlet globPattern = pattern;\n\t\t\tlet thinkingLevel: ThinkingLevel | undefined;\n\n\t\t\tif (colonIdx !== -1) {\n\t\t\t\tconst suffix = pattern.substring(colonIdx + 1);\n\t\t\t\tif (isValidThinkingLevel(suffix)) {\n\t\t\t\t\tthinkingLevel = suffix;\n\t\t\t\t\tglobPattern = pattern.substring(0, colonIdx);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Match against \"provider/modelId\" format OR just model ID\n\t\t\t// This allows \"*sonnet*\" to match without requiring \"anthropic/*sonnet*\"\n\t\t\tconst matchingModels = availableModels.filter((m) => {\n\t\t\t\tconst fullId = `${m.provider}/${m.id}`;\n\t\t\t\treturn minimatch(fullId, globPattern, { nocase: true }) || minimatch(m.id, globPattern, { nocase: true });\n\t\t\t});\n\n\t\t\tif (matchingModels.length === 0) {\n\t\t\t\tconsole.warn(chalk.yellow(`Warning: No models match pattern \"${pattern}\"`));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tfor (const model of matchingModels) {\n\t\t\t\tif (!scopedModels.find((sm) => modelsAreEqual(sm.model, model))) {\n\t\t\t\t\tscopedModels.push({ model, thinkingLevel });\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst { model, thinkingLevel, warning } = parseModelPattern(pattern, availableModels);\n\n\t\tif (warning) {\n\t\t\tconsole.warn(chalk.yellow(`Warning: ${warning}`));\n\t\t}\n\n\t\tif (!model) {\n\t\t\tconsole.warn(chalk.yellow(`Warning: No models match pattern \"${pattern}\"`));\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Avoid duplicates\n\t\tif (!scopedModels.find((sm) => modelsAreEqual(sm.model, model))) {\n\t\t\tscopedModels.push({ model, thinkingLevel });\n\t\t}\n\t}\n\n\treturn scopedModels;\n}\n\nexport interface ResolveCliModelResult {\n\tmodel: Model<Api> | undefined;\n\tthinkingLevel?: ThinkingLevel;\n\twarning: string | undefined;\n\t/**\n\t * Error message suitable for CLI display.\n\t * When set, model will be undefined.\n\t */\n\terror: string | undefined;\n}\n\n/**\n * Resolve a single model from CLI flags.\n *\n * Supports:\n * - --provider <provider> --model <pattern>\n * - --model <provider>/<pattern>\n * - Fuzzy matching (same rules as model scoping: exact id, then partial id/name)\n *\n * Note: This does not apply the thinking level by itself, but it may *parse* and\n * return a thinking level from \"<pattern>:<thinking>\" so the caller can apply it.\n */\nexport function resolveCliModel(options: {\n\tcliProvider?: string;\n\tcliModel?: string;\n\tmodelRegistry: ModelRegistry;\n}): ResolveCliModelResult {\n\tconst { cliProvider, cliModel, modelRegistry } = options;\n\n\tif (!cliModel) {\n\t\treturn { model: undefined, warning: undefined, error: undefined };\n\t}\n\n\t// Important: use *all* models here, not just models with pre-configured auth.\n\t// This allows \"--api-key\" to be used for first-time setup.\n\tconst availableModels = modelRegistry.getAll();\n\tif (availableModels.length === 0) {\n\t\treturn {\n\t\t\tmodel: undefined,\n\t\t\twarning: undefined,\n\t\t\terror: \"No models available. Check your installation or add models to models.json.\",\n\t\t};\n\t}\n\n\t// Build canonical provider lookup (case-insensitive)\n\tconst providerMap = new Map<string, string>();\n\tfor (const m of availableModels) {\n\t\tproviderMap.set(m.provider.toLowerCase(), m.provider);\n\t}\n\n\tlet provider = cliProvider ? providerMap.get(cliProvider.toLowerCase()) : undefined;\n\tif (cliProvider && !provider) {\n\t\treturn {\n\t\t\tmodel: undefined,\n\t\t\twarning: undefined,\n\t\t\terror: `Unknown provider \"${cliProvider}\". Use --list-models to see available providers/models.`,\n\t\t};\n\t}\n\n\t// If no explicit --provider, try to interpret \"provider/model\" format first.\n\t// When the prefix before the first slash matches a known provider, prefer that\n\t// interpretation over matching models whose IDs literally contain slashes\n\t// (e.g. \"zai/glm-5\" should resolve to provider=zai, model=glm-5, not to a\n\t// vercel-ai-gateway model with id \"zai/glm-5\").\n\tlet pattern = cliModel;\n\tlet inferredProvider = false;\n\n\tif (!provider) {\n\t\tconst slashIndex = cliModel.indexOf(\"/\");\n\t\tif (slashIndex !== -1) {\n\t\t\tconst maybeProvider = cliModel.substring(0, slashIndex);\n\t\t\tconst canonical = providerMap.get(maybeProvider.toLowerCase());\n\t\t\tif (canonical) {\n\t\t\t\tprovider = canonical;\n\t\t\t\tpattern = cliModel.substring(slashIndex + 1);\n\t\t\t\tinferredProvider = true;\n\t\t\t}\n\t\t}\n\t}\n\n\t// If no provider was inferred from the slash, try exact matches without provider inference.\n\t// This handles models whose IDs naturally contain slashes (e.g. OpenRouter-style IDs).\n\tif (!provider) {\n\t\tconst lower = cliModel.toLowerCase();\n\t\tconst exact = availableModels.find(\n\t\t\t(m) => m.id.toLowerCase() === lower || `${m.provider}/${m.id}`.toLowerCase() === lower,\n\t\t);\n\t\tif (exact) {\n\t\t\treturn { model: exact, warning: undefined, thinkingLevel: undefined, error: undefined };\n\t\t}\n\t}\n\n\tif (cliProvider && provider) {\n\t\t// If both were provided, tolerate --model <provider>/<pattern> by stripping the provider prefix\n\t\tconst prefix = `${provider}/`;\n\t\tif (cliModel.toLowerCase().startsWith(prefix.toLowerCase())) {\n\t\t\tpattern = cliModel.substring(prefix.length);\n\t\t}\n\t}\n\n\tconst candidates = provider ? availableModels.filter((m) => m.provider === provider) : availableModels;\n\tconst { model, thinkingLevel, warning } = parseModelPattern(pattern, candidates, {\n\t\tallowInvalidThinkingLevelFallback: false,\n\t});\n\n\tif (model) {\n\t\treturn { model, thinkingLevel, warning, error: undefined };\n\t}\n\n\t// If we inferred a provider from the slash but found no match within that provider,\n\t// fall back to matching the full input as a raw model id across all models.\n\t// This handles OpenRouter-style IDs like \"openai/gpt-4o:extended\" where \"openai\"\n\t// looks like a provider but the full string is actually a model id on openrouter.\n\tif (inferredProvider) {\n\t\tconst lower = cliModel.toLowerCase();\n\t\tconst exact = availableModels.find(\n\t\t\t(m) => m.id.toLowerCase() === lower || `${m.provider}/${m.id}`.toLowerCase() === lower,\n\t\t);\n\t\tif (exact) {\n\t\t\treturn { model: exact, warning: undefined, thinkingLevel: undefined, error: undefined };\n\t\t}\n\t\t// Also try parseModelPattern on the full input against all models\n\t\tconst fallback = parseModelPattern(cliModel, availableModels, {\n\t\t\tallowInvalidThinkingLevelFallback: false,\n\t\t});\n\t\tif (fallback.model) {\n\t\t\treturn {\n\t\t\t\tmodel: fallback.model,\n\t\t\t\tthinkingLevel: fallback.thinkingLevel,\n\t\t\t\twarning: fallback.warning,\n\t\t\t\terror: undefined,\n\t\t\t};\n\t\t}\n\t}\n\n\tif (provider) {\n\t\tconst fallbackModel = buildFallbackModel(provider, pattern, availableModels);\n\t\tif (fallbackModel) {\n\t\t\tconst fallbackWarning = warning\n\t\t\t\t? `${warning} Model \"${pattern}\" not found for provider \"${provider}\". Using custom model id.`\n\t\t\t\t: `Model \"${pattern}\" not found for provider \"${provider}\". Using custom model id.`;\n\t\t\treturn { model: fallbackModel, thinkingLevel: undefined, warning: fallbackWarning, error: undefined };\n\t\t}\n\t}\n\n\tconst display = provider ? `${provider}/${pattern}` : cliModel;\n\treturn {\n\t\tmodel: undefined,\n\t\tthinkingLevel: undefined,\n\t\twarning,\n\t\terror: `Model \"${display}\" not found. Use --list-models to see available models.`,\n\t};\n}\n\nexport interface InitialModelResult {\n\tmodel: Model<Api> | undefined;\n\tthinkingLevel: ThinkingLevel;\n\tfallbackMessage: string | undefined;\n}\n\n/**\n * Find the initial model to use based on priority:\n * 1. CLI args (provider + model)\n * 2. First model from scoped models (if not continuing/resuming)\n * 3. Restored from session (if continuing/resuming)\n * 4. Saved default from settings\n * 5. First available model with valid API key\n */\nexport async function findInitialModel(options: {\n\tcliProvider?: string;\n\tcliModel?: string;\n\tscopedModels: ScopedModel[];\n\tisContinuing: boolean;\n\tdefaultProvider?: string;\n\tdefaultModelId?: string;\n\tdefaultThinkingLevel?: ThinkingLevel;\n\tmodelRegistry: ModelRegistry;\n}): Promise<InitialModelResult> {\n\tconst {\n\t\tcliProvider,\n\t\tcliModel,\n\t\tscopedModels,\n\t\tisContinuing,\n\t\tdefaultProvider,\n\t\tdefaultModelId,\n\t\tdefaultThinkingLevel,\n\t\tmodelRegistry,\n\t} = options;\n\n\tlet model: Model<Api> | undefined;\n\tlet thinkingLevel: ThinkingLevel = DEFAULT_THINKING_LEVEL;\n\n\t// 1. CLI args take priority\n\tif (cliProvider && cliModel) {\n\t\tconst resolved = resolveCliModel({\n\t\t\tcliProvider,\n\t\t\tcliModel,\n\t\t\tmodelRegistry,\n\t\t});\n\t\tif (resolved.error) {\n\t\t\tconsole.error(chalk.red(resolved.error));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tif (resolved.model) {\n\t\t\treturn { model: resolved.model, thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n\t\t}\n\t}\n\n\t// 2. Use first model from scoped models (skip if continuing/resuming)\n\tif (scopedModels.length > 0 && !isContinuing) {\n\t\treturn {\n\t\t\tmodel: scopedModels[0].model,\n\t\t\tthinkingLevel: scopedModels[0].thinkingLevel ?? defaultThinkingLevel ?? DEFAULT_THINKING_LEVEL,\n\t\t\tfallbackMessage: undefined,\n\t\t};\n\t}\n\n\t// 3. Try saved default from settings\n\tif (defaultProvider && defaultModelId) {\n\t\tconst found = modelRegistry.find(defaultProvider, defaultModelId);\n\t\tif (found) {\n\t\t\tmodel = found;\n\t\t\tif (defaultThinkingLevel) {\n\t\t\t\tthinkingLevel = defaultThinkingLevel;\n\t\t\t}\n\t\t\treturn { model, thinkingLevel, fallbackMessage: undefined };\n\t\t}\n\t}\n\n\t// 4. Try first available model with valid API key\n\tconst availableModels = await modelRegistry.getAvailable();\n\n\tif (availableModels.length > 0) {\n\t\t// Try to find a default model from known providers\n\t\tfor (const provider of Object.keys(defaultModelPerProvider) as KnownProvider[]) {\n\t\t\tconst defaultId = defaultModelPerProvider[provider];\n\t\t\tconst match = availableModels.find((m) => m.provider === provider && m.id === defaultId);\n\t\t\tif (match) {\n\t\t\t\treturn { model: match, thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n\t\t\t}\n\t\t}\n\n\t\t// If no default found, use first available\n\t\treturn { model: availableModels[0], thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n\t}\n\n\t// 5. No model found\n\treturn { model: undefined, thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n}\n\n/**\n * Restore model from session, with fallback to available models\n */\nexport async function restoreModelFromSession(\n\tsavedProvider: string,\n\tsavedModelId: string,\n\tcurrentModel: Model<Api> | undefined,\n\tshouldPrintMessages: boolean,\n\tmodelRegistry: ModelRegistry,\n): Promise<{ model: Model<Api> | undefined; fallbackMessage: string | undefined }> {\n\tconst restoredModel = modelRegistry.find(savedProvider, savedModelId);\n\n\t// Check if restored model exists and still has auth configured\n\tconst hasConfiguredAuth = restoredModel ? modelRegistry.hasConfiguredAuth(restoredModel) : false;\n\n\tif (restoredModel && hasConfiguredAuth) {\n\t\tif (shouldPrintMessages) {\n\t\t\tconsole.log(chalk.dim(`Restored model: ${savedProvider}/${savedModelId}`));\n\t\t}\n\t\treturn { model: restoredModel, fallbackMessage: undefined };\n\t}\n\n\t// Model not found or no API key - fall back\n\tconst reason = !restoredModel ? \"model no longer exists\" : \"no auth configured\";\n\n\tif (shouldPrintMessages) {\n\t\tconsole.error(chalk.yellow(`Warning: Could not restore model ${savedProvider}/${savedModelId} (${reason}).`));\n\t}\n\n\t// If we already have a model, use it as fallback\n\tif (currentModel) {\n\t\tif (shouldPrintMessages) {\n\t\t\tconsole.log(chalk.dim(`Falling back to: ${currentModel.provider}/${currentModel.id}`));\n\t\t}\n\t\treturn {\n\t\t\tmodel: currentModel,\n\t\t\tfallbackMessage: `Could not restore model ${savedProvider}/${savedModelId} (${reason}). Using ${currentModel.provider}/${currentModel.id}.`,\n\t\t};\n\t}\n\n\t// Try to find any available model\n\tconst availableModels = await modelRegistry.getAvailable();\n\n\tif (availableModels.length > 0) {\n\t\t// Try to find a default model from known providers\n\t\tlet fallbackModel: Model<Api> | undefined;\n\t\tfor (const provider of Object.keys(defaultModelPerProvider) as KnownProvider[]) {\n\t\t\tconst defaultId = defaultModelPerProvider[provider];\n\t\t\tconst match = availableModels.find((m) => m.provider === provider && m.id === defaultId);\n\t\t\tif (match) {\n\t\t\t\tfallbackModel = match;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// If no default found, use first available\n\t\tif (!fallbackModel) {\n\t\t\tfallbackModel = availableModels[0];\n\t\t}\n\n\t\tif (shouldPrintMessages) {\n\t\t\tconsole.log(chalk.dim(`Falling back to: ${fallbackModel.provider}/${fallbackModel.id}`));\n\t\t}\n\n\t\treturn {\n\t\t\tmodel: fallbackModel,\n\t\t\tfallbackMessage: `Could not restore model ${savedProvider}/${savedModelId} (${reason}). Using ${fallbackModel.provider}/${fallbackModel.id}.`,\n\t\t};\n\t}\n\n\t// No models available\n\treturn { model: undefined, fallbackMessage: undefined };\n}\n"]}
1
+ {"version":3,"file":"model-resolver.d.ts","sourceRoot":"","sources":["../../src/core/model-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Model resolution, scoping, and initial selection\n */\n\nimport chalk from \"chalk\";\nimport { minimatch } from \"minimatch\";\nimport type { ThinkingLevel } from \"omk-agent-core\";\nimport { type Api, type KnownProvider, type Model, modelsAreEqual } from \"omk-ai\";\nimport { isValidThinkingLevel } from \"../cli/args.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport type { ModelRegistry } from \"./model-registry.ts\";\n\n/** Default model IDs for each known provider */\nexport const defaultModelPerProvider: Record<KnownProvider, string> = {\n\t\"amazon-bedrock\": \"us.anthropic.claude-opus-4-6-v1\",\n\t\"ant-ling\": \"Ring-2.6-1T\",\n\tanthropic: \"claude-opus-4-8\",\n\topenai: \"gpt-5.4\",\n\t\"azure-openai-responses\": \"gpt-5.4\",\n\t\"openai-codex\": \"gpt-5.5\",\n\tnvidia: \"nvidia/nemotron-3-super-120b-a12b\",\n\tdeepseek: \"deepseek-v4-pro\",\n\tgoogle: \"gemini-3.1-pro-preview\",\n\t\"google-vertex\": \"gemini-3.1-pro-preview\",\n\t\"github-copilot\": \"gpt-5.4\",\n\topenrouter: \"moonshotai/kimi-k2.6\",\n\t\"vercel-ai-gateway\": \"zai/glm-5.1\",\n\txai: \"grok-4.20-0309-reasoning\",\n\tgroq: \"openai/gpt-oss-120b\",\n\tcerebras: \"zai-glm-4.7\",\n\tzai: \"glm-5.1\",\n\t\"zai-coding-cn\": \"glm-5.1\",\n\tmistral: \"devstral-medium-latest\",\n\tminimax: \"MiniMax-M2.7\",\n\t\"minimax-cn\": \"MiniMax-M2.7\",\n\tmoonshotai: \"kimi-k2.6\",\n\t\"moonshotai-cn\": \"kimi-k2.6\",\n\thuggingface: \"moonshotai/Kimi-K2.6\",\n\tfireworks: \"accounts/fireworks/models/kimi-k2p6\",\n\ttogether: \"moonshotai/Kimi-K2.6\",\n\topencode: \"kimi-k2.6\",\n\t\"opencode-go\": \"kimi-k2.6\",\n\t\"kimi-coding\": \"k2p7\",\n\t\"cloudflare-workers-ai\": \"@cf/moonshotai/kimi-k2.6\",\n\t\"cloudflare-ai-gateway\": \"workers-ai/@cf/moonshotai/kimi-k2.6\",\n\txiaomi: \"mimo-v2.5-pro\",\n\t\"xiaomi-token-plan-cn\": \"mimo-v2.5-pro\",\n\t\"xiaomi-token-plan-ams\": \"mimo-v2.5-pro\",\n\t\"xiaomi-token-plan-sgp\": \"mimo-v2.5-pro\",\n\tzyloo: \"claude-opus-4-7\",\n};\n\nexport interface ScopedModel {\n\tmodel: Model<Api>;\n\t/** Thinking level if explicitly specified in pattern (e.g., \"model:high\"), undefined otherwise */\n\tthinkingLevel?: ThinkingLevel;\n}\n\n/**\n * Helper to check if a model ID looks like an alias (no date suffix)\n * Dates are typically in format: -20241022 or -20250929\n */\nfunction isAlias(id: string): boolean {\n\t// Check if ID ends with -latest\n\tif (id.endsWith(\"-latest\")) return true;\n\n\t// Check if ID ends with a date pattern (-YYYYMMDD)\n\tconst datePattern = /-\\d{8}$/;\n\treturn !datePattern.test(id);\n}\n\n/**\n * Find an exact model reference match.\n * Supports either a bare model id or a canonical provider/modelId reference.\n * When matching by bare id, ambiguous matches across providers are rejected.\n */\nexport function findExactModelReferenceMatch(\n\tmodelReference: string,\n\tavailableModels: Model<Api>[],\n): Model<Api> | undefined {\n\tconst trimmedReference = modelReference.trim();\n\tif (!trimmedReference) {\n\t\treturn undefined;\n\t}\n\n\tconst normalizedReference = trimmedReference.toLowerCase();\n\n\tconst canonicalMatches = availableModels.filter(\n\t\t(model) => `${model.provider}/${model.id}`.toLowerCase() === normalizedReference,\n\t);\n\tif (canonicalMatches.length === 1) {\n\t\treturn canonicalMatches[0];\n\t}\n\tif (canonicalMatches.length > 1) {\n\t\treturn undefined;\n\t}\n\n\tconst slashIndex = trimmedReference.indexOf(\"/\");\n\tif (slashIndex !== -1) {\n\t\tconst provider = trimmedReference.substring(0, slashIndex).trim();\n\t\tconst modelId = trimmedReference.substring(slashIndex + 1).trim();\n\t\tif (provider && modelId) {\n\t\t\tconst providerMatches = availableModels.filter(\n\t\t\t\t(model) =>\n\t\t\t\t\tmodel.provider.toLowerCase() === provider.toLowerCase() &&\n\t\t\t\t\tmodel.id.toLowerCase() === modelId.toLowerCase(),\n\t\t\t);\n\t\t\tif (providerMatches.length === 1) {\n\t\t\t\treturn providerMatches[0];\n\t\t\t}\n\t\t\tif (providerMatches.length > 1) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst idMatches = availableModels.filter((model) => model.id.toLowerCase() === normalizedReference);\n\treturn idMatches.length === 1 ? idMatches[0] : undefined;\n}\n\n/**\n * Try to match a pattern to a model from the available models list.\n * Returns the matched model or undefined if no match found.\n */\nfunction tryMatchModel(modelPattern: string, availableModels: Model<Api>[]): Model<Api> | undefined {\n\tconst exactMatch = findExactModelReferenceMatch(modelPattern, availableModels);\n\tif (exactMatch) {\n\t\treturn exactMatch;\n\t}\n\n\t// No exact match - fall back to partial matching\n\tconst matches = availableModels.filter(\n\t\t(m) =>\n\t\t\tm.id.toLowerCase().includes(modelPattern.toLowerCase()) ||\n\t\t\tm.name?.toLowerCase().includes(modelPattern.toLowerCase()),\n\t);\n\n\tif (matches.length === 0) {\n\t\treturn undefined;\n\t}\n\n\t// Separate into aliases and dated versions\n\tconst aliases = matches.filter((m) => isAlias(m.id));\n\tconst datedVersions = matches.filter((m) => !isAlias(m.id));\n\n\tif (aliases.length > 0) {\n\t\t// Prefer alias - if multiple aliases, pick the one that sorts highest\n\t\taliases.sort((a, b) => b.id.localeCompare(a.id));\n\t\treturn aliases[0];\n\t} else {\n\t\t// No alias found, pick latest dated version\n\t\tdatedVersions.sort((a, b) => b.id.localeCompare(a.id));\n\t\treturn datedVersions[0];\n\t}\n}\n\nexport interface ParsedModelResult {\n\tmodel: Model<Api> | undefined;\n\t/** Thinking level if explicitly specified in pattern, undefined otherwise */\n\tthinkingLevel?: ThinkingLevel;\n\twarning: string | undefined;\n}\n\nfunction buildFallbackModel(provider: string, modelId: string, availableModels: Model<Api>[]): Model<Api> | undefined {\n\tconst providerModels = availableModels.filter((m) => m.provider === provider);\n\tif (providerModels.length === 0) return undefined;\n\n\tconst defaultId = defaultModelPerProvider[provider as KnownProvider];\n\tconst baseModel = defaultId\n\t\t? (providerModels.find((m) => m.id === defaultId) ?? providerModels[0])\n\t\t: providerModels[0];\n\n\treturn {\n\t\t...baseModel,\n\t\tid: modelId,\n\t\tname: modelId,\n\t};\n}\n\n/**\n * Parse a pattern to extract model and thinking level.\n * Handles models with colons in their IDs (e.g., OpenRouter's :exacto suffix).\n *\n * Algorithm:\n * 1. Try to match full pattern as a model\n * 2. If found, return it with \"off\" thinking level\n * 3. If not found and has colons, split on last colon:\n * - If suffix is valid thinking level, use it and recurse on prefix\n * - If suffix is invalid, warn and recurse on prefix with \"off\"\n *\n * @internal Exported for testing\n */\nexport function parseModelPattern(\n\tpattern: string,\n\tavailableModels: Model<Api>[],\n\toptions?: { allowInvalidThinkingLevelFallback?: boolean },\n): ParsedModelResult {\n\t// Try exact match first\n\tconst exactMatch = tryMatchModel(pattern, availableModels);\n\tif (exactMatch) {\n\t\treturn { model: exactMatch, thinkingLevel: undefined, warning: undefined };\n\t}\n\n\t// No match - try splitting on last colon if present\n\tconst lastColonIndex = pattern.lastIndexOf(\":\");\n\tif (lastColonIndex === -1) {\n\t\t// No colons, pattern simply doesn't match any model\n\t\treturn { model: undefined, thinkingLevel: undefined, warning: undefined };\n\t}\n\n\tconst prefix = pattern.substring(0, lastColonIndex);\n\tconst suffix = pattern.substring(lastColonIndex + 1);\n\n\tif (isValidThinkingLevel(suffix)) {\n\t\t// Valid thinking level - recurse on prefix and use this level\n\t\tconst result = parseModelPattern(prefix, availableModels, options);\n\t\tif (result.model) {\n\t\t\t// Only use this thinking level if no warning from inner recursion\n\t\t\treturn {\n\t\t\t\tmodel: result.model,\n\t\t\t\tthinkingLevel: result.warning ? undefined : suffix,\n\t\t\t\twarning: result.warning,\n\t\t\t};\n\t\t}\n\t\treturn result;\n\t} else {\n\t\t// Invalid suffix\n\t\tconst allowFallback = options?.allowInvalidThinkingLevelFallback ?? true;\n\t\tif (!allowFallback) {\n\t\t\t// In strict mode (CLI --model parsing), treat it as part of the model id and fail.\n\t\t\t// This avoids accidentally resolving to a different model.\n\t\t\treturn { model: undefined, thinkingLevel: undefined, warning: undefined };\n\t\t}\n\n\t\t// Scope mode: recurse on prefix and warn\n\t\tconst result = parseModelPattern(prefix, availableModels, options);\n\t\tif (result.model) {\n\t\t\treturn {\n\t\t\t\tmodel: result.model,\n\t\t\t\tthinkingLevel: undefined,\n\t\t\t\twarning: `Invalid thinking level \"${suffix}\" in pattern \"${pattern}\". Using default instead.`,\n\t\t\t};\n\t\t}\n\t\treturn result;\n\t}\n}\n\n/**\n * Resolve model patterns to actual Model objects with optional thinking levels\n * Format: \"pattern:level\" where :level is optional\n * For each pattern, finds all matching models and picks the best version:\n * 1. Prefer alias (e.g., claude-sonnet-4-5) over dated versions (claude-sonnet-4-5-20250929)\n * 2. If no alias, pick the latest dated version\n *\n * Supports models with colons in their IDs (e.g., OpenRouter's model:exacto).\n * The algorithm tries to match the full pattern first, then progressively\n * strips colon-suffixes to find a match.\n */\nexport async function resolveModelScope(patterns: string[], modelRegistry: ModelRegistry): Promise<ScopedModel[]> {\n\tconst availableModels = await modelRegistry.getAvailable();\n\tconst scopedModels: ScopedModel[] = [];\n\n\tfor (const pattern of patterns) {\n\t\t// Check if pattern contains glob characters\n\t\tif (pattern.includes(\"*\") || pattern.includes(\"?\") || pattern.includes(\"[\")) {\n\t\t\t// Extract optional thinking level suffix (e.g., \"provider/*:high\")\n\t\t\tconst colonIdx = pattern.lastIndexOf(\":\");\n\t\t\tlet globPattern = pattern;\n\t\t\tlet thinkingLevel: ThinkingLevel | undefined;\n\n\t\t\tif (colonIdx !== -1) {\n\t\t\t\tconst suffix = pattern.substring(colonIdx + 1);\n\t\t\t\tif (isValidThinkingLevel(suffix)) {\n\t\t\t\t\tthinkingLevel = suffix;\n\t\t\t\t\tglobPattern = pattern.substring(0, colonIdx);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Match against \"provider/modelId\" format OR just model ID\n\t\t\t// This allows \"*sonnet*\" to match without requiring \"anthropic/*sonnet*\"\n\t\t\tconst matchingModels = availableModels.filter((m) => {\n\t\t\t\tconst fullId = `${m.provider}/${m.id}`;\n\t\t\t\treturn minimatch(fullId, globPattern, { nocase: true }) || minimatch(m.id, globPattern, { nocase: true });\n\t\t\t});\n\n\t\t\tif (matchingModels.length === 0) {\n\t\t\t\tconsole.warn(chalk.yellow(`Warning: No models match pattern \"${pattern}\"`));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tfor (const model of matchingModels) {\n\t\t\t\tif (!scopedModels.find((sm) => modelsAreEqual(sm.model, model))) {\n\t\t\t\t\tscopedModels.push({ model, thinkingLevel });\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst { model, thinkingLevel, warning } = parseModelPattern(pattern, availableModels);\n\n\t\tif (warning) {\n\t\t\tconsole.warn(chalk.yellow(`Warning: ${warning}`));\n\t\t}\n\n\t\tif (!model) {\n\t\t\tconsole.warn(chalk.yellow(`Warning: No models match pattern \"${pattern}\"`));\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Avoid duplicates\n\t\tif (!scopedModels.find((sm) => modelsAreEqual(sm.model, model))) {\n\t\t\tscopedModels.push({ model, thinkingLevel });\n\t\t}\n\t}\n\n\treturn scopedModels;\n}\n\nexport interface ResolveCliModelResult {\n\tmodel: Model<Api> | undefined;\n\tthinkingLevel?: ThinkingLevel;\n\twarning: string | undefined;\n\t/**\n\t * Error message suitable for CLI display.\n\t * When set, model will be undefined.\n\t */\n\terror: string | undefined;\n}\n\n/**\n * Resolve a single model from CLI flags.\n *\n * Supports:\n * - --provider <provider> --model <pattern>\n * - --model <provider>/<pattern>\n * - Fuzzy matching (same rules as model scoping: exact id, then partial id/name)\n *\n * Note: This does not apply the thinking level by itself, but it may *parse* and\n * return a thinking level from \"<pattern>:<thinking>\" so the caller can apply it.\n */\nexport function resolveCliModel(options: {\n\tcliProvider?: string;\n\tcliModel?: string;\n\tmodelRegistry: ModelRegistry;\n}): ResolveCliModelResult {\n\tconst { cliProvider, cliModel, modelRegistry } = options;\n\n\tif (!cliModel) {\n\t\treturn { model: undefined, warning: undefined, error: undefined };\n\t}\n\n\t// Important: use *all* models here, not just models with pre-configured auth.\n\t// This allows \"--api-key\" to be used for first-time setup.\n\tconst availableModels = modelRegistry.getAll();\n\tif (availableModels.length === 0) {\n\t\treturn {\n\t\t\tmodel: undefined,\n\t\t\twarning: undefined,\n\t\t\terror: \"No models available. Check your installation or add models to models.json.\",\n\t\t};\n\t}\n\n\t// Build canonical provider lookup (case-insensitive)\n\tconst providerMap = new Map<string, string>();\n\tfor (const m of availableModels) {\n\t\tproviderMap.set(m.provider.toLowerCase(), m.provider);\n\t}\n\n\tlet provider = cliProvider ? providerMap.get(cliProvider.toLowerCase()) : undefined;\n\tif (cliProvider && !provider) {\n\t\treturn {\n\t\t\tmodel: undefined,\n\t\t\twarning: undefined,\n\t\t\terror: `Unknown provider \"${cliProvider}\". Use --list-models to see available providers/models.`,\n\t\t};\n\t}\n\n\t// If no explicit --provider, try to interpret \"provider/model\" format first.\n\t// When the prefix before the first slash matches a known provider, prefer that\n\t// interpretation over matching models whose IDs literally contain slashes\n\t// (e.g. \"zai/glm-5\" should resolve to provider=zai, model=glm-5, not to a\n\t// vercel-ai-gateway model with id \"zai/glm-5\").\n\tlet pattern = cliModel;\n\tlet inferredProvider = false;\n\n\tif (!provider) {\n\t\tconst slashIndex = cliModel.indexOf(\"/\");\n\t\tif (slashIndex !== -1) {\n\t\t\tconst maybeProvider = cliModel.substring(0, slashIndex);\n\t\t\tconst canonical = providerMap.get(maybeProvider.toLowerCase());\n\t\t\tif (canonical) {\n\t\t\t\tprovider = canonical;\n\t\t\t\tpattern = cliModel.substring(slashIndex + 1);\n\t\t\t\tinferredProvider = true;\n\t\t\t}\n\t\t}\n\t}\n\n\t// If no provider was inferred from the slash, try exact matches without provider inference.\n\t// This handles models whose IDs naturally contain slashes (e.g. OpenRouter-style IDs).\n\tif (!provider) {\n\t\tconst lower = cliModel.toLowerCase();\n\t\tconst exact = availableModels.find(\n\t\t\t(m) => m.id.toLowerCase() === lower || `${m.provider}/${m.id}`.toLowerCase() === lower,\n\t\t);\n\t\tif (exact) {\n\t\t\treturn { model: exact, warning: undefined, thinkingLevel: undefined, error: undefined };\n\t\t}\n\t}\n\n\tif (cliProvider && provider) {\n\t\t// If both were provided, tolerate --model <provider>/<pattern> by stripping the provider prefix\n\t\tconst prefix = `${provider}/`;\n\t\tif (cliModel.toLowerCase().startsWith(prefix.toLowerCase())) {\n\t\t\tpattern = cliModel.substring(prefix.length);\n\t\t}\n\t}\n\n\tconst candidates = provider ? availableModels.filter((m) => m.provider === provider) : availableModels;\n\tconst { model, thinkingLevel, warning } = parseModelPattern(pattern, candidates, {\n\t\tallowInvalidThinkingLevelFallback: false,\n\t});\n\n\tif (model) {\n\t\treturn { model, thinkingLevel, warning, error: undefined };\n\t}\n\n\t// If we inferred a provider from the slash but found no match within that provider,\n\t// fall back to matching the full input as a raw model id across all models.\n\t// This handles OpenRouter-style IDs like \"openai/gpt-4o:extended\" where \"openai\"\n\t// looks like a provider but the full string is actually a model id on openrouter.\n\tif (inferredProvider) {\n\t\tconst lower = cliModel.toLowerCase();\n\t\tconst exact = availableModels.find(\n\t\t\t(m) => m.id.toLowerCase() === lower || `${m.provider}/${m.id}`.toLowerCase() === lower,\n\t\t);\n\t\tif (exact) {\n\t\t\treturn { model: exact, warning: undefined, thinkingLevel: undefined, error: undefined };\n\t\t}\n\t\t// Also try parseModelPattern on the full input against all models\n\t\tconst fallback = parseModelPattern(cliModel, availableModels, {\n\t\t\tallowInvalidThinkingLevelFallback: false,\n\t\t});\n\t\tif (fallback.model) {\n\t\t\treturn {\n\t\t\t\tmodel: fallback.model,\n\t\t\t\tthinkingLevel: fallback.thinkingLevel,\n\t\t\t\twarning: fallback.warning,\n\t\t\t\terror: undefined,\n\t\t\t};\n\t\t}\n\t}\n\n\tif (provider) {\n\t\tconst fallbackModel = buildFallbackModel(provider, pattern, availableModels);\n\t\tif (fallbackModel) {\n\t\t\tconst fallbackWarning = warning\n\t\t\t\t? `${warning} Model \"${pattern}\" not found for provider \"${provider}\". Using custom model id.`\n\t\t\t\t: `Model \"${pattern}\" not found for provider \"${provider}\". Using custom model id.`;\n\t\t\treturn { model: fallbackModel, thinkingLevel: undefined, warning: fallbackWarning, error: undefined };\n\t\t}\n\t}\n\n\tconst display = provider ? `${provider}/${pattern}` : cliModel;\n\treturn {\n\t\tmodel: undefined,\n\t\tthinkingLevel: undefined,\n\t\twarning,\n\t\terror: `Model \"${display}\" not found. Use --list-models to see available models.`,\n\t};\n}\n\nexport interface InitialModelResult {\n\tmodel: Model<Api> | undefined;\n\tthinkingLevel: ThinkingLevel;\n\tfallbackMessage: string | undefined;\n}\n\n/**\n * Find the initial model to use based on priority:\n * 1. CLI args (provider + model)\n * 2. First model from scoped models (if not continuing/resuming)\n * 3. Restored from session (if continuing/resuming)\n * 4. Saved default from settings\n * 5. First available model with valid API key\n */\nexport async function findInitialModel(options: {\n\tcliProvider?: string;\n\tcliModel?: string;\n\tscopedModels: ScopedModel[];\n\tisContinuing: boolean;\n\tdefaultProvider?: string;\n\tdefaultModelId?: string;\n\tdefaultThinkingLevel?: ThinkingLevel;\n\tmodelRegistry: ModelRegistry;\n}): Promise<InitialModelResult> {\n\tconst {\n\t\tcliProvider,\n\t\tcliModel,\n\t\tscopedModels,\n\t\tisContinuing,\n\t\tdefaultProvider,\n\t\tdefaultModelId,\n\t\tdefaultThinkingLevel,\n\t\tmodelRegistry,\n\t} = options;\n\n\tlet model: Model<Api> | undefined;\n\tlet thinkingLevel: ThinkingLevel = DEFAULT_THINKING_LEVEL;\n\n\t// 1. CLI args take priority\n\tif (cliProvider && cliModel) {\n\t\tconst resolved = resolveCliModel({\n\t\t\tcliProvider,\n\t\t\tcliModel,\n\t\t\tmodelRegistry,\n\t\t});\n\t\tif (resolved.error) {\n\t\t\tconsole.error(chalk.red(resolved.error));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tif (resolved.model) {\n\t\t\treturn { model: resolved.model, thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n\t\t}\n\t}\n\n\t// 2. Use first model from scoped models (skip if continuing/resuming)\n\tif (scopedModels.length > 0 && !isContinuing) {\n\t\treturn {\n\t\t\tmodel: scopedModels[0].model,\n\t\t\tthinkingLevel: scopedModels[0].thinkingLevel ?? defaultThinkingLevel ?? DEFAULT_THINKING_LEVEL,\n\t\t\tfallbackMessage: undefined,\n\t\t};\n\t}\n\n\t// 3. Try saved default from settings\n\tif (defaultProvider && defaultModelId) {\n\t\tconst found = modelRegistry.find(defaultProvider, defaultModelId);\n\t\tif (found) {\n\t\t\tmodel = found;\n\t\t\tif (defaultThinkingLevel) {\n\t\t\t\tthinkingLevel = defaultThinkingLevel;\n\t\t\t}\n\t\t\treturn { model, thinkingLevel, fallbackMessage: undefined };\n\t\t}\n\t}\n\n\t// 4. Try first available model with valid API key\n\tconst availableModels = await modelRegistry.getAvailable();\n\n\tif (availableModels.length > 0) {\n\t\t// Try to find a default model from known providers\n\t\tfor (const provider of Object.keys(defaultModelPerProvider) as KnownProvider[]) {\n\t\t\tconst defaultId = defaultModelPerProvider[provider];\n\t\t\tconst match = availableModels.find((m) => m.provider === provider && m.id === defaultId);\n\t\t\tif (match) {\n\t\t\t\treturn { model: match, thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n\t\t\t}\n\t\t}\n\n\t\t// If no default found, use first available\n\t\treturn { model: availableModels[0], thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n\t}\n\n\t// 5. No model found\n\treturn { model: undefined, thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n}\n\n/**\n * Restore model from session, with fallback to available models\n */\nexport async function restoreModelFromSession(\n\tsavedProvider: string,\n\tsavedModelId: string,\n\tcurrentModel: Model<Api> | undefined,\n\tshouldPrintMessages: boolean,\n\tmodelRegistry: ModelRegistry,\n): Promise<{ model: Model<Api> | undefined; fallbackMessage: string | undefined }> {\n\tconst restoredModel = modelRegistry.find(savedProvider, savedModelId);\n\n\t// Check if restored model exists and still has auth configured\n\tconst hasConfiguredAuth = restoredModel ? modelRegistry.hasConfiguredAuth(restoredModel) : false;\n\n\tif (restoredModel && hasConfiguredAuth) {\n\t\tif (shouldPrintMessages) {\n\t\t\tconsole.log(chalk.dim(`Restored model: ${savedProvider}/${savedModelId}`));\n\t\t}\n\t\treturn { model: restoredModel, fallbackMessage: undefined };\n\t}\n\n\t// Model not found or no API key - fall back\n\tconst reason = !restoredModel ? \"model no longer exists\" : \"no auth configured\";\n\n\tif (shouldPrintMessages) {\n\t\tconsole.error(chalk.yellow(`Warning: Could not restore model ${savedProvider}/${savedModelId} (${reason}).`));\n\t}\n\n\t// If we already have a model, use it as fallback\n\tif (currentModel) {\n\t\tif (shouldPrintMessages) {\n\t\t\tconsole.log(chalk.dim(`Falling back to: ${currentModel.provider}/${currentModel.id}`));\n\t\t}\n\t\treturn {\n\t\t\tmodel: currentModel,\n\t\t\tfallbackMessage: `Could not restore model ${savedProvider}/${savedModelId} (${reason}). Using ${currentModel.provider}/${currentModel.id}.`,\n\t\t};\n\t}\n\n\t// Try to find any available model\n\tconst availableModels = await modelRegistry.getAvailable();\n\n\tif (availableModels.length > 0) {\n\t\t// Try to find a default model from known providers\n\t\tlet fallbackModel: Model<Api> | undefined;\n\t\tfor (const provider of Object.keys(defaultModelPerProvider) as KnownProvider[]) {\n\t\t\tconst defaultId = defaultModelPerProvider[provider];\n\t\t\tconst match = availableModels.find((m) => m.provider === provider && m.id === defaultId);\n\t\t\tif (match) {\n\t\t\t\tfallbackModel = match;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// If no default found, use first available\n\t\tif (!fallbackModel) {\n\t\t\tfallbackModel = availableModels[0];\n\t\t}\n\n\t\tif (shouldPrintMessages) {\n\t\t\tconsole.log(chalk.dim(`Falling back to: ${fallbackModel.provider}/${fallbackModel.id}`));\n\t\t}\n\n\t\treturn {\n\t\t\tmodel: fallbackModel,\n\t\t\tfallbackMessage: `Could not restore model ${savedProvider}/${savedModelId} (${reason}). Using ${fallbackModel.provider}/${fallbackModel.id}.`,\n\t\t};\n\t}\n\n\t// No models available\n\treturn { model: undefined, fallbackMessage: undefined };\n}\n"]}
@@ -36,7 +36,7 @@ export const defaultModelPerProvider = {
36
36
  together: "moonshotai/Kimi-K2.6",
37
37
  opencode: "kimi-k2.6",
38
38
  "opencode-go": "kimi-k2.6",
39
- "kimi-coding": "kimi-for-coding",
39
+ "kimi-coding": "k2p7",
40
40
  "cloudflare-workers-ai": "@cf/moonshotai/kimi-k2.6",
41
41
  "cloudflare-ai-gateway": "workers-ai/@cf/moonshotai/kimi-k2.6",
42
42
  xiaomi: "mimo-v2.5-pro",
@@ -1 +1 @@
1
- {"version":3,"file":"model-resolver.js","sourceRoot":"","sources":["../../src/core/model-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Model resolution, scoping, and initial selection\n */\n\nimport chalk from \"chalk\";\nimport { minimatch } from \"minimatch\";\nimport type { ThinkingLevel } from \"omk-agent-core\";\nimport { type Api, type KnownProvider, type Model, modelsAreEqual } from \"omk-ai\";\nimport { isValidThinkingLevel } from \"../cli/args.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport type { ModelRegistry } from \"./model-registry.ts\";\n\n/** Default model IDs for each known provider */\nexport const defaultModelPerProvider: Record<KnownProvider, string> = {\n\t\"amazon-bedrock\": \"us.anthropic.claude-opus-4-6-v1\",\n\t\"ant-ling\": \"Ring-2.6-1T\",\n\tanthropic: \"claude-opus-4-8\",\n\topenai: \"gpt-5.4\",\n\t\"azure-openai-responses\": \"gpt-5.4\",\n\t\"openai-codex\": \"gpt-5.5\",\n\tnvidia: \"nvidia/nemotron-3-super-120b-a12b\",\n\tdeepseek: \"deepseek-v4-pro\",\n\tgoogle: \"gemini-3.1-pro-preview\",\n\t\"google-vertex\": \"gemini-3.1-pro-preview\",\n\t\"github-copilot\": \"gpt-5.4\",\n\topenrouter: \"moonshotai/kimi-k2.6\",\n\t\"vercel-ai-gateway\": \"zai/glm-5.1\",\n\txai: \"grok-4.20-0309-reasoning\",\n\tgroq: \"openai/gpt-oss-120b\",\n\tcerebras: \"zai-glm-4.7\",\n\tzai: \"glm-5.1\",\n\t\"zai-coding-cn\": \"glm-5.1\",\n\tmistral: \"devstral-medium-latest\",\n\tminimax: \"MiniMax-M2.7\",\n\t\"minimax-cn\": \"MiniMax-M2.7\",\n\tmoonshotai: \"kimi-k2.6\",\n\t\"moonshotai-cn\": \"kimi-k2.6\",\n\thuggingface: \"moonshotai/Kimi-K2.6\",\n\tfireworks: \"accounts/fireworks/models/kimi-k2p6\",\n\ttogether: \"moonshotai/Kimi-K2.6\",\n\topencode: \"kimi-k2.6\",\n\t\"opencode-go\": \"kimi-k2.6\",\n\t\"kimi-coding\": \"kimi-for-coding\",\n\t\"cloudflare-workers-ai\": \"@cf/moonshotai/kimi-k2.6\",\n\t\"cloudflare-ai-gateway\": \"workers-ai/@cf/moonshotai/kimi-k2.6\",\n\txiaomi: \"mimo-v2.5-pro\",\n\t\"xiaomi-token-plan-cn\": \"mimo-v2.5-pro\",\n\t\"xiaomi-token-plan-ams\": \"mimo-v2.5-pro\",\n\t\"xiaomi-token-plan-sgp\": \"mimo-v2.5-pro\",\n\tzyloo: \"claude-opus-4-7\",\n};\n\nexport interface ScopedModel {\n\tmodel: Model<Api>;\n\t/** Thinking level if explicitly specified in pattern (e.g., \"model:high\"), undefined otherwise */\n\tthinkingLevel?: ThinkingLevel;\n}\n\n/**\n * Helper to check if a model ID looks like an alias (no date suffix)\n * Dates are typically in format: -20241022 or -20250929\n */\nfunction isAlias(id: string): boolean {\n\t// Check if ID ends with -latest\n\tif (id.endsWith(\"-latest\")) return true;\n\n\t// Check if ID ends with a date pattern (-YYYYMMDD)\n\tconst datePattern = /-\\d{8}$/;\n\treturn !datePattern.test(id);\n}\n\n/**\n * Find an exact model reference match.\n * Supports either a bare model id or a canonical provider/modelId reference.\n * When matching by bare id, ambiguous matches across providers are rejected.\n */\nexport function findExactModelReferenceMatch(\n\tmodelReference: string,\n\tavailableModels: Model<Api>[],\n): Model<Api> | undefined {\n\tconst trimmedReference = modelReference.trim();\n\tif (!trimmedReference) {\n\t\treturn undefined;\n\t}\n\n\tconst normalizedReference = trimmedReference.toLowerCase();\n\n\tconst canonicalMatches = availableModels.filter(\n\t\t(model) => `${model.provider}/${model.id}`.toLowerCase() === normalizedReference,\n\t);\n\tif (canonicalMatches.length === 1) {\n\t\treturn canonicalMatches[0];\n\t}\n\tif (canonicalMatches.length > 1) {\n\t\treturn undefined;\n\t}\n\n\tconst slashIndex = trimmedReference.indexOf(\"/\");\n\tif (slashIndex !== -1) {\n\t\tconst provider = trimmedReference.substring(0, slashIndex).trim();\n\t\tconst modelId = trimmedReference.substring(slashIndex + 1).trim();\n\t\tif (provider && modelId) {\n\t\t\tconst providerMatches = availableModels.filter(\n\t\t\t\t(model) =>\n\t\t\t\t\tmodel.provider.toLowerCase() === provider.toLowerCase() &&\n\t\t\t\t\tmodel.id.toLowerCase() === modelId.toLowerCase(),\n\t\t\t);\n\t\t\tif (providerMatches.length === 1) {\n\t\t\t\treturn providerMatches[0];\n\t\t\t}\n\t\t\tif (providerMatches.length > 1) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst idMatches = availableModels.filter((model) => model.id.toLowerCase() === normalizedReference);\n\treturn idMatches.length === 1 ? idMatches[0] : undefined;\n}\n\n/**\n * Try to match a pattern to a model from the available models list.\n * Returns the matched model or undefined if no match found.\n */\nfunction tryMatchModel(modelPattern: string, availableModels: Model<Api>[]): Model<Api> | undefined {\n\tconst exactMatch = findExactModelReferenceMatch(modelPattern, availableModels);\n\tif (exactMatch) {\n\t\treturn exactMatch;\n\t}\n\n\t// No exact match - fall back to partial matching\n\tconst matches = availableModels.filter(\n\t\t(m) =>\n\t\t\tm.id.toLowerCase().includes(modelPattern.toLowerCase()) ||\n\t\t\tm.name?.toLowerCase().includes(modelPattern.toLowerCase()),\n\t);\n\n\tif (matches.length === 0) {\n\t\treturn undefined;\n\t}\n\n\t// Separate into aliases and dated versions\n\tconst aliases = matches.filter((m) => isAlias(m.id));\n\tconst datedVersions = matches.filter((m) => !isAlias(m.id));\n\n\tif (aliases.length > 0) {\n\t\t// Prefer alias - if multiple aliases, pick the one that sorts highest\n\t\taliases.sort((a, b) => b.id.localeCompare(a.id));\n\t\treturn aliases[0];\n\t} else {\n\t\t// No alias found, pick latest dated version\n\t\tdatedVersions.sort((a, b) => b.id.localeCompare(a.id));\n\t\treturn datedVersions[0];\n\t}\n}\n\nexport interface ParsedModelResult {\n\tmodel: Model<Api> | undefined;\n\t/** Thinking level if explicitly specified in pattern, undefined otherwise */\n\tthinkingLevel?: ThinkingLevel;\n\twarning: string | undefined;\n}\n\nfunction buildFallbackModel(provider: string, modelId: string, availableModels: Model<Api>[]): Model<Api> | undefined {\n\tconst providerModels = availableModels.filter((m) => m.provider === provider);\n\tif (providerModels.length === 0) return undefined;\n\n\tconst defaultId = defaultModelPerProvider[provider as KnownProvider];\n\tconst baseModel = defaultId\n\t\t? (providerModels.find((m) => m.id === defaultId) ?? providerModels[0])\n\t\t: providerModels[0];\n\n\treturn {\n\t\t...baseModel,\n\t\tid: modelId,\n\t\tname: modelId,\n\t};\n}\n\n/**\n * Parse a pattern to extract model and thinking level.\n * Handles models with colons in their IDs (e.g., OpenRouter's :exacto suffix).\n *\n * Algorithm:\n * 1. Try to match full pattern as a model\n * 2. If found, return it with \"off\" thinking level\n * 3. If not found and has colons, split on last colon:\n * - If suffix is valid thinking level, use it and recurse on prefix\n * - If suffix is invalid, warn and recurse on prefix with \"off\"\n *\n * @internal Exported for testing\n */\nexport function parseModelPattern(\n\tpattern: string,\n\tavailableModels: Model<Api>[],\n\toptions?: { allowInvalidThinkingLevelFallback?: boolean },\n): ParsedModelResult {\n\t// Try exact match first\n\tconst exactMatch = tryMatchModel(pattern, availableModels);\n\tif (exactMatch) {\n\t\treturn { model: exactMatch, thinkingLevel: undefined, warning: undefined };\n\t}\n\n\t// No match - try splitting on last colon if present\n\tconst lastColonIndex = pattern.lastIndexOf(\":\");\n\tif (lastColonIndex === -1) {\n\t\t// No colons, pattern simply doesn't match any model\n\t\treturn { model: undefined, thinkingLevel: undefined, warning: undefined };\n\t}\n\n\tconst prefix = pattern.substring(0, lastColonIndex);\n\tconst suffix = pattern.substring(lastColonIndex + 1);\n\n\tif (isValidThinkingLevel(suffix)) {\n\t\t// Valid thinking level - recurse on prefix and use this level\n\t\tconst result = parseModelPattern(prefix, availableModels, options);\n\t\tif (result.model) {\n\t\t\t// Only use this thinking level if no warning from inner recursion\n\t\t\treturn {\n\t\t\t\tmodel: result.model,\n\t\t\t\tthinkingLevel: result.warning ? undefined : suffix,\n\t\t\t\twarning: result.warning,\n\t\t\t};\n\t\t}\n\t\treturn result;\n\t} else {\n\t\t// Invalid suffix\n\t\tconst allowFallback = options?.allowInvalidThinkingLevelFallback ?? true;\n\t\tif (!allowFallback) {\n\t\t\t// In strict mode (CLI --model parsing), treat it as part of the model id and fail.\n\t\t\t// This avoids accidentally resolving to a different model.\n\t\t\treturn { model: undefined, thinkingLevel: undefined, warning: undefined };\n\t\t}\n\n\t\t// Scope mode: recurse on prefix and warn\n\t\tconst result = parseModelPattern(prefix, availableModels, options);\n\t\tif (result.model) {\n\t\t\treturn {\n\t\t\t\tmodel: result.model,\n\t\t\t\tthinkingLevel: undefined,\n\t\t\t\twarning: `Invalid thinking level \"${suffix}\" in pattern \"${pattern}\". Using default instead.`,\n\t\t\t};\n\t\t}\n\t\treturn result;\n\t}\n}\n\n/**\n * Resolve model patterns to actual Model objects with optional thinking levels\n * Format: \"pattern:level\" where :level is optional\n * For each pattern, finds all matching models and picks the best version:\n * 1. Prefer alias (e.g., claude-sonnet-4-5) over dated versions (claude-sonnet-4-5-20250929)\n * 2. If no alias, pick the latest dated version\n *\n * Supports models with colons in their IDs (e.g., OpenRouter's model:exacto).\n * The algorithm tries to match the full pattern first, then progressively\n * strips colon-suffixes to find a match.\n */\nexport async function resolveModelScope(patterns: string[], modelRegistry: ModelRegistry): Promise<ScopedModel[]> {\n\tconst availableModels = await modelRegistry.getAvailable();\n\tconst scopedModels: ScopedModel[] = [];\n\n\tfor (const pattern of patterns) {\n\t\t// Check if pattern contains glob characters\n\t\tif (pattern.includes(\"*\") || pattern.includes(\"?\") || pattern.includes(\"[\")) {\n\t\t\t// Extract optional thinking level suffix (e.g., \"provider/*:high\")\n\t\t\tconst colonIdx = pattern.lastIndexOf(\":\");\n\t\t\tlet globPattern = pattern;\n\t\t\tlet thinkingLevel: ThinkingLevel | undefined;\n\n\t\t\tif (colonIdx !== -1) {\n\t\t\t\tconst suffix = pattern.substring(colonIdx + 1);\n\t\t\t\tif (isValidThinkingLevel(suffix)) {\n\t\t\t\t\tthinkingLevel = suffix;\n\t\t\t\t\tglobPattern = pattern.substring(0, colonIdx);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Match against \"provider/modelId\" format OR just model ID\n\t\t\t// This allows \"*sonnet*\" to match without requiring \"anthropic/*sonnet*\"\n\t\t\tconst matchingModels = availableModels.filter((m) => {\n\t\t\t\tconst fullId = `${m.provider}/${m.id}`;\n\t\t\t\treturn minimatch(fullId, globPattern, { nocase: true }) || minimatch(m.id, globPattern, { nocase: true });\n\t\t\t});\n\n\t\t\tif (matchingModels.length === 0) {\n\t\t\t\tconsole.warn(chalk.yellow(`Warning: No models match pattern \"${pattern}\"`));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tfor (const model of matchingModels) {\n\t\t\t\tif (!scopedModels.find((sm) => modelsAreEqual(sm.model, model))) {\n\t\t\t\t\tscopedModels.push({ model, thinkingLevel });\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst { model, thinkingLevel, warning } = parseModelPattern(pattern, availableModels);\n\n\t\tif (warning) {\n\t\t\tconsole.warn(chalk.yellow(`Warning: ${warning}`));\n\t\t}\n\n\t\tif (!model) {\n\t\t\tconsole.warn(chalk.yellow(`Warning: No models match pattern \"${pattern}\"`));\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Avoid duplicates\n\t\tif (!scopedModels.find((sm) => modelsAreEqual(sm.model, model))) {\n\t\t\tscopedModels.push({ model, thinkingLevel });\n\t\t}\n\t}\n\n\treturn scopedModels;\n}\n\nexport interface ResolveCliModelResult {\n\tmodel: Model<Api> | undefined;\n\tthinkingLevel?: ThinkingLevel;\n\twarning: string | undefined;\n\t/**\n\t * Error message suitable for CLI display.\n\t * When set, model will be undefined.\n\t */\n\terror: string | undefined;\n}\n\n/**\n * Resolve a single model from CLI flags.\n *\n * Supports:\n * - --provider <provider> --model <pattern>\n * - --model <provider>/<pattern>\n * - Fuzzy matching (same rules as model scoping: exact id, then partial id/name)\n *\n * Note: This does not apply the thinking level by itself, but it may *parse* and\n * return a thinking level from \"<pattern>:<thinking>\" so the caller can apply it.\n */\nexport function resolveCliModel(options: {\n\tcliProvider?: string;\n\tcliModel?: string;\n\tmodelRegistry: ModelRegistry;\n}): ResolveCliModelResult {\n\tconst { cliProvider, cliModel, modelRegistry } = options;\n\n\tif (!cliModel) {\n\t\treturn { model: undefined, warning: undefined, error: undefined };\n\t}\n\n\t// Important: use *all* models here, not just models with pre-configured auth.\n\t// This allows \"--api-key\" to be used for first-time setup.\n\tconst availableModels = modelRegistry.getAll();\n\tif (availableModels.length === 0) {\n\t\treturn {\n\t\t\tmodel: undefined,\n\t\t\twarning: undefined,\n\t\t\terror: \"No models available. Check your installation or add models to models.json.\",\n\t\t};\n\t}\n\n\t// Build canonical provider lookup (case-insensitive)\n\tconst providerMap = new Map<string, string>();\n\tfor (const m of availableModels) {\n\t\tproviderMap.set(m.provider.toLowerCase(), m.provider);\n\t}\n\n\tlet provider = cliProvider ? providerMap.get(cliProvider.toLowerCase()) : undefined;\n\tif (cliProvider && !provider) {\n\t\treturn {\n\t\t\tmodel: undefined,\n\t\t\twarning: undefined,\n\t\t\terror: `Unknown provider \"${cliProvider}\". Use --list-models to see available providers/models.`,\n\t\t};\n\t}\n\n\t// If no explicit --provider, try to interpret \"provider/model\" format first.\n\t// When the prefix before the first slash matches a known provider, prefer that\n\t// interpretation over matching models whose IDs literally contain slashes\n\t// (e.g. \"zai/glm-5\" should resolve to provider=zai, model=glm-5, not to a\n\t// vercel-ai-gateway model with id \"zai/glm-5\").\n\tlet pattern = cliModel;\n\tlet inferredProvider = false;\n\n\tif (!provider) {\n\t\tconst slashIndex = cliModel.indexOf(\"/\");\n\t\tif (slashIndex !== -1) {\n\t\t\tconst maybeProvider = cliModel.substring(0, slashIndex);\n\t\t\tconst canonical = providerMap.get(maybeProvider.toLowerCase());\n\t\t\tif (canonical) {\n\t\t\t\tprovider = canonical;\n\t\t\t\tpattern = cliModel.substring(slashIndex + 1);\n\t\t\t\tinferredProvider = true;\n\t\t\t}\n\t\t}\n\t}\n\n\t// If no provider was inferred from the slash, try exact matches without provider inference.\n\t// This handles models whose IDs naturally contain slashes (e.g. OpenRouter-style IDs).\n\tif (!provider) {\n\t\tconst lower = cliModel.toLowerCase();\n\t\tconst exact = availableModels.find(\n\t\t\t(m) => m.id.toLowerCase() === lower || `${m.provider}/${m.id}`.toLowerCase() === lower,\n\t\t);\n\t\tif (exact) {\n\t\t\treturn { model: exact, warning: undefined, thinkingLevel: undefined, error: undefined };\n\t\t}\n\t}\n\n\tif (cliProvider && provider) {\n\t\t// If both were provided, tolerate --model <provider>/<pattern> by stripping the provider prefix\n\t\tconst prefix = `${provider}/`;\n\t\tif (cliModel.toLowerCase().startsWith(prefix.toLowerCase())) {\n\t\t\tpattern = cliModel.substring(prefix.length);\n\t\t}\n\t}\n\n\tconst candidates = provider ? availableModels.filter((m) => m.provider === provider) : availableModels;\n\tconst { model, thinkingLevel, warning } = parseModelPattern(pattern, candidates, {\n\t\tallowInvalidThinkingLevelFallback: false,\n\t});\n\n\tif (model) {\n\t\treturn { model, thinkingLevel, warning, error: undefined };\n\t}\n\n\t// If we inferred a provider from the slash but found no match within that provider,\n\t// fall back to matching the full input as a raw model id across all models.\n\t// This handles OpenRouter-style IDs like \"openai/gpt-4o:extended\" where \"openai\"\n\t// looks like a provider but the full string is actually a model id on openrouter.\n\tif (inferredProvider) {\n\t\tconst lower = cliModel.toLowerCase();\n\t\tconst exact = availableModels.find(\n\t\t\t(m) => m.id.toLowerCase() === lower || `${m.provider}/${m.id}`.toLowerCase() === lower,\n\t\t);\n\t\tif (exact) {\n\t\t\treturn { model: exact, warning: undefined, thinkingLevel: undefined, error: undefined };\n\t\t}\n\t\t// Also try parseModelPattern on the full input against all models\n\t\tconst fallback = parseModelPattern(cliModel, availableModels, {\n\t\t\tallowInvalidThinkingLevelFallback: false,\n\t\t});\n\t\tif (fallback.model) {\n\t\t\treturn {\n\t\t\t\tmodel: fallback.model,\n\t\t\t\tthinkingLevel: fallback.thinkingLevel,\n\t\t\t\twarning: fallback.warning,\n\t\t\t\terror: undefined,\n\t\t\t};\n\t\t}\n\t}\n\n\tif (provider) {\n\t\tconst fallbackModel = buildFallbackModel(provider, pattern, availableModels);\n\t\tif (fallbackModel) {\n\t\t\tconst fallbackWarning = warning\n\t\t\t\t? `${warning} Model \"${pattern}\" not found for provider \"${provider}\". Using custom model id.`\n\t\t\t\t: `Model \"${pattern}\" not found for provider \"${provider}\". Using custom model id.`;\n\t\t\treturn { model: fallbackModel, thinkingLevel: undefined, warning: fallbackWarning, error: undefined };\n\t\t}\n\t}\n\n\tconst display = provider ? `${provider}/${pattern}` : cliModel;\n\treturn {\n\t\tmodel: undefined,\n\t\tthinkingLevel: undefined,\n\t\twarning,\n\t\terror: `Model \"${display}\" not found. Use --list-models to see available models.`,\n\t};\n}\n\nexport interface InitialModelResult {\n\tmodel: Model<Api> | undefined;\n\tthinkingLevel: ThinkingLevel;\n\tfallbackMessage: string | undefined;\n}\n\n/**\n * Find the initial model to use based on priority:\n * 1. CLI args (provider + model)\n * 2. First model from scoped models (if not continuing/resuming)\n * 3. Restored from session (if continuing/resuming)\n * 4. Saved default from settings\n * 5. First available model with valid API key\n */\nexport async function findInitialModel(options: {\n\tcliProvider?: string;\n\tcliModel?: string;\n\tscopedModels: ScopedModel[];\n\tisContinuing: boolean;\n\tdefaultProvider?: string;\n\tdefaultModelId?: string;\n\tdefaultThinkingLevel?: ThinkingLevel;\n\tmodelRegistry: ModelRegistry;\n}): Promise<InitialModelResult> {\n\tconst {\n\t\tcliProvider,\n\t\tcliModel,\n\t\tscopedModels,\n\t\tisContinuing,\n\t\tdefaultProvider,\n\t\tdefaultModelId,\n\t\tdefaultThinkingLevel,\n\t\tmodelRegistry,\n\t} = options;\n\n\tlet model: Model<Api> | undefined;\n\tlet thinkingLevel: ThinkingLevel = DEFAULT_THINKING_LEVEL;\n\n\t// 1. CLI args take priority\n\tif (cliProvider && cliModel) {\n\t\tconst resolved = resolveCliModel({\n\t\t\tcliProvider,\n\t\t\tcliModel,\n\t\t\tmodelRegistry,\n\t\t});\n\t\tif (resolved.error) {\n\t\t\tconsole.error(chalk.red(resolved.error));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tif (resolved.model) {\n\t\t\treturn { model: resolved.model, thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n\t\t}\n\t}\n\n\t// 2. Use first model from scoped models (skip if continuing/resuming)\n\tif (scopedModels.length > 0 && !isContinuing) {\n\t\treturn {\n\t\t\tmodel: scopedModels[0].model,\n\t\t\tthinkingLevel: scopedModels[0].thinkingLevel ?? defaultThinkingLevel ?? DEFAULT_THINKING_LEVEL,\n\t\t\tfallbackMessage: undefined,\n\t\t};\n\t}\n\n\t// 3. Try saved default from settings\n\tif (defaultProvider && defaultModelId) {\n\t\tconst found = modelRegistry.find(defaultProvider, defaultModelId);\n\t\tif (found) {\n\t\t\tmodel = found;\n\t\t\tif (defaultThinkingLevel) {\n\t\t\t\tthinkingLevel = defaultThinkingLevel;\n\t\t\t}\n\t\t\treturn { model, thinkingLevel, fallbackMessage: undefined };\n\t\t}\n\t}\n\n\t// 4. Try first available model with valid API key\n\tconst availableModels = await modelRegistry.getAvailable();\n\n\tif (availableModels.length > 0) {\n\t\t// Try to find a default model from known providers\n\t\tfor (const provider of Object.keys(defaultModelPerProvider) as KnownProvider[]) {\n\t\t\tconst defaultId = defaultModelPerProvider[provider];\n\t\t\tconst match = availableModels.find((m) => m.provider === provider && m.id === defaultId);\n\t\t\tif (match) {\n\t\t\t\treturn { model: match, thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n\t\t\t}\n\t\t}\n\n\t\t// If no default found, use first available\n\t\treturn { model: availableModels[0], thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n\t}\n\n\t// 5. No model found\n\treturn { model: undefined, thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n}\n\n/**\n * Restore model from session, with fallback to available models\n */\nexport async function restoreModelFromSession(\n\tsavedProvider: string,\n\tsavedModelId: string,\n\tcurrentModel: Model<Api> | undefined,\n\tshouldPrintMessages: boolean,\n\tmodelRegistry: ModelRegistry,\n): Promise<{ model: Model<Api> | undefined; fallbackMessage: string | undefined }> {\n\tconst restoredModel = modelRegistry.find(savedProvider, savedModelId);\n\n\t// Check if restored model exists and still has auth configured\n\tconst hasConfiguredAuth = restoredModel ? modelRegistry.hasConfiguredAuth(restoredModel) : false;\n\n\tif (restoredModel && hasConfiguredAuth) {\n\t\tif (shouldPrintMessages) {\n\t\t\tconsole.log(chalk.dim(`Restored model: ${savedProvider}/${savedModelId}`));\n\t\t}\n\t\treturn { model: restoredModel, fallbackMessage: undefined };\n\t}\n\n\t// Model not found or no API key - fall back\n\tconst reason = !restoredModel ? \"model no longer exists\" : \"no auth configured\";\n\n\tif (shouldPrintMessages) {\n\t\tconsole.error(chalk.yellow(`Warning: Could not restore model ${savedProvider}/${savedModelId} (${reason}).`));\n\t}\n\n\t// If we already have a model, use it as fallback\n\tif (currentModel) {\n\t\tif (shouldPrintMessages) {\n\t\t\tconsole.log(chalk.dim(`Falling back to: ${currentModel.provider}/${currentModel.id}`));\n\t\t}\n\t\treturn {\n\t\t\tmodel: currentModel,\n\t\t\tfallbackMessage: `Could not restore model ${savedProvider}/${savedModelId} (${reason}). Using ${currentModel.provider}/${currentModel.id}.`,\n\t\t};\n\t}\n\n\t// Try to find any available model\n\tconst availableModels = await modelRegistry.getAvailable();\n\n\tif (availableModels.length > 0) {\n\t\t// Try to find a default model from known providers\n\t\tlet fallbackModel: Model<Api> | undefined;\n\t\tfor (const provider of Object.keys(defaultModelPerProvider) as KnownProvider[]) {\n\t\t\tconst defaultId = defaultModelPerProvider[provider];\n\t\t\tconst match = availableModels.find((m) => m.provider === provider && m.id === defaultId);\n\t\t\tif (match) {\n\t\t\t\tfallbackModel = match;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// If no default found, use first available\n\t\tif (!fallbackModel) {\n\t\t\tfallbackModel = availableModels[0];\n\t\t}\n\n\t\tif (shouldPrintMessages) {\n\t\t\tconsole.log(chalk.dim(`Falling back to: ${fallbackModel.provider}/${fallbackModel.id}`));\n\t\t}\n\n\t\treturn {\n\t\t\tmodel: fallbackModel,\n\t\t\tfallbackMessage: `Could not restore model ${savedProvider}/${savedModelId} (${reason}). Using ${fallbackModel.provider}/${fallbackModel.id}.`,\n\t\t};\n\t}\n\n\t// No models available\n\treturn { model: undefined, fallbackMessage: undefined };\n}\n"]}
1
+ {"version":3,"file":"model-resolver.js","sourceRoot":"","sources":["../../src/core/model-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Model resolution, scoping, and initial selection\n */\n\nimport chalk from \"chalk\";\nimport { minimatch } from \"minimatch\";\nimport type { ThinkingLevel } from \"omk-agent-core\";\nimport { type Api, type KnownProvider, type Model, modelsAreEqual } from \"omk-ai\";\nimport { isValidThinkingLevel } from \"../cli/args.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport type { ModelRegistry } from \"./model-registry.ts\";\n\n/** Default model IDs for each known provider */\nexport const defaultModelPerProvider: Record<KnownProvider, string> = {\n\t\"amazon-bedrock\": \"us.anthropic.claude-opus-4-6-v1\",\n\t\"ant-ling\": \"Ring-2.6-1T\",\n\tanthropic: \"claude-opus-4-8\",\n\topenai: \"gpt-5.4\",\n\t\"azure-openai-responses\": \"gpt-5.4\",\n\t\"openai-codex\": \"gpt-5.5\",\n\tnvidia: \"nvidia/nemotron-3-super-120b-a12b\",\n\tdeepseek: \"deepseek-v4-pro\",\n\tgoogle: \"gemini-3.1-pro-preview\",\n\t\"google-vertex\": \"gemini-3.1-pro-preview\",\n\t\"github-copilot\": \"gpt-5.4\",\n\topenrouter: \"moonshotai/kimi-k2.6\",\n\t\"vercel-ai-gateway\": \"zai/glm-5.1\",\n\txai: \"grok-4.20-0309-reasoning\",\n\tgroq: \"openai/gpt-oss-120b\",\n\tcerebras: \"zai-glm-4.7\",\n\tzai: \"glm-5.1\",\n\t\"zai-coding-cn\": \"glm-5.1\",\n\tmistral: \"devstral-medium-latest\",\n\tminimax: \"MiniMax-M2.7\",\n\t\"minimax-cn\": \"MiniMax-M2.7\",\n\tmoonshotai: \"kimi-k2.6\",\n\t\"moonshotai-cn\": \"kimi-k2.6\",\n\thuggingface: \"moonshotai/Kimi-K2.6\",\n\tfireworks: \"accounts/fireworks/models/kimi-k2p6\",\n\ttogether: \"moonshotai/Kimi-K2.6\",\n\topencode: \"kimi-k2.6\",\n\t\"opencode-go\": \"kimi-k2.6\",\n\t\"kimi-coding\": \"k2p7\",\n\t\"cloudflare-workers-ai\": \"@cf/moonshotai/kimi-k2.6\",\n\t\"cloudflare-ai-gateway\": \"workers-ai/@cf/moonshotai/kimi-k2.6\",\n\txiaomi: \"mimo-v2.5-pro\",\n\t\"xiaomi-token-plan-cn\": \"mimo-v2.5-pro\",\n\t\"xiaomi-token-plan-ams\": \"mimo-v2.5-pro\",\n\t\"xiaomi-token-plan-sgp\": \"mimo-v2.5-pro\",\n\tzyloo: \"claude-opus-4-7\",\n};\n\nexport interface ScopedModel {\n\tmodel: Model<Api>;\n\t/** Thinking level if explicitly specified in pattern (e.g., \"model:high\"), undefined otherwise */\n\tthinkingLevel?: ThinkingLevel;\n}\n\n/**\n * Helper to check if a model ID looks like an alias (no date suffix)\n * Dates are typically in format: -20241022 or -20250929\n */\nfunction isAlias(id: string): boolean {\n\t// Check if ID ends with -latest\n\tif (id.endsWith(\"-latest\")) return true;\n\n\t// Check if ID ends with a date pattern (-YYYYMMDD)\n\tconst datePattern = /-\\d{8}$/;\n\treturn !datePattern.test(id);\n}\n\n/**\n * Find an exact model reference match.\n * Supports either a bare model id or a canonical provider/modelId reference.\n * When matching by bare id, ambiguous matches across providers are rejected.\n */\nexport function findExactModelReferenceMatch(\n\tmodelReference: string,\n\tavailableModels: Model<Api>[],\n): Model<Api> | undefined {\n\tconst trimmedReference = modelReference.trim();\n\tif (!trimmedReference) {\n\t\treturn undefined;\n\t}\n\n\tconst normalizedReference = trimmedReference.toLowerCase();\n\n\tconst canonicalMatches = availableModels.filter(\n\t\t(model) => `${model.provider}/${model.id}`.toLowerCase() === normalizedReference,\n\t);\n\tif (canonicalMatches.length === 1) {\n\t\treturn canonicalMatches[0];\n\t}\n\tif (canonicalMatches.length > 1) {\n\t\treturn undefined;\n\t}\n\n\tconst slashIndex = trimmedReference.indexOf(\"/\");\n\tif (slashIndex !== -1) {\n\t\tconst provider = trimmedReference.substring(0, slashIndex).trim();\n\t\tconst modelId = trimmedReference.substring(slashIndex + 1).trim();\n\t\tif (provider && modelId) {\n\t\t\tconst providerMatches = availableModels.filter(\n\t\t\t\t(model) =>\n\t\t\t\t\tmodel.provider.toLowerCase() === provider.toLowerCase() &&\n\t\t\t\t\tmodel.id.toLowerCase() === modelId.toLowerCase(),\n\t\t\t);\n\t\t\tif (providerMatches.length === 1) {\n\t\t\t\treturn providerMatches[0];\n\t\t\t}\n\t\t\tif (providerMatches.length > 1) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst idMatches = availableModels.filter((model) => model.id.toLowerCase() === normalizedReference);\n\treturn idMatches.length === 1 ? idMatches[0] : undefined;\n}\n\n/**\n * Try to match a pattern to a model from the available models list.\n * Returns the matched model or undefined if no match found.\n */\nfunction tryMatchModel(modelPattern: string, availableModels: Model<Api>[]): Model<Api> | undefined {\n\tconst exactMatch = findExactModelReferenceMatch(modelPattern, availableModels);\n\tif (exactMatch) {\n\t\treturn exactMatch;\n\t}\n\n\t// No exact match - fall back to partial matching\n\tconst matches = availableModels.filter(\n\t\t(m) =>\n\t\t\tm.id.toLowerCase().includes(modelPattern.toLowerCase()) ||\n\t\t\tm.name?.toLowerCase().includes(modelPattern.toLowerCase()),\n\t);\n\n\tif (matches.length === 0) {\n\t\treturn undefined;\n\t}\n\n\t// Separate into aliases and dated versions\n\tconst aliases = matches.filter((m) => isAlias(m.id));\n\tconst datedVersions = matches.filter((m) => !isAlias(m.id));\n\n\tif (aliases.length > 0) {\n\t\t// Prefer alias - if multiple aliases, pick the one that sorts highest\n\t\taliases.sort((a, b) => b.id.localeCompare(a.id));\n\t\treturn aliases[0];\n\t} else {\n\t\t// No alias found, pick latest dated version\n\t\tdatedVersions.sort((a, b) => b.id.localeCompare(a.id));\n\t\treturn datedVersions[0];\n\t}\n}\n\nexport interface ParsedModelResult {\n\tmodel: Model<Api> | undefined;\n\t/** Thinking level if explicitly specified in pattern, undefined otherwise */\n\tthinkingLevel?: ThinkingLevel;\n\twarning: string | undefined;\n}\n\nfunction buildFallbackModel(provider: string, modelId: string, availableModels: Model<Api>[]): Model<Api> | undefined {\n\tconst providerModels = availableModels.filter((m) => m.provider === provider);\n\tif (providerModels.length === 0) return undefined;\n\n\tconst defaultId = defaultModelPerProvider[provider as KnownProvider];\n\tconst baseModel = defaultId\n\t\t? (providerModels.find((m) => m.id === defaultId) ?? providerModels[0])\n\t\t: providerModels[0];\n\n\treturn {\n\t\t...baseModel,\n\t\tid: modelId,\n\t\tname: modelId,\n\t};\n}\n\n/**\n * Parse a pattern to extract model and thinking level.\n * Handles models with colons in their IDs (e.g., OpenRouter's :exacto suffix).\n *\n * Algorithm:\n * 1. Try to match full pattern as a model\n * 2. If found, return it with \"off\" thinking level\n * 3. If not found and has colons, split on last colon:\n * - If suffix is valid thinking level, use it and recurse on prefix\n * - If suffix is invalid, warn and recurse on prefix with \"off\"\n *\n * @internal Exported for testing\n */\nexport function parseModelPattern(\n\tpattern: string,\n\tavailableModels: Model<Api>[],\n\toptions?: { allowInvalidThinkingLevelFallback?: boolean },\n): ParsedModelResult {\n\t// Try exact match first\n\tconst exactMatch = tryMatchModel(pattern, availableModels);\n\tif (exactMatch) {\n\t\treturn { model: exactMatch, thinkingLevel: undefined, warning: undefined };\n\t}\n\n\t// No match - try splitting on last colon if present\n\tconst lastColonIndex = pattern.lastIndexOf(\":\");\n\tif (lastColonIndex === -1) {\n\t\t// No colons, pattern simply doesn't match any model\n\t\treturn { model: undefined, thinkingLevel: undefined, warning: undefined };\n\t}\n\n\tconst prefix = pattern.substring(0, lastColonIndex);\n\tconst suffix = pattern.substring(lastColonIndex + 1);\n\n\tif (isValidThinkingLevel(suffix)) {\n\t\t// Valid thinking level - recurse on prefix and use this level\n\t\tconst result = parseModelPattern(prefix, availableModels, options);\n\t\tif (result.model) {\n\t\t\t// Only use this thinking level if no warning from inner recursion\n\t\t\treturn {\n\t\t\t\tmodel: result.model,\n\t\t\t\tthinkingLevel: result.warning ? undefined : suffix,\n\t\t\t\twarning: result.warning,\n\t\t\t};\n\t\t}\n\t\treturn result;\n\t} else {\n\t\t// Invalid suffix\n\t\tconst allowFallback = options?.allowInvalidThinkingLevelFallback ?? true;\n\t\tif (!allowFallback) {\n\t\t\t// In strict mode (CLI --model parsing), treat it as part of the model id and fail.\n\t\t\t// This avoids accidentally resolving to a different model.\n\t\t\treturn { model: undefined, thinkingLevel: undefined, warning: undefined };\n\t\t}\n\n\t\t// Scope mode: recurse on prefix and warn\n\t\tconst result = parseModelPattern(prefix, availableModels, options);\n\t\tif (result.model) {\n\t\t\treturn {\n\t\t\t\tmodel: result.model,\n\t\t\t\tthinkingLevel: undefined,\n\t\t\t\twarning: `Invalid thinking level \"${suffix}\" in pattern \"${pattern}\". Using default instead.`,\n\t\t\t};\n\t\t}\n\t\treturn result;\n\t}\n}\n\n/**\n * Resolve model patterns to actual Model objects with optional thinking levels\n * Format: \"pattern:level\" where :level is optional\n * For each pattern, finds all matching models and picks the best version:\n * 1. Prefer alias (e.g., claude-sonnet-4-5) over dated versions (claude-sonnet-4-5-20250929)\n * 2. If no alias, pick the latest dated version\n *\n * Supports models with colons in their IDs (e.g., OpenRouter's model:exacto).\n * The algorithm tries to match the full pattern first, then progressively\n * strips colon-suffixes to find a match.\n */\nexport async function resolveModelScope(patterns: string[], modelRegistry: ModelRegistry): Promise<ScopedModel[]> {\n\tconst availableModels = await modelRegistry.getAvailable();\n\tconst scopedModels: ScopedModel[] = [];\n\n\tfor (const pattern of patterns) {\n\t\t// Check if pattern contains glob characters\n\t\tif (pattern.includes(\"*\") || pattern.includes(\"?\") || pattern.includes(\"[\")) {\n\t\t\t// Extract optional thinking level suffix (e.g., \"provider/*:high\")\n\t\t\tconst colonIdx = pattern.lastIndexOf(\":\");\n\t\t\tlet globPattern = pattern;\n\t\t\tlet thinkingLevel: ThinkingLevel | undefined;\n\n\t\t\tif (colonIdx !== -1) {\n\t\t\t\tconst suffix = pattern.substring(colonIdx + 1);\n\t\t\t\tif (isValidThinkingLevel(suffix)) {\n\t\t\t\t\tthinkingLevel = suffix;\n\t\t\t\t\tglobPattern = pattern.substring(0, colonIdx);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Match against \"provider/modelId\" format OR just model ID\n\t\t\t// This allows \"*sonnet*\" to match without requiring \"anthropic/*sonnet*\"\n\t\t\tconst matchingModels = availableModels.filter((m) => {\n\t\t\t\tconst fullId = `${m.provider}/${m.id}`;\n\t\t\t\treturn minimatch(fullId, globPattern, { nocase: true }) || minimatch(m.id, globPattern, { nocase: true });\n\t\t\t});\n\n\t\t\tif (matchingModels.length === 0) {\n\t\t\t\tconsole.warn(chalk.yellow(`Warning: No models match pattern \"${pattern}\"`));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tfor (const model of matchingModels) {\n\t\t\t\tif (!scopedModels.find((sm) => modelsAreEqual(sm.model, model))) {\n\t\t\t\t\tscopedModels.push({ model, thinkingLevel });\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst { model, thinkingLevel, warning } = parseModelPattern(pattern, availableModels);\n\n\t\tif (warning) {\n\t\t\tconsole.warn(chalk.yellow(`Warning: ${warning}`));\n\t\t}\n\n\t\tif (!model) {\n\t\t\tconsole.warn(chalk.yellow(`Warning: No models match pattern \"${pattern}\"`));\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Avoid duplicates\n\t\tif (!scopedModels.find((sm) => modelsAreEqual(sm.model, model))) {\n\t\t\tscopedModels.push({ model, thinkingLevel });\n\t\t}\n\t}\n\n\treturn scopedModels;\n}\n\nexport interface ResolveCliModelResult {\n\tmodel: Model<Api> | undefined;\n\tthinkingLevel?: ThinkingLevel;\n\twarning: string | undefined;\n\t/**\n\t * Error message suitable for CLI display.\n\t * When set, model will be undefined.\n\t */\n\terror: string | undefined;\n}\n\n/**\n * Resolve a single model from CLI flags.\n *\n * Supports:\n * - --provider <provider> --model <pattern>\n * - --model <provider>/<pattern>\n * - Fuzzy matching (same rules as model scoping: exact id, then partial id/name)\n *\n * Note: This does not apply the thinking level by itself, but it may *parse* and\n * return a thinking level from \"<pattern>:<thinking>\" so the caller can apply it.\n */\nexport function resolveCliModel(options: {\n\tcliProvider?: string;\n\tcliModel?: string;\n\tmodelRegistry: ModelRegistry;\n}): ResolveCliModelResult {\n\tconst { cliProvider, cliModel, modelRegistry } = options;\n\n\tif (!cliModel) {\n\t\treturn { model: undefined, warning: undefined, error: undefined };\n\t}\n\n\t// Important: use *all* models here, not just models with pre-configured auth.\n\t// This allows \"--api-key\" to be used for first-time setup.\n\tconst availableModels = modelRegistry.getAll();\n\tif (availableModels.length === 0) {\n\t\treturn {\n\t\t\tmodel: undefined,\n\t\t\twarning: undefined,\n\t\t\terror: \"No models available. Check your installation or add models to models.json.\",\n\t\t};\n\t}\n\n\t// Build canonical provider lookup (case-insensitive)\n\tconst providerMap = new Map<string, string>();\n\tfor (const m of availableModels) {\n\t\tproviderMap.set(m.provider.toLowerCase(), m.provider);\n\t}\n\n\tlet provider = cliProvider ? providerMap.get(cliProvider.toLowerCase()) : undefined;\n\tif (cliProvider && !provider) {\n\t\treturn {\n\t\t\tmodel: undefined,\n\t\t\twarning: undefined,\n\t\t\terror: `Unknown provider \"${cliProvider}\". Use --list-models to see available providers/models.`,\n\t\t};\n\t}\n\n\t// If no explicit --provider, try to interpret \"provider/model\" format first.\n\t// When the prefix before the first slash matches a known provider, prefer that\n\t// interpretation over matching models whose IDs literally contain slashes\n\t// (e.g. \"zai/glm-5\" should resolve to provider=zai, model=glm-5, not to a\n\t// vercel-ai-gateway model with id \"zai/glm-5\").\n\tlet pattern = cliModel;\n\tlet inferredProvider = false;\n\n\tif (!provider) {\n\t\tconst slashIndex = cliModel.indexOf(\"/\");\n\t\tif (slashIndex !== -1) {\n\t\t\tconst maybeProvider = cliModel.substring(0, slashIndex);\n\t\t\tconst canonical = providerMap.get(maybeProvider.toLowerCase());\n\t\t\tif (canonical) {\n\t\t\t\tprovider = canonical;\n\t\t\t\tpattern = cliModel.substring(slashIndex + 1);\n\t\t\t\tinferredProvider = true;\n\t\t\t}\n\t\t}\n\t}\n\n\t// If no provider was inferred from the slash, try exact matches without provider inference.\n\t// This handles models whose IDs naturally contain slashes (e.g. OpenRouter-style IDs).\n\tif (!provider) {\n\t\tconst lower = cliModel.toLowerCase();\n\t\tconst exact = availableModels.find(\n\t\t\t(m) => m.id.toLowerCase() === lower || `${m.provider}/${m.id}`.toLowerCase() === lower,\n\t\t);\n\t\tif (exact) {\n\t\t\treturn { model: exact, warning: undefined, thinkingLevel: undefined, error: undefined };\n\t\t}\n\t}\n\n\tif (cliProvider && provider) {\n\t\t// If both were provided, tolerate --model <provider>/<pattern> by stripping the provider prefix\n\t\tconst prefix = `${provider}/`;\n\t\tif (cliModel.toLowerCase().startsWith(prefix.toLowerCase())) {\n\t\t\tpattern = cliModel.substring(prefix.length);\n\t\t}\n\t}\n\n\tconst candidates = provider ? availableModels.filter((m) => m.provider === provider) : availableModels;\n\tconst { model, thinkingLevel, warning } = parseModelPattern(pattern, candidates, {\n\t\tallowInvalidThinkingLevelFallback: false,\n\t});\n\n\tif (model) {\n\t\treturn { model, thinkingLevel, warning, error: undefined };\n\t}\n\n\t// If we inferred a provider from the slash but found no match within that provider,\n\t// fall back to matching the full input as a raw model id across all models.\n\t// This handles OpenRouter-style IDs like \"openai/gpt-4o:extended\" where \"openai\"\n\t// looks like a provider but the full string is actually a model id on openrouter.\n\tif (inferredProvider) {\n\t\tconst lower = cliModel.toLowerCase();\n\t\tconst exact = availableModels.find(\n\t\t\t(m) => m.id.toLowerCase() === lower || `${m.provider}/${m.id}`.toLowerCase() === lower,\n\t\t);\n\t\tif (exact) {\n\t\t\treturn { model: exact, warning: undefined, thinkingLevel: undefined, error: undefined };\n\t\t}\n\t\t// Also try parseModelPattern on the full input against all models\n\t\tconst fallback = parseModelPattern(cliModel, availableModels, {\n\t\t\tallowInvalidThinkingLevelFallback: false,\n\t\t});\n\t\tif (fallback.model) {\n\t\t\treturn {\n\t\t\t\tmodel: fallback.model,\n\t\t\t\tthinkingLevel: fallback.thinkingLevel,\n\t\t\t\twarning: fallback.warning,\n\t\t\t\terror: undefined,\n\t\t\t};\n\t\t}\n\t}\n\n\tif (provider) {\n\t\tconst fallbackModel = buildFallbackModel(provider, pattern, availableModels);\n\t\tif (fallbackModel) {\n\t\t\tconst fallbackWarning = warning\n\t\t\t\t? `${warning} Model \"${pattern}\" not found for provider \"${provider}\". Using custom model id.`\n\t\t\t\t: `Model \"${pattern}\" not found for provider \"${provider}\". Using custom model id.`;\n\t\t\treturn { model: fallbackModel, thinkingLevel: undefined, warning: fallbackWarning, error: undefined };\n\t\t}\n\t}\n\n\tconst display = provider ? `${provider}/${pattern}` : cliModel;\n\treturn {\n\t\tmodel: undefined,\n\t\tthinkingLevel: undefined,\n\t\twarning,\n\t\terror: `Model \"${display}\" not found. Use --list-models to see available models.`,\n\t};\n}\n\nexport interface InitialModelResult {\n\tmodel: Model<Api> | undefined;\n\tthinkingLevel: ThinkingLevel;\n\tfallbackMessage: string | undefined;\n}\n\n/**\n * Find the initial model to use based on priority:\n * 1. CLI args (provider + model)\n * 2. First model from scoped models (if not continuing/resuming)\n * 3. Restored from session (if continuing/resuming)\n * 4. Saved default from settings\n * 5. First available model with valid API key\n */\nexport async function findInitialModel(options: {\n\tcliProvider?: string;\n\tcliModel?: string;\n\tscopedModels: ScopedModel[];\n\tisContinuing: boolean;\n\tdefaultProvider?: string;\n\tdefaultModelId?: string;\n\tdefaultThinkingLevel?: ThinkingLevel;\n\tmodelRegistry: ModelRegistry;\n}): Promise<InitialModelResult> {\n\tconst {\n\t\tcliProvider,\n\t\tcliModel,\n\t\tscopedModels,\n\t\tisContinuing,\n\t\tdefaultProvider,\n\t\tdefaultModelId,\n\t\tdefaultThinkingLevel,\n\t\tmodelRegistry,\n\t} = options;\n\n\tlet model: Model<Api> | undefined;\n\tlet thinkingLevel: ThinkingLevel = DEFAULT_THINKING_LEVEL;\n\n\t// 1. CLI args take priority\n\tif (cliProvider && cliModel) {\n\t\tconst resolved = resolveCliModel({\n\t\t\tcliProvider,\n\t\t\tcliModel,\n\t\t\tmodelRegistry,\n\t\t});\n\t\tif (resolved.error) {\n\t\t\tconsole.error(chalk.red(resolved.error));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tif (resolved.model) {\n\t\t\treturn { model: resolved.model, thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n\t\t}\n\t}\n\n\t// 2. Use first model from scoped models (skip if continuing/resuming)\n\tif (scopedModels.length > 0 && !isContinuing) {\n\t\treturn {\n\t\t\tmodel: scopedModels[0].model,\n\t\t\tthinkingLevel: scopedModels[0].thinkingLevel ?? defaultThinkingLevel ?? DEFAULT_THINKING_LEVEL,\n\t\t\tfallbackMessage: undefined,\n\t\t};\n\t}\n\n\t// 3. Try saved default from settings\n\tif (defaultProvider && defaultModelId) {\n\t\tconst found = modelRegistry.find(defaultProvider, defaultModelId);\n\t\tif (found) {\n\t\t\tmodel = found;\n\t\t\tif (defaultThinkingLevel) {\n\t\t\t\tthinkingLevel = defaultThinkingLevel;\n\t\t\t}\n\t\t\treturn { model, thinkingLevel, fallbackMessage: undefined };\n\t\t}\n\t}\n\n\t// 4. Try first available model with valid API key\n\tconst availableModels = await modelRegistry.getAvailable();\n\n\tif (availableModels.length > 0) {\n\t\t// Try to find a default model from known providers\n\t\tfor (const provider of Object.keys(defaultModelPerProvider) as KnownProvider[]) {\n\t\t\tconst defaultId = defaultModelPerProvider[provider];\n\t\t\tconst match = availableModels.find((m) => m.provider === provider && m.id === defaultId);\n\t\t\tif (match) {\n\t\t\t\treturn { model: match, thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n\t\t\t}\n\t\t}\n\n\t\t// If no default found, use first available\n\t\treturn { model: availableModels[0], thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n\t}\n\n\t// 5. No model found\n\treturn { model: undefined, thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n}\n\n/**\n * Restore model from session, with fallback to available models\n */\nexport async function restoreModelFromSession(\n\tsavedProvider: string,\n\tsavedModelId: string,\n\tcurrentModel: Model<Api> | undefined,\n\tshouldPrintMessages: boolean,\n\tmodelRegistry: ModelRegistry,\n): Promise<{ model: Model<Api> | undefined; fallbackMessage: string | undefined }> {\n\tconst restoredModel = modelRegistry.find(savedProvider, savedModelId);\n\n\t// Check if restored model exists and still has auth configured\n\tconst hasConfiguredAuth = restoredModel ? modelRegistry.hasConfiguredAuth(restoredModel) : false;\n\n\tif (restoredModel && hasConfiguredAuth) {\n\t\tif (shouldPrintMessages) {\n\t\t\tconsole.log(chalk.dim(`Restored model: ${savedProvider}/${savedModelId}`));\n\t\t}\n\t\treturn { model: restoredModel, fallbackMessage: undefined };\n\t}\n\n\t// Model not found or no API key - fall back\n\tconst reason = !restoredModel ? \"model no longer exists\" : \"no auth configured\";\n\n\tif (shouldPrintMessages) {\n\t\tconsole.error(chalk.yellow(`Warning: Could not restore model ${savedProvider}/${savedModelId} (${reason}).`));\n\t}\n\n\t// If we already have a model, use it as fallback\n\tif (currentModel) {\n\t\tif (shouldPrintMessages) {\n\t\t\tconsole.log(chalk.dim(`Falling back to: ${currentModel.provider}/${currentModel.id}`));\n\t\t}\n\t\treturn {\n\t\t\tmodel: currentModel,\n\t\t\tfallbackMessage: `Could not restore model ${savedProvider}/${savedModelId} (${reason}). Using ${currentModel.provider}/${currentModel.id}.`,\n\t\t};\n\t}\n\n\t// Try to find any available model\n\tconst availableModels = await modelRegistry.getAvailable();\n\n\tif (availableModels.length > 0) {\n\t\t// Try to find a default model from known providers\n\t\tlet fallbackModel: Model<Api> | undefined;\n\t\tfor (const provider of Object.keys(defaultModelPerProvider) as KnownProvider[]) {\n\t\t\tconst defaultId = defaultModelPerProvider[provider];\n\t\t\tconst match = availableModels.find((m) => m.provider === provider && m.id === defaultId);\n\t\t\tif (match) {\n\t\t\t\tfallbackModel = match;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// If no default found, use first available\n\t\tif (!fallbackModel) {\n\t\t\tfallbackModel = availableModels[0];\n\t\t}\n\n\t\tif (shouldPrintMessages) {\n\t\t\tconsole.log(chalk.dim(`Falling back to: ${fallbackModel.provider}/${fallbackModel.id}`));\n\t\t}\n\n\t\treturn {\n\t\t\tmodel: fallbackModel,\n\t\t\tfallbackMessage: `Could not restore model ${savedProvider}/${savedModelId} (${reason}). Using ${fallbackModel.provider}/${fallbackModel.id}.`,\n\t\t};\n\t}\n\n\t// No models available\n\treturn { model: undefined, fallbackMessage: undefined };\n}\n"]}
@@ -28,6 +28,7 @@ export interface PiPackageIntakeSummary {
28
28
  readonly acceptedNative: number;
29
29
  readonly acceptedReference: number;
30
30
  readonly acceptedMeasurement: number;
31
+ readonly acceptedAdvisory: number;
31
32
  readonly deferred: number;
32
33
  readonly reject: number;
33
34
  readonly hardForkBlocked: number;
@@ -1 +1 @@
1
- {"version":3,"file":"pi-package-intake.d.ts","sourceRoot":"","sources":["../../src/core/pi-package-intake.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,iBAAiB,EAAoB,MAAM,0BAA0B,CAAC;AACnG,OAAO,EAGN,KAAK,6BAA6B,EAClC,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAC3B,MAAM,mCAAmC,CAAC;AAE3C,YAAY,EACX,6BAA6B,EAC7B,aAAa,EACb,sBAAsB,EACtB,iBAAiB,GACjB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,6BAA6B,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AAEjH;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,EAAE,SAAS,sBAAsB,EAG3E,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,sBAAsB,EAAE,CAAC;IACxD,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,6BAA6B,EAAE,CAAC;IAC5D,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACnD;AAED,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,UAAU,EAAE,sBAAsB,CAAC;IAC5C,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,yBAAyB,EAAE,OAAO,CAAC;CAC5C;AAED,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,OAAO,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACnD,QAAQ,CAAC,OAAO,EAAE,sBAAsB,CAAC;CACzC;AAuBD,wBAAgB,uBAAuB,CAAC,KAAK,GAAE,oBAAyB,GAAG,qBAAqB,CAO/F;AAED,wBAAgB,0BAA0B,CACzC,UAAU,EAAE,sBAAsB,EAClC,WAAW,CAAC,EAAE,6BAA6B,EAC3C,GAAG,CAAC,EAAE,IAAI,GACR,qBAAqB,CAkBvB;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,SAAS,qBAAqB,EAAE,GAAG,sBAAsB,CAgD1G","sourcesContent":["import { type Adoption, type ProcurementReview, procureCandidate } from \"./package-procurement.ts\";\nimport {\n\tP0_PI_PACKAGE_PORT_CANDIDATES,\n\tP1_PI_PACKAGE_PORT_CANDIDATES,\n\ttype PiPackageCandidateReviewInput,\n\ttype PiPackageLane,\n\ttype PiPackagePortCandidate,\n} from \"./pi-package-intake-candidates.ts\";\n\nexport type {\n\tPiPackageCandidateReviewInput,\n\tPiPackageLane,\n\tPiPackagePortCandidate,\n\tPiPackagePortMode,\n} from \"./pi-package-intake-candidates.ts\";\nexport { P0_PI_PACKAGE_PORT_CANDIDATES, P1_PI_PACKAGE_PORT_CANDIDATES } from \"./pi-package-intake-candidates.ts\";\n\n/**\n * Combined default candidate set (P0 + P1). P1 was drawn from a full crawl of\n * pi.dev/packages (4653 unique packages) and is intentionally more conservative\n * (reference/measurement-gated/report-only only, never native) since no source-level\n * review has been run on any P1 candidate yet.\n */\nexport const ALL_PI_PACKAGE_PORT_CANDIDATES: readonly PiPackagePortCandidate[] = [\n\t...P0_PI_PACKAGE_PORT_CANDIDATES,\n\t...P1_PI_PACKAGE_PORT_CANDIDATES,\n];\n\nexport interface PiPackageIntakeInput {\n\treadonly candidates?: readonly PiPackagePortCandidate[];\n\treadonly reviews?: readonly PiPackageCandidateReviewInput[];\n\treadonly now?: Date;\n}\n\nexport interface PiPackageLaneSummary {\n\treadonly lane: PiPackageLane;\n\treadonly label: string;\n\treadonly total: number;\n\treadonly accepted: number;\n\treadonly deferred: number;\n\treadonly reject: number;\n\treadonly hardForkBlocked: number;\n}\n\nexport interface PiPackageIntakeSummary {\n\treadonly total: number;\n\treadonly acceptedNative: number;\n\treadonly acceptedReference: number;\n\treadonly acceptedMeasurement: number;\n\treadonly deferred: number;\n\treadonly reject: number;\n\treadonly hardForkBlocked: number;\n\treadonly topLanes: readonly PiPackageLaneSummary[];\n}\n\nexport interface PiPackageIntakeResult {\n\treadonly definition: PiPackagePortCandidate;\n\treadonly review: ProcurementReview;\n\treadonly hardForkBlocked: boolean;\n\treadonly hardForkReasons: readonly string[];\n\treadonly directPermanentPiAdoption: boolean;\n}\n\nexport interface PiPackageIntakeReport {\n\treadonly results: readonly PiPackageIntakeResult[];\n\treadonly summary: PiPackageIntakeSummary;\n}\n\nconst HARD_FORK_FINDING_KINDS = new Set([\n\t\"legacy-home-path\",\n\t\"legacy-state-dir\",\n\t\"legacy-project-path\",\n\t\"legacy-package-path\",\n\t\"legacy-cli-invocation\",\n\t\"legacy-import\",\n]);\n\nconst DIRECT_PI_ADOPTION_BLOCKED = new Set<Adoption>([\"permanent-package\"]);\n\ninterface MutablePiPackageLaneSummary {\n\tlane: PiPackageLane;\n\tlabel: string;\n\ttotal: number;\n\taccepted: number;\n\tdeferred: number;\n\treject: number;\n\thardForkBlocked: number;\n}\n\nexport function evaluatePiPackageIntake(input: PiPackageIntakeInput = {}): PiPackageIntakeReport {\n\tconst candidates = input.candidates ?? ALL_PI_PACKAGE_PORT_CANDIDATES;\n\tconst reviewInputs = new Map((input.reviews ?? []).map((review) => [review.candidateId, review]));\n\tconst results = candidates.map((definition) =>\n\t\tevaluatePiPackageCandidate(definition, reviewInputs.get(definition.id), input.now),\n\t);\n\treturn { results, summary: summarizePiPackageIntake(results) };\n}\n\nexport function evaluatePiPackageCandidate(\n\tdefinition: PiPackagePortCandidate,\n\treviewInput?: PiPackageCandidateReviewInput,\n\tnow?: Date,\n): PiPackageIntakeResult {\n\tconst review = procureCandidate({\n\t\tcandidate: definition.candidate,\n\t\tdeclaredLicense: reviewInput?.declaredLicense ?? \"MIT\",\n\t\tpackageJsonScripts: reviewInput?.packageJsonScripts,\n\t\treviewedScriptAllowlist: reviewInput?.reviewedScriptAllowlist,\n\t\tsources: reviewInput?.sources,\n\t\ttransitiveLicenses: reviewInput?.transitiveLicenses,\n\t\tnow,\n\t});\n\tconst hardForkReasons = hardForkBlockReasons(review);\n\treturn {\n\t\tdefinition,\n\t\treview,\n\t\thardForkBlocked: hardForkReasons.length > 0,\n\t\thardForkReasons,\n\t\tdirectPermanentPiAdoption: isDirectPermanentPiAdoption(definition, review),\n\t};\n}\n\nexport function summarizePiPackageIntake(results: readonly PiPackageIntakeResult[]): PiPackageIntakeSummary {\n\tconst laneSummaries = new Map<PiPackageLane, MutablePiPackageLaneSummary>();\n\tlet acceptedNative = 0;\n\tlet acceptedReference = 0;\n\tlet acceptedMeasurement = 0;\n\tlet deferred = 0;\n\tlet reject = 0;\n\tlet hardForkBlocked = 0;\n\n\tfor (const result of results) {\n\t\tconst lane = laneSummaries.get(result.definition.lane) ?? laneSummaryFor(result);\n\t\tlaneSummaries.set(result.definition.lane, lane);\n\t\tlane.total += 1;\n\n\t\tif (result.hardForkBlocked) {\n\t\t\thardForkBlocked += 1;\n\t\t\tlane.hardForkBlocked += 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (result.review.adoption === \"native\") {\n\t\t\tacceptedNative += 1;\n\t\t\tlane.accepted += 1;\n\t\t} else if (result.review.adoption === \"reference-only\") {\n\t\t\tacceptedReference += 1;\n\t\t\tlane.accepted += 1;\n\t\t} else if (result.review.adoption === \"measurement-gated\") {\n\t\t\tacceptedMeasurement += 1;\n\t\t\tlane.accepted += 1;\n\t\t} else if (result.review.adoption === \"deferred\") {\n\t\t\tdeferred += 1;\n\t\t\tlane.deferred += 1;\n\t\t} else if (result.review.adoption === \"reject\") {\n\t\t\treject += 1;\n\t\t\tlane.reject += 1;\n\t\t}\n\t}\n\n\treturn {\n\t\ttotal: results.length,\n\t\tacceptedNative,\n\t\tacceptedReference,\n\t\tacceptedMeasurement,\n\t\tdeferred,\n\t\treject,\n\t\thardForkBlocked,\n\t\ttopLanes: [...laneSummaries.values()].sort(compareLaneSummaries).map((lane) => ({ ...lane })),\n\t};\n}\n\nfunction hardForkBlockReasons(review: ProcurementReview): string[] {\n\tconst reasons = review.compatibilityFindings\n\t\t.filter((finding) => finding.severity === \"block\" && HARD_FORK_FINDING_KINDS.has(finding.kind))\n\t\t.map((finding) => `${finding.kind}:${finding.path ?? \"source\"}:${finding.line}`);\n\tif (review.lifecycleVerdict === \"reject\") {\n\t\treasons.push(...review.declaredLifecycleScripts.map((script) => `lifecycle-script:${script}`));\n\t}\n\treturn [...new Set(reasons)];\n}\n\nfunction isDirectPermanentPiAdoption(definition: PiPackagePortCandidate, review: ProcurementReview): boolean {\n\treturn definition.candidate.intendedUse === \"permanent-adopt\" || DIRECT_PI_ADOPTION_BLOCKED.has(review.adoption);\n}\n\nfunction laneSummaryFor(result: PiPackageIntakeResult): MutablePiPackageLaneSummary {\n\treturn {\n\t\tlane: result.definition.lane,\n\t\tlabel: result.definition.laneLabel,\n\t\ttotal: 0,\n\t\taccepted: 0,\n\t\tdeferred: 0,\n\t\treject: 0,\n\t\thardForkBlocked: 0,\n\t};\n}\n\nfunction compareLaneSummaries(a: PiPackageLaneSummary, b: PiPackageLaneSummary): number {\n\tconst acceptedDelta = b.accepted - a.accepted;\n\tif (acceptedDelta !== 0) return acceptedDelta;\n\tconst totalDelta = b.total - a.total;\n\tif (totalDelta !== 0) return totalDelta;\n\treturn laneRank(a.lane) - laneRank(b.lane);\n}\n\nfunction laneRank(lane: PiPackageLane): number {\n\treturn ALL_PI_PACKAGE_PORT_CANDIDATES.findIndex((candidate) => candidate.lane === lane);\n}\n"]}
1
+ {"version":3,"file":"pi-package-intake.d.ts","sourceRoot":"","sources":["../../src/core/pi-package-intake.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,iBAAiB,EAAoB,MAAM,0BAA0B,CAAC;AACnG,OAAO,EAGN,KAAK,6BAA6B,EAClC,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAC3B,MAAM,mCAAmC,CAAC;AAE3C,YAAY,EACX,6BAA6B,EAC7B,aAAa,EACb,sBAAsB,EACtB,iBAAiB,GACjB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,6BAA6B,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AAEjH;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,EAAE,SAAS,sBAAsB,EAG3E,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,sBAAsB,EAAE,CAAC;IACxD,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,6BAA6B,EAAE,CAAC;IAC5D,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACnD;AAED,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,UAAU,EAAE,sBAAsB,CAAC;IAC5C,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,yBAAyB,EAAE,OAAO,CAAC;CAC5C;AAED,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,OAAO,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACnD,QAAQ,CAAC,OAAO,EAAE,sBAAsB,CAAC;CACzC;AAuBD,wBAAgB,uBAAuB,CAAC,KAAK,GAAE,oBAAyB,GAAG,qBAAqB,CAO/F;AAED,wBAAgB,0BAA0B,CACzC,UAAU,EAAE,sBAAsB,EAClC,WAAW,CAAC,EAAE,6BAA6B,EAC3C,GAAG,CAAC,EAAE,IAAI,GACR,qBAAqB,CAkBvB;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,SAAS,qBAAqB,EAAE,GAAG,sBAAsB,CAsD1G","sourcesContent":["import { type Adoption, type ProcurementReview, procureCandidate } from \"./package-procurement.ts\";\nimport {\n\tP0_PI_PACKAGE_PORT_CANDIDATES,\n\tP1_PI_PACKAGE_PORT_CANDIDATES,\n\ttype PiPackageCandidateReviewInput,\n\ttype PiPackageLane,\n\ttype PiPackagePortCandidate,\n} from \"./pi-package-intake-candidates.ts\";\n\nexport type {\n\tPiPackageCandidateReviewInput,\n\tPiPackageLane,\n\tPiPackagePortCandidate,\n\tPiPackagePortMode,\n} from \"./pi-package-intake-candidates.ts\";\nexport { P0_PI_PACKAGE_PORT_CANDIDATES, P1_PI_PACKAGE_PORT_CANDIDATES } from \"./pi-package-intake-candidates.ts\";\n\n/**\n * Combined default candidate set (P0 + P1). P1 was drawn from a full crawl of\n * pi.dev/packages (4653 unique packages) and is intentionally more conservative\n * (reference/measurement-gated/report-only only, never native) since no source-level\n * review has been run on any P1 candidate yet.\n */\nexport const ALL_PI_PACKAGE_PORT_CANDIDATES: readonly PiPackagePortCandidate[] = [\n\t...P0_PI_PACKAGE_PORT_CANDIDATES,\n\t...P1_PI_PACKAGE_PORT_CANDIDATES,\n];\n\nexport interface PiPackageIntakeInput {\n\treadonly candidates?: readonly PiPackagePortCandidate[];\n\treadonly reviews?: readonly PiPackageCandidateReviewInput[];\n\treadonly now?: Date;\n}\n\nexport interface PiPackageLaneSummary {\n\treadonly lane: PiPackageLane;\n\treadonly label: string;\n\treadonly total: number;\n\treadonly accepted: number;\n\treadonly deferred: number;\n\treadonly reject: number;\n\treadonly hardForkBlocked: number;\n}\n\nexport interface PiPackageIntakeSummary {\n\treadonly total: number;\n\treadonly acceptedNative: number;\n\treadonly acceptedReference: number;\n\treadonly acceptedMeasurement: number;\n\treadonly acceptedAdvisory: number;\n\treadonly deferred: number;\n\treadonly reject: number;\n\treadonly hardForkBlocked: number;\n\treadonly topLanes: readonly PiPackageLaneSummary[];\n}\n\nexport interface PiPackageIntakeResult {\n\treadonly definition: PiPackagePortCandidate;\n\treadonly review: ProcurementReview;\n\treadonly hardForkBlocked: boolean;\n\treadonly hardForkReasons: readonly string[];\n\treadonly directPermanentPiAdoption: boolean;\n}\n\nexport interface PiPackageIntakeReport {\n\treadonly results: readonly PiPackageIntakeResult[];\n\treadonly summary: PiPackageIntakeSummary;\n}\n\nconst HARD_FORK_FINDING_KINDS = new Set([\n\t\"legacy-home-path\",\n\t\"legacy-state-dir\",\n\t\"legacy-project-path\",\n\t\"legacy-package-path\",\n\t\"legacy-cli-invocation\",\n\t\"legacy-import\",\n]);\n\nconst DIRECT_PI_ADOPTION_BLOCKED = new Set<Adoption>([\"permanent-package\"]);\n\ninterface MutablePiPackageLaneSummary {\n\tlane: PiPackageLane;\n\tlabel: string;\n\ttotal: number;\n\taccepted: number;\n\tdeferred: number;\n\treject: number;\n\thardForkBlocked: number;\n}\n\nexport function evaluatePiPackageIntake(input: PiPackageIntakeInput = {}): PiPackageIntakeReport {\n\tconst candidates = input.candidates ?? ALL_PI_PACKAGE_PORT_CANDIDATES;\n\tconst reviewInputs = new Map((input.reviews ?? []).map((review) => [review.candidateId, review]));\n\tconst results = candidates.map((definition) =>\n\t\tevaluatePiPackageCandidate(definition, reviewInputs.get(definition.id), input.now),\n\t);\n\treturn { results, summary: summarizePiPackageIntake(results) };\n}\n\nexport function evaluatePiPackageCandidate(\n\tdefinition: PiPackagePortCandidate,\n\treviewInput?: PiPackageCandidateReviewInput,\n\tnow?: Date,\n): PiPackageIntakeResult {\n\tconst review = procureCandidate({\n\t\tcandidate: definition.candidate,\n\t\tdeclaredLicense: reviewInput?.declaredLicense ?? \"MIT\",\n\t\tpackageJsonScripts: reviewInput?.packageJsonScripts,\n\t\treviewedScriptAllowlist: reviewInput?.reviewedScriptAllowlist,\n\t\tsources: reviewInput?.sources,\n\t\ttransitiveLicenses: reviewInput?.transitiveLicenses,\n\t\tnow,\n\t});\n\tconst hardForkReasons = hardForkBlockReasons(review);\n\treturn {\n\t\tdefinition,\n\t\treview,\n\t\thardForkBlocked: hardForkReasons.length > 0,\n\t\thardForkReasons,\n\t\tdirectPermanentPiAdoption: isDirectPermanentPiAdoption(definition, review),\n\t};\n}\n\nexport function summarizePiPackageIntake(results: readonly PiPackageIntakeResult[]): PiPackageIntakeSummary {\n\tconst laneSummaries = new Map<PiPackageLane, MutablePiPackageLaneSummary>();\n\tlet acceptedNative = 0;\n\tlet acceptedReference = 0;\n\tlet acceptedMeasurement = 0;\n\tlet acceptedAdvisory = 0;\n\tlet deferred = 0;\n\tlet reject = 0;\n\tlet hardForkBlocked = 0;\n\n\tfor (const result of results) {\n\t\tconst lane = laneSummaries.get(result.definition.lane) ?? laneSummaryFor(result);\n\t\tlaneSummaries.set(result.definition.lane, lane);\n\t\tlane.total += 1;\n\n\t\tif (result.hardForkBlocked) {\n\t\t\thardForkBlocked += 1;\n\t\t\tlane.hardForkBlocked += 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (result.review.adoption === \"native\") {\n\t\t\tacceptedNative += 1;\n\t\t\tlane.accepted += 1;\n\t\t} else if (result.review.adoption === \"reference-only\") {\n\t\t\tacceptedReference += 1;\n\t\t\tlane.accepted += 1;\n\t\t} else if (result.review.adoption === \"measurement-gated\") {\n\t\t\tacceptedMeasurement += 1;\n\t\t\tlane.accepted += 1;\n\t\t} else if (result.review.adoption === \"advisory-only\" || result.review.adoption === \"report-only\") {\n\t\t\t// Accepted read-only ports (advisor/quality lanes); connected, never mutating.\n\t\t\tacceptedAdvisory += 1;\n\t\t\tlane.accepted += 1;\n\t\t} else if (result.review.adoption === \"deferred\") {\n\t\t\tdeferred += 1;\n\t\t\tlane.deferred += 1;\n\t\t} else if (result.review.adoption === \"reject\") {\n\t\t\treject += 1;\n\t\t\tlane.reject += 1;\n\t\t}\n\t}\n\n\treturn {\n\t\ttotal: results.length,\n\t\tacceptedNative,\n\t\tacceptedReference,\n\t\tacceptedMeasurement,\n\t\tacceptedAdvisory,\n\t\tdeferred,\n\t\treject,\n\t\thardForkBlocked,\n\t\ttopLanes: [...laneSummaries.values()].sort(compareLaneSummaries).map((lane) => ({ ...lane })),\n\t};\n}\n\nfunction hardForkBlockReasons(review: ProcurementReview): string[] {\n\tconst reasons = review.compatibilityFindings\n\t\t.filter((finding) => finding.severity === \"block\" && HARD_FORK_FINDING_KINDS.has(finding.kind))\n\t\t.map((finding) => `${finding.kind}:${finding.path ?? \"source\"}:${finding.line}`);\n\tif (review.lifecycleVerdict === \"reject\") {\n\t\treasons.push(...review.declaredLifecycleScripts.map((script) => `lifecycle-script:${script}`));\n\t}\n\treturn [...new Set(reasons)];\n}\n\nfunction isDirectPermanentPiAdoption(definition: PiPackagePortCandidate, review: ProcurementReview): boolean {\n\treturn definition.candidate.intendedUse === \"permanent-adopt\" || DIRECT_PI_ADOPTION_BLOCKED.has(review.adoption);\n}\n\nfunction laneSummaryFor(result: PiPackageIntakeResult): MutablePiPackageLaneSummary {\n\treturn {\n\t\tlane: result.definition.lane,\n\t\tlabel: result.definition.laneLabel,\n\t\ttotal: 0,\n\t\taccepted: 0,\n\t\tdeferred: 0,\n\t\treject: 0,\n\t\thardForkBlocked: 0,\n\t};\n}\n\nfunction compareLaneSummaries(a: PiPackageLaneSummary, b: PiPackageLaneSummary): number {\n\tconst acceptedDelta = b.accepted - a.accepted;\n\tif (acceptedDelta !== 0) return acceptedDelta;\n\tconst totalDelta = b.total - a.total;\n\tif (totalDelta !== 0) return totalDelta;\n\treturn laneRank(a.lane) - laneRank(b.lane);\n}\n\nfunction laneRank(lane: PiPackageLane): number {\n\treturn ALL_PI_PACKAGE_PORT_CANDIDATES.findIndex((candidate) => candidate.lane === lane);\n}\n"]}
@@ -50,6 +50,7 @@ export function summarizePiPackageIntake(results) {
50
50
  let acceptedNative = 0;
51
51
  let acceptedReference = 0;
52
52
  let acceptedMeasurement = 0;
53
+ let acceptedAdvisory = 0;
53
54
  let deferred = 0;
54
55
  let reject = 0;
55
56
  let hardForkBlocked = 0;
@@ -74,6 +75,11 @@ export function summarizePiPackageIntake(results) {
74
75
  acceptedMeasurement += 1;
75
76
  lane.accepted += 1;
76
77
  }
78
+ else if (result.review.adoption === "advisory-only" || result.review.adoption === "report-only") {
79
+ // Accepted read-only ports (advisor/quality lanes); connected, never mutating.
80
+ acceptedAdvisory += 1;
81
+ lane.accepted += 1;
82
+ }
77
83
  else if (result.review.adoption === "deferred") {
78
84
  deferred += 1;
79
85
  lane.deferred += 1;
@@ -88,6 +94,7 @@ export function summarizePiPackageIntake(results) {
88
94
  acceptedNative,
89
95
  acceptedReference,
90
96
  acceptedMeasurement,
97
+ acceptedAdvisory,
91
98
  deferred,
92
99
  reject,
93
100
  hardForkBlocked,