From 69c064b0745f6c576256408d63f557f515e387b0 Mon Sep 17 00:00:00 2001 From: AeBoPi <109503402+AeBoPi@users.noreply.github.com> Date: Mon, 18 May 2026 11:57:03 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E7=BC=96=E7=A0=81=EF=BC=8C=E8=AF=AD=E9=9F=B3=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- backend/api/routes/voice.py | 28 ++++++++++++++++++++-------- docs/en/voice-mode.md | Bin 32588 -> 16387 bytes docs/voice-mode.md | Bin 17882 -> 14637 bytes firmware/src/network.cpp | 3 +-- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/backend/api/routes/voice.py b/backend/api/routes/voice.py index 91593c8..625d3c2 100644 --- a/backend/api/routes/voice.py +++ b/backend/api/routes/voice.py @@ -396,20 +396,31 @@ async def device_voice_ws( ): mac = validate_mac_param(mac) x_device_token = websocket.headers.get("x-device-token") or websocket.query_params.get("token") + + # Accept immediately so the client (ESP32) gets HTTP 101 without waiting for DB queries. + # Auth and session setup happen right after; if they fail we close with an error code. + await websocket.accept() + logger.info("[VOICE_WS] accepted mac=%s has_token=%s", mac, bool(x_device_token)) + try: await require_device_token(mac, x_device_token, websocket.headers.get("accept-language")) except HTTPException as exc: + logger.warning("[VOICE_WS] auth failed mac=%s status=%d detail=%s", mac, exc.status_code, exc.detail) await websocket.close(code=1008, reason=str(exc.detail)[:120]) return - settings = await _resolve_device_voice_runtime_settings(mac) - session = create_voice_ws_session( - settings=settings, - access_user_id=None, - access_mac=mac, - ) - await websocket.accept() - logger.info("[VOICE_WS] accepted mac=%s session_id=%s", mac, session.session_id) + try: + settings = await _resolve_device_voice_runtime_settings(mac) + session = create_voice_ws_session( + settings=settings, + access_user_id=None, + access_mac=mac, + ) + logger.info("[VOICE_WS] session ready mac=%s session_id=%s provider=%s", mac, getattr(session, "session_id", "?"), getattr(settings, "llm_provider", "?")) + except Exception: + logger.exception("[VOICE_WS] session setup failed mac=%s", mac) + await websocket.close(code=1011, reason="internal error") + return async def _sender() -> None: async for event in iter_voice_ws_events(session): @@ -430,6 +441,7 @@ async def _sender() -> None: ws_message.get("type"), ) if ws_message.get("type") == "websocket.disconnect": + logger.info("[VOICE_WS] client disconnected mac=%s code=%s", mac, ws_message.get("code")) break if "bytes" in ws_message and ws_message["bytes"]: diff --git a/docs/en/voice-mode.md b/docs/en/voice-mode.md index e5fe4483532cd5ad805b1827584ee0f0850c0e3c..0b1ace9f2abd5bf1ff2157517d2fd9c89891a36c 100644 GIT binary patch literal 16387 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 literal 32588 zcmc(oU2j#_c7~VIyQ-CX(TiTXpr}q&L-t1ww z-CO;3uY29?chB_OE&ct2{=CvRZ@NSMc2w^8rhC`DEcg6%_m>@iW{`wIep8gzZ%pdjd51Qd+_f(&_$}G>iW8LvozrED8BYpo|-$CI!U5WdaMEgkL{mrP%{Z`-d_i=gdpnTs_@wChe_dLP8rh})Sbno@| zn?lElu0rua`Tm{mW9*|ci|K|Q=tZVK=w7(|Cw)emdm8K2>GSXf%`0U#h_0$VJv8St{)jiPxeJ8rc_iwvPy0)$Rtb;?*YF+y?zjObA?tP{!Nd2|= zY^g^E&$@prR`5o0@SRD)p+bUkw-&yK=qQcLu z78yO!J^cBHGS*G~_Og6$ewVv{|KY#hU|nzYEs`&oB#}DH_)c0t&);2cqAAcWlCH#HNT0*|z?eQd9e_HIu)-sWPwom7HrfYZr zyucGyj8{YiVeZf$wuOxoWr#M+z;oE9{TJ?e!ZrXOL;E;UB*3eXqy21*!`9xzLf@A; z_vA(Ug+ip3^5fID8kIVvJ{%9#-_!Kk8>o-}WQQq-fZ(BGO=q+q&;3 z{l3&K%iiJmv-14!^^G-&d|IEgAMPp+{HUjox@#JTcyp|OpBEoIkz7`aRG|Sq5Yu)w zQpBBC#kbyxBI5L(xL}@?Nh@`(!Lc>f=L_p5r##jiPsGJ*NrnjXcIw^Cf^LuX4I^RA zjE3gW^|;m4u?aoI?6yokF^2OM+@VWbRM^wI!aFlAYyQ15Kli-SH&_&7o`_cb`c0vY zD7G)1@{QxrIBnQSXnIn{LfdupvQ|UOwdSG5mVI_j<5O6CX6qIGj^5E9`E{tqYcBv-z> zC+#~jlGE)~krnw&3?$xzi(bnvj1Zyjv+{f!aYGx%Sxhq{6nqIduHOX2Gm@ti;Hr~IDZ#;?UFMmjg8m#DpF z$p?!wy{0Lm6|_ScJ{MYVE$K-!x-$sAjqiQm{Xx&|RaT4*kb&UW)->BjnHL*%><=sm z9j;LA4^K2!jeEo9BD&O+kK3X7-jpWE40wp+Y0GCui*ZyQ^Cs_(`K>PQ6l8&yZHc?| zm|Ff&Zp61Fe_SgyRgL>1LgrYT-GhQnLpH=J5G&HIqm=y%?*P#v`Mysw!n~_V2Tupj z%rPF5>R5us-<5okAG1)?wlYTYEt)6RI)4+*pXd`-!_x<%9sf&z!lxr5EOl2)y?00V z5K(_D|Ke+p^+ce@cw%-WaP9xJB$CEkZD@Q=2q^hBS{#U+hg=ke#F3j`KYz;2N(Qfp&aR{Av^Ynq=svDB#1 z&2dXVs0GwTUU*aN#$KN>p_LG`A?3qL?)w_UapXw9VV&>wnSaq}R%(2v7ZbXP_>MlW z=x+SRnU0#mISfl$l`LE>Mg*q1V8$3JW3#W=@3%w^_xV$1kLTjmxpICKXY^qdZog?i zWdxt~y(7Cvb`0O>?w9O*y}K?cWVE;^Y4!U_pxO=D*<>o)Hzh(-Il)O>;r9p95Lq3$ zIabt`gdErPhjGSY9ueS5_obrzo$hD-PG&Uz$jBbEh1VX-GE%NJhxeqxf9byNzLHIT z(fv-JlFP|yK53H< zReN_vnU!grfmihGSOd4zV~k@uBEt{87kN2`WZyV@TWD&wCDxYfiaI#7J=WJ#CR|&@ z%{P+ZhOF3@JsW8;-+W(7pIr3Y{Bb-JQF={3rt6v_*EN0PPn*&dxy=1P*PgbhL<--? z+p$b!(Ed&&Cg!8Fynmv(zCFD^WO7CJ=rO_ziL&nf)K5Py9`3pF*{^%gg09J=&KE>X z@=iU@q@p>-xhBqA8un#_)Du`NxYT|c;~+n*sqgX2vaf!87~0bCp8p?va{OLoNqPO_ z+0>Za&|tsk5jMJ_*!!rgM5T4r7I;fqV{OVA+_;Yz61EW4ZG7j5<~0~1hdZ{e8$Axx zq)medL3fF1!ZNVWn^QYqmZgyqFPCrb%Jw6>Wkk559MW3e6Gb^JcH9f@o{o(_T<&h` z@3B$8?2WqEFH9?0`IchUL&f#sxL1|0TWZr!km1lv>Rf`4)wpoGdv$G^a}qr@7}c02PKnXOYW^jK5VN~Y>4QRR&rJGiEk|XyRt-gm2(A? z-0qlXYj-{B8r1cGWBKeFqNdUr*0FyPrM2HpgazE6cNY=VK}H_Zf#HTg;adtz0$Ex&>{NQovUb`~DLu=$Qa0fS%jD;i5;y;LZp=GdbpE?CQpSBe zy~bi+Xtvwpx$S|XKGA*r2EN%Z{Utg=T;W*|0XX8#B?#Ho~wj-1T=QZt51{IyeE1MLoZw5#1fFF;Zfo`I^gaifzjp#kx{+ zJK_`VA4oP!-HnoI!@_Ov+#lbplzM!%R2&Z^!JDc+9tdIe5#9|+nde%YPA?vIo%&XZ z6tF1l!1Wtz+sP5QJFVPU`;r)Tl%!E-*%@o(e3=a{Fuf`;TXL_wY{3(mP<#}Yy0d;1j`cpxK?*evohG#EcZ3r z&FRb!M8iW-6Ei=Mgafg9bqblT%K~%FfqR(CtG3wSQ~k~k2UaNDr)0GZ|7JC7zxW5( z8Q=GwMMnW>B_^>)$i1evW8nJLdccSK6~j$QjY{H&Q)>uU8Q^HCErIc_#QCUbj{JI!g}A z?OSyJbKJ+jX-Bgx5^HHKFIJz)2i~>IIuj9-T_N5(80&kn&oAd0@AgKA1>3`38H<^{ z>J?X`8_AWnwrG2TSn^fn1@;|LuVJaf$U`o}PPvVF{M6dK*B9GQ84`I83zt0gSX|3b--Ip;h5J^7CezvUX-2uu~QtTyn z(<~1#l5K;i!@ea)(b(Mr4tBSKwO;Ht_ZE=djm)^~wyx7(c_A&pJ2Z`ZUcFxBm|u5z z1C7-YU~FfB*WY7jan9NI8n4KcyJN+*)n-ji&`mdGr66PHrz6>d`@G17yF$Ac#pOiT zj!V`;4rkF7w$+|?80IjK8GE4Y^JE!TqKShM@9-DaetklKa|q8)<-e*=FH3%8{QeF> z#^70Zw8=!NTXqTXEHkZ^ZrjpyA9Kj)mgY&T;%;m^_B%!=ucei!?G>TE3~%a5@4$zz z{+xVf%@K;wd!UOL#rx$S>8ibIsryb(w7j#D%It8|pKVju7&Xos{8>4fQz)$XfDJF} z2MH#Hmx|n|UA!WHNmrTgec{hn59JAgSPlwp_&YWdx`QH4oM7|t;(Z`%Q%Q0+_vZPU zRuh5NFHAMGA`Pu~f71QnS0XEwY($F-Wd_HhbzL1+U9nFcT!N>!(K#y=q!cTw;jP}6 z5%v&x+UP!Z+uAenBjP)Lg6;Kp_jA&SvmCjf`9t=mBh7iUPoyd8E;17~1HZ$a)Vqbk zMSG=(bKMhPc3eF{ zSkVG`c%O0l3jEy`UD%&}x4(PGF_f|K9cZ7wnmq95J*<56Yd<7g@o zwQ=<2f~I{|3Ta>ma1^=Vn4LuNqy;HefUY}-cc0P?UOo=@mV)q*8Nd4U_qb+;uxn2%)ieJ z)O1@`eU43QeV@l2zb|zLcf^JDQ%fdx2cHo!cGYz_kL2*7y53-wkp3HgqYeDZy(qkl zz1y{}uzBvo@@My+9Fee(-81MC|Bh8NKk2h0Nxe{RVpSJf5SmZh-24ofCC(<6Bxjj!w4jdPzI3(hWz|6#0Rd}_x2=`Xaj zuOFh8*ONaskE~ejsI#?IxTM<~Sdje=#87&EuS=9~@!wNj2@H5y_ps z-rK@{f%THX*uyrFJg%xAFs6$!dt|l#r=q`i(xE$3uITA88|kB4?B=|hatCKe)IHLl z`|?0~;(yY=)cJJ5*>`$XyXL+uJq&0bW|VE|ZV_5>e&Km=dK&>}Thdu2x?6Iz^Ngdi z&$)p===0J&a_7|YB5V6TqYm#6@hKYedhAwp-Qg_7j%+LppJc?el*Dk@Z+!~O(U0!# zXXV_7Es-aogHZy>qU9sy6%Z*N8*|iag+9Fmf@~>q1|6Fj{bkSMtWxj$ucf;tiFr+I zY{!4w4R@}_>&bh|vVEVW!%E2joPnuxLf}2tzK+T>fuGj(`9Si(C+irJb;&i2wXNqk zzp?1->iIJv^GELx%b?4S4bV%6vP5;u@|GKg{+8J^YW>u*`A$4 zKzZ1NEq_=Awf0e0gvgLy3>6)ccMaxK2-!!f*UYn;1bN=lyyug6O7F%fFSQ&({$p|b z>Zu_I=9xHb2JF@B<{s};CbwId?k`B6>E?+P1q=_ zr{qTF`&`lCivA`RpJ!I=;jXX@$n=KdX`8t>W!Y~_EMpEjgmn6C?L-SK7aZq(;vh8N zeLfnfc()Zr@019@95ts=4^U+IIFd;A4j1+4f8zV*CUvDR=)_ta60H~ zp%=37^&+?59>L6`ueKj&(pAa+Ukm*)p~i-WXlx!YX#?hDYh>QffRpp65!OuzI$Zx7SA3y0==I3^yfb-Svz!5nDiJ+Z+524OA@bF%g zfN}6c_BQaHwF5q)4&xeJf($Gtc!MWmV_hM`NxyC#qAd1OxV|GZLT^oz^IxDXa3g2N zBMbLO2Lt3o)^oqjmq|x<;RfgFXry>$E%e zQsonWk<=SKy;itn1oA_~(d~lCjk=?!N9G_~xt6eW;<=O}-_!51_hx4$(4sTmLBaOe z1Uu2A(ulWuU?+W!sJZE*IA_M0-ry9+Z>0yimq;GHL ziJ_E+`Ox~Ie(xjn*db>7?DKd&?Ko?X*A9Iuz4l*sEQXw8vwlBQD<|8~kV{j07B1)U z<%)<}zVa-@zcoqE~X9P#D{!{ox?v^Eb_9eo1#4YbrtR-WQV&2R- z(cQ^F5Nn^gNCSBh|4sEr54A5s@;|v{8kzg0i#_ zXKga0C51H-Bl%{wHMlputv=_tEu2RtttE`f1o>uu%pO5Y#ZWiYM`zUyvbHDUGxk&W zx3D`jH@<_A4CC19+Pu|yttsQd$b7ACvMv)q0XZjjE%~%6?;OD2Ba_#sCa4gx1L`W`5ne)7 z>+rqUS?#^VV`4DzDR(hjmb=n3oQ3bOGIpezm*<@k9R=xbM`zingU$if3%S_m zmV5_KF&{Cp?s5;S@x?JZdL$bf(O!)Q1%k^AfrRQD5qGe&I`##(=&_GPEY+bkSxQvB zydMzB$Ldk6`NKa^AKiF=?2ywBi! zYh1eTG#4IKNA5%k$iisTyxX6N7{M=EKp(N*Va${k7}^Pc4i4L>6Z~0%)cmfPh!U0n zSl!j6qYnN;?M3ze>WtMrqs`azhp&>Y3+b><&CU?p&7$?ONl&)5RHLJUwCqi1M>+k< z#F51NS!4Z~_=;xGCl-f|4ZEPVpE}xMqkRk$?`~*q1>3Ld0d^S-B{WeEVpqa_<$dd<=UDDj!vH<%vyuOlj z(K6ZHBYTem*~}3(&>V3pBgNS>f9B@B(sx8VZC`!fE(0hwZV8z!(oO8;Hb+D=dZ(@* zog=_I#&-5xG(z?atP|0*e>TKX3#;PZejjd78u-BsqC+eCBJ5qeGZ z64}wgTJZpEvcKOs@?Cn-McrTLGH9>IMGi48T;oefD&o=5_s_p4iud`jOM&r`|5%ji zM~`jQ1Y4z>1xBNm?C)Co`h#P}`jqE(b;40}toz(z9@oWWCst*SOY8`H@w%!<0)0B- zCPw0l@ea7gc^*GI%ey}7b?kWe5Oy0q_}TR12i}X-dVh?Pdm4NK)^U)C=$& z`>G@R!(m1<>ngE)AI(Cq_hxV=5WL9q_!4u{g}_s5uIjxM>^yXghcn>~XxcLH z{yY7z8p5EUJ=YH)Ddu1Ys-qwCwG}Ir1a3h(U?FxvIg1W459jsbEwSdq6$)LY_S6ov zhIbl^eo?58QxkZ+Wr{Z<73!Teaaq4tJ4SdYK0r3a?Z_DI8@AgR8Ff=2PVdzBNla%| zcPUi4>b$D}s|ZQP3v0wu>RtY?ysxX+o5d28vk z=h?Rwk z`)3bNenZ9K-M9I!S#$ANv~mXij{e=6a(1DyrN}r`%Jqn06Bo);K?!-r_#gW>EyxDz zelhii{ynB-O>`L9al&CfE!b>5OIG$RHEBIXj!>44c= z1JTwTCPJkGu6K@JP^a#D(dCl{V-!Wy^gBLygMVfwb4{L@hidCl?d3*FAv1Tl;gBdD z^65v_FH2MdhUoCwqOfg`7d5bEu z(3m`PZ;NghpIQRjLS>?Xer?m9b>rPabgt4K<9`Y1&rMg;Z$+ukS}pE|wr8`rAIZ3@ zkKMcH;LgppVmIwxC`)+!-6?oT`U_g%Q|$2LbM8>6ePOJtX$jEJVT4)pxt^!$0y**r zi}qPaVx#+J?$U+N^fl00Mq~!R+c<01+7dE8xU*=~g3qL$$yHAjZ8@#%-LzqQL+$2x z<`aLmv@*)&$m1v`=;jPCec3f-CdTz?Uq^s-QE1P>mO~!xcu^*#2W!ZLujdvIaf7qovV!HB04#?+$}K(1V}}WZt>!vv*p6oHL=n5 zBf283j5sIlbGpoE@1JNEumLMWcyJqc+u6X<)b5-BqCkEGm(ti74lMCZlGPBEHgV##LLIwNV+EtYwWmScqMoq@yC z6SqZ2SUvO|DSFoyXkQ;znfSn%u3Nq%(&y~Zd{Fp2Dpc4%O+}qiGh_PP1`_rTC9IZg z$-l{6dShq;$`fr55yGUxDU5_1TFeP5KvMS5$#l*O1wUC&v!nwmw9YTc+v%PY$&x3o zdq(Wab+xOGStEwOxfc6fiT+d!SdrI^=##RS&RRSul=D>h@|vz85BuFl@lkZ0Zzus9 z+Mn%Vi+c0%*5=wSa~H1p=UVg~LNj^V7%8})z}!&FN)Yjpx$WOzzz@sq#31D9b2oJE z$8$zRKF=MY25|9uYQKG%_OmSZ={LYd+}YK;IojSh*y7J+-P2JI8jxGWG4DDI zD@B`*)rm>SGxe%7(t<|hOh&>(`HXj4E*>4}@jd)<`l+>)R$Hx|3|E(P*U$KA2r!rB zOIO3FzRf4KK4zcJp#M^z>&-J3{LdDSDt)ccgXvrPJPwAPT3ZBC!af{d{3gCJ%bv|w z{!bLh9!}c-2{7LD)7m5BVbKu*YFjW`jZDs%!+4F3q1*32k2UL7+x@uEUsH^Cr`I(E zQOABv1a7&p1>=>VQ7jPYao?nHLo9W?tWN?GNsT!jBZfFEa#eQnp=h_^d#7kg~?upeA7!KSO!$ZBU+)A;fKGv^6GQ-_7Xf)rf6wX69ZoO+A%5pa?vCEvCHRF8fZiI-^@J>C1EF(+Q`ZNl{=H{*b&Rcb=H9WR!W@w{P zO$=={ykczC2}$B9t?tIxPKOc7`tn**$llb3?I3}%9S)9dbu|eBbtPzYPtUEGsMS>FpKu9sdjALT)4g diff --git a/docs/voice-mode.md b/docs/voice-mode.md index c98ab44589eee31b87fb63dc53bbdd910fd900f1..4e85b01f244f95a887bd29c38b3696e5acaa264b 100644 GIT binary patch literal 14637 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 literal 17882 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 P8qGsh#yZ;1VsHC@g6VA( diff --git a/firmware/src/network.cpp b/firmware/src/network.cpp index ba6aa6e..b5b7667 100644 --- a/firmware/src/network.cpp +++ b/firmware/src/network.cpp @@ -1431,9 +1431,8 @@ bool voiceWsOpen(int sampleRate, int screenW, int screenH, bool includeImage) { } String mac = WiFi.macAddress(); - String path = basePath + "/api/device/" + mac + "/voice/ws"; + String path = basePath + "/api/device/" + mac + "/voice/ws?token=" + cfgDeviceToken; String extraHeaders = String("X-Device-Token: ") + cfgDeviceToken; - String startMsg = String("{\"type\":\"session.start\",\"sample_rate\":") + sampleRate + ",\"w\":" + screenW + ",\"h\":" + screenH