macOS companion app
همپوشانی صوتی
چرخهٔ عمر همپوشان صوتی (macOS)
مخاطب: مشارکتکنندگان برنامهٔ macOS. هدف: قابل پیشبینی نگه داشتن همپوشان صوتی وقتی واژهٔ بیدارباش و فشار برای صحبت همپوشانی دارند.
هدف فعلی
- اگر همپوشان از طریق واژهٔ بیدارباش از قبل نمایان باشد و کاربر کلید میانبر را فشار دهد، نشست کلید میانبر بهجای بازنشانی متن موجود، آن را میپذیرد. همپوشان تا زمانی که کلید میانبر نگه داشته شده است باقی میماند. وقتی کاربر رها میکند: اگر متن برشخوردهای وجود داشته باشد ارسال شود، وگرنه بسته شود.
- واژهٔ بیدارباش بهتنهایی همچنان هنگام سکوت بهطور خودکار ارسال میکند؛ فشار برای صحبت بلافاصله هنگام رها کردن ارسال میکند.
پیادهسازیشده (۹ دسامبر ۲۰۲۵)
- نشستهای همپوشان اکنون برای هر ضبط (واژهٔ بیدارباش یا فشار برای صحبت) یک توکن دارند. بهروزرسانیهای جزئی/نهایی/ارسال/بستن/سطح وقتی توکن مطابقت نداشته باشد کنار گذاشته میشوند و از callbackهای کهنه جلوگیری میشود.
- فشار برای صحبت هر متن نمایان همپوشان را بهعنوان پیشوند میپذیرد (بنابراین فشار دادن کلید میانبر وقتی همپوشان بیدارباش باز است، متن را نگه میدارد و گفتار جدید را به آن اضافه میکند). پیش از بازگشت به متن فعلی، تا ۱٫۵ ثانیه برای transcript نهایی منتظر میماند.
- ثبت گزارش chime/همپوشان با سطح
infoدر دستههایvoicewake.overlay،voicewake.pttوvoicewake.chimeمنتشر میشود (شروع نشست، جزئی، نهایی، ارسال، بستن، دلیل chime).
گامهای بعدی
- VoiceSessionCoordinator (اکتور)
- در هر زمان دقیقاً مالک یک
VoiceSessionاست. - API (مبتنی بر توکن):
beginWakeCapture،beginPushToTalk،updatePartial،endCapture،cancel،applyCooldown. - callbackهایی را که توکنهای کهنه دارند کنار میگذارد (از باز کردن دوبارهٔ همپوشان توسط تشخیصدهندههای قدیمی جلوگیری میکند).
- در هر زمان دقیقاً مالک یک
- VoiceSession (مدل)
- فیلدها:
token،source(wakeWord|pushToTalk)، متن ثبتشده/موقت، پرچمهای chime، تایمرها (ارسال خودکار، بیکاری)،overlayMode(display|editing|sending)، مهلت cooldown.
- فیلدها:
- اتصال همپوشان
VoiceSessionPublisher(ObservableObject) نشست فعال را در SwiftUI بازتاب میدهد.VoiceWakeOverlayViewفقط از طریق publisher رندر میشود؛ هرگز singletonهای سراسری را مستقیم تغییر نمیدهد.- کنشهای کاربر در همپوشان (
sendNow،dismiss،edit) با توکن نشست به coordinator برمیگردند.
- مسیر ارسال یکپارچه
- در
endCapture: اگر متن برشخورده خالی باشد → بستن؛ وگرنهperformSend(session:)(chime ارسال را یک بار پخش میکند، ارسال میکند، میبندد). - فشار برای صحبت: بدون تأخیر؛ واژهٔ بیدارباش: تأخیر اختیاری برای ارسال خودکار.
- پس از پایان فشار برای صحبت، یک cooldown کوتاه روی runtime بیدارباش اعمال کنید تا واژهٔ بیدارباش بلافاصله دوباره فعال نشود.
- در
- ثبت گزارش
- coordinator گزارشهای
.infoرا در subsystemai.openclawو دستههایvoicewake.overlayوvoicewake.chimeمنتشر میکند. - رویدادهای کلیدی:
session_started،adopted_by_push_to_talk،partial،finalized،send،dismiss،cancel،cooldown.
- coordinator گزارشهای
فهرست بررسی اشکالزدایی
-
هنگام بازتولید همپوشان گیرکرده، گزارشها را استریم کنید:
sudo log stream --predicate 'subsystem == "ai.openclaw" AND category CONTAINS "voicewake"' --level info --style compact -
بررسی کنید فقط یک توکن نشست فعال وجود داشته باشد؛ callbackهای کهنه باید توسط coordinator کنار گذاشته شوند.
-
مطمئن شوید رها کردن فشار برای صحبت همیشه
endCaptureرا با توکن فعال فراخوانی میکند؛ اگر متن خالی باشد، انتظارdismissبدون chime یا ارسال را داشته باشید.
گامهای مهاجرت (پیشنهادی)
VoiceSessionCoordinator،VoiceSessionوVoiceSessionPublisherرا اضافه کنید.VoiceWakeRuntimeرا بازآرایی کنید تا بهجای دست زدن مستقیم بهVoiceWakeOverlayController، نشستها را ایجاد/بهروزرسانی/پایان دهد.VoicePushToTalkرا بازآرایی کنید تا نشستهای موجود را بپذیرد و هنگام رها کردنendCaptureرا فراخوانی کند؛ cooldown مربوط به runtime را اعمال کنید.VoiceWakeOverlayControllerرا به publisher وصل کنید؛ فراخوانیهای مستقیم از runtime/PTT را حذف کنید.- آزمونهای یکپارچهسازی برای پذیرش نشست، cooldown و بستن متن خالی اضافه کنید.