hindsight-api 0.1.4__py3-none-any.whl → 0.1.6__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.
Files changed (63) hide show
  1. hindsight_api/__init__.py +10 -9
  2. hindsight_api/alembic/env.py +5 -8
  3. hindsight_api/alembic/versions/5a366d414dce_initial_schema.py +266 -180
  4. hindsight_api/alembic/versions/b7c4d8e9f1a2_add_chunks_table.py +32 -32
  5. hindsight_api/alembic/versions/c8e5f2a3b4d1_add_retain_params_to_documents.py +11 -11
  6. hindsight_api/alembic/versions/d9f6a3b4c5e2_rename_bank_to_interactions.py +7 -12
  7. hindsight_api/alembic/versions/e0a1b2c3d4e5_disposition_to_3_traits.py +23 -15
  8. hindsight_api/alembic/versions/rename_personality_to_disposition.py +30 -21
  9. hindsight_api/api/__init__.py +10 -10
  10. hindsight_api/api/http.py +575 -593
  11. hindsight_api/api/mcp.py +31 -33
  12. hindsight_api/banner.py +13 -6
  13. hindsight_api/config.py +17 -12
  14. hindsight_api/engine/__init__.py +9 -9
  15. hindsight_api/engine/cross_encoder.py +23 -27
  16. hindsight_api/engine/db_utils.py +5 -4
  17. hindsight_api/engine/embeddings.py +22 -21
  18. hindsight_api/engine/entity_resolver.py +81 -75
  19. hindsight_api/engine/llm_wrapper.py +74 -88
  20. hindsight_api/engine/memory_engine.py +663 -673
  21. hindsight_api/engine/query_analyzer.py +100 -97
  22. hindsight_api/engine/response_models.py +105 -106
  23. hindsight_api/engine/retain/__init__.py +9 -16
  24. hindsight_api/engine/retain/bank_utils.py +34 -58
  25. hindsight_api/engine/retain/chunk_storage.py +4 -12
  26. hindsight_api/engine/retain/deduplication.py +9 -28
  27. hindsight_api/engine/retain/embedding_processing.py +4 -11
  28. hindsight_api/engine/retain/embedding_utils.py +3 -4
  29. hindsight_api/engine/retain/entity_processing.py +7 -17
  30. hindsight_api/engine/retain/fact_extraction.py +155 -165
  31. hindsight_api/engine/retain/fact_storage.py +11 -23
  32. hindsight_api/engine/retain/link_creation.py +11 -39
  33. hindsight_api/engine/retain/link_utils.py +166 -95
  34. hindsight_api/engine/retain/observation_regeneration.py +39 -52
  35. hindsight_api/engine/retain/orchestrator.py +72 -62
  36. hindsight_api/engine/retain/types.py +49 -43
  37. hindsight_api/engine/search/__init__.py +15 -1
  38. hindsight_api/engine/search/fusion.py +6 -15
  39. hindsight_api/engine/search/graph_retrieval.py +234 -0
  40. hindsight_api/engine/search/mpfp_retrieval.py +438 -0
  41. hindsight_api/engine/search/observation_utils.py +9 -16
  42. hindsight_api/engine/search/reranking.py +4 -7
  43. hindsight_api/engine/search/retrieval.py +388 -193
  44. hindsight_api/engine/search/scoring.py +5 -7
  45. hindsight_api/engine/search/temporal_extraction.py +8 -11
  46. hindsight_api/engine/search/think_utils.py +115 -39
  47. hindsight_api/engine/search/trace.py +68 -38
  48. hindsight_api/engine/search/tracer.py +49 -35
  49. hindsight_api/engine/search/types.py +22 -16
  50. hindsight_api/engine/task_backend.py +21 -26
  51. hindsight_api/engine/utils.py +25 -10
  52. hindsight_api/main.py +21 -40
  53. hindsight_api/mcp_local.py +190 -0
  54. hindsight_api/metrics.py +44 -30
  55. hindsight_api/migrations.py +10 -8
  56. hindsight_api/models.py +60 -72
  57. hindsight_api/pg0.py +64 -337
  58. hindsight_api/server.py +3 -6
  59. {hindsight_api-0.1.4.dist-info → hindsight_api-0.1.6.dist-info}/METADATA +6 -5
  60. hindsight_api-0.1.6.dist-info/RECORD +64 -0
  61. {hindsight_api-0.1.4.dist-info → hindsight_api-0.1.6.dist-info}/entry_points.txt +1 -0
  62. hindsight_api-0.1.4.dist-info/RECORD +0 -61
  63. {hindsight_api-0.1.4.dist-info → hindsight_api-0.1.6.dist-info}/WHEEL +0 -0
hindsight_api/pg0.py CHANGED
@@ -1,407 +1,134 @@
1
1
  import asyncio
2
- import json
3
2
  import logging
4
- import os
5
- import platform
6
- import re
7
- import shutil
8
- import stat
9
- import subprocess
10
- from pathlib import Path
11
- from typing import Optional
12
3
 
13
- import httpx
4
+ from pg0 import Pg0
14
5
 
15
6
  logger = logging.getLogger(__name__)
16
7
 
17
- # pg0 configuration
18
- BINARY_NAME = "pg0"
19
- DEFAULT_PORT = 5555
20
8
  DEFAULT_USERNAME = "hindsight"
21
9
  DEFAULT_PASSWORD = "hindsight"
22
10
  DEFAULT_DATABASE = "hindsight"
23
11
 
24
12
 
25
- def get_platform_binary_name() -> str:
26
- """Get the appropriate binary name for the current platform.
27
-
28
- Supported platforms:
29
- - macOS ARM64 (darwin-aarch64)
30
- - Linux x86_64 (gnu)
31
- - Linux ARM64 (gnu)
32
- - Windows x86_64
33
- """
34
- system = platform.system().lower()
35
- machine = platform.machine().lower()
36
-
37
- # Normalize architecture names
38
- if machine in ("x86_64", "amd64"):
39
- arch = "x86_64"
40
- elif machine in ("arm64", "aarch64"):
41
- arch = "aarch64"
42
- else:
43
- raise RuntimeError(
44
- f"Embedded PostgreSQL is not supported on architecture: {machine}. "
45
- f"Supported architectures: x86_64/amd64 (Linux, Windows), aarch64/arm64 (macOS, Linux)"
46
- )
47
-
48
- if system == "darwin" and arch == "aarch64":
49
- return "pg0-darwin-aarch64"
50
- elif system == "linux" and arch == "x86_64":
51
- return "pg0-linux-x86_64-gnu"
52
- elif system == "linux" and arch == "aarch64":
53
- return "pg0-linux-aarch64-gnu"
54
- elif system == "windows" and arch == "x86_64":
55
- return "pg0-windows-x86_64.exe"
56
- else:
57
- raise RuntimeError(
58
- f"Embedded PostgreSQL is not supported on {system}-{arch}. "
59
- f"Supported platforms: darwin-aarch64 (macOS ARM), linux-x86_64-gnu, linux-aarch64-gnu, windows-x86_64"
60
- )
61
-
62
-
63
- def get_download_url(
64
- version: str = "latest",
65
- repo: str = "vectorize-io/pg0",
66
- ) -> str:
67
- """Get the download URL for pg0 binary."""
68
- binary_name = get_platform_binary_name()
69
-
70
- if version == "latest":
71
- return f"https://github.com/{repo}/releases/latest/download/{binary_name}"
72
- else:
73
- return f"https://github.com/{repo}/releases/download/{version}/{binary_name}"
74
-
75
-
76
- def _find_pg0_binary() -> Optional[Path]:
77
- """Find pg0 binary in PATH or default install location."""
78
- # First check PATH
79
- pg0_in_path = shutil.which("pg0")
80
- if pg0_in_path:
81
- return Path(pg0_in_path)
82
-
83
- # Fall back to default install location
84
- default_path = Path.home() / ".hindsight" / "bin" / "pg0"
85
- if default_path.exists() and os.access(default_path, os.X_OK):
86
- return default_path
87
-
88
- return None
89
-
90
-
91
13
  class EmbeddedPostgres:
92
- """
93
- Manages an embedded PostgreSQL server instance using pg0.
94
-
95
- This class handles:
96
- - Finding or downloading the pg0 CLI
97
- - Starting/stopping the PostgreSQL server
98
- - Getting the connection URI
99
-
100
- Example:
101
- pg = EmbeddedPostgres()
102
- await pg.ensure_installed()
103
- await pg.start()
104
- uri = await pg.get_uri()
105
- # ... use uri with asyncpg ...
106
- await pg.stop()
107
- """
14
+ """Manages an embedded PostgreSQL server instance using pg0-embedded."""
108
15
 
109
16
  def __init__(
110
17
  self,
111
- version: str = "latest",
112
- port: int = DEFAULT_PORT,
18
+ port: int | None = None,
113
19
  username: str = DEFAULT_USERNAME,
114
20
  password: str = DEFAULT_PASSWORD,
115
21
  database: str = DEFAULT_DATABASE,
116
22
  name: str = "hindsight",
23
+ **kwargs,
117
24
  ):
118
- """
119
- Initialize the embedded PostgreSQL manager.
120
-
121
- Args:
122
- version: Version of pg0 to download if not found. Defaults to "latest"
123
- port: Port to listen on. Defaults to 5555
124
- username: Username for the database. Defaults to "hindsight"
125
- password: Password for the database. Defaults to "hindsight"
126
- database: Database name to create. Defaults to "hindsight"
127
- name: Instance name for pg0. Defaults to "hindsight"
128
- """
129
- self.version = version
130
- self.port = port
25
+ self.port = port # None means pg0 will auto-assign
131
26
  self.username = username
132
27
  self.password = password
133
28
  self.database = database
134
29
  self.name = name
135
-
136
- # Will be set when binary is found/installed
137
- self._binary_path: Optional[Path] = _find_pg0_binary()
138
-
139
- @property
140
- def binary_path(self) -> Path:
141
- """Get the path to the pg0 binary."""
142
- if self._binary_path is None:
143
- # Default install location
144
- return Path.home() / ".hindsight" / "bin" / "pg0"
145
- return self._binary_path
146
-
147
- def is_installed(self) -> bool:
148
- """Check if pg0 is available (in PATH or installed)."""
149
- self._binary_path = _find_pg0_binary()
150
- return self._binary_path is not None
151
-
152
- async def ensure_installed(self) -> None:
153
- """
154
- Ensure pg0 is available.
155
-
156
- Checks PATH and default location. If not found, raises an error
157
- instructing the user to install pg0 manually.
158
- """
159
- if self.is_installed():
160
- logger.debug(f"pg0 found at {self._binary_path}")
161
- return
162
-
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
- )
168
-
169
- def _run_command(self, *args: str, capture_output: bool = True) -> subprocess.CompletedProcess:
170
- """Run a pg0 command synchronously."""
171
- cmd = [str(self.binary_path), *args]
172
- return subprocess.run(cmd, capture_output=capture_output, text=True)
173
-
174
- async def _run_command_async(self, *args: str, timeout: int = 120) -> tuple[int, str, str]:
175
- """Run a pg0 command asynchronously."""
176
- cmd = [str(self.binary_path), *args]
177
-
178
- def run_sync():
179
- try:
180
- result = subprocess.run(
181
- cmd,
182
- stdin=subprocess.DEVNULL,
183
- stdout=subprocess.PIPE,
184
- stderr=subprocess.PIPE,
185
- text=True,
186
- timeout=timeout,
187
- )
188
- return result.returncode, result.stdout, result.stderr
189
- except subprocess.TimeoutExpired:
190
- return 1, "", "Command timed out"
191
-
192
- loop = asyncio.get_event_loop()
193
- return await loop.run_in_executor(None, run_sync)
194
-
195
- def _extract_uri_from_output(self, output: str) -> Optional[str]:
196
- """Extract the PostgreSQL URI from pg0 start output."""
197
- match = re.search(r"Connection URI:\s*(postgresql://[^\s]+)", output)
198
- if match:
199
- return match.group(1)
200
- return None
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
-
209
- async def start(self, max_retries: int = 3, retry_delay: float = 2.0) -> str:
210
- """
211
- Start the PostgreSQL server with retry logic.
212
-
213
- Args:
214
- max_retries: Maximum number of start attempts (default: 3)
215
- retry_delay: Initial delay between retries in seconds (default: 2.0)
216
-
217
- Returns:
218
- The connection URI for the started server.
219
-
220
- Raises:
221
- RuntimeError: If the server fails to start after all retries.
222
- """
223
- if not self.is_installed():
224
- raise RuntimeError("pg0 is not installed. Call ensure_installed() first.")
225
-
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})...")
229
-
30
+ self._pg0: Pg0 | None = None
31
+
32
+ def _get_pg0(self) -> Pg0:
33
+ if self._pg0 is None:
34
+ kwargs = {
35
+ "name": self.name,
36
+ "username": self.username,
37
+ "password": self.password,
38
+ "database": self.database,
39
+ }
40
+ # Only set port if explicitly specified
41
+ if self.port is not None:
42
+ kwargs["port"] = self.port
43
+ self._pg0 = Pg0(**kwargs)
44
+ return self._pg0
45
+
46
+ async def start(self, max_retries: int = 5, retry_delay: float = 4.0) -> str:
47
+ """Start the PostgreSQL server with retry logic."""
48
+ port_info = f"port={self.port}" if self.port else "port=auto"
49
+ logger.info(f"Starting embedded PostgreSQL (name={self.name}, {port_info})...")
50
+
51
+ pg0 = self._get_pg0()
230
52
  last_error = None
231
- for attempt in range(1, max_retries + 1):
232
- returncode, stdout, stderr = await self._run_command_async(
233
- "start",
234
- "--name", self.name,
235
- "--port", str(self.port),
236
- "--username", self.username,
237
- "--password", self.password,
238
- "--database", self.database,
239
- timeout=300,
240
- )
241
53
 
242
- # Try to extract URI from output
243
- uri = self._extract_uri_from_output(stdout)
244
- if uri:
245
- logger.info(f"PostgreSQL started on port {self.port}")
246
- return uri
247
-
248
- # Check if pg0 info can find the running instance
54
+ for attempt in range(1, max_retries + 1):
249
55
  try:
250
- uri = await self.get_uri()
251
- logger.info(f"PostgreSQL started on port {self.port}")
56
+ loop = asyncio.get_event_loop()
57
+ info = await loop.run_in_executor(None, pg0.start)
58
+ # Get URI from pg0 (includes auto-assigned port)
59
+ uri = info.uri
60
+ logger.info(f"PostgreSQL started: {uri}")
252
61
  return uri
253
- except RuntimeError:
254
- pass
62
+ except Exception as e:
63
+ last_error = str(e)
64
+ if attempt < max_retries:
65
+ delay = retry_delay * (2 ** (attempt - 1))
66
+ logger.debug(f"pg0 start attempt {attempt}/{max_retries} failed: {last_error}")
67
+ logger.debug(f"Retrying in {delay:.1f}s...")
68
+ await asyncio.sleep(delay)
69
+ else:
70
+ logger.debug(f"pg0 start attempt {attempt}/{max_retries} failed: {last_error}")
255
71
 
256
- # Start failed, log and retry
257
- last_error = stderr or f"pg0 start returned exit code {returncode}"
258
- if attempt < max_retries:
259
- delay = retry_delay * (2 ** (attempt - 1))
260
- logger.debug(f"pg0 start attempt {attempt}/{max_retries} failed: {last_error.strip()}")
261
- logger.debug(f"Retrying in {delay:.1f}s...")
262
- await asyncio.sleep(delay)
263
- else:
264
- logger.debug(f"pg0 start attempt {attempt}/{max_retries} failed: {last_error.strip()}")
265
-
266
- # All retries exhausted - fail
267
72
  raise RuntimeError(
268
- f"Failed to start embedded PostgreSQL after {max_retries} attempts. "
269
- f"Last error: {last_error.strip() if last_error else 'unknown'}"
73
+ f"Failed to start embedded PostgreSQL after {max_retries} attempts. Last error: {last_error}"
270
74
  )
271
75
 
272
76
  async def stop(self) -> None:
273
77
  """Stop the PostgreSQL server."""
274
- if not self.is_installed():
275
- return
276
-
78
+ pg0 = self._get_pg0()
277
79
  logger.info(f"Stopping embedded PostgreSQL (name: {self.name})...")
278
80
 
279
- returncode, stdout, stderr = await self._run_command_async("stop", "--name", self.name)
280
-
281
- if returncode != 0:
282
- if "not running" in stderr.lower():
283
- return
284
- raise RuntimeError(f"Failed to stop PostgreSQL: {stderr}")
285
-
286
- logger.info("Embedded PostgreSQL stopped")
287
-
288
- async def _get_info(self) -> dict:
289
- """Get info from pg0 using the `info -o json` command."""
290
- if not self.is_installed():
291
- raise RuntimeError("pg0 is not installed.")
292
-
293
- returncode, stdout, stderr = await self._run_command_async(
294
- "info", "--name", self.name, "-o", "json"
295
- )
296
-
297
- if returncode != 0:
298
- raise RuntimeError(f"Failed to get PostgreSQL info: {stderr}")
299
-
300
81
  try:
301
- return json.loads(stdout.strip())
302
- except json.JSONDecodeError as e:
303
- raise RuntimeError(f"Failed to parse pg0 info output: {e}")
82
+ loop = asyncio.get_event_loop()
83
+ await loop.run_in_executor(None, pg0.stop)
84
+ logger.info("Embedded PostgreSQL stopped")
85
+ except Exception as e:
86
+ if "not running" in str(e).lower():
87
+ return
88
+ raise RuntimeError(f"Failed to stop PostgreSQL: {e}")
304
89
 
305
90
  async def get_uri(self) -> str:
306
91
  """Get the connection URI for the PostgreSQL server."""
307
- info = await self._get_info()
308
- uri = info.get("uri")
309
- if not uri:
310
- raise RuntimeError("PostgreSQL server is not running or URI not available")
311
- return uri
312
-
313
- async def status(self) -> dict:
314
- """Get the status of the PostgreSQL server."""
315
- if not self.is_installed():
316
- return {"installed": False, "running": False}
317
-
318
- try:
319
- info = await self._get_info()
320
- return {
321
- "installed": True,
322
- "running": info.get("running", False),
323
- "uri": info.get("uri"),
324
- }
325
- except RuntimeError:
326
- return {"installed": True, "running": False}
92
+ pg0 = self._get_pg0()
93
+ loop = asyncio.get_event_loop()
94
+ info = await loop.run_in_executor(None, pg0.info)
95
+ return info.uri
327
96
 
328
97
  async def is_running(self) -> bool:
329
98
  """Check if the PostgreSQL server is currently running."""
330
- if not self.is_installed():
331
- return False
332
99
  try:
333
- info = await self._get_info()
334
- return info.get("running", False)
335
- except RuntimeError:
100
+ pg0 = self._get_pg0()
101
+ loop = asyncio.get_event_loop()
102
+ info = await loop.run_in_executor(None, pg0.info)
103
+ return info is not None and info.running
104
+ except Exception:
336
105
  return False
337
106
 
338
107
  async def ensure_running(self) -> str:
339
- """
340
- Ensure the PostgreSQL server is running.
341
-
342
- Installs if needed, starts if not running.
343
-
344
- Returns:
345
- The connection URI.
346
- """
347
- await self.ensure_installed()
348
-
108
+ """Ensure the PostgreSQL server is running, starting it if needed."""
349
109
  if await self.is_running():
350
110
  return await self.get_uri()
351
-
352
111
  return await self.start()
353
112
 
354
- def uninstall(self) -> None:
355
- """Remove the pg0 binary (only if we installed it)."""
356
- default_path = Path.home() / ".hindsight" / "bin" / "pg0"
357
- if default_path.exists():
358
- default_path.unlink()
359
- logger.info(f"Removed {default_path}")
360
113
 
361
- def clear_data(self) -> None:
362
- """Remove all PostgreSQL data (destructive!)."""
363
- result = self._run_command("drop", "--name", self.name, "--force")
364
- if result.returncode == 0:
365
- logger.info(f"Dropped pg0 instance {self.name}")
366
- else:
367
- logger.warning(f"Failed to drop pg0 instance {self.name}: {result.stderr}")
368
-
369
-
370
- # Convenience functions
371
-
372
- _default_instance: Optional[EmbeddedPostgres] = None
114
+ _default_instance: EmbeddedPostgres | None = None
373
115
 
374
116
 
375
117
  def get_embedded_postgres() -> EmbeddedPostgres:
376
118
  """Get or create the default EmbeddedPostgres instance."""
377
119
  global _default_instance
378
-
379
120
  if _default_instance is None:
380
121
  _default_instance = EmbeddedPostgres()
381
-
382
122
  return _default_instance
383
123
 
384
124
 
385
125
  async def start_embedded_postgres() -> str:
386
- """
387
- Quick start function for embedded PostgreSQL.
388
-
389
- Downloads, installs, and starts PostgreSQL in one call.
390
-
391
- Returns:
392
- Connection URI string
393
-
394
- Example:
395
- db_url = await start_embedded_postgres()
396
- conn = await asyncpg.connect(db_url)
397
- """
398
- pg = get_embedded_postgres()
399
- return await pg.ensure_running()
126
+ """Quick start function for embedded PostgreSQL."""
127
+ return await get_embedded_postgres().ensure_running()
400
128
 
401
129
 
402
130
  async def stop_embedded_postgres() -> None:
403
131
  """Stop the default embedded PostgreSQL instance."""
404
132
  global _default_instance
405
-
406
133
  if _default_instance:
407
134
  await _default_instance.stop()
hindsight_api/server.py CHANGED
@@ -6,6 +6,7 @@ This module provides the ASGI app for uvicorn import string usage:
6
6
 
7
7
  For CLI usage, use the hindsight-api command instead.
8
8
  """
9
+
9
10
  import os
10
11
  import warnings
11
12
 
@@ -29,15 +30,11 @@ config.configure_logging()
29
30
  _memory = MemoryEngine()
30
31
 
31
32
  # Create unified app with both HTTP and optionally MCP
32
- app = create_app(
33
- memory=_memory,
34
- http_api_enabled=True,
35
- mcp_api_enabled=config.mcp_enabled,
36
- mcp_mount_path="/mcp"
37
- )
33
+ app = create_app(memory=_memory, http_api_enabled=True, mcp_api_enabled=config.mcp_enabled, mcp_mount_path="/mcp")
38
34
 
39
35
 
40
36
  if __name__ == "__main__":
41
37
  # When run directly, delegate to the CLI
42
38
  from hindsight_api.main import main
39
+
43
40
  main()
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hindsight-api
3
- Version: 0.1.4
3
+ Version: 0.1.6
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
7
7
  Requires-Dist: asyncpg>=0.29.0
8
8
  Requires-Dist: dateparser>=1.2.2
9
9
  Requires-Dist: fastapi[standard]>=0.120.3
10
- Requires-Dist: fastmcp>=2.0.0
10
+ Requires-Dist: fastmcp>=2.3.0
11
11
  Requires-Dist: google-genai>=1.0.0
12
12
  Requires-Dist: greenlet>=3.2.4
13
13
  Requires-Dist: httpx>=0.27.0
@@ -17,17 +17,18 @@ Requires-Dist: opentelemetry-api>=1.20.0
17
17
  Requires-Dist: opentelemetry-exporter-prometheus>=0.41b0
18
18
  Requires-Dist: opentelemetry-instrumentation-fastapi>=0.41b0
19
19
  Requires-Dist: opentelemetry-sdk>=1.20.0
20
+ Requires-Dist: pg0-embedded>=0.11.0
20
21
  Requires-Dist: pgvector>=0.4.1
21
22
  Requires-Dist: psycopg2-binary>=2.9.11
22
23
  Requires-Dist: pydantic>=2.0.0
23
24
  Requires-Dist: python-dateutil>=2.8.0
24
25
  Requires-Dist: python-dotenv>=1.0.0
25
26
  Requires-Dist: rich>=13.0.0
26
- Requires-Dist: sentence-transformers>=3.0.0
27
+ Requires-Dist: sentence-transformers<3.3.0,>=3.0.0
27
28
  Requires-Dist: sqlalchemy>=2.0.44
28
29
  Requires-Dist: tiktoken>=0.12.0
29
- Requires-Dist: torch>=2.0.0
30
- Requires-Dist: transformers>=4.30.0
30
+ Requires-Dist: torch<2.6.0,>=2.0.0
31
+ Requires-Dist: transformers<4.46.0,>=4.30.0
31
32
  Requires-Dist: uvicorn>=0.38.0
32
33
  Requires-Dist: wsproto>=1.0.0
33
34
  Provides-Extra: test
@@ -0,0 +1,64 @@
1
+ hindsight_api/__init__.py,sha256=paLZxYov7BBgbOSl1RTNtFYvqHXlZTzTEDygR3kAFLc,1140
2
+ hindsight_api/banner.py,sha256=BXn-jhkXe4xi-YV4JeuaVvjYhTMs96O43XoOMv4Cd28,4591
3
+ hindsight_api/config.py,sha256=qxdxmeQWJozKIjMUe-Aza9hGIgT34HxMnXs0gh3uXXs,5538
4
+ hindsight_api/main.py,sha256=TO5zLzXpu-CjGfvLHdZFEHerrJbNns2cQGlc4gofaPI,5970
5
+ hindsight_api/mcp_local.py,sha256=ozKMv-PrehzZTLawscP-TDePwqiOH962HCQzTa9x8AY,6646
6
+ hindsight_api/metrics.py,sha256=sQI5MhC2xj9ONZ6Hdjf6r6r3NbYYd3ExyVOn1Uky49A,7239
7
+ hindsight_api/migrations.py,sha256=bN9ejR3cn7EAP3LFkpAjnWsUm9kykgzbzqeCB9HMPvA,7315
8
+ hindsight_api/models.py,sha256=vLFkxykmK8KOoN_sQz4SsiJS6vqOjFIv_82BuKg8qD8,12329
9
+ hindsight_api/pg0.py,sha256=y8EE3v1q2OUJbsSHl-hG_sPZEIWQrgkxrGcf-kuEECE,4624
10
+ hindsight_api/server.py,sha256=OrSd0G-79U07EXFc838c1vzUL-1O6wuxTMqUmMINpGY,1247
11
+ hindsight_api/alembic/README,sha256=MVlc9TYmr57RbhXET6QxgyCcwWP7w-vLkEsirENqiIQ,38
12
+ hindsight_api/alembic/env.py,sha256=x5MoBxdfRunSve1zARCOZ8KZDg2M3-NYrjJsR1hePg4,4753
13
+ hindsight_api/alembic/script.py.mako,sha256=04kgeBtNMa4cCnG8CfQcKt6P6rnloIfj8wy0u_DBydM,704
14
+ hindsight_api/alembic/versions/5a366d414dce_initial_schema.py,sha256=g3G7fV70Z10PZxwTrTmR34OAlEZjQTLJKr-Ol54JqrQ,17665
15
+ hindsight_api/alembic/versions/b7c4d8e9f1a2_add_chunks_table.py,sha256=MaHFU4JczUIFLeUMBTKIV3ocuclil55N9fPPim-HRfk,2599
16
+ hindsight_api/alembic/versions/c8e5f2a3b4d1_add_retain_params_to_documents.py,sha256=ChqkHANauZb4-nBt2uepoZN3q0vRzN6aRsWTGueULiA,1146
17
+ hindsight_api/alembic/versions/d9f6a3b4c5e2_rename_bank_to_interactions.py,sha256=28KBE6mAAj2PEXm0iALJOiMcjn4eTx_X5nUPaJ1aRYk,1480
18
+ hindsight_api/alembic/versions/e0a1b2c3d4e5_disposition_to_3_traits.py,sha256=LLj0Tl6Kjw5uZPo7lCcG2IH8lFSPEmc9jG_riMF3Bj0,2370
19
+ hindsight_api/alembic/versions/rename_personality_to_disposition.py,sha256=gpMSG8hdvqn9__lGgS0EE2de1nki1YAaCEI3pDdJRzA,2281
20
+ hindsight_api/api/__init__.py,sha256=zoDWA86ttx-UriC35UIgdPswIrau7GuMWTN63wYsUdM,2916
21
+ hindsight_api/api/http.py,sha256=eYVnsQwx5LW3MvdcAQjiLw6WwBobw5aGeYSPYLIFllE,70922
22
+ hindsight_api/api/mcp.py,sha256=I9C_jUz6d7efMstBfOyoqnnsB94JU6c2mMk6eQ_KDz0,7462
23
+ hindsight_api/engine/__init__.py,sha256=z6srTnyvGQM0eya7E8r2yagTAc4C7IhHauUK8NM-gW8,1406
24
+ hindsight_api/engine/cross_encoder.py,sha256=5WmUx9yfJdIwZ0nA218O-mMKQJ7EKaPOtwhMiDbG8KQ,10483
25
+ hindsight_api/engine/db_utils.py,sha256=0T5tL2SZ49JQihfyZYlTDThIfocKzkr1OpxQpJzPCGE,2687
26
+ hindsight_api/engine/embeddings.py,sha256=IEdP5-p6oTJRRKV2JzUEojByJGShUEmkInCyA9wM8tg,10219
27
+ hindsight_api/engine/entity_resolver.py,sha256=XHAViwIaEXMUhp9Eifvx0b3MZ4QwiFvH_k_ZHTwczxE,23151
28
+ hindsight_api/engine/llm_wrapper.py,sha256=-EQnDoMr4BHTcp24dGNiOnYVGA5uGYmGFT5qQHhxGwY,21134
29
+ hindsight_api/engine/memory_engine.py,sha256=l6NeQ_xHj8YfOs6Jpr6k6nYCUFRpZYIYZgf8H6JB7U8,135992
30
+ hindsight_api/engine/query_analyzer.py,sha256=DKFxmyyVVc59zwKbbGx4D22UVp6TxmD7jAa7cg9FGSU,19641
31
+ hindsight_api/engine/response_models.py,sha256=QeESHC7oh84SYPDrR6FqHjiGBZnTAzo61IDB-qwVTSY,8737
32
+ hindsight_api/engine/task_backend.py,sha256=XT0C-QFWfdcOHJjplkoarlnwvz-kCF2l6wAGW1dTJkw,7144
33
+ hindsight_api/engine/utils.py,sha256=TwuipFRvN0Pu196JLakzQ71E3GAwySc5q6pByC81Ak4,6991
34
+ hindsight_api/engine/retain/__init__.py,sha256=t6q3-_kf4iYTl9j2PVB6laqMSs6UuPeXBSYMW6HT1sA,1152
35
+ hindsight_api/engine/retain/bank_utils.py,sha256=-Q_GW_F1rmT6Twxgk7aLPmfintLp6TQhC5xT0i5hZzg,13970
36
+ hindsight_api/engine/retain/chunk_storage.py,sha256=yIofSL6RwMOIBR_xo1sTOUdkYQoRZBfjdqYuH-dj1EY,2012
37
+ hindsight_api/engine/retain/deduplication.py,sha256=kqs7I7eIc_ppvgAF9GlzL6fSGuEEzrgw17-7NdyUDis,3099
38
+ hindsight_api/engine/retain/embedding_processing.py,sha256=R35oyKYIKjuqC-yZl5Ru56F8xRe0N6KW_9p5PZ9CBi0,1649
39
+ hindsight_api/engine/retain/embedding_utils.py,sha256=uulXIBiA7XNsj16K1VGawR3s5jV-hsAmvmoCi-IodpU,1565
40
+ hindsight_api/engine/retain/entity_processing.py,sha256=5EYzyH_JjbhYQ0zQ8gX6xs0wCH6vmxMYUe6_qVJdvQA,2547
41
+ hindsight_api/engine/retain/fact_extraction.py,sha256=E9AswSrqx3X74gj5-qstbm2wqPv4kUMddkdn5yExKvI,50166
42
+ hindsight_api/engine/retain/fact_storage.py,sha256=SmWbdNTrOJW6MOHGOQ094f5DJSqasYp6yXGuxjh4_IA,5513
43
+ hindsight_api/engine/retain/link_creation.py,sha256=KP2kGU2VCymJptgw0hjaSdsjvncBgNp3P_A4OB_qx-w,3082
44
+ hindsight_api/engine/retain/link_utils.py,sha256=sB4aI3Ai7ukm1yQ6C_sotZ1inljjtDM8I9kSr8-a12o,32697
45
+ hindsight_api/engine/retain/observation_regeneration.py,sha256=HdKiVakeAEfBBUpKYYn2Rbb9jrx4FBhICEMZJ-sFQWU,7960
46
+ hindsight_api/engine/retain/orchestrator.py,sha256=obOpfzpAAg6PfTxR45RnKPvXnndNfUlmShkImj1cYOA,17418
47
+ hindsight_api/engine/retain/types.py,sha256=sez-Rq5nNNUnu6Z04QrmnR-CbrkXeQ1myAXHj9X79Pw,6379
48
+ hindsight_api/engine/search/__init__.py,sha256=YPz_4g7IOabx078Xwg3RBfbOpJ649NRwNfe0gTI9P1U,802
49
+ hindsight_api/engine/search/fusion.py,sha256=cY81BH9U5RyWrPXbQnrDBghtelDMckZWCke9aqMyNnQ,4220
50
+ hindsight_api/engine/search/graph_retrieval.py,sha256=AiC2oSRuZBdD5MmtIk0xSG7CxI5E6uQZe2-IbPqvJQw,8544
51
+ hindsight_api/engine/search/mpfp_retrieval.py,sha256=_OJUxgOYw169OjIxfOjpowg1gstXvVC0VhmJaClBJz8,13849
52
+ hindsight_api/engine/search/observation_utils.py,sha256=rlvGA4oFomMZNCZiJvPIQ0iwGaq9XqhRM530unqziCE,4243
53
+ hindsight_api/engine/search/reranking.py,sha256=RZSKe3JDkLfEdTAdgbS-xZka6Jq4mmTBPDXBpyH73zA,3278
54
+ hindsight_api/engine/search/retrieval.py,sha256=vs-kX5U5Vq4VV6lKq5Aoq1TzlJTtw5vDfnU4gPJ49Aw,25190
55
+ hindsight_api/engine/search/scoring.py,sha256=7jbBtdnow7JU0d8xdW-ZqYvP4s-TYX2tqPhu2DiqHUI,5132
56
+ hindsight_api/engine/search/temporal_extraction.py,sha256=j7hPqpx2jMdR2BqgFrL-rrV2Hzq8HV24MtjYLJqVl2U,1732
57
+ hindsight_api/engine/search/think_utils.py,sha256=rTRyoefRkZc65gcPQtffKiqHinpi7rrRD3m6i57fxNY,13900
58
+ hindsight_api/engine/search/trace.py,sha256=UTCmNRfAvIvDFGm5ifkuUk6JOKYrLlA_rPA72Zz_DfI,11217
59
+ hindsight_api/engine/search/tracer.py,sha256=6OFlkRy_41gr2kgJZ1cmxnerUO069wPfnmiQrMvkOpg,15459
60
+ hindsight_api/engine/search/types.py,sha256=2cK-5oynPTWc7UxnA7TFnwzNkcujCfOUvVf5VCk_srM,5594
61
+ hindsight_api-0.1.6.dist-info/METADATA,sha256=5vGOGWT1fI8hafqlmoIbTtBA8nARhZGBGvO5dxUqfMU,1524
62
+ hindsight_api-0.1.6.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
63
+ hindsight_api-0.1.6.dist-info/entry_points.txt,sha256=vqZv5WLHbSx8vyec5RtMlUqtE_ul7DTgEVODSmou6Og,109
64
+ hindsight_api-0.1.6.dist-info/RECORD,,
@@ -1,2 +1,3 @@
1
1
  [console_scripts]
2
2
  hindsight-api = hindsight_api.main:main
3
+ hindsight-local-mcp = hindsight_api.mcp_local:main