{{ message }}
Default the episodic long-term memory backend to event memory - #1518
Open
edwinyyyu wants to merge 1 commit into
Open
Default the episodic long-term memory backend to event memory#1518edwinyyyu wants to merge 1 commit into
edwinyyyu wants to merge 1 commit into
Conversation
The configuration wizard has defaulted to `backend: event` for a while, but the static shipped configs (sample_configs/*.sample, the Helm ConfigMap) still wired the declarative VectorGraphStore backend, so every non-wizard install landed on declarative. Switch those defaults to the event backend (VectorStore + SegmentStore) and make the shipped stacks able to run it: - sample_configs cpu/gpu: `backend: event` with `vector_store: event_vector_store` and `segment_store: profile_storage`; the declarative block moves to a commented alternative. The nebula sample stays declarative on purpose -- it exists to demonstrate NebulaGraph -- and now says `backend: declarative` explicitly. - The Neo4j resource is commented out in the cpu/gpu samples. Resources are not lazy: ResourceManager.build() calls build_all(validate=True), so a configured but unused Neo4j entry would still make a reachable Neo4j server a startup requirement. - Qdrant becomes the shipped vector store. It is added to docker-compose (with a volume and a healthcheck that uses bash's /dev/tcp, since the image has no curl) and to the Helm chart (Deployment, Service, PVC, values). The Dockerfile now installs the `qdrant` extra, without which a qdrant resource fails to build inside the published image. - docker-compose moves Neo4j behind a `declarative` profile so the default `up` no longer starts or waits on it; `docker compose --profile declarative up` brings it back. memmachine-compose.sh waits on Qdrant instead, keeps the Neo4j wait for when that profile is active, and rewrites `localhost` to `qdrant` for qdrant resources the way it already does for postgres and neo4j. - Helm gains `memmachine.longTermMemory.backend` (default `event`). Only the database resource the selected backend needs is emitted, and the app's init container waits on Qdrant or Neo4j to match. `neo4j.enabled` now defaults to false so the chart does not provision an unused StatefulSet and RWX PVC. The parse-time default is unchanged: a config with no `backend` field still loads as declarative for backwards compatibility. The test that pinned this behaviour to the cpu sample is split in two -- one asserting the sample now declares the event backend, one asserting a synthesized pre-discriminator config still resolves to declarative. This does not migrate data. Memories written through the declarative backend live in Neo4j and are not visible to the event backend; existing deployments keep their own configuration.yml and are unaffected until they adopt the new samples. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Edwin Yu <edwinyyyu@gmail.com>
edwinyyyu
force-pushed
the
default-event-backend
branch
from
August 25, 2026 23:13
5cb3625 to
6c5b4bd
Compare
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.

Purpose of the change
The configuration wizard has defaulted to
backend: eventfor a while (configuration_wizard.py), but the static shipped configs still wired the declarative VectorGraphStore backend. So every install that does not go through the wizard --memmachine-compose.sh, the Helm chart, anyone copying a sample -- landed on declarative. This makes the event backend (VectorStore + SegmentStore) the default in the configuration files too, and makes the shipped stacks actually able to run it.Description
Configuration files
sample_configs/episodic_memory_config.{cpu,gpu}.sample:backend: eventwithvector_store: event_vector_storeandsegment_store: profile_storage. The declarative block is preserved as the commented alternative.sample_configs/episodic_memory_config.nebula.samplestays declarative on purpose -- it exists to demonstrate NebulaGraph as thevector_graph_store-- and now statesbackend: declarativeexplicitly with a pointer to the cpu/gpu samples.ResourceManager.build()callsDatabaseManager.build_all(validate=True), which connects to and validates every configured database. A configured-but-unused Neo4j entry would keep a reachable Neo4j server as a hard startup requirement, so leaving it defined would defeat the switch.memmachine.longTermMemory.backendvalue (defaultevent). Only the resource the selected backend needs is emitted, for the same eager-validation reason.Making the default runnable
Qdrant is the shipped vector store, matching what the samples already recommended and what the wizard picks when the extra is available.
Dockerfile: installs theqdrantextra. Without it,qdrant-clientis missing inside the published image and a qdrant resource fails to build. (Nopyproject.toml/uv.lockchange --qdrant-client>=1.17.0is already a declared optional dependency and is in the lock.)docker-compose.yml: adds aqdrantservice (pinnedv1.19.0), aqdrant_datavolume, and a healthcheck. The healthcheck probes the port with bash's/dev/tcpbecause the Qdrant image ships neither curl nor wget.docker-compose.yml: Neo4j moves behind adeclarativecompose profile, and MemMachine'sdepends_onswitches from Neo4j to Qdrant. A defaultdocker compose upno longer starts or blocks on a database nothing uses;docker compose --profile declarative upbrings it back.memmachine-compose.sh: waits on Qdrant, keeps the Neo4j wait for when that profile is running, prints the Qdrant endpoint, and rewriteslocalhostto theqdrantservice name for qdrant resources -- the same treatment postgres and neo4j already get.qdrant-deployment.yaml/qdrant-service.yaml/qdrant-pvc, aqdrant.*values block, and the app's init container waits on Qdrant or Neo4j to match the selected backend.One deliberate asymmetry to flag for review. In docker-compose the Neo4j service is kept (behind a profile) so switching back is easy. In Helm,
neo4j.enablednow defaults tofalse, so the chart does not provision an in-cluster Neo4j Deployment plus a 5Gi RWX PVC that nothing reads. Switching back is--set memmachine.longTermMemory.backend=declarative --set neo4j.enabled=true. Happy to flip that totrueif you would rather the chart keep deploying Neo4j by default.Not changed: the parse-time default. A config with no
backendfield still loads as declarative (_long_term_memory_backend_discriminator), so pre-discriminator configs keep working.Fixes/Closes
N/A
Type of change
How Has This Been Tested?
test_existing_sample_yaml_loads_as_declarative_via_full_configurationpinned both "the cpu sample has nobackendfield" and "a backend-less config resolves to declarative". Those are now separate tests: one asserts the sample declares the event backend and resolves toEventLongTermMemoryConf, the other synthesizes a pre-discriminator config and asserts it still resolves toDeclarativeLongTermMemoryConf.Test Results:
Every changed config was also validated against the real
Configurationpydantic model, not just parsed as YAML:backend='event' vector_store='event_vector_store' segment_store='profile_storage'memmachine-compose.sh's awk rewritepostgres/qdranthelm templatedefaultbackend='event' vector_store='db_qdrant' segment_store='db_postgres'helm template --set memmachine.longTermMemory.backend=declarative --set neo4j.enabled=truebackend='declarative' vector_graph_store='db_neo4j'Also checked:
docker compose configpasses;config --serviceslistsqdrant, docs, postgres, memmachineby default and addsneo4junder--profile declarative.helm templaterenders cleanly in both backend modes; the default render contains no Neo4j Deployment/Service/PVC.bash -n memmachine-compose.sh, and the awk rewrite was extracted and run against the new sample.uv lock --checkpasses (no dependency change).Not tested: an actual
docker compose upend to end, since no Docker daemon was available in this environment. The Qdrant healthcheck's reliance on bash in the Qdrant image is worth one live confirmation before merge (the image isdebian:13-slim-based, which includes bash but not curl).Checklist
Screenshots/Gifs
N/A
Further comments
Migration. This does not migrate data. Memories written through the declarative backend live in Neo4j and are not visible to the event backend. Existing deployments are unaffected until they adopt the new samples, because
configuration.ymlis gitignored and generated only when absent -- but a fresh install after this change will not see an old install's memories.Docs left alone deliberately. The provider-specific guides (
docs/install_guide/{ollama,aws_bedrock}.mdxand theirconfig/copies, the NebulaGraph integration guide, and the CloudFormation template incloud_deploy/aws_cloudformation.mdx) still show the declarative backend. Each is tied to a specific stack, and the CloudFormation one would need Qdrant added to the template. Happy to do those in a follow-up if you want them converted.Unrelated pre-existing issue noticed.
sample_configs/episodic_memory_config.nebula.samplefailsConfiguration.model_validateonsemantic_memory.config_databasebeing required but absent. This reproduces identically onmain, so it is untouched here -- flagging it rather than mixing the fix into this PR.🤖 Generated with Claude Code