From 299a416f51426cbb52660549412287e7455e0bc6 Mon Sep 17 00:00:00 2001 From: "Billy D." Date: Sat, 21 Feb 2026 15:46:24 -0500 Subject: [PATCH] =?UTF-8?q?docs:=20accept=20ADR-0061=20(Go=20handler=20ref?= =?UTF-8?q?actor),=20supersede=20ADR-0004=20(msgpack=E2=86=92protobuf)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All 5 handler services + companions-frontend migrated to handler-base v1.0.0 with protobuf wire format. golangci-lint clean across all repos. --- decisions/0004-use-messagepack-for-nats.md | 2 +- decisions/0061-go-handler-refactor.md | 46 +++++++++++++--------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/decisions/0004-use-messagepack-for-nats.md b/decisions/0004-use-messagepack-for-nats.md index 09b4cf9..138ad60 100644 --- a/decisions/0004-use-messagepack-for-nats.md +++ b/decisions/0004-use-messagepack-for-nats.md @@ -1,6 +1,6 @@ # Use MessagePack for NATS Messages -* Status: accepted +* Status: superseded by [ADR-0061](0061-go-handler-refactor.md) (Protocol Buffers) * Date: 2025-12-01 * Deciders: Billy Davies * Technical Story: Selecting serialization format for NATS messages diff --git a/decisions/0061-go-handler-refactor.md b/decisions/0061-go-handler-refactor.md index 3871e56..251fae5 100644 --- a/decisions/0061-go-handler-refactor.md +++ b/decisions/0061-go-handler-refactor.md @@ -1,7 +1,8 @@ # Refactor NATS Handler Services from Python to Go -* Status: proposed +* Status: accepted * Date: 2026-02-19 +* Decided: 2026-02-21 * Deciders: Billy * Technical Story: Reduce container image sizes and resource consumption for non-ML handler services by rewriting them in Go @@ -9,6 +10,8 @@ The AI pipeline's non-inference services — `chat-handler`, `voice-assistant`, `pipeline-bridge`, `tts-module`, and the HTTP-forwarding variant of `stt-module` — are Python applications built on the `handler-base` shared library. None of these services perform local ML inference; they orchestrate calls to external Ray Serve endpoints over HTTP and route messages via NATS with MessagePack encoding. +> **Implementation note (2026-02-21):** During the Go rewrite, the wire format was upgraded from MessagePack to **Protocol Buffers** (see [ADR-0004 superseded](0004-use-messagepack-for-nats.md)). The shared Go module is published as `handler-base` v1.0.0 (not `handler-go` as originally proposed). + Despite doing only lightweight I/O orchestration, each service inherits the full Python runtime and its dependency tree through `handler-base` (which pulls in `numpy`, `pymilvus`, `redis`, `httpx`, `pydantic`, `opentelemetry-*`, `mlflow`, and `psycopg2-binary`). This results in container images of **500–700 MB each** — five services totalling **~3 GB** of registry storage — for workloads that are fundamentally HTTP/NATS glue code. The homelab already has two production Go services (`companions-frontend` and `ntfy-discord`) that prove the NATS + MessagePack + OpenTelemetry pattern works well in Go with images under 30 MB. @@ -82,37 +85,42 @@ Chosen option: **Option 1 — Rewrite handler services in Go**, because the serv ## Implementation Plan -### Phase 1: `handler-go` Shared Module +### Phase 1: `handler-base` Go Module (COMPLETE) -Create `git.daviestechlabs.io/daviestechlabs/handler-go` as a Go module with: +Published as `git.daviestechlabs.io/daviestechlabs/handler-base` v1.0.0 with: | Package | Purpose | Python Equivalent | |---------|---------|-------------------| -| `nats/` | NATS/JetStream client with msgpack encoding | `handler_base.nats_client` | +| `natsutil/` | NATS publish/request/decode with protobuf encoding | `handler_base.nats_client` | | `health/` | HTTP health + readiness server | `handler_base.health` | | `telemetry/` | OTel traces + metrics setup | `handler_base.telemetry` | | `config/` | Env-based configuration (struct tags) | `handler_base.config` (pydantic-settings) | | `clients/` | HTTP clients for LLM, embeddings, reranker, STT, TTS | `handler_base.clients` | -| `milvus/` | Milvus vector search client | `pymilvus` wrapper in handler_base | +| `handler/` | Typed NATS message handler with OTel + health wiring | `handler_base.handler` | +| `messages/` | Type aliases from generated protobuf stubs | `handler_base.messages` | +| `gen/messagespb/` | protoc-generated Go stubs (21 message types) | — | +| `proto/messages/v1/` | `.proto` schema source | — | -Reference implementations: `companions-frontend/internal/` (NATS, msgpack, OTel), `ntfy-discord/internal/` (health, config, metrics). +### Phase 2: Service Ports (COMPLETE) -### Phase 2: Service Ports (in order of complexity) +All five services rewritten in Go and migrated to handler-base v1.0.0 with protobuf wire format: -| Order | Service | Rationale | -|-------|---------|-----------| -| 1 | `pipeline-bridge` | Simplest — NATS + HTTP + k8s API calls. Validates `handler-go` module. | -| 2 | `tts-module` | Tiny NATS ↔ HTTP bridge to external Coqui API | -| 3 | `chat-handler` | Core text pipeline — NATS + Milvus + HTTP calls | -| 4 | `voice-assistant` | Same pattern as chat-handler with audio base64 handling | -| 5 | `stt-module` (streaming) | Requires Go VAD bindings for the HTTP-forwarding variant | +| Order | Service | Status | Notes | +|-------|---------|--------|-------| +| 1 | `pipeline-bridge` | ✅ Done | NATS + HTTP + k8s API calls. Parameters changed to `map[string]string`. | +| 2 | `tts-module` | ✅ Done | NATS ↔ HTTP bridge. `[]*TTSVoiceInfo` pointer slices, `int32` casts. | +| 3 | `chat-handler` | ✅ Done | Core text pipeline. `EffectiveQuery()` standalone func, `int32(TopK)`. | +| 4 | `voice-assistant` | ✅ Done | Same pattern with `[]*DocumentSource` pointer slices. | +| 5 | `stt-module` | ✅ Done | HTTP-forwarding variant. `SessionId`/`SpeakerId` field renames, `int32(Sequence)`. | -### Phase 3: Cleanup +`companions-frontend` also migrated: 129-line duplicate type definitions replaced with type aliases from handler-base/messages. -* Archive Python versions of ported services -* Update Flux manifests for new Go images -* Update CI pipelines (Gitea Actions) for Go build/test/lint -* Update CODING-CONVENTIONS.md with Go section +### Phase 3: Cleanup (COMPLETE) + +* ~~Archive Python versions of ported services~~ — Python handler-base remains for Ray Serve/Kubeflow +* CI pipelines use `golangci-lint` v2 with errcheck, govet, staticcheck, misspell, bodyclose, nilerr +* All repos pass `golangci-lint run ./...` and `go test ./...` +* Wire format upgraded from MessagePack to Protocol Buffers (ADR-0004 superseded) ### What Stays in Python