feat(web-search): add WebSearchTask with pluggable search providers #3256
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build & Test | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.head.ref || (github.event_name == 'workflow_dispatch' && github.run_id || github.ref_name) }} | |
| cancel-in-progress: true | |
| env: | |
| CI: "true" | |
| DO_NOT_TRACK: "1" | |
| TURBO_TELEMETRY_DISABLED: "1" | |
| # PRs: only packages the change can reach. Push/dispatch: full suite. | |
| TEST_CHANGED: ${{ github.event_name == 'pull_request' && format('--changed {0}', github.event.pull_request.base.sha) || '' }} | |
| jobs: | |
| typecheck-budget: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - run: bun i | |
| # Fails the PR if any package's type-instantiation count grows past its | |
| # committed budget (scripts/typecheck-budget.json). Re-baseline intentional | |
| # growth with: bun run typecheck:budget --update | |
| - name: Typecheck budget guard | |
| run: bun run typecheck:budget | |
| # Co-located `__tests__` are excluded from each package's build program so | |
| # they never reach `dist`, which also takes them out of every tsc run. | |
| # `tsconfig.test.json` is the program that still checks them; without this | |
| # step a type error in a test file is invisible until someone runs it. | |
| # Must follow the budget guard, which is what emits the `dist/*.d.ts` these | |
| # programs resolve their own package against. | |
| - name: Typecheck co-located tests | |
| run: bun run typecheck:tests | |
| test-discovery: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - run: bun i | |
| # Fails if any test file is unreachable by section+kind selection. Every | |
| # other job passes a kind, so an unreachable file silently never runs. | |
| - name: Test discovery guard | |
| run: bun scripts/test.ts --check-sections | |
| build: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - run: bun i | |
| - run: bun run build | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: build-output | |
| path: | | |
| packages/*/dist/** | |
| providers/*/dist/** | |
| examples/*/dist/** | |
| retention-days: 1 | |
| test-vitest-unit: | |
| runs-on: ubuntu-latest | |
| needs: build | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - run: bun i | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: build-output | |
| path: . | |
| - name: Run unit tests via vitest | |
| run: bun run test:vitest:unit -- ${{ env.TEST_CHANGED }} | |
| - name: Copy Vitest coverage fragment | |
| run: | | |
| if [ -f coverage/coverage-final.json ]; then | |
| cp coverage/coverage-final.json vitest-unit-coverage.json | |
| else | |
| echo '{}' > vitest-unit-coverage.json | |
| fi | |
| - name: Upload Vitest coverage fragment | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: coverage-vitest-unit | |
| path: vitest-unit-coverage.json | |
| retention-days: 1 | |
| test-vitest-integration: | |
| runs-on: ubuntu-latest | |
| needs: build | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - run: bun i | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: build-output | |
| path: . | |
| - name: Run integration tests via vitest | |
| env: | |
| WORKGLOW_SECRETS_PASSPHRASE: ${{ secrets.WORKGLOW_SECRETS_PASSPHRASE }} | |
| run: bun run test:vitest:integration -- ${{ env.TEST_CHANGED }} | |
| - name: Copy Vitest coverage fragment | |
| run: | | |
| if [ -f coverage/coverage-final.json ]; then | |
| cp coverage/coverage-final.json vitest-integration-coverage.json | |
| else | |
| echo '{}' > vitest-integration-coverage.json | |
| fi | |
| - name: Upload Vitest coverage fragment | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: coverage-vitest-integration | |
| path: vitest-integration-coverage.json | |
| retention-days: 1 | |
| test-vitest-rag: | |
| runs-on: ubuntu-latest | |
| needs: build | |
| timeout-minutes: 25 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - run: bun i | |
| - name: Cache Hugging Face model downloads | |
| uses: actions/cache@v4 | |
| with: | |
| path: models | |
| key: hf-models-rag-${{ runner.os }}-${{ hashFiles('packages/test/src/samples/**') }} | |
| restore-keys: | | |
| hf-models-rag-${{ runner.os }}- | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: build-output | |
| path: . | |
| - name: Run rag tests via vitest | |
| env: | |
| WORKGLOW_SECRETS_PASSPHRASE: ${{ secrets.WORKGLOW_SECRETS_PASSPHRASE }} | |
| run: bun run test:vitest:rag -- ${{ env.TEST_CHANGED }} | |
| - name: Copy Vitest coverage fragment | |
| run: | | |
| if [ -f coverage/coverage-final.json ]; then | |
| cp coverage/coverage-final.json vitest-rag-coverage.json | |
| else | |
| echo '{}' > vitest-rag-coverage.json | |
| fi | |
| - name: Upload Vitest coverage fragment | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: coverage-vitest-rag | |
| path: vitest-rag-coverage.json | |
| retention-days: 1 | |
| test-vitest-ai-provider-hft: | |
| runs-on: ubuntu-latest | |
| needs: build | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - run: bun i | |
| - name: Cache Hugging Face model downloads | |
| uses: actions/cache@v4 | |
| with: | |
| path: models | |
| key: hf-models-hft-${{ runner.os }}-${{ hashFiles('packages/test/src/samples/**') }} | |
| restore-keys: | | |
| hf-models-hft-${{ runner.os }}- | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: build-output | |
| path: . | |
| - name: Run HuggingFace Transformers provider tests via vitest | |
| env: | |
| WORKGLOW_SECRETS_PASSPHRASE: ${{ secrets.WORKGLOW_SECRETS_PASSPHRASE }} | |
| run: bun run test:vitest:ai-provider-hft -- ${{ env.TEST_CHANGED }} | |
| - name: Copy Vitest coverage fragment | |
| run: | | |
| if [ -f coverage/coverage-final.json ]; then | |
| cp coverage/coverage-final.json vitest-ai-provider-hft-coverage.json | |
| else | |
| echo '{}' > vitest-ai-provider-hft-coverage.json | |
| fi | |
| - name: Upload Vitest coverage fragment | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: coverage-vitest-ai-provider-hft | |
| path: vitest-ai-provider-hft-coverage.json | |
| retention-days: 1 | |
| test-vitest-ai-provider-nodellama: | |
| runs-on: ubuntu-latest | |
| needs: build | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - run: bun i | |
| - name: Cache Hugging Face / GGUF model downloads | |
| uses: actions/cache@v4 | |
| with: | |
| path: models | |
| key: hf-models-nodellama-${{ runner.os }}-${{ hashFiles('packages/test/src/samples/**') }} | |
| restore-keys: | | |
| hf-models-nodellama-${{ runner.os }}- | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: build-output | |
| path: . | |
| - name: Run LlamaCpp provider tests via vitest | |
| env: | |
| WORKGLOW_SECRETS_PASSPHRASE: ${{ secrets.WORKGLOW_SECRETS_PASSPHRASE }} | |
| run: bun run test:vitest:ai-provider-nodellama -- ${{ env.TEST_CHANGED }} | |
| - name: Copy Vitest coverage fragment | |
| run: | | |
| if [ -f coverage/coverage-final.json ]; then | |
| cp coverage/coverage-final.json vitest-ai-provider-nodellama-coverage.json | |
| else | |
| echo '{}' > vitest-ai-provider-nodellama-coverage.json | |
| fi | |
| - name: Upload Vitest coverage fragment | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: coverage-vitest-ai-provider-nodellama | |
| path: vitest-ai-provider-nodellama-coverage.json | |
| retention-days: 1 | |
| test-vitest-ai-provider-api: | |
| runs-on: ubuntu-latest | |
| needs: build | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - run: bun i | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: build-output | |
| path: . | |
| - name: Run API provider tests via vitest | |
| env: | |
| WORKGLOW_SECRETS_PASSPHRASE: ${{ secrets.WORKGLOW_SECRETS_PASSPHRASE }} | |
| run: bun run test:vitest:ai-provider-api -- ${{ env.TEST_CHANGED }} | |
| - name: Copy Vitest coverage fragment | |
| run: | | |
| if [ -f coverage/coverage-final.json ]; then | |
| cp coverage/coverage-final.json vitest-ai-provider-api-coverage.json | |
| else | |
| echo '{}' > vitest-ai-provider-api-coverage.json | |
| fi | |
| - name: Upload Vitest coverage fragment | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: coverage-vitest-ai-provider-api | |
| path: vitest-ai-provider-api-coverage.json | |
| retention-days: 1 | |
| merge-vitest-coverage: | |
| runs-on: ubuntu-latest | |
| needs: | |
| - test-vitest-unit | |
| - test-vitest-integration | |
| - test-vitest-rag | |
| - test-vitest-ai-provider-hft | |
| - test-vitest-ai-provider-nodellama | |
| - test-vitest-ai-provider-api | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - run: bun i | |
| - name: Download Vitest coverage fragments | |
| run: mkdir -p coverage-parts | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: coverage-vitest-unit | |
| path: coverage-parts | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: coverage-vitest-integration | |
| path: coverage-parts | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: coverage-vitest-rag | |
| path: coverage-parts | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: coverage-vitest-ai-provider-hft | |
| path: coverage-parts | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: coverage-vitest-ai-provider-nodellama | |
| path: coverage-parts | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: coverage-vitest-ai-provider-api | |
| path: coverage-parts | |
| - name: Merge coverage (nyc) and emit HTML/LCOV | |
| run: | | |
| shopt -s nullglob | |
| parts=(coverage-parts/*.json) | |
| if [ ${#parts[@]} -eq 0 ]; then | |
| echo "No coverage fragments (no tests ran for this change)" | |
| mkdir -p coverage | |
| exit 0 | |
| fi | |
| bunx nyc merge coverage-parts merged.json | |
| mkdir -p .nyc_output | |
| cp merged.json .nyc_output/out.json | |
| bunx nyc report --reporter=json --reporter=json-summary --reporter=html --reporter=lcov --reporter=text-summary --report-dir=coverage --temp-dir=.nyc_output | |
| - name: Upload merged Vitest coverage | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: vitest-coverage-merged | |
| path: coverage | |
| retention-days: 1 | |
| - name: Report Coverage | |
| if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && hashFiles('coverage/coverage-summary.json') != '' | |
| uses: davelosert/vitest-coverage-report-action@v2 | |
| cleanup: | |
| runs-on: ubuntu-latest | |
| needs: | |
| [ | |
| test-vitest-unit, | |
| test-vitest-integration, | |
| test-vitest-rag, | |
| test-vitest-ai-provider-hft, | |
| test-vitest-ai-provider-nodellama, | |
| test-vitest-ai-provider-api, | |
| merge-vitest-coverage, | |
| ] | |
| steps: | |
| - name: Delete build artifacts | |
| uses: geekyeggo/delete-artifact@v6 | |
| with: | |
| name: build-output | |
| - name: Delete Vitest coverage fragments | |
| uses: geekyeggo/delete-artifact@v6 | |
| with: | |
| name: coverage-vitest-* | |
| - name: Delete merged Vitest coverage | |
| uses: geekyeggo/delete-artifact@v6 | |
| with: | |
| name: vitest-coverage-merged |