Skip to content

feat(agents): add OpenCode agent adapter (#5001) #1378

feat(agents): add OpenCode agent adapter (#5001)

feat(agents): add OpenCode agent adapter (#5001) #1378

Workflow file for this run

# Always-run workflow with internal path gating + aggregator. See #364.
#
# Why: branch protection on `main` requires specific checks to pass on
# every PR. A top-level `paths:` filter would make this workflow silently
# absent on unrelated PRs, leaving any required check stuck pending. So
# the workflow always runs; `changes` decides whether jobs do real work
# or skip; `python-complete` aggregates and reports one final status
# that branch protection requires.
name: python-ci
on:
push:
branches:
- main
pull_request:
workflow_dispatch:
env:
CI: true
concurrency:
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
changes:
runs-on: ubuntu-latest
outputs:
relevant: ${{ steps.detect.outputs.relevant }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: ./.github/actions/detect-changes
id: detect
with:
filters: |
relevant:
- 'python/**'
- '.github/workflows/python-ci.yml'
test:
needs: changes
if: needs.changes.outputs.relevant == 'true'
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.12"] # Focus on primary version for performance
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@7f4fc3e22c37d6ff65e88745f38bd3157c663f7c # v4
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- name: Cache dependencies
uses: actions/cache@6f8efc29b200d32929f49075959781ed54ec270c # v3
with:
path: |
.venv
~/.cache/uv
key: ${{ runner.os }}-uv-${{ hashFiles('**/pyproject.toml', '**/uv.lock') }}
restore-keys: |
${{ runner.os }}-uv-
- name: Install dependencies
run: uv sync --frozen
working-directory: python
- name: Verify capability matrix is in sync with AdapterCapabilities
run: |
uv run python scripts/gen_capability_matrix.py
git diff --exit-code ../docs/docs/pages/_generated/voice/capability-matrix.mdx \
|| (echo "Capability matrix is stale. Run 'python scripts/gen_capability_matrix.py' and commit the regen." && exit 1)
working-directory: python
- name: Run tests
# `-m "not integration"` deselects voice e2e tests (auto-marked by
# tests/voice/conftest.py). Those hit live providers and run nightly
# via voice-integration.yml.
run: uv run pytest tests/ -v --tb=short -m "not integration"
working-directory: python
- name: Type check
run: uv run pyright .
working-directory: python
# Examples — skipped for Dependabot PRs since they don't have access to repo secrets
- name: Test (Examples)
# Examples hit real LLMs over the network; they can legitimately take
# well over the 60s per-test timeout that pytest.ini sets for the unit
# suite. Override to 300s here so slow-but-correct runs don't get
# pytest-timeout'd.
run: uv run pytest examples/ -v --tb=short --timeout=300
env:
LANGWATCH_API_KEY: ${{ secrets.LANGWATCH_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
working-directory: python
# One required check for the whole workflow. Reports success if every
# upstream job either passed or was legitimately skipped (paths didn't
# match). Reports failure if any upstream job failed.
python-complete:
needs: [changes, test]
if: always()
runs-on: ubuntu-latest
steps:
- name: Verify all needs succeeded or were legitimately skipped
run: |
echo '${{ toJSON(needs) }}' | jq -e 'to_entries | all(.value.result == "success" or .value.result == "skipped")'