chore(chat): remove deployed-chat voice mode - #6215
Conversation
Removes the voice-first interface and TTS playback from the deployed chat, keeping workspace dictation, which is a separate feature. - Deletes the VoiceInterface UI and its particles canvas, the chat mic input, the TTS audio-streaming hook, the /api/proxy/tts/stream relay and its contract, and the voice-settings query hook. - Unpicks the voice wiring in chat.tsx and use-chat-streaming: the audio stream handler, sentence-splitting for speech, voice-first mode state, and the isVoiceInput plumbing through ChatInput. - Drops the now-dead chatId branch from /api/speech/token. It was the anonymous public-chat path; with no caller left it would have stayed an unauthenticated relay spending the platform key. That leaves resolveDeployedChatCaller unused, so it goes too. - Removes code the above orphaned: MAX_CHAT_SESSION_MS, the noop util, the audio/position refs in use-chat-streaming that were only ever written, and the chatId field on the speech contract. Keeps /api/settings/voice, lib/speech and use-speech-to-text: the workspace home input still uses them. Keeps the voice-output usage source, enum and label — Postgres cannot drop an enum value, and historical usage_log rows still need a label to render.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Client: Deletes voice UI ( API / contracts: Removes Intentionally kept: Workspace home dictation ( Reviewed by Cursor Bugbot for commit b5207dd. Configure here. |
Greptile SummaryRemoves deployed-chat voice input and text-to-speech while preserving workspace dictation.
Confidence Score: 5/5The PR appears safe to merge with no actionable changed-code defects identified. The removed voice-only UI, streaming, API, and contract paths have no remaining callers, while text chat, attachment submission, and authenticated workspace dictation retain consistent call and authorization contracts.
|
| Filename | Overview |
|---|---|
| apps/sim/app/(interfaces)/chat/[identifier]/chat.tsx | Removes deployed-chat voice state, controls, audio playback, and voice-specific submission wiring while preserving text and attachment submission. |
| apps/sim/app/(interfaces)/chat/components/input/input.tsx | Removes voice-only properties and microphone controls and consistently updates the submission callback to pass attachments as its second argument. |
| apps/sim/app/(interfaces)/chat/hooks/use-chat-streaming.ts | Removes voice-specific sentence segmentation and audio callbacks without altering the established text-stream parsing and terminal-state handling. |
| apps/sim/app/api/speech/token/route.ts | Removes the intentionally deprecated anonymous deployed-chat token branch and retains authenticated workspace membership, billing, rate-limit, and usage checks. |
| apps/sim/lib/api/contracts/media/speech.ts | Removes the obsolete chatId request field while preserving the workspaceId contract used by workspace dictation. |
| apps/sim/app/api/proxy/tts/stream/route.ts | Deletes the deployed-chat TTS relay as part of the voice-output feature removal. |
Reviews (1): Last reviewed commit: "chore(chat): remove deployed-chat voice ..." | Re-trigger Greptile
* refactor(chat): clean up the deployed chat surface Eight-angle cleanup pass over the full contents of the chat surface and the speech code that survived the voice-mode removal. Dead code - enforceChatRateLimit: added for the TTS relay in #6212, orphaned when #6215 deleted that route. Zero consumers. - ChatToolCallStatus, ChatErrorType, and six unused CHAT_ERROR_MESSAGES keys (only GENERIC_ERROR and CHAT_UNAVAILABLE are read). - scrollToMessage was declared and destructured by ChatMessageContainer but never used in its body; removing the prop also made the scrollToShowOnlyMessage branch unreachable, since the sole caller passed true. - permissionState and the language prop on useSpeechToText: both write-only across the repo. - The image branch in ChatFileDownload's renderIcon returned the same DefaultFileIcon at the same size as the fallback. - chatKeys.status/detail: aliases of deploymentKeys nothing imported, and misleading since they root under a different key namespace. Redundant state - password-auth and email-auth each kept a boolean in lockstep with `errors.length > 0`; email-auth also validated on every keystroke and then immediately hid the result. - file-download tracked hover in state to drive one opacity class; now group-hover. Verified emcn Button sets no `group` class of its own. Memoization - ChatMessageContainer's memo() could never bail: chat.tsx passes an inline arrow for scrollToBottom and displayMessages is a fresh array. Four of the five things that re-render ChatClient are its props anyway, so the memo is dropped rather than propped up. - ClientChatMessage keeps its memo — it blocks markdown re-parsing — but loses the custom comparator, which compared proxies (a key:status fingerprint, files by length) and ignored attachments and type entirely. Default shallow compare on its single prop is both simpler and stricter. - Six useCallbacks whose consumers are native DOM handlers or inline arrows, so nothing observed their identity. Effects - The scroll listener attached in an effect keyed on [chatConfig, authRequired] — values it never reads, standing in for "the container has mounted". It now attaches via a ref callback, so it no longer re-attaches on every config refetch. Design system and a11y - z-[100] -> z-[var(--z-dropdown)] (same value), shadow-lg -> shadow-medium, list styles from inline style to Tailwind classes, hover: -> hover-hover: on touch-reachable targets, Check sourced from emcn alongside its Duplicate pair. - Accessible names on the remove-attachment, stop, and send buttons, which announced only as "button". - Dropped a keyboard handler on a role='group' div with no tabIndex, where target === currentTarget was unreachable, and the Tooltip Provider wrappers and delayDuration, which emcn documents as no-op passthroughs. * fix(chat): restore markdown list markers The design-system pass swapped inline `listStyleType` for Tailwind classes, but the edit that added `list-disc`/`list-decimal` silently did not apply while the one removing the inline style did. With Preflight setting `list-style: none`, every bullet and number in an assistant response disappeared. `list-item` on the `li` sets display only, not the marker type.
Summary
VoiceInterfaceUI + particles canvas, the chat mic input, the TTS audio-streaming hook, the/api/proxy/tts/streamrelay and its contract, and thevoice-settingsquery hook.chat.tsxanduse-chat-streaming: audio stream handler, sentence-splitting for speech, voice-first mode state, and theisVoiceInputplumbing throughChatInput.chatIdbranch from/api/speech/token, which leavesresolveDeployedChatCallerunused, so that goes too.MAX_CHAT_SESSION_MS, thenooputil, write-only refs inuse-chat-streaming, and thechatIdfield on the speech contract.Notes for review
chatIdbranch in/api/speech/tokenwas the anonymous public-chat path. With chat voice gone it had no legitimate caller, but leaving it would have kept an unauthenticated STT relay spending the platform ElevenLabs key. Removed rather than left dormant./api/settings/voice,lib/speech/*anduse-speech-to-text— the workspace home input still uses them for dictation.voice-outputusage source, its pg enum value and its label. Postgres cannot drop an enum value, and historicalusage_logrows written while the TTS relay was live still need a label to render on the credit-usage page.Type of Change
Testing
555 tests pass across chat, speech, settings, usage-logs and billing. Typecheck clean on
apps/simandpackages/db; all 23 lint tasks pass. Removed two/api/speech/tokentests and oneuse-chat-streamingtest that covered the deleted paths. Not manually exercised in a browser.Checklist