@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
@@ -4,20 +4,31 @@
4
4
  * @packageDocumentation
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.resolveEffectiveTools = exports.modelSpec = exports.modelSpecKey = exports.aiAssistSettings = exports.aiAssistProviderConfig = exports.aiToolEnablement = exports.aiServerToolConfig = exports.aiWebSearchToolConfig = exports.aiServerToolType = exports.aiProviderId = exports.callProxiedCompletion = exports.callProviderCompletion = exports.getProviderDescriptor = exports.getProviderDescriptors = exports.allProviderIds = exports.resolveModel = exports.MODEL_SPEC_BASE_KEY = exports.allModelSpecKeys = exports.DEFAULT_AI_ASSIST = exports.AiPrompt = void 0;
7
+ exports.resolveEffectiveTools = exports.modelSpec = exports.modelSpecKey = exports.aiAssistSettings = exports.aiAssistProviderConfig = exports.aiToolEnablement = exports.aiServerToolConfig = exports.aiWebSearchToolConfig = exports.aiServerToolType = exports.aiProviderId = exports.callProxiedCompletionStream = exports.callProviderCompletionStream = exports.callProxiedListModels = exports.callProviderListModels = exports.callProxiedImageGeneration = exports.callProviderImageGeneration = exports.callProxiedCompletion = exports.callProviderCompletion = exports.DEFAULT_MODEL_CAPABILITY_CONFIG = exports.supportsImageGeneration = exports.resolveImageCapability = exports.getProviderDescriptor = exports.getProviderDescriptors = exports.allProviderIds = exports.toDataUrl = exports.resolveModel = exports.MODEL_SPEC_BASE_KEY = exports.allModelSpecKeys = exports.DEFAULT_AI_ASSIST = exports.AiPrompt = void 0;
8
8
  var model_1 = require("./model");
9
9
  Object.defineProperty(exports, "AiPrompt", { enumerable: true, get: function () { return model_1.AiPrompt; } });
10
10
  Object.defineProperty(exports, "DEFAULT_AI_ASSIST", { enumerable: true, get: function () { return model_1.DEFAULT_AI_ASSIST; } });
11
11
  Object.defineProperty(exports, "allModelSpecKeys", { enumerable: true, get: function () { return model_1.allModelSpecKeys; } });
12
12
  Object.defineProperty(exports, "MODEL_SPEC_BASE_KEY", { enumerable: true, get: function () { return model_1.MODEL_SPEC_BASE_KEY; } });
13
13
  Object.defineProperty(exports, "resolveModel", { enumerable: true, get: function () { return model_1.resolveModel; } });
14
+ Object.defineProperty(exports, "toDataUrl", { enumerable: true, get: function () { return model_1.toDataUrl; } });
14
15
  var registry_1 = require("./registry");
15
16
  Object.defineProperty(exports, "allProviderIds", { enumerable: true, get: function () { return registry_1.allProviderIds; } });
16
17
  Object.defineProperty(exports, "getProviderDescriptors", { enumerable: true, get: function () { return registry_1.getProviderDescriptors; } });
17
18
  Object.defineProperty(exports, "getProviderDescriptor", { enumerable: true, get: function () { return registry_1.getProviderDescriptor; } });
19
+ Object.defineProperty(exports, "resolveImageCapability", { enumerable: true, get: function () { return registry_1.resolveImageCapability; } });
20
+ Object.defineProperty(exports, "supportsImageGeneration", { enumerable: true, get: function () { return registry_1.supportsImageGeneration; } });
21
+ Object.defineProperty(exports, "DEFAULT_MODEL_CAPABILITY_CONFIG", { enumerable: true, get: function () { return registry_1.DEFAULT_MODEL_CAPABILITY_CONFIG; } });
18
22
  var apiClient_1 = require("./apiClient");
19
23
  Object.defineProperty(exports, "callProviderCompletion", { enumerable: true, get: function () { return apiClient_1.callProviderCompletion; } });
20
24
  Object.defineProperty(exports, "callProxiedCompletion", { enumerable: true, get: function () { return apiClient_1.callProxiedCompletion; } });
25
+ Object.defineProperty(exports, "callProviderImageGeneration", { enumerable: true, get: function () { return apiClient_1.callProviderImageGeneration; } });
26
+ Object.defineProperty(exports, "callProxiedImageGeneration", { enumerable: true, get: function () { return apiClient_1.callProxiedImageGeneration; } });
27
+ Object.defineProperty(exports, "callProviderListModels", { enumerable: true, get: function () { return apiClient_1.callProviderListModels; } });
28
+ Object.defineProperty(exports, "callProxiedListModels", { enumerable: true, get: function () { return apiClient_1.callProxiedListModels; } });
29
+ var streamingClient_1 = require("./streamingClient");
30
+ Object.defineProperty(exports, "callProviderCompletionStream", { enumerable: true, get: function () { return streamingClient_1.callProviderCompletionStream; } });
31
+ Object.defineProperty(exports, "callProxiedCompletionStream", { enumerable: true, get: function () { return streamingClient_1.callProxiedCompletionStream; } });
21
32
  var converters_1 = require("./converters");
22
33
  Object.defineProperty(exports, "aiProviderId", { enumerable: true, get: function () { return converters_1.aiProviderId; } });
23
34
  Object.defineProperty(exports, "aiServerToolType", { enumerable: true, get: function () { return converters_1.aiServerToolType; } });
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/packlets/ai-assist/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,iCAuCiB;AAtCf,iGAAA,QAAQ,OAAA;AAeR,0GAAA,iBAAiB,OAAA;AAmBjB,yGAAA,gBAAgB,OAAA;AAChB,4GAAA,mBAAmB,OAAA;AACnB,qGAAA,YAAY,OAAA;AACZ,kGAAA,SAAS,OAAA;AAGX,uCAOoB;AANlB,0GAAA,cAAc,OAAA;AACd,kHAAA,sBAAsB,OAAA;AACtB,iHAAA,qBAAqB,OAAA;AACrB,kHAAA,sBAAsB,OAAA;AACtB,mHAAA,uBAAuB,OAAA;AACvB,2HAAA,+BAA+B,OAAA;AAGjC,yCAUqB;AATnB,mHAAA,sBAAsB,OAAA;AACtB,kHAAA,qBAAqB,OAAA;AACrB,wHAAA,2BAA2B,OAAA;AAC3B,uHAAA,0BAA0B,OAAA;AAC1B,mHAAA,sBAAsB,OAAA;AACtB,kHAAA,qBAAqB,OAAA;AAMvB,qDAI2B;AAHzB,+HAAA,4BAA4B,OAAA;AAC5B,8HAAA,2BAA2B,OAAA;AAI7B,2CAUsB;AATpB,0GAAA,YAAY,OAAA;AACZ,8GAAA,gBAAgB,OAAA;AAChB,mHAAA,qBAAqB,OAAA;AACrB,gHAAA,kBAAkB,OAAA;AAClB,8GAAA,gBAAgB,OAAA;AAChB,oHAAA,sBAAsB,OAAA;AACtB,8GAAA,gBAAgB,OAAA;AAChB,0GAAA,YAAY,OAAA;AACZ,uGAAA,SAAS,OAAA;AAGX,6CAAsD;AAA7C,oHAAA,qBAAqB,OAAA","sourcesContent":["/**\n * AI assist packlet - provider registry, prompt class, settings, and API client.\n * @packageDocumentation\n */\n\nexport {\n AiPrompt,\n type AiModelCapability,\n type AiProviderId,\n type AiServerToolType,\n type AiServerToolConfig,\n type IAiWebSearchToolConfig,\n type IAiToolEnablement,\n type IAiCompletionResponse,\n type IChatMessage,\n type AiApiFormat,\n type AiImageApiFormat,\n type IAiImageModelCapability,\n type IAiProviderDescriptor,\n type IAiAssistProviderConfig,\n type IAiAssistSettings,\n DEFAULT_AI_ASSIST,\n type IAiAssistKeyStore,\n type IAiImageAttachment,\n type IAiImageData,\n type IAiImageGenerationOptions,\n type IAiImageGenerationParams,\n type IAiGeneratedImage,\n type IAiImageGenerationResponse,\n type IAiModelCapabilityRule,\n type IAiModelCapabilityConfig,\n type IAiModelInfo,\n type IAiStreamEvent,\n type IAiStreamTextDelta,\n type IAiStreamToolEvent,\n type IAiStreamDone,\n type IAiStreamError,\n type ModelSpec,\n type ModelSpecKey,\n type IModelSpecMap,\n allModelSpecKeys,\n MODEL_SPEC_BASE_KEY,\n resolveModel,\n toDataUrl\n} from './model';\n\nexport {\n allProviderIds,\n getProviderDescriptors,\n getProviderDescriptor,\n resolveImageCapability,\n supportsImageGeneration,\n DEFAULT_MODEL_CAPABILITY_CONFIG\n} from './registry';\n\nexport {\n callProviderCompletion,\n callProxiedCompletion,\n callProviderImageGeneration,\n callProxiedImageGeneration,\n callProviderListModels,\n callProxiedListModels,\n type IProviderCompletionParams,\n type IProviderImageGenerationParams,\n type IProviderListModelsParams\n} from './apiClient';\n\nexport {\n callProviderCompletionStream,\n callProxiedCompletionStream,\n type IProviderCompletionStreamParams\n} from './streamingClient';\n\nexport {\n aiProviderId,\n aiServerToolType,\n aiWebSearchToolConfig,\n aiServerToolConfig,\n aiToolEnablement,\n aiAssistProviderConfig,\n aiAssistSettings,\n modelSpecKey,\n modelSpec\n} from './converters';\n\nexport { resolveEffectiveTools } from './toolFormats';\n"]}
@@ -3,6 +3,49 @@
3
3
  * @packageDocumentation
4
4
  */
5
5
  import { type Result } from '@fgv/ts-utils';
6
+ /**
7
+ * Universal image representation used for both image input (vision prompts)
8
+ * and image output (generation responses).
9
+ *
10
+ * @remarks
11
+ * The base64 string is raw — no `data:` URL prefix. Use {@link AiAssist.toDataUrl} to
12
+ * format it for browser-display contexts.
13
+ *
14
+ * @public
15
+ */
16
+ export interface IAiImageData {
17
+ /** MIME type, e.g. `'image/png'`, `'image/jpeg'`, `'image/webp'`. */
18
+ readonly mimeType: string;
19
+ /** Base64-encoded image bytes (no `data:` prefix). */
20
+ readonly base64: string;
21
+ }
22
+ /**
23
+ * Formats an {@link IAiImageData} as a `data:` URL suitable for browser display.
24
+ * @param image - The image to format
25
+ * @returns A `data:<mime>;base64,<data>` URL string
26
+ * @public
27
+ */
28
+ export declare function toDataUrl(image: IAiImageData): string;
29
+ /**
30
+ * Image attachment for a vision (image-input) prompt.
31
+ *
32
+ * @remarks
33
+ * Extends {@link IAiImageData} with an OpenAI-specific `detail` hint that is
34
+ * silently ignored by Anthropic, Gemini, and other providers.
35
+ *
36
+ * @public
37
+ */
38
+ export interface IAiImageAttachment extends IAiImageData {
39
+ /**
40
+ * OpenAI vision detail hint:
41
+ * - `'low'`: faster, cheaper, lower fidelity
42
+ * - `'high'`: slower, more expensive, higher fidelity
43
+ * - `'auto'` (default): provider chooses
44
+ *
45
+ * Ignored by providers other than OpenAI.
46
+ */
47
+ readonly detail?: 'low' | 'high' | 'auto';
48
+ }
6
49
  /**
7
50
  * A structured AI prompt with system/user split for direct API calls,
8
51
  * and a lazily-constructed combined version for copy/paste workflows.
@@ -13,8 +56,18 @@ export declare class AiPrompt {
13
56
  readonly system: string;
14
57
  /** User request: the specific entity generation request. */
15
58
  readonly user: string;
16
- constructor(user: string, system: string);
17
- /** Combined single-string version (user + system joined) for copy/paste. */
59
+ /**
60
+ * Optional image attachments. When present, vision-capable providers will
61
+ * include them in the user message; non-vision providers will reject the
62
+ * call up front (see {@link AiAssist.IAiProviderDescriptor.acceptsImageInput}).
63
+ */
64
+ readonly attachments: ReadonlyArray<IAiImageAttachment>;
65
+ constructor(user: string, system: string, attachments?: ReadonlyArray<IAiImageAttachment>);
66
+ /**
67
+ * Combined single-string version (user + system joined) for copy/paste.
68
+ * When attachments are present, includes a sentinel noting they aren't
69
+ * part of the copied text.
70
+ */
18
71
  get combined(): string;
19
72
  }
20
73
  /**
@@ -139,6 +192,22 @@ export type AiProviderId = 'copy-paste' | 'xai-grok' | 'openai' | 'anthropic' |
139
192
  * @public
140
193
  */
141
194
  export type AiApiFormat = 'openai' | 'anthropic' | 'gemini';
195
+ /**
196
+ * API format categories for image-generation provider routing.
197
+ *
198
+ * @remarks
199
+ * - `'openai-images'` — OpenAI Images API. Routes to `/images/generations`
200
+ * (text-only) or `/images/edits` (when reference images are present).
201
+ * - `'xai-images'` — xAI Images API. Same wire shape as OpenAI but text-only;
202
+ * no reference-image support on grok-2-image.
203
+ * - `'gemini-imagen'` — Google Imagen `:predict` endpoint. Text-only.
204
+ * - `'gemini-image-out'` — Google Gemini chat-style `:generateContent`
205
+ * endpoint that returns image parts (Gemini 2.5 Flash Image / "Nano
206
+ * Banana"). Accepts reference images.
207
+ *
208
+ * @public
209
+ */
210
+ export type AiImageApiFormat = 'openai-images' | 'gemini-imagen' | 'xai-images' | 'gemini-image-out';
142
211
  /**
143
212
  * Result of an AI provider completion call.
144
213
  * @public
@@ -149,6 +218,67 @@ export interface IAiCompletionResponse {
149
218
  /** Whether the response was truncated due to token limits */
150
219
  readonly truncated: boolean;
151
220
  }
221
+ /**
222
+ * A text-content delta arriving during a streaming completion.
223
+ * @public
224
+ */
225
+ export interface IAiStreamTextDelta {
226
+ readonly type: 'text-delta';
227
+ /** The newly arrived text fragment. */
228
+ readonly delta: string;
229
+ }
230
+ /**
231
+ * A server-side tool progress event arriving during a streaming completion.
232
+ * Surfaced for providers that emit explicit tool-progress markers (OpenAI
233
+ * Responses API, Anthropic). Gemini's grounding doesn't emit these.
234
+ * @public
235
+ */
236
+ export interface IAiStreamToolEvent {
237
+ readonly type: 'tool-event';
238
+ /** Which server-side tool this event describes. */
239
+ readonly toolType: AiServerToolType;
240
+ /** Tool lifecycle phase. */
241
+ readonly phase: 'started' | 'completed';
242
+ /**
243
+ * Optional provider-specific detail. For web_search this is typically the
244
+ * search query when available; format varies by provider.
245
+ */
246
+ readonly detail?: string;
247
+ }
248
+ /**
249
+ * Terminal success event for a streaming completion. Carries the aggregated
250
+ * full text and truncation status for callers that want both the progressive
251
+ * UI and the complete result.
252
+ * @public
253
+ */
254
+ export interface IAiStreamDone {
255
+ readonly type: 'done';
256
+ /** Whether the response was truncated due to token limits. */
257
+ readonly truncated: boolean;
258
+ /** The full concatenated text from all `text-delta` events. */
259
+ readonly fullText: string;
260
+ }
261
+ /**
262
+ * Terminal failure event for a streaming completion. After this event no
263
+ * further events are emitted.
264
+ *
265
+ * @remarks
266
+ * Connection-time failures (auth, network, pre-flight CORS rejection) are
267
+ * surfaced via the outer `Result.fail` returned by
268
+ * `callProviderCompletionStream` rather than as an `error` event, so callers
269
+ * can distinguish "didn't start" from "started but errored mid-stream."
270
+ *
271
+ * @public
272
+ */
273
+ export interface IAiStreamError {
274
+ readonly type: 'error';
275
+ readonly message: string;
276
+ }
277
+ /**
278
+ * Discriminated union of events emitted by a streaming completion.
279
+ * @public
280
+ */
281
+ export type IAiStreamEvent = IAiStreamTextDelta | IAiStreamToolEvent | IAiStreamDone | IAiStreamError;
152
282
  /**
153
283
  * Describes a single AI provider — single source of truth for all metadata.
154
284
  * @public
@@ -172,6 +302,206 @@ export interface IAiProviderDescriptor {
172
302
  readonly supportedTools: ReadonlyArray<AiServerToolType>;
173
303
  /** Whether this provider's API enforces CORS restrictions that prevent direct browser calls. */
174
304
  readonly corsRestricted: boolean;
305
+ /**
306
+ * Whether this provider's streaming completion endpoint requires a proxy
307
+ * for direct browser calls. Some providers gate streaming separately from
308
+ * non-streaming (rare), so this is tracked independently from
309
+ * {@link IAiProviderDescriptor.corsRestricted}.
310
+ *
311
+ * @remarks
312
+ * When `true`, `callProviderCompletionStream` rejects up front unless the
313
+ * call is being routed through a proxy.
314
+ */
315
+ readonly streamingCorsRestricted: boolean;
316
+ /**
317
+ * Whether this provider's chat completions API accepts image input
318
+ * (i.e. supports vision prompts). When false, calls with
319
+ * `prompt.attachments` are rejected up front.
320
+ */
321
+ readonly acceptsImageInput: boolean;
322
+ /**
323
+ * Image-generation capabilities, scoped to model id prefixes. Empty or
324
+ * undefined means the provider does not support image generation.
325
+ *
326
+ * @remarks
327
+ * The dispatcher matches the resolved model id against each rule's
328
+ * `modelPrefix` and selects the longest match (see
329
+ * {@link AiAssist.resolveImageCapability}). An empty `modelPrefix` is the
330
+ * catch-all and matches every model id.
331
+ *
332
+ * Multiple entries support providers that host more than one image-API
333
+ * surface under one baseUrl. Google Gemini is the canonical case: the
334
+ * `imagen-*` family is predict-only via `:predict`, while
335
+ * `gemini-2.5-flash-image` uses chat-style `:generateContent` and accepts
336
+ * reference images. Listing both lets callers pick the right model and the
337
+ * dispatcher routes accordingly.
338
+ *
339
+ * Image-model selection reuses the existing `image` {@link ModelSpecKey}.
340
+ * Providers that declare `imageGeneration` should declare a model in
341
+ * `defaultModel.image`, e.g. `{ base: 'gpt-4o', image: 'dall-e-3' }`.
342
+ */
343
+ readonly imageGeneration?: ReadonlyArray<IAiImageModelCapability>;
344
+ }
345
+ /**
346
+ * Image-generation capability for a model family within a provider. Used as
347
+ * an entry in {@link IAiProviderDescriptor.imageGeneration}.
348
+ *
349
+ * @public
350
+ */
351
+ export interface IAiImageModelCapability {
352
+ /**
353
+ * Prefix matched against the resolved image model id. The empty string is
354
+ * the catch-all and matches every model. When multiple rules' prefixes
355
+ * match a model id, the longest prefix wins; ties are broken by
356
+ * first-encountered.
357
+ */
358
+ readonly modelPrefix: string;
359
+ /** API format used to dispatch requests for matching models. */
360
+ readonly format: AiImageApiFormat;
361
+ /**
362
+ * Whether matching models accept reference images via
363
+ * {@link AiAssist.IAiImageGenerationParams.referenceImages}. When false or
364
+ * undefined, calls that include reference images are rejected up front.
365
+ *
366
+ * @remarks
367
+ * Per-model constraints beyond ref support (e.g. dall-e-3 ignores edits)
368
+ * are not validated here and surface as provider 400s, consistent with the
369
+ * existing image-generation policy.
370
+ */
371
+ readonly acceptsImageReferenceInput?: boolean;
372
+ }
373
+ /**
374
+ * Options for image generation requests.
375
+ *
376
+ * @remarks
377
+ * Provider compatibility is documented per field. The library does not
378
+ * pre-validate against per-model constraints (e.g. `dall-e-3` rejects
379
+ * `count > 1`); provider 400 errors surface through the failure path.
380
+ *
381
+ * @public
382
+ */
383
+ export interface IAiImageGenerationOptions {
384
+ /**
385
+ * Image dimensions. Used by openai-format providers (mapped to the
386
+ * provider's `size` field). Ignored by Imagen — use
387
+ * {@link IAiImageGenerationOptions.imagen} `aspectRatio` instead.
388
+ *
389
+ * Note: each model has its own accepted set; `dall-e-3` only accepts the
390
+ * values listed here.
391
+ */
392
+ readonly size?: '1024x1024' | '1024x1792' | '1792x1024' | 'auto';
393
+ /**
394
+ * Number of images to generate. Default 1.
395
+ *
396
+ * Note: `dall-e-3` rejects `count > 1`.
397
+ */
398
+ readonly count?: number;
399
+ /** Generation quality hint where supported. */
400
+ readonly quality?: 'standard' | 'high';
401
+ /** Random seed for reproducibility, where supported. */
402
+ readonly seed?: number;
403
+ /**
404
+ * Imagen-specific options. Ignored by other providers.
405
+ */
406
+ readonly imagen?: {
407
+ readonly negativePrompt?: string;
408
+ readonly aspectRatio?: '1:1' | '3:4' | '4:3' | '9:16' | '16:9';
409
+ };
410
+ }
411
+ /**
412
+ * Parameters for an image-generation request.
413
+ * @public
414
+ */
415
+ export interface IAiImageGenerationParams {
416
+ /** The text prompt describing the desired image. */
417
+ readonly prompt: string;
418
+ /** Optional generation options. */
419
+ readonly options?: IAiImageGenerationOptions;
420
+ /**
421
+ * Optional reference images. When present, the provider will use them as
422
+ * visual context (e.g. to preserve a character's appearance across multiple
423
+ * generations). The dispatcher resolves the
424
+ * {@link AiAssist.IAiImageModelCapability} for the requested model and
425
+ * rejects the call up front if `acceptsImageReferenceInput` is not set on
426
+ * the matching capability. An empty array is treated identically to
427
+ * `undefined`.
428
+ */
429
+ readonly referenceImages?: ReadonlyArray<IAiImageAttachment>;
430
+ }
431
+ /**
432
+ * A single generated image.
433
+ * @public
434
+ */
435
+ export interface IAiGeneratedImage extends IAiImageData {
436
+ /**
437
+ * The prompt as rewritten by the provider, if any. OpenAI's image models
438
+ * commonly rewrite prompts; other providers do not.
439
+ */
440
+ readonly revisedPrompt?: string;
441
+ }
442
+ /**
443
+ * Capability vocabulary used to describe what a model can do. Used as both
444
+ * a filter and as a tag in {@link AiAssist.IAiModelInfo.capabilities}.
445
+ *
446
+ * @remarks
447
+ * Adding a new capability is cheap; adding the *first* one after consumers
448
+ * already exist forces churn. The initial vocabulary is intentionally broad
449
+ * even though only `image-generation` is fully exercised today.
450
+ *
451
+ * @public
452
+ */
453
+ export type AiModelCapability = 'chat' | 'tools' | 'vision' | 'image-generation';
454
+ /**
455
+ * Information about a single model returned by a provider's list endpoint,
456
+ * with capabilities already resolved (native + config rules).
457
+ * @public
458
+ */
459
+ export interface IAiModelInfo {
460
+ /** Provider-native model identifier. */
461
+ readonly id: string;
462
+ /** Resolved capability set — union of native declarations and config rules. */
463
+ readonly capabilities: ReadonlySet<AiModelCapability>;
464
+ /** Friendly name for display, when known. */
465
+ readonly displayName?: string;
466
+ }
467
+ /**
468
+ * One rule in an {@link IAiModelCapabilityConfig}. Multiple rules can match
469
+ * a single model — their capability arrays are unioned.
470
+ * @public
471
+ */
472
+ export interface IAiModelCapabilityRule {
473
+ /** RegExp tested against the model id (using `.test`). */
474
+ readonly idPattern: RegExp;
475
+ /** Capabilities this rule attributes to matching models. */
476
+ readonly capabilities: ReadonlyArray<AiModelCapability>;
477
+ /**
478
+ * Friendly display-name override for matching models. The function form
479
+ * lets one rule format many ids (e.g. `(id) => id.toUpperCase()`).
480
+ * If multiple matching rules supply `displayName`, the first match wins.
481
+ */
482
+ readonly displayName?: string | ((id: string) => string);
483
+ }
484
+ /**
485
+ * Configuration that maps model id patterns to capabilities. Used to
486
+ * augment (or, where the provider supplies no capability info, fully
487
+ * derive) the capability set for each listed model.
488
+ * @public
489
+ */
490
+ export interface IAiModelCapabilityConfig {
491
+ /** Per-provider rules. Tried before {@link AiAssist.IAiModelCapabilityConfig.global}. */
492
+ readonly perProvider?: {
493
+ readonly [P in AiProviderId]?: ReadonlyArray<IAiModelCapabilityRule>;
494
+ };
495
+ /** Cross-provider fallback rules. */
496
+ readonly global?: ReadonlyArray<IAiModelCapabilityRule>;
497
+ }
498
+ /**
499
+ * Result of an image-generation call.
500
+ * @public
501
+ */
502
+ export interface IAiImageGenerationResponse {
503
+ /** The generated images, in provider-returned order. */
504
+ readonly images: ReadonlyArray<IAiGeneratedImage>;
175
505
  }
176
506
  /**
177
507
  * Configuration for a single AI assist provider.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/packlets/ai-assist/model.ts"],"names":[],"mappings":"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"}
@@ -20,7 +20,17 @@
20
20
  // SOFTWARE.
21
21
  Object.defineProperty(exports, "__esModule", { value: true });
22
22
  exports.DEFAULT_AI_ASSIST = exports.MODEL_SPEC_BASE_KEY = exports.allModelSpecKeys = exports.AiPrompt = void 0;
23
+ exports.toDataUrl = toDataUrl;
23
24
  exports.resolveModel = resolveModel;
25
+ /**
26
+ * Formats an {@link IAiImageData} as a `data:` URL suitable for browser display.
27
+ * @param image - The image to format
28
+ * @returns A `data:<mime>;base64,<data>` URL string
29
+ * @public
30
+ */
31
+ function toDataUrl(image) {
32
+ return `data:${image.mimeType};base64,${image.base64}`;
33
+ }
24
34
  // ============================================================================
25
35
  // AiPrompt
26
36
  // ============================================================================
@@ -30,13 +40,21 @@ exports.resolveModel = resolveModel;
30
40
  * @public
31
41
  */
32
42
  class AiPrompt {
33
- constructor(user, system) {
43
+ constructor(user, system, attachments) {
34
44
  this.system = system;
35
45
  this.user = user;
46
+ this.attachments = attachments !== null && attachments !== void 0 ? attachments : [];
36
47
  }
37
- /** Combined single-string version (user + system joined) for copy/paste. */
48
+ /**
49
+ * Combined single-string version (user + system joined) for copy/paste.
50
+ * When attachments are present, includes a sentinel noting they aren't
51
+ * part of the copied text.
52
+ */
38
53
  get combined() {
39
- return `${this.user}\n\n${this.system}`;
54
+ const sentinel = this.attachments.length > 0
55
+ ? `\n\n[${this.attachments.length} image attachment(s) — not included in copied text]`
56
+ : '';
57
+ return `${this.user}${sentinel}\n\n${this.system}`;
40
58
  }
41
59
  }
42
60
  exports.AiPrompt = AiPrompt;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/packlets/ai-assist/model.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;AAoCZ,8BAEC;AAqMD,oCAsBC;AAnOD;;;;;GAKG;AACH,SAAgB,SAAS,CAAC,KAAmB;IAC3C,OAAO,QAAQ,KAAK,CAAC,QAAQ,WAAW,KAAK,CAAC,MAAM,EAAE,CAAC;AACzD,CAAC;AAuBD,+EAA+E;AAC/E,WAAW;AACX,+EAA+E;AAE/E;;;;GAIG;AACH,MAAa,QAAQ;IAYnB,YAAmB,IAAY,EAAE,MAAc,EAAE,WAA+C;QAC9F,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,WAAW,GAAG,WAAW,aAAX,WAAW,cAAX,WAAW,GAAI,EAAE,CAAC;IACvC,CAAC;IAED;;;;OAIG;IACH,IAAW,QAAQ;QACjB,MAAM,QAAQ,GACZ,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;YACzB,CAAC,CAAC,QAAQ,IAAI,CAAC,WAAW,CAAC,MAAM,qDAAqD;YACtF,CAAC,CAAC,EAAE,CAAC;QACT,OAAO,GAAG,IAAI,CAAC,IAAI,GAAG,QAAQ,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;IACrD,CAAC;CACF;AA9BD,4BA8BC;AA6ED;;;GAGG;AACU,QAAA,gBAAgB,GAAgC,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAExF;;;GAGG;AACU,QAAA,mBAAmB,GAAiB,MAAM,CAAC;AAiCxD;;;;;;;;;;;;;;GAcG;AACH,SAAgB,YAAY,CAAC,IAAe,EAAE,OAAgB;IAC5D,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,sCAAsC;IACtC,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;QAC7C,OAAO,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACrC,CAAC;IAED,sBAAsB;IACtB,IAAI,2BAAmB,IAAI,IAAI,EAAE,CAAC;QAChC,OAAO,YAAY,CAAC,IAAI,CAAC,2BAAmB,CAAC,CAAC,CAAC;IACjD,CAAC;IAED,yCAAyC;IACzC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,6FAA6F;IAC7F,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC;AAC7B,CAAC;AAiZD;;;GAGG;AACU,QAAA,iBAAiB,GAAsB;IAClD,SAAS,EAAE,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;CACxC,CAAC","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n/**\n * Core types for AI assist: prompt class, provider descriptors, settings, and chat messages.\n * @packageDocumentation\n */\n\nimport { type Result } from '@fgv/ts-utils';\n\n// ============================================================================\n// Image Data\n// ============================================================================\n\n/**\n * Universal image representation used for both image input (vision prompts)\n * and image output (generation responses).\n *\n * @remarks\n * The base64 string is raw — no `data:` URL prefix. Use {@link AiAssist.toDataUrl} to\n * format it for browser-display contexts.\n *\n * @public\n */\nexport interface IAiImageData {\n /** MIME type, e.g. `'image/png'`, `'image/jpeg'`, `'image/webp'`. */\n readonly mimeType: string;\n /** Base64-encoded image bytes (no `data:` prefix). */\n readonly base64: string;\n}\n\n/**\n * Formats an {@link IAiImageData} as a `data:` URL suitable for browser display.\n * @param image - The image to format\n * @returns A `data:<mime>;base64,<data>` URL string\n * @public\n */\nexport function toDataUrl(image: IAiImageData): string {\n return `data:${image.mimeType};base64,${image.base64}`;\n}\n\n/**\n * Image attachment for a vision (image-input) prompt.\n *\n * @remarks\n * Extends {@link IAiImageData} with an OpenAI-specific `detail` hint that is\n * silently ignored by Anthropic, Gemini, and other providers.\n *\n * @public\n */\nexport interface IAiImageAttachment extends IAiImageData {\n /**\n * OpenAI vision detail hint:\n * - `'low'`: faster, cheaper, lower fidelity\n * - `'high'`: slower, more expensive, higher fidelity\n * - `'auto'` (default): provider chooses\n *\n * Ignored by providers other than OpenAI.\n */\n readonly detail?: 'low' | 'high' | 'auto';\n}\n\n// ============================================================================\n// AiPrompt\n// ============================================================================\n\n/**\n * A structured AI prompt with system/user split for direct API calls,\n * and a lazily-constructed combined version for copy/paste workflows.\n * @public\n */\nexport class AiPrompt {\n /** System instructions: schema documentation, format rules, general guidance. */\n public readonly system: string;\n /** User request: the specific entity generation request. */\n public readonly user: string;\n /**\n * Optional image attachments. When present, vision-capable providers will\n * include them in the user message; non-vision providers will reject the\n * call up front (see {@link AiAssist.IAiProviderDescriptor.acceptsImageInput}).\n */\n public readonly attachments: ReadonlyArray<IAiImageAttachment>;\n\n public constructor(user: string, system: string, attachments?: ReadonlyArray<IAiImageAttachment>) {\n this.system = system;\n this.user = user;\n this.attachments = attachments ?? [];\n }\n\n /**\n * Combined single-string version (user + system joined) for copy/paste.\n * When attachments are present, includes a sentinel noting they aren't\n * part of the copied text.\n */\n public get combined(): string {\n const sentinel =\n this.attachments.length > 0\n ? `\\n\\n[${this.attachments.length} image attachment(s) — not included in copied text]`\n : '';\n return `${this.user}${sentinel}\\n\\n${this.system}`;\n }\n}\n\n// ============================================================================\n// Chat Message\n// ============================================================================\n\n/**\n * A single chat message in OpenAI format.\n * @public\n */\nexport interface IChatMessage {\n /** Message role */\n readonly role: 'system' | 'user' | 'assistant';\n /** Message content */\n readonly content: string;\n}\n\n// ============================================================================\n// Server-Side Tools\n// ============================================================================\n\n/**\n * Built-in server-side tool types supported across providers.\n * @public\n */\nexport type AiServerToolType = 'web_search';\n\n/**\n * Configuration specific to web search tools.\n * @public\n */\nexport interface IAiWebSearchToolConfig {\n readonly type: 'web_search';\n /** Optional: restrict search to these domains. */\n readonly allowedDomains?: ReadonlyArray<string>;\n /** Optional: exclude these domains from search. */\n readonly blockedDomains?: ReadonlyArray<string>;\n /** Optional: max number of searches per request. */\n readonly maxUses?: number;\n /**\n * Optional: enable image understanding during web search.\n * When true, the model can view and analyze images found during search.\n * Currently supported by xAI only; ignored by other providers.\n */\n readonly enableImageUnderstanding?: boolean;\n}\n\n/**\n * Union of all server-side tool configurations. Discriminated on `type`.\n * @public\n */\nexport type AiServerToolConfig = IAiWebSearchToolConfig;\n\n/**\n * Declares a tool as enabled/disabled in provider settings.\n * Tools are disabled by default — consuming apps must opt in explicitly.\n * @public\n */\nexport interface IAiToolEnablement {\n /** Which tool type. */\n readonly type: AiServerToolType;\n /** Whether this tool is enabled by default for this provider. */\n readonly enabled: boolean;\n /** Optional tool-specific configuration. */\n readonly config?: AiServerToolConfig;\n}\n\n// ============================================================================\n// Model Specification\n// ============================================================================\n\n/**\n * Known context keys for model specification maps.\n * @public\n */\nexport type ModelSpecKey = 'base' | 'tools' | 'image';\n\n/**\n * All valid {@link ModelSpecKey} values.\n * @public\n */\nexport const allModelSpecKeys: ReadonlyArray<ModelSpecKey> = ['base', 'tools', 'image'];\n\n/**\n * Default context key used as fallback when resolving a {@link ModelSpec}.\n * @public\n */\nexport const MODEL_SPEC_BASE_KEY: ModelSpecKey = 'base';\n\n/**\n * A model specification: either a simple model string or a record mapping\n * context keys to nested model specs.\n *\n * @remarks\n * A bare string is equivalent to `{ base: string }`. This keeps the simple\n * case simple while allowing context-aware model selection (e.g. different\n * models for tool-augmented vs. base completions).\n *\n * @example\n * ```typescript\n * // Simple — same model for all contexts:\n * const simple: ModelSpec = 'grok-4-1-fast';\n *\n * // Context-aware — reasoning model when tools are active:\n * const split: ModelSpec = { base: 'grok-4-1-fast', tools: 'grok-4-1-fast-reasoning' };\n *\n * // Future nested — per-tool model selection:\n * const nested: ModelSpec = { base: 'grok-fast', tools: { base: 'grok-r', image: 'grok-v' } };\n * ```\n * @public\n */\nexport interface IModelSpecMap {\n readonly [key: string]: ModelSpec;\n}\n\n/**\n * @public\n */\nexport type ModelSpec = string | IModelSpecMap;\n\n/**\n * Resolves a {@link ModelSpec} to a concrete model string given an optional context key.\n *\n * @remarks\n * Resolution rules:\n * 1. If the spec is a string, return it directly (context is irrelevant).\n * 2. If the spec is an object and the context key exists, recurse into that branch.\n * 3. Otherwise, fall back to the {@link MODEL_SPEC_BASE_KEY | 'base'} key.\n * 4. If neither context nor `'base'` exists, use the first available value.\n *\n * @param spec - The model specification to resolve\n * @param context - Optional context key (e.g. `'tools'`)\n * @returns The resolved model string\n * @public\n */\nexport function resolveModel(spec: ModelSpec, context?: string): string {\n if (typeof spec === 'string') {\n return spec;\n }\n\n // Try the requested context key first\n if (context !== undefined && context in spec) {\n return resolveModel(spec[context]);\n }\n\n // Fall back to 'base'\n if (MODEL_SPEC_BASE_KEY in spec) {\n return resolveModel(spec[MODEL_SPEC_BASE_KEY]);\n }\n\n // Last resort: first value in the record\n const first = Object.values(spec)[0];\n /* c8 ignore next 3 - defensive: only reachable with empty object (prevented by converter) */\n if (first === undefined) {\n return '';\n }\n return resolveModel(first);\n}\n\n// ============================================================================\n// Provider Descriptor\n// ============================================================================\n\n/**\n * All known AI provider identifiers.\n * @public\n */\nexport type AiProviderId =\n | 'copy-paste'\n | 'xai-grok'\n | 'openai'\n | 'anthropic'\n | 'google-gemini'\n | 'groq'\n | 'mistral';\n\n/**\n * API format categories for provider routing.\n * @public\n */\nexport type AiApiFormat = 'openai' | 'anthropic' | 'gemini';\n\n/**\n * API format categories for image-generation provider routing.\n *\n * @remarks\n * - `'openai-images'` — OpenAI Images API. Routes to `/images/generations`\n * (text-only) or `/images/edits` (when reference images are present).\n * - `'xai-images'` — xAI Images API. Same wire shape as OpenAI but text-only;\n * no reference-image support on grok-2-image.\n * - `'gemini-imagen'` — Google Imagen `:predict` endpoint. Text-only.\n * - `'gemini-image-out'` — Google Gemini chat-style `:generateContent`\n * endpoint that returns image parts (Gemini 2.5 Flash Image / \"Nano\n * Banana\"). Accepts reference images.\n *\n * @public\n */\nexport type AiImageApiFormat = 'openai-images' | 'gemini-imagen' | 'xai-images' | 'gemini-image-out';\n\n// ============================================================================\n// Completion Response\n// ============================================================================\n\n/**\n * Result of an AI provider completion call.\n * @public\n */\nexport interface IAiCompletionResponse {\n /** The generated text content */\n readonly content: string;\n /** Whether the response was truncated due to token limits */\n readonly truncated: boolean;\n}\n\n// ============================================================================\n// Streaming Events\n// ============================================================================\n\n/**\n * A text-content delta arriving during a streaming completion.\n * @public\n */\nexport interface IAiStreamTextDelta {\n readonly type: 'text-delta';\n /** The newly arrived text fragment. */\n readonly delta: string;\n}\n\n/**\n * A server-side tool progress event arriving during a streaming completion.\n * Surfaced for providers that emit explicit tool-progress markers (OpenAI\n * Responses API, Anthropic). Gemini's grounding doesn't emit these.\n * @public\n */\nexport interface IAiStreamToolEvent {\n readonly type: 'tool-event';\n /** Which server-side tool this event describes. */\n readonly toolType: AiServerToolType;\n /** Tool lifecycle phase. */\n readonly phase: 'started' | 'completed';\n /**\n * Optional provider-specific detail. For web_search this is typically the\n * search query when available; format varies by provider.\n */\n readonly detail?: string;\n}\n\n/**\n * Terminal success event for a streaming completion. Carries the aggregated\n * full text and truncation status for callers that want both the progressive\n * UI and the complete result.\n * @public\n */\nexport interface IAiStreamDone {\n readonly type: 'done';\n /** Whether the response was truncated due to token limits. */\n readonly truncated: boolean;\n /** The full concatenated text from all `text-delta` events. */\n readonly fullText: string;\n}\n\n/**\n * Terminal failure event for a streaming completion. After this event no\n * further events are emitted.\n *\n * @remarks\n * Connection-time failures (auth, network, pre-flight CORS rejection) are\n * surfaced via the outer `Result.fail` returned by\n * `callProviderCompletionStream` rather than as an `error` event, so callers\n * can distinguish \"didn't start\" from \"started but errored mid-stream.\"\n *\n * @public\n */\nexport interface IAiStreamError {\n readonly type: 'error';\n readonly message: string;\n}\n\n/**\n * Discriminated union of events emitted by a streaming completion.\n * @public\n */\nexport type IAiStreamEvent = IAiStreamTextDelta | IAiStreamToolEvent | IAiStreamDone | IAiStreamError;\n\n/**\n * Describes a single AI provider — single source of truth for all metadata.\n * @public\n */\nexport interface IAiProviderDescriptor {\n /** Provider identifier (e.g. 'xai-grok', 'anthropic') */\n readonly id: AiProviderId;\n /** Human-readable label (e.g. \"xAI Grok\") */\n readonly label: string;\n /** Button label for action buttons (e.g. \"AI Assist | Grok\") */\n readonly buttonLabel: string;\n /** Whether this provider requires an API key secret */\n readonly needsSecret: boolean;\n /** Which API adapter format to use */\n readonly apiFormat: AiApiFormat;\n /** Base URL for the API (e.g. 'https://api.x.ai/v1') */\n readonly baseUrl: string;\n /** Default model specification — string or context-aware map. */\n readonly defaultModel: ModelSpec;\n /** Which server-side tools this provider supports (empty = none). */\n readonly supportedTools: ReadonlyArray<AiServerToolType>;\n /** Whether this provider's API enforces CORS restrictions that prevent direct browser calls. */\n readonly corsRestricted: boolean;\n /**\n * Whether this provider's streaming completion endpoint requires a proxy\n * for direct browser calls. Some providers gate streaming separately from\n * non-streaming (rare), so this is tracked independently from\n * {@link IAiProviderDescriptor.corsRestricted}.\n *\n * @remarks\n * When `true`, `callProviderCompletionStream` rejects up front unless the\n * call is being routed through a proxy.\n */\n readonly streamingCorsRestricted: boolean;\n /**\n * Whether this provider's chat completions API accepts image input\n * (i.e. supports vision prompts). When false, calls with\n * `prompt.attachments` are rejected up front.\n */\n readonly acceptsImageInput: boolean;\n /**\n * Image-generation capabilities, scoped to model id prefixes. Empty or\n * undefined means the provider does not support image generation.\n *\n * @remarks\n * The dispatcher matches the resolved model id against each rule's\n * `modelPrefix` and selects the longest match (see\n * {@link AiAssist.resolveImageCapability}). An empty `modelPrefix` is the\n * catch-all and matches every model id.\n *\n * Multiple entries support providers that host more than one image-API\n * surface under one baseUrl. Google Gemini is the canonical case: the\n * `imagen-*` family is predict-only via `:predict`, while\n * `gemini-2.5-flash-image` uses chat-style `:generateContent` and accepts\n * reference images. Listing both lets callers pick the right model and the\n * dispatcher routes accordingly.\n *\n * Image-model selection reuses the existing `image` {@link ModelSpecKey}.\n * Providers that declare `imageGeneration` should declare a model in\n * `defaultModel.image`, e.g. `{ base: 'gpt-4o', image: 'dall-e-3' }`.\n */\n readonly imageGeneration?: ReadonlyArray<IAiImageModelCapability>;\n}\n\n/**\n * Image-generation capability for a model family within a provider. Used as\n * an entry in {@link IAiProviderDescriptor.imageGeneration}.\n *\n * @public\n */\nexport interface IAiImageModelCapability {\n /**\n * Prefix matched against the resolved image model id. The empty string is\n * the catch-all and matches every model. When multiple rules' prefixes\n * match a model id, the longest prefix wins; ties are broken by\n * first-encountered.\n */\n readonly modelPrefix: string;\n /** API format used to dispatch requests for matching models. */\n readonly format: AiImageApiFormat;\n /**\n * Whether matching models accept reference images via\n * {@link AiAssist.IAiImageGenerationParams.referenceImages}. When false or\n * undefined, calls that include reference images are rejected up front.\n *\n * @remarks\n * Per-model constraints beyond ref support (e.g. dall-e-3 ignores edits)\n * are not validated here and surface as provider 400s, consistent with the\n * existing image-generation policy.\n */\n readonly acceptsImageReferenceInput?: boolean;\n}\n\n// ============================================================================\n// Image Generation\n// ============================================================================\n\n/**\n * Options for image generation requests.\n *\n * @remarks\n * Provider compatibility is documented per field. The library does not\n * pre-validate against per-model constraints (e.g. `dall-e-3` rejects\n * `count > 1`); provider 400 errors surface through the failure path.\n *\n * @public\n */\nexport interface IAiImageGenerationOptions {\n /**\n * Image dimensions. Used by openai-format providers (mapped to the\n * provider's `size` field). Ignored by Imagen — use\n * {@link IAiImageGenerationOptions.imagen} `aspectRatio` instead.\n *\n * Note: each model has its own accepted set; `dall-e-3` only accepts the\n * values listed here.\n */\n readonly size?: '1024x1024' | '1024x1792' | '1792x1024' | 'auto';\n /**\n * Number of images to generate. Default 1.\n *\n * Note: `dall-e-3` rejects `count > 1`.\n */\n readonly count?: number;\n /** Generation quality hint where supported. */\n readonly quality?: 'standard' | 'high';\n /** Random seed for reproducibility, where supported. */\n readonly seed?: number;\n /**\n * Imagen-specific options. Ignored by other providers.\n */\n readonly imagen?: {\n readonly negativePrompt?: string;\n readonly aspectRatio?: '1:1' | '3:4' | '4:3' | '9:16' | '16:9';\n };\n}\n\n/**\n * Parameters for an image-generation request.\n * @public\n */\nexport interface IAiImageGenerationParams {\n /** The text prompt describing the desired image. */\n readonly prompt: string;\n /** Optional generation options. */\n readonly options?: IAiImageGenerationOptions;\n /**\n * Optional reference images. When present, the provider will use them as\n * visual context (e.g. to preserve a character's appearance across multiple\n * generations). The dispatcher resolves the\n * {@link AiAssist.IAiImageModelCapability} for the requested model and\n * rejects the call up front if `acceptsImageReferenceInput` is not set on\n * the matching capability. An empty array is treated identically to\n * `undefined`.\n */\n readonly referenceImages?: ReadonlyArray<IAiImageAttachment>;\n}\n\n/**\n * A single generated image.\n * @public\n */\nexport interface IAiGeneratedImage extends IAiImageData {\n /**\n * The prompt as rewritten by the provider, if any. OpenAI's image models\n * commonly rewrite prompts; other providers do not.\n */\n readonly revisedPrompt?: string;\n}\n\n// ============================================================================\n// Model Catalog (listModels)\n// ============================================================================\n\n/**\n * Capability vocabulary used to describe what a model can do. Used as both\n * a filter and as a tag in {@link AiAssist.IAiModelInfo.capabilities}.\n *\n * @remarks\n * Adding a new capability is cheap; adding the *first* one after consumers\n * already exist forces churn. The initial vocabulary is intentionally broad\n * even though only `image-generation` is fully exercised today.\n *\n * @public\n */\nexport type AiModelCapability = 'chat' | 'tools' | 'vision' | 'image-generation';\n\n/**\n * Information about a single model returned by a provider's list endpoint,\n * with capabilities already resolved (native + config rules).\n * @public\n */\nexport interface IAiModelInfo {\n /** Provider-native model identifier. */\n readonly id: string;\n /** Resolved capability set — union of native declarations and config rules. */\n readonly capabilities: ReadonlySet<AiModelCapability>;\n /** Friendly name for display, when known. */\n readonly displayName?: string;\n}\n\n/**\n * One rule in an {@link IAiModelCapabilityConfig}. Multiple rules can match\n * a single model — their capability arrays are unioned.\n * @public\n */\nexport interface IAiModelCapabilityRule {\n /** RegExp tested against the model id (using `.test`). */\n readonly idPattern: RegExp;\n /** Capabilities this rule attributes to matching models. */\n readonly capabilities: ReadonlyArray<AiModelCapability>;\n /**\n * Friendly display-name override for matching models. The function form\n * lets one rule format many ids (e.g. `(id) => id.toUpperCase()`).\n * If multiple matching rules supply `displayName`, the first match wins.\n */\n readonly displayName?: string | ((id: string) => string);\n}\n\n/**\n * Configuration that maps model id patterns to capabilities. Used to\n * augment (or, where the provider supplies no capability info, fully\n * derive) the capability set for each listed model.\n * @public\n */\nexport interface IAiModelCapabilityConfig {\n /** Per-provider rules. Tried before {@link AiAssist.IAiModelCapabilityConfig.global}. */\n readonly perProvider?: { readonly [P in AiProviderId]?: ReadonlyArray<IAiModelCapabilityRule> };\n /** Cross-provider fallback rules. */\n readonly global?: ReadonlyArray<IAiModelCapabilityRule>;\n}\n\n/**\n * Result of an image-generation call.\n * @public\n */\nexport interface IAiImageGenerationResponse {\n /** The generated images, in provider-returned order. */\n readonly images: ReadonlyArray<IAiGeneratedImage>;\n}\n\n// ============================================================================\n// Settings\n// ============================================================================\n\n/**\n * Configuration for a single AI assist provider.\n * @public\n */\nexport interface IAiAssistProviderConfig {\n /** Which provider this configures */\n readonly provider: AiProviderId;\n /** For API-based providers: the keystore secret name holding the API key */\n readonly secretName?: string;\n /** Optional model override — string or context-aware map. */\n readonly model?: ModelSpec;\n /** Tool enablement/configuration. Tools are disabled unless explicitly enabled. */\n readonly tools?: ReadonlyArray<IAiToolEnablement>;\n}\n\n/**\n * AI assist settings — which providers are enabled and their configuration.\n * @public\n */\nexport interface IAiAssistSettings {\n /** Enabled providers and their configuration. */\n readonly providers: ReadonlyArray<IAiAssistProviderConfig>;\n /** Which enabled provider is the default for the main button. Falls back to first in list. */\n readonly defaultProvider?: AiProviderId;\n /** Optional proxy URL for routing API requests through a backend server (e.g. `http://localhost:3002`). */\n readonly proxyUrl?: string;\n /** When true, route all providers through the proxy. When false (default), only CORS-restricted providers use the proxy. */\n readonly proxyAllProviders?: boolean;\n}\n\n/**\n * Default AI assist settings (copy-paste only).\n * @public\n */\nexport const DEFAULT_AI_ASSIST: IAiAssistSettings = {\n providers: [{ provider: 'copy-paste' }]\n};\n\n// ============================================================================\n// Keystore Interface\n// ============================================================================\n\n/**\n * Minimal keystore interface for AI assist API key resolution.\n * Satisfied structurally by the concrete `KeyStore` class from `@fgv/ts-extras`.\n * @public\n */\nexport interface IAiAssistKeyStore {\n /** Whether the keystore is currently unlocked */\n readonly isUnlocked: boolean;\n /** Check if a named secret exists */\n hasSecret(name: string): Result<boolean>;\n /** Get an API key by secret name */\n getApiKey(name: string): Result<string>;\n}\n"]}
@@ -3,7 +3,7 @@
3
3
  * @packageDocumentation
4
4
  */
5
5
  import { Result } from '@fgv/ts-utils';
6
- import { type AiProviderId, type IAiProviderDescriptor } from './model';
6
+ import { type AiProviderId, type IAiImageModelCapability, type IAiModelCapabilityConfig, type IAiProviderDescriptor } from './model';
7
7
  /**
8
8
  * All valid provider ID values, in the same order as the registry.
9
9
  * @public
@@ -22,4 +22,37 @@ export declare function getProviderDescriptors(): ReadonlyArray<IAiProviderDescr
22
22
  * @public
23
23
  */
24
24
  export declare function getProviderDescriptor(id: string): Result<IAiProviderDescriptor>;
25
+ /**
26
+ * Whether a provider declares any image-generation capability at all.
27
+ *
28
+ * @param descriptor - The provider descriptor
29
+ * @returns `true` when {@link IAiProviderDescriptor.imageGeneration} has at
30
+ * least one entry; `false` otherwise.
31
+ * @public
32
+ */
33
+ export declare function supportsImageGeneration(descriptor: IAiProviderDescriptor): boolean;
34
+ /**
35
+ * Resolve the image-generation capability that applies to a given model id
36
+ * for a provider. Returns the entry from
37
+ * {@link IAiProviderDescriptor.imageGeneration} whose `modelPrefix` is the
38
+ * longest prefix of `modelId`. Ties are broken by first-encountered, so rule
39
+ * order does not matter for correctness — only for tie-breaking among rules
40
+ * with identical-length prefixes (an unusual case).
41
+ *
42
+ * @param descriptor - The provider descriptor
43
+ * @param modelId - The resolved image model id
44
+ * @returns The matching capability, or `undefined` when no rule matches or
45
+ * the provider declares no image-generation capabilities.
46
+ * @public
47
+ */
48
+ export declare function resolveImageCapability(descriptor: IAiProviderDescriptor, modelId: string): IAiImageModelCapability | undefined;
49
+ /**
50
+ * Default capability config used by `callProviderListModels` when callers
51
+ * don't supply their own. Patterns are intentionally narrow — false
52
+ * positives are worse than missing a model. Caller can override per call
53
+ * via {@link IProviderListModelsParams.capabilityConfig}.
54
+ *
55
+ * @public
56
+ */
57
+ export declare const DEFAULT_MODEL_CAPABILITY_CONFIG: IAiModelCapabilityConfig;
25
58
  //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/packlets/ai-assist/registry.ts"],"names":[],"mappings":"AAoBA;;;GAGG;AAEH,OAAO,EAAQ,MAAM,EAAW,MAAM,eAAe,CAAC;AAEtD,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,EAC3B,MAAM,SAAS,CAAC;AAuIjB;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,aAAa,CAAC,YAAY,CAAsC,CAAC;AAE9F;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,aAAa,CAAC,qBAAqB,CAAC,CAE7E;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAM/E;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,qBAAqB,GAAG,OAAO,CAElF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,qBAAqB,EACjC,OAAO,EAAE,MAAM,GACd,uBAAuB,GAAG,SAAS,CAOrC;AAMD;;;;;;;GAOG;AACH,eAAO,MAAM,+BAA+B,EAAE,wBAwB7C,CAAC"}