Commit graph

1 commit

Author SHA1 Message Date
Rocker Zhang
38f1404432
fix(cli): fall back gracefully when embedding-server sidecar is absent (#1206)
## Description

`headroom proxy --embedding-server` crashes at startup with
`ModuleNotFoundError: No module named
'headroom.memory.adapters.watchdog'` instead of falling back to the
per-worker embedder. The `EmbeddingServerWatchdog` import sits above the
`try/except` that is meant to catch sidecar-startup failures, so a
missing sidecar module raises before the guard runs and takes the whole
proxy down. The sidecar module is not present on main (it ships with the
dedicated embedding-server sidecar work).

## Type of Change

- [x] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
- [ ] Performance improvement
- [ ] Code refactoring (no functional changes)

## Changes Made

- Move the `EmbeddingServerWatchdog` import into the guarded
`_start_embed_watchdog` coroutine in `headroom/cli/proxy.py`, so a
missing sidecar module is caught by the existing `try/except` and the
proxy degrades to the per-worker embedder.
- Add `tests/test_cli_proxy_embedding_server.py`, a regression test that
forces the sidecar module unimportable and asserts the flag falls back
instead of crashing.

## Testing

- [ ] Unit tests pass (`pytest`)
- [x] Linting passes (`ruff check .`)
- [ ] Type checking passes (`mypy headroom`)
- [x] New tests added for new functionality
- [x] Manual testing performed

### Test Output

```text
# The new regression test was validated fail-before / pass-after against the released
# build via click's CliRunner (forces the sidecar module unimportable, stubs run_server):
#   before fix (parent commit):  exit_code 1, ModuleNotFoundError, no fallback message
#   after fix:                    exit_code 0, no exception, "Falling back to per-worker embedder"
# ruff check . and ruff format --check . pass locally on the rebased branch.
# Full pytest suite / mypy not run locally; left to CI.
```

## Real Behavior Proof

- Environment: released build (headroom 0.26.0), Linux
- Exact command / steps: `headroom proxy --embedding-server --port 8799`
- Observed result: the proxy no longer crashes. Before the fix it exits
immediately with `ModuleNotFoundError: No module named
'headroom.memory.adapters.watchdog'`; after the fix it logs `WARNING:
Failed to start embedding server sidecar: No module named
'headroom.memory.adapters.watchdog'. Falling back to per-worker
embedder.`, then prints `URL: http://127.0.0.1:8799` and `Optimization:
ENABLED` and serves normally.
- Not tested: full pytest suite and mypy locally (left to CI)

## Review Readiness

- [x] I have performed a self-review
- [x] This PR is ready for human review

## Checklist

- [x] My code follows the project's style guidelines
- [x] I have performed a self-review of my code
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] I have updated the CHANGELOG.md if applicable

---------

Co-authored-by: JerrettDavis <mxjerrett@gmail.com>
2026-06-23 07:47:51 -05:00