Skip to content

feat(web-search): add WebSearchTask with pluggable search providers #3255

feat(web-search): add WebSearchTask with pluggable search providers

feat(web-search): add WebSearchTask with pluggable search providers #3255

Workflow file for this run

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