Use Case
Periodic compaction of delta-mode reflections. Over time, incremental delta refreshes accumulate drift — small inaccuracies compound as each refresh only sees new facts since the last. A scheduled full re-synthesis every 48h produces a clean baseline from all facts.
Without this parameter, the only workaround is toggling a trailing space on source_query before each refresh to force a last_refreshed_source_query mismatch — a fragile hack that mutates model state for a side effect.
Problem Statement
There's no way to force a full (non-delta) refresh on a delta-mode mental model via the API. The only workaround is mutating source_query to create a mismatch with last_refreshed_source_query, which forces use_delta = False on the next refresh.
This is needed for periodic compaction — delta refreshes accumulate drift over time, and callers want to trigger a clean full re-synthesis without permanently changing the model's trigger configuration.
How This Feature Would Help
- Clean API contract: callers express intent ("refresh fully") rather than exploiting internal side effects (source_query mismatch)
- No state mutation: the model's config stays unchanged — the override is per-request, not persisted
- Composable with existing triggers: delta mode stays the default for consolidation-triggered refreshes; full mode is opt-in when the caller knows it's needed
Proposed Solution
Add an optional mode query parameter to POST /v1/default/banks/{bank_id}/mental-models/{mental_model_id}/refresh:
POST /v1/default/banks/my-bank/mental-models/abc123/refresh?mode=full
- Accepts
"full" or "delta"
- Overrides stored
trigger.mode for that single refresh only
- No parameter = current behavior (use stored trigger mode)
Suggested Implementation
Thread the override through the async task pipeline:
# api/http.py — add query param
async def api_refresh_mental_model(
bank_id: str,
mental_model_id: str,
mode: str | None = Query(None, description="Override refresh mode for this refresh"),
...
):
result = await app.state.memory.submit_async_refresh_mental_model(
bank_id=bank_id,
mental_model_id=mental_model_id,
mode_override=mode,
request_context=request_context,
)
# engine/memory_engine.py — submit stores it in task payload
async def submit_async_refresh_mental_model(self, ..., mode_override: str | None = None, ...):
task_dict = {
"bank_id": bank_id,
"mental_model_id": mental_model_id,
"mode_override": mode_override,
...
}
# engine/memory_engine.py — handler passes it through
async def _handle_refresh_mental_model(self, task_dict):
}
# engine/memory_engine.py — handler passes it through
async def _handle_refresh_mental_model(self, task_dict):
refreshed = await self.refresh_mental_model(
bank_id=bank_id,
mental_model_id=mental_model_id,
mode_override=task_dict.get("mode_override"),
request_context=internal_context,
)
# engine/memory_engine.py:7586 — one-line change
refresh_mode = mode_override or trigger_data.get("mode") or "full"
Alternatives Considered
-
Toggle source_query trailing space — current workaround. Mutates stored state for a side effect. Leaves invisible whitespace in the
model. Requires the caller to understand Hindsight's internal delta-bypass logic.
-
Patch trigger.mode to "full", refresh, patch back to "delta" — three API calls, race window where the model is misconfigured, and a
consolidation-triggered refresh during that window would also be full (unintended).
-
Delete + recreate the mental model — loses version history, resets created_at, triggers a fresh async initial refresh instead of a
synchronous controlled one.
All three work but leak implementation details to the caller. A first-class mode parameter is the minimal, non-breaking addition that makes
them unnecessary.
Priority
Important - affects my workflow
Additional Context
No response
Checklist
Use Case
Periodic compaction of delta-mode reflections. Over time, incremental delta refreshes accumulate drift — small inaccuracies compound as each refresh only sees new facts since the last. A scheduled full re-synthesis every 48h produces a clean baseline from all facts.
Without this parameter, the only workaround is toggling a trailing space on
source_querybefore each refresh to force alast_refreshed_source_querymismatch — a fragile hack that mutates model state for a side effect.Problem Statement
There's no way to force a full (non-delta) refresh on a delta-mode mental model via the API. The only workaround is mutating
source_queryto create a mismatch withlast_refreshed_source_query, which forcesuse_delta = Falseon the next refresh.This is needed for periodic compaction — delta refreshes accumulate drift over time, and callers want to trigger a clean full re-synthesis without permanently changing the model's trigger configuration.
How This Feature Would Help
Proposed Solution
Add an optional
modequery parameter toPOST /v1/default/banks/{bank_id}/mental-models/{mental_model_id}/refresh:POST /v1/default/banks/my-bank/mental-models/abc123/refresh?mode=full
"full"or"delta"trigger.modefor that single refresh onlySuggested Implementation
Thread the override through the async task pipeline:
Alternatives Considered
Toggle
source_querytrailing space — current workaround. Mutates stored state for a side effect. Leaves invisible whitespace in themodel. Requires the caller to understand Hindsight's internal delta-bypass logic.
Patch
trigger.modeto "full", refresh, patch back to "delta" — three API calls, race window where the model is misconfigured, and aconsolidation-triggered refresh during that window would also be full (unintended).
Delete + recreate the mental model — loses version history, resets
created_at, triggers a fresh async initial refresh instead of asynchronous controlled one.
All three work but leak implementation details to the caller. A first-class
modeparameter is the minimal, non-breaking addition that makesthem unnecessary.
Priority
Important - affects my workflow
Additional Context
No response
Checklist