Fix #2103: fix: Search_memories在默认dedup=mmr下调试用 info 日志打印完整 embedding 向量#2106
Fix #2103: fix: Search_memories在默认dedup=mmr下调试用 info 日志打印完整 embedding 向量#2106Memtensor-AI wants to merge 3 commits into
Conversation
SingleCubeView.search_memories was logging the full MOSSearchResult at
INFO on every call. Under the default APISearchRequest (dedup="mmr"),
each memory keeps its metadata.embedding vector, so the log line
contained megabytes of floats per search — an explosion of noise plus
a privacy/compliance risk. The paired `len(memories_result)` line was
also buggy: it counted top-level dict keys (~7 constant), not memories.
Introduce _summarize_search_result_for_log(result), a pure helper that
returns a bounded dict with per-bucket counts, an aggregate total, a
capped sample of {id, memory_type, relativity} entries per bucket, and
a has_embedding boolean flag — never the raw vector. Replace the two
offending logger.info lines with a single sanitized summary line using
%s deferred formatting.
Behaviour of the search API and its response payload is unchanged; this
is a logging-only fix.
Add regression tests under tests/multi_mem_cube/ covering the no-leak
contract, per-bucket counts, sample bounding, both dedup branches
(mmr/sim vs no), and malformed-input robustness. Tests import the
helper lazily to work around the existing circular import in
memos.api.handlers.__init__ (same workaround as
tests/test_add_stage_logging.py).
Fixes MemTensor#2103
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
🤖 Open Code ReviewTarget: PR #2106 🔍 OpenCodeReview found 2 issue(s) in this PR. 1.
|
🔧 Open Code Review requested Agent fixOpen Code Review found 2 issue(s). I have resumed the development Agent to fix them.
The Agent will push a new commit to this PR branch. OCR will recheck after the commit is pushed. |
…rtion Address two Open Code Review findings on PR MemTensor#2106: 1) src/memos/multi_mem_cube/single_cube.py — `_summarize_search_result_for_log` was doing `counts[bucket] += len(memories)` before the per-item `isinstance(mem, dict)` guard, so heterogeneous input (strings, None, etc.) silently inflated the reported bucket total and diverged from the docstring's "total memories per bucket" contract. Move the increment inside the loop, after validation, so only well-formed dict entries count. 2) tests/multi_mem_cube/test_search_log_sanitization.py — the parametrized `test_both_branches_produce_safe_output` case had zero leak assertions on the `embedding_value=[]` branch because the `for value in embedding_value` loop is a no-op. Add an explicit structural assertion that `'"embedding"'` never appears in the rendered summary so `dedup="no"` carries real leak-detection signal. Also update the malformed-input regression case (`test_non_dict_memory_items_do_not_raise`) to assert the new post-validation count semantics (1 valid dict, not 3 raw list entries). Related PR: MemTensor#2106 Refs MemTensor#2103 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
🤖 Open Code ReviewTarget: PR #2106 🔍 OpenCodeReview found 1 issue(s) in this PR. 1.
|
🔧 Open Code Review requested Agent fixOpen Code Review found 1 issue(s). I have resumed the development Agent to fix them.
The Agent will push a new commit to this PR branch. OCR will recheck after the commit is pushed. |
Address the OCR round-2 finding on tests/multi_mem_cube/test_search_log_sanitization.py L265:
The previous compensating check `assert '"embedding"' not in rendered` was
trivially always True — `_summarize_search_result_for_log` never emits an
`"embedding"` key at all (only the boolean `"has_embedding"`), so the
assertion couldn't fail even if a future change re-introduced the raw vector
under a different name (`"embed"`, `"vector"`, `"raw_embedding"`, …).
Replace it with two assertions that carry real signal:
* Parametrize `expected_has_embedding` alongside `embedding_value` and
assert `summary["has_embedding"] is expected_has_embedding`. The empty
branch now has a concrete non-trivial claim (must be False), and the
populated branch pins the True case.
* Pin the top-level keyset with `==` (not `>=`) so any surprise extra key
— the most likely shape of an accidental future leak — fails the test.
No production-code change; this is a pure test-strengthening fix.
Related PR: MemTensor#2106
Refs MemTensor#2103
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
🤖 Open Code ReviewTarget: PR #2106 🔍 OpenCodeReview found 2 issue(s) in this PR. 1.
|
|
Description
Fixes #2103: SingleCubeView.search_memories no longer leaks full embedding vectors into INFO logs. Under the default APISearchRequest (dedup="mmr"), each memory previously carried its raw metadata.embedding into a
logger.info(f"Search memories result: {memories_result}")call, producing megabytes of floats per search plus a paired misleadinglen(memories_result)line that counted top-level dict keys instead of memories.The fix introduces
_summarize_search_result_for_login src/memos/multi_mem_cube/single_cube.py — a pure helper that produces a bounded dict: per-bucket counts (text_mem / pref_mem / tool_mem / skill_mem), an aggregate total, a capped 5-per-bucket sample exposing only {id, memory_type, relativity}, and ahas_embeddingboolean flag (never the raw vector). The two offending logger.info lines are replaced with a single sanitized summary line using %s deferred formatting (matches AGENTS.md logging style). Search API behaviour, response payload, and OpenAPI contract are unchanged; this is a logging-only fix.Verification:
PYTHONPATH=src pytest tests/multi_mem_cube/ -q→ 11 passed (all new regression cases covering no-embedding-leak, per-bucket counts, sample bounding, both dedup branches, and malformed-input robustness).ruff checkandruff format --checkboth clean on changed files.tests/api/test_search_pipeline_hooks.py→ 4 passed. Adjacenttests/test_add_stage_logging.pyfailures verified identical between clean tree and this branch → pre-existing and unrelated.Reviewers: @MatthewZhuang, @CarltonXiang, @syzsunshine219, @World-controller.
Related Issue (Required): Fixes #2103
Type of change
Please delete options that are not relevant.
How Has This Been Tested?
Not run; documentation-only change.
Checklist
@MatthewZhuang, @CarltonXiang, @syzsunshine219, @World-controller please review this PR.
Reviewer Checklist