macOS companion app
โอเวอร์เลย์เสียง
วงจรชีวิตของโอเวอร์เลย์เสียง (macOS)
กลุ่มเป้าหมาย: ผู้มีส่วนร่วมของแอป macOS เป้าหมาย: ทำให้โอเวอร์เลย์เสียงคาดการณ์ได้เมื่อคำปลุกและกดเพื่อพูดทำงานทับซ้อนกัน
เจตนาปัจจุบัน
- หากโอเวอร์เลย์แสดงอยู่แล้วจากคำปลุกและผู้ใช้กดปุ่มลัด เซสชันจากปุ่มลัดจะ รับช่วง ข้อความที่มีอยู่แทนการรีเซ็ต โอเวอร์เลย์จะยังคงแสดงอยู่ขณะกดปุ่มลัดค้างไว้ เมื่อผู้ใช้ปล่อยปุ่ม: ส่งหากมีข้อความหลังตัดช่องว่างแล้ว มิฉะนั้นให้ปิด
- คำปลุกเพียงอย่างเดียวยังคงส่งอัตโนมัติเมื่อเงียบ ส่วนกดเพื่อพูดจะส่งทันทีเมื่อปล่อยปุ่ม
ดำเนินการแล้ว (9 ธ.ค. 2025)
- ตอนนี้เซสชันโอเวอร์เลย์มีโทเค็นต่อการจับเสียงแต่ละครั้ง (คำปลุกหรือกดเพื่อพูด) การอัปเดตข้อความบางส่วน/สุดท้าย/ส่ง/ปิด/ระดับจะถูกทิ้งเมื่อโทเค็นไม่ตรงกัน เพื่อหลีกเลี่ยงคอลแบ็กเก่า
- กดเพื่อพูดจะรับช่วงข้อความโอเวอร์เลย์ที่มองเห็นอยู่เป็นคำนำหน้า (ดังนั้นการกดปุ่มลัดขณะโอเวอร์เลย์คำปลุกแสดงอยู่จะคงข้อความไว้และต่อท้ายคำพูดใหม่) ระบบจะรอทรานสคริปต์สุดท้ายนานสูงสุด 1.5 วินาทีก่อนถอยกลับไปใช้ข้อความปัจจุบัน
- บันทึก chime/overlay ถูกปล่อยที่ระดับ
infoในหมวดหมู่voicewake.overlay,voicewake.pttและvoicewake.chime(เริ่มเซสชัน, บางส่วน, สุดท้าย, ส่ง, ปิด, เหตุผล chime)
ขั้นตอนถัดไป
- VoiceSessionCoordinator (แอกเตอร์)
- ถือครอง
VoiceSessionเพียงหนึ่งรายการในแต่ละครั้ง - API (อิงโทเค็น):
beginWakeCapture,beginPushToTalk,updatePartial,endCapture,cancel,applyCooldown - ทิ้งคอลแบ็กที่มีโทเค็นเก่า (ป้องกันไม่ให้ตัวรู้จำเก่าเปิดโอเวอร์เลย์อีกครั้ง)
- ถือครอง
- VoiceSession (โมเดล)
- ฟิลด์:
token,source(wakeWord|pushToTalk), ข้อความที่ยืนยันแล้ว/ชั่วคราว, แฟล็ก chime, ตัวจับเวลา (ส่งอัตโนมัติ, ว่าง),overlayMode(display|editing|sending), เส้นตาย cooldown
- ฟิลด์:
- การผูกโอเวอร์เลย์
VoiceSessionPublisher(ObservableObject) สะท้อนเซสชันที่ทำงานอยู่เข้าไปยัง SwiftUIVoiceWakeOverlayViewเรนเดอร์ผ่าน publisher เท่านั้น และไม่แก้ไข singleton ส่วนกลางโดยตรง- การกระทำของผู้ใช้บนโอเวอร์เลย์ (
sendNow,dismiss,edit) เรียกกลับเข้า coordinator พร้อมโทเค็นเซสชัน
- เส้นทางการส่งแบบรวม
- เมื่อ
endCapture: หากข้อความหลังตัดช่องว่างว่างเปล่า → ปิด; มิฉะนั้นperformSend(session:)(เล่น chime สำหรับการส่งหนึ่งครั้ง, ส่งต่อ, ปิด) - กดเพื่อพูด: ไม่มีการหน่วงเวลา; คำปลุก: หน่วงเวลาได้สำหรับการส่งอัตโนมัติ
- ใช้ cooldown สั้น ๆ กับรันไทม์คำปลุกหลังจากกดเพื่อพูดเสร็จ เพื่อไม่ให้คำปลุกถูกทริกเกอร์ซ้ำทันที
- เมื่อ
- การบันทึก
- Coordinator ปล่อยบันทึก
.infoในซับซิสเต็มai.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 -
ตรวจสอบว่ามีโทเค็นเซสชันที่ทำงานอยู่เพียงหนึ่งรายการ คอลแบ็กเก่าควรถูกทิ้งโดย coordinator
-
ตรวจให้แน่ใจว่าการปล่อยปุ่มกดเพื่อพูดเรียก
endCaptureพร้อมโทเค็นที่ทำงานอยู่เสมอ หากข้อความว่างเปล่า ควรเห็นdismissโดยไม่มี chime หรือการส่ง
ขั้นตอนการย้าย (แนะนำ)
- เพิ่ม
VoiceSessionCoordinator,VoiceSessionและVoiceSessionPublisher - รีแฟกเตอร์
VoiceWakeRuntimeให้สร้าง/อัปเดต/สิ้นสุดเซสชันแทนการแตะVoiceWakeOverlayControllerโดยตรง - รีแฟกเตอร์
VoicePushToTalkให้รับช่วงเซสชันที่มีอยู่และเรียกendCaptureเมื่อปล่อยปุ่ม; ใช้ runtime cooldown - เชื่อม
VoiceWakeOverlayControllerเข้ากับ publisher; ลบการเรียกโดยตรงจาก runtime/PTT - เพิ่มการทดสอบอินทิเกรชันสำหรับการรับช่วงเซสชัน, cooldown และการปิดเมื่อข้อความว่างเปล่า