تخطَّ إلى المحتوى
kazma.
البحث في كاظمه والتوثيق
EN

الصوت والوسائط

تستطيع كاظمه السماع (تحويل الكلام إلى نص)، والتحدث (تحويل النص إلى كلام)، والرؤية (صور/PDF/مستندات) عبر كل منصات الدردشة — Telegram وDiscord وSlack وواجهة الويب.


مخزن مفاتيح واحد، ومنتقيان.

الواجهةما هي
الإعدادات → المزوّدونمن يحمل مفتاح API (OpenAI وGroq وCohere و…). زر Test لدى المزوّد يرسل /chat/completions — وسيرفض Whisper عمدًا.
الإعدادات → الصوتكيف تسمع كاظمه وتتحدث: اسم مزوّد STT، ونموذج Whisper، واللغة، وصوت TTS. تُقرأ المفاتيح من بطاقة المزوّد المطابقة.

Whisper ليس نموذج دردشة. هو مخفي عن منتقيات الدردشة وعن Discover كنموذج دردشة قابل للتحديد. لا تضبطه كنموذج الدردشة النشط.

صوت كاظمه قائم على الأدوار افتراضيًا (STT → LangGraph → TTS) على كل منصة. في واجهة الويب، يفتح زر Live نافذة /ws/voice: نفس مخطط المُشرف ذي نقاط الحفظ (checkpointed) ونفس خيط الدردشة/السجل كالرسائل المكتوبة — الصوت الحي فمٌ لا دماغ ثانٍ. تكلّم؛ يمكنك المقاطعة أثناء كلامه.

كاشف النشاط الصوتي القائم على الطاقة (Energy VAD) هو التنفيذ. KAZMA_SILERO_VAD=1 يختار مصنّف إطارات أفضل عند توفره فعلًا: WebRTC VAD مع pip install webrtcvad (8/16/32/48 kHz). يتطلب Silero نموذجًا مضمّنًا لا تُسلّمه كاظمه بعد — وحتى ذلك الحين لا يفعل العلم شيئًا وراء ذلك، ويعمل Energy VAD (يُسجَّل ذلك مرة واحدة). لا تنزيل نماذج وقت التشغيل.

الصوت الحي على الويب (/ws/voice)

Section titled “الصوت الحي على الويب (/ws/voice)”
  • دماغ واحد، خيط واحد. يُنسخ كلامك، ويُرسل إلى نفس المخطط الذي يستخدمه /api/chat/stream، ويُدوَّن في نفس المحادثة. مقبس الصوت يكتب سطر المستخدم (كما يفعل Send للنص المكتوب)؛ السجل يكتب سطر المساعد — وواجهة الدردشة ترسم الدور منه.
  • TTS ينطق الرد النهائي فقط، جملة جملة (كل مقطع MP3 مكتمل، فيبدأ التشغيل بالجملة الأولى). تخطيط المُشرف، وثرثرة الأدوات، والأدوار الفاشلة (إشعارات ⚠️) لا تُنطق أبدًا.
  • الأدوات الخطرة تتوقف للموافقة كالدردشة المكتوبة: تحصل على بطاقة الموافقة المعتادة في واجهة الدردشة (POST /api/approve/{thread_id} للاستئناف)؛ يرد الصوت «الموافقة مطلوبة» ويواصل الاستماع. إن كان المقبس ما زال مفتوحًا حين ينتهي الدور المُوافَق عليه، يُنطق الرد.
  • المقاطعة (barge-in): الكلام مجددًا يوقف التشغيل ويبدأ دورًا جديدًا (الكلام الجديد رسالة مستخدم جديدة — تُلغي الجارية، نفس قاعدة الدردشة المكتوبة).
  • أمسك الميكروفون (الزر الدائري) للإملاء في محرر الرسائل؛ النقرة تُتجاهل. وضع Live يواصل الاستماع عبر الصمت — فرقعة فتح الميكروفون ليست «فشل النسخ».
  • يوثّق المقبس نفسه كأي WS آخر ويحلّ جلسة الدردشة من جهة الخادم؛ الجلسة غير المعروفة أو خيط المنصة (gw-*) يُرفض.

ثنائي الاتجاه عبر LiveKit (الويب فقط، ترقية نقل اختيارية)

Section titled “ثنائي الاتجاه عبر LiveKit (الويب فقط، ترقية نقل اختيارية)”

تحتاج خادم LiveKit (استضافة ذاتية أو LiveKit Cloud). كاظمه لا تبدأ واحدًا.

نافذة طرفيّة
LIVEKIT_URL=wss://your-project.livekit.cloud
LIVEKIT_API_KEY=APIxxxx
LIVEKIT_API_SECRET=...
# Kill-switch: KAZMA_VOICE_DUPLEX=0

أو عبر ConfigStore ‏voice.livekit.url / api_key / api_secret. عندها ينضم زر Live في / إلى غرفة (POST /api/voice/livekit/token) وتُلغي المقاطعة TTS حين تتكلم. حين يكون الثنائي مفعّلًا، ينشر المتصفح أيضًا TTS داخل الغرفة (publishTrack) ليكون مسار الوسائط صادقًا (tts_in_room على /api/voice/livekit/status). LiveKit هو نقل WebRTC + إلغاء صدى المتصفح — ليس مستوى وسائط خادميًا وليس دماغًا ثانيًا؛ حلقة LangGraph ‏/ws/voice ما زالت تملك المحادثة. Telegram / Discord / Slack ما زالت ملاحظات صوتية.

لا يُستخدم OpenAI Realtime وGemini Live إطلاقًا: لا يستطيعان البقاء codec-only دون امتلاك حلقة الأدوات، وهو ما كان سيتجاوز HITL. يعمل الصوت دائمًا على مزوّدي STT/TTS عبر REST أدناه، ولا يوجد إعداد يغيّر ذلك.

الصوت كتلة إعداد واحدة تتحكم بكل المنصات. عند التفعيل يُنسخ الصوت الوارد إلى نص قبل وصوله للوكيل. ردود الملاحظات الصوتية التلقائية (tts_reply) تولّد صوتًا فقط عندما كان الدور الوارد صوتيًا (وليس لنص عادي).

دردشة الويب المكتوبة لا تشغّل TTS تلقائيًا. اضغط 🔊 على الرسالة لتسمعها. الصوت الحي (/ws/voice) ما زال يقرأ الرد أثناء ذلك الوضع. الإعدادات → الصوت لا تعيد تسليح الكلام في المتصفح بعد التحديث.

في kazma.yaml تحت gateway، أو وقت التشغيل عبر الويب → الإعدادات → الصوت:

gateway:
voice:
enabled: true
tts_reply: true # platform auto voice-note replies (toggle in UI)
stt_provider: openai # speech-to-text provider (not the chat model)
stt_language: auto # auto, ar, en, … (Settings is a dropdown)
tts_provider: edgetts # text-to-speech provider
tts_voice: default
tts_output_format: mp3
الإعدادالأثر
نظام الصوت (enabled)تشغيل/إيقاف رئيسي لـ STT + TTS
ردود صوتية تلقائية (tts_reply)Telegram/Discord/Slack: نطق الرد بعد وارد صوتي. الإيقاف = ردود نصية فقط؛ STT يستمر
لغة STT (stt_language)auto يترك الكشف للمزوّد. ar يختار مسار STT العربي لدى Cohere حين يكون Cohere مزوّد STT
مزوّد STT / TTSالاسم فقط. المفتاح من نفس بطاقة الإعدادات → المزوّدون

نفس المفاتيح تُقرأ حيًا من كل المُكيّفات (voice_helpers.py).

نموذج الدردشة لدى NVIDIA (integrate.api.nvidia.com) ليس ASR. إن كان مزوّد STT هو nvidia دون voice.stt_base_url يشير إلى Speech NIM، تتخطاه كاظمه وترجع إلى OpenAI ثم Groq.

المزوّدالمفتاحيحتاجملاحظات
OpenAI Whisperopenaiبطاقة المزوّد / OPENAI_API_KEYالافتراضي؛ متين عبر اللغات.
Groq Whispergroqبطاقة المزوّد / GROQ_API_KEYالأسرع؛ ممتاز للزمن الحقيقي.
Coherecohereبطاقة المزوّد / COHERE_API_KEYنموذج عربي حين تكون اللغة ar.
NVIDIA Speech NIMnvidiavoice.stt_base_url + مفتاحليس رابط integrate الخاص بنموذج الدردشة.
faster-whisper (محلي)faster-whisperpip install faster-whisperعلى الجهاز؛ بلا مفتاح API.
المزوّدالمفتاحيحتاجملاحظات
Edge TTSedgettsلا شيءمجاني — الافتراضي
OpenAIopenaiOPENAI_API_KEYأصوات عصبية عالية الجودة
NVIDIA NIMnvidiaNVIDIA_API_KEY
Kokoro (محلي)kokoroتثبيت محلي
Coqui (محلي)coquiتثبيت محلي
المنصةوارد (أنت → الوكيل)صادر (الوكيل → أنت)
Telegramملاحظة صوتية → نصرد صوتي فقط إن tts_reply وكان الدور صوتيًا
Discordمرفق صوتي → نصنفس الشرط؛ رفع ملف
Slackملف صوتي → نصنفس الشرط
Web UIPOST /api/voice/sttPOST /api/voice/tts / /ws/voice (لا يُقيَّد بـ tts_reply المنصة)

إن لم يُضبط STT، ملاحظة صوتية واردة تعيد رسالة احتياطية ودّية بدل الفشل الصامت.


عقد الرسالة يحمل قائمة attachments (Attachment في gateway.py) إلى جانب النص. كل مرفق له kind (image / file / audio / video)، mime، filename، وإما data في الذاكرة أو url قابل للجلب.

كيف يستلم الوكيل الوسائط

Section titled “كيف يستلم الوكيل الوسائط”
نوع المرفقالسلوك
صورة (PNG/JPEG/WEBP/GIF، ≤ 8 MB، نموذج يدعم الرؤية)تُضمَّن ككتلة رؤية image_url بترميز base64 — يرى النموذج اللغوي الصورة مباشرة. النماذج النصية فقط تحصل على مسار حفظ-و-كعب نصي بدل image_url (تجنّبًا لأخطاء 400 من المزوّد).
مستند (PDF/DOCX/XLSX/PPTX/CSV/… عند توفر قدرة تحليل مستندات)يُحفظ تحت kazma-data/attachments/. تحلّل المنصة تلقائيًا مقتطفًا محدودًا عبر DocumentService.read_transient_sync (في عامل المستندات المعزول نفسه الذي يعالج الرفع، وتحت سياسة PDF نفسها؛ ولا يُرسَل المقتطف أبدًا إلى محلِّل بعيد)، وتغلّفه بسياج غير موثوق (source="document_attachment")، وتضيف مؤشرًا إلى المحتوى الكامل (فضّل أدوات document_read الدائمة / أدوات المنصة حين يكون الملف مُستوعَبًا أيضًا).
غير ذلك / غير قابل للتحليل / فوق السعةيُحفظ ويُمثَّل بكعب نصي (file_read أو تلميح مسار) ليبقى حجم الموجّه محدودًا.

الحدود (مسار مرفقات بوابة الدردشة): 20 MiB للملف، و10 ملفات، و50 MiB إجمالًا. منصة ذكاء المستندات الدائمة تستخدم حدود استقبال خاصة بها (50 MiB افتراضيًا للملف).

صيغة الرؤية OpenAI (content: [{type:image_url,...}, {type:text,...}]) تمر عبر llm_provider.py كما هي — أي نموذج يدعم الرؤية يعمل للصور المضمّنة.

المنصةواردصادر
Telegramصورة / مستند / فيديو / رسومsendPhoto / sendDocument / …
Discordمرفقات + embeds صوررفع multipart
Slackfiles (Socket Mode)مسار رفع Slack الخارجي
Web UIPOST /api/chat/upload (حد 20 MB)روابط تنزيل

إرسال وسائط من واجهة الويب

Section titled “إرسال وسائط من واجهة الويب”
  1. زر المرفق (📎) في صندوق الدردشة.
  2. ملفات نصية صغيرة (≤ 1 MB) تُضمَّن من جهة العميل.
  3. صور وPDF وثنائي تُرفع عبر POST /api/chat/upload.

الوكيل يمكنه أيضًا إنتاج وسائط — مثل generate_image → kazma-data/images/.


الصوت والوسائط اختيارية. الصوت افتراضيًا enabled: false. التقاط الوسائط يعمل حيث يدعمه المُكيّف؛ كبح الصادر يكون لكل أداة (الوكيل يرسل فقط ما ينشئه صراحة).