fix(chat): give every backend-tagged system event its own timeline chip (#936)

System events ride as role=user rows with a display_kind sidecar (backend
issues #904/#82888). The full-bleed renderer routes any displayKind != null
to a SystemEvent, but timelineMarkerLabelRes only had labels for
model_switch / personality_switch / auto_continue / async_delegation_complete.
skill_invocation and internal_notification had NO label, so TimelineMarkerChip
returned early and they fell through to the bare SystemBubble (centered italic
text, no clear system identity) instead of a distinct chip.

- Add skill_invocation + internal_notification to timelineMarkerLabelRes.
- Add string resources en/zh/ko (ko was missing all timeline markers; added
  the two new ones for parity).
- TimelineMarkerTest: assert both new kinds map to labels.

Result: every backend system message type now renders as its own centered
timeline chip, never as a user bubble. Legacy sessions persisted before the
backend added display_kind tagging still lack the sidecar and would need a
one-time backend re-tag to stop rendering as user bubbles.

Co-authored-by: M57 <hy4ri@users.noreply.github.com>
This commit is contained in:
M57andM57 authored and GitHub committed 2026-08-18 17:32:26 +03:00
1 parent 82e2d787af
commit 0d1b4fee11
5 files changed
+16

No files matched your search

@@ -28,6 +28,8 @@ internal fun timelineMarkerLabelRes(kind: String?): Int? =
"personality_switch" -> R.string.timeline_marker_personality_switch
"auto_continue" -> R.string.timeline_marker_auto_continue
"async_delegation_complete" -> R.string.timeline_marker_delegation_complete
"skill_invocation" -> R.string.timeline_marker_skill_invocation
"internal_notification" -> R.string.timeline_marker_internal_notification
else -> null
}
+2
View File
@@ -752,4 +752,6 @@
<string name="image_viewer_save_failed">이미지를 저장할 수 없음</string>
<string name="image_viewer_load_failed">이미지를 불러올 수 없음: %1$s</string>
<string name="image_viewer_share_failed">이미지를 공유할 수 없음</string>
<string name="timeline_marker_skill_invocation">스킬 호출됨</string>
<string name="timeline_marker_internal_notification">시스템 알림</string>
</resources>
+2
View File
@@ -979,6 +979,8 @@
<string name="timeline_marker_personality_switch">人格已切换</string>
<string name="timeline_marker_auto_continue">回合已自动继续</string>
<string name="timeline_marker_delegation_complete">委派任务已完成</string>
<string name="timeline_marker_skill_invocation">技能已调用</string>
<string name="timeline_marker_internal_notification">系统通知</string>
<string name="message_your_response">你的回复</string>
<string name="moa_add_preset">添加预设</string>
<string name="moa_add_reference">添加参考模型</string>
+2
View File
@@ -1102,6 +1102,8 @@
<string name="timeline_marker_personality_switch">Personality switched</string>
<string name="timeline_marker_auto_continue">Turn auto-continued</string>
<string name="timeline_marker_delegation_complete">Delegated task completed</string>
<string name="timeline_marker_skill_invocation">Skill invoked</string>
<string name="timeline_marker_internal_notification">System notification</string>
<string name="message_your_response">Your response</string>
<string name="moa_add_preset">Add preset</string>
<string name="moa_add_reference">Add reference model</string>
@@ -18,6 +18,14 @@ class TimelineMarkerTest {
R.string.timeline_marker_delegation_complete,
timelineMarkerLabelRes("async_delegation_complete"),
)
assertEquals(
R.string.timeline_marker_skill_invocation,
timelineMarkerLabelRes("skill_invocation"),
)
assertEquals(
R.string.timeline_marker_internal_notification,
timelineMarkerLabelRes("internal_notification"),
)
}
@Test