الصوت لعقلك الخاص

إن كان لديك وكيل أو نموذج يقرر الردود بنفسه، فاستخدم صُرَد للصوت وحده: يحول كلام المستخدم إلى نص، وينطق ردك بصوت عربي ثابت تختاره في Studio.

الإعداد

  • أنشئ وكيلاً في Studio واختر صوته وقواعد نطقه، ثم من صفحته ← «شكل الرد» ← «من يكتب الردود؟» اختر «عقلك الخاص» (EXTERNAL_AGENT) وانشر. عندها لا يكتب صُرَد الردود، بل ينطق ما ترسله.
  • الرموز والجلسات كما في صفحة الخادم: رمز جلسة من خادمك، ثم جلسة، ثم الطلبات أدناه.

نطق الرد

POST/api/v1/widget/conversations/{conversation_id}/turns

الحقلالنوعالوصف
capability*"tts_only"نطق نص جاهز دون عقل صُرَد.
ready_text*stringالنص العربي النهائي كما تريد نطقه.
idempotency_keystringمفتاح جديد لكل طلب نطق (UUID)، فريد في مساحة العمل كلها. تكراره لا ينطق من جديد: يعيد الصوت الأصلي إن اكتمل خلال آخر 10 دقائق في المحادثة نفسها، وإلا يعود بلا صوت ومعه requires_new_idempotency_key: true. بعد فشل أعد بمفتاح جديد.
synthesis_transport"grpc_stream"لبث الصوت أجزاءً فور توليده عبر قناة الأحداث (انظر أدناه).
client_request_idstringمعرّف طلبك أنت، يعاد كما هو للربط مع سجلاتك.

يعود الصوت كاملاً في audio.content_base64 (WAV)، ومعه هوية التنفيذ: identity.executed_profile_id(ملف صوت وكيلك) وaudio.executed_voice (الصوت الذي نطق) وidentity.transport. سجّلها مع قياساتك لتتأكد أن صوت وكيلك ثابت في كل طلب.

curl
curl -X POST https://app.surad-ai.com/api/v1/widget/conversations/$CONVERSATION_ID/turns \
  -H "Authorization: Bearer $TOKEN" -H "Origin: https://app.example.com" \
  -H "Content-Type: application/json" \
  -d '{
    "capability": "tts_only",
    "ready_text": "أهلاً بك، طلبك وصلنا وراح نتواصل معك خلال ساعتين.",
    "idempotency_key": "7f3c9a2e-5b1d-4c8e-9a6f-2d4b8e1c0a57"
  }'

البث: أول صوت خلال أقل من ثانية

بالبث يصل أول جزء من الصوت قرابة 0.6 ثانية (وسيط مقيس على خوادمنا بصوت Gemini، لردود من نحو 5 ثوانٍ)، بدل انتظار الصوت كاملاً (نحو 3.7 ثانية). ما يسمعه المستخدم يضاف إليه زمن الشبكة وخادمك والمتصفح. يظل الطلب يعيد الصوت كاملاً عند انتهائه، فلا تشغّل النسختين معاً.

JavaScript
// 1) افتح قناة الأحداث مرة واحدة لكل محادثة (انظر صفحة الخادم لطريقة القراءة)
// 2) اطلب النطق مع البث
await fetch(API + '/api/v1/widget/conversations/' + conversationId + '/turns', {
  method: 'POST',
  headers: { Authorization: 'Bearer ' + token, Origin: ORIGIN, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    capability: 'tts_only',
    ready_text: reply,          // الرد كاملاً في طلب واحد
    idempotency_key: crypto.randomUUID(), // جديد لكل طلب ولكل إعادة محاولة
    synthesis_transport: 'grpc_stream',
  }),
})
// 3) من قناة الأحداث:
//   audio.first   → payload: encoding LINEAR16, sample_rate_hz 24000, channels 1
//   audio.chunk   → payload.seq + payload.content_base64 (PCM16 خام) — شغّل فور الوصول بترتيب seq
//   audio.completed → انتهى صوت الدور
البث يُفعَّل لكل مساحة عمل من جهتنا، ويعمل اليوم مع ملفات الصوت المبنية على Gemini. في غير ذلك يُتجاهلsynthesis_transport ويعود الصوت كاملاً كالمعتاد، ويصل حدث audio.chunk واحد يحمل الصوت كله. تواصل معنا لتفعيله.

تحويل كلام المستخدم إلى نص

POST/api/v1/widget/conversations/{conversation_id}/voice/utterance

ترسل الصوت ملفاً في الحقل file، ويعود transcript.text لتمرره إلى عقلك. الأنسب: WAV أحادي 16kHz بترميز PCM16، حتى 4MB.

curl
curl -X POST https://app.surad-ai.com/api/v1/widget/conversations/$CONVERSATION_ID/voice/utterance \
  -H "Authorization: Bearer $TOKEN" -H "Origin: https://app.example.com" \
  -F "file=@user.wav;type=audio/wav"
# الرد: { "transcript": { "text": "...", "provider": "...", "model": "..." }, ... }

WebSocket لخوادم الوسيط (متقدم)

إن كان خادمك يمرر صوت المستخدم بثاً (مثل مكالمة جارية)، فهذان المساران يحملان الصوت في الاتجاهين دون انتظار نهاية الكلام. المصادقة برمز الجلسة في Authorization وترويسة Origin كبقية الطلبات، ولا أسرار في الرابط.

الاستماع المتدفق: stt-stream

WS/api/v1/widget/conversations/{conversation_id}/stt-stream

  • ترسل: {"type": "start", "stream_id": "…"} ثم إطارات ثنائية (4 بايت ترتيب little-endian ثم PCM16 أحادي 16kHz)، ثم {"type": "end"}. ويمكنك cancel وping.
  • تستقبل: stream_opened، وspeech_started، وtranscript_interim، وspeech_ended، وtranscript_final، وno_speech، وstream_error. الحد الأقصى 60 ثانية للبث الواحد.

النطق المتدفق: tts-stream

WS/api/v1/widget/conversations/{conversation_id}/tts-stream

  • ترسل: {"type": "synthesize", "stream_id": "…", "text": "…", "idempotency_key": "…"} (حتى 4000 حرف)، ويمكنك cancel وping.
  • تستقبل: إطارات ثنائية (4 بايت ترتيب ثم PCM16 أحادي 24kHz) فور توليدها، وأحداث tts_startedوaudio_config وtts_completed وtts_cancelled وtts_error.
يُفعَّل المساران لكل مساحة عمل من جهتنا، ويقبلان النطاقات المعتمدة على مستوى المنصة. إن احتجتهما تواصل معنا. والمسار الأبسط لأغلب التكاملات هو البث عبر قناة الأحداث أعلاه.

لتجربة أسرع

  • أرسل الرد كاملاً في طلب نطق واحد بدل جملة في كل طلب: البث يعطي أول صوت بسرعة، والطلب الواحد يحافظ على نبرة متصلة.
  • افتح الجلسة عند تحميل الصفحة أو بداية المكالمة، لا عند أول جملة.
  • إن كان بين المتصفح وصُرَد خادم وسيط، فمرّر أجزاء الصوت فور وصولها، دون تجميع أو إعادة ترميز.
  • قِس من جهتك: لحظة الطلب، ووصول audio.first، وبدء التشغيل في المتصفح، ووصول audio.completed. وأرسل إلينا identity.request_id لكل دور لنطابقها مع توقيتاتنا.

إن تعذّر الصوت

إن فشل المزوّد في النطق (انتهاء المهلة مثلاً)، يعود الطلب 200 ومعه audio: null وfailed: trueوerror_code، والنص كاملاً. وإن تعذّر على صُرَد تحميل إعدادات صوت وكيلك، يعودAUDIO_PRODUCTION_FAILURE (HTTP 502). في الحالتين لا ينطق صُرَد بصوت آخر. أعد المحاولة مرة واحدة بمفتاحidempotency_key جديد، ثم اكتفِ بالنص.