Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ JIT_ENRICHMENT_ENABLED=true # Run entity/summary extraction in
# Search scoring weights (all floats, see docs/ENVIRONMENT_VARIABLES.md)
SEARCH_WEIGHT_VECTOR=0.35 # Semantic similarity via Qdrant
SEARCH_WEIGHT_KEYWORD=0.35 # Keyword/TF-IDF matching
SEARCH_WEIGHT_METADATA=0.35 # Metadata sidecar match score
SEARCH_WEIGHT_RELATION=0.25 # Graph relationship boost
SEARCH_WEIGHT_TAG=0.20 # Tag overlap scoring
SEARCH_WEIGHT_EXACT=0.20 # Exact phrase in metadata
Expand Down
1 change: 1 addition & 0 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ def _parse_viewer_allowed_origins() -> Any:
from automem.search.runtime_keywords import load_keyword_runtime
from automem.search.runtime_recall_helpers import (
_graph_keyword_search,
_metadata_keyword_search,
_result_passes_filters,
_vector_filter_only_tag_search,
_vector_search,
Expand Down
25 changes: 25 additions & 0 deletions automem/api/recall.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
FILTERABLE_RELATIONS,
RECALL_ADAPTIVE_FLOOR,
RECALL_EXPANSION_LIMIT,
RECALL_METADATA_SEARCH_ENABLED,
RECALL_MIN_SCORE,
RECALL_RELATION_LIMIT,
canonicalize_relation_type,
Expand Down Expand Up @@ -1417,6 +1418,7 @@ def handle_recall(
expansion_limit_default: Optional[int] = None,
on_access: Optional[Callable[[List[str]], None]] = None,
jit_enrich_fn: Optional[Callable[[str, Dict[str, Any]], Optional[Dict[str, Any]]]] = None,
metadata_keyword_search: Optional[Callable[..., List[Dict[str, Any]]]] = None,
):
query_start = time.perf_counter()
query_text = (request.args.get("query") or "").strip()
Expand Down Expand Up @@ -1666,6 +1668,27 @@ def _run_single_query(
)
local_results.extend(graph_matches[:remaining_slots])

if (
graph is not None
and metadata_keyword_search is not None
and query_str
and RECALL_METADATA_SEARCH_ENABLED
):
metadata_slots = max(1, min(per_query_limit, 10))
metadata_matches = metadata_keyword_search(
graph,
query_str,
metadata_slots,
local_seen,
start_time=start_time,
end_time=end_time,
tag_filters=tag_filters,
tag_mode=tag_mode,
tag_match=tag_match,
exclude_tags=exclude_tags,
)
local_results.extend(metadata_matches)

tags_only_request = (
not query_str
and not (embedding_param and embedding_param.strip())
Expand Down Expand Up @@ -2139,6 +2162,7 @@ def create_recall_blueprint(
summarize_relation_node: Callable[[Dict[str, Any]], Dict[str, Any]] | None = None,
on_access: Optional[Callable[[List[str]], None]] = None,
jit_enrich_fn: Optional[Callable[[str, Dict[str, Any]], Optional[Dict[str, Any]]]] = None,
metadata_keyword_search: Optional[Callable[..., List[Dict[str, Any]]]] = None,
) -> Blueprint:
bp = Blueprint("recall", __name__)

Expand Down Expand Up @@ -2170,6 +2194,7 @@ def recall_memories() -> Any:
expansion_limit_default=RECALL_EXPANSION_LIMIT,
on_access=on_access,
jit_enrich_fn=jit_enrich_fn,
metadata_keyword_search=metadata_keyword_search,
)

@bp.route("/startup-recall", methods=["GET"])
Expand Down
2 changes: 2 additions & 0 deletions automem/api/runtime_bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def register_blueprints(
consolidation_tick_seconds: int,
consolidation_history_limit: int,
require_api_token_fn: Callable[[], None],
metadata_keyword_search_fn: Optional[Callable[..., list[dict[str, Any]]]] = None,
) -> None:
health_bp = create_health_blueprint(
get_memory_graph_fn,
Expand Down Expand Up @@ -106,6 +107,7 @@ def register_blueprints(
summarize_relation_node_fn,
update_last_accessed_fn,
jit_enrich_fn=jit_enrich_fn,
metadata_keyword_search=metadata_keyword_search_fn,
)

memory_bp = create_memory_blueprint_full(
Expand Down
2 changes: 2 additions & 0 deletions automem/api/runtime_recall_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def recall_memories(
emit_event_fn: Any,
utc_now_fn: Any,
abort_fn: Any, # noqa: ARG001 - kept for DI compatibility
metadata_keyword_search_fn: Any = None,
) -> Any:
query_start = perf_counter_fn()
query_text = (request_obj.args.get("query") or "").strip()
Expand Down Expand Up @@ -66,6 +67,7 @@ def recall_memories(
default_expand_relations=default_expand_relations,
relation_limit=recall_relation_limit,
expansion_limit_default=recall_expansion_limit,
metadata_keyword_search=metadata_keyword_search_fn,
)

elapsed_ms = int((perf_counter_fn() - query_start) * 1000)
Expand Down
8 changes: 8 additions & 0 deletions automem/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@
RECALL_EXPANSION_LIMIT = int(os.getenv("RECALL_EXPANSION_LIMIT", "25"))
RECALL_MIN_SCORE = float(os.getenv("RECALL_MIN_SCORE", "0.0"))
RECALL_ADAPTIVE_FLOOR = os.getenv("RECALL_ADAPTIVE_FLOOR", "true").lower() in ("true", "1", "yes")
RECALL_METADATA_SEARCH_ENABLED = os.getenv(
"RECALL_METADATA_SEARCH_ENABLED", "true"
).lower() not in {
"0",
"false",
"no",
}

# Memory content size limits (governs auto-summarization on store)
# Soft limit: Content above this triggers auto-summarization
Expand Down Expand Up @@ -447,6 +454,7 @@ def expand_relation_query_types(relation_types: Iterable[str]) -> list[str]:
# Search weighting parameters (can be overridden via environment variables)
SEARCH_WEIGHT_VECTOR = float(os.getenv("SEARCH_WEIGHT_VECTOR", "0.35"))
SEARCH_WEIGHT_KEYWORD = float(os.getenv("SEARCH_WEIGHT_KEYWORD", "0.35"))
SEARCH_WEIGHT_METADATA = float(os.getenv("SEARCH_WEIGHT_METADATA", "0.35"))
SEARCH_WEIGHT_TAG = float(os.getenv("SEARCH_WEIGHT_TAG", "0.2"))
Comment thread
jack-arturo marked this conversation as resolved.
SEARCH_WEIGHT_IMPORTANCE = float(os.getenv("SEARCH_WEIGHT_IMPORTANCE", "0.1"))
SEARCH_WEIGHT_CONFIDENCE = float(os.getenv("SEARCH_WEIGHT_CONFIDENCE", "0.05"))
Expand Down
1 change: 1 addition & 0 deletions automem/runtime_wiring.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def wire_recall_and_blueprints(
consolidation_tick_seconds=module.CONSOLIDATION_TICK_SECONDS,
consolidation_history_limit=module.CONSOLIDATION_HISTORY_LIMIT,
require_api_token_fn=module.require_api_token,
metadata_keyword_search_fn=module._metadata_keyword_search,
)


Expand Down
Loading
Loading