project-nomad/admin
Gabe Graves 8a920188de feat(ai): support local vision attachments
Closes #1176. Salvages @gabegraves's work from #1178, rebased onto the
RagPipelineService refactor that landed after it was written.

Adds JPEG/PNG/WebP attachments to chat over multipart, leaving text-only JSON
requests on their existing path. Images are normalized server-side to bounded
JPEG with metadata stripped, capped on count/size/pixels/output, and the
temporary uploads are cleaned up on every validation path. They are attached
only to the latest user message, are excluded from RAG, titles, logs and
persisted history, and are never written to storage.

Vision support is resolved per model from what the backend actually reports --
OpenAI-compatible /v1/models metadata, then Ollama /api/show, then llama.cpp
/props -- never inferred from a model name. A model that reports no vision
support has attachments disabled with a visible explanation; a backend that
reports nothing is allowed with a warning and its rejection is translated into
plain compatibility guidance rather than a raw error.

Changes from the original:

- Prompt assembly moved into RagPipelineService in the meantime, so the
  controller half is rebuilt against the trace and the multipart-aware
  collection filter is now the only one (dev's request.input() version would
  have silently dropped the collection on every image request).
- Added a native-path converter. dev split chat into native and OpenAI-compat
  paths after this was written; Ollama's native /api/chat does not take OpenAI
  content parts, it takes a sibling `images` array of bare base64. Without this
  every image request on a native Ollama backend would fail.
- Dropped the model-recommendation change (selectRecommendedModels and the
  Qwen3-VL fallback entry). Displacing a recommended model at first-time setup
  is a product decision and is being taken separately. The "Supports images"
  label in Easy Setup is kept: it describes what is already on offer rather
  than changing it.
- Dropped the DEFAULT_QUERY_REWRITE_MODEL download prompt his branch carried,
  which dev deleted in d022c2d.
- Removed a duplicate checkModelHasThinking; kept dev's memoized getModelInfo
  path, since thinking detection is not part of this feature.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F8Mgg1vd2eKSs8StZiuyMV
2026-09-29 15:54:41 -07:00
..
app feat(ai): support local vision attachments 2026-09-29 15:54:41 -07:00
bin feat: curated content system overhaul 2026-02-11 15:44:46 -08:00
commands fix(queue): stop stalled-job recovery forking the embedding chain 2026-09-29 15:54:41 -07:00
config fix: lazy-connect + retry for ioredis to avoid blocked startup 2026-06-23 17:40:10 +00:00
constants Revert "fix(zim): extract Kiwix catalog URL into system-wide constant" 2026-09-29 15:54:41 -07:00
database feat: show source document and date as citations under RAG chat answers 2026-09-29 15:54:41 -07:00
docs docs: answer the RAM question alongside disk 2026-09-29 15:54:41 -07:00
inertia feat(ai): support local vision attachments 2026-09-29 15:54:41 -07:00
providers fix(kiwix): self-heal a missing or corrupt library XML on startup 2026-06-23 04:46:56 +00:00
public feat(creator-packs): add missing Modern Rogue banner asset (#1147) 2026-08-04 03:39:52 +00:00
resources chore: standardize brand name to Project NOMAD, retire backronym 2026-08-04 03:37:32 +00:00
scripts refactor(drug-reference): make collections JSON the single source for curated data (#1130) 2026-08-04 03:38:35 +00:00
start feat: auto-generating OpenAPI docs with Scalar UI (#1128) 2026-08-04 03:38:33 +00:00
tests feat(ai): support local vision attachments 2026-09-29 15:54:41 -07:00
types feat(ai): support local vision attachments 2026-09-29 15:54:41 -07:00
util Add offline FDA drug reference (labels, interaction view, conditions, remedies) (#1040) 2026-08-04 03:38:33 +00:00
views chore: standardize brand name to Project NOMAD, retire backronym 2026-08-04 03:37:32 +00:00
.editorconfig feat: initial commit 2025-06-29 15:51:08 -07:00
.env.example feat(creator-packs): gated per-creator video packs, offline via Kiwix (#1106) 2026-08-04 03:38:27 +00:00
ace.js feat: initial commit 2025-06-29 15:51:08 -07:00
adonisrc.ts feat(GPU): auto-remediate nomad_ollama passthrough loss on admin boot (#755) 2026-05-20 10:16:00 -07:00
eslint.config.js feat: openwebui+ollama and zim management 2025-07-09 09:08:21 -07:00
package-lock.json chore(deps): bump axios and systeminformation in /admin 2026-08-04 03:38:40 +00:00
package.json feat(eval): standardized RAG quality evaluation harness (#1233) 2026-09-29 15:54:41 -07:00
tailwind.config.ts feat: initial commit 2025-06-29 15:51:08 -07:00
tsconfig.json Add offline FDA drug reference (labels, interaction view, conditions, remedies) (#1040) 2026-08-04 03:38:33 +00:00
vite.config.ts fix(Maps): ensure proper parsing of hostnames (#640) 2026-04-03 14:26:50 -07:00