@herbertgao/pi-extensions 2026.9.0 → 2026.9.1
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/node_modules/@czottmann/pi-automode/CHANGELOG.md +13 -1
- package/node_modules/@czottmann/pi-automode/README.md +20 -0
- package/node_modules/@czottmann/pi-automode/docs/GLOSSARY.md +1 -1
- package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +2 -1
- package/node_modules/@czottmann/pi-automode/docs/defaults.md +3 -2
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/classifier.ts +38 -2
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +5 -3
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +11 -3
- package/node_modules/@czottmann/pi-automode/package.json +1 -1
- package/node_modules/@pi-plugins/fast-mode/README.md +5 -3
- package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts.map +1 -1
- package/node_modules/@pi-plugins/fast-mode/dist/index.mjs +20 -55
- package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -1
- package/node_modules/@pi-plugins/fast-mode/package.json +1 -1
- package/node_modules/pi-lens/CHANGELOG.md +988 -0
- package/node_modules/pi-lens/README.md +3 -0
- package/node_modules/pi-lens/config/biome/core.jsonc +11 -2
- package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +13 -1
- package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +927 -80
- package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +13 -4
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +123 -3
- package/node_modules/pi-lens/dist/clients/ast-grep-rule-manager.js +60 -5
- package/node_modules/pi-lens/dist/clients/ast-grep-tool-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +1 -3
- package/node_modules/pi-lens/dist/clients/biome-client.js +9 -2
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +14 -0
- package/node_modules/pi-lens/dist/clients/bootstrap.js +509 -73
- package/node_modules/pi-lens/dist/clients/bounded-cache.js +152 -12
- package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +59 -4
- package/node_modules/pi-lens/dist/clients/bundled-resource-health.js +113 -0
- package/node_modules/pi-lens/dist/clients/bus-events-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +31 -4
- package/node_modules/pi-lens/dist/clients/cache-manager.js +105 -6
- package/node_modules/pi-lens/dist/clients/cache-observability.js +44 -18
- package/node_modules/pi-lens/dist/clients/cargo-manifest.js +422 -0
- package/node_modules/pi-lens/dist/clients/cascade-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +13 -3
- package/node_modules/pi-lens/dist/clients/complexity-client.js +16 -5
- package/node_modules/pi-lens/dist/clients/config-core/deny.js +221 -0
- package/node_modules/pi-lens/dist/clients/config-core/index.js +47 -0
- package/node_modules/pi-lens/dist/clients/config-core/merge.js +357 -0
- package/node_modules/pi-lens/dist/clients/config-core/normalize.js +340 -0
- package/node_modules/pi-lens/dist/clients/config-core/process-spec.js +248 -0
- package/node_modules/pi-lens/dist/clients/config-core/provenance.js +171 -0
- package/node_modules/pi-lens/dist/clients/config-core/records.js +218 -0
- package/node_modules/pi-lens/dist/clients/config-core/resolve.js +125 -0
- package/node_modules/pi-lens/dist/clients/config-core/safe-object.js +78 -0
- package/node_modules/pi-lens/dist/clients/config-core/schema.js +167 -0
- package/node_modules/pi-lens/dist/clients/config-diagnostic-codes.js +281 -0
- package/node_modules/pi-lens/dist/clients/config-locations.js +160 -0
- package/node_modules/pi-lens/dist/clients/config-resolve.js +789 -0
- package/node_modules/pi-lens/dist/clients/config-schema.js +197 -0
- package/node_modules/pi-lens/dist/clients/config-warn.js +407 -0
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +19 -14
- package/node_modules/pi-lens/dist/clients/dead-code-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/deadline-utils.js +178 -0
- package/node_modules/pi-lens/dist/clients/debug-handles.js +2 -2
- package/node_modules/pi-lens/dist/clients/debug-heap.js +3 -3
- package/node_modules/pi-lens/dist/clients/deferred-lsp-work.js +106 -0
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +113 -7
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +8 -19
- package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +12 -9
- package/node_modules/pi-lens/dist/clients/diagnostic-logger.js +14 -4
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +162 -18
- package/node_modules/pi-lens/dist/clients/dispatch/fact-store.js +97 -0
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +9 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +380 -26
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dart-analyze.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/fact-rules.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +1 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +13 -18
- package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/prisma-validate.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +7 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rubocop.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +1 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +3 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +3 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +194 -80
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +84 -15
- package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/disposition-logger.js +3 -3
- package/node_modules/pi-lens/dist/clients/effective-config.js +403 -0
- package/node_modules/pi-lens/dist/clients/error-class.js +23 -0
- package/node_modules/pi-lens/dist/clients/event-loop-hold.js +274 -0
- package/node_modules/pi-lens/dist/clients/extension-log.js +2 -2
- package/node_modules/pi-lens/dist/clients/feature-hints.js +2 -1
- package/node_modules/pi-lens/dist/clients/file-time.js +6 -1
- package/node_modules/pi-lens/dist/clients/file-utils.js +112 -9
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +50 -13
- package/node_modules/pi-lens/dist/clients/format-service.js +6 -1
- package/node_modules/pi-lens/dist/clients/formatters.js +276 -102
- package/node_modules/pi-lens/dist/clients/freshness-cadence.js +17 -0
- package/node_modules/pi-lens/dist/clients/generated-artifacts.js +114 -19
- package/node_modules/pi-lens/dist/clients/generation-guard.js +4 -9
- package/node_modules/pi-lens/dist/clients/git-guard.js +1 -1
- package/node_modules/pi-lens/dist/clients/go-client.js +39 -0
- package/node_modules/pi-lens/dist/clients/gradle-ktfmt-style.js +252 -0
- package/node_modules/pi-lens/dist/clients/hashline-anchor.js +424 -0
- package/node_modules/pi-lens/dist/clients/hook-budgets.js +76 -0
- package/node_modules/pi-lens/dist/clients/host-edit-normalize.js +5 -2
- package/node_modules/pi-lens/dist/clients/host-ports.js +1 -1
- package/node_modules/pi-lens/dist/clients/installer/index.js +71 -52
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +104 -230
- package/node_modules/pi-lens/dist/clients/instance-registry.js +6 -3
- package/node_modules/pi-lens/dist/clients/language-registry.js +595 -0
- package/node_modules/pi-lens/dist/clients/latency-logger.js +160 -2
- package/node_modules/pi-lens/dist/clients/ledger-bounds.js +13 -0
- package/node_modules/pi-lens/dist/clients/lens-config.js +141 -30
- package/node_modules/pi-lens/dist/clients/lens-engine.js +30 -37
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +59 -6
- package/node_modules/pi-lens/dist/clients/log-cleanup.js +2 -2
- package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +3 -1
- package/node_modules/pi-lens/dist/clients/lsp/client.js +168 -30
- package/node_modules/pi-lens/dist/clients/lsp/config.js +483 -158
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/edits.js +15 -2
- package/node_modules/pi-lens/dist/clients/lsp/index.js +676 -71
- package/node_modules/pi-lens/dist/clients/lsp/language.js +18 -169
- package/node_modules/pi-lens/dist/clients/lsp/launch.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +5 -16
- package/node_modules/pi-lens/dist/clients/lsp/server.js +284 -147
- package/node_modules/pi-lens/dist/clients/lsp/session-roots.js +116 -23
- package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +2 -7
- package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +9 -2
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp-mutation.js +163 -21
- package/node_modules/pi-lens/dist/clients/map-with-concurrency.js +36 -0
- package/node_modules/pi-lens/dist/clients/mcp/analyze.js +33 -4
- package/node_modules/pi-lens/dist/clients/mcp/session.js +5 -16
- package/node_modules/pi-lens/dist/clients/memory-sampler.js +8 -3
- package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +2 -4
- package/node_modules/pi-lens/dist/clients/module-report.js +20 -45
- package/node_modules/pi-lens/dist/clients/mutating-tool.js +651 -0
- package/node_modules/pi-lens/dist/clients/mutation-attribution.js +368 -0
- package/node_modules/pi-lens/dist/clients/mutation-bridge.js +240 -0
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +247 -20
- package/node_modules/pi-lens/dist/clients/observed-mutation-sources.js +101 -0
- package/node_modules/pi-lens/dist/clients/observed-mutation.js +1215 -0
- package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +68 -22
- package/node_modules/pi-lens/dist/clients/opengrep-config.js +4 -0
- package/node_modules/pi-lens/dist/clients/package-manager.js +195 -26
- package/node_modules/pi-lens/dist/clients/partial-edit-apply.js +359 -80
- package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +23 -7
- package/node_modules/pi-lens/dist/clients/path-keyed-map.js +21 -2
- package/node_modules/pi-lens/dist/clients/path-utils.js +428 -13
- package/node_modules/pi-lens/dist/clients/persist-debounce.js +8 -1
- package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +114 -0
- package/node_modules/pi-lens/dist/clients/pipeline.js +77 -16
- package/node_modules/pi-lens/dist/clients/probe-home-state.js +228 -0
- package/node_modules/pi-lens/dist/clients/process-bridge.js +66 -0
- package/node_modules/pi-lens/dist/clients/process-snapshot.js +68 -0
- package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +4 -3
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +27 -3
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +51 -20
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +393 -122
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +52 -24
- package/node_modules/pi-lens/dist/clients/python-environment.js +217 -0
- package/node_modules/pi-lens/dist/clients/python-provenance.js +639 -0
- package/node_modules/pi-lens/dist/clients/quiet-window.js +6 -1
- package/node_modules/pi-lens/dist/clients/read-bridge.js +13 -21
- package/node_modules/pi-lens/dist/clients/read-expansion.js +9 -46
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +15 -4
- package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +364 -212
- package/node_modules/pi-lens/dist/clients/read-guard.js +21 -0
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +195 -96
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +152 -109
- package/node_modules/pi-lens/dist/clients/review-graph/service.js +55 -3
- package/node_modules/pi-lens/dist/clients/review-graph/shared-extraction-ir.js +7 -15
- package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +10 -74
- package/node_modules/pi-lens/dist/clients/review-graph-logger.js +9 -3
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +18 -2
- package/node_modules/pi-lens/dist/clients/runtime-context.js +49 -16
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +25 -6
- package/node_modules/pi-lens/dist/clients/runtime-session.js +139 -22
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +168 -35
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +797 -243
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +1028 -53
- package/node_modules/pi-lens/dist/clients/rust-client.js +31 -0
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +33 -10
- package/node_modules/pi-lens/dist/clients/sanitize.js +7 -1
- package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +1 -3
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +3 -0
- package/node_modules/pi-lens/dist/clients/session-lifecycle.js +1 -1
- package/node_modules/pi-lens/dist/clients/session-start-observability.js +79 -0
- package/node_modules/pi-lens/dist/clients/sessionstart-logger.js +12 -3
- package/node_modules/pi-lens/dist/clients/sgconfig.js +6 -1
- package/node_modules/pi-lens/dist/clients/skills-resolver.js +105 -0
- package/node_modules/pi-lens/dist/clients/smells-rollup.js +2 -2
- package/node_modules/pi-lens/dist/clients/string-utils.js +13 -0
- package/node_modules/pi-lens/dist/clients/subagent-mode.js +17 -4
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +176 -39
- package/node_modules/pi-lens/dist/clients/test-runner-delivery.js +239 -0
- package/node_modules/pi-lens/dist/clients/tool-definition.js +41 -1
- package/node_modules/pi-lens/dist/clients/tool-policy.js +91 -21
- package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +40 -40
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +86 -48
- package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +81 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +51 -46
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +28 -0
- package/node_modules/pi-lens/dist/clients/typos-config.js +5 -0
- package/node_modules/pi-lens/dist/clients/user-notify.js +6 -2
- package/node_modules/pi-lens/dist/clients/widget-state.js +191 -26
- package/node_modules/pi-lens/dist/clients/word-index-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/word-index-store.js +20 -5
- package/node_modules/pi-lens/dist/clients/word-index.js +243 -31
- package/node_modules/pi-lens/dist/clients/workspace-topology.js +8 -1
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +3 -0
- package/node_modules/pi-lens/dist/index.js +64335 -54300
- package/node_modules/pi-lens/dist/mcp/analyze-cli.js +3 -1
- package/node_modules/pi-lens/dist/mcp/server.js +127 -5
- package/node_modules/pi-lens/dist/scripts/lib/process-scan.mjs +583 -0
- package/node_modules/pi-lens/dist/scripts/lib/skills-predicate.mjs +129 -0
- package/node_modules/pi-lens/dist/tools/effective-config.js +89 -0
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +95 -24
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +67 -80
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +37 -16
- package/node_modules/pi-lens/dist/tools/shared.js +0 -1
- package/node_modules/pi-lens/docs/agent-guide.md +64 -1
- package/node_modules/pi-lens/docs/configuration.md +222 -0
- package/node_modules/pi-lens/docs/dependencies.md +3 -3
- package/node_modules/pi-lens/docs/features.md +44 -5
- package/node_modules/pi-lens/docs/language-coverage.md +2 -2
- package/node_modules/pi-lens/docs/pi-lens-fixer.md +25 -0
- package/node_modules/pi-lens/docs/pi-lens-investigator.md +25 -0
- package/node_modules/pi-lens/docs/pi-lens-reviewer.md +27 -0
- package/node_modules/pi-lens/docs/pi-lens-subagent.md +38 -0
- package/node_modules/pi-lens/docs/pi-lens-warden.md +55 -0
- package/node_modules/pi-lens/docs/public-api-stability.md +359 -0
- package/node_modules/pi-lens/docs/release-qa-baseline.md +182 -0
- package/node_modules/pi-lens/docs/subagent-compat.md +110 -30
- package/node_modules/pi-lens/docs/tree-sitter_rules_catalog.md +2 -2
- package/node_modules/pi-lens/package.json +15 -23
- package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-cross-language-method.yml +3 -3
- package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-hallucinated-import.yml +2 -2
- package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-sql-injection.yml +12 -2
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +192 -1
- package/node_modules/pi-lens/scripts/install-selftest.mjs +58 -2
- package/node_modules/pi-lens/scripts/lib/skills-predicate.mjs +129 -0
- package/node_modules/pi-lens/scripts/rpc-load-check.mjs +3 -1
- package/node_modules/pi-web-access/CHANGELOG.md +28 -0
- package/node_modules/pi-web-access/README.md +62 -15
- package/node_modules/pi-web-access/curator-page.ts +3 -1
- package/node_modules/pi-web-access/curator-server.ts +5 -1
- package/node_modules/pi-web-access/gemini-search.ts +8 -4
- package/node_modules/pi-web-access/github-extract.ts +242 -1
- package/node_modules/pi-web-access/index.ts +118 -64
- package/node_modules/pi-web-access/mistral-search.ts +281 -0
- package/node_modules/pi-web-access/package.json +2 -2
- package/node_modules/pi-web-access/perplexity.ts +14 -1
- package/node_modules/pi-web-access/utils.ts +23 -6
- package/node_modules/pi-web-access/xai-search.ts +96 -33
- package/package.json +5 -5
|
@@ -1,6 +1,7 @@
|
|
|
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 pLimit from "p-limit";
|
|
4
5
|
import { StringEnum, type ImageContent, type TextContent } from "@earendil-works/pi-ai/compat";
|
|
5
6
|
import type { ExtractedContent, ExtractOptions } from "./extract.ts";
|
|
6
7
|
import { normalizeFetchContentParams } from "./fetch-params.ts";
|
|
@@ -64,6 +65,7 @@ import { isSearXNGAvailable } from "./searxng.ts";
|
|
|
64
65
|
import { isDuckDuckGoAvailable } from "./duckduckgo.ts";
|
|
65
66
|
import { isAnySearchAvailable } from "./anysearch.ts";
|
|
66
67
|
import { isXaiSearchAvailable } from "./xai-search.ts";
|
|
68
|
+
import { isMistralAvailable } from "./mistral-search.ts";
|
|
67
69
|
import { isKimiSearchAvailable } from "./kimi-search.ts";
|
|
68
70
|
import { isBrightDataAvailable } from "./brightdata.ts";
|
|
69
71
|
import { isSerpBaseAvailable } from "./serpbase.ts";
|
|
@@ -229,6 +231,23 @@ const DEFAULT_CURATOR_TIMEOUT_SECONDS = 20;
|
|
|
229
231
|
const DEFAULT_REMOTE_CURATOR_TIMEOUT_SECONDS = 60;
|
|
230
232
|
const MAX_CURATOR_TIMEOUT_SECONDS = 600;
|
|
231
233
|
const MAX_SUMMARY_GENERATION_DEADLINE_MS = 600_000;
|
|
234
|
+
const SEARCH_QUERY_CONCURRENCY = 3;
|
|
235
|
+
|
|
236
|
+
// Limit each batch independently so separate Pi tool calls can still run in parallel.
|
|
237
|
+
function runSearchQueries<T>(queries: string[], run: (query: string, index: number) => Promise<T>): Promise<T[]> {
|
|
238
|
+
const limit = pLimit(SEARCH_QUERY_CONCURRENCY);
|
|
239
|
+
return Promise.all(queries.map((query, index) => limit(() => run(query, index))));
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Keep primary query indexes stable for curator slots, then interleave additional
|
|
243
|
+
// provider entries deterministically instead of assigning by completion order.
|
|
244
|
+
function curatorResultIndex(queryIndex: number, entryIndex: number, queryCount: number): number {
|
|
245
|
+
return entryIndex * queryCount + queryIndex;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function curatorResultIndexCapacity(queryCount: number): number {
|
|
249
|
+
return queryCount * RESOLVED_SEARCH_PROVIDERS.length;
|
|
250
|
+
}
|
|
232
251
|
|
|
233
252
|
function searchProviderSchema(description: string) {
|
|
234
253
|
return Type.Union([
|
|
@@ -423,6 +442,7 @@ async function getProviderAvailability(ctx: ExtensionContext): Promise<ProviderA
|
|
|
423
442
|
anysearch: isAnySearchAvailable(),
|
|
424
443
|
xcrawl: isXcrawlAvailable(),
|
|
425
444
|
xai: await isXaiSearchAvailable(ctx),
|
|
445
|
+
mistral: isMistralAvailable(),
|
|
426
446
|
brightdata: isBrightDataAvailable(),
|
|
427
447
|
serpbase: isSerpBaseAvailable(),
|
|
428
448
|
serper: isSerperAvailable(),
|
|
@@ -1069,7 +1089,8 @@ export default function (pi: ExtensionAPI) {
|
|
|
1069
1089
|
const fetchId = generateId();
|
|
1070
1090
|
const controller = new AbortController();
|
|
1071
1091
|
pendingFetches.set(fetchId, controller);
|
|
1072
|
-
|
|
1092
|
+
Promise.resolve()
|
|
1093
|
+
.then(() => runWithProxy(proxy, () => fetchAllContent(urls, controller.signal, withRegisteredFetchOptions(undefined, registeredToolNames, proxy))))
|
|
1073
1094
|
.then((fetched) => {
|
|
1074
1095
|
if (!sessionActive || !pendingFetches.has(fetchId)) return;
|
|
1075
1096
|
const data = {
|
|
@@ -1340,7 +1361,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1340
1361
|
}
|
|
1341
1362
|
|
|
1342
1363
|
const selected = filterByQueryIndices(payload.selectedQueryIndices, resultsByIndex).results;
|
|
1343
|
-
const fallbackResults = selected.length > 0 ? selected :
|
|
1364
|
+
const fallbackResults = selected.length > 0 ? selected : orderedSearchResults(resultsByIndex);
|
|
1344
1365
|
const deterministic = buildDeterministicSummary(fallbackResults);
|
|
1345
1366
|
return {
|
|
1346
1367
|
approvedSummary: deterministic.summary,
|
|
@@ -1395,6 +1416,11 @@ export default function (pi: ExtensionAPI) {
|
|
|
1395
1416
|
|
|
1396
1417
|
const searchId = storeAndPublishSearch(opts.results);
|
|
1397
1418
|
const isBackgroundFetch = fetchId !== null && !hasInlineReady;
|
|
1419
|
+
// The model only sees `content`, not `details`: surface the id it needs to
|
|
1420
|
+
// call get_search_content, the same way fetch_content does.
|
|
1421
|
+
if (getSearchContentEnabled && !hasApprovedSummary) {
|
|
1422
|
+
output += `\n---\nResults stored as responseId "${searchId}". Use ${toolNames.getSearchContent}({ responseId: "${searchId}", queryIndex: 0 }) to retrieve them.`;
|
|
1423
|
+
}
|
|
1398
1424
|
|
|
1399
1425
|
return {
|
|
1400
1426
|
content: [{ type: "text", text: output.trim() }],
|
|
@@ -1452,8 +1478,14 @@ export default function (pi: ExtensionAPI) {
|
|
|
1452
1478
|
return { results: filteredResults, urls: filteredUrls };
|
|
1453
1479
|
}
|
|
1454
1480
|
|
|
1481
|
+
function orderedSearchResults(resultsByIndex: Map<number, QueryResultData>): QueryResultData[] {
|
|
1482
|
+
return [...resultsByIndex.entries()]
|
|
1483
|
+
.sort(([leftIndex], [rightIndex]) => leftIndex - rightIndex)
|
|
1484
|
+
.map(([, result]) => result);
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1455
1487
|
function collectAllResultsAndUrls(resultsByIndex: Map<number, QueryResultData>) {
|
|
1456
|
-
const results =
|
|
1488
|
+
const results = orderedSearchResults(resultsByIndex);
|
|
1457
1489
|
const urls: string[] = [];
|
|
1458
1490
|
for (const result of results) {
|
|
1459
1491
|
for (const source of result.results) {
|
|
@@ -1492,6 +1524,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1492
1524
|
handle = await startCuratorServer(
|
|
1493
1525
|
{
|
|
1494
1526
|
queries: pc.queryList,
|
|
1527
|
+
initialResultIndexCapacity: curatorResultIndexCapacity(pc.queryList.length),
|
|
1495
1528
|
sessionToken,
|
|
1496
1529
|
timeout: pc.timeoutSeconds,
|
|
1497
1530
|
availableProviders: pc.availableProviders,
|
|
@@ -1573,7 +1606,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1573
1606
|
} else {
|
|
1574
1607
|
const conn = activeCurators.get(callId)?.getConnectionState();
|
|
1575
1608
|
pc.finish(buildCurationCancelledReturn(reason, {
|
|
1576
|
-
queries:
|
|
1609
|
+
queries: orderedSearchResults(pc.searchResults),
|
|
1577
1610
|
queryCount: pc.queryList.length,
|
|
1578
1611
|
browserConnected: conn?.browserConnected,
|
|
1579
1612
|
lastHeartbeatAgeMs: conn?.lastHeartbeatAgeMs,
|
|
@@ -1750,19 +1783,19 @@ export default function (pi: ExtensionAPI) {
|
|
|
1750
1783
|
name: toolNames.webSearch,
|
|
1751
1784
|
label: "Web Search",
|
|
1752
1785
|
description:
|
|
1753
|
-
`Search the web using OpenAI, Brave, Parallel, Parallel MCP, TinyFish, Search1API, Searchinfinity, Querit, Tavily, Firecrawl, Jina, SERPdive, Kagi, Bocha, Ollama, SearXNG, DuckDuckGo, Exa, Perplexity, Gemini, Kimi, AnySearch, XCrawl, Valyu, xAI, Bright Data, SerpBase, or Serper. Pass a provider array to search only those providers simultaneously, or use provider "all" to search every eligible provider except Parallel MCP, DuckDuckGo, Kimi, AnySearch, XCrawl, Valyu, xAI, Bright Data, SerpBase, and Serper. Returns an AI-synthesized answer with source citations. OpenAI search uses a Codex subscription or OpenAI API key; Kimi search uses a Kimi Code Plan authenticated through /login kimi-coding; xAI search uses a SuperGrok/X Premium subscription or xAI API key. Parallel MCP, DuckDuckGo, Kimi, AnySearch, XCrawl, Valyu, xAI, Bright Data, SerpBase, and Serper are available only when explicitly selected. For comprehensive research, prefer queries (plural) with 2-4 varied angles over a single query — each query gets its own synthesized answer, so varying phrasing and scope gives much broader coverage. When includeContent is true, full page content is fetched in the background. Searches auto-open the interactive browser curator and stream results live; set workflow to "none" to skip curation or "auto-summary" for a model-generated summary without the browser curator. The configured provider is used when provider is omitted or set to auto; omit provider unless explicitly overriding it. Without a configured provider, SearXNG is preferred first for local/private search. When the active Pi model is openai-codex, Codex-backed OpenAI search is preferred next. Otherwise Exa is preferred before OpenAI, then Brave, Parallel, TinyFish, Search1API, Searchinfinity, Querit, Tavily, Firecrawl, Jina, SERPdive, Kagi, Bocha, Ollama, Perplexity, Gemini API, or Gemini Web.`,
|
|
1786
|
+
`Search the web using OpenAI, Brave, Parallel, Parallel MCP, TinyFish, Search1API, Searchinfinity, Querit, Tavily, Firecrawl, Jina, SERPdive, Kagi, Bocha, Ollama, SearXNG, DuckDuckGo, Exa, Perplexity, Gemini, Kimi, AnySearch, XCrawl, Valyu, xAI, Mistral, Bright Data, SerpBase, or Serper. Pass a provider array to search only those providers simultaneously, or use provider "all" to search every eligible provider except Parallel MCP, DuckDuckGo, Kimi, AnySearch, XCrawl, Valyu, xAI, Mistral, Bright Data, SerpBase, and Serper. Returns an AI-synthesized answer with source citations. OpenAI search uses a Codex subscription or OpenAI API key; Kimi search uses a Kimi Code Plan authenticated through /login kimi-coding; xAI search uses a SuperGrok/X Premium subscription or xAI API key; Mistral search uses a Mistral API key. Parallel MCP, DuckDuckGo, Kimi, AnySearch, XCrawl, Valyu, xAI, Mistral, Bright Data, SerpBase, and Serper are available only when explicitly selected. For comprehensive research, prefer queries (plural) with 2-4 varied angles over a single query — each query gets its own synthesized answer, so varying phrasing and scope gives much broader coverage. When includeContent is true, full page content is fetched in the background. Searches auto-open the interactive browser curator and stream results live; set workflow to "none" to skip curation or "auto-summary" for a model-generated summary without the browser curator. The configured provider is used when provider is omitted or set to auto; omit provider unless explicitly overriding it. Without a configured provider, SearXNG is preferred first for local/private search. When the active Pi model is openai-codex, Codex-backed OpenAI search is preferred next. Otherwise Exa is preferred before OpenAI, then Brave, Parallel, TinyFish, Search1API, Searchinfinity, Querit, Tavily, Firecrawl, Jina, SERPdive, Kagi, Bocha, Ollama, Perplexity, Gemini API, or Gemini Web.`,
|
|
1754
1787
|
promptSnippet:
|
|
1755
1788
|
"Use for web research questions. Prefer {queries:[...]} with 2-4 varied angles over a single query for broader coverage. Omit provider unless explicitly overriding the configured default.",
|
|
1756
1789
|
parameters: Type.Object({
|
|
1757
1790
|
query: Type.Optional(Type.String({ description: "Single search query. For research tasks, prefer 'queries' with multiple varied angles instead." })),
|
|
1758
|
-
queries: Type.Optional(Type.Array(Type.String(), { description: "Multiple queries searched
|
|
1791
|
+
queries: Type.Optional(Type.Array(Type.String(), { description: "Multiple queries searched concurrently (up to three at a time), each returning its own synthesized answer. Prefer this for research — vary phrasing, scope, and angle across 2-4 queries to maximize coverage. Good: ['React vs Vue performance benchmarks 2026', 'React vs Vue developer experience comparison', 'React ecosystem size vs Vue ecosystem']. Bad: ['React vs Vue', 'React vs Vue comparison', 'React vs Vue review'] (too similar, redundant results)." })),
|
|
1759
1792
|
numResults: Type.Optional(Type.Integer({ minimum: 1, maximum: 20, description: "Results per query (default: 5, max: 20)" })),
|
|
1760
1793
|
includeContent: Type.Optional(Type.Boolean({ description: "Fetch full page content (async)" })),
|
|
1761
1794
|
recencyFilter: Type.Optional(
|
|
1762
1795
|
StringEnum(["day", "week", "month", "year"], { description: "Filter by recency" }),
|
|
1763
1796
|
),
|
|
1764
1797
|
domainFilter: Type.Optional(Type.Array(Type.String(), { description: "Limit to domains (prefix with - to exclude)" })),
|
|
1765
|
-
provider: Type.Optional(searchProviderSchema("Search provider or non-empty list of providers to search simultaneously; use all to search every eligible provider except Parallel MCP, DuckDuckGo, Kimi, AnySearch, XCrawl, Valyu, xAI, Bright Data, SerpBase, and Serper, omit this field to use the configured provider, or use auto when none is configured")),
|
|
1798
|
+
provider: Type.Optional(searchProviderSchema("Search provider or non-empty list of providers to search simultaneously; use all to search every eligible provider except Parallel MCP, DuckDuckGo, Kimi, AnySearch, XCrawl, Valyu, xAI, Mistral, Bright Data, SerpBase, and Serper, omit this field to use the configured provider, or use auto when none is configured")),
|
|
1766
1799
|
workflow: Type.Optional(
|
|
1767
1800
|
StringEnum(["none", "summary-review", "auto-summary"], {
|
|
1768
1801
|
description: "Search workflow mode: none = no curator, summary-review = open curator with auto summary draft (default), auto-summary = generate summary without opening curator",
|
|
@@ -1809,7 +1842,6 @@ export default function (pi: ExtensionAPI) {
|
|
|
1809
1842
|
const searchResults = new Map<number, QueryResultData>();
|
|
1810
1843
|
const resultSlots = new Map<number, number>();
|
|
1811
1844
|
const allInlineContent: ExtractedContent[] = [];
|
|
1812
|
-
let nextResultIndex = queryList.length;
|
|
1813
1845
|
const searchAbort = new AbortController();
|
|
1814
1846
|
const searchSignal = signal
|
|
1815
1847
|
? AbortSignal.any([signal, searchAbort.signal])
|
|
@@ -1876,7 +1908,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1876
1908
|
if (cancelled) return;
|
|
1877
1909
|
const conn = activeCurators.get(callId)?.getConnectionState();
|
|
1878
1910
|
finish(buildCurationCancelledReturn(reason, {
|
|
1879
|
-
queries:
|
|
1911
|
+
queries: orderedSearchResults(searchResults),
|
|
1880
1912
|
queryCount: queryList.length,
|
|
1881
1913
|
browserConnected: conn?.browserConnected,
|
|
1882
1914
|
lastHeartbeatAgeMs: conn?.lastHeartbeatAgeMs,
|
|
@@ -1893,15 +1925,16 @@ export default function (pi: ExtensionAPI) {
|
|
|
1893
1925
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
1894
1926
|
pc.browserPromise = openCuratorBrowser(callId, pc, ctx, false);
|
|
1895
1927
|
|
|
1896
|
-
|
|
1897
|
-
|
|
1928
|
+
let completedSearches = 0;
|
|
1929
|
+
await runSearchQueries(queryList, async (query, qi) => {
|
|
1930
|
+
if (signal?.aborted || cancelled || searchAbort.signal.aborted) return;
|
|
1898
1931
|
onUpdate?.({
|
|
1899
|
-
content: [{ type: "text", text: `Searching ${
|
|
1900
|
-
details: { phase: "searching", progress:
|
|
1932
|
+
content: [{ type: "text", text: `Searching "${query}" (${completedSearches}/${queryList.length} complete)...` }],
|
|
1933
|
+
details: { phase: "searching", progress: completedSearches / queryList.length, currentQuery: query },
|
|
1901
1934
|
});
|
|
1902
1935
|
const requestedProvider = pc.searchProvider;
|
|
1903
1936
|
try {
|
|
1904
|
-
const response = await search(
|
|
1937
|
+
const response = await search(query, {
|
|
1905
1938
|
provider: requestedProvider,
|
|
1906
1939
|
numResults: params.numResults,
|
|
1907
1940
|
recencyFilter,
|
|
@@ -1910,40 +1943,48 @@ export default function (pi: ExtensionAPI) {
|
|
|
1910
1943
|
signal: searchSignal,
|
|
1911
1944
|
extensionContext: ctx,
|
|
1912
1945
|
});
|
|
1913
|
-
if (signal?.aborted || cancelled || searchAbort.signal.aborted)
|
|
1946
|
+
if (signal?.aborted || cancelled || searchAbort.signal.aborted) return;
|
|
1914
1947
|
if (response.inlineContent) allInlineContent.push(...response.inlineContent);
|
|
1915
1948
|
const entries = toCuratorSearchEntries(response);
|
|
1916
1949
|
const curator = activeCurators.get(callId);
|
|
1917
1950
|
for (let entryIndex = 0; entryIndex < entries.length; entryIndex++) {
|
|
1918
1951
|
const entry = entries[entryIndex];
|
|
1919
|
-
const resultIndex =
|
|
1952
|
+
const resultIndex = curatorResultIndex(qi, entryIndex, queryList.length);
|
|
1920
1953
|
const indexedEntry: IndexedCuratorSearchEntry = {
|
|
1921
1954
|
...entry,
|
|
1922
1955
|
queryIndex: resultIndex,
|
|
1923
|
-
query
|
|
1956
|
+
query,
|
|
1924
1957
|
};
|
|
1925
1958
|
searchResults.set(resultIndex, indexedCuratorEntryToQueryResult(indexedEntry));
|
|
1926
1959
|
resultSlots.set(resultIndex, qi);
|
|
1927
1960
|
if (curator) {
|
|
1928
1961
|
if (entry.error) {
|
|
1929
|
-
curator.pushError(resultIndex, entry.error, entry.provider, { query
|
|
1962
|
+
curator.pushError(resultIndex, entry.error, entry.provider, { query, slotIndex: qi });
|
|
1930
1963
|
} else {
|
|
1931
|
-
curator.pushResult(resultIndex, { ...entry, query
|
|
1964
|
+
curator.pushResult(resultIndex, { ...entry, query, slotIndex: qi });
|
|
1932
1965
|
}
|
|
1933
1966
|
}
|
|
1934
1967
|
}
|
|
1935
1968
|
} catch (err) {
|
|
1936
|
-
if (signal?.aborted || cancelled || searchAbort.signal.aborted)
|
|
1969
|
+
if (signal?.aborted || cancelled || searchAbort.signal.aborted) return;
|
|
1937
1970
|
const message = err instanceof Error ? err.message : String(err);
|
|
1938
1971
|
const failedProvider = toCuratorProvider(requestedProvider);
|
|
1939
|
-
searchResults.set(qi, { query
|
|
1972
|
+
searchResults.set(qi, { query, answer: "", results: [], error: message, provider: failedProvider });
|
|
1940
1973
|
resultSlots.set(qi, qi);
|
|
1941
1974
|
const curator = activeCurators.get(callId);
|
|
1942
1975
|
if (curator) {
|
|
1943
|
-
curator.pushError(qi, message, failedProvider, { query
|
|
1976
|
+
curator.pushError(qi, message, failedProvider, { query, slotIndex: qi });
|
|
1977
|
+
}
|
|
1978
|
+
} finally {
|
|
1979
|
+
completedSearches++;
|
|
1980
|
+
if (!signal?.aborted && !cancelled && !searchAbort.signal.aborted) {
|
|
1981
|
+
onUpdate?.({
|
|
1982
|
+
content: [{ type: "text", text: `Completed ${completedSearches}/${queryList.length} searches.` }],
|
|
1983
|
+
details: { phase: "searching", progress: completedSearches / queryList.length, currentQuery: query },
|
|
1984
|
+
});
|
|
1944
1985
|
}
|
|
1945
1986
|
}
|
|
1946
|
-
}
|
|
1987
|
+
});
|
|
1947
1988
|
|
|
1948
1989
|
if (signal?.aborted || cancelled || searchAbort.signal.aborted) {
|
|
1949
1990
|
cancel();
|
|
@@ -1983,17 +2024,16 @@ export default function (pi: ExtensionAPI) {
|
|
|
1983
2024
|
return promise;
|
|
1984
2025
|
}
|
|
1985
2026
|
|
|
1986
|
-
|
|
2027
|
+
let completedSearches = 0;
|
|
1987
2028
|
const allUrls: string[] = [];
|
|
1988
2029
|
const allInlineContent: ExtractedContent[] = [];
|
|
1989
2030
|
const resolvedProvider = resolveRequestedProvider(params.provider);
|
|
1990
2031
|
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
2032
|
+
const queryResponses = await runSearchQueries(queryList, async (query) => {
|
|
2033
|
+
signal?.throwIfAborted();
|
|
1994
2034
|
onUpdate?.({
|
|
1995
|
-
content: [{ type: "text", text: `Searching ${
|
|
1996
|
-
details: { phase: "search", progress:
|
|
2035
|
+
content: [{ type: "text", text: `Searching "${query}" (${completedSearches}/${queryList.length} complete)...` }],
|
|
2036
|
+
details: { phase: "search", progress: completedSearches / queryList.length, currentQuery: query },
|
|
1997
2037
|
});
|
|
1998
2038
|
|
|
1999
2039
|
try {
|
|
@@ -2007,19 +2047,31 @@ export default function (pi: ExtensionAPI) {
|
|
|
2007
2047
|
extensionContext: ctx,
|
|
2008
2048
|
});
|
|
2009
2049
|
|
|
2010
|
-
|
|
2011
|
-
for (const r of results) {
|
|
2012
|
-
if (!allUrls.includes(r.url)) {
|
|
2013
|
-
allUrls.push(r.url);
|
|
2014
|
-
}
|
|
2015
|
-
}
|
|
2016
|
-
if (inlineContent) allInlineContent.push(...inlineContent);
|
|
2050
|
+
return { result: { query, answer, results, error: null, provider } satisfies QueryResultData, inlineContent };
|
|
2017
2051
|
} catch (err) {
|
|
2018
2052
|
if (signal?.aborted || isAbortError(err)) throw err;
|
|
2019
2053
|
const message = err instanceof Error ? err.message : String(err);
|
|
2020
2054
|
const requestedProvider = toCuratorProvider(resolvedProvider);
|
|
2021
|
-
|
|
2055
|
+
return {
|
|
2056
|
+
result: { query, answer: "", results: [], error: message, provider: requestedProvider } satisfies QueryResultData,
|
|
2057
|
+
inlineContent: undefined,
|
|
2058
|
+
};
|
|
2059
|
+
} finally {
|
|
2060
|
+
completedSearches++;
|
|
2061
|
+
if (!signal?.aborted) {
|
|
2062
|
+
onUpdate?.({
|
|
2063
|
+
content: [{ type: "text", text: `Completed ${completedSearches}/${queryList.length} searches.` }],
|
|
2064
|
+
details: { phase: "search", progress: completedSearches / queryList.length, currentQuery: query },
|
|
2065
|
+
});
|
|
2066
|
+
}
|
|
2022
2067
|
}
|
|
2068
|
+
});
|
|
2069
|
+
const searchResults = queryResponses.map(response => response.result);
|
|
2070
|
+
for (const response of queryResponses) {
|
|
2071
|
+
for (const result of response.result.results) {
|
|
2072
|
+
if (!allUrls.includes(result.url)) allUrls.push(result.url);
|
|
2073
|
+
}
|
|
2074
|
+
if (response.inlineContent) allInlineContent.push(...response.inlineContent);
|
|
2023
2075
|
}
|
|
2024
2076
|
|
|
2025
2077
|
let approvedSummary: string | undefined;
|
|
@@ -2337,7 +2389,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
2337
2389
|
fetchContent: Type.Optional(Type.Boolean({ description: "Fetch up to 5 result pages for exact passage extraction." })),
|
|
2338
2390
|
recencyFilter: Type.Optional(StringEnum(["day", "week", "month", "year"], { description: "Filter by recency." })),
|
|
2339
2391
|
domainFilter: Type.Optional(Type.Array(Type.String(), { description: "Limit to domains; prefix with - to exclude." })),
|
|
2340
|
-
provider: Type.Optional(searchProviderSchema("Search provider or non-empty list of providers to search simultaneously; all searches every eligible provider except Parallel MCP, DuckDuckGo, Kimi, AnySearch, XCrawl, Valyu, xAI, Bright Data, SerpBase, and Serper")),
|
|
2392
|
+
provider: Type.Optional(searchProviderSchema("Search provider or non-empty list of providers to search simultaneously; all searches every eligible provider except Parallel MCP, DuckDuckGo, Kimi, AnySearch, XCrawl, Valyu, xAI, Mistral, Bright Data, SerpBase, and Serper")),
|
|
2341
2393
|
proxy: Type.Optional(Type.String({
|
|
2342
2394
|
description: "http(s) proxy URL (e.g. http://host:port) used for every outbound request in this call (search APIs and result-page fetches). Empty string forces direct access.",
|
|
2343
2395
|
})),
|
|
@@ -3163,6 +3215,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
3163
3215
|
const handle = await startCuratorServer(
|
|
3164
3216
|
{
|
|
3165
3217
|
queries,
|
|
3218
|
+
initialResultIndexCapacity: curatorResultIndexCapacity(queries.length),
|
|
3166
3219
|
sessionToken,
|
|
3167
3220
|
timeout: curatorTimeoutSeconds,
|
|
3168
3221
|
availableProviders,
|
|
@@ -3244,19 +3297,21 @@ export default function (pi: ExtensionAPI) {
|
|
|
3244
3297
|
}
|
|
3245
3298
|
},
|
|
3246
3299
|
async onAddSearch(query, provider) {
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3300
|
+
return runWithProxy(undefined, async () => {
|
|
3301
|
+
if (commandHandle && !isCommandActive()) {
|
|
3302
|
+
throw new Error("Curator session is no longer active.");
|
|
3303
|
+
}
|
|
3304
|
+
const requestedProvider = resolveCuratorSearchProvider(provider, currentSearchProvider);
|
|
3305
|
+
const response = await search(query, {
|
|
3306
|
+
provider: requestedProvider,
|
|
3307
|
+
signal: searchAbort.signal,
|
|
3308
|
+
extensionContext: ctx,
|
|
3309
|
+
});
|
|
3310
|
+
if (commandHandle && !isCommandActive()) {
|
|
3311
|
+
throw new Error("Curator session is no longer active.");
|
|
3312
|
+
}
|
|
3313
|
+
return toCuratorSearchEntries(response);
|
|
3255
3314
|
});
|
|
3256
|
-
if (commandHandle && !isCommandActive()) {
|
|
3257
|
-
throw new Error("Curator session is no longer active.");
|
|
3258
|
-
}
|
|
3259
|
-
return toCuratorSearchEntries(response);
|
|
3260
3315
|
},
|
|
3261
3316
|
onAddSearchResults(entries) {
|
|
3262
3317
|
if (commandHandle && !isCommandActive()) return;
|
|
@@ -3315,41 +3370,40 @@ export default function (pi: ExtensionAPI) {
|
|
|
3315
3370
|
|
|
3316
3371
|
if (queries.length > 0) {
|
|
3317
3372
|
(async () => {
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
if (aborted || !isCommandActive()) break;
|
|
3373
|
+
await runSearchQueries(queries, async (query, qi) => {
|
|
3374
|
+
if (aborted || !isCommandActive()) return;
|
|
3321
3375
|
const requestedProvider = currentSearchProvider;
|
|
3322
3376
|
try {
|
|
3323
|
-
const response = await search(
|
|
3377
|
+
const response = await runWithProxy(undefined, () => search(query, {
|
|
3324
3378
|
provider: requestedProvider,
|
|
3325
3379
|
signal: searchAbort.signal,
|
|
3326
3380
|
extensionContext: ctx,
|
|
3327
|
-
});
|
|
3328
|
-
if (aborted || !isCommandActive())
|
|
3381
|
+
}));
|
|
3382
|
+
if (aborted || !isCommandActive()) return;
|
|
3329
3383
|
const entries = toCuratorSearchEntries(response);
|
|
3330
3384
|
for (let entryIndex = 0; entryIndex < entries.length; entryIndex++) {
|
|
3331
3385
|
const entry = entries[entryIndex];
|
|
3332
|
-
const resultIndex =
|
|
3386
|
+
const resultIndex = curatorResultIndex(qi, entryIndex, queries.length);
|
|
3333
3387
|
const indexedEntry: IndexedCuratorSearchEntry = {
|
|
3334
3388
|
...entry,
|
|
3335
3389
|
queryIndex: resultIndex,
|
|
3336
|
-
query
|
|
3390
|
+
query,
|
|
3337
3391
|
};
|
|
3338
3392
|
collected.set(resultIndex, indexedCuratorEntryToQueryResult(indexedEntry));
|
|
3339
3393
|
if (entry.error) {
|
|
3340
|
-
handle.pushError(resultIndex, entry.error, entry.provider, { query
|
|
3394
|
+
handle.pushError(resultIndex, entry.error, entry.provider, { query, slotIndex: qi });
|
|
3341
3395
|
} else {
|
|
3342
|
-
handle.pushResult(resultIndex, { ...entry, query
|
|
3396
|
+
handle.pushResult(resultIndex, { ...entry, query, slotIndex: qi });
|
|
3343
3397
|
}
|
|
3344
3398
|
}
|
|
3345
3399
|
} catch (err) {
|
|
3346
|
-
if (aborted || !isCommandActive())
|
|
3400
|
+
if (aborted || !isCommandActive()) return;
|
|
3347
3401
|
const message = err instanceof Error ? err.message : String(err);
|
|
3348
3402
|
const failedProvider = toCuratorProvider(requestedProvider);
|
|
3349
|
-
handle.pushError(qi, message, failedProvider, { query
|
|
3350
|
-
collected.set(qi, { query
|
|
3403
|
+
handle.pushError(qi, message, failedProvider, { query, slotIndex: qi });
|
|
3404
|
+
collected.set(qi, { query, answer: "", results: [], error: message, provider: failedProvider });
|
|
3351
3405
|
}
|
|
3352
|
-
}
|
|
3406
|
+
});
|
|
3353
3407
|
if (!aborted && isCommandActive()) handle.searchesDone();
|
|
3354
3408
|
})();
|
|
3355
3409
|
} else {
|