mirror of
https://github.com/moltbot/moltbot.git
synced 2026-05-07 07:58:36 +00:00
fix(control-ui): preserve optimistic messages on empty history
This commit is contained in:
@@ -76,6 +76,7 @@ Docs: https://docs.openclaw.ai
|
||||
- ACP: wait for the configured runtime backend to become healthy before startup identity reconciliation, avoiding transient acpx warnings during Gateway boot. Fixes #40566.
|
||||
- Channels/ACP bindings: time out configured binding readiness checks instead of letting Discord preflight hang forever when an ACP target never settles. Fixes #68776.
|
||||
- Control UI: hide the chat loading skeleton during background history reloads when existing messages or active stream content are already visible, avoiding reload flashes on high-latency local gateways. Fixes #71844. Thanks @WolvenRA.
|
||||
- Control UI: keep locally optimistic chat messages visible when a history reload temporarily returns empty, avoiding lost first-turn messages on high-latency gateways. Fixes #71878. Thanks @WolvenRA.
|
||||
- Agents/images: scrub old `[media attached: ...]`, `[Image: source: ...]`,
|
||||
and `media://inbound/...` markers from pruned model replay context so stale
|
||||
media refs are not rehydrated as fresh prompt images. Fixes #71868. Thanks
|
||||
|
||||
@@ -818,6 +818,33 @@ describe("loadChatHistory", () => {
|
||||
expect(state.chatStream).toBeNull();
|
||||
});
|
||||
|
||||
it("keeps local optimistic messages when history reload returns empty", async () => {
|
||||
const optimisticUser = {
|
||||
role: "user",
|
||||
content: [{ type: "text", text: "first ask" }],
|
||||
timestamp: 10,
|
||||
};
|
||||
const optimisticAssistant = {
|
||||
role: "assistant",
|
||||
content: [{ type: "text", text: "first answer" }],
|
||||
timestamp: 11,
|
||||
};
|
||||
const request = vi.fn().mockResolvedValue({
|
||||
messages: [],
|
||||
thinkingLevel: "low",
|
||||
});
|
||||
const state = createState({
|
||||
connected: true,
|
||||
client: { request } as unknown as ChatState["client"],
|
||||
chatMessages: [optimisticUser, optimisticAssistant],
|
||||
});
|
||||
|
||||
await loadChatHistory(state);
|
||||
|
||||
expect(state.chatMessages).toEqual([optimisticUser, optimisticAssistant]);
|
||||
expect(state.chatStream).toBeNull();
|
||||
});
|
||||
|
||||
it("does not duplicate optimistic tail messages after history catches up", async () => {
|
||||
const optimisticUser = {
|
||||
role: "user",
|
||||
|
||||
@@ -268,9 +268,17 @@ function preserveOptimisticTailMessages(
|
||||
historyMessages: unknown[],
|
||||
previousMessages: unknown[],
|
||||
): unknown[] {
|
||||
if (historyMessages.length === 0 || previousMessages.length === 0) {
|
||||
if (previousMessages.length === 0) {
|
||||
return historyMessages;
|
||||
}
|
||||
if (historyMessages.length === 0) {
|
||||
const optimisticMessages = previousMessages.filter(
|
||||
(message) => isLocallyOptimisticHistoryMessage(message) && !shouldHideHistoryMessage(message),
|
||||
);
|
||||
return optimisticMessages.length === previousMessages.length
|
||||
? previousMessages
|
||||
: historyMessages;
|
||||
}
|
||||
const historySignatures = new Set(
|
||||
historyMessages
|
||||
.map((message) => messageDisplaySignature(message))
|
||||
|
||||
Reference in New Issue
Block a user