fleet-memory/hindsight-api/hindsight_api/engine
Nicolò Boschi f903948a26
feat: support timestamp="unset" to retain content without a date (#465)
* feat: support timestamp="unset" to retain content without a date

When callers retain timeless content (e.g. fictional documents, static
reference material), passing timestamp="unset" now skips the utcnow()
default so mentioned_at is stored as NULL instead of an artificial date.

- HTTP: validate_timestamp recognises "unset" sentinel and threads it
  through api_retain as event_date=None (key present, value None), which
  the orchestrator distinguishes from key-absent (still defaults to now)
- Orchestrator: new branching logic separates "key absent" → utcnow()
  from "key present but None" → no date
- types.py: RetainContent.event_date and ProcessedFact.mentioned_at are
  now datetime | None; removed the unused _now_utc factory
- fact_extraction.py: all event_date params accept datetime | None;
  _build_user_message emits "Event Date: Unknown" when None; removed
  mentioned_at from the Fact LLM response model (LLM never sets it)
- embedding_processing: skip date suffix when fact_date is None
- entity_resolver: COALESCE(event_date, now()) for first_seen/last_seen
  so entities table NOT NULL constraint is preserved
- link_utils: skip temporal linking for units without event_date
- Migration aa2b3c4d5e6f: DROP NOT NULL on memory_units.event_date
- Tests: test_retain_no_timestamp and test_retain_omit_timestamp_defaults_to_now
- Docs + OpenAPI + TypeScript client updated

* refactor: replace _TIMESTAMP_UNKNOWN sentinel with plain string comparison

The sentinel object() was only needed to distinguish "unset" from None
at the boundary — but since the field type is datetime | str | None,
"unset" can pass through the validator unchanged and be compared directly.

* chore: regenerate OpenAPI spec and clients after timestamp type change

timestamp field is now datetime | str | None to accept the "unset" sentinel value.
2026-03-02 12:03:23 +01:00
..
consolidation feat: observation_scopes field to drive observations granularity (#447) 2026-02-28 10:46:21 +01:00
directives feat: revisit mental models, directives and reflections (#179) 2026-01-22 17:13:16 +01:00
mental_models feat: revisit mental models, directives and reflections (#179) 2026-01-22 17:13:16 +01:00
parsers feat: add iris as file parser (#395) 2026-02-18 14:09:56 +01:00
providers fix: resolve JSON serialization and logging exception propagation in claude_code_llm (#458, #459) (#461) 2026-03-02 10:14:16 +01:00
reflect fix(reflect): prevent context_length_exceeded on large memory banks (#462) 2026-03-02 12:03:12 +01:00
retain feat: support timestamp="unset" to retain content without a date (#465) 2026-03-02 12:03:23 +01:00
search fix: improve memory footprint of recall (#423) 2026-02-23 11:30:16 +01:00
storage fix(storage): use dynamic schema_getter in PostgreSQLFileStorage for multi-tenant (#440) 2026-02-25 15:19:08 +01:00
__init__.py feat: extensions (#54) 2025-12-22 11:05:23 +01:00
cross_encoder.py fix: zeroentropy rerank URL missing /v1 prefix and MCP retain async_processing param (#460) 2026-03-02 10:32:01 +01:00
db_budget.py fix: batch queries on recall (#149) 2026-01-13 13:20:22 +01:00
db_utils.py misc: performance improvements (#140) 2026-01-09 14:47:20 +01:00
embeddings.py fix: pass encoding_format="float" in LiteLLM embedding calls (#434) 2026-02-25 10:32:05 +01:00
entity_resolver.py feat: support timestamp="unset" to retain content without a date (#465) 2026-03-02 12:03:23 +01:00
interface.py fix: propagate document tags in async retain path (#374) 2026-02-16 10:04:48 +01:00
llm_interface.py feat: support Batch API for retain (openai/groq) (#365) 2026-02-16 13:31:50 +01:00
llm_wrapper.py misc: fix vertex/gemini errors and use it for ci tests (#414) 2026-02-20 22:35:38 +01:00
memory_engine.py fix(reflect): prevent context_length_exceeded on large memory banks (#462) 2026-03-02 12:03:12 +01:00
operation_metadata.py fix: improve async batch retain with large payloads (#366) 2026-02-16 12:51:42 +01:00
query_analyzer.py fix: improve mpfp retrieval (#146) 2026-01-12 18:58:05 +01:00
response_models.py feat: include source facts in observation recall (#404) 2026-02-19 14:54:19 +01:00
task_backend.py fix: retain async fails if timestamp is set (#251) 2026-01-30 13:04:33 +01:00
utils.py feat: implement hierarchical configuration (system, tenant, bank) (#329) 2026-02-12 13:14:57 +01:00