@fgv/ts-extras 5.1.0-2 → 5.1.0-20

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 (264) hide show
  1. package/dist/index.browser.js +2 -1
  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 +792 -57
  5. package/dist/packlets/ai-assist/apiClient.js.map +1 -0
  6. package/dist/packlets/ai-assist/chatRequestBuilders.js +180 -0
  7. package/dist/packlets/ai-assist/chatRequestBuilders.js.map +1 -0
  8. package/dist/packlets/ai-assist/converters.js.map +1 -0
  9. package/dist/packlets/ai-assist/index.js +4 -3
  10. package/dist/packlets/ai-assist/index.js.map +1 -0
  11. package/dist/packlets/ai-assist/model.js +20 -3
  12. package/dist/packlets/ai-assist/model.js.map +1 -0
  13. package/dist/packlets/ai-assist/registry.js +111 -10
  14. package/dist/packlets/ai-assist/registry.js.map +1 -0
  15. package/dist/packlets/ai-assist/sseParser.js +122 -0
  16. package/dist/packlets/ai-assist/sseParser.js.map +1 -0
  17. package/dist/packlets/ai-assist/streamingAdapters/anthropic.js +192 -0
  18. package/dist/packlets/ai-assist/streamingAdapters/anthropic.js.map +1 -0
  19. package/dist/packlets/ai-assist/streamingAdapters/common.js +77 -0
  20. package/dist/packlets/ai-assist/streamingAdapters/common.js.map +1 -0
  21. package/dist/packlets/ai-assist/streamingAdapters/gemini.js +160 -0
  22. package/dist/packlets/ai-assist/streamingAdapters/gemini.js.map +1 -0
  23. package/dist/packlets/ai-assist/streamingAdapters/openaiChat.js +149 -0
  24. package/dist/packlets/ai-assist/streamingAdapters/openaiChat.js.map +1 -0
  25. package/dist/packlets/ai-assist/streamingAdapters/openaiResponses.js +163 -0
  26. package/dist/packlets/ai-assist/streamingAdapters/openaiResponses.js.map +1 -0
  27. package/dist/packlets/ai-assist/streamingAdapters/proxy.js +157 -0
  28. package/dist/packlets/ai-assist/streamingAdapters/proxy.js.map +1 -0
  29. package/dist/packlets/ai-assist/streamingClient.js +88 -0
  30. package/dist/packlets/ai-assist/streamingClient.js.map +1 -0
  31. package/dist/packlets/ai-assist/toolFormats.js.map +1 -0
  32. package/dist/packlets/conversion/converters.js +34 -1
  33. package/dist/packlets/conversion/converters.js.map +1 -0
  34. package/dist/packlets/conversion/index.js.map +1 -0
  35. package/dist/packlets/crypto-utils/constants.js.map +1 -0
  36. package/dist/packlets/crypto-utils/converters.js.map +1 -0
  37. package/dist/packlets/crypto-utils/directEncryptionProvider.js.map +1 -0
  38. package/dist/packlets/crypto-utils/encryptedFile.js.map +1 -0
  39. package/dist/packlets/crypto-utils/index.browser.js +2 -0
  40. package/dist/packlets/crypto-utils/index.browser.js.map +1 -0
  41. package/dist/packlets/crypto-utils/index.js +2 -0
  42. package/dist/packlets/crypto-utils/index.js.map +1 -0
  43. package/dist/packlets/crypto-utils/keyPairAlgorithmParams.js +57 -0
  44. package/dist/packlets/crypto-utils/keyPairAlgorithmParams.js.map +1 -0
  45. package/dist/packlets/crypto-utils/keystore/converters.js +101 -9
  46. package/dist/packlets/crypto-utils/keystore/converters.js.map +1 -0
  47. package/dist/packlets/crypto-utils/keystore/index.js +1 -0
  48. package/dist/packlets/crypto-utils/keystore/index.js.map +1 -0
  49. package/dist/packlets/crypto-utils/keystore/keyStore.js +431 -118
  50. package/dist/packlets/crypto-utils/keystore/keyStore.js.map +1 -0
  51. package/dist/packlets/crypto-utils/keystore/model.js +22 -1
  52. package/dist/packlets/crypto-utils/keystore/model.js.map +1 -0
  53. package/dist/packlets/crypto-utils/keystore/privateKeyStorage.js +21 -0
  54. package/dist/packlets/crypto-utils/keystore/privateKeyStorage.js.map +1 -0
  55. package/dist/packlets/crypto-utils/model.js +9 -0
  56. package/dist/packlets/crypto-utils/model.js.map +1 -0
  57. package/dist/packlets/crypto-utils/nodeCryptoProvider.js +152 -1
  58. package/dist/packlets/crypto-utils/nodeCryptoProvider.js.map +1 -0
  59. package/dist/packlets/csv/csvFileHelpers.js.map +1 -0
  60. package/dist/packlets/csv/csvHelpers.js.map +1 -0
  61. package/dist/packlets/csv/index.browser.js.map +1 -0
  62. package/dist/packlets/csv/index.js.map +1 -0
  63. package/dist/packlets/experimental/extendedArray.js.map +1 -0
  64. package/dist/packlets/experimental/formatter.js.map +1 -0
  65. package/dist/packlets/experimental/index.js.map +1 -0
  66. package/dist/packlets/experimental/rangeOf.js.map +1 -0
  67. package/dist/packlets/hash/index.browser.js.map +1 -0
  68. package/dist/packlets/hash/index.js.map +1 -0
  69. package/dist/packlets/hash/index.node.js.map +1 -0
  70. package/dist/packlets/hash/md5Normalizer.browser.js.map +1 -0
  71. package/dist/packlets/hash/md5Normalizer.js.map +1 -0
  72. package/dist/packlets/mustache/index.js.map +1 -0
  73. package/dist/packlets/mustache/interfaces.js.map +1 -0
  74. package/dist/packlets/mustache/mustacheTemplate.js.map +1 -0
  75. package/dist/packlets/record-jar/index.browser.js.map +1 -0
  76. package/dist/packlets/record-jar/index.js.map +1 -0
  77. package/dist/packlets/record-jar/recordJarFileHelpers.js.map +1 -0
  78. package/dist/packlets/record-jar/recordJarHelpers.js.map +1 -0
  79. package/dist/packlets/yaml/converters.js.map +1 -0
  80. package/dist/packlets/yaml/index.js +1 -0
  81. package/dist/packlets/yaml/index.js.map +1 -0
  82. package/dist/packlets/yaml/serializers.js +48 -0
  83. package/dist/packlets/yaml/serializers.js.map +1 -0
  84. package/dist/packlets/zip-file-tree/index.js.map +1 -0
  85. package/dist/packlets/zip-file-tree/zipFileTreeAccessors.js +2 -2
  86. package/dist/packlets/zip-file-tree/zipFileTreeAccessors.js.map +1 -0
  87. package/dist/packlets/zip-file-tree/zipFileTreeWriter.js.map +1 -0
  88. package/dist/ts-extras.d.ts +1442 -45
  89. package/dist/tsdoc-metadata.json +1 -1
  90. package/lib/index.browser.d.ts +2 -1
  91. package/lib/index.browser.d.ts.map +1 -0
  92. package/lib/index.browser.js +3 -1
  93. package/lib/index.browser.js.map +1 -0
  94. package/lib/index.d.ts.map +1 -0
  95. package/lib/index.js.map +1 -0
  96. package/lib/packlets/ai-assist/apiClient.d.ts +111 -1
  97. package/lib/packlets/ai-assist/apiClient.d.ts.map +1 -0
  98. package/lib/packlets/ai-assist/apiClient.js +795 -56
  99. package/lib/packlets/ai-assist/apiClient.js.map +1 -0
  100. package/lib/packlets/ai-assist/chatRequestBuilders.d.ts +89 -0
  101. package/lib/packlets/ai-assist/chatRequestBuilders.d.ts.map +1 -0
  102. package/lib/packlets/ai-assist/chatRequestBuilders.js +189 -0
  103. package/lib/packlets/ai-assist/chatRequestBuilders.js.map +1 -0
  104. package/lib/packlets/ai-assist/converters.d.ts.map +1 -0
  105. package/lib/packlets/ai-assist/converters.js.map +1 -0
  106. package/lib/packlets/ai-assist/index.d.ts +4 -3
  107. package/lib/packlets/ai-assist/index.d.ts.map +1 -0
  108. package/lib/packlets/ai-assist/index.js +12 -1
  109. package/lib/packlets/ai-assist/index.js.map +1 -0
  110. package/lib/packlets/ai-assist/model.d.ts +332 -2
  111. package/lib/packlets/ai-assist/model.d.ts.map +1 -0
  112. package/lib/packlets/ai-assist/model.js +21 -3
  113. package/lib/packlets/ai-assist/model.js.map +1 -0
  114. package/lib/packlets/ai-assist/registry.d.ts +34 -1
  115. package/lib/packlets/ai-assist/registry.d.ts.map +1 -0
  116. package/lib/packlets/ai-assist/registry.js +114 -11
  117. package/lib/packlets/ai-assist/registry.js.map +1 -0
  118. package/lib/packlets/ai-assist/sseParser.d.ts +45 -0
  119. package/lib/packlets/ai-assist/sseParser.d.ts.map +1 -0
  120. package/lib/packlets/ai-assist/sseParser.js +127 -0
  121. package/lib/packlets/ai-assist/sseParser.js.map +1 -0
  122. package/lib/packlets/ai-assist/streamingAdapters/anthropic.d.ts +18 -0
  123. package/lib/packlets/ai-assist/streamingAdapters/anthropic.d.ts.map +1 -0
  124. package/lib/packlets/ai-assist/streamingAdapters/anthropic.js +195 -0
  125. package/lib/packlets/ai-assist/streamingAdapters/anthropic.js.map +1 -0
  126. package/lib/packlets/ai-assist/streamingAdapters/common.d.ts +71 -0
  127. package/lib/packlets/ai-assist/streamingAdapters/common.d.ts.map +1 -0
  128. package/lib/packlets/ai-assist/streamingAdapters/common.js +81 -0
  129. package/lib/packlets/ai-assist/streamingAdapters/common.js.map +1 -0
  130. package/lib/packlets/ai-assist/streamingAdapters/gemini.d.ts +19 -0
  131. package/lib/packlets/ai-assist/streamingAdapters/gemini.d.ts.map +1 -0
  132. package/lib/packlets/ai-assist/streamingAdapters/gemini.js +163 -0
  133. package/lib/packlets/ai-assist/streamingAdapters/gemini.js.map +1 -0
  134. package/lib/packlets/ai-assist/streamingAdapters/openaiChat.d.ts +18 -0
  135. package/lib/packlets/ai-assist/streamingAdapters/openaiChat.d.ts.map +1 -0
  136. package/lib/packlets/ai-assist/streamingAdapters/openaiChat.js +152 -0
  137. package/lib/packlets/ai-assist/streamingAdapters/openaiChat.js.map +1 -0
  138. package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.d.ts +19 -0
  139. package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.d.ts.map +1 -0
  140. package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.js +166 -0
  141. package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.js.map +1 -0
  142. package/lib/packlets/ai-assist/streamingAdapters/proxy.d.ts +34 -0
  143. package/lib/packlets/ai-assist/streamingAdapters/proxy.d.ts.map +1 -0
  144. package/lib/packlets/ai-assist/streamingAdapters/proxy.js +160 -0
  145. package/lib/packlets/ai-assist/streamingAdapters/proxy.js.map +1 -0
  146. package/lib/packlets/ai-assist/streamingClient.d.ts +33 -0
  147. package/lib/packlets/ai-assist/streamingClient.d.ts.map +1 -0
  148. package/lib/packlets/ai-assist/streamingClient.js +93 -0
  149. package/lib/packlets/ai-assist/streamingClient.js.map +1 -0
  150. package/lib/packlets/ai-assist/toolFormats.d.ts.map +1 -0
  151. package/lib/packlets/ai-assist/toolFormats.js.map +1 -0
  152. package/lib/packlets/conversion/converters.d.ts +8 -1
  153. package/lib/packlets/conversion/converters.d.ts.map +1 -0
  154. package/lib/packlets/conversion/converters.js +35 -2
  155. package/lib/packlets/conversion/converters.js.map +1 -0
  156. package/lib/packlets/conversion/index.d.ts.map +1 -0
  157. package/lib/packlets/conversion/index.js.map +1 -0
  158. package/lib/packlets/crypto-utils/constants.d.ts.map +1 -0
  159. package/lib/packlets/crypto-utils/constants.js.map +1 -0
  160. package/lib/packlets/crypto-utils/converters.d.ts.map +1 -0
  161. package/lib/packlets/crypto-utils/converters.js.map +1 -0
  162. package/lib/packlets/crypto-utils/directEncryptionProvider.d.ts.map +1 -0
  163. package/lib/packlets/crypto-utils/directEncryptionProvider.js.map +1 -0
  164. package/lib/packlets/crypto-utils/encryptedFile.d.ts.map +1 -0
  165. package/lib/packlets/crypto-utils/encryptedFile.js.map +1 -0
  166. package/lib/packlets/crypto-utils/index.browser.d.ts +1 -0
  167. package/lib/packlets/crypto-utils/index.browser.d.ts.map +1 -0
  168. package/lib/packlets/crypto-utils/index.browser.js +4 -1
  169. package/lib/packlets/crypto-utils/index.browser.js.map +1 -0
  170. package/lib/packlets/crypto-utils/index.d.ts +1 -0
  171. package/lib/packlets/crypto-utils/index.d.ts.map +1 -0
  172. package/lib/packlets/crypto-utils/index.js +4 -1
  173. package/lib/packlets/crypto-utils/index.js.map +1 -0
  174. package/lib/packlets/crypto-utils/keyPairAlgorithmParams.d.ts +39 -0
  175. package/lib/packlets/crypto-utils/keyPairAlgorithmParams.d.ts.map +1 -0
  176. package/lib/packlets/crypto-utils/keyPairAlgorithmParams.js +60 -0
  177. package/lib/packlets/crypto-utils/keyPairAlgorithmParams.js.map +1 -0
  178. package/lib/packlets/crypto-utils/keystore/converters.d.ts +68 -6
  179. package/lib/packlets/crypto-utils/keystore/converters.d.ts.map +1 -0
  180. package/lib/packlets/crypto-utils/keystore/converters.js +100 -8
  181. package/lib/packlets/crypto-utils/keystore/converters.js.map +1 -0
  182. package/lib/packlets/crypto-utils/keystore/index.d.ts +1 -0
  183. package/lib/packlets/crypto-utils/keystore/index.d.ts.map +1 -0
  184. package/lib/packlets/crypto-utils/keystore/index.js +1 -0
  185. package/lib/packlets/crypto-utils/keystore/index.js.map +1 -0
  186. package/lib/packlets/crypto-utils/keystore/keyStore.d.ts +125 -12
  187. package/lib/packlets/crypto-utils/keystore/keyStore.d.ts.map +1 -0
  188. package/lib/packlets/crypto-utils/keystore/keyStore.js +431 -118
  189. package/lib/packlets/crypto-utils/keystore/keyStore.js.map +1 -0
  190. package/lib/packlets/crypto-utils/keystore/model.d.ts +248 -17
  191. package/lib/packlets/crypto-utils/keystore/model.d.ts.map +1 -0
  192. package/lib/packlets/crypto-utils/keystore/model.js +24 -2
  193. package/lib/packlets/crypto-utils/keystore/model.js.map +1 -0
  194. package/lib/packlets/crypto-utils/keystore/privateKeyStorage.d.ts +50 -0
  195. package/lib/packlets/crypto-utils/keystore/privateKeyStorage.d.ts.map +1 -0
  196. package/lib/packlets/crypto-utils/keystore/privateKeyStorage.js +22 -0
  197. package/lib/packlets/crypto-utils/keystore/privateKeyStorage.js.map +1 -0
  198. package/lib/packlets/crypto-utils/model.d.ts +140 -0
  199. package/lib/packlets/crypto-utils/model.d.ts.map +1 -0
  200. package/lib/packlets/crypto-utils/model.js +10 -1
  201. package/lib/packlets/crypto-utils/model.js.map +1 -0
  202. package/lib/packlets/crypto-utils/nodeCryptoProvider.d.ts +51 -1
  203. package/lib/packlets/crypto-utils/nodeCryptoProvider.d.ts.map +1 -0
  204. package/lib/packlets/crypto-utils/nodeCryptoProvider.js +151 -0
  205. package/lib/packlets/crypto-utils/nodeCryptoProvider.js.map +1 -0
  206. package/lib/packlets/csv/csvFileHelpers.d.ts.map +1 -0
  207. package/lib/packlets/csv/csvFileHelpers.js.map +1 -0
  208. package/lib/packlets/csv/csvHelpers.d.ts.map +1 -0
  209. package/lib/packlets/csv/csvHelpers.js.map +1 -0
  210. package/lib/packlets/csv/index.browser.d.ts.map +1 -0
  211. package/lib/packlets/csv/index.browser.js.map +1 -0
  212. package/lib/packlets/csv/index.d.ts.map +1 -0
  213. package/lib/packlets/csv/index.js.map +1 -0
  214. package/lib/packlets/experimental/extendedArray.d.ts.map +1 -0
  215. package/lib/packlets/experimental/extendedArray.js.map +1 -0
  216. package/lib/packlets/experimental/formatter.d.ts.map +1 -0
  217. package/lib/packlets/experimental/formatter.js.map +1 -0
  218. package/lib/packlets/experimental/index.d.ts.map +1 -0
  219. package/lib/packlets/experimental/index.js.map +1 -0
  220. package/lib/packlets/experimental/rangeOf.d.ts.map +1 -0
  221. package/lib/packlets/experimental/rangeOf.js.map +1 -0
  222. package/lib/packlets/hash/index.browser.d.ts.map +1 -0
  223. package/lib/packlets/hash/index.browser.js.map +1 -0
  224. package/lib/packlets/hash/index.d.ts.map +1 -0
  225. package/lib/packlets/hash/index.js.map +1 -0
  226. package/lib/packlets/hash/index.node.d.ts.map +1 -0
  227. package/lib/packlets/hash/index.node.js.map +1 -0
  228. package/lib/packlets/hash/md5Normalizer.browser.d.ts.map +1 -0
  229. package/lib/packlets/hash/md5Normalizer.browser.js.map +1 -0
  230. package/lib/packlets/hash/md5Normalizer.d.ts.map +1 -0
  231. package/lib/packlets/hash/md5Normalizer.js.map +1 -0
  232. package/lib/packlets/mustache/index.d.ts.map +1 -0
  233. package/lib/packlets/mustache/index.js.map +1 -0
  234. package/lib/packlets/mustache/interfaces.d.ts.map +1 -0
  235. package/lib/packlets/mustache/interfaces.js.map +1 -0
  236. package/lib/packlets/mustache/mustacheTemplate.d.ts.map +1 -0
  237. package/lib/packlets/mustache/mustacheTemplate.js.map +1 -0
  238. package/lib/packlets/record-jar/index.browser.d.ts.map +1 -0
  239. package/lib/packlets/record-jar/index.browser.js.map +1 -0
  240. package/lib/packlets/record-jar/index.d.ts.map +1 -0
  241. package/lib/packlets/record-jar/index.js.map +1 -0
  242. package/lib/packlets/record-jar/recordJarFileHelpers.d.ts.map +1 -0
  243. package/lib/packlets/record-jar/recordJarFileHelpers.js.map +1 -0
  244. package/lib/packlets/record-jar/recordJarHelpers.d.ts.map +1 -0
  245. package/lib/packlets/record-jar/recordJarHelpers.js.map +1 -0
  246. package/lib/packlets/yaml/converters.d.ts.map +1 -0
  247. package/lib/packlets/yaml/converters.js.map +1 -0
  248. package/lib/packlets/yaml/index.d.ts +1 -0
  249. package/lib/packlets/yaml/index.d.ts.map +1 -0
  250. package/lib/packlets/yaml/index.js +1 -0
  251. package/lib/packlets/yaml/index.js.map +1 -0
  252. package/lib/packlets/yaml/serializers.d.ts +45 -0
  253. package/lib/packlets/yaml/serializers.d.ts.map +1 -0
  254. package/lib/packlets/yaml/serializers.js +84 -0
  255. package/lib/packlets/yaml/serializers.js.map +1 -0
  256. package/lib/packlets/zip-file-tree/index.d.ts.map +1 -0
  257. package/lib/packlets/zip-file-tree/index.js.map +1 -0
  258. package/lib/packlets/zip-file-tree/zipFileTreeAccessors.d.ts +2 -2
  259. package/lib/packlets/zip-file-tree/zipFileTreeAccessors.d.ts.map +1 -0
  260. package/lib/packlets/zip-file-tree/zipFileTreeAccessors.js +2 -2
  261. package/lib/packlets/zip-file-tree/zipFileTreeAccessors.js.map +1 -0
  262. package/lib/packlets/zip-file-tree/zipFileTreeWriter.d.ts.map +1 -0
  263. package/lib/packlets/zip-file-tree/zipFileTreeWriter.js.map +1 -0
  264. package/package.json +24 -23
@@ -1,5 +1,6 @@
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';
5
6
  import { JsonValue } from '@fgv/ts-json-base';
@@ -22,6 +23,7 @@ declare type AiApiFormat = 'openai' | 'anthropic' | 'gemini';
22
23
  declare namespace AiAssist {
23
24
  export {
24
25
  AiPrompt,
26
+ AiModelCapability,
25
27
  AiProviderId,
26
28
  AiServerToolType,
27
29
  AiServerToolConfig,
@@ -30,23 +32,52 @@ declare namespace AiAssist {
30
32
  IAiCompletionResponse,
31
33
  IChatMessage,
32
34
  AiApiFormat,
35
+ AiImageApiFormat,
36
+ IAiImageModelCapability,
33
37
  IAiProviderDescriptor,
34
38
  IAiAssistProviderConfig,
35
39
  IAiAssistSettings,
36
40
  DEFAULT_AI_ASSIST,
37
41
  IAiAssistKeyStore,
42
+ IAiImageAttachment,
43
+ IAiImageData,
44
+ IAiImageGenerationOptions,
45
+ IAiImageGenerationParams,
46
+ IAiGeneratedImage,
47
+ IAiImageGenerationResponse,
48
+ IAiModelCapabilityRule,
49
+ IAiModelCapabilityConfig,
50
+ IAiModelInfo,
51
+ IAiStreamEvent,
52
+ IAiStreamTextDelta,
53
+ IAiStreamToolEvent,
54
+ IAiStreamDone,
55
+ IAiStreamError,
38
56
  ModelSpec,
39
57
  ModelSpecKey,
40
58
  IModelSpecMap,
41
59
  allModelSpecKeys,
42
60
  MODEL_SPEC_BASE_KEY,
43
61
  resolveModel,
62
+ toDataUrl,
44
63
  allProviderIds,
45
64
  getProviderDescriptors,
46
65
  getProviderDescriptor,
66
+ resolveImageCapability,
67
+ supportsImageGeneration,
68
+ DEFAULT_MODEL_CAPABILITY_CONFIG,
47
69
  callProviderCompletion,
48
70
  callProxiedCompletion,
71
+ callProviderImageGeneration,
72
+ callProxiedImageGeneration,
73
+ callProviderListModels,
74
+ callProxiedListModels,
49
75
  IProviderCompletionParams,
76
+ IProviderImageGenerationParams,
77
+ IProviderListModelsParams,
78
+ callProviderCompletionStream,
79
+ callProxiedCompletionStream,
80
+ IProviderCompletionStreamParams,
50
81
  aiProviderId,
51
82
  aiServerToolType,
52
83
  aiWebSearchToolConfig,
@@ -73,6 +104,36 @@ declare const aiAssistProviderConfig: Converter<IAiAssistProviderConfig>;
73
104
  */
74
105
  declare const aiAssistSettings: Converter<IAiAssistSettings>;
75
106
 
107
+ /**
108
+ * API format categories for image-generation provider routing.
109
+ *
110
+ * @remarks
111
+ * - `'openai-images'` — OpenAI Images API. Routes to `/images/generations`
112
+ * (text-only) or `/images/edits` (when reference images are present).
113
+ * - `'xai-images'` — xAI Images API. Same wire shape as OpenAI but text-only;
114
+ * no reference-image support on grok-2-image.
115
+ * - `'gemini-imagen'` — Google Imagen `:predict` endpoint. Text-only.
116
+ * - `'gemini-image-out'` — Google Gemini chat-style `:generateContent`
117
+ * endpoint that returns image parts (Gemini 2.5 Flash Image / "Nano
118
+ * Banana"). Accepts reference images.
119
+ *
120
+ * @public
121
+ */
122
+ declare type AiImageApiFormat = 'openai-images' | 'gemini-imagen' | 'xai-images' | 'gemini-image-out';
123
+
124
+ /**
125
+ * Capability vocabulary used to describe what a model can do. Used as both
126
+ * a filter and as a tag in {@link AiAssist.IAiModelInfo.capabilities}.
127
+ *
128
+ * @remarks
129
+ * Adding a new capability is cheap; adding the *first* one after consumers
130
+ * already exist forces churn. The initial vocabulary is intentionally broad
131
+ * even though only `image-generation` is fully exercised today.
132
+ *
133
+ * @public
134
+ */
135
+ declare type AiModelCapability = 'chat' | 'tools' | 'vision' | 'image-generation';
136
+
76
137
  /**
77
138
  * A structured AI prompt with system/user split for direct API calls,
78
139
  * and a lazily-constructed combined version for copy/paste workflows.
@@ -83,8 +144,18 @@ declare class AiPrompt {
83
144
  readonly system: string;
84
145
  /** User request: the specific entity generation request. */
85
146
  readonly user: string;
86
- constructor(user: string, system: string);
87
- /** Combined single-string version (user + system joined) for copy/paste. */
147
+ /**
148
+ * Optional image attachments. When present, vision-capable providers will
149
+ * include them in the user message; non-vision providers will reject the
150
+ * call up front (see {@link AiAssist.IAiProviderDescriptor.acceptsImageInput}).
151
+ */
152
+ readonly attachments: ReadonlyArray<IAiImageAttachment>;
153
+ constructor(user: string, system: string, attachments?: ReadonlyArray<IAiImageAttachment>);
154
+ /**
155
+ * Combined single-string version (user + system joined) for copy/paste.
156
+ * When attachments are present, includes a sentinel noting they aren't
157
+ * part of the copied text.
158
+ */
88
159
  get combined(): string;
89
160
  }
90
161
 
@@ -136,12 +207,30 @@ declare const aiToolEnablement: Converter<IAiToolEnablement>;
136
207
  */
137
208
  declare const aiWebSearchToolConfig: Converter<IAiWebSearchToolConfig>;
138
209
 
210
+ /**
211
+ * All valid key pair algorithms.
212
+ * @public
213
+ */
214
+ declare const allKeyPairAlgorithms: ReadonlyArray<KeyPairAlgorithm>;
215
+
216
+ /**
217
+ * All valid asymmetric secret types.
218
+ * @public
219
+ */
220
+ declare const allKeyStoreAsymmetricSecretTypes: ReadonlyArray<KeyStoreAsymmetricSecretType>;
221
+
139
222
  /**
140
223
  * All valid key store secret types.
141
224
  * @public
142
225
  */
143
226
  declare const allKeyStoreSecretTypes: ReadonlyArray<KeyStoreSecretType>;
144
227
 
228
+ /**
229
+ * All valid symmetric secret types.
230
+ * @public
231
+ */
232
+ declare const allKeyStoreSymmetricSecretTypes: ReadonlyArray<KeyStoreSymmetricSecretType>;
233
+
145
234
  /**
146
235
  * All valid {@link ModelSpecKey} values.
147
236
  * @public
@@ -179,6 +268,60 @@ declare const base64String: Converter<string>;
179
268
  */
180
269
  declare function callProviderCompletion(params: IProviderCompletionParams): Promise<Result<IAiCompletionResponse>>;
181
270
 
271
+ /**
272
+ * Calls the appropriate streaming chat completion API for a given provider.
273
+ *
274
+ * @remarks
275
+ * Pre-flight rejection: when `descriptor.streamingCorsRestricted === true`
276
+ * and the call isn't being routed through a proxy, this returns
277
+ * `Result.fail` before fetch is invoked. Callers should route through
278
+ * {@link AiAssist.callProxiedCompletionStream} or surface the failure to the user.
279
+ *
280
+ * Connection-time failures (auth, network, non-2xx) surface as the outer
281
+ * `Result.fail`. Once iteration begins, errors mid-stream surface as a
282
+ * terminal error event ({@link AiAssist.IAiStreamError}) followed by the iterable
283
+ * ending. The final successful event is {@link AiAssist.IAiStreamDone}.
284
+ *
285
+ * @param params - Request parameters including descriptor, API key, prompt, and optional tools
286
+ * @returns A streaming iterable of unified events, or a Result.fail
287
+ * @public
288
+ */
289
+ declare function callProviderCompletionStream(params: IProviderCompletionStreamParams): Promise<Result<AsyncIterable<IAiStreamEvent>>>;
290
+
291
+ /**
292
+ * Calls the appropriate image-generation API for a given provider.
293
+ *
294
+ * Resolves a {@link IAiImageModelCapability} from
295
+ * {@link IAiProviderDescriptor.imageGeneration} for the requested model and
296
+ * routes by its `format`:
297
+ * - `'openai-images'` for OpenAI (DALL-E, gpt-image-1)
298
+ * - `'xai-images'` for xAI Grok image models
299
+ * - `'gemini-imagen'` for Google Imagen `:predict`
300
+ * - `'gemini-image-out'` for Gemini chat-style image output (Nano Banana)
301
+ *
302
+ * Image-model selection reuses the existing `'image'` {@link ModelSpecKey}.
303
+ * When `request.referenceImages` is non-empty, the call is rejected up front
304
+ * unless the resolved capability declares `acceptsImageReferenceInput`.
305
+ *
306
+ * @param params - Request parameters including descriptor, API key, and prompt
307
+ * @returns The generated images, or a failure
308
+ * @public
309
+ */
310
+ declare function callProviderImageGeneration(params: IProviderImageGenerationParams): Promise<Result<IAiImageGenerationResponse>>;
311
+
312
+ /**
313
+ * Lists models available from a provider, with capabilities resolved from
314
+ * native provider info (where supplied) and a configurable rule set.
315
+ *
316
+ * Routes based on `descriptor.apiFormat` — listing reuses the existing
317
+ * format dispatch and does not require a separate descriptor field.
318
+ *
319
+ * @param params - Request parameters including descriptor, API key, and optional capability filter
320
+ * @returns The resolved model list, or a failure
321
+ * @public
322
+ */
323
+ declare function callProviderListModels(params: IProviderListModelsParams): Promise<Result<ReadonlyArray<IAiModelInfo>>>;
324
+
182
325
  /**
183
326
  * Calls the AI completion endpoint on a proxy server instead of calling
184
327
  * the provider API directly from the browser.
@@ -194,6 +337,71 @@ declare function callProviderCompletion(params: IProviderCompletionParams): Prom
194
337
  */
195
338
  declare function callProxiedCompletion(proxyUrl: string, params: IProviderCompletionParams): Promise<Result<IAiCompletionResponse>>;
196
339
 
340
+ /**
341
+ * Calls the streaming chat endpoint on a proxy server instead of calling
342
+ * the provider directly from the browser.
343
+ *
344
+ * @remarks
345
+ * Proxy contract:
346
+ * - Endpoint: `POST ${proxyUrl}/api/ai/completion-stream`
347
+ * - Request body: same JSON as `/api/ai/completion` plus `"stream": true`
348
+ * - Response: `Content-Type: text/event-stream`; body is the unified
349
+ * {@link AiAssist.IAiStreamEvent} JSON-serialized one event per SSE `data:` line
350
+ * (no `event:` line needed since the type discriminator is in the JSON).
351
+ * - Error response (when the proxy can't even start): JSON `{error: string}`
352
+ * with a non-2xx status, surfaced as `proxy: ${error}`.
353
+ *
354
+ * The proxy server is responsible for opening the upstream SSE connection,
355
+ * translating provider-native events to the unified vocabulary, and
356
+ * forwarding events as they arrive (no buffering). The library does not
357
+ * ship a proxy implementation.
358
+ *
359
+ * @public
360
+ */
361
+ declare function callProxiedCompletionStream(proxyUrl: string, params: IProviderCompletionStreamParams): Promise<Result<AsyncIterable<IAiStreamEvent>>>;
362
+
363
+ /**
364
+ * Calls the image-generation endpoint on a proxy server instead of calling
365
+ * the provider API directly from the browser.
366
+ *
367
+ * @remarks
368
+ * The proxy contract:
369
+ * - Endpoint: `POST ${proxyUrl}/api/ai/image-generation`
370
+ * - Request body: `{providerId, apiKey, params, modelOverride?}`
371
+ * - Success response body: an {@link IAiImageGenerationResponse}
372
+ * - Error response body: `{error: string}` (surfaced as `proxy: ${error}`)
373
+ *
374
+ * The proxy server is responsible for descriptor lookup, model resolution,
375
+ * provider dispatch, and response normalization. When `params.referenceImages`
376
+ * is present, the proxy is also responsible for repackaging it into the
377
+ * upstream wire format (e.g. multipart/form-data for OpenAI `/images/edits`,
378
+ * `inlineData` parts for Gemini `:generateContent`).
379
+ *
380
+ * @param proxyUrl - Base URL of the proxy server (e.g. `http://localhost:3001`)
381
+ * @param params - Same parameters as {@link callProviderImageGeneration}
382
+ * @returns The generated images, or a failure
383
+ * @public
384
+ */
385
+ declare function callProxiedImageGeneration(proxyUrl: string, params: IProviderImageGenerationParams): Promise<Result<IAiImageGenerationResponse>>;
386
+
387
+ /**
388
+ * Calls the model-listing endpoint on a proxy server.
389
+ *
390
+ * @remarks
391
+ * Proxy contract:
392
+ * - Endpoint: `POST ${proxyUrl}/api/ai/list-models`
393
+ * - Request body: `{providerId, apiKey, capability?}`. Capability config is
394
+ * not forwarded — the proxy applies its own (typically the same default
395
+ * the library ships).
396
+ * - Success response body: an `IAiModelInfo[]` (under key `models`) where
397
+ * `capabilities` is serialized as a string array (not Set, which doesn't
398
+ * round-trip through JSON).
399
+ * - Error response body: `{error: string}`, surfaced as `proxy: ${error}`.
400
+ *
401
+ * @public
402
+ */
403
+ declare function callProxiedListModels(proxyUrl: string, params: IProviderListModelsParams): Promise<Result<ReadonlyArray<IAiModelInfo>>>;
404
+
197
405
  declare namespace Constants {
198
406
  export {
199
407
  ENCRYPTED_FILE_FORMAT,
@@ -210,7 +418,8 @@ declare namespace Converters {
210
418
  extendedArrayOf,
211
419
  rangeTypeOf,
212
420
  rangeOf,
213
- isoDate
421
+ isoDate,
422
+ isoDateTime
214
423
  }
215
424
  }
216
425
  export { Converters }
@@ -219,6 +428,12 @@ declare namespace Converters_2 {
219
428
  export {
220
429
  keystoreFormat,
221
430
  keystoreSecretType,
431
+ keystoreSymmetricSecretType,
432
+ keystoreAsymmetricSecretType,
433
+ keyPairAlgorithm,
434
+ jsonWebKeyShape,
435
+ keystoreSymmetricEntryJson,
436
+ keystoreAsymmetricEntryJson,
222
437
  keystoreSecretEntryJson,
223
438
  keystoreVaultContents,
224
439
  keystoreFile
@@ -271,6 +486,8 @@ declare namespace CryptoUtils {
271
486
  Converters_3 as Converters,
272
487
  DirectEncryptionProvider,
273
488
  IDirectEncryptionProviderParams,
489
+ IKeyPairAlgorithmParams,
490
+ keyPairAlgorithmParams,
274
491
  NodeCryptoProvider,
275
492
  nodeCryptoProvider,
276
493
  createEncryptedFile,
@@ -284,6 +501,10 @@ declare namespace CryptoUtils {
284
501
  EncryptedFileFormat,
285
502
  INamedSecret,
286
503
  IEncryptionResult,
504
+ KeyPairAlgorithm,
505
+ IWrapBytesOptions,
506
+ IWrappedBytes,
507
+ allKeyPairAlgorithms,
287
508
  KeyDerivationFunction,
288
509
  IKeyDerivationParams,
289
510
  IEncryptedFile,
@@ -345,6 +566,16 @@ declare const DEFAULT_ALGORITHM: "AES-256-GCM";
345
566
  */
346
567
  declare const DEFAULT_KEYSTORE_ITERATIONS: number;
347
568
 
569
+ /**
570
+ * Default capability config used by `callProviderListModels` when callers
571
+ * don't supply their own. Patterns are intentionally narrow — false
572
+ * positives are worse than missing a model. Caller can override per call
573
+ * via {@link IProviderListModelsParams.capabilityConfig}.
574
+ *
575
+ * @public
576
+ */
577
+ declare const DEFAULT_MODEL_CAPABILITY_CONFIG: IAiModelCapabilityConfig;
578
+
348
579
  /**
349
580
  * Default {@link Experimental.RangeOfFormats | formats} to use for both
350
581
  * open-ended and complete {@link Experimental.RangeOf | RangeOf<T>}.
@@ -532,7 +763,7 @@ declare class ExtendedArray<T> extends Array<T> {
532
763
  * If `onError` is `'failOnError'` (default), then the entire conversion fails if any element cannot
533
764
  * be converted. If `onError` is `'ignoreErrors'`, then failing elements are silently ignored.
534
765
  * @param converter - `Converter` used to convert each item in the array
535
- * @param ignoreErrors - Specifies treatment of unconvertible elements
766
+ * @param onError - Specifies treatment of unconvertible elements
536
767
  * @beta
537
768
  */
538
769
  declare function extendedArrayOf<T, TC = undefined>(label: string, converter: Converter<T, TC>, onError?: Conversion.OnError): Converter<ExtendedArray<T>, TC>;
@@ -650,6 +881,50 @@ declare namespace Hash {
650
881
  }
651
882
  export { Hash }
652
883
 
884
+ /**
885
+ * Options for adding an asymmetric keypair to the key store.
886
+ * @public
887
+ */
888
+ declare interface IAddKeyPairOptions {
889
+ /**
890
+ * Algorithm to use for the new keypair.
891
+ */
892
+ readonly algorithm: KeyPairAlgorithm;
893
+ /**
894
+ * Optional description for the entry.
895
+ */
896
+ readonly description?: string;
897
+ /**
898
+ * Whether to replace an existing entry with the same name.
899
+ * Replacement mints a fresh storage `id` and best-effort deletes the
900
+ * displaced storage blob; see the keystore design doc for details.
901
+ */
902
+ readonly replace?: boolean;
903
+ }
904
+
905
+ /**
906
+ * Result of adding an asymmetric keypair to the key store.
907
+ * @public
908
+ */
909
+ declare interface IAddKeyPairResult {
910
+ /**
911
+ * The asymmetric entry that was added.
912
+ */
913
+ readonly entry: IKeyStoreAsymmetricEntry;
914
+ /**
915
+ * Whether this replaced an existing entry.
916
+ */
917
+ readonly replaced: boolean;
918
+ /**
919
+ * Best-effort warning from displaced-resource cleanup. Set when this call
920
+ * replaced a prior entry but the corresponding
921
+ * {@link CryptoUtils.KeyStore.IPrivateKeyStorage}.delete failed; the new
922
+ * keypair is still committed and the orphaned blob is left for consumer-side
923
+ * GC to reconcile.
924
+ */
925
+ readonly warning?: string;
926
+ }
927
+
653
928
  /**
654
929
  * Options for adding a secret derived from a password.
655
930
  * @public
@@ -700,11 +975,19 @@ declare interface IAddSecretResult {
700
975
  /**
701
976
  * The secret entry that was added.
702
977
  */
703
- readonly entry: IKeyStoreSecretEntry;
978
+ readonly entry: IKeyStoreSymmetricEntry;
704
979
  /**
705
980
  * Whether this replaced an existing secret.
706
981
  */
707
982
  readonly replaced: boolean;
983
+ /**
984
+ * Best-effort warning from displaced-resource cleanup. Set when this call
985
+ * replaced an asymmetric-keypair entry but the corresponding
986
+ * {@link CryptoUtils.KeyStore.IPrivateKeyStorage}.delete failed; the new
987
+ * entry is still committed and the orphaned blob is left for consumer-side
988
+ * GC to reconcile.
989
+ */
990
+ readonly warning?: string;
708
991
  }
709
992
 
710
993
  /**
@@ -762,6 +1045,201 @@ declare interface IAiCompletionResponse {
762
1045
  readonly truncated: boolean;
763
1046
  }
764
1047
 
1048
+ /**
1049
+ * A single generated image.
1050
+ * @public
1051
+ */
1052
+ declare interface IAiGeneratedImage extends IAiImageData {
1053
+ /**
1054
+ * The prompt as rewritten by the provider, if any. OpenAI's image models
1055
+ * commonly rewrite prompts; other providers do not.
1056
+ */
1057
+ readonly revisedPrompt?: string;
1058
+ }
1059
+
1060
+ /**
1061
+ * Image attachment for a vision (image-input) prompt.
1062
+ *
1063
+ * @remarks
1064
+ * Extends {@link IAiImageData} with an OpenAI-specific `detail` hint that is
1065
+ * silently ignored by Anthropic, Gemini, and other providers.
1066
+ *
1067
+ * @public
1068
+ */
1069
+ declare interface IAiImageAttachment extends IAiImageData {
1070
+ /**
1071
+ * OpenAI vision detail hint:
1072
+ * - `'low'`: faster, cheaper, lower fidelity
1073
+ * - `'high'`: slower, more expensive, higher fidelity
1074
+ * - `'auto'` (default): provider chooses
1075
+ *
1076
+ * Ignored by providers other than OpenAI.
1077
+ */
1078
+ readonly detail?: 'low' | 'high' | 'auto';
1079
+ }
1080
+
1081
+ /**
1082
+ * Universal image representation used for both image input (vision prompts)
1083
+ * and image output (generation responses).
1084
+ *
1085
+ * @remarks
1086
+ * The base64 string is raw — no `data:` URL prefix. Use {@link AiAssist.toDataUrl} to
1087
+ * format it for browser-display contexts.
1088
+ *
1089
+ * @public
1090
+ */
1091
+ declare interface IAiImageData {
1092
+ /** MIME type, e.g. `'image/png'`, `'image/jpeg'`, `'image/webp'`. */
1093
+ readonly mimeType: string;
1094
+ /** Base64-encoded image bytes (no `data:` prefix). */
1095
+ readonly base64: string;
1096
+ }
1097
+
1098
+ /**
1099
+ * Options for image generation requests.
1100
+ *
1101
+ * @remarks
1102
+ * Provider compatibility is documented per field. The library does not
1103
+ * pre-validate against per-model constraints (e.g. `dall-e-3` rejects
1104
+ * `count > 1`); provider 400 errors surface through the failure path.
1105
+ *
1106
+ * @public
1107
+ */
1108
+ declare interface IAiImageGenerationOptions {
1109
+ /**
1110
+ * Image dimensions. Used by openai-format providers (mapped to the
1111
+ * provider's `size` field). Ignored by Imagen — use
1112
+ * {@link IAiImageGenerationOptions.imagen} `aspectRatio` instead.
1113
+ *
1114
+ * Note: each model has its own accepted set; `dall-e-3` only accepts the
1115
+ * values listed here.
1116
+ */
1117
+ readonly size?: '1024x1024' | '1024x1792' | '1792x1024' | 'auto';
1118
+ /**
1119
+ * Number of images to generate. Default 1.
1120
+ *
1121
+ * Note: `dall-e-3` rejects `count > 1`.
1122
+ */
1123
+ readonly count?: number;
1124
+ /** Generation quality hint where supported. */
1125
+ readonly quality?: 'standard' | 'high';
1126
+ /** Random seed for reproducibility, where supported. */
1127
+ readonly seed?: number;
1128
+ /**
1129
+ * Imagen-specific options. Ignored by other providers.
1130
+ */
1131
+ readonly imagen?: {
1132
+ readonly negativePrompt?: string;
1133
+ readonly aspectRatio?: '1:1' | '3:4' | '4:3' | '9:16' | '16:9';
1134
+ };
1135
+ }
1136
+
1137
+ /**
1138
+ * Parameters for an image-generation request.
1139
+ * @public
1140
+ */
1141
+ declare interface IAiImageGenerationParams {
1142
+ /** The text prompt describing the desired image. */
1143
+ readonly prompt: string;
1144
+ /** Optional generation options. */
1145
+ readonly options?: IAiImageGenerationOptions;
1146
+ /**
1147
+ * Optional reference images. When present, the provider will use them as
1148
+ * visual context (e.g. to preserve a character's appearance across multiple
1149
+ * generations). The dispatcher resolves the
1150
+ * {@link AiAssist.IAiImageModelCapability} for the requested model and
1151
+ * rejects the call up front if `acceptsImageReferenceInput` is not set on
1152
+ * the matching capability. An empty array is treated identically to
1153
+ * `undefined`.
1154
+ */
1155
+ readonly referenceImages?: ReadonlyArray<IAiImageAttachment>;
1156
+ }
1157
+
1158
+ /**
1159
+ * Result of an image-generation call.
1160
+ * @public
1161
+ */
1162
+ declare interface IAiImageGenerationResponse {
1163
+ /** The generated images, in provider-returned order. */
1164
+ readonly images: ReadonlyArray<IAiGeneratedImage>;
1165
+ }
1166
+
1167
+ /**
1168
+ * Image-generation capability for a model family within a provider. Used as
1169
+ * an entry in {@link IAiProviderDescriptor.imageGeneration}.
1170
+ *
1171
+ * @public
1172
+ */
1173
+ declare interface IAiImageModelCapability {
1174
+ /**
1175
+ * Prefix matched against the resolved image model id. The empty string is
1176
+ * the catch-all and matches every model. When multiple rules' prefixes
1177
+ * match a model id, the longest prefix wins; ties are broken by
1178
+ * first-encountered.
1179
+ */
1180
+ readonly modelPrefix: string;
1181
+ /** API format used to dispatch requests for matching models. */
1182
+ readonly format: AiImageApiFormat;
1183
+ /**
1184
+ * Whether matching models accept reference images via
1185
+ * {@link AiAssist.IAiImageGenerationParams.referenceImages}. When false or
1186
+ * undefined, calls that include reference images are rejected up front.
1187
+ *
1188
+ * @remarks
1189
+ * Per-model constraints beyond ref support (e.g. dall-e-3 ignores edits)
1190
+ * are not validated here and surface as provider 400s, consistent with the
1191
+ * existing image-generation policy.
1192
+ */
1193
+ readonly acceptsImageReferenceInput?: boolean;
1194
+ }
1195
+
1196
+ /**
1197
+ * Configuration that maps model id patterns to capabilities. Used to
1198
+ * augment (or, where the provider supplies no capability info, fully
1199
+ * derive) the capability set for each listed model.
1200
+ * @public
1201
+ */
1202
+ declare interface IAiModelCapabilityConfig {
1203
+ /** Per-provider rules. Tried before {@link AiAssist.IAiModelCapabilityConfig.global}. */
1204
+ readonly perProvider?: {
1205
+ readonly [P in AiProviderId]?: ReadonlyArray<IAiModelCapabilityRule>;
1206
+ };
1207
+ /** Cross-provider fallback rules. */
1208
+ readonly global?: ReadonlyArray<IAiModelCapabilityRule>;
1209
+ }
1210
+
1211
+ /**
1212
+ * One rule in an {@link IAiModelCapabilityConfig}. Multiple rules can match
1213
+ * a single model — their capability arrays are unioned.
1214
+ * @public
1215
+ */
1216
+ declare interface IAiModelCapabilityRule {
1217
+ /** RegExp tested against the model id (using `.test`). */
1218
+ readonly idPattern: RegExp;
1219
+ /** Capabilities this rule attributes to matching models. */
1220
+ readonly capabilities: ReadonlyArray<AiModelCapability>;
1221
+ /**
1222
+ * Friendly display-name override for matching models. The function form
1223
+ * lets one rule format many ids (e.g. `(id) => id.toUpperCase()`).
1224
+ * If multiple matching rules supply `displayName`, the first match wins.
1225
+ */
1226
+ readonly displayName?: string | ((id: string) => string);
1227
+ }
1228
+
1229
+ /**
1230
+ * Information about a single model returned by a provider's list endpoint,
1231
+ * with capabilities already resolved (native + config rules).
1232
+ * @public
1233
+ */
1234
+ declare interface IAiModelInfo {
1235
+ /** Provider-native model identifier. */
1236
+ readonly id: string;
1237
+ /** Resolved capability set — union of native declarations and config rules. */
1238
+ readonly capabilities: ReadonlySet<AiModelCapability>;
1239
+ /** Friendly name for display, when known. */
1240
+ readonly displayName?: string;
1241
+ }
1242
+
765
1243
  /**
766
1244
  * Describes a single AI provider — single source of truth for all metadata.
767
1245
  * @public
@@ -785,6 +1263,111 @@ declare interface IAiProviderDescriptor {
785
1263
  readonly supportedTools: ReadonlyArray<AiServerToolType>;
786
1264
  /** Whether this provider's API enforces CORS restrictions that prevent direct browser calls. */
787
1265
  readonly corsRestricted: boolean;
1266
+ /**
1267
+ * Whether this provider's streaming completion endpoint requires a proxy
1268
+ * for direct browser calls. Some providers gate streaming separately from
1269
+ * non-streaming (rare), so this is tracked independently from
1270
+ * {@link IAiProviderDescriptor.corsRestricted}.
1271
+ *
1272
+ * @remarks
1273
+ * When `true`, `callProviderCompletionStream` rejects up front unless the
1274
+ * call is being routed through a proxy.
1275
+ */
1276
+ readonly streamingCorsRestricted: boolean;
1277
+ /**
1278
+ * Whether this provider's chat completions API accepts image input
1279
+ * (i.e. supports vision prompts). When false, calls with
1280
+ * `prompt.attachments` are rejected up front.
1281
+ */
1282
+ readonly acceptsImageInput: boolean;
1283
+ /**
1284
+ * Image-generation capabilities, scoped to model id prefixes. Empty or
1285
+ * undefined means the provider does not support image generation.
1286
+ *
1287
+ * @remarks
1288
+ * The dispatcher matches the resolved model id against each rule's
1289
+ * `modelPrefix` and selects the longest match (see
1290
+ * {@link AiAssist.resolveImageCapability}). An empty `modelPrefix` is the
1291
+ * catch-all and matches every model id.
1292
+ *
1293
+ * Multiple entries support providers that host more than one image-API
1294
+ * surface under one baseUrl. Google Gemini is the canonical case: the
1295
+ * `imagen-*` family is predict-only via `:predict`, while
1296
+ * `gemini-2.5-flash-image` uses chat-style `:generateContent` and accepts
1297
+ * reference images. Listing both lets callers pick the right model and the
1298
+ * dispatcher routes accordingly.
1299
+ *
1300
+ * Image-model selection reuses the existing `image` {@link ModelSpecKey}.
1301
+ * Providers that declare `imageGeneration` should declare a model in
1302
+ * `defaultModel.image`, e.g. `{ base: 'gpt-4o', image: 'dall-e-3' }`.
1303
+ */
1304
+ readonly imageGeneration?: ReadonlyArray<IAiImageModelCapability>;
1305
+ }
1306
+
1307
+ /**
1308
+ * Terminal success event for a streaming completion. Carries the aggregated
1309
+ * full text and truncation status for callers that want both the progressive
1310
+ * UI and the complete result.
1311
+ * @public
1312
+ */
1313
+ declare interface IAiStreamDone {
1314
+ readonly type: 'done';
1315
+ /** Whether the response was truncated due to token limits. */
1316
+ readonly truncated: boolean;
1317
+ /** The full concatenated text from all `text-delta` events. */
1318
+ readonly fullText: string;
1319
+ }
1320
+
1321
+ /**
1322
+ * Terminal failure event for a streaming completion. After this event no
1323
+ * further events are emitted.
1324
+ *
1325
+ * @remarks
1326
+ * Connection-time failures (auth, network, pre-flight CORS rejection) are
1327
+ * surfaced via the outer `Result.fail` returned by
1328
+ * `callProviderCompletionStream` rather than as an `error` event, so callers
1329
+ * can distinguish "didn't start" from "started but errored mid-stream."
1330
+ *
1331
+ * @public
1332
+ */
1333
+ declare interface IAiStreamError {
1334
+ readonly type: 'error';
1335
+ readonly message: string;
1336
+ }
1337
+
1338
+ /**
1339
+ * Discriminated union of events emitted by a streaming completion.
1340
+ * @public
1341
+ */
1342
+ declare type IAiStreamEvent = IAiStreamTextDelta | IAiStreamToolEvent | IAiStreamDone | IAiStreamError;
1343
+
1344
+ /**
1345
+ * A text-content delta arriving during a streaming completion.
1346
+ * @public
1347
+ */
1348
+ declare interface IAiStreamTextDelta {
1349
+ readonly type: 'text-delta';
1350
+ /** The newly arrived text fragment. */
1351
+ readonly delta: string;
1352
+ }
1353
+
1354
+ /**
1355
+ * A server-side tool progress event arriving during a streaming completion.
1356
+ * Surfaced for providers that emit explicit tool-progress markers (OpenAI
1357
+ * Responses API, Anthropic). Gemini's grounding doesn't emit these.
1358
+ * @public
1359
+ */
1360
+ declare interface IAiStreamToolEvent {
1361
+ readonly type: 'tool-event';
1362
+ /** Which server-side tool this event describes. */
1363
+ readonly toolType: AiServerToolType;
1364
+ /** Tool lifecycle phase. */
1365
+ readonly phase: 'started' | 'completed';
1366
+ /**
1367
+ * Optional provider-specific detail. For web_search this is typically the
1368
+ * search query when available; format varies by provider.
1369
+ */
1370
+ readonly detail?: string;
788
1371
  }
789
1372
 
790
1373
  /**
@@ -937,6 +1520,12 @@ declare interface ICryptoProvider {
937
1520
  * @returns Success with derived 32-byte key, or Failure with error
938
1521
  */
939
1522
  deriveKey(password: string, salt: Uint8Array, iterations: number): Promise<Result<Uint8Array>>;
1523
+ /**
1524
+ * Computes a SHA-256 hash of the given data.
1525
+ * @param data - UTF-8 string to hash
1526
+ * @returns Success with hex-encoded hash string, or Failure with error
1527
+ */
1528
+ sha256(data: string): Promise<Result<string>>;
940
1529
  /**
941
1530
  * Generates cryptographically secure random bytes.
942
1531
  * @param length - Number of bytes to generate
@@ -955,6 +1544,73 @@ declare interface ICryptoProvider {
955
1544
  * @returns Success with decoded bytes, or Failure if invalid base64
956
1545
  */
957
1546
  fromBase64(base64: string): Result<Uint8Array>;
1547
+ /**
1548
+ * Generates a new asymmetric keypair for the requested algorithm.
1549
+ * @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} to use.
1550
+ * @param extractable - Whether the resulting `CryptoKey` objects may be exported.
1551
+ * Set `false` on backends that store `CryptoKey` references directly (e.g.
1552
+ * IndexedDB). Set `true` when the private key must round-trip through JWK or
1553
+ * PKCS#8 (e.g. encrypted-file backends).
1554
+ * @returns Success with the generated `CryptoKeyPair`, or Failure with error context.
1555
+ */
1556
+ generateKeyPair(algorithm: KeyPairAlgorithm, extractable: boolean): Promise<Result<CryptoKeyPair>>;
1557
+ /**
1558
+ * Exports the public half of a keypair as a JSON Web Key.
1559
+ * @param publicKey - The public `CryptoKey` to export. Must be an `extractable`
1560
+ * key generated for an asymmetric algorithm.
1561
+ * @returns Success with the JWK, or Failure with error context.
1562
+ */
1563
+ exportPublicKeyJwk(publicKey: CryptoKey): Promise<Result<JsonWebKey>>;
1564
+ /**
1565
+ * Re-imports a public-key JWK as a `CryptoKey` usable for verification or
1566
+ * encryption (depending on algorithm).
1567
+ * @param jwk - The JSON Web Key produced by {@link CryptoUtils.ICryptoProvider.exportPublicKeyJwk | exportPublicKeyJwk}.
1568
+ * @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} the
1569
+ * key was generated for. Determines the import parameters and key usages.
1570
+ * @returns Success with the imported public `CryptoKey`, or Failure with error context.
1571
+ */
1572
+ importPublicKeyJwk(jwk: JsonWebKey, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;
1573
+ /**
1574
+ * Wraps `plaintext` for delivery to the holder of the private key paired
1575
+ * with `recipientPublicKey`. Uses ECIES with ECDH P-256, HKDF-SHA256, and
1576
+ * AES-GCM-256.
1577
+ *
1578
+ * Generates a fresh ephemeral keypair per call; the ephemeral private key
1579
+ * is discarded after the shared-secret derive. Only the recipient (with the
1580
+ * matching private key) and the same HKDF parameters can recover
1581
+ * `plaintext`.
1582
+ *
1583
+ * Empty `plaintext` is permitted; the resulting wrap contains only the
1584
+ * 16-byte GCM authentication tag and round-trips back to an empty
1585
+ * `Uint8Array`.
1586
+ * @param plaintext - The bytes to wrap. Any length supported by AES-GCM
1587
+ * (in practice, well below 2^39 - 256 bits).
1588
+ * @param recipientPublicKey - The recipient's ECDH P-256 public `CryptoKey`.
1589
+ * Must have algorithm name `'ECDH'` and named curve `'P-256'`; mismatched
1590
+ * algorithm or curve yields a `Failure` with error context.
1591
+ * @param options - HKDF parameters; see {@link CryptoUtils.IWrapBytesOptions | IWrapBytesOptions}.
1592
+ * @returns `Success` with the wrapped payload, or `Failure` with error context.
1593
+ */
1594
+ wrapBytes(plaintext: Uint8Array, recipientPublicKey: CryptoKey, options: IWrapBytesOptions): Promise<Result<IWrappedBytes>>;
1595
+ /**
1596
+ * Inverse of {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes}.
1597
+ * Recovers the original `plaintext` from a wrapped payload using the
1598
+ * recipient's private key.
1599
+ *
1600
+ * Returns a `Failure` (never throws) on any of:
1601
+ * - Tampered nonce or ciphertext (AES-GCM authentication fails)
1602
+ * - Wrong private key (different shared secret derives a different wrap key)
1603
+ * - Wrong HKDF parameters (different wrap key)
1604
+ * - Malformed `ephemeralPublicKey` JWK
1605
+ * - Malformed base64 in `nonce` or `ciphertext`
1606
+ * @param wrapped - The wrapped payload produced by `wrapBytes`.
1607
+ * @param recipientPrivateKey - The recipient's ECDH P-256 private
1608
+ * `CryptoKey`. Must have algorithm name `'ECDH'` and named curve `'P-256'`,
1609
+ * and key usages including `'deriveKey'` or `'deriveBits'`.
1610
+ * @param options - The same HKDF parameters used at wrap time.
1611
+ * @returns `Success` with the original `plaintext`, or `Failure` with error context.
1612
+ */
1613
+ unwrapBytes(wrapped: IWrappedBytes, recipientPrivateKey: CryptoKey, options: IWrapBytesOptions): Promise<Result<Uint8Array>>;
958
1614
  }
959
1615
 
960
1616
  /**
@@ -1093,6 +1749,19 @@ declare interface IEncryptionResult {
1093
1749
  readonly encryptedData: Uint8Array;
1094
1750
  }
1095
1751
 
1752
+ /**
1753
+ * Options for importing raw key material via {@link KeyStore.importSecret}.
1754
+ * Extends {@link IImportSecretOptions} with a type classification.
1755
+ * @public
1756
+ */
1757
+ declare interface IImportKeyOptions extends IImportSecretOptions {
1758
+ /**
1759
+ * Symmetric secret type classification for the imported key material.
1760
+ * @defaultValue 'encryption-key'
1761
+ */
1762
+ readonly type?: KeyStoreSymmetricSecretType;
1763
+ }
1764
+
1096
1765
  /**
1097
1766
  * Options for importing a secret.
1098
1767
  * @public
@@ -1113,15 +1782,120 @@ declare interface IKeyDerivationParams {
1113
1782
  /**
1114
1783
  * Key derivation function used.
1115
1784
  */
1116
- readonly kdf: KeyDerivationFunction;
1785
+ readonly kdf: KeyDerivationFunction;
1786
+ /**
1787
+ * Base64-encoded salt used for key derivation.
1788
+ */
1789
+ readonly salt: string;
1790
+ /**
1791
+ * Number of iterations used for key derivation.
1792
+ */
1793
+ readonly iterations: number;
1794
+ }
1795
+
1796
+ /**
1797
+ * WebCrypto parameters for a single {@link CryptoUtils.KeyPairAlgorithm}.
1798
+ * Implementations of {@link CryptoUtils.ICryptoProvider} use this table to
1799
+ * translate the small public algorithm enum into the WebCrypto algorithm
1800
+ * objects and key-usage arrays expected by `crypto.subtle`.
1801
+ * @public
1802
+ */
1803
+ declare interface IKeyPairAlgorithmParams {
1804
+ /**
1805
+ * Algorithm parameters for `crypto.subtle.generateKey`. Always an asymmetric
1806
+ * variant — these algorithms produce a `CryptoKeyPair`, not a single key.
1807
+ */
1808
+ readonly generateKey: RsaHashedKeyGenParams | EcKeyGenParams;
1809
+ /**
1810
+ * Algorithm parameters for `crypto.subtle.importKey('jwk', ...)` when
1811
+ * importing the public half of a keypair.
1812
+ */
1813
+ readonly importPublicKey: RsaHashedImportParams | EcKeyImportParams;
1814
+ /**
1815
+ * Default key usages for the generated `CryptoKeyPair`. Both halves receive
1816
+ * the usages WebCrypto considers valid for their role; the platform filters.
1817
+ */
1818
+ readonly keyPairUsages: ReadonlyArray<KeyUsage>;
1819
+ /**
1820
+ * Key usages applied when re-importing only the public key.
1821
+ */
1822
+ readonly publicKeyUsages: ReadonlyArray<KeyUsage>;
1823
+ }
1824
+
1825
+ /**
1826
+ * An asymmetric keypair entry stored in the vault (in-memory representation).
1827
+ * Holds only the public key (as a JWK) and a stable handle (`id`) the
1828
+ * {@link CryptoUtils.KeyStore.IPrivateKeyStorage} provider uses to fetch the private key.
1829
+ * @public
1830
+ */
1831
+ declare interface IKeyStoreAsymmetricEntry {
1832
+ /**
1833
+ * Unique name for this entry (used as vault lookup key, renameable).
1834
+ */
1835
+ readonly name: string;
1836
+ /**
1837
+ * Asymmetric secret type discriminator.
1838
+ */
1839
+ readonly type: KeyStoreAsymmetricSecretType;
1840
+ /**
1841
+ * Immutable handle used by {@link CryptoUtils.KeyStore.IPrivateKeyStorage} to address the
1842
+ * private key. Independent of `name`; survives renames.
1843
+ */
1844
+ readonly id: string;
1845
+ /**
1846
+ * Algorithm used to generate this keypair.
1847
+ */
1848
+ readonly algorithm: KeyPairAlgorithm;
1849
+ /**
1850
+ * The public key as a JSON Web Key.
1851
+ */
1852
+ readonly publicKeyJwk: JsonWebKey;
1853
+ /**
1854
+ * Optional description for this entry.
1855
+ */
1856
+ readonly description?: string;
1857
+ /**
1858
+ * When this entry was added (ISO 8601).
1859
+ */
1860
+ readonly createdAt: string;
1861
+ }
1862
+
1863
+ /**
1864
+ * JSON-serializable representation of an asymmetric keypair entry.
1865
+ * The private key is not present here — it lives in the
1866
+ * {@link CryptoUtils.KeyStore.IPrivateKeyStorage} provider, addressed by `id`.
1867
+ * @public
1868
+ */
1869
+ declare interface IKeyStoreAsymmetricEntryJson {
1870
+ /**
1871
+ * Unique name for this entry.
1872
+ */
1873
+ readonly name: string;
1874
+ /**
1875
+ * Asymmetric secret type discriminator.
1876
+ */
1877
+ readonly type: KeyStoreAsymmetricSecretType;
1878
+ /**
1879
+ * Immutable handle used by {@link CryptoUtils.KeyStore.IPrivateKeyStorage} to address the
1880
+ * private key.
1881
+ */
1882
+ readonly id: string;
1883
+ /**
1884
+ * Algorithm used to generate this keypair.
1885
+ */
1886
+ readonly algorithm: KeyPairAlgorithm;
1887
+ /**
1888
+ * The public key as a JSON Web Key.
1889
+ */
1890
+ readonly publicKeyJwk: JsonWebKey;
1117
1891
  /**
1118
- * Base64-encoded salt used for key derivation.
1892
+ * Optional description.
1119
1893
  */
1120
- readonly salt: string;
1894
+ readonly description?: string;
1121
1895
  /**
1122
- * Number of iterations used for key derivation.
1896
+ * When this entry was added (ISO 8601).
1123
1897
  */
1124
- readonly iterations: number;
1898
+ readonly createdAt: string;
1125
1899
  }
1126
1900
 
1127
1901
  /**
@@ -1137,8 +1911,26 @@ declare interface IKeyStoreCreateParams {
1137
1911
  * PBKDF2 iterations (defaults to DEFAULT_KEYSTORE_ITERATIONS).
1138
1912
  */
1139
1913
  readonly iterations?: number;
1914
+ /**
1915
+ * Optional private-key storage backend. Required to use `addKeyPair` /
1916
+ * `getKeyPair`; absent backends still permit opening, listing, and reading
1917
+ * public-key metadata for asymmetric entries.
1918
+ */
1919
+ readonly privateKeyStorage?: IPrivateKeyStorage;
1140
1920
  }
1141
1921
 
1922
+ /**
1923
+ * Any vault entry, discriminated by `type`.
1924
+ * @public
1925
+ */
1926
+ declare type IKeyStoreEntry = IKeyStoreSymmetricEntry | IKeyStoreAsymmetricEntry;
1927
+
1928
+ /**
1929
+ * Any JSON vault entry, discriminated by `type`.
1930
+ * @public
1931
+ */
1932
+ declare type IKeyStoreEntryJson = IKeyStoreSymmetricEntryJson | IKeyStoreAsymmetricEntryJson;
1933
+
1142
1934
  /**
1143
1935
  * The encrypted key store file format.
1144
1936
  * @public
@@ -1183,22 +1975,46 @@ declare interface IKeyStoreOpenParams {
1183
1975
  * The encrypted key store file content.
1184
1976
  */
1185
1977
  readonly keystoreFile: IKeyStoreFile;
1978
+ /**
1979
+ * Optional private-key storage backend. Required to use `addKeyPair` /
1980
+ * `getKeyPair`; absent backends still permit opening, listing, and reading
1981
+ * public-key metadata for asymmetric entries.
1982
+ */
1983
+ readonly privateKeyStorage?: IPrivateKeyStorage;
1186
1984
  }
1187
1985
 
1188
1986
  /**
1189
- * A secret entry stored in the vault (in-memory representation).
1987
+ * Backwards-compatible alias for {@link CryptoUtils.KeyStore.IKeyStoreSymmetricEntry}.
1988
+ * @deprecated Use {@link CryptoUtils.KeyStore.IKeyStoreSymmetricEntry} for symmetric
1989
+ * entries or {@link CryptoUtils.KeyStore.IKeyStoreEntry} for the discriminated union.
1990
+ * @public
1991
+ */
1992
+ declare type IKeyStoreSecretEntry = IKeyStoreSymmetricEntry;
1993
+
1994
+ /**
1995
+ * Backwards-compatible alias for {@link CryptoUtils.KeyStore.IKeyStoreSymmetricEntryJson}.
1996
+ * @deprecated Use {@link CryptoUtils.KeyStore.IKeyStoreSymmetricEntryJson} for
1997
+ * symmetric entries or {@link CryptoUtils.KeyStore.IKeyStoreEntryJson} for the
1998
+ * discriminated union.
1190
1999
  * @public
1191
2000
  */
1192
- declare interface IKeyStoreSecretEntry {
2001
+ declare type IKeyStoreSecretEntryJson = IKeyStoreSymmetricEntryJson;
2002
+
2003
+ /**
2004
+ * A symmetric secret entry stored in the vault (in-memory representation).
2005
+ * Holds the raw key material directly — for `'encryption-key'` it is a 32-byte
2006
+ * AES-256 key; for `'api-key'` it is the UTF-8 encoded API key string.
2007
+ * @public
2008
+ */
2009
+ declare interface IKeyStoreSymmetricEntry {
1193
2010
  /**
1194
2011
  * Unique name for this secret (used as lookup key).
1195
2012
  */
1196
2013
  readonly name: string;
1197
2014
  /**
1198
- * Secret type discriminator.
1199
- * Defaults to `'encryption-key'` for backwards compatibility.
2015
+ * Symmetric secret type discriminator.
1200
2016
  */
1201
- readonly type: KeyStoreSecretType;
2017
+ readonly type: KeyStoreSymmetricSecretType;
1202
2018
  /**
1203
2019
  * The secret data.
1204
2020
  * - For `'encryption-key'`: 32-byte AES-256 key.
@@ -1216,19 +2032,34 @@ declare interface IKeyStoreSecretEntry {
1216
2032
  }
1217
2033
 
1218
2034
  /**
1219
- * JSON-serializable version of secret entry (for storage).
2035
+ * JSON-serializable representation of a symmetric secret entry.
2036
+ *
2037
+ * @remarks
2038
+ * Describes the *normalized* shape after parsing. `type` is required here
2039
+ * because the converter (see
2040
+ * {@link CryptoUtils.KeyStore.Converters.keystoreSymmetricEntryJson | keystoreSymmetricEntryJson})
2041
+ * injects the default `'encryption-key'` when reading vaults written before
2042
+ * asymmetric-keypair support added the discriminator. Raw on-wire bytes from
2043
+ * a legacy vault may therefore omit `type`; downstream code only ever sees
2044
+ * the post-conversion shape declared here.
2045
+ *
1220
2046
  * @public
1221
2047
  */
1222
- declare interface IKeyStoreSecretEntryJson {
2048
+ declare interface IKeyStoreSymmetricEntryJson {
1223
2049
  /**
1224
2050
  * Unique name for this secret.
1225
2051
  */
1226
2052
  readonly name: string;
1227
2053
  /**
1228
- * Secret type discriminator.
1229
- * Optional for backwards compatibility — missing means `'encryption-key'`.
2054
+ * Symmetric secret type discriminator.
2055
+ *
2056
+ * Required on this normalized model type. Vaults written prior to the
2057
+ * asymmetric-keypair support may omit this field on the wire; the
2058
+ * converter injects `'encryption-key'` when missing for backwards
2059
+ * compatibility, so by the time a value of this type is observed the
2060
+ * discriminator is always present.
1230
2061
  */
1231
- readonly type?: KeyStoreSecretType;
2062
+ readonly type: KeyStoreSymmetricSecretType;
1232
2063
  /**
1233
2064
  * Base64-encoded secret data.
1234
2065
  */
@@ -1244,7 +2075,7 @@ declare interface IKeyStoreSecretEntryJson {
1244
2075
  }
1245
2076
 
1246
2077
  /**
1247
- * The decrypted vault contents - a versioned map of secrets.
2078
+ * The decrypted vault contents - a versioned map of entries.
1248
2079
  * @public
1249
2080
  */
1250
2081
  declare interface IKeyStoreVaultContents {
@@ -1253,9 +2084,9 @@ declare interface IKeyStoreVaultContents {
1253
2084
  */
1254
2085
  readonly version: KeyStoreFormat;
1255
2086
  /**
1256
- * Map of secret name to secret entry.
2087
+ * Map of entry name to entry (symmetric or asymmetric).
1257
2088
  */
1258
- readonly secrets: Record<string, IKeyStoreSecretEntryJson>;
2089
+ readonly secrets: Record<string, IKeyStoreEntryJson>;
1259
2090
  }
1260
2091
 
1261
2092
  /**
@@ -1338,6 +2169,55 @@ declare interface INamedSecret {
1338
2169
  readonly key: Uint8Array;
1339
2170
  }
1340
2171
 
2172
+ /**
2173
+ * Pluggable backend that persists raw asymmetric private keys outside of the
2174
+ * encrypted keystore vault. Concrete implementations live in platform-specific
2175
+ * packages (e.g. an IndexedDB-backed implementation in `@fgv/ts-web-extras` or
2176
+ * an encrypted-file implementation in `@fgv/ts-chocolate`).
2177
+ *
2178
+ * The keystore writes storage-first: a private key is always stored here
2179
+ * before the corresponding public-key vault entry is committed. Conversely,
2180
+ * deletes hit the vault first and then this storage best-effort. As a result,
2181
+ * crashes or skipped saves can leave orphaned blobs here; callers are expected
2182
+ * to reconcile via {@link CryptoUtils.KeyStore.IPrivateKeyStorage.list} cross-referenced
2183
+ * against the keystore's asymmetric entries.
2184
+ *
2185
+ * @public
2186
+ */
2187
+ declare interface IPrivateKeyStorage {
2188
+ /**
2189
+ * Whether keys generated for this backend may be marked
2190
+ * `extractable: false`. `true` on backends that store `CryptoKey`
2191
+ * objects directly (e.g. IndexedDB). `false` on backends that must
2192
+ * round-trip via JWK (e.g. encrypted-file backends).
2193
+ */
2194
+ readonly supportsNonExtractable: boolean;
2195
+ /**
2196
+ * Stores `key` under `id`. Returns the stored `id` on success so the
2197
+ * call can compose into a Result chain.
2198
+ * @param id - Storage handle to write under.
2199
+ * @param key - The private `CryptoKey` to persist.
2200
+ */
2201
+ store(id: string, key: CryptoKey): Promise<Result<string>>;
2202
+ /**
2203
+ * Loads the private key previously stored under `id`.
2204
+ * @param id - Storage handle to look up.
2205
+ */
2206
+ load(id: string): Promise<Result<CryptoKey>>;
2207
+ /**
2208
+ * Deletes the entry stored under `id`. Returns the deleted `id` on
2209
+ * success so the call can compose into a Result chain.
2210
+ * @param id - Storage handle to remove.
2211
+ */
2212
+ delete(id: string): Promise<Result<string>>;
2213
+ /**
2214
+ * Lists every `id` currently held by the backend. Used by consumers to
2215
+ * garbage-collect orphans left by crashes or aborted sessions; the
2216
+ * keystore itself does not invoke this automatically.
2217
+ */
2218
+ list(): Promise<Result<readonly string[]>>;
2219
+ }
2220
+
1341
2221
  /**
1342
2222
  * Parameters for a provider completion request.
1343
2223
  * @public
@@ -1362,6 +2242,97 @@ declare interface IProviderCompletionParams {
1362
2242
  readonly logger?: Logging.ILogger;
1363
2243
  /** Server-side tools to include in the request. Overrides settings-level tool config when provided. */
1364
2244
  readonly tools?: ReadonlyArray<AiServerToolConfig>;
2245
+ /** Optional abort signal for cancelling the in-flight request. */
2246
+ readonly signal?: AbortSignal;
2247
+ }
2248
+
2249
+ /**
2250
+ * Parameters for a streaming completion request. Structurally identical to
2251
+ * the non-streaming `IProviderCompletionParams`; kept as its own interface
2252
+ * so callers can be explicit about which path they're invoking.
2253
+ *
2254
+ * @public
2255
+ */
2256
+ declare interface IProviderCompletionStreamParams {
2257
+ /** The provider descriptor */
2258
+ readonly descriptor: IAiProviderDescriptor;
2259
+ /** API key for authentication */
2260
+ readonly apiKey: string;
2261
+ /** The structured prompt to send */
2262
+ readonly prompt: AiPrompt;
2263
+ /**
2264
+ * Prior conversation history to insert between the system prompt and the
2265
+ * prompt's user message. The new user turn (carried by `prompt.user`) is
2266
+ * always sent last, so the wire shape becomes
2267
+ * `[system, ...messagesBefore, user=prompt.user]`.
2268
+ */
2269
+ readonly messagesBefore?: ReadonlyArray<IChatMessage>;
2270
+ /** Sampling temperature (default: 0.7) */
2271
+ readonly temperature?: number;
2272
+ /** Optional model override — string or context-aware map. */
2273
+ readonly modelOverride?: ModelSpec;
2274
+ /** Optional logger for request/response observability. */
2275
+ readonly logger?: Logging.ILogger;
2276
+ /** Server-side tools to include in the request. */
2277
+ readonly tools?: ReadonlyArray<AiServerToolConfig>;
2278
+ /** Optional abort signal for cancelling the in-flight stream. */
2279
+ readonly signal?: AbortSignal;
2280
+ }
2281
+
2282
+ /**
2283
+ * Parameters for an image-generation request.
2284
+ * @public
2285
+ */
2286
+ declare interface IProviderImageGenerationParams {
2287
+ /** The provider descriptor */
2288
+ readonly descriptor: IAiProviderDescriptor;
2289
+ /** API key for authentication */
2290
+ readonly apiKey: string;
2291
+ /** The image-generation request */
2292
+ readonly params: IAiImageGenerationParams;
2293
+ /** Optional model override — string or context-aware map (uses descriptor.defaultModel.image otherwise) */
2294
+ readonly modelOverride?: ModelSpec;
2295
+ /** Optional logger for request/response observability. */
2296
+ readonly logger?: Logging.ILogger;
2297
+ /** Optional abort signal for cancelling the in-flight request. */
2298
+ readonly signal?: AbortSignal;
2299
+ }
2300
+
2301
+ /**
2302
+ * Parameters for a list-models request.
2303
+ * @public
2304
+ */
2305
+ declare interface IProviderListModelsParams {
2306
+ /** The provider descriptor */
2307
+ readonly descriptor: IAiProviderDescriptor;
2308
+ /** API key for authentication */
2309
+ readonly apiKey: string;
2310
+ /** Optional capability filter; when set, only models declaring this capability are returned. */
2311
+ readonly capability?: AiModelCapability;
2312
+ /** Optional capability config override (defaults to {@link DEFAULT_MODEL_CAPABILITY_CONFIG}). */
2313
+ readonly capabilityConfig?: IAiModelCapabilityConfig;
2314
+ /** Optional logger for request/response observability. */
2315
+ readonly logger?: Logging.ILogger;
2316
+ /** Optional abort signal for cancelling the in-flight request. */
2317
+ readonly signal?: AbortSignal;
2318
+ }
2319
+
2320
+ /**
2321
+ * Result of removing a secret from the key store.
2322
+ * @public
2323
+ */
2324
+ declare interface IRemoveSecretResult {
2325
+ /**
2326
+ * The secret entry that was removed from the vault.
2327
+ */
2328
+ readonly entry: IKeyStoreEntry;
2329
+ /**
2330
+ * Best-effort warning from {@link CryptoUtils.KeyStore.IPrivateKeyStorage}.delete
2331
+ * for asymmetric entries when the storage call failed. The vault entry is
2332
+ * still considered removed and the orphaned blob is left for consumer-side
2333
+ * GC to reconcile.
2334
+ */
2335
+ readonly warning?: string;
1365
2336
  }
1366
2337
 
1367
2338
  /**
@@ -1399,6 +2370,13 @@ declare function isKeyStoreFile(json: unknown): boolean;
1399
2370
  */
1400
2371
  declare const isoDate: Converter<Date, unknown>;
1401
2372
 
2373
+ /**
2374
+ * A `Converter` which converts an iso formatted string, a number or a `Date` object to
2375
+ * a `DateTime` object.
2376
+ * @public
2377
+ */
2378
+ declare const isoDateTime: Converter<DateTime, unknown>;
2379
+
1402
2380
  /**
1403
2381
  * Represents a variable reference extracted from a Mustache template.
1404
2382
  * @public
@@ -1423,6 +2401,95 @@ declare interface IVariableRef {
1423
2401
  readonly isSection: boolean;
1424
2402
  }
1425
2403
 
2404
+ /**
2405
+ * Caller-supplied HKDF parameters that domain-separate one
2406
+ * {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes} call from another.
2407
+ * Two wraps that share recipient but differ on `salt` or `info` derive distinct
2408
+ * wrap keys, so callers should pick values that bind the wrap to its
2409
+ * application context (e.g. a content hash for `salt` and a secret name for
2410
+ * `info`).
2411
+ *
2412
+ * Both fields are required; pass an empty `Uint8Array` if the caller has no
2413
+ * value to bind on a given axis. Silent defaulting would hide protocol
2414
+ * mistakes, so the API does not pick defaults.
2415
+ * @public
2416
+ */
2417
+ declare interface IWrapBytesOptions {
2418
+ /**
2419
+ * HKDF salt. Domain-separates this wrap from others in different contexts.
2420
+ * Caller picks; common choices include a content hash, document id, channel
2421
+ * id, etc.
2422
+ */
2423
+ readonly salt: Uint8Array;
2424
+ /**
2425
+ * HKDF info. Further binds the derived key to a specific use within the
2426
+ * calling application. Caller picks; common choices include a secret name,
2427
+ * message type, or version tag.
2428
+ */
2429
+ readonly info: Uint8Array;
2430
+ }
2431
+
2432
+ /**
2433
+ * Output of {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes}. The
2434
+ * shape is JSON-serializable so it can travel directly over the wire or be
2435
+ * persisted as-is.
2436
+ * @public
2437
+ */
2438
+ declare interface IWrappedBytes {
2439
+ /**
2440
+ * Sender's ephemeral ECDH P-256 public key as a JSON Web Key. The matching
2441
+ * ephemeral private key is dropped after the shared-secret derive.
2442
+ */
2443
+ readonly ephemeralPublicKey: JsonWebKey;
2444
+ /**
2445
+ * AES-GCM nonce, base64-encoded. 12 bytes (96 bits) — the standard AES-GCM
2446
+ * nonce length.
2447
+ */
2448
+ readonly nonce: string;
2449
+ /**
2450
+ * AES-GCM ciphertext concatenated with the 16-byte authentication tag,
2451
+ * base64-encoded. Tampering with either the nonce or the ciphertext causes
2452
+ * unwrap to fail GCM authentication.
2453
+ */
2454
+ readonly ciphertext: string;
2455
+ }
2456
+
2457
+ /**
2458
+ * Options for YAML serialization, mirroring commonly-used `js-yaml` `DumpOptions`.
2459
+ * @public
2460
+ */
2461
+ declare interface IYamlSerializeOptions {
2462
+ /**
2463
+ * Indentation width in spaces (default: 2).
2464
+ */
2465
+ readonly indent?: number;
2466
+ /**
2467
+ * Nesting level at which to switch from block to flow style.
2468
+ * -1 means block style everywhere (default: -1).
2469
+ */
2470
+ readonly flowLevel?: number;
2471
+ /**
2472
+ * If true, sort keys when dumping (default: false).
2473
+ */
2474
+ readonly sortKeys?: boolean;
2475
+ /**
2476
+ * Maximum line width (default: 80).
2477
+ */
2478
+ readonly lineWidth?: number;
2479
+ /**
2480
+ * If true, don't convert duplicate objects into references (default: false).
2481
+ */
2482
+ readonly noRefs?: boolean;
2483
+ /**
2484
+ * If true, don't add an indentation level to array elements (default: false).
2485
+ */
2486
+ readonly noArrayIndent?: boolean;
2487
+ /**
2488
+ * If true, all non-key strings will be quoted (default: false).
2489
+ */
2490
+ readonly forceQuotes?: boolean;
2491
+ }
2492
+
1426
2493
  /**
1427
2494
  * Simple interface for a file to be added to a zip file.
1428
2495
  * @public
@@ -1452,6 +2519,24 @@ declare interface JarRecordParserOptions {
1452
2519
  readonly fixedContinuationSize?: number;
1453
2520
  }
1454
2521
 
2522
+ /**
2523
+ * In-place shape check for a JSON Web Key. Asserts only that the input is a
2524
+ * non-array object whose `kty` discriminator is a string; every other JWK
2525
+ * field passes through untouched. This is intentionally **not** a true JWK
2526
+ * validator — per-algorithm correctness (RSA `n`/`e`, EC `crv`/`x`/`y`,
2527
+ * key-size constraints, etc.) is delegated to `crypto.subtle.importKey` at
2528
+ * first use, which is the authoritative checker. The "shape" suffix in the
2529
+ * name is the warning sign for readers expecting full validation.
2530
+ * @remarks
2531
+ * Built with `Validators.object` (in-place, non-strict) so unknown JWK fields
2532
+ * survive the round-trip; the cast to `FieldValidators<JsonWebKey>` is required
2533
+ * only because TypeScript's mapped type demands an entry for every key in
2534
+ * `JsonWebKey`. At runtime the `ObjectValidator` only inspects keys present in
2535
+ * the field-validators map.
2536
+ * @public
2537
+ */
2538
+ declare const jsonWebKeyShape: Validator<JsonWebKey>;
2539
+
1455
2540
  /**
1456
2541
  * Supported key derivation functions.
1457
2542
  * @public
@@ -1470,18 +2555,58 @@ declare const keyDerivationFunction: Converter<KeyDerivationFunction>;
1470
2555
  */
1471
2556
  declare const keyDerivationParams: Converter<IKeyDerivationParams>;
1472
2557
 
2558
+ /**
2559
+ * Asymmetric keypair algorithms supported by the crypto provider.
2560
+ * - `'ecdsa-p256'`: ECDSA over the P-256 curve, for signing.
2561
+ * - `'rsa-oaep-2048'`: RSA-OAEP, 2048-bit modulus with SHA-256, for encryption.
2562
+ * - `'ecdh-p256'`: ECDH over the P-256 curve, for key agreement
2563
+ * (e.g. as the recipient keypair in
2564
+ * {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes} /
2565
+ * {@link CryptoUtils.ICryptoProvider.unwrapBytes | unwrapBytes}).
2566
+ * @public
2567
+ */
2568
+ declare type KeyPairAlgorithm = 'ecdsa-p256' | 'rsa-oaep-2048' | 'ecdh-p256';
2569
+
2570
+ /**
2571
+ * Converter for {@link CryptoUtils.KeyStore.KeyPairAlgorithm | key pair algorithm}.
2572
+ * @public
2573
+ */
2574
+ declare const keyPairAlgorithm: Converter<KeyPairAlgorithm>;
2575
+
2576
+ /**
2577
+ * Lookup table from {@link CryptoUtils.KeyPairAlgorithm} to the WebCrypto
2578
+ * parameters needed to drive `crypto.subtle`. Shared between every
2579
+ * {@link CryptoUtils.ICryptoProvider} implementation since both Node and
2580
+ * browser providers speak the same WebCrypto API. Exposed for downstream
2581
+ * provider implementations (e.g. browser-side providers in `@fgv/ts-web-extras`).
2582
+ * @public
2583
+ */
2584
+ declare const keyPairAlgorithmParams: Readonly<Record<KeyPairAlgorithm, IKeyPairAlgorithmParams>>;
2585
+
1473
2586
  declare namespace KeyStore {
1474
2587
  export {
1475
2588
  Converters_2 as Converters,
1476
2589
  KeyStore_2 as KeyStore,
1477
2590
  isKeyStoreFile,
2591
+ allKeyPairAlgorithms,
2592
+ KeyPairAlgorithm,
1478
2593
  KeyStoreFormat,
1479
2594
  KEYSTORE_FORMAT,
1480
2595
  DEFAULT_KEYSTORE_ITERATIONS,
1481
2596
  MIN_SALT_LENGTH,
2597
+ KeyStoreSymmetricSecretType,
2598
+ allKeyStoreSymmetricSecretTypes,
2599
+ KeyStoreAsymmetricSecretType,
2600
+ allKeyStoreAsymmetricSecretTypes,
1482
2601
  KeyStoreSecretType,
1483
2602
  allKeyStoreSecretTypes,
2603
+ IKeyStoreSymmetricEntry,
2604
+ IKeyStoreAsymmetricEntry,
2605
+ IKeyStoreEntry,
1484
2606
  IKeyStoreSecretEntry,
2607
+ IKeyStoreSymmetricEntryJson,
2608
+ IKeyStoreAsymmetricEntryJson,
2609
+ IKeyStoreEntryJson,
1485
2610
  IKeyStoreSecretEntryJson,
1486
2611
  IKeyStoreVaultContents,
1487
2612
  IKeyStoreFile,
@@ -1491,9 +2616,14 @@ declare namespace KeyStore {
1491
2616
  IAddSecretResult,
1492
2617
  IAddSecretOptions,
1493
2618
  IImportSecretOptions,
2619
+ IImportKeyOptions,
1494
2620
  IAddSecretFromPasswordOptions,
1495
2621
  DEFAULT_SECRET_ITERATIONS,
1496
- IAddSecretFromPasswordResult
2622
+ IAddSecretFromPasswordResult,
2623
+ IAddKeyPairOptions,
2624
+ IAddKeyPairResult,
2625
+ IRemoveSecretResult,
2626
+ IPrivateKeyStorage
1497
2627
  }
1498
2628
  }
1499
2629
 
@@ -1530,6 +2660,7 @@ declare namespace KeyStore {
1530
2660
  */
1531
2661
  declare class KeyStore_2 implements IEncryptionProvider {
1532
2662
  private readonly _cryptoProvider;
2663
+ private readonly _privateKeyStorage;
1533
2664
  private readonly _iterations;
1534
2665
  private _keystoreFile;
1535
2666
  private _salt;
@@ -1571,6 +2702,21 @@ declare class KeyStore_2 implements IEncryptionProvider {
1571
2702
  * @public
1572
2703
  */
1573
2704
  unlock(password: string): Promise<Result<KeyStore_2>>;
2705
+ /**
2706
+ * Unlocks an existing key store with a pre-derived key, bypassing
2707
+ * PBKDF2 key derivation. Use this when the derived key has been
2708
+ * stored externally (e.g., in another key store) and the original
2709
+ * password is no longer available.
2710
+ *
2711
+ * The supplied key must have been derived from the correct password
2712
+ * using the key store file's own PBKDF2 parameters (salt and
2713
+ * iteration count).
2714
+ *
2715
+ * @param derivedKey - The pre-derived master key (32 bytes for AES-256)
2716
+ * @returns Success with this instance when unlocked, Failure if key is incorrect
2717
+ * @public
2718
+ */
2719
+ unlockWithKey(derivedKey: Uint8Array): Promise<Result<KeyStore_2>>;
1574
2720
  /**
1575
2721
  * Locks the key store, clearing all secrets from memory.
1576
2722
  * @param force - If true, discards unsaved changes
@@ -1613,12 +2759,23 @@ declare class KeyStore_2 implements IEncryptionProvider {
1613
2759
  */
1614
2760
  listSecrets(): Result<readonly string[]>;
1615
2761
  /**
1616
- * Gets a secret by name.
2762
+ * Gets a secret by name. Returns the {@link CryptoUtils.KeyStore.IKeyStoreEntry | discriminated union}
2763
+ * — callers must check `entry.type` before accessing `key`/`id` since asymmetric
2764
+ * entries carry no raw key material.
1617
2765
  * @param name - Name of the secret
1618
2766
  * @returns Success with secret entry, Failure if not found or locked
1619
2767
  * @public
1620
2768
  */
1621
- getSecret(name: string): Result<IKeyStoreSecretEntry>;
2769
+ getSecret(name: string): Result<IKeyStoreEntry>;
2770
+ /**
2771
+ * Returns the public-key JWK for an asymmetric-keypair entry.
2772
+ * Available without {@link CryptoUtils.KeyStore.IPrivateKeyStorage} since the
2773
+ * public key lives in the vault metadata directly.
2774
+ * @param name - Name of the entry
2775
+ * @returns Success with the JWK, Failure if not found, locked, or wrong type
2776
+ * @public
2777
+ */
2778
+ getPublicKeyJwk(name: string): Result<JsonWebKey>;
1622
2779
  /**
1623
2780
  * Checks if a secret exists.
1624
2781
  * @param name - Name of the secret
@@ -1635,14 +2792,20 @@ declare class KeyStore_2 implements IEncryptionProvider {
1635
2792
  */
1636
2793
  addSecret(name: string, options?: IAddSecretOptions): Promise<Result<IAddSecretResult>>;
1637
2794
  /**
1638
- * Imports an existing secret key.
2795
+ * Imports raw 32-byte key material into the vault.
2796
+ *
2797
+ * Always validates that the key is exactly 32 bytes (AES-256). The optional
2798
+ * `type` field is a classification label stored with the entry; it does not
2799
+ * change the validation rules. For importing UTF-8 API key strings (variable
2800
+ * length), use {@link KeyStore.importApiKey} instead.
2801
+ *
1639
2802
  * @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
2803
+ * @param key - The 32-byte AES-256 key material
2804
+ * @param options - Optional type classification, description, whether to replace existing
1642
2805
  * @returns Success with entry, Failure if locked, key invalid, or exists and !replace
1643
2806
  * @public
1644
2807
  */
1645
- importSecret(name: string, key: Uint8Array, options?: IImportSecretOptions): Result<IAddSecretResult>;
2808
+ importSecret(name: string, key: Uint8Array, options?: IImportKeyOptions): Promise<Result<IAddSecretResult>>;
1646
2809
  /**
1647
2810
  * Adds a secret derived from a password using PBKDF2.
1648
2811
  *
@@ -1659,12 +2822,16 @@ declare class KeyStore_2 implements IEncryptionProvider {
1659
2822
  */
1660
2823
  addSecretFromPassword(name: string, password: string, options?: IAddSecretFromPasswordOptions): Promise<Result<IAddSecretFromPasswordResult>>;
1661
2824
  /**
1662
- * Removes a secret by name.
2825
+ * Removes a secret by name. Vault-first: the in-memory vault entry is dropped
2826
+ * before any storage cleanup runs. For asymmetric-keypair entries, best-effort
2827
+ * calls {@link CryptoUtils.KeyStore.IPrivateKeyStorage}.delete on the entry's
2828
+ * `id`; a failure is reported via `warning` on the result but does not roll
2829
+ * back the vault removal.
1663
2830
  * @param name - Name of the secret to remove
1664
- * @returns Success with removed entry, Failure if not found or locked
2831
+ * @returns Success with removed entry (and optional warning), Failure if not found or locked
1665
2832
  * @public
1666
2833
  */
1667
- removeSecret(name: string): Result<IKeyStoreSecretEntry>;
2834
+ removeSecret(name: string): Promise<Result<IRemoveSecretResult>>;
1668
2835
  /**
1669
2836
  * Imports an API key string into the vault.
1670
2837
  * The string is UTF-8 encoded and stored with type `'api-key'`.
@@ -1674,7 +2841,7 @@ declare class KeyStore_2 implements IEncryptionProvider {
1674
2841
  * @returns Success with entry, Failure if locked, empty, or exists and !replace
1675
2842
  * @public
1676
2843
  */
1677
- importApiKey(name: string, apiKey: string, options?: IImportSecretOptions): Result<IAddSecretResult>;
2844
+ importApiKey(name: string, apiKey: string, options?: IImportSecretOptions): Promise<Result<IAddSecretResult>>;
1678
2845
  /**
1679
2846
  * Retrieves an API key string by name.
1680
2847
  * Only works for secrets with type `'api-key'`.
@@ -1683,6 +2850,41 @@ declare class KeyStore_2 implements IEncryptionProvider {
1683
2850
  * @public
1684
2851
  */
1685
2852
  getApiKey(name: string): Result<string>;
2853
+ /**
2854
+ * Adds a new asymmetric keypair to the vault. Storage-first: the private key
2855
+ * is stored under a freshly-minted `id` before the public-key vault entry is
2856
+ * committed. If the storage call fails, no vault entry is written and the
2857
+ * operation returns Failure.
2858
+ *
2859
+ * When `replace: true` displaces an existing entry (asymmetric or symmetric),
2860
+ * a fresh `id` is minted; the displaced entry's resources are released
2861
+ * best-effort. Failure of the storage delete is reported via `warning` on the
2862
+ * result but does not roll back the replacement.
2863
+ *
2864
+ * Requires a {@link CryptoUtils.KeyStore.IPrivateKeyStorage} backend
2865
+ * supplied at construction.
2866
+ *
2867
+ * @param name - Unique name for the entry
2868
+ * @param options - Algorithm, optional description, replace flag
2869
+ * @returns Success with the new entry, Failure if locked, no provider, or storage write failed
2870
+ * @public
2871
+ */
2872
+ addKeyPair(name: string, options: IAddKeyPairOptions): Promise<Result<IAddKeyPairResult>>;
2873
+ /**
2874
+ * Retrieves the keypair for an asymmetric-keypair entry. The private key is
2875
+ * loaded from {@link CryptoUtils.KeyStore.IPrivateKeyStorage} on every call —
2876
+ * the keystore never caches private `CryptoKey` references between calls.
2877
+ * The public key is re-imported from the vault's JWK so callers always
2878
+ * receive a `CryptoKey` rather than the JWK form.
2879
+ * @param name - Name of the entry
2880
+ * @returns Success with `{ publicKey, privateKey }`, Failure if not found,
2881
+ * locked, wrong type, no provider, or storage load failed.
2882
+ * @public
2883
+ */
2884
+ getKeyPair(name: string): Promise<Result<{
2885
+ publicKey: CryptoKey;
2886
+ privateKey: CryptoKey;
2887
+ }>>;
1686
2888
  /**
1687
2889
  * Lists secret names filtered by type.
1688
2890
  * @param type - The secret type to filter by
@@ -1697,7 +2899,7 @@ declare class KeyStore_2 implements IEncryptionProvider {
1697
2899
  * @returns Success with updated entry, Failure if source not found, target exists, or locked
1698
2900
  * @public
1699
2901
  */
1700
- renameSecret(oldName: string, newName: string): Result<IKeyStoreSecretEntry>;
2902
+ renameSecret(oldName: string, newName: string): Result<IKeyStoreEntry>;
1701
2903
  /**
1702
2904
  * Saves the key store, returning the encrypted file content.
1703
2905
  * Requires the master password to encrypt.
@@ -1706,6 +2908,20 @@ declare class KeyStore_2 implements IEncryptionProvider {
1706
2908
  * @public
1707
2909
  */
1708
2910
  save(password: string): Promise<Result<IKeyStoreFile>>;
2911
+ /**
2912
+ * Saves the key store using a pre-derived key, bypassing PBKDF2 key
2913
+ * derivation. Use this when the derived key has been stored externally
2914
+ * (e.g., in another key store) and the original password is no longer
2915
+ * available.
2916
+ *
2917
+ * The supplied key must be the same key that was (or would be) derived
2918
+ * from the master password using the key store's PBKDF2 parameters.
2919
+ *
2920
+ * @param derivedKey - The pre-derived master key (32 bytes for AES-256)
2921
+ * @returns Success with IKeyStoreFile, Failure if locked or key invalid
2922
+ * @public
2923
+ */
2924
+ saveWithKey(derivedKey: Uint8Array): Promise<Result<IKeyStoreFile>>;
1709
2925
  /**
1710
2926
  * Changes the master password.
1711
2927
  * Re-encrypts the vault with the new password-derived key.
@@ -1730,6 +2946,33 @@ declare class KeyStore_2 implements IEncryptionProvider {
1730
2946
  * @public
1731
2947
  */
1732
2948
  getEncryptionConfig(): Result<Pick<IEncryptionConfig, 'secretProvider' | 'cryptoProvider'>>;
2949
+ /**
2950
+ * Encrypts the vault with a derived key and returns the key store file.
2951
+ * Shared by `save()` and `saveWithKey()`.
2952
+ */
2953
+ private _encryptVault;
2954
+ /**
2955
+ * Decrypts the vault with a derived key and loads secrets into memory.
2956
+ * Shared by `unlock()` and `unlockWithKey()`.
2957
+ */
2958
+ private _decryptVault;
2959
+ /**
2960
+ * Releases the resources held by an entry being displaced from the vault.
2961
+ * Symmetric entries get their key buffer zeroed in place. Asymmetric entries
2962
+ * have their private-key blob best-effort deleted from
2963
+ * {@link CryptoUtils.KeyStore.IPrivateKeyStorage}; if the storage call fails,
2964
+ * a warning string is returned but the displacement still proceeds — the
2965
+ * orphaned blob is left for consumer-side GC. Without a configured provider,
2966
+ * asymmetric cleanup is silently skipped.
2967
+ * @returns A warning string if storage cleanup failed, otherwise undefined.
2968
+ */
2969
+ private _releaseEntryResources;
2970
+ /**
2971
+ * Mints a fresh UUID v4 storage handle using the crypto provider's
2972
+ * {@link CryptoUtils.ICryptoProvider.generateRandomBytes | generateRandomBytes}.
2973
+ * Random-bytes failures propagate as Failure.
2974
+ */
2975
+ private _generateId;
1733
2976
  }
1734
2977
 
1735
2978
  /**
@@ -1738,6 +2981,31 @@ declare class KeyStore_2 implements IEncryptionProvider {
1738
2981
  */
1739
2982
  declare const KEYSTORE_FORMAT: KeyStoreFormat;
1740
2983
 
2984
+ /**
2985
+ * Converter for {@link CryptoUtils.KeyStore.IKeyStoreAsymmetricEntryJson | asymmetric keypair entry} in JSON form.
2986
+ * The `publicKeyJwk` field passes through {@link CryptoUtils.KeyStore.Converters.jsonWebKeyShape | jsonWebKeyShape}
2987
+ * (shape check only — see its docs); cryptographic correctness is enforced by
2988
+ * `crypto.subtle.importKey` at use.
2989
+ * @public
2990
+ */
2991
+ declare const keystoreAsymmetricEntryJson: Converter<IKeyStoreAsymmetricEntryJson>;
2992
+
2993
+ /**
2994
+ * Discriminator for asymmetric secret types stored in the vault.
2995
+ * - `'asymmetric-keypair'`: A public/private key pair. The public key is held in
2996
+ * the vault as a JWK; the private key lives in the supplied
2997
+ * {@link CryptoUtils.KeyStore.IPrivateKeyStorage} provider.
2998
+ * @public
2999
+ */
3000
+ declare type KeyStoreAsymmetricSecretType = 'asymmetric-keypair';
3001
+
3002
+ /**
3003
+ * Converter for {@link CryptoUtils.KeyStore.KeyStoreAsymmetricSecretType | asymmetric secret type} discriminator.
3004
+ * Accepts only `'asymmetric-keypair'`.
3005
+ * @public
3006
+ */
3007
+ declare const keystoreAsymmetricSecretType: Converter<KeyStoreAsymmetricSecretType>;
3008
+
1741
3009
  /**
1742
3010
  * Converter for {@link CryptoUtils.KeyStore.IKeyStoreFile | encrypted key store file}.
1743
3011
  * @public
@@ -1763,25 +3031,59 @@ declare const keystoreFormat: Converter<KeyStoreFormat>;
1763
3031
  declare type KeyStoreLockState = 'locked' | 'unlocked';
1764
3032
 
1765
3033
  /**
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'`.
3034
+ * Discriminated-union converter for any {@link CryptoUtils.KeyStore.IKeyStoreEntryJson | key store entry} in JSON form.
3035
+ * Routes by the `type` field: `'asymmetric-keypair'` is parsed by
3036
+ * {@link CryptoUtils.KeyStore.Converters.keystoreAsymmetricEntryJson | keystoreAsymmetricEntryJson},
3037
+ * anything else (including a missing `type` field for backwards compatibility) by
3038
+ * {@link CryptoUtils.KeyStore.Converters.keystoreSymmetricEntryJson | keystoreSymmetricEntryJson}.
3039
+ * @public
3040
+ */
3041
+ declare const keystoreSecretEntryJson: Converter<IKeyStoreEntryJson>;
3042
+
3043
+ /**
3044
+ * Discriminator for any secret type stored in the vault.
3045
+ * @public
3046
+ */
3047
+ declare type KeyStoreSecretType = KeyStoreSymmetricSecretType | KeyStoreAsymmetricSecretType;
3048
+
3049
+ /**
3050
+ * Converter for {@link CryptoUtils.KeyStore.KeyStoreSecretType | any key store secret type} discriminator.
3051
+ * Accepts both symmetric and asymmetric type values.
3052
+ * @public
3053
+ */
3054
+ declare const keystoreSecretType: Converter<KeyStoreSecretType>;
3055
+
3056
+ /**
3057
+ * Converter for {@link CryptoUtils.KeyStore.IKeyStoreSymmetricEntryJson | symmetric secret entry} in JSON form.
3058
+ *
3059
+ * @remarks
3060
+ * Backwards compatibility with vaults written before asymmetric-keypair
3061
+ * support: those entries may lack the `type` discriminator on the wire. To
3062
+ * keep the model type honest (`type` is required on
3063
+ * {@link CryptoUtils.KeyStore.IKeyStoreSymmetricEntryJson}, see its docs),
3064
+ * we declare `type` in `optionalFields` so the inner `Converters.object` will
3065
+ * accept input without it, then `.map()` injects the default
3066
+ * `'encryption-key'` when missing. The output therefore always carries the
3067
+ * discriminator and downstream code never sees the legacy missing-type form.
3068
+ *
1768
3069
  * @public
1769
3070
  */
1770
- declare const keystoreSecretEntryJson: Converter<IKeyStoreSecretEntryJson>;
3071
+ declare const keystoreSymmetricEntryJson: Converter<IKeyStoreSymmetricEntryJson>;
1771
3072
 
1772
3073
  /**
1773
- * Discriminator for secret types stored in the vault.
3074
+ * Discriminator for symmetric secret types stored in the vault.
1774
3075
  * - `'encryption-key'`: A 32-byte AES-256 encryption key.
1775
3076
  * - `'api-key'`: An arbitrary-length API key string (UTF-8 encoded).
1776
3077
  * @public
1777
3078
  */
1778
- declare type KeyStoreSecretType = 'encryption-key' | 'api-key';
3079
+ declare type KeyStoreSymmetricSecretType = 'encryption-key' | 'api-key';
1779
3080
 
1780
3081
  /**
1781
- * Converter for {@link CryptoUtils.KeyStore.KeyStoreSecretType | key store secret type} discriminator.
3082
+ * Converter for {@link CryptoUtils.KeyStore.KeyStoreSymmetricSecretType | symmetric secret type} discriminator.
3083
+ * Accepts only `'encryption-key'` and `'api-key'`.
1782
3084
  * @public
1783
3085
  */
1784
- declare const keystoreSecretType: Converter<KeyStoreSecretType>;
3086
+ declare const keystoreSymmetricSecretType: Converter<KeyStoreSymmetricSecretType>;
1785
3087
 
1786
3088
  /**
1787
3089
  * Converter for {@link CryptoUtils.KeyStore.IKeyStoreVaultContents | key store vault contents} (decrypted state).
@@ -1971,6 +3273,12 @@ declare class NodeCryptoProvider implements ICryptoProvider {
1971
3273
  * @returns `Success` with derived 32-byte key, or `Failure` with an error.
1972
3274
  */
1973
3275
  deriveKey(password: string, salt: Uint8Array, iterations: number): Promise<Result<Uint8Array>>;
3276
+ /**
3277
+ * Computes a SHA-256 hash of the given data.
3278
+ * @param data - UTF-8 string to hash
3279
+ * @returns `Success` with hex-encoded hash string, or `Failure` with an error.
3280
+ */
3281
+ sha256(data: string): Promise<Result<string>>;
1974
3282
  /**
1975
3283
  * Generates cryptographically secure random bytes.
1976
3284
  * @param length - Number of bytes to generate
@@ -1989,6 +3297,50 @@ declare class NodeCryptoProvider implements ICryptoProvider {
1989
3297
  * @returns Success with decoded bytes, or Failure if invalid base64
1990
3298
  */
1991
3299
  fromBase64(base64: string): Result<Uint8Array>;
3300
+ /**
3301
+ * Generates a new asymmetric keypair using Node's WebCrypto.
3302
+ * @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} to use.
3303
+ * @param extractable - Whether the resulting keys may be exported.
3304
+ * @returns `Success` with the generated `CryptoKeyPair`, or `Failure` with an error.
3305
+ */
3306
+ generateKeyPair(algorithm: KeyPairAlgorithm, extractable: boolean): Promise<Result<CryptoKeyPair>>;
3307
+ /**
3308
+ * Exports a public `CryptoKey` as a JSON Web Key.
3309
+ * @remarks
3310
+ * Rejects non-public keys at runtime. WebCrypto's `exportKey('jwk', ...)`
3311
+ * does not enforce public-vs-private; without this guard a caller that
3312
+ * passed an extractable private key would receive its private fields
3313
+ * (`d`, `p`, `q`, ...) as JWK, defeating the method's name.
3314
+ * @param publicKey - Extractable public key to export.
3315
+ * @returns `Success` with the JWK, or `Failure` if not a public key or if export fails.
3316
+ */
3317
+ exportPublicKeyJwk(publicKey: CryptoKey): Promise<Result<JsonWebKey>>;
3318
+ /**
3319
+ * Imports a public-key JWK as a `CryptoKey` for the requested algorithm.
3320
+ * @param jwk - The JSON Web Key produced by a prior export.
3321
+ * @param algorithm - The algorithm the key was generated for.
3322
+ * @returns `Success` with the imported public `CryptoKey`, or `Failure` with an error.
3323
+ */
3324
+ importPublicKeyJwk(jwk: JsonWebKey, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;
3325
+ /**
3326
+ * Wraps `plaintext` for the holder of `recipientPublicKey` using
3327
+ * ECIES (ECDH P-256 + HKDF-SHA256 + AES-GCM-256). See
3328
+ * {@link CryptoUtils.ICryptoProvider.wrapBytes | ICryptoProvider.wrapBytes}.
3329
+ * @param plaintext - The bytes to wrap.
3330
+ * @param recipientPublicKey - The recipient's ECDH P-256 public `CryptoKey`.
3331
+ * @param options - HKDF salt and info; see {@link CryptoUtils.IWrapBytesOptions | IWrapBytesOptions}.
3332
+ * @returns `Success` with the wrapped payload, or `Failure` with an error.
3333
+ */
3334
+ wrapBytes(plaintext: Uint8Array, recipientPublicKey: CryptoKey, options: IWrapBytesOptions): Promise<Result<IWrappedBytes>>;
3335
+ /**
3336
+ * Unwraps a payload produced by `wrapBytes` using the recipient's private
3337
+ * key. See {@link CryptoUtils.ICryptoProvider.unwrapBytes | ICryptoProvider.unwrapBytes}.
3338
+ * @param wrapped - The wrapped payload.
3339
+ * @param recipientPrivateKey - The recipient's ECDH P-256 private `CryptoKey`.
3340
+ * @param options - HKDF salt and info matching the wrap call.
3341
+ * @returns `Success` with the original `plaintext`, or `Failure` with an error.
3342
+ */
3343
+ unwrapBytes(wrapped: IWrappedBytes, recipientPrivateKey: CryptoKey, options: IWrapBytesOptions): Promise<Result<Uint8Array>>;
1992
3344
  }
1993
3345
 
1994
3346
  /**
@@ -2218,6 +3570,22 @@ export { RecordJar }
2218
3570
  */
2219
3571
  declare function resolveEffectiveTools(descriptor: IAiProviderDescriptor, settingsTools?: ReadonlyArray<IAiToolEnablement>, perCallTools?: ReadonlyArray<AiServerToolConfig>): ReadonlyArray<AiServerToolConfig>;
2220
3572
 
3573
+ /**
3574
+ * Resolve the image-generation capability that applies to a given model id
3575
+ * for a provider. Returns the entry from
3576
+ * {@link IAiProviderDescriptor.imageGeneration} whose `modelPrefix` is the
3577
+ * longest prefix of `modelId`. Ties are broken by first-encountered, so rule
3578
+ * order does not matter for correctness — only for tie-breaking among rules
3579
+ * with identical-length prefixes (an unusual case).
3580
+ *
3581
+ * @param descriptor - The provider descriptor
3582
+ * @param modelId - The resolved image model id
3583
+ * @returns The matching capability, or `undefined` when no rule matches or
3584
+ * the provider declares no image-generation capabilities.
3585
+ * @public
3586
+ */
3587
+ declare function resolveImageCapability(descriptor: IAiProviderDescriptor, modelId: string): IAiImageModelCapability | undefined;
3588
+
2221
3589
  /**
2222
3590
  * Resolves a {@link ModelSpec} to a concrete model string given an optional context key.
2223
3591
  *
@@ -2241,6 +3609,16 @@ declare function resolveModel(spec: ModelSpec, context?: string): string;
2241
3609
  */
2242
3610
  declare type SecretProvider = (secretName: string) => Promise<Result<Uint8Array>>;
2243
3611
 
3612
+ /**
3613
+ * Whether a provider declares any image-generation capability at all.
3614
+ *
3615
+ * @param descriptor - The provider descriptor
3616
+ * @returns `true` when {@link IAiProviderDescriptor.imageGeneration} has at
3617
+ * least one entry; `false` otherwise.
3618
+ * @public
3619
+ */
3620
+ declare function supportsImageGeneration(descriptor: IAiProviderDescriptor): boolean;
3621
+
2244
3622
  /**
2245
3623
  * Helper function to create a `StringConverter` which converts
2246
3624
  * `unknown` to `string`, applying template conversions supplied at construction time or at
@@ -2261,6 +3639,14 @@ declare function templateString(defaultContext?: unknown): Conversion.StringConv
2261
3639
  */
2262
3640
  declare function toBase64(bytes: Uint8Array): string;
2263
3641
 
3642
+ /**
3643
+ * Formats an {@link IAiImageData} as a `data:` URL suitable for browser display.
3644
+ * @param image - The image to format
3645
+ * @returns A `data:<mime>;base64,<data>` URL string
3646
+ * @public
3647
+ */
3648
+ declare function toDataUrl(image: IAiImageData): string;
3649
+
2264
3650
  /**
2265
3651
  * Attempts to parse and decrypt a JSON object as an {@link CryptoUtils.IEncryptedFile | encrypted file}.
2266
3652
  * @typeParam TPayload - Expected type of decrypted content
@@ -2283,7 +3669,9 @@ declare const uint8ArrayFromBase64: Converter<Uint8Array>;
2283
3669
 
2284
3670
  declare namespace Yaml {
2285
3671
  export {
2286
- yamlConverter
3672
+ yamlConverter,
3673
+ yamlStringify,
3674
+ IYamlSerializeOptions
2287
3675
  }
2288
3676
  }
2289
3677
  export { Yaml }
@@ -2296,6 +3684,15 @@ export { Yaml }
2296
3684
  */
2297
3685
  declare function yamlConverter<T>(converter: Converter<T>): Converter<T>;
2298
3686
 
3687
+ /**
3688
+ * Serializes a value to a YAML string.
3689
+ * @param value - The value to serialize (must be an object or array)
3690
+ * @param options - Optional serialization options
3691
+ * @returns `Success` with YAML string, or `Failure` with error
3692
+ * @public
3693
+ */
3694
+ declare function yamlStringify(value: unknown, options?: IYamlSerializeOptions): Result<string>;
3695
+
2299
3696
  /**
2300
3697
  * Supported compression levels for zip files.
2301
3698
  * @public
@@ -2449,8 +3846,8 @@ declare class ZipFileTreeAccessors<TCT extends string = string> implements FileT
2449
3846
  private constructor();
2450
3847
  /**
2451
3848
  * 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.
3849
+ * @param __filePath - The path of the file.
3850
+ * @param __provided - Optional supplied content type.
2454
3851
  * @returns `Success` with the content type of the file if successful, or
2455
3852
  * `Failure` with an error message otherwise.
2456
3853
  * @remarks This default implementation always returns `Success` with `undefined`.