macOS companion app
پوشش صوتی
چرخهٔ عمر لایهٔ رویی صوتی (macOS)
مخاطب: مشارکتکنندگان برنامهٔ macOS. هدف: حفظ رفتار پیشبینیپذیر لایهٔ رویی صوتی هنگام همپوشانی واژهٔ بیدارباش و فشار برای صحبت.
رفتار
- اگر لایهٔ رویی از قبل بهدلیل واژهٔ بیدارباش قابل مشاهده باشد و کاربر کلید میانبر را فشار دهد، نشست کلید میانبر بهجای بازنشانی متن، متن موجود را بهکار میگیرد. تا زمانی که کلید میانبر نگه داشته شده است، لایهٔ رویی باز میماند. هنگام رهاسازی: اگر پس از حذف فاصلههای ابتدا و انتها متنی وجود دارد، آن را ارسال میکند؛ در غیر این صورت، لایهٔ رویی را میبندد.
- واژهٔ بیدارباش بهتنهایی همچنان هنگام سکوت بهطور خودکار ارسال میکند؛ فشار برای صحبت نیز بلافاصله پس از رهاسازی ارسال میکند.
پیادهسازی
VoiceSessionCoordinator(apps/macos/Sources/OpenClaw/VoiceSessionCoordinator.swift) تنها مالک نشست صوتی فعال است. این مؤلفه یک تکنمونهٔ@MainActor @Observableاست، نه یک actor. رابط برنامهنویسی:startSession،updatePartial،finalize،sendNow،dismiss،updateLevel،snapshot. هر نشست یک توکنUUIDدارد؛ فراخوانیهایی با توکن منقضی یا نامطابق نادیده گرفته میشوند.VoiceWakeOverlayController(VoiceWakeOverlayController+Session.swift) لایهٔ رویی را نمایش میدهد و کنشهای کاربر (requestSend،dismiss) را با استفاده از توکن نشست به هماهنگکننده بازمیگرداند. این مؤلفه هرگز مالک وضعیت نشست نیست.- فشار برای صحبت (
VoicePushToTalk.begin()) هر متن قابل مشاهده در لایهٔ رویی را بهعنوانadoptedPrefix(از طریقVoiceSessionCoordinator.shared.snapshot()) بهکار میگیرد؛ بنابراین، فشردن کلید میانبر هنگامی که لایهٔ رویی بیدارباش باز است، متن را حفظ میکند و گفتار جدید را به آن میافزاید. هنگام رهاسازی، تا ۱٫۵ ثانیه منتظر رونوشت نهایی میماند و سپس، در صورت آمادهنشدن آن، از متن فعلی استفاده میکند. - هنگام
dismiss، لایهٔ روییVoiceSessionCoordinator.overlayDidDismissرا فراخوانی میکند که باعث اجرایVoiceWakeRuntime.refresh(state:)میشود؛ در نتیجه، بستن دستی با X، بستن بهدلیل خالیبودن متن و بستن پس از ارسال، همگی گوشدادن برای واژهٔ بیدارباش را از سر میگیرند. - مسیر یکپارچهٔ ارسال: اگر متن پس از حذف فاصلههای ابتدا و انتها خالی باشد، لایهٔ رویی بسته میشود؛ در غیر این صورت،
sendNowصدای اعلان ارسال را یکبار پخش میکند، متن را از طریقVoiceWakeForwarderمیفرستد و سپس لایهٔ رویی را میبندد.
ثبت گزارش
زیرسامانهٔ صوتی ai.openclaw است؛ هر مؤلفه گزارشها را در دستهٔ مخصوص خود ثبت میکند:
| دسته | مؤلفه |
|---|---|
voicewake.coordinator |
VoiceSessionCoordinator |
voicewake.overlay |
VoiceWakeOverlayController/VoiceWakeOverlay |
voicewake.ptt |
کلید میانبر و ضبط فشار برای صحبت |
voicewake.runtime |
زمان اجرای واژهٔ بیدارباش |
voicewake.chime |
پخش صدای اعلان |
voicewake.sync |
همگامسازی تنظیمات سراسری |
voicewake.forward |
ارسال رونوشت |
voicewake.meter |
پایشگر سطح میکروفون |
فهرست بررسی اشکالزدایی
-
هنگام بازتولید لایهٔ رویی گیرکرده، گزارشها را بهصورت جریانی مشاهده کنید:
bash sudo log stream --predicate 'subsystem == "ai.openclaw" AND category CONTAINS "voicewake"' --level info --style compact -
بررسی کنید که فقط یک توکن نشست فعال وجود داشته باشد؛ فراخوانیهای برگشتی منقضی توسط هماهنگکننده نادیده گرفته میشوند.
-
تأیید کنید که رهاسازی فشار برای صحبت همیشه
end()را با توکن فعال فراخوانی میکند؛ اگر متن خالی باشد، انتظار میرود لایهٔ رویی بدون صدای اعلان یا ارسال بسته شود.
مرتبط
Was this useful?