onbuzz 3.4.0 → 3.6.2
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/package.json +1 -1
- package/scripts/bump-version.js +116 -0
- package/src/__test-utils__/fixtures/malformedJson.js +31 -0
- package/src/__test-utils__/globalSetup.js +9 -0
- package/src/__test-utils__/globalTeardown.js +12 -0
- package/src/__test-utils__/mockFactories.js +101 -0
- package/src/analyzers/__tests__/CSSAnalyzer.test.js +41 -0
- package/src/analyzers/__tests__/ConfigValidator.test.js +362 -0
- package/src/analyzers/__tests__/ESLintAnalyzer.test.js +271 -0
- package/src/analyzers/__tests__/JavaScriptAnalyzer.test.js +40 -0
- package/src/analyzers/__tests__/PrettierFormatter.test.js +197 -0
- package/src/analyzers/__tests__/PythonAnalyzer.test.js +208 -0
- package/src/analyzers/__tests__/SecurityAnalyzer.test.js +303 -0
- package/src/analyzers/__tests__/SparrowAnalyzer.test.js +270 -0
- package/src/analyzers/__tests__/TypeScriptAnalyzer.test.js +187 -0
- package/src/core/__tests__/agentPool.test.js +601 -0
- package/src/core/__tests__/agentScheduler.test.js +576 -0
- package/src/core/__tests__/contextManager.test.js +252 -0
- package/src/core/__tests__/flowExecutor.test.js +262 -0
- package/src/core/__tests__/messageProcessor.test.js +627 -0
- package/src/core/__tests__/orchestrator.test.js +257 -0
- package/src/core/__tests__/stateManager.test.js +375 -0
- package/src/core/agentPool.js +26 -4
- package/src/core/agentScheduler.js +79 -21
- package/src/core/messageProcessor.js +110 -2
- package/src/index.js +27 -11
- package/src/interfaces/__tests__/imageServing.test.js +228 -0
- package/src/interfaces/terminal/__tests__/smoke/imports.test.js +3 -5
- package/src/interfaces/webServer.js +97 -13
- package/src/services/__tests__/agentActivityService.test.js +319 -0
- package/src/services/__tests__/apiKeyManager.test.js +206 -0
- package/src/services/__tests__/benchmarkService.test.js +184 -0
- package/src/services/__tests__/budgetService.test.js +211 -0
- package/src/services/__tests__/contextInjectionService.test.js +205 -0
- package/src/services/__tests__/conversationCompactionService.test.js +280 -0
- package/src/services/__tests__/credentialVault.test.js +469 -0
- package/src/services/__tests__/errorHandler.test.js +314 -0
- package/src/services/__tests__/fileAttachmentService.test.js +278 -0
- package/src/services/__tests__/flowContextService.test.js +199 -0
- package/src/services/__tests__/memoryService.test.js +450 -0
- package/src/services/__tests__/modelRouterService.test.js +388 -0
- package/src/services/__tests__/modelsService.test.js +261 -0
- package/src/services/__tests__/portRegistry.test.js +123 -0
- package/src/services/__tests__/projectDetector.test.js +34 -0
- package/src/services/__tests__/promptService.test.js +242 -0
- package/src/services/__tests__/qualityInspector.test.js +97 -0
- package/src/services/__tests__/scheduleService.test.js +308 -0
- package/src/services/__tests__/serviceRegistry.test.js +74 -0
- package/src/services/__tests__/skillsService.test.js +402 -0
- package/src/services/__tests__/tokenCountingService.test.js +48 -0
- package/src/services/conversationCompactionService.js +2 -2
- package/src/services/visualEditorServer.js +26 -7
- package/src/tools/__tests__/agentCommunicationTool.test.js +500 -0
- package/src/tools/__tests__/agentDelayTool.test.js +342 -0
- package/src/tools/__tests__/asyncToolManager.test.js +344 -0
- package/src/tools/__tests__/baseTool.test.js +420 -0
- package/src/tools/__tests__/codeMapTool.test.js +348 -0
- package/src/tools/__tests__/fileContentReplaceTool.test.js +309 -0
- package/src/tools/__tests__/fileTreeTool.test.js +274 -0
- package/src/tools/__tests__/filesystemTool.test.js +717 -0
- package/src/tools/__tests__/helpTool.test.js +204 -0
- package/src/tools/__tests__/jobDoneTool.test.js +296 -0
- package/src/tools/__tests__/memoryTool.test.js +297 -0
- package/src/tools/__tests__/seekTool.test.js +282 -0
- package/src/tools/__tests__/skillsTool.test.js +226 -0
- package/src/tools/__tests__/staticAnalysisTool.test.js +509 -0
- package/src/tools/__tests__/taskManagerTool.test.js +725 -0
- package/src/tools/__tests__/terminalTool.test.js +384 -0
- package/src/tools/__tests__/userPromptTool.test.js +297 -0
- package/src/tools/__tests__/webTool.e2e.test.js +25 -11
- package/src/tools/imageTool.js +41 -5
- package/src/tools/webTool.js +161 -48
- package/src/types/__tests__/agent.test.js +499 -0
- package/src/types/__tests__/contextReference.test.js +606 -0
- package/src/types/__tests__/conversation.test.js +555 -0
- package/src/types/__tests__/toolCommand.test.js +584 -0
- package/src/types/contextReference.js +1 -1
- package/src/utilities/__tests__/attachmentValidator.test.js +80 -0
- package/src/utilities/__tests__/configManager.test.js +397 -0
- package/src/utilities/__tests__/constants.test.js +49 -0
- package/src/utilities/__tests__/directoryAccessManager.test.js +388 -0
- package/src/utilities/__tests__/fileProcessor.test.js +104 -0
- package/src/utilities/__tests__/jsonRepair.test.js +104 -0
- package/src/utilities/__tests__/logger.test.js +129 -0
- package/src/utilities/__tests__/platformUtils.test.js +87 -0
- package/src/utilities/__tests__/structuredFileValidator.test.js +263 -0
- package/src/utilities/__tests__/tagParser.test.js +887 -0
- package/src/utilities/__tests__/toolConstants.test.js +94 -0
- package/src/utilities/tagParser.js +2 -2
- package/web-ui/build/index.html +2 -2
- package/web-ui/build/static/1c-8PZzOTzp.js +1 -0
- package/web-ui/build/static/abap-Bcx_Au1F.js +1 -0
- package/web-ui/build/static/abnf-BKTLqpWA.js +1 -0
- package/web-ui/build/static/abnf-J05BAvJt.js +1 -0
- package/web-ui/build/static/accesslog-Cp8_lqVY.js +1 -0
- package/web-ui/build/static/actionscript-BK0UaMrm.js +1 -0
- package/web-ui/build/static/actionscript-CyqZUddh.js +1 -0
- package/web-ui/build/static/ada-BNirS6Nr.js +1 -0
- package/web-ui/build/static/ada-BSFWcT1O.js +1 -0
- package/web-ui/build/static/agda-D0NJDJg7.js +1 -0
- package/web-ui/build/static/al-rWARKtwb.js +1 -0
- package/web-ui/build/static/angelscript-fCehtOYk.js +1 -0
- package/web-ui/build/static/antlr4-Dn9jrnZN.js +1 -0
- package/web-ui/build/static/apache-DaQCsvNW.js +1 -0
- package/web-ui/build/static/apacheconf-dY4i0Xvz.js +1 -0
- package/web-ui/build/static/apex-vhS4SI46.js +1 -0
- package/web-ui/build/static/apl-CKRkxH90.js +1 -0
- package/web-ui/build/static/applescript-CWmpQIEB.js +1 -0
- package/web-ui/build/static/applescript-DBaX7Uqo.js +1 -0
- package/web-ui/build/static/aql-8s41lrIa.js +1 -0
- package/web-ui/build/static/arcade-w2_RhAcq.js +1 -0
- package/web-ui/build/static/arduino-I7BtZTu6.js +1 -0
- package/web-ui/build/static/arduino-h2LZErKQ.js +1 -0
- package/web-ui/build/static/arff-C543-5a1.js +1 -0
- package/web-ui/build/static/armasm-DyZdFOzz.js +1 -0
- package/web-ui/build/static/asciidoc-ZzENlACu.js +1 -0
- package/web-ui/build/static/asciidoc-_j9x9bUz.js +1 -0
- package/web-ui/build/static/asm6502-CsNsmBfq.js +1 -0
- package/web-ui/build/static/asmatmel-CkIVf_tD.js +1 -0
- package/web-ui/build/static/aspectj-C6AQLme_.js +1 -0
- package/web-ui/build/static/aspnet-5AkdiVyL.js +1 -0
- package/web-ui/build/static/autohotkey-BRZVABiS.js +1 -0
- package/web-ui/build/static/autohotkey-DVTmfk_f.js +1 -0
- package/web-ui/build/static/autoit-3UEcWu5a.js +1 -0
- package/web-ui/build/static/autoit-BDByIKSH.js +1 -0
- package/web-ui/build/static/avisynth-BHc4uUkP.js +1 -0
- package/web-ui/build/static/avrasm-BAPq8_aI.js +1 -0
- package/web-ui/build/static/avro-idl-BKEBYUtv.js +1 -0
- package/web-ui/build/static/awk-CBCkArRT.js +1 -0
- package/web-ui/build/static/axapta-DlOgnXSZ.js +1 -0
- package/web-ui/build/static/bash-C6Brp5OE.js +1 -0
- package/web-ui/build/static/bash-DkEO7JRq.js +1 -0
- package/web-ui/build/static/basic-DG6TYB0R.js +1 -0
- package/web-ui/build/static/basic-DRPcNfAn.js +1 -0
- package/web-ui/build/static/batch-DdjZ5KC1.js +1 -0
- package/web-ui/build/static/bbcode-DCXEEs2w.js +1 -0
- package/web-ui/build/static/bicep-CpLhfOwt.js +1 -0
- package/web-ui/build/static/birb-DNWkqgQm.js +1 -0
- package/web-ui/build/static/bison-DwxbQHJ9.js +1 -0
- package/web-ui/build/static/bnf-Cgnt7npj.js +1 -0
- package/web-ui/build/static/bnf-DSTq_eu9.js +1 -0
- package/web-ui/build/static/brainfuck-Bi8mGutW.js +1 -0
- package/web-ui/build/static/brainfuck-DOWfqVtR.js +1 -0
- package/web-ui/build/static/brightscript-D95pbP-v.js +1 -0
- package/web-ui/build/static/bro-BrDVwXeg.js +1 -0
- package/web-ui/build/static/bsl-BMoXI84g.js +1 -0
- package/web-ui/build/static/c-CKH4C7-Z.js +1 -0
- package/web-ui/build/static/c-Z0txyaeJ.js +1 -0
- package/web-ui/build/static/c-like-Dzm9dMmR.js +1 -0
- package/web-ui/build/static/cal-DoyAwiUt.js +1 -0
- package/web-ui/build/static/capnproto-DeIi9LOH.js +1 -0
- package/web-ui/build/static/ceylon-Coim6DIe.js +1 -0
- package/web-ui/build/static/cfscript-CwsndC-j.js +1 -0
- package/web-ui/build/static/chaiscript-D6Aq-PSv.js +1 -0
- package/web-ui/build/static/cil-vi56VRk_.js +1 -0
- package/web-ui/build/static/clean-BfpKrTdp.js +1 -0
- package/web-ui/build/static/clojure-DUtl6BaB.js +1 -0
- package/web-ui/build/static/clojure-DXJHtDlY.js +1 -0
- package/web-ui/build/static/clojure-repl-BxwP5C3g.js +1 -0
- package/web-ui/build/static/cmake-C9_VZ1vH.js +1 -0
- package/web-ui/build/static/cmake-dplO-PGD.js +1 -0
- package/web-ui/build/static/cobol-DsZhu02V.js +1 -0
- package/web-ui/build/static/coffeescript-Cw9jtGNP.js +1 -0
- package/web-ui/build/static/coffeescript-DvDt4T2l.js +1 -0
- package/web-ui/build/static/concurnas-Bzc_Dcdd.js +1 -0
- package/web-ui/build/static/coq-Cv-5BqGo.js +1 -0
- package/web-ui/build/static/coq-DWFe2ssK.js +1 -0
- package/web-ui/build/static/cos-D6Lc6Cah.js +1 -0
- package/web-ui/build/static/cpp-BFmLjd76.js +1 -0
- package/web-ui/build/static/cpp-DVQgbHji.js +1 -0
- package/web-ui/build/static/crmsh-Cqveth9p.js +1 -0
- package/web-ui/build/static/crystal-0syYaH4Y.js +1 -0
- package/web-ui/build/static/crystal-Noptp-kr.js +1 -0
- package/web-ui/build/static/csharp-B799cFMH.js +1 -0
- package/web-ui/build/static/csharp-_HlvMZzJ.js +1 -0
- package/web-ui/build/static/cshtml-CnwOXlhP.js +1 -0
- package/web-ui/build/static/csp-1ffxIG_-.js +1 -0
- package/web-ui/build/static/csp-Bws60bPu.js +1 -0
- package/web-ui/build/static/css-BGdwXzpm.js +1 -0
- package/web-ui/build/static/css-extras-DZCECiOa.js +1 -0
- package/web-ui/build/static/csv-FMFGT0T4.js +1 -0
- package/web-ui/build/static/cypher-DnXoEwRp.js +1 -0
- package/web-ui/build/static/d-CBrts1xB.js +1 -0
- package/web-ui/build/static/d-qrJLxk2L.js +1 -0
- package/web-ui/build/static/dart-3vBSXJVV.js +1 -0
- package/web-ui/build/static/dart-Cj5b7BV9.js +1 -0
- package/web-ui/build/static/dataweave-BuFf63rk.js +1 -0
- package/web-ui/build/static/dax-Cl-se1JI.js +1 -0
- package/web-ui/build/static/delphi-CLkRb26y.js +1 -0
- package/web-ui/build/static/dhall--TIL2Z--.js +1 -0
- package/web-ui/build/static/diff-Bn-XL2om.js +1 -0
- package/web-ui/build/static/diff-BsTwly4w.js +1 -0
- package/web-ui/build/static/django-BfRtHnTS.js +1 -0
- package/web-ui/build/static/django-Dm9O4e3A.js +1 -0
- package/web-ui/build/static/dns-BIVEp3uD.js +1 -0
- package/web-ui/build/static/dns-zone-file-CO7LnOdh.js +1 -0
- package/web-ui/build/static/docker-BhwMip1R.js +1 -0
- package/web-ui/build/static/dockerfile-8Tjw9_jF.js +1 -0
- package/web-ui/build/static/dos-CRMiAo46.js +1 -0
- package/web-ui/build/static/dot-DPpW7LrJ.js +1 -0
- package/web-ui/build/static/dsconfig-D0zbYilI.js +1 -0
- package/web-ui/build/static/dts-C_-yqWEL.js +1 -0
- package/web-ui/build/static/dust-CucJgqnE.js +1 -0
- package/web-ui/build/static/ebnf-CCHK0H6j.js +1 -0
- package/web-ui/build/static/ebnf-CDdAcveH.js +1 -0
- package/web-ui/build/static/editorconfig-f-5b95UM.js +1 -0
- package/web-ui/build/static/eiffel-MmghFce7.js +1 -0
- package/web-ui/build/static/ejs-CPMN4-jk.js +1 -0
- package/web-ui/build/static/elixir-57Ldyw8h.js +1 -0
- package/web-ui/build/static/elixir-DTxnmhIt.js +1 -0
- package/web-ui/build/static/elm-ClV9zQoT.js +1 -0
- package/web-ui/build/static/elm-pX-i6o7U.js +1 -0
- package/web-ui/build/static/erb-BPeO9smT.js +1 -0
- package/web-ui/build/static/erb-BnZQ4STz.js +1 -0
- package/web-ui/build/static/erlang-DPtI7VK_.js +1 -0
- package/web-ui/build/static/erlang-KG5mg5wN.js +1 -0
- package/web-ui/build/static/erlang-repl-BqPVXZ3Y.js +1 -0
- package/web-ui/build/static/etlua-BRc0Qbbs.js +1 -0
- package/web-ui/build/static/excel-BAlZ9Hkj.js +1 -0
- package/web-ui/build/static/excel-formula-BOW-bnHh.js +1 -0
- package/web-ui/build/static/factor-DCCsCpGM.js +1 -0
- package/web-ui/build/static/false-CnqnCzBU.js +1 -0
- package/web-ui/build/static/firestore-security-rules-DtkQ3uEq.js +1 -0
- package/web-ui/build/static/fix-CfPjl4Xr.js +1 -0
- package/web-ui/build/static/flix-BCA3BceS.js +1 -0
- package/web-ui/build/static/flow-C-5ewqYW.js +1 -0
- package/web-ui/build/static/fortran-CfDtl8An.js +1 -0
- package/web-ui/build/static/fortran-DQ_knNPt.js +1 -0
- package/web-ui/build/static/fsharp-CcVQ3IqX.js +1 -0
- package/web-ui/build/static/fsharp-olQ6ojCa.js +1 -0
- package/web-ui/build/static/ftl-DIWHDyWt.js +1 -0
- package/web-ui/build/static/gams-_NVFTSj5.js +1 -0
- package/web-ui/build/static/gap-DIG5TV2b.js +1 -0
- package/web-ui/build/static/gauss-C8rjPjTG.js +1 -0
- package/web-ui/build/static/gcode-8wJu4gcL.js +1 -0
- package/web-ui/build/static/gcode-DjHf417I.js +1 -0
- package/web-ui/build/static/gdscript-BZdmRCYu.js +1 -0
- package/web-ui/build/static/gedcom-BVFJ8C_Q.js +1 -0
- package/web-ui/build/static/gherkin-7NQkoaub.js +1 -0
- package/web-ui/build/static/gherkin-bSpNbJ48.js +1 -0
- package/web-ui/build/static/git-BRY_UXsc.js +1 -0
- package/web-ui/build/static/glsl-Ck6ShGRC.js +1 -0
- package/web-ui/build/static/glsl-jwCJ0Pmg.js +1 -0
- package/web-ui/build/static/gml-BAjG4Kr2.js +1 -0
- package/web-ui/build/static/gml-BnhKb5Da.js +1 -0
- package/web-ui/build/static/gn-Dux09iX8.js +1 -0
- package/web-ui/build/static/go-BOG-9Cqk.js +1 -0
- package/web-ui/build/static/go-BWZB_3b5.js +1 -0
- package/web-ui/build/static/go-module-BVLW7KBE.js +1 -0
- package/web-ui/build/static/golo-BD_SOfwL.js +1 -0
- package/web-ui/build/static/gradle-zSadWOD2.js +1 -0
- package/web-ui/build/static/graphql-BQlyj78B.js +1 -0
- package/web-ui/build/static/groovy-BurRMqQS.js +1 -0
- package/web-ui/build/static/groovy-SP58zwlE.js +1 -0
- package/web-ui/build/static/haml-eZ5ah5KY.js +1 -0
- package/web-ui/build/static/haml-lFC47IZb.js +1 -0
- package/web-ui/build/static/handlebars-B4UXrB-Q.js +1 -0
- package/web-ui/build/static/handlebars-CQ-Q5HnC.js +1 -0
- package/web-ui/build/static/haskell-AQrRyTSy.js +1 -0
- package/web-ui/build/static/haskell-BZTSbaB_.js +1 -0
- package/web-ui/build/static/haxe-5l1X6ESp.js +1 -0
- package/web-ui/build/static/haxe-DBn90muG.js +1 -0
- package/web-ui/build/static/hcl-CnMewPLM.js +1 -0
- package/web-ui/build/static/hlsl-RAtuBzr5.js +1 -0
- package/web-ui/build/static/hoon-CSqRU_4M.js +1 -0
- package/web-ui/build/static/hpkp-_gNbXcHt.js +1 -0
- package/web-ui/build/static/hsp-DY1V4au3.js +1 -0
- package/web-ui/build/static/hsts-j5z2jJo8.js +1 -0
- package/web-ui/build/static/htmlbars-C5EHvatr.js +1 -0
- package/web-ui/build/static/http-DgWgQrZh.js +1 -0
- package/web-ui/build/static/http-DphJL0q2.js +1 -0
- package/web-ui/build/static/hy-DnBqjPsB.js +1 -0
- package/web-ui/build/static/ichigojam-DeiCOKyF.js +1 -0
- package/web-ui/build/static/icon-CWANFWY5.js +1 -0
- package/web-ui/build/static/icu-message-format-C7w3vpgC.js +1 -0
- package/web-ui/build/static/idris-BeD8eULz.js +1 -0
- package/web-ui/build/static/iecst-BIznHXqY.js +1 -0
- package/web-ui/build/static/ignore-BcFgcNaS.js +1 -0
- package/web-ui/build/static/index-D8uVofpo.js +13 -0
- package/web-ui/build/static/index-DPFadqM6.css +1 -0
- package/web-ui/build/static/index-SkOgWEAU.js +1 -0
- package/web-ui/build/static/index-Vd3WlhtC.js +747 -0
- package/web-ui/build/static/inform7-CkQD_jz-.js +1 -0
- package/web-ui/build/static/inform7-phQiuDty.js +1 -0
- package/web-ui/build/static/ini-Bw_QAbzV.js +1 -0
- package/web-ui/build/static/ini-CB8ZxX7y.js +1 -0
- package/web-ui/build/static/io-D6IgpCmL.js +1 -0
- package/web-ui/build/static/irpf90-Ctj0koST.js +1 -0
- package/web-ui/build/static/isbl-D2mGcH87.js +1 -0
- package/web-ui/build/static/j-KvHmDBWH.js +1 -0
- package/web-ui/build/static/java-BeBIdo5i.js +1 -0
- package/web-ui/build/static/java-llFZkHLe.js +1 -0
- package/web-ui/build/static/javadoc-DXvQGu0s.js +1 -0
- package/web-ui/build/static/javadoclike-B5qdA9KZ.js +1 -0
- package/web-ui/build/static/javascript-De6HzHvc.js +1 -0
- package/web-ui/build/static/javastacktrace-C5MolKiP.js +1 -0
- package/web-ui/build/static/jboss-cli-2TXd54zo.js +1 -0
- package/web-ui/build/static/jexl-W4AVA9fi.js +1 -0
- package/web-ui/build/static/jolie-DTJKRMZN.js +1 -0
- package/web-ui/build/static/jq-BYg-QQKh.js +1 -0
- package/web-ui/build/static/js-extras-BrYWd2VE.js +1 -0
- package/web-ui/build/static/js-templates-DorYpbHq.js +1 -0
- package/web-ui/build/static/jsdoc-CRF8n9pZ.js +1 -0
- package/web-ui/build/static/json-Dlcd7rla.js +1 -0
- package/web-ui/build/static/json-rhOJZzzZ.js +1 -0
- package/web-ui/build/static/json5-hTq1nNIW.js +1 -0
- package/web-ui/build/static/jsonp-CMg9Xvol.js +1 -0
- package/web-ui/build/static/jsstacktrace-hEeYxHtB.js +1 -0
- package/web-ui/build/static/jsx-B7PtA8WD.js +1 -0
- package/web-ui/build/static/julia-CNiEEY-n.js +1 -0
- package/web-ui/build/static/julia-eE0_SJlc.js +1 -0
- package/web-ui/build/static/julia-repl-CUJTTT4C.js +1 -0
- package/web-ui/build/static/keepalived-GUWJBqyD.js +1 -0
- package/web-ui/build/static/keyman-Bdf9MJyu.js +1 -0
- package/web-ui/build/static/kotlin-Ch6Bej5W.js +1 -0
- package/web-ui/build/static/kotlin-DFJ7D7Lw.js +1 -0
- package/web-ui/build/static/kumir-DJLIjcCs.js +1 -0
- package/web-ui/build/static/kusto-BM0YTwU4.js +1 -0
- package/web-ui/build/static/lasso-Z1DVS84K.js +1 -0
- package/web-ui/build/static/latex-BWbw71RK.js +1 -0
- package/web-ui/build/static/latex-CMzqmbhw.js +1 -0
- package/web-ui/build/static/latte-C1g8_grc.js +1 -0
- package/web-ui/build/static/ldif-C6QH3OIL.js +1 -0
- package/web-ui/build/static/leaf-CbR--ZsH.js +1 -0
- package/web-ui/build/static/less-ClVrKh2Z.js +1 -0
- package/web-ui/build/static/less-DNSxm8UA.js +1 -0
- package/web-ui/build/static/lilypond-lTzf_sWt.js +1 -0
- package/web-ui/build/static/liquid-Bn91mVfC.js +1 -0
- package/web-ui/build/static/lisp-CU3bHohQ.js +1 -0
- package/web-ui/build/static/lisp-DbgzE9W8.js +1 -0
- package/web-ui/build/static/livecodeserver-Cse1Uz3H.js +1 -0
- package/web-ui/build/static/livescript-BaxbgzWP.js +1 -0
- package/web-ui/build/static/livescript-nJt61DBy.js +1 -0
- package/web-ui/build/static/llvm-DBboo6UI.js +1 -0
- package/web-ui/build/static/llvm-vIy7XYVy.js +1 -0
- package/web-ui/build/static/log-CT7nfoDW.js +1 -0
- package/web-ui/build/static/lolcode-CUKVytZh.js +1 -0
- package/web-ui/build/static/lsl-CsAOlGF2.js +1 -0
- package/web-ui/build/static/lua-BuU2FFxP.js +1 -0
- package/web-ui/build/static/lua-CiDuKQaa.js +1 -0
- package/web-ui/build/static/magma-7vR0zcmS.js +1 -0
- package/web-ui/build/static/makefile-Buiz-Msh.js +1 -0
- package/web-ui/build/static/makefile-DXW_-6OY.js +1 -0
- package/web-ui/build/static/markdown-Bk5DUoGY.js +1 -0
- package/web-ui/build/static/markdown-CRS5W_Ai.js +1 -0
- package/web-ui/build/static/markup-templating-24odpmF3.js +1 -0
- package/web-ui/build/static/mathematica-BxcwhJUp.js +1 -0
- package/web-ui/build/static/matlab-3pJYx_Fb.js +1 -0
- package/web-ui/build/static/matlab-BqlRrzMf.js +1 -0
- package/web-ui/build/static/maxima-DlCfUpcj.js +1 -0
- package/web-ui/build/static/maxscript-Cu_gCaFU.js +1 -0
- package/web-ui/build/static/mel-D7iQ-5Up.js +1 -0
- package/web-ui/build/static/mel-DzBKNpoN.js +1 -0
- package/web-ui/build/static/mercury-Dfrb-i8A.js +1 -0
- package/web-ui/build/static/mermaid-WN7V2_Eq.js +1 -0
- package/web-ui/build/static/mipsasm-CcijzL0q.js +1 -0
- package/web-ui/build/static/mizar-Bk68zACP.js +1 -0
- package/web-ui/build/static/mizar-Twc2-iZ4.js +1 -0
- package/web-ui/build/static/mojolicious-DBbo2S7X.js +1 -0
- package/web-ui/build/static/mongodb-2RsFIjgg.js +1 -0
- package/web-ui/build/static/monkey-CPXtQ0Bf.js +1 -0
- package/web-ui/build/static/monkey-DjV7Wcek.js +1 -0
- package/web-ui/build/static/moonscript-B5M5as70.js +1 -0
- package/web-ui/build/static/moonscript-D1BHW4Il.js +1 -0
- package/web-ui/build/static/n1ql-D0heNDBD.js +1 -0
- package/web-ui/build/static/n1ql-DfHqXQD7.js +1 -0
- package/web-ui/build/static/n4js-CaPf44Dz.js +1 -0
- package/web-ui/build/static/nand2tetris-hdl-D1nf9mn4.js +1 -0
- package/web-ui/build/static/naniscript-DnCnu5ZX.js +1 -0
- package/web-ui/build/static/nasm-BZrSaMsK.js +1 -0
- package/web-ui/build/static/neon-D29Grm2v.js +1 -0
- package/web-ui/build/static/nevod-DgSNbQkE.js +1 -0
- package/web-ui/build/static/nginx-BAaDGDfT.js +1 -0
- package/web-ui/build/static/nginx-BvJ1lrHX.js +1 -0
- package/web-ui/build/static/nim--9zzVe5F.js +1 -0
- package/web-ui/build/static/nim-Br1relpU.js +1 -0
- package/web-ui/build/static/nix--0ftErCy.js +1 -0
- package/web-ui/build/static/nix-104ztQqr.js +1 -0
- package/web-ui/build/static/node-repl-BUMAf7_p.js +1 -0
- package/web-ui/build/static/nsis-BaeKybNA.js +1 -0
- package/web-ui/build/static/nsis-CdZEv2iA.js +1 -0
- package/web-ui/build/static/objectivec-DBB4ymdg.js +1 -0
- package/web-ui/build/static/objectivec-kFYXC6g4.js +1 -0
- package/web-ui/build/static/ocaml-D1GXvN7c.js +1 -0
- package/web-ui/build/static/ocaml-D80jRMPE.js +1 -0
- package/web-ui/build/static/opencl-fb7BfRdO.js +1 -0
- package/web-ui/build/static/openqasm-CWUBrR2w.js +1 -0
- package/web-ui/build/static/openscad-Dim7ILSL.js +1 -0
- package/web-ui/build/static/oxygene-BSwApkwz.js +1 -0
- package/web-ui/build/static/oz-CMtRoi5F.js +1 -0
- package/web-ui/build/static/parigp-AH8cZ38D.js +1 -0
- package/web-ui/build/static/parser-bBNjuhG3.js +1 -0
- package/web-ui/build/static/parser3-DUtoWEAd.js +1 -0
- package/web-ui/build/static/pascal-Cr3DPIYT.js +1 -0
- package/web-ui/build/static/pascaligo-pWW12jfs.js +1 -0
- package/web-ui/build/static/pcaxis-DBw9rxmr.js +1 -0
- package/web-ui/build/static/peoplecode-aCpMPm_s.js +1 -0
- package/web-ui/build/static/perl-BpZ7GmJ3.js +1 -0
- package/web-ui/build/static/perl-fnHTrqJL.js +1 -0
- package/web-ui/build/static/pf-Dz352ty7.js +1 -0
- package/web-ui/build/static/pgsql-CHPUdlI_.js +1 -0
- package/web-ui/build/static/php-BRwItjmS.js +1 -0
- package/web-ui/build/static/php-CrX_kswO.js +1 -0
- package/web-ui/build/static/php-extras-BmeRXDSO.js +1 -0
- package/web-ui/build/static/php-template-B0MFJ9RR.js +1 -0
- package/web-ui/build/static/phpdoc-wAPkJj9X.js +1 -0
- package/web-ui/build/static/plaintext-CmPk1gvP.js +1 -0
- package/web-ui/build/static/plsql-pWVw0sCJ.js +1 -0
- package/web-ui/build/static/pony-B4SXhyDS.js +1 -0
- package/web-ui/build/static/powerquery-ZJ28bdRR.js +1 -0
- package/web-ui/build/static/powershell-CWg1ca6z.js +1 -0
- package/web-ui/build/static/powershell-Dnl0aBXc.js +1 -0
- package/web-ui/build/static/processing-CbYVU7hZ.js +1 -0
- package/web-ui/build/static/processing-DnroirEw.js +1 -0
- package/web-ui/build/static/profile-DLNc-MTA.js +1 -0
- package/web-ui/build/static/prolog-4KlPFQus.js +1 -0
- package/web-ui/build/static/prolog-CtUicY87.js +1 -0
- package/web-ui/build/static/promql-C_i6OJVg.js +1 -0
- package/web-ui/build/static/properties-Cj0lBOSP.js +1 -0
- package/web-ui/build/static/properties-vGFibcz9.js +1 -0
- package/web-ui/build/static/protobuf-BOIGxbSP.js +1 -0
- package/web-ui/build/static/protobuf-CQ3su-J7.js +1 -0
- package/web-ui/build/static/psl-DeG5_YUF.js +1 -0
- package/web-ui/build/static/pug-BieVVXYz.js +1 -0
- package/web-ui/build/static/puppet-Ba40SVKU.js +1 -0
- package/web-ui/build/static/puppet-D7BzrcGt.js +1 -0
- package/web-ui/build/static/pure-DZnkz1iT.js +1 -0
- package/web-ui/build/static/purebasic-CLLZW_6G.js +1 -0
- package/web-ui/build/static/purebasic-CYPZo_H6.js +1 -0
- package/web-ui/build/static/purescript-Dyjfu5Id.js +1 -0
- package/web-ui/build/static/python-BdIWKxdN.js +1 -0
- package/web-ui/build/static/python-ofKsqxv7.js +1 -0
- package/web-ui/build/static/python-repl-DiTYb1xK.js +1 -0
- package/web-ui/build/static/q-B4P0If_I.js +1 -0
- package/web-ui/build/static/q-t_17xfY8.js +1 -0
- package/web-ui/build/static/qml-B5WhiN48.js +1 -0
- package/web-ui/build/static/qml-Dq0cESXJ.js +1 -0
- package/web-ui/build/static/qore-DCx30XRf.js +1 -0
- package/web-ui/build/static/qsharp-UrBScekp.js +1 -0
- package/web-ui/build/static/r-B0Ty1RKQ.js +1 -0
- package/web-ui/build/static/r-B0za8QKS.js +1 -0
- package/web-ui/build/static/racket-Dj6WEyhS.js +1 -0
- package/web-ui/build/static/reason-dj9hJSfr.js +1 -0
- package/web-ui/build/static/reasonml-B-q5_wag.js +1 -0
- package/web-ui/build/static/regex-4HEc5C1m.js +1 -0
- package/web-ui/build/static/rego-BdQe18RK.js +1 -0
- package/web-ui/build/static/renpy-CVMA2llL.js +1 -0
- package/web-ui/build/static/rest-9B4JWVGr.js +1 -0
- package/web-ui/build/static/rib-DR-U8OaT.js +1 -0
- package/web-ui/build/static/rip-Bu2t_rFZ.js +1 -0
- package/web-ui/build/static/roboconf-CJeXD5-I.js +1 -0
- package/web-ui/build/static/roboconf-DzDTVrdM.js +1 -0
- package/web-ui/build/static/robotframework-CR7KyPpN.js +1 -0
- package/web-ui/build/static/routeros-B2741z2k.js +1 -0
- package/web-ui/build/static/rsl-B9F_ZCgv.js +1 -0
- package/web-ui/build/static/ruby-I2JTNgyY.js +1 -0
- package/web-ui/build/static/ruby-QGDPOmJX.js +1 -0
- package/web-ui/build/static/ruleslanguage-CGzXEUCO.js +1 -0
- package/web-ui/build/static/rust-BxW5-WOm.js +1 -0
- package/web-ui/build/static/rust-CSOA43di.js +1 -0
- package/web-ui/build/static/sas-Bclfx4g3.js +1 -0
- package/web-ui/build/static/sas-xbQaiYjT.js +1 -0
- package/web-ui/build/static/sass-DJPbdNwd.js +1 -0
- package/web-ui/build/static/scala-Bo18NtHQ.js +1 -0
- package/web-ui/build/static/scala-Cy0JH-SG.js +1 -0
- package/web-ui/build/static/scheme-BjcWWjIx.js +1 -0
- package/web-ui/build/static/scheme-DQdj8PzN.js +1 -0
- package/web-ui/build/static/scilab-Bn1KHdK-.js +1 -0
- package/web-ui/build/static/scss-B1twkZBz.js +1 -0
- package/web-ui/build/static/scss-DmOuMI4v.js +1 -0
- package/web-ui/build/static/shell-BUlkJG0S.js +1 -0
- package/web-ui/build/static/shell-session-Bke-svxA.js +1 -0
- package/web-ui/build/static/smali-Ch9S16HV.js +1 -0
- package/web-ui/build/static/smali-D_yDr_Aj.js +1 -0
- package/web-ui/build/static/smalltalk-B9TfQ5Md.js +1 -0
- package/web-ui/build/static/smalltalk-EwbZxZsR.js +1 -0
- package/web-ui/build/static/smarty-9kDPpeSm.js +1 -0
- package/web-ui/build/static/sml-2fEfT7rd.js +1 -0
- package/web-ui/build/static/sml-BiwoLNk7.js +1 -0
- package/web-ui/build/static/solidity-n_x8Oe0h.js +1 -0
- package/web-ui/build/static/solution-file-B2mvjI3e.js +1 -0
- package/web-ui/build/static/soy-DPkgKBIS.js +1 -0
- package/web-ui/build/static/sparql-Cy95tds0.js +1 -0
- package/web-ui/build/static/splunk-spl-Ym3z9ouN.js +1 -0
- package/web-ui/build/static/sqf-CXZTG8WE.js +1 -0
- package/web-ui/build/static/sqf-Cwi3yg7f.js +1 -0
- package/web-ui/build/static/sql-DPxSQY4S.js +1 -0
- package/web-ui/build/static/sql-peh7ijGj.js +1 -0
- package/web-ui/build/static/sql_more-0YAbAuPw.js +1 -0
- package/web-ui/build/static/squirrel-CphzjV0e.js +1 -0
- package/web-ui/build/static/stan-0-xZ95-O.js +1 -0
- package/web-ui/build/static/stan-CaI4__2g.js +1 -0
- package/web-ui/build/static/stata-BrbzrGSs.js +1 -0
- package/web-ui/build/static/step21-C_qeyVLw.js +1 -0
- package/web-ui/build/static/stylus-Btycb2sZ.js +1 -0
- package/web-ui/build/static/stylus-FoBJ7jki.js +1 -0
- package/web-ui/build/static/subunit-Dpg-m04-.js +1 -0
- package/web-ui/build/static/swift-Cr9uZmgb.js +1 -0
- package/web-ui/build/static/swift-hGLFtD7e.js +1 -0
- package/web-ui/build/static/systemd-Bls2D9Vj.js +1 -0
- package/web-ui/build/static/t4-cs-C4qDO-jJ.js +1 -0
- package/web-ui/build/static/t4-templating-BbCFPMPO.js +1 -0
- package/web-ui/build/static/t4-vb-D1zoEccT.js +1 -0
- package/web-ui/build/static/taggerscript-CWHk9Gih.js +1 -0
- package/web-ui/build/static/tap-Bjt0UnzV.js +1 -0
- package/web-ui/build/static/tap-BnHKwLQs.js +1 -0
- package/web-ui/build/static/tcl-Zo9kx4y-.js +1 -0
- package/web-ui/build/static/tcl-fzLmefkt.js +1 -0
- package/web-ui/build/static/textile-9lIlUPH5.js +1 -0
- package/web-ui/build/static/thrift-M3K6r5Cy.js +1 -0
- package/web-ui/build/static/toml-HpaKqckc.js +1 -0
- package/web-ui/build/static/tp-DFKuxrKj.js +1 -0
- package/web-ui/build/static/tremor-D4_bUtMB.js +1 -0
- package/web-ui/build/static/tsx-o1RT-T90.js +1 -0
- package/web-ui/build/static/tt2-1xDqcN_2.js +1 -0
- package/web-ui/build/static/turtle-Dlt-aGky.js +1 -0
- package/web-ui/build/static/twig-CJ_BnGSR.js +1 -0
- package/web-ui/build/static/twig-CjsiSQb6.js +1 -0
- package/web-ui/build/static/typescript-B8B9zUn-.js +1 -0
- package/web-ui/build/static/typescript-D0Jgo8O7.js +1 -0
- package/web-ui/build/static/typoscript-C8Qke4ZB.js +1 -0
- package/web-ui/build/static/unrealscript-YxJdDNZ3.js +1 -0
- package/web-ui/build/static/uorazor-CtEVnqBv.js +1 -0
- package/web-ui/build/static/uri-YdaiQl4c.js +1 -0
- package/web-ui/build/static/v-CIyttMDD.js +1 -0
- package/web-ui/build/static/vala-DGslcym_.js +1 -0
- package/web-ui/build/static/vala-GFPx3uEJ.js +1 -0
- package/web-ui/build/static/vbnet-B20itab-.js +1 -0
- package/web-ui/build/static/vbnet-BdoN6egk.js +1 -0
- package/web-ui/build/static/vbscript-PHVh6Fp_.js +1 -0
- package/web-ui/build/static/vbscript-html-woH1VZ7U.js +1 -0
- package/web-ui/build/static/velocity-DtVfCZeg.js +1 -0
- package/web-ui/build/static/verilog-Bt6edXvM.js +1 -0
- package/web-ui/build/static/verilog-k_7lr9Zq.js +1 -0
- package/web-ui/build/static/vhdl-BMzOgOeK.js +1 -0
- package/web-ui/build/static/vhdl-BcAbtPG6.js +1 -0
- package/web-ui/build/static/vim-DrinG9a4.js +1 -0
- package/web-ui/build/static/vim-WihLATJL.js +1 -0
- package/web-ui/build/static/visual-basic-CJnvgPjM.js +1 -0
- package/web-ui/build/static/warpscript-zMlbUoZs.js +1 -0
- package/web-ui/build/static/wasm-GUnfTBUL.js +1 -0
- package/web-ui/build/static/web-idl-CfaLTG_r.js +1 -0
- package/web-ui/build/static/wiki-13AlLoOc.js +1 -0
- package/web-ui/build/static/wolfram-zHocYNXW.js +1 -0
- package/web-ui/build/static/wren-Byq862Iu.js +1 -0
- package/web-ui/build/static/x86asm-CLcOnePY.js +1 -0
- package/web-ui/build/static/xeora-BVHqWOFS.js +1 -0
- package/web-ui/build/static/xl-lXi8OYfr.js +1 -0
- package/web-ui/build/static/xml-KZjGBKxi.js +1 -0
- package/web-ui/build/static/xml-doc-DrQSDcEW.js +1 -0
- package/web-ui/build/static/xojo-DosHeFXU.js +1 -0
- package/web-ui/build/static/xquery-BZN1F14Q.js +1 -0
- package/web-ui/build/static/xquery-Cnz7ZLFr.js +1 -0
- package/web-ui/build/static/yaml-BzXOcy9u.js +1 -0
- package/web-ui/build/static/yaml-C207y5bt.js +1 -0
- package/web-ui/build/static/yang-ByrBdDIg.js +1 -0
- package/web-ui/build/static/zephir-bahTa7of.js +1 -0
- package/web-ui/build/static/zig-BlFYhdtC.js +1 -0
- package/src/tools/browserTool.js +0 -897
- package/src/utilities/platformUtils.test.js +0 -98
- package/web-ui/build/static/index-SmQFfvBs.js +0 -746
- package/web-ui/build/static/index-V2ySwjHp.css +0 -1
package/src/tools/browserTool.js
DELETED
|
@@ -1,897 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @deprecated This tool is DEPRECATED as of December 2024.
|
|
3
|
-
* Use WebTool (toolId: "web") instead for all browser automation tasks.
|
|
4
|
-
*
|
|
5
|
-
* WebTool provides:
|
|
6
|
-
* - All browser automation features (navigate, click, type, screenshot, etc.)
|
|
7
|
-
* - Built-in search engine support (Google, Bing, DuckDuckGo)
|
|
8
|
-
* - Tab management with agent isolation
|
|
9
|
-
* - AI-powered screenshot analysis
|
|
10
|
-
*
|
|
11
|
-
* This file is kept for backward compatibility but will be removed in a future version.
|
|
12
|
-
*
|
|
13
|
-
* Migration guide:
|
|
14
|
-
* - Replace toolId "browser" with "web"
|
|
15
|
-
* - Use operation: "interactive" with actions array
|
|
16
|
-
* - Wrap actions in open-tab for tab context
|
|
17
|
-
*
|
|
18
|
-
* Original BrowserTool - Handle browser automation and web interaction tasks
|
|
19
|
-
*
|
|
20
|
-
* Purpose:
|
|
21
|
-
* - Automate web browser interactions
|
|
22
|
-
* - Navigate websites and extract data
|
|
23
|
-
* - Fill forms and interact with web elements
|
|
24
|
-
* - Take screenshots and analyze web content
|
|
25
|
-
* - Handle authentication and sessions
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
import { BaseTool } from './baseTool.js';
|
|
29
|
-
import TagParser from '../utilities/tagParser.js';
|
|
30
|
-
import puppeteer from 'puppeteer';
|
|
31
|
-
import fs from 'fs/promises';
|
|
32
|
-
import path from 'path';
|
|
33
|
-
|
|
34
|
-
import {
|
|
35
|
-
TOOL_STATUS,
|
|
36
|
-
SYSTEM_DEFAULTS
|
|
37
|
-
} from '../utilities/constants.js';
|
|
38
|
-
import { getDefaultUserAgent } from '../utilities/platformUtils.js';
|
|
39
|
-
|
|
40
|
-
class BrowserTool extends BaseTool {
|
|
41
|
-
constructor(config = {}, logger = null) {
|
|
42
|
-
super(config, logger);
|
|
43
|
-
|
|
44
|
-
// Tool metadata
|
|
45
|
-
this.requiresProject = false;
|
|
46
|
-
this.isAsync = true; // Browser operations can be slow
|
|
47
|
-
this.timeout = config.timeout || 60000; // 1 minute default
|
|
48
|
-
this.maxConcurrentOperations = config.maxConcurrentOperations || 2;
|
|
49
|
-
|
|
50
|
-
// Browser configuration
|
|
51
|
-
this.browserConfig = {
|
|
52
|
-
headless: config.headless !== false, // Default to headless
|
|
53
|
-
viewport: config.viewport || { width: 1280, height: 720 },
|
|
54
|
-
userAgent: config.userAgent || getDefaultUserAgent(),
|
|
55
|
-
timeout: config.pageTimeout || 30000
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
// Active browser instances
|
|
59
|
-
this.browserInstances = new Map();
|
|
60
|
-
|
|
61
|
-
// Security settings
|
|
62
|
-
this.allowedDomains = config.allowedDomains || null; // null = all allowed
|
|
63
|
-
this.blockedDomains = config.blockedDomains || [];
|
|
64
|
-
this.maxScreenshotSize = config.maxScreenshotSize || 5 * 1024 * 1024; // 5MB
|
|
65
|
-
|
|
66
|
-
// Operation history
|
|
67
|
-
this.operationHistory = [];
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Get tool description for LLM consumption
|
|
72
|
-
* @returns {string} Tool description
|
|
73
|
-
*/
|
|
74
|
-
getDescription() {
|
|
75
|
-
return `
|
|
76
|
-
Browser Tool: Automate web browser interactions, navigation, and data extraction.
|
|
77
|
-
|
|
78
|
-
USAGE:
|
|
79
|
-
\`\`\`json
|
|
80
|
-
{
|
|
81
|
-
"toolId": "browser",
|
|
82
|
-
"actions": [
|
|
83
|
-
{"type": "navigate", "url": "https://example.com"},
|
|
84
|
-
{"type": "wait", "waitTime": 2000},
|
|
85
|
-
{"type": "click", "selector": "button.submit"},
|
|
86
|
-
{"type": "screenshot", "outputPath": "screenshot.png"}
|
|
87
|
-
]
|
|
88
|
-
}
|
|
89
|
-
\`\`\`
|
|
90
|
-
|
|
91
|
-
SUPPORTED ACTIONS:
|
|
92
|
-
- navigate: Navigate to URL (url)
|
|
93
|
-
- click: Click element (selector)
|
|
94
|
-
- type: Type text (selector, text)
|
|
95
|
-
- wait: Wait for element/time (waitTime or waitSelector)
|
|
96
|
-
- screenshot: Take screenshot (outputPath, fullPage)
|
|
97
|
-
- extract: Extract data (selector, attribute)
|
|
98
|
-
- scroll: Scroll page (direction, pixels)
|
|
99
|
-
- close: Close browser
|
|
100
|
-
|
|
101
|
-
PARAMETERS:
|
|
102
|
-
- url: Target URL for navigation
|
|
103
|
-
- selector: CSS selector (e.g., "#id", ".class", "button[type='submit']")
|
|
104
|
-
- text: Text to type
|
|
105
|
-
- outputPath: Screenshot file path
|
|
106
|
-
- waitTime: Wait in milliseconds (100-30000)
|
|
107
|
-
- waitSelector: Element selector to wait for
|
|
108
|
-
- attribute: HTML attribute to extract (default: "text")
|
|
109
|
-
- direction: "up", "down", "left", "right"
|
|
110
|
-
- pixels: Scroll distance (default: 300)
|
|
111
|
-
- fullPage: Full page screenshot (true/false)
|
|
112
|
-
|
|
113
|
-
EXAMPLES:
|
|
114
|
-
|
|
115
|
-
Screenshot a page:
|
|
116
|
-
\`\`\`json
|
|
117
|
-
{
|
|
118
|
-
"toolId": "browser",
|
|
119
|
-
"actions": [
|
|
120
|
-
{"type": "navigate", "url": "https://github.com/trending"},
|
|
121
|
-
{"type": "wait", "waitTime": 2000},
|
|
122
|
-
{"type": "screenshot", "outputPath": "trending.png"},
|
|
123
|
-
{"type": "close"}
|
|
124
|
-
]
|
|
125
|
-
}
|
|
126
|
-
\`\`\`
|
|
127
|
-
|
|
128
|
-
Form automation:
|
|
129
|
-
\`\`\`json
|
|
130
|
-
{
|
|
131
|
-
"toolId": "browser",
|
|
132
|
-
"actions": [
|
|
133
|
-
{"type": "navigate", "url": "https://example.com/login"},
|
|
134
|
-
{"type": "wait", "waitSelector": "input#username"},
|
|
135
|
-
{"type": "type", "selector": "input#username", "text": "myuser"},
|
|
136
|
-
{"type": "type", "selector": "input#password", "text": "mypass"},
|
|
137
|
-
{"type": "click", "selector": "button[type='submit']"},
|
|
138
|
-
{"type": "close"}
|
|
139
|
-
]
|
|
140
|
-
}
|
|
141
|
-
\`\`\`
|
|
142
|
-
|
|
143
|
-
SECURITY:
|
|
144
|
-
- Restricted to allowed domains
|
|
145
|
-
- Screenshot size limits (max 5MB)
|
|
146
|
-
- Auto-cleanup after 10 minutes
|
|
147
|
-
|
|
148
|
-
VIEWPORT: ${this.browserConfig.viewport.width}x${this.browserConfig.viewport.height}
|
|
149
|
-
TIMEOUT: ${this.browserConfig.timeout}ms per operation
|
|
150
|
-
`;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Parse parameters from tool command content
|
|
155
|
-
* @param {string} content - Raw tool command content
|
|
156
|
-
* @returns {Object} Parsed parameters
|
|
157
|
-
*/
|
|
158
|
-
parseParameters(content) {
|
|
159
|
-
try {
|
|
160
|
-
// Try JSON first (for JSON in code blocks)
|
|
161
|
-
if (content.trim().startsWith('{')) {
|
|
162
|
-
const parsed = JSON.parse(content);
|
|
163
|
-
// Ensure actions is an array
|
|
164
|
-
if (!parsed.actions) {
|
|
165
|
-
parsed.actions = [];
|
|
166
|
-
}
|
|
167
|
-
if (!Array.isArray(parsed.actions)) {
|
|
168
|
-
parsed.actions = [parsed.actions];
|
|
169
|
-
}
|
|
170
|
-
return parsed;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const params = {};
|
|
174
|
-
const actions = [];
|
|
175
|
-
|
|
176
|
-
// Extract self-closing tags (e.g., <navigate url="..." />)
|
|
177
|
-
const selfClosingTags = [
|
|
178
|
-
'navigate', 'click', 'type', 'wait', 'screenshot',
|
|
179
|
-
'extract', 'scroll', 'close'
|
|
180
|
-
];
|
|
181
|
-
|
|
182
|
-
for (const tagName of selfClosingTags) {
|
|
183
|
-
// Extract self-closing tags using regex
|
|
184
|
-
const selfClosingPattern = new RegExp(
|
|
185
|
-
`<${tagName}\\s+([^>]*?)\\s*\\/?>`,
|
|
186
|
-
'gi'
|
|
187
|
-
);
|
|
188
|
-
|
|
189
|
-
let match;
|
|
190
|
-
while ((match = selfClosingPattern.exec(content)) !== null) {
|
|
191
|
-
const attributeString = match[1];
|
|
192
|
-
const attributes = this.parseAttributes(attributeString);
|
|
193
|
-
|
|
194
|
-
const action = {
|
|
195
|
-
type: tagName,
|
|
196
|
-
...attributes
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
// Normalize common attribute names (kebab-case to camelCase)
|
|
200
|
-
if (action['output-path']) {
|
|
201
|
-
action.outputPath = action['output-path'];
|
|
202
|
-
delete action['output-path'];
|
|
203
|
-
}
|
|
204
|
-
if (action['wait-time']) {
|
|
205
|
-
action.waitTime = parseInt(action['wait-time'], 10);
|
|
206
|
-
delete action['wait-time'];
|
|
207
|
-
}
|
|
208
|
-
if (action['wait-selector']) {
|
|
209
|
-
action.waitSelector = action['wait-selector'];
|
|
210
|
-
delete action['wait-selector'];
|
|
211
|
-
}
|
|
212
|
-
if (action['wait-type']) {
|
|
213
|
-
action.waitType = action['wait-type'];
|
|
214
|
-
delete action['wait-type'];
|
|
215
|
-
}
|
|
216
|
-
if (action['full-page']) {
|
|
217
|
-
action.fullPage = action['full-page'] === 'true';
|
|
218
|
-
delete action['full-page'];
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
actions.push(action);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Ensure actions is always an array (even if empty)
|
|
226
|
-
params.actions = Array.isArray(actions) ? actions : [];
|
|
227
|
-
params.rawContent = content.trim();
|
|
228
|
-
|
|
229
|
-
return params;
|
|
230
|
-
|
|
231
|
-
} catch (error) {
|
|
232
|
-
// If JSON parsing fails, return a structure with empty actions
|
|
233
|
-
// This prevents "actions is not iterable" errors
|
|
234
|
-
this.logger?.error('Failed to parse browser parameters', { error: error.message });
|
|
235
|
-
return {
|
|
236
|
-
actions: [], // Always return an array
|
|
237
|
-
rawContent: content.trim(),
|
|
238
|
-
parseError: error.message
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Parse attributes from attribute string
|
|
245
|
-
* @param {string} attributeString - String containing attributes
|
|
246
|
-
* @returns {Object} Parsed attributes object
|
|
247
|
-
* @private
|
|
248
|
-
*/
|
|
249
|
-
parseAttributes(attributeString) {
|
|
250
|
-
const attributes = {};
|
|
251
|
-
|
|
252
|
-
if (!attributeString) return attributes;
|
|
253
|
-
|
|
254
|
-
// Match attribute="value" or attribute='value'
|
|
255
|
-
const attrPattern = /([\w-]+)\s*=\s*["']([^"']*)["']/g;
|
|
256
|
-
let match;
|
|
257
|
-
|
|
258
|
-
while ((match = attrPattern.exec(attributeString)) !== null) {
|
|
259
|
-
const attrName = match[1];
|
|
260
|
-
const attrValue = match[2];
|
|
261
|
-
attributes[attrName] = attrValue;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
return attributes;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* Get required parameters
|
|
269
|
-
* @returns {Array<string>} Array of required parameter names
|
|
270
|
-
*/
|
|
271
|
-
getRequiredParameters() {
|
|
272
|
-
return ['actions'];
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* Custom parameter validation
|
|
277
|
-
* @param {Object} params - Parameters to validate
|
|
278
|
-
* @returns {Object} Validation result
|
|
279
|
-
*/
|
|
280
|
-
customValidateParameters(params) {
|
|
281
|
-
const errors = [];
|
|
282
|
-
|
|
283
|
-
if (!params.actions || !Array.isArray(params.actions) || params.actions.length === 0) {
|
|
284
|
-
errors.push('At least one action is required');
|
|
285
|
-
} else {
|
|
286
|
-
// Validate each action
|
|
287
|
-
for (const [index, action] of params.actions.entries()) {
|
|
288
|
-
if (!action.type) {
|
|
289
|
-
errors.push(`Action ${index + 1}: type is required`);
|
|
290
|
-
continue;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
switch (action.type) {
|
|
294
|
-
case 'navigate':
|
|
295
|
-
if (!action.url) {
|
|
296
|
-
errors.push(`Action ${index + 1}: url is required for navigate`);
|
|
297
|
-
} else if (!this.isAllowedUrl(action.url)) {
|
|
298
|
-
errors.push(`Action ${index + 1}: URL not allowed: ${action.url}`);
|
|
299
|
-
}
|
|
300
|
-
break;
|
|
301
|
-
|
|
302
|
-
case 'click':
|
|
303
|
-
case 'extract':
|
|
304
|
-
if (!action.selector) {
|
|
305
|
-
errors.push(`Action ${index + 1}: selector is required for ${action.type}`);
|
|
306
|
-
}
|
|
307
|
-
break;
|
|
308
|
-
|
|
309
|
-
case 'type':
|
|
310
|
-
if (!action.selector) {
|
|
311
|
-
errors.push(`Action ${index + 1}: selector is required for type`);
|
|
312
|
-
}
|
|
313
|
-
if (!action.text && action.text !== '') {
|
|
314
|
-
errors.push(`Action ${index + 1}: text is required for type`);
|
|
315
|
-
}
|
|
316
|
-
break;
|
|
317
|
-
|
|
318
|
-
case 'wait':
|
|
319
|
-
if (!action.waitTime && !action.waitSelector) {
|
|
320
|
-
errors.push(`Action ${index + 1}: either wait-time or wait-selector is required`);
|
|
321
|
-
}
|
|
322
|
-
if (action.waitTime && (action.waitTime < 100 || action.waitTime > 30000)) {
|
|
323
|
-
errors.push(`Action ${index + 1}: wait-time must be between 100 and 30000 milliseconds`);
|
|
324
|
-
}
|
|
325
|
-
break;
|
|
326
|
-
|
|
327
|
-
case 'screenshot':
|
|
328
|
-
if (!action.outputPath) {
|
|
329
|
-
errors.push(`Action ${index + 1}: output-path is required for screenshot`);
|
|
330
|
-
}
|
|
331
|
-
break;
|
|
332
|
-
|
|
333
|
-
case 'scroll':
|
|
334
|
-
if (!action.direction) {
|
|
335
|
-
errors.push(`Action ${index + 1}: direction is required for scroll`);
|
|
336
|
-
} else if (!['up', 'down', 'left', 'right'].includes(action.direction)) {
|
|
337
|
-
errors.push(`Action ${index + 1}: invalid scroll direction: ${action.direction}`);
|
|
338
|
-
}
|
|
339
|
-
break;
|
|
340
|
-
|
|
341
|
-
case 'close':
|
|
342
|
-
// No additional validation needed
|
|
343
|
-
break;
|
|
344
|
-
|
|
345
|
-
default:
|
|
346
|
-
errors.push(`Action ${index + 1}: unknown action type: ${action.type}`);
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
return {
|
|
352
|
-
valid: errors.length === 0,
|
|
353
|
-
errors
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* Execute tool with parsed parameters
|
|
359
|
-
* @param {Object} params - Parsed parameters
|
|
360
|
-
* @param {Object} context - Execution context
|
|
361
|
-
* @returns {Promise<Object>} Execution result
|
|
362
|
-
*/
|
|
363
|
-
async execute(params, context) {
|
|
364
|
-
const { actions } = params;
|
|
365
|
-
const { agentId, projectDir } = context;
|
|
366
|
-
|
|
367
|
-
const browserKey = `${agentId}-${projectDir || 'default'}`;
|
|
368
|
-
const results = [];
|
|
369
|
-
|
|
370
|
-
for (const action of actions) {
|
|
371
|
-
try {
|
|
372
|
-
let result;
|
|
373
|
-
|
|
374
|
-
switch (action.type) {
|
|
375
|
-
case 'navigate':
|
|
376
|
-
result = await this.navigate(action.url, browserKey);
|
|
377
|
-
break;
|
|
378
|
-
|
|
379
|
-
case 'click':
|
|
380
|
-
result = await this.click(action.selector, browserKey);
|
|
381
|
-
break;
|
|
382
|
-
|
|
383
|
-
case 'type':
|
|
384
|
-
result = await this.type(action.selector, action.text, browserKey);
|
|
385
|
-
break;
|
|
386
|
-
|
|
387
|
-
case 'wait':
|
|
388
|
-
result = await this.wait(action, browserKey);
|
|
389
|
-
break;
|
|
390
|
-
|
|
391
|
-
case 'screenshot':
|
|
392
|
-
result = await this.screenshot(action.outputPath, projectDir, browserKey, action);
|
|
393
|
-
break;
|
|
394
|
-
|
|
395
|
-
case 'extract':
|
|
396
|
-
result = await this.extract(action.selector, action.attribute || 'text', browserKey);
|
|
397
|
-
break;
|
|
398
|
-
|
|
399
|
-
case 'scroll':
|
|
400
|
-
result = await this.scroll(action, browserKey);
|
|
401
|
-
break;
|
|
402
|
-
|
|
403
|
-
case 'close':
|
|
404
|
-
result = await this.closeBrowser(browserKey);
|
|
405
|
-
break;
|
|
406
|
-
|
|
407
|
-
default:
|
|
408
|
-
throw new Error(`Unknown action type: ${action.type}`);
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
results.push(result);
|
|
412
|
-
this.addToHistory(action, result, agentId);
|
|
413
|
-
|
|
414
|
-
} catch (error) {
|
|
415
|
-
const errorResult = {
|
|
416
|
-
success: false,
|
|
417
|
-
action: action.type,
|
|
418
|
-
error: error.message,
|
|
419
|
-
selector: action.selector || action.url
|
|
420
|
-
};
|
|
421
|
-
|
|
422
|
-
results.push(errorResult);
|
|
423
|
-
this.addToHistory(action, errorResult, agentId);
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
return {
|
|
428
|
-
success: true,
|
|
429
|
-
actions: results,
|
|
430
|
-
executedActions: actions.length,
|
|
431
|
-
toolUsed: 'browser'
|
|
432
|
-
};
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
/**
|
|
436
|
-
* Navigate to URL
|
|
437
|
-
* @private
|
|
438
|
-
*/
|
|
439
|
-
async navigate(url, browserKey) {
|
|
440
|
-
const browser = await this.getBrowser(browserKey);
|
|
441
|
-
const page = await this.getPage(browserKey);
|
|
442
|
-
|
|
443
|
-
const startTime = Date.now();
|
|
444
|
-
|
|
445
|
-
try {
|
|
446
|
-
await page.goto(url, {
|
|
447
|
-
waitUntil: 'networkidle0',
|
|
448
|
-
timeout: this.browserConfig.timeout
|
|
449
|
-
});
|
|
450
|
-
|
|
451
|
-
const title = await page.title();
|
|
452
|
-
const currentUrl = page.url();
|
|
453
|
-
|
|
454
|
-
return {
|
|
455
|
-
success: true,
|
|
456
|
-
action: 'navigate',
|
|
457
|
-
url: currentUrl,
|
|
458
|
-
originalUrl: url,
|
|
459
|
-
title,
|
|
460
|
-
loadTime: Date.now() - startTime,
|
|
461
|
-
message: `Navigated to ${url}`
|
|
462
|
-
};
|
|
463
|
-
|
|
464
|
-
} catch (error) {
|
|
465
|
-
throw new Error(`Navigation failed: ${error.message}`);
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
/**
|
|
470
|
-
* Click on element
|
|
471
|
-
* @private
|
|
472
|
-
*/
|
|
473
|
-
async click(selector, browserKey) {
|
|
474
|
-
const page = await this.getPage(browserKey);
|
|
475
|
-
|
|
476
|
-
try {
|
|
477
|
-
await page.waitForSelector(selector, { timeout: 5000 });
|
|
478
|
-
await page.click(selector);
|
|
479
|
-
|
|
480
|
-
return {
|
|
481
|
-
success: true,
|
|
482
|
-
action: 'click',
|
|
483
|
-
selector,
|
|
484
|
-
message: `Clicked on ${selector}`
|
|
485
|
-
};
|
|
486
|
-
|
|
487
|
-
} catch (error) {
|
|
488
|
-
throw new Error(`Click failed on ${selector}: ${error.message}`);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
/**
|
|
493
|
-
* Type text into element
|
|
494
|
-
* @private
|
|
495
|
-
*/
|
|
496
|
-
async type(selector, text, browserKey) {
|
|
497
|
-
const page = await this.getPage(browserKey);
|
|
498
|
-
|
|
499
|
-
try {
|
|
500
|
-
await page.waitForSelector(selector, { timeout: 5000 });
|
|
501
|
-
await page.focus(selector);
|
|
502
|
-
await page.keyboard.selectAll();
|
|
503
|
-
await page.type(selector, text);
|
|
504
|
-
|
|
505
|
-
return {
|
|
506
|
-
success: true,
|
|
507
|
-
action: 'type',
|
|
508
|
-
selector,
|
|
509
|
-
text,
|
|
510
|
-
textLength: text.length,
|
|
511
|
-
message: `Typed ${text.length} characters into ${selector}`
|
|
512
|
-
};
|
|
513
|
-
|
|
514
|
-
} catch (error) {
|
|
515
|
-
throw new Error(`Type failed on ${selector}: ${error.message}`);
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
/**
|
|
520
|
-
* Wait for condition
|
|
521
|
-
* @private
|
|
522
|
-
*/
|
|
523
|
-
async wait(action, browserKey) {
|
|
524
|
-
const page = await this.getPage(browserKey);
|
|
525
|
-
|
|
526
|
-
try {
|
|
527
|
-
if (action.waitTime) {
|
|
528
|
-
// Use setTimeout wrapped in Promise (waitForTimeout was removed in Puppeteer v22+)
|
|
529
|
-
await new Promise(resolve => setTimeout(resolve, action.waitTime));
|
|
530
|
-
return {
|
|
531
|
-
success: true,
|
|
532
|
-
action: 'wait',
|
|
533
|
-
waitTime: action.waitTime,
|
|
534
|
-
message: `Waited ${action.waitTime}ms`
|
|
535
|
-
};
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
if (action.waitSelector) {
|
|
539
|
-
const waitType = action.waitType || 'visible';
|
|
540
|
-
const options = { timeout: 10000 };
|
|
541
|
-
|
|
542
|
-
if (waitType === 'hidden') {
|
|
543
|
-
await page.waitForSelector(action.waitSelector, { ...options, hidden: true });
|
|
544
|
-
} else {
|
|
545
|
-
await page.waitForSelector(action.waitSelector, options);
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
return {
|
|
549
|
-
success: true,
|
|
550
|
-
action: 'wait',
|
|
551
|
-
waitSelector: action.waitSelector,
|
|
552
|
-
waitType,
|
|
553
|
-
message: `Waited for ${action.waitSelector} to be ${waitType}`
|
|
554
|
-
};
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
} catch (error) {
|
|
558
|
-
throw new Error(`Wait failed: ${error.message}`);
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
/**
|
|
563
|
-
* Take screenshot
|
|
564
|
-
* @private
|
|
565
|
-
*/
|
|
566
|
-
async screenshot(outputPath, projectDir, browserKey, options = {}) {
|
|
567
|
-
const page = await this.getPage(browserKey);
|
|
568
|
-
|
|
569
|
-
try {
|
|
570
|
-
const fullPath = projectDir ? path.resolve(projectDir, outputPath) : path.resolve(outputPath);
|
|
571
|
-
|
|
572
|
-
// Ensure directory exists
|
|
573
|
-
const dir = path.dirname(fullPath);
|
|
574
|
-
await fs.mkdir(dir, { recursive: true });
|
|
575
|
-
|
|
576
|
-
const screenshotOptions = {
|
|
577
|
-
path: fullPath,
|
|
578
|
-
type: 'png'
|
|
579
|
-
};
|
|
580
|
-
|
|
581
|
-
if (options.fullPage) {
|
|
582
|
-
screenshotOptions.fullPage = true;
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
await page.screenshot(screenshotOptions);
|
|
586
|
-
|
|
587
|
-
const stats = await fs.stat(fullPath);
|
|
588
|
-
|
|
589
|
-
if (stats.size > this.maxScreenshotSize) {
|
|
590
|
-
throw new Error(`Screenshot too large: ${stats.size} bytes (max ${this.maxScreenshotSize})`);
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
return {
|
|
594
|
-
success: true,
|
|
595
|
-
action: 'screenshot',
|
|
596
|
-
outputPath: path.relative(projectDir || process.cwd(), fullPath),
|
|
597
|
-
size: stats.size,
|
|
598
|
-
fullPage: !!options.fullPage,
|
|
599
|
-
message: `Screenshot saved: ${outputPath}`
|
|
600
|
-
};
|
|
601
|
-
|
|
602
|
-
} catch (error) {
|
|
603
|
-
throw new Error(`Screenshot failed: ${error.message}`);
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
/**
|
|
608
|
-
* Extract data from elements
|
|
609
|
-
* @private
|
|
610
|
-
*/
|
|
611
|
-
async extract(selector, attribute, browserKey) {
|
|
612
|
-
const page = await this.getPage(browserKey);
|
|
613
|
-
|
|
614
|
-
try {
|
|
615
|
-
await page.waitForSelector(selector, { timeout: 5000 });
|
|
616
|
-
|
|
617
|
-
let data;
|
|
618
|
-
if (attribute === 'text') {
|
|
619
|
-
data = await page.$eval(selector, el => el.textContent.trim());
|
|
620
|
-
} else {
|
|
621
|
-
data = await page.$eval(selector, (el, attr) => el.getAttribute(attr), attribute);
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
return {
|
|
625
|
-
success: true,
|
|
626
|
-
action: 'extract',
|
|
627
|
-
selector,
|
|
628
|
-
attribute,
|
|
629
|
-
data,
|
|
630
|
-
message: `Extracted ${attribute} from ${selector}`
|
|
631
|
-
};
|
|
632
|
-
|
|
633
|
-
} catch (error) {
|
|
634
|
-
throw new Error(`Extract failed on ${selector}: ${error.message}`);
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
/**
|
|
639
|
-
* Scroll page or element
|
|
640
|
-
* @private
|
|
641
|
-
*/
|
|
642
|
-
async scroll(action, browserKey) {
|
|
643
|
-
const page = await this.getPage(browserKey);
|
|
644
|
-
|
|
645
|
-
try {
|
|
646
|
-
const { direction, pixels = 300, selector } = action;
|
|
647
|
-
|
|
648
|
-
if (selector) {
|
|
649
|
-
// Scroll specific element
|
|
650
|
-
await page.evaluate((sel, dir, px) => {
|
|
651
|
-
const element = document.querySelector(sel);
|
|
652
|
-
if (element) {
|
|
653
|
-
if (dir === 'down') element.scrollTop += px;
|
|
654
|
-
else if (dir === 'up') element.scrollTop -= px;
|
|
655
|
-
else if (dir === 'right') element.scrollLeft += px;
|
|
656
|
-
else if (dir === 'left') element.scrollLeft -= px;
|
|
657
|
-
}
|
|
658
|
-
}, selector, direction, pixels);
|
|
659
|
-
} else {
|
|
660
|
-
// Scroll page
|
|
661
|
-
await page.evaluate((dir, px) => {
|
|
662
|
-
if (dir === 'down') window.scrollBy(0, px);
|
|
663
|
-
else if (dir === 'up') window.scrollBy(0, -px);
|
|
664
|
-
else if (dir === 'right') window.scrollBy(px, 0);
|
|
665
|
-
else if (dir === 'left') window.scrollBy(-px, 0);
|
|
666
|
-
}, direction, pixels);
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
return {
|
|
670
|
-
success: true,
|
|
671
|
-
action: 'scroll',
|
|
672
|
-
direction,
|
|
673
|
-
pixels,
|
|
674
|
-
selector: selector || 'page',
|
|
675
|
-
message: `Scrolled ${direction} by ${pixels}px`
|
|
676
|
-
};
|
|
677
|
-
|
|
678
|
-
} catch (error) {
|
|
679
|
-
throw new Error(`Scroll failed: ${error.message}`);
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
/**
|
|
684
|
-
* Get or create browser instance
|
|
685
|
-
* @private
|
|
686
|
-
*/
|
|
687
|
-
async getBrowser(browserKey) {
|
|
688
|
-
if (this.browserInstances.has(browserKey)) {
|
|
689
|
-
const instance = this.browserInstances.get(browserKey);
|
|
690
|
-
if (!instance.browser.isConnected()) {
|
|
691
|
-
this.browserInstances.delete(browserKey);
|
|
692
|
-
} else {
|
|
693
|
-
return instance.browser;
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
const browser = await puppeteer.launch({
|
|
698
|
-
headless: this.browserConfig.headless,
|
|
699
|
-
args: [
|
|
700
|
-
'--no-sandbox',
|
|
701
|
-
'--disable-setuid-sandbox',
|
|
702
|
-
'--disable-dev-shm-usage',
|
|
703
|
-
'--disable-gpu'
|
|
704
|
-
]
|
|
705
|
-
});
|
|
706
|
-
|
|
707
|
-
const page = await browser.newPage();
|
|
708
|
-
await page.setViewport(this.browserConfig.viewport);
|
|
709
|
-
await page.setUserAgent(this.browserConfig.userAgent);
|
|
710
|
-
|
|
711
|
-
this.browserInstances.set(browserKey, {
|
|
712
|
-
browser,
|
|
713
|
-
page,
|
|
714
|
-
created: Date.now()
|
|
715
|
-
});
|
|
716
|
-
|
|
717
|
-
// Auto-cleanup after 10 minutes of inactivity
|
|
718
|
-
setTimeout(() => {
|
|
719
|
-
this.cleanupBrowser(browserKey);
|
|
720
|
-
}, 10 * 60 * 1000);
|
|
721
|
-
|
|
722
|
-
return browser;
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
/**
|
|
726
|
-
* Get page instance
|
|
727
|
-
* @private
|
|
728
|
-
*/
|
|
729
|
-
async getPage(browserKey) {
|
|
730
|
-
await this.getBrowser(browserKey);
|
|
731
|
-
return this.browserInstances.get(browserKey).page;
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
/**
|
|
735
|
-
* Close browser instance
|
|
736
|
-
* @private
|
|
737
|
-
*/
|
|
738
|
-
async closeBrowser(browserKey) {
|
|
739
|
-
const instance = this.browserInstances.get(browserKey);
|
|
740
|
-
|
|
741
|
-
if (instance) {
|
|
742
|
-
try {
|
|
743
|
-
await instance.browser.close();
|
|
744
|
-
this.browserInstances.delete(browserKey);
|
|
745
|
-
|
|
746
|
-
return {
|
|
747
|
-
success: true,
|
|
748
|
-
action: 'close',
|
|
749
|
-
browserKey,
|
|
750
|
-
message: 'Browser instance closed'
|
|
751
|
-
};
|
|
752
|
-
} catch (error) {
|
|
753
|
-
throw new Error(`Failed to close browser: ${error.message}`);
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
return {
|
|
758
|
-
success: true,
|
|
759
|
-
action: 'close',
|
|
760
|
-
browserKey,
|
|
761
|
-
message: 'Browser instance not found (already closed)'
|
|
762
|
-
};
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
/**
|
|
766
|
-
* Cleanup browser instance
|
|
767
|
-
* @private
|
|
768
|
-
*/
|
|
769
|
-
async cleanupBrowser(browserKey) {
|
|
770
|
-
const instance = this.browserInstances.get(browserKey);
|
|
771
|
-
|
|
772
|
-
if (instance) {
|
|
773
|
-
try {
|
|
774
|
-
await instance.browser.close();
|
|
775
|
-
} catch (error) {
|
|
776
|
-
// Ignore cleanup errors
|
|
777
|
-
} finally {
|
|
778
|
-
this.browserInstances.delete(browserKey);
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
/**
|
|
784
|
-
* Check if URL is allowed
|
|
785
|
-
* @private
|
|
786
|
-
*/
|
|
787
|
-
isAllowedUrl(url) {
|
|
788
|
-
try {
|
|
789
|
-
const urlObj = new URL(url);
|
|
790
|
-
const hostname = urlObj.hostname.toLowerCase();
|
|
791
|
-
|
|
792
|
-
// Check blocked domains
|
|
793
|
-
if (this.blockedDomains.some(blocked => hostname.includes(blocked.toLowerCase()))) {
|
|
794
|
-
return false;
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
// Check allowed domains if specified
|
|
798
|
-
if (this.allowedDomains && this.allowedDomains.length > 0) {
|
|
799
|
-
return this.allowedDomains.some(allowed => hostname.includes(allowed.toLowerCase()));
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
return true;
|
|
803
|
-
} catch {
|
|
804
|
-
return false;
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
/**
|
|
809
|
-
* Add operation to history
|
|
810
|
-
* @private
|
|
811
|
-
*/
|
|
812
|
-
addToHistory(action, result, agentId) {
|
|
813
|
-
const historyEntry = {
|
|
814
|
-
timestamp: new Date().toISOString(),
|
|
815
|
-
agentId,
|
|
816
|
-
action: action.type,
|
|
817
|
-
selector: action.selector || action.url,
|
|
818
|
-
success: result.success,
|
|
819
|
-
loadTime: result.loadTime || 0
|
|
820
|
-
};
|
|
821
|
-
|
|
822
|
-
this.operationHistory.push(historyEntry);
|
|
823
|
-
|
|
824
|
-
// Keep only last 100 entries
|
|
825
|
-
if (this.operationHistory.length > 100) {
|
|
826
|
-
this.operationHistory = this.operationHistory.slice(-100);
|
|
827
|
-
}
|
|
828
|
-
}
|
|
829
|
-
|
|
830
|
-
/**
|
|
831
|
-
* Get supported actions for this tool
|
|
832
|
-
* @returns {Array<string>} Array of supported action names
|
|
833
|
-
*/
|
|
834
|
-
getSupportedActions() {
|
|
835
|
-
return ['navigate', 'click', 'type', 'wait', 'screenshot', 'extract', 'scroll', 'close'];
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
/**
|
|
839
|
-
* Get parameter schema for validation
|
|
840
|
-
* @returns {Object} Parameter schema
|
|
841
|
-
*/
|
|
842
|
-
getParameterSchema() {
|
|
843
|
-
return {
|
|
844
|
-
type: 'object',
|
|
845
|
-
properties: {
|
|
846
|
-
actions: {
|
|
847
|
-
type: 'array',
|
|
848
|
-
minItems: 1,
|
|
849
|
-
items: {
|
|
850
|
-
type: 'object',
|
|
851
|
-
properties: {
|
|
852
|
-
type: {
|
|
853
|
-
type: 'string',
|
|
854
|
-
enum: this.getSupportedActions()
|
|
855
|
-
},
|
|
856
|
-
url: { type: 'string' },
|
|
857
|
-
selector: { type: 'string' },
|
|
858
|
-
text: { type: 'string' },
|
|
859
|
-
outputPath: { type: 'string' },
|
|
860
|
-
waitTime: { type: 'integer' },
|
|
861
|
-
waitSelector: { type: 'string' },
|
|
862
|
-
attribute: { type: 'string' },
|
|
863
|
-
direction: { type: 'string' },
|
|
864
|
-
pixels: { type: 'integer' }
|
|
865
|
-
},
|
|
866
|
-
required: ['type']
|
|
867
|
-
}
|
|
868
|
-
}
|
|
869
|
-
},
|
|
870
|
-
required: ['actions']
|
|
871
|
-
};
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
/**
|
|
875
|
-
* Resource cleanup
|
|
876
|
-
* @param {string} operationId - Operation identifier
|
|
877
|
-
*/
|
|
878
|
-
async cleanup(operationId) {
|
|
879
|
-
// Close all browser instances
|
|
880
|
-
for (const [browserKey] of this.browserInstances) {
|
|
881
|
-
await this.cleanupBrowser(browserKey);
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
/**
|
|
886
|
-
* Get operation history for debugging
|
|
887
|
-
* @returns {Array} Operation history
|
|
888
|
-
*/
|
|
889
|
-
getOperationHistory(agentId = null) {
|
|
890
|
-
if (agentId) {
|
|
891
|
-
return this.operationHistory.filter(entry => entry.agentId === agentId);
|
|
892
|
-
}
|
|
893
|
-
return [...this.operationHistory];
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
export default BrowserTool;
|