diff --git a/mobile/src/session/mobile-agent-message-attribution.test.ts b/mobile/src/session/mobile-agent-message-attribution.test.ts index 371758a525f..41c74205f78 100644 --- a/mobile/src/session/mobile-agent-message-attribution.test.ts +++ b/mobile/src/session/mobile-agent-message-attribution.test.ts @@ -49,8 +49,7 @@ describe('who another agent’s message is from, on mobile', () => { }, { messageId: 'person', position: 2, state: 'waiting', body } ], - [], - { pendingPrompt: false } + [] ) expect(cards.map((card) => card.attribution)).toEqual(['From Coder', null]) }) diff --git a/mobile/src/session/mobile-structured-queued-message-cards.test.ts b/mobile/src/session/mobile-structured-queued-message-cards.test.ts index ce3eda3c57b..5f49f8e8571 100644 --- a/mobile/src/session/mobile-structured-queued-message-cards.test.ts +++ b/mobile/src/session/mobile-structured-queued-message-cards.test.ts @@ -41,7 +41,7 @@ describe('mobileQueuedMessageCards', () => { const [card] = mobileQueuedMessageCards( [draft({ messageId: 'auth', ...returnedAs(agentSessionFailureFact('notSignedIn')) })], [], - { pendingPrompt: false, agentName } + { agentName } ) expect(card?.caption).toContain(agentName) expect(card?.caption).toContain(guidance) @@ -54,12 +54,11 @@ describe('mobileQueuedMessageCards', () => { (agentName) => { const fact = agentSessionFailureFact('notSignedIn', { account: 'managed' }) const drafts = [draft({ messageId: 'auth', ...returnedAs(fact) })] - const [card] = mobileQueuedMessageCards(drafts, [], { pendingPrompt: false, agentName }) + const [card] = mobileQueuedMessageCards(drafts, [], { agentName }) expect(card?.caption).toBe( `This ${agentName} account isn't signed in. Sign in again in ${agentName} Accounts settings.` ) const [stated] = mobileQueuedMessageCards(drafts, [], { - pendingPrompt: false, agentName, statedFailures: [fact] }) @@ -80,14 +79,13 @@ describe('mobileQueuedMessageCards', () => { } }) ], - [], - { pendingPrompt: false } + [] ) expect(card).toMatchObject({ text: '/compact', command: true, caption: null }) expect(card).not.toHaveProperty('waitsForAgent') - expect( - mobileQueuedMessageCards([draft({ messageId: 'a' })], [], { pendingPrompt: false })[0] - ).not.toHaveProperty('command') + expect(mobileQueuedMessageCards([draft({ messageId: 'a' })], [])[0]).not.toHaveProperty( + 'command' + ) const compact = draft({ messageId: 'c', body: { @@ -97,9 +95,10 @@ describe('mobileQueuedMessageCards', () => { command: { name: 'compact' } } }) - expect( - mobileQueuedMessageCards([compact], [], { pendingPrompt: false, agentWorking: true })[0] - ).toMatchObject({ command: true, waitsForAgent: true }) + expect(mobileQueuedMessageCards([compact], [], { agentWorking: true })[0]).toMatchObject({ + command: true, + waitsForAgent: true + }) }) it("a send-failed command card's caption names Send only when Send is there", () => { @@ -114,24 +113,22 @@ describe('mobileQueuedMessageCards', () => { command: { name: 'compact' } } }) - expect( - mobileQueuedMessageCards([failed], [], { pendingPrompt: false, agentWorking: true })[0] - ?.caption - ).toBe("Couldn't send — tap Send to retry once the agent finishes") - expect(mobileQueuedMessageCards([failed], [], { pendingPrompt: false })[0]?.caption).toBe( + expect(mobileQueuedMessageCards([failed], [], { agentWorking: true })[0]?.caption).toBe( + "Couldn't send — tap Send to retry once the agent finishes" + ) + expect(mobileQueuedMessageCards([failed], [])[0]?.caption).toBe( "Couldn't send — tap Send to retry" ) }) it('renders nothing without a published list', () => { - expect(mobileQueuedMessageCards(null, [], { pendingPrompt: false })).toEqual([]) - expect(mobileQueuedMessageCards([], [], { pendingPrompt: false })).toEqual([]) + expect(mobileQueuedMessageCards(null, [])).toEqual([]) + expect(mobileQueuedMessageCards([], [])).toEqual([]) }) + // The card knows no open question or paused queue: the question and the pause row say why. it('captions nothing on a plain waiting draft, as the desktop row', () => { - const [card] = mobileQueuedMessageCards([draft({ messageId: 'a' })], [], { - pendingPrompt: false - }) + const [card] = mobileQueuedMessageCards([draft({ messageId: 'a' })], []) expect(card).toEqual({ messageId: 'a', text: 'body of a', @@ -143,31 +140,13 @@ describe('mobileQueuedMessageCards', () => { }) }) - it('captions a waiting draft behind a pending prompt', () => { - const [card] = mobileQueuedMessageCards([draft({ messageId: 'a' })], [], { - pendingPrompt: true - }) - expect(card?.caption).toBe('Waiting for your answer') - }) - - it('captions nothing on a waiting card of a paused queue; its pause row explains', () => { - const [card] = mobileQueuedMessageCards([draft({ messageId: 'a' })], [], { - pendingPrompt: false, - queuePaused: true - }) - expect(card?.caption).toBeNull() - expect(card?.paused).toBe(false) - expect(card?.needsAttention).toBe(false) - }) - - it("keeps a card's own failed send and reads a prompt's wait as queued under a paused queue", () => { + it("keeps a card's own failed send beside a plainly queued one", () => { const cards = mobileQueuedMessageCards( [ draft({ messageId: 'a', paused: true, pausedReason: QUEUED_MESSAGE_PAUSED_SEND_FAILED }), draft({ messageId: 'b', position: 2 }) ], - [], - { pendingPrompt: true, queuePaused: true } + [] ) expect(cards.map((card) => card.caption)).toEqual(["Couldn't send — tap Send to retry", null]) expect(cards[0]?.paused).toBe(true) @@ -175,9 +154,7 @@ describe('mobileQueuedMessageCards', () => { it('finds something for Resume to send only in a waiting card with no hold, ahead of a returned one', () => { const resumable = (drafts: AgentSessionQueuedMessage[]) => - mobileQueueHasResumableCard( - mobileQueuedMessageCards(drafts, [], { pendingPrompt: false, queuePaused: true }) - ) + mobileQueueHasResumableCard(mobileQueuedMessageCards(drafts, [])) const returned = draft({ messageId: 'r', ...returnedAs(agentSessionFailureFact('hostRestarted')) @@ -205,9 +182,7 @@ describe('mobileQueuedMessageCards', () => { }) it('captions a reasonless pause as a plain pause, promising no release rule', () => { - const [card] = mobileQueuedMessageCards([draft({ messageId: 'a', paused: true })], [], { - pendingPrompt: false - }) + const [card] = mobileQueuedMessageCards([draft({ messageId: 'a', paused: true })], []) expect(card?.caption).toBe('Paused') }) @@ -217,8 +192,7 @@ describe('mobileQueuedMessageCards', () => { }) const cards = mobileQueuedMessageCards( [draft({ messageId: 'a', ...returnedAs(refused) }), draft({ messageId: 'b', position: 2 })], - [], - { pendingPrompt: false } + [] ) expect(cards[0]?.caption).toContain('Steering is unavailable') expect(cards[0]?.state).toBe('returned') @@ -237,8 +211,7 @@ describe('mobileQueuedMessageCards', () => { [ { queuedMessageId: 'returned', dispatchState: 'rejected' }, { queuedMessageId: 'drained', dispatchState: 'pending' } - ], - { pendingPrompt: false } + ] ) expect(cards.map((card) => card.messageId)).toEqual(['returned', 'waiting']) expect(cards[1]?.caption).toBe('Waiting — a message ahead needs attention') @@ -257,8 +230,7 @@ describe('mobileQueuedMessageCards', () => { { queuedMessageId: 'requeued', dispatchState: 'rejected' }, { queuedMessageId: 'sending', dispatchState: 'pending' }, { queuedMessageId: 'sent', dispatchState: 'accepted' } - ], - { pendingPrompt: false } + ] ) expect(cards.map((card) => card.messageId)).toEqual(['requeued']) }) @@ -266,8 +238,7 @@ describe('mobileQueuedMessageCards', () => { it('maps a Stop-withdrawn returned card to its own English copy', () => { const [card] = mobileQueuedMessageCards( [draft({ messageId: 'a', ...returnedAs(agentSessionFailureFact('cancelled')) })], - [], - { pendingPrompt: false } + [] ) expect(card?.caption).toBe('Stopped before it was sent') }) @@ -282,8 +253,7 @@ describe('mobileQueuedMessageCards', () => { returnedRejection: { kind: 'cancelled' } }) ], - [], - { pendingPrompt: false } + [] ) expect(card?.caption).toBe('Stopped before it was sent') }) @@ -291,8 +261,7 @@ describe('mobileQueuedMessageCards', () => { it('words a host-restart returned card from its fact, as a rejected send', () => { const [card] = mobileQueuedMessageCards( [draft({ messageId: 'a', ...returnedAs(agentSessionFailureFact('hostRestarted')) })], - [], - { pendingPrompt: false } + [] ) expect(card?.caption).toBe('Orca restarted before this message was sent.') }) @@ -301,13 +270,7 @@ describe('mobileQueuedMessageCards', () => { const refused = agentSessionFailureFact('providerRejected', { detail: { text: 'stack trace for the log', audience: 'log' } }) - const [card] = mobileQueuedMessageCards( - [draft({ messageId: 'a', ...returnedAs(refused) })], - [], - { - pendingPrompt: false - } - ) + const [card] = mobileQueuedMessageCards([draft({ messageId: 'a', ...returnedAs(refused) })], []) expect(card?.caption).not.toContain('stack trace') }) @@ -321,8 +284,7 @@ describe('mobileQueuedMessageCards', () => { returnedRejection: { kind: 'laterKind' } }) ], - [], - { pendingPrompt: false } + [] ) expect(card?.caption).toBe('Words for a kind a newer host added.') }) @@ -343,8 +305,7 @@ describe('mobileQueuedMessageCards', () => { returnedRejection: newer }) ], - [], - { pendingPrompt: false } + [] ) expect(card?.caption).toBe(reason) }) @@ -357,8 +318,7 @@ describe('mobileQueuedMessageCards', () => { // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: simulates a marker from a newer host than this build's union. draft({ messageId: 'b', position: 2, paused: true, pausedReason: 'later_marker' as never }) ], - [], - { pendingPrompt: false } + [] ) expect(cards.map((card) => card.caption)).toEqual([ "Couldn't send — tap Send to retry", @@ -377,8 +337,7 @@ describe('mobileQueuedMessageCards', () => { returnedReason: DISPATCH_REJECTED_HOST_RESTARTED }) ], - [], - { pendingPrompt: false } + [] ) expect(card?.caption).toBe('Your message was not sent.') }) diff --git a/mobile/src/session/mobile-structured-queued-message-cards.ts b/mobile/src/session/mobile-structured-queued-message-cards.ts index 42883b4ed4d..10be250e254 100644 --- a/mobile/src/session/mobile-structured-queued-message-cards.ts +++ b/mobile/src/session/mobile-structured-queued-message-cards.ts @@ -30,7 +30,8 @@ export type MobileQueuedMessageCard = { paused: boolean /** Returned, or its own send failed: the row leads with an alert. */ needsAttention: boolean - /** Status under the text; null for a card plainly waiting its turn, the paused queue's too. */ + /** Status under the text; null for a card plainly waiting its turn, also behind an open + * question or in a paused queue: the question and the pause row say why. */ caption: string | null /** "From " on another agent's card; null on the person's. */ attribution: string | null @@ -112,12 +113,10 @@ export function mobileQueuedMessageCards( queuedMessages: readonly AgentSessionQueuedMessage[] | null, submissions: readonly Pick[], facts: { - pendingPrompt: boolean - queuePaused?: boolean agentWorking?: boolean agentName?: string statedFailures?: readonly AgentSessionFailureFact[] - } + } = {} ): MobileQueuedMessageCard[] { if (!queuedMessages || queuedMessages.length === 0) { return [] @@ -146,12 +145,7 @@ export function mobileQueuedMessageCards( ) : behindReturned ? 'Waiting — a message ahead needs attention' - : facts.queuePaused - ? // The pause row says why and offers Resume; the card promises no send time. - null - : facts.pendingPrompt - ? 'Waiting for your answer' - : null + : null cards.push({ messageId: draft.messageId, text: queuedMessageBodyText(draft.body), diff --git a/mobile/src/session/use-mobile-structured-agent-session.ts b/mobile/src/session/use-mobile-structured-agent-session.ts index fb3c69c51aa..ceb17230648 100644 --- a/mobile/src/session/use-mobile-structured-agent-session.ts +++ b/mobile/src/session/use-mobile-structured-agent-session.ts @@ -219,7 +219,6 @@ export function useMobileStructuredAgentSession(args: { queuedMessages, queuePause, submissions: state.submissions, - pendingPrompt: approvalPrompt !== null || questionPrompt !== null, agentWorking: isStructuredAgentSessionMainAgentWorking(turnId, state.submissions, state.fence), mutate, appendComposerText, diff --git a/mobile/src/session/use-mobile-structured-queued-message-controls.ts b/mobile/src/session/use-mobile-structured-queued-message-controls.ts index 1a73756841f..e162a8a3013 100644 --- a/mobile/src/session/use-mobile-structured-queued-message-controls.ts +++ b/mobile/src/session/use-mobile-structured-queued-message-controls.ts @@ -55,7 +55,6 @@ export function useMobileStructuredQueuedMessageControls(args: { queuedMessages: MobileQueuedMessageFeed queuePause: MobileQueuePause submissions: readonly AgentJournalSubmission[] - pendingPrompt: boolean /** The chat shows the agent working: a command card offers no send then. */ agentWorking?: boolean mutate: MobileStructuredAgentMutate @@ -71,7 +70,6 @@ export function useMobileStructuredQueuedMessageControls(args: { mutate, onActionResolved, onSendError, - pendingPrompt, queuedMessages, queuePause, sessionKey, @@ -81,23 +79,13 @@ export function useMobileStructuredQueuedMessageControls(args: { const cards = useMemo( () => mobileQueuedMessageCards(queuedMessages, submissions, { - pendingPrompt, agentWorking, agentName: args.agentName, statedFailures: queuedMessages?.some((draft) => draft.state === 'returned') ? agentSessionVisibleFailureFacts(args.journalItems ?? []) - : [], - queuePaused: queuePause !== null + : [] }), - [ - agentWorking, - args.agentName, - args.journalItems, - pendingPrompt, - queuePause, - queuedMessages, - submissions - ] + [agentWorking, args.agentName, args.journalItems, queuedMessages, submissions] ) const resolved = useCallback( (accepted: boolean): boolean => { diff --git a/src/main/native-chat/agent-session-wire/structured-agent-session-queued-card-holds.test.ts b/src/main/native-chat/agent-session-wire/structured-agent-session-queued-card-holds.test.ts index 0feaf809f2a..b6e2fd41a01 100644 --- a/src/main/native-chat/agent-session-wire/structured-agent-session-queued-card-holds.test.ts +++ b/src/main/native-chat/agent-session-wire/structured-agent-session-queued-card-holds.test.ts @@ -151,10 +151,7 @@ async function watchClient(): Promise { const hostWorking = isStructuredAgentSessionMainAgentWorking(running, all) // As use-structured-agent-session.ts derives it. const working = hostWorking || (nextQueuedMessageId !== null && !hostWorking) - const cards = projectQueuedMessageCards(queued, all, { - hasPendingPrompt: false, - queuePaused: queuePause !== null - }) + const cards = projectQueuedMessageCards(queued, all, { queuePaused: queuePause !== null }) // As use-structured-agent-session-queued-messages.ts derives them. const header = queuedMessagesQueuePause(cards, queuePause) !== null const queueHeld = header && !working diff --git a/src/renderer/src/components/native-chat/NativeChatQueuedMessageCard.tsx b/src/renderer/src/components/native-chat/NativeChatQueuedMessageCard.tsx index c372efbe93d..827e825268e 100644 --- a/src/renderer/src/components/native-chat/NativeChatQueuedMessageCard.tsx +++ b/src/renderer/src/components/native-chat/NativeChatQueuedMessageCard.tsx @@ -92,11 +92,6 @@ export function queuedMessageCardCaption( 'components.native-chat.queuedMessages.behindReturnedHold', 'Waiting — a message ahead needs attention' ) - case 'awaiting-answer': - return translate( - 'components.native-chat.queuedMessages.awaitingAnswerHold', - 'Waiting for your answer' - ) case 'sending': return translate('components.native-chat.messageSending', 'Sending…') case 'turn': diff --git a/src/renderer/src/components/native-chat/NativeChatQueuedMessageList.inline-edit.test.tsx b/src/renderer/src/components/native-chat/NativeChatQueuedMessageList.inline-edit.test.tsx index 1b170c031a4..4f209d9e514 100644 --- a/src/renderer/src/components/native-chat/NativeChatQueuedMessageList.inline-edit.test.tsx +++ b/src/renderer/src/components/native-chat/NativeChatQueuedMessageList.inline-edit.test.tsx @@ -120,7 +120,7 @@ describe('NativeChatQueuedMessageList inline edit', () => { const cards = [ card({ messageId: 'mail', - hold: 'awaiting-answer', + hold: 'behind-returned', from: { kind: 'agent', senders: [], orchestration: null } }) ] @@ -128,7 +128,7 @@ describe('NativeChatQueuedMessageList inline edit', () => { const row = screen.getByRole('listitem') expect(within(row).getByText('Editing message')).toBeTruthy() expect(within(row).getByText('From')).toBeTruthy() - expect(within(row).queryByText('Waiting for your answer')).toBeNull() + expect(within(row).queryByText('Waiting — a message ahead needs attention')).toBeNull() fireEvent.click(within(row).getByRole('button', { name: 'Cancel editing' })) expect(editor.cancel).toHaveBeenCalledOnce() rerender( @@ -142,7 +142,7 @@ describe('NativeChatQueuedMessageList inline edit', () => { /> ) - expect(screen.getByText('Waiting for your answer')).toBeTruthy() + expect(screen.getByText('Waiting — a message ahead needs attention')).toBeTruthy() expect(screen.queryByText('Editing message')).toBeNull() }) diff --git a/src/renderer/src/components/native-chat/NativeChatQueuedMessageList.test.tsx b/src/renderer/src/components/native-chat/NativeChatQueuedMessageList.test.tsx index 97ba96c3868..8fe95a5f602 100644 --- a/src/renderer/src/components/native-chat/NativeChatQueuedMessageList.test.tsx +++ b/src/renderer/src/components/native-chat/NativeChatQueuedMessageList.test.tsx @@ -110,7 +110,8 @@ function waitingDraft( * Nothing runs after a Stop or a /clear. */ function renderHeldQueue( queuedMessages: AgentSessionQueuedMessage[], - queuePause: AgentSessionQueuePause | null + queuePause: AgentSessionQueuePause | null, + hasPendingPrompt = false ) { const mutate = vi.fn(async (..._call: [string, string, Record]) => null) function HeldQueue(): React.JSX.Element { @@ -119,7 +120,7 @@ function renderHeldQueue( queuedMessages, queuePause, submissions: [], - hasPendingPrompt: false, + hasPendingPrompt, isWorking: false, composerScopeKey: undefined, // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: the list only awaits mutate; its answer is never read. @@ -472,6 +473,21 @@ describe('NativeChatQueuedMessageList', () => { } ) + it('a card behind an open question shows no caption and keeps its actions', () => { + const { mutate } = renderHeldQueue([waitingDraft('mail', 1)], null, true) + const row = screen.getByRole('listitem') + // The open question below already says the agent waits; the text is the card's only line. + expect(row.querySelectorAll('p')).toHaveLength(1) + expect(within(row).getByRole('button', { name: 'Delete' })).toBeTruthy() + expect(within(row).getByRole('button', { name: 'More actions' })).toBeTruthy() + fireEvent.click(within(row).getByRole('button', { name: 'Steer' })) + expect(mutate).toHaveBeenCalledWith( + 'agentSession.queuedMessageSend', + 'agentSession.queuedMessageSend', + { messageId: 'mail' } + ) + }) + it('a paused queue holds every card, in order, under one header', () => { renderHeldQueue([waitingDraft('a', 1), waitingDraft('b', 2)], { reason: 'stopped' }) expect(screen.getByText('Queue paused because you interrupted')).toBeTruthy() @@ -638,7 +654,7 @@ describe('NativeChatQueuedMessageList', () => { }) it('every card still waiting on the queue reads Steer; one held on its own or returned, Send', () => { - for (const hold of ['turn', 'awaiting-answer', 'behind-returned', 'queue-paused'] as const) { + for (const hold of ['turn', 'behind-returned', 'queue-paused'] as const) { expect(queuedMessageCardSendNow(card({ messageId: hold, hold }))).toEqual({ steers: true, label: 'Steer', diff --git a/src/renderer/src/components/native-chat/structured-agent-session-queued-cards.test.ts b/src/renderer/src/components/native-chat/structured-agent-session-queued-cards.test.ts index 73a3c3ab1be..5653e8f25b1 100644 --- a/src/renderer/src/components/native-chat/structured-agent-session-queued-cards.test.ts +++ b/src/renderer/src/components/native-chat/structured-agent-session-queued-cards.test.ts @@ -56,7 +56,7 @@ function handOff( return submission(id, dispatchState, draftId) } -const IDLE = { hasPendingPrompt: false } +const IDLE = {} describe('queued message cards', () => { it('orders by host position whatever order the list arrives in', () => { @@ -65,11 +65,8 @@ describe('queued message cards', () => { expect(cards[0]?.text).toBe('text of a') }) - it('holds: waiting defaults to the turn, a pending prompt changes the caption', () => { + it('holds: a waiting card waits its turn', () => { expect(projectQueuedMessageCards([draft('a', 1)], [], IDLE)[0]?.hold).toBe('turn') - expect( - projectQueuedMessageCards([draft('a', 1)], [], { hasPendingPrompt: true })[0]?.hold - ).toBe('awaiting-answer') }) it('a returned card carries its stored reason and blocks the label of drafts behind it', () => { @@ -139,7 +136,7 @@ describe('queued message cards', () => { expect(cards.map((card) => card.messageId)).toEqual(['kept', 'refused']) }) - it('a paused queue outranks a pending prompt: an answer does not drain it', () => { + it("a paused queue holds its waiting cards; a card's own hold or return still shows", () => { const cards = projectQueuedMessageCards( [ draft('waiting', 1), @@ -148,7 +145,7 @@ describe('queued message cards', () => { draft('behind', 4) ], [], - { hasPendingPrompt: true, queuePaused: true } + { queuePaused: true } ) expect(cards.map((card) => card.hold)).toEqual([ 'queue-paused', @@ -156,14 +153,10 @@ describe('queued message cards', () => { 'returned', 'behind-returned' ]) - expect( - projectQueuedMessageCards([draft('waiting', 1)], [], { hasPendingPrompt: true })[0]?.hold - ).toBe('awaiting-answer') }) - it('a paused queue holds every waiting card, in order: an answer does not drain it', () => { + it('a paused queue holds every waiting card, in order', () => { const cards = projectQueuedMessageCards([draft('held', 1), draft('typed-after', 2)], [], { - hasPendingPrompt: true, queuePaused: true }) expect(cards.map((card) => card.hold)).toEqual(['queue-paused', 'queue-paused']) @@ -174,7 +167,7 @@ describe('queued message cards', () => { it("the header names the queue's pause while it holds a card, and none over cards Resume would not send", () => { const stopped = { reason: 'stopped' } as const const project = (messages: AgentSessionQueuedMessage[], queuePaused = true) => - projectQueuedMessageCards(messages, [], { hasPendingPrompt: false, queuePaused }) + projectQueuedMessageCards(messages, [], { queuePaused }) expect(queuedMessagesQueuePause(project([draft('held', 1)]), stopped)).toEqual(stopped) const unsendable = [ draft('returned', 1, { state: 'returned', returnedReason: null }), @@ -309,7 +302,7 @@ describe("another agent's card", () => { const cards = projectQueuedMessageCards( [{ ...agentDraft, body: { ...agentDraft.body, from } }, draft('b', 2)], [], - { hasPendingPrompt: false } + IDLE ) expect(cards.map((card) => card.from)).toEqual([from, undefined]) }) diff --git a/src/renderer/src/components/native-chat/structured-agent-session-queued-cards.ts b/src/renderer/src/components/native-chat/structured-agent-session-queued-cards.ts index 4192b552d79..cf0e35ffe7c 100644 --- a/src/renderer/src/components/native-chat/structured-agent-session-queued-cards.ts +++ b/src/renderer/src/components/native-chat/structured-agent-session-queued-cards.ts @@ -16,11 +16,11 @@ import { handedOffQueuedMessageIds } from '../../../../shared/structured-agent-s /** Why a card is not on its way right now; decides the caption under the text. */ export type QueuedMessageCardHold = + /** Plainly queued, also behind an open question: the question already says the agent waits. */ | 'turn' /** The whole queue is paused: the header row says why and offers Resume, so the card makes * no promise about when it sends — not even after an answer, which does not drain it. */ | 'queue-paused' - | 'awaiting-answer' | 'paused' | 'behind-returned' | 'returned' @@ -61,7 +61,7 @@ function queuedMessageCardText(body: AgentSessionQueuedMessage['body']): string export function projectQueuedMessageCards( queuedMessages: readonly AgentSessionQueuedMessage[] | null | undefined, submissions: readonly AgentJournalSubmission[], - session: { hasPendingPrompt: boolean; queuePaused?: boolean; agentWorking?: boolean } + session: { queuePaused?: boolean; agentWorking?: boolean } ): QueuedMessageCard[] { const handedOff = handedOffQueuedMessageIds( submissions.filter((submission) => submission.dispatchState !== 'rejected') @@ -80,9 +80,7 @@ export function projectQueuedMessageCards( ? 'behind-returned' : session.queuePaused ? 'queue-paused' - : session.hasPendingPrompt - ? 'awaiting-answer' - : 'turn' + : 'turn' behindReturned = behindReturned || message.state === 'returned' const from = readAgentMessageSource(message.body.from) return { diff --git a/src/renderer/src/components/native-chat/use-structured-agent-session-queued-edit.test.tsx b/src/renderer/src/components/native-chat/use-structured-agent-session-queued-edit.test.tsx index 061e28913ba..778cf93da22 100644 --- a/src/renderer/src/components/native-chat/use-structured-agent-session-queued-edit.test.tsx +++ b/src/renderer/src/components/native-chat/use-structured-agent-session-queued-edit.test.tsx @@ -90,7 +90,7 @@ function harness(capable = true, initial: Props = { messages: [message] }) { write }, messages: props.messages, - cards: projectQueuedMessageCards(props.messages, submissions, { hasPendingPrompt: true }), + cards: projectQueuedMessageCards(props.messages, submissions, {}), submissions, composerScopeKey: SCOPE, promptOpen: props.promptOpen ?? false diff --git a/src/renderer/src/components/native-chat/use-structured-agent-session-queued-messages.ts b/src/renderer/src/components/native-chat/use-structured-agent-session-queued-messages.ts index cd6342a6140..5f40c4e495c 100644 --- a/src/renderer/src/components/native-chat/use-structured-agent-session-queued-messages.ts +++ b/src/renderer/src/components/native-chat/use-structured-agent-session-queued-messages.ts @@ -99,7 +99,6 @@ export function useStructuredAgentSessionQueuedMessages(args: { const cards = useMemo( () => [ ...projectQueuedMessageCards(queuedMessages, submissions, { - hasPendingPrompt, // A command card offers no send while the agent works. agentWorking: isWorking, queuePaused: queuePause !== null @@ -113,7 +112,7 @@ export function useStructuredAgentSessionQueuedMessages(args: { ) ) ], - [hasPendingPrompt, isWorking, sending, queuePause, queuedMessages, submissions] + [isWorking, sending, queuePause, queuedMessages, submissions] ) const cardsRef = useRef(cards) useEffect(() => { diff --git a/src/renderer/src/i18n/locales/en.json b/src/renderer/src/i18n/locales/en.json index 3651e900af1..901d219cf71 100644 --- a/src/renderer/src/i18n/locales/en.json +++ b/src/renderer/src/i18n/locales/en.json @@ -18655,7 +18655,6 @@ "visualOpenInNewTab": "Open in new tab", "queuedMessages": { "behindReturnedHold": "Waiting — a message ahead needs attention", - "awaitingAnswerHold": "Waiting for your answer", "steer": "Steer", "send": "Send", "steerHint": "Submit without interrupting the model", diff --git a/src/renderer/src/i18n/locales/es.json b/src/renderer/src/i18n/locales/es.json index 7db4ad6f2f7..12ca5c4ee3c 100644 --- a/src/renderer/src/i18n/locales/es.json +++ b/src/renderer/src/i18n/locales/es.json @@ -18252,7 +18252,6 @@ "alreadySent": "Este mensaje ya se envió.", "listLabel": "Mensajes en cola", "behindReturnedHold": "En espera: un mensaje anterior necesita atención", - "awaitingAnswerHold": "Esperando tu respuesta", "steer": "Enviar ahora", "send": "Enviar", "steerHint": "Enviar sin interrumpir al modelo", diff --git a/src/renderer/src/i18n/locales/fr.json b/src/renderer/src/i18n/locales/fr.json index ce936eba3e1..f7b5341df90 100644 --- a/src/renderer/src/i18n/locales/fr.json +++ b/src/renderer/src/i18n/locales/fr.json @@ -18492,7 +18492,6 @@ "alreadySent": "Ce message a déjà été envoyé.", "listLabel": "Messages en file d'attente", "behindReturnedHold": "En attente — un message précédent nécessite votre attention", - "awaitingAnswerHold": "En attente de votre réponse", "steer": "Envoyer maintenant", "send": "Envoyer", "steerHint": "Envoyer sans interrompre le modèle", diff --git a/src/renderer/src/i18n/locales/ja.json b/src/renderer/src/i18n/locales/ja.json index a2c674d7fad..4d26a1b4d89 100644 --- a/src/renderer/src/i18n/locales/ja.json +++ b/src/renderer/src/i18n/locales/ja.json @@ -18425,7 +18425,6 @@ "alreadySent": "このメッセージはすでに送信されています。", "listLabel": "キュー内のメッセージ", "behindReturnedHold": "待機中 — 前のメッセージの対応が必要です", - "awaitingAnswerHold": "回答を待っています", "steer": "今すぐ送信", "send": "送信", "steerHint": "モデルを中断せずに送信します", diff --git a/src/renderer/src/i18n/locales/ko.json b/src/renderer/src/i18n/locales/ko.json index bb1210c207e..3db01ad6a40 100644 --- a/src/renderer/src/i18n/locales/ko.json +++ b/src/renderer/src/i18n/locales/ko.json @@ -18425,7 +18425,6 @@ "alreadySent": "이 메시지는 이미 전송되었습니다.", "listLabel": "대기 중인 메시지", "behindReturnedHold": "대기 중 — 앞의 메시지에 확인이 필요합니다", - "awaitingAnswerHold": "답변을 기다리는 중", "steer": "지금 보내기", "send": "보내기", "steerHint": "모델을 중단하지 않고 보냅니다", diff --git a/src/renderer/src/i18n/locales/zh.json b/src/renderer/src/i18n/locales/zh.json index a00f3b46fab..374c625fec2 100644 --- a/src/renderer/src/i18n/locales/zh.json +++ b/src/renderer/src/i18n/locales/zh.json @@ -18390,7 +18390,6 @@ "alreadySent": "此消息已发送。", "listLabel": "排队的消息", "behindReturnedHold": "等待中 — 前面有一条消息需要处理", - "awaitingAnswerHold": "等待你的回答", "steer": "立即发送", "send": "发送", "steerHint": "提交且不中断模型",