@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
|
@@ -10,13 +10,11 @@ import {
|
|
|
10
10
|
} from "react";
|
|
11
11
|
import {
|
|
12
12
|
type AIModelProvider,
|
|
13
|
-
|
|
13
|
+
getReasoningCapabilities,
|
|
14
|
+
getReasoningChoices,
|
|
14
15
|
getRecentModels,
|
|
15
16
|
type ModelInfo,
|
|
16
|
-
|
|
17
|
-
modelSupportsOpenAIReasoning,
|
|
18
|
-
modelSupportsThinking,
|
|
19
|
-
type OpenAIReasoningEffort,
|
|
17
|
+
type ReasoningSetting,
|
|
20
18
|
} from "../../../core/ai";
|
|
21
19
|
import type { Config } from "../../../core/config/config";
|
|
22
20
|
import { getAvailableModels } from "../../../core/providers/utils";
|
|
@@ -84,8 +82,7 @@ type NavigationItem =
|
|
|
84
82
|
| { type: "model"; model: ModelInfo }
|
|
85
83
|
| { type: "recent-model"; model: ModelInfo }
|
|
86
84
|
| { type: "local-input"; field: LocalInputField }
|
|
87
|
-
| { type: "reasoning" }
|
|
88
|
-
| { type: "openai-reasoning" };
|
|
85
|
+
| { type: "reasoning" };
|
|
89
86
|
|
|
90
87
|
type LocalInputField = "url" | "model";
|
|
91
88
|
|
|
@@ -94,7 +91,6 @@ function getNavItemId(item: NavigationItem): string {
|
|
|
94
91
|
if (item.type === "model") return `model-${item.model.id}`;
|
|
95
92
|
if (item.type === "recent-model") return `recent-model-${item.model.id}`;
|
|
96
93
|
if (item.type === "reasoning") return "reasoning-toggle";
|
|
97
|
-
if (item.type === "openai-reasoning") return "openai-reasoning-effort";
|
|
98
94
|
return `local-input-${item.field}`;
|
|
99
95
|
}
|
|
100
96
|
|
|
@@ -107,10 +103,8 @@ export interface ModelPickerProps {
|
|
|
107
103
|
onConfigUpdate?: (update: Partial<Config>) => Promise<void>;
|
|
108
104
|
focused?: boolean;
|
|
109
105
|
isModelUserSelected?: boolean;
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
openAIReasoningEffort?: OpenAIReasoningEffort;
|
|
113
|
-
onOpenAIReasoningEffortChange?: (effort: OpenAIReasoningEffort) => void;
|
|
106
|
+
reasoning?: ReasoningSetting;
|
|
107
|
+
onReasoningChange?: (setting: ReasoningSetting) => void;
|
|
114
108
|
}
|
|
115
109
|
|
|
116
110
|
export function ModelPicker({
|
|
@@ -122,12 +116,19 @@ export function ModelPicker({
|
|
|
122
116
|
onConfigUpdate,
|
|
123
117
|
focused = true,
|
|
124
118
|
isModelUserSelected = false,
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
openAIReasoningEffort = "medium",
|
|
128
|
-
onOpenAIReasoningEffortChange,
|
|
119
|
+
reasoning = "default",
|
|
120
|
+
onReasoningChange,
|
|
129
121
|
}: ModelPickerProps) {
|
|
130
122
|
const { colors } = useTheme();
|
|
123
|
+
const reasoningCapabilities = useMemo(
|
|
124
|
+
() => getReasoningCapabilities(selectedModel.id, config?.customProviders),
|
|
125
|
+
[selectedModel.id, config?.customProviders],
|
|
126
|
+
);
|
|
127
|
+
const reasoningChoices = useMemo(
|
|
128
|
+
() => getReasoningChoices(reasoningCapabilities),
|
|
129
|
+
[reasoningCapabilities],
|
|
130
|
+
);
|
|
131
|
+
const reasoningAvailable = reasoningChoices.length > 0;
|
|
131
132
|
const scrollBoxRef = useRef<ScrollBoxRenderable | null>(null);
|
|
132
133
|
const [availableModels, setAvailableModels] = useState<ModelInfo[]>([]);
|
|
133
134
|
const [searchQuery, setSearchQuery] = useState("");
|
|
@@ -256,21 +257,8 @@ export function ModelPicker({
|
|
|
256
257
|
}
|
|
257
258
|
}
|
|
258
259
|
}
|
|
259
|
-
if (
|
|
260
|
-
!isSearching &&
|
|
261
|
-
onReasoningToggle &&
|
|
262
|
-
modelSupportsThinking(selectedModel.id) &&
|
|
263
|
-
!modelRequiresThinking(selectedModel.id)
|
|
264
|
-
) {
|
|
260
|
+
if (onReasoningChange && reasoningAvailable)
|
|
265
261
|
items.push({ type: "reasoning" });
|
|
266
|
-
}
|
|
267
|
-
if (
|
|
268
|
-
!isSearching &&
|
|
269
|
-
onOpenAIReasoningEffortChange &&
|
|
270
|
-
modelSupportsOpenAIReasoning(selectedModel.id)
|
|
271
|
-
) {
|
|
272
|
-
items.push({ type: "openai-reasoning" });
|
|
273
|
-
}
|
|
274
262
|
return items;
|
|
275
263
|
}, [
|
|
276
264
|
groupedModels,
|
|
@@ -278,9 +266,8 @@ export function ModelPicker({
|
|
|
278
266
|
recentModels,
|
|
279
267
|
isSearching,
|
|
280
268
|
expandedProviders,
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
selectedModel.id,
|
|
269
|
+
onReasoningChange,
|
|
270
|
+
reasoningAvailable,
|
|
284
271
|
]);
|
|
285
272
|
|
|
286
273
|
useEffect(() => {
|
|
@@ -329,31 +316,21 @@ export function ModelPicker({
|
|
|
329
316
|
commitLocalConfig(localUrl, localModelName);
|
|
330
317
|
}, [localUrl, localModelName, commitLocalConfig]);
|
|
331
318
|
|
|
332
|
-
const thinkingSupported = modelSupportsThinking(selectedModel.id);
|
|
333
|
-
const thinkingRequired = modelRequiresThinking(selectedModel.id);
|
|
334
|
-
const openAIReasoningSupported = modelSupportsOpenAIReasoning(
|
|
335
|
-
selectedModel.id,
|
|
336
|
-
);
|
|
337
|
-
const openAIReasoningEfforts = getOpenAIReasoningEfforts(selectedModel.id);
|
|
338
319
|
const isReasoningFocused =
|
|
339
320
|
navigationItems[focusedIndex]?.type === "reasoning";
|
|
340
|
-
const
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
onOpenAIReasoningEffortChange,
|
|
354
|
-
openAIReasoningEffort,
|
|
355
|
-
openAIReasoningEfforts,
|
|
356
|
-
]);
|
|
321
|
+
const cycleReasoning = useCallback(
|
|
322
|
+
(direction: -1 | 1 = 1) => {
|
|
323
|
+
if (!onReasoningChange || !reasoningAvailable) return;
|
|
324
|
+
const index = Math.max(0, reasoningChoices.indexOf(reasoning));
|
|
325
|
+
const next =
|
|
326
|
+
reasoningChoices[
|
|
327
|
+
(index + direction + reasoningChoices.length) %
|
|
328
|
+
reasoningChoices.length
|
|
329
|
+
];
|
|
330
|
+
if (next) onReasoningChange(next);
|
|
331
|
+
},
|
|
332
|
+
[onReasoningChange, reasoningAvailable, reasoningChoices, reasoning],
|
|
333
|
+
);
|
|
357
334
|
|
|
358
335
|
// Handle keyboard navigation (most keys disabled while editing local input)
|
|
359
336
|
const handleKeyboard = useCallback(
|
|
@@ -402,21 +379,19 @@ export function ModelPicker({
|
|
|
402
379
|
const currentItem = navigationItems[focusedIndex];
|
|
403
380
|
|
|
404
381
|
if (
|
|
405
|
-
key.name === "
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
382
|
+
(key.name === "left" || key.name === "right") &&
|
|
383
|
+
onReasoningChange &&
|
|
384
|
+
reasoningAvailable &&
|
|
385
|
+
!key.ctrl &&
|
|
386
|
+
!key.meta &&
|
|
387
|
+
!key.shift
|
|
409
388
|
) {
|
|
410
|
-
|
|
389
|
+
cycleReasoning(key.name === "left" ? -1 : 1);
|
|
411
390
|
return true;
|
|
412
391
|
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
onOpenAIReasoningEffortChange &&
|
|
417
|
-
openAIReasoningSupported
|
|
418
|
-
) {
|
|
419
|
-
cycleOpenAIReasoningEffort();
|
|
392
|
+
|
|
393
|
+
if (key.name === "space" && currentItem?.type === "reasoning") {
|
|
394
|
+
cycleReasoning();
|
|
420
395
|
return true;
|
|
421
396
|
}
|
|
422
397
|
|
|
@@ -430,9 +405,7 @@ export function ModelPicker({
|
|
|
430
405
|
}
|
|
431
406
|
|
|
432
407
|
if (currentItem.type === "reasoning") {
|
|
433
|
-
|
|
434
|
-
} else if (currentItem.type === "openai-reasoning") {
|
|
435
|
-
cycleOpenAIReasoningEffort();
|
|
408
|
+
cycleReasoning();
|
|
436
409
|
} else if (currentItem.type === "provider") {
|
|
437
410
|
const targetProvider = currentItem.provider;
|
|
438
411
|
setExpandedProviders((prev) => {
|
|
@@ -448,8 +421,8 @@ export function ModelPicker({
|
|
|
448
421
|
currentItem.type === "model" ||
|
|
449
422
|
currentItem.type === "recent-model"
|
|
450
423
|
) {
|
|
451
|
-
|
|
452
|
-
|
|
424
|
+
if (currentItem.model.id === selectedModel.id) onConfirm?.();
|
|
425
|
+
else onSelectModel(currentItem.model);
|
|
453
426
|
}
|
|
454
427
|
return true;
|
|
455
428
|
}
|
|
@@ -461,8 +434,7 @@ export function ModelPicker({
|
|
|
461
434
|
if (
|
|
462
435
|
!currentItem ||
|
|
463
436
|
currentItem.type === "recent-model" ||
|
|
464
|
-
currentItem.type === "reasoning"
|
|
465
|
-
currentItem.type === "openai-reasoning"
|
|
437
|
+
currentItem.type === "reasoning"
|
|
466
438
|
) {
|
|
467
439
|
return false;
|
|
468
440
|
}
|
|
@@ -502,15 +474,13 @@ export function ModelPicker({
|
|
|
502
474
|
navigationItems,
|
|
503
475
|
focusedIndex,
|
|
504
476
|
onSelectModel,
|
|
477
|
+
selectedModel.id,
|
|
505
478
|
onConfirm,
|
|
506
479
|
onCancel,
|
|
507
480
|
searchQuery,
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
onOpenAIReasoningEffortChange,
|
|
512
|
-
openAIReasoningSupported,
|
|
513
|
-
cycleOpenAIReasoningEffort,
|
|
481
|
+
onReasoningChange,
|
|
482
|
+
reasoningAvailable,
|
|
483
|
+
cycleReasoning,
|
|
514
484
|
isSearching,
|
|
515
485
|
],
|
|
516
486
|
);
|
|
@@ -862,36 +832,28 @@ export function ModelPicker({
|
|
|
862
832
|
})}
|
|
863
833
|
</scrollbox>
|
|
864
834
|
|
|
865
|
-
{
|
|
866
|
-
{!isSearching && onReasoningToggle && thinkingSupported && (
|
|
835
|
+
{onReasoningChange && reasoningAvailable && (
|
|
867
836
|
<box flexShrink={0} paddingTop={1}>
|
|
868
837
|
<PickerRow id="reasoning-toggle">
|
|
869
838
|
<text fg={isReasoningFocused ? colors.primary : colors.text}>
|
|
870
|
-
{
|
|
871
|
-
|
|
872
|
-
|
|
839
|
+
{isReasoningFocused ? "❯ " : " "}
|
|
840
|
+
{reasoningCapabilities.control === "effort"
|
|
841
|
+
? "Effort"
|
|
842
|
+
: "Extended Thinking"}
|
|
843
|
+
:{" "}
|
|
844
|
+
{reasoning === "default" &&
|
|
845
|
+
reasoningCapabilities.defaultEnabled === false
|
|
846
|
+
? "default (off)"
|
|
847
|
+
: reasoning === "default" && reasoningCapabilities.defaultEffort
|
|
848
|
+
? `default (${reasoningCapabilities.defaultEffort})`
|
|
849
|
+
: reasoning === "xhigh"
|
|
850
|
+
? "extra high"
|
|
851
|
+
: reasoning}
|
|
873
852
|
</text>
|
|
874
853
|
</PickerRow>
|
|
875
854
|
</box>
|
|
876
855
|
)}
|
|
877
856
|
|
|
878
|
-
{!isSearching &&
|
|
879
|
-
onOpenAIReasoningEffortChange &&
|
|
880
|
-
openAIReasoningSupported && (
|
|
881
|
-
<box flexShrink={0} paddingTop={1}>
|
|
882
|
-
<PickerRow id="openai-reasoning-effort">
|
|
883
|
-
<text
|
|
884
|
-
fg={isOpenAIReasoningFocused ? colors.primary : colors.text}
|
|
885
|
-
>
|
|
886
|
-
Reasoning Effort:{" "}
|
|
887
|
-
{openAIReasoningEffort === "xhigh"
|
|
888
|
-
? "extra high"
|
|
889
|
-
: openAIReasoningEffort}
|
|
890
|
-
</text>
|
|
891
|
-
</PickerRow>
|
|
892
|
-
</box>
|
|
893
|
-
)}
|
|
894
|
-
|
|
895
857
|
{/* Help text for inline editing only — general controls are in ModelPickerDialog */}
|
|
896
858
|
{editingLocalField && (
|
|
897
859
|
<box flexShrink={0}>
|
|
@@ -20,18 +20,14 @@ interface ModelPickerDialogProps {
|
|
|
20
20
|
export default function ModelPickerDialog({ onClose }: ModelPickerDialogProps) {
|
|
21
21
|
const { colors } = useTheme();
|
|
22
22
|
const config = useConfig();
|
|
23
|
-
const {
|
|
24
|
-
|
|
25
|
-
setModel,
|
|
26
|
-
isModelUserSelected,
|
|
27
|
-
reasoningEnabled,
|
|
28
|
-
setReasoningEnabled,
|
|
29
|
-
openAIReasoningEffort,
|
|
30
|
-
setOpenAIReasoningEffort,
|
|
31
|
-
} = useAgent();
|
|
23
|
+
const { model, setModel, isModelUserSelected, reasoning, setReasoning } =
|
|
24
|
+
useAgent();
|
|
32
25
|
|
|
33
26
|
const footerActions: FooterAction[] = [
|
|
34
|
-
{ key: "Enter", label: "confirm", variant: "primary" },
|
|
27
|
+
{ key: "Enter", label: "select / confirm", variant: "primary" },
|
|
28
|
+
...(reasoning !== undefined
|
|
29
|
+
? [{ key: "←/→", label: "change reasoning" }]
|
|
30
|
+
: []),
|
|
35
31
|
];
|
|
36
32
|
|
|
37
33
|
const title = (
|
|
@@ -63,10 +59,8 @@ export default function ModelPickerDialog({ onClose }: ModelPickerDialogProps) {
|
|
|
63
59
|
onConfigUpdate={config.update}
|
|
64
60
|
focused={true}
|
|
65
61
|
isModelUserSelected={isModelUserSelected}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
openAIReasoningEffort={openAIReasoningEffort}
|
|
69
|
-
onOpenAIReasoningEffortChange={setOpenAIReasoningEffort}
|
|
62
|
+
reasoning={reasoning}
|
|
63
|
+
onReasoningChange={setReasoning}
|
|
70
64
|
/>
|
|
71
65
|
</box>
|
|
72
66
|
</DialogLayout>
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { mock } from "bun:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { testRender } from "@opentui/react/test-utils";
|
|
6
|
+
import { act, useState } from "react";
|
|
7
|
+
import { getModelInfo, type ReasoningSetting } from "../../../../core/ai";
|
|
8
|
+
import type { Config } from "../../../../core/config/config";
|
|
9
|
+
|
|
10
|
+
const scenario = process.argv[2];
|
|
11
|
+
const selected = getModelInfo(
|
|
12
|
+
scenario === "toggle"
|
|
13
|
+
? "claude-sonnet-4-5"
|
|
14
|
+
: scenario === "unknown"
|
|
15
|
+
? "gpt-4o"
|
|
16
|
+
: "claude-opus-5-5",
|
|
17
|
+
);
|
|
18
|
+
const config = {
|
|
19
|
+
anthropicAPIKey: "test",
|
|
20
|
+
openAiAPIKey: "test",
|
|
21
|
+
responsibleUseAccepted: true,
|
|
22
|
+
} as Config;
|
|
23
|
+
mock.module(
|
|
24
|
+
join(import.meta.dirname, "../../../../core/providers/utils.ts"),
|
|
25
|
+
() => ({ getAvailableModels: () => [selected] }),
|
|
26
|
+
);
|
|
27
|
+
mock.module(join(import.meta.dirname, "../../../context/config.tsx"), () => ({
|
|
28
|
+
useConfig: () => ({ data: config, update: async () => {} }),
|
|
29
|
+
}));
|
|
30
|
+
const { ModelPicker } = await import("../ModelPicker");
|
|
31
|
+
const { ThemeProvider, registerBuiltinThemes } = await import("../../../theme");
|
|
32
|
+
registerBuiltinThemes();
|
|
33
|
+
const changed: ReasoningSetting[] = [];
|
|
34
|
+
function Harness() {
|
|
35
|
+
const [reasoning, setReasoning] = useState<ReasoningSetting>("default");
|
|
36
|
+
return (
|
|
37
|
+
<ThemeProvider>
|
|
38
|
+
<ModelPicker
|
|
39
|
+
config={config}
|
|
40
|
+
selectedModel={selected}
|
|
41
|
+
onSelectModel={() => {}}
|
|
42
|
+
reasoning={reasoning}
|
|
43
|
+
onReasoningChange={(next) => {
|
|
44
|
+
changed.push(next);
|
|
45
|
+
setReasoning(next);
|
|
46
|
+
}}
|
|
47
|
+
/>
|
|
48
|
+
</ThemeProvider>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
const setup = await testRender(<Harness />, {
|
|
52
|
+
width: scenario === "compact" ? 60 : 100,
|
|
53
|
+
height: scenario === "compact" ? 18 : 28,
|
|
54
|
+
exitOnCtrlC: false,
|
|
55
|
+
});
|
|
56
|
+
async function frame() {
|
|
57
|
+
for (let i = 0; i < 3; i++) await act(async () => {});
|
|
58
|
+
await act(setup.renderOnce);
|
|
59
|
+
return setup.captureCharFrame();
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
const initial = await frame();
|
|
63
|
+
assert.ok(initial.includes(selected.name), initial);
|
|
64
|
+
if (scenario === "unknown") {
|
|
65
|
+
assert.ok(!initial.includes("Effort:"), initial);
|
|
66
|
+
assert.ok(!initial.includes("Extended Thinking:"), initial);
|
|
67
|
+
await act(async () => setup.mockInput.pressKey("ARROW_LEFT"));
|
|
68
|
+
await frame();
|
|
69
|
+
await act(async () => setup.mockInput.pressKey("ARROW_RIGHT"));
|
|
70
|
+
await frame();
|
|
71
|
+
assert.deepEqual(changed, []);
|
|
72
|
+
} else {
|
|
73
|
+
assert.ok(
|
|
74
|
+
initial.includes(
|
|
75
|
+
scenario === "toggle"
|
|
76
|
+
? "Extended Thinking: default"
|
|
77
|
+
: "Effort: default",
|
|
78
|
+
),
|
|
79
|
+
initial,
|
|
80
|
+
);
|
|
81
|
+
assert.ok(
|
|
82
|
+
!initial.includes(
|
|
83
|
+
scenario === "toggle" ? "Effort:" : "Extended Thinking:",
|
|
84
|
+
),
|
|
85
|
+
initial,
|
|
86
|
+
);
|
|
87
|
+
const firstChoice = scenario === "toggle" ? "enabled" : "low";
|
|
88
|
+
const lastChoice = scenario === "toggle" ? "disabled" : "max";
|
|
89
|
+
await act(async () => setup.mockInput.pressKey("ARROW_RIGHT"));
|
|
90
|
+
const next = await frame();
|
|
91
|
+
assert.deepEqual(changed, [firstChoice]);
|
|
92
|
+
assert.ok(
|
|
93
|
+
next.includes(
|
|
94
|
+
scenario === "toggle" ? "Extended Thinking: enabled" : "Effort: low",
|
|
95
|
+
),
|
|
96
|
+
next,
|
|
97
|
+
);
|
|
98
|
+
await act(async () => setup.mockInput.pressKey("ARROW_LEFT"));
|
|
99
|
+
await frame();
|
|
100
|
+
await act(async () => setup.mockInput.pressKey("ARROW_LEFT"));
|
|
101
|
+
await frame();
|
|
102
|
+
await act(async () => setup.mockInput.pressKey("ARROW_RIGHT"));
|
|
103
|
+
await frame();
|
|
104
|
+
assert.deepEqual(changed, [firstChoice, "default", lastChoice, "default"]);
|
|
105
|
+
|
|
106
|
+
await act(async () => setup.mockInput.pressKey("ARROW_UP"));
|
|
107
|
+
await frame();
|
|
108
|
+
await act(async () => setup.mockInput.pressKey("RETURN"));
|
|
109
|
+
const collapsed = await frame();
|
|
110
|
+
assert.ok(!collapsed.includes(selected.name), collapsed);
|
|
111
|
+
await act(async () => setup.mockInput.pressKey("RETURN"));
|
|
112
|
+
const expanded = await frame();
|
|
113
|
+
assert.ok(expanded.includes(selected.name), expanded);
|
|
114
|
+
|
|
115
|
+
await act(async () => setup.mockInput.typeText("claude "));
|
|
116
|
+
const search = await frame();
|
|
117
|
+
assert.ok(search.includes("Search claude"), search);
|
|
118
|
+
assert.ok(search.includes("Results (1)"), search);
|
|
119
|
+
await act(async () => setup.mockInput.pressKey("ARROW_LEFT"));
|
|
120
|
+
await frame();
|
|
121
|
+
await act(async () => setup.mockInput.typeText("s"));
|
|
122
|
+
const afterArrows = await frame();
|
|
123
|
+
assert.ok(afterArrows.includes("Search claude s"), afterArrows);
|
|
124
|
+
await act(async () => setup.mockInput.pressKey("ARROW_RIGHT"));
|
|
125
|
+
await frame();
|
|
126
|
+
assert.deepEqual(changed, [
|
|
127
|
+
firstChoice,
|
|
128
|
+
"default",
|
|
129
|
+
lastChoice,
|
|
130
|
+
"default",
|
|
131
|
+
lastChoice,
|
|
132
|
+
"default",
|
|
133
|
+
]);
|
|
134
|
+
|
|
135
|
+
await act(async () => setup.mockInput.pressKey("ARROW_UP"));
|
|
136
|
+
const focused = await frame();
|
|
137
|
+
assert.ok(
|
|
138
|
+
focused.includes(
|
|
139
|
+
scenario === "toggle" ? "❯ Extended Thinking:" : "❯ Effort:",
|
|
140
|
+
),
|
|
141
|
+
focused,
|
|
142
|
+
);
|
|
143
|
+
await act(async () => setup.mockInput.pressKey(" "));
|
|
144
|
+
const updated = await frame();
|
|
145
|
+
assert.equal(changed.at(-1), firstChoice);
|
|
146
|
+
assert.ok(
|
|
147
|
+
updated.includes(
|
|
148
|
+
scenario === "toggle" ? "Extended Thinking: enabled" : "Effort: low",
|
|
149
|
+
),
|
|
150
|
+
updated,
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
if (process.env.APEX_TEST_FRAME_DIR) {
|
|
154
|
+
mkdirSync(process.env.APEX_TEST_FRAME_DIR, { recursive: true });
|
|
155
|
+
writeFileSync(
|
|
156
|
+
join(process.env.APEX_TEST_FRAME_DIR, `${scenario}.txt`),
|
|
157
|
+
await frame(),
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
} finally {
|
|
161
|
+
await act(async () => setup.renderer.destroy());
|
|
162
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { expect, it } from "vitest";
|
|
4
|
+
|
|
5
|
+
for (const scenario of ["effort", "toggle", "unknown", "compact"] as const) {
|
|
6
|
+
it(`renders and operates the ${scenario} reasoning control`, () => {
|
|
7
|
+
const result = spawnSync(
|
|
8
|
+
"bun",
|
|
9
|
+
[join(import.meta.dirname, "__tests__/reasoning-control.tsx"), scenario],
|
|
10
|
+
{ encoding: "utf8", timeout: 30000 },
|
|
11
|
+
);
|
|
12
|
+
expect(result.error).toBeUndefined();
|
|
13
|
+
expect(result.status, result.stderr).toBe(0);
|
|
14
|
+
});
|
|
15
|
+
}
|