feat: Task 10 — AMQP connection layer with aio-pika

amqp.py: connect/disconnect/get_channel/publish with auto-reconnect
  - Graceful degradation when aio-pika not installed
  - Lazy secret file reader via config.get_amqp_url()
  - Fire-and-forget publish (logs error, never raises)
  - Connection errors caught and logged (non-fatal)

config.py: AMQP_RECONNECT_DELAY, exchanges, get_amqp_url() helper

app.py: connect in lifespan after assess_hardware, disconnect on shutdown

requirements.txt: aio-pika>=9.0.0

tests/test_amqp.py: 3 mocked tests (publish success, publish disconnected
no-raise, get_channel reconnect)

135 tests pass (132 existing + 3 new)
Fixes: AGENTS.md test/run commands (venv was incomplete)
This commit is contained in:
gramps
2026-07-06 08:51:36 -07:00
parent 659339cb1f
commit 975e7579cf
9 changed files with 210 additions and 3 deletions
+3
View File
@@ -14,6 +14,7 @@ from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from amqp import connect as amqp_connect, disconnect as amqp_disconnect
from config import VERSION, RATE_WINDOW_SECONDS, UPLOAD_DIR, RAG_MAX_VECTORS, RAG_EVICTION_HIGH_WATER, RAG_EVICTION_LOW_WATER, RAG_EVICTION_BATCH
from db import init_db
from hardware import assess_hardware
@@ -57,6 +58,7 @@ async def lifespan(app: FastAPI):
init_db()
log.info(f"Memory system: {get_memory_count()} memories loaded")
await assess_hardware()
await amqp_connect()
if RAG_MAX_VECTORS > 0:
if RAG_EVICTION_HIGH_WATER <= RAG_EVICTION_LOW_WATER:
@@ -71,6 +73,7 @@ async def lifespan(app: FastAPI):
yield
log.info("JarvisChat shutting down")
await amqp_disconnect()
app = FastAPI(title="JarvisChat", lifespan=lifespan)