feat(ios): record and send voice notes from the chat composer - #100946
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed July 6, 2026, 6:41 PM ET / 22:41 UTC. Summary PR surface: Other +1121. Total +1121 across 18 files. Reproducibility: not applicable. as a bug reproduction: this PR adds a new iOS composer capability. Source review confirms current main lacks a voice-note recorder in the first-party iOS composer while the gateway already supports non-image chat attachments. Review metrics: 2 noteworthy metrics.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review detailsBest possible solution: Land a scoped iOS v1 only after maintainers accept the product direction, exact-head CI is green, and redacted device or simulator proof shows record -> staged audio chip -> send through the existing attachment path. Do we have a high-confidence way to reproduce the issue? Not applicable as a bug reproduction: this PR adds a new iOS composer capability. Source review confirms current main lacks a voice-note recorder in the first-party iOS composer while the gateway already supports non-image chat attachments. Is this the best way to solve the issue? Yes, this is the right implementation layer if maintainers accept the feature: the native app owns recording and UI, while the existing chat.send attachment and media-understanding path owns server-side handling. The remaining gap is proof of the device-level mic and send path, not a reason to add a new server API. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against fc77c2b04b4d. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Other +1121. Total +1121 across 18 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (2 earlier review cycles)
|
25826f4 to
0e220ee
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0e220eeb8a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| .disabled( | ||
| !self.isComposerEnabled | ||
| || self.control.isTalkActive | ||
| || self.control.recorder.isRequestingPermission) |
There was a problem hiding this comment.
Disable voice-note recording when attachments are offline
When the iOS chat is offline but the durable text outbox is available, ChatProTab passes isComposerEnabled: gatewayConnected || canQueueOffline while isAttachmentInputEnabled stays tied to gatewayConnected. This new button only gates on isComposerEnabled, so that offline-but-queueable state lets users record and stage an audio attachment; canSendMessage then refuses to send because attachments require isAttachmentInputEnabled, leaving an unsendable draft until reconnect. Gate voice-note recording on the same attachment-input availability as the paperclip.
Useful? React with 👍 / 👎.
f110a66 to
7e78d5c
Compare
7e78d5c to
a9d4a52
Compare
Adds tap-to-record voice notes to the shared chat composer: m4a/AAC mono capture with a 3-minute cap, lazy mic permission, cancel/finish controls, audio attachment chips with duration, and a voice-note transcript row. Voice-wake suppression becomes reason-scoped so recording and Talk cannot clobber each other. Attachments stay online-only per the outbox contract. Related: #100709
a9d4a52 to
d352bf6
Compare
|
Land-ready review complete for exact head
Known proof gap: physical microphone permission, record, send, and rendered-bubble interaction remains manual-device proof; automated simulator/build evidence does not claim that physical-device flow. |
|
Merged via squash.
|
…aw#100946) * feat(ios): record and send voice notes from the chat composer Adds tap-to-record voice notes to the shared chat composer: m4a/AAC mono capture with a 3-minute cap, lazy mic permission, cancel/finish controls, audio attachment chips with duration, and a voice-note transcript row. Voice-wake suppression becomes reason-scoped so recording and Talk cannot clobber each other. Attachments stay online-only per the outbox contract. Related: openclaw#100709 * fix(ios): harden voice note attachment staging * chore(ios): keep voice note changelog release-owned * fix(ios): gate voice notes with attachment availability * chore(ios): refresh native localization inventory
Related: #100709
What Problem This Solves
iOS users have no way to send a quick, fire-and-forget voice message to their agent from the chat composer. Talk mode is a live synchronous session and wake word drives immediate voice turns; neither covers "record 30 seconds now, get an answer whenever it's ready." Channels such as Telegram and WhatsApp already accept voice notes and transcribe them through media understanding — only the first-party app lacked a way to produce one.
Why This Change Was Made
Adds tap-to-record voice notes to the shared chat composer (OpenClawChatUI), reusing the existing
chat.sendattachment path end to end: a newOpenClawVoiceNoteRecorderstate machine (idle → requesting permission → recording → finished/failed) records m4a/AAC mono (24 kHz, 32 kbps) with a named 3-minute cap that auto-finishes, and the finished note is staged as a regular pending attachment (audio/mp4, existing 5 MB bound) sent with the normal send button. No server changes: gatewaychat.sendalready accepts non-image attachments and the reply pipeline already transcribes audio via media understanding. Mic ownership is coordinated, not fought:VoiceWakeManagersuppression is reason-scoped (talk,voiceNote) so ending Talk cannot restart wake listening over an active recording; recording is unavailable while Talk or push-to-talk owns the microphone; and enabling Talk cancels an in-flight recording. The voice-note button follows the same attachment-availability gate as the picker, while asynchronous staging and send reconciliation retain the captured attachment draft rather than mutable composer state. The control is injected host-side (same pattern astalkControl), so macOS and other OpenClawKit consumers are unaffected. Non-goals per the tracking issue: playback of sent notes, waveform visualization, slide-to-cancel, and offline queueing of attachments (attachments stay online-only per the outbox contract).User Impact
iOS users can tap the mic button next to the attachment picker, record up to 3 minutes, cancel or finish, see the note as a "Voice note · m:ss" chip (optionally alongside text), and send it. The sent bubble renders a voice-note row with duration, preserved across same-session history reconciliation and the local transcript cache. Mic permission is requested lazily on first use. If the gateway is offline, the existing attachments-online-only behavior applies unchanged.
Evidence
git diff --check: clean.