Commit fbb74d7
committed
memory/memu_bridge: route memU embeddings through MEMU_EMBEDDING_BASE_URL
Symptom: memory_recall returns "No relevant memories found" for any
query that should match a memory written after 2026-05-06. memU's
own logs reported route_category and recall succeeding, but vector
search at recall time was effectively disabled.
Root cause: memu_bridge gated the embedding LLM profile, the
"rag" retrieve method, and the categorize_items step exclusively on
self.config.openai_api_key. The 2026-05-05 sidecar work landed an
Ollama service in docker-compose.yml and set MEMU_EMBEDDING_BASE_URL
on the agent container, but the in-process bridge code never read
the env var. With openai_api_key cleared (the sidecar was supposed
to replace it) the bridge took the no-embed branch:
- _categorize_no_embed replaced categorize_items, persisting every
new item with embedding_json=NULL.
- retrieve_config["method"] resolved to "llm" instead of "rag", so
recall fanned out chat queries against the categories instead of
doing a cosine search over item vectors.
- _has_embeddings returned False, suppressing vector lookups
upstream of recall too.
5,100 of 6,888 memu_memory_items rows on the running container had
embedding_json=NULL; all 879 with embeddings dated to 2026-05-05
when the OpenAI key was still active. RCA in
notes/lessons/2026-05-09-memu-embeddings-not-wired.md.
Fix: resolve the embedding endpoint as env -> YAML -> OpenAI in one
place, set a single embeddings_configured flag, and key every
downstream behavior off that flag. Concretely:
- nerve/config.py: MemoryConfig gains embedding_base_url,
embedding_api_key, and llm_concurrency fields with env-var-aware
defaults. llm_concurrency clamps to >= 1 since 0 deadlocks the
semaphore wrapper.
- nerve/memory/memu_bridge.py:
- _initialize() reads MEMU_EMBEDDING_BASE_URL,
MEMU_EMBEDDING_API_KEY, and MEMU_EMBED_MODEL with YAML config
fallback. When base_url is set, registers the embedding profile
against that endpoint with api_key="placeholder" if not provided
(the OpenAI SDK requires a non-empty string; Ollama and TEI
ignore it).
- embeddings_configured = (env or YAML base URL set) OR (openai
key set). _categorize_no_embed only takes the no-embed path
when neither provider is configured. retrieve method is "rag"
when configured, "llm" otherwise. memory_extract_llm_profile
follows the same flag.
- _has_embeddings checks all three sources (env, YAML, OpenAI).
- Bounded asyncio.Semaphore wraps memU's chat calls so the
per-memory-type fan-out (4-way gather in memU's
extract_items pipeline) doesn't blow the Anthropic rate limit
on lower API tiers. Configurable via memory.llm_concurrency,
default 1. Re-instrumentation reuses the same Semaphore so
callers already queued don't lose their slot.
- SDK retries enabled at max_retries=4 (was 0). With concurrency
bounded, retries actually drain the queue instead of stacking.
- nerve/bootstrap.py: _build_docker_compose now writes the
embeddings service block (Ollama + nomic-embed-text), the
MEMU_EMBEDDING_* env vars on the nerve service,
depends_on: embeddings: condition: service_healthy, the
~/.nerve/claude bind mount for persisted Claude Code state,
the path-aligned ${HOME}/nerve-workspace and ${HOME}/projects
mounts, and /var/run/docker.sock for direct daemon access.
The entrypoint creates /root/* symlinks pointing at HOST_HOME so
hardcoded /root/nerve-workspace and /root/projects paths still
resolve. Brings nerve init regeneration in line with the live
host docker-compose.yml.
Tests: 18 new tests in test_memu_bridge.py covering the new
MemoryConfig fields, llm_concurrency clamping, and the semaphore
wrapper (serialization at concurrency=1, peak respect at
concurrency=3, instance reuse across resets). 4 updates in
test_bootstrap.py for the host-aligned mount assertions and the
NERVE_DOCKER unset that lets the test pass when run inside the
agent container.
Notes: the original 2026-05-05 stash also added a
"nerve-services = nerve.services:main" console-script entry to
pyproject.toml and assorted comments about a docker-mcp sidecar.
nerve/services lives only on the abandoned alex/docker-mcp-spike
branch, so installing with that entry breaks pip install -e. The
entry and the sidecar comments are dropped here. The
engine-SDK-resume-guard half of the original stash already shipped
on f39e62b and is excluded.1 parent 54542e0 commit fbb74d7
5 files changed
Lines changed: 533 additions & 62 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1847 | 1847 | | |
1848 | 1848 | | |
1849 | 1849 | | |
| 1850 | + | |
| 1851 | + | |
| 1852 | + | |
| 1853 | + | |
| 1854 | + | |
| 1855 | + | |
| 1856 | + | |
| 1857 | + | |
| 1858 | + | |
| 1859 | + | |
| 1860 | + | |
| 1861 | + | |
| 1862 | + | |
1850 | 1863 | | |
1851 | 1864 | | |
1852 | 1865 | | |
| |||
1870 | 1883 | | |
1871 | 1884 | | |
1872 | 1885 | | |
| 1886 | + | |
| 1887 | + | |
| 1888 | + | |
| 1889 | + | |
| 1890 | + | |
| 1891 | + | |
| 1892 | + | |
| 1893 | + | |
| 1894 | + | |
| 1895 | + | |
| 1896 | + | |
| 1897 | + | |
| 1898 | + | |
| 1899 | + | |
| 1900 | + | |
| 1901 | + | |
| 1902 | + | |
| 1903 | + | |
| 1904 | + | |
| 1905 | + | |
| 1906 | + | |
| 1907 | + | |
1873 | 1908 | | |
1874 | 1909 | | |
| 1910 | + | |
1875 | 1911 | | |
| 1912 | + | |
1876 | 1913 | | |
1877 | 1914 | | |
1878 | 1915 | | |
1879 | 1916 | | |
1880 | | - | |
1881 | | - | |
| 1917 | + | |
| 1918 | + | |
| 1919 | + | |
| 1920 | + | |
| 1921 | + | |
| 1922 | + | |
| 1923 | + | |
| 1924 | + | |
| 1925 | + | |
| 1926 | + | |
| 1927 | + | |
| 1928 | + | |
| 1929 | + | |
| 1930 | + | |
| 1931 | + | |
| 1932 | + | |
| 1933 | + | |
| 1934 | + | |
| 1935 | + | |
| 1936 | + | |
| 1937 | + | |
| 1938 | + | |
| 1939 | + | |
| 1940 | + | |
| 1941 | + | |
| 1942 | + | |
| 1943 | + | |
| 1944 | + | |
1882 | 1945 | | |
1883 | | - | |
| 1946 | + | |
| 1947 | + | |
| 1948 | + | |
| 1949 | + | |
| 1950 | + | |
| 1951 | + | |
| 1952 | + | |
| 1953 | + | |
| 1954 | + | |
| 1955 | + | |
| 1956 | + | |
| 1957 | + | |
| 1958 | + | |
| 1959 | + | |
| 1960 | + | |
| 1961 | + | |
| 1962 | + | |
1884 | 1963 | | |
1885 | 1964 | | |
1886 | 1965 | | |
1887 | | - | |
| 1966 | + | |
| 1967 | + | |
| 1968 | + | |
1888 | 1969 | | |
1889 | 1970 | | |
1890 | 1971 | | |
1891 | 1972 | | |
1892 | 1973 | | |
1893 | | - | |
1894 | | - | |
1895 | | - | |
1896 | 1974 | | |
1897 | 1975 | | |
1898 | 1976 | | |
| |||
1902 | 1980 | | |
1903 | 1981 | | |
1904 | 1982 | | |
| 1983 | + | |
| 1984 | + | |
| 1985 | + | |
| 1986 | + | |
| 1987 | + | |
| 1988 | + | |
| 1989 | + | |
| 1990 | + | |
| 1991 | + | |
| 1992 | + | |
| 1993 | + | |
1905 | 1994 | | |
1906 | 1995 | | |
1907 | 1996 | | |
1908 | | - | |
1909 | 1997 | | |
1910 | 1998 | | |
1911 | | - | |
1912 | | - | |
| 1999 | + | |
| 2000 | + | |
| 2001 | + | |
| 2002 | + | |
| 2003 | + | |
| 2004 | + | |
| 2005 | + | |
| 2006 | + | |
| 2007 | + | |
| 2008 | + | |
| 2009 | + | |
| 2010 | + | |
| 2011 | + | |
| 2012 | + | |
| 2013 | + | |
1913 | 2014 | | |
1914 | 2015 | | |
1915 | | - | |
| 2016 | + | |
| 2017 | + | |
| 2018 | + | |
| 2019 | + | |
| 2020 | + | |
| 2021 | + | |
| 2022 | + | |
| 2023 | + | |
| 2024 | + | |
| 2025 | + | |
| 2026 | + | |
| 2027 | + | |
| 2028 | + | |
| 2029 | + | |
| 2030 | + | |
| 2031 | + | |
| 2032 | + | |
| 2033 | + | |
1916 | 2034 | | |
1917 | 2035 | | |
1918 | 2036 | | |
1919 | 2037 | | |
1920 | 2038 | | |
1921 | 2039 | | |
1922 | 2040 | | |
1923 | | - | |
| 2041 | + | |
| 2042 | + | |
| 2043 | + | |
| 2044 | + | |
| 2045 | + | |
| 2046 | + | |
| 2047 | + | |
| 2048 | + | |
| 2049 | + | |
| 2050 | + | |
| 2051 | + | |
| 2052 | + | |
| 2053 | + | |
| 2054 | + | |
| 2055 | + | |
| 2056 | + | |
| 2057 | + | |
| 2058 | + | |
| 2059 | + | |
| 2060 | + | |
| 2061 | + | |
| 2062 | + | |
| 2063 | + | |
| 2064 | + | |
| 2065 | + | |
| 2066 | + | |
| 2067 | + | |
| 2068 | + | |
| 2069 | + | |
| 2070 | + | |
| 2071 | + | |
| 2072 | + | |
| 2073 | + | |
| 2074 | + | |
| 2075 | + | |
| 2076 | + | |
| 2077 | + | |
| 2078 | + | |
| 2079 | + | |
| 2080 | + | |
| 2081 | + | |
| 2082 | + | |
| 2083 | + | |
| 2084 | + | |
| 2085 | + | |
| 2086 | + | |
| 2087 | + | |
| 2088 | + | |
| 2089 | + | |
| 2090 | + | |
1924 | 2091 | | |
1925 | 2092 | | |
1926 | 2093 | | |
| |||
1937 | 2104 | | |
1938 | 2105 | | |
1939 | 2106 | | |
| 2107 | + | |
| 2108 | + | |
| 2109 | + | |
| 2110 | + | |
| 2111 | + | |
| 2112 | + | |
| 2113 | + | |
| 2114 | + | |
| 2115 | + | |
| 2116 | + | |
| 2117 | + | |
| 2118 | + | |
| 2119 | + | |
| 2120 | + | |
| 2121 | + | |
| 2122 | + | |
| 2123 | + | |
| 2124 | + | |
| 2125 | + | |
| 2126 | + | |
| 2127 | + | |
| 2128 | + | |
| 2129 | + | |
| 2130 | + | |
| 2131 | + | |
| 2132 | + | |
| 2133 | + | |
1940 | 2134 | | |
1941 | 2135 | | |
1942 | 2136 | | |
| |||
1960 | 2154 | | |
1961 | 2155 | | |
1962 | 2156 | | |
| 2157 | + | |
| 2158 | + | |
| 2159 | + | |
| 2160 | + | |
| 2161 | + | |
| 2162 | + | |
| 2163 | + | |
| 2164 | + | |
1963 | 2165 | | |
1964 | 2166 | | |
1965 | 2167 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
287 | 287 | | |
288 | 288 | | |
289 | 289 | | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
290 | 309 | | |
291 | 310 | | |
292 | 311 | | |
| |||
302 | 321 | | |
303 | 322 | | |
304 | 323 | | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
305 | 327 | | |
306 | 328 | | |
307 | 329 | | |
| |||
0 commit comments