Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ vi.mock('react-native-reanimated', () => ({
LinearTransition: { duration: () => ({}) },
useReducedMotion: () => true,
}));
vi.mock('@/components/agents/session-row', () => ({
vi.mock('@/components/agents/remote-session-row', () => ({
RemoteSessionRow: 'RemoteSessionRow',
}));
vi.mock('@/components/agents/session-list-section-header', () => ({
Expand Down
2 changes: 1 addition & 1 deletion apps/mobile/src/components/agents/active-now-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Animated, {
useReducedMotion,
} from 'react-native-reanimated';

import { RemoteSessionRow } from '@/components/agents/session-row';
import { RemoteSessionRow } from '@/components/agents/remote-session-row';
import { SessionListSectionHeader } from '@/components/agents/session-list-section-header';
import { ACTIVE_NOW_TRAY_CAP, selectTrayWindow } from '@/components/agents/active-now-window';
import { Text } from '@/components/ui/text';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ describe('getContextSheetContent', () => {
expect(content.percentage).toBe('125%');
expect(content.remainingTokens).toBe('0');
expect(content.remainingPercentage).toBe('0%');
expect(content.cost).toBeNull();
expect(content.cost).toBe('$0.0000');
expect(content.tone).toBe('destructive');
});

Expand All @@ -244,14 +244,14 @@ describe('getContextSheetContent', () => {
expect(content.windowUnavailable).toBe(true);
expect(content.percentage).toBeNull();
expect(content.remainingTokens).toBeNull();
expect(content.cost).toBeNull();
expect(content.cost).toBe('$0.0000');
expect(content.windowUnavailableLabel).toBe('Context-window size unavailable');
expect(content.tone).toBe('neutral');
});

it('omits the cost line when total cost is zero', () => {
it('shows the cost line as $0.0000 when total cost is zero', () => {
const content = getContextSheetContent(info({ percentage: 20 }), 0);
expect(content.cost).toBeNull();
expect(content.cost).toBe('$0.0000');
});
});

Expand Down
4 changes: 2 additions & 2 deletions apps/mobile/src/components/agents/context-usage-display.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ type ContextSheetContent = {
percentage: string | null;
remainingTokens: string | null;
remainingPercentage: string | null;
cost: string | null;
cost: string;
tone: ContextTone;
};

Expand All @@ -124,7 +124,7 @@ export function getContextSheetContent(
): ContextSheetContent {
const tone = getContextTone(info.percentage);
const usedTokens = formatExactTokens(info.contextTokens);
const cost = totalCost > 0 ? formatCost(totalCost) : null;
const cost = formatCost(totalCost);
if (info.contextWindow === undefined) {
return {
usedTokens,
Expand Down
17 changes: 17 additions & 0 deletions apps/mobile/src/components/agents/message-bubble.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ type MessageBubbleProps = {
onOpenChildSession?: OpenChildSession;
/** Per-user-message delivery state. v1 surfaces only a "Queued" badge. */
deliveryState?: MessageDeliveryState;
/**
* Subtle model label for an assistant message, precomputed by the parent
* via `computeMessageModelLabels`. Only the assistant branch renders it
* (and only when truthy); the user branch and the unlabelled
* same-model follow-ups render nothing.
*/
modelLabel?: string;
};

export function MessageBubble({
Expand All @@ -34,6 +41,7 @@ export function MessageBubble({
defaultReasoningExpanded,
onOpenChildSession,
deliveryState,
modelLabel,
}: Readonly<MessageBubbleProps>) {
const isUser = message.info.role === 'user';
const { copyMessage } = useMessageCopy();
Expand Down Expand Up @@ -131,6 +139,15 @@ export function MessageBubble({
onOpenChildSession={onOpenChildSession}
/>
))}
{modelLabel ? (
<Text
className="text-xs text-muted-foreground"
accessibilityRole="text"
accessibilityLabel={`Model: ${modelLabel}`}
>
{modelLabel}
</Text>
) : null}
</View>
</Pressable>
);
Expand Down
Loading