Prefs: owner defaults — model, backend, persona_id, reel span/length (new columns) #127
Notifications
Due Date
No due date set.
Depends on
Reference: Apps/ImageApi#127
Reference in new issue
Block a user
Part of #113
What to build
Second wave of the prefs surface (#126 built the endpoints over the existing
columns; this adds the recurring per-user picks that are currently
re-sent on every request). One migration grows
user_ai_prefs, and theexisting
PUT /prefs/GET /prefssurface exposes the new fields with thesame partial-update semantics.
New columns on
user_ai_prefs(all nullable — NULL = keep the currentper-request/default behavior):
default_model— last/explicit choice for insight + chat model(local id or OpenRouter id).
default_backend—"local"|"hybrid".default_persona_id— active persona for persona chat (currentlyhard-defaults to
"default").reel_span—"day"|"week"|"month".reel_max_segments—i32.Resolution order on every consumer that accepts these per request:
request param → stored pref → current hard default. The per-request
knobs stay per-request — sampling params (temperature/top_p/top_k/min_p),
system_prompt,num_ctx,max_iterations,enable_thinking,amenddeliberately do NOT become prefs (ephemeral or per-object).
Where the pref is consulted: insight generation (model/backend), persona
chat turn (persona), reel creation (span/max_segments). Capture: either an
explicit "save as default" flag on the create request, or the PUT /prefs
surface (client's choice — the FV settings page owns it); do not silently
overwrite a stored pref on every reel request (that's what
capture_prefsdoes for the existing columns today and is fine there because those fields
were always "last value wins"; the model/backend pick is different — an
experiment with a hybrid model must not clobber the stored default).
Acceptance criteria
GET /prefsreturns the new fields;PUT /prefspartial-update semanticsapply identically (omitted = unchanged, explicit null = cleared).
default_backendvalidated against the known backend names; invalid → 400.Blocked by
Implemented on
feature/prefs-owner-defaults— PR #129.Five nullable owner-default columns on
user_ai_prefs(default_model,default_backend,default_persona_id,reel_span,reel_max_segments), exposed through the existingGET/PUT /prefssurface with the same three-state partial-update semantics (omitted = unchanged, null = clear, value = set). Resolution order at every consumer: request param → stored pref → hard default — insight generation (standard + agentic), all three chat-turn variants (model/backend/persona), and reel creation (span/max_segments viaresolve_reel_params).Notable:
capture_prefs(reel passive mirror) now reads the existing row and carries the AI owner-defaults through unchanged — the upsert overwrites all columns, so the original shape would have wiped the owner defaults on every reel creation. Regression-tested. Validation runs before any write and delegates to the canonicalBackendKind::parse.1463/0 tests (+27 vs master), clippy clean, two-axis subagent review: spec all-conformant, standards zero findings.
Cross-client audit (FileViewer-React, subagent, read-only): SAFE-WITH-CAVEATS.