@fgv/ts-extras 5.1.0-3 → 5.1.0-30

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 (334) hide show
  1. package/dist/index.browser.js +4 -2
  2. package/dist/index.browser.js.map +1 -0
  3. package/dist/index.js.map +1 -0
  4. package/dist/packlets/ai-assist/apiClient.js +958 -131
  5. package/dist/packlets/ai-assist/apiClient.js.map +1 -0
  6. package/dist/packlets/ai-assist/chatRequestBuilders.js +186 -0
  7. package/dist/packlets/ai-assist/chatRequestBuilders.js.map +1 -0
  8. package/dist/packlets/ai-assist/converters.js +2 -1
  9. package/dist/packlets/ai-assist/converters.js.map +1 -0
  10. package/dist/packlets/ai-assist/endpoint.js +78 -0
  11. package/dist/packlets/ai-assist/endpoint.js.map +1 -0
  12. package/dist/packlets/ai-assist/imageOptionsResolver.js +212 -0
  13. package/dist/packlets/ai-assist/imageOptionsResolver.js.map +1 -0
  14. package/dist/packlets/ai-assist/index.js +7 -3
  15. package/dist/packlets/ai-assist/index.js.map +1 -0
  16. package/dist/packlets/ai-assist/jsonCompletion.js +95 -0
  17. package/dist/packlets/ai-assist/jsonCompletion.js.map +1 -0
  18. package/dist/packlets/ai-assist/jsonResponse.js +149 -0
  19. package/dist/packlets/ai-assist/jsonResponse.js.map +1 -0
  20. package/dist/packlets/ai-assist/model.js +21 -4
  21. package/dist/packlets/ai-assist/model.js.map +1 -0
  22. package/dist/packlets/ai-assist/registry.js +235 -10
  23. package/dist/packlets/ai-assist/registry.js.map +1 -0
  24. package/dist/packlets/ai-assist/sseParser.js +123 -0
  25. package/dist/packlets/ai-assist/sseParser.js.map +1 -0
  26. package/dist/packlets/ai-assist/streamingAdapters/anthropic.js +197 -0
  27. package/dist/packlets/ai-assist/streamingAdapters/anthropic.js.map +1 -0
  28. package/dist/packlets/ai-assist/streamingAdapters/common.js +79 -0
  29. package/dist/packlets/ai-assist/streamingAdapters/common.js.map +1 -0
  30. package/dist/packlets/ai-assist/streamingAdapters/gemini.js +172 -0
  31. package/dist/packlets/ai-assist/streamingAdapters/gemini.js.map +1 -0
  32. package/dist/packlets/ai-assist/streamingAdapters/openaiChat.js +165 -0
  33. package/dist/packlets/ai-assist/streamingAdapters/openaiChat.js.map +1 -0
  34. package/dist/packlets/ai-assist/streamingAdapters/openaiResponses.js +179 -0
  35. package/dist/packlets/ai-assist/streamingAdapters/openaiResponses.js.map +1 -0
  36. package/dist/packlets/ai-assist/streamingAdapters/proxy.js +163 -0
  37. package/dist/packlets/ai-assist/streamingAdapters/proxy.js.map +1 -0
  38. package/dist/packlets/ai-assist/streamingClient.js +116 -0
  39. package/dist/packlets/ai-assist/streamingClient.js.map +1 -0
  40. package/dist/packlets/ai-assist/thinkingOptionsResolver.js +265 -0
  41. package/dist/packlets/ai-assist/thinkingOptionsResolver.js.map +1 -0
  42. package/dist/packlets/ai-assist/toolFormats.js.map +1 -0
  43. package/dist/packlets/conversion/converters.js +35 -1
  44. package/dist/packlets/conversion/converters.js.map +1 -0
  45. package/dist/packlets/conversion/index.js.map +1 -0
  46. package/dist/packlets/crypto-utils/constants.js.map +1 -0
  47. package/dist/packlets/crypto-utils/converters.js +24 -4
  48. package/dist/packlets/crypto-utils/converters.js.map +1 -0
  49. package/dist/packlets/crypto-utils/directEncryptionProvider.js.map +1 -0
  50. package/dist/packlets/crypto-utils/encryptedFile.js.map +1 -0
  51. package/dist/packlets/crypto-utils/hpkeProvider.js +333 -0
  52. package/dist/packlets/crypto-utils/hpkeProvider.js.map +1 -0
  53. package/dist/packlets/crypto-utils/index.browser.js +7 -0
  54. package/dist/packlets/crypto-utils/index.browser.js.map +1 -0
  55. package/dist/packlets/crypto-utils/index.js +6 -0
  56. package/dist/packlets/crypto-utils/index.js.map +1 -0
  57. package/dist/packlets/crypto-utils/keyPairAlgorithmParams.js +71 -0
  58. package/dist/packlets/crypto-utils/keyPairAlgorithmParams.js.map +1 -0
  59. package/dist/packlets/crypto-utils/keystore/converters.js +103 -11
  60. package/dist/packlets/crypto-utils/keystore/converters.js.map +1 -0
  61. package/dist/packlets/crypto-utils/keystore/index.js +1 -0
  62. package/dist/packlets/crypto-utils/keystore/index.js.map +1 -0
  63. package/dist/packlets/crypto-utils/keystore/keyStore.js +618 -118
  64. package/dist/packlets/crypto-utils/keystore/keyStore.js.map +1 -0
  65. package/dist/packlets/crypto-utils/keystore/model.js +22 -1
  66. package/dist/packlets/crypto-utils/keystore/model.js.map +1 -0
  67. package/dist/packlets/crypto-utils/keystore/privateKeyStorage.js +21 -0
  68. package/dist/packlets/crypto-utils/keystore/privateKeyStorage.js.map +1 -0
  69. package/dist/packlets/crypto-utils/model.js +32 -0
  70. package/dist/packlets/crypto-utils/model.js.map +1 -0
  71. package/dist/packlets/crypto-utils/nodeCryptoProvider.js +270 -1
  72. package/dist/packlets/crypto-utils/nodeCryptoProvider.js.map +1 -0
  73. package/dist/packlets/crypto-utils/spkiHelpers.js +130 -0
  74. package/dist/packlets/crypto-utils/spkiHelpers.js.map +1 -0
  75. package/dist/packlets/csv/csvFileHelpers.js +0 -14
  76. package/dist/packlets/csv/csvFileHelpers.js.map +1 -0
  77. package/dist/packlets/csv/csvHelpers.js +14 -0
  78. package/dist/packlets/csv/csvHelpers.js.map +1 -0
  79. package/dist/packlets/csv/index.browser.js +1 -3
  80. package/dist/packlets/csv/index.browser.js.map +1 -0
  81. package/dist/packlets/csv/index.js.map +1 -0
  82. package/dist/packlets/experimental/extendedArray.js.map +1 -0
  83. package/dist/packlets/experimental/formatter.js.map +1 -0
  84. package/dist/packlets/experimental/index.js.map +1 -0
  85. package/dist/packlets/experimental/rangeOf.js.map +1 -0
  86. package/dist/packlets/hash/index.browser.js.map +1 -0
  87. package/dist/packlets/hash/index.js.map +1 -0
  88. package/dist/packlets/hash/index.node.js.map +1 -0
  89. package/dist/packlets/hash/md5Normalizer.browser.js.map +1 -0
  90. package/dist/packlets/hash/md5Normalizer.js.map +1 -0
  91. package/dist/packlets/mustache/index.js.map +1 -0
  92. package/dist/packlets/mustache/interfaces.js.map +1 -0
  93. package/dist/packlets/mustache/mustacheTemplate.js +42 -4
  94. package/dist/packlets/mustache/mustacheTemplate.js.map +1 -0
  95. package/dist/packlets/record-jar/index.browser.js +1 -3
  96. package/dist/packlets/record-jar/index.browser.js.map +1 -0
  97. package/dist/packlets/record-jar/index.js.map +1 -0
  98. package/dist/packlets/record-jar/recordJarFileHelpers.js +0 -18
  99. package/dist/packlets/record-jar/recordJarFileHelpers.js.map +1 -0
  100. package/dist/packlets/record-jar/recordJarHelpers.js +18 -0
  101. package/dist/packlets/record-jar/recordJarHelpers.js.map +1 -0
  102. package/dist/packlets/yaml/converters.js.map +1 -0
  103. package/dist/packlets/yaml/index.js +1 -0
  104. package/dist/packlets/yaml/index.js.map +1 -0
  105. package/dist/packlets/yaml/serializers.js +48 -0
  106. package/dist/packlets/yaml/serializers.js.map +1 -0
  107. package/dist/packlets/zip-file-tree/index.js.map +1 -0
  108. package/dist/packlets/zip-file-tree/zipFileTreeAccessors.js +2 -2
  109. package/dist/packlets/zip-file-tree/zipFileTreeAccessors.js.map +1 -0
  110. package/dist/packlets/zip-file-tree/zipFileTreeWriter.js.map +1 -0
  111. package/dist/ts-extras.d.ts +2869 -154
  112. package/dist/tsdoc-metadata.json +1 -1
  113. package/lib/index.browser.d.ts +4 -2
  114. package/lib/index.browser.d.ts.map +1 -0
  115. package/lib/index.browser.js +8 -3
  116. package/lib/index.browser.js.map +1 -0
  117. package/lib/index.d.ts.map +1 -0
  118. package/lib/index.js.map +1 -0
  119. package/lib/packlets/ai-assist/apiClient.d.ts +99 -16
  120. package/lib/packlets/ai-assist/apiClient.d.ts.map +1 -0
  121. package/lib/packlets/ai-assist/apiClient.js +961 -130
  122. package/lib/packlets/ai-assist/apiClient.js.map +1 -0
  123. package/lib/packlets/ai-assist/chatRequestBuilders.d.ts +89 -0
  124. package/lib/packlets/ai-assist/chatRequestBuilders.d.ts.map +1 -0
  125. package/lib/packlets/ai-assist/chatRequestBuilders.js +195 -0
  126. package/lib/packlets/ai-assist/chatRequestBuilders.js.map +1 -0
  127. package/lib/packlets/ai-assist/converters.d.ts.map +1 -0
  128. package/lib/packlets/ai-assist/converters.js +2 -1
  129. package/lib/packlets/ai-assist/converters.js.map +1 -0
  130. package/lib/packlets/ai-assist/endpoint.d.ts +28 -0
  131. package/lib/packlets/ai-assist/endpoint.d.ts.map +1 -0
  132. package/lib/packlets/ai-assist/endpoint.js +82 -0
  133. package/lib/packlets/ai-assist/endpoint.js.map +1 -0
  134. package/lib/packlets/ai-assist/imageOptionsResolver.d.ts +74 -0
  135. package/lib/packlets/ai-assist/imageOptionsResolver.d.ts.map +1 -0
  136. package/lib/packlets/ai-assist/imageOptionsResolver.js +216 -0
  137. package/lib/packlets/ai-assist/imageOptionsResolver.js.map +1 -0
  138. package/lib/packlets/ai-assist/index.d.ts +7 -3
  139. package/lib/packlets/ai-assist/index.d.ts.map +1 -0
  140. package/lib/packlets/ai-assist/index.js +21 -1
  141. package/lib/packlets/ai-assist/index.js.map +1 -0
  142. package/lib/packlets/ai-assist/jsonCompletion.d.ts +93 -0
  143. package/lib/packlets/ai-assist/jsonCompletion.d.ts.map +1 -0
  144. package/lib/packlets/ai-assist/jsonCompletion.js +99 -0
  145. package/lib/packlets/ai-assist/jsonCompletion.js.map +1 -0
  146. package/lib/packlets/ai-assist/jsonResponse.d.ts +91 -0
  147. package/lib/packlets/ai-assist/jsonResponse.d.ts.map +1 -0
  148. package/lib/packlets/ai-assist/jsonResponse.js +154 -0
  149. package/lib/packlets/ai-assist/jsonResponse.js.map +1 -0
  150. package/lib/packlets/ai-assist/model.d.ts +720 -7
  151. package/lib/packlets/ai-assist/model.d.ts.map +1 -0
  152. package/lib/packlets/ai-assist/model.js +22 -4
  153. package/lib/packlets/ai-assist/model.js.map +1 -0
  154. package/lib/packlets/ai-assist/registry.d.ts +34 -1
  155. package/lib/packlets/ai-assist/registry.d.ts.map +1 -0
  156. package/lib/packlets/ai-assist/registry.js +238 -11
  157. package/lib/packlets/ai-assist/registry.js.map +1 -0
  158. package/lib/packlets/ai-assist/sseParser.d.ts +45 -0
  159. package/lib/packlets/ai-assist/sseParser.d.ts.map +1 -0
  160. package/lib/packlets/ai-assist/sseParser.js +128 -0
  161. package/lib/packlets/ai-assist/sseParser.js.map +1 -0
  162. package/lib/packlets/ai-assist/streamingAdapters/anthropic.d.ts +19 -0
  163. package/lib/packlets/ai-assist/streamingAdapters/anthropic.d.ts.map +1 -0
  164. package/lib/packlets/ai-assist/streamingAdapters/anthropic.js +200 -0
  165. package/lib/packlets/ai-assist/streamingAdapters/anthropic.js.map +1 -0
  166. package/lib/packlets/ai-assist/streamingAdapters/common.d.ts +83 -0
  167. package/lib/packlets/ai-assist/streamingAdapters/common.d.ts.map +1 -0
  168. package/lib/packlets/ai-assist/streamingAdapters/common.js +83 -0
  169. package/lib/packlets/ai-assist/streamingAdapters/common.js.map +1 -0
  170. package/lib/packlets/ai-assist/streamingAdapters/gemini.d.ts +20 -0
  171. package/lib/packlets/ai-assist/streamingAdapters/gemini.d.ts.map +1 -0
  172. package/lib/packlets/ai-assist/streamingAdapters/gemini.js +175 -0
  173. package/lib/packlets/ai-assist/streamingAdapters/gemini.js.map +1 -0
  174. package/lib/packlets/ai-assist/streamingAdapters/openaiChat.d.ts +19 -0
  175. package/lib/packlets/ai-assist/streamingAdapters/openaiChat.d.ts.map +1 -0
  176. package/lib/packlets/ai-assist/streamingAdapters/openaiChat.js +168 -0
  177. package/lib/packlets/ai-assist/streamingAdapters/openaiChat.js.map +1 -0
  178. package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.d.ts +20 -0
  179. package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.d.ts.map +1 -0
  180. package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.js +182 -0
  181. package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.js.map +1 -0
  182. package/lib/packlets/ai-assist/streamingAdapters/proxy.d.ts +34 -0
  183. package/lib/packlets/ai-assist/streamingAdapters/proxy.d.ts.map +1 -0
  184. package/lib/packlets/ai-assist/streamingAdapters/proxy.js +166 -0
  185. package/lib/packlets/ai-assist/streamingAdapters/proxy.js.map +1 -0
  186. package/lib/packlets/ai-assist/streamingClient.d.ts +33 -0
  187. package/lib/packlets/ai-assist/streamingClient.d.ts.map +1 -0
  188. package/lib/packlets/ai-assist/streamingClient.js +121 -0
  189. package/lib/packlets/ai-assist/streamingClient.js.map +1 -0
  190. package/lib/packlets/ai-assist/thinkingOptionsResolver.d.ts +71 -0
  191. package/lib/packlets/ai-assist/thinkingOptionsResolver.d.ts.map +1 -0
  192. package/lib/packlets/ai-assist/thinkingOptionsResolver.js +270 -0
  193. package/lib/packlets/ai-assist/thinkingOptionsResolver.js.map +1 -0
  194. package/lib/packlets/ai-assist/toolFormats.d.ts.map +1 -0
  195. package/lib/packlets/ai-assist/toolFormats.js.map +1 -0
  196. package/lib/packlets/conversion/converters.d.ts +8 -1
  197. package/lib/packlets/conversion/converters.d.ts.map +1 -0
  198. package/lib/packlets/conversion/converters.js +36 -2
  199. package/lib/packlets/conversion/converters.js.map +1 -0
  200. package/lib/packlets/conversion/index.d.ts.map +1 -0
  201. package/lib/packlets/conversion/index.js.map +1 -0
  202. package/lib/packlets/crypto-utils/constants.d.ts.map +1 -0
  203. package/lib/packlets/crypto-utils/constants.js.map +1 -0
  204. package/lib/packlets/crypto-utils/converters.d.ts +12 -1
  205. package/lib/packlets/crypto-utils/converters.d.ts.map +1 -0
  206. package/lib/packlets/crypto-utils/converters.js +25 -5
  207. package/lib/packlets/crypto-utils/converters.js.map +1 -0
  208. package/lib/packlets/crypto-utils/directEncryptionProvider.d.ts.map +1 -0
  209. package/lib/packlets/crypto-utils/directEncryptionProvider.js.map +1 -0
  210. package/lib/packlets/crypto-utils/encryptedFile.d.ts.map +1 -0
  211. package/lib/packlets/crypto-utils/encryptedFile.js.map +1 -0
  212. package/lib/packlets/crypto-utils/hpkeProvider.d.ts +142 -0
  213. package/lib/packlets/crypto-utils/hpkeProvider.d.ts.map +1 -0
  214. package/lib/packlets/crypto-utils/hpkeProvider.js +337 -0
  215. package/lib/packlets/crypto-utils/hpkeProvider.js.map +1 -0
  216. package/lib/packlets/crypto-utils/index.browser.d.ts +3 -0
  217. package/lib/packlets/crypto-utils/index.browser.d.ts.map +1 -0
  218. package/lib/packlets/crypto-utils/index.browser.js +14 -1
  219. package/lib/packlets/crypto-utils/index.browser.js.map +1 -0
  220. package/lib/packlets/crypto-utils/index.d.ts +3 -0
  221. package/lib/packlets/crypto-utils/index.d.ts.map +1 -0
  222. package/lib/packlets/crypto-utils/index.js +13 -1
  223. package/lib/packlets/crypto-utils/index.js.map +1 -0
  224. package/lib/packlets/crypto-utils/keyPairAlgorithmParams.d.ts +54 -0
  225. package/lib/packlets/crypto-utils/keyPairAlgorithmParams.d.ts.map +1 -0
  226. package/lib/packlets/crypto-utils/keyPairAlgorithmParams.js +74 -0
  227. package/lib/packlets/crypto-utils/keyPairAlgorithmParams.js.map +1 -0
  228. package/lib/packlets/crypto-utils/keystore/converters.d.ts +68 -6
  229. package/lib/packlets/crypto-utils/keystore/converters.d.ts.map +1 -0
  230. package/lib/packlets/crypto-utils/keystore/converters.js +101 -9
  231. package/lib/packlets/crypto-utils/keystore/converters.js.map +1 -0
  232. package/lib/packlets/crypto-utils/keystore/index.d.ts +1 -0
  233. package/lib/packlets/crypto-utils/keystore/index.d.ts.map +1 -0
  234. package/lib/packlets/crypto-utils/keystore/index.js +1 -0
  235. package/lib/packlets/crypto-utils/keystore/index.js.map +1 -0
  236. package/lib/packlets/crypto-utils/keystore/keyStore.d.ts +198 -13
  237. package/lib/packlets/crypto-utils/keystore/keyStore.d.ts.map +1 -0
  238. package/lib/packlets/crypto-utils/keystore/keyStore.js +624 -124
  239. package/lib/packlets/crypto-utils/keystore/keyStore.js.map +1 -0
  240. package/lib/packlets/crypto-utils/keystore/model.d.ts +268 -19
  241. package/lib/packlets/crypto-utils/keystore/model.d.ts.map +1 -0
  242. package/lib/packlets/crypto-utils/keystore/model.js +24 -2
  243. package/lib/packlets/crypto-utils/keystore/model.js.map +1 -0
  244. package/lib/packlets/crypto-utils/keystore/privateKeyStorage.d.ts +50 -0
  245. package/lib/packlets/crypto-utils/keystore/privateKeyStorage.d.ts.map +1 -0
  246. package/lib/packlets/crypto-utils/keystore/privateKeyStorage.js +22 -0
  247. package/lib/packlets/crypto-utils/keystore/privateKeyStorage.js.map +1 -0
  248. package/lib/packlets/crypto-utils/model.d.ts +338 -10
  249. package/lib/packlets/crypto-utils/model.d.ts.map +1 -0
  250. package/lib/packlets/crypto-utils/model.js +33 -1
  251. package/lib/packlets/crypto-utils/model.js.map +1 -0
  252. package/lib/packlets/crypto-utils/nodeCryptoProvider.d.ts +110 -2
  253. package/lib/packlets/crypto-utils/nodeCryptoProvider.d.ts.map +1 -0
  254. package/lib/packlets/crypto-utils/nodeCryptoProvider.js +269 -0
  255. package/lib/packlets/crypto-utils/nodeCryptoProvider.js.map +1 -0
  256. package/lib/packlets/crypto-utils/spkiHelpers.d.ts +53 -0
  257. package/lib/packlets/crypto-utils/spkiHelpers.d.ts.map +1 -0
  258. package/lib/packlets/crypto-utils/spkiHelpers.js +136 -0
  259. package/lib/packlets/crypto-utils/spkiHelpers.js.map +1 -0
  260. package/lib/packlets/csv/csvFileHelpers.d.ts +0 -10
  261. package/lib/packlets/csv/csvFileHelpers.d.ts.map +1 -0
  262. package/lib/packlets/csv/csvFileHelpers.js +0 -15
  263. package/lib/packlets/csv/csvFileHelpers.js.map +1 -0
  264. package/lib/packlets/csv/csvHelpers.d.ts +10 -0
  265. package/lib/packlets/csv/csvHelpers.d.ts.map +1 -0
  266. package/lib/packlets/csv/csvHelpers.js +15 -0
  267. package/lib/packlets/csv/csvHelpers.js.map +1 -0
  268. package/lib/packlets/csv/index.browser.d.ts +0 -1
  269. package/lib/packlets/csv/index.browser.d.ts.map +1 -0
  270. package/lib/packlets/csv/index.browser.js +1 -5
  271. package/lib/packlets/csv/index.browser.js.map +1 -0
  272. package/lib/packlets/csv/index.d.ts.map +1 -0
  273. package/lib/packlets/csv/index.js.map +1 -0
  274. package/lib/packlets/experimental/extendedArray.d.ts.map +1 -0
  275. package/lib/packlets/experimental/extendedArray.js.map +1 -0
  276. package/lib/packlets/experimental/formatter.d.ts.map +1 -0
  277. package/lib/packlets/experimental/formatter.js.map +1 -0
  278. package/lib/packlets/experimental/index.d.ts.map +1 -0
  279. package/lib/packlets/experimental/index.js.map +1 -0
  280. package/lib/packlets/experimental/rangeOf.d.ts.map +1 -0
  281. package/lib/packlets/experimental/rangeOf.js.map +1 -0
  282. package/lib/packlets/hash/index.browser.d.ts.map +1 -0
  283. package/lib/packlets/hash/index.browser.js.map +1 -0
  284. package/lib/packlets/hash/index.d.ts.map +1 -0
  285. package/lib/packlets/hash/index.js.map +1 -0
  286. package/lib/packlets/hash/index.node.d.ts.map +1 -0
  287. package/lib/packlets/hash/index.node.js.map +1 -0
  288. package/lib/packlets/hash/md5Normalizer.browser.d.ts.map +1 -0
  289. package/lib/packlets/hash/md5Normalizer.browser.js.map +1 -0
  290. package/lib/packlets/hash/md5Normalizer.d.ts.map +1 -0
  291. package/lib/packlets/hash/md5Normalizer.js.map +1 -0
  292. package/lib/packlets/mustache/index.d.ts +1 -1
  293. package/lib/packlets/mustache/index.d.ts.map +1 -0
  294. package/lib/packlets/mustache/index.js.map +1 -0
  295. package/lib/packlets/mustache/interfaces.d.ts +34 -0
  296. package/lib/packlets/mustache/interfaces.d.ts.map +1 -0
  297. package/lib/packlets/mustache/interfaces.js.map +1 -0
  298. package/lib/packlets/mustache/mustacheTemplate.d.ts +2 -0
  299. package/lib/packlets/mustache/mustacheTemplate.d.ts.map +1 -0
  300. package/lib/packlets/mustache/mustacheTemplate.js +42 -4
  301. package/lib/packlets/mustache/mustacheTemplate.js.map +1 -0
  302. package/lib/packlets/record-jar/index.browser.d.ts +0 -1
  303. package/lib/packlets/record-jar/index.browser.d.ts.map +1 -0
  304. package/lib/packlets/record-jar/index.browser.js +1 -5
  305. package/lib/packlets/record-jar/index.browser.js.map +1 -0
  306. package/lib/packlets/record-jar/index.d.ts.map +1 -0
  307. package/lib/packlets/record-jar/index.js.map +1 -0
  308. package/lib/packlets/record-jar/recordJarFileHelpers.d.ts +0 -11
  309. package/lib/packlets/record-jar/recordJarFileHelpers.d.ts.map +1 -0
  310. package/lib/packlets/record-jar/recordJarFileHelpers.js +0 -19
  311. package/lib/packlets/record-jar/recordJarFileHelpers.js.map +1 -0
  312. package/lib/packlets/record-jar/recordJarHelpers.d.ts +11 -0
  313. package/lib/packlets/record-jar/recordJarHelpers.d.ts.map +1 -0
  314. package/lib/packlets/record-jar/recordJarHelpers.js +19 -0
  315. package/lib/packlets/record-jar/recordJarHelpers.js.map +1 -0
  316. package/lib/packlets/yaml/converters.d.ts.map +1 -0
  317. package/lib/packlets/yaml/converters.js.map +1 -0
  318. package/lib/packlets/yaml/index.d.ts +1 -0
  319. package/lib/packlets/yaml/index.d.ts.map +1 -0
  320. package/lib/packlets/yaml/index.js +1 -0
  321. package/lib/packlets/yaml/index.js.map +1 -0
  322. package/lib/packlets/yaml/serializers.d.ts +45 -0
  323. package/lib/packlets/yaml/serializers.d.ts.map +1 -0
  324. package/lib/packlets/yaml/serializers.js +84 -0
  325. package/lib/packlets/yaml/serializers.js.map +1 -0
  326. package/lib/packlets/zip-file-tree/index.d.ts.map +1 -0
  327. package/lib/packlets/zip-file-tree/index.js.map +1 -0
  328. package/lib/packlets/zip-file-tree/zipFileTreeAccessors.d.ts +2 -2
  329. package/lib/packlets/zip-file-tree/zipFileTreeAccessors.d.ts.map +1 -0
  330. package/lib/packlets/zip-file-tree/zipFileTreeAccessors.js +2 -2
  331. package/lib/packlets/zip-file-tree/zipFileTreeAccessors.js.map +1 -0
  332. package/lib/packlets/zip-file-tree/zipFileTreeWriter.d.ts.map +1 -0
  333. package/lib/packlets/zip-file-tree/zipFileTreeWriter.js.map +1 -0
  334. package/package.json +16 -15
@@ -1,10 +1,13 @@
1
1
  import { Conversion } from '@fgv/ts-utils';
2
2
  import { Converter } from '@fgv/ts-utils';
3
+ import { DateTime } from 'luxon';
3
4
  import { FileTree } from '@fgv/ts-json-base';
4
5
  import { Hash as Hash_2 } from '@fgv/ts-utils';
6
+ import { JsonObject } from '@fgv/ts-json-base';
5
7
  import { JsonValue } from '@fgv/ts-json-base';
6
8
  import { Logging } from '@fgv/ts-utils';
7
9
  import { Result } from '@fgv/ts-utils';
10
+ import { Uuid } from '@fgv/ts-utils';
8
11
  import { Validator } from '@fgv/ts-utils';
9
12
 
10
13
  /**
@@ -22,6 +25,7 @@ declare type AiApiFormat = 'openai' | 'anthropic' | 'gemini';
22
25
  declare namespace AiAssist {
23
26
  export {
24
27
  AiPrompt,
28
+ AiModelCapability,
25
29
  AiProviderId,
26
30
  AiServerToolType,
27
31
  AiServerToolConfig,
@@ -30,23 +34,95 @@ declare namespace AiAssist {
30
34
  IAiCompletionResponse,
31
35
  IChatMessage,
32
36
  AiApiFormat,
37
+ AiImageApiFormat,
38
+ IAiImageModelCapability,
33
39
  IAiProviderDescriptor,
34
40
  IAiAssistProviderConfig,
35
41
  IAiAssistSettings,
36
42
  DEFAULT_AI_ASSIST,
37
43
  IAiAssistKeyStore,
44
+ IAiImageAttachment,
45
+ IAiImageData,
46
+ AiImageSize,
47
+ AiImageQuality,
48
+ DallE2Size,
49
+ DallE3Size,
50
+ GptImageSize,
51
+ DallE3Quality,
52
+ GptImageQuality,
53
+ DallEModelNames,
54
+ GptImageModelNames,
55
+ GrokImagineModelNames,
56
+ Imagen4ModelNames,
57
+ GeminiFlashImageModelNames,
58
+ IDallEImageGenerationConfig,
59
+ IGptImageGenerationConfig,
60
+ IGrokImagineImageGenerationConfig,
61
+ IImagen4GenerationConfig,
62
+ IGeminiFlashImageGenerationConfig,
63
+ IDallEModelOptions,
64
+ IGptImageModelOptions,
65
+ IGrokImagineModelOptions,
66
+ IImagen4ModelOptions,
67
+ IGeminiFlashImageModelOptions,
68
+ IOtherModelOptions,
69
+ IModelFamilyConfig,
70
+ IAiImageGenerationOptions,
71
+ IAiImageGenerationParams,
72
+ IAiGeneratedImage,
73
+ IAiImageGenerationResponse,
74
+ IAiModelCapabilityRule,
75
+ IAiModelCapabilityConfig,
76
+ IAiModelInfo,
77
+ IAiStreamEvent,
78
+ IAiStreamTextDelta,
79
+ IAiStreamToolEvent,
80
+ IAiStreamDone,
81
+ IAiStreamError,
38
82
  ModelSpec,
39
83
  ModelSpecKey,
40
84
  IModelSpecMap,
41
85
  allModelSpecKeys,
42
86
  MODEL_SPEC_BASE_KEY,
43
87
  resolveModel,
88
+ toDataUrl,
89
+ AiThinkingMode,
90
+ IThinkingConfig,
91
+ IThinkingProviderConfig,
92
+ IAnthropicThinkingOptions,
93
+ IOpenAiThinkingOptions,
94
+ IGeminiThinkingOptions,
95
+ IXAiThinkingOptions,
96
+ IOtherThinkingOptions,
97
+ IAnthropicThinkingConfig,
98
+ IOpenAiThinkingConfig,
99
+ IGeminiThinkingConfig,
100
+ IXAiThinkingConfig,
101
+ AnthropicThinkingModelNames,
102
+ OpenAiThinkingModelNames,
103
+ GeminiThinkingModelNames,
104
+ XAiThinkingModelNames,
105
+ IResolvedImageOptions,
106
+ resolveImageOptions,
107
+ validateResolvedOptions,
44
108
  allProviderIds,
45
109
  getProviderDescriptors,
46
110
  getProviderDescriptor,
111
+ resolveImageCapability,
112
+ supportsImageGeneration,
113
+ DEFAULT_MODEL_CAPABILITY_CONFIG,
47
114
  callProviderCompletion,
48
115
  callProxiedCompletion,
116
+ callProviderImageGeneration,
117
+ callProxiedImageGeneration,
118
+ callProviderListModels,
119
+ callProxiedListModels,
49
120
  IProviderCompletionParams,
121
+ IProviderImageGenerationParams,
122
+ IProviderListModelsParams,
123
+ callProviderCompletionStream,
124
+ callProxiedCompletionStream,
125
+ IProviderCompletionStreamParams,
50
126
  aiProviderId,
51
127
  aiServerToolType,
52
128
  aiWebSearchToolConfig,
@@ -56,7 +132,17 @@ declare namespace AiAssist {
56
132
  aiAssistSettings,
57
133
  modelSpecKey,
58
134
  modelSpec,
59
- resolveEffectiveTools
135
+ resolveEffectiveTools,
136
+ extractJsonText,
137
+ fencedStringifiedJson,
138
+ IFencedStringifiedJsonExtractorOptions,
139
+ IFencedStringifiedJsonOptions,
140
+ JsonTextExtractor,
141
+ generateJsonCompletion,
142
+ SMART_JSON_PROMPT_HINT,
143
+ IGenerateJsonCompletionParams,
144
+ IGenerateJsonCompletionResult,
145
+ JsonPromptHint
60
146
  }
61
147
  }
62
148
  export { AiAssist }
@@ -73,6 +159,43 @@ declare const aiAssistProviderConfig: Converter<IAiAssistProviderConfig>;
73
159
  */
74
160
  declare const aiAssistSettings: Converter<IAiAssistSettings>;
75
161
 
162
+ /**
163
+ * API format categories for image-generation provider routing.
164
+ *
165
+ * @remarks
166
+ * - `'openai-images'` — OpenAI Images API. Routes to `/images/generations`
167
+ * (text-only) or `/images/edits` (when reference images are present).
168
+ * - `'xai-images'` — xAI Images API. Text-only JSON generation request.
169
+ * - `'xai-images-edits'` — xAI Images API for Grok Imagine models. Uses JSON
170
+ * body with `{ type: "image_url" }` objects (not multipart).
171
+ * - `'gemini-imagen'` — Google Imagen `:predict` endpoint. Text-only.
172
+ * - `'gemini-image-out'` — Google Gemini chat-style `:generateContent`
173
+ * endpoint that returns image parts (Gemini 2.5 Flash Image / "Nano
174
+ * Banana"). Accepts reference images.
175
+ *
176
+ * @public
177
+ */
178
+ declare type AiImageApiFormat = 'openai-images' | 'gemini-imagen' | 'xai-images' | 'xai-images-edits' | 'gemini-image-out';
179
+
180
+ /** All accepted quality strings across all providers. @public */
181
+ declare type AiImageQuality = DallE3Quality | GptImageQuality;
182
+
183
+ /** All accepted image size strings across all providers. @public */
184
+ declare type AiImageSize = DallE2Size | DallE3Size | GptImageSize;
185
+
186
+ /**
187
+ * Capability vocabulary used to describe what a model can do. Used as both
188
+ * a filter and as a tag in {@link AiAssist.IAiModelInfo.capabilities}.
189
+ *
190
+ * @remarks
191
+ * Adding a new capability is cheap; adding the *first* one after consumers
192
+ * already exist forces churn. The initial vocabulary is intentionally broad
193
+ * even though only `image-generation` is fully exercised today.
194
+ *
195
+ * @public
196
+ */
197
+ declare type AiModelCapability = 'chat' | 'tools' | 'vision' | 'image-generation' | 'thinking';
198
+
76
199
  /**
77
200
  * A structured AI prompt with system/user split for direct API calls,
78
201
  * and a lazily-constructed combined version for copy/paste workflows.
@@ -83,8 +206,18 @@ declare class AiPrompt {
83
206
  readonly system: string;
84
207
  /** User request: the specific entity generation request. */
85
208
  readonly user: string;
86
- constructor(user: string, system: string);
87
- /** Combined single-string version (user + system joined) for copy/paste. */
209
+ /**
210
+ * Optional image attachments. When present, vision-capable providers will
211
+ * include them in the user message; non-vision providers will reject the
212
+ * call up front (see {@link AiAssist.IAiProviderDescriptor.acceptsImageInput}).
213
+ */
214
+ readonly attachments: ReadonlyArray<IAiImageAttachment>;
215
+ constructor(user: string, system: string, attachments?: ReadonlyArray<IAiImageAttachment>);
216
+ /**
217
+ * Combined single-string version (user + system joined) for copy/paste.
218
+ * When attachments are present, includes a sentinel noting they aren't
219
+ * part of the copied text.
220
+ */
88
221
  get combined(): string;
89
222
  }
90
223
 
@@ -92,7 +225,7 @@ declare class AiPrompt {
92
225
  * All known AI provider identifiers.
93
226
  * @public
94
227
  */
95
- declare type AiProviderId = 'copy-paste' | 'xai-grok' | 'openai' | 'anthropic' | 'google-gemini' | 'groq' | 'mistral';
228
+ declare type AiProviderId = 'copy-paste' | 'xai-grok' | 'openai' | 'openai-compat' | 'anthropic' | 'google-gemini' | 'groq' | 'mistral' | 'ollama';
96
229
 
97
230
  /**
98
231
  * Converter for {@link AiProviderId}.
@@ -124,6 +257,12 @@ declare type AiServerToolType = 'web_search';
124
257
  */
125
258
  declare const aiServerToolType: Converter<AiServerToolType>;
126
259
 
260
+ /**
261
+ * Thinking/reasoning mode support for a provider.
262
+ * @public
263
+ */
264
+ declare type AiThinkingMode = 'optional' | 'required' | 'unsupported';
265
+
127
266
  /**
128
267
  * Converter for {@link IAiToolEnablement}.
129
268
  * @public
@@ -136,12 +275,30 @@ declare const aiToolEnablement: Converter<IAiToolEnablement>;
136
275
  */
137
276
  declare const aiWebSearchToolConfig: Converter<IAiWebSearchToolConfig>;
138
277
 
278
+ /**
279
+ * All valid key pair algorithms.
280
+ * @public
281
+ */
282
+ declare const allKeyPairAlgorithms: ReadonlyArray<KeyPairAlgorithm>;
283
+
284
+ /**
285
+ * All valid asymmetric secret types.
286
+ * @public
287
+ */
288
+ declare const allKeyStoreAsymmetricSecretTypes: ReadonlyArray<KeyStoreAsymmetricSecretType>;
289
+
139
290
  /**
140
291
  * All valid key store secret types.
141
292
  * @public
142
293
  */
143
294
  declare const allKeyStoreSecretTypes: ReadonlyArray<KeyStoreSecretType>;
144
295
 
296
+ /**
297
+ * All valid symmetric secret types.
298
+ * @public
299
+ */
300
+ declare const allKeyStoreSymmetricSecretTypes: ReadonlyArray<KeyStoreSymmetricSecretType>;
301
+
145
302
  /**
146
303
  * All valid {@link ModelSpecKey} values.
147
304
  * @public
@@ -154,6 +311,31 @@ declare const allModelSpecKeys: ReadonlyArray<ModelSpecKey>;
154
311
  */
155
312
  declare const allProviderIds: ReadonlyArray<AiProviderId>;
156
313
 
314
+ /**
315
+ * Model IDs for Anthropic thinking-capable models.
316
+ * @public
317
+ */
318
+ declare type AnthropicThinkingModelNames = 'claude-sonnet-4-5' | 'claude-sonnet-4-6' | 'claude-opus-4-6' | 'claude-opus-4-7';
319
+
320
+ /**
321
+ * Recommended OWASP 2023 minimum Argon2id parameters.
322
+ * Suitable for recovery-row key derivation (high-entropy inputs).
323
+ * @public
324
+ */
325
+ declare const ARGON2ID_OWASP_MIN: IArgon2idParams;
326
+
327
+ /**
328
+ * Stronger Argon2id parameters suitable for user-typed passphrases.
329
+ * @public
330
+ */
331
+ declare const ARGON2ID_PASSPHRASE: IArgon2idParams;
332
+
333
+ /**
334
+ * Converter for {@link CryptoUtils.IArgon2idKeyDerivationParams | Argon2id key derivation parameters}.
335
+ * @public
336
+ */
337
+ declare const argon2idKeyDerivationParams: Converter<IArgon2idKeyDerivationParams>;
338
+
157
339
  /**
158
340
  * Converter for base64 strings (validates format).
159
341
  * @public
@@ -162,22 +344,54 @@ declare const base64String: Converter<string>;
162
344
 
163
345
  /**
164
346
  * Calls the appropriate chat completion API for a given provider.
347
+ * Routes by `apiFormat`: `'openai'` (xAI/OpenAI/Groq/Mistral — switches to Responses API when
348
+ * tools are set), `'anthropic'`, or `'gemini'`.
349
+ * @param params - Request parameters including descriptor, API key, prompt, and optional tools
350
+ * @returns The completion response with content and truncation status, or a failure
351
+ * @public
352
+ */
353
+ declare function callProviderCompletion(params: IProviderCompletionParams): Promise<Result<IAiCompletionResponse>>;
354
+
355
+ /**
356
+ * Calls the appropriate streaming chat completion API for a given provider.
165
357
  *
166
- * Routes based on the provider descriptor's `apiFormat` field:
167
- * - `'openai'` for xAI, OpenAI, Groq, Mistral
168
- * - `'anthropic'` for Anthropic Claude
169
- * - `'gemini'` for Google Gemini
358
+ * @remarks
359
+ * Pre-flight rejection: when `descriptor.streamingCorsRestricted === true`
360
+ * and the call isn't being routed through a proxy, this returns
361
+ * `Result.fail` before fetch is invoked. Callers should route through
362
+ * {@link AiAssist.callProxiedCompletionStream} or surface the failure to the user.
170
363
  *
171
- * When tools are provided and the provider supports them:
172
- * - OpenAI-format providers switch to the Responses API
173
- * - Anthropic includes tools in the Messages API request
174
- * - Gemini includes Google Search grounding
364
+ * Connection-time failures (auth, network, non-2xx) surface as the outer
365
+ * `Result.fail`. Once iteration begins, errors mid-stream surface as a
366
+ * terminal error event ({@link AiAssist.IAiStreamError}) followed by the iterable
367
+ * ending. The final successful event is {@link AiAssist.IAiStreamDone}.
175
368
  *
176
369
  * @param params - Request parameters including descriptor, API key, prompt, and optional tools
177
- * @returns The completion response with content and truncation status, or a failure
370
+ * @returns A streaming iterable of unified events, or a Result.fail
178
371
  * @public
179
372
  */
180
- declare function callProviderCompletion(params: IProviderCompletionParams): Promise<Result<IAiCompletionResponse>>;
373
+ declare function callProviderCompletionStream(params: IProviderCompletionStreamParams): Promise<Result<AsyncIterable<IAiStreamEvent>>>;
374
+
375
+ /**
376
+ * Calls the appropriate image-generation API for a given provider.
377
+ * Routes by the `format` field of the resolved {@link IAiImageModelCapability}:
378
+ * `'openai-images'`, `'xai-images'`, `'xai-images-edits'`, `'gemini-imagen'`,
379
+ * or `'gemini-image-out'`. Rejects up front if `referenceImages` is set but the
380
+ * capability does not declare `acceptsImageReferenceInput`.
381
+ * @param params - Request parameters including descriptor, API key, and prompt
382
+ * @returns The generated images, or a failure
383
+ * @public
384
+ */
385
+ declare function callProviderImageGeneration(params: IProviderImageGenerationParams): Promise<Result<IAiImageGenerationResponse>>;
386
+
387
+ /**
388
+ * Lists models available from a provider, routing by `descriptor.apiFormat`.
389
+ * Capabilities are resolved from native provider info and a configurable rule set.
390
+ * @param params - Request parameters including descriptor, API key, and optional capability filter
391
+ * @returns The resolved model list, or a failure
392
+ * @public
393
+ */
394
+ declare function callProviderListModels(params: IProviderListModelsParams): Promise<Result<ReadonlyArray<IAiModelInfo>>>;
181
395
 
182
396
  /**
183
397
  * Calls the AI completion endpoint on a proxy server instead of calling
@@ -194,6 +408,53 @@ declare function callProviderCompletion(params: IProviderCompletionParams): Prom
194
408
  */
195
409
  declare function callProxiedCompletion(proxyUrl: string, params: IProviderCompletionParams): Promise<Result<IAiCompletionResponse>>;
196
410
 
411
+ /**
412
+ * Calls the streaming chat endpoint on a proxy server instead of calling
413
+ * the provider directly from the browser.
414
+ *
415
+ * @remarks
416
+ * Proxy contract:
417
+ * - Endpoint: `POST ${proxyUrl}/api/ai/completion-stream`
418
+ * - Request body: same JSON as `/api/ai/completion` plus `"stream": true`
419
+ * - Response: `Content-Type: text/event-stream`; body is the unified
420
+ * {@link AiAssist.IAiStreamEvent} JSON-serialized one event per SSE `data:` line
421
+ * (no `event:` line needed since the type discriminator is in the JSON).
422
+ * - Error response (when the proxy can't even start): JSON `{error: string}`
423
+ * with a non-2xx status, surfaced as `proxy: ${error}`.
424
+ *
425
+ * The proxy server is responsible for opening the upstream SSE connection,
426
+ * translating provider-native events to the unified vocabulary, and
427
+ * forwarding events as they arrive (no buffering). The library does not
428
+ * ship a proxy implementation.
429
+ *
430
+ * @public
431
+ */
432
+ declare function callProxiedCompletionStream(proxyUrl: string, params: IProviderCompletionStreamParams): Promise<Result<AsyncIterable<IAiStreamEvent>>>;
433
+
434
+ /**
435
+ * Calls the image-generation endpoint on a proxy server instead of calling
436
+ * the provider API directly from the browser.
437
+ * Endpoint: `POST ${proxyUrl}/api/ai/image-generation`. Request body:
438
+ * `{providerId, apiKey, params, modelOverride?}`. The proxy handles descriptor
439
+ * lookup, model resolution, provider dispatch, and response normalization
440
+ * (including repackaging `referenceImages` for the upstream wire format).
441
+ * Error body `{error: string}` is surfaced as `proxy: ${error}`.
442
+ * @param proxyUrl - Base URL of the proxy server (e.g. `http://localhost:3001`)
443
+ * @param params - Same parameters as {@link callProviderImageGeneration}
444
+ * @returns The generated images, or a failure
445
+ * @public
446
+ */
447
+ declare function callProxiedImageGeneration(proxyUrl: string, params: IProviderImageGenerationParams): Promise<Result<IAiImageGenerationResponse>>;
448
+
449
+ /**
450
+ * Calls the model-listing endpoint on a proxy server.
451
+ * Endpoint: `POST ${proxyUrl}/api/ai/list-models`. Capability config is not
452
+ * forwarded. `capabilities` is serialized as a string array. Error body
453
+ * `{error: string}` is surfaced as `proxy: ${error}`.
454
+ * @public
455
+ */
456
+ declare function callProxiedListModels(proxyUrl: string, params: IProviderListModelsParams): Promise<Result<ReadonlyArray<IAiModelInfo>>>;
457
+
197
458
  declare namespace Constants {
198
459
  export {
199
460
  ENCRYPTED_FILE_FORMAT,
@@ -210,7 +471,8 @@ declare namespace Converters {
210
471
  extendedArrayOf,
211
472
  rangeTypeOf,
212
473
  rangeOf,
213
- isoDate
474
+ isoDate,
475
+ isoDateTime
214
476
  }
215
477
  }
216
478
  export { Converters }
@@ -219,6 +481,12 @@ declare namespace Converters_2 {
219
481
  export {
220
482
  keystoreFormat,
221
483
  keystoreSecretType,
484
+ keystoreSymmetricSecretType,
485
+ keystoreAsymmetricSecretType,
486
+ keyPairAlgorithm,
487
+ jsonWebKeyShape,
488
+ keystoreSymmetricEntryJson,
489
+ keystoreAsymmetricEntryJson,
222
490
  keystoreSecretEntryJson,
223
491
  keystoreVaultContents,
224
492
  keystoreFile
@@ -232,6 +500,8 @@ declare namespace Converters_3 {
232
500
  encryptedFileFormat,
233
501
  encryptedFileErrorMode,
234
502
  keyDerivationFunction,
503
+ pbkdf2KeyDerivationParams,
504
+ argon2idKeyDerivationParams,
235
505
  keyDerivationParams,
236
506
  base64String,
237
507
  uint8ArrayFromBase64,
@@ -271,6 +541,8 @@ declare namespace CryptoUtils {
271
541
  Converters_3 as Converters,
272
542
  DirectEncryptionProvider,
273
543
  IDirectEncryptionProviderParams,
544
+ IKeyPairAlgorithmParams,
545
+ keyPairAlgorithmParams,
274
546
  NodeCryptoProvider,
275
547
  nodeCryptoProvider,
276
548
  createEncryptedFile,
@@ -279,13 +551,29 @@ declare namespace CryptoUtils {
279
551
  ICreateEncryptedFileParams,
280
552
  toBase64,
281
553
  tryDecryptFile,
554
+ exportPublicKeyAsMultibaseSpki,
555
+ importPublicKeyFromMultibaseSpki,
556
+ multibaseBase64UrlDecode,
557
+ multibaseBase64UrlEncode,
558
+ HpkeProvider,
559
+ IHpkeSealResult,
282
560
  isEncryptedFile,
283
561
  EncryptionAlgorithm,
284
562
  EncryptedFileFormat,
285
563
  INamedSecret,
286
564
  IEncryptionResult,
565
+ KeyPairAlgorithm,
566
+ IWrapBytesOptions,
567
+ IWrappedBytes,
568
+ allKeyPairAlgorithms,
287
569
  KeyDerivationFunction,
570
+ IPbkdf2KeyDerivationParams,
571
+ IArgon2idKeyDerivationParams,
288
572
  IKeyDerivationParams,
573
+ IArgon2idParams,
574
+ ARGON2ID_OWASP_MIN,
575
+ ARGON2ID_PASSPHRASE,
576
+ IArgon2idProvider,
289
577
  IEncryptedFile,
290
578
  ICryptoProvider,
291
579
  IEncryptionProvider,
@@ -299,9 +587,9 @@ export { CryptoUtils }
299
587
  declare namespace Csv {
300
588
  export {
301
589
  parseCsvString,
590
+ readCsvFromTree,
302
591
  CsvOptions,
303
- readCsvFileSync,
304
- readCsvFromTree
592
+ readCsvFileSync
305
593
  }
306
594
  }
307
595
  export { Csv }
@@ -314,6 +602,18 @@ declare interface CsvOptions {
314
602
  delimiter?: string;
315
603
  }
316
604
 
605
+ /** Pixel dimension sizes accepted by dall-e-2. @public */
606
+ declare type DallE2Size = '256x256' | '512x512' | '1024x1024';
607
+
608
+ /** Quality values for dall-e-3. @public */
609
+ declare type DallE3Quality = 'standard' | 'hd';
610
+
611
+ /** Pixel dimension sizes accepted by dall-e-3. @public */
612
+ declare type DallE3Size = '1024x1024' | '1792x1024' | '1024x1792';
613
+
614
+ /** Model names in the DALL-E family. @public */
615
+ declare type DallEModelNames = 'dall-e-2' | 'dall-e-3';
616
+
317
617
  /**
318
618
  * Decrypts an {@link CryptoUtils.IEncryptedFile | encrypted file} and returns the JSON content.
319
619
  * @typeParam TPayload - Expected type of decrypted content
@@ -345,6 +645,16 @@ declare const DEFAULT_ALGORITHM: "AES-256-GCM";
345
645
  */
346
646
  declare const DEFAULT_KEYSTORE_ITERATIONS: number;
347
647
 
648
+ /**
649
+ * Default capability config used by `callProviderListModels` when callers
650
+ * don't supply their own. Patterns are intentionally narrow — false
651
+ * positives are worse than missing a model. Caller can override per call
652
+ * via {@link IProviderListModelsParams.capabilityConfig}.
653
+ *
654
+ * @public
655
+ */
656
+ declare const DEFAULT_MODEL_CAPABILITY_CONFIG: IAiModelCapabilityConfig;
657
+
348
658
  /**
349
659
  * Default {@link Experimental.RangeOfFormats | formats} to use for both
350
660
  * open-ended and complete {@link Experimental.RangeOf | RangeOf<T>}.
@@ -471,6 +781,20 @@ declare namespace Experimental {
471
781
  }
472
782
  export { Experimental }
473
783
 
784
+ /**
785
+ * Exports a public `CryptoKey` as a multibase base64url-encoded SPKI blob.
786
+ *
787
+ * The SPKI (SubjectPublicKeyInfo) format is the standard DER-encoded structure
788
+ * for public keys defined in RFC 5280, RFC 5480, and RFC 8410. It is
789
+ * algorithm-agnostic and suitable for storage and transmission.
790
+ *
791
+ * @param key - The `CryptoKey` to export. Must have `key.type === 'public'`.
792
+ * @param provider - The {@link CryptoUtils.ICryptoProvider} to use for the export operation.
793
+ * @returns `Success` with the multibase SPKI string, or `Failure` with error context.
794
+ * @public
795
+ */
796
+ declare function exportPublicKeyAsMultibaseSpki(key: CryptoKey, provider: ICryptoProvider): Promise<Result<string>>;
797
+
474
798
  /**
475
799
  * An experimental array template which extend built-in `Array` to include a handful
476
800
  * of predicates which return `Result<T>`.
@@ -532,11 +856,59 @@ declare class ExtendedArray<T> extends Array<T> {
532
856
  * If `onError` is `'failOnError'` (default), then the entire conversion fails if any element cannot
533
857
  * be converted. If `onError` is `'ignoreErrors'`, then failing elements are silently ignored.
534
858
  * @param converter - `Converter` used to convert each item in the array
535
- * @param ignoreErrors - Specifies treatment of unconvertible elements
859
+ * @param onError - Specifies treatment of unconvertible elements
536
860
  * @beta
537
861
  */
538
862
  declare function extendedArrayOf<T, TC = undefined>(label: string, converter: Converter<T, TC>, onError?: Conversion.OnError): Converter<ExtendedArray<T>, TC>;
539
863
 
864
+ /**
865
+ * Default {@link AiAssist.JsonTextExtractor | extractor} for LLM responses. Tolerates:
866
+ *
867
+ * - Leading/trailing whitespace and a leading byte-order mark.
868
+ * - Markdown code fences (with or without a language tag).
869
+ * - Conversational preamble before the first `{` or `[`.
870
+ * - Trailing prose after the matched closing `}` or `]`.
871
+ *
872
+ * Out of scope: repairing malformed JSON, handling smart quotes, etc.
873
+ *
874
+ * @param text - Raw model output.
875
+ * @returns A `Result<string>` containing the JSON-shaped substring, or a
876
+ * `Failure` if no JSON-shaped substring was found.
877
+ * @public
878
+ */
879
+ declare const extractJsonText: JsonTextExtractor;
880
+
881
+ /**
882
+ * Creates a `Converter` that accepts raw LLM response text, runs it through a
883
+ * tolerant extractor (default: {@link AiAssist.extractJsonText}), parses the
884
+ * extracted substring as JSON, and applies an optional inner converter or
885
+ * validator.
886
+ *
887
+ * @example
888
+ * ```ts
889
+ * const converter = fencedStringifiedJson({ inner: myShapeConverter });
890
+ * const result = converter.convert(llmText); // Result<MyShape>
891
+ * ```
892
+ *
893
+ * @param options - Optional extractor; omit to keep the default. Without an
894
+ * `inner` step, the converter resolves to the parsed `JsonValue`.
895
+ * @returns A `Converter<JsonValue>`.
896
+ * @public
897
+ */
898
+ declare function fencedStringifiedJson(options?: IFencedStringifiedJsonExtractorOptions): Converter<JsonValue>;
899
+
900
+ /**
901
+ * Creates a `Converter` that accepts raw LLM response text, runs it through a
902
+ * tolerant extractor (default: {@link AiAssist.extractJsonText}), parses the
903
+ * extracted substring as JSON, and applies the supplied inner converter or
904
+ * validator.
905
+ *
906
+ * @param options - Required `inner` converter/validator and optional extractor.
907
+ * @returns A `Converter<T>`.
908
+ * @public
909
+ */
910
+ declare function fencedStringifiedJson<T>(options: IFencedStringifiedJsonOptions<T>): Converter<T>;
911
+
540
912
  /**
541
913
  * Formats a list of items using the supplied template and formatter, one result
542
914
  * per output line.
@@ -628,6 +1000,36 @@ declare const GCM_AUTH_TAG_SIZE: number;
628
1000
  */
629
1001
  declare const GCM_IV_SIZE: number;
630
1002
 
1003
+ /** Model names in the Gemini Flash Image family. @public */
1004
+ declare type GeminiFlashImageModelNames = 'gemini-2.5-flash-image';
1005
+
1006
+ /**
1007
+ * Model IDs for Google Gemini thinking-capable models.
1008
+ * @public
1009
+ */
1010
+ declare type GeminiThinkingModelNames = 'gemini-2.5-pro' | 'gemini-2.5-flash' | 'gemini-2.5-flash-lite';
1011
+
1012
+ /**
1013
+ * Calls {@link AiAssist.callProviderCompletion}, then runs the response text
1014
+ * through a tolerant JSON converter (default:
1015
+ * {@link AiAssist.fencedStringifiedJson}) and the caller's
1016
+ * `converter`/`validator`. Returns the validated value plus the raw text and
1017
+ * underlying completion response for diagnostics.
1018
+ *
1019
+ * @remarks
1020
+ * The default smart prompt hint asks the model to emit raw JSON. The read-side
1021
+ * extractor still tolerates fences and prose, so models that ignore the hint
1022
+ * are still handled.
1023
+ *
1024
+ * Either `converter` or `jsonConverter` must be provided; passing both lets
1025
+ * `jsonConverter` win.
1026
+ *
1027
+ * @param params - Provider parameters plus JSON validation options.
1028
+ * @returns The validated value, the raw text, and the underlying response.
1029
+ * @public
1030
+ */
1031
+ declare function generateJsonCompletion<T>(params: IGenerateJsonCompletionParams<T>): Promise<Result<IGenerateJsonCompletionResult<T>>>;
1032
+
631
1033
  /**
632
1034
  * Get a provider descriptor by id.
633
1035
  * @param id - The provider identifier
@@ -643,6 +1045,18 @@ declare function getProviderDescriptor(id: string): Result<IAiProviderDescriptor
643
1045
  */
644
1046
  declare function getProviderDescriptors(): ReadonlyArray<IAiProviderDescriptor>;
645
1047
 
1048
+ /** Model names in the GPT Image family. @public */
1049
+ declare type GptImageModelNames = 'gpt-image-1';
1050
+
1051
+ /** Quality values for gpt-image-1. @public */
1052
+ declare type GptImageQuality = 'low' | 'medium' | 'high' | 'auto';
1053
+
1054
+ /** Pixel dimension sizes accepted by gpt-image-1. @public */
1055
+ declare type GptImageSize = '1024x1024' | '1536x1024' | '1024x1536' | 'auto';
1056
+
1057
+ /** Model names in the xAI Grok Imagine family. @public */
1058
+ declare type GrokImagineModelNames = 'grok-imagine-image' | 'grok-imagine-image-quality';
1059
+
646
1060
  declare namespace Hash {
647
1061
  export {
648
1062
  Md5Normalizer
@@ -650,6 +1064,191 @@ declare namespace Hash {
650
1064
  }
651
1065
  export { Hash }
652
1066
 
1067
+ /**
1068
+ * HPKE base mode (RFC 9180) — `DHKEM(X25519, HKDF-SHA256) + HKDF-SHA256 + AES-256-GCM`.
1069
+ *
1070
+ * Class-based provider that captures a `SubtleCrypto` instance at construction,
1071
+ * matching the existing `NodeCryptoProvider` / `BrowserCryptoProvider` / `KeyStore`
1072
+ * factory pattern used throughout `@fgv/ts-extras/crypto-utils`.
1073
+ *
1074
+ * **Node.js usage:**
1075
+ * ```typescript
1076
+ * import * as crypto from 'crypto';
1077
+ * const hpke = HpkeProvider.create(crypto.webcrypto.subtle).orThrow();
1078
+ * ```
1079
+ *
1080
+ * **Browser usage:**
1081
+ * ```typescript
1082
+ * const hpke = HpkeProvider.create(globalThis.crypto.subtle).orThrow();
1083
+ * ```
1084
+ *
1085
+ * **Runtime requirements:** Node.js 20+ (X25519 in `crypto.webcrypto`);
1086
+ * Chrome 113+, Safari 16.4+, Firefox 118+ (X25519 added to Web Crypto in 2023).
1087
+ * @public
1088
+ */
1089
+ declare class HpkeProvider {
1090
+ private readonly _subtle;
1091
+ private constructor();
1092
+ /**
1093
+ * Creates an `HpkeProvider` bound to the given `SubtleCrypto` instance.
1094
+ *
1095
+ * @param subtle - Web Crypto SubtleCrypto instance.
1096
+ * Node.js: `(await import('crypto')).webcrypto.subtle`.
1097
+ * Browser: `globalThis.crypto.subtle`.
1098
+ * @returns `Success` with the provider, or `Failure` if construction fails.
1099
+ */
1100
+ static create(subtle: SubtleCrypto): Result<HpkeProvider>;
1101
+ /**
1102
+ * HPKE base-mode seal (sender side). RFC 9180 §6.1.
1103
+ *
1104
+ * Generates a fresh ephemeral X25519 keypair, runs DHKEM Encap to produce a
1105
+ * shared secret and `enc` (32-byte raw ephemeral public key), derives the AEAD
1106
+ * key and nonce deterministically via the RFC 9180 key schedule, then encrypts
1107
+ * `plaintext` with AES-256-GCM.
1108
+ *
1109
+ * @param recipientPublicKey - Recipient's X25519 public `CryptoKey`
1110
+ * (`algorithm.name === 'X25519'`, `type === 'public'`, **`extractable: true`**).
1111
+ * Must be extractable — DHKEM Encap calls `exportKey('raw', ...)` on this key to
1112
+ * build the KEM shared-secret context. Keys imported with `extractable: false` will
1113
+ * cause this method to return a `Failure`.
1114
+ * @param info - Context-binding bytes. **Load-bearing — no default.**
1115
+ * Binds this ciphertext to a specific application context, preventing replay
1116
+ * across different contexts sharing the same recipient keypair.
1117
+ * Use `new TextEncoder().encode('myapp/v1/use-case\x00' + contextId)` pattern.
1118
+ * Never pass an empty array in production: empty `info` provides no context binding.
1119
+ * @param aad - Additional authenticated data. Integrity-protected but not encrypted.
1120
+ * `new Uint8Array(0)` is valid when no AAD is needed.
1121
+ * @param plaintext - Bytes to encrypt. `new Uint8Array(0)` is valid.
1122
+ * @returns `Success` with `{ enc, ciphertext }`, or `Failure` with error context.
1123
+ */
1124
+ sealBase(recipientPublicKey: CryptoKey, info: Uint8Array, aad: Uint8Array, plaintext: Uint8Array): Promise<Result<IHpkeSealResult>>;
1125
+ /**
1126
+ * HPKE base-mode open (recipient side). RFC 9180 §6.1.
1127
+ *
1128
+ * Decapsulates `enc` using the recipient's X25519 private key, derives the same
1129
+ * AEAD key and nonce from the shared secret and `info`, then authenticates and
1130
+ * decrypts `ciphertext` with AES-256-GCM.
1131
+ *
1132
+ * Returns `Failure` on any of:
1133
+ * - Wrong private key (different DH output → different key derivation)
1134
+ * - Wrong `info` (different key schedule context → different AEAD key)
1135
+ * - Wrong `aad` (AES-GCM authentication fails)
1136
+ * - Tampered `ciphertext` or `enc` (authentication fails or DH fails)
1137
+ * - `enc` not exactly 32 bytes
1138
+ * - `ciphertext` shorter than 16 bytes (no room for authentication tag)
1139
+ *
1140
+ * @param recipientPrivateKey - Recipient's X25519 private `CryptoKey`
1141
+ * (`algorithm.name === 'X25519'`, `type === 'private'`, `usages` includes `'deriveBits'`).
1142
+ * **Must be extractable** (`extractable: true`) — the recipient's public key bytes
1143
+ * are recovered from the JWK `x` field during Decap.
1144
+ * @param info - Context-binding bytes. Must exactly match `info` from `sealBase`.
1145
+ * @param aad - Must exactly match `aad` from `sealBase`.
1146
+ * @param enc - The encapsulated key from `sealBase` — exactly 32 bytes.
1147
+ * @param ciphertext - The ciphertext from `sealBase` — `plaintext.length + 16` bytes.
1148
+ * @returns `Success` with decrypted plaintext bytes, or `Failure` with error context.
1149
+ */
1150
+ openBase(recipientPrivateKey: CryptoKey, info: Uint8Array, aad: Uint8Array, enc: Uint8Array, ciphertext: Uint8Array): Promise<Result<Uint8Array>>;
1151
+ /**
1152
+ * HKDF-SHA256 key derivation (RFC 5869). Extract-then-Expand using SHA-256.
1153
+ *
1154
+ * This is raw RFC 5869 HKDF — it does **not** use RFC 9180's labeled variants.
1155
+ * The HPKE key schedule internally uses labeled HKDF; this method is the unlabeled
1156
+ * version for callers that need standalone key derivation.
1157
+ *
1158
+ * @param secret - Input keying material (IKM). Any length.
1159
+ * @param salt - Optional salt. Use `new Uint8Array(0)` if no salt is available
1160
+ * (RFC 5869: 32 zero bytes are used internally when salt is empty).
1161
+ * @param info - Context / application-binding bytes. Any length.
1162
+ * @param length - Number of output bytes to derive. Maximum 8160 bytes (255 × 32).
1163
+ * @returns `Success` with derived bytes, or `Failure` with error context.
1164
+ */
1165
+ hkdf(secret: Uint8Array, salt: Uint8Array, info: Uint8Array, length: number): Promise<Result<Uint8Array>>;
1166
+ /**
1167
+ * Encodes an {@link IHpkeSealResult} as a single contiguous byte array for wire transport.
1168
+ *
1169
+ * Format: `enc` (32 bytes, fixed) || `ciphertext` (variable length).
1170
+ * The 32-byte `enc` length is fixed for X25519; the split point is unambiguous.
1171
+ *
1172
+ * @param result - The output of {@link HpkeProvider.sealBase}.
1173
+ * @returns Concatenated bytes: `enc || ciphertext`.
1174
+ */
1175
+ static encodeEnvelope(result: IHpkeSealResult): Uint8Array;
1176
+ /**
1177
+ * Decodes an envelope produced by {@link HpkeProvider.encodeEnvelope}.
1178
+ *
1179
+ * Validates that the buffer is at least 48 bytes (32-byte enc + 16-byte minimum
1180
+ * ciphertext containing the AES-GCM auth tag; zero-length plaintext is the minimum
1181
+ * meaningful case).
1182
+ *
1183
+ * @param envelope - Envelope bytes from `encodeEnvelope`.
1184
+ * @returns `Success` with `{ enc, ciphertext }`, or `Failure` if malformed.
1185
+ */
1186
+ static decodeEnvelope(envelope: Uint8Array): Result<IHpkeSealResult>;
1187
+ }
1188
+
1189
+ /**
1190
+ * Options for adding an asymmetric keypair to the key store.
1191
+ * @public
1192
+ */
1193
+ declare interface IAddKeyPairOptions {
1194
+ /**
1195
+ * Algorithm to use for the new keypair.
1196
+ */
1197
+ readonly algorithm: KeyPairAlgorithm;
1198
+ /**
1199
+ * Optional description for the entry.
1200
+ */
1201
+ readonly description?: string;
1202
+ /**
1203
+ * Whether to replace an existing entry with the same name.
1204
+ * Replacement mints a fresh storage `id` and best-effort deletes the
1205
+ * displaced storage blob; see the keystore design doc for details.
1206
+ */
1207
+ readonly replace?: boolean;
1208
+ }
1209
+
1210
+ /**
1211
+ * Result of adding an asymmetric keypair to the key store.
1212
+ * @public
1213
+ */
1214
+ declare interface IAddKeyPairResult {
1215
+ /**
1216
+ * The asymmetric entry that was added.
1217
+ */
1218
+ readonly entry: IKeyStoreAsymmetricEntry;
1219
+ /**
1220
+ * Whether this replaced an existing entry.
1221
+ */
1222
+ readonly replaced: boolean;
1223
+ /**
1224
+ * Best-effort warning from displaced-resource cleanup. Set when this call
1225
+ * replaced a prior entry but the corresponding
1226
+ * {@link CryptoUtils.KeyStore.IPrivateKeyStorage}.delete failed; the new
1227
+ * keypair is still committed and the orphaned blob is left for consumer-side
1228
+ * GC to reconcile.
1229
+ */
1230
+ readonly warning?: string;
1231
+ }
1232
+
1233
+ /**
1234
+ * Options for adding an Argon2id password-derived secret.
1235
+ * @public
1236
+ */
1237
+ declare interface IAddSecretFromPasswordArgon2idOptions {
1238
+ /**
1239
+ * Argon2id parameters. Defaults to {@link CryptoUtils.ARGON2ID_OWASP_MIN}.
1240
+ */
1241
+ readonly params?: IArgon2idParams;
1242
+ /**
1243
+ * Optional description for the secret.
1244
+ */
1245
+ readonly description?: string;
1246
+ /**
1247
+ * Whether to replace an existing secret with the same name.
1248
+ */
1249
+ readonly replace?: boolean;
1250
+ }
1251
+
653
1252
  /**
654
1253
  * Options for adding a secret derived from a password.
655
1254
  * @public
@@ -700,11 +1299,19 @@ declare interface IAddSecretResult {
700
1299
  /**
701
1300
  * The secret entry that was added.
702
1301
  */
703
- readonly entry: IKeyStoreSecretEntry;
1302
+ readonly entry: IKeyStoreSymmetricEntry;
704
1303
  /**
705
1304
  * Whether this replaced an existing secret.
706
1305
  */
707
1306
  readonly replaced: boolean;
1307
+ /**
1308
+ * Best-effort warning from displaced-resource cleanup. Set when this call
1309
+ * replaced an asymmetric-keypair entry but the corresponding
1310
+ * {@link CryptoUtils.KeyStore.IPrivateKeyStorage}.delete failed; the new
1311
+ * entry is still committed and the orphaned blob is left for consumer-side
1312
+ * GC to reconcile.
1313
+ */
1314
+ readonly warning?: string;
708
1315
  }
709
1316
 
710
1317
  /**
@@ -734,6 +1341,14 @@ declare interface IAiAssistProviderConfig {
734
1341
  readonly model?: ModelSpec;
735
1342
  /** Tool enablement/configuration. Tools are disabled unless explicitly enabled. */
736
1343
  readonly tools?: ReadonlyArray<IAiToolEnablement>;
1344
+ /**
1345
+ * Optional caller-supplied endpoint URL (http/https). Overrides
1346
+ * `descriptor.baseUrl` for this provider. Used to point a provider at a
1347
+ * self-hosted server (Ollama, LM Studio, llama.cpp's openai-server) or a
1348
+ * local proxy. Validation lives in `@fgv/ts-extras` — query strings,
1349
+ * fragments, and userinfo are rejected.
1350
+ */
1351
+ readonly endpoint?: string;
737
1352
  }
738
1353
 
739
1354
  /**
@@ -763,46 +1378,372 @@ declare interface IAiCompletionResponse {
763
1378
  }
764
1379
 
765
1380
  /**
766
- * Describes a single AI provider — single source of truth for all metadata.
1381
+ * A single generated image.
767
1382
  * @public
768
1383
  */
769
- declare interface IAiProviderDescriptor {
770
- /** Provider identifier (e.g. 'xai-grok', 'anthropic') */
771
- readonly id: AiProviderId;
772
- /** Human-readable label (e.g. "xAI Grok") */
773
- readonly label: string;
774
- /** Button label for action buttons (e.g. "AI Assist | Grok") */
775
- readonly buttonLabel: string;
776
- /** Whether this provider requires an API key secret */
777
- readonly needsSecret: boolean;
778
- /** Which API adapter format to use */
779
- readonly apiFormat: AiApiFormat;
780
- /** Base URL for the API (e.g. 'https://api.x.ai/v1') */
781
- readonly baseUrl: string;
782
- /** Default model specification — string or context-aware map. */
783
- readonly defaultModel: ModelSpec;
784
- /** Which server-side tools this provider supports (empty = none). */
785
- readonly supportedTools: ReadonlyArray<AiServerToolType>;
786
- /** Whether this provider's API enforces CORS restrictions that prevent direct browser calls. */
787
- readonly corsRestricted: boolean;
1384
+ declare interface IAiGeneratedImage extends IAiImageData {
1385
+ /**
1386
+ * The prompt as rewritten by the provider, if any. OpenAI's image models
1387
+ * commonly rewrite prompts; other providers do not.
1388
+ */
1389
+ readonly revisedPrompt?: string;
788
1390
  }
789
1391
 
790
1392
  /**
791
- * Declares a tool as enabled/disabled in provider settings.
792
- * Tools are disabled by default — consuming apps must opt in explicitly.
1393
+ * Image attachment for a vision (image-input) prompt.
1394
+ *
1395
+ * @remarks
1396
+ * Extends {@link IAiImageData} with an OpenAI-specific `detail` hint that is
1397
+ * silently ignored by Anthropic, Gemini, and other providers.
1398
+ *
793
1399
  * @public
794
1400
  */
795
- declare interface IAiToolEnablement {
796
- /** Which tool type. */
797
- readonly type: AiServerToolType;
798
- /** Whether this tool is enabled by default for this provider. */
799
- readonly enabled: boolean;
800
- /** Optional tool-specific configuration. */
801
- readonly config?: AiServerToolConfig;
1401
+ declare interface IAiImageAttachment extends IAiImageData {
1402
+ /**
1403
+ * OpenAI vision detail hint:
1404
+ * - `'low'`: faster, cheaper, lower fidelity
1405
+ * - `'high'`: slower, more expensive, higher fidelity
1406
+ * - `'auto'` (default): provider chooses
1407
+ *
1408
+ * Ignored by providers other than OpenAI.
1409
+ */
1410
+ readonly detail?: 'low' | 'high' | 'auto';
802
1411
  }
803
1412
 
804
1413
  /**
805
- * Configuration specific to web search tools.
1414
+ * Universal image representation used for both image input (vision prompts)
1415
+ * and image output (generation responses).
1416
+ *
1417
+ * @remarks
1418
+ * The base64 string is raw — no `data:` URL prefix. Use {@link AiAssist.toDataUrl} to
1419
+ * format it for browser-display contexts.
1420
+ *
1421
+ * @public
1422
+ */
1423
+ declare interface IAiImageData {
1424
+ /** MIME type, e.g. `'image/png'`, `'image/jpeg'`, `'image/webp'`. */
1425
+ readonly mimeType: string;
1426
+ /** Base64-encoded image bytes (no `data:` prefix). */
1427
+ readonly base64: string;
1428
+ }
1429
+
1430
+ /**
1431
+ * Options for image generation requests.
1432
+ *
1433
+ * @remarks
1434
+ * Uses a layered architecture:
1435
+ * 1. Generic top-level options (size, count, quality, seed) apply across providers
1436
+ * via the resolved model's registry mapping.
1437
+ * 2. Optional `models` array contains model-family-scoped blocks; the resolver
1438
+ * picks applicable blocks based on the resolved model and applies them in
1439
+ * declaration order.
1440
+ *
1441
+ * **Merge precedence (later wins):**
1442
+ * 1. Generic top-level options (lowest precedence)
1443
+ * 2. Family-generic blocks (matching family, models field omitted)
1444
+ * 3. Model-specific blocks (models array includes resolved model name)
1445
+ * 4. Other blocks (provider: 'other', models array includes resolved model name)
1446
+ *
1447
+ * Provider-mismatch: blocks whose provider doesn't match the dispatcher's
1448
+ * provider lineage are silently skipped.
1449
+ *
1450
+ * @public
1451
+ */
1452
+ declare interface IAiImageGenerationOptions {
1453
+ /**
1454
+ * Image dimensions for OpenAI models (mapped to `size` field).
1455
+ * For xAI aspect ratio or Imagen aspect ratio, use the corresponding `models` family block.
1456
+ */
1457
+ readonly size?: AiImageSize;
1458
+ /** Number of images. Default 1. Some models enforce a maximum. */
1459
+ readonly count?: number;
1460
+ /**
1461
+ * Quality tier. Accepted values differ per model:
1462
+ * - dall-e-3: 'standard' | 'hd'
1463
+ * - gpt-image-1: 'low' | 'medium' | 'high' | 'auto'
1464
+ * Other models ignore this field.
1465
+ */
1466
+ readonly quality?: AiImageQuality;
1467
+ /** Reproducibility seed, where supported. */
1468
+ readonly seed?: number;
1469
+ /**
1470
+ * Optional precision via model-family-scoped blocks. The resolver picks
1471
+ * applicable blocks dynamically based on the resolved model.
1472
+ */
1473
+ readonly models?: ReadonlyArray<IModelFamilyConfig>;
1474
+ }
1475
+
1476
+ /**
1477
+ * Parameters for an image-generation request.
1478
+ * @public
1479
+ */
1480
+ declare interface IAiImageGenerationParams {
1481
+ /** The text prompt describing the desired image. */
1482
+ readonly prompt: string;
1483
+ /** Optional generation options. */
1484
+ readonly options?: IAiImageGenerationOptions;
1485
+ /**
1486
+ * Optional reference images. When present, the provider will use them as
1487
+ * visual context (e.g. to preserve a character's appearance across multiple
1488
+ * generations). The dispatcher resolves the
1489
+ * {@link AiAssist.IAiImageModelCapability} for the requested model and
1490
+ * rejects the call up front if `acceptsImageReferenceInput` is not set on
1491
+ * the matching capability. An empty array is treated identically to
1492
+ * `undefined`.
1493
+ */
1494
+ readonly referenceImages?: ReadonlyArray<IAiImageAttachment>;
1495
+ }
1496
+
1497
+ /**
1498
+ * Result of an image-generation call.
1499
+ * @public
1500
+ */
1501
+ declare interface IAiImageGenerationResponse {
1502
+ /** The generated images, in provider-returned order. */
1503
+ readonly images: ReadonlyArray<IAiGeneratedImage>;
1504
+ }
1505
+
1506
+ /**
1507
+ * Image-generation capability for a model family within a provider. Used as
1508
+ * an entry in {@link IAiProviderDescriptor.imageGeneration}.
1509
+ *
1510
+ * @public
1511
+ */
1512
+ declare interface IAiImageModelCapability {
1513
+ /**
1514
+ * Prefix matched against the resolved image model id. The empty string is
1515
+ * the catch-all and matches every model. When multiple rules' prefixes
1516
+ * match a model id, the longest prefix wins; ties are broken by
1517
+ * first-encountered.
1518
+ */
1519
+ readonly modelPrefix: string;
1520
+ /** API format used to dispatch requests for matching models. */
1521
+ readonly format: AiImageApiFormat;
1522
+ /**
1523
+ * Whether matching models accept reference images via
1524
+ * {@link AiAssist.IAiImageGenerationParams.referenceImages}. When false or
1525
+ * undefined, calls that include reference images are rejected up front.
1526
+ */
1527
+ readonly acceptsImageReferenceInput?: boolean;
1528
+ /** Accepted size strings. When present, dispatcher pre-validates. */
1529
+ readonly acceptedSizes?: ReadonlyArray<string>;
1530
+ /** When true, quality param is sent. When false/undefined, don't send quality. */
1531
+ readonly supportsQualityParam?: boolean;
1532
+ /** Accepted quality values when supportsQualityParam is true. */
1533
+ readonly acceptedQualities?: ReadonlyArray<string>;
1534
+ /** Maximum count (n). When present, dispatcher pre-validates. */
1535
+ readonly maxCount?: number;
1536
+ /**
1537
+ * How to encode the output format on the wire:
1538
+ * - 'response-format': send response_format: 'b64_json' (dall-e-2, dall-e-3)
1539
+ * - 'output-format': send output_format (gpt-image-1)
1540
+ * - 'none': send neither (Imagen, Gemini Flash)
1541
+ */
1542
+ readonly outputParamStyle?: 'response-format' | 'output-format' | 'none';
1543
+ /** Default MIME type for response images. */
1544
+ readonly defaultOutputMimeType?: string;
1545
+ }
1546
+
1547
+ /**
1548
+ * Configuration that maps model id patterns to capabilities. Used to
1549
+ * augment (or, where the provider supplies no capability info, fully
1550
+ * derive) the capability set for each listed model.
1551
+ * @public
1552
+ */
1553
+ declare interface IAiModelCapabilityConfig {
1554
+ /** Per-provider rules. Tried before {@link AiAssist.IAiModelCapabilityConfig.global}. */
1555
+ readonly perProvider?: {
1556
+ readonly [P in AiProviderId]?: ReadonlyArray<IAiModelCapabilityRule>;
1557
+ };
1558
+ /** Cross-provider fallback rules. */
1559
+ readonly global?: ReadonlyArray<IAiModelCapabilityRule>;
1560
+ }
1561
+
1562
+ /**
1563
+ * One rule in an {@link IAiModelCapabilityConfig}. Multiple rules can match
1564
+ * a single model — their capability arrays are unioned.
1565
+ * @public
1566
+ */
1567
+ declare interface IAiModelCapabilityRule {
1568
+ /** RegExp tested against the model id (using `.test`). */
1569
+ readonly idPattern: RegExp;
1570
+ /** Capabilities this rule attributes to matching models. */
1571
+ readonly capabilities: ReadonlyArray<AiModelCapability>;
1572
+ /**
1573
+ * Friendly display-name override for matching models. The function form
1574
+ * lets one rule format many ids (e.g. `(id) => id.toUpperCase()`).
1575
+ * If multiple matching rules supply `displayName`, the first match wins.
1576
+ */
1577
+ readonly displayName?: string | ((id: string) => string);
1578
+ }
1579
+
1580
+ /**
1581
+ * Information about a single model returned by a provider's list endpoint,
1582
+ * with capabilities already resolved (native + config rules).
1583
+ * @public
1584
+ */
1585
+ declare interface IAiModelInfo {
1586
+ /** Provider-native model identifier. */
1587
+ readonly id: string;
1588
+ /** Resolved capability set — union of native declarations and config rules. */
1589
+ readonly capabilities: ReadonlySet<AiModelCapability>;
1590
+ /** Friendly name for display, when known. */
1591
+ readonly displayName?: string;
1592
+ }
1593
+
1594
+ /**
1595
+ * Describes a single AI provider — single source of truth for all metadata.
1596
+ * @public
1597
+ */
1598
+ declare interface IAiProviderDescriptor {
1599
+ /** Provider identifier (e.g. 'xai-grok', 'anthropic') */
1600
+ readonly id: AiProviderId;
1601
+ /** Human-readable label (e.g. "xAI Grok") */
1602
+ readonly label: string;
1603
+ /** Button label for action buttons (e.g. "AI Assist | Grok") */
1604
+ readonly buttonLabel: string;
1605
+ /** Whether this provider requires an API key secret */
1606
+ readonly needsSecret: boolean;
1607
+ /** Which API adapter format to use */
1608
+ readonly apiFormat: AiApiFormat;
1609
+ /** Base URL for the API (e.g. 'https://api.x.ai/v1') */
1610
+ readonly baseUrl: string;
1611
+ /** Default model specification — string or context-aware map. */
1612
+ readonly defaultModel: ModelSpec;
1613
+ /** Which server-side tools this provider supports (empty = none). */
1614
+ readonly supportedTools: ReadonlyArray<AiServerToolType>;
1615
+ /** Whether this provider's API enforces CORS restrictions that prevent direct browser calls. */
1616
+ readonly corsRestricted: boolean;
1617
+ /**
1618
+ * Whether this provider's streaming completion endpoint requires a proxy
1619
+ * for direct browser calls. Some providers gate streaming separately from
1620
+ * non-streaming (rare), so this is tracked independently from
1621
+ * {@link IAiProviderDescriptor.corsRestricted}.
1622
+ *
1623
+ * @remarks
1624
+ * When `true`, `callProviderCompletionStream` rejects up front unless the
1625
+ * call is being routed through a proxy.
1626
+ */
1627
+ readonly streamingCorsRestricted: boolean;
1628
+ /**
1629
+ * Whether this provider's chat completions API accepts image input
1630
+ * (i.e. supports vision prompts). When false, calls with
1631
+ * `prompt.attachments` are rejected up front.
1632
+ */
1633
+ readonly acceptsImageInput: boolean;
1634
+ /**
1635
+ * Whether this provider supports thinking/reasoning mode.
1636
+ * - 'optional': thinking can be enabled but is not required
1637
+ * - 'required': thinking is always active (e.g. o-series models)
1638
+ * - 'unsupported': thinking is not supported
1639
+ */
1640
+ readonly thinkingMode: AiThinkingMode;
1641
+ /**
1642
+ * Image-generation capabilities, scoped to model id prefixes. Empty or
1643
+ * undefined means the provider does not support image generation.
1644
+ *
1645
+ * @remarks
1646
+ * The dispatcher matches the resolved model id against each rule's
1647
+ * `modelPrefix` and selects the longest match (see
1648
+ * {@link AiAssist.resolveImageCapability}). An empty `modelPrefix` is the
1649
+ * catch-all and matches every model id.
1650
+ *
1651
+ * Multiple entries support providers that host more than one image-API
1652
+ * surface under one baseUrl. Google Gemini is the canonical case: the
1653
+ * `imagen-*` family is predict-only via `:predict`, while
1654
+ * `gemini-2.5-flash-image` uses chat-style `:generateContent` and accepts
1655
+ * reference images. Listing both lets callers pick the right model and the
1656
+ * dispatcher routes accordingly.
1657
+ *
1658
+ * Image-model selection reuses the existing `image` {@link ModelSpecKey}.
1659
+ * Providers that declare `imageGeneration` should declare a model in
1660
+ * `defaultModel.image`, e.g. `{ base: 'gpt-4o', image: 'dall-e-3' }`.
1661
+ */
1662
+ readonly imageGeneration?: ReadonlyArray<IAiImageModelCapability>;
1663
+ }
1664
+
1665
+ /**
1666
+ * Terminal success event for a streaming completion. Carries the aggregated
1667
+ * full text and truncation status for callers that want both the progressive
1668
+ * UI and the complete result.
1669
+ * @public
1670
+ */
1671
+ declare interface IAiStreamDone {
1672
+ readonly type: 'done';
1673
+ /** Whether the response was truncated due to token limits. */
1674
+ readonly truncated: boolean;
1675
+ /** The full concatenated text from all `text-delta` events. */
1676
+ readonly fullText: string;
1677
+ }
1678
+
1679
+ /**
1680
+ * Terminal failure event for a streaming completion. After this event no
1681
+ * further events are emitted.
1682
+ *
1683
+ * @remarks
1684
+ * Connection-time failures (auth, network, pre-flight CORS rejection) are
1685
+ * surfaced via the outer `Result.fail` returned by
1686
+ * `callProviderCompletionStream` rather than as an `error` event, so callers
1687
+ * can distinguish "didn't start" from "started but errored mid-stream."
1688
+ *
1689
+ * @public
1690
+ */
1691
+ declare interface IAiStreamError {
1692
+ readonly type: 'error';
1693
+ readonly message: string;
1694
+ }
1695
+
1696
+ /**
1697
+ * Discriminated union of events emitted by a streaming completion.
1698
+ * @public
1699
+ */
1700
+ declare type IAiStreamEvent = IAiStreamTextDelta | IAiStreamToolEvent | IAiStreamDone | IAiStreamError;
1701
+
1702
+ /**
1703
+ * A text-content delta arriving during a streaming completion.
1704
+ * @public
1705
+ */
1706
+ declare interface IAiStreamTextDelta {
1707
+ readonly type: 'text-delta';
1708
+ /** The newly arrived text fragment. */
1709
+ readonly delta: string;
1710
+ }
1711
+
1712
+ /**
1713
+ * A server-side tool progress event arriving during a streaming completion.
1714
+ * Surfaced for providers that emit explicit tool-progress markers (OpenAI
1715
+ * Responses API, Anthropic). Gemini's grounding doesn't emit these.
1716
+ * @public
1717
+ */
1718
+ declare interface IAiStreamToolEvent {
1719
+ readonly type: 'tool-event';
1720
+ /** Which server-side tool this event describes. */
1721
+ readonly toolType: AiServerToolType;
1722
+ /** Tool lifecycle phase. */
1723
+ readonly phase: 'started' | 'completed';
1724
+ /**
1725
+ * Optional provider-specific detail. For web_search this is typically the
1726
+ * search query when available; format varies by provider.
1727
+ */
1728
+ readonly detail?: string;
1729
+ }
1730
+
1731
+ /**
1732
+ * Declares a tool as enabled/disabled in provider settings.
1733
+ * Tools are disabled by default — consuming apps must opt in explicitly.
1734
+ * @public
1735
+ */
1736
+ declare interface IAiToolEnablement {
1737
+ /** Which tool type. */
1738
+ readonly type: AiServerToolType;
1739
+ /** Whether this tool is enabled by default for this provider. */
1740
+ readonly enabled: boolean;
1741
+ /** Optional tool-specific configuration. */
1742
+ readonly config?: AiServerToolConfig;
1743
+ }
1744
+
1745
+ /**
1746
+ * Configuration specific to web search tools.
806
1747
  * @public
807
1748
  */
808
1749
  declare interface IAiWebSearchToolConfig {
@@ -821,6 +1762,104 @@ declare interface IAiWebSearchToolConfig {
821
1762
  readonly enableImageUnderstanding?: boolean;
822
1763
  }
823
1764
 
1765
+ /**
1766
+ * Anthropic-specific thinking configuration.
1767
+ * @public
1768
+ */
1769
+ declare interface IAnthropicThinkingConfig {
1770
+ /**
1771
+ * Anthropic effort level. Maps 1:1 to `output_config.effort` on the wire.
1772
+ * - 'low' | 'medium' | 'high': all thinking-capable models
1773
+ * - 'max': Opus 4.6 only
1774
+ */
1775
+ readonly effort?: 'low' | 'medium' | 'high' | 'max';
1776
+ }
1777
+
1778
+ /**
1779
+ * Anthropic-specific thinking options block.
1780
+ * @public
1781
+ */
1782
+ declare interface IAnthropicThinkingOptions {
1783
+ readonly provider: 'anthropic';
1784
+ readonly models?: ReadonlyArray<AnthropicThinkingModelNames>;
1785
+ readonly config: IAnthropicThinkingConfig;
1786
+ }
1787
+
1788
+ /**
1789
+ * Argon2id key derivation parameters (RFC 9106).
1790
+ * @public
1791
+ */
1792
+ declare interface IArgon2idKeyDerivationParams {
1793
+ /** Key derivation function discriminator. */
1794
+ readonly kdf: 'argon2id';
1795
+ /** Base64-encoded salt used for key derivation. */
1796
+ readonly salt: string;
1797
+ /** Memory cost in kibibytes. */
1798
+ readonly memoryKiB: number;
1799
+ /** Number of passes (time cost). */
1800
+ readonly iterations: number;
1801
+ /** Degree of parallelism. */
1802
+ readonly parallelism: number;
1803
+ }
1804
+
1805
+ /**
1806
+ * Parameters for Argon2id key derivation (RFC 9106).
1807
+ * All fields are required; fgv does not pick defaults silently.
1808
+ * @public
1809
+ */
1810
+ declare interface IArgon2idParams {
1811
+ /**
1812
+ * Memory cost in kibibytes (KiB).
1813
+ * OWASP 2023 minimum: 19456 (19 MiB). Stronger: 65536 (64 MiB).
1814
+ * Constraint: \>= 8.
1815
+ */
1816
+ readonly memoryKiB: number;
1817
+ /**
1818
+ * Number of passes (iterations / time cost).
1819
+ * OWASP 2023 minimum: 2. Range: \>= 1.
1820
+ */
1821
+ readonly iterations: number;
1822
+ /**
1823
+ * Degree of parallelism (threads).
1824
+ * Note: WASM-based implementations compute sequentially regardless of this value,
1825
+ * but the value is wired into the algorithm and AFFECTS the output hash bytes.
1826
+ * Callers must use the same parallelism value consistently for a given secret.
1827
+ * Range: 1–255.
1828
+ */
1829
+ readonly parallelism: number;
1830
+ /**
1831
+ * Number of output bytes (hash length).
1832
+ * Typical values: 16 (128-bit), 32 (256-bit, AES-256 key), 64 (512-bit).
1833
+ * Constraint: \>= 4.
1834
+ */
1835
+ readonly outputBytes: number;
1836
+ }
1837
+
1838
+ /**
1839
+ * Argon2id key derivation provider (RFC 9106).
1840
+ *
1841
+ * Implementations are in separate packages to avoid WASM bundle costs for
1842
+ * consumers who don't need Argon2id:
1843
+ * - Node: `@fgv/ts-extras-argon2` (`NodeArgon2Provider`)
1844
+ * - Browser: `@fgv/ts-web-extras-argon2` (`BrowserArgon2Provider`)
1845
+ *
1846
+ * @public
1847
+ */
1848
+ declare interface IArgon2idProvider {
1849
+ /**
1850
+ * Derives key material from a password using Argon2id (RFC 9106 §3.1).
1851
+ *
1852
+ * Returns the raw derived bytes as a `Uint8Array`. Both Node and browser
1853
+ * implementations produce bit-identical output for identical inputs.
1854
+ *
1855
+ * @param password - Password or passphrase. Accepts string (UTF-8) or raw bytes.
1856
+ * @param salt - Salt bytes. Must be random and unique per credential (\>= 16 bytes recommended).
1857
+ * @param params - Argon2id parameters. Use `ARGON2ID_OWASP_MIN` as a starting point.
1858
+ * @returns Success with derived bytes, Failure with error context.
1859
+ */
1860
+ argon2id(password: Uint8Array | string, salt: Uint8Array, params: IArgon2idParams): Promise<Result<Uint8Array>>;
1861
+ }
1862
+
824
1863
  /**
825
1864
  * A single chat message in OpenAI format.
826
1865
  * @public
@@ -937,12 +1976,27 @@ declare interface ICryptoProvider {
937
1976
  * @returns Success with derived 32-byte key, or Failure with error
938
1977
  */
939
1978
  deriveKey(password: string, salt: Uint8Array, iterations: number): Promise<Result<Uint8Array>>;
1979
+ /**
1980
+ * Computes a SHA-256 hash of the given data.
1981
+ * @param data - UTF-8 string to hash
1982
+ * @returns Success with hex-encoded hash string, or Failure with error
1983
+ */
1984
+ sha256(data: string): Promise<Result<string>>;
940
1985
  /**
941
1986
  * Generates cryptographically secure random bytes.
942
1987
  * @param length - Number of bytes to generate
943
1988
  * @returns Success with random bytes, or Failure with error
944
1989
  */
945
1990
  generateRandomBytes(length: number): Result<Uint8Array>;
1991
+ /**
1992
+ * Generates a cryptographically random UUIDv4 using the provider's
1993
+ * underlying source of randomness. The default Node and browser
1994
+ * implementations delegate to `globalThis.crypto.randomUUID`;
1995
+ * deterministic providers (e.g. test stubs) may override to produce
1996
+ * reproducible values.
1997
+ * @returns Success with a canonical UUID, or Failure with error.
1998
+ */
1999
+ generateUuid(): Result<Uuid>;
946
2000
  /**
947
2001
  * Encodes binary data to base64 string.
948
2002
  * @param data - Binary data to encode
@@ -955,6 +2009,191 @@ declare interface ICryptoProvider {
955
2009
  * @returns Success with decoded bytes, or Failure if invalid base64
956
2010
  */
957
2011
  fromBase64(base64: string): Result<Uint8Array>;
2012
+ /**
2013
+ * Generates a new asymmetric keypair for the requested algorithm.
2014
+ * @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} to use.
2015
+ * @param extractable - Whether the resulting `CryptoKey` objects may be exported.
2016
+ * Set `false` on backends that store `CryptoKey` references directly (e.g.
2017
+ * IndexedDB). Set `true` when the private key must round-trip through JWK or
2018
+ * PKCS#8 (e.g. encrypted-file backends).
2019
+ * @returns Success with the generated `CryptoKeyPair`, or Failure with error context.
2020
+ */
2021
+ generateKeyPair(algorithm: KeyPairAlgorithm, extractable: boolean): Promise<Result<CryptoKeyPair>>;
2022
+ /**
2023
+ * Exports the public half of a keypair as a JSON Web Key.
2024
+ * @param publicKey - The public `CryptoKey` to export. Must be an `extractable`
2025
+ * key generated for an asymmetric algorithm.
2026
+ * @returns Success with the JWK, or Failure with error context.
2027
+ */
2028
+ exportPublicKeyJwk(publicKey: CryptoKey): Promise<Result<JsonWebKey>>;
2029
+ /**
2030
+ * Re-imports a public-key JWK as a `CryptoKey` usable for verification or
2031
+ * encryption (depending on algorithm).
2032
+ * @param jwk - The JSON Web Key produced by {@link CryptoUtils.ICryptoProvider.exportPublicKeyJwk | exportPublicKeyJwk}.
2033
+ * @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} the
2034
+ * key was generated for. Determines the import parameters and key usages.
2035
+ * @returns Success with the imported public `CryptoKey`, or Failure with error context.
2036
+ */
2037
+ importPublicKeyJwk(jwk: JsonWebKey, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;
2038
+ /**
2039
+ * Exports a public `CryptoKey` as a DER-encoded SPKI (SubjectPublicKeyInfo) blob.
2040
+ * SPKI is the standard algorithm-agnostic format for public key storage and transport.
2041
+ * @param publicKey - The `CryptoKey` to export. Must have `key.type === 'public'`.
2042
+ * @returns `Success` with the raw SPKI bytes, or `Failure` with error context.
2043
+ */
2044
+ exportPublicKeySpki(publicKey: CryptoKey): Promise<Result<Uint8Array>>;
2045
+ /**
2046
+ * Imports a public key from a DER-encoded SPKI blob.
2047
+ * @param spkiBytes - The raw SPKI bytes produced by {@link CryptoUtils.ICryptoProvider.exportPublicKeySpki | exportPublicKeySpki}.
2048
+ * @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} the key was generated for.
2049
+ * @returns `Success` with the imported public `CryptoKey`, or `Failure` with error context.
2050
+ */
2051
+ importPublicKeySpki(spkiBytes: Uint8Array, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;
2052
+ /**
2053
+ * Wraps `plaintext` for delivery to the holder of the private key paired
2054
+ * with `recipientPublicKey`. Uses ECIES with ECDH P-256, HKDF-SHA256, and
2055
+ * AES-GCM-256.
2056
+ *
2057
+ * Generates a fresh ephemeral keypair per call; the ephemeral private key
2058
+ * is discarded after the shared-secret derive. Only the recipient (with the
2059
+ * matching private key) and the same HKDF parameters can recover
2060
+ * `plaintext`.
2061
+ *
2062
+ * Empty `plaintext` is permitted; the resulting wrap contains only the
2063
+ * 16-byte GCM authentication tag and round-trips back to an empty
2064
+ * `Uint8Array`.
2065
+ * @param plaintext - The bytes to wrap. Any length supported by AES-GCM
2066
+ * (in practice, well below 2^39 - 256 bits).
2067
+ * @param recipientPublicKey - The recipient's ECDH P-256 public `CryptoKey`.
2068
+ * Must have algorithm name `'ECDH'` and named curve `'P-256'`; mismatched
2069
+ * algorithm or curve yields a `Failure` with error context.
2070
+ * @param options - HKDF parameters; see {@link CryptoUtils.IWrapBytesOptions | IWrapBytesOptions}.
2071
+ * @returns `Success` with the wrapped payload, or `Failure` with error context.
2072
+ */
2073
+ wrapBytes(plaintext: Uint8Array, recipientPublicKey: CryptoKey, options: IWrapBytesOptions): Promise<Result<IWrappedBytes>>;
2074
+ /**
2075
+ * Inverse of {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes}.
2076
+ * Recovers the original `plaintext` from a wrapped payload using the
2077
+ * recipient's private key.
2078
+ *
2079
+ * Returns a `Failure` (never throws) on any of:
2080
+ * - Tampered nonce or ciphertext (AES-GCM authentication fails)
2081
+ * - Wrong private key (different shared secret derives a different wrap key)
2082
+ * - Wrong HKDF parameters (different wrap key)
2083
+ * - Malformed `ephemeralPublicKey` JWK
2084
+ * - Malformed base64 in `nonce` or `ciphertext`
2085
+ * @param wrapped - The wrapped payload produced by `wrapBytes`.
2086
+ * @param recipientPrivateKey - The recipient's ECDH P-256 private
2087
+ * `CryptoKey`. Must have algorithm name `'ECDH'` and named curve `'P-256'`,
2088
+ * and key usages including `'deriveKey'` or `'deriveBits'`.
2089
+ * @param options - The same HKDF parameters used at wrap time.
2090
+ * @returns `Success` with the original `plaintext`, or `Failure` with error context.
2091
+ */
2092
+ unwrapBytes(wrapped: IWrappedBytes, recipientPrivateKey: CryptoKey, options: IWrapBytesOptions): Promise<Result<Uint8Array>>;
2093
+ /**
2094
+ * Signs `data` with `privateKey` using the algorithm inferred from the key.
2095
+ * Delegates to `crypto.subtle.sign`; the algorithm is derived from
2096
+ * `privateKey.algorithm.name` — ECDSA keys are augmented with
2097
+ * `hash: 'SHA-256'` at sign time (the hash is not stored in the key);
2098
+ * all other algorithm names are passed through as-is.
2099
+ * Intended for Ed25519 and ECDSA-P256 asymmetric private keys; for
2100
+ * HMAC-SHA256 authentication codes use {@link ICryptoProvider.hmacSha256} instead.
2101
+ * @param privateKey - A `CryptoKey` with `'sign'` usage (e.g. generated by
2102
+ * {@link CryptoUtils.ICryptoProvider.generateKeyPair | generateKeyPair} with
2103
+ * `'ecdsa-p256'` or `'ed25519'`).
2104
+ * @param data - The bytes to sign.
2105
+ * @returns `Success` with the raw signature bytes, or `Failure` with error context.
2106
+ */
2107
+ sign(privateKey: CryptoKey, data: Uint8Array): Promise<Result<Uint8Array>>;
2108
+ /**
2109
+ * Verifies a signature produced by {@link ICryptoProvider.sign}.
2110
+ * Delegates to `crypto.subtle.verify`; the algorithm is derived from
2111
+ * `publicKey.algorithm.name` — ECDSA keys are augmented with
2112
+ * `hash: 'SHA-256'`; all other algorithm names are passed through as-is.
2113
+ * Intended for Ed25519 and ECDSA-P256 asymmetric public keys; for
2114
+ * HMAC-SHA256 verification use {@link ICryptoProvider.verifyHmacSha256} instead.
2115
+ * @param publicKey - A `CryptoKey` with `'verify'` usage (e.g. the public
2116
+ * half of a keypair generated by
2117
+ * {@link CryptoUtils.ICryptoProvider.generateKeyPair | generateKeyPair} with
2118
+ * `'ecdsa-p256'` or `'ed25519'`).
2119
+ * @param signature - The raw signature bytes produced by `sign`.
2120
+ * @param data - The original data that was signed.
2121
+ * @returns `Success` with `true` if the signature is valid, `false` if it is
2122
+ * not, or `Failure` with error context if the operation itself failed.
2123
+ */
2124
+ verify(publicKey: CryptoKey, signature: Uint8Array, data: Uint8Array): Promise<Result<boolean>>;
2125
+ /**
2126
+ * Compares two byte arrays in constant time.
2127
+ *
2128
+ * The comparison visits all bytes of `a` and `b` regardless of where they
2129
+ * diverge, accumulating XOR differences with bitwise-OR. No early-return is
2130
+ * possible once the length check passes, making timing independent of the
2131
+ * byte values. This prevents timing side-channels when comparing MAC outputs,
2132
+ * signed-token bytes, or any secret-derived byte sequences.
2133
+ *
2134
+ * Returns `false` immediately (before the loop) when `a.length !== b.length`;
2135
+ * the length mismatch itself is not secret in normal use.
2136
+ * @param a - First byte array.
2137
+ * @param b - Second byte array.
2138
+ * @returns `true` if the arrays have the same length and identical contents,
2139
+ * `false` otherwise.
2140
+ */
2141
+ timingSafeEqual(a: Uint8Array, b: Uint8Array): boolean;
2142
+ /**
2143
+ * Computes an HMAC-SHA256 authentication code for `data` using `key`.
2144
+ *
2145
+ * The key must be a `CryptoKey` with `'sign'` usage and algorithm name
2146
+ * `'HMAC'` (e.g. derived via PBKDF2 or imported with
2147
+ * `crypto.subtle.importKey`). Use {@link ICryptoProvider.verifyHmacSha256}
2148
+ * for constant-time verification of the output.
2149
+ * @param key - An HMAC `CryptoKey` with `'sign'` usage.
2150
+ * @param data - The bytes to authenticate.
2151
+ * @returns `Success` with the 32-byte MAC, or `Failure` with error context.
2152
+ */
2153
+ hmacSha256(key: CryptoKey, data: Uint8Array): Promise<Result<Uint8Array>>;
2154
+ /**
2155
+ * Verifies an HMAC-SHA256 authentication code in constant time.
2156
+ *
2157
+ * Computes the expected MAC over `data` with `key`, then compares it to
2158
+ * `signature` using {@link ICryptoProvider.timingSafeEqual} so that
2159
+ * mismatches do not leak information through timing.
2160
+ * @param key - An HMAC `CryptoKey` with `'sign'` usage.
2161
+ * @param signature - The MAC bytes to verify (typically 32 bytes).
2162
+ * @param data - The original data that was authenticated.
2163
+ * @returns `Success` with `true` if the MAC is valid, `false` if it is not,
2164
+ * or `Failure` with error context if the MAC computation itself failed.
2165
+ */
2166
+ verifyHmacSha256(key: CryptoKey, signature: Uint8Array, data: Uint8Array): Promise<Result<boolean>>;
2167
+ }
2168
+
2169
+ /**
2170
+ * Provider-specific config for DALL-E models (dall-e-2, dall-e-3).
2171
+ * @remarks
2172
+ * style is only valid for dall-e-3; the runtime validator rejects it for dall-e-2.
2173
+ * @public
2174
+ */
2175
+ declare interface IDallEImageGenerationConfig {
2176
+ /** Image dimensions (dall-e-2: 256x256|512x512|1024x1024; dall-e-3: 1024x1024|1792x1024|1024x1792). */
2177
+ readonly size?: DallE2Size | DallE3Size;
2178
+ /** dall-e-3 only. Quality tier. */
2179
+ readonly quality?: DallE3Quality;
2180
+ /** dall-e-3 only. Visual style. */
2181
+ readonly style?: 'vivid' | 'natural';
2182
+ }
2183
+
2184
+ /**
2185
+ * Options block scoped to DALL-E family models.
2186
+ * @public
2187
+ */
2188
+ declare interface IDallEModelOptions extends INamedModelFamilyConfig {
2189
+ /** Discriminator: openai provider lineage. */
2190
+ readonly provider: 'openai';
2191
+ /** Family identifier. */
2192
+ readonly family: 'dall-e';
2193
+ /** Optional model names this block applies to. Omit = applies to all DALL-E models. */
2194
+ readonly models?: DallEModelNames[];
2195
+ /** Family-specific config. */
2196
+ readonly config: IDallEImageGenerationConfig;
958
2197
  }
959
2198
 
960
2199
  /**
@@ -1094,58 +2333,416 @@ declare interface IEncryptionResult {
1094
2333
  }
1095
2334
 
1096
2335
  /**
1097
- * Options for importing a secret.
2336
+ * Options shared by every {@link AiAssist.fencedStringifiedJson} call.
1098
2337
  * @public
1099
2338
  */
1100
- declare interface IImportSecretOptions extends IAddSecretOptions {
2339
+ declare interface IFencedStringifiedJsonExtractorOptions {
1101
2340
  /**
1102
- * Whether to replace an existing secret with the same name.
2341
+ * Optional pre-parse extractor. Defaults to {@link AiAssist.extractJsonText}.
2342
+ * Provide a custom extractor to handle response shapes the default does not
2343
+ * understand.
1103
2344
  */
1104
- readonly replace?: boolean;
2345
+ readonly extractor?: JsonTextExtractor;
1105
2346
  }
1106
2347
 
1107
2348
  /**
1108
- * Key derivation parameters stored in encrypted files.
1109
- * Allows decryption with password without needing to know the original salt/iterations.
2349
+ * Options for the validating overload of {@link AiAssist.fencedStringifiedJson}.
2350
+ * `inner` is required so the typed `Converter<T>` return value can never lie
2351
+ * about the runtime shape.
1110
2352
  * @public
1111
2353
  */
1112
- declare interface IKeyDerivationParams {
1113
- /**
1114
- * Key derivation function used.
1115
- */
1116
- readonly kdf: KeyDerivationFunction;
1117
- /**
1118
- * Base64-encoded salt used for key derivation.
1119
- */
1120
- readonly salt: string;
1121
- /**
1122
- * Number of iterations used for key derivation.
1123
- */
1124
- readonly iterations: number;
2354
+ declare interface IFencedStringifiedJsonOptions<T> extends IFencedStringifiedJsonExtractorOptions {
2355
+ /** Inner converter or validator applied to the parsed JSON value. */
2356
+ readonly inner: Converter<T> | Validator<T>;
1125
2357
  }
1126
2358
 
1127
2359
  /**
1128
- * Parameters for creating a new key store.
2360
+ * Provider-specific config for Gemini Flash Image.
1129
2361
  * @public
1130
2362
  */
1131
- declare interface IKeyStoreCreateParams {
1132
- /**
1133
- * Crypto provider to use.
1134
- */
1135
- readonly cryptoProvider: ICryptoProvider;
1136
- /**
1137
- * PBKDF2 iterations (defaults to DEFAULT_KEYSTORE_ITERATIONS).
1138
- */
1139
- readonly iterations?: number;
2363
+ declare interface IGeminiFlashImageGenerationConfig {
2364
+ /** Aspect ratio string. */
2365
+ readonly aspectRatio?: string;
1140
2366
  }
1141
2367
 
1142
2368
  /**
1143
- * The encrypted key store file format.
2369
+ * Options block scoped to Gemini Flash Image models.
1144
2370
  * @public
1145
2371
  */
1146
- declare interface IKeyStoreFile {
1147
- /**
1148
- * Format identifier.
2372
+ declare interface IGeminiFlashImageModelOptions extends INamedModelFamilyConfig {
2373
+ readonly provider: 'google';
2374
+ readonly family: 'gemini-flash-image';
2375
+ readonly models?: GeminiFlashImageModelNames[];
2376
+ readonly config: IGeminiFlashImageGenerationConfig;
2377
+ }
2378
+
2379
+ /**
2380
+ * Google Gemini-specific thinking configuration.
2381
+ * @public
2382
+ */
2383
+ declare interface IGeminiThinkingConfig {
2384
+ /**
2385
+ * Token budget for thinking. Maps 1:1 to `thinkingBudget` on the wire.
2386
+ * - 0: disable thinking (Flash and Flash-Lite only; error on Pro)
2387
+ * - positive integer: soft token cap
2388
+ * - -1: dynamic
2389
+ * - omitted: model default
2390
+ */
2391
+ readonly thinkingBudget?: number;
2392
+ /**
2393
+ * Whether to include thought summaries in the response.
2394
+ * @remarks
2395
+ * INERT in phase B. Adapters never send `includeThoughts: true`.
2396
+ * Wired up by the followup stream `ai-assist-thinking-events`.
2397
+ */
2398
+ readonly includeThoughts?: boolean;
2399
+ }
2400
+
2401
+ /**
2402
+ * Google Gemini-specific thinking options block.
2403
+ * @public
2404
+ */
2405
+ declare interface IGeminiThinkingOptions {
2406
+ readonly provider: 'google';
2407
+ readonly models?: ReadonlyArray<GeminiThinkingModelNames>;
2408
+ readonly config: IGeminiThinkingConfig;
2409
+ }
2410
+
2411
+ /**
2412
+ * Parameters for {@link AiAssist.generateJsonCompletion}. Extends
2413
+ * {@link AiAssist.IProviderCompletionParams} with JSON-validation knobs.
2414
+ * @public
2415
+ */
2416
+ declare interface IGenerateJsonCompletionParams<T> extends IProviderCompletionParams {
2417
+ /**
2418
+ * Caller-supplied `Converter<T>` or `Validator<T>` applied to the parsed
2419
+ * JSON value. Wrapped internally in {@link AiAssist.fencedStringifiedJson}
2420
+ * unless {@link AiAssist.IGenerateJsonCompletionParams.jsonConverter} is
2421
+ * provided.
2422
+ */
2423
+ readonly converter?: Converter<T> | Validator<T>;
2424
+ /**
2425
+ * Full string-to-`T` pipeline override. When supplied, takes precedence over
2426
+ * {@link AiAssist.IGenerateJsonCompletionParams.converter} and lets the
2427
+ * caller plug in a custom extractor or skip the default fence tolerance
2428
+ * entirely.
2429
+ */
2430
+ readonly jsonConverter?: Converter<T>;
2431
+ /**
2432
+ * Controls the optional system-prompt augmentation. Defaults to `'smart'`.
2433
+ * Pass `'none'` to disable, or a string to append custom guidance.
2434
+ */
2435
+ readonly promptHint?: JsonPromptHint;
2436
+ }
2437
+
2438
+ /**
2439
+ * Successful result of {@link AiAssist.generateJsonCompletion}.
2440
+ * @public
2441
+ */
2442
+ declare interface IGenerateJsonCompletionResult<T> {
2443
+ /** The validated JSON value. */
2444
+ readonly value: T;
2445
+ /** The raw response text returned by the provider. */
2446
+ readonly raw: string;
2447
+ /** The full underlying completion response. */
2448
+ readonly response: IAiCompletionResponse;
2449
+ }
2450
+
2451
+ /**
2452
+ * Provider-specific config for gpt-image-1.
2453
+ * @public
2454
+ */
2455
+ declare interface IGptImageGenerationConfig {
2456
+ /** Image dimensions. */
2457
+ readonly size?: GptImageSize;
2458
+ /** Quality tier. */
2459
+ readonly quality?: GptImageQuality;
2460
+ /** Output format (replaces response_format for this model). */
2461
+ readonly outputFormat?: 'png' | 'jpeg' | 'webp';
2462
+ /** JPEG/WebP compression level 0–100. */
2463
+ readonly outputCompression?: number;
2464
+ /** Background transparency control. */
2465
+ readonly background?: 'transparent' | 'opaque' | 'auto';
2466
+ /** Content moderation strictness. */
2467
+ readonly moderation?: 'low' | 'auto';
2468
+ }
2469
+
2470
+ /**
2471
+ * Options block scoped to GPT Image family models.
2472
+ * @public
2473
+ */
2474
+ declare interface IGptImageModelOptions extends INamedModelFamilyConfig {
2475
+ readonly provider: 'openai';
2476
+ readonly family: 'gpt-image';
2477
+ readonly models?: GptImageModelNames[];
2478
+ readonly config: IGptImageGenerationConfig;
2479
+ }
2480
+
2481
+ /**
2482
+ * Provider-specific config for xAI Grok Imagine models.
2483
+ * @public
2484
+ */
2485
+ declare interface IGrokImagineImageGenerationConfig {
2486
+ /** Aspect ratio string (xAI uses aspect ratios, not pixel dimensions). */
2487
+ readonly aspectRatio?: string;
2488
+ /** Resolution hint. */
2489
+ readonly resolution?: string;
2490
+ }
2491
+
2492
+ /**
2493
+ * Options block scoped to xAI Grok Imagine family models.
2494
+ * @public
2495
+ */
2496
+ declare interface IGrokImagineModelOptions extends INamedModelFamilyConfig {
2497
+ readonly provider: 'xai';
2498
+ readonly family: 'grok-imagine';
2499
+ readonly models?: GrokImagineModelNames[];
2500
+ readonly config: IGrokImagineImageGenerationConfig;
2501
+ }
2502
+
2503
+ /**
2504
+ * Output of {@link HpkeProvider.sealBase}.
2505
+ *
2506
+ * The `ciphertext` field includes the 16-byte AES-256-GCM authentication tag
2507
+ * appended by Web Crypto's `encrypt()` operation: `length = plaintext.length + 16`.
2508
+ * @public
2509
+ */
2510
+ declare interface IHpkeSealResult {
2511
+ /**
2512
+ * Encapsulated key — 32-byte raw X25519 ephemeral public key (`enc` in RFC 9180).
2513
+ * Must be transmitted to the recipient alongside `ciphertext`.
2514
+ */
2515
+ readonly enc: Uint8Array;
2516
+ /**
2517
+ * AES-256-GCM ciphertext with the 16-byte authentication tag appended.
2518
+ * Length = `plaintext.length + 16`.
2519
+ */
2520
+ readonly ciphertext: Uint8Array;
2521
+ }
2522
+
2523
+ /**
2524
+ * Provider-specific config for Google Imagen 4 models.
2525
+ * @public
2526
+ */
2527
+ declare interface IImagen4GenerationConfig {
2528
+ /** Aspect ratio string. */
2529
+ readonly aspectRatio?: '1:1' | '3:4' | '4:3' | '9:16' | '16:9';
2530
+ /** Output resolution. */
2531
+ readonly imageSize?: '1K' | '2K';
2532
+ /** Whether to add SynthID watermark. Must be false to use seed. */
2533
+ readonly addWatermark?: boolean;
2534
+ /** LLM-based prompt rewriting. */
2535
+ readonly enhancePrompt?: boolean;
2536
+ /** Output MIME type. */
2537
+ readonly outputMimeType?: 'image/jpeg' | 'image/png';
2538
+ /** JPEG compression quality. */
2539
+ readonly outputCompressionQuality?: number;
2540
+ /** Person generation policy. */
2541
+ readonly personGeneration?: 'allow_all' | 'allow_adult' | 'dont_allow';
2542
+ }
2543
+
2544
+ /**
2545
+ * Options block scoped to Google Imagen 4 models.
2546
+ * @public
2547
+ */
2548
+ declare interface IImagen4ModelOptions extends INamedModelFamilyConfig {
2549
+ readonly provider: 'google';
2550
+ readonly family: 'imagen-4';
2551
+ readonly models?: Imagen4ModelNames[];
2552
+ readonly config: IImagen4GenerationConfig;
2553
+ }
2554
+
2555
+ /**
2556
+ * Options for importing raw key material via {@link KeyStore.importSecret}.
2557
+ * Extends {@link IImportSecretOptions} with a type classification.
2558
+ * @public
2559
+ */
2560
+ declare interface IImportKeyOptions extends IImportSecretOptions {
2561
+ /**
2562
+ * Symmetric secret type classification for the imported key material.
2563
+ * @defaultValue 'encryption-key'
2564
+ */
2565
+ readonly type?: KeyStoreSymmetricSecretType;
2566
+ }
2567
+
2568
+ /**
2569
+ * Options for importing a secret.
2570
+ * @public
2571
+ */
2572
+ declare interface IImportSecretOptions extends IAddSecretOptions {
2573
+ /**
2574
+ * Whether to replace an existing secret with the same name.
2575
+ */
2576
+ readonly replace?: boolean;
2577
+ }
2578
+
2579
+ /**
2580
+ * Key derivation parameters stored in encrypted files.
2581
+ * Discriminated union on `kdf` field: `'pbkdf2'` or `'argon2id'`.
2582
+ * @public
2583
+ */
2584
+ declare type IKeyDerivationParams = IPbkdf2KeyDerivationParams | IArgon2idKeyDerivationParams;
2585
+
2586
+ /**
2587
+ * WebCrypto parameters for a single {@link CryptoUtils.KeyPairAlgorithm}.
2588
+ * Implementations of {@link CryptoUtils.ICryptoProvider} use this table to
2589
+ * translate the small public algorithm enum into the WebCrypto algorithm
2590
+ * objects and key-usage arrays expected by `crypto.subtle`.
2591
+ * @public
2592
+ */
2593
+ declare interface IKeyPairAlgorithmParams {
2594
+ /**
2595
+ * Algorithm parameters for `crypto.subtle.generateKey`. Always an asymmetric
2596
+ * variant — these algorithms produce a `CryptoKeyPair`, not a single key.
2597
+ * The literal `{ name: 'Ed25519' }` member covers WebCrypto's Secure-Curves
2598
+ * Ed25519 algorithm; `{ name: 'X25519' }` covers the X25519 key-agreement
2599
+ * algorithm. Both take only a `name`; using literals rather than the base
2600
+ * `Algorithm` keeps the union closed to the algorithms this table supports.
2601
+ */
2602
+ readonly generateKey: RsaHashedKeyGenParams | EcKeyGenParams | {
2603
+ readonly name: 'Ed25519';
2604
+ } | {
2605
+ readonly name: 'X25519';
2606
+ };
2607
+ /**
2608
+ * Algorithm parameters for `crypto.subtle.importKey('jwk', ...)` when
2609
+ * importing the public half of a keypair. The literal `{ name: 'Ed25519' }`
2610
+ * member covers Ed25519 imports; `{ name: 'X25519' }` covers X25519 imports.
2611
+ * Both take only a `name`; using literals rather than the base `Algorithm`
2612
+ * keeps the union closed to the algorithms this table supports.
2613
+ */
2614
+ readonly importPublicKey: RsaHashedImportParams | EcKeyImportParams | {
2615
+ readonly name: 'Ed25519';
2616
+ } | {
2617
+ readonly name: 'X25519';
2618
+ };
2619
+ /**
2620
+ * Default key usages for the generated `CryptoKeyPair`. Both halves receive
2621
+ * the usages WebCrypto considers valid for their role; the platform filters.
2622
+ */
2623
+ readonly keyPairUsages: ReadonlyArray<KeyUsage>;
2624
+ /**
2625
+ * Key usages applied when re-importing only the public key.
2626
+ */
2627
+ readonly publicKeyUsages: ReadonlyArray<KeyUsage>;
2628
+ }
2629
+
2630
+ /**
2631
+ * An asymmetric keypair entry stored in the vault (in-memory representation).
2632
+ * Holds only the public key (as a JWK) and a stable handle (`id`) the
2633
+ * {@link CryptoUtils.KeyStore.IPrivateKeyStorage} provider uses to fetch the private key.
2634
+ * @public
2635
+ */
2636
+ declare interface IKeyStoreAsymmetricEntry {
2637
+ /**
2638
+ * Unique name for this entry (used as vault lookup key, renameable).
2639
+ */
2640
+ readonly name: string;
2641
+ /**
2642
+ * Asymmetric secret type discriminator.
2643
+ */
2644
+ readonly type: KeyStoreAsymmetricSecretType;
2645
+ /**
2646
+ * Immutable handle used by {@link CryptoUtils.KeyStore.IPrivateKeyStorage} to address the
2647
+ * private key. Independent of `name`; survives renames.
2648
+ */
2649
+ readonly id: string;
2650
+ /**
2651
+ * Algorithm used to generate this keypair.
2652
+ */
2653
+ readonly algorithm: KeyPairAlgorithm;
2654
+ /**
2655
+ * The public key as a JSON Web Key.
2656
+ */
2657
+ readonly publicKeyJwk: JsonWebKey;
2658
+ /**
2659
+ * Optional description for this entry.
2660
+ */
2661
+ readonly description?: string;
2662
+ /**
2663
+ * When this entry was added (ISO 8601).
2664
+ */
2665
+ readonly createdAt: string;
2666
+ }
2667
+
2668
+ /**
2669
+ * JSON-serializable representation of an asymmetric keypair entry.
2670
+ * The private key is not present here — it lives in the
2671
+ * {@link CryptoUtils.KeyStore.IPrivateKeyStorage} provider, addressed by `id`.
2672
+ * @public
2673
+ */
2674
+ declare interface IKeyStoreAsymmetricEntryJson {
2675
+ /**
2676
+ * Unique name for this entry.
2677
+ */
2678
+ readonly name: string;
2679
+ /**
2680
+ * Asymmetric secret type discriminator.
2681
+ */
2682
+ readonly type: KeyStoreAsymmetricSecretType;
2683
+ /**
2684
+ * Immutable handle used by {@link CryptoUtils.KeyStore.IPrivateKeyStorage} to address the
2685
+ * private key.
2686
+ */
2687
+ readonly id: string;
2688
+ /**
2689
+ * Algorithm used to generate this keypair.
2690
+ */
2691
+ readonly algorithm: KeyPairAlgorithm;
2692
+ /**
2693
+ * The public key as a JSON Web Key.
2694
+ */
2695
+ readonly publicKeyJwk: JsonWebKey;
2696
+ /**
2697
+ * Optional description.
2698
+ */
2699
+ readonly description?: string;
2700
+ /**
2701
+ * When this entry was added (ISO 8601).
2702
+ */
2703
+ readonly createdAt: string;
2704
+ }
2705
+
2706
+ /**
2707
+ * Parameters for creating a new key store.
2708
+ * @public
2709
+ */
2710
+ declare interface IKeyStoreCreateParams {
2711
+ /**
2712
+ * Crypto provider to use.
2713
+ */
2714
+ readonly cryptoProvider: ICryptoProvider;
2715
+ /**
2716
+ * PBKDF2 iterations (defaults to DEFAULT_KEYSTORE_ITERATIONS).
2717
+ */
2718
+ readonly iterations?: number;
2719
+ /**
2720
+ * Optional private-key storage backend. Required to use `addKeyPair` /
2721
+ * `getKeyPair`; absent backends still permit opening, listing, and reading
2722
+ * public-key metadata for asymmetric entries.
2723
+ */
2724
+ readonly privateKeyStorage?: IPrivateKeyStorage;
2725
+ }
2726
+
2727
+ /**
2728
+ * Any vault entry, discriminated by `type`.
2729
+ * @public
2730
+ */
2731
+ declare type IKeyStoreEntry = IKeyStoreSymmetricEntry | IKeyStoreAsymmetricEntry;
2732
+
2733
+ /**
2734
+ * Any JSON vault entry, discriminated by `type`.
2735
+ * @public
2736
+ */
2737
+ declare type IKeyStoreEntryJson = IKeyStoreSymmetricEntryJson | IKeyStoreAsymmetricEntryJson;
2738
+
2739
+ /**
2740
+ * The encrypted key store file format.
2741
+ * @public
2742
+ */
2743
+ declare interface IKeyStoreFile {
2744
+ /**
2745
+ * Format identifier.
1149
2746
  */
1150
2747
  readonly format: KeyStoreFormat;
1151
2748
  /**
@@ -1165,9 +2762,9 @@ declare interface IKeyStoreFile {
1165
2762
  */
1166
2763
  readonly encryptedData: string;
1167
2764
  /**
1168
- * Key derivation parameters (required for key store - always password-derived).
2765
+ * Key derivation parameters for the vault master key (always PBKDF2).
1169
2766
  */
1170
- readonly keyDerivation: IKeyDerivationParams;
2767
+ readonly keyDerivation: IPbkdf2KeyDerivationParams;
1171
2768
  }
1172
2769
 
1173
2770
  /**
@@ -1183,22 +2780,46 @@ declare interface IKeyStoreOpenParams {
1183
2780
  * The encrypted key store file content.
1184
2781
  */
1185
2782
  readonly keystoreFile: IKeyStoreFile;
2783
+ /**
2784
+ * Optional private-key storage backend. Required to use `addKeyPair` /
2785
+ * `getKeyPair`; absent backends still permit opening, listing, and reading
2786
+ * public-key metadata for asymmetric entries.
2787
+ */
2788
+ readonly privateKeyStorage?: IPrivateKeyStorage;
1186
2789
  }
1187
2790
 
1188
2791
  /**
1189
- * A secret entry stored in the vault (in-memory representation).
2792
+ * Backwards-compatible alias for {@link CryptoUtils.KeyStore.IKeyStoreSymmetricEntry}.
2793
+ * @deprecated Use {@link CryptoUtils.KeyStore.IKeyStoreSymmetricEntry} for symmetric
2794
+ * entries or {@link CryptoUtils.KeyStore.IKeyStoreEntry} for the discriminated union.
1190
2795
  * @public
1191
2796
  */
1192
- declare interface IKeyStoreSecretEntry {
2797
+ declare type IKeyStoreSecretEntry = IKeyStoreSymmetricEntry;
2798
+
2799
+ /**
2800
+ * Backwards-compatible alias for {@link CryptoUtils.KeyStore.IKeyStoreSymmetricEntryJson}.
2801
+ * @deprecated Use {@link CryptoUtils.KeyStore.IKeyStoreSymmetricEntryJson} for
2802
+ * symmetric entries or {@link CryptoUtils.KeyStore.IKeyStoreEntryJson} for the
2803
+ * discriminated union.
2804
+ * @public
2805
+ */
2806
+ declare type IKeyStoreSecretEntryJson = IKeyStoreSymmetricEntryJson;
2807
+
2808
+ /**
2809
+ * A symmetric secret entry stored in the vault (in-memory representation).
2810
+ * Holds the raw key material directly — for `'encryption-key'` it is a 32-byte
2811
+ * AES-256 key; for `'api-key'` it is the UTF-8 encoded API key string.
2812
+ * @public
2813
+ */
2814
+ declare interface IKeyStoreSymmetricEntry {
1193
2815
  /**
1194
2816
  * Unique name for this secret (used as lookup key).
1195
2817
  */
1196
2818
  readonly name: string;
1197
2819
  /**
1198
- * Secret type discriminator.
1199
- * Defaults to `'encryption-key'` for backwards compatibility.
2820
+ * Symmetric secret type discriminator.
1200
2821
  */
1201
- readonly type: KeyStoreSecretType;
2822
+ readonly type: KeyStoreSymmetricSecretType;
1202
2823
  /**
1203
2824
  * The secret data.
1204
2825
  * - For `'encryption-key'`: 32-byte AES-256 key.
@@ -1216,19 +2837,34 @@ declare interface IKeyStoreSecretEntry {
1216
2837
  }
1217
2838
 
1218
2839
  /**
1219
- * JSON-serializable version of secret entry (for storage).
2840
+ * JSON-serializable representation of a symmetric secret entry.
2841
+ *
2842
+ * @remarks
2843
+ * Describes the *normalized* shape after parsing. `type` is required here
2844
+ * because the converter (see
2845
+ * {@link CryptoUtils.KeyStore.Converters.keystoreSymmetricEntryJson | keystoreSymmetricEntryJson})
2846
+ * injects the default `'encryption-key'` when reading vaults written before
2847
+ * asymmetric-keypair support added the discriminator. Raw on-wire bytes from
2848
+ * a legacy vault may therefore omit `type`; downstream code only ever sees
2849
+ * the post-conversion shape declared here.
2850
+ *
1220
2851
  * @public
1221
2852
  */
1222
- declare interface IKeyStoreSecretEntryJson {
2853
+ declare interface IKeyStoreSymmetricEntryJson {
1223
2854
  /**
1224
2855
  * Unique name for this secret.
1225
2856
  */
1226
2857
  readonly name: string;
1227
2858
  /**
1228
- * Secret type discriminator.
1229
- * Optional for backwards compatibility — missing means `'encryption-key'`.
2859
+ * Symmetric secret type discriminator.
2860
+ *
2861
+ * Required on this normalized model type. Vaults written prior to the
2862
+ * asymmetric-keypair support may omit this field on the wire; the
2863
+ * converter injects `'encryption-key'` when missing for backwards
2864
+ * compatibility, so by the time a value of this type is observed the
2865
+ * discriminator is always present.
1230
2866
  */
1231
- readonly type?: KeyStoreSecretType;
2867
+ readonly type: KeyStoreSymmetricSecretType;
1232
2868
  /**
1233
2869
  * Base64-encoded secret data.
1234
2870
  */
@@ -1244,7 +2880,7 @@ declare interface IKeyStoreSecretEntryJson {
1244
2880
  }
1245
2881
 
1246
2882
  /**
1247
- * The decrypted vault contents - a versioned map of secrets.
2883
+ * The decrypted vault contents - a versioned map of entries.
1248
2884
  * @public
1249
2885
  */
1250
2886
  declare interface IKeyStoreVaultContents {
@@ -1253,11 +2889,14 @@ declare interface IKeyStoreVaultContents {
1253
2889
  */
1254
2890
  readonly version: KeyStoreFormat;
1255
2891
  /**
1256
- * Map of secret name to secret entry.
2892
+ * Map of entry name to entry (symmetric or asymmetric).
1257
2893
  */
1258
- readonly secrets: Record<string, IKeyStoreSecretEntryJson>;
2894
+ readonly secrets: Record<string, IKeyStoreEntryJson>;
1259
2895
  }
1260
2896
 
2897
+ /** Model names in the Imagen 4 family. @public */
2898
+ declare type Imagen4ModelNames = 'imagen-4.0-generate-001' | 'imagen-4.0-ultra-generate-001' | 'imagen-4.0-fast-generate-001';
2899
+
1261
2900
  /**
1262
2901
  * Details about a missing variable in context validation.
1263
2902
  * @public
@@ -1278,6 +2917,13 @@ declare interface IMissingVariableDetail {
1278
2917
  readonly existingPath: readonly string[];
1279
2918
  }
1280
2919
 
2920
+ /**
2921
+ * Discriminated union of all model-family option blocks.
2922
+ * Discriminated on `provider` + `family` fields.
2923
+ * @public
2924
+ */
2925
+ declare type IModelFamilyConfig = IDallEModelOptions | IGptImageModelOptions | IGrokImagineModelOptions | IImagen4ModelOptions | IGeminiFlashImageModelOptions | IOtherModelOptions;
2926
+
1281
2927
  /**
1282
2928
  * A model specification: either a simple model string or a record mapping
1283
2929
  * context keys to nested model specs.
@@ -1290,10 +2936,10 @@ declare interface IMissingVariableDetail {
1290
2936
  * @example
1291
2937
  * ```typescript
1292
2938
  * // Simple — same model for all contexts:
1293
- * const simple: ModelSpec = 'grok-4-1-fast';
2939
+ * const simple: ModelSpec = 'grok-4.3';
1294
2940
  *
1295
- * // Context-aware — reasoning model when tools are active:
1296
- * const split: ModelSpec = { base: 'grok-4-1-fast', tools: 'grok-4-1-fast-reasoning' };
2941
+ * // Context-aware — different model for tools and thinking:
2942
+ * const split: ModelSpec = { base: 'grok-4.3', tools: 'grok-4.3', thinking: 'grok-4.3' };
1297
2943
  *
1298
2944
  * // Future nested — per-tool model selection:
1299
2945
  * const nested: ModelSpec = { base: 'grok-fast', tools: { base: 'grok-r', image: 'grok-v' } };
@@ -1304,6 +2950,21 @@ declare interface IModelSpecMap {
1304
2950
  readonly [key: string]: ModelSpec;
1305
2951
  }
1306
2952
 
2953
+ /**
2954
+ * Imports a public key from a multibase base64url-encoded SPKI blob.
2955
+ *
2956
+ * Decodes the multibase prefix, decodes the base64url body, then uses
2957
+ * the provider to import the key with the algorithm parameters from
2958
+ * {@link CryptoUtils.keyPairAlgorithmParams}.
2959
+ *
2960
+ * @param encoded - A multibase SPKI string produced by {@link CryptoUtils.exportPublicKeyAsMultibaseSpki}.
2961
+ * @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm} the key was generated for.
2962
+ * @param provider - The {@link CryptoUtils.ICryptoProvider} to use for the import operation.
2963
+ * @returns `Success` with the imported public `CryptoKey`, or `Failure` with error context.
2964
+ * @public
2965
+ */
2966
+ declare function importPublicKeyFromMultibaseSpki(encoded: string, algorithm: KeyPairAlgorithm, provider: ICryptoProvider): Promise<Result<CryptoKey>>;
2967
+
1307
2968
  /**
1308
2969
  * Options for template parsing and validation.
1309
2970
  * @public
@@ -1321,6 +2982,32 @@ declare interface IMustacheTemplateOptions {
1321
2982
  * Whether to include partial references in variable extraction (default: false)
1322
2983
  */
1323
2984
  readonly includePartials?: boolean;
2985
+ /**
2986
+ * Escape strategy applied to double-brace `{{name}}` tokens at render
2987
+ * time. Default `'html'` preserves the existing mustache.js behavior
2988
+ * (back-compat).
2989
+ *
2990
+ * Pass `'none'` for LLM-prompt or other non-HTML targets where the
2991
+ * default `& → &amp;` escape would corrupt the output. Pass a custom
2992
+ * function for any other escape policy.
2993
+ *
2994
+ * The strategy is applied per-template via a private `Mustache.Writer`
2995
+ * instance; no global state on the `mustache` module is mutated, so
2996
+ * concurrent templates with different strategies are safe.
2997
+ *
2998
+ * Note: triple-brace `{{{name}}}` tokens are always rendered unescaped
2999
+ * regardless of strategy (standard mustache.js semantics).
3000
+ */
3001
+ readonly escape?: MustacheEscapeStrategy;
3002
+ }
3003
+
3004
+ /**
3005
+ * Base shape shared by all named family option blocks.
3006
+ * Provides a typed `models` field for applicability filtering without unsafe casts.
3007
+ * @internal
3008
+ */
3009
+ declare interface INamedModelFamilyConfig {
3010
+ readonly models?: readonly string[];
1324
3011
  }
1325
3012
 
1326
3013
  /**
@@ -1338,6 +3025,129 @@ declare interface INamedSecret {
1338
3025
  readonly key: Uint8Array;
1339
3026
  }
1340
3027
 
3028
+ /**
3029
+ * OpenAI-specific thinking configuration.
3030
+ * @remarks
3031
+ * Maps to `reasoning_effort` (Chat Completions path) or `reasoning.effort`
3032
+ * (Responses API path) on the wire. The adapter selects the correct field.
3033
+ * @public
3034
+ */
3035
+ declare interface IOpenAiThinkingConfig {
3036
+ /**
3037
+ * OpenAI reasoning effort. Maps 1:1 to the wire field.
3038
+ * - 'none': disables reasoning (gpt-5.x only; rejected by o-series)
3039
+ * - 'minimal': fastest (gpt-5.x)
3040
+ * - 'low' | 'medium' | 'high': standard tiers
3041
+ * - 'xhigh': highest (select gpt-5.x models only)
3042
+ *
3043
+ * @remarks
3044
+ * When effective effort is 'none', reasoning is disabled and temperature is
3045
+ * accepted by gpt-5.x models. This is the only case where temperature and
3046
+ * thinking config co-exist without a Result.fail.
3047
+ */
3048
+ readonly effort?: 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';
3049
+ }
3050
+
3051
+ /**
3052
+ * OpenAI-specific thinking options block.
3053
+ * @public
3054
+ */
3055
+ declare interface IOpenAiThinkingOptions {
3056
+ readonly provider: 'openai';
3057
+ readonly models?: ReadonlyArray<OpenAiThinkingModelNames>;
3058
+ readonly config: IOpenAiThinkingConfig;
3059
+ }
3060
+
3061
+ /**
3062
+ * Escape-hatch options block for models not covered by a named family.
3063
+ * @remarks
3064
+ * `models` is required — there is no implicit "all" for unknown model families.
3065
+ * `config` is `JsonObject` — passed verbatim to the wire request with no validation.
3066
+ * This is the "trust me, I know what I'm doing" path for callers who need to send
3067
+ * wire params our typed configs don't yet expose.
3068
+ * @public
3069
+ */
3070
+ declare interface IOtherModelOptions {
3071
+ readonly provider: 'other';
3072
+ readonly models: string[];
3073
+ readonly config: JsonObject;
3074
+ }
3075
+
3076
+ /**
3077
+ * Escape-hatch options block for providers not covered by typed configs.
3078
+ * @remarks
3079
+ * `models` is required — no implicit "all" for unknown providers.
3080
+ * `config` fields are merged verbatim into the wire request.
3081
+ * @public
3082
+ */
3083
+ declare interface IOtherThinkingOptions {
3084
+ readonly provider: 'other';
3085
+ readonly models: ReadonlyArray<string>;
3086
+ readonly config: JsonObject;
3087
+ }
3088
+
3089
+ /**
3090
+ * PBKDF2 key derivation parameters.
3091
+ * @public
3092
+ */
3093
+ declare interface IPbkdf2KeyDerivationParams {
3094
+ /** Key derivation function discriminator. */
3095
+ readonly kdf: 'pbkdf2';
3096
+ /** Base64-encoded salt used for key derivation. */
3097
+ readonly salt: string;
3098
+ /** Number of iterations used for key derivation. */
3099
+ readonly iterations: number;
3100
+ }
3101
+
3102
+ /**
3103
+ * Pluggable backend that persists raw asymmetric private keys outside of the
3104
+ * encrypted keystore vault. Concrete implementations live in platform-specific
3105
+ * packages (e.g. an IndexedDB-backed implementation in `@fgv/ts-web-extras` or
3106
+ * an encrypted-file implementation in `@fgv/ts-chocolate`).
3107
+ *
3108
+ * The keystore writes storage-first: a private key is always stored here
3109
+ * before the corresponding public-key vault entry is committed. Conversely,
3110
+ * deletes hit the vault first and then this storage best-effort. As a result,
3111
+ * crashes or skipped saves can leave orphaned blobs here; callers are expected
3112
+ * to reconcile via {@link CryptoUtils.KeyStore.IPrivateKeyStorage.list} cross-referenced
3113
+ * against the keystore's asymmetric entries.
3114
+ *
3115
+ * @public
3116
+ */
3117
+ declare interface IPrivateKeyStorage {
3118
+ /**
3119
+ * Whether keys generated for this backend may be marked
3120
+ * `extractable: false`. `true` on backends that store `CryptoKey`
3121
+ * objects directly (e.g. IndexedDB). `false` on backends that must
3122
+ * round-trip via JWK (e.g. encrypted-file backends).
3123
+ */
3124
+ readonly supportsNonExtractable: boolean;
3125
+ /**
3126
+ * Stores `key` under `id`. Returns the stored `id` on success so the
3127
+ * call can compose into a Result chain.
3128
+ * @param id - Storage handle to write under.
3129
+ * @param key - The private `CryptoKey` to persist.
3130
+ */
3131
+ store(id: string, key: CryptoKey): Promise<Result<string>>;
3132
+ /**
3133
+ * Loads the private key previously stored under `id`.
3134
+ * @param id - Storage handle to look up.
3135
+ */
3136
+ load(id: string): Promise<Result<CryptoKey>>;
3137
+ /**
3138
+ * Deletes the entry stored under `id`. Returns the deleted `id` on
3139
+ * success so the call can compose into a Result chain.
3140
+ * @param id - Storage handle to remove.
3141
+ */
3142
+ delete(id: string): Promise<Result<string>>;
3143
+ /**
3144
+ * Lists every `id` currently held by the backend. Used by consumers to
3145
+ * garbage-collect orphans left by crashes or aborted sessions; the
3146
+ * keystore itself does not invoke this automatically.
3147
+ */
3148
+ list(): Promise<Result<readonly string[]>>;
3149
+ }
3150
+
1341
3151
  /**
1342
3152
  * Parameters for a provider completion request.
1343
3153
  * @public
@@ -1349,10 +3159,7 @@ declare interface IProviderCompletionParams {
1349
3159
  readonly apiKey: string;
1350
3160
  /** The structured prompt to send */
1351
3161
  readonly prompt: AiPrompt;
1352
- /**
1353
- * Additional messages to append after system+user (e.g. for correction retries).
1354
- * These are appended in order after the initial system and user messages.
1355
- */
3162
+ /** Additional messages to append after system+user in order (e.g. for correction retries). */
1356
3163
  readonly additionalMessages?: ReadonlyArray<IChatMessage>;
1357
3164
  /** Sampling temperature (default: 0.7) */
1358
3165
  readonly temperature?: number;
@@ -1362,6 +3169,125 @@ declare interface IProviderCompletionParams {
1362
3169
  readonly logger?: Logging.ILogger;
1363
3170
  /** Server-side tools to include in the request. Overrides settings-level tool config when provided. */
1364
3171
  readonly tools?: ReadonlyArray<AiServerToolConfig>;
3172
+ /** Optional abort signal for cancelling the in-flight request. */
3173
+ readonly signal?: AbortSignal;
3174
+ /**
3175
+ * Optional override of the descriptor's default base URL (scheme + host +
3176
+ * optional port + path prefix). The per-route suffix (e.g. `/chat/completions`)
3177
+ * is appended unchanged. Must be a well-formed `http`/`https` URL. Auth shape
3178
+ * is unchanged: `needsSecret` providers still require an API key.
3179
+ */
3180
+ readonly endpoint?: string;
3181
+ /**
3182
+ * Optional thinking/reasoning config. Anthropic, OpenAI, and xAI reject `temperature` when
3183
+ * the effective merged effort is non-`'none'`; Gemini always accepts both.
3184
+ */
3185
+ readonly thinking?: IThinkingConfig;
3186
+ }
3187
+
3188
+ /**
3189
+ * Parameters for a streaming completion request. Structurally identical to
3190
+ * the non-streaming `IProviderCompletionParams`; kept as its own interface
3191
+ * so callers can be explicit about which path they're invoking.
3192
+ *
3193
+ * @public
3194
+ */
3195
+ declare interface IProviderCompletionStreamParams {
3196
+ /** The provider descriptor */
3197
+ readonly descriptor: IAiProviderDescriptor;
3198
+ /** API key for authentication */
3199
+ readonly apiKey: string;
3200
+ /** The structured prompt to send */
3201
+ readonly prompt: AiPrompt;
3202
+ /**
3203
+ * Prior conversation history to insert between the system prompt and the
3204
+ * prompt's user message. The new user turn (carried by `prompt.user`) is
3205
+ * always sent last, so the wire shape becomes
3206
+ * `[system, ...messagesBefore, user=prompt.user]`.
3207
+ */
3208
+ readonly messagesBefore?: ReadonlyArray<IChatMessage>;
3209
+ /** Sampling temperature (default: 0.7) */
3210
+ readonly temperature?: number;
3211
+ /** Optional model override — string or context-aware map. */
3212
+ readonly modelOverride?: ModelSpec;
3213
+ /** Optional logger for request/response observability. */
3214
+ readonly logger?: Logging.ILogger;
3215
+ /** Server-side tools to include in the request. */
3216
+ readonly tools?: ReadonlyArray<AiServerToolConfig>;
3217
+ /** Optional abort signal for cancelling the in-flight stream. */
3218
+ readonly signal?: AbortSignal;
3219
+ /**
3220
+ * Optional override of the descriptor's default base URL. Same semantics as
3221
+ * the non-streaming completion path: a well-formed `http`/`https` URL is
3222
+ * substituted for `descriptor.baseUrl` when composing the streaming
3223
+ * request, with the per-format suffix appended unchanged. Validated at the
3224
+ * dispatcher; auth shape is unaffected.
3225
+ */
3226
+ readonly endpoint?: string;
3227
+ /**
3228
+ * Optional thinking/reasoning mode configuration.
3229
+ */
3230
+ readonly thinking?: IThinkingConfig;
3231
+ }
3232
+
3233
+ /**
3234
+ * Parameters for an image-generation request.
3235
+ * @public
3236
+ */
3237
+ declare interface IProviderImageGenerationParams {
3238
+ /** The provider descriptor */
3239
+ readonly descriptor: IAiProviderDescriptor;
3240
+ /** API key for authentication */
3241
+ readonly apiKey: string;
3242
+ /** The image-generation request */
3243
+ readonly params: IAiImageGenerationParams;
3244
+ /** Optional model override — string or context-aware map (uses descriptor.defaultModel.image otherwise) */
3245
+ readonly modelOverride?: ModelSpec;
3246
+ /** Optional logger for request/response observability. */
3247
+ readonly logger?: Logging.ILogger;
3248
+ /** Optional abort signal for cancelling the in-flight request. */
3249
+ readonly signal?: AbortSignal;
3250
+ /** Optional override of the descriptor's base URL; per-route suffix is appended unchanged. */
3251
+ readonly endpoint?: string;
3252
+ }
3253
+
3254
+ /**
3255
+ * Parameters for a list-models request.
3256
+ * @public
3257
+ */
3258
+ declare interface IProviderListModelsParams {
3259
+ /** The provider descriptor */
3260
+ readonly descriptor: IAiProviderDescriptor;
3261
+ /** API key for authentication */
3262
+ readonly apiKey: string;
3263
+ /** Optional capability filter; when set, only models declaring this capability are returned. */
3264
+ readonly capability?: AiModelCapability;
3265
+ /** Optional capability config override (defaults to {@link DEFAULT_MODEL_CAPABILITY_CONFIG}). */
3266
+ readonly capabilityConfig?: IAiModelCapabilityConfig;
3267
+ /** Optional logger for request/response observability. */
3268
+ readonly logger?: Logging.ILogger;
3269
+ /** Optional abort signal for cancelling the in-flight request. */
3270
+ readonly signal?: AbortSignal;
3271
+ /** Optional override of the descriptor's base URL; per-format `/models` route is appended unchanged. */
3272
+ readonly endpoint?: string;
3273
+ }
3274
+
3275
+ /**
3276
+ * Result of removing a secret from the key store.
3277
+ * @public
3278
+ */
3279
+ declare interface IRemoveSecretResult {
3280
+ /**
3281
+ * The secret entry that was removed from the vault.
3282
+ */
3283
+ readonly entry: IKeyStoreEntry;
3284
+ /**
3285
+ * Best-effort warning from {@link CryptoUtils.KeyStore.IPrivateKeyStorage}.delete
3286
+ * for asymmetric entries when the storage call failed. The vault entry is
3287
+ * still considered removed and the orphaned blob is left for consumer-side
3288
+ * GC to reconcile.
3289
+ */
3290
+ readonly warning?: string;
1365
3291
  }
1366
3292
 
1367
3293
  /**
@@ -1372,55 +3298,240 @@ declare interface IRequiredMustacheTemplateOptions {
1372
3298
  readonly tags: [string, string];
1373
3299
  readonly includeComments: boolean;
1374
3300
  readonly includePartials: boolean;
3301
+ readonly escape: MustacheEscapeStrategy;
3302
+ }
3303
+
3304
+ /**
3305
+ * The resolved, merged wire parameters for an image generation request.
3306
+ * Built from the layered options and ready for provider-specific encoding.
3307
+ * @public
3308
+ */
3309
+ declare interface IResolvedImageOptions {
3310
+ /** Number of images to generate. */
3311
+ readonly n: number;
3312
+ /** Image size (OpenAI-style pixel strings). */
3313
+ readonly size?: string;
3314
+ /** Quality tier. */
3315
+ readonly quality?: string;
3316
+ /** Seed for reproducibility. */
3317
+ readonly seed?: number;
3318
+ readonly style?: string;
3319
+ readonly outputFormat?: string;
3320
+ readonly outputCompression?: number;
3321
+ readonly background?: string;
3322
+ readonly moderation?: string;
3323
+ readonly aspectRatio?: string;
3324
+ readonly resolution?: string;
3325
+ readonly imagenAspectRatio?: string;
3326
+ readonly imageSize?: string;
3327
+ readonly addWatermark?: boolean;
3328
+ readonly enhancePrompt?: boolean;
3329
+ readonly imagenOutputMimeType?: string;
3330
+ readonly imagenOutputCompressionQuality?: number;
3331
+ readonly personGeneration?: string;
3332
+ readonly geminiAspectRatio?: string;
3333
+ readonly otherParams?: JsonObject;
3334
+ }
3335
+
3336
+ /**
3337
+ * Checks if a JSON object appears to be an encrypted file.
3338
+ * Uses the format field as a discriminator.
3339
+ * @param json - JSON object to check
3340
+ * @returns true if the object has the encrypted file format field
3341
+ * @public
3342
+ */
3343
+ declare function isEncryptedFile(json: unknown): boolean;
3344
+
3345
+ /**
3346
+ * Checks if a JSON object appears to be a key store file.
3347
+ * Uses the format field as a discriminator.
3348
+ * @param json - JSON object to check
3349
+ * @returns true if the object has the key store format field
3350
+ * @public
3351
+ */
3352
+ declare function isKeyStoreFile(json: unknown): boolean;
3353
+
3354
+ /**
3355
+ * A `Converter` which converts an iso formatted string, a number or a `Date` object to
3356
+ * a `Date` object.
3357
+ * @public
3358
+ */
3359
+ declare const isoDate: Converter<Date, unknown>;
3360
+
3361
+ /**
3362
+ * A `Converter` which converts an iso formatted string, a number or a `Date` object to
3363
+ * a `DateTime` object.
3364
+ * @public
3365
+ */
3366
+ declare const isoDateTime: Converter<DateTime, unknown>;
3367
+
3368
+ /**
3369
+ * Thinking/reasoning mode configuration for a completion request.
3370
+ *
3371
+ * @remarks
3372
+ * The generic `effort` field covers the common-subset cross-provider vocabulary.
3373
+ * For provider-specific precision (Anthropic 'max', OpenAI 'xhigh', Gemini token
3374
+ * budgets, xAI effort-level tuning), use the `providers` array.
3375
+ *
3376
+ * Absence (or undefined) means "no thinking mode" — existing callers are unaffected.
3377
+ *
3378
+ * @public
3379
+ */
3380
+ declare interface IThinkingConfig {
3381
+ /**
3382
+ * Cross-provider effort level. Common-subset mapping:
3383
+ * - 'low': Anthropic effort:low | OpenAI effort:low | Gemini thinkingBudget:1024 | xAI reasoning_effort:low
3384
+ * - 'medium': effort:medium | effort:medium | thinkingBudget:4096 | reasoning_effort:medium
3385
+ * - 'high': effort:high | effort:high | thinkingBudget:8192 | reasoning_effort:high
3386
+ */
3387
+ readonly effort?: 'low' | 'medium' | 'high';
3388
+ /**
3389
+ * Optional per-provider precision blocks. Blocks for providers that don't
3390
+ * match the resolved model's provider are silently skipped.
3391
+ */
3392
+ readonly providers?: ReadonlyArray<IThinkingProviderConfig>;
3393
+ }
3394
+
3395
+ /**
3396
+ * Discriminated union of per-provider thinking config blocks.
3397
+ * @public
3398
+ */
3399
+ declare type IThinkingProviderConfig = IAnthropicThinkingOptions | IOpenAiThinkingOptions | IGeminiThinkingOptions | IXAiThinkingOptions | IOtherThinkingOptions;
3400
+
3401
+ /**
3402
+ * Represents a variable reference extracted from a Mustache template.
3403
+ * @public
3404
+ */
3405
+ declare interface IVariableRef {
3406
+ /**
3407
+ * The raw variable name as it appears in the template (e.g., 'user.name')
3408
+ */
3409
+ readonly name: string;
3410
+ /**
3411
+ * The path segments parsed from the variable name (e.g., ['user', 'name'])
3412
+ */
3413
+ readonly path: readonly string[];
3414
+ /**
3415
+ * The type of token this variable was extracted from
3416
+ */
3417
+ readonly tokenType: MustacheTokenType;
3418
+ /**
3419
+ * Whether this variable is used in a section context (# or ^)
3420
+ * Section variables may reference arrays/objects for iteration
3421
+ */
3422
+ readonly isSection: boolean;
3423
+ }
3424
+
3425
+ /**
3426
+ * Caller-supplied HKDF parameters that domain-separate one
3427
+ * {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes} call from another.
3428
+ * Two wraps that share recipient but differ on `salt` or `info` derive distinct
3429
+ * wrap keys, so callers should pick values that bind the wrap to its
3430
+ * application context (e.g. a content hash for `salt` and a secret name for
3431
+ * `info`).
3432
+ *
3433
+ * Both fields are required; pass an empty `Uint8Array` if the caller has no
3434
+ * value to bind on a given axis. Silent defaulting would hide protocol
3435
+ * mistakes, so the API does not pick defaults.
3436
+ * @public
3437
+ */
3438
+ declare interface IWrapBytesOptions {
3439
+ /**
3440
+ * HKDF salt. Domain-separates this wrap from others in different contexts.
3441
+ * Caller picks; common choices include a content hash, document id, channel
3442
+ * id, etc.
3443
+ */
3444
+ readonly salt: Uint8Array;
3445
+ /**
3446
+ * HKDF info. Further binds the derived key to a specific use within the
3447
+ * calling application. Caller picks; common choices include a secret name,
3448
+ * message type, or version tag.
3449
+ */
3450
+ readonly info: Uint8Array;
1375
3451
  }
1376
3452
 
1377
3453
  /**
1378
- * Checks if a JSON object appears to be an encrypted file.
1379
- * Uses the format field as a discriminator.
1380
- * @param json - JSON object to check
1381
- * @returns true if the object has the encrypted file format field
3454
+ * Output of {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes}. The
3455
+ * shape is JSON-serializable so it can travel directly over the wire or be
3456
+ * persisted as-is.
1382
3457
  * @public
1383
3458
  */
1384
- declare function isEncryptedFile(json: unknown): boolean;
3459
+ declare interface IWrappedBytes {
3460
+ /**
3461
+ * Sender's ephemeral ECDH P-256 public key as a JSON Web Key. The matching
3462
+ * ephemeral private key is dropped after the shared-secret derive.
3463
+ */
3464
+ readonly ephemeralPublicKey: JsonWebKey;
3465
+ /**
3466
+ * AES-GCM nonce, base64-encoded. 12 bytes (96 bits) — the standard AES-GCM
3467
+ * nonce length.
3468
+ */
3469
+ readonly nonce: string;
3470
+ /**
3471
+ * AES-GCM ciphertext concatenated with the 16-byte authentication tag,
3472
+ * base64-encoded. Tampering with either the nonce or the ciphertext causes
3473
+ * unwrap to fail GCM authentication.
3474
+ */
3475
+ readonly ciphertext: string;
3476
+ }
1385
3477
 
1386
3478
  /**
1387
- * Checks if a JSON object appears to be a key store file.
1388
- * Uses the format field as a discriminator.
1389
- * @param json - JSON object to check
1390
- * @returns true if the object has the key store format field
3479
+ * xAI-specific thinking configuration.
1391
3480
  * @public
1392
3481
  */
1393
- declare function isKeyStoreFile(json: unknown): boolean;
3482
+ declare interface IXAiThinkingConfig {
3483
+ /**
3484
+ * xAI reasoning effort. Maps 1:1 to `reasoning_effort` on the wire.
3485
+ * For grok-4, the adapter omits this field (grok-4 always reasons and
3486
+ * rejects the parameter).
3487
+ */
3488
+ readonly effort?: 'none' | 'low' | 'medium' | 'high';
3489
+ }
1394
3490
 
1395
3491
  /**
1396
- * A `Converter` which converts an iso formatted string, a number or a `Date` object to
1397
- * a `Date` object.
3492
+ * xAI-specific thinking options block.
1398
3493
  * @public
1399
3494
  */
1400
- declare const isoDate: Converter<Date, unknown>;
3495
+ declare interface IXAiThinkingOptions {
3496
+ readonly provider: 'xai';
3497
+ readonly models?: ReadonlyArray<XAiThinkingModelNames>;
3498
+ readonly config: IXAiThinkingConfig;
3499
+ }
1401
3500
 
1402
3501
  /**
1403
- * Represents a variable reference extracted from a Mustache template.
3502
+ * Options for YAML serialization, mirroring commonly-used `js-yaml` `DumpOptions`.
1404
3503
  * @public
1405
3504
  */
1406
- declare interface IVariableRef {
3505
+ declare interface IYamlSerializeOptions {
1407
3506
  /**
1408
- * The raw variable name as it appears in the template (e.g., 'user.name')
3507
+ * Indentation width in spaces (default: 2).
1409
3508
  */
1410
- readonly name: string;
3509
+ readonly indent?: number;
1411
3510
  /**
1412
- * The path segments parsed from the variable name (e.g., ['user', 'name'])
3511
+ * Nesting level at which to switch from block to flow style.
3512
+ * -1 means block style everywhere (default: -1).
1413
3513
  */
1414
- readonly path: readonly string[];
3514
+ readonly flowLevel?: number;
1415
3515
  /**
1416
- * The type of token this variable was extracted from
3516
+ * If true, sort keys when dumping (default: false).
1417
3517
  */
1418
- readonly tokenType: MustacheTokenType;
3518
+ readonly sortKeys?: boolean;
1419
3519
  /**
1420
- * Whether this variable is used in a section context (# or ^)
1421
- * Section variables may reference arrays/objects for iteration
3520
+ * Maximum line width (default: 80).
1422
3521
  */
1423
- readonly isSection: boolean;
3522
+ readonly lineWidth?: number;
3523
+ /**
3524
+ * If true, don't convert duplicate objects into references (default: false).
3525
+ */
3526
+ readonly noRefs?: boolean;
3527
+ /**
3528
+ * If true, don't add an indentation level to array elements (default: false).
3529
+ */
3530
+ readonly noArrayIndent?: boolean;
3531
+ /**
3532
+ * If true, all non-key strings will be quoted (default: false).
3533
+ */
3534
+ readonly forceQuotes?: boolean;
1424
3535
  }
1425
3536
 
1426
3537
  /**
@@ -1452,11 +3563,54 @@ declare interface JarRecordParserOptions {
1452
3563
  readonly fixedContinuationSize?: number;
1453
3564
  }
1454
3565
 
3566
+ /**
3567
+ * Controls the optional system-prompt augmentation applied by
3568
+ * {@link AiAssist.generateJsonCompletion}.
3569
+ *
3570
+ * - `'smart'` (default): append {@link AiAssist.SMART_JSON_PROMPT_HINT}.
3571
+ * - `'none'`: do not modify the prompt.
3572
+ * - A string: append the supplied text verbatim.
3573
+ *
3574
+ * @remarks
3575
+ * The `string & {}` branch is the standard TypeScript trick that prevents
3576
+ * the literal members from being widened away — callers still get
3577
+ * autocomplete for `'smart'` and `'none'` while accepting any string.
3578
+ *
3579
+ * @public
3580
+ */
3581
+ declare type JsonPromptHint = 'smart' | 'none' | (string & {});
3582
+
3583
+ /**
3584
+ * A function that pulls a JSON-shaped substring out of arbitrary model text.
3585
+ * Implementations strip whatever wrappers the model added (fences, preamble,
3586
+ * trailing prose) and return the JSON-shaped substring ready for `JSON.parse`.
3587
+ * @public
3588
+ */
3589
+ declare type JsonTextExtractor = (text: string) => Result<string>;
3590
+
3591
+ /**
3592
+ * In-place shape check for a JSON Web Key. Asserts only that the input is a
3593
+ * non-array object whose `kty` discriminator is a string; every other JWK
3594
+ * field passes through untouched. This is intentionally **not** a true JWK
3595
+ * validator — per-algorithm correctness (RSA `n`/`e`, EC `crv`/`x`/`y`,
3596
+ * key-size constraints, etc.) is delegated to `crypto.subtle.importKey` at
3597
+ * first use, which is the authoritative checker. The "shape" suffix in the
3598
+ * name is the warning sign for readers expecting full validation.
3599
+ * @remarks
3600
+ * Built with `Validators.object` (in-place, non-strict) so unknown JWK fields
3601
+ * survive the round-trip; the cast to `FieldValidators<JsonWebKey>` is required
3602
+ * only because TypeScript's mapped type demands an entry for every key in
3603
+ * `JsonWebKey`. At runtime the `ObjectValidator` only inspects keys present in
3604
+ * the field-validators map.
3605
+ * @public
3606
+ */
3607
+ declare const jsonWebKeyShape: Validator<JsonWebKey>;
3608
+
1455
3609
  /**
1456
3610
  * Supported key derivation functions.
1457
3611
  * @public
1458
3612
  */
1459
- declare type KeyDerivationFunction = 'pbkdf2';
3613
+ declare type KeyDerivationFunction = 'pbkdf2' | 'argon2id';
1460
3614
 
1461
3615
  /**
1462
3616
  * Converter for {@link CryptoUtils.KeyDerivationFunction | key derivation function} type.
@@ -1466,22 +3620,72 @@ declare const keyDerivationFunction: Converter<KeyDerivationFunction>;
1466
3620
 
1467
3621
  /**
1468
3622
  * Converter for {@link CryptoUtils.IKeyDerivationParams | key derivation parameters}.
3623
+ * Handles both PBKDF2 and Argon2id discriminated union arms.
1469
3624
  * @public
1470
3625
  */
1471
3626
  declare const keyDerivationParams: Converter<IKeyDerivationParams>;
1472
3627
 
3628
+ /**
3629
+ * Asymmetric keypair algorithms supported by the crypto provider.
3630
+ * - `'ecdsa-p256'`: ECDSA over the P-256 curve, for signing.
3631
+ * - `'rsa-oaep-2048'`: RSA-OAEP, 2048-bit modulus with SHA-256, for encryption.
3632
+ * - `'ecdh-p256'`: ECDH over the P-256 curve, for key agreement
3633
+ * (e.g. as the recipient keypair in
3634
+ * {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes} /
3635
+ * {@link CryptoUtils.ICryptoProvider.unwrapBytes | unwrapBytes}).
3636
+ * - `'ed25519'`: EdDSA over the Edwards25519 curve, for signing.
3637
+ * Deterministic — the per-signature nonce is derived from the private key
3638
+ * and message rather than sampled randomly, eliminating the random-nonce
3639
+ * reuse risk that ECDSA carries. Distinct from X25519 (key agreement over
3640
+ * the Montgomery form, Curve25519).
3641
+ * - `'x25519'`: Diffie-Hellman key agreement over the Montgomery form of
3642
+ * Curve25519. Key-agreement only — use `deriveBits`/`deriveKey` to produce
3643
+ * a shared secret from one party's private key and the peer's public key.
3644
+ * Distinct from Ed25519 (which uses the twisted-Edwards form for signing).
3645
+ * @public
3646
+ */
3647
+ declare type KeyPairAlgorithm = 'ecdsa-p256' | 'rsa-oaep-2048' | 'ecdh-p256' | 'ed25519' | 'x25519';
3648
+
3649
+ /**
3650
+ * Converter for {@link CryptoUtils.KeyStore.KeyPairAlgorithm | key pair algorithm}.
3651
+ * @public
3652
+ */
3653
+ declare const keyPairAlgorithm: Converter<KeyPairAlgorithm>;
3654
+
3655
+ /**
3656
+ * Lookup table from {@link CryptoUtils.KeyPairAlgorithm} to the WebCrypto
3657
+ * parameters needed to drive `crypto.subtle`. Shared between every
3658
+ * {@link CryptoUtils.ICryptoProvider} implementation since both Node and
3659
+ * browser providers speak the same WebCrypto API. Exposed for downstream
3660
+ * provider implementations (e.g. browser-side providers in `@fgv/ts-web-extras`).
3661
+ * @public
3662
+ */
3663
+ declare const keyPairAlgorithmParams: Readonly<Record<KeyPairAlgorithm, IKeyPairAlgorithmParams>>;
3664
+
1473
3665
  declare namespace KeyStore {
1474
3666
  export {
1475
3667
  Converters_2 as Converters,
1476
3668
  KeyStore_2 as KeyStore,
1477
3669
  isKeyStoreFile,
3670
+ allKeyPairAlgorithms,
3671
+ KeyPairAlgorithm,
1478
3672
  KeyStoreFormat,
1479
3673
  KEYSTORE_FORMAT,
1480
3674
  DEFAULT_KEYSTORE_ITERATIONS,
1481
3675
  MIN_SALT_LENGTH,
3676
+ KeyStoreSymmetricSecretType,
3677
+ allKeyStoreSymmetricSecretTypes,
3678
+ KeyStoreAsymmetricSecretType,
3679
+ allKeyStoreAsymmetricSecretTypes,
1482
3680
  KeyStoreSecretType,
1483
3681
  allKeyStoreSecretTypes,
3682
+ IKeyStoreSymmetricEntry,
3683
+ IKeyStoreAsymmetricEntry,
3684
+ IKeyStoreEntry,
1484
3685
  IKeyStoreSecretEntry,
3686
+ IKeyStoreSymmetricEntryJson,
3687
+ IKeyStoreAsymmetricEntryJson,
3688
+ IKeyStoreEntryJson,
1485
3689
  IKeyStoreSecretEntryJson,
1486
3690
  IKeyStoreVaultContents,
1487
3691
  IKeyStoreFile,
@@ -1491,9 +3695,15 @@ declare namespace KeyStore {
1491
3695
  IAddSecretResult,
1492
3696
  IAddSecretOptions,
1493
3697
  IImportSecretOptions,
3698
+ IImportKeyOptions,
1494
3699
  IAddSecretFromPasswordOptions,
1495
3700
  DEFAULT_SECRET_ITERATIONS,
1496
- IAddSecretFromPasswordResult
3701
+ IAddSecretFromPasswordResult,
3702
+ IAddSecretFromPasswordArgon2idOptions,
3703
+ IAddKeyPairOptions,
3704
+ IAddKeyPairResult,
3705
+ IRemoveSecretResult,
3706
+ IPrivateKeyStorage
1497
3707
  }
1498
3708
  }
1499
3709
 
@@ -1530,6 +3740,7 @@ declare namespace KeyStore {
1530
3740
  */
1531
3741
  declare class KeyStore_2 implements IEncryptionProvider {
1532
3742
  private readonly _cryptoProvider;
3743
+ private readonly _privateKeyStorage;
1533
3744
  private readonly _iterations;
1534
3745
  private _keystoreFile;
1535
3746
  private _salt;
@@ -1571,6 +3782,21 @@ declare class KeyStore_2 implements IEncryptionProvider {
1571
3782
  * @public
1572
3783
  */
1573
3784
  unlock(password: string): Promise<Result<KeyStore_2>>;
3785
+ /**
3786
+ * Unlocks an existing key store with a pre-derived key, bypassing
3787
+ * PBKDF2 key derivation. Use this when the derived key has been
3788
+ * stored externally (e.g., in another key store) and the original
3789
+ * password is no longer available.
3790
+ *
3791
+ * The supplied key must have been derived from the correct password
3792
+ * using the key store file's own PBKDF2 parameters (salt and
3793
+ * iteration count).
3794
+ *
3795
+ * @param derivedKey - The pre-derived master key (32 bytes for AES-256)
3796
+ * @returns Success with this instance when unlocked, Failure if key is incorrect
3797
+ * @public
3798
+ */
3799
+ unlockWithKey(derivedKey: Uint8Array): Promise<Result<KeyStore_2>>;
1574
3800
  /**
1575
3801
  * Locks the key store, clearing all secrets from memory.
1576
3802
  * @param force - If true, discards unsaved changes
@@ -1613,12 +3839,23 @@ declare class KeyStore_2 implements IEncryptionProvider {
1613
3839
  */
1614
3840
  listSecrets(): Result<readonly string[]>;
1615
3841
  /**
1616
- * Gets a secret by name.
3842
+ * Gets a secret by name. Returns the {@link CryptoUtils.KeyStore.IKeyStoreEntry | discriminated union}
3843
+ * — callers must check `entry.type` before accessing `key`/`id` since asymmetric
3844
+ * entries carry no raw key material.
1617
3845
  * @param name - Name of the secret
1618
3846
  * @returns Success with secret entry, Failure if not found or locked
1619
3847
  * @public
1620
3848
  */
1621
- getSecret(name: string): Result<IKeyStoreSecretEntry>;
3849
+ getSecret(name: string): Result<IKeyStoreEntry>;
3850
+ /**
3851
+ * Returns the public-key JWK for an asymmetric-keypair entry.
3852
+ * Available without {@link CryptoUtils.KeyStore.IPrivateKeyStorage} since the
3853
+ * public key lives in the vault metadata directly.
3854
+ * @param name - Name of the entry
3855
+ * @returns Success with the JWK, Failure if not found, locked, or wrong type
3856
+ * @public
3857
+ */
3858
+ getPublicKeyJwk(name: string): Result<JsonWebKey>;
1622
3859
  /**
1623
3860
  * Checks if a secret exists.
1624
3861
  * @param name - Name of the secret
@@ -1635,14 +3872,20 @@ declare class KeyStore_2 implements IEncryptionProvider {
1635
3872
  */
1636
3873
  addSecret(name: string, options?: IAddSecretOptions): Promise<Result<IAddSecretResult>>;
1637
3874
  /**
1638
- * Imports an existing secret key.
3875
+ * Imports raw 32-byte key material into the vault.
3876
+ *
3877
+ * Always validates that the key is exactly 32 bytes (AES-256). The optional
3878
+ * `type` field is a classification label stored with the entry; it does not
3879
+ * change the validation rules. For importing UTF-8 API key strings (variable
3880
+ * length), use {@link KeyStore.importApiKey} instead.
3881
+ *
1639
3882
  * @param name - Unique name for the secret
1640
- * @param key - The 32-byte AES-256 key
1641
- * @param options - Optional description, whether to replace existing
3883
+ * @param key - The 32-byte AES-256 key material
3884
+ * @param options - Optional type classification, description, whether to replace existing
1642
3885
  * @returns Success with entry, Failure if locked, key invalid, or exists and !replace
1643
3886
  * @public
1644
3887
  */
1645
- importSecret(name: string, key: Uint8Array, options?: IImportSecretOptions): Result<IAddSecretResult>;
3888
+ importSecret(name: string, key: Uint8Array, options?: IImportKeyOptions): Promise<Result<IAddSecretResult>>;
1646
3889
  /**
1647
3890
  * Adds a secret derived from a password using PBKDF2.
1648
3891
  *
@@ -1659,12 +3902,81 @@ declare class KeyStore_2 implements IEncryptionProvider {
1659
3902
  */
1660
3903
  addSecretFromPassword(name: string, password: string, options?: IAddSecretFromPasswordOptions): Promise<Result<IAddSecretFromPasswordResult>>;
1661
3904
  /**
1662
- * Removes a secret by name.
3905
+ * Verifies that a candidate password derives the same key material currently
3906
+ * stored under `name`, using the supplied
3907
+ * {@link CryptoUtils.IKeyDerivationParams | key derivation parameters}.
3908
+ *
3909
+ * The keystore does not persist per-slot key derivation parameters with the
3910
+ * entry — callers receive them from `addSecretFromPassword` and store them
3911
+ * alongside the encrypted artifact (or wherever else makes sense). Pass
3912
+ * those same parameters here for verification.
3913
+ *
3914
+ * Re-derives a key from `password` + `keyDerivation`, then compares it to
3915
+ * the stored key material in constant time. Restricted to entries of type
3916
+ * `'encryption-key'` — the type produced by `addSecretFromPassword`. Other
3917
+ * symmetric types (`'api-key'`) and asymmetric entries are rejected so
3918
+ * the boolean result reflects "this slot accepts this password" rather
3919
+ * than an incidental byte-equality match against unrelated material.
3920
+ *
3921
+ * Note: the keystore does not currently flag whether an `'encryption-key'`
3922
+ * entry was actually password-derived (vs. random via `addSecret` or raw
3923
+ * via `importSecret`). A `true` result therefore means "the candidate
3924
+ * password produces the same 32 bytes currently stored", which is what
3925
+ * the equivalent consumer-side helper (`verifyGatePassword`) already
3926
+ * implies for entries it manages.
3927
+ *
3928
+ * @param name - Name of the secret to verify against
3929
+ * @param password - Candidate password to test
3930
+ * @param keyDerivation - The key derivation parameters returned by
3931
+ * `addSecretFromPassword` when the secret was created. Only
3932
+ * `kdf: 'pbkdf2'` is supported.
3933
+ * @returns Success(true) when the candidate matches the stored key,
3934
+ * Success(false) when it does not, Failure if locked, secret missing,
3935
+ * wrong type, unsupported `kdf`, or key derivation fails
3936
+ * @public
3937
+ */
3938
+ verifySecretFromPassword(name: string, password: string, keyDerivation: IKeyDerivationParams): Promise<Result<boolean>>;
3939
+ /**
3940
+ * Adds a secret derived from a password using Argon2id (RFC 9106).
3941
+ *
3942
+ * The Argon2id provider must be supplied explicitly; the KeyStore does not
3943
+ * hold one by default (consumers opt in by depending on the argon2 package).
3944
+ *
3945
+ * Returns the key derivation parameters so callers can store them alongside
3946
+ * encrypted artifacts, enabling future re-derivation and verification.
3947
+ *
3948
+ * @param name - Unique name for the secret
3949
+ * @param password - Password or passphrase
3950
+ * @param argon2idProvider - Argon2id provider (Node or Browser implementation)
3951
+ * @param options - Optional: Argon2id params (defaults to ARGON2ID_OWASP_MIN), description, replace flag
3952
+ * @returns Success with entry and keyDerivation params, Failure if locked or invalid
3953
+ * @public
3954
+ */
3955
+ addSecretFromPasswordArgon2id(name: string, password: string, argon2idProvider: IArgon2idProvider, options?: IAddSecretFromPasswordArgon2idOptions): Promise<Result<IAddSecretFromPasswordResult>>;
3956
+ /**
3957
+ * Verifies a candidate password against an Argon2id-derived entry using the
3958
+ * supplied key derivation parameters. Constant-time comparison.
3959
+ *
3960
+ * @param name - Name of the secret to verify against
3961
+ * @param password - Candidate password to test
3962
+ * @param argon2idProvider - Argon2id provider (must produce bit-identical output for identical inputs)
3963
+ * @param keyDerivation - The Argon2id key derivation parameters returned by `addSecretFromPasswordArgon2id`
3964
+ * @returns Success(true) if candidate matches stored key, Success(false) if not,
3965
+ * Failure if locked, secret missing, wrong type, or derivation fails
3966
+ * @public
3967
+ */
3968
+ verifySecretFromPasswordArgon2id(name: string, password: string, argon2idProvider: IArgon2idProvider, keyDerivation: IArgon2idKeyDerivationParams): Promise<Result<boolean>>;
3969
+ /**
3970
+ * Removes a secret by name. Vault-first: the in-memory vault entry is dropped
3971
+ * before any storage cleanup runs. For asymmetric-keypair entries, best-effort
3972
+ * calls {@link CryptoUtils.KeyStore.IPrivateKeyStorage}.delete on the entry's
3973
+ * `id`; a failure is reported via `warning` on the result but does not roll
3974
+ * back the vault removal.
1663
3975
  * @param name - Name of the secret to remove
1664
- * @returns Success with removed entry, Failure if not found or locked
3976
+ * @returns Success with removed entry (and optional warning), Failure if not found or locked
1665
3977
  * @public
1666
3978
  */
1667
- removeSecret(name: string): Result<IKeyStoreSecretEntry>;
3979
+ removeSecret(name: string): Promise<Result<IRemoveSecretResult>>;
1668
3980
  /**
1669
3981
  * Imports an API key string into the vault.
1670
3982
  * The string is UTF-8 encoded and stored with type `'api-key'`.
@@ -1674,7 +3986,7 @@ declare class KeyStore_2 implements IEncryptionProvider {
1674
3986
  * @returns Success with entry, Failure if locked, empty, or exists and !replace
1675
3987
  * @public
1676
3988
  */
1677
- importApiKey(name: string, apiKey: string, options?: IImportSecretOptions): Result<IAddSecretResult>;
3989
+ importApiKey(name: string, apiKey: string, options?: IImportSecretOptions): Promise<Result<IAddSecretResult>>;
1678
3990
  /**
1679
3991
  * Retrieves an API key string by name.
1680
3992
  * Only works for secrets with type `'api-key'`.
@@ -1683,6 +3995,41 @@ declare class KeyStore_2 implements IEncryptionProvider {
1683
3995
  * @public
1684
3996
  */
1685
3997
  getApiKey(name: string): Result<string>;
3998
+ /**
3999
+ * Adds a new asymmetric keypair to the vault. Storage-first: the private key
4000
+ * is stored under a freshly-minted `id` before the public-key vault entry is
4001
+ * committed. If the storage call fails, no vault entry is written and the
4002
+ * operation returns Failure.
4003
+ *
4004
+ * When `replace: true` displaces an existing entry (asymmetric or symmetric),
4005
+ * a fresh `id` is minted; the displaced entry's resources are released
4006
+ * best-effort. Failure of the storage delete is reported via `warning` on the
4007
+ * result but does not roll back the replacement.
4008
+ *
4009
+ * Requires a {@link CryptoUtils.KeyStore.IPrivateKeyStorage} backend
4010
+ * supplied at construction.
4011
+ *
4012
+ * @param name - Unique name for the entry
4013
+ * @param options - Algorithm, optional description, replace flag
4014
+ * @returns Success with the new entry, Failure if locked, no provider, or storage write failed
4015
+ * @public
4016
+ */
4017
+ addKeyPair(name: string, options: IAddKeyPairOptions): Promise<Result<IAddKeyPairResult>>;
4018
+ /**
4019
+ * Retrieves the keypair for an asymmetric-keypair entry. The private key is
4020
+ * loaded from {@link CryptoUtils.KeyStore.IPrivateKeyStorage} on every call —
4021
+ * the keystore never caches private `CryptoKey` references between calls.
4022
+ * The public key is re-imported from the vault's JWK so callers always
4023
+ * receive a `CryptoKey` rather than the JWK form.
4024
+ * @param name - Name of the entry
4025
+ * @returns Success with `{ publicKey, privateKey }`, Failure if not found,
4026
+ * locked, wrong type, no provider, or storage load failed.
4027
+ * @public
4028
+ */
4029
+ getKeyPair(name: string): Promise<Result<{
4030
+ publicKey: CryptoKey;
4031
+ privateKey: CryptoKey;
4032
+ }>>;
1686
4033
  /**
1687
4034
  * Lists secret names filtered by type.
1688
4035
  * @param type - The secret type to filter by
@@ -1697,7 +4044,7 @@ declare class KeyStore_2 implements IEncryptionProvider {
1697
4044
  * @returns Success with updated entry, Failure if source not found, target exists, or locked
1698
4045
  * @public
1699
4046
  */
1700
- renameSecret(oldName: string, newName: string): Result<IKeyStoreSecretEntry>;
4047
+ renameSecret(oldName: string, newName: string): Result<IKeyStoreEntry>;
1701
4048
  /**
1702
4049
  * Saves the key store, returning the encrypted file content.
1703
4050
  * Requires the master password to encrypt.
@@ -1706,6 +4053,20 @@ declare class KeyStore_2 implements IEncryptionProvider {
1706
4053
  * @public
1707
4054
  */
1708
4055
  save(password: string): Promise<Result<IKeyStoreFile>>;
4056
+ /**
4057
+ * Saves the key store using a pre-derived key, bypassing PBKDF2 key
4058
+ * derivation. Use this when the derived key has been stored externally
4059
+ * (e.g., in another key store) and the original password is no longer
4060
+ * available.
4061
+ *
4062
+ * The supplied key must be the same key that was (or would be) derived
4063
+ * from the master password using the key store's PBKDF2 parameters.
4064
+ *
4065
+ * @param derivedKey - The pre-derived master key (32 bytes for AES-256)
4066
+ * @returns Success with IKeyStoreFile, Failure if locked or key invalid
4067
+ * @public
4068
+ */
4069
+ saveWithKey(derivedKey: Uint8Array): Promise<Result<IKeyStoreFile>>;
1709
4070
  /**
1710
4071
  * Changes the master password.
1711
4072
  * Re-encrypts the vault with the new password-derived key.
@@ -1730,6 +4091,40 @@ declare class KeyStore_2 implements IEncryptionProvider {
1730
4091
  * @public
1731
4092
  */
1732
4093
  getEncryptionConfig(): Result<Pick<IEncryptionConfig, 'secretProvider' | 'cryptoProvider'>>;
4094
+ /**
4095
+ * Encrypts the vault with a derived key and returns the key store file.
4096
+ * Shared by `save()` and `saveWithKey()`.
4097
+ */
4098
+ private _encryptVault;
4099
+ /**
4100
+ * Decrypts the vault with a derived key and loads secrets into memory.
4101
+ * Shared by `unlock()` and `unlockWithKey()`.
4102
+ */
4103
+ private _decryptVault;
4104
+ /**
4105
+ * Releases the resources held by an entry being displaced from the vault.
4106
+ * Symmetric entries get their key buffer zeroed in place. Asymmetric entries
4107
+ * have their private-key blob best-effort deleted from
4108
+ * {@link CryptoUtils.KeyStore.IPrivateKeyStorage}; if the storage call fails,
4109
+ * a warning string is returned but the displacement still proceeds — the
4110
+ * orphaned blob is left for consumer-side GC. Without a configured provider,
4111
+ * asymmetric cleanup is silently skipped.
4112
+ * @returns A warning string if storage cleanup failed, otherwise undefined.
4113
+ */
4114
+ private _releaseEntryResources;
4115
+ /**
4116
+ * Constant-time byte comparison. Returns false immediately for length
4117
+ * mismatch (length is not secret); for equal-length inputs, walks the full
4118
+ * buffer accumulating differences via XOR so the running time does not leak
4119
+ * the position of the first differing byte.
4120
+ */
4121
+ private static _timingSafeEqual;
4122
+ /**
4123
+ * Mints a fresh UUID v4 storage handle using the crypto provider's
4124
+ * {@link CryptoUtils.ICryptoProvider.generateRandomBytes | generateRandomBytes}.
4125
+ * Random-bytes failures propagate as Failure.
4126
+ */
4127
+ private _generateId;
1733
4128
  }
1734
4129
 
1735
4130
  /**
@@ -1738,6 +4133,31 @@ declare class KeyStore_2 implements IEncryptionProvider {
1738
4133
  */
1739
4134
  declare const KEYSTORE_FORMAT: KeyStoreFormat;
1740
4135
 
4136
+ /**
4137
+ * Converter for {@link CryptoUtils.KeyStore.IKeyStoreAsymmetricEntryJson | asymmetric keypair entry} in JSON form.
4138
+ * The `publicKeyJwk` field passes through {@link CryptoUtils.KeyStore.Converters.jsonWebKeyShape | jsonWebKeyShape}
4139
+ * (shape check only — see its docs); cryptographic correctness is enforced by
4140
+ * `crypto.subtle.importKey` at use.
4141
+ * @public
4142
+ */
4143
+ declare const keystoreAsymmetricEntryJson: Converter<IKeyStoreAsymmetricEntryJson>;
4144
+
4145
+ /**
4146
+ * Discriminator for asymmetric secret types stored in the vault.
4147
+ * - `'asymmetric-keypair'`: A public/private key pair. The public key is held in
4148
+ * the vault as a JWK; the private key lives in the supplied
4149
+ * {@link CryptoUtils.KeyStore.IPrivateKeyStorage} provider.
4150
+ * @public
4151
+ */
4152
+ declare type KeyStoreAsymmetricSecretType = 'asymmetric-keypair';
4153
+
4154
+ /**
4155
+ * Converter for {@link CryptoUtils.KeyStore.KeyStoreAsymmetricSecretType | asymmetric secret type} discriminator.
4156
+ * Accepts only `'asymmetric-keypair'`.
4157
+ * @public
4158
+ */
4159
+ declare const keystoreAsymmetricSecretType: Converter<KeyStoreAsymmetricSecretType>;
4160
+
1741
4161
  /**
1742
4162
  * Converter for {@link CryptoUtils.KeyStore.IKeyStoreFile | encrypted key store file}.
1743
4163
  * @public
@@ -1763,25 +4183,59 @@ declare const keystoreFormat: Converter<KeyStoreFormat>;
1763
4183
  declare type KeyStoreLockState = 'locked' | 'unlocked';
1764
4184
 
1765
4185
  /**
1766
- * Converter for {@link CryptoUtils.KeyStore.IKeyStoreSecretEntryJson | key store secret entry} in JSON format.
1767
- * The `type` field is optional for backwards compatibility — missing means `'encryption-key'`.
4186
+ * Discriminated-union converter for any {@link CryptoUtils.KeyStore.IKeyStoreEntryJson | key store entry} in JSON form.
4187
+ * Routes by the `type` field: `'asymmetric-keypair'` is parsed by
4188
+ * {@link CryptoUtils.KeyStore.Converters.keystoreAsymmetricEntryJson | keystoreAsymmetricEntryJson},
4189
+ * anything else (including a missing `type` field for backwards compatibility) by
4190
+ * {@link CryptoUtils.KeyStore.Converters.keystoreSymmetricEntryJson | keystoreSymmetricEntryJson}.
4191
+ * @public
4192
+ */
4193
+ declare const keystoreSecretEntryJson: Converter<IKeyStoreEntryJson>;
4194
+
4195
+ /**
4196
+ * Discriminator for any secret type stored in the vault.
4197
+ * @public
4198
+ */
4199
+ declare type KeyStoreSecretType = KeyStoreSymmetricSecretType | KeyStoreAsymmetricSecretType;
4200
+
4201
+ /**
4202
+ * Converter for {@link CryptoUtils.KeyStore.KeyStoreSecretType | any key store secret type} discriminator.
4203
+ * Accepts both symmetric and asymmetric type values.
4204
+ * @public
4205
+ */
4206
+ declare const keystoreSecretType: Converter<KeyStoreSecretType>;
4207
+
4208
+ /**
4209
+ * Converter for {@link CryptoUtils.KeyStore.IKeyStoreSymmetricEntryJson | symmetric secret entry} in JSON form.
4210
+ *
4211
+ * @remarks
4212
+ * Backwards compatibility with vaults written before asymmetric-keypair
4213
+ * support: those entries may lack the `type` discriminator on the wire. To
4214
+ * keep the model type honest (`type` is required on
4215
+ * {@link CryptoUtils.KeyStore.IKeyStoreSymmetricEntryJson}, see its docs),
4216
+ * we declare `type` in `optionalFields` so the inner `Converters.object` will
4217
+ * accept input without it, then `.map()` injects the default
4218
+ * `'encryption-key'` when missing. The output therefore always carries the
4219
+ * discriminator and downstream code never sees the legacy missing-type form.
4220
+ *
1768
4221
  * @public
1769
4222
  */
1770
- declare const keystoreSecretEntryJson: Converter<IKeyStoreSecretEntryJson>;
4223
+ declare const keystoreSymmetricEntryJson: Converter<IKeyStoreSymmetricEntryJson>;
1771
4224
 
1772
4225
  /**
1773
- * Discriminator for secret types stored in the vault.
4226
+ * Discriminator for symmetric secret types stored in the vault.
1774
4227
  * - `'encryption-key'`: A 32-byte AES-256 encryption key.
1775
4228
  * - `'api-key'`: An arbitrary-length API key string (UTF-8 encoded).
1776
4229
  * @public
1777
4230
  */
1778
- declare type KeyStoreSecretType = 'encryption-key' | 'api-key';
4231
+ declare type KeyStoreSymmetricSecretType = 'encryption-key' | 'api-key';
1779
4232
 
1780
4233
  /**
1781
- * Converter for {@link CryptoUtils.KeyStore.KeyStoreSecretType | key store secret type} discriminator.
4234
+ * Converter for {@link CryptoUtils.KeyStore.KeyStoreSymmetricSecretType | symmetric secret type} discriminator.
4235
+ * Accepts only `'encryption-key'` and `'api-key'`.
1782
4236
  * @public
1783
4237
  */
1784
- declare const keystoreSecretType: Converter<KeyStoreSecretType>;
4238
+ declare const keystoreSymmetricSecretType: Converter<KeyStoreSymmetricSecretType>;
1785
4239
 
1786
4240
  /**
1787
4241
  * Converter for {@link CryptoUtils.KeyStore.IKeyStoreVaultContents | key store vault contents} (decrypted state).
@@ -1829,7 +4283,7 @@ declare const modelSpec: Converter<ModelSpec>;
1829
4283
  * Known context keys for model specification maps.
1830
4284
  * @public
1831
4285
  */
1832
- declare type ModelSpecKey = 'base' | 'tools' | 'image';
4286
+ declare type ModelSpecKey = 'base' | 'tools' | 'image' | 'thinking';
1833
4287
 
1834
4288
  /**
1835
4289
  * Converter for {@link ModelSpecKey}.
@@ -1837,18 +4291,61 @@ declare type ModelSpecKey = 'base' | 'tools' | 'image';
1837
4291
  */
1838
4292
  declare const modelSpecKey: Converter<ModelSpecKey>;
1839
4293
 
4294
+ /**
4295
+ * Decodes a multibase base64url (no-padding) string back to a `Uint8Array`.
4296
+ *
4297
+ * Validates that the first character is `'m'` (the multibase prefix for
4298
+ * RFC 4648 base64url without padding), then decodes the remaining body.
4299
+ *
4300
+ * @param encoded - A multibase-prefixed base64url string.
4301
+ * @returns `Success` with the decoded bytes, or `Failure` with error context.
4302
+ * @public
4303
+ */
4304
+ declare function multibaseBase64UrlDecode(encoded: string): Result<Uint8Array>;
4305
+
4306
+ /**
4307
+ * Encodes a `Uint8Array` as a multibase base64url (no-padding) string.
4308
+ *
4309
+ * The multibase prefix `'m'` identifies the encoding as RFC 4648 base64url
4310
+ * without padding. The body uses base64url alphabet: `+` → `-`, `/` → `_`,
4311
+ * and trailing `=` padding is stripped.
4312
+ *
4313
+ * @param data - The binary data to encode.
4314
+ * @returns A multibase-prefixed base64url string (`'m' + base64url-no-pad`).
4315
+ * @public
4316
+ */
4317
+ declare function multibaseBase64UrlEncode(data: Uint8Array): string;
4318
+
1840
4319
  declare namespace Mustache {
1841
4320
  export {
1842
4321
  IContextValidationResult,
1843
4322
  IMissingVariableDetail,
1844
4323
  IMustacheTemplateOptions,
1845
4324
  IVariableRef,
4325
+ MustacheEscapeStrategy,
1846
4326
  MustacheTokenType,
1847
4327
  MustacheTemplate
1848
4328
  }
1849
4329
  }
1850
4330
  export { Mustache }
1851
4331
 
4332
+ /**
4333
+ * Strategy applied to double-brace `{{name}}` tokens at render time.
4334
+ *
4335
+ * - `'html'`: the standard mustache.js HTML escape (back-compat default).
4336
+ * - `'none'`: verbatim passthrough — values are interpolated as-is
4337
+ * (coerced to `String`). Suitable for LLM-prompt rendering and other
4338
+ * non-HTML targets where `& → &amp;` corrupts the output.
4339
+ * - `(value) => string`: caller-supplied escape function.
4340
+ *
4341
+ * Note: triple-brace `{{{name}}}` (and `{{&name}}`) tokens are always
4342
+ * rendered unescaped regardless of this strategy — that is the standard
4343
+ * mustache.js semantics and is not affected by this option.
4344
+ *
4345
+ * @public
4346
+ */
4347
+ declare type MustacheEscapeStrategy = 'html' | 'none' | ((value: string) => string);
4348
+
1852
4349
  /**
1853
4350
  * A helper class for working with Mustache templates that provides
1854
4351
  * validation, variable extraction, and context validation utilities.
@@ -1864,6 +4361,8 @@ declare class MustacheTemplate {
1864
4361
  */
1865
4362
  readonly options: Readonly<IRequiredMustacheTemplateOptions>;
1866
4363
  private readonly _tokens;
4364
+ private readonly _writer;
4365
+ private readonly _escapeFn;
1867
4366
  private _variables?;
1868
4367
  private constructor();
1869
4368
  /**
@@ -1971,12 +4470,24 @@ declare class NodeCryptoProvider implements ICryptoProvider {
1971
4470
  * @returns `Success` with derived 32-byte key, or `Failure` with an error.
1972
4471
  */
1973
4472
  deriveKey(password: string, salt: Uint8Array, iterations: number): Promise<Result<Uint8Array>>;
4473
+ /**
4474
+ * Computes a SHA-256 hash of the given data.
4475
+ * @param data - UTF-8 string to hash
4476
+ * @returns `Success` with hex-encoded hash string, or `Failure` with an error.
4477
+ */
4478
+ sha256(data: string): Promise<Result<string>>;
1974
4479
  /**
1975
4480
  * Generates cryptographically secure random bytes.
1976
4481
  * @param length - Number of bytes to generate
1977
4482
  * @returns Success with random bytes, or Failure with error
1978
4483
  */
1979
4484
  generateRandomBytes(length: number): Result<Uint8Array>;
4485
+ /**
4486
+ * Generates a cryptographically random UUIDv4 via the platform Web Crypto API.
4487
+ * @returns `Success` with the generated UUID, or `Failure` if the runtime
4488
+ * does not expose `globalThis.crypto.randomUUID`.
4489
+ */
4490
+ generateUuid(): Result<Uuid>;
1980
4491
  /**
1981
4492
  * Encodes binary data to base64 string.
1982
4493
  * @param data - Binary data to encode
@@ -1989,6 +4500,102 @@ declare class NodeCryptoProvider implements ICryptoProvider {
1989
4500
  * @returns Success with decoded bytes, or Failure if invalid base64
1990
4501
  */
1991
4502
  fromBase64(base64: string): Result<Uint8Array>;
4503
+ /**
4504
+ * Generates a new asymmetric keypair using Node's WebCrypto.
4505
+ * @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} to use.
4506
+ * @param extractable - Whether the resulting keys may be exported.
4507
+ * @returns `Success` with the generated `CryptoKeyPair`, or `Failure` with an error.
4508
+ */
4509
+ generateKeyPair(algorithm: KeyPairAlgorithm, extractable: boolean): Promise<Result<CryptoKeyPair>>;
4510
+ /**
4511
+ * Exports a public `CryptoKey` as a JSON Web Key.
4512
+ * @remarks
4513
+ * Rejects non-public keys at runtime. WebCrypto's `exportKey('jwk', ...)`
4514
+ * does not enforce public-vs-private; without this guard a caller that
4515
+ * passed an extractable private key would receive its private fields
4516
+ * (`d`, `p`, `q`, ...) as JWK, defeating the method's name.
4517
+ * @param publicKey - Extractable public key to export.
4518
+ * @returns `Success` with the JWK, or `Failure` if not a public key or if export fails.
4519
+ */
4520
+ exportPublicKeyJwk(publicKey: CryptoKey): Promise<Result<JsonWebKey>>;
4521
+ /**
4522
+ * Imports a public-key JWK as a `CryptoKey` for the requested algorithm.
4523
+ * @param jwk - The JSON Web Key produced by a prior export.
4524
+ * @param algorithm - The algorithm the key was generated for.
4525
+ * @returns `Success` with the imported public `CryptoKey`, or `Failure` with an error.
4526
+ */
4527
+ importPublicKeyJwk(jwk: JsonWebKey, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;
4528
+ /**
4529
+ * Exports a public `CryptoKey` as a DER-encoded SPKI blob.
4530
+ * @param publicKey - The public `CryptoKey` to export.
4531
+ * @returns `Success` with the raw SPKI bytes, or `Failure` with error context.
4532
+ */
4533
+ exportPublicKeySpki(publicKey: CryptoKey): Promise<Result<Uint8Array>>;
4534
+ /**
4535
+ * Imports a public key from a DER-encoded SPKI blob.
4536
+ * @param spkiBytes - The raw SPKI bytes.
4537
+ * @param algorithm - The algorithm the key was generated for.
4538
+ * @returns `Success` with the imported public `CryptoKey`, or `Failure` with error context.
4539
+ */
4540
+ importPublicKeySpki(spkiBytes: Uint8Array, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;
4541
+ /**
4542
+ * Signs `data` with `privateKey` using the algorithm inferred from the key.
4543
+ * @param privateKey - A signing `CryptoKey` (`'ecdsa-p256'` or `'ed25519'`).
4544
+ * @param data - The bytes to sign.
4545
+ * @returns `Success` with the raw signature bytes, or `Failure` with error context.
4546
+ */
4547
+ sign(privateKey: CryptoKey, data: Uint8Array): Promise<Result<Uint8Array>>;
4548
+ /**
4549
+ * Verifies a signature produced by {@link NodeCryptoProvider.sign}.
4550
+ * @param publicKey - A verify `CryptoKey` (`'ecdsa-p256'` or `'ed25519'`).
4551
+ * @param signature - The raw signature bytes.
4552
+ * @param data - The original data that was signed.
4553
+ * @returns `Success` with `true` if valid, `false` if not, or `Failure` with error context.
4554
+ */
4555
+ verify(publicKey: CryptoKey, signature: Uint8Array, data: Uint8Array): Promise<Result<boolean>>;
4556
+ /**
4557
+ * Compares two byte arrays in constant time using Node's native
4558
+ * `crypto.timingSafeEqual`. Returns `false` for mismatched lengths
4559
+ * rather than throwing (Node's native throws on length mismatch).
4560
+ * @param a - First byte array.
4561
+ * @param b - Second byte array.
4562
+ * @returns `true` if lengths match and all bytes are equal, `false` otherwise.
4563
+ */
4564
+ timingSafeEqual(a: Uint8Array, b: Uint8Array): boolean;
4565
+ /**
4566
+ * Computes an HMAC-SHA256 MAC for `data` using `key`.
4567
+ * @param key - An HMAC `CryptoKey` with `'sign'` usage.
4568
+ * @param data - The bytes to authenticate.
4569
+ * @returns `Success` with the 32-byte MAC, or `Failure` with error context.
4570
+ */
4571
+ hmacSha256(key: CryptoKey, data: Uint8Array): Promise<Result<Uint8Array>>;
4572
+ /**
4573
+ * Verifies an HMAC-SHA256 MAC in constant time.
4574
+ * @param key - An HMAC `CryptoKey` with `'sign'` usage.
4575
+ * @param signature - The MAC bytes to verify.
4576
+ * @param data - The original data that was authenticated.
4577
+ * @returns `Success` with `true` if valid, `false` if not, or `Failure` with error context.
4578
+ */
4579
+ verifyHmacSha256(key: CryptoKey, signature: Uint8Array, data: Uint8Array): Promise<Result<boolean>>;
4580
+ /**
4581
+ * Wraps `plaintext` for the holder of `recipientPublicKey` using
4582
+ * ECIES (ECDH P-256 + HKDF-SHA256 + AES-GCM-256). See
4583
+ * {@link CryptoUtils.ICryptoProvider.wrapBytes | ICryptoProvider.wrapBytes}.
4584
+ * @param plaintext - The bytes to wrap.
4585
+ * @param recipientPublicKey - The recipient's ECDH P-256 public `CryptoKey`.
4586
+ * @param options - HKDF salt and info; see {@link CryptoUtils.IWrapBytesOptions | IWrapBytesOptions}.
4587
+ * @returns `Success` with the wrapped payload, or `Failure` with an error.
4588
+ */
4589
+ wrapBytes(plaintext: Uint8Array, recipientPublicKey: CryptoKey, options: IWrapBytesOptions): Promise<Result<IWrappedBytes>>;
4590
+ /**
4591
+ * Unwraps a payload produced by `wrapBytes` using the recipient's private
4592
+ * key. See {@link CryptoUtils.ICryptoProvider.unwrapBytes | ICryptoProvider.unwrapBytes}.
4593
+ * @param wrapped - The wrapped payload.
4594
+ * @param recipientPrivateKey - The recipient's ECDH P-256 private `CryptoKey`.
4595
+ * @param options - HKDF salt and info matching the wrap call.
4596
+ * @returns `Success` with the original `plaintext`, or `Failure` with an error.
4597
+ */
4598
+ unwrapBytes(wrapped: IWrappedBytes, recipientPrivateKey: CryptoKey, options: IWrapBytesOptions): Promise<Result<Uint8Array>>;
1992
4599
  }
1993
4600
 
1994
4601
  /**
@@ -1997,6 +4604,12 @@ declare class NodeCryptoProvider implements ICryptoProvider {
1997
4604
  */
1998
4605
  declare const nodeCryptoProvider: NodeCryptoProvider;
1999
4606
 
4607
+ /**
4608
+ * Model IDs for OpenAI thinking-capable models.
4609
+ * @public
4610
+ */
4611
+ declare type OpenAiThinkingModelNames = 'o3' | 'o4-mini' | 'o3-deep-research' | 'o4-mini-deep-research' | 'gpt-5' | 'gpt-5.1' | 'gpt-5.2' | 'gpt-5.5' | 'gpt-5-pro';
4612
+
2000
4613
  /**
2001
4614
  * Parses CSV data from a string.
2002
4615
  * @param body - The CSV string to parse.
@@ -2016,6 +4629,12 @@ declare function parseCsvString(body: string, options?: CsvOptions): Result<unkn
2016
4629
  */
2017
4630
  declare function parseRecordJarLines(lines: string[], options?: JarRecordParserOptions): Result<JarRecord[]>;
2018
4631
 
4632
+ /**
4633
+ * Converter for {@link CryptoUtils.IPbkdf2KeyDerivationParams | PBKDF2 key derivation parameters}.
4634
+ * @public
4635
+ */
4636
+ declare const pbkdf2KeyDerivationParams: Converter<IPbkdf2KeyDerivationParams>;
4637
+
2019
4638
  /**
2020
4639
  * Simple implementation of a possibly open-ended range of some comparable
2021
4640
  * type `<T>` with test and formatting.
@@ -2193,11 +4812,11 @@ declare function readRecordJarFromTree(fileTree: FileTree.FileTree, filePath: st
2193
4812
  declare namespace RecordJar {
2194
4813
  export {
2195
4814
  parseRecordJarLines,
4815
+ readRecordJarFromTree,
2196
4816
  JarRecord,
2197
4817
  JarFieldPicker,
2198
4818
  JarRecordParserOptions,
2199
- readRecordJarFileSync,
2200
- readRecordJarFromTree
4819
+ readRecordJarFileSync
2201
4820
  }
2202
4821
  }
2203
4822
  export { RecordJar }
@@ -2218,6 +4837,44 @@ export { RecordJar }
2218
4837
  */
2219
4838
  declare function resolveEffectiveTools(descriptor: IAiProviderDescriptor, settingsTools?: ReadonlyArray<IAiToolEnablement>, perCallTools?: ReadonlyArray<AiServerToolConfig>): ReadonlyArray<AiServerToolConfig>;
2220
4839
 
4840
+ /**
4841
+ * Resolve the image-generation capability that applies to a given model id
4842
+ * for a provider. Returns the entry from
4843
+ * {@link IAiProviderDescriptor.imageGeneration} whose `modelPrefix` is the
4844
+ * longest prefix of `modelId`. Ties are broken by first-encountered, so rule
4845
+ * order does not matter for correctness — only for tie-breaking among rules
4846
+ * with identical-length prefixes (an unusual case).
4847
+ *
4848
+ * @param descriptor - The provider descriptor
4849
+ * @param modelId - The resolved image model id
4850
+ * @returns The matching capability, or `undefined` when no rule matches or
4851
+ * the provider declares no image-generation capabilities.
4852
+ * @public
4853
+ */
4854
+ declare function resolveImageCapability(descriptor: IAiProviderDescriptor, modelId: string): IAiImageModelCapability | undefined;
4855
+
4856
+ /**
4857
+ * Resolves the merged image options for a given model and capability.
4858
+ *
4859
+ * @remarks
4860
+ * **Merge precedence (later wins):**
4861
+ * 1. Generic top-level options (size, count, quality, seed)
4862
+ * 2. Family-generic blocks (models field omitted, provider matches)
4863
+ * 3. Model-specific blocks (models array includes the resolved model name)
4864
+ * 4. Other blocks (provider: 'other', models array includes model name)
4865
+ *
4866
+ * Provider-mismatch blocks are silently skipped.
4867
+ *
4868
+ * Within each tier, declaration order — later declaration wins.
4869
+ *
4870
+ * @param modelId - The resolved model string
4871
+ * @param capability - The resolved IAiImageModelCapability for this model
4872
+ * @param options - Caller-supplied options
4873
+ * @returns The merged wire parameters
4874
+ * @public
4875
+ */
4876
+ declare function resolveImageOptions(modelId: string, capability: IAiImageModelCapability, options: IAiImageGenerationOptions | undefined): IResolvedImageOptions;
4877
+
2221
4878
  /**
2222
4879
  * Resolves a {@link ModelSpec} to a concrete model string given an optional context key.
2223
4880
  *
@@ -2241,6 +4898,24 @@ declare function resolveModel(spec: ModelSpec, context?: string): string;
2241
4898
  */
2242
4899
  declare type SecretProvider = (secretName: string) => Promise<Result<Uint8Array>>;
2243
4900
 
4901
+ /**
4902
+ * Default system-prompt suffix appended when {@link AiAssist.IGenerateJsonCompletionParams.promptHint}
4903
+ * is `'smart'` (the default). Designed to discourage code fences and prose in
4904
+ * the model's response while still tolerating them via the read-side extractor.
4905
+ * @public
4906
+ */
4907
+ declare const SMART_JSON_PROMPT_HINT: string;
4908
+
4909
+ /**
4910
+ * Whether a provider declares any image-generation capability at all.
4911
+ *
4912
+ * @param descriptor - The provider descriptor
4913
+ * @returns `true` when {@link IAiProviderDescriptor.imageGeneration} has at
4914
+ * least one entry; `false` otherwise.
4915
+ * @public
4916
+ */
4917
+ declare function supportsImageGeneration(descriptor: IAiProviderDescriptor): boolean;
4918
+
2244
4919
  /**
2245
4920
  * Helper function to create a `StringConverter` which converts
2246
4921
  * `unknown` to `string`, applying template conversions supplied at construction time or at
@@ -2261,6 +4936,14 @@ declare function templateString(defaultContext?: unknown): Conversion.StringConv
2261
4936
  */
2262
4937
  declare function toBase64(bytes: Uint8Array): string;
2263
4938
 
4939
+ /**
4940
+ * Formats an {@link IAiImageData} as a `data:` URL suitable for browser display.
4941
+ * @param image - The image to format
4942
+ * @returns A `data:<mime>;base64,<data>` URL string
4943
+ * @public
4944
+ */
4945
+ declare function toDataUrl(image: IAiImageData): string;
4946
+
2264
4947
  /**
2265
4948
  * Attempts to parse and decrypt a JSON object as an {@link CryptoUtils.IEncryptedFile | encrypted file}.
2266
4949
  * @typeParam TPayload - Expected type of decrypted content
@@ -2281,9 +4964,32 @@ declare function tryDecryptFile<TPayload extends JsonValue = JsonValue, TMetadat
2281
4964
  */
2282
4965
  declare const uint8ArrayFromBase64: Converter<Uint8Array>;
2283
4966
 
4967
+ /**
4968
+ * Validates the resolved options against per-model registry constraints.
4969
+ *
4970
+ * @remarks
4971
+ * Fails fast on the first violation. Error format:
4972
+ * `model "${model}": ${field} "${value}" is not accepted; accepted values: ${JSON.stringify(accepted)}`
4973
+ *
4974
+ * @param modelId - The resolved model string
4975
+ * @param capability - The resolved capability entry from the registry
4976
+ * @param resolved - The merged options from resolveImageOptions
4977
+ * @returns The same resolved options on success, or a failure with a contextual message
4978
+ * @public
4979
+ */
4980
+ declare function validateResolvedOptions(modelId: string, capability: IAiImageModelCapability, resolved: IResolvedImageOptions): Result<IResolvedImageOptions>;
4981
+
4982
+ /**
4983
+ * Model IDs for xAI thinking-capable models.
4984
+ * @public
4985
+ */
4986
+ declare type XAiThinkingModelNames = 'grok-3-mini' | 'grok-4.3' | 'grok-4';
4987
+
2284
4988
  declare namespace Yaml {
2285
4989
  export {
2286
- yamlConverter
4990
+ yamlConverter,
4991
+ yamlStringify,
4992
+ IYamlSerializeOptions
2287
4993
  }
2288
4994
  }
2289
4995
  export { Yaml }
@@ -2296,6 +5002,15 @@ export { Yaml }
2296
5002
  */
2297
5003
  declare function yamlConverter<T>(converter: Converter<T>): Converter<T>;
2298
5004
 
5005
+ /**
5006
+ * Serializes a value to a YAML string.
5007
+ * @param value - The value to serialize (must be an object or array)
5008
+ * @param options - Optional serialization options
5009
+ * @returns `Success` with YAML string, or `Failure` with error
5010
+ * @public
5011
+ */
5012
+ declare function yamlStringify(value: unknown, options?: IYamlSerializeOptions): Result<string>;
5013
+
2299
5014
  /**
2300
5015
  * Supported compression levels for zip files.
2301
5016
  * @public
@@ -2449,8 +5164,8 @@ declare class ZipFileTreeAccessors<TCT extends string = string> implements FileT
2449
5164
  private constructor();
2450
5165
  /**
2451
5166
  * Default function to infer the content type of a file.
2452
- * @param filePath - The path of the file.
2453
- * @param provided - Optional supplied content type.
5167
+ * @param __filePath - The path of the file.
5168
+ * @param __provided - Optional supplied content type.
2454
5169
  * @returns `Success` with the content type of the file if successful, or
2455
5170
  * `Failure` with an error message otherwise.
2456
5171
  * @remarks This default implementation always returns `Success` with `undefined`.