hindsight-api 0.1.8__tar.gz → 0.1.10__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.8 → hindsight_api-0.1.10}/PKG-INFO +1 -1
  2. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/config.py +24 -1
  3. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/llm_wrapper.py +2 -3
  4. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/retain/orchestrator.py +4 -0
  5. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/main.py +2 -0
  6. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/mcp_local.py +31 -28
  7. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/pyproject.toml +1 -1
  8. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/.gitignore +0 -0
  9. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/README.md +0 -0
  10. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/__init__.py +0 -0
  11. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/alembic/README +0 -0
  12. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/alembic/env.py +0 -0
  13. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/alembic/script.py.mako +0 -0
  14. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/alembic/versions/5a366d414dce_initial_schema.py +0 -0
  15. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/alembic/versions/b7c4d8e9f1a2_add_chunks_table.py +0 -0
  16. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/alembic/versions/c8e5f2a3b4d1_add_retain_params_to_documents.py +0 -0
  17. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/alembic/versions/d9f6a3b4c5e2_rename_bank_to_interactions.py +0 -0
  18. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/alembic/versions/e0a1b2c3d4e5_disposition_to_3_traits.py +0 -0
  19. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/alembic/versions/rename_personality_to_disposition.py +0 -0
  20. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/api/__init__.py +0 -0
  21. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/api/http.py +0 -0
  22. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/api/mcp.py +0 -0
  23. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/banner.py +0 -0
  24. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/__init__.py +0 -0
  25. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/cross_encoder.py +0 -0
  26. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/db_utils.py +0 -0
  27. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/embeddings.py +0 -0
  28. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/entity_resolver.py +0 -0
  29. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/memory_engine.py +0 -0
  30. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/query_analyzer.py +0 -0
  31. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/response_models.py +0 -0
  32. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/retain/__init__.py +0 -0
  33. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/retain/bank_utils.py +0 -0
  34. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/retain/chunk_storage.py +0 -0
  35. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/retain/deduplication.py +0 -0
  36. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/retain/embedding_processing.py +0 -0
  37. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/retain/embedding_utils.py +0 -0
  38. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/retain/entity_processing.py +0 -0
  39. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/retain/fact_extraction.py +0 -0
  40. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/retain/fact_storage.py +0 -0
  41. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/retain/link_creation.py +0 -0
  42. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/retain/link_utils.py +0 -0
  43. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/retain/observation_regeneration.py +0 -0
  44. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/retain/types.py +0 -0
  45. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/search/__init__.py +0 -0
  46. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/search/fusion.py +0 -0
  47. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/search/graph_retrieval.py +0 -0
  48. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/search/mpfp_retrieval.py +0 -0
  49. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/search/observation_utils.py +0 -0
  50. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/search/reranking.py +0 -0
  51. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/search/retrieval.py +0 -0
  52. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/search/scoring.py +0 -0
  53. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/search/temporal_extraction.py +0 -0
  54. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/search/think_utils.py +0 -0
  55. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/search/trace.py +0 -0
  56. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/search/tracer.py +0 -0
  57. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/search/types.py +0 -0
  58. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/task_backend.py +0 -0
  59. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/engine/utils.py +0 -0
  60. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/metrics.py +0 -0
  61. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/migrations.py +0 -0
  62. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/models.py +0 -0
  63. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/hindsight_api/pg0.py +0 -0
  64. {hindsight_api-0.1.8 → hindsight_api-0.1.10}/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.8
3
+ Version: 0.1.10
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
@@ -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
 
@@ -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.8"
7
+ version = "0.1.10"
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