hindsight-api 0.1.16__py3-none-any.whl → 0.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,16 +13,23 @@ logger = logging.getLogger(__name__)
13
13
 
14
14
 
15
15
  async def process_entities_batch(
16
- entity_resolver, conn, bank_id: str, unit_ids: list[str], facts: list[ProcessedFact], log_buffer: list[str] = None
16
+ entity_resolver,
17
+ conn,
18
+ bank_id: str,
19
+ unit_ids: list[str],
20
+ facts: list[ProcessedFact],
21
+ log_buffer: list[str] = None,
22
+ user_entities_per_content: dict[int, list[dict]] = None,
17
23
  ) -> list[EntityLink]:
18
24
  """
19
25
  Process entities for all facts and create entity links.
20
26
 
21
27
  This function:
22
28
  1. Extracts entity mentions from fact texts
23
- 2. Resolves entity names to canonical entities
24
- 3. Creates entity records in the database
25
- 4. Returns entity links ready for insertion
29
+ 2. Merges user-provided entities with LLM-extracted entities
30
+ 3. Resolves entity names to canonical entities
31
+ 4. Creates entity records in the database
32
+ 5. Returns entity links ready for insertion
26
33
 
27
34
  Args:
28
35
  entity_resolver: EntityResolver instance for entity resolution
@@ -31,6 +38,7 @@ async def process_entities_batch(
31
38
  unit_ids: List of unit IDs (same length as facts)
32
39
  facts: List of ProcessedFact objects
33
40
  log_buffer: Optional buffer for detailed logging
41
+ user_entities_per_content: Dict mapping content_index to list of user-provided entities
34
42
 
35
43
  Returns:
36
44
  List of EntityLink objects for batch insertion
@@ -41,14 +49,35 @@ async def process_entities_batch(
41
49
  if len(unit_ids) != len(facts):
42
50
  raise ValueError(f"Mismatch between unit_ids ({len(unit_ids)}) and facts ({len(facts)})")
43
51
 
52
+ user_entities_per_content = user_entities_per_content or {}
53
+
44
54
  # Extract data for link_utils function
45
55
  fact_texts = [fact.fact_text for fact in facts]
46
56
  # Use occurred_start if available, otherwise use mentioned_at for entity timestamps
47
57
  fact_dates = [fact.occurred_start if fact.occurred_start is not None else fact.mentioned_at for fact in facts]
48
- # Convert EntityRef objects to dict format expected by link_utils
49
- entities_per_fact = [
50
- [{"text": entity.name, "type": "CONCEPT"} for entity in (fact.entities or [])] for fact in facts
51
- ]
58
+
59
+ # Convert EntityRef objects to dict format and merge with user-provided entities
60
+ entities_per_fact = []
61
+ for fact in facts:
62
+ # Start with LLM-extracted entities
63
+ llm_entities = [{"text": entity.name, "type": "CONCEPT"} for entity in (fact.entities or [])]
64
+
65
+ # Get user entities for this content (use content_index from fact)
66
+ user_entities = user_entities_per_content.get(fact.content_index, [])
67
+
68
+ # Merge with case-insensitive deduplication
69
+ seen_texts = {e["text"].lower() for e in llm_entities}
70
+ for user_entity in user_entities:
71
+ if user_entity["text"].lower() not in seen_texts:
72
+ llm_entities.append(
73
+ {
74
+ "text": user_entity["text"],
75
+ "type": user_entity.get("type", "CONCEPT"),
76
+ }
77
+ )
78
+ seen_texts.add(user_entity["text"].lower())
79
+
80
+ entities_per_fact.append(llm_entities)
52
81
 
53
82
  # Use existing link_utils function for entity processing
54
83
  entity_links = await link_utils.extract_entities_batch_optimized(
@@ -17,6 +17,44 @@ from pydantic import BaseModel, ConfigDict, Field, field_validator
17
17
  from ..llm_wrapper import LLMConfig, OutputTooLongError
18
18
 
19
19
 
20
+ def _infer_temporal_date(fact_text: str, event_date: datetime) -> str | None:
21
+ """
22
+ Infer a temporal date from fact text when LLM didn't provide occurred_start.
23
+
24
+ This is a fallback for when the LLM fails to extract temporal information
25
+ from relative time expressions like "last night", "yesterday", etc.
26
+ """
27
+ import re
28
+
29
+ fact_lower = fact_text.lower()
30
+
31
+ # Map relative time expressions to day offsets
32
+ temporal_patterns = {
33
+ r"\blast night\b": -1,
34
+ r"\byesterday\b": -1,
35
+ r"\btoday\b": 0,
36
+ r"\bthis morning\b": 0,
37
+ r"\bthis afternoon\b": 0,
38
+ r"\bthis evening\b": 0,
39
+ r"\btonigh?t\b": 0,
40
+ r"\btomorrow\b": 1,
41
+ r"\blast week\b": -7,
42
+ r"\bthis week\b": 0,
43
+ r"\bnext week\b": 7,
44
+ r"\blast month\b": -30,
45
+ r"\bthis month\b": 0,
46
+ r"\bnext month\b": 30,
47
+ }
48
+
49
+ for pattern, offset_days in temporal_patterns.items():
50
+ if re.search(pattern, fact_lower):
51
+ target_date = event_date + timedelta(days=offset_days)
52
+ return target_date.replace(hour=0, minute=0, second=0, microsecond=0).isoformat()
53
+
54
+ # If no relative time expression found, return None
55
+ return None
56
+
57
+
20
58
  def _sanitize_text(text: str) -> str:
21
59
  """
22
60
  Sanitize text by removing invalid Unicode surrogate characters.
@@ -676,13 +714,18 @@ Text:
676
714
  if fact_kind == "event":
677
715
  occurred_start = get_value("occurred_start")
678
716
  occurred_end = get_value("occurred_end")
679
- if occurred_start:
717
+
718
+ # If LLM didn't set temporal fields, try to extract them from the fact text
719
+ if not occurred_start:
720
+ fact_data["occurred_start"] = _infer_temporal_date(combined_text, event_date)
721
+ else:
680
722
  fact_data["occurred_start"] = occurred_start
681
- # For point events: if occurred_end not set, default to occurred_start
682
- if occurred_end:
683
- fact_data["occurred_end"] = occurred_end
684
- else:
685
- fact_data["occurred_end"] = occurred_start
723
+
724
+ # For point events: if occurred_end not set, default to occurred_start
725
+ if occurred_end:
726
+ fact_data["occurred_end"] = occurred_end
727
+ elif fact_data.get("occurred_start"):
728
+ fact_data["occurred_end"] = fact_data["occurred_start"]
686
729
 
687
730
  # Add entities if present (validate as Entity objects)
688
731
  # LLM sometimes returns strings instead of {"text": "..."} format
@@ -9,6 +9,7 @@ import time
9
9
  import uuid
10
10
  from datetime import UTC, datetime
11
11
 
12
+ from ...config import get_config
12
13
  from ..memory_engine import fq_table
13
14
  from ..search import observation_utils
14
15
  from . import embedding_utils
@@ -49,8 +50,9 @@ async def regenerate_observations_batch(
49
50
  entity_links: Entity links from this batch
50
51
  log_buffer: Optional log buffer for timing
51
52
  """
52
- TOP_N_ENTITIES = 5
53
- MIN_FACTS_THRESHOLD = 5
53
+ config = get_config()
54
+ TOP_N_ENTITIES = config.observation_top_entities
55
+ MIN_FACTS_THRESHOLD = config.observation_min_facts
54
56
 
55
57
  if not entity_links:
56
58
  return
@@ -91,6 +91,7 @@ async def retain_batch(
91
91
  context=item.get("context", ""),
92
92
  event_date=item.get("event_date") or utcnow(),
93
93
  metadata=item.get("metadata", {}),
94
+ entities=item.get("entities", []),
94
95
  )
95
96
  contents.append(content)
96
97
 
@@ -352,8 +353,18 @@ async def retain_batch(
352
353
 
353
354
  # Process entities
354
355
  step_start = time.time()
356
+ # Build map of content_index -> user entities for merging
357
+ user_entities_per_content = {
358
+ idx: content.entities for idx, content in enumerate(contents) if content.entities
359
+ }
355
360
  entity_links = await entity_processing.process_entities_batch(
356
- entity_resolver, conn, bank_id, unit_ids, non_duplicate_facts, log_buffer
361
+ entity_resolver,
362
+ conn,
363
+ bank_id,
364
+ unit_ids,
365
+ non_duplicate_facts,
366
+ log_buffer,
367
+ user_entities_per_content=user_entities_per_content,
357
368
  )
358
369
  log_buffer.append(f"[6] Process entities: {len(entity_links)} links in {time.time() - step_start:.3f}s")
359
370
 
@@ -20,6 +20,7 @@ class RetainContentDict(TypedDict, total=False):
20
20
  event_date: When the content occurred (optional, defaults to now)
21
21
  metadata: Custom key-value metadata (optional)
22
22
  document_id: Document ID for this content item (optional)
23
+ entities: User-provided entities to merge with extracted entities (optional)
23
24
  """
24
25
 
25
26
  content: str # Required
@@ -27,6 +28,7 @@ class RetainContentDict(TypedDict, total=False):
27
28
  event_date: datetime
28
29
  metadata: dict[str, str]
29
30
  document_id: str
31
+ entities: list[dict[str, str]] # [{"text": "...", "type": "..."}]
30
32
 
31
33
 
32
34
  def _now_utc() -> datetime:
@@ -46,6 +48,7 @@ class RetainContent:
46
48
  context: str = ""
47
49
  event_date: datetime = field(default_factory=_now_utc)
48
50
  metadata: dict[str, str] = field(default_factory=dict)
51
+ entities: list[dict[str, str]] = field(default_factory=list) # User-provided entities
49
52
 
50
53
 
51
54
  @dataclass
@@ -152,6 +155,9 @@ class ProcessedFact:
152
155
  # DB fields (set after insertion)
153
156
  unit_id: UUID | None = None
154
157
 
158
+ # Track which content this fact came from (for user entity merging)
159
+ content_index: int = 0
160
+
155
161
  @property
156
162
  def is_duplicate(self) -> bool:
157
163
  """Check if this fact was marked as a duplicate."""
@@ -194,6 +200,7 @@ class ProcessedFact:
194
200
  entities=entities,
195
201
  causal_relations=extracted_fact.causal_relations,
196
202
  chunk_id=chunk_id,
203
+ content_index=extracted_fact.content_index,
197
204
  )
198
205
 
199
206
 
@@ -98,7 +98,14 @@ class DefaultExtensionContext(ExtensionContext):
98
98
  """Run migrations for a specific schema."""
99
99
  from hindsight_api.migrations import run_migrations
100
100
 
101
- run_migrations(self._database_url, schema=schema)
101
+ # Prefer getting URL from memory engine (handles pg0 case where URL is set after init)
102
+ db_url = self._database_url
103
+ if self._memory_engine is not None:
104
+ engine_url = getattr(self._memory_engine, "db_url", None)
105
+ if engine_url:
106
+ db_url = engine_url
107
+
108
+ run_migrations(db_url, schema=schema)
102
109
 
103
110
  def get_memory_engine(self) -> "MemoryEngineInterface":
104
111
  """Get the memory engine interface."""
@@ -17,8 +17,9 @@ if TYPE_CHECKING:
17
17
  class OperationValidationError(Exception):
18
18
  """Raised when an operation fails validation."""
19
19
 
20
- def __init__(self, reason: str):
20
+ def __init__(self, reason: str, status_code: int = 403):
21
21
  self.reason = reason
22
+ self.status_code = status_code
22
23
  super().__init__(f"Operation validation failed: {reason}")
23
24
 
24
25
 
@@ -28,6 +29,7 @@ class ValidationResult:
28
29
 
29
30
  allowed: bool
30
31
  reason: str | None = None
32
+ status_code: int = 403 # Default to Forbidden
31
33
 
32
34
  @classmethod
33
35
  def accept(cls) -> "ValidationResult":
@@ -35,9 +37,9 @@ class ValidationResult:
35
37
  return cls(allowed=True)
36
38
 
37
39
  @classmethod
38
- def reject(cls, reason: str) -> "ValidationResult":
39
- """Create a rejected validation result with a reason."""
40
- return cls(allowed=False, reason=reason)
40
+ def reject(cls, reason: str, status_code: int = 403) -> "ValidationResult":
41
+ """Create a rejected validation result with a reason and HTTP status code."""
42
+ return cls(allowed=False, reason=reason, status_code=status_code)
41
43
 
42
44
 
43
45
  # =============================================================================
hindsight_api/main.py CHANGED
@@ -31,6 +31,7 @@ from .daemon import (
31
31
  IdleTimeoutMiddleware,
32
32
  daemonize,
33
33
  )
34
+ from .extensions import DefaultExtensionContext, OperationValidatorExtension, TenantExtension, load_extension
34
35
 
35
36
  # Filter deprecation warnings from third-party libraries
36
37
  warnings.filterwarnings("ignore", message="websockets.legacy is deprecated")
@@ -168,6 +169,8 @@ def main():
168
169
  llm_api_key=config.llm_api_key,
169
170
  llm_model=config.llm_model,
170
171
  llm_base_url=config.llm_base_url,
172
+ llm_max_concurrent=config.llm_max_concurrent,
173
+ llm_timeout=config.llm_timeout,
171
174
  embeddings_provider=config.embeddings_provider,
172
175
  embeddings_local_model=config.embeddings_local_model,
173
176
  embeddings_tei_url=config.embeddings_tei_url,
@@ -179,6 +182,8 @@ def main():
179
182
  log_level=args.log_level,
180
183
  mcp_enabled=config.mcp_enabled,
181
184
  graph_retriever=config.graph_retriever,
185
+ observation_min_facts=config.observation_min_facts,
186
+ observation_top_entities=config.observation_top_entities,
182
187
  skip_llm_verification=config.skip_llm_verification,
183
188
  lazy_reranker=config.lazy_reranker,
184
189
  )
@@ -191,8 +196,31 @@ def main():
191
196
  signal.signal(signal.SIGINT, _signal_handler)
192
197
  signal.signal(signal.SIGTERM, _signal_handler)
193
198
 
199
+ # Load operation validator extension if configured
200
+ operation_validator = load_extension("OPERATION_VALIDATOR", OperationValidatorExtension)
201
+ if operation_validator:
202
+ import logging
203
+
204
+ logging.info(f"Loaded operation validator: {operation_validator.__class__.__name__}")
205
+
206
+ # Load tenant extension if configured
207
+ tenant_extension = load_extension("TENANT", TenantExtension)
208
+ if tenant_extension:
209
+ import logging
210
+
211
+ logging.info(f"Loaded tenant extension: {tenant_extension.__class__.__name__}")
212
+
194
213
  # Create MemoryEngine (reads configuration from environment)
195
- _memory = MemoryEngine()
214
+ _memory = MemoryEngine(operation_validator=operation_validator, tenant_extension=tenant_extension)
215
+
216
+ # Set extension context on tenant extension (needed for schema provisioning)
217
+ if tenant_extension:
218
+ extension_context = DefaultExtensionContext(
219
+ database_url=config.database_url,
220
+ memory_engine=_memory,
221
+ )
222
+ tenant_extension.set_context(extension_context)
223
+ logging.info("Extension context set on tenant extension")
196
224
 
197
225
  # Create FastAPI app
198
226
  app = create_app(
hindsight_api/models.py CHANGED
@@ -18,6 +18,9 @@ class RequestContext:
18
18
  """
19
19
 
20
20
  api_key: str | None = None
21
+ api_key_id: str | None = None # UUID of the API key used for authentication
22
+ tenant_id: str | None = None # Tenant identifier (set by extension after auth)
23
+ internal: bool = False # True for background/internal operations (not user-visible)
21
24
 
22
25
 
23
26
  from pgvector.sqlalchemy import Vector
@@ -1,9 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hindsight-api
3
- Version: 0.1.16
3
+ Version: 0.2.1
4
4
  Summary: Hindsight: Agent Memory That Works Like Human Memory
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: alembic>=1.17.1
7
+ Requires-Dist: anthropic>=0.40.0
7
8
  Requires-Dist: asyncpg>=0.29.0
8
9
  Requires-Dist: dateparser>=1.2.2
9
10
  Requires-Dist: fastapi[standard]>=0.120.3
@@ -121,7 +122,7 @@ Configure via environment variables:
121
122
  | Variable | Description | Default |
122
123
  |----------|-------------|---------|
123
124
  | `HINDSIGHT_API_DATABASE_URL` | PostgreSQL connection string | `pg0` (embedded) |
124
- | `HINDSIGHT_API_LLM_PROVIDER` | `openai`, `groq`, `gemini`, `ollama` | `openai` |
125
+ | `HINDSIGHT_API_LLM_PROVIDER` | `openai`, `anthropic`, `gemini`, `groq`, `ollama`, `lmstudio` | `openai` |
125
126
  | `HINDSIGHT_API_LLM_API_KEY` | API key for LLM provider | - |
126
127
  | `HINDSIGHT_API_LLM_MODEL` | Model name | `gpt-4o-mini` |
127
128
  | `HINDSIGHT_API_HOST` | Server bind address | `0.0.0.0` |
@@ -1,12 +1,12 @@
1
1
  hindsight_api/__init__.py,sha256=lPhgtKMvT8qjORFKWlhlq-LVdwesIu0gbUYNPZQEFiI,1197
2
2
  hindsight_api/banner.py,sha256=BXn-jhkXe4xi-YV4JeuaVvjYhTMs96O43XoOMv4Cd28,4591
3
- hindsight_api/config.py,sha256=9li81n7Ugiefzr4q2A0w6V6JhwrFkUaIa6yXMetIvas,6919
3
+ hindsight_api/config.py,sha256=cf1vjDJay-HrTKp0ONGPmgk5szcK7Ynz-UJvjup3jb0,8175
4
4
  hindsight_api/daemon.py,sha256=3CKcO_ENQ57dIWrTsmYUj-V4zvoAB1toNtVh3EVkg-c,5982
5
- hindsight_api/main.py,sha256=7AFOaZIx7Rm86BCQGZnEniDCh0BhKg2_ggMS4qUvuTc,8636
5
+ hindsight_api/main.py,sha256=ZhUVwAnkt7Po4y2LsGj_EwUUXLi1t-MDkilp8H_gvro,9969
6
6
  hindsight_api/mcp_local.py,sha256=fL2hpwQSNExcjIwZn1E5vy5No6iZFmw78yRNXxJzri0,7371
7
7
  hindsight_api/metrics.py,sha256=sQI5MhC2xj9ONZ6Hdjf6r6r3NbYYd3ExyVOn1Uky49A,7239
8
8
  hindsight_api/migrations.py,sha256=X5jYkrDhbeFzXOUoPRvPzkGHQsjlZ7oz_P71UI82VT4,9104
9
- hindsight_api/models.py,sha256=LvOpCfuDjnVH-dEzOSolCOZnkoPiOZP_J9HK82sD1_0,12700
9
+ hindsight_api/models.py,sha256=p-rM84d9TR4TKIwV8-brLyEqDlSoBuP0bYs4Fl-ju2s,12954
10
10
  hindsight_api/pg0.py,sha256=SEIwYq8xp0s0YbV3CIy_ioZ5-Bfe8_rxdeP0YasAeXk,4677
11
11
  hindsight_api/server.py,sha256=OrSd0G-79U07EXFc838c1vzUL-1O6wuxTMqUmMINpGY,1247
12
12
  hindsight_api/alembic/README,sha256=MVlc9TYmr57RbhXET6QxgyCcwWP7w-vLkEsirENqiIQ,38
@@ -18,19 +18,19 @@ hindsight_api/alembic/versions/c8e5f2a3b4d1_add_retain_params_to_documents.py,sh
18
18
  hindsight_api/alembic/versions/d9f6a3b4c5e2_rename_bank_to_interactions.py,sha256=s5_B2D0JdaxO7WM-vWC5Yt6hAtTsAUzJhFGLFSkfuQU,1808
19
19
  hindsight_api/alembic/versions/e0a1b2c3d4e5_disposition_to_3_traits.py,sha256=IdDP6fgsYj5fCXAF0QT-3t_wcKJsnf7B0mh7qS-cf_w,3806
20
20
  hindsight_api/alembic/versions/rename_personality_to_disposition.py,sha256=A29-nDJ2Re4u9jdp2sUw29It808j4h6BpcA4wDHJMJ8,2765
21
- hindsight_api/api/__init__.py,sha256=zoDWA86ttx-UriC35UIgdPswIrau7GuMWTN63wYsUdM,2916
22
- hindsight_api/api/http.py,sha256=M3mJIfqILPe5kC3iO2Ds11XmVPD5n_SuUSF3s8mUmhM,76049
23
- hindsight_api/api/mcp.py,sha256=Iowo3ourjWx7ZqLiCwF9nvjMAJpRceBprF5cgn5M6fs,7853
21
+ hindsight_api/api/__init__.py,sha256=npF0AAy8WJhHF5a9ehkNn9_iYLk7RQOk2gdkdFb49Hk,3840
22
+ hindsight_api/api/http.py,sha256=R9S55BnIhDxuAfbEbKD2SuMhB-uSHtgoHkDmBn_hijo,80177
23
+ hindsight_api/api/mcp.py,sha256=G4EnptAO9aaKc7QjlX1vp_cNNGDvKHgoBvow1olbjjs,15192
24
24
  hindsight_api/engine/__init__.py,sha256=-BwaSwG9fTT_BBO0c_2MBkxG6-tGdclSzIqsgHw4cnw,1633
25
25
  hindsight_api/engine/cross_encoder.py,sha256=5WmUx9yfJdIwZ0nA218O-mMKQJ7EKaPOtwhMiDbG8KQ,10483
26
26
  hindsight_api/engine/db_utils.py,sha256=0T5tL2SZ49JQihfyZYlTDThIfocKzkr1OpxQpJzPCGE,2687
27
27
  hindsight_api/engine/embeddings.py,sha256=IEdP5-p6oTJRRKV2JzUEojByJGShUEmkInCyA9wM8tg,10219
28
28
  hindsight_api/engine/entity_resolver.py,sha256=f-fbUDKCrM9a5Sz10J0rW3jV7dib7BmpyGyassspKXg,23510
29
- hindsight_api/engine/interface.py,sha256=F6BgnjloH7EgL9_D2NpPuabR_zR-h_iEJBQ0ERC2P58,16090
30
- hindsight_api/engine/llm_wrapper.py,sha256=nLdVAk2xtkbwxLFMQNmEU-JmHucdtQoh3ph0BWX4sDc,29140
31
- hindsight_api/engine/memory_engine.py,sha256=wQESgZ49srxgbpQTfvAM5BDp4-st1NGhiqktj753qaA,167050
29
+ hindsight_api/engine/interface.py,sha256=zNfBvK5_RV8st7fHdeIfnVk7AMmbpo3O6uVpXHWgiJ4,16297
30
+ hindsight_api/engine/llm_wrapper.py,sha256=_xfGWmHth8No93hLHSCOxFaa18IxodUxDdEYJ6Wjcnc,39956
31
+ hindsight_api/engine/memory_engine.py,sha256=69KEpqCiWOdTdzGEPRpVM8zOcRaCHwgGqtiZTw50Afc,169504
32
32
  hindsight_api/engine/query_analyzer.py,sha256=DKFxmyyVVc59zwKbbGx4D22UVp6TxmD7jAa7cg9FGSU,19641
33
- hindsight_api/engine/response_models.py,sha256=QeESHC7oh84SYPDrR6FqHjiGBZnTAzo61IDB-qwVTSY,8737
33
+ hindsight_api/engine/response_models.py,sha256=UUNkWGquoBBIU7Fm2GfW1GllcSk_4t-PGB-8_qsKUnA,9115
34
34
  hindsight_api/engine/task_backend.py,sha256=txtcMUzHW1MigDCW7XsVZc5zqvM9FbR_xF_c9BKokBk,8054
35
35
  hindsight_api/engine/utils.py,sha256=TwuipFRvN0Pu196JLakzQ71E3GAwySc5q6pByC81Ak4,6991
36
36
  hindsight_api/engine/retain/__init__.py,sha256=t6q3-_kf4iYTl9j2PVB6laqMSs6UuPeXBSYMW6HT1sA,1152
@@ -39,14 +39,14 @@ hindsight_api/engine/retain/chunk_storage.py,sha256=zXAqbcFeYpjyWlOoi8zeK5G91zHp
39
39
  hindsight_api/engine/retain/deduplication.py,sha256=kqs7I7eIc_ppvgAF9GlzL6fSGuEEzrgw17-7NdyUDis,3099
40
40
  hindsight_api/engine/retain/embedding_processing.py,sha256=R35oyKYIKjuqC-yZl5Ru56F8xRe0N6KW_9p5PZ9CBi0,1649
41
41
  hindsight_api/engine/retain/embedding_utils.py,sha256=uulXIBiA7XNsj16K1VGawR3s5jV-hsAmvmoCi-IodpU,1565
42
- hindsight_api/engine/retain/entity_processing.py,sha256=5EYzyH_JjbhYQ0zQ8gX6xs0wCH6vmxMYUe6_qVJdvQA,2547
43
- hindsight_api/engine/retain/fact_extraction.py,sha256=E9AswSrqx3X74gj5-qstbm2wqPv4kUMddkdn5yExKvI,50166
42
+ hindsight_api/engine/retain/entity_processing.py,sha256=0x5b48Im7pWjeqg3xTMIRVhrzd4otc4rSkFBjxgOL9Y,3632
43
+ hindsight_api/engine/retain/fact_extraction.py,sha256=tR7fvk1eH7xcoQARdCregu3D7ETD9upz4WnhLOUlCcM,51641
44
44
  hindsight_api/engine/retain/fact_storage.py,sha256=zhIiccW1D4wkgnZMFcbxDeMeHy5v4JGKfEPBIFNLch4,5632
45
45
  hindsight_api/engine/retain/link_creation.py,sha256=KP2kGU2VCymJptgw0hjaSdsjvncBgNp3P_A4OB_qx-w,3082
46
46
  hindsight_api/engine/retain/link_utils.py,sha256=w8n_pPzs_rd3EMkb7nv4k_qSZttAKDig93hSSjl-Xbc,32854
47
- hindsight_api/engine/retain/observation_regeneration.py,sha256=qE1-iSyH0lh5Zab1XIwSQSpxEArdOJOAC_yJY5iHLMQ,8143
48
- hindsight_api/engine/retain/orchestrator.py,sha256=9l27-IMemx4Wrym2HJ59DSUuh6NqMpTs0wqul2dwUzA,20631
49
- hindsight_api/engine/retain/types.py,sha256=UzCXauLrMD26g5oZK3_oQ-gTaSSsd-Ttjh17le64HH4,6898
47
+ hindsight_api/engine/retain/observation_regeneration.py,sha256=GByj4cQ-kp5iM_juryWjKYRYN2H63ttsmcpoUJzIIaI,8259
48
+ hindsight_api/engine/retain/orchestrator.py,sha256=Qy6g8Df-k666GPhJK2xPvt5TjyVH4IY8jxiEIg_pUug,21052
49
+ hindsight_api/engine/retain/types.py,sha256=dgWFvr1oeAq5y4UFVBXWzUjUKA2WB7nlJ0n9V1Ceuvw,7301
50
50
  hindsight_api/engine/search/__init__.py,sha256=YPz_4g7IOabx078Xwg3RBfbOpJ649NRwNfe0gTI9P1U,802
51
51
  hindsight_api/engine/search/fusion.py,sha256=cY81BH9U5RyWrPXbQnrDBghtelDMckZWCke9aqMyNnQ,4220
52
52
  hindsight_api/engine/search/graph_retrieval.py,sha256=KV1LK_y8R_x4dYwikbZaJTVGPp7kXcrCy0IswaXCD4g,8625
@@ -62,14 +62,14 @@ hindsight_api/engine/search/tracer.py,sha256=hjm8fEESqJnOhsQwmwmvO1gthIO87WC3Pd-
62
62
  hindsight_api/engine/search/types.py,sha256=2cK-5oynPTWc7UxnA7TFnwzNkcujCfOUvVf5VCk_srM,5594
63
63
  hindsight_api/extensions/__init__.py,sha256=gt8RxBwz6JOjbwbPPJ1LGE7ugk1nYkEAlD-LN1ap7FE,1926
64
64
  hindsight_api/extensions/base.py,sha256=M7zXuM-tbqDnUwXX1mxAxiFs1eXOzNqIJutKLiUE4mU,2357
65
- hindsight_api/extensions/context.py,sha256=NXXoBd6Z_nhYWFHgzl6oxrWM_VfPvY99erYLrHR24CE,3640
65
+ hindsight_api/extensions/context.py,sha256=nyp-ARqclo4K8SWwkIGhHAxl43XZIY5JEcuQWTAMo3k,3937
66
66
  hindsight_api/extensions/http.py,sha256=c-a1g6R6rzibyReyR-WHz8DjRRGr4rVSyV9KB4UxVVU,2907
67
67
  hindsight_api/extensions/loader.py,sha256=UwGM0XH7zHGng_xfHUY0VbOQemj9DmjuDaMst1TrFi8,4170
68
- hindsight_api/extensions/operation_validator.py,sha256=zQPD8pTMJJxQjpByxa4JxvGgD5i3A4PBaK9Z1BizL7o,10536
68
+ hindsight_api/extensions/operation_validator.py,sha256=340M0NqA7juSZimOicIhkZ2j0lc9L4M3Uzr94iGnLKA,10720
69
69
  hindsight_api/extensions/tenant.py,sha256=gvngBMn3cJtUfd4P0P_288faNJq00T8zPQkeldEsD3g,1903
70
70
  hindsight_api/extensions/builtin/__init__.py,sha256=hLx2oFYZ1JtZhTWfab6AYcR02SWP2gIdbEqnZezT8ek,526
71
71
  hindsight_api/extensions/builtin/tenant.py,sha256=lsS0GDEUXmfPBzqhqk2FpN4Z_k5cA3Y3PFNYyiiuZjU,1444
72
- hindsight_api-0.1.16.dist-info/METADATA,sha256=mMw-GSyQPrE_DnBIZWMfNck4qjyEuFQ8fyDsBP6i9ZQ,5408
73
- hindsight_api-0.1.16.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
74
- hindsight_api-0.1.16.dist-info/entry_points.txt,sha256=vqZv5WLHbSx8vyec5RtMlUqtE_ul7DTgEVODSmou6Og,109
75
- hindsight_api-0.1.16.dist-info/RECORD,,
72
+ hindsight_api-0.2.1.dist-info/METADATA,sha256=RyCudeeIv6lefNtSIS2n-MDGYcp5jHCF8GkjRUIGzfM,5465
73
+ hindsight_api-0.2.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
74
+ hindsight_api-0.2.1.dist-info/entry_points.txt,sha256=vqZv5WLHbSx8vyec5RtMlUqtE_ul7DTgEVODSmou6Og,109
75
+ hindsight_api-0.2.1.dist-info/RECORD,,