hindsight-api 0.1.7__tar.gz → 0.1.9__tar.gz

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 (64) hide show
  1. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/PKG-INFO +1 -1
  2. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/api/http.py +16 -12
  3. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/config.py +24 -1
  4. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/llm_wrapper.py +2 -3
  5. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/memory_engine.py +3 -3
  6. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/retain/orchestrator.py +4 -0
  7. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/main.py +2 -0
  8. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/mcp_local.py +31 -28
  9. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/pyproject.toml +1 -1
  10. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/.gitignore +0 -0
  11. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/README.md +0 -0
  12. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/__init__.py +0 -0
  13. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/alembic/README +0 -0
  14. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/alembic/env.py +0 -0
  15. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/alembic/script.py.mako +0 -0
  16. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/alembic/versions/5a366d414dce_initial_schema.py +0 -0
  17. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/alembic/versions/b7c4d8e9f1a2_add_chunks_table.py +0 -0
  18. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/alembic/versions/c8e5f2a3b4d1_add_retain_params_to_documents.py +0 -0
  19. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/alembic/versions/d9f6a3b4c5e2_rename_bank_to_interactions.py +0 -0
  20. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/alembic/versions/e0a1b2c3d4e5_disposition_to_3_traits.py +0 -0
  21. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/alembic/versions/rename_personality_to_disposition.py +0 -0
  22. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/api/__init__.py +0 -0
  23. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/api/mcp.py +0 -0
  24. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/banner.py +0 -0
  25. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/__init__.py +0 -0
  26. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/cross_encoder.py +0 -0
  27. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/db_utils.py +0 -0
  28. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/embeddings.py +0 -0
  29. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/entity_resolver.py +0 -0
  30. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/query_analyzer.py +0 -0
  31. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/response_models.py +0 -0
  32. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/retain/__init__.py +0 -0
  33. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/retain/bank_utils.py +0 -0
  34. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/retain/chunk_storage.py +0 -0
  35. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/retain/deduplication.py +0 -0
  36. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/retain/embedding_processing.py +0 -0
  37. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/retain/embedding_utils.py +0 -0
  38. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/retain/entity_processing.py +0 -0
  39. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/retain/fact_extraction.py +0 -0
  40. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/retain/fact_storage.py +0 -0
  41. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/retain/link_creation.py +0 -0
  42. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/retain/link_utils.py +0 -0
  43. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/retain/observation_regeneration.py +0 -0
  44. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/retain/types.py +0 -0
  45. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/search/__init__.py +0 -0
  46. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/search/fusion.py +0 -0
  47. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/search/graph_retrieval.py +0 -0
  48. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/search/mpfp_retrieval.py +0 -0
  49. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/search/observation_utils.py +0 -0
  50. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/search/reranking.py +0 -0
  51. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/search/retrieval.py +0 -0
  52. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/search/scoring.py +0 -0
  53. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/search/temporal_extraction.py +0 -0
  54. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/search/think_utils.py +0 -0
  55. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/search/trace.py +0 -0
  56. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/search/tracer.py +0 -0
  57. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/search/types.py +0 -0
  58. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/task_backend.py +0 -0
  59. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/engine/utils.py +0 -0
  60. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/metrics.py +0 -0
  61. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/migrations.py +0 -0
  62. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/models.py +0 -0
  63. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/pg0.py +0 -0
  64. {hindsight_api-0.1.7 → hindsight_api-0.1.9}/hindsight_api/server.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hindsight-api
3
- Version: 0.1.7
3
+ Version: 0.1.9
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
@@ -506,9 +506,9 @@ class BankListItem(BaseModel):
506
506
  """Bank list item with profile summary."""
507
507
 
508
508
  bank_id: str
509
- name: str
509
+ name: str | None = None
510
510
  disposition: DispositionTraits
511
- background: str
511
+ background: str | None = None
512
512
  created_at: str | None = None
513
513
  updated_at: str | None = None
514
514
 
@@ -1452,18 +1452,22 @@ def _register_routes(app: FastAPI):
1452
1452
  bank_id,
1453
1453
  )
1454
1454
 
1455
+ def parse_metadata(metadata):
1456
+ """Parse result_metadata which may be a string or dict."""
1457
+ if metadata is None:
1458
+ return {}
1459
+ if isinstance(metadata, str):
1460
+ return json.loads(metadata)
1461
+ return metadata
1462
+
1455
1463
  return {
1456
1464
  "bank_id": bank_id,
1457
1465
  "operations": [
1458
1466
  {
1459
1467
  "id": str(row["operation_id"]),
1460
1468
  "task_type": row["operation_type"],
1461
- "items_count": row["result_metadata"].get("items_count", 0)
1462
- if row["result_metadata"]
1463
- else 0,
1464
- "document_id": row["result_metadata"].get("document_id")
1465
- if row["result_metadata"]
1466
- else None,
1469
+ "items_count": parse_metadata(row["result_metadata"]).get("items_count", 0),
1470
+ "document_id": parse_metadata(row["result_metadata"]).get("document_id"),
1467
1471
  "created_at": row["created_at"].isoformat(),
1468
1472
  "status": row["status"],
1469
1473
  "error_message": row["error_message"],
@@ -1499,7 +1503,7 @@ def _register_routes(app: FastAPI):
1499
1503
  async with acquire_with_retry(pool) as conn:
1500
1504
  # Check if operation exists and belongs to this memory bank
1501
1505
  result = await conn.fetchrow(
1502
- "SELECT bank_id FROM async_operations WHERE id = $1 AND bank_id = $2", op_uuid, bank_id
1506
+ "SELECT bank_id FROM async_operations WHERE operation_id = $1 AND bank_id = $2", op_uuid, bank_id
1503
1507
  )
1504
1508
 
1505
1509
  if not result:
@@ -1508,7 +1512,7 @@ def _register_routes(app: FastAPI):
1508
1512
  )
1509
1513
 
1510
1514
  # Delete the operation
1511
- await conn.execute("DELETE FROM async_operations WHERE id = $1", op_uuid)
1515
+ await conn.execute("DELETE FROM async_operations WHERE operation_id = $1", op_uuid)
1512
1516
 
1513
1517
  return {
1514
1518
  "success": True,
@@ -1769,13 +1773,13 @@ def _register_routes(app: FastAPI):
1769
1773
  async with acquire_with_retry(pool) as conn:
1770
1774
  await conn.execute(
1771
1775
  """
1772
- INSERT INTO async_operations (id, bank_id, task_type, items_count)
1776
+ INSERT INTO async_operations (operation_id, bank_id, operation_type, result_metadata)
1773
1777
  VALUES ($1, $2, $3, $4)
1774
1778
  """,
1775
1779
  operation_id,
1776
1780
  bank_id,
1777
1781
  "retain",
1778
- len(contents),
1782
+ json.dumps({"items_count": len(contents)}),
1779
1783
  )
1780
1784
 
1781
1785
  # Submit task to background queue
@@ -31,6 +31,7 @@ ENV_LOG_LEVEL = "HINDSIGHT_API_LOG_LEVEL"
31
31
  ENV_MCP_ENABLED = "HINDSIGHT_API_MCP_ENABLED"
32
32
  ENV_GRAPH_RETRIEVER = "HINDSIGHT_API_GRAPH_RETRIEVER"
33
33
  ENV_MCP_LOCAL_BANK_ID = "HINDSIGHT_API_MCP_LOCAL_BANK_ID"
34
+ ENV_MCP_INSTRUCTIONS = "HINDSIGHT_API_MCP_INSTRUCTIONS"
34
35
 
35
36
  # Default values
36
37
  DEFAULT_DATABASE_URL = "pg0"
@@ -50,6 +51,26 @@ DEFAULT_MCP_ENABLED = True
50
51
  DEFAULT_GRAPH_RETRIEVER = "bfs" # Options: "bfs", "mpfp"
51
52
  DEFAULT_MCP_LOCAL_BANK_ID = "mcp"
52
53
 
54
+ # Default MCP tool descriptions (can be customized via env vars)
55
+ DEFAULT_MCP_RETAIN_DESCRIPTION = """Store important information to long-term memory.
56
+
57
+ Use this tool PROACTIVELY whenever the user shares:
58
+ - Personal facts, preferences, or interests
59
+ - Important events or milestones
60
+ - User history, experiences, or background
61
+ - Decisions, opinions, or stated preferences
62
+ - Goals, plans, or future intentions
63
+ - Relationships or people mentioned
64
+ - Work context, projects, or responsibilities"""
65
+
66
+ DEFAULT_MCP_RECALL_DESCRIPTION = """Search memories to provide personalized, context-aware responses.
67
+
68
+ Use this tool PROACTIVELY to:
69
+ - Check user's preferences before making suggestions
70
+ - Recall user's history to provide continuity
71
+ - Remember user's goals and context
72
+ - Personalize responses based on past interactions"""
73
+
53
74
  # Required embedding dimension for database schema
54
75
  EMBEDDING_DIMENSION = 384
55
76
 
@@ -142,7 +163,9 @@ class HindsightConfig:
142
163
  def configure_logging(self) -> None:
143
164
  """Configure Python logging based on the log level."""
144
165
  logging.basicConfig(
145
- level=self.get_python_log_level(), format="%(asctime)s - %(levelname)s - %(name)s - %(message)s"
166
+ level=self.get_python_log_level(),
167
+ format="%(asctime)s - %(levelname)s - %(name)s - %(message)s",
168
+ force=True, # Override any existing configuration
146
169
  )
147
170
 
148
171
  def log_config(self) -> None:
@@ -172,7 +172,7 @@ class LLMProvider:
172
172
 
173
173
  # Check if model supports reasoning parameter (o1, o3, gpt-5 families)
174
174
  model_lower = self.model.lower()
175
- is_reasoning_model = any(x in model_lower for x in ["gpt-5", "o1", "o3"])
175
+ is_reasoning_model = any(x in model_lower for x in ["gpt-5", "o1", "o3", "deepseek"])
176
176
 
177
177
  # For GPT-4 and GPT-4.1 models, cap max_completion_tokens to 32000
178
178
  # For GPT-4o models, cap to 16384
@@ -194,7 +194,7 @@ class LLMProvider:
194
194
  call_params["temperature"] = temperature
195
195
 
196
196
  # Set reasoning_effort for reasoning models (OpenAI gpt-5, o1, o3)
197
- if is_reasoning_model and self.provider == "openai":
197
+ if is_reasoning_model:
198
198
  call_params["reasoning_effort"] = self.reasoning_effort
199
199
 
200
200
  # Provider-specific parameters
@@ -203,7 +203,6 @@ class LLMProvider:
203
203
  extra_body = {"service_tier": "auto"}
204
204
  # Only add reasoning parameters for reasoning models
205
205
  if is_reasoning_model:
206
- extra_body["reasoning_effort"] = self.reasoning_effort
207
206
  extra_body["include_reasoning"] = False
208
207
  call_params["extra_body"] = extra_body
209
208
 
@@ -311,7 +311,7 @@ class MemoryEngine:
311
311
  pool = await self._get_pool()
312
312
  async with acquire_with_retry(pool) as conn:
313
313
  result = await conn.fetchrow(
314
- "SELECT id FROM async_operations WHERE id = $1", uuid.UUID(operation_id)
314
+ "SELECT operation_id FROM async_operations WHERE operation_id = $1", uuid.UUID(operation_id)
315
315
  )
316
316
  if not result:
317
317
  # Operation was cancelled, skip processing
@@ -369,7 +369,7 @@ class MemoryEngine:
369
369
  try:
370
370
  pool = await self._get_pool()
371
371
  async with acquire_with_retry(pool) as conn:
372
- await conn.execute("DELETE FROM async_operations WHERE id = $1", uuid.UUID(operation_id))
372
+ await conn.execute("DELETE FROM async_operations WHERE operation_id = $1", uuid.UUID(operation_id))
373
373
  except Exception as e:
374
374
  logger.error(f"Failed to delete async operation record {operation_id}: {e}")
375
375
 
@@ -386,7 +386,7 @@ class MemoryEngine:
386
386
  """
387
387
  UPDATE async_operations
388
388
  SET status = 'failed', error_message = $2
389
- WHERE id = $1
389
+ WHERE operation_id = $1
390
390
  """,
391
391
  uuid.UUID(operation_id),
392
392
  truncated_error,
@@ -107,6 +107,10 @@ async def retain_batch(
107
107
  )
108
108
 
109
109
  if not extracted_facts:
110
+ total_time = time.time() - start_time
111
+ logger.info(
112
+ f"RETAIN_BATCH COMPLETE: 0 facts extracted from {len(contents)} contents in {total_time:.3f}s (nothing to store)"
113
+ )
110
114
  return [[] for _ in contents]
111
115
 
112
116
  # Apply fact_type_override if provided
@@ -127,8 +127,10 @@ def main():
127
127
  port=args.port,
128
128
  log_level=args.log_level,
129
129
  mcp_enabled=config.mcp_enabled,
130
+ graph_retriever=config.graph_retriever,
130
131
  )
131
132
  config.configure_logging()
133
+ config.log_config()
132
134
 
133
135
  # Register cleanup handlers
134
136
  atexit.register(_cleanup)
@@ -28,7 +28,15 @@ Environment variables:
28
28
  HINDSIGHT_API_LLM_PROVIDER: Optional. LLM provider (default: "openai").
29
29
  HINDSIGHT_API_LLM_MODEL: Optional. LLM model (default: "gpt-4o-mini").
30
30
  HINDSIGHT_API_MCP_LOCAL_BANK_ID: Optional. Memory bank ID (default: "mcp").
31
- HINDSIGHT_API_LOG_LEVEL: Optional. Log level (default: "info").
31
+ HINDSIGHT_API_LOG_LEVEL: Optional. Log level (default: "warning").
32
+ HINDSIGHT_API_MCP_INSTRUCTIONS: Optional. Additional instructions appended to both retain and recall tools.
33
+
34
+ Example custom instructions (these are ADDED to the default behavior):
35
+ To also store assistant actions:
36
+ HINDSIGHT_API_MCP_INSTRUCTIONS="Also store every action you take, including tool calls, code written, and decisions made."
37
+
38
+ To also store conversation summaries:
39
+ HINDSIGHT_API_MCP_INSTRUCTIONS="Also store summaries of important conversations and their outcomes."
32
40
  """
33
41
 
34
42
  import logging
@@ -36,14 +44,19 @@ import os
36
44
  import sys
37
45
 
38
46
  from mcp.server.fastmcp import FastMCP
47
+ from mcp.types import Icon
39
48
 
40
49
  from hindsight_api.config import (
41
50
  DEFAULT_MCP_LOCAL_BANK_ID,
51
+ DEFAULT_MCP_RECALL_DESCRIPTION,
52
+ DEFAULT_MCP_RETAIN_DESCRIPTION,
53
+ ENV_MCP_INSTRUCTIONS,
42
54
  ENV_MCP_LOCAL_BANK_ID,
43
55
  )
44
56
 
45
- # Configure logging - default to info
46
- _log_level_str = os.environ.get("HINDSIGHT_API_LOG_LEVEL", "info").lower()
57
+ # Configure logging - default to warning to avoid polluting stderr during MCP init
58
+ # MCP clients interpret stderr output as errors, so we suppress INFO logs by default
59
+ _log_level_str = os.environ.get("HINDSIGHT_API_LOG_LEVEL", "warning").lower()
47
60
  _log_level_map = {
48
61
  "critical": logging.CRITICAL,
49
62
  "error": logging.ERROR,
@@ -79,22 +92,21 @@ def create_local_mcp_server(bank_id: str, memory=None) -> FastMCP:
79
92
  if memory is None:
80
93
  memory = MemoryEngine(db_url="pg0://hindsight-mcp")
81
94
 
95
+ # Get custom instructions from environment variable (appended to both tools)
96
+ extra_instructions = os.environ.get(ENV_MCP_INSTRUCTIONS, "")
97
+
98
+ retain_description = DEFAULT_MCP_RETAIN_DESCRIPTION
99
+ recall_description = DEFAULT_MCP_RECALL_DESCRIPTION
100
+
101
+ if extra_instructions:
102
+ retain_description = f"{DEFAULT_MCP_RETAIN_DESCRIPTION}\n\nAdditional instructions: {extra_instructions}"
103
+ recall_description = f"{DEFAULT_MCP_RECALL_DESCRIPTION}\n\nAdditional instructions: {extra_instructions}"
104
+
82
105
  mcp = FastMCP("hindsight")
83
106
 
84
- @mcp.tool()
107
+ @mcp.tool(description=retain_description)
85
108
  async def retain(content: str, context: str = "general") -> dict:
86
109
  """
87
- Store important information to long-term memory.
88
-
89
- Use this tool PROACTIVELY whenever the user shares:
90
- - Personal facts, preferences, or interests
91
- - Important events or milestones
92
- - User history, experiences, or background
93
- - Decisions, opinions, or stated preferences
94
- - Goals, plans, or future intentions
95
- - Relationships or people mentioned
96
- - Work context, projects, or responsibilities
97
-
98
110
  Args:
99
111
  content: The fact/memory to store (be specific and include relevant details)
100
112
  context: Category for the memory (e.g., 'preferences', 'work', 'hobbies', 'family'). Default: 'general'
@@ -111,17 +123,9 @@ def create_local_mcp_server(bank_id: str, memory=None) -> FastMCP:
111
123
  asyncio.create_task(_retain())
112
124
  return {"status": "accepted", "message": "Memory storage initiated"}
113
125
 
114
- @mcp.tool()
126
+ @mcp.tool(description=recall_description)
115
127
  async def recall(query: str, max_tokens: int = 4096, budget: str = "low") -> dict:
116
128
  """
117
- Search memories to provide personalized, context-aware responses.
118
-
119
- Use this tool PROACTIVELY to:
120
- - Check user's preferences before making suggestions
121
- - Recall user's history to provide continuity
122
- - Remember user's goals and context
123
- - Personalize responses based on past interactions
124
-
125
129
  Args:
126
130
  query: Natural language search query (e.g., "user's food preferences", "what projects is user working on")
127
131
  max_tokens: Maximum tokens to return in results (default: 4096)
@@ -153,10 +157,9 @@ async def _initialize_and_run(bank_id: str):
153
157
  from hindsight_api import MemoryEngine
154
158
 
155
159
  # Create and initialize memory engine with pg0 embedded database
156
- print("Initializing memory engine...", file=sys.stderr)
160
+ # Note: We avoid printing to stderr during init as MCP clients show it as "errors"
157
161
  memory = MemoryEngine(db_url="pg0://hindsight-mcp")
158
162
  await memory.initialize()
159
- print("Memory engine initialized.", file=sys.stderr)
160
163
 
161
164
  # Create and run the server
162
165
  mcp = create_local_mcp_server(bank_id, memory=memory)
@@ -179,8 +182,8 @@ def main():
179
182
  # Get bank ID from environment, default to "mcp"
180
183
  bank_id = os.environ.get(ENV_MCP_LOCAL_BANK_ID, DEFAULT_MCP_LOCAL_BANK_ID)
181
184
 
182
- # Print startup message to stderr (stdout is reserved for MCP protocol)
183
- print(f"Hindsight MCP server starting (bank_id={bank_id})...", file=sys.stderr)
185
+ # Note: We don't print to stderr as MCP clients display it as "error output"
186
+ # Use HINDSIGHT_API_LOG_LEVEL=debug for verbose startup logging
184
187
 
185
188
  # Run the async initialization and server
186
189
  asyncio.run(_initialize_and_run(bank_id))
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "hindsight-api"
7
- version = "0.1.7"
7
+ version = "0.1.9"
8
8
  description = "Hindsight: Agent Memory That Works Like Human Memory"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
File without changes
File without changes