fix(mobile): isolate image echo occurrences by count

(cherry picked from commit c51e8e6bbb)
This commit is contained in:
Brennan Benson
2026-08-16 12:02:57 -07:00
parent e2450ab9db
commit 40f4240389
2 changed files with 46 additions and 1 deletions
@@ -198,4 +198,46 @@ describe('mobile literal image-marker turns', () => {
['file:///a.jpg', 'file:///b.jpg', 'file:///c.jpg']
])
})
it('reconciles rapid equal captions in separate image-count namespaces', async () => {
await mount()
send('compare', ['file:///a.jpg'])
send('compare', ['file:///b.jpg', 'file:///c.jpg', 'file:///d.jpg'])
const messages = [
userTextMessage('source-a', '[Image: source: /tmp/a.png]'),
userTextMessage('prompt-a', 'compare [Image #1]'),
userTextMessage('source-b', '[Image: source: /tmp/b.png]'),
userTextMessage('source-c', '[Image: source: /tmp/c.png]'),
userTextMessage('source-d', '[Image: source: /tmp/d.png]'),
userTextMessage('prompt-b', 'compare [Image #1] [Image #2] [Image #3]')
]
await transcript(messages)
const rendered = rows(messages)
expect(rendered).toHaveLength(2)
expect(rendered.map(rowImages)).toEqual([
['file:///a.jpg'],
['file:///b.jpg', 'file:///c.jpg', 'file:///d.jpg']
])
})
it('reconciles rapid captionless sends in separate image-count namespaces', async () => {
await mount()
send('', ['file:///a.jpg'])
send('', ['file:///b.jpg', 'file:///c.jpg', 'file:///d.jpg'])
const messages = [
userTextMessage('prompt-a', '[Image #1]'),
userTextMessage('prompt-b', '[Image #1] [Image #2] [Image #3]')
]
await transcript(messages)
const rendered = rows(messages)
expect(rendered).toHaveLength(2)
expect(rendered.map(rowImages)).toEqual([
['file:///a.jpg'],
['file:///b.jpg', 'file:///c.jpg', 'file:///d.jpg']
])
})
})
@@ -52,13 +52,16 @@ export function appendMobileNativeChatPending(
const earlierOutstanding = current.filter(
(pending) =>
pendingMatchText(pending) === origin.normalizedText &&
(pending.images?.length ?? 0) >= origin.imageCount &&
pending.expectedOccurrence > origin.baselineOccurrences
).length
// An image send whose caption is only markers still reconciles by image
// ordinal, matching how `captureSendOrigin` normalized it.
const expectedImageEchoOrdinal =
current.filter(
(pending) => pending.images?.length && normalizeNativeChatUserText(pending.text) === ''
(pending) =>
(pending.images?.length ?? 0) >= origin.imageCount &&
normalizeNativeChatUserText(pending.text) === ''
).length + 1
return {
...previous,