diff --git a/src/contextweaver/_utils.py b/src/contextweaver/_utils.py index fdd1ff7..fedcfaa 100644 --- a/src/contextweaver/_utils.py +++ b/src/contextweaver/_utils.py @@ -200,8 +200,6 @@ def jaccard(a: set[str], b: set[str]) -> float: if not a and not b: return 0.0 union = a | b - if not union: - return 0.0 return len(a & b) / len(union) diff --git a/src/contextweaver/config.py b/src/contextweaver/config.py index 372dd41..91c91b6 100644 --- a/src/contextweaver/config.py +++ b/src/contextweaver/config.py @@ -7,7 +7,7 @@ from __future__ import annotations from dataclasses import dataclass, field -from typing import Any +from typing import Any, Literal from contextweaver.types import ItemKind, Phase, Sensitivity @@ -114,7 +114,7 @@ class ContextPolicy: max_items_per_kind: dict[ItemKind, int] = field( default_factory=lambda: {k: 50 for k in ItemKind} ) - ttl_behavior: str = "drop" + ttl_behavior: Literal["drop", "warn"] = "drop" sensitivity_floor: Sensitivity = Sensitivity.confidential redaction_hooks: list[str] = field(default_factory=list) extra: dict[str, Any] = field(default_factory=dict) diff --git a/src/contextweaver/context/manager.py b/src/contextweaver/context/manager.py index 2b3c934..46f4aa2 100644 --- a/src/contextweaver/context/manager.py +++ b/src/contextweaver/context/manager.py @@ -89,6 +89,7 @@ def __init__( self._scoring = scoring_config or ScoringConfig() self._estimator: TokenEstimator = estimator or CharDivFourEstimator() self._hook: EventHook = hook or NoOpHook() + self._fact_counter: int = 0 # ------------------------------------------------------------------ # Properties @@ -290,7 +291,8 @@ def add_fact(self, key: str, value: str, metadata: dict[str, Any] | None = None) value: Fact value. metadata: Optional metadata dict. """ - fact_id = f"fact:{key}:{len(self._fact_store.all())}" + self._fact_counter += 1 + fact_id = f"fact:{key}:{self._fact_counter}" self._fact_store.put( Fact( fact_id=fact_id, diff --git a/src/contextweaver/protocols.py b/src/contextweaver/protocols.py index e229cf4..978bec0 100644 --- a/src/contextweaver/protocols.py +++ b/src/contextweaver/protocols.py @@ -121,10 +121,6 @@ def exists(self, handle: str) -> bool: """Return ``True`` if *handle* is in the store.""" ... - def metadata(self, handle: str) -> ArtifactRef: - """Return the :class:`~contextweaver.types.ArtifactRef` for *handle*.""" - ... - def drilldown(self, handle: str, selector: dict[str, Any]) -> str: """Return a subset of the artifact's content according to *selector*.""" ... diff --git a/src/contextweaver/routing/router.py b/src/contextweaver/routing/router.py index ff321bc..ca9377b 100644 --- a/src/contextweaver/routing/router.py +++ b/src/contextweaver/routing/router.py @@ -88,6 +88,7 @@ def __init__( self._items: dict[str, SelectableItem] = {} self._scorer = scorer self._indexed = False + self._doc_id_to_idx: dict[str, int] = {} if items is not None: self.set_items(items) @@ -124,7 +125,7 @@ def _ensure_index(self) -> None: doc_ids.append(node_id) self._scorer.fit(docs) - self._doc_id_to_idx: dict[str, int] = {did: i for i, did in enumerate(doc_ids)} + self._doc_id_to_idx = {did: i for i, did in enumerate(doc_ids)} self._indexed = True def _score_node(self, query: str, node_id: str) -> float: