Loading
Loading
Hits with verdicts. Each carries the deposit, a score, and four dispersion-aware flags.
@dataclass(frozen=True, slots=True)
class SearchResult:
deposit: Deposit
score: float
is_confident: bool
has_disagreement: bool
agreement_score: float # [0, 1] — public alias for bag_precision
is_thin_evidence: bool
conflict_peers: tuple[str, ...] = ()
# Hot-path property aliases (no __getattr__ magic):
@property
def id(self) -> str: ...
@property
def content(self) -> str: ...
@property
def polarity(self) -> Polarity: ...
@property
def evidence_grade(self) -> EvidenceGrade: ...
@property
def scope(self) -> Scope: ...
@property
def tags(self) -> tuple[str, ...]: ...
def explain(self) -> str: ...@dataclass(frozen=True, slots=True)
class SearchResults:
items: tuple[SearchResult, ...]
has_disagreement: bool # bag-level: any returned bag flagged
is_confident: bool # bag-level: at least one confident bag, no disagreement anywhere
def __iter__(self) -> Iterator[SearchResult]: ...
def __len__(self) -> int: ...
def __getitem__(self, idx) -> SearchResult: ...
def __bool__(self) -> bool: ...
def explain(self) -> str: ...Iterable, length-able, indexable, truthy if non-empty. Not a list subclass.
has_disagreement is computed over every bag the engine returns, not just the sliced top-limit. A conflict can't hide from your agent because of pagination.
results = user.recall("threshold")
# Bag-level verdict
print(results.explain())
# "5 hits across 2 bags · 1 bag in conflict · not confident"
# Per-hit
for r in results:
marker = "⚠" if r.has_disagreement else "✓" if r.is_confident else "·"
print(marker, r.content, f"agreement={r.agreement_score:.2f}")result.to_dict() uses kind: "search_result" and flattens the most common Deposit fields to the top level so consumers can pull r["content"] without nesting through r["deposit"]["content"].
Was this page helpful?