@pensar/apex 2.6.1 → 2.7.0-canary.1572d9a4
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/build/{agent-ayreaj6z.js → agent-3g1b578v.js} +6 -5
- package/build/{agent-yby11zaq.js → agent-p8cezgbb.js} +7 -6
- package/build/{agent-runs-g37vkrjr.js → agent-runs-f86emmgg.js} +23 -20
- package/build/agent-vaq31je6.js +14 -0
- package/build/agent-vvdqga09.js +14 -0
- package/build/{apps-xn6km9yn.js → apps-3stwnmen.js} +16 -13
- package/build/{auth-d105wc64.js → auth-7md9kwda.js} +16 -13
- package/build/blackboxAgent-ct8bejef.js +14 -0
- package/build/{blackboxPentest-ps78v3w7.js → blackboxPentest-w2nr4md3.js} +21 -15
- package/build/{cli-c05y640n.js → cli-1j28cbhy.js} +1 -1
- package/build/{cli-d37a42dc.js → cli-2jz2jz06.js} +206 -90
- package/build/{cli-az3xq70v.js → cli-4a8dsz2k.js} +4 -4
- package/build/{cli-qgz1q9g5.js → cli-58781vcf.js} +1192 -1473
- package/build/{cli-gx71jcke.js → cli-7067zzeb.js} +1 -1
- package/build/{cli-3sp6nd8d.js → cli-81smmd5w.js} +5 -5
- package/build/{cli-k2nwxta0.js → cli-8b25dhky.js} +2 -2
- package/build/{cli-fy6vh2a7.js → cli-8sw5zpqz.js} +1 -1
- package/build/{cli-709rvekb.js → cli-cg3ypx5n.js} +14 -7
- package/build/{cli-dpsw2fe6.js → cli-e9v6zg6h.js} +40941 -40172
- package/build/cli-fjxmphg1.js +36 -0
- package/build/{cli-7eea4e2y.js → cli-gzb6qrzh.js} +31 -60
- package/build/{cli-65g6rcat.js → cli-khnf5xrf.js} +2 -1
- package/build/{cli-1ve18npr.js → cli-mdzt2e8j.js} +4 -2
- package/build/{cli-n2en7j5b.js → cli-n8mmw4c4.js} +1 -1
- package/build/cli-pndb7mh9.js +1193 -0
- package/build/cli-px6ehzqx.js +54 -0
- package/build/{cli-xtc2t6me.js → cli-qs4msn6x.js} +111 -47
- package/build/{cli-kb21qhvm.js → cli-rvybdhgn.js} +4 -3
- package/build/{cli-ae8jqxqr.js → cli-v739h7hb.js} +2 -2
- package/build/{cli-ngq9dr8n.js → cli-wm8ech0x.js} +3 -3
- package/build/cli.js +170 -51
- package/build/{config-zpqkd5cz.js → config-e5v1bkh1.js} +1 -1
- package/build/{fastStrike-mcjdvwez.js → fastStrike-efp0rjs3.js} +74 -17
- package/build/{fixes-kytx5dmj.js → fixes-926cw1ej.js} +16 -13
- package/build/{index-n65z6v7b.js → index-3t41p258.js} +7 -6
- package/build/{index-qv4cc65p.js → index-bv09af6g.js} +19 -15
- package/build/{index-je6hcsqr.js → index-bv6dtwse.js} +1 -1
- package/build/{index-4vqdgb42.js → index-jt52ffgn.js} +1657 -1400
- package/build/{index-ns4m4s01.js → index-np405b9e.js} +11 -7
- package/build/{index-r9yjkfrv.js → index-qys178kp.js} +5 -4
- package/build/{index-wqetp6gq.js → index-tpyzq2wq.js} +42 -11
- package/build/{index-fv64eb32.js → index-vrcdyebh.js} +2 -2
- package/build/{index-dr3tg1w3.js → index-z1g8vbtm.js} +1 -1
- package/build/{issues-eb3q9d3a.js → issues-sncyqh14.js} +16 -13
- package/build/{knowledge-fqsvtx0f.js → knowledge-esgvy5ws.js} +16 -13
- package/build/lance-sacfgs1z.js +232 -0
- package/build/lib/{chunk-9yksqgzr.js → chunk-4aevegnc.js} +77 -45
- package/build/lib/{chunk-9tt2021m.js → chunk-4kf4a15q.js} +13 -13
- package/build/lib/{chunk-fy3bbbqy.js → chunk-5avnedwm.js} +7 -1
- package/build/lib/{chunk-bb0ekhkw.js → chunk-5nz5tk3p.js} +76 -22
- package/build/lib/{chunk-4hwzqthr.js → chunk-7s8e5wrd.js} +3 -2
- package/build/lib/{chunk-yrnrbjes.js → chunk-85kpxwzs.js} +4 -2
- package/build/lib/{chunk-mg03jdmt.js → chunk-9jkzk9nc.js} +1 -1
- package/build/lib/{chunk-r4j8ybn9.js → chunk-9wwts6r6.js} +824 -77
- package/build/lib/{chunk-nhfax4gb.js → chunk-bxznzxdy.js} +5 -1
- package/build/lib/{chunk-r2dkp4tb.js → chunk-cqxm95md.js} +1 -1
- package/build/lib/{chunk-w66ce82a.js → chunk-e3agqspc.js} +12 -4
- package/build/lib/{chunk-ba41jh41.js → chunk-eh5yw385.js} +1137 -333
- package/build/lib/{chunk-1azdancq.js → chunk-ewc9r84m.js} +5 -1
- package/build/lib/{chunk-2njv7wz3.js → chunk-hbyxyxdc.js} +4 -0
- package/build/lib/{chunk-e8yy2k73.js → chunk-jhhwts6w.js} +28 -2
- package/build/lib/{chunk-1jvwqnem.js → chunk-kbxbd1kn.js} +108 -44
- package/build/lib/{chunk-7pwa92rn.js → chunk-mph5fvk7.js} +1 -1
- package/build/lib/chunk-psc23epq.js +107 -0
- package/build/lib/{chunk-acgbyf5h.js → chunk-qxad7qjd.js} +4 -2
- package/build/lib/{chunk-3c00n0cy.js → chunk-r0v3vvgm.js} +54 -33
- package/build/lib/{chunk-1yct6cra.js → chunk-rt13120a.js} +1 -1
- package/build/lib/{chunk-v3dk9j7k.js → chunk-sgya016v.js} +93 -22
- package/build/lib/{chunk-1fy8azee.js → chunk-txef92hq.js} +1 -1
- package/build/lib/{chunk-2qsq76xq.js → chunk-vcd90qrn.js} +189 -90
- package/build/lib/{chunk-7gjdygcx.js → chunk-vwr9w3ab.js} +2 -0
- package/build/lib/{chunk-z137x08b.js → chunk-wf6ak0m3.js} +92 -70
- package/build/lib/{chunk-xhdpgpkm.js → chunk-xft0ms9j.js} +2 -2
- package/build/lib/core/agents/agentRuntime.d.ts +3 -1
- package/build/lib/core/agents/defineAgent.d.ts +3 -2
- package/build/lib/core/agents/lance.d.ts +153 -0
- package/build/lib/core/agents/lanceJudge.d.ts +3 -0
- package/build/lib/core/agents/offSecAgent/index.d.ts +3 -1
- package/build/lib/core/agents/offSecAgent/index.js +16 -14
- package/build/lib/core/agents/offSecAgent/offensiveSecurityAgent.d.ts +4 -0
- package/build/lib/core/agents/offSecAgent/prompt.d.ts +3 -1
- package/build/lib/core/agents/offSecAgent/subagentSpawner.d.ts +18 -2
- package/build/lib/core/agents/offSecAgent/subagentSpawner.js +10 -8
- package/build/lib/core/agents/offSecAgent/toolExecutionContext.d.ts +3 -0
- package/build/lib/core/agents/offSecAgent/toolLifecycle.d.ts +1 -0
- package/build/lib/core/agents/offSecAgent/tools/index.js +10 -6
- package/build/lib/core/agents/offSecAgent/tools/listMemories.d.ts +11 -1
- package/build/lib/core/agents/offSecAgent/tools/reportError.d.ts +2 -1
- package/build/lib/core/agents/offSecAgent/tools/runPentestWorkflow.d.ts +20 -1
- package/build/lib/core/agents/offSecAgent/tools/spawnPentestAgent.d.ts +4 -7
- package/build/lib/core/agents/offSecAgent/tools/spawnPentestSwarm.d.ts +7 -1
- package/build/lib/core/agents/offSecAgent/tools/types.d.ts +6 -3
- package/build/lib/core/agents/offSecAgent/tools/whiteboxCandidates.d.ts +2 -2
- package/build/lib/core/agents/offSecAgent/types.d.ts +19 -3
- package/build/lib/core/agents/specialized/attackSurface/blackboxAgent.js +13 -13
- package/build/lib/core/agents/specialized/attackSurface/schemas.js +12 -12
- package/build/lib/core/agents/specialized/authenticationAgent/index.js +14 -14
- package/build/lib/core/agents/specialized/codeAgent/agent.js +13 -13
- package/build/lib/core/agents/specialized/codeAgent/prompts.d.ts +1 -0
- package/build/lib/core/agents/specialized/cvssScorer/index.d.ts +2 -1
- package/build/lib/core/agents/specialized/findingJudge/agent.js +11 -11
- package/build/lib/core/agents/specialized/findingJudge/index.d.ts +2 -1
- package/build/lib/core/agents/specialized/findingJudge/index.js +4 -4
- package/build/lib/core/agents/specialized/patching/index.js +14 -14
- package/build/lib/core/agents/specialized/pentest/agent.d.ts +18 -4
- package/build/lib/core/agents/specialized/pentest/agent.js +15 -13
- package/build/lib/core/agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent.d.ts +2 -1
- package/build/lib/core/agents/specialized/whiteboxAttackSurface/index.js +13 -13
- package/build/lib/core/ai/ai.d.ts +29 -70
- package/build/lib/core/ai/ai.js +5 -3
- package/build/lib/core/ai/index.d.ts +1 -0
- package/build/lib/core/ai/index.js +16 -4
- package/build/lib/core/ai/models/claude-capabilities.d.ts +3 -2
- package/build/lib/core/ai/models/concentrate.d.ts +1 -0
- package/build/lib/core/ai/models/index.d.ts +1 -1
- package/build/lib/core/ai/providers/concentrate.d.ts +1 -0
- package/build/lib/core/ai/reasoning.d.ts +44 -0
- package/build/lib/core/ai/utils.d.ts +2 -0
- package/build/lib/core/ai/utils.js +5 -3
- package/build/lib/core/api/index.d.ts +6 -0
- package/build/lib/core/api/index.js +32 -23
- package/build/lib/core/api/lance.d.ts +6 -0
- package/build/lib/core/api/offesecAgent.d.ts +1 -0
- package/build/lib/core/api/reasoning.d.ts +12 -0
- package/build/lib/core/api/targetedPentest.d.ts +1 -0
- package/build/lib/core/api/targetedPentest.js +14 -14
- package/build/lib/core/cli/reasoning.d.ts +4 -0
- package/build/lib/core/config/config.d.ts +10 -2
- package/build/lib/core/config/customProviders.d.ts +11 -0
- package/build/lib/core/config/index.js +1 -1
- package/build/lib/core/eventBus.js +1 -1
- package/build/lib/core/findings/registry.d.ts +3 -1
- package/build/lib/core/findings/registry.js +4 -4
- package/build/lib/core/observability/index.js +1 -1
- package/build/lib/core/observability/telemetry.d.ts +4 -0
- package/build/lib/core/session/index.d.ts +47 -0
- package/build/lib/core/session/index.js +6 -4
- package/build/lib/core/session/persistence.d.ts +7 -0
- package/build/lib/core/session/persistence.js +8 -4
- package/build/lib/core/tools/backends/index.js +1 -1
- package/build/lib/core/tools/backends/resolve.d.ts +1 -0
- package/build/lib/core/workflows/fastStrike.d.ts +3 -1
- package/build/lib/core/workflows/pentest.d.ts +12 -2
- package/build/lib/core/workflows/pentest.js +19 -19
- package/build/lib/core/workflows/seams.js +5 -5
- package/build/lib/core/workflows/threatModel.d.ts +1 -0
- package/build/lib/core/workflows/whiteboxAttackSurface.d.ts +6 -4
- package/build/lib/core/workflows/whiteboxAttackSurface.js +15 -15
- package/build/lib/index.js +25 -25
- package/build/{logs-x62b7hk1.js → logs-bcbjpjp6.js} +16 -13
- package/build/{native-rollout-evidence-c9yhfqcs.js → native-rollout-evidence-rph1774m.js} +5 -5
- package/build/offesecAgent-81h1p6ee.js +32 -0
- package/build/pentest-2q20q6n1.js +23 -0
- package/build/{pentests-e0f32aqx.js → pentests-jgw031mc.js} +16 -13
- package/build/recordedRunClient-6axj6fba.js +11 -0
- package/build/subagentSpawner-a861gvt0.js +12 -0
- package/build/targetedPentest-6yxznt7s.js +91 -0
- package/build/{targets-xj9g3q0z.js → targets-bjah19dp.js} +16 -13
- package/build/threatModel-739kpexm.js +24 -0
- package/build/{uninstall-7s784q4a.js → uninstall-yxrn9edt.js} +1 -1
- package/build/{upload-4gvhwmvr.js → upload-34ewrjp5.js} +4 -4
- package/build/{utils-cjrz64pc.js → utils-fzm66efw.js} +5 -5
- package/package.json +2 -1
- package/src/cli/issues.test.ts +17 -1
- package/src/cli/lance-verifier.test.ts +57 -0
- package/src/cli/lance-verifier.ts +73 -0
- package/src/cli/lance.test.ts +71 -0
- package/src/cli/lance.ts +48 -0
- package/src/cli.ts +109 -19
- package/src/core/agents/agentRuntime.test.ts +42 -0
- package/src/core/agents/agentRuntime.ts +7 -2
- package/src/core/agents/defineAgent.ts +3 -1
- package/src/core/agents/lance.test.ts +421 -0
- package/src/core/agents/lance.ts +701 -0
- package/src/core/agents/lanceJudge.test.ts +166 -0
- package/src/core/agents/lanceJudge.ts +115 -0
- package/src/core/agents/offSecAgent/index.ts +3 -0
- package/src/core/agents/offSecAgent/interruptedStepFinalization.test.ts +51 -0
- package/src/core/agents/offSecAgent/lance.test.ts +188 -0
- package/src/core/agents/offSecAgent/offensiveSecurityAgent.test.ts +92 -5
- package/src/core/agents/offSecAgent/offensiveSecurityAgent.ts +244 -41
- package/src/core/agents/offSecAgent/prompt.test.ts +46 -0
- package/src/core/agents/offSecAgent/prompt.ts +52 -8
- package/src/core/agents/offSecAgent/selectiveConstruction.publicPath.test.ts +38 -0
- package/src/core/agents/offSecAgent/selectiveConstruction.test.ts +64 -0
- package/src/core/agents/offSecAgent/subagentSpawner.hooks.test.ts +11 -3
- package/src/core/agents/offSecAgent/subagentSpawner.reasoning.test.ts +167 -0
- package/src/core/agents/offSecAgent/subagentSpawner.ts +82 -28
- package/src/core/agents/offSecAgent/toolExecutionContext.test.ts +230 -0
- package/src/core/agents/offSecAgent/toolExecutionContext.ts +56 -0
- package/src/core/agents/offSecAgent/toolLifecycle.ts +2 -0
- package/src/core/agents/offSecAgent/tools/delegateAuth.ts +4 -2
- package/src/core/agents/offSecAgent/tools/documentFinding.test.ts +9 -4
- package/src/core/agents/offSecAgent/tools/documentFinding.ts +10 -9
- package/src/core/agents/offSecAgent/tools/listMemories.test.ts +230 -0
- package/src/core/agents/offSecAgent/tools/listMemories.ts +73 -6
- package/src/core/agents/offSecAgent/tools/reportError.test.ts +6 -0
- package/src/core/agents/offSecAgent/tools/reportError.ts +10 -2
- package/src/core/agents/offSecAgent/tools/runAttackSurface.ts +7 -4
- package/src/core/agents/offSecAgent/tools/runPentestWorkflow.test.ts +57 -0
- package/src/core/agents/offSecAgent/tools/runPentestWorkflow.ts +21 -1
- package/src/core/agents/offSecAgent/tools/runWhiteboxScan.ts +5 -2
- package/src/core/agents/offSecAgent/tools/spawnCodingAgent.ts +50 -67
- package/src/core/agents/offSecAgent/tools/spawnPentestAgent.test.ts +79 -3
- package/src/core/agents/offSecAgent/tools/spawnPentestAgent.ts +36 -16
- package/src/core/agents/offSecAgent/tools/spawnPentestSwarm.ts +28 -5
- package/src/core/agents/offSecAgent/tools/threatModelGenerator.ts +4 -3
- package/src/core/agents/offSecAgent/tools/types.ts +12 -2
- package/src/core/agents/offSecAgent/tools/updateTask.ts +5 -1
- package/src/core/agents/offSecAgent/tools/whiteboxCandidates.ts +11 -4
- package/src/core/agents/offSecAgent/types.ts +22 -1
- package/src/core/agents/specialized/codeAgent/agent.test.ts +7 -0
- package/src/core/agents/specialized/codeAgent/agent.ts +9 -2
- package/src/core/agents/specialized/codeAgent/prompts.ts +6 -0
- package/src/core/agents/specialized/cvssScorer/index.test.ts +2 -1
- package/src/core/agents/specialized/cvssScorer/index.ts +3 -0
- package/src/core/agents/specialized/findingJudge/index.ts +6 -0
- package/src/core/agents/specialized/pentest/agent.test.ts +155 -0
- package/src/core/agents/specialized/pentest/agent.ts +181 -52
- package/src/core/agents/specialized/pentest/results.test.ts +59 -4
- package/src/core/agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent.concurrency.test.ts +59 -2
- package/src/core/agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent.hooks.test.ts +127 -0
- package/src/core/agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent.ts +74 -68
- package/src/core/ai/ai.durability-hooks.test.ts +25 -7
- package/src/core/ai/ai.lance.test.ts +581 -0
- package/src/core/ai/ai.operator-context.bench.test.ts +1390 -0
- package/src/core/ai/ai.recorded-context.test.ts +89 -8
- package/src/core/ai/ai.test.ts +81 -59
- package/src/core/ai/ai.ts +453 -327
- package/src/core/ai/compactionTelemetry.test.ts +69 -17
- package/src/core/ai/index.ts +11 -0
- package/src/core/ai/models/anthropic.ts +6 -0
- package/src/core/ai/models/bedrock.ts +18 -0
- package/src/core/ai/models/claude-capabilities.ts +29 -8
- package/src/core/ai/models/concentrate.ts +52 -0
- package/src/core/ai/models/index.ts +25 -4
- package/src/core/ai/models/models.test.ts +179 -7
- package/src/core/ai/models/openrouter-reasoning.json +219 -0
- package/src/core/ai/models/openrouter.ts +43 -1
- package/src/core/ai/providers/anthropic-models.test.ts +60 -1
- package/src/core/ai/providers/bedrock-models.test.ts +81 -0
- package/src/core/ai/providers/concentrate.test.ts +31 -0
- package/src/core/ai/providers/concentrate.ts +11 -0
- package/src/core/ai/providers/custom.test.ts +74 -0
- package/src/core/ai/providers/custom.ts +3 -1
- package/src/core/ai/providers/gateway-models.test.ts +16 -6
- package/src/core/ai/providers/pensarFormatters.ts +8 -1
- package/src/core/ai/reasoning.test.ts +313 -0
- package/src/core/ai/reasoning.ts +500 -0
- package/src/core/ai/streamIdleTimeout.test.ts +21 -0
- package/src/core/ai/utils.native-rollout-evidence.test.ts +21 -8
- package/src/core/ai/utils.ts +269 -163
- package/src/core/api/attackSurface.ts +1 -0
- package/src/core/api/blackboxPentest.ts +9 -1
- package/src/core/api/index.ts +17 -0
- package/src/core/api/lance.ts +23 -0
- package/src/core/api/offesecAgent.test.ts +51 -0
- package/src/core/api/offesecAgent.ts +15 -1
- package/src/core/api/reasoning.test.ts +213 -0
- package/src/core/api/reasoning.ts +44 -0
- package/src/core/api/recordedRun.loop.test.ts +5 -1
- package/src/core/api/targetedPentest.test.ts +14 -2
- package/src/core/api/targetedPentest.ts +52 -5
- package/src/core/cli/reasoning.test.ts +149 -0
- package/src/core/cli/reasoning.ts +95 -0
- package/src/core/config/config.test.ts +35 -0
- package/src/core/config/config.ts +11 -0
- package/src/core/config/customProviders.ts +21 -2
- package/src/core/eventBus.ts +1 -0
- package/src/core/findings/registry.test.ts +9 -1
- package/src/core/findings/registry.ts +6 -0
- package/src/core/observability/telemetry.test.ts +131 -79
- package/src/core/observability/telemetry.ts +5 -0
- package/src/core/runtime/sqliteRunObservation.test.ts +1 -1
- package/src/core/session/index.ts +38 -0
- package/src/core/session/persistence.test.ts +62 -0
- package/src/core/session/persistence.ts +56 -0
- package/src/core/tools/backends/resolve.ts +7 -0
- package/src/core/tools/backends/whiteboxJobs.test.ts +9 -8
- package/src/core/workflows/fastStrike.seams.test.ts +149 -0
- package/src/core/workflows/fastStrike.test.ts +18 -1
- package/src/core/workflows/fastStrike.ts +106 -11
- package/src/core/workflows/pentest.test.ts +104 -0
- package/src/core/workflows/pentest.ts +128 -7
- package/src/core/workflows/seams.test.ts +13 -0
- package/src/core/workflows/seams.ts +5 -1
- package/src/core/workflows/threatModel.ts +2 -0
- package/src/core/workflows/whiteboxAttackSurface.test.ts +74 -2
- package/src/core/workflows/whiteboxAttackSurface.ts +102 -73
- package/src/tui/command-registry.test.ts +12 -0
- package/src/tui/command-registry.ts +10 -0
- package/src/tui/components/chat/config-view.tsx +6 -10
- package/src/tui/components/chat/home-view.tsx +2 -2
- package/src/tui/components/chat/input-area.tsx +2 -2
- package/src/tui/components/chat/loading-indicator.tsx +20 -4
- package/src/tui/components/chat/message-list.tsx +1 -0
- package/src/tui/components/commands/__tests__/advanced-settings-lifecycle.tsx +164 -0
- package/src/tui/components/commands/advanced-settings.test.ts +34 -0
- package/src/tui/components/commands/advanced-settings.tsx +220 -31
- package/src/tui/components/commands/models-display.tsx +7 -1
- package/src/tui/components/model-picker/ModelPicker.tsx +65 -103
- package/src/tui/components/model-picker/ModelPickerDialog.tsx +8 -14
- package/src/tui/components/model-picker/__tests__/reasoning-control.tsx +162 -0
- package/src/tui/components/model-picker/reasoning-control.test.ts +15 -0
- package/src/tui/components/operator-dashboard/index.tsx +166 -50
- package/src/tui/components/operator-dashboard/logic.test.ts +144 -2
- package/src/tui/components/operator-dashboard/logic.ts +54 -3
- package/src/tui/components/operator-dashboard/run-events.test.ts +3 -1
- package/src/tui/components/shared/__tests__/tool-renderer-lifecycle.tsx +18 -0
- package/src/tui/components/shared/action-label.test.ts +9 -0
- package/src/tui/components/shared/compacting-icon.tsx +18 -0
- package/src/tui/components/shared/index.ts +1 -0
- package/src/tui/components/shared/tool-registry.ts +1 -0
- package/src/tui/components/shared/tool-renderer.tsx +21 -7
- package/src/tui/context/agent.tsx +32 -79
- package/src/tui/context/route.tsx +2 -0
- package/src/tui/index.tsx +1 -0
- package/src/tui/keybindings/registry.ts +2 -0
- package/build/agent-6w7egcf1.js +0 -13
- package/build/agent-9zx75feh.js +0 -13
- package/build/blackboxAgent-s56sgx9b.js +0 -13
- package/build/cli-g06s7edq.js +0 -11
- package/build/lib/chunk-z96pbjhd.js +0 -56
- package/build/offesecAgent-5whnpeta.js +0 -22
- package/build/pentest-e61hc38s.js +0 -22
- package/build/recordedRunClient-dp032c32.js +0 -11
- package/build/targetedPentest-rcbs4nvp.js +0 -57
- package/build/threatModel-jkxfa40s.js +0 -21
|
@@ -8,7 +8,7 @@ import type {
|
|
|
8
8
|
TextStreamPart,
|
|
9
9
|
ToolSet,
|
|
10
10
|
} from "ai";
|
|
11
|
-
import { hasToolCall } from "ai";
|
|
11
|
+
import { hasToolCall, stepCountIs } from "ai";
|
|
12
12
|
import { normalizeStepUsage, streamResponse } from "../../ai";
|
|
13
13
|
import { AgentEventBus, type StreamIdContext } from "../../eventBus";
|
|
14
14
|
import { newMessageId, newPartId } from "../../id/id";
|
|
@@ -25,6 +25,8 @@ import { ApprovalDeniedError } from "../../operator";
|
|
|
25
25
|
import type { RunContextRecorder } from "../../runtime/runContext";
|
|
26
26
|
import { create as createSession, type SessionInfo } from "../../session";
|
|
27
27
|
import { scopedLogger } from "../../util/lazyLogger";
|
|
28
|
+
import { LANCE_CONFIG, LANCE_SYSTEM_PROMPT, LanceRuntime } from "../lance";
|
|
29
|
+
import { createLanceJudgeVerifier } from "../lanceJudge";
|
|
28
30
|
import {
|
|
29
31
|
createInterruptedStepFinalizer,
|
|
30
32
|
type FinalizeInterruptedStepInput,
|
|
@@ -43,6 +45,7 @@ import {
|
|
|
43
45
|
} from "./runtimeContext";
|
|
44
46
|
import { responseArgBytes, StreamDiagnostics } from "./streamDiagnostics";
|
|
45
47
|
import { inProcessSubagentSpawner } from "./subagentSpawner";
|
|
48
|
+
import { wrapToolExecutionContext } from "./toolExecutionContext";
|
|
46
49
|
import { ToolLifecycleTracker } from "./toolLifecycle";
|
|
47
50
|
import {
|
|
48
51
|
ASK_USER_QUESTIONS_TOOL_NAME,
|
|
@@ -298,6 +301,7 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
298
301
|
|
|
299
302
|
private readonly resolveResult?: (
|
|
300
303
|
streamResult: StreamTextResult<ToolSet, never>,
|
|
304
|
+
validatedResponse?: unknown,
|
|
301
305
|
) => TResult | Promise<TResult>;
|
|
302
306
|
|
|
303
307
|
/** The structured result captured by the `response` tool, or `null` until it fires. */
|
|
@@ -423,8 +427,18 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
423
427
|
let session = input.session;
|
|
424
428
|
if (!session) {
|
|
425
429
|
session = await createSession({
|
|
430
|
+
...(input.mode === "lance" ? { name: "Lance" } : {}),
|
|
426
431
|
targets: input.target ? [input.target] : [],
|
|
427
|
-
config:
|
|
432
|
+
config:
|
|
433
|
+
input.reasoning === undefined
|
|
434
|
+
? input.sessionConfig
|
|
435
|
+
: {
|
|
436
|
+
...input.sessionConfig,
|
|
437
|
+
modelReasoning: {
|
|
438
|
+
model: input.model,
|
|
439
|
+
setting: input.reasoning,
|
|
440
|
+
},
|
|
441
|
+
},
|
|
428
442
|
model: input.model,
|
|
429
443
|
authConfig: input.authConfig,
|
|
430
444
|
userMessage: input.prompt,
|
|
@@ -444,7 +458,65 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
444
458
|
return this.subagentId ?? this._session.id;
|
|
445
459
|
}
|
|
446
460
|
|
|
461
|
+
readonly lanceRuntime?: LanceRuntime;
|
|
462
|
+
private lanceModel?: string;
|
|
463
|
+
|
|
447
464
|
constructor(input: OffensiveSecurityAgentInput<TResult>) {
|
|
465
|
+
if (
|
|
466
|
+
input.mode === "lance" &&
|
|
467
|
+
!input.lance?.interactive &&
|
|
468
|
+
existsSync(join(input.session.rootPath, "lance-result.json"))
|
|
469
|
+
) {
|
|
470
|
+
throw new Error("This Lance attempt is terminal; use a new session");
|
|
471
|
+
}
|
|
472
|
+
if (input.mode === "lance") {
|
|
473
|
+
if (
|
|
474
|
+
input.extraTools ||
|
|
475
|
+
input.responseSchema ||
|
|
476
|
+
input.subagentSpawner ||
|
|
477
|
+
input.system ||
|
|
478
|
+
input.resolveResult ||
|
|
479
|
+
input.subagentId
|
|
480
|
+
) {
|
|
481
|
+
throw new Error(
|
|
482
|
+
"Lance does not permit tool, prompt, response, or spawner overrides",
|
|
483
|
+
);
|
|
484
|
+
}
|
|
485
|
+
const lanceOptions = { ...input.lance };
|
|
486
|
+
this.lanceRuntime = new LanceRuntime(
|
|
487
|
+
lanceOptions,
|
|
488
|
+
input.abortSignal,
|
|
489
|
+
input.session.rootPath,
|
|
490
|
+
);
|
|
491
|
+
if (input.findingPolicy === "native" && !lanceOptions.verifyObjective) {
|
|
492
|
+
lanceOptions.verificationSource = "apex_judge";
|
|
493
|
+
lanceOptions.verifyObjective = createLanceJudgeVerifier(
|
|
494
|
+
input,
|
|
495
|
+
this.lanceRuntime,
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
this.lanceModel = input.model;
|
|
499
|
+
const middleware = input.languageModelMiddleware;
|
|
500
|
+
input = {
|
|
501
|
+
...input,
|
|
502
|
+
system: LANCE_SYSTEM_PROMPT,
|
|
503
|
+
abortSignal: this.lanceRuntime.signal,
|
|
504
|
+
subagentSpawner: this.lanceRuntime.spawner,
|
|
505
|
+
languageModelMiddleware: [
|
|
506
|
+
this.lanceRuntime.middleware,
|
|
507
|
+
...(Array.isArray(middleware)
|
|
508
|
+
? middleware
|
|
509
|
+
: middleware
|
|
510
|
+
? [middleware]
|
|
511
|
+
: []),
|
|
512
|
+
],
|
|
513
|
+
stopWhen: [
|
|
514
|
+
() => this.lanceRuntime!.terminal,
|
|
515
|
+
stepCountIs(LANCE_CONFIG.maxSteps),
|
|
516
|
+
],
|
|
517
|
+
skillsRegistry: undefined,
|
|
518
|
+
};
|
|
519
|
+
}
|
|
448
520
|
this._session = input.session;
|
|
449
521
|
this.subagentId = input.subagentId;
|
|
450
522
|
this.subagentName = input.subagentName;
|
|
@@ -552,6 +624,7 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
552
624
|
input.credentialManager ?? input.session.credentialManager;
|
|
553
625
|
|
|
554
626
|
const toolCtx = {
|
|
627
|
+
findingPolicy: input.findingPolicy,
|
|
555
628
|
...(input.attackSurfaceArtifactsPath
|
|
556
629
|
? { attackSurfaceArtifactsPath: input.attackSurfaceArtifactsPath }
|
|
557
630
|
: {}),
|
|
@@ -589,6 +662,7 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
589
662
|
enableThinking: input.enableThinking,
|
|
590
663
|
thinkingEffort: input.thinkingEffort,
|
|
591
664
|
openAIReasoningEffort: input.openAIReasoningEffort,
|
|
665
|
+
reasoning: input.reasoning,
|
|
592
666
|
surfaceIntegrationEnabled: input.surfaceIntegrationEnabled,
|
|
593
667
|
projectThreatModel: input.projectThreatModel,
|
|
594
668
|
planSubagentId: input.planSubagentId,
|
|
@@ -607,6 +681,7 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
607
681
|
emailAdapterFor: input.emailAdapterFor,
|
|
608
682
|
languageModelMiddleware: input.languageModelMiddleware,
|
|
609
683
|
usageRecorder: input.usageRecorder,
|
|
684
|
+
toolExecutionContext: input.toolExecutionContext,
|
|
610
685
|
streamIdFactory: input.streamIdFactory,
|
|
611
686
|
};
|
|
612
687
|
|
|
@@ -630,7 +705,9 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
630
705
|
let activeTools = (input.activeTools as string[]).filter(
|
|
631
706
|
passesEmailSmsGates,
|
|
632
707
|
);
|
|
633
|
-
if (input.mode === "
|
|
708
|
+
if (input.mode === "lance") {
|
|
709
|
+
activeTools = [...LANCE_CONFIG.tools];
|
|
710
|
+
} else if (input.mode === "plan") {
|
|
634
711
|
const planSet = new Set<string>(PLAN_MODE_TOOL_NAMES);
|
|
635
712
|
activeTools = activeTools.filter((t) => planSet.has(t));
|
|
636
713
|
} else if (input.mode === "fast-strike") {
|
|
@@ -658,6 +735,12 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
658
735
|
}
|
|
659
736
|
}
|
|
660
737
|
|
|
738
|
+
if (input.findingPolicy === "external") {
|
|
739
|
+
activeTools = activeTools.filter(
|
|
740
|
+
(name) => name !== "document_vulnerability",
|
|
741
|
+
);
|
|
742
|
+
}
|
|
743
|
+
|
|
661
744
|
activeTools = filterWorkspaceToolsForRun(
|
|
662
745
|
activeTools,
|
|
663
746
|
input.prompt,
|
|
@@ -666,10 +749,37 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
666
749
|
|
|
667
750
|
const builtinTools = createToolsForNames(toolCtx, activeTools);
|
|
668
751
|
|
|
669
|
-
|
|
670
|
-
|
|
752
|
+
const extraTools =
|
|
753
|
+
input.findingPolicy === "external" && input.extraTools
|
|
754
|
+
? Object.fromEntries(
|
|
755
|
+
Object.entries(input.extraTools).filter(
|
|
756
|
+
([name]) => name !== "document_vulnerability",
|
|
757
|
+
),
|
|
758
|
+
)
|
|
759
|
+
: input.extraTools;
|
|
760
|
+
let tools: ToolSet = extraTools
|
|
761
|
+
? { ...builtinTools, ...extraTools }
|
|
671
762
|
: { ...builtinTools };
|
|
672
763
|
|
|
764
|
+
if (this.lanceRuntime) {
|
|
765
|
+
const runtime = this.lanceRuntime;
|
|
766
|
+
tools = Object.fromEntries(
|
|
767
|
+
Object.entries(tools).map(([name, definition]) => [
|
|
768
|
+
name,
|
|
769
|
+
{
|
|
770
|
+
...definition,
|
|
771
|
+
execute: async (
|
|
772
|
+
args: unknown,
|
|
773
|
+
options: Parameters<NonNullable<typeof definition.execute>>[1],
|
|
774
|
+
) => {
|
|
775
|
+
runtime.checkAgent();
|
|
776
|
+
return definition.execute!(args, options);
|
|
777
|
+
},
|
|
778
|
+
},
|
|
779
|
+
]),
|
|
780
|
+
);
|
|
781
|
+
}
|
|
782
|
+
|
|
673
783
|
// Only approved calls may reach the execution journal.
|
|
674
784
|
if (input.toolExecutionRecorder) {
|
|
675
785
|
tools = wrapRecordedTools(tools, input.toolExecutionRecorder);
|
|
@@ -681,9 +791,15 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
681
791
|
tools,
|
|
682
792
|
input.approvalGate,
|
|
683
793
|
AGENT_PAUSE_TOOLS,
|
|
794
|
+
this.lanceRuntime?.signal,
|
|
684
795
|
);
|
|
685
796
|
}
|
|
686
797
|
|
|
798
|
+
if (this.lanceRuntime) {
|
|
799
|
+
tools = this.lanceRuntime.tools(tools);
|
|
800
|
+
activeTools = Object.keys(tools);
|
|
801
|
+
}
|
|
802
|
+
|
|
687
803
|
// -- Response schema → auto capture / stop / resolve ----------------------
|
|
688
804
|
if (input.responseSchema) {
|
|
689
805
|
tools = {
|
|
@@ -712,7 +828,7 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
712
828
|
Promise.race([sr.response, this._drainRejection]),
|
|
713
829
|
},
|
|
714
830
|
});
|
|
715
|
-
return customResolve(guarded);
|
|
831
|
+
return customResolve(guarded, result);
|
|
716
832
|
})
|
|
717
833
|
.then((resolved) => {
|
|
718
834
|
this._capturedResponse = resolved;
|
|
@@ -730,6 +846,10 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
730
846
|
};
|
|
731
847
|
}
|
|
732
848
|
|
|
849
|
+
if (input.toolExecutionContext) {
|
|
850
|
+
tools = wrapToolExecutionContext(tools, input.toolExecutionContext);
|
|
851
|
+
}
|
|
852
|
+
|
|
733
853
|
if (input.resolveResult) {
|
|
734
854
|
this.resolveResult = input.resolveResult;
|
|
735
855
|
} else if (input.responseSchema) {
|
|
@@ -759,16 +879,36 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
759
879
|
}
|
|
760
880
|
this.messagesPath = join(messagesDir, "messages.json");
|
|
761
881
|
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
882
|
+
const preparedContextRef = {
|
|
883
|
+
current: {
|
|
884
|
+
messages: input.messages
|
|
885
|
+
? [...input.messages]
|
|
886
|
+
: [
|
|
887
|
+
{
|
|
888
|
+
role: "user" as const,
|
|
889
|
+
content: [{ type: "text" as const, text: input.prompt }],
|
|
890
|
+
},
|
|
891
|
+
],
|
|
892
|
+
responseMessageOffset: 0,
|
|
893
|
+
},
|
|
894
|
+
};
|
|
895
|
+
const legacyMessages = (responseMessages: ModelMessage[]) => [
|
|
896
|
+
...preparedContextRef.current.messages,
|
|
897
|
+
...responseMessages.slice(
|
|
898
|
+
preparedContextRef.current.responseMessageOffset,
|
|
899
|
+
),
|
|
900
|
+
];
|
|
901
|
+
const persistedMessages = (messages: ModelMessage[]) => {
|
|
902
|
+
// Cache-marked system messages are transport context; the next turn
|
|
903
|
+
// supplies a fresh system prompt and must not replay saved copies.
|
|
904
|
+
let first = 0;
|
|
905
|
+
while (
|
|
906
|
+
messages[first]?.role === "system" &&
|
|
907
|
+
messages[first]?.providerOptions
|
|
908
|
+
) {
|
|
909
|
+
first++;
|
|
910
|
+
}
|
|
911
|
+
return first === 0 ? messages : messages.slice(first);
|
|
772
912
|
};
|
|
773
913
|
|
|
774
914
|
// Agent-local persistence: debounce, latest snapshot, and the
|
|
@@ -796,6 +936,7 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
796
936
|
input.system ??
|
|
797
937
|
buildBaseSystemPrompt({
|
|
798
938
|
sandboxMode: agentCwd === input.session.rootPath,
|
|
939
|
+
findingPolicy: input.findingPolicy,
|
|
799
940
|
});
|
|
800
941
|
const commandPlatform = resolveCommandPlatform(toolCtx);
|
|
801
942
|
const workspaceSection = buildSessionWorkspaceSection(
|
|
@@ -803,6 +944,7 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
803
944
|
agentCwd,
|
|
804
945
|
activeTools,
|
|
805
946
|
fileWorkspaceRoot,
|
|
947
|
+
input.findingPolicy,
|
|
806
948
|
);
|
|
807
949
|
// Bundled wordlist paths are host-local: advertise them only when
|
|
808
950
|
// commands execute locally.
|
|
@@ -824,9 +966,9 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
824
966
|
// Only agents whose tools can execute commands, touch files, or run
|
|
825
967
|
// PoCs get a runtime probe — for anyone else the facts are noise and the
|
|
826
968
|
// probe is a wasted subprocess.
|
|
827
|
-
this.probesRuntime =
|
|
828
|
-
|
|
829
|
-
|
|
969
|
+
this.probesRuntime =
|
|
970
|
+
input.mode !== "lance" &&
|
|
971
|
+
activeTools.some((name) => RUNTIME_CAPABLE_TOOL_NAMES.has(name));
|
|
830
972
|
|
|
831
973
|
// -- Init record + stream --------------------------------------------------
|
|
832
974
|
// Created by async initialization (streamReady) so the AI SDK telemetry
|
|
@@ -840,7 +982,10 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
840
982
|
// so the hash is stable across runs with identical prompt versions. No
|
|
841
983
|
// step record can precede this init line: steps only originate from the
|
|
842
984
|
// stream created below.
|
|
843
|
-
const baseWithFacts =
|
|
985
|
+
const baseWithFacts =
|
|
986
|
+
input.mode === "lance"
|
|
987
|
+
? LANCE_SYSTEM_PROMPT
|
|
988
|
+
: assembleBaseSystemPrompt(facts);
|
|
844
989
|
traceWriter.writeInit({
|
|
845
990
|
model: input.model,
|
|
846
991
|
systemPrompt: baseWithFacts,
|
|
@@ -848,11 +993,30 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
848
993
|
sessionId: input.session.id,
|
|
849
994
|
target: input.target,
|
|
850
995
|
});
|
|
996
|
+
this.lanceRuntime?.start();
|
|
997
|
+
const continuation = this.lanceRuntime?.continuationContext();
|
|
851
998
|
return streamResponse({
|
|
852
|
-
prompt:
|
|
853
|
-
|
|
999
|
+
prompt: continuation
|
|
1000
|
+
? `${input.prompt}\n\n${continuation}`
|
|
1001
|
+
: input.prompt,
|
|
1002
|
+
system:
|
|
1003
|
+
input.mode === "lance"
|
|
1004
|
+
? `${LANCE_SYSTEM_PROMPT}\nWorking directory (not automatically in scope): ${agentCwd}\nTarget: ${input.target ?? "Use the user's explicit target, or ask if missing"}\nDeadline: ${new Date(this.lanceRuntime!.softDeadlineAt).toISOString()}`
|
|
1005
|
+
: baseWithFacts + workspaceSection,
|
|
1006
|
+
primaryModelOnly: input.mode === "lance",
|
|
1007
|
+
_initialPrompt: input.mode === "lance" ? input.prompt : undefined,
|
|
1008
|
+
runContextCompaction: this.lanceRuntime?.runContextCompaction,
|
|
1009
|
+
getContinuationContext: this.lanceRuntime?.continuationContext,
|
|
1010
|
+
onInvalidToolCall: (name) => {
|
|
1011
|
+
if (this.lanceRuntime && !activeTools.includes(name)) {
|
|
1012
|
+
this.lanceRuntime.violation("forbidden_tool", name);
|
|
1013
|
+
}
|
|
1014
|
+
},
|
|
854
1015
|
model: input.model,
|
|
855
|
-
messages:
|
|
1016
|
+
messages:
|
|
1017
|
+
continuation && input.messages
|
|
1018
|
+
? [...input.messages, { role: "user", content: continuation }]
|
|
1019
|
+
: input.messages,
|
|
856
1020
|
tools,
|
|
857
1021
|
activeTools,
|
|
858
1022
|
stopWhen,
|
|
@@ -861,6 +1025,15 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
861
1025
|
usageRecorder: input.usageRecorder,
|
|
862
1026
|
contextRecorder: input.contextRecorder,
|
|
863
1027
|
inferenceRecorder: input.inferenceRecorder,
|
|
1028
|
+
onContextPrepared: (context) => {
|
|
1029
|
+
preparedContextRef.current = {
|
|
1030
|
+
messages: [...context.messages],
|
|
1031
|
+
responseMessageOffset: context.responseMessageOffset,
|
|
1032
|
+
};
|
|
1033
|
+
if (this.lanceRuntime) {
|
|
1034
|
+
this.writer.setLatest(persistedMessages(context.messages));
|
|
1035
|
+
}
|
|
1036
|
+
},
|
|
864
1037
|
// Per-subagent so the overflow tool-result dumps land next to this
|
|
865
1038
|
// agent's messages.json (`subagents/{id}/tool-results/`) and a host
|
|
866
1039
|
// can reclaim them when the subagent finishes, instead of piling up
|
|
@@ -880,16 +1053,11 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
880
1053
|
return;
|
|
881
1054
|
}
|
|
882
1055
|
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
const canonical = input.contextRecorder?.latest() ?? [
|
|
889
|
-
...initialMessagesRef.current,
|
|
890
|
-
...event.response.messages,
|
|
891
|
-
];
|
|
892
|
-
this.writer.setLatest(canonical);
|
|
1056
|
+
this.lanceRuntime?.stepFinished();
|
|
1057
|
+
const canonical =
|
|
1058
|
+
input.contextRecorder?.latest() ??
|
|
1059
|
+
legacyMessages(event.response.messages);
|
|
1060
|
+
this.writer.setLatest(persistedMessages(canonical));
|
|
893
1061
|
schedulePersist();
|
|
894
1062
|
traceWriter.recordStep(
|
|
895
1063
|
event.response.messages as ModelMessage[],
|
|
@@ -905,9 +1073,10 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
905
1073
|
await input.onStepFinish?.(event);
|
|
906
1074
|
},
|
|
907
1075
|
onSummarized: () => {
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
1076
|
+
preparedContextRef.current = {
|
|
1077
|
+
messages: [],
|
|
1078
|
+
responseMessageOffset: 0,
|
|
1079
|
+
};
|
|
911
1080
|
traceWriter.markSummarized();
|
|
912
1081
|
},
|
|
913
1082
|
onFinish: async (event) => {
|
|
@@ -915,11 +1084,11 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
915
1084
|
this.writer.cancelTimer();
|
|
916
1085
|
// Skip if the interrupted-step finalizer already wrote the abort snapshot.
|
|
917
1086
|
if (!this.writer.syntheticsPersisted) {
|
|
918
|
-
const finalMessages =
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
1087
|
+
const finalMessages = persistedMessages(
|
|
1088
|
+
input.contextRecorder?.latest() ??
|
|
1089
|
+
this.writer.latest ??
|
|
1090
|
+
legacyMessages(event.response.messages),
|
|
1091
|
+
);
|
|
923
1092
|
this.writer.setLatest(finalMessages);
|
|
924
1093
|
await this.writer.enqueueWrite(finalMessages).catch(() => {});
|
|
925
1094
|
}
|
|
@@ -931,6 +1100,7 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
931
1100
|
enableThinking: input.enableThinking,
|
|
932
1101
|
thinkingEffort: input.thinkingEffort,
|
|
933
1102
|
openAIReasoningEffort: input.openAIReasoningEffort,
|
|
1103
|
+
reasoning: input.reasoning,
|
|
934
1104
|
silent: true,
|
|
935
1105
|
});
|
|
936
1106
|
};
|
|
@@ -1039,6 +1209,21 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
1039
1209
|
* @returns The value produced by `resolveResult`, or `void` if none was provided.
|
|
1040
1210
|
*/
|
|
1041
1211
|
async consume(): Promise<TResult> {
|
|
1212
|
+
if (!this.lanceRuntime) return this.consumeRun();
|
|
1213
|
+
this.lanceRuntime.start();
|
|
1214
|
+
let error: unknown;
|
|
1215
|
+
try {
|
|
1216
|
+
return await this.consumeRun();
|
|
1217
|
+
} catch (cause) {
|
|
1218
|
+
error = cause;
|
|
1219
|
+
return undefined as TResult;
|
|
1220
|
+
} finally {
|
|
1221
|
+
this.lanceRuntime.finish(error);
|
|
1222
|
+
this.lanceRuntime.persist(this.session.rootPath, this.lanceModel!);
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
private async consumeRun(): Promise<TResult> {
|
|
1042
1227
|
const sid = this.subagentId;
|
|
1043
1228
|
const bus = this.eventBus;
|
|
1044
1229
|
|
|
@@ -1196,6 +1381,13 @@ export class OffensiveSecurityAgent<TResult = void> {
|
|
|
1196
1381
|
}
|
|
1197
1382
|
return result;
|
|
1198
1383
|
} catch (err) {
|
|
1384
|
+
if (this.lanceRuntime?.terminal) {
|
|
1385
|
+
span.setAttribute(
|
|
1386
|
+
"pensar.lance.outcome",
|
|
1387
|
+
this.lanceRuntime.metrics(this.lanceModel!).outcome,
|
|
1388
|
+
);
|
|
1389
|
+
throw err;
|
|
1390
|
+
}
|
|
1199
1391
|
// Record once, keep the cardinality low, preserve the original.
|
|
1200
1392
|
span.recordException(err as Error);
|
|
1201
1393
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
@@ -1550,6 +1742,7 @@ function wrapToolsWithApprovalGate(
|
|
|
1550
1742
|
tools: ToolSet,
|
|
1551
1743
|
gate: ApprovalGate,
|
|
1552
1744
|
exemptToolNames?: Set<string>,
|
|
1745
|
+
signal?: AbortSignal,
|
|
1553
1746
|
): ToolSet {
|
|
1554
1747
|
const wrapped: ToolSet = {};
|
|
1555
1748
|
|
|
@@ -1578,7 +1771,15 @@ function wrapToolsWithApprovalGate(
|
|
|
1578
1771
|
`tc_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
1579
1772
|
|
|
1580
1773
|
log.debug(`${name} (${toolCallId}): checking`);
|
|
1774
|
+
const cancelApproval = () => {
|
|
1775
|
+
for (const pending of gate.getPendingApprovals()) {
|
|
1776
|
+
if (pending.toolCallId === String(toolCallId))
|
|
1777
|
+
gate.deny(pending.id);
|
|
1778
|
+
}
|
|
1779
|
+
};
|
|
1581
1780
|
try {
|
|
1781
|
+
signal?.throwIfAborted();
|
|
1782
|
+
signal?.addEventListener("abort", cancelApproval, { once: true });
|
|
1582
1783
|
await gate.check(name, String(toolCallId), args);
|
|
1583
1784
|
} catch (err) {
|
|
1584
1785
|
if (err instanceof ApprovalDeniedError) {
|
|
@@ -1586,6 +1787,8 @@ function wrapToolsWithApprovalGate(
|
|
|
1586
1787
|
return { blocked: true, reason: "Denied by operator" };
|
|
1587
1788
|
}
|
|
1588
1789
|
throw err;
|
|
1790
|
+
} finally {
|
|
1791
|
+
signal?.removeEventListener("abort", cancelApproval);
|
|
1589
1792
|
}
|
|
1590
1793
|
log.debug(`${name} (${toolCallId}): approved, executing`);
|
|
1591
1794
|
|
|
@@ -70,3 +70,49 @@ describe("buildBaseSystemPrompt workspace management", () => {
|
|
|
70
70
|
);
|
|
71
71
|
});
|
|
72
72
|
});
|
|
73
|
+
|
|
74
|
+
describe("external finding policy prompts", () => {
|
|
75
|
+
const session = {
|
|
76
|
+
rootPath: "/tmp/apex-external-prompt",
|
|
77
|
+
findingsPath: "/tmp/apex-external-prompt/findings",
|
|
78
|
+
pocsPath: "/tmp/apex-external-prompt/pocs",
|
|
79
|
+
scratchpadPath: "/tmp/apex-external-prompt/scratchpad",
|
|
80
|
+
logsPath: "/tmp/apex-external-prompt/logs",
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
it("keeps exploration guidance without directing an unavailable finding tool", () => {
|
|
84
|
+
const prompt = buildBaseSystemPrompt({ findingPolicy: "external" });
|
|
85
|
+
expect(prompt).toContain("Source code analysis");
|
|
86
|
+
expect(prompt).toContain("caller grades them after the run");
|
|
87
|
+
expect(prompt).not.toContain("document_vulnerability");
|
|
88
|
+
expect(prompt).not.toContain("published PoCs");
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it.each([
|
|
92
|
+
[session.rootPath, undefined],
|
|
93
|
+
["/project", undefined],
|
|
94
|
+
["/project", "/tmp/apex-external-prompt/helpers"],
|
|
95
|
+
])("uses the caller's finding contract for cwd %s", (cwd, fileWorkspaceRoot) => {
|
|
96
|
+
const prompt = buildSessionWorkspaceSection(
|
|
97
|
+
session,
|
|
98
|
+
cwd,
|
|
99
|
+
["execute_command", "read_file"],
|
|
100
|
+
fileWorkspaceRoot,
|
|
101
|
+
"external",
|
|
102
|
+
);
|
|
103
|
+
expect(prompt).toContain("caller's output contract");
|
|
104
|
+
expect(prompt).not.toContain("document_vulnerability");
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("keeps source guidance policy-safe even when tool names are not supplied", () => {
|
|
108
|
+
const prompt = buildSessionWorkspaceSection(
|
|
109
|
+
{ ...session, config: { codebasePath: "/project" } },
|
|
110
|
+
"/project",
|
|
111
|
+
undefined,
|
|
112
|
+
undefined,
|
|
113
|
+
"external",
|
|
114
|
+
);
|
|
115
|
+
expect(prompt).toContain("Source Code Assessment");
|
|
116
|
+
expect(prompt).not.toContain("document_vulnerability");
|
|
117
|
+
});
|
|
118
|
+
});
|