Files
aiturk-mobil/app
M57andM57 caed4db316 fix(chat): route ALL synthetic backend user rows to system events (#937)
The backend persists a whole class of internal scaffolding as plain
role=user rows with NO display_kind (SessionDB strips underscore metadata):
runtime nudges (max tool-call iterations), context injections ([System:/[CONTEXT/
[PRIOR CONTEXT), background/cron/delegation notices ([IMPORTANT: Background/
Cronjob Response:/[ASYNC DELEGATION), out-of-band markers ([OUT-OF-BAND), and
todo/planning injections ([Your active task list/[Planning state preserved).
These are NOT real human turns, but the mobile rendered them as user bubbles.

Mirror the backend's own synthetic-detection contract
(agent.context_compressor._synthetic_user_row) with a prefix map. Any role=user
row with no display_kind that starts with a known synthetic prefix is routed to
a SystemEvent instead of a user turn. The 90-calls nudge maps to a specific
"Reached tool-call limit" chip; the rest map to a generic "System notice" chip.
Real user messages (no synthetic prefix) are unaffected.

- FullBleedTurns: SYNTHETIC_USER_PREFIX_KINDS map + syntheticSystemKind() that
  tags matched rows so the timeline chip can name them.
- timelineMarkerLabelRes: max_iterations_reached + system_notice labels.
- Strings en/zh/ko for both.
- Tests: assert the new labels map; assert every synthetic prefix routes to a
  SystemEvent (not a user turn); assert a real user message stays a user turn.

The display_kind-tagged events (model/personality switches, auto-continue,
delegation complete, skill invocation, internal notification) are already
handled separately (PR #936, merged).

ktlint + Android Lint + unit tests green locally.

Co-authored-by: M57 <hy4ri@users.noreply.github.com>
2026-08-18 19:04:44 +03:00
..