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
|
@@ -7,17 +7,31 @@
|
|
|
7
7
|
*
|
|
8
8
|
* NOTE: These tests require network access and a working Puppeteer install.
|
|
9
9
|
* They are slower (~60s total) and are tagged for separate runs.
|
|
10
|
+
* Skipped on WSL/headless Linux (no display server for Chromium).
|
|
10
11
|
*
|
|
11
|
-
* Run with: npm test
|
|
12
|
+
* Run with: npm run test:e2e
|
|
12
13
|
*/
|
|
13
14
|
|
|
14
15
|
import { describe, test, expect, beforeAll, afterAll } from '@jest/globals';
|
|
16
|
+
import os from 'os';
|
|
17
|
+
import fs from 'fs';
|
|
18
|
+
|
|
19
|
+
// Skip on WSL (no display) or when SKIP_BROWSER_TESTS is set
|
|
20
|
+
const isWSL = (() => {
|
|
21
|
+
try {
|
|
22
|
+
return os.platform() === 'linux' && fs.readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft');
|
|
23
|
+
} catch { return false; }
|
|
24
|
+
})();
|
|
25
|
+
const skipBrowser = isWSL || process.env.SKIP_BROWSER_TESTS === 'true';
|
|
26
|
+
|
|
27
|
+
const describeIfBrowser = skipBrowser ? describe.skip : describe;
|
|
15
28
|
|
|
16
29
|
let WebTool;
|
|
17
30
|
let wt;
|
|
18
31
|
const silentLogger = { info() {}, warn() {}, error() {}, debug() {} };
|
|
19
32
|
|
|
20
33
|
beforeAll(async () => {
|
|
34
|
+
if (skipBrowser) return;
|
|
21
35
|
const mod = await import('../../tools/webTool.js');
|
|
22
36
|
WebTool = mod.default;
|
|
23
37
|
wt = new WebTool({ logger: silentLogger });
|
|
@@ -29,7 +43,7 @@ afterAll(async () => {
|
|
|
29
43
|
|
|
30
44
|
// ─── HTTP Status Detection ──────────────────────────────────────────────────
|
|
31
45
|
|
|
32
|
-
|
|
46
|
+
describeIfBrowser('HTTP status detection', () => {
|
|
33
47
|
test('fetch valid page returns success with HTTP 200', async () => {
|
|
34
48
|
const result = await wt.execute(
|
|
35
49
|
{ operation: 'fetch', url: 'https://example.com', formats: ['title'] },
|
|
@@ -63,7 +77,7 @@ describe('HTTP status detection', () => {
|
|
|
63
77
|
|
|
64
78
|
// ─── Selector Pre-Validation ─────────────────────────────────────────────────
|
|
65
79
|
|
|
66
|
-
|
|
80
|
+
describeIfBrowser('Selector pre-validation', () => {
|
|
67
81
|
test('click on non-existent selector returns actionable error', async () => {
|
|
68
82
|
const result = await wt.execute({
|
|
69
83
|
operation: 'interactive',
|
|
@@ -174,7 +188,7 @@ describe('Selector pre-validation', () => {
|
|
|
174
188
|
|
|
175
189
|
// ─── URL Validation in Interactive ───────────────────────────────────────────
|
|
176
190
|
|
|
177
|
-
|
|
191
|
+
describeIfBrowser('URL validation in interactive actions', () => {
|
|
178
192
|
test('navigate to invalid URL returns error without crashing', async () => {
|
|
179
193
|
const result = await wt.execute({
|
|
180
194
|
operation: 'interactive',
|
|
@@ -212,7 +226,7 @@ describe('URL validation in interactive actions', () => {
|
|
|
212
226
|
|
|
213
227
|
// ─── Wait-for Timeout Feedback ───────────────────────────────────────────────
|
|
214
228
|
|
|
215
|
-
|
|
229
|
+
describeIfBrowser('Wait-for timeout feedback', () => {
|
|
216
230
|
test('wait-for non-existent element returns timeout error with context', async () => {
|
|
217
231
|
const result = await wt.execute({
|
|
218
232
|
operation: 'interactive',
|
|
@@ -253,7 +267,7 @@ describe('Wait-for timeout feedback', () => {
|
|
|
253
267
|
|
|
254
268
|
// ─── Successful Operations ───────────────────────────────────────────────────
|
|
255
269
|
|
|
256
|
-
|
|
270
|
+
describeIfBrowser('Successful operations', () => {
|
|
257
271
|
test('extract-text on existing element returns content', async () => {
|
|
258
272
|
const result = await wt.execute({
|
|
259
273
|
operation: 'interactive',
|
|
@@ -329,7 +343,7 @@ describe('Successful operations', () => {
|
|
|
329
343
|
|
|
330
344
|
// ─── Search ──────────────────────────────────────────────────────────────────
|
|
331
345
|
|
|
332
|
-
|
|
346
|
+
describeIfBrowser('Search operations', () => {
|
|
333
347
|
test('search with valid query returns results', async () => {
|
|
334
348
|
const result = await wt.execute(
|
|
335
349
|
{ operation: 'search', query: 'javascript MDN', engine: 'duckduckgo', maxResults: 3 },
|
|
@@ -355,7 +369,7 @@ describe('Search operations', () => {
|
|
|
355
369
|
|
|
356
370
|
// ─── Multi-Action Chains ─────────────────────────────────────────────────────
|
|
357
371
|
|
|
358
|
-
|
|
372
|
+
describeIfBrowser('Multi-action chains', () => {
|
|
359
373
|
test('chain of actions reports per-action success/failure', async () => {
|
|
360
374
|
const result = await wt.execute({
|
|
361
375
|
operation: 'interactive',
|
|
@@ -409,7 +423,7 @@ describe('Multi-action chains', () => {
|
|
|
409
423
|
|
|
410
424
|
// ─── Tab Reuse ───────────────────────────────────────────────────────────────
|
|
411
425
|
|
|
412
|
-
|
|
426
|
+
describeIfBrowser('Tab reuse', () => {
|
|
413
427
|
test('reusing existing tab preserves session and returns reused flag', async () => {
|
|
414
428
|
// First: open tab
|
|
415
429
|
await wt.execute({
|
|
@@ -441,7 +455,7 @@ describe('Tab reuse', () => {
|
|
|
441
455
|
|
|
442
456
|
// ─── JS Error & Network Failure Detection ────────────────────────────────────
|
|
443
457
|
|
|
444
|
-
|
|
458
|
+
describeIfBrowser('JS error and network failure detection', () => {
|
|
445
459
|
test('JS errors on page are captured in pageErrors tracker', async () => {
|
|
446
460
|
// Open tab first
|
|
447
461
|
await wt.execute({
|
|
@@ -518,7 +532,7 @@ describe('JS error and network failure detection', () => {
|
|
|
518
532
|
|
|
519
533
|
// ─── Result Structure ────────────────────────────────────────────────────────
|
|
520
534
|
|
|
521
|
-
|
|
535
|
+
describeIfBrowser('Result structure and data consistency', () => {
|
|
522
536
|
test('fetch result has required fields', async () => {
|
|
523
537
|
const result = await wt.execute(
|
|
524
538
|
{ operation: 'fetch', url: 'https://example.com', formats: ['title', 'text'] },
|
package/src/tools/imageTool.js
CHANGED
|
@@ -479,13 +479,33 @@ export class ImageTool extends BaseTool {
|
|
|
479
479
|
let imageUrl;
|
|
480
480
|
let isTemporary = false;
|
|
481
481
|
|
|
482
|
+
this.logger?.info('Image generation result', {
|
|
483
|
+
jobId: job.jobId,
|
|
484
|
+
savedToDisk: result.savedToDisk,
|
|
485
|
+
resolvedOutputPath: result.resolvedOutputPath,
|
|
486
|
+
temporaryUrl: result.temporaryUrl?.substring(0, 80),
|
|
487
|
+
downloadError: result.downloadError,
|
|
488
|
+
isBase64Response: result.isBase64Response
|
|
489
|
+
});
|
|
490
|
+
|
|
482
491
|
if (result.savedToDisk && result.resolvedOutputPath) {
|
|
483
492
|
// Image was saved successfully - use our server endpoint
|
|
484
493
|
imageUrl = this._convertToWebUrl(result.resolvedOutputPath, job.sessionId);
|
|
494
|
+
this.logger?.info('Using local server URL for image', { imageUrl });
|
|
485
495
|
} else if (result.temporaryUrl) {
|
|
486
496
|
// Download failed - use temporary AI-generated URL (expires in ~1 hour)
|
|
487
497
|
imageUrl = result.temporaryUrl;
|
|
488
498
|
isTemporary = true;
|
|
499
|
+
this.logger?.warn('Using temporary AI URL for image (local save failed)', {
|
|
500
|
+
imageUrl: imageUrl.substring(0, 80),
|
|
501
|
+
downloadError: result.downloadError
|
|
502
|
+
});
|
|
503
|
+
} else {
|
|
504
|
+
this.logger?.error('No image URL available - neither local save nor temporary URL', {
|
|
505
|
+
jobId: job.jobId,
|
|
506
|
+
savedToDisk: result.savedToDisk,
|
|
507
|
+
hasTemporaryUrl: !!result.temporaryUrl
|
|
508
|
+
});
|
|
489
509
|
}
|
|
490
510
|
|
|
491
511
|
global.loxiaWebServer.broadcastToSession(job.sessionId, {
|
|
@@ -788,11 +808,19 @@ export class ImageTool extends BaseTool {
|
|
|
788
808
|
|
|
789
809
|
try {
|
|
790
810
|
if (b64Json) {
|
|
791
|
-
// Flux response: Save base64 directly to disk
|
|
792
|
-
this.logger?.info(
|
|
811
|
+
// Flux/GPT-Image response: Save base64 directly to disk
|
|
812
|
+
this.logger?.info(`Saving base64 image to disk: ${resolvedOutputPath}`);
|
|
793
813
|
const imageBuffer = Buffer.from(b64Json, 'base64');
|
|
794
814
|
await fs.writeFile(resolvedOutputPath, imageBuffer);
|
|
795
|
-
|
|
815
|
+
|
|
816
|
+
// Verify the file was actually written
|
|
817
|
+
const stat = await fs.stat(resolvedOutputPath);
|
|
818
|
+
if (stat.size > 0) {
|
|
819
|
+
savedToDisk = true;
|
|
820
|
+
this.logger?.info(`Image saved successfully: ${resolvedOutputPath} (${stat.size} bytes)`);
|
|
821
|
+
} else {
|
|
822
|
+
this.logger?.warn(`Image file is empty after write: ${resolvedOutputPath}`);
|
|
823
|
+
}
|
|
796
824
|
|
|
797
825
|
// For web display, we'll use our local server endpoint (set below)
|
|
798
826
|
displayUrl = null; // Will be converted to web URL later
|
|
@@ -800,7 +828,15 @@ export class ImageTool extends BaseTool {
|
|
|
800
828
|
// URL response: Download from URL
|
|
801
829
|
this.logger?.info(`Downloading image from URL: ${imageUrl.substring(0, 50)}...`);
|
|
802
830
|
await this._downloadImage(imageUrl, resolvedOutputPath);
|
|
803
|
-
|
|
831
|
+
|
|
832
|
+
// Verify the file was actually written
|
|
833
|
+
const stat = await fs.stat(resolvedOutputPath);
|
|
834
|
+
if (stat.size > 0) {
|
|
835
|
+
savedToDisk = true;
|
|
836
|
+
this.logger?.info(`Image downloaded successfully: ${resolvedOutputPath} (${stat.size} bytes)`);
|
|
837
|
+
} else {
|
|
838
|
+
this.logger?.warn(`Downloaded image file is empty: ${resolvedOutputPath}`);
|
|
839
|
+
}
|
|
804
840
|
displayUrl = imageUrl;
|
|
805
841
|
}
|
|
806
842
|
|
|
@@ -811,7 +847,7 @@ export class ImageTool extends BaseTool {
|
|
|
811
847
|
} catch (error) {
|
|
812
848
|
// Save failed, but we might still have a temporary URL
|
|
813
849
|
downloadError = error.message;
|
|
814
|
-
this.logger?.
|
|
850
|
+
this.logger?.error(`Failed to save image to disk at ${resolvedOutputPath}: ${error.message}`);
|
|
815
851
|
|
|
816
852
|
if (!imageUrl) {
|
|
817
853
|
// No URL fallback for Flux - this is a real failure
|
package/src/tools/webTool.js
CHANGED
|
@@ -9,18 +9,13 @@
|
|
|
9
9
|
* - Screenshot capture and AI-powered analysis
|
|
10
10
|
* - Mouse and keyboard event simulation
|
|
11
11
|
*
|
|
12
|
-
* NOTE: This tool replaces the deprecated BrowserTool (December 2024).
|
|
13
|
-
* WebTool provides equivalent functionality with a singleton browser instance
|
|
14
|
-
* architecture for better resource management.
|
|
15
|
-
*
|
|
16
12
|
* ============================================================================
|
|
17
|
-
* TODO: FEATURES TO ADD
|
|
13
|
+
* TODO: FEATURES TO ADD
|
|
18
14
|
* ============================================================================
|
|
19
15
|
*
|
|
20
16
|
* TODO 1: TIME-BASED WAIT ACTION
|
|
21
17
|
* -----------------------------------------------------------------------------
|
|
22
18
|
* Add a time-based wait capability alongside the existing 'wait-for-selector'.
|
|
23
|
-
* The deprecated BrowserTool supported: { "action": "wait", "waitTime": 3000 }
|
|
24
19
|
*
|
|
25
20
|
* Implementation details:
|
|
26
21
|
* - Add new action type: 'wait' or 'delay' (distinct from 'wait-for-selector')
|
|
@@ -46,8 +41,7 @@
|
|
|
46
41
|
* TODO 2: IMPROVED TYPE ACTION WITH ELEMENT WAITING AND CLEARING
|
|
47
42
|
* -----------------------------------------------------------------------------
|
|
48
43
|
* Enhance the 'type' action to automatically wait for the element and optionally
|
|
49
|
-
* clear existing content before typing.
|
|
50
|
-
* handling for form inputs.
|
|
44
|
+
* clear existing content before typing.
|
|
51
45
|
*
|
|
52
46
|
* Implementation details:
|
|
53
47
|
* - Before typing, wait for the selector to be visible (with configurable timeout)
|
|
@@ -279,7 +273,7 @@ First FETCH the login page to identify form selectors, then authenticate:
|
|
|
279
273
|
|
|
280
274
|
1. SEARCH - Search the web
|
|
281
275
|
\`\`\`json
|
|
282
|
-
{"toolId": "web", "operation": "search", "query": "search terms", "engine": "
|
|
276
|
+
{"toolId": "web", "operation": "search", "query": "search terms", "engine": "duckduckgo", "maxResults": 10}
|
|
283
277
|
\`\`\`
|
|
284
278
|
|
|
285
279
|
2. FETCH - Get page content (public pages only)
|
|
@@ -404,7 +398,7 @@ If blocked (CAPTCHA, access denied), use stealthLevel: "maximum" (visible browse
|
|
|
404
398
|
switch (params.operation) {
|
|
405
399
|
case 'search':
|
|
406
400
|
params.query = TagParser.extractContent(content, 'query')[0]?.trim();
|
|
407
|
-
params.engine = TagParser.extractContent(content, 'engine')[0]?.trim() || '
|
|
401
|
+
params.engine = TagParser.extractContent(content, 'engine')[0]?.trim() || 'duckduckgo';
|
|
408
402
|
const maxResults = TagParser.extractContent(content, 'max-results')[0]?.trim();
|
|
409
403
|
params.maxResults = maxResults ? parseInt(maxResults, 10) : 10;
|
|
410
404
|
// stealthLevel for search (default standard, use maximum if getting blocked)
|
|
@@ -666,7 +660,7 @@ If blocked (CAPTCHA, access denied), use stealthLevel: "maximum" (visible browse
|
|
|
666
660
|
switch (operation) {
|
|
667
661
|
case 'search':
|
|
668
662
|
result = await this.search(params.query, {
|
|
669
|
-
engine: params.engine || '
|
|
663
|
+
engine: params.engine || 'duckduckgo',
|
|
670
664
|
maxResults: params.maxResults || 10,
|
|
671
665
|
stealthLevel: effectiveStealthLevel,
|
|
672
666
|
agentId
|
|
@@ -719,23 +713,63 @@ If blocked (CAPTCHA, access denied), use stealthLevel: "maximum" (visible browse
|
|
|
719
713
|
// Flatten result for easier access (result.title instead of result.result.title)
|
|
720
714
|
// IMPORTANT: Respect the operation's own success flag — don't override it to true
|
|
721
715
|
const operationSuccess = result.success !== undefined ? result.success : true;
|
|
716
|
+
|
|
717
|
+
// Surface the FIRST actionable error from nested results so the agent
|
|
718
|
+
// always sees a top-level error/suggestion on failure — not just success:false.
|
|
719
|
+
let surfacedError = result.error;
|
|
720
|
+
let surfacedSuggestion = result.suggestion;
|
|
721
|
+
let surfacedWarning = result.warning;
|
|
722
|
+
if (!surfacedError && !operationSuccess && result.results) {
|
|
723
|
+
for (const tabResult of (Array.isArray(result.results) ? result.results : [])) {
|
|
724
|
+
// Check tab-level error first
|
|
725
|
+
if (tabResult.error && !surfacedError) {
|
|
726
|
+
surfacedError = tabResult.error;
|
|
727
|
+
if (tabResult.suggestion) surfacedSuggestion = tabResult.suggestion;
|
|
728
|
+
}
|
|
729
|
+
// Then check nested action results
|
|
730
|
+
if (tabResult.results && Array.isArray(tabResult.results)) {
|
|
731
|
+
for (const actionResult of tabResult.results) {
|
|
732
|
+
if (actionResult.success === false && actionResult.error && !surfacedError) {
|
|
733
|
+
surfacedError = actionResult.error;
|
|
734
|
+
if (actionResult.suggestion) surfacedSuggestion = actionResult.suggestion;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
if (!surfacedWarning && tabResult.warning) surfacedWarning = tabResult.warning;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
|
|
722
742
|
return {
|
|
723
743
|
success: operationSuccess,
|
|
724
744
|
operation,
|
|
725
745
|
toolUsed: 'web',
|
|
726
746
|
// Spread operation-specific data at top level
|
|
727
747
|
data: result,
|
|
748
|
+
// Always surface error/suggestion at top level so agent sees why it failed
|
|
749
|
+
...(surfacedError && { error: surfacedError }),
|
|
750
|
+
...(surfacedSuggestion && { suggestion: surfacedSuggestion }),
|
|
751
|
+
...(surfacedWarning && { warning: surfacedWarning }),
|
|
728
752
|
// Also keep common properties at top level for convenience
|
|
729
753
|
...(result.title !== undefined && { title: result.title }),
|
|
730
754
|
...(result.text !== undefined && { text: result.text }),
|
|
731
755
|
...(result.url !== undefined && { url: result.url }),
|
|
732
756
|
...(result.results !== undefined && { results: result.results }),
|
|
733
757
|
...(result.resultsCount !== undefined && { resultsCount: result.resultsCount }),
|
|
734
|
-
...(result.error !== undefined && { error: result.error }),
|
|
735
|
-
...(result.warning !== undefined && { warning: result.warning }),
|
|
736
758
|
...(result.httpStatus !== undefined && { httpStatus: result.httpStatus }),
|
|
737
|
-
...(result.
|
|
738
|
-
// Surface page-level
|
|
759
|
+
...(result.stealthNotice !== undefined && { stealthNotice: result.stealthNotice }),
|
|
760
|
+
// Surface diagnostics (page-level observations separate from tool success)
|
|
761
|
+
// Check both top-level and nested results for diagnostics
|
|
762
|
+
...((() => {
|
|
763
|
+
const diag = result.diagnostics ? { ...result.diagnostics } : {};
|
|
764
|
+
if (result.results) {
|
|
765
|
+
for (const tabResult of (Array.isArray(result.results) ? result.results : [])) {
|
|
766
|
+
if (tabResult.diagnostics) Object.assign(diag, tabResult.diagnostics);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
return Object.keys(diag).length > 0 ? { diagnostics: diag } : {};
|
|
770
|
+
})()),
|
|
771
|
+
...(result.notice && { notice: result.notice }),
|
|
772
|
+
// Legacy: also surface flat arrays for backwards compatibility
|
|
739
773
|
...(result.jsErrors?.length > 0 && { jsErrors: result.jsErrors }),
|
|
740
774
|
...(result.networkFailures?.length > 0 && { networkFailures: result.networkFailures }),
|
|
741
775
|
...(result.httpErrors?.length > 0 && { httpErrors: result.httpErrors })
|
|
@@ -777,11 +811,25 @@ If blocked (CAPTCHA, access denied), use stealthLevel: "maximum" (visible browse
|
|
|
777
811
|
suggestion = 'The page took too long to load. Check your internet connection or try again.';
|
|
778
812
|
}
|
|
779
813
|
|
|
814
|
+
// Detect bot detection / CAPTCHA failures — may be stealth-related
|
|
815
|
+
if (error.message.includes('CAPTCHA') || error.message.includes('blocked') ||
|
|
816
|
+
error.message.includes('403') || error.message.includes('Access Denied')) {
|
|
817
|
+
const currentLevel = this.browser?._stealthConfig?.stealthLevel || 'unknown';
|
|
818
|
+
if (currentLevel === 'standard') {
|
|
819
|
+
suggestion = (suggestion ? suggestion + ' ' : '') +
|
|
820
|
+
`Currently running at stealth level 'standard' (headless). This site may require stealthLevel: 'maximum' (visible browser) to bypass bot detection. Close open tabs first if needed.`;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
// Include current stealth context so agent can make informed decisions
|
|
825
|
+
const currentStealthLevel = this.browser?._stealthConfig?.stealthLevel || null;
|
|
826
|
+
|
|
780
827
|
return {
|
|
781
828
|
success: false,
|
|
782
829
|
operation,
|
|
783
830
|
error: enhancedError,
|
|
784
831
|
...(suggestion && { suggestion }),
|
|
832
|
+
...(currentStealthLevel && { currentStealthLevel }),
|
|
785
833
|
toolUsed: 'web'
|
|
786
834
|
};
|
|
787
835
|
}
|
|
@@ -893,7 +941,10 @@ If blocked (CAPTCHA, access denied), use stealthLevel: "maximum" (visible browse
|
|
|
893
941
|
// called it with the appropriate stealth level. This prevents accidentally
|
|
894
942
|
// resetting the browser to 'standard' stealth when 'maximum' is needed.
|
|
895
943
|
if (!this.browser || !this.browser.isConnected()) {
|
|
896
|
-
throw new Error(
|
|
944
|
+
throw new Error(
|
|
945
|
+
'Browser not initialized or connection lost. This can happen if another operation ' +
|
|
946
|
+
'changed the stealth level and restarted the browser. Retry the operation.'
|
|
947
|
+
);
|
|
897
948
|
}
|
|
898
949
|
|
|
899
950
|
const page = await createStealthPage(this.browser, {
|
|
@@ -916,7 +967,7 @@ If blocked (CAPTCHA, access denied), use stealthLevel: "maximum" (visible browse
|
|
|
916
967
|
* @returns {Promise<Object>} Search results
|
|
917
968
|
*/
|
|
918
969
|
async search(query, options = {}) {
|
|
919
|
-
const { engine = '
|
|
970
|
+
const { engine = 'duckduckgo', maxResults = 10, agentId, humanMode = true, stealthLevel = 'standard' } = options;
|
|
920
971
|
|
|
921
972
|
// Validate query
|
|
922
973
|
if (!query || typeof query !== 'string' || query.trim().length === 0) {
|
|
@@ -930,8 +981,17 @@ If blocked (CAPTCHA, access denied), use stealthLevel: "maximum" (visible browse
|
|
|
930
981
|
|
|
931
982
|
this.logger?.info('[WebTool] Performing web search', { query, engine, agentId, humanMode, stealthLevel });
|
|
932
983
|
|
|
933
|
-
//
|
|
934
|
-
|
|
984
|
+
// Reuse existing browser if running (preserve interactive/auth sessions)
|
|
985
|
+
let stealthDowngradeNotice = null;
|
|
986
|
+
if (this.browser && this.browser.isConnected()) {
|
|
987
|
+
const currentLevel = this.browser._stealthConfig?.stealthLevel || 'standard';
|
|
988
|
+
if (currentLevel !== stealthLevel) {
|
|
989
|
+
stealthDowngradeNotice = `Note: Running at stealth level '${currentLevel}' instead of requested '${stealthLevel}' to preserve active browser sessions. If this operation fails due to bot detection, close open tabs first and retry with stealthLevel: '${stealthLevel}'.`;
|
|
990
|
+
this.logger?.info('[WebTool] search: reusing existing browser', { requested: stealthLevel, actual: currentLevel });
|
|
991
|
+
}
|
|
992
|
+
} else {
|
|
993
|
+
await this.ensureBrowser({ stealthLevel });
|
|
994
|
+
}
|
|
935
995
|
|
|
936
996
|
// Create stealth page with optional human-like cursor
|
|
937
997
|
const { page, cursor } = await this.createPage({ humanMode });
|
|
@@ -998,6 +1058,10 @@ If blocked (CAPTCHA, access denied), use stealthLevel: "maximum" (visible browse
|
|
|
998
1058
|
results
|
|
999
1059
|
};
|
|
1000
1060
|
|
|
1061
|
+
if (stealthDowngradeNotice) {
|
|
1062
|
+
searchResult.stealthNotice = stealthDowngradeNotice;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1001
1065
|
// Warn when 0 results — may indicate selector mismatch or CAPTCHA
|
|
1002
1066
|
if (results.length === 0) {
|
|
1003
1067
|
searchResult.warning = 'Search returned 0 results. This may indicate: (1) no matching results exist, (2) the search engine blocked the request (CAPTCHA), or (3) the page layout changed and results could not be extracted.';
|
|
@@ -1031,8 +1095,17 @@ If blocked (CAPTCHA, access denied), use stealthLevel: "maximum" (visible browse
|
|
|
1031
1095
|
return { success: false, error: `Invalid URL format: "${url}". Must include protocol (e.g. https://example.com)` };
|
|
1032
1096
|
}
|
|
1033
1097
|
|
|
1034
|
-
//
|
|
1035
|
-
|
|
1098
|
+
// Reuse existing browser if running (preserve interactive/auth sessions)
|
|
1099
|
+
let stealthDowngradeNotice = null;
|
|
1100
|
+
if (this.browser && this.browser.isConnected()) {
|
|
1101
|
+
const currentLevel = this.browser._stealthConfig?.stealthLevel || 'standard';
|
|
1102
|
+
if (currentLevel !== stealthLevel) {
|
|
1103
|
+
stealthDowngradeNotice = `Note: Running at stealth level '${currentLevel}' instead of requested '${stealthLevel}' to preserve active browser sessions. If this operation fails due to bot detection, close open tabs first and retry with stealthLevel: '${stealthLevel}'.`;
|
|
1104
|
+
this.logger?.info('[WebTool] fetch: reusing existing browser', { requested: stealthLevel, actual: currentLevel });
|
|
1105
|
+
}
|
|
1106
|
+
} else {
|
|
1107
|
+
await this.ensureBrowser({ stealthLevel });
|
|
1108
|
+
}
|
|
1036
1109
|
|
|
1037
1110
|
this.logger?.info('Fetching web content', { url, formats, agentId, stealthLevel });
|
|
1038
1111
|
|
|
@@ -1057,10 +1130,11 @@ If blocked (CAPTCHA, access denied), use stealthLevel: "maximum" (visible browse
|
|
|
1057
1130
|
|
|
1058
1131
|
if (fetchStatus && fetchStatus >= 400) {
|
|
1059
1132
|
const errorResult = {
|
|
1060
|
-
success:
|
|
1133
|
+
success: true, // Fetch itself executed — page returned error status
|
|
1061
1134
|
url,
|
|
1062
1135
|
httpStatus: fetchStatus,
|
|
1063
|
-
|
|
1136
|
+
diagnostic: `Page returned HTTP ${fetchStatus} (${fetchStatus >= 500 ? 'server error' : fetchStatus === 404 ? 'page not found' : fetchStatus === 403 ? 'access forbidden' : 'client error'})`,
|
|
1137
|
+
warning: `HTTP ${fetchStatus} — the page loaded but returned an error status. Content may still be available.`
|
|
1064
1138
|
};
|
|
1065
1139
|
// Still try to get title for context
|
|
1066
1140
|
try { errorResult.title = await page.title(); } catch {}
|
|
@@ -1102,10 +1176,14 @@ If blocked (CAPTCHA, access denied), use stealthLevel: "maximum" (visible browse
|
|
|
1102
1176
|
|
|
1103
1177
|
this.logger?.info('Fetch completed', { url, formats, agentId });
|
|
1104
1178
|
|
|
1105
|
-
|
|
1179
|
+
const fetchResult = {
|
|
1106
1180
|
success: true,
|
|
1107
1181
|
...result
|
|
1108
1182
|
};
|
|
1183
|
+
if (stealthDowngradeNotice) {
|
|
1184
|
+
fetchResult.stealthNotice = stealthDowngradeNotice;
|
|
1185
|
+
}
|
|
1186
|
+
return fetchResult;
|
|
1109
1187
|
|
|
1110
1188
|
} finally {
|
|
1111
1189
|
try { await page.close(); } catch {}
|
|
@@ -1430,9 +1508,18 @@ If blocked (CAPTCHA, access denied), use stealthLevel: "maximum" (visible browse
|
|
|
1430
1508
|
// Check for existing session cookies
|
|
1431
1509
|
const existingSession = vault.getSession(normalizedSiteId);
|
|
1432
1510
|
|
|
1433
|
-
//
|
|
1434
|
-
//
|
|
1435
|
-
|
|
1511
|
+
// Reuse existing browser if one is running (preserve interactive sessions).
|
|
1512
|
+
// Only use the requested stealthLevel if no browser exists yet.
|
|
1513
|
+
let stealthDowngradeNotice = null;
|
|
1514
|
+
if (this.browser && this.browser.isConnected()) {
|
|
1515
|
+
const currentLevel = this.browser._stealthConfig?.stealthLevel || 'standard';
|
|
1516
|
+
if (currentLevel !== stealthLevel) {
|
|
1517
|
+
stealthDowngradeNotice = `Note: Authenticating at stealth level '${currentLevel}' instead of '${stealthLevel}' to preserve active browser sessions. If login fails due to bot detection, close open tabs first and retry with stealthLevel: '${stealthLevel}'.`;
|
|
1518
|
+
this.logger?.info('[WebTool] authenticate: reusing existing browser', { requested: stealthLevel, actual: currentLevel });
|
|
1519
|
+
}
|
|
1520
|
+
} else {
|
|
1521
|
+
await this.ensureBrowser({ stealthLevel });
|
|
1522
|
+
}
|
|
1436
1523
|
const { page, cursor } = await this.createPage({ humanMode: true });
|
|
1437
1524
|
|
|
1438
1525
|
try {
|
|
@@ -1458,7 +1545,8 @@ If blocked (CAPTCHA, access denied), use stealthLevel: "maximum" (visible browse
|
|
|
1458
1545
|
success: true,
|
|
1459
1546
|
message: `Already logged into ${credentials.name || normalizedSiteId} (session restored)`,
|
|
1460
1547
|
siteId: normalizedSiteId,
|
|
1461
|
-
method: 'session_restore'
|
|
1548
|
+
method: 'session_restore',
|
|
1549
|
+
...(stealthDowngradeNotice && { stealthNotice: stealthDowngradeNotice })
|
|
1462
1550
|
};
|
|
1463
1551
|
} catch {
|
|
1464
1552
|
// Session invalid, need to login
|
|
@@ -1600,7 +1688,8 @@ If blocked (CAPTCHA, access denied), use stealthLevel: "maximum" (visible browse
|
|
|
1600
1688
|
siteId: normalizedSiteId,
|
|
1601
1689
|
method: 'credentials',
|
|
1602
1690
|
tabName,
|
|
1603
|
-
tabKeptOpen: true
|
|
1691
|
+
tabKeptOpen: true,
|
|
1692
|
+
...(stealthDowngradeNotice && { stealthNotice: stealthDowngradeNotice })
|
|
1604
1693
|
};
|
|
1605
1694
|
}
|
|
1606
1695
|
|
|
@@ -1609,7 +1698,8 @@ If blocked (CAPTCHA, access denied), use stealthLevel: "maximum" (visible browse
|
|
|
1609
1698
|
success: true,
|
|
1610
1699
|
message: `Successfully logged into ${credentials.name || normalizedSiteId}`,
|
|
1611
1700
|
siteId: normalizedSiteId,
|
|
1612
|
-
method: 'credentials'
|
|
1701
|
+
method: 'credentials',
|
|
1702
|
+
...(stealthDowngradeNotice && { stealthNotice: stealthDowngradeNotice })
|
|
1613
1703
|
};
|
|
1614
1704
|
} else {
|
|
1615
1705
|
await page.close();
|
|
@@ -1692,10 +1782,11 @@ If blocked (CAPTCHA, access denied), use stealthLevel: "maximum" (visible browse
|
|
|
1692
1782
|
if (reuseNavStatus && reuseNavStatus >= 400) {
|
|
1693
1783
|
results.push({
|
|
1694
1784
|
action: 'navigate',
|
|
1695
|
-
success:
|
|
1785
|
+
success: true,
|
|
1696
1786
|
url: existingTab.page.url(),
|
|
1697
1787
|
httpStatus: reuseNavStatus,
|
|
1698
|
-
|
|
1788
|
+
diagnostic: `Page returned HTTP ${reuseNavStatus}`,
|
|
1789
|
+
warning: `HTTP ${reuseNavStatus} — page loaded but returned an error status. Tab is still usable.`
|
|
1699
1790
|
});
|
|
1700
1791
|
}
|
|
1701
1792
|
}
|
|
@@ -1726,17 +1817,28 @@ If blocked (CAPTCHA, access denied), use stealthLevel: "maximum" (visible browse
|
|
|
1726
1817
|
if (humanMode) await humanWait('action');
|
|
1727
1818
|
}
|
|
1728
1819
|
|
|
1729
|
-
const
|
|
1820
|
+
const failedActions = results.filter(r => r.success === false);
|
|
1821
|
+
const diagnosticActions = results.filter(r => r.diagnostic);
|
|
1822
|
+
const reusedJsErrors = WebTool._dedupeErrors((existingTab.pageErrors || []).map(e => e.message));
|
|
1823
|
+
const reusedNetFails = WebTool._dedupeErrors((existingTab.networkFailures || []).map(f => `${f.method} ${f.url} → ${f.errorText}`));
|
|
1824
|
+
|
|
1825
|
+
const diagnostics = {};
|
|
1826
|
+
if (reusedJsErrors.length > 0) diagnostics.jsErrors = reusedJsErrors;
|
|
1827
|
+
if (reusedNetFails.length > 0) diagnostics.networkFailures = reusedNetFails;
|
|
1828
|
+
if (diagnosticActions.length > 0) diagnostics.pageIssues = diagnosticActions.map(a => a.diagnostic);
|
|
1829
|
+
|
|
1730
1830
|
return {
|
|
1731
|
-
success:
|
|
1831
|
+
success: failedActions.length === 0,
|
|
1732
1832
|
tabName,
|
|
1733
1833
|
url: existingTab.page.url(),
|
|
1734
1834
|
actionsExecuted: results.length,
|
|
1735
1835
|
results,
|
|
1736
1836
|
reused: true,
|
|
1737
|
-
...(
|
|
1738
|
-
...(
|
|
1739
|
-
|
|
1837
|
+
...(failedActions.length > 0 && { warning: `${failedActions.length} of ${results.length} action(s) failed` }),
|
|
1838
|
+
...(diagnosticActions.length > 0 && !failedActions.length && {
|
|
1839
|
+
notice: `All actions executed successfully. ${diagnosticActions.length} page-level issue(s) detected — see diagnostics.`
|
|
1840
|
+
}),
|
|
1841
|
+
...(Object.keys(diagnostics).length > 0 && { diagnostics }),
|
|
1740
1842
|
...((existingTab.httpErrors || []).length > 0 && { httpErrors: WebTool._dedupeErrors(existingTab.httpErrors.map(e => `${e.method} ${e.url} → ${e.status}`)) })
|
|
1741
1843
|
};
|
|
1742
1844
|
}
|
|
@@ -1886,10 +1988,11 @@ If blocked (CAPTCHA, access denied), use stealthLevel: "maximum" (visible browse
|
|
|
1886
1988
|
if (openTabStatus && openTabStatus >= 400) {
|
|
1887
1989
|
results.push({
|
|
1888
1990
|
action: 'navigate',
|
|
1889
|
-
success:
|
|
1991
|
+
success: true,
|
|
1890
1992
|
url: tabInfo.url,
|
|
1891
1993
|
httpStatus: openTabStatus,
|
|
1892
|
-
|
|
1994
|
+
diagnostic: `Page returned HTTP ${openTabStatus}`,
|
|
1995
|
+
warning: `HTTP ${openTabStatus} — page loaded but returned an error status. Tab is still usable.`
|
|
1893
1996
|
});
|
|
1894
1997
|
}
|
|
1895
1998
|
}
|
|
@@ -1934,23 +2037,32 @@ If blocked (CAPTCHA, access denied), use stealthLevel: "maximum" (visible browse
|
|
|
1934
2037
|
}
|
|
1935
2038
|
}
|
|
1936
2039
|
|
|
1937
|
-
const
|
|
2040
|
+
const failedActions = results.filter(r => r.success === false);
|
|
2041
|
+
const diagnosticActions = results.filter(r => r.diagnostic);
|
|
1938
2042
|
// Summarize all page issues for the agent (deduplicated)
|
|
1939
2043
|
const allJsErrors = WebTool._dedupeErrors(pageErrors.map(e => e.message));
|
|
1940
2044
|
const allNetworkFails = WebTool._dedupeErrors(networkFailures.map(f => `${f.method} ${f.url} → ${f.errorText}`));
|
|
1941
2045
|
const allHttpErrs = WebTool._dedupeErrors(httpErrors.map(e => `${e.method} ${e.url} → ${e.status}`));
|
|
1942
2046
|
|
|
2047
|
+
// Collect diagnostics: page-level observations that aren't action failures
|
|
2048
|
+
const diagnostics = {};
|
|
2049
|
+
if (allJsErrors.length > 0) diagnostics.jsErrors = allJsErrors;
|
|
2050
|
+
if (allNetworkFails.length > 0) diagnostics.networkFailures = allNetworkFails;
|
|
2051
|
+
if (allHttpErrs.length > 0) diagnostics.httpErrors = allHttpErrs;
|
|
2052
|
+
if (diagnosticActions.length > 0) diagnostics.pageIssues = diagnosticActions.map(a => a.diagnostic);
|
|
2053
|
+
|
|
1943
2054
|
return {
|
|
1944
|
-
success:
|
|
2055
|
+
success: failedActions.length === 0,
|
|
1945
2056
|
tabName,
|
|
1946
2057
|
url: tabInfo.url,
|
|
1947
2058
|
actionsExecuted: results.length,
|
|
1948
2059
|
results,
|
|
1949
|
-
...(
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
2060
|
+
...(failedActions.length > 0 && { warning: `${failedActions.length} of ${results.length} action(s) failed` }),
|
|
2061
|
+
...(diagnosticActions.length > 0 && !failedActions.length && {
|
|
2062
|
+
notice: `All actions executed successfully. ${diagnosticActions.length} page-level issue(s) detected — see diagnostics.`
|
|
2063
|
+
}),
|
|
2064
|
+
// Surface diagnostics at top level for agent awareness
|
|
2065
|
+
...(Object.keys(diagnostics).length > 0 && { diagnostics })
|
|
1954
2066
|
};
|
|
1955
2067
|
|
|
1956
2068
|
} catch (error) {
|
|
@@ -2027,10 +2139,11 @@ If blocked (CAPTCHA, access denied), use stealthLevel: "maximum" (visible browse
|
|
|
2027
2139
|
}
|
|
2028
2140
|
if (navStatus && navStatus >= 400) {
|
|
2029
2141
|
return {
|
|
2030
|
-
success:
|
|
2142
|
+
success: true, // Navigation itself executed — page just returned an error status
|
|
2031
2143
|
url: tabInfo.url,
|
|
2032
2144
|
httpStatus: navStatus,
|
|
2033
|
-
|
|
2145
|
+
diagnostic: `Page returned HTTP ${navStatus} (${navStatus >= 500 ? 'server error' : navStatus === 404 ? 'page not found' : navStatus === 403 ? 'access forbidden' : 'client error'})`,
|
|
2146
|
+
warning: `HTTP ${navStatus} — the page loaded but returned an error status. The tab is still usable.`
|
|
2034
2147
|
};
|
|
2035
2148
|
}
|
|
2036
2149
|
return { success: true, url: tabInfo.url, httpStatus: navStatus };
|