Skip to content

feat: add ai-kit health tracking for both AI stacks, exposed via /api/health - #417

Merged
catomean merged 2 commits into
mainfrom
feat/ai-kit-health-tracking
Aug 31, 2026
Merged

feat: add ai-kit health tracking for both AI stacks, exposed via /api/health#417
catomean merged 2 commits into
mainfrom
feat/ai-kit-health-tracking

Conversation

@catomean

Copy link
Copy Markdown
Collaborator

Summary

  • evig has two independent AI provider systems — src/lib/hirn/providers (DB-backed, admin-configurable, per-user) and src/lib/ai/providers.ts (env-based cascade for form-assist/advisors/blog-translate). Both correctly stay OFF ai-kit's chain/model layer — each already owns a model registry ai-kit doesn't model, same reasoning fleet/SHARED.md documents for kivvi and orangecat.
  • Both lacked persistent health state. /api/health has only ever checked database + Meilisearch — an AI outage was invisible to it, the exact blind spot that took down botsmann's chat this session.
  • New: src/lib/hirn/health.ts + src/lib/ai/health.ts — two separate ai-kit createHealthTracker instances (a bug isolated to one stack shows as one named service, not an averaged bucket).
  • hirn/providers/index.ts: new getChatResponse() consolidates 3 call sites that duplicated getDefaultChatProvider() + .chat() with nothing recording the outcome.
  • ai/providers.ts: callWithFallback/callVisionWithFallback's existing cascade logic is untouched — 2 lines added at each function's existing return points.
  • /api/health/route.ts: adds hirn and aiTools as named services. An AI outage can only push overall status to degraded, never unhealthy/503 — that's reserved for the database, since a dead API key isn't fixed by a restart.
  • jest.config.js: ai-kit is ESM-only; added to both transformIgnorePatterns allowlists, the same two-place fix botsmann's jest.config already documents.
  • Fixes a stale catomean org ref on @fleet/ai-forms.

Test plan

  • Full verify green: eslint (whole repo), lint:umlauts, compliance:ci (0 new violations), typecheck, 7775 tests (40 new), production build
  • CI green on this PR

catomean and others added 2 commits August 31, 2026 09:47
…/health

evig has two independent AI provider systems -- src/lib/hirn/providers
(DB-backed, admin-configurable, per-user; powers Hirn chat) and
src/lib/ai/providers.ts (env-based cascade; powers form-assist,
protocol/task/vote advisors, smart product entry, blog translation).
Both are correctly NOT adopting ai-kit's chain/model layer -- each
already owns a model registry (context windows, tool/vision support,
per-token cost) that ai-kit does not model, the same reasoning
documented in fleet/SHARED.md for kivvi and orangecat.

What both lacked was persistent health state. /api/health has checked
only the database and Meilisearch since it existed -- an AI outage was
invisible to it, the same blind spot that took down botsmann's chat
this session (a friendly fallback and a database-only health check
that both kept reporting "healthy").

- src/lib/hirn/health.ts + src/lib/ai/health.ts (new): two SEPARATE
  ai-kit createHealthTracker instances -- a bug isolated to one stack
  should show as one named service going down, not get averaged into
  a single "AI" bucket.
- hirn/providers/index.ts: new getChatResponse() wraps
  getDefaultChatProvider + .chat() + health recording in one step.
  Three call sites (chat.ts, the public chat route, deliverables/ai.ts)
  used to duplicate that pair with nothing recording whether it
  worked; all three now call getChatResponse instead.
- ai/providers.ts: callWithFallback/callVisionWithFallback already had
  solid cascade + error-categorization logic (Groq -> OpenRouter ->
  Ollama, auth/rate_limit/network/timeout reasons) -- untouched. Two
  lines added at each function's existing return points to record the
  outcome, using the already-exported buildFailureMessage for a
  readable lastError.
- /api/health/route.ts: adds hirn and aiTools as named services,
  mapped onto the existing healthy/degraded/unhealthy vocabulary.
  "unknown" (nothing attempted since restart) reads as healthy, and --
  matching the file's own existing rule for Meilisearch -- an AI
  outage can only ever push the overall status to degraded, never to
  the unhealthy/503 that's reserved for the database. A dead API key
  is not fixed by a restart, so it must never fail whatever gate
  decides whether to kill this process.
- jest.config.js: ai-kit is ESM-only, Jest runs CJS -- added to both
  transformIgnorePatterns allowlists (the static one and next/jest's
  own generated one), the exact two-place fix botsmann's jest.config
  already documents for the same package.
- One existing test (chat.test.ts) mocked getDefaultChatProvider
  directly; updated to mock getChatResponse, the function chat.ts
  actually calls now. No other existing test needed changes.
- Fixes a stale catomean org reference on @fleet/ai-forms while
  editing this dependency block.

ai-kit bumped to v0.5.0. Full verify green: eslint (whole repo),
lint:umlauts, compliance:ci (SSOT/i18n/hardcoded-strings/leaks, 0 new
violations), typecheck, 7775 tests (40 new), production build.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…acking

# Conflicts:
#	package-lock.json
#	package.json
@catomean
catomean merged commit 224ebcd into main Aug 31, 2026
8 checks passed
@catomean
catomean deleted the feat/ai-kit-health-tracking branch August 31, 2026 08:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant