@herbertgao/pi-extensions 2026.10.2 → 2026.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -12
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +8 -0
- package/node_modules/@herbertgao/pi-subagents/README.md +1 -1
- package/node_modules/@herbertgao/pi-subagents/package.json +4 -5
- package/node_modules/@herbertgao/pi-subagents/src/index.ts +1 -1
- package/node_modules/@herbertgao/pi-subagents/src/invocation-config.ts +1 -1
- package/node_modules/@herbertgao/pi-subagents/src/mention-clone.ts +48 -72
- package/node_modules/@herbertgao/pi-subagents/src/nested-tools.ts +1 -1
- package/node_modules/@herbertgao/pi-subagents/src/output-file.ts +15 -6
- package/node_modules/@herbertgao/pi-subagents/src/workflow/collisions.ts +4 -1
- package/node_modules/@herbertgao/pi-subagents/src/workflow/json-schema.ts +9 -8
- package/node_modules/@narumitw/pi-caffeinate/dist/index.ts +6 -1
- package/node_modules/@narumitw/pi-caffeinate/dist/index.ts.map +2 -2
- package/node_modules/@narumitw/pi-caffeinate/package.json +1 -1
- package/node_modules/@narumitw/pi-caffeinate/src/dbus-inhibit.ts +13 -1
- package/node_modules/pi-lens/CHANGELOG.md +95 -0
- package/node_modules/pi-lens/README.md +1 -0
- package/node_modules/pi-lens/dist/chunk-2FQ62SPM.js +83 -0
- package/node_modules/pi-lens/dist/{chunk-6P62QVEA.js → chunk-2UMYMRI3.js} +2 -2
- package/node_modules/pi-lens/dist/{chunk-O6TQT6RI.js → chunk-34OCDWOS.js} +1 -1
- package/node_modules/pi-lens/dist/{chunk-XK4CIILI.js → chunk-3FERWMCH.js} +26 -26
- package/node_modules/pi-lens/dist/{chunk-ZAWW3AF6.js → chunk-3JL6IFD7.js} +8 -8
- package/node_modules/pi-lens/dist/{chunk-OAXNDZJ7.js → chunk-3JSEWUWI.js} +8 -4
- package/node_modules/pi-lens/dist/{chunk-RPD5K5NC.js → chunk-3MRXIJ6I.js} +2 -2
- package/node_modules/pi-lens/dist/{chunk-IVP5KAB7.js → chunk-3P4PF2BX.js} +14 -14
- package/node_modules/pi-lens/dist/{chunk-5THXD6X5.js → chunk-3PNFWVHT.js} +2 -2
- package/node_modules/pi-lens/dist/{chunk-VD4JQCQC.js → chunk-3TTPKMEF.js} +37 -37
- package/node_modules/pi-lens/dist/{chunk-7F72PXY2.js → chunk-5JHXUETW.js} +3 -3
- package/node_modules/pi-lens/dist/{chunk-5ZEJHV35.js → chunk-64LU2OVH.js} +2 -2
- package/node_modules/pi-lens/dist/{chunk-ODEEOXPH.js → chunk-6B5I6ICN.js} +11 -11
- package/node_modules/pi-lens/dist/{chunk-5RXBNSW2.js → chunk-6P54TMWL.js} +16 -8
- package/node_modules/pi-lens/dist/{chunk-K6VYLB2U.js → chunk-6UYA642J.js} +12 -12
- package/node_modules/pi-lens/dist/{chunk-V7R425XG.js → chunk-6XX5HCLK.js} +4 -4
- package/node_modules/pi-lens/dist/{chunk-D6QS3U6M.js → chunk-7AXO3ZDF.js} +15 -15
- package/node_modules/pi-lens/dist/{chunk-YGVYKNSN.js → chunk-7BX5DWSA.js} +59 -12
- package/node_modules/pi-lens/dist/{chunk-N3YQJI6O.js → chunk-7ELY2CSM.js} +7 -4
- package/node_modules/pi-lens/dist/{chunk-AWE5TMPO.js → chunk-7M4T5N3V.js} +13 -13
- package/node_modules/pi-lens/dist/{chunk-AJ3QXTRQ.js → chunk-AFZYMAIV.js} +33 -33
- package/node_modules/pi-lens/dist/{chunk-AJXODZY6.js → chunk-ALQRYH6O.js} +12 -12
- package/node_modules/pi-lens/dist/{chunk-AJVLWNFN.js → chunk-AXKPQ6ZI.js} +5 -5
- package/node_modules/pi-lens/dist/{chunk-HWBZIGMJ.js → chunk-BHWHXMQ2.js} +8 -8
- package/node_modules/pi-lens/dist/{chunk-IXEBJSUE.js → chunk-BJF25SUG.js} +10 -10
- package/node_modules/pi-lens/dist/{chunk-GVXA6CCE.js → chunk-BNKLYOOO.js} +1 -1
- package/node_modules/pi-lens/dist/{chunk-T4ERT73Y.js → chunk-CBD2B5CP.js} +20 -20
- package/node_modules/pi-lens/dist/{chunk-O5WILGMI.js → chunk-CFYISHUW.js} +5 -5
- package/node_modules/pi-lens/dist/{chunk-EOKRQ3SA.js → chunk-CMU4RMJB.js} +1 -1
- package/node_modules/pi-lens/dist/{chunk-YSNFMJKN.js → chunk-CULQYFLU.js} +2 -2
- package/node_modules/pi-lens/dist/{chunk-ORTMY4Q4.js → chunk-D65GOCJB.js} +21 -14
- package/node_modules/pi-lens/dist/{chunk-NTUJEGDZ.js → chunk-D6YF5HKX.js} +2 -2
- package/node_modules/pi-lens/dist/{chunk-BRJKOBZP.js → chunk-DMS52BEP.js} +17 -6
- package/node_modules/pi-lens/dist/{chunk-NL5GLMFI.js → chunk-ELVWJYRV.js} +11 -11
- package/node_modules/pi-lens/dist/{chunk-4W2PLC4J.js → chunk-EUT3B22Y.js} +12 -12
- package/node_modules/pi-lens/dist/{chunk-GUOGVTCQ.js → chunk-F5VLZHUW.js} +1 -1
- package/node_modules/pi-lens/dist/{chunk-I7SPGOWI.js → chunk-FGALODG3.js} +1 -1
- package/node_modules/pi-lens/dist/{chunk-Q5U6FMDI.js → chunk-G3RLJYA2.js} +12 -6
- package/node_modules/pi-lens/dist/{chunk-FJNKANOS.js → chunk-GAYGGICG.js} +9 -9
- package/node_modules/pi-lens/dist/{chunk-HVUZXSWK.js → chunk-H2W2AXD3.js} +38 -40
- package/node_modules/pi-lens/dist/{chunk-VHQLPIRJ.js → chunk-H5EV3VMF.js} +2 -2
- package/node_modules/pi-lens/dist/{chunk-27BBHSZC.js → chunk-HREZQCT3.js} +3 -3
- package/node_modules/pi-lens/dist/{chunk-TT22N74J.js → chunk-HSIRMK2D.js} +12 -12
- package/node_modules/pi-lens/dist/{chunk-3I5QFT3N.js → chunk-IMSQR4WO.js} +6 -3
- package/node_modules/pi-lens/dist/{chunk-B3I2UUT4.js → chunk-IQZXOZ7S.js} +156 -32
- package/node_modules/pi-lens/dist/{chunk-RIISMHKN.js → chunk-IR6XFA5P.js} +14 -13
- package/node_modules/pi-lens/dist/{chunk-LNAKEO63.js → chunk-IUKPRZER.js} +4 -4
- package/node_modules/pi-lens/dist/{chunk-RUOG5D2C.js → chunk-IUR76K6A.js} +5 -5
- package/node_modules/pi-lens/dist/{chunk-TO6WL3GM.js → chunk-J3FZR3YY.js} +12 -2
- package/node_modules/pi-lens/dist/{chunk-Y4T27COV.js → chunk-J6DFZDFA.js} +4 -4
- package/node_modules/pi-lens/dist/{chunk-E4MAEDPM.js → chunk-J7WJZ6W7.js} +11 -11
- package/node_modules/pi-lens/dist/{chunk-52H5B5TC.js → chunk-JONGANYH.js} +30 -30
- package/node_modules/pi-lens/dist/{chunk-TGPXLY2J.js → chunk-KJCWXUUS.js} +35 -1
- package/node_modules/pi-lens/dist/{chunk-I3R7GKDR.js → chunk-KJN4IOEJ.js} +1 -1
- package/node_modules/pi-lens/dist/{chunk-RPD4ZSB7.js → chunk-KMGPUKFD.js} +12 -12
- package/node_modules/pi-lens/dist/{chunk-OQGFCZJ4.js → chunk-LD7WFTRX.js} +13 -13
- package/node_modules/pi-lens/dist/{chunk-DIULIWKU.js → chunk-LNOMA3MP.js} +3 -3
- package/node_modules/pi-lens/dist/{chunk-HHYAELLJ.js → chunk-MGIWSROG.js} +5 -5
- package/node_modules/pi-lens/dist/{chunk-YLF3PPT5.js → chunk-MQA2YBAH.js} +3 -3
- package/node_modules/pi-lens/dist/{chunk-TVN5N6GY.js → chunk-MTDRLSI7.js} +690 -186
- package/node_modules/pi-lens/dist/{chunk-DQ2NZ7C4.js → chunk-N2IRDBZI.js} +44 -6
- package/node_modules/pi-lens/dist/{chunk-AHDW3GPE.js → chunk-N77WFUL7.js} +22 -22
- package/node_modules/pi-lens/dist/{chunk-NXPS2L6U.js → chunk-N7YNJE5R.js} +7 -7
- package/node_modules/pi-lens/dist/{chunk-7FBF7NPR.js → chunk-NFXP47RV.js} +13 -12
- package/node_modules/pi-lens/dist/{chunk-UY752QSN.js → chunk-NJF2X5XF.js} +17 -17
- package/node_modules/pi-lens/dist/{chunk-WONERJTP.js → chunk-O7HZX7CA.js} +1 -1
- package/node_modules/pi-lens/dist/{chunk-AS44CFQ4.js → chunk-OC7LYAU5.js} +7 -7
- package/node_modules/pi-lens/dist/{chunk-4RERDEXR.js → chunk-OEX24ECI.js} +30 -30
- package/node_modules/pi-lens/dist/{chunk-6VCD4VKZ.js → chunk-OYOB3ZFG.js} +2 -2
- package/node_modules/pi-lens/dist/{chunk-IIXOAGHR.js → chunk-OYTMZXRF.js} +18 -15
- package/node_modules/pi-lens/dist/{chunk-ARFCXG7S.js → chunk-OZJINN4O.js} +2 -2
- package/node_modules/pi-lens/dist/{chunk-34U7PLGE.js → chunk-PCHDGUKT.js} +11 -11
- package/node_modules/pi-lens/dist/{chunk-VCSRSYLF.js → chunk-RJFED73B.js} +34 -36
- package/node_modules/pi-lens/dist/chunk-RTQNRM5X.js +27 -0
- package/node_modules/pi-lens/dist/{chunk-PAK6IDME.js → chunk-S6AMWKPC.js} +2 -2
- package/node_modules/pi-lens/dist/{chunk-U3VGR4VU.js → chunk-T4QZ6FEH.js} +4 -4
- package/node_modules/pi-lens/dist/{chunk-VN2AXLEX.js → chunk-T54VJRAD.js} +54 -12
- package/node_modules/pi-lens/dist/{chunk-ZMOL6RQC.js → chunk-TA5L5KWQ.js} +2 -2
- package/node_modules/pi-lens/dist/{chunk-JOLITGCC.js → chunk-TQFBZVCG.js} +1 -1
- package/node_modules/pi-lens/dist/{chunk-VDBPVIKD.js → chunk-U52SAGRM.js} +1 -1
- package/node_modules/pi-lens/dist/{chunk-LW6XKDZQ.js → chunk-UEAHAMEI.js} +284 -35
- package/node_modules/pi-lens/dist/{chunk-NMABWBZN.js → chunk-UGSMCQ4D.js} +1 -1
- package/node_modules/pi-lens/dist/{chunk-6QIUX4EP.js → chunk-USHG4DLH.js} +7 -7
- package/node_modules/pi-lens/dist/{chunk-LSMJ6KBE.js → chunk-V5MEBST3.js} +16 -16
- package/node_modules/pi-lens/dist/chunk-VGEVL5EQ.js +29 -0
- package/node_modules/pi-lens/dist/{chunk-47D2BO4S.js → chunk-VPWKF3GN.js} +10 -10
- package/node_modules/pi-lens/dist/{chunk-UK3CMEAL.js → chunk-VSMJK3ZJ.js} +1 -1
- package/node_modules/pi-lens/dist/{chunk-22AVIGXS.js → chunk-VYKKMYVT.js} +7 -7
- package/node_modules/pi-lens/dist/{chunk-OS32RNR2.js → chunk-VZHJS6DR.js} +15 -15
- package/node_modules/pi-lens/dist/{chunk-E2WFBRHM.js → chunk-WATC3IQR.js} +3 -3
- package/node_modules/pi-lens/dist/chunk-WPE5FPGR.js +54 -0
- package/node_modules/pi-lens/dist/{chunk-V5PXFSZK.js → chunk-WSEWKCXU.js} +4 -4
- package/node_modules/pi-lens/dist/{chunk-NKOUFPQF.js → chunk-WW5BLB74.js} +2 -2
- package/node_modules/pi-lens/dist/{chunk-PWFHBTSF.js → chunk-XGUL4SLQ.js} +2 -2
- package/node_modules/pi-lens/dist/{chunk-F3P7VQ7H.js → chunk-XHSCVSOL.js} +3 -3
- package/node_modules/pi-lens/dist/{chunk-DFVMIKMQ.js → chunk-YLN4K6WD.js} +45 -9
- package/node_modules/pi-lens/dist/{chunk-VNMT7C64.js → chunk-Z6BB4JLQ.js} +2 -2
- package/node_modules/pi-lens/dist/{chunk-NTHH2J74.js → chunk-Z7QQA2KT.js} +12 -12
- package/node_modules/pi-lens/dist/{chunk-F3AU2TMM.js → chunk-ZETYB3XG.js} +15 -15
- package/node_modules/pi-lens/dist/{chunk-XECLWQZN.js → chunk-ZMOMPX2Z.js} +12 -10
- package/node_modules/pi-lens/dist/{chunk-C2AUYXQH.js → chunk-ZOEYVXSV.js} +4 -4
- package/node_modules/pi-lens/dist/{chunk-TLGFBM3F.js → chunk-ZZUFZUQZ.js} +68 -64
- package/node_modules/pi-lens/dist/index.js +30113 -28398
- package/node_modules/pi-lens/dist/mcp/analyze-cli.js +8 -8
- package/node_modules/pi-lens/dist/mcp/cli.js +37 -37
- package/node_modules/pi-lens/dist/mcp/server.js +257 -158
- package/node_modules/pi-lens/dist/mcp/worker.js +55 -55
- package/node_modules/pi-lens/dist/probes/installer.js +19 -19
- package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +2 -2
- package/node_modules/pi-lens/docs/configuration.md +9 -2
- package/node_modules/pi-lens/docs/custom-rules.md +25 -2
- package/node_modules/pi-lens/docs/environment-variables.md +34 -6
- package/node_modules/pi-lens/docs/features.md +37 -1
- package/node_modules/pi-lens/docs/globalconfig.md +1 -1
- package/node_modules/pi-lens/docs/lsp-capability-matrix.md +2 -1
- package/node_modules/pi-lens/docs/lsp-idle-eviction.md +1 -1
- package/node_modules/pi-lens/docs/pi-lens-fixer.md +9 -5
- package/node_modules/pi-lens/docs/pi-lens-merge-policy.md +43 -1
- package/node_modules/pi-lens/docs/pi-lens-monitor.md +3 -1
- package/node_modules/pi-lens/docs/pi-lens-reviewer.md +4 -3
- package/node_modules/pi-lens/docs/schema/pi-lens-config-v1.json +530 -0
- package/node_modules/pi-lens/docs/servercapabilities.md +4 -1
- package/node_modules/pi-lens/docs/word-index.md +6 -0
- package/node_modules/pi-lens/package.json +1 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-identity-operator-on-literals-test.yml +12 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/throw-new-error-js-test.yml +2 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/throw-new-error-test.yml +2 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-identity-operator-on-literals.yml +20 -12
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/throw-new-error-js.yml +2 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/throw-new-error.yml +2 -2
- package/node_modules/pi-web-access/CHANGELOG.md +28 -0
- package/node_modules/pi-web-access/README.md +10 -6
- package/node_modules/pi-web-access/ceramic.ts +219 -0
- package/node_modules/pi-web-access/curator-page.ts +3 -1
- package/node_modules/pi-web-access/curator-server.ts +1 -0
- package/node_modules/pi-web-access/dist/index.js +846 -588
- package/node_modules/pi-web-access/dist/mcp-cli.js +725 -516
- package/node_modules/pi-web-access/gemini-search.ts +8 -4
- package/node_modules/pi-web-access/github-extract.ts +34 -2
- package/node_modules/pi-web-access/index.ts +72 -30
- package/node_modules/pi-web-access/openai-search.ts +3 -3
- package/node_modules/pi-web-access/package.json +2 -2
- package/node_modules/pi-web-access/page-query.ts +6 -9
- package/node_modules/pi-web-access/parallel-mcp.ts +2 -0
- package/node_modules/pi-web-access/query-rewrite.ts +2 -2
- package/node_modules/pi-web-access/storage.ts +49 -0
- package/node_modules/pi-web-access/summary-review.ts +7 -6
- package/node_modules/pi-web-access/utils.ts +21 -6
- package/node_modules/pi-web-access/web-tool-core.ts +1 -0
- package/package.json +7 -12
- package/node_modules/pi-lens/dist/chunk-54B42YRX.js +0 -27
- package/node_modules/pi-lens/dist/chunk-CGGAIP7J.js +0 -29
- package/node_modules/pi-lens/dist/chunk-HMFXILPV.js +0 -83
- package/node_modules/pi-lens/dist/chunk-T6D4Q4AQ.js +0 -54
- package/node_modules/pi-web-access/opencode-session-headers.ts +0 -24
- package/node_modules/remote-pi/LICENSE +0 -21
- package/node_modules/remote-pi/README.md +0 -675
- package/node_modules/remote-pi/dist/actions/handlers.d.ts +0 -122
- package/node_modules/remote-pi/dist/actions/handlers.js +0 -160
- package/node_modules/remote-pi/dist/actions/handlers.js.map +0 -1
- package/node_modules/remote-pi/dist/actions/registry.d.ts +0 -39
- package/node_modules/remote-pi/dist/actions/registry.js +0 -58
- package/node_modules/remote-pi/dist/actions/registry.js.map +0 -1
- package/node_modules/remote-pi/dist/bin/supervisord.d.ts +0 -2
- package/node_modules/remote-pi/dist/bin/supervisord.js +0 -86
- package/node_modules/remote-pi/dist/bin/supervisord.js.map +0 -1
- package/node_modules/remote-pi/dist/commands/builtin_mirror.d.ts +0 -58
- package/node_modules/remote-pi/dist/commands/builtin_mirror.js +0 -71
- package/node_modules/remote-pi/dist/commands/builtin_mirror.js.map +0 -1
- package/node_modules/remote-pi/dist/commands/list_commands.d.ts +0 -60
- package/node_modules/remote-pi/dist/commands/list_commands.js +0 -73
- package/node_modules/remote-pi/dist/commands/list_commands.js.map +0 -1
- package/node_modules/remote-pi/dist/config.d.ts +0 -62
- package/node_modules/remote-pi/dist/config.js +0 -115
- package/node_modules/remote-pi/dist/config.js.map +0 -1
- package/node_modules/remote-pi/dist/daemon/client.d.ts +0 -20
- package/node_modules/remote-pi/dist/daemon/client.js +0 -131
- package/node_modules/remote-pi/dist/daemon/client.js.map +0 -1
- package/node_modules/remote-pi/dist/daemon/control_protocol.d.ts +0 -176
- package/node_modules/remote-pi/dist/daemon/control_protocol.js +0 -63
- package/node_modules/remote-pi/dist/daemon/control_protocol.js.map +0 -1
- package/node_modules/remote-pi/dist/daemon/cron_log.d.ts +0 -45
- package/node_modules/remote-pi/dist/daemon/cron_log.js +0 -72
- package/node_modules/remote-pi/dist/daemon/cron_log.js.map +0 -1
- package/node_modules/remote-pi/dist/daemon/cron_registry.d.ts +0 -80
- package/node_modules/remote-pi/dist/daemon/cron_registry.js +0 -194
- package/node_modules/remote-pi/dist/daemon/cron_registry.js.map +0 -1
- package/node_modules/remote-pi/dist/daemon/id.d.ts +0 -24
- package/node_modules/remote-pi/dist/daemon/id.js +0 -36
- package/node_modules/remote-pi/dist/daemon/id.js.map +0 -1
- package/node_modules/remote-pi/dist/daemon/install.d.ts +0 -170
- package/node_modules/remote-pi/dist/daemon/install.js +0 -547
- package/node_modules/remote-pi/dist/daemon/install.js.map +0 -1
- package/node_modules/remote-pi/dist/daemon/registry.d.ts +0 -63
- package/node_modules/remote-pi/dist/daemon/registry.js +0 -153
- package/node_modules/remote-pi/dist/daemon/registry.js.map +0 -1
- package/node_modules/remote-pi/dist/daemon/rpc_child.d.ts +0 -194
- package/node_modules/remote-pi/dist/daemon/rpc_child.js +0 -389
- package/node_modules/remote-pi/dist/daemon/rpc_child.js.map +0 -1
- package/node_modules/remote-pi/dist/daemon/supervisor.d.ts +0 -93
- package/node_modules/remote-pi/dist/daemon/supervisor.js +0 -596
- package/node_modules/remote-pi/dist/daemon/supervisor.js.map +0 -1
- package/node_modules/remote-pi/dist/extension_ui_bridge.d.ts +0 -26
- package/node_modules/remote-pi/dist/extension_ui_bridge.js +0 -341
- package/node_modules/remote-pi/dist/extension_ui_bridge.js.map +0 -1
- package/node_modules/remote-pi/dist/index.d.ts +0 -213
- package/node_modules/remote-pi/dist/index.js +0 -4996
- package/node_modules/remote-pi/dist/index.js.map +0 -1
- package/node_modules/remote-pi/dist/mcp/mesh_result.d.ts +0 -10
- package/node_modules/remote-pi/dist/mcp/mesh_result.js +0 -42
- package/node_modules/remote-pi/dist/mcp/mesh_result.js.map +0 -1
- package/node_modules/remote-pi/dist/mcp/mesh_server.d.ts +0 -16
- package/node_modules/remote-pi/dist/mcp/mesh_server.js +0 -327
- package/node_modules/remote-pi/dist/mcp/mesh_server.js.map +0 -1
- package/node_modules/remote-pi/dist/mesh/canonical.d.ts +0 -30
- package/node_modules/remote-pi/dist/mesh/canonical.js +0 -61
- package/node_modules/remote-pi/dist/mesh/canonical.js.map +0 -1
- package/node_modules/remote-pi/dist/mesh/client.d.ts +0 -18
- package/node_modules/remote-pi/dist/mesh/client.js +0 -125
- package/node_modules/remote-pi/dist/mesh/client.js.map +0 -1
- package/node_modules/remote-pi/dist/mesh/encoding.d.ts +0 -38
- package/node_modules/remote-pi/dist/mesh/encoding.js +0 -216
- package/node_modules/remote-pi/dist/mesh/encoding.js.map +0 -1
- package/node_modules/remote-pi/dist/mesh/self_revoke.d.ts +0 -73
- package/node_modules/remote-pi/dist/mesh/self_revoke.js +0 -401
- package/node_modules/remote-pi/dist/mesh/self_revoke.js.map +0 -1
- package/node_modules/remote-pi/dist/mesh/siblings.d.ts +0 -49
- package/node_modules/remote-pi/dist/mesh/siblings.js +0 -159
- package/node_modules/remote-pi/dist/mesh/siblings.js.map +0 -1
- package/node_modules/remote-pi/dist/mesh/types.d.ts +0 -34
- package/node_modules/remote-pi/dist/mesh/types.js +0 -11
- package/node_modules/remote-pi/dist/mesh/types.js.map +0 -1
- package/node_modules/remote-pi/dist/mesh/verify.d.ts +0 -17
- package/node_modules/remote-pi/dist/mesh/verify.js +0 -86
- package/node_modules/remote-pi/dist/mesh/verify.js.map +0 -1
- package/node_modules/remote-pi/dist/pairing/crypto.d.ts +0 -8
- package/node_modules/remote-pi/dist/pairing/crypto.js +0 -22
- package/node_modules/remote-pi/dist/pairing/crypto.js.map +0 -1
- package/node_modules/remote-pi/dist/pairing/handshake.d.ts +0 -28
- package/node_modules/remote-pi/dist/pairing/handshake.js +0 -113
- package/node_modules/remote-pi/dist/pairing/handshake.js.map +0 -1
- package/node_modules/remote-pi/dist/pairing/noise-sha256.d.ts +0 -16
- package/node_modules/remote-pi/dist/pairing/noise-sha256.js +0 -103
- package/node_modules/remote-pi/dist/pairing/noise-sha256.js.map +0 -1
- package/node_modules/remote-pi/dist/pairing/qr.d.ts +0 -59
- package/node_modules/remote-pi/dist/pairing/qr.js +0 -125
- package/node_modules/remote-pi/dist/pairing/qr.js.map +0 -1
- package/node_modules/remote-pi/dist/pairing/storage.d.ts +0 -120
- package/node_modules/remote-pi/dist/pairing/storage.js +0 -604
- package/node_modules/remote-pi/dist/pairing/storage.js.map +0 -1
- package/node_modules/remote-pi/dist/protocol/codec.d.ts +0 -7
- package/node_modules/remote-pi/dist/protocol/codec.js +0 -49
- package/node_modules/remote-pi/dist/protocol/codec.js.map +0 -1
- package/node_modules/remote-pi/dist/protocol/types.d.ts +0 -393
- package/node_modules/remote-pi/dist/protocol/types.js +0 -2
- package/node_modules/remote-pi/dist/protocol/types.js.map +0 -1
- package/node_modules/remote-pi/dist/rooms.d.ts +0 -29
- package/node_modules/remote-pi/dist/rooms.js +0 -57
- package/node_modules/remote-pi/dist/rooms.js.map +0 -1
- package/node_modules/remote-pi/dist/session/address.d.ts +0 -49
- package/node_modules/remote-pi/dist/session/address.js +0 -58
- package/node_modules/remote-pi/dist/session/address.js.map +0 -1
- package/node_modules/remote-pi/dist/session/agent_bridge.d.ts +0 -55
- package/node_modules/remote-pi/dist/session/agent_bridge.js +0 -146
- package/node_modules/remote-pi/dist/session/agent_bridge.js.map +0 -1
- package/node_modules/remote-pi/dist/session/bridge.d.ts +0 -37
- package/node_modules/remote-pi/dist/session/bridge.js +0 -130
- package/node_modules/remote-pi/dist/session/bridge.js.map +0 -1
- package/node_modules/remote-pi/dist/session/broker.d.ts +0 -189
- package/node_modules/remote-pi/dist/session/broker.js +0 -507
- package/node_modules/remote-pi/dist/session/broker.js.map +0 -1
- package/node_modules/remote-pi/dist/session/broker_remote.d.ts +0 -74
- package/node_modules/remote-pi/dist/session/broker_remote.js +0 -583
- package/node_modules/remote-pi/dist/session/broker_remote.js.map +0 -1
- package/node_modules/remote-pi/dist/session/cwd_lock.d.ts +0 -33
- package/node_modules/remote-pi/dist/session/cwd_lock.js +0 -126
- package/node_modules/remote-pi/dist/session/cwd_lock.js.map +0 -1
- package/node_modules/remote-pi/dist/session/envelope.d.ts +0 -33
- package/node_modules/remote-pi/dist/session/envelope.js +0 -117
- package/node_modules/remote-pi/dist/session/envelope.js.map +0 -1
- package/node_modules/remote-pi/dist/session/global_config.d.ts +0 -33
- package/node_modules/remote-pi/dist/session/global_config.js +0 -73
- package/node_modules/remote-pi/dist/session/global_config.js.map +0 -1
- package/node_modules/remote-pi/dist/session/ipc.d.ts +0 -27
- package/node_modules/remote-pi/dist/session/ipc.js +0 -22
- package/node_modules/remote-pi/dist/session/ipc.js.map +0 -1
- package/node_modules/remote-pi/dist/session/leader_election.d.ts +0 -32
- package/node_modules/remote-pi/dist/session/leader_election.js +0 -106
- package/node_modules/remote-pi/dist/session/leader_election.js.map +0 -1
- package/node_modules/remote-pi/dist/session/local_config.d.ts +0 -55
- package/node_modules/remote-pi/dist/session/local_config.js +0 -157
- package/node_modules/remote-pi/dist/session/local_config.js.map +0 -1
- package/node_modules/remote-pi/dist/session/mesh_message.d.ts +0 -20
- package/node_modules/remote-pi/dist/session/mesh_message.js +0 -28
- package/node_modules/remote-pi/dist/session/mesh_message.js.map +0 -1
- package/node_modules/remote-pi/dist/session/mesh_node.d.ts +0 -116
- package/node_modules/remote-pi/dist/session/mesh_node.js +0 -573
- package/node_modules/remote-pi/dist/session/mesh_node.js.map +0 -1
- package/node_modules/remote-pi/dist/session/peer.d.ts +0 -139
- package/node_modules/remote-pi/dist/session/peer.js +0 -451
- package/node_modules/remote-pi/dist/session/peer.js.map +0 -1
- package/node_modules/remote-pi/dist/session/peer_inventory.d.ts +0 -13
- package/node_modules/remote-pi/dist/session/peer_inventory.js +0 -48
- package/node_modules/remote-pi/dist/session/peer_inventory.js.map +0 -1
- package/node_modules/remote-pi/dist/session/peer_limits.d.ts +0 -9
- package/node_modules/remote-pi/dist/session/peer_limits.js +0 -21
- package/node_modules/remote-pi/dist/session/peer_limits.js.map +0 -1
- package/node_modules/remote-pi/dist/session/setup_wizard.d.ts +0 -39
- package/node_modules/remote-pi/dist/session/setup_wizard.js +0 -63
- package/node_modules/remote-pi/dist/session/setup_wizard.js.map +0 -1
- package/node_modules/remote-pi/dist/session/tool_gate.d.ts +0 -5
- package/node_modules/remote-pi/dist/session/tool_gate.js +0 -11
- package/node_modules/remote-pi/dist/session/tool_gate.js.map +0 -1
- package/node_modules/remote-pi/dist/session/tools.d.ts +0 -24
- package/node_modules/remote-pi/dist/session/tools.js +0 -252
- package/node_modules/remote-pi/dist/session/tools.js.map +0 -1
- package/node_modules/remote-pi/dist/session/wizard.d.ts +0 -13
- package/node_modules/remote-pi/dist/session/wizard.js +0 -20
- package/node_modules/remote-pi/dist/session/wizard.js.map +0 -1
- package/node_modules/remote-pi/dist/settings.d.ts +0 -15
- package/node_modules/remote-pi/dist/settings.js +0 -52
- package/node_modules/remote-pi/dist/settings.js.map +0 -1
- package/node_modules/remote-pi/dist/transport/peer_channel.d.ts +0 -37
- package/node_modules/remote-pi/dist/transport/peer_channel.js +0 -98
- package/node_modules/remote-pi/dist/transport/peer_channel.js.map +0 -1
- package/node_modules/remote-pi/dist/transport/pi_forward_client.d.ts +0 -29
- package/node_modules/remote-pi/dist/transport/pi_forward_client.js +0 -62
- package/node_modules/remote-pi/dist/transport/pi_forward_client.js.map +0 -1
- package/node_modules/remote-pi/dist/transport/relay_client.d.ts +0 -91
- package/node_modules/remote-pi/dist/transport/relay_client.js +0 -206
- package/node_modules/remote-pi/dist/transport/relay_client.js.map +0 -1
- package/node_modules/remote-pi/dist/ui/footer.d.ts +0 -32
- package/node_modules/remote-pi/dist/ui/footer.js +0 -34
- package/node_modules/remote-pi/dist/ui/footer.js.map +0 -1
- package/node_modules/remote-pi/docs/daemon.md +0 -289
- package/node_modules/remote-pi/package.json +0 -92
- package/node_modules/remote-pi/service-templates/launchd.plist.template +0 -35
- package/node_modules/remote-pi/service-templates/systemd.service.template +0 -19
- package/node_modules/remote-pi/service-templates/task-launcher.vbs.template +0 -10
- package/node_modules/remote-pi/service-templates/task-scheduler.xml.template +0 -38
- package/node_modules/remote-pi/skills/agent-network/SKILL.md +0 -310
|
@@ -90,8 +90,8 @@ var init_activity = __esm({
|
|
|
90
90
|
// credential-source.ts
|
|
91
91
|
import { exec } from "node:child_process";
|
|
92
92
|
import { promisify } from "node:util";
|
|
93
|
-
function redactCredential(
|
|
94
|
-
return credential ?
|
|
93
|
+
function redactCredential(text4, credential) {
|
|
94
|
+
return credential ? text4.split(credential).join("[redacted]") : text4;
|
|
95
95
|
}
|
|
96
96
|
function normalize(value) {
|
|
97
97
|
if (typeof value !== "string") return null;
|
|
@@ -346,8 +346,8 @@ function isTimeoutError(err) {
|
|
|
346
346
|
const message = err.message ?? "";
|
|
347
347
|
return name === "AbortError" || code === "ETIMEDOUT" || message.toLowerCase().includes("timed out");
|
|
348
348
|
}
|
|
349
|
-
function trimErrorText(
|
|
350
|
-
return
|
|
349
|
+
function trimErrorText(text4) {
|
|
350
|
+
return text4.replace(/\s+/g, " ").trim().slice(0, 200);
|
|
351
351
|
}
|
|
352
352
|
function mapFfmpegError(err) {
|
|
353
353
|
const { code, stderr, message } = readExecError(err);
|
|
@@ -441,7 +441,7 @@ function installGlobalProxyFetch() {
|
|
|
441
441
|
const current = globalThis.fetch;
|
|
442
442
|
if (typeof current !== "function" || current.__piWebAccessProxyFetch === true) return;
|
|
443
443
|
const nativeFetch = current;
|
|
444
|
-
const wrapped = ((input, init) => {
|
|
444
|
+
const wrapped = (async (input, init) => {
|
|
445
445
|
const proxy = init?.__proxy ?? getActiveProxy();
|
|
446
446
|
if (!proxy) return nativeFetch(input, init);
|
|
447
447
|
let url = null;
|
|
@@ -453,12 +453,20 @@ function installGlobalProxyFetch() {
|
|
|
453
453
|
if (!url || url.protocol !== "http:" && url.protocol !== "https:" || isProxyBypassedUrl(url)) {
|
|
454
454
|
return nativeFetch(input, init);
|
|
455
455
|
}
|
|
456
|
+
if (input instanceof Request) {
|
|
457
|
+
const request = new Request(input, init);
|
|
458
|
+
request.signal.throwIfAborted();
|
|
459
|
+
const body = request.body === null ? null : new Uint8Array(await new Response(
|
|
460
|
+
request.body.pipeThrough(new TransformStream(), { signal: request.signal })
|
|
461
|
+
).arrayBuffer());
|
|
462
|
+
init = { ...init, method: request.method, headers: request.headers, body, signal: request.signal, redirect: request.redirect };
|
|
463
|
+
}
|
|
456
464
|
return fetchViaCurl(url, init ?? {}, proxy);
|
|
457
465
|
});
|
|
458
466
|
wrapped.__piWebAccessProxyFetch = true;
|
|
459
467
|
globalThis.fetch = wrapped;
|
|
460
468
|
}
|
|
461
|
-
function parseHeaderDump(dump) {
|
|
469
|
+
function parseHeaderDump(dump, keepLengthHeaders) {
|
|
462
470
|
const blocks = dump.split(/\r?\n\r?\n/).filter((block2) => /^HTTP\/[\d.]+\s+\d{3}/.test(block2.trim()));
|
|
463
471
|
const block = (blocks.length > 0 ? blocks[blocks.length - 1] : "").trim();
|
|
464
472
|
const lines = block.split(/\r?\n/);
|
|
@@ -476,7 +484,7 @@ function parseHeaderDump(dump) {
|
|
|
476
484
|
const separator = line.indexOf(":");
|
|
477
485
|
if (separator > 0) {
|
|
478
486
|
const name = line.slice(0, separator).trim();
|
|
479
|
-
if (name.toLowerCase() === "content-encoding" || name.toLowerCase() === "content-length") continue;
|
|
487
|
+
if (!keepLengthHeaders && (name.toLowerCase() === "content-encoding" || name.toLowerCase() === "content-length")) continue;
|
|
480
488
|
headers.push([name, line.slice(separator + 1).trim()]);
|
|
481
489
|
}
|
|
482
490
|
}
|
|
@@ -537,7 +545,8 @@ async function fetchViaCurlOnce(url, init, proxyUrl) {
|
|
|
537
545
|
"--write-out",
|
|
538
546
|
"%{json}"
|
|
539
547
|
];
|
|
540
|
-
if (method
|
|
548
|
+
if (method === "HEAD") args.push("--head");
|
|
549
|
+
else if (method !== "GET") args.push("-X", method);
|
|
541
550
|
for (const [name, value] of headers.entries()) {
|
|
542
551
|
if (value === "") continue;
|
|
543
552
|
args.push("-H", `${name}: ${value}`);
|
|
@@ -553,6 +562,8 @@ async function fetchViaCurlOnce(url, init, proxyUrl) {
|
|
|
553
562
|
await writeFile(requestBodyFile, buffer);
|
|
554
563
|
args.push("--data-binary", `@${requestBodyFile}`);
|
|
555
564
|
if (method === "GET") args.unshift("-X", "GET");
|
|
565
|
+
} else if ((method === "POST" || method === "PUT") && !headers.has("content-length")) {
|
|
566
|
+
args.push("-H", "Content-Length: 0");
|
|
556
567
|
}
|
|
557
568
|
args.push(url.toString());
|
|
558
569
|
const signal = init.signal ?? null;
|
|
@@ -609,7 +620,7 @@ async function fetchViaCurlOnce(url, init, proxyUrl) {
|
|
|
609
620
|
await rm(dir, { recursive: true, force: true }).catch(() => {
|
|
610
621
|
});
|
|
611
622
|
}
|
|
612
|
-
const { status, statusText, headers: responseHeaders } = parseHeaderDump(dump);
|
|
623
|
+
const { status, statusText, headers: responseHeaders } = parseHeaderDump(dump, method === "HEAD");
|
|
613
624
|
if (status === 0) {
|
|
614
625
|
throw new Error(`Proxy fetch to ${url.toString()} via ${redactProxyUrl(proxyUrl)} returned no HTTP status`);
|
|
615
626
|
}
|
|
@@ -624,7 +635,7 @@ async function fetchViaCurlOnce(url, init, proxyUrl) {
|
|
|
624
635
|
}
|
|
625
636
|
} catch {
|
|
626
637
|
}
|
|
627
|
-
const nullBody = status === 204 || status === 205 || status === 304;
|
|
638
|
+
const nullBody = method === "HEAD" || status === 204 || status === 205 || status === 304;
|
|
628
639
|
const response = new Response(nullBody ? null : new Uint8Array(bodyBuffer), {
|
|
629
640
|
status,
|
|
630
641
|
statusText: statusText || void 0,
|
|
@@ -733,10 +744,10 @@ function parseAdcFile(raw) {
|
|
|
733
744
|
}
|
|
734
745
|
return { type };
|
|
735
746
|
}
|
|
736
|
-
function parseTokenExchangeResponse(
|
|
747
|
+
function parseTokenExchangeResponse(text4, context) {
|
|
737
748
|
let raw;
|
|
738
749
|
try {
|
|
739
|
-
raw = JSON.parse(
|
|
750
|
+
raw = JSON.parse(text4);
|
|
740
751
|
} catch (err) {
|
|
741
752
|
const message = err instanceof Error ? err.message : String(err);
|
|
742
753
|
throw new Error(`${context} returned invalid JSON: ${message}`);
|
|
@@ -783,11 +794,11 @@ async function exchangeRefreshToken(cfg, signal) {
|
|
|
783
794
|
body,
|
|
784
795
|
signal
|
|
785
796
|
});
|
|
786
|
-
const
|
|
797
|
+
const text4 = await res.text();
|
|
787
798
|
if (!res.ok) {
|
|
788
|
-
throwOnTokenExchangeFailure(res,
|
|
799
|
+
throwOnTokenExchangeFailure(res, text4, res.status);
|
|
789
800
|
}
|
|
790
|
-
return parseTokenExchangeResponse(
|
|
801
|
+
return parseTokenExchangeResponse(text4, "Gemini ADC token exchange");
|
|
791
802
|
}
|
|
792
803
|
async function exchangeServiceAccountJwt(cfg, signal) {
|
|
793
804
|
if (!cfg.client_email || !cfg.private_key) {
|
|
@@ -819,11 +830,11 @@ async function exchangeServiceAccountJwt(cfg, signal) {
|
|
|
819
830
|
body,
|
|
820
831
|
signal
|
|
821
832
|
});
|
|
822
|
-
const
|
|
833
|
+
const text4 = await res.text();
|
|
823
834
|
if (!res.ok) {
|
|
824
|
-
throwOnTokenExchangeFailure(res,
|
|
835
|
+
throwOnTokenExchangeFailure(res, text4, res.status);
|
|
825
836
|
}
|
|
826
|
-
return parseTokenExchangeResponse(
|
|
837
|
+
return parseTokenExchangeResponse(text4, "Gemini ADC service account token exchange");
|
|
827
838
|
}
|
|
828
839
|
async function getAdcAccessToken(signal) {
|
|
829
840
|
if (cachedToken && cachedToken.expiresAt > Date.now()) {
|
|
@@ -954,14 +965,14 @@ function buildAuthHeaders(apiKey = null, cloudflareApiKey = getLegacyCloudflareA
|
|
|
954
965
|
if (!isCloudflareGateway()) return apiKey ? { "x-goog-api-key": apiKey } : {};
|
|
955
966
|
return cloudflareApiKey ? { "cf-aig-authorization": `Bearer ${cloudflareApiKey}` } : {};
|
|
956
967
|
}
|
|
957
|
-
function redactGeminiCredentials(
|
|
958
|
-
let out = redactCredential(redactCredential(
|
|
968
|
+
function redactGeminiCredentials(text4, apiKey, cloudflareApiKey, adcToken) {
|
|
969
|
+
let out = redactCredential(redactCredential(text4, apiKey), cloudflareApiKey);
|
|
959
970
|
if (adcToken) out = redactCredential(out, adcToken);
|
|
960
971
|
return out;
|
|
961
972
|
}
|
|
962
|
-
function redactGeminiApiResponse(response,
|
|
973
|
+
function redactGeminiApiResponse(response, text4, apiKey, adcToken) {
|
|
963
974
|
const credentials = responseCredentials.get(response);
|
|
964
|
-
return redactGeminiCredentials(
|
|
975
|
+
return redactGeminiCredentials(text4, credentials?.apiKey ?? apiKey, credentials?.cloudflareApiKey, credentials?.adcToken ?? adcToken);
|
|
965
976
|
}
|
|
966
977
|
async function fetchGeminiApi(url, init = {}, apiKey) {
|
|
967
978
|
const parsedUrl = new URL(url);
|
|
@@ -1061,9 +1072,9 @@ async function queryGeminiApiWithInlineData(prompt, data, mimeType, options = {}
|
|
|
1061
1072
|
}
|
|
1062
1073
|
const response = await res.json();
|
|
1063
1074
|
const candidate = response.candidates?.[0];
|
|
1064
|
-
const
|
|
1075
|
+
const text4 = candidate?.content?.parts?.map((part) => part.text).filter((part) => typeof part === "string" && part.length > 0).join("\n") ?? "";
|
|
1065
1076
|
return {
|
|
1066
|
-
text:
|
|
1077
|
+
text: text4,
|
|
1067
1078
|
...candidate?.finishReason ? { finishReason: candidate.finishReason } : {},
|
|
1068
1079
|
...response.promptFeedback?.blockReason ? { blockReason: response.promptFeedback.blockReason } : {}
|
|
1069
1080
|
};
|
|
@@ -1104,9 +1115,9 @@ async function queryGeminiApiWithVideo(prompt, videoUri, options = {}) {
|
|
|
1104
1115
|
throw new Error(`Gemini API error ${res.status}: ${errorText.slice(0, 300)}`);
|
|
1105
1116
|
}
|
|
1106
1117
|
const data = await res.json();
|
|
1107
|
-
const
|
|
1108
|
-
if (!
|
|
1109
|
-
return
|
|
1118
|
+
const text4 = data.candidates?.[0]?.content?.parts?.map((p) => p.text).filter(Boolean).join("\n");
|
|
1119
|
+
if (!text4) throw new Error("Gemini API returned empty response");
|
|
1120
|
+
return text4;
|
|
1110
1121
|
}
|
|
1111
1122
|
var DEFAULT_API_HOST, API_VERSION, API_BASE, CONFIG_PATH2, DEFAULT_MODEL, cachedConfig2, responseCredentials;
|
|
1112
1123
|
var init_gemini_api = __esm({
|
|
@@ -1996,8 +2007,8 @@ Content-Type: ${file.mimeType}\r
|
|
|
1996
2007
|
signal
|
|
1997
2008
|
});
|
|
1998
2009
|
if (!res.ok) {
|
|
1999
|
-
const
|
|
2000
|
-
throw new Error(`File upload failed: ${res.status} (${
|
|
2010
|
+
const text4 = await res.text();
|
|
2011
|
+
throw new Error(`File upload failed: ${res.status} (${text4.slice(0, 200)})`);
|
|
2001
2012
|
}
|
|
2002
2013
|
return { id: await res.text(), name: fileName };
|
|
2003
2014
|
}
|
|
@@ -2022,13 +2033,13 @@ function getNestedValue(value, pathParts) {
|
|
|
2022
2033
|
}
|
|
2023
2034
|
return current;
|
|
2024
2035
|
}
|
|
2025
|
-
function trimJsonEnvelope(
|
|
2026
|
-
const start =
|
|
2027
|
-
const end =
|
|
2036
|
+
function trimJsonEnvelope(text4) {
|
|
2037
|
+
const start = text4.indexOf("[");
|
|
2038
|
+
const end = text4.lastIndexOf("]");
|
|
2028
2039
|
if (start === -1 || end === -1 || end <= start) {
|
|
2029
2040
|
throw new Error("Gemini response did not contain a JSON payload.");
|
|
2030
2041
|
}
|
|
2031
|
-
return
|
|
2042
|
+
return text4.slice(start, end + 1);
|
|
2032
2043
|
}
|
|
2033
2044
|
function extractErrorCode(responseJson) {
|
|
2034
2045
|
const code = getNestedValue(responseJson, [0, 5, 2, 0, 1, 0]);
|
|
@@ -2036,12 +2047,12 @@ function extractErrorCode(responseJson) {
|
|
|
2036
2047
|
}
|
|
2037
2048
|
function extractCandidateText(candidate) {
|
|
2038
2049
|
const textRaw = getNestedValue(candidate, [1, 0]);
|
|
2039
|
-
let
|
|
2040
|
-
if (/^http:\/\/googleusercontent\.com\/card_content\/\d+/.test(
|
|
2050
|
+
let text4 = typeof textRaw === "string" ? textRaw : "";
|
|
2051
|
+
if (/^http:\/\/googleusercontent\.com\/card_content\/\d+/.test(text4)) {
|
|
2041
2052
|
const alt = getNestedValue(candidate, [22, 0]);
|
|
2042
|
-
if (typeof alt === "string" && alt.length > 0)
|
|
2053
|
+
if (typeof alt === "string" && alt.length > 0) text4 = alt;
|
|
2043
2054
|
}
|
|
2044
|
-
return
|
|
2055
|
+
return text4;
|
|
2045
2056
|
}
|
|
2046
2057
|
function parseStreamGenerateResponse(rawText) {
|
|
2047
2058
|
const responseJson = JSON.parse(trimJsonEnvelope(rawText));
|
|
@@ -2058,13 +2069,13 @@ function parseStreamGenerateResponse(rawText) {
|
|
|
2058
2069
|
if (!Array.isArray(candidateList) || candidateList.length === 0) continue;
|
|
2059
2070
|
const firstCandidate = candidateList[0];
|
|
2060
2071
|
if (firstCandidateSeen === void 0) firstCandidateSeen = firstCandidate;
|
|
2061
|
-
const
|
|
2062
|
-
if (
|
|
2072
|
+
const text5 = extractCandidateText(firstCandidate);
|
|
2073
|
+
if (text5.length > 0) latestNonEmptyText = text5;
|
|
2063
2074
|
} catch {
|
|
2064
2075
|
}
|
|
2065
2076
|
}
|
|
2066
|
-
const
|
|
2067
|
-
return { text:
|
|
2077
|
+
const text4 = latestNonEmptyText.length > 0 ? latestNonEmptyText : extractCandidateText(firstCandidateSeen);
|
|
2078
|
+
return { text: text4, errorCode };
|
|
2068
2079
|
}
|
|
2069
2080
|
var GEMINI_APP_URL, GEMINI_STREAM_GENERATE_URL, GEMINI_UPLOAD_URL, GEMINI_UPLOAD_PUSH_ID, USER_AGENT, MODEL_HEADER_NAME, DEFAULT_GEMINI_WEB_MODEL, MODEL_HEADERS, REQUIRED_COOKIES, geminiFetchImpl, geminiFetchOverride, GEMINI_MAX_HEADER_SIZE;
|
|
2070
2081
|
var init_gemini_web = __esm({
|
|
@@ -2645,7 +2656,9 @@ async function callParallelMcp(toolName, args, signal) {
|
|
|
2645
2656
|
const apiKey = await resolveParallelApiKey(signal);
|
|
2646
2657
|
const headers = {
|
|
2647
2658
|
"Content-Type": "application/json",
|
|
2648
|
-
"Accept": "application/json, text/event-stream"
|
|
2659
|
+
"Accept": "application/json, text/event-stream",
|
|
2660
|
+
// Parallel's free tier rate-limits the default "undici" User-Agent.
|
|
2661
|
+
"User-Agent": "pi-web-access"
|
|
2649
2662
|
};
|
|
2650
2663
|
if (apiKey) headers.Authorization = `Bearer ${apiKey}`;
|
|
2651
2664
|
let response;
|
|
@@ -2688,20 +2701,20 @@ async function callParallelMcp(toolName, args, signal) {
|
|
|
2688
2701
|
throw new Error(`Parallel MCP error${code}: ${message}`);
|
|
2689
2702
|
}
|
|
2690
2703
|
if (parsed.result?.isError) {
|
|
2691
|
-
const
|
|
2692
|
-
throw new Error(apiKey ? redactCredential(
|
|
2704
|
+
const text5 = parsed.result.content?.find((item) => item.type === "text" && typeof item.text === "string")?.text?.trim() || "Parallel MCP returned an error";
|
|
2705
|
+
throw new Error(apiKey ? redactCredential(text5, apiKey) : text5);
|
|
2693
2706
|
}
|
|
2694
2707
|
if (parsed.result?.structuredContent && typeof parsed.result.structuredContent === "object") return parsed.result.structuredContent;
|
|
2695
|
-
const
|
|
2696
|
-
if (!
|
|
2708
|
+
const text4 = parsed.result?.content?.find((item) => item.type === "text" && typeof item.text === "string" && item.text.trim())?.text;
|
|
2709
|
+
if (!text4) throw new Error("Parallel MCP returned empty content");
|
|
2697
2710
|
try {
|
|
2698
|
-
return JSON.parse(
|
|
2711
|
+
return JSON.parse(text4);
|
|
2699
2712
|
} catch {
|
|
2700
|
-
return
|
|
2713
|
+
return text4;
|
|
2701
2714
|
}
|
|
2702
2715
|
}
|
|
2703
|
-
function parseTextResults(
|
|
2704
|
-
return
|
|
2716
|
+
function parseTextResults(text4) {
|
|
2717
|
+
return text4.split(/(?=^Title: )/m).flatMap((block) => {
|
|
2705
2718
|
const url = block.match(/^URL: (.+)/m)?.[1]?.trim();
|
|
2706
2719
|
if (!url) return [];
|
|
2707
2720
|
const title = block.match(/^Title: (.+)/m)?.[1]?.trim() ?? "";
|
|
@@ -4248,8 +4261,8 @@ async function firecrawlFetch(endpoint, body, signal, options, label = endpoint,
|
|
|
4248
4261
|
signal: requestSignal9(options?.timeoutMs ?? EXTRACT_TIMEOUT_MS, signal)
|
|
4249
4262
|
}, options);
|
|
4250
4263
|
if (!response.ok) {
|
|
4251
|
-
const
|
|
4252
|
-
throw new Error(`Firecrawl ${label} error ${response.status}: ${redactCredential(
|
|
4264
|
+
const text4 = await response.text().catch(() => "");
|
|
4265
|
+
throw new Error(`Firecrawl ${label} error ${response.status}: ${redactCredential(text4.slice(0, 300), apiKey)}`);
|
|
4253
4266
|
}
|
|
4254
4267
|
let data;
|
|
4255
4268
|
try {
|
|
@@ -4759,7 +4772,7 @@ var init_ollama = __esm({
|
|
|
4759
4772
|
});
|
|
4760
4773
|
|
|
4761
4774
|
// auth-fetch.ts
|
|
4762
|
-
import { existsSync as
|
|
4775
|
+
import { existsSync as existsSync41, readFileSync as readFileSync42 } from "node:fs";
|
|
4763
4776
|
function resolveAuthFetchProfile(request) {
|
|
4764
4777
|
const profiles = loadAuthFetchProfiles();
|
|
4765
4778
|
if (profiles.length === 0) {
|
|
@@ -4797,8 +4810,8 @@ function authFetchRedirectGuard(profile, from, to) {
|
|
|
4797
4810
|
}
|
|
4798
4811
|
}
|
|
4799
4812
|
function loadAuthFetchProfiles() {
|
|
4800
|
-
if (!
|
|
4801
|
-
const raw =
|
|
4813
|
+
if (!existsSync41(WEB_SEARCH_CONFIG_PATH2)) return [];
|
|
4814
|
+
const raw = readFileSync42(WEB_SEARCH_CONFIG_PATH2, "utf-8");
|
|
4802
4815
|
let parsed;
|
|
4803
4816
|
try {
|
|
4804
4817
|
const value = JSON.parse(raw);
|
|
@@ -5132,8 +5145,8 @@ function extractRSCContent(html) {
|
|
|
5132
5145
|
if (!Array.isArray(node)) return;
|
|
5133
5146
|
if (node[0] === "$" && (node[1] === "td" || node[1] === "th")) {
|
|
5134
5147
|
const cellProps = node[3] || {};
|
|
5135
|
-
const
|
|
5136
|
-
cells.push(
|
|
5148
|
+
const text4 = extractNode(cellProps.children, { inTable: true, inCode: false }).trim().replace(/\n/g, " ").replace(/\\/g, "\\\\").replace(/\|/g, "\\|");
|
|
5149
|
+
cells.push(text4);
|
|
5137
5150
|
} else if (node[0] === "$" && typeof node[1] === "string" && node[1].startsWith("$L")) {
|
|
5138
5151
|
const refId = node[1].slice(2);
|
|
5139
5152
|
if (!visitedRefs.has(refId)) {
|
|
@@ -5173,9 +5186,9 @@ function extractRSCContent(html) {
|
|
|
5173
5186
|
const parsed = getParsedChunk(id);
|
|
5174
5187
|
if (!parsed) continue;
|
|
5175
5188
|
visitedRefs.clear();
|
|
5176
|
-
const
|
|
5177
|
-
if (
|
|
5178
|
-
contentParts.push({ order: parseInt(id, 16), text:
|
|
5189
|
+
const text4 = extractNode(parsed);
|
|
5190
|
+
if (text4.trim().length > 50 && !text4.includes("page was not found") && !text4.includes("404")) {
|
|
5191
|
+
contentParts.push({ order: parseInt(id, 16), text: text4.trim() });
|
|
5179
5192
|
}
|
|
5180
5193
|
}
|
|
5181
5194
|
if (contentParts.length === 0) return null;
|
|
@@ -5198,20 +5211,20 @@ var init_rsc_extract = __esm({
|
|
|
5198
5211
|
});
|
|
5199
5212
|
|
|
5200
5213
|
// datalab-pdf-extract.ts
|
|
5201
|
-
import { existsSync as
|
|
5202
|
-
function
|
|
5203
|
-
if (
|
|
5204
|
-
if (!
|
|
5205
|
-
|
|
5206
|
-
return
|
|
5214
|
+
import { existsSync as existsSync42, readFileSync as readFileSync44 } from "node:fs";
|
|
5215
|
+
function loadConfig36() {
|
|
5216
|
+
if (cachedConfig35) return cachedConfig35;
|
|
5217
|
+
if (!existsSync42(CONFIG_PATH39)) {
|
|
5218
|
+
cachedConfig35 = {};
|
|
5219
|
+
return cachedConfig35;
|
|
5207
5220
|
}
|
|
5208
|
-
const rawText =
|
|
5221
|
+
const rawText = readFileSync44(CONFIG_PATH39, "utf-8");
|
|
5209
5222
|
try {
|
|
5210
|
-
|
|
5211
|
-
return
|
|
5223
|
+
cachedConfig35 = JSON.parse(rawText);
|
|
5224
|
+
return cachedConfig35;
|
|
5212
5225
|
} catch (err) {
|
|
5213
5226
|
const message = err instanceof Error ? err.message : String(err);
|
|
5214
|
-
throw new Error(`Failed to parse ${
|
|
5227
|
+
throw new Error(`Failed to parse ${CONFIG_PATH39}: ${message}`);
|
|
5215
5228
|
}
|
|
5216
5229
|
}
|
|
5217
5230
|
function normalizeString(value) {
|
|
@@ -5226,14 +5239,14 @@ function normalizeFileId(value) {
|
|
|
5226
5239
|
function isDatalabApiAvailable() {
|
|
5227
5240
|
return hasCredentialSource({
|
|
5228
5241
|
provider: "Datalab",
|
|
5229
|
-
configuredValue:
|
|
5242
|
+
configuredValue: loadConfig36().datalabApiKey,
|
|
5230
5243
|
environmentValue: process.env.DATALAB_API_KEY
|
|
5231
5244
|
});
|
|
5232
5245
|
}
|
|
5233
5246
|
async function getDatalabApiKey(signal) {
|
|
5234
5247
|
return resolveCredential({
|
|
5235
5248
|
provider: "Datalab",
|
|
5236
|
-
configuredValue:
|
|
5249
|
+
configuredValue: loadConfig36().datalabApiKey,
|
|
5237
5250
|
environmentValue: process.env.DATALAB_API_KEY,
|
|
5238
5251
|
signal
|
|
5239
5252
|
});
|
|
@@ -5505,18 +5518,18 @@ async function fetchDatalab(url, init, apiKey) {
|
|
|
5505
5518
|
}
|
|
5506
5519
|
}
|
|
5507
5520
|
async function readJsonResponse(response, apiKey) {
|
|
5508
|
-
const
|
|
5521
|
+
const text4 = await readResponseText(response);
|
|
5509
5522
|
if (!response.ok) {
|
|
5510
|
-
const detail =
|
|
5523
|
+
const detail = text4.trim().slice(0, MAX_ERROR_BODY_BYTES);
|
|
5511
5524
|
const message = detail ? `Datalab PDF conversion failed: HTTP ${response.status} ${response.statusText}: ${detail}` : `Datalab PDF conversion failed: HTTP ${response.status} ${response.statusText}`;
|
|
5512
5525
|
throw new Error(redactCredential(message, apiKey));
|
|
5513
5526
|
}
|
|
5514
|
-
return parseJsonRecord(
|
|
5527
|
+
return parseJsonRecord(text4);
|
|
5515
5528
|
}
|
|
5516
|
-
function parseJsonRecord(
|
|
5529
|
+
function parseJsonRecord(text4) {
|
|
5517
5530
|
let parsed;
|
|
5518
5531
|
try {
|
|
5519
|
-
parsed = JSON.parse(
|
|
5532
|
+
parsed = JSON.parse(text4);
|
|
5520
5533
|
} catch (error) {
|
|
5521
5534
|
throw new Error("Datalab PDF conversion returned invalid JSON", { cause: error });
|
|
5522
5535
|
}
|
|
@@ -5558,7 +5571,7 @@ async function readResponseText(response) {
|
|
|
5558
5571
|
function datalabFilename(title) {
|
|
5559
5572
|
return title.toLowerCase().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 60) || "document";
|
|
5560
5573
|
}
|
|
5561
|
-
var DEFAULT_API_HOST2, API_PREFIX, DEFAULT_TIMEOUT_MS, DEFAULT_POLL_INTERVAL_MS, MAX_RESPONSE_BYTES, MAX_ERROR_BODY_BYTES, CLEANUP_TIMEOUT_MS,
|
|
5574
|
+
var DEFAULT_API_HOST2, API_PREFIX, DEFAULT_TIMEOUT_MS, DEFAULT_POLL_INTERVAL_MS, MAX_RESPONSE_BYTES, MAX_ERROR_BODY_BYTES, CLEANUP_TIMEOUT_MS, CONFIG_PATH39, DATALAB_MODE_VALUES, DATALAB_LOCATION_VALUES, DEFAULT_DATALAB_MODE, DEFAULT_PROCESSING_LOCATION, DEFAULT_DATALAB_TIMEOUT_MS, cachedConfig35;
|
|
5562
5575
|
var init_datalab_pdf_extract = __esm({
|
|
5563
5576
|
"datalab-pdf-extract.ts"() {
|
|
5564
5577
|
init_credential_source();
|
|
@@ -5570,7 +5583,7 @@ var init_datalab_pdf_extract = __esm({
|
|
|
5570
5583
|
MAX_RESPONSE_BYTES = 4 * 1024 * 1024;
|
|
5571
5584
|
MAX_ERROR_BODY_BYTES = 300;
|
|
5572
5585
|
CLEANUP_TIMEOUT_MS = 5e3;
|
|
5573
|
-
|
|
5586
|
+
CONFIG_PATH39 = getWebSearchConfigPath();
|
|
5574
5587
|
DATALAB_MODE_VALUES = /* @__PURE__ */ new Set([
|
|
5575
5588
|
"fast",
|
|
5576
5589
|
"balanced",
|
|
@@ -5583,7 +5596,7 @@ var init_datalab_pdf_extract = __esm({
|
|
|
5583
5596
|
DEFAULT_DATALAB_MODE = "balanced";
|
|
5584
5597
|
DEFAULT_PROCESSING_LOCATION = "us";
|
|
5585
5598
|
DEFAULT_DATALAB_TIMEOUT_MS = DEFAULT_TIMEOUT_MS;
|
|
5586
|
-
|
|
5599
|
+
cachedConfig35 = null;
|
|
5587
5600
|
}
|
|
5588
5601
|
});
|
|
5589
5602
|
|
|
@@ -5673,12 +5686,12 @@ var init_gemini_pdf_extract = __esm({
|
|
|
5673
5686
|
});
|
|
5674
5687
|
|
|
5675
5688
|
// pdf-extract.ts
|
|
5676
|
-
import { existsSync as
|
|
5689
|
+
import { existsSync as existsSync43, readFileSync as readFileSync45 } from "node:fs";
|
|
5677
5690
|
import { writeFile as writeFile2, mkdir } from "node:fs/promises";
|
|
5678
5691
|
import { join as join5, basename as basename2 } from "node:path";
|
|
5679
5692
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
5680
5693
|
function loadPDFConfig() {
|
|
5681
|
-
if (!
|
|
5694
|
+
if (!existsSync43(CONFIG_PATH40)) {
|
|
5682
5695
|
return {
|
|
5683
5696
|
enabled: true,
|
|
5684
5697
|
maxSizeMB: DEFAULT_PDF_MAX_SIZE_MB,
|
|
@@ -5688,13 +5701,13 @@ function loadPDFConfig() {
|
|
|
5688
5701
|
datalabTimeoutMs: DEFAULT_DATALAB_TIMEOUT_MS
|
|
5689
5702
|
};
|
|
5690
5703
|
}
|
|
5691
|
-
const rawText =
|
|
5704
|
+
const rawText = readFileSync45(CONFIG_PATH40, "utf-8");
|
|
5692
5705
|
let raw;
|
|
5693
5706
|
try {
|
|
5694
5707
|
raw = JSON.parse(rawText);
|
|
5695
5708
|
} catch (err) {
|
|
5696
5709
|
const message = err instanceof Error ? err.message : String(err);
|
|
5697
|
-
throw new Error(`Failed to parse ${
|
|
5710
|
+
throw new Error(`Failed to parse ${CONFIG_PATH40}: ${message}`);
|
|
5698
5711
|
}
|
|
5699
5712
|
const root = raw && typeof raw === "object" ? raw : {};
|
|
5700
5713
|
const pdf = root.pdf && typeof root.pdf === "object" ? root.pdf : {};
|
|
@@ -5903,7 +5916,7 @@ function isPDF(url, contentType) {
|
|
|
5903
5916
|
return false;
|
|
5904
5917
|
}
|
|
5905
5918
|
}
|
|
5906
|
-
var PDF_PROVIDER_VALUES, DEFAULT_PDF_MAX_SIZE_MB, MAX_PDF_MAX_SIZE_MB, MAX_DATALAB_TIMEOUT_MS, DEFAULT_MAX_PAGES, DEFAULT_OUTPUT_DIR,
|
|
5919
|
+
var PDF_PROVIDER_VALUES, DEFAULT_PDF_MAX_SIZE_MB, MAX_PDF_MAX_SIZE_MB, MAX_DATALAB_TIMEOUT_MS, DEFAULT_MAX_PAGES, DEFAULT_OUTPUT_DIR, CONFIG_PATH40, PAGE_MARKER_PATTERN2;
|
|
5907
5920
|
var init_pdf_extract = __esm({
|
|
5908
5921
|
"pdf-extract.ts"() {
|
|
5909
5922
|
init_credential_source();
|
|
@@ -5922,7 +5935,7 @@ var init_pdf_extract = __esm({
|
|
|
5922
5935
|
MAX_DATALAB_TIMEOUT_MS = 3e5;
|
|
5923
5936
|
DEFAULT_MAX_PAGES = 100;
|
|
5924
5937
|
DEFAULT_OUTPUT_DIR = join5(tmpdir3(), "pi-web-pdf");
|
|
5925
|
-
|
|
5938
|
+
CONFIG_PATH40 = getWebSearchConfigPath();
|
|
5926
5939
|
PAGE_MARKER_PATTERN2 = /^<!-- Page (\d+) -->$/gm;
|
|
5927
5940
|
}
|
|
5928
5941
|
});
|
|
@@ -6100,7 +6113,7 @@ var init_github_api = __esm({
|
|
|
6100
6113
|
});
|
|
6101
6114
|
|
|
6102
6115
|
// github-extract.ts
|
|
6103
|
-
import { chmodSync, closeSync as closeSync2, constants as fsConstants, existsSync as
|
|
6116
|
+
import { chmodSync, closeSync as closeSync2, constants as fsConstants, existsSync as existsSync44, lstatSync as lstatSync2, mkdirSync as mkdirSync2, mkdtempSync as mkdtempSync2, openSync as openSync2, readFileSync as readFileSync46, readSync, readdirSync as readdirSync3, realpathSync as realpathSync2, rmSync as rmSync2, statSync as statSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
6104
6117
|
import { lstat as lstatAsync, open as openAsync, opendir as opendirAsync, readFile as readFileAsync, realpath as realpathAsync, rm as rmAsync } from "node:fs/promises";
|
|
6105
6118
|
import { execFile as execFile3, spawn as spawn2 } from "node:child_process";
|
|
6106
6119
|
import { createHash as createHash2 } from "node:crypto";
|
|
@@ -6129,33 +6142,33 @@ function normalizeClonePath(value, fallback) {
|
|
|
6129
6142
|
return expandPath(normalized);
|
|
6130
6143
|
}
|
|
6131
6144
|
function loadGitHubConfig() {
|
|
6132
|
-
if (
|
|
6145
|
+
if (cachedConfig36) return cachedConfig36;
|
|
6133
6146
|
const defaults2 = {
|
|
6134
6147
|
enabled: true,
|
|
6135
6148
|
maxRepoSizeMB: 350,
|
|
6136
6149
|
cloneTimeoutSeconds: 30,
|
|
6137
6150
|
clonePath: "/tmp/pi-github-repos"
|
|
6138
6151
|
};
|
|
6139
|
-
if (!
|
|
6140
|
-
|
|
6141
|
-
return
|
|
6152
|
+
if (!existsSync44(CONFIG_PATH41)) {
|
|
6153
|
+
cachedConfig36 = defaults2;
|
|
6154
|
+
return cachedConfig36;
|
|
6142
6155
|
}
|
|
6143
|
-
const rawText =
|
|
6156
|
+
const rawText = readFileSync46(CONFIG_PATH41, "utf-8");
|
|
6144
6157
|
let raw;
|
|
6145
6158
|
try {
|
|
6146
6159
|
raw = JSON.parse(rawText);
|
|
6147
6160
|
} catch (err) {
|
|
6148
6161
|
const message = err instanceof Error ? err.message : String(err);
|
|
6149
|
-
throw new Error(`Failed to parse ${
|
|
6162
|
+
throw new Error(`Failed to parse ${CONFIG_PATH41}: ${message}`);
|
|
6150
6163
|
}
|
|
6151
6164
|
const gc = raw.githubClone ?? {};
|
|
6152
|
-
|
|
6165
|
+
cachedConfig36 = {
|
|
6153
6166
|
enabled: normalizeEnabled(gc.enabled, defaults2.enabled),
|
|
6154
6167
|
maxRepoSizeMB: normalizePositiveNumber(gc.maxRepoSizeMB, defaults2.maxRepoSizeMB),
|
|
6155
6168
|
cloneTimeoutSeconds: normalizePositiveNumber(gc.cloneTimeoutSeconds, defaults2.cloneTimeoutSeconds),
|
|
6156
6169
|
clonePath: normalizeClonePath(gc.clonePath, defaults2.clonePath)
|
|
6157
6170
|
};
|
|
6158
|
-
return
|
|
6171
|
+
return cachedConfig36;
|
|
6159
6172
|
}
|
|
6160
6173
|
function parseGitHubUrl(url) {
|
|
6161
6174
|
let parsed;
|
|
@@ -6206,7 +6219,7 @@ function cacheKey(owner, repo, ref) {
|
|
|
6206
6219
|
}
|
|
6207
6220
|
function readLinuxBootId() {
|
|
6208
6221
|
try {
|
|
6209
|
-
const bootId =
|
|
6222
|
+
const bootId = readFileSync46("/proc/sys/kernel/random/boot_id", "utf-8").trim();
|
|
6210
6223
|
return bootId.length > 0 ? bootId : null;
|
|
6211
6224
|
} catch {
|
|
6212
6225
|
return null;
|
|
@@ -6231,7 +6244,7 @@ function parseLinuxProcessInfo(stat) {
|
|
|
6231
6244
|
}
|
|
6232
6245
|
function readLinuxProcessInfo(pid) {
|
|
6233
6246
|
try {
|
|
6234
|
-
return parseLinuxProcessInfo(
|
|
6247
|
+
return parseLinuxProcessInfo(readFileSync46(`/proc/${pid}/stat`, "utf-8"));
|
|
6235
6248
|
} catch (err) {
|
|
6236
6249
|
if (err && typeof err === "object" && "code" in err && err.code === "ENOENT") {
|
|
6237
6250
|
return { state: "", startTime: null, dead: true };
|
|
@@ -6273,10 +6286,10 @@ function writeCloneRuntimeOwner(runtimePath) {
|
|
|
6273
6286
|
mode: 384
|
|
6274
6287
|
});
|
|
6275
6288
|
}
|
|
6276
|
-
function parseCloneRuntimeOwner(
|
|
6289
|
+
function parseCloneRuntimeOwner(text4) {
|
|
6277
6290
|
let parsed;
|
|
6278
6291
|
try {
|
|
6279
|
-
parsed = JSON.parse(
|
|
6292
|
+
parsed = JSON.parse(text4);
|
|
6280
6293
|
} catch {
|
|
6281
6294
|
return null;
|
|
6282
6295
|
}
|
|
@@ -6569,7 +6582,7 @@ function resolveWithinRepo(rootPath, relativePath) {
|
|
|
6569
6582
|
const rootPrefix = normalizedRoot.endsWith(pathSep) ? normalizedRoot : normalizedRoot + pathSep;
|
|
6570
6583
|
if (!candidate.startsWith(rootPrefix)) return null;
|
|
6571
6584
|
}
|
|
6572
|
-
if (!
|
|
6585
|
+
if (!existsSync44(candidate)) return candidate;
|
|
6573
6586
|
try {
|
|
6574
6587
|
const realRoot = realpathSync2(normalizedRoot);
|
|
6575
6588
|
const realCandidate = realpathSync2(candidate);
|
|
@@ -6582,7 +6595,7 @@ function resolveWithinRepo(rootPath, relativePath) {
|
|
|
6582
6595
|
}
|
|
6583
6596
|
function readTextFile(path) {
|
|
6584
6597
|
try {
|
|
6585
|
-
return
|
|
6598
|
+
return readFileSync46(path, "utf-8");
|
|
6586
6599
|
} catch {
|
|
6587
6600
|
return null;
|
|
6588
6601
|
}
|
|
@@ -6665,9 +6678,9 @@ function readReadme(localPath) {
|
|
|
6665
6678
|
const candidates = ["README.md", "readme.md", "README", "README.txt", "README.rst"];
|
|
6666
6679
|
for (const name of candidates) {
|
|
6667
6680
|
const readmePath = join6(localPath, name);
|
|
6668
|
-
if (
|
|
6681
|
+
if (existsSync44(readmePath)) {
|
|
6669
6682
|
try {
|
|
6670
|
-
const content =
|
|
6683
|
+
const content = readFileSync46(readmePath, "utf-8");
|
|
6671
6684
|
return content.length > 8192 ? content.slice(0, 8192) + "\n\n[README truncated at 8K chars]" : content;
|
|
6672
6685
|
} catch {
|
|
6673
6686
|
continue;
|
|
@@ -6696,7 +6709,7 @@ function generateContent(localPath, info) {
|
|
|
6696
6709
|
if (info.type === "tree") {
|
|
6697
6710
|
const dirPath = info.path || "";
|
|
6698
6711
|
const fullDirPath = resolveWithinRepo(localPath, dirPath);
|
|
6699
|
-
if (!fullDirPath || !
|
|
6712
|
+
if (!fullDirPath || !existsSync44(fullDirPath)) {
|
|
6700
6713
|
lines.push(`Path \`${dirPath}\` not found in clone. Showing repository root instead.`);
|
|
6701
6714
|
lines.push("");
|
|
6702
6715
|
lines.push("## Structure");
|
|
@@ -6712,7 +6725,7 @@ function generateContent(localPath, info) {
|
|
|
6712
6725
|
if (info.type === "blob") {
|
|
6713
6726
|
const filePath = info.path || "";
|
|
6714
6727
|
const fullFilePath = resolveWithinRepo(localPath, filePath);
|
|
6715
|
-
if (!fullFilePath || !
|
|
6728
|
+
if (!fullFilePath || !existsSync44(fullFilePath)) {
|
|
6716
6729
|
lines.push(`Path \`${filePath}\` not found in clone. Showing repository root instead.`);
|
|
6717
6730
|
lines.push("");
|
|
6718
6731
|
lines.push("## Structure");
|
|
@@ -6785,7 +6798,10 @@ async function extractGitHub(url, signal, forceClone) {
|
|
|
6785
6798
|
const { owner, repo } = info;
|
|
6786
6799
|
const key = cacheKey(owner, repo, info.ref);
|
|
6787
6800
|
const cached = cloneCache.get(key);
|
|
6788
|
-
if (cached)
|
|
6801
|
+
if (cached) {
|
|
6802
|
+
cached.lastUsedAt = Date.now();
|
|
6803
|
+
return awaitCachedClone(cached, url, owner, repo, info, signal);
|
|
6804
|
+
}
|
|
6789
6805
|
if (info.refIsFullSha) {
|
|
6790
6806
|
if (signal?.aborted) return null;
|
|
6791
6807
|
const sizeNote = `Note: Commit SHA URLs use the GitHub API instead of cloning.`;
|
|
@@ -6822,6 +6838,7 @@ async function extractGitHub(url, signal, forceClone) {
|
|
|
6822
6838
|
}
|
|
6823
6839
|
const cachedAfterSizeCheck = cloneCache.get(key);
|
|
6824
6840
|
if (cachedAfterSizeCheck) {
|
|
6841
|
+
cachedAfterSizeCheck.lastUsedAt = Date.now();
|
|
6825
6842
|
const cachedResult = await awaitCachedClone(cachedAfterSizeCheck, url, owner, repo, info, signal);
|
|
6826
6843
|
if (signal?.aborted) {
|
|
6827
6844
|
activityMonitor.logComplete(activityId, 0);
|
|
@@ -6840,7 +6857,11 @@ async function extractGitHub(url, signal, forceClone) {
|
|
|
6840
6857
|
return apiFallback;
|
|
6841
6858
|
}
|
|
6842
6859
|
const clonePromise = cloneRepo(owner, repo, info.ref, config, destination, signal);
|
|
6843
|
-
|
|
6860
|
+
const entry = { destination, clonePromise, lastUsedAt: Date.now(), settled: false };
|
|
6861
|
+
cloneCache.set(key, entry);
|
|
6862
|
+
void clonePromise.finally(() => {
|
|
6863
|
+
entry.settled = true;
|
|
6864
|
+
});
|
|
6844
6865
|
const result = await clonePromise;
|
|
6845
6866
|
if (signal?.aborted) {
|
|
6846
6867
|
if (!result) cloneCache.delete(key);
|
|
@@ -6866,13 +6887,13 @@ async function extractGitHub(url, signal, forceClone) {
|
|
|
6866
6887
|
const title = info.path ? `${owner}/${repo} - ${info.path}` : `${owner}/${repo}`;
|
|
6867
6888
|
return { url, title, content, error: null };
|
|
6868
6889
|
}
|
|
6869
|
-
var
|
|
6890
|
+
var CONFIG_PATH41, BINARY_EXTENSIONS, NOISE_DIRS, MAX_INLINE_FILE_CHARS2, MAX_TREE_ENTRIES2, CLONE_RUNTIME_OWNER_FILENAME, CLONE_RUNTIME_OWNER_VERSION, MAX_CLONE_RUNTIME_OWNER_BYTES, cloneCache, startedCloneRuntimeCleanups, cachedConfig36, cloneRuntime, NON_CODE_SEGMENTS, PROCESS_KILL_GRACE_MS;
|
|
6870
6891
|
var init_github_extract = __esm({
|
|
6871
6892
|
"github-extract.ts"() {
|
|
6872
6893
|
init_activity();
|
|
6873
6894
|
init_github_api();
|
|
6874
6895
|
init_utils();
|
|
6875
|
-
|
|
6896
|
+
CONFIG_PATH41 = getWebSearchConfigPath();
|
|
6876
6897
|
BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
6877
6898
|
".png",
|
|
6878
6899
|
".jpg",
|
|
@@ -6960,7 +6981,7 @@ var init_github_extract = __esm({
|
|
|
6960
6981
|
MAX_CLONE_RUNTIME_OWNER_BYTES = 1024;
|
|
6961
6982
|
cloneCache = /* @__PURE__ */ new Map();
|
|
6962
6983
|
startedCloneRuntimeCleanups = /* @__PURE__ */ new Set();
|
|
6963
|
-
|
|
6984
|
+
cachedConfig36 = null;
|
|
6964
6985
|
cloneRuntime = null;
|
|
6965
6986
|
NON_CODE_SEGMENTS = /* @__PURE__ */ new Set([
|
|
6966
6987
|
"issues",
|
|
@@ -6999,29 +7020,29 @@ var init_github_extract = __esm({
|
|
|
6999
7020
|
|
|
7000
7021
|
// github-issue-pr.ts
|
|
7001
7022
|
import { execFile as execFile4 } from "node:child_process";
|
|
7002
|
-
import { existsSync as
|
|
7003
|
-
function
|
|
7004
|
-
if (
|
|
7023
|
+
import { existsSync as existsSync45, readFileSync as readFileSync47 } from "node:fs";
|
|
7024
|
+
function loadConfig37() {
|
|
7025
|
+
if (cachedConfig37) return cachedConfig37;
|
|
7005
7026
|
const defaults2 = { enabled: true };
|
|
7006
|
-
if (!
|
|
7007
|
-
|
|
7008
|
-
return
|
|
7027
|
+
if (!existsSync45(CONFIG_PATH42)) {
|
|
7028
|
+
cachedConfig37 = defaults2;
|
|
7029
|
+
return cachedConfig37;
|
|
7009
7030
|
}
|
|
7010
7031
|
let parsed;
|
|
7011
7032
|
try {
|
|
7012
|
-
parsed = JSON.parse(
|
|
7033
|
+
parsed = JSON.parse(readFileSync47(CONFIG_PATH42, "utf-8"));
|
|
7013
7034
|
} catch (err) {
|
|
7014
7035
|
const message = err instanceof Error ? err.message : String(err);
|
|
7015
|
-
throw new Error(`Failed to parse ${
|
|
7036
|
+
throw new Error(`Failed to parse ${CONFIG_PATH42}: ${message}`);
|
|
7016
7037
|
}
|
|
7017
7038
|
const root = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
7018
7039
|
const value = root.githubPrIssue;
|
|
7019
7040
|
if (value !== void 0 && (typeof value !== "object" || value === null || Array.isArray(value))) {
|
|
7020
|
-
throw new Error(`githubPrIssue in ${
|
|
7041
|
+
throw new Error(`githubPrIssue in ${CONFIG_PATH42} must be an object`);
|
|
7021
7042
|
}
|
|
7022
7043
|
const enabled = typeof value?.enabled === "boolean" ? value.enabled : true;
|
|
7023
|
-
|
|
7024
|
-
return
|
|
7044
|
+
cachedConfig37 = { enabled };
|
|
7045
|
+
return cachedConfig37;
|
|
7025
7046
|
}
|
|
7026
7047
|
function validOwner(owner) {
|
|
7027
7048
|
return /^[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/.test(owner) && !owner.includes("--");
|
|
@@ -7029,11 +7050,11 @@ function validOwner(owner) {
|
|
|
7029
7050
|
function validRepo(repo) {
|
|
7030
7051
|
return /^[A-Za-z0-9._-]{1,100}$/.test(repo) && repo !== "." && repo !== "..";
|
|
7031
7052
|
}
|
|
7032
|
-
function
|
|
7053
|
+
function errorMessage28(err) {
|
|
7033
7054
|
return err instanceof Error ? err.message : String(err);
|
|
7034
7055
|
}
|
|
7035
7056
|
function isAbortError3(err) {
|
|
7036
|
-
return
|
|
7057
|
+
return errorMessage28(err).toLowerCase().includes("abort");
|
|
7037
7058
|
}
|
|
7038
7059
|
function parseGitHubIssuePrUrl(url) {
|
|
7039
7060
|
let parsed;
|
|
@@ -7269,7 +7290,7 @@ async function restFallback(url, info, options, signal) {
|
|
|
7269
7290
|
return { data: { url, owner: info.owner, repo: info.repo, kind: info.kind, number: info.number, anchor: info.anchor, view, reviewThreads, fallbackNotes: notes } };
|
|
7270
7291
|
} catch (err) {
|
|
7271
7292
|
if (signal?.aborted || isAbortError3(err)) return { url, title: "", content: "", error: "Aborted" };
|
|
7272
|
-
const message =
|
|
7293
|
+
const message = errorMessage28(err);
|
|
7273
7294
|
return { url, title: `${info.owner}/${info.repo}#${info.number}`, content: message, error: `GitHub REST fallback failed: ${message}` };
|
|
7274
7295
|
}
|
|
7275
7296
|
}
|
|
@@ -7327,12 +7348,12 @@ function milestoneTitle(value) {
|
|
|
7327
7348
|
if (!value || typeof value !== "object" || Array.isArray(value)) return "none";
|
|
7328
7349
|
return stringValue(value.title) || "none";
|
|
7329
7350
|
}
|
|
7330
|
-
function truncateText(
|
|
7331
|
-
if (
|
|
7351
|
+
function truncateText(text4, limit, label, appendix) {
|
|
7352
|
+
if (text4.length <= limit) return text4;
|
|
7332
7353
|
appendix.push(`## Full ${label}
|
|
7333
7354
|
|
|
7334
|
-
${
|
|
7335
|
-
return `${
|
|
7355
|
+
${text4}`);
|
|
7356
|
+
return `${text4.slice(0, limit)}
|
|
7336
7357
|
|
|
7337
7358
|
[${label} truncated; use get_search_content findText or offset for the full text]`;
|
|
7338
7359
|
}
|
|
@@ -7562,7 +7583,7 @@ function renderGitHubPrIssue(data) {
|
|
|
7562
7583
|
async function extractGitHubIssuePr(url, signal, options) {
|
|
7563
7584
|
const info = parseGitHubIssuePrUrl(url);
|
|
7564
7585
|
if (!info) return null;
|
|
7565
|
-
if (!
|
|
7586
|
+
if (!loadConfig37().enabled) return null;
|
|
7566
7587
|
if (signal?.aborted) return { url, title: "", content: "", error: "Aborted" };
|
|
7567
7588
|
const ghAvailable2 = await checkGhAvailable(signal);
|
|
7568
7589
|
if (signal?.aborted) return { url, title: "", content: "", error: "Aborted" };
|
|
@@ -7585,13 +7606,13 @@ async function extractGitHubIssuePr(url, signal, options) {
|
|
|
7585
7606
|
if ("data" in fallback) return renderGitHubPrIssue(fallback.data);
|
|
7586
7607
|
return fallback;
|
|
7587
7608
|
}
|
|
7588
|
-
var
|
|
7609
|
+
var CONFIG_PATH42, GH_TIMEOUT_MS, GH_TOTAL_TIMEOUT_MS, MAX_DOC_CHARS, BODY_INLINE_CHARS, COMMENT_INLINE_CHARS, MAX_INLINE_COMMENTS, MAX_INLINE_REVIEWS, MAX_INLINE_CHECKS, MAX_INLINE_FILES, MAX_INLINE_COMMITS, MAX_INLINE_REVIEW_THREADS, REST_HEADERS, PR_SUBPATHS, PR_FIELDS, PR_CORE_FIELDS, ISSUE_FIELDS, ISSUE_CORE_FIELDS, cachedConfig37;
|
|
7589
7610
|
var init_github_issue_pr = __esm({
|
|
7590
7611
|
"github-issue-pr.ts"() {
|
|
7591
7612
|
init_github_api();
|
|
7592
7613
|
init_ssrf_protection();
|
|
7593
7614
|
init_utils();
|
|
7594
|
-
|
|
7615
|
+
CONFIG_PATH42 = getWebSearchConfigPath();
|
|
7595
7616
|
GH_TIMEOUT_MS = 1e4;
|
|
7596
7617
|
GH_TOTAL_TIMEOUT_MS = 2e4;
|
|
7597
7618
|
MAX_DOC_CHARS = 15e4;
|
|
@@ -7672,20 +7693,20 @@ var init_github_issue_pr = __esm({
|
|
|
7672
7693
|
"url"
|
|
7673
7694
|
];
|
|
7674
7695
|
ISSUE_CORE_FIELDS = ["title", "number", "state", "author", "createdAt", "closedAt", "labels", "assignees", "milestone", "comments", "body", "url"];
|
|
7675
|
-
|
|
7696
|
+
cachedConfig37 = null;
|
|
7676
7697
|
}
|
|
7677
7698
|
});
|
|
7678
7699
|
|
|
7679
7700
|
// feature-config.ts
|
|
7680
|
-
import { existsSync as
|
|
7701
|
+
import { existsSync as existsSync46, readFileSync as readFileSync48 } from "node:fs";
|
|
7681
7702
|
function loadFeatureConfig() {
|
|
7682
|
-
if (!
|
|
7703
|
+
if (!existsSync46(CONFIG_PATH43)) return {};
|
|
7683
7704
|
try {
|
|
7684
|
-
const raw = JSON.parse(
|
|
7705
|
+
const raw = JSON.parse(readFileSync48(CONFIG_PATH43, "utf-8"));
|
|
7685
7706
|
return raw && typeof raw === "object" ? raw : {};
|
|
7686
7707
|
} catch (err) {
|
|
7687
7708
|
const message = err instanceof Error ? err.message : String(err);
|
|
7688
|
-
throw new Error(`Failed to parse ${
|
|
7709
|
+
throw new Error(`Failed to parse ${CONFIG_PATH43}: ${message}`);
|
|
7689
7710
|
}
|
|
7690
7711
|
}
|
|
7691
7712
|
function isImageEnabled() {
|
|
@@ -7698,25 +7719,25 @@ function canAttachImages() {
|
|
|
7698
7719
|
return false;
|
|
7699
7720
|
}
|
|
7700
7721
|
}
|
|
7701
|
-
var
|
|
7722
|
+
var CONFIG_PATH43;
|
|
7702
7723
|
var init_feature_config = __esm({
|
|
7703
7724
|
"feature-config.ts"() {
|
|
7704
7725
|
init_utils();
|
|
7705
|
-
|
|
7726
|
+
CONFIG_PATH43 = getWebSearchConfigPath();
|
|
7706
7727
|
}
|
|
7707
7728
|
});
|
|
7708
7729
|
|
|
7709
7730
|
// youtube-extract.ts
|
|
7710
7731
|
import { execFileSync } from "node:child_process";
|
|
7711
|
-
import { existsSync as
|
|
7712
|
-
function
|
|
7732
|
+
import { existsSync as existsSync47, readFileSync as readFileSync49 } from "node:fs";
|
|
7733
|
+
function errorMessage29(err) {
|
|
7713
7734
|
return err instanceof Error ? err.message : String(err);
|
|
7714
7735
|
}
|
|
7715
7736
|
function shouldRethrow(err) {
|
|
7716
|
-
return
|
|
7737
|
+
return errorMessage29(err).startsWith("Failed to parse ");
|
|
7717
7738
|
}
|
|
7718
7739
|
function addAttemptError(errors, label, err) {
|
|
7719
|
-
const message =
|
|
7740
|
+
const message = errorMessage29(err).replace(/\s+/g, " ").trim();
|
|
7720
7741
|
if (message) errors.push(`${label}: ${message}`);
|
|
7721
7742
|
}
|
|
7722
7743
|
function normalizePreferredModel(value, fallback) {
|
|
@@ -7728,25 +7749,25 @@ function normalizeEnabled2(value, fallback) {
|
|
|
7728
7749
|
return typeof value === "boolean" ? value : fallback;
|
|
7729
7750
|
}
|
|
7730
7751
|
function loadYouTubeConfig() {
|
|
7731
|
-
if (
|
|
7732
|
-
if (!
|
|
7733
|
-
|
|
7734
|
-
return
|
|
7752
|
+
if (cachedConfig38) return cachedConfig38;
|
|
7753
|
+
if (!existsSync47(CONFIG_PATH44)) {
|
|
7754
|
+
cachedConfig38 = { ...defaults };
|
|
7755
|
+
return cachedConfig38;
|
|
7735
7756
|
}
|
|
7736
|
-
const rawText =
|
|
7757
|
+
const rawText = readFileSync49(CONFIG_PATH44, "utf-8");
|
|
7737
7758
|
let raw;
|
|
7738
7759
|
try {
|
|
7739
7760
|
raw = JSON.parse(rawText);
|
|
7740
7761
|
} catch (err) {
|
|
7741
7762
|
const message = err instanceof Error ? err.message : String(err);
|
|
7742
|
-
throw new Error(`Failed to parse ${
|
|
7763
|
+
throw new Error(`Failed to parse ${CONFIG_PATH44}: ${message}`);
|
|
7743
7764
|
}
|
|
7744
7765
|
const yt = raw.youtube ?? {};
|
|
7745
|
-
|
|
7766
|
+
cachedConfig38 = {
|
|
7746
7767
|
enabled: normalizeEnabled2(yt.enabled, defaults.enabled),
|
|
7747
7768
|
preferredModel: normalizePreferredModel(yt.preferredModel, defaults.preferredModel)
|
|
7748
7769
|
};
|
|
7749
|
-
return
|
|
7770
|
+
return cachedConfig38;
|
|
7750
7771
|
}
|
|
7751
7772
|
function isYouTubeURL(url) {
|
|
7752
7773
|
try {
|
|
@@ -7876,7 +7897,7 @@ async function tryGeminiWeb(url, prompt, model, signal, attemptErrors) {
|
|
|
7876
7897
|
const cookies = await isGeminiWebAvailable();
|
|
7877
7898
|
if (!cookies) return null;
|
|
7878
7899
|
if (signal?.aborted) return null;
|
|
7879
|
-
const
|
|
7900
|
+
const text4 = await queryWithCookies(prompt, cookies, {
|
|
7880
7901
|
youtubeUrl: url,
|
|
7881
7902
|
...model !== "gemini-3.6-flash" ? { model } : {},
|
|
7882
7903
|
signal,
|
|
@@ -7884,8 +7905,8 @@ async function tryGeminiWeb(url, prompt, model, signal, attemptErrors) {
|
|
|
7884
7905
|
});
|
|
7885
7906
|
return {
|
|
7886
7907
|
url,
|
|
7887
|
-
title: extractHeadingTitle(
|
|
7888
|
-
content:
|
|
7908
|
+
title: extractHeadingTitle(text4) ?? "YouTube Video",
|
|
7909
|
+
content: text4,
|
|
7889
7910
|
error: null
|
|
7890
7911
|
};
|
|
7891
7912
|
} catch (err) {
|
|
@@ -7898,15 +7919,15 @@ async function tryGeminiApi(url, prompt, model, signal, attemptErrors) {
|
|
|
7898
7919
|
try {
|
|
7899
7920
|
if (!isGeminiApiAvailableWithVideo()) return null;
|
|
7900
7921
|
if (signal?.aborted) return null;
|
|
7901
|
-
const
|
|
7922
|
+
const text4 = await queryGeminiApiWithVideo(prompt, url, {
|
|
7902
7923
|
model,
|
|
7903
7924
|
signal,
|
|
7904
7925
|
timeoutMs: 12e4
|
|
7905
7926
|
});
|
|
7906
7927
|
return {
|
|
7907
7928
|
url,
|
|
7908
|
-
title: extractHeadingTitle(
|
|
7909
|
-
content:
|
|
7929
|
+
title: extractHeadingTitle(text4) ?? "YouTube Video",
|
|
7930
|
+
content: text4,
|
|
7910
7931
|
error: null
|
|
7911
7932
|
};
|
|
7912
7933
|
} catch (err) {
|
|
@@ -7938,7 +7959,7 @@ ${answer}
|
|
|
7938
7959
|
return null;
|
|
7939
7960
|
}
|
|
7940
7961
|
}
|
|
7941
|
-
var
|
|
7962
|
+
var CONFIG_PATH44, YOUTUBE_PROMPT, YOUTUBE_REGEX, defaults, cachedConfig38;
|
|
7942
7963
|
var init_youtube_extract = __esm({
|
|
7943
7964
|
"youtube-extract.ts"() {
|
|
7944
7965
|
init_activity();
|
|
@@ -7948,7 +7969,7 @@ var init_youtube_extract = __esm({
|
|
|
7948
7969
|
init_perplexity();
|
|
7949
7970
|
init_extract();
|
|
7950
7971
|
init_utils();
|
|
7951
|
-
|
|
7972
|
+
CONFIG_PATH44 = getWebSearchConfigPath();
|
|
7952
7973
|
YOUTUBE_PROMPT = `Extract the complete content of this YouTube video. Include:
|
|
7953
7974
|
1. Video title, channel name, and duration
|
|
7954
7975
|
2. A brief summary (2-3 sentences)
|
|
@@ -7958,7 +7979,7 @@ var init_youtube_extract = __esm({
|
|
|
7958
7979
|
Format as markdown.`;
|
|
7959
7980
|
YOUTUBE_REGEX = /(?:(?:www\.|m\.)?youtube\.com\/(?:watch\?.*v=|shorts\/|live\/|embed\/|v\/)|youtu\.be\/)([a-zA-Z0-9_-]{11})/;
|
|
7960
7981
|
defaults = { enabled: true, preferredModel: "gemini-3.6-flash" };
|
|
7961
|
-
|
|
7982
|
+
cachedConfig38 = null;
|
|
7962
7983
|
}
|
|
7963
7984
|
});
|
|
7964
7985
|
|
|
@@ -8020,14 +8041,14 @@ async function extractWithGeminiWeb(url, signal) {
|
|
|
8020
8041
|
if (!cookies) return null;
|
|
8021
8042
|
const activityId = activityMonitor.logStart({ type: "api", query: `gemini_web: ${url}` });
|
|
8022
8043
|
try {
|
|
8023
|
-
const
|
|
8044
|
+
const text4 = await queryWithCookies(EXTRACTION_PROMPT + url, cookies, {
|
|
8024
8045
|
signal,
|
|
8025
8046
|
timeoutMs: 6e4
|
|
8026
8047
|
});
|
|
8027
8048
|
activityMonitor.logComplete(activityId, 200);
|
|
8028
|
-
if (!
|
|
8029
|
-
const title = extractTitleFromContent(
|
|
8030
|
-
return { url, title, content:
|
|
8049
|
+
if (!text4 || text4.length < 50) return null;
|
|
8050
|
+
const title = extractTitleFromContent(text4, url);
|
|
8051
|
+
return { url, title, content: text4, error: null };
|
|
8031
8052
|
} catch (err) {
|
|
8032
8053
|
if (shouldRethrow2(err)) throw err;
|
|
8033
8054
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -8039,8 +8060,8 @@ async function extractWithGeminiWeb(url, signal) {
|
|
|
8039
8060
|
return null;
|
|
8040
8061
|
}
|
|
8041
8062
|
}
|
|
8042
|
-
function extractTitleFromContent(
|
|
8043
|
-
return extractHeadingTitle(
|
|
8063
|
+
function extractTitleFromContent(text4, url) {
|
|
8064
|
+
return extractHeadingTitle(text4) ?? (new URL(url).pathname.split("/").pop() || url);
|
|
8044
8065
|
}
|
|
8045
8066
|
var EXTRACTION_PROMPT;
|
|
8046
8067
|
var init_gemini_url_context = __esm({
|
|
@@ -8060,26 +8081,26 @@ URL: `;
|
|
|
8060
8081
|
});
|
|
8061
8082
|
|
|
8062
8083
|
// crawl4ai.ts
|
|
8063
|
-
import { existsSync as
|
|
8064
|
-
function
|
|
8065
|
-
if (
|
|
8066
|
-
if (!
|
|
8067
|
-
|
|
8068
|
-
return
|
|
8084
|
+
import { existsSync as existsSync48, readFileSync as readFileSync50 } from "node:fs";
|
|
8085
|
+
function loadConfig38() {
|
|
8086
|
+
if (cachedConfig39) return cachedConfig39;
|
|
8087
|
+
if (!existsSync48(CONFIG_PATH45)) {
|
|
8088
|
+
cachedConfig39 = {};
|
|
8089
|
+
return cachedConfig39;
|
|
8069
8090
|
}
|
|
8070
|
-
const raw =
|
|
8091
|
+
const raw = readFileSync50(CONFIG_PATH45, "utf8");
|
|
8071
8092
|
let parsed;
|
|
8072
8093
|
try {
|
|
8073
8094
|
parsed = JSON.parse(raw);
|
|
8074
8095
|
} catch (err) {
|
|
8075
8096
|
const message = err instanceof Error ? err.message : String(err);
|
|
8076
|
-
throw new Error(`Failed to parse ${
|
|
8097
|
+
throw new Error(`Failed to parse ${CONFIG_PATH45}: ${message}`);
|
|
8077
8098
|
}
|
|
8078
8099
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
8079
|
-
throw new Error(`Invalid config in ${
|
|
8100
|
+
throw new Error(`Invalid config in ${CONFIG_PATH45}: expected a JSON object`);
|
|
8080
8101
|
}
|
|
8081
|
-
|
|
8082
|
-
return
|
|
8102
|
+
cachedConfig39 = parsed;
|
|
8103
|
+
return cachedConfig39;
|
|
8083
8104
|
}
|
|
8084
8105
|
function normalizeBaseUrl5(value) {
|
|
8085
8106
|
if (typeof value !== "string") return null;
|
|
@@ -8089,13 +8110,13 @@ function normalizeBaseUrl5(value) {
|
|
|
8089
8110
|
try {
|
|
8090
8111
|
parsed = new URL(trimmed);
|
|
8091
8112
|
} catch {
|
|
8092
|
-
throw new Error(`Invalid Crawl4AI base URL in ${
|
|
8113
|
+
throw new Error(`Invalid Crawl4AI base URL in ${CONFIG_PATH45}: expected an HTTP or HTTPS URL`);
|
|
8093
8114
|
}
|
|
8094
8115
|
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
8095
|
-
throw new Error(`Invalid Crawl4AI base URL in ${
|
|
8116
|
+
throw new Error(`Invalid Crawl4AI base URL in ${CONFIG_PATH45}: expected an HTTP or HTTPS URL`);
|
|
8096
8117
|
}
|
|
8097
8118
|
if (parsed.username || parsed.password) {
|
|
8098
|
-
throw new Error(`Invalid Crawl4AI base URL in ${
|
|
8119
|
+
throw new Error(`Invalid Crawl4AI base URL in ${CONFIG_PATH45}: URL credentials are not allowed`);
|
|
8099
8120
|
}
|
|
8100
8121
|
parsed.pathname = parsed.pathname.replace(/\/+$/, "");
|
|
8101
8122
|
parsed.search = "";
|
|
@@ -8103,14 +8124,14 @@ function normalizeBaseUrl5(value) {
|
|
|
8103
8124
|
return parsed.toString().replace(/\/+$/, "");
|
|
8104
8125
|
}
|
|
8105
8126
|
function getBaseUrl4() {
|
|
8106
|
-
return normalizeBaseUrl5(process.env.CRAWL4AI_BASE_URL) ?? normalizeBaseUrl5(
|
|
8127
|
+
return normalizeBaseUrl5(process.env.CRAWL4AI_BASE_URL) ?? normalizeBaseUrl5(loadConfig38().crawl4aiBaseUrl);
|
|
8107
8128
|
}
|
|
8108
8129
|
function requireBaseUrl4() {
|
|
8109
8130
|
const baseUrl = getBaseUrl4();
|
|
8110
8131
|
if (!baseUrl) {
|
|
8111
8132
|
throw new Error(
|
|
8112
8133
|
`Crawl4AI base URL not configured. Either:
|
|
8113
|
-
1. Set crawl4aiBaseUrl in ${
|
|
8134
|
+
1. Set crawl4aiBaseUrl in ${CONFIG_PATH45}
|
|
8114
8135
|
2. Set CRAWL4AI_BASE_URL environment variable`
|
|
8115
8136
|
);
|
|
8116
8137
|
}
|
|
@@ -8119,7 +8140,7 @@ function requireBaseUrl4() {
|
|
|
8119
8140
|
async function getApiToken(signal) {
|
|
8120
8141
|
return resolveCredential({
|
|
8121
8142
|
provider: "Crawl4AI",
|
|
8122
|
-
configuredValue:
|
|
8143
|
+
configuredValue: loadConfig38().crawl4aiApiToken,
|
|
8123
8144
|
environmentValue: process.env.CRAWL4AI_API_TOKEN,
|
|
8124
8145
|
signal
|
|
8125
8146
|
});
|
|
@@ -8128,7 +8149,7 @@ function requestSignal13(timeoutMs, signal) {
|
|
|
8128
8149
|
const timeout = AbortSignal.timeout(timeoutMs);
|
|
8129
8150
|
return signal ? AbortSignal.any([timeout, signal]) : timeout;
|
|
8130
8151
|
}
|
|
8131
|
-
function
|
|
8152
|
+
function errorMessage30(err) {
|
|
8132
8153
|
return err instanceof Error ? err.message : String(err);
|
|
8133
8154
|
}
|
|
8134
8155
|
function isAbortException(err) {
|
|
@@ -8176,8 +8197,8 @@ async function extractWithCrawl4ai(url, signal, options) {
|
|
|
8176
8197
|
}
|
|
8177
8198
|
});
|
|
8178
8199
|
if (!response.ok) {
|
|
8179
|
-
const
|
|
8180
|
-
throw new Error(`Crawl4AI md error ${response.status}: ${redactCredential(
|
|
8200
|
+
const text4 = await response.text().catch(() => "");
|
|
8201
|
+
throw new Error(`Crawl4AI md error ${response.status}: ${redactCredential(text4, token).slice(0, 300)}`);
|
|
8181
8202
|
}
|
|
8182
8203
|
let data;
|
|
8183
8204
|
try {
|
|
@@ -8205,49 +8226,49 @@ async function extractWithCrawl4ai(url, signal, options) {
|
|
|
8205
8226
|
return { url, title: firstHeadingTitle(content), content, error: null };
|
|
8206
8227
|
} catch (err) {
|
|
8207
8228
|
if (signal?.aborted || isAbortException(err)) activityMonitor.logComplete(activityId, 0);
|
|
8208
|
-
else activityMonitor.logError(activityId,
|
|
8229
|
+
else activityMonitor.logError(activityId, errorMessage30(err));
|
|
8209
8230
|
throw err;
|
|
8210
8231
|
}
|
|
8211
8232
|
}
|
|
8212
|
-
var
|
|
8233
|
+
var CONFIG_PATH45, EXTRACT_TIMEOUT_MS2, MARKDOWN_FILTER, cachedConfig39;
|
|
8213
8234
|
var init_crawl4ai = __esm({
|
|
8214
8235
|
"crawl4ai.ts"() {
|
|
8215
8236
|
init_activity();
|
|
8216
8237
|
init_credential_source();
|
|
8217
8238
|
init_ssrf_protection();
|
|
8218
8239
|
init_utils();
|
|
8219
|
-
|
|
8240
|
+
CONFIG_PATH45 = getWebSearchConfigPath();
|
|
8220
8241
|
EXTRACT_TIMEOUT_MS2 = 6e4;
|
|
8221
8242
|
MARKDOWN_FILTER = "fit";
|
|
8222
|
-
|
|
8243
|
+
cachedConfig39 = null;
|
|
8223
8244
|
}
|
|
8224
8245
|
});
|
|
8225
8246
|
|
|
8226
8247
|
// brightdata-unlocker.ts
|
|
8227
|
-
import { existsSync as
|
|
8248
|
+
import { existsSync as existsSync49, readFileSync as readFileSync51 } from "node:fs";
|
|
8228
8249
|
function parseFailureDetail(err) {
|
|
8229
8250
|
const message = err instanceof Error ? err.message : String(err);
|
|
8230
8251
|
const position = message.match(/at position \d+(?: \(line \d+ column \d+\))?/);
|
|
8231
8252
|
return position ? `invalid JSON ${position[0]}` : "invalid JSON";
|
|
8232
8253
|
}
|
|
8233
|
-
function
|
|
8234
|
-
if (
|
|
8235
|
-
if (!
|
|
8236
|
-
|
|
8237
|
-
return
|
|
8254
|
+
function loadConfig39() {
|
|
8255
|
+
if (cachedConfig40) return cachedConfig40;
|
|
8256
|
+
if (!existsSync49(CONFIG_PATH46)) {
|
|
8257
|
+
cachedConfig40 = {};
|
|
8258
|
+
return cachedConfig40;
|
|
8238
8259
|
}
|
|
8239
|
-
const raw =
|
|
8260
|
+
const raw = readFileSync51(CONFIG_PATH46, "utf8");
|
|
8240
8261
|
let parsed;
|
|
8241
8262
|
try {
|
|
8242
8263
|
parsed = JSON.parse(raw);
|
|
8243
8264
|
} catch (err) {
|
|
8244
|
-
throw new Error(`Failed to parse ${
|
|
8265
|
+
throw new Error(`Failed to parse ${CONFIG_PATH46}: ${parseFailureDetail(err)}`);
|
|
8245
8266
|
}
|
|
8246
8267
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
8247
|
-
throw new Error(`Invalid config in ${
|
|
8268
|
+
throw new Error(`Invalid config in ${CONFIG_PATH46}: expected a JSON object`);
|
|
8248
8269
|
}
|
|
8249
|
-
|
|
8250
|
-
return
|
|
8270
|
+
cachedConfig40 = parsed;
|
|
8271
|
+
return cachedConfig40;
|
|
8251
8272
|
}
|
|
8252
8273
|
function normalizeZone2(value) {
|
|
8253
8274
|
if (typeof value !== "string") return null;
|
|
@@ -8258,8 +8279,8 @@ function normalizeZone2(value) {
|
|
|
8258
8279
|
function zoneSetting() {
|
|
8259
8280
|
const fromEnv = process.env.BRIGHTDATA_UNLOCKER_ZONE;
|
|
8260
8281
|
if (typeof fromEnv === "string" && fromEnv.trim()) return { raw: fromEnv.trim(), label: "BRIGHTDATA_UNLOCKER_ZONE" };
|
|
8261
|
-
const configured =
|
|
8262
|
-
if (typeof configured === "string" && configured.trim()) return { raw: configured.trim(), label: `brightdataUnlockerZone in ${
|
|
8282
|
+
const configured = loadConfig39().brightdataUnlockerZone;
|
|
8283
|
+
if (typeof configured === "string" && configured.trim()) return { raw: configured.trim(), label: `brightdataUnlockerZone in ${CONFIG_PATH46}` };
|
|
8263
8284
|
return null;
|
|
8264
8285
|
}
|
|
8265
8286
|
function getZone() {
|
|
@@ -8277,7 +8298,7 @@ function requireZone() {
|
|
|
8277
8298
|
}
|
|
8278
8299
|
throw new Error(
|
|
8279
8300
|
`Bright Data Web Unlocker zone not configured. Either:
|
|
8280
|
-
1. Set brightdataUnlockerZone in ${
|
|
8301
|
+
1. Set brightdataUnlockerZone in ${CONFIG_PATH46}
|
|
8281
8302
|
2. Set BRIGHTDATA_UNLOCKER_ZONE environment variable
|
|
8282
8303
|
The zone must be of type "unblocker"; a SERP zone will not serve Web Unlocker requests.`
|
|
8283
8304
|
);
|
|
@@ -8285,14 +8306,14 @@ The zone must be of type "unblocker"; a SERP zone will not serve Web Unlocker re
|
|
|
8285
8306
|
async function getApiKey27(signal) {
|
|
8286
8307
|
const apiKey = await resolveCredential({
|
|
8287
8308
|
provider: "Bright Data",
|
|
8288
|
-
configuredValue:
|
|
8309
|
+
configuredValue: loadConfig39().brightdataApiKey,
|
|
8289
8310
|
environmentValue: process.env.BRIGHTDATA_API_KEY,
|
|
8290
8311
|
signal
|
|
8291
8312
|
});
|
|
8292
8313
|
if (!apiKey) {
|
|
8293
8314
|
throw new Error(
|
|
8294
8315
|
`Bright Data API key not found. Either:
|
|
8295
|
-
1. Create ${
|
|
8316
|
+
1. Create ${CONFIG_PATH46} with { "brightdataApiKey": "your-key" }
|
|
8296
8317
|
2. Set BRIGHTDATA_API_KEY environment variable
|
|
8297
8318
|
Get a key at https://brightdata.com/cp/setting/users`
|
|
8298
8319
|
);
|
|
@@ -8303,11 +8324,11 @@ function requestSignal14(timeoutMs, signal) {
|
|
|
8303
8324
|
const timeout = AbortSignal.timeout(timeoutMs);
|
|
8304
8325
|
return signal ? AbortSignal.any([timeout, signal]) : timeout;
|
|
8305
8326
|
}
|
|
8306
|
-
function
|
|
8327
|
+
function errorMessage31(err) {
|
|
8307
8328
|
return err instanceof Error ? err.message : String(err);
|
|
8308
8329
|
}
|
|
8309
8330
|
function isAbortError4(err) {
|
|
8310
|
-
return
|
|
8331
|
+
return errorMessage31(err).toLowerCase().includes("abort");
|
|
8311
8332
|
}
|
|
8312
8333
|
function ssrfOptions3(options) {
|
|
8313
8334
|
return {
|
|
@@ -8366,11 +8387,11 @@ async function brightDataRequest(url, zone, signal, options) {
|
|
|
8366
8387
|
const errorText = await response.text().catch(() => "");
|
|
8367
8388
|
throw new Error(`Bright Data Web Unlocker error ${response.status}: ${redactCredential(errorText, apiKey).slice(0, 300)}`);
|
|
8368
8389
|
}
|
|
8369
|
-
const
|
|
8390
|
+
const text4 = await response.text();
|
|
8370
8391
|
activityMonitor.logComplete(activityId, response.status);
|
|
8371
|
-
return
|
|
8392
|
+
return text4;
|
|
8372
8393
|
} catch (err) {
|
|
8373
|
-
const message =
|
|
8394
|
+
const message = errorMessage31(err);
|
|
8374
8395
|
const redactedMessage = redactCredential(message, apiKey);
|
|
8375
8396
|
if (isAbortError4(err)) activityMonitor.logComplete(activityId, 0);
|
|
8376
8397
|
else activityMonitor.logError(activityId, redactedMessage);
|
|
@@ -8380,8 +8401,8 @@ async function brightDataRequest(url, zone, signal, options) {
|
|
|
8380
8401
|
throw redactedError;
|
|
8381
8402
|
}
|
|
8382
8403
|
}
|
|
8383
|
-
function headingTitle(
|
|
8384
|
-
const match =
|
|
8404
|
+
function headingTitle(text4) {
|
|
8405
|
+
const match = text4.match(/^#{1,2}\s+(.+)/m);
|
|
8385
8406
|
if (!match) return "";
|
|
8386
8407
|
return match[1].replace(/\*+/g, "").trim();
|
|
8387
8408
|
}
|
|
@@ -8389,7 +8410,7 @@ function isBrightDataUnlockerAvailable() {
|
|
|
8389
8410
|
if (getZone() === null) return false;
|
|
8390
8411
|
return hasCredentialSource({
|
|
8391
8412
|
provider: "Bright Data",
|
|
8392
|
-
configuredValue:
|
|
8413
|
+
configuredValue: loadConfig39().brightdataApiKey,
|
|
8393
8414
|
environmentValue: process.env.BRIGHTDATA_API_KEY
|
|
8394
8415
|
});
|
|
8395
8416
|
}
|
|
@@ -8401,26 +8422,26 @@ async function extractWithBrightDataUnlocker(url, signal, options) {
|
|
|
8401
8422
|
if (!content) return null;
|
|
8402
8423
|
return { url, title: headingTitle(content), content, error: null };
|
|
8403
8424
|
}
|
|
8404
|
-
var
|
|
8425
|
+
var CONFIG_PATH46, BRIGHTDATA_REQUEST_URL, EXTRACT_TIMEOUT_MS3, DEFAULT_MAX_REDIRECTS3, REDIRECT_STATUSES3, ZONE_PATTERN2, cachedConfig40;
|
|
8405
8426
|
var init_brightdata_unlocker = __esm({
|
|
8406
8427
|
"brightdata-unlocker.ts"() {
|
|
8407
8428
|
init_activity();
|
|
8408
8429
|
init_credential_source();
|
|
8409
8430
|
init_ssrf_protection();
|
|
8410
8431
|
init_utils();
|
|
8411
|
-
|
|
8432
|
+
CONFIG_PATH46 = getWebSearchConfigPath();
|
|
8412
8433
|
BRIGHTDATA_REQUEST_URL = "https://api.brightdata.com/request";
|
|
8413
8434
|
EXTRACT_TIMEOUT_MS3 = 6e4;
|
|
8414
8435
|
DEFAULT_MAX_REDIRECTS3 = 5;
|
|
8415
8436
|
REDIRECT_STATUSES3 = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
|
|
8416
8437
|
ZONE_PATTERN2 = /^[a-z0-9_-]+$/i;
|
|
8417
|
-
|
|
8438
|
+
cachedConfig40 = null;
|
|
8418
8439
|
}
|
|
8419
8440
|
});
|
|
8420
8441
|
|
|
8421
8442
|
// video-extract.ts
|
|
8422
8443
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
8423
|
-
import { existsSync as
|
|
8444
|
+
import { existsSync as existsSync50, readFileSync as readFileSync52, readdirSync as readdirSync4, statSync as statSync3 } from "node:fs";
|
|
8424
8445
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
8425
8446
|
import { resolve, extname as extname2, basename as basename4, join as join7, dirname as dirname2 } from "node:path";
|
|
8426
8447
|
function shouldRethrow3(err) {
|
|
@@ -8441,17 +8462,17 @@ function normalizeMaxSizeMB(value, fallback) {
|
|
|
8441
8462
|
}
|
|
8442
8463
|
function loadVideoConfig() {
|
|
8443
8464
|
if (cachedVideoConfig) return cachedVideoConfig;
|
|
8444
|
-
if (!
|
|
8465
|
+
if (!existsSync50(CONFIG_PATH47)) {
|
|
8445
8466
|
cachedVideoConfig = { ...VIDEO_CONFIG_DEFAULTS };
|
|
8446
8467
|
return cachedVideoConfig;
|
|
8447
8468
|
}
|
|
8448
|
-
const rawText =
|
|
8469
|
+
const rawText = readFileSync52(CONFIG_PATH47, "utf-8");
|
|
8449
8470
|
let raw;
|
|
8450
8471
|
try {
|
|
8451
8472
|
raw = JSON.parse(rawText);
|
|
8452
8473
|
} catch (err) {
|
|
8453
8474
|
const message = err instanceof Error ? err.message : String(err);
|
|
8454
|
-
throw new Error(`Failed to parse ${
|
|
8475
|
+
throw new Error(`Failed to parse ${CONFIG_PATH47}: ${message}`);
|
|
8455
8476
|
}
|
|
8456
8477
|
const v = raw.video ?? {};
|
|
8457
8478
|
cachedVideoConfig = {
|
|
@@ -8497,10 +8518,10 @@ function isVideoFile(input) {
|
|
|
8497
8518
|
}
|
|
8498
8519
|
function resolveFilePath(filePath) {
|
|
8499
8520
|
const absolutePath = resolve(filePath);
|
|
8500
|
-
if (
|
|
8521
|
+
if (existsSync50(absolutePath)) return absolutePath;
|
|
8501
8522
|
const dir = dirname2(absolutePath);
|
|
8502
8523
|
const base = basename4(absolutePath);
|
|
8503
|
-
if (!
|
|
8524
|
+
if (!existsSync50(dir)) return null;
|
|
8504
8525
|
try {
|
|
8505
8526
|
const normalizedBase = normalizeSpaces(base);
|
|
8506
8527
|
const match = readdirSync4(dir).find((f) => normalizeSpaces(f) === normalizedBase);
|
|
@@ -8592,7 +8613,7 @@ async function tryVideoGeminiWeb(info, prompt, model, signal) {
|
|
|
8592
8613
|
const cookies = await isGeminiWebAvailable();
|
|
8593
8614
|
if (!cookies) return null;
|
|
8594
8615
|
if (signal?.aborted) return null;
|
|
8595
|
-
const
|
|
8616
|
+
const text4 = await queryWithCookies(prompt, cookies, {
|
|
8596
8617
|
files: [{ path: info.absolutePath, mimeType: info.mimeType }],
|
|
8597
8618
|
...model !== "gemini-3.6-flash" ? { model } : {},
|
|
8598
8619
|
signal,
|
|
@@ -8600,8 +8621,8 @@ async function tryVideoGeminiWeb(info, prompt, model, signal) {
|
|
|
8600
8621
|
});
|
|
8601
8622
|
return {
|
|
8602
8623
|
url: info.absolutePath,
|
|
8603
|
-
title: extractVideoTitle(
|
|
8604
|
-
content:
|
|
8624
|
+
title: extractVideoTitle(text4, info.absolutePath),
|
|
8625
|
+
content: text4,
|
|
8605
8626
|
error: null
|
|
8606
8627
|
};
|
|
8607
8628
|
} catch (err) {
|
|
@@ -8618,7 +8639,7 @@ async function tryVideoGeminiApi(info, prompt, model, signal) {
|
|
|
8618
8639
|
const uploaded = await uploadToFilesApi(info, apiKey, signal);
|
|
8619
8640
|
fileName = uploaded.name;
|
|
8620
8641
|
await pollFileState(fileName, apiKey, signal, 12e4);
|
|
8621
|
-
const
|
|
8642
|
+
const text4 = await queryGeminiApiWithVideo(prompt, uploaded.uri, {
|
|
8622
8643
|
apiKey,
|
|
8623
8644
|
model,
|
|
8624
8645
|
mimeType: info.mimeType,
|
|
@@ -8627,8 +8648,8 @@ async function tryVideoGeminiApi(info, prompt, model, signal) {
|
|
|
8627
8648
|
});
|
|
8628
8649
|
return {
|
|
8629
8650
|
url: info.absolutePath,
|
|
8630
|
-
title: extractVideoTitle(
|
|
8631
|
-
content:
|
|
8651
|
+
title: extractVideoTitle(text4, info.absolutePath),
|
|
8652
|
+
content: text4,
|
|
8632
8653
|
error: null
|
|
8633
8654
|
};
|
|
8634
8655
|
} catch (err) {
|
|
@@ -8653,8 +8674,8 @@ async function uploadToFilesApi(info, apiKey, signal) {
|
|
|
8653
8674
|
signal
|
|
8654
8675
|
}, apiKey);
|
|
8655
8676
|
if (!initRes.ok) {
|
|
8656
|
-
const
|
|
8657
|
-
throw new Error(`File upload init failed: ${initRes.status} (${
|
|
8677
|
+
const text4 = redactGeminiApiResponse(initRes, await initRes.text(), apiKey);
|
|
8678
|
+
throw new Error(`File upload init failed: ${initRes.status} (${text4.slice(0, 200)})`);
|
|
8658
8679
|
}
|
|
8659
8680
|
const uploadUrl = initRes.headers.get("x-goog-upload-url");
|
|
8660
8681
|
if (!uploadUrl) throw new Error("No upload URL in response headers");
|
|
@@ -8670,8 +8691,8 @@ async function uploadToFilesApi(info, apiKey, signal) {
|
|
|
8670
8691
|
signal
|
|
8671
8692
|
}, apiKey);
|
|
8672
8693
|
if (!uploadRes.ok) {
|
|
8673
|
-
const
|
|
8674
|
-
throw new Error(`File upload failed: ${uploadRes.status} (${
|
|
8694
|
+
const text4 = redactGeminiApiResponse(uploadRes, await uploadRes.text(), apiKey);
|
|
8695
|
+
throw new Error(`File upload failed: ${uploadRes.status} (${text4.slice(0, 200)})`);
|
|
8675
8696
|
}
|
|
8676
8697
|
const result = await uploadRes.json();
|
|
8677
8698
|
return result.file;
|
|
@@ -8695,10 +8716,10 @@ function deleteGeminiFile(fileName, apiKey) {
|
|
|
8695
8716
|
console.error(`Failed to delete Gemini file ${fileName}: ${message}`);
|
|
8696
8717
|
});
|
|
8697
8718
|
}
|
|
8698
|
-
function extractVideoTitle(
|
|
8699
|
-
return extractHeadingTitle(
|
|
8719
|
+
function extractVideoTitle(text4, filePath) {
|
|
8720
|
+
return extractHeadingTitle(text4) ?? basename4(filePath, extname2(filePath));
|
|
8700
8721
|
}
|
|
8701
|
-
var
|
|
8722
|
+
var CONFIG_PATH47, DEFAULT_VIDEO_PROMPT, VIDEO_EXTENSIONS, VIDEO_CONFIG_DEFAULTS, cachedVideoConfig;
|
|
8702
8723
|
var init_video_extract = __esm({
|
|
8703
8724
|
"video-extract.ts"() {
|
|
8704
8725
|
init_activity();
|
|
@@ -8707,7 +8728,7 @@ var init_video_extract = __esm({
|
|
|
8707
8728
|
init_gemini_api();
|
|
8708
8729
|
init_extract();
|
|
8709
8730
|
init_utils();
|
|
8710
|
-
|
|
8731
|
+
CONFIG_PATH47 = getWebSearchConfigPath();
|
|
8711
8732
|
DEFAULT_VIDEO_PROMPT = `Extract the complete content of this video. Include:
|
|
8712
8733
|
1. Video title (infer from content if not explicit), duration
|
|
8713
8734
|
2. A brief summary (2-3 sentences)
|
|
@@ -8897,33 +8918,33 @@ function sha256Bytes(value) {
|
|
|
8897
8918
|
function asciiLowerCode(code) {
|
|
8898
8919
|
return code >= 65 && code <= 90 ? code + 32 : code;
|
|
8899
8920
|
}
|
|
8900
|
-
function matchesDataScheme(
|
|
8901
|
-
return index + 5 <=
|
|
8921
|
+
function matchesDataScheme(text4, index) {
|
|
8922
|
+
return index + 5 <= text4.length && asciiLowerCode(text4.charCodeAt(index)) === 100 && asciiLowerCode(text4.charCodeAt(index + 1)) === 97 && asciiLowerCode(text4.charCodeAt(index + 2)) === 116 && asciiLowerCode(text4.charCodeAt(index + 3)) === 97 && text4.charCodeAt(index + 4) === 58;
|
|
8902
8923
|
}
|
|
8903
|
-
function isSchemeBoundary(
|
|
8924
|
+
function isSchemeBoundary(text4, index) {
|
|
8904
8925
|
if (index === 0) return true;
|
|
8905
|
-
const code =
|
|
8926
|
+
const code = text4.charCodeAt(index - 1);
|
|
8906
8927
|
const alphaNumeric = code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122;
|
|
8907
8928
|
return !alphaNumeric && code !== 43 && code !== 45 && code !== 46;
|
|
8908
8929
|
}
|
|
8909
|
-
function findNextDataScheme(
|
|
8910
|
-
for (let i = from; i + 5 <=
|
|
8911
|
-
if (matchesDataScheme(
|
|
8930
|
+
function findNextDataScheme(text4, from) {
|
|
8931
|
+
for (let i = from; i + 5 <= text4.length; i++) {
|
|
8932
|
+
if (matchesDataScheme(text4, i) && isSchemeBoundary(text4, i)) return i;
|
|
8912
8933
|
}
|
|
8913
8934
|
return -1;
|
|
8914
8935
|
}
|
|
8915
|
-
function dataUriEnclosure(
|
|
8936
|
+
function dataUriEnclosure(text4, start) {
|
|
8916
8937
|
if (start === 0) return null;
|
|
8917
8938
|
const immediateIndex = start - 1;
|
|
8918
|
-
const immediate =
|
|
8939
|
+
const immediate = text4[immediateIndex];
|
|
8919
8940
|
if (immediate === '"' || immediate === "'" || immediate === "`") {
|
|
8920
|
-
const beforeQuote = immediateIndex > 0 ?
|
|
8941
|
+
const beforeQuote = immediateIndex > 0 ? text4[immediateIndex - 1] : "";
|
|
8921
8942
|
const likelyOpeningQuote = immediateIndex === 0 || beforeQuote === "=" || beforeQuote === "(" || beforeQuote === "[" || beforeQuote === "{" || beforeQuote === ":" || beforeQuote === "," || /\s/.test(beforeQuote);
|
|
8922
8943
|
if (likelyOpeningQuote) return { kind: "quote", close: immediate };
|
|
8923
8944
|
}
|
|
8924
8945
|
let openerIndex = immediateIndex;
|
|
8925
|
-
while (openerIndex >= 0 && (
|
|
8926
|
-
const opener =
|
|
8946
|
+
while (openerIndex >= 0 && (text4[openerIndex] === " " || text4[openerIndex] === " ")) openerIndex--;
|
|
8947
|
+
const opener = text4[openerIndex];
|
|
8927
8948
|
if (opener === "(") return { kind: "parentheses" };
|
|
8928
8949
|
if (opener === "<") return { kind: "angle" };
|
|
8929
8950
|
return null;
|
|
@@ -8932,13 +8953,13 @@ function isBareDataUriTerminator(ch) {
|
|
|
8932
8953
|
const code = ch.charCodeAt(0);
|
|
8933
8954
|
return code <= 32 || code === 127 || ch === '"' || ch === "`" || ch === "<" || ch === ">";
|
|
8934
8955
|
}
|
|
8935
|
-
function scanDataUriCandidate(
|
|
8936
|
-
const enclosure = dataUriEnclosure(
|
|
8956
|
+
function scanDataUriCandidate(text4, start) {
|
|
8957
|
+
const enclosure = dataUriEnclosure(text4, start);
|
|
8937
8958
|
let comma = -1;
|
|
8938
8959
|
let depth = enclosure?.kind === "parentheses" ? 1 : 0;
|
|
8939
8960
|
let index = start + 5;
|
|
8940
|
-
for (; index <
|
|
8941
|
-
const ch =
|
|
8961
|
+
for (; index < text4.length; index++) {
|
|
8962
|
+
const ch = text4[index];
|
|
8942
8963
|
if (enclosure?.kind === "quote") {
|
|
8943
8964
|
if (ch === enclosure.close) break;
|
|
8944
8965
|
} else if (enclosure?.kind === "parentheses") {
|
|
@@ -8957,16 +8978,16 @@ function scanDataUriCandidate(text3, start) {
|
|
|
8957
8978
|
}
|
|
8958
8979
|
return { end: index, comma, enclosure };
|
|
8959
8980
|
}
|
|
8960
|
-
function headerEndsWithBase64(
|
|
8981
|
+
function headerEndsWithBase64(text4, headerStart, comma) {
|
|
8961
8982
|
let end = comma;
|
|
8962
|
-
while (end > headerStart && (
|
|
8983
|
+
while (end > headerStart && (text4[end - 1] === " " || text4[end - 1] === " ")) end--;
|
|
8963
8984
|
const token = "base64";
|
|
8964
8985
|
if (end - headerStart < token.length + 1) return false;
|
|
8965
8986
|
const tokenStart = end - token.length;
|
|
8966
8987
|
for (let i = 0; i < token.length; i++) {
|
|
8967
|
-
if (asciiLowerCode(
|
|
8988
|
+
if (asciiLowerCode(text4.charCodeAt(tokenStart + i)) !== token.charCodeAt(i)) return false;
|
|
8968
8989
|
}
|
|
8969
|
-
return tokenStart > headerStart &&
|
|
8990
|
+
return tokenStart > headerStart && text4[tokenStart - 1] === ";";
|
|
8970
8991
|
}
|
|
8971
8992
|
function isMimeTokenChar(code) {
|
|
8972
8993
|
if (code < 33 || code > 126) return false;
|
|
@@ -9005,14 +9026,14 @@ function isMimeTokenChar(code) {
|
|
|
9005
9026
|
return true;
|
|
9006
9027
|
}
|
|
9007
9028
|
}
|
|
9008
|
-
function normalizeMimeType(
|
|
9029
|
+
function normalizeMimeType(text4, headerStart, comma) {
|
|
9009
9030
|
let end = headerStart;
|
|
9010
|
-
while (end < comma &&
|
|
9031
|
+
while (end < comma && text4[end] !== ";") end++;
|
|
9011
9032
|
if (end === headerStart) return "text/plain";
|
|
9012
9033
|
if (end - headerStart > MAX_MIME_CHARS) return "application/octet-stream";
|
|
9013
9034
|
let slashCount = 0;
|
|
9014
9035
|
for (let i = headerStart; i < end; i++) {
|
|
9015
|
-
const code =
|
|
9036
|
+
const code = text4.charCodeAt(i);
|
|
9016
9037
|
if (code === 47) {
|
|
9017
9038
|
slashCount++;
|
|
9018
9039
|
if (i === headerStart || i === end - 1) return "application/octet-stream";
|
|
@@ -9021,7 +9042,7 @@ function normalizeMimeType(text3, headerStart, comma) {
|
|
|
9021
9042
|
if (!isMimeTokenChar(code)) return "application/octet-stream";
|
|
9022
9043
|
}
|
|
9023
9044
|
if (slashCount !== 1) return "application/octet-stream";
|
|
9024
|
-
return
|
|
9045
|
+
return text4.slice(headerStart, end).toLowerCase();
|
|
9025
9046
|
}
|
|
9026
9047
|
function hexValue(code) {
|
|
9027
9048
|
if (code >= 48 && code <= 57) return code - 48;
|
|
@@ -9095,15 +9116,15 @@ function buildDataUriMarker(omission) {
|
|
|
9095
9116
|
const decodeError = omission.decodeError ? `; decodeError=${omission.decodeError}` : "";
|
|
9096
9117
|
return `[pi-web-access inline data URI omitted; ordinal=${omission.ordinal}; source=${omission.sourcePath}; mime=${omission.mimeType}; encoding=${omission.encoding}; encodedBytes=${omission.encodedBytes}; decodedBytes=${decoded}${decodeError}; sha256=${omission.sha256}; digestBasis=${omission.digestBasis}; retrieval=not-retained]`;
|
|
9097
9118
|
}
|
|
9098
|
-
function sanitizeTextInternal(
|
|
9119
|
+
function sanitizeTextInternal(text4, sourcePath, state) {
|
|
9099
9120
|
let scanFrom = 0;
|
|
9100
9121
|
let retainedFrom = 0;
|
|
9101
9122
|
let outputLength = 0;
|
|
9102
9123
|
const pieces = [];
|
|
9103
|
-
while (scanFrom <
|
|
9104
|
-
const start = findNextDataScheme(
|
|
9124
|
+
while (scanFrom < text4.length) {
|
|
9125
|
+
const start = findNextDataScheme(text4, scanFrom);
|
|
9105
9126
|
if (start < 0) break;
|
|
9106
|
-
const candidate = scanDataUriCandidate(
|
|
9127
|
+
const candidate = scanDataUriCandidate(text4, start);
|
|
9107
9128
|
const end = candidate.end;
|
|
9108
9129
|
const headerStart = start + 5;
|
|
9109
9130
|
const missingComma = candidate.comma < 0;
|
|
@@ -9113,9 +9134,9 @@ function sanitizeTextInternal(text3, sourcePath, state) {
|
|
|
9113
9134
|
}
|
|
9114
9135
|
const headerEnd = missingComma ? end : candidate.comma;
|
|
9115
9136
|
const headerLength = headerEnd - headerStart;
|
|
9116
|
-
const encoding = headerEndsWithBase64(
|
|
9117
|
-
const mimeType = normalizeMimeType(
|
|
9118
|
-
const payload = missingComma ?
|
|
9137
|
+
const encoding = headerEndsWithBase64(text4, headerStart, headerEnd) ? "base64" : "percent-encoded";
|
|
9138
|
+
const mimeType = normalizeMimeType(text4, headerStart, headerEnd);
|
|
9139
|
+
const payload = missingComma ? text4.slice(headerStart, end) : text4.slice(candidate.comma + 1, end);
|
|
9119
9140
|
const encodedBytes = Buffer3.byteLength(payload, "utf8");
|
|
9120
9141
|
let decodedBytes = null;
|
|
9121
9142
|
let decodeError;
|
|
@@ -9151,7 +9172,7 @@ function sanitizeTextInternal(text3, sourcePath, state) {
|
|
|
9151
9172
|
retrieval: "not-retained"
|
|
9152
9173
|
};
|
|
9153
9174
|
const marker = buildDataUriMarker(omission);
|
|
9154
|
-
const prefix =
|
|
9175
|
+
const prefix = text4.slice(retainedFrom, start);
|
|
9155
9176
|
pieces.push(prefix, marker);
|
|
9156
9177
|
outputLength += prefix.length;
|
|
9157
9178
|
const markerStart = outputLength;
|
|
@@ -9160,13 +9181,13 @@ function sanitizeTextInternal(text3, sourcePath, state) {
|
|
|
9160
9181
|
retainedFrom = end;
|
|
9161
9182
|
scanFrom = end;
|
|
9162
9183
|
}
|
|
9163
|
-
if (state.omissions.length === 0 && retainedFrom === 0) return
|
|
9164
|
-
pieces.push(
|
|
9184
|
+
if (state.omissions.length === 0 && retainedFrom === 0) return text4;
|
|
9185
|
+
pieces.push(text4.slice(retainedFrom));
|
|
9165
9186
|
return pieces.join("");
|
|
9166
9187
|
}
|
|
9167
|
-
function sanitizeInlineDataUris(
|
|
9188
|
+
function sanitizeInlineDataUris(text4, sourcePath) {
|
|
9168
9189
|
const state = { nextOrdinal: 1, omissions: [] };
|
|
9169
|
-
const sanitized = sanitizeTextInternal(
|
|
9190
|
+
const sanitized = sanitizeTextInternal(text4, sourcePath, state);
|
|
9170
9191
|
return {
|
|
9171
9192
|
text: sanitized,
|
|
9172
9193
|
omissions: state.omissions.map(({ markerStart: _start, markerEnd: _end, ...omission }) => omission)
|
|
@@ -9192,13 +9213,13 @@ __export(extract_exports, {
|
|
|
9192
9213
|
readPDFResponseBuffer: () => readPDFResponseBuffer,
|
|
9193
9214
|
resolveFetchTimeoutMs: () => resolveFetchTimeoutMs
|
|
9194
9215
|
});
|
|
9195
|
-
import { existsSync as
|
|
9216
|
+
import { existsSync as existsSync51, readFileSync as readFileSync53 } from "node:fs";
|
|
9196
9217
|
import pLimit from "p-limit";
|
|
9197
9218
|
function loadFetchTimeoutMs() {
|
|
9198
|
-
if (!
|
|
9219
|
+
if (!existsSync51(WEB_SEARCH_CONFIG_PATH3)) return DEFAULT_TIMEOUT_MS3;
|
|
9199
9220
|
let raw;
|
|
9200
9221
|
try {
|
|
9201
|
-
raw = JSON.parse(
|
|
9222
|
+
raw = JSON.parse(readFileSync53(WEB_SEARCH_CONFIG_PATH3, "utf-8"));
|
|
9202
9223
|
} catch (err) {
|
|
9203
9224
|
const message = err instanceof Error ? err.message : String(err);
|
|
9204
9225
|
throw new Error(`Failed to parse ${WEB_SEARCH_CONFIG_PATH3}: ${message}`);
|
|
@@ -9226,10 +9247,10 @@ function isDefuddleConsoleError(args) {
|
|
|
9226
9247
|
const prefix = args[0];
|
|
9227
9248
|
return prefix === "Defuddle" || typeof prefix === "string" && /^Defuddle(?:\s|:)/.test(prefix);
|
|
9228
9249
|
}
|
|
9229
|
-
async function extractWithDefuddle(
|
|
9250
|
+
async function extractWithDefuddle(text4, url) {
|
|
9230
9251
|
const { Defuddle } = await import("defuddle/node");
|
|
9231
9252
|
const { parseHTML } = await import("linkedom");
|
|
9232
|
-
const { document } = parseHTML(
|
|
9253
|
+
const { document } = parseHTML(text4);
|
|
9233
9254
|
Object.defineProperty(document, "location", {
|
|
9234
9255
|
value: new URL(url),
|
|
9235
9256
|
configurable: true
|
|
@@ -9253,21 +9274,21 @@ async function extractWithDefuddle(text3, url) {
|
|
|
9253
9274
|
}
|
|
9254
9275
|
const result = await resultPromise;
|
|
9255
9276
|
if (processingError !== void 0) {
|
|
9256
|
-
throw new Error(`Defuddle failed to process document: ${
|
|
9277
|
+
throw new Error(`Defuddle failed to process document: ${errorMessage32(processingError)}`);
|
|
9257
9278
|
}
|
|
9258
9279
|
return typeof result.content === "string" ? { title: result.title, content: result.content } : null;
|
|
9259
9280
|
}
|
|
9260
9281
|
function loadSsrfAllowRanges() {
|
|
9261
9282
|
return loadSsrfConfig().allowRanges;
|
|
9262
9283
|
}
|
|
9263
|
-
function
|
|
9284
|
+
function errorMessage32(err) {
|
|
9264
9285
|
return err instanceof Error ? err.message : String(err);
|
|
9265
9286
|
}
|
|
9266
9287
|
function isConfigParseError(err) {
|
|
9267
|
-
return
|
|
9288
|
+
return errorMessage32(err).startsWith("Failed to parse ");
|
|
9268
9289
|
}
|
|
9269
9290
|
function isAbortError5(err) {
|
|
9270
|
-
return
|
|
9291
|
+
return errorMessage32(err).toLowerCase().includes("abort");
|
|
9271
9292
|
}
|
|
9272
9293
|
function isAbortException2(err) {
|
|
9273
9294
|
return err instanceof DOMException && (err.name === "AbortError" || err.name === "TimeoutError");
|
|
@@ -9282,7 +9303,7 @@ function imageGateError() {
|
|
|
9282
9303
|
try {
|
|
9283
9304
|
return isImageEnabled() ? null : "Image fetching is disabled by image.enabled";
|
|
9284
9305
|
} catch (err) {
|
|
9285
|
-
return
|
|
9306
|
+
return errorMessage32(err);
|
|
9286
9307
|
}
|
|
9287
9308
|
}
|
|
9288
9309
|
async function resolveAuthCookieHeader(url, profile) {
|
|
@@ -9329,12 +9350,12 @@ async function fetchAuthenticatedRemoteUrl(url, init, validationOptions, profile
|
|
|
9329
9350
|
throw new Error(`Too many redirects fetching ${current.toString()}`);
|
|
9330
9351
|
}
|
|
9331
9352
|
function loadFetchRouting() {
|
|
9332
|
-
if (!
|
|
9353
|
+
if (!existsSync51(WEB_SEARCH_CONFIG_PATH3)) {
|
|
9333
9354
|
return { providers: DEFAULT_FETCH_PROVIDER_ORDER, allowRemoteHostedProviders: false };
|
|
9334
9355
|
}
|
|
9335
9356
|
let raw;
|
|
9336
9357
|
try {
|
|
9337
|
-
const parsed = JSON.parse(
|
|
9358
|
+
const parsed = JSON.parse(readFileSync53(WEB_SEARCH_CONFIG_PATH3, "utf-8"));
|
|
9338
9359
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
9339
9360
|
throw new Error("expected a JSON object");
|
|
9340
9361
|
}
|
|
@@ -9525,7 +9546,7 @@ function safeVideoInfo(url) {
|
|
|
9525
9546
|
const info = isVideoFile(url);
|
|
9526
9547
|
return info ? { status: "video", info } : { status: "not-video" };
|
|
9527
9548
|
} catch (err) {
|
|
9528
|
-
return { status: "invalid", error:
|
|
9549
|
+
return { status: "invalid", error: errorMessage32(err) };
|
|
9529
9550
|
}
|
|
9530
9551
|
}
|
|
9531
9552
|
async function extractContent(url, signal, options) {
|
|
@@ -9550,14 +9571,14 @@ async function extractContent(url, signal, options) {
|
|
|
9550
9571
|
...options?.lookup ? { lookup: options.lookup } : {}
|
|
9551
9572
|
});
|
|
9552
9573
|
} catch (err) {
|
|
9553
|
-
return { url, title: "", content: "", error:
|
|
9574
|
+
return { url, title: "", content: "", error: errorMessage32(err) };
|
|
9554
9575
|
}
|
|
9555
9576
|
}
|
|
9556
9577
|
if (options?.authFetchProfile || options?.mode === "raw") {
|
|
9557
9578
|
try {
|
|
9558
9579
|
return await extractViaHttp(url, resolveFetchTimeoutMs(options), signal, options);
|
|
9559
9580
|
} catch (err) {
|
|
9560
|
-
return { url, title: "", content: "", error:
|
|
9581
|
+
return { url, title: "", content: "", error: errorMessage32(err) };
|
|
9561
9582
|
}
|
|
9562
9583
|
}
|
|
9563
9584
|
if (options?.frames || options?.timestamp) {
|
|
@@ -9695,20 +9716,20 @@ async function extractContent(url, signal, options) {
|
|
|
9695
9716
|
2. Set GEMINI_API_KEY in ${WEB_SEARCH_CONFIG_PATH3}` };
|
|
9696
9717
|
} catch (err) {
|
|
9697
9718
|
if (isAbortError5(err)) return abortedResult(url);
|
|
9698
|
-
return { url, title: "", content: "", error:
|
|
9719
|
+
return { url, title: "", content: "", error: errorMessage32(err) };
|
|
9699
9720
|
}
|
|
9700
9721
|
}
|
|
9701
9722
|
try {
|
|
9702
9723
|
if (!remoteUrl) new URL(url);
|
|
9703
9724
|
} catch (err) {
|
|
9704
|
-
return { url, title: "", content: "", error:
|
|
9725
|
+
return { url, title: "", content: "", error: errorMessage32(err) };
|
|
9705
9726
|
}
|
|
9706
9727
|
try {
|
|
9707
9728
|
const ghIssuePrResult = await extractGitHubIssuePr(url, signal, options);
|
|
9708
9729
|
if (ghIssuePrResult) return ghIssuePrResult;
|
|
9709
9730
|
if (signal?.aborted) return abortedResult(url);
|
|
9710
9731
|
} catch (err) {
|
|
9711
|
-
const message =
|
|
9732
|
+
const message = errorMessage32(err);
|
|
9712
9733
|
if (isAbortError5(err)) return abortedResult(url);
|
|
9713
9734
|
if (isConfigParseError(err)) {
|
|
9714
9735
|
return { url, title: "", content: "", error: message };
|
|
@@ -9719,7 +9740,7 @@ async function extractContent(url, signal, options) {
|
|
|
9719
9740
|
if (ghResult) return ghResult;
|
|
9720
9741
|
if (signal?.aborted) return abortedResult(url);
|
|
9721
9742
|
} catch (err) {
|
|
9722
|
-
const message =
|
|
9743
|
+
const message = errorMessage32(err);
|
|
9723
9744
|
if (isAbortError5(err)) return abortedResult(url);
|
|
9724
9745
|
if (isConfigParseError(err)) {
|
|
9725
9746
|
return { url, title: "", content: "", error: message };
|
|
@@ -9730,7 +9751,7 @@ async function extractContent(url, signal, options) {
|
|
|
9730
9751
|
try {
|
|
9731
9752
|
youtubeEnabled = isYouTubeEnabled();
|
|
9732
9753
|
} catch (err) {
|
|
9733
|
-
return { url, title: "", content: "", error:
|
|
9754
|
+
return { url, title: "", content: "", error: errorMessage32(err) };
|
|
9734
9755
|
}
|
|
9735
9756
|
if (ytInfo.isYouTube && youtubeEnabled) {
|
|
9736
9757
|
try {
|
|
@@ -9738,7 +9759,7 @@ async function extractContent(url, signal, options) {
|
|
|
9738
9759
|
if (ytResult) return ytResult;
|
|
9739
9760
|
if (signal?.aborted) return abortedResult(url);
|
|
9740
9761
|
} catch (err) {
|
|
9741
|
-
const message =
|
|
9762
|
+
const message = errorMessage32(err);
|
|
9742
9763
|
if (isAbortError5(err)) return abortedResult(url);
|
|
9743
9764
|
return { url, title: "", content: "", error: message };
|
|
9744
9765
|
}
|
|
@@ -9754,13 +9775,13 @@ async function extractContent(url, signal, options) {
|
|
|
9754
9775
|
try {
|
|
9755
9776
|
fetchTimeoutMs = resolveFetchTimeoutMs(options);
|
|
9756
9777
|
} catch (err) {
|
|
9757
|
-
return { url, title: "", content: "", error:
|
|
9778
|
+
return { url, title: "", content: "", error: errorMessage32(err) };
|
|
9758
9779
|
}
|
|
9759
9780
|
let fetchRouting;
|
|
9760
9781
|
try {
|
|
9761
9782
|
fetchRouting = loadFetchRouting();
|
|
9762
9783
|
} catch (err) {
|
|
9763
|
-
return { url, title: "", content: "", error:
|
|
9784
|
+
return { url, title: "", content: "", error: errorMessage32(err) };
|
|
9764
9785
|
}
|
|
9765
9786
|
const providerOrder = remoteUrl && !fetchRouting.allowRemoteHostedProviders ? fetchRouting.providers.filter((provider) => !REMOTE_HOSTED_FETCH_PROVIDERS.has(provider)) : fetchRouting.providers;
|
|
9766
9787
|
if (providerOrder.length === 0) {
|
|
@@ -9823,7 +9844,7 @@ async function extractContent(url, signal, options) {
|
|
|
9823
9844
|
}
|
|
9824
9845
|
} catch (err) {
|
|
9825
9846
|
if (isAbortError5(err)) return abortedResult(url);
|
|
9826
|
-
firecrawlError =
|
|
9847
|
+
firecrawlError = errorMessage32(err);
|
|
9827
9848
|
if (isConfigParseError(err)) return parseErrorResult(firecrawlError);
|
|
9828
9849
|
}
|
|
9829
9850
|
continue;
|
|
@@ -9841,7 +9862,7 @@ async function extractContent(url, signal, options) {
|
|
|
9841
9862
|
}
|
|
9842
9863
|
} catch (err) {
|
|
9843
9864
|
if (signal?.aborted || isAbortException2(err)) return abortedResult(url);
|
|
9844
|
-
crawl4aiError =
|
|
9865
|
+
crawl4aiError = errorMessage32(err);
|
|
9845
9866
|
if (isConfigParseError(err)) return parseErrorResult(crawl4aiError);
|
|
9846
9867
|
}
|
|
9847
9868
|
continue;
|
|
@@ -9859,7 +9880,7 @@ async function extractContent(url, signal, options) {
|
|
|
9859
9880
|
}
|
|
9860
9881
|
} catch (err) {
|
|
9861
9882
|
if (isAbortError5(err)) return abortedResult(url);
|
|
9862
|
-
tinyfishError =
|
|
9883
|
+
tinyfishError = errorMessage32(err);
|
|
9863
9884
|
if (isConfigParseError(err)) return parseErrorResult(tinyfishError);
|
|
9864
9885
|
}
|
|
9865
9886
|
continue;
|
|
@@ -9872,7 +9893,7 @@ async function extractContent(url, signal, options) {
|
|
|
9872
9893
|
}
|
|
9873
9894
|
} catch (err) {
|
|
9874
9895
|
if (isAbortError5(err)) return abortedResult(url);
|
|
9875
|
-
search1apiError =
|
|
9896
|
+
search1apiError = errorMessage32(err);
|
|
9876
9897
|
if (isConfigParseError(err)) return parseErrorResult(search1apiError);
|
|
9877
9898
|
}
|
|
9878
9899
|
continue;
|
|
@@ -9885,7 +9906,7 @@ async function extractContent(url, signal, options) {
|
|
|
9885
9906
|
}
|
|
9886
9907
|
} catch (err) {
|
|
9887
9908
|
if (isAbortError5(err)) return abortedResult(url);
|
|
9888
|
-
queritError =
|
|
9909
|
+
queritError = errorMessage32(err);
|
|
9889
9910
|
if (isConfigParseError(err)) return parseErrorResult(queritError);
|
|
9890
9911
|
}
|
|
9891
9912
|
continue;
|
|
@@ -9903,7 +9924,7 @@ async function extractContent(url, signal, options) {
|
|
|
9903
9924
|
}
|
|
9904
9925
|
} catch (err) {
|
|
9905
9926
|
if (isAbortError5(err)) return abortedResult(url);
|
|
9906
|
-
kagiError =
|
|
9927
|
+
kagiError = errorMessage32(err);
|
|
9907
9928
|
if (isConfigParseError(err)) return parseErrorResult(kagiError);
|
|
9908
9929
|
}
|
|
9909
9930
|
continue;
|
|
@@ -9921,7 +9942,7 @@ async function extractContent(url, signal, options) {
|
|
|
9921
9942
|
}
|
|
9922
9943
|
} catch (err) {
|
|
9923
9944
|
if (isAbortError5(err)) return abortedResult(url);
|
|
9924
|
-
ollamaError =
|
|
9945
|
+
ollamaError = errorMessage32(err);
|
|
9925
9946
|
if (isConfigParseError(err)) return parseErrorResult(ollamaError);
|
|
9926
9947
|
}
|
|
9927
9948
|
continue;
|
|
@@ -9934,7 +9955,7 @@ async function extractContent(url, signal, options) {
|
|
|
9934
9955
|
}
|
|
9935
9956
|
} catch (err) {
|
|
9936
9957
|
if (isAbortError5(err)) return abortedResult(url);
|
|
9937
|
-
parallelError =
|
|
9958
|
+
parallelError = errorMessage32(err);
|
|
9938
9959
|
if (isConfigParseError(err)) return parseErrorResult(parallelError);
|
|
9939
9960
|
}
|
|
9940
9961
|
continue;
|
|
@@ -9945,7 +9966,7 @@ async function extractContent(url, signal, options) {
|
|
|
9945
9966
|
if (parallelMcpResult) return withDeclaredLinks(parallelMcpResult);
|
|
9946
9967
|
} catch (err) {
|
|
9947
9968
|
if (isAbortError5(err)) return abortedResult(url);
|
|
9948
|
-
parallelMcpError =
|
|
9969
|
+
parallelMcpError = errorMessage32(err);
|
|
9949
9970
|
if (isConfigParseError(err)) return parseErrorResult(parallelMcpError);
|
|
9950
9971
|
}
|
|
9951
9972
|
continue;
|
|
@@ -9963,7 +9984,7 @@ async function extractContent(url, signal, options) {
|
|
|
9963
9984
|
}
|
|
9964
9985
|
} catch (err) {
|
|
9965
9986
|
if (isAbortError5(err)) return abortedResult(url);
|
|
9966
|
-
brightdataError =
|
|
9987
|
+
brightdataError = errorMessage32(err);
|
|
9967
9988
|
if (isConfigParseError(err)) return parseErrorResult(brightdataError);
|
|
9968
9989
|
}
|
|
9969
9990
|
continue;
|
|
@@ -9975,7 +9996,7 @@ async function extractContent(url, signal, options) {
|
|
|
9975
9996
|
} catch (err) {
|
|
9976
9997
|
if (isAbortError5(err)) return abortedResult(url);
|
|
9977
9998
|
if (err instanceof CredentialResolutionError || isConfigParseError(err)) {
|
|
9978
|
-
return parseErrorResult(
|
|
9999
|
+
return parseErrorResult(errorMessage32(err));
|
|
9979
10000
|
}
|
|
9980
10001
|
}
|
|
9981
10002
|
if (geminiResult) return withDeclaredLinks(geminiResult);
|
|
@@ -10019,10 +10040,10 @@ async function extractContent(url, signal, options) {
|
|
|
10019
10040
|
].join("\n");
|
|
10020
10041
|
return { ...finalHttpResult ?? { url, title: "", content: "", error: null }, error: guidance };
|
|
10021
10042
|
}
|
|
10022
|
-
function isCloudflareChallenge(response,
|
|
10043
|
+
function isCloudflareChallenge(response, text4, isHTML) {
|
|
10023
10044
|
if (response.status !== 200) return false;
|
|
10024
10045
|
if (response.headers.get("cf-mitigated") === "challenge") return true;
|
|
10025
|
-
return isHTML && /<title>\s*Just a moment\.\.\.\s*<\/title>/i.test(
|
|
10046
|
+
return isHTML && /<title>\s*Just a moment\.\.\.\s*<\/title>/i.test(text4) && text4.includes("window._cf_chl_opt") && text4.includes("/cdn-cgi/challenge-platform/");
|
|
10026
10047
|
}
|
|
10027
10048
|
function isLikelyJSRendered(html) {
|
|
10028
10049
|
const bodyMatch = html.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
|
|
@@ -10161,9 +10182,9 @@ async function extractViaHttp(url, timeoutMs, signal, options, preferMarkdown =
|
|
|
10161
10182
|
activityMonitor.logComplete(activityId, response.status);
|
|
10162
10183
|
return { url, title: "", content: "", error: `Unsupported content type in raw mode: ${mimeType || "missing"}`, mimeType, status: response.status };
|
|
10163
10184
|
}
|
|
10164
|
-
const
|
|
10185
|
+
const text5 = await readTextResponseWithLimit(response, maxResponseSize);
|
|
10165
10186
|
activityMonitor.logComplete(activityId, response.status);
|
|
10166
|
-
return { url, title: extractTextTitle(
|
|
10187
|
+
return { url, title: extractTextTitle(text5, url), content: text5, error: null, mimeType, status: response.status };
|
|
10167
10188
|
}
|
|
10168
10189
|
if (SUPPORTED_IMAGE_TYPES.has(mimeType)) {
|
|
10169
10190
|
const disabled = imageGateError();
|
|
@@ -10192,7 +10213,7 @@ async function extractViaHttp(url, timeoutMs, signal, options, preferMarkdown =
|
|
|
10192
10213
|
status: response.status
|
|
10193
10214
|
};
|
|
10194
10215
|
} catch (err) {
|
|
10195
|
-
const message =
|
|
10216
|
+
const message = errorMessage32(err);
|
|
10196
10217
|
activityMonitor.logError(activityId, message);
|
|
10197
10218
|
return { url, title: "", content: "", error: message, mimeType, status: response.status };
|
|
10198
10219
|
}
|
|
@@ -10233,19 +10254,19 @@ Characters: ${result.chars}`,
|
|
|
10233
10254
|
error: `Unsupported content type: ${contentType.split(";")[0]}`
|
|
10234
10255
|
};
|
|
10235
10256
|
}
|
|
10236
|
-
const
|
|
10257
|
+
const text4 = await readTextResponseWithLimit(response, maxResponseSize);
|
|
10237
10258
|
const isHTML = contentType.includes("text/html") || contentType.includes("application/xhtml+xml");
|
|
10238
|
-
if (isCloudflareChallenge(response,
|
|
10259
|
+
if (isCloudflareChallenge(response, text4, isHTML)) {
|
|
10239
10260
|
activityMonitor.logComplete(activityId, response.status);
|
|
10240
10261
|
return { url, title: "", content: "", error: `HTTP ${response.status}: Blocked by Cloudflare challenge page`, status: response.status };
|
|
10241
10262
|
}
|
|
10242
10263
|
if (!isHTML) {
|
|
10243
10264
|
activityMonitor.logComplete(activityId, response.status);
|
|
10244
|
-
const title = extractTextTitle(
|
|
10245
|
-
if (mimeType !== "text/markdown" && mimeType !== "text/x-markdown") return { url, title, content:
|
|
10265
|
+
const title = extractTextTitle(text4, url);
|
|
10266
|
+
if (mimeType !== "text/markdown" && mimeType !== "text/x-markdown") return { url, title, content: text4, error: null };
|
|
10246
10267
|
const declaredLinks2 = discoverDeclaredWebLinks(null, response.headers.get("link"), response.url || url);
|
|
10247
|
-
const markdown2 = { url, title, content: appendDeclaredWebLinks(
|
|
10248
|
-
if (!preferMarkdown ||
|
|
10268
|
+
const markdown2 = { url, title, content: appendDeclaredWebLinks(text4, declaredLinks2), error: null, declaredLinks: declaredLinks2 };
|
|
10269
|
+
if (!preferMarkdown || text4.trim().length >= MIN_USEFUL_CONTENT2) return markdown2;
|
|
10249
10270
|
const normal = await extractViaHttp(url, Math.max(1, timeoutMs - (Date.now() - startedAt)), signal, options, false);
|
|
10250
10271
|
if (signal?.aborted || isNonRecoverableHttpError(normal.error) || normal.status === 404 || normal.status === 410 || isAbortError5(normal.error)) return normal;
|
|
10251
10272
|
const normalHasBody = normal.content.trim() !== appendDeclaredWebLinks("", normal.declaredLinks ?? []).trim();
|
|
@@ -10258,7 +10279,7 @@ Browser retry failed: ${normal.error}` : "")
|
|
|
10258
10279
|
};
|
|
10259
10280
|
}
|
|
10260
10281
|
const { parseHTML } = await import("linkedom");
|
|
10261
|
-
const { document } = parseHTML(
|
|
10282
|
+
const { document } = parseHTML(text4);
|
|
10262
10283
|
const documentTitle = document.title?.trim() ?? "";
|
|
10263
10284
|
const declaredLinks = discoverDeclaredWebLinks(
|
|
10264
10285
|
document,
|
|
@@ -10269,7 +10290,7 @@ Browser retry failed: ${normal.error}` : "")
|
|
|
10269
10290
|
const reader = new Readability(document);
|
|
10270
10291
|
const article = reader.parse();
|
|
10271
10292
|
if (!article) {
|
|
10272
|
-
const rscResult = extractRSCContent(
|
|
10293
|
+
const rscResult = extractRSCContent(text4);
|
|
10273
10294
|
if (rscResult && rscResult.content.length >= MIN_USEFUL_CONTENT2) {
|
|
10274
10295
|
activityMonitor.logComplete(activityId, response.status);
|
|
10275
10296
|
return {
|
|
@@ -10281,7 +10302,7 @@ Browser retry failed: ${normal.error}` : "")
|
|
|
10281
10302
|
};
|
|
10282
10303
|
}
|
|
10283
10304
|
controller.signal.throwIfAborted();
|
|
10284
|
-
const defuddleResult = await extractWithDefuddle(
|
|
10305
|
+
const defuddleResult = await extractWithDefuddle(text4, response.url || url);
|
|
10285
10306
|
controller.signal.throwIfAborted();
|
|
10286
10307
|
if (defuddleResult && defuddleResult.content.length >= MIN_USEFUL_CONTENT2) {
|
|
10287
10308
|
activityMonitor.logComplete(activityId, response.status);
|
|
@@ -10294,7 +10315,7 @@ Browser retry failed: ${normal.error}` : "")
|
|
|
10294
10315
|
};
|
|
10295
10316
|
}
|
|
10296
10317
|
activityMonitor.logComplete(activityId, response.status);
|
|
10297
|
-
const jsRendered = isLikelyJSRendered(
|
|
10318
|
+
const jsRendered = isLikelyJSRendered(text4);
|
|
10298
10319
|
const errorMsg = jsRendered ? "Page appears to be JavaScript-rendered (content loads dynamically)" : "Could not extract readable content from HTML structure";
|
|
10299
10320
|
return {
|
|
10300
10321
|
url,
|
|
@@ -10310,7 +10331,7 @@ Browser retry failed: ${normal.error}` : "")
|
|
|
10310
10331
|
const markdown = (await getTurndown()).turndown(article.content);
|
|
10311
10332
|
activityMonitor.logComplete(activityId, response.status);
|
|
10312
10333
|
if (markdown.length < MIN_USEFUL_CONTENT2) {
|
|
10313
|
-
const rscResult = extractRSCContent(
|
|
10334
|
+
const rscResult = extractRSCContent(text4);
|
|
10314
10335
|
if (rscResult && rscResult.content.length >= MIN_USEFUL_CONTENT2) {
|
|
10315
10336
|
return {
|
|
10316
10337
|
url,
|
|
@@ -10321,7 +10342,7 @@ Browser retry failed: ${normal.error}` : "")
|
|
|
10321
10342
|
};
|
|
10322
10343
|
}
|
|
10323
10344
|
controller.signal.throwIfAborted();
|
|
10324
|
-
const defuddleResult = await extractWithDefuddle(
|
|
10345
|
+
const defuddleResult = await extractWithDefuddle(text4, response.url || url);
|
|
10325
10346
|
controller.signal.throwIfAborted();
|
|
10326
10347
|
if (defuddleResult && defuddleResult.content.length >= MIN_USEFUL_CONTENT2) {
|
|
10327
10348
|
return {
|
|
@@ -10336,7 +10357,7 @@ Browser retry failed: ${normal.error}` : "")
|
|
|
10336
10357
|
url,
|
|
10337
10358
|
title: article.title || documentTitle,
|
|
10338
10359
|
content: appendDeclaredWebLinks(markdown, declaredLinks),
|
|
10339
|
-
error: isLikelyJSRendered(
|
|
10360
|
+
error: isLikelyJSRendered(text4) ? "Page appears to be JavaScript-rendered (content loads dynamically)" : "Extracted content appears incomplete",
|
|
10340
10361
|
declaredLinks
|
|
10341
10362
|
};
|
|
10342
10363
|
}
|
|
@@ -10364,14 +10385,14 @@ Browser retry failed: ${normal.error}` : "")
|
|
|
10364
10385
|
}
|
|
10365
10386
|
}
|
|
10366
10387
|
}
|
|
10367
|
-
function extractHeadingTitle(
|
|
10368
|
-
const match =
|
|
10388
|
+
function extractHeadingTitle(text4) {
|
|
10389
|
+
const match = text4.match(/^#{1,2}\s+(.+)/m);
|
|
10369
10390
|
if (!match) return null;
|
|
10370
10391
|
const cleaned = match[1].replace(/\*+/g, "").trim();
|
|
10371
10392
|
return cleaned || null;
|
|
10372
10393
|
}
|
|
10373
|
-
function extractTextTitle(
|
|
10374
|
-
return extractHeadingTitle(
|
|
10394
|
+
function extractTextTitle(text4, url) {
|
|
10395
|
+
return extractHeadingTitle(text4) ?? (new URL(url).pathname.split("/").pop() || url);
|
|
10375
10396
|
}
|
|
10376
10397
|
async function fetchAllContent(urls, signal, options) {
|
|
10377
10398
|
const results = await Promise.all(urls.map((url) => fetchLimit(() => extractContent(url, signal, options))));
|
|
@@ -10438,7 +10459,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
10438
10459
|
// package.json
|
|
10439
10460
|
var package_default = {
|
|
10440
10461
|
name: "pi-web-access",
|
|
10441
|
-
version: "0.
|
|
10462
|
+
version: "0.38.0",
|
|
10442
10463
|
description: "Web search, URL fetching, GitHub repo cloning, PDF extraction, YouTube video understanding, and local video analysis for Pi coding agent. Supports OpenAI, Brave, Parallel, TinyFish, Search1API, Searchinfinity, Querit, Tavily, Firecrawl, Crawl4AI, Jina, SERPdive, Kagi, Ollama, AnySearch, Bright Data SERP, SerpBase, SerpApi, Serply, You.com, SearXNG, degoog, Exa, Perplexity, Gemini, Kimi, and Mistral.",
|
|
10443
10464
|
type: "module",
|
|
10444
10465
|
bin: {
|
|
@@ -10499,7 +10520,7 @@ var package_default = {
|
|
|
10499
10520
|
typescript: "^7.0.2"
|
|
10500
10521
|
},
|
|
10501
10522
|
dependencies: {
|
|
10502
|
-
"@modelcontextprotocol/sdk": "1.
|
|
10523
|
+
"@modelcontextprotocol/sdk": "1.32.1",
|
|
10503
10524
|
"@mozilla/readability": "^0.6.0",
|
|
10504
10525
|
defuddle: "0.19.3",
|
|
10505
10526
|
linkedom: "^0.16.0",
|
|
@@ -19015,7 +19036,7 @@ init_gemini_api();
|
|
|
19015
19036
|
init_gemini_adc();
|
|
19016
19037
|
init_gemini_web();
|
|
19017
19038
|
init_perplexity();
|
|
19018
|
-
import { existsSync as
|
|
19039
|
+
import { existsSync as existsSync40, readFileSync as readFileSync41 } from "node:fs";
|
|
19019
19040
|
|
|
19020
19041
|
// exa.ts
|
|
19021
19042
|
init_activity();
|
|
@@ -19216,14 +19237,14 @@ async function callExaMcp(toolName, args, signal) {
|
|
|
19216
19237
|
const message = parsed.result.content?.find((item) => item.type === "text" && typeof item.text === "string")?.text?.trim();
|
|
19217
19238
|
throw new Error(message || "Exa MCP returned an error");
|
|
19218
19239
|
}
|
|
19219
|
-
const
|
|
19220
|
-
if (!
|
|
19240
|
+
const text4 = parsed.result?.content?.find((item) => item.type === "text" && typeof item.text === "string" && item.text.trim().length > 0)?.text;
|
|
19241
|
+
if (!text4) {
|
|
19221
19242
|
throw new Error("Exa MCP returned empty content");
|
|
19222
19243
|
}
|
|
19223
|
-
return
|
|
19244
|
+
return text4;
|
|
19224
19245
|
}
|
|
19225
|
-
function parseMcpResults(
|
|
19226
|
-
const blocks =
|
|
19246
|
+
function parseMcpResults(text4) {
|
|
19247
|
+
const blocks = text4.split(/(?=^Title: )/m).filter((block) => block.trim().length > 0);
|
|
19227
19248
|
const parsed = blocks.map((block) => {
|
|
19228
19249
|
const title = block.match(/^Title: (.+)/m)?.[1]?.trim() ?? "";
|
|
19229
19250
|
const url = block.match(/^URL: (.+)/m)?.[1]?.trim() ?? "";
|
|
@@ -19288,17 +19309,17 @@ function buildMcpQuery(query, options) {
|
|
|
19288
19309
|
function isAbortMessage(message) {
|
|
19289
19310
|
return message.toLowerCase().includes("abort");
|
|
19290
19311
|
}
|
|
19291
|
-
function parseJsonMcpResults(
|
|
19312
|
+
function parseJsonMcpResults(text4) {
|
|
19292
19313
|
try {
|
|
19293
|
-
const results = JSON.parse(
|
|
19314
|
+
const results = JSON.parse(text4).results;
|
|
19294
19315
|
return Array.isArray(results) && results.length > 0 ? results : null;
|
|
19295
19316
|
} catch {
|
|
19296
19317
|
return null;
|
|
19297
19318
|
}
|
|
19298
19319
|
}
|
|
19299
19320
|
async function searchWithExaMcpTool(tool, args, options) {
|
|
19300
|
-
const
|
|
19301
|
-
const jsonResults = parseJsonMcpResults(
|
|
19321
|
+
const text4 = await callExaMcp(tool, args, options.signal);
|
|
19322
|
+
const jsonResults = parseJsonMcpResults(text4);
|
|
19302
19323
|
if (jsonResults) {
|
|
19303
19324
|
return toSearchResponse(
|
|
19304
19325
|
buildAnswerFromSearchResults(jsonResults),
|
|
@@ -19306,7 +19327,7 @@ async function searchWithExaMcpTool(tool, args, options) {
|
|
|
19306
19327
|
options.includeContent ? mapInlineContent(jsonResults) : null
|
|
19307
19328
|
);
|
|
19308
19329
|
}
|
|
19309
|
-
const textResults = parseMcpResults(
|
|
19330
|
+
const textResults = parseMcpResults(text4);
|
|
19310
19331
|
if (!textResults) return null;
|
|
19311
19332
|
return toSearchResponse(
|
|
19312
19333
|
buildAnswerFromMcpResults(textResults),
|
|
@@ -19725,7 +19746,7 @@ var CONFIG_PATH7 = getWebSearchConfigPath();
|
|
|
19725
19746
|
var SEARCH_TIMEOUT_MS2 = 6e4;
|
|
19726
19747
|
var EXCLUDED_MODEL_SEGMENTS = /* @__PURE__ */ new Set(["pro", "ultra"]);
|
|
19727
19748
|
var MODEL_PREFERENCE = [
|
|
19728
|
-
(id) => id.includes("
|
|
19749
|
+
(id) => id.includes("luna"),
|
|
19729
19750
|
(id) => /^gpt-\d+(\.\d+)?$/.test(id),
|
|
19730
19751
|
(id) => /^gpt-\d/.test(id)
|
|
19731
19752
|
];
|
|
@@ -19986,7 +20007,7 @@ async function resolveOpenAIAuth(ctx, signal) {
|
|
|
19986
20007
|
environmentValue: process.env.OPENAI_API_KEY,
|
|
19987
20008
|
signal
|
|
19988
20009
|
});
|
|
19989
|
-
return apiKey ? { provider: "openai", apiKey, model: modelOverride ?? "gpt-
|
|
20010
|
+
return apiKey ? { provider: "openai", apiKey, model: modelOverride ?? "gpt-6-luna", headers: {}, responsesUrl } : void 0;
|
|
19990
20011
|
}
|
|
19991
20012
|
async function isOpenAISearchAvailable(ctx) {
|
|
19992
20013
|
const config = loadConfig7();
|
|
@@ -20062,8 +20083,8 @@ function isWebSearchCall(item) {
|
|
|
20062
20083
|
return !!item && typeof item === "object" && item.type === "web_search_call";
|
|
20063
20084
|
}
|
|
20064
20085
|
async function parseOpenAIResponse(response) {
|
|
20065
|
-
const
|
|
20066
|
-
const trimmed =
|
|
20086
|
+
const text4 = await response.text();
|
|
20087
|
+
const trimmed = text4.trim();
|
|
20067
20088
|
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
20068
20089
|
try {
|
|
20069
20090
|
const parsed = JSON.parse(trimmed);
|
|
@@ -20079,7 +20100,7 @@ async function parseOpenAIResponse(response) {
|
|
|
20079
20100
|
let completedResponse = null;
|
|
20080
20101
|
let webSearchCallSeen = false;
|
|
20081
20102
|
let streamError = null;
|
|
20082
|
-
for (const line of
|
|
20103
|
+
for (const line of text4.split("\n")) {
|
|
20083
20104
|
if (!line.startsWith("data: ")) continue;
|
|
20084
20105
|
const data = line.slice(6).trim();
|
|
20085
20106
|
if (!data || data === "[DONE]") continue;
|
|
@@ -20131,11 +20152,11 @@ function cleanSourceUrl(rawUrl) {
|
|
|
20131
20152
|
return rawUrl.replace(/[?&]utm_source=openai$/, "");
|
|
20132
20153
|
}
|
|
20133
20154
|
}
|
|
20134
|
-
function extractSnippetAround(
|
|
20135
|
-
if (typeof start !== "number" || typeof end !== "number" || !
|
|
20155
|
+
function extractSnippetAround(text4, start, end) {
|
|
20156
|
+
if (typeof start !== "number" || typeof end !== "number" || !text4) return "";
|
|
20136
20157
|
const before = Math.max(0, start - 100);
|
|
20137
|
-
const after = Math.min(
|
|
20138
|
-
const snippet =
|
|
20158
|
+
const after = Math.min(text4.length, end + 100);
|
|
20159
|
+
const snippet = text4.slice(before, after).replace(/\[([^\]]*)\]\([^)]*\)/g, "$1").trim();
|
|
20139
20160
|
return snippet.length > 300 ? `${snippet.slice(0, 297)}...` : snippet;
|
|
20140
20161
|
}
|
|
20141
20162
|
function addResult(results, seen, url, title, snippet = "") {
|
|
@@ -20158,7 +20179,7 @@ function extractSearchResults(output, numResults) {
|
|
|
20158
20179
|
if (!Array.isArray(content)) continue;
|
|
20159
20180
|
for (const part of content) {
|
|
20160
20181
|
if (!part || typeof part !== "object") continue;
|
|
20161
|
-
const
|
|
20182
|
+
const text4 = typeof part.text === "string" ? part.text : "";
|
|
20162
20183
|
const annotations = part.annotations;
|
|
20163
20184
|
if (!Array.isArray(annotations)) continue;
|
|
20164
20185
|
for (const annotation of annotations) {
|
|
@@ -20168,7 +20189,7 @@ function extractSearchResults(output, numResults) {
|
|
|
20168
20189
|
seenUrls,
|
|
20169
20190
|
annotation.url,
|
|
20170
20191
|
annotation.title,
|
|
20171
|
-
extractSnippetAround(
|
|
20192
|
+
extractSnippetAround(text4, annotation.start_index, annotation.end_index)
|
|
20172
20193
|
);
|
|
20173
20194
|
}
|
|
20174
20195
|
}
|
|
@@ -20200,8 +20221,8 @@ function extractAnswer(output) {
|
|
|
20200
20221
|
if (!Array.isArray(content)) continue;
|
|
20201
20222
|
for (const part of content) {
|
|
20202
20223
|
if (!part || typeof part !== "object") continue;
|
|
20203
|
-
const
|
|
20204
|
-
if (typeof
|
|
20224
|
+
const text4 = part.text;
|
|
20225
|
+
if (typeof text4 === "string" && text4.trim().length > 0) parts.push(text4);
|
|
20205
20226
|
}
|
|
20206
20227
|
}
|
|
20207
20228
|
return parts.join("\n").trim();
|
|
@@ -20253,10 +20274,10 @@ function buildAlphaSearchHeaders(headers, apiKey) {
|
|
|
20253
20274
|
return result;
|
|
20254
20275
|
}
|
|
20255
20276
|
async function parseAlphaSearchResponse(response, numResults = 5) {
|
|
20256
|
-
const
|
|
20277
|
+
const text4 = await response.text();
|
|
20257
20278
|
let payload;
|
|
20258
20279
|
try {
|
|
20259
|
-
payload = JSON.parse(
|
|
20280
|
+
payload = JSON.parse(text4);
|
|
20260
20281
|
} catch {
|
|
20261
20282
|
throw new Error("OpenAI alpha/search returned invalid JSON");
|
|
20262
20283
|
}
|
|
@@ -21874,8 +21895,8 @@ function parseResponse(value) {
|
|
|
21874
21895
|
if (!Array.isArray(envelope.results)) throw invalidResponse4("expected a results array");
|
|
21875
21896
|
return envelope.results;
|
|
21876
21897
|
}
|
|
21877
|
-
function redactSecrets(
|
|
21878
|
-
let redacted =
|
|
21898
|
+
function redactSecrets(text4, secrets) {
|
|
21899
|
+
let redacted = text4;
|
|
21879
21900
|
for (const secret of secrets) redacted = redactCredential(redacted, secret);
|
|
21880
21901
|
return redacted;
|
|
21881
21902
|
}
|
|
@@ -22568,11 +22589,11 @@ function addSources(results, seen, sources) {
|
|
|
22568
22589
|
if (!Array.isArray(sources)) return;
|
|
22569
22590
|
for (const source of sources) addSource(results, seen, source);
|
|
22570
22591
|
}
|
|
22571
|
-
function extractSnippetAround2(
|
|
22572
|
-
if (typeof start !== "number" || typeof end !== "number" || !
|
|
22592
|
+
function extractSnippetAround2(text4, start, end) {
|
|
22593
|
+
if (typeof start !== "number" || typeof end !== "number" || !text4) return "";
|
|
22573
22594
|
const before = Math.max(0, start - 100);
|
|
22574
|
-
const after = Math.min(
|
|
22575
|
-
const snippet =
|
|
22595
|
+
const after = Math.min(text4.length, end + 100);
|
|
22596
|
+
const snippet = text4.slice(before, after).replace(/\[([^\]]*)\]\([^)]*\)/g, "$1").trim();
|
|
22576
22597
|
return snippet.length > 300 ? `${snippet.slice(0, 297)}...` : snippet;
|
|
22577
22598
|
}
|
|
22578
22599
|
function extractAnswer2(output) {
|
|
@@ -22583,8 +22604,8 @@ function extractAnswer2(output) {
|
|
|
22583
22604
|
if (!Array.isArray(content)) continue;
|
|
22584
22605
|
for (const part of content) {
|
|
22585
22606
|
if (!part || typeof part !== "object") continue;
|
|
22586
|
-
const
|
|
22587
|
-
if (typeof
|
|
22607
|
+
const text4 = part.text;
|
|
22608
|
+
if (typeof text4 === "string" && text4.trim().length > 0) parts.push(text4);
|
|
22588
22609
|
}
|
|
22589
22610
|
}
|
|
22590
22611
|
return parts.join("\n").trim();
|
|
@@ -22598,7 +22619,7 @@ function extractSearchResults2(output, citations, numResults) {
|
|
|
22598
22619
|
if (!Array.isArray(content)) continue;
|
|
22599
22620
|
for (const part of content) {
|
|
22600
22621
|
if (!part || typeof part !== "object") continue;
|
|
22601
|
-
const
|
|
22622
|
+
const text4 = typeof part.text === "string" ? part.text : "";
|
|
22602
22623
|
const annotations = part.annotations;
|
|
22603
22624
|
if (!Array.isArray(annotations)) continue;
|
|
22604
22625
|
for (const annotation of annotations) {
|
|
@@ -22609,7 +22630,7 @@ function extractSearchResults2(output, citations, numResults) {
|
|
|
22609
22630
|
seenUrls,
|
|
22610
22631
|
annotation.url,
|
|
22611
22632
|
annotation.title,
|
|
22612
|
-
extractSnippetAround2(
|
|
22633
|
+
extractSnippetAround2(text4, annotation.start_index, annotation.end_index)
|
|
22613
22634
|
);
|
|
22614
22635
|
}
|
|
22615
22636
|
}
|
|
@@ -22847,8 +22868,8 @@ function errorMessage18(err) {
|
|
|
22847
22868
|
}
|
|
22848
22869
|
var STATUS_SHAPED_PATTERN = /\b(?:error|status|http)[\s:=-]{1,4}(\d{3})\b/gi;
|
|
22849
22870
|
var QUOTA_SHAPED_PATTERN = /rate limit|quota|too many requests/gi;
|
|
22850
|
-
function untrustedText(
|
|
22851
|
-
return
|
|
22871
|
+
function untrustedText(text4, limit = 300) {
|
|
22872
|
+
return text4.replace(/\s+/g, " ").trim().slice(0, limit).replace(STATUS_SHAPED_PATTERN, "upstream $1").replace(QUOTA_SHAPED_PATTERN, "upstream rate-limit notice");
|
|
22852
22873
|
}
|
|
22853
22874
|
function invalidResponse7(zone, message) {
|
|
22854
22875
|
return new Error(`Bright Data API returned invalid response for zone ${zone}: ${message}`);
|
|
@@ -23817,8 +23838,8 @@ function searchArguments2(query, options) {
|
|
|
23817
23838
|
...domain ? { search_domain_filter: domain } : {}
|
|
23818
23839
|
};
|
|
23819
23840
|
}
|
|
23820
|
-
function parseResults(
|
|
23821
|
-
let value = JSON.parse(
|
|
23841
|
+
function parseResults(text4, limit, domain) {
|
|
23842
|
+
let value = JSON.parse(text4);
|
|
23822
23843
|
if (typeof value === "string") value = JSON.parse(value);
|
|
23823
23844
|
if (!Array.isArray(value)) throw new Error("Z.ai returned invalid response: expected a result list");
|
|
23824
23845
|
const results = [];
|
|
@@ -23883,9 +23904,9 @@ async function searchWithZai(query, options = {}) {
|
|
|
23883
23904
|
if (!toolName) throw new Error("Z.ai returned invalid response: web search tool not listed");
|
|
23884
23905
|
const result = await client.callTool({ name: toolName, arguments: args }, void 0, { signal, timeout: SEARCH_TIMEOUT_MS28 });
|
|
23885
23906
|
if (result.isError) throw new Error("Z.ai search tool returned an error");
|
|
23886
|
-
const
|
|
23887
|
-
if (!
|
|
23888
|
-
const results = parseResults(
|
|
23907
|
+
const text4 = (Array.isArray(result.content) ? result.content : []).find((item) => item.type === "text" && typeof item.text === "string");
|
|
23908
|
+
if (!text4) throw new Error("Z.ai returned invalid response: no search text");
|
|
23909
|
+
const results = parseResults(text4.text, limit, args.search_domain_filter);
|
|
23889
23910
|
activityMonitor.logComplete(activityId, 200);
|
|
23890
23911
|
return { answer: formatSearchResultsAsAnswer(results), results };
|
|
23891
23912
|
} catch (err) {
|
|
@@ -24241,6 +24262,189 @@ async function searchWithKeenable(query, options = {}) {
|
|
|
24241
24262
|
return { answer: formatSearchResultsAsAnswer(results), results };
|
|
24242
24263
|
}
|
|
24243
24264
|
|
|
24265
|
+
// ceramic.ts
|
|
24266
|
+
init_activity();
|
|
24267
|
+
init_domain_filter_normalization();
|
|
24268
|
+
init_search_answer_formatting();
|
|
24269
|
+
init_search_result_count_normalization();
|
|
24270
|
+
init_credential_source();
|
|
24271
|
+
init_utils();
|
|
24272
|
+
import { existsSync as existsSync38, readFileSync as readFileSync39 } from "node:fs";
|
|
24273
|
+
var CERAMIC_SEARCH_URL = "https://api.ceramic.ai/search";
|
|
24274
|
+
var CONFIG_PATH36 = getWebSearchConfigPath();
|
|
24275
|
+
var SEARCH_TIMEOUT_MS31 = 3e4;
|
|
24276
|
+
var MAX_REQUEST_RESULTS2 = 20;
|
|
24277
|
+
var REQUEST_DESCRIPTION_CHARS = 1e3;
|
|
24278
|
+
var MAX_SNIPPET_CHARS3 = 500;
|
|
24279
|
+
var cachedConfig33 = null;
|
|
24280
|
+
function loadConfig34() {
|
|
24281
|
+
if (cachedConfig33) return cachedConfig33;
|
|
24282
|
+
if (!existsSync38(CONFIG_PATH36)) {
|
|
24283
|
+
cachedConfig33 = {};
|
|
24284
|
+
return cachedConfig33;
|
|
24285
|
+
}
|
|
24286
|
+
const raw = readFileSync39(CONFIG_PATH36, "utf-8");
|
|
24287
|
+
let parsed;
|
|
24288
|
+
try {
|
|
24289
|
+
parsed = JSON.parse(raw);
|
|
24290
|
+
} catch (err) {
|
|
24291
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
24292
|
+
throw new Error(`Failed to parse ${CONFIG_PATH36}: ${message}`);
|
|
24293
|
+
}
|
|
24294
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
24295
|
+
throw new Error(`Invalid config in ${CONFIG_PATH36}: expected a JSON object`);
|
|
24296
|
+
}
|
|
24297
|
+
cachedConfig33 = parsed;
|
|
24298
|
+
return cachedConfig33;
|
|
24299
|
+
}
|
|
24300
|
+
async function requireApiKey14(signal) {
|
|
24301
|
+
const apiKey = await resolveCredential({
|
|
24302
|
+
provider: "Ceramic",
|
|
24303
|
+
configuredValue: loadConfig34().ceramicApiKey,
|
|
24304
|
+
environmentValue: process.env.CERAMIC_API_KEY,
|
|
24305
|
+
signal
|
|
24306
|
+
});
|
|
24307
|
+
if (!apiKey) {
|
|
24308
|
+
throw new Error(
|
|
24309
|
+
`Ceramic API key not found. Either:
|
|
24310
|
+
1. Create ${CONFIG_PATH36} with { "ceramicApiKey": "your-key" }
|
|
24311
|
+
2. Set CERAMIC_API_KEY environment variable
|
|
24312
|
+
Get a key at https://platform.ceramic.ai/keys`
|
|
24313
|
+
);
|
|
24314
|
+
}
|
|
24315
|
+
return apiKey;
|
|
24316
|
+
}
|
|
24317
|
+
function parseDomainFilter10(domainFilter) {
|
|
24318
|
+
const filters = { include: [], exclude: [] };
|
|
24319
|
+
for (const raw of domainFilter ?? []) {
|
|
24320
|
+
const domain = normalizeDomain(raw);
|
|
24321
|
+
if (!domain) continue;
|
|
24322
|
+
const target = raw.trim().startsWith("-") ? filters.exclude : filters.include;
|
|
24323
|
+
if (!target.includes(domain)) target.push(domain);
|
|
24324
|
+
}
|
|
24325
|
+
return filters;
|
|
24326
|
+
}
|
|
24327
|
+
function passesDomainFilters10(url, filters) {
|
|
24328
|
+
if (filters.include.length === 0 && filters.exclude.length === 0) return true;
|
|
24329
|
+
const hostname2 = url.hostname.toLowerCase();
|
|
24330
|
+
const matches = (domain) => hostname2 === domain || hostname2.endsWith(`.${domain}`);
|
|
24331
|
+
if (filters.exclude.some(matches)) return false;
|
|
24332
|
+
return filters.include.length === 0 || filters.include.some(matches);
|
|
24333
|
+
}
|
|
24334
|
+
function buildQuery7(query, filters) {
|
|
24335
|
+
if (filters.include.length === 0) return query;
|
|
24336
|
+
const sites = filters.include.map((domain) => `site:${domain}`);
|
|
24337
|
+
return `${query} ${sites.length === 1 ? sites[0] : `(${sites.join(" OR ")})`}`;
|
|
24338
|
+
}
|
|
24339
|
+
function text3(value) {
|
|
24340
|
+
return typeof value === "string" ? value.replace(/\s+/g, " ").trim() : "";
|
|
24341
|
+
}
|
|
24342
|
+
function errorMessage25(err) {
|
|
24343
|
+
return err instanceof Error ? err.message : String(err);
|
|
24344
|
+
}
|
|
24345
|
+
function invalidResponse14(message) {
|
|
24346
|
+
return new Error(`Ceramic returned invalid response: ${message}`);
|
|
24347
|
+
}
|
|
24348
|
+
function parseResponse10(value) {
|
|
24349
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw invalidResponse14("expected an object envelope");
|
|
24350
|
+
const result = value.result;
|
|
24351
|
+
if (!result || typeof result !== "object" || Array.isArray(result)) throw invalidResponse14("expected result object");
|
|
24352
|
+
const results = result.results;
|
|
24353
|
+
if (!Array.isArray(results)) throw invalidResponse14("expected result.results array");
|
|
24354
|
+
return results;
|
|
24355
|
+
}
|
|
24356
|
+
function describeError(body) {
|
|
24357
|
+
try {
|
|
24358
|
+
const parsed = JSON.parse(body);
|
|
24359
|
+
const parts = [text3(parsed.title), text3(parsed.detail)].filter(Boolean);
|
|
24360
|
+
if (parts.length > 0) return parts.join(": ");
|
|
24361
|
+
} catch {
|
|
24362
|
+
}
|
|
24363
|
+
return body;
|
|
24364
|
+
}
|
|
24365
|
+
function isCeramicAvailable() {
|
|
24366
|
+
return hasCredentialSource({ provider: "Ceramic", configuredValue: loadConfig34().ceramicApiKey, environmentValue: process.env.CERAMIC_API_KEY });
|
|
24367
|
+
}
|
|
24368
|
+
async function searchWithCeramic(query, options = {}) {
|
|
24369
|
+
const apiKey = await requireApiKey14(options.signal);
|
|
24370
|
+
const numResults = normalizeSearchResultCount(options.numResults);
|
|
24371
|
+
const filters = parseDomainFilter10(options.domainFilter);
|
|
24372
|
+
const hasDomainFilters = filters.include.length > 0 || filters.exclude.length > 0;
|
|
24373
|
+
const body = {
|
|
24374
|
+
query: buildQuery7(query, filters),
|
|
24375
|
+
maxResults: hasDomainFilters ? Math.min(MAX_REQUEST_RESULTS2, numResults + 5) : numResults,
|
|
24376
|
+
maxDescriptionLength: REQUEST_DESCRIPTION_CHARS
|
|
24377
|
+
};
|
|
24378
|
+
const activityId = activityMonitor.logStart({ type: "api", query });
|
|
24379
|
+
const timeoutSignal = AbortSignal.timeout(SEARCH_TIMEOUT_MS31);
|
|
24380
|
+
let response;
|
|
24381
|
+
let entries;
|
|
24382
|
+
try {
|
|
24383
|
+
response = await fetchWithCredentialRedirects(CERAMIC_SEARCH_URL, {
|
|
24384
|
+
method: "POST",
|
|
24385
|
+
headers: {
|
|
24386
|
+
Accept: "application/json",
|
|
24387
|
+
"Content-Type": "application/json",
|
|
24388
|
+
Authorization: `Bearer ${apiKey}`
|
|
24389
|
+
},
|
|
24390
|
+
body: JSON.stringify(body),
|
|
24391
|
+
signal: options.signal ? AbortSignal.any([timeoutSignal, options.signal]) : timeoutSignal
|
|
24392
|
+
}, ["Authorization"]);
|
|
24393
|
+
if (!response.ok) {
|
|
24394
|
+
const errorText = redactCredential(describeError(await response.text()), apiKey).slice(0, 300);
|
|
24395
|
+
throw new Error(`Ceramic error ${response.status}: ${errorText}`);
|
|
24396
|
+
}
|
|
24397
|
+
let rawData;
|
|
24398
|
+
try {
|
|
24399
|
+
rawData = await response.json();
|
|
24400
|
+
} catch (err) {
|
|
24401
|
+
if (err instanceof Error && err.name === "TimeoutError") throw err;
|
|
24402
|
+
throw new Error(`Ceramic returned invalid JSON: ${errorMessage25(err)}`);
|
|
24403
|
+
}
|
|
24404
|
+
entries = parseResponse10(rawData);
|
|
24405
|
+
} catch (err) {
|
|
24406
|
+
if (options.signal?.aborted) {
|
|
24407
|
+
activityMonitor.logComplete(activityId, 0);
|
|
24408
|
+
throw new Error("Aborted");
|
|
24409
|
+
}
|
|
24410
|
+
const message = errorMessage25(err);
|
|
24411
|
+
const providerTimeout = timeoutSignal.aborted || err instanceof Error && err.name === "TimeoutError";
|
|
24412
|
+
const outgoing = providerTimeout ? new Error(`Ceramic request timed out after ${Math.round(SEARCH_TIMEOUT_MS31 / 1e3)}s`) : (() => {
|
|
24413
|
+
const redactedMessage = redactCredential(message, apiKey);
|
|
24414
|
+
if (redactedMessage === message && err instanceof Error) return err;
|
|
24415
|
+
const redactedError = new Error(redactedMessage);
|
|
24416
|
+
if (err instanceof Error) redactedError.name = err.name;
|
|
24417
|
+
return redactedError;
|
|
24418
|
+
})();
|
|
24419
|
+
activityMonitor.logError(activityId, redactCredential(errorMessage25(outgoing), apiKey));
|
|
24420
|
+
throw outgoing;
|
|
24421
|
+
}
|
|
24422
|
+
activityMonitor.logComplete(activityId, response.status);
|
|
24423
|
+
const results = [];
|
|
24424
|
+
const seen = /* @__PURE__ */ new Set();
|
|
24425
|
+
for (const entry of entries) {
|
|
24426
|
+
if (!entry || typeof entry !== "object") continue;
|
|
24427
|
+
if (typeof entry.url !== "string" || !entry.url) continue;
|
|
24428
|
+
let resultUrl;
|
|
24429
|
+
try {
|
|
24430
|
+
resultUrl = new URL(entry.url);
|
|
24431
|
+
} catch {
|
|
24432
|
+
continue;
|
|
24433
|
+
}
|
|
24434
|
+
if (resultUrl.protocol !== "http:" && resultUrl.protocol !== "https:") continue;
|
|
24435
|
+
if (!passesDomainFilters10(resultUrl, filters)) continue;
|
|
24436
|
+
if (seen.has(resultUrl.href)) continue;
|
|
24437
|
+
seen.add(resultUrl.href);
|
|
24438
|
+
results.push({
|
|
24439
|
+
title: text3(entry.title) || `Source ${results.length + 1}`,
|
|
24440
|
+
url: resultUrl.href,
|
|
24441
|
+
snippet: text3(entry.description).slice(0, MAX_SNIPPET_CHARS3)
|
|
24442
|
+
});
|
|
24443
|
+
if (results.length >= numResults) break;
|
|
24444
|
+
}
|
|
24445
|
+
return { answer: formatSearchResultsAsAnswer(results), results };
|
|
24446
|
+
}
|
|
24447
|
+
|
|
24244
24448
|
// kimi-search.ts
|
|
24245
24449
|
init_activity();
|
|
24246
24450
|
init_domain_filter_normalization();
|
|
@@ -24250,7 +24454,7 @@ init_search_result_count_normalization();
|
|
|
24250
24454
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
24251
24455
|
var KIMI_SEARCH_URL = "https://api.kimi.com/coding/v1/search";
|
|
24252
24456
|
var KIMI_PROVIDERS = ["kimi-coding", "kimi-code"];
|
|
24253
|
-
var
|
|
24457
|
+
var SEARCH_TIMEOUT_MS32 = 3e4;
|
|
24254
24458
|
function buildRequestHeaders(auth) {
|
|
24255
24459
|
const headers = new Headers();
|
|
24256
24460
|
for (const [name, value] of Object.entries(auth.headers)) {
|
|
@@ -24365,7 +24569,7 @@ async function searchWithKimi(query, options = {}, ctx) {
|
|
|
24365
24569
|
throw new Error("Kimi Code web search unavailable. Run /login kimi-coding to authenticate a Kimi Code Plan account.");
|
|
24366
24570
|
}
|
|
24367
24571
|
const activityId = activityMonitor.logStart({ type: "api", query });
|
|
24368
|
-
const timeoutSignal = AbortSignal.timeout(
|
|
24572
|
+
const timeoutSignal = AbortSignal.timeout(SEARCH_TIMEOUT_MS32);
|
|
24369
24573
|
const requestSignal15 = options.signal ? AbortSignal.any([timeoutSignal, options.signal]) : timeoutSignal;
|
|
24370
24574
|
try {
|
|
24371
24575
|
const response = await fetch(KIMI_SEARCH_URL, {
|
|
@@ -24417,45 +24621,45 @@ init_activity();
|
|
|
24417
24621
|
init_domain_filter_normalization();
|
|
24418
24622
|
init_credential_source();
|
|
24419
24623
|
init_utils();
|
|
24420
|
-
import { existsSync as
|
|
24624
|
+
import { existsSync as existsSync39, readFileSync as readFileSync40 } from "node:fs";
|
|
24421
24625
|
var MISTRAL_CONVERSATIONS_URL = "https://api.mistral.ai/v1/conversations";
|
|
24422
|
-
var
|
|
24423
|
-
var
|
|
24626
|
+
var CONFIG_PATH37 = getWebSearchConfigPath();
|
|
24627
|
+
var SEARCH_TIMEOUT_MS33 = 6e4;
|
|
24424
24628
|
var DEFAULT_SEARCH_MODEL = "mistral-small-latest";
|
|
24425
24629
|
var DEFAULT_SEARCH_TOOL = "web_search";
|
|
24426
24630
|
var MAX_RESULTS = 20;
|
|
24427
|
-
var
|
|
24428
|
-
function
|
|
24429
|
-
if (
|
|
24430
|
-
if (!
|
|
24431
|
-
|
|
24432
|
-
return
|
|
24631
|
+
var cachedConfig34 = null;
|
|
24632
|
+
function loadConfig35() {
|
|
24633
|
+
if (cachedConfig34) return cachedConfig34;
|
|
24634
|
+
if (!existsSync39(CONFIG_PATH37)) {
|
|
24635
|
+
cachedConfig34 = {};
|
|
24636
|
+
return cachedConfig34;
|
|
24433
24637
|
}
|
|
24434
|
-
const raw =
|
|
24638
|
+
const raw = readFileSync40(CONFIG_PATH37, "utf-8");
|
|
24435
24639
|
let parsed;
|
|
24436
24640
|
try {
|
|
24437
24641
|
parsed = JSON.parse(raw);
|
|
24438
24642
|
} catch (err) {
|
|
24439
24643
|
const message = err instanceof Error ? err.message : String(err);
|
|
24440
|
-
throw new Error(`Failed to parse ${
|
|
24644
|
+
throw new Error(`Failed to parse ${CONFIG_PATH37}: ${message}`);
|
|
24441
24645
|
}
|
|
24442
24646
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
24443
|
-
throw new Error(`Invalid config in ${
|
|
24647
|
+
throw new Error(`Invalid config in ${CONFIG_PATH37}: expected a JSON object`);
|
|
24444
24648
|
}
|
|
24445
|
-
|
|
24446
|
-
return
|
|
24649
|
+
cachedConfig34 = parsed;
|
|
24650
|
+
return cachedConfig34;
|
|
24447
24651
|
}
|
|
24448
24652
|
function resolveSearchModel(value) {
|
|
24449
24653
|
if (value === void 0) return DEFAULT_SEARCH_MODEL;
|
|
24450
24654
|
if (typeof value !== "string" || value.trim().length === 0) {
|
|
24451
|
-
throw new Error(`mistralSearchModel in ${
|
|
24655
|
+
throw new Error(`mistralSearchModel in ${CONFIG_PATH37} must be a non-empty string`);
|
|
24452
24656
|
}
|
|
24453
24657
|
return value.trim();
|
|
24454
24658
|
}
|
|
24455
24659
|
function resolveSearchTool(value) {
|
|
24456
24660
|
if (value === void 0) return DEFAULT_SEARCH_TOOL;
|
|
24457
24661
|
if (value !== "web_search" && value !== "web_search_premium") {
|
|
24458
|
-
throw new Error(`mistralSearchTool in ${
|
|
24662
|
+
throw new Error(`mistralSearchTool in ${CONFIG_PATH37} must be either web_search or web_search_premium`);
|
|
24459
24663
|
}
|
|
24460
24664
|
return value;
|
|
24461
24665
|
}
|
|
@@ -24473,7 +24677,7 @@ function parseDomainFilters(domainFilter) {
|
|
|
24473
24677
|
}
|
|
24474
24678
|
return filters;
|
|
24475
24679
|
}
|
|
24476
|
-
function
|
|
24680
|
+
function passesDomainFilters11(url, filters) {
|
|
24477
24681
|
if (filters.include.length === 0 && filters.exclude.length === 0) return true;
|
|
24478
24682
|
const hostname2 = new URL(url).hostname.toLowerCase();
|
|
24479
24683
|
const matches = (domain) => hostname2 === domain || hostname2.endsWith(`.${domain}`);
|
|
@@ -24513,18 +24717,18 @@ function buildSearchPrompt(query, options, numResults) {
|
|
|
24513
24717
|
|
|
24514
24718
|
${query}` : query;
|
|
24515
24719
|
}
|
|
24516
|
-
function
|
|
24720
|
+
function errorMessage26(err) {
|
|
24517
24721
|
return err instanceof Error ? err.message : String(err);
|
|
24518
24722
|
}
|
|
24519
|
-
function
|
|
24723
|
+
function invalidResponse15(message) {
|
|
24520
24724
|
return new Error(`Mistral API returned invalid response: ${message}`);
|
|
24521
24725
|
}
|
|
24522
24726
|
function parseConversationResponse(value, options, numResults) {
|
|
24523
24727
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
24524
|
-
throw
|
|
24728
|
+
throw invalidResponse15("expected an object envelope");
|
|
24525
24729
|
}
|
|
24526
24730
|
const outputs = value.outputs;
|
|
24527
|
-
if (!Array.isArray(outputs)) throw
|
|
24731
|
+
if (!Array.isArray(outputs)) throw invalidResponse15("outputs must be an array");
|
|
24528
24732
|
const answerParts = [];
|
|
24529
24733
|
const results = [];
|
|
24530
24734
|
const seenUrls = /* @__PURE__ */ new Set();
|
|
@@ -24548,7 +24752,7 @@ function parseConversationResponse(value, options, numResults) {
|
|
|
24548
24752
|
}
|
|
24549
24753
|
if (part.type !== "tool_reference" || results.length >= numResults) continue;
|
|
24550
24754
|
const url = normalizeResultUrl2(part.url);
|
|
24551
|
-
if (!url || !
|
|
24755
|
+
if (!url || !passesDomainFilters11(url, domainFilters) || seenUrls.has(url)) continue;
|
|
24552
24756
|
seenUrls.add(url);
|
|
24553
24757
|
const title = typeof part.title === "string" && part.title.trim() ? part.title.trim() : url;
|
|
24554
24758
|
const snippet = typeof part.description === "string" ? part.description : "";
|
|
@@ -24556,20 +24760,20 @@ function parseConversationResponse(value, options, numResults) {
|
|
|
24556
24760
|
}
|
|
24557
24761
|
}
|
|
24558
24762
|
const answer = answerParts.join("\n").trim();
|
|
24559
|
-
if (!answer && results.length === 0) throw
|
|
24763
|
+
if (!answer && results.length === 0) throw invalidResponse15("no answer or sources");
|
|
24560
24764
|
return { answer, results };
|
|
24561
24765
|
}
|
|
24562
24766
|
async function getApiKey26(signal) {
|
|
24563
24767
|
const apiKey = await resolveCredential({
|
|
24564
24768
|
provider: "Mistral",
|
|
24565
|
-
configuredValue:
|
|
24769
|
+
configuredValue: loadConfig35().mistralApiKey,
|
|
24566
24770
|
environmentValue: process.env.MISTRAL_API_KEY,
|
|
24567
24771
|
signal
|
|
24568
24772
|
});
|
|
24569
24773
|
if (!apiKey) {
|
|
24570
24774
|
throw new Error(
|
|
24571
24775
|
`Mistral API key not found. Either:
|
|
24572
|
-
1. Create ${
|
|
24776
|
+
1. Create ${CONFIG_PATH37} with { "mistralApiKey": "your-key" }
|
|
24573
24777
|
2. Set MISTRAL_API_KEY environment variable
|
|
24574
24778
|
Get a key at https://console.mistral.ai/api-keys`
|
|
24575
24779
|
);
|
|
@@ -24578,7 +24782,7 @@ Get a key at https://console.mistral.ai/api-keys`
|
|
|
24578
24782
|
}
|
|
24579
24783
|
function isMistralAvailable() {
|
|
24580
24784
|
try {
|
|
24581
|
-
const config =
|
|
24785
|
+
const config = loadConfig35();
|
|
24582
24786
|
resolveSearchModel(config.mistralSearchModel);
|
|
24583
24787
|
resolveSearchTool(config.mistralSearchTool);
|
|
24584
24788
|
return hasCredentialSource({
|
|
@@ -24591,12 +24795,12 @@ function isMistralAvailable() {
|
|
|
24591
24795
|
}
|
|
24592
24796
|
}
|
|
24593
24797
|
async function searchWithMistral(query, options = {}) {
|
|
24594
|
-
const config =
|
|
24798
|
+
const config = loadConfig35();
|
|
24595
24799
|
const model = resolveSearchModel(config.mistralSearchModel);
|
|
24596
24800
|
const tool = resolveSearchTool(config.mistralSearchTool);
|
|
24597
24801
|
const numResults = normalizeCount4(options.numResults);
|
|
24598
24802
|
const apiKey = await getApiKey26(options.signal);
|
|
24599
|
-
const requestSignal15 = options.signal ? AbortSignal.any([AbortSignal.timeout(
|
|
24803
|
+
const requestSignal15 = options.signal ? AbortSignal.any([AbortSignal.timeout(SEARCH_TIMEOUT_MS33), options.signal]) : AbortSignal.timeout(SEARCH_TIMEOUT_MS33);
|
|
24600
24804
|
const activityId = activityMonitor.logStart({ type: "api", query });
|
|
24601
24805
|
try {
|
|
24602
24806
|
const response = await fetch(MISTRAL_CONVERSATIONS_URL, {
|
|
@@ -24621,13 +24825,13 @@ async function searchWithMistral(query, options = {}) {
|
|
|
24621
24825
|
try {
|
|
24622
24826
|
parsed = await response.json();
|
|
24623
24827
|
} catch (err) {
|
|
24624
|
-
throw new Error(`Mistral API returned invalid JSON: ${
|
|
24828
|
+
throw new Error(`Mistral API returned invalid JSON: ${errorMessage26(err)}`);
|
|
24625
24829
|
}
|
|
24626
24830
|
const result = parseConversationResponse(parsed, options, numResults);
|
|
24627
24831
|
activityMonitor.logComplete(activityId, response.status);
|
|
24628
24832
|
return result;
|
|
24629
24833
|
} catch (err) {
|
|
24630
|
-
const message =
|
|
24834
|
+
const message = errorMessage26(err);
|
|
24631
24835
|
const redactedMessage = redactCredential(message, apiKey);
|
|
24632
24836
|
if (redactedMessage.toLowerCase().includes("abort")) {
|
|
24633
24837
|
activityMonitor.logComplete(activityId, 0);
|
|
@@ -24643,7 +24847,7 @@ async function searchWithMistral(query, options = {}) {
|
|
|
24643
24847
|
|
|
24644
24848
|
// gemini-search.ts
|
|
24645
24849
|
init_utils();
|
|
24646
|
-
var RESOLVED_SEARCH_PROVIDERS = ["openai", "brave", "parallel", "parallel-mcp", "tinyfish", "search1api", "searchinfinity", "querit", "tavily", "you", "firecrawl", "jina", "searxng", "degoog", "duckduckgo", "perplexity", "gemini", "kimi", "exa", "serpdive", "kagi", "ollama", "anysearch", "xai", "mistral", "brightdata", "serpbase", "serpapi", "serper", "serply", "valyu", "bocha", "xcrawl", "baizhi", "zai", "keenable"];
|
|
24850
|
+
var RESOLVED_SEARCH_PROVIDERS = ["openai", "brave", "parallel", "parallel-mcp", "tinyfish", "search1api", "searchinfinity", "querit", "tavily", "you", "firecrawl", "jina", "searxng", "degoog", "duckduckgo", "perplexity", "gemini", "kimi", "exa", "serpdive", "kagi", "ollama", "anysearch", "xai", "mistral", "brightdata", "serpbase", "serpapi", "serper", "serply", "valyu", "bocha", "xcrawl", "baizhi", "zai", "keenable", "ceramic"];
|
|
24647
24851
|
var SEARCH_PROVIDERS = ["auto", "all", ...RESOLVED_SEARCH_PROVIDERS];
|
|
24648
24852
|
var SearchProviderError = class extends Error {
|
|
24649
24853
|
provider;
|
|
@@ -24659,18 +24863,18 @@ var SearchProviderError = class extends Error {
|
|
|
24659
24863
|
this.causeError = cause;
|
|
24660
24864
|
}
|
|
24661
24865
|
};
|
|
24662
|
-
var
|
|
24866
|
+
var CONFIG_PATH38 = getWebSearchConfigPath();
|
|
24663
24867
|
var DEFAULT_SEARCH_MODEL2 = "gemini-3.6-flash";
|
|
24664
24868
|
var ALL_SEARCH_PROVIDERS = ["searxng", "openai", "exa", "brave", "parallel", "tinyfish", "search1api", "searchinfinity", "querit", "tavily", "firecrawl", "jina", "serpdive", "kagi", "ollama", "perplexity", "gemini", "bocha"];
|
|
24665
24869
|
var VALID_ROUTING_KINDS = ["transient", "quota", "network", "invalid-response", "unsupported"];
|
|
24666
24870
|
var cachedSearchConfig = null;
|
|
24667
24871
|
function getSearchConfig() {
|
|
24668
24872
|
if (cachedSearchConfig) return cachedSearchConfig;
|
|
24669
|
-
if (!
|
|
24873
|
+
if (!existsSync40(CONFIG_PATH38)) {
|
|
24670
24874
|
cachedSearchConfig = { searchProvider: "auto", searchProviderConfigured: false };
|
|
24671
24875
|
return cachedSearchConfig;
|
|
24672
24876
|
}
|
|
24673
|
-
const rawText =
|
|
24877
|
+
const rawText = readFileSync41(CONFIG_PATH38, "utf-8");
|
|
24674
24878
|
let raw;
|
|
24675
24879
|
try {
|
|
24676
24880
|
const parsed = JSON.parse(rawText);
|
|
@@ -24680,25 +24884,25 @@ function getSearchConfig() {
|
|
|
24680
24884
|
raw = parsed;
|
|
24681
24885
|
} catch (err) {
|
|
24682
24886
|
const message = err instanceof Error ? err.message : String(err);
|
|
24683
|
-
throw new Error(`Failed to parse ${
|
|
24887
|
+
throw new Error(`Failed to parse ${CONFIG_PATH38}: ${message}`);
|
|
24684
24888
|
}
|
|
24685
24889
|
const searchModel = normalizeSearchModel(raw.searchModel);
|
|
24686
24890
|
const webSearch = raw.webSearch;
|
|
24687
24891
|
if (webSearch !== void 0 && (!webSearch || typeof webSearch !== "object" || Array.isArray(webSearch))) {
|
|
24688
|
-
throw new Error(`webSearch in ${
|
|
24892
|
+
throw new Error(`webSearch in ${CONFIG_PATH38} must be an object`);
|
|
24689
24893
|
}
|
|
24690
|
-
const allowedProviders = webSearch && Object.hasOwn(webSearch, "allowedProviders") ? normalizeResolvedProviderList(webSearch.allowedProviders, `webSearch.allowedProviders in ${
|
|
24894
|
+
const allowedProviders = webSearch && Object.hasOwn(webSearch, "allowedProviders") ? normalizeResolvedProviderList(webSearch.allowedProviders, `webSearch.allowedProviders in ${CONFIG_PATH38}`) : void 0;
|
|
24691
24895
|
const searchProviderConfigured = Object.hasOwn(raw, "searchProvider") || Object.hasOwn(raw, "provider");
|
|
24692
|
-
const searchProvider = normalizeSearchProviderSelection(raw.searchProvider ?? raw.provider, `provider in ${
|
|
24896
|
+
const searchProvider = normalizeSearchProviderSelection(raw.searchProvider ?? raw.provider, `provider in ${CONFIG_PATH38}`);
|
|
24693
24897
|
const searchRouting = Object.hasOwn(raw, "searchRouting") ? normalizeSearchRouting(raw.searchRouting) : void 0;
|
|
24694
24898
|
if (allowedProviders) {
|
|
24695
24899
|
if (Object.hasOwn(raw, "searchProvider")) {
|
|
24696
|
-
assertSearchProviderSelectionAllowed(normalizeSearchProviderSelection(raw.searchProvider), `searchProvider in ${
|
|
24900
|
+
assertSearchProviderSelectionAllowed(normalizeSearchProviderSelection(raw.searchProvider), `searchProvider in ${CONFIG_PATH38}`, allowedProviders);
|
|
24697
24901
|
}
|
|
24698
24902
|
if (Object.hasOwn(raw, "provider")) {
|
|
24699
|
-
assertSearchProviderSelectionAllowed(normalizeSearchProviderSelection(raw.provider), `provider in ${
|
|
24903
|
+
assertSearchProviderSelectionAllowed(normalizeSearchProviderSelection(raw.provider), `provider in ${CONFIG_PATH38}`, allowedProviders);
|
|
24700
24904
|
}
|
|
24701
|
-
if (searchRouting) assertSearchProviderSelectionAllowed(searchRouting.providers, `searchRouting.providers in ${
|
|
24905
|
+
if (searchRouting) assertSearchProviderSelectionAllowed(searchRouting.providers, `searchRouting.providers in ${CONFIG_PATH38}`, allowedProviders);
|
|
24702
24906
|
}
|
|
24703
24907
|
cachedSearchConfig = {
|
|
24704
24908
|
searchProvider,
|
|
@@ -24711,21 +24915,21 @@ function getSearchConfig() {
|
|
|
24711
24915
|
}
|
|
24712
24916
|
function normalizeSearchRouting(value) {
|
|
24713
24917
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
24714
|
-
throw new Error(`searchRouting in ${
|
|
24918
|
+
throw new Error(`searchRouting in ${CONFIG_PATH38} must be an object`);
|
|
24715
24919
|
}
|
|
24716
24920
|
const raw = value;
|
|
24717
|
-
const providers = normalizeResolvedProviderList(raw.providers, `searchRouting.providers in ${
|
|
24921
|
+
const providers = normalizeResolvedProviderList(raw.providers, `searchRouting.providers in ${CONFIG_PATH38}`);
|
|
24718
24922
|
const useCurrentModel = raw.useCurrentModel;
|
|
24719
24923
|
if (useCurrentModel !== void 0 && typeof useCurrentModel !== "boolean") {
|
|
24720
|
-
throw new Error(`searchRouting.useCurrentModel in ${
|
|
24924
|
+
throw new Error(`searchRouting.useCurrentModel in ${CONFIG_PATH38} must be a boolean`);
|
|
24721
24925
|
}
|
|
24722
24926
|
if (!Array.isArray(raw.fallbackOn) || raw.fallbackOn.length === 0) {
|
|
24723
|
-
throw new Error(`searchRouting.fallbackOn in ${
|
|
24927
|
+
throw new Error(`searchRouting.fallbackOn in ${CONFIG_PATH38} must be a non-empty array`);
|
|
24724
24928
|
}
|
|
24725
24929
|
const fallbackOn = [];
|
|
24726
24930
|
for (const kind of raw.fallbackOn) {
|
|
24727
24931
|
if (typeof kind !== "string" || !VALID_ROUTING_KINDS.includes(kind)) {
|
|
24728
|
-
throw new Error(`searchRouting.fallbackOn in ${
|
|
24932
|
+
throw new Error(`searchRouting.fallbackOn in ${CONFIG_PATH38} may only contain transient, quota, network, invalid-response, or unsupported`);
|
|
24729
24933
|
}
|
|
24730
24934
|
if (!fallbackOn.includes(kind)) {
|
|
24731
24935
|
fallbackOn.push(kind);
|
|
@@ -24775,11 +24979,11 @@ function normalizeSearchProviderSelection(value, label = "provider") {
|
|
|
24775
24979
|
const normalized = typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
24776
24980
|
return SEARCH_PROVIDERS.includes(normalized) ? normalized : "auto";
|
|
24777
24981
|
}
|
|
24778
|
-
function
|
|
24982
|
+
function errorMessage27(err) {
|
|
24779
24983
|
return err instanceof Error ? err.message : String(err);
|
|
24780
24984
|
}
|
|
24781
24985
|
function isAbortError2(err) {
|
|
24782
|
-
return
|
|
24986
|
+
return errorMessage27(err).toLowerCase().includes("abort");
|
|
24783
24987
|
}
|
|
24784
24988
|
async function tryOpenAIInAuto(query, options, fallbackErrors) {
|
|
24785
24989
|
try {
|
|
@@ -24789,7 +24993,7 @@ async function tryOpenAIInAuto(query, options, fallbackErrors) {
|
|
|
24789
24993
|
}
|
|
24790
24994
|
} catch (err) {
|
|
24791
24995
|
if (isAbortError2(err)) throw err;
|
|
24792
|
-
fallbackErrors.push(`OpenAI: ${
|
|
24996
|
+
fallbackErrors.push(`OpenAI: ${errorMessage27(err)}`);
|
|
24793
24997
|
}
|
|
24794
24998
|
return null;
|
|
24795
24999
|
}
|
|
@@ -24800,7 +25004,7 @@ async function searchWithGemini(query, options, strictErrors) {
|
|
|
24800
25004
|
if (apiResult) return apiResult;
|
|
24801
25005
|
} catch (err) {
|
|
24802
25006
|
if (err instanceof CredentialResolutionError || isAbortError2(err)) throw err;
|
|
24803
|
-
errors.push(`Gemini API: ${
|
|
25007
|
+
errors.push(`Gemini API: ${errorMessage27(err)}`);
|
|
24804
25008
|
}
|
|
24805
25009
|
try {
|
|
24806
25010
|
const webResult = await searchWithGeminiWeb(query, options);
|
|
@@ -24809,7 +25013,7 @@ async function searchWithGemini(query, options, strictErrors) {
|
|
|
24809
25013
|
if (diagnostic) errors.push(`Gemini Web: ${diagnostic}`);
|
|
24810
25014
|
} catch (err) {
|
|
24811
25015
|
if (isAbortError2(err)) throw err;
|
|
24812
|
-
errors.push(`Gemini Web: ${
|
|
25016
|
+
errors.push(`Gemini Web: ${errorMessage27(err)}`);
|
|
24813
25017
|
}
|
|
24814
25018
|
if (strictErrors && errors.length > 0) {
|
|
24815
25019
|
throw new Error(`Gemini search failed:
|
|
@@ -24824,11 +25028,11 @@ function providerErrorStatus(message) {
|
|
|
24824
25028
|
}
|
|
24825
25029
|
function classifyProviderError(provider, err) {
|
|
24826
25030
|
if (err instanceof SearchProviderError) return err;
|
|
24827
|
-
const message =
|
|
25031
|
+
const message = errorMessage27(err);
|
|
24828
25032
|
const lower = message.toLowerCase();
|
|
24829
25033
|
const status = providerErrorStatus(message);
|
|
24830
25034
|
const openAIStreamError = provider === "openai" && lower.includes("openai api stream error");
|
|
24831
|
-
const
|
|
25035
|
+
const text4 = openAIStreamError ? lower.replace(/_/g, " ") : lower;
|
|
24832
25036
|
let kind = "unknown";
|
|
24833
25037
|
const mentionsUnsupportedWebSearch = /(?:web[_ -]?search|web[_ -]?search_preview|(?:the )?tool)\b.*\b(?:unsupported|not supported|does not support|doesn't support|unknown|unrecognized|unavailable|not found)|\b(?:unsupported|not supported|does not support|doesn't support|unknown|unrecognized|unavailable|not found)\b.*\b(?:web[_ -]?search|web[_ -]?search_preview|(?:the )?tool)/i.test(lower);
|
|
24834
25038
|
if (err instanceof CredentialResolutionError || /(?:api )?key (?:not found|missing)|credential resolution/.test(lower)) {
|
|
@@ -24849,19 +25053,19 @@ function classifyProviderError(provider, err) {
|
|
|
24849
25053
|
kind = "quota";
|
|
24850
25054
|
} else if (status !== void 0 && (status === 408 || status === 425 || status >= 500)) {
|
|
24851
25055
|
kind = "transient";
|
|
24852
|
-
} else if (/rate limit|quota|too many requests/.test(
|
|
25056
|
+
} else if (/rate limit|quota|too many requests/.test(text4) || openAIStreamError && /usage limit/.test(text4)) {
|
|
24853
25057
|
kind = "quota";
|
|
24854
|
-
} else if (/unauthorized|forbidden|permission denied/.test(
|
|
25058
|
+
} else if (/unauthorized|forbidden|permission denied/.test(text4) || openAIStreamError && /authentication error|permission error|invalid api key/.test(text4)) {
|
|
24855
25059
|
kind = "auth";
|
|
24856
|
-
} else if (/bad request|invalid request/.test(
|
|
25060
|
+
} else if (/bad request|invalid request/.test(text4)) {
|
|
24857
25061
|
kind = "invalid-request";
|
|
24858
|
-
} else if (/invalid json|no parseable response|no parseable results|invalid response|returned empty response|no web_search_call/.test(
|
|
25062
|
+
} else if (/invalid json|no parseable response|no parseable results|invalid response|returned empty response|no web_search_call/.test(text4)) {
|
|
24859
25063
|
kind = "invalid-response";
|
|
24860
|
-
} else if (/temporar|service unavailable|server error/.test(
|
|
25064
|
+
} else if (/temporar|service unavailable|server error/.test(text4) || openAIStreamError && /internal error|\bapi error|overloaded/.test(text4)) {
|
|
24861
25065
|
kind = "transient";
|
|
24862
|
-
} else if (err instanceof TypeError || /fetch failed|network|econnreset|econnrefused|enotfound|etimedout|timed out|socket/.test(
|
|
25066
|
+
} else if (err instanceof TypeError || /fetch failed|network|econnreset|econnrefused|enotfound|etimedout|timed out|socket/.test(text4)) {
|
|
24863
25067
|
kind = "network";
|
|
24864
|
-
} else if (/invalid or missing|invalid config|failed to parse|must be an? |configuration/.test(
|
|
25068
|
+
} else if (/invalid or missing|invalid config|failed to parse|must be an? |configuration/.test(text4)) {
|
|
24865
25069
|
kind = "config";
|
|
24866
25070
|
} else if (openAIStreamError) {
|
|
24867
25071
|
kind = "invalid-response";
|
|
@@ -24900,6 +25104,7 @@ async function searchWithResolvedProvider(provider, query, options, useCurrentMo
|
|
|
24900
25104
|
if (provider === "zai") return { ...await searchWithZai(query, options), provider };
|
|
24901
25105
|
if (provider === "valyu") return { ...await searchWithValyu(query, options), provider };
|
|
24902
25106
|
if (provider === "keenable") return { ...await searchWithKeenable(query, options), provider };
|
|
25107
|
+
if (provider === "ceramic") return { ...await searchWithCeramic(query, options), provider };
|
|
24903
25108
|
if (provider === "xcrawl") return { ...await searchWithXCrawl(query, options), provider };
|
|
24904
25109
|
if (provider === "perplexity") return { ...await searchWithPerplexity(query, options), provider };
|
|
24905
25110
|
if (provider === "searxng") return { ...await searchWithSearXNG(query, options), provider };
|
|
@@ -24911,7 +25116,7 @@ async function searchWithResolvedProvider(provider, query, options, useCurrentMo
|
|
|
24911
25116
|
if (result2) return { ...result2, provider };
|
|
24912
25117
|
throw new Error(
|
|
24913
25118
|
`Gemini search unavailable. Either:
|
|
24914
|
-
1. Configure geminiApiKey in ${
|
|
25119
|
+
1. Configure geminiApiKey in ${CONFIG_PATH38} or set GEMINI_API_KEY
|
|
24915
25120
|
2. Set GOOGLE_GEMINI_BASE_URL + CLOUDFLARE_API_KEY for Cloudflare AI Gateway routing
|
|
24916
25121
|
3. Set geminiAuth to "adc" in web-search.json with a Google Cloud ADC + project/location
|
|
24917
25122
|
4. Sign into gemini.google.com in a supported Chromium-based browser`
|
|
@@ -24952,6 +25157,7 @@ async function isResolvedProviderAvailable(provider, options, useCurrentModel =
|
|
|
24952
25157
|
if (provider === "zai") return isZaiAvailable();
|
|
24953
25158
|
if (provider === "valyu") return isValyuAvailable();
|
|
24954
25159
|
if (provider === "keenable") return isKeenableAvailable();
|
|
25160
|
+
if (provider === "ceramic") return isCeramicAvailable();
|
|
24955
25161
|
if (provider === "xcrawl") return isXcrawlAvailable();
|
|
24956
25162
|
if (provider === "perplexity") return isPerplexityAvailable();
|
|
24957
25163
|
if (provider === "searxng") return isSearXNGAvailable();
|
|
@@ -24997,6 +25203,7 @@ function providerLabel(provider) {
|
|
|
24997
25203
|
if (provider === "zai") return "Z.ai";
|
|
24998
25204
|
if (provider === "valyu") return "Valyu";
|
|
24999
25205
|
if (provider === "keenable") return "Keenable";
|
|
25206
|
+
if (provider === "ceramic") return "Ceramic";
|
|
25000
25207
|
return provider.charAt(0).toUpperCase() + provider.slice(1);
|
|
25001
25208
|
}
|
|
25002
25209
|
async function searchWithAllProvider(provider, query, options) {
|
|
@@ -25012,7 +25219,7 @@ async function searchWithProviders(query, options, selectedProviders) {
|
|
|
25012
25219
|
available: provider === "gemini" ? isGeminiApiAvailable() : await isResolvedProviderAvailable(provider, options)
|
|
25013
25220
|
})))).filter((entry) => entry.available).map((entry) => entry.provider);
|
|
25014
25221
|
if (providers.length === 0) {
|
|
25015
|
-
throw new Error('No configured search provider available for provider "all". Parallel MCP, degoog, DuckDuckGo, Kimi, AnySearch, xAI, Mistral, Bright Data, SerpBase, SerpApi, Serper, Serply, You.com, Valyu, Baizhi, Z.ai, XCrawl, and
|
|
25222
|
+
throw new Error('No configured search provider available for provider "all". Parallel MCP, degoog, DuckDuckGo, Kimi, AnySearch, xAI, Mistral, Bright Data, SerpBase, SerpApi, Serper, Serply, You.com, Valyu, Baizhi, Z.ai, XCrawl, Keenable, and Ceramic are excluded.');
|
|
25016
25223
|
}
|
|
25017
25224
|
const settled = await Promise.allSettled(
|
|
25018
25225
|
providers.map((provider) => selectedProviders ? searchWithResolvedProvider(provider, query, options) : searchWithAllProvider(provider, query, options))
|
|
@@ -25025,7 +25232,7 @@ async function searchWithProviders(query, options, selectedProviders) {
|
|
|
25025
25232
|
if (outcome.status === "fulfilled") {
|
|
25026
25233
|
successes.push(outcome.value);
|
|
25027
25234
|
} else {
|
|
25028
|
-
failures.push({ provider: providers[index], error:
|
|
25235
|
+
failures.push({ provider: providers[index], error: errorMessage27(outcome.reason) });
|
|
25029
25236
|
}
|
|
25030
25237
|
}
|
|
25031
25238
|
if (successes.length === 0) {
|
|
@@ -25082,7 +25289,7 @@ async function searchWithConfiguredRouting(query, options, routing) {
|
|
|
25082
25289
|
return await searchWithResolvedProvider(provider, query, options, useCurrentModel);
|
|
25083
25290
|
} catch (err) {
|
|
25084
25291
|
const classified = classifyProviderError(provider, err);
|
|
25085
|
-
diagnostics.push(`${provider} [${classified.kind}]: ${
|
|
25292
|
+
diagnostics.push(`${provider} [${classified.kind}]: ${errorMessage27(err)}`);
|
|
25086
25293
|
if (!routing.fallbackOn.includes(classified.kind)) {
|
|
25087
25294
|
throw classified;
|
|
25088
25295
|
}
|
|
@@ -25111,7 +25318,7 @@ async function search(query, options = {}) {
|
|
|
25111
25318
|
return { ...result, provider: "searxng" };
|
|
25112
25319
|
} catch (err) {
|
|
25113
25320
|
if (isAbortError2(err)) throw err;
|
|
25114
|
-
fallbackErrors.push(`SearXNG: ${
|
|
25321
|
+
fallbackErrors.push(`SearXNG: ${errorMessage27(err)}`);
|
|
25115
25322
|
}
|
|
25116
25323
|
}
|
|
25117
25324
|
let triedOpenAI = false;
|
|
@@ -25126,7 +25333,7 @@ async function search(query, options = {}) {
|
|
|
25126
25333
|
if (result) return { ...result, provider: "exa" };
|
|
25127
25334
|
} catch (err) {
|
|
25128
25335
|
if (err instanceof CredentialResolutionError || isAbortError2(err)) throw err;
|
|
25129
|
-
fallbackErrors.push(`Exa: ${
|
|
25336
|
+
fallbackErrors.push(`Exa: ${errorMessage27(err)}`);
|
|
25130
25337
|
}
|
|
25131
25338
|
}
|
|
25132
25339
|
if (allowed.has("openai") && !triedOpenAI) {
|
|
@@ -25139,7 +25346,7 @@ async function search(query, options = {}) {
|
|
|
25139
25346
|
return { ...result, provider: "brave" };
|
|
25140
25347
|
} catch (err) {
|
|
25141
25348
|
if (isAbortError2(err)) throw err;
|
|
25142
|
-
fallbackErrors.push(`Brave: ${
|
|
25349
|
+
fallbackErrors.push(`Brave: ${errorMessage27(err)}`);
|
|
25143
25350
|
}
|
|
25144
25351
|
}
|
|
25145
25352
|
if (allowed.has("parallel") && isParallelAvailable()) {
|
|
@@ -25148,7 +25355,7 @@ async function search(query, options = {}) {
|
|
|
25148
25355
|
return { ...result, provider: "parallel" };
|
|
25149
25356
|
} catch (err) {
|
|
25150
25357
|
if (isAbortError2(err)) throw err;
|
|
25151
|
-
fallbackErrors.push(`Parallel: ${
|
|
25358
|
+
fallbackErrors.push(`Parallel: ${errorMessage27(err)}`);
|
|
25152
25359
|
}
|
|
25153
25360
|
}
|
|
25154
25361
|
if (allowed.has("tinyfish") && isTinyFishAvailable()) {
|
|
@@ -25157,7 +25364,7 @@ async function search(query, options = {}) {
|
|
|
25157
25364
|
return { ...result, provider: "tinyfish" };
|
|
25158
25365
|
} catch (err) {
|
|
25159
25366
|
if (isAbortError2(err)) throw err;
|
|
25160
|
-
fallbackErrors.push(`TinyFish: ${
|
|
25367
|
+
fallbackErrors.push(`TinyFish: ${errorMessage27(err)}`);
|
|
25161
25368
|
}
|
|
25162
25369
|
}
|
|
25163
25370
|
if (allowed.has("search1api") && isSearch1APIAvailable()) {
|
|
@@ -25166,7 +25373,7 @@ async function search(query, options = {}) {
|
|
|
25166
25373
|
return { ...result, provider: "search1api" };
|
|
25167
25374
|
} catch (err) {
|
|
25168
25375
|
if (isAbortError2(err)) throw err;
|
|
25169
|
-
fallbackErrors.push(`Search1API: ${
|
|
25376
|
+
fallbackErrors.push(`Search1API: ${errorMessage27(err)}`);
|
|
25170
25377
|
}
|
|
25171
25378
|
}
|
|
25172
25379
|
if (allowed.has("searchinfinity") && isSearchinfinityAvailable()) {
|
|
@@ -25175,7 +25382,7 @@ async function search(query, options = {}) {
|
|
|
25175
25382
|
return { ...result, provider: "searchinfinity" };
|
|
25176
25383
|
} catch (err) {
|
|
25177
25384
|
if (isAbortError2(err)) throw err;
|
|
25178
|
-
fallbackErrors.push(`Searchinfinity: ${
|
|
25385
|
+
fallbackErrors.push(`Searchinfinity: ${errorMessage27(err)}`);
|
|
25179
25386
|
}
|
|
25180
25387
|
}
|
|
25181
25388
|
if (allowed.has("querit") && isQueritAvailable()) {
|
|
@@ -25184,7 +25391,7 @@ async function search(query, options = {}) {
|
|
|
25184
25391
|
return { ...result, provider: "querit" };
|
|
25185
25392
|
} catch (err) {
|
|
25186
25393
|
if (isAbortError2(err)) throw err;
|
|
25187
|
-
fallbackErrors.push(`Querit: ${
|
|
25394
|
+
fallbackErrors.push(`Querit: ${errorMessage27(err)}`);
|
|
25188
25395
|
}
|
|
25189
25396
|
}
|
|
25190
25397
|
if (allowed.has("tavily") && isTavilyAvailable()) {
|
|
@@ -25193,7 +25400,7 @@ async function search(query, options = {}) {
|
|
|
25193
25400
|
return { ...result, provider: "tavily" };
|
|
25194
25401
|
} catch (err) {
|
|
25195
25402
|
if (isAbortError2(err)) throw err;
|
|
25196
|
-
fallbackErrors.push(`Tavily: ${
|
|
25403
|
+
fallbackErrors.push(`Tavily: ${errorMessage27(err)}`);
|
|
25197
25404
|
}
|
|
25198
25405
|
}
|
|
25199
25406
|
if (allowed.has("firecrawl") && isFirecrawlAvailable()) {
|
|
@@ -25202,7 +25409,7 @@ async function search(query, options = {}) {
|
|
|
25202
25409
|
return { ...result, provider: "firecrawl" };
|
|
25203
25410
|
} catch (err) {
|
|
25204
25411
|
if (isAbortError2(err)) throw err;
|
|
25205
|
-
fallbackErrors.push(`Firecrawl: ${
|
|
25412
|
+
fallbackErrors.push(`Firecrawl: ${errorMessage27(err)}`);
|
|
25206
25413
|
}
|
|
25207
25414
|
}
|
|
25208
25415
|
if (allowed.has("jina") && isJinaSearchAvailable()) {
|
|
@@ -25211,7 +25418,7 @@ async function search(query, options = {}) {
|
|
|
25211
25418
|
return { ...result, provider: "jina" };
|
|
25212
25419
|
} catch (err) {
|
|
25213
25420
|
if (isAbortError2(err)) throw err;
|
|
25214
|
-
fallbackErrors.push(`Jina: ${
|
|
25421
|
+
fallbackErrors.push(`Jina: ${errorMessage27(err)}`);
|
|
25215
25422
|
}
|
|
25216
25423
|
}
|
|
25217
25424
|
if (allowed.has("serpdive") && isSerpdiveAvailable()) {
|
|
@@ -25220,7 +25427,7 @@ async function search(query, options = {}) {
|
|
|
25220
25427
|
return { ...result, provider: "serpdive" };
|
|
25221
25428
|
} catch (err) {
|
|
25222
25429
|
if (isAbortError2(err)) throw err;
|
|
25223
|
-
fallbackErrors.push(`SERPdive: ${
|
|
25430
|
+
fallbackErrors.push(`SERPdive: ${errorMessage27(err)}`);
|
|
25224
25431
|
}
|
|
25225
25432
|
}
|
|
25226
25433
|
if (allowed.has("kagi") && isKagiAvailable()) {
|
|
@@ -25229,7 +25436,7 @@ async function search(query, options = {}) {
|
|
|
25229
25436
|
return { ...result, provider: "kagi" };
|
|
25230
25437
|
} catch (err) {
|
|
25231
25438
|
if (isAbortError2(err)) throw err;
|
|
25232
|
-
fallbackErrors.push(`Kagi: ${
|
|
25439
|
+
fallbackErrors.push(`Kagi: ${errorMessage27(err)}`);
|
|
25233
25440
|
}
|
|
25234
25441
|
}
|
|
25235
25442
|
if (allowed.has("bocha") && isBochaAvailable()) {
|
|
@@ -25238,7 +25445,7 @@ async function search(query, options = {}) {
|
|
|
25238
25445
|
return { ...result, provider: "bocha" };
|
|
25239
25446
|
} catch (err) {
|
|
25240
25447
|
if (isAbortError2(err)) throw err;
|
|
25241
|
-
fallbackErrors.push(`Bocha: ${
|
|
25448
|
+
fallbackErrors.push(`Bocha: ${errorMessage27(err)}`);
|
|
25242
25449
|
}
|
|
25243
25450
|
}
|
|
25244
25451
|
if (allowed.has("ollama") && isOllamaAvailable()) {
|
|
@@ -25247,7 +25454,7 @@ async function search(query, options = {}) {
|
|
|
25247
25454
|
return { ...result, provider: "ollama" };
|
|
25248
25455
|
} catch (err) {
|
|
25249
25456
|
if (isAbortError2(err)) throw err;
|
|
25250
|
-
fallbackErrors.push(`Ollama: ${
|
|
25457
|
+
fallbackErrors.push(`Ollama: ${errorMessage27(err)}`);
|
|
25251
25458
|
}
|
|
25252
25459
|
}
|
|
25253
25460
|
if (allowed.has("perplexity") && isPerplexityAvailable()) {
|
|
@@ -25256,7 +25463,7 @@ async function search(query, options = {}) {
|
|
|
25256
25463
|
return { ...result, provider: "perplexity" };
|
|
25257
25464
|
} catch (err) {
|
|
25258
25465
|
if (isAbortError2(err)) throw err;
|
|
25259
|
-
fallbackErrors.push(`Perplexity: ${
|
|
25466
|
+
fallbackErrors.push(`Perplexity: ${errorMessage27(err)}`);
|
|
25260
25467
|
}
|
|
25261
25468
|
}
|
|
25262
25469
|
if (allowed.has("gemini")) try {
|
|
@@ -25264,7 +25471,7 @@ async function search(query, options = {}) {
|
|
|
25264
25471
|
if (geminiResult) return { ...geminiResult, provider: "gemini" };
|
|
25265
25472
|
} catch (err) {
|
|
25266
25473
|
if (isAbortError2(err)) throw err;
|
|
25267
|
-
fallbackErrors.push(`Gemini: ${
|
|
25474
|
+
fallbackErrors.push(`Gemini: ${errorMessage27(err)}`);
|
|
25268
25475
|
}
|
|
25269
25476
|
if (fallbackErrors.length > 0) {
|
|
25270
25477
|
throw new Error(`Auto provider search failed:
|
|
@@ -25273,11 +25480,11 @@ async function search(query, options = {}) {
|
|
|
25273
25480
|
throw new Error(
|
|
25274
25481
|
`No search provider available. Either:
|
|
25275
25482
|
1. Use /login to sign in with a Codex subscription for OpenAI web search
|
|
25276
|
-
2. Set openaiApiKey, braveApiKey, parallelApiKey, tinyfishApiKey, search1apiApiKey, searchinfinityApiKey, queritApiKey, tavilyApiKey, firecrawlBaseUrl, jinaApiKey, serpdiveApiKey, kagiApiKey, ollamaApiKey, searxngBaseUrl, perplexityApiKey, exaApiKey, geminiApiKey, bochaApiKey, or cloudflareApiKey in ${
|
|
25483
|
+
2. Set openaiApiKey, braveApiKey, parallelApiKey, tinyfishApiKey, search1apiApiKey, searchinfinityApiKey, queritApiKey, tavilyApiKey, firecrawlBaseUrl, jinaApiKey, serpdiveApiKey, kagiApiKey, ollamaApiKey, searxngBaseUrl, perplexityApiKey, exaApiKey, geminiApiKey, bochaApiKey, or cloudflareApiKey in ${CONFIG_PATH38}
|
|
25277
25484
|
3. Set OPENAI_API_KEY, BRAVE_API_KEY, PARALLEL_API_KEY, TINYFISH_API_KEY, SEARCH1API_KEY, SEARCHINFINITY_API_KEY, QUERIT_API_KEY, TAVILY_API_KEY, FIRECRAWL_BASE_URL, JINA_API_KEY, SERPDIVE_API_KEY, KAGI_API_KEY, BOCHA_API_KEY, OLLAMA_API_KEY, SEARXNG_BASE_URL, EXA_API_KEY, PERPLEXITY_API_KEY, GEMINI_API_KEY, or CLOUDFLARE_API_KEY env vars
|
|
25278
25485
|
4. Set GOOGLE_GEMINI_BASE_URL with CLOUDFLARE_API_KEY for Cloudflare AI Gateway routing
|
|
25279
25486
|
5. Sign into gemini.google.com in a supported Chromium-based browser
|
|
25280
|
-
6. Explicitly select provider: "anysearch" for anonymous AnySearch, "xcrawl" for XCrawl, "xai" for Grok, "mistral" for Mistral Conversations web search, "brightdata" with brightdataSerpZone for paid Bright Data SERP, "serpbase", "serpapi", "serper", or "serply" for Google SERP, "you" for You.com, "zai" for Z.ai GLM Coding Plan search, "valyu" for research search,
|
|
25487
|
+
6. Explicitly select provider: "anysearch" for anonymous AnySearch, "xcrawl" for XCrawl, "xai" for Grok, "mistral" for Mistral Conversations web search, "brightdata" with brightdataSerpZone for paid Bright Data SERP, "serpbase", "serpapi", "serper", or "serply" for Google SERP, "you" for You.com, "zai" for Z.ai GLM Coding Plan search, "valyu" for research search, "keenable" for keyless Keenable search, or "ceramic" for Ceramic search`
|
|
25281
25488
|
);
|
|
25282
25489
|
}
|
|
25283
25490
|
async function searchWithGeminiApi(query, options = {}) {
|
|
@@ -25327,13 +25534,13 @@ async function searchWithGeminiWeb(query, options = {}) {
|
|
|
25327
25534
|
const prompt = buildSearchPrompt2(query, options);
|
|
25328
25535
|
const activityId = activityMonitor.logStart({ type: "api", query });
|
|
25329
25536
|
try {
|
|
25330
|
-
const
|
|
25537
|
+
const text4 = await queryWithCookies(prompt, cookies, {
|
|
25331
25538
|
signal: options.signal,
|
|
25332
25539
|
timeoutMs: 12e4
|
|
25333
25540
|
});
|
|
25334
25541
|
activityMonitor.logComplete(activityId, 200);
|
|
25335
|
-
const results = extractSourceUrls(
|
|
25336
|
-
return { answer:
|
|
25542
|
+
const results = extractSourceUrls(text4);
|
|
25543
|
+
return { answer: text4, results };
|
|
25337
25544
|
} catch (err) {
|
|
25338
25545
|
const message = err instanceof Error ? err.message : String(err);
|
|
25339
25546
|
if (message.toLowerCase().includes("abort")) {
|
|
@@ -25514,8 +25721,8 @@ var TOOL_RUNNERS = {
|
|
|
25514
25721
|
get_search_content: (core2, args, signal) => core2.getSearchContent(args, signal),
|
|
25515
25722
|
source_check: (core2, args, signal) => core2.sourceCheck(args, signal)
|
|
25516
25723
|
};
|
|
25517
|
-
function errorResult(
|
|
25518
|
-
return { content: [{ type: "text", text:
|
|
25724
|
+
function errorResult(text4) {
|
|
25725
|
+
return { content: [{ type: "text", text: text4 }], isError: true };
|
|
25519
25726
|
}
|
|
25520
25727
|
function toCallToolResult(result) {
|
|
25521
25728
|
return { content: result.content, ...result.isError && { isError: true } };
|
|
@@ -25550,7 +25757,7 @@ function createMcpServer(core2, info, enabledTools) {
|
|
|
25550
25757
|
}
|
|
25551
25758
|
|
|
25552
25759
|
// web-tool-core.ts
|
|
25553
|
-
import { existsSync as
|
|
25760
|
+
import { existsSync as existsSync52, readFileSync as readFileSync54 } from "node:fs";
|
|
25554
25761
|
import pLimit2 from "p-limit";
|
|
25555
25762
|
|
|
25556
25763
|
// fetch-params.ts
|
|
@@ -25654,8 +25861,8 @@ function editDistanceWithin(left, right, maximum) {
|
|
|
25654
25861
|
}
|
|
25655
25862
|
return previous[right.length] <= maximum;
|
|
25656
25863
|
}
|
|
25657
|
-
function literalMatches(
|
|
25658
|
-
const haystack = caseInsensitive ?
|
|
25864
|
+
function literalMatches(text4, query, caseInsensitive) {
|
|
25865
|
+
const haystack = caseInsensitive ? text4.toLocaleLowerCase() : text4;
|
|
25659
25866
|
const needle = caseInsensitive ? query.toLocaleLowerCase() : query;
|
|
25660
25867
|
const matches = [];
|
|
25661
25868
|
for (let start = haystack.indexOf(needle); start >= 0; start = haystack.indexOf(needle, start + Math.max(needle.length, 1))) {
|
|
@@ -25663,12 +25870,12 @@ function literalMatches(text3, query, caseInsensitive) {
|
|
|
25663
25870
|
}
|
|
25664
25871
|
return matches;
|
|
25665
25872
|
}
|
|
25666
|
-
function fuzzyMatches(
|
|
25873
|
+
function fuzzyMatches(text4, query) {
|
|
25667
25874
|
const queryTokens = normalize2(query).match(/[\p{L}\p{N}]+/gu) ?? [];
|
|
25668
25875
|
if (queryTokens.length === 0) return [];
|
|
25669
25876
|
const matches = [];
|
|
25670
25877
|
const paragraphs = /[^\n]+(?:\n(?!\n)[^\n]+)*/g;
|
|
25671
|
-
for (const paragraph of
|
|
25878
|
+
for (const paragraph of text4.matchAll(paragraphs)) {
|
|
25672
25879
|
const paragraphText = paragraph[0];
|
|
25673
25880
|
if (paragraphText.trim().length === 0 || paragraph.index === void 0) continue;
|
|
25674
25881
|
const tokens = [...paragraphText.matchAll(/[\p{L}\p{N}]+/gu)];
|
|
@@ -25727,10 +25934,10 @@ function upperBound(values, target) {
|
|
|
25727
25934
|
}
|
|
25728
25935
|
return low;
|
|
25729
25936
|
}
|
|
25730
|
-
function findContent(
|
|
25937
|
+
function findContent(text4, queries, mode) {
|
|
25731
25938
|
const normalizedQueries = [...new Set(queries.map((query) => query.trim()).filter(Boolean))];
|
|
25732
25939
|
const occurrences = normalizedQueries.map((query) => {
|
|
25733
|
-
const matches2 = mode === "fuzzy" ? fuzzyMatches(
|
|
25940
|
+
const matches2 = mode === "fuzzy" ? fuzzyMatches(text4, query) : literalMatches(text4, query, mode === "case-insensitive");
|
|
25734
25941
|
return { query, matches: matches2, starts: matches2.map((match) => match.start), ends: matches2.map((match) => match.end) };
|
|
25735
25942
|
});
|
|
25736
25943
|
const matches = occurrences.flatMap((result) => result.matches);
|
|
@@ -25742,7 +25949,7 @@ function findContent(text3, queries, mode) {
|
|
|
25742
25949
|
id: `Q${index + 1}`,
|
|
25743
25950
|
order: index
|
|
25744
25951
|
}));
|
|
25745
|
-
const whitespaceRuns = [...
|
|
25952
|
+
const whitespaceRuns = [...text4.matchAll(/\s+/g)].map((run) => ({ start: run.index, end: run.index + run[0].length }));
|
|
25746
25953
|
const whitespaceStarts = whitespaceRuns.map((run) => run.start);
|
|
25747
25954
|
const whitespaceEnds = whitespaceRuns.map((run) => run.end);
|
|
25748
25955
|
const whitespaceSavings = [0];
|
|
@@ -25775,7 +25982,7 @@ function findContent(text3, queries, mode) {
|
|
|
25775
25982
|
const counts = rangeCounts(range);
|
|
25776
25983
|
if (counts.length === 0) continue;
|
|
25777
25984
|
const labelsLength = counts.reduce((total, result) => total + (overflow ? result.id.length : result.query.length + 2) + 2 + String(result.count).length, 2 * (counts.length - 1));
|
|
25778
|
-
const snippetLength = normalizedLength(range.start, range.end) + (range.start > 0 ? 1 : 0) + (range.end <
|
|
25985
|
+
const snippetLength = normalizedLength(range.start, range.end) + (range.start > 0 ? 1 : 0) + (range.end < text4.length ? 1 : 0);
|
|
25779
25986
|
length += 2 + String(index + 1).length + 2 + labelsLength + 1 + snippetLength;
|
|
25780
25987
|
returnedMatches += counts.reduce((total, result) => total + result.count, 0);
|
|
25781
25988
|
}
|
|
@@ -25792,8 +25999,8 @@ function findContent(text3, queries, mode) {
|
|
|
25792
25999
|
const contained = rangeCounts(range);
|
|
25793
26000
|
if (contained.length === 0) continue;
|
|
25794
26001
|
const prefix = range.start > 0 ? "\u2026" : "";
|
|
25795
|
-
const suffix = range.end <
|
|
25796
|
-
const snippet = `${prefix}${
|
|
26002
|
+
const suffix = range.end < text4.length ? "\u2026" : "";
|
|
26003
|
+
const snippet = `${prefix}${text4.slice(range.start, range.end).replace(/\s+/g, " ").trim()}${suffix}`;
|
|
25797
26004
|
const counts = contained.map((result) => `${overflow ? result.id : `"${result.query}"`} \xD7${result.count}`).join(", ");
|
|
25798
26005
|
sections.push(`${index + 1}. ${counts}
|
|
25799
26006
|
${snippet}`);
|
|
@@ -25804,18 +26011,18 @@ ${snippet}`);
|
|
|
25804
26011
|
if (returnedMatches < matches.length) sections.push(`Showing ${returnedMatches} of ${matches.length} matches.`);
|
|
25805
26012
|
return { text: sections.join("\n\n"), matchCount: matches.length, returnedMatches, queryResults };
|
|
25806
26013
|
}
|
|
25807
|
-
const fullRanges = contextRanges(
|
|
26014
|
+
const fullRanges = contextRanges(text4.length, matches);
|
|
25808
26015
|
const full = measure(fullRanges);
|
|
25809
26016
|
if (full.returnedMatches === matches.length && full.length <= MAX_OUTPUT_CHARS) return formatRanges(fullRanges);
|
|
25810
26017
|
let ranges = [];
|
|
25811
26018
|
let omitted = matchingQueries.map((result) => result.id);
|
|
25812
26019
|
if (measure(ranges, true, omitted).length > MAX_OUTPUT_CHARS) {
|
|
25813
|
-
const
|
|
26020
|
+
const text5 = `${heading}
|
|
25814
26021
|
|
|
25815
26022
|
Unable to format bounded excerpts: query metadata exceeds ${MAX_OUTPUT_CHARS} characters.
|
|
25816
26023
|
|
|
25817
26024
|
Showing 0 of ${matches.length} matches.`;
|
|
25818
|
-
return { text:
|
|
26025
|
+
return { text: text5, matchCount: matches.length, returnedMatches: 0, queryResults };
|
|
25819
26026
|
}
|
|
25820
26027
|
const witnesses = [];
|
|
25821
26028
|
for (const { id, matches: queryMatches } of matchingQueries) {
|
|
@@ -25841,7 +26048,7 @@ Showing 0 of ${matches.length} matches.`;
|
|
|
25841
26048
|
for (const witness of witnesses) {
|
|
25842
26049
|
const proposed = mergeRanges([...ranges, {
|
|
25843
26050
|
start: Math.max(0, witness.start - CONTEXT_CHARS),
|
|
25844
|
-
end: Math.min(
|
|
26051
|
+
end: Math.min(text4.length, witness.end + CONTEXT_CHARS)
|
|
25845
26052
|
}]);
|
|
25846
26053
|
if (measure(proposed, true, omitted).length <= MAX_OUTPUT_CHARS) ranges = proposed;
|
|
25847
26054
|
}
|
|
@@ -25854,7 +26061,7 @@ Showing 0 of ${matches.length} matches.`;
|
|
|
25854
26061
|
init_utils();
|
|
25855
26062
|
|
|
25856
26063
|
// storage.ts
|
|
25857
|
-
import { closeSync, constants, fchmodSync, fstatSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync as
|
|
26064
|
+
import { closeSync, constants, fchmodSync, fstatSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync as readFileSync43, readdirSync as readdirSync2, renameSync, unlinkSync, writeFileSync } from "node:fs";
|
|
25858
26065
|
init_utils();
|
|
25859
26066
|
import { join as join4 } from "node:path";
|
|
25860
26067
|
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
@@ -25866,6 +26073,7 @@ var DEFAULT_CACHE_LIMITS = { maxEntries: 128, maxBytes: 128 * 1024 * 1024 };
|
|
|
25866
26073
|
var O_DIRECTORY = process.platform === "win32" ? 0 : constants.O_DIRECTORY ?? 0;
|
|
25867
26074
|
var O_NOFOLLOW = process.platform === "win32" ? 0 : constants.O_NOFOLLOW ?? 0;
|
|
25868
26075
|
var storedResults = /* @__PURE__ */ new Map();
|
|
26076
|
+
var resultHolders = /* @__PURE__ */ new Map();
|
|
25869
26077
|
function generateId() {
|
|
25870
26078
|
return Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
|
|
25871
26079
|
}
|
|
@@ -26014,7 +26222,7 @@ function readCachedFetchData(data) {
|
|
|
26014
26222
|
const opened = openRegularFile(path);
|
|
26015
26223
|
fd = opened.fd;
|
|
26016
26224
|
enforceMode(fd, 384);
|
|
26017
|
-
const parsed = JSON.parse(
|
|
26225
|
+
const parsed = JSON.parse(readFileSync43(fd, "utf8"));
|
|
26018
26226
|
if (!isValidStoredData(parsed) || parsed.type !== "fetch" || parsed.id !== data.id || !isInlineFetchData(parsed)) {
|
|
26019
26227
|
return unavailableFetchData(data, "Cached fetched content is invalid");
|
|
26020
26228
|
}
|
|
@@ -26057,6 +26265,7 @@ function deleteResult(id) {
|
|
|
26057
26265
|
} catch {
|
|
26058
26266
|
}
|
|
26059
26267
|
}
|
|
26268
|
+
resultHolders.delete(id);
|
|
26060
26269
|
return storedResults.delete(id);
|
|
26061
26270
|
}
|
|
26062
26271
|
function isValidStoredData(data) {
|
|
@@ -26105,8 +26314,8 @@ function classifySource(url) {
|
|
|
26105
26314
|
if (BLOG_HOSTS.test(host) || BLOG_PATHS.test(path)) return "blog";
|
|
26106
26315
|
return "unknown";
|
|
26107
26316
|
}
|
|
26108
|
-
function hashContent(
|
|
26109
|
-
return `sha256:${createHash("sha256").update(
|
|
26317
|
+
function hashContent(text4) {
|
|
26318
|
+
return `sha256:${createHash("sha256").update(text4, "utf8").digest("hex")}`;
|
|
26110
26319
|
}
|
|
26111
26320
|
function tokenize(value) {
|
|
26112
26321
|
return [...new Set(value.toLowerCase().split(/[^a-z0-9]+/).filter((term) => term.length > 3))];
|
|
@@ -26116,10 +26325,10 @@ function extractRelevantSpans(content, hint) {
|
|
|
26116
26325
|
const sentencePattern = /[^.!?]+(?:[.!?]+(?=\s|$)|$)/g;
|
|
26117
26326
|
for (const match of content.matchAll(sentencePattern)) {
|
|
26118
26327
|
const raw = match[0];
|
|
26119
|
-
const
|
|
26120
|
-
if (
|
|
26121
|
-
const start = (match.index ?? 0) + raw.indexOf(
|
|
26122
|
-
sentences.push({ text:
|
|
26328
|
+
const text4 = raw.trim();
|
|
26329
|
+
if (text4.length > 0 && text4.length <= 400) {
|
|
26330
|
+
const start = (match.index ?? 0) + raw.indexOf(text4);
|
|
26331
|
+
sentences.push({ text: text4, start, end: start + text4.length });
|
|
26123
26332
|
}
|
|
26124
26333
|
}
|
|
26125
26334
|
const terms = tokenize(hint);
|
|
@@ -26242,9 +26451,9 @@ function parseConfigRoot(raw) {
|
|
|
26242
26451
|
}
|
|
26243
26452
|
return parsed;
|
|
26244
26453
|
}
|
|
26245
|
-
function
|
|
26246
|
-
if (!
|
|
26247
|
-
return parseConfigRoot(
|
|
26454
|
+
function loadConfig40() {
|
|
26455
|
+
if (!existsSync52(WEB_SEARCH_CONFIG_PATH4)) return {};
|
|
26456
|
+
return parseConfigRoot(readFileSync54(WEB_SEARCH_CONFIG_PATH4, "utf-8"));
|
|
26248
26457
|
}
|
|
26249
26458
|
var DEFAULT_TOOL_NAMES = {
|
|
26250
26459
|
webSearch: "web_search",
|
|
@@ -26295,7 +26504,7 @@ function resolveRequestedProvider(requested) {
|
|
|
26295
26504
|
assertSearchProviderSelectionAllowed(normalizedRequested, "Requested provider");
|
|
26296
26505
|
return normalizedRequested;
|
|
26297
26506
|
}
|
|
26298
|
-
const config =
|
|
26507
|
+
const config = loadConfig40();
|
|
26299
26508
|
const provider = normalizeProviderInput(config.searchProvider ?? config.provider, `provider in ${WEB_SEARCH_CONFIG_PATH4}`) ?? "auto";
|
|
26300
26509
|
assertSearchProviderSelectionAllowed(provider, `configured provider in ${WEB_SEARCH_CONFIG_PATH4}`);
|
|
26301
26510
|
return provider;
|
|
@@ -26358,7 +26567,7 @@ function isAbortError6(err) {
|
|
|
26358
26567
|
var DEFAULT_MAX_INLINE_CONTENT_CHARS = 3e4;
|
|
26359
26568
|
var MIN_INLINE_CONTENT_CHARS = 1e3;
|
|
26360
26569
|
var MAX_INLINE_CONTENT_CHARS = 2e5;
|
|
26361
|
-
function getMaxInlineContentChars(config =
|
|
26570
|
+
function getMaxInlineContentChars(config = loadConfig40()) {
|
|
26362
26571
|
const value = config.maxInlineContentChars;
|
|
26363
26572
|
if (typeof value !== "number" || !Number.isFinite(value) || !Number.isInteger(value) || value < MIN_INLINE_CONTENT_CHARS) {
|
|
26364
26573
|
return DEFAULT_MAX_INLINE_CONTENT_CHARS;
|
|
@@ -26394,14 +26603,14 @@ function initialContentSlice(content, maxChars) {
|
|
|
26394
26603
|
const lineBreak = content.lastIndexOf("\n", endOffset);
|
|
26395
26604
|
if (lineBreak >= Math.floor(maxChars * 0.8)) endOffset = lineBreak + 1;
|
|
26396
26605
|
}
|
|
26397
|
-
const
|
|
26606
|
+
const text4 = content.slice(0, endOffset);
|
|
26398
26607
|
return {
|
|
26399
|
-
text:
|
|
26608
|
+
text: text4,
|
|
26400
26609
|
endOffset,
|
|
26401
26610
|
totalBytes: Buffer.byteLength(content),
|
|
26402
26611
|
totalLines: content.length === 0 ? 0 : content.split("\n").length,
|
|
26403
|
-
shownBytes: Buffer.byteLength(
|
|
26404
|
-
shownLines:
|
|
26612
|
+
shownBytes: Buffer.byteLength(text4),
|
|
26613
|
+
shownLines: text4.length === 0 ? 0 : text4.split("\n").length
|
|
26405
26614
|
};
|
|
26406
26615
|
}
|
|
26407
26616
|
function normalizeFindQueries(value) {
|
|
@@ -26520,23 +26729,23 @@ ${r.snippet}` : ""}
|
|
|
26520
26729
|
}
|
|
26521
26730
|
return output;
|
|
26522
26731
|
}
|
|
26523
|
-
function boundSearchPresentation(
|
|
26524
|
-
const fullText = `${
|
|
26732
|
+
function boundSearchPresentation(text4, guidance, truncationGuidance, maxChars) {
|
|
26733
|
+
const fullText = `${text4}${guidance}`;
|
|
26525
26734
|
if (fullText.length <= maxChars) {
|
|
26526
|
-
return { text: fullText, truncated: false, originalChars:
|
|
26735
|
+
return { text: fullText, truncated: false, originalChars: text4.length, returnedChars: text4.length, omittedChars: 0 };
|
|
26527
26736
|
}
|
|
26528
26737
|
const marker = `
|
|
26529
26738
|
|
|
26530
26739
|
---
|
|
26531
26740
|
[Output truncated.]${truncationGuidance}`;
|
|
26532
26741
|
const prefixLength = maxChars - marker.length;
|
|
26533
|
-
const bounded = `${
|
|
26742
|
+
const bounded = `${text4.slice(0, prefixLength)}${marker}`;
|
|
26534
26743
|
return {
|
|
26535
26744
|
text: bounded,
|
|
26536
26745
|
truncated: true,
|
|
26537
|
-
originalChars:
|
|
26746
|
+
originalChars: text4.length,
|
|
26538
26747
|
returnedChars: prefixLength,
|
|
26539
|
-
omittedChars:
|
|
26748
|
+
omittedChars: text4.length - prefixLength
|
|
26540
26749
|
};
|
|
26541
26750
|
}
|
|
26542
26751
|
function registeredFetchToolNames(settings2) {
|
|
@@ -27064,9 +27273,9 @@ Use ${toolNames.getSearchContent}({ responseId: "${responseId}", urlIndex: 0 })
|
|
|
27064
27273
|
if (params.findText !== void 0) {
|
|
27065
27274
|
try {
|
|
27066
27275
|
const found = findContent(serialized, normalizeFindQueries(params.findText), params.findMode ?? "case-insensitive");
|
|
27067
|
-
const { text:
|
|
27276
|
+
const { text: text5, ...findDetails } = found;
|
|
27068
27277
|
return {
|
|
27069
|
-
content: [{ type: "text", text:
|
|
27278
|
+
content: [{ type: "text", text: text5 }],
|
|
27070
27279
|
details: { responseId: artifact.id, type: "research", contentLength: serialized.length, findMode: params.findMode ?? "case-insensitive", ...findDetails }
|
|
27071
27280
|
};
|
|
27072
27281
|
} catch (err) {
|
|
@@ -27097,13 +27306,13 @@ Use ${toolNames.getSearchContent}({ responseId: "${responseId}", urlIndex: 0 })
|
|
|
27097
27306
|
details: { error: "Offset out of range", offset, contentLength: serialized.length }
|
|
27098
27307
|
};
|
|
27099
27308
|
}
|
|
27100
|
-
const { endOffset, text:
|
|
27309
|
+
const { endOffset, text: text4 } = sliceWithContinuation(serialized, offset, limit, maxInlineContentChars, (end) => `
|
|
27101
27310
|
|
|
27102
27311
|
---
|
|
27103
27312
|
Showing chars ${offset}-${end} of ${serialized.length}. Use ${toolNames.getSearchContent}({ responseId: "${artifact.id}", offset: ${end}, limit: ${limit} }) for the next slice.`);
|
|
27104
27313
|
const hasMore = endOffset < serialized.length;
|
|
27105
27314
|
return {
|
|
27106
|
-
content: [{ type: "text", text:
|
|
27315
|
+
content: [{ type: "text", text: text4 }],
|
|
27107
27316
|
details: { responseId: artifact.id, type: "research", contentLength: serialized.length, offset, limit, returnedChars: endOffset - offset, nextOffset: hasMore ? endOffset : null, truncated: hasMore }
|
|
27108
27317
|
};
|
|
27109
27318
|
}
|
|
@@ -27144,9 +27353,9 @@ Showing chars ${offset}-${end} of ${serialized.length}. Use ${toolNames.getSearc
|
|
|
27144
27353
|
if (params.findText !== void 0) {
|
|
27145
27354
|
try {
|
|
27146
27355
|
const found = findContent(fullResults, normalizeFindQueries(params.findText), params.findMode ?? "case-insensitive");
|
|
27147
|
-
const { text:
|
|
27356
|
+
const { text: text5, ...findDetails } = found;
|
|
27148
27357
|
return {
|
|
27149
|
-
content: [{ type: "text", text:
|
|
27358
|
+
content: [{ type: "text", text: text5 }],
|
|
27150
27359
|
details: { responseId: params.responseId, query: queryData.query, resultCount: queryData.results.length, contentLength: fullResults.length, findMode: params.findMode ?? "case-insensitive", ...findDetails }
|
|
27151
27360
|
};
|
|
27152
27361
|
} catch (err) {
|
|
@@ -27178,14 +27387,14 @@ Showing chars ${offset}-${end} of ${serialized.length}. Use ${toolNames.getSearc
|
|
|
27178
27387
|
};
|
|
27179
27388
|
}
|
|
27180
27389
|
const queryIndex = data.queries.indexOf(queryData);
|
|
27181
|
-
const { endOffset, text:
|
|
27390
|
+
const { endOffset, text: text4 } = sliceWithContinuation(fullResults, offset, limit, maxInlineContentChars, (end) => `
|
|
27182
27391
|
|
|
27183
27392
|
---
|
|
27184
27393
|
Showing chars ${offset}-${end} of ${fullResults.length}. Use ${toolNames.getSearchContent}({ responseId: "${params.responseId}", queryIndex: ${queryIndex}, offset: ${end}, limit: ${limit} }) for the next slice.`);
|
|
27185
27394
|
const returnedChars = endOffset - offset;
|
|
27186
27395
|
const hasMore = endOffset < fullResults.length;
|
|
27187
27396
|
return {
|
|
27188
|
-
content: [{ type: "text", text:
|
|
27397
|
+
content: [{ type: "text", text: text4 }],
|
|
27189
27398
|
details: {
|
|
27190
27399
|
responseId: params.responseId,
|
|
27191
27400
|
query: queryData.query,
|
|
@@ -27246,11 +27455,11 @@ Use one of the available indexes.` }],
|
|
|
27246
27455
|
if (params.findText !== void 0) {
|
|
27247
27456
|
try {
|
|
27248
27457
|
const found = findContent(urlData.content, normalizeFindQueries(params.findText), params.findMode ?? "case-insensitive");
|
|
27249
|
-
const { text:
|
|
27458
|
+
const { text: text5, ...findDetails } = found;
|
|
27250
27459
|
return {
|
|
27251
27460
|
content: [{ type: "text", text: `# ${urlData.title || urlData.url}
|
|
27252
27461
|
|
|
27253
|
-
${
|
|
27462
|
+
${text5}` }],
|
|
27254
27463
|
details: { url: urlData.url, title: urlData.title, contentLength: urlData.content.length, findMode: params.findMode ?? "case-insensitive", ...findDetails }
|
|
27255
27464
|
};
|
|
27256
27465
|
} catch (err) {
|
|
@@ -27284,20 +27493,20 @@ ${text4}` }],
|
|
|
27284
27493
|
const endOffset = Math.min(offset + limit, urlData.content.length);
|
|
27285
27494
|
const contentSlice = urlData.content.slice(offset, endOffset);
|
|
27286
27495
|
const hasMore = endOffset < urlData.content.length;
|
|
27287
|
-
let
|
|
27496
|
+
let text4 = `# ${urlData.title || urlData.url}
|
|
27288
27497
|
|
|
27289
27498
|
${contentSlice}`;
|
|
27290
27499
|
if (hasMore || offset > 0) {
|
|
27291
|
-
|
|
27500
|
+
text4 += `
|
|
27292
27501
|
|
|
27293
27502
|
---
|
|
27294
27503
|
Showing chars ${offset}-${endOffset} of ${urlData.content.length}.`;
|
|
27295
27504
|
if (hasMore) {
|
|
27296
|
-
|
|
27505
|
+
text4 += ` Use ${toolNames.getSearchContent}({ responseId: "${params.responseId}", urlIndex: ${selectedUrlIndex}, offset: ${endOffset}, limit: ${limit} }) for the next slice.`;
|
|
27297
27506
|
}
|
|
27298
27507
|
}
|
|
27299
27508
|
return {
|
|
27300
|
-
content: [{ type: "text", text:
|
|
27509
|
+
content: [{ type: "text", text: text4 }],
|
|
27301
27510
|
details: {
|
|
27302
27511
|
url: urlData.url,
|
|
27303
27512
|
title: urlData.title,
|
|
@@ -27367,7 +27576,7 @@ function standaloneFetchRejection(params, fetchModes) {
|
|
|
27367
27576
|
return void 0;
|
|
27368
27577
|
}
|
|
27369
27578
|
function createStandaloneWebToolCore() {
|
|
27370
|
-
const config =
|
|
27579
|
+
const config = loadConfig40();
|
|
27371
27580
|
const settings2 = {
|
|
27372
27581
|
toolNames: { ...DEFAULT_TOOL_NAMES },
|
|
27373
27582
|
enabledTools: {
|