Files
famapp/docs/decisions/0006-api-llm-agent.md

4.9 KiB

0006 — API auth and LLM agent architecture

Date: 2026-07-03 Status: accepted (2026-07-04)

Context

P1 needs a documented HTTP API with token auth coexisting with OIDC session auth, plus a provider-agnostic OpenAI-compatible agent that tool-calls the API. Tasks 87 (API surface) and 88 (agent chat) depend on these choices. Gitea: #14 (epic #13).

Existing auth: Authentik OIDC via Auth.js, database sessions, household-scoped data via getCurrentSession(). Mutations today are server actions; a handful of route handlers exist under /api/ for uploads, SSE, and auth.

What we decided (2026-07-04)

# Topic Choice
1 API token model One shared household token (not per-user)
1b Token management Household owner only — create, revoke, view last-used
2 API shape REST JSON under /api/v1/ — additive versioning
3 LLM provider Env-configured OpenAI-compatible endpoint (LLM_BASE_URL, optional LLM_API_KEY, LLM_MODEL)
4 Agent → API wiring Direct tools (JSON-schema tools → HTTP calls). No MCP server in v1

Decision

Token auth (coexists with OIDC session)

  • Add a single household-scoped API token stored hashed in the database (household_api_tokens or equivalent).
  • Non-browser clients send Authorization: Bearer <token>.
  • /api/v1/* route handlers accept either a valid Auth.js session cookie or a valid household bearer token. Both resolve to the same household scope and permission checks.
  • OIDC / browser login is unchanged. Middleware continues to guard pages; API routes perform their own auth (session or bearer).
  • Token lifecycle UI on /settings (owner only): create (show raw token once), revoke, last-used timestamp.
  • Activity log for API mutations may attribute actorId from session when present; bearer-token calls use actorId = null (same pattern as share-link anonymous mutations).

API shape

  • REST resources under /api/v1/ with JSON request/response bodies.
  • Additive versioning: new modules (journal, etc.) add routes under /api/v1/ without breaking existing clients. No v2 until a breaking change is unavoidable.
  • Task 87 covers: calendars, events, lists, list items, notes, garden (plants + containers), bangs. Dashboards deferred unless needed.
  • OpenAPI spec committed as living docs (docs/api/openapi.yaml or generated from route definitions).
  • Handlers call the same module server queries/actions as the web app — no parallel business logic.

LLM provider (task 88)

  • Famapp does not host a model. The agent client points at an external OpenAI-compatible HTTP API configured via environment variables.
  • Compatible with Ollama, vLLM, LiteLLM proxy, or any /v1/chat/completions-style endpoint on the homelab.
  • CI uses a mock/stub provider — no live LLM calls in tests.

Agent tool-calling (task 88)

  • Direct tools: the in-app agent defines tool schemas (name, description, parameters) that map to /api/v1/ HTTP methods. The agent loop calls the API with the household bearer token.
  • No MCP server in v1. Revisit if famapp needs to be a tool provider for Cursor or other MCP clients later.

Consequences

Positive

  • One token to configure for scripts, wife's automations, and the agent — simple for a two-user household.
  • REST + OpenAPI gives predictable integration and straightforward tool schema generation.
  • Session and bearer auth share household scope; web app behavior unchanged.
  • Direct tools avoid MCP transport, extra processes, and protocol overhead.

Trade-offs

  • Shared token: revoking it disables all non-browser clients at once; no per-person revocation.
  • Bearer calls lack a user actorId in activity log unless we add optional token metadata later.
  • Direct tools couple agent definitions to famapp's HTTP API; external MCP consumers would need a separate effort.

Implementation notes (task 87)

  • Schema: household_api_tokens with household_id, token_hash, name (e.g. "default"), last_used_at, created_by (owner), revoked_at.
  • Middleware: exempt /api/v1/ from session redirect; handlers enforce auth.
  • Settings: owner-only card for token create/revoke.
  • Tests: Vitest for bearer auth resolution, 401/403 paths, and representative CRUD handlers.

References

  • Task briefs: docs/tasks/87-api-surface.md, docs/tasks/88-llm-agent-chat.md
  • Design: docs/superpowers/specs/2026-07-03-backlog-triage-design.md