symfonic.core.learning.entity_extractor¶
entity_extractor ¶
EntityExtractor protocol + EntityCandidate dataclass + shared utilities.
This module is import-light: no spaCy, no langchain, no I/O. Strategy
implementations live in their own files (entity_extractor_spacy.py /
entity_extractor_llm.py) so the regex default ships without optional
dependencies.
Design reference: .claude/docs/2026-05-23-entity-linker-design.md §4.5, §5, §13.6. Roadmap reference: .claude/docs/2026-05-16-7.1.x-7.2-roadmap.md §11.
EntityCandidate
dataclass
¶
EntityCandidate(
surface_form: str,
kind: EntityKind,
confidence: float,
start: int | None = None,
end: int | None = None,
)
A single extracted entity mention.
Attributes:
| Name | Type | Description |
|---|---|---|
surface_form |
str
|
Verbatim text as observed in the episodic. |
kind |
EntityKind
|
One of the five canonical entity kinds. |
confidence |
float
|
Extractor-reported probability in [0.0, 1.0]. |
start |
int | None
|
Optional character offset of the mention in the source text. |
end |
int | None
|
Optional character offset (exclusive) of the mention. |
EntityExtractor ¶
Bases: Protocol
Async pure-function protocol: text -> list[EntityCandidate].
Implementations MUST be side-effect free with respect to the framework state and SHOULD be deterministic so the consolidation phase honours its idempotency contract (design §9). The LLM extractor is the documented exception (design §9.3).
canonicalise_surface ¶
Decision 2 canonical-form helper.
Proper-noun buckets (person / place / event) collapse via
case-insensitive exact match: the canonical form is the surface
lowercased with internal whitespace normalised to single underscores
("Cafe Milano" -> "cafe_milano").
Common-noun buckets (object / other) use the same whitespace
normalisation plus lemma+lowercase when lemmatise=True (regex
strategy: rule-based; spaCy strategy: real lemmatiser). When
lemmatise=False the bucket falls back to lowercase-only.
Returns the empty string when surface is blank.
Source code in src/symfonic/core/learning/entity_extractor.py
strip_phase11_markers ¶
Remove [semantic:...] and [SOUL: ...] markers from text.
These markers are Phase 11's territory; the entity_links phase must not double-count them as entity surfaces (design §13.6).