feat(mental-models): cron-scheduled refresh via the maintenance loop#2377
Draft
nicoloboschi wants to merge 1 commit into
Draft
feat(mental-models): cron-scheduled refresh via the maintenance loop#2377nicoloboschi wants to merge 1 commit into
nicoloboschi wants to merge 1 commit into
Conversation
Mental models could be refreshed two ways: automatically after consolidation (trigger.refresh_after_consolidation) or manually via the refresh endpoint. This adds a third, independent path — refresh on a cron schedule — reusing the existing background MaintenanceLoop ticker. - New trigger.refresh_cron field (UTC, 5-field cron) on MentalModelTrigger, validated with croniter. - New PG-only discovery routine public.mental_models_with_cron() that returns cron-scheduled models across all tenant schemas in one round-trip and excludes models with an in-flight refresh (mirrors banks_needing_consolidation; EXCEPTION-guarded against vanished schemas). - MaintenanceLoop._run_scheduled_mm_refresh: evaluates cron due-ness in Python (cron arithmetic isn't expressible in SQL), then refreshes a due model only when it is stale (new memories in scope since last refresh), so a scheduled tick never burns an LLM call on unchanged content. - New static config HINDSIGHT_API_MENTAL_MODEL_REFRESH_TICK_SECONDS (the check cadence; 0 disables). Disabled by default in tests. Regenerated OpenAPI + clients; synced the control-plane trigger type.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a third, independent way to refresh a mental model: on a cron schedule, alongside the existing auto (
trigger.refresh_after_consolidation) and manual (POST .../refresh) paths. Uses the existing backgroundMaintenanceLoopticker — no new worker process.Why
Today a mental model only refreshes when consolidation runs or when someone calls the endpoint by hand. For models that should track a slowly-changing corpus, a fixed cadence ("rebuild this every night at 03:00") is the natural trigger.
How
refresh_cron: str | NoneonMentalModelTrigger(UTC, standard 5-field cron), validated withcroniter. Independent ofrefresh_after_consolidation.public.mental_models_with_cron()(migrationf4d1c2b3a5e6) returns every cron-scheduled model across all tenant schemas in one round-trip, excluding models that already have arefresh_mental_modelop in flight. Mirrorsbanks_needing_consolidationand isEXCEPTION-guarded against schemas that vanish mid-scan (likec7e9f1a3b5d2).MaintenanceLoop._run_scheduled_mm_refreshevaluates cron due-ness in Python (cron arithmetic isn't expressible in plain SQL: a fire is due when the most recent cron boundary at/before now is later thanlast_refreshed_at), then refreshes a due model only when it is stale (new memories in its scope since the last refresh). A schedule that fires while nothing changed costs a cheap staleness query, not an LLM call.HINDSIGHT_API_MENTAL_MODEL_REFRESH_TICK_SECONDS(the check cadence; the schedule itself is per-model;0disables). Disabled by default in the test suite.All three refresh paths converge on the existing
refresh_mental_modelasync op — no new worker handler.Tests
tests/test_mental_model_scheduled_refresh.py(deterministic, no LLM):refresh_cronround-trips through create → get.Plumbing
triggertype inlib/api.ts.configuration.md(follows theRECONCILE_INTERVAL_SECONDSprecedent of documenting server-static maintenance knobs there rather than in.env.example).Notes for reviewers
last_refreshed_atonly advances on an actual refresh.