Compare commits

...
5 Commits
Author SHA1 Message Date
jpmschweitzerandClaude Fable 5 cdd5a55613 chore: release v2.4.2
Build and Push / release (push) Successful in 3s
Build and Push / build (push) Successful in 1m3s
Fixes the v2.4.1 crash-loop: fresh image builds resolved
opentelemetry-api 1.44.0, which removed the private _events module
that pydantic-ai 1.27 imports at startup.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 13:10:57 +02:00
jpmschweitzerandClaude Fable 5 287d66fff7 chore: release v2.4.1
Build and Push / release (push) Successful in 3s
Build and Push / build (push) Successful in 2m44s
Move the container-name network-defaults change from [Unreleased] into
the 2.4.1 section and bump pyproject.toml. Patch release: the change
corrects service-host defaults (SEARXNG_HOST, LIBRARY_DESK_HOST,
CORE_API_HOST) for the docker-dataplane deployment, including the
wrong CORE_API_HOST port.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 12:32:10 +02:00
jpmschweitzerandClaude Fable 5 65debb6e44 fix(config): default service hosts to docker container names
The homelab is retiring *.schweitz.internal and will rebind host
ports to loopback; container-to-container traffic must use container
names on docker-dataplane.

- SEARXNG_HOST: http://localhost:8087 -> http://searxng:8080
  (SearXNG's internal port is 8080; 8087 was the host-published port)
- LIBRARY_DESK_HOST: http://localhost:8089 -> http://library-desk:8089
- CORE_API_HOST: http://localhost:8090 -> http://core-api:8083
  (8090 is the Scheduler's host port; Core-API serves 8083 internally,
  confirmed by the housekeeper client and test suite hitting :8083)
- scripts/test_housekeeper.sh: reach Core-API via localhost:8083
  instead of the LAN IP, which will refuse after loopback rebinding

Local development against host-published ports keeps working via .env
overrides (.env.example unchanged; localhost stays valid on the host).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 12:21:40 +02:00
jpmschweitzerandClaude Fable 5 0d7514b90e chore(ci): push images via git.schweitz.net registry
The .internal registry domain is being retired; git.schweitz.net now
serves the registry without SSO on /v2/.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 11:10:04 +02:00
jpmschweitzerandClaude Fable 5 99683357d2 docs: replace CPU-era latency figures with measured GPU numbers
The ~35s steward / ~2 min flow figures dated from the driver-mismatch era
and were being inherited by downstream consumers (desklock architecture
doc) as planning baselines. Current measured: steward ~6s warm, full flow
11-25s.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 17:17:13 +02:00
6 changed files with 28 additions and 12 deletions
+3 -3
View File
@@ -25,7 +25,7 @@ jobs:
- name: Login to Gitea Registry - name: Login to Gitea Registry
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: git.schweitz.internal registry: git.schweitz.net
username: ${{ secrets.REGISTRY_USER }} username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_PASSWORD }} password: ${{ secrets.REGISTRY_PASSWORD }}
@@ -37,8 +37,8 @@ jobs:
provenance: false provenance: false
sbom: false sbom: false
tags: | tags: |
git.schweitz.internal/jpmschweitzer/tatlock:latest git.schweitz.net/jpmschweitzer/tatlock:latest
git.schweitz.internal/jpmschweitzer/tatlock:${{ github.ref_name }} git.schweitz.net/jpmschweitzer/tatlock:${{ github.ref_name }}
- name: Trigger Watchtower update - name: Trigger Watchtower update
if: success() if: success()
+13
View File
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [2.4.2] - 2026-07-19
### Fixed
- Container crash-loop on fresh builds: cap `opentelemetry-api` below 1.44,
which removed the private `_events` module that pydantic-ai 1.27 imports
## [2.4.1] - 2026-07-19
### Changed
- **Container-name network defaults** - `SEARXNG_HOST`, `LIBRARY_DESK_HOST`, and `CORE_API_HOST` now default to docker container names on the docker-dataplane network (`http://searxng:8080`, `http://library-desk:8089`, `http://core-api:8083`) instead of host `localhost` ports, ahead of the loopback port rebinding; this also fixes `CORE_API_HOST` pointing at port 8090 (the Scheduler's host port) rather than Core-API's 8083. `scripts/test_housekeeper.sh` now reaches Core-API via `localhost:8083` instead of the LAN IP. Local development against host-published ports still works via `.env` overrides
## [2.4.0] - 2026-07-14 ## [2.4.0] - 2026-07-14
### Removed ### Removed
+1 -1
View File
@@ -27,7 +27,7 @@ Dependencies are in `pyproject.toml` (`[project.dependencies]` and `[project.opt
**Claude Sonnet 5+ rejects sampling parameters.** `temperature`/`top_p`/`top_k` return a 400. Use `get_sampling_settings()` from the model selector instead of passing `ModelSettings(temperature=...)` directly to agents that can run on the Claude fallback. The contract test suite pins this (`make test-contracts`). **Claude Sonnet 5+ rejects sampling parameters.** `temperature`/`top_p`/`top_k` return a 400. Use `get_sampling_settings()` from the model selector instead of passing `ModelSettings(temperature=...)` directly to agents that can run on the Claude fallback. The contract test suite pins this (`make test-contracts`).
**Integration test timeouts.** Set to 120s to match `OLLAMA_TIMEOUT` config (300s for the pure-Ollama fallback test, which cannot be rescued by Claude). The full local Steward → orchestrate → synthesize flow takes ~2 minutes on gemma4. Steward analysis alone needs ~35s warm — `STEWARD_TIMEOUT` defaults to 60s. **Integration test timeouts.** Set to 120s to match `OLLAMA_TIMEOUT` config (300s for the pure-Ollama fallback test, which cannot be rescued by Claude). Current GPU-resident numbers (2026-07-14, driver 570, gemma4:e2b at ~100 tok/s): Steward analysis ~6s warm, full Steward → orchestrate → synthesize flow 1125s, librarian-routed queries ~20-25s. The old "~35s steward / ~2 min flow" figures were measured during the CPU-only era (driver mismatch, 13 tok/s) — do not plan against them. Cold start after 2h idle adds ~8s (`OLLAMA_KEEP_ALIVE=2h`). `STEWARD_TIMEOUT` defaults to 60s.
**`get_benchmark_store` does not exist.** The benchmarking module (`src/core/benchmarks.py`) was never implemented. `scripts/benchmark_analysis.py` also references it and is broken. Do not add mocks for it in tests. **`get_benchmark_store` does not exist.** The benchmarking module (`src/core/benchmarks.py`) was never implemented. `scripts/benchmark_analysis.py` also references it and is broken. Do not add mocks for it in tests.
+4 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "tatlock" name = "tatlock"
version = "2.4.0" version = "2.4.2"
description = "OpenAI-compatible API with Ollama backend" description = "OpenAI-compatible API with Ollama backend"
requires-python = ">=3.12" requires-python = ">=3.12"
dependencies = [ dependencies = [
@@ -13,6 +13,9 @@ dependencies = [
"pydantic>=2.11,<2.13", "pydantic>=2.11,<2.13",
"pydantic-settings>=2.12,<2.13", "pydantic-settings>=2.12,<2.13",
"pydantic-ai-slim[openai,anthropic]>=1.27,<1.28", "pydantic-ai-slim[openai,anthropic]>=1.27,<1.28",
# pydantic-ai 1.27 imports the private opentelemetry._events module,
# removed in opentelemetry-api 1.44 — cap until pydantic-ai is bumped
"opentelemetry-api>=1.30,<1.44",
"anthropic>=0.77,<1.0", "anthropic>=0.77,<1.0",
"httpx>=0.28,<0.29", "httpx>=0.28,<0.29",
"sse-starlette>=3.0,<3.1", "sse-starlette>=3.0,<3.1",
+1 -1
View File
@@ -3,7 +3,7 @@
# Verifies room groups are controlled by checking actual state changes # Verifies room groups are controlled by checking actual state changes
API_URL="http://localhost:8777/v1/chat/completions" API_URL="http://localhost:8777/v1/chat/completions"
CORE_API="http://192.168.86.149:8083" CORE_API="http://localhost:8083"
RESULTS_FILE="/tmp/housekeeper_test_results.txt" RESULTS_FILE="/tmp/housekeeper_test_results.txt"
GREEN='\033[0;32m' GREEN='\033[0;32m'
+6 -6
View File
@@ -110,8 +110,8 @@ class Config(BaseSettings):
# SearXNG Configuration # SearXNG Configuration
SEARXNG_HOST: HttpUrl = Field( SEARXNG_HOST: HttpUrl = Field(
default="http://localhost:8087", default="http://searxng:8080",
description="SearXNG server URL" description="SearXNG server URL (container name; internal port 8080)"
) )
SEARXNG_TIMEOUT: int = Field( SEARXNG_TIMEOUT: int = Field(
default=30, default=30,
@@ -138,8 +138,8 @@ class Config(BaseSettings):
description="Total time budget for a librarian delegation in seconds" description="Total time budget for a librarian delegation in seconds"
) )
LIBRARY_DESK_HOST: HttpUrl = Field( LIBRARY_DESK_HOST: HttpUrl = Field(
default="http://localhost:8089", default="http://library-desk:8089",
description="Library-Desk API URL" description="Library-Desk API URL (container name; internal port 8089)"
) )
LIBRARY_DESK_API_KEY: str = Field( LIBRARY_DESK_API_KEY: str = Field(
default="", default="",
@@ -152,8 +152,8 @@ class Config(BaseSettings):
# Core-API Configuration (The Housekeeper backend) # Core-API Configuration (The Housekeeper backend)
CORE_API_HOST: HttpUrl = Field( CORE_API_HOST: HttpUrl = Field(
default="http://localhost:8090", default="http://core-api:8083",
description="Core-API URL for Home Assistant integration" description="Core-API URL for Home Assistant integration (container name; internal port 8083)"
) )
CORE_API_KEY: str = Field( CORE_API_KEY: str = Field(
default="", default="",