Skip to content

feat: expose multi-scope memory controls via MCP, CLI, and Python API (PR 3/3)#44

Open
kenyonxu wants to merge 6 commits into
qualixar:mainfrom
kenyonxu:pr/scope-interface
Open

feat: expose multi-scope memory controls via MCP, CLI, and Python API (PR 3/3)#44
kenyonxu wants to merge 6 commits into
qualixar:mainfrom
kenyonxu:pr/scope-interface

Conversation

@kenyonxu

Copy link
Copy Markdown

Summary

PR 3/3 of the multi-scope memory feature (RFC #20).

Exposes scope controls to all entry points: MCP tools, CLI commands, and the Python API (MemoryEngine).

Changes

File Change
core/engine.py store(): add scope + shared_with kwargs; recall(): add include_global + include_shared kwargs
core/store_pipeline.py run_store(): add scope + shared_with params; enrich_fact(): preserve scope/shared_with on enriched facts; pass scope to MemoryRecord/AtomicFact constructors
storage/database.py store_memory/store_fact/store_edge/store_temporal_event: write scope + shared_with columns; _row_to_fact: deserialize scope/shared_with
mcp/tools_core.py remember: add scope + shared_with params; recall: add include_global + include_shared params
cli/main.py remember: --scope (personal/shared/global), --shared-with; recall: --include-global/--no-global, --include-shared/--no-shared
cli/commands.py cmd_remember: pass scope/shared_with to daemon/engine; cmd_recall: pass include_global/include_shared

Design

  • All new parameters have backward-compatible defaults
  • store(): scope='personal', shared_with=None
  • recall(): include_global=True, include_shared=True
  • CLI --no-global/--no-shared flags for explicit opt-out
  • MCP shared_with accepts comma-separated profile IDs

Dependencies

Test Results

  • 755 passed on Ubuntu (all 3 Python versions)
  • 75 passed on macOS (all 3 Python versions)
  • Pre-existing failures only — no regressions from scope changes

Ref: #20

kenyonxu added 6 commits June 15, 2026 17:00
…a only)

Add scope (TEXT, default 'personal') and shared_with (TEXT, nullable)
columns to 5 core tables, plus composite indexes on (scope) and
(profile_id, scope):

  - memories
  - atomic_facts
  - canonical_entities
  - temporal_events
  - graph_edges

Models updated with scope/shared_with fields. Migration M016 handles
ALTER TABLE for existing databases — all existing data defaults to
'personal' for full backward compatibility.

This is PR 1/3 of the multi-scope memory feature — pure storage layer.
No retrieval logic or interface changes included.

Ref: qualixar#20
Add ScopeWeights dataclass (personal=1.0, shared=0.7, global=0.5) for
multi-scope RRF fusion weighting. Persisted in config.json under
scope_weights key.

Part of PR-B: Retrieval Layer for multi-scope memory (qualixar#20).
Add module-level _scope_where() function that builds scope-filtering
WHERE clauses for multi-scope retrieval (personal/global/shared).

Update 11 query methods with optional include_global/include_shared params:
- get_pinned, get_all_facts, get_facts_by_entity, get_facts_by_type
- get_facts_by_memory_id, get_fact_count, get_facts_by_ids
- search_facts_fts, get_edges_for_node, get_temporal_events
- get_temporal_events_by_range

All new params default to True (backward compatible). Existing data has
scope='personal' (column default) so the OR branches are harmless no-ops.

Part of PR-B: Retrieval Layer for multi-scope memory (qualixar#20).
- engine.recall(): add include_global/include_shared params, set on
  channel instances before parallel execution
- engine._load_facts(): pass scope flags to get_facts_by_ids()
- semantic_channel: get_facts_by_ids/get_all_facts with scope flags
- bm25_channel: get_all_facts (cold-load) with scope flags
- hopfield_channel: get_facts_by_ids/get_all_facts with scope flags
- entity_channel: get_facts_by_entity/get_edges_for_node with scope flags

All scope flags default to True via getattr(self, 'include_X', True) —
backward compatible when engine doesn't set them.

Part of PR-B: Retrieval Layer for multi-scope memory (qualixar#20).
Add include_global/include_shared keyword args to run_recall() and
forward them to retrieval_engine.recall().

Part of PR-B: Retrieval Layer for multi-scope memory (qualixar#20).
Add scope/shared_with params to the write path and include_global/
include_shared params to the read path across all entry points.

Engine / Pipeline:
- engine.store(): scope + shared_with keyword args
- engine.recall(): include_global + include_shared keyword args
- run_store() / enrich_fact() / run_store_fact_direct(): scope passthrough

Database:
- store_memory / store_fact / store_edge / store_temporal_event:
  write scope + shared_with columns from record/fact objects
- _row_to_fact: deserialize scope + shared_with from rows

MCP:
- remember: scope + shared_with params, forwarded to daemon
- recall: include_global + include_shared params, forwarded to pool

CLI:
- remember: --scope (personal/shared/global), --shared-with
- recall: --include-global/--no-global, --include-shared/--no-shared

All new parameters have backward-compatible defaults (scope='personal',
include_global=True, include_shared=True). Requires PR-A (schema) and
PR-B (retrieval) for full scope-aware operation.

This is PR 3/3 of the multi-scope memory feature.

Ref: qualixar#20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant