@pensar/apex 2.5.0 → 2.6.1-canary.00edace1

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 (1511) hide show
  1. package/README.md +38 -0
  2. package/bin/pensar.js +12 -4
  3. package/build/{agent-m30a62kh.js → agent-6fmfe7zc.js} +48 -50
  4. package/build/agent-9zhatpdh.js +13 -0
  5. package/build/agent-jattzenq.js +13 -0
  6. package/build/agent-runs-c5t2a2k8.js +313 -0
  7. package/build/agent-vq7nhjwf.js +15 -0
  8. package/build/{apps-x4ef2gpc.js → apps-kwyra69c.js} +50 -58
  9. package/build/{auth-7ay8qgxm.js → auth-qknzk1fs.js} +61 -68
  10. package/build/blackboxAgent-4c9rc4qj.js +13 -0
  11. package/build/blackboxPentest-jt4htpg1.js +59 -0
  12. package/build/cli-1xz3k7c1.js +175 -0
  13. package/build/{cli-zav1yx5k.js → cli-34refsmx.js} +990 -632
  14. package/build/{cli-ee3axgts.js → cli-3gt761d2.js} +7 -1
  15. package/build/cli-3qznjsnr.js +14 -0
  16. package/build/{cli-sx3jkv7p.js → cli-4t980vvb.js} +29592 -26602
  17. package/build/{cli-vkbzcnw1.js → cli-5j2jazzv.js} +43 -40
  18. package/build/{cli-53rm0rrz.js → cli-8w8k4dph.js} +1 -1
  19. package/build/{cli-68260ckj.js → cli-91gs9whc.js} +1658 -1606
  20. package/build/{cli-knd276ed.js → cli-bb02pjt0.js} +31 -31
  21. package/build/{cli-j54qa6tm.js → cli-c2k4xxaw.js} +42 -42
  22. package/build/{cli-k71t434r.js → cli-ec2hwkv3.js} +34 -76
  23. package/build/{cli-7vg06q5r.js → cli-f27svfd0.js} +135 -125
  24. package/build/{cli-z5c0ypg1.js → cli-fx0zc3z5.js} +4 -4
  25. package/build/cli-g06s7edq.js +11 -0
  26. package/build/cli-gsaf4jk3.js +280 -0
  27. package/build/{cli-bc05qbss.js → cli-h6y3bt60.js} +13 -21
  28. package/build/cli-jdrx44ge.js +14 -0
  29. package/build/cli-mz5pk30x.js +5508 -0
  30. package/build/{cli-y3dpm18e.js → cli-n6eagdnm.js} +75 -92
  31. package/build/cli-pwm29ks7.js +6337 -0
  32. package/build/{cli-x92fkt2f.js → cli-qnwc6k4n.js} +55 -97
  33. package/build/{cli-p4r7q012.js → cli-r2pt74b3.js} +16892 -13395
  34. package/build/cli-retw3rw5.js +12 -0
  35. package/build/{cli-3py0a0wg.js → cli-scwvvr3d.js} +206 -136
  36. package/build/cli-se8ae8z3.js +2250 -0
  37. package/build/{cli-dm0fc0bm.js → cli-v1sarr4y.js} +5 -9
  38. package/build/cli-wf04sngj.js +62 -0
  39. package/build/{cli-73k43t1r.js → cli-wmha2xw1.js} +53 -78
  40. package/build/cli-wv50bsyn.js +186 -0
  41. package/build/cli-x4ymfc9t.js +22 -0
  42. package/build/cli-xcy2vxj2.js +1732 -0
  43. package/build/{cli-bw2ddttk.js → cli-xr4a62zr.js} +4730 -267
  44. package/build/cli-ypant18n.js +429 -0
  45. package/build/cli-yz6mykyx.js +355 -0
  46. package/build/{cli-kff2bbq7.js → cli-z3ef8eh7.js} +43 -43
  47. package/build/cli.js +769 -195
  48. package/build/{config-4kzh88xz.js → config-s4mp7mnb.js} +16 -19
  49. package/build/{doctor-rz7sx6ev.js → doctor-z94afr10.js} +26 -15
  50. package/build/export-trajectory-rt4tf07k.js +112 -0
  51. package/build/{fastStrike-a54atjc8.js → fastStrike-8pdk35we.js} +56 -31
  52. package/build/{fixes-fv66yn1z.js → fixes-cg01qdys.js} +22 -30
  53. package/build/{getMachineId-bsd-xj3bn2fv.js → getMachineId-bsd-zr67nd9p.js} +5 -5
  54. package/build/{getMachineId-darwin-07jzjcx6.js → getMachineId-darwin-fd1d562d.js} +5 -5
  55. package/build/{getMachineId-linux-ahngynxd.js → getMachineId-linux-kjmg243j.js} +4 -4
  56. package/build/{getMachineId-unsupported-vy43b44z.js → getMachineId-unsupported-n4r58vke.js} +4 -4
  57. package/build/{getMachineId-win-8x66cynz.js → getMachineId-win-yzgpfsrb.js} +5 -5
  58. package/build/index-27yf0j2g.js +102 -0
  59. package/build/index-3r0f4993.js +9 -0
  60. package/build/index-6xqf6ybr.js +17 -0
  61. package/build/{index-kyd1jm89.js → index-7a1cej0p.js} +159 -169
  62. package/build/index-a0bxw5zq.js +17477 -0
  63. package/build/{index-cbwn03kz.js → index-a2xycbjs.js} +12 -31
  64. package/build/{index-psqjpw5m.js → index-c1h0g35p.js} +11 -11
  65. package/build/index-qnyevb6q.js +1563 -0
  66. package/build/index-rb59mdw1.js +25 -0
  67. package/build/index-v8yndwms.js +36 -0
  68. package/build/index-whwz8wq4.js +12 -0
  69. package/build/index-wn3newjz.js +121 -0
  70. package/build/{index-fpwr10qm.js → index-y5vr1yg7.js} +5106 -3803
  71. package/build/{issues-019678t0.js → issues-7jaghcad.js} +51 -47
  72. package/build/knowledge-6vqq5pnn.js +139 -0
  73. package/build/lib/chunk-2njv7wz3.js +178 -0
  74. package/build/lib/chunk-2p7tv7jw.js +27 -0
  75. package/build/lib/chunk-3q89v4xv.js +21 -0
  76. package/build/lib/chunk-4bdsr592.js +685 -0
  77. package/build/lib/chunk-580kjrad.js +7150 -0
  78. package/build/lib/chunk-6d588qgq.js +186 -0
  79. package/build/lib/chunk-7gjdygcx.js +171 -0
  80. package/build/lib/chunk-8vhr65w3.js +272 -0
  81. package/build/lib/chunk-9nsrd4xg.js +12 -0
  82. package/build/lib/chunk-b35zyxyz.js +11209 -0
  83. package/build/lib/chunk-b8eq85d2.js +143 -0
  84. package/build/lib/chunk-baffatvh.js +922 -0
  85. package/build/lib/chunk-btdfy3d7.js +572 -0
  86. package/build/lib/chunk-bx94rwt5.js +24 -0
  87. package/build/lib/chunk-c8baz874.js +143 -0
  88. package/build/lib/chunk-dwxx20nv.js +120 -0
  89. package/build/lib/chunk-eb4h4k1f.js +213 -0
  90. package/build/lib/chunk-esymacwg.js +14 -0
  91. package/build/lib/chunk-fxm1r7vt.js +980 -0
  92. package/build/lib/chunk-fy3bbbqy.js +7896 -0
  93. package/build/lib/chunk-hsxcndfn.js +431 -0
  94. package/build/lib/chunk-j0m8s2r3.js +317 -0
  95. package/build/lib/chunk-ja7j565c.js +743 -0
  96. package/build/lib/chunk-jdjagvgr.js +85 -0
  97. package/build/lib/chunk-jtxxer1z.js +317 -0
  98. package/build/lib/chunk-jwezppfx.js +510 -0
  99. package/build/lib/chunk-mv74mq5n.js +59 -0
  100. package/build/lib/chunk-mwy4qcmg.js +345 -0
  101. package/build/lib/chunk-n0ba7khr.js +64 -0
  102. package/build/lib/chunk-p1xsnbtn.js +212 -0
  103. package/build/lib/chunk-q5e23acz.js +52 -0
  104. package/build/lib/chunk-s2zb90ym.js +2446 -0
  105. package/build/lib/chunk-scydgpm0.js +1412 -0
  106. package/build/lib/chunk-t5bt5vn1.js +146 -0
  107. package/build/lib/chunk-t652qvwk.js +56 -0
  108. package/build/lib/chunk-tpt4pdfj.js +9402 -0
  109. package/build/lib/chunk-v3fmrm2q.js +102 -0
  110. package/build/lib/chunk-vx228eeq.js +82 -0
  111. package/build/lib/chunk-wyk6gyj6.js +62 -0
  112. package/build/lib/chunk-xkpj1tha.js +439 -0
  113. package/build/lib/chunk-xp3krsrm.js +31 -0
  114. package/build/lib/chunk-xpfg2fbk.js +90 -0
  115. package/build/lib/chunk-zrbqn62x.js +697 -0
  116. package/build/lib/core/agents/agentRuntime.d.ts +47 -0
  117. package/build/lib/core/agents/defineAgent.d.ts +82 -0
  118. package/build/lib/core/agents/offSecAgent/index.d.ts +9 -0
  119. package/build/lib/core/agents/offSecAgent/index.js +225 -0
  120. package/build/lib/core/agents/offSecAgent/interruptedStepFinalization.d.ts +23 -0
  121. package/build/lib/core/agents/offSecAgent/interruptedStepMessages.d.ts +42 -0
  122. package/build/lib/core/agents/offSecAgent/messagePersistence.d.ts +39 -0
  123. package/build/lib/core/agents/offSecAgent/offensiveSecurityAgent.d.ts +233 -0
  124. package/build/lib/core/agents/offSecAgent/prompt.d.ts +35 -0
  125. package/build/lib/core/agents/offSecAgent/recordedTools.d.ts +11 -0
  126. package/build/lib/core/agents/offSecAgent/runtimeContext.d.ts +43 -0
  127. package/build/lib/core/agents/offSecAgent/streamDiagnostics.d.ts +67 -0
  128. package/build/lib/core/agents/offSecAgent/subagentSpawner.d.ts +223 -0
  129. package/build/lib/core/agents/offSecAgent/subagentSpawner.js +19 -0
  130. package/build/lib/core/agents/offSecAgent/toolLifecycle.d.ts +54 -0
  131. package/build/lib/core/agents/offSecAgent/tools/__tests__/sandboxScript.d.ts +1 -0
  132. package/build/lib/core/agents/offSecAgent/tools/addMemory.d.ts +16 -0
  133. package/build/lib/core/agents/offSecAgent/tools/agentScratch.d.ts +17 -0
  134. package/build/lib/core/agents/offSecAgent/tools/applyPatch.d.ts +8 -0
  135. package/build/lib/core/agents/offSecAgent/tools/applyPatchImpl.d.ts +24 -0
  136. package/build/lib/core/agents/offSecAgent/tools/askUserQuestions.d.ts +42 -0
  137. package/build/lib/core/agents/offSecAgent/tools/browserHeaderRouting.d.ts +9 -0
  138. package/build/lib/core/agents/offSecAgent/tools/browserToolFactories.d.ts +40 -0
  139. package/build/lib/core/agents/offSecAgent/tools/browserTools.d.ts +96 -0
  140. package/build/lib/core/agents/offSecAgent/tools/callbackListener.d.ts +212 -0
  141. package/build/lib/core/agents/offSecAgent/tools/camoufox.d.ts +106 -0
  142. package/build/lib/core/agents/offSecAgent/tools/checkpointState.d.ts +17 -0
  143. package/build/lib/core/agents/offSecAgent/tools/completeAuthentication.d.ts +39 -0
  144. package/build/lib/core/agents/offSecAgent/tools/crawlAuthenticated.d.ts +36 -0
  145. package/build/lib/core/agents/offSecAgent/tools/createAttackSurfaceReport.d.ts +31 -0
  146. package/build/lib/core/agents/offSecAgent/tools/createFile.d.ts +12 -0
  147. package/build/lib/core/agents/offSecAgent/tools/createTask.d.ts +20 -0
  148. package/build/lib/core/agents/offSecAgent/tools/delegateAuth.d.ts +72 -0
  149. package/build/lib/core/agents/offSecAgent/tools/deleteFile.d.ts +10 -0
  150. package/build/lib/core/agents/offSecAgent/tools/destructiveGuard.d.ts +94 -0
  151. package/build/lib/core/agents/offSecAgent/tools/detectAuthScheme.d.ts +72 -0
  152. package/build/lib/core/agents/offSecAgent/tools/documentApp.d.ts +38 -0
  153. package/build/lib/core/agents/offSecAgent/tools/documentEndpoint.d.ts +111 -0
  154. package/build/lib/core/agents/offSecAgent/tools/documentFinding.d.ts +285 -0
  155. package/build/lib/core/agents/offSecAgent/tools/email/adapters.d.ts +45 -0
  156. package/build/lib/core/agents/offSecAgent/tools/email/adapters.js +8 -0
  157. package/build/lib/core/agents/offSecAgent/tools/email/getAttachments.d.ts +33 -0
  158. package/build/lib/core/agents/offSecAgent/tools/email/getMessage.d.ts +20 -0
  159. package/build/lib/core/agents/offSecAgent/tools/email/index.d.ts +145 -0
  160. package/build/lib/core/agents/offSecAgent/tools/email/listInboxes.d.ts +23 -0
  161. package/build/lib/core/agents/offSecAgent/tools/email/listMessages.d.ts +22 -0
  162. package/build/lib/core/agents/offSecAgent/tools/email/markRead.d.ts +20 -0
  163. package/build/lib/core/agents/offSecAgent/tools/email/searchMessages.d.ts +24 -0
  164. package/build/lib/core/agents/offSecAgent/tools/email/sendEmail.d.ts +28 -0
  165. package/build/lib/core/agents/offSecAgent/tools/email/types.d.ts +40 -0
  166. package/build/lib/core/agents/offSecAgent/tools/email/types.js +0 -0
  167. package/build/lib/core/agents/offSecAgent/tools/executeCommand.d.ts +84 -0
  168. package/build/lib/core/agents/offSecAgent/tools/extractJsEndpoints.d.ts +13 -0
  169. package/build/lib/core/agents/offSecAgent/tools/fileWorkspace.d.ts +21 -0
  170. package/build/lib/core/agents/offSecAgent/tools/fileWorkspaceRemote.d.ts +13 -0
  171. package/build/lib/core/agents/offSecAgent/tools/getMemory.d.ts +12 -0
  172. package/build/lib/core/agents/offSecAgent/tools/getPage.d.ts +17 -0
  173. package/build/lib/core/agents/offSecAgent/tools/gitDiff.d.ts +12 -0
  174. package/build/lib/core/agents/offSecAgent/tools/gitStatus.d.ts +10 -0
  175. package/build/lib/core/agents/offSecAgent/tools/glob.d.ts +8 -0
  176. package/build/lib/core/agents/offSecAgent/tools/globImpl.d.ts +13 -0
  177. package/build/lib/core/agents/offSecAgent/tools/globPattern.d.ts +7 -0
  178. package/build/lib/core/agents/offSecAgent/tools/grep.d.ts +10 -0
  179. package/build/lib/core/agents/offSecAgent/tools/grepImpl.d.ts +34 -0
  180. package/build/lib/core/agents/offSecAgent/tools/httpRequest.d.ts +70 -0
  181. package/build/lib/core/agents/offSecAgent/tools/index.d.ts +466 -0
  182. package/build/lib/core/agents/offSecAgent/tools/index.js +262 -0
  183. package/build/lib/core/agents/offSecAgent/tools/listFiles.d.ts +9 -0
  184. package/build/lib/core/agents/offSecAgent/tools/listFilesImpl.d.ts +27 -0
  185. package/build/lib/core/agents/offSecAgent/tools/listMemories.d.ts +23 -0
  186. package/build/lib/core/agents/offSecAgent/tools/listPromptInjections.d.ts +18 -0
  187. package/build/lib/core/agents/offSecAgent/tools/listTasks.d.ts +24 -0
  188. package/build/lib/core/agents/offSecAgent/tools/patchApply.d.ts +24 -0
  189. package/build/lib/core/agents/offSecAgent/tools/patchParse.d.ts +24 -0
  190. package/build/lib/core/agents/offSecAgent/tools/perCommandShell.d.ts +82 -0
  191. package/build/lib/core/agents/offSecAgent/tools/playwrightMcp.d.ts +369 -0
  192. package/build/lib/core/agents/offSecAgent/tools/probeAuthEndpoints.d.ts +28 -0
  193. package/build/lib/core/agents/offSecAgent/tools/profileCodebase.d.ts +33 -0
  194. package/build/lib/core/agents/offSecAgent/tools/provideComparisonResults.d.ts +31 -0
  195. package/build/lib/core/agents/offSecAgent/tools/queryWhiteboxCatalog.d.ts +17 -0
  196. package/build/lib/core/agents/offSecAgent/tools/readFile.d.ts +11 -0
  197. package/build/lib/core/agents/offSecAgent/tools/readFileImpl.d.ts +31 -0
  198. package/build/lib/core/agents/offSecAgent/tools/readSkill.d.ts +15 -0
  199. package/build/lib/core/agents/offSecAgent/tools/reportError.d.ts +31 -0
  200. package/build/lib/core/agents/offSecAgent/tools/response.d.ts +15 -0
  201. package/build/lib/core/agents/offSecAgent/tools/runAttackSurface.d.ts +81 -0
  202. package/build/lib/core/agents/offSecAgent/tools/runCodeQuery.d.ts +44 -0
  203. package/build/lib/core/agents/offSecAgent/tools/runPentestWorkflow.d.ts +32 -0
  204. package/build/lib/core/agents/offSecAgent/tools/runWhiteboxScan.d.ts +52 -0
  205. package/build/lib/core/agents/offSecAgent/tools/sandbox.d.ts +30 -0
  206. package/build/lib/core/agents/offSecAgent/tools/sandboxPlaywright.d.ts +137 -0
  207. package/build/lib/core/agents/offSecAgent/tools/sandboxScript.d.ts +6 -0
  208. package/build/lib/core/agents/offSecAgent/tools/scopeGuard.d.ts +91 -0
  209. package/build/lib/core/agents/offSecAgent/tools/scriptSyntaxCheck.d.ts +45 -0
  210. package/build/lib/core/agents/offSecAgent/tools/smsInbox.d.ts +67 -0
  211. package/build/lib/core/agents/offSecAgent/tools/smsInbox.js +6 -0
  212. package/build/lib/core/agents/offSecAgent/tools/smsListMessages.d.ts +29 -0
  213. package/build/lib/core/agents/offSecAgent/tools/spawnCodingAgent.d.ts +43 -0
  214. package/build/lib/core/agents/offSecAgent/tools/spawnPentestAgent.d.ts +51 -0
  215. package/build/lib/core/agents/offSecAgent/tools/spawnPentestSwarm.d.ts +52 -0
  216. package/build/lib/core/agents/offSecAgent/tools/submitPlan.d.ts +12 -0
  217. package/build/lib/core/agents/offSecAgent/tools/testEndpointVariations.d.ts +34 -0
  218. package/build/lib/core/agents/offSecAgent/tools/threatModelGenerator.d.ts +32 -0
  219. package/build/lib/core/agents/offSecAgent/tools/toolOutput.d.ts +23 -0
  220. package/build/lib/core/agents/offSecAgent/tools/types.d.ts +215 -0
  221. package/build/lib/core/agents/offSecAgent/tools/updateFile.d.ts +14 -0
  222. package/build/lib/core/agents/offSecAgent/tools/updateTask.d.ts +20 -0
  223. package/build/lib/core/agents/offSecAgent/tools/validateDiscovery.d.ts +24 -0
  224. package/build/lib/core/agents/offSecAgent/tools/webSearch.d.ts +16 -0
  225. package/build/lib/core/agents/offSecAgent/tools/whiteboxCandidates.d.ts +108 -0
  226. package/build/lib/core/agents/offSecAgent/tools/whiteboxJobs.d.ts +157 -0
  227. package/build/lib/core/agents/offSecAgent/tools/windowsCurl.d.ts +20 -0
  228. package/build/lib/core/agents/offSecAgent/tools/workspaceApps.d.ts +120 -0
  229. package/build/lib/core/agents/offSecAgent/tools/workspaceDomains.d.ts +22 -0
  230. package/build/lib/core/agents/offSecAgent/tools/workspaceFailure.d.ts +6 -0
  231. package/build/lib/core/agents/offSecAgent/tools/writePlan.d.ts +13 -0
  232. package/build/lib/core/agents/offSecAgent/trace.d.ts +268 -0
  233. package/build/lib/core/agents/offSecAgent/types.d.ts +543 -0
  234. package/build/lib/core/agents/offSecAgent/types.js +7 -0
  235. package/build/lib/core/agents/specialized/attackSurface/blackboxAgent.d.ts +66 -0
  236. package/build/lib/core/agents/specialized/attackSurface/blackboxAgent.js +33 -0
  237. package/build/lib/core/agents/specialized/attackSurface/blackboxRiskScoring.d.ts +30 -0
  238. package/build/lib/core/agents/specialized/attackSurface/grpcSchema.d.ts +93 -0
  239. package/build/lib/core/agents/specialized/attackSurface/jsExtraction.d.ts +42 -0
  240. package/build/lib/core/agents/specialized/attackSurface/prompts.d.ts +1 -0
  241. package/build/lib/core/agents/specialized/attackSurface/schemas.d.ts +284 -0
  242. package/build/lib/core/agents/specialized/attackSurface/schemas.js +144 -0
  243. package/build/lib/core/agents/specialized/attackSurface/types.d.ts +32 -0
  244. package/build/lib/core/agents/specialized/authenticationAgent/agent.d.ts +73 -0
  245. package/build/lib/core/agents/specialized/authenticationAgent/index.d.ts +4 -0
  246. package/build/lib/core/agents/specialized/authenticationAgent/index.js +71 -0
  247. package/build/lib/core/agents/specialized/authenticationAgent/prompts.d.ts +10 -0
  248. package/build/lib/core/agents/specialized/authenticationAgent/types.d.ts +620 -0
  249. package/build/lib/core/agents/specialized/benchmark/comparisonAgent.d.ts +10 -0
  250. package/build/lib/core/agents/specialized/benchmark/docker-utils.d.ts +17 -0
  251. package/build/lib/core/agents/specialized/benchmark/flag-detector.d.ts +60 -0
  252. package/build/lib/core/agents/specialized/benchmark/index.d.ts +8 -0
  253. package/build/lib/core/agents/specialized/benchmark/prompts.d.ts +1 -0
  254. package/build/lib/core/agents/specialized/benchmark/remote/circuit-breaker.d.ts +22 -0
  255. package/build/lib/core/agents/specialized/benchmark/remote/daytona-wrapper.d.ts +33 -0
  256. package/build/lib/core/agents/specialized/benchmark/remote/index.d.ts +2 -0
  257. package/build/lib/core/agents/specialized/benchmark/types.d.ts +92 -0
  258. package/build/lib/core/agents/specialized/benchmarkComparisonAgent.d.ts +27 -0
  259. package/build/lib/core/agents/specialized/codeAgent/agent.d.ts +50 -0
  260. package/build/lib/core/agents/specialized/codeAgent/agent.js +31 -0
  261. package/build/lib/core/agents/specialized/codeAgent/prompts.d.ts +1 -0
  262. package/build/lib/core/agents/specialized/codeAgent/schemas.d.ts +11 -0
  263. package/build/lib/core/agents/specialized/codeAgent/schemas.js +10 -0
  264. package/build/lib/core/agents/specialized/cvssScorer/index.d.ts +56 -0
  265. package/build/lib/core/agents/specialized/environment/agent.d.ts +43 -0
  266. package/build/lib/core/agents/specialized/environment/index.d.ts +4 -0
  267. package/build/lib/core/agents/specialized/environment/prompts.d.ts +10 -0
  268. package/build/lib/core/agents/specialized/environment/types.d.ts +37 -0
  269. package/build/lib/core/agents/specialized/findingJudge/agent.d.ts +22 -0
  270. package/build/lib/core/agents/specialized/findingJudge/agent.js +224 -0
  271. package/build/lib/core/agents/specialized/findingJudge/index.d.ts +31 -0
  272. package/build/lib/core/agents/specialized/findingJudge/index.js +13 -0
  273. package/build/lib/core/agents/specialized/findingJudge/prompts.d.ts +3 -0
  274. package/build/lib/core/agents/specialized/findingJudge/types.d.ts +77 -0
  275. package/build/lib/core/agents/specialized/googleSignInPrompt.d.ts +4 -0
  276. package/build/lib/core/agents/specialized/mobileOtpPrompt.d.ts +1 -0
  277. package/build/lib/core/agents/specialized/patching/agent.d.ts +64 -0
  278. package/build/lib/core/agents/specialized/patching/index.d.ts +4 -0
  279. package/build/lib/core/agents/specialized/patching/index.js +44 -0
  280. package/build/lib/core/agents/specialized/patching/prompts.d.ts +17 -0
  281. package/build/lib/core/agents/specialized/patching/types.d.ts +40 -0
  282. package/build/lib/core/agents/specialized/pentest/agent.d.ts +172 -0
  283. package/build/lib/core/agents/specialized/pentest/agent.js +43 -0
  284. package/build/lib/core/agents/specialized/pentest/helperWorkspace.d.ts +16 -0
  285. package/build/lib/core/agents/specialized/pentest/planPrompt.d.ts +13 -0
  286. package/build/lib/core/agents/specialized/utils.d.ts +7 -0
  287. package/build/lib/core/agents/specialized/vulnerabilityReproduction/agent.d.ts +94 -0
  288. package/build/lib/core/agents/specialized/whiteboxAttackSurface/agent.d.ts +148 -0
  289. package/build/lib/core/agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent.d.ts +61 -0
  290. package/build/lib/core/agents/specialized/whiteboxAttackSurface/index.d.ts +5 -0
  291. package/build/lib/core/agents/specialized/whiteboxAttackSurface/index.js +47 -0
  292. package/build/lib/core/agents/specialized/whiteboxAttackSurface/prompts.d.ts +34 -0
  293. package/build/lib/core/agents/specialized/whiteboxAttackSurface/types.d.ts +382 -0
  294. package/build/lib/core/agents/specialized/whiteboxAttackSurface/types.js +21 -0
  295. package/build/lib/core/ai/ai.d.ts +349 -0
  296. package/build/lib/core/ai/ai.js +68 -0
  297. package/build/lib/core/ai/caching.d.ts +26 -0
  298. package/build/lib/core/ai/compactionEvidence.d.ts +15 -0
  299. package/build/lib/core/ai/compactionTelemetry.d.ts +55 -0
  300. package/build/lib/core/ai/contextManagement.d.ts +85 -0
  301. package/build/lib/core/ai/index.d.ts +10 -0
  302. package/build/lib/core/ai/index.js +72 -0
  303. package/build/lib/core/ai/inference-attempt/adapters.d.ts +15 -0
  304. package/build/lib/core/ai/inference-attempt/builder.d.ts +31 -0
  305. package/build/lib/core/ai/inference-attempt/envelope.d.ts +120 -0
  306. package/build/lib/core/ai/inference-attempt/errors.d.ts +6 -0
  307. package/build/lib/core/ai/inference-attempt/identity.d.ts +13 -0
  308. package/build/lib/core/ai/inference-attempt/index.d.ts +36 -0
  309. package/build/lib/core/ai/inference-attempt/project.d.ts +21 -0
  310. package/build/lib/core/ai/inference-attempt/recording.d.ts +23 -0
  311. package/build/lib/core/ai/inference-attempt/tokens.d.ts +13 -0
  312. package/build/lib/core/ai/inference-attempt/validate.d.ts +2 -0
  313. package/build/lib/core/ai/mantle.d.ts +28 -0
  314. package/build/lib/core/ai/model-history.d.ts +4 -0
  315. package/build/lib/core/ai/models/anthropic.d.ts +2 -0
  316. package/build/lib/core/ai/models/bedrock.d.ts +2 -0
  317. package/build/lib/core/ai/models/claude-capabilities.d.ts +7 -0
  318. package/build/lib/core/ai/models/concentrate.d.ts +2 -0
  319. package/build/lib/core/ai/models/google.d.ts +2 -0
  320. package/build/lib/core/ai/models/inception.d.ts +2 -0
  321. package/build/lib/core/ai/models/index.d.ts +29 -0
  322. package/build/lib/core/ai/models/mantle.d.ts +2 -0
  323. package/build/lib/core/ai/models/openai.d.ts +2 -0
  324. package/build/lib/core/ai/models/openrouter.d.ts +2 -0
  325. package/build/lib/core/ai/models/pensar.d.ts +2 -0
  326. package/build/lib/core/ai/native-rollout-evidence/capture.d.ts +31 -0
  327. package/build/lib/core/ai/native-rollout-evidence/content.d.ts +14 -0
  328. package/build/lib/core/ai/native-rollout-evidence/index.d.ts +9 -0
  329. package/build/lib/core/ai/native-rollout-evidence/provider-metadata.d.ts +15 -0
  330. package/build/lib/core/ai/native-rollout-evidence/schema.d.ts +554 -0
  331. package/build/lib/core/ai/native-rollout-evidence/validate.d.ts +8 -0
  332. package/build/lib/core/ai/providers/anthropic.d.ts +2 -0
  333. package/build/lib/core/ai/providers/concentrate.d.ts +9 -0
  334. package/build/lib/core/ai/providers/custom.d.ts +3 -0
  335. package/build/lib/core/ai/providers/hoonify.d.ts +6 -0
  336. package/build/lib/core/ai/providers/openai-pro-fetch.d.ts +2 -0
  337. package/build/lib/core/ai/providers/pensar.d.ts +34 -0
  338. package/build/lib/core/ai/providers/pensarFormatters.d.ts +2 -0
  339. package/build/lib/core/ai/providers/pensarResponsesStream.d.ts +15 -0
  340. package/build/lib/core/ai/providers/pensarSSE.d.ts +23 -0
  341. package/build/lib/core/ai/providers/pensarSigning.d.ts +1 -0
  342. package/build/lib/core/ai/providers/pensarStreamUsage.d.ts +19 -0
  343. package/build/lib/core/ai/streamTelemetry.d.ts +22 -0
  344. package/build/lib/core/ai/utils.d.ts +92 -0
  345. package/build/lib/core/ai/utils.js +24 -0
  346. package/build/lib/core/api/apiClient.d.ts +7 -0
  347. package/build/lib/core/api/apps.d.ts +213 -0
  348. package/build/lib/core/api/attackSurface.d.ts +14 -0
  349. package/build/lib/core/api/authentication.d.ts +3 -0
  350. package/build/lib/core/api/benchmark.d.ts +5 -0
  351. package/build/lib/core/api/blackboxPentest.d.ts +11 -0
  352. package/build/lib/core/api/clientIdentity.d.ts +10 -0
  353. package/build/lib/core/api/constants.d.ts +5 -0
  354. package/build/lib/core/api/domains.d.ts +19 -0
  355. package/build/lib/core/api/environment.d.ts +16 -0
  356. package/build/lib/core/api/index.d.ts +41 -0
  357. package/build/lib/core/api/index.js +187 -0
  358. package/build/lib/core/api/issues.d.ts +273 -0
  359. package/build/lib/core/api/knowledge.d.ts +33 -0
  360. package/build/lib/core/api/localWorker.d.ts +4 -0
  361. package/build/lib/core/api/offesecAgent.d.ts +34 -0
  362. package/build/lib/core/api/patching.d.ts +15 -0
  363. package/build/lib/core/api/recordedRun.d.ts +36 -0
  364. package/build/lib/core/api/targetedPentest.d.ts +15 -0
  365. package/build/lib/core/api/targetedPentest.js +32 -0
  366. package/build/lib/core/api/threatModel.d.ts +1 -0
  367. package/build/lib/core/api/trajectoryExport.d.ts +38 -0
  368. package/build/lib/core/api/vulnerabilityReproduction.d.ts +10 -0
  369. package/build/lib/core/assets/wordlists.d.ts +31 -0
  370. package/build/lib/core/atif/convert.d.ts +27 -0
  371. package/build/lib/core/atif/index.d.ts +7 -0
  372. package/build/lib/core/atif/schema.d.ts +459 -0
  373. package/build/lib/core/atif/serialize.d.ts +2 -0
  374. package/build/lib/core/atif/test-fixtures.d.ts +28 -0
  375. package/build/lib/core/atif/validate.d.ts +12 -0
  376. package/build/lib/core/auth/connection.d.ts +12 -0
  377. package/build/lib/core/auth/device-flow.d.ts +38 -0
  378. package/build/lib/core/auth/gateway.d.ts +25 -0
  379. package/build/lib/core/auth/index.d.ts +8 -0
  380. package/build/lib/core/auth/signing.d.ts +14 -0
  381. package/build/lib/core/auth/token.d.ts +17 -0
  382. package/build/lib/core/auth/types.d.ts +85 -0
  383. package/build/lib/core/auth/workspaces.d.ts +34 -0
  384. package/build/lib/core/benchmark/index.d.ts +3 -0
  385. package/build/lib/core/benchmark/report.d.ts +3 -0
  386. package/build/lib/core/benchmark/runner.d.ts +3 -0
  387. package/build/lib/core/benchmark/types.d.ts +80 -0
  388. package/build/lib/core/cli/logLevelArgs.d.ts +18 -0
  389. package/build/lib/core/cli/model.d.ts +9 -0
  390. package/build/lib/core/cli/pentestMode.d.ts +5 -0
  391. package/build/lib/core/cli/tuiArgs.d.ts +5 -0
  392. package/build/lib/core/config/config.d.ts +86 -0
  393. package/build/lib/core/config/customProviders.d.ts +62 -0
  394. package/build/lib/core/config/index.d.ts +6 -0
  395. package/build/lib/core/config/index.js +6 -0
  396. package/build/lib/core/credentials/index.d.ts +2 -0
  397. package/build/lib/core/credentials/manager.d.ts +85 -0
  398. package/build/lib/core/credentials/types.d.ts +79 -0
  399. package/build/lib/core/doctor.d.ts +1 -0
  400. package/build/lib/core/eventBus.d.ts +195 -0
  401. package/build/lib/core/eventBus.js +6 -0
  402. package/build/lib/core/findings/attackSurfaceRegistry.d.ts +88 -0
  403. package/build/lib/core/findings/attackSurfaceRegistry.js +6 -0
  404. package/build/lib/core/findings/registry.d.ts +177 -0
  405. package/build/lib/core/findings/registry.js +21 -0
  406. package/build/lib/core/history.d.ts +23 -0
  407. package/build/lib/core/hoonify.d.ts +8 -0
  408. package/build/lib/core/http/parse.d.ts +50 -0
  409. package/build/lib/core/http/redirects.d.ts +23 -0
  410. package/build/lib/core/http/targetHeaders.d.ts +30 -0
  411. package/build/lib/core/http/targetScope.d.ts +12 -0
  412. package/build/lib/core/http/types.d.ts +11 -0
  413. package/build/lib/core/id/id.d.ts +60 -0
  414. package/build/lib/core/id/id.js +28 -0
  415. package/build/lib/core/installation/index.d.ts +25 -0
  416. package/build/lib/core/integrations/herdr.d.ts +13 -0
  417. package/build/lib/core/integrations/surface/index.d.ts +37 -0
  418. package/build/lib/core/integrations/surface/types.d.ts +22 -0
  419. package/build/lib/core/integrations/wandb/client.d.ts +23 -0
  420. package/build/lib/core/integrations/wandb/upload.d.ts +36 -0
  421. package/build/lib/core/logger/index.d.ts +62 -0
  422. package/build/lib/core/logger/structured.d.ts +30 -0
  423. package/build/lib/core/memory/index.d.ts +92 -0
  424. package/build/lib/core/memory/index.js +21 -0
  425. package/build/lib/core/messages/types.d.ts +96 -0
  426. package/build/lib/core/obfuscation/engine.d.ts +51 -0
  427. package/build/lib/core/obfuscation/index.d.ts +20 -0
  428. package/build/lib/core/observability/active-root-spans.d.ts +5 -0
  429. package/build/lib/core/observability/active-spans.d.ts +22 -0
  430. package/build/lib/core/observability/index.d.ts +36 -0
  431. package/build/lib/core/observability/index.js +27 -0
  432. package/build/lib/core/observability/runtime.d.ts +63 -0
  433. package/build/lib/core/observability/telemetry.d.ts +52 -0
  434. package/build/lib/core/observability/testkit.d.ts +24 -0
  435. package/build/lib/core/operator/approvalGate.d.ts +61 -0
  436. package/build/lib/core/operator/index.d.ts +9 -0
  437. package/build/lib/core/operator/types.d.ts +167 -0
  438. package/build/lib/core/plan/index.d.ts +16 -0
  439. package/build/lib/core/prompt-injections/index.d.ts +111 -0
  440. package/build/lib/core/prompt-injections/index.js +24 -0
  441. package/build/lib/core/providers/index.d.ts +5 -0
  442. package/build/lib/core/providers/types.d.ts +13 -0
  443. package/build/lib/core/providers/utils.d.ts +15 -0
  444. package/build/lib/core/providers/verify.d.ts +11 -0
  445. package/build/lib/core/report/builder.d.ts +9 -0
  446. package/build/lib/core/report/index.d.ts +7 -0
  447. package/build/lib/core/report/renderers/json.d.ts +2 -0
  448. package/build/lib/core/report/renderers/markdown.d.ts +2 -0
  449. package/build/lib/core/report/schemas.d.ts +115 -0
  450. package/build/lib/core/runtime/agentExecution.d.ts +15 -0
  451. package/build/lib/core/runtime/launchLocalWorker.d.ts +33 -0
  452. package/build/lib/core/runtime/localRunLock.d.ts +9 -0
  453. package/build/lib/core/runtime/localRunWorker.d.ts +18 -0
  454. package/build/lib/core/runtime/localWorkerEndpoint.d.ts +14 -0
  455. package/build/lib/core/runtime/localWorkerProtocol.d.ts +294 -0
  456. package/build/lib/core/runtime/localWorkerTransport.d.ts +30 -0
  457. package/build/lib/core/runtime/persistenceError.d.ts +9 -0
  458. package/build/lib/core/runtime/recordedExecution.d.ts +6 -0
  459. package/build/lib/core/runtime/recordedRunClient.d.ts +34 -0
  460. package/build/lib/core/runtime/runCheckpointStore.d.ts +11 -0
  461. package/build/lib/core/runtime/runContext.d.ts +48 -0
  462. package/build/lib/core/runtime/runControl.d.ts +44 -0
  463. package/build/lib/core/runtime/runControlStore.d.ts +83 -0
  464. package/build/lib/core/runtime/runDeadline.d.ts +4 -0
  465. package/build/lib/core/runtime/runEvidence.d.ts +37 -0
  466. package/build/lib/core/runtime/runInference.d.ts +9 -0
  467. package/build/lib/core/runtime/runModelStore.d.ts +27 -0
  468. package/build/lib/core/runtime/runObservation.d.ts +19 -0
  469. package/build/lib/core/runtime/runRecoveryContext.d.ts +20 -0
  470. package/build/lib/core/runtime/runRecoveryPlan.d.ts +38 -0
  471. package/build/lib/core/runtime/runRecoveryStore.d.ts +77 -0
  472. package/build/lib/core/runtime/runStore.d.ts +133 -0
  473. package/build/lib/core/runtime/runStorePath.d.ts +1 -0
  474. package/build/lib/core/runtime/runToolStore.d.ts +50 -0
  475. package/build/lib/core/runtime/runTools.d.ts +16 -0
  476. package/build/lib/core/runtime/sqliteControlStore.d.ts +41 -0
  477. package/build/lib/core/runtime/sqliteModelStore.d.ts +20 -0
  478. package/build/lib/core/runtime/sqliteRecoveryStore.d.ts +35 -0
  479. package/build/lib/core/runtime/sqliteRunStore.d.ts +8 -0
  480. package/build/lib/core/runtime/sqliteToolStore.d.ts +30 -0
  481. package/build/lib/core/runtime/testfixtures/localWorkerChild.d.ts +1 -0
  482. package/build/lib/core/runtime/testfixtures/localWorkerLauncher.d.ts +1 -0
  483. package/build/lib/core/runtime/testfixtures/recoveryChild.d.ts +1 -0
  484. package/build/lib/core/services/rateLimiter/index.d.ts +36 -0
  485. package/build/lib/core/services/rateLimiter/types.d.ts +10 -0
  486. package/build/lib/core/session/execution-metrics.d.ts +37 -0
  487. package/build/lib/core/session/index.d.ts +586 -0
  488. package/build/lib/core/session/index.js +36 -0
  489. package/build/lib/core/session/loader.d.ts +30 -0
  490. package/build/lib/core/session/persistence.d.ts +215 -0
  491. package/build/lib/core/session/persistence.js +35 -0
  492. package/build/lib/core/session/types.d.ts +59 -0
  493. package/build/lib/core/session/usage.d.ts +37 -0
  494. package/build/lib/core/skills/builtins/index.d.ts +13 -0
  495. package/build/lib/core/skills/builtins/pentest.d.ts +19 -0
  496. package/build/lib/core/skills/builtins/promptInjection.d.ts +2 -0
  497. package/build/lib/core/skills/builtins/threatModel.d.ts +11 -0
  498. package/build/lib/core/skills/index.d.ts +5 -0
  499. package/build/lib/core/skills/parser.d.ts +11 -0
  500. package/build/lib/core/skills/registry.d.ts +30 -0
  501. package/build/lib/core/skills/scanner.d.ts +12 -0
  502. package/build/lib/core/skills/types.d.ts +44 -0
  503. package/build/lib/core/skills/utils.d.ts +6 -0
  504. package/build/lib/core/storage/index.d.ts +248 -0
  505. package/build/lib/core/tasks/index.d.ts +78 -0
  506. package/build/lib/core/tools/backends/capture.d.ts +10 -0
  507. package/build/lib/core/tools/backends/collectCommand.d.ts +9 -0
  508. package/build/lib/core/tools/backends/helpers.d.ts +43 -0
  509. package/build/lib/core/tools/backends/httpTransport.d.ts +18 -0
  510. package/build/lib/core/tools/backends/index.d.ts +8 -0
  511. package/build/lib/core/tools/backends/index.js +31 -0
  512. package/build/lib/core/tools/backends/local.d.ts +11 -0
  513. package/build/lib/core/tools/backends/policy.d.ts +39 -0
  514. package/build/lib/core/tools/backends/resolve.d.ts +25 -0
  515. package/build/lib/core/tools/backends/types.d.ts +240 -0
  516. package/build/lib/core/tools/backends/whitebox.d.ts +6 -0
  517. package/build/lib/core/tools/backends/whiteboxJobs.d.ts +18 -0
  518. package/build/lib/core/tools/backends/windowsProgram.d.ts +4 -0
  519. package/build/lib/core/tools/daytonaSandbox.d.ts +14 -0
  520. package/build/lib/core/toolset/index.d.ts +28 -0
  521. package/build/lib/core/util/lazyLogger.d.ts +16 -0
  522. package/build/lib/core/utils/concurrency.d.ts +16 -0
  523. package/build/lib/core/utils/prompt.d.ts +12 -0
  524. package/build/lib/core/whitebox/adapters.d.ts +29 -0
  525. package/build/lib/core/whitebox/artifacts.d.ts +32 -0
  526. package/build/lib/core/whitebox/boundedProcess.d.ts +35 -0
  527. package/build/lib/core/whitebox/candidates.d.ts +29 -0
  528. package/build/lib/core/whitebox/catalog.d.ts +10 -0
  529. package/build/lib/core/whitebox/index.d.ts +9 -0
  530. package/build/lib/core/whitebox/jobKernel.d.ts +33 -0
  531. package/build/lib/core/whitebox/jobSupervisor.d.ts +14 -0
  532. package/build/lib/core/whitebox/jobs.d.ts +17 -0
  533. package/build/lib/core/whitebox/paths.d.ts +22 -0
  534. package/build/lib/core/whitebox/profileTransport.d.ts +10 -0
  535. package/build/lib/core/whitebox/profiles.d.ts +3 -0
  536. package/build/lib/core/whitebox/repoProfile.d.ts +4 -0
  537. package/build/lib/core/whitebox/types.d.ts +108 -0
  538. package/build/lib/core/workflows/fastStrike.d.ts +4 -0
  539. package/build/lib/core/workflows/pentest.d.ts +167 -0
  540. package/build/lib/core/workflows/pentest.js +42 -0
  541. package/build/lib/core/workflows/seams.d.ts +102 -0
  542. package/build/lib/core/workflows/seams.js +37 -0
  543. package/build/lib/core/workflows/threatModel.d.ts +26 -0
  544. package/build/lib/core/workflows/whiteboxAttackSurface.d.ts +142 -0
  545. package/build/lib/core/workflows/whiteboxAttackSurface.js +36 -0
  546. package/build/lib/index.d.ts +26 -0
  547. package/build/lib/index.js +96 -0
  548. package/build/lib/lib/attack-path/types.d.ts +9 -0
  549. package/build/lib/lib/cvss/calculator.d.ts +31 -0
  550. package/build/lib/lib/cvss/index.d.ts +24 -0
  551. package/build/lib/lib/cvss/index.js +24 -0
  552. package/build/lib/lib/cvss/macrovector-scores.d.ts +59 -0
  553. package/build/lib/lib/cvss/types.d.ts +114 -0
  554. package/build/lib/lib/cvss/types.js +8 -0
  555. package/build/lib/lib/cwe/cwe-catalog.d.ts +13 -0
  556. package/build/lib/lib/cwe/types.d.ts +28 -0
  557. package/build/lib/lib/cwe/validate.d.ts +15 -0
  558. package/build/lib/lib/evidence/types.d.ts +12 -0
  559. package/build/lib/util/errors.d.ts +186 -0
  560. package/build/lib/util/lock.d.ts +2 -0
  561. package/build/lib/util/name.d.ts +14 -0
  562. package/build/lib/util/url.d.ts +40 -0
  563. package/build/{logs-wzr5176k.js → logs-sxjgdzad.js} +22 -30
  564. package/build/{multipart-parser-g2xxkezz.js → multipart-parser-vjjdbpd1.js} +10 -10
  565. package/build/native-rollout-evidence-4t42nfhm.js +135 -0
  566. package/build/offesecAgent-tjdbr5rj.js +22 -0
  567. package/build/{parse-rtccymzn.js → parse-cqecqrc5.js} +0 -4
  568. package/build/pentest-v7zcbdhw.js +22 -0
  569. package/build/pentests-g8mh9azr.js +143 -0
  570. package/build/recordedRunClient-2sf7b87c.js +11 -0
  571. package/build/{targetedPentest-tdwtgmxm.js → targetedPentest-ex9knnwy.js} +22 -22
  572. package/build/{targets-763n91t7.js → targets-m42t5xk9.js} +24 -32
  573. package/build/threatModel-anzm2xgv.js +21 -0
  574. package/build/{token-3bbp59y6.js → token-mk7t8y0y.js} +2 -2
  575. package/build/{token-util-6xjme11b.js → token-util-vd776hrv.js} +1 -2
  576. package/build/{uninstall-d33159cz.js → uninstall-ze0fj4q8.js} +3 -3
  577. package/build/{upload-9qj1kpt9.js → upload-dapb1553.js} +8 -14
  578. package/build/{utils-t7gc2903.js → utils-a91dn29f.js} +29 -29
  579. package/package.json +230 -5
  580. package/src/cli/agent-runs.attach.test.ts +359 -0
  581. package/src/cli/agent-runs.test.ts +1172 -0
  582. package/src/cli/agent-runs.ts +430 -0
  583. package/src/cli/apps.test.ts +63 -0
  584. package/src/cli/apps.ts +526 -0
  585. package/src/cli/auth.ts +375 -0
  586. package/src/cli/command-exit.test.ts +15 -0
  587. package/src/cli/command-exit.ts +3 -0
  588. package/src/cli/config.ts +210 -0
  589. package/src/cli/export-trajectory.test.ts +224 -0
  590. package/src/cli/export-trajectory.ts +119 -0
  591. package/src/cli/fixes.ts +56 -0
  592. package/src/cli/issues.test.ts +214 -0
  593. package/src/cli/issues.ts +242 -0
  594. package/src/cli/json-output.test.ts +62 -0
  595. package/src/cli/knowledge.test.ts +140 -0
  596. package/src/cli/knowledge.ts +146 -0
  597. package/src/cli/launcher.test.ts +81 -0
  598. package/src/cli/logs.ts +111 -0
  599. package/src/cli/native-rollout-evidence.test.ts +322 -0
  600. package/src/cli/native-rollout-evidence.ts +206 -0
  601. package/src/cli/pentests.test.ts +194 -0
  602. package/src/cli/pentests.ts +159 -0
  603. package/src/cli/resume.test.ts +107 -0
  604. package/src/cli/targets.ts +125 -0
  605. package/src/cli/uninstall.ts +302 -0
  606. package/src/cli.ts +882 -0
  607. package/src/core/agents/agentRuntime.test.ts +242 -0
  608. package/src/core/agents/agentRuntime.ts +120 -0
  609. package/src/core/agents/defineAgent.ts +134 -0
  610. package/src/core/agents/offSecAgent/index.ts +162 -0
  611. package/src/core/agents/offSecAgent/interruptedStepFinalization.test.ts +295 -0
  612. package/src/core/agents/offSecAgent/interruptedStepFinalization.ts +162 -0
  613. package/src/core/agents/offSecAgent/interruptedStepMessages.test.ts +296 -0
  614. package/src/core/agents/offSecAgent/interruptedStepMessages.ts +137 -0
  615. package/src/core/agents/offSecAgent/messagePersistence.test.ts +281 -0
  616. package/src/core/agents/offSecAgent/messagePersistence.ts +111 -0
  617. package/src/core/agents/offSecAgent/offensiveSecurityAgent.runtimeContext.test.ts +689 -0
  618. package/src/core/agents/offSecAgent/offensiveSecurityAgent.test.ts +2986 -0
  619. package/src/core/agents/offSecAgent/offensiveSecurityAgent.ts +1631 -0
  620. package/src/core/agents/offSecAgent/prompt.test.ts +72 -0
  621. package/src/core/agents/offSecAgent/prompt.ts +368 -0
  622. package/src/core/agents/offSecAgent/recordedTools.test.ts +580 -0
  623. package/src/core/agents/offSecAgent/recordedTools.ts +162 -0
  624. package/src/core/agents/offSecAgent/runtimeContext.test.ts +531 -0
  625. package/src/core/agents/offSecAgent/runtimeContext.ts +387 -0
  626. package/src/core/agents/offSecAgent/selectiveConstruction.publicPath.test.ts +295 -0
  627. package/src/core/agents/offSecAgent/selectiveConstruction.test.ts +498 -0
  628. package/src/core/agents/offSecAgent/streamDiagnostics.test.ts +310 -0
  629. package/src/core/agents/offSecAgent/streamDiagnostics.ts +237 -0
  630. package/src/core/agents/offSecAgent/subagentSpawner.hooks.test.ts +102 -0
  631. package/src/core/agents/offSecAgent/subagentSpawner.test.ts +384 -0
  632. package/src/core/agents/offSecAgent/subagentSpawner.ts +664 -0
  633. package/src/core/agents/offSecAgent/toolLifecycle.test.ts +199 -0
  634. package/src/core/agents/offSecAgent/toolLifecycle.ts +171 -0
  635. package/src/core/agents/offSecAgent/tools/__tests__/sandboxScript.ts +14 -0
  636. package/src/core/agents/offSecAgent/tools/addMemory.ts +87 -0
  637. package/src/core/agents/offSecAgent/tools/agentScratch.test.ts +36 -0
  638. package/src/core/agents/offSecAgent/tools/agentScratch.ts +23 -0
  639. package/src/core/agents/offSecAgent/tools/applyPatch.test.ts +546 -0
  640. package/src/core/agents/offSecAgent/tools/applyPatch.ts +58 -0
  641. package/src/core/agents/offSecAgent/tools/applyPatchImpl.ts +300 -0
  642. package/src/core/agents/offSecAgent/tools/askUserQuestions.ts +81 -0
  643. package/src/core/agents/offSecAgent/tools/authBackendStatus.test.ts +112 -0
  644. package/src/core/agents/offSecAgent/tools/browserHeaderRouting.test.ts +136 -0
  645. package/src/core/agents/offSecAgent/tools/browserHeaderRouting.ts +81 -0
  646. package/src/core/agents/offSecAgent/tools/browserToolFactories.ts +372 -0
  647. package/src/core/agents/offSecAgent/tools/browserTools.test.ts +243 -0
  648. package/src/core/agents/offSecAgent/tools/browserTools.ts +285 -0
  649. package/src/core/agents/offSecAgent/tools/callbackListener.test.ts +1011 -0
  650. package/src/core/agents/offSecAgent/tools/callbackListener.ts +1038 -0
  651. package/src/core/agents/offSecAgent/tools/camoufox.test.ts +119 -0
  652. package/src/core/agents/offSecAgent/tools/camoufox.ts +199 -0
  653. package/src/core/agents/offSecAgent/tools/checkpointState.ts +79 -0
  654. package/src/core/agents/offSecAgent/tools/codingTools.windows.test.ts +625 -0
  655. package/src/core/agents/offSecAgent/tools/completeAuthentication.ts +136 -0
  656. package/src/core/agents/offSecAgent/tools/crawlAuthenticated.test.ts +267 -0
  657. package/src/core/agents/offSecAgent/tools/crawlAuthenticated.ts +170 -0
  658. package/src/core/agents/offSecAgent/tools/createAttackSurfaceReport.ts +75 -0
  659. package/src/core/agents/offSecAgent/tools/createFile.test.ts +111 -0
  660. package/src/core/agents/offSecAgent/tools/createFile.ts +44 -0
  661. package/src/core/agents/offSecAgent/tools/createTask.ts +118 -0
  662. package/src/core/agents/offSecAgent/tools/delegateAuth.ts +391 -0
  663. package/src/core/agents/offSecAgent/tools/deleteFile.test.ts +102 -0
  664. package/src/core/agents/offSecAgent/tools/deleteFile.ts +39 -0
  665. package/src/core/agents/offSecAgent/tools/destructiveGuard.test.ts +827 -0
  666. package/src/core/agents/offSecAgent/tools/destructiveGuard.ts +747 -0
  667. package/src/core/agents/offSecAgent/tools/detectAuthScheme.ts +191 -0
  668. package/src/core/agents/offSecAgent/tools/documentApp.ts +242 -0
  669. package/src/core/agents/offSecAgent/tools/documentEndpoint.ts +291 -0
  670. package/src/core/agents/offSecAgent/tools/documentFinding.test.ts +2091 -0
  671. package/src/core/agents/offSecAgent/tools/documentFinding.ts +1240 -0
  672. package/src/core/agents/offSecAgent/tools/email/adapters.test.ts +279 -0
  673. package/src/core/agents/offSecAgent/tools/email/adapters.ts +1121 -0
  674. package/src/core/agents/offSecAgent/tools/email/getAttachments.ts +73 -0
  675. package/src/core/agents/offSecAgent/tools/email/getMessage.ts +56 -0
  676. package/src/core/agents/offSecAgent/tools/email/inboxBackend.test.ts +137 -0
  677. package/src/core/agents/offSecAgent/tools/email/index.ts +55 -0
  678. package/src/core/agents/offSecAgent/tools/email/listInboxes.ts +47 -0
  679. package/src/core/agents/offSecAgent/tools/email/listMessages.ts +67 -0
  680. package/src/core/agents/offSecAgent/tools/email/markRead.ts +57 -0
  681. package/src/core/agents/offSecAgent/tools/email/searchMessages.ts +76 -0
  682. package/src/core/agents/offSecAgent/tools/email/sendEmail.ts +165 -0
  683. package/src/core/agents/offSecAgent/tools/email/types.ts +45 -0
  684. package/src/core/agents/offSecAgent/tools/executeCommand.backends.test.ts +171 -0
  685. package/src/core/agents/offSecAgent/tools/executeCommand.test.ts +1153 -0
  686. package/src/core/agents/offSecAgent/tools/executeCommand.ts +604 -0
  687. package/src/core/agents/offSecAgent/tools/extractJsEndpoints.ts +44 -0
  688. package/src/core/agents/offSecAgent/tools/fileBackends.test.ts +66 -0
  689. package/src/core/agents/offSecAgent/tools/fileMutations.test.ts +159 -0
  690. package/src/core/agents/offSecAgent/tools/fileToolBackendPurity.test.ts +72 -0
  691. package/src/core/agents/offSecAgent/tools/fileWorkspace.test.ts +357 -0
  692. package/src/core/agents/offSecAgent/tools/fileWorkspace.ts +434 -0
  693. package/src/core/agents/offSecAgent/tools/fileWorkspaceRemote.ts +263 -0
  694. package/src/core/agents/offSecAgent/tools/getMemory.ts +69 -0
  695. package/src/core/agents/offSecAgent/tools/getPage.test.ts +1127 -0
  696. package/src/core/agents/offSecAgent/tools/getPage.ts +70 -0
  697. package/src/core/agents/offSecAgent/tools/gitDiff.ts +67 -0
  698. package/src/core/agents/offSecAgent/tools/gitStatus.ts +61 -0
  699. package/src/core/agents/offSecAgent/tools/gitTools.test.ts +237 -0
  700. package/src/core/agents/offSecAgent/tools/glob.test.ts +695 -0
  701. package/src/core/agents/offSecAgent/tools/glob.ts +51 -0
  702. package/src/core/agents/offSecAgent/tools/globImpl.ts +313 -0
  703. package/src/core/agents/offSecAgent/tools/globPattern.ts +203 -0
  704. package/src/core/agents/offSecAgent/tools/grep.test.ts +922 -0
  705. package/src/core/agents/offSecAgent/tools/grep.ts +73 -0
  706. package/src/core/agents/offSecAgent/tools/grepImpl.ts +718 -0
  707. package/src/core/agents/offSecAgent/tools/httpBackends.test.ts +534 -0
  708. package/src/core/agents/offSecAgent/tools/httpRequest.test.ts +2409 -0
  709. package/src/core/agents/offSecAgent/tools/httpRequest.ts +425 -0
  710. package/src/core/agents/offSecAgent/tools/index.ts +787 -0
  711. package/src/core/agents/offSecAgent/tools/listFiles.bounded.test.ts +514 -0
  712. package/src/core/agents/offSecAgent/tools/listFiles.public-counters.test.ts +163 -0
  713. package/src/core/agents/offSecAgent/tools/listFiles.test.ts +521 -0
  714. package/src/core/agents/offSecAgent/tools/listFiles.ts +49 -0
  715. package/src/core/agents/offSecAgent/tools/listFilesImpl.ts +351 -0
  716. package/src/core/agents/offSecAgent/tools/listMemories.test.ts +230 -0
  717. package/src/core/agents/offSecAgent/tools/listMemories.ts +138 -0
  718. package/src/core/agents/offSecAgent/tools/listPromptInjections.test.ts +201 -0
  719. package/src/core/agents/offSecAgent/tools/listPromptInjections.ts +78 -0
  720. package/src/core/agents/offSecAgent/tools/listTasks.ts +100 -0
  721. package/src/core/agents/offSecAgent/tools/patchApply.test.ts +573 -0
  722. package/src/core/agents/offSecAgent/tools/patchApply.ts +430 -0
  723. package/src/core/agents/offSecAgent/tools/patchParse.test.ts +383 -0
  724. package/src/core/agents/offSecAgent/tools/patchParse.ts +354 -0
  725. package/src/core/agents/offSecAgent/tools/perCommandShell.drain.test.ts +109 -0
  726. package/src/core/agents/offSecAgent/tools/perCommandShell.test.ts +565 -0
  727. package/src/core/agents/offSecAgent/tools/perCommandShell.ts +516 -0
  728. package/src/core/agents/offSecAgent/tools/perCommandShell.windows.test.ts +142 -0
  729. package/src/core/agents/offSecAgent/tools/playwrightMcp.test.ts +778 -0
  730. package/src/core/agents/offSecAgent/tools/playwrightMcp.ts +1426 -0
  731. package/src/core/agents/offSecAgent/tools/probeAuthEndpoints.ts +262 -0
  732. package/src/core/agents/offSecAgent/tools/profileCodebase.ts +110 -0
  733. package/src/core/agents/offSecAgent/tools/provideComparisonResults.ts +106 -0
  734. package/src/core/agents/offSecAgent/tools/queryWhiteboxCatalog.coalescing-cost.test.ts +108 -0
  735. package/src/core/agents/offSecAgent/tools/queryWhiteboxCatalog.test.ts +183 -0
  736. package/src/core/agents/offSecAgent/tools/queryWhiteboxCatalog.ts +143 -0
  737. package/src/core/agents/offSecAgent/tools/readFile.test.ts +1242 -0
  738. package/src/core/agents/offSecAgent/tools/readFile.ts +89 -0
  739. package/src/core/agents/offSecAgent/tools/readFileImpl.ts +956 -0
  740. package/src/core/agents/offSecAgent/tools/readSkill.ts +38 -0
  741. package/src/core/agents/offSecAgent/tools/reportError.test.ts +48 -0
  742. package/src/core/agents/offSecAgent/tools/reportError.ts +65 -0
  743. package/src/core/agents/offSecAgent/tools/response.ts +27 -0
  744. package/src/core/agents/offSecAgent/tools/runAttackSurface.ts +198 -0
  745. package/src/core/agents/offSecAgent/tools/runCodeQuery.test.ts +82 -0
  746. package/src/core/agents/offSecAgent/tools/runCodeQuery.ts +237 -0
  747. package/src/core/agents/offSecAgent/tools/runPentestWorkflow.ts +122 -0
  748. package/src/core/agents/offSecAgent/tools/runWhiteboxScan.ts +189 -0
  749. package/src/core/agents/offSecAgent/tools/runtimeBackendConsumers.test.ts +143 -0
  750. package/src/core/agents/offSecAgent/tools/sandbox.ts +37 -0
  751. package/src/core/agents/offSecAgent/tools/sandboxPlaywright.test.ts +235 -0
  752. package/src/core/agents/offSecAgent/tools/sandboxPlaywright.ts +1029 -0
  753. package/src/core/agents/offSecAgent/tools/sandboxScript.test.ts +31 -0
  754. package/src/core/agents/offSecAgent/tools/sandboxScript.ts +60 -0
  755. package/src/core/agents/offSecAgent/tools/scopeGuard.test.ts +574 -0
  756. package/src/core/agents/offSecAgent/tools/scopeGuard.ts +317 -0
  757. package/src/core/agents/offSecAgent/tools/scriptSyntaxCheck.test.ts +566 -0
  758. package/src/core/agents/offSecAgent/tools/scriptSyntaxCheck.ts +240 -0
  759. package/src/core/agents/offSecAgent/tools/selectiveFactories.test.ts +476 -0
  760. package/src/core/agents/offSecAgent/tools/smsInbox.ts +130 -0
  761. package/src/core/agents/offSecAgent/tools/smsListMessages.test.ts +443 -0
  762. package/src/core/agents/offSecAgent/tools/smsListMessages.ts +123 -0
  763. package/src/core/agents/offSecAgent/tools/spawnCodingAgent.ts +229 -0
  764. package/src/core/agents/offSecAgent/tools/spawnPentestAgent.test.ts +413 -0
  765. package/src/core/agents/offSecAgent/tools/spawnPentestAgent.ts +266 -0
  766. package/src/core/agents/offSecAgent/tools/spawnPentestSwarm.ts +146 -0
  767. package/src/core/agents/offSecAgent/tools/submitPlan.ts +51 -0
  768. package/src/core/agents/offSecAgent/tools/testEndpointVariations.ts +127 -0
  769. package/src/core/agents/offSecAgent/tools/threatModelGenerator.ts +664 -0
  770. package/src/core/agents/offSecAgent/tools/toolOutput.test.ts +480 -0
  771. package/src/core/agents/offSecAgent/tools/toolOutput.ts +160 -0
  772. package/src/core/agents/offSecAgent/tools/types.ts +267 -0
  773. package/src/core/agents/offSecAgent/tools/updateFile.ts +121 -0
  774. package/src/core/agents/offSecAgent/tools/updateTask.ts +107 -0
  775. package/src/core/agents/offSecAgent/tools/validateDiscovery.ts +123 -0
  776. package/src/core/agents/offSecAgent/tools/webSearch.ts +265 -0
  777. package/src/core/agents/offSecAgent/tools/whiteboxCandidates.ts +197 -0
  778. package/src/core/agents/offSecAgent/tools/whiteboxJobs.ts +312 -0
  779. package/src/core/agents/offSecAgent/tools/windowsCurl.test.ts +801 -0
  780. package/src/core/agents/offSecAgent/tools/windowsCurl.ts +202 -0
  781. package/src/core/agents/offSecAgent/tools/workspaceApps.test.ts +257 -0
  782. package/src/core/agents/offSecAgent/tools/workspaceApps.ts +334 -0
  783. package/src/core/agents/offSecAgent/tools/workspaceDomains.test.ts +113 -0
  784. package/src/core/agents/offSecAgent/tools/workspaceDomains.ts +57 -0
  785. package/src/core/agents/offSecAgent/tools/workspaceFailure.ts +11 -0
  786. package/src/core/agents/offSecAgent/tools/writePlan.ts +65 -0
  787. package/src/core/agents/offSecAgent/trace.test.ts +796 -0
  788. package/src/core/agents/offSecAgent/trace.ts +633 -0
  789. package/src/core/agents/offSecAgent/types.test.ts +224 -0
  790. package/src/core/agents/offSecAgent/types.ts +676 -0
  791. package/src/core/agents/specialized/attackSurface/blackboxAgent.test.ts +31 -0
  792. package/src/core/agents/specialized/attackSurface/blackboxAgent.ts +272 -0
  793. package/src/core/agents/specialized/attackSurface/blackboxRiskScoring.ts +276 -0
  794. package/src/core/agents/specialized/attackSurface/grpcSchema.ts +142 -0
  795. package/src/core/agents/specialized/attackSurface/jsExtraction.test.ts +237 -0
  796. package/src/core/agents/specialized/attackSurface/jsExtraction.ts +174 -0
  797. package/src/core/agents/specialized/attackSurface/prompts.ts +349 -0
  798. package/src/core/agents/specialized/attackSurface/schemas.ts +300 -0
  799. package/src/core/agents/specialized/attackSurface/types.ts +100 -0
  800. package/src/core/agents/specialized/authenticationAgent/agent.test.ts +111 -0
  801. package/src/core/agents/specialized/authenticationAgent/agent.ts +300 -0
  802. package/src/core/agents/specialized/authenticationAgent/index.ts +74 -0
  803. package/src/core/agents/specialized/authenticationAgent/prompts.test.ts +36 -0
  804. package/src/core/agents/specialized/authenticationAgent/prompts.ts +645 -0
  805. package/src/core/agents/specialized/authenticationAgent/types.ts +833 -0
  806. package/src/core/agents/specialized/benchmark/comparisonAgent.ts +344 -0
  807. package/src/core/agents/specialized/benchmark/docker-utils.ts +257 -0
  808. package/src/core/agents/specialized/benchmark/flag-detector.ts +686 -0
  809. package/src/core/agents/specialized/benchmark/index.ts +28 -0
  810. package/src/core/agents/specialized/benchmark/prompts.ts +257 -0
  811. package/src/core/agents/specialized/benchmark/remote/circuit-breaker.ts +108 -0
  812. package/src/core/agents/specialized/benchmark/remote/daytona-wrapper.ts +1005 -0
  813. package/src/core/agents/specialized/benchmark/remote/index.ts +2 -0
  814. package/src/core/agents/specialized/benchmark/types.ts +98 -0
  815. package/src/core/agents/specialized/benchmarkComparisonAgent.test.ts +111 -0
  816. package/src/core/agents/specialized/benchmarkComparisonAgent.ts +203 -0
  817. package/src/core/agents/specialized/codeAgent/agent.test.ts +89 -0
  818. package/src/core/agents/specialized/codeAgent/agent.ts +134 -0
  819. package/src/core/agents/specialized/codeAgent/prompts.ts +48 -0
  820. package/src/core/agents/specialized/codeAgent/schemas.ts +33 -0
  821. package/src/core/agents/specialized/cvssScorer/index.test.ts +87 -0
  822. package/src/core/agents/specialized/cvssScorer/index.ts +546 -0
  823. package/src/core/agents/specialized/environment/agent.ts +75 -0
  824. package/src/core/agents/specialized/environment/index.ts +16 -0
  825. package/src/core/agents/specialized/environment/prompts.ts +194 -0
  826. package/src/core/agents/specialized/environment/types.ts +48 -0
  827. package/src/core/agents/specialized/findingJudge/agent.test.ts +114 -0
  828. package/src/core/agents/specialized/findingJudge/agent.ts +59 -0
  829. package/src/core/agents/specialized/findingJudge/index.test.ts +155 -0
  830. package/src/core/agents/specialized/findingJudge/index.ts +166 -0
  831. package/src/core/agents/specialized/findingJudge/prompts.ts +140 -0
  832. package/src/core/agents/specialized/findingJudge/types.ts +115 -0
  833. package/src/core/agents/specialized/googleSignInPrompt.test.ts +29 -0
  834. package/src/core/agents/specialized/googleSignInPrompt.ts +18 -0
  835. package/src/core/agents/specialized/mobileOtpPrompt.ts +9 -0
  836. package/src/core/agents/specialized/patching/agent.test.ts +220 -0
  837. package/src/core/agents/specialized/patching/agent.ts +146 -0
  838. package/src/core/agents/specialized/patching/index.ts +20 -0
  839. package/src/core/agents/specialized/patching/prompts.test.ts +172 -0
  840. package/src/core/agents/specialized/patching/prompts.ts +396 -0
  841. package/src/core/agents/specialized/patching/types.ts +49 -0
  842. package/src/core/agents/specialized/pentest/agent.test.ts +1046 -0
  843. package/src/core/agents/specialized/pentest/agent.ts +1482 -0
  844. package/src/core/agents/specialized/pentest/helperLifecycle.test.ts +425 -0
  845. package/src/core/agents/specialized/pentest/helperWorkspace.test.ts +84 -0
  846. package/src/core/agents/specialized/pentest/helperWorkspace.ts +33 -0
  847. package/src/core/agents/specialized/pentest/planPrompt.ts +68 -0
  848. package/src/core/agents/specialized/pentest/results.test.ts +198 -0
  849. package/src/core/agents/specialized/utils.test.ts +16 -0
  850. package/src/core/agents/specialized/utils.ts +28 -0
  851. package/src/core/agents/specialized/vulnerabilityReproduction/agent.test.ts +195 -0
  852. package/src/core/agents/specialized/vulnerabilityReproduction/agent.ts +159 -0
  853. package/src/core/agents/specialized/whiteboxAttackSurface/agent.test.ts +39 -0
  854. package/src/core/agents/specialized/whiteboxAttackSurface/agent.ts +227 -0
  855. package/src/core/agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent.concurrency.test.ts +138 -0
  856. package/src/core/agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent.test.ts +199 -0
  857. package/src/core/agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent.ts +330 -0
  858. package/src/core/agents/specialized/whiteboxAttackSurface/index.ts +24 -0
  859. package/src/core/agents/specialized/whiteboxAttackSurface/prompts.ts +345 -0
  860. package/src/core/agents/specialized/whiteboxAttackSurface/types.test.ts +67 -0
  861. package/src/core/agents/specialized/whiteboxAttackSurface/types.ts +234 -0
  862. package/src/core/ai/ai.contract.test.ts +43 -0
  863. package/src/core/ai/ai.durability-hooks.test.ts +527 -0
  864. package/src/core/ai/ai.effective-tools.test.ts +739 -0
  865. package/src/core/ai/ai.native-rollout-evidence.test.ts +373 -0
  866. package/src/core/ai/ai.operator-context.bench.test.ts +1408 -0
  867. package/src/core/ai/ai.outer-catch-recovery.test.ts +82 -0
  868. package/src/core/ai/ai.proactive-recovery.test.ts +69 -0
  869. package/src/core/ai/ai.recorded-attempts.test.ts +621 -0
  870. package/src/core/ai/ai.recorded-context.test.ts +522 -0
  871. package/src/core/ai/ai.recorded-tools.test.ts +850 -0
  872. package/src/core/ai/ai.request-retention.test.ts +296 -0
  873. package/src/core/ai/ai.test.ts +690 -0
  874. package/src/core/ai/ai.ts +2568 -0
  875. package/src/core/ai/caching.test.ts +179 -0
  876. package/src/core/ai/caching.ts +119 -0
  877. package/src/core/ai/compactionEvidence.test.ts +52 -0
  878. package/src/core/ai/compactionEvidence.ts +101 -0
  879. package/src/core/ai/compactionTelemetry.test.ts +621 -0
  880. package/src/core/ai/compactionTelemetry.ts +287 -0
  881. package/src/core/ai/concentrate.test.ts +28 -0
  882. package/src/core/ai/contextManagement.test.ts +350 -0
  883. package/src/core/ai/contextManagement.ts +594 -0
  884. package/src/core/ai/index.ts +73 -0
  885. package/src/core/ai/inference-attempt/adapters.test.ts +84 -0
  886. package/src/core/ai/inference-attempt/adapters.ts +391 -0
  887. package/src/core/ai/inference-attempt/attempt.test.ts +198 -0
  888. package/src/core/ai/inference-attempt/builder.ts +171 -0
  889. package/src/core/ai/inference-attempt/envelope.ts +120 -0
  890. package/src/core/ai/inference-attempt/errors.ts +15 -0
  891. package/src/core/ai/inference-attempt/fixtures/anthropic-messages-cache-create.json +18 -0
  892. package/src/core/ai/inference-attempt/fixtures/anthropic-messages-cache-read.json +18 -0
  893. package/src/core/ai/inference-attempt/fixtures/anthropic-messages-incomplete.json +16 -0
  894. package/src/core/ai/inference-attempt/fixtures/anthropic-messages-mixed.json +22 -0
  895. package/src/core/ai/inference-attempt/fixtures/anthropic-messages-non-cache.json +26 -0
  896. package/src/core/ai/inference-attempt/fixtures/bedrock-converse-cache-create.json +18 -0
  897. package/src/core/ai/inference-attempt/fixtures/bedrock-converse-cache-read.json +26 -0
  898. package/src/core/ai/inference-attempt/fixtures/bedrock-converse-incomplete.json +19 -0
  899. package/src/core/ai/inference-attempt/fixtures/bedrock-converse-mixed.json +20 -0
  900. package/src/core/ai/inference-attempt/fixtures/bedrock-converse-non-cache.json +24 -0
  901. package/src/core/ai/inference-attempt/fixtures/openai-responses-cache-read.json +17 -0
  902. package/src/core/ai/inference-attempt/fixtures/openai-responses-incomplete.json +16 -0
  903. package/src/core/ai/inference-attempt/fixtures/openai-responses-non-cache.json +23 -0
  904. package/src/core/ai/inference-attempt/fixtures/pensar-anthropic-rest-incomplete.json +21 -0
  905. package/src/core/ai/inference-attempt/fixtures/pensar-anthropic-rest-native.json +16 -0
  906. package/src/core/ai/inference-attempt/fixtures/pensar-anthropic-stream-cache-create.json +20 -0
  907. package/src/core/ai/inference-attempt/fixtures/pensar-anthropic-stream-cache-read.json +20 -0
  908. package/src/core/ai/inference-attempt/fixtures/pensar-anthropic-stream-incomplete.json +16 -0
  909. package/src/core/ai/inference-attempt/fixtures/pensar-anthropic-stream-mixed.json +21 -0
  910. package/src/core/ai/inference-attempt/fixtures/pensar-anthropic-stream-non-cache.json +19 -0
  911. package/src/core/ai/inference-attempt/fixtures/reject-cache-read-exceeds-inclusive.json +11 -0
  912. package/src/core/ai/inference-attempt/fixtures/reject-components-exceed-inclusive.json +12 -0
  913. package/src/core/ai/inference-attempt/fixtures/reject-identity-mismatch.json +13 -0
  914. package/src/core/ai/inference-attempt/fixtures/reject-negative-token.json +9 -0
  915. package/src/core/ai/inference-attempt/fixtures/reject-non-integer-token.json +8 -0
  916. package/src/core/ai/inference-attempt/fixtures/sdk-normalized-cache-read.json +19 -0
  917. package/src/core/ai/inference-attempt/fixtures/sdk-normalized-incomplete.json +15 -0
  918. package/src/core/ai/inference-attempt/fixtures/sdk-normalized-mixed.json +20 -0
  919. package/src/core/ai/inference-attempt/fixtures/sdk-normalized-non-cache.json +16 -0
  920. package/src/core/ai/inference-attempt/identity.ts +25 -0
  921. package/src/core/ai/inference-attempt/index.ts +70 -0
  922. package/src/core/ai/inference-attempt/project.test.ts +118 -0
  923. package/src/core/ai/inference-attempt/project.ts +60 -0
  924. package/src/core/ai/inference-attempt/recording.ts +46 -0
  925. package/src/core/ai/inference-attempt/tokens.ts +165 -0
  926. package/src/core/ai/inference-attempt/validate.ts +20 -0
  927. package/src/core/ai/mantle.test.ts +50 -0
  928. package/src/core/ai/mantle.ts +45 -0
  929. package/src/core/ai/model-history.test.ts +53 -0
  930. package/src/core/ai/model-history.ts +38 -0
  931. package/src/core/ai/models/anthropic.ts +151 -0
  932. package/src/core/ai/models/bedrock.ts +618 -0
  933. package/src/core/ai/models/claude-capabilities.ts +43 -0
  934. package/src/core/ai/models/concentrate.ts +192 -0
  935. package/src/core/ai/models/google.ts +154 -0
  936. package/src/core/ai/models/inception.ts +10 -0
  937. package/src/core/ai/models/index.ts +253 -0
  938. package/src/core/ai/models/mantle.ts +14 -0
  939. package/src/core/ai/models/models.test.ts +313 -0
  940. package/src/core/ai/models/openai.ts +409 -0
  941. package/src/core/ai/models/openrouter.ts +342 -0
  942. package/src/core/ai/models/pensar.ts +66 -0
  943. package/src/core/ai/native-rollout-evidence/capture.test.ts +1836 -0
  944. package/src/core/ai/native-rollout-evidence/capture.ts +1572 -0
  945. package/src/core/ai/native-rollout-evidence/content.test.ts +55 -0
  946. package/src/core/ai/native-rollout-evidence/content.ts +129 -0
  947. package/src/core/ai/native-rollout-evidence/index.ts +68 -0
  948. package/src/core/ai/native-rollout-evidence/provider-metadata.test.ts +85 -0
  949. package/src/core/ai/native-rollout-evidence/provider-metadata.ts +129 -0
  950. package/src/core/ai/native-rollout-evidence/recording.test.ts +398 -0
  951. package/src/core/ai/native-rollout-evidence/schema.test.ts +210 -0
  952. package/src/core/ai/native-rollout-evidence/schema.ts +353 -0
  953. package/src/core/ai/native-rollout-evidence/validate.ts +141 -0
  954. package/src/core/ai/providers/anthropic-models.test.ts +348 -0
  955. package/src/core/ai/providers/anthropic.ts +73 -0
  956. package/src/core/ai/providers/bedrock-models.test.ts +81 -0
  957. package/src/core/ai/providers/concentrate.live.test.ts +71 -0
  958. package/src/core/ai/providers/concentrate.test.ts +160 -0
  959. package/src/core/ai/providers/concentrate.ts +145 -0
  960. package/src/core/ai/providers/custom.live.test.ts +42 -0
  961. package/src/core/ai/providers/custom.test.ts +474 -0
  962. package/src/core/ai/providers/custom.ts +70 -0
  963. package/src/core/ai/providers/gateway-models.test.ts +648 -0
  964. package/src/core/ai/providers/hoonify.live.test.ts +72 -0
  965. package/src/core/ai/providers/hoonify.test.ts +284 -0
  966. package/src/core/ai/providers/hoonify.ts +32 -0
  967. package/src/core/ai/providers/openai-models.test.ts +356 -0
  968. package/src/core/ai/providers/openai-pro-fetch.test.ts +64 -0
  969. package/src/core/ai/providers/openai-pro-fetch.ts +32 -0
  970. package/src/core/ai/providers/pensar.ts +645 -0
  971. package/src/core/ai/providers/pensarFormatters.test.ts +272 -0
  972. package/src/core/ai/providers/pensarFormatters.ts +533 -0
  973. package/src/core/ai/providers/pensarResponsesStream.test.ts +191 -0
  974. package/src/core/ai/providers/pensarResponsesStream.ts +294 -0
  975. package/src/core/ai/providers/pensarSSE.test.ts +83 -0
  976. package/src/core/ai/providers/pensarSSE.ts +128 -0
  977. package/src/core/ai/providers/pensarSigning.ts +2 -0
  978. package/src/core/ai/providers/pensarStreamUsage.test.ts +79 -0
  979. package/src/core/ai/providers/pensarStreamUsage.ts +62 -0
  980. package/src/core/ai/stepContext.test.ts +61 -0
  981. package/src/core/ai/streamIdleTimeout.test.ts +390 -0
  982. package/src/core/ai/streamTelemetry.ts +90 -0
  983. package/src/core/ai/usage-callback.test.ts +511 -0
  984. package/src/core/ai/utils.native-rollout-evidence.test.ts +136 -0
  985. package/src/core/ai/utils.pensar.test.ts +59 -0
  986. package/src/core/ai/utils.ts +842 -0
  987. package/src/core/api/apiClient.test.ts +58 -0
  988. package/src/core/api/apiClient.ts +73 -0
  989. package/src/core/api/apps.test.ts +78 -0
  990. package/src/core/api/apps.ts +388 -0
  991. package/src/core/api/attackSurface.test.ts +24 -0
  992. package/src/core/api/attackSurface.ts +89 -0
  993. package/src/core/api/authentication.ts +8 -0
  994. package/src/core/api/benchmark.ts +35 -0
  995. package/src/core/api/blackboxPentest.test.ts +89 -0
  996. package/src/core/api/blackboxPentest.ts +64 -0
  997. package/src/core/api/clientIdentity.test.ts +61 -0
  998. package/src/core/api/clientIdentity.ts +57 -0
  999. package/src/core/api/comments.test.ts +69 -0
  1000. package/src/core/api/constants.ts +15 -0
  1001. package/src/core/api/domains.test.ts +35 -0
  1002. package/src/core/api/domains.ts +32 -0
  1003. package/src/core/api/environment.ts +47 -0
  1004. package/src/core/api/index.ts +219 -0
  1005. package/src/core/api/issues.test.ts +82 -0
  1006. package/src/core/api/issues.ts +439 -0
  1007. package/src/core/api/knowledge.ts +70 -0
  1008. package/src/core/api/localWorker.ts +29 -0
  1009. package/src/core/api/offesecAgent.test.ts +289 -0
  1010. package/src/core/api/offesecAgent.ts +77 -0
  1011. package/src/core/api/patching.ts +44 -0
  1012. package/src/core/api/recordedRun.control.test.ts +830 -0
  1013. package/src/core/api/recordedRun.inference.test.ts +529 -0
  1014. package/src/core/api/recordedRun.loop.test.ts +290 -0
  1015. package/src/core/api/recordedRun.recovery.test.ts +651 -0
  1016. package/src/core/api/recordedRun.test.ts +646 -0
  1017. package/src/core/api/recordedRun.ts +542 -0
  1018. package/src/core/api/targetedPentest.test.ts +177 -0
  1019. package/src/core/api/targetedPentest.ts +83 -0
  1020. package/src/core/api/threatModel.ts +5 -0
  1021. package/src/core/api/trajectoryExport.test.ts +299 -0
  1022. package/src/core/api/trajectoryExport.ts +362 -0
  1023. package/src/core/api/vulnerabilityReproduction.test.ts +56 -0
  1024. package/src/core/api/vulnerabilityReproduction.ts +54 -0
  1025. package/src/core/assets/wordlists.test.ts +85 -0
  1026. package/src/core/assets/wordlists.ts +111 -0
  1027. package/src/core/atif/compatibility.test.ts +107 -0
  1028. package/src/core/atif/convert.test.ts +815 -0
  1029. package/src/core/atif/convert.ts +1658 -0
  1030. package/src/core/atif/fixtures/portable-bundle-v1.json +813 -0
  1031. package/src/core/atif/index.ts +34 -0
  1032. package/src/core/atif/schema.ts +345 -0
  1033. package/src/core/atif/serialize.test.ts +244 -0
  1034. package/src/core/atif/serialize.ts +419 -0
  1035. package/src/core/atif/test-fixtures.ts +184 -0
  1036. package/src/core/atif/validate.test.ts +188 -0
  1037. package/src/core/atif/validate.ts +289 -0
  1038. package/src/core/auth/connection.ts +26 -0
  1039. package/src/core/auth/device-flow.ts +203 -0
  1040. package/src/core/auth/gateway.ts +66 -0
  1041. package/src/core/auth/index.ts +29 -0
  1042. package/src/core/auth/signing.ts +25 -0
  1043. package/src/core/auth/token.ts +140 -0
  1044. package/src/core/auth/types.ts +106 -0
  1045. package/src/core/auth/workspaces.ts +192 -0
  1046. package/src/core/benchmark/index.ts +11 -0
  1047. package/src/core/benchmark/report.ts +257 -0
  1048. package/src/core/benchmark/runner.ts +698 -0
  1049. package/src/core/benchmark/types.ts +80 -0
  1050. package/src/core/cli/logLevelArgs.test.ts +83 -0
  1051. package/src/core/cli/logLevelArgs.ts +62 -0
  1052. package/src/core/cli/model.ts +35 -0
  1053. package/src/core/cli/pentestMode.test.ts +24 -0
  1054. package/src/core/cli/pentestMode.ts +23 -0
  1055. package/src/core/cli/tuiArgs.test.ts +58 -0
  1056. package/src/core/cli/tuiArgs.ts +28 -0
  1057. package/src/core/config/config.test.ts +183 -0
  1058. package/src/core/config/config.ts +201 -0
  1059. package/src/core/config/customProviders.test.ts +183 -0
  1060. package/src/core/config/customProviders.ts +190 -0
  1061. package/src/core/config/index.ts +7 -0
  1062. package/src/core/credentials/index.ts +6 -0
  1063. package/src/core/credentials/manager.ts +313 -0
  1064. package/src/core/credentials/types.ts +112 -0
  1065. package/src/core/doctor.ts +138 -0
  1066. package/src/core/eventBus.test.ts +374 -0
  1067. package/src/core/eventBus.ts +410 -0
  1068. package/src/core/findings/attackSurfaceRegistry.ts +294 -0
  1069. package/src/core/findings/registry.test.ts +1680 -0
  1070. package/src/core/findings/registry.ts +800 -0
  1071. package/src/core/history.ts +82 -0
  1072. package/src/core/hoonify.test.ts +250 -0
  1073. package/src/core/hoonify.ts +163 -0
  1074. package/src/core/http/headers.contract.test.ts +1161 -0
  1075. package/src/core/http/parse.ts +257 -0
  1076. package/src/core/http/redirects.test.ts +207 -0
  1077. package/src/core/http/redirects.ts +145 -0
  1078. package/src/core/http/targetHeaders.ts +604 -0
  1079. package/src/core/http/targetScope.ts +52 -0
  1080. package/src/core/http/types.ts +39 -0
  1081. package/src/core/id/id.test.ts +88 -0
  1082. package/src/core/id/id.ts +138 -0
  1083. package/src/core/installation/index.ts +222 -0
  1084. package/src/core/installation/installation.test.ts +415 -0
  1085. package/src/core/integrations/herdr.test.ts +335 -0
  1086. package/src/core/integrations/herdr.ts +163 -0
  1087. package/src/core/integrations/surface/index.test.ts +534 -0
  1088. package/src/core/integrations/surface/index.ts +224 -0
  1089. package/src/core/integrations/surface/types.ts +29 -0
  1090. package/src/core/integrations/wandb/client.ts +167 -0
  1091. package/src/core/integrations/wandb/upload.test.ts +415 -0
  1092. package/src/core/integrations/wandb/upload.ts +76 -0
  1093. package/src/core/logger/errorLog.test.ts +98 -0
  1094. package/src/core/logger/index.ts +214 -0
  1095. package/src/core/logger/structured.test.ts +212 -0
  1096. package/src/core/logger/structured.ts +207 -0
  1097. package/src/core/memory/backend.test.ts +186 -0
  1098. package/src/core/memory/index.ts +279 -0
  1099. package/src/core/memory/memory.test.ts +362 -0
  1100. package/src/core/messages/types.ts +141 -0
  1101. package/src/core/obfuscation/engine.test.ts +314 -0
  1102. package/src/core/obfuscation/engine.ts +647 -0
  1103. package/src/core/obfuscation/index.ts +27 -0
  1104. package/src/core/observability/active-root-spans.ts +30 -0
  1105. package/src/core/observability/active-spans.ts +80 -0
  1106. package/src/core/observability/index.ts +91 -0
  1107. package/src/core/observability/log-correlation.test.ts +276 -0
  1108. package/src/core/observability/payload-capture.test.ts +59 -0
  1109. package/src/core/observability/runtime.test.ts +743 -0
  1110. package/src/core/observability/runtime.ts +371 -0
  1111. package/src/core/observability/shutdown.test.ts +551 -0
  1112. package/src/core/observability/telemetry.test.ts +894 -0
  1113. package/src/core/observability/telemetry.ts +220 -0
  1114. package/src/core/observability/testkit.test.ts +66 -0
  1115. package/src/core/observability/testkit.ts +97 -0
  1116. package/src/core/observability/trace-contract.test.ts +1031 -0
  1117. package/src/core/observability.test.ts +135 -0
  1118. package/src/core/operator/approvalGate.test.ts +300 -0
  1119. package/src/core/operator/approvalGate.ts +287 -0
  1120. package/src/core/operator/index.ts +30 -0
  1121. package/src/core/operator/types.ts +355 -0
  1122. package/src/core/plan/index.ts +44 -0
  1123. package/src/core/prompt-injections/index.test.ts +248 -0
  1124. package/src/core/prompt-injections/index.ts +350 -0
  1125. package/src/core/providers/index.ts +5 -0
  1126. package/src/core/providers/types.ts +87 -0
  1127. package/src/core/providers/utils.test.ts +189 -0
  1128. package/src/core/providers/utils.ts +183 -0
  1129. package/src/core/providers/verify.test.ts +49 -0
  1130. package/src/core/providers/verify.ts +198 -0
  1131. package/src/core/report/builder.test.ts +229 -0
  1132. package/src/core/report/builder.ts +58 -0
  1133. package/src/core/report/index.ts +13 -0
  1134. package/src/core/report/renderers/json.test.ts +76 -0
  1135. package/src/core/report/renderers/json.ts +5 -0
  1136. package/src/core/report/renderers/markdown.test.ts +366 -0
  1137. package/src/core/report/renderers/markdown.ts +133 -0
  1138. package/src/core/report/schemas.ts +48 -0
  1139. package/src/core/runtime/agentExecution.test.ts +94 -0
  1140. package/src/core/runtime/agentExecution.ts +27 -0
  1141. package/src/core/runtime/launchLocalWorker.test.ts +707 -0
  1142. package/src/core/runtime/launchLocalWorker.ts +273 -0
  1143. package/src/core/runtime/localRunLock.ts +118 -0
  1144. package/src/core/runtime/localRunWorker.test.ts +381 -0
  1145. package/src/core/runtime/localRunWorker.ts +287 -0
  1146. package/src/core/runtime/localWorker.acceptance.test.ts +548 -0
  1147. package/src/core/runtime/localWorkerEndpoint.test.ts +145 -0
  1148. package/src/core/runtime/localWorkerEndpoint.ts +82 -0
  1149. package/src/core/runtime/localWorkerProtocol.ts +176 -0
  1150. package/src/core/runtime/localWorkerTransport.test.ts +841 -0
  1151. package/src/core/runtime/localWorkerTransport.ts +434 -0
  1152. package/src/core/runtime/persistenceError.ts +14 -0
  1153. package/src/core/runtime/recordedExecution.ts +43 -0
  1154. package/src/core/runtime/recordedRunClient.integration.test.ts +106 -0
  1155. package/src/core/runtime/recordedRunClient.test.ts +677 -0
  1156. package/src/core/runtime/recordedRunClient.ts +303 -0
  1157. package/src/core/runtime/runCheckpointStore.ts +23 -0
  1158. package/src/core/runtime/runContext.test.ts +445 -0
  1159. package/src/core/runtime/runContext.ts +184 -0
  1160. package/src/core/runtime/runControl.test.ts +923 -0
  1161. package/src/core/runtime/runControl.ts +419 -0
  1162. package/src/core/runtime/runControlStore.ts +106 -0
  1163. package/src/core/runtime/runDeadline.test.ts +44 -0
  1164. package/src/core/runtime/runDeadline.ts +28 -0
  1165. package/src/core/runtime/runEvidence.test.ts +384 -0
  1166. package/src/core/runtime/runEvidence.ts +267 -0
  1167. package/src/core/runtime/runInference.test.ts +408 -0
  1168. package/src/core/runtime/runInference.ts +125 -0
  1169. package/src/core/runtime/runModelStore.ts +55 -0
  1170. package/src/core/runtime/runObservation.ts +24 -0
  1171. package/src/core/runtime/runRecoveryContext.test.ts +602 -0
  1172. package/src/core/runtime/runRecoveryContext.ts +195 -0
  1173. package/src/core/runtime/runRecoveryPlan.test.ts +851 -0
  1174. package/src/core/runtime/runRecoveryPlan.ts +540 -0
  1175. package/src/core/runtime/runRecoveryStore.ts +78 -0
  1176. package/src/core/runtime/runStore.ts +148 -0
  1177. package/src/core/runtime/runStorePath.ts +13 -0
  1178. package/src/core/runtime/runToolStore.ts +66 -0
  1179. package/src/core/runtime/runTools.crash.test.ts +414 -0
  1180. package/src/core/runtime/runTools.test.ts +689 -0
  1181. package/src/core/runtime/runTools.ts +208 -0
  1182. package/src/core/runtime/sqliteControlStore.test.ts +917 -0
  1183. package/src/core/runtime/sqliteControlStore.ts +555 -0
  1184. package/src/core/runtime/sqliteModelStore.test.ts +619 -0
  1185. package/src/core/runtime/sqliteModelStore.ts +286 -0
  1186. package/src/core/runtime/sqliteRecoveryStore.public.test.ts +374 -0
  1187. package/src/core/runtime/sqliteRecoveryStore.test.ts +836 -0
  1188. package/src/core/runtime/sqliteRecoveryStore.ts +435 -0
  1189. package/src/core/runtime/sqliteRunContext.test.ts +1000 -0
  1190. package/src/core/runtime/sqliteRunObservation.test.ts +432 -0
  1191. package/src/core/runtime/sqliteRunStore.test.ts +698 -0
  1192. package/src/core/runtime/sqliteRunStore.ts +593 -0
  1193. package/src/core/runtime/sqliteToolStore.test.ts +1231 -0
  1194. package/src/core/runtime/sqliteToolStore.ts +419 -0
  1195. package/src/core/runtime/testfixtures/localWorkerChild.ts +254 -0
  1196. package/src/core/runtime/testfixtures/localWorkerLauncher.ts +15 -0
  1197. package/src/core/runtime/testfixtures/recoveryChild.ts +159 -0
  1198. package/src/core/services/rateLimiter/index.test.ts +106 -0
  1199. package/src/core/services/rateLimiter/index.ts +157 -0
  1200. package/src/core/services/rateLimiter/types.ts +10 -0
  1201. package/src/core/session/admitted-config.test.ts +50 -0
  1202. package/src/core/session/deprecated-headers-shim.test.ts +111 -0
  1203. package/src/core/session/execution-metrics.test.ts +297 -0
  1204. package/src/core/session/execution-metrics.ts +176 -0
  1205. package/src/core/session/index.ts +1085 -0
  1206. package/src/core/session/loader.ts +212 -0
  1207. package/src/core/session/persistence.test.ts +1210 -0
  1208. package/src/core/session/persistence.ts +1076 -0
  1209. package/src/core/session/rehydrate.test.ts +393 -0
  1210. package/src/core/session/types.ts +139 -0
  1211. package/src/core/session/usage.test.ts +99 -0
  1212. package/src/core/session/usage.ts +84 -0
  1213. package/src/core/skills/builtins/index.ts +22 -0
  1214. package/src/core/skills/builtins/pentest.ts +135 -0
  1215. package/src/core/skills/builtins/promptInjection.ts +44 -0
  1216. package/src/core/skills/builtins/threatModel.ts +336 -0
  1217. package/src/core/skills/index.ts +15 -0
  1218. package/src/core/skills/parser.test.ts +120 -0
  1219. package/src/core/skills/parser.ts +106 -0
  1220. package/src/core/skills/registry.test.ts +202 -0
  1221. package/src/core/skills/registry.ts +109 -0
  1222. package/src/core/skills/scanner.test.ts +157 -0
  1223. package/src/core/skills/scanner.ts +115 -0
  1224. package/src/core/skills/types.ts +45 -0
  1225. package/src/core/skills/utils.ts +16 -0
  1226. package/src/core/storage/index.ts +150 -0
  1227. package/src/core/tasks/index.ts +242 -0
  1228. package/src/core/tools/backends/capture.ts +38 -0
  1229. package/src/core/tools/backends/collectCommand.test.ts +33 -0
  1230. package/src/core/tools/backends/collectCommand.ts +28 -0
  1231. package/src/core/tools/backends/helpers.ts +140 -0
  1232. package/src/core/tools/backends/httpTransport.ts +534 -0
  1233. package/src/core/tools/backends/index.ts +61 -0
  1234. package/src/core/tools/backends/local.test.ts +307 -0
  1235. package/src/core/tools/backends/local.ts +820 -0
  1236. package/src/core/tools/backends/policy.test.ts +137 -0
  1237. package/src/core/tools/backends/policy.ts +129 -0
  1238. package/src/core/tools/backends/resolve.test.ts +309 -0
  1239. package/src/core/tools/backends/resolve.ts +152 -0
  1240. package/src/core/tools/backends/types.ts +279 -0
  1241. package/src/core/tools/backends/whitebox.test.ts +275 -0
  1242. package/src/core/tools/backends/whitebox.ts +14 -0
  1243. package/src/core/tools/backends/whiteboxJobs.test.ts +375 -0
  1244. package/src/core/tools/backends/whiteboxJobs.ts +157 -0
  1245. package/src/core/tools/backends/windowsProgram.ts +36 -0
  1246. package/src/core/tools/daytonaSandbox.test.ts +491 -0
  1247. package/src/core/tools/daytonaSandbox.ts +232 -0
  1248. package/src/core/toolset/index.ts +583 -0
  1249. package/src/core/util/lazyLogger.ts +32 -0
  1250. package/src/core/utils/concurrency.test.ts +204 -0
  1251. package/src/core/utils/concurrency.ts +75 -0
  1252. package/src/core/utils/prompt.ts +28 -0
  1253. package/src/core/whitebox/adapters.ts +277 -0
  1254. package/src/core/whitebox/artifacts.ts +128 -0
  1255. package/src/core/whitebox/boundedProcess.ts +265 -0
  1256. package/src/core/whitebox/candidates.ts +268 -0
  1257. package/src/core/whitebox/catalog.ts +82 -0
  1258. package/src/core/whitebox/index.ts +53 -0
  1259. package/src/core/whitebox/jobKernel.test.ts +91 -0
  1260. package/src/core/whitebox/jobKernel.ts +347 -0
  1261. package/src/core/whitebox/jobSupervisor.ts +264 -0
  1262. package/src/core/whitebox/jobs.ts +21 -0
  1263. package/src/core/whitebox/paths.ts +94 -0
  1264. package/src/core/whitebox/profileTransport.ts +225 -0
  1265. package/src/core/whitebox/profiles.ts +294 -0
  1266. package/src/core/whitebox/repoProfile.test.ts +217 -0
  1267. package/src/core/whitebox/repoProfile.ts +256 -0
  1268. package/src/core/whitebox/types.ts +189 -0
  1269. package/src/core/whitebox/whitebox.test.ts +789 -0
  1270. package/src/core/workflows/fastStrike.seams.test.ts +217 -0
  1271. package/src/core/workflows/fastStrike.test.ts +29 -0
  1272. package/src/core/workflows/fastStrike.ts +239 -0
  1273. package/src/core/workflows/pentest.test.ts +575 -0
  1274. package/src/core/workflows/pentest.ts +1022 -0
  1275. package/src/core/workflows/seams.test.ts +386 -0
  1276. package/src/core/workflows/seams.ts +276 -0
  1277. package/src/core/workflows/threatModel.ts +108 -0
  1278. package/src/core/workflows/usage-forwarding.test.ts +203 -0
  1279. package/src/core/workflows/whiteboxAttackSurface.test.ts +695 -0
  1280. package/src/core/workflows/whiteboxAttackSurface.ts +1740 -0
  1281. package/src/index.ts +49 -0
  1282. package/src/lib/attack-path/types.ts +13 -0
  1283. package/src/lib/cvss/calculator.test.ts +2090 -0
  1284. package/src/lib/cvss/calculator.ts +643 -0
  1285. package/src/lib/cvss/index.ts +65 -0
  1286. package/src/lib/cvss/macrovector-scores.ts +402 -0
  1287. package/src/lib/cvss/types.ts +241 -0
  1288. package/src/lib/cwe/cwe-catalog.ts +444 -0
  1289. package/src/lib/cwe/types.test.ts +142 -0
  1290. package/src/lib/cwe/types.ts +37 -0
  1291. package/src/lib/cwe/validate.test.ts +110 -0
  1292. package/src/lib/cwe/validate.ts +53 -0
  1293. package/src/lib/evidence/types.ts +9 -0
  1294. package/src/tests/agentWorkingDirectory.test.ts +175 -0
  1295. package/src/tests/attackSurface.test.ts +35 -0
  1296. package/src/tests/auth.test.ts +196 -0
  1297. package/src/tests/authCookieExport.test.ts +143 -0
  1298. package/src/tests/authPentestHandoff.test.ts +231 -0
  1299. package/src/tests/browserCookies.test.ts +128 -0
  1300. package/src/tests/credentialManager.test.ts +657 -0
  1301. package/src/tests/data/console.openapi.json +1037 -0
  1302. package/src/tests/data/console.sitemap.xml +348 -0
  1303. package/src/tests/delegateAuthMerge.test.ts +48 -0
  1304. package/src/tui/auto-copy.ts +36 -0
  1305. package/src/tui/clipboard.ts +65 -0
  1306. package/src/tui/command-registry.test.ts +124 -0
  1307. package/src/tui/command-registry.ts +645 -0
  1308. package/src/tui/command-router.ts +81 -0
  1309. package/src/tui/components/agent-display.tsx +480 -0
  1310. package/src/tui/components/ascii-art.tsx +225 -0
  1311. package/src/tui/components/chat/approval-inline.tsx +51 -0
  1312. package/src/tui/components/chat/config-view.tsx +279 -0
  1313. package/src/tui/components/chat/home-view.tsx +288 -0
  1314. package/src/tui/components/chat/index.tsx +161 -0
  1315. package/src/tui/components/chat/input-area.tsx +529 -0
  1316. package/src/tui/components/chat/lib/play-core/num.ts +102 -0
  1317. package/src/tui/components/chat/lib/wave-simulation.ts +124 -0
  1318. package/src/tui/components/chat/loading-indicator.test.ts +33 -0
  1319. package/src/tui/components/chat/loading-indicator.tsx +131 -0
  1320. package/src/tui/components/chat/message-list.tsx +265 -0
  1321. package/src/tui/components/chat/petri-animation.tsx +175 -0
  1322. package/src/tui/components/chat/plan-review-message.tsx +49 -0
  1323. package/src/tui/components/chat/questions-form.tsx +756 -0
  1324. package/src/tui/components/commands/__tests__/recorded-runs-lifecycle.tsx +907 -0
  1325. package/src/tui/components/commands/advanced-settings.tsx +94 -0
  1326. package/src/tui/components/commands/api-key-input.tsx +122 -0
  1327. package/src/tui/components/commands/auth-flow-logic.test.ts +58 -0
  1328. package/src/tui/components/commands/auth-flow-logic.ts +30 -0
  1329. package/src/tui/components/commands/auth-flow.tsx +702 -0
  1330. package/src/tui/components/commands/credits-flow.tsx +210 -0
  1331. package/src/tui/components/commands/help-dialog.tsx +238 -0
  1332. package/src/tui/components/commands/models-display.tsx +111 -0
  1333. package/src/tui/components/commands/operator-wizard.tsx +328 -0
  1334. package/src/tui/components/commands/provider-manager.tsx +241 -0
  1335. package/src/tui/components/commands/provider-selection.tsx +129 -0
  1336. package/src/tui/components/commands/recorded-runs.test.ts +40 -0
  1337. package/src/tui/components/commands/recorded-runs.tsx +793 -0
  1338. package/src/tui/components/commands/sessions-display.tsx +365 -0
  1339. package/src/tui/components/commands/shortcuts-dialog.tsx +52 -0
  1340. package/src/tui/components/commands/skills-dialog.tsx +308 -0
  1341. package/src/tui/components/commands/theme-picker.tsx +177 -0
  1342. package/src/tui/components/commands/web-wizard.tsx +965 -0
  1343. package/src/tui/components/dialog-layout.tsx +73 -0
  1344. package/src/tui/components/error-boundary.tsx +82 -0
  1345. package/src/tui/components/footer.tsx +101 -0
  1346. package/src/tui/components/input.tsx +43 -0
  1347. package/src/tui/components/loaders.tsx +784 -0
  1348. package/src/tui/components/model-picker/ModelPicker.tsx +907 -0
  1349. package/src/tui/components/model-picker/ModelPickerDialog.tsx +75 -0
  1350. package/src/tui/components/model-picker/index.ts +2 -0
  1351. package/src/tui/components/model-picker/model-navigation.test.ts +102 -0
  1352. package/src/tui/components/model-picker/model-navigation.ts +54 -0
  1353. package/src/tui/components/model-picker/model-search.test.ts +62 -0
  1354. package/src/tui/components/model-picker/model-search.ts +42 -0
  1355. package/src/tui/components/model-picker/model-visibility.test.ts +65 -0
  1356. package/src/tui/components/model-picker/model-visibility.ts +59 -0
  1357. package/src/tui/components/operator-dashboard/conversation.test.ts +431 -0
  1358. package/src/tui/components/operator-dashboard/conversation.ts +179 -0
  1359. package/src/tui/components/operator-dashboard/display-state.test.ts +369 -0
  1360. package/src/tui/components/operator-dashboard/display-state.ts +163 -0
  1361. package/src/tui/components/operator-dashboard/herdr-state.test.ts +162 -0
  1362. package/src/tui/components/operator-dashboard/herdr-state.ts +81 -0
  1363. package/src/tui/components/operator-dashboard/index.tsx +2044 -0
  1364. package/src/tui/components/operator-dashboard/logic.test.ts +753 -0
  1365. package/src/tui/components/operator-dashboard/logic.ts +465 -0
  1366. package/src/tui/components/operator-dashboard/queue.test.ts +147 -0
  1367. package/src/tui/components/operator-dashboard/queue.ts +55 -0
  1368. package/src/tui/components/operator-dashboard/queued-messages.tsx +50 -0
  1369. package/src/tui/components/operator-dashboard/run-events.test.ts +915 -0
  1370. package/src/tui/components/operator-dashboard/run-events.ts +507 -0
  1371. package/src/tui/components/operator-dashboard/run-tracing.test.ts +206 -0
  1372. package/src/tui/components/operator-dashboard/run-tracing.ts +105 -0
  1373. package/src/tui/components/operator-dashboard/subagent-detail-view.tsx +51 -0
  1374. package/src/tui/components/operator-dashboard/subagent-dialog.tsx +142 -0
  1375. package/src/tui/components/operator-dashboard/subagent-hub.test.ts +162 -0
  1376. package/src/tui/components/operator-dashboard/subagent-hub.tsx +266 -0
  1377. package/src/tui/components/operator-dashboard/subagent-state.test.ts +431 -0
  1378. package/src/tui/components/operator-dashboard/subagent-state.ts +404 -0
  1379. package/src/tui/components/operator-dashboard/subagent-status-bar.tsx +80 -0
  1380. package/src/tui/components/operator-dashboard/tool-argument-buffer.test.ts +317 -0
  1381. package/src/tui/components/operator-dashboard/tool-arguments.perf.test.ts +121 -0
  1382. package/src/tui/components/operator-dashboard/welcome-logo.tsx +79 -0
  1383. package/src/tui/components/operator-dashboard/workflow-data.test.ts +291 -0
  1384. package/src/tui/components/operator-dashboard/workflow-data.ts +130 -0
  1385. package/src/tui/components/report-viewer-dialog.tsx +98 -0
  1386. package/src/tui/components/responsible-use-disclosure.tsx +55 -0
  1387. package/src/tui/components/screenshot-modal.tsx +204 -0
  1388. package/src/tui/components/shared/__tests__/prompt-input-lifecycle.tsx +64 -0
  1389. package/src/tui/components/shared/__tests__/tool-renderer-lifecycle.tsx +87 -0
  1390. package/src/tui/components/shared/action-label.test.ts +142 -0
  1391. package/src/tui/components/shared/action-label.ts +18 -0
  1392. package/src/tui/components/shared/ascii-spinner.tsx +40 -0
  1393. package/src/tui/components/shared/compacting-icon.tsx +18 -0
  1394. package/src/tui/components/shared/dialog-controls.tsx +76 -0
  1395. package/src/tui/components/shared/index.ts +38 -0
  1396. package/src/tui/components/shared/markdown-viewer.tsx +188 -0
  1397. package/src/tui/components/shared/markdown.ts +239 -0
  1398. package/src/tui/components/shared/message-renderer.tsx +178 -0
  1399. package/src/tui/components/shared/message-utils.ts +175 -0
  1400. package/src/tui/components/shared/pentest-workflow-display.tsx +330 -0
  1401. package/src/tui/components/shared/prompt-input-lifecycle.test.ts +22 -0
  1402. package/src/tui/components/shared/prompt-input-logic.test.ts +782 -0
  1403. package/src/tui/components/shared/prompt-input-logic.ts +423 -0
  1404. package/src/tui/components/shared/prompt-input.tsx +782 -0
  1405. package/src/tui/components/shared/result-registry.test.ts +90 -0
  1406. package/src/tui/components/shared/result-registry.ts +900 -0
  1407. package/src/tui/components/shared/syntax-highlight.ts +242 -0
  1408. package/src/tui/components/shared/tool-registry.test.ts +59 -0
  1409. package/src/tui/components/shared/tool-registry.ts +280 -0
  1410. package/src/tui/components/shared/tool-renderer.test.ts +13 -0
  1411. package/src/tui/components/shared/tool-renderer.tsx +237 -0
  1412. package/src/tui/components/shared/type-guards.ts +64 -0
  1413. package/src/tui/components/shared/use-paste-extmarks.ts +109 -0
  1414. package/src/tui/components/switch.tsx +81 -0
  1415. package/src/tui/components/terminal-focus-handler.tsx +34 -0
  1416. package/src/tui/components/toast.tsx +82 -0
  1417. package/src/tui/components/usage-labels.test.ts +191 -0
  1418. package/src/tui/components/usage-labels.ts +78 -0
  1419. package/src/tui/console-theme.ts +59 -0
  1420. package/src/tui/context/agent.tsx +251 -0
  1421. package/src/tui/context/command.tsx +291 -0
  1422. package/src/tui/context/config.tsx +59 -0
  1423. package/src/tui/context/dialog.tsx +206 -0
  1424. package/src/tui/context/dimensions.tsx +31 -0
  1425. package/src/tui/context/focus-ownership.test.ts +26 -0
  1426. package/src/tui/context/focus-ownership.ts +12 -0
  1427. package/src/tui/context/focus.tsx +86 -0
  1428. package/src/tui/context/herdr.tsx +28 -0
  1429. package/src/tui/context/input.tsx +45 -0
  1430. package/src/tui/context/keybinding.tsx +92 -0
  1431. package/src/tui/context/obfuscation.tsx +114 -0
  1432. package/src/tui/context/route.tsx +127 -0
  1433. package/src/tui/context/session-usage.test.ts +295 -0
  1434. package/src/tui/context/session-usage.ts +204 -0
  1435. package/src/tui/context/session.tsx +62 -0
  1436. package/src/tui/context/toast.tsx +66 -0
  1437. package/src/tui/generated-ascii-art.json +1 -0
  1438. package/src/tui/generated-ascii-art.json.d.ts +2 -0
  1439. package/src/tui/herdr-startup.test.ts +157 -0
  1440. package/src/tui/hooks/use-sessions-list.ts +165 -0
  1441. package/src/tui/index.tsx +838 -0
  1442. package/src/tui/keybindings/index.ts +126 -0
  1443. package/src/tui/keybindings/registry.ts +146 -0
  1444. package/src/tui/keybindings-registry.ts +43 -0
  1445. package/src/tui/obfuscation/patch.ts +139 -0
  1446. package/src/tui/terminal-focus.ts +218 -0
  1447. package/src/tui/theme/colors.ts +43 -0
  1448. package/src/tui/theme/context.tsx +137 -0
  1449. package/src/tui/theme/detect-mode.ts +56 -0
  1450. package/src/tui/theme/index.ts +75 -0
  1451. package/src/tui/theme/registry.ts +29 -0
  1452. package/src/tui/theme/themes/apex.ts +190 -0
  1453. package/src/tui/theme/themes/ayu.ts +189 -0
  1454. package/src/tui/theme/themes/catppuccin.ts +189 -0
  1455. package/src/tui/theme/themes/dracula.ts +190 -0
  1456. package/src/tui/theme/themes/everforest.ts +189 -0
  1457. package/src/tui/theme/themes/flexoki.ts +190 -0
  1458. package/src/tui/theme/themes/github.ts +189 -0
  1459. package/src/tui/theme/themes/gruvbox.ts +189 -0
  1460. package/src/tui/theme/themes/index.ts +54 -0
  1461. package/src/tui/theme/themes/kanagawa.ts +189 -0
  1462. package/src/tui/theme/themes/material.ts +190 -0
  1463. package/src/tui/theme/themes/monokai.ts +190 -0
  1464. package/src/tui/theme/themes/nightfox.ts +189 -0
  1465. package/src/tui/theme/themes/nord.ts +190 -0
  1466. package/src/tui/theme/themes/onedark.ts +190 -0
  1467. package/src/tui/theme/themes/rose-pine.ts +189 -0
  1468. package/src/tui/theme/themes/solarized.ts +189 -0
  1469. package/src/tui/theme/themes/tokyonight.ts +189 -0
  1470. package/src/tui/theme/themes/vesper.ts +191 -0
  1471. package/src/tui/theme/types.ts +143 -0
  1472. package/src/tui/utils/command-flags.test.ts +269 -0
  1473. package/src/tui/utils/command-flags.ts +377 -0
  1474. package/src/tui/utils/kitty-graphics.ts +76 -0
  1475. package/src/tui/utils/open-file.ts +37 -0
  1476. package/src/tui/utils/open-report.ts +34 -0
  1477. package/src/tui/utils/open-url.ts +39 -0
  1478. package/src/tui/utils/paste.ts +8 -0
  1479. package/src/tui/utils/scroll.ts +81 -0
  1480. package/src/util/errors.ts +58 -0
  1481. package/src/util/lock.ts +100 -0
  1482. package/src/util/name.ts +148 -0
  1483. package/src/util/url.test.ts +162 -0
  1484. package/src/util/url.ts +107 -0
  1485. package/build/agent-13rrhp8d.js +0 -20
  1486. package/build/agent-zbj2331s.js +0 -30
  1487. package/build/authentication-f4j3w5vs.js +0 -20
  1488. package/build/blackboxAgent-v2vx9ws4.js +0 -20
  1489. package/build/blackboxPentest-w5nwzpvk.js +0 -70
  1490. package/build/cli-5wemv37a.js +0 -194
  1491. package/build/cli-7s062hr6.js +0 -22
  1492. package/build/cli-9qbxkhye.js +0 -55
  1493. package/build/cli-avmhkjtv.js +0 -22961
  1494. package/build/cli-g3czc3jz.js +0 -204
  1495. package/build/cli-ww7hbazg.js +0 -88
  1496. package/build/index-18vyy6mj.js +0 -19
  1497. package/build/index-5wh7gq37.js +0 -12858
  1498. package/build/index-e23zc8g4.js +0 -34
  1499. package/build/index-hnwhswqj.js +0 -213
  1500. package/build/index-wkmnr4nm.js +0 -39
  1501. package/build/index-ywmfnd30.js +0 -12
  1502. package/build/offesecAgent-c97pqzcn.js +0 -27
  1503. package/build/pentest-4p5jt7gj.js +0 -30
  1504. package/build/pentests-v98eg8n3.js +0 -92
  1505. package/build/threatModel-81d4rcbk.js +0 -29
  1506. /package/build/{cli-c8131c4q.js → cli-0wsh8j2t.js} +0 -0
  1507. /package/build/{cli-9pbk8m32.js → cli-ag6jtndp.js} +0 -0
  1508. /package/build/{cli-e08r86zk.js → cli-b3dvxjgk.js} +0 -0
  1509. /package/build/{cli-fw5r7pfj.js → cli-q126f6ef.js} +0 -0
  1510. /package/build/{cli-9fsre5pt.js → cli-qba2x69h.js} +0 -0
  1511. /package/build/{cli-7q3ae3ft.js → cli-z82n3qk1.js} +0 -0
@@ -0,0 +1,2568 @@
1
+ import { AsyncLocalStorage, AsyncResource } from "node:async_hooks";
2
+ import { setTimeout as delay } from "node:timers/promises";
3
+ import type { AnthropicMessagesModelId } from "@ai-sdk/anthropic/internal";
4
+ import type { OpenAIResponsesProviderOptions } from "@ai-sdk/openai";
5
+ import type { OpenAIChatModelId } from "@ai-sdk/openai/internal";
6
+ import {
7
+ generateText,
8
+ type LanguageModel,
9
+ type LanguageModelMiddleware,
10
+ type ModelMessage,
11
+ Output,
12
+ type StopCondition,
13
+ type StreamTextOnFinishCallback,
14
+ type StreamTextOnStepFinishCallback,
15
+ type StreamTextResult,
16
+ streamText,
17
+ type TextStreamPart,
18
+ type ToolChoice,
19
+ type ToolSet,
20
+ wrapLanguageModel,
21
+ } from "ai";
22
+ import type { z } from "zod";
23
+ import {
24
+ type CustomProviders,
25
+ parseCustomModelId,
26
+ resolveCustomModel,
27
+ } from "../config/customProviders";
28
+ import { type HoonifyModel, resolveHoonifyModel } from "../hoonify";
29
+ import { createLogger } from "../logger/structured";
30
+ import {
31
+ type AiTelemetryOperation,
32
+ createAiTelemetrySettings,
33
+ createGenerationSpanTracker,
34
+ type GenerationSpanTracker,
35
+ withModelCallDiagnostics,
36
+ } from "../observability";
37
+ import { RunPersistenceError } from "../runtime/persistenceError";
38
+ import type { RunContextRecorder } from "../runtime/runContext";
39
+ import { RunControlInterruption } from "../runtime/runControlStore";
40
+ import { RunLimitError } from "../runtime/runModelStore";
41
+ import { scopedLogger } from "../util/lazyLogger";
42
+ import {
43
+ cacheBreakpointFor,
44
+ withCachedLastMessage,
45
+ withCachedSystemPrompt,
46
+ } from "./caching";
47
+ import {
48
+ beginCompaction,
49
+ type CompactionLink,
50
+ type CompactionTrigger,
51
+ } from "./compactionTelemetry";
52
+ import {
53
+ estimateMessageTokens,
54
+ estimateTokens,
55
+ estimateToolsOverheadTokens,
56
+ type FitContextResult,
57
+ fitMessagesToContext,
58
+ truncateWithMarker,
59
+ } from "./contextManagement";
60
+ import {
61
+ getInferenceRecorder,
62
+ type InferenceRecorder,
63
+ runWithInferenceRecorder,
64
+ } from "./inference-attempt";
65
+ import {
66
+ type ClaudeThinkingEffort,
67
+ getClaudeCapabilities,
68
+ getMaxOutputTokens,
69
+ getModelInfo,
70
+ prefersSequentialToolCalls,
71
+ } from "./models";
72
+ import {
73
+ runWithNativeRolloutOperation,
74
+ withNativeRolloutEvidenceModel,
75
+ } from "./native-rollout-evidence";
76
+ import { CONCENTRATE_GLM_5_3_MODEL_ID } from "./providers/concentrate";
77
+ import { OPENAI_PRO_TIMEOUT_MS } from "./providers/openai-pro-fetch";
78
+ import { STREAM_DEBUG } from "./streamTelemetry";
79
+ import {
80
+ type AIAuthConfig,
81
+ CompactionRejectedError,
82
+ checkIfContextLengthError,
83
+ createSummarizationStream,
84
+ getProviderModel,
85
+ isAnthropicProvider,
86
+ } from "./utils";
87
+
88
+ const log = scopedLogger(() => createLogger("ai"));
89
+
90
+ // Opt-in debug logging for the empty-`{}` / looping response failure; bypasses `silent`.
91
+ const RESPONSE_DEBUG =
92
+ process.env.RESPONSE_DEBUG === "1" || process.env.RESPONSE_DEBUG === "true";
93
+ const RESPONSE_TOOL_NAME = "response";
94
+
95
+ function nativeRolloutOperation(
96
+ operation?: AiTelemetryOperation,
97
+ ): "structured.generate" | "context.summarize" | "tool.repair" {
98
+ if (operation === "apex.context.summarize") return "context.summarize";
99
+ if (operation === "apex.tool.repair") return "tool.repair";
100
+ return "structured.generate";
101
+ }
102
+
103
+ /**
104
+ * Tools whose arguments carry a security-authorization boundary the model must
105
+ * never have re-synthesized by tool-call repair. Repair asks a model to invent
106
+ * schema-valid arguments from a failed call; for these tools a fabricated value
107
+ * (e.g. a default/localhost `target`) would silently bypass deterministic scope
108
+ * enforcement. Repair therefore FAILS CLOSED for them — it returns `null` and
109
+ * the original invalid call is never executed.
110
+ *
111
+ * Result-submission tools (`submit_results`, `document_vulnerability`) are
112
+ * deliberately NOT listed: they carry no authorization boundary, so repair is
113
+ * safe and desirable — it re-prompts the model to fix a mis-shaped field (e.g.
114
+ * `method` sent as an array) instead of dropping a completed recon or a
115
+ * confirmed finding.
116
+ */
117
+ const REPAIR_FAIL_CLOSED_TOOLS: ReadonlySet<string> = new Set([
118
+ "spawn_pentest_agent",
119
+ ]);
120
+
121
+ /**
122
+ * Whether tool-call repair must fail closed (no argument synthesis) for a tool.
123
+ * Exported for regression tests covering the repaired-invalid-call path.
124
+ */
125
+ export function isRepairFailClosedTool(toolName: string): boolean {
126
+ return REPAIR_FAIL_CLOSED_TOOLS.has(toolName);
127
+ }
128
+
129
+ export type AIModel = AnthropicMessagesModelId | OpenAIChatModelId | string; // For gateway and Bedrock model IDs
130
+
131
+ export type OpenAIReasoningEffort =
132
+ | "none"
133
+ | "low"
134
+ | "medium"
135
+ | "high"
136
+ | "xhigh"
137
+ | "max"
138
+ | "ultra";
139
+
140
+ export const DEFAULT_OPENAI_REASONING_EFFORT: OpenAIReasoningEffort = "medium";
141
+
142
+ /**
143
+ * Anthropic adaptive-thinking effort hint. Soft guidance for how much the model
144
+ * reasons (see AWS "adaptive thinking"): `low` minimizes thinking while
145
+ * `xhigh` and `max` allow progressively deeper work. Only meaningful for
146
+ * models that support adaptive thinking; ignored elsewhere.
147
+ */
148
+ export type ThinkingEffort = ClaudeThinkingEffort;
149
+
150
+ const OPENAI_REASONING_MODEL_IDS = new Set([
151
+ "gpt-6.1-sol",
152
+ "gpt-6-luna",
153
+ "gpt-6-sol",
154
+ "gpt-6-astra",
155
+ "gpt-5.5-pro",
156
+ "gpt-5.5-pro-2026-04-23",
157
+ "gpt-5.4-nano",
158
+ "gpt-5.4-nano-2026-03-17",
159
+ "gpt-5.4-mini",
160
+ "gpt-5.4-mini-2026-03-17",
161
+ "gpt-5",
162
+ "gpt-5-2025-08-07",
163
+ "gpt-5.1",
164
+ "gpt-5.1-2025-11-13",
165
+ "gpt-5.2",
166
+ "gpt-5.2-2025-12-11",
167
+ "gpt-5.2-pro",
168
+ "gpt-5.2-pro-2025-12-11",
169
+ "gpt-5.4",
170
+ "gpt-5.4-2026-03-05",
171
+ "gpt-5.4-pro",
172
+ "gpt-5.4-pro-2026-03-05",
173
+ "gpt-5.5",
174
+ "gpt-5.5-2026-04-23",
175
+ "gpt-5.6-sol",
176
+ "gpt-5.6-terra",
177
+ "gpt-5.6-luna",
178
+ ]);
179
+
180
+ /** Per-step billing context attached to a usage report, attributing cost to a specific `(sessionId, stepSeq)`. */
181
+ export interface UsageStepContext {
182
+ sessionId?: string;
183
+ stepSeq?: number;
184
+ }
185
+
186
+ /**
187
+ * Context attached to every usage report. The cache counters are always
188
+ * present — zero when the provider supplies none — and are already included
189
+ * in `inputTokens`:
190
+ * `uncachedInputTokens = inputTokens - cacheReadTokens - cacheWriteTokens`.
191
+ */
192
+ export interface UsageCallbackContext extends UsageStepContext {
193
+ cacheReadTokens: number;
194
+ cacheWriteTokens: number;
195
+ }
196
+
197
+ /** Callback for reporting token usage from AI operations. */
198
+ export type UsageCallback = (
199
+ modelId: string,
200
+ inputTokens: number,
201
+ outputTokens: number,
202
+ context: UsageCallbackContext,
203
+ ) => void | Promise<void>;
204
+
205
+ /**
206
+ * Per-run usage recorder threaded through {@link StreamResponseOpts}. When set
207
+ * it replaces the ALS run sink and the ambient {@link onUsage} callback for
208
+ * that call. Async work is awaited before the next model step. Receives the
209
+ * same cache-aware {@link UsageCallbackContext} as the global callback, so
210
+ * the cached/uncached split travels on the usage event itself.
211
+ */
212
+ export type UsageRecorder = (
213
+ model: string,
214
+ inputTokens: number,
215
+ outputTokens: number,
216
+ context?: UsageCallbackContext,
217
+ ) => void | Promise<void>;
218
+
219
+ let _usageCallback: UsageCallback | null = null;
220
+
221
+ /** Ambient default usage sink when no run-context sink is set. */
222
+ export function onUsage(cb: UsageCallback | null): void {
223
+ _usageCallback = cb;
224
+ }
225
+
226
+ /** Normalized per-step usage: input/output plus cache buckets, provider-agnostic. */
227
+ export interface NormalizedStepUsage {
228
+ inputTokens: number;
229
+ outputTokens: number;
230
+ cacheReadTokens: number;
231
+ cacheWriteTokens: number;
232
+ }
233
+
234
+ /**
235
+ * Extract normalized usage from one completed model step. A single function
236
+ * feeds both `onCacheMetrics` and the usage callback so provider metadata is
237
+ * never parsed twice. Anthropic's `providerMetadata.anthropic` wins; the
238
+ * SDK's normalized `usage.inputTokenDetails` is the fallback (Pensar
239
+ * provider). Input stays inclusive of cached tokens.
240
+ */
241
+ export function normalizeStepUsage(step: {
242
+ usage?: {
243
+ inputTokens?: number;
244
+ outputTokens?: number;
245
+ inputTokenDetails?: {
246
+ cacheReadTokens?: number;
247
+ cacheWriteTokens?: number;
248
+ };
249
+ };
250
+ providerMetadata?: unknown;
251
+ }): NormalizedStepUsage {
252
+ const inputTokens = step.usage?.inputTokens ?? 0;
253
+ const outputTokens = step.usage?.outputTokens ?? 0;
254
+
255
+ // Extract Anthropic cache metrics from providerMetadata (direct Anthropic / Bedrock SDK)
256
+ const meta = (
257
+ step.providerMetadata as
258
+ | { anthropic?: Record<string, unknown> }
259
+ | null
260
+ | undefined
261
+ )?.anthropic;
262
+ let cacheRead = (meta?.cacheReadInputTokens as number) ?? 0;
263
+ let cacheWrite = (meta?.cacheCreationInputTokens as number) ?? 0;
264
+
265
+ // Pensar provider doesn't populate providerMetadata.anthropic;
266
+ // fall back to the SDK's normalized usage.inputTokenDetails.
267
+ const details = step.usage?.inputTokenDetails;
268
+ if (cacheRead === 0) {
269
+ cacheRead = details?.cacheReadTokens ?? 0;
270
+ }
271
+ if (cacheWrite === 0) {
272
+ cacheWrite = details?.cacheWriteTokens ?? 0;
273
+ }
274
+
275
+ return {
276
+ inputTokens,
277
+ outputTokens,
278
+ cacheReadTokens: cacheRead,
279
+ cacheWriteTokens: cacheWrite,
280
+ };
281
+ }
282
+
283
+ // Per-run step counter for billing attribution, scoped via AsyncLocalStorage so
284
+ // concurrent runs never race a shared index. Not a strict global sequence —
285
+ // the DB `stepSeq` on `agent_messages` remains authoritative; this only labels
286
+ // live usage reports.
287
+
288
+ interface StepContext {
289
+ sessionId?: string;
290
+ /** Next step index to hand out; mutated in place as steps finish. */
291
+ next: number;
292
+ /** Per-run usage sink; wins over the ambient {@link onUsage} callback. */
293
+ usageSink?: UsageCallback;
294
+ }
295
+
296
+ const stepContextStore = new AsyncLocalStorage<StepContext>();
297
+
298
+ /** Runs `fn` in a per-run step-counting context; `streamResponse` steps inside it report usage tagged with `sessionId` and an increasing `stepSeq` starting at `seedStepSeq`. */
299
+ export function runWithStepContext<T>(
300
+ opts: {
301
+ sessionId?: string;
302
+ seedStepSeq?: number;
303
+ usageSink?: UsageCallback;
304
+ },
305
+ fn: () => T,
306
+ ): T {
307
+ const parent = stepContextStore.getStore();
308
+ return stepContextStore.run(
309
+ {
310
+ sessionId: opts.sessionId,
311
+ next: opts.seedStepSeq ?? 0,
312
+ usageSink: opts.usageSink ?? parent?.usageSink,
313
+ },
314
+ fn,
315
+ );
316
+ }
317
+
318
+ /** Takes and advances the next `stepSeq` for the current run; returns `undefined` outside any run context. */
319
+ export function takeStepContext(): UsageStepContext | undefined {
320
+ const store = stepContextStore.getStore();
321
+ if (!store) return undefined;
322
+ const stepSeq = store.next;
323
+ store.next += 1;
324
+ return { sessionId: store.sessionId, stepSeq };
325
+ }
326
+
327
+ /**
328
+ * Report one finished model call to a usage sink. Advances `stepSeq` whenever
329
+ * a sink is present (including zero-token steps) so the index stays aligned
330
+ * with the AI SDK. Skips the callback itself when both token counts are 0.
331
+ */
332
+ async function emitUsage(
333
+ model: string,
334
+ stepUsage: NormalizedStepUsage,
335
+ sink: UsageRecorder | UsageCallback | null | undefined,
336
+ ): Promise<void> {
337
+ if (!sink) return;
338
+ const stepCtx = takeStepContext();
339
+ if (stepUsage.inputTokens <= 0 && stepUsage.outputTokens <= 0) return;
340
+ await sink(model, stepUsage.inputTokens, stepUsage.outputTokens, {
341
+ ...stepCtx,
342
+ cacheReadTokens: stepUsage.cacheReadTokens,
343
+ cacheWriteTokens: stepUsage.cacheWriteTokens,
344
+ });
345
+ }
346
+
347
+ /** explicit recorder > ALS run sink > ambient {@link onUsage}. */
348
+ function resolveUsageSink(
349
+ explicit?: UsageRecorder,
350
+ ): UsageRecorder | UsageCallback | null {
351
+ return explicit ?? stepContextStore.getStore()?.usageSink ?? _usageCallback;
352
+ }
353
+
354
+ export type AIModelProvider =
355
+ | "custom"
356
+ | "anthropic"
357
+ | "openai"
358
+ | "google"
359
+ | "openrouter"
360
+ | "concentrate"
361
+ | "bedrock"
362
+ | "bedrock-mantle"
363
+ | "pensar"
364
+ | "inception"
365
+ | "hoonify"
366
+ | "local";
367
+
368
+ /** Conservative default when `getModelInfo` doesn't have a `contextLength`. */
369
+ export function getContextWindow(
370
+ modelId: string,
371
+ customProviders?: CustomProviders,
372
+ hoonifyModels?: HoonifyModel[],
373
+ ): number {
374
+ if (modelId.startsWith("hoonify:"))
375
+ return resolveHoonifyModel(modelId, hoonifyModels).contextLength;
376
+ if (parseCustomModelId(modelId))
377
+ return resolveCustomModel(modelId, customProviders).model.contextLength;
378
+ return getModelInfo(modelId).contextLength ?? 200_000;
379
+ }
380
+
381
+ function checkIfRateLimitError(error: unknown): boolean {
382
+ const errObj =
383
+ typeof error === "object" && error !== null
384
+ ? (error as Record<string, unknown>)
385
+ : {};
386
+
387
+ // Check message — works for both Error instances and plain objects
388
+ // (Bedrock streaming errors are plain { message: "..." } records)
389
+ const errorMessage = (
390
+ typeof errObj.message === "string" ? errObj.message : ""
391
+ ).toLowerCase();
392
+ const errorCode = String(
393
+ typeof errObj.code === "string" ? errObj.code : "",
394
+ ).toLowerCase();
395
+ // AWS SDK errors surface the exception type via .name
396
+ const errorName = (
397
+ typeof errObj.name === "string" ? errObj.name : ""
398
+ ).toLowerCase();
399
+ // Bedrock HTTP-level errors include $metadata.httpStatusCode
400
+ const httpStatus =
401
+ typeof errObj.$metadata === "object" && errObj.$metadata !== null
402
+ ? (errObj.$metadata as Record<string, unknown>).httpStatusCode
403
+ : undefined;
404
+ // Stringified fallback for opaque error objects (e.g. Bedrock stream records)
405
+ const errorString =
406
+ errorMessage || errorName ? "" : String(error).toLowerCase();
407
+
408
+ return (
409
+ // Message-based detection
410
+ errorMessage.includes("too many tokens") ||
411
+ errorMessage.includes("rate limit") ||
412
+ errorMessage.includes("request rate") ||
413
+ errorMessage.includes("throttl") ||
414
+ errorMessage.includes("overloaded") ||
415
+ errorMessage.includes("too many requests") ||
416
+ errorMessage.includes("please wait") ||
417
+ errorMessage.includes("service unavailable") ||
418
+ // AWS SDK exception names (ThrottlingException, TooManyRequestsException)
419
+ errorName.includes("throttl") ||
420
+ errorName.includes("toomanyrequests") ||
421
+ errorName.includes("serviceunavailable") ||
422
+ // Error codes
423
+ errorCode === "rate_limit_exceeded" ||
424
+ errorCode === "throttling" ||
425
+ errorCode === "429" ||
426
+ // HTTP status from AWS SDK $metadata
427
+ httpStatus === 429 ||
428
+ httpStatus === 529 ||
429
+ httpStatus === 503 ||
430
+ // Fallback: stringified error for opaque Bedrock stream records
431
+ errorString.includes("throttl") ||
432
+ errorString.includes("too many") ||
433
+ errorString.includes("request rate")
434
+ );
435
+ }
436
+
437
+ // Injected into the system prompt for models that mis-parse parallel tool
438
+ // calls (DeepSeek V3.1 on Bedrock). See prefersSequentialToolCalls.
439
+ const SEQUENTIAL_TOOL_CALL_INSTRUCTION =
440
+ "CRITICAL TOOL-CALLING RULE: Emit EXACTLY ONE tool call per response. " +
441
+ "Never emit more than one tool call in a single turn. After each tool call, " +
442
+ "wait for its result before making the next one. Emitting multiple tool " +
443
+ "calls in one turn corrupts their arguments.";
444
+
445
+ // Returns the system prompt that is actually sent to the provider, accounting
446
+ // for the sequential-tool-call policy appended for models that mis-parse
447
+ // parallel tool calls. Token budgeting (`fitMessagesToContext`) must use this
448
+ // value, not the raw `system`, or it underestimates the system prompt size and
449
+ // overestimates the message budget near the context limit.
450
+ function applySequentialToolCallPolicy(
451
+ system: string | undefined,
452
+ tools: ToolSet | undefined,
453
+ model: AIModel,
454
+ ): string | undefined {
455
+ if (
456
+ tools &&
457
+ Object.keys(tools).length > 0 &&
458
+ prefersSequentialToolCalls(model)
459
+ ) {
460
+ return `${system ? `${system}\n\n` : ""}${SEQUENTIAL_TOOL_CALL_INSTRUCTION}`;
461
+ }
462
+ return system;
463
+ }
464
+
465
+ // The structured-output `response` tool is injected by the caller alongside its
466
+ // own tools, so an allowlist of those tools must not hide it from the model.
467
+ // Composed into `resolveEffectiveTools` at the call site so the executable map
468
+ // keeps `response` even when a caller omits it from `activeTools`.
469
+ export function withResponseToolActive(
470
+ tools: ToolSet | undefined,
471
+ activeTools: string[] | undefined,
472
+ ): string[] | undefined {
473
+ if (
474
+ !tools ||
475
+ !activeTools ||
476
+ activeTools.length === 0 ||
477
+ !(RESPONSE_TOOL_NAME in tools) ||
478
+ activeTools.includes(RESPONSE_TOOL_NAME)
479
+ ) {
480
+ return activeTools;
481
+ }
482
+ return [...activeTools, RESPONSE_TOOL_NAME];
483
+ }
484
+
485
+ /**
486
+ * Resolve the effective toolset from `activeTools` before any context
487
+ * fitting. The AI SDK treats `activeTools` as advertise-only — it still
488
+ * parses, executes, and enumerates every tool in the full map — so the
489
+ * executable map itself must be filtered here for budgeting, provider
490
+ * exposure, execution, and repair to agree. Built with DefineOwnProperty
491
+ * semantics so prototype-shaped names like `__proto__` survive as own keys.
492
+ * Feed it `withResponseToolActive(tools, activeTools)` so the injected
493
+ * structured-output tool survives the filter.
494
+ */
495
+ export function resolveEffectiveTools(
496
+ tools: ToolSet | undefined,
497
+ activeTools: string[] | undefined,
498
+ ): Pick<StreamResponseOpts, "tools" | "activeTools"> {
499
+ if (!tools || !activeTools) return {};
500
+ if (activeTools.length === 0) return { tools: {}, activeTools: undefined };
501
+ const allow = new Set(activeTools);
502
+ return {
503
+ tools: Object.fromEntries(
504
+ Object.entries(tools).filter(([name]) => allow.has(name)),
505
+ ),
506
+ activeTools: undefined,
507
+ };
508
+ }
509
+
510
+ // Kept for callers/tests that filter a tool map without consuming `activeTools`
511
+ // (e.g. `withResponseToolActive` composition). `resolveEffectiveTools` is the
512
+ // stream-loop entry point; this is the same filter returning just the map.
513
+ export function restrictToolsToActive(
514
+ tools: ToolSet | undefined,
515
+ activeTools: string[] | undefined,
516
+ ): ToolSet | undefined {
517
+ if (!tools || !activeTools || activeTools.length === 0) {
518
+ return tools;
519
+ }
520
+ const allow = new Set(activeTools);
521
+ const restricted: ToolSet = {};
522
+ for (const [name, tool] of Object.entries(tools)) {
523
+ if (allow.has(name)) {
524
+ restricted[name] = tool;
525
+ }
526
+ }
527
+ return restricted;
528
+ }
529
+
530
+ const MAX_RATE_LIMIT_RETRIES = 20;
531
+ const MAX_IDLE_RESUME_RETRIES = 3;
532
+ const STREAM_IDLE_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
533
+
534
+ // Observe the existing depth allowance only for accepted restarts.
535
+ export async function recordContextRestart(
536
+ depth: number,
537
+ opts?: Pick<StreamResponseOpts, "inferenceRecorder">,
538
+ ): Promise<void> {
539
+ if (depth > MAX_RESTART_DEPTH) return;
540
+ await getInferenceRecorder(opts)?.retry({
541
+ authority: "context-restart",
542
+ count: depth,
543
+ maxRetries: MAX_RESTART_DEPTH,
544
+ delayMs: 0,
545
+ });
546
+ }
547
+
548
+ function getStreamIdleTimeoutMs(model: AIModel): number {
549
+ // Pro cannot stream progress while reasoning; wait for its completed response.
550
+ return /^(?:openai\/)?gpt-5\.5-pro(?:-|$)/.test(model)
551
+ ? OPENAI_PRO_TIMEOUT_MS
552
+ : STREAM_IDLE_TIMEOUT_MS;
553
+ }
554
+
555
+ class StreamIdleTimeoutError extends Error {
556
+ constructor(idleMs: number) {
557
+ super(`Stream idle for ${Math.round(idleMs / 1000)}s — no chunks received`);
558
+ this.name = "StreamIdleTimeoutError";
559
+ }
560
+ }
561
+
562
+ /**
563
+ * Wraps an async iterable with a per-chunk idle timeout. If no chunk arrives
564
+ * within `idleMs`, throws a {@link StreamIdleTimeoutError} so the caller can
565
+ * resume the conversation from accumulated messages.
566
+ *
567
+ * @param isIdleTimerActive Optional predicate evaluated before awaiting each
568
+ * chunk. When it returns `false` the timer is skipped for that chunk and we
569
+ * wait indefinitely. This lets callers suppress the timeout during expected
570
+ * long pauses (e.g. while a tool call is executing) so a slow tool isn't
571
+ * misread as a stalled provider stream.
572
+ */
573
+ async function* withIdleTimeout<T>(
574
+ stream: AsyncIterable<T>,
575
+ idleMs: number,
576
+ isIdleTimerActive?: () => boolean,
577
+ ): AsyncGenerator<T> {
578
+ const iterator = stream[Symbol.asyncIterator]();
579
+ try {
580
+ while (true) {
581
+ const timerActive = isIdleTimerActive?.() ?? true;
582
+ let result: IteratorResult<T>;
583
+ if (timerActive) {
584
+ let timer: ReturnType<typeof setTimeout> | undefined;
585
+ result = await Promise.race([
586
+ iterator.next(),
587
+ new Promise<never>((_, reject) => {
588
+ timer = setTimeout(
589
+ () => reject(new StreamIdleTimeoutError(idleMs)),
590
+ idleMs,
591
+ );
592
+ if (typeof timer === "object" && "unref" in timer) timer.unref();
593
+ }),
594
+ ]);
595
+ clearTimeout(timer);
596
+ } else {
597
+ result = await iterator.next();
598
+ }
599
+
600
+ if (result.done) return;
601
+ yield result.value;
602
+ }
603
+ } finally {
604
+ // Best-effort cleanup — don't block on a stuck iterator. The underlying
605
+ // stream may be wedged (that's why we're here), so a hanging return()
606
+ // would deadlock the consumer.
607
+ iterator.return?.()?.catch?.(() => {});
608
+ }
609
+ }
610
+
611
+ function isStreamIdleTimeoutError(error: unknown): boolean {
612
+ // AI SDK may rewrap the error, so walk `cause`.
613
+ for (let e: unknown = error, depth = 0; e != null && depth < 6; depth++) {
614
+ if (e instanceof StreamIdleTimeoutError) return true;
615
+ e = (e as { cause?: unknown }).cause;
616
+ }
617
+ return false;
618
+ }
619
+
620
+ /**
621
+ * Gates the idle-timeout in {@link withIdleTimeout} so it only fires while
622
+ * we're waiting on the **model**, not while a tool is executing.
623
+ *
624
+ * The provider stream emits nothing between a `tool-call` chunk and the
625
+ * matching `tool-result`. A slow tool (e.g. `run_attack_surface`, which
626
+ * spawns a multi-minute sub-agent) would otherwise be misread as a stalled
627
+ * stream — triggering the auto-resume path and causing the model to re-issue
628
+ * the same tool call, which spawns a duplicate sub-agent.
629
+ *
630
+ * Parallel tool calls are tracked by `toolCallId`. Duplicate `tool-call`
631
+ * chunks for the same id (defensive — should never happen in practice) are
632
+ * deduplicated. Terminal chunks (`tool-result` / `tool-error`) without a
633
+ * matching open call are ignored so the counter can never go negative.
634
+ *
635
+ * EXCEPTION: `response` is never gated — its `execute` returns synchronously so
636
+ * it's not a slow tool, but a Bedrock stream wedging mid-payload while
637
+ * streaming its (often large) args would otherwise suppress the idle timeout
638
+ * forever (confirmed hang). Leaving it ungated keeps idle-timeout auto-resume working.
639
+ */
640
+ const NON_GATED_TOOLS = new Set<string>(["response"]);
641
+
642
+ function createToolExecutionGate(): {
643
+ shouldEnforceIdleTimeout: () => boolean;
644
+ observe: (chunk: {
645
+ type: string;
646
+ toolCallId?: string;
647
+ toolName?: string;
648
+ }) => void;
649
+ } {
650
+ let inFlight = 0;
651
+ const open = new Set<string>();
652
+
653
+ return {
654
+ shouldEnforceIdleTimeout: () => inFlight === 0,
655
+ observe: (chunk) => {
656
+ if (chunk.type === "tool-call") {
657
+ if (chunk.toolName && NON_GATED_TOOLS.has(chunk.toolName)) return;
658
+ const id = chunk.toolCallId;
659
+ if (id) {
660
+ if (!open.has(id)) {
661
+ open.add(id);
662
+ inFlight++;
663
+ }
664
+ } else {
665
+ inFlight++;
666
+ }
667
+ } else if (chunk.type === "tool-result" || chunk.type === "tool-error") {
668
+ // A failed tool is just as terminal for the gate as a successful one —
669
+ // without this, a tool-error leaves its slot open forever, suppressing
670
+ // the idle timeout for the rest of the run.
671
+ const id = chunk.toolCallId;
672
+ if (id) {
673
+ if (open.delete(id)) {
674
+ inFlight = Math.max(0, inFlight - 1);
675
+ }
676
+ } else if (!(chunk.toolName && NON_GATED_TOOLS.has(chunk.toolName))) {
677
+ inFlight = Math.max(0, inFlight - 1);
678
+ }
679
+ }
680
+ },
681
+ };
682
+ }
683
+
684
+ class InStreamCompactionRequired extends Error {
685
+ constructor(readonly fitted: FitContextResult) {
686
+ super("In-stream compaction required before provider dispatch");
687
+ }
688
+ }
689
+
690
+ // Retry once after new tool output, then let fitting handle this turn.
691
+ const MAX_PROACTIVE_SUMMARY_FAILURES = 2;
692
+
693
+ function shouldSummarizeBeforeFitting(
694
+ messages: ModelMessage[],
695
+ contextWindow: number,
696
+ maxOutputTokens: number,
697
+ overheadTokens: number,
698
+ safetyMarginTokens: number,
699
+ system?: string,
700
+ toolChoice?: ToolChoice<ToolSet>,
701
+ ): boolean {
702
+ const historyBudget =
703
+ contextWindow -
704
+ maxOutputTokens -
705
+ overheadTokens -
706
+ safetyMarginTokens -
707
+ (system ? estimateTokens(system) : 0);
708
+ const estimatedHistoryTokens = estimateMessageTokens(messages);
709
+ // Forced-tool replays missed the summary cache; keep their fitted history path.
710
+ return (
711
+ historyBudget > 0 &&
712
+ messages.length > 2 &&
713
+ toolChoice !== "required" &&
714
+ typeof toolChoice !== "object" &&
715
+ estimatedHistoryTokens >=
716
+ Math.max(100_000, Math.floor(historyBudget * 0.8)) &&
717
+ estimatedHistoryTokens <= historyBudget
718
+ );
719
+ }
720
+
721
+ // Helper function to wrap a stream with error handling for async errors
722
+ function wrapStreamWithErrorHandler(
723
+ originalStream: StreamTextResult<ToolSet, never>,
724
+ messagesContainer: { current: ModelMessage[] },
725
+ opts: StreamResponseOpts,
726
+ model: LanguageModel,
727
+ silent?: boolean,
728
+ rateLimitRetryCount: number = 0,
729
+ idleResumeCount: number = 0,
730
+ generationSpans?: GenerationSpanTracker,
731
+ ): StreamTextResult<ToolSet, never> {
732
+ // Create a lazy getter for fullStream that wraps it with error handling
733
+ let wrappedStream: AsyncIterable<TextStreamPart<ToolSet>> | null = null;
734
+
735
+ const handler = {
736
+ get(_target: StreamTextResult<ToolSet, never>, prop: string | symbol) {
737
+ // Intercept access to fullStream
738
+ if (prop === "fullStream") {
739
+ if (!wrappedStream) {
740
+ // Tool-execution gate: keeps the idle timer paused while a tool
741
+ // is in flight (see {@link createToolExecutionGate}). The gate's
742
+ // predicate is read by `withIdleTimeout` at the top of each
743
+ // iteration — which always runs AFTER the previous chunk's body
744
+ // finished mutating the gate, so observations are always visible
745
+ // before the next idle-race begins.
746
+ const toolGate = createToolExecutionGate();
747
+
748
+ wrappedStream = (async function* () {
749
+ let streamError: unknown;
750
+ try {
751
+ for await (const chunk of withIdleTimeout(
752
+ originalStream.fullStream,
753
+ getStreamIdleTimeoutMs(opts.model),
754
+ toolGate.shouldEnforceIdleTimeout,
755
+ )) {
756
+ toolGate.observe(chunk);
757
+
758
+ // [response-debug] Log AI-SDK-level response-tool chunks / finish-step, below the consume() loop.
759
+ if (RESPONSE_DEBUG) {
760
+ const c = chunk as {
761
+ type: string;
762
+ toolName?: string;
763
+ toolCallId?: string;
764
+ finishReason?: string;
765
+ invalid?: boolean;
766
+ };
767
+ if (
768
+ (c.type === "tool-call" ||
769
+ c.type === "tool-error" ||
770
+ c.type === "tool-result") &&
771
+ c.toolName === RESPONSE_TOOL_NAME
772
+ ) {
773
+ log.warn(
774
+ `[response-debug] ai-layer chunk=${c.type} response id=${c.toolCallId} invalid=${c.invalid === true}`,
775
+ );
776
+ } else if (c.type === "finish-step") {
777
+ log.warn(
778
+ `[response-debug] ai-layer finish-step finishReason=${c.finishReason}`,
779
+ );
780
+ }
781
+ }
782
+
783
+ // Only stream-level errors are fatal; tool-level errors
784
+ // flow through so the UI renders them as failed tool results.
785
+ // Instead of throwing mid-stream, capture the error and drain
786
+ // the tail (finish-step/finish): the AI SDK's terminal
787
+ // lifecycle — root-span end included — only runs when the
788
+ // stream completes, and aborting the iteration leaks it.
789
+ if (chunk.type === "error") {
790
+ streamError = (chunk as unknown as { error: unknown }).error;
791
+ // Mark the root generation span failed NOW: the SDK's
792
+ // flush ends it mid-drain, before the loop exits — a
793
+ // later mark is a no-op on an ended span.
794
+ generationSpans?.markFailed(streamError);
795
+ continue;
796
+ }
797
+ // Drain the post-error tail silently: the terminal parts
798
+ // must be consumed for the SDK's finalization, but consumers
799
+ // must not observe step-close-out after a fatal error.
800
+ if (streamError !== undefined) {
801
+ continue;
802
+ }
803
+
804
+ yield chunk;
805
+ }
806
+ if (streamError !== undefined) {
807
+ // The tail is consumed but the SDK's finalization
808
+ // (root-span end) settles with the response promise —
809
+ // await it so the error never overtakes the span lifecycle.
810
+ await Promise.resolve(originalStream.response).catch(() => {});
811
+ throw streamError;
812
+ }
813
+ } catch (caughtError) {
814
+ // A tail-drain failure must not replace the provider error that
815
+ // put the wrapper into drain mode.
816
+ const error =
817
+ streamError !== undefined ? streamError : caughtError;
818
+ // Error-part runs complete normally inside the SDK, so nothing
819
+ // sets the root generation span failed — mark it here (the
820
+ // SDK's own thrown-error marking is guarded against below).
821
+ generationSpans?.markFailed(error);
822
+
823
+ const errorMessage =
824
+ error instanceof Error ? error.message : String(error);
825
+
826
+ // SDK RetryError can wrap a critical failure after a prior provider retry.
827
+ await getInferenceRecorder(opts)?.flush();
828
+
829
+ // Check context length FIRST — these should never be retried
830
+ // as-is; the prompt must be reduced via summarization.
831
+ const isCtxError =
832
+ error instanceof InStreamCompactionRequired ||
833
+ error instanceof CompactionRejectedError ||
834
+ checkIfContextLengthError(error);
835
+
836
+ // A latched persistence failure is terminal: retrying would
837
+ // dispatch a turn whose context was never durably committed.
838
+ if (
839
+ error instanceof RunPersistenceError ||
840
+ error instanceof RunLimitError ||
841
+ error instanceof RunControlInterruption
842
+ ) {
843
+ throw error;
844
+ }
845
+
846
+ // Handle stream idle timeout — resume from accumulated messages
847
+ if (
848
+ !isCtxError &&
849
+ isStreamIdleTimeoutError(error) &&
850
+ idleResumeCount < MAX_IDLE_RESUME_RETRIES &&
851
+ messagesContainer.current.length > 0
852
+ ) {
853
+ const nextIdleCount = idleResumeCount + 1;
854
+ await getInferenceRecorder(opts)?.retry({
855
+ authority: "stream-idle",
856
+ count: nextIdleCount,
857
+ maxRetries: MAX_IDLE_RESUME_RETRIES,
858
+ delayMs: 0,
859
+ });
860
+ // Surfaced on silent sub-agents too when stream-debugging.
861
+ if (!silent || STREAM_DEBUG) {
862
+ log.warn(
863
+ `Stream stalled (attempt ${nextIdleCount}/${MAX_IDLE_RESUME_RETRIES}), resuming with ${messagesContainer.current.length} messages: ${errorMessage}`,
864
+ );
865
+ }
866
+
867
+ const retriedStream = streamResponse({
868
+ ...opts,
869
+ messages: messagesContainer.current,
870
+ });
871
+
872
+ const wrappedRetriedStream = wrapStreamWithErrorHandler(
873
+ retriedStream,
874
+ messagesContainer,
875
+ opts,
876
+ model,
877
+ silent,
878
+ rateLimitRetryCount,
879
+ nextIdleCount,
880
+ );
881
+
882
+ for await (const chunk of wrappedRetriedStream.fullStream) {
883
+ yield chunk;
884
+ }
885
+ return;
886
+ }
887
+
888
+ // Handle rate limit errors with exponential backoff retry
889
+ if (
890
+ !isCtxError &&
891
+ checkIfRateLimitError(error) &&
892
+ rateLimitRetryCount < MAX_RATE_LIMIT_RETRIES
893
+ ) {
894
+ const nextRetryCount = rateLimitRetryCount + 1;
895
+ const delayMs = Math.min(1000 * nextRetryCount, 30000);
896
+ const recorder = getInferenceRecorder(opts);
897
+ await recorder?.retry({
898
+ authority: "stream-rate-limit",
899
+ count: nextRetryCount,
900
+ maxRetries: MAX_RATE_LIMIT_RETRIES,
901
+ delayMs,
902
+ });
903
+
904
+ if (!silent) {
905
+ log.warn(
906
+ `Rate limit error (attempt ${nextRetryCount}/${MAX_RATE_LIMIT_RETRIES}), waiting ${delayMs}ms: ${errorMessage}`,
907
+ );
908
+ }
909
+
910
+ if (recorder) {
911
+ await delay(delayMs, undefined, { signal: opts.abortSignal });
912
+ } else {
913
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
914
+ }
915
+
916
+ const retriedStream = streamResponse({
917
+ ...opts,
918
+ messages:
919
+ messagesContainer.current.length > 0
920
+ ? messagesContainer.current
921
+ : undefined,
922
+ });
923
+
924
+ const wrappedRetriedStream = wrapStreamWithErrorHandler(
925
+ retriedStream,
926
+ messagesContainer,
927
+ opts,
928
+ model,
929
+ silent,
930
+ nextRetryCount,
931
+ idleResumeCount,
932
+ );
933
+
934
+ for await (const chunk of wrappedRetriedStream.fullStream) {
935
+ yield chunk;
936
+ }
937
+ return;
938
+ }
939
+
940
+ if (isCtxError) {
941
+ let currentMessages: ModelMessage[] =
942
+ error instanceof InStreamCompactionRequired
943
+ ? error.fitted.messages
944
+ : messagesContainer.current;
945
+ if (!(error instanceof InStreamCompactionRequired)) {
946
+ try {
947
+ const response = await originalStream.response;
948
+ if (response.messages && response.messages.length > 0) {
949
+ currentMessages = response.messages as ModelMessage[];
950
+ }
951
+ } catch {
952
+ // Fall back to container messages.
953
+ }
954
+ }
955
+
956
+ const fitted =
957
+ error instanceof InStreamCompactionRequired
958
+ ? error.fitted
959
+ : fitMessagesToContext(currentMessages, {
960
+ contextWindow: getContextWindow(
961
+ opts.model,
962
+ opts.authConfig?.customProviders,
963
+ opts.authConfig?.hoonifyModels,
964
+ ),
965
+ maxOutputTokens: getMaxOutputTokens(
966
+ opts.model,
967
+ opts.authConfig?.customProviders,
968
+ opts.authConfig?.hoonifyModels,
969
+ ),
970
+ system: applySequentialToolCallPolicy(
971
+ opts.system,
972
+ opts.tools,
973
+ opts.model,
974
+ ),
975
+ tools: opts.tools,
976
+ sessionPath: opts.sessionPath,
977
+ telemetry: {
978
+ trigger: "context_overflow",
979
+ model: opts.model,
980
+ sessionId: opts.sessionId,
981
+ restartDepth: opts._restartDepth,
982
+ previous: opts._compaction?.last,
983
+ },
984
+ });
985
+
986
+ if (fitted.compaction && opts._compaction)
987
+ opts._compaction.last = fitted.compaction;
988
+
989
+ messagesContainer.current = fitted.messages;
990
+
991
+ // Track depth across the reactive paths so that a failed
992
+ // Layer 1+2 retry CONTRIBUTES to the Layer 3 budget too.
993
+ // Without this, a failed retry's increment is "lost" on
994
+ // fall-through (Layer 3 reads outer `opts._restartDepth`,
995
+ // not the post-retry value) and recovery can burn close
996
+ // to double the intended provider calls before
997
+ // `MAX_RESTART_DEPTH` finally trips.
998
+ let postReactiveDepth = opts._restartDepth ?? 0;
999
+
1000
+ if (
1001
+ !(error instanceof CompactionRejectedError) &&
1002
+ fitted.fitsBudget &&
1003
+ fitted.modified
1004
+ ) {
1005
+ if (!silent) {
1006
+ log.warn(
1007
+ `Context length error — Layer 1+2 reduced to ~${fitted.estimatedInputTokens} tokens, retrying`,
1008
+ );
1009
+ }
1010
+ try {
1011
+ // Bump `_restartDepth` so a tokenizer-drift loop where
1012
+ // every reactive retry trips the same provider rejection
1013
+ // (fitsBudget=true by our estimator, still rejected by
1014
+ // the provider) eventually exhausts the depth bound at
1015
+ // the top of `streamResponse` instead of looping
1016
+ // forever. Without this, only Layer-3 escalation
1017
+ // increments depth and a drift-driven loop can burn
1018
+ // arbitrarily many failed provider calls.
1019
+ await recordContextRestart(postReactiveDepth + 1, opts);
1020
+ const retried = streamResponse({
1021
+ ...opts,
1022
+ messages: fitted.messages,
1023
+ _restartDepth: postReactiveDepth + 1,
1024
+ });
1025
+ const wrappedRetry = wrapStreamWithErrorHandler(
1026
+ retried,
1027
+ messagesContainer,
1028
+ opts,
1029
+ model,
1030
+ silent,
1031
+ rateLimitRetryCount,
1032
+ idleResumeCount,
1033
+ );
1034
+ for await (const chunk of wrappedRetry.fullStream) {
1035
+ yield chunk;
1036
+ }
1037
+ return;
1038
+ } catch (retryError) {
1039
+ // Always propagate the typed terminal error and
1040
+ // cancellations — these MUST escape the cascade
1041
+ // immediately. Currently `ContextLengthExhaustedError`
1042
+ // propagates only by accident (its message
1043
+ // "Context-length recovery exhausted…" uses a hyphen
1044
+ // that doesn't match any `checkIfContextLengthError`
1045
+ // pattern); the explicit `instanceof` and abort
1046
+ // checks are defensive against a future message-text
1047
+ // tweak that would otherwise silently swallow
1048
+ // recovery exhaustion. Mirrors the Layer 3
1049
+ // `summarizeError` catch below for symmetry.
1050
+ if (
1051
+ retryError instanceof ContextLengthExhaustedError ||
1052
+ (retryError instanceof Error &&
1053
+ retryError.name === "AbortError") ||
1054
+ opts.abortSignal?.aborted ||
1055
+ !checkIfContextLengthError(retryError)
1056
+ ) {
1057
+ throw retryError;
1058
+ }
1059
+ // Account for the depth slot the failed retry just
1060
+ // consumed so the Layer 3 paths below don't grant a
1061
+ // fresh budget on top of the already-spent cycle.
1062
+ postReactiveDepth += 1;
1063
+ }
1064
+ }
1065
+
1066
+ // Layer 3: full summarization. Wrapped because
1067
+ // `summarizeConversation` itself calls `generateText` and
1068
+ // can throw — fall back to a minimal-context restart.
1069
+ const messagesForSummary = messagesContainer.current;
1070
+ if (!silent) {
1071
+ log.warn(
1072
+ `Context length error — summarizing ${messagesForSummary.length} messages`,
1073
+ );
1074
+ }
1075
+
1076
+ try {
1077
+ if (error instanceof CompactionRejectedError) throw error;
1078
+ const summarizationStream = createSummarizationStream(
1079
+ messagesForSummary,
1080
+ {
1081
+ ...opts,
1082
+ _restartDepth: postReactiveDepth,
1083
+ _compactionTrigger:
1084
+ error instanceof InStreamCompactionRequired
1085
+ ? "proactive"
1086
+ : "context_overflow",
1087
+ _proactiveSummaryMayFit:
1088
+ error instanceof InStreamCompactionRequired &&
1089
+ error.fitted.fitsBudget,
1090
+ },
1091
+ model,
1092
+ );
1093
+ for await (const chunk of summarizationStream.fullStream) {
1094
+ yield chunk;
1095
+ }
1096
+ } catch (summarizeError) {
1097
+ // Fall through to minimal restart for context or rejected-summary
1098
+ // errors. For everything else — auth failures, network
1099
+ // errors, abort signals, the typed terminal
1100
+ // `ContextLengthExhaustedError`, or non-`Error` throws —
1101
+ // propagate immediately. Without this, an aborted call
1102
+ // would spawn a new provider request, and a transient
1103
+ // auth failure would burn an extra cycle that fails
1104
+ // identically.
1105
+ if (
1106
+ summarizeError instanceof ContextLengthExhaustedError ||
1107
+ (summarizeError instanceof Error &&
1108
+ summarizeError.name === "AbortError") ||
1109
+ opts.abortSignal?.aborted ||
1110
+ !(
1111
+ checkIfContextLengthError(summarizeError) ||
1112
+ summarizeError instanceof CompactionRejectedError
1113
+ )
1114
+ ) {
1115
+ throw summarizeError;
1116
+ }
1117
+ if (!silent) {
1118
+ const sumMsg =
1119
+ summarizeError instanceof Error
1120
+ ? summarizeError.message
1121
+ : String(summarizeError);
1122
+ log.warn(
1123
+ `Layer 3 summarization failed (${sumMsg}). Falling back to minimal-context restart.`,
1124
+ );
1125
+ }
1126
+ opts.onSummarized?.("");
1127
+ const minimalPrompt =
1128
+ typeof opts.prompt === "string" && opts.prompt.length > 0
1129
+ ? opts.prompt.slice(0, 4_000)
1130
+ : MINIMAL_RESTART_PROMPT;
1131
+ const reset = beginCompaction("reset", {
1132
+ trigger: "summary_overflow",
1133
+ model: opts.model,
1134
+ sessionId: opts.sessionId,
1135
+ restartDepth: postReactiveDepth,
1136
+ previous: opts._compaction?.last,
1137
+ });
1138
+ reset?.capture("before", () => ({
1139
+ messages: messagesForSummary,
1140
+ system: opts.system,
1141
+ prompt: opts.prompt,
1142
+ }));
1143
+ reset?.measure(
1144
+ "before",
1145
+ () => estimateMessageTokens(messagesForSummary),
1146
+ messagesForSummary.length,
1147
+ );
1148
+ reset?.measure(
1149
+ "after",
1150
+ () =>
1151
+ estimateMessageTokens([
1152
+ { role: "user", content: minimalPrompt },
1153
+ ]),
1154
+ 1,
1155
+ );
1156
+ reset?.capture("after", () => ({
1157
+ messages: [{ role: "user", content: minimalPrompt }],
1158
+ system: opts.system,
1159
+ }));
1160
+ reset?.finish("completed");
1161
+ if (reset && opts._compaction)
1162
+ opts._compaction.last = reset.link;
1163
+ await recordContextRestart(postReactiveDepth + 1, opts);
1164
+ const fallback = streamResponse({
1165
+ ...opts,
1166
+ prompt: minimalPrompt,
1167
+ messages: undefined,
1168
+ _restartDepth: postReactiveDepth + 1,
1169
+ });
1170
+ for await (const chunk of fallback.fullStream) {
1171
+ yield chunk;
1172
+ }
1173
+ }
1174
+ } else {
1175
+ if (!silent) {
1176
+ log.error("Non-recoverable stream error, re-throwing", {
1177
+ error: errorMessage,
1178
+ });
1179
+ }
1180
+ throw error;
1181
+ }
1182
+ }
1183
+ })();
1184
+ }
1185
+ return wrappedStream;
1186
+ }
1187
+
1188
+ // For all other properties, return the original
1189
+ return (originalStream as unknown as Record<string | symbol, unknown>)[
1190
+ prop
1191
+ ];
1192
+ },
1193
+ };
1194
+
1195
+ return new Proxy(originalStream, handler);
1196
+ }
1197
+
1198
+ // Available models with names
1199
+ export interface ModelInfo {
1200
+ id: AIModel;
1201
+ name: string;
1202
+ provider: AIModelProvider;
1203
+ contextLength?: number;
1204
+ }
1205
+
1206
+ export function modelRequiresThinking(modelId: string): boolean {
1207
+ return getClaudeCapabilities(modelId)?.alwaysOnThinking ?? false;
1208
+ }
1209
+
1210
+ /**
1211
+ * Check whether a model supports extended thinking based on its ID.
1212
+ *
1213
+ * Thinking is available on Claude 3.7 Sonnet and all Claude 4.x+ models
1214
+ * (Sonnet, Opus, Haiku 4.5). Works for Anthropic direct, Bedrock, and
1215
+ * Pensar provider IDs.
1216
+ */
1217
+ export function modelSupportsThinking(modelId: string): boolean {
1218
+ if (getClaudeCapabilities(modelId)) return true;
1219
+ // Normalize: strip provider prefixes so we match the base Claude model ID
1220
+ const normalized = modelId
1221
+ .replace(/^pensar:/, "")
1222
+ .replace(/^(us\.|eu\.|global\.|ap\.)?anthropic\./, "");
1223
+
1224
+ return (
1225
+ /^claude-3-7-sonnet/.test(normalized) ||
1226
+ /^claude-sonnet-4/.test(normalized) ||
1227
+ /^claude-opus-4/.test(normalized) ||
1228
+ /^claude-haiku-4-5/.test(normalized)
1229
+ );
1230
+ }
1231
+
1232
+ /**
1233
+ * Whether a model accepts the `adaptive` thinking type — Claude Opus 4.6+ and
1234
+ * Sonnet 4.6+. Pre-4.6 models (Opus 4.0–4.5, Sonnet 4.5, Haiku 4.5) support
1235
+ * extended thinking but reject `adaptive`, so we don't request thinking for
1236
+ * them at all.
1237
+ */
1238
+ export function modelSupportsAdaptiveThinking(modelId: string): boolean {
1239
+ if (getClaudeCapabilities(modelId)) return true;
1240
+ const normalized = modelId
1241
+ .replace(/^pensar:/, "")
1242
+ .replace(/^(us\.|eu\.|global\.|ap\.)?anthropic\./, "");
1243
+
1244
+ return (
1245
+ /^claude-sonnet-4-[6-9]/.test(normalized) ||
1246
+ /^claude-opus-4-[6-9]/.test(normalized)
1247
+ );
1248
+ }
1249
+
1250
+ export function modelSupportsOpenAIReasoning(modelId: string): boolean {
1251
+ if (modelId === CONCENTRATE_GLM_5_3_MODEL_ID) return true;
1252
+ const { provider } = getModelInfo(modelId);
1253
+ if (!["openai", "openrouter", "concentrate"].includes(provider)) return false;
1254
+ modelId = modelId.replace(/^(openai\/|concentrate:)/, "");
1255
+ return (
1256
+ OPENAI_REASONING_MODEL_IDS.has(modelId) || /^o[134](?:\b|-)/.test(modelId)
1257
+ );
1258
+ }
1259
+
1260
+ export function modelRequiresReasoning(modelId: string): boolean {
1261
+ return modelId === CONCENTRATE_GLM_5_3_MODEL_ID;
1262
+ }
1263
+
1264
+ export function getOpenAIReasoningEfforts(
1265
+ modelId: string,
1266
+ ): OpenAIReasoningEffort[] {
1267
+ if (!modelSupportsOpenAIReasoning(modelId)) return [];
1268
+ if (modelId === CONCENTRATE_GLM_5_3_MODEL_ID) {
1269
+ return ["low", "high", "max"];
1270
+ }
1271
+ if (/^concentrate:gpt-5\.4-(?:mini|nano)$/.test(modelId)) {
1272
+ return ["none", "low", "medium", "high"];
1273
+ }
1274
+ modelId = modelId.replace(/^(openai\/|concentrate:)/, "");
1275
+ if (modelId === "gpt-6-sol" || modelId === "gpt-6-luna") {
1276
+ return ["none", "low", "medium", "high", "xhigh", "max"];
1277
+ }
1278
+ if (/^gpt-6[.-]/.test(modelId)) {
1279
+ return ["low", "medium", "high", "xhigh", "max"];
1280
+ }
1281
+ if (/^gpt-5\.5-pro(?:-|$)/.test(modelId)) {
1282
+ return ["medium", "high", "xhigh"];
1283
+ }
1284
+ if (/^gpt-5\.4-(?:mini|nano)(?:-|$)/.test(modelId)) {
1285
+ return ["none", "low", "medium", "high", "xhigh"];
1286
+ }
1287
+ if (/^gpt-5\.6(?:\b|-)/.test(modelId)) {
1288
+ return ["low", "medium", "high", "xhigh", "max", "ultra"];
1289
+ }
1290
+ if (/^gpt-5\.5(?:\b|-)/.test(modelId)) {
1291
+ return ["none", "low", "medium", "high", "xhigh"];
1292
+ }
1293
+ return ["low", "medium", "high"];
1294
+ }
1295
+
1296
+ export function normalizeOpenAIReasoningEffort(
1297
+ modelId: string,
1298
+ effort?: OpenAIReasoningEffort | null,
1299
+ ): OpenAIReasoningEffort | undefined {
1300
+ if (modelId === CONCENTRATE_GLM_5_3_MODEL_ID) {
1301
+ switch (effort) {
1302
+ case "none":
1303
+ case "low":
1304
+ return "low";
1305
+ case "medium":
1306
+ case "high":
1307
+ return "high";
1308
+ case "xhigh":
1309
+ case "max":
1310
+ case "ultra":
1311
+ return "max";
1312
+ default:
1313
+ return "high";
1314
+ }
1315
+ }
1316
+ const efforts = getOpenAIReasoningEfforts(modelId);
1317
+ if (efforts.length === 0) return undefined;
1318
+ if (effort && efforts.includes(effort)) {
1319
+ // ponytail: OpenAI has no distinct ultra level; keep the UI choice as a max alias.
1320
+ return effort === "ultra" ? "max" : effort;
1321
+ }
1322
+ return DEFAULT_OPENAI_REASONING_EFFORT;
1323
+ }
1324
+
1325
+ /**
1326
+ * Provider-specific options passed to `streamText` to request reasoning /
1327
+ * extended thinking. Each provider reads only its own namespace:
1328
+ * - `anthropic.thinking` — direct Anthropic provider AND the Pensar gateway
1329
+ * (the gateway formatter maps it to the Bedrock `thinking` field).
1330
+ * - `bedrock.reasoningConfig` — the AWS Bedrock provider; it ignores the
1331
+ * `anthropic` namespace entirely, so Anthropic-on-Bedrock thinking is only
1332
+ * requested when this key is present. `display: 'summarized'` makes the
1333
+ * model actually return reasoning text (adaptive can otherwise omit it).
1334
+ * - `openai.reasoningEffort` — OpenAI/o-series reasoning models.
1335
+ */
1336
+ export type ReasoningProviderOptions = {
1337
+ openrouter?: {
1338
+ reasoning: { effort: OpenAIReasoningEffort; enabled?: boolean };
1339
+ };
1340
+ anthropic?: {
1341
+ thinking:
1342
+ | { type: "adaptive"; display?: "summarized" }
1343
+ | { type: "disabled" };
1344
+ // Soft effort hint for adaptive thinking; omitted when no level requested
1345
+ // (model defaults to "high"). Sibling of `thinking` per the AI SDK.
1346
+ effort?: ThinkingEffort;
1347
+ };
1348
+ bedrock?: {
1349
+ reasoningConfig:
1350
+ | {
1351
+ type: "adaptive";
1352
+ display: "summarized";
1353
+ // Bedrock's channel for the adaptive effort hint (maps to Claude's
1354
+ // output_config.effort).
1355
+ maxReasoningEffort?: ThinkingEffort;
1356
+ }
1357
+ | { type: "disabled" };
1358
+ /** Explicitly forwarded for Anthropic because the Bedrock SDK currently
1359
+ * drops reasoningConfig.type="disabled" instead of sending it. */
1360
+ additionalModelRequestFields?: {
1361
+ thinking: { type: "disabled" };
1362
+ };
1363
+ };
1364
+ openai?: OpenAIResponsesProviderOptions;
1365
+ };
1366
+
1367
+ export type OpenRouterProviderOptions = {
1368
+ openrouter?: {
1369
+ provider:
1370
+ | {
1371
+ only: ["z-ai"];
1372
+ allow_fallbacks: false;
1373
+ }
1374
+ | {
1375
+ order: ["z-ai"];
1376
+ allow_fallbacks: true;
1377
+ require_parameters: true;
1378
+ };
1379
+ };
1380
+ };
1381
+
1382
+ function isZaiPinnedModel(model: AIModel): boolean {
1383
+ return model === "z-ai/glm-5.2" || model === "z-ai/glm-5.3";
1384
+ }
1385
+
1386
+ export function buildOpenRouterProviderOptions(
1387
+ model: AIModel,
1388
+ ): OpenRouterProviderOptions | undefined {
1389
+ if (!isZaiPinnedModel(model)) return undefined;
1390
+ return {
1391
+ openrouter: {
1392
+ provider: {
1393
+ only: ["z-ai"],
1394
+ allow_fallbacks: false,
1395
+ },
1396
+ },
1397
+ };
1398
+ }
1399
+
1400
+ /**
1401
+ * Z.AI's endpoint is the only `z-ai/*` provider that does not advertise
1402
+ * `structured_outputs`, so under the hard pin above `response_format` is a soft
1403
+ * preference and nothing enforces the schema. Prefer Z.AI, but require an
1404
+ * endpoint that enforces it rather than silently returning unparseable output.
1405
+ */
1406
+ export function buildOpenRouterStructuredProviderOptions(
1407
+ model: AIModel,
1408
+ ): OpenRouterProviderOptions | undefined {
1409
+ if (!isZaiPinnedModel(model)) return undefined;
1410
+ return {
1411
+ openrouter: {
1412
+ provider: {
1413
+ order: ["z-ai"],
1414
+ allow_fallbacks: true,
1415
+ require_parameters: true,
1416
+ },
1417
+ },
1418
+ };
1419
+ }
1420
+
1421
+ /**
1422
+ * Build the `providerOptions` for a request based on the model and reasoning
1423
+ * settings. Returns `undefined` when no reasoning/thinking is requested.
1424
+ *
1425
+ * When thinking is enabled for an Anthropic-family model we set BOTH the
1426
+ * `anthropic` and `bedrock` keys: the resolved provider (direct Anthropic,
1427
+ * Pensar gateway, or Bedrock) reads only its own namespace and ignores the
1428
+ * other, so this is safe across all three and avoids brittle provider
1429
+ * branching here.
1430
+ */
1431
+ export function buildReasoningProviderOptions(
1432
+ model: AIModel,
1433
+ opts: {
1434
+ enableThinking?: boolean;
1435
+ /**
1436
+ * Adaptive-thinking effort hint for Anthropic models that support it
1437
+ * Ignored on models without adaptive support. When omitted, models in the
1438
+ * Claude capability registry use their documented provider default.
1439
+ */
1440
+ thinkingEffort?: ThinkingEffort | null;
1441
+ openAIReasoningEffort?: OpenAIReasoningEffort | null;
1442
+ },
1443
+ ): ReasoningProviderOptions | undefined {
1444
+ const claude = getClaudeCapabilities(model);
1445
+ if (claude) {
1446
+ const provider = getModelInfo(model).provider;
1447
+ const thinking = !!opts.enableThinking || claude.alwaysOnThinking;
1448
+ const effort = opts.thinkingEffort ?? claude.defaultEffort;
1449
+ if (provider === "openrouter") {
1450
+ return {
1451
+ openrouter: {
1452
+ reasoning: {
1453
+ effort: thinking ? effort : "none",
1454
+ enabled: thinking,
1455
+ },
1456
+ },
1457
+ };
1458
+ }
1459
+ if (provider === "concentrate") {
1460
+ return {
1461
+ openai: {
1462
+ forceReasoning: true,
1463
+ reasoningEffort: thinking ? effort : "none",
1464
+ reasoningSummary: "auto",
1465
+ },
1466
+ };
1467
+ }
1468
+ return {
1469
+ anthropic: {
1470
+ thinking: thinking
1471
+ ? { type: "adaptive", display: "summarized" }
1472
+ : { type: "disabled" },
1473
+ ...(thinking ? { effort } : {}),
1474
+ },
1475
+ ...(provider === "bedrock"
1476
+ ? {
1477
+ bedrock: {
1478
+ reasoningConfig: thinking
1479
+ ? {
1480
+ type: "adaptive" as const,
1481
+ display: "summarized" as const,
1482
+ maxReasoningEffort: effort,
1483
+ }
1484
+ : { type: "disabled" as const },
1485
+ ...(!thinking
1486
+ ? {
1487
+ additionalModelRequestFields: {
1488
+ thinking: { type: "disabled" as const },
1489
+ },
1490
+ }
1491
+ : {}),
1492
+ },
1493
+ }
1494
+ : {}),
1495
+ };
1496
+ }
1497
+ const useThinking =
1498
+ !!opts.enableThinking &&
1499
+ isAnthropicProvider(model) &&
1500
+ modelSupportsAdaptiveThinking(model);
1501
+ const normalizedOpenAIEffort = normalizeOpenAIReasoningEffort(
1502
+ model,
1503
+ opts.openAIReasoningEffort,
1504
+ );
1505
+ // The effort hint only rides along when adaptive thinking is actually used.
1506
+ const effort = useThinking ? (opts.thinkingEffort ?? undefined) : undefined;
1507
+
1508
+ if (!useThinking && !normalizedOpenAIEffort) return undefined;
1509
+
1510
+ if (getModelInfo(model).provider === "openrouter" && normalizedOpenAIEffort) {
1511
+ return { openrouter: { reasoning: { effort: normalizedOpenAIEffort } } };
1512
+ }
1513
+
1514
+ return {
1515
+ ...(useThinking
1516
+ ? {
1517
+ anthropic: {
1518
+ thinking: { type: "adaptive" as const },
1519
+ ...(effort ? { effort } : {}),
1520
+ },
1521
+ bedrock: {
1522
+ reasoningConfig: {
1523
+ type: "adaptive" as const,
1524
+ display: "summarized" as const,
1525
+ ...(effort ? { maxReasoningEffort: effort } : {}),
1526
+ },
1527
+ },
1528
+ }
1529
+ : {}),
1530
+ ...(normalizedOpenAIEffort
1531
+ ? { openai: { reasoningEffort: normalizedOpenAIEffort } }
1532
+ : {}),
1533
+ };
1534
+ }
1535
+
1536
+ /** Cache token metrics extracted from Anthropic providerMetadata */
1537
+ export interface CacheMetrics {
1538
+ cacheReadInputTokens: number;
1539
+ cacheCreationInputTokens: number;
1540
+ }
1541
+
1542
+ export interface StreamResponseOpts {
1543
+ prompt: string;
1544
+ system?: string;
1545
+ model: AIModel;
1546
+ messages?: Array<ModelMessage>;
1547
+ stopWhen?:
1548
+ | StopCondition<NoInfer<ToolSet>>
1549
+ | StopCondition<NoInfer<ToolSet>>[];
1550
+ toolChoice?: ToolChoice<ToolSet>;
1551
+ tools?: ToolSet;
1552
+ onStepFinish?: StreamTextOnStepFinishCallback<ToolSet>;
1553
+ /** Provider middleware applied only to this stream's model calls. */
1554
+ languageModelMiddleware?: LanguageModelMiddleware | LanguageModelMiddleware[];
1555
+ /** Explicit undefined clears an inherited recorder for an unrecorded child. */
1556
+ inferenceRecorder?: InferenceRecorder;
1557
+ /** Per-run usage recorder; when set it replaces the global usage callback for this stream. */
1558
+ usageRecorder?: UsageRecorder;
1559
+ abortSignal?: AbortSignal;
1560
+ activeTools?: string[];
1561
+ silent?: boolean;
1562
+ authConfig?: AIAuthConfig;
1563
+ onFinish?: StreamTextOnFinishCallback<ToolSet>;
1564
+ /**
1565
+ * Called when the context window overflows and the conversation is
1566
+ * summarized. Callers should use this to discard stale message history
1567
+ * so that subsequent persistence writes only include the summary +
1568
+ * new messages (not the full pre-summarization history).
1569
+ */
1570
+ onSummarized?: (summary: string) => void;
1571
+ /** The fitted context and prior generated-message count for transcript writers. */
1572
+ onContextPrepared?: (context: {
1573
+ messages: ModelMessage[];
1574
+ responseMessageOffset: number;
1575
+ }) => void;
1576
+ /**
1577
+ * Deprecated host shim: fires only when a cache counter is `> 0`.
1578
+ * Apex internals read cache from {@link normalizeStepUsage} on the step.
1579
+ */
1580
+ onCacheMetrics?: (metrics: CacheMetrics) => void;
1581
+ /** Enable extended thinking for supported models (Anthropic Claude 3.7+) */
1582
+ enableThinking?: boolean;
1583
+ /**
1584
+ * Adaptive-thinking effort hint for Anthropic models that support it
1585
+ * (Opus/Sonnet 4.6+). Ignored where unsupported; model defaults to `high`.
1586
+ */
1587
+ thinkingEffort?: ThinkingEffort | null;
1588
+ /** OpenAI reasoning effort for GPT/o-series reasoning models. */
1589
+ openAIReasoningEffort?: OpenAIReasoningEffort | null;
1590
+ /** Session root path — used by context management layers to persist truncated tool results */
1591
+ sessionPath?: string;
1592
+ /** Session id (`ses_…`) of the agent making this call; stamped onto AI-span telemetry so traces are filterable by session. */
1593
+ sessionId?: string;
1594
+ /**
1595
+ * Opt-in durable context authority for recorded runs. Turn-0 base and each
1596
+ * step's cumulative context are checkpointed before selection/dispatch;
1597
+ * unset → legacy behavior, no persistence.
1598
+ */
1599
+ contextRecorder?: RunContextRecorder;
1600
+ /**
1601
+ * Internal: recovery-recursion depth. Bumped at each summarize → resume
1602
+ * boundary; throws `ContextLengthExhaustedError` past `MAX_RESTART_DEPTH`.
1603
+ */
1604
+ _restartDepth?: number;
1605
+ /** Shared only by continuations of this stream, never across agents. */
1606
+ _compaction?: { last?: CompactionLink };
1607
+ _compactionTrigger?: CompactionTrigger;
1608
+ _proactiveSummaryMayFit?: boolean;
1609
+ _proactiveSummaryFailures?: number;
1610
+ }
1611
+
1612
+ const NATIVE_STREAM_RECOVERY = Symbol("native-stream-recovery");
1613
+
1614
+ interface NativeStreamRecovery {
1615
+ model: LanguageModel;
1616
+ run<T>(fn: () => T): T;
1617
+ }
1618
+
1619
+ type InternalStreamResponseOpts = StreamResponseOpts & {
1620
+ [NATIVE_STREAM_RECOVERY]?: NativeStreamRecovery;
1621
+ };
1622
+
1623
+ export function streamResponse(
1624
+ opts: StreamResponseOpts,
1625
+ ): StreamTextResult<ToolSet, never> {
1626
+ opts = { ...opts, inferenceRecorder: getInferenceRecorder(opts) };
1627
+ return runWithInferenceRecorder(opts.inferenceRecorder, () => {
1628
+ const recovery = (opts as InternalStreamResponseOpts)[
1629
+ NATIVE_STREAM_RECOVERY
1630
+ ];
1631
+ if (recovery) {
1632
+ return recovery.run(() => streamResponseWithinOperation(opts, recovery));
1633
+ }
1634
+ return streamResponseWithinOperation(opts);
1635
+ });
1636
+ }
1637
+
1638
+ function streamResponseWithinOperation(
1639
+ opts: StreamResponseOpts,
1640
+ nativeRecovery?: NativeStreamRecovery,
1641
+ ): StreamTextResult<ToolSet, never> {
1642
+ const compactionState = opts._compaction ?? {};
1643
+ // One effective tool selection per stream, before any fitting: proactive
1644
+ // fit, provider schemas, execution, repair, and every continuation path
1645
+ // below spread this same opts object, so they must all see the filtered
1646
+ // map. Re-entry is identity (`activeTools` already consumed).
1647
+ opts = {
1648
+ ...opts,
1649
+ _compaction: compactionState,
1650
+ // `activeTools` is authoritative for advertisement and execution: a tool
1651
+ // (including `response`) is exposed only when the caller lists it, so the
1652
+ // structured-output tool is included when listed and inert when omitted.
1653
+ ...resolveEffectiveTools(opts.tools, opts.activeTools),
1654
+ };
1655
+ // Bound recovery recursion (summarize → resume → overflow → …).
1656
+ const restartDepth = opts._restartDepth ?? 0;
1657
+ if (restartDepth > MAX_RESTART_DEPTH) {
1658
+ throw new ContextLengthExhaustedError(
1659
+ `Context-length recovery exhausted after ${restartDepth} restart cycles`,
1660
+ restartDepth,
1661
+ );
1662
+ }
1663
+
1664
+ const {
1665
+ prompt,
1666
+ system,
1667
+ model,
1668
+ messages,
1669
+ stopWhen,
1670
+ toolChoice,
1671
+ tools,
1672
+ onStepFinish: userOnStepFinish,
1673
+ languageModelMiddleware,
1674
+ usageRecorder,
1675
+ abortSignal,
1676
+ activeTools,
1677
+ silent,
1678
+ authConfig,
1679
+ onFinish,
1680
+ onCacheMetrics,
1681
+ enableThinking,
1682
+ thinkingEffort,
1683
+ openAIReasoningEffort,
1684
+ sessionId,
1685
+ sessionPath,
1686
+ contextRecorder,
1687
+ onContextPrepared,
1688
+ } = opts;
1689
+
1690
+ // response.messages accumulates generated steps after prepareStep rewrites
1691
+ // provider context. The offset prevents transcript writers from appending
1692
+ // older, pre-fit messages again.
1693
+ let recorderBase: ModelMessage[] | undefined;
1694
+ let responseMessageLength = 0;
1695
+ const estimatedOverheadTokens = estimateToolsOverheadTokens(tools) + 1_000;
1696
+ let preparedInputEstimateTokens = 0;
1697
+ let inputSafetyMarginTokens = 10_000;
1698
+
1699
+ // Wrap onStepFinish to fire cache metrics and the usage callback for every
1700
+ // step. Must be async so that callers returning a Promise (persistence,
1701
+ // issue queuing, or the usage callback itself) are fully awaited before
1702
+ // the AI SDK starts the next step. One normalization feeds both sinks —
1703
+ // provider metadata is never parsed twice.
1704
+ const onStepFinish: typeof userOnStepFinish = async (step) => {
1705
+ const stepUsage = normalizeStepUsage(step);
1706
+ if (
1707
+ preparedInputEstimateTokens > 0 &&
1708
+ stepUsage.inputTokens > 0 &&
1709
+ step.response?.id !== "summarization" &&
1710
+ step.response?.id !== "tool-repair"
1711
+ ) {
1712
+ // Fixed system and tool overhead is already reserved by the fitter; calibrate only the remaining tokenization gap.
1713
+ inputSafetyMarginTokens = Math.max(
1714
+ inputSafetyMarginTokens,
1715
+ stepUsage.inputTokens - preparedInputEstimateTokens + 10_000,
1716
+ );
1717
+ }
1718
+ // Canonical commit precedes every downstream use; the recorder latches
1719
+ // rejections (SDK notify() swallows them) until the next turn gate or
1720
+ // agent-side flush turns the latch into a stream failure.
1721
+ // Synthetic summarization/tool-repair events re-report context that
1722
+ // already includes the base (messagesContainer.current) — committing
1723
+ // them would duplicate the prefix.
1724
+ if (
1725
+ contextRecorder &&
1726
+ step.response.id !== "summarization" &&
1727
+ step.response.id !== "tool-repair"
1728
+ ) {
1729
+ if (!recorderBase) {
1730
+ throw new Error("context recorder active without a committed base");
1731
+ }
1732
+ await contextRecorder.checkpoint({
1733
+ messages: [
1734
+ ...recorderBase,
1735
+ ...step.response.messages.slice(responseMessageLength),
1736
+ ],
1737
+ system: effectiveSystem ?? null,
1738
+ });
1739
+ }
1740
+ if (
1741
+ step.response?.id !== "summarization" &&
1742
+ step.response?.id !== "tool-repair" &&
1743
+ step.response?.messages
1744
+ ) {
1745
+ responseMessageLength = step.response.messages.length;
1746
+ }
1747
+ if (
1748
+ onCacheMetrics &&
1749
+ (stepUsage.cacheReadTokens > 0 || stepUsage.cacheWriteTokens > 0)
1750
+ ) {
1751
+ await onCacheMetrics({
1752
+ cacheReadInputTokens: stepUsage.cacheReadTokens,
1753
+ cacheCreationInputTokens: stepUsage.cacheWriteTokens,
1754
+ });
1755
+ }
1756
+ await userOnStepFinish?.(step);
1757
+ await emitUsage(model, stepUsage, resolveUsageSink(usageRecorder));
1758
+ };
1759
+ const providerModel =
1760
+ nativeRecovery?.model ??
1761
+ (() => {
1762
+ const baseProviderModel = withNativeRolloutEvidenceModel(
1763
+ withModelCallDiagnostics(getProviderModel(model, authConfig)),
1764
+ {
1765
+ requestedModelId: model,
1766
+ operationKind: "agent.stream",
1767
+ sessionId,
1768
+ },
1769
+ );
1770
+ return languageModelMiddleware
1771
+ ? wrapLanguageModel({
1772
+ model: baseProviderModel,
1773
+ middleware: languageModelMiddleware,
1774
+ })
1775
+ : baseProviderModel;
1776
+ })();
1777
+ // Undefined when the model has no cache breakpoint we can express (non-Claude
1778
+ // Bedrock models, OpenAI/Google/OpenRouter) — those run uncached.
1779
+ const cacheBreakpoint = cacheBreakpointFor(model);
1780
+
1781
+ // Models that mis-parse multiple tool calls per turn (DeepSeek V3.1 on
1782
+ // Bedrock) are constrained to one tool call per turn via system prompt —
1783
+ // single calls parse correctly, parallel calls drop/empty arguments. Only
1784
+ // applied when tools are actually bound. See prefersSequentialToolCalls.
1785
+ // Computed before context fitting so token budgeting accounts for the
1786
+ // appended instruction that is actually sent to the provider.
1787
+ const systemWithToolPolicy = applySequentialToolCallPolicy(
1788
+ system,
1789
+ tools,
1790
+ model,
1791
+ );
1792
+
1793
+ const contextWindow = getContextWindow(
1794
+ model,
1795
+ authConfig?.customProviders,
1796
+ authConfig?.hoonifyModels,
1797
+ );
1798
+ const maxOutputTokens = getMaxOutputTokens(
1799
+ model,
1800
+ authConfig?.customProviders,
1801
+ authConfig?.hoonifyModels,
1802
+ );
1803
+ if (
1804
+ messages &&
1805
+ !opts._proactiveSummaryFailures &&
1806
+ shouldSummarizeBeforeFitting(
1807
+ messages,
1808
+ contextWindow,
1809
+ maxOutputTokens,
1810
+ estimatedOverheadTokens,
1811
+ inputSafetyMarginTokens,
1812
+ systemWithToolPolicy,
1813
+ toolChoice,
1814
+ )
1815
+ ) {
1816
+ return wrapStreamWithErrorHandler(
1817
+ createSummarizationStream(
1818
+ messages,
1819
+ {
1820
+ ...opts,
1821
+ _compactionTrigger: "proactive",
1822
+ _proactiveSummaryMayFit: true,
1823
+ },
1824
+ providerModel,
1825
+ ),
1826
+ { current: messages },
1827
+ opts,
1828
+ providerModel,
1829
+ silent,
1830
+ );
1831
+ }
1832
+
1833
+ // Proactive context fit: compact before the call. Reactive recovery
1834
+ // below is a safety net for tokenizer drift the estimate doesn't catch.
1835
+ let fittedMessages = messages;
1836
+ let proactiveFitFailed = false;
1837
+ if (messages && messages.length > 0) {
1838
+ const fitted = fitMessagesToContext(messages, {
1839
+ contextWindow,
1840
+ maxOutputTokens,
1841
+ system: systemWithToolPolicy,
1842
+ tools,
1843
+ sessionPath: opts.sessionPath,
1844
+ telemetry: {
1845
+ trigger: "proactive",
1846
+ model,
1847
+ sessionId,
1848
+ restartDepth,
1849
+ previous: opts._compaction?.last,
1850
+ },
1851
+ });
1852
+ if (fitted.compaction) compactionState.last = fitted.compaction;
1853
+ fittedMessages = fitted.messages;
1854
+ proactiveFitFailed = !fitted.fitsBudget;
1855
+ if (fitted.modified && !silent) {
1856
+ log.warn(
1857
+ `Proactive context fit: compacted messages to ~${fitted.estimatedInputTokens} tokens (fits=${fitted.fitsBudget})`,
1858
+ );
1859
+ }
1860
+ }
1861
+
1862
+ // Container reference is stable; value gets reassigned by `prepareStep`
1863
+ // and the recovery paths so nested retries read the latest compacted view.
1864
+ const messagesContainer = { current: fittedMessages || [] };
1865
+
1866
+ // Layer 1+2 alone can't fit — escalate before sending a doomed request.
1867
+ // Wrap with the same error handler the streamText path uses, otherwise
1868
+ // an overflow inside the summarization call itself escapes uncaught while
1869
+ // the equivalent post-streamText path (line ~880) recovers.
1870
+ if (proactiveFitFailed && fittedMessages) {
1871
+ if (!silent) {
1872
+ log.warn(
1873
+ `Proactive context fit returned fitsBudget=false on ${fittedMessages.length} messages — escalating to summarization before send`,
1874
+ );
1875
+ }
1876
+ // Pass `opts` through unchanged. The slot for this escalation is
1877
+ // consumed by `summarizeConversation`'s internal `_restartDepth + 1`
1878
+ // bump on the resumed `streamResponse` call — pre-bumping here would
1879
+ // double-count vs the reactive Layer 3 path (which also passes
1880
+ // `opts._restartDepth` to `createSummarizationStream` after a
1881
+ // no-retry fall-through). With the post-bump, all three escalation
1882
+ // entry points (proactive, outer-catch, reactive Layer 3) consume
1883
+ // exactly one depth slot per summarization attempt — symmetric.
1884
+ return wrapStreamWithErrorHandler(
1885
+ createSummarizationStream(
1886
+ fittedMessages,
1887
+ {
1888
+ ...opts,
1889
+ _compactionTrigger: "proactive",
1890
+ _proactiveSummaryMayFit: false,
1891
+ },
1892
+ providerModel,
1893
+ ),
1894
+ messagesContainer,
1895
+ opts,
1896
+ providerModel,
1897
+ silent,
1898
+ );
1899
+ }
1900
+
1901
+ // For cacheable models, move the system prompt into messages behind a cache
1902
+ // breakpoint. This caches tools + system prompt across multi-turn
1903
+ // conversations (~90% cost reduction on cache hits).
1904
+ let effectiveSystem: string | undefined = systemWithToolPolicy;
1905
+ let effectiveMessages: ModelMessage[] | undefined = fittedMessages;
1906
+
1907
+ if (cacheBreakpoint && systemWithToolPolicy) {
1908
+ const baseMessages: ModelMessage[] = fittedMessages ?? [
1909
+ { role: "user" as const, content: prompt },
1910
+ ];
1911
+ effectiveMessages = withCachedSystemPrompt(
1912
+ systemWithToolPolicy,
1913
+ baseMessages,
1914
+ cacheBreakpoint,
1915
+ );
1916
+ effectiveSystem = undefined;
1917
+ }
1918
+
1919
+ // Build providerOptions for extended thinking when enabled on a supported model.
1920
+ // Caching uses message-level breakpoints (withCachedSystemPrompt / withCachedLastMessage),
1921
+ // not top-level providerOptions, so there is no collision.
1922
+ // Note: when thinking is enabled, temperature must not be set (Anthropic rejects it);
1923
+ // this path never sets temperature, so there is nothing to clear.
1924
+ const reasoningProviderOptions = buildReasoningProviderOptions(model, {
1925
+ enableThinking,
1926
+ thinkingEffort,
1927
+ openAIReasoningEffort,
1928
+ });
1929
+ const openRouterProviderOptions = buildOpenRouterProviderOptions(model);
1930
+ const providerOptions =
1931
+ reasoningProviderOptions || openRouterProviderOptions
1932
+ ? { ...reasoningProviderOptions, ...openRouterProviderOptions }
1933
+ : undefined;
1934
+
1935
+ let rateLimitRetryCount = 0;
1936
+
1937
+ // Make `activeTools` authoritative: advertise, execute, and enumerate only
1938
+ // the allowlisted tools. A no-op when `activeTools` is empty/undefined.
1939
+ // `resolveEffectiveTools` above already filtered the map and cleared
1940
+ // `activeTools`, so this is a no-op on the normal path; kept for callers that
1941
+ // reach streamText with an intact `activeTools` (identity when undefined).
1942
+ const allowedTools = withResponseToolActive(tools, activeTools);
1943
+ const effectiveTools = restrictToolsToActive(tools, allowedTools);
1944
+
1945
+ try {
1946
+ // Create the appropriate provider instance. The span tracker captures
1947
+ // the SDK's root generation span for error marking (see below).
1948
+ const generationSpans = createGenerationSpanTracker();
1949
+ const responseOptions: Parameters<typeof streamText>[0] = {
1950
+ model: providerModel,
1951
+ system: effectiveSystem,
1952
+ ...(effectiveMessages ? { messages: effectiveMessages } : { prompt }),
1953
+ stopWhen,
1954
+ toolChoice,
1955
+ tools: effectiveTools,
1956
+ maxRetries: 3,
1957
+ providerOptions,
1958
+ // Step history would retain a serialized request body per step, and
1959
+ // later steps re-send the whole conversation, so they accumulate.
1960
+ // Native capture reads the provider stream result, not this filter.
1961
+ experimental_include: { requestBody: false },
1962
+ // The forwarding tracer keeps a handle on the SDK's root generation
1963
+ // span: error-part runs complete normally in the SDK, so nothing
1964
+ // marks the span failed — the wrapper's catch does.
1965
+ experimental_telemetry: {
1966
+ ...createAiTelemetrySettings({
1967
+ operation: "apex.agent.stream",
1968
+ sessionId,
1969
+ compaction: opts._compaction?.last,
1970
+ }),
1971
+ tracer: generationSpans.tracer,
1972
+ },
1973
+ // Pin actual emission to the same value `fitMessagesToContext`
1974
+ // reserved for output. Without this, the SDK applies provider
1975
+ // defaults that can exceed our budget — e.g. GPT-4o defaults to
1976
+ // 16K output but our messages were sized assuming a smaller
1977
+ // reservation. Making the value explicit closes that drift class.
1978
+ maxOutputTokens: getMaxOutputTokens(
1979
+ model,
1980
+ authConfig?.customProviders,
1981
+ authConfig?.hoonifyModels,
1982
+ ),
1983
+ // Awaiting inside prepareStep keeps streamResponse synchronous; the
1984
+ // SDK awaits it before provider dispatch, so every turn and every
1985
+ // recovery re-entry commits before use.
1986
+ prepareStep: async (step) => {
1987
+ let stepMessages = step.messages;
1988
+ if (step.stepNumber > 0) {
1989
+ if (
1990
+ (opts._proactiveSummaryFailures ?? 0) <
1991
+ MAX_PROACTIVE_SUMMARY_FAILURES &&
1992
+ shouldSummarizeBeforeFitting(
1993
+ stepMessages,
1994
+ contextWindow,
1995
+ maxOutputTokens,
1996
+ estimatedOverheadTokens,
1997
+ inputSafetyMarginTokens,
1998
+ effectiveSystem,
1999
+ toolChoice,
2000
+ )
2001
+ ) {
2002
+ messagesContainer.current = stepMessages;
2003
+ throw new InStreamCompactionRequired({
2004
+ messages: stepMessages,
2005
+ estimatedInputTokens: estimateMessageTokens(stepMessages),
2006
+ modified: false,
2007
+ fitsBudget: true,
2008
+ });
2009
+ }
2010
+ const fitted = fitMessagesToContext(stepMessages, {
2011
+ contextWindow,
2012
+ maxOutputTokens,
2013
+ system: effectiveSystem,
2014
+ tools,
2015
+ overheadTokens: estimatedOverheadTokens,
2016
+ sessionPath,
2017
+ safetyMarginTokens: inputSafetyMarginTokens,
2018
+ telemetry: {
2019
+ trigger: "proactive",
2020
+ model,
2021
+ sessionId,
2022
+ restartDepth,
2023
+ previous: compactionState.last,
2024
+ },
2025
+ });
2026
+ if (fitted.compaction) compactionState.last = fitted.compaction;
2027
+ stepMessages = fitted.messages;
2028
+ if (!fitted.fitsBudget) {
2029
+ messagesContainer.current = stepMessages;
2030
+ throw new InStreamCompactionRequired(fitted);
2031
+ }
2032
+ }
2033
+ if (contextRecorder) {
2034
+ recorderBase = structuredClone(stepMessages);
2035
+ // Full logical context each turn — accepted step outputs must
2036
+ // survive into every later commit, and system is explicit (when
2037
+ // cached into messages, effectiveSystem is undefined → null).
2038
+ await contextRecorder.checkpoint({
2039
+ messages: stepMessages,
2040
+ system: effectiveSystem ?? null,
2041
+ });
2042
+ }
2043
+ // Update the container with the latest messages
2044
+ messagesContainer.current = stepMessages;
2045
+ preparedInputEstimateTokens =
2046
+ estimateMessageTokens(stepMessages) +
2047
+ estimatedOverheadTokens +
2048
+ (effectiveSystem ? estimateTokens(effectiveSystem) : 0);
2049
+ onContextPrepared?.({
2050
+ messages: stepMessages,
2051
+ responseMessageOffset: responseMessageLength,
2052
+ });
2053
+ // Mark the last message so the growing conversation caches incrementally
2054
+ if (cacheBreakpoint) {
2055
+ return {
2056
+ messages: withCachedLastMessage(stepMessages, cacheBreakpoint),
2057
+ };
2058
+ }
2059
+ return stepMessages === step.messages
2060
+ ? undefined
2061
+ : { messages: stepMessages };
2062
+ },
2063
+ onError: async ({ error }: { error: unknown }) => {
2064
+ // Never throw here: the SDK calls this inside its stream pipeline,
2065
+ // and a thrown callback kills the pipeline's terminal lifecycle —
2066
+ // the root generation span never ends and nothing exports. Return
2067
+ // normally instead; the error part continues downstream and the
2068
+ // consumption wrapper converts it to a thrown error (after the
2069
+ // tail drains), where the retry machinery takes over.
2070
+ const errorMessage =
2071
+ error instanceof Error ? error.message : String(error);
2072
+ if (
2073
+ errorMessage.toLowerCase().includes("too many tokens") ||
2074
+ errorMessage.toLowerCase().includes("overloaded")
2075
+ ) {
2076
+ rateLimitRetryCount++;
2077
+ if (getInferenceRecorder(opts)) {
2078
+ // This SDK callback must not throw, including when cancellation ends its wait.
2079
+ await delay(1000 * rateLimitRetryCount, undefined, {
2080
+ signal: abortSignal,
2081
+ }).catch(() => {});
2082
+ } else {
2083
+ await new Promise((resolve) =>
2084
+ setTimeout(resolve, 1000 * rateLimitRetryCount),
2085
+ );
2086
+ }
2087
+ }
2088
+ },
2089
+ onStepFinish,
2090
+ abortSignal,
2091
+ activeTools: allowedTools,
2092
+ experimental_repairToolCall: async ({
2093
+ toolCall,
2094
+ inputSchema,
2095
+ tools,
2096
+ error,
2097
+ }) => {
2098
+ // [response-debug] Log when repair fires for `response` (streamed args failed Zod validation), bypassing `silent`.
2099
+ if (RESPONSE_DEBUG && toolCall.toolName === RESPONSE_TOOL_NAME) {
2100
+ const raw = toolCall.input;
2101
+ const rawLen =
2102
+ typeof raw === "string" ? raw.length : JSON.stringify(raw).length;
2103
+ log.warn(
2104
+ `[response-debug] experimental_repairToolCall FIRED for response ` +
2105
+ `rawInputChars=${rawLen} error=${(error.message || String(error)).slice(0, 200)}`,
2106
+ );
2107
+ }
2108
+
2109
+ // Fail closed for security-sensitive tools: never let repair invent or
2110
+ // replace arguments (e.g. a spawn `target`). Returning null drops the
2111
+ // invalid call instead of executing a model-synthesized one.
2112
+ if (isRepairFailClosedTool(toolCall.toolName)) {
2113
+ if (!silent) {
2114
+ log.warn(
2115
+ `Tool-call repair disabled for security-sensitive tool "${toolCall.toolName}" — failing closed (no argument synthesis).`,
2116
+ );
2117
+ }
2118
+ return null;
2119
+ }
2120
+
2121
+ try {
2122
+ if (!silent) {
2123
+ log.debug(`Repairing tool call: ${toolCall.toolName}`, {
2124
+ error: error.message || String(error),
2125
+ });
2126
+
2127
+ // Log specific details for common enum errors
2128
+ if (
2129
+ error.message &&
2130
+ (error.message.includes("severity") ||
2131
+ error.message.includes("riskLevel"))
2132
+ ) {
2133
+ log.debug(
2134
+ "Enum validation error — tool call repair will normalize the value",
2135
+ );
2136
+ }
2137
+ }
2138
+
2139
+ // Get the actual tool definition which contains the Zod schema
2140
+ const tool = tools[toolCall.toolName];
2141
+ if (!tool?.inputSchema) {
2142
+ if (!silent) {
2143
+ log.warn(
2144
+ `Cannot repair tool call: ${toolCall.toolName} not found or has no schema`,
2145
+ );
2146
+ }
2147
+ return null;
2148
+ }
2149
+
2150
+ const jsonSchema = inputSchema({ toolName: toolCall.toolName });
2151
+
2152
+ // Bound input + schema so the repair call can't itself overflow.
2153
+ const rawInput = toolCall.input;
2154
+ const inputAsText =
2155
+ typeof rawInput === "string" ? rawInput : JSON.stringify(rawInput);
2156
+ const boundedInput = truncateWithMarker(
2157
+ inputAsText,
2158
+ MAX_TOOL_INPUT_CHARS,
2159
+ );
2160
+ const boundedSchema = truncateWithMarker(
2161
+ JSON.stringify(jsonSchema),
2162
+ MAX_SCHEMA_CHARS,
2163
+ "schema",
2164
+ );
2165
+
2166
+ const {
2167
+ output: repairedArgs,
2168
+ usage: repairUsage,
2169
+ providerMetadata: repairProviderMetadata,
2170
+ } = await runWithNativeRolloutOperation(
2171
+ { operationKind: "tool.repair", sessionId },
2172
+ () =>
2173
+ generateText({
2174
+ model: providerModel,
2175
+ providerOptions: {
2176
+ ...openRouterProviderOptions,
2177
+ // Durable runtime: tool-call repair fires only when a
2178
+ // replayed tool call fails validation — nondeterministically
2179
+ // vs the first run — so it must stay off the checkpoint
2180
+ // journal. The agent-runtime middleware reads this namespace
2181
+ // and runs the call without a durable step; the underlying
2182
+ // provider ignores it.
2183
+ pensarRuntime: { ephemeral: true },
2184
+ },
2185
+ output: Output.object({
2186
+ schema: tool.inputSchema, // Use the actual Zod schema from the tool
2187
+ }),
2188
+ prompt: [
2189
+ `The model tried to call the tool "${toolCall.toolName}"` +
2190
+ ` with the following inputs:`,
2191
+ boundedInput,
2192
+ `The tool accepts the following schema:`,
2193
+ boundedSchema,
2194
+ `Error encountered: ${error}`,
2195
+ "Please fix the inputs to match the schema.",
2196
+ "",
2197
+ "IMPORTANT: For enum fields like 'severity' or 'riskLevel', use ONLY the exact values from the enum (e.g., 'HIGH', 'CRITICAL', 'MEDIUM', 'LOW').",
2198
+ "Do not add prefixes, suffixes, or formatting characters like '>', '-', '!', etc.",
2199
+ ].join("\n"),
2200
+ abortSignal,
2201
+ experimental_telemetry: createAiTelemetrySettings({
2202
+ operation: "apex.tool.repair",
2203
+ sessionId,
2204
+ }),
2205
+ }),
2206
+ );
2207
+
2208
+ // Report tool repair token usage if onStepFinish callback is
2209
+ // provided. Awaited: the callback persists messages and records
2210
+ // usage — a detached invocation would leak unhandled rejections
2211
+ // into the tool loop. Provider metadata and cache details flow
2212
+ // through so repair usage stays attributable.
2213
+ if (onStepFinish && repairUsage) {
2214
+ try {
2215
+ await onStepFinish({
2216
+ text: "",
2217
+ reasoning: undefined,
2218
+ reasoningDetails: [],
2219
+ files: [],
2220
+ sources: [],
2221
+ toolCalls: [],
2222
+ toolResults: [],
2223
+ finishReason: "stop",
2224
+ usage: {
2225
+ inputTokens: repairUsage.inputTokens ?? 0,
2226
+ outputTokens: repairUsage.outputTokens ?? 0,
2227
+ totalTokens: repairUsage.totalTokens ?? 0,
2228
+ ...(repairUsage.inputTokenDetails
2229
+ ? { inputTokenDetails: repairUsage.inputTokenDetails }
2230
+ : {}),
2231
+ },
2232
+ warnings: [],
2233
+ request: {},
2234
+ response: {
2235
+ id: "tool-repair",
2236
+ timestamp: new Date(),
2237
+ modelId: "",
2238
+ messages: messagesContainer.current,
2239
+ },
2240
+ providerMetadata: repairProviderMetadata,
2241
+ stepType: "initial",
2242
+ isContinued: false,
2243
+ } as unknown as Parameters<
2244
+ StreamTextOnStepFinishCallback<ToolSet>
2245
+ >[0]);
2246
+ } catch (callbackError) {
2247
+ if (!silent) {
2248
+ log.warn("Error reporting tool repair usage", {
2249
+ error: String(callbackError),
2250
+ });
2251
+ }
2252
+ }
2253
+ }
2254
+
2255
+ if (repairedArgs === undefined || repairedArgs === null) {
2256
+ if (!silent) {
2257
+ log.warn(
2258
+ `Tool call repair for "${toolCall.toolName}" produced no valid output`,
2259
+ );
2260
+ }
2261
+ return null;
2262
+ }
2263
+ return { ...toolCall, input: JSON.stringify(repairedArgs) };
2264
+ } catch (repairError) {
2265
+ if (!silent) {
2266
+ log.warn("Error repairing tool call", {
2267
+ error: String(repairError),
2268
+ });
2269
+ }
2270
+ return null;
2271
+ }
2272
+ },
2273
+ onFinish,
2274
+ };
2275
+ let recovery = nativeRecovery;
2276
+ const response = recovery
2277
+ ? streamText(responseOptions)
2278
+ : runWithNativeRolloutOperation(
2279
+ { operationKind: "agent.stream", sessionId },
2280
+ () => {
2281
+ const operation = new AsyncResource("apex.native-stream-recovery");
2282
+ recovery = {
2283
+ model: providerModel,
2284
+ run: (fn) => operation.runInAsyncScope(fn),
2285
+ };
2286
+ return streamText(responseOptions);
2287
+ },
2288
+ );
2289
+
2290
+ // Wrap the stream to catch async errors during consumption
2291
+ const recoveryOpts: InternalStreamResponseOpts = recovery
2292
+ ? { ...opts, [NATIVE_STREAM_RECOVERY]: recovery }
2293
+ : opts;
2294
+ return wrapStreamWithErrorHandler(
2295
+ response,
2296
+ messagesContainer,
2297
+ recoveryOpts,
2298
+ providerModel,
2299
+ silent,
2300
+ 0,
2301
+ 0,
2302
+ generationSpans,
2303
+ );
2304
+ } catch (error) {
2305
+ // Check if the error is related to context length
2306
+ const isContextLengthError = checkIfContextLengthError(error);
2307
+ const outerErrorMessage =
2308
+ error instanceof Error ? error.message : String(error);
2309
+
2310
+ if (isContextLengthError) {
2311
+ if (!silent) {
2312
+ log.warn(
2313
+ `Context length error, summarizing ${messagesContainer.current.length} messages`,
2314
+ { error: outerErrorMessage },
2315
+ );
2316
+ }
2317
+ // Wrap so a context error inside the summarization stream itself
2318
+ // (or the resumed `streamResponse` it triggers) is caught and routed
2319
+ // through the same recovery cascade as the proactive and reactive
2320
+ // paths — invariant I4: every context-recovery failure must be caught
2321
+ // at the `streamResponse` boundary, never escape raw to the consumer.
2322
+ //
2323
+ // Pass `opts` through unchanged — the slot is consumed by
2324
+ // `summarizeConversation`'s internal `_restartDepth + 1` bump on
2325
+ // the resumed call. See the proactive escalation comment above
2326
+ // for the symmetry rationale.
2327
+ return wrapStreamWithErrorHandler(
2328
+ createSummarizationStream(
2329
+ messagesContainer.current,
2330
+ { ...opts, _compactionTrigger: "context_overflow" },
2331
+ providerModel,
2332
+ ),
2333
+ messagesContainer,
2334
+ opts,
2335
+ providerModel,
2336
+ silent,
2337
+ );
2338
+ }
2339
+ if (!silent) {
2340
+ log.error("Non-context length error, re-throwing", {
2341
+ error: outerErrorMessage,
2342
+ });
2343
+ }
2344
+
2345
+ // Re-throw if it's not a context length error
2346
+ throw error;
2347
+ }
2348
+ }
2349
+
2350
+ export interface GenerateObjectOpts<T extends z.ZodType> {
2351
+ model: AIModel;
2352
+ schema: T;
2353
+ prompt: string;
2354
+ system?: string;
2355
+ maxTokens?: number;
2356
+ temperature?: number;
2357
+ openAIReasoningEffort?: OpenAIReasoningEffort | null;
2358
+ authConfig?: AIAuthConfig;
2359
+ abortSignal?: AbortSignal;
2360
+ onTokenUsage?: (inputTokens: number, outputTokens: number) => void;
2361
+ /** Provider middleware applied only to this call's model. */
2362
+ languageModelMiddleware?: LanguageModelMiddleware | LanguageModelMiddleware[];
2363
+ /** Explicit undefined clears an inherited recorder for an unrecorded child. */
2364
+ inferenceRecorder?: InferenceRecorder;
2365
+ /** Per-run usage recorder; when set it replaces the global usage callback. */
2366
+ usageRecorder?: UsageRecorder;
2367
+ /** Session id (`ses_…`) of the caller — stamped onto AI-span telemetry. */
2368
+ sessionId?: string;
2369
+ /** Stable operation id; defaults to `apex.structured.generate`. */
2370
+ operation?: AiTelemetryOperation;
2371
+ }
2372
+
2373
+ const MAX_OBJECT_RATE_LIMIT_RETRIES = 8;
2374
+
2375
+ export async function generateObjectResponse<T extends z.ZodType>(
2376
+ opts: GenerateObjectOpts<T>,
2377
+ ): Promise<z.infer<T>> {
2378
+ opts = { ...opts, inferenceRecorder: getInferenceRecorder(opts) };
2379
+ return runWithInferenceRecorder(opts.inferenceRecorder, () =>
2380
+ generateObjectResponseWithinRecorder(opts),
2381
+ );
2382
+ }
2383
+
2384
+ async function generateObjectResponseWithinRecorder<T extends z.ZodType>(
2385
+ opts: GenerateObjectOpts<T>,
2386
+ ): Promise<z.infer<T>> {
2387
+ const {
2388
+ model,
2389
+ schema,
2390
+ prompt,
2391
+ system,
2392
+ maxTokens,
2393
+ temperature,
2394
+ openAIReasoningEffort,
2395
+ authConfig,
2396
+ abortSignal,
2397
+ onTokenUsage,
2398
+ languageModelMiddleware,
2399
+ usageRecorder,
2400
+ sessionId,
2401
+ } = opts;
2402
+
2403
+ const baseProviderModel = withNativeRolloutEvidenceModel(
2404
+ withModelCallDiagnostics(getProviderModel(model, authConfig)),
2405
+ {
2406
+ requestedModelId: model,
2407
+ operationKind: nativeRolloutOperation(opts.operation),
2408
+ sessionId,
2409
+ },
2410
+ );
2411
+ const providerModel = languageModelMiddleware
2412
+ ? wrapLanguageModel({
2413
+ model: baseProviderModel,
2414
+ middleware: languageModelMiddleware,
2415
+ })
2416
+ : baseProviderModel;
2417
+ const reasoningProviderOptions = buildReasoningProviderOptions(model, {
2418
+ openAIReasoningEffort,
2419
+ });
2420
+ const openRouterProviderOptions =
2421
+ buildOpenRouterStructuredProviderOptions(model);
2422
+
2423
+ return runWithNativeRolloutOperation(
2424
+ {
2425
+ operationKind: nativeRolloutOperation(opts.operation),
2426
+ sessionId,
2427
+ },
2428
+ async () => {
2429
+ let lastError: unknown;
2430
+
2431
+ for (
2432
+ let attempt = 0;
2433
+ attempt <= MAX_OBJECT_RATE_LIMIT_RETRIES;
2434
+ attempt++
2435
+ ) {
2436
+ try {
2437
+ const { output, usage, providerMetadata } = await generateText({
2438
+ model: providerModel,
2439
+ output: Output.object({
2440
+ schema,
2441
+ }),
2442
+ prompt,
2443
+ system,
2444
+ maxOutputTokens: maxTokens,
2445
+ temperature,
2446
+ providerOptions:
2447
+ reasoningProviderOptions || openRouterProviderOptions
2448
+ ? {
2449
+ ...reasoningProviderOptions,
2450
+ ...(openRouterProviderOptions
2451
+ ? {
2452
+ openrouter: {
2453
+ ...reasoningProviderOptions?.openrouter,
2454
+ ...openRouterProviderOptions.openrouter,
2455
+ },
2456
+ }
2457
+ : {}),
2458
+ }
2459
+ : undefined,
2460
+ maxRetries: 0,
2461
+ abortSignal,
2462
+ experimental_telemetry: createAiTelemetrySettings({
2463
+ operation: opts.operation ?? "apex.structured.generate",
2464
+ sessionId,
2465
+ }),
2466
+ });
2467
+
2468
+ if (onTokenUsage && usage) {
2469
+ onTokenUsage(usage.inputTokens ?? 0, usage.outputTokens ?? 0);
2470
+ }
2471
+
2472
+ if (usage) {
2473
+ await emitUsage(
2474
+ model,
2475
+ normalizeStepUsage({ usage, providerMetadata }),
2476
+ resolveUsageSink(usageRecorder),
2477
+ );
2478
+ }
2479
+
2480
+ // zod v4: the AI SDK's `Output.object` no longer carries the schema's
2481
+ // inferred type through `output` (it widens to `unknown`), so restore it
2482
+ // from the schema generic for callers.
2483
+ return output as z.infer<T>;
2484
+ } catch (error) {
2485
+ // Surface latched persistence/limit failures before any retry
2486
+ // classification — they are terminal, never delayed or retried.
2487
+ await getInferenceRecorder(opts)?.flush();
2488
+ if (
2489
+ error instanceof RunPersistenceError ||
2490
+ error instanceof RunLimitError ||
2491
+ error instanceof RunControlInterruption
2492
+ ) {
2493
+ throw error;
2494
+ }
2495
+ lastError = error;
2496
+
2497
+ if (checkIfContextLengthError(error)) {
2498
+ const msg = error instanceof Error ? error.message : String(error);
2499
+ throw new ContextLengthError(
2500
+ `Prompt exceeds model context window: ${msg}`,
2501
+ );
2502
+ }
2503
+
2504
+ if (
2505
+ checkIfRateLimitError(error) &&
2506
+ attempt < MAX_OBJECT_RATE_LIMIT_RETRIES
2507
+ ) {
2508
+ const delayMs = Math.min(1000 * 2 ** attempt, 60_000);
2509
+ const recorder = getInferenceRecorder(opts);
2510
+ await recorder?.retry({
2511
+ authority: "object-rate-limit",
2512
+ count: attempt + 1,
2513
+ maxRetries: MAX_OBJECT_RATE_LIMIT_RETRIES,
2514
+ delayMs,
2515
+ });
2516
+ if (recorder) {
2517
+ await delay(delayMs, undefined, { signal: abortSignal });
2518
+ } else {
2519
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
2520
+ }
2521
+ continue;
2522
+ }
2523
+
2524
+ throw error;
2525
+ }
2526
+ }
2527
+
2528
+ throw lastError;
2529
+ },
2530
+ );
2531
+ }
2532
+
2533
+ class ContextLengthError extends Error {
2534
+ constructor(message: string) {
2535
+ super(message);
2536
+ this.name = "ContextLengthError";
2537
+ }
2538
+ }
2539
+
2540
+ /**
2541
+ * Terminal: all recovery paths exhausted. The only context-length error
2542
+ * allowed to escape `streamResponse` — others are recoverable by design.
2543
+ */
2544
+ export class ContextLengthExhaustedError extends Error {
2545
+ readonly restartDepth: number;
2546
+ constructor(message: string, restartDepth: number) {
2547
+ super(message);
2548
+ this.name = "ContextLengthExhaustedError";
2549
+ this.restartDepth = restartDepth;
2550
+ }
2551
+ }
2552
+
2553
+ const MAX_RESTART_DEPTH = 3;
2554
+
2555
+ const MAX_TOOL_INPUT_CHARS = 8_000;
2556
+ const MAX_SCHEMA_CHARS = 6_000;
2557
+
2558
+ const MINIMAL_RESTART_PROMPT =
2559
+ "Continue the previous task. Earlier context was discarded due to repeated context-length errors.";
2560
+
2561
+ export {
2562
+ applySequentialToolCallPolicy,
2563
+ createToolExecutionGate,
2564
+ getStreamIdleTimeoutMs,
2565
+ SEQUENTIAL_TOOL_CALL_INSTRUCTION,
2566
+ StreamIdleTimeoutError,
2567
+ withIdleTimeout,
2568
+ };