@theokit/sdk 4.37.2 → 4.39.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 (457) hide show
  1. package/CHANGELOG.md +309 -72
  2. package/dist/a2a/index.cjs +3 -3
  3. package/dist/a2a/index.js +1 -1
  4. package/dist/a2a/subagent.d.cts +1 -0
  5. package/dist/a2a/subagent.d.ts +1 -0
  6. package/dist/{agent-SmxntivO.d.ts → agent-D7bRK9Kg.d.cts} +108 -41
  7. package/dist/agent-I3EZZR6S.cjs +55 -0
  8. package/dist/{agent-IE6IE4NW.cjs.map → agent-I3EZZR6S.cjs.map} +1 -1
  9. package/dist/agent-KKZYLY5D.js +46 -0
  10. package/dist/{agent-DW2J37IH.js.map → agent-KKZYLY5D.js.map} +1 -1
  11. package/dist/{agent-DGv1-d81.d.cts → agent-ZCZa7YQv.d.ts} +108 -41
  12. package/dist/agent-session-store-N4TVKHBU.cjs +23 -0
  13. package/dist/agent-session-store-N4TVKHBU.cjs.map +1 -0
  14. package/dist/agent-session-store-RHMHP5DG.js +6 -0
  15. package/dist/agent-session-store-RHMHP5DG.js.map +1 -0
  16. package/dist/agent.d.ts +38 -2
  17. package/dist/auth/index.cjs +15 -15
  18. package/dist/auth/index.js +4 -4
  19. package/dist/{batch-SY5GZLFD.js → batch-6KQM3EBA.js} +12 -12
  20. package/dist/batch-6KQM3EBA.js.map +1 -0
  21. package/dist/{batch-3SEPDXCU.cjs → batch-X6JKGDPK.cjs} +26 -26
  22. package/dist/batch-X6JKGDPK.cjs.map +1 -0
  23. package/dist/chunk-2RW7K6FN.cjs +34 -0
  24. package/dist/chunk-2RW7K6FN.cjs.map +1 -0
  25. package/dist/chunk-3I4B3OIX.js +105 -0
  26. package/dist/chunk-3I4B3OIX.js.map +1 -0
  27. package/dist/{chunk-2WFB5ZOX.js → chunk-42IFCKQZ.js} +5 -5
  28. package/dist/{chunk-2WFB5ZOX.js.map → chunk-42IFCKQZ.js.map} +1 -1
  29. package/dist/{chunk-DCJ5MCJ3.js → chunk-4F7JQZOX.js} +9 -36
  30. package/dist/chunk-4F7JQZOX.js.map +1 -0
  31. package/dist/{chunk-JNIWFCKI.js → chunk-4JSZYSGW.js} +3 -3
  32. package/dist/{chunk-JNIWFCKI.js.map → chunk-4JSZYSGW.js.map} +1 -1
  33. package/dist/{chunk-EEZ7CFMM.js → chunk-5KOW3GLE.js} +2 -2
  34. package/dist/chunk-5KOW3GLE.js.map +1 -0
  35. package/dist/{chunk-6VP3XGEK.js → chunk-65ONFZWM.js} +12 -11
  36. package/dist/chunk-65ONFZWM.js.map +1 -0
  37. package/dist/{chunk-CSZRJ4RE.js → chunk-6EEYRFJC.js} +5 -5
  38. package/dist/{chunk-CSZRJ4RE.js.map → chunk-6EEYRFJC.js.map} +1 -1
  39. package/dist/{chunk-FAY3QDGC.cjs → chunk-6LGQECT7.cjs} +11 -11
  40. package/dist/{chunk-FAY3QDGC.cjs.map → chunk-6LGQECT7.cjs.map} +1 -1
  41. package/dist/{chunk-PAEJPLVN.cjs → chunk-6NEHIHFU.cjs} +4 -4
  42. package/dist/{chunk-PAEJPLVN.cjs.map → chunk-6NEHIHFU.cjs.map} +1 -1
  43. package/dist/chunk-6YNYA7GD.cjs +103 -0
  44. package/dist/chunk-6YNYA7GD.cjs.map +1 -0
  45. package/dist/chunk-74D7KSBP.cjs +112 -0
  46. package/dist/chunk-74D7KSBP.cjs.map +1 -0
  47. package/dist/{chunk-FK4EJD2I.cjs → chunk-75DSEWTJ.cjs} +7 -7
  48. package/dist/{chunk-FK4EJD2I.cjs.map → chunk-75DSEWTJ.cjs.map} +1 -1
  49. package/dist/{chunk-SWIBQFPH.cjs → chunk-7OLG7VI4.cjs} +4 -4
  50. package/dist/{chunk-SWIBQFPH.cjs.map → chunk-7OLG7VI4.cjs.map} +1 -1
  51. package/dist/chunk-7U2HAAWB.cjs +199 -0
  52. package/dist/chunk-7U2HAAWB.cjs.map +1 -0
  53. package/dist/{chunk-YBFDBOUN.cjs → chunk-7YBJZS5P.cjs} +8 -8
  54. package/dist/{chunk-YBFDBOUN.cjs.map → chunk-7YBJZS5P.cjs.map} +1 -1
  55. package/dist/{chunk-GLUWH6JO.js → chunk-AECV3G5Z.js} +4 -4
  56. package/dist/{chunk-GLUWH6JO.js.map → chunk-AECV3G5Z.js.map} +1 -1
  57. package/dist/{chunk-UQPDFW4E.js → chunk-AR5MQZ3J.js} +3 -3
  58. package/dist/{chunk-UQPDFW4E.js.map → chunk-AR5MQZ3J.js.map} +1 -1
  59. package/dist/{chunk-G2F67XUR.cjs → chunk-B4YA6BRS.cjs} +13 -14
  60. package/dist/chunk-B4YA6BRS.cjs.map +1 -0
  61. package/dist/{chunk-LTCOPATU.cjs → chunk-BCQ3E2ZG.cjs} +12 -3
  62. package/dist/chunk-BCQ3E2ZG.cjs.map +1 -0
  63. package/dist/{chunk-ALU3KC4G.cjs → chunk-BPN5ONSW.cjs} +223 -277
  64. package/dist/chunk-BPN5ONSW.cjs.map +1 -0
  65. package/dist/{chunk-YHZXBDAW.js → chunk-BQDUEG4C.js} +16 -16
  66. package/dist/{chunk-YHZXBDAW.js.map → chunk-BQDUEG4C.js.map} +1 -1
  67. package/dist/{chunk-IT3PWBW4.cjs → chunk-BURYFNOM.cjs} +2 -2
  68. package/dist/chunk-BURYFNOM.cjs.map +1 -0
  69. package/dist/{chunk-BJMKQOY2.cjs → chunk-C7OP3FAK.cjs} +47 -11
  70. package/dist/chunk-C7OP3FAK.cjs.map +1 -0
  71. package/dist/{chunk-XAYVHS2B.cjs → chunk-CEIHCKTO.cjs} +4 -4
  72. package/dist/chunk-CEIHCKTO.cjs.map +1 -0
  73. package/dist/{chunk-2423XDPT.cjs → chunk-CN6UX5EV.cjs} +28 -56
  74. package/dist/chunk-CN6UX5EV.cjs.map +1 -0
  75. package/dist/{chunk-VNNK6AKU.js → chunk-D7IULBF2.js} +3 -3
  76. package/dist/chunk-D7IULBF2.js.map +1 -0
  77. package/dist/chunk-DCXRHCZJ.cjs +118 -0
  78. package/dist/chunk-DCXRHCZJ.cjs.map +1 -0
  79. package/dist/{chunk-ICYBIC6N.cjs → chunk-DGLLVCNB.cjs} +4 -4
  80. package/dist/chunk-DGLLVCNB.cjs.map +1 -0
  81. package/dist/{chunk-I35DI7ES.js → chunk-DKFGUOWL.js} +3 -3
  82. package/dist/{chunk-I35DI7ES.js.map → chunk-DKFGUOWL.js.map} +1 -1
  83. package/dist/{chunk-TQI3KRXZ.cjs → chunk-DMTZ3FII.cjs} +18 -18
  84. package/dist/{chunk-TQI3KRXZ.cjs.map → chunk-DMTZ3FII.cjs.map} +1 -1
  85. package/dist/{chunk-QFMXXUUT.js → chunk-DU7DE543.js} +3 -3
  86. package/dist/{chunk-QFMXXUUT.js.map → chunk-DU7DE543.js.map} +1 -1
  87. package/dist/{chunk-W4QN5CMG.cjs → chunk-DWY25VLP.cjs} +9 -9
  88. package/dist/{chunk-W4QN5CMG.cjs.map → chunk-DWY25VLP.cjs.map} +1 -1
  89. package/dist/chunk-E2FFG33C.js +109 -0
  90. package/dist/chunk-E2FFG33C.js.map +1 -0
  91. package/dist/{chunk-QUFSDDNU.cjs → chunk-E4IUN3JB.cjs} +15 -15
  92. package/dist/{chunk-QUFSDDNU.cjs.map → chunk-E4IUN3JB.cjs.map} +1 -1
  93. package/dist/{chunk-THEYGCYS.cjs → chunk-ECHGWE47.cjs} +4 -4
  94. package/dist/chunk-ECHGWE47.cjs.map +1 -0
  95. package/dist/{chunk-U2WLFOA3.cjs → chunk-ECW2MLEW.cjs} +4 -4
  96. package/dist/{chunk-U2WLFOA3.cjs.map → chunk-ECW2MLEW.cjs.map} +1 -1
  97. package/dist/{chunk-MXSMAGDU.js → chunk-ET6PHZRX.js} +33 -26
  98. package/dist/chunk-ET6PHZRX.js.map +1 -0
  99. package/dist/{chunk-G6AASL5T.cjs → chunk-FRUBE44B.cjs} +24 -24
  100. package/dist/{chunk-G6AASL5T.cjs.map → chunk-FRUBE44B.cjs.map} +1 -1
  101. package/dist/{chunk-3ILFUXNE.cjs → chunk-FWBSDQZ7.cjs} +5 -5
  102. package/dist/{chunk-3ILFUXNE.cjs.map → chunk-FWBSDQZ7.cjs.map} +1 -1
  103. package/dist/{chunk-7DXLNNKH.cjs → chunk-G2Q3ZC6C.cjs} +4 -4
  104. package/dist/{chunk-7DXLNNKH.cjs.map → chunk-G2Q3ZC6C.cjs.map} +1 -1
  105. package/dist/{chunk-56ZM6P7Z.cjs → chunk-G4XUXSRN.cjs} +12 -12
  106. package/dist/chunk-G4XUXSRN.cjs.map +1 -0
  107. package/dist/{chunk-VYJSHGAY.js → chunk-GIRD3RWH.js} +422 -295
  108. package/dist/chunk-GIRD3RWH.js.map +1 -0
  109. package/dist/{chunk-NQ4AC2U4.cjs → chunk-HIQFVHC6.cjs} +9 -9
  110. package/dist/{chunk-NQ4AC2U4.cjs.map → chunk-HIQFVHC6.cjs.map} +1 -1
  111. package/dist/{chunk-EXQV452X.js → chunk-HWNVAUK4.js} +3 -3
  112. package/dist/{chunk-EXQV452X.js.map → chunk-HWNVAUK4.js.map} +1 -1
  113. package/dist/{chunk-P34DHHYQ.cjs → chunk-I53ZQHU6.cjs} +34 -27
  114. package/dist/chunk-I53ZQHU6.cjs.map +1 -0
  115. package/dist/{chunk-MHCKWQR3.cjs → chunk-IHFNRNTJ.cjs} +8 -8
  116. package/dist/{chunk-MHCKWQR3.cjs.map → chunk-IHFNRNTJ.cjs.map} +1 -1
  117. package/dist/{chunk-W52DKZBR.cjs → chunk-INSFS5GT.cjs} +680 -553
  118. package/dist/chunk-INSFS5GT.cjs.map +1 -0
  119. package/dist/{chunk-TAPQWDW2.js → chunk-IVSD7L22.js} +12 -4
  120. package/dist/chunk-IVSD7L22.js.map +1 -0
  121. package/dist/{chunk-WDGCZDRG.js → chunk-J3UK2GMN.js} +3 -3
  122. package/dist/{chunk-WDGCZDRG.js.map → chunk-J3UK2GMN.js.map} +1 -1
  123. package/dist/{chunk-4YB7B3RP.cjs → chunk-J6T5LWJ4.cjs} +15 -14
  124. package/dist/chunk-J6T5LWJ4.cjs.map +1 -0
  125. package/dist/{chunk-XAEAMI5H.js → chunk-JRLXEYR4.js} +21 -5
  126. package/dist/chunk-JRLXEYR4.js.map +1 -0
  127. package/dist/{chunk-ZJN6NTHE.js → chunk-JZUPMTJY.js} +3 -3
  128. package/dist/{chunk-ZJN6NTHE.js.map → chunk-JZUPMTJY.js.map} +1 -1
  129. package/dist/{chunk-M5ZQBOIZ.js → chunk-KE6XKRLQ.js} +3 -3
  130. package/dist/{chunk-M5ZQBOIZ.js.map → chunk-KE6XKRLQ.js.map} +1 -1
  131. package/dist/chunk-KGRIHEDT.js +110 -0
  132. package/dist/chunk-KGRIHEDT.js.map +1 -0
  133. package/dist/{chunk-T4QWDOG6.js → chunk-KWUNN5J2.js} +5 -5
  134. package/dist/{chunk-T4QWDOG6.js.map → chunk-KWUNN5J2.js.map} +1 -1
  135. package/dist/{chunk-56OXYUZE.js → chunk-KX7JV5KM.js} +3 -3
  136. package/dist/chunk-KX7JV5KM.js.map +1 -0
  137. package/dist/{chunk-D4ZUJTFB.cjs → chunk-LALG2K33.cjs} +8 -8
  138. package/dist/{chunk-D4ZUJTFB.cjs.map → chunk-LALG2K33.cjs.map} +1 -1
  139. package/dist/{chunk-QGDKZDPN.js → chunk-LGILIGV3.js} +3 -3
  140. package/dist/{chunk-QGDKZDPN.js.map → chunk-LGILIGV3.js.map} +1 -1
  141. package/dist/{chunk-HEN5WXXI.js → chunk-LJX2SQV2.js} +6 -6
  142. package/dist/{chunk-HEN5WXXI.js.map → chunk-LJX2SQV2.js.map} +1 -1
  143. package/dist/{chunk-SDIBMLL5.js → chunk-MC5EINBV.js} +44 -8
  144. package/dist/chunk-MC5EINBV.js.map +1 -0
  145. package/dist/{chunk-F6Y4IEQM.js → chunk-ML5A5DOJ.js} +4 -4
  146. package/dist/{chunk-F6Y4IEQM.js.map → chunk-ML5A5DOJ.js.map} +1 -1
  147. package/dist/{chunk-6EDQBX7U.cjs → chunk-N475ETD6.cjs} +17 -17
  148. package/dist/{chunk-6EDQBX7U.cjs.map → chunk-N475ETD6.cjs.map} +1 -1
  149. package/dist/{chunk-YPQF26X7.cjs → chunk-OBA6YK2R.cjs} +2 -2
  150. package/dist/chunk-OBA6YK2R.cjs.map +1 -0
  151. package/dist/chunk-OXNYIMZZ.js +31 -0
  152. package/dist/chunk-OXNYIMZZ.js.map +1 -0
  153. package/dist/{chunk-NFCKEBHI.js → chunk-PI4RO4GR.js} +3 -3
  154. package/dist/{chunk-NFCKEBHI.js.map → chunk-PI4RO4GR.js.map} +1 -1
  155. package/dist/{chunk-2ONFGMBV.js → chunk-PY2RQOA7.js} +2 -2
  156. package/dist/chunk-PY2RQOA7.js.map +1 -0
  157. package/dist/chunk-QKE556YD.js +197 -0
  158. package/dist/chunk-QKE556YD.js.map +1 -0
  159. package/dist/{chunk-FV3YEMQ7.js → chunk-RP5HQVLD.js} +13 -14
  160. package/dist/chunk-RP5HQVLD.js.map +1 -0
  161. package/dist/chunk-SCFW5MJZ.js +100 -0
  162. package/dist/chunk-SCFW5MJZ.js.map +1 -0
  163. package/dist/{chunk-CD73YHEH.js → chunk-SG5ZWT6C.js} +3 -3
  164. package/dist/{chunk-CD73YHEH.js.map → chunk-SG5ZWT6C.js.map} +1 -1
  165. package/dist/{chunk-MRODLUGY.cjs → chunk-TIMPJL5V.cjs} +4 -4
  166. package/dist/{chunk-MRODLUGY.cjs.map → chunk-TIMPJL5V.cjs.map} +1 -1
  167. package/dist/{chunk-77WHPVXE.js → chunk-TOTP24P6.js} +4 -4
  168. package/dist/chunk-TOTP24P6.js.map +1 -0
  169. package/dist/{chunk-3O2ELBST.cjs → chunk-USZTVNUQ.cjs} +5 -5
  170. package/dist/{chunk-3O2ELBST.cjs.map → chunk-USZTVNUQ.cjs.map} +1 -1
  171. package/dist/{chunk-YDLNI7J6.js → chunk-V2RBCCN5.js} +3 -3
  172. package/dist/chunk-V2RBCCN5.js.map +1 -0
  173. package/dist/{chunk-NNSKJCBM.cjs → chunk-VJYSQXN6.cjs} +10 -10
  174. package/dist/{chunk-NNSKJCBM.cjs.map → chunk-VJYSQXN6.cjs.map} +1 -1
  175. package/dist/{chunk-GM7QDQ24.cjs → chunk-W4WKVOOQ.cjs} +11 -11
  176. package/dist/{chunk-GM7QDQ24.cjs.map → chunk-W4WKVOOQ.cjs.map} +1 -1
  177. package/dist/chunk-XYOHKCYG.cjs +109 -0
  178. package/dist/chunk-XYOHKCYG.cjs.map +1 -0
  179. package/dist/{chunk-ZW345YOI.js → chunk-YP67XZES.js} +4 -4
  180. package/dist/{chunk-ZW345YOI.js.map → chunk-YP67XZES.js.map} +1 -1
  181. package/dist/{chunk-YCXMSDSP.js → chunk-YRXY2A5L.js} +4 -4
  182. package/dist/{chunk-YCXMSDSP.js.map → chunk-YRXY2A5L.js.map} +1 -1
  183. package/dist/{chunk-IEUDKUPM.cjs → chunk-Z2CUEBXV.cjs} +25 -9
  184. package/dist/chunk-Z2CUEBXV.cjs.map +1 -0
  185. package/dist/{chunk-GL7CFBVC.js → chunk-ZYB6B7QJ.js} +112 -165
  186. package/dist/chunk-ZYB6B7QJ.js.map +1 -0
  187. package/dist/compact-session-PYEC3NZV.js +18 -0
  188. package/dist/{compact-session-WNKKIIDW.js.map → compact-session-PYEC3NZV.js.map} +1 -1
  189. package/dist/compact-session-VVT6IBJG.cjs +55 -0
  190. package/dist/{compact-session-H5TKLD55.cjs.map → compact-session-VVT6IBJG.cjs.map} +1 -1
  191. package/dist/compaction.cjs +19 -19
  192. package/dist/compaction.d.cts +9 -9
  193. package/dist/compaction.d.ts +9 -9
  194. package/dist/compaction.js +3 -3
  195. package/dist/concurrency.cjs +6 -6
  196. package/dist/concurrency.js +4 -4
  197. package/dist/context-2FZSC6VQ.cjs +22 -0
  198. package/dist/{context-ZV33V4DC.cjs.map → context-2FZSC6VQ.cjs.map} +1 -1
  199. package/dist/context-ATJJAFOS.js +5 -0
  200. package/dist/{context-VAYLPT4O.js.map → context-ATJJAFOS.js.map} +1 -1
  201. package/dist/{cron-Dx7B-3WB.d.ts → cron-Bx7tzm5R.d.ts} +54 -2
  202. package/dist/{cron-BiK_aNJI.d.cts → cron-D-DVjGQe.d.cts} +54 -2
  203. package/dist/cron.cjs +34 -30
  204. package/dist/cron.d.cts +3 -3
  205. package/dist/cron.d.ts +3 -3
  206. package/dist/cron.js +33 -29
  207. package/dist/{errors-DyVbXdR4.d.cts → errors-DMY-gLSK.d.cts} +1 -1
  208. package/dist/{errors-Cua4WC9H.d.ts → errors-DjBQ4Tn8.d.ts} +1 -1
  209. package/dist/errors.cjs +21 -21
  210. package/dist/errors.d.cts +2 -2
  211. package/dist/errors.d.ts +2 -2
  212. package/dist/errors.js +2 -2
  213. package/dist/eval.cjs +42 -37
  214. package/dist/eval.cjs.map +1 -1
  215. package/dist/eval.js +38 -33
  216. package/dist/eval.js.map +1 -1
  217. package/dist/{executor-OZSYXDKF.cjs → executor-BMRICN46.cjs} +26 -25
  218. package/dist/executor-BMRICN46.cjs.map +1 -0
  219. package/dist/{executor-PAH72CB5.js → executor-T65PPOPT.js} +10 -9
  220. package/dist/executor-T65PPOPT.js.map +1 -0
  221. package/dist/filesystem/index.cjs +7 -7
  222. package/dist/filesystem/index.js +3 -3
  223. package/dist/fs-session-store-J5MCFFUM.cjs +19 -0
  224. package/dist/{fs-session-store-7E7UPLF2.cjs.map → fs-session-store-J5MCFFUM.cjs.map} +1 -1
  225. package/dist/fs-session-store-O6FNHECD.js +10 -0
  226. package/dist/{fs-session-store-6MY7PNI2.js.map → fs-session-store-O6FNHECD.js.map} +1 -1
  227. package/dist/generate-object-UF6WIZLF.cjs +20 -0
  228. package/dist/{generate-object-5SCEH2EE.cjs.map → generate-object-UF6WIZLF.cjs.map} +1 -1
  229. package/dist/generate-object-XDCBYVK3.js +7 -0
  230. package/dist/{generate-object-I7UD4NWN.js.map → generate-object-XDCBYVK3.js.map} +1 -1
  231. package/dist/index-manager-N7RQYUKT.cjs +20 -0
  232. package/dist/{index-manager-R6ZJFEZF.cjs.map → index-manager-N7RQYUKT.cjs.map} +1 -1
  233. package/dist/index-manager-ZVZUHPP7.js +11 -0
  234. package/dist/{index-manager-KKAK7NT3.js.map → index-manager-ZVZUHPP7.js.map} +1 -1
  235. package/dist/index.cjs +154 -148
  236. package/dist/index.cjs.map +1 -1
  237. package/dist/index.d.cts +201 -43
  238. package/dist/index.d.ts +201 -43
  239. package/dist/index.js +62 -59
  240. package/dist/index.js.map +1 -1
  241. package/dist/{inject-session-UXNJQTZ6.js → inject-session-GQMTDZUN.js} +8 -7
  242. package/dist/inject-session-GQMTDZUN.js.map +1 -0
  243. package/dist/{inject-session-DM4SKTZO.cjs → inject-session-LFCYVSLJ.cjs} +11 -10
  244. package/dist/inject-session-LFCYVSLJ.cjs.map +1 -0
  245. package/dist/internal/agent-loop/live-events.d.ts +46 -0
  246. package/dist/internal/agent-loop/loop-thinking-steps.d.ts +28 -0
  247. package/dist/internal/agent-loop/message-builders.d.ts +12 -3
  248. package/dist/internal/budget/compute-cost.d.ts +1 -1
  249. package/dist/internal/diagnostics.d.ts +46 -31
  250. package/dist/internal/error-mappers/anthropic.d.ts +1 -1
  251. package/dist/internal/global-singleton.d.ts +7 -7
  252. package/dist/internal/judge/judge-call.d.ts +14 -14
  253. package/dist/internal/llm/anthropic-shared.d.ts +4 -4
  254. package/dist/internal/llm/retrying-client.d.ts +29 -29
  255. package/dist/internal/llm/transport-error.d.ts +2 -2
  256. package/dist/internal/llm/types.d.ts +49 -9
  257. package/dist/internal/local-agent/mcp-pool.d.ts +7 -3
  258. package/dist/internal/memory/adapters/azure-openai-embedding.d.cts +2 -0
  259. package/dist/internal/memory/adapters/catalog.d.cts +1 -0
  260. package/dist/internal/memory/adapters/cohere-embedding.d.cts +2 -0
  261. package/dist/internal/memory/adapters/deepinfra-embedding.d.cts +2 -0
  262. package/dist/internal/memory/adapters/gemini-embedding.d.cts +2 -0
  263. package/dist/internal/memory/adapters/index.cjs +28 -0
  264. package/dist/internal/memory/adapters/index.cjs.map +1 -0
  265. package/dist/internal/memory/adapters/index.d.cts +16 -0
  266. package/dist/internal/memory/adapters/index.d.ts +16 -0
  267. package/dist/internal/memory/adapters/index.js +11 -0
  268. package/dist/internal/memory/adapters/index.js.map +1 -0
  269. package/dist/internal/memory/adapters/jina-embedding.d.cts +2 -0
  270. package/dist/internal/memory/adapters/mistral-embedding.d.cts +2 -0
  271. package/dist/internal/memory/adapters/ollama-embedding.d.cts +34 -0
  272. package/dist/internal/memory/adapters/openai-compatible.d.cts +51 -0
  273. package/dist/internal/memory/adapters/openai-compatible.d.ts +28 -0
  274. package/dist/internal/memory/adapters/openai-embedding.d.cts +2 -0
  275. package/dist/internal/memory/adapters/openrouter-embedding.d.cts +2 -0
  276. package/dist/internal/memory/adapters/voyage-embedding.d.cts +2 -0
  277. package/dist/internal/memory/dreaming/diary.d.ts +4 -0
  278. package/dist/internal/memory/dreaming/phases.d.ts +15 -0
  279. package/dist/internal/memory/dreaming/run.d.ts +10 -0
  280. package/dist/internal/memory/migrate-sqlite-to-lance.d.ts +15 -0
  281. package/dist/internal/memory/sdk-memory-peer-loader.d.ts +21 -0
  282. package/dist/internal/persistence/exclusive-create.d.cts +2 -2
  283. package/dist/internal/persistence/exclusive-create.d.ts +2 -2
  284. package/dist/internal/persistence/fs-session-store.d.cts +18 -18
  285. package/dist/internal/persistence/fs-session-store.d.ts +18 -18
  286. package/dist/internal/persistence/index.cjs +25 -25
  287. package/dist/internal/persistence/index.cjs.map +1 -1
  288. package/dist/internal/persistence/index.js +6 -6
  289. package/dist/internal/persistence/index.js.map +1 -1
  290. package/dist/internal/persistence/paths.d.cts +7 -7
  291. package/dist/internal/persistence/paths.d.ts +7 -7
  292. package/dist/internal/persistence/session-transcript.d.cts +13 -7
  293. package/dist/internal/persistence/session-transcript.d.ts +13 -7
  294. package/dist/internal/persistence/session-writer.d.cts +30 -13
  295. package/dist/internal/persistence/session-writer.d.ts +30 -13
  296. package/dist/internal/runtime/concurrency/subagent-credentials.d.ts +35 -0
  297. package/dist/internal/runtime/fixtures/fixture-run-base.d.ts +45 -13
  298. package/dist/internal/runtime/lifecycle/goal-marker.d.ts +8 -8
  299. package/dist/internal/security/index.cjs +13 -13
  300. package/dist/internal/security/index.js +3 -3
  301. package/dist/internal/session/agent-session-store.d.ts +1 -0
  302. package/dist/internal/session/agent-session.d.ts +14 -14
  303. package/dist/internal/session/session-cache.d.ts +9 -9
  304. package/dist/internal/session/session-types.d.ts +6 -1
  305. package/dist/judge-call-NA2G6ZMJ.js +5 -0
  306. package/dist/{judge-call-TAEIXMYG.js.map → judge-call-NA2G6ZMJ.js.map} +1 -1
  307. package/dist/judge-call-U2D33JOW.cjs +22 -0
  308. package/dist/{judge-call-SP3G3X2Y.cjs.map → judge-call-U2D33JOW.cjs.map} +1 -1
  309. package/dist/models.cjs +20 -20
  310. package/dist/models.cjs.map +1 -1
  311. package/dist/models.js +5 -5
  312. package/dist/models.js.map +1 -1
  313. package/dist/path-safety.cjs +10 -10
  314. package/dist/path-safety.js +3 -3
  315. package/dist/persistence.cjs +43 -43
  316. package/dist/persistence.cjs.map +1 -1
  317. package/dist/persistence.d.cts +1 -1
  318. package/dist/persistence.d.ts +1 -1
  319. package/dist/persistence.js +14 -14
  320. package/dist/persistence.js.map +1 -1
  321. package/dist/project.cjs +5 -5
  322. package/dist/project.js +3 -3
  323. package/dist/registry-CAS6Y5ZY.js +9 -0
  324. package/dist/{registry-SOXE4RY6.js.map → registry-CAS6Y5ZY.js.map} +1 -1
  325. package/dist/registry-JSDI4WKA.cjs +46 -0
  326. package/dist/{registry-N3GTKYCI.cjs.map → registry-JSDI4WKA.cjs.map} +1 -1
  327. package/dist/retry.cjs +4 -4
  328. package/dist/retry.js +3 -3
  329. package/dist/{run-CwEJtLPE.d.ts → run-i2-fUohR.d.cts} +217 -174
  330. package/dist/{run-CwEJtLPE.d.cts → run-i2-fUohR.d.ts} +217 -174
  331. package/dist/{run-until-YZ2ODWOF.js → run-until-BK56WG4P.js} +3 -3
  332. package/dist/{run-until-YZ2ODWOF.js.map → run-until-BK56WG4P.js.map} +1 -1
  333. package/dist/{run-until-ZZ2JLPJM.cjs → run-until-L5KQD3PV.cjs} +4 -4
  334. package/dist/{run-until-ZZ2JLPJM.cjs.map → run-until-L5KQD3PV.cjs.map} +1 -1
  335. package/dist/sandbox/bwrap.d.cts +20 -20
  336. package/dist/sandbox/bwrap.d.ts +20 -20
  337. package/dist/sandbox/index.cjs +39 -39
  338. package/dist/sandbox/index.cjs.map +1 -1
  339. package/dist/sandbox/index.d.cts +1 -1
  340. package/dist/sandbox/index.d.ts +1 -1
  341. package/dist/sandbox/index.js +35 -35
  342. package/dist/sandbox/index.js.map +1 -1
  343. package/dist/sandbox/linux-sandbox.d.cts +26 -21
  344. package/dist/sandbox/linux-sandbox.d.ts +26 -21
  345. package/dist/server/auth/index.cjs.map +1 -1
  346. package/dist/server/auth/index.d.cts +6 -6
  347. package/dist/server/auth/index.d.ts +6 -6
  348. package/dist/server/auth/index.js.map +1 -1
  349. package/dist/server/auth/orchestrator.d.cts +2 -2
  350. package/dist/server/auth/orchestrator.d.ts +2 -2
  351. package/dist/server/auth/types.d.cts +4 -4
  352. package/dist/server/auth/types.d.ts +4 -4
  353. package/dist/server/errors-envelope.cjs +14 -14
  354. package/dist/server/errors-envelope.d.cts +3 -3
  355. package/dist/server/errors-envelope.d.ts +3 -3
  356. package/dist/server/errors-envelope.js +3 -3
  357. package/dist/session-transcript-3B52DKTG.js +5 -0
  358. package/dist/{session-transcript-6WKLYIN4.js.map → session-transcript-3B52DKTG.js.map} +1 -1
  359. package/dist/session-transcript-H7NUFXXM.cjs +50 -0
  360. package/dist/{session-transcript-EAKR4D2W.cjs.map → session-transcript-H7NUFXXM.cjs.map} +1 -1
  361. package/dist/skills.cjs +7 -7
  362. package/dist/skills.js +5 -5
  363. package/dist/stream-object-4FDU76YW.cjs +20 -0
  364. package/dist/{stream-object-Y7YCX3BI.cjs.map → stream-object-4FDU76YW.cjs.map} +1 -1
  365. package/dist/stream-object-HWDEEQN4.js +7 -0
  366. package/dist/{stream-object-OFM66VUT.js.map → stream-object-HWDEEQN4.js.map} +1 -1
  367. package/dist/subagents-loader-A4W6C3QP.cjs +15 -0
  368. package/dist/subagents-loader-A4W6C3QP.cjs.map +1 -0
  369. package/dist/subagents-loader-X33KH2SZ.js +6 -0
  370. package/dist/subagents-loader-X33KH2SZ.js.map +1 -0
  371. package/dist/subagents-loader.cjs +6 -6
  372. package/dist/subagents-loader.d.cts +2 -2
  373. package/dist/subagents-loader.d.ts +2 -2
  374. package/dist/subagents-loader.js +4 -4
  375. package/dist/subscription/index.cjs +3 -3
  376. package/dist/subscription/index.js +2 -2
  377. package/dist/task-store.cjs +7 -7
  378. package/dist/task-store.js +4 -4
  379. package/dist/types/agent-prims.d.ts +4 -4
  380. package/dist/types/agent.d.ts +68 -3
  381. package/dist/types/conversation.d.ts +7 -0
  382. package/dist/types/goal-events.d.ts +24 -23
  383. package/dist/types/messages.d.ts +9 -0
  384. package/dist/types/run.d.ts +27 -0
  385. package/dist/types/session-message.d.ts +59 -0
  386. package/dist/types/session-record.d.ts +14 -13
  387. package/dist/types/workflow.d.ts +36 -0
  388. package/dist/workflow.cjs +27 -27
  389. package/dist/workflow.d.cts +17 -1
  390. package/dist/workflow.d.ts +17 -1
  391. package/dist/workflow.js +6 -6
  392. package/docs/harness-capability-map.md +22 -0
  393. package/package.json +22 -13
  394. package/dist/agent-DW2J37IH.js +0 -42
  395. package/dist/agent-IE6IE4NW.cjs +0 -51
  396. package/dist/batch-3SEPDXCU.cjs.map +0 -1
  397. package/dist/batch-SY5GZLFD.js.map +0 -1
  398. package/dist/chunk-2423XDPT.cjs.map +0 -1
  399. package/dist/chunk-2ONFGMBV.js.map +0 -1
  400. package/dist/chunk-4YB7B3RP.cjs.map +0 -1
  401. package/dist/chunk-56OXYUZE.js.map +0 -1
  402. package/dist/chunk-56ZM6P7Z.cjs.map +0 -1
  403. package/dist/chunk-5SB4V74H.js +0 -176
  404. package/dist/chunk-5SB4V74H.js.map +0 -1
  405. package/dist/chunk-6VP3XGEK.js.map +0 -1
  406. package/dist/chunk-77WHPVXE.js.map +0 -1
  407. package/dist/chunk-ALU3KC4G.cjs.map +0 -1
  408. package/dist/chunk-BJMKQOY2.cjs.map +0 -1
  409. package/dist/chunk-DCJ5MCJ3.js.map +0 -1
  410. package/dist/chunk-EEZ7CFMM.js.map +0 -1
  411. package/dist/chunk-FV3YEMQ7.js.map +0 -1
  412. package/dist/chunk-G2F67XUR.cjs.map +0 -1
  413. package/dist/chunk-GL7CFBVC.js.map +0 -1
  414. package/dist/chunk-H5YVJB4K.cjs +0 -185
  415. package/dist/chunk-H5YVJB4K.cjs.map +0 -1
  416. package/dist/chunk-ICYBIC6N.cjs.map +0 -1
  417. package/dist/chunk-IEUDKUPM.cjs.map +0 -1
  418. package/dist/chunk-IT3PWBW4.cjs.map +0 -1
  419. package/dist/chunk-ITLS5LRF.cjs +0 -105
  420. package/dist/chunk-ITLS5LRF.cjs.map +0 -1
  421. package/dist/chunk-LTCOPATU.cjs.map +0 -1
  422. package/dist/chunk-MXSMAGDU.js.map +0 -1
  423. package/dist/chunk-P34DHHYQ.cjs.map +0 -1
  424. package/dist/chunk-SDIBMLL5.js.map +0 -1
  425. package/dist/chunk-TAPQWDW2.js.map +0 -1
  426. package/dist/chunk-THEYGCYS.cjs.map +0 -1
  427. package/dist/chunk-VNNK6AKU.js.map +0 -1
  428. package/dist/chunk-VYJSHGAY.js.map +0 -1
  429. package/dist/chunk-W52DKZBR.cjs.map +0 -1
  430. package/dist/chunk-XAEAMI5H.js.map +0 -1
  431. package/dist/chunk-XAYVHS2B.cjs.map +0 -1
  432. package/dist/chunk-YDLNI7J6.js.map +0 -1
  433. package/dist/chunk-YPQF26X7.cjs.map +0 -1
  434. package/dist/chunk-YVTNFKZO.js +0 -103
  435. package/dist/chunk-YVTNFKZO.js.map +0 -1
  436. package/dist/compact-session-H5TKLD55.cjs +0 -54
  437. package/dist/compact-session-WNKKIIDW.js +0 -17
  438. package/dist/context-VAYLPT4O.js +0 -5
  439. package/dist/context-ZV33V4DC.cjs +0 -22
  440. package/dist/executor-OZSYXDKF.cjs.map +0 -1
  441. package/dist/executor-PAH72CB5.js.map +0 -1
  442. package/dist/fs-session-store-6MY7PNI2.js +0 -10
  443. package/dist/fs-session-store-7E7UPLF2.cjs +0 -19
  444. package/dist/generate-object-5SCEH2EE.cjs +0 -20
  445. package/dist/generate-object-I7UD4NWN.js +0 -7
  446. package/dist/index-manager-KKAK7NT3.js +0 -10
  447. package/dist/index-manager-R6ZJFEZF.cjs +0 -19
  448. package/dist/inject-session-DM4SKTZO.cjs.map +0 -1
  449. package/dist/inject-session-UXNJQTZ6.js.map +0 -1
  450. package/dist/judge-call-SP3G3X2Y.cjs +0 -22
  451. package/dist/judge-call-TAEIXMYG.js +0 -5
  452. package/dist/registry-N3GTKYCI.cjs +0 -46
  453. package/dist/registry-SOXE4RY6.js +0 -9
  454. package/dist/session-transcript-6WKLYIN4.js +0 -5
  455. package/dist/session-transcript-EAKR4D2W.cjs +0 -50
  456. package/dist/stream-object-OFM66VUT.js +0 -7
  457. package/dist/stream-object-Y7YCX3BI.cjs +0 -20
package/CHANGELOG.md CHANGED
@@ -1,16 +1,253 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.39.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 5143651: New `Agent.describe(agentId)` — read-only introspection of a registered agent (theokit#123).
8
+
9
+ `Agent.list()` / `Agent.get()` enumerate agents and `agent.skills.list()` covers skills, but a
10
+ registered agent's tools and subagents were reachable only through the internal registry record. A
11
+ reflection endpoint — theokit-studio's `theokit dev` — had no way to report them, so it degraded to
12
+ `tools: []` / `workflows: []` with an `unavailable_reason`.
13
+
14
+ `describe` returns `{ agentId, runtime, model?, tools, subagents }`. Tools carry `name`,
15
+ `description` and the `inputSchema` the model is sent; subagents carry `name`, `description`, their
16
+ `model` and their tool whitelist.
17
+
18
+ It is a projection, not the options object: tool handlers and subagent prompts are stripped. A
19
+ handler is an executable that cannot cross a process boundary, and a prompt is the agent's
20
+ instructions rather than its signature — a reflection endpoint serializes whatever it is handed.
21
+
22
+ `tools` and `subagents` are always arrays, so a caller can distinguish "this agent has none" from
23
+ "the SDK did not say". An unknown agent throws `UnknownAgentError` rather than returning an empty
24
+ description, which would be indistinguishable from a real agent with nothing registered.
25
+
26
+ `AgentDescription`, `AgentToolDescription` and `AgentSubagentDescription` are exported from the
27
+ package barrel.
28
+
29
+ - ae27def: Every SDK diagnostic now goes through the interceptable channel (theokit#147).
30
+
31
+ `setDiagnosticsSink` let a TUI host keep the SDK's warnings out of its alternate screen, but the
32
+ original migration only covered `internal/`. Six sites in the package's own modules — `batch.ts`,
33
+ `event-bus.ts`, `compaction.ts` and the Workflow branch step — still wrote straight to
34
+ `process.stderr` / `console.warn`, so a host could install a sink and still have its frame corrupted
35
+ by a batch run or a failed summarizer. Those are routed through the channel, and a lint gate now
36
+ fails the build if a new direct write appears in `src/`.
37
+
38
+ The remaining allowlisted writers are seams whose destination the caller already chooses
39
+ (`opts.warn`, `opts.logger`, the Workflow logger), each listed with its reason.
40
+
41
+ `setDiagnosticsSink` is now exported from the package barrel. It previously existed only on an
42
+ internal path no consumer could import, so the channel these six fixes route into could not actually
43
+ be installed by a host — the reported blocker survived a green suite.
44
+
45
+ **Diagnostics are now silent by default.** With no sink installed the SDK writes nothing to the
46
+ terminal — a library does not own the host's screen. Installing a sink is how you see them:
47
+
48
+ ```ts
49
+ import { setDiagnosticsSink } from "@theokit/sdk";
50
+ setDiagnosticsSink((message) => myLogger.warn(message));
51
+ ```
52
+
53
+ This is a behaviour change for anyone who relied on reading SDK warnings from stderr. Restore the
54
+ old behaviour in one line: `setDiagnosticsSink((m) => process.stderr.write(m))`.
55
+
56
+ - 0bd082f: Three advertised embedding providers now actually work (theokit#159).
57
+
58
+ `azure-openai`, `cohere` and `gemini` were in the catalog and rejected on every call. The shared
59
+ runtime spoke exactly one wire — `Authorization: Bearer`, a `{ model, input }` body, a
60
+ `{ data: [{ embedding }] }` response — and none of the three speak it:
61
+
62
+ - **Azure** authenticates an API key with the `api-key` header (`Bearer` carries an Entra ID token,
63
+ not the key from `AZURE_OPENAI_API_KEY`), and the deployment is already in the URL path, so
64
+ `model` does not belong in the body.
65
+ - **Cohere**'s `/v2/embed` names the payload `texts`, requires `input_type`, and answers
66
+ `{ embeddings: { float } }`.
67
+ - **Gemini**'s OpenAI-compatible surface is at `/v1beta/openai/embeddings`, not `/v1/embeddings`.
68
+
69
+ The runtime gained three optional per-provider hooks — auth headers, request body, response reader —
70
+ whose defaults are exactly the previous behaviour, so the seven providers that were already correct
71
+ are untouched. Each divergence is asserted by a test that records the real request.
72
+
73
+ Advertising a provider that cannot work is worse than not advertising it; that is what this closes.
74
+
75
+ - 108679d: A resumed session can be re-rendered as tool cards, not prose (theokit#146).
76
+
77
+ The transcript always replayed correctly to the model, but the only projection a host could read
78
+ folded a tool call to the literal string `[tool call] NAME` — no call id, no arguments — and a
79
+ result to `[tool result] <body>`, with nothing tying the two together. A card-rendering TUI got flat
80
+ text on resume, which made cross-restart resume worth less than starting fresh.
81
+
82
+ Two additions, both additive:
83
+
84
+ - `SessionMessage` gains an optional `parts` array carrying `text`, `tool_use` (id, name, input) and
85
+ `tool_result` (toolUseId, content, isError). `text` is byte-identical to before, so every existing
86
+ reader — including the runtime's own prior-context replay — is untouched.
87
+ - New `Agent.transcript(agentId)` returns a local agent's persisted turns with both projections.
88
+ Read-only; it opens the session store and walks the transcript, appending nothing. Throws
89
+ `UnknownAgentError` for an unknown or non-local agent rather than returning an empty list, so a
90
+ typo cannot look like an empty session.
91
+
92
+ `SessionMessage` and `SessionMessagePart` are exported from the package barrel.
93
+
94
+ - 1e2a5e3: Extended-thinking sessions can be resumed (theokit#122).
95
+
96
+ Anthropic signs each `thinking` block and verifies that signature when the block is replayed on the
97
+ next turn. The SDK captured none of it, so a session that used extended thinking could be persisted
98
+ and then never resumed — the next request failed with `400 "thinking blocks cannot be modified"`.
99
+
100
+ The signature was dropped at four independent points, and fixing any one alone would have changed
101
+ nothing:
102
+
103
+ - the Anthropic adapter never requested extended thinking, so no signature was ever issued;
104
+ - it did not parse `thinking` blocks, so neither the text nor the signature left the stream;
105
+ - the agent loop emitted a thinking event and dropped it — nothing ever produced a `thinkingMessage`
106
+ step, so no thinking reached the transcript at all;
107
+ - the transcript reader discarded `thinking` blocks, so a resumed conversation lost them.
108
+
109
+ All four are closed, and the block now round-trips from the provider through persistence and back
110
+ onto the wire unchanged. Thinking and its answer text stay in one assistant message, in that order,
111
+ as Anthropic requires.
112
+
113
+ A thinking block with no signature — history recorded before this shipped, or reasoning text from an
114
+ OpenAI-compatible provider, which is never signed — is kept in the transcript but not replayed to
115
+ Anthropic. Sending it unsigned would fail the same validation and break the whole turn rather than
116
+ lose one block of context.
117
+
118
+ `SDKThinkingMessage` and the conversation `ThinkingMessage` gain an optional `signature`.
119
+
120
+ - c3f69bc: New `workflow.describe()` — a committed workflow can report its own shape (theokit#161).
121
+
122
+ Returns `{ name, steps }`, each step carrying its `id` and `kind` and recursing into `parallel`,
123
+ `branch`, `foreach` and `dowhile`. Executables a step holds — predicates, conditions, agents, prompt
124
+ templates — are omitted: they cannot cross a process boundary and say nothing about shape.
125
+
126
+ There is deliberately **no** `Workflow.list()`. A workflow is a value the caller constructs and
127
+ holds, so the caller already knows which ones exist; what it lacked was a way to describe one. A
128
+ registry would have added process-global state that nothing releases in order to re-answer a
129
+ question the host can answer itself, and coupling workflows to `AgentOptions` would tie together two
130
+ things that are independent today — a workflow runs perfectly well without an agent.
131
+
132
+ A reflection endpoint maps over its own workflows and calls this.
133
+
134
+ ### Patch Changes
135
+
136
+ - a4a9920: `@theokit/sdk-memory` now uses the SDK's embedding runtime instead of its own copy (theokit#160).
137
+
138
+ The two packages each carried a full copy of `createOpenAiCompatibleRuntime`, and the satellite's
139
+ catalog replaces the SDK's at runtime when installed — so the copy that ran was not the copy most
140
+ people read. That duplication is what produced the two-month adapter gap fixed in theokit#128, and
141
+ every fix since had to be applied to both files by hand.
142
+
143
+ There is now one implementation, imported from `@theokit/sdk/internal/memory-adapters` — a
144
+ semver-exempt sub-path in the same family as `internal/persistence` and `internal/security`, which
145
+ exist for exactly this reason.
146
+
147
+ **Behaviour change for `@theokit/sdk-memory` consumers:** embedding batches now run with bounded
148
+ parallelism instead of serially, and the embedding cache is process-wide instead of per-adapter.
149
+ Both are what the SDK already did; the satellite had silently missed both improvements.
150
+
151
+ - 50ffa6c: Removed the dead `tool_use` and `stop` variants from the internal `LlmEvent` union (theokit#144).
152
+
153
+ They declared a live, provider-level tool channel that never existed: only two providers yielded
154
+ them, the agent loop's collector never read them, and the tool calls they carried duplicated
155
+ `LlmFinish.toolCalls`. A declaration without a consumer is worse than an omission — it cost
156
+ `@theokit/agents` a workaround that held every text delta until the stream drained, which broke
157
+ live token streaming on text-only turns (issue #47).
158
+
159
+ The canonical live tool channel is `onDelta`: the `tool-call-started` / `tool-call-completed`
160
+ `InteractionUpdate`s emitted between LLM rounds, uniform across providers and correlated by
161
+ `callId`. `Run.events()` merges them with the structural messages into one ordered timeline. This
162
+ is now documented on the `LlmEvent` type itself.
163
+
164
+ Internal type only — no public API change.
165
+
166
+ - 0308f9f: `@theokit/sdk-memory` now serves every embedding provider the SDK advertises (theokit#128).
167
+
168
+ `azure-openai`, `cohere`, `jina` and `gemini` landed in the SDK core catalog in June 2026 and the
169
+ satellite never picked them up. That was not cosmetic drift: when `@theokit/sdk-memory` is
170
+ installed, its catalog _replaces_ core's in the routing path, while `Theokit.inspect.embeddingAdapters()`
171
+ kept listing all ten — so asking for one of the four got an "unknown provider" error from a provider
172
+ the SDK itself had just advertised. A cross-package test now fails the build if core ever advertises
173
+ a provider the peer cannot serve.
174
+
175
+ Also fixes the Azure OpenAI endpoint in both packages. Azure addresses the deployment in the URL
176
+ path (`/openai/deployments/{deployment}/embeddings`), and the placeholder was never substituted —
177
+ every Azure embedding request went to a URL containing the literal text `{model}` and could only 404. Providers with a static path are unaffected.
178
+
179
+ - a15d80f: `mcpLifecycle: 'session'` now actually keeps the MCP server alive between turns (theokit#155).
180
+
181
+ The option pooled the client _object_ but not the child _process_: every run's `finally` closed
182
+ every client it had been handed, so the previous turn SIGTERM'd the server and the next turn's
183
+ `initialize()` spawned a new one. Measured at 146 ms +/- 28 (n=12) of spawn + handshake per turn
184
+ for one stdio server, paid identically under `'run'` and `'session'` — the knob bought 0 ms.
185
+
186
+ Two changes, both needed:
187
+
188
+ - A run now closes only the MCP clients it owns. Under `'session'` the pool owns them, and they are
189
+ released by `dispose()` (or by the idle reaper), not by the turn that borrowed them.
190
+ - `initialize()` is a no-op while the child is live, so the per-turn handshake no longer replaces a
191
+ healthy process (which would have orphaned it and paid the spawn cost anyway). The reconnect path
192
+ is unaffected — it re-spawns directly, exactly as before.
193
+
194
+ The regression tests count child PIDs rather than client objects; counting objects is what let the
195
+ defect ship green.
196
+
197
+ - 32a82c4: Subagent credential inheritance no longer rides a property on the tool object (theokit#148).
198
+
199
+ A delegated child inherited its parent's API key through a symbol-keyed slot installed on the
200
+ subagent tool. That contract assumed the object would reach the dispatcher with an extra property
201
+ intact — and it broke twice: once because the bundler inlined two copies of the module that
202
+ disagreed on the key (#142/#143), and once because any layer rebuilding the tool from its known
203
+ fields simply dropped it. `@theokit/agents` hit the second and had to add an explicit symbol-copy
204
+ loop to compensate; the SDK's own tool assembly performs the same rebuild.
205
+
206
+ Credentials now travel on the run's async scope, so they reach the handler no matter what the tool
207
+ object looks like by the time it is dispatched. Consumers that normalize, wrap, or re-create SDK
208
+ tools no longer need to preserve hidden properties — a delegated child gets the parent's key either
209
+ way. The band-aid symbol-copy in `@theokit/agents` becomes unnecessary once the SDK
210
+ carrying this change is the resolved version. Against an OLDER SDK the copy loop is still required:
211
+ the pre-fix runtime reads the credential sink off the tool object, so a band-aid-free
212
+ `@theokit/agents` resolving an SDK below this release reproduces the very credential loss this issue
213
+ reports. `@theokit/agents` declares a caret range on `@theokit/sdk`, so that pairing is a normal
214
+ install rather than a hypothetical — raise the dependency floor in the same release that removes
215
+ the loop.
216
+
217
+ Also fixes a latent defect the old design could not avoid: credentials were stored per tool
218
+ instance, so one subagent tool shared by two concurrently running agents got last-writer-wins. Each
219
+ run now reads its own.
220
+
221
+ - f760c57: Fixes four defects in the extended-thinking support shipped moments earlier (theokit#122).
222
+
223
+ A `/review` of that change found it created, on the most common thinking shape, the exact failure it
224
+ was meant to remove. A round that reasons and then calls a tool **without preamble text** never
225
+ consumed its thinking block: the block survived onto the next round and was persisted against the
226
+ wrong text, carrying a signature that no longer matched its body. And the replayed assistant turn
227
+ never carried the block at all, so the round after a thinking + tool_use turn reached the provider
228
+ missing it.
229
+
230
+ The block is now a value on the round's own output rather than state on the loop context, which
231
+ makes that class of leak unrepresentable, and it is recorded on whichever path closes the round —
232
+ assistant text or tool call. The replayed assistant message leads with it, as the provider requires.
233
+
234
+ Two smaller corrections in the same area: redacting the thinking text now drops the signature
235
+ instead of persisting a pair that cannot verify (the block survives as display-only history, which
236
+ loses one block of context rather than the whole turn), and the provider's own reported block is now
237
+ what the loop consumes — previously it was produced and read by nobody, the same dead-channel shape
238
+ this release deletes elsewhere.
239
+
3
240
  ## 4.37.2
4
241
 
5
242
  ### Patch Changes
6
243
 
7
- - Servidores MCP que respondem em fluxo de eventos voltam a entregar suas ferramentas: a resposta passa a ser lida no formato que o próprio cliente pediu, em vez de falhar ao interpretá-la.
244
+ - MCP servers that reply with an event stream deliver their tools again: the response is now read in the format the client itself asked for, instead of failing to interpret it.
8
245
 
9
246
  ## 4.37.1
10
247
 
11
248
  ### Patch Changes
12
249
 
13
- - Servidores MCP com transporte HTTP **stateful** voltam a servir suas ferramentas: o cliente passa a guardar a sessão que o servidor emite no handshake e a reenviá-la nas chamadas seguintes, e passa a declarar os dois tipos de mídia que a especificação pede.
250
+ - MCP servers on the **stateful** HTTP transport serve their tools again: the client now stores the session the server issues at handshake and replays it on subsequent calls, and declares both media types the specification asks for.
14
251
 
15
252
  ## 4.37.0
16
253
 
@@ -58,139 +295,139 @@ cwd })` previously compiled and was silently ignored — it hydrated the process
58
295
 
59
296
  ### Minor Changes
60
297
 
61
- - Publica uma consulta que responde "esta sessão tem escritor?" sem tomar a trava.
298
+ - Publishes a query answering "does this session have a writer?" without taking the lock.
62
299
 
63
- Perguntar tomando cria a disputa que se queria detectar: dois processos consultando uma sessão **livre** ao mesmo tempo faziam um deles perder, e quem consome derivava uma sessão nova sem motivo. A consulta é uma foto, não uma garantiaquem precisa da garantia continua tomando a trava; quem precisa decidir um identificador antes de abrir qualquer coisa usa a consulta e trata a corrida onde ela aparece.
300
+ Asking by taking creates the very contention it meant to detect: two processes querying a **free** session at the same time made one of them lose, and the consumer derived a new session for no reason. The query is a snapshot, not a guaranteecallers needing the guarantee keep taking the lock; callers needing to decide an identifier before opening anything use the query and handle the race where it shows up.
64
301
 
65
302
  ## 4.34.2
66
303
 
67
304
  ### Patch Changes
68
305
 
69
- - Dois refinamentos na trava de sessão.
306
+ - Two refinements to the session lock.
70
307
 
71
- - **Uma abertura que falha solta apenas a trava do próprio agente.** Um armazenamento injetado pelo consumidor pode servir vários agentes, e a versão anterior liberava todas as travas deleum agente que falha ao abrir derrubava a proteção de outro que seguia escrevendo.
72
- - **Um caminho de trava que seja um diretório volta a ser recuperável.** Nenhum processo desta biblioteca cria um, e tratá-lo como "dono desconhecido" bloqueava a sessão para sempreo oposto do que a trava existe para garantir.
308
+ - **An open that fails releases only its own agent's lock.** A store injected by the consumer may serve several agents, and the previous version released all of its locksan agent failing to open tore down the protection of another that was still writing.
309
+ - **A lock path that is a directory becomes recoverable again.** No process in this library creates one, and treating it as an "unknown owner" locked the session out foreverthe opposite of what the lock exists to guarantee.
73
310
 
74
311
  ## 4.34.1
75
312
 
76
313
  ### Patch Changes
77
314
 
78
- - Corrige três formas de a trava de sessão ficar presa ou ser ignorada.
315
+ - Fixes three ways the session lock could get stuck or be ignored.
79
316
 
80
- - **Uma abertura de sessão que falha depois de tomar a trava agora a solta.** O dono ficava sendo o próprio processo vivo, mesma máquinae a trava nunca mais era considerada obsoleta: a sessão ficava bloqueada pelo tempo de vida do processo, sem crash e sem caminho de recuperação. É a mesma situação que a trava existe para eliminar, entrando por outra porta.
81
- - **Uma trava que existe mas não pode ser lida deixa de ser tratada como inexistente.** Não saber quem é o dono não é o mesmo que não haver dono: a versão anterior seguia em frente sem proteção, com outro escritor ativo na mesma sessão. Em diretório compartilhado isso era o caminho comum, porque a permissão restrita torna a trava alheia ilegível por desenho.
82
- - **A permissão restrita passa a valer também para uma trava herdada de versão anterior**, que antes mantinha a permissão antiga depois de ser reclamada.
317
+ - **A session open that fails after taking the lock now releases it.** The owner ended up being this very processalive, same machineand the lock was never considered stale again: the session stayed blocked for the process's lifetime, with no crash and no recovery path. It is the same situation the lock exists to eliminate, entering through another door.
318
+ - **A lock that exists but cannot be read stops being treated as absent.** Not knowing who the owner is differs from there being no owner: the previous version proceeded without protection, with another writer active on the same session. In a shared directory this was the common path, because the restricted permission makes another user's lock unreadable by design.
319
+ - **The restricted permission now also applies to a lock inherited from an earlier version**, which previously kept the old permission after being reclaimed.
83
320
 
84
321
  ## 4.34.0
85
322
 
86
323
  ### Minor Changes
87
324
 
88
- - O lease de escritor passa a ser tomado na abertura da sessão, não na primeira gravação.
325
+ - The writer lease is now taken when the session opens, not on the first write.
89
326
 
90
- **Corrige uma perda silenciosa de turno.** A gravação de sessão é best-effort por contratouma rejeição é registrada em stderr, nunca lançada a quem chamou. Tomar o lease ali fazia o erro de "sessão ocupada" ser engolido: em vez de dois escritores intercalarem linhas, o perdedor **perdia o turno inteiro**, sem nada em disco e sem como reagir. Na abertura, o erro chega a quem pode decidire a decisão que ele prescreve é criar uma sessão derivada.
327
+ **Fixes a silent turn loss.** Session writing is best-effort by contracta rejection is logged to stderr, never thrown to the caller. Taking the lease there made the "session busy" error get swallowed: instead of two writers interleaving lines, the loser **lost the whole turn**, with nothing on disk and no way to react. At open time the error reaches someone who can decide and the decision it prescribes is to create a derived session.
91
328
 
92
- Uma falha de I/O que **não** seja disputa (diretório sem permissão, disco cheio) não derruba mais a abertura do agente: não segundo escritor a evitar, e a gravação era best-effort.
329
+ An I/O failure that is **not** contention (an unwritable directory, a full disk) no longer fails the agent's open: there is no second writer to avoid, and the write was already best-effort.
93
330
 
94
331
  ### Corrigido
95
332
 
96
- - **As caches de sessão em memória voltam a ser apagadas de fato.** Três dos quatro mapas são endereçados por uma chave composta e estavam sendo removidos por outra: na prática, nunca eram apagados. E o descarte por limite deixava a marca de hidratação para trás, fazendo uma sessão descartada voltar **vazia** em vez de recarregar do disco.
97
- - **O arquivo de trava nasce restrito ao dono.** Com a permissão anterior, outro usuário do mesmo grupo podia sobrescrevê-lo e forjar a posse da sessãoa partir daí o dono legítimo é quem passava a ser recusado.
98
- - **O limite máximo de janela de contexto declarada subiu para 10M.** O valor anterior recusava a janela real de um modelo publicadoque chega exatamente pelo provider sem catálogo, isto é, o caso que o limite existe para cobrir. Perder 80% da janela em silêncio é pior que o excesso que o limite evita.
333
+ - **The in-memory session caches are actually erased again.** Three of the four maps are addressed by a composite key and were being removed by a different one: in practice, they were never erased. And eviction by ceiling left the hydration marker behind, making an evicted session come back **empty** instead of reloading from disk.
334
+ - **The lock file is born restricted to its owner.** With the previous permission, another user in the same group could overwrite it and forge ownership of the session from then on it was the legitimate owner who got refused.
335
+ - **The maximum declared context window rose to 10M.** The previous value refused the real window of a published model which arrives precisely via the catalog-less provider, that is, the case the limit exists to cover. Silently losing 80% of the window is worse than the excess the limit prevents.
99
336
 
100
337
  ## 4.33.1
101
338
 
102
339
  ### Patch Changes
103
340
 
104
- - Corrige um lease de sessão que podia ser tomado de um processo vivo.
341
+ - Fixes a session lease that could be taken from a live process.
105
342
 
106
- O registro de dono é gravado na aquisição e não é renovado a cada escrita, e a versão anterior considerava reclamável qualquer lock mais velho que a janela de heartbeat inclusive no mesmo host. Na prática isso significava que **toda** sessão que durasse mais que a janela ficava disponível para um segundo escritor, que é exatamente o que o lease existe para impedir.
343
+ The owner record is written at acquisition and is not renewed on each write, and the previous version considered any lock older than the heartbeat window reclaimableincluding on the same host. In practice that meant **every** session lasting longer than the window became available to a second writer, which is exactly what the lease exists to prevent.
107
344
 
108
- No mesmo host a pergunta "o dono ainda existe?" tem resposta exata, e a idade não acrescenta nada a ela. A janela continua valendo entre máquinas diferentes, onde um número de processo não significa nada.
345
+ On the same host the question "does the owner still exist?" has an exact answer, and age adds nothing to it. The window still applies between different machines, where a process number means nothing.
109
346
 
110
347
  ## 4.33.0
111
348
 
112
349
  ### Minor Changes
113
350
 
114
- - M95 — o escritor único passa a existir de fato, e as caches de sessão ganham dono.
351
+ - M95 — the single writer actually starts existing, and the session caches gain an owner.
115
352
 
116
- - **A garantia de escritor único está ligada.** Ela existia como função desde a versão que a introduziu e não tinha **nenhum** chamador: o transcript nunca foi protegido. Agora o store a adquire na primeira gravação e a solta ao encerrar.
117
- - **Um processo que morreu deixa de trancar a sessão para sempre.** O lock não registrava dono, então uma interface encerrada abruptamente bloqueava o usuário fora da própria sessão sem caminho de recuperação. O lock passa a gravar `{pid, hostname, mtime}`, e um dono mortoou um lock mais velho que a janela de heartbeat cede o lugar. Entre máquinas diferentes a janela vale, porque um número de processo não significa nada fora do host onde nasceu.
118
- - **As caches de sessão em memória param de crescer sem limite.** Duas das quatro nunca eram apagadas por sessão; agora todas caem no encerramento do agente, e a conversa em cache respeita um teto com descarte da menos recente.
353
+ - **The single-writer guarantee is wired.** It had existed as a function since the version that introduced it and had **no** caller at all: the transcript was never protected. The store now acquires it on the first write and releases it on shutdown.
354
+ - **A dead process no longer locks the session forever.** The lock recorded no owner, so an abruptly terminated interface locked the user out of their own session with no recovery path. The lock now writes `{pid, hostname, mtime}`, and a dead owneror a lock older than the heartbeat windowyields its place. Between different machines only the window counts, because a process number means nothing outside the host where it was born.
355
+ - **The in-memory session caches stop growing without bound.** Two of the four were never erased per session; now all of them drop when the agent shuts down, and the cached conversation respects a ceiling with least-recently-used eviction.
119
356
 
120
357
  ### Corrigido
121
358
 
122
- - **Uma janela de contexto declarada absurdamente alta volta a ser limitada mesmo sem entrada de catálogo.** O limite existia quando havia catálogoe a razão de ser da declaração é justamente o modelo que não tem. Um zero a mais na configuração fazia o agente nunca compactar até o provider recusar o turno.
123
- - **A resolução de provider a partir do id de modelo passa a usar o parser canônico**, então aliases, maiúsculas e espaços resolvem como em todo o resto do SDK. A versão anterior refazia a separação à mão e não reconhecia sete formas válidas.
359
+ - **An absurdly high declared context window is bounded again even without a catalog entry.** The limit only existed when a catalog was presentand the whole reason the declaration exists is the model that has none. One extra zero in the configuration made the agent never compact until the provider refused the turn.
360
+ - **Provider resolution from a model id now uses the canonical parser**, so aliases, capitalization and spaces resolve as everywhere else in the SDK. The previous version redid the split by hand and did not recognize seven valid forms.
124
361
 
125
362
  ## 4.32.0
126
363
 
127
364
  ### Minor Changes
128
365
 
129
- - M94 — publica quatro resolvedores que o SDK conhecia internamente.
366
+ - M94 — publishes four resolvers the SDK already knew internally.
130
367
 
131
- - **`transcriptRoot()` é exportado e honra `THEOKIT_HOME`.** Antes, a raiz do transcript ignorava a variável enquanto os stores irmãos a respeitavam: quem a definia tinha o estado partido em dois em silêncio, e as sessões antigas sumiam da listagem sem erro. O fallback continua sendo `~/.theokit` — deliberadamente **não** o resolvedor cwd-ancorado de `paths.ts`, cuja troca moveria o transcript de quem **não** define a variável.
132
- - **`ModelSelection.contextWindow` atravessa até o orçamento de compactação.** O resolvedor aceitava um `override` desde a versão anterior e nenhum caminho de produção o passava: um modelo de 400k sem entrada de catálogo era orçado contra o piso de 128k e compactava cerca de três vezes mais do que precisava. Um valor acima do que o catálogo conhece continua sendo limitado.
133
- - **`SessionRecord.message` deixa de ser `Record<string, unknown>`.** O novo `TranscriptMessage` descreve a forma que o escritor sempre produziu. **Não** se chama `SessionMessage`: esse nome existe com forma incompatível, e reaproveitá-lo repetiria uma quebra silenciosa anterior. A leitura do disco segue tolerante o que muda é o tipo.
134
- - **`Provider.forModel(modelId)`** um dono único à gramática `provider/modelo`. Um id sem barra devolve `undefined` em vez de casar parcialmente, para que quem chama possa distinguir "modelo não-roteável" de "caminho default".
368
+ - **`transcriptRoot()` is exported and honors `THEOKIT_HOME`.** Before, the transcript root ignored the variable while its sibling stores respected it: whoever set it had their state silently split in two, and older sessions vanished from the listing with no error. The fallback is still `~/.theokit` — deliberately **not** the cwd-anchored resolver in `paths.ts`, whose adoption would move the transcript of everyone who does **not** set the variable.
369
+ - **`ModelSelection.contextWindow` reaches the compaction budget.** The resolver had accepted an `override` since the previous version and no production path passed it: a 400k model with no catalog entry was budgeted against the 128k floor and compacted about three times more than it needed to. A value above what the catalog knows is still clamped.
370
+ - **`SessionRecord.message` stops being `Record<string, unknown>`.** The new `TranscriptMessage` describes the shape the writer has always produced. It is **not** called `SessionMessage`: that name already exists with an incompatible shape, and reusing it would repeat an earlier silent break. Reading from disk stays tolerantwhat changes is the type.
371
+ - **`Provider.forModel(modelId)`** gives the `provider/model` grammar a single owner. An id without a slash returns `undefined` instead of matching partially, so the caller can tell "non-routable model" from "default path".
135
372
 
136
- Nota de rótulo: `4.31.1` continha, por engano, parte destas adiçõesfoi publicado como patch quando o correto era minor. Nada quebra (adições são compatíveis), e esta versão declara a superfície corretamente.
373
+ Labelling note: `4.31.1` already contained some of these additions by mistake it was published as a patch when a minor was correct. Nothing breaks (additions are compatible), and this version declares the surface correctly.
137
374
 
138
375
  ## 4.31.1
139
376
 
140
377
  ### Patch Changes
141
378
 
142
- - M93 — oito correções da revisão adversarial.
379
+ - M93 — eight fixes from adversarial review.
143
380
 
144
- - **O retry deixa de reexecutar um stream já parcialmente consumido.** Uma falha depois do primeiro evento reexecutava o turno inteiro, duplicando texto e blocos `tool_use` — exatamente no cenário que motivou o retry (429 depois de várias tool calls).
145
- - **O transcript volta a nascer `0600`.** A troca para append incremental perdeu o modo explícito e, sob `umask 022`, o arquivoque carrega conteúdo em trânsito nascia legível por outros.
146
- - **Um append sobre arquivo truncado por crash não engole mais o registro novo.**
147
- - **Erro transitório passa a ser decidido pelo status estruturado, não pelo texto da mensagem.** A heurística anterior classificava `ECONNREFUSED …:443` como não-transitório porque a porta casava o padrão de "4xx": o retry ficava desligado justamente para falha de rede.
148
- - **Falha de socket passa a ser tipada nos transportes Anthropic e OpenAI.** Sem isso, o erro cru escapava e nenhuma política de retry o reconhecia.
149
- - **`CredentialPoolExhaustedError` e circuito aberto deixam de ser reexecutados.** O pool gastou o próprio orçamento; reexecutar por cima triplicava a espera e desfazia o fail-fast do circuit breaker.
150
- - Cancelamento (`AbortError`) nunca é confundido com falha de rede.
381
+ - **Retry stops re-running an already partially consumed stream.** A failure after the first event retried the whole turn, duplicating text and `tool_use` blocks precisely in the scenario that motivated the retry (a 429 after several tool calls).
382
+ - **The transcript is born `0600` again.** The switch to incremental append lost the explicit mode and, under `umask 022`, the filewhich carries in-flight contentwas born readable by others.
383
+ - **An append over a crash-truncated file no longer swallows the new record.**
384
+ - **Transient errors are now decided by structured status, not by message text.** The previous heuristic classified `ECONNREFUSED ...:443` as non-transient because the port matched the "4xx" pattern: retry was switched off precisely for network failures.
385
+ - **Socket failures are now typed in the Anthropic and OpenAI transports.** Without that, the raw error escaped and no retry policy recognized it.
386
+ - **`CredentialPoolExhaustedError` and an open circuit stop being retried.** The pool already spent its own budget; retrying on top tripled the wait and undid the circuit breaker's fail-fast.
387
+ - Cancellation (`AbortError`) is never confused with a network failure.
151
388
 
152
389
  ## 4.31.0
153
390
 
154
391
  ### Minor Changes
155
392
 
156
- - d8412b6: **Um erro transitório de provider deixa de destruir o turno inteiro.**
393
+ - d8412b6: **A transient provider error stops destroying the whole turn.**
157
394
 
158
- Três defeitos que, combinados, tornavam a perda total:
395
+ Three defects that, combined, made the loss total:
159
396
 
160
- - **O caminho de chave única não tinha retry.** `buildPoolOrSingle` dava `PoolAwareLlmClient` — circuit
161
- breaker, backoff de jitter total, `Retry-After`, rotaçãocom **≥ 2** chaves, e o transporte **cru**
162
- com uma. Um consumidor que resolve exatamente uma credencial (o caso comum) caía sempre no braço sem
163
- resiliência. A assimetria não tem justificativa de domínio: **um pool de 1 chave é um pool de tamanho
164
- 1**. `RetryingLlmClient` é composição — `computeBackoffMs` e `sleepWithAbort` eram módulos
165
- independentese aplica-se aos **três** braços (o do pool ambiente também estava de fora).
397
+ - **The single-key path had no retry.** `buildPoolOrSingle` gave a `PoolAwareLlmClient` — circuit
398
+ breaker, full-jitter backoff, `Retry-After`, rotationwith **>= 2** keys, and the **raw** transport
399
+ with one. A consumer resolving exactly one credential (the common case) always landed on the arm without
400
+ resilience. The asymmetry has no domain justification: **a pool of 1 key is a pool of size
401
+ 1**. `RetryingLlmClient` is composition — `computeBackoffMs` and `sleepWithAbort` were already
402
+ independent modules and it applies to all **three** arms (the ambient pool's was also left out).
166
403
 
167
- - **O caminho de erro não persistia nada.** O `catch` de `run.wait()` chamava `flushSessionWrites()` e
168
- retornava; `persistTurnToTranscript` é chamado depois, e é o único chamador do repositório. O
169
- flush drenava um conjunto **vazio**. Agora persiste o **parcial** — user + tool calls concluídas
170
- sem reconstruir o que não aconteceu.
404
+ - **The error path persisted nothing.** `run.wait()`'s `catch` called `flushSessionWrites()` and
405
+ returned; `persistTurnToTranscript` is only called later, and it is the repository's only caller. The
406
+ flush drained an **empty** set. It now persists the **partial** — user + completed tool calls —
407
+ without reconstructing what did not happen.
171
408
 
172
- - **`appendRecords` reescrevia o arquivo inteiro por turno.** O(n) de I/O **e** de parse a cada turno,
173
- O(n²) por sessão. Correto porque o formato ** é append-only** (o DAG de `parentUuid` não depende da
174
- ordem de linha), e `appendJsonl` ** existia** no pacote com um único chamador. O `withFileLock`
175
- permaneceé ele que serializa appends concorrentes.
409
+ - **`appendRecords` rewrote the whole file every turn.** O(n) of I/O **and** of parsing on every turn,
410
+ O(n^2) per session. Correct because the format **is already append-only** (the `parentUuid` DAG does not depend on
411
+ line order), and `appendJsonl` **already existed** in the package with a single caller. `withFileLock`
412
+ staysit is what serializes concurrent appends.
176
413
 
177
- erro **transitório** reexecuta: 402 (billing) não é, porque cota não se resolve em milissegundos, e
178
- 401 falha na primeira. Teto de 3 tentativas, ciente de `AbortSignal`.
414
+ Only a **transient** error is retried: 402 (billing) is not, because a quota does not resolve in milliseconds, and
415
+ a 401 fails on the first. Ceiling of 3 attempts, `AbortSignal`-aware.
179
416
 
180
417
  ### Patch Changes
181
418
 
182
419
  - f76ed61: Corrige o docstring de `Agent.getOrCreate`, que afirmava o oposto do comportamento real.
183
420
 
184
421
  Ele dizia: _"Disposed agents are NOT auto-deleted from the registry. To force a fresh agent, call
185
- `Agent.delete(agentId)` first."_ Medido, é falso — `dispose()` chama `liveAgentRegistry.forget(id)`,
186
- então o próximo `getOrCreate(id)` constrói um handle novo, sem `Agent.delete`.
422
+ `Agent.delete(agentId)` first."_ Measured, that is false — `dispose()` calls `liveAgentRegistry.forget(id)`,
423
+ so the next `getOrCreate(id)` builds a fresh handle, with no `Agent.delete`.
187
424
 
188
- A afirmação era sobre o registro **persistente** e foi lida como sendo sobre o **cache vivo**; um
189
- consumidor construiu em cima da metade errada. Travado por `tests/m91-getorcreate-apos-dispose.test.ts`.
425
+ The claim was about the **persistent** registry and was read as being about the **live cache**; a
426
+ consumer built on the wrong half. Locked by `tests/m91-getorcreate-after-dispose.test.ts`.
190
427
 
191
- O bullet novo também registra o que continua verdadeiro: `close()` marca o handle descartado **sem**
192
- evictar a entrada do cache. É interno e sem chamador hoje; se voltar a ser alcançável, o bullet deixa
193
- de valer para aquele caminho e está escrito para que a próxima pessoa não precise redescobrir.
428
+ The new bullet also records what remains true: `close()` marks the handle disposed **without**
429
+ evicting the cache entry. It is internal and has no caller today; if it becomes reachable again, the bullet stops
430
+ holding for that pathand it is written down so the next person need not rediscover it.
194
431
 
195
432
  ## 4.17.1
196
433
 
@@ -1507,9 +1744,9 @@ cwd })` previously compiled and was silently ignored — it hydrated the process
1507
1744
 
1508
1745
  - **Forbidden-path blocklist expansion + case-insensitive matching (T5.6 of plan `sdk-superiority-2026-06-07`, DR6 finding #6)**: pre-T5.6 `isForbiddenPath` blocked only `.env*`, `.git/`, `node_modules/`, `.theo/`, and 4 lockfile basenames — and it compared case-sensitively. A coding agent recursing through a developer laptop could happily read `.ssh/id_rsa`, `.aws/credentials`, `.docker/config.json`, `.kube/config`, `.npmrc`, `.netrc`, `.pgpass`, `authorized_keys`, `known_hosts`, OR any `*.pem` / `*.key` file. On macOS/Windows case-insensitive filesystems, `.ENV` and `.SSH/` slipped through entirely because the path string was compared verbatim against lowercase constants. T5.6 (a) lowercases the normalized path BEFORE matching, defeating case-only bypass; (b) adds 3 new pattern sets: `SENSITIVE_FIRST_SEGMENTS` (.ssh / .aws / .docker / .kube / .npmrc / .netrc / .pgpass at top level), `SENSITIVE_BASENAMES` (id_rsa / id_ed25519 / id_ecdsa / id_dsa / authorized_keys / known_hosts / .npmrc / .netrc / .pgpass at any depth), and `SENSITIVE_SUFFIXES` (.pem / .key / .p12 / .pfx at any depth). Implementation matches the `.env.example` allowlist contract — `isForbiddenPath` returns false for safe templates. 28 new tests at `tests/internal/security/path-guard-forbidden-expansion.test.ts`; 102/102 path-guard sink tests GREEN across 6 files. Closes DR6 finding #6.
1509
1746
 
1510
- - **NUL byte + C0/DEL control-char rejection across path-guard primitives (T5.5 of plan `sdk-superiority-2026-06-07`, DR6 finding #5)**: pre-T5.5 `safePathJoin`, `assertNoSymlinkEscape`, and `sanitizeIdentifier` did NOT explicitly reject NUL (`\x00`) or C0/DEL control characters (`\x01-\x1F`, `\x7F`) in path-shaped or identifier-shaped inputs. NUL bytes in path strings have a long history of security bugs: legacy N-API callers historically truncated paths silently at the NUL boundary, letting `foo.txt\x00.env` be opened as `foo.txt` while the upstream caller saw the full string and approved it. C0 control chars are universally invalid in POSIX paths and identifiers. `validateArtifactPath` (T1.4 — line 269) already rejected NUL, so T5.5 propagates the same defense to the sibling primitives so a caller can never bypass NUL/control checks by choosing a different entrypoint. New internal helper `rejectNulAndControlChars(input, role)` centralizes the check; wired into `safePathJoin` (for `base` + each `part`), `assertNoSymlinkEscape` (for `path` + `base`), and `sanitizeIdentifier`. The latter previously threw a generic "invalid characters" message via the alphanumeric-only `IDENTIFIER_PATTERN`; T5.5 routes NUL through the same helper so operators see a precise `<nul-byte>` / `<control-char-0x..>` diagnostic instead — making prompt-injection traces legible per Inquebrável Rule 3. 11 new tests at `tests/internal/security/path-guard-nul-rejection.test.ts` + 1 pre-existing assertion at `tests/internal/security/path-guard.test.ts:249` updated to match the new specific NUL message. 68/68 path-guard sink tests GREEN across 4 files (path-guard unit / property / public-api / agent-session-store).
1747
+ - **NUL byte + C0/DEL control-char rejection across path-guard primitives (T5.5 of plan `sdk-superiority-2026-06-07`, DR6 finding #5)**: pre-T5.5 `safePathJoin`, `assertNoSymlinkEscape`, and `sanitizeIdentifier` did NOT explicitly reject NUL (`\x00`) or C0/DEL control characters (`\x01-\x1F`, `\x7F`) in path-shaped or identifier-shaped inputs. NUL bytes in path strings have a long history of security bugs: legacy N-API callers historically truncated paths silently at the NUL boundary, letting `foo.txt\x00.env` be opened as `foo.txt` while the upstream caller saw the full string and approved it. C0 control chars are universally invalid in POSIX paths and identifiers. `validateArtifactPath` (T1.4 — line 269) already rejected NUL, so T5.5 propagates the same defense to the sibling primitives so a caller can never bypass NUL/control checks by choosing a different entrypoint. New internal helper `rejectNulAndControlChars(input, role)` centralizes the check; wired into `safePathJoin` (for `base` + each `part`), `assertNoSymlinkEscape` (for `path` + `base`), and `sanitizeIdentifier`. The latter previously threw a generic "invalid characters" message via the alphanumeric-only `IDENTIFIER_PATTERN`; T5.5 routes NUL through the same helper so operators see a precise `<nul-byte>` / `<control-char-0x..>` diagnostic instead — making prompt-injection traces legible per Unbreakable Rule 3. 11 new tests at `tests/internal/security/path-guard-nul-rejection.test.ts` + 1 pre-existing assertion at `tests/internal/security/path-guard.test.ts:249` updated to match the new specific NUL message. 68/68 path-guard sink tests GREEN across 4 files (path-guard unit / property / public-api / agent-session-store).
1511
1748
 
1512
- - **HKDF-SHA256 key derivation for OAuth tx-cookie AES-256-GCM key (T5.1 of plan `sdk-superiority-2026-06-07`, CRITICAL — DR6 finding #1)**: pre-T5.1 `server/auth/oauth-transaction-store.ts:deriveKey` zero-padded secret bytes to 32 if shorter and truncated if longer. This is NOT a key derivation function. Two near-identical secrets (e.g., `"a".repeat(31)` vs `"b".repeat(31)`) produced AES keys differing in only one byte across 32 — an attacker who recovered one cookie could brute-force adjacent deployments cheaply. T5.1 replaces the zero-padding with HKDF-SHA256 (RFC 5869) using `info="theokit:oauth-tx-v1"` and a salt sourced from `THEOKIT_OAUTH_TX_SALT` env var (defaults to RFC 5869 zero-string; operators MUST set per-app salt in production to eliminate cross-deployment collision risk). Distinct secrets now produce avalanche-distinct keys (Hamming distance > 160 bits empirically). **Breaking validation**: `encodeTransaction` (and via the SDK's `defineAuth` chain, any `startSignIn`/`finishSignIn` flow) now throws the new typed `AuthSecretTooShortError` when the configured secret has fewer than 32 bytes of UTF-8 encoded entropy. Pre-T5.1 secrets shorter than 32 bytes were silently zero-padded and produced insecure keys; rejecting them surfaces the misconfiguration honestly per Inquebrável Rule 3. Generate a fresh value with `openssl rand -base64 33`. New test seam `__TESTING__deriveKey` exposed for unit-test avalanche assertions; NOT in the public barrel. 7 new tests at `tests/server-auth-hkdf-derive-key.test.ts` + 1 fixture update at `tests/server-auth.test.ts` (`secret` widened 31 → 32 bytes). 23/23 server-auth tests GREEN.
1749
+ - **HKDF-SHA256 key derivation for OAuth tx-cookie AES-256-GCM key (T5.1 of plan `sdk-superiority-2026-06-07`, CRITICAL — DR6 finding #1)**: pre-T5.1 `server/auth/oauth-transaction-store.ts:deriveKey` zero-padded secret bytes to 32 if shorter and truncated if longer. This is NOT a key derivation function. Two near-identical secrets (e.g., `"a".repeat(31)` vs `"b".repeat(31)`) produced AES keys differing in only one byte across 32 — an attacker who recovered one cookie could brute-force adjacent deployments cheaply. T5.1 replaces the zero-padding with HKDF-SHA256 (RFC 5869) using `info="theokit:oauth-tx-v1"` and a salt sourced from `THEOKIT_OAUTH_TX_SALT` env var (defaults to RFC 5869 zero-string; operators MUST set per-app salt in production to eliminate cross-deployment collision risk). Distinct secrets now produce avalanche-distinct keys (Hamming distance > 160 bits empirically). **Breaking validation**: `encodeTransaction` (and via the SDK's `defineAuth` chain, any `startSignIn`/`finishSignIn` flow) now throws the new typed `AuthSecretTooShortError` when the configured secret has fewer than 32 bytes of UTF-8 encoded entropy. Pre-T5.1 secrets shorter than 32 bytes were silently zero-padded and produced insecure keys; rejecting them surfaces the misconfiguration honestly per Unbreakable Rule 3. Generate a fresh value with `openssl rand -base64 33`. New test seam `__TESTING__deriveKey` exposed for unit-test avalanche assertions; NOT in the public barrel. 7 new tests at `tests/server-auth-hkdf-derive-key.test.ts` + 1 fixture update at `tests/server-auth.test.ts` (`secret` widened 31 → 32 bytes). 23/23 server-auth tests GREEN.
1513
1750
 
1514
1751
  ### Added
1515
1752
 
@@ -1534,7 +1771,7 @@ cwd })` previously compiled and was silently ignored — it hydrated the process
1534
1771
  - Self-cycle on `types/agent.ts` (audit #3) closed by replacing the inline `import("./agent.js").SDKAgent` in `AgentOptions.handoffs?` with a direct forward-reference to the locally-defined `SDKAgent` interface.
1535
1772
  - madge cycle count: **8 → 3** in one slice. Closed: cycles #3/#5/#6/#7/#10. Remaining: #1+#2 D428-acknowledged (rollup-dts subscribe-at-sub-path); #4 documented as deviation requiring HIGH-impact SDKAgent-interface extraction (out of T4.1 scope).
1536
1773
  - Zero public type surface change. Public-type-surface smoke test in `tests/architecture/type-cycles-closed.test.ts` verifies barrels still resolve.
1537
- - **Architecture-test integrity fix (T4.1 follow-up)**: `tests/architecture/cycle-{8,9,11-12-13}-closed.test.ts` were passing **vacuously** because `repoRoot = resolve(__dirname, "../../../../..")` (5 ups) landed in the meta-repo `theokit-tools` which has no pnpm workspace — `pnpm exec madge` errored out and the cycle-line filter returned `[]`. Corrected to 4 ups (theokit-sdk workspace root). The underlying cycle closures from T1.1/T2.1/T3.1 are real (12/12 architecture tests now PASS against actual `madge --circular` output post-fix); the prior test integrity bug is surfaced honestly here per Inquebrável Rule 3 rather than buried.
1774
+ - **Architecture-test integrity fix (T4.1 follow-up)**: `tests/architecture/cycle-{8,9,11-12-13}-closed.test.ts` were passing **vacuously** because `repoRoot = resolve(__dirname, "../../../../..")` (5 ups) landed in the meta-repo `theokit-tools` which has no pnpm workspace — `pnpm exec madge` errored out and the cycle-line filter returned `[]`. Corrected to 4 ups (theokit-sdk workspace root). The underlying cycle closures from T1.1/T2.1/T3.1 are real (12/12 architecture tests now PASS against actual `madge --circular` output post-fix); the prior test integrity bug is surfaced honestly here per Unbreakable Rule 3 rather than buried.
1538
1775
  - **CRITICAL runtime↔persistence cycle #9 closed**: extracted `internal/runtime/session-types.ts` (leaf types file ~15 LOC) holding `SessionMessage`. `agent-session-store.ts` now imports the type from this leaf; `agent-session.ts` re-exports it for back-compat with downstream importers. Closes the audit's only CRITICAL cycle (Phase 5 cartographer cycle #9 — `agent-session.ts → conversation-storage-fs.ts → agent-session-store.ts → agent-session.ts`, runtime↔persistence layer-crossing). madge cycle count: 9 → 8. Architecture test asserts via spawnSync. **Plan-vs-reality deviation:** ADR D432 prescribed a full port-and-adapter refactor; empirical inspection found the back-edge was a single types-only import, so type-leaf extraction is the smallest break that actually closes the cycle. Documented in `session-types.ts` JSDoc.
1539
1776
  - **Memory cluster cycles #11 + #12 + #13 closed**: extracted `internal/memory/index-manager-contract.ts` (leaf types file holding `MemorySearchHit`, `IndexStatus`, `SearchOptions`, `MemoryBackend`, `OpenIndexOptions`). All 4 cluster members (`index-manager.ts`, `index-manager-dispatch.ts`, `lance-memory-adapter.ts`, `memory-index.ts`) now import these types from the contract; only the orchestrator imports runtime functions from dispatch (one direction). Single ~70 LOC extraction closes 3 HIGH cycles in one move (T2.1 of plan `arch-review-fixes-2026-06-06`, ADR D433). madge cycle count: 12 → 9. Back-compat re-export preserved on `index-manager.ts`. No public API touched.
1540
1777
  - **Runtime cycle #8 closed**: extracted `internal/runtime/agent-registry-contract.ts` (leaf types file, ~60 LOC) holding `AgentRuntime` + `RegisteredAgent`. Both `agent-registry.ts` and `agent-registry-store.ts` now import these types from the contract; the previous runtime↔store 2-node cycle is closed (T3.1 of plan `arch-review-fixes-2026-06-06`, ADR D431). Back-compat re-export preserved on `agent-registry.ts` for existing downstream importers — no public API change. madge cycle count: 13 → 12 (HIGH cycle #8 resolved; remaining 12 covered by T1.1/T2.1/T4.1).
@@ -1583,7 +1820,7 @@ cwd })` previously compiled and was silently ignored — it hydrated the process
1583
1820
 
1584
1821
  ### Fixed
1585
1822
 
1586
- - **`safeListTools` no longer silently swallows MCP failures** (PV#6, plan `arch-review-fixes-2026-06-06` T8.1). When `client.listTools()` throws (MCP server unreachable, auth refused, etc.), the agent loop now emits a structured `[theokit-sdk] mcp listTools failed (server=<name>): <error>` line to stderr **while preserving the empty-list fallback** that consumers depend on for graceful degradation. The previous behaviour violated Inquebrável Rule 8 (`FALHE alto, FALHE cedo, FALHE claro`). `safeListTools` is now `export`ed from `internal/agent-loop/loop.ts` to enable unit-test access to the catch path — NOT promoted to the public `@theokit/sdk` API surface.
1823
+ - **`safeListTools` no longer silently swallows MCP failures** (PV#6, plan `arch-review-fixes-2026-06-06` T8.1). When `client.listTools()` throws (MCP server unreachable, auth refused, etc.), the agent loop now emits a structured `[theokit-sdk] mcp listTools failed (server=<name>): <error>` line to stderr **while preserving the empty-list fallback** that consumers depend on for graceful degradation. The previous behaviour violated Unbreakable Rule 8 (`FAIL loud, FAIL early, FAIL clear`). `safeListTools` is now `export`ed from `internal/agent-loop/loop.ts` to enable unit-test access to the catch path — NOT promoted to the public `@theokit/sdk` API surface.
1587
1824
 
1588
1825
  ### Notes
1589
1826
 
@@ -1651,7 +1888,7 @@ cwd })` previously compiled and was silently ignored — it hydrated the process
1651
1888
 
1652
1889
  ### Added
1653
1890
 
1654
- - **`@theokit/sdk/server/auth` sub-path** (per ADR D6 of plan g11-auth-architecture-implementation v1.4) — orchestrator-only auth surface ships `defineAuth<TSession>(opts)` factory + 5 supporting types. Implements **Caminho C (Hybrid)** from discovery blueprint `g11-auth-architecture-decision` (SHIPPABLE 97.9). Providers ship as opt-in `@theokit/auth-*` packages (Tier 1: Google + GitHub + Magic Link — separate packages, semver-independent). Aligned with `AUTH-DELEGATION` lock in `theokit/CLAUDE.md:217-225` (lock's own escape-hatch clause "If we do adopt later: ship providers as separate optional packages under `@theokit/auth-*`, NEVER in the framework core").
1891
+ - **`@theokit/sdk/server/auth` sub-path** (per ADR D6 of plan g11-auth-architecture-implementation v1.4) — orchestrator-only auth surface ships `defineAuth<TSession>(opts)` factory + 5 supporting types. Implements **Path C (Hybrid)** from discovery blueprint `g11-auth-architecture-decision` (SHIPPABLE 97.9). Providers ship as opt-in `@theokit/auth-*` packages (Tier 1: Google + GitHub + Magic Link — separate packages, semver-independent). Aligned with `AUTH-DELEGATION` lock in `theokit/CLAUDE.md:217-225` (lock's own escape-hatch clause "If we do adopt later: ship providers as separate optional packages under `@theokit/auth-*`, NEVER in the framework core").
1655
1892
  - **6 type exports** at `@theokit/sdk/server/auth`:
1656
1893
  - `defineAuth<TSession>(opts): AuthOrchestrator<TSession>` factory
1657
1894
  - `DefineAuthOptions<TSession>` config shape
@@ -1674,13 +1911,13 @@ cwd })` previously compiled and was silently ignored — it hydrated the process
1674
1911
 
1675
1912
  - v1.6.0 is **additive** — no breaking changes. Existing consumers of `createSessionManager` (from `theokit/server/auth`) unaffected.
1676
1913
  - Providers (`@theokit/auth-google`, `@theokit/auth-github`, `@theokit/auth-magic-link`) ship in separate npm packages (Phase 2-4 of plan G11). They will publish to `@next` tag first per ADR D3 (4-6 week telemetry observation window before promote to `@latest`).
1677
- - Tests: 16/16 GREEN in `tests/server-auth.test.ts` covering config validation, EC-1, EC-2, EC-10, Caminho A signIn, expired transaction, unknown provider.
1914
+ - Tests: 16/16 GREEN in `tests/server-auth.test.ts` covering config validation, EC-1, EC-2, EC-10, Path A signIn, expired transaction, unknown provider.
1678
1915
 
1679
1916
  ## 1.5.0
1680
1917
 
1681
1918
  ### Changed
1682
1919
 
1683
- - **`publishConfig.provenance` removed (alinhado com política do monorepo).** Esta era a única `package.json` de 11 pacotes publicáveis com `provenance: true`; drift arquitetural a flag prometia attestation criptográfica mas nenhum repo do monorepo tem release.yml com `id-token: write` permission para mintar OIDC token contra o npm registry. Resultado: publishes locais falhavam com `EUSAGE: Automatic provenance generation not supported for provider: null`. Decisão: alinhar intent à infra atual (10/11 outros pacotes não declaram provenance). **Follow-up estratégico:** adicionar release.yml com `id-token: write` em todos os repos (theokit-sdk + theokit + theokit-plugins + theo-ui) habilita provenance universal escopo separado.
1920
+ - **`publishConfig.provenance` removed (aligned with the monorepo's policy).** This was the only `package.json` of 11 publishable packages with `provenance: true`; architectural drift — the flag promised cryptographic attestation but no repo in the monorepo has a release.yml with `id-token: write` permission to mint an OIDC token against the npm registry. Result: local publishes failed with `EUSAGE: Automatic provenance generation not supported for provider: null`. Decision: align intent with the current infrastructure (10 of the 11 other packages declare no provenance). **Strategic follow-up:** adding a release.yml with `id-token: write` across every repo (theokit-sdk + theokit + theokit-plugins + theo-ui) enables universal provenance — separate scope.
1684
1921
 
1685
1922
  ### Breaking Changes
1686
1923