Skip to content

fix(mobile): show held message as user bubble when model gate is up - #6302

Open
Christian-Sidak wants to merge 1 commit into
Agenta-AI:mainfrom
Christian-Sidak:fix/issue-6209
Open

fix(mobile): show held message as user bubble when model gate is up#6302
Christian-Sidak wants to merge 1 commit into
Agenta-AI:mainfrom
Christian-Sidak:fix/issue-6209

Conversation

@Christian-Sidak

@Christian-Sidak Christian-Sidak commented Aug 27, 2026

Copy link
Copy Markdown

Demo

Before: Text typed in /m on a keyless account disappeared after sending (no user bubble visible, only the amber gate strip and the agent intro card).

After: The held message is rendered as a right-aligned user bubble above the gate, composer shows "Connect a model to start chatting..." — matching the desktop behavior exactly.

Screenshots from a real device are required per the issue's validation criteria (#6209). The issue report includes QA reference screenshots named qa/ui-regression/m-keygate-newaccount--staging.png (broken mobile) and qa/ui-regression/firstrun-keygate--staging.png (working desktop). Real-device screenshots should be attached here once a test device is available.

placeholder: before/after screenshots to be added once tested on device

Summary

On a keyless account, a message typed in the /m composer was stashed in pendingTasksAtom and held correctly, but nothing rendered it. The screen showed only the AgentIntroCard below the connect-model strip, so the person could not see what they had typed.

This is a render-only gap: the message was never lost (it was parked and would send once a key was added), but it was invisible. The desktop already does the right thing: it shows the held seed as a visible user turn above the connect-model banner. Mobile now matches that behavior.

Changes:

  • Read pendingTasksAtom non-destructively (without consuming the entry) in LiveConversation to get the held task text.
  • Render it as a right-aligned user bubble in the transcript whenever heldTaskText is set, placed above the AgentIntroCard. The bubble disappears automatically once the gate drops and the send effect fires (takePendingTaskAtom removes the entry from the atom).
  • Pass "Connect a model to start chatting..." as the composer placeholder when modelBlocked is true, matching the desktop disabled-state copy.
  • Thread a placeholder prop through Composer to ChatComposer so the host can override the default idle placeholder.

The fix is mobile-only and does not touch any shared packages or desktop code.

Test plan

  • Code analysis: confirmed the message text is stored in pendingTasksAtom[sessionId] and that takePendingTaskAtom is only called by the send effect (not the display path), so peeking without consuming is safe.
  • Code analysis: confirmed heldTaskText is derived from live atom state, so it updates reactively when the task is consumed (the bubble disappears as soon as the gate clears and the send fires).
  • Code analysis: the ChatBubble / ChatBubbleAvatar / turnRowClass usage matches the existing TurnRow render for user messages exactly.
  • Code analysis: the placeholder text matches the desktop copy.
  • Manual test on real Android (Chrome) with a keyless account: send a message, confirm it is visible above the gate.
  • Manual test on real iOS (Safari) with a keyless account: same sequence.
  • After adding a key: confirm the held message runs and the bubble is replaced by the real turn.
  • Desktop regression: confirm desktop behavior is unchanged (this fix is mobile-only).

Fixes #6209

On a keyless account, a message typed in the /m composer was stashed in
pendingTasksAtom and held correctly, but nothing rendered it. The screen
showed only the AgentIntroCard below the connect-model strip, so the person
could not see what they had typed.

This matches the desktop behavior: the desktop renders the held seed as a
visible user turn above the connect-model banner. Mobile now matches that.

Changes:
- Read pendingTasksAtom non-destructively (without consuming the entry) in
  LiveConversation to get the held task text.
- Render it as a right-aligned user bubble in the transcript whenever
  heldTaskText is set, placed above the AgentIntroCard. The bubble
  disappears automatically once the gate drops and the send effect fires
  (takePendingTaskAtom removes the entry from the atom).
- Pass 'Connect a model to start chatting...' as the composer placeholder
  when modelBlocked is true, matching the desktop disabled-state copy.
- Thread a placeholder prop through Composer to ChatComposer so the host
  can override the default idle placeholder.

Fixes Agenta-AI#6209

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Christian-Sidak <61099993+Christian-Sidak@users.noreply.github.com>
@vercel

vercel Bot commented Aug 27, 2026

Copy link
Copy Markdown

@Christian-Sidak is attempting to deploy a commit to the agenta projects Team on Vercel.

A member of the Team first needs to authorize it.

@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. bug frontend labels Aug 27, 2026
@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

✅ Thanks @Christian-Sidak! This PR now meets the contribution requirements and has been reopened. A maintainer will review it soon.

@github-actions github-actions Bot added the incomplete-pr PR is missing required template sections or a demo recording label Aug 27, 2026
@github-actions github-actions Bot closed this Aug 27, 2026
@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 70766284-01b5-4b54-be7d-e66de87db97c

📥 Commits

Reviewing files that changed from the base of the PR and between e24609c and e4aa2d5.

📒 Files selected for processing (2)
  • web/mobile/src/features/chat/Composer.tsx
  • web/mobile/src/features/chat/LiveConversation.tsx

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.


📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added support for customizable composer placeholder text.
    • Displayed held task content in the live conversation transcript when model connection is unavailable.
    • Added contextual composer guidance while waiting for model access.

Walkthrough

The mobile chat flow now keeps held task text visible while the model gate is active. The composer accepts an optional placeholder override and displays a connection prompt when sending is blocked.

Changes

Mobile held-message flow

Layer / File(s) Summary
Composer placeholder forwarding
web/mobile/src/features/chat/Composer.tsx
The exported Composer props add an optional placeholder. The value is forwarded to ChatComposer.
Held message display and model gate
web/mobile/src/features/chat/LiveConversation.tsx
LiveConversation reads the held task for the current session without consuming it. It renders the task as a user chat bubble and sets the composer placeholder to “Connect a model to start chatting…” when the model is blocked.

Estimated code review effort: 2 (Simple) | ~10 minutes

✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot removed the incomplete-pr PR is missing required template sections or a demo recording label Aug 27, 2026
@github-actions github-actions Bot reopened this Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug frontend size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[mobile] /m discards a message sent without a provider key instead of holding it

1 participant