v1.75.1 — the memory embedder resolves its endpoint from providers: yaml
A patch on the v1.75 line. One runtime fix plus the memory-architecture guide.
Repointing ollama-local at a new Ollama host the documented way —
providers: ollama-local: base_url: in loomcycle.yaml — moved CHAT but not the
EMBEDDER. providerbuild prefers the map entry, while the embedder read
cfg.Env.OllamaBaseURL only, so the two halves of one provider account resolved
independently.
Observed live: chat reached a newly-installed Ollama box and billed 50 calls
while every embed failed dial tcp: lookup <host> on 127.0.0.11:53: no such host — the env var named a Tailscale MagicDNS host, which does not resolve
against Docker's embedded DNS inside the container.
An embed failure warns but does not fail the write (by design: the k/v row is
kept, the response carries embedded:false + embed_warning), so a caller that
ignores that field just accumulates unembedded rows. A live scope reached 108
fact rows with ~0 embeddings and /v1/_memory/search 500'd, while every write
still reported 200.
The two copies of the per-provider base-URL switch are now one shared function.
base_url precedence, highest first:
memory.embedder.base_url > providers.<id>.base_url > the per-id env default
YAML is the config home; the env var is only the floor. Chat resolution is
unchanged — byte-identical inputs to every driver factory.
Two carve-outs, both covered by tests: anthropic inherits NEITHER half of its
chat entry (that embedder slot is a Voyage AI proxy, so an Anthropic proxy
base_url would receive Voyage requests and ANTHROPIC_API_KEY would be sent to
Voyage), and the per-id env KEY stays the last resort for a deployment with no
providers: block (the openai embedder accepts an empty key at construction and
only fails later at 401).
Operators: if the embedder endpoint is set via memory.embedder.base_url it
still wins by design — remove it to inherit the providers: entry. Either way
the address must be one the CONTAINER can resolve; prefer a tailnet IP or a
compose service name over a MagicDNS name. PUT /v1/_memory/scopes/<scope>/<id>/keys/<key>?embed=true
returns embed_warning naming the endpoint and the error — the whole diagnosis
in one call.
The memory architecture guide, with structure and state diagrams, exported from
the document store to docs/MEMORY-ARCHITECTURE.md.
Tagged as a patch but released with force_full, because the fix is in the Go
runtime: the patch tier alone builds only loomcycle-browser. Adapters are
unchanged and their publish jobs skip clean on version mismatch (no wire change).