def select(backend, scope, request):
"""Scan existing references, retaining at most limit+one profile references."""
from symfonic.memory.backends.in_memory_ownership import native_owner
def rows():
for node in backend._nodes.get(scope.tenant_id, {}).values():
path = stored_scope_path(node.properties, node.tenant_id, scope=scope)
if not _is_native_scope(scope) and native_owner(path):
continue
visible = (
path in request.allowed_scope_paths
if request.allowed_scope_paths is not None
else backend._node_visible(scope, node)
)
if _is_native_scope(scope):
visible = visible and backend._node_visible(scope, node)
if not visible or not eligible(node, request):
continue
if request.exact_scope and path != materialise_scope_path(scope):
continue
yield node
tokens = set(request.cue.lower().split())
def key(node):
text = (node.label + " " + str(node.properties.get("content", ""))).lower()
overlap = len(tokens & set(text.split())) / len(tokens) if tokens else 1.0
salience = round((min(max(float(node.importance), 1), 10) - 1) / 9, 12)
prefixes = scope.ancestor_prefix_paths()
stored = stored_scope_path(node.properties, node.tenant_id, scope=scope)
distance = (
len(prefixes) - 1 - prefixes.index(stored)
if stored in prefixes else 1
)
score = salience * (0.25 + 0.75 * overlap) * (0.5 ** distance)
return (-score, distance, str(node.id))
reserved = nsmallest(request.profile_slots, (node for node in rows() if profile(node)), key=key)
ids = {str(node.id) for node in reserved}
count = 0
def ordinary():
nonlocal count
for node in rows():
count += 1
if str(node.id) not in ids:
yield node
ranked = nsmallest(request.limit, ordinary(), key=key)
selected = reserved + ranked[:request.limit - len(reserved)]
return CandidatePage(
tuple(node.model_copy(deep=True) for node in selected), count <= request.limit,
)