name: Interactive Shell Live (PR + post-merge) on: pull_request: branches: [main] paths: - "core/agent/**" - "core/agent_harness/**" - "tests/core/agent/**" - "surfaces/interactive_shell/**" - "core/runtime/**" - "tools/**" - "integrations/**" - "pytest.ini" - "pyproject.toml" - "uv.lock" - ".github/workflows/interactive-shell-live.yml" push: branches: [main] paths: - "core/agent/**" - "core/agent_harness/**" - "tests/core/agent/**" - "surfaces/interactive_shell/**" - "core/runtime/**" - "tools/**" - "integrations/**" - "pytest.ini" - "pyproject.toml" - "uv.lock" - ".github/workflows/interactive-shell-live.yml" workflow_dispatch: inputs: shard_indexes: description: "Comma-separated shard indexes to run (0-7)" required: false default: "0,1,2,3,4,5,6,7" permissions: contents: read concurrency: group: interactive-shell-live-${{ github.event.pull_request.number || github.sha }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: turn-checks: name: turn-checks (no-LLM) runs-on: ubuntu-latest timeout-minutes: 10 env: OPENSRE_DISABLE_KEYRING: "1" PYTHONUTF8: "1" steps: - uses: actions/checkout@v5 - name: Install uv uses: astral-sh/setup-uv@v8.1.0 with: enable-cache: true cache-dependency-glob: | pyproject.toml uv.lock - name: Set up Python uses: actions/setup-python@v6 with: python-version: "3.13" - name: Install dependencies run: uv sync --frozen --extra dev - name: Deterministic turn + fixture integrity run: >- uv run python -m pytest -n auto -v tests/core/agent/ -m "not live_llm" turn-live: # Run on push to main, manual dispatch, and same-repo PRs. Fork PRs have no # secrets, so they skip the live job (the no-LLM turn-checks job above # still gates them) instead of failing the credential-validation step. if: >- github.repository == 'Tracer-Cloud/opensre' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false) name: turn-live shard ${{ matrix.shard_index }} runs-on: ubuntu-latest timeout-minutes: 20 strategy: fail-fast: false matrix: shard_index: ${{ fromJSON(github.event_name == 'workflow_dispatch' && format('[{0}]', github.event.inputs.shard_indexes) || '[0, 1, 2, 3, 4, 5, 6, 7]') }} env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} LLM_PROVIDER: openai OPENSRE_DISABLE_KEYRING: "1" TURN_SHARD_TOTAL: "8" TURN_SHARD_INDEX: ${{ matrix.shard_index }} PYTHONUTF8: "1" # @live gather scenarios (316, 333–335, 337) require these secrets in CI. # Missing values fail the job in preflight and via skip_or_fail in tests. SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_ORG_SLUG: tracer-30 SENTRY_PROJECT_SLUG: python SENTRY_URL: https://sentry.io DD_API_KEY: ${{ secrets.DD_API_KEY }} DD_APP_KEY: ${{ secrets.DD_APP_KEY }} DD_SITE: datadoghq.com GRAFANA_READ_TOKEN: ${{ secrets.GRAFANA_READ_TOKEN }} GRAFANA_INSTANCE_URL: ${{ secrets.GRAFANA_INSTANCE_URL }} steps: - uses: actions/checkout@v5 - name: Install uv uses: astral-sh/setup-uv@v8.1.0 with: enable-cache: true cache-dependency-glob: | pyproject.toml uv.lock - name: Set up Python uses: actions/setup-python@v6 with: python-version: "3.13" - name: Install dependencies run: uv sync --frozen --extra dev - name: Validate live turn credentials run: | missing=() if [ -z "${OPENAI_API_KEY}" ]; then missing+=(OPENAI_API_KEY) fi if [ -z "${SENTRY_AUTH_TOKEN}" ]; then missing+=(SENTRY_AUTH_TOKEN) fi if [ -z "${DD_API_KEY}" ]; then missing+=(DD_API_KEY) fi if [ -z "${DD_APP_KEY}" ]; then missing+=(DD_APP_KEY) fi if [ ${#missing[@]} -gt 0 ]; then echo "::error::Missing secrets for live turn tests: ${missing[*]}" exit 1 fi - name: Run sharded live turn suite run: >- uv run python -m pytest -n auto -v -m live_llm tests/core/agent/test_turn_scenarios.py -k "test_live_turn_execution_oracle or test_live_action_planning"