opencode-rehydra-core 0.14.0

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 (432) hide show
  1. package/LICENSE +22 -0
  2. package/README.en.md +191 -0
  3. package/README.md +191 -0
  4. package/dist/browser.d.ts +54 -0
  5. package/dist/browser.d.ts.map +1 -0
  6. package/dist/browser.js +74 -0
  7. package/dist/browser.js.map +1 -0
  8. package/dist/core/anonymizer.d.ts +309 -0
  9. package/dist/core/anonymizer.d.ts.map +1 -0
  10. package/dist/core/anonymizer.js +555 -0
  11. package/dist/core/anonymizer.js.map +1 -0
  12. package/dist/core/index.d.ts +6 -0
  13. package/dist/core/index.d.ts.map +1 -0
  14. package/dist/core/index.js +6 -0
  15. package/dist/core/index.js.map +1 -0
  16. package/dist/crypto/index.d.ts +6 -0
  17. package/dist/crypto/index.d.ts.map +1 -0
  18. package/dist/crypto/index.js +6 -0
  19. package/dist/crypto/index.js.map +1 -0
  20. package/dist/crypto/pii-map-crypto.d.ts +114 -0
  21. package/dist/crypto/pii-map-crypto.d.ts.map +1 -0
  22. package/dist/crypto/pii-map-crypto.js +228 -0
  23. package/dist/crypto/pii-map-crypto.js.map +1 -0
  24. package/dist/index.d.ts +53 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +72 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/ner/bio-decoder.d.ts +64 -0
  29. package/dist/ner/bio-decoder.d.ts.map +1 -0
  30. package/dist/ner/bio-decoder.js +218 -0
  31. package/dist/ner/bio-decoder.js.map +1 -0
  32. package/dist/ner/index.d.ts +12 -0
  33. package/dist/ner/index.d.ts.map +1 -0
  34. package/dist/ner/index.js +12 -0
  35. package/dist/ner/index.js.map +1 -0
  36. package/dist/ner/inference-server-client.d.ts +81 -0
  37. package/dist/ner/inference-server-client.d.ts.map +1 -0
  38. package/dist/ner/inference-server-client.js +120 -0
  39. package/dist/ner/inference-server-client.js.map +1 -0
  40. package/dist/ner/inference-server-ner-model.d.ts +43 -0
  41. package/dist/ner/inference-server-ner-model.d.ts.map +1 -0
  42. package/dist/ner/inference-server-ner-model.js +119 -0
  43. package/dist/ner/inference-server-ner-model.js.map +1 -0
  44. package/dist/ner/model-manager.d.ts +111 -0
  45. package/dist/ner/model-manager.d.ts.map +1 -0
  46. package/dist/ner/model-manager.js +334 -0
  47. package/dist/ner/model-manager.js.map +1 -0
  48. package/dist/ner/ner-model.d.ts +172 -0
  49. package/dist/ner/ner-model.d.ts.map +1 -0
  50. package/dist/ner/ner-model.js +514 -0
  51. package/dist/ner/ner-model.js.map +1 -0
  52. package/dist/ner/onnx-runtime.browser.d.ts +46 -0
  53. package/dist/ner/onnx-runtime.browser.d.ts.map +1 -0
  54. package/dist/ner/onnx-runtime.browser.js +90 -0
  55. package/dist/ner/onnx-runtime.browser.js.map +1 -0
  56. package/dist/ner/onnx-runtime.d.ts +72 -0
  57. package/dist/ner/onnx-runtime.d.ts.map +1 -0
  58. package/dist/ner/onnx-runtime.js +132 -0
  59. package/dist/ner/onnx-runtime.js.map +1 -0
  60. package/dist/ner/token-window.d.ts +19 -0
  61. package/dist/ner/token-window.d.ts.map +1 -0
  62. package/dist/ner/token-window.js +101 -0
  63. package/dist/ner/token-window.js.map +1 -0
  64. package/dist/ner/tokenizer.d.ts +142 -0
  65. package/dist/ner/tokenizer.d.ts.map +1 -0
  66. package/dist/ner/tokenizer.js +362 -0
  67. package/dist/ner/tokenizer.js.map +1 -0
  68. package/dist/opencode-plugin/git-identity.d.ts +3 -0
  69. package/dist/opencode-plugin/git-identity.d.ts.map +1 -0
  70. package/dist/opencode-plugin/git-identity.js +37 -0
  71. package/dist/opencode-plugin/git-identity.js.map +1 -0
  72. package/dist/opencode-plugin/github-username.d.ts +3 -0
  73. package/dist/opencode-plugin/github-username.d.ts.map +1 -0
  74. package/dist/opencode-plugin/github-username.js +41 -0
  75. package/dist/opencode-plugin/github-username.js.map +1 -0
  76. package/dist/opencode-plugin/identity-recognizer.d.ts +5 -0
  77. package/dist/opencode-plugin/identity-recognizer.d.ts.map +1 -0
  78. package/dist/opencode-plugin/identity-recognizer.js +21 -0
  79. package/dist/opencode-plugin/identity-recognizer.js.map +1 -0
  80. package/dist/opencode-plugin/index.d.ts +7 -0
  81. package/dist/opencode-plugin/index.d.ts.map +1 -0
  82. package/dist/opencode-plugin/index.js +6 -0
  83. package/dist/opencode-plugin/index.js.map +1 -0
  84. package/dist/opencode-plugin/plugin.d.ts +39 -0
  85. package/dist/opencode-plugin/plugin.d.ts.map +1 -0
  86. package/dist/opencode-plugin/plugin.js +294 -0
  87. package/dist/opencode-plugin/plugin.js.map +1 -0
  88. package/dist/opencode-plugin/types.d.ts +33 -0
  89. package/dist/opencode-plugin/types.d.ts.map +1 -0
  90. package/dist/opencode-plugin/types.js +5 -0
  91. package/dist/opencode-plugin/types.js.map +1 -0
  92. package/dist/opencode-plugin/v2/anon-state.d.ts +12 -0
  93. package/dist/opencode-plugin/v2/anon-state.d.ts.map +1 -0
  94. package/dist/opencode-plugin/v2/anon-state.js +14 -0
  95. package/dist/opencode-plugin/v2/anon-state.js.map +1 -0
  96. package/dist/opencode-plugin/v2/deep-rehydrate.d.ts +13 -0
  97. package/dist/opencode-plugin/v2/deep-rehydrate.d.ts.map +1 -0
  98. package/dist/opencode-plugin/v2/deep-rehydrate.js +33 -0
  99. package/dist/opencode-plugin/v2/deep-rehydrate.js.map +1 -0
  100. package/dist/opencode-plugin/v2/index.d.ts +17 -0
  101. package/dist/opencode-plugin/v2/index.d.ts.map +1 -0
  102. package/dist/opencode-plugin/v2/index.js +17 -0
  103. package/dist/opencode-plugin/v2/index.js.map +1 -0
  104. package/dist/opencode-plugin/v2/logger.d.ts +24 -0
  105. package/dist/opencode-plugin/v2/logger.d.ts.map +1 -0
  106. package/dist/opencode-plugin/v2/logger.js +73 -0
  107. package/dist/opencode-plugin/v2/logger.js.map +1 -0
  108. package/dist/opencode-plugin/v2/options.d.ts +40 -0
  109. package/dist/opencode-plugin/v2/options.d.ts.map +1 -0
  110. package/dist/opencode-plugin/v2/options.js +132 -0
  111. package/dist/opencode-plugin/v2/options.js.map +1 -0
  112. package/dist/opencode-plugin/v2/register-hooks.d.ts +43 -0
  113. package/dist/opencode-plugin/v2/register-hooks.d.ts.map +1 -0
  114. package/dist/opencode-plugin/v2/register-hooks.js +160 -0
  115. package/dist/opencode-plugin/v2/register-hooks.js.map +1 -0
  116. package/dist/opencode-plugin/v2/rehydrate-tail.d.ts +101 -0
  117. package/dist/opencode-plugin/v2/rehydrate-tail.d.ts.map +1 -0
  118. package/dist/opencode-plugin/v2/rehydrate-tail.js +147 -0
  119. package/dist/opencode-plugin/v2/rehydrate-tail.js.map +1 -0
  120. package/dist/opencode-plugin/v2/response-rehydrate.d.ts +78 -0
  121. package/dist/opencode-plugin/v2/response-rehydrate.d.ts.map +1 -0
  122. package/dist/opencode-plugin/v2/response-rehydrate.js +210 -0
  123. package/dist/opencode-plugin/v2/response-rehydrate.js.map +1 -0
  124. package/dist/opencode-plugin/v2/scrub-messages.d.ts +39 -0
  125. package/dist/opencode-plugin/v2/scrub-messages.d.ts.map +1 -0
  126. package/dist/opencode-plugin/v2/scrub-messages.js +260 -0
  127. package/dist/opencode-plugin/v2/scrub-messages.js.map +1 -0
  128. package/dist/opencode-plugin/v2/sessions.d.ts +17 -0
  129. package/dist/opencode-plugin/v2/sessions.d.ts.map +1 -0
  130. package/dist/opencode-plugin/v2/sessions.js +23 -0
  131. package/dist/opencode-plugin/v2/sessions.js.map +1 -0
  132. package/dist/opencode-plugin/v2/sse.d.ts +101 -0
  133. package/dist/opencode-plugin/v2/sse.d.ts.map +1 -0
  134. package/dist/opencode-plugin/v2/sse.js +235 -0
  135. package/dist/opencode-plugin/v2/sse.js.map +1 -0
  136. package/dist/opencode-plugin/v2/types.d.ts +188 -0
  137. package/dist/opencode-plugin/v2/types.d.ts.map +1 -0
  138. package/dist/opencode-plugin/v2/types.js +10 -0
  139. package/dist/opencode-plugin/v2/types.js.map +1 -0
  140. package/dist/opencode-plugin/vcs-command.d.ts +3 -0
  141. package/dist/opencode-plugin/vcs-command.d.ts.map +1 -0
  142. package/dist/opencode-plugin/vcs-command.js +34 -0
  143. package/dist/opencode-plugin/vcs-command.js.map +1 -0
  144. package/dist/pipeline/index.d.ts +12 -0
  145. package/dist/pipeline/index.d.ts.map +1 -0
  146. package/dist/pipeline/index.js +12 -0
  147. package/dist/pipeline/index.js.map +1 -0
  148. package/dist/pipeline/prenormalize.d.ts +48 -0
  149. package/dist/pipeline/prenormalize.d.ts.map +1 -0
  150. package/dist/pipeline/prenormalize.js +94 -0
  151. package/dist/pipeline/prenormalize.js.map +1 -0
  152. package/dist/pipeline/resolver.d.ts +56 -0
  153. package/dist/pipeline/resolver.d.ts.map +1 -0
  154. package/dist/pipeline/resolver.js +239 -0
  155. package/dist/pipeline/resolver.js.map +1 -0
  156. package/dist/pipeline/semantic-data-loader.d.ts +171 -0
  157. package/dist/pipeline/semantic-data-loader.d.ts.map +1 -0
  158. package/dist/pipeline/semantic-data-loader.js +677 -0
  159. package/dist/pipeline/semantic-data-loader.js.map +1 -0
  160. package/dist/pipeline/semantic-enricher.d.ts +112 -0
  161. package/dist/pipeline/semantic-enricher.d.ts.map +1 -0
  162. package/dist/pipeline/semantic-enricher.js +322 -0
  163. package/dist/pipeline/semantic-enricher.js.map +1 -0
  164. package/dist/pipeline/tagger.d.ts +121 -0
  165. package/dist/pipeline/tagger.d.ts.map +1 -0
  166. package/dist/pipeline/tagger.js +545 -0
  167. package/dist/pipeline/tagger.js.map +1 -0
  168. package/dist/pipeline/title-extractor.d.ts +79 -0
  169. package/dist/pipeline/title-extractor.d.ts.map +1 -0
  170. package/dist/pipeline/title-extractor.js +801 -0
  171. package/dist/pipeline/title-extractor.js.map +1 -0
  172. package/dist/pipeline/validator.d.ts +65 -0
  173. package/dist/pipeline/validator.d.ts.map +1 -0
  174. package/dist/pipeline/validator.js +292 -0
  175. package/dist/pipeline/validator.js.map +1 -0
  176. package/dist/proxy/index.d.ts +13 -0
  177. package/dist/proxy/index.d.ts.map +1 -0
  178. package/dist/proxy/index.js +12 -0
  179. package/dist/proxy/index.js.map +1 -0
  180. package/dist/proxy/providers/anthropic.d.ts +28 -0
  181. package/dist/proxy/providers/anthropic.d.ts.map +1 -0
  182. package/dist/proxy/providers/anthropic.js +265 -0
  183. package/dist/proxy/providers/anthropic.js.map +1 -0
  184. package/dist/proxy/providers/index.d.ts +19 -0
  185. package/dist/proxy/providers/index.d.ts.map +1 -0
  186. package/dist/proxy/providers/index.js +41 -0
  187. package/dist/proxy/providers/index.js.map +1 -0
  188. package/dist/proxy/providers/openai.d.ts +27 -0
  189. package/dist/proxy/providers/openai.d.ts.map +1 -0
  190. package/dist/proxy/providers/openai.js +203 -0
  191. package/dist/proxy/providers/openai.js.map +1 -0
  192. package/dist/proxy/providers/streaming-tool-loop.d.ts +12 -0
  193. package/dist/proxy/providers/streaming-tool-loop.d.ts.map +1 -0
  194. package/dist/proxy/providers/streaming-tool-loop.js +223 -0
  195. package/dist/proxy/providers/streaming-tool-loop.js.map +1 -0
  196. package/dist/proxy/providers/types.d.ts +109 -0
  197. package/dist/proxy/providers/types.d.ts.map +1 -0
  198. package/dist/proxy/providers/types.js +2 -0
  199. package/dist/proxy/providers/types.js.map +1 -0
  200. package/dist/proxy/proxy-server.d.ts +61 -0
  201. package/dist/proxy/proxy-server.d.ts.map +1 -0
  202. package/dist/proxy/proxy-server.js +146 -0
  203. package/dist/proxy/proxy-server.js.map +1 -0
  204. package/dist/proxy/rehydra-fetch.d.ts +35 -0
  205. package/dist/proxy/rehydra-fetch.d.ts.map +1 -0
  206. package/dist/proxy/rehydra-fetch.js +631 -0
  207. package/dist/proxy/rehydra-fetch.js.map +1 -0
  208. package/dist/proxy/rehydra-proxy.d.ts +40 -0
  209. package/dist/proxy/rehydra-proxy.d.ts.map +1 -0
  210. package/dist/proxy/rehydra-proxy.js +150 -0
  211. package/dist/proxy/rehydra-proxy.js.map +1 -0
  212. package/dist/proxy/sse-parser.d.ts +59 -0
  213. package/dist/proxy/sse-parser.d.ts.map +1 -0
  214. package/dist/proxy/sse-parser.js +112 -0
  215. package/dist/proxy/sse-parser.js.map +1 -0
  216. package/dist/proxy/system-instruction.d.ts +19 -0
  217. package/dist/proxy/system-instruction.d.ts.map +1 -0
  218. package/dist/proxy/system-instruction.js +33 -0
  219. package/dist/proxy/system-instruction.js.map +1 -0
  220. package/dist/proxy/tool-loop-stream.d.ts +7 -0
  221. package/dist/proxy/tool-loop-stream.d.ts.map +1 -0
  222. package/dist/proxy/tool-loop-stream.js +65 -0
  223. package/dist/proxy/tool-loop-stream.js.map +1 -0
  224. package/dist/proxy/types.d.ts +138 -0
  225. package/dist/proxy/types.d.ts.map +1 -0
  226. package/dist/proxy/types.js +5 -0
  227. package/dist/proxy/types.js.map +1 -0
  228. package/dist/proxy/wrap-client.d.ts +47 -0
  229. package/dist/proxy/wrap-client.d.ts.map +1 -0
  230. package/dist/proxy/wrap-client.js +70 -0
  231. package/dist/proxy/wrap-client.js.map +1 -0
  232. package/dist/recognizers/address.d.ts +2 -0
  233. package/dist/recognizers/address.d.ts.map +1 -0
  234. package/dist/recognizers/address.js +23 -0
  235. package/dist/recognizers/address.js.map +1 -0
  236. package/dist/recognizers/base.d.ts +78 -0
  237. package/dist/recognizers/base.d.ts.map +1 -0
  238. package/dist/recognizers/base.js +100 -0
  239. package/dist/recognizers/base.js.map +1 -0
  240. package/dist/recognizers/bic-swift.d.ts +10 -0
  241. package/dist/recognizers/bic-swift.d.ts.map +1 -0
  242. package/dist/recognizers/bic-swift.js +107 -0
  243. package/dist/recognizers/bic-swift.js.map +1 -0
  244. package/dist/recognizers/credit-card.d.ts +32 -0
  245. package/dist/recognizers/credit-card.d.ts.map +1 -0
  246. package/dist/recognizers/credit-card.js +160 -0
  247. package/dist/recognizers/credit-card.js.map +1 -0
  248. package/dist/recognizers/custom-id.d.ts +28 -0
  249. package/dist/recognizers/custom-id.d.ts.map +1 -0
  250. package/dist/recognizers/custom-id.js +116 -0
  251. package/dist/recognizers/custom-id.js.map +1 -0
  252. package/dist/recognizers/date.d.ts +10 -0
  253. package/dist/recognizers/date.d.ts.map +1 -0
  254. package/dist/recognizers/date.js +228 -0
  255. package/dist/recognizers/date.js.map +1 -0
  256. package/dist/recognizers/email.d.ts +10 -0
  257. package/dist/recognizers/email.d.ts.map +1 -0
  258. package/dist/recognizers/email.js +75 -0
  259. package/dist/recognizers/email.js.map +1 -0
  260. package/dist/recognizers/iban.d.ts +14 -0
  261. package/dist/recognizers/iban.d.ts.map +1 -0
  262. package/dist/recognizers/iban.js +67 -0
  263. package/dist/recognizers/iban.js.map +1 -0
  264. package/dist/recognizers/index.d.ts +25 -0
  265. package/dist/recognizers/index.d.ts.map +1 -0
  266. package/dist/recognizers/index.js +53 -0
  267. package/dist/recognizers/index.js.map +1 -0
  268. package/dist/recognizers/ip-address.d.ts +14 -0
  269. package/dist/recognizers/ip-address.d.ts.map +1 -0
  270. package/dist/recognizers/ip-address.js +183 -0
  271. package/dist/recognizers/ip-address.js.map +1 -0
  272. package/dist/recognizers/phone.d.ts +10 -0
  273. package/dist/recognizers/phone.d.ts.map +1 -0
  274. package/dist/recognizers/phone.js +145 -0
  275. package/dist/recognizers/phone.js.map +1 -0
  276. package/dist/recognizers/postal-code.d.ts +16 -0
  277. package/dist/recognizers/postal-code.d.ts.map +1 -0
  278. package/dist/recognizers/postal-code.js +42 -0
  279. package/dist/recognizers/postal-code.js.map +1 -0
  280. package/dist/recognizers/registry.d.ts +59 -0
  281. package/dist/recognizers/registry.d.ts.map +1 -0
  282. package/dist/recognizers/registry.js +113 -0
  283. package/dist/recognizers/registry.js.map +1 -0
  284. package/dist/recognizers/secrets/api-key.d.ts +6 -0
  285. package/dist/recognizers/secrets/api-key.d.ts.map +1 -0
  286. package/dist/recognizers/secrets/api-key.js +40 -0
  287. package/dist/recognizers/secrets/api-key.js.map +1 -0
  288. package/dist/recognizers/secrets/aws-credentials.d.ts +7 -0
  289. package/dist/recognizers/secrets/aws-credentials.d.ts.map +1 -0
  290. package/dist/recognizers/secrets/aws-credentials.js +68 -0
  291. package/dist/recognizers/secrets/aws-credentials.js.map +1 -0
  292. package/dist/recognizers/secrets/config-secret.d.ts +8 -0
  293. package/dist/recognizers/secrets/config-secret.d.ts.map +1 -0
  294. package/dist/recognizers/secrets/config-secret.js +59 -0
  295. package/dist/recognizers/secrets/config-secret.js.map +1 -0
  296. package/dist/recognizers/secrets/connection-string.d.ts +6 -0
  297. package/dist/recognizers/secrets/connection-string.d.ts.map +1 -0
  298. package/dist/recognizers/secrets/connection-string.js +40 -0
  299. package/dist/recognizers/secrets/connection-string.js.map +1 -0
  300. package/dist/recognizers/secrets/env-var.d.ts +8 -0
  301. package/dist/recognizers/secrets/env-var.d.ts.map +1 -0
  302. package/dist/recognizers/secrets/env-var.js +54 -0
  303. package/dist/recognizers/secrets/env-var.js.map +1 -0
  304. package/dist/recognizers/secrets/index.d.ts +22 -0
  305. package/dist/recognizers/secrets/index.d.ts.map +1 -0
  306. package/dist/recognizers/secrets/index.js +41 -0
  307. package/dist/recognizers/secrets/index.js.map +1 -0
  308. package/dist/recognizers/secrets/jwt.d.ts +6 -0
  309. package/dist/recognizers/secrets/jwt.d.ts.map +1 -0
  310. package/dist/recognizers/secrets/jwt.js +47 -0
  311. package/dist/recognizers/secrets/jwt.js.map +1 -0
  312. package/dist/recognizers/secrets/key-patterns.d.ts +10 -0
  313. package/dist/recognizers/secrets/key-patterns.d.ts.map +1 -0
  314. package/dist/recognizers/secrets/key-patterns.js +15 -0
  315. package/dist/recognizers/secrets/key-patterns.js.map +1 -0
  316. package/dist/recognizers/secrets/literal-value.d.ts +10 -0
  317. package/dist/recognizers/secrets/literal-value.d.ts.map +1 -0
  318. package/dist/recognizers/secrets/literal-value.js +48 -0
  319. package/dist/recognizers/secrets/literal-value.js.map +1 -0
  320. package/dist/recognizers/secrets/private-key.d.ts +6 -0
  321. package/dist/recognizers/secrets/private-key.d.ts.map +1 -0
  322. package/dist/recognizers/secrets/private-key.js +16 -0
  323. package/dist/recognizers/secrets/private-key.js.map +1 -0
  324. package/dist/recognizers/url.d.ts +14 -0
  325. package/dist/recognizers/url.d.ts.map +1 -0
  326. package/dist/recognizers/url.js +121 -0
  327. package/dist/recognizers/url.js.map +1 -0
  328. package/dist/storage/browser.d.ts +13 -0
  329. package/dist/storage/browser.d.ts.map +1 -0
  330. package/dist/storage/browser.js +13 -0
  331. package/dist/storage/browser.js.map +1 -0
  332. package/dist/storage/in-memory.d.ts +60 -0
  333. package/dist/storage/in-memory.d.ts.map +1 -0
  334. package/dist/storage/in-memory.js +108 -0
  335. package/dist/storage/in-memory.js.map +1 -0
  336. package/dist/storage/index.d.ts +11 -0
  337. package/dist/storage/index.d.ts.map +1 -0
  338. package/dist/storage/index.js +11 -0
  339. package/dist/storage/index.js.map +1 -0
  340. package/dist/storage/indexeddb.d.ts +69 -0
  341. package/dist/storage/indexeddb.d.ts.map +1 -0
  342. package/dist/storage/indexeddb.js +274 -0
  343. package/dist/storage/indexeddb.js.map +1 -0
  344. package/dist/storage/session-base.d.ts +34 -0
  345. package/dist/storage/session-base.d.ts.map +1 -0
  346. package/dist/storage/session-base.js +122 -0
  347. package/dist/storage/session-base.js.map +1 -0
  348. package/dist/storage/session.d.ts +19 -0
  349. package/dist/storage/session.d.ts.map +1 -0
  350. package/dist/storage/session.js +31 -0
  351. package/dist/storage/session.js.map +1 -0
  352. package/dist/storage/sqlite.d.ts +80 -0
  353. package/dist/storage/sqlite.d.ts.map +1 -0
  354. package/dist/storage/sqlite.js +255 -0
  355. package/dist/storage/sqlite.js.map +1 -0
  356. package/dist/storage/types.d.ts +208 -0
  357. package/dist/storage/types.d.ts.map +1 -0
  358. package/dist/storage/types.js +6 -0
  359. package/dist/storage/types.js.map +1 -0
  360. package/dist/streaming/anonymizer-stream.d.ts +63 -0
  361. package/dist/streaming/anonymizer-stream.d.ts.map +1 -0
  362. package/dist/streaming/anonymizer-stream.js +184 -0
  363. package/dist/streaming/anonymizer-stream.js.map +1 -0
  364. package/dist/streaming/index.d.ts +9 -0
  365. package/dist/streaming/index.d.ts.map +1 -0
  366. package/dist/streaming/index.js +8 -0
  367. package/dist/streaming/index.js.map +1 -0
  368. package/dist/streaming/sentence-buffer.d.ts +78 -0
  369. package/dist/streaming/sentence-buffer.d.ts.map +1 -0
  370. package/dist/streaming/sentence-buffer.js +239 -0
  371. package/dist/streaming/sentence-buffer.js.map +1 -0
  372. package/dist/streaming/stream-factory.d.ts +38 -0
  373. package/dist/streaming/stream-factory.d.ts.map +1 -0
  374. package/dist/streaming/stream-factory.js +69 -0
  375. package/dist/streaming/stream-factory.js.map +1 -0
  376. package/dist/streaming/types.d.ts +121 -0
  377. package/dist/streaming/types.d.ts.map +1 -0
  378. package/dist/streaming/types.js +5 -0
  379. package/dist/streaming/types.js.map +1 -0
  380. package/dist/types/index.d.ts +269 -0
  381. package/dist/types/index.d.ts.map +1 -0
  382. package/dist/types/index.js +95 -0
  383. package/dist/types/index.js.map +1 -0
  384. package/dist/types/pii-types.d.ts +64 -0
  385. package/dist/types/pii-types.d.ts.map +1 -0
  386. package/dist/types/pii-types.js +153 -0
  387. package/dist/types/pii-types.js.map +1 -0
  388. package/dist/utils/iban-checksum.d.ts +23 -0
  389. package/dist/utils/iban-checksum.d.ts.map +1 -0
  390. package/dist/utils/iban-checksum.js +106 -0
  391. package/dist/utils/iban-checksum.js.map +1 -0
  392. package/dist/utils/index.d.ts +11 -0
  393. package/dist/utils/index.d.ts.map +1 -0
  394. package/dist/utils/index.js +11 -0
  395. package/dist/utils/index.js.map +1 -0
  396. package/dist/utils/json-walk.d.ts +21 -0
  397. package/dist/utils/json-walk.d.ts.map +1 -0
  398. package/dist/utils/json-walk.js +44 -0
  399. package/dist/utils/json-walk.js.map +1 -0
  400. package/dist/utils/luhn.d.ts +17 -0
  401. package/dist/utils/luhn.d.ts.map +1 -0
  402. package/dist/utils/luhn.js +55 -0
  403. package/dist/utils/luhn.js.map +1 -0
  404. package/dist/utils/offsets.d.ts +86 -0
  405. package/dist/utils/offsets.d.ts.map +1 -0
  406. package/dist/utils/offsets.js +124 -0
  407. package/dist/utils/offsets.js.map +1 -0
  408. package/dist/utils/path.d.ts +34 -0
  409. package/dist/utils/path.d.ts.map +1 -0
  410. package/dist/utils/path.js +96 -0
  411. package/dist/utils/path.js.map +1 -0
  412. package/dist/utils/regex.d.ts +11 -0
  413. package/dist/utils/regex.d.ts.map +1 -0
  414. package/dist/utils/regex.js +14 -0
  415. package/dist/utils/regex.js.map +1 -0
  416. package/dist/utils/storage-browser.d.ts +51 -0
  417. package/dist/utils/storage-browser.d.ts.map +1 -0
  418. package/dist/utils/storage-browser.js +381 -0
  419. package/dist/utils/storage-browser.js.map +1 -0
  420. package/dist/utils/storage-node.d.ts +51 -0
  421. package/dist/utils/storage-node.d.ts.map +1 -0
  422. package/dist/utils/storage-node.js +153 -0
  423. package/dist/utils/storage-node.js.map +1 -0
  424. package/dist/utils/storage.browser.d.ts +75 -0
  425. package/dist/utils/storage.browser.d.ts.map +1 -0
  426. package/dist/utils/storage.browser.js +69 -0
  427. package/dist/utils/storage.browser.js.map +1 -0
  428. package/dist/utils/storage.d.ts +73 -0
  429. package/dist/utils/storage.d.ts.map +1 -0
  430. package/dist/utils/storage.js +69 -0
  431. package/dist/utils/storage.js.map +1 -0
  432. package/package.json +148 -0
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 ELAN Languages
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
package/README.en.md ADDED
@@ -0,0 +1,191 @@
1
+ <p align="center">
2
+ <img src="https://framerusercontent.com/images/NT4xWP34VHd2Wlrk197je5BUi4.png?scale-down-to=512" width="400" alt="Rehydra" />
3
+ </p>
4
+
5
+ <p align="center">
6
+ PII security for AI workflows, coding agents and browser workloads.<br/>
7
+ Detects, replaces, encrypts, and <strong>rehydrates</strong> back when needed.
8
+ </p>
9
+
10
+ <p align="center">
11
+ <a href="https://github.com/EightDoor/opencode-rehydra-sdk/issues">Issues</a> ·
12
+ <a href="./README.md">中文</a>
13
+ </p>
14
+
15
+ <p align="center">
16
+ <a href="https://www.npmjs.com/package/opencode-rehydra-core"><img src="https://img.shields.io/npm/v/opencode-rehydra-core?color=blue" alt="npm" /></a>
17
+ <a href="https://github.com/EightDoor/opencode-rehydra-sdk/blob/main/LICENSE"><img src="https://img.shields.io/github/license/EightDoor/opencode-rehydra-sdk" alt="license" /></a>
18
+ </p>
19
+
20
+ <p align="center">
21
+ <code>npm i opencode-rehydra-core</code> · <code>npm i <a href="packages/opencode-plugin/">opencode-rehydar</a></code>
22
+ </p>
23
+
24
+ ## The Problem
25
+
26
+ When you send code, messages, or documents through an LLM, real names, emails, and API keys go with them. Existing anonymizers either strip PII permanently — which breaks the conversation — or merely mask it, which leaves the model unable to reason.
27
+
28
+ You need **pseudonyms** the LLM can work with and your tools can reverse.
29
+
30
+ ## How Rehydra Solves It
31
+
32
+ 1. **Detect** — Regex patterns catch structured PII (emails, phones, UK postcodes, IBANs, credit cards). An on-device NER model (ONNX, no cloud calls) catches soft PII (names, organizations, locations).
33
+ 2. **Replace** — Each PII value gets a stable placeholder: `<PII type="PERSON" id="1"/>`. The LLM works with these instead of real data.
34
+ 3. **Persist** — The same entity always gets the same ID, across every message in the session. The LLM maintains relational coherence without ever seeing real PII.
35
+ 4. **Rehydrate** — When a response needs to become real again (a file write, a bash command, a final answer), Rehydra restores the original values from its encrypted map.
36
+
37
+ ## Quick Start
38
+
39
+ ### OpenCode plugin
40
+
41
+ ```bash
42
+ npm install opencode-rehydar
43
+ ```
44
+
45
+ Enable it in `opencode.json` (V2 uses a `plugins` list):
46
+
47
+ ```json
48
+ {
49
+ "plugins": [
50
+ {
51
+ "package": "opencode-rehydar",
52
+ "options": { "envFiles": [".env", ".env.local"] }
53
+ }
54
+ ]
55
+ }
56
+ ```
57
+
58
+ It intercepts the conversation between [OpenCode](https://github.com/sst/opencode) and the LLM. Secrets from `.env` files are replaced with placeholders before they leave your machine and restored before tools execute. Requires OpenCode's **V2** plugin API; the V1 `plugin` configuration and hook set are not supported.
59
+
60
+ The plugin scrubs the session-title request (`session.hook("title")`), but rehydrates responses only for the primary answer (`http.response` with `kind === "primary"`). Session titles can therefore display `<PII .../>` placeholders, so disable the title agent to avoid placeholder titles; see [the limitation and configuration](packages/opencode-plugin/README.en.md#session-title-limitation).
61
+
62
+ ### Library — embed PII anonymization in your app
63
+
64
+ The highly customizable backbone behind the implementations above. Supports custom NER models, encryption key providers, session storage providers, tag formats and many more tweaks.
65
+
66
+ ```typescript
67
+ import { anonymize } from 'opencode-rehydra-core';
68
+
69
+ const { anonymizedText } = await anonymize(
70
+ 'Email john.smith@acme-corp.com or call John at +41 79 123 45 67'
71
+ );
72
+ ```
73
+
74
+ Works in **Node.js**, **Bun**, and **browsers**. No data leaves your machine.
75
+
76
+ ### Proxy module
77
+
78
+ The SDK ships a `rehydra/proxy` module you can embed in your own services. It anonymizes outbound messages and rehydrates tool-call arguments before they execute, so the LLM works with placeholders while your tools always get real values.
79
+
80
+ ```typescript
81
+ import { createRehydraProxy } from "rehydra/proxy";
82
+ // Mount createRehydraProxy({ ... }) on the host you control.
83
+ ```
84
+
85
+ Tool results (file reads, bash output) are anonymized on the way out. Tool call arguments (file writes, bash commands) are rehydrated on the way back.
86
+
87
+ ## Why Rehydra?
88
+
89
+ ### Reversible, not destructive
90
+
91
+ Most PII libraries mask or redact permanently. Rehydra encrypts the original values with AES-256-GCM and restores them on demand. Anonymize for the LLM, rehydrate for your tools — a full round-trip, not a one-way street.
92
+
93
+ ### Session-persistent identity
94
+
95
+ `PERSON_1` stays `PERSON_1` across every message in the conversation. When John Smith comes up in message 1, message 5, and message 20, the LLM sees the same placeholder every time. It can track relationships, reference earlier context, and produce coherent multi-turn output — without ever seeing real PII. Sessions persist to SQLite (server), IndexedDB (browser), or in-memory, so identity mappings survive restarts.
96
+
97
+ ### Zero-trust, on-device
98
+
99
+ NER inference runs locally via ONNX Runtime (~280 MB quantized model). No API calls to external services. Works offline. PII never leaves your machine.
100
+
101
+ ### Core capabilities
102
+
103
+ - **Secrets, not just PII**: beyond names, emails, and phone numbers, Rehydra detects API keys (OpenAI, Anthropic, Stripe, AWS, GitHub...), JWTs, private keys, database connection strings, and `.env` secrets.
104
+ - **Streaming-aware**: purpose-built for LLM token streams. A sentence-buffered chunking system with NER overlap preservation ensures accurate detection even when PII spans chunk boundaries, with a low-latency mode for real-time streaming.
105
+ - **Server-side tool loops**: `createRehydraFetch` supports `onToolCall` for OpenAI Chat Completions and Anthropic Messages requests with `stream: true`. The first response is buffered and its complete tool calls are validated before callbacks run. Interleaved calls retain their IDs and arguments. Tool arguments are rehydrated locally, and tool results are anonymized before the next request. Continuation requests use `stream: false`; the final response is returned as provider-compatible SSE including completion events and usage. This buffers the initial response and final JSON response, so it does not preserve token-by-token generation latency. Streams without tool calls retain their original events. Set `maxToolRounds` to bound callback rounds (default 10) and `maxToolResponseBytes` to bound each buffered response (default 8 MiB); on reaching the round limit, pending calls are returned to the caller without execution. Pass an `AbortSignal` through fetch to cancel buffering or prevent later callbacks; a callback already running must manage its own cancellation. Truncated calls, malformed arguments, and oversized streams fail before tool execution. Upstream HTTP errors retain their status. OpenAI tool loops require a single completion choice. Custom providers can opt in through `streamingToolLoop` on `LLMContentProvider`.
106
+ - **Semantic enrichment for machine translation**: optional gender and scope attributes on PII tags (`<PII type="PERSON" gender="male" id="1"/>`, `<PII type="LOCATION" scope="city" id="2"/>`) preserve grammatical context for downstream systems.
107
+ - **Stable external tag IDs**: callers that manage PII maps across independent anonymization calls can seed lowercase alphanumeric IDs through `existingPiiMap`. This allows an ID to be derived from the value it masks, for example with a keyed HMAC, instead of depending on a per-call counter.
108
+
109
+ ```typescript
110
+ const existingPiiMap = new Map([
111
+ ['EMAIL_a4f2c9d8e7b6q', 'alice@acme.com'],
112
+ ]);
113
+
114
+ const result = await anonymizer.anonymize(
115
+ 'Email alice@acme.com',
116
+ undefined,
117
+ policy,
118
+ existingPiiMap,
119
+ );
120
+ // → 'Email <PII type="EMAIL" id="a4f2c9d8e7b6q"/>'
121
+ ```
122
+
123
+ External IDs must match `[0-9a-z]+`. Decimal-only IDs retain their existing numeric behavior. Avoid IDs beginning with recognizer prefixes such as `case`, `file`, `ref`, or `ticket`, and avoid runs of seven or more digits; those shapes may themselves be detected as case IDs or phone numbers inside an inbound tag.
124
+
125
+ ## Example: Full Round-Trip with Sessions
126
+
127
+ ```typescript
128
+ import {
129
+ createAnonymizer,
130
+ InMemoryKeyProvider,
131
+ SQLitePIIStorageProvider,
132
+ } from 'opencode-rehydra-core';
133
+
134
+ const keyProvider = new InMemoryKeyProvider();
135
+ const anonymizer = createAnonymizer({
136
+ ner: {
137
+ mode: 'quantized', // ~280 MB model, auto-downloads on first use
138
+ caseFallback: true, // detect lowercase names like "tom"
139
+ thresholds: { PERSON: 0.8 }, // require higher confidence for names
140
+ onStatus: console.log, // log model download progress
141
+ },
142
+ semantic: { enabled: true }, // adds gender/scope attributes for MT
143
+ secrets: { enabled: true }, // detect API keys, JWTs, connection strings
144
+ keyProvider,
145
+ piiStorageProvider: new SQLitePIIStorageProvider('./pii.db'),
146
+ });
147
+
148
+ const session = anonymizer.session('chat-123');
149
+
150
+ // Message 1 — NER detects names and orgs, regex catches emails
151
+ const r1 = await session.anonymize(
152
+ 'Tell John Smith at Acme Corp (john.smith@acme-corp.com) we accept the offer'
153
+ );
154
+ // → "Tell <PII type="PERSON" gender="male" id="1"/> at <PII type="ORG" id="2"/>
155
+ // (<PII type="EMAIL" id="3"/>) we accept the offer"
156
+
157
+ // Message 2 — same entities keep their IDs across messages
158
+ const r2 = await session.anonymize(
159
+ 'CC john.smith@acme-corp.com and loop in admin@acme-corp.com'
160
+ );
161
+ // → "CC <PII type="EMAIL" id="3"/> and loop in <PII type="EMAIL" id="4"/>"
162
+
163
+ // Rehydrate any message — PII map is loaded from SQLite automatically
164
+ const original = await session.rehydrate(r2.anonymizedText);
165
+ // → "CC john.smith@acme-corp.com and loop in admin@acme-corp.com"
166
+
167
+ await anonymizer.dispose();
168
+ ```
169
+
170
+ ## Address detection
171
+
172
+ The default regex registry detects UK postcode syntax and numbered English-language street addresses such as `34a Friskin Road`. Apartment identifiers are included when adjacent to a street address, as in `Flat 1\n34a Friskin Road`. A contiguous UK address block ending in a postcode is masked as one `ADDRESS`; a standalone postcode uses `POSTAL_CODE`. Bare apartment numbers, unnumbered buildings, and other countries' postal formats need custom recognizers or NER. Postcode matching checks syntax, not whether a postcode is currently assigned.
173
+
174
+ Disable `ADDRESS` or `POSTAL_CODE` through the detection policy to opt out of either recognizer.
175
+
176
+ ## Packages
177
+
178
+ | Package | Description |
179
+ |---------|-------------|
180
+ | [`opencode-rehydra-core`](https://www.npmjs.com/package/opencode-rehydra-core) | Core SDK — detect, anonymize, rehydrate |
181
+ | [`opencode-rehydar`](packages/opencode-plugin/) | OpenCode plugin — scrubs secrets before they reach LLM providers |
182
+
183
+ ## Documentation
184
+
185
+ - [Core SDK usage](#library--embed-pii-anonymization-in-your-app)
186
+ - [OpenCode plugin](packages/opencode-plugin/README.en.md)
187
+ - [中文](README.md)
188
+
189
+ ## License
190
+
191
+ [MIT](LICENSE)
package/README.md ADDED
@@ -0,0 +1,191 @@
1
+ <p align="center">
2
+ <img src="https://framerusercontent.com/images/NT4xWP34VHd2Wlrk197je5BUi4.png?scale-down-to=512" width="400" alt="Rehydra" />
3
+ </p>
4
+
5
+ <p align="center">
6
+ 为 AI 工作流、编程助手和浏览器场景提供 PII 安全防护。<br/>
7
+ 检测、替换、加密,并在需要时<strong>还原</strong>真实值。
8
+ </p>
9
+
10
+ <p align="center">
11
+ <a href="https://github.com/EightDoor/opencode-rehydra-sdk/issues">Issues</a> ·
12
+ <a href="./README.en.md">English</a>
13
+ </p>
14
+
15
+ <p align="center">
16
+ <a href="https://www.npmjs.com/package/opencode-rehydra-core"><img src="https://img.shields.io/npm/v/opencode-rehydra-core?color=blue" alt="npm" /></a>
17
+ <a href="https://github.com/EightDoor/opencode-rehydra-sdk/blob/main/LICENSE"><img src="https://img.shields.io/github/license/EightDoor/opencode-rehydra-sdk" alt="license" /></a>
18
+ </p>
19
+
20
+ <p align="center">
21
+ <code>npm i opencode-rehydra-core</code> · <code>npm i <a href="packages/opencode-plugin/">opencode-rehydar</a></code>
22
+ </p>
23
+
24
+ ## 问题所在
25
+
26
+ 当你把代码、消息或文档发给 LLM 时,真实姓名、邮箱和 API Key 会一并离开你的机器。已有的匿名化工具要么永久删除 PII(那样对话就断了),要么只是临时遮盖(那样模型无法推理)。
27
+
28
+ 你需要的是**化名**:模型能拿来推理,你的工具又能还原回去。
29
+
30
+ ## Rehydra 的做法
31
+
32
+ 1. **检测** — 正则捕获结构化 PII(邮箱、电话、英国邮编、IBAN、信用卡卡号)。本地 NER 模型(ONNX,不联网)捕获非结构化 PII(人名、机构、地点)。
33
+ 2. **替换** — 每个 PII 值获得一个稳定占位符:`<PII type="PERSON" id="1"/>`。模型用占位符而不是真实数据来工作。
34
+ 3. **持久化** — 同一实体在整个会话的每条消息里都是同一个 ID。模型能维持关系一致性,却从未看到真实 PII。
35
+ 4. **还原** — 当响应需要变回真实值时(写文件、执行 bash 命令、给出最终答案),Rehydra 从加密映射中还原原始值。
36
+
37
+ ## 快速开始
38
+
39
+ ### OpenCode 插件
40
+
41
+ ```bash
42
+ npm install opencode-rehydar
43
+ ```
44
+
45
+ 在 `opencode.json` 中启用(V2 使用 `plugins` 列表):
46
+
47
+ ```json
48
+ {
49
+ "plugins": [
50
+ {
51
+ "package": "opencode-rehydar",
52
+ "options": { "envFiles": [".env", ".env.local"] }
53
+ }
54
+ ]
55
+ }
56
+ ```
57
+
58
+ 它拦截 [OpenCode](https://github.com/sst/opencode) 与 LLM 之间的对话。`.env` 文件中的密钥在离开本机前被替换为占位符,在工具执行前被还原。需要 OpenCode 的 **V2** 插件 API;不支持 V1 的 `plugin` 配置和 hook 集合。
59
+
60
+ 插件会脱敏会话标题请求(`session.hook("title")`),但只对主回答还原响应(`http.response` 且 `kind === "primary"`)。因此会话标题可能显示 `<PII .../>` 占位符,建议禁用标题 agent 以避免占位符标题,详见[限制与配置](packages/opencode-plugin/README.md#session-title-limitation)。
61
+
62
+ ### 作为库嵌入你的应用
63
+
64
+ 上面实现背后的可高度定制内核。支持自定义 NER 模型、加密密钥提供器、会话存储提供器、标签格式等多种调整。
65
+
66
+ ```typescript
67
+ import { anonymize } from 'opencode-rehydra-core';
68
+
69
+ const { anonymizedText } = await anonymize(
70
+ 'Email john.smith@acme-corp.com or call John at +41 79 123 45 67'
71
+ );
72
+ ```
73
+
74
+ 在 **Node.js**、**Bun** 和**浏览器**中都能运行。数据不离开你的机器。
75
+
76
+ ### 代理模块
77
+
78
+ SDK 内置 `rehydra/proxy` 模块,可嵌入你自己的服务。它在出站消息上做脱敏,并在工具调用执行前还原参数,因此模型用占位符工作,而你的工具始终拿到真实值。
79
+
80
+ ```typescript
81
+ import { createRehydraProxy } from "rehydra/proxy";
82
+ // 将 createRehydraProxy({ ... }) 挂载到你自己的宿主上。
83
+ ```
84
+
85
+ 工具结果(文件读取、bash 输出)在返回时脱敏。工具调用参数(文件写入、bash 命令)在执行前还原。
86
+
87
+ ## 为什么选 Rehydra
88
+
89
+ ### 可逆,而非破坏性
90
+
91
+ 多数 PII 库做的是永久遮盖或删除。Rehydra 用 AES-256-GCM 加密原始值,按需还原。给模型用匿名值,给工具用还原值——完整往返,而不是单行道。
92
+
93
+ ### 跨会话稳定的身份
94
+
95
+ `PERSON_1` 在整段对话的每条消息里都是 `PERSON_1`。当 John Smith 分别出现在第 1、5、20 条消息里,模型每次看到的都是同一个占位符。它能追踪关系、引用前文、产出连贯的多轮输出——而从未看到真实 PII。会话可持久化到 SQLite(服务端)、IndexedDB(浏览器)或内存,身份映射在重启后依然有效。
96
+
97
+ ### 零信任,端侧运行
98
+
99
+ NER 推理通过 ONNX Runtime 在本地执行(量化模型约 280 MB)。不调用任何外部 API。可离线工作。PII 永不离开你的机器。
100
+
101
+ ### 关键能力
102
+
103
+ - **密钥而不只是 PII**:除姓名、邮箱、电话外,还能检测 API Key(OpenAI、Anthropic、Stripe、AWS、GitHub 等)、JWT、私钥、数据库连接串和 `.env` 密钥。
104
+ - **面向流式**:专为 LLM token 流设计。带句子缓冲的分块系统配合 NER 重叠保留,确保 PII 跨分块边界时仍能准确检测,并提供低延迟实时流式模式。
105
+ - **服务端工具循环**:`createRehydraFetch` 支持在 `stream: true` 的 OpenAI Chat Completions 与 Anthropic Messages 请求上使用 `onToolCall`。首次响应被缓冲,其完整工具调用在回调执行前完成校验。交错调用保留各自的 ID 和参数。工具参数在本地还原,工具结果在下一次请求前脱敏。续请求使用 `stream: false`,最终响应以兼容 provider 的 SSE 返回,包含完成事件和用量信息;代价是缓冲了首包和最终 JSON,因此不保留逐 token 的生成延迟。不含工具调用的流保持原始事件。`maxToolRounds` 限制回调轮数(默认 10 轮),`maxToolResponseBytes` 限制每个缓冲响应大小(默认 8 MiB);达到轮数上限时未执行的调用原样返回给调用方。通过 fetch 传入 `AbortSignal` 可取消缓冲或阻止后续回调,已在运行的回调需自行处理取消。被截断的调用、畸形参数和超限流会在工具执行前失败。上游 HTTP 错误保留其状态码。OpenAI 工具循环要求只有一个 completion choice。自定义 provider 可通过 `LLMContentProvider` 上的 `streamingToolLoop` 接入。
106
+ - **机器翻译的语义增强**:PII 标签上的可选性别和范围属性(`<PII type="PERSON" gender="male" id="1"/>`、`<PII type="LOCATION" scope="city" id="2"/>`)为下游系统保留语法上下文。
107
+ - **稳定的外部标签 ID**:跨独立匿名化调用管理 PII 映射的调用方,可以通过 `existingPiiMap` 预置小写字母数字 ID。这允许 ID 由被遮盖的值派生(例如用带密钥的 HMAC),而不依赖每次调用的计数器。
108
+
109
+ ```typescript
110
+ const existingPiiMap = new Map([
111
+ ['EMAIL_a4f2c9d8e7b6q', 'alice@acme.com'],
112
+ ]);
113
+
114
+ const result = await anonymizer.anonymize(
115
+ 'Email alice@acme.com',
116
+ undefined,
117
+ policy,
118
+ existingPiiMap,
119
+ );
120
+ // → 'Email <PII type="EMAIL" id="a4f2c9d8e7b6q"/>'
121
+ ```
122
+
123
+ 外部 ID 必须匹配 `[0-9a-z]+`。纯数字 ID 保留现有的数字行为。避免以识别器前缀开头(`case`、`file`、`ref`、`ticket`)的 ID,也避免连续七位或更多数字——这些形态本身可能在传入的标签里被识别成 case ID 或电话号码。
124
+
125
+ ## 示例:带会话的完整往返
126
+
127
+ ```typescript
128
+ import {
129
+ createAnonymizer,
130
+ InMemoryKeyProvider,
131
+ SQLitePIIStorageProvider,
132
+ } from 'opencode-rehydra-core';
133
+
134
+ const keyProvider = new InMemoryKeyProvider();
135
+ const anonymizer = createAnonymizer({
136
+ ner: {
137
+ mode: 'quantized', // ~280 MB 模型,首次使用时自动下载
138
+ caseFallback: true, // 检测 "tom" 这类小写名字
139
+ thresholds: { PERSON: 0.8 }, // 对人名要求更高置信度
140
+ onStatus: console.log, // 打印模型下载进度
141
+ },
142
+ semantic: { enabled: true }, // 为机器翻译添加性别/范围属性
143
+ secrets: { enabled: true }, // 检测 API Key、JWT、连接串
144
+ keyProvider,
145
+ piiStorageProvider: new SQLitePIIStorageProvider('./pii.db'),
146
+ });
147
+
148
+ const session = anonymizer.session('chat-123');
149
+
150
+ // 消息 1 — NER 检测人名和机构,正则捕获邮箱
151
+ const r1 = await session.anonymize(
152
+ 'Tell John Smith at Acme Corp (john.smith@acme-corp.com) we accept the offer'
153
+ );
154
+ // → "Tell <PII type="PERSON" gender="male" id="1"/> at <PII type="ORG" id="2"/>
155
+ // (<PII type="EMAIL" id="3"/>) we accept the offer"
156
+
157
+ // 消息 2 — 同一实体跨消息保持 ID
158
+ const r2 = await session.anonymize(
159
+ 'CC john.smith@acme-corp.com and loop in admin@acme-corp.com'
160
+ );
161
+ // → "CC <PII type="EMAIL" id="3"/> and loop in <PII type="EMAIL" id="4"/>"
162
+
163
+ // 还原任意消息 — PII 映射会自动从 SQLite 加载
164
+ const original = await session.rehydrate(r2.anonymizedText);
165
+ // → "CC john.smith@acme-corp.com and loop in admin@acme-corp.com"
166
+
167
+ await anonymizer.dispose();
168
+ ```
169
+
170
+ ## 地址识别说明
171
+
172
+ 默认正则注册表检测英国邮编语法和带门牌号的英文街道地址,例如 `34a Friskin Road`。当公寓标识与街道地址相邻时会被包含,例如 `Flat 1\n34a Friskin Road`。以邮编结尾的连续英国地址块会被整体遮盖为一个 `ADDRESS`;独立的邮编使用 `POSTAL_CODE`。裸公寓号、无门牌号的建筑以及其他国家的邮编格式需要自定义识别器或 NER。邮编匹配只检查语法,不验证该邮编当前是否仍在使用。
173
+
174
+ 通过检测策略禁用 `ADDRESS` 或 `POSTAL_CODE` 即可关闭对应识别器。
175
+
176
+ ## 包
177
+
178
+ | 包 | 说明 |
179
+ |---|---|
180
+ | [`opencode-rehydra-core`](https://www.npmjs.com/package/opencode-rehydra-core) | 核心 SDK —— 检测、匿名化、还原 |
181
+ | [`opencode-rehydar`](packages/opencode-plugin/) | OpenCode 插件 —— 在密钥到达 LLM provider 前脱敏 |
182
+
183
+ ## 文档
184
+
185
+ - [核心 SDK 用法](#作为库嵌入你的应用)
186
+ - [OpenCode 插件](packages/opencode-plugin/README.md)
187
+ - [English](README.en.md)
188
+
189
+ ## License
190
+
191
+ [MIT](LICENSE)
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Rehydra Module - Browser Entry Point
3
+ * Browser-safe entry point for on-device PII anonymization
4
+ *
5
+ * This module excludes Node.js-specific exports like SQLitePIIStorageProvider.
6
+ * For full functionality including SQLite, use the main entry point or import from 'rehydra/node'.
7
+ */
8
+ export * from "./types/index.js";
9
+ export type { Recognizer } from "./recognizers/index.js";
10
+ export { RegexRecognizer, RecognizerRegistry, createDefaultRegistry, createRegistry, getGlobalRegistry, emailRecognizer, phoneRecognizer, ukPostalCodeRecognizer, streetAddressRecognizer, UK_POSTAL_CODE_PATTERN, isValidUKPostalCode, normalizeUKPostalCode, ibanRecognizer, bicSwiftRecognizer, creditCardRecognizer, ipAddressRecognizer, urlRecognizer, createCustomIdRecognizer, createCaseIdRecognizer, createCustomerIdRecognizer, } from "./recognizers/index.js";
11
+ export { NERModel, NERModelStub, createNERModel, createNERModelStub, WordPieceTokenizer, loadVocabFromFile, parseVocab, loadRuntime, detectRuntime, getRuntimeType, type INERModel, type NERModelConfig, type NERPrediction, type NERModelMode, type DownloadProgressCallback, type OrtSessionOptions, MODEL_REGISTRY, getModelCacheDir, isModelDownloaded, downloadModel, ensureModel, clearModelCache, listDownloadedModels, } from "./ner/index.js";
12
+ export { prenormalize, resolveEntities, tagEntities, validateOutput, generateTag, parseTag, rehydrate, enrichSemantics, inferGender, classifyLocation, getDatabaseStats, hasName, hasLocation, isSemanticDataAvailable, isSemanticDataDownloaded, getSemanticDataCacheDir, getDataDirectory, downloadSemanticData, ensureSemanticData, initializeSemanticData, loadSemanticData, clearSemanticData, clearSemanticDataCache, getSemanticDataInfo, SEMANTIC_DATA_FILES, extractTitle, extractTitlesFromSpans, mergeAdjacentTitleSpans, getTitlesForLanguage, getAllTitles, startsWithTitle, isOnlyTitle, type SemanticDataFileInfo, type EnricherConfig, type GenderResult, type LocationResult, type TitleExtractionResult, } from "./pipeline/index.js";
13
+ export type { KeyProvider } from "./crypto/index.js";
14
+ export { encryptPIIMap, decryptPIIMap, generateKey, deriveKey, generateSalt, InMemoryKeyProvider, ConfigKeyProvider, validateKey, secureCompare, uint8ArrayToBase64, base64ToUint8Array, } from "./crypto/index.js";
15
+ export { getStorageProvider, isNode, isBrowser, resetStorageProvider, setStorageProvider, type StorageProvider, } from "#storage";
16
+ export { type PIIStorageProvider, type PIIMapMetadata, type StoredPIIMap, type ListOptions, type AnonymizerSession, InMemoryPIIStorageProvider, IndexedDBPIIStorageProvider, } from "./storage/browser.js";
17
+ export { join as pathJoin, dirname as pathDirname, basename as pathBasename, normalize as pathNormalize, extname as pathExtname, isAbsolute as pathIsAbsolute, } from "./utils/path.js";
18
+ import { Anonymizer as AnonymizerCore, anonymize as anonymizeCore, anonymizeRegexOnly as anonymizeRegexOnlyCore, anonymizeWithNER as anonymizeWithNERCore, type AnonymizerConfig, type NERConfig } from "./core/index.js";
19
+ export type { AnonymizerConfig, NERConfig };
20
+ /**
21
+ * Anonymizer instance
22
+ * Main class for performing PII anonymization
23
+ */
24
+ export declare class Anonymizer extends AnonymizerCore {
25
+ constructor(config?: AnonymizerConfig);
26
+ }
27
+ /**
28
+ * Creates an anonymizer with the specified configuration
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * // Regex-only (no NER)
33
+ * const anonymizer = createAnonymizer();
34
+ *
35
+ * // With NER (auto-downloads model on first use)
36
+ * const anonymizer = createAnonymizer({
37
+ * ner: { mode: 'quantized' }
38
+ * });
39
+ *
40
+ * // With NER and progress callback
41
+ * const anonymizer = createAnonymizer({
42
+ * ner: {
43
+ * mode: 'standard',
44
+ * onStatus: (status) => console.log(status),
45
+ * onDownloadProgress: (p) => console.log(`${p.file}: ${p.percent}%`)
46
+ * }
47
+ * });
48
+ * ```
49
+ */
50
+ export declare function createAnonymizer(config?: AnonymizerConfig): Anonymizer;
51
+ export declare const anonymize: typeof anonymizeCore;
52
+ export declare const anonymizeRegexOnly: typeof anonymizeRegexOnlyCore;
53
+ export declare const anonymizeWithNER: typeof anonymizeWithNERCore;
54
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,cAAc,kBAAkB,CAAC;AAGjC,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,mBAAmB,EACnB,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,EACb,wBAAwB,EACxB,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,aAAa,EACb,cAAc,EACd,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,wBAAwB,EAC7B,KAAK,iBAAiB,EACtB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,eAAe,EACf,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,YAAY,EACZ,eAAe,EACf,WAAW,EACX,cAAc,EACd,WAAW,EACX,QAAQ,EACR,SAAS,EACT,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,OAAO,EACP,WAAW,EAEX,uBAAuB,EACvB,wBAAwB,EACxB,uBAAuB,EACvB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EAEnB,YAAY,EACZ,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,EACpB,YAAY,EACZ,eAAe,EACf,WAAW,EACX,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,qBAAqB,GAC3B,MAAM,qBAAqB,CAAC;AAG7B,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EACL,aAAa,EACb,aAAa,EACb,WAAW,EACX,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,kBAAkB,EAClB,MAAM,EACN,SAAS,EACT,oBAAoB,EACpB,kBAAkB,EAClB,KAAK,eAAe,GACrB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,0BAA0B,EAC1B,2BAA2B,GAG5B,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,IAAI,IAAI,QAAQ,EAChB,OAAO,IAAI,WAAW,EACtB,QAAQ,IAAI,YAAY,EACxB,SAAS,IAAI,aAAa,EAC1B,OAAO,IAAI,WAAW,EACtB,UAAU,IAAI,cAAc,GAC7B,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,UAAU,IAAI,cAAc,EAC5B,SAAS,IAAI,aAAa,EAC1B,kBAAkB,IAAI,sBAAsB,EAC5C,gBAAgB,IAAI,oBAAoB,EACxC,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACf,MAAM,iBAAiB,CAAC;AAMzB,YAAY,EAAE,gBAAgB,EAAE,SAAS,EAAE,CAAC;AAE5C;;;GAGG;AACH,qBAAa,UAAW,SAAQ,cAAc;gBAChC,MAAM,GAAE,gBAAqB;CAU1C;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,CAAC,EAAE,gBAAgB,GAAG,UAAU,CAEtE;AAGD,eAAO,MAAM,SAAS,sBAAgB,CAAC;AACvC,eAAO,MAAM,kBAAkB,+BAAyB,CAAC;AACzD,eAAO,MAAM,gBAAgB,6BAAuB,CAAC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Rehydra Module - Browser Entry Point
3
+ * Browser-safe entry point for on-device PII anonymization
4
+ *
5
+ * This module excludes Node.js-specific exports like SQLitePIIStorageProvider.
6
+ * For full functionality including SQLite, use the main entry point or import from 'rehydra/node'.
7
+ */
8
+ // Re-export types
9
+ export * from "./types/index.js";
10
+ export { RegexRecognizer, RecognizerRegistry, createDefaultRegistry, createRegistry, getGlobalRegistry, emailRecognizer, phoneRecognizer, ukPostalCodeRecognizer, streetAddressRecognizer, UK_POSTAL_CODE_PATTERN, isValidUKPostalCode, normalizeUKPostalCode, ibanRecognizer, bicSwiftRecognizer, creditCardRecognizer, ipAddressRecognizer, urlRecognizer, createCustomIdRecognizer, createCaseIdRecognizer, createCustomerIdRecognizer, } from "./recognizers/index.js";
11
+ // Re-export NER components
12
+ export { NERModel, NERModelStub, createNERModel, createNERModelStub, WordPieceTokenizer, loadVocabFromFile, parseVocab, loadRuntime, detectRuntime, getRuntimeType, MODEL_REGISTRY, getModelCacheDir, isModelDownloaded, downloadModel, ensureModel, clearModelCache, listDownloadedModels, } from "./ner/index.js";
13
+ // Re-export pipeline components
14
+ export { prenormalize, resolveEntities, tagEntities, validateOutput, generateTag, parseTag, rehydrate, enrichSemantics, inferGender, classifyLocation, getDatabaseStats, hasName, hasLocation,
15
+ // Semantic data loader exports
16
+ isSemanticDataAvailable, isSemanticDataDownloaded, getSemanticDataCacheDir, getDataDirectory, downloadSemanticData, ensureSemanticData, initializeSemanticData, loadSemanticData, clearSemanticData, clearSemanticDataCache, getSemanticDataInfo, SEMANTIC_DATA_FILES,
17
+ // Title extractor exports
18
+ extractTitle, extractTitlesFromSpans, mergeAdjacentTitleSpans, getTitlesForLanguage, getAllTitles, startsWithTitle, isOnlyTitle, } from "./pipeline/index.js";
19
+ export { encryptPIIMap, decryptPIIMap, generateKey, deriveKey, generateSalt, InMemoryKeyProvider, ConfigKeyProvider, validateKey, secureCompare, uint8ArrayToBase64, base64ToUint8Array, } from "./crypto/index.js";
20
+ // Re-export storage utilities (file system abstraction)
21
+ export { getStorageProvider, isNode, isBrowser, resetStorageProvider, setStorageProvider, } from "#storage";
22
+ // Re-export PII storage providers (browser-safe only - no SQLite)
23
+ export { InMemoryPIIStorageProvider, IndexedDBPIIStorageProvider,
24
+ // Note: SQLitePIIStorageProvider is NOT exported in browser build
25
+ // Import from 'rehydra/storage/sqlite' if needed in Node.js
26
+ } from "./storage/browser.js";
27
+ // Re-export path utilities
28
+ export { join as pathJoin, dirname as pathDirname, basename as pathBasename, normalize as pathNormalize, extname as pathExtname, isAbsolute as pathIsAbsolute, } from "./utils/path.js";
29
+ // Import core anonymizer components
30
+ import { Anonymizer as AnonymizerCore, anonymize as anonymizeCore, anonymizeRegexOnly as anonymizeRegexOnlyCore, anonymizeWithNER as anonymizeWithNERCore, } from "./core/index.js";
31
+ // Import session implementation
32
+ import { AnonymizerSessionImpl } from "./storage/session-base.js";
33
+ /**
34
+ * Anonymizer instance
35
+ * Main class for performing PII anonymization
36
+ */
37
+ export class Anonymizer extends AnonymizerCore {
38
+ constructor(config = {}) {
39
+ super(config, (anonymizer, sessionId, storage, keyProvider) => {
40
+ return new AnonymizerSessionImpl(anonymizer, sessionId, storage, keyProvider);
41
+ });
42
+ }
43
+ }
44
+ /**
45
+ * Creates an anonymizer with the specified configuration
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * // Regex-only (no NER)
50
+ * const anonymizer = createAnonymizer();
51
+ *
52
+ * // With NER (auto-downloads model on first use)
53
+ * const anonymizer = createAnonymizer({
54
+ * ner: { mode: 'quantized' }
55
+ * });
56
+ *
57
+ * // With NER and progress callback
58
+ * const anonymizer = createAnonymizer({
59
+ * ner: {
60
+ * mode: 'standard',
61
+ * onStatus: (status) => console.log(status),
62
+ * onDownloadProgress: (p) => console.log(`${p.file}: ${p.percent}%`)
63
+ * }
64
+ * });
65
+ * ```
66
+ */
67
+ export function createAnonymizer(config) {
68
+ return new Anonymizer(config);
69
+ }
70
+ // Re-export standalone functions from core
71
+ export const anonymize = anonymizeCore;
72
+ export const anonymizeRegexOnly = anonymizeRegexOnlyCore;
73
+ export const anonymizeWithNER = anonymizeWithNERCore;
74
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"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"}