الصوت
الصوت هو إمكانية وسائط اختيارية. هو منفصل عن مسار مزود LLM الأساسي ويستخدم بيانات اعتماد متغيرات البيئة المباشرة فقط.
إذا كانت مزودات الصوت أو أدوات الصوت المحلية أو بيانات الاعتماد الحية غير متوفرة، يستمر تشغيل CLI والبوابة النصي الأساسي دون تغيير. الصوت لا يحظر بقية النظام.
ما يغطيه الصوت
| الإمكانية | الوظيفة |
|---|---|
| TTS | تحويل ردود العميل النصية إلى صوت. |
| STT | تحويل صوت المستخدم إلى نص مكتوب. |
| Auto-TTS | ت vocalizing ردود البوابة اختياريًا لكل محادثة. |
| CLI push-to-talk | تسجيل إدخال الميكروفون المحلي وإدخال النص في جلسة CLI الحالية. |
نضج المزود في v0.1.0
TTS المستضاف — مستقر
| المزود | ملاحظات |
|---|---|
OpenAI | مزود TTS مستضاف يتطلب مفتاح API. يستخدم محلل بيانات اعتماد OpenAI الصوتي المشترك. |
| ElevenLabs | يستخدم xi-api-key وحودود النص الخاصة بالمزود. |
| MiniMax | يفك تشفير استجابات الصوت base64 JSON. |
| Gemini | يرسل speechConfig.voiceConfig.prebuiltVoiceConfig.voiceName. |
| xAI | يستخدم نقطة النهاية الأصلية {baseUrl}/tts؛ غير متوافق مع OpenAI. |
Edge | خيار الإعداد الموجّه الموصى به/الافتراضي. لا يتطلب مفتاح API؛ يُرسل نص التوليف إلى خدمة Microsoft Edge speech، لذلك فهو شبكي وليس TTS محليًا/offline. يُرجع MP3 (audio/mpeg). |
STT المستضاف — مستقر
| المزود | ملاحظات |
|---|---|
| OpenAI | يستخدم محلل بيانات اعتماد OpenAI الصوتي المشترك. |
| Groq | بحث مباشر عن مفتاح البيئة. |
| xAI | يستخدم نقطة النهاية الأصلية {baseUrl}/stt؛ غير متوافق مع OpenAI. |
STT المحلي — مستقر
| المحرك | ملاحظات |
|---|---|
faster-whisper | الافتراضي عند stt.provider: "local" في v0.1.0. يستخدم بيئة Python المُدارة من EstaCoda ما لم تُضبط Python مخصصة. |
command | اختيار صريح عبر stt.local.engine: "command". يشغل قالب أمر مُعد؛ يفضل نص transcript من stdout. |
مؤجل أو تجريبي
- مزودا TTS المحليان/offline
neuttsوkittentts— غير مُنفذين في v0.1.0. - Mistral TTS/STT — قد توجد أشكال الإعدادات، لكن التنفيذ غير متاح.
لا تُعد مزودات مؤجلة للإنتاج.
الإعدادات
إعدادات الصوت موجودة في الملف الشخصي المحدد:
~/.estacoda/profiles/<profile-id>/config.json
مثال:
{
"tts": {
"enabled": true,
"provider": "openai",
"openai": {
"model": "gpt-4o-mini-tts",
"voice": "alloy",
"apiKeyEnv": "VOICE_TOOLS_OPENAI_KEY"
}
},
"stt": {
"enabled": true,
"provider": "openai",
"openai": {
"model": "gpt-4o-mini-transcribe",
"apiKeyEnv": "VOICE_TOOLS_OPENAI_KEY"
}
},
"voice": {
"autoTts": false,
"autoTtsMaxCharsPerReply": 1200,
"autoTtsMaxCharsPerHourPerChat": 5000
}
}
الحقول الأساسية:
| الحقل | المعنى |
|---|---|
tts.provider | القيم المنفذة: openai، elevenlabs، minimax، gemini، xai، edge. |
tts.enabled | عند false، يفشل TTS حتى لو كانت البيانات الاعتماد موجودة. |
stt.provider | القيم المنفذة: openai، groq، xai، local. |
stt.enabled | عند false، يفشل STT قبل آثار النسخ. |
voice.autoTts | الإعداد الافتراضي العام لـ auto-TTS في البوابة. الافتراضي false. |
voice.autoTtsMaxCharsPerReply | حد اختياري لكل رد يُفحص قبل التوليف. |
voice.autoTtsMaxCharsPerHourPerChat | حد اختياري ساعيّ لكل منصة/محادثة. |
الإعداد الموجّه
يسألك Setup Editor وOnboarding Wizard عن اختيار مزود STT ومزود TTS. لا يطلبان أسماء النماذج أو أسماء مراجع متغيرات البيئة؛ توفر إعدادات التشغيل الافتراضية النماذج والأصوات وإعدادات المزود.
لمزودي Voice المستضافين، يجمع الإعداد مفتاح API الحقيقي عبر إدخال masked. تخزن خطوة review/apply مراجع متغيرات البيئة فقط في الإعدادات، وتكتب قيم الأسرار المحلية للملف الشخصي إلى .env الخاص بالملف الشخصي المحدد بعد التأكيد. لا تُخزن مفاتيح API الخام في الإعدادات، ولا تظهر في review manifests، ولا تُدرج في prompt context، ولا تُسجل أو تُعاد في الأخطاء.
المزودون بلا مفتاح هم STT local وTTS edge. لا يتطلب edge مفتاح API، لكنه ما زال ينفذ طلبًا شبكيًا إلى خدمة Microsoft Edge speech ويرسل نص التوليف إلى تلك الخدمة. المزودون المستضافون الذين يتطلبون مفتاحًا هم STT openai وgroq وxai؛ وTTS openai وelevenlabs وminimax وgemini وxai. المزودون المؤجلون هم STT mistral؛ وTTS mistral وneutts وkittentts.
يمكن للإعداد إعادة استخدام بيانات اعتماد موجودة عبر مراجع متغيرات البيئة مثل VOICE_TOOLS_OPENAI_KEY وOPENAI_API_KEY وGEMINI_API_KEY وGROQ_API_KEY وXAI_API_KEY، وعبر إعدادات/مسارات المزود المتوافقة الموجودة حيثما يكون ذلك مدعومًا. تبقى أعلام CLI المباشرة للمشغل مثل estacoda voice setup --tts-model و--stt-model و--tts-api-key-env و--stt-api-key-env و--tts-api-key و--stt-api-key متاحة للإعداد الصريح عبر السكربتات.
بيانات الاعتماد
تخزن إعدادات الصوت مراجع متغيرات بيئة مباشرة فقط. لا توجد مجمعات بيانات اعتماد أو وسطاء بوابة أو بدائل.
Edge TTS لا يستخدم مفتاح API. لكنه ما زال ينفذ طلبًا شبكيًا إلى خدمة Microsoft Edge speech ويرسل نص التوليف إلى تلك الخدمة.
ترتيب محلل بيانات اعتماد OpenAI الصوتي:
config.openai.apiKeyEnvVOICE_TOOLS_OPENAI_KEYOPENAI_API_KEY، فقط عندما يكون المتغير المُعد هو الافتراضيVOICE_TOOLS_OPENAI_KEY
متغير بيئة مخصص مفقود لا يعود إلى OPENAI_API_KEY. لا يتم تسجيل المفاتيح المحلولة أو إرجاعها في الأخطاء.
ملاحظات خاصة بالمزود:
- xAI TTS يستخدم
voiceId،language،sampleRate،bitRate،baseUrl،apiKeyEnv، وspeedالاختياري. لا يستخدمtts.xai.model. - xAI STT يستخدم
baseUrl/base_url،apiKeyEnv/api_key_env،languageالاختياري،format،diarize،keyterms،fillerWords، وتلميحات raw-audio. لا يستخدمstt.xai.model. - Gemini TTS يرسل
speechConfig.voiceConfig.prebuiltVoiceConfig.voiceName. - Edge TTS يستخدم
tts.edge.voiceوtts.edge.speedالاختياري و fallback منtts.speed. الصوت الافتراضي هوen-US-AriaNeural.
CLI push-to-talk
وضع صوت CLI محلي للملف الشخصي:
estacoda voice mode on # تفعيل إدخال push-to-talk
estacoda voice mode tts # تفعيل push-to-talk مع تشغيل TTS محلي على أفضل وجه
estacoda voice mode off # إلغاء التفعيل
estacoda voice mode status # عرض الوضع الحالي
ملف الحالة:
~/.estacoda/profiles/<profile-id>/cli-voice-mode.json
السلوك:
- تسجيل إدخال الميكروفون المحلي بصيغة WAV أحادية 16 كيلوهرتز.
- كتابة الصوت فقط في مساحة temp audio الخاصة بالملف الشخصي المحدد.
- النسخ عبر مزود STT المُعد.
- طباعة النص المكتوب.
- إدخال النص غير الفارغ كدورة مستخدم تالية في جلسة CLI الحالية.
- في وضع
tts، التشغيل المحلي على أفضل وجه بعد توفر الرد. - أوامر التشغيل المدعومة:
afplay،aplay،paplay،ffplay. - إذا لم يكن مشغل محلي متاحًا، يتم تخطي التشغيل بسلاسة.
كشف الميكروفون:
| البيئة | السلوك |
|---|---|
| جلسة SSH | يُبلغ بأن الميكروفون المحلي غير متاح؛ يقترح تسجيل محلي أو إدخال مسار. |
| Termux | يستخدم termux-microphone-record عند توفره. |
| WSL / PulseAudio | يفحص pactl list sources. |
| Linux / macOS أصلي | يستخدم أوامر تسجيل مدعومة (sox، arec، rec) عند توفرها. |
إضافات الصوت الأصلية لـ Node خارج النطاق.
Auto-TTS في البوابة
تُحلل أوامر /voice في البوابة بواسطة ChannelGateway، وليس بواسطة المحولات. تُعرض المحولات methods القدرات حيثما لزم.
حالة الصوت لكل محادثة محلية للملف الشخصي:
~/.estacoda/profiles/<profile-id>/gateway/voice-mode.json
الأوضاع:
| الوضع | المعنى |
|---|---|
off | عدم auto-TTS ردود البوابة لهذه المحادثة. |
voice_only | auto-TTS فقط للردود على الرسائل الصوتية الواردة التي أنتجت نصًا. |
all | auto-TTS للردود النصية المؤهلة في هذه المحادثة. |
الأوامر:
| الأمر | السلوك |
|---|---|
/voice on | ضبط المحادثة على voice_only. |
/voice voice | بديل لـ voice_only. |
/voice all | ضبط المحادثة على all. |
/voice tts | بديل لـ all. |
/voice off | ضبط المحادثة على off. |
/voice status | الإبلاغ عن الوضع المحلول للمحادثة. |
/voice channel | Discord فقط؛ ينضم إلى قناة الصوت الحالية للمتصل عند السماح. |
/voice leave | Discord فقط؛ يغادر قناة صوت Discord النشطة. |
معالجة /voice في محادثات المجموعة تتبع مصادقة البوابة الحالية، ومنطق الذكر، وبوابة الاستجابة الحرة. المستخدمون غير المصرح لهم لا يمكنهم تغيير حالة الصوت لكل محادثة.
حقن النص المكتوب
يستخدم STT الناجح بالضبط:
[Voice message transcript]
{text}
بعد النسخ الناجح، تُزال مرفق الصوت الأصلي من سياق النموذج. فشل النسخ لا يحول ملف صوتي غير صالح إلى نص مرئي للنموذج.
كبت النصوص المكررة هو لكل (platform, chatId):
- مخزن دائري لآخر 5 نصوص مُطابقة.
- نافذة مقارنة مدتها 12 ثانية.
- التطبيع يقلم، يحول لأحرف صغيرة، يضغط المسافات، ويحذف علامات الترقيم.
- التطابقات الدقيقة للتجزئة/النص تُسقط.
- نسبة التطابق القريب تُطبق فقط عندما يكون كلا النصين 16 حرفًا على الأقل.
سلوك Auto-TTS
Auto-TTS في البوابة اختياري والنص أولًا:
voice.autoTtsافتراضيًاfalse.- إذا لم يكن هناك تجاوز لكل محادثة، فإن
voice.autoTts: trueيعيّنvoice_only، وليسall. - توصيل النص يبقى أساسيًا.
- Auto-TTS هو أفضل جهد وفتح للفشل إلى النص.
- فشل المزود أو التوصيل يسجل تحذيرات آمنة ويترك النص سليمًا.
- في Telegram، يفعّل
/voice onالردود المنطوقة فقط بعد الرسائل الصوتية الواردة، ويجعل/voice allالردود النصية المؤهلة منطوقة أيضًا، ويعطل/voice offالردود المنطوقة، ويعرض/voice statusالوضع المحلول. - مع
/voice on، تتبع رسالة Telegram الصوتية الواردة هذا المسار: Telegram voice message -> STT transcript -> agent text response -> configured TTS provider -> Telegram voice/audio reply.
Auto-TTS يتخطى:
- الوضع
off voice_onlyعندما كانت الرسالة الواردة ليست رسالة صوتية مكتوبة- نص الرد فارغ أو مسافة فقط
- ردود الأخطاء، بما في ذلك
Error: - ردود أوامر البوابة مثل
/voice status - الدورات حيث أنتج العميل أداة TTS/صوت أو استدعى
voice.speak - الردود التي تحتوي بالفعل على مخرج صوتي
- تجاوز حدود المزود
- تجاوز
voice.autoTtsMaxCharsPerReply - تجاوز
voice.autoTtsMaxCharsPerHourPerChat - فشل جاهزية المزود
وسائط Auto-TTS مؤقتة. تُكتب الملفات في مساحة temp audio الخاصة بالملف الشخصي، تُسلَّم ككائنات Artifact مع metadata.deliveryHint: "voice" و metadata.ephemeral: true، وتُحذف في كتلة finally على أفضل وجه بعد نجاح أو فشل التوصيل. لا تُحفظ في durable artifact history، ولا تدخل في prompt context، ولا تصبح model-visible attachments أو artifacts طويلة الأجل عادية.
يحاول Telegram تسليم Auto-TTS كـ voice bubble أصلي. يُرجع Edge ملف MP3 (audio/mpeg)، لذلك يتطلب توصيل voice bubble عادةً تحويل ffmpeg إلى OGG/Opus. مع ffmpeg، يحصل Telegram على voice bubble أصلي؛ وبدون ffmpeg، يتلقى Telegram ملفًا صوتيًا عاديًا بدلًا من ذلك.
نص MEDIA:/path الصادر عن النموذج بشكل عشوائي ليس إشارة auto-TTS.
faster-whisper محلي STT
يعمل faster-whisper المحلي عبر عامل Python JSONL طويل الأجل مملوك من قبل بيئة التشغيل لكل runtime/profile. في v0.1.0، يعني stt.provider: "local" مسار faster-whisper المُدار افتراضياً.
المسارات المُدارة:
~/.estacoda/python-env
~/.estacoda/cache/huggingface
~/.estacoda/python-env هي بيئة venv المُدارة. ~/.estacoda/cache/huggingface هي ذاكرة تخزين النموذج الافتراضية. ذاكرة النموذج لا تعيش داخل venv.
شكل الإعدادات:
{
"stt": {
"provider": "local",
"local": {
"engine": "faster-whisper",
"model": "base",
"pythonBinary": "/optional/custom/python",
"fasterWhisper": {
"enabled": true,
"model": "base",
"device": "auto",
"computeType": "default",
"hfHome": "/optional/model-cache",
"allowModelDownload": true,
"gatewayAllowModelDownload": true,
"queueDepth": 1,
"timeoutMs": 300000
}
}
}
}
وضع الأوامر:
{
"stt": {
"provider": "local",
"local": {
"engine": "command",
"command": "/path/to/transcriber {input}"
}
}
}
stt.local.engine: "command" هو الحاكم ولا يستخدم faster-whisper المُدار.
إعداد البيئة المُدارة
estacoda voice setup --stt-provider local
عند عدم توفير Python مخصصة، يقوم الإعداد بما يلي:
- يفحص
~/.estacoda/python-env - ينشئه أو يصلحه عندما يكون مفقوداً أو تالفاً
- يثبّت بالضبط
faster-whisper==1.2.1 - يتحقق من
import faster_whisper - يكتب إعداد STT المحلي فقط بعد نجاح الإعداد
يعرض الإعداد رسائل تقدم منتقاة، وليس سجلات pip الخام. لا تثبت EstaCoda حزم مستخدم عشوائية في البيئة المُدارة. يُستخدم Python النظام فقط لإنشاء venv؛ لا تُعدّل EstaCoda Python النظام أو conda envs أو project venvs أو poetry envs أو uv envs. تُحصر ذاكرة pip المؤقتة أثناء الإعداد المُدار تحت حالة EstaCoda.
Python مخصص:
estacoda voice setup --stt-provider local --python-binary /path/to/python
هذا يتخطى فحص/إنشاء البيئة المُدارة ويخزن المسار المخصص. المشغل يملك بيئة Python هذه، بما في ذلك تثبيت faster-whisper.
إعداد TTS فقط يبقى TTS فقط:
estacoda voice setup --tts-provider openai
لا يغيّر إعداد STT ولا يلمس بيئة Python المُدارة.
سلوك التشغيل
- يحل runtime مسار
stt.local.pythonBinaryالمُعد أولاً، وإلا يستخدم مسار venv المُدار تحت~/.estacoda/python-env. - يضبط runtime قيم
HF_HOME/TRANSFORMERS_CACHEدائمة تحت~/.estacoda/cache/huggingface. - عندما يكون STT المحلي عبر faster-whisper مضبوطاً دون
pythonBinaryمخصص، ينشئ runtime بيئة Python المُدارة أو يصلحها عند أول عملية نسخ. - يثبّت إعداد runtime المُدار حزمة faster-whisper المثبّتة فقط داخل
~/.estacoda/python-env؛ ولا يغيّر system Python أو venvs المملوكة للمشغل. - فشل إعداد Python المُدار لا يمنع بدء runtime أو البوابة؛ يصبح نسخ faster-whisper المحلي فقط غير متاح إلى أن تُصلح البيئة.
- قد يضيف أمر
voice doctorلاحقاً فحص/إصلاح هذا المسار.
سلوك تشغيلي:
- النموذج الافتراضي هو
base. الإعدادات المدعومة:tiny،small،medium،large-v1،large-v2،large-v3. - بروتوكول العامل يتضمن
protocolVersion: 1. - النماذج مخبأة حسب
(model, device, computeType). - فشل CUDA/الجهاز يعيد المحاولة مرة واحدة بـ
device: "cpu"وcomputeType: "int8"عبر نفس العامل. - خروج العامل غير المتوقع يُعيد التشغيل مرة واحدة، ثم يُعلّم faster-whisper غير متاح للـ runtime الحالي.
runtime.dispose()يُوقف العامل.- المهلة الافتراضية 300 ثانية.
- عمق الطابور الافتراضي 1 ما لم يُعدل.
- تجاوز الطابور يفشل سريعًا.
- ترث تنزيلات النموذج الأولى عبر البوابة
allowModelDownload. لأنallowModelDownloadافتراضياًtrue، قد تُنزّل أول رسالة صوتية عبر البوابة ملفات النموذج المضبوط. - اضبط
gatewayAllowModelDownload: falseفقط عندما يجب أن تستخدم رسائل البوابة الصوتية نماذج مخزّنة مسبقًا. - يسمح faster-whisper المحلي غير المُطلق من البوابة بتنزيل النماذج افتراضياً.
- يُمرَّر
hfHomeإلى العامل عند ضبطه. وإلا تضبط EstaCodaHF_HOMEافتراضياً إلى~/.estacoda/cache/huggingfaceوتحافظ علىTRANSFORMERS_CACHEالموجود إذا ضبطته بيئة العملية مسبقاً.
ملف العامل مُعبَّأ في:
workers/faster-whisper/faster-whisper-worker.py
أنماط الفشل
| العرض | السبب المحتمل | الاستعادة |
|---|---|---|
missing key | متغير البيئة المُشار إليه من المزود غير موجود. | أضفه إلى .env الخاص بالملف الشخصي أو بيئة الخدمة. |
disabled | tts.enabled أو stt.enabled هي false. | فعّل المزود في إعدادات الملف الشخصي إذا كان مقصودًا. |
not implemented | مزود مؤجل مُحدد (مثل Mistral). | اختر مزودًا منفذًا. |
python package missing | فشل استيراد faster-whisper. | شغّل estacoda voice setup --stt-provider local، أو أصلح ~/.estacoda/python-env. عند استخدام --python-binary، أصلح بيئة Python المملوكة للمشغل. |
venv support missing | يبلغ Python عن نقص ensurepip أو دعم venv. | ثبّت حزمة venv الخاصة بالنظام، مثل sudo apt install python3.13-venv أو sudo apt install python3-venv، ثم أعد محاولة إعداد STT المحلي. |
download required | النموذج المحدد غير مخبأ والتنزيلات ممنوعة. | خزّن النموذج مسبقًا أو اسمح بالتنزيل صراحةً. |
queue full | تجاوز عمق طابور faster-whisper. | انتظر، أو زِد عمق الطابور، أو قلل الطلبات المتزامنة. |
timeout | تجاوز طلب STT المهلة. | تحقق من أداء النموذج/الجهاز وإعدادات المهلة. |
| المزود غير متاح | خطأ شبكة أو 5xx من المزود. | تحقق من الاتصال وحالة المزود. |
| تجاوز حد auto-TTS في البوابة | تجاوز الحد لكل رد أو ساعة. | انتظر النافذة الساعية أو ارفع الحد. |
| تبعية صوت مفقودة | ffmpeg مفقود لتطبيع التنسيق. | ثبّت ffmpeg؛ العملية تتدهور بسلاسة بدونه. |
مواقع الحالة والملفات المؤقتة والتخزين المؤقت
| المسار | الغرض |
|---|---|
~/.estacoda/profiles/<profile-id>/temp/audio/ | تسجيلات CLI، ملفات auto-TTS المؤقتة، تحويلات Telegram، استقبال Discord. |
~/.estacoda/profiles/<profile-id>/audio-cache/ | ذاكرة التخزين المؤقت للصوت ومساحة عمل إخراج الأمر المحلي. |
~/.estacoda/profiles/<profile-id>/channel-media/ | مرفقات القنوات التي تم تنزيلها عبر البوابة. |
~/.estacoda/profiles/<profile-id>/gateway/logs/voice-stt-preprocess.jsonl | أحداث تدقيق معالجة STT المسبقة في البوابة. |
~/.estacoda/python-env | بيئة Python الافتراضية المُدارة لـ STT المحلي عبر faster-whisper. |
~/.estacoda/cache/huggingface | ذاكرة تخزين النموذج الافتراضية لـ faster-whisper / Hugging Face. منفصلة عن venv. |
~/.estacoda/cache/pip | ذاكرة pip المؤقتة أثناء تثبيت البيئة المُدارة. |
hfHome أو متغير بيئة Hugging Face cache | تجاوز اختياري لذاكرة نماذج faster-whisper. |
لا تسجل أحداث التدقيق المسارات الخاصة الكاملة. تستخدم تجزئات مسارات مستقرة وبيانات وصفية آمنة للمرفقات.
حدود الأمان
تجري معالجة STT المسبقة في البوابة قبل إرسال المزود، أو بدء العامل، أو ffmpeg، أو STT المستضاف، أو التنزيلات، أو الكتابات المؤقتة:
- توحيد
attachment.localPath ?? attachment.pathضمن جذور الوسائط/الصوت المسموح بها. - التحقق من نوع الملف والحجم باستخدام التحقق من صوت الإدخال.
- فحص جاهزية STT و
stt.enabled !== false. - تطبيق سياسة تنزيل faster-whisper قبل أي تنزيل نموذج أولي تُطلقه البوابة. ترث تنزيلات البوابة
allowModelDownload، وهو افتراضياًtrue؛ ويمنعهاgatewayAllowModelDownload: falseصراحةً.
الجذور المسموح بها هي وسائط القنوات المحلية للملف الشخصي، وذاكرة تخزين الصوت المؤقتة، وجذور temp audio المستخدمة في مسارات استقبال قنوات الصوت.