build(client): use locked uv environment in launcher and Docker
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
# Backend development and compatibility
|
||||
|
||||
The FastAPI project lives entirely in `s2s-client/`. It uses uv 0.12.5, Python
|
||||
3.12, and a committed `uv.lock`. The frontend and speech pipeline keep their
|
||||
own tooling. Runtime dependency versions match the environment used to capture
|
||||
the pre-migration server; framework upgrades require a separate compatibility
|
||||
review.
|
||||
|
||||
## Commands
|
||||
|
||||
From the repository root:
|
||||
|
||||
```bash
|
||||
make -C s2s-client install # uv sync --locked, including development tools
|
||||
make -C s2s-client format # Ruff safe fixes and formatting
|
||||
make -C s2s-client check # lock freshness, format, lint, mypy, pytest
|
||||
make -C s2s-client test-launcher # Bash supervisor integration fixtures
|
||||
make -C s2s-client test-image # Docker build and isolated runtime smoke test
|
||||
```
|
||||
|
||||
Run `uv lock` inside `s2s-client/` when intentionally changing dependencies.
|
||||
Do not install server packages into a shared root environment. The launcher
|
||||
syncs `s2s-client/.venv` and retains root `.env` loading, port defaults,
|
||||
readiness checks, and process-group shutdown. Offline starts require the
|
||||
locked packages and Python runtime to have been installed or cached already.
|
||||
|
||||
Optional hooks use `make -C s2s-client hooks-install`; the configuration stays
|
||||
in `s2s-client/.pre-commit-config.yaml`. `make -C s2s-client hooks-run` runs the
|
||||
same hooks without installing them. Hooks and Python quality checks apply
|
||||
only to the client service. The server entry points are `s2s_client.main:app`
|
||||
and the retained `server:app` shim; use `--app-dir s2s-client` from the root.
|
||||
|
||||
## Schema boundaries
|
||||
|
||||
`models/requests.py` retains the existing search, reasoning, and ApiPilot
|
||||
request models, including their defaults, coercion, and ignored extra fields.
|
||||
The queue beacon still accepts malformed JSON and non-object bodies as before;
|
||||
its Pydantic view is applied only after the original object check, and
|
||||
`queueId` remains unconstrained.
|
||||
|
||||
`models/responses.py` validates structure constructed by this server. Fields
|
||||
owned by external services remain `Any` where the old parser imposed no type
|
||||
constraint. Object models allow extra fields. Caller profiles can be arbitrary
|
||||
JSON; load-balancer fields remain optional; execution results and error details
|
||||
remain open. Existing provider parsing, authentication precedence, argument
|
||||
filtering, environment parsing, and WebSocket frames are unchanged.
|
||||
|
||||
HTTP handlers call `validated_json_response`: Pydantic validates the payload,
|
||||
then `JSONResponse` serializes the original object. Returning a dumped model
|
||||
would insert defaults or change values/key order, so do not replace this helper
|
||||
with model serialization without a contract review. Route `response_model`
|
||||
declarations publish the new response schemas in OpenAPI. Existing request
|
||||
schemas and validation errors remain unchanged. HTTP exceptions retain their
|
||||
existing error shapes; there is no new common error envelope.
|
||||
|
||||
## Compatibility evidence
|
||||
|
||||
`tests/fixtures/legacy-contracts.json` was captured from the original monolithic
|
||||
server at commit `3d42df5`, before refactoring. Tests compare 86 HTTP scenarios,
|
||||
including exact response text, statuses, selected headers, and outgoing mock
|
||||
HTTP requests. They also compare request OpenAPI definitions and representative
|
||||
realtime frames. Additional tests cover response validation and permissive
|
||||
upstream values; the original local HTTP/WebSocket tests remain in the suite.
|
||||
|
||||
The captures deliberately preserve unknown fields, omitted fields, unusual JSON
|
||||
values, queue beacon edge cases, permissive tool arguments, and known failures.
|
||||
Examples include reasoning's existing uninitialized local variables in certain
|
||||
configuration combinations, API-key-only tool precheck behavior, the catalog
|
||||
cache's existing key, and relay termination after a suppressed invalid
|
||||
`session.update` error. Fix those in separately reviewed behavior changes;
|
||||
do not regenerate golden captures to make a refactor pass.
|
||||
|
||||
These checks use local fixtures and do not claim exhaustive coverage of all
|
||||
provider responses, live speech models, or production configuration. No deployed
|
||||
services or real credentials are needed. The Docker check verifies the actual
|
||||
runtime image, API configuration, documentation, OpenAPI, and the backend's
|
||||
existing root 404; it removes its temporary container and image afterward.
|
||||
Reference in New Issue
Block a user