feat: add mlx-vlm support for Gemma 4 models - #1
Open
waylonkenning wants to merge 2 commits into
Open
Conversation
stamsam
reviewed
Apr 29, 2026
There was a problem hiding this comment.
Thanks for working on this. I’m new to the project, so please take this as a drive-by suggestion rather than anything authoritative. The overall direction makes sense to me: Gemma 4 seems to need a VLM-capable loader, and routing those models through mlx_vlm.server feels like the right shape.
A few things that might make this easier for the maintainer to merge:
- The README screenshot change looks unrelated to the runtime fix, so it might be cleaner as a separate PR.
model.includes("gemma-4")works with the current names, but explicit model/runtime metadata inAVAILABLE_MODELSmight age better, something likeruntime: "mlx-lm" | "mlx-vlm".- Checking for
mlx_vlmin everylocateMLX()call means setup can fail even for users who only want text/MLX-LM models. Maybe the VLM dependency could be checked/installed only when starting a VLM-backed model, unless the intent is for the managed venv to always include both runtimes. - This may overlap with #8, which moves the MLX server off the hardcoded Ollama port. If that lands first, this would probably want to use the selected port rather than
MLX_PORTdirectly. - The image payload formatting looks useful, but I’m not sure the current renderer sends images into
MLXChatMessageyet. Could be a follow-up unless it is needed for the crash fix.
Again, not trying to block anything here. This PR fixes an important problem; I just wanted to share a couple of review notes in case they help make the change smaller and easier to land.
MindXpansion
added a commit
to MindXpansion/gemma-chat
that referenced
this pull request
May 26, 2026
Stands up gemma-chat-memory — a fully isolated, RAG-grade Neo4j 5.x
database living inside the existing kg-arch-enterprise DBMS. Schema
pinned verbatim to docs/research/05-neo4j-voyageai-rag-design.md
(authored 2026-05-17 by Claude-as-neo4j-kg-architect, 1029 lines).
FOUNDATION (this patch, ~2 hrs work):
• New database gemma-chat-memory created inside kg-arch-enterprise
(Enterprise multi-DB — same heap/page-cache, fully isolated stores)
• Dedicated user `gemma-chat` with role `gemma_chat_rw`:
- GRANT ALL ON DATABASE gemma-chat-memory
- GRANT ALL ON GRAPH gemma-chat-memory ← critical, separate from DATABASE
- DENY ACCESS ON DATABASE neo4j (partnership KG)
- DENY ACCESS ON DATABASE system
• Generated password persisted to ~/.gemma-chat.env (mode 600)
• Full schema applied (idempotent, IF NOT EXISTS throughout):
- 10 uniqueness constraints (Document.uri, Document.sha256, all
UUID keys for Chunk/Image/Conversation/Turn/Summary/Observation/
Pattern + Workspace.id)
- 5 range indexes on created_at / started_at for time-window
queries
- 2 full-text indexes (chunk_text_ft, summary_text_ft) for hybrid
retrieval (vector + BM25) per research-05 §5
- 5 vector indexes (chunk/image/summary/observation/pattern
_embedding) at 1024-dim cosine, native vector-2.0 provider
DEFERS TO LATER PATCHES per research-05 §12 phased rollout:
• Patch 21 — voyageai-4-large ingestion of the 4 research docs (~$0.04)
• Patch 22 — aios.recall + reranker + citation packaging
• Patch 23 — aios.cite / aios.search_kg / aios.index
• Patch 24 — auto-conversation-ingestion (Turn/Summary autowrites)
• Patch 25 — backup launchd, ingest queue, UI badges, spend tracker
APP-SIDE WIRING:
• env-loader.ts: NEO4J_GEMMA_URI/USER/PASSWORD/DATABASE added to
whitelist, read from ~/.gemma-chat.env at app boot
• aios-neo4j.ts refactored to support TWO graph targets via
GraphTarget = 'partnership' | 'gemma':
- Per-target driver cache, lazy init, failure memo
- runCypher(target, cypher, params) — accepts both reads and
writes, surfaces write counters
- getSchemaSummary(target) — labels/rels/constraints, indicates
which graph
- closeNeo4j() drains both drivers cleanly on app quit
• New tools (symmetric to aios_kg_*):
- gemma_kg_schema() — your-own-graph schema
- gemma_kg_query(cypher, params) — read/write Cypher to gemma-
chat-memory. Vector search ready once Patch 21 ingests embed
chunks: `CALL db.index.vector.queryNodes('chunk_embedding', $k,
$vec) YIELD node, score`
• System prompt updated: explicit two-graph model — partnership KG
treads-carefully + own KG write-freely
SETUP SCRIPT (scripts/patch-20-foundation.cjs):
• Idempotent, re-runnable
• Reads admin creds from ~/.intelligence_partner/neo4j-creds.env
• Pre-flight in code AND verified manually before run: enterprise
edition, single :7687 listener (no Docker/Homebrew duplicate per
architect anti-pattern ammaarreshi#1), no existing gemma-chat-memory
• Smoke-tests after schema apply: probe document write+read+cleanup,
constraint-fires verification (duplicate INSERT correctly rejected)
• Rotates user password if user already exists
VERIFICATION (executed live, this commit):
✓ partnership driver: 69 labels reachable
✓ gemma driver: 10 constraints, 5 vector indexes, 2 fulltext, 15 range
✓ Isolation: gemma-chat user DENIED on database 'neo4j' (auth layer)
DESIGN DOC: docs/patch-20-gemma-own-kg-design.md distills research-05
into the patch sequence with risk assessment and Bear's three sign-off
decisions (voyage-4-large, demand-driven embedding, Foundation+Ingestion
tonight).
Build: vite clean. Pre-existing index.ts:22 hasMode warning unchanged.
Next: Patch 21 (voyageai-4-large ingestion of the 4 research docs +
minimum-viable recall tool). Will need a VOYAGE_API_KEY in
~/.gemma-chat.env or ~/.zshenv.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
MindXpansion
added a commit
to MindXpansion/gemma-chat
that referenced
this pull request
May 27, 2026
…ompt
Issue surfaced today: heartbeat-adjacent chat turn produced a clean ToM
output where every field parsed correctly EXCEPT user_intention, which
the model emitted as "clarifying" — not in our closed eight-value
enum. parseToM() silently dropped the field; the required-field guard
then nulled the entire UserMentalModel, so no UMM was written for that
turn, no PSV adaptation drove the response, and the operator only saw
a single `[tom] parse-failed wall=1836ms raw="..."` log line.
Two contributors, both fixed:
1. Prompt-side (proximate). The enum was listed but nothing forbade
inventing new values. Strengthened the line to
"pick EXACTLY one: ..." and added a note explicitly calling out the
three categories the model is most prone to invent
("clarifying" -> asking; "thanking" -> celebrating; "agreeing" ->
other) so the model has somewhere to put them.
2. Parser-side (defense in depth). Even with a tighter prompt, models
deviate. Instead of silently dropping, coerce unknown verbs to
"other" and log the original verb so we can see the deviation rate
in journal/console. This preserves the rest of the analyzer's read
(emotion, rapport, knowledge_gap, confidence) instead of nulling
everything because of one bad token.
Net effect: ToM keeps working through model deviation; we get an audit
trail of what the model tried to invent; nothing crashes.
Closes Issue ammaarreshi#1 of today's three-issue triage (parser was the only
fully-diagnosed item — timeout and stutter come next as separate
patches per agreed sequence).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue: Gemma 4 models crash with ValueError on startup
Description:
When attempting to run Gemma 4 models (e.g.,
gemma-4-e4b-it-4bit), the MLX server crashes with aValueError: Received 126 parameters not in model. This is because Gemma 4 is a multi-modal model that includes new architecture components (likek_normand vision/audio projectors) that the standardmlx-lmlibrary does not yet fully support in its default model loader.Fix:
This PR updates the MLX runtime management to use
mlx-vlmfor Gemma 4 models, which provides native support for the full Gemma 4 model family.Changes:
installMLXandlocateMLXto ensure bothmlx-lm>=0.31.0andmlx-vlm>=0.4.0are installed and verified.startServerto dynamically switch tomlx_vlm.serverwhen a Gemma 4 model is detected.chatStreamto support the OpenAI-compatible multi-modal message format (image_url), enabling the app to leverage Gemma 4's vision capabilities.mlx-vlm's "Started server process" message, preventing the UI from hanging during initialization.Fixes #2