hindsight-api 0.0.21__py3-none-any.whl → 0.1.0__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.
@@ -28,30 +28,48 @@ class OpinionExtractionResponse(BaseModel):
28
28
  )
29
29
 
30
30
 
31
- def describe_trait(name: str, value: float) -> str:
32
- """Convert trait value to descriptive text."""
33
- if value >= 0.8:
34
- return f"very high {name}"
35
- elif value >= 0.6:
36
- return f"high {name}"
37
- elif value >= 0.4:
38
- return f"moderate {name}"
39
- elif value >= 0.2:
40
- return f"low {name}"
41
- else:
42
- return f"very low {name}"
31
+ def describe_trait_level(value: int) -> str:
32
+ """Convert trait value (1-5) to descriptive text."""
33
+ levels = {
34
+ 1: "very low",
35
+ 2: "low",
36
+ 3: "moderate",
37
+ 4: "high",
38
+ 5: "very high"
39
+ }
40
+ return levels.get(value, "moderate")
43
41
 
44
42
 
45
43
  def build_disposition_description(disposition: DispositionTraits) -> str:
46
44
  """Build a disposition description string from disposition traits."""
47
- return f"""Your disposition traits:
48
- - {describe_trait('openness to new ideas', disposition.openness)}
49
- - {describe_trait('conscientiousness and organization', disposition.conscientiousness)}
50
- - {describe_trait('extraversion and sociability', disposition.extraversion)}
51
- - {describe_trait('agreeableness and cooperation', disposition.agreeableness)}
52
- - {describe_trait('emotional sensitivity', disposition.neuroticism)}
45
+ skepticism_desc = {
46
+ 1: "You are very trusting and tend to take information at face value.",
47
+ 2: "You tend to trust information but may question obvious inconsistencies.",
48
+ 3: "You have a balanced approach to information, neither too trusting nor too skeptical.",
49
+ 4: "You are somewhat skeptical and often question the reliability of information.",
50
+ 5: "You are highly skeptical and critically examine all information for accuracy and hidden motives."
51
+ }
52
+
53
+ literalism_desc = {
54
+ 1: "You interpret information very flexibly, reading between the lines and inferring intent.",
55
+ 2: "You tend to consider context and implied meaning alongside literal statements.",
56
+ 3: "You balance literal interpretation with contextual understanding.",
57
+ 4: "You prefer to interpret information more literally and precisely.",
58
+ 5: "You interpret information very literally and focus on exact wording and commitments."
59
+ }
60
+
61
+ empathy_desc = {
62
+ 1: "You focus primarily on facts and data, setting aside emotional context.",
63
+ 2: "You consider facts first but acknowledge emotional factors exist.",
64
+ 3: "You balance factual analysis with emotional understanding.",
65
+ 4: "You give significant weight to emotional context and human factors.",
66
+ 5: "You strongly consider the emotional state and circumstances of others when forming memories."
67
+ }
53
68
 
54
- Disposition influence strength: {int(disposition.bias_strength * 100)}% (how much your disposition shapes your opinions)"""
69
+ return f"""Your disposition traits:
70
+ - Skepticism ({describe_trait_level(disposition.skepticism)}): {skepticism_desc.get(disposition.skepticism, skepticism_desc[3])}
71
+ - Literalism ({describe_trait_level(disposition.literalism)}): {literalism_desc.get(disposition.literalism, literalism_desc[3])}
72
+ - Empathy ({describe_trait_level(disposition.empathy)}): {empathy_desc.get(disposition.empathy, empathy_desc[3])}"""
55
73
 
56
74
 
57
75
  def format_facts_for_prompt(facts: List[MemoryFact]) -> str:
@@ -78,10 +96,6 @@ def format_facts_for_prompt(facts: List[MemoryFact]) -> str:
78
96
  elif isinstance(occurred_start, datetime):
79
97
  fact_obj["occurred_start"] = occurred_start.strftime('%Y-%m-%d %H:%M:%S')
80
98
 
81
- # Add activation if available
82
- if fact.activation is not None:
83
- fact_obj["score"] = fact.activation
84
-
85
99
  formatted.append(fact_obj)
86
100
 
87
101
  return json.dumps(formatted, indent=2)
@@ -141,13 +155,28 @@ Based on everything I know, believe, and who I am (including my name, dispositio
141
155
 
142
156
  def get_system_message(disposition: DispositionTraits) -> str:
143
157
  """Get the system message for the think LLM call."""
144
- bias_strength = disposition.bias_strength
145
- if bias_strength >= 0.7:
146
- disposition_instruction = "Your disposition strongly influences your thinking. Let your traits guide how you interpret facts and form opinions. Don't be afraid to be biased based on your disposition."
147
- elif bias_strength >= 0.4:
148
- disposition_instruction = "Your disposition moderately influences your thinking. Balance your personal traits with objective analysis."
149
- else:
150
- disposition_instruction = "Your disposition has minimal influence on your thinking. Focus primarily on facts while keeping your traits in mind."
158
+ # Build disposition-specific instructions based on trait values
159
+ instructions = []
160
+
161
+ # Skepticism influences how much to question/doubt information
162
+ if disposition.skepticism >= 4:
163
+ instructions.append("Be skeptical of claims and look for potential issues or inconsistencies.")
164
+ elif disposition.skepticism <= 2:
165
+ instructions.append("Trust the information provided and take statements at face value.")
166
+
167
+ # Literalism influences interpretation style
168
+ if disposition.literalism >= 4:
169
+ instructions.append("Interpret information literally and focus on exact commitments and wording.")
170
+ elif disposition.literalism <= 2:
171
+ instructions.append("Read between the lines and consider implied meaning and context.")
172
+
173
+ # Empathy influences consideration of emotional factors
174
+ if disposition.empathy >= 4:
175
+ instructions.append("Consider the emotional state and circumstances behind the information.")
176
+ elif disposition.empathy <= 2:
177
+ instructions.append("Focus on facts and outcomes rather than emotional context.")
178
+
179
+ disposition_instruction = " ".join(instructions) if instructions else "Balance your disposition traits when interpreting information."
151
180
 
152
181
  return f"You are a person with your own thoughts, experiences, opinions, and disposition. When asked a question, respond naturally like a human would - share what you genuinely think based on what you know and have experienced. {disposition_instruction} Be direct, express your views confidently, and use 'I think', 'I believe', 'in my view', etc. Respond in plain text without markdown formatting."
153
182
 
@@ -3,8 +3,8 @@ Database migration management using Alembic.
3
3
 
4
4
  This module provides programmatic access to run database migrations
5
5
  on application startup. It is designed to be safe for concurrent
6
- execution - Alembic uses PostgreSQL transactions to prevent
7
- conflicts when multiple instances start simultaneously.
6
+ execution using PostgreSQL advisory locks to coordinate between
7
+ distributed workers.
8
8
 
9
9
  Important: All migrations must be backward-compatible to allow
10
10
  safe rolling deployments.
@@ -19,19 +19,51 @@ from typing import Optional
19
19
 
20
20
  from alembic import command
21
21
  from alembic.config import Config
22
+ from sqlalchemy import create_engine, text
22
23
 
23
24
  logger = logging.getLogger(__name__)
24
25
 
26
+ # Advisory lock ID for migrations (arbitrary unique number)
27
+ MIGRATION_LOCK_ID = 123456789
28
+
29
+
30
+ def _run_migrations_internal(database_url: str, script_location: str) -> None:
31
+ """
32
+ Internal function to run migrations without locking.
33
+ """
34
+ logger.info(f"Running database migrations to head...")
35
+ logger.info(f"Database URL: {database_url}")
36
+ logger.info(f"Script location: {script_location}")
37
+
38
+ # Create Alembic configuration programmatically (no alembic.ini needed)
39
+ alembic_cfg = Config()
40
+
41
+ # Set the script location (where alembic versions are stored)
42
+ alembic_cfg.set_main_option("script_location", script_location)
43
+
44
+ # Set the database URL
45
+ alembic_cfg.set_main_option("sqlalchemy.url", database_url)
46
+
47
+ # Configure logging (optional, but helps with debugging)
48
+ # Uses Python's logging system instead of alembic.ini
49
+ alembic_cfg.set_main_option("prepend_sys_path", ".")
50
+
51
+ # Set path_separator to avoid deprecation warning
52
+ alembic_cfg.set_main_option("path_separator", "os")
53
+
54
+ # Run migrations to head (latest version)
55
+ command.upgrade(alembic_cfg, "head")
56
+
57
+ logger.info("Database migrations completed successfully")
25
58
 
26
59
 
27
60
  def run_migrations(database_url: str, script_location: Optional[str] = None) -> None:
28
61
  """
29
62
  Run database migrations to the latest version using programmatic Alembic configuration.
30
63
 
31
- This function is safe to call on every application startup:
32
- - Alembic checks the current schema version in the database
33
- - Only missing migrations are applied
34
- - PostgreSQL transactions prevent concurrent migration conflicts
64
+ This function is safe to call from multiple distributed workers simultaneously:
65
+ - Uses PostgreSQL advisory lock to ensure only one worker runs migrations at a time
66
+ - Other workers wait for the lock, then verify migrations are complete
35
67
  - If schema is already up-to-date, this is a fast no-op
36
68
 
37
69
  Args:
@@ -69,32 +101,22 @@ def run_migrations(database_url: str, script_location: Optional[str] = None) ->
69
101
  "Database migrations cannot be run."
70
102
  )
71
103
 
72
- logger.info(f"Running database migrations to head...")
73
- logger.info(f"Database URL: {database_url}")
74
- logger.info(f"Script location: {script_location}")
75
-
76
- # Create Alembic configuration programmatically (no alembic.ini needed)
77
- alembic_cfg = Config()
78
-
79
- # Set the script location (where alembic versions are stored)
80
- alembic_cfg.set_main_option("script_location", script_location)
81
-
82
- # Set the database URL
83
- alembic_cfg.set_main_option("sqlalchemy.url", database_url)
84
-
85
- # Configure logging (optional, but helps with debugging)
86
- # Uses Python's logging system instead of alembic.ini
87
- alembic_cfg.set_main_option("prepend_sys_path", ".")
88
-
89
- # Set path_separator to avoid deprecation warning
90
- alembic_cfg.set_main_option("path_separator", "os")
91
-
92
- # Run migrations to head (latest version)
93
- # Note: Alembic may call sys.exit() on errors instead of raising exceptions
94
- # We rely on the outer try/except and logging to catch issues
95
- command.upgrade(alembic_cfg, "head")
96
-
97
- logger.info("Database migrations completed successfully")
104
+ # Use PostgreSQL advisory lock to coordinate between distributed workers
105
+ engine = create_engine(database_url)
106
+ with engine.connect() as conn:
107
+ # pg_advisory_lock blocks until the lock is acquired
108
+ # The lock is automatically released when the connection closes
109
+ logger.debug(f"Acquiring migration advisory lock (id={MIGRATION_LOCK_ID})...")
110
+ conn.execute(text(f"SELECT pg_advisory_lock({MIGRATION_LOCK_ID})"))
111
+ logger.debug("Migration advisory lock acquired")
112
+
113
+ try:
114
+ # Run migrations while holding the lock
115
+ _run_migrations_internal(database_url, script_location)
116
+ finally:
117
+ # Explicitly release the lock (also released on connection close)
118
+ conn.execute(text(f"SELECT pg_advisory_unlock({MIGRATION_LOCK_ID})"))
119
+ logger.debug("Migration advisory lock released")
98
120
 
99
121
  except FileNotFoundError:
100
122
  logger.error(f"Alembic script location not found at {script_location}")
hindsight_api/models.py CHANGED
@@ -292,8 +292,7 @@ class Bank(Base):
292
292
  JSONB,
293
293
  nullable=False,
294
294
  server_default=sql_text(
295
- '\'{"openness": 0.5, "conscientiousness": 0.5, "extraversion": 0.5, '
296
- '"agreeableness": 0.5, "neuroticism": 0.5, "bias_strength": 0.5}\'::jsonb'
295
+ '\'{"skepticism": 3, "literalism": 3, "empathy": 3}\'::jsonb'
297
296
  )
298
297
  )
299
298
  background: Mapped[str] = mapped_column(Text, nullable=False, server_default="")
hindsight_api/pg0.py CHANGED
@@ -153,46 +153,18 @@ class EmbeddedPostgres:
153
153
  """
154
154
  Ensure pg0 is available.
155
155
 
156
- First checks PATH, then default location, then downloads if needed.
156
+ Checks PATH and default location. If not found, raises an error
157
+ instructing the user to install pg0 manually.
157
158
  """
158
159
  if self.is_installed():
159
160
  logger.debug(f"pg0 found at {self._binary_path}")
160
161
  return
161
162
 
162
- logger.info("pg0 not found, downloading...")
163
-
164
- # Log platform information
165
- binary_name = get_platform_binary_name()
166
- logger.info(f"Detected platform: system={platform.system()}, machine={platform.machine()}")
167
-
168
- # Install to default location
169
- install_dir = Path.home() / ".hindsight" / "bin"
170
- install_dir.mkdir(parents=True, exist_ok=True)
171
- install_path = install_dir / "pg0"
172
-
173
- # Download the binary
174
- download_url = get_download_url(self.version)
175
- logger.info(f"Downloading from {download_url}")
176
-
177
- try:
178
- async with httpx.AsyncClient(follow_redirects=True, timeout=300.0) as client:
179
- response = await client.get(download_url)
180
- response.raise_for_status()
181
-
182
- # Write binary to disk
183
- with open(install_path, "wb") as f:
184
- f.write(response.content)
185
-
186
- # Make executable on Unix
187
- if platform.system() != "Windows":
188
- st = os.stat(install_path)
189
- os.chmod(install_path, st.st_mode | stat.S_IEXEC)
190
-
191
- self._binary_path = install_path
192
- logger.info(f"Installed pg0 to {install_path}")
193
-
194
- except httpx.HTTPError as e:
195
- raise RuntimeError(f"Failed to download pg0: {e}") from e
163
+ raise RuntimeError(
164
+ "pg0 is not installed. Please install it manually:\n"
165
+ " curl -fsSL https://github.com/vectorize-io/pg0/releases/latest/download/pg0-linux-amd64 -o ~/.local/bin/pg0 && chmod +x ~/.local/bin/pg0\n"
166
+ "Or visit: https://github.com/vectorize-io/pg0/releases"
167
+ )
196
168
 
197
169
  def _run_command(self, *args: str, capture_output: bool = True) -> subprocess.CompletedProcess:
198
170
  """Run a pg0 command synchronously."""
@@ -227,6 +199,13 @@ class EmbeddedPostgres:
227
199
  return match.group(1)
228
200
  return None
229
201
 
202
+ async def _get_version(self) -> str:
203
+ """Get the pg0 version."""
204
+ returncode, stdout, stderr = await self._run_command_async("--version", timeout=10)
205
+ if returncode == 0 and stdout:
206
+ return stdout.strip()
207
+ return "unknown"
208
+
230
209
  async def start(self, max_retries: int = 3, retry_delay: float = 2.0) -> str:
231
210
  """
232
211
  Start the PostgreSQL server with retry logic.
@@ -244,7 +223,9 @@ class EmbeddedPostgres:
244
223
  if not self.is_installed():
245
224
  raise RuntimeError("pg0 is not installed. Call ensure_installed() first.")
246
225
 
247
- logger.info(f"Starting embedded PostgreSQL (name: {self.name}, port: {self.port})...")
226
+ # Log pg0 version
227
+ version = await self._get_version()
228
+ logger.info(f"Starting embedded PostgreSQL with pg0 {version} (name: {self.name}, port: {self.port})...")
248
229
 
249
230
  last_error = None
250
231
  for attempt in range(1, max_retries + 1):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hindsight-api
3
- Version: 0.0.21
3
+ Version: 0.1.0
4
4
  Summary: Temporal + Semantic + Entity Memory System for AI agents using PostgreSQL
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: alembic>=1.17.1
@@ -23,7 +23,7 @@ Requires-Dist: pydantic>=2.0.0
23
23
  Requires-Dist: python-dateutil>=2.8.0
24
24
  Requires-Dist: python-dotenv>=1.0.0
25
25
  Requires-Dist: rich>=13.0.0
26
- Requires-Dist: sentence-transformers>=2.2.0
26
+ Requires-Dist: sentence-transformers>=3.0.0
27
27
  Requires-Dist: sqlalchemy>=2.0.44
28
28
  Requires-Dist: tiktoken>=0.12.0
29
29
  Requires-Dist: torch>=2.0.0
@@ -36,7 +36,6 @@ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'test'
36
36
  Requires-Dist: pytest-timeout>=2.4.0; extra == 'test'
37
37
  Requires-Dist: pytest-xdist>=3.0.0; extra == 'test'
38
38
  Requires-Dist: pytest>=7.0.0; extra == 'test'
39
- Requires-Dist: testcontainers[postgres]>=4.0.0; extra == 'test'
40
39
  Description-Content-Type: text/markdown
41
40
 
42
41
  # Memory
@@ -0,0 +1,51 @@
1
+ hindsight_api/__init__.py,sha256=yQWYWUWEhvs1OY1coENhZV_CuOAWmN_YKZXQMIvGN94,851
2
+ hindsight_api/cli.py,sha256=NPuykf35Us8J40iV4-mrGk13d1GSt2TeBl5Nd88CY0I,3274
3
+ hindsight_api/metrics.py,sha256=j4-eeqVjjcGQxAxS_GgEaBNm10KdUxrGS_I2d1IM1hY,7255
4
+ hindsight_api/migrations.py,sha256=A6D1LVuReJ7Ua10ABWyW2-neE7CtRErGWFipbVNH7mw,7382
5
+ hindsight_api/models.py,sha256=ncIi8agl3PVk7ffyXlJosFym1jJZZhVmXTguZ3EnAEc,12515
6
+ hindsight_api/pg0.py,sha256=_GuVccjE0_OthaK72_GXC3NkcI9q3MkU3i8m685mDfQ,13542
7
+ hindsight_api/api/__init__.py,sha256=dIJqoygqYaEgm-Bd7qwZ4UTnb9UPyXtlDxZnQpvVC0o,2946
8
+ hindsight_api/api/http.py,sha256=7g6ij_Kegu5fSoqDIpPYWVS1cqxpD1Uc_0moQ5bbddA,69206
9
+ hindsight_api/api/mcp.py,sha256=DldtC8LQUguAbJSSHnEBS65wC-AQBjcF8rl51xUR1gQ,7808
10
+ hindsight_api/engine/__init__.py,sha256=5DU5DvnJdzkrgNgKchpzkiJr-37I-kE1tegJg2LF04k,1214
11
+ hindsight_api/engine/cross_encoder.py,sha256=8BBMyM5ryRuQ7W8x0jea4Y6GW3MtqtxyHGz1yyCXz2g,3175
12
+ hindsight_api/engine/db_utils.py,sha256=p1Ne70wPP327xdPI_XjMfnagilY8sknbkhEIZuED6DU,2724
13
+ hindsight_api/engine/embeddings.py,sha256=9drPQoK8LtertxsnI8GU24bPQtOJb8n3Uguhz6Nl_x0,3886
14
+ hindsight_api/engine/entity_resolver.py,sha256=w5DPCuYNsK4GF8Qe3oY7jCKcOT1WYx2h0YD1nX0QRtA,23184
15
+ hindsight_api/engine/llm_wrapper.py,sha256=Pro7r-bkilfqRH3x4E_k08p41kntRoCpJQ0FyrQBzJ0,22003
16
+ hindsight_api/engine/memory_engine.py,sha256=dk3NjIQo-re8Y1rrRNDwukQdAqr5Yxe-Nuaf27XeCnU,133449
17
+ hindsight_api/engine/query_analyzer.py,sha256=K0QCg7tsbqtwC7TR5wt3FPoP8QDuZsX9r0Zljc8nnYo,19733
18
+ hindsight_api/engine/response_models.py,sha256=e-_vE1zAVFLpkl6SeHIYvHcQ4Z-AaOdq0jjjhh8yHk4,8683
19
+ hindsight_api/engine/task_backend.py,sha256=ojxMC9PeHdnkWVs2ozeqycjI_1mmpkDa0_Qfej9AHrg,7287
20
+ hindsight_api/engine/utils.py,sha256=VAjpZSbdiwhlE6cDlYfTt_-5hIJ--0xtfixETK0LPSk,6910
21
+ hindsight_api/engine/retain/__init__.py,sha256=L_QuR1YLHsJ7OCmVFNsZe8WDjbsTTHL-wCiUXtw1aUE,1230
22
+ hindsight_api/engine/retain/bank_utils.py,sha256=j5vzmNwUvtx3kCIQgzSHCvByCvpIRjLbjx74r1XGEIg,14121
23
+ hindsight_api/engine/retain/chunk_storage.py,sha256=rjmfnllS185tmjJGkMjWZ9q_6hJO4N6Ll9jgPx6f5xo,2081
24
+ hindsight_api/engine/retain/deduplication.py,sha256=9YXgVI_m1Mtz5Cv46ZceCEs0GwpLqTPHrZ-vlWlXk6I,3313
25
+ hindsight_api/engine/retain/embedding_processing.py,sha256=cHTt3rPvDCWBWVPfSeg6bwH8HoXYGmP4bvS21boNONI,1734
26
+ hindsight_api/engine/retain/embedding_utils.py,sha256=Q24h_iw6pRAW2vDWPvauWY1o3bXLzW3eWvSxDALDiE0,1588
27
+ hindsight_api/engine/retain/entity_processing.py,sha256=F_6yYjf7Me5khg-X57ZW4wK5BBAmzMpry-TXwVFQZ-8,2658
28
+ hindsight_api/engine/retain/fact_extraction.py,sha256=ZBT--eKLcAW0a3GJ-TE7k_nzA_R4fJboEaakKx5W2iA,50807
29
+ hindsight_api/engine/retain/fact_storage.py,sha256=rKJiWr_1lrqyB6s0mTCnTiHVZIUbCfd3zigNwISnVPI,5637
30
+ hindsight_api/engine/retain/link_creation.py,sha256=rkYKO73dWBL8BbRBeiwNgHzwrU-sKWUjmrgLIxr3LiA,3280
31
+ hindsight_api/engine/retain/link_utils.py,sha256=g80xUMr45na8UX505VnoZ7jSKdvyRgxDHnDoINd8GNI,28828
32
+ hindsight_api/engine/retain/observation_regeneration.py,sha256=ykEMZihF1Vt8Z7427k1OJKyEjYp0qIs9P1IqP6eyI58,8069
33
+ hindsight_api/engine/retain/orchestrator.py,sha256=z71wMuJsdjLFlhhwnLHuJ3Y3QQk-9w_faKn1zZUYCXw,17156
34
+ hindsight_api/engine/retain/types.py,sha256=JJ4t8Qtp64kTPB9CKOFDXqdos2i8GZXmJZNzBDaNwHY,6514
35
+ hindsight_api/engine/search/__init__.py,sha256=7X6U10bVw0JRWxQdE5RCfVpawDlSUldi1mPoCzY0V0A,363
36
+ hindsight_api/engine/search/fusion.py,sha256=so6LU7kWRR-VJd1Pxlu8idRJ7P2WLCoDwXUnb8jQifo,4309
37
+ hindsight_api/engine/search/observation_utils.py,sha256=SPrDx6M0daJ_zLLkk78GlQIG3EL7DqMKSu_etKerUfU,4331
38
+ hindsight_api/engine/search/reranking.py,sha256=Bk5i5kal5yy4CM8m2uSxAumLPgLeHdncBX6wk4WTmEI,3525
39
+ hindsight_api/engine/search/retrieval.py,sha256=i6pffxsfYkTjQYS8iNMC60owMr__a8i7khkHb4LUWuI,19661
40
+ hindsight_api/engine/search/scoring.py,sha256=feFPalpbIMndp8j2Ab0zvu7fRq3c43Wmzrjw3piQ0eM,5167
41
+ hindsight_api/engine/search/temporal_extraction.py,sha256=5klrZdza3mkgk5A15_m_j4IIfOHMc6fUR9UJuzLa790,1812
42
+ hindsight_api/engine/search/think_utils.py,sha256=VJJXFmBg03yO4Mg--UBMlTQW9IZOj2eyTZztjzhT8F8,11315
43
+ hindsight_api/engine/search/trace.py,sha256=Hx-siW9yAfqZoK9LG6esbed0vQuHMNsGxSvCg4FK6-4,11042
44
+ hindsight_api/engine/search/tracer.py,sha256=mcM9qZpj3YFudrBCESwc6YKNAiWIMx1lScXWn5ru-ok,15017
45
+ hindsight_api/engine/search/types.py,sha256=qIeHW_gT7f291vteTZXygAM8oAaPp2dq6uEdvOyOwzs,5488
46
+ hindsight_api/web/__init__.py,sha256=WABqyqiAVFJJWOhKCytkj5Vcb61eAsRib3Ek7IMX6_U,378
47
+ hindsight_api/web/server.py,sha256=l-Tw8G9IRdcSay-KWiUT4VlIJBzxbe-TV0rjX0fwLMc,4464
48
+ hindsight_api-0.1.0.dist-info/METADATA,sha256=7KQUZY0Kcdl83K9zVA4gPVJAMOy12IxL7sr0PjI9EKs,1466
49
+ hindsight_api-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
50
+ hindsight_api-0.1.0.dist-info/entry_points.txt,sha256=53Fn-VxtkqreZhOPTJB_FupH7e5GyiMY3gzEp22d8xs,57
51
+ hindsight_api-0.1.0.dist-info/RECORD,,
@@ -1,50 +0,0 @@
1
- hindsight_api/__init__.py,sha256=yQWYWUWEhvs1OY1coENhZV_CuOAWmN_YKZXQMIvGN94,851
2
- hindsight_api/cli.py,sha256=-dxAHsET_pHd6NlA3ufI4KEKQA3fL3YapCvDB_x2ax8,3303
3
- hindsight_api/metrics.py,sha256=j4-eeqVjjcGQxAxS_GgEaBNm10KdUxrGS_I2d1IM1hY,7255
4
- hindsight_api/migrations.py,sha256=VY-ILJLWEY1IaeJgQ2jlAVUtPLzq_41Dytg_DjuF0GA,6402
5
- hindsight_api/models.py,sha256=euUSdFEVgpH4aXumGtydjfXpY_YPlkeV3i9_A2thIuk,12610
6
- hindsight_api/pg0.py,sha256=scFcYngOwbZ2oOQb7TysnUHgNgPyiN30pjPcIqMDmao,14158
7
- hindsight_api/api/__init__.py,sha256=Ih1BKXK5MW75lyyFAyU1JKU7eZYj4kp5UG175pGVYCM,3017
8
- hindsight_api/api/http.py,sha256=wl9O6TCHe6tgx48MZD9BfJmIuthWvTj1-UECs0OIz8M,71628
9
- hindsight_api/api/mcp.py,sha256=lxgPEvTsfsftd2f3qhFvfk4iuDa_sIxmerjtYv6nxJI,7740
10
- hindsight_api/engine/__init__.py,sha256=5DU5DvnJdzkrgNgKchpzkiJr-37I-kE1tegJg2LF04k,1214
11
- hindsight_api/engine/cross_encoder.py,sha256=kfwLiqlQUfvOgLyrkRReO1wWlO020lGbLXY8U0jKiPA,2875
12
- hindsight_api/engine/db_utils.py,sha256=p1Ne70wPP327xdPI_XjMfnagilY8sknbkhEIZuED6DU,2724
13
- hindsight_api/engine/embeddings.py,sha256=a0wox2SCIE7ezgy-B5_23Cp1_icYiUR3g06hPpzi_ck,3586
14
- hindsight_api/engine/entity_resolver.py,sha256=y_KWDkWaJwKluhGgJYAr_Amg4GTzyJAnrmRKnsyevsk,21737
15
- hindsight_api/engine/llm_wrapper.py,sha256=NkoE3ZkW9yPExj-8o9YjUyp93Ko74PEi7qtglIBupGs,17103
16
- hindsight_api/engine/memory_engine.py,sha256=ke8sdyoVjlN0_xF_b0Myzwwd4D0isHDyS043rdGL__w,128225
17
- hindsight_api/engine/query_analyzer.py,sha256=K0QCg7tsbqtwC7TR5wt3FPoP8QDuZsX9r0Zljc8nnYo,19733
18
- hindsight_api/engine/response_models.py,sha256=6Qm3-kCtaFC_YlCtZSj46mWqTBbNM1l8nOxXO1al9q8,8799
19
- hindsight_api/engine/task_backend.py,sha256=ojxMC9PeHdnkWVs2ozeqycjI_1mmpkDa0_Qfej9AHrg,7287
20
- hindsight_api/engine/utils.py,sha256=VAjpZSbdiwhlE6cDlYfTt_-5hIJ--0xtfixETK0LPSk,6910
21
- hindsight_api/engine/retain/__init__.py,sha256=L_QuR1YLHsJ7OCmVFNsZe8WDjbsTTHL-wCiUXtw1aUE,1230
22
- hindsight_api/engine/retain/bank_utils.py,sha256=anEF5I6rX_jQRe58EiSyHgRMzSRYNodGp-a2lvivei8,14482
23
- hindsight_api/engine/retain/chunk_storage.py,sha256=rjmfnllS185tmjJGkMjWZ9q_6hJO4N6Ll9jgPx6f5xo,2081
24
- hindsight_api/engine/retain/deduplication.py,sha256=9YXgVI_m1Mtz5Cv46ZceCEs0GwpLqTPHrZ-vlWlXk6I,3313
25
- hindsight_api/engine/retain/embedding_processing.py,sha256=cHTt3rPvDCWBWVPfSeg6bwH8HoXYGmP4bvS21boNONI,1734
26
- hindsight_api/engine/retain/embedding_utils.py,sha256=Q24h_iw6pRAW2vDWPvauWY1o3bXLzW3eWvSxDALDiE0,1588
27
- hindsight_api/engine/retain/entity_processing.py,sha256=meHOjsFzdvh1tbe6YlTofhcUs2Y6TcAN3S-0EKOvFP0,2705
28
- hindsight_api/engine/retain/fact_extraction.py,sha256=vMDDtGCoT9-nfAvLJXy0VIB_-EVlMv6hy_pXMIkCXcY,46171
29
- hindsight_api/engine/retain/fact_storage.py,sha256=07YoLYoH2QsoqrPUhMMFF3ThrLRnJKOkDoWTgrIJmK4,5717
30
- hindsight_api/engine/retain/link_creation.py,sha256=XJx7U3HboJLHtGgt_tHGsCa58lGo2ZyywzMNosrY9Xc,3154
31
- hindsight_api/engine/retain/link_utils.py,sha256=KkPE0TixurCacfpeAAm_HC8Pva4ZsQBkPPSz90uaq8Y,29924
32
- hindsight_api/engine/retain/orchestrator.py,sha256=I-EVH2REQLE3CypvWjcB9iZoJcl6dhXo3QPJMeWUz_4,17524
33
- hindsight_api/engine/retain/types.py,sha256=zUEQqZty1UQH76shmkaG9kjr4rlrmwKc65E2vmoOZAw,6224
34
- hindsight_api/engine/search/__init__.py,sha256=7X6U10bVw0JRWxQdE5RCfVpawDlSUldi1mPoCzY0V0A,363
35
- hindsight_api/engine/search/fusion.py,sha256=so6LU7kWRR-VJd1Pxlu8idRJ7P2WLCoDwXUnb8jQifo,4309
36
- hindsight_api/engine/search/observation_utils.py,sha256=SPrDx6M0daJ_zLLkk78GlQIG3EL7DqMKSu_etKerUfU,4331
37
- hindsight_api/engine/search/reranking.py,sha256=Bk5i5kal5yy4CM8m2uSxAumLPgLeHdncBX6wk4WTmEI,3525
38
- hindsight_api/engine/search/retrieval.py,sha256=kfQTU34LPLgB1QVcCAv7v2IPhOB2ag68xJ8RzvdSP10,19661
39
- hindsight_api/engine/search/scoring.py,sha256=feFPalpbIMndp8j2Ab0zvu7fRq3c43Wmzrjw3piQ0eM,5167
40
- hindsight_api/engine/search/temporal_extraction.py,sha256=5klrZdza3mkgk5A15_m_j4IIfOHMc6fUR9UJuzLa790,1812
41
- hindsight_api/engine/search/think_utils.py,sha256=KgWt8aasC-oQfKXnm5kZamIk5zrGUYH_2-3ExAmw4vU,9629
42
- hindsight_api/engine/search/trace.py,sha256=Hx-siW9yAfqZoK9LG6esbed0vQuHMNsGxSvCg4FK6-4,11042
43
- hindsight_api/engine/search/tracer.py,sha256=mcM9qZpj3YFudrBCESwc6YKNAiWIMx1lScXWn5ru-ok,15017
44
- hindsight_api/engine/search/types.py,sha256=qIeHW_gT7f291vteTZXygAM8oAaPp2dq6uEdvOyOwzs,5488
45
- hindsight_api/web/__init__.py,sha256=WABqyqiAVFJJWOhKCytkj5Vcb61eAsRib3Ek7IMX6_U,378
46
- hindsight_api/web/server.py,sha256=l-Tw8G9IRdcSay-KWiUT4VlIJBzxbe-TV0rjX0fwLMc,4464
47
- hindsight_api-0.0.21.dist-info/METADATA,sha256=cbvXe_7S66Lcw8krbS7Vh7rfKV1naljnMKVj9W8Nao0,1531
48
- hindsight_api-0.0.21.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
49
- hindsight_api-0.0.21.dist-info/entry_points.txt,sha256=53Fn-VxtkqreZhOPTJB_FupH7e5GyiMY3gzEp22d8xs,57
50
- hindsight_api-0.0.21.dist-info/RECORD,,