@fgv/ts-extras 5.1.0-4 → 5.1.0-40

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 (368) hide show
  1. package/dist/index.browser.js +4 -2
  2. package/dist/index.browser.js.map +1 -0
  3. package/dist/index.js.map +1 -0
  4. package/dist/packlets/ai-assist/apiClient.js +886 -158
  5. package/dist/packlets/ai-assist/apiClient.js.map +1 -0
  6. package/dist/packlets/ai-assist/chatRequestBuilders.js +282 -0
  7. package/dist/packlets/ai-assist/chatRequestBuilders.js.map +1 -0
  8. package/dist/packlets/ai-assist/converters.js +47 -3
  9. package/dist/packlets/ai-assist/converters.js.map +1 -0
  10. package/dist/packlets/ai-assist/embeddingClient.js +345 -0
  11. package/dist/packlets/ai-assist/embeddingClient.js.map +1 -0
  12. package/dist/packlets/ai-assist/endpoint.js +78 -0
  13. package/dist/packlets/ai-assist/endpoint.js.map +1 -0
  14. package/dist/packlets/ai-assist/http.js +75 -0
  15. package/dist/packlets/ai-assist/http.js.map +1 -0
  16. package/dist/packlets/ai-assist/imageOptionsResolver.js +193 -0
  17. package/dist/packlets/ai-assist/imageOptionsResolver.js.map +1 -0
  18. package/dist/packlets/ai-assist/index.js +10 -4
  19. package/dist/packlets/ai-assist/index.js.map +1 -0
  20. package/dist/packlets/ai-assist/jsonCompletion.js +93 -0
  21. package/dist/packlets/ai-assist/jsonCompletion.js.map +1 -0
  22. package/dist/packlets/ai-assist/jsonResponse.js +149 -0
  23. package/dist/packlets/ai-assist/jsonResponse.js.map +1 -0
  24. package/dist/packlets/ai-assist/model.js +193 -9
  25. package/dist/packlets/ai-assist/model.js.map +1 -0
  26. package/dist/packlets/ai-assist/registry.js +314 -12
  27. package/dist/packlets/ai-assist/registry.js.map +1 -0
  28. package/dist/packlets/ai-assist/sseParser.js +123 -0
  29. package/dist/packlets/ai-assist/sseParser.js.map +1 -0
  30. package/dist/packlets/ai-assist/streamingAdapters/anthropic.js +368 -0
  31. package/dist/packlets/ai-assist/streamingAdapters/anthropic.js.map +1 -0
  32. package/dist/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.js +687 -0
  33. package/dist/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.js.map +1 -0
  34. package/dist/packlets/ai-assist/streamingAdapters/common.js +187 -0
  35. package/dist/packlets/ai-assist/streamingAdapters/common.js.map +1 -0
  36. package/dist/packlets/ai-assist/streamingAdapters/gemini.js +204 -0
  37. package/dist/packlets/ai-assist/streamingAdapters/gemini.js.map +1 -0
  38. package/dist/packlets/ai-assist/streamingAdapters/openaiChat.js +170 -0
  39. package/dist/packlets/ai-assist/streamingAdapters/openaiChat.js.map +1 -0
  40. package/dist/packlets/ai-assist/streamingAdapters/openaiResponses.js +386 -0
  41. package/dist/packlets/ai-assist/streamingAdapters/openaiResponses.js.map +1 -0
  42. package/dist/packlets/ai-assist/streamingAdapters/proxy.js +173 -0
  43. package/dist/packlets/ai-assist/streamingAdapters/proxy.js.map +1 -0
  44. package/dist/packlets/ai-assist/streamingClient.js +140 -0
  45. package/dist/packlets/ai-assist/streamingClient.js.map +1 -0
  46. package/dist/packlets/ai-assist/thinkingOptionsResolver.js +288 -0
  47. package/dist/packlets/ai-assist/thinkingOptionsResolver.js.map +1 -0
  48. package/dist/packlets/ai-assist/toolFormats.js +106 -10
  49. package/dist/packlets/ai-assist/toolFormats.js.map +1 -0
  50. package/dist/packlets/conversion/converters.js +35 -1
  51. package/dist/packlets/conversion/converters.js.map +1 -0
  52. package/dist/packlets/conversion/index.js.map +1 -0
  53. package/dist/packlets/crypto-utils/constants.js.map +1 -0
  54. package/dist/packlets/crypto-utils/converters.js +42 -4
  55. package/dist/packlets/crypto-utils/converters.js.map +1 -0
  56. package/dist/packlets/crypto-utils/directEncryptionProvider.js.map +1 -0
  57. package/dist/packlets/crypto-utils/encryptedFile.js.map +1 -0
  58. package/dist/packlets/crypto-utils/hpkeProvider.js +333 -0
  59. package/dist/packlets/crypto-utils/hpkeProvider.js.map +1 -0
  60. package/dist/packlets/crypto-utils/index.browser.js +10 -2
  61. package/dist/packlets/crypto-utils/index.browser.js.map +1 -0
  62. package/dist/packlets/crypto-utils/index.js +6 -0
  63. package/dist/packlets/crypto-utils/index.js.map +1 -0
  64. package/dist/packlets/crypto-utils/keyPairAlgorithmParams.js +71 -0
  65. package/dist/packlets/crypto-utils/keyPairAlgorithmParams.js.map +1 -0
  66. package/dist/packlets/crypto-utils/keystore/converters.js +103 -11
  67. package/dist/packlets/crypto-utils/keystore/converters.js.map +1 -0
  68. package/dist/packlets/crypto-utils/keystore/encryptedFilePrivateKeyStorage.js +287 -0
  69. package/dist/packlets/crypto-utils/keystore/encryptedFilePrivateKeyStorage.js.map +1 -0
  70. package/dist/packlets/crypto-utils/keystore/index.browser.js +36 -0
  71. package/dist/packlets/crypto-utils/keystore/index.browser.js.map +1 -0
  72. package/dist/packlets/crypto-utils/keystore/index.js +3 -0
  73. package/dist/packlets/crypto-utils/keystore/index.js.map +1 -0
  74. package/dist/packlets/crypto-utils/keystore/keyStore.js +633 -118
  75. package/dist/packlets/crypto-utils/keystore/keyStore.js.map +1 -0
  76. package/dist/packlets/crypto-utils/keystore/model.js +22 -1
  77. package/dist/packlets/crypto-utils/keystore/model.js.map +1 -0
  78. package/dist/packlets/crypto-utils/keystore/privateKeyStorage.js +21 -0
  79. package/dist/packlets/crypto-utils/keystore/privateKeyStorage.js.map +1 -0
  80. package/dist/packlets/crypto-utils/model.js +32 -0
  81. package/dist/packlets/crypto-utils/model.js.map +1 -0
  82. package/dist/packlets/crypto-utils/nodeCryptoProvider.js +270 -1
  83. package/dist/packlets/crypto-utils/nodeCryptoProvider.js.map +1 -0
  84. package/dist/packlets/crypto-utils/spkiHelpers.js +209 -0
  85. package/dist/packlets/crypto-utils/spkiHelpers.js.map +1 -0
  86. package/dist/packlets/csv/csvFileHelpers.js +0 -14
  87. package/dist/packlets/csv/csvFileHelpers.js.map +1 -0
  88. package/dist/packlets/csv/csvHelpers.js +14 -0
  89. package/dist/packlets/csv/csvHelpers.js.map +1 -0
  90. package/dist/packlets/csv/index.browser.js +1 -3
  91. package/dist/packlets/csv/index.browser.js.map +1 -0
  92. package/dist/packlets/csv/index.js.map +1 -0
  93. package/dist/packlets/experimental/extendedArray.js.map +1 -0
  94. package/dist/packlets/experimental/formatter.js.map +1 -0
  95. package/dist/packlets/experimental/index.js.map +1 -0
  96. package/dist/packlets/experimental/rangeOf.js.map +1 -0
  97. package/dist/packlets/hash/index.browser.js.map +1 -0
  98. package/dist/packlets/hash/index.js.map +1 -0
  99. package/dist/packlets/hash/index.node.js.map +1 -0
  100. package/dist/packlets/hash/md5Normalizer.browser.js.map +1 -0
  101. package/dist/packlets/hash/md5Normalizer.js.map +1 -0
  102. package/dist/packlets/mustache/index.js.map +1 -0
  103. package/dist/packlets/mustache/interfaces.js.map +1 -0
  104. package/dist/packlets/mustache/mustacheTemplate.js +42 -4
  105. package/dist/packlets/mustache/mustacheTemplate.js.map +1 -0
  106. package/dist/packlets/record-jar/index.browser.js +1 -3
  107. package/dist/packlets/record-jar/index.browser.js.map +1 -0
  108. package/dist/packlets/record-jar/index.js.map +1 -0
  109. package/dist/packlets/record-jar/recordJarFileHelpers.js +0 -18
  110. package/dist/packlets/record-jar/recordJarFileHelpers.js.map +1 -0
  111. package/dist/packlets/record-jar/recordJarHelpers.js +18 -0
  112. package/dist/packlets/record-jar/recordJarHelpers.js.map +1 -0
  113. package/dist/packlets/yaml/converters.js.map +1 -0
  114. package/dist/packlets/yaml/index.js +1 -0
  115. package/dist/packlets/yaml/index.js.map +1 -0
  116. package/dist/packlets/yaml/serializers.js +48 -0
  117. package/dist/packlets/yaml/serializers.js.map +1 -0
  118. package/dist/packlets/zip-file-tree/index.js.map +1 -0
  119. package/dist/packlets/zip-file-tree/zipFileTreeAccessors.js +2 -2
  120. package/dist/packlets/zip-file-tree/zipFileTreeAccessors.js.map +1 -0
  121. package/dist/packlets/zip-file-tree/zipFileTreeWriter.js.map +1 -0
  122. package/dist/ts-extras.d.ts +3880 -105
  123. package/dist/tsdoc-metadata.json +1 -1
  124. package/lib/index.browser.d.ts +4 -2
  125. package/lib/index.browser.d.ts.map +1 -0
  126. package/lib/index.browser.js +8 -3
  127. package/lib/index.browser.js.map +1 -0
  128. package/lib/index.d.ts.map +1 -0
  129. package/lib/index.js.map +1 -0
  130. package/lib/packlets/ai-assist/apiClient.d.ts +115 -32
  131. package/lib/packlets/ai-assist/apiClient.d.ts.map +1 -0
  132. package/lib/packlets/ai-assist/apiClient.js +888 -156
  133. package/lib/packlets/ai-assist/apiClient.js.map +1 -0
  134. package/lib/packlets/ai-assist/chatRequestBuilders.d.ts +149 -0
  135. package/lib/packlets/ai-assist/chatRequestBuilders.d.ts.map +1 -0
  136. package/lib/packlets/ai-assist/chatRequestBuilders.js +293 -0
  137. package/lib/packlets/ai-assist/chatRequestBuilders.js.map +1 -0
  138. package/lib/packlets/ai-assist/converters.d.ts +15 -1
  139. package/lib/packlets/ai-assist/converters.d.ts.map +1 -0
  140. package/lib/packlets/ai-assist/converters.js +47 -3
  141. package/lib/packlets/ai-assist/converters.js.map +1 -0
  142. package/lib/packlets/ai-assist/embeddingClient.d.ts +69 -0
  143. package/lib/packlets/ai-assist/embeddingClient.d.ts.map +1 -0
  144. package/lib/packlets/ai-assist/embeddingClient.js +349 -0
  145. package/lib/packlets/ai-assist/embeddingClient.js.map +1 -0
  146. package/lib/packlets/ai-assist/endpoint.d.ts +28 -0
  147. package/lib/packlets/ai-assist/endpoint.d.ts.map +1 -0
  148. package/lib/packlets/ai-assist/endpoint.js +82 -0
  149. package/lib/packlets/ai-assist/endpoint.js.map +1 -0
  150. package/lib/packlets/ai-assist/http.d.ts +24 -0
  151. package/lib/packlets/ai-assist/http.d.ts.map +1 -0
  152. package/lib/packlets/ai-assist/http.js +78 -0
  153. package/lib/packlets/ai-assist/http.js.map +1 -0
  154. package/lib/packlets/ai-assist/imageOptionsResolver.d.ts +66 -0
  155. package/lib/packlets/ai-assist/imageOptionsResolver.d.ts.map +1 -0
  156. package/lib/packlets/ai-assist/imageOptionsResolver.js +197 -0
  157. package/lib/packlets/ai-assist/imageOptionsResolver.js.map +1 -0
  158. package/lib/packlets/ai-assist/index.d.ts +10 -4
  159. package/lib/packlets/ai-assist/index.d.ts.map +1 -0
  160. package/lib/packlets/ai-assist/index.js +36 -1
  161. package/lib/packlets/ai-assist/index.js.map +1 -0
  162. package/lib/packlets/ai-assist/jsonCompletion.d.ts +93 -0
  163. package/lib/packlets/ai-assist/jsonCompletion.d.ts.map +1 -0
  164. package/lib/packlets/ai-assist/jsonCompletion.js +97 -0
  165. package/lib/packlets/ai-assist/jsonCompletion.js.map +1 -0
  166. package/lib/packlets/ai-assist/jsonResponse.d.ts +91 -0
  167. package/lib/packlets/ai-assist/jsonResponse.d.ts.map +1 -0
  168. package/lib/packlets/ai-assist/jsonResponse.js +154 -0
  169. package/lib/packlets/ai-assist/jsonResponse.js.map +1 -0
  170. package/lib/packlets/ai-assist/model.d.ts +1202 -12
  171. package/lib/packlets/ai-assist/model.d.ts.map +1 -0
  172. package/lib/packlets/ai-assist/model.js +198 -10
  173. package/lib/packlets/ai-assist/model.js.map +1 -0
  174. package/lib/packlets/ai-assist/registry.d.ts +56 -1
  175. package/lib/packlets/ai-assist/registry.d.ts.map +1 -0
  176. package/lib/packlets/ai-assist/registry.js +319 -13
  177. package/lib/packlets/ai-assist/registry.js.map +1 -0
  178. package/lib/packlets/ai-assist/sseParser.d.ts +45 -0
  179. package/lib/packlets/ai-assist/sseParser.d.ts.map +1 -0
  180. package/lib/packlets/ai-assist/sseParser.js +128 -0
  181. package/lib/packlets/ai-assist/sseParser.js.map +1 -0
  182. package/lib/packlets/ai-assist/streamingAdapters/anthropic.d.ts +72 -0
  183. package/lib/packlets/ai-assist/streamingAdapters/anthropic.d.ts.map +1 -0
  184. package/lib/packlets/ai-assist/streamingAdapters/anthropic.js +371 -0
  185. package/lib/packlets/ai-assist/streamingAdapters/anthropic.js.map +1 -0
  186. package/lib/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.d.ts +260 -0
  187. package/lib/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.d.ts.map +1 -0
  188. package/lib/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.js +694 -0
  189. package/lib/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.js.map +1 -0
  190. package/lib/packlets/ai-assist/streamingAdapters/common.d.ts +154 -0
  191. package/lib/packlets/ai-assist/streamingAdapters/common.d.ts.map +1 -0
  192. package/lib/packlets/ai-assist/streamingAdapters/common.js +193 -0
  193. package/lib/packlets/ai-assist/streamingAdapters/common.js.map +1 -0
  194. package/lib/packlets/ai-assist/streamingAdapters/gemini.d.ts +43 -0
  195. package/lib/packlets/ai-assist/streamingAdapters/gemini.d.ts.map +1 -0
  196. package/lib/packlets/ai-assist/streamingAdapters/gemini.js +207 -0
  197. package/lib/packlets/ai-assist/streamingAdapters/gemini.js.map +1 -0
  198. package/lib/packlets/ai-assist/streamingAdapters/openaiChat.d.ts +19 -0
  199. package/lib/packlets/ai-assist/streamingAdapters/openaiChat.d.ts.map +1 -0
  200. package/lib/packlets/ai-assist/streamingAdapters/openaiChat.js +173 -0
  201. package/lib/packlets/ai-assist/streamingAdapters/openaiChat.js.map +1 -0
  202. package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.d.ts +33 -0
  203. package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.d.ts.map +1 -0
  204. package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.js +389 -0
  205. package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.js.map +1 -0
  206. package/lib/packlets/ai-assist/streamingAdapters/proxy.d.ts +34 -0
  207. package/lib/packlets/ai-assist/streamingAdapters/proxy.d.ts.map +1 -0
  208. package/lib/packlets/ai-assist/streamingAdapters/proxy.js +176 -0
  209. package/lib/packlets/ai-assist/streamingAdapters/proxy.js.map +1 -0
  210. package/lib/packlets/ai-assist/streamingClient.d.ts +50 -0
  211. package/lib/packlets/ai-assist/streamingClient.d.ts.map +1 -0
  212. package/lib/packlets/ai-assist/streamingClient.js +146 -0
  213. package/lib/packlets/ai-assist/streamingClient.js.map +1 -0
  214. package/lib/packlets/ai-assist/thinkingOptionsResolver.d.ts +87 -0
  215. package/lib/packlets/ai-assist/thinkingOptionsResolver.d.ts.map +1 -0
  216. package/lib/packlets/ai-assist/thinkingOptionsResolver.js +294 -0
  217. package/lib/packlets/ai-assist/thinkingOptionsResolver.js.map +1 -0
  218. package/lib/packlets/ai-assist/toolFormats.d.ts +40 -9
  219. package/lib/packlets/ai-assist/toolFormats.d.ts.map +1 -0
  220. package/lib/packlets/ai-assist/toolFormats.js +107 -10
  221. package/lib/packlets/ai-assist/toolFormats.js.map +1 -0
  222. package/lib/packlets/conversion/converters.d.ts +8 -1
  223. package/lib/packlets/conversion/converters.d.ts.map +1 -0
  224. package/lib/packlets/conversion/converters.js +36 -2
  225. package/lib/packlets/conversion/converters.js.map +1 -0
  226. package/lib/packlets/conversion/index.d.ts.map +1 -0
  227. package/lib/packlets/conversion/index.js.map +1 -0
  228. package/lib/packlets/crypto-utils/constants.d.ts.map +1 -0
  229. package/lib/packlets/crypto-utils/constants.js.map +1 -0
  230. package/lib/packlets/crypto-utils/converters.d.ts +20 -1
  231. package/lib/packlets/crypto-utils/converters.d.ts.map +1 -0
  232. package/lib/packlets/crypto-utils/converters.js +43 -5
  233. package/lib/packlets/crypto-utils/converters.js.map +1 -0
  234. package/lib/packlets/crypto-utils/directEncryptionProvider.d.ts.map +1 -0
  235. package/lib/packlets/crypto-utils/directEncryptionProvider.js.map +1 -0
  236. package/lib/packlets/crypto-utils/encryptedFile.d.ts.map +1 -0
  237. package/lib/packlets/crypto-utils/encryptedFile.js.map +1 -0
  238. package/lib/packlets/crypto-utils/hpkeProvider.d.ts +142 -0
  239. package/lib/packlets/crypto-utils/hpkeProvider.d.ts.map +1 -0
  240. package/lib/packlets/crypto-utils/hpkeProvider.js +337 -0
  241. package/lib/packlets/crypto-utils/hpkeProvider.js.map +1 -0
  242. package/lib/packlets/crypto-utils/index.browser.d.ts +4 -1
  243. package/lib/packlets/crypto-utils/index.browser.d.ts.map +1 -0
  244. package/lib/packlets/crypto-utils/index.browser.js +21 -3
  245. package/lib/packlets/crypto-utils/index.browser.js.map +1 -0
  246. package/lib/packlets/crypto-utils/index.d.ts +3 -0
  247. package/lib/packlets/crypto-utils/index.d.ts.map +1 -0
  248. package/lib/packlets/crypto-utils/index.js +17 -1
  249. package/lib/packlets/crypto-utils/index.js.map +1 -0
  250. package/lib/packlets/crypto-utils/keyPairAlgorithmParams.d.ts +54 -0
  251. package/lib/packlets/crypto-utils/keyPairAlgorithmParams.d.ts.map +1 -0
  252. package/lib/packlets/crypto-utils/keyPairAlgorithmParams.js +74 -0
  253. package/lib/packlets/crypto-utils/keyPairAlgorithmParams.js.map +1 -0
  254. package/lib/packlets/crypto-utils/keystore/converters.d.ts +68 -6
  255. package/lib/packlets/crypto-utils/keystore/converters.d.ts.map +1 -0
  256. package/lib/packlets/crypto-utils/keystore/converters.js +101 -9
  257. package/lib/packlets/crypto-utils/keystore/converters.js.map +1 -0
  258. package/lib/packlets/crypto-utils/keystore/encryptedFilePrivateKeyStorage.d.ts +148 -0
  259. package/lib/packlets/crypto-utils/keystore/encryptedFilePrivateKeyStorage.d.ts.map +1 -0
  260. package/lib/packlets/crypto-utils/keystore/encryptedFilePrivateKeyStorage.js +324 -0
  261. package/lib/packlets/crypto-utils/keystore/encryptedFilePrivateKeyStorage.js.map +1 -0
  262. package/lib/packlets/crypto-utils/keystore/index.browser.d.ts +10 -0
  263. package/lib/packlets/crypto-utils/keystore/index.browser.d.ts.map +1 -0
  264. package/lib/packlets/crypto-utils/keystore/index.browser.js +76 -0
  265. package/lib/packlets/crypto-utils/keystore/index.browser.js.map +1 -0
  266. package/lib/packlets/crypto-utils/keystore/index.d.ts +2 -0
  267. package/lib/packlets/crypto-utils/keystore/index.d.ts.map +1 -0
  268. package/lib/packlets/crypto-utils/keystore/index.js +5 -1
  269. package/lib/packlets/crypto-utils/keystore/index.js.map +1 -0
  270. package/lib/packlets/crypto-utils/keystore/keyStore.d.ts +205 -13
  271. package/lib/packlets/crypto-utils/keystore/keyStore.d.ts.map +1 -0
  272. package/lib/packlets/crypto-utils/keystore/keyStore.js +639 -124
  273. package/lib/packlets/crypto-utils/keystore/keyStore.js.map +1 -0
  274. package/lib/packlets/crypto-utils/keystore/model.d.ts +275 -19
  275. package/lib/packlets/crypto-utils/keystore/model.d.ts.map +1 -0
  276. package/lib/packlets/crypto-utils/keystore/model.js +24 -2
  277. package/lib/packlets/crypto-utils/keystore/model.js.map +1 -0
  278. package/lib/packlets/crypto-utils/keystore/privateKeyStorage.d.ts +53 -0
  279. package/lib/packlets/crypto-utils/keystore/privateKeyStorage.d.ts.map +1 -0
  280. package/lib/packlets/crypto-utils/keystore/privateKeyStorage.js +22 -0
  281. package/lib/packlets/crypto-utils/keystore/privateKeyStorage.js.map +1 -0
  282. package/lib/packlets/crypto-utils/model.d.ts +348 -10
  283. package/lib/packlets/crypto-utils/model.d.ts.map +1 -0
  284. package/lib/packlets/crypto-utils/model.js +33 -1
  285. package/lib/packlets/crypto-utils/model.js.map +1 -0
  286. package/lib/packlets/crypto-utils/nodeCryptoProvider.d.ts +110 -2
  287. package/lib/packlets/crypto-utils/nodeCryptoProvider.d.ts.map +1 -0
  288. package/lib/packlets/crypto-utils/nodeCryptoProvider.js +269 -0
  289. package/lib/packlets/crypto-utils/nodeCryptoProvider.js.map +1 -0
  290. package/lib/packlets/crypto-utils/spkiHelpers.d.ts +110 -0
  291. package/lib/packlets/crypto-utils/spkiHelpers.d.ts.map +1 -0
  292. package/lib/packlets/crypto-utils/spkiHelpers.js +219 -0
  293. package/lib/packlets/crypto-utils/spkiHelpers.js.map +1 -0
  294. package/lib/packlets/csv/csvFileHelpers.d.ts +0 -10
  295. package/lib/packlets/csv/csvFileHelpers.d.ts.map +1 -0
  296. package/lib/packlets/csv/csvFileHelpers.js +0 -15
  297. package/lib/packlets/csv/csvFileHelpers.js.map +1 -0
  298. package/lib/packlets/csv/csvHelpers.d.ts +10 -0
  299. package/lib/packlets/csv/csvHelpers.d.ts.map +1 -0
  300. package/lib/packlets/csv/csvHelpers.js +15 -0
  301. package/lib/packlets/csv/csvHelpers.js.map +1 -0
  302. package/lib/packlets/csv/index.browser.d.ts +0 -1
  303. package/lib/packlets/csv/index.browser.d.ts.map +1 -0
  304. package/lib/packlets/csv/index.browser.js +1 -5
  305. package/lib/packlets/csv/index.browser.js.map +1 -0
  306. package/lib/packlets/csv/index.d.ts.map +1 -0
  307. package/lib/packlets/csv/index.js.map +1 -0
  308. package/lib/packlets/experimental/extendedArray.d.ts.map +1 -0
  309. package/lib/packlets/experimental/extendedArray.js.map +1 -0
  310. package/lib/packlets/experimental/formatter.d.ts.map +1 -0
  311. package/lib/packlets/experimental/formatter.js.map +1 -0
  312. package/lib/packlets/experimental/index.d.ts.map +1 -0
  313. package/lib/packlets/experimental/index.js.map +1 -0
  314. package/lib/packlets/experimental/rangeOf.d.ts.map +1 -0
  315. package/lib/packlets/experimental/rangeOf.js.map +1 -0
  316. package/lib/packlets/hash/index.browser.d.ts.map +1 -0
  317. package/lib/packlets/hash/index.browser.js.map +1 -0
  318. package/lib/packlets/hash/index.d.ts.map +1 -0
  319. package/lib/packlets/hash/index.js.map +1 -0
  320. package/lib/packlets/hash/index.node.d.ts.map +1 -0
  321. package/lib/packlets/hash/index.node.js.map +1 -0
  322. package/lib/packlets/hash/md5Normalizer.browser.d.ts.map +1 -0
  323. package/lib/packlets/hash/md5Normalizer.browser.js.map +1 -0
  324. package/lib/packlets/hash/md5Normalizer.d.ts.map +1 -0
  325. package/lib/packlets/hash/md5Normalizer.js.map +1 -0
  326. package/lib/packlets/mustache/index.d.ts +1 -1
  327. package/lib/packlets/mustache/index.d.ts.map +1 -0
  328. package/lib/packlets/mustache/index.js.map +1 -0
  329. package/lib/packlets/mustache/interfaces.d.ts +34 -0
  330. package/lib/packlets/mustache/interfaces.d.ts.map +1 -0
  331. package/lib/packlets/mustache/interfaces.js.map +1 -0
  332. package/lib/packlets/mustache/mustacheTemplate.d.ts +2 -0
  333. package/lib/packlets/mustache/mustacheTemplate.d.ts.map +1 -0
  334. package/lib/packlets/mustache/mustacheTemplate.js +42 -4
  335. package/lib/packlets/mustache/mustacheTemplate.js.map +1 -0
  336. package/lib/packlets/record-jar/index.browser.d.ts +0 -1
  337. package/lib/packlets/record-jar/index.browser.d.ts.map +1 -0
  338. package/lib/packlets/record-jar/index.browser.js +1 -5
  339. package/lib/packlets/record-jar/index.browser.js.map +1 -0
  340. package/lib/packlets/record-jar/index.d.ts.map +1 -0
  341. package/lib/packlets/record-jar/index.js.map +1 -0
  342. package/lib/packlets/record-jar/recordJarFileHelpers.d.ts +0 -11
  343. package/lib/packlets/record-jar/recordJarFileHelpers.d.ts.map +1 -0
  344. package/lib/packlets/record-jar/recordJarFileHelpers.js +0 -19
  345. package/lib/packlets/record-jar/recordJarFileHelpers.js.map +1 -0
  346. package/lib/packlets/record-jar/recordJarHelpers.d.ts +11 -0
  347. package/lib/packlets/record-jar/recordJarHelpers.d.ts.map +1 -0
  348. package/lib/packlets/record-jar/recordJarHelpers.js +19 -0
  349. package/lib/packlets/record-jar/recordJarHelpers.js.map +1 -0
  350. package/lib/packlets/yaml/converters.d.ts.map +1 -0
  351. package/lib/packlets/yaml/converters.js.map +1 -0
  352. package/lib/packlets/yaml/index.d.ts +1 -0
  353. package/lib/packlets/yaml/index.d.ts.map +1 -0
  354. package/lib/packlets/yaml/index.js +1 -0
  355. package/lib/packlets/yaml/index.js.map +1 -0
  356. package/lib/packlets/yaml/serializers.d.ts +45 -0
  357. package/lib/packlets/yaml/serializers.d.ts.map +1 -0
  358. package/lib/packlets/yaml/serializers.js +84 -0
  359. package/lib/packlets/yaml/serializers.js.map +1 -0
  360. package/lib/packlets/zip-file-tree/index.d.ts.map +1 -0
  361. package/lib/packlets/zip-file-tree/index.js.map +1 -0
  362. package/lib/packlets/zip-file-tree/zipFileTreeAccessors.d.ts +2 -2
  363. package/lib/packlets/zip-file-tree/zipFileTreeAccessors.d.ts.map +1 -0
  364. package/lib/packlets/zip-file-tree/zipFileTreeAccessors.js +2 -2
  365. package/lib/packlets/zip-file-tree/zipFileTreeAccessors.js.map +1 -0
  366. package/lib/packlets/zip-file-tree/zipFileTreeWriter.d.ts.map +1 -0
  367. package/lib/packlets/zip-file-tree/zipFileTreeWriter.js.map +1 -0
  368. package/package.json +20 -15
@@ -0,0 +1,368 @@
1
+ // Copyright (c) 2026 Erik Fortune
2
+ //
3
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ // of this software and associated documentation files (the "Software"), to deal
5
+ // in the Software without restriction, including without limitation the rights
6
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ // copies of the Software, and to permit persons to whom the Software is
8
+ // furnished to do so, subject to the following conditions:
9
+ //
10
+ // The above copyright notice and this permission notice shall be included in all
11
+ // copies or substantial portions of the Software.
12
+ //
13
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ // SOFTWARE.
20
+ var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
21
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
22
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
23
+ var m = o[Symbol.asyncIterator], i;
24
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
25
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
26
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
27
+ };
28
+ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
29
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
30
+ var g = generator.apply(thisArg, _arguments || []), i, q = [];
31
+ return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
32
+ function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
33
+ function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
34
+ function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
35
+ function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
36
+ function fulfill(value) { resume("next", value); }
37
+ function reject(value) { resume("throw", value); }
38
+ function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
39
+ };
40
+ /**
41
+ * Streaming adapter for the Anthropic Messages API. Handles server tool
42
+ * use (e.g. `web_search`) as unified `tool-event` markers and client-defined
43
+ * tool calls (type `tool_use`) with B4 thinking-block accumulation.
44
+ *
45
+ * The ordered accumulation buffer preserves all content blocks from the
46
+ * assistant turn in their original stream positions. The C3 continuation
47
+ * builder reads this buffer to reconstruct the assistant turn for the
48
+ * follow-up request.
49
+ *
50
+ * @packageDocumentation
51
+ */
52
+ import { succeed, Validators } from '@fgv/ts-utils';
53
+ import { buildAnthropicMessages } from '../chatRequestBuilders';
54
+ import { parseSseEventJson, readSseEvents } from '../sseParser';
55
+ import { toAnthropicTools } from '../toolFormats';
56
+ import { anthropicEffortToBudgetTokens } from '../thinkingOptionsResolver';
57
+ import { MALFORMED_TOOL_USE_WARN_TAG, UNRECOGNIZED_EVENT_WARN_TAG, formatUnrecognizedEventPayloadPreview, openSseConnection, validateEventPayload } from './common';
58
+ const anthropicContentBlockInner = Validators.object({
59
+ type: Validators.string.optional(),
60
+ name: Validators.string.optional(),
61
+ id: Validators.string.optional(),
62
+ data: Validators.string.optional()
63
+ }, { options: { optionalFields: ['type', 'name', 'id', 'data'] } });
64
+ const anthropicContentBlockStartPayload = Validators.object({
65
+ index: Validators.number.optional(),
66
+ content_block: anthropicContentBlockInner
67
+ }, { options: { optionalFields: ['index'] } });
68
+ const anthropicContentBlockDeltaInner = Validators.object({
69
+ type: Validators.string.optional(),
70
+ text: Validators.string.optional(),
71
+ partial_json: Validators.string.optional(),
72
+ thinking: Validators.string.optional(),
73
+ signature: Validators.string.optional()
74
+ }, { options: { optionalFields: ['type', 'text', 'partial_json', 'thinking', 'signature'] } });
75
+ const anthropicContentBlockDeltaPayload = Validators.object({
76
+ index: Validators.number.optional(),
77
+ delta: anthropicContentBlockDeltaInner
78
+ }, { options: { optionalFields: ['index'] } });
79
+ const anthropicContentBlockStopPayload = Validators.object({ index: Validators.number.optional() }, { options: { optionalFields: ['index'] } });
80
+ const anthropicMessageDeltaInner = Validators.object({ stop_reason: Validators.string.optional() }, { options: { optionalFields: ['stop_reason'] } });
81
+ const anthropicMessageDeltaPayload = Validators.object({
82
+ delta: anthropicMessageDeltaInner
83
+ });
84
+ const anthropicErrorInner = Validators.object({ message: Validators.string.optional() }, { options: { optionalFields: ['message'] } });
85
+ const anthropicErrorPayload = Validators.object({ error: anthropicErrorInner.optional() }, { options: { optionalFields: ['error'] } });
86
+ // ============================================================================
87
+ // Stream translator
88
+ // ============================================================================
89
+ /**
90
+ * Recognized Anthropic Messages API SSE event names. Anything not in this set surfaces a
91
+ * one-time `logger.warn` per stream — same rationale as the OpenAI Responses adapter's
92
+ * `RECOGNIZED_OPENAI_RESPONSES_EVENTS` allowlist in `openaiResponses.ts`. Add to this set
93
+ * when a new event type is observed and confirmed safe to ignore.
94
+ *
95
+ * @internal
96
+ */
97
+ const RECOGNIZED_ANTHROPIC_EVENTS = new Set([
98
+ // ---- handled by the translator ----
99
+ 'content_block_start',
100
+ 'content_block_delta',
101
+ 'content_block_stop',
102
+ 'message_delta',
103
+ 'message_stop',
104
+ 'error',
105
+ // ---- lifecycle / heartbeats: intentionally silent ----
106
+ 'message_start',
107
+ 'ping'
108
+ ]);
109
+ /**
110
+ * Translates an Anthropic Messages API SSE stream into unified events.
111
+ *
112
+ * Maintains an ordered accumulation buffer (keyed by SSE `index`) for all
113
+ * content blocks: `thinking`, `redacted_thinking`, `text`, and `tool_use`.
114
+ * The buffer is available on the returned generator via `.accumulationBuffer`.
115
+ *
116
+ * Unrecognized event names are reported once per stream via `logger?.warn` —
117
+ * see {@link RECOGNIZED_ANTHROPIC_EVENTS}.
118
+ *
119
+ * @internal
120
+ */
121
+ function translateAnthropicStream(response, accumulationBuffer, logger) {
122
+ return __asyncGenerator(this, arguments, function* translateAnthropicStream_1() {
123
+ var _a, e_1, _b, _c;
124
+ var _d, _e, _f, _g;
125
+ let fullText = '';
126
+ let truncated = false;
127
+ let stopped = false;
128
+ // Track unrecognized event names we have already warned about, so a hot stream of
129
+ // an unknown event type produces exactly one log line per name per stream.
130
+ const warnedEvents = new Set();
131
+ try {
132
+ /* c8 ignore next - body is non-null at this point per openSseConnection */
133
+ if (!response.body)
134
+ return yield __await(void 0);
135
+ try {
136
+ for (var _h = true, _j = __asyncValues(readSseEvents(response.body)), _k; _k = yield __await(_j.next()), _a = _k.done, !_a; _h = true) {
137
+ _c = _k.value;
138
+ _h = false;
139
+ const message = _c;
140
+ const eventName = message.event;
141
+ if (eventName === 'content_block_start') {
142
+ const payload = validateEventPayload(parseSseEventJson(message.data), anthropicContentBlockStartPayload);
143
+ /* c8 ignore next 1 - defensive: payload null branch unreachable after validation */
144
+ if (!payload)
145
+ continue;
146
+ const { index: rawIndex, content_block: block } = payload;
147
+ const index = rawIndex !== null && rawIndex !== void 0 ? rawIndex : 0;
148
+ if (block.type === 'thinking') {
149
+ accumulationBuffer.set(index, { type: 'thinking', thinking: '', signature: '' });
150
+ }
151
+ else if (block.type === 'redacted_thinking') {
152
+ accumulationBuffer.set(index, {
153
+ type: 'redacted_thinking',
154
+ /* c8 ignore next 1 - defensive: Anthropic always provides data for redacted_thinking */
155
+ data: (_d = block.data) !== null && _d !== void 0 ? _d : ''
156
+ });
157
+ }
158
+ else if (block.type === 'text') {
159
+ accumulationBuffer.set(index, { type: 'text', text: '' });
160
+ }
161
+ else if (block.type === 'tool_use') {
162
+ // A tool_use block_start MUST carry a non-empty id and name: the id is the
163
+ // sole correlation key for the follow-up tool_result, and dropping the block
164
+ // silently (then ignoring its input_json_delta chunks at the delta handler
165
+ // below) is exactly how an orphaned block leaves the harness without a clean
166
+ // id and corrupts the continuation. Surface it loudly instead of dropping it.
167
+ if (block.id && block.name) {
168
+ accumulationBuffer.set(index, {
169
+ type: 'tool_use',
170
+ id: block.id,
171
+ name: block.name,
172
+ argsBuffer: ''
173
+ });
174
+ yield yield __await({ type: 'client-tool-call-start', toolName: block.name, callId: block.id });
175
+ }
176
+ else {
177
+ logger === null || logger === void 0 ? void 0 : logger.warn(`${MALFORMED_TOOL_USE_WARN_TAG} Anthropic streaming adapter: tool_use content_block_start ` +
178
+ `at index ${index} is missing a usable id and/or name ` +
179
+ `(id=${JSON.stringify(block.id)}, name=${JSON.stringify(block.name)}). ` +
180
+ `No client tool call will be issued for this block; its argument deltas are dropped. ` +
181
+ `This usually indicates provider drift or a truncated stream.`);
182
+ }
183
+ }
184
+ else if (block.type === 'server_tool_use' && block.name === 'web_search') {
185
+ yield yield __await({ type: 'tool-event', toolType: 'web_search', phase: 'started' });
186
+ }
187
+ else if (block.type === 'web_search_tool_result') {
188
+ yield yield __await({ type: 'tool-event', toolType: 'web_search', phase: 'completed' });
189
+ }
190
+ }
191
+ else if (eventName === 'content_block_delta') {
192
+ const payload = validateEventPayload(parseSseEventJson(message.data), anthropicContentBlockDeltaPayload);
193
+ /* c8 ignore next 1 - defensive: payload null branch unreachable after validation */
194
+ if (!payload)
195
+ continue;
196
+ const { index: rawDeltaIndex, delta } = payload;
197
+ const index = rawDeltaIndex !== null && rawDeltaIndex !== void 0 ? rawDeltaIndex : 0;
198
+ const block = accumulationBuffer.get(index);
199
+ if (delta.type === 'text_delta' && typeof delta.text === 'string') {
200
+ /* c8 ignore next 1 - defensive: delta arrives only after block_start sets buffer entry */
201
+ if ((block === null || block === void 0 ? void 0 : block.type) === 'text') {
202
+ block.text += delta.text;
203
+ }
204
+ if (delta.text.length > 0) {
205
+ fullText += delta.text;
206
+ yield yield __await({ type: 'text-delta', delta: delta.text });
207
+ }
208
+ }
209
+ else if (delta.type === 'input_json_delta' && typeof delta.partial_json === 'string') {
210
+ /* c8 ignore next 1 - defensive: delta arrives only after block_start sets buffer entry */
211
+ if ((block === null || block === void 0 ? void 0 : block.type) === 'tool_use') {
212
+ block.argsBuffer += delta.partial_json;
213
+ }
214
+ }
215
+ else if (delta.type === 'thinking_delta' && typeof delta.thinking === 'string') {
216
+ /* c8 ignore next 1 - defensive: delta arrives only after block_start sets buffer entry */
217
+ if ((block === null || block === void 0 ? void 0 : block.type) === 'thinking') {
218
+ block.thinking += delta.thinking;
219
+ }
220
+ }
221
+ else if (delta.type === 'signature_delta' && typeof delta.signature === 'string') {
222
+ // CRITICAL (E5): signature must be APPENDED, not overwritten.
223
+ // The signature is base64 arriving in multiple chunks.
224
+ // Overwriting produces a truncated signature that Anthropic rejects with HTTP 400.
225
+ /* c8 ignore next 1 - defensive: delta arrives only after block_start sets buffer entry */
226
+ if ((block === null || block === void 0 ? void 0 : block.type) === 'thinking') {
227
+ block.signature += delta.signature;
228
+ }
229
+ }
230
+ }
231
+ else if (eventName === 'content_block_stop') {
232
+ const payload = validateEventPayload(parseSseEventJson(message.data), anthropicContentBlockStopPayload);
233
+ /* c8 ignore next 1 - defensive: payload null branch unreachable after validation */
234
+ if (!payload)
235
+ continue;
236
+ /* c8 ignore next 1 - defensive: payload.index ?? 0 null branch is unreachable */
237
+ const block = accumulationBuffer.get((_e = payload.index) !== null && _e !== void 0 ? _e : 0);
238
+ /* c8 ignore next 1 - defensive: block always exists when block_stop follows block_start */
239
+ if ((block === null || block === void 0 ? void 0 : block.type) === 'tool_use') {
240
+ let args;
241
+ try {
242
+ /* c8 ignore next 1 - defensive: argsBuffer || '{}' empty-string branch unreachable in tests */
243
+ const parsed = JSON.parse(block.argsBuffer || '{}');
244
+ /* c8 ignore start - defensive: non-object/malformed parse defaults to empty object */
245
+ args =
246
+ parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)
247
+ ? parsed
248
+ : {};
249
+ }
250
+ catch (_l) {
251
+ args = {};
252
+ }
253
+ /* c8 ignore stop */
254
+ yield yield __await({ type: 'client-tool-call-done', toolName: block.name, callId: block.id, args });
255
+ }
256
+ }
257
+ else if (eventName === 'message_delta') {
258
+ const payload = validateEventPayload(parseSseEventJson(message.data), anthropicMessageDeltaPayload);
259
+ /* c8 ignore next 1 - defensive: payload?.delta null branch unreachable after validation */
260
+ if ((payload === null || payload === void 0 ? void 0 : payload.delta.stop_reason) === 'max_tokens') {
261
+ truncated = true;
262
+ }
263
+ }
264
+ else if (eventName === 'message_stop') {
265
+ stopped = true;
266
+ }
267
+ else if (eventName === 'error') {
268
+ const payload = validateEventPayload(parseSseEventJson(message.data), anthropicErrorPayload);
269
+ yield yield __await({
270
+ type: 'error',
271
+ /* c8 ignore next 1 - defensive: payload?.error null branch unreachable after validation */
272
+ message: (_g = (_f = payload === null || payload === void 0 ? void 0 : payload.error) === null || _f === void 0 ? void 0 : _f.message) !== null && _g !== void 0 ? _g : 'Anthropic stream returned an error event'
273
+ });
274
+ return yield __await(void 0);
275
+ }
276
+ else if (typeof eventName === 'string' &&
277
+ !RECOGNIZED_ANTHROPIC_EVENTS.has(eventName) &&
278
+ !warnedEvents.has(eventName)) {
279
+ // Empirical drift instrument: an unrecognized Anthropic event surfaces as a one-time
280
+ // warning per stream. Update RECOGNIZED_ANTHROPIC_EVENTS once the new event is either
281
+ // handled or confirmed safe to ignore.
282
+ warnedEvents.add(eventName);
283
+ logger === null || logger === void 0 ? void 0 : logger.warn(`${UNRECOGNIZED_EVENT_WARN_TAG} Anthropic streaming adapter: unrecognized SSE event ` +
284
+ `'${eventName}'. ` +
285
+ `payload preview: ${formatUnrecognizedEventPayloadPreview(message.data)}. ` +
286
+ `This may indicate provider drift — if the new event carries data the adapter ` +
287
+ `should surface, add a handler; otherwise add the name to ` +
288
+ `RECOGNIZED_ANTHROPIC_EVENTS.`);
289
+ }
290
+ }
291
+ }
292
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
293
+ finally {
294
+ try {
295
+ if (!_h && !_a && (_b = _j.return)) yield __await(_b.call(_j));
296
+ }
297
+ finally { if (e_1) throw e_1.error; }
298
+ }
299
+ }
300
+ catch (err) /* c8 ignore start - defensive: stream errors are always Error instances */ {
301
+ yield yield __await({ type: 'error', message: err instanceof Error ? err.message : String(err) });
302
+ return yield __await(void 0);
303
+ } /* c8 ignore stop */
304
+ if (stopped) {
305
+ yield yield __await({ type: 'done', truncated, fullText });
306
+ }
307
+ else {
308
+ yield yield __await({ type: 'error', message: 'Anthropic stream ended without a message_stop event' });
309
+ }
310
+ });
311
+ }
312
+ // ============================================================================
313
+ // Per-format request caller
314
+ // ============================================================================
315
+ /**
316
+ * Issues a streaming Anthropic Messages request and returns the
317
+ * unified-event iterable on success.
318
+ *
319
+ * @internal
320
+ */
321
+ export async function callAnthropicStream(config, prompt, messagesBefore, temperature, tools, logger, signal, resolvedThinking, accumulationBuffer, continuationMessages) {
322
+ const url = `${config.baseUrl}/messages`;
323
+ const messages = buildAnthropicMessages(prompt, {
324
+ head: messagesBefore,
325
+ rawTail: continuationMessages
326
+ });
327
+ const body = {
328
+ model: config.model,
329
+ system: prompt.system,
330
+ messages,
331
+ max_tokens: 4096,
332
+ stream: true
333
+ };
334
+ // Temperature is sent only when explicitly provided (Claude-5 rejects any temperature). When
335
+ // thinking is active it is also rejected — the completion/streaming paths validate this upstream,
336
+ // and the effort gate here is the safety net for the (unguarded) client-tool path.
337
+ if ((resolvedThinking === null || resolvedThinking === void 0 ? void 0 : resolvedThinking.anthropicEffort) === undefined) {
338
+ if (temperature !== undefined) {
339
+ body.temperature = temperature;
340
+ }
341
+ }
342
+ if ((resolvedThinking === null || resolvedThinking === void 0 ? void 0 : resolvedThinking.anthropicEffort) !== undefined) {
343
+ body.thinking = {
344
+ type: 'enabled',
345
+ budget_tokens: anthropicEffortToBudgetTokens(resolvedThinking.anthropicEffort)
346
+ };
347
+ }
348
+ if ((resolvedThinking === null || resolvedThinking === void 0 ? void 0 : resolvedThinking.otherParams) !== undefined) {
349
+ Object.assign(body, resolvedThinking.otherParams);
350
+ }
351
+ if (tools && tools.length > 0) {
352
+ body.tools = toAnthropicTools(tools);
353
+ }
354
+ const headers = {
355
+ 'x-api-key': config.apiKey,
356
+ 'anthropic-version': '2023-06-01',
357
+ 'anthropic-dangerous-direct-browser-access': 'true'
358
+ };
359
+ /* c8 ignore next 4 - optional logger diagnostic output */
360
+ if (logger) {
361
+ const toolTypes = tools && tools.length > 0 ? tools.map((t) => t.type).join(',') : 'none';
362
+ logger.info(`Anthropic streaming: model=${config.model}, tools=${toolTypes}`);
363
+ }
364
+ const buffer = accumulationBuffer !== null && accumulationBuffer !== void 0 ? accumulationBuffer : new Map();
365
+ const conn = await openSseConnection(url, headers, body, logger, signal);
366
+ return conn.onSuccess((response) => succeed(translateAnthropicStream(response, buffer, logger)));
367
+ }
368
+ //# sourceMappingURL=anthropic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../../../src/packlets/ai-assist/streamingAdapters/anthropic.ts"],"names":[],"mappings":"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","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 * Streaming adapter for the Anthropic Messages API. Handles server tool\n * use (e.g. `web_search`) as unified `tool-event` markers and client-defined\n * tool calls (type `tool_use`) with B4 thinking-block accumulation.\n *\n * The ordered accumulation buffer preserves all content blocks from the\n * assistant turn in their original stream positions. The C3 continuation\n * builder reads this buffer to reconstruct the assistant turn for the\n * follow-up request.\n *\n * @packageDocumentation\n */\n\nimport { type Logging, Result, succeed, type Validator, Validators } from '@fgv/ts-utils';\nimport { type JsonObject } from '@fgv/ts-json-base';\n\nimport { buildAnthropicMessages } from '../chatRequestBuilders';\nimport { AiPrompt, type AiToolConfig, type IAiStreamEvent, type IChatMessage } from '../model';\nimport { parseSseEventJson, readSseEvents } from '../sseParser';\nimport { toAnthropicTools } from '../toolFormats';\nimport { anthropicEffortToBudgetTokens, type IResolvedThinkingConfig } from '../thinkingOptionsResolver';\nimport {\n IStreamApiConfig,\n MALFORMED_TOOL_USE_WARN_TAG,\n UNRECOGNIZED_EVENT_WARN_TAG,\n formatUnrecognizedEventPayloadPreview,\n openSseConnection,\n validateEventPayload\n} from './common';\n\n// ============================================================================\n// Accumulated block types (internal — used by C3 continuation builder)\n// ============================================================================\n\n/**\n * An accumulated `thinking` block from the assistant turn. The `thinking` text\n * and `signature` are both concatenated across their respective delta events.\n * The full block is passed to the C3 continuation builder for round-trip preservation.\n * @internal\n */\nexport interface IAccumulatedThinkingBlock {\n readonly type: 'thinking';\n thinking: string;\n signature: string;\n}\n\n/**\n * An accumulated `redacted_thinking` block from the assistant turn. The `data`\n * field is opaque and arrives complete in the `content_block_start` event — no\n * delta events follow. Passed through unmodified to the C3 continuation builder.\n * @internal\n */\nexport interface IAccumulatedRedactedThinkingBlock {\n readonly type: 'redacted_thinking';\n readonly data: string;\n}\n\n/**\n * An accumulated `text` block from the assistant turn.\n * @internal\n */\nexport interface IAccumulatedTextBlock {\n readonly type: 'text';\n text: string;\n}\n\n/**\n * An accumulated `tool_use` block from the assistant turn (client-defined tool call).\n * The `argsBuffer` is the concatenation of all `input_json_delta` chunks.\n * @internal\n */\nexport interface IAccumulatedToolUseBlock {\n readonly type: 'tool_use';\n readonly id: string;\n readonly name: string;\n argsBuffer: string;\n}\n\n/**\n * Discriminated union of all accumulated Anthropic content block types.\n * The ordered accumulation buffer is a `Map<number, IAccumulatedBlock>` keyed\n * by the SSE `index` field from `content_block_start` events.\n * @internal\n */\nexport type IAccumulatedBlock =\n | IAccumulatedThinkingBlock\n | IAccumulatedRedactedThinkingBlock\n | IAccumulatedTextBlock\n | IAccumulatedToolUseBlock;\n\n// ============================================================================\n// Event payload shapes\n// ============================================================================\n\n/**\n * Payload of a `content_block_start` SSE event with the `index` field.\n * The `index` field is optional for backward compatibility with providers that\n * omit it; absent index defaults to 0 in the stream translator.\n * @internal\n */\ninterface IAnthropicContentBlockStartPayload {\n readonly index?: number;\n readonly content_block: {\n readonly type?: string;\n readonly name?: string;\n readonly id?: string;\n readonly data?: string;\n };\n}\n\n/**\n * Payload of a `content_block_delta` SSE event. Various delta types are\n * discriminated on `delta.type`:\n * - `text_delta`: text content\n * - `input_json_delta`: tool argument accumulation\n * - `thinking_delta`: thinking text accumulation\n * - `signature_delta`: thinking signature accumulation (MUST be appended, not overwritten)\n *\n * The `index` field is optional; absent index defaults to 0 in the stream translator.\n * @internal\n */\ninterface IAnthropicContentBlockDeltaPayload {\n readonly index?: number;\n readonly delta: {\n readonly type?: string;\n readonly text?: string;\n readonly partial_json?: string;\n readonly thinking?: string;\n readonly signature?: string;\n };\n}\n\n/**\n * Payload of a `content_block_stop` SSE event.\n * The `index` field is optional; absent index defaults to 0 in the stream translator.\n * @internal\n */\ninterface IAnthropicContentBlockStopPayload {\n readonly index?: number;\n}\n\n/**\n * Payload of a `message_delta` SSE event carrying the final stop reason.\n * @internal\n */\ninterface IAnthropicMessageDeltaPayload {\n readonly delta: { readonly stop_reason?: string };\n}\n\n/**\n * Payload of an `error` SSE event.\n * @internal\n */\ninterface IAnthropicErrorPayload {\n readonly error?: { readonly message?: string };\n}\n\nconst anthropicContentBlockInner: Validator<{\n type?: string;\n name?: string;\n id?: string;\n data?: string;\n}> = Validators.object<{ type?: string; name?: string; id?: string; data?: string }>(\n {\n type: Validators.string.optional(),\n name: Validators.string.optional(),\n id: Validators.string.optional(),\n data: Validators.string.optional()\n },\n { options: { optionalFields: ['type', 'name', 'id', 'data'] } }\n);\n\nconst anthropicContentBlockStartPayload: Validator<IAnthropicContentBlockStartPayload> =\n Validators.object<IAnthropicContentBlockStartPayload>(\n {\n index: Validators.number.optional(),\n content_block: anthropicContentBlockInner\n },\n { options: { optionalFields: ['index'] } }\n );\n\nconst anthropicContentBlockDeltaInner: Validator<{\n type?: string;\n text?: string;\n partial_json?: string;\n thinking?: string;\n signature?: string;\n}> = Validators.object<{\n type?: string;\n text?: string;\n partial_json?: string;\n thinking?: string;\n signature?: string;\n}>(\n {\n type: Validators.string.optional(),\n text: Validators.string.optional(),\n partial_json: Validators.string.optional(),\n thinking: Validators.string.optional(),\n signature: Validators.string.optional()\n },\n { options: { optionalFields: ['type', 'text', 'partial_json', 'thinking', 'signature'] } }\n);\n\nconst anthropicContentBlockDeltaPayload: Validator<IAnthropicContentBlockDeltaPayload> =\n Validators.object<IAnthropicContentBlockDeltaPayload>(\n {\n index: Validators.number.optional(),\n delta: anthropicContentBlockDeltaInner\n },\n { options: { optionalFields: ['index'] } }\n );\n\nconst anthropicContentBlockStopPayload: Validator<IAnthropicContentBlockStopPayload> =\n Validators.object<IAnthropicContentBlockStopPayload>(\n { index: Validators.number.optional() },\n { options: { optionalFields: ['index'] } }\n );\n\nconst anthropicMessageDeltaInner: Validator<{ stop_reason?: string }> = Validators.object<{\n stop_reason?: string;\n}>({ stop_reason: Validators.string.optional() }, { options: { optionalFields: ['stop_reason'] } });\n\nconst anthropicMessageDeltaPayload: Validator<IAnthropicMessageDeltaPayload> =\n Validators.object<IAnthropicMessageDeltaPayload>({\n delta: anthropicMessageDeltaInner\n });\n\nconst anthropicErrorInner: Validator<{ message?: string }> = Validators.object<{ message?: string }>(\n { message: Validators.string.optional() },\n { options: { optionalFields: ['message'] } }\n);\n\nconst anthropicErrorPayload: Validator<IAnthropicErrorPayload> = Validators.object<IAnthropicErrorPayload>(\n { error: anthropicErrorInner.optional() },\n { options: { optionalFields: ['error'] } }\n);\n\n// ============================================================================\n// Stream translator\n// ============================================================================\n\n/**\n * Recognized Anthropic Messages API SSE event names. Anything not in this set surfaces a\n * one-time `logger.warn` per stream — same rationale as the OpenAI Responses adapter's\n * `RECOGNIZED_OPENAI_RESPONSES_EVENTS` allowlist in `openaiResponses.ts`. Add to this set\n * when a new event type is observed and confirmed safe to ignore.\n *\n * @internal\n */\nconst RECOGNIZED_ANTHROPIC_EVENTS: ReadonlySet<string> = new Set<string>([\n // ---- handled by the translator ----\n 'content_block_start',\n 'content_block_delta',\n 'content_block_stop',\n 'message_delta',\n 'message_stop',\n 'error',\n // ---- lifecycle / heartbeats: intentionally silent ----\n 'message_start',\n 'ping'\n]);\n\n/**\n * Translates an Anthropic Messages API SSE stream into unified events.\n *\n * Maintains an ordered accumulation buffer (keyed by SSE `index`) for all\n * content blocks: `thinking`, `redacted_thinking`, `text`, and `tool_use`.\n * The buffer is available on the returned generator via `.accumulationBuffer`.\n *\n * Unrecognized event names are reported once per stream via `logger?.warn` —\n * see {@link RECOGNIZED_ANTHROPIC_EVENTS}.\n *\n * @internal\n */\nasync function* translateAnthropicStream(\n response: Response,\n accumulationBuffer: Map<number, IAccumulatedBlock>,\n logger?: Logging.ILogger\n): AsyncGenerator<IAiStreamEvent> {\n let fullText = '';\n let truncated = false;\n let stopped = false;\n // Track unrecognized event names we have already warned about, so a hot stream of\n // an unknown event type produces exactly one log line per name per stream.\n const warnedEvents = new Set<string>();\n\n try {\n /* c8 ignore next - body is non-null at this point per openSseConnection */\n if (!response.body) return;\n for await (const message of readSseEvents(response.body)) {\n const eventName = message.event;\n\n if (eventName === 'content_block_start') {\n const payload = validateEventPayload(\n parseSseEventJson(message.data),\n anthropicContentBlockStartPayload\n );\n /* c8 ignore next 1 - defensive: payload null branch unreachable after validation */\n if (!payload) continue;\n const { index: rawIndex, content_block: block } = payload;\n const index = rawIndex ?? 0;\n\n if (block.type === 'thinking') {\n accumulationBuffer.set(index, { type: 'thinking', thinking: '', signature: '' });\n } else if (block.type === 'redacted_thinking') {\n accumulationBuffer.set(index, {\n type: 'redacted_thinking',\n /* c8 ignore next 1 - defensive: Anthropic always provides data for redacted_thinking */\n data: block.data ?? ''\n });\n } else if (block.type === 'text') {\n accumulationBuffer.set(index, { type: 'text', text: '' });\n } else if (block.type === 'tool_use') {\n // A tool_use block_start MUST carry a non-empty id and name: the id is the\n // sole correlation key for the follow-up tool_result, and dropping the block\n // silently (then ignoring its input_json_delta chunks at the delta handler\n // below) is exactly how an orphaned block leaves the harness without a clean\n // id and corrupts the continuation. Surface it loudly instead of dropping it.\n if (block.id && block.name) {\n accumulationBuffer.set(index, {\n type: 'tool_use',\n id: block.id,\n name: block.name,\n argsBuffer: ''\n });\n yield { type: 'client-tool-call-start', toolName: block.name, callId: block.id };\n } else {\n logger?.warn(\n `${MALFORMED_TOOL_USE_WARN_TAG} Anthropic streaming adapter: tool_use content_block_start ` +\n `at index ${index} is missing a usable id and/or name ` +\n `(id=${JSON.stringify(block.id)}, name=${JSON.stringify(block.name)}). ` +\n `No client tool call will be issued for this block; its argument deltas are dropped. ` +\n `This usually indicates provider drift or a truncated stream.`\n );\n }\n } else if (block.type === 'server_tool_use' && block.name === 'web_search') {\n yield { type: 'tool-event', toolType: 'web_search', phase: 'started' };\n } else if (block.type === 'web_search_tool_result') {\n yield { type: 'tool-event', toolType: 'web_search', phase: 'completed' };\n }\n } else if (eventName === 'content_block_delta') {\n const payload = validateEventPayload(\n parseSseEventJson(message.data),\n anthropicContentBlockDeltaPayload\n );\n /* c8 ignore next 1 - defensive: payload null branch unreachable after validation */\n if (!payload) continue;\n const { index: rawDeltaIndex, delta } = payload;\n const index = rawDeltaIndex ?? 0;\n const block = accumulationBuffer.get(index);\n\n if (delta.type === 'text_delta' && typeof delta.text === 'string') {\n /* c8 ignore next 1 - defensive: delta arrives only after block_start sets buffer entry */\n if (block?.type === 'text') {\n block.text += delta.text;\n }\n if (delta.text.length > 0) {\n fullText += delta.text;\n yield { type: 'text-delta', delta: delta.text };\n }\n } else if (delta.type === 'input_json_delta' && typeof delta.partial_json === 'string') {\n /* c8 ignore next 1 - defensive: delta arrives only after block_start sets buffer entry */\n if (block?.type === 'tool_use') {\n block.argsBuffer += delta.partial_json;\n }\n } else if (delta.type === 'thinking_delta' && typeof delta.thinking === 'string') {\n /* c8 ignore next 1 - defensive: delta arrives only after block_start sets buffer entry */\n if (block?.type === 'thinking') {\n block.thinking += delta.thinking;\n }\n } else if (delta.type === 'signature_delta' && typeof delta.signature === 'string') {\n // CRITICAL (E5): signature must be APPENDED, not overwritten.\n // The signature is base64 arriving in multiple chunks.\n // Overwriting produces a truncated signature that Anthropic rejects with HTTP 400.\n /* c8 ignore next 1 - defensive: delta arrives only after block_start sets buffer entry */\n if (block?.type === 'thinking') {\n block.signature += delta.signature;\n }\n }\n } else if (eventName === 'content_block_stop') {\n const payload = validateEventPayload(\n parseSseEventJson(message.data),\n anthropicContentBlockStopPayload\n );\n /* c8 ignore next 1 - defensive: payload null branch unreachable after validation */\n if (!payload) continue;\n /* c8 ignore next 1 - defensive: payload.index ?? 0 null branch is unreachable */\n const block = accumulationBuffer.get(payload.index ?? 0);\n /* c8 ignore next 1 - defensive: block always exists when block_stop follows block_start */\n if (block?.type === 'tool_use') {\n let args: JsonObject;\n try {\n /* c8 ignore next 1 - defensive: argsBuffer || '{}' empty-string branch unreachable in tests */\n const parsed = JSON.parse(block.argsBuffer || '{}') as unknown;\n /* c8 ignore start - defensive: non-object/malformed parse defaults to empty object */\n args =\n parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)\n ? (parsed as JsonObject)\n : {};\n } catch {\n args = {};\n }\n /* c8 ignore stop */\n yield { type: 'client-tool-call-done', toolName: block.name, callId: block.id, args };\n }\n } else if (eventName === 'message_delta') {\n const payload = validateEventPayload(parseSseEventJson(message.data), anthropicMessageDeltaPayload);\n /* c8 ignore next 1 - defensive: payload?.delta null branch unreachable after validation */\n if (payload?.delta.stop_reason === 'max_tokens') {\n truncated = true;\n }\n } else if (eventName === 'message_stop') {\n stopped = true;\n } else if (eventName === 'error') {\n const payload = validateEventPayload(parseSseEventJson(message.data), anthropicErrorPayload);\n yield {\n type: 'error',\n /* c8 ignore next 1 - defensive: payload?.error null branch unreachable after validation */\n message: payload?.error?.message ?? 'Anthropic stream returned an error event'\n };\n return;\n } else if (\n typeof eventName === 'string' &&\n !RECOGNIZED_ANTHROPIC_EVENTS.has(eventName) &&\n !warnedEvents.has(eventName)\n ) {\n // Empirical drift instrument: an unrecognized Anthropic event surfaces as a one-time\n // warning per stream. Update RECOGNIZED_ANTHROPIC_EVENTS once the new event is either\n // handled or confirmed safe to ignore.\n warnedEvents.add(eventName);\n logger?.warn(\n `${UNRECOGNIZED_EVENT_WARN_TAG} Anthropic streaming adapter: unrecognized SSE event ` +\n `'${eventName}'. ` +\n `payload preview: ${formatUnrecognizedEventPayloadPreview(message.data)}. ` +\n `This may indicate provider drift — if the new event carries data the adapter ` +\n `should surface, add a handler; otherwise add the name to ` +\n `RECOGNIZED_ANTHROPIC_EVENTS.`\n );\n }\n }\n } catch (err: unknown) /* c8 ignore start - defensive: stream errors are always Error instances */ {\n yield { type: 'error', message: err instanceof Error ? err.message : String(err) };\n return;\n } /* c8 ignore stop */\n\n if (stopped) {\n yield { type: 'done', truncated, fullText };\n } else {\n yield { type: 'error', message: 'Anthropic stream ended without a message_stop event' };\n }\n}\n\n// ============================================================================\n// Per-format request caller\n// ============================================================================\n\n/**\n * Issues a streaming Anthropic Messages request and returns the\n * unified-event iterable on success.\n *\n * @internal\n */\nexport async function callAnthropicStream(\n config: IStreamApiConfig,\n prompt: AiPrompt,\n messagesBefore: ReadonlyArray<IChatMessage> | undefined,\n temperature: number | undefined,\n tools: ReadonlyArray<AiToolConfig> | undefined,\n logger?: Logging.ILogger,\n signal?: AbortSignal,\n resolvedThinking?: IResolvedThinkingConfig,\n accumulationBuffer?: Map<number, IAccumulatedBlock>,\n continuationMessages?: ReadonlyArray<JsonObject>\n): Promise<Result<AsyncIterable<IAiStreamEvent>>> {\n const url = `${config.baseUrl}/messages`;\n const messages = buildAnthropicMessages(prompt, {\n head: messagesBefore,\n rawTail: continuationMessages\n });\n const body: Record<string, unknown> = {\n model: config.model,\n system: prompt.system,\n messages,\n max_tokens: 4096,\n stream: true\n };\n // Temperature is sent only when explicitly provided (Claude-5 rejects any temperature). When\n // thinking is active it is also rejected — the completion/streaming paths validate this upstream,\n // and the effort gate here is the safety net for the (unguarded) client-tool path.\n if (resolvedThinking?.anthropicEffort === undefined) {\n if (temperature !== undefined) {\n body.temperature = temperature;\n }\n }\n if (resolvedThinking?.anthropicEffort !== undefined) {\n body.thinking = {\n type: 'enabled',\n budget_tokens: anthropicEffortToBudgetTokens(resolvedThinking.anthropicEffort)\n };\n }\n if (resolvedThinking?.otherParams !== undefined) {\n Object.assign(body, resolvedThinking.otherParams);\n }\n if (tools && tools.length > 0) {\n body.tools = toAnthropicTools(tools);\n }\n const headers: Record<string, string> = {\n 'x-api-key': config.apiKey,\n 'anthropic-version': '2023-06-01',\n 'anthropic-dangerous-direct-browser-access': 'true'\n };\n /* c8 ignore next 4 - optional logger diagnostic output */\n if (logger) {\n const toolTypes = tools && tools.length > 0 ? tools.map((t) => t.type).join(',') : 'none';\n logger.info(`Anthropic streaming: model=${config.model}, tools=${toolTypes}`);\n }\n const buffer = accumulationBuffer ?? new Map<number, IAccumulatedBlock>();\n const conn = await openSseConnection(url, headers, body, logger, signal);\n return conn.onSuccess((response) => succeed(translateAnthropicStream(response, buffer, logger)));\n}\n"]}