Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .kilo_workflow/learnings/mobile-remote-cli-model-id-prefix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# mobile: remote-cli.sh exec run -m kilo-auto/efficient fails ProviderModelNotFoundError — CLI ids need the kilo/ prefix

Symptom: `apps/mobile/e2e/remote-cli.sh exec run -m kilo-auto/efficient --auto "<prompt>"` fails
with `ProviderModelNotFoundError` / `Model not found: kilo-auto/efficient`, and the run still
creates an empty session row in the mobile Agents list.

Cause: the handoff/workflow "kilo-auto/efficient" id is the IN-APP id. The CLI's provider/model
format needs the provider prefix: `kilo/kilo-auto/efficient` (WORKFLOW.md's "kilo/kilo-auto/* are
the same models as CLI ids" is the only place this is stated, and it is easy to read past).

Fix: run `apps/mobile/e2e/remote-cli.sh exec models` first and copy the exact id
(`kilo/kilo-auto/efficient`); never guess from the in-app id. Side effect to expect: each failed
run leaves an empty `New session - <ts>` row in the session list — harmless, but do not confuse
it with the content session when picking rows to tap.

Bonus: a fresh E2E account starts with $0 credit; `kilo/kilo-auto/efficient` then fails with
"Add credits to continue". Seed first:
`pnpm dev:seed app:user-id <email>` then `pnpm dev:seed app:add-credits <user-id> 10`.
1 change: 1 addition & 0 deletions apps/mobile/src/app/(app)/agent-chat/[session-id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export default function SessionDetailScreen() {
info={undefined}
totalCostMicrodollars={null}
hasMessages={false}
loading
/>
}
/>
Expand Down
31 changes: 18 additions & 13 deletions apps/mobile/src/components/agents/session-context-metrics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ type SessionContextMetricsProps = {
totalCostMicrodollars: number | null;
hasMessages: boolean;
onPress?: () => void;
/**
* Hide the pill while the session page loads; the layout box stays reserved so the header does not
* shift.
*/
loading?: boolean;
};

const RING_SIZE = 28;
Expand All @@ -37,11 +42,12 @@ export function SessionContextMetrics({
totalCostMicrodollars,
hasMessages,
onPress,
loading = false,
}: Readonly<SessionContextMetricsProps>) {
const content = getHeaderPillContent({ info, totalCostMicrodollars, hasMessages });
// Single source for element kind and a11y affordance wording so a future
// caller with interactive content but no onPress cannot advertise a tap.
const pressable = content.interactive && onPress != null;
const pressable = !loading && content.interactive && onPress != null;
const accessibilityLabel = getMetricsAccessibilityLabel({
info,
totalCostMicrodollars,
Expand All @@ -52,20 +58,16 @@ export function SessionContextMetrics({
// NativeWind 5 preview (rem ≈ 14px here), so an arbitrary px value is required
// for the 44pt minimum touch target; height is identical in every pill state.
const pillClassName =
'h-[44px] flex-row items-center gap-1.5 rounded-full border border-border bg-secondary px-2.5';
'h-[44px] flex-row items-center gap-2 rounded-full border border-border bg-secondary px-3';

const body = (
<>
<View className="h-7 w-7 items-center justify-center">
<View className="absolute inset-0">
<ContextUsageRing
size={RING_SIZE}
strokeWidth={RING_STROKE}
arcFraction={content.arcFraction}
tone={content.tone}
/>
</View>
</View>
<ContextUsageRing
size={RING_SIZE}
strokeWidth={RING_STROKE}
arcFraction={content.arcFraction}
tone={content.tone}
/>
{content.primary != null ? (
<View className="flex-row items-baseline gap-1">
<Text className={cn('text-xs font-semibold tabular-nums', toneTextClass(content.tone))}>
Expand Down Expand Up @@ -103,7 +105,10 @@ export function SessionContextMetrics({
return (
<View
accessibilityLabel={accessibilityLabel || undefined}
className={pillClassName}
{...(loading
? { accessibilityElementsHidden: true, importantForAccessibility: 'no' as const }
: {})}
className={cn(pillClassName, loading && 'opacity-0')}
testID="session-context-metrics"
>
{body}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@ export function SessionDetailContent({
info={contextInfo}
totalCostMicrodollars={totalMicrodollars}
hasMessages={messages.length > 0}
loading={shouldShowLoading}
onPress={
contextInfo
? () => {
Expand Down
Loading