@pensar/apex 2.5.0 → 2.6.1-canary.025b1ecf
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.
- package/README.md +38 -0
- package/bin/pensar.js +12 -4
- package/build/agent-b37fm1yh.js +13 -0
- package/build/{agent-m30a62kh.js → agent-f8rpt4sb.js} +48 -50
- package/build/agent-gqexqg2q.js +13 -0
- package/build/agent-qk30vqmf.js +15 -0
- package/build/agent-runs-nw7dwp1d.js +313 -0
- package/build/{apps-x4ef2gpc.js → apps-zeqbjbs4.js} +50 -58
- package/build/{auth-7ay8qgxm.js → auth-038hsg1s.js} +61 -68
- package/build/blackboxAgent-fjrv4q3d.js +13 -0
- package/build/blackboxPentest-6dtb7vnq.js +59 -0
- package/build/{cli-73k43t1r.js → cli-17ndymmb.js} +53 -78
- package/build/{cli-3py0a0wg.js → cli-1rwe9a9v.js} +206 -136
- package/build/{cli-y3dpm18e.js → cli-2tfnaeca.js} +75 -92
- package/build/{cli-ee3axgts.js → cli-3gt761d2.js} +7 -1
- package/build/cli-3qznjsnr.js +14 -0
- package/build/{cli-sx3jkv7p.js → cli-3w0mx2mv.js} +28872 -25951
- package/build/cli-5qq1655n.js +175 -0
- package/build/{cli-53rm0rrz.js → cli-8w8k4dph.js} +1 -1
- package/build/{cli-68260ckj.js → cli-91gs9whc.js} +1658 -1606
- package/build/cli-99gxp2yb.js +62 -0
- package/build/cli-ayqhdajr.js +22 -0
- package/build/{cli-knd276ed.js → cli-bb02pjt0.js} +31 -31
- package/build/{cli-p4r7q012.js → cli-bw31v3z7.js} +16743 -13352
- package/build/{cli-j54qa6tm.js → cli-c2k4xxaw.js} +42 -42
- package/build/{cli-z5c0ypg1.js → cli-czwr2xmh.js} +4 -4
- package/build/{cli-k71t434r.js → cli-ec2hwkv3.js} +34 -76
- package/build/{cli-vkbzcnw1.js → cli-fxmref08.js} +43 -40
- package/build/cli-g06s7edq.js +11 -0
- package/build/cli-gsaf4jk3.js +280 -0
- package/build/{cli-bc05qbss.js → cli-h6y3bt60.js} +13 -21
- package/build/cli-jdrx44ge.js +14 -0
- package/build/{cli-x92fkt2f.js → cli-m3btkdbx.js} +55 -97
- package/build/cli-mdk51kby.js +429 -0
- package/build/{cli-bw2ddttk.js → cli-mnpzhtg6.js} +4730 -267
- package/build/cli-mz5pk30x.js +5508 -0
- package/build/cli-pwm29ks7.js +6337 -0
- package/build/cli-retw3rw5.js +12 -0
- package/build/{cli-kff2bbq7.js → cli-rxj14t82.js} +43 -43
- package/build/cli-se8ae8z3.js +2250 -0
- package/build/cli-skedjgqy.js +186 -0
- package/build/{cli-dm0fc0bm.js → cli-v1sarr4y.js} +5 -9
- package/build/cli-vfzpbv3g.js +355 -0
- package/build/cli-xcy2vxj2.js +1732 -0
- package/build/{cli-zav1yx5k.js → cli-yn4sj3z1.js} +990 -632
- package/build/{cli-7vg06q5r.js → cli-zsq8kfgc.js} +135 -125
- package/build/cli.js +769 -195
- package/build/{config-4kzh88xz.js → config-4emx9c35.js} +16 -19
- package/build/{doctor-rz7sx6ev.js → doctor-z94afr10.js} +26 -15
- package/build/export-trajectory-rt4tf07k.js +112 -0
- package/build/{fastStrike-a54atjc8.js → fastStrike-mnn8g4ay.js} +56 -31
- package/build/{fixes-fv66yn1z.js → fixes-hm5569vq.js} +22 -30
- package/build/{getMachineId-bsd-xj3bn2fv.js → getMachineId-bsd-zr67nd9p.js} +5 -5
- package/build/{getMachineId-darwin-07jzjcx6.js → getMachineId-darwin-fd1d562d.js} +5 -5
- package/build/{getMachineId-linux-ahngynxd.js → getMachineId-linux-kjmg243j.js} +4 -4
- package/build/{getMachineId-unsupported-vy43b44z.js → getMachineId-unsupported-n4r58vke.js} +4 -4
- package/build/{getMachineId-win-8x66cynz.js → getMachineId-win-yzgpfsrb.js} +5 -5
- package/build/index-0yfxwj9h.js +25 -0
- package/build/{index-kyd1jm89.js → index-1qjwwg4x.js} +159 -169
- package/build/index-939ypn8a.js +12 -0
- package/build/index-a0bxw5zq.js +17477 -0
- package/build/{index-cbwn03kz.js → index-a2xycbjs.js} +12 -31
- package/build/{index-psqjpw5m.js → index-c1h0g35p.js} +11 -11
- package/build/{index-fpwr10qm.js → index-f2xpfw4x.js} +5106 -3803
- package/build/index-g9akqryt.js +9 -0
- package/build/index-mrrfbsyz.js +17 -0
- package/build/index-qnyevb6q.js +1563 -0
- package/build/index-ttwhf2se.js +36 -0
- package/build/index-vy2pm5zf.js +121 -0
- package/build/index-x8ab8x86.js +102 -0
- package/build/{issues-019678t0.js → issues-wxd3ca1d.js} +51 -47
- package/build/knowledge-rvcpbak8.js +139 -0
- package/build/lib/chunk-0y40tebt.js +102 -0
- package/build/lib/chunk-0ydfy4hq.js +510 -0
- package/build/lib/chunk-2njv7wz3.js +178 -0
- package/build/lib/chunk-3q89v4xv.js +21 -0
- package/build/lib/chunk-4p2n69vn.js +62 -0
- package/build/lib/chunk-7gjdygcx.js +171 -0
- package/build/lib/chunk-8d8w07a9.js +431 -0
- package/build/lib/chunk-8dqz8cwa.js +27 -0
- package/build/lib/chunk-8vhr65w3.js +272 -0
- package/build/lib/chunk-8xnzgfs0.js +56 -0
- package/build/lib/chunk-9nsrd4xg.js +12 -0
- package/build/lib/chunk-a3gxgj9r.js +317 -0
- package/build/lib/chunk-afef65e0.js +7150 -0
- package/build/lib/chunk-b8eq85d2.js +143 -0
- package/build/lib/chunk-bqrmw2tn.js +439 -0
- package/build/lib/chunk-bx94rwt5.js +24 -0
- package/build/lib/chunk-c2b0hxs7.js +143 -0
- package/build/lib/chunk-cwj17b1f.js +345 -0
- package/build/lib/chunk-cx7yrzh1.js +2429 -0
- package/build/lib/chunk-eb4h4k1f.js +213 -0
- package/build/lib/chunk-esymacwg.js +14 -0
- package/build/lib/chunk-fy3bbbqy.js +7896 -0
- package/build/lib/chunk-gdrv2h1p.js +11157 -0
- package/build/lib/chunk-ja7j565c.js +743 -0
- package/build/lib/chunk-jdjagvgr.js +85 -0
- package/build/lib/chunk-k4rz1yvj.js +31 -0
- package/build/lib/chunk-kfvq4m1s.js +685 -0
- package/build/lib/chunk-mgppdr6j.js +980 -0
- package/build/lib/chunk-mhxe717m.js +572 -0
- package/build/lib/chunk-mv74mq5n.js +59 -0
- package/build/lib/chunk-n0ba7khr.js +64 -0
- package/build/lib/chunk-q5e23acz.js +52 -0
- package/build/lib/chunk-q8bk9dys.js +922 -0
- package/build/lib/chunk-sgd2126b.js +9294 -0
- package/build/lib/chunk-t5bt5vn1.js +146 -0
- package/build/lib/chunk-v2q8anzw.js +120 -0
- package/build/lib/chunk-vd6hr8pm.js +212 -0
- package/build/lib/chunk-ve7m90fb.js +317 -0
- package/build/lib/chunk-vx228eeq.js +82 -0
- package/build/lib/chunk-wchtd611.js +186 -0
- package/build/lib/chunk-ws86wx87.js +1412 -0
- package/build/lib/chunk-xpfg2fbk.js +90 -0
- package/build/lib/chunk-zrbqn62x.js +697 -0
- package/build/lib/core/agents/agentRuntime.d.ts +47 -0
- package/build/lib/core/agents/defineAgent.d.ts +82 -0
- package/build/lib/core/agents/offSecAgent/index.d.ts +9 -0
- package/build/lib/core/agents/offSecAgent/index.js +225 -0
- package/build/lib/core/agents/offSecAgent/interruptedStepFinalization.d.ts +23 -0
- package/build/lib/core/agents/offSecAgent/interruptedStepMessages.d.ts +42 -0
- package/build/lib/core/agents/offSecAgent/messagePersistence.d.ts +39 -0
- package/build/lib/core/agents/offSecAgent/offensiveSecurityAgent.d.ts +233 -0
- package/build/lib/core/agents/offSecAgent/prompt.d.ts +35 -0
- package/build/lib/core/agents/offSecAgent/recordedTools.d.ts +11 -0
- package/build/lib/core/agents/offSecAgent/runtimeContext.d.ts +43 -0
- package/build/lib/core/agents/offSecAgent/streamDiagnostics.d.ts +67 -0
- package/build/lib/core/agents/offSecAgent/subagentSpawner.d.ts +223 -0
- package/build/lib/core/agents/offSecAgent/subagentSpawner.js +19 -0
- package/build/lib/core/agents/offSecAgent/toolLifecycle.d.ts +54 -0
- package/build/lib/core/agents/offSecAgent/tools/__tests__/sandboxScript.d.ts +1 -0
- package/build/lib/core/agents/offSecAgent/tools/addMemory.d.ts +16 -0
- package/build/lib/core/agents/offSecAgent/tools/agentScratch.d.ts +17 -0
- package/build/lib/core/agents/offSecAgent/tools/applyPatch.d.ts +8 -0
- package/build/lib/core/agents/offSecAgent/tools/applyPatchImpl.d.ts +24 -0
- package/build/lib/core/agents/offSecAgent/tools/askUserQuestions.d.ts +42 -0
- package/build/lib/core/agents/offSecAgent/tools/browserHeaderRouting.d.ts +9 -0
- package/build/lib/core/agents/offSecAgent/tools/browserToolFactories.d.ts +40 -0
- package/build/lib/core/agents/offSecAgent/tools/browserTools.d.ts +96 -0
- package/build/lib/core/agents/offSecAgent/tools/callbackListener.d.ts +212 -0
- package/build/lib/core/agents/offSecAgent/tools/camoufox.d.ts +106 -0
- package/build/lib/core/agents/offSecAgent/tools/checkpointState.d.ts +17 -0
- package/build/lib/core/agents/offSecAgent/tools/completeAuthentication.d.ts +39 -0
- package/build/lib/core/agents/offSecAgent/tools/crawlAuthenticated.d.ts +36 -0
- package/build/lib/core/agents/offSecAgent/tools/createAttackSurfaceReport.d.ts +31 -0
- package/build/lib/core/agents/offSecAgent/tools/createFile.d.ts +12 -0
- package/build/lib/core/agents/offSecAgent/tools/createTask.d.ts +20 -0
- package/build/lib/core/agents/offSecAgent/tools/delegateAuth.d.ts +72 -0
- package/build/lib/core/agents/offSecAgent/tools/deleteFile.d.ts +10 -0
- package/build/lib/core/agents/offSecAgent/tools/destructiveGuard.d.ts +94 -0
- package/build/lib/core/agents/offSecAgent/tools/detectAuthScheme.d.ts +72 -0
- package/build/lib/core/agents/offSecAgent/tools/documentApp.d.ts +38 -0
- package/build/lib/core/agents/offSecAgent/tools/documentEndpoint.d.ts +111 -0
- package/build/lib/core/agents/offSecAgent/tools/documentFinding.d.ts +285 -0
- package/build/lib/core/agents/offSecAgent/tools/email/adapters.d.ts +45 -0
- package/build/lib/core/agents/offSecAgent/tools/email/adapters.js +8 -0
- package/build/lib/core/agents/offSecAgent/tools/email/getAttachments.d.ts +33 -0
- package/build/lib/core/agents/offSecAgent/tools/email/getMessage.d.ts +20 -0
- package/build/lib/core/agents/offSecAgent/tools/email/index.d.ts +145 -0
- package/build/lib/core/agents/offSecAgent/tools/email/listInboxes.d.ts +23 -0
- package/build/lib/core/agents/offSecAgent/tools/email/listMessages.d.ts +22 -0
- package/build/lib/core/agents/offSecAgent/tools/email/markRead.d.ts +20 -0
- package/build/lib/core/agents/offSecAgent/tools/email/searchMessages.d.ts +24 -0
- package/build/lib/core/agents/offSecAgent/tools/email/sendEmail.d.ts +28 -0
- package/build/lib/core/agents/offSecAgent/tools/email/types.d.ts +40 -0
- package/build/lib/core/agents/offSecAgent/tools/email/types.js +0 -0
- package/build/lib/core/agents/offSecAgent/tools/executeCommand.d.ts +84 -0
- package/build/lib/core/agents/offSecAgent/tools/extractJsEndpoints.d.ts +13 -0
- package/build/lib/core/agents/offSecAgent/tools/fileWorkspace.d.ts +21 -0
- package/build/lib/core/agents/offSecAgent/tools/fileWorkspaceRemote.d.ts +13 -0
- package/build/lib/core/agents/offSecAgent/tools/getMemory.d.ts +12 -0
- package/build/lib/core/agents/offSecAgent/tools/getPage.d.ts +17 -0
- package/build/lib/core/agents/offSecAgent/tools/gitDiff.d.ts +12 -0
- package/build/lib/core/agents/offSecAgent/tools/gitStatus.d.ts +10 -0
- package/build/lib/core/agents/offSecAgent/tools/glob.d.ts +8 -0
- package/build/lib/core/agents/offSecAgent/tools/globImpl.d.ts +13 -0
- package/build/lib/core/agents/offSecAgent/tools/globPattern.d.ts +7 -0
- package/build/lib/core/agents/offSecAgent/tools/grep.d.ts +10 -0
- package/build/lib/core/agents/offSecAgent/tools/grepImpl.d.ts +34 -0
- package/build/lib/core/agents/offSecAgent/tools/httpRequest.d.ts +70 -0
- package/build/lib/core/agents/offSecAgent/tools/index.d.ts +466 -0
- package/build/lib/core/agents/offSecAgent/tools/index.js +262 -0
- package/build/lib/core/agents/offSecAgent/tools/listFiles.d.ts +9 -0
- package/build/lib/core/agents/offSecAgent/tools/listFilesImpl.d.ts +27 -0
- package/build/lib/core/agents/offSecAgent/tools/listMemories.d.ts +13 -0
- package/build/lib/core/agents/offSecAgent/tools/listPromptInjections.d.ts +18 -0
- package/build/lib/core/agents/offSecAgent/tools/listTasks.d.ts +24 -0
- package/build/lib/core/agents/offSecAgent/tools/patchApply.d.ts +24 -0
- package/build/lib/core/agents/offSecAgent/tools/patchParse.d.ts +24 -0
- package/build/lib/core/agents/offSecAgent/tools/perCommandShell.d.ts +82 -0
- package/build/lib/core/agents/offSecAgent/tools/playwrightMcp.d.ts +369 -0
- package/build/lib/core/agents/offSecAgent/tools/probeAuthEndpoints.d.ts +28 -0
- package/build/lib/core/agents/offSecAgent/tools/profileCodebase.d.ts +33 -0
- package/build/lib/core/agents/offSecAgent/tools/provideComparisonResults.d.ts +31 -0
- package/build/lib/core/agents/offSecAgent/tools/queryWhiteboxCatalog.d.ts +17 -0
- package/build/lib/core/agents/offSecAgent/tools/readFile.d.ts +11 -0
- package/build/lib/core/agents/offSecAgent/tools/readFileImpl.d.ts +31 -0
- package/build/lib/core/agents/offSecAgent/tools/readSkill.d.ts +15 -0
- package/build/lib/core/agents/offSecAgent/tools/reportError.d.ts +31 -0
- package/build/lib/core/agents/offSecAgent/tools/response.d.ts +15 -0
- package/build/lib/core/agents/offSecAgent/tools/runAttackSurface.d.ts +81 -0
- package/build/lib/core/agents/offSecAgent/tools/runCodeQuery.d.ts +44 -0
- package/build/lib/core/agents/offSecAgent/tools/runPentestWorkflow.d.ts +32 -0
- package/build/lib/core/agents/offSecAgent/tools/runWhiteboxScan.d.ts +52 -0
- package/build/lib/core/agents/offSecAgent/tools/sandbox.d.ts +30 -0
- package/build/lib/core/agents/offSecAgent/tools/sandboxPlaywright.d.ts +137 -0
- package/build/lib/core/agents/offSecAgent/tools/sandboxScript.d.ts +6 -0
- package/build/lib/core/agents/offSecAgent/tools/scopeGuard.d.ts +91 -0
- package/build/lib/core/agents/offSecAgent/tools/scriptSyntaxCheck.d.ts +45 -0
- package/build/lib/core/agents/offSecAgent/tools/smsInbox.d.ts +67 -0
- package/build/lib/core/agents/offSecAgent/tools/smsInbox.js +6 -0
- package/build/lib/core/agents/offSecAgent/tools/smsListMessages.d.ts +29 -0
- package/build/lib/core/agents/offSecAgent/tools/spawnCodingAgent.d.ts +43 -0
- package/build/lib/core/agents/offSecAgent/tools/spawnPentestAgent.d.ts +51 -0
- package/build/lib/core/agents/offSecAgent/tools/spawnPentestSwarm.d.ts +52 -0
- package/build/lib/core/agents/offSecAgent/tools/submitPlan.d.ts +12 -0
- package/build/lib/core/agents/offSecAgent/tools/testEndpointVariations.d.ts +34 -0
- package/build/lib/core/agents/offSecAgent/tools/threatModelGenerator.d.ts +32 -0
- package/build/lib/core/agents/offSecAgent/tools/toolOutput.d.ts +23 -0
- package/build/lib/core/agents/offSecAgent/tools/types.d.ts +215 -0
- package/build/lib/core/agents/offSecAgent/tools/updateFile.d.ts +14 -0
- package/build/lib/core/agents/offSecAgent/tools/updateTask.d.ts +20 -0
- package/build/lib/core/agents/offSecAgent/tools/validateDiscovery.d.ts +24 -0
- package/build/lib/core/agents/offSecAgent/tools/webSearch.d.ts +16 -0
- package/build/lib/core/agents/offSecAgent/tools/whiteboxCandidates.d.ts +108 -0
- package/build/lib/core/agents/offSecAgent/tools/whiteboxJobs.d.ts +157 -0
- package/build/lib/core/agents/offSecAgent/tools/windowsCurl.d.ts +20 -0
- package/build/lib/core/agents/offSecAgent/tools/workspaceApps.d.ts +120 -0
- package/build/lib/core/agents/offSecAgent/tools/workspaceDomains.d.ts +22 -0
- package/build/lib/core/agents/offSecAgent/tools/workspaceFailure.d.ts +6 -0
- package/build/lib/core/agents/offSecAgent/tools/writePlan.d.ts +13 -0
- package/build/lib/core/agents/offSecAgent/trace.d.ts +268 -0
- package/build/lib/core/agents/offSecAgent/types.d.ts +543 -0
- package/build/lib/core/agents/offSecAgent/types.js +7 -0
- package/build/lib/core/agents/specialized/attackSurface/blackboxAgent.d.ts +66 -0
- package/build/lib/core/agents/specialized/attackSurface/blackboxAgent.js +33 -0
- package/build/lib/core/agents/specialized/attackSurface/blackboxRiskScoring.d.ts +30 -0
- package/build/lib/core/agents/specialized/attackSurface/grpcSchema.d.ts +93 -0
- package/build/lib/core/agents/specialized/attackSurface/jsExtraction.d.ts +42 -0
- package/build/lib/core/agents/specialized/attackSurface/prompts.d.ts +1 -0
- package/build/lib/core/agents/specialized/attackSurface/schemas.d.ts +284 -0
- package/build/lib/core/agents/specialized/attackSurface/schemas.js +144 -0
- package/build/lib/core/agents/specialized/attackSurface/types.d.ts +32 -0
- package/build/lib/core/agents/specialized/authenticationAgent/agent.d.ts +73 -0
- package/build/lib/core/agents/specialized/authenticationAgent/index.d.ts +4 -0
- package/build/lib/core/agents/specialized/authenticationAgent/index.js +71 -0
- package/build/lib/core/agents/specialized/authenticationAgent/prompts.d.ts +10 -0
- package/build/lib/core/agents/specialized/authenticationAgent/types.d.ts +620 -0
- package/build/lib/core/agents/specialized/benchmark/comparisonAgent.d.ts +10 -0
- package/build/lib/core/agents/specialized/benchmark/docker-utils.d.ts +17 -0
- package/build/lib/core/agents/specialized/benchmark/flag-detector.d.ts +60 -0
- package/build/lib/core/agents/specialized/benchmark/index.d.ts +8 -0
- package/build/lib/core/agents/specialized/benchmark/prompts.d.ts +1 -0
- package/build/lib/core/agents/specialized/benchmark/remote/circuit-breaker.d.ts +22 -0
- package/build/lib/core/agents/specialized/benchmark/remote/daytona-wrapper.d.ts +33 -0
- package/build/lib/core/agents/specialized/benchmark/remote/index.d.ts +2 -0
- package/build/lib/core/agents/specialized/benchmark/types.d.ts +92 -0
- package/build/lib/core/agents/specialized/benchmarkComparisonAgent.d.ts +27 -0
- package/build/lib/core/agents/specialized/codeAgent/agent.d.ts +50 -0
- package/build/lib/core/agents/specialized/codeAgent/agent.js +31 -0
- package/build/lib/core/agents/specialized/codeAgent/prompts.d.ts +1 -0
- package/build/lib/core/agents/specialized/codeAgent/schemas.d.ts +11 -0
- package/build/lib/core/agents/specialized/codeAgent/schemas.js +10 -0
- package/build/lib/core/agents/specialized/cvssScorer/index.d.ts +56 -0
- package/build/lib/core/agents/specialized/environment/agent.d.ts +43 -0
- package/build/lib/core/agents/specialized/environment/index.d.ts +4 -0
- package/build/lib/core/agents/specialized/environment/prompts.d.ts +10 -0
- package/build/lib/core/agents/specialized/environment/types.d.ts +37 -0
- package/build/lib/core/agents/specialized/findingJudge/agent.d.ts +22 -0
- package/build/lib/core/agents/specialized/findingJudge/agent.js +224 -0
- package/build/lib/core/agents/specialized/findingJudge/index.d.ts +31 -0
- package/build/lib/core/agents/specialized/findingJudge/index.js +13 -0
- package/build/lib/core/agents/specialized/findingJudge/prompts.d.ts +3 -0
- package/build/lib/core/agents/specialized/findingJudge/types.d.ts +77 -0
- package/build/lib/core/agents/specialized/googleSignInPrompt.d.ts +4 -0
- package/build/lib/core/agents/specialized/mobileOtpPrompt.d.ts +1 -0
- package/build/lib/core/agents/specialized/patching/agent.d.ts +64 -0
- package/build/lib/core/agents/specialized/patching/index.d.ts +4 -0
- package/build/lib/core/agents/specialized/patching/index.js +44 -0
- package/build/lib/core/agents/specialized/patching/prompts.d.ts +17 -0
- package/build/lib/core/agents/specialized/patching/types.d.ts +40 -0
- package/build/lib/core/agents/specialized/pentest/agent.d.ts +172 -0
- package/build/lib/core/agents/specialized/pentest/agent.js +43 -0
- package/build/lib/core/agents/specialized/pentest/helperWorkspace.d.ts +16 -0
- package/build/lib/core/agents/specialized/pentest/planPrompt.d.ts +13 -0
- package/build/lib/core/agents/specialized/utils.d.ts +7 -0
- package/build/lib/core/agents/specialized/vulnerabilityReproduction/agent.d.ts +94 -0
- package/build/lib/core/agents/specialized/whiteboxAttackSurface/agent.d.ts +148 -0
- package/build/lib/core/agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent.d.ts +61 -0
- package/build/lib/core/agents/specialized/whiteboxAttackSurface/index.d.ts +5 -0
- package/build/lib/core/agents/specialized/whiteboxAttackSurface/index.js +47 -0
- package/build/lib/core/agents/specialized/whiteboxAttackSurface/prompts.d.ts +34 -0
- package/build/lib/core/agents/specialized/whiteboxAttackSurface/types.d.ts +382 -0
- package/build/lib/core/agents/specialized/whiteboxAttackSurface/types.js +21 -0
- package/build/lib/core/ai/ai.d.ts +342 -0
- package/build/lib/core/ai/ai.js +68 -0
- package/build/lib/core/ai/caching.d.ts +26 -0
- package/build/lib/core/ai/compactionEvidence.d.ts +15 -0
- package/build/lib/core/ai/compactionTelemetry.d.ts +55 -0
- package/build/lib/core/ai/contextManagement.d.ts +85 -0
- package/build/lib/core/ai/index.d.ts +10 -0
- package/build/lib/core/ai/index.js +72 -0
- package/build/lib/core/ai/inference-attempt/adapters.d.ts +15 -0
- package/build/lib/core/ai/inference-attempt/builder.d.ts +31 -0
- package/build/lib/core/ai/inference-attempt/envelope.d.ts +120 -0
- package/build/lib/core/ai/inference-attempt/errors.d.ts +6 -0
- package/build/lib/core/ai/inference-attempt/identity.d.ts +13 -0
- package/build/lib/core/ai/inference-attempt/index.d.ts +36 -0
- package/build/lib/core/ai/inference-attempt/project.d.ts +21 -0
- package/build/lib/core/ai/inference-attempt/recording.d.ts +23 -0
- package/build/lib/core/ai/inference-attempt/tokens.d.ts +13 -0
- package/build/lib/core/ai/inference-attempt/validate.d.ts +2 -0
- package/build/lib/core/ai/mantle.d.ts +28 -0
- package/build/lib/core/ai/model-history.d.ts +4 -0
- package/build/lib/core/ai/models/anthropic.d.ts +2 -0
- package/build/lib/core/ai/models/bedrock.d.ts +2 -0
- package/build/lib/core/ai/models/claude-capabilities.d.ts +7 -0
- package/build/lib/core/ai/models/concentrate.d.ts +2 -0
- package/build/lib/core/ai/models/google.d.ts +2 -0
- package/build/lib/core/ai/models/inception.d.ts +2 -0
- package/build/lib/core/ai/models/index.d.ts +29 -0
- package/build/lib/core/ai/models/mantle.d.ts +2 -0
- package/build/lib/core/ai/models/openai.d.ts +2 -0
- package/build/lib/core/ai/models/openrouter.d.ts +2 -0
- package/build/lib/core/ai/models/pensar.d.ts +2 -0
- package/build/lib/core/ai/native-rollout-evidence/capture.d.ts +31 -0
- package/build/lib/core/ai/native-rollout-evidence/content.d.ts +14 -0
- package/build/lib/core/ai/native-rollout-evidence/index.d.ts +9 -0
- package/build/lib/core/ai/native-rollout-evidence/provider-metadata.d.ts +15 -0
- package/build/lib/core/ai/native-rollout-evidence/schema.d.ts +554 -0
- package/build/lib/core/ai/native-rollout-evidence/validate.d.ts +8 -0
- package/build/lib/core/ai/providers/anthropic.d.ts +2 -0
- package/build/lib/core/ai/providers/concentrate.d.ts +9 -0
- package/build/lib/core/ai/providers/custom.d.ts +3 -0
- package/build/lib/core/ai/providers/hoonify.d.ts +6 -0
- package/build/lib/core/ai/providers/openai-pro-fetch.d.ts +2 -0
- package/build/lib/core/ai/providers/pensar.d.ts +34 -0
- package/build/lib/core/ai/providers/pensarFormatters.d.ts +2 -0
- package/build/lib/core/ai/providers/pensarResponsesStream.d.ts +15 -0
- package/build/lib/core/ai/providers/pensarSSE.d.ts +23 -0
- package/build/lib/core/ai/providers/pensarSigning.d.ts +1 -0
- package/build/lib/core/ai/providers/pensarStreamUsage.d.ts +19 -0
- package/build/lib/core/ai/streamTelemetry.d.ts +22 -0
- package/build/lib/core/ai/utils.d.ts +90 -0
- package/build/lib/core/ai/utils.js +22 -0
- package/build/lib/core/api/apiClient.d.ts +7 -0
- package/build/lib/core/api/apps.d.ts +213 -0
- package/build/lib/core/api/attackSurface.d.ts +14 -0
- package/build/lib/core/api/authentication.d.ts +3 -0
- package/build/lib/core/api/benchmark.d.ts +5 -0
- package/build/lib/core/api/blackboxPentest.d.ts +11 -0
- package/build/lib/core/api/clientIdentity.d.ts +10 -0
- package/build/lib/core/api/constants.d.ts +5 -0
- package/build/lib/core/api/domains.d.ts +19 -0
- package/build/lib/core/api/environment.d.ts +16 -0
- package/build/lib/core/api/index.d.ts +41 -0
- package/build/lib/core/api/index.js +187 -0
- package/build/lib/core/api/issues.d.ts +273 -0
- package/build/lib/core/api/knowledge.d.ts +33 -0
- package/build/lib/core/api/localWorker.d.ts +4 -0
- package/build/lib/core/api/offesecAgent.d.ts +34 -0
- package/build/lib/core/api/patching.d.ts +15 -0
- package/build/lib/core/api/recordedRun.d.ts +36 -0
- package/build/lib/core/api/targetedPentest.d.ts +15 -0
- package/build/lib/core/api/targetedPentest.js +32 -0
- package/build/lib/core/api/threatModel.d.ts +1 -0
- package/build/lib/core/api/trajectoryExport.d.ts +38 -0
- package/build/lib/core/api/vulnerabilityReproduction.d.ts +10 -0
- package/build/lib/core/assets/wordlists.d.ts +31 -0
- package/build/lib/core/atif/convert.d.ts +27 -0
- package/build/lib/core/atif/index.d.ts +7 -0
- package/build/lib/core/atif/schema.d.ts +459 -0
- package/build/lib/core/atif/serialize.d.ts +2 -0
- package/build/lib/core/atif/test-fixtures.d.ts +28 -0
- package/build/lib/core/atif/validate.d.ts +12 -0
- package/build/lib/core/auth/connection.d.ts +12 -0
- package/build/lib/core/auth/device-flow.d.ts +38 -0
- package/build/lib/core/auth/gateway.d.ts +25 -0
- package/build/lib/core/auth/index.d.ts +8 -0
- package/build/lib/core/auth/signing.d.ts +14 -0
- package/build/lib/core/auth/token.d.ts +17 -0
- package/build/lib/core/auth/types.d.ts +85 -0
- package/build/lib/core/auth/workspaces.d.ts +34 -0
- package/build/lib/core/benchmark/index.d.ts +3 -0
- package/build/lib/core/benchmark/report.d.ts +3 -0
- package/build/lib/core/benchmark/runner.d.ts +3 -0
- package/build/lib/core/benchmark/types.d.ts +80 -0
- package/build/lib/core/cli/logLevelArgs.d.ts +18 -0
- package/build/lib/core/cli/model.d.ts +9 -0
- package/build/lib/core/cli/pentestMode.d.ts +5 -0
- package/build/lib/core/cli/tuiArgs.d.ts +5 -0
- package/build/lib/core/config/config.d.ts +86 -0
- package/build/lib/core/config/customProviders.d.ts +62 -0
- package/build/lib/core/config/index.d.ts +6 -0
- package/build/lib/core/config/index.js +6 -0
- package/build/lib/core/credentials/index.d.ts +2 -0
- package/build/lib/core/credentials/manager.d.ts +85 -0
- package/build/lib/core/credentials/types.d.ts +79 -0
- package/build/lib/core/doctor.d.ts +1 -0
- package/build/lib/core/eventBus.d.ts +195 -0
- package/build/lib/core/eventBus.js +6 -0
- package/build/lib/core/findings/attackSurfaceRegistry.d.ts +88 -0
- package/build/lib/core/findings/attackSurfaceRegistry.js +6 -0
- package/build/lib/core/findings/registry.d.ts +177 -0
- package/build/lib/core/findings/registry.js +21 -0
- package/build/lib/core/history.d.ts +23 -0
- package/build/lib/core/hoonify.d.ts +8 -0
- package/build/lib/core/http/parse.d.ts +50 -0
- package/build/lib/core/http/redirects.d.ts +23 -0
- package/build/lib/core/http/targetHeaders.d.ts +30 -0
- package/build/lib/core/http/targetScope.d.ts +12 -0
- package/build/lib/core/http/types.d.ts +11 -0
- package/build/lib/core/id/id.d.ts +60 -0
- package/build/lib/core/id/id.js +28 -0
- package/build/lib/core/installation/index.d.ts +25 -0
- package/build/lib/core/integrations/herdr.d.ts +13 -0
- package/build/lib/core/integrations/surface/index.d.ts +37 -0
- package/build/lib/core/integrations/surface/types.d.ts +22 -0
- package/build/lib/core/integrations/wandb/client.d.ts +23 -0
- package/build/lib/core/integrations/wandb/upload.d.ts +36 -0
- package/build/lib/core/logger/index.d.ts +62 -0
- package/build/lib/core/logger/structured.d.ts +30 -0
- package/build/lib/core/memory/index.d.ts +92 -0
- package/build/lib/core/memory/index.js +21 -0
- package/build/lib/core/messages/types.d.ts +96 -0
- package/build/lib/core/obfuscation/engine.d.ts +51 -0
- package/build/lib/core/obfuscation/index.d.ts +20 -0
- package/build/lib/core/observability/active-root-spans.d.ts +5 -0
- package/build/lib/core/observability/active-spans.d.ts +22 -0
- package/build/lib/core/observability/index.d.ts +36 -0
- package/build/lib/core/observability/index.js +27 -0
- package/build/lib/core/observability/runtime.d.ts +63 -0
- package/build/lib/core/observability/telemetry.d.ts +52 -0
- package/build/lib/core/observability/testkit.d.ts +24 -0
- package/build/lib/core/operator/approvalGate.d.ts +61 -0
- package/build/lib/core/operator/index.d.ts +9 -0
- package/build/lib/core/operator/types.d.ts +167 -0
- package/build/lib/core/plan/index.d.ts +16 -0
- package/build/lib/core/prompt-injections/index.d.ts +111 -0
- package/build/lib/core/prompt-injections/index.js +24 -0
- package/build/lib/core/providers/index.d.ts +5 -0
- package/build/lib/core/providers/types.d.ts +13 -0
- package/build/lib/core/providers/utils.d.ts +15 -0
- package/build/lib/core/providers/verify.d.ts +11 -0
- package/build/lib/core/report/builder.d.ts +9 -0
- package/build/lib/core/report/index.d.ts +7 -0
- package/build/lib/core/report/renderers/json.d.ts +2 -0
- package/build/lib/core/report/renderers/markdown.d.ts +2 -0
- package/build/lib/core/report/schemas.d.ts +115 -0
- package/build/lib/core/runtime/agentExecution.d.ts +15 -0
- package/build/lib/core/runtime/launchLocalWorker.d.ts +33 -0
- package/build/lib/core/runtime/localRunLock.d.ts +9 -0
- package/build/lib/core/runtime/localRunWorker.d.ts +18 -0
- package/build/lib/core/runtime/localWorkerEndpoint.d.ts +14 -0
- package/build/lib/core/runtime/localWorkerProtocol.d.ts +294 -0
- package/build/lib/core/runtime/localWorkerTransport.d.ts +30 -0
- package/build/lib/core/runtime/persistenceError.d.ts +9 -0
- package/build/lib/core/runtime/recordedExecution.d.ts +6 -0
- package/build/lib/core/runtime/recordedRunClient.d.ts +34 -0
- package/build/lib/core/runtime/runCheckpointStore.d.ts +11 -0
- package/build/lib/core/runtime/runContext.d.ts +48 -0
- package/build/lib/core/runtime/runControl.d.ts +44 -0
- package/build/lib/core/runtime/runControlStore.d.ts +83 -0
- package/build/lib/core/runtime/runDeadline.d.ts +4 -0
- package/build/lib/core/runtime/runEvidence.d.ts +37 -0
- package/build/lib/core/runtime/runInference.d.ts +9 -0
- package/build/lib/core/runtime/runModelStore.d.ts +27 -0
- package/build/lib/core/runtime/runObservation.d.ts +19 -0
- package/build/lib/core/runtime/runRecoveryContext.d.ts +20 -0
- package/build/lib/core/runtime/runRecoveryPlan.d.ts +38 -0
- package/build/lib/core/runtime/runRecoveryStore.d.ts +77 -0
- package/build/lib/core/runtime/runStore.d.ts +133 -0
- package/build/lib/core/runtime/runStorePath.d.ts +1 -0
- package/build/lib/core/runtime/runToolStore.d.ts +50 -0
- package/build/lib/core/runtime/runTools.d.ts +16 -0
- package/build/lib/core/runtime/sqliteControlStore.d.ts +41 -0
- package/build/lib/core/runtime/sqliteModelStore.d.ts +20 -0
- package/build/lib/core/runtime/sqliteRecoveryStore.d.ts +35 -0
- package/build/lib/core/runtime/sqliteRunStore.d.ts +8 -0
- package/build/lib/core/runtime/sqliteToolStore.d.ts +30 -0
- package/build/lib/core/runtime/testfixtures/localWorkerChild.d.ts +1 -0
- package/build/lib/core/runtime/testfixtures/localWorkerLauncher.d.ts +1 -0
- package/build/lib/core/runtime/testfixtures/recoveryChild.d.ts +1 -0
- package/build/lib/core/services/rateLimiter/index.d.ts +36 -0
- package/build/lib/core/services/rateLimiter/types.d.ts +10 -0
- package/build/lib/core/session/execution-metrics.d.ts +37 -0
- package/build/lib/core/session/index.d.ts +586 -0
- package/build/lib/core/session/index.js +36 -0
- package/build/lib/core/session/loader.d.ts +30 -0
- package/build/lib/core/session/persistence.d.ts +215 -0
- package/build/lib/core/session/persistence.js +35 -0
- package/build/lib/core/session/types.d.ts +59 -0
- package/build/lib/core/session/usage.d.ts +37 -0
- package/build/lib/core/skills/builtins/index.d.ts +13 -0
- package/build/lib/core/skills/builtins/pentest.d.ts +19 -0
- package/build/lib/core/skills/builtins/promptInjection.d.ts +2 -0
- package/build/lib/core/skills/builtins/threatModel.d.ts +11 -0
- package/build/lib/core/skills/index.d.ts +5 -0
- package/build/lib/core/skills/parser.d.ts +11 -0
- package/build/lib/core/skills/registry.d.ts +30 -0
- package/build/lib/core/skills/scanner.d.ts +12 -0
- package/build/lib/core/skills/types.d.ts +44 -0
- package/build/lib/core/skills/utils.d.ts +6 -0
- package/build/lib/core/storage/index.d.ts +248 -0
- package/build/lib/core/tasks/index.d.ts +78 -0
- package/build/lib/core/tools/backends/capture.d.ts +10 -0
- package/build/lib/core/tools/backends/collectCommand.d.ts +9 -0
- package/build/lib/core/tools/backends/helpers.d.ts +43 -0
- package/build/lib/core/tools/backends/httpTransport.d.ts +18 -0
- package/build/lib/core/tools/backends/index.d.ts +8 -0
- package/build/lib/core/tools/backends/index.js +31 -0
- package/build/lib/core/tools/backends/local.d.ts +11 -0
- package/build/lib/core/tools/backends/policy.d.ts +39 -0
- package/build/lib/core/tools/backends/resolve.d.ts +25 -0
- package/build/lib/core/tools/backends/types.d.ts +240 -0
- package/build/lib/core/tools/backends/whitebox.d.ts +6 -0
- package/build/lib/core/tools/backends/whiteboxJobs.d.ts +18 -0
- package/build/lib/core/tools/backends/windowsProgram.d.ts +4 -0
- package/build/lib/core/tools/daytonaSandbox.d.ts +14 -0
- package/build/lib/core/toolset/index.d.ts +28 -0
- package/build/lib/core/util/lazyLogger.d.ts +16 -0
- package/build/lib/core/utils/concurrency.d.ts +16 -0
- package/build/lib/core/utils/prompt.d.ts +12 -0
- package/build/lib/core/whitebox/adapters.d.ts +29 -0
- package/build/lib/core/whitebox/artifacts.d.ts +32 -0
- package/build/lib/core/whitebox/boundedProcess.d.ts +35 -0
- package/build/lib/core/whitebox/candidates.d.ts +29 -0
- package/build/lib/core/whitebox/catalog.d.ts +10 -0
- package/build/lib/core/whitebox/index.d.ts +9 -0
- package/build/lib/core/whitebox/jobKernel.d.ts +33 -0
- package/build/lib/core/whitebox/jobSupervisor.d.ts +14 -0
- package/build/lib/core/whitebox/jobs.d.ts +17 -0
- package/build/lib/core/whitebox/paths.d.ts +22 -0
- package/build/lib/core/whitebox/profileTransport.d.ts +10 -0
- package/build/lib/core/whitebox/profiles.d.ts +3 -0
- package/build/lib/core/whitebox/repoProfile.d.ts +4 -0
- package/build/lib/core/whitebox/types.d.ts +108 -0
- package/build/lib/core/workflows/fastStrike.d.ts +4 -0
- package/build/lib/core/workflows/pentest.d.ts +167 -0
- package/build/lib/core/workflows/pentest.js +42 -0
- package/build/lib/core/workflows/seams.d.ts +102 -0
- package/build/lib/core/workflows/seams.js +37 -0
- package/build/lib/core/workflows/threatModel.d.ts +26 -0
- package/build/lib/core/workflows/whiteboxAttackSurface.d.ts +142 -0
- package/build/lib/core/workflows/whiteboxAttackSurface.js +36 -0
- package/build/lib/index.d.ts +26 -0
- package/build/lib/index.js +96 -0
- package/build/lib/lib/attack-path/types.d.ts +9 -0
- package/build/lib/lib/cvss/calculator.d.ts +31 -0
- package/build/lib/lib/cvss/index.d.ts +24 -0
- package/build/lib/lib/cvss/index.js +24 -0
- package/build/lib/lib/cvss/macrovector-scores.d.ts +59 -0
- package/build/lib/lib/cvss/types.d.ts +114 -0
- package/build/lib/lib/cvss/types.js +8 -0
- package/build/lib/lib/cwe/cwe-catalog.d.ts +13 -0
- package/build/lib/lib/cwe/types.d.ts +28 -0
- package/build/lib/lib/cwe/validate.d.ts +15 -0
- package/build/lib/lib/evidence/types.d.ts +12 -0
- package/build/lib/util/errors.d.ts +186 -0
- package/build/lib/util/lock.d.ts +2 -0
- package/build/lib/util/name.d.ts +14 -0
- package/build/lib/util/url.d.ts +40 -0
- package/build/{logs-wzr5176k.js → logs-v5503qqk.js} +22 -30
- package/build/{multipart-parser-g2xxkezz.js → multipart-parser-vjjdbpd1.js} +10 -10
- package/build/native-rollout-evidence-1qwze8nm.js +135 -0
- package/build/offesecAgent-w5a2r0wa.js +22 -0
- package/build/{parse-rtccymzn.js → parse-cqecqrc5.js} +0 -4
- package/build/pentest-fxya42cg.js +22 -0
- package/build/pentests-6qntz6wz.js +143 -0
- package/build/recordedRunClient-rtdeagzx.js +11 -0
- package/build/{targetedPentest-tdwtgmxm.js → targetedPentest-khnxcvmb.js} +22 -22
- package/build/{targets-763n91t7.js → targets-ty7dahv4.js} +24 -32
- package/build/threatModel-28ayxe0n.js +21 -0
- package/build/{token-3bbp59y6.js → token-mk7t8y0y.js} +2 -2
- package/build/{token-util-6xjme11b.js → token-util-vd776hrv.js} +1 -2
- package/build/{uninstall-d33159cz.js → uninstall-nrhvt32a.js} +3 -3
- package/build/{upload-9qj1kpt9.js → upload-sx9gth59.js} +8 -14
- package/build/{utils-t7gc2903.js → utils-qetcfvgg.js} +29 -29
- package/package.json +230 -5
- package/src/cli/agent-runs.attach.test.ts +359 -0
- package/src/cli/agent-runs.test.ts +1172 -0
- package/src/cli/agent-runs.ts +430 -0
- package/src/cli/apps.test.ts +63 -0
- package/src/cli/apps.ts +526 -0
- package/src/cli/auth.ts +375 -0
- package/src/cli/command-exit.test.ts +15 -0
- package/src/cli/command-exit.ts +3 -0
- package/src/cli/config.ts +210 -0
- package/src/cli/export-trajectory.test.ts +224 -0
- package/src/cli/export-trajectory.ts +119 -0
- package/src/cli/fixes.ts +56 -0
- package/src/cli/issues.test.ts +214 -0
- package/src/cli/issues.ts +242 -0
- package/src/cli/json-output.test.ts +62 -0
- package/src/cli/knowledge.test.ts +140 -0
- package/src/cli/knowledge.ts +146 -0
- package/src/cli/launcher.test.ts +81 -0
- package/src/cli/logs.ts +111 -0
- package/src/cli/native-rollout-evidence.test.ts +322 -0
- package/src/cli/native-rollout-evidence.ts +206 -0
- package/src/cli/pentests.test.ts +194 -0
- package/src/cli/pentests.ts +159 -0
- package/src/cli/resume.test.ts +107 -0
- package/src/cli/targets.ts +125 -0
- package/src/cli/uninstall.ts +302 -0
- package/src/cli.ts +882 -0
- package/src/core/agents/agentRuntime.test.ts +242 -0
- package/src/core/agents/agentRuntime.ts +120 -0
- package/src/core/agents/defineAgent.ts +134 -0
- package/src/core/agents/offSecAgent/index.ts +162 -0
- package/src/core/agents/offSecAgent/interruptedStepFinalization.test.ts +295 -0
- package/src/core/agents/offSecAgent/interruptedStepFinalization.ts +162 -0
- package/src/core/agents/offSecAgent/interruptedStepMessages.test.ts +296 -0
- package/src/core/agents/offSecAgent/interruptedStepMessages.ts +137 -0
- package/src/core/agents/offSecAgent/messagePersistence.test.ts +281 -0
- package/src/core/agents/offSecAgent/messagePersistence.ts +111 -0
- package/src/core/agents/offSecAgent/offensiveSecurityAgent.runtimeContext.test.ts +689 -0
- package/src/core/agents/offSecAgent/offensiveSecurityAgent.test.ts +2899 -0
- package/src/core/agents/offSecAgent/offensiveSecurityAgent.ts +1610 -0
- package/src/core/agents/offSecAgent/prompt.test.ts +72 -0
- package/src/core/agents/offSecAgent/prompt.ts +368 -0
- package/src/core/agents/offSecAgent/recordedTools.test.ts +580 -0
- package/src/core/agents/offSecAgent/recordedTools.ts +162 -0
- package/src/core/agents/offSecAgent/runtimeContext.test.ts +531 -0
- package/src/core/agents/offSecAgent/runtimeContext.ts +387 -0
- package/src/core/agents/offSecAgent/selectiveConstruction.publicPath.test.ts +295 -0
- package/src/core/agents/offSecAgent/selectiveConstruction.test.ts +498 -0
- package/src/core/agents/offSecAgent/streamDiagnostics.test.ts +310 -0
- package/src/core/agents/offSecAgent/streamDiagnostics.ts +237 -0
- package/src/core/agents/offSecAgent/subagentSpawner.hooks.test.ts +102 -0
- package/src/core/agents/offSecAgent/subagentSpawner.test.ts +384 -0
- package/src/core/agents/offSecAgent/subagentSpawner.ts +664 -0
- package/src/core/agents/offSecAgent/toolLifecycle.test.ts +199 -0
- package/src/core/agents/offSecAgent/toolLifecycle.ts +171 -0
- package/src/core/agents/offSecAgent/tools/__tests__/sandboxScript.ts +14 -0
- package/src/core/agents/offSecAgent/tools/addMemory.ts +87 -0
- package/src/core/agents/offSecAgent/tools/agentScratch.test.ts +36 -0
- package/src/core/agents/offSecAgent/tools/agentScratch.ts +23 -0
- package/src/core/agents/offSecAgent/tools/applyPatch.test.ts +546 -0
- package/src/core/agents/offSecAgent/tools/applyPatch.ts +58 -0
- package/src/core/agents/offSecAgent/tools/applyPatchImpl.ts +300 -0
- package/src/core/agents/offSecAgent/tools/askUserQuestions.ts +81 -0
- package/src/core/agents/offSecAgent/tools/authBackendStatus.test.ts +112 -0
- package/src/core/agents/offSecAgent/tools/browserHeaderRouting.test.ts +136 -0
- package/src/core/agents/offSecAgent/tools/browserHeaderRouting.ts +81 -0
- package/src/core/agents/offSecAgent/tools/browserToolFactories.ts +372 -0
- package/src/core/agents/offSecAgent/tools/browserTools.test.ts +243 -0
- package/src/core/agents/offSecAgent/tools/browserTools.ts +285 -0
- package/src/core/agents/offSecAgent/tools/callbackListener.test.ts +1011 -0
- package/src/core/agents/offSecAgent/tools/callbackListener.ts +1038 -0
- package/src/core/agents/offSecAgent/tools/camoufox.test.ts +119 -0
- package/src/core/agents/offSecAgent/tools/camoufox.ts +199 -0
- package/src/core/agents/offSecAgent/tools/checkpointState.ts +79 -0
- package/src/core/agents/offSecAgent/tools/codingTools.windows.test.ts +625 -0
- package/src/core/agents/offSecAgent/tools/completeAuthentication.ts +136 -0
- package/src/core/agents/offSecAgent/tools/crawlAuthenticated.test.ts +267 -0
- package/src/core/agents/offSecAgent/tools/crawlAuthenticated.ts +170 -0
- package/src/core/agents/offSecAgent/tools/createAttackSurfaceReport.ts +75 -0
- package/src/core/agents/offSecAgent/tools/createFile.test.ts +111 -0
- package/src/core/agents/offSecAgent/tools/createFile.ts +44 -0
- package/src/core/agents/offSecAgent/tools/createTask.ts +118 -0
- package/src/core/agents/offSecAgent/tools/delegateAuth.ts +391 -0
- package/src/core/agents/offSecAgent/tools/deleteFile.test.ts +102 -0
- package/src/core/agents/offSecAgent/tools/deleteFile.ts +39 -0
- package/src/core/agents/offSecAgent/tools/destructiveGuard.test.ts +827 -0
- package/src/core/agents/offSecAgent/tools/destructiveGuard.ts +747 -0
- package/src/core/agents/offSecAgent/tools/detectAuthScheme.ts +191 -0
- package/src/core/agents/offSecAgent/tools/documentApp.ts +242 -0
- package/src/core/agents/offSecAgent/tools/documentEndpoint.ts +291 -0
- package/src/core/agents/offSecAgent/tools/documentFinding.test.ts +2091 -0
- package/src/core/agents/offSecAgent/tools/documentFinding.ts +1240 -0
- package/src/core/agents/offSecAgent/tools/email/adapters.test.ts +279 -0
- package/src/core/agents/offSecAgent/tools/email/adapters.ts +1121 -0
- package/src/core/agents/offSecAgent/tools/email/getAttachments.ts +73 -0
- package/src/core/agents/offSecAgent/tools/email/getMessage.ts +56 -0
- package/src/core/agents/offSecAgent/tools/email/inboxBackend.test.ts +137 -0
- package/src/core/agents/offSecAgent/tools/email/index.ts +55 -0
- package/src/core/agents/offSecAgent/tools/email/listInboxes.ts +47 -0
- package/src/core/agents/offSecAgent/tools/email/listMessages.ts +67 -0
- package/src/core/agents/offSecAgent/tools/email/markRead.ts +57 -0
- package/src/core/agents/offSecAgent/tools/email/searchMessages.ts +76 -0
- package/src/core/agents/offSecAgent/tools/email/sendEmail.ts +165 -0
- package/src/core/agents/offSecAgent/tools/email/types.ts +45 -0
- package/src/core/agents/offSecAgent/tools/executeCommand.backends.test.ts +171 -0
- package/src/core/agents/offSecAgent/tools/executeCommand.test.ts +1153 -0
- package/src/core/agents/offSecAgent/tools/executeCommand.ts +604 -0
- package/src/core/agents/offSecAgent/tools/extractJsEndpoints.ts +44 -0
- package/src/core/agents/offSecAgent/tools/fileBackends.test.ts +66 -0
- package/src/core/agents/offSecAgent/tools/fileMutations.test.ts +159 -0
- package/src/core/agents/offSecAgent/tools/fileToolBackendPurity.test.ts +72 -0
- package/src/core/agents/offSecAgent/tools/fileWorkspace.test.ts +357 -0
- package/src/core/agents/offSecAgent/tools/fileWorkspace.ts +434 -0
- package/src/core/agents/offSecAgent/tools/fileWorkspaceRemote.ts +263 -0
- package/src/core/agents/offSecAgent/tools/getMemory.ts +69 -0
- package/src/core/agents/offSecAgent/tools/getPage.test.ts +1127 -0
- package/src/core/agents/offSecAgent/tools/getPage.ts +70 -0
- package/src/core/agents/offSecAgent/tools/gitDiff.ts +67 -0
- package/src/core/agents/offSecAgent/tools/gitStatus.ts +61 -0
- package/src/core/agents/offSecAgent/tools/gitTools.test.ts +237 -0
- package/src/core/agents/offSecAgent/tools/glob.test.ts +695 -0
- package/src/core/agents/offSecAgent/tools/glob.ts +51 -0
- package/src/core/agents/offSecAgent/tools/globImpl.ts +313 -0
- package/src/core/agents/offSecAgent/tools/globPattern.ts +203 -0
- package/src/core/agents/offSecAgent/tools/grep.test.ts +922 -0
- package/src/core/agents/offSecAgent/tools/grep.ts +73 -0
- package/src/core/agents/offSecAgent/tools/grepImpl.ts +718 -0
- package/src/core/agents/offSecAgent/tools/httpBackends.test.ts +534 -0
- package/src/core/agents/offSecAgent/tools/httpRequest.test.ts +2409 -0
- package/src/core/agents/offSecAgent/tools/httpRequest.ts +425 -0
- package/src/core/agents/offSecAgent/tools/index.ts +787 -0
- package/src/core/agents/offSecAgent/tools/listFiles.bounded.test.ts +514 -0
- package/src/core/agents/offSecAgent/tools/listFiles.public-counters.test.ts +163 -0
- package/src/core/agents/offSecAgent/tools/listFiles.test.ts +521 -0
- package/src/core/agents/offSecAgent/tools/listFiles.ts +49 -0
- package/src/core/agents/offSecAgent/tools/listFilesImpl.ts +351 -0
- package/src/core/agents/offSecAgent/tools/listMemories.ts +71 -0
- package/src/core/agents/offSecAgent/tools/listPromptInjections.test.ts +201 -0
- package/src/core/agents/offSecAgent/tools/listPromptInjections.ts +78 -0
- package/src/core/agents/offSecAgent/tools/listTasks.ts +100 -0
- package/src/core/agents/offSecAgent/tools/patchApply.test.ts +573 -0
- package/src/core/agents/offSecAgent/tools/patchApply.ts +430 -0
- package/src/core/agents/offSecAgent/tools/patchParse.test.ts +383 -0
- package/src/core/agents/offSecAgent/tools/patchParse.ts +354 -0
- package/src/core/agents/offSecAgent/tools/perCommandShell.drain.test.ts +109 -0
- package/src/core/agents/offSecAgent/tools/perCommandShell.test.ts +565 -0
- package/src/core/agents/offSecAgent/tools/perCommandShell.ts +516 -0
- package/src/core/agents/offSecAgent/tools/perCommandShell.windows.test.ts +142 -0
- package/src/core/agents/offSecAgent/tools/playwrightMcp.test.ts +778 -0
- package/src/core/agents/offSecAgent/tools/playwrightMcp.ts +1426 -0
- package/src/core/agents/offSecAgent/tools/probeAuthEndpoints.ts +262 -0
- package/src/core/agents/offSecAgent/tools/profileCodebase.ts +110 -0
- package/src/core/agents/offSecAgent/tools/provideComparisonResults.ts +106 -0
- package/src/core/agents/offSecAgent/tools/queryWhiteboxCatalog.coalescing-cost.test.ts +108 -0
- package/src/core/agents/offSecAgent/tools/queryWhiteboxCatalog.test.ts +183 -0
- package/src/core/agents/offSecAgent/tools/queryWhiteboxCatalog.ts +143 -0
- package/src/core/agents/offSecAgent/tools/readFile.test.ts +1242 -0
- package/src/core/agents/offSecAgent/tools/readFile.ts +89 -0
- package/src/core/agents/offSecAgent/tools/readFileImpl.ts +956 -0
- package/src/core/agents/offSecAgent/tools/readSkill.ts +38 -0
- package/src/core/agents/offSecAgent/tools/reportError.test.ts +48 -0
- package/src/core/agents/offSecAgent/tools/reportError.ts +65 -0
- package/src/core/agents/offSecAgent/tools/response.ts +27 -0
- package/src/core/agents/offSecAgent/tools/runAttackSurface.ts +198 -0
- package/src/core/agents/offSecAgent/tools/runCodeQuery.test.ts +82 -0
- package/src/core/agents/offSecAgent/tools/runCodeQuery.ts +237 -0
- package/src/core/agents/offSecAgent/tools/runPentestWorkflow.ts +122 -0
- package/src/core/agents/offSecAgent/tools/runWhiteboxScan.ts +189 -0
- package/src/core/agents/offSecAgent/tools/runtimeBackendConsumers.test.ts +143 -0
- package/src/core/agents/offSecAgent/tools/sandbox.ts +37 -0
- package/src/core/agents/offSecAgent/tools/sandboxPlaywright.test.ts +235 -0
- package/src/core/agents/offSecAgent/tools/sandboxPlaywright.ts +1029 -0
- package/src/core/agents/offSecAgent/tools/sandboxScript.test.ts +31 -0
- package/src/core/agents/offSecAgent/tools/sandboxScript.ts +60 -0
- package/src/core/agents/offSecAgent/tools/scopeGuard.test.ts +574 -0
- package/src/core/agents/offSecAgent/tools/scopeGuard.ts +317 -0
- package/src/core/agents/offSecAgent/tools/scriptSyntaxCheck.test.ts +566 -0
- package/src/core/agents/offSecAgent/tools/scriptSyntaxCheck.ts +240 -0
- package/src/core/agents/offSecAgent/tools/selectiveFactories.test.ts +476 -0
- package/src/core/agents/offSecAgent/tools/smsInbox.ts +130 -0
- package/src/core/agents/offSecAgent/tools/smsListMessages.test.ts +443 -0
- package/src/core/agents/offSecAgent/tools/smsListMessages.ts +123 -0
- package/src/core/agents/offSecAgent/tools/spawnCodingAgent.ts +229 -0
- package/src/core/agents/offSecAgent/tools/spawnPentestAgent.test.ts +413 -0
- package/src/core/agents/offSecAgent/tools/spawnPentestAgent.ts +266 -0
- package/src/core/agents/offSecAgent/tools/spawnPentestSwarm.ts +146 -0
- package/src/core/agents/offSecAgent/tools/submitPlan.ts +51 -0
- package/src/core/agents/offSecAgent/tools/testEndpointVariations.ts +127 -0
- package/src/core/agents/offSecAgent/tools/threatModelGenerator.ts +664 -0
- package/src/core/agents/offSecAgent/tools/toolOutput.test.ts +480 -0
- package/src/core/agents/offSecAgent/tools/toolOutput.ts +160 -0
- package/src/core/agents/offSecAgent/tools/types.ts +267 -0
- package/src/core/agents/offSecAgent/tools/updateFile.ts +121 -0
- package/src/core/agents/offSecAgent/tools/updateTask.ts +107 -0
- package/src/core/agents/offSecAgent/tools/validateDiscovery.ts +123 -0
- package/src/core/agents/offSecAgent/tools/webSearch.ts +265 -0
- package/src/core/agents/offSecAgent/tools/whiteboxCandidates.ts +197 -0
- package/src/core/agents/offSecAgent/tools/whiteboxJobs.ts +312 -0
- package/src/core/agents/offSecAgent/tools/windowsCurl.test.ts +801 -0
- package/src/core/agents/offSecAgent/tools/windowsCurl.ts +202 -0
- package/src/core/agents/offSecAgent/tools/workspaceApps.test.ts +257 -0
- package/src/core/agents/offSecAgent/tools/workspaceApps.ts +334 -0
- package/src/core/agents/offSecAgent/tools/workspaceDomains.test.ts +113 -0
- package/src/core/agents/offSecAgent/tools/workspaceDomains.ts +57 -0
- package/src/core/agents/offSecAgent/tools/workspaceFailure.ts +11 -0
- package/src/core/agents/offSecAgent/tools/writePlan.ts +65 -0
- package/src/core/agents/offSecAgent/trace.test.ts +796 -0
- package/src/core/agents/offSecAgent/trace.ts +633 -0
- package/src/core/agents/offSecAgent/types.test.ts +224 -0
- package/src/core/agents/offSecAgent/types.ts +676 -0
- package/src/core/agents/specialized/attackSurface/blackboxAgent.test.ts +31 -0
- package/src/core/agents/specialized/attackSurface/blackboxAgent.ts +272 -0
- package/src/core/agents/specialized/attackSurface/blackboxRiskScoring.ts +276 -0
- package/src/core/agents/specialized/attackSurface/grpcSchema.ts +142 -0
- package/src/core/agents/specialized/attackSurface/jsExtraction.test.ts +237 -0
- package/src/core/agents/specialized/attackSurface/jsExtraction.ts +174 -0
- package/src/core/agents/specialized/attackSurface/prompts.ts +349 -0
- package/src/core/agents/specialized/attackSurface/schemas.ts +300 -0
- package/src/core/agents/specialized/attackSurface/types.ts +100 -0
- package/src/core/agents/specialized/authenticationAgent/agent.test.ts +111 -0
- package/src/core/agents/specialized/authenticationAgent/agent.ts +300 -0
- package/src/core/agents/specialized/authenticationAgent/index.ts +74 -0
- package/src/core/agents/specialized/authenticationAgent/prompts.test.ts +36 -0
- package/src/core/agents/specialized/authenticationAgent/prompts.ts +645 -0
- package/src/core/agents/specialized/authenticationAgent/types.ts +833 -0
- package/src/core/agents/specialized/benchmark/comparisonAgent.ts +344 -0
- package/src/core/agents/specialized/benchmark/docker-utils.ts +257 -0
- package/src/core/agents/specialized/benchmark/flag-detector.ts +686 -0
- package/src/core/agents/specialized/benchmark/index.ts +28 -0
- package/src/core/agents/specialized/benchmark/prompts.ts +257 -0
- package/src/core/agents/specialized/benchmark/remote/circuit-breaker.ts +108 -0
- package/src/core/agents/specialized/benchmark/remote/daytona-wrapper.ts +1005 -0
- package/src/core/agents/specialized/benchmark/remote/index.ts +2 -0
- package/src/core/agents/specialized/benchmark/types.ts +98 -0
- package/src/core/agents/specialized/benchmarkComparisonAgent.test.ts +111 -0
- package/src/core/agents/specialized/benchmarkComparisonAgent.ts +203 -0
- package/src/core/agents/specialized/codeAgent/agent.test.ts +89 -0
- package/src/core/agents/specialized/codeAgent/agent.ts +134 -0
- package/src/core/agents/specialized/codeAgent/prompts.ts +48 -0
- package/src/core/agents/specialized/codeAgent/schemas.ts +33 -0
- package/src/core/agents/specialized/cvssScorer/index.test.ts +87 -0
- package/src/core/agents/specialized/cvssScorer/index.ts +546 -0
- package/src/core/agents/specialized/environment/agent.ts +75 -0
- package/src/core/agents/specialized/environment/index.ts +16 -0
- package/src/core/agents/specialized/environment/prompts.ts +194 -0
- package/src/core/agents/specialized/environment/types.ts +48 -0
- package/src/core/agents/specialized/findingJudge/agent.test.ts +114 -0
- package/src/core/agents/specialized/findingJudge/agent.ts +59 -0
- package/src/core/agents/specialized/findingJudge/index.test.ts +155 -0
- package/src/core/agents/specialized/findingJudge/index.ts +166 -0
- package/src/core/agents/specialized/findingJudge/prompts.ts +140 -0
- package/src/core/agents/specialized/findingJudge/types.ts +115 -0
- package/src/core/agents/specialized/googleSignInPrompt.test.ts +29 -0
- package/src/core/agents/specialized/googleSignInPrompt.ts +18 -0
- package/src/core/agents/specialized/mobileOtpPrompt.ts +9 -0
- package/src/core/agents/specialized/patching/agent.test.ts +220 -0
- package/src/core/agents/specialized/patching/agent.ts +146 -0
- package/src/core/agents/specialized/patching/index.ts +20 -0
- package/src/core/agents/specialized/patching/prompts.test.ts +172 -0
- package/src/core/agents/specialized/patching/prompts.ts +396 -0
- package/src/core/agents/specialized/patching/types.ts +49 -0
- package/src/core/agents/specialized/pentest/agent.test.ts +1046 -0
- package/src/core/agents/specialized/pentest/agent.ts +1482 -0
- package/src/core/agents/specialized/pentest/helperLifecycle.test.ts +425 -0
- package/src/core/agents/specialized/pentest/helperWorkspace.test.ts +84 -0
- package/src/core/agents/specialized/pentest/helperWorkspace.ts +33 -0
- package/src/core/agents/specialized/pentest/planPrompt.ts +68 -0
- package/src/core/agents/specialized/pentest/results.test.ts +198 -0
- package/src/core/agents/specialized/utils.test.ts +16 -0
- package/src/core/agents/specialized/utils.ts +28 -0
- package/src/core/agents/specialized/vulnerabilityReproduction/agent.test.ts +195 -0
- package/src/core/agents/specialized/vulnerabilityReproduction/agent.ts +159 -0
- package/src/core/agents/specialized/whiteboxAttackSurface/agent.test.ts +39 -0
- package/src/core/agents/specialized/whiteboxAttackSurface/agent.ts +227 -0
- package/src/core/agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent.concurrency.test.ts +138 -0
- package/src/core/agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent.test.ts +199 -0
- package/src/core/agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent.ts +330 -0
- package/src/core/agents/specialized/whiteboxAttackSurface/index.ts +24 -0
- package/src/core/agents/specialized/whiteboxAttackSurface/prompts.ts +345 -0
- package/src/core/agents/specialized/whiteboxAttackSurface/types.test.ts +67 -0
- package/src/core/agents/specialized/whiteboxAttackSurface/types.ts +234 -0
- package/src/core/ai/ai.contract.test.ts +43 -0
- package/src/core/ai/ai.durability-hooks.test.ts +527 -0
- package/src/core/ai/ai.effective-tools.test.ts +739 -0
- package/src/core/ai/ai.native-rollout-evidence.test.ts +373 -0
- package/src/core/ai/ai.outer-catch-recovery.test.ts +82 -0
- package/src/core/ai/ai.proactive-recovery.test.ts +69 -0
- package/src/core/ai/ai.recorded-attempts.test.ts +621 -0
- package/src/core/ai/ai.recorded-context.test.ts +448 -0
- package/src/core/ai/ai.recorded-tools.test.ts +850 -0
- package/src/core/ai/ai.request-retention.test.ts +296 -0
- package/src/core/ai/ai.test.ts +690 -0
- package/src/core/ai/ai.ts +2377 -0
- package/src/core/ai/caching.test.ts +179 -0
- package/src/core/ai/caching.ts +119 -0
- package/src/core/ai/compactionEvidence.test.ts +52 -0
- package/src/core/ai/compactionEvidence.ts +101 -0
- package/src/core/ai/compactionTelemetry.test.ts +621 -0
- package/src/core/ai/compactionTelemetry.ts +287 -0
- package/src/core/ai/concentrate.test.ts +28 -0
- package/src/core/ai/contextManagement.test.ts +350 -0
- package/src/core/ai/contextManagement.ts +594 -0
- package/src/core/ai/index.ts +73 -0
- package/src/core/ai/inference-attempt/adapters.test.ts +84 -0
- package/src/core/ai/inference-attempt/adapters.ts +391 -0
- package/src/core/ai/inference-attempt/attempt.test.ts +198 -0
- package/src/core/ai/inference-attempt/builder.ts +171 -0
- package/src/core/ai/inference-attempt/envelope.ts +120 -0
- package/src/core/ai/inference-attempt/errors.ts +15 -0
- package/src/core/ai/inference-attempt/fixtures/anthropic-messages-cache-create.json +18 -0
- package/src/core/ai/inference-attempt/fixtures/anthropic-messages-cache-read.json +18 -0
- package/src/core/ai/inference-attempt/fixtures/anthropic-messages-incomplete.json +16 -0
- package/src/core/ai/inference-attempt/fixtures/anthropic-messages-mixed.json +22 -0
- package/src/core/ai/inference-attempt/fixtures/anthropic-messages-non-cache.json +26 -0
- package/src/core/ai/inference-attempt/fixtures/bedrock-converse-cache-create.json +18 -0
- package/src/core/ai/inference-attempt/fixtures/bedrock-converse-cache-read.json +26 -0
- package/src/core/ai/inference-attempt/fixtures/bedrock-converse-incomplete.json +19 -0
- package/src/core/ai/inference-attempt/fixtures/bedrock-converse-mixed.json +20 -0
- package/src/core/ai/inference-attempt/fixtures/bedrock-converse-non-cache.json +24 -0
- package/src/core/ai/inference-attempt/fixtures/openai-responses-cache-read.json +17 -0
- package/src/core/ai/inference-attempt/fixtures/openai-responses-incomplete.json +16 -0
- package/src/core/ai/inference-attempt/fixtures/openai-responses-non-cache.json +23 -0
- package/src/core/ai/inference-attempt/fixtures/pensar-anthropic-rest-incomplete.json +21 -0
- package/src/core/ai/inference-attempt/fixtures/pensar-anthropic-rest-native.json +16 -0
- package/src/core/ai/inference-attempt/fixtures/pensar-anthropic-stream-cache-create.json +20 -0
- package/src/core/ai/inference-attempt/fixtures/pensar-anthropic-stream-cache-read.json +20 -0
- package/src/core/ai/inference-attempt/fixtures/pensar-anthropic-stream-incomplete.json +16 -0
- package/src/core/ai/inference-attempt/fixtures/pensar-anthropic-stream-mixed.json +21 -0
- package/src/core/ai/inference-attempt/fixtures/pensar-anthropic-stream-non-cache.json +19 -0
- package/src/core/ai/inference-attempt/fixtures/reject-cache-read-exceeds-inclusive.json +11 -0
- package/src/core/ai/inference-attempt/fixtures/reject-components-exceed-inclusive.json +12 -0
- package/src/core/ai/inference-attempt/fixtures/reject-identity-mismatch.json +13 -0
- package/src/core/ai/inference-attempt/fixtures/reject-negative-token.json +9 -0
- package/src/core/ai/inference-attempt/fixtures/reject-non-integer-token.json +8 -0
- package/src/core/ai/inference-attempt/fixtures/sdk-normalized-cache-read.json +19 -0
- package/src/core/ai/inference-attempt/fixtures/sdk-normalized-incomplete.json +15 -0
- package/src/core/ai/inference-attempt/fixtures/sdk-normalized-mixed.json +20 -0
- package/src/core/ai/inference-attempt/fixtures/sdk-normalized-non-cache.json +16 -0
- package/src/core/ai/inference-attempt/identity.ts +25 -0
- package/src/core/ai/inference-attempt/index.ts +70 -0
- package/src/core/ai/inference-attempt/project.test.ts +118 -0
- package/src/core/ai/inference-attempt/project.ts +60 -0
- package/src/core/ai/inference-attempt/recording.ts +46 -0
- package/src/core/ai/inference-attempt/tokens.ts +165 -0
- package/src/core/ai/inference-attempt/validate.ts +20 -0
- package/src/core/ai/mantle.test.ts +50 -0
- package/src/core/ai/mantle.ts +45 -0
- package/src/core/ai/model-history.test.ts +53 -0
- package/src/core/ai/model-history.ts +38 -0
- package/src/core/ai/models/anthropic.ts +151 -0
- package/src/core/ai/models/bedrock.ts +618 -0
- package/src/core/ai/models/claude-capabilities.ts +43 -0
- package/src/core/ai/models/concentrate.ts +192 -0
- package/src/core/ai/models/google.ts +154 -0
- package/src/core/ai/models/inception.ts +10 -0
- package/src/core/ai/models/index.ts +253 -0
- package/src/core/ai/models/mantle.ts +14 -0
- package/src/core/ai/models/models.test.ts +313 -0
- package/src/core/ai/models/openai.ts +409 -0
- package/src/core/ai/models/openrouter.ts +342 -0
- package/src/core/ai/models/pensar.ts +66 -0
- package/src/core/ai/native-rollout-evidence/capture.test.ts +1836 -0
- package/src/core/ai/native-rollout-evidence/capture.ts +1572 -0
- package/src/core/ai/native-rollout-evidence/content.test.ts +55 -0
- package/src/core/ai/native-rollout-evidence/content.ts +129 -0
- package/src/core/ai/native-rollout-evidence/index.ts +68 -0
- package/src/core/ai/native-rollout-evidence/provider-metadata.test.ts +85 -0
- package/src/core/ai/native-rollout-evidence/provider-metadata.ts +129 -0
- package/src/core/ai/native-rollout-evidence/recording.test.ts +398 -0
- package/src/core/ai/native-rollout-evidence/schema.test.ts +210 -0
- package/src/core/ai/native-rollout-evidence/schema.ts +353 -0
- package/src/core/ai/native-rollout-evidence/validate.ts +141 -0
- package/src/core/ai/providers/anthropic-models.test.ts +348 -0
- package/src/core/ai/providers/anthropic.ts +73 -0
- package/src/core/ai/providers/bedrock-models.test.ts +81 -0
- package/src/core/ai/providers/concentrate.live.test.ts +71 -0
- package/src/core/ai/providers/concentrate.test.ts +160 -0
- package/src/core/ai/providers/concentrate.ts +145 -0
- package/src/core/ai/providers/custom.live.test.ts +42 -0
- package/src/core/ai/providers/custom.test.ts +474 -0
- package/src/core/ai/providers/custom.ts +70 -0
- package/src/core/ai/providers/gateway-models.test.ts +648 -0
- package/src/core/ai/providers/hoonify.live.test.ts +72 -0
- package/src/core/ai/providers/hoonify.test.ts +284 -0
- package/src/core/ai/providers/hoonify.ts +32 -0
- package/src/core/ai/providers/openai-models.test.ts +356 -0
- package/src/core/ai/providers/openai-pro-fetch.test.ts +64 -0
- package/src/core/ai/providers/openai-pro-fetch.ts +32 -0
- package/src/core/ai/providers/pensar.ts +645 -0
- package/src/core/ai/providers/pensarFormatters.test.ts +272 -0
- package/src/core/ai/providers/pensarFormatters.ts +533 -0
- package/src/core/ai/providers/pensarResponsesStream.test.ts +191 -0
- package/src/core/ai/providers/pensarResponsesStream.ts +294 -0
- package/src/core/ai/providers/pensarSSE.test.ts +83 -0
- package/src/core/ai/providers/pensarSSE.ts +128 -0
- package/src/core/ai/providers/pensarSigning.ts +2 -0
- package/src/core/ai/providers/pensarStreamUsage.test.ts +79 -0
- package/src/core/ai/providers/pensarStreamUsage.ts +62 -0
- package/src/core/ai/stepContext.test.ts +61 -0
- package/src/core/ai/streamIdleTimeout.test.ts +390 -0
- package/src/core/ai/streamTelemetry.ts +90 -0
- package/src/core/ai/usage-callback.test.ts +511 -0
- package/src/core/ai/utils.native-rollout-evidence.test.ts +135 -0
- package/src/core/ai/utils.pensar.test.ts +59 -0
- package/src/core/ai/utils.ts +795 -0
- package/src/core/api/apiClient.test.ts +58 -0
- package/src/core/api/apiClient.ts +73 -0
- package/src/core/api/apps.test.ts +78 -0
- package/src/core/api/apps.ts +388 -0
- package/src/core/api/attackSurface.test.ts +24 -0
- package/src/core/api/attackSurface.ts +89 -0
- package/src/core/api/authentication.ts +8 -0
- package/src/core/api/benchmark.ts +35 -0
- package/src/core/api/blackboxPentest.test.ts +89 -0
- package/src/core/api/blackboxPentest.ts +64 -0
- package/src/core/api/clientIdentity.test.ts +61 -0
- package/src/core/api/clientIdentity.ts +57 -0
- package/src/core/api/comments.test.ts +69 -0
- package/src/core/api/constants.ts +15 -0
- package/src/core/api/domains.test.ts +35 -0
- package/src/core/api/domains.ts +32 -0
- package/src/core/api/environment.ts +47 -0
- package/src/core/api/index.ts +219 -0
- package/src/core/api/issues.test.ts +82 -0
- package/src/core/api/issues.ts +439 -0
- package/src/core/api/knowledge.ts +70 -0
- package/src/core/api/localWorker.ts +29 -0
- package/src/core/api/offesecAgent.test.ts +289 -0
- package/src/core/api/offesecAgent.ts +77 -0
- package/src/core/api/patching.ts +44 -0
- package/src/core/api/recordedRun.control.test.ts +830 -0
- package/src/core/api/recordedRun.inference.test.ts +529 -0
- package/src/core/api/recordedRun.loop.test.ts +290 -0
- package/src/core/api/recordedRun.recovery.test.ts +651 -0
- package/src/core/api/recordedRun.test.ts +646 -0
- package/src/core/api/recordedRun.ts +542 -0
- package/src/core/api/targetedPentest.test.ts +177 -0
- package/src/core/api/targetedPentest.ts +83 -0
- package/src/core/api/threatModel.ts +5 -0
- package/src/core/api/trajectoryExport.test.ts +299 -0
- package/src/core/api/trajectoryExport.ts +362 -0
- package/src/core/api/vulnerabilityReproduction.test.ts +56 -0
- package/src/core/api/vulnerabilityReproduction.ts +54 -0
- package/src/core/assets/wordlists.test.ts +85 -0
- package/src/core/assets/wordlists.ts +111 -0
- package/src/core/atif/compatibility.test.ts +107 -0
- package/src/core/atif/convert.test.ts +815 -0
- package/src/core/atif/convert.ts +1658 -0
- package/src/core/atif/fixtures/portable-bundle-v1.json +813 -0
- package/src/core/atif/index.ts +34 -0
- package/src/core/atif/schema.ts +345 -0
- package/src/core/atif/serialize.test.ts +244 -0
- package/src/core/atif/serialize.ts +419 -0
- package/src/core/atif/test-fixtures.ts +184 -0
- package/src/core/atif/validate.test.ts +188 -0
- package/src/core/atif/validate.ts +289 -0
- package/src/core/auth/connection.ts +26 -0
- package/src/core/auth/device-flow.ts +203 -0
- package/src/core/auth/gateway.ts +66 -0
- package/src/core/auth/index.ts +29 -0
- package/src/core/auth/signing.ts +25 -0
- package/src/core/auth/token.ts +140 -0
- package/src/core/auth/types.ts +106 -0
- package/src/core/auth/workspaces.ts +192 -0
- package/src/core/benchmark/index.ts +11 -0
- package/src/core/benchmark/report.ts +257 -0
- package/src/core/benchmark/runner.ts +698 -0
- package/src/core/benchmark/types.ts +80 -0
- package/src/core/cli/logLevelArgs.test.ts +83 -0
- package/src/core/cli/logLevelArgs.ts +62 -0
- package/src/core/cli/model.ts +35 -0
- package/src/core/cli/pentestMode.test.ts +24 -0
- package/src/core/cli/pentestMode.ts +23 -0
- package/src/core/cli/tuiArgs.test.ts +58 -0
- package/src/core/cli/tuiArgs.ts +28 -0
- package/src/core/config/config.test.ts +183 -0
- package/src/core/config/config.ts +201 -0
- package/src/core/config/customProviders.test.ts +183 -0
- package/src/core/config/customProviders.ts +190 -0
- package/src/core/config/index.ts +7 -0
- package/src/core/credentials/index.ts +6 -0
- package/src/core/credentials/manager.ts +313 -0
- package/src/core/credentials/types.ts +112 -0
- package/src/core/doctor.ts +138 -0
- package/src/core/eventBus.test.ts +374 -0
- package/src/core/eventBus.ts +410 -0
- package/src/core/findings/attackSurfaceRegistry.ts +294 -0
- package/src/core/findings/registry.test.ts +1680 -0
- package/src/core/findings/registry.ts +800 -0
- package/src/core/history.ts +82 -0
- package/src/core/hoonify.test.ts +250 -0
- package/src/core/hoonify.ts +163 -0
- package/src/core/http/headers.contract.test.ts +1161 -0
- package/src/core/http/parse.ts +257 -0
- package/src/core/http/redirects.test.ts +207 -0
- package/src/core/http/redirects.ts +145 -0
- package/src/core/http/targetHeaders.ts +604 -0
- package/src/core/http/targetScope.ts +52 -0
- package/src/core/http/types.ts +39 -0
- package/src/core/id/id.test.ts +88 -0
- package/src/core/id/id.ts +138 -0
- package/src/core/installation/index.ts +222 -0
- package/src/core/installation/installation.test.ts +415 -0
- package/src/core/integrations/herdr.test.ts +335 -0
- package/src/core/integrations/herdr.ts +163 -0
- package/src/core/integrations/surface/index.test.ts +534 -0
- package/src/core/integrations/surface/index.ts +224 -0
- package/src/core/integrations/surface/types.ts +29 -0
- package/src/core/integrations/wandb/client.ts +167 -0
- package/src/core/integrations/wandb/upload.test.ts +415 -0
- package/src/core/integrations/wandb/upload.ts +76 -0
- package/src/core/logger/errorLog.test.ts +98 -0
- package/src/core/logger/index.ts +214 -0
- package/src/core/logger/structured.test.ts +212 -0
- package/src/core/logger/structured.ts +207 -0
- package/src/core/memory/backend.test.ts +186 -0
- package/src/core/memory/index.ts +279 -0
- package/src/core/memory/memory.test.ts +362 -0
- package/src/core/messages/types.ts +141 -0
- package/src/core/obfuscation/engine.test.ts +314 -0
- package/src/core/obfuscation/engine.ts +647 -0
- package/src/core/obfuscation/index.ts +27 -0
- package/src/core/observability/active-root-spans.ts +30 -0
- package/src/core/observability/active-spans.ts +80 -0
- package/src/core/observability/index.ts +91 -0
- package/src/core/observability/log-correlation.test.ts +276 -0
- package/src/core/observability/payload-capture.test.ts +59 -0
- package/src/core/observability/runtime.test.ts +743 -0
- package/src/core/observability/runtime.ts +371 -0
- package/src/core/observability/shutdown.test.ts +551 -0
- package/src/core/observability/telemetry.test.ts +895 -0
- package/src/core/observability/telemetry.ts +220 -0
- package/src/core/observability/testkit.test.ts +66 -0
- package/src/core/observability/testkit.ts +97 -0
- package/src/core/observability/trace-contract.test.ts +1031 -0
- package/src/core/observability.test.ts +135 -0
- package/src/core/operator/approvalGate.test.ts +300 -0
- package/src/core/operator/approvalGate.ts +287 -0
- package/src/core/operator/index.ts +30 -0
- package/src/core/operator/types.ts +355 -0
- package/src/core/plan/index.ts +44 -0
- package/src/core/prompt-injections/index.test.ts +248 -0
- package/src/core/prompt-injections/index.ts +350 -0
- package/src/core/providers/index.ts +5 -0
- package/src/core/providers/types.ts +87 -0
- package/src/core/providers/utils.test.ts +189 -0
- package/src/core/providers/utils.ts +183 -0
- package/src/core/providers/verify.test.ts +49 -0
- package/src/core/providers/verify.ts +198 -0
- package/src/core/report/builder.test.ts +229 -0
- package/src/core/report/builder.ts +58 -0
- package/src/core/report/index.ts +13 -0
- package/src/core/report/renderers/json.test.ts +76 -0
- package/src/core/report/renderers/json.ts +5 -0
- package/src/core/report/renderers/markdown.test.ts +366 -0
- package/src/core/report/renderers/markdown.ts +133 -0
- package/src/core/report/schemas.ts +48 -0
- package/src/core/runtime/agentExecution.test.ts +94 -0
- package/src/core/runtime/agentExecution.ts +27 -0
- package/src/core/runtime/launchLocalWorker.test.ts +707 -0
- package/src/core/runtime/launchLocalWorker.ts +273 -0
- package/src/core/runtime/localRunLock.ts +118 -0
- package/src/core/runtime/localRunWorker.test.ts +381 -0
- package/src/core/runtime/localRunWorker.ts +287 -0
- package/src/core/runtime/localWorker.acceptance.test.ts +548 -0
- package/src/core/runtime/localWorkerEndpoint.test.ts +145 -0
- package/src/core/runtime/localWorkerEndpoint.ts +82 -0
- package/src/core/runtime/localWorkerProtocol.ts +176 -0
- package/src/core/runtime/localWorkerTransport.test.ts +841 -0
- package/src/core/runtime/localWorkerTransport.ts +434 -0
- package/src/core/runtime/persistenceError.ts +14 -0
- package/src/core/runtime/recordedExecution.ts +43 -0
- package/src/core/runtime/recordedRunClient.integration.test.ts +106 -0
- package/src/core/runtime/recordedRunClient.test.ts +677 -0
- package/src/core/runtime/recordedRunClient.ts +303 -0
- package/src/core/runtime/runCheckpointStore.ts +23 -0
- package/src/core/runtime/runContext.test.ts +445 -0
- package/src/core/runtime/runContext.ts +184 -0
- package/src/core/runtime/runControl.test.ts +923 -0
- package/src/core/runtime/runControl.ts +419 -0
- package/src/core/runtime/runControlStore.ts +106 -0
- package/src/core/runtime/runDeadline.test.ts +44 -0
- package/src/core/runtime/runDeadline.ts +28 -0
- package/src/core/runtime/runEvidence.test.ts +384 -0
- package/src/core/runtime/runEvidence.ts +267 -0
- package/src/core/runtime/runInference.test.ts +408 -0
- package/src/core/runtime/runInference.ts +125 -0
- package/src/core/runtime/runModelStore.ts +55 -0
- package/src/core/runtime/runObservation.ts +24 -0
- package/src/core/runtime/runRecoveryContext.test.ts +602 -0
- package/src/core/runtime/runRecoveryContext.ts +195 -0
- package/src/core/runtime/runRecoveryPlan.test.ts +851 -0
- package/src/core/runtime/runRecoveryPlan.ts +540 -0
- package/src/core/runtime/runRecoveryStore.ts +78 -0
- package/src/core/runtime/runStore.ts +148 -0
- package/src/core/runtime/runStorePath.ts +13 -0
- package/src/core/runtime/runToolStore.ts +66 -0
- package/src/core/runtime/runTools.crash.test.ts +414 -0
- package/src/core/runtime/runTools.test.ts +689 -0
- package/src/core/runtime/runTools.ts +208 -0
- package/src/core/runtime/sqliteControlStore.test.ts +917 -0
- package/src/core/runtime/sqliteControlStore.ts +555 -0
- package/src/core/runtime/sqliteModelStore.test.ts +619 -0
- package/src/core/runtime/sqliteModelStore.ts +286 -0
- package/src/core/runtime/sqliteRecoveryStore.public.test.ts +374 -0
- package/src/core/runtime/sqliteRecoveryStore.test.ts +836 -0
- package/src/core/runtime/sqliteRecoveryStore.ts +435 -0
- package/src/core/runtime/sqliteRunContext.test.ts +1000 -0
- package/src/core/runtime/sqliteRunObservation.test.ts +432 -0
- package/src/core/runtime/sqliteRunStore.test.ts +698 -0
- package/src/core/runtime/sqliteRunStore.ts +593 -0
- package/src/core/runtime/sqliteToolStore.test.ts +1231 -0
- package/src/core/runtime/sqliteToolStore.ts +419 -0
- package/src/core/runtime/testfixtures/localWorkerChild.ts +254 -0
- package/src/core/runtime/testfixtures/localWorkerLauncher.ts +15 -0
- package/src/core/runtime/testfixtures/recoveryChild.ts +159 -0
- package/src/core/services/rateLimiter/index.test.ts +106 -0
- package/src/core/services/rateLimiter/index.ts +157 -0
- package/src/core/services/rateLimiter/types.ts +10 -0
- package/src/core/session/admitted-config.test.ts +50 -0
- package/src/core/session/deprecated-headers-shim.test.ts +111 -0
- package/src/core/session/execution-metrics.test.ts +297 -0
- package/src/core/session/execution-metrics.ts +176 -0
- package/src/core/session/index.ts +1085 -0
- package/src/core/session/loader.ts +212 -0
- package/src/core/session/persistence.test.ts +1210 -0
- package/src/core/session/persistence.ts +1076 -0
- package/src/core/session/rehydrate.test.ts +393 -0
- package/src/core/session/types.ts +139 -0
- package/src/core/session/usage.test.ts +99 -0
- package/src/core/session/usage.ts +84 -0
- package/src/core/skills/builtins/index.ts +22 -0
- package/src/core/skills/builtins/pentest.ts +135 -0
- package/src/core/skills/builtins/promptInjection.ts +44 -0
- package/src/core/skills/builtins/threatModel.ts +336 -0
- package/src/core/skills/index.ts +15 -0
- package/src/core/skills/parser.test.ts +120 -0
- package/src/core/skills/parser.ts +106 -0
- package/src/core/skills/registry.test.ts +202 -0
- package/src/core/skills/registry.ts +109 -0
- package/src/core/skills/scanner.test.ts +157 -0
- package/src/core/skills/scanner.ts +115 -0
- package/src/core/skills/types.ts +45 -0
- package/src/core/skills/utils.ts +16 -0
- package/src/core/storage/index.ts +150 -0
- package/src/core/tasks/index.ts +242 -0
- package/src/core/tools/backends/capture.ts +38 -0
- package/src/core/tools/backends/collectCommand.test.ts +33 -0
- package/src/core/tools/backends/collectCommand.ts +28 -0
- package/src/core/tools/backends/helpers.ts +140 -0
- package/src/core/tools/backends/httpTransport.ts +534 -0
- package/src/core/tools/backends/index.ts +61 -0
- package/src/core/tools/backends/local.test.ts +307 -0
- package/src/core/tools/backends/local.ts +820 -0
- package/src/core/tools/backends/policy.test.ts +137 -0
- package/src/core/tools/backends/policy.ts +129 -0
- package/src/core/tools/backends/resolve.test.ts +309 -0
- package/src/core/tools/backends/resolve.ts +152 -0
- package/src/core/tools/backends/types.ts +279 -0
- package/src/core/tools/backends/whitebox.test.ts +275 -0
- package/src/core/tools/backends/whitebox.ts +14 -0
- package/src/core/tools/backends/whiteboxJobs.test.ts +375 -0
- package/src/core/tools/backends/whiteboxJobs.ts +157 -0
- package/src/core/tools/backends/windowsProgram.ts +36 -0
- package/src/core/tools/daytonaSandbox.test.ts +491 -0
- package/src/core/tools/daytonaSandbox.ts +232 -0
- package/src/core/toolset/index.ts +583 -0
- package/src/core/util/lazyLogger.ts +32 -0
- package/src/core/utils/concurrency.test.ts +204 -0
- package/src/core/utils/concurrency.ts +75 -0
- package/src/core/utils/prompt.ts +28 -0
- package/src/core/whitebox/adapters.ts +277 -0
- package/src/core/whitebox/artifacts.ts +128 -0
- package/src/core/whitebox/boundedProcess.ts +265 -0
- package/src/core/whitebox/candidates.ts +268 -0
- package/src/core/whitebox/catalog.ts +82 -0
- package/src/core/whitebox/index.ts +53 -0
- package/src/core/whitebox/jobKernel.test.ts +91 -0
- package/src/core/whitebox/jobKernel.ts +347 -0
- package/src/core/whitebox/jobSupervisor.ts +264 -0
- package/src/core/whitebox/jobs.ts +21 -0
- package/src/core/whitebox/paths.ts +94 -0
- package/src/core/whitebox/profileTransport.ts +225 -0
- package/src/core/whitebox/profiles.ts +294 -0
- package/src/core/whitebox/repoProfile.test.ts +217 -0
- package/src/core/whitebox/repoProfile.ts +256 -0
- package/src/core/whitebox/types.ts +189 -0
- package/src/core/whitebox/whitebox.test.ts +789 -0
- package/src/core/workflows/fastStrike.seams.test.ts +217 -0
- package/src/core/workflows/fastStrike.test.ts +29 -0
- package/src/core/workflows/fastStrike.ts +239 -0
- package/src/core/workflows/pentest.test.ts +575 -0
- package/src/core/workflows/pentest.ts +1022 -0
- package/src/core/workflows/seams.test.ts +386 -0
- package/src/core/workflows/seams.ts +276 -0
- package/src/core/workflows/threatModel.ts +108 -0
- package/src/core/workflows/usage-forwarding.test.ts +203 -0
- package/src/core/workflows/whiteboxAttackSurface.test.ts +695 -0
- package/src/core/workflows/whiteboxAttackSurface.ts +1740 -0
- package/src/index.ts +49 -0
- package/src/lib/attack-path/types.ts +13 -0
- package/src/lib/cvss/calculator.test.ts +2090 -0
- package/src/lib/cvss/calculator.ts +643 -0
- package/src/lib/cvss/index.ts +65 -0
- package/src/lib/cvss/macrovector-scores.ts +402 -0
- package/src/lib/cvss/types.ts +241 -0
- package/src/lib/cwe/cwe-catalog.ts +444 -0
- package/src/lib/cwe/types.test.ts +142 -0
- package/src/lib/cwe/types.ts +37 -0
- package/src/lib/cwe/validate.test.ts +110 -0
- package/src/lib/cwe/validate.ts +53 -0
- package/src/lib/evidence/types.ts +9 -0
- package/src/tests/agentWorkingDirectory.test.ts +175 -0
- package/src/tests/attackSurface.test.ts +35 -0
- package/src/tests/auth.test.ts +196 -0
- package/src/tests/authCookieExport.test.ts +143 -0
- package/src/tests/authPentestHandoff.test.ts +231 -0
- package/src/tests/browserCookies.test.ts +128 -0
- package/src/tests/credentialManager.test.ts +657 -0
- package/src/tests/data/console.openapi.json +1037 -0
- package/src/tests/data/console.sitemap.xml +348 -0
- package/src/tests/delegateAuthMerge.test.ts +48 -0
- package/src/tui/auto-copy.ts +36 -0
- package/src/tui/clipboard.ts +65 -0
- package/src/tui/command-registry.test.ts +124 -0
- package/src/tui/command-registry.ts +645 -0
- package/src/tui/command-router.ts +81 -0
- package/src/tui/components/agent-display.tsx +480 -0
- package/src/tui/components/ascii-art.tsx +225 -0
- package/src/tui/components/chat/approval-inline.tsx +51 -0
- package/src/tui/components/chat/config-view.tsx +279 -0
- package/src/tui/components/chat/home-view.tsx +288 -0
- package/src/tui/components/chat/index.tsx +161 -0
- package/src/tui/components/chat/input-area.tsx +529 -0
- package/src/tui/components/chat/lib/play-core/num.ts +102 -0
- package/src/tui/components/chat/lib/wave-simulation.ts +124 -0
- package/src/tui/components/chat/loading-indicator.test.ts +33 -0
- package/src/tui/components/chat/loading-indicator.tsx +131 -0
- package/src/tui/components/chat/message-list.tsx +265 -0
- package/src/tui/components/chat/petri-animation.tsx +175 -0
- package/src/tui/components/chat/plan-review-message.tsx +49 -0
- package/src/tui/components/chat/questions-form.tsx +756 -0
- package/src/tui/components/commands/__tests__/recorded-runs-lifecycle.tsx +907 -0
- package/src/tui/components/commands/advanced-settings.tsx +94 -0
- package/src/tui/components/commands/api-key-input.tsx +122 -0
- package/src/tui/components/commands/auth-flow-logic.test.ts +58 -0
- package/src/tui/components/commands/auth-flow-logic.ts +30 -0
- package/src/tui/components/commands/auth-flow.tsx +702 -0
- package/src/tui/components/commands/credits-flow.tsx +210 -0
- package/src/tui/components/commands/help-dialog.tsx +238 -0
- package/src/tui/components/commands/models-display.tsx +111 -0
- package/src/tui/components/commands/operator-wizard.tsx +328 -0
- package/src/tui/components/commands/provider-manager.tsx +241 -0
- package/src/tui/components/commands/provider-selection.tsx +129 -0
- package/src/tui/components/commands/recorded-runs.test.ts +40 -0
- package/src/tui/components/commands/recorded-runs.tsx +793 -0
- package/src/tui/components/commands/sessions-display.tsx +365 -0
- package/src/tui/components/commands/shortcuts-dialog.tsx +52 -0
- package/src/tui/components/commands/skills-dialog.tsx +308 -0
- package/src/tui/components/commands/theme-picker.tsx +177 -0
- package/src/tui/components/commands/web-wizard.tsx +965 -0
- package/src/tui/components/dialog-layout.tsx +73 -0
- package/src/tui/components/error-boundary.tsx +82 -0
- package/src/tui/components/footer.tsx +101 -0
- package/src/tui/components/input.tsx +43 -0
- package/src/tui/components/loaders.tsx +784 -0
- package/src/tui/components/model-picker/ModelPicker.tsx +907 -0
- package/src/tui/components/model-picker/ModelPickerDialog.tsx +75 -0
- package/src/tui/components/model-picker/index.ts +2 -0
- package/src/tui/components/model-picker/model-navigation.test.ts +102 -0
- package/src/tui/components/model-picker/model-navigation.ts +54 -0
- package/src/tui/components/model-picker/model-search.test.ts +62 -0
- package/src/tui/components/model-picker/model-search.ts +42 -0
- package/src/tui/components/model-picker/model-visibility.test.ts +65 -0
- package/src/tui/components/model-picker/model-visibility.ts +59 -0
- package/src/tui/components/operator-dashboard/conversation.test.ts +431 -0
- package/src/tui/components/operator-dashboard/conversation.ts +179 -0
- package/src/tui/components/operator-dashboard/display-state.test.ts +369 -0
- package/src/tui/components/operator-dashboard/display-state.ts +163 -0
- package/src/tui/components/operator-dashboard/herdr-state.test.ts +162 -0
- package/src/tui/components/operator-dashboard/herdr-state.ts +81 -0
- package/src/tui/components/operator-dashboard/index.tsx +2044 -0
- package/src/tui/components/operator-dashboard/logic.test.ts +753 -0
- package/src/tui/components/operator-dashboard/logic.ts +465 -0
- package/src/tui/components/operator-dashboard/queue.test.ts +147 -0
- package/src/tui/components/operator-dashboard/queue.ts +55 -0
- package/src/tui/components/operator-dashboard/queued-messages.tsx +50 -0
- package/src/tui/components/operator-dashboard/run-events.test.ts +915 -0
- package/src/tui/components/operator-dashboard/run-events.ts +507 -0
- package/src/tui/components/operator-dashboard/run-tracing.test.ts +206 -0
- package/src/tui/components/operator-dashboard/run-tracing.ts +105 -0
- package/src/tui/components/operator-dashboard/subagent-detail-view.tsx +51 -0
- package/src/tui/components/operator-dashboard/subagent-dialog.tsx +142 -0
- package/src/tui/components/operator-dashboard/subagent-hub.test.ts +162 -0
- package/src/tui/components/operator-dashboard/subagent-hub.tsx +266 -0
- package/src/tui/components/operator-dashboard/subagent-state.test.ts +431 -0
- package/src/tui/components/operator-dashboard/subagent-state.ts +404 -0
- package/src/tui/components/operator-dashboard/subagent-status-bar.tsx +80 -0
- package/src/tui/components/operator-dashboard/tool-argument-buffer.test.ts +317 -0
- package/src/tui/components/operator-dashboard/tool-arguments.perf.test.ts +121 -0
- package/src/tui/components/operator-dashboard/welcome-logo.tsx +79 -0
- package/src/tui/components/operator-dashboard/workflow-data.test.ts +291 -0
- package/src/tui/components/operator-dashboard/workflow-data.ts +130 -0
- package/src/tui/components/report-viewer-dialog.tsx +98 -0
- package/src/tui/components/responsible-use-disclosure.tsx +55 -0
- package/src/tui/components/screenshot-modal.tsx +204 -0
- package/src/tui/components/shared/__tests__/prompt-input-lifecycle.tsx +64 -0
- package/src/tui/components/shared/__tests__/tool-renderer-lifecycle.tsx +87 -0
- package/src/tui/components/shared/action-label.test.ts +142 -0
- package/src/tui/components/shared/action-label.ts +18 -0
- package/src/tui/components/shared/ascii-spinner.tsx +40 -0
- package/src/tui/components/shared/compacting-icon.tsx +18 -0
- package/src/tui/components/shared/dialog-controls.tsx +76 -0
- package/src/tui/components/shared/index.ts +38 -0
- package/src/tui/components/shared/markdown-viewer.tsx +188 -0
- package/src/tui/components/shared/markdown.ts +239 -0
- package/src/tui/components/shared/message-renderer.tsx +178 -0
- package/src/tui/components/shared/message-utils.ts +175 -0
- package/src/tui/components/shared/pentest-workflow-display.tsx +330 -0
- package/src/tui/components/shared/prompt-input-lifecycle.test.ts +22 -0
- package/src/tui/components/shared/prompt-input-logic.test.ts +782 -0
- package/src/tui/components/shared/prompt-input-logic.ts +423 -0
- package/src/tui/components/shared/prompt-input.tsx +782 -0
- package/src/tui/components/shared/result-registry.test.ts +90 -0
- package/src/tui/components/shared/result-registry.ts +900 -0
- package/src/tui/components/shared/syntax-highlight.ts +242 -0
- package/src/tui/components/shared/tool-registry.test.ts +59 -0
- package/src/tui/components/shared/tool-registry.ts +280 -0
- package/src/tui/components/shared/tool-renderer.test.ts +13 -0
- package/src/tui/components/shared/tool-renderer.tsx +237 -0
- package/src/tui/components/shared/type-guards.ts +64 -0
- package/src/tui/components/shared/use-paste-extmarks.ts +109 -0
- package/src/tui/components/switch.tsx +81 -0
- package/src/tui/components/terminal-focus-handler.tsx +34 -0
- package/src/tui/components/toast.tsx +82 -0
- package/src/tui/components/usage-labels.test.ts +191 -0
- package/src/tui/components/usage-labels.ts +78 -0
- package/src/tui/console-theme.ts +59 -0
- package/src/tui/context/agent.tsx +251 -0
- package/src/tui/context/command.tsx +291 -0
- package/src/tui/context/config.tsx +59 -0
- package/src/tui/context/dialog.tsx +206 -0
- package/src/tui/context/dimensions.tsx +31 -0
- package/src/tui/context/focus-ownership.test.ts +26 -0
- package/src/tui/context/focus-ownership.ts +12 -0
- package/src/tui/context/focus.tsx +86 -0
- package/src/tui/context/herdr.tsx +28 -0
- package/src/tui/context/input.tsx +45 -0
- package/src/tui/context/keybinding.tsx +92 -0
- package/src/tui/context/obfuscation.tsx +114 -0
- package/src/tui/context/route.tsx +127 -0
- package/src/tui/context/session-usage.test.ts +295 -0
- package/src/tui/context/session-usage.ts +204 -0
- package/src/tui/context/session.tsx +62 -0
- package/src/tui/context/toast.tsx +66 -0
- package/src/tui/generated-ascii-art.json +1 -0
- package/src/tui/generated-ascii-art.json.d.ts +2 -0
- package/src/tui/herdr-startup.test.ts +157 -0
- package/src/tui/hooks/use-sessions-list.ts +165 -0
- package/src/tui/index.tsx +838 -0
- package/src/tui/keybindings/index.ts +126 -0
- package/src/tui/keybindings/registry.ts +146 -0
- package/src/tui/keybindings-registry.ts +43 -0
- package/src/tui/obfuscation/patch.ts +139 -0
- package/src/tui/terminal-focus.ts +218 -0
- package/src/tui/theme/colors.ts +43 -0
- package/src/tui/theme/context.tsx +137 -0
- package/src/tui/theme/detect-mode.ts +56 -0
- package/src/tui/theme/index.ts +75 -0
- package/src/tui/theme/registry.ts +29 -0
- package/src/tui/theme/themes/apex.ts +190 -0
- package/src/tui/theme/themes/ayu.ts +189 -0
- package/src/tui/theme/themes/catppuccin.ts +189 -0
- package/src/tui/theme/themes/dracula.ts +190 -0
- package/src/tui/theme/themes/everforest.ts +189 -0
- package/src/tui/theme/themes/flexoki.ts +190 -0
- package/src/tui/theme/themes/github.ts +189 -0
- package/src/tui/theme/themes/gruvbox.ts +189 -0
- package/src/tui/theme/themes/index.ts +54 -0
- package/src/tui/theme/themes/kanagawa.ts +189 -0
- package/src/tui/theme/themes/material.ts +190 -0
- package/src/tui/theme/themes/monokai.ts +190 -0
- package/src/tui/theme/themes/nightfox.ts +189 -0
- package/src/tui/theme/themes/nord.ts +190 -0
- package/src/tui/theme/themes/onedark.ts +190 -0
- package/src/tui/theme/themes/rose-pine.ts +189 -0
- package/src/tui/theme/themes/solarized.ts +189 -0
- package/src/tui/theme/themes/tokyonight.ts +189 -0
- package/src/tui/theme/themes/vesper.ts +191 -0
- package/src/tui/theme/types.ts +143 -0
- package/src/tui/utils/command-flags.test.ts +269 -0
- package/src/tui/utils/command-flags.ts +377 -0
- package/src/tui/utils/kitty-graphics.ts +76 -0
- package/src/tui/utils/open-file.ts +37 -0
- package/src/tui/utils/open-report.ts +34 -0
- package/src/tui/utils/open-url.ts +39 -0
- package/src/tui/utils/paste.ts +8 -0
- package/src/tui/utils/scroll.ts +81 -0
- package/src/util/errors.ts +58 -0
- package/src/util/lock.ts +100 -0
- package/src/util/name.ts +148 -0
- package/src/util/url.test.ts +162 -0
- package/src/util/url.ts +107 -0
- package/build/agent-13rrhp8d.js +0 -20
- package/build/agent-zbj2331s.js +0 -30
- package/build/authentication-f4j3w5vs.js +0 -20
- package/build/blackboxAgent-v2vx9ws4.js +0 -20
- package/build/blackboxPentest-w5nwzpvk.js +0 -70
- package/build/cli-5wemv37a.js +0 -194
- package/build/cli-7s062hr6.js +0 -22
- package/build/cli-9qbxkhye.js +0 -55
- package/build/cli-avmhkjtv.js +0 -22961
- package/build/cli-g3czc3jz.js +0 -204
- package/build/cli-ww7hbazg.js +0 -88
- package/build/index-18vyy6mj.js +0 -19
- package/build/index-5wh7gq37.js +0 -12858
- package/build/index-e23zc8g4.js +0 -34
- package/build/index-hnwhswqj.js +0 -213
- package/build/index-wkmnr4nm.js +0 -39
- package/build/index-ywmfnd30.js +0 -12
- package/build/offesecAgent-c97pqzcn.js +0 -27
- package/build/pentest-4p5jt7gj.js +0 -30
- package/build/pentests-v98eg8n3.js +0 -92
- package/build/threatModel-81d4rcbk.js +0 -29
- /package/build/{cli-c8131c4q.js → cli-0wsh8j2t.js} +0 -0
- /package/build/{cli-9pbk8m32.js → cli-ag6jtndp.js} +0 -0
- /package/build/{cli-e08r86zk.js → cli-b3dvxjgk.js} +0 -0
- /package/build/{cli-fw5r7pfj.js → cli-q126f6ef.js} +0 -0
- /package/build/{cli-9fsre5pt.js → cli-qba2x69h.js} +0 -0
- /package/build/{cli-7q3ae3ft.js → cli-z82n3qk1.js} +0 -0
|
@@ -0,0 +1,1610 @@
|
|
|
1
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { SpanStatusCode } from "@opentelemetry/api";
|
|
4
|
+
import type {
|
|
5
|
+
ModelMessage,
|
|
6
|
+
StopCondition,
|
|
7
|
+
StreamTextResult,
|
|
8
|
+
TextStreamPart,
|
|
9
|
+
ToolSet,
|
|
10
|
+
} from "ai";
|
|
11
|
+
import { hasToolCall } from "ai";
|
|
12
|
+
import { normalizeStepUsage, streamResponse } from "../../ai";
|
|
13
|
+
import { AgentEventBus, type StreamIdContext } from "../../eventBus";
|
|
14
|
+
import { newMessageId, newPartId } from "../../id/id";
|
|
15
|
+
import { createLogger } from "../../logger/structured";
|
|
16
|
+
import {
|
|
17
|
+
getApexTracer,
|
|
18
|
+
registerActiveRootSpan,
|
|
19
|
+
shouldRecordAiPayloads,
|
|
20
|
+
unregisterActiveRootSpan,
|
|
21
|
+
withSubagentSessionBaggage,
|
|
22
|
+
} from "../../observability";
|
|
23
|
+
import type { ApprovalGate } from "../../operator";
|
|
24
|
+
import { ApprovalDeniedError } from "../../operator";
|
|
25
|
+
import type { RunContextRecorder } from "../../runtime/runContext";
|
|
26
|
+
import { create as createSession, type SessionInfo } from "../../session";
|
|
27
|
+
import { scopedLogger } from "../../util/lazyLogger";
|
|
28
|
+
import {
|
|
29
|
+
createInterruptedStepFinalizer,
|
|
30
|
+
type FinalizeInterruptedStepInput,
|
|
31
|
+
} from "./interruptedStepFinalization";
|
|
32
|
+
import { AgentMessageWriter } from "./messagePersistence";
|
|
33
|
+
import { buildBaseSystemPrompt, buildSessionWorkspaceSection } from "./prompt";
|
|
34
|
+
import { wrapRecordedTools } from "./recordedTools";
|
|
35
|
+
import {
|
|
36
|
+
buildBundledAssetsSection,
|
|
37
|
+
buildRuntimeContextSection,
|
|
38
|
+
peekSettledRuntimeFacts,
|
|
39
|
+
probeRuntimeFacts,
|
|
40
|
+
type RuntimeExecutionFacts,
|
|
41
|
+
resolveCommandPlatform,
|
|
42
|
+
UNKNOWN_FACTS,
|
|
43
|
+
} from "./runtimeContext";
|
|
44
|
+
import { responseArgBytes, StreamDiagnostics } from "./streamDiagnostics";
|
|
45
|
+
import { inProcessSubagentSpawner } from "./subagentSpawner";
|
|
46
|
+
import { ToolLifecycleTracker } from "./toolLifecycle";
|
|
47
|
+
import {
|
|
48
|
+
ASK_USER_QUESTIONS_TOOL_NAME,
|
|
49
|
+
CallbackListenerRegistry,
|
|
50
|
+
createResponseTool,
|
|
51
|
+
createToolsForNames,
|
|
52
|
+
EMAIL_TOOL_NAMES_ACTIVE,
|
|
53
|
+
FAST_STRIKE_EXCLUDED_TOOL_NAMES,
|
|
54
|
+
listToolRegistryNames,
|
|
55
|
+
PerCommandShell,
|
|
56
|
+
PLAN_MODE_TOOL_NAMES,
|
|
57
|
+
PlaywrightMcpSession,
|
|
58
|
+
RESPONSE_TOOL_NAME,
|
|
59
|
+
resolveBrowserHeaderPolicy,
|
|
60
|
+
SEND_EMAIL_TOOL_NAME,
|
|
61
|
+
SMS_TOOL_NAMES_ACTIVE,
|
|
62
|
+
sessionHasSmsPasswordless,
|
|
63
|
+
WORKSPACE_TOOL_NAMES,
|
|
64
|
+
WORKSPACE_WRITE_TOOL_NAMES,
|
|
65
|
+
} from "./tools";
|
|
66
|
+
import type { ToolContext } from "./tools/types";
|
|
67
|
+
import { StepTraceWriter } from "./trace";
|
|
68
|
+
import type {
|
|
69
|
+
AgentMode,
|
|
70
|
+
CreateAgentInput,
|
|
71
|
+
OffensiveSecurityAgentInput,
|
|
72
|
+
StreamIdFactory,
|
|
73
|
+
} from "./types";
|
|
74
|
+
|
|
75
|
+
function isGenericAbortError(error: unknown): boolean {
|
|
76
|
+
return (
|
|
77
|
+
error instanceof Error &&
|
|
78
|
+
error.name === "AbortError" &&
|
|
79
|
+
error.cause === undefined &&
|
|
80
|
+
/^(?:Aborted|Agent aborted by user|(?:This|The) operation was aborted|The user aborted a request)\.?$/.test(
|
|
81
|
+
error.message,
|
|
82
|
+
)
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function agentAbortReason(signal: AbortSignal): unknown {
|
|
87
|
+
const reason: unknown = signal.reason;
|
|
88
|
+
return reason === undefined || isGenericAbortError(reason)
|
|
89
|
+
? new DOMException("Agent aborted by user", "AbortError")
|
|
90
|
+
: reason;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const log = scopedLogger(() => createLogger("approval-gate"));
|
|
94
|
+
|
|
95
|
+
// Opt-in `response` tool lifecycle tracer (RESPONSE_DEBUG=1) for the empty-`{}` / "Tool call did not complete" loop on threat-model sub-agents.
|
|
96
|
+
const RESPONSE_DEBUG =
|
|
97
|
+
process.env.RESPONSE_DEBUG === "1" || process.env.RESPONSE_DEBUG === "true";
|
|
98
|
+
const rlog = scopedLogger(() => createLogger("response-debug"));
|
|
99
|
+
|
|
100
|
+
const WORKSPACE_TOOL_NAME_SET = new Set<string>(WORKSPACE_TOOL_NAMES);
|
|
101
|
+
const WORKSPACE_WRITE_TOOL_NAME_SET = new Set<string>(
|
|
102
|
+
WORKSPACE_WRITE_TOOL_NAMES,
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
// Tools whose presence means backend-probed execution facts can change what
|
|
106
|
+
// the agent should attempt: command execution, native file tools, and PoC
|
|
107
|
+
// runs. Agents holding none of these skip the runtime probe entirely.
|
|
108
|
+
const RUNTIME_CAPABLE_TOOL_NAMES = new Set<string>([
|
|
109
|
+
"execute_command",
|
|
110
|
+
"read_file",
|
|
111
|
+
"list_files",
|
|
112
|
+
"glob",
|
|
113
|
+
"grep",
|
|
114
|
+
"create_file",
|
|
115
|
+
"update_file",
|
|
116
|
+
"delete_file",
|
|
117
|
+
"apply_patch",
|
|
118
|
+
"document_vulnerability",
|
|
119
|
+
]);
|
|
120
|
+
|
|
121
|
+
const WORKSPACE_TARGET_RE = /\b(?:console|workspace)\b/i;
|
|
122
|
+
const WORKSPACE_NOUN_RE =
|
|
123
|
+
/\b(?:domains?|apps?|applications?|endpoints?|threat\s+models?|attack\s+surfaces?)\b/i;
|
|
124
|
+
const WORKSPACE_READ_REQUEST_RE =
|
|
125
|
+
/(?:\b(?:list|show|find|search|get)\s+(?:(?:me|a|an|the|my|our|all|any|list|of|for|in|within|registered|existing|available|console|workspace|which)\s+){0,8}(?:domains?|apps?|applications?|endpoints?)\b|\b(?:what|which)\s+(?:(?:of|a|an|the|my|our|all|any|are|is|do|does|we|i|have|has|there|registered|existing|available|console|workspace)\s+){0,8}(?:domains?|apps?|applications?|endpoints?)\b)/i;
|
|
126
|
+
const WORKSPACE_WRITE_ACTION = String.raw`(?:add|create|register|import|update|edit|change|set|correct|repair|link|unlink|rename|break\s+down)`;
|
|
127
|
+
const WORKSPACE_EXPLICIT_WRITE_REQUEST_RE = new RegExp(
|
|
128
|
+
String.raw`(?:^\s*|[.?!;\n]\s*|\b(?:please|kindly)\s+|\b(?:can|could|would|will)\s+you\s+|\b(?:i|we)\s+(?:want|need)\s+(?:you\s+)?to\s+|\bi(?:['’]d| would)\s+like\s+(?:you\s+)?to\s+|\blet['’]s\s+|\bgo\s+ahead\s+and\s+)${WORKSPACE_WRITE_ACTION}\b`,
|
|
129
|
+
"i",
|
|
130
|
+
);
|
|
131
|
+
const WORKSPACE_NEGATED_WRITE_REQUEST_RE = new RegExp(
|
|
132
|
+
String.raw`\b(?:do\s+not|don't|never|avoid)\b[^.?!;\n]{0,40}\b${WORKSPACE_WRITE_ACTION}\b`,
|
|
133
|
+
"i",
|
|
134
|
+
);
|
|
135
|
+
const WORKSPACE_CLAUSE_BOUNDARY_RE = new RegExp(
|
|
136
|
+
String.raw`(?:[.!?;]+(?=\s|$)\s*|\n+|\s+(?:but|however)\s+|\s+and\s+(?=(?:(?:do\s+not|don't|never|avoid)\s+)?${WORKSPACE_WRITE_ACTION}\b))`,
|
|
137
|
+
"i",
|
|
138
|
+
);
|
|
139
|
+
// Sentence delimiters only (never splits `example.com`), so a leading
|
|
140
|
+
// capability question can be scoped to the whole sentence before the
|
|
141
|
+
// clause-level `and`/`but` split runs.
|
|
142
|
+
const WORKSPACE_SENTENCE_BOUNDARY_RE = /(?:[.!?;]+(?=\s|$)\s*|\n+)/;
|
|
143
|
+
// Capability/permission questions ("Can I … and create …", "How do I …")
|
|
144
|
+
// stay read-only: the interrogative governs every coordinated clause, so the
|
|
145
|
+
// clause split must not let a trailing bare write verb pass as an imperative.
|
|
146
|
+
// Requests aimed at the agent ("Can you …", "Please …", "I'd like to …") are
|
|
147
|
+
// not questions and are handled by WORKSPACE_EXPLICIT_WRITE_REQUEST_RE.
|
|
148
|
+
const WORKSPACE_CAPABILITY_QUESTION_RE =
|
|
149
|
+
/^\s*(?:(?:so|and|also|then|ok|okay|well|hey|hi|actually|but)[,\s]+)*(?:is\s+it\s+possible\b|what\s+if\b|how\s+(?:do|can|could|should|would|shall|might)\s+(?:i|we)\b|(?:can|could|should|would|may|will|do|does|did|am|are|is|shall|have|has)\s+(?:i|we)\b)/i;
|
|
150
|
+
const WORKSPACE_CREATE_REQUEST_RE =
|
|
151
|
+
/\b(?:add|create|register|import)\s+(?:(?:the|this|that|a|an|my|our|existing|new|current|connected|authenticated|console|workspace|attached|provided)\s+){0,4}(?:domains?|apps?|applications?|endpoints?|threat\s+models?|attack\s+surfaces?)\b/i;
|
|
152
|
+
const WORKSPACE_DOMAIN_HOST_WRITE_RE =
|
|
153
|
+
/\b(?:add|create|register|import|link)\s+(?:https?:\/\/)?(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}(?::\d+)?(?:\/\S*)?\s+(?:to|in|under)\s+(?:(?:the|my|our|connected|authenticated)\s+)?(?:console|workspace)\b/i;
|
|
154
|
+
const WORKSPACE_APP_FIELD_UPDATE_RE =
|
|
155
|
+
/\b(?:update|edit|change|set|correct|repair)\s+(?:(?:the|this|that|my|our|existing|current|connected|authenticated|console|workspace)\s+){0,4}(?:apps?|applications?)(?:['’]s)?\s+(?:name|description|type|framework|domain|disallowed\s+actions?)\s+(?:(?:to|as|with|from)\b|[:=])/i;
|
|
156
|
+
const WORKSPACE_ENDPOINT_FIELD_UPDATE_RE =
|
|
157
|
+
/\b(?:update|edit|change|set|correct|repair)\s+(?:(?:the|this|that|my|our|existing|current|connected|authenticated|console|workspace)\s+){0,4}endpoints?(?:['’]s)?\s+(?:path|route|url|description|type|transport|location|source(?:\s+location)?|start\s+line|end\s+line|line\s+numbers?|objectives?|authentication(?:\s+requirements?)?|business\s+logic|threat\s+model|parent\s+application)\s+(?:(?:to|as|with|from)\b|[:=])/i;
|
|
158
|
+
const WORKSPACE_LINK_CLAUSE_GAP = String.raw`[^.?!;\n]{0,80}`;
|
|
159
|
+
const WORKSPACE_APP_RESOURCE = String.raw`\b(?:apps?|applications?)\b`;
|
|
160
|
+
const WORKSPACE_DOMAIN_RESOURCE = String.raw`\b(?:domains?|(?:https?:\/\/)?(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,})\b`;
|
|
161
|
+
const WORKSPACE_APP_DOMAIN_LINK_RE = new RegExp(
|
|
162
|
+
String.raw`(?:\blink\b${WORKSPACE_LINK_CLAUSE_GAP}${WORKSPACE_APP_RESOURCE}${WORKSPACE_LINK_CLAUSE_GAP}\bto\b${WORKSPACE_LINK_CLAUSE_GAP}${WORKSPACE_DOMAIN_RESOURCE}|\blink\b${WORKSPACE_LINK_CLAUSE_GAP}${WORKSPACE_DOMAIN_RESOURCE}${WORKSPACE_LINK_CLAUSE_GAP}\bto\b${WORKSPACE_LINK_CLAUSE_GAP}${WORKSPACE_APP_RESOURCE}|\bunlink\b${WORKSPACE_LINK_CLAUSE_GAP}${WORKSPACE_APP_RESOURCE}${WORKSPACE_LINK_CLAUSE_GAP}\bfrom\b${WORKSPACE_LINK_CLAUSE_GAP}${WORKSPACE_DOMAIN_RESOURCE}|\bunlink\b${WORKSPACE_LINK_CLAUSE_GAP}${WORKSPACE_DOMAIN_RESOURCE}${WORKSPACE_LINK_CLAUSE_GAP}\bfrom\b${WORKSPACE_LINK_CLAUSE_GAP}${WORKSPACE_APP_RESOURCE})`,
|
|
163
|
+
"i",
|
|
164
|
+
);
|
|
165
|
+
const WORKSPACE_APP_RENAME_RE =
|
|
166
|
+
/\brename\s+(?:(?:the|this|that|my|our|existing|current|connected|authenticated|console|workspace)\s+){0,4}(?:apps?|applications?)\b[^.?!;\n]{0,60}\b(?:to|as)\b/i;
|
|
167
|
+
const WORKSPACE_BREAK_DOWN_IMPORT_RE =
|
|
168
|
+
/\bbreak\s+down\b[^.?!;\n]{0,100}\b(?:threat\s+models?|attack\s+surfaces?)\b[^.?!;\n]{0,100}\b(?:into|as)\b[^.?!;\n]{0,40}\b(?:apps?|applications?|endpoints?)\b/i;
|
|
169
|
+
|
|
170
|
+
function hasExplicitWorkspaceWriteRequest(
|
|
171
|
+
prompt: string,
|
|
172
|
+
targetsWorkspace: boolean,
|
|
173
|
+
): boolean {
|
|
174
|
+
return prompt.split(WORKSPACE_SENTENCE_BOUNDARY_RE).some((sentence) => {
|
|
175
|
+
// A capability question governs its whole sentence, so its clauses stay
|
|
176
|
+
// read-only even when `and`/`but` splits a bare write verb off the front.
|
|
177
|
+
if (WORKSPACE_CAPABILITY_QUESTION_RE.test(sentence)) return false;
|
|
178
|
+
|
|
179
|
+
return sentence.split(WORKSPACE_CLAUSE_BOUNDARY_RE).some((clause) => {
|
|
180
|
+
if (
|
|
181
|
+
!WORKSPACE_EXPLICIT_WRITE_REQUEST_RE.test(clause) ||
|
|
182
|
+
WORKSPACE_NEGATED_WRITE_REQUEST_RE.test(clause)
|
|
183
|
+
) {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return (
|
|
188
|
+
WORKSPACE_DOMAIN_HOST_WRITE_RE.test(clause) ||
|
|
189
|
+
(targetsWorkspace &&
|
|
190
|
+
(WORKSPACE_CREATE_REQUEST_RE.test(clause) ||
|
|
191
|
+
WORKSPACE_APP_FIELD_UPDATE_RE.test(clause) ||
|
|
192
|
+
WORKSPACE_ENDPOINT_FIELD_UPDATE_RE.test(clause) ||
|
|
193
|
+
WORKSPACE_APP_DOMAIN_LINK_RE.test(clause) ||
|
|
194
|
+
WORKSPACE_APP_RENAME_RE.test(clause) ||
|
|
195
|
+
WORKSPACE_BREAK_DOWN_IMPORT_RE.test(clause)))
|
|
196
|
+
);
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// ponytail: current-message opt-in avoids persistent workspace capability state.
|
|
202
|
+
//
|
|
203
|
+
// Read (`list_*`) and write (`create_*` / `update_*`) tools are gated
|
|
204
|
+
// separately: recon phrasing (find/search/show/list a domain, app, or endpoint on the "console"/
|
|
205
|
+
// "workspace") is common in ordinary Operator pentests, so it must never
|
|
206
|
+
// expose mutation tools. Write tools require an explicit mutation request —
|
|
207
|
+
// a write verb, a "break down …" import, or a direct tool-name mention.
|
|
208
|
+
export function filterWorkspaceToolsForRun(
|
|
209
|
+
activeTools: string[],
|
|
210
|
+
prompt: string,
|
|
211
|
+
hasInteractiveApprovalGate: boolean,
|
|
212
|
+
): string[] {
|
|
213
|
+
const gated =
|
|
214
|
+
hasInteractiveApprovalGate && !prompt.trimStart().startsWith("<skill ");
|
|
215
|
+
|
|
216
|
+
if (!gated) {
|
|
217
|
+
return activeTools.filter((name) => !WORKSPACE_TOOL_NAME_SET.has(name));
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const targetsWorkspace =
|
|
221
|
+
WORKSPACE_TARGET_RE.test(prompt) && WORKSPACE_NOUN_RE.test(prompt);
|
|
222
|
+
|
|
223
|
+
const writeRequested =
|
|
224
|
+
WORKSPACE_WRITE_TOOL_NAMES.some((name) => prompt.includes(name)) ||
|
|
225
|
+
hasExplicitWorkspaceWriteRequest(prompt, targetsWorkspace);
|
|
226
|
+
|
|
227
|
+
const readRequested =
|
|
228
|
+
writeRequested ||
|
|
229
|
+
WORKSPACE_TOOL_NAMES.some((name) => prompt.includes(name)) ||
|
|
230
|
+
(targetsWorkspace && WORKSPACE_READ_REQUEST_RE.test(prompt));
|
|
231
|
+
|
|
232
|
+
return activeTools.filter((name) => {
|
|
233
|
+
if (WORKSPACE_WRITE_TOOL_NAME_SET.has(name)) return writeRequested;
|
|
234
|
+
if (WORKSPACE_TOOL_NAME_SET.has(name)) return readRequested;
|
|
235
|
+
return true;
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* General-purpose offensive security agent harness.
|
|
241
|
+
*
|
|
242
|
+
* The agent **owns tool creation** — all available tools are built from
|
|
243
|
+
* the session context, and specific agents select which ones to activate
|
|
244
|
+
* via the `activeTools` array (passed through to the AI SDK).
|
|
245
|
+
*
|
|
246
|
+
* The stream is created lazily on first consumption (see {@link streamReady}
|
|
247
|
+
* and {@link streamResult}) — after backend-probed runtime facts settle —
|
|
248
|
+
* so the AI SDK telemetry nests under this agent's span — no separate `.run()`.
|
|
249
|
+
*
|
|
250
|
+
* @typeParam TResult - The type returned by {@link consume}. When the input
|
|
251
|
+
* includes a `resolveResult` function, `consume()` awaits it after the
|
|
252
|
+
* stream finishes and returns the value. Defaults to `void`.
|
|
253
|
+
*
|
|
254
|
+
* ## Consumption (pick one — stream is single-read)
|
|
255
|
+
*
|
|
256
|
+
* **1. Emit to EventBus via `.consume()` → `TResult`**
|
|
257
|
+
* ```ts
|
|
258
|
+
* const bus = new AgentEventBus();
|
|
259
|
+
* bus.on("text-delta", (e) => process.stdout.write(e.text));
|
|
260
|
+
* bus.on("tool-call-complete", (e) => console.log(`→ ${e.toolName}`));
|
|
261
|
+
* const agent = new OffensiveSecurityAgent({ ..., eventBus: bus });
|
|
262
|
+
* const result = await agent.consume();
|
|
263
|
+
* ```
|
|
264
|
+
*
|
|
265
|
+
* **2. `for await` directly on the agent**
|
|
266
|
+
* ```ts
|
|
267
|
+
* for await (const chunk of agent) { ... }
|
|
268
|
+
* ```
|
|
269
|
+
*
|
|
270
|
+
* **3. Raw stream access**
|
|
271
|
+
* ```ts
|
|
272
|
+
* for await (const chunk of agent.fullStream) { ... }
|
|
273
|
+
* ```
|
|
274
|
+
*/
|
|
275
|
+
export class OffensiveSecurityAgent<TResult = void> {
|
|
276
|
+
/** The real SDK stream result — created exactly once, with backend-probed facts via {@link streamReady} or settled-or-unknown facts via the sync escape hatch. */
|
|
277
|
+
private _streamResult: StreamTextResult<ToolSet, never> | null = null;
|
|
278
|
+
|
|
279
|
+
/** Composes the final system prompt, writes the trace init record, and calls `streamResponse`. Invoked at most once; both creation paths guard on `_streamResult`. */
|
|
280
|
+
private readonly createStream: (
|
|
281
|
+
facts: RuntimeExecutionFacts | null,
|
|
282
|
+
) => StreamTextResult<ToolSet, never>;
|
|
283
|
+
|
|
284
|
+
/** Lazy runtime probe, then `createStream`; memoized by {@link streamInit}. */
|
|
285
|
+
private readonly initializeStreamOnce: () => Promise<void>;
|
|
286
|
+
|
|
287
|
+
/** Memoized {@link streamReady} promise; initialization runs at most once. */
|
|
288
|
+
private streamInit: Promise<void> | null = null;
|
|
289
|
+
|
|
290
|
+
/** True when this agent's tool selection can use backend-probed execution facts. */
|
|
291
|
+
private readonly probesRuntime: boolean;
|
|
292
|
+
|
|
293
|
+
/** The tool context whose runtime scope keys fact discovery and the sync fallback. */
|
|
294
|
+
private readonly toolCtx: ToolContext;
|
|
295
|
+
|
|
296
|
+
/** The event bus for this agent's streaming output. */
|
|
297
|
+
public readonly eventBus: AgentEventBus;
|
|
298
|
+
|
|
299
|
+
private readonly resolveResult?: (
|
|
300
|
+
streamResult: StreamTextResult<ToolSet, never>,
|
|
301
|
+
) => TResult | Promise<TResult>;
|
|
302
|
+
|
|
303
|
+
/** The structured result captured by the `response` tool, or `null` until it fires. */
|
|
304
|
+
private _capturedResponse: TResult | null = null;
|
|
305
|
+
|
|
306
|
+
/** Set synchronously when `response` fires, ahead of any async `resolveResult`, to distinguish a clean finish from an abort. */
|
|
307
|
+
private _responseToolFired = false;
|
|
308
|
+
|
|
309
|
+
/** Raw structured result submitted to the response tool, retained for root-span output. */
|
|
310
|
+
private _responseToolResult: unknown;
|
|
311
|
+
|
|
312
|
+
/** Resolves the instant `response` captures the result, so {@link consume} can return early and drain in the background. */
|
|
313
|
+
private _resolveResponseCaptured!: (result: TResult) => void;
|
|
314
|
+
private _rejectResponseCaptured!: (err: unknown) => void;
|
|
315
|
+
public readonly responseCaptured: Promise<TResult> = new Promise(
|
|
316
|
+
(resolve, reject) => {
|
|
317
|
+
this._resolveResponseCaptured = resolve;
|
|
318
|
+
this._rejectResponseCaptured = reject;
|
|
319
|
+
},
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
/** Rejects when the background drain errors, so a custom resolver racing `streamResult.response` isn't blocked by a wedged stream. */
|
|
323
|
+
private _drainRejection: Promise<never> = new Promise<never>(() => {});
|
|
324
|
+
|
|
325
|
+
/** Settles when the background drain (including its synthetic-close finally) has fully finished. */
|
|
326
|
+
public drained: Promise<void> = Promise.resolve();
|
|
327
|
+
|
|
328
|
+
/** Identifier for this agent when it is running as a subagent. */
|
|
329
|
+
private readonly subagentId?: string;
|
|
330
|
+
|
|
331
|
+
/** Display label for span name / `gen_ai.agent.name`; the id stays the join key. */
|
|
332
|
+
private readonly subagentName?: string;
|
|
333
|
+
/** Operating mode (tools surface); used for run-span attribution. */
|
|
334
|
+
private readonly agentMode: AgentMode;
|
|
335
|
+
/** The current open assistant message id (`msg_…`); minted on `start-step` in {@link consume}, `null` between steps. */
|
|
336
|
+
private currentMessageId: string | null = null;
|
|
337
|
+
|
|
338
|
+
/** Per-run stream counters for deterministic id derivation via {@link streamIdFactory}. */
|
|
339
|
+
private streamStepIndex = -1;
|
|
340
|
+
|
|
341
|
+
private streamTextPartIndex = 0;
|
|
342
|
+
|
|
343
|
+
/** Per-command executor for local-mode command execution; disposed on consume() completion. */
|
|
344
|
+
private readonly commandShell?: PerCommandShell;
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* This agent's Playwright MCP browser session. Either constructed fresh
|
|
348
|
+
* by this agent (when no `browserSession` was passed in) or supplied by
|
|
349
|
+
* the caller (e.g. `spawn_pentest_agent` constructs a fresh, isolated
|
|
350
|
+
* session for each worker, seeds it with a snapshot of the orchestrator's
|
|
351
|
+
* cookies + localStorage, and hands the seeded session in here so this
|
|
352
|
+
* agent's browser tools operate against an authenticated-but-isolated
|
|
353
|
+
* Chromium).
|
|
354
|
+
*
|
|
355
|
+
* Exposed publicly so spawn tools can read this agent's session (e.g.
|
|
356
|
+
* the pentest orchestrator's `browserSession` is what `spawn_pentest_agent`
|
|
357
|
+
* snapshots when it builds the worker's seeded clone). The session
|
|
358
|
+
* object is NOT shared between agents at runtime — each agent gets its
|
|
359
|
+
* own isolated Chromium so a sub-agent can't clobber its parent's DOM,
|
|
360
|
+
* cookies, or navigation state.
|
|
361
|
+
*
|
|
362
|
+
* Only populated for non-sandbox (local MCP) mode. In sandbox mode,
|
|
363
|
+
* browser state is already shared via the sandbox's per-sandbox
|
|
364
|
+
* Playwright user-data directory, so no host-side session object is
|
|
365
|
+
* needed.
|
|
366
|
+
*/
|
|
367
|
+
public readonly browserSession?: PlaywrightMcpSession;
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* True when this agent constructed its own {@link browserSession} (no
|
|
371
|
+
* `browserSession` was passed in). Only the owner disconnects it on
|
|
372
|
+
* `consume()` completion — an inherited session is torn down by whoever
|
|
373
|
+
* created it (e.g. `spawn_pentest_agent` for worker clones), so we must
|
|
374
|
+
* never disconnect a session we don't own.
|
|
375
|
+
*/
|
|
376
|
+
private readonly ownsBrowserSession: boolean;
|
|
377
|
+
|
|
378
|
+
/** Guards against double force-kill across the drain-finally and result-capture paths. */
|
|
379
|
+
private browserDisconnected = false;
|
|
380
|
+
private shellDisposed = false;
|
|
381
|
+
|
|
382
|
+
/** Listeners started by this agent's callback helper tools; drained on finalization. */
|
|
383
|
+
private readonly callbackListeners = new CallbackListenerRegistry();
|
|
384
|
+
// Cached dispose barrier — repeat disposeOwnedShell() calls return the
|
|
385
|
+
// same settlement wait instead of a fire-and-forget.
|
|
386
|
+
private shellDisposeBarrier: Promise<void> | null = null;
|
|
387
|
+
|
|
388
|
+
private readonly abortSignal?: AbortSignal;
|
|
389
|
+
|
|
390
|
+
private readonly streamIdFactory?: StreamIdFactory;
|
|
391
|
+
|
|
392
|
+
/** Recorded-run durable context authority; flushed (and failing) in finalizeRun. */
|
|
393
|
+
private readonly contextRecorder?: RunContextRecorder;
|
|
394
|
+
|
|
395
|
+
/** The user-facing prompt passed to the model. */
|
|
396
|
+
public readonly userPrompt: string;
|
|
397
|
+
|
|
398
|
+
/** The session this agent is operating within. */
|
|
399
|
+
private readonly _session: SessionInfo;
|
|
400
|
+
|
|
401
|
+
/** Agent-local message persistence (debounce + serialized writes). */
|
|
402
|
+
private readonly writer!: AgentMessageWriter;
|
|
403
|
+
|
|
404
|
+
/** Closes an interrupted step: synthetic results, reconstruction, write. */
|
|
405
|
+
private readonly finalizeInterruptedStep!: (
|
|
406
|
+
input: FinalizeInterruptedStepInput,
|
|
407
|
+
) => Promise<void>;
|
|
408
|
+
|
|
409
|
+
private messagesPath: string | null = null;
|
|
410
|
+
|
|
411
|
+
/** Serializes agent-owned messages.json writes in enqueue order. */
|
|
412
|
+
/**
|
|
413
|
+
* Async factory that creates a session when one is not provided,
|
|
414
|
+
* then constructs the agent. Use this instead of `new` when you
|
|
415
|
+
* want the agent to own session lifecycle.
|
|
416
|
+
*
|
|
417
|
+
* Pass an existing `session` to reuse one (console integration,
|
|
418
|
+
* subagent spawning, etc.).
|
|
419
|
+
*/
|
|
420
|
+
static async create<TResult = void>(
|
|
421
|
+
input: CreateAgentInput<TResult>,
|
|
422
|
+
): Promise<OffensiveSecurityAgent<TResult>> {
|
|
423
|
+
let session = input.session;
|
|
424
|
+
if (!session) {
|
|
425
|
+
session = await createSession({
|
|
426
|
+
targets: input.target ? [input.target] : [],
|
|
427
|
+
config: input.sessionConfig,
|
|
428
|
+
model: input.model,
|
|
429
|
+
authConfig: input.authConfig,
|
|
430
|
+
userMessage: input.prompt,
|
|
431
|
+
onNameGenerated: input.onNameGenerated,
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
return new OffensiveSecurityAgent({ ...input, session });
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/** The session this agent is operating within. */
|
|
438
|
+
get session(): SessionInfo {
|
|
439
|
+
return this._session;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/** This agent's identity on the event bus (subagent's session id, or the root session's id). */
|
|
443
|
+
private get busSessionId(): string {
|
|
444
|
+
return this.subagentId ?? this._session.id;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
constructor(input: OffensiveSecurityAgentInput<TResult>) {
|
|
448
|
+
this._session = input.session;
|
|
449
|
+
this.subagentId = input.subagentId;
|
|
450
|
+
this.subagentName = input.subagentName;
|
|
451
|
+
this.agentMode = input.mode ?? "default";
|
|
452
|
+
this.abortSignal = input.abortSignal;
|
|
453
|
+
this.streamIdFactory = input.streamIdFactory;
|
|
454
|
+
this.contextRecorder = input.contextRecorder;
|
|
455
|
+
this.userPrompt = input.prompt;
|
|
456
|
+
this.eventBus = input.eventBus ?? new AgentEventBus();
|
|
457
|
+
|
|
458
|
+
// -- Resolve agent working directory ----------------------------------------
|
|
459
|
+
// Explicit input wins over session config; command cwd and file-tool
|
|
460
|
+
// scoping (fileWorkspaceRoot) are independent and resolved separately.
|
|
461
|
+
const agentCwd =
|
|
462
|
+
input.agentCwd ??
|
|
463
|
+
input.session.config?.agentCwd ??
|
|
464
|
+
input.session.rootPath;
|
|
465
|
+
// Same precedence for the file-tool workspace: an explicit root (e.g. a
|
|
466
|
+
// child agent's helper directory) wins over the session's remote root.
|
|
467
|
+
const fileWorkspaceRoot =
|
|
468
|
+
input.fileWorkspaceRoot ?? input.session.config?.remoteFileWorkspaceRoot;
|
|
469
|
+
|
|
470
|
+
// -- Per-command executor (local mode only) -------------------------------
|
|
471
|
+
// Shell survives command cancellation; only disposed in consume() after the
|
|
472
|
+
// stream ends, or when the agent is fully killed.
|
|
473
|
+
if (!input.sandbox) {
|
|
474
|
+
this.commandShell = new PerCommandShell({
|
|
475
|
+
cwd: agentCwd,
|
|
476
|
+
env: input.environmentVariables,
|
|
477
|
+
});
|
|
478
|
+
if (input.commandCancelHandle) {
|
|
479
|
+
const shell = this.commandShell;
|
|
480
|
+
input.commandCancelHandle.cancel = () => shell.cancelCurrentCommand();
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// -- Browser session (local MCP mode only) -------------------------------
|
|
485
|
+
// Either inherit from the parent agent (e.g. pentest orchestrator handing
|
|
486
|
+
// its authenticated context down via spawn_pentest_agent) or construct a
|
|
487
|
+
// fresh one. The session itself does not spawn the MCP child / Chromium
|
|
488
|
+
// until the first browser tool call, so eager construction is cheap even
|
|
489
|
+
// for agents that never use browser tools. Sandbox-mode agents already
|
|
490
|
+
// share browser state via the sandbox's per-sandbox Playwright user-data
|
|
491
|
+
// dir, so they don't need a session object on the host.
|
|
492
|
+
if (!input.sandbox) {
|
|
493
|
+
this.ownsBrowserSession = !input.browserSession;
|
|
494
|
+
this.browserSession =
|
|
495
|
+
input.browserSession ??
|
|
496
|
+
new PlaywrightMcpSession({
|
|
497
|
+
headerPolicy: resolveBrowserHeaderPolicy(input.session, input.target),
|
|
498
|
+
display: input.display,
|
|
499
|
+
engine: input.browserEngine,
|
|
500
|
+
});
|
|
501
|
+
// Owned sessions aren't wired through createBrowserTools' abort path
|
|
502
|
+
// (existingSession skips that listener). Disconnect on abort so timeout/
|
|
503
|
+
// pause reaps Camoufox even when consume()'s drain is still unwinding.
|
|
504
|
+
if (this.ownsBrowserSession && this.abortSignal) {
|
|
505
|
+
const onAbort = () => {
|
|
506
|
+
void this.disconnectOwnedBrowser();
|
|
507
|
+
};
|
|
508
|
+
if (this.abortSignal.aborted) onAbort();
|
|
509
|
+
else
|
|
510
|
+
this.abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
511
|
+
}
|
|
512
|
+
} else {
|
|
513
|
+
this.ownsBrowserSession = false;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// -- Step trace (trace.jsonl) ---------------------------------------------
|
|
517
|
+
// Created before tools so the checkpoint_state tool can reference it.
|
|
518
|
+
const messagesDir =
|
|
519
|
+
input.messagesDir ??
|
|
520
|
+
(input.subagentId
|
|
521
|
+
? join(input.session.rootPath, "subagents", input.subagentId)
|
|
522
|
+
: input.session.rootPath);
|
|
523
|
+
const tracePath = input.subagentId
|
|
524
|
+
? join(
|
|
525
|
+
input.session.rootPath,
|
|
526
|
+
"subagents",
|
|
527
|
+
`${input.subagentId}.trace.jsonl`,
|
|
528
|
+
)
|
|
529
|
+
: join(messagesDir, "trace.jsonl");
|
|
530
|
+
const traceWriter = new StepTraceWriter({
|
|
531
|
+
tracePath,
|
|
532
|
+
agentId: input.subagentId ?? null,
|
|
533
|
+
eventBus: this.eventBus,
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
// -- Task directory (per-agent tasks, opt-in via taskDriven config) -------
|
|
537
|
+
const taskDriven = input.session.config?.taskDriven ?? false;
|
|
538
|
+
const tasksDir =
|
|
539
|
+
input.tasksDir ??
|
|
540
|
+
(taskDriven
|
|
541
|
+
? input.subagentId
|
|
542
|
+
? join(
|
|
543
|
+
input.session.rootPath,
|
|
544
|
+
"subagents",
|
|
545
|
+
`${input.subagentId}-tasks`,
|
|
546
|
+
)
|
|
547
|
+
: join(input.session.rootPath, "tasks")
|
|
548
|
+
: undefined);
|
|
549
|
+
|
|
550
|
+
// -- Tools ----------------------------------------------------------------
|
|
551
|
+
const credentialManager =
|
|
552
|
+
input.credentialManager ?? input.session.credentialManager;
|
|
553
|
+
|
|
554
|
+
const toolCtx = {
|
|
555
|
+
...(input.attackSurfaceArtifactsPath
|
|
556
|
+
? { attackSurfaceArtifactsPath: input.attackSurfaceArtifactsPath }
|
|
557
|
+
: {}),
|
|
558
|
+
session: input.session,
|
|
559
|
+
agentCwd,
|
|
560
|
+
fileWorkspaceRoot,
|
|
561
|
+
target: input.target,
|
|
562
|
+
grpc: input.grpc,
|
|
563
|
+
systemScope: input.systemScope,
|
|
564
|
+
abortSignal: input.abortSignal,
|
|
565
|
+
model: input.model,
|
|
566
|
+
authConfig: input.authConfig,
|
|
567
|
+
eventBus: this.eventBus,
|
|
568
|
+
onStepFinish: input.forwardUsageCallbacksToSpawnedAgents
|
|
569
|
+
? input.onStepFinish
|
|
570
|
+
: undefined,
|
|
571
|
+
onCacheMetrics: input.forwardUsageCallbacksToSpawnedAgents
|
|
572
|
+
? input.onCacheMetrics
|
|
573
|
+
: undefined,
|
|
574
|
+
sandbox: input.sandbox,
|
|
575
|
+
backends: input.backends,
|
|
576
|
+
findingsRegistry: input.findingsRegistry,
|
|
577
|
+
attackSurfaceRegistry: input.attackSurfaceRegistry,
|
|
578
|
+
credentialManager,
|
|
579
|
+
secretValues: input.secretValues,
|
|
580
|
+
environmentVariables: input.environmentVariables,
|
|
581
|
+
commandShell: this.commandShell,
|
|
582
|
+
skillsRegistry: input.skillsRegistry,
|
|
583
|
+
promptInjectionLibrary: input.promptInjectionLibrary,
|
|
584
|
+
promptInjectionLibrarySource:
|
|
585
|
+
input.promptInjectionLibrarySource ??
|
|
586
|
+
input.session.config?.promptInjectionLibrarySource,
|
|
587
|
+
traceWriter,
|
|
588
|
+
tasksDir,
|
|
589
|
+
enableThinking: input.enableThinking,
|
|
590
|
+
thinkingEffort: input.thinkingEffort,
|
|
591
|
+
openAIReasoningEffort: input.openAIReasoningEffort,
|
|
592
|
+
surfaceIntegrationEnabled: input.surfaceIntegrationEnabled,
|
|
593
|
+
projectThreatModel: input.projectThreatModel,
|
|
594
|
+
planSubagentId: input.planSubagentId,
|
|
595
|
+
subagentId: input.subagentId,
|
|
596
|
+
browserSession: this.browserSession,
|
|
597
|
+
// Propagate this agent's display so spawned workers run on the SAME
|
|
598
|
+
// virtual desktop (their browsers belong to the same endpoint's stream),
|
|
599
|
+
// rather than falling back to the process-wide DISPLAY (:0).
|
|
600
|
+
display: input.display,
|
|
601
|
+
// Spawn seam + durable hooks inherited by any sub-agent this agent spawns.
|
|
602
|
+
// Resolve the default once here so every tool sees a guaranteed spawner.
|
|
603
|
+
subagentSpawner: input.subagentSpawner ?? inProcessSubagentSpawner,
|
|
604
|
+
// Owned-listener cleanup seam: drained by finalizeRun/abortAndDrain.
|
|
605
|
+
callbackListeners: this.callbackListeners,
|
|
606
|
+
smsInbox: input.smsInbox,
|
|
607
|
+
emailAdapterFor: input.emailAdapterFor,
|
|
608
|
+
languageModelMiddleware: input.languageModelMiddleware,
|
|
609
|
+
usageRecorder: input.usageRecorder,
|
|
610
|
+
streamIdFactory: input.streamIdFactory,
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
// -- Effective tool selection (names only — factories run below) ---------
|
|
614
|
+
// Resolved BEFORE construction so inactive factories never run. Fast
|
|
615
|
+
// strike enumerates the live registry (conditional availability plus
|
|
616
|
+
// any extra tools) exactly as Object.keys on the merged map did.
|
|
617
|
+
const hasEmail =
|
|
618
|
+
(input.session.config?.emailIntegration?.inboxes?.length ?? 0) > 0;
|
|
619
|
+
const hasSmtp = !!input.session.config?.smtpConfig;
|
|
620
|
+
const emailToolSet = new Set<string>(EMAIL_TOOL_NAMES_ACTIVE);
|
|
621
|
+
const smsToolSet = new Set<string>(SMS_TOOL_NAMES_ACTIVE);
|
|
622
|
+
const hasSms = sessionHasSmsPasswordless(input.session);
|
|
623
|
+
const passesEmailSmsGates = (t: string): boolean => {
|
|
624
|
+
if (smsToolSet.has(t)) return hasSms;
|
|
625
|
+
if (!emailToolSet.has(t)) return true;
|
|
626
|
+
if (t === SEND_EMAIL_TOOL_NAME) return hasSmtp;
|
|
627
|
+
return hasEmail;
|
|
628
|
+
};
|
|
629
|
+
|
|
630
|
+
let activeTools = (input.activeTools as string[]).filter(
|
|
631
|
+
passesEmailSmsGates,
|
|
632
|
+
);
|
|
633
|
+
if (input.mode === "plan") {
|
|
634
|
+
const planSet = new Set<string>(PLAN_MODE_TOOL_NAMES);
|
|
635
|
+
activeTools = activeTools.filter((t) => planSet.has(t));
|
|
636
|
+
} else if (input.mode === "fast-strike") {
|
|
637
|
+
const excluded = new Set<string>(FAST_STRIKE_EXCLUDED_TOOL_NAMES);
|
|
638
|
+
// Mirror Object.keys({...builtins, ...extras}): an own extra replaces
|
|
639
|
+
// the builtin's value but keeps its insertion position; new extras
|
|
640
|
+
// append. Object.keys already yields own enumerable keys only.
|
|
641
|
+
const mergedNames = input.extraTools
|
|
642
|
+
? Object.keys({
|
|
643
|
+
...Object.fromEntries(
|
|
644
|
+
listToolRegistryNames(toolCtx).map((n) => [n, null]),
|
|
645
|
+
),
|
|
646
|
+
...input.extraTools,
|
|
647
|
+
})
|
|
648
|
+
: listToolRegistryNames(toolCtx);
|
|
649
|
+
activeTools = mergedNames.filter((t) => {
|
|
650
|
+
if (excluded.has(t)) return false;
|
|
651
|
+
return passesEmailSmsGates(t);
|
|
652
|
+
});
|
|
653
|
+
// Baseline enumerated Object.keys(tools) AFTER response injection, so
|
|
654
|
+
// fast-strike + responseSchema activates the injected response tool
|
|
655
|
+
// even when the input list omits it. Default mode stays caller-explicit.
|
|
656
|
+
if (input.responseSchema && !activeTools.includes(RESPONSE_TOOL_NAME)) {
|
|
657
|
+
activeTools = [...activeTools, RESPONSE_TOOL_NAME];
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
activeTools = filterWorkspaceToolsForRun(
|
|
662
|
+
activeTools,
|
|
663
|
+
input.prompt,
|
|
664
|
+
input.approvalGate !== undefined,
|
|
665
|
+
);
|
|
666
|
+
|
|
667
|
+
const builtinTools = createToolsForNames(toolCtx, activeTools);
|
|
668
|
+
|
|
669
|
+
let tools: ToolSet = input.extraTools
|
|
670
|
+
? { ...builtinTools, ...input.extraTools }
|
|
671
|
+
: { ...builtinTools };
|
|
672
|
+
|
|
673
|
+
// Only approved calls may reach the execution journal.
|
|
674
|
+
if (input.toolExecutionRecorder) {
|
|
675
|
+
tools = wrapRecordedTools(tools, input.toolExecutionRecorder);
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
// -- Approval gate wrapping -----------------------------------------------
|
|
679
|
+
if (input.approvalGate) {
|
|
680
|
+
tools = wrapToolsWithApprovalGate(
|
|
681
|
+
tools,
|
|
682
|
+
input.approvalGate,
|
|
683
|
+
AGENT_PAUSE_TOOLS,
|
|
684
|
+
);
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// -- Response schema → auto capture / stop / resolve ----------------------
|
|
688
|
+
if (input.responseSchema) {
|
|
689
|
+
tools = {
|
|
690
|
+
...tools,
|
|
691
|
+
[RESPONSE_TOOL_NAME]: createResponseTool(
|
|
692
|
+
input.responseSchema,
|
|
693
|
+
(result) => {
|
|
694
|
+
this._responseToolFired = true;
|
|
695
|
+
this._responseToolResult = result;
|
|
696
|
+
if (RESPONSE_DEBUG) {
|
|
697
|
+
rlog.warn(
|
|
698
|
+
`[response-debug] response tool EXECUTED (captured) session=${this.busSessionId} ` +
|
|
699
|
+
`resultBytes=${responseArgBytes(result)} — happy path`,
|
|
700
|
+
);
|
|
701
|
+
}
|
|
702
|
+
// With a custom resolveResult (e.g. TargetedPentestAgent), the raw schema result must be funnelled through it before fulfilling consume()'s race.
|
|
703
|
+
const customResolve = input.resolveResult;
|
|
704
|
+
if (customResolve) {
|
|
705
|
+
void Promise.resolve()
|
|
706
|
+
.then(() => {
|
|
707
|
+
// Race .response against _drainRejection so a wedged stream can't hang a resolver awaiting it.
|
|
708
|
+
const sr = this.streamResult;
|
|
709
|
+
const guarded = Object.create(sr, {
|
|
710
|
+
response: {
|
|
711
|
+
get: () =>
|
|
712
|
+
Promise.race([sr.response, this._drainRejection]),
|
|
713
|
+
},
|
|
714
|
+
});
|
|
715
|
+
return customResolve(guarded);
|
|
716
|
+
})
|
|
717
|
+
.then((resolved) => {
|
|
718
|
+
this._capturedResponse = resolved;
|
|
719
|
+
this._resolveResponseCaptured(resolved);
|
|
720
|
+
})
|
|
721
|
+
.catch((err) => {
|
|
722
|
+
this._rejectResponseCaptured(err);
|
|
723
|
+
});
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
this._capturedResponse = result as TResult;
|
|
727
|
+
this._resolveResponseCaptured(result as TResult);
|
|
728
|
+
},
|
|
729
|
+
),
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
if (input.resolveResult) {
|
|
734
|
+
this.resolveResult = input.resolveResult;
|
|
735
|
+
} else if (input.responseSchema) {
|
|
736
|
+
this.resolveResult = () => {
|
|
737
|
+
if (this._capturedResponse !== null) return this._capturedResponse;
|
|
738
|
+
return undefined as TResult;
|
|
739
|
+
};
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
let stopWhen = input.stopWhen;
|
|
743
|
+
if (input.responseSchema) {
|
|
744
|
+
const responseStop = hasToolCall(
|
|
745
|
+
RESPONSE_TOOL_NAME,
|
|
746
|
+
) as StopCondition<ToolSet>;
|
|
747
|
+
if (!stopWhen) {
|
|
748
|
+
stopWhen = responseStop;
|
|
749
|
+
} else if (Array.isArray(stopWhen)) {
|
|
750
|
+
stopWhen = [...stopWhen, responseStop];
|
|
751
|
+
} else {
|
|
752
|
+
stopWhen = [stopWhen, responseStop];
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
// -- Messages persistence -------------------------------------------------
|
|
757
|
+
if (!existsSync(messagesDir)) {
|
|
758
|
+
mkdirSync(messagesDir, { recursive: true });
|
|
759
|
+
}
|
|
760
|
+
this.messagesPath = join(messagesDir, "messages.json");
|
|
761
|
+
|
|
762
|
+
// Mutable so that summarization can clear stale history.
|
|
763
|
+
const initialMessagesRef: { current: ModelMessage[] } = {
|
|
764
|
+
current: input.messages
|
|
765
|
+
? [...input.messages]
|
|
766
|
+
: [
|
|
767
|
+
{
|
|
768
|
+
role: "user" as const,
|
|
769
|
+
content: [{ type: "text", text: input.prompt }],
|
|
770
|
+
},
|
|
771
|
+
],
|
|
772
|
+
};
|
|
773
|
+
|
|
774
|
+
// Agent-local persistence: debounce, latest snapshot, and the
|
|
775
|
+
// serialized write queue live in the writer (see ./messagePersistence).
|
|
776
|
+
this.writer = new AgentMessageWriter({ messagesPath: this.messagesPath });
|
|
777
|
+
this.finalizeInterruptedStep = createInterruptedStepFinalizer({
|
|
778
|
+
eventBus: this.eventBus,
|
|
779
|
+
sessionId: this.busSessionId,
|
|
780
|
+
subagentId: this.subagentId,
|
|
781
|
+
writer: this.writer,
|
|
782
|
+
responseToolName: RESPONSE_TOOL_NAME,
|
|
783
|
+
responseToolFired: () => this._responseToolFired,
|
|
784
|
+
...(RESPONSE_DEBUG
|
|
785
|
+
? { debugLog: (message: string) => rlog.warn(message) }
|
|
786
|
+
: {}),
|
|
787
|
+
});
|
|
788
|
+
const schedulePersist = () => this.writer.schedulePersist();
|
|
789
|
+
|
|
790
|
+
// -- System prompt ---------------------------------------------------------
|
|
791
|
+
// Persona first; execution facts and the workspace section are appended by
|
|
792
|
+
// the harness for every persona, so custom prompts no longer bypass them.
|
|
793
|
+
// Facts are probed through the agent's actual command backend (see
|
|
794
|
+
// ./runtimeContext) — asynchronous, so the stream is created once they settle.
|
|
795
|
+
const baseSystemPrompt =
|
|
796
|
+
input.system ??
|
|
797
|
+
buildBaseSystemPrompt({
|
|
798
|
+
sandboxMode: agentCwd === input.session.rootPath,
|
|
799
|
+
});
|
|
800
|
+
const commandPlatform = resolveCommandPlatform(toolCtx);
|
|
801
|
+
const workspaceSection = buildSessionWorkspaceSection(
|
|
802
|
+
input.session,
|
|
803
|
+
agentCwd,
|
|
804
|
+
activeTools,
|
|
805
|
+
fileWorkspaceRoot,
|
|
806
|
+
);
|
|
807
|
+
// Bundled wordlist paths are host-local: advertise them only when
|
|
808
|
+
// commands execute locally.
|
|
809
|
+
const bundledAssets =
|
|
810
|
+
input.backends || input.sandbox ? null : buildBundledAssetsSection();
|
|
811
|
+
const assembleBaseSystemPrompt = (
|
|
812
|
+
facts: RuntimeExecutionFacts | null,
|
|
813
|
+
): string => {
|
|
814
|
+
const sections: string[] = [baseSystemPrompt];
|
|
815
|
+
if (facts) {
|
|
816
|
+
sections.push(
|
|
817
|
+
buildRuntimeContextSection(facts, { platform: commandPlatform }),
|
|
818
|
+
);
|
|
819
|
+
}
|
|
820
|
+
if (bundledAssets) sections.push(bundledAssets);
|
|
821
|
+
return sections.join("\n\n");
|
|
822
|
+
};
|
|
823
|
+
this.toolCtx = toolCtx;
|
|
824
|
+
// Only agents whose tools can execute commands, touch files, or run
|
|
825
|
+
// PoCs get a runtime probe — for anyone else the facts are noise and the
|
|
826
|
+
// probe is a wasted subprocess.
|
|
827
|
+
this.probesRuntime = activeTools.some((name) =>
|
|
828
|
+
RUNTIME_CAPABLE_TOOL_NAMES.has(name),
|
|
829
|
+
);
|
|
830
|
+
|
|
831
|
+
// -- Init record + stream --------------------------------------------------
|
|
832
|
+
// Created by async initialization (streamReady) so the AI SDK telemetry
|
|
833
|
+
// binds to the span active at first consumption (this agent's
|
|
834
|
+
// invoke_agent span in consume()) and the system prompt can embed
|
|
835
|
+
// backend-probed facts. The synchronous escape hatch calls the same
|
|
836
|
+
// factory with settled-or-unknown facts — never host facts — guarded so
|
|
837
|
+
// exactly one model stream exists either way.
|
|
838
|
+
this.createStream = (facts) => {
|
|
839
|
+
// Hash only the base system prompt (excluding session workspace paths)
|
|
840
|
+
// so the hash is stable across runs with identical prompt versions. No
|
|
841
|
+
// step record can precede this init line: steps only originate from the
|
|
842
|
+
// stream created below.
|
|
843
|
+
const baseWithFacts = assembleBaseSystemPrompt(facts);
|
|
844
|
+
traceWriter.writeInit({
|
|
845
|
+
model: input.model,
|
|
846
|
+
systemPrompt: baseWithFacts,
|
|
847
|
+
activeTools,
|
|
848
|
+
sessionId: input.session.id,
|
|
849
|
+
target: input.target,
|
|
850
|
+
});
|
|
851
|
+
return streamResponse({
|
|
852
|
+
prompt: input.prompt,
|
|
853
|
+
system: baseWithFacts + workspaceSection,
|
|
854
|
+
model: input.model,
|
|
855
|
+
messages: input.messages,
|
|
856
|
+
tools,
|
|
857
|
+
activeTools,
|
|
858
|
+
stopWhen,
|
|
859
|
+
toolChoice: "auto",
|
|
860
|
+
languageModelMiddleware: input.languageModelMiddleware,
|
|
861
|
+
usageRecorder: input.usageRecorder,
|
|
862
|
+
contextRecorder: input.contextRecorder,
|
|
863
|
+
inferenceRecorder: input.inferenceRecorder,
|
|
864
|
+
// Per-subagent so the overflow tool-result dumps land next to this
|
|
865
|
+
// agent's messages.json (`subagents/{id}/tool-results/`) and a host
|
|
866
|
+
// can reclaim them when the subagent finishes, instead of piling up
|
|
867
|
+
// at the shared session root for the whole scan (ENOSPC). Falls back
|
|
868
|
+
// to the session root for the root/operator agent.
|
|
869
|
+
sessionPath: messagesDir,
|
|
870
|
+
sessionId: this.busSessionId,
|
|
871
|
+
onStepFinish: async (event) => {
|
|
872
|
+
const auxiliaryModelEvent =
|
|
873
|
+
event.response.id === "summarization" ||
|
|
874
|
+
event.response.id === "tool-repair";
|
|
875
|
+
const stepUsage = normalizeStepUsage(event);
|
|
876
|
+
|
|
877
|
+
if (auxiliaryModelEvent) {
|
|
878
|
+
traceWriter.recordStep([], stepUsage, { usageOnly: true });
|
|
879
|
+
await input.onStepFinish?.(event);
|
|
880
|
+
return;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
// Recorded runs project the canonical committed context; the
|
|
884
|
+
// legacy path reconstructs from the (possibly stale after a fit)
|
|
885
|
+
// initial prefix. Canonical latest() already includes this step's
|
|
886
|
+
// messages — committing happens upstream in the ai layer's
|
|
887
|
+
// onStepFinish wrapper, before this user callback runs.
|
|
888
|
+
const canonical = input.contextRecorder?.latest() ?? [
|
|
889
|
+
...initialMessagesRef.current,
|
|
890
|
+
...event.response.messages,
|
|
891
|
+
];
|
|
892
|
+
this.writer.setLatest(canonical);
|
|
893
|
+
schedulePersist();
|
|
894
|
+
traceWriter.recordStep(
|
|
895
|
+
event.response.messages as ModelMessage[],
|
|
896
|
+
stepUsage,
|
|
897
|
+
);
|
|
898
|
+
this.eventBus.emit("step-finish", {
|
|
899
|
+
messages: event.response.messages,
|
|
900
|
+
subagentId: this.subagentId,
|
|
901
|
+
sessionId: this.busSessionId,
|
|
902
|
+
messageId: this.currentMessageId ?? undefined,
|
|
903
|
+
});
|
|
904
|
+
this.currentMessageId = null;
|
|
905
|
+
await input.onStepFinish?.(event);
|
|
906
|
+
},
|
|
907
|
+
onSummarized: () => {
|
|
908
|
+
// Context was reset by summarization — discard the old history so
|
|
909
|
+
// subsequent onStepFinish writes only persist post-summary messages.
|
|
910
|
+
initialMessagesRef.current = [];
|
|
911
|
+
traceWriter.markSummarized();
|
|
912
|
+
},
|
|
913
|
+
onFinish: async (event) => {
|
|
914
|
+
// Flush any pending persistence before finishing
|
|
915
|
+
this.writer.cancelTimer();
|
|
916
|
+
// Skip if the interrupted-step finalizer already wrote the abort snapshot.
|
|
917
|
+
if (!this.writer.syntheticsPersisted) {
|
|
918
|
+
const finalMessages = input.contextRecorder?.latest() ??
|
|
919
|
+
this.writer.latest ?? [
|
|
920
|
+
...initialMessagesRef.current,
|
|
921
|
+
...event.response.messages,
|
|
922
|
+
];
|
|
923
|
+
this.writer.setLatest(finalMessages);
|
|
924
|
+
await this.writer.enqueueWrite(finalMessages).catch(() => {});
|
|
925
|
+
}
|
|
926
|
+
await input.onFinish?.(event);
|
|
927
|
+
},
|
|
928
|
+
abortSignal: input.abortSignal,
|
|
929
|
+
authConfig: input.authConfig,
|
|
930
|
+
onCacheMetrics: input.onCacheMetrics,
|
|
931
|
+
enableThinking: input.enableThinking,
|
|
932
|
+
thinkingEffort: input.thinkingEffort,
|
|
933
|
+
openAIReasoningEffort: input.openAIReasoningEffort,
|
|
934
|
+
silent: true,
|
|
935
|
+
});
|
|
936
|
+
};
|
|
937
|
+
this.initializeStreamOnce = async () => {
|
|
938
|
+
// The sync escape hatch may have created the stream while discovery was
|
|
939
|
+
// pending — never a second model stream.
|
|
940
|
+
if (this._streamResult !== null) return;
|
|
941
|
+
// Abort-before-start skips the probe but still creates the stream so the
|
|
942
|
+
// SDK surfaces the abort normally; a probe failure degrades the prompt
|
|
943
|
+
// to unknown facts rather than failing the stream.
|
|
944
|
+
const facts =
|
|
945
|
+
this.probesRuntime && !this.abortSignal?.aborted
|
|
946
|
+
? await probeRuntimeFacts(toolCtx).catch(
|
|
947
|
+
(): RuntimeExecutionFacts => UNKNOWN_FACTS,
|
|
948
|
+
)
|
|
949
|
+
: null;
|
|
950
|
+
// Re-check after the await: the escape hatch may have raced the probe.
|
|
951
|
+
if (this._streamResult !== null) return;
|
|
952
|
+
this._streamResult = this.createStream(facts);
|
|
953
|
+
};
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
// ---------------------------------------------------------------------------
|
|
957
|
+
// Stream access
|
|
958
|
+
// ---------------------------------------------------------------------------
|
|
959
|
+
|
|
960
|
+
/**
|
|
961
|
+
* Asynchronous initialization seam: probe runtime facts through this
|
|
962
|
+
* agent's command backend (only when its selected tools can use them), then
|
|
963
|
+
* create the stream. Idempotent; every consumption entry point awaits it,
|
|
964
|
+
* so the AI layer's prompt budgeting and recovery see the actual final
|
|
965
|
+
* system text.
|
|
966
|
+
*/
|
|
967
|
+
streamReady(): Promise<void> {
|
|
968
|
+
this.streamInit ??= this.initializeStreamOnce();
|
|
969
|
+
return this.streamInit;
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
/**
|
|
973
|
+
* The underlying Vercel AI SDK stream result — synchronous escape hatch.
|
|
974
|
+
* Always a real SDK result. Cold access creates it immediately with facts
|
|
975
|
+
* already settled for this runtime scope, else explicit unknown facts —
|
|
976
|
+
* never host facts; callers needing freshly probed facts await
|
|
977
|
+
* {@link streamReady}, `consume()`, or `fullStream` iteration instead.
|
|
978
|
+
* Guarded so a cold access racing an in-flight probe never creates a
|
|
979
|
+
* second model stream.
|
|
980
|
+
*/
|
|
981
|
+
get streamResult(): StreamTextResult<ToolSet, never> {
|
|
982
|
+
if (this._streamResult === null) {
|
|
983
|
+
const facts = this.probesRuntime
|
|
984
|
+
? (peekSettledRuntimeFacts(this.toolCtx) ?? UNKNOWN_FACTS)
|
|
985
|
+
: null;
|
|
986
|
+
this._streamResult = this.createStream(facts);
|
|
987
|
+
}
|
|
988
|
+
return this._streamResult;
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
/**
|
|
992
|
+
* The raw async-iterable stream of chunks.
|
|
993
|
+
* Equivalent to `streamResult.fullStream`; before initialization it
|
|
994
|
+
* settles {@link streamReady} on first iteration, then delegates to the
|
|
995
|
+
* real stream.
|
|
996
|
+
*/
|
|
997
|
+
get fullStream(): AsyncIterable<TextStreamPart<ToolSet>> {
|
|
998
|
+
if (this._streamResult !== null) {
|
|
999
|
+
return this._streamResult.fullStream;
|
|
1000
|
+
}
|
|
1001
|
+
const self = this;
|
|
1002
|
+
return (async function* () {
|
|
1003
|
+
await self.streamReady();
|
|
1004
|
+
const stream = self._streamResult;
|
|
1005
|
+
if (stream === null) {
|
|
1006
|
+
throw new Error("Stream initialization did not produce a stream");
|
|
1007
|
+
}
|
|
1008
|
+
yield* stream.fullStream;
|
|
1009
|
+
})();
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
/**
|
|
1013
|
+
* Makes the agent instance itself async-iterable so callers can write:
|
|
1014
|
+
* ```ts
|
|
1015
|
+
* for await (const chunk of agent) { ... }
|
|
1016
|
+
* ```
|
|
1017
|
+
*
|
|
1018
|
+
* **Note:** The underlying stream can only be consumed once.
|
|
1019
|
+
*/
|
|
1020
|
+
async *[Symbol.asyncIterator](): AsyncIterator<TextStreamPart<ToolSet>> {
|
|
1021
|
+
await this.streamReady();
|
|
1022
|
+
for await (const chunk of this.streamResult.fullStream) {
|
|
1023
|
+
yield chunk;
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
// ---------------------------------------------------------------------------
|
|
1028
|
+
// Convenience helpers
|
|
1029
|
+
// ---------------------------------------------------------------------------
|
|
1030
|
+
|
|
1031
|
+
/**
|
|
1032
|
+
* Consume the stream, emitting each chunk on the {@link eventBus}, then
|
|
1033
|
+
* resolve the final result.
|
|
1034
|
+
*
|
|
1035
|
+
* Each AI SDK stream part is forwarded to the bus via
|
|
1036
|
+
* {@link AgentEventBus.emitStreamPart}, tagged with this agent's
|
|
1037
|
+
* `subagentId` when present.
|
|
1038
|
+
*
|
|
1039
|
+
* @returns The value produced by `resolveResult`, or `void` if none was provided.
|
|
1040
|
+
*/
|
|
1041
|
+
async consume(): Promise<TResult> {
|
|
1042
|
+
const sid = this.subagentId;
|
|
1043
|
+
const bus = this.eventBus;
|
|
1044
|
+
|
|
1045
|
+
const runConsume = async (): Promise<TResult> => {
|
|
1046
|
+
// Reset per-run stream counters so a replayed run derives the same ids.
|
|
1047
|
+
this.streamStepIndex = -1;
|
|
1048
|
+
this.streamTextPartIndex = 0;
|
|
1049
|
+
// Tool-call part ids are minted once and reused for the WHOLE session, never reset per step.
|
|
1050
|
+
const toolParts = new Map<string, string>();
|
|
1051
|
+
const ids: StreamIdContext = {
|
|
1052
|
+
// The TUI routes any event with a subagentId into a subagent panel, so
|
|
1053
|
+
// the orchestrator must leave it undefined; only real subagents set it.
|
|
1054
|
+
subagentId: this.subagentId,
|
|
1055
|
+
sessionId: this.busSessionId,
|
|
1056
|
+
messageId: undefined,
|
|
1057
|
+
textPartId: undefined,
|
|
1058
|
+
toolPartId: (toolCallId: string) => {
|
|
1059
|
+
let p = toolParts.get(toolCallId);
|
|
1060
|
+
if (!p) {
|
|
1061
|
+
p =
|
|
1062
|
+
this.streamIdFactory?.({ kind: "tool-part", toolCallId }) ??
|
|
1063
|
+
newPartId();
|
|
1064
|
+
toolParts.set(toolCallId, p);
|
|
1065
|
+
}
|
|
1066
|
+
return p;
|
|
1067
|
+
},
|
|
1068
|
+
};
|
|
1069
|
+
|
|
1070
|
+
// Tool lifecycle state: in-flight calls awaiting a result, completed but
|
|
1071
|
+
// unpersisted results (PR #779), streamed arg text, and deferred tool
|
|
1072
|
+
// errors — all owned by the tracker (see ./toolLifecycle).
|
|
1073
|
+
const tracker = new ToolLifecycleTracker();
|
|
1074
|
+
let streamError: unknown;
|
|
1075
|
+
let hasStreamError = false;
|
|
1076
|
+
|
|
1077
|
+
// Opt-in stall watchdog + response-tool tracer (see ./streamDiagnostics).
|
|
1078
|
+
const diagnostics = new StreamDiagnostics({
|
|
1079
|
+
sessionId: this._session.id,
|
|
1080
|
+
subagentId: sid,
|
|
1081
|
+
inFlightTools: () => tracker.inFlightTools,
|
|
1082
|
+
responseToolFired: () => this._responseToolFired,
|
|
1083
|
+
responseToolName: RESPONSE_TOOL_NAME,
|
|
1084
|
+
});
|
|
1085
|
+
diagnostics.start();
|
|
1086
|
+
|
|
1087
|
+
try {
|
|
1088
|
+
// Initialize (runtime probe + stream creation) inside the span so
|
|
1089
|
+
// telemetry binds to this agent's invoke_agent span.
|
|
1090
|
+
await this.streamReady();
|
|
1091
|
+
// 1–3. Iterate the stream: observe diagnostics, apply the part (id
|
|
1092
|
+
// bookkeeping, tracker updates, step-close emissions), forward it.
|
|
1093
|
+
for await (const chunk of this.streamResult.fullStream) {
|
|
1094
|
+
diagnostics.observeChunk(chunk);
|
|
1095
|
+
this.applyStreamPart(chunk, { ids, tracker, diagnostics });
|
|
1096
|
+
bus.emitStreamPart(chunk, ids);
|
|
1097
|
+
}
|
|
1098
|
+
// The tracker keeps completed results: an abort with no trailing
|
|
1099
|
+
// finish-step needs them for the finalization snapshot.
|
|
1100
|
+
} catch (err) {
|
|
1101
|
+
// 4. Capture the error; finalization below still runs.
|
|
1102
|
+
streamError =
|
|
1103
|
+
this.abortSignal?.aborted && isGenericAbortError(err)
|
|
1104
|
+
? agentAbortReason(this.abortSignal)
|
|
1105
|
+
: err;
|
|
1106
|
+
hasStreamError = true;
|
|
1107
|
+
} finally {
|
|
1108
|
+
// Preserve an already-observed abort if cleanup subsequently fails.
|
|
1109
|
+
if (!hasStreamError && this.abortSignal?.aborted) {
|
|
1110
|
+
streamError = agentAbortReason(this.abortSignal);
|
|
1111
|
+
hasStreamError = true;
|
|
1112
|
+
}
|
|
1113
|
+
// 5–7. Close the interrupted step, dispose owned resources, settle.
|
|
1114
|
+
const finalizeError = await this.finalizeRun({
|
|
1115
|
+
tracker,
|
|
1116
|
+
diagnostics,
|
|
1117
|
+
ids,
|
|
1118
|
+
streamError,
|
|
1119
|
+
});
|
|
1120
|
+
// Teardown failures must not replace the originating run failure.
|
|
1121
|
+
if (!hasStreamError && finalizeError !== null) {
|
|
1122
|
+
streamError = finalizeError;
|
|
1123
|
+
hasStreamError = true;
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
if (hasStreamError) {
|
|
1128
|
+
throw streamError;
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
if (this.abortSignal?.aborted) {
|
|
1132
|
+
throw agentAbortReason(this.abortSignal);
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
if (this.resolveResult) {
|
|
1136
|
+
if (this._responseToolFired) {
|
|
1137
|
+
return undefined as TResult;
|
|
1138
|
+
}
|
|
1139
|
+
return this.resolveResult(this.streamResult);
|
|
1140
|
+
}
|
|
1141
|
+
return undefined as TResult;
|
|
1142
|
+
};
|
|
1143
|
+
|
|
1144
|
+
// One invoke_agent span per execution. The conversation/root id stays
|
|
1145
|
+
// stable across the tree while each span identifies its current agent.
|
|
1146
|
+
const isSubagent = Boolean(sid);
|
|
1147
|
+
const spanLabel = isSubagent
|
|
1148
|
+
? (this.subagentName ?? sid ?? "subagent")
|
|
1149
|
+
: this.agentMode;
|
|
1150
|
+
const rootSessionId = this._session.id;
|
|
1151
|
+
const agentSessionId = this.busSessionId;
|
|
1152
|
+
const runSpanAttributes: Record<string, string> = {
|
|
1153
|
+
"gen_ai.operation.name": "invoke_agent",
|
|
1154
|
+
"gen_ai.agent.id": agentSessionId,
|
|
1155
|
+
"gen_ai.agent.name": spanLabel,
|
|
1156
|
+
"gen_ai.conversation.id": rootSessionId,
|
|
1157
|
+
"session.id": rootSessionId,
|
|
1158
|
+
"pensar.session.id": agentSessionId,
|
|
1159
|
+
"pensar.root_session.id": rootSessionId,
|
|
1160
|
+
...(!isSubagent ? { "pensar.agent.mode": this.agentMode } : {}),
|
|
1161
|
+
};
|
|
1162
|
+
|
|
1163
|
+
const runInSpan = () =>
|
|
1164
|
+
getApexTracer().startActiveSpan(
|
|
1165
|
+
`invoke_agent ${spanLabel}`,
|
|
1166
|
+
{ attributes: runSpanAttributes },
|
|
1167
|
+
async (span) => {
|
|
1168
|
+
// Root runs register so process-exit shutdown can end an
|
|
1169
|
+
// in-flight run's span before the final flush.
|
|
1170
|
+
if (!isSubagent) registerActiveRootSpan(span);
|
|
1171
|
+
// Root-level input/output for trace previews — ONLY under full
|
|
1172
|
+
// payload capture (sensitive: objectives can name internal hosts).
|
|
1173
|
+
// Fast Strike uses a synthetic subagent id for UI routing but is the
|
|
1174
|
+
// primary run in that workflow.
|
|
1175
|
+
const recordRootIO =
|
|
1176
|
+
(!isSubagent || this.agentMode === "fast-strike") &&
|
|
1177
|
+
shouldRecordAiPayloads();
|
|
1178
|
+
if (recordRootIO && this.userPrompt) {
|
|
1179
|
+
span.setAttribute("gen_ai.prompt", this.userPrompt);
|
|
1180
|
+
}
|
|
1181
|
+
try {
|
|
1182
|
+
const result = await runConsume();
|
|
1183
|
+
const completedResult =
|
|
1184
|
+
result === undefined && this._responseToolFired
|
|
1185
|
+
? this._responseToolResult
|
|
1186
|
+
: result;
|
|
1187
|
+
if (
|
|
1188
|
+
recordRootIO &&
|
|
1189
|
+
completedResult !== undefined &&
|
|
1190
|
+
completedResult !== null
|
|
1191
|
+
) {
|
|
1192
|
+
span.setAttribute(
|
|
1193
|
+
"gen_ai.completion",
|
|
1194
|
+
safePreview(completedResult),
|
|
1195
|
+
);
|
|
1196
|
+
}
|
|
1197
|
+
return result;
|
|
1198
|
+
} catch (err) {
|
|
1199
|
+
// Record once, keep the cardinality low, preserve the original.
|
|
1200
|
+
span.recordException(err as Error);
|
|
1201
|
+
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1202
|
+
span.setAttribute(
|
|
1203
|
+
"error.type",
|
|
1204
|
+
err instanceof Error ? err.name : "Error",
|
|
1205
|
+
);
|
|
1206
|
+
if (recordRootIO) {
|
|
1207
|
+
span.setAttribute(
|
|
1208
|
+
"gen_ai.completion",
|
|
1209
|
+
this._responseToolFired
|
|
1210
|
+
? safePreview(this._responseToolResult)
|
|
1211
|
+
: `Failure: ${err instanceof Error ? err.message : String(err)}`,
|
|
1212
|
+
);
|
|
1213
|
+
}
|
|
1214
|
+
throw err;
|
|
1215
|
+
} finally {
|
|
1216
|
+
unregisterActiveRootSpan(span);
|
|
1217
|
+
// Ends only after runConsume's finalization (persistence +
|
|
1218
|
+
// owned-resource disposal) has settled. Shutdown may have already
|
|
1219
|
+
// ended it while that finalization was still in flight.
|
|
1220
|
+
if (span.isRecording()) span.end();
|
|
1221
|
+
}
|
|
1222
|
+
},
|
|
1223
|
+
);
|
|
1224
|
+
|
|
1225
|
+
const drain = !isSubagent
|
|
1226
|
+
? runInSpan()
|
|
1227
|
+
: withSubagentSessionBaggage(sid, runInSpan);
|
|
1228
|
+
|
|
1229
|
+
// Decouple the result from stream teardown: with a `response` schema, return as soon as it's captured rather than waiting for the stream to close (which can wedge).
|
|
1230
|
+
let rejectDrain: ((err: unknown) => void) | undefined;
|
|
1231
|
+
this._drainRejection = new Promise<never>((_, reject) => {
|
|
1232
|
+
rejectDrain = reject;
|
|
1233
|
+
});
|
|
1234
|
+
this._drainRejection.catch(() => {});
|
|
1235
|
+
|
|
1236
|
+
// Lets a caller that aborts after capturing the result await the drain's finally (in-flight tool closes) before completing.
|
|
1237
|
+
this.drained = drain.then(
|
|
1238
|
+
() => {},
|
|
1239
|
+
() => {},
|
|
1240
|
+
);
|
|
1241
|
+
|
|
1242
|
+
// Don't let drain's settle (reject OR resolve) mask an already-captured
|
|
1243
|
+
// response; unblock the resolver's streamResult.response wait either way.
|
|
1244
|
+
const guardedDrain = drain
|
|
1245
|
+
.then((result) => {
|
|
1246
|
+
if (this._responseToolFired) {
|
|
1247
|
+
rejectDrain?.(new Error("drain resolved"));
|
|
1248
|
+
return this.responseCaptured;
|
|
1249
|
+
}
|
|
1250
|
+
return result;
|
|
1251
|
+
})
|
|
1252
|
+
.catch((err) => {
|
|
1253
|
+
rejectDrain?.(err);
|
|
1254
|
+
if (!this._responseToolFired) throw err;
|
|
1255
|
+
return this.responseCaptured;
|
|
1256
|
+
});
|
|
1257
|
+
guardedDrain.catch(() => {});
|
|
1258
|
+
|
|
1259
|
+
const result = await Promise.race([guardedDrain, this.responseCaptured]);
|
|
1260
|
+
// Free the browser on result capture; the drain can wedge and leak camoufox.
|
|
1261
|
+
await this.disconnectOwnedBrowser();
|
|
1262
|
+
return result;
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
/**
|
|
1266
|
+
* Apply one stream part: part-id bookkeeping, lifecycle-tracker updates,
|
|
1267
|
+
* and the finish-step close-out emissions. Pure projection of the part
|
|
1268
|
+
* onto run state; forwarding to the bus is the caller's job.
|
|
1269
|
+
*/
|
|
1270
|
+
private applyStreamPart(
|
|
1271
|
+
chunk: TextStreamPart<ToolSet>,
|
|
1272
|
+
ctx: {
|
|
1273
|
+
ids: StreamIdContext;
|
|
1274
|
+
tracker: ToolLifecycleTracker;
|
|
1275
|
+
diagnostics: StreamDiagnostics;
|
|
1276
|
+
},
|
|
1277
|
+
): void {
|
|
1278
|
+
const { ids, tracker, diagnostics } = ctx;
|
|
1279
|
+
const sid = this.subagentId;
|
|
1280
|
+
const bus = this.eventBus;
|
|
1281
|
+
switch (chunk.type) {
|
|
1282
|
+
case "start-step":
|
|
1283
|
+
this.streamStepIndex++;
|
|
1284
|
+
this.streamTextPartIndex = 0;
|
|
1285
|
+
ids.messageId =
|
|
1286
|
+
this.streamIdFactory?.({
|
|
1287
|
+
kind: "message",
|
|
1288
|
+
stepIndex: this.streamStepIndex,
|
|
1289
|
+
}) ?? newMessageId();
|
|
1290
|
+
this.currentMessageId = ids.messageId;
|
|
1291
|
+
ids.textPartId = undefined;
|
|
1292
|
+
break;
|
|
1293
|
+
case "text-start":
|
|
1294
|
+
ids.textPartId =
|
|
1295
|
+
this.streamIdFactory?.({
|
|
1296
|
+
kind: "text-part",
|
|
1297
|
+
stepIndex: this.streamStepIndex,
|
|
1298
|
+
textPartIndex: this.streamTextPartIndex,
|
|
1299
|
+
}) ?? newPartId();
|
|
1300
|
+
this.streamTextPartIndex++;
|
|
1301
|
+
break;
|
|
1302
|
+
case "text-end":
|
|
1303
|
+
ids.textPartId = undefined;
|
|
1304
|
+
break;
|
|
1305
|
+
case "finish-step": {
|
|
1306
|
+
tracker.onStepPersisted();
|
|
1307
|
+
const finishReason = (chunk as { finishReason?: string }).finishReason;
|
|
1308
|
+
const truncated = finishReason === "length";
|
|
1309
|
+
|
|
1310
|
+
for (const [toolCallId, info] of tracker.toolErrors) {
|
|
1311
|
+
diagnostics.logSurfacedToolError({
|
|
1312
|
+
toolCallId,
|
|
1313
|
+
toolName: info.toolName,
|
|
1314
|
+
message: info.message,
|
|
1315
|
+
streamedArgChars: (tracker.streamedArgText.get(toolCallId) ?? "")
|
|
1316
|
+
.length,
|
|
1317
|
+
finishReason,
|
|
1318
|
+
truncated,
|
|
1319
|
+
});
|
|
1320
|
+
bus.emit("tool-result", {
|
|
1321
|
+
toolCallId,
|
|
1322
|
+
toolName: info.toolName,
|
|
1323
|
+
result: {
|
|
1324
|
+
type: "error-text",
|
|
1325
|
+
value: truncated
|
|
1326
|
+
? `Tool call failed: the model's output was truncated at its max output tokens before the "${info.toolName}" arguments were complete. ${info.message}`
|
|
1327
|
+
: `Tool call failed: ${info.message}`,
|
|
1328
|
+
},
|
|
1329
|
+
sessionId: this.busSessionId,
|
|
1330
|
+
subagentId: sid,
|
|
1331
|
+
partId: ids.toolPartId?.(toolCallId),
|
|
1332
|
+
messageId: ids.messageId,
|
|
1333
|
+
});
|
|
1334
|
+
}
|
|
1335
|
+
tracker.clearToolErrors();
|
|
1336
|
+
|
|
1337
|
+
// Close any call still in flight (args never finalized) so it doesn't render stuck "running".
|
|
1338
|
+
for (const [toolCallId, toolName] of tracker.inFlightTools) {
|
|
1339
|
+
diagnostics.logClosingInFlightTool({
|
|
1340
|
+
toolCallId,
|
|
1341
|
+
toolName,
|
|
1342
|
+
finishReason,
|
|
1343
|
+
truncated,
|
|
1344
|
+
});
|
|
1345
|
+
// Already-fired response: mark submitted, not "did not complete".
|
|
1346
|
+
const result =
|
|
1347
|
+
toolName === RESPONSE_TOOL_NAME && this._responseToolFired
|
|
1348
|
+
? { type: "text" as const, value: "Response submitted." }
|
|
1349
|
+
: {
|
|
1350
|
+
type: "error-text" as const,
|
|
1351
|
+
value: truncated
|
|
1352
|
+
? "Tool call did not complete: the model's output was truncated at its max output tokens before the arguments were finalized."
|
|
1353
|
+
: "Tool call did not complete",
|
|
1354
|
+
};
|
|
1355
|
+
bus.emit("tool-result", {
|
|
1356
|
+
toolCallId,
|
|
1357
|
+
toolName,
|
|
1358
|
+
result,
|
|
1359
|
+
sessionId: this.busSessionId,
|
|
1360
|
+
subagentId: sid,
|
|
1361
|
+
partId: ids.toolPartId?.(toolCallId),
|
|
1362
|
+
messageId: ids.messageId,
|
|
1363
|
+
});
|
|
1364
|
+
}
|
|
1365
|
+
tracker.clearInFlight();
|
|
1366
|
+
break;
|
|
1367
|
+
}
|
|
1368
|
+
default:
|
|
1369
|
+
// Tool-input/delta, tool-call, tool-error, tool-result → tracker.
|
|
1370
|
+
tracker.observePart(chunk);
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
/**
|
|
1375
|
+
* Finalize a finished (or failed) run: stop diagnostics, dispose the owned
|
|
1376
|
+
* shell, surface deferred tool errors, close the interrupted step, and
|
|
1377
|
+
* disconnect the owned browser on every path. Returns the first
|
|
1378
|
+
* finalization error (or null) — the caller keeps the stream error
|
|
1379
|
+
* primary.
|
|
1380
|
+
*/
|
|
1381
|
+
private async finalizeRun(input: {
|
|
1382
|
+
tracker: ToolLifecycleTracker;
|
|
1383
|
+
diagnostics: StreamDiagnostics;
|
|
1384
|
+
ids: StreamIdContext;
|
|
1385
|
+
streamError: unknown;
|
|
1386
|
+
}): Promise<unknown> {
|
|
1387
|
+
const { tracker, diagnostics, ids, streamError } = input;
|
|
1388
|
+
const sid = this.subagentId;
|
|
1389
|
+
const bus = this.eventBus;
|
|
1390
|
+
|
|
1391
|
+
// Stop the stall watchdog so it never leaks past stream end / throw.
|
|
1392
|
+
diagnostics.stop();
|
|
1393
|
+
let finalizationError: unknown;
|
|
1394
|
+
let hasFinalizationError = false;
|
|
1395
|
+
const recordFinalizationError = (error: unknown) => {
|
|
1396
|
+
if (hasFinalizationError) return;
|
|
1397
|
+
finalizationError = error;
|
|
1398
|
+
hasFinalizationError = true;
|
|
1399
|
+
};
|
|
1400
|
+
|
|
1401
|
+
try {
|
|
1402
|
+
// Dispose first — the 3s kill protocol is awaited, never
|
|
1403
|
+
// fire-and-forget: hosts rely on drained before closeout, so an
|
|
1404
|
+
// active command must settle (bounded) before finalization continues.
|
|
1405
|
+
try {
|
|
1406
|
+
await this.disposeOwnedShell();
|
|
1407
|
+
} catch (error) {
|
|
1408
|
+
recordFinalizationError(error);
|
|
1409
|
+
}
|
|
1410
|
+
// Stop this agent's callback listeners (each outcome independent;
|
|
1411
|
+
// the seam clears the abort signal so cleanup still runs post-abort).
|
|
1412
|
+
try {
|
|
1413
|
+
const outcomes = await this.callbackListeners.stopAll();
|
|
1414
|
+
const failed = outcomes.find((o) => o.error);
|
|
1415
|
+
if (failed) {
|
|
1416
|
+
recordFinalizationError(
|
|
1417
|
+
new Error(
|
|
1418
|
+
`callback listener cleanup failed for ${failed.jobId}: ${failed.error}`,
|
|
1419
|
+
),
|
|
1420
|
+
);
|
|
1421
|
+
}
|
|
1422
|
+
} catch (error) {
|
|
1423
|
+
recordFinalizationError(error);
|
|
1424
|
+
}
|
|
1425
|
+
// Flush after disposal: surfaces the latched step-commit failure (the
|
|
1426
|
+
// SDK swallows onStepFinish errors) without skipping owned cleanup.
|
|
1427
|
+
if (this.contextRecorder) {
|
|
1428
|
+
try {
|
|
1429
|
+
await this.contextRecorder.flush();
|
|
1430
|
+
} catch (error) {
|
|
1431
|
+
recordFinalizationError(error);
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
// Flush tool-errors that never reached a finish-step into the snapshot.
|
|
1435
|
+
for (const [toolCallId, info] of tracker.flushToolErrorsToResults()) {
|
|
1436
|
+
const result = {
|
|
1437
|
+
type: "error-text" as const,
|
|
1438
|
+
value: `Tool call failed: ${info.message}`,
|
|
1439
|
+
};
|
|
1440
|
+
try {
|
|
1441
|
+
bus.emit("tool-result", {
|
|
1442
|
+
toolCallId,
|
|
1443
|
+
toolName: info.toolName,
|
|
1444
|
+
result,
|
|
1445
|
+
sessionId: this.busSessionId,
|
|
1446
|
+
subagentId: sid,
|
|
1447
|
+
partId: ids.toolPartId?.(toolCallId),
|
|
1448
|
+
messageId: ids.messageId,
|
|
1449
|
+
});
|
|
1450
|
+
} catch (error) {
|
|
1451
|
+
recordFinalizationError(error);
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
// Snapshot unpersisted step state: open tools get synthetic closes,
|
|
1455
|
+
// completed/errored results get written.
|
|
1456
|
+
if (tracker.hasUnpersistedState()) {
|
|
1457
|
+
const failure =
|
|
1458
|
+
streamError ??
|
|
1459
|
+
(this.abortSignal?.aborted
|
|
1460
|
+
? agentAbortReason(this.abortSignal)
|
|
1461
|
+
: undefined);
|
|
1462
|
+
const reason =
|
|
1463
|
+
failure instanceof Error && failure.message
|
|
1464
|
+
? failure.message
|
|
1465
|
+
: failure !== undefined
|
|
1466
|
+
? String(failure)
|
|
1467
|
+
: "Stream terminated unexpectedly";
|
|
1468
|
+
try {
|
|
1469
|
+
await this.finalizeInterruptedStep({
|
|
1470
|
+
snapshot: tracker.snapshot(),
|
|
1471
|
+
reason,
|
|
1472
|
+
partIdFor: ids.toolPartId,
|
|
1473
|
+
messageId: ids.messageId,
|
|
1474
|
+
});
|
|
1475
|
+
} catch (error) {
|
|
1476
|
+
recordFinalizationError(error);
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
} catch (error) {
|
|
1480
|
+
recordFinalizationError(error);
|
|
1481
|
+
} finally {
|
|
1482
|
+
// Tear down the Chromium child process we own. Without this, a
|
|
1483
|
+
// naturally-finishing agent leaks its Playwright MCP browser — over a
|
|
1484
|
+
// long single-process scan (many endpoints) the leaked Chromium
|
|
1485
|
+
// processes exhaust memory and OOM the run. disconnect() force-kills
|
|
1486
|
+
// and never hangs, so awaiting here is safe.
|
|
1487
|
+
await this.disconnectOwnedBrowser();
|
|
1488
|
+
}
|
|
1489
|
+
return hasFinalizationError ? finalizationError : null;
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
// ---------------------------------------------------------------------------
|
|
1493
|
+
// Owned-resource disposal — explicit idempotent operations; the
|
|
1494
|
+
// finalization path and host teardown (abortAndDrain) coordinate them
|
|
1495
|
+
// without knowing the shell/browser implementations.
|
|
1496
|
+
// ---------------------------------------------------------------------------
|
|
1497
|
+
|
|
1498
|
+
/**
|
|
1499
|
+
* Disposes the owned per-command executor exactly once; safe to call from
|
|
1500
|
+
* multiple teardown paths. Returns the same cached barrier on repeat
|
|
1501
|
+
* calls; the barrier resolves once a killed invocation's bounded
|
|
1502
|
+
* termination protocol has settled, so closeout never races an active
|
|
1503
|
+
* command.
|
|
1504
|
+
*/
|
|
1505
|
+
disposeOwnedShell(): Promise<void> {
|
|
1506
|
+
if (this.shellDisposed) {
|
|
1507
|
+
return this.shellDisposeBarrier ?? Promise.resolve();
|
|
1508
|
+
}
|
|
1509
|
+
this.shellDisposed = true;
|
|
1510
|
+
this.shellDisposeBarrier =
|
|
1511
|
+
this.commandShell?.dispose() ?? Promise.resolve();
|
|
1512
|
+
return this.shellDisposeBarrier;
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1515
|
+
/** Force-kills the owned Chromium child process exactly once; safe to call from multiple teardown paths. */
|
|
1516
|
+
private async disconnectOwnedBrowser(): Promise<void> {
|
|
1517
|
+
if (this.browserDisconnected) return;
|
|
1518
|
+
if (!this.ownsBrowserSession || !this.browserSession) return;
|
|
1519
|
+
this.browserDisconnected = true;
|
|
1520
|
+
await this.browserSession.disconnect().catch(() => {});
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1523
|
+
/**
|
|
1524
|
+
* Idempotent teardown for hosts that abort before `consume()` settles
|
|
1525
|
+
* (Console `settleOnAbort` on timeout/pause). Force-disconnects the owned
|
|
1526
|
+
* browser, awaits the shell's bounded kill barrier, then awaits the drain
|
|
1527
|
+
* so owned work settles before the host starts closeout.
|
|
1528
|
+
*/
|
|
1529
|
+
async abortAndDrain(): Promise<void> {
|
|
1530
|
+
await this.disconnectOwnedBrowser();
|
|
1531
|
+
await this.disposeOwnedShell().catch(() => {});
|
|
1532
|
+
await this.callbackListeners.stopAll().catch(() => {});
|
|
1533
|
+
await this.drained.catch(() => {});
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
/**
|
|
1537
|
+
* Promise that resolves to the final response metadata once the stream
|
|
1538
|
+
* has been fully consumed. Await this *after* iterating the stream.
|
|
1539
|
+
*/
|
|
1540
|
+
get response() {
|
|
1541
|
+
return this.streamReady().then(() => this.streamResult.response);
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
// These tools pause the agent and surface their own UI to the operator.
|
|
1546
|
+
// Gating them through the approval gate would double-prompt.
|
|
1547
|
+
const AGENT_PAUSE_TOOLS = new Set<string>([ASK_USER_QUESTIONS_TOOL_NAME]);
|
|
1548
|
+
|
|
1549
|
+
function wrapToolsWithApprovalGate(
|
|
1550
|
+
tools: ToolSet,
|
|
1551
|
+
gate: ApprovalGate,
|
|
1552
|
+
exemptToolNames?: Set<string>,
|
|
1553
|
+
): ToolSet {
|
|
1554
|
+
const wrapped: ToolSet = {};
|
|
1555
|
+
|
|
1556
|
+
for (const [name, coreTool] of Object.entries(tools)) {
|
|
1557
|
+
if (exemptToolNames?.has(name)) {
|
|
1558
|
+
wrapped[name] = coreTool;
|
|
1559
|
+
continue;
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
// biome-ignore lint/suspicious/noExplicitAny: ai-sdk CoreTool is a discriminated union that requires runtime narrowing for the approval gate wrapper.
|
|
1563
|
+
const t = coreTool as any;
|
|
1564
|
+
|
|
1565
|
+
if (!t.execute) {
|
|
1566
|
+
wrapped[name] = coreTool;
|
|
1567
|
+
continue;
|
|
1568
|
+
}
|
|
1569
|
+
|
|
1570
|
+
const originalExecute = t.execute;
|
|
1571
|
+
|
|
1572
|
+
wrapped[name] = {
|
|
1573
|
+
...t,
|
|
1574
|
+
// biome-ignore lint/suspicious/noExplicitAny: ai-sdk tool execute receives an opaque ExecuteContext we don't need to narrow.
|
|
1575
|
+
execute: async (args: Record<string, unknown>, options: any) => {
|
|
1576
|
+
const toolCallId =
|
|
1577
|
+
args.toolCallId ??
|
|
1578
|
+
`tc_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
1579
|
+
|
|
1580
|
+
log.debug(`${name} (${toolCallId}): checking`);
|
|
1581
|
+
try {
|
|
1582
|
+
await gate.check(name, String(toolCallId), args);
|
|
1583
|
+
} catch (err) {
|
|
1584
|
+
if (err instanceof ApprovalDeniedError) {
|
|
1585
|
+
log.debug(`${name} (${toolCallId}): denied`);
|
|
1586
|
+
return { blocked: true, reason: "Denied by operator" };
|
|
1587
|
+
}
|
|
1588
|
+
throw err;
|
|
1589
|
+
}
|
|
1590
|
+
log.debug(`${name} (${toolCallId}): approved, executing`);
|
|
1591
|
+
|
|
1592
|
+
const result = await originalExecute(args, options);
|
|
1593
|
+
log.debug(`${name} (${toolCallId}): execute finished`);
|
|
1594
|
+
return result;
|
|
1595
|
+
},
|
|
1596
|
+
};
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
return wrapped;
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1602
|
+
/** Bounded, crash-safe JSON preview of a run result for span output. */
|
|
1603
|
+
function safePreview(value: unknown): string {
|
|
1604
|
+
try {
|
|
1605
|
+
const text = JSON.stringify(value);
|
|
1606
|
+
return text === undefined ? String(value) : text.slice(0, 2000);
|
|
1607
|
+
} catch {
|
|
1608
|
+
return "[unserializable result]";
|
|
1609
|
+
}
|
|
1610
|
+
}
|