fix(chat): stabilize message identities

This commit is contained in:
2026-07-20 18:30:21 +08:00
parent 159e8bfd59
commit 1e13f94b5d
33 changed files with 718 additions and 212 deletions
@@ -46,6 +46,7 @@ export const loadHistoryActor = fromCallback<
const cacheIdentity = await resolveHistoryCacheIdentity(input.characterId);
const localSnapshot = await readLocalHistorySnapshot(
cacheIdentity,
input.characterId,
input.emptyChatGreeting,
);
if (cancelled) return;
@@ -57,6 +58,7 @@ export const loadHistoryActor = fromCallback<
const networkSnapshot = await syncNetworkHistory(
input.characterId,
localSnapshot.localCount,
localSnapshot.messages.map((message) => message.displayId),
cacheIdentity,
input.emptyChatGreeting,
controller.signal,
+6
View File
@@ -9,6 +9,7 @@ import {
finishPendingReply,
type HttpSendOutput,
} from "../helper/send-state";
import { createClientUiMessageIdentity } from "../ui-message";
import { historyMachineSetup } from "./history-flow";
import { createChatActorActionSetup } from "./setup";
@@ -36,6 +37,7 @@ const appendGuestUserMessageAction = historyMachineSetup.assign(
messages: [
...context.messages,
{
...createClientUiMessageIdentity("message"),
content: event.content,
isFromAI: false,
date: today,
@@ -63,6 +65,7 @@ const appendUserMessageAction = historyMachineSetup.assign(
messages: [
...context.messages,
{
...createClientUiMessageIdentity("message"),
content: event.content,
isFromAI: false,
date: today,
@@ -83,6 +86,7 @@ const appendQueuedSendErrorMessageAction = historyMachineSetup.assign(
const messages = [
...context.messages,
{
...createClientUiMessageIdentity("error"),
content: unavailable
? "This character is temporarily unavailable. Please try again shortly."
: "Something went wrong. Try sending again?",
@@ -135,6 +139,7 @@ const appendGuestUserImageAction = historyMachineSetup.assign(
messages: [
...context.messages,
{
...createClientUiMessageIdentity("image"),
content: "[Image]",
isFromAI: false,
date: today,
@@ -162,6 +167,7 @@ const appendUserImageAction = historyMachineSetup.assign(
messages: [
...context.messages,
{
...createClientUiMessageIdentity("image"),
content: "[Image]",
isFromAI: false,
date: today,
+2 -1
View File
@@ -157,7 +157,8 @@ const userReadyState = chatMachineSetup.createStateConfig({
actions: "appendUserImage",
},
ChatUnlockMessageRequested: {
guard: ({ event }) => event.messageId.trim().length > 0,
guard: ({ event }) =>
event.displayMessageId.trim().length > 0,
target: "unlockingMessage",
actions: "markUnlockMessageStarted",
},
+9 -8
View File
@@ -45,12 +45,12 @@ const markUnlockHistoryFailedAction = sendMachineSetup.assign(() => ({
const markUnlockMessageStartedAction = sendMachineSetup.assign(
({ event }) => {
if (event.type !== "ChatUnlockMessageRequested") return {};
const remoteMessageId =
event.remoteMessageId ?? (event.lockType ? undefined : event.messageId);
return {
unlockingMessage: {
displayMessageId: event.messageId,
...(remoteMessageId ? { messageId: remoteMessageId } : {}),
displayMessageId: event.displayMessageId,
...(event.remoteMessageId
? { messageId: event.remoteMessageId }
: {}),
kind: event.kind,
...(event.lockType ? { lockType: event.lockType } : {}),
...(event.clientLockId
@@ -90,8 +90,7 @@ const requestUnlockPaymentFromOutputAction = sendMachineSetup.assign(
unlockMessageError: output.response.reason,
unlockPaywallRequest: shouldOpenPaywall
? {
displayMessageId:
output.response.messageId || output.displayMessageId,
displayMessageId: output.displayMessageId,
...(output.response.messageId || output.request.messageId
? {
messageId:
@@ -105,7 +104,8 @@ const requestUnlockPaymentFromOutputAction = sendMachineSetup.assign(
...(output.request.clientLockId
? { clientLockId: output.request.clientLockId }
: {}),
...(context.promotion?.message.id === output.displayMessageId
...(context.promotion?.message.displayId ===
output.displayMessageId
? { promotion: context.promotion.session }
: {}),
reason: output.response.reason,
@@ -130,7 +130,8 @@ const requestUnlockPaymentFromErrorAction = sendMachineSetup.assign(
unlockPaywallRequest: request
? {
...request,
...(context.promotion?.message.id === request.displayMessageId
...(context.promotion?.message.displayId ===
request.displayMessageId
? { promotion: context.promotion.session }
: {}),
reason: "unlock_failed",