hindsight-api 0.4.3__tar.gz → 0.4.5__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 (112) hide show
  1. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/PKG-INFO +1 -1
  2. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/__init__.py +1 -1
  3. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/retain/fact_extraction.py +10 -4
  4. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/retain/orchestrator.py +43 -1
  5. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/task_backend.py +10 -1
  6. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/pyproject.toml +1 -1
  7. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/.gitignore +0 -0
  8. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/README.md +0 -0
  9. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/admin/__init__.py +0 -0
  10. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/admin/cli.py +0 -0
  11. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/README +0 -0
  12. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/env.py +0 -0
  13. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/script.py.mako +0 -0
  14. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/5a366d414dce_initial_schema.py +0 -0
  15. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/b7c4d8e9f1a2_add_chunks_table.py +0 -0
  16. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/c8e5f2a3b4d1_add_retain_params_to_documents.py +0 -0
  17. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/d9f6a3b4c5e2_rename_bank_to_interactions.py +0 -0
  18. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/e0a1b2c3d4e5_disposition_to_3_traits.py +0 -0
  19. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/f1a2b3c4d5e6_add_memory_links_composite_index.py +0 -0
  20. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/g2a3b4c5d6e7_add_tags_column.py +0 -0
  21. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/h3c4d5e6f7g8_mental_models_v4.py +0 -0
  22. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/i4d5e6f7g8h9_delete_opinions.py +0 -0
  23. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/j5e6f7g8h9i0_mental_model_versions.py +0 -0
  24. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/k6f7g8h9i0j1_add_directive_subtype.py +0 -0
  25. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/l7g8h9i0j1k2_add_worker_columns.py +0 -0
  26. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/m8h9i0j1k2l3_mental_model_id_to_text.py +0 -0
  27. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/n9i0j1k2l3m4_learnings_and_pinned_reflections.py +0 -0
  28. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/o0j1k2l3m4n5_migrate_mental_models_data.py +0 -0
  29. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/p1k2l3m4n5o6_new_knowledge_architecture.py +0 -0
  30. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/q2l3m4n5o6p7_fix_mental_model_fact_type.py +0 -0
  31. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/r3m4n5o6p7q8_add_reflect_response_to_reflections.py +0 -0
  32. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/rename_personality_to_disposition.py +0 -0
  33. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/s4n5o6p7q8r9_add_consolidated_at_to_memory_units.py +0 -0
  34. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/t5o6p7q8r9s0_rename_mental_models_to_observations.py +0 -0
  35. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/u6p7q8r9s0t1_mental_models_text_id.py +0 -0
  36. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/alembic/versions/v7q8r9s0t1u2_add_max_tokens_to_mental_models.py +0 -0
  37. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/api/__init__.py +0 -0
  38. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/api/http.py +0 -0
  39. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/api/mcp.py +0 -0
  40. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/banner.py +0 -0
  41. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/config.py +0 -0
  42. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/daemon.py +0 -0
  43. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/__init__.py +0 -0
  44. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/consolidation/__init__.py +0 -0
  45. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/consolidation/consolidator.py +0 -0
  46. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/consolidation/prompts.py +0 -0
  47. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/cross_encoder.py +0 -0
  48. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/db_budget.py +0 -0
  49. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/db_utils.py +0 -0
  50. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/directives/__init__.py +0 -0
  51. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/directives/models.py +0 -0
  52. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/embeddings.py +0 -0
  53. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/entity_resolver.py +0 -0
  54. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/interface.py +0 -0
  55. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/llm_wrapper.py +0 -0
  56. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/memory_engine.py +0 -0
  57. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/mental_models/__init__.py +0 -0
  58. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/mental_models/models.py +0 -0
  59. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/query_analyzer.py +0 -0
  60. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/reflect/__init__.py +0 -0
  61. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/reflect/agent.py +0 -0
  62. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/reflect/models.py +0 -0
  63. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/reflect/observations.py +0 -0
  64. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/reflect/prompts.py +0 -0
  65. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/reflect/tools.py +0 -0
  66. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/reflect/tools_schema.py +0 -0
  67. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/response_models.py +0 -0
  68. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/retain/__init__.py +0 -0
  69. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/retain/bank_utils.py +0 -0
  70. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/retain/chunk_storage.py +0 -0
  71. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/retain/deduplication.py +0 -0
  72. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/retain/embedding_processing.py +0 -0
  73. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/retain/embedding_utils.py +0 -0
  74. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/retain/entity_processing.py +0 -0
  75. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/retain/fact_storage.py +0 -0
  76. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/retain/link_creation.py +0 -0
  77. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/retain/link_utils.py +0 -0
  78. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/retain/types.py +0 -0
  79. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/search/__init__.py +0 -0
  80. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/search/fusion.py +0 -0
  81. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/search/graph_retrieval.py +0 -0
  82. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/search/link_expansion_retrieval.py +0 -0
  83. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/search/mpfp_retrieval.py +0 -0
  84. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/search/reranking.py +0 -0
  85. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/search/retrieval.py +0 -0
  86. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/search/tags.py +0 -0
  87. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/search/temporal_extraction.py +0 -0
  88. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/search/think_utils.py +0 -0
  89. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/search/trace.py +0 -0
  90. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/search/tracer.py +0 -0
  91. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/search/types.py +0 -0
  92. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/engine/utils.py +0 -0
  93. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/extensions/__init__.py +0 -0
  94. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/extensions/base.py +0 -0
  95. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/extensions/builtin/__init__.py +0 -0
  96. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/extensions/builtin/tenant.py +0 -0
  97. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/extensions/context.py +0 -0
  98. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/extensions/http.py +0 -0
  99. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/extensions/loader.py +0 -0
  100. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/extensions/operation_validator.py +0 -0
  101. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/extensions/tenant.py +0 -0
  102. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/main.py +0 -0
  103. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/mcp_local.py +0 -0
  104. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/mcp_tools.py +0 -0
  105. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/metrics.py +0 -0
  106. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/migrations.py +0 -0
  107. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/models.py +0 -0
  108. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/pg0.py +0 -0
  109. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/server.py +0 -0
  110. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/worker/__init__.py +0 -0
  111. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/worker/main.py +0 -0
  112. {hindsight_api-0.4.3 → hindsight_api-0.4.5}/hindsight_api/worker/poller.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hindsight-api
3
- Version: 0.4.3
3
+ Version: 0.4.5
4
4
  Summary: Hindsight: Agent Memory That Works Like Human Memory
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: aiohttp>=3.13.3
@@ -46,4 +46,4 @@ __all__ = [
46
46
  "RemoteTEICrossEncoder",
47
47
  "LLMConfig",
48
48
  ]
49
- __version__ = "0.4.3"
49
+ __version__ = "0.4.5"
@@ -759,6 +759,10 @@ async def _extract_facts_from_chunk(
759
759
 
760
760
  # Build user message with metadata and chunk content in a clear format
761
761
  # Format event_date with day of week for better temporal reasoning
762
+ # Handle both datetime objects and ISO string formats (from deserialized async tasks)
763
+ from .orchestrator import parse_datetime_flexible
764
+
765
+ event_date = parse_datetime_flexible(event_date)
762
766
  event_date_formatted = event_date.strftime("%A, %B %d, %Y") # e.g., "Monday, June 10, 2024"
763
767
  user_message = f"""Extract facts from the following text chunk.
764
768
 
@@ -1346,6 +1350,8 @@ def _add_temporal_offsets(facts: list[ExtractedFactType], contents: list[RetainC
1346
1350
 
1347
1351
  Modifies facts in place.
1348
1352
  """
1353
+ from .orchestrator import parse_datetime_flexible
1354
+
1349
1355
  # Group facts by content_index
1350
1356
  current_content_idx = 0
1351
1357
  content_fact_start = 0
@@ -1360,10 +1366,10 @@ def _add_temporal_offsets(facts: list[ExtractedFactType], contents: list[RetainC
1360
1366
  fact_position = i - content_fact_start
1361
1367
  offset = timedelta(seconds=fact_position * SECONDS_PER_FACT)
1362
1368
 
1363
- # Apply offset to all temporal fields
1369
+ # Apply offset to all temporal fields (handle both datetime objects and ISO strings)
1364
1370
  if fact.occurred_start:
1365
- fact.occurred_start = fact.occurred_start + offset
1371
+ fact.occurred_start = parse_datetime_flexible(fact.occurred_start) + offset
1366
1372
  if fact.occurred_end:
1367
- fact.occurred_end = fact.occurred_end + offset
1373
+ fact.occurred_end = parse_datetime_flexible(fact.occurred_end) + offset
1368
1374
  if fact.mentioned_at:
1369
- fact.mentioned_at = fact.mentioned_at + offset
1375
+ fact.mentioned_at = parse_datetime_flexible(fact.mentioned_at) + offset
@@ -8,6 +8,7 @@ import logging
8
8
  import time
9
9
  import uuid
10
10
  from datetime import UTC, datetime
11
+ from typing import Any
11
12
 
12
13
  from ..db_utils import acquire_with_retry
13
14
  from . import bank_utils
@@ -18,6 +19,39 @@ def utcnow():
18
19
  return datetime.now(UTC)
19
20
 
20
21
 
22
+ def parse_datetime_flexible(value: Any) -> datetime:
23
+ """
24
+ Parse a datetime value that could be either a datetime object or an ISO string.
25
+
26
+ This handles datetime values from both direct Python calls and deserialized JSON
27
+ (where datetime objects are serialized as ISO strings).
28
+
29
+ Args:
30
+ value: Either a datetime object or an ISO format string
31
+
32
+ Returns:
33
+ datetime object (timezone-aware)
34
+
35
+ Raises:
36
+ TypeError: If value is neither datetime nor string
37
+ ValueError: If string is not a valid ISO datetime
38
+ """
39
+ if isinstance(value, datetime):
40
+ # Ensure timezone-aware
41
+ if value.tzinfo is None:
42
+ return value.replace(tzinfo=UTC)
43
+ return value
44
+ elif isinstance(value, str):
45
+ # Parse ISO format string (handles both 'Z' and '+00:00' timezone formats)
46
+ dt = datetime.fromisoformat(value.replace("Z", "+00:00"))
47
+ # Ensure timezone-aware
48
+ if dt.tzinfo is None:
49
+ return dt.replace(tzinfo=UTC)
50
+ return dt
51
+ else:
52
+ raise TypeError(f"Expected datetime or string, got {type(value).__name__}")
53
+
54
+
21
55
  from ..response_models import TokenUsage
22
56
  from . import (
23
57
  chunk_storage,
@@ -89,10 +123,18 @@ async def retain_batch(
89
123
  # Merge item-level tags with document-level tags
90
124
  item_tags = item.get("tags", []) or []
91
125
  merged_tags = list(set(item_tags + (document_tags or [])))
126
+
127
+ # Handle event_date: parse flexibly (handles both datetime objects and ISO strings)
128
+ event_date_value = item.get("event_date")
129
+ if event_date_value:
130
+ event_date_value = parse_datetime_flexible(event_date_value)
131
+ else:
132
+ event_date_value = utcnow()
133
+
92
134
  content = RetainContent(
93
135
  content=item["content"],
94
136
  context=item.get("context", ""),
95
- event_date=item.get("event_date") or utcnow(),
137
+ event_date=event_date_value,
96
138
  metadata=item.get("metadata", {}),
97
139
  entities=item.get("entities", []),
98
140
  tags=merged_tags,
@@ -182,7 +182,16 @@ class BrokerTaskBackend(TaskBackend):
182
182
  operation_id = task_dict.get("operation_id")
183
183
  task_type = task_dict.get("type", "unknown")
184
184
  bank_id = task_dict.get("bank_id")
185
- payload_json = json.dumps(task_dict)
185
+
186
+ # Custom encoder to handle datetime objects
187
+ from datetime import datetime
188
+
189
+ def datetime_encoder(obj):
190
+ if isinstance(obj, datetime):
191
+ return obj.isoformat()
192
+ raise TypeError(f"Object of type {type(obj).__name__} is not JSON serializable")
193
+
194
+ payload_json = json.dumps(task_dict, default=datetime_encoder)
186
195
 
187
196
  schema = self._schema_getter() if self._schema_getter else self._schema
188
197
  table = fq_table("async_operations", schema)
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "hindsight-api"
7
- version = "0.4.3"
7
+ version = "0.4.5"
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