Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
9c18c5c
Make NeMo preflight validate real adapter runtime
kaitwalla Sep 17, 2026
fcb22de
Make doctor run NeMo adapter diagnostics
kaitwalla Sep 17, 2026
e993432
Test real NeMo preflight and adapter env isolation
kaitwalla Sep 17, 2026
ba1b1fe
Add reproducible Hermes source installer
kaitwalla Sep 17, 2026
72c7bc0
Ignore locally installed source dependencies
kaitwalla Sep 17, 2026
b1ec396
Use shared Hermes installer in production image
kaitwalla Sep 17, 2026
c521364
Test Avo from a clean non-editable install
kaitwalla Sep 17, 2026
02489fb
Document the install path CI actually verifies
kaitwalla Sep 17, 2026
edcd97b
Fix clean-install workflow YAML
kaitwalla Sep 17, 2026
c39cba4
Treat NeMo warnings as nonfatal and anchor paths
kaitwalla Sep 17, 2026
bce1f63
Cover Fabric base_dir and warning diagnostics
kaitwalla Sep 17, 2026
5b275aa
Surface nonfatal NeMo doctor warnings
kaitwalla Sep 17, 2026
adc21e3
Allow persistent state path during init
kaitwalla Sep 17, 2026
4d6ea6d
Test persistent state configuration during init
kaitwalla Sep 17, 2026
0a7c82a
Document a persistent working Docker deployment
kaitwalla Sep 17, 2026
79d9486
Smoke test installed API and production container
kaitwalla Sep 17, 2026
b06b828
Use preinstalled NeMo adapter resolution
kaitwalla Sep 17, 2026
721645b
Validate Hermes model credentials before first run
kaitwalla Sep 17, 2026
7531e4c
Test Hermes credential preflight and resolution mode
kaitwalla Sep 17, 2026
6110e91
Satisfy Hermes credential preflight in image build
kaitwalla Sep 17, 2026
00c1e9c
Add local OpenAI-compatible runtime smoke server
kaitwalla Sep 17, 2026
a394f06
Execute a real Hermes turn in clean-install CI
kaitwalla Sep 17, 2026
3c8d64d
Pin Expo-compatible UI dependencies
kaitwalla Sep 17, 2026
74e3ae6
Validate chat route without assuming an empty default thread
kaitwalla Sep 17, 2026
17da5f4
Use Avo interpreter for NeMo adapter hosts by default
kaitwalla Sep 17, 2026
9869760
Test default NeMo adapter interpreter selection
kaitwalla Sep 17, 2026
d271be1
Document Hermes credentials and reachable model endpoints
kaitwalla Sep 17, 2026
7b4098d
Pin the validated Python and NeMo runtime contract
kaitwalla Sep 17, 2026
f0e9177
Fail fast on broken worker runtime before web startup
kaitwalla Sep 17, 2026
b2bbdce
Trust only active Avo repositories for Git operations
kaitwalla Sep 17, 2026
fb554ee
Test exact-path Git trust configuration
kaitwalla Sep 17, 2026
2caa35c
Smoke test every supported NeMo adapter extra
kaitwalla Sep 17, 2026
1f900ca
Respect Deep Agents max-turn capability
kaitwalla Sep 17, 2026
331a192
Lock Deep Agents runtime capability regression
kaitwalla Sep 17, 2026
d765039
Exercise installed chat flow end to end
kaitwalla Sep 17, 2026
b4a74d9
Add runtime-only NeMo Fabric extra for isolated adapters
kaitwalla Sep 17, 2026
2d3ff87
Prove Hermes works from a separate adapter virtualenv
kaitwalla Sep 17, 2026
d156e34
Install Hermes as a normal source-built package
kaitwalla Sep 17, 2026
7e28871
Preserve Hermes source checkout for supported editable install
kaitwalla Sep 17, 2026
dbdc188
Document durable Hermes and isolated adapter installs
kaitwalla Sep 17, 2026
ee3b66b
Fix chat acceptance smoke and avoid duplicate PR runs
kaitwalla Sep 17, 2026
84d3c78
Avoid duplicate adapter matrix runs on PR branches
kaitwalla Sep 17, 2026
061e297
Harden Hermes install and Git subprocesses
kaitwalla Sep 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 154 additions & 0 deletions .github/workflows/adapters.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
name: Avo Adapter Matrix

on:
push:
branches: [main]
pull_request:

jobs:
adapter-discovery:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- extra: codex
adapter: nvidia.fabric.codex
- extra: claude
adapter: nvidia.fabric.claude
- extra: deepagents
adapter: nvidia.fabric.langchain.deepagents
- extra: mini-swe-agent
adapter: nvidia.fabric.mini-swe-agent
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.12"
cache: pip
cache-dependency-path: pyproject.toml
- name: Create isolated environment
run: python -m venv "$RUNNER_TEMP/avo-adapter"
- name: Install Avo and adapter
env:
AVO_ADAPTER_EXTRA: ${{ matrix.extra }}
run: |
"$RUNNER_TEMP/avo-adapter/bin/python" -m pip install ".[${AVO_ADAPTER_EXTRA}]"
"$RUNNER_TEMP/avo-adapter/bin/python" -m pip check
- name: Resolve and plan installed adapter
env:
AVO_ADAPTER_ID: ${{ matrix.adapter }}
run: |
cd "$RUNNER_TEMP"
"$RUNNER_TEMP/avo-adapter/bin/python" - <<'PY'
import os
import sys
from pathlib import Path

from nemo_fabric import Fabric

from avo_harness.config import WorkerConfig
from avo_harness.worker import NeMoWorker, _adapter_python_env

adapter_id = os.environ["AVO_ADAPTER_ID"]
workspace = Path(os.environ["GITHUB_WORKSPACE"])
config = WorkerConfig(
backend="nemo",
adapter_id=adapter_id,
provider="openai",
model="smoke",
api_key_env="OPENAI_API_KEY",
base_url="http://127.0.0.1:1/v1",
env={"OPENAI_API_KEY": "smoke"},
timeout_seconds=5,
)
worker = NeMoWorker(config)
with _adapter_python_env(sys.executable):
fabric_config = worker._fabric_config(workspace)
plan = Fabric().plan(fabric_config, base_dir=workspace)
resolved = getattr(getattr(plan, "adapter", None), "adapter_id", None)
assert resolved == adapter_id, (resolved, adapter_id)
print(f"resolved {adapter_id} with {sys.executable}")
PY

isolated-hermes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.12"
cache: pip
cache-dependency-path: pyproject.toml
- name: Create separate Avo and Hermes environments
run: |
python -m venv "$RUNNER_TEMP/avo-main"
python -m venv "$RUNNER_TEMP/hermes-adapter"
- name: Install Avo runtime without the Hermes adapter
run: |
"$RUNNER_TEMP/avo-main/bin/python" -m pip install '.[fabric]'
"$RUNNER_TEMP/avo-main/bin/python" -m pip check
- name: Install Hermes only in the adapter environment
run: |
"$RUNNER_TEMP/hermes-adapter/bin/python" -m pip install 'nemo-fabric[hermes-agent]==0.2.0'
"$RUNNER_TEMP/hermes-adapter/bin/python" scripts/install_hermes.py "$RUNNER_TEMP/hermes-agent"
"$RUNNER_TEMP/hermes-adapter/bin/python" -m pip check
- name: Run Hermes through ADAPTER_PYTHON
run: |
"$RUNNER_TEMP/avo-main/bin/python" \
"$GITHUB_WORKSPACE/tests/support/openai_smoke_server.py" 18080 \
>"$RUNNER_TEMP/isolated-hermes-smoke.log" 2>&1 &
fixture_pid=$!
cleanup() {
kill "$fixture_pid" 2>/dev/null || true
}
trap cleanup EXIT

ready=0
for _ in $(seq 1 20); do
if curl -fsS http://127.0.0.1:18080/v1/models >/dev/null; then
ready=1
break
fi
sleep 0.25
done
if [ "$ready" -ne 1 ]; then
cat "$RUNNER_TEMP/isolated-hermes-smoke.log"
exit 1
fi

cd "$RUNNER_TEMP"
"$RUNNER_TEMP/avo-main/bin/python" - <<'PY'
import os
from pathlib import Path

from avo_harness.config import WorkerConfig
from avo_harness.worker import NeMoWorker

workspace = Path(os.environ["GITHUB_WORKSPACE"])
adapter_python = str(Path(os.environ["RUNNER_TEMP"], "hermes-adapter", "bin", "python"))
worker = NeMoWorker(
WorkerConfig(
backend="nemo",
adapter_id="nvidia.fabric.hermes",
provider="openai",
model="local-open-model",
base_url="http://127.0.0.1:18080/v1",
env={
"ADAPTER_PYTHON": adapter_python,
"OPENAI_API_KEY": "smoke",
},
max_turns=1,
timeout_seconds=30,
system_prompt="Do not use tools. Return the model response directly.",
)
)
preflight = worker.validate(workspace)
assert preflight.success, preflight.error
assert preflight.metadata["adapter_python"] == adapter_python
result = worker.run("Reply exactly AVO_HERMES_SMOKE_OK", workspace)
assert result.success, result.error
assert result.metadata["adapter_python"] == adapter_python
assert "AVO_HERMES_SMOKE_OK" in result.output, result.output
print(result.output)
PY
Loading
Loading