mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 17:17:38 +00:00
* fix(native-chat): list not-sent rows at their journal places The shared projection appended rows the host recorded but never delivered after every other row, leaving the reader to sort them. A reader that draws the list as given showed an old not-sent message under newer turns. Merge them in at their journal places, after the stop rows are built, so the list is already in order. The desktop sorts by the same order, so what it draws is unchanged. * refactor(native-chat): move the recorded-rejection line into shared words The desktop's words for a message the host recorded and then rejected now live beside the other rejection words, returning notice parts each client renders its own way, so the phone can say the same thing. The desktop calls it with the same inputs; its words are unchanged. * refactor(native-chat): one projection behaviour for rejected rows Every reader now draws a message the host recorded and then rejected where it was sent, marked not sent, so the rejectedInPlace option goes. The phone was its last off caller apart from the host's conversation outline, which now leaves not-sent rows out itself; a test proves the outline is the same as if the rejected message had never been sent. * fix(mobile): show a not-sent message in place with the reason under it The phone now draws a message the host recorded and then rejected where it was sent, as the desktop does, with one small line under the bubble in the desktop's words. The line is built from the journal the view already receives; when a start-failure or sign-in row already gives the reason, it says only that the message was not sent. The load-earlier header moves to its own file to keep the view under its line limit. * fix(mobile): a send the host recorded is never handed back When the send's own reply said the host recorded the message and then rejected it, the phone put the text back in the composer with a banner, though the host and the desktop keep it in the chat. A recorded send now settles like any other: its row draws it in place as not sent (or its kept card holds it), and the composer stays empty. The banner's failure-fact plumbing, fed only by that branch, goes with it; the transcript states the sign-in guidance once. * fix(mobile): keep each structured send on the shared optimistic list Once a not-sent row stays in the chat, matching a pending bubble by its text breaks: resending the same words after a not-sent message never reached the count the bubble waited for, so a stray copy stayed, and an acknowledgement lost on that resend showed a false "Delivery unconfirmed". A structured send is now one record, kept by the structured session under the id it is sent with. Three parts match the desktop's sender: the id, the drawing (the shared projection draws it at the tail until the host's row under that id lands, in the same pass) and the settle rule (the host's own record of it, a submission, a card, or a card's hand-off, drops it by the one rule the desktop now shares). The rest stays the phone's own: the bubble shows once the host accepts the send, not from the tap; a send whose answer was lost is held undrawn and says "Delivery unconfirmed" only if its deadline passes first, instead of going back to the composer; records are kept whether or not a chat view is open; and one send in flight is the composer's rule, not the sender's. Its photo is kept under the row id it shares with the host's row, so it shows on the bubble, the landed row and a not-sent row. The drafts' text matching, with its older queued-card matching, now serves only terminal-backed chats, whose transcripts carry no ids. * fix(native-chat): merge not-sent rows by the transcript order alone The merge kept a rule for rows with no journal place that no caller reaches and that the desktop's sort does not have; drop it, and say what merging after the stop rows actually keeps. A test pins that the list the phone draws as given is already in the desktop's sorted order, with a moved stop row, a retry run, a cut-turn notice, a held card and two not-sent rows. * fix(mobile): draw the not-sent line as the desktop does Red and capped to the bubble's width, like the desktop's line and the phone's own returned-card caption, and only when there is a notice: the row had a second, unreachable source of words. A send a Stop took back is no failure, so it no longer rebuilds the notices on every streaming frame.
30 lines
1.1 KiB
TypeScript
30 lines
1.1 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import type { AgentJournalSubmission } from './agent-session-journal-types'
|
|
import { structuredAgentSessionSettledSends } from './structured-agent-session-send-settlement'
|
|
|
|
function submission(clientMessageId: string, queuedMessageId?: string): AgentJournalSubmission {
|
|
return {
|
|
clientMessageId,
|
|
...(queuedMessageId ? { queuedMessageId } : {}),
|
|
fence: 1,
|
|
payloadFingerprint: clientMessageId,
|
|
dispatchState: 'accepted',
|
|
providerItemId: null,
|
|
reason: null,
|
|
submittedAt: 1,
|
|
resolvedAt: 1
|
|
}
|
|
}
|
|
|
|
describe('structuredAgentSessionSettledSends', () => {
|
|
it('reads a send as a card while queued or once handed off, else as recorded under its id', () => {
|
|
const handOff = submission('hand-off', 'was-queued')
|
|
const sent = submission('sent')
|
|
const { cards, recorded } = structuredAgentSessionSettledSends([handOff, sent], ['on-queue'])
|
|
expect([...cards]).toEqual(['on-queue', 'was-queued'])
|
|
expect(recorded.get('sent')).toBe(sent)
|
|
expect(recorded.get('hand-off')).toBe(handOff)
|
|
expect(recorded.has('on-queue')).toBe(false)
|
|
})
|
|
})
|