Foresight.Reflect.MentalModels (Foresight v0.3.0)

Copy Markdown View Source

Mental models for reflect, at parity with Hindsight: ranked by embedding similarity to the query, capped, and reported with a per-model staleness verdict.

Mental models are documents (metadata.document_type = "mental_model"). Their embeddings live in mental_model_embeddings and are kept current lazily: before a search the models whose content, dimension or model no longer match their stored row are re-embedded under the bank's embedding profile, so curated models that predate this table get indexed on first use and a profile change re-indexes them.

A model is stale when a memory in its scope was written after last_refreshed_at. The scope is the model's tags under trigger.tags_match (any | all | any_strict | all_strict, the recall semantics; the non-strict modes also admit untagged memories) and trigger.fact_types when set. An untagged model is global and any new memory makes it stale. A model never refreshed is stale by definition.

Summary

Functions

Embed (or re-embed) every model whose stored embedding is missing or outdated.

The tool/result entry for one ranked model.

Order documents by cosine similarity of their stored embedding to query, most similar first, models without a comparable embedding last. Falls back to lexical ranking when the query is blank, the profile is unknown or the query cannot be embedded. Returns {document, relevance | nil} pairs, at most limit.

Rank documents for query, embed the stragglers first, and return at most limit tool entries (Hindsight's tool_search_mental_models shape plus the title/text keys older callers read). Without a usable profile or query the lexical ranking stands in, with relevance absent.

Whether new in-scope memories arrived since the model's last refresh, with the reason.

Types

staleness()

@type staleness() :: {boolean(), String.t() | nil}

Functions

ensure_embeddings(repo, bank_id, documents, profile, embedder, repo_opts)

@spec ensure_embeddings(module(), String.t(), [struct()], map(), module(), keyword()) ::
  :ok

Embed (or re-embed) every model whose stored embedding is missing or outdated.

entry(document, relevance, arg)

@spec entry(struct(), float() | nil, staleness()) :: map()

The tool/result entry for one ranked model.

rank(repo, bank_id, documents, query, limit, profile, embedder, repo_opts)

@spec rank(
  module(),
  String.t(),
  [struct()],
  String.t(),
  pos_integer(),
  map() | nil,
  module() | nil,
  keyword()
) :: [{struct(), float() | nil}]

Order documents by cosine similarity of their stored embedding to query, most similar first, models without a comparable embedding last. Falls back to lexical ranking when the query is blank, the profile is unknown or the query cannot be embedded. Returns {document, relevance | nil} pairs, at most limit.

search(repo, bank_id, documents, query, limit, opts)

@spec search(module(), String.t(), [struct()], String.t(), pos_integer(), keyword()) ::
  [map()]

Rank documents for query, embed the stragglers first, and return at most limit tool entries (Hindsight's tool_search_mental_models shape plus the title/text keys older callers read). Without a usable profile or query the lexical ranking stands in, with relevance absent.

stale?(repo, bank_id, document, repo_opts)

@spec stale?(module(), String.t(), struct(), keyword()) :: staleness()

Whether new in-scope memories arrived since the model's last refresh, with the reason.