symfonic.capabilities.memory.extraction¶
extraction ¶
Deliverable 1: turning one finished turn into candidate memories.
The service does four things the shipped extractor spreads across three modules and one orchestrator method, and it reports on all four:
- Ask. It builds the extraction prompt — the same wire format the shipped extractor uses, so a deployment that swaps implementations mid-migration gets the same answers out of the same model.
- Read. The reply is read per provider family (:mod:
.families) instead of stringified, so an Anthropic block list or an OpenAI envelope is parsed rather than mined. - Scrub. Credentials are removed before a record exists (:mod:
.scrubbing), in both directions: out of the turn before the model sees it, and out of the extracted memory before the write port does. - Refuse, out loud. Every omission carries a reason (:mod:
.operations).
The service holds no provider SDK. It takes an :class:ExtractionModelPort —
one method, complete(prompt) -> reply — which a composition root binds.
Unbound, the service is inert: no model is a configuration, not an error,
which is the same property that makes a memoryless agent an ordinary deployment
rather than a fork.
Failure never reaches the turn. A model that raises produces a degraded
result. Two things are not caught: this capability's own contract errors, which
mean the call was impossible rather than the model, and CancelledError,
which is re-raised unswallowed (CXL-2) — a cancelled invocation is not a turn
that failed to remember.
MemoryExtractionService ¶
MemoryExtractionService(model: ExtractionModelPort | None = None, *, scrubber: CredentialScrubber | None = None)
Extracts candidate memories from a finished turn.
Source code in src/symfonic/capabilities/memory/extraction.py
extract
async
¶
Ask the model, read the reply, and mint what survives the policy.
Source code in src/symfonic/capabilities/memory/extraction.py
parse ¶
parse(reply: ProviderReply, request: ExtractionRequest, *, redactions: tuple[str, ...] = ()) -> ExtractionResult
Turn a read reply into records. Pure, so a corpus can replay it.
Source code in src/symfonic/capabilities/memory/extraction.py
parse_inline ¶
parse_inline(operations: tuple[Mapping[str, Any], ...], request: ExtractionRequest) -> ExtractionResult
Mint operations emitted by the response model's directive.
The response adapter has already recognised and stripped the envelope, so this method receives only JSON objects. It deliberately shares the same minting path as a dedicated extraction model: inline operations get the same validation, credential scrubbing, write receipt and lifecycle publication rather than becoming an unreviewed side path.
Source code in src/symfonic/capabilities/memory/extraction.py
prompt ¶
The extraction prompt for request, with credentials removed.
Scrubbing here is not belt-and-braces for the store: a secret handed to a provider is disclosed whether or not anyone ever writes it down.