From 9bcc45f069cf6829045c2860a353d0798e6bed4c Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Mon, 26 Oct 2026 12:08:12 +0000 Subject: [PATCH] fix: the mic starts a call with the agents in the real app (0.13.4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Anthony on 0.13.3: "voices are still not using elevenlabs". The mic did dictation (his messages were 🗣️ and his phone read the replies), never a call: it looked for agents in the chat store's conversations, but the sidebar keeps its own list and the store's copy can be empty, so it saw no agents. The agents were in the call speaking ElevenLabs into an empty room. - The composer loads the chat's members itself (GET /api/chat/conversations/[id]/participants) and uses them for the mic, the voice bar and voice mode. - That endpoint now returns users.account_type, so agents can be told apart. Tested in Chromium with an empty store and the endpoint returning the Agents group: the mic reads "Voice call with riotcoder, cha0spunk" and tapping it calls startCall, with no dictation bar. Co-Authored-By: Claude Opus 5.5 --- package.json | 2 +- .../conversations/[id]/participants/route.js | 3 ++- src/lib/components/chat/MessageInput.jsx | 18 +++++++++++++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 98392129..d9bc29e5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "qryptchat-web", "private": true, - "version": "0.13.3", + "version": "0.13.4", "type": "module", "bin": { "qc": "./bin/qc.js", diff --git a/src/app/api/chat/conversations/[id]/participants/route.js b/src/app/api/chat/conversations/[id]/participants/route.js index 1f9e6610..dd064bb6 100644 --- a/src/app/api/chat/conversations/[id]/participants/route.js +++ b/src/app/api/chat/conversations/[id]/participants/route.js @@ -162,7 +162,8 @@ export async function GET(request, { params } = {}) { id, username, display_name, - avatar_url + avatar_url, + account_type ) `) .eq('conversation_id', conversationId) diff --git a/src/lib/components/chat/MessageInput.jsx b/src/lib/components/chat/MessageInput.jsx index fd66a24f..cfb2cd27 100644 --- a/src/lib/components/chat/MessageInput.jsx +++ b/src/lib/components/chat/MessageInput.jsx @@ -71,7 +71,23 @@ export default function MessageInput({ conversationId, disabled = false }) { ); // Voice mode: talk to the chat (your agents) and hear the replies. - const activeConversation = conversations?.find((c) => c.id === conversationId); + // The chat's members, loaded here: the sidebar keeps its own chat list, so the + // store's copy can be empty, and then the mic never knew the chat had agents. + const [members, setMembers] = useState(null); + useEffect(() => { + setMembers(null); + if (!conversationId) return; + let stale = false; + fetch(`/api/chat/conversations/${encodeURIComponent(conversationId)}/participants`) + .then((r) => (r.ok ? r.json() : null)) + .then((d) => { if (!stale && Array.isArray(d?.participants)) setMembers(d.participants); }) + .catch(() => {}); + return () => { stale = true; }; + }, [conversationId]); + const storedConversation = conversations?.find((c) => c.id === conversationId); + const activeConversation = members + ? { ...(storedConversation || { id: conversationId }), participants: members } + : storedConversation; const voice = useVoiceMode({ conversation: activeConversation, messages,