@herbertgao/pi-extensions 2026.10.0 → 2026.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -12
- package/THIRD_PARTY_NOTICES.md +3 -3
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-audit.md +2 -2
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-debt.md +2 -2
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-gain.md +1 -1
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-help.md +1 -1
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-review.md +2 -2
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail.md +1 -1
- package/node_modules/@dietrichgebert/ponytail/.opencode/plugins/index.js +4 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/plugins/ponytail-frontmatter.cjs +43 -3
- package/node_modules/@dietrichgebert/ponytail/.opencode/plugins/ponytail.mjs +142 -59
- package/node_modules/@dietrichgebert/ponytail/.qoder/rules/ponytail.md +21 -21
- package/node_modules/@dietrichgebert/ponytail/.qoder-plugin/plugin.json +1 -1
- package/node_modules/@dietrichgebert/ponytail/AGENTS.md +21 -21
- package/node_modules/@dietrichgebert/ponytail/README.md +52 -242
- package/node_modules/@dietrichgebert/ponytail/hooks/claude-codex-hooks.json +3 -3
- package/node_modules/@dietrichgebert/ponytail/hooks/copilot-hooks.json +4 -4
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-activate.js +70 -16
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-config.js +8 -7
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-instructions.js +30 -30
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-map.js +103 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-mode-tracker.js +46 -23
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-runtime.js +39 -7
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-subagent.js +20 -3
- package/node_modules/@dietrichgebert/ponytail/hooks/qoder-hooks.json +3 -3
- package/node_modules/@dietrichgebert/ponytail/package.json +3 -3
- package/node_modules/@dietrichgebert/ponytail/pi-extension/index.js +47 -17
- package/node_modules/@dietrichgebert/ponytail/scripts/uninstall.js +21 -7
- package/node_modules/@dietrichgebert/ponytail/skills/plugin.json +5 -0
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail/SKILL.md +33 -101
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-audit/SKILL.md +89 -27
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-debt/SKILL.md +13 -12
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-gain/SKILL.md +21 -18
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-help/SKILL.md +12 -13
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-review/SKILL.md +96 -52
- package/node_modules/@herbertgao/pi-agency/LICENSE +21 -0
- package/node_modules/@herbertgao/pi-agency/README.md +40 -0
- package/node_modules/@herbertgao/pi-agency/package.json +53 -0
- package/node_modules/@herbertgao/pi-agency/src/index.ts +441 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +12 -12
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +30 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +15 -9
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +27 -9
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/codemode.ts +4 -1
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +2 -2
- package/node_modules/@narumitw/pi-caffeinate/package.json +4 -4
- package/node_modules/@tifan/pi-mermaid-open/package.json +5 -1
- package/node_modules/@tifan/pi-mermaid-open/src/index.ts +26 -9
- package/node_modules/@tifan/pi-recap/package.json +1 -1
- package/node_modules/@tifan/pi-recap/src/index.ts +104 -20
- package/node_modules/@tifan/pi-recap/src/models.ts +46 -4
- package/node_modules/pi-antigravity/README.md +23 -2
- package/node_modules/pi-antigravity/package.json +5 -3
- package/node_modules/pi-antigravity/src/diagnostics/diagnostics.ts +3 -2
- package/node_modules/pi-antigravity/src/features/generate-image.ts +72 -0
- package/node_modules/pi-antigravity/src/features/google-search.ts +71 -0
- package/node_modules/pi-antigravity/src/image/image.ts +86 -47
- package/node_modules/pi-antigravity/src/image/native.ts +69 -0
- package/node_modules/pi-antigravity/src/index.ts +52 -137
- package/node_modules/pi-antigravity/src/search/search.ts +130 -31
- package/node_modules/pi-antigravity/src/stream/stream.ts +162 -113
- package/node_modules/pi-antigravity/src/types/enums.ts +1 -0
- package/node_modules/pi-antigravity/src/types/types.ts +1 -1
- package/node_modules/pi-antigravity/src/utils/security.ts +47 -1
- package/node_modules/pi-antigravity/src/utils/util.ts +38 -6
- package/node_modules/pi-lens/CHANGELOG.md +1064 -0
- package/node_modules/pi-lens/README.md +115 -25
- package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +6 -2
- package/node_modules/pi-lens/dist/chunk-22AVIGXS.js +560 -0
- package/node_modules/pi-lens/dist/chunk-27BBHSZC.js +106 -0
- package/node_modules/pi-lens/dist/chunk-2BEMIWEW.js +51 -0
- package/node_modules/pi-lens/dist/chunk-2EECBNC5.js +89 -0
- package/node_modules/pi-lens/dist/chunk-34U7PLGE.js +23 -0
- package/node_modules/pi-lens/dist/chunk-3I5QFT3N.js +181 -0
- package/node_modules/pi-lens/dist/chunk-3MED75HT.js +37 -0
- package/node_modules/pi-lens/dist/chunk-47D2BO4S.js +87 -0
- package/node_modules/pi-lens/dist/chunk-4RERDEXR.js +348 -0
- package/node_modules/pi-lens/dist/chunk-4W2PLC4J.js +27 -0
- package/node_modules/pi-lens/dist/chunk-52H5B5TC.js +202 -0
- package/node_modules/pi-lens/dist/chunk-54B42YRX.js +27 -0
- package/node_modules/pi-lens/dist/chunk-5RXBNSW2.js +266 -0
- package/node_modules/pi-lens/dist/chunk-5THXD6X5.js +201 -0
- package/node_modules/pi-lens/dist/chunk-5W3R6LFT.js +24 -0
- package/node_modules/pi-lens/dist/chunk-5ZEJHV35.js +341 -0
- package/node_modules/pi-lens/dist/chunk-6P62QVEA.js +118 -0
- package/node_modules/pi-lens/dist/chunk-6QIUX4EP.js +459 -0
- package/node_modules/pi-lens/dist/chunk-6VCD4VKZ.js +78 -0
- package/node_modules/pi-lens/dist/chunk-7F72PXY2.js +326 -0
- package/node_modules/pi-lens/dist/chunk-7FBF7NPR.js +998 -0
- package/node_modules/pi-lens/dist/chunk-7U2IDNXN.js +37 -0
- package/node_modules/pi-lens/dist/chunk-ABBOA7UD.js +157 -0
- package/node_modules/pi-lens/dist/chunk-AHDW3GPE.js +50 -0
- package/node_modules/pi-lens/dist/chunk-AJ3QXTRQ.js +756 -0
- package/node_modules/pi-lens/dist/chunk-AJVLWNFN.js +1610 -0
- package/node_modules/pi-lens/dist/chunk-AJXODZY6.js +112 -0
- package/node_modules/pi-lens/dist/chunk-ARFCXG7S.js +84 -0
- package/node_modules/pi-lens/dist/chunk-AS44CFQ4.js +708 -0
- package/node_modules/pi-lens/dist/chunk-AWE5TMPO.js +38 -0
- package/node_modules/pi-lens/dist/chunk-B3I2UUT4.js +4692 -0
- package/node_modules/pi-lens/dist/chunk-BRJKOBZP.js +331 -0
- package/node_modules/pi-lens/dist/chunk-BW5KFIQC.js +59 -0
- package/node_modules/pi-lens/dist/chunk-C2AUYXQH.js +149 -0
- package/node_modules/pi-lens/dist/chunk-CGGAIP7J.js +29 -0
- package/node_modules/pi-lens/dist/chunk-D6QS3U6M.js +30 -0
- package/node_modules/pi-lens/dist/chunk-DFVMIKMQ.js +349 -0
- package/node_modules/pi-lens/dist/chunk-DIULIWKU.js +169 -0
- package/node_modules/pi-lens/dist/chunk-DQ2NZ7C4.js +2317 -0
- package/node_modules/pi-lens/dist/chunk-E2WFBRHM.js +213 -0
- package/node_modules/pi-lens/dist/chunk-E4MAEDPM.js +50 -0
- package/node_modules/pi-lens/dist/chunk-EOKRQ3SA.js +30 -0
- package/node_modules/pi-lens/dist/chunk-F3AU2TMM.js +2626 -0
- package/node_modules/pi-lens/dist/chunk-F3P7VQ7H.js +170 -0
- package/node_modules/pi-lens/dist/chunk-FC4RP4I2.js +12 -0
- package/node_modules/pi-lens/dist/chunk-FJNKANOS.js +32 -0
- package/node_modules/pi-lens/dist/chunk-GUOGVTCQ.js +146 -0
- package/node_modules/pi-lens/dist/chunk-GVXA6CCE.js +18 -0
- package/node_modules/pi-lens/dist/chunk-HHYAELLJ.js +2334 -0
- package/node_modules/pi-lens/dist/chunk-HMFXILPV.js +83 -0
- package/node_modules/pi-lens/dist/chunk-HVUZXSWK.js +421 -0
- package/node_modules/pi-lens/dist/chunk-HWBZIGMJ.js +62 -0
- package/node_modules/pi-lens/dist/chunk-I3R7GKDR.js +17 -0
- package/node_modules/pi-lens/dist/chunk-I7SPGOWI.js +55 -0
- package/node_modules/pi-lens/dist/chunk-IIXOAGHR.js +38 -0
- package/node_modules/pi-lens/dist/chunk-IVP5KAB7.js +2250 -0
- package/node_modules/pi-lens/dist/chunk-IXEBJSUE.js +22 -0
- package/node_modules/pi-lens/dist/chunk-JOLITGCC.js +27 -0
- package/node_modules/pi-lens/dist/chunk-K6VYLB2U.js +145 -0
- package/node_modules/pi-lens/dist/chunk-LJDODBBZ.js +78 -0
- package/node_modules/pi-lens/dist/chunk-LNAKEO63.js +78 -0
- package/node_modules/pi-lens/dist/chunk-LSMJ6KBE.js +4139 -0
- package/node_modules/pi-lens/dist/chunk-LW6XKDZQ.js +5565 -0
- package/node_modules/pi-lens/dist/chunk-N3YQJI6O.js +899 -0
- package/node_modules/pi-lens/dist/chunk-NABLC7W3.js +148 -0
- package/node_modules/pi-lens/dist/chunk-NKOUFPQF.js +659 -0
- package/node_modules/pi-lens/dist/chunk-NL5GLMFI.js +211 -0
- package/node_modules/pi-lens/dist/chunk-NMABWBZN.js +327 -0
- package/node_modules/pi-lens/dist/chunk-NTHH2J74.js +27 -0
- package/node_modules/pi-lens/dist/chunk-NTUJEGDZ.js +59 -0
- package/node_modules/pi-lens/dist/chunk-NXL4FFQQ.js +47 -0
- package/node_modules/pi-lens/dist/chunk-NXPS2L6U.js +466 -0
- package/node_modules/pi-lens/dist/chunk-O5WILGMI.js +42 -0
- package/node_modules/pi-lens/dist/chunk-O6TQT6RI.js +48 -0
- package/node_modules/pi-lens/dist/chunk-OAXNDZJ7.js +323 -0
- package/node_modules/pi-lens/dist/chunk-ODEEOXPH.js +44 -0
- package/node_modules/pi-lens/dist/chunk-OQGFCZJ4.js +4533 -0
- package/node_modules/pi-lens/dist/chunk-ORTMY4Q4.js +282 -0
- package/node_modules/pi-lens/dist/chunk-OS32RNR2.js +442 -0
- package/node_modules/pi-lens/dist/chunk-PAK6IDME.js +189 -0
- package/node_modules/pi-lens/dist/chunk-PWFHBTSF.js +406 -0
- package/node_modules/pi-lens/dist/chunk-Q5U6FMDI.js +2352 -0
- package/node_modules/pi-lens/dist/chunk-QOZXJ4NA.js +3364 -0
- package/node_modules/pi-lens/dist/chunk-QYF5S6P6.js +45 -0
- package/node_modules/pi-lens/dist/chunk-RIISMHKN.js +36 -0
- package/node_modules/pi-lens/dist/chunk-RPD4ZSB7.js +25 -0
- package/node_modules/pi-lens/dist/chunk-RPD5K5NC.js +79 -0
- package/node_modules/pi-lens/dist/chunk-RUOG5D2C.js +262 -0
- package/node_modules/pi-lens/dist/chunk-T4ERT73Y.js +599 -0
- package/node_modules/pi-lens/dist/chunk-T6D4Q4AQ.js +54 -0
- package/node_modules/pi-lens/dist/chunk-TGPXLY2J.js +391 -0
- package/node_modules/pi-lens/dist/chunk-TLGFBM3F.js +12116 -0
- package/node_modules/pi-lens/dist/chunk-TO6WL3GM.js +88 -0
- package/node_modules/pi-lens/dist/chunk-TT22N74J.js +517 -0
- package/node_modules/pi-lens/dist/chunk-TVN5N6GY.js +21216 -0
- package/node_modules/pi-lens/dist/chunk-U3VGR4VU.js +308 -0
- package/node_modules/pi-lens/dist/chunk-UK3CMEAL.js +1250 -0
- package/node_modules/pi-lens/dist/chunk-UOPVJQ4N.js +103 -0
- package/node_modules/pi-lens/dist/chunk-UXVNL3D7.js +23 -0
- package/node_modules/pi-lens/dist/chunk-UY752QSN.js +45 -0
- package/node_modules/pi-lens/dist/chunk-V5PXFSZK.js +188 -0
- package/node_modules/pi-lens/dist/chunk-V7R425XG.js +398 -0
- package/node_modules/pi-lens/dist/chunk-VCSRSYLF.js +81 -0
- package/node_modules/pi-lens/dist/chunk-VD4JQCQC.js +162 -0
- package/node_modules/pi-lens/dist/chunk-VDBPVIKD.js +62 -0
- package/node_modules/pi-lens/dist/chunk-VHQLPIRJ.js +114 -0
- package/node_modules/pi-lens/dist/chunk-VN2AXLEX.js +5414 -0
- package/node_modules/pi-lens/dist/chunk-VNMT7C64.js +478 -0
- package/node_modules/pi-lens/dist/chunk-WONERJTP.js +309 -0
- package/node_modules/pi-lens/dist/chunk-XECLWQZN.js +85 -0
- package/node_modules/pi-lens/dist/chunk-XIMYZ3JA.js +27 -0
- package/node_modules/pi-lens/dist/chunk-XK4CIILI.js +144 -0
- package/node_modules/pi-lens/dist/chunk-Y4T27COV.js +562 -0
- package/node_modules/pi-lens/dist/chunk-YGVYKNSN.js +1860 -0
- package/node_modules/pi-lens/dist/chunk-YLF3PPT5.js +308 -0
- package/node_modules/pi-lens/dist/chunk-YSNFMJKN.js +14 -0
- package/node_modules/pi-lens/dist/chunk-Z3CCVDUB.js +76 -0
- package/node_modules/pi-lens/dist/chunk-Z54ZSOBZ.js +61 -0
- package/node_modules/pi-lens/dist/chunk-ZAWW3AF6.js +97 -0
- package/node_modules/pi-lens/dist/chunk-ZMOL6RQC.js +167 -0
- package/node_modules/pi-lens/dist/index.js +16456 -8335
- package/node_modules/pi-lens/dist/mcp/analyze-cli.js +186 -232
- package/node_modules/pi-lens/dist/mcp/cli.js +137 -98
- package/node_modules/pi-lens/dist/mcp/server.js +22589 -1573
- package/node_modules/pi-lens/dist/mcp/worker.js +97 -38
- package/node_modules/pi-lens/dist/probes/installer.js +135 -0
- package/node_modules/pi-lens/dist/workers/project-snapshot-persist-worker.js +22 -0
- package/node_modules/pi-lens/dist/workers/review-graph-persist-worker.js +15 -0
- package/node_modules/pi-lens/docs/agent-guide.md +13 -4
- package/node_modules/pi-lens/docs/agent-tools.md +42 -0
- package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +3 -2
- package/node_modules/pi-lens/docs/configuration.md +20 -1
- package/node_modules/pi-lens/docs/environment-variables.md +52 -2
- package/node_modules/pi-lens/docs/features.md +8 -4
- package/node_modules/pi-lens/docs/globalconfig.md +1 -0
- package/node_modules/pi-lens/docs/io-bridge-v2-migration.md +94 -0
- package/node_modules/pi-lens/docs/lsp-capability-matrix.md +36 -4
- package/node_modules/pi-lens/docs/lsp-idle-eviction.md +124 -0
- package/node_modules/pi-lens/docs/mcp.md +21 -5
- package/node_modules/pi-lens/docs/merge-queue-rollout.md +77 -0
- package/node_modules/pi-lens/docs/pi-lens-fixer.md +156 -88
- package/node_modules/pi-lens/docs/pi-lens-investigator.md +74 -26
- package/node_modules/pi-lens/docs/pi-lens-merge-policy.md +694 -0
- package/node_modules/pi-lens/docs/pi-lens-monitor.md +73 -7
- package/node_modules/pi-lens/docs/pi-lens-retro.md +6 -4
- package/node_modules/pi-lens/docs/pi-lens-reviewer.md +188 -48
- package/node_modules/pi-lens/docs/pi-lens-subagent.md +246 -45
- package/node_modules/pi-lens/docs/pi-lens-warden.md +18 -7
- package/node_modules/pi-lens/docs/public-api-stability.md +55 -0
- package/node_modules/pi-lens/docs/release-qa-baseline.md +84 -17
- package/node_modules/pi-lens/docs/rfcs/3654-unified-io-bridge-v2.md +316 -0
- package/node_modules/pi-lens/docs/servercapabilities.md +53 -49
- package/node_modules/pi-lens/docs/settings.md +1 -0
- package/node_modules/pi-lens/docs/usage.md +5 -1
- package/node_modules/pi-lens/grammars/tree-sitter-bash.wasm +0 -0
- package/node_modules/pi-lens/grammars/tree-sitter-bash.wasm.json +3 -3
- package/node_modules/pi-lens/package.json +18 -6
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/advisory-registry-subset-test.yml +41 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/advisory-registry-subset.yml +50 -0
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +1275 -62
- package/node_modules/pi-lens/scripts/download-grammars.js +5 -0
- package/node_modules/pi-lens/scripts/grammars.lock.json +6 -1
- package/node_modules/pi-lens/scripts/install-selftest.mjs +33 -34
- package/node_modules/pi-lens/scripts/lib/host-provided-deps.mjs +13 -4
- package/node_modules/pi-lens/scripts/lib/web-tree-sitter-dir.mjs +18 -0
- package/node_modules/pi-typesafe/README.md +1 -1
- package/node_modules/pi-typesafe/dist/backends.d.ts +15 -5
- package/node_modules/pi-typesafe/dist/backends.js +18 -0
- package/node_modules/pi-typesafe/dist/client.d.ts +4 -3
- package/node_modules/pi-typesafe/dist/client.js +22 -7
- package/node_modules/pi-typesafe/dist/index.d.ts +2 -2
- package/node_modules/pi-typesafe/dist/index.js +1 -1
- package/node_modules/pi-typesafe/dist/usage.d.ts +14 -4
- package/node_modules/pi-typesafe/dist/usage.js +147 -42
- package/node_modules/pi-typesafe/package.json +1 -1
- package/node_modules/pi-web-access/CHANGELOG.md +48 -0
- package/node_modules/pi-web-access/README.md +57 -11
- package/node_modules/pi-web-access/brave-rate-limit.ts +8 -2
- package/node_modules/pi-web-access/curator-page.ts +5 -1
- package/node_modules/pi-web-access/curator-server.ts +2 -0
- package/node_modules/pi-web-access/declared-web-links.ts +2 -2
- package/node_modules/pi-web-access/degoog.ts +323 -0
- package/node_modules/pi-web-access/dist/index.js +3483 -2745
- package/node_modules/pi-web-access/dist/mcp-cli.js +27443 -0
- package/node_modules/pi-web-access/exa.ts +5 -1
- package/node_modules/pi-web-access/extract.ts +41 -3
- package/node_modules/pi-web-access/firecrawl.ts +35 -4
- package/node_modules/pi-web-access/gemini-search.ts +34 -11
- package/node_modules/pi-web-access/gemini-web.ts +14 -9
- package/node_modules/pi-web-access/index.ts +153 -1202
- package/node_modules/pi-web-access/keenable.ts +221 -0
- package/node_modules/pi-web-access/mcp-cli.ts +40 -0
- package/node_modules/pi-web-access/mcp-server.ts +81 -0
- package/node_modules/pi-web-access/mcp-tool-definitions.ts +117 -0
- package/node_modules/pi-web-access/openai-search.ts +34 -1
- package/node_modules/pi-web-access/package.json +23 -5
- package/node_modules/pi-web-access/perplexity.ts +64 -56
- package/node_modules/pi-web-access/tool-arguments.ts +20 -0
- package/node_modules/pi-web-access/video-extract.ts +1 -1
- package/node_modules/pi-web-access/web-tool-contract.ts +86 -0
- package/node_modules/pi-web-access/web-tool-core.ts +1502 -0
- package/node_modules/pi-web-access/youtube-extract.ts +2 -5
- package/package.json +17 -12
- package/node_modules/@dietrichgebert/ponytail/README.es.md +0 -329
- package/node_modules/@dietrichgebert/ponytail/README.ko.md +0 -346
- package/node_modules/@dietrichgebert/ponytail/assets/benchmark-3model.svg +0 -21
- package/node_modules/@dietrichgebert/ponytail/assets/benchmark-agentic.svg +0 -62
- package/node_modules/@dietrichgebert/ponytail/assets/logo-dark.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/logo-dark.svg +0 -115
- package/node_modules/@dietrichgebert/ponytail/assets/logo-greenpt-dark.svg +0 -27
- package/node_modules/@dietrichgebert/ponytail/assets/logo-greenpt.svg +0 -27
- package/node_modules/@dietrichgebert/ponytail/assets/logo.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/retriever-icon.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/retriever-logo-dark.svg +0 -4
- package/node_modules/@dietrichgebert/ponytail/assets/retriever-logo-light.svg +0 -4
- package/node_modules/@dietrichgebert/ponytail/assets/social-preview.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner-es.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner-ko.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner.png +0 -0
- package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +0 -35
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +0 -1610
- package/node_modules/pi-lens/dist/clients/advisory-provenance.js +0 -593
- package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +0 -147
- package/node_modules/pi-lens/dist/clients/agent-nudge.js +0 -325
- package/node_modules/pi-lens/dist/clients/analysed-root.js +0 -1
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +0 -731
- package/node_modules/pi-lens/dist/clients/ast-grep-rule-manager.js +0 -146
- package/node_modules/pi-lens/dist/clients/ast-grep-tool-logger.js +0 -118
- package/node_modules/pi-lens/dist/clients/ast-grep-types.js +0 -10
- package/node_modules/pi-lens/dist/clients/ast-grep-yaml-synth.js +0 -154
- package/node_modules/pi-lens/dist/clients/atomic-write-staging.js +0 -75
- package/node_modules/pi-lens/dist/clients/atomic-write.js +0 -189
- package/node_modules/pi-lens/dist/clients/availability-probe-flight.js +0 -12
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +0 -1056
- package/node_modules/pi-lens/dist/clients/biome-client.js +0 -357
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +0 -837
- package/node_modules/pi-lens/dist/clients/blocker-past-eof.js +0 -129
- package/node_modules/pi-lens/dist/clients/bootstrap.js +0 -569
- package/node_modules/pi-lens/dist/clients/bounded-cache.js +0 -190
- package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +0 -202
- package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +0 -295
- package/node_modules/pi-lens/dist/clients/build-identity.js +0 -95
- package/node_modules/pi-lens/dist/clients/bundled-resource-health.js +0 -113
- package/node_modules/pi-lens/dist/clients/bus-events-logger.js +0 -105
- package/node_modules/pi-lens/dist/clients/bus-publish.js +0 -171
- package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +0 -190
- package/node_modules/pi-lens/dist/clients/cache-manager.js +0 -524
- package/node_modules/pi-lens/dist/clients/cache-observability.js +0 -1313
- package/node_modules/pi-lens/dist/clients/call-graph.js +0 -852
- package/node_modules/pi-lens/dist/clients/cargo-manifest.js +0 -422
- package/node_modules/pi-lens/dist/clients/cascade-budget.js +0 -196
- package/node_modules/pi-lens/dist/clients/cascade-format.js +0 -315
- package/node_modules/pi-lens/dist/clients/cascade-logger.js +0 -31
- package/node_modules/pi-lens/dist/clients/cascade-types.js +0 -9
- package/node_modules/pi-lens/dist/clients/child-unref.js +0 -124
- package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +0 -286
- package/node_modules/pi-lens/dist/clients/codebase-model.js +0 -173
- package/node_modules/pi-lens/dist/clients/collateral-test-role.js +0 -40
- package/node_modules/pi-lens/dist/clients/complexity-client.js +0 -462
- package/node_modules/pi-lens/dist/clients/config-core/deny.js +0 -221
- package/node_modules/pi-lens/dist/clients/config-core/index.js +0 -50
- package/node_modules/pi-lens/dist/clients/config-core/merge.js +0 -357
- package/node_modules/pi-lens/dist/clients/config-core/normalize.js +0 -340
- package/node_modules/pi-lens/dist/clients/config-core/process-spec.js +0 -248
- package/node_modules/pi-lens/dist/clients/config-core/provenance.js +0 -164
- package/node_modules/pi-lens/dist/clients/config-core/records.js +0 -218
- package/node_modules/pi-lens/dist/clients/config-core/resolve.js +0 -125
- package/node_modules/pi-lens/dist/clients/config-core/safe-object.js +0 -78
- package/node_modules/pi-lens/dist/clients/config-core/schema.js +0 -165
- package/node_modules/pi-lens/dist/clients/config-diagnostic-codes.js +0 -285
- package/node_modules/pi-lens/dist/clients/config-locations.js +0 -388
- package/node_modules/pi-lens/dist/clients/config-resolve.js +0 -798
- package/node_modules/pi-lens/dist/clients/config-schema.js +0 -251
- package/node_modules/pi-lens/dist/clients/config-warn.js +0 -407
- package/node_modules/pi-lens/dist/clients/console-guard-install.js +0 -26
- package/node_modules/pi-lens/dist/clients/cooperative-budget.js +0 -42
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +0 -510
- package/node_modules/pi-lens/dist/clients/dead-code-logger.js +0 -30
- package/node_modules/pi-lens/dist/clients/deadline-utils.js +0 -280
- package/node_modules/pi-lens/dist/clients/debug-handles.js +0 -211
- package/node_modules/pi-lens/dist/clients/debug-heap.js +0 -174
- package/node_modules/pi-lens/dist/clients/deferred-lsp-work.js +0 -106
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +0 -426
- package/node_modules/pi-lens/dist/clients/demoted-finding-render.js +0 -169
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +0 -885
- package/node_modules/pi-lens/dist/clients/deps/ast-grep-napi.js +0 -22
- package/node_modules/pi-lens/dist/clients/deps/js-yaml.js +0 -9
- package/node_modules/pi-lens/dist/clients/deps/minimatch.js +0 -4
- package/node_modules/pi-lens/dist/clients/deps/pi-tui.js +0 -14
- package/node_modules/pi-lens/dist/clients/deps/typebox.js +0 -14
- package/node_modules/pi-lens/dist/clients/deps/vscode-jsonrpc.js +0 -1
- package/node_modules/pi-lens/dist/clients/deps/web-tree-sitter.js +0 -24
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +0 -630
- package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +0 -305
- package/node_modules/pi-lens/dist/clients/diagnostic-logger.js +0 -73
- package/node_modules/pi-lens/dist/clients/diagnostic-tracker.js +0 -105
- package/node_modules/pi-lens/dist/clients/diagnostics-publish.js +0 -230
- package/node_modules/pi-lens/dist/clients/dispatch/ast-grep-catalog.js +0 -65
- package/node_modules/pi-lens/dist/clients/dispatch/auxiliary-lsp.js +0 -343
- package/node_modules/pi-lens/dist/clients/dispatch/collect-later-tier.js +0 -35
- package/node_modules/pi-lens/dist/clients/dispatch/diagnostic-taxonomy.js +0 -66
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +0 -1269
- package/node_modules/pi-lens/dist/clients/dispatch/fact-provider-types.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/fact-rule-runner.js +0 -17
- package/node_modules/pi-lens/dist/clients/dispatch/fact-runner.js +0 -30
- package/node_modules/pi-lens/dist/clients/dispatch/fact-scheduler.js +0 -68
- package/node_modules/pi-lens/dist/clients/dispatch/fact-store.js +0 -377
- package/node_modules/pi-lens/dist/clients/dispatch/facts/comment-facts.js +0 -22
- package/node_modules/pi-lens/dist/clients/dispatch/facts/file-content.js +0 -19
- package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +0 -348
- package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +0 -204
- package/node_modules/pi-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +0 -34
- package/node_modules/pi-lens/dist/clients/dispatch/facts/try-catch-facts.js +0 -119
- package/node_modules/pi-lens/dist/clients/dispatch/finding-policy.js +0 -339
- package/node_modules/pi-lens/dist/clients/dispatch/indent-detect.js +0 -417
- package/node_modules/pi-lens/dist/clients/dispatch/inline-suppressions.js +0 -89
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +0 -2377
- package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +0 -11
- package/node_modules/pi-lens/dist/clients/dispatch/pending-runner-findings.js +0 -87
- package/node_modules/pi-lens/dist/clients/dispatch/plan.js +0 -278
- package/node_modules/pi-lens/dist/clients/dispatch/priorities.js +0 -20
- package/node_modules/pi-lens/dist/clients/dispatch/rule-id-normalize.js +0 -50
- package/node_modules/pi-lens/dist/clients/dispatch/rule-ignores.js +0 -69
- package/node_modules/pi-lens/dist/clients/dispatch/rule-policy.js +0 -135
- package/node_modules/pi-lens/dist/clients/dispatch/rules/async-noise.js +0 -40
- package/node_modules/pi-lens/dist/clients/dispatch/rules/async-unnecessary-wrapper.js +0 -27
- package/node_modules/pi-lens/dist/clients/dispatch/rules/cors-wildcard.js +0 -54
- package/node_modules/pi-lens/dist/clients/dispatch/rules/error-obscuring.js +0 -32
- package/node_modules/pi-lens/dist/clients/dispatch/rules/error-swallowing.js +0 -31
- package/node_modules/pi-lens/dist/clients/dispatch/rules/framework-call-noise.js +0 -67
- package/node_modules/pi-lens/dist/clients/dispatch/rules/high-complexity.js +0 -72
- package/node_modules/pi-lens/dist/clients/dispatch/rules/high-fan-out.js +0 -74
- package/node_modules/pi-lens/dist/clients/dispatch/rules/high-import-coupling.js +0 -37
- package/node_modules/pi-lens/dist/clients/dispatch/rules/missing-error-propagation.js +0 -62
- package/node_modules/pi-lens/dist/clients/dispatch/rules/no-commented-credentials.js +0 -52
- package/node_modules/pi-lens/dist/clients/dispatch/rules/pass-through-wrappers.js +0 -42
- package/node_modules/pi-lens/dist/clients/dispatch/rules/placeholder-comments.js +0 -40
- package/node_modules/pi-lens/dist/clients/dispatch/rules/unsafe-boundary.js +0 -126
- package/node_modules/pi-lens/dist/clients/dispatch/runner-context.js +0 -52
- package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +0 -111
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +0 -1196
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +0 -296
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +0 -219
- package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +0 -82
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +0 -416
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dart-analyze.js +0 -183
- package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +0 -176
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +0 -164
- package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +0 -195
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +0 -137
- package/node_modules/pi-lens/dist/clients/dispatch/runners/fact-rules.js +0 -29
- package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +0 -69
- package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +0 -167
- package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +0 -104
- package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +0 -135
- package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +0 -91
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +0 -171
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +0 -940
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +0 -117
- package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +0 -108
- package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +0 -99
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +0 -110
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +0 -379
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +0 -167
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +0 -102
- package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +0 -414
- package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +0 -85
- package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +0 -120
- package/node_modules/pi-lens/dist/clients/dispatch/runners/prisma-validate.js +0 -62
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +0 -445
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +0 -169
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rubocop.js +0 -99
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +0 -88
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +0 -256
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +0 -173
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +0 -102
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +0 -128
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +0 -259
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +0 -183
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +0 -166
- package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +0 -163
- package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +0 -174
- package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +0 -168
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +0 -125
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +0 -643
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +0 -253
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +0 -496
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +0 -90
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +0 -95
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +0 -274
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +0 -1701
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +0 -101
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +0 -235
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +0 -169
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils.js +0 -15
- package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +0 -128
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +0 -242
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +0 -95
- package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +0 -79
- package/node_modules/pi-lens/dist/clients/dispatch/suppress-writer.js +0 -79
- package/node_modules/pi-lens/dist/clients/dispatch/tool-profile.js +0 -30
- package/node_modules/pi-lens/dist/clients/dispatch/types.js +0 -21
- package/node_modules/pi-lens/dist/clients/dispatch/utils/format-utils.js +0 -45
- package/node_modules/pi-lens/dist/clients/dispatch/utils/lsp-diagnostics.js +0 -35
- package/node_modules/pi-lens/dist/clients/disposition-logger.js +0 -32
- package/node_modules/pi-lens/dist/clients/disposition-publish.js +0 -124
- package/node_modules/pi-lens/dist/clients/durable-store.js +0 -97
- package/node_modules/pi-lens/dist/clients/effective-config.js +0 -415
- package/node_modules/pi-lens/dist/clients/env-utils.js +0 -83
- package/node_modules/pi-lens/dist/clients/error-class.js +0 -23
- package/node_modules/pi-lens/dist/clients/eval-timestamp.js +0 -17
- package/node_modules/pi-lens/dist/clients/event-loop-hold.js +0 -274
- package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +0 -250
- package/node_modules/pi-lens/dist/clients/extension-log.js +0 -504
- package/node_modules/pi-lens/dist/clients/extension-mode.js +0 -73
- package/node_modules/pi-lens/dist/clients/feature-hints.js +0 -103
- package/node_modules/pi-lens/dist/clients/file-kinds.js +0 -412
- package/node_modules/pi-lens/dist/clients/file-role.js +0 -134
- package/node_modules/pi-lens/dist/clients/file-time.js +0 -160
- package/node_modules/pi-lens/dist/clients/file-utils.js +0 -1032
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +0 -494
- package/node_modules/pi-lens/dist/clients/finding-identity.js +0 -88
- package/node_modules/pi-lens/dist/clients/fix-worklog.js +0 -103
- package/node_modules/pi-lens/dist/clients/format-events-publish.js +0 -343
- package/node_modules/pi-lens/dist/clients/format-service.js +0 -222
- package/node_modules/pi-lens/dist/clients/formatters-lazy.js +0 -9
- package/node_modules/pi-lens/dist/clients/formatters.js +0 -2032
- package/node_modules/pi-lens/dist/clients/freshness-cadence.js +0 -17
- package/node_modules/pi-lens/dist/clients/freshness.js +0 -38
- package/node_modules/pi-lens/dist/clients/generated-artifacts.js +0 -394
- package/node_modules/pi-lens/dist/clients/generation-guard.js +0 -215
- package/node_modules/pi-lens/dist/clients/git-guard.js +0 -1136
- package/node_modules/pi-lens/dist/clients/git-tracked-ignore.js +0 -243
- package/node_modules/pi-lens/dist/clients/gitleaks-client.js +0 -509
- package/node_modules/pi-lens/dist/clients/go-client.js +0 -104
- package/node_modules/pi-lens/dist/clients/govulncheck-client.js +0 -605
- package/node_modules/pi-lens/dist/clients/gradle-ktfmt-style.js +0 -348
- package/node_modules/pi-lens/dist/clients/grammar-source.js +0 -465
- package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +0 -135
- package/node_modules/pi-lens/dist/clients/hashline-anchor.js +0 -424
- package/node_modules/pi-lens/dist/clients/hook-budgets.js +0 -76
- package/node_modules/pi-lens/dist/clients/host-edit-normalize.js +0 -140
- package/node_modules/pi-lens/dist/clients/host-ports.js +0 -39
- package/node_modules/pi-lens/dist/clients/indent-retarget.js +0 -154
- package/node_modules/pi-lens/dist/clients/inline-blocker-dispositions.js +0 -186
- package/node_modules/pi-lens/dist/clients/install-diagnostics.js +0 -156
- package/node_modules/pi-lens/dist/clients/installer/index.js +0 -5416
- package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh-session.js +0 -58
- package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +0 -783
- package/node_modules/pi-lens/dist/clients/instance-reaper-state.js +0 -7
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +0 -1137
- package/node_modules/pi-lens/dist/clients/instance-registry-lock.js +0 -145
- package/node_modules/pi-lens/dist/clients/instance-registry.js +0 -773
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +0 -378
- package/node_modules/pi-lens/dist/clients/json-cache-read.js +0 -65
- package/node_modules/pi-lens/dist/clients/knip-client.js +0 -788
- package/node_modules/pi-lens/dist/clients/language-policy.js +0 -252
- package/node_modules/pi-lens/dist/clients/language-profile.js +0 -361
- package/node_modules/pi-lens/dist/clients/language-registry.js +0 -603
- package/node_modules/pi-lens/dist/clients/latency-logger.js +0 -727
- package/node_modules/pi-lens/dist/clients/lazy-import.js +0 -21
- package/node_modules/pi-lens/dist/clients/ledger-bounds.js +0 -54
- package/node_modules/pi-lens/dist/clients/lens-config.js +0 -404
- package/node_modules/pi-lens/dist/clients/lens-engine.js +0 -358
- package/node_modules/pi-lens/dist/clients/lens-events.js +0 -125
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +0 -467
- package/node_modules/pi-lens/dist/clients/lens-map.js +0 -1156
- package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +0 -74
- package/node_modules/pi-lens/dist/clients/log-cleanup.js +0 -222
- package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +0 -178
- package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +0 -421
- package/node_modules/pi-lens/dist/clients/lsp/client.js +0 -4593
- package/node_modules/pi-lens/dist/clients/lsp/config.js +0 -691
- package/node_modules/pi-lens/dist/clients/lsp/content-limits.js +0 -41
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +0 -225
- package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +0 -467
- package/node_modules/pi-lens/dist/clients/lsp/edits.js +0 -1219
- package/node_modules/pi-lens/dist/clients/lsp/index.js +0 -8305
- package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +0 -216
- package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +0 -298
- package/node_modules/pi-lens/dist/clients/lsp/language.js +0 -63
- package/node_modules/pi-lens/dist/clients/lsp/launch.js +0 -746
- package/node_modules/pi-lens/dist/clients/lsp/lombok.js +0 -158
- package/node_modules/pi-lens/dist/clients/lsp/path-utils.js +0 -5
- package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +0 -251
- package/node_modules/pi-lens/dist/clients/lsp/position-encoding.js +0 -61
- package/node_modules/pi-lens/dist/clients/lsp/ruby-drive-dirs.js +0 -83
- package/node_modules/pi-lens/dist/clients/lsp/server.js +0 -3290
- package/node_modules/pi-lens/dist/clients/lsp/session-roots.js +0 -192
- package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +0 -17
- package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +0 -56
- package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +0 -332
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/capability-snapshot.js +0 -1
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/classification.js +0 -85
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/index.js +0 -10
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +0 -392
- package/node_modules/pi-lens/dist/clients/lsp/watch-queue.js +0 -61
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +0 -639
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-session.js +0 -30
- package/node_modules/pi-lens/dist/clients/lsp/workspace-sweep-hold.js +0 -184
- package/node_modules/pi-lens/dist/clients/lsp-budget.js +0 -186
- package/node_modules/pi-lens/dist/clients/lsp-document-symbols.js +0 -110
- package/node_modules/pi-lens/dist/clients/lsp-lazy.js +0 -9
- package/node_modules/pi-lens/dist/clients/lsp-mutation.js +0 -396
- package/node_modules/pi-lens/dist/clients/lsp-status.js +0 -59
- package/node_modules/pi-lens/dist/clients/map-with-concurrency.js +0 -40
- package/node_modules/pi-lens/dist/clients/mcp/analyze.js +0 -420
- package/node_modules/pi-lens/dist/clients/mcp/host-shim.js +0 -31
- package/node_modules/pi-lens/dist/clients/mcp/ipc.js +0 -523
- package/node_modules/pi-lens/dist/clients/mcp/review.js +0 -197
- package/node_modules/pi-lens/dist/clients/mcp/session.js +0 -412
- package/node_modules/pi-lens/dist/clients/memory-sampler.js +0 -208
- package/node_modules/pi-lens/dist/clients/message-end-attribution.js +0 -30
- package/node_modules/pi-lens/dist/clients/metrics-client.js +0 -107
- package/node_modules/pi-lens/dist/clients/metrics-history.js +0 -327
- package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +0 -263
- package/node_modules/pi-lens/dist/clients/model-provider.js +0 -53
- package/node_modules/pi-lens/dist/clients/module-report-lsp.js +0 -189
- package/node_modules/pi-lens/dist/clients/module-report.js +0 -2150
- package/node_modules/pi-lens/dist/clients/mutating-tool.js +0 -651
- package/node_modules/pi-lens/dist/clients/mutation-attribution.js +0 -368
- package/node_modules/pi-lens/dist/clients/mutation-bridge.js +0 -240
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +0 -734
- package/node_modules/pi-lens/dist/clients/observed-mutation-sources.js +0 -101
- package/node_modules/pi-lens/dist/clients/observed-mutation.js +0 -1253
- package/node_modules/pi-lens/dist/clients/oldtext-autopatch.js +0 -128
- package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +0 -496
- package/node_modules/pi-lens/dist/clients/opengrep-client.js +0 -333
- package/node_modules/pi-lens/dist/clients/opengrep-config.js +0 -76
- package/node_modules/pi-lens/dist/clients/package-manager.js +0 -607
- package/node_modules/pi-lens/dist/clients/package-root.js +0 -38
- package/node_modules/pi-lens/dist/clients/partial-edit-apply.js +0 -439
- package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +0 -43
- package/node_modules/pi-lens/dist/clients/path-keyed-map.js +0 -108
- package/node_modules/pi-lens/dist/clients/path-utils.js +0 -1244
- package/node_modules/pi-lens/dist/clients/performance-report.js +0 -331
- package/node_modules/pi-lens/dist/clients/persist-debounce.js +0 -70
- package/node_modules/pi-lens/dist/clients/persistent-reverify.js +0 -271
- package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +0 -119
- package/node_modules/pi-lens/dist/clients/pipeline.js +0 -1480
- package/node_modules/pi-lens/dist/clients/post-autofix-notice.js +0 -37
- package/node_modules/pi-lens/dist/clients/print-mode.js +0 -21
- package/node_modules/pi-lens/dist/clients/probe-home-state.js +0 -228
- package/node_modules/pi-lens/dist/clients/process-bridge.js +0 -66
- package/node_modules/pi-lens/dist/clients/process-singletons.js +0 -210
- package/node_modules/pi-lens/dist/clients/process-snapshot.js +0 -68
- package/node_modules/pi-lens/dist/clients/project-changes.js +0 -181
- package/node_modules/pi-lens/dist/clients/project-conventions.js +0 -171
- package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +0 -137
- package/node_modules/pi-lens/dist/clients/project-diagnostics/extractors.js +0 -109
- package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +0 -668
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +0 -118
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/dead-code.js +0 -47
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +0 -40
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/govulncheck.js +0 -34
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/jscpd.js +0 -38
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/knip.js +0 -47
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/madge.js +0 -48
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/opengrep.js +0 -40
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +0 -127
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +0 -81
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +0 -520
- package/node_modules/pi-lens/dist/clients/project-diagnostics/types.js +0 -1
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +0 -807
- package/node_modules/pi-lens/dist/clients/project-report.js +0 -701
- package/node_modules/pi-lens/dist/clients/project-scale.js +0 -237
- package/node_modules/pi-lens/dist/clients/project-scan-policy.js +0 -11
- package/node_modules/pi-lens/dist/clients/project-snapshot-fingerprint.js +0 -48
- package/node_modules/pi-lens/dist/clients/project-snapshot-persist-worker.js +0 -20
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +0 -1653
- package/node_modules/pi-lens/dist/clients/project-trust.js +0 -181
- package/node_modules/pi-lens/dist/clients/python-environment.js +0 -217
- package/node_modules/pi-lens/dist/clients/python-provenance.js +0 -639
- package/node_modules/pi-lens/dist/clients/quiet-window-config.js +0 -47
- package/node_modules/pi-lens/dist/clients/quiet-window.js +0 -236
- package/node_modules/pi-lens/dist/clients/read-bridge.js +0 -139
- package/node_modules/pi-lens/dist/clients/read-expansion.js +0 -266
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +0 -251
- package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +0 -1306
- package/node_modules/pi-lens/dist/clients/read-guard.js +0 -1561
- package/node_modules/pi-lens/dist/clients/recent-touches.js +0 -240
- package/node_modules/pi-lens/dist/clients/redact/secrets.js +0 -449
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +0 -628
- package/node_modules/pi-lens/dist/clients/reverse-deps.js +0 -270
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +0 -5126
- package/node_modules/pi-lens/dist/clients/review-graph/format.js +0 -33
- package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +0 -163
- package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +0 -481
- package/node_modules/pi-lens/dist/clients/review-graph/persist-worker.js +0 -10
- package/node_modules/pi-lens/dist/clients/review-graph/query.js +0 -244
- package/node_modules/pi-lens/dist/clients/review-graph/revision-drift.js +0 -21
- package/node_modules/pi-lens/dist/clients/review-graph/service.js +0 -96
- package/node_modules/pi-lens/dist/clients/review-graph/shared-extraction-ir.js +0 -82
- package/node_modules/pi-lens/dist/clients/review-graph/symbol-id.js +0 -103
- package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +0 -299
- package/node_modules/pi-lens/dist/clients/review-graph/types.js +0 -1
- package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +0 -449
- package/node_modules/pi-lens/dist/clients/review-graph-logger.js +0 -81
- package/node_modules/pi-lens/dist/clients/ruff-client.js +0 -179
- package/node_modules/pi-lens/dist/clients/rules-scanner.js +0 -131
- package/node_modules/pi-lens/dist/clients/run-duration.js +0 -55
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +0 -746
- package/node_modules/pi-lens/dist/clients/runtime-config.js +0 -77
- package/node_modules/pi-lens/dist/clients/runtime-context.js +0 -211
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +0 -1324
- package/node_modules/pi-lens/dist/clients/runtime-session.js +0 -2485
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +0 -1295
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +0 -2049
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +0 -3767
- package/node_modules/pi-lens/dist/clients/rust-client.js +0 -97
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +0 -2357
- package/node_modules/pi-lens/dist/clients/sanitize.js +0 -286
- package/node_modules/pi-lens/dist/clients/scan-utils.js +0 -25
- package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +0 -165
- package/node_modules/pi-lens/dist/clients/search-read-registration.js +0 -94
- package/node_modules/pi-lens/dist/clients/secret-findings.js +0 -114
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +0 -352
- package/node_modules/pi-lens/dist/clients/session-event-guard.js +0 -297
- package/node_modules/pi-lens/dist/clients/session-lifecycle.js +0 -484
- package/node_modules/pi-lens/dist/clients/session-start-observability.js +0 -94
- package/node_modules/pi-lens/dist/clients/session-state-store.js +0 -101
- package/node_modules/pi-lens/dist/clients/session-summary.js +0 -15
- package/node_modules/pi-lens/dist/clients/sessionstart-logger.js +0 -27
- package/node_modules/pi-lens/dist/clients/sg-runner.js +0 -876
- package/node_modules/pi-lens/dist/clients/sgconfig.js +0 -347
- package/node_modules/pi-lens/dist/clients/shared-checkout-guard.js +0 -338
- package/node_modules/pi-lens/dist/clients/single-flight.js +0 -158
- package/node_modules/pi-lens/dist/clients/situational-tool-telemetry.js +0 -108
- package/node_modules/pi-lens/dist/clients/skills-resolver.js +0 -141
- package/node_modules/pi-lens/dist/clients/slow-fs.js +0 -138
- package/node_modules/pi-lens/dist/clients/smells-rollup.js +0 -231
- package/node_modules/pi-lens/dist/clients/source-filter.js +0 -596
- package/node_modules/pi-lens/dist/clients/source-walker.js +0 -211
- package/node_modules/pi-lens/dist/clients/spawn-output-cap.js +0 -120
- package/node_modules/pi-lens/dist/clients/spawn-timeout-cooldown.js +0 -110
- package/node_modules/pi-lens/dist/clients/stale-marker.js +0 -17
- package/node_modules/pi-lens/dist/clients/startup-scan.js +0 -400
- package/node_modules/pi-lens/dist/clients/startup-timing.js +0 -130
- package/node_modules/pi-lens/dist/clients/string-utils.js +0 -33
- package/node_modules/pi-lens/dist/clients/subagent-mode.js +0 -111
- package/node_modules/pi-lens/dist/clients/symbol-containment.js +0 -24
- package/node_modules/pi-lens/dist/clients/symbol-types.js +0 -5
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +0 -2507
- package/node_modules/pi-lens/dist/clients/test-runner-delivery.js +0 -287
- package/node_modules/pi-lens/dist/clients/todo-scanner.js +0 -229
- package/node_modules/pi-lens/dist/clients/tool-agreement.js +0 -423
- package/node_modules/pi-lens/dist/clients/tool-config.js +0 -249
- package/node_modules/pi-lens/dist/clients/tool-cwd.js +0 -270
- package/node_modules/pi-lens/dist/clients/tool-definition.js +0 -47
- package/node_modules/pi-lens/dist/clients/tool-event.js +0 -105
- package/node_modules/pi-lens/dist/clients/tool-policy.js +0 -2755
- package/node_modules/pi-lens/dist/clients/tool-probe.js +0 -53
- package/node_modules/pi-lens/dist/clients/tool-render.js +0 -156
- package/node_modules/pi-lens/dist/clients/tool-set-policy.js +0 -118
- package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +0 -364
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +0 -4195
- package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +0 -100
- package/node_modules/pi-lens/dist/clients/tree-sitter-navigator.js +0 -269
- package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +0 -569
- package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +0 -158
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +0 -1265
- package/node_modules/pi-lens/dist/clients/trivy-client.js +0 -467
- package/node_modules/pi-lens/dist/clients/tui-fit.js +0 -50
- package/node_modules/pi-lens/dist/clients/turn-context.js +0 -52
- package/node_modules/pi-lens/dist/clients/turn-end/lane.js +0 -51
- package/node_modules/pi-lens/dist/clients/turn-end/lanes/govulncheck.js +0 -112
- package/node_modules/pi-lens/dist/clients/turn-end/lanes/secrets.js +0 -204
- package/node_modules/pi-lens/dist/clients/turn-summary-render.js +0 -72
- package/node_modules/pi-lens/dist/clients/turn-summary.js +0 -132
- package/node_modules/pi-lens/dist/clients/typos-config.js +0 -29
- package/node_modules/pi-lens/dist/clients/user-notify.js +0 -51
- package/node_modules/pi-lens/dist/clients/vanished-instance-marker.js +0 -57
- package/node_modules/pi-lens/dist/clients/warm-attach.js +0 -305
- package/node_modules/pi-lens/dist/clients/widget-state.js +0 -1808
- package/node_modules/pi-lens/dist/clients/word-index-logger.js +0 -49
- package/node_modules/pi-lens/dist/clients/word-index-store.js +0 -459
- package/node_modules/pi-lens/dist/clients/word-index.js +0 -2080
- package/node_modules/pi-lens/dist/clients/workspace-topology.js +0 -443
- package/node_modules/pi-lens/dist/clients/write-ordering-guard.js +0 -65
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +0 -340
- package/node_modules/pi-lens/dist/i18n.js +0 -69
- package/node_modules/pi-lens/dist/mcp/build-staleness.js +0 -124
- package/node_modules/pi-lens/dist/scripts/lib/process-scan.mjs +0 -583
- package/node_modules/pi-lens/dist/scripts/lib/skills-predicate.mjs +0 -129
- package/node_modules/pi-lens/dist/scripts/lib/web-tree-sitter-dir.mjs +0 -123
- package/node_modules/pi-lens/dist/tools/activate-tools.js +0 -87
- package/node_modules/pi-lens/dist/tools/ast-grep-outline.js +0 -137
- package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +0 -244
- package/node_modules/pi-lens/dist/tools/ast-grep-search.js +0 -762
- package/node_modules/pi-lens/dist/tools/effective-config.js +0 -90
- package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +0 -375
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +0 -2571
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +0 -1745
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +0 -1367
- package/node_modules/pi-lens/dist/tools/lsp-structured-output.js +0 -294
- package/node_modules/pi-lens/dist/tools/module-report.js +0 -382
- package/node_modules/pi-lens/dist/tools/project-report.js +0 -86
- package/node_modules/pi-lens/dist/tools/render-compact.js +0 -374
- package/node_modules/pi-lens/dist/tools/scan-progress.js +0 -53
- package/node_modules/pi-lens/dist/tools/shared.js +0 -29
- package/node_modules/pi-lens/dist/tools/symbol-search.js +0 -155
|
@@ -1,30 +1,22 @@
|
|
|
1
1
|
import type { AgentToolResult, ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { Box, Text, truncateToWidth, type KeyId } from "@earendil-works/pi-tui";
|
|
3
3
|
import { Type } from "typebox";
|
|
4
|
-
import
|
|
5
|
-
import type { ImageContent, TextContent } from "@earendil-works/pi-ai/compat";
|
|
6
|
-
import type { ExtractedContent, ExtractOptions } from "./extract.ts";
|
|
4
|
+
import type { ExtractedContent } from "./extract.ts";
|
|
7
5
|
import { normalizeFetchContentParams } from "./fetch-params.ts";
|
|
8
|
-
import { resolveAuthFetchProfile, type AuthFetchProfile } from "./auth-fetch.ts";
|
|
9
|
-
import { findContent, type FindMode } from "./content-find.ts";
|
|
10
6
|
import { answerFromPage } from "./page-query.ts";
|
|
11
7
|
import { rewriteSearchQuery } from "./query-rewrite.ts";
|
|
12
8
|
import { clearCloneCache } from "./github-extract.ts";
|
|
13
|
-
import { ALL_SEARCH_PROVIDERS,
|
|
9
|
+
import { ALL_SEARCH_PROVIDERS, getAllowedSearchProviders, getConfiguredSearchRouting, providerLabel, RESOLVED_SEARCH_PROVIDERS, search, type AttributedSearchResponse, type ProviderAvailability, type SearchProvider, type SearchProviderSelection, type ResolvedSearchProvider } from "./gemini-search.ts";
|
|
14
10
|
export type { ProviderAvailability } from "./gemini-search.ts";
|
|
15
|
-
import
|
|
16
|
-
import { formatSeconds, getWebSearchConfigDir, getWebSearchConfigPath, resolveCuratorNetworkConfig, runWithProxy } from "./utils.ts";
|
|
11
|
+
import { formatSeconds, getWebSearchConfigDir, resolveCuratorNetworkConfig, runWithProxy } from "./utils.ts";
|
|
17
12
|
import {
|
|
18
13
|
clearResults,
|
|
19
14
|
deleteResult,
|
|
20
15
|
generateId,
|
|
21
16
|
getAllResults,
|
|
22
|
-
getResult,
|
|
23
17
|
restoreFromSession,
|
|
24
18
|
storeFetchedContentResult,
|
|
25
|
-
storeResult,
|
|
26
19
|
type QueryResultData,
|
|
27
|
-
type StoredSearchData,
|
|
28
20
|
} from "./storage.ts";
|
|
29
21
|
import { activityMonitor, type ActivityEntry } from "./activity.ts";
|
|
30
22
|
import { startCuratorServer, type CuratorSearchEntry, type CuratorServerHandle, type IndexedCuratorSearchEntry } from "./curator-server.ts";
|
|
@@ -50,6 +42,7 @@ import { isBraveAvailable } from "./brave.ts";
|
|
|
50
42
|
import { isCurrentModelHostedSearchEligible, isOpenAISearchAvailable, isOpenAISubscriptionModelSelected } from "./openai-search.ts";
|
|
51
43
|
import { isParallelAvailable } from "./parallel.ts";
|
|
52
44
|
import { isParallelMcpAvailable } from "./parallel-mcp.ts";
|
|
45
|
+
import { parseStringifiedArrays } from "./tool-arguments.ts";
|
|
53
46
|
import { isTinyFishAvailable } from "./tinyfish.ts";
|
|
54
47
|
import { isSearch1APIAvailable } from "./search1api.ts";
|
|
55
48
|
import { isSearchinfinityAvailable } from "./searchinfinity.ts";
|
|
@@ -63,6 +56,7 @@ import { isKagiAvailable } from "./kagi.ts";
|
|
|
63
56
|
import { isBochaAvailable } from "./bocha.ts";
|
|
64
57
|
import { isOllamaAvailable } from "./ollama.ts";
|
|
65
58
|
import { isSearXNGAvailable } from "./searxng.ts";
|
|
59
|
+
import { isDegoogAvailable } from "./degoog.ts";
|
|
66
60
|
import { isDuckDuckGoAvailable } from "./duckduckgo.ts";
|
|
67
61
|
import { isAnySearchAvailable } from "./anysearch.ts";
|
|
68
62
|
import { isXaiSearchAvailable } from "./xai-search.ts";
|
|
@@ -73,6 +67,7 @@ import { isSerpBaseAvailable } from "./serpbase.ts";
|
|
|
73
67
|
import { isSerpApiAvailable } from "./serpapi.ts";
|
|
74
68
|
import { isSerperAvailable } from "./serper.ts";
|
|
75
69
|
import { isSerplyAvailable } from "./serply.ts";
|
|
70
|
+
import { isKeenableAvailable } from "./keenable.ts";
|
|
76
71
|
import { isBaizhiAvailable } from "./baizhi.ts";
|
|
77
72
|
import { isZaiAvailable } from "./zai.ts";
|
|
78
73
|
import { isValyuAvailable } from "./valyu.ts";
|
|
@@ -80,15 +75,38 @@ import { isXcrawlAvailable } from "./xcrawl.ts";
|
|
|
80
75
|
import { buildSearchErrorPlan, type SearchErrorDetails, type SearchErrorPlan } from "./render-search-error.ts";
|
|
81
76
|
import { findModelWithProviderRouting, isModelInScope, splitThinkingSuffix } from "./summary-model-scope.ts";
|
|
82
77
|
import { registerCuratorRunLifecycle, resolveWebSearchWorkflow, type WebSearchWorkflow } from "./curator-run.ts";
|
|
83
|
-
import {
|
|
84
|
-
buildResearchArtifact,
|
|
85
|
-
withClaimAssessment,
|
|
86
|
-
storeResearchArtifact,
|
|
87
|
-
getResearchArtifact,
|
|
88
|
-
type RecencyFilter,
|
|
89
|
-
type ResearchArtifact,
|
|
90
|
-
} from "./source-check.ts";
|
|
91
78
|
import { registerWebToolActivation } from "./tool-activation.ts";
|
|
79
|
+
import {
|
|
80
|
+
createWebToolCore,
|
|
81
|
+
DEFAULT_TOOL_NAMES,
|
|
82
|
+
expandQueryString,
|
|
83
|
+
fetchAllContent,
|
|
84
|
+
fetchUncoveredContent,
|
|
85
|
+
getMaxInlineContentChars,
|
|
86
|
+
isToolEnabled,
|
|
87
|
+
loadConfig,
|
|
88
|
+
markToolError,
|
|
89
|
+
normalizeProviderInput,
|
|
90
|
+
normalizeQueryList,
|
|
91
|
+
normalizeRecencyFilter,
|
|
92
|
+
parseConfigRoot,
|
|
93
|
+
registeredFetchToolNames,
|
|
94
|
+
resolveFetchModeConfig,
|
|
95
|
+
resolveRequestedProvider,
|
|
96
|
+
runSearchQueries,
|
|
97
|
+
storedContentSourceNames,
|
|
98
|
+
stripThumbnails,
|
|
99
|
+
toCuratorProvider,
|
|
100
|
+
WEB_SEARCH_CONFIG_PATH,
|
|
101
|
+
withRegisteredFetchOptions,
|
|
102
|
+
type FetchedContentData,
|
|
103
|
+
type FetchMode,
|
|
104
|
+
type SearchReturnOptions,
|
|
105
|
+
type SummaryWorkflow,
|
|
106
|
+
type ToolNames,
|
|
107
|
+
type WebSearchCallOptions,
|
|
108
|
+
type WebSearchConfig,
|
|
109
|
+
} from "./web-tool-core.ts";
|
|
92
110
|
|
|
93
111
|
// Match pi-ai's StringEnum without loading its compat barrel during registration.
|
|
94
112
|
function StringEnum<T extends string[]>(values: T, options?: { description?: string; default?: T[number] }) {
|
|
@@ -102,33 +120,33 @@ function StringEnum<T extends string[]>(values: T, options?: { description?: str
|
|
|
102
120
|
|
|
103
121
|
type ExtensionTheme = ExtensionContext["ui"]["theme"];
|
|
104
122
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
123
|
+
// structuredContent shapes that codemode scripts receive (web-tool-contract.ts),
|
|
124
|
+
// on success and on isError results.
|
|
125
|
+
const nullableString = (description: string) => Type.Union([Type.String(), Type.Null()], { description });
|
|
126
|
+
const webSearchOutputSchema = Type.Object({
|
|
127
|
+
responseId: Type.String({ description: "Id of the stored search results" }),
|
|
128
|
+
fetchId: nullableString("Stored page content id when includeContent fetched or started fetching content, else null"),
|
|
129
|
+
queries: Type.Array(Type.Object({
|
|
130
|
+
query: Type.String(),
|
|
131
|
+
answer: Type.String({ description: "Provider answer text, empty when the provider returned only results" }),
|
|
132
|
+
error: nullableString("Why this query failed, null on success"),
|
|
133
|
+
provider: Type.Optional(Type.String()),
|
|
134
|
+
providers: Type.Optional(Type.Array(Type.String())),
|
|
135
|
+
results: Type.Array(Type.Object({ title: Type.String(), url: Type.String(), snippet: Type.String() })),
|
|
136
|
+
})),
|
|
137
|
+
});
|
|
138
|
+
const fetchContentOutputSchema = Type.Object({
|
|
139
|
+
responseId: nullableString("Id of the stored content, null when nothing was stored"),
|
|
140
|
+
urls: Type.Array(Type.Object({
|
|
141
|
+
url: Type.String(),
|
|
142
|
+
title: Type.String(),
|
|
143
|
+
content: Type.String({ description: "Full extracted content, not limited by the inline character cap" }),
|
|
144
|
+
error: nullableString("Why this URL failed, null on success"),
|
|
145
|
+
mimeType: Type.Optional(Type.String()),
|
|
146
|
+
status: Type.Optional(Type.Number()),
|
|
147
|
+
duration: Type.Optional(Type.Number()),
|
|
148
|
+
})),
|
|
149
|
+
});
|
|
132
150
|
|
|
133
151
|
/** Shared collapsed/expanded renderer for an error/cancel plan produced by
|
|
134
152
|
* buildSearchErrorPlan(). Used by every tool renderResult's error branch so
|
|
@@ -148,60 +166,8 @@ function renderSearchErrorPlan(plan: SearchErrorPlan, expanded: boolean, theme:
|
|
|
148
166
|
return box;
|
|
149
167
|
}
|
|
150
168
|
|
|
151
|
-
interface WebSearchConfig {
|
|
152
|
-
anysearchApiKey?: unknown;
|
|
153
|
-
xcrawlApiKey?: unknown;
|
|
154
|
-
brightdataApiKey?: unknown;
|
|
155
|
-
brightdataSerpZone?: unknown;
|
|
156
|
-
kagiApiKey?: unknown;
|
|
157
|
-
ollamaApiKey?: unknown;
|
|
158
|
-
serpbaseApiKey?: unknown;
|
|
159
|
-
serpapiApiKey?: unknown;
|
|
160
|
-
serperApiKey?: unknown;
|
|
161
|
-
serplyApiKey?: unknown;
|
|
162
|
-
youApiKey?: unknown;
|
|
163
|
-
baizhiApiKey?: unknown;
|
|
164
|
-
zaiApiKey?: unknown;
|
|
165
|
-
tinyfishApiKey?: unknown;
|
|
166
|
-
valyuApiKey?: unknown;
|
|
167
|
-
xaiApiKey?: unknown;
|
|
168
|
-
provider?: unknown;
|
|
169
|
-
searchProvider?: unknown;
|
|
170
|
-
workflow?: string;
|
|
171
|
-
curatorTimeoutSeconds?: unknown;
|
|
172
|
-
autoOpenBrowser?: unknown;
|
|
173
|
-
curatorRemote?: unknown;
|
|
174
|
-
summaryModel?: string;
|
|
175
|
-
summaryGenerationDeadlineMs?: unknown;
|
|
176
|
-
summaryInstructions?: unknown;
|
|
177
|
-
maxInlineContentChars?: unknown;
|
|
178
|
-
fetch?: {
|
|
179
|
-
defaultMode?: unknown;
|
|
180
|
-
allowedModes?: unknown;
|
|
181
|
-
};
|
|
182
|
-
webSearch?: {
|
|
183
|
-
enabled?: boolean;
|
|
184
|
-
allowedProviders?: unknown;
|
|
185
|
-
};
|
|
186
|
-
tools?: Partial<Record<keyof ToolNames, { enabled?: boolean }>>;
|
|
187
|
-
toolActivation?: unknown;
|
|
188
|
-
commands?: Partial<Record<"websearch" | "curator" | "search" | "google-account", { enabled?: boolean }>>;
|
|
189
|
-
toolNames?: Partial<ToolNames>;
|
|
190
|
-
shortcuts?: {
|
|
191
|
-
curate?: KeyId;
|
|
192
|
-
activity?: KeyId;
|
|
193
|
-
};
|
|
194
|
-
ssrf?: {
|
|
195
|
-
/** CIDR ranges exempted from the SSRF guard (e.g. fake-IP proxy ranges). */
|
|
196
|
-
allowRanges?: string[];
|
|
197
|
-
/** Skip local hostname DNS preflight when an HTTP(S)_PROXY env var applies. */
|
|
198
|
-
trustEnvProxy?: boolean;
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
|
|
202
169
|
type CuratorWorkflow = "summary-review";
|
|
203
170
|
export type CuratorProvider = SearchProvider;
|
|
204
|
-
type SummaryWorkflow = "summary-review" | "auto-summary";
|
|
205
171
|
|
|
206
172
|
interface CuratorBootstrap {
|
|
207
173
|
availableProviders: ProviderAvailability;
|
|
@@ -209,25 +175,6 @@ interface CuratorBootstrap {
|
|
|
209
175
|
timeoutSeconds: number;
|
|
210
176
|
}
|
|
211
177
|
|
|
212
|
-
function parseConfigRoot(raw: string): Record<string, unknown> {
|
|
213
|
-
let parsed: unknown;
|
|
214
|
-
try {
|
|
215
|
-
parsed = JSON.parse(raw);
|
|
216
|
-
} catch (err) {
|
|
217
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
218
|
-
throw new Error(`Failed to parse ${WEB_SEARCH_CONFIG_PATH}: ${message}`);
|
|
219
|
-
}
|
|
220
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
221
|
-
throw new Error(`Invalid config in ${WEB_SEARCH_CONFIG_PATH}: expected a JSON object`);
|
|
222
|
-
}
|
|
223
|
-
return parsed as Record<string, unknown>;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
function loadConfig(): WebSearchConfig {
|
|
227
|
-
if (!existsSync(WEB_SEARCH_CONFIG_PATH)) return {};
|
|
228
|
-
return parseConfigRoot(readFileSync(WEB_SEARCH_CONFIG_PATH, "utf-8")) as WebSearchConfig;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
178
|
function saveConfig(updates: Partial<WebSearchConfig>): void {
|
|
232
179
|
let config: Record<string, unknown> = {};
|
|
233
180
|
if (existsSync(WEB_SEARCH_CONFIG_PATH)) {
|
|
@@ -240,57 +187,18 @@ function saveConfig(updates: Partial<WebSearchConfig>): void {
|
|
|
240
187
|
writeFileSync(WEB_SEARCH_CONFIG_PATH, JSON.stringify(config, null, 2) + "\n");
|
|
241
188
|
}
|
|
242
189
|
|
|
243
|
-
type ToolNames = {
|
|
244
|
-
webSearch: string;
|
|
245
|
-
sourceCheck: string;
|
|
246
|
-
fetchContent: string;
|
|
247
|
-
getSearchContent: string;
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
const DEFAULT_TOOL_NAMES: ToolNames = {
|
|
251
|
-
webSearch: "web_search",
|
|
252
|
-
sourceCheck: "source_check",
|
|
253
|
-
fetchContent: "fetch_content",
|
|
254
|
-
getSearchContent: "get_search_content",
|
|
255
|
-
};
|
|
256
190
|
const TOOL_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/;
|
|
257
191
|
const DEFAULT_SHORTCUTS = { curate: "ctrl+shift+s", activity: "ctrl+shift+w" } satisfies Record<string, KeyId>;
|
|
258
192
|
const DEFAULT_CURATOR_TIMEOUT_SECONDS = 20;
|
|
259
193
|
const DEFAULT_REMOTE_CURATOR_TIMEOUT_SECONDS = 60;
|
|
260
194
|
const MAX_CURATOR_TIMEOUT_SECONDS = 600;
|
|
261
195
|
const MAX_SUMMARY_GENERATION_DEADLINE_MS = 600_000;
|
|
262
|
-
const SEARCH_QUERY_CONCURRENCY = 3;
|
|
263
|
-
const FETCH_MODES = ["readable", "raw", "answer"] as const;
|
|
264
|
-
type FetchMode = typeof FETCH_MODES[number];
|
|
265
196
|
const FETCH_MODE_DESCRIPTIONS: Record<FetchMode, string> = {
|
|
266
197
|
readable: "extract readable content as markdown",
|
|
267
198
|
raw: "return the exact textual body using direct HTTP only",
|
|
268
199
|
answer: "answer a prompt using only fetched content",
|
|
269
200
|
};
|
|
270
201
|
|
|
271
|
-
function resolveFetchModeConfig(config: WebSearchConfig): { defaultMode: FetchMode; allowedModes: FetchMode[] } {
|
|
272
|
-
const configuredModes = config.fetch?.allowedModes ?? FETCH_MODES;
|
|
273
|
-
if (!Array.isArray(configuredModes) || configuredModes.length === 0 || configuredModes.some(mode => !FETCH_MODES.includes(mode as FetchMode))) {
|
|
274
|
-
throw new Error(`fetch.allowedModes in ${WEB_SEARCH_CONFIG_PATH} must be a non-empty array containing only "readable", "raw", or "answer"`);
|
|
275
|
-
}
|
|
276
|
-
const allowedModes = configuredModes as FetchMode[];
|
|
277
|
-
const duplicateMode = allowedModes.find((mode, index) => allowedModes.indexOf(mode) !== index);
|
|
278
|
-
if (duplicateMode) {
|
|
279
|
-
throw new Error(`fetch.allowedModes in ${WEB_SEARCH_CONFIG_PATH} must not contain duplicates: "${duplicateMode}"`);
|
|
280
|
-
}
|
|
281
|
-
const defaultMode = config.fetch?.defaultMode ?? "readable";
|
|
282
|
-
if (!allowedModes.includes(defaultMode as FetchMode)) {
|
|
283
|
-
throw new Error(`fetch.defaultMode in ${WEB_SEARCH_CONFIG_PATH} must be one of fetch.allowedModes`);
|
|
284
|
-
}
|
|
285
|
-
return { defaultMode: defaultMode as FetchMode, allowedModes };
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// Limit each batch independently so separate Pi tool calls can still run in parallel.
|
|
289
|
-
function runSearchQueries<T>(queries: string[], run: (query: string, index: number) => Promise<T>): Promise<T[]> {
|
|
290
|
-
const limit = pLimit(SEARCH_QUERY_CONCURRENCY);
|
|
291
|
-
return Promise.all(queries.map((query, index) => limit(() => run(query, index))));
|
|
292
|
-
}
|
|
293
|
-
|
|
294
202
|
// Keep primary query indexes stable for curator slots, then interleave additional
|
|
295
203
|
// provider entries deterministically instead of assigning by completion order.
|
|
296
204
|
function curatorResultIndex(queryIndex: number, entryIndex: number, queryCount: number): number {
|
|
@@ -308,23 +216,10 @@ function searchProviderSchema(description: string, allowedProviders: readonly Re
|
|
|
308
216
|
], { description });
|
|
309
217
|
}
|
|
310
218
|
|
|
311
|
-
function isToolEnabled(config: WebSearchConfig, key: keyof ToolNames): boolean {
|
|
312
|
-
const override = config.tools?.[key]?.enabled;
|
|
313
|
-
if (typeof override === "boolean") return override;
|
|
314
|
-
return key !== "webSearch" && key !== "sourceCheck" || config.webSearch?.enabled !== false;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
219
|
function isCommandEnabled(config: WebSearchConfig, name: "websearch" | "curator" | "search" | "google-account"): boolean {
|
|
318
220
|
return config.commands?.[name]?.enabled !== false;
|
|
319
221
|
}
|
|
320
222
|
|
|
321
|
-
function joinToolNames(names: string[]): string {
|
|
322
|
-
if (names.length === 0) return "stored content";
|
|
323
|
-
if (names.length === 1) return names[0];
|
|
324
|
-
if (names.length === 2) return `${names[0]} or ${names[1]}`;
|
|
325
|
-
return `${names.slice(0, -1).join(", ")}, or ${names[names.length - 1]}`;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
223
|
function resolveToolNames(config: WebSearchConfig): ToolNames {
|
|
329
224
|
if (config.toolNames !== undefined && (!config.toolNames || typeof config.toolNames !== "object" || Array.isArray(config.toolNames))) {
|
|
330
225
|
throw new Error(`toolNames in ${WEB_SEARCH_CONFIG_PATH} must be an object`);
|
|
@@ -363,40 +258,12 @@ function loadConfigForExtensionInit(): WebSearchConfig {
|
|
|
363
258
|
}
|
|
364
259
|
}
|
|
365
260
|
|
|
366
|
-
function normalizeProviderInput(value: unknown, label = "provider"): SearchProviderSelection | undefined {
|
|
367
|
-
if (value === undefined) return undefined;
|
|
368
|
-
return normalizeSearchProviderSelection(value, label);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
function resolveRequestedProvider(requested: unknown): SearchProviderSelection {
|
|
372
|
-
const normalizedRequested = normalizeProviderInput(requested);
|
|
373
|
-
if (normalizedRequested && normalizedRequested !== "auto") {
|
|
374
|
-
assertSearchProviderSelectionAllowed(normalizedRequested, "Requested provider");
|
|
375
|
-
return normalizedRequested;
|
|
376
|
-
}
|
|
377
|
-
const config = loadConfig();
|
|
378
|
-
const provider = normalizeProviderInput(config.searchProvider ?? config.provider, `provider in ${WEB_SEARCH_CONFIG_PATH}`) ?? "auto";
|
|
379
|
-
assertSearchProviderSelectionAllowed(provider, `configured provider in ${WEB_SEARCH_CONFIG_PATH}`);
|
|
380
|
-
return provider;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
function toCuratorProvider(provider: SearchProviderSelection): SearchProvider | undefined {
|
|
384
|
-
if (Array.isArray(provider)) return "all";
|
|
385
|
-
return provider === "auto" ? undefined : provider;
|
|
386
|
-
}
|
|
387
|
-
|
|
388
261
|
function resolveCuratorSearchProvider(requested: unknown, current: SearchProviderSelection): SearchProviderSelection {
|
|
389
262
|
const normalized = normalizeProviderInput(requested);
|
|
390
263
|
if (!normalized || normalized === "auto") return current;
|
|
391
264
|
return normalized === "all" && Array.isArray(current) ? current : normalized;
|
|
392
265
|
}
|
|
393
266
|
|
|
394
|
-
function normalizeRecencyFilter(value: unknown): RecencyFilter | undefined {
|
|
395
|
-
return value === "day" || value === "week" || value === "month" || value === "year"
|
|
396
|
-
? value
|
|
397
|
-
: undefined;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
267
|
function normalizeCuratorTimeoutSeconds(value: unknown): number | undefined {
|
|
401
268
|
if (typeof value !== "number" || !Number.isFinite(value)) return undefined;
|
|
402
269
|
const normalized = Math.floor(value);
|
|
@@ -404,43 +271,6 @@ function normalizeCuratorTimeoutSeconds(value: unknown): number | undefined {
|
|
|
404
271
|
return Math.min(normalized, MAX_CURATOR_TIMEOUT_SECONDS);
|
|
405
272
|
}
|
|
406
273
|
|
|
407
|
-
function normalizeQueryList(queryList: unknown[]): string[] {
|
|
408
|
-
const normalized: string[] = [];
|
|
409
|
-
for (const query of queryList) {
|
|
410
|
-
if (typeof query !== "string") continue;
|
|
411
|
-
const trimmed = query.trim();
|
|
412
|
-
if (trimmed.length > 0) normalized.push(trimmed);
|
|
413
|
-
}
|
|
414
|
-
return normalized;
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
// Some local models serialize a multi-query list into the single-string `query`
|
|
418
|
-
// field as a JSON array (query: "[\"a\", \"b\"]") instead of using the
|
|
419
|
-
// `queries` parameter. Forwarding that raw string verbatim makes every backend
|
|
420
|
-
// search for the literal array text and return zero results, with no signal to
|
|
421
|
-
// the model that its argument shape was wrong. Expand a string that parses as a
|
|
422
|
-
// JSON array of strings so each element is searched independently.
|
|
423
|
-
function expandQueryString(query: unknown): string[] {
|
|
424
|
-
if (typeof query !== "string") return [];
|
|
425
|
-
const trimmed = query.trim();
|
|
426
|
-
if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
427
|
-
try {
|
|
428
|
-
const parsed: unknown = JSON.parse(trimmed);
|
|
429
|
-
// Only expand an unambiguously string-only array. Mixed or non-string
|
|
430
|
-
// arrays are kept as the literal query so we never silently drop
|
|
431
|
-
// members or collapse them into an empty search.
|
|
432
|
-
if (Array.isArray(parsed) && parsed.every((entry): entry is string => typeof entry === "string")) {
|
|
433
|
-
return parsed
|
|
434
|
-
.map((entry) => entry.trim())
|
|
435
|
-
.filter((entry) => entry.length > 0);
|
|
436
|
-
}
|
|
437
|
-
} catch {
|
|
438
|
-
// Not JSON — treat as a literal query string.
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
return [query];
|
|
442
|
-
}
|
|
443
|
-
|
|
444
274
|
function getCuratorTimeoutSeconds(): number {
|
|
445
275
|
const source = loadConfig();
|
|
446
276
|
const explicit = normalizeCuratorTimeoutSeconds(source.curatorTimeoutSeconds);
|
|
@@ -492,6 +322,7 @@ async function getProviderAvailability(ctx: ExtensionContext): Promise<ProviderA
|
|
|
492
322
|
bocha: allowedProviders.has("bocha") && isBochaAvailable(),
|
|
493
323
|
ollama: allowedProviders.has("ollama") && isOllamaAvailable(),
|
|
494
324
|
searxng: allowedProviders.has("searxng") && isSearXNGAvailable(),
|
|
325
|
+
degoog: allowedProviders.has("degoog") && isDegoogAvailable(),
|
|
495
326
|
duckduckgo: allowedProviders.has("duckduckgo") && isDuckDuckGoAvailable(),
|
|
496
327
|
perplexity: allowedProviders.has("perplexity") && isPerplexityAvailable(),
|
|
497
328
|
exa: allowedProviders.has("exa") && isExaAvailable(),
|
|
@@ -509,6 +340,7 @@ async function getProviderAvailability(ctx: ExtensionContext): Promise<ProviderA
|
|
|
509
340
|
baizhi: allowedProviders.has("baizhi") && isBaizhiAvailable(),
|
|
510
341
|
zai: allowedProviders.has("zai") && isZaiAvailable(),
|
|
511
342
|
valyu: allowedProviders.has("valyu") && isValyuAvailable(),
|
|
343
|
+
keenable: allowedProviders.has("keenable") && isKeenableAvailable(),
|
|
512
344
|
};
|
|
513
345
|
return {
|
|
514
346
|
all: ALL_SEARCH_PROVIDERS.some(provider => provider === "gemini" ? geminiApiAvail : providers[provider]),
|
|
@@ -618,6 +450,7 @@ interface PendingCurate {
|
|
|
618
450
|
numResults?: number;
|
|
619
451
|
recencyFilter?: "day" | "week" | "month" | "year";
|
|
620
452
|
domainFilter?: string[];
|
|
453
|
+
category?: string;
|
|
621
454
|
availableProviders: ProviderAvailability;
|
|
622
455
|
defaultProvider: SearchProvider;
|
|
623
456
|
searchProvider: SearchProviderSelection;
|
|
@@ -635,194 +468,6 @@ interface PendingCurate {
|
|
|
635
468
|
browserOpenError?: string;
|
|
636
469
|
}
|
|
637
470
|
|
|
638
|
-
|
|
639
|
-
const DEFAULT_MAX_INLINE_CONTENT_CHARS = 30_000;
|
|
640
|
-
const MIN_INLINE_CONTENT_CHARS = 1_000;
|
|
641
|
-
const MAX_INLINE_CONTENT_CHARS = 200_000;
|
|
642
|
-
|
|
643
|
-
function getMaxInlineContentChars(config = loadConfig()): number {
|
|
644
|
-
const value = config.maxInlineContentChars;
|
|
645
|
-
if (typeof value !== "number" || !Number.isFinite(value) || !Number.isInteger(value) || value < MIN_INLINE_CONTENT_CHARS) {
|
|
646
|
-
return DEFAULT_MAX_INLINE_CONTENT_CHARS;
|
|
647
|
-
}
|
|
648
|
-
return Math.min(value, MAX_INLINE_CONTENT_CHARS);
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
function stripThumbnails(results: ExtractedContent[]): ExtractedContent[] {
|
|
652
|
-
return results.map(({ thumbnail, frames, ...rest }) => rest);
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
function storeFetchResult(pi: { appendEntry(type: string, data: unknown): void }, responseId: string, data: StoredSearchData & { type: "fetch"; urls: ExtractedContent[] }, authProfile?: AuthFetchProfile): boolean {
|
|
656
|
-
if (authProfile?.cache === "off") return false;
|
|
657
|
-
pi.appendEntry("web-search-results", storeFetchedContentResult(responseId, data));
|
|
658
|
-
return true;
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
function initialContentSlice(content: string, maxChars: number): {
|
|
662
|
-
text: string;
|
|
663
|
-
endOffset: number;
|
|
664
|
-
totalBytes: number;
|
|
665
|
-
totalLines: number;
|
|
666
|
-
shownBytes: number;
|
|
667
|
-
shownLines: number;
|
|
668
|
-
} {
|
|
669
|
-
let endOffset = Math.min(content.length, maxChars);
|
|
670
|
-
if (endOffset < content.length) {
|
|
671
|
-
const lineBreak = content.lastIndexOf("\n", endOffset);
|
|
672
|
-
if (lineBreak >= Math.floor(maxChars * 0.8)) endOffset = lineBreak + 1;
|
|
673
|
-
}
|
|
674
|
-
const text = content.slice(0, endOffset);
|
|
675
|
-
return {
|
|
676
|
-
text,
|
|
677
|
-
endOffset,
|
|
678
|
-
totalBytes: Buffer.byteLength(content),
|
|
679
|
-
totalLines: content.length === 0 ? 0 : content.split("\n").length,
|
|
680
|
-
shownBytes: Buffer.byteLength(text),
|
|
681
|
-
shownLines: text.length === 0 ? 0 : text.split("\n").length,
|
|
682
|
-
};
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
function normalizeFindQueries(value: string | string[]): string[] {
|
|
686
|
-
const queries = (Array.isArray(value) ? value : [value]).map(query => query.trim()).filter(Boolean);
|
|
687
|
-
if (queries.length === 0) throw new Error("findText must contain at least one non-empty string");
|
|
688
|
-
return queries;
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
interface GetSearchContentParams {
|
|
692
|
-
responseId: string;
|
|
693
|
-
query?: string;
|
|
694
|
-
queryIndex?: number;
|
|
695
|
-
url?: string;
|
|
696
|
-
urlIndex?: number;
|
|
697
|
-
offset?: number;
|
|
698
|
-
limit?: number;
|
|
699
|
-
findText?: string | string[];
|
|
700
|
-
findMode?: FindMode;
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
type RawGetSearchContentParams = Omit<GetSearchContentParams, "findMode"> & { findMode?: unknown };
|
|
704
|
-
|
|
705
|
-
function normalizeFindMode(value: unknown): FindMode | undefined {
|
|
706
|
-
if (value === undefined) return undefined;
|
|
707
|
-
if (value === "exact" || value === "case-insensitive" || value === "fuzzy") return value;
|
|
708
|
-
throw new Error('findMode must be "exact", "case-insensitive", or "fuzzy"');
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
function normalizeGetSearchContentParams(params: RawGetSearchContentParams): GetSearchContentParams {
|
|
712
|
-
const normalized: GetSearchContentParams = { ...params, findMode: normalizeFindMode(params.findMode) };
|
|
713
|
-
|
|
714
|
-
if (normalized.query?.trim() === "") delete normalized.query;
|
|
715
|
-
if (normalized.url?.trim() === "") delete normalized.url;
|
|
716
|
-
|
|
717
|
-
if (normalized.findText !== undefined) {
|
|
718
|
-
delete normalized.offset;
|
|
719
|
-
delete normalized.limit;
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
return normalized;
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
function formatInputValue(value: unknown): string {
|
|
726
|
-
if (typeof value === "string") return JSON.stringify(value);
|
|
727
|
-
if (typeof value === "number") return Number.isNaN(value) ? "NaN" : String(value);
|
|
728
|
-
try {
|
|
729
|
-
const serialized = JSON.stringify(value);
|
|
730
|
-
return serialized === undefined ? String(value) : serialized;
|
|
731
|
-
} catch {
|
|
732
|
-
return String(value);
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
function formatSearchSummary(results: SearchResult[], answer: string): string {
|
|
737
|
-
if (results.length === 0) {
|
|
738
|
-
return answer ? `${answer}\n\n---\n\n**Sources:**\nNo sources returned.` : "No results found.";
|
|
739
|
-
}
|
|
740
|
-
let output = answer ? `${answer}\n\n---\n\n**Sources:**\n` : "";
|
|
741
|
-
output += results.map((r, i) => `${i + 1}. ${r.title}\n ${r.url}`).join("\n\n");
|
|
742
|
-
return output;
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
function formatSourceCheckResult(artifact: ResearchArtifact, getSearchContentTool: string | null = DEFAULT_TOOL_NAMES.getSearchContent): string {
|
|
746
|
-
const assessment = artifact.claims?.[0];
|
|
747
|
-
const lines = [`# Source check: ${artifact.query}`, ""];
|
|
748
|
-
if (assessment) {
|
|
749
|
-
lines.push(`**Status:** ${assessment.status} (confidence ${assessment.confidence.toFixed(2)})`);
|
|
750
|
-
lines.push(`**Rationale:** ${assessment.rationale}`);
|
|
751
|
-
if (assessment.supporting_passages.length > 0) lines.push(`**Supporting passages:** ${assessment.supporting_passages.join(", ")}`);
|
|
752
|
-
if (assessment.contradicting_passages.length > 0) lines.push(`**Contradicting passages:** ${assessment.contradicting_passages.join(", ")}`);
|
|
753
|
-
lines.push("");
|
|
754
|
-
}
|
|
755
|
-
if (artifact.sources.length > 0) {
|
|
756
|
-
lines.push("## Sources");
|
|
757
|
-
for (const source of artifact.sources) lines.push(`${source.rank}. [${source.quality}] ${source.title}\n ${source.url}`);
|
|
758
|
-
lines.push("");
|
|
759
|
-
}
|
|
760
|
-
if (artifact.errors?.length) lines.push(`Search errors: ${artifact.errors.map((entry) => `${entry.query}: ${entry.error}`).join("; ")}`);
|
|
761
|
-
lines.push(getSearchContentTool
|
|
762
|
-
? `Artifact responseId: ${artifact.id} (retrievable via ${getSearchContentTool}).`
|
|
763
|
-
: `Artifact responseId: ${artifact.id}. Content retrieval is not registered.`);
|
|
764
|
-
return lines.join("\n");
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
function duplicateQuerySet(results: QueryResultData[]): Set<string> {
|
|
768
|
-
const counts = new Map<string, number>();
|
|
769
|
-
for (const result of results) {
|
|
770
|
-
counts.set(result.query, (counts.get(result.query) ?? 0) + 1);
|
|
771
|
-
}
|
|
772
|
-
const duplicates = new Set<string>();
|
|
773
|
-
for (const [query, count] of counts) {
|
|
774
|
-
if (count > 1) duplicates.add(query);
|
|
775
|
-
}
|
|
776
|
-
return duplicates;
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
function formatQueryHeader(query: string, provider: string | undefined, duplicateQueries: Set<string>): string {
|
|
780
|
-
const suffix = duplicateQueries.has(query) && provider ? ` (${provider})` : "";
|
|
781
|
-
return `## Query: "${query}"${suffix}\n\n`;
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
function hasFullInlineCoverage(urls: string[], inlineContent: ExtractedContent[] | undefined): boolean {
|
|
785
|
-
if (!inlineContent || inlineContent.length === 0) return false;
|
|
786
|
-
const coveredUrls = new Set(inlineContent.map(c => c.url));
|
|
787
|
-
return urls.every(url => coveredUrls.has(url));
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
function formatFullResults(queryData: QueryResultData): string {
|
|
791
|
-
let output = `## Results for: "${queryData.query}"\n\n`;
|
|
792
|
-
const providers = queryData.providers ?? (queryData.provider ? [queryData.provider] : []);
|
|
793
|
-
if (providers.length > 0) output += `**Provider${providers.length === 1 ? "" : "s"}:** ${providers.join(", ")}\n\n`;
|
|
794
|
-
if (queryData.answer) {
|
|
795
|
-
output += `${queryData.answer}\n\n---\n\n`;
|
|
796
|
-
}
|
|
797
|
-
for (const r of queryData.results) {
|
|
798
|
-
output += `### ${r.title}\n${r.url}${r.snippet ? `\n\n${r.snippet}` : ""}\n\n`;
|
|
799
|
-
}
|
|
800
|
-
return output;
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
function boundSearchPresentation(
|
|
804
|
-
text: string,
|
|
805
|
-
guidance: string,
|
|
806
|
-
truncationGuidance: string,
|
|
807
|
-
maxChars: number,
|
|
808
|
-
): { text: string; truncated: boolean; originalChars: number; returnedChars: number; omittedChars: number } {
|
|
809
|
-
const fullText = `${text}${guidance}`;
|
|
810
|
-
if (fullText.length <= maxChars) {
|
|
811
|
-
return { text: fullText, truncated: false, originalChars: text.length, returnedChars: text.length, omittedChars: 0 };
|
|
812
|
-
}
|
|
813
|
-
const marker = `\n\n---\n[Output truncated.]${truncationGuidance}`;
|
|
814
|
-
// Reserve marker space so the complete model-visible response never exceeds the configured ceiling.
|
|
815
|
-
const prefixLength = maxChars - marker.length;
|
|
816
|
-
const bounded = `${text.slice(0, prefixLength)}${marker}`;
|
|
817
|
-
return {
|
|
818
|
-
text: bounded,
|
|
819
|
-
truncated: true,
|
|
820
|
-
originalChars: text.length,
|
|
821
|
-
returnedChars: prefixLength,
|
|
822
|
-
omittedChars: text.length - prefixLength,
|
|
823
|
-
};
|
|
824
|
-
}
|
|
825
|
-
|
|
826
471
|
function abortPendingFetches(): void {
|
|
827
472
|
for (const controller of pendingFetches.values()) {
|
|
828
473
|
controller.abort();
|
|
@@ -1098,17 +743,21 @@ export default function (pi: ExtensionAPI) {
|
|
|
1098
743
|
const sourceCheckEnabled = isToolEnabled(initConfig, "sourceCheck");
|
|
1099
744
|
const fetchContentEnabled = isToolEnabled(initConfig, "fetchContent");
|
|
1100
745
|
const getSearchContentEnabled = isToolEnabled(initConfig, "getSearchContent");
|
|
746
|
+
const coreSettings = {
|
|
747
|
+
toolNames,
|
|
748
|
+
enabledTools: {
|
|
749
|
+
webSearch: webSearchEnabled,
|
|
750
|
+
sourceCheck: sourceCheckEnabled,
|
|
751
|
+
fetchContent: fetchContentEnabled,
|
|
752
|
+
getSearchContent: getSearchContentEnabled,
|
|
753
|
+
},
|
|
754
|
+
maxInlineContentChars: getMaxInlineContentChars(initConfig),
|
|
755
|
+
fetchModes: fetchModeConfig,
|
|
756
|
+
};
|
|
1101
757
|
// Names as registered this session, so fetch failure guidance never points
|
|
1102
758
|
// at tools that are disabled or were renamed after init.
|
|
1103
|
-
const registeredToolNames =
|
|
1104
|
-
|
|
1105
|
-
...(fetchContentEnabled ? { fetchContent: toolNames.fetchContent } : {}),
|
|
1106
|
-
};
|
|
1107
|
-
const storedContentSources = joinToolNames([
|
|
1108
|
-
...(webSearchEnabled ? [toolNames.webSearch] : []),
|
|
1109
|
-
...(sourceCheckEnabled ? [toolNames.sourceCheck] : []),
|
|
1110
|
-
...(fetchContentEnabled ? [toolNames.fetchContent] : []),
|
|
1111
|
-
]);
|
|
759
|
+
const registeredToolNames = registeredFetchToolNames(coreSettings);
|
|
760
|
+
const storedContentSources = storedContentSourceNames(coreSettings);
|
|
1112
761
|
const searchQueryDescription = webSearchEnabled
|
|
1113
762
|
? `Get content for this query (${toolNames.webSearch})`
|
|
1114
763
|
: "Get content for a stored search query";
|
|
@@ -1121,13 +770,13 @@ export default function (pi: ExtensionAPI) {
|
|
|
1121
770
|
const curateKey = initConfig.shortcuts?.curate || DEFAULT_SHORTCUTS.curate;
|
|
1122
771
|
const activityKey = initConfig.shortcuts?.activity || DEFAULT_SHORTCUTS.activity;
|
|
1123
772
|
|
|
1124
|
-
function startBackgroundFetch(urls: string[], proxy?: string): string | null {
|
|
773
|
+
function startBackgroundFetch(urls: string[], proxy?: string, provided?: ExtractedContent[]): string | null {
|
|
1125
774
|
if (urls.length === 0) return null;
|
|
1126
775
|
const fetchId = generateId();
|
|
1127
776
|
const controller = new AbortController();
|
|
1128
777
|
pendingFetches.set(fetchId, controller);
|
|
1129
778
|
Promise.resolve()
|
|
1130
|
-
.then(() => runWithProxy(proxy, () => fetchAllContent(
|
|
779
|
+
.then(() => fetchUncoveredContent(urls, provided, missing => runWithProxy(proxy, () => fetchAllContent(missing, controller.signal, withRegisteredFetchOptions(undefined, registeredToolNames, proxy)))))
|
|
1131
780
|
.then((fetched) => {
|
|
1132
781
|
if (!sessionActive || !pendingFetches.has(fetchId)) return;
|
|
1133
782
|
const data = {
|
|
@@ -1135,7 +784,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1135
784
|
type: "fetch",
|
|
1136
785
|
timestamp: Date.now(),
|
|
1137
786
|
urls: stripThumbnails(fetched),
|
|
1138
|
-
} satisfies
|
|
787
|
+
} satisfies FetchedContentData;
|
|
1139
788
|
pi.appendEntry("web-search-results", storeFetchedContentResult(fetchId, data));
|
|
1140
789
|
const ok = fetched.filter(f => !f.error).length;
|
|
1141
790
|
const availability = ok === fetched.length
|
|
@@ -1171,29 +820,18 @@ export default function (pi: ExtensionAPI) {
|
|
|
1171
820
|
return fetchId;
|
|
1172
821
|
}
|
|
1173
822
|
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
}
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
results: QueryResultData[];
|
|
1187
|
-
urls: string[];
|
|
1188
|
-
includeContent: boolean;
|
|
1189
|
-
inlineContent?: ExtractedContent[];
|
|
1190
|
-
curated?: boolean;
|
|
1191
|
-
curatedFrom?: number;
|
|
1192
|
-
workflow?: SummaryWorkflow;
|
|
1193
|
-
approvedSummary?: string;
|
|
1194
|
-
summaryMeta?: SummaryMeta;
|
|
1195
|
-
proxy?: string;
|
|
1196
|
-
}
|
|
823
|
+
const core = createWebToolCore({
|
|
824
|
+
settings: coreSettings,
|
|
825
|
+
storeFetchedContent(id, data) {
|
|
826
|
+
pi.appendEntry("web-search-results", storeFetchedContentResult(id, data));
|
|
827
|
+
},
|
|
828
|
+
publishResult(data) {
|
|
829
|
+
pi.appendEntry("web-search-results", data);
|
|
830
|
+
},
|
|
831
|
+
startBackgroundFetch,
|
|
832
|
+
answerFromPage: (request, ctx, signal) => answerFromPage(request, ctx!, signal),
|
|
833
|
+
});
|
|
834
|
+
const buildSearchReturn = core.buildSearchReturn;
|
|
1197
835
|
|
|
1198
836
|
function normalizeSummaryMeta(meta: SummaryMeta | undefined, summaryText: string): SummaryMeta {
|
|
1199
837
|
const normalizedText = summaryText.trim();
|
|
@@ -1396,127 +1034,6 @@ export default function (pi: ExtensionAPI) {
|
|
|
1396
1034
|
};
|
|
1397
1035
|
}
|
|
1398
1036
|
|
|
1399
|
-
function buildSearchReturn(opts: SearchReturnOptions): AgentToolResult<Record<string, unknown>> {
|
|
1400
|
-
const sc = opts.results.filter(r => !r.error).length;
|
|
1401
|
-
const tr = opts.results.reduce((sum, r) => sum + r.results.length, 0);
|
|
1402
|
-
|
|
1403
|
-
const hasApprovedSummary = typeof opts.approvedSummary === "string" && opts.approvedSummary.trim().length > 0;
|
|
1404
|
-
const maxInlineContentChars = getMaxInlineContentChars(initConfig);
|
|
1405
|
-
let output = "";
|
|
1406
|
-
if (hasApprovedSummary) {
|
|
1407
|
-
output = opts.approvedSummary!.trim();
|
|
1408
|
-
} else {
|
|
1409
|
-
if (opts.curated) {
|
|
1410
|
-
output += "[These results were manually curated by the user in the browser. Use them as-is — do not re-search or discard.]\n\n";
|
|
1411
|
-
}
|
|
1412
|
-
const providerNames = opts.results.map(result => {
|
|
1413
|
-
const providers = result.providers ?? (result.provider ? [result.provider] : []);
|
|
1414
|
-
return providers.join(", ") || "unknown";
|
|
1415
|
-
});
|
|
1416
|
-
output += opts.results.length === 1
|
|
1417
|
-
? `**Provider:** ${providerNames[0]}\n\n`
|
|
1418
|
-
: `**Providers used:** ${providerNames.map((name, index) => `Query ${index + 1}: ${name}`).join("; ")}\n\n`;
|
|
1419
|
-
const duplicateQueries = opts.curated ? duplicateQuerySet(opts.results) : new Set<string>();
|
|
1420
|
-
for (const { query, answer, results, error, provider } of opts.results) {
|
|
1421
|
-
if (opts.queryList.length > 1) {
|
|
1422
|
-
output += opts.curated
|
|
1423
|
-
? formatQueryHeader(query, provider, duplicateQueries)
|
|
1424
|
-
: `## Query: "${query}"\n\n`;
|
|
1425
|
-
}
|
|
1426
|
-
if (error) output += `Error: ${error}\n\n`;
|
|
1427
|
-
else output += formatSearchSummary(results, answer) + "\n\n";
|
|
1428
|
-
}
|
|
1429
|
-
}
|
|
1430
|
-
|
|
1431
|
-
const hasInlineReady = hasFullInlineCoverage(opts.urls, opts.inlineContent);
|
|
1432
|
-
let fetchId: string | null = null;
|
|
1433
|
-
if (hasInlineReady && opts.inlineContent) {
|
|
1434
|
-
fetchId = generateId();
|
|
1435
|
-
const data = {
|
|
1436
|
-
id: fetchId,
|
|
1437
|
-
type: "fetch",
|
|
1438
|
-
timestamp: Date.now(),
|
|
1439
|
-
urls: opts.inlineContent,
|
|
1440
|
-
} satisfies StoredSearchData & { type: "fetch"; urls: ExtractedContent[] };
|
|
1441
|
-
pi.appendEntry("web-search-results", storeFetchedContentResult(fetchId, data));
|
|
1442
|
-
} else if (opts.includeContent) {
|
|
1443
|
-
fetchId = startBackgroundFetch(opts.urls, opts.proxy);
|
|
1444
|
-
}
|
|
1445
|
-
|
|
1446
|
-
const searchId = storeAndPublishSearch(opts.results);
|
|
1447
|
-
const isBackgroundFetch = fetchId !== null && !hasInlineReady;
|
|
1448
|
-
const unboundedPresentation = output.trim();
|
|
1449
|
-
const buildGuidance = (forTruncation: boolean): string => {
|
|
1450
|
-
let value = "";
|
|
1451
|
-
if (hasInlineReady && opts.inlineContent && fetchId) {
|
|
1452
|
-
value += `\n---\nFull content for ${opts.inlineContent.length} sources is ready as responseId "${fetchId}". `;
|
|
1453
|
-
value += getSearchContentEnabled
|
|
1454
|
-
? `Use ${toolNames.getSearchContent}({ responseId: "${fetchId}", urlIndex: 0, offset: 0, limit: ${maxInlineContentChars} }) to retrieve the first bounded page.`
|
|
1455
|
-
: forTruncation ? `Enable ${toolNames.getSearchContent} to retrieve the full stored content.` : "";
|
|
1456
|
-
} else if (isBackgroundFetch && fetchId) {
|
|
1457
|
-
value += `\n---\nContent fetching in background as responseId "${fetchId}". Will notify when ready.`;
|
|
1458
|
-
}
|
|
1459
|
-
if (getSearchContentEnabled || forTruncation) {
|
|
1460
|
-
value += `\n---\nFull search results are stored as responseId "${searchId}". `;
|
|
1461
|
-
value += getSearchContentEnabled
|
|
1462
|
-
? `Use ${toolNames.getSearchContent}({ responseId: "${searchId}", queryIndex: 0, offset: 0, limit: ${maxInlineContentChars} }) to retrieve the first bounded page${opts.results.length > 1 ? `; repeat with queryIndex 1 through ${opts.results.length - 1}` : ""}.`
|
|
1463
|
-
: `Enable ${toolNames.getSearchContent} to retrieve the full stored results.`;
|
|
1464
|
-
}
|
|
1465
|
-
return value;
|
|
1466
|
-
};
|
|
1467
|
-
const presentation = hasApprovedSummary
|
|
1468
|
-
? { text: unboundedPresentation, truncated: false, originalChars: unboundedPresentation.length, returnedChars: unboundedPresentation.length, omittedChars: 0 }
|
|
1469
|
-
: boundSearchPresentation(unboundedPresentation, buildGuidance(false), buildGuidance(true), maxInlineContentChars);
|
|
1470
|
-
|
|
1471
|
-
return {
|
|
1472
|
-
content: [{ type: "text", text: presentation.text }],
|
|
1473
|
-
details: {
|
|
1474
|
-
queries: opts.queryList,
|
|
1475
|
-
queryCount: opts.queryList.length,
|
|
1476
|
-
successfulQueries: sc,
|
|
1477
|
-
totalResults: tr,
|
|
1478
|
-
includeContent: opts.includeContent,
|
|
1479
|
-
fetchId,
|
|
1480
|
-
fetchUrls: isBackgroundFetch ? opts.urls : undefined,
|
|
1481
|
-
searchId,
|
|
1482
|
-
queryProviders: opts.results.map(result => ({
|
|
1483
|
-
query: result.query,
|
|
1484
|
-
providers: result.providers ?? (result.provider ? [result.provider] : []),
|
|
1485
|
-
})),
|
|
1486
|
-
truncated: presentation.truncated,
|
|
1487
|
-
originalChars: presentation.originalChars,
|
|
1488
|
-
returnedChars: presentation.returnedChars,
|
|
1489
|
-
omittedChars: presentation.omittedChars,
|
|
1490
|
-
...(opts.curated ? {
|
|
1491
|
-
curated: true,
|
|
1492
|
-
curatedFrom: opts.curatedFrom,
|
|
1493
|
-
curatedQueries: opts.results.map(r => ({
|
|
1494
|
-
query: r.query,
|
|
1495
|
-
provider: r.provider || null,
|
|
1496
|
-
answer: r.answer || null,
|
|
1497
|
-
sources: r.results.map(s => ({ title: s.title, url: s.url })),
|
|
1498
|
-
error: r.error,
|
|
1499
|
-
})),
|
|
1500
|
-
} : {}),
|
|
1501
|
-
...((opts.workflow && hasApprovedSummary)
|
|
1502
|
-
? {
|
|
1503
|
-
summary: {
|
|
1504
|
-
text: opts.approvedSummary!.trim(),
|
|
1505
|
-
workflow: opts.workflow,
|
|
1506
|
-
model: opts.summaryMeta?.model ?? null,
|
|
1507
|
-
durationMs: opts.summaryMeta?.durationMs ?? 0,
|
|
1508
|
-
tokenEstimate: opts.summaryMeta?.tokenEstimate ?? 0,
|
|
1509
|
-
fallbackUsed: opts.summaryMeta?.fallbackUsed === true,
|
|
1510
|
-
fallbackReason: opts.summaryMeta?.fallbackReason,
|
|
1511
|
-
phase: opts.summaryMeta?.phase,
|
|
1512
|
-
edited: opts.summaryMeta?.edited === true,
|
|
1513
|
-
},
|
|
1514
|
-
}
|
|
1515
|
-
: {}),
|
|
1516
|
-
},
|
|
1517
|
-
};
|
|
1518
|
-
}
|
|
1519
|
-
|
|
1520
1037
|
function filterByQueryIndices(selectedQueryIndices: number[], results: Map<number, QueryResultData>) {
|
|
1521
1038
|
const filteredResults: QueryResultData[] = [];
|
|
1522
1039
|
const filteredUrls: string[] = [];
|
|
@@ -1694,6 +1211,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1694
1211
|
recencyFilter: pc.recencyFilter,
|
|
1695
1212
|
domainFilter: pc.domainFilter,
|
|
1696
1213
|
includeContent: pc.includeContent,
|
|
1214
|
+
category: pc.category,
|
|
1697
1215
|
signal: addSearchSignal,
|
|
1698
1216
|
extensionContext: ctx,
|
|
1699
1217
|
});
|
|
@@ -1818,11 +1336,20 @@ export default function (pi: ExtensionAPI) {
|
|
|
1818
1336
|
},
|
|
1819
1337
|
});
|
|
1820
1338
|
|
|
1821
|
-
|
|
1822
|
-
|
|
1339
|
+
// web_search calls a tool made, such as a codemode script, reach the tool_call
|
|
1340
|
+
// handlers before execute with parentToolCallId set; execute consumes the id.
|
|
1341
|
+
// Ids of calls a later handler blocked are dropped when the session changes.
|
|
1342
|
+
const nestedSearchCallIds = new Set<string>();
|
|
1343
|
+
if (webSearchEnabled) pi.on("tool_call", (event) => {
|
|
1344
|
+
if (event.parentToolCallId && event.toolName === toolNames.webSearch) nestedSearchCallIds.add(event.toolCallId);
|
|
1345
|
+
});
|
|
1346
|
+
|
|
1347
|
+
pi.on("session_start", async (_event, ctx) => { nestedSearchCallIds.clear(); handleSessionChange(ctx); });
|
|
1348
|
+
pi.on("session_tree", async (_event, ctx) => { nestedSearchCallIds.clear(); handleSessionChange(ctx); });
|
|
1823
1349
|
|
|
1824
1350
|
pi.on("session_shutdown", () => {
|
|
1825
1351
|
sessionActive = false;
|
|
1352
|
+
nestedSearchCallIds.clear();
|
|
1826
1353
|
abortPendingFetches();
|
|
1827
1354
|
closeCurator();
|
|
1828
1355
|
clearCloneCache();
|
|
@@ -1837,6 +1364,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1837
1364
|
if (webSearchEnabled) pi.registerTool({
|
|
1838
1365
|
name: toolNames.webSearch,
|
|
1839
1366
|
label: "Web Search",
|
|
1367
|
+
prepareArguments: (args) => parseStringifiedArrays(args, ["provider", "queries", "domainFilter"]) as never,
|
|
1840
1368
|
description:
|
|
1841
1369
|
`Search the web with ${allowedSearchProviders.map(providerLabel).join(", ")}. Provider arrays run simultaneously; ${allPolicyDescription}. The default workflow is none: it returns bounded source-linked search results or provider answers without a curator or generated summary, identifies the providers used, and stores full results for retrieval by responseId. For comprehensive research, prefer queries (plural) with 2-4 varied angles over a single query. When includeContent is true, full page content is fetched in the background. Set workflow to "summary-review" to open the curator with an auto-generated summary draft or "auto-summary" to generate a summary without the browser curator. The configured provider is used when provider is omitted or set to auto; omit provider unless explicitly overriding it.`,
|
|
1842
1370
|
promptSnippet:
|
|
@@ -1850,6 +1378,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1850
1378
|
StringEnum(["day", "week", "month", "year"], { description: "Filter by recency" }),
|
|
1851
1379
|
),
|
|
1852
1380
|
domainFilter: Type.Optional(Type.Array(Type.String(), { description: "Limit to domains (prefix with - to exclude)" })),
|
|
1381
|
+
category: Type.Optional(Type.String({ description: "Exa only: result category, e.g. news, research paper" })),
|
|
1853
1382
|
provider: Type.Optional(searchProviderSchema(`Search provider or non-empty list of allowed providers to search simultaneously; ${allPolicyDescription}; omit this field to use the configured provider, or use auto when none is configured`, allowedSearchProviders)),
|
|
1854
1383
|
workflow: Type.Optional(
|
|
1855
1384
|
StringEnum(["none", "summary-review", "auto-summary"], {
|
|
@@ -1860,15 +1389,20 @@ export default function (pi: ExtensionAPI) {
|
|
|
1860
1389
|
description: "http(s) or socks proxy URL (e.g. http://host:port or socks5h://host:port) used for every outbound request in this call (search APIs and content fetches). Node fetch ignores HTTP(S)_PROXY env vars, so set this (or `proxy` in web-search.json) when direct access is blocked; empty string forces direct access.",
|
|
1861
1390
|
})),
|
|
1862
1391
|
}),
|
|
1392
|
+
outputSchema: webSearchOutputSchema,
|
|
1863
1393
|
|
|
1864
1394
|
async execute(callId, params, signal, onUpdate, ctx) {
|
|
1865
|
-
|
|
1395
|
+
// Nested calls neither open the curator unless asked nor fetch content in the background.
|
|
1396
|
+
const nested = nestedSearchCallIds.delete(callId);
|
|
1397
|
+
return markToolError(await runWithProxy(typeof params.proxy === "string" ? params.proxy : undefined, async () => {
|
|
1866
1398
|
const rawQueryList: unknown[] = Array.isArray(params.queries)
|
|
1867
1399
|
? params.queries
|
|
1868
1400
|
: (params.query !== undefined ? expandQueryString(params.query) : []);
|
|
1869
1401
|
const queryList = normalizeQueryList(rawQueryList);
|
|
1870
1402
|
const configWorkflow = loadConfigForExtensionInit().workflow;
|
|
1871
|
-
const workflow =
|
|
1403
|
+
const workflow = nested && params.workflow === undefined
|
|
1404
|
+
? "none"
|
|
1405
|
+
: curatorRunState.resolve(params.workflow, configWorkflow, ctx?.hasUI !== false);
|
|
1872
1406
|
const shouldCurate = workflow === "summary-review";
|
|
1873
1407
|
const recencyFilter = normalizeRecencyFilter(params.recencyFilter);
|
|
1874
1408
|
|
|
@@ -1934,6 +1468,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1934
1468
|
numResults: params.numResults,
|
|
1935
1469
|
recencyFilter,
|
|
1936
1470
|
domainFilter: params.domainFilter,
|
|
1471
|
+
category: params.category,
|
|
1937
1472
|
availableProviders,
|
|
1938
1473
|
defaultProvider,
|
|
1939
1474
|
searchProvider,
|
|
@@ -1995,6 +1530,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1995
1530
|
recencyFilter,
|
|
1996
1531
|
domainFilter: params.domainFilter,
|
|
1997
1532
|
includeContent: params.includeContent,
|
|
1533
|
+
category: params.category,
|
|
1998
1534
|
signal: searchSignal,
|
|
1999
1535
|
extensionContext: ctx,
|
|
2000
1536
|
});
|
|
@@ -2079,103 +1615,41 @@ export default function (pi: ExtensionAPI) {
|
|
|
2079
1615
|
return promise;
|
|
2080
1616
|
}
|
|
2081
1617
|
|
|
2082
|
-
let
|
|
2083
|
-
const allUrls: string[] = [];
|
|
2084
|
-
const allInlineContent: ExtractedContent[] = [];
|
|
2085
|
-
const resolvedProvider = resolveRequestedProvider(params.provider);
|
|
2086
|
-
|
|
2087
|
-
const queryResponses = await runSearchQueries(queryList, async (query) => {
|
|
2088
|
-
signal?.throwIfAborted();
|
|
2089
|
-
onUpdate?.({
|
|
2090
|
-
content: [{ type: "text", text: `Searching "${query}" (${completedSearches}/${queryList.length} complete)...` }],
|
|
2091
|
-
details: { phase: "search", progress: completedSearches / queryList.length, currentQuery: query },
|
|
2092
|
-
});
|
|
2093
|
-
|
|
2094
|
-
try {
|
|
2095
|
-
const { answer, results, inlineContent, provider, providerResponses } = await search(query, {
|
|
2096
|
-
provider: resolvedProvider,
|
|
2097
|
-
numResults: params.numResults,
|
|
2098
|
-
recencyFilter,
|
|
2099
|
-
domainFilter: params.domainFilter,
|
|
2100
|
-
includeContent: params.includeContent,
|
|
2101
|
-
signal,
|
|
2102
|
-
extensionContext: ctx,
|
|
2103
|
-
});
|
|
2104
|
-
|
|
2105
|
-
const providers = providerResponses?.map(response => response.provider) ?? [provider];
|
|
2106
|
-
return { result: { query, answer, results, error: null, provider, providers } satisfies QueryResultData, inlineContent };
|
|
2107
|
-
} catch (err) {
|
|
2108
|
-
if (signal?.aborted || isAbortError(err)) throw err;
|
|
2109
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
2110
|
-
const requestedProvider = toCuratorProvider(resolvedProvider);
|
|
2111
|
-
return {
|
|
2112
|
-
result: { query, answer: "", results: [], error: message, provider: requestedProvider } satisfies QueryResultData,
|
|
2113
|
-
inlineContent: undefined,
|
|
2114
|
-
};
|
|
2115
|
-
} finally {
|
|
2116
|
-
completedSearches++;
|
|
2117
|
-
if (!signal?.aborted) {
|
|
2118
|
-
onUpdate?.({
|
|
2119
|
-
content: [{ type: "text", text: `Completed ${completedSearches}/${queryList.length} searches.` }],
|
|
2120
|
-
details: { phase: "search", progress: completedSearches / queryList.length, currentQuery: query },
|
|
2121
|
-
});
|
|
2122
|
-
}
|
|
2123
|
-
}
|
|
2124
|
-
});
|
|
2125
|
-
const searchResults = queryResponses.map(response => response.result);
|
|
2126
|
-
for (const response of queryResponses) {
|
|
2127
|
-
for (const result of response.result.results) {
|
|
2128
|
-
if (!allUrls.includes(result.url)) allUrls.push(result.url);
|
|
2129
|
-
}
|
|
2130
|
-
if (response.inlineContent) allInlineContent.push(...response.inlineContent);
|
|
2131
|
-
}
|
|
2132
|
-
|
|
2133
|
-
let approvedSummary: string | undefined;
|
|
2134
|
-
let summaryMeta: SummaryMeta | undefined;
|
|
1618
|
+
let summarize: WebSearchCallOptions["summarize"];
|
|
2135
1619
|
if (workflow === "auto-summary") {
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
1620
|
+
summarize = async (searchResults) => {
|
|
1621
|
+
if (!ctx) {
|
|
1622
|
+
return {
|
|
1623
|
+
content: [{ type: "text", text: "Error: Auto-summary requires an active extension context." }],
|
|
1624
|
+
details: { error: "Missing extension context" },
|
|
1625
|
+
};
|
|
1626
|
+
}
|
|
1627
|
+
onUpdate?.({
|
|
1628
|
+
content: [{ type: "text", text: "Generating summary..." }],
|
|
1629
|
+
details: { phase: "generating-summary", progress: 1 },
|
|
1630
|
+
});
|
|
1631
|
+
const summaryContext: SummaryGenerationContext = {
|
|
1632
|
+
model: ctx.model,
|
|
1633
|
+
modelRegistry: ctx.modelRegistry,
|
|
1634
|
+
sessionManager: ctx.sessionManager,
|
|
1635
|
+
scopedModels: ctx.scopedModels,
|
|
2140
1636
|
};
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
1637
|
+
const summaryModelChoices = await loadSummaryModelChoices(summaryContext);
|
|
1638
|
+
const generated = await generateSummaryDraft(
|
|
1639
|
+
searchResults,
|
|
1640
|
+
summaryContext,
|
|
1641
|
+
signal,
|
|
1642
|
+
summaryModelChoices.defaultSummaryModel ?? undefined,
|
|
1643
|
+
undefined,
|
|
1644
|
+
undefined,
|
|
1645
|
+
getSummaryGenerationDeadlineMs(),
|
|
1646
|
+
getSummaryInstructions(),
|
|
1647
|
+
);
|
|
1648
|
+
return { approvedSummary: generated.summary, summaryMeta: generated.meta };
|
|
2151
1649
|
};
|
|
2152
|
-
const summaryModelChoices = await loadSummaryModelChoices(summaryContext);
|
|
2153
|
-
const generated = await generateSummaryDraft(
|
|
2154
|
-
searchResults,
|
|
2155
|
-
summaryContext,
|
|
2156
|
-
signal,
|
|
2157
|
-
summaryModelChoices.defaultSummaryModel ?? undefined,
|
|
2158
|
-
undefined,
|
|
2159
|
-
undefined,
|
|
2160
|
-
getSummaryGenerationDeadlineMs(),
|
|
2161
|
-
getSummaryInstructions(),
|
|
2162
|
-
);
|
|
2163
|
-
approvedSummary = generated.summary;
|
|
2164
|
-
summaryMeta = generated.meta;
|
|
2165
1650
|
}
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
queryList,
|
|
2169
|
-
results: searchResults,
|
|
2170
|
-
urls: allUrls,
|
|
2171
|
-
includeContent: params.includeContent ?? false,
|
|
2172
|
-
inlineContent: allInlineContent.length > 0 ? allInlineContent : undefined,
|
|
2173
|
-
workflow: workflow === "auto-summary" ? "auto-summary" : undefined,
|
|
2174
|
-
approvedSummary,
|
|
2175
|
-
summaryMeta,
|
|
2176
|
-
proxy: typeof params.proxy === "string" ? params.proxy : undefined,
|
|
2177
|
-
});
|
|
2178
|
-
});
|
|
1651
|
+
return core.webSearch(params, signal, { extensionContext: ctx, onUpdate, summarize, awaitContent: nested });
|
|
1652
|
+
}));
|
|
2179
1653
|
},
|
|
2180
1654
|
|
|
2181
1655
|
renderCall(args, theme) {
|
|
@@ -2450,84 +1924,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
2450
1924
|
})),
|
|
2451
1925
|
}),
|
|
2452
1926
|
async execute(_callId, params, signal, _onUpdate, ctx) {
|
|
2453
|
-
return
|
|
2454
|
-
const claim = typeof params.claim === "string" ? params.claim.trim() : "";
|
|
2455
|
-
if (!claim) {
|
|
2456
|
-
return { content: [{ type: "text", text: "Error: 'claim' is required." }], details: { error: "Missing claim" } };
|
|
2457
|
-
}
|
|
2458
|
-
|
|
2459
|
-
const requestedQueries = Array.isArray(params.queries)
|
|
2460
|
-
? params.queries.filter((query): query is string => typeof query === "string").map((query) => query.trim()).filter(Boolean)
|
|
2461
|
-
: [];
|
|
2462
|
-
const queries = (requestedQueries.length > 0 ? requestedQueries : [claim]).slice(0, 8);
|
|
2463
|
-
const numResults = typeof params.numResults === "number" && Number.isFinite(params.numResults)
|
|
2464
|
-
? Math.min(20, Math.max(1, Math.floor(params.numResults)))
|
|
2465
|
-
: 5;
|
|
2466
|
-
const domainFilter = Array.isArray(params.domainFilter)
|
|
2467
|
-
? params.domainFilter.filter((domain): domain is string => typeof domain === "string")
|
|
2468
|
-
: undefined;
|
|
2469
|
-
const recencyFilter = normalizeRecencyFilter(params.recencyFilter);
|
|
2470
|
-
const resultsByUrl = new Map<string, SearchResult>();
|
|
2471
|
-
const summaries: string[] = [];
|
|
2472
|
-
const errors: Array<{ query: string; error: string }> = [];
|
|
2473
|
-
let provider: string | undefined;
|
|
2474
|
-
|
|
2475
|
-
for (const query of queries) {
|
|
2476
|
-
if (signal?.aborted) break;
|
|
2477
|
-
try {
|
|
2478
|
-
const response = await search(query, {
|
|
2479
|
-
provider: resolveRequestedProvider(params.provider),
|
|
2480
|
-
numResults,
|
|
2481
|
-
recencyFilter,
|
|
2482
|
-
domainFilter,
|
|
2483
|
-
signal,
|
|
2484
|
-
extensionContext: ctx,
|
|
2485
|
-
});
|
|
2486
|
-
if (signal?.aborted) break;
|
|
2487
|
-
provider ??= response.provider;
|
|
2488
|
-
if (response.answer) summaries.push(`${query}: ${response.answer}`);
|
|
2489
|
-
for (const result of response.results) {
|
|
2490
|
-
if (!resultsByUrl.has(result.url)) resultsByUrl.set(result.url, result);
|
|
2491
|
-
}
|
|
2492
|
-
} catch (err) {
|
|
2493
|
-
if (signal?.aborted || isAbortError(err)) break;
|
|
2494
|
-
errors.push({ query, error: err instanceof Error ? err.message : String(err) });
|
|
2495
|
-
}
|
|
2496
|
-
}
|
|
2497
|
-
|
|
2498
|
-
const results = [...resultsByUrl.values()].slice(0, 20).map((result, index) => ({ ...result, rank: index + 1 }));
|
|
2499
|
-
let fetched: ExtractedContent[] = [];
|
|
2500
|
-
if (params.fetchContent && results.length > 0) {
|
|
2501
|
-
const urls = results.slice(0, 5).map((result) => result.url);
|
|
2502
|
-
try {
|
|
2503
|
-
fetched = await fetchAllContent(urls, signal, withRegisteredFetchOptions(undefined, registeredToolNames, typeof params.proxy === "string" ? params.proxy : undefined));
|
|
2504
|
-
} catch (err) {
|
|
2505
|
-
if (signal?.aborted || isAbortError(err)) throw err;
|
|
2506
|
-
fetched = urls.map((url) => ({ url, title: "", content: "", error: err instanceof Error ? err.message : String(err) }));
|
|
2507
|
-
}
|
|
2508
|
-
}
|
|
2509
|
-
const artifact = withClaimAssessment(buildResearchArtifact({
|
|
2510
|
-
query: claim,
|
|
2511
|
-
provider,
|
|
2512
|
-
summary: summaries.length > 0 ? summaries.join("\n\n") : undefined,
|
|
2513
|
-
results,
|
|
2514
|
-
fetched,
|
|
2515
|
-
recency: recencyFilter,
|
|
2516
|
-
domainFilter,
|
|
2517
|
-
}), [claim]);
|
|
2518
|
-
if (errors.length > 0) artifact.errors = errors;
|
|
2519
|
-
storeResearchArtifact(artifact);
|
|
2520
|
-
pi.appendEntry("web-search-results", {
|
|
2521
|
-
id: artifact.id,
|
|
2522
|
-
type: "research",
|
|
2523
|
-
timestamp: artifact.timestamp,
|
|
2524
|
-
artifact,
|
|
2525
|
-
});
|
|
2526
|
-
return {
|
|
2527
|
-
content: [{ type: "text", text: formatSourceCheckResult(artifact, getSearchContentEnabled ? toolNames.getSearchContent : null) }],
|
|
2528
|
-
details: { responseId: artifact.id, artifact, sourceCount: artifact.sources.length, passageCount: artifact.passages.length },
|
|
2529
|
-
};
|
|
2530
|
-
});
|
|
1927
|
+
return markToolError(await core.sourceCheck(params, signal, { extensionContext: ctx }));
|
|
2531
1928
|
},
|
|
2532
1929
|
});
|
|
2533
1930
|
|
|
@@ -2574,177 +1971,10 @@ export default function (pi: ExtensionAPI) {
|
|
|
2574
1971
|
description: "http(s) or socks proxy URL (e.g. http://host:port or socks5h://host:port) used for this fetch. Needed when the target is unreachable directly; localhost and NO_PROXY hosts always bypass the proxy. Empty string forces direct access.",
|
|
2575
1972
|
})),
|
|
2576
1973
|
}),
|
|
1974
|
+
outputSchema: fetchContentOutputSchema,
|
|
2577
1975
|
|
|
2578
1976
|
async execute(_toolCallId, params, signal, onUpdate, ctx): Promise<AgentToolResult<Record<string, unknown>>> {
|
|
2579
|
-
|
|
2580
|
-
try {
|
|
2581
|
-
normalized = normalizeFetchContentParams(params);
|
|
2582
|
-
} catch (err) {
|
|
2583
|
-
const error = err instanceof Error ? err.message : String(err);
|
|
2584
|
-
return { content: [{ type: "text", text: `Error: ${error}` }], details: { error } };
|
|
2585
|
-
}
|
|
2586
|
-
const { urlList, options } = normalized;
|
|
2587
|
-
const mode = options.mode ?? fetchModeConfig.defaultMode;
|
|
2588
|
-
if (!fetchModeConfig.allowedModes.includes(mode)) {
|
|
2589
|
-
const error = `Fetch mode "${mode}" is disabled by fetch.allowedModes.`;
|
|
2590
|
-
return { content: [{ type: "text", text: `Error: ${error}` }], details: { error } };
|
|
2591
|
-
}
|
|
2592
|
-
return runWithProxy(options.proxy, async () => {
|
|
2593
|
-
if (mode === "answer" && !options.prompt) {
|
|
2594
|
-
return { content: [{ type: "text", text: "Error: mode answer requires prompt." }], details: { error: "mode answer requires prompt" } };
|
|
2595
|
-
}
|
|
2596
|
-
if (mode === "raw" && (options.forceClone === true || options.timestamp || options.frames || options.prompt || options.model || options.answerModel)) {
|
|
2597
|
-
return { content: [{ type: "text", text: "Error: mode raw cannot be combined with forceClone, prompt, timestamp, frames, model, or answerModel." }], details: { error: "Incompatible raw mode options" } };
|
|
2598
|
-
}
|
|
2599
|
-
if (mode !== "answer" && options.answerModel) {
|
|
2600
|
-
return { content: [{ type: "text", text: "Error: answerModel requires mode answer." }], details: { error: "answerModel requires mode answer" } };
|
|
2601
|
-
}
|
|
2602
|
-
if (mode === "answer" && options.model) {
|
|
2603
|
-
return { content: [{ type: "text", text: "Error: use answerModel, not model, with mode answer." }], details: { error: "model is incompatible with mode answer" } };
|
|
2604
|
-
}
|
|
2605
|
-
if (mode === "answer" && options.auth !== undefined) {
|
|
2606
|
-
return { content: [{ type: "text", text: "Error: auth cannot be combined with mode answer." }], details: { error: "auth cannot be combined with mode answer" } };
|
|
2607
|
-
}
|
|
2608
|
-
let authFetchProfile: AuthFetchProfile | undefined;
|
|
2609
|
-
if (options.auth !== undefined) {
|
|
2610
|
-
try {
|
|
2611
|
-
authFetchProfile = resolveAuthFetchProfile(options.auth);
|
|
2612
|
-
} catch (err) {
|
|
2613
|
-
const error = err instanceof Error ? err.message : String(err);
|
|
2614
|
-
return { content: [{ type: "text", text: `Error: ${error}` }], details: { error } };
|
|
2615
|
-
}
|
|
2616
|
-
}
|
|
2617
|
-
if (urlList.length === 0) {
|
|
2618
|
-
return {
|
|
2619
|
-
content: [{ type: "text", text: "Error: No URL provided." }],
|
|
2620
|
-
details: { error: "No URL provided" },
|
|
2621
|
-
};
|
|
2622
|
-
}
|
|
2623
|
-
|
|
2624
|
-
onUpdate?.({
|
|
2625
|
-
content: [{ type: "text", text: `Fetching ${urlList.length} URL(s)...` }],
|
|
2626
|
-
details: { phase: "fetch", progress: 0 },
|
|
2627
|
-
});
|
|
2628
|
-
|
|
2629
|
-
const { answerModel: _answerModel, auth: _auth, ...extractionOptions } = { ...options, mode };
|
|
2630
|
-
const { prompt: _prompt, ...answerExtractionOptions } = extractionOptions;
|
|
2631
|
-
const fetchOptions = {
|
|
2632
|
-
...(mode === "answer" ? answerExtractionOptions : extractionOptions),
|
|
2633
|
-
...(authFetchProfile ? { authFetchProfile } : {}),
|
|
2634
|
-
};
|
|
2635
|
-
const fetchResults = await fetchAllContent(urlList, signal, withRegisteredFetchOptions(fetchOptions, registeredToolNames, options.proxy));
|
|
2636
|
-
const presentedResults = mode === "answer"
|
|
2637
|
-
? await Promise.all(fetchResults.map(async result => {
|
|
2638
|
-
if (result.error) return result;
|
|
2639
|
-
if (result.thumbnail || result.mimeType?.startsWith("image/")) {
|
|
2640
|
-
return { ...result, error: "Page answer requires textual fetched content" };
|
|
2641
|
-
}
|
|
2642
|
-
try {
|
|
2643
|
-
const answer = await answerFromPage({
|
|
2644
|
-
question: options.prompt!,
|
|
2645
|
-
pageText: result.content,
|
|
2646
|
-
sourceUrl: result.url,
|
|
2647
|
-
...(options.answerModel ? { model: options.answerModel } : {}),
|
|
2648
|
-
}, ctx, signal);
|
|
2649
|
-
return { ...result, content: answer.text };
|
|
2650
|
-
} catch (err) {
|
|
2651
|
-
return { ...result, error: `Page answer failed: ${err instanceof Error ? err.message : String(err)}` };
|
|
2652
|
-
}
|
|
2653
|
-
}))
|
|
2654
|
-
: fetchResults;
|
|
2655
|
-
const successful = presentedResults.filter((r) => !r.error).length;
|
|
2656
|
-
const totalChars = presentedResults.reduce((sum, r) => sum + r.content.length, 0);
|
|
2657
|
-
|
|
2658
|
-
const responseId = generateId();
|
|
2659
|
-
const data = {
|
|
2660
|
-
id: responseId,
|
|
2661
|
-
type: "fetch",
|
|
2662
|
-
timestamp: Date.now(),
|
|
2663
|
-
urls: stripThumbnails(fetchResults),
|
|
2664
|
-
} satisfies StoredSearchData & { type: "fetch"; urls: ExtractedContent[] };
|
|
2665
|
-
const storedContent = storeFetchResult(pi, responseId, data, authFetchProfile);
|
|
2666
|
-
|
|
2667
|
-
if (urlList.length === 1) {
|
|
2668
|
-
const result = presentedResults[0];
|
|
2669
|
-
if (result.error) {
|
|
2670
|
-
return {
|
|
2671
|
-
content: [{ type: "text", text: `Error: ${result.error}` }],
|
|
2672
|
-
details: { urls: urlList, urlCount: 1, successful: 0, error: result.error, ...(storedContent ? { responseId } : {}), prompt: params.prompt, timestamp: params.timestamp, frames: params.frames },
|
|
2673
|
-
};
|
|
2674
|
-
}
|
|
2675
|
-
|
|
2676
|
-
const fullLength = result.content.length;
|
|
2677
|
-
const slice = initialContentSlice(result.content, getMaxInlineContentChars());
|
|
2678
|
-
const truncated = slice.endOffset < fullLength;
|
|
2679
|
-
let output = slice.text;
|
|
2680
|
-
|
|
2681
|
-
if (truncated) {
|
|
2682
|
-
output += `\n\n---\nShowing ${slice.endOffset} of ${fullLength} chars, ${slice.shownBytes} of ${slice.totalBytes} bytes, and ${slice.shownLines} of ${slice.totalLines} lines. `;
|
|
2683
|
-
output += storedContent
|
|
2684
|
-
? getSearchContentEnabled
|
|
2685
|
-
? `Use ${toolNames.getSearchContent}({ responseId: "${responseId}", urlIndex: 0, offset: ${slice.endOffset} }) for the next slice.`
|
|
2686
|
-
: "Content retrieval is not registered."
|
|
2687
|
-
: "Authenticated fetch cache is off; repeat the fetch to read more.";
|
|
2688
|
-
}
|
|
2689
|
-
|
|
2690
|
-
const content: Array<TextContent | ImageContent> = [];
|
|
2691
|
-
if (result.frames?.length) {
|
|
2692
|
-
for (const frame of result.frames) {
|
|
2693
|
-
content.push({ type: "image", data: frame.data, mimeType: frame.mimeType });
|
|
2694
|
-
content.push({ type: "text", text: `Frame at ${frame.timestamp}` });
|
|
2695
|
-
}
|
|
2696
|
-
} else if (result.thumbnail) {
|
|
2697
|
-
content.push({ type: "image", data: result.thumbnail.data, mimeType: result.thumbnail.mimeType });
|
|
2698
|
-
}
|
|
2699
|
-
content.push({ type: "text", text: output });
|
|
2700
|
-
|
|
2701
|
-
const imageCount = (result.frames?.length ?? 0) + (result.thumbnail ? 1 : 0);
|
|
2702
|
-
return {
|
|
2703
|
-
content,
|
|
2704
|
-
details: {
|
|
2705
|
-
urls: urlList,
|
|
2706
|
-
urlCount: 1,
|
|
2707
|
-
successful: 1,
|
|
2708
|
-
totalChars: fullLength,
|
|
2709
|
-
title: result.title,
|
|
2710
|
-
...(storedContent ? { responseId } : {}),
|
|
2711
|
-
truncated,
|
|
2712
|
-
hasImage: imageCount > 0,
|
|
2713
|
-
imageCount,
|
|
2714
|
-
prompt: params.prompt,
|
|
2715
|
-
timestamp: params.timestamp,
|
|
2716
|
-
frames: params.frames,
|
|
2717
|
-
duration: result.duration,
|
|
2718
|
-
mode,
|
|
2719
|
-
mimeType: result.mimeType,
|
|
2720
|
-
status: result.status,
|
|
2721
|
-
totalBytes: slice.totalBytes,
|
|
2722
|
-
totalLines: slice.totalLines,
|
|
2723
|
-
shownBytes: slice.shownBytes,
|
|
2724
|
-
shownLines: slice.shownLines,
|
|
2725
|
-
},
|
|
2726
|
-
};
|
|
2727
|
-
}
|
|
2728
|
-
|
|
2729
|
-
let output = "## Fetched URLs\n\n";
|
|
2730
|
-
for (const { url, title, content, error } of presentedResults) {
|
|
2731
|
-
if (error) {
|
|
2732
|
-
output += `- ${url}: Error - ${error}\n`;
|
|
2733
|
-
} else {
|
|
2734
|
-
output += `- ${title || url} (${content.length} chars)\n`;
|
|
2735
|
-
}
|
|
2736
|
-
}
|
|
2737
|
-
output += storedContent
|
|
2738
|
-
? getSearchContentEnabled
|
|
2739
|
-
? `\n---\nUse ${toolNames.getSearchContent}({ responseId: "${responseId}", urlIndex: 0 }) to retrieve bounded content slices.`
|
|
2740
|
-
: "\n---\nContent retrieval is not registered."
|
|
2741
|
-
: "\n---\nAuthenticated fetch cache is off; repeat the fetch to read content.";
|
|
2742
|
-
|
|
2743
|
-
return {
|
|
2744
|
-
content: [{ type: "text", text: output }],
|
|
2745
|
-
details: { urls: urlList, urlCount: urlList.length, successful, totalChars, ...(storedContent ? { responseId } : {}) },
|
|
2746
|
-
};
|
|
2747
|
-
});
|
|
1977
|
+
return markToolError(await core.fetchContent(params, signal, { extensionContext: ctx, onUpdate }));
|
|
2748
1978
|
},
|
|
2749
1979
|
|
|
2750
1980
|
renderCall(args, theme) {
|
|
@@ -2908,286 +2138,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
2908
2138
|
}),
|
|
2909
2139
|
|
|
2910
2140
|
async execute(_toolCallId, rawParams): Promise<AgentToolResult<Record<string, unknown>>> {
|
|
2911
|
-
|
|
2912
|
-
if (params.findMode !== undefined && params.findText === undefined) {
|
|
2913
|
-
return {
|
|
2914
|
-
content: [{ type: "text", text: `findMode ${formatInputValue(params.findMode)} requires findText; provide findText or omit findMode.` }],
|
|
2915
|
-
details: { error: "findMode requires findText" },
|
|
2916
|
-
};
|
|
2917
|
-
}
|
|
2918
|
-
const data = getResult(params.responseId);
|
|
2919
|
-
if (!data) {
|
|
2920
|
-
return {
|
|
2921
|
-
content: [{ type: "text", text: `Error: No stored results for responseId ${formatInputValue(params.responseId)}. Use a responseId returned by ${storedContentSources}.` }],
|
|
2922
|
-
details: { error: "Not found", responseId: params.responseId },
|
|
2923
|
-
};
|
|
2924
|
-
}
|
|
2925
|
-
|
|
2926
|
-
if (data.type === "research") {
|
|
2927
|
-
const artifact = getResearchArtifact(params.responseId);
|
|
2928
|
-
if (!artifact) {
|
|
2929
|
-
return {
|
|
2930
|
-
content: [{ type: "text", text: `Error: stored research artifact for responseId ${formatInputValue(params.responseId)} was not found. Use a responseId returned by ${storedContentSources}.` }],
|
|
2931
|
-
details: { error: "Artifact not found", responseId: params.responseId },
|
|
2932
|
-
};
|
|
2933
|
-
}
|
|
2934
|
-
const serialized = JSON.stringify(artifact, null, 2);
|
|
2935
|
-
if (params.findText !== undefined) {
|
|
2936
|
-
try {
|
|
2937
|
-
const found = findContent(serialized, normalizeFindQueries(params.findText), params.findMode ?? "case-insensitive");
|
|
2938
|
-
const { text, ...findDetails } = found;
|
|
2939
|
-
return {
|
|
2940
|
-
content: [{ type: "text", text }],
|
|
2941
|
-
details: { responseId: artifact.id, type: "research", contentLength: serialized.length, findMode: params.findMode ?? "case-insensitive", ...findDetails },
|
|
2942
|
-
};
|
|
2943
|
-
} catch (err) {
|
|
2944
|
-
const error = err instanceof Error ? err.message : String(err);
|
|
2945
|
-
return {
|
|
2946
|
-
content: [{ type: "text", text: `Unable to find ${formatInputValue(params.findText)} in research artifact for responseId ${formatInputValue(params.responseId)}: ${error}. Check findText and use a supported findMode.` }],
|
|
2947
|
-
details: { error, responseId: params.responseId, type: "research" },
|
|
2948
|
-
};
|
|
2949
|
-
}
|
|
2950
|
-
}
|
|
2951
|
-
const offset = params.offset ?? 0;
|
|
2952
|
-
const limit = params.limit ?? maxInlineContentChars;
|
|
2953
|
-
if (!Number.isInteger(offset) || offset < 0) {
|
|
2954
|
-
return {
|
|
2955
|
-
content: [{ type: "text", text: `Invalid offset: received ${formatInputValue(offset)} for responseId ${formatInputValue(params.responseId)}; offset must be a non-negative integer. Use 0 or a larger integer.` }],
|
|
2956
|
-
details: { error: "Invalid offset", offset },
|
|
2957
|
-
};
|
|
2958
|
-
}
|
|
2959
|
-
if (!Number.isInteger(limit) || limit <= 0 || limit > maxInlineContentChars) {
|
|
2960
|
-
return {
|
|
2961
|
-
content: [{ type: "text", text: `Invalid limit: received ${formatInputValue(limit)} for responseId ${formatInputValue(params.responseId)}; limit must be an integer from 1 to ${maxInlineContentChars}. Use a value in that range.` }],
|
|
2962
|
-
details: { error: "Invalid limit", limit, maxLimit: maxInlineContentChars },
|
|
2963
|
-
};
|
|
2964
|
-
}
|
|
2965
|
-
if (offset > serialized.length) {
|
|
2966
|
-
return {
|
|
2967
|
-
content: [{ type: "text", text: `Offset ${offset} is out of range for responseId ${formatInputValue(params.responseId)}. Received offset ${offset}; valid range is 0-${serialized.length}. Use an offset within that range.` }],
|
|
2968
|
-
details: { error: "Offset out of range", offset, contentLength: serialized.length },
|
|
2969
|
-
};
|
|
2970
|
-
}
|
|
2971
|
-
const endOffset = Math.min(offset + limit, serialized.length);
|
|
2972
|
-
const artifactSlice = serialized.slice(offset, endOffset);
|
|
2973
|
-
const hasMore = endOffset < serialized.length;
|
|
2974
|
-
return {
|
|
2975
|
-
content: [{ type: "text", text: artifactSlice }],
|
|
2976
|
-
details: { responseId: artifact.id, type: "research", contentLength: serialized.length, offset, limit, returnedChars: artifactSlice.length, nextOffset: hasMore ? endOffset : null, truncated: hasMore },
|
|
2977
|
-
};
|
|
2978
|
-
}
|
|
2979
|
-
|
|
2980
|
-
if (data.type === "search" && data.queries) {
|
|
2981
|
-
let queryData: QueryResultData | undefined;
|
|
2982
|
-
|
|
2983
|
-
if (params.query !== undefined) {
|
|
2984
|
-
queryData = data.queries.find((q) => q.query === params.query);
|
|
2985
|
-
if (!queryData) {
|
|
2986
|
-
const available = data.queries.map((q) => `"${q.query}"`).join(", ");
|
|
2987
|
-
return {
|
|
2988
|
-
content: [{ type: "text", text: `Query ${formatInputValue(params.query)} was not found for responseId ${formatInputValue(params.responseId)}. Received query=${formatInputValue(params.query)}. Available queries: ${available || "none"}. Use one of the available queries or queryIndex.` }],
|
|
2989
|
-
details: { error: "Query not found" },
|
|
2990
|
-
};
|
|
2991
|
-
}
|
|
2992
|
-
} else if (params.queryIndex !== undefined) {
|
|
2993
|
-
queryData = data.queries[params.queryIndex];
|
|
2994
|
-
if (!queryData) {
|
|
2995
|
-
const available = data.queries.map((q, i) => `${i}: "${q.query}"`).join(", ");
|
|
2996
|
-
return {
|
|
2997
|
-
content: [{ type: "text", text: `Query index ${formatInputValue(params.queryIndex)} is out of range for responseId ${formatInputValue(params.responseId)}. Received queryIndex=${formatInputValue(params.queryIndex)}; valid indexes are 0-${data.queries.length - 1}. Available queries: ${available || "none"}. Use one of the available indexes.` }],
|
|
2998
|
-
details: { error: "Index out of range" },
|
|
2999
|
-
};
|
|
3000
|
-
}
|
|
3001
|
-
} else {
|
|
3002
|
-
const available = data.queries.map((q, i) => `${i}: "${q.query}"`).join(", ");
|
|
3003
|
-
return {
|
|
3004
|
-
content: [{ type: "text", text: `Specify query or queryIndex for responseId ${formatInputValue(params.responseId)}. Available queries: ${available || "none"}.` }],
|
|
3005
|
-
details: { error: "No query specified" },
|
|
3006
|
-
};
|
|
3007
|
-
}
|
|
3008
|
-
|
|
3009
|
-
if (queryData.error) {
|
|
3010
|
-
return {
|
|
3011
|
-
content: [{ type: "text", text: `Error retrieving query ${formatInputValue(queryData.query)} from responseId ${formatInputValue(params.responseId)}: ${queryData.error}. Check the stored search result and retry with another query or queryIndex if needed.` }],
|
|
3012
|
-
details: { error: queryData.error, query: queryData.query },
|
|
3013
|
-
};
|
|
3014
|
-
}
|
|
3015
|
-
|
|
3016
|
-
const fullResults = formatFullResults(queryData);
|
|
3017
|
-
if (params.findText !== undefined) {
|
|
3018
|
-
try {
|
|
3019
|
-
const found = findContent(fullResults, normalizeFindQueries(params.findText), params.findMode ?? "case-insensitive");
|
|
3020
|
-
const { text, ...findDetails } = found;
|
|
3021
|
-
return {
|
|
3022
|
-
content: [{ type: "text", text }],
|
|
3023
|
-
details: { responseId: params.responseId, query: queryData.query, resultCount: queryData.results.length, contentLength: fullResults.length, findMode: params.findMode ?? "case-insensitive", ...findDetails },
|
|
3024
|
-
};
|
|
3025
|
-
} catch (err) {
|
|
3026
|
-
const error = err instanceof Error ? err.message : String(err);
|
|
3027
|
-
return {
|
|
3028
|
-
content: [{ type: "text", text: `Unable to find ${formatInputValue(params.findText)} in query ${formatInputValue(queryData.query)} for responseId ${formatInputValue(params.responseId)}: ${error}. Check findText and use a supported findMode.` }],
|
|
3029
|
-
details: { error, query: queryData.query },
|
|
3030
|
-
};
|
|
3031
|
-
}
|
|
3032
|
-
}
|
|
3033
|
-
|
|
3034
|
-
const offset = params.offset ?? 0;
|
|
3035
|
-
const limit = params.limit ?? maxInlineContentChars;
|
|
3036
|
-
if (!Number.isInteger(offset) || offset < 0) {
|
|
3037
|
-
return {
|
|
3038
|
-
content: [{ type: "text", text: `Invalid offset: received ${formatInputValue(offset)} for query ${formatInputValue(queryData.query)}; offset must be a non-negative integer. Use 0 or a larger integer.` }],
|
|
3039
|
-
details: { error: "Invalid offset", offset },
|
|
3040
|
-
};
|
|
3041
|
-
}
|
|
3042
|
-
if (!Number.isInteger(limit) || limit <= 0 || limit > maxInlineContentChars) {
|
|
3043
|
-
return {
|
|
3044
|
-
content: [{ type: "text", text: `Invalid limit: received ${formatInputValue(limit)} for query ${formatInputValue(queryData.query)}; limit must be an integer from 1 to ${maxInlineContentChars}. Use a value in that range.` }],
|
|
3045
|
-
details: { error: "Invalid limit", limit, maxLimit: maxInlineContentChars },
|
|
3046
|
-
};
|
|
3047
|
-
}
|
|
3048
|
-
if (offset > fullResults.length) {
|
|
3049
|
-
return {
|
|
3050
|
-
content: [{ type: "text", text: `Offset ${offset} is out of range for query ${formatInputValue(queryData.query)} in responseId ${formatInputValue(params.responseId)}. Received offset ${offset}; valid range is 0-${fullResults.length}. Use an offset within that range.` }],
|
|
3051
|
-
details: { error: "Offset out of range", offset, contentLength: fullResults.length },
|
|
3052
|
-
};
|
|
3053
|
-
}
|
|
3054
|
-
const queryIndex = data.queries.indexOf(queryData);
|
|
3055
|
-
let returnedChars = Math.min(limit, fullResults.length - offset);
|
|
3056
|
-
let endOffset = offset + returnedChars;
|
|
3057
|
-
let continuation = "";
|
|
3058
|
-
while (endOffset < fullResults.length) {
|
|
3059
|
-
continuation = `\n\n---\nShowing chars ${offset}-${endOffset} of ${fullResults.length}. Use ${toolNames.getSearchContent}({ responseId: "${params.responseId}", queryIndex: ${queryIndex}, offset: ${endOffset}, limit: ${limit} }) for the next slice.`;
|
|
3060
|
-
const overflow = returnedChars + continuation.length - maxInlineContentChars;
|
|
3061
|
-
if (overflow <= 0) break;
|
|
3062
|
-
returnedChars -= overflow;
|
|
3063
|
-
endOffset = offset + returnedChars;
|
|
3064
|
-
}
|
|
3065
|
-
const resultSlice = fullResults.slice(offset, endOffset);
|
|
3066
|
-
const hasMore = endOffset < fullResults.length;
|
|
3067
|
-
const text = `${resultSlice}${hasMore ? continuation : ""}`;
|
|
3068
|
-
return {
|
|
3069
|
-
content: [{ type: "text", text }],
|
|
3070
|
-
details: {
|
|
3071
|
-
responseId: params.responseId,
|
|
3072
|
-
query: queryData.query,
|
|
3073
|
-
resultCount: queryData.results.length,
|
|
3074
|
-
contentLength: fullResults.length,
|
|
3075
|
-
offset,
|
|
3076
|
-
limit,
|
|
3077
|
-
returnedChars,
|
|
3078
|
-
nextOffset: hasMore ? endOffset : null,
|
|
3079
|
-
truncated: hasMore,
|
|
3080
|
-
},
|
|
3081
|
-
};
|
|
3082
|
-
}
|
|
3083
|
-
|
|
3084
|
-
if (data.type === "fetch" && data.urls) {
|
|
3085
|
-
let urlData: ExtractedContent | undefined;
|
|
3086
|
-
let selectedUrlIndex = -1;
|
|
3087
|
-
|
|
3088
|
-
if (params.url !== undefined) {
|
|
3089
|
-
selectedUrlIndex = data.urls.findIndex((u) => u.url === params.url);
|
|
3090
|
-
urlData = data.urls[selectedUrlIndex];
|
|
3091
|
-
if (!urlData) {
|
|
3092
|
-
const available = data.urls.map((u) => u.url).join("\n ");
|
|
3093
|
-
return {
|
|
3094
|
-
content: [{ type: "text", text: `URL ${formatInputValue(params.url)} was not found for responseId ${formatInputValue(params.responseId)}. Received url=${formatInputValue(params.url)}. Available URLs:\n ${available || " none"}\nUse one of the available URLs or urlIndex.` }],
|
|
3095
|
-
details: { error: "URL not found" },
|
|
3096
|
-
};
|
|
3097
|
-
}
|
|
3098
|
-
} else if (params.urlIndex !== undefined) {
|
|
3099
|
-
selectedUrlIndex = params.urlIndex;
|
|
3100
|
-
urlData = data.urls[selectedUrlIndex];
|
|
3101
|
-
if (!urlData) {
|
|
3102
|
-
const available = data.urls.map((u, i) => `${i}: ${u.url}`).join("\n ");
|
|
3103
|
-
return {
|
|
3104
|
-
content: [{ type: "text", text: `URL index ${formatInputValue(params.urlIndex)} is out of range for responseId ${formatInputValue(params.responseId)}. Received urlIndex=${formatInputValue(params.urlIndex)}; valid indexes are 0-${data.urls.length - 1}. Available URLs:\n ${available || " none"}\nUse one of the available indexes.` }],
|
|
3105
|
-
details: { error: "Index out of range" },
|
|
3106
|
-
};
|
|
3107
|
-
}
|
|
3108
|
-
} else {
|
|
3109
|
-
const available = data.urls.map((u, i) => `${i}: ${u.url}`).join("\n ");
|
|
3110
|
-
return {
|
|
3111
|
-
content: [{ type: "text", text: `Specify url or urlIndex for responseId ${formatInputValue(params.responseId)}. Available URLs:\n ${available || " none"}` }],
|
|
3112
|
-
details: { error: "No URL specified" },
|
|
3113
|
-
};
|
|
3114
|
-
}
|
|
3115
|
-
|
|
3116
|
-
if (urlData.error) {
|
|
3117
|
-
return {
|
|
3118
|
-
content: [{ type: "text", text: `Error retrieving URL ${formatInputValue(urlData.url)} from responseId ${formatInputValue(params.responseId)}: ${urlData.error}. Check the stored fetch result and retry with another URL or urlIndex if needed.` }],
|
|
3119
|
-
details: { error: urlData.error, url: urlData.url },
|
|
3120
|
-
};
|
|
3121
|
-
}
|
|
3122
|
-
|
|
3123
|
-
if (params.findText !== undefined) {
|
|
3124
|
-
try {
|
|
3125
|
-
const found = findContent(urlData.content, normalizeFindQueries(params.findText), params.findMode ?? "case-insensitive");
|
|
3126
|
-
const { text, ...findDetails } = found;
|
|
3127
|
-
return {
|
|
3128
|
-
content: [{ type: "text", text: `# ${urlData.title || urlData.url}\n\n${text}` }],
|
|
3129
|
-
details: { url: urlData.url, title: urlData.title, contentLength: urlData.content.length, findMode: params.findMode ?? "case-insensitive", ...findDetails },
|
|
3130
|
-
};
|
|
3131
|
-
} catch (err) {
|
|
3132
|
-
const error = err instanceof Error ? err.message : String(err);
|
|
3133
|
-
return {
|
|
3134
|
-
content: [{ type: "text", text: `Unable to find ${formatInputValue(params.findText)} in URL ${formatInputValue(urlData.url)} for responseId ${formatInputValue(params.responseId)}: ${error}. Check findText and use a supported findMode.` }],
|
|
3135
|
-
details: { error, url: urlData.url },
|
|
3136
|
-
};
|
|
3137
|
-
}
|
|
3138
|
-
}
|
|
3139
|
-
|
|
3140
|
-
const offset = params.offset ?? 0;
|
|
3141
|
-
const limit = params.limit ?? maxInlineContentChars;
|
|
3142
|
-
if (!Number.isInteger(offset) || offset < 0) {
|
|
3143
|
-
return {
|
|
3144
|
-
content: [{ type: "text", text: `Invalid offset: received ${formatInputValue(offset)} for URL ${formatInputValue(urlData.url)}; offset must be a non-negative integer. Use 0 or a larger integer.` }],
|
|
3145
|
-
details: { error: "Invalid offset", offset },
|
|
3146
|
-
};
|
|
3147
|
-
}
|
|
3148
|
-
if (!Number.isInteger(limit) || limit <= 0 || limit > maxInlineContentChars) {
|
|
3149
|
-
return {
|
|
3150
|
-
content: [{ type: "text", text: `Invalid limit: received ${formatInputValue(limit)} for URL ${formatInputValue(urlData.url)}; limit must be an integer from 1 to ${maxInlineContentChars}. Use a value in that range.` }],
|
|
3151
|
-
details: { error: "Invalid limit", limit, maxLimit: maxInlineContentChars },
|
|
3152
|
-
};
|
|
3153
|
-
}
|
|
3154
|
-
if (offset > urlData.content.length) {
|
|
3155
|
-
return {
|
|
3156
|
-
content: [{ type: "text", text: `Offset ${offset} is out of range for URL ${formatInputValue(urlData.url)} in responseId ${formatInputValue(params.responseId)}. Received offset ${offset}; valid range is 0-${urlData.content.length}. Use an offset within that range.` }],
|
|
3157
|
-
details: { error: "Offset out of range", offset, contentLength: urlData.content.length },
|
|
3158
|
-
};
|
|
3159
|
-
}
|
|
3160
|
-
|
|
3161
|
-
const endOffset = Math.min(offset + limit, urlData.content.length);
|
|
3162
|
-
const contentSlice = urlData.content.slice(offset, endOffset);
|
|
3163
|
-
const hasMore = endOffset < urlData.content.length;
|
|
3164
|
-
let text = `# ${urlData.title || urlData.url}\n\n${contentSlice}`;
|
|
3165
|
-
if (hasMore || offset > 0) {
|
|
3166
|
-
text += `\n\n---\nShowing chars ${offset}-${endOffset} of ${urlData.content.length}.`;
|
|
3167
|
-
if (hasMore) {
|
|
3168
|
-
text += ` Use ${toolNames.getSearchContent}({ responseId: "${params.responseId}", urlIndex: ${selectedUrlIndex}, offset: ${endOffset}, limit: ${limit} }) for the next slice.`;
|
|
3169
|
-
}
|
|
3170
|
-
}
|
|
3171
|
-
|
|
3172
|
-
return {
|
|
3173
|
-
content: [{ type: "text", text }],
|
|
3174
|
-
details: {
|
|
3175
|
-
url: urlData.url,
|
|
3176
|
-
title: urlData.title,
|
|
3177
|
-
contentLength: urlData.content.length,
|
|
3178
|
-
offset,
|
|
3179
|
-
limit,
|
|
3180
|
-
returnedChars: contentSlice.length,
|
|
3181
|
-
nextOffset: hasMore ? endOffset : null,
|
|
3182
|
-
truncated: hasMore,
|
|
3183
|
-
},
|
|
3184
|
-
};
|
|
3185
|
-
}
|
|
3186
|
-
|
|
3187
|
-
return {
|
|
3188
|
-
content: [{ type: "text", text: `Invalid stored data for responseId ${formatInputValue(params.responseId)}: received type ${formatInputValue(data.type)}. Use a responseId returned by ${storedContentSources}.` }],
|
|
3189
|
-
details: { error: "Invalid data" },
|
|
3190
|
-
};
|
|
2141
|
+
return markToolError(await core.getSearchContent(rawParams));
|
|
3191
2142
|
},
|
|
3192
2143
|
|
|
3193
2144
|
renderCall(args, theme) {
|