Deduplication, observability, and CLI settings
Settings and constructs that sit outside MemorySettings for Configuration reference: the DeduplicationConfig dataclass and how it follows ResolutionConfig, the observability factory, and CLI configuration — plus how invalid values are validated.
Deduplication configuration
DeduplicationConfig is a dataclass from neo4j_agent_memory.memory.long_term. It belongs to the bolt LongTermMemory constructor; it is not a MemorySettings group or a MemoryClient constructor argument. There is no DeduplicationStrategy enum and no NAM_DEDUPLICATION__… environment family; variables with that prefix are ignored.
Since 0.7 the thresholds live on ResolutionConfig (Resolution configuration), and both write paths use them:
-
Message ingestion resolves extracted mentions with
OntologyResolver, the resolverstrategy="composite"builds on bolt, and bands them withauto_merge_thresholdandreview_threshold. -
MemoryClient builds its long-term store with
DeduplicationConfig.from_resolution_config(settings.resolution), which copiesauto_merge_threshold,review_threshold(asflag_threshold),fuzzy_threshold, andcandidate_limit(asmax_candidates). When the configured resolver is anOntologyResolver,add_entitydelegates its duplicate check to that resolver, so it bands exactly like ingestion. The dataclass thresholds drive the embedding-similarity check only with any other resolver.
Construct the dataclass yourself only when you build a LongTermMemory directly. Derive it from resolution settings so the two paths cannot drift:
from neo4j_agent_memory.config.settings import ResolutionConfig
from neo4j_agent_memory.memory.long_term import DeduplicationConfig, LongTermMemory
config = DeduplicationConfig.from_resolution_config(
ResolutionConfig(auto_merge_threshold=0.95, review_threshold=0.88)
)
# Use only when constructing a store explicitly with your connected graph client.
store = LongTermMemory(graph_client, embedder=embedder, deduplication=config)
add_entity checks only when an embedder is configured; add_entity(…, deduplicate=False) disables checking for that call. Per-entity-type thresholds belong on the ontology: EntityTypeDef.resolution_threshold and EntityTypeDef.review_threshold. See Deduplication and provenance for all fields and review/merge operations.
Observability configuration
There is no ObservabilityConfig on MemorySettings and no NAM_OBSERVABILITY__… family. Use the observability factory and provider SDK settings.
Install the extra for the provider you use: opentelemetry adds the OpenTelemetry API, SDK and OTLP exporter, and opik adds Opik. See Python extras.
pip install 'neo4j-agent-memory[opentelemetry]==0.7.0'
# Or: pip install 'neo4j-agent-memory[opik]==0.7.0'
This fragment assumes a connected MemoryClient named client and a query string, inside an async function:
from neo4j_agent_memory.observability import get_tracer
tracer = get_tracer(
provider="opentelemetry", service_name="my-agent-memory",
endpoint="http://localhost:4317",
)
# Or: get_tracer(provider="opik", project_name="my-agent-memory")
async with tracer.async_span("entity-search") as span:
span.set_attribute("query_length", len(query))
result = await client.long_term.search_entities(query)
get_tracer accepts auto, opentelemetry, opik, and noop; auto-detection depends on installed libraries. Instrument the operations you intend to trace. OpenTelemetry export requires an explicit endpoint and an installed OTLP exporter; merely setting OTEL_EXPORTER_OTLP_ENDPOINT does not install an exporter on this tracer. Use tracer.span for a synchronous context manager or tracer.async_span for an async one.
CLI configuration
The CLI exposes command-specific Click options and environment aliases; see CLI reference. It does not automatically read .neo4j-memory.yaml, nor does it implement NAM_CLI__…. An extraction --schema argument is a YAML EntitySchemaConfig file path, not a CLI settings file or named built-in schema; use --gliner-schema for a built-in template name and --ontology for an ontology document.
Validation
Numeric constraints appear in each field table. Invalid enum values or unknown constructor/nested fields raise Pydantic ValidationError, and so does a ResolutionConfig whose review_threshold exceeds its auto_merge_threshold. Missing optional provider packages may instead fail during provider construction; connection and model requests have their own errors.
from pydantic import ValidationError
from neo4j_agent_memory.config.settings import ResolutionConfig
try:
ResolutionConfig(semantic_threshold=1.5)
except ValidationError as exc:
print(exc.errors()[0]["type"]) # less_than_equal