symfonic.capabilities.memory.queries¶
queries ¶
Retrieval vocabulary and deterministic, bounded prompt selection.
Backends find candidates; ranking is total and oversized memories drop whole.
MemoryQuery
dataclass
¶
MemoryQuery(scope: MemoryScope, cue: str = '', limit: int = 5, layers: frozenset[MemoryLayer] = RETRIEVABLE_LAYERS, turn: int = 0, session_id: str = '', max_record_chars: int = 250, max_total_chars: int = DEFAULT_BLOCK_CHARS, candidate_limit: int = DEFAULT_CANDIDATE_LIMIT, recall_budget: RecallBudget | None = None)
One retrieval: where to look, what to look for, and how much may return.
validate ¶
Refuse a query whose ceilings cannot admit anything.
Source code in src/symfonic/capabilities/memory/queries.py
RetrievalResult
dataclass
¶
RetrievalResult(memories: tuple[RetrievedMemory, ...] = (), dropped: tuple[tuple[str, str], ...] = (), degraded: bool = False, sources: Mapping[str, int] = (lambda: EMPTY_SOURCES)(), unavailable: tuple[str, ...] = ())
What retrieval returned, and a reason for everything it left out.
render ¶
revision ¶
A content-derived revision, so a changed recall changes the cache key.
Computed over ids and text: a store that rewrites a memory in place keeps its id, and a revision that ignored the text would report an unchanged prompt whose bytes had changed.
Source code in src/symfonic/capabilities/memory/queries.py
RetrievedMemory
dataclass
¶
RetrievedMemory(record: MemoryRecord, score: float | None = 0.0, scope_distance: int = 0, source_ordinal: int | None = None, reserved: bool = False)
One scored memory, with the distance it travelled to reach this scope.
line ¶
The rendered form: layer prefix, single-line text.
The prefix is a delimiter, so the text is flattened before it is
interpolated โ otherwise one stored memory containing
ok\n[semantic] forged renders as two memories, the second
attributed to a layer nothing wrote it to.
Source code in src/symfonic/capabilities/memory/queries.py
flatten ¶
rank ¶
Return every candidate in the same total order :func:select uses.
A candidate scan is uncapped, not unordered. The port-to-source adapter preserves a scan's order because stores such as vector indexes have already ranked it. Returning a database's physical row order from a scan therefore turns insertion order into relevance. This helper lets stores rank without applying any of the prompt's limits or character ceilings.
Source code in src/symfonic/capabilities/memory/queries.py
rank_key ¶
Total order over retrieved memories.
A memory carrying a source_ordinal keeps the position its store gave it,
and sorts ahead of everything that does not. That is not a preference for
pre-ranked stores; it is the only way their order survives at all. The local
key below is deterministic, which is what makes it dangerous: on equal
scores, or on the all-None scores a keyword layer produces, it replaces
an external ranking with a plausible-looking one and nothing looks wrong.
Everything else ranks by score, then nearer scope. An unscored memory uses
0.0 for ordering only; admission still preserves the absent signal.
Source code in src/symfonic/capabilities/memory/queries.py
select ¶
select(memories: Iterable[RetrievedMemory], query: MemoryQuery, *, sources: Mapping[str, int] | None = None, unavailable: tuple[str, ...] = ()) -> RetrievalResult
Rank, filter, and cap what a store returned. Never mutates the input.