memorymaster 3.15.0__tar.gz → 3.16.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {memorymaster-3.15.0/memorymaster.egg-info → memorymaster-3.16.0}/PKG-INFO +15 -1
- {memorymaster-3.15.0 → memorymaster-3.16.0}/README.md +14 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/config.py +25 -5
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/retrieval.py +74 -4
- {memorymaster-3.15.0 → memorymaster-3.16.0/memorymaster.egg-info}/PKG-INFO +15 -1
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster.egg-info/SOURCES.txt +2 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/pyproject.toml +1 -1
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_config.py +7 -1
- memorymaster-3.16.0/tests/test_retrieval_rrf_tiebreaker.py +84 -0
- memorymaster-3.16.0/tests/test_retrieval_weights.py +69 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/LICENSE +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/artifacts/bm25-per-field-eval-harness.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/benchmarks/longmemeval_runner.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/benchmarks/longmemeval_vector_runner.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/benchmarks/perf_smoke.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/__init__.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/__main__.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/_storage_lifecycle.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/_storage_read.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/_storage_schema.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/_storage_shared.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/_storage_sources.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/_storage_write_claims.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/access_control.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/action_exporters.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/action_extractor.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/atlas_claim_extractor.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/atlas_contract.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/auto_extractor.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/auto_resolver.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/candidate_dedupe.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/claim_edges.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/claim_verifier.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/cli.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/cli_handlers_basic.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/cli_handlers_curation.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/cli_helpers.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/closets.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/config_templates/claude-md-append.md +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/config_templates/codex-agents-md-append.md +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/config_templates/hooks/memorymaster-auto-ingest.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/config_templates/hooks/memorymaster-classify.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/config_templates/hooks/memorymaster-dream-sync.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/config_templates/hooks/memorymaster-precompact.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/config_templates/hooks/memorymaster-recall.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/config_templates/hooks/memorymaster-session-start.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/config_templates/hooks/memorymaster-steward-cycle.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/config_templates/hooks/memorymaster-validate-wiki.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/conflict_resolver.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/connectors/__init__.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/connectors/whatsapp.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/context_hook.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/context_optimizer.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/daily_notes.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/dashboard.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/db_merge.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/dream_bridge.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/embeddings.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/entity_extractor.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/entity_graph.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/entity_registry.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/federated_graphify.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/feedback.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/graph_store.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/hook_log.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/jobs/__init__.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/jobs/calibration.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/jobs/compact_summaries.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/jobs/compactor.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/jobs/decay.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/jobs/dedup.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/jobs/deterministic.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/jobs/entity_graph_export.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/jobs/extractor.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/jobs/staleness.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/jobs/validator.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/key_rotator.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/lifecycle.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/llm_provider.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/llm_rerank.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/llm_steward.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/mcp_server.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/mcp_usage.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/media_processing.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/media_providers.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/metrics_exporter.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/models.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/observability.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/operator.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/operator_queue.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/plugins.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/policy.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/postgres_store.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/qdrant_backend.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/qdrant_recall_fallback.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/qmd_bridge.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/query_classifier.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/query_expansion.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/recall_fusion.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/recall_tokenizer.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/retry.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/review.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/rl_trainer.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/scheduler.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/schema.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/schema.sql +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/schema_postgres.sql +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/scope_utils.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/security.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/service.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/session_tracker.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/setup_hooks.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/skill_evolver.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/snapshot.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/steward.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/steward_classifier.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/steward_features.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/storage.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/store_factory.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/transcript_miner.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/turn_schema.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/vault_bases.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/vault_curator.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/vault_exporter.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/vault_linter.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/vault_log.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/vault_query_capture.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/vault_synthesis.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/verbatim_recall.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/verbatim_store.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/webhook.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/wiki_engine.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/wiki_freshness.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/wiki_similarity.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/wiki_suggest.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/wiki_validate.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster.egg-info/dependency_links.txt +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster.egg-info/entry_points.txt +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster.egg-info/requires.txt +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster.egg-info/top_level.txt +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/agg_recall_latency.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/alert_operator_metrics.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/audit_dedupe_precision.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/autoresearch_daemon.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/backfill_entity_extraction.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/backfill_graph_store.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/backfill_stop_hook_citations.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/backtest_steward_classifier.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/build_steward_training_set.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/check_hook_template_drift.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/claude_to_turns.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/codex_live_to_turns.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/compaction_edge_cases.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/compaction_trace_report.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/compaction_trace_validate.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/confusion_matrix_eval.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/conversation_importer.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/conversation_to_turns.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/e2e_operator.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/email_live_to_turns.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/eval_bm25_sweep.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/eval_classify_f1.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/eval_memorymaster.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/eval_recall_precision_at_5.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/eval_recall_quality.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/eval_steward_pareto.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/eval_verbatim_recall.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/expand_recall_eval.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/generate_drill_signoff.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/git_to_turns.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/github_live_to_turns.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/gitnexus_to_claims.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/grid_recall_weights.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/index_claims_to_qdrant.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/ingest_planning_docs.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/jira_live_to_turns.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/label_prompts_with_judge.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/llm_benchmark.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/measure_dedupe_thresholds.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/merge_scope_variants.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/messages_to_turns.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/operator_metrics.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/precompute_candidates.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/recurring_incident_drill.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/release_readiness.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/run_codex_autologger.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/run_incident_drill.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/scheduled_ingest.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/setup-hooks.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/slack_live_to_turns.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/sync_hook_templates.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/tickets_to_turns.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/train_steward_classifier.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/scripts/webhook_to_turns.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/setup.cfg +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/bench_longmemeval.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/conftest.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/integration/test_extract_llm_ollama_live.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_access_control.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_action_exporters.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_action_extractor.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_atlas_claim_extractor.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_atlas_contract.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_atlas_source_schema.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_auto_extractor.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_auto_ingest_hook_citations.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_auto_ingest_hook_schema.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_auto_resolver.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_auto_validate.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_bm25_per_field.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_calibration.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_calibration_priors_applied.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_candidate_dedupe.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_claim_edges.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_claim_links.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_claim_type_ranking.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_classify_hook_f1.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_classify_hook_latency.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_claude_to_turns.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_cli_dry_run.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_cli_json_flag.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_cli_ready.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_cli_review_queue.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_cli_subcommands.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_closets.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_closets_recall_integration.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_compact_summaries.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_compact_summaries_sensitivity.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_compaction_trace.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_compactor_artifact_order.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_conflict_resolver.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_confusion_matrix_eval.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_connection_retry.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_connectors.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_context_hook.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_context_optimizer.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_context_optimizer_provider.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_conversation_to_turns.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_dashboard.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_dashboard_coverage.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_dashboard_latency.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_dashboard_lineage.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_dashboard_review_queue.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_db_merge_confidence_conflict.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_db_merge_coverage_v2.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_decay_coverage.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_decay_respects_pinned.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_dedup.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_dedup_cli.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_dedup_conflict_disambiguation.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_deterministic_predicates.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_dream_bridge_coverage_v2.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_dream_bridge_sensitivity.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_embeddings_coverage.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_entity_extractor.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_entity_extractor_llm.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_entity_graph.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_entity_graph_export.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_entity_new_kinds.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_entity_regex_v3.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_entity_registry.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_eval_harness.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_events_schema.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_extract_llm_ollama.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_federated_graphify_mcp.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_federated_query_safety.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_feedback.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_fts5_search.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_graph_distance.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_graph_store.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_handler_regressions.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_hook_env_isolation.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_human_id.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_incident_drill_runner.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_integration_workflows.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_key_rotator.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_lifecycle.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_lifecycle_supersede_invariant.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_llm_fallback.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_llm_provider_claude_cli.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_llm_provider_key_rotation.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_llm_steward_coverage.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_llm_steward_key_rotation.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_mcp_filter_bypass.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_mcp_helpers.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_mcp_rate_limit.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_mcp_server_validation.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_mcp_usage.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_media_processing.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_meta_decisions.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_metrics_exporter.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_observability.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_obsidian_mind_patterns.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_operator.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_operator_queue.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_perf_smoke_config.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_plugins.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_policy_coverage.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_policy_mode_env.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_postgres_parity.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_qdrant_backend.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_qmd_bridge.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_query_classifier.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_query_expansion.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_recall_entity_fanout.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_recall_fusion.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_recall_latency.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_recall_precision_at_5.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_recall_tokenizer.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_recall_vector_fallback.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_reliability_hardening.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_resolvers_concurrent_supersede.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_retrieval_profile.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_review.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_rl_trainer.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_rrf_auto_gate.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_scheduler.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_schema.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_scope_boost.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_scope_utils.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_security_access.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_security_patterns.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_sensitivity_filter_adversarial.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_sensitivity_filter_adversarial_v2.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_sensitivity_filter_t07.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_service_coverage.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_session_tracker.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_snapshot.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_snapshot_roundtrip.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_sqlite_core.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_staleness.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_stealth_mode.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_steward.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_steward_classifier.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_steward_features.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_steward_features_v3.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_steward_resolution_parity.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_storage_parity.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_store_factory.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_tenant_isolation.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_turn_schema.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_two_pass_recall.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_v311_fixes.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_v313_e2e.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_v313_run_cycle_dedupe.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_v390_e2e.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_v391_strict_warnings.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_vault_exporter.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_vault_linter_orphan.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_vector_search.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_verbatim_dedup.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_verbatim_recall.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_verbatim_store.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_verbatim_store_qdrant.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_webhook.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_whatsapp_importer.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_wiki_autopromote.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_wiki_binding.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_wiki_engine_idempotency.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_wiki_explored_and_contradictions.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_wiki_freshness.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_wiki_similarity_multiscope.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_wiki_suggest.py +0 -0
- {memorymaster-3.15.0 → memorymaster-3.16.0}/tests/test_wiki_validate_cli.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: memorymaster
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.16.0
|
|
4
4
|
Summary: Production-grade memory reliability system for AI coding agents. Lifecycle-managed claims with citations, conflict detection, steward governance, and MCP integration.
|
|
5
5
|
Author: wolverin0
|
|
6
6
|
License: MIT
|
|
@@ -98,6 +98,20 @@ recent PR status, and sensitivity-filter invariants.
|
|
|
98
98
|
|
|
99
99
|
Full feature index lives in [`docs/handbook.md`](docs/handbook.md).
|
|
100
100
|
|
|
101
|
+
## Benchmarks
|
|
102
|
+
|
|
103
|
+
**LongMemEval-S (N=500, retrieval-only)** — v3.15.0 now leads the publicly-reported numbers from [agentmemory](https://github.com/rohitg00/agentmemory) on R@5 and MRR, after wiring `sentence-transformers/all-MiniLM-L6-v2` into the bench harness (the v3.14 baseline was unintentionally BM25-only).
|
|
104
|
+
|
|
105
|
+

|
|
106
|
+
|
|
107
|
+
| Metric | v3.14.0 | **v3.15.0** | agentmemory | Δ vs agentmemory |
|
|
108
|
+
|---|---|---|---|---|
|
|
109
|
+
| Recall@5 | 0.894 | **0.966** | 0.952 | **+0.014** ★ |
|
|
110
|
+
| Recall@10 | 0.942 | **0.984** | 0.986 | -0.002 |
|
|
111
|
+
| MRR | 0.799 | **0.902** | 0.882 | **+0.020** ★ |
|
|
112
|
+
|
|
113
|
+
Reproduce: `python tests/bench_longmemeval.py --retrieval-only`. Full methodology, experiment-by-experiment deltas (1 KEEP, 2 REVERT, 3 NULL), and the architectural findings that surfaced along the way live in [`docs/longmemeval-results.md`](docs/longmemeval-results.md) and [`docs/v315-experiments/`](docs/v315-experiments/). QA-accuracy pass (with judge) is deferred until provider quotas allow.
|
|
114
|
+
|
|
101
115
|
## Prerequisites
|
|
102
116
|
|
|
103
117
|
**Required (the package won't function without these)**
|
|
@@ -52,6 +52,20 @@ recent PR status, and sensitivity-filter invariants.
|
|
|
52
52
|
|
|
53
53
|
Full feature index lives in [`docs/handbook.md`](docs/handbook.md).
|
|
54
54
|
|
|
55
|
+
## Benchmarks
|
|
56
|
+
|
|
57
|
+
**LongMemEval-S (N=500, retrieval-only)** — v3.15.0 now leads the publicly-reported numbers from [agentmemory](https://github.com/rohitg00/agentmemory) on R@5 and MRR, after wiring `sentence-transformers/all-MiniLM-L6-v2` into the bench harness (the v3.14 baseline was unintentionally BM25-only).
|
|
58
|
+
|
|
59
|
+

|
|
60
|
+
|
|
61
|
+
| Metric | v3.14.0 | **v3.15.0** | agentmemory | Δ vs agentmemory |
|
|
62
|
+
|---|---|---|---|---|
|
|
63
|
+
| Recall@5 | 0.894 | **0.966** | 0.952 | **+0.014** ★ |
|
|
64
|
+
| Recall@10 | 0.942 | **0.984** | 0.986 | -0.002 |
|
|
65
|
+
| MRR | 0.799 | **0.902** | 0.882 | **+0.020** ★ |
|
|
66
|
+
|
|
67
|
+
Reproduce: `python tests/bench_longmemeval.py --retrieval-only`. Full methodology, experiment-by-experiment deltas (1 KEEP, 2 REVERT, 3 NULL), and the architectural findings that surfaced along the way live in [`docs/longmemeval-results.md`](docs/longmemeval-results.md) and [`docs/v315-experiments/`](docs/v315-experiments/). QA-accuracy pass (with judge) is deferred until provider quotas allow.
|
|
68
|
+
|
|
55
69
|
## Prerequisites
|
|
56
70
|
|
|
57
71
|
**Required (the package won't function without these)**
|
|
@@ -8,7 +8,11 @@ Environment variables
|
|
|
8
8
|
---------------------
|
|
9
9
|
MEMORYMASTER_RETRIEVAL_WEIGHTS
|
|
10
10
|
Comma-separated floats for hybrid ranking: lexical,confidence,freshness,vector.
|
|
11
|
-
Default: ``0.
|
|
11
|
+
Default: ``0.30,0.20,0.10,0.40``
|
|
12
|
+
|
|
13
|
+
MEMORYMASTER_W_LEX, MEMORYMASTER_W_CONF, MEMORYMASTER_W_FRESH, MEMORYMASTER_W_VEC
|
|
14
|
+
Individual overrides for the four hybrid ranking weights. These take
|
|
15
|
+
precedence over ``MEMORYMASTER_RETRIEVAL_WEIGHTS`` when set.
|
|
12
16
|
|
|
13
17
|
MEMORYMASTER_RETRIEVAL_WEIGHTS_NO_VECTOR
|
|
14
18
|
Weights when vector search is disabled: lexical,confidence,freshness.
|
|
@@ -55,6 +59,14 @@ MEMORYMASTER_LLM_RERANK
|
|
|
55
59
|
Enable Gemini cross-encoder reranking over the top retrieval candidates.
|
|
56
60
|
Default: ``0``
|
|
57
61
|
|
|
62
|
+
MEMORYMASTER_RRF_TIEBREAKER
|
|
63
|
+
Enable RRF near-tie reordering after linear retrieval ranking.
|
|
64
|
+
Default: ``0``
|
|
65
|
+
|
|
66
|
+
MEMORYMASTER_RRF_TIEBREAKER_THRESHOLD
|
|
67
|
+
Maximum adjacent score gap considered a near tie.
|
|
68
|
+
Default: ``0.01``
|
|
69
|
+
|
|
58
70
|
MEMORYMASTER_CONFIG_FILE
|
|
59
71
|
Path to a JSON config file. Keys match attribute names on ``Config``.
|
|
60
72
|
"""
|
|
@@ -159,10 +171,10 @@ class Config:
|
|
|
159
171
|
"""Immutable configuration for tunable MemoryMaster constants."""
|
|
160
172
|
|
|
161
173
|
# --- Retrieval ranking weights (hybrid mode with vector) ---
|
|
162
|
-
retrieval_weight_lexical: float = 0.
|
|
163
|
-
retrieval_weight_confidence: float = 0.
|
|
164
|
-
retrieval_weight_freshness: float = 0.
|
|
165
|
-
retrieval_weight_vector: float = 0.
|
|
174
|
+
retrieval_weight_lexical: float = 0.30
|
|
175
|
+
retrieval_weight_confidence: float = 0.20
|
|
176
|
+
retrieval_weight_freshness: float = 0.10
|
|
177
|
+
retrieval_weight_vector: float = 0.40
|
|
166
178
|
|
|
167
179
|
# --- Retrieval ranking weights (hybrid mode without vector) ---
|
|
168
180
|
retrieval_weight_lexical_no_vector: float = 0.55
|
|
@@ -197,6 +209,8 @@ class Config:
|
|
|
197
209
|
pinned_bonus: float = 0.03
|
|
198
210
|
session_diversity_cap: int = 3
|
|
199
211
|
llm_rerank: bool = False
|
|
212
|
+
rrf_tiebreaker_enabled: bool = False
|
|
213
|
+
rrf_tiebreaker_threshold: float = 0.01
|
|
200
214
|
|
|
201
215
|
# --- Initial confidence priors calibrated from validator outcomes ---
|
|
202
216
|
default_initial_confidence: float = DEFAULT_INITIAL_CONFIDENCE
|
|
@@ -310,6 +324,10 @@ def load_config(config_path: str | Path | None = None) -> Config:
|
|
|
310
324
|
"retrieval_weight_freshness",
|
|
311
325
|
"retrieval_weight_vector",
|
|
312
326
|
])
|
|
327
|
+
_apply_env_float(overrides, "MEMORYMASTER_W_LEX", "retrieval_weight_lexical")
|
|
328
|
+
_apply_env_float(overrides, "MEMORYMASTER_W_CONF", "retrieval_weight_confidence")
|
|
329
|
+
_apply_env_float(overrides, "MEMORYMASTER_W_FRESH", "retrieval_weight_freshness")
|
|
330
|
+
_apply_env_float(overrides, "MEMORYMASTER_W_VEC", "retrieval_weight_vector")
|
|
313
331
|
_apply_env_floats(overrides, "MEMORYMASTER_RETRIEVAL_WEIGHTS_NO_VECTOR", 3, [
|
|
314
332
|
"retrieval_weight_lexical_no_vector",
|
|
315
333
|
"retrieval_weight_confidence_no_vector",
|
|
@@ -343,6 +361,8 @@ def load_config(config_path: str | Path | None = None) -> Config:
|
|
|
343
361
|
_apply_env_float(overrides, "MEMORYMASTER_PINNED_BONUS", "pinned_bonus")
|
|
344
362
|
_apply_env_int(overrides, "MEMORYMASTER_SESSION_DIVERSITY_CAP", "session_diversity_cap")
|
|
345
363
|
_apply_env_bool(overrides, "MEMORYMASTER_LLM_RERANK", "llm_rerank")
|
|
364
|
+
_apply_env_bool(overrides, "MEMORYMASTER_RRF_TIEBREAKER", "rrf_tiebreaker_enabled")
|
|
365
|
+
_apply_env_float(overrides, "MEMORYMASTER_RRF_TIEBREAKER_THRESHOLD", "rrf_tiebreaker_threshold")
|
|
346
366
|
|
|
347
367
|
# Filter to only valid Config fields
|
|
348
368
|
valid_fields = {f.name for f in Config.__dataclass_fields__.values()}
|
|
@@ -8,6 +8,7 @@ from typing import Callable, Mapping
|
|
|
8
8
|
|
|
9
9
|
from memorymaster.config import get_config
|
|
10
10
|
from memorymaster.models import Claim
|
|
11
|
+
from memorymaster.recall_fusion import RRF_K_DEFAULT, rrf_fuse
|
|
11
12
|
|
|
12
13
|
RETRIEVAL_MODES = ("legacy", "hybrid")
|
|
13
14
|
|
|
@@ -136,12 +137,12 @@ def rank_claims(
|
|
|
136
137
|
def _compute_claim_score(claim: Claim, lexical: float, confidence: float, freshness: float, vector: float, vector_enabled: bool, semantic_vectors: bool) -> float:
|
|
137
138
|
"""Compute relevance score for a claim."""
|
|
138
139
|
cfg = get_config()
|
|
140
|
+
w_l, w_c, w_f, w_v = cfg.retrieval_weights
|
|
139
141
|
if vector_enabled and semantic_vectors:
|
|
140
|
-
# Real semantic embeddings
|
|
141
|
-
|
|
142
|
+
# Real semantic embeddings use the same configurable blend as other
|
|
143
|
+
# vector-enabled ranking so env sweeps affect both paths.
|
|
144
|
+
score = (w_l * lexical) + (w_c * confidence) + (w_f * freshness) + (w_v * vector)
|
|
142
145
|
elif vector_enabled:
|
|
143
|
-
# Hash-based vectors: limited semantic value, keep lexical dominant
|
|
144
|
-
w_l, w_c, w_f, w_v = cfg.retrieval_weights
|
|
145
146
|
score = (w_l * lexical) + (w_c * confidence) + (w_f * freshness) + (w_v * vector)
|
|
146
147
|
else:
|
|
147
148
|
w_l, w_c, w_f = cfg.retrieval_weights_no_vector
|
|
@@ -180,6 +181,69 @@ def apply_session_diversity_cap(ranked: list[RankedClaim], cap: int) -> list[Ran
|
|
|
180
181
|
return result
|
|
181
182
|
|
|
182
183
|
|
|
184
|
+
def _component_rankings(rows: list[RankedClaim]) -> dict[str, list[int]]:
|
|
185
|
+
original_positions = {row.claim.id: index for index, row in enumerate(rows)}
|
|
186
|
+
|
|
187
|
+
def ranked_ids(score_attr: str) -> list[int]:
|
|
188
|
+
ordered = sorted(
|
|
189
|
+
rows,
|
|
190
|
+
key=lambda row: (
|
|
191
|
+
-float(getattr(row, score_attr)),
|
|
192
|
+
original_positions[row.claim.id],
|
|
193
|
+
),
|
|
194
|
+
)
|
|
195
|
+
return [row.claim.id for row in ordered]
|
|
196
|
+
|
|
197
|
+
return {
|
|
198
|
+
"lexical": ranked_ids("lexical_score"),
|
|
199
|
+
"vector": ranked_ids("vector_score"),
|
|
200
|
+
"confidence": ranked_ids("confidence_score"),
|
|
201
|
+
"freshness": ranked_ids("freshness_score"),
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def apply_rrf_tiebreaker(
|
|
206
|
+
ranked: list[RankedClaim],
|
|
207
|
+
*,
|
|
208
|
+
threshold: float = 0.01,
|
|
209
|
+
k: int = RRF_K_DEFAULT,
|
|
210
|
+
enabled: bool = True,
|
|
211
|
+
) -> list[RankedClaim]:
|
|
212
|
+
if not enabled or len(ranked) < 2:
|
|
213
|
+
return ranked
|
|
214
|
+
|
|
215
|
+
threshold = max(0.0, threshold)
|
|
216
|
+
threshold_epsilon = 1e-12
|
|
217
|
+
head_count = min(10, len(ranked))
|
|
218
|
+
result = list(ranked)
|
|
219
|
+
index = 0
|
|
220
|
+
|
|
221
|
+
while index < head_count:
|
|
222
|
+
group_end = index + 1
|
|
223
|
+
while (
|
|
224
|
+
group_end < head_count
|
|
225
|
+
and abs(ranked[group_end - 1].score - ranked[group_end].score)
|
|
226
|
+
<= threshold + threshold_epsilon
|
|
227
|
+
):
|
|
228
|
+
group_end += 1
|
|
229
|
+
|
|
230
|
+
if group_end - index > 1:
|
|
231
|
+
group = ranked[index:group_end]
|
|
232
|
+
original_positions = {row.claim.id: offset for offset, row in enumerate(group)}
|
|
233
|
+
rrf_scores = rrf_fuse(_component_rankings(group), k=k)
|
|
234
|
+
result[index:group_end] = sorted(
|
|
235
|
+
group,
|
|
236
|
+
key=lambda row: (
|
|
237
|
+
-rrf_scores.get(row.claim.id, 0.0),
|
|
238
|
+
original_positions[row.claim.id],
|
|
239
|
+
),
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
index = group_end
|
|
243
|
+
|
|
244
|
+
return result
|
|
245
|
+
|
|
246
|
+
|
|
183
247
|
def rank_claim_rows(
|
|
184
248
|
query_text: str,
|
|
185
249
|
claims: list[Claim],
|
|
@@ -262,5 +326,11 @@ def rank_claim_rows(
|
|
|
262
326
|
),
|
|
263
327
|
reverse=True,
|
|
264
328
|
)
|
|
329
|
+
cfg = get_config()
|
|
330
|
+
ranked = apply_rrf_tiebreaker(
|
|
331
|
+
ranked,
|
|
332
|
+
threshold=cfg.rrf_tiebreaker_threshold,
|
|
333
|
+
enabled=cfg.rrf_tiebreaker_enabled,
|
|
334
|
+
)
|
|
265
335
|
ranked = apply_session_diversity_cap(ranked, get_config().session_diversity_cap)
|
|
266
336
|
return ranked[:limit]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: memorymaster
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.16.0
|
|
4
4
|
Summary: Production-grade memory reliability system for AI coding agents. Lifecycle-managed claims with citations, conflict detection, steward governance, and MCP integration.
|
|
5
5
|
Author: wolverin0
|
|
6
6
|
License: MIT
|
|
@@ -98,6 +98,20 @@ recent PR status, and sensitivity-filter invariants.
|
|
|
98
98
|
|
|
99
99
|
Full feature index lives in [`docs/handbook.md`](docs/handbook.md).
|
|
100
100
|
|
|
101
|
+
## Benchmarks
|
|
102
|
+
|
|
103
|
+
**LongMemEval-S (N=500, retrieval-only)** — v3.15.0 now leads the publicly-reported numbers from [agentmemory](https://github.com/rohitg00/agentmemory) on R@5 and MRR, after wiring `sentence-transformers/all-MiniLM-L6-v2` into the bench harness (the v3.14 baseline was unintentionally BM25-only).
|
|
104
|
+
|
|
105
|
+

|
|
106
|
+
|
|
107
|
+
| Metric | v3.14.0 | **v3.15.0** | agentmemory | Δ vs agentmemory |
|
|
108
|
+
|---|---|---|---|---|
|
|
109
|
+
| Recall@5 | 0.894 | **0.966** | 0.952 | **+0.014** ★ |
|
|
110
|
+
| Recall@10 | 0.942 | **0.984** | 0.986 | -0.002 |
|
|
111
|
+
| MRR | 0.799 | **0.902** | 0.882 | **+0.020** ★ |
|
|
112
|
+
|
|
113
|
+
Reproduce: `python tests/bench_longmemeval.py --retrieval-only`. Full methodology, experiment-by-experiment deltas (1 KEEP, 2 REVERT, 3 NULL), and the architectural findings that surfaced along the way live in [`docs/longmemeval-results.md`](docs/longmemeval-results.md) and [`docs/v315-experiments/`](docs/v315-experiments/). QA-accuracy pass (with judge) is deferred until provider quotas allow.
|
|
114
|
+
|
|
101
115
|
## Prerequisites
|
|
102
116
|
|
|
103
117
|
**Required (the package won't function without these)**
|
|
@@ -306,6 +306,8 @@ tests/test_recall_vector_fallback.py
|
|
|
306
306
|
tests/test_reliability_hardening.py
|
|
307
307
|
tests/test_resolvers_concurrent_supersede.py
|
|
308
308
|
tests/test_retrieval_profile.py
|
|
309
|
+
tests/test_retrieval_rrf_tiebreaker.py
|
|
310
|
+
tests/test_retrieval_weights.py
|
|
309
311
|
tests/test_review.py
|
|
310
312
|
tests/test_rl_trainer.py
|
|
311
313
|
tests/test_rrf_auto_gate.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "memorymaster"
|
|
7
|
-
version = "3.
|
|
7
|
+
version = "3.16.0"
|
|
8
8
|
description = "Production-grade memory reliability system for AI coding agents. Lifecycle-managed claims with citations, conflict detection, steward governance, and MCP integration."
|
|
9
9
|
license = {text = "MIT"}
|
|
10
10
|
authors = [{name = "wolverin0"}]
|
|
@@ -22,7 +22,7 @@ def _reset():
|
|
|
22
22
|
class TestConfigDefaults:
|
|
23
23
|
def test_default_retrieval_weights(self):
|
|
24
24
|
cfg = Config()
|
|
25
|
-
assert cfg.retrieval_weights == (0.
|
|
25
|
+
assert cfg.retrieval_weights == (0.30, 0.20, 0.10, 0.40)
|
|
26
26
|
|
|
27
27
|
def test_default_no_vector_weights(self):
|
|
28
28
|
cfg = Config()
|
|
@@ -58,6 +58,12 @@ class TestConfigEnvOverrides:
|
|
|
58
58
|
cfg = load_config()
|
|
59
59
|
assert cfg.retrieval_weights == (0.40, 0.25, 0.20, 0.15)
|
|
60
60
|
|
|
61
|
+
def test_individual_retrieval_weight_env(self, monkeypatch):
|
|
62
|
+
monkeypatch.setenv("MEMORYMASTER_RETRIEVAL_WEIGHTS", "0.40,0.25,0.20,0.15")
|
|
63
|
+
monkeypatch.setenv("MEMORYMASTER_W_LEX", "0.55")
|
|
64
|
+
cfg = load_config()
|
|
65
|
+
assert cfg.retrieval_weights == (0.55, 0.25, 0.20, 0.15)
|
|
66
|
+
|
|
61
67
|
def test_retrieval_weights_no_vector_env(self, monkeypatch):
|
|
62
68
|
monkeypatch.setenv("MEMORYMASTER_RETRIEVAL_WEIGHTS_NO_VECTOR", "0.60,0.25,0.15")
|
|
63
69
|
cfg = load_config()
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from memorymaster.config import get_config, reset_config
|
|
4
|
+
from memorymaster.models import Claim
|
|
5
|
+
from memorymaster.retrieval import RankedClaim, apply_rrf_tiebreaker
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _claim(claim_id: int) -> Claim:
|
|
9
|
+
return Claim(
|
|
10
|
+
id=claim_id,
|
|
11
|
+
text=f"claim {claim_id}",
|
|
12
|
+
idempotency_key=None,
|
|
13
|
+
normalized_text=None,
|
|
14
|
+
claim_type=None,
|
|
15
|
+
subject=None,
|
|
16
|
+
predicate=None,
|
|
17
|
+
object_value=None,
|
|
18
|
+
scope="project",
|
|
19
|
+
volatility="medium",
|
|
20
|
+
status="confirmed",
|
|
21
|
+
confidence=0.8,
|
|
22
|
+
pinned=False,
|
|
23
|
+
supersedes_claim_id=None,
|
|
24
|
+
replaced_by_claim_id=None,
|
|
25
|
+
created_at="2026-03-01T00:00:00+00:00",
|
|
26
|
+
updated_at="2026-03-08T00:00:00+00:00",
|
|
27
|
+
last_validated_at=None,
|
|
28
|
+
archived_at=None,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _row(
|
|
33
|
+
claim_id: int,
|
|
34
|
+
*,
|
|
35
|
+
score: float,
|
|
36
|
+
lexical: float,
|
|
37
|
+
vector: float,
|
|
38
|
+
confidence: float,
|
|
39
|
+
freshness: float,
|
|
40
|
+
) -> RankedClaim:
|
|
41
|
+
return RankedClaim(
|
|
42
|
+
claim=_claim(claim_id),
|
|
43
|
+
score=score,
|
|
44
|
+
lexical_score=lexical,
|
|
45
|
+
vector_score=vector,
|
|
46
|
+
confidence_score=confidence,
|
|
47
|
+
freshness_score=freshness,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_clear_winner_pair_unchanged() -> None:
|
|
52
|
+
rows = [
|
|
53
|
+
_row(1, score=0.8, lexical=0.1, vector=0.1, confidence=0.1, freshness=0.1),
|
|
54
|
+
_row(2, score=0.5, lexical=1.0, vector=1.0, confidence=1.0, freshness=1.0),
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
result = apply_rrf_tiebreaker(rows, threshold=0.01, enabled=True)
|
|
58
|
+
|
|
59
|
+
assert [row.claim.id for row in result] == [1, 2]
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def test_near_tie_reordered_by_rrf() -> None:
|
|
63
|
+
rows = [
|
|
64
|
+
_row(1, score=0.81, lexical=1.0, vector=0.0, confidence=0.0, freshness=0.0),
|
|
65
|
+
_row(2, score=0.80, lexical=0.9, vector=1.0, confidence=1.0, freshness=1.0),
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
result = apply_rrf_tiebreaker(rows, threshold=0.01, enabled=True)
|
|
69
|
+
|
|
70
|
+
assert [row.claim.id for row in result] == [2, 1]
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def test_disabled_flag_no_op(monkeypatch) -> None:
|
|
74
|
+
monkeypatch.setenv("MEMORYMASTER_RRF_TIEBREAKER", "0")
|
|
75
|
+
reset_config()
|
|
76
|
+
rows = [
|
|
77
|
+
_row(1, score=0.81, lexical=1.0, vector=0.0, confidence=0.0, freshness=0.0),
|
|
78
|
+
_row(2, score=0.80, lexical=0.9, vector=1.0, confidence=1.0, freshness=1.0),
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
result = apply_rrf_tiebreaker(rows, threshold=0.01, enabled=get_config().rrf_tiebreaker_enabled)
|
|
82
|
+
|
|
83
|
+
assert [row.claim.id for row in result] == [1, 2]
|
|
84
|
+
reset_config()
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from memorymaster.config import reset_config
|
|
6
|
+
from memorymaster.models import Claim
|
|
7
|
+
from memorymaster.retrieval import rank_claim_rows
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.fixture(autouse=True)
|
|
11
|
+
def _reset_config():
|
|
12
|
+
reset_config()
|
|
13
|
+
yield
|
|
14
|
+
reset_config()
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _claim() -> Claim:
|
|
18
|
+
return Claim(
|
|
19
|
+
id=1,
|
|
20
|
+
text="alpha beta retrieval target",
|
|
21
|
+
idempotency_key=None,
|
|
22
|
+
normalized_text=None,
|
|
23
|
+
claim_type=None,
|
|
24
|
+
subject=None,
|
|
25
|
+
predicate=None,
|
|
26
|
+
object_value=None,
|
|
27
|
+
scope="project",
|
|
28
|
+
volatility="medium",
|
|
29
|
+
status="confirmed",
|
|
30
|
+
confidence=0.8,
|
|
31
|
+
pinned=False,
|
|
32
|
+
supersedes_claim_id=None,
|
|
33
|
+
replaced_by_claim_id=None,
|
|
34
|
+
created_at="2999-01-01T00:00:00+00:00",
|
|
35
|
+
updated_at="2999-01-01T00:00:00+00:00",
|
|
36
|
+
last_validated_at=None,
|
|
37
|
+
archived_at=None,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _row(*, semantic_vectors: bool):
|
|
42
|
+
def vector_hook(query, claims):
|
|
43
|
+
return {claim.id: 0.6 for claim in claims}
|
|
44
|
+
|
|
45
|
+
return rank_claim_rows(
|
|
46
|
+
"alpha beta",
|
|
47
|
+
[_claim()],
|
|
48
|
+
mode="hybrid",
|
|
49
|
+
limit=1,
|
|
50
|
+
vector_hook=vector_hook,
|
|
51
|
+
semantic_vectors=semantic_vectors,
|
|
52
|
+
)[0]
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_memorymaster_w_lex_affects_vector_enabled_ranking_paths(monkeypatch):
|
|
56
|
+
default_lexical = _row(semantic_vectors=False)
|
|
57
|
+
default_semantic = _row(semantic_vectors=True)
|
|
58
|
+
|
|
59
|
+
monkeypatch.setenv("MEMORYMASTER_W_LEX", "0.55")
|
|
60
|
+
reset_config()
|
|
61
|
+
|
|
62
|
+
override_lexical = _row(semantic_vectors=False)
|
|
63
|
+
override_semantic = _row(semantic_vectors=True)
|
|
64
|
+
expected_delta = (0.55 - 0.30) * default_lexical.lexical_score
|
|
65
|
+
|
|
66
|
+
assert override_lexical.score - default_lexical.score == pytest.approx(expected_delta)
|
|
67
|
+
assert override_semantic.score - default_semantic.score == pytest.approx(expected_delta)
|
|
68
|
+
assert override_lexical.score != default_lexical.score
|
|
69
|
+
assert override_semantic.score != default_semantic.score
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/config_templates/claude-md-append.md
RENAMED
|
File without changes
|
{memorymaster-3.15.0 → memorymaster-3.16.0}/memorymaster/config_templates/codex-agents-md-append.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|